Blame deps/regex/regex_internal.c

Packit Service 20376f
/* Extended regular expression matching and search library.
Packit Service 20376f
   Copyright (C) 2002-2006, 2010 Free Software Foundation, Inc.
Packit Service 20376f
   This file is part of the GNU C Library.
Packit Service 20376f
   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
Packit Service 20376f
Packit Service 20376f
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 20376f
   modify it under the terms of the GNU Lesser General Public
Packit Service 20376f
   License as published by the Free Software Foundation; either
Packit Service 20376f
   version 2.1 of the License, or (at your option) any later version.
Packit Service 20376f
Packit Service 20376f
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 20376f
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 20376f
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 20376f
   Lesser General Public License for more details.
Packit Service 20376f
Packit Service 20376f
   You should have received a copy of the GNU Lesser General Public
Packit Service 20376f
   License along with the GNU C Library; if not, write to the Free
Packit Service 20376f
   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 20376f
   02110-1301 USA.  */
Packit Service 20376f
Packit Service 20376f
static void re_string_construct_common (const char *str, int len,
Packit Service 20376f
					re_string_t *pstr,
Packit Service 20376f
					RE_TRANSLATE_TYPE trans, int icase,
Packit Service 20376f
					const re_dfa_t *dfa) internal_function;
Packit Service 20376f
static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa,
Packit Service 20376f
					  const re_node_set *nodes,
Packit Service 20376f
					  unsigned int hash) internal_function;
Packit Service 20376f
static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
Packit Service 20376f
					  const re_node_set *nodes,
Packit Service 20376f
					  unsigned int context,
Packit Service 20376f
					  unsigned int hash) internal_function;
Packit Service 20376f
Packit Service 20376f
#ifdef GAWK
Packit Service 20376f
#undef MAX	/* safety */
Packit Service 20376f
static size_t
Packit Service 20376f
MAX(size_t a, size_t b)
Packit Service 20376f
{
Packit Service 20376f
	return (a > b ? a : b);
Packit Service 20376f
}
Packit Service 20376f
#endif
Packit Service 20376f

Packit Service 20376f
/* Functions for string operation.  */
Packit Service 20376f
Packit Service 20376f
/* This function allocate the buffers.  It is necessary to call
Packit Service 20376f
   re_string_reconstruct before using the object.  */
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
Packit Service 20376f
		    RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
Packit Service 20376f
{
Packit Service 20376f
  reg_errcode_t ret;
Packit Service 20376f
  int init_buf_len;
Packit Service 20376f
Packit Service 20376f
  /* Ensure at least one character fits into the buffers.  */
Packit Service 20376f
  if (init_len < dfa->mb_cur_max)
Packit Service 20376f
    init_len = dfa->mb_cur_max;
Packit Service 20376f
  init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
Packit Service 20376f
  re_string_construct_common (str, len, pstr, trans, icase, dfa);
Packit Service 20376f
Packit Service 20376f
  ret = re_string_realloc_buffers (pstr, init_buf_len);
Packit Service 20376f
  if (BE (ret != REG_NOERROR, 0))
Packit Service 20376f
    return ret;
Packit Service 20376f
Packit Service 20376f
  pstr->word_char = dfa->word_char;
Packit Service 20376f
  pstr->word_ops_used = dfa->word_ops_used;
Packit Service 20376f
  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
Packit Service 20376f
  pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
Packit Service 20376f
  pstr->valid_raw_len = pstr->valid_len;
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* This function allocate the buffers, and initialize them.  */
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
re_string_construct (re_string_t *pstr, const char *str, int len,
Packit Service 20376f
		     RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
Packit Service 20376f
{
Packit Service 20376f
  reg_errcode_t ret;
Packit Service 20376f
  memset (pstr, '\0', sizeof (re_string_t));
Packit Service 20376f
  re_string_construct_common (str, len, pstr, trans, icase, dfa);
Packit Service 20376f
Packit Service 20376f
  if (len > 0)
Packit Service 20376f
    {
Packit Service 20376f
      ret = re_string_realloc_buffers (pstr, len + 1);
Packit Service 20376f
      if (BE (ret != REG_NOERROR, 0))
Packit Service 20376f
	return ret;
Packit Service 20376f
    }
Packit Service 20376f
  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
Packit Service 20376f
Packit Service 20376f
  if (icase)
Packit Service 20376f
    {
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
      if (dfa->mb_cur_max > 1)
Packit Service 20376f
	{
Packit Service 20376f
	  while (1)
Packit Service 20376f
	    {
Packit Service 20376f
	      ret = build_wcs_upper_buffer (pstr);
Packit Service 20376f
	      if (BE (ret != REG_NOERROR, 0))
Packit Service 20376f
		return ret;
Packit Service 20376f
	      if (pstr->valid_raw_len >= len)
Packit Service 20376f
		break;
Packit Service 20376f
	      if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
Packit Service 20376f
		break;
Packit Service 20376f
	      ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
Packit Service 20376f
	      if (BE (ret != REG_NOERROR, 0))
Packit Service 20376f
		return ret;
Packit Service 20376f
	    }
Packit Service 20376f
	}
Packit Service 20376f
      else
Packit Service 20376f
#endif /* RE_ENABLE_I18N  */
Packit Service 20376f
	build_upper_buffer (pstr);
Packit Service 20376f
    }
Packit Service 20376f
  else
Packit Service 20376f
    {
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
      if (dfa->mb_cur_max > 1)
Packit Service 20376f
	build_wcs_buffer (pstr);
Packit Service 20376f
      else
Packit Service 20376f
#endif /* RE_ENABLE_I18N  */
Packit Service 20376f
	{
Packit Service 20376f
	  if (trans != NULL)
Packit Service 20376f
	    re_string_translate_buffer (pstr);
Packit Service 20376f
	  else
Packit Service 20376f
	    {
Packit Service 20376f
	      pstr->valid_len = pstr->bufs_len;
Packit Service 20376f
	      pstr->valid_raw_len = pstr->bufs_len;
Packit Service 20376f
	    }
Packit Service 20376f
	}
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Helper functions for re_string_allocate, and re_string_construct.  */
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
Packit Service 20376f
{
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
  if (pstr->mb_cur_max > 1)
Packit Service 20376f
    {
Packit Service 20376f
      wint_t *new_wcs;
Packit Service 20376f
Packit Service 20376f
      /* Avoid overflow in realloc.  */
Packit Service 20376f
      const size_t max_object_size = MAX (sizeof (wint_t), sizeof (int));
Packit Service 20376f
      if (BE (SIZE_MAX / max_object_size < new_buf_len, 0))
Packit Service 20376f
	return REG_ESPACE;
Packit Service 20376f
Packit Service 20376f
      new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
Packit Service 20376f
      if (BE (new_wcs == NULL, 0))
Packit Service 20376f
	return REG_ESPACE;
Packit Service 20376f
      pstr->wcs = new_wcs;
Packit Service 20376f
      if (pstr->offsets != NULL)
Packit Service 20376f
	{
Packit Service 20376f
	  int *new_offsets = re_realloc (pstr->offsets, int, new_buf_len);
Packit Service 20376f
	  if (BE (new_offsets == NULL, 0))
Packit Service 20376f
	    return REG_ESPACE;
Packit Service 20376f
	  pstr->offsets = new_offsets;
Packit Service 20376f
	}
Packit Service 20376f
    }
Packit Service 20376f
#endif /* RE_ENABLE_I18N  */
Packit Service 20376f
  if (pstr->mbs_allocated)
Packit Service 20376f
    {
Packit Service 20376f
      unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
Packit Service 20376f
					   new_buf_len);
Packit Service 20376f
      if (BE (new_mbs == NULL, 0))
Packit Service 20376f
	return REG_ESPACE;
Packit Service 20376f
      pstr->mbs = new_mbs;
Packit Service 20376f
    }
Packit Service 20376f
  pstr->bufs_len = new_buf_len;
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
Packit Service 20376f
static void
Packit Service 20376f
internal_function
Packit Service 20376f
re_string_construct_common (const char *str, int len, re_string_t *pstr,
Packit Service 20376f
			    RE_TRANSLATE_TYPE trans, int icase,
Packit Service 20376f
			    const re_dfa_t *dfa)
Packit Service 20376f
{
Packit Service 20376f
  pstr->raw_mbs = (const unsigned char *) str;
Packit Service 20376f
  pstr->len = len;
Packit Service 20376f
  pstr->raw_len = len;
Packit Service 20376f
  pstr->trans = trans;
Packit Service 20376f
  pstr->icase = icase ? 1 : 0;
Packit Service 20376f
  pstr->mbs_allocated = (trans != NULL || icase);
Packit Service 20376f
  pstr->mb_cur_max = dfa->mb_cur_max;
Packit Service 20376f
  pstr->is_utf8 = dfa->is_utf8;
Packit Service 20376f
  pstr->map_notascii = dfa->map_notascii;
Packit Service 20376f
  pstr->stop = pstr->len;
Packit Service 20376f
  pstr->raw_stop = pstr->stop;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
Packit Service 20376f
/* Build wide character buffer PSTR->WCS.
Packit Service 20376f
   If the byte sequence of the string are:
Packit Service 20376f
     <mb1>(0), <mb1>(1), <mb2>(0), <mb2>(1), <sb3>
Packit Service 20376f
   Then wide character buffer will be:
Packit Service 20376f
     <wc1>   , WEOF    , <wc2>   , WEOF    , <wc3>
Packit Service 20376f
   We use WEOF for padding, they indicate that the position isn't
Packit Service 20376f
   a first byte of a multibyte character.
Packit Service 20376f
Packit Service 20376f
   Note that this function assumes PSTR->VALID_LEN elements are already
Packit Service 20376f
   built and starts from PSTR->VALID_LEN.  */
Packit Service 20376f
Packit Service 20376f
static void
Packit Service 20376f
internal_function
Packit Service 20376f
build_wcs_buffer (re_string_t *pstr)
Packit Service 20376f
{
Packit Service 20376f
#ifdef _LIBC
Packit Service 20376f
  unsigned char buf[MB_LEN_MAX];
Packit Service 20376f
  assert (MB_LEN_MAX >= pstr->mb_cur_max);
Packit Service 20376f
#else
Packit Service 20376f
  unsigned char buf[64];
Packit Service 20376f
#endif
Packit Service 20376f
  mbstate_t prev_st;
Packit Service 20376f
  int byte_idx, end_idx, remain_len;
Packit Service 20376f
  size_t mbclen;
Packit Service 20376f
Packit Service 20376f
  /* Build the buffers from pstr->valid_len to either pstr->len or
Packit Service 20376f
     pstr->bufs_len.  */
Packit Service 20376f
  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
Packit Service 20376f
  for (byte_idx = pstr->valid_len; byte_idx < end_idx;)
Packit Service 20376f
    {
Packit Service 20376f
      wchar_t wc;
Packit Service 20376f
      const char *p;
Packit Service 20376f
Packit Service 20376f
      remain_len = end_idx - byte_idx;
Packit Service 20376f
      prev_st = pstr->cur_state;
Packit Service 20376f
      /* Apply the translation if we need.  */
Packit Service 20376f
      if (BE (pstr->trans != NULL, 0))
Packit Service 20376f
	{
Packit Service 20376f
	  int i, ch;
Packit Service 20376f
Packit Service 20376f
	  for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
Packit Service 20376f
	    {
Packit Service 20376f
	      ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];
Packit Service 20376f
	      buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];
Packit Service 20376f
	    }
Packit Service 20376f
	  p = (const char *) buf;
Packit Service 20376f
	}
Packit Service 20376f
      else
Packit Service 20376f
	p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
Packit Service 20376f
      mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
Packit Service 20376f
      if (BE (mbclen == (size_t) -2, 0))
Packit Service 20376f
	{
Packit Service 20376f
	  /* The buffer doesn't have enough space, finish to build.  */
Packit Service 20376f
	  pstr->cur_state = prev_st;
Packit Service 20376f
	  break;
Packit Service 20376f
	}
Packit Service 20376f
      else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0))
Packit Service 20376f
	{
Packit Service 20376f
	  /* We treat these cases as a singlebyte character.  */
Packit Service 20376f
	  mbclen = 1;
Packit Service 20376f
	  wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
Packit Service 20376f
	  if (BE (pstr->trans != NULL, 0))
Packit Service 20376f
	    wc = pstr->trans[wc];
Packit Service 20376f
	  pstr->cur_state = prev_st;
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
      /* Write wide character and padding.  */
Packit Service 20376f
      pstr->wcs[byte_idx++] = wc;
Packit Service 20376f
      /* Write paddings.  */
Packit Service 20376f
      for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
Packit Service 20376f
	pstr->wcs[byte_idx++] = WEOF;
Packit Service 20376f
    }
Packit Service 20376f
  pstr->valid_len = byte_idx;
Packit Service 20376f
  pstr->valid_raw_len = byte_idx;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Build wide character buffer PSTR->WCS like build_wcs_buffer,
Packit Service 20376f
   but for REG_ICASE.  */
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
build_wcs_upper_buffer (re_string_t *pstr)
Packit Service 20376f
{
Packit Service 20376f
  mbstate_t prev_st;
Packit Service 20376f
  int src_idx, byte_idx, end_idx, remain_len;
Packit Service 20376f
  size_t mbclen;
Packit Service 20376f
#ifdef _LIBC
Packit Service 20376f
  char buf[MB_LEN_MAX];
Packit Service 20376f
  assert (MB_LEN_MAX >= pstr->mb_cur_max);
Packit Service 20376f
#else
Packit Service 20376f
  char buf[64];
Packit Service 20376f
#endif
Packit Service 20376f
Packit Service 20376f
  byte_idx = pstr->valid_len;
Packit Service 20376f
  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
Packit Service 20376f
Packit Service 20376f
  /* The following optimization assumes that ASCII characters can be
Packit Service 20376f
     mapped to wide characters with a simple cast.  */
Packit Service 20376f
  if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed)
Packit Service 20376f
    {
Packit Service 20376f
      while (byte_idx < end_idx)
Packit Service 20376f
	{
Packit Service 20376f
	  wchar_t wc;
Packit Service 20376f
Packit Service 20376f
	  if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx])
Packit Service 20376f
	      && mbsinit (&pstr->cur_state))
Packit Service 20376f
	    {
Packit Service 20376f
	      /* In case of a singlebyte character.  */
Packit Service 20376f
	      pstr->mbs[byte_idx]
Packit Service 20376f
		= toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
Packit Service 20376f
	      /* The next step uses the assumption that wchar_t is encoded
Packit Service 20376f
		 ASCII-safe: all ASCII values can be converted like this.  */
Packit Service 20376f
	      pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx];
Packit Service 20376f
	      ++byte_idx;
Packit Service 20376f
	      continue;
Packit Service 20376f
	    }
Packit Service 20376f
Packit Service 20376f
	  remain_len = end_idx - byte_idx;
Packit Service 20376f
	  prev_st = pstr->cur_state;
Packit Service 20376f
	  mbclen = __mbrtowc (&wc,
Packit Service 20376f
			      ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
Packit Service 20376f
			       + byte_idx), remain_len, &pstr->cur_state);
