/*
  regexec.c - TRE POSIX compatible matching functions (and more).

  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#include <limits.h>

#include <regex.h>

#include "tre.h"

#include <assert.h>

static void tre_fill_pmatch(size_t nmatch,
                            regmatch_t pmatch[],
                            int cflags,
                            const tre_tnfa_t* tnfa,
                            int* tags,
                            int match_eo);

/***********************************************************************
 from tre-match-utils.h
***********************************************************************/

#define GET_NEXT_WCHAR()                                               \
  do {                                                                 \
    prev_c = next_c;                                                   \
    pos += pos_add_next;                                               \
    if ((pos_add_next = mbtowc(&next_c, str_byte, MB_LEN_MAX)) <= 0) { \
      if (pos_add_next < 0) {                                          \
        ret = REG_NOMATCH;                                             \
        goto error_exit;                                               \
      } else                                                           \
        pos_add_next++;                                                \
    }                                                                  \
    str_byte += pos_add_next;                                          \
  } while (0)

#define IS_WORD_CHAR(c) ((c) == L'_' || tre_isalnum(c))

#define CHECK_ASSERTIONS(assertions)                                   \
  (((assertions & ASSERT_AT_BOL) && (pos > 0 || reg_notbol) &&         \
    (prev_c != L'\n' || !reg_newline)) ||                              \
   ((assertions & ASSERT_AT_EOL) && (next_c != L'\0' || reg_noteol) && \
    (next_c != L'\n' || !reg_newline)) ||                              \
   ((assertions & ASSERT_AT_BOW) &&                                    \
    (IS_WORD_CHAR(prev_c) || !IS_WORD_CHAR(next_c))) ||                \
   ((assertions & ASSERT_AT_EOW) &&                                    \
    (!IS_WORD_CHAR(prev_c) || IS_WORD_CHAR(next_c))) ||                \
   ((assertions & ASSERT_AT_WB) &&                                     \
    (pos != 0 && next_c != L'\0' &&                                    \
     IS_WORD_CHAR(prev_c) == IS_WORD_CHAR(next_c))) ||                 \
   ((assertions & ASSERT_AT_WB_NEG) &&                                 \
    (pos == 0 || next_c == L'\0' ||                                    \
     IS_WORD_CHAR(prev_c) != IS_WORD_CHAR(next_c))))

#define CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)                              \
  (((trans_i->assertions & ASSERT_CHAR_CLASS) &&                               \
    !(tnfa->cflags & REG_ICASE) &&                                             \
    !tre_isctype((tre_cint_t)prev_c, trans_i->u.class)) ||                     \
   ((trans_i->assertions & ASSERT_CHAR_CLASS) && (tnfa->cflags & REG_ICASE) && \
    !tre_isctype(tre_tolower((tre_cint_t)prev_c), trans_i->u.class) &&         \
    !tre_isctype(tre_toupper((tre_cint_t)prev_c), trans_i->u.class)) ||        \
   ((trans_i->assertions & ASSERT_CHAR_CLASS_NEG) &&                           \
    tre_neg_char_classes_match(trans_i->neg_classes, (tre_cint_t)prev_c,       \
                               tnfa->cflags & REG_ICASE)))

/* Returns 1 if `t1' wins `t2', 0 otherwise. */
static int tre_tag_order(int num_tags,
                         tre_tag_direction_t* tag_directions,
                         int* t1,
                         int* t2) {
  int i;
  for (i = 0; i < num_tags; i++) {
    if (tag_directions[i] == TRE_TAG_MINIMIZE) {
      if (t1[i] < t2[i])
        return 1;
      if (t1[i] > t2[i])
        return 0;
    } else {
      if (t1[i] > t2[i])
        return 1;
      if (t1[i] < t2[i])
        return 0;
    }
  }
  /*  assert(0);*/
  return 0;
}

