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