FreeBSD/usr.bin/grep/regex/tre-fastmatch.c
/*
 * Executes matching of the precompiled pattern on the input string.
 * Returns REG_OK or REG_NOMATCH depending on if we find a match or not.
 */
Executes matching of the precompiled pattern on the input string.
Returns REG_OK or REG_NOMATCH depending on if we find a match or not.
Executes matching of the precompiled pattern on the input string . Returns REG_OK or REG_NOMATCH depending on if we find a match or not .
int
tre_match_fast(const fastmatch_t *fg, const void *data, size_t len,
    tre_str_type_t type, int nmatch, regmatch_t pmatch[], int eflags)
{
  unsigned int shift, u = 0, v = 0;
  ssize_t j = 0;
  int ret = REG_NOMATCH;
  int mismatch;
  const char *str_byte = data;
  const void *startptr = NULL;
  const tre_char_t *str_wide = data;
  if (len == (size_t)-1)
    switch (type)
      {
	case STR_WIDE:
	  len = tre_strlen(str_wide);
	  break;
	default:
	  len = strlen(str_byte);
	  break;
      }
  if (fg->matchall)
    {
      if (!fg->nosub && nmatch >= 1)
	{
	  pmatch[0].rm_so = 0;
	  pmatch[0].rm_eo = len;
	}
      if (fg->bol && fg->eol)
	return (len == 0) ? REG_OK : REG_NOMATCH;
      else
	return REG_OK;
    }
  switch (type)
    {
      case STR_WIDE:
	if (len < fg->wlen)
	  return ret;
	shift = fg->wlen;
	break;
      default:
	if (len < fg->len)
	  return ret;
	shift = fg->len;
    }
  if (fg->bol && (eflags & REG_NOTBOL))
    j = 1;
  if (fg->eol && (eflags & REG_NOTEOL))
    len--;
  if (fg->reversed)
    j = len - (type == STR_WIDE ? fg->wlen : fg->len);
  if ((fg->bol || fg->eol) && !fg->newline && !(eflags & REG_NOTBOL) &&
      !(eflags & REG_NOTEOL))
    {
      if (!((fg->bol && fg->eol) &&
	  (type == STR_WIDE ? (len != fg->wlen) : (len != fg->len))))
	{
	  j = fg->eol ? len - (type == STR_WIDE ? fg->wlen : fg->len) : 0;
	  SKIP_CHARS(j);
	  mismatch = fastcmp(fg, startptr, type);
	  if (mismatch == REG_OK)
	    {
	      if (fg->word && !IS_ON_WORD_BOUNDARY)
		return ret;
	      if (!fg->nosub && nmatch >= 1)
		{
		  pmatch[0].rm_so = j;
		  pmatch[0].rm_eo = j + (type == STR_WIDE ? fg->wlen : fg->len);
		}
	      return REG_OK;
            }
        }
    }
  else
    {
      do
	{
	  SKIP_CHARS(j);
	  mismatch = fastcmp(fg, startptr, type);
	  if (mismatch == REG_OK)
	    {
	      if (fg->word)
		CHECK_WORD_BOUNDARY;
	      if (fg->bol)
		CHECK_BOL_ANCHOR;
	      if (fg->eol)
		CHECK_EOL_ANCHOR;
	      if (!fg->nosub && nmatch >= 1)
		{
		  pmatch[0].rm_so = j;
		  pmatch[0].rm_eo = j + ((type == STR_WIDE) ? fg->wlen : fg->len);
		}
	      return REG_OK;
	    }
	  else if (mismatch > 0)
	    return mismatch;
	  mismatch = -mismatch - 1;
	  SHIFT;
        } while (!IS_OUT_OF_BOUNDS);
    }
    return ret;
}
int tre_match_fast ( const fastmatch_t * fg , const void * data , size_t len , tre_str_type_t type , int nmatch , regmatch_t pmatch [ ] , int eflags ) { unsigned int shift , u = 0 , v = 0 ; ssize_t j = 0 ; int ret = REG_NOMATCH ; int mismatch ; const char * str_byte = data ; const void * startptr = NULL ; const tre_char_t * str_wide = data ; if ( len == ( size_t ) -1 ) switch ( type ) { case STR_WIDE : len = tre_strlen ( str_wide ) ; break ; default : len = strlen ( str_byte ) ; break ; } if ( fg -> matchall ) { if ( ! fg -> nosub && nmatch >= 1 ) { pmatch [ 0 ] . rm_so = 0 ; pmatch [ 0 ] . rm_eo = len ; } if ( fg -> bol && fg -> eol ) return ( len == 0 ) ? REG_OK : REG_NOMATCH ; else return REG_OK ; } switch ( type ) { case STR_WIDE : if ( len < fg -> wlen ) return ret ; shift = fg -> wlen ; break ; default : if ( len < fg -> len ) return ret ; shift = fg -> len ; } if ( fg -> bol && ( eflags & REG_NOTBOL ) ) j = 1 ; if ( fg -> eol && ( eflags & REG_NOTEOL ) ) len -- ; if ( fg -> reversed ) j = len - ( type == STR_WIDE ? fg -> wlen : fg -> len ) ; if ( ( fg -> bol || fg -> eol ) && ! fg -> newline && ! ( eflags & REG_NOTBOL ) && ! ( eflags & REG_NOTEOL ) ) { if ( ! ( ( fg -> bol && fg -> eol ) && ( type == STR_WIDE ? ( len != fg -> wlen ) : ( len != fg -> len ) ) ) ) { j = fg -> eol ? len - ( type == STR_WIDE ? fg -> wlen : fg -> len ) : 0 ; SKIP_CHARS ( j ) ; mismatch = fastcmp ( fg , startptr , type ) ; if ( mismatch == REG_OK ) { if ( fg -> word && ! IS_ON_WORD_BOUNDARY ) return ret ; if ( ! fg -> nosub && nmatch >= 1 ) { pmatch [ 0 ] . rm_so = j ; pmatch [ 0 ] . rm_eo = j + ( type == STR_WIDE ? fg -> wlen : fg -> len ) ; } return REG_OK ; } } } else { do { SKIP_CHARS ( j ) ; mismatch = fastcmp ( fg , startptr , type ) ; if ( mismatch == REG_OK ) { if ( fg -> word ) CHECK_WORD_BOUNDARY ; if ( fg -> bol ) CHECK_BOL_ANCHOR ; if ( fg -> eol ) CHECK_EOL_ANCHOR ; if ( ! fg -> nosub && nmatch >= 1 ) { pmatch [ 0 ] . rm_so = j ; pmatch [ 0 ] . rm_eo = j + ( ( type == STR_WIDE ) ? fg -> wlen : fg -> len ) ; } return REG_OK ; } else if ( mismatch > 0 ) return mismatch ; mismatch = - mismatch - 1 ; SHIFT ; } while ( ! IS_OUT_OF_BOUNDS ) ; } return ret ; }
Executes matching of the precompiled pattern on the input string.
Executes matching of the precompiled pattern on the input string .
/* Calculate length if unspecified. */ /* Shortcut for empty pattern */ /* No point in going farther if we do not have enough data. */ /*
   * REG_NOTBOL means not anchoring ^ to the beginning of the line, so we
   * can shift one because there can't be a match at the beginning.
   */ /*
   * Like above, we cannot have a match at the very end when anchoring to
   * the end and REG_NOTEOL is specified.
   */ /* Only try once at the beginning or ending of the line. */ /* Simple text comparison. */ /* Determine where in data to start search at. */ /* Quick Search / Turbo Boyer-Moore algorithm. */