Back to index

nagios-plugins  1.4.16
Functions
regex_internal.c File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

static void re_string_construct_common (const char *str, Idx len, re_string_t *pstr, RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) internal_function
static re_dfastate_tcreate_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, re_hashval_t hash) internal_function
static re_dfastate_tcreate_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, unsigned int context, re_hashval_t hash) internal_function
static reg_errcode_t
internal_function
__attribute_warn_unused_result__ 
re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
static reg_errcode_t
internal_function
__attribute_warn_unused_result__ 
re_string_construct (re_string_t *pstr, const char *str, Idx len, RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
static reg_errcode_t
internal_function
__attribute_warn_unused_result__ 
re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
static void internal_function build_upper_buffer (re_string_t *pstr)
static void internal_function re_string_translate_buffer (re_string_t *pstr)
static reg_errcode_t
internal_function
__attribute_warn_unused_result__ 
re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
static unsigned char
internal_function 
__attribute ((pure))
static void internal_function re_string_destruct (re_string_t *pstr)
static unsigned int
internal_function 
re_string_context_at (const re_string_t *input, Idx idx, int eflags)
static reg_errcode_t
internal_function
__attribute_warn_unused_result__ 
re_node_set_alloc (re_node_set *set, Idx size)
static reg_errcode_t
internal_function
__attribute_warn_unused_result__ 
re_node_set_init_1 (re_node_set *set, Idx elem)
static reg_errcode_t
internal_function
__attribute_warn_unused_result__ 
re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
static reg_errcode_t
internal_function
__attribute_warn_unused_result__ 
re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
static reg_errcode_t
internal_function
__attribute_warn_unused_result__ 
re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, const re_node_set *src2)
static reg_errcode_t
internal_function
__attribute_warn_unused_result__ 
re_node_set_init_union (re_node_set *dest, const re_node_set *src1, const re_node_set *src2)
static reg_errcode_t
internal_function
__attribute_warn_unused_result__ 
re_node_set_merge (re_node_set *dest, const re_node_set *src)
static bool internal_function
__attribute_warn_unused_result__ 
re_node_set_insert (re_node_set *set, Idx elem)
static bool internal_function
__attribute_warn_unused_result__ 
re_node_set_insert_last (re_node_set *set, Idx elem)
static void internal_function re_node_set_remove_at (re_node_set *set, Idx idx)
static Idx internal_function re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
static re_hashval_t
internal_function 
calc_state_hash (const re_node_set *nodes, unsigned int context)
static re_dfastate_t
*internal_function
__attribute_warn_unused_result__ 
re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, const re_node_set *nodes)
static re_dfastate_t
*internal_function
__attribute_warn_unused_result__ 
re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, const re_node_set *nodes, unsigned int context)
static reg_errcode_t
__attribute_warn_unused_result__ 
register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, re_hashval_t hash)
static void free_state (re_dfastate_t *state)

Function Documentation

static Idx internal_function __attribute ( (pure)  ) [static]

Definition at line 835 of file regex_internal.c.

{
  int ch;
  Idx off;

  /* Handle the common (easiest) cases first.  */
  if (BE (!pstr->mbs_allocated, 1))
    return re_string_peek_byte (pstr, idx);

#ifdef RE_ENABLE_I18N
  if (pstr->mb_cur_max > 1
      && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
    return re_string_peek_byte (pstr, idx);
#endif

  off = pstr->cur_idx + idx;
#ifdef RE_ENABLE_I18N
  if (pstr->offsets_needed)
    off = pstr->offsets[off];
#endif

  ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];

#ifdef RE_ENABLE_I18N
  /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I
     this function returns CAPITAL LETTER I instead of first byte of
     DOTLESS SMALL LETTER I.  The latter would confuse the parser,
     since peek_byte_case doesn't advance cur_idx in any way.  */
  if (pstr->offsets_needed && !isascii (ch))
    return re_string_peek_byte (pstr, idx);
#endif

  return ch;
}
static void internal_function build_upper_buffer ( re_string_t pstr) [static]

Definition at line 529 of file regex_internal.c.

{
  Idx char_idx, end_idx;
  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;

  for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
    {
      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
      if (BE (pstr->trans != NULL, 0))
       ch = pstr->trans[ch];
      if (islower (ch))
       pstr->mbs[char_idx] = toupper (ch);
      else
       pstr->mbs[char_idx] = ch;
    }
  pstr->valid_len = char_idx;
  pstr->valid_raw_len = char_idx;
}

Here is the caller graph for this function:

static re_hashval_t internal_function calc_state_hash ( const re_node_set nodes,
unsigned int  context 
) [inline, static]

Definition at line 1459 of file regex_internal.c.

{
  re_hashval_t hash = nodes->nelem + context;
  Idx i;
  for (i = 0 ; i < nodes->nelem ; i++)
    hash += nodes->elems[i];
  return hash;
}

