egrep.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 470 行 · 第 1/2 页
C
470 行
}
static char *getNextLine( int in, int newfile, const char *filename, unsigned lineno )
{
static int rd;
static char * offset;
static char * start;
static char * endbuf;
static int finalread;
static int done = 0;
if( done ) {
done = 0;
return( NULL );
}
if( newfile ) {
if( -1 == ( rd = read( in, IObuffer, IObsize ) ) ) errorExit( "I/O error" );
start = offset = IObuffer;
endbuf = IObuffer + rd;
finalread = ( (size_t) rd < IObsize );
}
for( ; ; ) {
size_t const len = (unsigned int) ( ( endbuf - start ) - ( offset - start ) );
char * const lf = memchr( offset, '\n', len );
char * const line = start;
if( lf != NULL ) {
if( lf > IObuffer && lf[-1] == '\r' ) lf[-1] = '\0';
*lf = '\0';
offset = start = lf + 1;
return( line );
}
if( finalread ) {
endbuf[1] = '\0';
done = 1;
return( start );
}
if( len >= IObsize ) {
free( IObuffer );
if( ( IObuffer = malloc( IObsize += IObsize >> 1 ) ) == 0
|| -1 == lseek( in, -rd, SEEK_CUR ) )
errorExit( "line too long: len (%lu) >= IObsize (%lu) at \"%s\":%u",
(unsigned long) len, (unsigned long) IObsize, filename, lineno );
return getNextLine( in, newfile, filename, lineno );
}
memmove( IObuffer, offset, len );
start = IObuffer;
offset = IObuffer + len;
if( -1 == ( rd = read( in, offset, IObsize - len ) ) ) errorExit( "I/O error" );
finalread = ( (size_t) rd < IObsize - len );
endbuf = offset + rd;
}
}
static unsigned searchFile( const char *filename, int in, int numfile )
{
char *line;
char match;
char const invert = ((Flags & M_SEARCH_INVERT) != 0);
unsigned lineno = 1;
unsigned matches = 0;
int new = 1;
while( ( line = getNextLine( in, new, filename, lineno ) ) != NULL ) { // returns offset into IObuffer
new = 0;
match = (char) searchBuffer( line );
if( match ^ invert ) {
matches++;
if( Omode == OUT_LINES ) {
if( numfile > 1 ) {
printf( "%s: ", filename );
}
if( Flags & M_PREFIX_LINE ) {
printf( "%u: ", lineno );
}
printf( "%s\n", line );
} else if( Omode == OUT_FILES ) {
printf( "%s\n", filename );
break;
}
}
lineno++;
}
return( matches );
}
static void parsePatterns( void )
{
char * const *pat;
char *p;
for( pat = fPatterns; *pat != NULL; pat++ ) {
for( p = *pat; *p; p++ ) {
*p = CharTrans[ *p ];
CharExist[ *p ] = 1;
}
}
}
static void insertPattern( const char *pat )
{
if( PatCount >= MAX_SEARCH_STR ) {
errorExit( "too many search patterns" );
}
#ifdef FGREP
fPatterns[ PatCount ] = strdup( pat );
#else
ePatterns[ PatCount ] = RegComp( (char *) pat );
if( ePatterns[ PatCount ] == NULL ) {
errorExit( "error forming regular expression" );
}
#endif
PatCount++;
}
static void readPatternFile( const char *filename )
{
FILE *fp = fopen( filename, "r" );
char *cr;
unsigned const patstart = PatCount;
if( fp == NULL )
errorExit( "cannot open pattern file \"%s\"", filename );
while( fgets( IObuffer, IObsize, fp ) ) {
if( ( cr = strrchr( IObuffer, '\n' ) ) == NULL )
errorExit( "invalid pattern \"%s\" in \"%s\"", IObuffer, filename );
*cr = '\0';
insertPattern( IObuffer );
}
(void) fclose( fp );
if( patstart == PatCount )
errorExit( "No pattern in \"%s\"", filename );
}
static void changeTransTable( void )
{
int ch;
for( ch = 'A'; ch <= 'Z'; ch++ ) { // Change uppers to lowers in
CharTrans[ ch ] |= 0x20; // translation table
}
}
static void handle_options( int *pargc, char **argv, int *prematch )
{
int ch; // switch chars
while( -1 != ( ch = GetOpt( pargc, argv, (char *) "ce:f:ilnsvXx", usageMsg ) ) ) {
switch( ch ) {
case 'c':
Omode = OUT_COUNT;
break;
case 'e':
insertPattern( OptArg );
break;
case 'f':
readPatternFile( OptArg );
break;
case 'i':
Flags |= M_SEARCH_IGNORE;
CaseIgnore = TRUE;
changeTransTable( );
break;
case 'l':
Omode = OUT_FILES;
break;
case 'n':
Flags |= M_PREFIX_LINE;
break;
case 's':
Flags |= M_SUPPRESS_ERROR;
break;
case 'v':
Flags |= M_SEARCH_INVERT;
break;
case 'X':
*prematch = 1;
break;
case 'x':
Flags |= M_SEARCH_EXACT;
break;
default: /* Do nothing */
break;
}
}
}
int main( int argc, char **argv )
{
int rematch = 0; // regexp file matching is OFF
unsigned matches = 0; // number of matches
if( ( IObuffer = malloc( IObsize = IOBUF_MIN ) ) == NULL )
errorExit( "insufficient memory for file buffer" );
CaseIgnore = FALSE; // case sensitive match by default
argv = ExpandEnv( &argc, argv );
handle_options( &argc, argv, &rematch );
if( PatCount == 0 ) {
if( argc <= 1 )
errorExit( "%s", usageMsg[0] );
argc--, argv++;
insertPattern( *argv );
}
parsePatterns( );
argv = ExpandArgv( &argc, argv, rematch );
if( *++argv == NULL ) {
(void) setmode( STDIN_FILENO, O_BINARY );
matches = searchFile( "stdin", STDIN_FILENO, 1 );
} else {
while( *argv != NULL ) {
int const in = open( *argv, O_BINARY | O_RDONLY ); // input file handle
if( in == -1 ) {
if( !(Flags & M_SUPPRESS_ERROR) )
fprintf( stderr, "%s: cannot open input file \"%s\"\n",
OptEnvVar, *argv );
} else {
matches += searchFile( *argv, in, argc - 1 );
close( in );
}
argv++;
}
}
if( Omode == OUT_COUNT )
printf( "%u\n", matches );
free( IObuffer );
freePatterns( );
return( matches == 0 );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?