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

📄 diff.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
/* GNU DIFF main routine.   Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.This file is part of GNU DIFF.GNU DIFF is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU DIFF; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  *//* GNU DIFF was written by Mike Haertel, David Hayes,   Richard Stallman, Len Tower, and Paul Eggert.  *//* $FreeBSD: src/contrib/diff/diff.c,v 1.3 1999/11/26 02:51:44 obrien Exp $ */#define GDIFF_MAIN#include "diff.h"#include <signal.h>#include "getopt.h"#ifdef __FreeBSD__#include <locale.h>#include <fnmatch.h>#else#include "fnmatch.h"#endif#include "prepend_args.h"#ifndef DEFAULT_WIDTH#define DEFAULT_WIDTH 130#endif#ifndef GUTTER_WIDTH_MINIMUM#define GUTTER_WIDTH_MINIMUM 3#endifstatic char const *filetype PARAMS((struct stat const *));static char *option_list PARAMS((char **, int));static int add_exclude_file PARAMS((char const *));static int ck_atoi PARAMS((char const *, int *));static int compare_files PARAMS((char const *, char const *, char const *, char const *, int));static int specify_format PARAMS((char **, char *));static void add_exclude PARAMS((char const *));static void add_regexp PARAMS((struct regexp_list **, char const *));static void specify_style PARAMS((enum output_style));static void try_help PARAMS((char const *));static void check_stdout PARAMS((void));static void usage PARAMS((void));/* Nonzero for -r: if comparing two directories,   compare their common subdirectories recursively.  */static int recursive;/* For debugging: don't do discard_confusing_lines.  */int no_discards;#if HAVE_SETMODE/* I/O mode: nonzero only if using binary input/output.  */static int binary_I_O;#endif/* Return a string containing the command options with which diff was invoked.   Spaces appear between what were separate ARGV-elements.   There is a space at the beginning but none at the end.   If there were no options, the result is an empty string.   Arguments: OPTIONVEC, a vector containing separate ARGV-elements, and COUNT,   the length of that vector.  */static char *option_list (optionvec, count)     char **optionvec;  /* Was `vector', but that collides on Alliant.  */     int count;{  int i;  size_t length = 0;  char *result;  for (i = 0; i < count; i++)    length += strlen (optionvec[i]) + 1;  result = xmalloc (length + 1);  result[0] = 0;  for (i = 0; i < count; i++)    {      strcat (result, " ");      strcat (result, optionvec[i]);    }  return result;}/* Convert STR to a positive integer, storing the result in *OUT.   If STR is not a valid integer, return -1 (otherwise 0). */static intck_atoi (str, out)     char const *str;     int *out;{  char const *p;  for (p = str; *p; p++)    if (*p < '0' || *p > '9')      return -1;  *out = atoi (optarg);  return 0;}/* Keep track of excluded file name patterns.  */static char const **exclude;static int exclude_alloc, exclude_count;intexcluded_filename (f)     char const *f;{  int i;  for (i = 0;  i < exclude_count;  i++)    if (fnmatch (exclude[i], f, 0) == 0)      return 1;  return 0;}static voidadd_exclude (pattern)     char const *pattern;{  if (exclude_alloc <= exclude_count)    exclude = (char const **)	      (exclude_alloc == 0	       ? xmalloc ((exclude_alloc = 64) * sizeof (*exclude))	       : xrealloc (exclude, (exclude_alloc *= 2) * sizeof (*exclude)));  exclude[exclude_count++] = pattern;}static intadd_exclude_file (name)     char const *name;{  struct file_data f;  char *p, *q, *lim;  f.name = optarg;  f.desc = (strcmp (name, "-") == 0	    ? STDIN_FILENO	    : open (name, O_RDONLY, 0));  if (f.desc < 0 || fstat (f.desc, &f.stat) != 0)    return -1;  sip (&f, 1);  slurp (&f);  for (p = f.buffer, lim = p + f.buffered_chars;  p < lim;  p = q)    {      q = (char *) memchr (p, '\n', lim - p);      if (!q)	q = lim;      *q++ = 0;      add_exclude (p);    }  return close (f.desc);}/* The numbers 129- that appear in the fourth element of some entries   tell the big switch in `main' how to process those options.  */static struct option const longopts[] ={  {"ignore-blank-lines", 0, 0, 'B'},  {"context", 2, 0, 'C'},  {"ifdef", 1, 0, 'D'},  {"show-function-line", 1, 0, 'F'},  {"speed-large-files", 0, 0, 'H'},  {"ignore-matching-lines", 1, 0, 'I'},  {"label", 1, 0, 'L'},  {"file-label", 1, 0, 'L'},	/* An alias, no longer recommended */  {"new-file", 0, 0, 'N'},  {"entire-new-file", 0, 0, 'N'},	/* An alias, no longer recommended */  {"unidirectional-new-file", 0, 0, 'P'},  {"starting-file", 1, 0, 'S'},  {"initial-tab", 0, 0, 'T'},  {"width", 1, 0, 'W'},  {"text", 0, 0, 'a'},  {"ascii", 0, 0, 'a'},		/* An alias, no longer recommended */  {"ignore-space-change", 0, 0, 'b'},  {"minimal", 0, 0, 'd'},  {"ed", 0, 0, 'e'},  {"forward-ed", 0, 0, 'f'},  {"ignore-case", 0, 0, 'i'},  {"paginate", 0, 0, 'l'},  {"print", 0, 0, 'l'},		/* An alias, no longer recommended */  {"rcs", 0, 0, 'n'},  {"show-c-function", 0, 0, 'p'},  {"brief", 0, 0, 'q'},  {"recursive", 0, 0, 'r'},  {"report-identical-files", 0, 0, 's'},  {"expand-tabs", 0, 0, 't'},  {"version", 0, 0, 'v'},  {"ignore-all-space", 0, 0, 'w'},  {"exclude", 1, 0, 'x'},  {"exclude-from", 1, 0, 'X'},  {"side-by-side", 0, 0, 'y'},  {"unified", 2, 0, 'U'},  {"left-column", 0, 0, 129},  {"suppress-common-lines", 0, 0, 130},  {"sdiff-merge-assist", 0, 0, 131},  {"old-line-format", 1, 0, 132},  {"new-line-format", 1, 0, 133},  {"unchanged-line-format", 1, 0, 134},  {"line-format", 1, 0, 135},  {"old-group-format", 1, 0, 136},  {"new-group-format", 1, 0, 137},  {"unchanged-group-format", 1, 0, 138},  {"changed-group-format", 1, 0, 139},  {"horizon-lines", 1, 0, 140},  {"help", 0, 0, 141},  {"binary", 0, 0, 142},  {0, 0, 0, 0}};intmain (argc, argv)     int argc;     char *argv[];{  int val;  int c;  int prev = -1;  int width = DEFAULT_WIDTH;  int show_c_function = 0;#ifdef __FreeBSD__  setlocale(LC_ALL, "");#endif  /* Do our initializations.  */  initialize_main (&argc, &argv);  program_name = argv[0];  output_style = OUTPUT_NORMAL;  context = -1;  prepend_default_options (getenv ("DIFF_OPTIONS"), &argc, &argv);  /* Decode the options.  */  while ((c = getopt_long (argc, argv,			   "0123456789abBcC:dD:efF:hHiI:lL:nNopPqrsS:tTuU:vwW:x:X:y",			   longopts, 0)) != EOF)    {      switch (c)	{	  /* All digits combine in decimal to specify the context-size.  */	case '1':	case '2':	case '3':	case '4':	case '5':	case '6':	case '7':	case '8':	case '9':	case '0':	  if (context == -1)	    context = 0;	  /* If a context length has already been specified,	     more digits allowed only if they follow right after the others.	     Reject two separate runs of digits, or digits after -C.  */	  else if (prev < '0' || prev > '9')	    fatal ("context length specified twice");	  context = context * 10 + c - '0';	  break;	case 'a':	  /* Treat all files as text files; never treat as binary.  */	  always_text_flag = 1;	  break;	case 'b':	  /* Ignore changes in amount of white space.  */	  ignore_space_change_flag = 1;	  ignore_some_changes = 1;	  ignore_some_line_changes = 1;	  break;	case 'B':	  /* Ignore changes affecting only blank lines.  */	  ignore_blank_lines_flag = 1;	  ignore_some_changes = 1;	  break;	case 'C':		/* +context[=lines] */	case 'U':		/* +unified[=lines] */	  if (optarg)	    {	      if (context >= 0)		fatal ("context length specified twice");	      if (ck_atoi (optarg, &context))		fatal ("invalid context length argument");	    }	  /* Falls through.  */	case 'c':	  /* Make context-style output.  */	  specify_style (c == 'U' ? OUTPUT_UNIFIED : OUTPUT_CONTEXT);	  break;	case 'd':	  /* Don't discard lines.  This makes things slower (sometimes much	     slower) but will find a guaranteed minimal set of changes.  */	  no_discards = 1;	  break;	case 'D':	  /* Make merged #ifdef output.  */	  specify_style (OUTPUT_IFDEF);	  {	    int i, err = 0;	    static char const C_ifdef_group_formats[] =	      "#ifndef %s\n%%<#endif /* not %s */\n%c#ifdef %s\n%%>#endif /* %s */\n%c%%=%c#ifndef %s\n%%<#else /* %s */\n%%>#endif /* %s */\n";	    char *b = xmalloc (sizeof (C_ifdef_group_formats)			       + 7 * strlen(optarg) - 14 /* 7*"%s" */			       - 8 /* 5*"%%" + 3*"%c" */);	    sprintf (b, C_ifdef_group_formats,		     optarg, optarg, 0,		     optarg, optarg, 0, 0,		     optarg, optarg, optarg);	    for (i = 0; i < 4; i++)	      {		err |= specify_format (&group_format[i], b);		b += strlen (b) + 1;	      }	    if (err)	      error ("conflicting #ifdef formats", 0, 0);	  }	  break;	case 'e':	  /* Make output that is a valid `ed' script.  */	  specify_style (OUTPUT_ED);	  break;	case 'f':	  /* Make output that looks vaguely like an `ed' script	     but has changes in the order they appear in the file.  */	  specify_style (OUTPUT_FORWARD_ED);	  break;	case 'F':	  /* Show, for each set of changes, the previous line that	     matches the specified regexp.  Currently affects only	     context-style output.  */	  add_regexp (&function_regexp_list, optarg);	  break;	case 'h':	  /* Split the files into chunks of around 1500 lines	     for faster processing.  Usually does not change the result.	     This currently has no effect.  */	  break;

⌨️ 快捷键说明

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