sedcomp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,082 行 · 第 1/4 页
C
1,082 行
firstep[2] = (char)width-1;
lastep++;
ep++;
}
break;
case CBACK:
break;
case CEOF: /* Can't happen - would require * after end of expression WFB 20040813 */
case CNL: /* Can't happen - * is literal after special ^ */
case CDOL: /* Can't happen - $ is literal if not last */
case CLNUM:/* Can't happen - * after line number is nonsense */
case CEND: /* Can't happen - CEND is always followed by CEOF */
default:
fprintf( stderr, INERR, "Unexpected symbol in RE" ), myexit( 2 );
}
break;
} /* switch( c ) */
} /* for( ;; ) */
}
/* read next command from -e argument or command file */
static int cmdline( register char *cbuf ) /* uses eflag, eargc, cmdf */
{
register int inc; /* not char because must hold EOF */
assert( cbuf == cp );
cbuf--; /* so pre-increment points us at cbuf */
/* e command flag is on */
if( eflag ) {
register char *p; /* ptr to current -e argument */
static char *savep; /* saves previous value of p */
if( eflag > 0 ) { /* there are pending -e arguments */
eflag = -1;
if( --eargc <= 0 ) /* barf if no argument */
fprintf( stderr, NEEDB, eargv[0] ), myexit( 2 );
/* else copy next e argument to cbuf */
p = *++eargv;
while( ( *++cbuf = *p++ ) != 0 )
if( *cbuf == '\\' ) { /* Could not sedtest this! WFB 20040802 */
if( ( *++cbuf = *p++ ) == '\0' ) {
if( --eargc <= 0 ) /* barf if no argument */
fprintf( stderr, NEEDB, eargv[0] ), myexit( 2 );
*cbuf = '\n';
p = *++eargv;
}
} else if( *cbuf == '\n' ) { /* end of 1 cmd line */
*cbuf = '\0';
return( savep = p, 1 );
/* we'll be back for the rest... */
}
/* have string-end;
* can advance to next argument */
return( savep = NULL, 1 );
}
if( ( p = savep ) == NULL )
return( 0 );
while( ( *++cbuf = *p++ ) != 0 )
if( *cbuf == '\\' ) {
if( ( *++cbuf = *p++ ) == '0' )
return( savep = NULL, 0 );
} else if( *cbuf == '\n' ) {
*cbuf = '\0';
return( savep = p, 1 );
}
return( savep = NULL, 1 );
}
/* if no -e flag
* read from command file descriptor */
while( ( inc = getc( cmdf ) ) != EOF ) { /* get next char */
switch( *++cbuf = (char)inc ) {
case '\\': /* if it's escape */
inc = getc( cmdf ), /* get next char */
*++cbuf = (char)inc;
break;
case '\n': /* end on newline */
return( *cbuf = '\0', 1 ); /* cap the string */
}
}
return( *++cbuf = '\0', cbuf >= cp+1 ); /* end-of-file, no more chars */
}
/* expand an address at *cp... into expbuf, return ptr at following char */
static char *getaddress( register char *expbuf ) /* uses cp, linenum */
{
static int numl = 0; /* current ind in addr-number table */
register char *rcp; /* temp compile ptr for forwd look */
long lno; /* computed value of numeric address */
switch( *cp ) {
case '$': /* end-of-source address */
*expbuf++ = CEND; /* write symbolic end address */
*expbuf++ = CEOF; /* and the end-of-address mark (!) */
cp++; /* go to next source character */
return( expbuf ); /* we're done */
case '\\': /* posix \cBREc address */
cp++; /* Point to delimiter */
case '/': /* start of regular-expression match */
return( recomp( expbuf, *cp++ ) ); /* compile the RE */
}
rcp = cp;
lno = 0; /* now handle a numeric address */
while( isdigit( *rcp ) ) /* collect digits */
lno = lno*10 + *rcp++ - '0'; /* compute their value */
if( rcp > cp ) { /* if we caught a number... */
*expbuf++ = CLNUM; /* put a numeric-address marker */
*expbuf++ = (char)numl; /* and the address table index */
linenum[numl++] = lno; /* and set the table entry */
/* Not exercised by sedtest.mak */
if( numl >= MAXLINES ) /* oh-oh, address table overflow */
ABORT( TMLNR ); /* abort with error message */
*expbuf++ = CEOF; /* write the end-of-address marker */
cp = rcp; /* point compile past the address */
return( expbuf ); /* we're done */
}
return( NULL ); /* no legal address was found */
}
/*
* accept multiline input from *cp... to *fp... ,
* optionally skipping leading whitespace
*/
static void gettext( int accept_whitespace )
{
char c;
if( !accept_whitespace )
SKIPWS( cp ); /* discard whitespace */
while( fp < poolend && ( c = *fp++ = *cp++ ) != 0 ) {
switch( c )
{
case '\\': /* handle escapes */
fp[-1] = *cp++;
break;
case '\n': /* SKIPWS after newline */
SKIPWS( cp );
break;
}
}
if( fp >= poolend )
ABORT( TMTXT ); /* Not exercised by sedtest.mak */
--cp;
return;
}
/* find the label matching *ptr, return NULL if none */
static label *search( void ) /* uses globals lablst and curlab */
{
register label *rp;
char const * const name = curlab->name;
for( rp = lablst; rp < curlab; rp++ )
if( strcmp( rp->name, name ) == 0 )
return( rp );
return( NULL );
}
/* write label links into the compiled-command space */
static void resolve( void ) /* uses global lablst */
{
register label const *rp;
register sedcmd *rptr;
register sedcmd *trptr;
/* loop through the label table */
for( rp = lablst; rp < curlab; rp++ )
if( rp->link == NULL ) /* barf if not defined */
fprintf( stderr, ULABL, rp->name ), myexit( 2 );
else if( rp->last ) { /* if last is non-null */
for( rptr = rp->last; ( trptr = rptr->u.link ) != 0; rptr = trptr )
rptr->u.link = rp->link;
rptr->u.link = rp->link - 1;
}
}
/* compile a y (transliterate) command */
static char *ycomp(
register char *ep, /* where to compile to */
char delim ) /* end delimiter to look for */
{
register int c;
register char *tp;
register char const *sp;
if( delim == 0 || delim == '\\' || delim == '\n' )
return( BAD );
/* scan 'from' for invalid chars */
for( sp = tp = cp; *tp != delim; tp++ ) {
if( *tp == '\\' )
tp++;
if( ( *tp == '\n' ) || ( *tp == '\0' ) )
return( BAD );
}
tp++; /* tp points at first char of 'to' */
/* now rescan the 'from' section */
while( ( c = (char)( *sp++ & 0x7F ) ) != delim ) {
if( c == '\\' )
switch( c = *sp++ & 0x7F ) {
case 'n': /* '\\''n' -> '\n' */
c = '\n';
break;
case '\\':
break;
default:
if( c != delim )
return( BAD );
c = delim;
break;
}
if( ep[c] != 0 )
return( BAD ); /* c has already been mapped */
if( ( ep[c] = *tp++ & 0x7F ) == '\\' ) {
switch( *tp ) {
case 'n': /* '\\''n' -> '\n' */
ep[c] = '\n';
break;
case '\\':
break;
default:
if( *tp != delim )
return( BAD );
ep[c] = delim;
break;
}
tp++;
}
if( ep[c] == '\0' )
return( BAD );
}
if( *tp != delim ) /* 'to', 'from' lengths unequal */
return( BAD );
cp = ++tp; /* point compile ptr past translit */
for( c = 0; c < 128; c++ ) /* fill in self-map entries in table */
if( ep[c] == 0 )
ep[c] = c;
return( ep + 0x80 ); /* first free location past table end */
}
/* Avoid race condition with calls like echo hello | fail */
static void myexit( int status )
{
assert( status != 0 ); /* Call only needed for failures */
if( !isatty( fileno( stdin ) ) )
while( fgets( linebuf, MAXBUF, stdin ) != NULL ) ;
exit( status );
}
static void usage( void )
{
const char * const *cpp;
for( cpp = USAGE; *cpp != NULL; cpp++ )
fprintf( stderr, "%s\n", *cpp );
myexit( 2 );
}
/* sedcomp.c ends here */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?