da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * posix regex compiler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "reglib.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _PACKAGE_ast
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "lclib.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define serialize re_serialize /* hp.ia64 <unistd.h>! */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define C_ESC (-1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define C_MB (-2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _AST_REGEX_DEBUG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DEBUG_TEST(f,y,n) ((debug&(debug_flag=f))?(y):(n))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DEBUG_CODE(f,y,n) do if(debug&(f)){y}else{n} while(0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DEBUG_INIT() do { char* t; if (!debug) { debug = 0x80000000; if (t = getenv("_AST_regex_comp_debug")) debug |= strtoul(t, NiL, 0); } } while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic unsigned long debug;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic unsigned long debug_flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DEBUG_INIT()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DEBUG_TEST(f,y,n) (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DEBUG_CODE(f,y,n) do {n} while(0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _PACKAGE_ast
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct Cchr_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dtlink_t lnk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char nam[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Ckey_t key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Cchr_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define eat(p) do{if ((p)->token.push)(p)->token.push=0;else (p)->cursor+=(p)->token.len;}while (0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * determine whether greedy matching will work, i.e. produce
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the best match first. such expressions are "easy", and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * need no backtracking once a complete match is found.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if an expression has backreferences or alts it's hard
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * else if it has only one closure it's easy
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * else if all closures are simple (i.e. one-character) it's easy
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * else it's hard.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct Stats_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long l; /* min length to left of x */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long k; /* min length to left of y */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long m; /* min length */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long n; /* max length */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned short a; /* number of alternations */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned short b; /* number of backrefs */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned short c; /* number of closures */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner unsigned short e; /* $ */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned short i; /* number of negations */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned short p; /* number of named subexpressions */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned short s; /* number of simple closures */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned short t; /* number of tries */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned short u; /* number of unnamed subexpressions */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* x; /* max length REX_STRING */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* y; /* max length REX_TRIE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Stats_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct Token_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long min;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long max;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short lex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short esc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short att;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short push;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Token_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct Cenv_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int delimiter; /* pattern delimiter */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int error; /* last error */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int explicit; /* explicit match on this char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int mappeddot; /* inverse mapped '.' */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int mappednewline; /* inverse mapped '\n' */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int mappedslash; /* inverse mapped '/' */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regflags_t flags; /* flags arg to regcomp */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int type; /* BRE,ERE,ARE,SRE,KRE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* cursor; /* curent point in re */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* pattern; /* the original pattern */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* literal; /* literal restart pattern */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int parno; /* number of last open paren */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int parnest; /* paren nest count */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int posixkludge; /* to make * nonspecial */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int regexp; /* <regexp.h> compatibility */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Token_t token; /* token lookahead */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Stats_t stats; /* RE statistics */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int terminator; /* pattern terminator */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* paren[2*(BACK_REF_MAX+2)];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* paren[i]!=0 if \i defined */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regex_t* regex; /* user handle */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regdisc_t* disc; /* user discipline */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* map; /* external to native ccode map */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* MAP; /* fold and/or map */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Cenv_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * allocate a new Rex_t node
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Rex_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinnode(Cenv_t* env, int type, int lo, int hi, size_t extra)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Rex_t* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e = (Rex_t*)alloc(env->disc, 0, sizeof(Rex_t) + extra))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(e, 0, sizeof(Rex_t) + extra);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->type = type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->marked = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->lo = lo;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->hi = hi;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->flags = env->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->map = (e->flags & REG_ICASE) ? env->MAP : env->map;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->explicit = env->explicit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (extra)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.data = (char*)e + sizeof(Rex_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * free a Trie_node_t node
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintriedrop(regdisc_t* disc, Trie_node_t* e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin triedrop(disc, e->son);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin triedrop(disc, e->sib);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin alloc(disc, e, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * free a Rex_t node
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindrop(regdisc_t* disc, Rex_t* e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e && !(disc->re_flags & REG_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (e->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_ALT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_CONJ:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(disc, e->re.group.expr.binary.left);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(disc, e->re.group.expr.binary.right);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_AHEAD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_AHEAD_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_BEHIND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_BEHIND_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_CUT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_NEG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_REP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(disc, e->re.group.expr.rex);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_TRIE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i <= UCHAR_MAX; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin triedrop(disc, e->re.trie.root[i]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = e->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin alloc(disc, e, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (e = x);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * mark e and descendants minimal
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmark(register Rex_t* e, int set)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e && !e->marked)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->marked = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (set)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->flags |= REG_MINIMAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->flags &= ~REG_MINIMAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (e->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_ALT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_CONJ:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_COND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->re.group.expr.binary.left)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mark(e->re.group.expr.binary.left, set);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->re.group.expr.binary.right)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mark(e->re.group.expr.binary.right, set);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_AHEAD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_AHEAD_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_BEHIND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_BEHIND_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_CUT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_NEG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_REP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_TRIE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mark(e->re.group.expr.rex, set);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (e = e->next);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * assign subexpression numbers by a preorder tree walk
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinserialize(Cenv_t* env, Rex_t* e, int n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->serial = n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (e->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_ALT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_COND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->re.group.expr.binary.left)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = serialize(env, e->re.group.expr.binary.left, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.group.expr.binary.serial = n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->re.group.expr.binary.right)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = serialize(env, e->re.group.expr.binary.right, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_CONJ:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = serialize(env, e->re.group.expr.binary.left, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = serialize(env, e->re.group.expr.binary.right, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_AHEAD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_AHEAD_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_BEHIND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_BEHIND_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_CUT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_NEG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_REP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = serialize(env, e->re.group.expr.rex, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (e = e->next);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * catenate e and f into a sequence, collapsing them if possible
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Rex_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincat(Cenv_t* env, Rex_t* e, Rex_t* f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* g;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->type == REX_NULL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f->type == REX_NULL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g = f->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = g;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (e->type == REX_DOT && f->type == REX_DOT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned int m = e->lo + f->lo;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned int n = e->hi + f->hi;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (m <= RE_DUP_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->hi > RE_DUP_MAX || f->hi > RE_DUP_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = RE_DUP_INF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto combine;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (n <= RE_DUP_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin combine:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->lo = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->hi = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g = f->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = g;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->next = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * collect re statistics
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstats(register Cenv_t* env, register Rex_t* e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned long n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned long m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long cm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long nm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long cn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long nn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (e->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_ALT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = env->stats.x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = env->stats.l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin y = env->stats.y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = env->stats.k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = env->stats.t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++env->stats.a <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cm = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cn = env->stats.n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stats(env, e->re.group.expr.binary.left))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = env->stats.n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->re.group.expr.binary.right && stats(env, e->re.group.expr.binary.right))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->stats.m > m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->stats.m += cm) < m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->stats.n < n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.n = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = env->stats.n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->stats.n += cn) < n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.x = x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.l = l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.y = y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.k = k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.t = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_BACK:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++env->stats.b <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_CLASS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_COLL_CLASS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_DOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_ONECHAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->stats.m += e->lo) < n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->hi != RE_DUP_INF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = env->stats.n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->stats.n += e->hi) < n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->lo != e->hi)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++env->stats.c <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++env->stats.s <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_CONJ:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cm = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cn = env->stats.n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stats(env, e->re.group.expr.binary.left))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nm = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nn = env->stats.n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stats(env, e->re.group.expr.binary.right))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->stats.m < nm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = nm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nm = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->stats.m += cm) < nm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->stats.n < nn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.n = nn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nn = env->stats.n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->stats.n += cn) < nn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case REX_END:
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner env->stats.e = 1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->re.group.number && ++env->stats.p <= 0 || !e->re.group.number && ++env->stats.u <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stats(env, e->re.group.expr.rex))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_AHEAD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_AHEAD_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_BEHIND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_BEHIND_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = env->stats.n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = env->stats.x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin y = env->stats.y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stats(env, e->re.group.expr.rex))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.n = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.x = x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.y = y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (e->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_AHEAD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_BEHIND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++env->stats.u <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_COND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++env->stats.u <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = env->stats.n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = env->stats.x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin y = env->stats.y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->re.group.size > 0 && ++env->stats.b <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->re.group.expr.binary.left && stats(env, e->re.group.expr.binary.left))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (q = e->re.group.expr.binary.right)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (q->re.group.expr.binary.left && stats(env, q->re.group.expr.binary.left))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (q->re.group.expr.binary.right && stats(env, q->re.group.expr.binary.right))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.n = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.x = x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.y = y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_CUT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++env->stats.u <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = env->stats.n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = env->stats.x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin y = env->stats.y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stats(env, e->re.group.expr.rex))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.n = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.x = x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.y = y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_NEG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.i++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = env->stats.x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = env->stats.l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin y = env->stats.y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = env->stats.k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = env->stats.t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cm = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stats(env, e->re.group.expr.rex))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = !env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->stats.m += cm) < cm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.x = x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.l = l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.y = y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.k = k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.t = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_REP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = env->stats.x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = env->stats.l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin y = env->stats.y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = env->stats.k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = env->stats.t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++env->stats.c <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = env->stats.b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = env->stats.c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cm = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stats(env, e->re.group.expr.rex))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->stats.m == 1 && b == env->stats.b && c == env->stats.c && ++env->stats.s <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->lo < 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.x = x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.l = l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.y = y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.k = k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.t = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.m = cm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->stats.m *= e->lo) > 0 && env->stats.m < m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->stats.m += cm) < m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->stats.x != x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.l = cm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->stats.y != y)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.k = cm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_STRING:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!e->map)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cm = env->stats.m;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((env->stats.m += e->re.string.size) < cm)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cn = env->stats.n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((env->stats.n += e->re.string.size) < cn)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!env->stats.x || env->stats.x->re.string.size < e->re.string.size)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin env->stats.x = e;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin env->stats.l = cm;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_TRIE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++env->stats.s <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cm = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->stats.m += e->re.trie.min) < cm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cn = env->stats.n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->stats.n += e->re.trie.max) < cn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.t++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!env->stats.y || env->stats.y->re.trie.min < e->re.trie.min)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.y = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->stats.k = cm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (e = e->next);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int token(Cenv_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmagic(register Cenv_t* env, register int c, int escaped)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int o = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int e = env->error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int l = env->token.len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short* mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp = state.magic[c])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = mp[env->type+escaped];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c >= T_META)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (char*)env->cursor + env->token.len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_LEFT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*sp >= '0' && *sp <= '9')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n > (INT_MAX / 10))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADBR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = n * 10 + *sp++ - '0';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sp == ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (env->type < SRE || *sp != ',')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin env->error = *sp ? REG_BADBR : REG_EBRACE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto bad;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (n > RE_DUP_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADBR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.min = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*sp == ',')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = ++sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*sp >= '0' && *sp <= '9')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n > (INT_MAX / 10))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADBR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = n * 10 + *sp++ - '0';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sp == ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = RE_DUP_INF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (n < env->token.min)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADBR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.max = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EBRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!escaped)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADBR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (escaped)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADBR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*sp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EBRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '}':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADBR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len = sp - (char*)env->cursor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_RIGHT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EBRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_OPEN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type < SRE && *sp == '?')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.lex = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto group;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_ESCAPE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = chresc(sp - 2, &ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep < sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len += ep - sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c >= T_META)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.lex = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = C_ESC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BACK+0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BACK+1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BACK+2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BACK+3:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BACK+4:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BACK+5:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BACK+6:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BACK+7:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = chresc(sp - 2, &ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep > sp + 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len += ep - sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BACK+8:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BACK+9:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type == SRE || c == T_BACK && !(env->flags & REG_LENIENT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADESC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->flags & REG_MULTIREF) && isdigit(*sp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (c - T_BACK) * 10 + (*sp - '0');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c > 0 && c <= env->parno && env->paren[c])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c += T_BACK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = chresc(sp - 2, &ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == T_BACK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BAD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (escaped == 1 && (env->flags & REG_LENIENT) && (c = mp[env->type+escaped+2]) >= T_META)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type >= SRE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == T_DOT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c < T_OPEN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type == KRE && *(env->cursor + env->token.len) == '-' && *(env->cursor + env->token.len + 1) == '(')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.att = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type == KRE && *(env->cursor + env->token.len) == '(')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_AT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_PERCENT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.lex = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto group;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_TILDE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.lex = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto group;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.lex = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = T_OPEN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == T_STAR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = T_DOTSTAR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == T_QUES)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = T_DOT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = o;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len = l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c > T_BACK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (c - T_BACK) * 2 - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (c > env->parno || !env->paren[c]) ? o : T_BACK + c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (env->type == KRE && !env->parnest && (env->flags & REG_SHELL_GROUP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == T_AND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '&';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == T_BAR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '|';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == T_OPEN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '(';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (escaped == 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type >= SRE && !(env->flags & REG_SHELL_ESCAPED) || (env->flags & REG_ESCAPE) && (c == '[' || c == '-' || c == ']' || env->delimiter && c == env->delimiter))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*ok*/;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADESC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (escaped && !(env->flags & REG_LENIENT) && c != ']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADESC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin group:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (char*)env->cursor + env->token.len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*sp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ')':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '#':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*sp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_BAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ')':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_GROUP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor = (unsigned char*)sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return token(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bad:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (escaped == 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (env->flags & REG_LENIENT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return o;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (escaped == 1 && !env->error)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mp || o == ']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return o;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADESC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_BAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintoken(register Cenv_t* env)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int posixkludge;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->token.push)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return env->token.lex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.att = env->token.esc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env->token.len = MBSIZE(env->cursor)) > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return env->token.lex = C_MB;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.lex = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *env->cursor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == 0 || c == env->delimiter || c == env->terminator)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_END;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(env->flags & REG_COMMENT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *++env->cursor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == 0 || c == env->delimiter)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_END;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (c != '\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!isspace(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '\n' && (env->flags & REG_MULTIPLE) && !env->delimiter)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->parnest)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_BAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->parno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->pattern = env->cursor + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_BAR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->flags & REG_LITERAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (posixkludge = env->posixkludge)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->posixkludge = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '*')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->flags & REG_SHELL_ESCAPED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(c = *(env->cursor + 1)) || c == env->terminator)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->flags & REG_LENIENT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.esc = env->token.len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len += MBSIZE(env->cursor + 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EESCAPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_BAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.esc = env->token.len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len += MBSIZE(env->cursor + 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->delimiter && c == 'n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == env->delimiter)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return magic(env, c, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '(' && env->type == BRE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->posixkludge = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == ')' && env->type == BRE && env->parnest <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_BAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (isspace(c) && (env->flags & REG_COMMENT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return magic(env, c, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '$')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type == BRE && (*(env->cursor + 1) == 0 || *(env->cursor + 1) == env->delimiter || *(env->cursor + 1) == env->terminator || *(env->cursor + 1) == '\\' && *(env->cursor + 2) == ')') || (env->flags & REG_MULTIPLE) && *(env->cursor + 1) == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_DOLL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '^')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (env->type == BRE && (env->cursor == env->pattern || posixkludge == 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner env->posixkludge = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_CFLX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == ')')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type != BRE && env->parnest <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '/' && env->explicit == env->mappedslash)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*(env->cursor + env->token.len) == c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return T_SLASHPLUS;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return magic(env, c, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Celt_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincol(Celt_t* ce, int ic, unsigned char* bp, int bw, int bc, unsigned char* ep, int ew, int ec)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int cc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int bt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int et;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Ckey_t key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (bw == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = bc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ic)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (isupper(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = tolower(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (islower(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = toupper(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *k++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (bw < COLL_KEY_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s = (char*)bp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (ic)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = mbchar(s);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (iswupper(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = towlower(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (iswlower(c))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = towupper(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (cc > 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = -1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner k += mbconv((char*)k, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (e = k + bw; k < e; *k++ = *s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *k = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mbxfrm(ce->beg, key, COLL_KEY_MAX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = mbchar(k);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (iswupper(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bt = COLL_range_uc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (iswlower(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bt = COLL_range_lc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bt = COLL_range;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ew == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ec;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ic)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (isupper(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = tolower(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (islower(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = toupper(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *k++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (ew < COLL_KEY_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s = (char*)ep;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (ic)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = mbchar(s);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (iswupper(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = towlower(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (iswlower(c))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = towupper(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (cc > 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = -1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner k += mbconv((char*)k, c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (e = k + ew; k < e; *k++ = *s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *k = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mbxfrm(ce->end, key, COLL_KEY_MAX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = mbchar(k);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (iswupper(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin et = COLL_range_uc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (iswlower(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin et = COLL_range_lc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin et = COLL_range;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->typ = bt == et ? bt : COLL_range;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->typ = COLL_char;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!ic || !cc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ic = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return ce;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Rex_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbra(Cenv_t* env)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int neg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int inrange;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int complicated;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int collate;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int elements;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* start;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* begin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regclass_t f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char buf[4 * (COLL_KEY_MAX + 1)];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _PACKAGE_ast
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ic;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char mbc[COLL_KEY_MAX + 1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = node(env, REX_CLASS, 1, 1, sizeof(Set_t))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin collate = complicated = elements = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*env->cursor == '^' || env->type >= SRE && *env->cursor == '!')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin neg = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin neg = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin first = env->cursor;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin start = first + MBSIZE(first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*env->cursor == 0 || *(env->cursor + 1) == 0 || *env->cursor == env->terminator || *(env->cursor + 1) == env->terminator || (env->flags & REG_ESCAPE) && (*env->cursor == env->delimiter || *env->cursor != '\\' && *(env->cursor + 1) == env->delimiter))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin = env->cursor + MBSIZE(env->cursor);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * inrange: 0=no, 1=possibly, 2=definitely
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (!(c = *env->cursor) || c == env->terminator || c == env->delimiter && (env->flags & REG_ESCAPE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor += (w = MBSIZE(env->cursor));
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (c == '\\' && ((env->flags & REG_CLASS_ESCAPE) || env->type >= SRE && env->parnest || *env->cursor == env->delimiter && (env->flags & REG_ESCAPE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*env->cursor)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*env->cursor == 'n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (env->type < SRE || !(env->flags & REG_SHELL_ESCAPED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = magic(env, *env->cursor, 2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->token.len > 1 || w != T_BAD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->token.len == 1 && (f = classfun(w)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type < SRE && !(env->flags & REG_LENIENT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto erange;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (c = 0; c <= UCHAR_MAX; c++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*f)(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin complicated++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin elements++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->token.len > 1 || w >= 0 && w < T_META)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c > UCHAR_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type < SRE && !(env->flags & REG_LENIENT) && !mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto erange;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = UCHAR_MAX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor += env->token.len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == ']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->cursor == begin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange != 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, last);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin elements++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange == 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, '-');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin elements++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!inrange && env->cursor != begin && *env->cursor != ']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type < SRE && !(env->flags & REG_LENIENT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto erange;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (inrange == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin complicated++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*env->cursor)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (env->regexp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto normal;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, last);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin elements++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = regclass((char*)env->cursor, (char**)&env->cursor)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->cursor == start && (c = *(env->cursor + 1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = start = env->cursor + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*++s && *s != ':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == ':' && *(s + 1) == ']' && *(s + 2) == ']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((i = (s - start)) == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '<':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = REX_WBEG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '>':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = REX_WEND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor = s + 3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return node(env, i, 0, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ECTYPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (c = 0; c <= UCHAR_MAX; c++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*f)(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin complicated++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin elements++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '=':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (env->regexp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto normal;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange == 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto erange;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, last);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin elements++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = regcollate((char*)env->cursor, (char**)&env->cursor, (char*)buf, sizeof(buf))) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto ecollate;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin collate++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, buf[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = buf[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin complicated++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin elements++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '.':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (env->regexp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto normal;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = regcollate((char*)env->cursor, (char**)&env->cursor, (char*)buf, sizeof(buf))) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto ecollate;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin collate++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = buf[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin complicated++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz normal:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*env->cursor == env->terminator || *env->cursor == env->delimiter && (env->flags & REG_ESCAPE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (w > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin complicated++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange == 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (last <= c)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner for (i = last; i <= c; i++)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner setadd(e->re.charclass, i);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner inrange = env->type >= SRE || (env->flags & REG_LENIENT);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner elements += 2;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if (env->type >= SRE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, last);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, c);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner elements += 2;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner inrange = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if (!(env->flags & REG_LENIENT))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner goto erange;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner inrange = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (inrange == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, last);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin elements++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _PACKAGE_ast
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (complicated && mbcoll())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dt_t* dt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Cchr_t* cc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Cchr_t* tc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Cchr_t* xc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Celt_t* ce;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Cchr_t key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int rw;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int rc;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int wc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* rp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* pp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char* wp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char cb[2][COLL_KEY_MAX+1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static Dtdisc_t disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static const char primary[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(dt = (Dt_t*)LCINFO(AST_LC_COLLATE)->data))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disc.key = offsetof(Cchr_t, key);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((cc = newof(0, Cchr_t, elementsof(primary), 0)) && (dt = dtopen(&disc, Dttree)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < elementsof(primary) - 1; i++, cc++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->nam[0] = primary[i];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mbxfrm(cc->key, cc->nam, COLL_KEY_MAX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtinsert(dt, cc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < elementsof(cc->key); i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc->key[i] = ~0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtinsert(dt, cc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin LCINFO(AST_LC_COLLATE)->data = (void*)dt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(cc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (dt)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ic = env->flags & REG_ICASE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin elements *= 2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!(e = node(env, REX_COLL_CLASS, 1, 1, (elements + 2) * sizeof(Celt_t))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce = (Celt_t*)e->re.data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.collate.invert = neg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.collate.elements = ce;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor = first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = *env->cursor) == 0 || c == env->terminator || (env->flags & REG_ESCAPE) && c == env->delimiter)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = env->cursor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor += (w = MBSIZE(env->cursor));
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (c == '\\' && ((env->flags & REG_CLASS_ESCAPE) || env->type >= SRE && env->parnest || *env->cursor == env->delimiter && (env->flags & REG_ESCAPE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*env->cursor)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*env->cursor == 'n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (env->type < SRE || !(env->flags & REG_SHELL_ESCAPED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = magic(env, *env->cursor, 2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->token.len > 1 || w != T_BAD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->token.len == 1 && (f = classfun(w)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type < SRE && !(env->flags & REG_LENIENT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto erange;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->fun = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->typ = COLL_call;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->token.len > 1 || w >= 0 && w < T_META)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = w;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner w = mbconv(mbc, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = (unsigned char*)mbc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor += env->token.len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == ']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->cursor == begin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rp = pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rw = w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange != 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce = col(ce, ic, rp, rw, rc, NiL, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange == 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce = col(ce, ic, NiL, 1, '-', NiL, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!inrange && env->cursor != begin && *env->cursor != ']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type < SRE && !(env->flags & REG_LENIENT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto erange;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (inrange == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*env->cursor)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (env->regexp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto complicated_normal;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce = col(ce, ic, rp, rw, rc, NiL, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = regclass((char*)env->cursor, (char**)&env->cursor)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->cursor == start && (c = *(env->cursor + 1)) && *(env->cursor + 2) == ':' && *(env->cursor + 3) == ']' && *(env->cursor + 4) == ']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '<':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = REX_WBEG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '>':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = REX_WEND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor += 5;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return node(env, i, 0, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ECTYPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->fun = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->typ = COLL_call;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '=':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (env->regexp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto complicated_normal;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange == 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto erange;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce = col(ce, ic, rp, rw, rc, NiL, 0, 0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pp = (unsigned char*)cb[inrange];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rp = env->cursor + 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((rw = regcollate((char*)env->cursor, (char**)&env->cursor, (char*)pp, COLL_KEY_MAX)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto ecollate;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin wp = (char*)pp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin wc = mbchar(wp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ic)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (iswupper(wc))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin wc = towlower(wc);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner rw = mbconv((char*)pp, wc);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = 'u';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (iswlower(wc))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = 'l';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (;;)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mbxfrm(key.key, (char*)pp, COLL_KEY_MAX);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!(cc = (Cchr_t*)dtsearch(dt, &key)) && !(cc = (Cchr_t*)dtprev(dt, &key)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto ecollate;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin xc = (tc = (Cchr_t*)dtprev(dt, cc)) && !strcasecmp((char*)tc->nam, (char*)cc->nam) ? tc : cc;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (c == 'l' || c == 'L' && !(c = 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->typ = COLL_range_lc;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (c == 'u' || c == 'U' && !(c = 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->typ = COLL_range_uc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->typ = COLL_range;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy((char*)ce->beg, (char*)xc->key);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cc = (Cchr_t*)dtnext(dt, cc)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto ecollate;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!strcasecmp((char*)xc->nam, (char*)cc->nam) && (tc = (Cchr_t*)dtnext(dt, cc)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cc = tc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy((char*)ce->end, (char*)cc->key);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->max = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (c == 'u')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin wc = towlower(wc);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = 'L';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin wc = towupper(wc);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = 'U';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner rw = mbconv((char*)pp, wc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = *pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '.':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (env->regexp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto complicated_normal;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pp = (unsigned char*)cb[inrange];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((w = regcollate((char*)env->cursor, (char**)&env->cursor, (char*)pp, COLL_KEY_MAX)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto ecollate;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = buf[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz complicated_normal:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*env->cursor == env->terminator || *env->cursor == env->delimiter && (env->flags & REG_ESCAPE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (inrange == 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce = col(ce, ic, rp, rw, rc, pp, w, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (strcmp((char*)ce->beg, (char*)ce->end) > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type < SRE && !(env->flags & REG_LENIENT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto erange;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (ce-1)->typ = COLL_char;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy((char*)ce->beg, (char*)(ce-1)->end);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->typ = COLL_char;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = env->type >= SRE || (env->flags & REG_LENIENT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (inrange == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce = col(ce, ic, rp, rw, rc, NiL, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inrange = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rp = pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rw = w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rc = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->typ = COLL_end;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (collate)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto ecollate;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->flags & REG_ICASE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i <= UCHAR_MAX; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (settst(e->re.charclass, i))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isupper(i))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = tolower(i);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (islower(i))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = toupper(i);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (neg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < elementsof(e->re.charclass->bits); i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.charclass->bits[i] ^= ~0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->explicit >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setclr(e->re.charclass, env->explicit);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ecollate:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ECOLLATE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin erange:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ERANGE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!env->error)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EBRACK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Rex_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinccl(Cenv_t* env, int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Celt_t* ce;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regclass_t f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = classfun(type)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADESC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mbcoll())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = node(env, REX_CLASS, 1, 1, sizeof(Set_t))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i <= UCHAR_MAX; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*f)(i))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setadd(e->re.charclass, i);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->explicit >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setclr(e->re.charclass, env->explicit);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = node(env, REX_COLL_CLASS, 1, 1, 2 * sizeof(Celt_t))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce = (Celt_t*)e->re.data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.collate.invert = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.collate.elements = ce;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->fun = f;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ce->typ = COLL_call;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ce->typ = COLL_end;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Rex_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinrep(Cenv_t* env, Rex_t* e, int number, int last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long m = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long n = RE_DUP_INF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int minimal = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (token(env))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BANG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = node(env, REX_NEG, m, n, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.expr.rex = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_QUES:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_STAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_PLUS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_LEFT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = env->token.min;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = env->token.max;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->token.att)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin minimal = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (env->type < SRE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (token(env))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_QUES:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin minimal = !(env->flags & REG_MINIMAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_STAR: /*AST*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin minimal = !!(env->flags & REG_MINIMAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (e->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_DOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_CLASS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_COLL_CLASS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_ONECHAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->lo = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->hi = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (minimal >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mark(e, minimal);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if HUH_2002_08_07
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_BEG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_BEG_STR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_END_STR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_FIN_STR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_WBEG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_WEND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_WORD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_WORD_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADRPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (m == 1 && n == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (minimal >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mark(e, minimal);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = node(env, REX_REP, m, n, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.expr.rex = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.number = number;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.last = last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (minimal >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mark(f, minimal);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (m <= n && n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; e && e->type >= REX_GROUP && e->type <= REX_GROUP_CUT; e = e->re.group.expr.rex);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e && e->type == REX_NEG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->type = REX_GROUP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinisstring(Rex_t* e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (e->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_ONECHAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e->lo == 1 && e->hi == 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_STRING:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Trie_node_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintrienode(Cenv_t* env, int c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Trie_node_t* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t = (Trie_node_t*)alloc(env->disc, 0, sizeof(Trie_node_t)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(t, 0, sizeof(Trie_node_t));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->c = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininsert(Cenv_t* env, Rex_t* f, Rex_t* g)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Trie_node_t* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char tmp[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (f->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_ONECHAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(s = tmp) = f->re.onechar;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = s + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_STRING:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = f->re.string.base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = s + f->re.string.size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(t = g->re.trie.root[*s]) && !(t = g->re.trie.root[*s] = trienode(env, *s)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (len = 1;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t->c == *s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++s >= e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!t->son && !(t->son = trienode(env, *s)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = t->son;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin len++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!t->sib && !(t->sib = trienode(env, *s)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = t->sib;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (g->re.trie.min > len)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g->re.trie.min = len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (g->re.trie.max < len)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g->re.trie.max = len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->end = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * trie() tries to combine nontrivial e and f into a REX_TRIE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * unless 0 is returned, e and f are deleted as far as possible
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * also called by regcomb
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Rex_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintrie(Cenv_t* env, Rex_t* e, Rex_t* f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* g;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->next || f->next || !isstring(e) || e->flags != f->flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isstring(f))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(g = node(env, REX_TRIE, 0, 0, (UCHAR_MAX + 1) * sizeof(Trie_node_t*))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g->re.trie.min = INT_MAX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (insert(env, f, g))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nospace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (f->type != REX_TRIE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (insert(env, e, g))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nospace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return g;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nospace:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (g != f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, g);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Rex_t* alt(Cenv_t*, int, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchr(register Cenv_t* env, int* escaped)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *escaped = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(c = *env->cursor))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->flags & REG_SHELL_ESCAPED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(c = *(env->cursor + 1)) || c == env->terminator)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->flags & REG_LENIENT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c ? c : '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EESCAPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = env->cursor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = chresc((char*)env->cursor - 1, (char**)&env->cursor);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *escaped = env->cursor - p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open the perly gates
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Rex_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chingrp(Cenv_t* env, int parno)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int esc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int typ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int beg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin beg = env->pattern == env->cursor - env->token.len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(c = env->token.lex) && (c = *env->cursor))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->parnest++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin typ = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '-':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '+':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'a':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'g':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'i':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'l':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'm':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'p':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'r':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'x':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'A':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'B':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'E':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'F':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'G':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'I':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'K':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 'L':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 'M': /* glob(3) */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 'N': /* glob(3) */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 'O': /* glob(3) */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case 'P':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 'R': /* pcre */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'S':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'U': /* pcre */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'X': /* pcre */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_GROUP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.push = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case ')':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!(env->flags & REG_LITERAL))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin env->error = REG_BADRPT;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_CLOSE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (token(env) == T_CLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '-':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '+':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'a':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= (REG_LEFT|REG_RIGHT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags &= ~(REG_LEFT|REG_RIGHT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'g':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags &= ~REG_MINIMAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_MINIMAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'i':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_ICASE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags &= ~REG_ICASE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'l':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_LEFT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags &= ~REG_LEFT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'm':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_NEWLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags &= ~REG_NEWLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->explicit = (env->flags & (REG_NEWLINE|REG_SPAN)) == REG_NEWLINE ? env->mappednewline : -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'p':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags &= ~REG_LENIENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_LENIENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'r':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_RIGHT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags &= ~REG_RIGHT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_SPAN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags &= ~REG_SPAN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->explicit = (env->flags & (REG_NEWLINE|REG_SPAN)) == REG_NEWLINE ? env->mappednewline : -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'x':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_COMMENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags &= ~REG_COMMENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'A':
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT|REG_CLASS_ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_AUGMENTED|REG_EXTENDED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin typ = ARE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'B':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'G':
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT|REG_CLASS_ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin typ = BRE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'E':
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT|REG_CLASS_ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_EXTENDED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin typ = ERE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'F':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'L':
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT|REG_CLASS_ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_LITERAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin typ = ERE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'K':
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT|REG_CLASS_ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_AUGMENTED|REG_SHELL|REG_LEFT|REG_RIGHT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin typ = KRE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'M':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* used by caller to disable glob(3) GLOB_BRACE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'N':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* used by caller to disable glob(3) GLOB_NOCHECK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 'O':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* used by caller to disable glob(3) GLOB_STARSTAR */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner case 'P':
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT|REG_CLASS_ESCAPE);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner env->flags |= REG_EXTENDED|REG_CLASS_ESCAPE;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner typ = ERE;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'S':
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT|REG_CLASS_ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_SHELL|REG_LEFT|REG_RIGHT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin typ = SRE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'U': /* PCRE_UNGREEDY */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_MINIMAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags &= ~REG_MINIMAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'X': /* PCRE_EXTRA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADRPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = token(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_GROUP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '=':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_GROUP_AHEAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '!':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_GROUP_AHEAD_NOT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '<':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (token(env))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '=':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_GROUP_BEHIND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '!':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BANG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_GROUP_BEHIND_NOT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADRPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '>':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_GROUP_CUT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '%':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_PERCENT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = node(env, REX_NEST, 0, 0, (UCHAR_MAX + 1) * sizeof(unsigned short));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.nest.primary = isalnum(*env->cursor) ? -1 : *env->cursor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (i = chr(env, &esc))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case -1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin invalid:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor -= esc + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'D':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_NEST_delimiter;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin delimiter:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((i = chr(env, &esc)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->re.nest.type[i] & ~x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.nest.type[i] = x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'E':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_NEST_escape;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto delimiter;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'L':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_NEST_literal;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto quote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'O':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (i = chr(env, &esc))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'T':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.nest.type[UCHAR_MAX+1] |= REX_NEST_terminator;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'Q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_NEST_quote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin quote:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((i = chr(env, &esc)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->re.nest.type[i] & ~x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.nest.type[i] = x|REX_NEST_open|REX_NEST_close|(i<<REX_NEST_SHIFT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'S':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_NEST_separator;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto delimiter;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'T':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = REX_NEST_terminator;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto delimiter;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '|':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '&':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!esc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nesting;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '(':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!esc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nesting;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ')':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!esc && !--n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nesting;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nesting:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isalnum(i) || (e->re.nest.type[i] & (REX_NEST_close|REX_NEST_escape|REX_NEST_literal|REX_NEST_quote|REX_NEST_delimiter|REX_NEST_separator|REX_NEST_terminator)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.nest.type[i] = REX_NEST_open;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((x = chr(env, &esc)) < 0 || (e->re.nest.type[x] & (REX_NEST_close|REX_NEST_escape|REX_NEST_delimiter|REX_NEST_separator|REX_NEST_terminator)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!esc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x == ')' && !--n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto invalid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (x == '(')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.nest.type[x] |= REX_NEST_close;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.nest.type[i] |= x << REX_NEST_SHIFT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->parnest--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == T_PERCENT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = 0; n < 2; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin parno = ++env->parno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = node(env, REX_GROUP, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (parno < elementsof(env->paren))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->paren[parno] = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.back = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.number = parno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.expr.rex = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '(':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isdigit(*env->cursor))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c > (INT_MAX / 10))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADRPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = c * 10 + (*env->cursor++ - '0');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (isdigit(*env->cursor));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*env->cursor++ != ')')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADRPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c && env->type >= SRE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = c * 2 - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!c || c > env->parno || !env->paren[c])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(env->flags & REG_LENIENT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ESUBREG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type < SRE && *env->cursor++ != '?')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADRPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = grp(env, parno + 1)) && env->error)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = node(env, REX_GROUP_COND, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.group.size = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.group.expr.binary.left = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e->re.group.expr.binary.right = alt(env, parno, 1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (token(env) != T_CLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->parnest--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return rep(env, e, parno, parno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '{':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = env->cursor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c = *env->cursor)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '\\' && *(env->cursor + 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '{')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == '}' && !--n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == env->delimiter || c == env->terminator)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != '}')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EBRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*++env->cursor != ')')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->parnest--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->disc->re_version < REG_VERSION_EXEC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADRPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!env->disc->re_execf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = node(env, REX_EXEC, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.exec.text = (const char*)p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.exec.size = env->cursor - p - 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!env->disc->re_compf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.exec.data = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.exec.data = (*env->disc->re_compf)(env->regex, e->re.exec.text, e->re.exec.size, env->disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '0': case '1': case '2': case '3': case '4':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '5': case '6': case '7': case '8': case '9':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c -= '0';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (isdigit(*env->cursor))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c > (INT_MAX / 10))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ESUBREG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = c * 10 + *env->cursor++ - '0';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*env->cursor == ')')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->cursor++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->parnest--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.len = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c > env->parno || !env->paren[c])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ESUBREG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->paren[c]->re.group.back = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return rep(env, node(env, REX_BACK, c, 0, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADRPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x && !(e = alt(env, parno, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = token(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->parnest--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (c != T_CLOSE && (!(env->flags & REG_LITERAL) || c != ')'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (typ >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (beg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->pattern = env->cursor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->type = typ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = node(env, x, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.expr.rex = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x == REX_GROUP_BEHIND || x == REX_GROUP_BEHIND_NOT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stats(env, e))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!env->error)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ECOUNT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.size = env->stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&env->stats, 0, sizeof(env->stats));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP_CUT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = rep(env, f, parno, env->parno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Rex_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinseq(Cenv_t* env)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Token_t tok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int parno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regflags_t flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* u;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char buf[256];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = token(env)) < T_META && s < &buf[sizeof(buf) - env->token.len])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = env->cursor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = (env->flags & REG_ICASE) ? toupper(c) : c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (c == C_ESC || (env->flags & REG_ICASE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = (c == C_ESC) ? env->token.lex : mbchar(p);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (env->flags & REG_ICASE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = towupper(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((&buf[sizeof(buf)] - s) < MB_CUR_MAX)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((n = mbconv((char*)s, c)) < 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *s++ = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (n)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s += n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = env->token.len - env->token.esc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (t = p, u = s + n; s < u; *s++ = *t++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == T_BAD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s > buf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_STAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_PLUS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_LEFT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_QUES:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BANG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((s -= n) == buf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = s - buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = node(env, REX_STRING, 0, 0, i)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((char*)(e->re.string.base = (unsigned char*)e->re.data), (char*)buf, i);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.string.size = i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = node(env, REX_ONECHAR, 1, 1, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.onechar = (env->flags & REG_ICASE) ? toupper(x) : x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!(f = node(env, REX_STRING, 0, 0, n)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy((char*)(f->re.string.base = (unsigned char*)f->re.data), (char*)p, n);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f->re.string.size = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = rep(env, f, 0, 0)) || !(f = cat(env, f, seq(env))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = cat(env, e, f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = s - buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = node(env, REX_STRING, 0, 0, c)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((char*)(e->re.string.base = (unsigned char*)e->re.data), (char*)buf, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.string.size = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return cat(env, e, seq(env));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c > T_BACK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c -= T_BACK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c > env->parno || !env->paren[c])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ESUBREG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->paren[c]->re.group.back = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, node(env, REX_BACK, c, 0, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_AND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_CLOSE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_END:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return node(env, REX_NULL, 0, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_DOLL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, node(env, REX_END, 0, 0, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_CFLX:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((e = node(env, REX_BEG, 0, 0, 0)) && (env->flags & REG_EXTENDED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, e, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_OPEN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tok = env->token;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags = env->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = env->type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->token.att)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags |= REG_MINIMAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->parnest++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type == KRE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ++env->parno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin parno = ++env->parno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = alt(env, parno + 1, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->type == REX_NULL && env->type == ERE && !(env->flags & REG_NULL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = (*env->cursor == 0 || *env->cursor == env->delimiter || *env->cursor == env->terminator) ? REG_EPAREN : REG_ENULL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (token(env) != T_CLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_EPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->parnest--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = node(env, REX_GROUP, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (parno < elementsof(env->paren))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->paren[parno] = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.back = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.number = parno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.expr.rex = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tok.lex)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tok.push = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token = tok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = rep(env, f, parno, env->parno)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->type == KRE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = node(env, REX_GROUP, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (--parno < elementsof(env->paren))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->paren[parno] = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.back = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.number = parno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->re.group.expr.rex = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags = flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->type = type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_GROUP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = env->cursor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags = env->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = env->type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = grp(env, env->parno + 1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->error)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->literal == env->pattern && env->literal == p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->literal = env->cursor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->flags = flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->type = type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BRA:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e = bra(env))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, e, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_ALNUM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_ALNUM_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_DIGIT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_DIGIT_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_SPACE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_SPACE_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e = ccl(env, c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, e, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_LT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, node(env, REX_WBEG, 0, 0, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_GT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, node(env, REX_WEND, 0, 0, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_DOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, node(env, REX_DOT, 1, 1, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_DOTSTAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.lex = T_STAR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.push = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, node(env, REX_DOT, 1, 1, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_SLASHPLUS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.lex = T_PLUS;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->token.push = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e = node(env, REX_ONECHAR, 1, 1, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->re.onechar = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, e, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_WORD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, node(env, REX_WORD, 0, 0, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_WORD_NOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, node(env, REX_WORD_NOT, 0, 0, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_BEG_STR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, node(env, REX_BEG_STR, 0, 0, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_END_STR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, node(env, REX_END_STR, 0, 0, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_FIN_STR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = rep(env, node(env, REX_FIN_STR, 0, 0, 0), 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_BADRPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e && *env->cursor != 0 && *env->cursor != env->delimiter && *env->cursor != env->terminator)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = cat(env, e, seq(env));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Rex_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincon(Cenv_t* env)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* g;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = seq(env)) || !(env->flags & REG_AUGMENTED) || token(env) != T_AND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = con(env)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(g = node(env, REX_CONJ, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g->re.group.expr.binary.left = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g->re.group.expr.binary.right = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return g;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Rex_t*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinalt(Cenv_t* env, int number, int cond)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* g;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = con(env)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (token(env) != T_BAR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cond)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->type == REX_NULL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eat(env);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = alt(env, number, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((e->type == REX_NULL || f->type == REX_NULL) && !(env->flags & REG_NULL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cond && (g = trie(env, e, f)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return g;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(g = node(env, REX_ALT, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ESPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g->re.group.number = number;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g->re.group.last = env->parno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g->re.group.expr.binary.left = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin g->re.group.expr.binary.right = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return g;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bad:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!env->error)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ENULL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * add v to REX_BM tables
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbmstr(Cenv_t* env, register Rex_t* a, unsigned char* v, int n, Bm_mask_t b)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t z;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (m = 0; m < n; m++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(z = n - m - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin z = HIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = v[m];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.mask[m][c] |= b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (z == HIT || !a->re.bm.skip[c] || a->re.bm.skip[c] > z && a->re.bm.skip[c] < HIT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.skip[c] = z;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (a->flags & REG_ICASE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isupper(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = tolower(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (islower(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = toupper(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.mask[m][c] |= b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (z == HIT || !a->re.bm.skip[c] || a->re.bm.skip[c] > z && a->re.bm.skip[c] < HIT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.skip[c] = z;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set up BM table from trie
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbmtrie(Cenv_t* env, Rex_t* a, unsigned char* v, Trie_node_t* x, int n, int m, Bm_mask_t b)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v[m] = x->c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (m >= (n - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bmstr(env, a, v, n, b);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(b <<= 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.complete = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (x->son)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.complete = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (x->son)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = bmtrie(env, a, v, x->son, n, m + 1, b);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (x = x->sib);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * rewrite the expression tree for some special cases
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 1. it is a null expression - illegal
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 2. max length fixed string found -- use BM algorithm
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 3. it begins with an unanchored string - use KMP algorithm
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 returned on success
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinspecial(Cenv_t* env, regex_t* p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* a;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* y;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin DEBUG_INIT();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e = p->env->rex)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((x = env->stats.x) && x->re.string.size < 3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((t = env->stats.y) && t->re.trie.min < 3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x && t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x->re.string.size >= t->re.trie.min)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (x || t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Bm_mask_t** mask;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Bm_mask_t* h;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t* q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin y = x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = m = x->re.string.size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = env->stats.l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin y = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = t->re.trie.min;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = t->re.trie.max;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin l = env->stats.k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(q = (size_t*)alloc(env->disc, 0, (n + 1) * sizeof(size_t))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(a = node(env, REX_BM, 0, 0, n * (sizeof(Bm_mask_t*) + (UCHAR_MAX + 1) * sizeof(Bm_mask_t)) + (UCHAR_MAX + n + 2) * sizeof(size_t))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin alloc(env->disc, q, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->flags = y->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->map = y->map;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.size = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.back = (y == e || y == e->re.group.expr.rex) ? (m - n) : -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.left = l - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.right = env->stats.m - l - n;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner a->re.bm.complete = (env->stats.e || y != e && (e->type != REX_GROUP || y != e->re.group.expr.rex) || e->next || ((a->re.bm.left + a->re.bm.right) >= 0)) ? 0 : n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin h = (Bm_mask_t*)&a->re.bm.mask[n];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.skip = (size_t*)(h + n * (UCHAR_MAX + 1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.fail = &a->re.bm.skip[UCHAR_MAX + 1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (m = 0; m <= UCHAR_MAX; m++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.skip[m] = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.skip[0] = a->re.bm.skip[env->mappednewline] = (y->next && y->next->type == REX_END) ? HIT : (n + a->re.bm.left);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 1; i <= n; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.fail[i] = 2 * n - i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mask = a->re.bm.mask;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (m = 0; m < n; m++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mask[m] = h;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin h += UCHAR_MAX + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bmstr(env, a, x->re.string.base, n, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = (unsigned char*)q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(v, 0, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i <= UCHAR_MAX; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t->re.trie.root[i])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = bmtrie(env, a, v, t->re.trie.root[i], n, 0, m);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mask--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(q, 0, n * sizeof(*q));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (k = (j = n) + 1; j > 0; j--, k--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin DEBUG_TEST(0x0010,(sfprintf(sfstderr, "BM#0: k=%d j=%d\n", k, j)),(0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (q[j] = k; k <= n; k = q[k])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (m = 0; m <= UCHAR_MAX; m++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mask[k][m] == mask[j][m])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin DEBUG_TEST(0x0010,sfprintf(sfstderr, "CUT1: mask[%d][%c]=mask[%d][%c]\n", k, m, j, m), (0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto cut;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin DEBUG_TEST(0x0010,sfprintf(sfstderr, "BM#2: fail[%d]=%d => %d\n", k, a->re.bm.fail[k], (a->re.bm.fail[k] > n - j) ? (n - j) : a->re.bm.fail[k]), (0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (a->re.bm.fail[k] > n - j)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.fail[k] = n - j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cut: ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 1; i <= n; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (a->re.bm.fail[i] > n + k - i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin DEBUG_TEST(0x0010,sfprintf(sfstderr, "BM#4: fail[%d]=%d => %d\n", i, a->re.bm.fail[i], n + k - i), (0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.bm.fail[i] = n + k - i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _AST_REGEX_DEBUG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (DEBUG_TEST(0x0020,(1),(0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "STAT: complete=%d n=%d k=%d l=%d r=%d y=%d:%d e=%d:%d\n", a->re.bm.complete, n, k, a->re.bm.left, a->re.bm.right, y->type, y->next ? y->next->type : 0, e->type, e->next ? e->next->type : 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (m = 0; m < n; m++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 1; i <= UCHAR_MAX; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (a->re.bm.mask[m][i])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "MASK: [%d]['%c'] = %032..2u\n", m, i, a->re.bm.mask[m][i]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = ' '; i <= UCHAR_MAX; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (a->re.bm.skip[i] >= HIT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "SKIP: ['%c'] = *\n", i);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (a->re.bm.skip[i] > 0 && a->re.bm.skip[i] < n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "SKIP: ['%c'] = %3d\n", i, a->re.bm.skip[i]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (j = 31; j >= 0; j--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (m = 0; m < n; m++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0040; i < 0177; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (a->re.bm.mask[m][i] & (1 << j))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " %c", i);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i >= 0177)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (j > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin j--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, " ?");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "FAIL: ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (m = 1; m <= n; m++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "%3d", a->re.bm.fail[m]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr, "\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin alloc(env->disc, q, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->next = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->rex = a;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (e->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_BEG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->flags & REG_NEWLINE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_GROUP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->stats.b)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = e->re.group.expr.rex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->type != REX_DOT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_DOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->lo == 0 && e->hi == RE_DUP_INF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_NULL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env->flags & REG_NULL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env->error = REG_ENULL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case REX_STRING:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((env->flags & (REG_LEFT|REG_LITERAL|REG_RIGHT)) || e->map)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = e->re.string.base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = e->re.string.size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(a = node(env, REX_KMP, 0, 0, n * (sizeof(int*) + 1))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->flags = e->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->map = e->map;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = a->re.string.fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((char*)(a->re.string.base = (unsigned char*)&f[n]), (char*)s, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = a->re.string.base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->re.string.size = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f[0] = m = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (k = 1; k < n; k++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (m >= 0 && s[m+1] != s[k])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = f[m];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s[m+1] == s[k])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f[k] = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a->next = e->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->rex = a;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env->disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->once = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinregcomp(regex_t* p, const char* pattern, regflags_t flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regdisc_t* disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* fold;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Cenv_t env;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return REG_BADPAT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & REG_DISCIPLINE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~REG_DISCIPLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disc = p->re_disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disc = &state.disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!disc->re_errorlevel)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disc->re_errorlevel = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!pattern)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(disc, REG_BADPAT, pattern);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!state.initialized)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state.initialized = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < elementsof(state.escape); i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state.magic[state.escape[i].key] = state.escape[i].val;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fold = (unsigned char*)LCINFO(AST_LC_CTYPE)->data))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fold = newof(0, unsigned char, UCHAR_MAX, 1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(disc, REG_ESPACE, pattern);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i <= UCHAR_MAX; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fold[i] = toupper(i);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin LCINFO(AST_LC_CTYPE)->data = (void*)fold;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin again:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p->env = (Env_t*)alloc(disc, 0, sizeof(Env_t))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(disc, REG_ESPACE, pattern);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(p->env, 0, sizeof(*p->env));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&env, 0, sizeof(env));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.regex = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.flags = flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.disc = p->env->disc = disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.flags & REG_AUGMENTED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.flags |= REG_EXTENDED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.mappeddot = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.mappednewline = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.mappedslash = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (disc->re_version >= REG_VERSION_MAP && disc->re_map)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.map = disc->re_map;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.MAP = p->env->fold;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i <= UCHAR_MAX; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.MAP[i] = fold[env.map[i]];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.map[i] == '.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.mappeddot = i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.map[i] == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.mappednewline = i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.map[i] == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.mappedslash = i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.MAP = fold;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.type = (env.flags & REG_AUGMENTED) ? ARE : (env.flags & REG_EXTENDED) ? ERE : BRE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.explicit = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.flags & REG_SHELL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.flags & REG_SHELL_PATH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.explicit = env.mappedslash;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.flags |= REG_LENIENT|REG_NULL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.type = env.type == BRE ? SRE : KRE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env.flags & (REG_NEWLINE|REG_SPAN)) == REG_NEWLINE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.explicit = env.mappednewline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->leading = (env.flags & REG_SHELL_DOT) ? env.mappeddot : -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.posixkludge = !(env.flags & (REG_EXTENDED|REG_SHELL));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz env.regexp = !!(env.flags & REG_REGEXP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.token.lex = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.token.push = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.flags & REG_DELIMITED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (env.delimiter = *pattern++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\r':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.error = REG_EDELIM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.terminator = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.literal = env.pattern = env.cursor = (unsigned char*)pattern;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p->env->rex = alt(&env, 1, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.parnest)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.error = REG_EPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->stats.re_flags = env.flags & (REG_EXTENDED|REG_AUGMENTED|REG_SHELL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.flags & REG_LEFT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p->env->rex->type != REX_BEG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p->env->rex->type == REX_ALT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.flags &= ~REG_FIRST;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = node(&env, REX_BEG, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfree(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(disc, REG_ESPACE, pattern);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->next = p->env->rex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->rex = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->once = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->stats.re_flags |= REG_LEFT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (e = p->env->rex; e->next; e = e->next);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->done.type = REX_DONE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->done.flags = e->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.flags & REG_RIGHT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->type != REX_END)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p->env->rex->type == REX_ALT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.flags &= ~REG_FIRST;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = node(&env, REX_END, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfree(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(disc, REG_ESPACE, pattern);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->flags = e->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->map = e->map;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->next = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->stats.re_flags |= REG_RIGHT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stats(&env, p->env->rex))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!env.error)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.error = REG_ECOUNT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.stats.b)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->hard = p->env->separate = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(env.flags & REG_FIRST) && (env.stats.a || env.stats.c > 1 && env.stats.c != env.stats.s || env.stats.t && (env.stats.t > 1 || env.stats.a || env.stats.c)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->hard = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p->env->hard || env.stats.c || env.stats.i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->stats.re_min = p->env->stats.re_max = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p->env->stats.re_min = env.stats.m))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->stats.re_min = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p->env->stats.re_max = env.stats.n))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->stats.re_max = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (special(&env, p))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin serialize(&env, p->env->rex, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->re_nsub = env.stats.p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.type == KRE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->re_nsub /= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.flags & REG_DELIMITED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->re_npat = env.cursor - env.pattern + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*env.cursor == env.delimiter)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->re_npat++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (env.flags & REG_MUSTDELIM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.error = REG_EDELIM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.flags &= ~REG_DELIMITED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->explicit = env.explicit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->flags = env.flags & REG_COMP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->min = env.stats.m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->nsub = env.stats.p + env.stats.u;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->refs = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bad:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfree(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!env.error)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.error = REG_ESPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (env.type >= SRE && env.error != REG_ESPACE && !(flags & REG_LITERAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= REG_LITERAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pattern = (const char*)env.literal;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto again;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(disc, env.error, pattern);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * regcomp() on sized pattern
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the lazy way around adding and checking env.end
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinregncomp(regex_t* p, const char* pattern, size_t size, regflags_t flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = malloc(size + 1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal((flags & REG_DISCIPLINE) ? p->re_disc : &state.disc, REG_ESPACE, pattern);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(s, pattern, size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s[size] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = regcomp(p, s, flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * combine two compiled regular expressions if possible,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * replacing first with the combination and freeing second.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return 0 on success.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the only combinations handled are building a Trie
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * from String|Kmp|Trie and String|Kmp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinregcomb(regex_t* p, regex_t* q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* e = p->env->rex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* f = q->env->rex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Rex_t* g;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner Rex_t* h;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Cenv_t env;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!e || !f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(p->env->disc, REG_BADPAT, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p->env->separate || q->env->separate)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return REG_ESUBREG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&env, 0, sizeof(env));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.disc = p->env->disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->type == REX_BM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->rex = e->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env.disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = p->env->rex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f->type == REX_BM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q->env->rex = f->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env.disc, f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = q->env->rex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e->type == REX_BEG && f->type == REX_BEG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->flags |= REG_LEFT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->rex = e->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env.disc, e);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = p->env->rex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q->env->rex = f->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin drop(env.disc, f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = q->env->rex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner for (g = e; g->next; g = g->next);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner for (h = f; h->next; h = h->next);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (g->next && g->next->type == REX_END && h->next && h->next->type == REX_END)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->flags |= REG_RIGHT;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner drop(env.disc, g->next);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner g->next = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner drop(env.disc, h->next);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner h->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(g = trie(&env, f, e)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(p->env->disc, REG_BADPAT, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->rex = g;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!q->env->once)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->once = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q->env->rex = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p->env->flags & REG_LEFT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = node(&env, REX_BEG, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfree(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(p->env->disc, REG_ESPACE, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e->next = p->env->rex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->rex = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->once = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p->env->flags & REG_RIGHT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (f = p->env->rex; f->next; f = f->next);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f->type != REX_END)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(e = node(&env, REX_END, 0, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfree(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(p->env->disc, REG_ESPACE, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->next = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.explicit = p->env->explicit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.flags = p->env->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin env.disc = p->env->disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stats(&env, p->env->rex))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfree(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(p->env->disc, env.error ? env.error : REG_ECOUNT, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (special(&env, p))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfree(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fatal(p->env->disc, env.error ? env.error : REG_ESPACE, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->min = g->re.trie.min;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy a reference of p into q
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * p and q may then have separate regsubcomp() instantiations
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinregdup(regex_t* p, regex_t* q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p || !q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return REG_BADPAT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *q = *p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->env->refs++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q->re_sub = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}