Packit Service 20376f
	  if (BE (mbclen + 2 > 2, 1))
Packit Service 20376f
	    {
Packit Service 20376f
	      wchar_t wcu = wc;
Packit Service 20376f
	      if (iswlower (wc))
Packit Service 20376f
		{
Packit Service 20376f
		  size_t mbcdlen;
Packit Service 20376f
Packit Service 20376f
		  wcu = towupper (wc);
Packit Service 20376f
		  mbcdlen = wcrtomb (buf, wcu, &prev_st);
Packit Service 20376f
		  if (BE (mbclen == mbcdlen, 1))
Packit Service 20376f
		    memcpy (pstr->mbs + byte_idx, buf, mbclen);
Packit Service 20376f
		  else
Packit Service 20376f
		    {
Packit Service 20376f
		      src_idx = byte_idx;
Packit Service 20376f
		      goto offsets_needed;
Packit Service 20376f
		    }
Packit Service 20376f
		}
Packit Service 20376f
	      else
Packit Service 20376f
		memcpy (pstr->mbs + byte_idx,
Packit Service 20376f
			pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen);
Packit Service 20376f
	      pstr->wcs[byte_idx++] = wcu;
Packit Service 20376f
	      /* Write paddings.  */
Packit Service 20376f
	      for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
Packit Service 20376f
		pstr->wcs[byte_idx++] = WEOF;
Packit Service 20376f
	    }
Packit Service 20376f
	  else if (mbclen == (size_t) -1 || mbclen == 0)
Packit Service 20376f
	    {
Packit Service 20376f
	      /* It is an invalid character or '\0'.  Just use the byte.  */
Packit Service 20376f
	      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
Packit Service 20376f
	      pstr->mbs[byte_idx] = ch;
Packit Service 20376f
	      /* And also cast it to wide char.  */
Packit Service 20376f
	      pstr->wcs[byte_idx++] = (wchar_t) ch;
Packit Service 20376f
	      if (BE (mbclen == (size_t) -1, 0))
Packit Service 20376f
		pstr->cur_state = prev_st;
Packit Service 20376f
	    }
Packit Service 20376f
	  else
Packit Service 20376f
	    {
Packit Service 20376f
	      /* The buffer doesn't have enough space, finish to build.  */
Packit Service 20376f
	      pstr->cur_state = prev_st;
Packit Service 20376f
	      break;
Packit Service 20376f
	    }
Packit Service 20376f
	}
Packit Service 20376f
      pstr->valid_len = byte_idx;
Packit Service 20376f
      pstr->valid_raw_len = byte_idx;
Packit Service 20376f
      return REG_NOERROR;
Packit Service 20376f
    }
Packit Service 20376f
  else
Packit Service 20376f
    for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;)
Packit Service 20376f
      {
Packit Service 20376f
	wchar_t wc;
Packit Service 20376f
	const char *p;
Packit Service 20376f
      offsets_needed:
Packit Service 20376f
	remain_len = end_idx - byte_idx;
Packit Service 20376f
	prev_st = pstr->cur_state;
Packit Service 20376f
	if (BE (pstr->trans != NULL, 0))
Packit Service 20376f
	  {
Packit Service 20376f
	    int i, ch;
Packit Service 20376f
Packit Service 20376f
	    for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
Packit Service 20376f
	      {
Packit Service 20376f
		ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
Packit Service 20376f
		buf[i] = pstr->trans[ch];
Packit Service 20376f
	      }
Packit Service 20376f
	    p = (const char *) buf;
Packit Service 20376f
	  }
Packit Service 20376f
	else
Packit Service 20376f
	  p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
Packit Service 20376f
	mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
Packit Service 20376f
	if (BE (mbclen + 2 > 2, 1))
Packit Service 20376f
	  {
Packit Service 20376f
	    wchar_t wcu = wc;
Packit Service 20376f
	    if (iswlower (wc))
Packit Service 20376f
	      {
Packit Service 20376f
		size_t mbcdlen;
Packit Service 20376f
Packit Service 20376f
		wcu = towupper (wc);
Packit Service 20376f
		mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st);
Packit Service 20376f
		if (BE (mbclen == mbcdlen, 1))
Packit Service 20376f
		  memcpy (pstr->mbs + byte_idx, buf, mbclen);
Packit Service 20376f
		else if (mbcdlen != (size_t) -1)
Packit Service 20376f
		  {
Packit Service 20376f
		    size_t i;
Packit Service 20376f
Packit Service 20376f
		    if (byte_idx + mbcdlen > pstr->bufs_len)
Packit Service 20376f
		      {
Packit Service 20376f
			pstr->cur_state = prev_st;
Packit Service 20376f
			break;
Packit Service 20376f
		      }
Packit Service 20376f
Packit Service 20376f
		    if (pstr->offsets == NULL)
Packit Service 20376f
		      {
Packit Service 20376f
			pstr->offsets = re_malloc (int, pstr->bufs_len);
Packit Service 20376f
Packit Service 20376f
			if (pstr->offsets == NULL)
Packit Service 20376f
			  return REG_ESPACE;
Packit Service 20376f
		      }
Packit Service 20376f
		    if (!pstr->offsets_needed)
Packit Service 20376f
		      {
Packit Service 20376f
			for (i = 0; i < (size_t) byte_idx; ++i)
Packit Service 20376f
			  pstr->offsets[i] = i;
Packit Service 20376f
			pstr->offsets_needed = 1;
Packit Service 20376f
		      }
Packit Service 20376f
Packit Service 20376f
		    memcpy (pstr->mbs + byte_idx, buf, mbcdlen);
Packit Service 20376f
		    pstr->wcs[byte_idx] = wcu;
Packit Service 20376f
		    pstr->offsets[byte_idx] = src_idx;
Packit Service 20376f
		    for (i = 1; i < mbcdlen; ++i)
Packit Service 20376f
		      {
Packit Service 20376f
			pstr->offsets[byte_idx + i]
Packit Service 20376f
			  = src_idx + (i < mbclen ? i : mbclen - 1);
Packit Service 20376f
			pstr->wcs[byte_idx + i] = WEOF;
Packit Service 20376f
		      }
Packit Service 20376f
		    pstr->len += mbcdlen - mbclen;
Packit Service 20376f
		    if (pstr->raw_stop > src_idx)
Packit Service 20376f
		      pstr->stop += mbcdlen - mbclen;
Packit Service 20376f
		    end_idx = (pstr->bufs_len > pstr->len)
Packit Service 20376f
			      ? pstr->len : pstr->bufs_len;
Packit Service 20376f
		    byte_idx += mbcdlen;
Packit Service 20376f
		    src_idx += mbclen;
Packit Service 20376f
		    continue;
Packit Service 20376f
		  }
Packit Service 20376f
		else
Packit Service 20376f
		  memcpy (pstr->mbs + byte_idx, p, mbclen);
Packit Service 20376f
	      }
Packit Service 20376f
	    else
Packit Service 20376f
	      memcpy (pstr->mbs + byte_idx, p, mbclen);
Packit Service 20376f
Packit Service 20376f
	    if (BE (pstr->offsets_needed != 0, 0))
Packit Service 20376f
	      {
Packit Service 20376f
		size_t i;
Packit Service 20376f
		for (i = 0; i < mbclen; ++i)
Packit Service 20376f
		  pstr->offsets[byte_idx + i] = src_idx + i;
Packit Service 20376f
	      }
Packit Service 20376f
	    src_idx += mbclen;
Packit Service 20376f
Packit Service 20376f
	    pstr->wcs[byte_idx++] = wcu;
Packit Service 20376f
	    /* Write paddings.  */
Packit Service 20376f
	    for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
Packit Service 20376f
	      pstr->wcs[byte_idx++] = WEOF;
Packit Service 20376f
	  }