Here is the caller graph for this function:

static re_dfastate_t *internal_function __attribute_warn_unused_result__ create_cd_newstate ( const re_dfa_t dfa,
const re_node_set nodes,
unsigned int  context,
re_hashval_t  hash 
) [static]

Definition at line 1673 of file regex_internal.c.

{
  Idx i, nctx_nodes = 0;
  reg_errcode_t err;
  re_dfastate_t *newstate;

  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
  if (BE (newstate == NULL, 0))
    return NULL;
  err = re_node_set_init_copy (&newstate->nodes, nodes);
  if (BE (err != REG_NOERROR, 0))
    {
      re_free (newstate);
      return NULL;
    }

  newstate->context = context;
  newstate->entrance_nodes = &newstate->nodes;

  for (i = 0 ; i < nodes->nelem ; i++)
    {
      re_token_t *node = dfa->nodes + nodes->elems[i];
      re_token_type_t type = node->type;
      unsigned int constraint = node->constraint;

      if (type == CHARACTER && !constraint)
       continue;
#ifdef RE_ENABLE_I18N
      newstate->accept_mb |= node->accept_mb;
#endif /* RE_ENABLE_I18N */

      /* If the state has the halt node, the state is a halt state.  */
      if (type == END_OF_RE)
       newstate->halt = 1;
      else if (type == OP_BACK_REF)
       newstate->has_backref = 1;

      if (constraint)
       {
         if (newstate->entrance_nodes == &newstate->nodes)
           {
             newstate->entrance_nodes = re_malloc (re_node_set, 1);
             if (BE (newstate->entrance_nodes == NULL, 0))
              {
                free_state (newstate);
                return NULL;
              }
             if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
                != REG_NOERROR)
              return NULL;
             nctx_nodes = 0;
             newstate->has_constraint = 1;
           }

         if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))
           {
             re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);
             ++nctx_nodes;
           }
       }
    }
  err = register_state (dfa, newstate, hash);
  if (BE (err != REG_NOERROR, 0))
    {
      free_state (newstate);
      newstate = NULL;
    }
  return  newstate;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1623 of file regex_internal.c.

{
  Idx i;
  reg_errcode_t err;
  re_dfastate_t *newstate;

  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
  if (BE (newstate == NULL, 0))
    return NULL;
  err = re_node_set_init_copy (&newstate->nodes, nodes);
  if (BE (err != REG_NOERROR, 0))
    {
      re_free (newstate);
      return NULL;
    }

  newstate->entrance_nodes = &newstate->nodes;
  for (i = 0 ; i < nodes->nelem ; i++)
    {
      re_token_t *node = dfa->nodes + nodes->elems[i];
      re_token_type_t type = node->type;
      if (type == CHARACTER && !node->constraint)
       continue;
#ifdef RE_ENABLE_I18N
      newstate->accept_mb |= node->accept_mb;
#endif /* RE_ENABLE_I18N */

      /* If the state has the halt node, the state is a halt state.  */
      if (type == END_OF_RE)
       newstate->halt = 1;
      else if (type == OP_BACK_REF)
       newstate->has_backref = 1;
      else if (type == ANCHOR || node->constraint)
       newstate->has_constraint = 1;
    }
  err = register_state (dfa, newstate, hash);
  if (BE (err != REG_NOERROR, 0))
    {
      free_state (newstate);
      newstate = NULL;
    }
  return newstate;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void free_state ( re_dfastate_t state) [static]

Definition at line 1603 of file regex_internal.c.

{
  re_node_set_free (&state->non_eps_nodes);
  re_node_set_free (&state->inveclosure);
  if (state->entrance_nodes != &state->nodes)
    {
      re_node_set_free (state->entrance_nodes);
      re_free (state->entrance_nodes);
    }
  re_node_set_free (&state->nodes);
  re_free (state->word_trtable);
  re_free (state->trtable);
  re_free (state);
}

Here is the caller graph for this function:

Definition at line 1479 of file regex_internal.c.

{
  re_hashval_t hash;
  re_dfastate_t *new_state;
  struct re_state_table_entry *spot;
  Idx i;
#ifdef lint
  /* Suppress bogus uninitialized-variable warnings.  */
  *err = REG_NOERROR;
#endif
  if (BE (nodes->nelem == 0, 0))
    {
      *err = REG_NOERROR;
      return NULL;
    }
  hash = calc_state_hash (nodes, 0);
  spot = dfa->state_table + (hash & dfa->state_hash_mask);

  for (i = 0 ; i < spot->num ; i++)
    {
      re_dfastate_t *state = spot->array[i];
      if (hash != state->hash)
       continue;
      if (re_node_set_compare (&state->nodes, nodes))
       return state;
    }

  /* There are no appropriate state in the dfa, create the new one.  */
  new_state = create_ci_newstate (dfa, nodes, hash);
  if (BE (new_state == NULL, 0))
    *err = REG_ESPACE;

  return new_state;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1527 of file regex_internal.c.

{
  re_hashval_t hash;
  re_dfastate_t *new_state;
  struct re_state_table_entry *spot;
  Idx i;
#ifdef lint
  /* Suppress bogus uninitialized-variable warnings.  */
  *err = REG_NOERROR;
#endif
  if (nodes->nelem == 0)
    {
      *err = REG_NOERROR;
      return NULL;
    }
  hash = calc_state_hash (nodes, context);
  spot = dfa->state_table + (hash & dfa->state_hash_mask);

  for (i = 0 ; i < spot->num ; i++)
    {
      re_dfastate_t *state = spot->array[i];
      if (state->hash == hash
         && state->context == context
         && re_node_set_compare (state->entrance_nodes, nodes))
       return state;
    }
  /* There are no appropriate state in `dfa', create the new one.  */
  new_state = create_cd_newstate (dfa, nodes, context, hash);
  if (BE (new_state == NULL, 0))
    *err = REG_ESPACE;

  return new_state;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Idx internal_function re_dfa_add_node ( re_dfa_t dfa,
re_token_t  token 
) [static]

Definition at line 1408 of file regex_internal.c.

{
  if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))
    {
      size_t new_nodes_alloc = dfa->nodes_alloc * 2;
      Idx *new_nexts, *new_indices;
      re_node_set *new_edests, *new_eclosures;
      re_token_t *new_nodes;
      size_t max_object_size =
       MAX (sizeof (re_token_t),
            MAX (sizeof (re_node_set),
                sizeof (Idx)));

      /* Avoid overflows.  */
      if (BE (SIZE_MAX / 2 / max_object_size < dfa->nodes_alloc, 0))
       return REG_MISSING;

      new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
      if (BE (new_nodes == NULL, 0))
       return REG_MISSING;
      dfa->nodes = new_nodes;
      new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);
      new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);
      new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
      new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
      if (BE (new_nexts == NULL || new_indices == NULL
             || new_edests == NULL || new_eclosures == NULL, 0))
       return REG_MISSING;
      dfa->nexts = new_nexts;
      dfa->org_indices = new_indices;
      dfa->edests = new_edests;
      dfa->eclosures = new_eclosures;
      dfa->nodes_alloc = new_nodes_alloc;
    }
  dfa->nodes[dfa->nodes_len] = token;
  dfa->nodes[dfa->nodes_len].constraint = 0;
