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

📄 pcregrep.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
      if (after_context > 0 || before_context > 0)        endhyphenpending = TRUE;      if (printname != NULL) fprintf(stdout, "%s:", printname);      if (number) fprintf(stdout, "%d:", linenumber);      /* In multiline mode, we want to print to the end of the line in which      the end of the matched string is found, so we adjust linelength and the      line number appropriately. Because the PCRE_FIRSTLINE option is set, the      start of the match will always be before the first newline sequence. */      if (multiline)        {        int ellength;        char *endmatch = ptr + offsets[1];        t = ptr;        while (t < endmatch)          {          t = end_of_line(t, endptr, &ellength);          if (t <= endmatch) linenumber++; else break;          }        endmatch = end_of_line(endmatch, endptr, &ellength);        linelength = endmatch - ptr - ellength;        }      /*** NOTE: Use only fwrite() to output the data line, so that binary      zeroes are treated as just another data character. */      /* This extra option, for Jeffrey Friedl's debugging requirements,      replaces the matched string, or a specific captured string if it exists,      with X. When this happens, colouring is ignored. */#ifdef JFRIEDL_DEBUG      if (S_arg >= 0 && S_arg < mrc)        {        int first = S_arg * 2;        int last  = first + 1;        fwrite(ptr, 1, offsets[first], stdout);        fprintf(stdout, "X");        fwrite(ptr + offsets[last], 1, linelength - offsets[last], stdout);        }      else#endif      /* We have to split the line(s) up if colouring. */      if (do_colour)        {        fwrite(ptr, 1, offsets[0], stdout);        fprintf(stdout, "%c[%sm", 0x1b, colour_string);        fwrite(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);        fprintf(stdout, "%c[00m", 0x1b);        fwrite(ptr + offsets[1], 1, linelength - offsets[1], stdout);        }      else fwrite(ptr, 1, linelength + endlinelength, stdout);      }    /* End of doing what has to be done for a match */    rc = 0;    /* Had some success */    /* Remember where the last match happened for after_context. We remember    where we are about to restart, and that line's number. */    lastmatchrestart = ptr + linelength + endlinelength;    lastmatchnumber = linenumber + 1;    }  /* Advance to after the newline and increment the line number. */  ptr += linelength + endlinelength;  linenumber++;  /* If we haven't yet reached the end of the file (the buffer is full), and  the current point is in the top 1/3 of the buffer, slide the buffer down by  1/3 and refill it. Before we do this, if some unprinted "after" lines are  about to be lost, print them. */  if (bufflength >= sizeof(buffer) && ptr > buffer + 2*MBUFTHIRD)    {    if (after_context > 0 &&        lastmatchnumber > 0 &&        lastmatchrestart < buffer + MBUFTHIRD)      {      do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);      lastmatchnumber = 0;      }    /* Now do the shuffle */    memmove(buffer, buffer + MBUFTHIRD, 2*MBUFTHIRD);    ptr -= MBUFTHIRD;    bufflength = 2*MBUFTHIRD + fread(buffer + 2*MBUFTHIRD, 1, MBUFTHIRD, in);    endptr = buffer + bufflength;    /* Adjust any last match point */    if (lastmatchnumber > 0) lastmatchrestart -= MBUFTHIRD;    }  }     /* Loop through the whole file *//* End of file; print final "after" lines if wanted; do_after_lines setshyphenpending if it prints something. */if (!only_matching && !count_only)  {  do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);  hyphenpending |= endhyphenpending;  }/* Print the file name if we are looking for those without matches and therewere none. If we found a match, we won't have got this far. */if (filenames == FN_NOMATCH_ONLY)  {  fprintf(stdout, "%s\n", printname);  return 0;  }/* Print the match count if wanted */if (count_only)  {  if (printname != NULL) fprintf(stdout, "%s:", printname);  fprintf(stdout, "%d\n", count);  }return rc;}/**************************************************     Grep a file or recurse into a directory    **************************************************//* Given a path name, if it's a directory, scan all the files if we arerecursing; if it's a file, grep it.Arguments:  pathname          the path to investigate  dir_recurse       TRUE if recursing is wanted (-r or -drecurse)  only_one_at_top   TRUE if the path is the only one at toplevelReturns:   0 if there was at least one match           1 if there were no matches           2 there was some kind of errorHowever, file opening failures are suppressed if "silent" is set.*/static intgrep_or_recurse(char *pathname, BOOL dir_recurse, BOOL only_one_at_top){int rc = 1;int sep;FILE *in;/* If the file name is "-" we scan stdin */if (strcmp(pathname, "-") == 0)  {  return pcregrep(stdin,    (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))?      stdin_name : NULL);  }/* If the file is a directory, skip if skipping or if we are recursing, scaneach file within it, subject to any include or exclude patterns that were set.The scanning code is localized so it can be made system-specific. */if ((sep = isdirectory(pathname)) != 0)  {  if (dee_action == dee_SKIP) return 1;  if (dee_action == dee_RECURSE)    {    char buffer[1024];    char *nextfile;    directory_type *dir = opendirectory(pathname);    if (dir == NULL)      {      if (!silent)        fprintf(stderr, "pcregrep: Failed to open directory %s: %s\n", pathname,          strerror(errno));      return 2;      }    while ((nextfile = readdirectory(dir)) != NULL)      {      int frc, blen;      sprintf(buffer, "%.512s%c%.128s", pathname, sep, nextfile);      blen = strlen(buffer);      if (exclude_compiled != NULL &&          pcre_exec(exclude_compiled, NULL, buffer, blen, 0, 0, NULL, 0) >= 0)        continue;      if (include_compiled != NULL &&          pcre_exec(include_compiled, NULL, buffer, blen, 0, 0, NULL, 0) < 0)        continue;      frc = grep_or_recurse(buffer, dir_recurse, FALSE);      if (frc > 1) rc = frc;       else if (frc == 0 && rc == 1) rc = 0;      }    closedirectory(dir);    return rc;    }  }/* If the file is not a directory and not a regular file, skip it if that'sbeen requested. */else if (!isregfile(pathname) && DEE_action == DEE_SKIP) return 1;/* Control reaches here if we have a regular file, or if we have a directoryand recursion or skipping was not requested, or if we have anything else andskipping was not requested. The scan proceeds. If this is the first and onlyargument at top level, we don't show the file name, unless we are only showingthe file name, or the filename was forced (-H). */in = fopen(pathname, "r");if (in == NULL)  {  if (!silent)    fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname,      strerror(errno));  return 2;  }rc = pcregrep(in, (filenames > FN_DEFAULT ||  (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL);fclose(in);return rc;}/**************************************************                Usage function                  **************************************************/static intusage(int rc){option_item *op;fprintf(stderr, "Usage: pcregrep [-");for (op = optionlist; op->one_char != 0; op++)  {  if (op->one_char > 0) fprintf(stderr, "%c", op->one_char);  }fprintf(stderr, "] [long options] [pattern] [files]\n");fprintf(stderr, "Type `pcregrep --help' for more information.\n");return rc;}/**************************************************                Help function                   **************************************************/static voidhelp(void){option_item *op;printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n");printf("Search for PATTERN in each FILE or standard input.\n");printf("PATTERN must be present if neither -e nor -f is used.\n");printf("\"-\" can be used as a file name to mean STDIN.\n\n");printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n");printf("Options:\n");for (op = optionlist; op->one_char != 0; op++)  {  int n;  char s[4];  if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, "   ");  printf("  %s --%s%n", s, op->long_name, &n);  n = 30 - n;  if (n < 1) n = 1;  printf("%.*s%s\n", n, "                    ", op->help_text);  }printf("\nWhen reading patterns from a file instead of using a command line option,\n");printf("trailing white space is removed and blank lines are ignored.\n");printf("There is a maximum of %d patterns.\n", MAX_PATTERN_COUNT);printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n");printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n");}/**************************************************    Handle a single-letter, no data option      **************************************************/static inthandle_option(int letter, int options){switch(letter)  {  case N_HELP: help(); exit(0);  case 'c': count_only = TRUE; break;  case 'F': process_options |= PO_FIXED_STRINGS; break;  case 'H': filenames = FN_FORCE; break;  case 'h': filenames = FN_NONE; break;  case 'i': options |= PCRE_CASELESS; break;  case 'l': filenames = FN_ONLY; break;  case 'L': filenames = FN_NOMATCH_ONLY; break;  case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break;  case 'n': number = TRUE; break;  case 'o': only_matching = TRUE; break;  case 'q': quiet = TRUE; break;  case 'r': dee_action = dee_RECURSE; break;  case 's': silent = TRUE; break;  case 'u': options |= PCRE_UTF8; utf8 = TRUE; break;  case 'v': invert = TRUE; break;  case 'w': process_options |= PO_WORD_MATCH; break;  case 'x': process_options |= PO_LINE_MATCH; break;  case 'V':  fprintf(stderr, "pcregrep version %s using ", VERSION);  fprintf(stderr, "PCRE version %s\n", pcre_version());  exit(0);  break;  default:  fprintf(stderr, "pcregrep: Unknown option -%c\n", letter);  exit(usage(2));  }return options;}/**************************************************          Construct printed ordinal             **************************************************//* This turns a number into "1st", "3rd", etc. */static char *ordin(int n){static char buffer[8];char *p = buffer;sprintf(p, "%d", n);while (*p != 0) p++;switch (n%10)  {  case 1: strcpy(p, "st"); break;  case 2: strcpy(p, "nd"); break;  case 3: strcpy(p, "rd"); break;  default: strcpy(p, "th"); break;  }return buffer;}/**************************************************          Compile a single pattern              **************************************************//* When the -F option has been used, this is called for each substring.Otherwise it's called for each supplied pattern.Arguments:  pattern        the pattern string  options        the PCRE options  filename       the file name, or NULL for a command-line pattern  count          0 if this is the only command line pattern, or                 number of the command line pattern, or                 linenumber for a pattern from a fileReturns:         TRUE on success, FALSE after an error*/static BOOLcompile_single_pattern(char *pattern, int options, char *filename, int count){char buffer[MBUFTHIRD + 16];const char *error;int errptr;if (pattern_count >= MAX_PATTERN_COUNT)  {  fprintf(stderr, "pcregrep: Too many %spatterns (max %d)\n",    (filename == NULL)? "command-line " : "", MAX_PATTERN_COUNT);  return FALSE;  }sprintf(buffer, "%s%.*s%s", prefix[process_options], MBUFTHIRD, pattern,  suffix[process_options]);pattern_list[pattern_count] =  pcre_compile(buffer, options, &error, &errptr, pcretables);if (pattern_list[pattern_count++] != NULL) return TRUE;/* Handle compile errors */errptr -= (int)strlen(prefix[process_options]);if (errptr > (int)strlen(pattern)) errptr = (int)strlen(pattern);if (filename == NULL)  {  if (count == 0)    fprintf(stderr, "pcregrep: Error in command-line regex "      "at offset %d: %s\n", errptr, error);  else    fprintf(stderr, "pcregrep: Error in %s command-line regex "      "at offset %d: %s\n", ordin(count), errptr, error);  }else  {  fprintf(stderr, "pcregrep: Error in regex in line %d of %s "    "at offset %d: %s\n", count, filename, errptr, error);  }return FALSE;}/**************************************************           Compile one supplied pattern         **************************************************//* When the -F option has been used, each string may be a list of strings,separated by line breaks. They will be matched literally.Arguments:  pattern        the pattern string  options        the PCRE options  filename       the file name, or NULL for a command-line pattern  count          0 if this is the only command line pattern, or                 number of the command line pattern, or                 linenumber for a pattern from a fileReturns:         TRUE on success, FALSE after an error*/static BOOLcompile_pattern(char *pattern, int options, char *filename, int count){if ((process_options & PO_FIXED_STRINGS) != 0)  {  char *eop = pattern + strlen(pattern);  char buffer[MBUFTHIRD];  for(;;)    {    int ellength;    char *p = end_of_line(pattern, eop, &ellength);    if (ellength == 0)      return compile_single_pattern(pattern, options, filename, count);    sprintf(buffer, "%.*s", p - pattern - ellength, pattern);    pattern = p;    if (!compile_single_pattern(buffer, options, filename, count))      return FALSE;    }  }else return compile_single_pattern(pattern, options, filename, count);}/**************************************************                Main program                    **************************************************//* Returns 0 if something matched, 1 if nothing matched, 2 after an error. */intmain(int argc, char **argv){int i, j;int rc = 1;int pcre_options = 0;int cmd_pattern_count = 0;int errptr;BOOL only_one_at_top;char *patterns[MAX_PATTERN_COUNT];const char *locale_from = "--locale";const char *error;/* Set the default line ending value from the default in the PCRE library;"lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf".

⌨️ 快捷键说明

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