Packit Service 20376f
	else if (mbclen == (size_t) -1 || mbclen == 0)
Packit Service 20376f
	  {
Packit Service 20376f
	    /* It is an invalid character or '\0'.  Just use the byte.  */
Packit Service 20376f
	    int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
Packit Service 20376f
Packit Service 20376f
	    if (BE (pstr->trans != NULL, 0))
Packit Service 20376f
	      ch = pstr->trans [ch];
Packit Service 20376f
	    pstr->mbs[byte_idx] = ch;
Packit Service 20376f
Packit Service 20376f
	    if (BE (pstr->offsets_needed != 0, 0))
Packit Service 20376f
	      pstr->offsets[byte_idx] = src_idx;
Packit Service 20376f
	    ++src_idx;
Packit Service 20376f
Packit Service 20376f
	    /* And also cast it to wide char.  */
Packit Service 20376f
	    pstr->wcs[byte_idx++] = (wchar_t) ch;
Packit Service 20376f
	    if (BE (mbclen == (size_t) -1, 0))
Packit Service 20376f
	      pstr->cur_state = prev_st;
Packit Service 20376f
	  }
Packit Service 20376f
	else
Packit Service 20376f
	  {
Packit Service 20376f
	    /* The buffer doesn't have enough space, finish to build.  */
Packit Service 20376f
	    pstr->cur_state = prev_st;
Packit Service 20376f
	    break;
Packit Service 20376f
	  }
Packit Service 20376f
      }
Packit Service 20376f
  pstr->valid_len = byte_idx;
Packit Service 20376f
  pstr->valid_raw_len = src_idx;
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Skip characters until the index becomes greater than NEW_RAW_IDX.
Packit Service 20376f
   Return the index.  */
Packit Service 20376f
Packit Service 20376f
static int
Packit Service 20376f
internal_function
Packit Service 20376f
re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
Packit Service 20376f
{
Packit Service 20376f
  mbstate_t prev_st;
Packit Service 20376f
  int rawbuf_idx;
Packit Service 20376f
  size_t mbclen;
Packit Service 20376f
  wint_t wc = WEOF;
Packit Service 20376f
Packit Service 20376f
  /* Skip the characters which are not necessary to check.  */
Packit Service 20376f
  for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
Packit Service 20376f
       rawbuf_idx < new_raw_idx;)
Packit Service 20376f
    {
Packit Service 20376f
      wchar_t wc2;
Packit Service 20376f
      int remain_len = pstr->len - rawbuf_idx;
Packit Service 20376f
      prev_st = pstr->cur_state;
Packit Service 20376f
      mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
Packit Service 20376f
			  remain_len, &pstr->cur_state);
Packit Service 20376f
      if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
Packit Service 20376f
	{
Packit Service 20376f
	  /* We treat these cases as a single byte character.  */
Packit Service 20376f
	  if (mbclen == 0 || remain_len == 0)
Packit Service 20376f
	    wc = L'\0';
Packit Service 20376f
	  else
Packit Service 20376f
	    wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx);
Packit Service 20376f
	  mbclen = 1;
Packit Service 20376f
	  pstr->cur_state = prev_st;
Packit Service 20376f
	}
Packit Service 20376f
      else
Packit Service 20376f
	wc = (wint_t) wc2;
Packit Service 20376f
      /* Then proceed the next character.  */
Packit Service 20376f
      rawbuf_idx += mbclen;
Packit Service 20376f
    }
Packit Service 20376f
  *last_wc = (wint_t) wc;
Packit Service 20376f
  return rawbuf_idx;
Packit Service 20376f
}
Packit Service 20376f
#endif /* RE_ENABLE_I18N  */
Packit Service 20376f
Packit Service 20376f
/* Build the buffer PSTR->MBS, and apply the translation if we need.
Packit Service 20376f
   This function is used in case of REG_ICASE.  */
Packit Service 20376f
Packit Service 20376f
static void
Packit Service 20376f
internal_function
Packit Service 20376f
build_upper_buffer (re_string_t *pstr)
Packit Service 20376f
{
Packit Service 20376f
  int char_idx, end_idx;
Packit Service 20376f
  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
Packit Service 20376f
Packit Service 20376f
  for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
Packit Service 20376f
    {
Packit Service 20376f
      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
Packit Service 20376f
      if (BE (pstr->trans != NULL, 0))
Packit Service 20376f
	ch = pstr->trans[ch];
Packit Service 20376f
      if (islower (ch))
Packit Service 20376f
	pstr->mbs[char_idx] = toupper (ch);
Packit Service 20376f
      else
Packit Service 20376f
	pstr->mbs[char_idx] = ch;
Packit Service 20376f
    }
Packit Service 20376f
  pstr->valid_len = char_idx;
Packit Service 20376f
  pstr->valid_raw_len = char_idx;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Apply TRANS to the buffer in PSTR.  */
Packit Service 20376f
Packit Service 20376f
static void
Packit Service 20376f
internal_function
Packit Service 20376f
re_string_translate_buffer (re_string_t *pstr)
Packit Service 20376f
{
Packit Service 20376f
  int buf_idx, end_idx;
Packit Service 20376f
  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
Packit Service 20376f
Packit Service 20376f
  for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx)
Packit Service 20376f
    {
Packit Service 20376f
      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx];
Packit Service 20376f
      pstr->mbs[buf_idx] = pstr->trans[ch];
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  pstr->valid_len = buf_idx;
Packit Service 20376f
  pstr->valid_raw_len = buf_idx;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* This function re-construct the buffers.
Packit Service 20376f
   Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
Packit Service 20376f
   convert to upper case in case of REG_ICASE, apply translation.  */
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
Packit Service 20376f
{
Packit Service 20376f
  int offset = idx - pstr->raw_mbs_idx;
Packit Service 20376f
  if (BE (offset < 0, 0))
Packit Service 20376f
    {
Packit Service 20376f
      /* Reset buffer.  */
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
      if (pstr->mb_cur_max > 1)
Packit Service 20376f
	memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
Packit Service 20376f
#endif /* RE_ENABLE_I18N */
Packit Service 20376f
      pstr->len = pstr->raw_len;
Packit Service 20376f
      pstr->stop = pstr->raw_stop;
Packit Service 20376f
      pstr->valid_len = 0;
Packit Service 20376f
      pstr->raw_mbs_idx = 0;
Packit Service 20376f
      pstr->valid_raw_len = 0;
Packit Service 20376f
      pstr->offsets_needed = 0;
Packit Service 20376f
      pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
Packit Service 20376f
			   : CONTEXT_NEWLINE | CONTEXT_BEGBUF);
Packit Service 20376f
      if (!pstr->mbs_allocated)
Packit Service 20376f
	pstr->mbs = (unsigned char *) pstr->raw_mbs;
Packit Service 20376f
      offset = idx;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  if (BE (offset != 0, 1))
Packit Service 20376f
    {
Packit Service 20376f
      /* Should the already checked characters be kept?  */
Packit Service 20376f
      if (BE (offset < pstr->valid_raw_len, 1))
Packit Service 20376f
	{
Packit Service 20376f
	  /* Yes, move them to the front of the buffer.  */
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
	  if (BE (pstr->offsets_needed, 0))
Packit Service 20376f
	    {
Packit Service 20376f
	      int low = 0, high = pstr->valid_len, mid;
Packit Service 20376f
	      do
Packit Service 20376f
		{
Packit Service 20376f
		  mid = (high + low) / 2;
Packit Service 20376f
		  if (pstr->offsets[mid] > offset)
Packit Service 20376f
		    high = mid;
Packit Service 20376f
		  else if (pstr->offsets[mid] < offset)
Packit Service 20376f
		    low = mid + 1;
Packit Service 20376f
		  else
Packit Service 20376f
		    break;
Packit Service 20376f
		}
Packit Service 20376f
	      while (low < high);
Packit Service 20376f
	      if (pstr->offsets[mid] < offset)
Packit Service 20376f
		++mid;
Packit Service 20376f
	      pstr->tip_context = re_string_context_at (pstr, mid - 1,
Packit Service 20376f
							eflags);
Packit Service 20376f
	      /* This can be quite complicated, so handle specially
Packit Service 20376f
		 only the common and easy case where the character with
Packit Service 20376f
		 different length representation of lower and upper
Packit Service 20376f
		 case is present at or after offset.  */
Packit Service 20376f
	      if (pstr->valid_len > offset
Packit Service 20376f
		  && mid == offset && pstr->offsets[mid] == offset)
Packit Service 20376f
		{
Packit Service 20376f
		  memmove (pstr->wcs, pstr->wcs + offset,
Packit Service 20376f
			   (pstr->valid_len - offset) * sizeof (wint_t));
Packit Service 20376f
		  memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset);
Packit Service 20376f
		  pstr->valid_len -= offset;
Packit Service 20376f
		  pstr->valid_raw_len -= offset;
Packit Service 20376f
		  for (low = 0; low < pstr->valid_len; low++)
Packit Service 20376f
		    pstr->offsets[low] = pstr->offsets[low + offset] - offset;
Packit Service 20376f
		}
Packit Service 20376f
	      else
Packit Service 20376f
		{
Packit Service 20376f
		  /* Otherwise, just find out how long the partial multibyte
Packit Service 20376f
		     character at offset is and fill it with WEOF/255.  */
Packit Service 20376f
		  pstr->len = pstr->raw_len - idx + offset;
Packit Service 20376f
		  pstr->stop = pstr->raw_stop - idx + offset;
Packit Service 20376f
		  pstr->offsets_needed = 0;
Packit Service 20376f
		  while (mid > 0 && pstr->offsets[mid - 1] == offset)
Packit Service 20376f
		    --mid;
Packit Service 20376f
		  while (mid < pstr->valid_len)
Packit Service 20376f
		    if (pstr->wcs[mid] != WEOF)
Packit Service 20376f
		      break;
Packit Service 20376f
		    else
Packit Service 20376f
		      ++mid;
Packit Service 20376f
		  if (mid == pstr->valid_len)
Packit Service 20376f
		    pstr->valid_len = 0;
Packit Service 20376f
		  else
Packit Service 20376f
		    {
Packit Service 20376f
		      pstr->valid_len = pstr->offsets[mid] - offset;
Packit Service 20376f
		      if (pstr->valid_len)
Packit Service 20376f
			{
Packit Service 20376f
			  for (low = 0; low < pstr->valid_len; ++low)
Packit Service 20376f
			    pstr->wcs[low] = WEOF;
Packit Service 20376f
			  memset (pstr->mbs, 255, pstr->valid_len);
Packit Service 20376f
			}
Packit Service 20376f
		    }
Packit Service 20376f
		  pstr->valid_raw_len = pstr->valid_len;
Packit Service 20376f
		}
Packit Service 20376f
	    }
Packit Service 20376f
	  else
Packit Service 20376f
#endif
Packit Service 20376f
	    {
Packit Service 20376f
	      pstr->tip_context = re_string_context_at (pstr, offset - 1,
Packit Service 20376f
							eflags);
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
	      if (pstr->mb_cur_max > 1)
Packit Service 20376f
		memmove (pstr->wcs, pstr->wcs + offset,
Packit Service 20376f
			 (pstr->valid_len - offset) * sizeof (wint_t));
Packit Service 20376f
#endif /* RE_ENABLE_I18N */
Packit Service 20376f
	      if (BE (pstr->mbs_allocated, 0))
Packit Service 20376f
		memmove (pstr->mbs, pstr->mbs + offset,
Packit Service 20376f
			 pstr->valid_len - offset);
Packit Service 20376f
	      pstr->valid_len -= offset;
Packit Service 20376f
	      pstr->valid_raw_len -= offset;
Packit Service 20376f
#if DEBUG
Packit Service 20376f
	      assert (pstr->valid_len > 0);
Packit Service 20376f
#endif
Packit Service 20376f
	    }
Packit Service 20376f
	}
Packit Service 20376f
      else
Packit Service 20376f
	{
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
	  /* No, skip all characters until IDX.  */
Packit Service 20376f
	  int prev_valid_len = pstr->valid_len;
Packit Service 20376f
Packit Service 20376f
	  if (BE (pstr->offsets_needed, 0))
Packit Service 20376f
	    {
Packit Service 20376f
	      pstr->len = pstr->raw_len - idx + offset;
Packit Service 20376f
	      pstr->stop = pstr->raw_stop - idx + offset;
Packit Service 20376f
	      pstr->offsets_needed = 0;
Packit Service 20376f
	    }
Packit Service 20376f
#endif
Packit Service 20376f
	  pstr->valid_len = 0;
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
	  if (pstr->mb_cur_max > 1)
Packit Service 20376f
	    {
Packit Service 20376f
	      int wcs_idx;
Packit Service 20376f
	      wint_t wc = WEOF;
Packit Service 20376f
Packit Service 20376f
	      if (pstr->is_utf8)
Packit Service 20376f
		{
Packit Service 20376f
		  const unsigned char *raw, *p, *end;
Packit Service 20376f
Packit Service 20376f
		  /* Special case UTF-8.  Multi-byte chars start with any
Packit Service 20376f
		     byte other than 0x80 - 0xbf.  */
Packit Service 20376f
		  raw = pstr->raw_mbs + pstr->raw_mbs_idx;
Packit Service 20376f
		  end = raw + (offset - pstr->mb_cur_max);
Packit Service 20376f
		  if (end < pstr->raw_mbs)
Packit Service 20376f
		    end = pstr->raw_mbs;
Packit Service 20376f
		  p = raw + offset - 1;
Packit Service 20376f
#ifdef _LIBC
Packit Service 20376f
		  /* We know the wchar_t encoding is UCS4, so for the simple
Packit Service 20376f
		     case, ASCII characters, skip the conversion step.  */
Packit Service 20376f
		  if (isascii (*p) && BE (pstr->trans == NULL, 1))
Packit Service 20376f
		    {
Packit Service 20376f
		      memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
Packit Service 20376f
		      /* pstr->valid_len = 0; */
Packit Service 20376f
		      wc = (wchar_t) *p;
Packit Service 20376f
		    }
Packit Service 20376f
		  else
Packit Service 20376f
#endif
Packit Service 20376f
		    for (; p >= end; --p)
Packit Service 20376f
		      if ((*p & 0xc0) != 0x80)
Packit Service 20376f
			{
Packit Service 20376f
			  mbstate_t cur_state;
Packit Service 20376f
			  wchar_t wc2;
Packit Service 20376f
			  int mlen = raw + pstr->len - p;
Packit Service 20376f
			  unsigned char buf[6];
Packit Service 20376f
			  size_t mbclen;
Packit Service 20376f
Packit Service 20376f
			  if (BE (pstr->trans != NULL, 0))
Packit Service 20376f
			    {
Packit Service 20376f
			      int i = mlen < 6 ? mlen : 6;
Packit Service 20376f
			      while (--i >= 0)
Packit Service 20376f
				buf[i] = pstr->trans[p[i]];
Packit Service 20376f
			    }
Packit Service 20376f
			  /* XXX Don't use mbrtowc, we know which conversion
Packit Service 20376f
			     to use (UTF-8 -> UCS4).  */
Packit Service 20376f
			  memset (&cur_state, 0, sizeof (cur_state));
Packit Service 20376f
			  mbclen = __mbrtowc (&wc2, (const char *) p, mlen,
Packit Service 20376f
					      &cur_state);
Packit Service 20376f
			  if (raw + offset - p <= mbclen
Packit Service 20376f
			      && mbclen < (size_t) -2)
Packit Service 20376f
			    {
Packit Service 20376f
			      memset (&pstr->cur_state, '\0',
Packit Service 20376f
				      sizeof (mbstate_t));
Packit Service 20376f
			      pstr->valid_len = mbclen - (raw + offset - p);
Packit Service 20376f
			      wc = wc2;
Packit Service 20376f
			    }
Packit Service 20376f
			  break;
Packit Service 20376f
			}
Packit Service 20376f
		}
Packit Service 20376f
Packit Service 20376f
	      if (wc == WEOF)
Packit Service 20376f
		pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
Packit Service 20376f
	      if (wc == WEOF)
Packit Service 20376f
		pstr->tip_context
Packit Service 20376f
		  = re_string_context_at (pstr, prev_valid_len - 1, eflags);
Packit Service 20376f
	      else
Packit Service 20376f
		pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
Packit Service 20376f
				      && IS_WIDE_WORD_CHAR (wc))
Packit Service 20376f
				     ? CONTEXT_WORD
Packit Service 20376f
				     : ((IS_WIDE_NEWLINE (wc)
Packit Service 20376f
					 && pstr->newline_anchor)
Packit Service 20376f
					? CONTEXT_NEWLINE : 0));
Packit Service 20376f
	      if (BE (pstr->valid_len, 0))
Packit Service 20376f
		{
Packit Service 20376f
		  for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
Packit Service 20376f
		    pstr->wcs[wcs_idx] = WEOF;
Packit Service 20376f
		  if (pstr->mbs_allocated)
Packit Service 20376f
		    memset (pstr->mbs, 255, pstr->valid_len);
Packit Service 20376f
		}
Packit Service 20376f
	      pstr->valid_raw_len = pstr->valid_len;
Packit Service 20376f
	    }
Packit Service 20376f
	  else
Packit Service 20376f
#endif /* RE_ENABLE_I18N */
Packit Service 20376f
	    {
Packit Service 20376f
	      int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
Packit Service 20376f
	      pstr->valid_raw_len = 0;
Packit Service 20376f
	      if (pstr->trans)
Packit Service 20376f
		c = pstr->trans[c];
Packit Service 20376f
	      pstr->tip_context = (bitset_contain (pstr->word_char, c)
Packit Service 20376f
				   ? CONTEXT_WORD
Packit Service 20376f
				   : ((IS_NEWLINE (c) && pstr->newline_anchor)
Packit Service 20376f
				      ? CONTEXT_NEWLINE : 0));
Packit Service 20376f
	    }
Packit Service 20376f
	}
Packit Service 20376f
      if (!BE (pstr->mbs_allocated, 0))
Packit Service 20376f
	pstr->mbs += offset;
Packit Service 20376f
    }
Packit Service 20376f
  pstr->raw_mbs_idx = idx;
Packit Service 20376f
  pstr->len -= offset;
Packit Service 20376f
  pstr->stop -= offset;
Packit Service 20376f
Packit Service 20376f
  /* Then build the buffers.  */
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
  if (pstr->mb_cur_max > 1)
Packit Service 20376f
    {
Packit Service 20376f
      if (pstr->icase)
Packit Service 20376f
	{
Packit Service 20376f
	  reg_errcode_t ret = build_wcs_upper_buffer (pstr);
Packit Service 20376f
	  if (BE (ret != REG_NOERROR, 0))
Packit Service 20376f
	    return ret;
Packit Service 20376f
	}
Packit Service 20376f
      else
Packit Service 20376f
	build_wcs_buffer (pstr);
Packit Service 20376f
    }
Packit Service 20376f
  else
Packit Service 20376f
#endif /* RE_ENABLE_I18N */
Packit Service 20376f
    if (BE (pstr->mbs_allocated, 0))
Packit Service 20376f
      {
Packit Service 20376f
	if (pstr->icase)
Packit Service 20376f
	  build_upper_buffer (pstr);
Packit Service 20376f
	else if (pstr->trans != NULL)
Packit Service 20376f
	  re_string_translate_buffer (pstr);
Packit Service 20376f
      }
Packit Service 20376f
    else
Packit Service 20376f
      pstr->valid_len = pstr->len;
Packit Service 20376f
Packit Service 20376f
  pstr->cur_idx = 0;
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static unsigned char
Packit Service 20376f
internal_function __attribute ((pure))
Packit Service 20376f
re_string_peek_byte_case (const re_string_t *pstr, int idx)
Packit Service 20376f
{
Packit Service 20376f
  int ch, off;
Packit Service 20376f
Packit Service 20376f
  /* Handle the common (easiest) cases first.  */
Packit Service 20376f
  if (BE (!pstr->mbs_allocated, 1))
Packit Service 20376f
    return re_string_peek_byte (pstr, idx);
Packit Service 20376f
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
  if (pstr->mb_cur_max > 1
Packit Service 20376f
      && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
Packit Service 20376f
    return re_string_peek_byte (pstr, idx);
Packit Service 20376f
#endif
Packit Service 20376f
Packit Service 20376f
  off = pstr->cur_idx + idx;
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
  if (pstr->offsets_needed)
Packit Service 20376f
    off = pstr->offsets[off];
Packit Service 20376f
#endif
Packit Service 20376f
Packit Service 20376f
  ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
Packit Service 20376f
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
  /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I
Packit Service 20376f
     this function returns CAPITAL LETTER I instead of first byte of
Packit Service 20376f
     DOTLESS SMALL LETTER I.  The latter would confuse the parser,
Packit Service 20376f
     since peek_byte_case doesn't advance cur_idx in any way.  */
Packit Service 20376f
  if (pstr->offsets_needed && !isascii (ch))
Packit Service 20376f
    return re_string_peek_byte (pstr, idx);
Packit Service 20376f
#endif
Packit Service 20376f
Packit Service 20376f
  return ch;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static unsigned char
Packit Service 20376f
internal_function __attribute ((pure))
Packit Service 20376f
re_string_fetch_byte_case (re_string_t *pstr)
Packit Service 20376f
{
Packit Service 20376f
  if (BE (!pstr->mbs_allocated, 1))
Packit Service 20376f
    return re_string_fetch_byte (pstr);
Packit Service 20376f
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
  if (pstr->offsets_needed)
Packit Service 20376f
    {
Packit Service 20376f
      int off, ch;
Packit Service 20376f
Packit Service 20376f
      /* For tr_TR.UTF-8 [[:islower:]] there is
Packit Service 20376f
	 [[: CAPITAL LETTER I WITH DOT lower:]] in mbs.  Skip
Packit Service 20376f
	 in that case the whole multi-byte character and return
Packit Service 20376f
	 the original letter.  On the other side, with
Packit Service 20376f
	 [[: DOTLESS SMALL LETTER I return [[:I, as doing
Packit Service 20376f
	 anything else would complicate things too much.  */
Packit Service 20376f
Packit Service 20376f
      if (!re_string_first_byte (pstr, pstr->cur_idx))
Packit Service 20376f
	return re_string_fetch_byte (pstr);
Packit Service 20376f
Packit Service 20376f
      off = pstr->offsets[pstr->cur_idx];
Packit Service 20376f
      ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
Packit Service 20376f
Packit Service 20376f
      if (! isascii (ch))
Packit Service 20376f
	return re_string_fetch_byte (pstr);
Packit Service 20376f
Packit Service 20376f
      re_string_skip_bytes (pstr,
Packit Service 20376f
			    re_string_char_size_at (pstr, pstr->cur_idx));
Packit Service 20376f
      return ch;
Packit Service 20376f
    }
Packit Service 20376f
#endif
Packit Service 20376f
Packit Service 20376f
  return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++];
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static void
Packit Service 20376f
internal_function
Packit Service 20376f
re_string_destruct (re_string_t *pstr)
Packit Service 20376f
{
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
  re_free (pstr->wcs);
Packit Service 20376f
  re_free (pstr->offsets);
Packit Service 20376f
#endif /* RE_ENABLE_I18N  */
Packit Service 20376f
  if (pstr->mbs_allocated)
Packit Service 20376f
    re_free (pstr->mbs);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Return the context at IDX in INPUT.  */
Packit Service 20376f
Packit Service 20376f
static unsigned int
Packit Service 20376f
internal_function
Packit Service 20376f
re_string_context_at (const re_string_t *input, int idx, int eflags)
Packit Service 20376f
{
Packit Service 20376f
  int c;
Packit Service 20376f
  if (BE (idx < 0, 0))
Packit Service 20376f
    /* In this case, we use the value stored in input->tip_context,
Packit Service 20376f
       since we can't know the character in input->mbs[-1] here.  */
Packit Service 20376f
    return input->tip_context;
Packit Service 20376f
  if (BE (idx == input->len, 0))
Packit Service 20376f
    return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
Packit Service 20376f
	    : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
  if (input->mb_cur_max > 1)
Packit Service 20376f
    {
Packit Service 20376f
      wint_t wc;
Packit Service 20376f
      int wc_idx = idx;
Packit Service 20376f
      while(input->wcs[wc_idx] == WEOF)
Packit Service 20376f
	{
Packit Service 20376f
#ifdef DEBUG
Packit Service 20376f
	  /* It must not happen.  */
Packit Service 20376f
	  assert (wc_idx >= 0);
Packit Service 20376f
#endif
Packit Service 20376f
	  --wc_idx;
Packit Service 20376f
	  if (wc_idx < 0)
Packit Service 20376f
	    return input->tip_context;
Packit Service 20376f
	}
Packit Service 20376f
      wc = input->wcs[wc_idx];
Packit Service 20376f
      if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc))
Packit Service 20376f
	return CONTEXT_WORD;
Packit Service 20376f
      return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
Packit Service 20376f
	      ? CONTEXT_NEWLINE : 0);
Packit Service 20376f
    }
Packit Service 20376f
  else
Packit Service 20376f
#endif
Packit Service 20376f
    {
Packit Service 20376f
      c = re_string_byte_at (input, idx);
Packit Service 20376f
      if (bitset_contain (input->word_char, c))
Packit Service 20376f
	return CONTEXT_WORD;
Packit Service 20376f
      return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0;
Packit Service 20376f
    }
Packit Service 20376f
}
Packit Service 20376f

Packit Service 20376f
/* Functions for set operation.  */
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
re_node_set_alloc (re_node_set *set, int size)
Packit Service 20376f
{
Packit Service 20376f
  /*
Packit Service 20376f
   * ADR: valgrind says size can be 0, which then doesn't
Packit Service 20376f
   * free the block of size 0.  Harumph. This seems
Packit Service 20376f
   * to work ok, though.
Packit Service 20376f
   */
Packit Service 20376f
  if (size == 0)
Packit Service 20376f
    {
Packit Service 20376f
       memset(set, 0, sizeof(*set));
Packit Service 20376f
       return REG_NOERROR;
Packit Service 20376f
    }
Packit Service 20376f
  set->alloc = size;
Packit Service 20376f
  set->nelem = 0;
Packit Service 20376f
  set->elems = re_malloc (int, size);
Packit Service 20376f
  if (BE (set->elems == NULL, 0))
Packit Service 20376f
    return REG_ESPACE;
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
re_node_set_init_1 (re_node_set *set, int elem)
Packit Service 20376f
{
Packit Service 20376f
  set->alloc = 1;
Packit Service 20376f
  set->nelem = 1;
Packit Service 20376f
  set->elems = re_malloc (int, 1);
Packit Service 20376f
  if (BE (set->elems == NULL, 0))
Packit Service 20376f
    {
Packit Service 20376f
      set->alloc = set->nelem = 0;
Packit Service 20376f
      return REG_ESPACE;
Packit Service 20376f
    }
Packit Service 20376f
  set->elems[0] = elem;
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
re_node_set_init_2 (re_node_set *set, int elem1, int elem2)
Packit Service 20376f
{
Packit Service 20376f
  set->alloc = 2;
Packit Service 20376f
  set->elems = re_malloc (int, 2);
Packit Service 20376f
  if (BE (set->elems == NULL, 0))
Packit Service 20376f
    return REG_ESPACE;
Packit Service 20376f
  if (elem1 == elem2)
Packit Service 20376f
    {
Packit Service 20376f
      set->nelem = 1;
Packit Service 20376f
      set->elems[0] = elem1;
Packit Service 20376f
    }
Packit Service 20376f
  else
Packit Service 20376f
    {
Packit Service 20376f
      set->nelem = 2;
Packit Service 20376f
      if (elem1 < elem2)
Packit Service 20376f
	{
Packit Service 20376f
	  set->elems[0] = elem1;
Packit Service 20376f
	  set->elems[1] = elem2;
Packit Service 20376f
	}
Packit Service 20376f
      else
Packit Service 20376f
	{
Packit Service 20376f
	  set->elems[0] = elem2;
Packit Service 20376f
	  set->elems[1] = elem1;
Packit Service 20376f
	}
Packit Service 20376f
    }
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
Packit Service 20376f
{
Packit Service 20376f
  dest->nelem = src->nelem;
Packit Service 20376f
  if (src->nelem > 0)
Packit Service 20376f
    {
Packit Service 20376f
      dest->alloc = dest->nelem;
Packit Service 20376f
      dest->elems = re_malloc (int, dest->alloc);
Packit Service 20376f
      if (BE (dest->elems == NULL, 0))
Packit Service 20376f
	{
Packit Service 20376f
	  dest->alloc = dest->nelem = 0;
Packit Service 20376f
	  return REG_ESPACE;
Packit Service 20376f
	}
Packit Service 20376f
      memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
Packit Service 20376f
    }
Packit Service 20376f
  else
Packit Service 20376f
    re_node_set_init_empty (dest);
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to
Packit Service 20376f
   DEST. Return value indicate the error code or REG_NOERROR if succeeded.
Packit Service 20376f
   Note: We assume dest->elems is NULL, when dest->alloc is 0.  */
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
Packit Service 20376f
			   const re_node_set *src2)
Packit Service 20376f
{
Packit Service 20376f
  int i1, i2, is, id, delta, sbase;
Packit Service 20376f
  if (src1->nelem == 0 || src2->nelem == 0)
Packit Service 20376f
    return REG_NOERROR;
Packit Service 20376f
Packit Service 20376f
  /* We need dest->nelem + 2 * elems_in_intersection; this is a
Packit Service 20376f
     conservative estimate.  */
Packit Service 20376f
  if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
Packit Service 20376f
    {
Packit Service 20376f
      int new_alloc = src1->nelem + src2->nelem + dest->alloc;
Packit Service 20376f
      int *new_elems = re_realloc (dest->elems, int, new_alloc);
Packit Service 20376f
      if (BE (new_elems == NULL, 0))
Packit Service 20376f
	return REG_ESPACE;
Packit Service 20376f
      dest->elems = new_elems;
Packit Service 20376f
      dest->alloc = new_alloc;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  /* Find the items in the intersection of SRC1 and SRC2, and copy
Packit Service 20376f
     into the top of DEST those that are not already in DEST itself.  */
Packit Service 20376f
  sbase = dest->nelem + src1->nelem + src2->nelem;
Packit Service 20376f
  i1 = src1->nelem - 1;
Packit Service 20376f
  i2 = src2->nelem - 1;
Packit Service 20376f
  id = dest->nelem - 1;
Packit Service 20376f
  for (;;)
Packit Service 20376f
    {
Packit Service 20376f
      if (src1->elems[i1] == src2->elems[i2])
Packit Service 20376f
	{
Packit Service 20376f
	  /* Try to find the item in DEST.  Maybe we could binary search?  */
Packit Service 20376f
	  while (id >= 0 && dest->elems[id] > src1->elems[i1])
Packit Service 20376f
	    --id;
Packit Service 20376f
Packit Service 20376f
	  if (id < 0 || dest->elems[id] != src1->elems[i1])
Packit Service 20376f
	    dest->elems[--sbase] = src1->elems[i1];
Packit Service 20376f
Packit Service 20376f
	  if (--i1 < 0 || --i2 < 0)
Packit Service 20376f
	    break;
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
      /* Lower the highest of the two items.  */
Packit Service 20376f
      else if (src1->elems[i1] < src2->elems[i2])
Packit Service 20376f
	{
Packit Service 20376f
	  if (--i2 < 0)
Packit Service 20376f
	    break;
Packit Service 20376f
	}
Packit Service 20376f
      else
Packit Service 20376f
	{
Packit Service 20376f
	  if (--i1 < 0)
Packit Service 20376f
	    break;
Packit Service 20376f
	}
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  id = dest->nelem - 1;
Packit Service 20376f
  is = dest->nelem + src1->nelem + src2->nelem - 1;
Packit Service 20376f
  delta = is - sbase + 1;
Packit Service 20376f
Packit Service 20376f
  /* Now copy.  When DELTA becomes zero, the remaining
Packit Service 20376f
     DEST elements are already in place; this is more or
Packit Service 20376f
     less the same loop that is in re_node_set_merge.  */
Packit Service 20376f
  dest->nelem += delta;
Packit Service 20376f
  if (delta > 0 && id >= 0)
Packit Service 20376f
    for (;;)
Packit Service 20376f
      {
Packit Service 20376f
	if (dest->elems[is] > dest->elems[id])
Packit Service 20376f
	  {
Packit Service 20376f
	    /* Copy from the top.  */
Packit Service 20376f
	    dest->elems[id + delta--] = dest->elems[is--];
Packit Service 20376f
	    if (delta == 0)
Packit Service 20376f
	      break;
Packit Service 20376f
	  }
Packit Service 20376f
	else
Packit Service 20376f
	  {
Packit Service 20376f
	    /* Slide from the bottom.  */
Packit Service 20376f
	    dest->elems[id + delta] = dest->elems[id];
Packit Service 20376f
	    if (--id < 0)
Packit Service 20376f
	      break;
Packit Service 20376f
	  }
Packit Service 20376f
      }
Packit Service 20376f
Packit Service 20376f
  /* Copy remaining SRC elements.  */
Packit Service 20376f
  memcpy (dest->elems, dest->elems + sbase, delta * sizeof (int));
Packit Service 20376f
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Calculate the union set of the sets SRC1 and SRC2. And store it to
Packit Service 20376f
   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
Packit Service 20376f
			const re_node_set *src2)
Packit Service 20376f
{
Packit Service 20376f
  int i1, i2, id;
Packit Service 20376f
  if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)
Packit Service 20376f
    {
Packit Service 20376f
      dest->alloc = src1->nelem + src2->nelem;
Packit Service 20376f
      dest->elems = re_malloc (int, dest->alloc);
Packit Service 20376f
      if (BE (dest->elems == NULL, 0))
Packit Service 20376f
	return REG_ESPACE;
Packit Service 20376f
    }
Packit Service 20376f
  else
Packit Service 20376f
    {
Packit Service 20376f
      if (src1 != NULL && src1->nelem > 0)
Packit Service 20376f
	return re_node_set_init_copy (dest, src1);
Packit Service 20376f
      else if (src2 != NULL && src2->nelem > 0)
Packit Service 20376f
	return re_node_set_init_copy (dest, src2);
Packit Service 20376f
      else
Packit Service 20376f
	re_node_set_init_empty (dest);
Packit Service 20376f
      return REG_NOERROR;
Packit Service 20376f
    }
Packit Service 20376f
  for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
Packit Service 20376f
    {
Packit Service 20376f
      if (src1->elems[i1] > src2->elems[i2])
Packit Service 20376f
	{
Packit Service 20376f
	  dest->elems[id++] = src2->elems[i2++];
Packit Service 20376f
	  continue;
Packit Service 20376f
	}
Packit Service 20376f
      if (src1->elems[i1] == src2->elems[i2])
Packit Service 20376f
	++i2;
Packit Service 20376f
      dest->elems[id++] = src1->elems[i1++];
Packit Service 20376f
    }
Packit Service 20376f
  if (i1 < src1->nelem)
Packit Service 20376f
    {
Packit Service 20376f
      memcpy (dest->elems + id, src1->elems + i1,
Packit Service 20376f
	     (src1->nelem - i1) * sizeof (int));
Packit Service 20376f
      id += src1->nelem - i1;
Packit Service 20376f
    }
Packit Service 20376f
  else if (i2 < src2->nelem)
Packit Service 20376f
    {
Packit Service 20376f
      memcpy (dest->elems + id, src2->elems + i2,
Packit Service 20376f
	     (src2->nelem - i2) * sizeof (int));
Packit Service 20376f
      id += src2->nelem - i2;
Packit Service 20376f
    }
Packit Service 20376f
  dest->nelem = id;
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Calculate the union set of the sets DEST and SRC. And store it to
Packit Service 20376f
   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
internal_function
Packit Service 20376f
re_node_set_merge (re_node_set *dest, const re_node_set *src)
Packit Service 20376f
{
Packit Service 20376f
  int is, id, sbase, delta;
Packit Service 20376f
  if (src == NULL || src->nelem == 0)
Packit Service 20376f
    return REG_NOERROR;
Packit Service 20376f
  if (dest->alloc < 2 * src->nelem + dest->nelem)
Packit Service 20376f
    {
Packit Service 20376f
      int new_alloc = 2 * (src->nelem + dest->alloc);
Packit Service 20376f
      int *new_buffer = re_realloc (dest->elems, int, new_alloc);
Packit Service 20376f
      if (BE (new_buffer == NULL, 0))
Packit Service 20376f
	return REG_ESPACE;
Packit Service 20376f
      dest->elems = new_buffer;
Packit Service 20376f
      dest->alloc = new_alloc;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  if (BE (dest->nelem == 0, 0))
Packit Service 20376f
    {
Packit Service 20376f
      dest->nelem = src->nelem;
Packit Service 20376f
      memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
Packit Service 20376f
      return REG_NOERROR;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  /* Copy into the top of DEST the items of SRC that are not
Packit Service 20376f
     found in DEST.  Maybe we could binary search in DEST?  */
Packit Service 20376f
  for (sbase = dest->nelem + 2 * src->nelem,
Packit Service 20376f
       is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; )
Packit Service 20376f
    {
Packit Service 20376f
      if (dest->elems[id] == src->elems[is])
Packit Service 20376f
	is--, id--;
Packit Service 20376f
      else if (dest->elems[id] < src->elems[is])
Packit Service 20376f
	dest->elems[--sbase] = src->elems[is--];
Packit Service 20376f
      else /* if (dest->elems[id] > src->elems[is]) */
Packit Service 20376f
	--id;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  if (is >= 0)
Packit Service 20376f
    {
Packit Service 20376f
      /* If DEST is exhausted, the remaining items of SRC must be unique.  */
Packit Service 20376f
      sbase -= is + 1;
Packit Service 20376f
      memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (int));
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  id = dest->nelem - 1;
Packit Service 20376f
  is = dest->nelem + 2 * src->nelem - 1;
Packit Service 20376f
  delta = is - sbase + 1;
Packit Service 20376f
  if (delta == 0)
Packit Service 20376f
    return REG_NOERROR;
Packit Service 20376f
Packit Service 20376f
  /* Now copy.  When DELTA becomes zero, the remaining
Packit Service 20376f
     DEST elements are already in place.  */
Packit Service 20376f
  dest->nelem += delta;
Packit Service 20376f
  for (;;)
Packit Service 20376f
    {
Packit Service 20376f
      if (dest->elems[is] > dest->elems[id])
Packit Service 20376f
	{
Packit Service 20376f
	  /* Copy from the top.  */
Packit Service 20376f
	  dest->elems[id + delta--] = dest->elems[is--];
Packit Service 20376f
	  if (delta == 0)
Packit Service 20376f
	    break;
Packit Service 20376f
	}
Packit Service 20376f
      else
Packit Service 20376f
	{
Packit Service 20376f
	  /* Slide from the bottom.  */
Packit Service 20376f
	  dest->elems[id + delta] = dest->elems[id];
Packit Service 20376f
	  if (--id < 0)
Packit Service 20376f
	    {
Packit Service 20376f
	      /* Copy remaining SRC elements.  */
Packit Service 20376f
	      memcpy (dest->elems, dest->elems + sbase,
Packit Service 20376f
		      delta * sizeof (int));
Packit Service 20376f
	      break;
Packit Service 20376f
	    }
Packit Service 20376f
	}
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Insert the new element ELEM to the re_node_set* SET.
Packit Service 20376f
   SET should not already have ELEM.
Packit Service 20376f
   return -1 if an error is occured, return 1 otherwise.  */
Packit Service 20376f
Packit Service 20376f
static int
Packit Service 20376f
internal_function
Packit Service 20376f
re_node_set_insert (re_node_set *set, int elem)
Packit Service 20376f
{
Packit Service 20376f
  int idx;
Packit Service 20376f
  /* In case the set is empty.  */
Packit Service 20376f
  if (set->alloc == 0)
Packit Service 20376f
    {
Packit Service 20376f
      if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1))
Packit Service 20376f
	return 1;
Packit Service 20376f
      else
Packit Service 20376f
	return -1;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  if (BE (set->nelem, 0) == 0)
Packit Service 20376f
    {
Packit Service 20376f
      /* We already guaranteed above that set->alloc != 0.  */
Packit Service 20376f
      set->elems[0] = elem;
Packit Service 20376f
      ++set->nelem;
Packit Service 20376f
      return 1;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  /* Realloc if we need.  */
Packit Service 20376f
  if (set->alloc == set->nelem)
Packit Service 20376f
    {
Packit Service 20376f
      int *new_elems;
Packit Service 20376f
      set->alloc = set->alloc * 2;
Packit Service 20376f
      new_elems = re_realloc (set->elems, int, set->alloc);
Packit Service 20376f
      if (BE (new_elems == NULL, 0))
Packit Service 20376f
	return -1;
Packit Service 20376f
      set->elems = new_elems;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  /* Move the elements which follows the new element.  Test the
Packit Service 20376f
     first element separately to skip a check in the inner loop.  */
Packit Service 20376f
  if (elem < set->elems[0])
Packit Service 20376f
    {
Packit Service 20376f
      idx = 0;
Packit Service 20376f
      for (idx = set->nelem; idx > 0; idx--)
Packit Service 20376f
	set->elems[idx] = set->elems[idx - 1];
Packit Service 20376f
    }
Packit Service 20376f
  else
Packit Service 20376f
    {
Packit Service 20376f
      for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
Packit Service 20376f
	set->elems[idx] = set->elems[idx - 1];
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  /* Insert the new element.  */
Packit Service 20376f
  set->elems[idx] = elem;
Packit Service 20376f
  ++set->nelem;
Packit Service 20376f
  return 1;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Insert the new element ELEM to the re_node_set* SET.
Packit Service 20376f
   SET should not already have any element greater than or equal to ELEM.
Packit Service 20376f
   Return -1 if an error is occured, return 1 otherwise.  */
Packit Service 20376f
Packit Service 20376f
static int
Packit Service 20376f
internal_function
Packit Service 20376f
re_node_set_insert_last (re_node_set *set, int elem)
Packit Service 20376f
{
Packit Service 20376f
  /* Realloc if we need.  */
Packit Service 20376f
  if (set->alloc == set->nelem)
Packit Service 20376f
    {
Packit Service 20376f
      int *new_elems;
Packit Service 20376f
      set->alloc = (set->alloc + 1) * 2;
Packit Service 20376f
      new_elems = re_realloc (set->elems, int, set->alloc);
Packit Service 20376f
      if (BE (new_elems == NULL, 0))
Packit Service 20376f
	return -1;
Packit Service 20376f
      set->elems = new_elems;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  /* Insert the new element.  */
Packit Service 20376f
  set->elems[set->nelem++] = elem;
Packit Service 20376f
  return 1;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Compare two node sets SET1 and SET2.
Packit Service 20376f
   return 1 if SET1 and SET2 are equivalent, return 0 otherwise.  */
Packit Service 20376f
Packit Service 20376f
static int
Packit Service 20376f
internal_function __attribute ((pure))
Packit Service 20376f
re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
Packit Service 20376f
{
Packit Service 20376f
  int i;
Packit Service 20376f
  if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
Packit Service 20376f
    return 0;
Packit Service 20376f
  for (i = set1->nelem ; --i >= 0 ; )
Packit Service 20376f
    if (set1->elems[i] != set2->elems[i])
Packit Service 20376f
      return 0;
Packit Service 20376f
  return 1;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */
Packit Service 20376f
Packit Service 20376f
static int
Packit Service 20376f
internal_function __attribute ((pure))
Packit Service 20376f
re_node_set_contains (const re_node_set *set, int elem)
Packit Service 20376f
{
Packit Service 20376f
  unsigned int idx, right, mid;
Packit Service 20376f
  if (set->nelem <= 0)
Packit Service 20376f
    return 0;
Packit Service 20376f
Packit Service 20376f
  /* Binary search the element.  */
Packit Service 20376f
  idx = 0;
Packit Service 20376f
  right = set->nelem - 1;
Packit Service 20376f
  while (idx < right)
Packit Service 20376f
    {
Packit Service 20376f
      mid = (idx + right) / 2;
Packit Service 20376f
      if (set->elems[mid] < elem)
Packit Service 20376f
	idx = mid + 1;
Packit Service 20376f
      else
Packit Service 20376f
	right = mid;
Packit Service 20376f
    }
Packit Service 20376f
  return set->elems[idx] == elem ? idx + 1 : 0;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static void
Packit Service 20376f
internal_function
Packit Service 20376f
re_node_set_remove_at (re_node_set *set, int idx)
Packit Service 20376f
{
Packit Service 20376f
  if (idx < 0 || idx >= set->nelem)
Packit Service 20376f
    return;
Packit Service 20376f
  --set->nelem;
Packit Service 20376f
  for (; idx < set->nelem; idx++)
Packit Service 20376f
    set->elems[idx] = set->elems[idx + 1];
Packit Service 20376f
}
Packit Service 20376f

Packit Service 20376f
Packit Service 20376f
/* Add the token TOKEN to dfa->nodes, and return the index of the token.
Packit Service 20376f
   Or return -1, if an error will be occured.  */
Packit Service 20376f
Packit Service 20376f
static int
Packit Service 20376f
internal_function
Packit Service 20376f
re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
Packit Service 20376f
{
Packit Service 20376f
  if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))
Packit Service 20376f
    {
Packit Service 20376f
      size_t new_nodes_alloc = dfa->nodes_alloc * 2;
Packit Service 20376f
      int *new_nexts, *new_indices;
Packit Service 20376f
      re_node_set *new_edests, *new_eclosures;
Packit Service 20376f
      re_token_t *new_nodes;
Packit Service 20376f
Packit Service 20376f
      /* Avoid overflows in realloc.  */
Packit Service 20376f
      const size_t max_object_size = MAX (sizeof (re_token_t),
Packit Service 20376f
					  MAX (sizeof (re_node_set),
Packit Service 20376f
					       sizeof (int)));
Packit Service 20376f
      if (BE (SIZE_MAX / max_object_size < new_nodes_alloc, 0))
Packit Service 20376f
	return -1;
Packit Service 20376f
Packit Service 20376f
      new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
Packit Service 20376f
      if (BE (new_nodes == NULL, 0))
Packit Service 20376f
	return -1;
Packit Service 20376f
      dfa->nodes = new_nodes;
Packit Service 20376f
      new_nexts = re_realloc (dfa->nexts, int, new_nodes_alloc);
Packit Service 20376f
      new_indices = re_realloc (dfa->org_indices, int, new_nodes_alloc);
Packit Service 20376f
      new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
Packit Service 20376f
      new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
Packit Service 20376f
      if (BE (new_nexts == NULL || new_indices == NULL
Packit Service 20376f
	      || new_edests == NULL || new_eclosures == NULL, 0))
Packit Service 20376f
	return -1;
Packit Service 20376f
      dfa->nexts = new_nexts;
Packit Service 20376f
      dfa->org_indices = new_indices;
Packit Service 20376f
      dfa->edests = new_edests;
Packit Service 20376f
      dfa->eclosures = new_eclosures;
Packit Service 20376f
      dfa->nodes_alloc = new_nodes_alloc;
Packit Service 20376f
    }
Packit Service 20376f
  dfa->nodes[dfa->nodes_len] = token;
Packit Service 20376f
  dfa->nodes[dfa->nodes_len].constraint = 0;
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
  dfa->nodes[dfa->nodes_len].accept_mb =
Packit Service 20376f
    (token.type == OP_PERIOD && dfa->mb_cur_max > 1) || token.type == COMPLEX_BRACKET;
Packit Service 20376f
#endif
Packit Service 20376f
  dfa->nexts[dfa->nodes_len] = -1;
Packit Service 20376f
  re_node_set_init_empty (dfa->edests + dfa->nodes_len);
Packit Service 20376f
  re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);
Packit Service 20376f
  return dfa->nodes_len++;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static inline unsigned int
Packit Service 20376f
internal_function
Packit Service 20376f
calc_state_hash (const re_node_set *nodes, unsigned int context)
Packit Service 20376f
{
Packit Service 20376f
  unsigned int hash = nodes->nelem + context;
Packit Service 20376f
  int i;
Packit Service 20376f
  for (i = 0 ; i < nodes->nelem ; i++)
Packit Service 20376f
    hash += nodes->elems[i];
Packit Service 20376f
  return hash;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Search for the state whose node_set is equivalent to NODES.
Packit Service 20376f
   Return the pointer to the state, if we found it in the DFA.
Packit Service 20376f
   Otherwise create the new one and return it.  In case of an error
Packit Service 20376f
   return NULL and set the error code in ERR.
Packit Service 20376f
   Note: - We assume NULL as the invalid state, then it is possible that
Packit Service 20376f
	   return value is NULL and ERR is REG_NOERROR.
Packit Service 20376f
	 - We never return non-NULL value in case of any errors, it is for
Packit Service 20376f
	   optimization.  */
Packit Service 20376f
Packit Service 20376f
static re_dfastate_t *
Packit Service 20376f
internal_function
Packit Service 20376f
re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
Packit Service 20376f
		  const re_node_set *nodes)
Packit Service 20376f
{
Packit Service 20376f
  unsigned int hash;
Packit Service 20376f
  re_dfastate_t *new_state;
Packit Service 20376f
  struct re_state_table_entry *spot;
Packit Service 20376f
  int i;
Packit Service 20376f
  if (BE (nodes->nelem == 0, 0))
Packit Service 20376f
    {
Packit Service 20376f
      *err = REG_NOERROR;
Packit Service 20376f
      return NULL;
Packit Service 20376f
    }
Packit Service 20376f
  hash = calc_state_hash (nodes, 0);
Packit Service 20376f
  spot = dfa->state_table + (hash & dfa->state_hash_mask);
Packit Service 20376f
Packit Service 20376f
  for (i = 0 ; i < spot->num ; i++)
Packit Service 20376f
    {
Packit Service 20376f
      re_dfastate_t *state = spot->array[i];
Packit Service 20376f
      if (hash != state->hash)
Packit Service 20376f
	continue;
Packit Service 20376f
      if (re_node_set_compare (&state->nodes, nodes))
Packit Service 20376f
	return state;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  /* There are no appropriate state in the dfa, create the new one.  */
Packit Service 20376f
  new_state = create_ci_newstate (dfa, nodes, hash);
Packit Service 20376f
  if (BE (new_state == NULL, 0))
Packit Service 20376f
    *err = REG_ESPACE;
Packit Service 20376f
Packit Service 20376f
  return new_state;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Search for the state whose node_set is equivalent to NODES and
Packit Service 20376f
   whose context is equivalent to CONTEXT.
Packit Service 20376f
   Return the pointer to the state, if we found it in the DFA.
Packit Service 20376f
   Otherwise create the new one and return it.  In case of an error
Packit Service 20376f
   return NULL and set the error code in ERR.
Packit Service 20376f
   Note: - We assume NULL as the invalid state, then it is possible that
Packit Service 20376f
	   return value is NULL and ERR is REG_NOERROR.
Packit Service 20376f
	 - We never return non-NULL value in case of any errors, it is for
Packit Service 20376f
	   optimization.  */
Packit Service 20376f
Packit Service 20376f
static re_dfastate_t *
Packit Service 20376f
internal_function
Packit Service 20376f
re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
Packit Service 20376f
			  const re_node_set *nodes, unsigned int context)
Packit Service 20376f
{
Packit Service 20376f
  unsigned int hash;
Packit Service 20376f
  re_dfastate_t *new_state;
Packit Service 20376f
  struct re_state_table_entry *spot;
Packit Service 20376f
  int i;
Packit Service 20376f
  if (nodes->nelem == 0)
Packit Service 20376f
    {
Packit Service 20376f
      *err = REG_NOERROR;
Packit Service 20376f
      return NULL;
Packit Service 20376f
    }
Packit Service 20376f
  hash = calc_state_hash (nodes, context);
Packit Service 20376f
  spot = dfa->state_table + (hash & dfa->state_hash_mask);
Packit Service 20376f
Packit Service 20376f
  for (i = 0 ; i < spot->num ; i++)
Packit Service 20376f
    {
Packit Service 20376f
      re_dfastate_t *state = spot->array[i];
Packit Service 20376f
      if (state->hash == hash
Packit Service 20376f
	  && state->context == context
Packit Service 20376f
	  && re_node_set_compare (state->entrance_nodes, nodes))
Packit Service 20376f
	return state;
Packit Service 20376f
    }
Packit Service 20376f
  /* There are no appropriate state in `dfa', create the new one.  */
Packit Service 20376f
  new_state = create_cd_newstate (dfa, nodes, context, hash);
Packit Service 20376f
  if (BE (new_state == NULL, 0))
Packit Service 20376f
    *err = REG_ESPACE;
Packit Service 20376f
Packit Service 20376f
  return new_state;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Finish initialization of the new state NEWSTATE, and using its hash value
Packit Service 20376f
   HASH put in the appropriate bucket of DFA's state table.  Return value
Packit Service 20376f
   indicates the error code if failed.  */
Packit Service 20376f
Packit Service 20376f
static reg_errcode_t
Packit Service 20376f
register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
Packit Service 20376f
		unsigned int hash)
Packit Service 20376f
{
Packit Service 20376f
  struct re_state_table_entry *spot;
Packit Service 20376f
  reg_errcode_t err;
Packit Service 20376f
  int i;
Packit Service 20376f
Packit Service 20376f
  newstate->hash = hash;
Packit Service 20376f
  err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
Packit Service 20376f
  if (BE (err != REG_NOERROR, 0))
Packit Service 20376f
    return REG_ESPACE;
Packit Service 20376f
  for (i = 0; i < newstate->nodes.nelem; i++)
Packit Service 20376f
    {
Packit Service 20376f
      int elem = newstate->nodes.elems[i];
Packit Service 20376f
      if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
Packit Service 20376f
	if (re_node_set_insert_last (&newstate->non_eps_nodes, elem) < 0)
Packit Service 20376f
	  return REG_ESPACE;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  spot = dfa->state_table + (hash & dfa->state_hash_mask);
Packit Service 20376f
  if (BE (spot->alloc <= spot->num, 0))
Packit Service 20376f
    {
Packit Service 20376f
      int new_alloc = 2 * spot->num + 2;
Packit Service 20376f
      re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
Packit Service 20376f
					      new_alloc);
Packit Service 20376f
      if (BE (new_array == NULL, 0))
Packit Service 20376f
	return REG_ESPACE;
Packit Service 20376f
      spot->array = new_array;
Packit Service 20376f
      spot->alloc = new_alloc;
Packit Service 20376f
    }
Packit Service 20376f
  spot->array[spot->num++] = newstate;
Packit Service 20376f
  return REG_NOERROR;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static void
Packit Service 20376f
free_state (re_dfastate_t *state)
Packit Service 20376f
{
Packit Service 20376f
  re_node_set_free (&state->non_eps_nodes);
Packit Service 20376f
  re_node_set_free (&state->inveclosure);
Packit Service 20376f
  if (state->entrance_nodes != &state->nodes)
Packit Service 20376f
    {
Packit Service 20376f
      re_node_set_free (state->entrance_nodes);
Packit Service 20376f
      re_free (state->entrance_nodes);
Packit Service 20376f
    }
Packit Service 20376f
  re_node_set_free (&state->nodes);
Packit Service 20376f
  re_free (state->word_trtable);
Packit Service 20376f
  re_free (state->trtable);
Packit Service 20376f
  re_free (state);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Create the new state which is independ of contexts.
Packit Service 20376f
   Return the new state if succeeded, otherwise return NULL.  */
Packit Service 20376f
Packit Service 20376f
static re_dfastate_t *
Packit Service 20376f
internal_function
Packit Service 20376f
create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
Packit Service 20376f
		    unsigned int hash)
Packit Service 20376f
{
Packit Service 20376f
  int i;
Packit Service 20376f
  reg_errcode_t err;
Packit Service 20376f
  re_dfastate_t *newstate;
Packit Service 20376f
Packit Service 20376f
  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
Packit Service 20376f
  if (BE (newstate == NULL, 0))
Packit Service 20376f
    return NULL;
Packit Service 20376f
  err = re_node_set_init_copy (&newstate->nodes, nodes);
Packit Service 20376f
  if (BE (err != REG_NOERROR, 0))
Packit Service 20376f
    {
Packit Service 20376f
      re_free (newstate);
Packit Service 20376f
      return NULL;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  newstate->entrance_nodes = &newstate->nodes;
Packit Service 20376f
  for (i = 0 ; i < nodes->nelem ; i++)
Packit Service 20376f
    {
Packit Service 20376f
      re_token_t *node = dfa->nodes + nodes->elems[i];
Packit Service 20376f
      re_token_type_t type = node->type;
Packit Service 20376f
      if (type == CHARACTER && !node->constraint)
Packit Service 20376f
	continue;
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
      newstate->accept_mb |= node->accept_mb;
Packit Service 20376f
#endif /* RE_ENABLE_I18N */
Packit Service 20376f
Packit Service 20376f
      /* If the state has the halt node, the state is a halt state.  */
Packit Service 20376f
      if (type == END_OF_RE)
Packit Service 20376f
	newstate->halt = 1;
Packit Service 20376f
      else if (type == OP_BACK_REF)
Packit Service 20376f
	newstate->has_backref = 1;
Packit Service 20376f
      else if (type == ANCHOR || node->constraint)
Packit Service 20376f
	newstate->has_constraint = 1;
Packit Service 20376f
    }
Packit Service 20376f
  err = register_state (dfa, newstate, hash);
Packit Service 20376f
  if (BE (err != REG_NOERROR, 0))
Packit Service 20376f
    {
Packit Service 20376f
      free_state (newstate);
Packit Service 20376f
      newstate = NULL;
Packit Service 20376f
    }
Packit Service 20376f
  return newstate;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/* Create the new state which is depend on the context CONTEXT.
Packit Service 20376f
   Return the new state if succeeded, otherwise return NULL.  */
Packit Service 20376f
Packit Service 20376f
static re_dfastate_t *
Packit Service 20376f
internal_function
Packit Service 20376f
create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
Packit Service 20376f
		    unsigned int context, unsigned int hash)
Packit Service 20376f
{
Packit Service 20376f
  int i, nctx_nodes = 0;
Packit Service 20376f
  reg_errcode_t err;
Packit Service 20376f
  re_dfastate_t *newstate;
Packit Service 20376f
Packit Service 20376f
  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
Packit Service 20376f
  if (BE (newstate == NULL, 0))
Packit Service 20376f
    return NULL;
Packit Service 20376f
  err = re_node_set_init_copy (&newstate->nodes, nodes);
Packit Service 20376f
  if (BE (err != REG_NOERROR, 0))
Packit Service 20376f
    {
Packit Service 20376f
      re_free (newstate);
Packit Service 20376f
      return NULL;
Packit Service 20376f
    }
Packit Service 20376f
Packit Service 20376f
  newstate->context = context;
Packit Service 20376f
  newstate->entrance_nodes = &newstate->nodes;
Packit Service 20376f
Packit Service 20376f
  for (i = 0 ; i < nodes->nelem ; i++)
Packit Service 20376f
    {
Packit Service 20376f
      re_token_t *node = dfa->nodes + nodes->elems[i];
Packit Service 20376f
      re_token_type_t type = node->type;
Packit Service 20376f
      unsigned int constraint = node->constraint;
Packit Service 20376f
Packit Service 20376f
      if (type == CHARACTER && !constraint)
Packit Service 20376f
	continue;
Packit Service 20376f
#ifdef RE_ENABLE_I18N
Packit Service 20376f
      newstate->accept_mb |= node->accept_mb;
Packit Service 20376f
#endif /* RE_ENABLE_I18N */
Packit Service 20376f
Packit Service 20376f
      /* If the state has the halt node, the state is a halt state.  */
Packit Service 20376f
      if (type == END_OF_RE)
Packit Service 20376f
	newstate->halt = 1;
Packit Service 20376f
      else if (type == OP_BACK_REF)
Packit Service 20376f
	newstate->has_backref = 1;
Packit Service 20376f
Packit Service 20376f
      if (constraint)
Packit Service 20376f
	{
Packit Service 20376f
	  if (newstate->entrance_nodes == &newstate->nodes)
Packit Service 20376f
	    {
Packit Service 20376f
	      newstate->entrance_nodes = re_malloc (re_node_set, 1);
Packit Service 20376f
	      if (BE (newstate->entrance_nodes == NULL, 0))
Packit Service 20376f
		{
Packit Service 20376f
		  free_state (newstate);
Packit Service 20376f
		  return NULL;
Packit Service 20376f
		}
Packit Service 20376f
	      if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
Packit Service 20376f
		  != REG_NOERROR)
Packit Service 20376f
		return NULL;
Packit Service 20376f
	      nctx_nodes = 0;
Packit Service 20376f
	      newstate->has_constraint = 1;
Packit Service 20376f
	    }
Packit Service 20376f
Packit Service 20376f
	  if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))
Packit Service 20376f
	    {
Packit Service 20376f
	      re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);
Packit Service 20376f
	      ++nctx_nodes;
Packit Service 20376f
	    }
Packit Service 20376f
	}
Packit Service 20376f
    }
Packit Service 20376f
  err = register_state (dfa, newstate, hash);
Packit Service 20376f
  if (BE (err != REG_NOERROR, 0))
Packit Service 20376f
    {
Packit Service 20376f
      free_state (newstate);
Packit Service 20376f
      newstate = NULL;
Packit Service 20376f
    }
Packit Service 20376f
  return  newstate;
Packit Service 20376f
}