#ifdef RE_ENABLE_I18N
  {
  int type = token.type;
  dfa->nodes[dfa->nodes_len].accept_mb =
    (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
  }
#endif
  dfa->nexts[dfa->nodes_len] = REG_MISSING;
  re_node_set_init_empty (dfa->edests + dfa->nodes_len);
  re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);
  return dfa->nodes_len++;
}

Here is the caller graph for this function:

Definition at line 1053 of file regex_internal.c.

{
  Idx i1, i2, is, id, delta, sbase;
  if (src1->nelem == 0 || src2->nelem == 0)
    return REG_NOERROR;

  /* We need dest->nelem + 2 * elems_in_intersection; this is a
     conservative estimate.  */
  if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
    {
      Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
      Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc);
      if (BE (new_elems == NULL, 0))
       return REG_ESPACE;
      dest->elems = new_elems;
      dest->alloc = new_alloc;
    }

  /* Find the items in the intersection of SRC1 and SRC2, and copy
     into the top of DEST those that are not already in DEST itself.  */
  sbase = dest->nelem + src1->nelem + src2->nelem;
  i1 = src1->nelem - 1;
  i2 = src2->nelem - 1;
  id = dest->nelem - 1;
  for (;;)
    {
      if (src1->elems[i1] == src2->elems[i2])
       {
         /* Try to find the item in DEST.  Maybe we could binary search?  */
         while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1])
           --id;

          if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1])
            dest->elems[--sbase] = src1->elems[i1];

         if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2))
           break;
       }

      /* Lower the highest of the two items.  */
      else if (src1->elems[i1] < src2->elems[i2])
       {
         if (! REG_VALID_INDEX (--i2))
           break;
       }
      else
       {
         if (! REG_VALID_INDEX (--i1))
           break;
       }
    }

  id = dest->nelem - 1;
  is = dest->nelem + src1->nelem + src2->nelem - 1;
  delta = is - sbase + 1;

  /* Now copy.  When DELTA becomes zero, the remaining
     DEST elements are already in place; this is more or
     less the same loop that is in re_node_set_merge.  */
  dest->nelem += delta;
  if (delta > 0 && REG_VALID_INDEX (id))
    for (;;)
      {
       if (dest->elems[is] > dest->elems[id])
         {
           /* Copy from the top.  */
           dest->elems[id + delta--] = dest->elems[is--];
           if (delta == 0)
             break;
         }
       else
         {
           /* Slide from the bottom.  */
           dest->elems[id + delta] = dest->elems[id];
           if (! REG_VALID_INDEX (--id))
             break;
         }
      }

  /* Copy remaining SRC elements.  */
  memcpy (dest->elems, dest->elems + sbase, delta * sizeof (Idx));

  return REG_NOERROR;
}

