1N/A/***********************************************************************
1N/A* *
1N/A* This software is part of the ast package *
1N/A* Copyright (c) 1985-2011 AT&T Intellectual Property *
1N/A* and is licensed under the *
1N/A* Common Public License, Version 1.0 *
1N/A* by AT&T Intellectual Property *
1N/A* *
1N/A* A copy of the License is available at *
1N/A* http://www.opensource.org/licenses/cpl1.0.txt *
1N/A* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1N/A* *
1N/A* Information and Software Systems Research *
1N/A* AT&T Research *
1N/A* Florham Park NJ *
1N/A* *
1N/A* Glenn Fowler <gsf@research.att.com> *
1N/A* David Korn <dgk@research.att.com> *
1N/A* Phong Vo <kpv@research.att.com> *
1N/A* *
1N/A***********************************************************************/
1N/A#pragma prototyped
1N/A/*
1N/A * <regexp.h> library support
1N/A */
1N/A
1N/A#define _REGEXP_DECLARE
1N/A
1N/A#include <ast.h>
1N/A#include <regexp.h>
1N/A#include <regex.h>
1N/A#include <align.h>
1N/A
1N/Atypedef struct
1N/A{
1N/A regex_t re;
1N/A char* buf;
1N/A char* cur;
1N/A unsigned int size;
1N/A} Env_t;
1N/A
1N/Astatic void*
1N/Ablock(void* handle, void* data, size_t size)
1N/A{
1N/A register Env_t* env = (Env_t*)handle;
1N/A
1N/A if (data || (size = roundof(size, ALIGN_BOUND2)) > (env->buf + env->size - env->cur))
1N/A return 0;
1N/A data = (void*)env->cur;
1N/A env->cur += size;
1N/A return data;
1N/A}
1N/A
1N/Aint
1N/A_re_comp(regexp_t* re, const char* pattern, char* handle, unsigned int size)
1N/A{
1N/A register Env_t* env = (Env_t*)handle;
1N/A register int n;
1N/A
1N/A if (size <= sizeof(Env_t))
1N/A return 50;
1N/A env->buf = env->cur = (char*)env + sizeof(Env_t);
1N/A env->size = size - sizeof(Env_t);
1N/A regalloc(env, block, REG_NOFREE);
1N/A n = regcomp(&env->re, pattern, REG_LENIENT|REG_NULL);
1N/A switch (n)
1N/A {
1N/A case 0:
1N/A break;
1N/A case REG_ERANGE:
1N/A n = 11;
1N/A break;
1N/A case REG_BADBR:
1N/A n = 16;
1N/A break;
1N/A case REG_ESUBREG:
1N/A n = 25;
1N/A break;
1N/A case REG_EPAREN:
1N/A n = 42;
1N/A break;
1N/A case REG_EBRACK:
1N/A n = 49;
1N/A break;
1N/A default:
1N/A n = 50;
1N/A break;
1N/A }
1N/A re->re_nbra = env->re.re_nsub;
1N/A return n;
1N/A}
1N/A
1N/Aint
1N/A_re_exec(regexp_t* re, const char* subject, const char* handle, int anchor)
1N/A{
1N/A register Env_t* env = (Env_t*)handle;
1N/A register int n;
1N/A regmatch_t match[elementsof(re->re_braslist)+1];
1N/A
1N/A if (regexec(&env->re, subject, elementsof(match), match, 0) || anchor && match[0].rm_so)
1N/A return 0;
1N/A re->re_loc1 = (char*)subject + match[0].rm_so;
1N/A re->re_loc2 = (char*)subject + match[0].rm_eo;
1N/A for (n = 1; n <= env->re.re_nsub; n++)
1N/A {
1N/A re->re_braslist[n-1] = (char*)subject + match[n].rm_so;
1N/A re->re_braelist[n-1] = (char*)subject + match[n].rm_eo;
1N/A }
1N/A return 1;
1N/A}
1N/A
1N/Achar*
1N/A_re_putc(int c)
1N/A{
1N/A static Sfio_t* sp;
1N/A
1N/A if (!sp && !(sp = sfstropen()))
1N/A return 0;
1N/A if (!c)
1N/A return sfstruse(sp);
1N/A sfputc(sp, c);
1N/A return 0;
1N/A}