1/* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License as 4 * published by the Free Software Foundation; either version 2 of 5 * the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 15 * MA 02111-1307 USA 16 */ 17/*************************************************************************** 18 * LPRng - An Extended Print Spooler System 19 * 20 * Copyright 1988-2003, Patrick Powell, San Diego, CA 21 * papowell@lprng.com 22 * See LICENSE for conditions of use. 23 * 24 ***************************************************************************/ 25 26 static char *const _id = 27"$Id: globmatch.c,v 1.1.1.1 2008/10/15 03:28:26 james26_jang Exp $"; 28 29#include "lp.h" 30 31/**** ENDINCLUDE ****/ 32 33int glob_pattern( char *pattern, const char *str ) 34{ 35 int result = 1; 36 int len, c, invert; 37 char *glob; 38 39 /* DEBUG4("glob_pattern: pattern '%s' to '%s'", pattern, str ); */ 40 if( (glob = safestrpbrk( pattern, "*?[" )) ){ 41 /* check the characters up to the glob length for a match */ 42 len = glob - pattern; 43 c = *glob; 44 /* DEBUG4("glob_pattern: meta '%c', len %d", c, len ); */ 45 if( (len == 0 || !safestrncasecmp( pattern, str, len )) ){ 46 /* matched: pattern xxxx* to xxxx 47 * now we have to do the remainder. We simply check for rest 48 */ 49 pattern += len+1; 50 str += len; 51 /* DEBUG4("glob_pattern: rest of pattern '%s', str '%s'", pattern, str ); */ 52 /* check for trailing glob */ 53 if( c == '?' ){ 54 if( *str ){ 55 result = glob_pattern( pattern, str+1 ); 56 } else { 57 result = 1; 58 } 59 } else if( c == '[' ){ 60 /* now we check for the characters in the pattern 61 * this can have the format N or N-M 62 */ 63 glob = safestrchr( pattern, ']' ); 64 if( glob == 0 ){ 65 return( 1 ); 66 } 67 len = glob - pattern; 68 invert = c = 0; 69 /* DEBUG4("globmatch: now case '%s', len %d", pattern, len ); */ 70 if( len > 0 && (invert = (*pattern == '^')) ){ 71 --len; ++pattern; 72 } 73 while( result && len > 0 ){ 74 /* DEBUG4("globmatch: c '0x%x', pat '%c', str '%c'", 75 c, *pattern, *str ); */ 76 if( c && *pattern == '-' && len > 1 ){ 77 /* we have preceeding, get end */ 78 pattern++; --len; 79 while( result && c <= *pattern ){ 80 /* DEBUG4("globmatch: range c '%c', pat '%c', str '%c'", 81 c, *pattern, *str ); */ 82 result = (*str != c++); 83 } 84 pattern++; --len; 85 c = 0; 86 } else { 87 c = *pattern++; --len; 88 result = (*str != c); 89 } 90 } 91 if( invert ) result = !result; 92 /* DEBUG4("globmatch: after pattern result %d", result); */ 93 if( result == 0 ){ 94 pattern += len+1; 95 ++str; 96 /* at this point pattern is past */ 97 result = glob_pattern( pattern, str ); 98 } 99 } else if( pattern[0] ){ 100 while( *str && (result = glob_pattern( pattern, str )) ){ 101 ++str; 102 } 103 } else { 104 result = 0; 105 } 106 } 107 } else { 108 result = safestrcasecmp( pattern, str ); 109 } 110 return( result ); 111} 112 113int Globmatch( char *pattern, const char *str ) 114{ 115 int result; 116 117 /* try simple test first: string compare */ 118 /* DEBUG4("Globmatch: pattern '%s' to '%s'", pattern, str ); */ 119 if( pattern == 0 ) pattern = ""; 120 if( str == 0 ) str = ""; 121 result = glob_pattern( pattern, str ); 122 DEBUG4("Globmatch: '%s' to '%s' result %d", pattern, str, result ); 123 return( result ); 124} 125 126int Globmatch_list( struct line_list *l, char *str ) 127{ 128 int result = 1, i; 129 for( i = 0; result && i < l->count; ++i ){ 130 result = Globmatch(l->list[i],str); 131 } 132 return( result ); 133} 134