Here is the caller graph for this function:

Definition at line 970 of file regex_internal.c.

{
  set->alloc = size;
  set->nelem = 0;
  set->elems = re_malloc (Idx, size);
  if (BE (set->elems == NULL, 0))
    return REG_ESPACE;
  return REG_NOERROR;
}

Here is the caller graph for this function:

Definition at line 982 of file regex_internal.c.

{
  set->alloc = 1;
  set->nelem = 1;
  set->elems = re_malloc (Idx, 1);
  if (BE (set->elems == NULL, 0))
    {
      set->alloc = set->nelem = 0;
      return REG_ESPACE;
    }
  set->elems[0] = elem;
  return REG_NOERROR;
}

Here is the caller graph for this function:

Definition at line 998 of file regex_internal.c.

{
  set->alloc = 2;
  set->elems = re_malloc (Idx, 2);
  if (BE (set->elems == NULL, 0))
    return REG_ESPACE;
  if (elem1 == elem2)
    {
      set->nelem = 1;
      set->elems[0] = elem1;
    }
  else
    {
      set->nelem = 2;
      if (elem1 < elem2)
       {
         set->elems[0] = elem1;
         set->elems[1] = elem2;
       }
      else
       {
         set->elems[0] = elem2;
         set->elems[1] = elem1;
       }
    }
  return REG_NOERROR;
}

Here is the caller graph for this function:

Definition at line 1028 of file regex_internal.c.

{
  dest->nelem = src->nelem;
  if (src->nelem > 0)
    {
      dest->alloc = dest->nelem;
      dest->elems = re_malloc (Idx, dest->alloc);
      if (BE (dest->elems == NULL, 0))
       {
         dest->alloc = dest->nelem = 0;
         return REG_ESPACE;
       }
      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
    }
  else
    re_node_set_init_empty (dest);
  return REG_NOERROR;
}

Here is the caller graph for this function:

Definition at line 1144 of file regex_internal.c.

{
  Idx i1, i2, id;
  if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)
    {
      dest->alloc = src1->nelem + src2->nelem;
      dest->elems = re_malloc (Idx, dest->alloc);
      if (BE (dest->elems == NULL, 0))
       return REG_ESPACE;
    }
  else
    {
      if (src1 != NULL && src1->nelem > 0)
       return re_node_set_init_copy (dest, src1);
      else if (src2 != NULL && src2->nelem > 0)
       return re_node_set_init_copy (dest, src2);
      else
       re_node_set_init_empty (dest);
      return REG_NOERROR;
    }
  for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
    {
      if (src1->elems[i1] > src2->elems[i2])
       {
         dest->elems[id++] = src2->elems[i2++];
         continue;
       }
      if (src1->elems[i1] == src2->elems[i2])
       ++i2;
      dest->elems[id++] = src1->elems[i1++];
    }
  if (i1 < src1->nelem)
    {
      memcpy (dest->elems + id, src1->elems + i1,
            (src1->nelem - i1) * sizeof (Idx));
      id += src1->nelem - i1;
    }
  else if (i2 < src2->nelem)
    {
      memcpy (dest->elems + id, src2->elems + i2,
            (src2->nelem - i2) * sizeof (Idx));
      id += src2->nelem - i2;
    }
  dest->nelem = id;
  return REG_NOERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1281 of file regex_internal.c.

{
  Idx idx;
  /* In case the set is empty.  */
  if (set->alloc == 0)
    return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1);

  if (BE (set->nelem, 0) == 0)
    {
      /* We already guaranteed above that set->alloc != 0.  */
      set->elems[0] = elem;
      ++set->nelem;
      return true;
    }

  /* Realloc if we need.  */
  if (set->alloc == set->nelem)
    {
      Idx *new_elems;
      set->alloc = set->alloc * 2;
      new_elems = re_realloc (set->elems, Idx, set->alloc);
      if (BE (new_elems == NULL, 0))
       return false;
      set->elems = new_elems;
    }

  /* Move the elements which follows the new element.  Test the
     first element separately to skip a check in the inner loop.  */
  if (elem < set->elems[0])
    {
      idx = 0;
      for (idx = set->nelem; idx > 0; idx--)
       set->elems[idx] = set->elems[idx - 1];
    }
  else
    {
      for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
       set->elems[idx] = set->elems[idx - 1];
    }

  /* Insert the new element.  */
  set->elems[idx] = elem;
  ++set->nelem;
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1333 of file regex_internal.c.

{
  /* Realloc if we need.  */
  if (set->alloc == set->nelem)
    {
      Idx *new_elems;
      set->alloc = (set->alloc + 1) * 2;
      new_elems = re_realloc (set->elems, Idx, set->alloc);
      if (BE (new_elems == NULL, 0))
       return false;
      set->elems = new_elems;
    }

  /* Insert the new element.  */
  set->elems[set->nelem++] = elem;
  return true;
}

Here is the caller graph for this function:

Definition at line 1197 of file regex_internal.c.

{
  Idx is, id, sbase, delta;
  if (src == NULL || src->nelem == 0)
    return REG_NOERROR;
  if (dest->alloc < 2 * src->nelem + dest->nelem)
    {
      Idx new_alloc = 2 * (src->nelem + dest->alloc);
      Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc);
      if (BE (new_buffer == NULL, 0))
       return REG_ESPACE;
      dest->elems = new_buffer;
      dest->alloc = new_alloc;
    }

  if (BE (dest->nelem == 0, 0))
    {
      dest->nelem = src->nelem;
      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
      return REG_NOERROR;
    }

  /* Copy into the top of DEST the items of SRC that are not
     found in DEST.  Maybe we could binary search in DEST?  */
  for (sbase = dest->nelem + 2 * src->nelem,
       is = src->nelem - 1, id = dest->nelem - 1;
       REG_VALID_INDEX (is) && REG_VALID_INDEX (id); )
    {
      if (dest->elems[id] == src->elems[is])
       is--, id--;
      else if (dest->elems[id] < src->elems[is])
       dest->elems[--sbase] = src->elems[is--];
      else /* if (dest->elems[id] > src->elems[is]) */
       --id;
    }

  if (REG_VALID_INDEX (is))
    {
      /* If DEST is exhausted, the remaining items of SRC must be unique.  */
      sbase -= is + 1;
      memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (Idx));
    }

  id = dest->nelem - 1;
  is = dest->nelem + 2 * src->nelem - 1;
  delta = is - sbase + 1;
  if (delta == 0)
    return REG_NOERROR;

  /* Now copy.  When DELTA becomes zero, the remaining
     DEST elements are already in place.  */
  dest->nelem += delta;
  for (;;)
    {
      if (dest->elems[is] > dest->elems[id])
       {
         /* Copy from the top.  */
         dest->elems[id + delta--] = dest->elems[is--];
         if (delta == 0)
           break;
       }
      else
       {
         /* Slide from the bottom.  */
         dest->elems[id + delta] = dest->elems[id];
         if (! REG_VALID_INDEX (--id))
           {
             /* Copy remaining SRC elements.  */
             memcpy (dest->elems, dest->elems + sbase,
                    delta * sizeof (Idx));
             break;
           }
       }
    }

  return REG_NOERROR;
}

Here is the caller graph for this function:

static void internal_function re_node_set_remove_at ( re_node_set set,
Idx  idx 
) [static]

Definition at line 1393 of file regex_internal.c.

{
  if (idx < 0 || idx >= set->nelem)
    return;
  --set->nelem;
  for (; idx < set->nelem; idx++)
    set->elems[idx] = set->elems[idx + 1];
}

Here is the caller graph for this function:

static reg_errcode_t internal_function __attribute_warn_unused_result__ re_string_allocate ( re_string_t pstr,
const char *  str,
Idx  len,
Idx  init_len,
RE_TRANSLATE_TYPE  trans,
bool  icase,
const re_dfa_t dfa 
) [static]

Definition at line 40 of file regex_internal.c.

{
  reg_errcode_t ret;
  Idx init_buf_len;

  /* Ensure at least one character fits into the buffers.  */
  if (init_len < dfa->mb_cur_max)
    init_len = dfa->mb_cur_max;
  init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
  re_string_construct_common (str, len, pstr, trans, icase, dfa);

  ret = re_string_realloc_buffers (pstr, init_buf_len);
  if (BE (ret != REG_NOERROR, 0))
    return ret;

  pstr->word_char = dfa->word_char;
  pstr->word_ops_used = dfa->word_ops_used;
  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
  pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
  pstr->valid_raw_len = pstr->valid_len;
  return REG_NOERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static reg_errcode_t internal_function __attribute_warn_unused_result__ re_string_construct ( re_string_t pstr,
const char *  str,
Idx  len,
RE_TRANSLATE_TYPE  trans,
bool  icase,
const re_dfa_t dfa 
) [static]

Definition at line 68 of file regex_internal.c.

{
  reg_errcode_t ret;
  memset (pstr, '\0', sizeof (re_string_t));
  re_string_construct_common (str, len, pstr, trans, icase, dfa);

  if (len > 0)
    {
      ret = re_string_realloc_buffers (pstr, len + 1);
      if (BE (ret != REG_NOERROR, 0))
       return ret;
    }
  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;

  if (icase)
    {
#ifdef RE_ENABLE_I18N
      if (dfa->mb_cur_max > 1)
       {
         while (1)
           {
             ret = build_wcs_upper_buffer (pstr);
             if (BE (ret != REG_NOERROR, 0))
              return ret;
             if (pstr->valid_raw_len >= len)
              break;
             if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
              break;
             ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
             if (BE (ret != REG_NOERROR, 0))
              return ret;
           }
       }
      else
#endif /* RE_ENABLE_I18N  */
       build_upper_buffer (pstr);
    }
  else
    {
#ifdef RE_ENABLE_I18N
      if (dfa->mb_cur_max > 1)
       build_wcs_buffer (pstr);
      else
#endif /* RE_ENABLE_I18N  */
       {
         if (trans != NULL)
           re_string_translate_buffer (pstr);
         else
           {
             pstr->valid_len = pstr->bufs_len;
             pstr->valid_raw_len = pstr->bufs_len;
           }
       }
    }

  return REG_NOERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void internal_function re_string_construct_common ( const char *  str,
Idx  len,
re_string_t pstr,
RE_TRANSLATE_TYPE  trans,
bool  icase,
const re_dfa_t dfa 
) [static]

Definition at line 171 of file regex_internal.c.

{
  pstr->raw_mbs = (const unsigned char *) str;
  pstr->len = len;
  pstr->raw_len = len;
  pstr->trans = trans;
  pstr->icase = icase;
  pstr->mbs_allocated = (trans != NULL || icase);
  pstr->mb_cur_max = dfa->mb_cur_max;
  pstr->is_utf8 = dfa->is_utf8;
  pstr->map_notascii = dfa->map_notascii;
  pstr->stop = pstr->len;
  pstr->raw_stop = pstr->stop;
}

Here is the caller graph for this function:

static unsigned int internal_function re_string_context_at ( const re_string_t input,
Idx  idx,
int  eflags 
) [static]

Definition at line 925 of file regex_internal.c.

{
  int c;
  if (BE (! REG_VALID_INDEX (idx), 0))
    /* In this case, we use the value stored in input->tip_context,
       since we can't know the character in input->mbs[-1] here.  */
    return input->tip_context;
  if (BE (idx == input->len, 0))
    return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
           : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
#ifdef RE_ENABLE_I18N
  if (input->mb_cur_max > 1)
    {
      wint_t wc;
      Idx wc_idx = idx;
      while(input->wcs[wc_idx] == WEOF)
       {
#ifdef DEBUG
         /* It must not happen.  */
         assert (REG_VALID_INDEX (wc_idx));
#endif
         --wc_idx;
         if (! REG_VALID_INDEX (wc_idx))
           return input->tip_context;
       }
      wc = input->wcs[wc_idx];
      if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc))
       return CONTEXT_WORD;
      return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
             ? CONTEXT_NEWLINE : 0);
    }
  else
#endif
    {
      c = re_string_byte_at (input, idx);
      if (bitset_contain (input->word_char, c))
       return CONTEXT_WORD;
      return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void internal_function re_string_destruct ( re_string_t pstr) [static]

Definition at line 911 of file regex_internal.c.

{
#ifdef RE_ENABLE_I18N
  re_free (pstr->wcs);
  re_free (pstr->offsets);
#endif /* RE_ENABLE_I18N  */
  if (pstr->mbs_allocated)
    re_free (pstr->mbs);
}

Here is the caller graph for this function:

Definition at line 131 of file regex_internal.c.

{
#ifdef RE_ENABLE_I18N
  if (pstr->mb_cur_max > 1)
    {
      wint_t *new_wcs;

      /* Avoid overflow.  */
      size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx));
      if (BE (SIZE_MAX / max_object_size < new_buf_len, 0))
       return REG_ESPACE;

      new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
      if (BE (new_wcs == NULL, 0))
       return REG_ESPACE;
      pstr->wcs = new_wcs;
      if (pstr->offsets != NULL)
       {
         Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len);
         if (BE (new_offsets == NULL, 0))
           return REG_ESPACE;
         pstr->offsets = new_offsets;
       }
    }
#endif /* RE_ENABLE_I18N  */
  if (pstr->mbs_allocated)
    {
      unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
                                      new_buf_len);
      if (BE (new_mbs == NULL, 0))
       return REG_ESPACE;
      pstr->mbs = new_mbs;
    }
  pstr->bufs_len = new_buf_len;
  return REG_NOERROR;
}

Here is the caller graph for this function:

Definition at line 573 of file regex_internal.c.

{
  Idx offset;

  if (BE (pstr->raw_mbs_idx <= idx, 0))
    offset = idx - pstr->raw_mbs_idx;
  else
    {
      /* Reset buffer.  */
#ifdef RE_ENABLE_I18N
      if (pstr->mb_cur_max > 1)
       memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
#endif /* RE_ENABLE_I18N */
      pstr->len = pstr->raw_len;
      pstr->stop = pstr->raw_stop;
      pstr->valid_len = 0;
      pstr->raw_mbs_idx = 0;
      pstr->valid_raw_len = 0;
      pstr->offsets_needed = 0;
      pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
                        : CONTEXT_NEWLINE | CONTEXT_BEGBUF);
      if (!pstr->mbs_allocated)
       pstr->mbs = (unsigned char *) pstr->raw_mbs;
      offset = idx;
    }

  if (BE (offset != 0, 1))
    {
      /* Should the already checked characters be kept?  */
      if (BE (offset < pstr->valid_raw_len, 1))
       {
         /* Yes, move them to the front of the buffer.  */
#ifdef RE_ENABLE_I18N
         if (BE (pstr->offsets_needed, 0))
           {
             Idx low = 0, high = pstr->valid_len, mid;
             do
              {
                mid = (high + low) / 2;
                if (pstr->offsets[mid] > offset)
                  high = mid;
                else if (pstr->offsets[mid] < offset)
                  low = mid + 1;
                else
                  break;
              }
             while (low < high);
             if (pstr->offsets[mid] < offset)
              ++mid;
             pstr->tip_context = re_string_context_at (pstr, mid - 1,
                                                 eflags);
             /* This can be quite complicated, so handle specially
               only the common and easy case where the character with
               different length representation of lower and upper
               case is present at or after offset.  */
             if (pstr->valid_len > offset
                && mid == offset && pstr->offsets[mid] == offset)
              {
                memmove (pstr->wcs, pstr->wcs + offset,
                        (pstr->valid_len - offset) * sizeof (wint_t));
                memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset);
                pstr->valid_len -= offset;
                pstr->valid_raw_len -= offset;
                for (low = 0; low < pstr->valid_len; low++)
                  pstr->offsets[low] = pstr->offsets[low + offset] - offset;
              }
             else
              {
                /* Otherwise, just find out how long the partial multibyte
                   character at offset is and fill it with WEOF/255.  */
                pstr->len = pstr->raw_len - idx + offset;
                pstr->stop = pstr->raw_stop - idx + offset;
                pstr->offsets_needed = 0;
                while (mid > 0 && pstr->offsets[mid - 1] == offset)
                  --mid;
                while (mid < pstr->valid_len)
                  if (pstr->wcs[mid] != WEOF)
                    break;
                  else
                    ++mid;
                if (mid == pstr->valid_len)
                  pstr->valid_len = 0;
                else
                  {
                    pstr->valid_len = pstr->offsets[mid] - offset;
                    if (pstr->valid_len)
                     {
                       for (low = 0; low < pstr->valid_len; ++low)
                         pstr->wcs[low] = WEOF;
                       memset (pstr->mbs, 255, pstr->valid_len);
                     }
                  }
                pstr->valid_raw_len = pstr->valid_len;
              }
           }
         else
#endif
           {
             pstr->tip_context = re_string_context_at (pstr, offset - 1,
                                                 eflags);
#ifdef RE_ENABLE_I18N
             if (pstr->mb_cur_max > 1)
              memmove (pstr->wcs, pstr->wcs + offset,
                      (pstr->valid_len - offset) * sizeof (wint_t));
#endif /* RE_ENABLE_I18N */
             if (BE (pstr->mbs_allocated, 0))
              memmove (pstr->mbs, pstr->mbs + offset,
                      pstr->valid_len - offset);
             pstr->valid_len -= offset;
             pstr->valid_raw_len -= offset;
#if DEBUG
             assert (pstr->valid_len > 0);
#endif
           }
       }
      else
       {
#ifdef RE_ENABLE_I18N
         /* No, skip all characters until IDX.  */
         Idx prev_valid_len = pstr->valid_len;

         if (BE (pstr->offsets_needed, 0))
           {
             pstr->len = pstr->raw_len - idx + offset;
             pstr->stop = pstr->raw_stop - idx + offset;
             pstr->offsets_needed = 0;
           }
#endif
         pstr->valid_len = 0;
#ifdef RE_ENABLE_I18N
         if (pstr->mb_cur_max > 1)
           {
             Idx wcs_idx;
             wint_t wc = WEOF;

             if (pstr->is_utf8)
              {
                const unsigned char *raw, *p, *end;

                /* Special case UTF-8.  Multi-byte chars start with any
                   byte other than 0x80 - 0xbf.  */
                raw = pstr->raw_mbs + pstr->raw_mbs_idx;
                end = raw + (offset - pstr->mb_cur_max);
                if (end < pstr->raw_mbs)
                  end = pstr->raw_mbs;
                p = raw + offset - 1;
#ifdef _LIBC
                /* We know the wchar_t encoding is UCS4, so for the simple
                   case, ASCII characters, skip the conversion step.  */
                if (isascii (*p) && BE (pstr->trans == NULL, 1))
                  {
                    memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
                    /* pstr->valid_len = 0; */
                    wc = (wchar_t) *p;
                  }
                else
#endif
                  for (; p >= end; --p)
                    if ((*p & 0xc0) != 0x80)
                     {
                       mbstate_t cur_state;
                       wchar_t wc2;
                       Idx mlen = raw + pstr->len - p;
                       size_t mbclen;

#if 0 /* dead code: buf is set but never used */
                       unsigned char buf[6];
                       if (BE (pstr->trans != NULL, 0))
                         {
                           int i = mlen < 6 ? mlen : 6;
                           while (--i >= 0)
                            buf[i] = pstr->trans[p[i]];
                         }
#endif
                       /* XXX Don't use mbrtowc, we know which conversion
                          to use (UTF-8 -> UCS4).  */
                       memset (&cur_state, 0, sizeof (cur_state));
                       mbclen = __mbrtowc (&wc2, (const char *) p, mlen,
                                         &cur_state);
                       if (raw + offset - p <= mbclen
                           && mbclen < (size_t) -2)
                         {
                           memset (&pstr->cur_state, '\0',
                                  sizeof (mbstate_t));
                           pstr->valid_len = mbclen - (raw + offset - p);
                           wc = wc2;
                         }
                       break;
                     }
              }

             if (wc == WEOF)
              pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
             if (wc == WEOF)
              pstr->tip_context
                = re_string_context_at (pstr, prev_valid_len - 1, eflags);
             else
              pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
                                  && IS_WIDE_WORD_CHAR (wc))
                                 ? CONTEXT_WORD
                                 : ((IS_WIDE_NEWLINE (wc)
                                    && pstr->newline_anchor)
                                   ? CONTEXT_NEWLINE : 0));
             if (BE (pstr->valid_len, 0))
              {
                for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
                  pstr->wcs[wcs_idx] = WEOF;
                if (pstr->mbs_allocated)
                  memset (pstr->mbs, 255, pstr->valid_len);
              }
             pstr->valid_raw_len = pstr->valid_len;
           }
         else
