summaryrefslogtreecommitdiff
path: root/match.c
blob: c0729dd8daf5ccf70106837b00125b341ab482ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
 * 
 * match.c
 * 
 * Author: Tatu Ylonen <ylo@cs.hut.fi>
 * 
 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 *                    All rights reserved
 * 
 * Created: Thu Jun 22 01:17:50 1995 ylo
 * 
 * Simple pattern matching, with '*' and '?' as wildcards.
 * 
 */

#include "includes.h"
RCSID("$Id: match.c,v 1.2 1999/11/24 13:26:22 damien Exp $");

#include "ssh.h"

/* Returns true if the given string matches the pattern (which may contain
   ? and * as wildcards), and zero if it does not match. */

int 
match_pattern(const char *s, const char *pattern)
{
	for (;;) {
		/* If at end of pattern, accept if also at end of string. */
		if (!*pattern)
			return !*s;

		/* Process '*'. */
		if (*pattern == '*') {
			/* Skip the asterisk. */
			pattern++;

			/* If at end of pattern, accept immediately. */
			if (!*pattern)
				return 1;

			/* If next character in pattern is known, optimize. */
			if (*pattern != '?' && *pattern != '*') {
				/* Look instances of the next character in
				   pattern, and try to match starting from
				   those. */
				for (; *s; s++)
					if (*s == *pattern &&
					    match_pattern(s + 1, pattern + 1))
						return 1;
				/* Failed. */
				return 0;
			}
			/* Move ahead one character at a time and try to
			   match at each position. */
			for (; *s; s++)
				if (match_pattern(s, pattern))
					return 1;
			/* Failed. */
			return 0;
		}
		/* There must be at least one more character in the
		   string.  If we are at the end, fail. */
		if (!*s)
			return 0;

		/* Check if the next character of the string is
		   acceptable. */
		if (*pattern != '?' && *pattern != *s)
			return 0;

		/* Move to the next character, both in string and in
		   pattern. */
		s++;
		pattern++;
	}
	/* NOTREACHED */
}