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

📄 grep.c

📁 linux平台中
💻 C
📖 第 1 页 / 共 4 页
字号:
static int filename_mask;	/* If zero, output nulls after filenames.  */static int out_quiet;		/* Suppress all normal output. */static int out_invert;		/* Print nonmatching stuff. */static int out_file;		/* Print filenames. */static int out_line;		/* Print line numbers. */static int out_byte;		/* Print byte offsets. */static int out_before;		/* Lines of leading context. */static int out_after;		/* Lines of trailing context. */static int count_matches;	/* Count matching lines.  */static int list_files;		/* List matching files.  */static int no_filenames;	/* Suppress file names.  */static off_t max_count;		/* Stop after outputting this many				   lines from an input file.  */static int line_buffered;       /* If nonzero, use line buffering, i.e.				   fflush everyline out.  */static char *label = NULL;      /* Fake filename for stdin *//* Internal variables to keep track of byte count, context, etc. */static uintmax_t totalcc;	/* Total character count before bufbeg. */static char const *lastnl;	/* Pointer after last newline counted. */static char const *lastout;	/* Pointer after last character output;				   NULL if no character has been output				   or if it's conceptually before bufbeg. */static uintmax_t totalnl;	/* Total newline count before lastnl. */static off_t outleft;		/* Maximum number of lines to be output.  */static int pending;		/* Pending lines of output.				   Always kept 0 if out_quiet is true.  */static int done_on_match;	/* Stop scanning file on first match.  */static int exit_on_match;	/* Exit on first match.  */#if defined(HAVE_DOS_FILE_CONTENTS)# include "dosbuf.c"#endif/* Add two numbers that count input bytes or lines, and report an   error if the addition overflows.  */static uintmax_tadd_count (uintmax_t a, uintmax_t b){  uintmax_t sum = a + b;  if (sum < a)    error (2, 0, _("input is too large to count"));  return sum;}static voidnlscan (char const *lim){  size_t newlines = 0;  char const *beg;  for (beg = lastnl; beg != lim; beg = memchr (beg, eolbyte, lim - beg), beg++)    newlines++;  totalnl = add_count (totalnl, newlines);  lastnl = lim;}/* Print a byte offset, followed by a character separator.  */static voidprint_offset_sep (uintmax_t pos, char sep){  /* Do not rely on printf to print pos, since uintmax_t may be longer     than long, and long long is not portable.  */  char buf[sizeof pos * CHAR_BIT];  char *p = buf + sizeof buf - 1;  *p = sep;  do    *--p = '0' + pos % 10;  while ((pos /= 10) != 0);  fwrite (p, 1, buf + sizeof buf - p, stdout);}static voidprline (char const *beg, char const *lim, int sep){  if (out_file)    printf ("%s%c", filename, sep & filename_mask);  if (out_line)    {      nlscan (beg);      totalnl = add_count (totalnl, 1);      print_offset_sep (totalnl, sep);      lastnl = lim;    }  if (out_byte)    {      uintmax_t pos = add_count (totalcc, beg - bufbeg);#if defined(HAVE_DOS_FILE_CONTENTS)      pos = dossified_pos (pos);#endif      print_offset_sep (pos, sep);    }  if (only_matching)    {      size_t match_size;      size_t match_offset;      while ((match_offset = (*execute) (beg, lim - beg, &match_size, 1))	  != (size_t) -1)        {	  char const *b = beg + match_offset;	  if (b == lim)	    break;	  if(color_option)	    printf("\33[%sm", grep_color);	  fwrite(b, sizeof (char), match_size, stdout);	  if(color_option)	    fputs("\33[00m", stdout);	  fputs("\n", stdout);	  beg = b + match_size;        }      lastout = lim;      if(line_buffered)	fflush(stdout);      return;    }  if (color_option)    {      size_t match_size;      size_t match_offset;      if(match_icase)        {	  /* Yuck, this is tricky */          char *buf = (char*) xmalloc (lim - beg);	  char *ibeg = buf;	  char *ilim = ibeg + (lim - beg);	  int i;	  for (i = 0; i < lim - beg; i++)	    ibeg[i] = tolower (beg[i]);	  while ((match_offset = (*execute) (ibeg, ilim-ibeg, &match_size, 1))		 != (size_t) -1)	    {	      char const *b = beg + match_offset;	      if (b == lim)		break;	      fwrite (beg, sizeof (char), match_offset, stdout);	      printf ("\33[%sm", grep_color);	      fwrite (b, sizeof (char), match_size, stdout);	      fputs ("\33[00m", stdout);	      beg = b + match_size;	      ibeg = ibeg + match_offset + match_size;	    }	  fwrite (beg, 1, lim - beg, stdout);	  free (buf);	  lastout = lim;	  return;	}      while ((match_offset = (*execute) (beg, lim - beg, &match_size, 1))	     != (size_t) -1)	{	  char const *b = beg + match_offset;	  /* Avoid matching the empty line at the end of the buffer. */	  if (b == lim)	    break;	  fwrite (beg, sizeof (char), match_offset, stdout);	  printf ("\33[%sm", grep_color);	  fwrite (b, sizeof (char), match_size, stdout);	  fputs ("\33[00m", stdout);	  beg = b + match_size;	}    }  fwrite (beg, 1, lim - beg, stdout);  if (ferror (stdout))    error (0, errno, _("writing output"));  lastout = lim;  if (line_buffered)    fflush (stdout);}/* Print pending lines of trailing context prior to LIM. Trailing context ends   at the next matching line when OUTLEFT is 0.  */static voidprpending (char const *lim){  if (!lastout)    lastout = bufbeg;  while (pending > 0 && lastout < lim)    {      char const *nl = memchr (lastout, eolbyte, lim - lastout);      size_t match_size;      --pending;      if (outleft	  || (((*execute) (lastout, nl - lastout, &match_size, 0) == (size_t) -1)	      == !out_invert))	prline (lastout, nl + 1, '-');      else	pending = 0;    }}/* Print the lines between BEG and LIM.  Deal with context crap.   If NLINESP is non-null, store a count of lines between BEG and LIM.  */static voidprtext (char const *beg, char const *lim, int *nlinesp){  static int used;		/* avoid printing "--" before any output */  char const *bp, *p;  char eol = eolbyte;  int i, n;  if (!out_quiet && pending > 0)    prpending (beg);  p = beg;  if (!out_quiet)    {      /* Deal with leading context crap. */      bp = lastout ? lastout : bufbeg;      for (i = 0; i < out_before; ++i)	if (p > bp)	  do	    --p;	  while (p[-1] != eol);      /* We only print the "--" separator if our output is	 discontiguous from the last output in the file. */      if ((out_before || out_after) && used && p != lastout)	puts ("--");      while (p < beg)	{	  char const *nl = memchr (p, eol, beg - p);	  nl++;	  prline (p, nl, '-');	  p = nl;	}    }  if (nlinesp)    {      /* Caller wants a line count. */      for (n = 0; p < lim && n < outleft; n++)	{	  char const *nl = memchr (p, eol, lim - p);	  nl++;	  if (!out_quiet)	    prline (p, nl, ':');	  p = nl;	}      *nlinesp = n;      /* relying on it that this function is never called when outleft = 0.  */      after_last_match = bufoffset - (buflim - p);    }  else    if (!out_quiet)      prline (beg, lim, ':');  pending = out_quiet ? 0 : out_after;  used = 1;}/* Scan the specified portion of the buffer, matching lines (or   between matching lines if OUT_INVERT is true).  Return a count of   lines printed. */static intgrepbuf (char const *beg, char const *lim){  int nlines, n;  register char const *p;  size_t match_offset;  size_t match_size;  nlines = 0;  p = beg;  while ((match_offset = (*execute) (p, lim - p, &match_size, 0)) != (size_t) -1)    {      char const *b = p + match_offset;      char const *endp = b + match_size;      /* Avoid matching the empty line at the end of the buffer. */      if (b == lim)	break;      if (!out_invert)	{	  prtext (b, endp, (int *) 0);	  nlines++;          outleft--;	  if (!outleft || done_on_match)	    {	      if (exit_on_match)		exit (0);	      after_last_match = bufoffset - (buflim - endp);	      return nlines;	    }	}      else if (p < b)	{	  prtext (p, b, &n);	  nlines += n;          outleft -= n;	  if (!outleft)	    return nlines;	}      p = endp;    }  if (out_invert && p < lim)    {      prtext (p, lim, &n);      nlines += n;      outleft -= n;    }  return nlines;}/* Search a given file.  Normally, return a count of lines printed;   but if the file is a directory and we search it recursively, then   return -2 if there was a match, and -1 otherwise.  */static intgrep (int fd, char const *file, struct stats *stats){  int nlines, i;  int not_text;  size_t residue, save;  char oldc;  char *beg;  char *lim;  char eol = eolbyte;  if (!reset (fd, file, stats))    return 0;  if (file && directories == RECURSE_DIRECTORIES      && S_ISDIR (stats->stat.st_mode))    {      /* Close fd now, so that we don't open a lot of file descriptors	 when we recurse deeply.  */      if (close (fd) != 0)	error (0, errno, "%s", file);      return grepdir (file, stats) - 2;    }  totalcc = 0;  lastout = 0;  totalnl = 0;  outleft = max_count;  after_last_match = 0;  pending = 0;  nlines = 0;  residue = 0;  save = 0;  if (! fillbuf (save, stats))    {      if (! is_EISDIR (errno, file))	suppressible_error (filename, errno);      return 0;    }  not_text = (((binary_files == BINARY_BINARY_FILES && !out_quiet)	       || binary_files == WITHOUT_MATCH_BINARY_FILES)	      && memchr (bufbeg, eol ? '\0' : '\200', buflim - bufbeg));  if (not_text && binary_files == WITHOUT_MATCH_BINARY_FILES)    return 0;  done_on_match += not_text;  out_quiet += not_text;  for (;;)    {      lastnl = bufbeg;      if (lastout)	lastout = bufbeg;      beg = bufbeg + save;      /* no more data to scan (eof) except for maybe a residue -> break */      if (beg == buflim)	break;      /* Determine new residue (the length of an incomplete line at the end of         the buffer, 0 means there is no incomplete last line).  */      oldc = beg[-1];      beg[-1] = eol;      for (lim = buflim; lim[-1] != eol; lim--)	continue;      beg[-1] = oldc;      if (lim == beg)	lim = beg - residue;      beg -= residue;      residue = buflim - lim;      if (beg < lim)	{	  if (outleft)	    nlines += grepbuf (beg, lim);	  if (pending)	    prpending (lim);	  if((!outleft && !pending) || (nlines && done_on_match && !out_invert))	    goto finish_grep;	}      /* The last OUT_BEFORE lines at the end of the buffer will be needed as	 leading context if there is a matching line at the begin of the	 next data. Make beg point to their begin.  */      i = 0;      beg = lim;      while (i < out_before && beg > bufbeg && beg != lastout)	{	  ++i;	  do	    --beg;	  while (beg[-1] != eol);	}      /* detect if leading context is discontinuous from last printed line.  */      if (beg != lastout)	lastout = 0;      /* Handle some details and read more data to scan.  */      save = residue + lim - beg;      if (out_byte)	totalcc = add_count (totalcc, buflim - bufbeg - save);      if (out_line)	nlscan (beg);      if (! fillbuf (save, stats))	{	  if (! is_EISDIR (errno, file))	    suppressible_error (filename, errno);	  goto finish_grep;	}    }  if (residue)    {      *buflim++ = eol;      if (outleft)	nlines += grepbuf (bufbeg + save - residue, buflim);      if (pending)        prpending (buflim);    }

⌨️ 快捷键说明

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