#endif /* RE_ENABLE_I18N */
           {
             int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
             pstr->valid_raw_len = 0;
             if (pstr->trans)
              c = pstr->trans[c];
             pstr->tip_context = (bitset_contain (pstr->word_char, c)
                               ? CONTEXT_WORD
                               : ((IS_NEWLINE (c) && pstr->newline_anchor)
                                  ? CONTEXT_NEWLINE : 0));
           }
       }
      if (!BE (pstr->mbs_allocated, 0))
       pstr->mbs += offset;
    }
  pstr->raw_mbs_idx = idx;
  pstr->len -= offset;
  pstr->stop -= offset;

  /* Then build the buffers.  */
#ifdef RE_ENABLE_I18N
  if (pstr->mb_cur_max > 1)
    {
      if (pstr->icase)
       {
         reg_errcode_t ret = build_wcs_upper_buffer (pstr);
         if (BE (ret != REG_NOERROR, 0))
           return ret;
       }
      else
       build_wcs_buffer (pstr);
    }
  else
#endif /* RE_ENABLE_I18N */
    if (BE (pstr->mbs_allocated, 0))
      {
       if (pstr->icase)
         build_upper_buffer (pstr);
       else if (pstr->trans != NULL)
         re_string_translate_buffer (pstr);
      }
    else
      pstr->valid_len = pstr->len;

  pstr->cur_idx = 0;
  return REG_NOERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void internal_function re_string_translate_buffer ( re_string_t pstr) [static]

Definition at line 552 of file regex_internal.c.

{
  Idx buf_idx, end_idx;
  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;

  for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx)
    {
      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx];
      pstr->mbs[buf_idx] = pstr->trans[ch];
    }

  pstr->valid_len = buf_idx;
  pstr->valid_raw_len = buf_idx;
}

Here is the caller graph for this function:

Definition at line 1568 of file regex_internal.c.

{
  struct re_state_table_entry *spot;
  reg_errcode_t err;
  Idx i;

  newstate->hash = hash;
  err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
  if (BE (err != REG_NOERROR, 0))
    return REG_ESPACE;
  for (i = 0; i < newstate->nodes.nelem; i++)
    {
      Idx elem = newstate->nodes.elems[i];
      if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
       if (BE (! re_node_set_insert_last (&newstate->non_eps_nodes, elem), 0))
         return REG_ESPACE;
    }

  spot = dfa->state_table + (hash & dfa->state_hash_mask);
  if (BE (spot->alloc <= spot->num, 0))
    {
      Idx new_alloc = 2 * spot->num + 2;
      re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
                                         new_alloc);
      if (BE (new_array == NULL, 0))
       return REG_ESPACE;
      spot->array = new_array;
      spot->alloc = new_alloc;
    }
  spot->array[spot->num++] = newstate;
  return REG_NOERROR;
}

Here is the call graph for this function:

Here is the caller graph for this function: