NetBSD/gnu/usr.bin/awk/rexp/rexp1.c
1993-03-21 09:45:37 +00:00

220 lines
4.3 KiB
C

/********************************************
rexp1.c
copyright 1991, Michael D. Brennan
This is a source file for mawk, an implementation of
the AWK programming language.
Mawk is distributed without warranty under the terms of
the GNU General Public License, version 2, 1991.
********************************************/
/*$Log: rexp1.c,v $
/*Revision 1.1.1.1 1993/03/21 09:45:37 cgd
/*initial import of 386bsd-0.1 sources
/*
* Revision 3.4 92/02/20 16:08:12 brennan
* change new_TWO() to work around sun acc bug
*
* Revision 3.3 91/10/29 10:54:01 brennan
* SIZE_T
*
* Revision 3.2 91/08/13 09:10:11 brennan
* VERSION .9994
*
* Revision 3.1 91/06/07 10:33:22 brennan
* VERSION 0.995
*
*/
/* re machine operations */
#include "rexp.h"
static void PROTO( new_TWO , (int, MACHINE *) ) ;
/* initialize a two state machine */
static void new_TWO(type, mp)
int type ;
MACHINE *mp ; /* init mp-> */
{
mp->start = (STATE *) RE_malloc(2*STATESZ) ;
mp->stop = mp->start + 1 ;
mp->start->type = type ;
mp->stop->type = M_ACCEPT ;
}
/* build a machine that recognizes any */
MACHINE RE_any()
{
MACHINE x ;
new_TWO(M_ANY, &x) ;
return x ;
}
/* build a machine that recognizes the start of string */
MACHINE RE_start()
{
MACHINE x ;
new_TWO(M_START, &x) ;
return x ;
}
MACHINE RE_end()
{
MACHINE x ;
new_TWO(M_END, &x) ;
return x ;
}
/* build a machine that recognizes a class */
MACHINE RE_class( bvp )
BV *bvp ;
{
MACHINE x ;
new_TWO(M_CLASS, &x) ;
x.start->data.bvp = bvp ;
return x ;
}
MACHINE RE_u()
{
MACHINE x ;
new_TWO(M_U, &x) ;
return x ;
}
MACHINE RE_str( str, len)
char *str ;
unsigned len ;
{
MACHINE x ;
new_TWO(M_STR, &x) ;
x.start->len = len ;
x.start->data.str = str ;
return x ;
}
/* replace m and n by a machine that recognizes mn */
void RE_cat( mp, np)
MACHINE *mp, *np ;
{ unsigned sz1, sz2, sz ;
sz1 = mp->stop - mp->start ;
sz2 = np->stop - np->start + 1 ;
sz = sz1 + sz2 ;
mp->start = (STATE *) RE_realloc( mp->start, sz * STATESZ ) ;
mp->stop = mp->start + (sz - 1) ;
(void) memcpy( mp->start + sz1, np->start, SIZE_T(sz2 * STATESZ) ) ;
free( np->start ) ;
}
/* replace m by a machine that recognizes m|n */
void RE_or( mp, np)
MACHINE *mp, *np ;
{ register STATE *p ;
unsigned szm, szn ;
szm = mp->stop - mp->start + 1 ;
szn = np->stop - np->start + 1 ;
p = (STATE *) RE_malloc( (szm+szn+1) * STATESZ ) ;
(void) memcpy( p+1, mp->start, SIZE_T(szm * STATESZ) ) ;
free( mp->start) ;
mp->start = p ;
(mp->stop = p + szm + szn) -> type = M_ACCEPT ;
p->type = M_2JA ;
p->data.jump = szm+1 ;
(void) memcpy( p + szm + 1 , np->start, SIZE_T(szn * STATESZ)) ;
free( np->start ) ;
(p += szm)->type = M_1J ;
p->data.jump = szn ;
}
/* UNARY OPERATIONS */
/* replace m by m* */
void RE_close( mp )
MACHINE *mp ;
{ register STATE *p ;
unsigned sz ;
sz = mp->stop - mp->start + 1 ;
p = (STATE *) RE_malloc( (sz+2) * STATESZ ) ;
(void) memcpy( p+1, mp->start, SIZE_T(sz * STATESZ)) ;
free( mp->start ) ;
mp->start = p ;
mp->stop = p + (sz+1) ;
p->type = M_2JA ;
p->data.jump = sz + 1 ;
(p += sz) -> type = M_2JB ;
p->data.jump = -(sz-1) ;
(p+1)->type = M_ACCEPT ;
}
/* replace m by m+ (positive closure) */
void RE_poscl( mp )
MACHINE *mp ;
{ register STATE *p ;
unsigned sz ;
sz = mp->stop - mp->start + 1 ;
mp->start = p = (STATE *) RE_realloc(mp->start , (sz+1) * STATESZ ) ;
mp->stop = p + sz ;
p += --sz ;
p->type = M_2JB ;
p->data.jump = -sz ;
(p+1)->type = M_ACCEPT ;
}
/* replace m by m? (zero or one) */
void RE_01( mp )
MACHINE *mp ;
{ unsigned sz ;
register STATE *p ;
sz = mp->stop - mp->start + 1 ;
p = (STATE *) RE_malloc( (sz+1) * STATESZ ) ;
(void) memcpy( p+1, mp->start, SIZE_T(sz * STATESZ)) ;
free( mp->start ) ;
mp->start = p ;
mp->stop = p + sz ;
p->type = M_2JB ;
p->data.jump = sz ;
}
/*===================================
MEMORY ALLOCATION
*==============================*/
VOID *RE_malloc( sz )
unsigned sz ;
{ register VOID *p ;
if ( ! ( p = malloc(SIZE_T(sz)) ) ) RE_error_trap(MEMORY_FAILURE) ;
return p ;
}
VOID *RE_realloc( p, sz)
register VOID *p ; unsigned sz ;
{ if ( ! ( p = realloc( p, SIZE_T(sz)) ) ) RE_error_trap(MEMORY_FAILURE) ;
return p ;
}