⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diff3.c

📁 制作2.6内核的CLFS时 使用的diffutils-2.8.7.tar.gz包
💻 C
📖 第 1 页 / 共 4 页
字号:
  else    {      D_LINEARRAY (result, FILE1) = 0;      D_LENARRAY (result, FILE1) = 0;    }  numlines = D_NUMLINES (result, FILE2);  if (numlines)    {      D_LINEARRAY (result, FILE2) = xcalloc (numlines, sizeof (char *));      D_LENARRAY (result, FILE2) = xcalloc (numlines, sizeof (size_t));    }  else    {      D_LINEARRAY (result, FILE2) = 0;      D_LENARRAY (result, FILE2) = 0;    }  /* Return */  return result;}/* Compare two lists of lines of text.   Return 1 if they are equivalent, 0 if not.  */static boolcompare_line_list (char * const list1[], size_t const lengths1[],		   char * const list2[], size_t const lengths2[],		   lin nl){  char * const *l1 = list1;  char * const *l2 = list2;  size_t const *lgths1 = lengths1;  size_t const *lgths2 = lengths2;  while (nl--)    if (!*l1 || !*l2 || *lgths1 != *lgths2++	|| memcmp (*l1++, *l2++, *lgths1++) != 0)      return false;  return true;}/* Input and parse two way diffs.  */static struct diff_block *process_diff (char const *filea,	      char const *fileb,	      struct diff_block **last_block){  char *diff_contents;  char *diff_limit;  char *scan_diff;  enum diff_type dt;  lin i;  struct diff_block *block_list, **block_list_end, *bptr;  size_t too_many_lines = (PTRDIFF_MAX			   / MIN (sizeof *bptr->lines[1],				  sizeof *bptr->lengths[1]));  diff_limit = read_diff (filea, fileb, &diff_contents);  scan_diff = diff_contents;  block_list_end = &block_list;  bptr = 0; /* Pacify `gcc -W'.  */  while (scan_diff < diff_limit)    {      bptr = xmalloc (sizeof *bptr);      bptr->lines[0] = bptr->lines[1] = 0;      bptr->lengths[0] = bptr->lengths[1] = 0;      dt = process_diff_control (&scan_diff, bptr);      if (dt == ERROR || *scan_diff != '\n')	{	  fprintf (stderr, _("%s: diff failed: "), program_name);	  do	    {	      putc (*scan_diff, stderr);	    }	  while (*scan_diff++ != '\n');	  exit (EXIT_TROUBLE);	}      scan_diff++;      /* Force appropriate ranges to be null, if necessary */      switch (dt)	{	case ADD:	  bptr->ranges[0][0]++;	  break;	case DELETE:	  bptr->ranges[1][0]++;	  break;	case CHANGE:	  break;	default:	  fatal ("internal error: invalid diff type in process_diff");	  break;	}      /* Allocate space for the pointers for the lines from filea, and	 parcel them out among these pointers */      if (dt != ADD)	{	  lin numlines = D_NUMLINES (bptr, 0);	  if (too_many_lines <= numlines)	    xalloc_die ();	  bptr->lines[0] = xmalloc (numlines * sizeof *bptr->lines[0]);	  bptr->lengths[0] = xmalloc (numlines * sizeof *bptr->lengths[0]);	  for (i = 0; i < numlines; i++)	    scan_diff = scan_diff_line (scan_diff,					&(bptr->lines[0][i]),					&(bptr->lengths[0][i]),					diff_limit,					'<');	}      /* Get past the separator for changes */      if (dt == CHANGE)	{	  if (strncmp (scan_diff, "---\n", 4))	    fatal ("invalid diff format; invalid change separator");	  scan_diff += 4;	}      /* Allocate space for the pointers for the lines from fileb, and	 parcel them out among these pointers */      if (dt != DELETE)	{	  lin numlines = D_NUMLINES (bptr, 1);	  if (too_many_lines <= numlines)	    xalloc_die ();	  bptr->lines[1] = xmalloc (numlines * sizeof *bptr->lines[1]);	  bptr->lengths[1] = xmalloc (numlines * sizeof *bptr->lengths[1]);	  for (i = 0; i < numlines; i++)	    scan_diff = scan_diff_line (scan_diff,					&(bptr->lines[1][i]),					&(bptr->lengths[1][i]),					diff_limit,					'>');	}      /* Place this block on the blocklist.  */      *block_list_end = bptr;      block_list_end = &bptr->next;    }  *block_list_end = 0;  *last_block = bptr;  return block_list;}/* Skip tabs and spaces, and return the first character after them.  */static char *skipwhite (char *s){  while (*s == ' ' || *s == '\t')    s++;  return s;}/* Read a nonnegative line number from S, returning the address of the   first character after the line number, and storing the number into   *PNUM.  Return 0 if S does not point to a valid line number.  */static char *readnum (char *s, lin *pnum){  unsigned char c = *s;  lin num = 0;  if (! ISDIGIT (c))    return 0;  do    {      num = c - '0' + num * 10;      c = *++s;    }  while (ISDIGIT (c));  *pnum = num;  return s;}/* Parse a normal format diff control string.  Return the type of the   diff (ERROR if the format is bad).  All of the other important   information is filled into to the structure pointed to by db, and   the string pointer (whose location is passed to this routine) is   updated to point beyond the end of the string parsed.  Note that   only the ranges in the diff_block will be set by this routine.   If some specific pair of numbers has been reduced to a single   number, then both corresponding numbers in the diff block are set   to that number.  In general these numbers are interpreted as ranges   inclusive, unless being used by the ADD or DELETE commands.  It is   assumed that these will be special cased in a superior routine.   */static enum diff_typeprocess_diff_control (char **string, struct diff_block *db){  char *s = *string;  enum diff_type type;  /* Read first set of digits */  s = readnum (skipwhite (s), &db->ranges[0][RANGE_START]);  if (! s)    return ERROR;  /* Was that the only digit? */  s = skipwhite (s);  if (*s == ',')    {      s = readnum (s + 1, &db->ranges[0][RANGE_END]);      if (! s)	return ERROR;    }  else    db->ranges[0][RANGE_END] = db->ranges[0][RANGE_START];  /* Get the letter */  s = skipwhite (s);  switch (*s)    {    case 'a':      type = ADD;      break;    case 'c':      type = CHANGE;      break;    case 'd':      type = DELETE;      break;    default:      return ERROR;			/* Bad format */    }  s++;				/* Past letter */  /* Read second set of digits */  s = readnum (skipwhite (s), &db->ranges[1][RANGE_START]);  if (! s)    return ERROR;  /* Was that the only digit? */  s = skipwhite (s);  if (*s == ',')    {      s = readnum (s + 1, &db->ranges[1][RANGE_END]);      if (! s)	return ERROR;      s = skipwhite (s);		/* To move to end */    }  else    db->ranges[1][RANGE_END] = db->ranges[1][RANGE_START];  *string = s;  return type;}static char *read_diff (char const *filea,	   char const *fileb,	   char **output_placement){  char *diff_result;  size_t current_chunk_size, total;  int fd, wstatus, status;  int werrno = 0;  struct stat pipestat;#if HAVE_WORKING_FORK || HAVE_WORKING_VFORK  char const *argv[9];  char const **ap;  int fds[2];  pid_t pid;  ap = argv;  *ap++ = diff_program;  if (text)    *ap++ = "-a";  if (strip_trailing_cr)    *ap++ = "--strip-trailing-cr";  *ap++ = "--horizon-lines=100";  *ap++ = "--";  *ap++ = filea;  *ap++ = fileb;  *ap = 0;  if (pipe (fds) != 0)    perror_with_exit ("pipe");  pid = vfork ();  if (pid == 0)    {      /* Child */      close (fds[0]);      if (fds[1] != STDOUT_FILENO)	{	  dup2 (fds[1], STDOUT_FILENO);	  close (fds[1]);	}      /* The cast to (char **) is needed for portability to older	 hosts with a nonstandard prototype for execvp.  */      execvp (diff_program, (char **) argv);      _exit (errno == ENOENT ? 127 : 126);    }  if (pid == -1)    perror_with_exit ("fork");  close (fds[1]);		/* Prevent erroneous lack of EOF */  fd = fds[0];#else  FILE *fpipe;  char const args[] = " --horizon-lines=100 -- ";  char *command = xmalloc (quote_system_arg (0, diff_program)			   + sizeof "-a"			   + sizeof "--strip-trailing-cr"			   + sizeof args - 1			   + quote_system_arg (0, filea) + 1			   + quote_system_arg (0, fileb) + 1);  char *p = command;  p += quote_system_arg (p, diff_program);  if (text)    {      strcpy (p, " -a");      p += 3;    }  if (strip_trailing_cr)    {      strcpy (p, " --strip-trailing-cr");      p += 20;    }  strcpy (p, args);  p += sizeof args - 1;  p += quote_system_arg (p, filea);  *p++ = ' ';  p += quote_system_arg (p, fileb);  *p = 0;  errno = 0;  fpipe = popen (command, "r");  if (!fpipe)    perror_with_exit (command);  free (command);  fd = fileno (fpipe);#endif  if (fstat (fd, &pipestat) != 0)    perror_with_exit ("fstat");  current_chunk_size = MAX (1, STAT_BLOCKSIZE (pipestat));  diff_result = xmalloc (current_chunk_size);  total = 0;  for (;;)    {      size_t bytes_to_read = current_chunk_size - total;      size_t bytes = block_read (fd, diff_result + total, bytes_to_read);      total += bytes;      if (bytes != bytes_to_read)	{	  if (bytes == SIZE_MAX)	    perror_with_exit (_("read failed"));	  break;	}      if (PTRDIFF_MAX / 2 <= current_chunk_size)	xalloc_die ();      current_chunk_size *= 2;      diff_result = xrealloc (diff_result, current_chunk_size);    }  if (total != 0 && diff_result[total-1] != '\n')    fatal ("invalid diff format; incomplete last line");  *output_placement = diff_result;#if ! (HAVE_WORKING_FORK || HAVE_WORKING_VFORK)  wstatus = pclose (fpipe);  if (wstatus == -1)    werrno = errno;#else  if (close (fd) != 0)    perror_with_exit ("close");  if (waitpid (pid, &wstatus, 0) < 0)    perror_with_exit ("waitpid");#endif  status = ! werrno && WIFEXITED (wstatus) ? WEXITSTATUS (wstatus) : INT_MAX;  if (EXIT_TROUBLE <= status)    error (EXIT_TROUBLE, werrno,	   _(status == 126	     ? "subsidiary program `%s' could not be invoked"	     : status == 127	     ? "subsidiary program `%s' not found"	     : status == INT_MAX	     ? "subsidiary program `%s' failed"	     : "subsidiary program `%s' failed (exit status %d)"),	   diff_program, status);  return diff_result + total;}/* Scan a regular diff line (consisting of > or <, followed by a   space, followed by text (including nulls) up to a newline.   This next routine began life as a macro and many parameters in it   are used as call-by-reference values.  */static char *scan_diff_line (char *scan_ptr, char **set_start, size_t *set_length,		char *limit, char leadingchar){  char *line_ptr;  if (!(scan_ptr[0] == leadingchar	&& scan_ptr[1] == ' '))    fatal ("invalid diff format; incorrect leading line chars");  *set_start = line_ptr = scan_ptr + 2;  while (*line_ptr++ != '\n')    continue;  /* Include newline if the original line ended in a newline,     or if an edit script is being generated.     Copy any missing newline message to stderr if an edit script is being     generated, because edit scripts cannot handle missing newlines.     Return the beginning of the next line.  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -