the matching starts from the begining of the buffer.  */
the matching starts from the beginning of the buffer.  */
re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,		    eflags)    const regex_t *preg;    const char *string;    int length, start, range, stop, eflags;    size_t nmatch;    regmatch_t pmatch[];{  reg_errcode_t err;  re_dfa_t *dfa = (re_dfa_t *)preg->buffer;  re_string_t input;  int left_lim, right_lim, incr;  int fl_longest_match, match_first, match_last = -1;  int fast_translate, sb;  re_match_context_t mctx;  char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate		    && range && !preg->can_be_null) ? preg->fastmap : NULL);  /* Check if the DFA haven't been compiled.  */  if (BE (preg->used == 0 || dfa->init_state == NULL	  || dfa->init_state_word == NULL || dfa->init_state_nl == NULL	  || dfa->init_state_begbuf == NULL, 0))    return REG_NOMATCH;  re_node_set_init_empty (&empty_set);  memset (&mctx, '\0', sizeof (re_match_context_t));  /* We must check the longest matching, if nmatch > 0.  */  fl_longest_match = (nmatch != 0 || dfa->nbackref);  err = re_string_allocate (&input, string, length, dfa->nodes_len + 1,			    preg->translate, preg->syntax & RE_ICASE, dfa);  if (BE (err != REG_NOERROR, 0))    goto free_return;  input.stop = stop;  err = match_ctx_init (&mctx, eflags, &input, dfa->nbackref * 2);  if (BE (err != REG_NOERROR, 0))    goto free_return;  /* We will log all the DFA states through which the dfa pass,     if nmatch > 1, or this dfa has "multibyte node", which is a     back-reference or a node which can accept multibyte character or     multi character collating element.  */  if (nmatch > 1 || dfa->has_mb_node)    {      mctx.state_log = re_malloc (re_dfastate_t *, dfa->nodes_len + 1);      if (BE (mctx.state_log == NULL, 0))	{	  err = REG_ESPACE;	  goto free_return;	}    }  else    mctx.state_log = NULL;#ifdef DEBUG  /* We assume front-end functions already check them.  */  assert (start + range >= 0 && start + range <= length);#endif  match_first = start;  input.tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF		       : CONTEXT_NEWLINE | CONTEXT_BEGBUF);  /* Check incrementally whether of not the input string match.  */  incr = (range < 0) ? -1 : 1;  left_lim = (range < 0) ? start + range : start;  right_lim = (range < 0) ? start : start + range;  sb = dfa->mb_cur_max == 1;  fast_translate = sb || !(preg->syntax & RE_ICASE || preg->translate);  for (;;)    {      /* At first get the current byte from input string.  */      if (fastmap)	{	  if (BE (fast_translate, 1))	    {	      unsigned RE_TRANSLATE_TYPE t		= (unsigned RE_TRANSLATE_TYPE) preg->translate;	      if (BE (range >= 0, 1))		{		  if (BE (t != NULL, 0))		    {		      while (BE (match_first < right_lim, 1)			     && !fastmap[t[(unsigned char) string[match_first]]])			++match_first;		    }		  else		    {		      while (BE (match_first < right_lim, 1)			     && !fastmap[(unsigned char) string[match_first]])			++match_first;		    }		  if (BE (match_first == right_lim, 0))		    {		      int ch = match_first >= length			       ? 0 : (unsigned char) string[match_first];		      if (!fastmap[t ? t[ch] : ch])			break;		    }		}	      else		{		  while (match_first >= left_lim)		    {		      int ch = match_first >= length			       ? 0 : (unsigned char) string[match_first];		      if (fastmap[t ? t[ch] : ch])			break;		      --match_first;		    }		  if (match_first < left_lim)		    break;		}	    }	  else	    {	      int ch;	      do		{		  /* In this case, we can't determine easily the current byte,		     since it might be a component byte of a multibyte		     character.  Then we use the constructed buffer		     instead.  */		  /* If MATCH_FIRST is out of the valid range, reconstruct the		     buffers.  */		  if (input.raw_mbs_idx + input.valid_len <= match_first		      || match_first < input.raw_mbs_idx)		    {		      err = re_string_reconstruct (&input, match_first, eflags,						   preg->newline_anchor);		      if (BE (err != REG_NOERROR, 0))			goto free_return;		    }		  /* If MATCH_FIRST is out of the buffer, leave it as '\0'.		     Note that MATCH_FIRST must not be smaller than 0.  */		  ch = ((match_first >= length) ? 0		       : re_string_byte_at (&input,					    match_first - input.raw_mbs_idx));		  if (fastmap[ch])		    break;		  match_first += incr;		}	      while (match_first >= left_lim && match_first <= right_lim);	      if (! fastmap[ch])		break;	    }	}      /* Reconstruct the buffers so that the matcher can assume that	 the matching starts from the begining of the buffer.  */      err = re_string_reconstruct (&input, match_first, eflags,				   preg->newline_anchor);      if (BE (err != REG_NOERROR, 0))	goto free_return;#ifdef RE_ENABLE_I18N     /* Eliminate it when it is a component of a multibyte character	 and isn't the head of a multibyte character.  */      if (sb || re_string_first_byte (&input, 0))#endif	{	  /* It seems to be appropriate one, then use the matcher.  */	  /* We assume that the matching starts from 0.  */	  mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;	  match_last = check_matching (preg, &mctx, fl_longest_match);	  if (match_last != -1)	    {	      if (BE (match_last == -2, 0))		{		  err = REG_ESPACE;		  goto free_return;		}	      else		{		  mctx.match_last = match_last;		  if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)		    {		      re_dfastate_t *pstate = mctx.state_log[match_last];		      mctx.last_node = check_halt_state_context (preg, pstate,								 &mctx, match_last);		    }		  if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)		      || dfa->nbackref)		    {		      err = prune_impossible_nodes (preg, &mctx);		      if (err == REG_NOERROR)			break;		      if (BE (err != REG_NOMATCH, 0))			goto free_return;		    }		  else		    break; /* We found a matching.  */		}	    }	  match_ctx_clean (&mctx);	}      /* Update counter.  */      match_first += incr;      if (match_first < left_lim || right_lim < match_first)	break;    }  /* Set pmatch[] if we need.  */  if (match_last != -1 && nmatch > 0)    {      int reg_idx;      /* Initialize registers.  */      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)	pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1;      /* Set the points where matching start/end.  */      pmatch[0].rm_so = 0;      pmatch[0].rm_eo = mctx.match_last;      if (!preg->no_sub && nmatch > 1)	{	  err = set_regs (preg, &mctx, nmatch, pmatch,			  dfa->has_plural_match && dfa->nbackref > 0);	  if (BE (err != REG_NOERROR, 0))	    goto free_return;	}      /* At last, add the offset to the each registers, since we slided	 the buffers so that We can assume that the matching starts from 0.  */      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)	if (pmatch[reg_idx].rm_so != -1)	  {	    pmatch[reg_idx].rm_so += match_first;	    pmatch[reg_idx].rm_eo += match_first;	  }    }  err = (match_last == -1) ? REG_NOMATCH : REG_NOERROR; free_return:  re_free (mctx.state_log);  if (dfa->nbackref)    match_ctx_free (&mctx);  re_string_destruct (&input);  return err;}