Logo Search packages:      
Sourcecode: ksh version File versions  Download package

regrexec.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*          Copyright (c) 1985-2007 AT&T Intellectual Property          *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                    by AT&T Intellectual Property                     *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                  David Korn <dgk@research.att.com>                   *
*                   Phong Vo <kpv@research.att.com>                    *
*                                                                      *
***********************************************************************/
#pragma prototyped

/*
 * posix regex record executor
 * multiple record sized-buffer interface
 */

#include "reglib.h"

/*
 * call regnexec() on records selected by Boyer-Moore
 */

int
regrexec(const regex_t* p, const char* s, size_t len, size_t nmatch, regmatch_t* match, regflags_t flags, int sep, void* handle, regrecord_t record)
{
      register unsigned char* buf = (unsigned char*)s;
      register unsigned char* beg;
      register unsigned char* l;
      register unsigned char* r;
      register unsigned char* x;
      register size_t*  skip;
      register size_t*  fail;
      register Bm_mask_t**    mask;
      register size_t         index;
      register int            n;
      unsigned char*          end;
      size_t                  mid;
      int               complete;
      int               exactlen;
      int               leftlen;
      int               rightlen;
      int               inv;
      Bm_mask_t         m;
      Env_t*                  env;
      Rex_t*                  e;

      if (!s || !p || !(env = p->env) || (e = env->rex)->type != REX_BM)
            return REG_BADPAT;
      inv = (flags & REG_INVERT) != 0;
      buf = beg = (unsigned char*)s;
      end = buf + len;
      mid = (len < e->re.bm.right) ? 0 : (len - e->re.bm.right);
      skip = e->re.bm.skip;
      fail = e->re.bm.fail;
      mask = e->re.bm.mask;
      complete = e->re.bm.complete && !nmatch;
      exactlen = e->re.bm.size;
      leftlen = e->re.bm.left + exactlen;
      rightlen = exactlen + e->re.bm.right;
      index = leftlen++;
      for (;;)
      {
            while ((index += skip[buf[index]]) < mid);
            if (index < HIT)
                  goto impossible;
            index -= HIT;
            m = mask[n = exactlen - 1][buf[index]];
            do
            {
                  if (!n--)
                        goto possible;
            } while (m &= mask[n][buf[--index]]);
            if ((index += fail[n + 1]) < len)
                  continue;
 impossible:
            if (inv)
            {
                  l = r = buf + len;
                  goto invert;
            }
            n = 0;
            goto done;
 possible:
            r = (l = buf + index) + exactlen;
            while (l > beg)
                  if (*--l == sep)
                  {
                        l++;
                        break;
                  }
            if ((r - l) < leftlen)
                  goto spanned;
            while (r < end && *r != sep)
                  r++;
            if ((r - (buf + index)) < rightlen)
                  goto spanned;
            if (complete || (env->rex = ((r - l) > 128) ? e : e->next) && !(n = regnexec(p, (char*)l, r - l, nmatch, match, flags)))
            {
                  if (inv)
                  {
 invert:
                        x = beg;
                        while (beg < l)
                        {
                              while (x < l && *x != sep)
                                    x++;
                              if (n = (*record)(handle, (char*)beg, x - beg))
                                    goto done;
                              beg = ++x;
                        }
                  }
                  else if (n = (*record)(handle, (char*)l, r - l))
                        goto done;
                  if ((index = (r - buf) + leftlen) >= len)
                  {
                        n = (inv && (++r - buf) < len) ? (*record)(handle, (char*)r, (buf + len) - r): 0;
                        goto done;
                  }
                  beg = r + 1;
            }
            else if (n != REG_NOMATCH)
                  goto done;
            else
            {
 spanned:
                  if ((index += exactlen) >= mid)
                        goto impossible;
            }
      }
 done:
      env->rex = e;
      return n;
}

Generated by  Doxygen 1.6.0   Back to index