static int tre_neg_char_classes_match(tre_ctype_t* classes,
                                      tre_cint_t wc,
                                      int icase) {
  while (*classes != (tre_ctype_t)0)
    if ((!icase && tre_isctype(wc, *classes)) ||
        (icase && (tre_isctype(tre_toupper(wc), *classes) ||
                   tre_isctype(tre_tolower(wc), *classes))))
      return 1; /* Match. */
    else
      classes++;
  return 0; /* No match. */
}

/***********************************************************************
 from tre-match-parallel.c
***********************************************************************/

/*
  This algorithm searches for matches basically by reading characters
  in the searched string one by one, starting at the beginning. All
  matching paths in the TNFA are traversed in parallel. When two or
  more paths reach the same state, exactly one is chosen according to
  tag ordering rules; if returning submatches is not required it does
  not matter which path is chosen.

  The worst case time required for finding the leftmost and longest
  match, or determining that there is no match, is always linearly
  dependent on the length of the text being searched.

  This algorithm cannot handle TNFAs with back referencing nodes.
  See `tre-match-backtrack.c'.
*/

typedef struct {
  tre_tnfa_transition_t* state;
  int* tags;
} tre_tnfa_reach_t;

typedef struct {
  int pos;
  int** tags;
} tre_reach_pos_t;

