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

📄 diff3.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 4 页
字号:
      switch (ptr->correspond)	{	case DIFF_ALL:	  x[0] = '\0';	  dontprint = 3;	/* Print them all */	  oddoneout = 3;	/* Nobody's odder than anyone else */	  break;	case DIFF_1ST:	case DIFF_2ND:	case DIFF_3RD:	  oddoneout = rev_mapping[(int) ptr->correspond - (int) DIFF_1ST];	  x[0] = oddoneout + '1';	  x[1] = '\0';	  dontprint = oddoneout==0;	  break;	default:	  fatal ("internal error: invalid diff type passed to output");	}      fprintf (outputfile, "====%s\n", x);      /* Go 0, 2, 1 if the first and third outputs are equivalent.  */      for (i = 0; i < 3;	   i = (oddoneout == 1 ? skew_increment[i] : i + 1))	{	  int realfile = mapping[i];	  int	    lowt = D_LOWLINE (ptr, realfile),	    hight = D_HIGHLINE (ptr, realfile);	  fprintf (outputfile, "%d:", i + 1);	  switch (lowt - hight)	    {	    case 1:	      fprintf (outputfile, "%da\n", lowt - 1);	      break;	    case 0:	      fprintf (outputfile, "%dc\n", lowt);	      break;	    default:	      fprintf (outputfile, "%d,%dc\n", lowt, hight);	      break;	    }	  if (i == dontprint) continue;	  if (lowt <= hight)	    {	      line = 0;	      do		{		  fprintf (outputfile, line_prefix);		  cp = D_RELNUM (ptr, realfile, line);		  length = D_RELLEN (ptr, realfile, line);		  fwrite (cp, sizeof (char), length, outputfile);		}	      while (++line < hight - lowt + 1);	      if (cp[length - 1] != '\n')		fprintf (outputfile, "\n\\ No newline at end of file\n");	    }	}    }}/* * Output to OUTPUTFILE the lines of B taken from FILENUM. * Double any initial '.'s; yield nonzero if any initial '.'s were doubled. */static intdotlines (outputfile, b, filenum)     FILE *outputfile;     struct diff3_block *b;     int filenum;{  int i;  int leading_dot = 0;  for (i = 0;       i < D_NUMLINES (b, filenum);       i++)    {      char *line = D_RELNUM (b, filenum, i);      if (line[0] == '.')	{	  leading_dot = 1;	  fprintf (outputfile, ".");	}      fwrite (line, sizeof (char),	      D_RELLEN (b, filenum, i), outputfile);    }  return leading_dot;}/* * Output to OUTPUTFILE a '.' line.  If LEADING_DOT is nonzero, * also output a command that removes initial '.'s * starting with line START and continuing for NUM lines. */static voidundotlines (outputfile, leading_dot, start, num)     FILE *outputfile;     int leading_dot, start, num;{  fprintf (outputfile, ".\n");  if (leading_dot)    if (num == 1)      fprintf (outputfile, "%ds/^\\.//\n", start);    else      fprintf (outputfile, "%d,%ds/^\\.//\n", start, start + num - 1);}/* * This routine outputs a diff3 set of blocks as an ed script.  This * script applies the changes between file's 2 & 3 to file 1.  It * takes the precise format of the ed script to be output from global * variables set during options processing.  Note that it does * destructive things to the set of diff3 blocks it is passed; it * reverses their order (this gets around the problems involved with * changing line numbers in an ed script). * * Note that this routine has the same problem of mapping as the last * one did; the variable MAPPING maps from file number according to * the argument list to file number according to the diff passed.  All * files listed below are in terms of the argument list. * REV_MAPPING is the inverse of MAPPING. * * The arguments FILE0, FILE1 and FILE2 are the strings to print * as the names of the three files.  These may be the actual names, * or may be the arguments specified with -L. * * Returns 1 if conflicts were found. */static intoutput_diff3_edscript (outputfile, diff, mapping, rev_mapping,		       file0, file1, file2)     FILE *outputfile;     struct diff3_block *diff;     int const mapping[3], rev_mapping[3];     char const *file0, *file1, *file2;{  int leading_dot;  int conflicts_found = 0, conflict;  struct diff3_block *b;  for (b = reverse_diff3_blocklist (diff); b; b = b->next)    {      /* Must do mapping correctly.  */      enum diff_type type	= ((b->correspond == DIFF_ALL) ?	   DIFF_ALL :	   ((enum diff_type)	    (((int) DIFF_1ST)	     + rev_mapping[(int) b->correspond - (int) DIFF_1ST])));      /* If we aren't supposed to do this output block, skip it.  */      switch (type)	{	default: continue;	case DIFF_2ND: if (!show_2nd) continue; conflict = 1; break;	case DIFF_3RD: if (overlap_only) continue; conflict = 0; break;	case DIFF_ALL: if (simple_only) continue; conflict = flagging; break;	}      if (conflict)	{	  conflicts_found = 1;	  /* Mark end of conflict.  */	  fprintf (outputfile, "%da\n", D_HIGHLINE (b, mapping[FILE0]));	  leading_dot = 0;	  if (type == DIFF_ALL)	    {	      if (show_2nd)		{		  /* Append lines from FILE1.  */		  fprintf (outputfile, "||||||| %s\n", file1);		  leading_dot = dotlines (outputfile, b, mapping[FILE1]);		}	      /* Append lines from FILE2.  */	      fprintf (outputfile, "=======\n");	      leading_dot |= dotlines (outputfile, b, mapping[FILE2]);	    }	  fprintf (outputfile, ">>>>>>> %s\n", file2);	  undotlines (outputfile, leading_dot,		      D_HIGHLINE (b, mapping[FILE0]) + 2,		      (D_NUMLINES (b, mapping[FILE1])		       + D_NUMLINES (b, mapping[FILE2]) + 1));	  /* Mark start of conflict.  */	  fprintf (outputfile, "%da\n<<<<<<< %s\n",		   D_LOWLINE (b, mapping[FILE0]) - 1,		   type == DIFF_ALL ? file0 : file1);	  leading_dot = 0;	  if (type == DIFF_2ND)	    {	      /* Prepend lines from FILE1.  */	      leading_dot = dotlines (outputfile, b, mapping[FILE1]);	      fprintf (outputfile, "=======\n");	    }	  undotlines (outputfile, leading_dot,		      D_LOWLINE (b, mapping[FILE0]) + 1,		      D_NUMLINES (b, mapping[FILE1]));	}      else if (D_NUMLINES (b, mapping[FILE2]) == 0)	/* Write out a delete */	{	  if (D_NUMLINES (b, mapping[FILE0]) == 1)	    fprintf (outputfile, "%dd\n",		     D_LOWLINE (b, mapping[FILE0]));	  else	    fprintf (outputfile, "%d,%dd\n",		     D_LOWLINE (b, mapping[FILE0]),		     D_HIGHLINE (b, mapping[FILE0]));	}      else	/* Write out an add or change */	{	  switch (D_NUMLINES (b, mapping[FILE0]))	    {	    case 0:	      fprintf (outputfile, "%da\n",		       D_HIGHLINE (b, mapping[FILE0]));	      break;	    case 1:	      fprintf (outputfile, "%dc\n",		       D_HIGHLINE (b, mapping[FILE0]));	      break;	    default:	      fprintf (outputfile, "%d,%dc\n",		       D_LOWLINE (b, mapping[FILE0]),		       D_HIGHLINE (b, mapping[FILE0]));	      break;	    }	  undotlines (outputfile, dotlines (outputfile, b, mapping[FILE2]),		      D_LOWLINE (b, mapping[FILE0]),		      D_NUMLINES (b, mapping[FILE2]));	}    }  if (finalwrite) fprintf (outputfile, "w\nq\n");  return conflicts_found;}/* * Read from INFILE and output to OUTPUTFILE a set of diff3_ blocks DIFF * as a merged file.  This acts like 'ed file0 <[output_diff3_edscript]', * except that it works even for binary data or incomplete lines. * * As before, MAPPING maps from arg list file number to diff file number, * REV_MAPPING is its inverse, * and FILE0, FILE1, and FILE2 are the names of the files. * * Returns 1 if conflicts were found. */static intoutput_diff3_merge (infile, outputfile, diff, mapping, rev_mapping,		    file0, file1, file2)     FILE *infile, *outputfile;     struct diff3_block *diff;     int const mapping[3], rev_mapping[3];     char const *file0, *file1, *file2;{  int c, i;  int conflicts_found = 0, conflict;  struct diff3_block *b;  int linesread = 0;  for (b = diff; b; b = b->next)    {      /* Must do mapping correctly.  */      enum diff_type type	= ((b->correspond == DIFF_ALL) ?	   DIFF_ALL :	   ((enum diff_type)	    (((int) DIFF_1ST)	     + rev_mapping[(int) b->correspond - (int) DIFF_1ST])));      char const *format_2nd = "<<<<<<< %s\n";      /* If we aren't supposed to do this output block, skip it.  */      switch (type)	{	default: continue;	case DIFF_2ND: if (!show_2nd) continue; conflict = 1; break;	case DIFF_3RD: if (overlap_only) continue; conflict = 0; break;	case DIFF_ALL: if (simple_only) continue; conflict = flagging;	  format_2nd = "||||||| %s\n";	  break;	}      /* Copy I lines from file 0.  */      i = D_LOWLINE (b, FILE0) - linesread - 1;      linesread += i;      while (0 <= --i)	do	  {	    c = getc (infile);	    if (c == EOF)	      if (ferror (infile))		perror_with_exit ("input file");	      else if (feof (infile))		fatal ("input file shrank");	    putc (c, outputfile);	  }	while (c != '\n');      if (conflict)	{	  conflicts_found = 1;	  if (type == DIFF_ALL)	    {	      /* Put in lines from FILE0 with bracket.  */	      fprintf (outputfile, "<<<<<<< %s\n", file0);	      for (i = 0;		   i < D_NUMLINES (b, mapping[FILE0]);		   i++)		fwrite (D_RELNUM (b, mapping[FILE0], i), sizeof (char),			D_RELLEN (b, mapping[FILE0], i), outputfile);	    }	  if (show_2nd)	    {	      /* Put in lines from FILE1 with bracket.  */	      fprintf (outputfile, format_2nd, file1);	      for (i = 0;		   i < D_NUMLINES (b, mapping[FILE1]);		   i++)		fwrite (D_RELNUM (b, mapping[FILE1], i), sizeof (char),			D_RELLEN (b, mapping[FILE1], i), outputfile);	    }	  fprintf (outputfile, "=======\n");	}      /* Put in lines from FILE2.  */      for (i = 0;	   i < D_NUMLINES (b, mapping[FILE2]);	   i++)	fwrite (D_RELNUM (b, mapping[FILE2], i), sizeof (char),		D_RELLEN (b, mapping[FILE2], i), outputfile);      if (conflict)	fprintf (outputfile, ">>>>>>> %s\n", file2);      /* Skip I lines in file 0.  */      i = D_NUMLINES (b, FILE0);      linesread += i;      while (0 <= --i)	while ((c = getc (infile)) != '\n')	  if (c == EOF)	    if (ferror (infile))	      perror_with_exit ("input file");	    else if (feof (infile))	      {		if (i || b->next)		  fatal ("input file shrank");		return conflicts_found;	      }    }  /* Copy rest of common file.  */  while ((c = getc (infile)) != EOF || !(ferror (infile) | feof (infile)))    putc (c, outputfile);  return conflicts_found;}/* * Reverse the order of the list of diff3 blocks. */static struct diff3_block *reverse_diff3_blocklist (diff)     struct diff3_block *diff;{  register struct diff3_block *tmp, *next, *prev;  for (tmp = diff, prev = 0;  tmp;  tmp = next)    {      next = tmp->next;      tmp->next = prev;      prev = tmp;    }  return prev;}static size_tmyread (fd, ptr, size)     int fd;     char *ptr;     size_t size;{  size_t result = read (fd, ptr, size);  if (result == -1)    perror_with_exit ("read failed");  return result;}static VOID *xmalloc (size)     size_t size;{  VOID *result = (VOID *) malloc (size ? size : 1);  if (!result)    fatal ("memory exhausted");  return result;}static VOID *xrealloc (ptr, size)     VOID *ptr;     size_t size;{  VOID *result = (VOID *) realloc (ptr, size ? size : 1);  if (!result)    fatal ("memory exhausted");  return result;}static voidfatal (string)     char const *string;{  fprintf (stderr, "%s: %s\n", program_name, string);  exit (2);}static voidperror_with_exit (string)     char const *string;{  int e = errno;  fprintf (stderr, "%s: ", program_name);  errno = e;  perror (string);  exit (2);}

⌨️ 快捷键说明

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