/* pcresearch.c - searching subroutines using PCRE for grep. Copyright 2000, 2007, 2009-2014 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* Written August 1992 by Mike Haertel. */ #include #include "search.h" #if HAVE_PCRE_H # include #elif HAVE_PCRE_PCRE_H # include #endif #if HAVE_LIBPCRE /* Compiled internal form of a Perl regular expression. */ static pcre *cre; /* Additional information about the pattern. */ static pcre_extra *extra; # ifdef PCRE_STUDY_JIT_COMPILE static pcre_jit_stack *jit_stack; # else # define PCRE_STUDY_JIT_COMPILE 0 # endif #endif /* Table, indexed by ! (flag & PCRE_NOTBOL), of whether the empty string matches when that flag is used. */ static int empty_match[2]; void Pcompile (char const *pattern, size_t size) { #if !HAVE_LIBPCRE error (EXIT_TROUBLE, 0, "%s", _("support for the -P option is not compiled into " "this --disable-perl-regexp binary")); #else int e; char const *ep; char *re = xnmalloc (4, size + 7); int flags = (PCRE_MULTILINE | (match_icase ? PCRE_CASELESS : 0)); char const *patlim = pattern + size; char *n = re; char const *p; char const *pnul; if (using_utf8 ()) flags |= PCRE_UTF8; else if (MB_CUR_MAX != 1) error (EXIT_TROUBLE, 0, _("-P supports only unibyte and UTF-8 locales")); /* FIXME: Remove these restrictions. */ if (memchr (pattern, '\n', size)) error (EXIT_TROUBLE, 0, _("the -P option only supports a single pattern")); *n = '\0'; if (match_lines) strcpy (n, "^(?:"); if (match_words) strcpy (n, "(?