static reg_errcode_t tre_tnfa_run_parallel(const tre_tnfa_t* tnfa,
                                           const void* string,
                                           int* match_tags,
                                           int eflags,
                                           int* match_end_ofs) {
  /* State variables required by GET_NEXT_WCHAR. */
  tre_char_t prev_c = 0, next_c = 0;
  const char* str_byte = string;
  int pos = -1;
  int pos_add_next = 1;
#ifdef TRE_MBSTATE
  mbstate_t mbstate;
#endif /* TRE_MBSTATE */
  int reg_notbol = eflags & REG_NOTBOL;
  int reg_noteol = eflags & REG_NOTEOL;
  int reg_newline = tnfa->cflags & REG_NEWLINE;
  reg_errcode_t ret;

  char* buf;
  tre_tnfa_transition_t* trans_i;
  tre_tnfa_reach_t *reach, *reach_next, *reach_i, *reach_next_i;
  tre_reach_pos_t* reach_pos;
  int* tag_i;
  int num_tags, i;

  int match_eo = -1; /* end offset of match (-1 if no match found yet) */
  int new_match = 0;
  int* tmp_tags = NULL;
  int* tmp_iptr;

#ifdef TRE_MBSTATE
  memset(&mbstate, '\0', sizeof(mbstate));
#endif /* TRE_MBSTATE */

  if (!match_tags)
    num_tags = 0;
  else
    num_tags = tnfa->num_tags;

  /* Allocate memory for temporary data required for matching. This needs to
     be done for every matching operation to be thread safe.  This allocates
     everything in a single large block from the stack frame using alloca()
     or with malloc() if alloca is unavailable. */
  {
    int tbytes, rbytes, pbytes, xbytes, total_bytes;
    char* tmp_buf;
    /* Compute the length of the block we need. */
    tbytes = sizeof(*tmp_tags) * num_tags;
    rbytes = sizeof(*reach_next) * (tnfa->num_states + 1);
    pbytes = sizeof(*reach_pos) * tnfa->num_states;
    xbytes = sizeof(int) * num_tags;
    total_bytes = (sizeof(long) - 1) * 4 /* for alignment paddings */
                  + (rbytes + xbytes * tnfa->num_states) * 2 + tbytes + pbytes;

    /* Allocate the memory. */
    buf = xmalloc((unsigned)total_bytes);
    if (buf == NULL)
      return REG_ESPACE;
    memset(buf, 0, (size_t)total_bytes);

    /* Get the various pointers within tmp_buf (properly aligned). */
    tmp_tags = (void*)buf;
    tmp_buf = buf + tbytes;
    tmp_buf += ALIGN(tmp_buf, long);
    reach_next = (void*)tmp_buf;
    tmp_buf += rbytes;
    tmp_buf += ALIGN(tmp_buf, long);
    reach = (void*)tmp_buf;
    tmp_buf += rbytes;
    tmp_buf += ALIGN(tmp_buf, long);
    reach_pos = (void*)tmp_buf;
    tmp_buf += pbytes;
    tmp_buf += ALIGN(tmp_buf, long);
    for (i = 0; i < tnfa->num_states; i++) {
      reach[i].tags = (void*)tmp_buf;
      tmp_buf += xbytes;
      reach_next[i].tags = (void*)tmp_buf;
      tmp_buf += xbytes;
    }
  }

  for (i = 0; i < tnfa->num_states; i++)
    reach_pos[i].pos = -1;

  GET_NEXT_WCHAR();
  pos = 0;

  reach_next_i = reach_next;
  while (1) {
    /* If no match found yet, add the initial states to `reach_next'. */
    if (match_eo < 0) {
      trans_i = tnfa->initial;
      while (trans_i->state != NULL) {
        if (reach_pos[trans_i->state_id].pos < pos) {
          if (trans_i->assertions && CHECK_ASSERTIONS(trans_i->assertions)) {
            trans_i++;
            continue;
          }

          reach_next_i->state = trans_i->state;
          for (i = 0; i < num_tags; i++)
            reach_next_i->tags[i] = -1;
          tag_i = trans_i->tags;
          if (tag_i)
            while (*tag_i >= 0) {
              if (*tag_i < num_tags)
                reach_next_i->tags[*tag_i] = pos;
              tag_i++;
            }
          if (reach_next_i->state == tnfa->final) {
            match_eo = pos;
            new_match = 1;
            for (i = 0; i < num_tags; i++)
              match_tags[i] = reach_next_i->tags[i];
          }
          reach_pos[trans_i->state_id].pos = pos;
          reach_pos[trans_i->state_id].tags = &reach_next_i->tags;
          reach_next_i++;
        }
        trans_i++;
      }
      reach_next_i->state = NULL;
    } else {
      if (num_tags == 0 || reach_next_i == reach_next)
        /* We have found a match. */
        break;
    }

    /* Check for end of string. */
    if (!next_c)
      break;

    GET_NEXT_WCHAR();

    /* Swap `reach' and `reach_next'. */
    reach_i = reach;
    reach = reach_next;
    reach_next = reach_i;

    /* For each state in `reach', weed out states that don't fulfill the
       minimal matching conditions. */
    if (tnfa->num_minimals && new_match) {
      new_match = 0;
      reach_next_i = reach_next;
      for (reach_i = reach; reach_i->state; reach_i++) {
        int skip = 0;
        for (i = 0; tnfa->minimal_tags[i] >= 0; i += 2) {
          int end = tnfa->minimal_tags[i];
          int start = tnfa->minimal_tags[i + 1];
          if (end >= num_tags) {
            skip = 1;
            break;
          } else if (reach_i->tags[start] == match_tags[start] &&
                     reach_i->tags[end] < match_tags[end]) {
            skip = 1;
            break;
          }
        }
        if (!skip) {
          reach_next_i->state = reach_i->state;
          tmp_iptr = reach_next_i->tags;
          reach_next_i->tags = reach_i->tags;
          reach_i->tags = tmp_iptr;
          reach_next_i++;
        }
      }
      reach_next_i->state = NULL;

      /* Swap `reach' and `reach_next'. */
      reach_i = reach;
      reach = reach_next;
      reach_next = reach_i;
    }

    /* For each state in `reach' see if there is a transition leaving with
       the current input symbol to a state not yet in `reach_next', and
       add the destination states to `reach_next'. */
    reach_next_i = reach_next;
    for (reach_i = reach; reach_i->state; reach_i++) {
      for (trans_i = reach_i->state; trans_i->state; trans_i++) {
        /* Does this transition match the input symbol? */
        if (trans_i->code_min <= (tre_cint_t)prev_c &&
            trans_i->code_max >= (tre_cint_t)prev_c) {
          if (trans_i->assertions &&
              (CHECK_ASSERTIONS(trans_i->assertions) ||
               CHECK_CHAR_CLASSES(trans_i, tnfa, eflags))) {
            continue;
          }

          /* Compute the tags after this transition. */
          for (i = 0; i < num_tags; i++)
            tmp_tags[i] = reach_i->tags[i];
          tag_i = trans_i->tags;
          if (tag_i != NULL)
            while (*tag_i >= 0) {
              if (*tag_i < num_tags)
                tmp_tags[*tag_i] = pos;
              tag_i++;
            }

          if (reach_pos[trans_i->state_id].pos < pos) {
            /* Found an unvisited node. */
            reach_next_i->state = trans_i->state;
            tmp_iptr = reach_next_i->tags;
            reach_next_i->tags = tmp_tags;
            tmp_tags = tmp_iptr;
            reach_pos[trans_i->state_id].pos = pos;
            reach_pos[trans_i->state_id].tags = &reach_next_i->tags;

            if (reach_next_i->state == tnfa->final &&
                (match_eo == -1 ||
                 (num_tags > 0 && reach_next_i->tags[0] <= match_tags[0]))) {
              match_eo = pos;
              new_match = 1;
              for (i = 0; i < num_tags; i++)
                match_tags[i] = reach_next_i->tags[i];
            }
            reach_next_i++;

          } else {
            assert(reach_pos[trans_i->state_id].pos == pos);
            /* Another path has also reached this state.  We choose
               the winner by examining the tag values for both
               paths. */
            if (tre_tag_order(num_tags, tnfa->tag_directions, tmp_tags,
                              *reach_pos[trans_i->state_id].tags)) {
              /* The new path wins. */
              tmp_iptr = *reach_pos[trans_i->state_id].tags;
              *reach_pos[trans_i->state_id].tags = tmp_tags;
              if (trans_i->state == tnfa->final) {
                match_eo = pos;
                new_match = 1;
                for (i = 0; i < num_tags; i++)
                  match_tags[i] = tmp_tags[i];
              }
              tmp_tags = tmp_iptr;
            }
          }
        }
      }
    }
    reach_next_i->state = NULL;
  }

  *match_end_ofs = match_eo;
  ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;
error_exit:
  xfree(buf);
  return ret;
}

/***********************************************************************
 from tre-match-backtrack.c
***********************************************************************/

/*
  This matcher is for regexps that use back referencing.  Regexp matching
  with back referencing is an NP-complete problem on the number of back
  references.  The easiest way to match them is to use a backtracking
  routine which basically goes through all possible paths in the TNFA
  and chooses the one which results in the best (leftmost and longest)
  match.  This can be spectacularly expensive and may run out of stack
  space, but there really is no better known generic algorithm. Quoting
  Henry Spencer from comp.compilers:
  <URL: http://compilers.iecc.com/comparch/article/93-03-102>

    POSIX.2 REs require longest match, which is really exciting to
    implement since the obsolete ("basic") variant also includes
    \<digit>.  I haven't found a better way of tackling this than doing
    a preliminary match using a DFA (or simulation) on a modified RE
    that just replicates subREs for \<digit>, and then doing a
    backtracking match to determine whether the subRE matches were
    right.  This can be rather slow, but I console myself with the
    thought that people who use \<digit> deserve very slow execution.
    (Pun unintentional but very appropriate.)

*/

typedef struct {
  int pos;
  const char* str_byte;
  tre_tnfa_transition_t* state;
  int state_id;
  int next_c;
  int* tags;
#ifdef TRE_MBSTATE
  mbstate_t mbstate;
#endif /* TRE_MBSTATE */
} tre_backtrack_item_t;

typedef struct tre_backtrack_struct {
  tre_backtrack_item_t item;
  struct tre_backtrack_struct* prev;
  struct tre_backtrack_struct* next;
} * tre_backtrack_t;

#ifdef TRE_MBSTATE
#define BT_STACK_MBSTATE_IN stack->item.mbstate = (mbstate)
#define BT_STACK_MBSTATE_OUT (mbstate) = stack->item.mbstate
#else /* !TRE_MBSTATE */
#define BT_STACK_MBSTATE_IN
#define BT_STACK_MBSTATE_OUT
#endif /* !TRE_MBSTATE */

#define tre_bt_mem_new tre_mem_new
#define tre_bt_mem_alloc tre_mem_alloc
#define tre_bt_mem_destroy tre_mem_destroy

#define BT_STACK_PUSH(_pos, _str_byte, _str_wide, _state, _state_id, _next_c, \
                      _tags, _mbstate)                                        \
  do {                                                                        \
    int i;                                                                    \
    if (!stack->next) {                                                       \
      tre_backtrack_t s;                                                      \
      s = tre_bt_mem_alloc(mem, sizeof(*s));                                  \
      if (!s) {                                                               \
        tre_bt_mem_destroy(mem);                                              \
        if (tags)                                                             \
          xfree(tags);                                                        \
        if (pmatch)                                                           \
          xfree(pmatch);                                                      \
        if (states_seen)                                                      \
          xfree(states_seen);                                                 \
        return REG_ESPACE;                                                    \
      }                                                                       \
      s->prev = stack;                                                        \
      s->next = NULL;                                                         \
      s->item.tags = tre_bt_mem_alloc(mem, sizeof(*tags) * tnfa->num_tags);   \
      if (!s->item.tags) {                                                    \
        tre_bt_mem_destroy(mem);                                              \
        if (tags)                                                             \
          xfree(tags);                                                        \
        if (pmatch)                                                           \
          xfree(pmatch);                                                      \
        if (states_seen)                                                      \
          xfree(states_seen);                                                 \
        return REG_ESPACE;                                                    \
      }                                                                       \
      stack->next = s;                                                        \
      stack = s;                                                              \
    } else                                                                    \
      stack = stack->next;                                                    \
    stack->item.pos = (_pos);                                                 \
    stack->item.str_byte = (_str_byte);                                       \
    stack->item.state = (_state);                                             \
    stack->item.state_id = (_state_id);                                       \
    stack->item.next_c = (_next_c);                                           \
    for (i = 0; i < tnfa->num_tags; i++)                                      \
      stack->item.tags[i] = (_tags)[i];                                       \
    BT_STACK_MBSTATE_IN;                                                      \
  } while (0)

#define BT_STACK_POP()                   \
  do {                                   \
    int i;                               \
    assert(stack->prev);                 \
    pos = stack->item.pos;               \
    str_byte = stack->item.str_byte;     \
    state = stack->item.state;           \
    next_c = stack->item.next_c;         \
    for (i = 0; i < tnfa->num_tags; i++) \
      tags[i] = stack->item.tags[i];     \
    BT_STACK_MBSTATE_OUT;                \
    stack = stack->prev;                 \
  } while (0)

#undef MIN
#define MIN(a, b) ((a) <= (b) ? (a) : (b))

static reg_errcode_t tre_tnfa_run_backtrack(const tre_tnfa_t* tnfa,
                                            const void* string,
                                            int* match_tags,
                                            int eflags,
                                            int* match_end_ofs) {
  /* State variables required by GET_NEXT_WCHAR. */
  tre_char_t prev_c = 0, next_c = 0;
  const char* str_byte = string;
  int pos = 0;
  int pos_add_next = 1;
#ifdef TRE_MBSTATE
  mbstate_t mbstate;
#endif /* TRE_MBSTATE */
  int reg_notbol = eflags & REG_NOTBOL;
  int reg_noteol = eflags & REG_NOTEOL;
  int reg_newline = tnfa->cflags & REG_NEWLINE;

  /* These are used to remember the necessary values of the above
     variables to return to the position where the current search
     started from. */
  int next_c_start;
  const char* str_byte_start;
  int pos_start = -1;
#ifdef TRE_MBSTATE
  mbstate_t mbstate_start;
#endif /* TRE_MBSTATE */

  /* End offset of best match so far, or -1 if no match found yet. */
  int match_eo = -1;
  /* Tag arrays. */
  int *next_tags, *tags = NULL;
  /* Current TNFA state. */
  tre_tnfa_transition_t* state;
  int* states_seen = NULL;

  /* Memory allocator to for allocating the backtracking stack. */
  tre_mem_t mem = tre_bt_mem_new();

  /* The backtracking stack. */
  tre_backtrack_t stack;

  tre_tnfa_transition_t* trans_i;
  regmatch_t* pmatch = NULL;
  int ret;

#ifdef TRE_MBSTATE
  memset(&mbstate, '\0', sizeof(mbstate));
#endif /* TRE_MBSTATE */

  if (!mem)
    return REG_ESPACE;
  stack = tre_bt_mem_alloc(mem, sizeof(*stack));
  if (!stack) {
    ret = REG_ESPACE;
    goto error_exit;
  }
  stack->prev = NULL;
  stack->next = NULL;

  if (tnfa->num_tags) {
    tags = xmalloc(sizeof(*tags) * tnfa->num_tags);
    if (!tags) {
      ret = REG_ESPACE;
      goto error_exit;
    }
  }
  if (tnfa->num_submatches) {
    pmatch = xmalloc(sizeof(*pmatch) * tnfa->num_submatches);
    if (!pmatch) {
      ret = REG_ESPACE;
      goto error_exit;
    }
  }
  if (tnfa->num_states) {
    states_seen = xmalloc(sizeof(*states_seen) * tnfa->num_states);
    if (!states_seen) {
      ret = REG_ESPACE;
      goto error_exit;
    }
  }

retry : {
  int i;
  for (i = 0; i < tnfa->num_tags; i++) {
    tags[i] = -1;
    if (match_tags)
      match_tags[i] = -1;
  }
  for (i = 0; i < tnfa->num_states; i++)
    states_seen[i] = 0;
}

  state = NULL;
  pos = pos_start;
  GET_NEXT_WCHAR();
  pos_start = pos;
  next_c_start = next_c;
  str_byte_start = str_byte;
#ifdef TRE_MBSTATE
  mbstate_start = mbstate;
#endif /* TRE_MBSTATE */

  /* Handle initial states. */
  next_tags = NULL;
  for (trans_i = tnfa->initial; trans_i->state; trans_i++) {
    if (trans_i->assertions && CHECK_ASSERTIONS(trans_i->assertions)) {
      continue;
    }
    if (state == NULL) {
      /* Start from this state. */
      state = trans_i->state;
      next_tags = trans_i->tags;
    } else {
      /* Backtrack to this state. */
      BT_STACK_PUSH(pos, str_byte, 0, trans_i->state, trans_i->state_id, next_c,
                    tags, mbstate);
      {
        int* tmp = trans_i->tags;
        if (tmp)
          while (*tmp >= 0)
            stack->item.tags[*tmp++] = pos;
      }
    }
  }

  if (next_tags)
    for (; *next_tags >= 0; next_tags++)
      tags[*next_tags] = pos;

  if (state == NULL)
    goto backtrack;

  while (1) {
    tre_tnfa_transition_t* next_state;
    int empty_br_match;

    if (state == tnfa->final) {
      if (match_eo < pos || (match_eo == pos && match_tags &&
                             tre_tag_order(tnfa->num_tags, tnfa->tag_directions,
                                           tags, match_tags))) {
        int i;
        /* This match wins the previous match. */
        match_eo = pos;
        if (match_tags)
          for (i = 0; i < tnfa->num_tags; i++)
            match_tags[i] = tags[i];
      }
      /* Our TNFAs never have transitions leaving from the final state,
         so we jump right to backtracking. */
      goto backtrack;
    }

    /* Go to the next character in the input string. */
    empty_br_match = 0;
    trans_i = state;
    if (trans_i->state && trans_i->assertions & ASSERT_BACKREF) {
      /* This is a back reference state.  All transitions leaving from
         this state have the same back reference "assertion".  Instead
         of reading the next character, we match the back reference. */
      int so, eo, bt = trans_i->u.backref;
      int bt_len;
      int result;

      /* Get the substring we need to match against.  Remember to
         turn off REG_NOSUB temporarily. */
      tre_fill_pmatch(bt + 1, pmatch, tnfa->cflags & ~REG_NOSUB, tnfa, tags,
                      pos);
      so = pmatch[bt].rm_so;
      eo = pmatch[bt].rm_eo;
      bt_len = eo - so;

      result = strncmp((const char*)string + so, str_byte - 1, (size_t)bt_len);

      if (result == 0) {
        /* Back reference matched.  Check for infinite loop. */
        if (bt_len == 0)
          empty_br_match = 1;
        if (empty_br_match && states_seen[trans_i->state_id]) {
          goto backtrack;
        }

        states_seen[trans_i->state_id] = empty_br_match;

        /* Advance in input string and resync `prev_c', `next_c'
           and pos. */
        str_byte += bt_len - 1;
        pos += bt_len - 1;
        GET_NEXT_WCHAR();
      } else {
        goto backtrack;
      }
    } else {
      /* Check for end of string. */
      if (next_c == L'\0')
        goto backtrack;

      /* Read the next character. */
      GET_NEXT_WCHAR();
    }

    next_state = NULL;
    for (trans_i = state; trans_i->state; trans_i++) {
      if (trans_i->code_min <= (tre_cint_t)prev_c &&
          trans_i->code_max >= (tre_cint_t)prev_c) {
        if (trans_i->assertions &&
            (CHECK_ASSERTIONS(trans_i->assertions) ||
             CHECK_CHAR_CLASSES(trans_i, tnfa, eflags))) {
          continue;
        }

        if (next_state == NULL) {
          /* First matching transition. */
          next_state = trans_i->state;
          next_tags = trans_i->tags;
        } else {
          /* Second matching transition.  We may need to backtrack here
             to take this transition instead of the first one, so we
             push this transition in the backtracking stack so we can
             jump back here if needed. */
          BT_STACK_PUSH(pos, str_byte, 0, trans_i->state, trans_i->state_id,
                        next_c, tags, mbstate);
          {
            int* tmp;
            for (tmp = trans_i->tags; tmp && *tmp >= 0; tmp++)
              stack->item.tags[*tmp] = pos;
          }
        }
      }
    }

    if (next_state != NULL) {
      /* Matching transitions were found.  Take the first one. */
      state = next_state;

      /* Update the tag values. */
      if (next_tags)
        while (*next_tags >= 0)
          tags[*next_tags++] = pos;
    } else {
    backtrack:
      /* A matching transition was not found.  Try to backtrack. */
      if (stack->prev) {
        if (stack->item.state->assertions & ASSERT_BACKREF) {
          states_seen[stack->item.state_id] = 0;
        }

        BT_STACK_POP();
      } else if (match_eo < 0) {
        /* Try starting from a later position in the input string. */
        /* Check for end of string. */
        if (next_c == L'\0') {
          break;
        }
        next_c = next_c_start;
#ifdef TRE_MBSTATE
        mbstate = mbstate_start;
#endif /* TRE_MBSTATE */
        str_byte = str_byte_start;
        goto retry;
      } else {
        break;
      }
    }
  }

  ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;
  *match_end_ofs = match_eo;

error_exit:
  tre_bt_mem_destroy(mem);
#ifndef TRE_USE_ALLOCA
  if (tags)
    xfree(tags);
  if (pmatch)
    xfree(pmatch);
  if (states_seen)
    xfree(states_seen);
#endif /* !TRE_USE_ALLOCA */

  return ret;
}

/***********************************************************************
 from regexec.c
***********************************************************************/

/* Fills the POSIX.2 regmatch_t array according to the TNFA tag and match
   endpoint values. */
static void tre_fill_pmatch(size_t nmatch,
                            regmatch_t pmatch[],
                            int cflags,
                            const tre_tnfa_t* tnfa,
                            int* tags,
                            int match_eo) {
  tre_submatch_data_t* submatch_data;
  unsigned int i, j;
  int* parents;

  i = 0;
  if (match_eo >= 0 && !(cflags & REG_NOSUB)) {
    /* Construct submatch offsets from the tags. */
    submatch_data = tnfa->submatch_data;
    while (i < tnfa->num_submatches && i < nmatch) {
      if (submatch_data[i].so_tag == tnfa->end_tag)
        pmatch[i].rm_so = match_eo;
      else
        pmatch[i].rm_so = tags[submatch_data[i].so_tag];

      if (submatch_data[i].eo_tag == tnfa->end_tag)
        pmatch[i].rm_eo = match_eo;
      else
        pmatch[i].rm_eo = tags[submatch_data[i].eo_tag];

      /* If either of the endpoints were not used, this submatch
         was not part of the match. */
      if (pmatch[i].rm_so == -1 || pmatch[i].rm_eo == -1)
        pmatch[i].rm_so = pmatch[i].rm_eo = -1;

      i++;
    }
    /* Reset all submatches that are not within all of their parent
       submatches. */
    i = 0;
    while (i < tnfa->num_submatches && i < nmatch) {
      if (pmatch[i].rm_eo == -1)
        assert(pmatch[i].rm_so == -1);
      assert(pmatch[i].rm_so <= pmatch[i].rm_eo);

      parents = submatch_data[i].parents;
      if (parents != NULL)
        for (j = 0; parents[j] >= 0; j++) {
          if (pmatch[i].rm_so < pmatch[parents[j]].rm_so ||
              pmatch[i].rm_eo > pmatch[parents[j]].rm_eo)
            pmatch[i].rm_so = pmatch[i].rm_eo = -1;
        }
      i++;
    }
  }

  while (i < nmatch) {
    pmatch[i].rm_so = -1;
    pmatch[i].rm_eo = -1;
    i++;
  }
}

/*
  Wrapper functions for POSIX compatible regexp matching.
*/

int regexec(const regex_t* restrict preg,
            const char* restrict string,
            size_t nmatch,
            regmatch_t pmatch[restrict],
            int eflags) {
  tre_tnfa_t* tnfa = (void*)preg->TRE_REGEX_T_FIELD;
  reg_errcode_t status;
  int *tags = NULL, eo;
  if (tnfa->cflags & REG_NOSUB)
    nmatch = 0;
  if (tnfa->num_tags > 0 && nmatch > 0) {
    tags = xmalloc(sizeof(*tags) * tnfa->num_tags);
    if (tags == NULL)
      return REG_ESPACE;
  }

  /* Dispatch to the appropriate matcher. */
  if (tnfa->have_backrefs) {
    /* The regex has back references, use the backtracking matcher. */
    status = tre_tnfa_run_backtrack(tnfa, string, tags, eflags, &eo);
  } else {
    /* Exact matching, no back references, use the parallel matcher. */
    status = tre_tnfa_run_parallel(tnfa, string, tags, eflags, &eo);
  }

  if (status == REG_OK)
    /* A match was found, so fill the submatch registers. */
    tre_fill_pmatch(nmatch, pmatch, tnfa->cflags, tnfa, tags, eo);
  if (tags)
    xfree(tags);
  return status;
}
