sedexec.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 911 行 · 第 1/3 页
C
911 行
curlp = lp;
while( memeql( bbeg, lp, ct ) )
lp += ct;
while( lp >= curlp ) {
if( advance( lp, ep ) )
return( TRUE );
lp -= ct;
}
return( FALSE );
case CDOT | STAR: /* match .* */
curlp = lp; /* save closure start loc */
while( ( *lp++ ) != 0 ) ; /* match anything */
goto star; /* now look for followers */
case CCHR | STAR: /* match <literal char>* */
curlp = lp; /* save closure start loc */
while( (int)( *lp++ == *ep ) != 0 ) ; /* match many of that char */
ep++; /* to start of next element */
goto star; /* match it and followers */
case CCL | STAR: /* match [...]* */
curlp = lp; /* save closure start loc */
while( c = *lp++ & 0x7F, ep[c >> 3] & bits[c & 07] ) ;
ep += 16; /* skip past the set */
goto star; /* match followers */
star: /* the repeat part of a * or + match */
if( --lp == curlp ) /* 0 matches */
break;
switch( *ep ) {
case CCHR:
c = ep[1];
break;
case CBACK:
c = *brastart[ep[1]];
break;
default:
do {
if( lp == locs )
break;
if( advance( lp, ep ) )
return( TRUE );
} while( lp-- > curlp );
return( FALSE );
}
do {
if( *lp == c )
if( advance( lp, ep ) )
return( TRUE );
} while( lp-- > curlp );
return( FALSE );
default:
fprintf( stderr, "sed: RE error, %o\n", *--ep );
exit( 2 );
case CBRA | STAR: /* start of starred tagged pattern */
{
int const tagindex = *ep;
int matched = FALSE;
curlp = lp; /* save closure start loc */
ct = ep[1];
bracend[tagindex] = bbeg = tep = lp;
ep++;
while( advance( brastart[tagindex] = bracend[tagindex], ep+1 ) && bracend[tagindex] > brastart[tagindex] )
if( advance( bracend[tagindex], ep + ct ) ) { /* Try to match RE after \(...\) */
matched = TRUE; /* Remember greediest match */
bbeg = brastart[tagindex];
tep = bracend[tagindex];
}
if( matched ) { /* Did we match RE after \(...\) */
brastart[tagindex] = bbeg; /* Set details of match */
bracend[tagindex] = tep;
return( TRUE );
}
return( advance( bracend[tagindex], ep + ct ) ); /* Zero matches */
}
case CBRA | MTYPE: /* \(...\)\{m,n\} WFB */
{
int const tagindex = *ep;
int matched = FALSE;
curlp = lp; /* save closure start loc */
ct = ep[1];
i1 = ep[ct-1] & 0xFF, i2 = ep[ct] & 0xFF;
bracend[tagindex] = bbeg = tep = lp;
while( i1 && advance( lp, ep+2 ) && bracend[tagindex] > lp )
brastart[tagindex] = lp, lp = bracend[tagindex], i1--;
if( i1 )
return( FALSE );
if( !i2 )
return( advance( bracend[tagindex], ep + ct + 1 ) ); /* Zero matches */
if( i2 == 0xFF )
i2 = MAXBUF;
while( advance( brastart[tagindex] = bracend[tagindex], ep+2 ) && bracend[tagindex] > brastart[tagindex] && i2 )
if( i2--, advance( bracend[tagindex], ep + ct + 1 ) ) { /* Try to match RE after \(...\) */
matched = TRUE; /* Remember greediest match */
bbeg = brastart[tagindex];
tep = bracend[tagindex];
}
if( matched ) { /* Did we match RE after \(...\) */
brastart[tagindex] = bbeg; /* Set details of match */
bracend[tagindex] = tep;
return( TRUE );
}
if( i1 )
return( FALSE );
return( advance( bracend[tagindex], ep + ct + 1 ) ); /* Zero matches */
}
case CCHR | MTYPE: /* Match <literal char>\{...\} */
c = *ep++; /* Get byte and skip to next element */
i1 = *ep++ & 0xFF, i2 = *ep++ & 0xFF;
while( c == *lp && i1 )
lp++, i1--;
if( i1 )
return( FALSE );
if( !i2 )
break;
if( i2 == 0xFF )
i2 = MAXBUF;
curlp = lp;
while( c == *lp++ && i2 )
i2--;
goto star;
case CKET | STAR: /* match \(..\)* */
case CKET | MTYPE: /* match \(..\)\{...\} */
bracend[*ep] = lp; /* mark it */
return( TRUE );
case CDOT | MTYPE: /* match .\{...\} */
i1 = *ep++ & 0xFF, i2 = *ep++ & 0xFF;
while( *lp && i1 )
lp++, i1--;
if( i1 )
return( FALSE );
if( !i2 )
break;
if( i2 == 0xFF )
i2 = MAXBUF;
curlp = lp;
while( *lp++ && i2 )
i2--;
goto star;
case CCL | MTYPE: /* match [...]\{...\} */
tep = ep;
ep += 16;
i1 = *ep++ & 0xFF, i2 = *ep++ & 0xFF;
/* WFB 1 CCL|MTYPE handler must be like CCHR|MTYPE or off by 1 */
while( ct = *lp, tep[(unsigned)ct >> 3] & bits[ct & 7] && i1 )
lp++, i1--;
if( i1 )
return( FALSE );
if( !i2 )
break;
if( i2 == 0xFF )
i2 = MAXBUF;
curlp = lp;
while( ct = *lp++ & 0xff, tep[(unsigned)ct >> 3] & bits[ct & 7] && i2 )
i2--;
goto star;
case CBACK | MTYPE: /* e.g. \(.\)\1\{5\} */
bbeg = brastart[*ep];
ct = bracend[*ep++] - bbeg;
i1 = *ep++ & 0xFF, i2 = *ep++ & 0xFF;
while( memeql( bbeg, lp, ct ) && i1 )
lp += ct, i1--;
if( i1 )
return( FALSE );
if( !i2 )
break;
if( i2 == 0xFF )
i2 = MAXBUF;
curlp = lp;
while( memeql( bbeg, lp, ct ) && i2 )
lp+= ct, i2--;
while( lp >= curlp ) {
if( advance( lp, ep ) )
return( TRUE );
lp -= ct;
}
return( FALSE );
} /* switch( *ep++ ) */
}
/* perform s command */
static int substitute( sedcmd const *ipc ) /* ptr to s command struct */
{
int fcnt = ipc->flags.nthone;
if( !match( ipc->u.lhs, 0, 0 ) ) /* if no match */
return( FALSE ); /* command fails */
if( fcnt ) {
while( --fcnt > 0 && *loc2 && match( ipc->u.lhs, 0, 1 ) )
;
if( fcnt != 0 )
return( FALSE ); /* command fails */
}
dosub( ipc->rhs ); /* perform it once */
if( ipc->flags.global ) /* if global flag enabled */
while( *loc2 && match( ipc->u.lhs, 1, 0 ) ) /* cycle through possibles */
dosub( ipc->rhs ); /* so substitute */
return( TRUE ); /* we succeeded */
}
/* generate substituted right-hand side (of s command) */
static void dosub( char const *rhsbuf ) /* where to put the result */
/* uses linebuf, genbuf, spend */
{
register char *lp;
register char *sp;
register char const *rp;
int c;
/* linebuf upto location 1 -> genbuf */
lp = linebuf;
sp = genbuf;
while( lp < loc1 ) {
if( sp >= genbuf + sizeof genbuf ) { /* Not exercised by sedtest.mak */
fprintf( stderr, NOROOM, sizeof genbuf, lnum );
break;
}
*sp++ = *lp++;
}
for( rp = rhsbuf; ( c = *rp++ ) != 0; ) {
if( c == '&' ) {
sp = place( sp, loc1, loc2 );
} else if( c & 0200 && ( c &= 0177 ) >= '1' && c < MAXTAGS + '1' ) {
sp = place( sp, brastart[c - '0'], bracend[c - '0'] );
} else {
if( sp >= genbuf + sizeof genbuf ) { /* Not exercised by sedtest.mak */
fprintf( stderr, NOROOM, sizeof genbuf, lnum );
break;
}
*sp++ = c & 0177;
}
}
lp = loc2;
loc2 = sp - ( genbuf - linebuf ); /* Last character to remove */
do{
if( sp >= genbuf + sizeof genbuf ) { /* Not exercised by sedtest.mak */
fprintf( stderr, NOROOM, sizeof genbuf, lnum );
break;
}
} while( ( *sp++ = *lp++ ) != 0 );
lp = linebuf;
sp = genbuf;
while( ( *lp++ = *sp++ ) != 0 ) ;
spend = lp - 1;
}
/* place chars at *al1...*(al1 - 1) at asp... in genbuf[] */
static char *place(
register char *asp,
register char const *al1,
register char const *al2 )
{
while( al1 < al2 ) {
if( asp >= genbuf + sizeof genbuf ) { /* Not exercised by sedtest.mak */
fprintf( stderr, NOROOM, sizeof genbuf, lnum );
break;
}
*asp++ = *al1++;
}
return( asp );
}
/* write a hex dump expansion of *p1... to fp */
static void listto(
register char const *p1, /* the source */
FILE *fp ) /* output stream to write to */
{
int const linesize = 64;
int written = 0;
p1--;
while( *++p1 ) {
if( ++written >= linesize )
fprintf( fp, "%c\n", '\\' ), written = 1;
if( *p1 == '\\' )
putc( *p1, fp ), putc( *p1, fp ), written++; /* Double literal backslash */
else if( *p1 == '\n' || isprint( *p1 ) )
putc( *p1, fp ); /* pass it through */
else {
written++;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?