The Machine Perception Toolbox

[Introduction]- [News]- [Download]- [Screenshots]- [Manual (pdf)]- [Forums]- [API Reference]- [Repository ]

 

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

glob.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 1994 Christopher Seiwald.  All rights reserved. 
00003  *
00004  * This file is part of Jam - see jam.c for Copyright information.
00005  */
00006 
00007 /*
00008  * glob.c - match a string against a simple pattern
00009  *
00010  * Understands the following patterns:
00011  *
00012  *      *       any number of characters
00013  *      ?       any single character
00014  *      [a-z]   any single character in the range a-z
00015  *      [^a-z]  any single character not in the range a-z
00016  *      \x      match x
00017  *      
00018  * External functions:
00019  *
00020  *      glob() - match a string against a simple pattern
00021  *
00022  * Internal functions:
00023  *
00024  *      globchars() - build a bitlist to check for character group match
00025  */
00026 
00027 # include "jam.h"
00028 
00029 # define CHECK_BIT( tab, bit ) ( tab[ (bit)/8 ] & (1<<( (bit)%8 )) )
00030 # define BITLISTSIZE 16 /* bytes used for [chars] in compiled expr */
00031 
00032 static void globchars( char *s, char *e, char *b );
00033 
00034 /*
00035  * glob() - match a string against a simple pattern
00036  */
00037 
00038 int
00039 glob(
00040         register char *c,
00041         register char *s )
00042 {
00043         char bitlist[ BITLISTSIZE ];
00044         char *here;
00045 
00046         for( ;; )
00047             switch( *c++ )
00048         {
00049         case '\0':
00050                 return *s ? -1 : 0;
00051 
00052         case '?':
00053                 if( !*s++ )
00054                     return 1;
00055                 break;
00056 
00057         case '[':
00058                 /* scan for matching ] */
00059 
00060                 here = c;
00061                 do if( !*c++ )
00062                         return 1;
00063                 while( here == c || *c != ']' );
00064                 c++;
00065 
00066                 /* build character class bitlist */
00067 
00068                 globchars( here, c, bitlist );
00069 
00070                 if( !CHECK_BIT( bitlist, *(unsigned char *)s ) )
00071                         return 1;
00072                 s++;
00073                 break;
00074 
00075         case '*':
00076                 here = s;
00077 
00078                 while( *s ) 
00079                         s++;
00080 
00081                 /* Try to match the rest of the pattern in a recursive */
00082                 /* call.  If the match fails we'll back up chars, retrying. */
00083 
00084                 while( s != here )
00085                 {
00086                         int r;
00087 
00088                         /* A fast path for the last token in a pattern */
00089 
00090                         r = *c ? glob( c, s ) : *s ? -1 : 0;
00091 
00092                         if( !r )
00093                                 return 0;
00094                         else if( r < 0 )
00095                                 return 1;
00096 
00097                         --s;
00098                 }
00099                 break;
00100 
00101         case '\\':
00102                 /* Force literal match of next char. */
00103 
00104                 if( !*c || *s++ != *c++ )
00105                     return 1;
00106                 break;
00107 
00108         default:
00109                 if( *s++ != c[-1] )
00110                     return 1;
00111                 break;
00112         }
00113 }
00114 
00115 /*
00116  * globchars() - build a bitlist to check for character group match
00117  */
00118 
00119 static void
00120 globchars( 
00121         char *s, 
00122         char *e, 
00123         char *b )
00124 {
00125         int neg = 0;
00126 
00127         memset( b, '\0', BITLISTSIZE  );
00128 
00129         if( *s == '^') 
00130                 neg++, s++;
00131 
00132         while( s < e )
00133         {
00134                 int c;
00135 
00136                 if( s+2 < e && s[1] == '-' )
00137                 {
00138                         for( c = s[0]; c <= s[2]; c++ )
00139                                 b[ c/8 ] |= (1<<(c%8));
00140                         s += 3;
00141                 } else {
00142                         c = *s++;
00143                         b[ c/8 ] |= (1<<(c%8));
00144                 }
00145         }
00146                         
00147         if( neg )
00148         {
00149                 int i;
00150                 for( i = 0; i < BITLISTSIZE; i++ )
00151                         b[ i ] ^= 0377;
00152         }
00153 
00154         /* Don't include \0 in either $[chars] or $[^chars] */
00155 
00156         b[0] &= 0376;
00157 }

Generated on Mon Nov 8 17:07:35 2004 for MPT by  doxygen 1.3.9.1