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

📄 diff.c

📁 制作2.6内核的CLFS时 使用的diffutils-2.8.7.tar.gz包
💻 C
📖 第 1 页 / 共 3 页
字号:
    %%  %\n\    %c'C'  the single character C\n\    %c'\\OOO'  the character with octal code OOO"),  "",  N_("-l  --paginate  Pass the output through `pr' to paginate it."),  N_("-t  --expand-tabs  Expand tabs to spaces in output."),  N_("-T  --initial-tab  Make tabs line up by prepending a tab."),  N_("--tabsize=NUM  Tab stops are every NUM (default 8) print columns."),  "",  N_("-r  --recursive  Recursively compare any subdirectories found."),  N_("-N  --new-file  Treat absent files as empty."),  N_("--unidirectional-new-file  Treat absent first files as empty."),  N_("-s  --report-identical-files  Report when two files are the same."),  N_("-x PAT  --exclude=PAT  Exclude files that match PAT."),  N_("-X FILE  --exclude-from=FILE  Exclude files that match any pattern in FILE."),  N_("-S FILE  --starting-file=FILE  Start with FILE when comparing directories."),  N_("--from-file=FILE1  Compare FILE1 to all operands.  FILE1 can be a directory."),  N_("--to-file=FILE2  Compare all operands to FILE2.  FILE2 can be a directory."),  "",  N_("--horizon-lines=NUM  Keep NUM lines of the common prefix and suffix."),  N_("-d  --minimal  Try hard to find a smaller set of changes."),  N_("--speed-large-files  Assume large files and many scattered small changes."),  "",  N_("-v  --version  Output version info."),  N_("--help  Output this help."),  "",  N_("FILES are `FILE1 FILE2' or `DIR1 DIR2' or `DIR FILE...' or `FILE... DIR'."),  N_("If --from-file or --to-file is given, there are no restrictions on FILES."),  N_("If a FILE is `-', read standard input."),  N_("Exit status is 0 if inputs are the same, 1 if different, 2 if trouble."),  "",  N_("Report bugs to <bug-gnu-utils@gnu.org>."),  0};static voidusage (void){  char const * const *p;  printf (_("Usage: %s [OPTION]... FILES\n"), program_name);  for (p = option_help_msgid;  *p;  p++)    {      if (!**p)	putchar ('\n');      else	{	  char const *msg = _(*p);	  char const *nl;	  while ((nl = strchr (msg, '\n')))	    {	      int msglen = nl + 1 - msg;	      printf ("  %.*s", msglen, msg);	      msg = nl + 1;	    }	  printf ("  %s\n" + 2 * (*msg != ' ' && *msg != '-'), msg);	}    }}/* Set VAR to VALUE, reporting an OPTION error if this is a   conflict.  */static voidspecify_value (char const **var, char const *value, char const *option){  if (*var && strcmp (*var, value) != 0)    {      error (0, 0, _("conflicting %s option value `%s'"), option, value);      try_help (0, 0);    }  *var = value;}/* Set the output style to STYLE, diagnosing conflicts.  */static voidspecify_style (enum output_style style){  if (output_style != style)    {      if (output_style != OUTPUT_UNSPECIFIED)	try_help ("conflicting output style options", 0);      output_style = style;    }}/* Set the last-modified time of *ST to be the current time.  */static voidset_mtime_to_now (struct stat *st){#ifdef ST_MTIM_NSEC# if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME  if (clock_gettime (CLOCK_REALTIME, &st->st_mtim) == 0)    return;# endif# if HAVE_GETTIMEOFDAY  {    struct timeval timeval;    if (gettimeofday (&timeval, 0) == 0)      {	st->st_mtime = timeval.tv_sec;	st->st_mtim.ST_MTIM_NSEC = timeval.tv_usec * 1000;	return;      }  }# endif#endif /* ST_MTIM_NSEC */  time (&st->st_mtime);}/* Compare two files (or dirs) with parent comparison PARENT   and names NAME0 and NAME1.   (If PARENT is 0, then the first name is just NAME0, etc.)   This is self-contained; it opens the files and closes them.   Value is EXIT_SUCCESS if files are the same, EXIT_FAILURE if   different, EXIT_TROUBLE if there is a problem opening them.  */static intcompare_files (struct comparison const *parent,	       char const *name0,	       char const *name1){  struct comparison cmp;#define DIR_P(f) (S_ISDIR (cmp.file[f].stat.st_mode) != 0)  register int f;  int status = EXIT_SUCCESS;  bool same_files;  char *free0, *free1;  /* If this is directory comparison, perhaps we have a file     that exists only in one of the directories.     If so, just print a message to that effect.  */  if (! ((name0 && name1)	 || (unidirectional_new_file && name1)	 || new_file))    {      char const *name = name0 == 0 ? name1 : name0;      char const *dir = parent->file[name0 == 0].name;      /* See POSIX 1003.1-2001 for this format.  */      message ("Only in %s: %s\n", dir, name);      /* Return EXIT_FAILURE so that diff_dirs will return	 EXIT_FAILURE ("some files differ").  */      return EXIT_FAILURE;    }  memset (cmp.file, 0, sizeof cmp.file);  cmp.parent = parent;  /* cmp.file[f].desc markers */#define NONEXISTENT (-1) /* nonexistent file */#define UNOPENED (-2) /* unopened file (e.g. directory) */#define ERRNO_ENCODE(errno) (-3 - (errno)) /* encoded errno value */#define ERRNO_DECODE(desc) (-3 - (desc)) /* inverse of ERRNO_ENCODE */  cmp.file[0].desc = name0 == 0 ? NONEXISTENT : UNOPENED;  cmp.file[1].desc = name1 == 0 ? NONEXISTENT : UNOPENED;  /* Now record the full name of each file, including nonexistent ones.  */  if (name0 == 0)    name0 = name1;  if (name1 == 0)    name1 = name0;  if (!parent)    {      free0 = 0;      free1 = 0;      cmp.file[0].name = name0;      cmp.file[1].name = name1;    }  else    {      cmp.file[0].name = free0	= dir_file_pathname (parent->file[0].name, name0);      cmp.file[1].name = free1	= dir_file_pathname (parent->file[1].name, name1);    }  /* Stat the files.  */  for (f = 0; f < 2; f++)    {      if (cmp.file[f].desc != NONEXISTENT)	{	  if (f && file_name_cmp (cmp.file[f].name, cmp.file[0].name) == 0)	    {	      cmp.file[f].desc = cmp.file[0].desc;	      cmp.file[f].stat = cmp.file[0].stat;	    }	  else if (strcmp (cmp.file[f].name, "-") == 0)	    {	      cmp.file[f].desc = STDIN_FILENO;	      if (fstat (STDIN_FILENO, &cmp.file[f].stat) != 0)		cmp.file[f].desc = ERRNO_ENCODE (errno);	      else		{		  if (S_ISREG (cmp.file[f].stat.st_mode))		    {		      off_t pos = lseek (STDIN_FILENO, (off_t) 0, SEEK_CUR);		      if (pos < 0)			cmp.file[f].desc = ERRNO_ENCODE (errno);		      else			cmp.file[f].stat.st_size =			  MAX (0, cmp.file[f].stat.st_size - pos);		    }		  /* POSIX 1003.1-2001 requires current time for		     stdin.  */		  set_mtime_to_now (&cmp.file[f].stat);		}	    }	  else if (stat (cmp.file[f].name, &cmp.file[f].stat) != 0)	    cmp.file[f].desc = ERRNO_ENCODE (errno);	}    }  /* Mark files as nonexistent as needed for -N and -P, if they are     inaccessible empty regular files (the kind of files that 'patch'     creates to indicate nonexistent backups), or if they are     top-level files that do not exist but their counterparts do     exist.  */  for (f = 0; f < 2; f++)    if ((new_file || (f == 0 && unidirectional_new_file))	&& (cmp.file[f].desc == UNOPENED	    ? (S_ISREG (cmp.file[f].stat.st_mode)	       && ! (cmp.file[f].stat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))	       && cmp.file[f].stat.st_size == 0)	    : (cmp.file[f].desc == ERRNO_ENCODE (ENOENT)	       && ! parent	       && cmp.file[1 - f].desc == UNOPENED)))      cmp.file[f].desc = NONEXISTENT;  for (f = 0; f < 2; f++)    if (cmp.file[f].desc == NONEXISTENT)      {	memset (&cmp.file[f].stat, 0, sizeof cmp.file[f].stat);	cmp.file[f].stat.st_mode = cmp.file[1 - f].stat.st_mode;      }  for (f = 0; f < 2; f++)    {      int e = ERRNO_DECODE (cmp.file[f].desc);      if (0 <= e)	{	  errno = e;	  perror_with_name (cmp.file[f].name);	  status = EXIT_TROUBLE;	}    }  if (status == EXIT_SUCCESS && ! parent && DIR_P (0) != DIR_P (1))    {      /* If one is a directory, and it was specified in the command line,	 use the file in that dir with the other file's basename.  */      int fnm_arg = DIR_P (0);      int dir_arg = 1 - fnm_arg;      char const *fnm = cmp.file[fnm_arg].name;      char const *dir = cmp.file[dir_arg].name;      char const *filename = cmp.file[dir_arg].name = free0	= dir_file_pathname (dir, base_name (fnm));      if (strcmp (fnm, "-") == 0)	fatal ("cannot compare `-' to a directory");      if (stat (filename, &cmp.file[dir_arg].stat) != 0)	{	  perror_with_name (filename);	  status = EXIT_TROUBLE;	}    }  if (status != EXIT_SUCCESS)    {      /* One of the files should exist but does not.  */    }  else if (cmp.file[0].desc == NONEXISTENT	   && cmp.file[1].desc == NONEXISTENT)    {      /* Neither file "exists", so there's nothing to compare.  */    }  else if ((same_files	    = (cmp.file[0].desc != NONEXISTENT	       && cmp.file[1].desc != NONEXISTENT	       && 0 < same_file (&cmp.file[0].stat, &cmp.file[1].stat)	       && same_file_attributes (&cmp.file[0].stat,					&cmp.file[1].stat)))	   && no_diff_means_no_output)    {      /* The two named files are actually the same physical file.	 We know they are identical without actually reading them.  */    }  else if (DIR_P (0) & DIR_P (1))    {      if (output_style == OUTPUT_IFDEF)	fatal ("-D option not supported with directories");      /* If both are directories, compare the files in them.  */      if (parent && !recursive)	{	  /* But don't compare dir contents one level down	     unless -r was specified.	     See POSIX 1003.1-2001 for this format.  */	  message ("Common subdirectories: %s and %s\n",		   cmp.file[0].name, cmp.file[1].name);	}      else	status = diff_dirs (&cmp, compare_files);    }  else if ((DIR_P (0) | DIR_P (1))	   || (parent	       && (! S_ISREG (cmp.file[0].stat.st_mode)		   || ! S_ISREG (cmp.file[1].stat.st_mode))))    {      if (cmp.file[0].desc == NONEXISTENT || cmp.file[1].desc == NONEXISTENT)	{	  /* We have a subdirectory that exists only in one directory.  */	  if ((DIR_P (0) | DIR_P (1))	      && recursive	      && (new_file		  || (unidirectional_new_file		      && cmp.file[0].desc == NONEXISTENT)))	    status = diff_dirs (&cmp, compare_files);	  else	    {	      char const *dir		= parent->file[cmp.file[0].desc == NONEXISTENT].name;	      /* See POSIX 1003.1-2001 for this format.  */	      message ("Only in %s: %s\n", dir, name0);	      status = EXIT_FAILURE;	    }	}      else	{	  /* We have two files that are not to be compared.  */	  /* See POSIX 1003.1-2001 for this format.  */	  message5 ("File %s is a %s while file %s is a %s\n",		    file_label[0] ? file_label[0] : cmp.file[0].name,		    file_type (&cmp.file[0].stat),		    file_label[1] ? file_label[1] : cmp.file[1].name,		    file_type (&cmp.file[1].stat));	  /* This is a difference.  */	  status = EXIT_FAILURE;	}    }  else if (files_can_be_treated_as_binary	   && S_ISREG (cmp.file[0].stat.st_mode)	   && S_ISREG (cmp.file[1].stat.st_mode)	   && cmp.file[0].stat.st_size != cmp.file[1].stat.st_size)    {      message ("Files %s and %s differ\n",	       file_label[0] ? file_label[0] : cmp.file[0].name,	       file_label[1] ? file_label[1] : cmp.file[1].name);      status = EXIT_FAILURE;    }  else    {      /* Both exist and neither is a directory.  */      /* Open the files and record their descriptors.  */      if (cmp.file[0].desc == UNOPENED)	if ((cmp.file[0].desc = open (cmp.file[0].name, O_RDONLY, 0)) < 0)	  {	    perror_with_name (cmp.file[0].name);	    status = EXIT_TROUBLE;	  }      if (cmp.file[1].desc == UNOPENED)	{	  if (same_files)	    cmp.file[1].desc = cmp.file[0].desc;	  else if ((cmp.file[1].desc = open (cmp.file[1].name, O_RDONLY, 0))		   < 0)	    {	      perror_with_name (cmp.file[1].name);	      status = EXIT_TROUBLE;	    }	}#if HAVE_SETMODE_DOS      if (binary)	for (f = 0; f < 2; f++)	  if (0 <= cmp.file[f].desc)	    set_binary_mode (cmp.file[f].desc, true);#endif      /* Compare the files, if no error was found.  */      if (status == EXIT_SUCCESS)	status = diff_2_files (&cmp);      /* Close the file descriptors.  */      if (0 <= cmp.file[0].desc && close (cmp.file[0].desc) != 0)	{	  perror_with_name (cmp.file[0].name);	  status = EXIT_TROUBLE;	}      if (0 <= cmp.file[1].desc && cmp.file[0].desc != cmp.file[1].desc	  && close (cmp.file[1].desc) != 0)	{	  perror_with_name (cmp.file[1].name);	  status = EXIT_TROUBLE;	}    }  /* Now the comparison has been done, if no error prevented it,     and STATUS is the value this function will return.  */  if (status == EXIT_SUCCESS)    {      if (report_identical_files && !DIR_P (0))	message ("Files %s and %s are identical\n",		 file_label[0] ? file_label[0] : cmp.file[0].name,		 file_label[1] ? file_label[1] : cmp.file[1].name);    }  else    {      /* Flush stdout so that the user sees differences immediately.	 This can hurt performance, unfortunately.  */      if (fflush (stdout) != 0)	pfatal_with_name (_("standard output"));    }  if (free0)    free (free0);  if (free1)    free (free1);  return status;}

⌨️ 快捷键说明

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