@ -2133,9 +2133,8 @@ static void destroy_pattern_tree(struct match_char *pattern_tree) /* pattern tre
* we could encode the special cases as 0xff XX where XX
* we could encode the special cases as 0xff XX where XX
* is 1 , 2 , 3 , 4 as used above .
* is 1 , 2 , 3 , 4 as used above .
*/
*/
static int ext_cmp1 ( const char * * p )
static int ext_cmp1 ( const char * * p , unsigned char * bitwise )
{
{
uint32_t chars [ 8 ] ;
int c , cmin = 0xff , count = 0 ;
int c , cmin = 0xff , count = 0 ;
const char * end ;
const char * end ;
@ -2143,6 +2142,7 @@ static int ext_cmp1(const char **p)
* a valid character .
* a valid character .
*/
*/
c = * ( * p ) + + ;
c = * ( * p ) + + ;
memset ( bitwise , 0xff , 32 ) ;
/* always return unless we have a set of chars */
/* always return unless we have a set of chars */
switch ( toupper ( c ) ) {
switch ( toupper ( c ) ) {
@ -2150,12 +2150,19 @@ static int ext_cmp1(const char **p)
return 0x0000 | ( c & 0xff ) ;
return 0x0000 | ( c & 0xff ) ;
case ' N ' : /* 2..9 */
case ' N ' : /* 2..9 */
bitwise [ 6 ] = 0x01 ;
bitwise [ 7 ] = 0xfe ;
return 0x0800 | ' 2 ' ;
return 0x0800 | ' 2 ' ;
case ' X ' : /* 0..9 */
case ' X ' : /* 0..9 */
bitwise [ 5 ] = 0x7f ;
bitwise [ 6 ] = 0x00 ;
bitwise [ 7 ] = 0xfe ;
return 0x0A00 | ' 0 ' ;
return 0x0A00 | ' 0 ' ;
case ' Z ' : /* 1..9 */
case ' Z ' : /* 1..9 */
bitwise [ 6 ] = 0x00 ;
bitwise [ 7 ] = 0xfe ;
return 0x0900 | ' 1 ' ;
return 0x0900 | ' 1 ' ;
case ' . ' : /* wildcard */
case ' . ' : /* wildcard */
@ -2179,22 +2186,28 @@ static int ext_cmp1(const char **p)
return 0x40000 ; /* XXX make this entry go last... */
return 0x40000 ; /* XXX make this entry go last... */
}
}
memset ( chars , ' \0 ' , sizeof ( chars ) ) ; /* clear all chars in the set */
for ( ; * p < end ; ( * p ) + + ) {
for ( ; * p < end ; ( * p ) + + ) {
unsigned char c1 , c2 ; /* first-last char in range */
unsigned char c1 , c2 ; /* first-last char in range */
c1 = ( unsigned char ) ( ( * p ) [ 0 ] ) ;
c1 = ( unsigned char ) ( ( * p ) [ 0 ] ) ;
if ( * p + 2 < end & & ( * p ) [ 1 ] = = ' - ' ) { /* this is a range */
if ( * p + 2 < end & & ( * p ) [ 1 ] = = ' - ' ) { /* this is a range */
c2 = ( unsigned char ) ( ( * p ) [ 2 ] ) ;
c2 = ( unsigned char ) ( ( * p ) [ 2 ] ) ;
* p + = 2 ; /* skip a total of 3 chars */
* p + = 2 ; /* skip a total of 3 chars */
} else /* individual character */
} else { /* individual character */
c2 = c1 ;
c2 = c1 ;
if ( c1 < cmin )
}
if ( c1 < cmin ) {
cmin = c1 ;
cmin = c1 ;
}
for ( ; c1 < = c2 ; c1 + + ) {
for ( ; c1 < = c2 ; c1 + + ) {
uint32_t mask = 1 < < ( c1 % 32 ) ;
unsigned char mask = 1 < < ( c1 % 8 ) ;
if ( ( chars [ c1 / 32 ] & mask ) = = 0 )
/* Count the number of characters in the class, discarding duplicates. */
if ( ( bitwise [ c1 / 8 ] & mask ) = = 1 ) {
count + = 0x100 ;
count + = 0x100 ;
chars [ c1 / 32 ] | = mask ;
}
/*!\note If two patterns score the same, but one includes '0' (as
* the lowest ASCII value in the given class ) and the other does
* not , then the one including ' 0 ' will compare as coming first . */
bitwise [ c1 / 8 ] & = ~ mask ;
}
}
}
}
( * p ) + + ;
( * p ) + + ;
@ -2208,8 +2221,9 @@ static int ext_cmp(const char *a, const char *b)
{
{
/* make sure non-patterns come first.
/* make sure non-patterns come first.
* If a is not a pattern , it either comes first or
* If a is not a pattern , it either comes first or
* we use strcmp to compare the strings .
* we do a more complex pattern comparison .
*/
*/
unsigned char bitwise [ 2 ] [ 32 ] ;
int ret = 0 ;
int ret = 0 ;
if ( a [ 0 ] ! = ' _ ' )
if ( a [ 0 ] ! = ' _ ' )
@ -2218,17 +2232,21 @@ static int ext_cmp(const char *a, const char *b)
/* Now we know a is a pattern; if b is not, a comes first */
/* Now we know a is a pattern; if b is not, a comes first */
if ( b [ 0 ] ! = ' _ ' )
if ( b [ 0 ] ! = ' _ ' )
return 1 ;
return 1 ;
#if 0 /* old mode for ext matching */
return strcmp ( a , b ) ;
# endif
/* ok we need full pattern sorting routine */
/* ok we need full pattern sorting routine */
while ( ! ret & & a & & b )
while ( ! ret & & a & & b ) {
ret = ext_cmp1 ( & a ) - ext_cmp1 ( & b ) ;
ret = ext_cmp1 ( & a , bitwise [ 0 ] ) - ext_cmp1 ( & b , bitwise [ 1 ] ) ;
if ( ret = = 0 )
if ( ret = = 0 ) {
/* Are the classes different, even though they score the same? */
ret = memcmp ( bitwise [ 0 ] , bitwise [ 1 ] , 32 ) ;
}
}
if ( ret = = 0 ) {
return 0 ;
return 0 ;
else
} else {
return ( ret > 0 ) ? 1 : - 1 ;
return ( ret > 0 ) ? 1 : - 1 ;
}
}
}
int ast_extension_cmp ( const char * a , const char * b )
int ast_extension_cmp ( const char * a , const char * b )
{
{