sedexec.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 911 行 · 第 1/3 页
C
911 行
putc( '\\', fp ); /* emit a backslash */
switch( *p1 ) {
case '\a':
putc( 'a', fp );
break;
case '\b':
putc( 'b', fp );
break;
case '\f':
putc( 'f', fp );
break;
case '\n': /* Never activated */
putc( 'n', fp );
break;
case '\r':
putc( 'r', fp );
break;
case '\t':
putc( 't', fp );
break;
case '\v':
putc( 'v', fp );
break;
default:
written++;
fprintf( fp, "%02x", *p1 & 0xFF );
}
}
}
putc( '$', fp );
putc( '\n', fp );
}
/* execute compiled command pointed at by ipc */
static void command( sedcmd *ipc )
{
static int didsub; /* true if last s succeeded */
static char holdsp[MAXHOLD]; /* the hold space */
static char *hspend = holdsp; /* hold space end pointer */
register char *p1;
register char *p2;
char *execp;
switch( ipc->command ) {
case ACMD: /* append */
if( aptr >= appends + MAXAPPENDS ) /* Not exercised by sedtest.mak */
fprintf( stderr, "sed: too many appends after line %ld\n", lnum );
*aptr++ = ipc;
break;
case CCMD: /* change pattern space */
delete = TRUE;
if( !ipc->flags.inrange || lastline )
printf( "%s\n", ipc->u.lhs );
break;
case DCMD: /* delete pattern space */
delete++;
break;
case CDCMD: /* delete a line in pattern space */
p1 = p2 = linebuf;
while( *p1 && *p1 != '\n' ) p1++;
if( !*p1++ )
return;
while( ( *p2++ = *p1++ ) != 0 ) ;
spend = p2 - 1;
delete = jump = TRUE;
break;
case EQCMD: /* show current line number */
fprintf( stdout, "%ld\n", lnum );
break;
case GCMD: /* copy hold space to pattern space */
p1 = linebuf;
p2 = holdsp;
while( ( *p1++ = *p2++ ) != 0 ) ;
spend = p1 - 1;
break;
case CGCMD: /* append hold space to pattern space */
*spend++ = '\n';
p1 = spend;
p2 = holdsp;
while( ( *p1++ = *p2++ ) != 0 )
if( p1 >= linebuf + MAXBUF ) {
fprintf( stderr, NOROOM, MAXBUF, lnum );
break;
}
spend = p1 - 1;
break;
case HCMD: /* copy pattern space to hold space */
p1 = holdsp;
p2 = linebuf;
while( ( *p1++ = *p2++ ) != 0 ) ;
hspend = p1 - 1;
break;
case CHCMD: /* append pattern space to hold space */
*hspend++ = '\n';
p1 = hspend;
p2 = linebuf;
while( ( *p1++ = *p2++ ) != 0 )
if( p1 >= holdsp + MAXBUF ) {
fprintf( stderr, NOROOM, MAXBUF, lnum );
break;
}
hspend = p1 - 1;
break;
case ICMD: /* insert text */
printf( "%s\n", ipc->u.lhs );
break;
case BCMD: /* branch to label */
jump = TRUE;
break;
case LCMD: /* list text */
listto( linebuf, ( ipc->fout != NULL ) ? ipc->fout : stdout );
break;
case NCMD: /* read next line into pattern space */
if( !nflag )
puts( linebuf ); /* flush out the current line */
readout(); /* do any pending a, r commands */
if( ( execp = getline( linebuf ) ) == BAD ) {
pending = ipc;
delete = TRUE;
break;
}
spend = execp;
break;
case CNCMD: /* append next line to pattern space */
readout(); /* do any pending a, r commands */
*spend++ = '\n'; /* seperate lines with '\n' */
if( ( execp = getline( spend ) ) == BAD ) {
*--spend = '\0'; /* Remove '\n' added for new line */
pending = ipc;
delete = TRUE;
break;
}
spend = execp;
break;
case PCMD: /* print pattern space */
puts( linebuf );
break;
case CPCMD: /* print one line from pattern space */
for( p1 = linebuf; *p1 != '\n' && *p1 != '\0'; p1++ )
putc( *p1, stdout );
putc( '\n', stdout );
break;
case QCMD: /* quit the stream editor */
if( !nflag )
puts( linebuf ); /* flush out the current line */
readout(); /* do any pending a and r commands */
exit( 0 );
case RCMD: /* read a file into the stream */
if( aptr >= appends + MAXAPPENDS ) /* Not exercised by sedtest.mak */
fprintf( stderr, "sed: too many reads after line %ld\n", lnum );
*aptr++ = ipc;
break;
case SCMD: /* substitute RE */
if( ( didsub = substitute( ipc ) ) != 0 ) {
switch( ipc->flags.print ) {
case 1:
puts( linebuf );
break;
case 2:
for( p1 = linebuf; *p1 != '\n' && *p1 != '\0'; p1++ )
putc( *p1, stdout );
putc( '\n', stdout );
break;
}
if( ipc->fout )
fprintf( ipc->fout, "%s\n", linebuf );
}
break;
case TCMD: /* branch on last s successful */
case CTCMD: /* branch on last s failed */
if( didsub == (int)( ipc->command == CTCMD ) )
break; /* no branch if last s failed, else */
didsub = FALSE;
jump = TRUE; /* set up to jump to assoc'd label */
break;
case CWCMD: /* write one line from pattern space */
for( p1 = linebuf; *p1 != '\n' && *p1 != '\0'; )
putc( *p1, ipc->fout ), p1++;
putc( '\n', ipc->fout );
break;
case WCMD: /* write pattern space to file */
fprintf( ipc->fout, "%s\n", linebuf );
break;
case XCMD: /* exchange pattern and hold spaces */
p1 = linebuf;
p2 = genbuf;
while( ( *p2++ = *p1++ ) != 0 ) ;
p1 = holdsp;
p2 = linebuf;
while( ( *p2++ = *p1++ ) != 0 ) ;
spend = p2 - 1;
p1 = genbuf;
p2 = holdsp;
while( ( *p2++ = *p1++ ) != 0 ) ;
hspend = p2 - 1;
break;
case YCMD:
p1 = linebuf;
p2 = ipc->u.lhs;
while( ( *p1 = p2[*p1] ) != 0 )
p1++;
break;
default: /* Can never happen */
fprintf( stderr, INTERR, "unrecognised command" );
}
}
/* get next line of text to be filtered */
static char *getline( register char *buf ) /* where to send the input */
{
static char const * const linebufend = linebuf + MAXBUF + 2;
int const room = linebufend - buf;
int temp;
char const * const sbuf = buf;
assert( buf >= linebuf && buf < linebufend );
/* The OW fgets has some strange behavior:
* 0 on input is not treated specially. sed ignores the rest of the line.
* 26 (^Z) stops reading the current line and is stripped.
*/
if (fgets(buf, room, stdin) != NULL) { /* gets() can smash program - WFB */
lnum++; /* note that we got another line */
while( ( *buf++ ) != 0 ) ; /* find the end of the input */
if( buf-- - sbuf >= room )
fprintf( stderr, NOROOM, room, lnum ), buf++;
if( *--buf != '\n' ) buf++;
*buf = 0;
if( eargc == 0 ) { /* if no more args */
lastline = ( ( temp = getc( stdin ) ) == EOF );
(void)ungetc( temp, stdin );
}
return( buf ); /* return ptr to terminating null */
} else {
if( eargc == 0 ) /* if no more args */
lastline = TRUE; /* set a flag */
return( BAD );
}
}
/* return TRUE if *a... == *b... for count chars, FALSE otherwise */
static int memeql(
register char const *a,
register char const *b,
int count )
{
while( count-- ) /* look at count characters */
if( *a++ != *b++ ) /* if any are nonequal */
return( FALSE ); /* return FALSE for false */
return( TRUE ); /* compare succeeded */
}
/* write file indicated by r command to output */
static void readout( void )
{
register int t; /* hold input char or EOF */
FILE *fi; /* ptr to file to be read */
sedcmd * const *ap; /* Loops through appends */
for( ap = appends; ap < aptr; ap ++ ) {
sedcmd const * const a = *ap;
char const * const lhs = a->u.lhs;
if( a->command == ACMD ) /* process "a" cmd */
printf( "%s\n", lhs );
else { /* process "r" cmd */
if( ( fi = fopen( lhs, "r" ) ) != NULL ) {
while( ( t = getc( fi ) ) != EOF )
putc( ( char ) t, stdout );
fclose( fi );
}
}
}
aptr = appends; /* reset the append ptr */
}
/* sedexec.c ends here */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?