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

📄 grep.c

📁 linux平台中
💻 C
📖 第 1 页 / 共 4 页
字号:
 finish_grep:  done_on_match -= not_text;  out_quiet -= not_text;  if ((not_text & ~out_quiet) && nlines != 0)    printf (_("Binary file %s matches\n"), filename);  return nlines;}static intgrepfile (char const *file, struct stats *stats){  int desc;  int count;  int status;  if (! file)    {      desc = 0;      filename = label ? label : _("(standard input)");    }  else    {      while ((desc = open (file, O_RDONLY)) < 0 && errno == EINTR)	continue;      if (desc < 0)	{	  int e = errno;	  if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES)	    {	      if (stat (file, &stats->stat) != 0)		{		  error (0, errno, "%s", file);		  return 1;		}	      return grepdir (file, stats);	    }	  if (!suppress_errors)	    {	      if (directories == SKIP_DIRECTORIES)		switch (e)		  {#if defined(EISDIR)		  case EISDIR:		    return 1;#endif		  case EACCES:		    /* When skipping directories, don't worry about		       directories that can't be opened.  */		    if (isdir (file))		      return 1;		    break;		  }	    }	  suppressible_error (file, e);	  return 1;	}      filename = file;    }#if defined(SET_BINARY)  /* Set input to binary mode.  Pipes are simulated with files     on DOS, so this includes the case of "foo | grep bar".  */  if (!isatty (desc))    SET_BINARY (desc);#endif  count = grep (desc, file, stats);  if (count < 0)    status = count + 2;  else    {      if (count_matches)	{	  if (out_file)	    printf ("%s%c", filename, ':' & filename_mask);	  printf ("%d\n", count);	}      status = !count;      if (list_files == 1 - 2 * status)	printf ("%s%c", filename, '\n' & filename_mask);      if (! file)	{	  off_t required_offset = outleft ? bufoffset : after_last_match;	  if ((bufmapped || required_offset != bufoffset)	      && lseek (desc, required_offset, SEEK_SET) < 0	      && S_ISREG (stats->stat.st_mode))	    error (0, errno, "%s", filename);	}      else	while (close (desc) != 0)	  if (errno != EINTR)	    {	      error (0, errno, "%s", file);	      break;	    }    }  return status;}static intgrepdir (char const *dir, struct stats const *stats){  int status = 1;  struct stats const *ancestor;  char *name_space;  /* Mingw32 does not support st_ino.  No known working hosts use zero     for st_ino, so assume that the Mingw32 bug applies if it's zero.  */  if (stats->stat.st_ino)    for (ancestor = stats;  (ancestor = ancestor->parent) != 0;  )      if (ancestor->stat.st_ino == stats->stat.st_ino	  && ancestor->stat.st_dev == stats->stat.st_dev)	{	  if (!suppress_errors)	    error (0, 0, _("warning: %s: %s\n"), dir,		   _("recursive directory loop"));	  return 1;	}  name_space = savedir (dir, stats->stat.st_size, included_patterns,			excluded_patterns);  if (! name_space)    {      if (errno)	suppressible_error (dir, errno);      else	xalloc_die ();    }  else    {      size_t dirlen = strlen (dir);      int needs_slash = ! (dirlen == FILESYSTEM_PREFIX_LEN (dir)			   || IS_SLASH (dir[dirlen - 1]));      char *file = NULL;      char const *namep = name_space;      struct stats child;      child.parent = stats;      out_file += !no_filenames;      while (*namep)	{	  size_t namelen = strlen (namep);	  file = xrealloc (file, dirlen + 1 + namelen + 1);	  strcpy (file, dir);	  file[dirlen] = '/';	  strcpy (file + dirlen + needs_slash, namep);	  namep += namelen + 1;	  status &= grepfile (file, &child);	}      out_file -= !no_filenames;      if (file)        free (file);      free (name_space);    }  return status;}static voidusage (int status){  if (status != 0)    {      fprintf (stderr, _("Usage: %s [OPTION]... PATTERN [FILE]...\n"),	       program_name);      fprintf (stderr, _("Try `%s --help' for more information.\n"),	       program_name);    }  else    {      printf (_("Usage: %s [OPTION]... PATTERN [FILE] ...\n"), program_name);      printf (_("\Search for PATTERN in each FILE or standard input.\n\Example: %s -i 'hello world' menu.h main.c\n\\n\Regexp selection and interpretation:\n"), program_name);      printf (_("\  -E, --extended-regexp     PATTERN is an extended regular expression\n\  -F, --fixed-strings       PATTERN is a set of newline-separated strings\n\  -G, --basic-regexp        PATTERN is a basic regular expression\n\  -P, --perl-regexp         PATTERN is a Perl regular expression\n"));      printf (_("\  -e, --regexp=PATTERN      use PATTERN as a regular expression\n\  -f, --file=FILE           obtain PATTERN from FILE\n\  -i, --ignore-case         ignore case distinctions\n\  -w, --word-regexp         force PATTERN to match only whole words\n\  -x, --line-regexp         force PATTERN to match only whole lines\n\  -z, --null-data           a data line ends in 0 byte, not newline\n"));      printf (_("\\n\Miscellaneous:\n\  -s, --no-messages         suppress error messages\n\  -v, --invert-match        select non-matching lines\n\  -V, --version             print version information and exit\n\      --help                display this help and exit\n\      --mmap                use memory-mapped input if possible\n"));      printf (_("\\n\Output control:\n\  -m, --max-count=NUM       stop after NUM matches\n\  -b, --byte-offset         print the byte offset with output lines\n\  -n, --line-number         print line number with output lines\n\      --line-buffered       flush output on every line\n\  -H, --with-filename       print the filename for each match\n\  -h, --no-filename         suppress the prefixing filename on output\n\      --label=LABEL         print LABEL as filename for standard input\n\  -o, --only-matching       show only the part of a line matching PATTERN\n\  -q, --quiet, --silent     suppress all normal output\n\      --binary-files=TYPE   assume that binary files are TYPE\n\                            TYPE is 'binary', 'text', or 'without-match'\n\  -a, --text                equivalent to --binary-files=text\n\  -I                        equivalent to --binary-files=without-match\n\  -d, --directories=ACTION  how to handle directories\n\                            ACTION is 'read', 'recurse', or 'skip'\n\  -D, --devices=ACTION      how to handle devices, FIFOs and sockets\n\                            ACTION is 'read' or 'skip'\n\  -R, -r, --recursive       equivalent to --directories=recurse\n\      --include=PATTERN     files that match PATTERN will be examined\n\      --exclude=PATTERN     files that match PATTERN will be skipped.\n\      --exclude-from=FILE   files that match PATTERN in FILE will be skipped.\n\  -L, --files-without-match only print FILE names containing no match\n\  -l, --files-with-matches  only print FILE names containing matches\n\  -c, --count               only print a count of matching lines per FILE\n\  -Z, --null                print 0 byte after FILE name\n"));      printf (_("\\n\Context control:\n\  -B, --before-context=NUM  print NUM lines of leading context\n\  -A, --after-context=NUM   print NUM lines of trailing context\n\  -C, --context=NUM         print NUM lines of output context\n\  -NUM                      same as --context=NUM\n\      --color[=WHEN],\n\      --colour[=WHEN]       use markers to distinguish the matching string\n\                            WHEN may be `always', `never' or `auto'.\n\  -U, --binary              do not strip CR characters at EOL (MSDOS)\n\  -u, --unix-byte-offsets   report offsets as if CRs were not there (MSDOS)\n\\n\`egrep' means `grep -E'.  `fgrep' means `grep -F'.\n\With no FILE, or when FILE is -, read standard input.  If less than\n\two FILEs given, assume -h.  Exit status is 0 if match, 1 if no match,\n\and 2 if trouble.\n"));      printf (_("\nReport bugs to <bug-gnu-utils@gnu.org>.\n"));    }  exit (status);}/* Set the matcher to M, reporting any conflicts.  */static voidsetmatcher (char const *m){  if (matcher && strcmp (matcher, m) != 0)    error (2, 0, _("conflicting matchers specified"));  matcher = m;}/* Go through the matchers vector and look for the specified matcher.   If we find it, install it in compile and execute, and return 1.  */static intinstall_matcher (char const *name){  int i;#if defined(HAVE_SETRLIMIT)  struct rlimit rlim;#endif  for (i = 0; matchers[i].compile; i++)    if (strcmp (name, matchers[i].name) == 0)      {	compile = matchers[i].compile;	execute = matchers[i].execute;#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK)	/* I think every platform needs to do this, so that regex.c	   doesn't oveflow the stack.  The default value of	   `re_max_failures' is too large for some platforms: it needs	   more than 3MB-large stack.	   The test for HAVE_SETRLIMIT should go into `configure'.  */	if (!getrlimit (RLIMIT_STACK, &rlim))	  {	    long newlim;	    extern long int re_max_failures; /* from regex.c */	    /* Approximate the amount regex.c needs, plus some more.  */	    newlim = re_max_failures * 2 * 20 * sizeof (char *);	    if (newlim > rlim.rlim_max)	      {		newlim = rlim.rlim_max;		re_max_failures = newlim / (2 * 20 * sizeof (char *));	      }	    if (rlim.rlim_cur < newlim)	      {		rlim.rlim_cur = newlim;		setrlimit (RLIMIT_STACK, &rlim);	      }	  }#endif	return 1;      }  return 0;}/* Find the white-space-separated options specified by OPTIONS, and   using BUF to store copies of these options, set ARGV[0], ARGV[1],   etc. to the option copies.  Return the number N of options found.   Do not set ARGV[N] to NULL.  If ARGV is NULL, do not store ARGV[0]   etc.  Backslash can be used to escape whitespace (and backslashes).  */static intprepend_args (char const *options, char *buf, char **argv){  char const *o = options;  char *b = buf;  int n = 0;  for (;;)    {      while (ISSPACE ((unsigned char) *o))	o++;      if (!*o)	return n;      if (argv)	argv[n] = b;      n++;      do	if ((*b++ = *o++) == '\\' && *o)	  b[-1] = *o++;      while (*o && ! ISSPACE ((unsigned char) *o));      *b++ = '\0';    }}/* Prepend the whitespace-separated options in OPTIONS to the argument   vector of a main program with argument count *PARGC and argument   vector *PARGV.  */static voidprepend_default_options (char const *options, int *pargc, char ***pargv){  if (options)    {      char *buf = xmalloc (strlen (options) + 1);      int prepended = prepend_args (options, buf, (char **) NULL);      int argc = *pargc;      char * const *argv = *pargv;      char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);      *pargc = prepended + argc;      *pargv = pp;      *pp++ = *argv++;      pp += prepend_args (options, buf, pp);      while ((*pp++ = *argv++))	continue;    }}/* Get the next non-digit option from ARGC and ARGV.   Return -1 if there are no more options.   Process any digit options that were encountered on the way,   and store the resulting integer into *DEFAULT_CONTEXT.  */static intget_nondigit_option (int argc, char *const *argv, int *default_context){  int opt;  char buf[sizeof (uintmax_t) * CHAR_BIT + 4];  char *p = buf;  /* Set buf[0] to anything but '0', for the leading-zero test below.  */  buf[0] = '\0';  while (opt = getopt_long (argc, argv, short_options, long_options, NULL),	 '0' <= opt && opt <= '9')    {      /* Suppress trivial leading zeros, to avoid incorrect	 diagnostic on strings like 00000000000.  */      p -= buf[0] == '0';      *p++ = opt;      if (p == buf + sizeof buf - 4)	{	  /* Too many digits.  Append "..." to make context_length_arg	     complain about "X...", where X contains the digits seen	     so far.  */	  strcpy (p, "...");	  p += 3;	  break;	}    }  if (p != buf)    {      *p = '\0';      context_length_arg (buf, default_context);    }  return opt;}intmain (int argc, char **argv){  char *keys;  size_t keycc, oldcc, keyalloc;  int with_filenames;  int opt, cc, status;  int default_context;  FILE *fp;  extern char *optarg;  extern int optind;  initialize_main (&argc, &argv);  program_name = argv[0];  if (program_name && strrchr (program_name, '/'))    program_name = strrchr (program_name, '/') + 1;  if (!strcmp(program_name, "egrep"))    setmatcher ("egrep");  if (!strcmp(program_name, "fgrep"))    setmatcher ("fgrep");#if defined(__MSDOS__) || defined(_WIN32)  /* DOS and MS-Windows use backslashes as directory separators, and usually     have an .exe suffix.  They also have case-insensitive filesystems.  */  if (program_name)    {      char *p = program_name;      char *bslash = strrchr (argv[0], '\\');      if (bslash && bslash >= program_name) /* for mixed forward/backslash case */

⌨️ 快捷键说明

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