mirror of
https://github.com/moses-smt/mosesdecoder.git
synced 2024-12-29 06:52:34 +03:00
153 lines
2.9 KiB
C
153 lines
2.9 KiB
C
/*
|
|
* Copyright 1994 Christopher Seiwald. All rights reserved.
|
|
*
|
|
* This file is part of Jam - see jam.c for Copyright information.
|
|
*/
|
|
|
|
/*
|
|
* glob.c - match a string against a simple pattern
|
|
*
|
|
* Understands the following patterns:
|
|
*
|
|
* * any number of characters
|
|
* ? any single character
|
|
* [a-z] any single character in the range a-z
|
|
* [^a-z] any single character not in the range a-z
|
|
* \x match x
|
|
*
|
|
* External functions:
|
|
*
|
|
* glob() - match a string against a simple pattern
|
|
*
|
|
* Internal functions:
|
|
*
|
|
* globchars() - build a bitlist to check for character group match
|
|
*/
|
|
|
|
# include "jam.h"
|
|
|
|
# define CHECK_BIT( tab, bit ) ( tab[ (bit)/8 ] & (1<<( (bit)%8 )) )
|
|
# define BITLISTSIZE 16 /* bytes used for [chars] in compiled expr */
|
|
|
|
static void globchars( char * s, char * e, char * b );
|
|
|
|
|
|
/*
|
|
* glob() - match a string against a simple pattern.
|
|
*/
|
|
|
|
int glob( char * c, char * s )
|
|
{
|
|
char bitlist[ BITLISTSIZE ];
|
|
char * here;
|
|
|
|
for ( ; ; )
|
|
switch ( *c++ )
|
|
{
|
|
case '\0':
|
|
return *s ? -1 : 0;
|
|
|
|
case '?':
|
|
if ( !*s++ )
|
|
return 1;
|
|
break;
|
|
|
|
case '[':
|
|
/* Scan for matching ]. */
|
|
|
|
here = c;
|
|
do if ( !*c++ ) return 1;
|
|
while ( ( here == c ) || ( *c != ']' ) );
|
|
++c;
|
|
|
|
/* Build character class bitlist. */
|
|
|
|
globchars( here, c, bitlist );
|
|
|
|
if ( !CHECK_BIT( bitlist, *(unsigned char *)s ) )
|
|
return 1;
|
|
++s;
|
|
break;
|
|
|
|
case '*':
|
|
here = s;
|
|
|
|
while ( *s )
|
|
++s;
|
|
|
|
/* Try to match the rest of the pattern in a recursive */
|
|
/* call. If the match fails we'll back up chars, retrying. */
|
|
|
|
while ( s != here )
|
|
{
|
|
int r;
|
|
|
|
/* A fast path for the last token in a pattern. */
|
|
r = *c ? glob( c, s ) : *s ? -1 : 0;
|
|
|
|
if ( !r )
|
|
return 0;
|
|
if ( r < 0 )
|
|
return 1;
|
|
--s;
|
|
}
|
|
break;
|
|
|
|
case '\\':
|
|
/* Force literal match of next char. */
|
|
if ( !*c || ( *s++ != *c++ ) )
|
|
return 1;
|
|
break;
|
|
|
|
default:
|
|
if ( *s++ != c[ -1 ] )
|
|
return 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* globchars() - build a bitlist to check for character group match.
|
|
*/
|
|
|
|
static void globchars( char * s, char * e, char * b )
|
|
{
|
|
int neg = 0;
|
|
|
|
memset( b, '\0', BITLISTSIZE );
|
|
|
|
if ( *s == '^' )
|
|
{
|
|
++neg;
|
|
++s;
|
|
}
|
|
|
|
while ( s < e )
|
|
{
|
|
int c;
|
|
|
|
if ( ( s + 2 < e ) && ( s[1] == '-' ) )
|
|
{
|
|
for ( c = s[0]; c <= s[2]; ++c )
|
|
b[ c/8 ] |= ( 1 << ( c % 8 ) );
|
|
s += 3;
|
|
}
|
|
else
|
|
{
|
|
c = *s++;
|
|
b[ c/8 ] |= ( 1 << ( c % 8 ) );
|
|
}
|
|
}
|
|
|
|
if ( neg )
|
|
{
|
|
int i;
|
|
for ( i = 0; i < BITLISTSIZE; ++i )
|
|
b[ i ] ^= 0377;
|
|
}
|
|
|
|
/* Do not include \0 in either $[chars] or $[^chars]. */
|
|
b[0] &= 0376;
|
|
}
|