2021-10-11 19:38:01 -03:00

351 lines
7.6 KiB
C
Executable File

/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)search.c 1.4 92/07/14 SMI" /* SVr4.0 1.6 */
#include <setjmp.h>
#include <table.h>
#include <internal.h>
extern jmp_buf TLenv;
#define INIT register char *sp = instring; extern char *TLenvp;
#define GETC() (*sp++)
#define PEEKC() (*sp)
#define UNGETC(c) (--sp)
#define RETURN(c) return;
#define ERROR(c) longjmp( TLenv, 0 )
#include <regexp.h>
#define ATOI(s,r) { \
unsigned char *ptr; \
r = (long)strtol( (char *)s, (char **)&ptr, 0L ); \
if( ptr == s ) return( FALSE ); \
}
extern tbl_t TLtables[];
extern unsigned char TLgenbuf[];
long strtol();
static int
TLs_strmatch( string, pattern )
unsigned char *string, *pattern;
{
unsigned char TLexpbuf[ TL_MAXLINESZ ];
/* Come back to this point if regexp error */
if( setjmp( TLenv ) ) return( FALSE );
(void) compile( (char *)pattern, (char *)TLexpbuf,
(char *)&TLexpbuf[TL_MAXLINESZ], '\0' );
return( TLsearch( string, TLexpbuf ) );
}
/*ARGSUSED*/
static int
TLs_op( tid, fieldvalue, sptr )
int tid;
unsigned char *fieldvalue;
TLsearch_t *sptr;
{
register rc, p_value, f_value, op;
if (fieldvalue == NULL)
return (0);
op = (int)(sptr->ts_operation);
switch( op ) {
case TLEQ:
rc = !Strcmp( fieldvalue, sptr->ts_pattern );
break;
case TLNE:
rc = Strcmp( fieldvalue, sptr->ts_pattern );
break;
case TLLT:
rc = (Strcmp( fieldvalue, sptr->ts_pattern ) < 0);
break;
case TLGT:
rc = (Strcmp( fieldvalue, sptr->ts_pattern ) > 0);
break;
case TLLE:
rc = (Strcmp( fieldvalue, sptr->ts_pattern ) <= 0 );
break;
case TLGE:
rc = (Strcmp( fieldvalue, sptr->ts_pattern ) >= 0 );
break;
case TLMATCH:
rc = TLs_strmatch( fieldvalue, sptr->ts_pattern );
break;
case TLNMATCH:
rc = !TLs_strmatch( fieldvalue, sptr->ts_pattern );
break;
case TLNUMEQ:
ATOI( fieldvalue, f_value )
ATOI( sptr->ts_pattern, p_value )
rc = (f_value == p_value);
break;
case TLNUMNE:
ATOI( fieldvalue, f_value )
ATOI( sptr->ts_pattern, p_value )
rc = (f_value != p_value);
break;
case TLNUMLT:
ATOI( fieldvalue, f_value )
ATOI( sptr->ts_pattern, p_value )
rc = (f_value < p_value);
break;
case TLNUMGT:
ATOI( fieldvalue, f_value )
ATOI( sptr->ts_pattern, p_value )
rc = (f_value > p_value);
break;
case TLNUMLE:
ATOI( fieldvalue, f_value )
ATOI( sptr->ts_pattern, p_value )
rc = (f_value <= p_value);
break;
case TLNUMGE:
ATOI( fieldvalue, f_value )
ATOI( sptr->ts_pattern, p_value )
rc = (f_value >= p_value);
break;
default:
rc = (*(sptr->ts_operation))( sptr->ts_fieldname, fieldvalue,
sptr->ts_pattern );
break;
}
return( rc );
}
static int
TLs_match( tid, entry, sarray, how_to_match )
int tid, how_to_match;
entry_t *entry;
TLsearch_t *sarray;
{
register tbl_t *tptr = TLtables + tid;
register TLsearch_t *sptr;
register unsigned char *fptr;
register accum = (how_to_match == TL_AND || how_to_match == TL_NOR ), rc;
register offset;
for( sptr = sarray; sptr->ts_fieldname; sptr++ ) {
/* Get pointer to string to match against */
if( !Strcmp( sptr->ts_fieldname, TLCOMMENT ) ) {
if( !E_NFIELDS(entry) ) fptr = E_COMMENT(entry);
else return( FALSE );
} else if( !Strcmp( sptr->ts_fieldname, TLTRAILING ) )
fptr = E_COMMENT(entry);
else if( (offset = TLf_find( &(tptr->fieldnames), sptr->ts_fieldname ))
== -1 )
return( FALSE );
else fptr = *E_GETFIELD(entry, offset);
rc = TLs_op( tid, fptr, sptr );
switch( how_to_match ) {
case TL_AND:
accum = accum && rc;
if( !accum ) return( FALSE );
break;
case TL_OR:
accum = accum || rc;
if( accum ) return( TRUE );
break;
case TL_NAND:
accum = accum || !rc;
if( accum ) return( TRUE );
break;
case TL_NOR:
accum = accum && !rc;
if( !accum ) return( FALSE );
break;
}
}
return( accum );
}
int
TLs_search( tid, sarray, first, last, how_to_match )
int tid, how_to_match;
TLsearch_t *sarray;
entryno_t first, last;
{
register tbl_t *tptr = TLtables + tid;
register TLsearch_t *sptr;
register entryno_t dot, direction = (first < last), done = FALSE;
register rc;
entry_t *entry;
for( sptr = sarray; sptr->ts_fieldname; sptr++ ) {
if( Strcmp( sptr->ts_fieldname, TLCOMMENT )
&& Strcmp( sptr->ts_fieldname, TLTRAILING )
&& TLf_find( &(tptr->fieldnames), sptr->ts_fieldname ) == -1 )
return( TLBADFIELD );
}
dot = first;
while( !done ) {
/* Get the current entry */
if( (rc = TLe_getentry( tid, dot, &entry )) != TLOK )
return( rc );
if( TLs_match( tid, entry, sarray, how_to_match ) )
return( dot );
if( direction ) {
dot++;
if( dot > last ) done = TRUE;
} else {
dot--;
if( dot < last ) done = TRUE;
}
}
return( TLFAILED );
}
static unsigned char *
TLplace( sp, l1, l2, limit )
register unsigned char *sp, *l1, *l2, *limit;
{
while (l1 < l2) {
*sp++ = *l1++;
if( sp >= limit ) return( 0 );
}
return( (unsigned char *)sp );
}
/*
Search for pattern in string; replace with replacetxt and leave
the result in TLgenbuf;
*/
static int
TLsubstitute( string, pattern, replacetxt )
unsigned char *string, *pattern, *replacetxt;
{
if( !TLs_strmatch( string, pattern ) ) return( 0 );
return( TLreplace( string, replacetxt ) );
}
static int
TLreplace( string, text )
unsigned char *string, *text;
{
register unsigned char *lp, *sp, *rp, *limit;
unsigned char c, buf[2];
register offset;
lp = (unsigned char *)string;
sp = TLgenbuf;
rp = (unsigned char *)text;
limit = (unsigned char *)(TLgenbuf + TL_MAXLINESZ);
/* Copy text from before match (loc1 points at 1st char of matched text) */
while (lp < (unsigned char *)loc1)
*sp++ = *lp++;
/* Copy Matched portion */
while( c = *rp++ ) {
if( c == '&' ) {
if( !(sp = TLplace( sp, (unsigned char *)loc1, (unsigned char *)loc2,
limit ) ) )
return( 0 );
continue;
} else if( c == '\\' ) {
buf[0] = c = *rp++;
buf[1] = '\0';
offset = atoi( (char *)buf );
if( offset > 0 && offset <= nbra ) {
sp = TLplace( sp, (unsigned char *)braslist[ offset - 1 ],
(unsigned char *)braelist[ offset - 1 ], limit );
if( !sp ) return( 0 );
continue;
}
}
*sp++ = c;
if( sp >= limit )
return( 0 );
}
/* Copy portion AFTER matched text */
lp = (unsigned char *)loc2;
while( *sp++ = *lp++ )
if( sp >= limit )
return( 0 );
return( 1 );
}
static
TLsearch( string, expbuf )
unsigned char *string, *expbuf;
{
register c;
/* Reset Braced expression list */
for( c = 0; c < NBRA; c++ ) {
braslist[c] = 0;
braelist[c] = 0;
}
locs = 0;
/*
* Check for NULL string, as in when backup
* register table has a line with only a # character
* in column 1.
*/
if (string == NULL)
return(0);
return( step( (char *)string, (char *)expbuf ) );
}
int
TLs_replace( tid, entry, fieldname, pattern, replacetxt )
int tid;
entry_t *entry;
unsigned char *fieldname, *pattern, *replacetxt;
{
register tbl_t *tptr = TLtables + tid;
register offset;
unsigned char buf[1], *fieldvalue;
if( !Strcmp( fieldname, TLCOMMENT ) ) {
if( !E_NFIELDS(entry) ) fieldvalue = E_COMMENT(entry);
else return( TLFAILED );
} else if( !Strcmp( fieldname, TLTRAILING ) )
fieldvalue = E_COMMENT(entry);
else if( (offset = TLf_find( &(tptr->fieldnames), fieldname ) ) == -1 )
return( TLBADFIELD );
else fieldvalue = *E_GETFIELD(entry, offset);
if( !replacetxt ) {
buf[0] = '\0';
replacetxt = buf;
}
if( !TLsubstitute( fieldvalue, pattern, replacetxt ) )
return( TLFAILED );
/* Now 'new' field value is in TLgenbuf */
return( TLf_assign( tid, entry, fieldname, TLgenbuf ) );
}