/* pcresearch.c - searching subroutines using PCRE for grep. Copyright 2000, 2007, 2009-2016 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_LIBPCRE # include /* This must be at least 2; everything after that is for performance in pcre_exec. */ enum { NSUB = 300 }; /* Compiled internal form of a Perl regular expression. */ static pcre *cre; /* Additional information about the pattern. */ static pcre_extra *extra; # ifndef PCRE_STUDY_JIT_COMPILE # define PCRE_STUDY_JIT_COMPILE 0 # endif # if PCRE_STUDY_JIT_COMPILE /* Maximum size of the JIT stack. */ static int jit_stack_size; # endif /* Match the already-compiled PCRE pattern against the data in SUBJECT, of size SEARCH_BYTES and starting with offset SEARCH_OFFSET, with options OPTIONS, and storing resulting matches into SUB. Return the (nonnegative) match location or a (negative) error number. */ static int jit_exec (char const *subject, int search_bytes, int search_offset, int options, int *sub) { while (true) { int e = pcre_exec (cre, extra, subject, search_bytes, search_offset, options, sub, NSUB); # if PCRE_STUDY_JIT_COMPILE if (e == PCRE_ERROR_JIT_STACKLIMIT && 0 < jit_stack_size && jit_stack_size <= INT_MAX / 2) { int old_size = jit_stack_size; int new_size = jit_stack_size = old_size * 2; static pcre_jit_stack *jit_stack; if (jit_stack) pcre_jit_stack_free (jit_stack); jit_stack = pcre_jit_stack_alloc (old_size, new_size); if (!jit_stack) error (EXIT_TROUBLE, 0, _("failed to allocate memory for the PCRE JIT stack")); pcre_assign_jit_stack (extra, NULL, jit_stack); continue; } # endif return e; } } #endif #if HAVE_LIBPCRE /* Table, indexed by ! (flag & PCRE_NOTBOL), of whether the empty string matches when that flag is used. */ static int empty_match[2]; static bool multibyte_locale; #endif 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; static char const wprefix[] = "(?