/******************************************** 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 ; }