Ejemplo n.º 1
0
char *cclenter(const char *argp)	/* add a character class */
{
	int i, c, c2;
	int j;
	uschar *p = (uschar *) argp;
	uschar *op, *bp;
	static uschar *buf = 0;
	static int bufsz = 100;

	op = p;
	if (buf == 0 && (buf = (uschar *) malloc(bufsz)) == NULL)
		FATAL("out of space for character class [%.10s...] 1", p);
	bp = buf;
	for (i = 0; (c = *p++) != 0; ) {
		if (c == '\\') {
			c = quoted(&p);
		} else if (c == '-' && i > 0 && bp[-1] != 0) {
			if (*p != 0) {
				c = bp[-1];
				c2 = *p++;
				if (c2 == '\\')
					c2 = quoted(&p);
				if (collate_range_cmp(c, c2) > 0) {
					bp--;
					i--;
					continue;
				}
				for (j = 0; j < NCHARS; j++) {
					if ((collate_range_cmp(c, j) > 0) ||
					    collate_range_cmp(j, c2) > 0)
						continue;
					if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1"))
						FATAL("out of space for character class [%.10s...] 2", p);
					*bp++ = j;
					i++;
				}
				continue;
			}
		}
		if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter2"))
			FATAL("out of space for character class [%.10s...] 3", p);
		*bp++ = c;
		i++;
	}
	*bp = 0;
	dprintf( ("cclenter: in = |%s|, out = |%s|\n", op, buf) );
	xfree(op);
	return (char *) tostring((char *) buf);
}
Ejemplo n.º 2
0
static int
patmatch(const char *pattern, const char *string, int squoted)
{
	const char *p, *q, *end;
	const char *bt_p, *bt_q;
	char c;
	wchar_t wc, wc2;

	p = pattern;
	q = string;
	bt_p = NULL;
	bt_q = NULL;
	for (;;) {
		switch (c = *p++) {
		case '\0':
			if (*q != '\0')
				goto backtrack;
			return 1;
		case CTLESC:
			if (squoted && *q == CTLESC)
				q++;
			if (*q++ != *p++)
				goto backtrack;
			break;
		case CTLQUOTEMARK:
			continue;
		case '?':
			if (squoted && *q == CTLESC)
				q++;
			if (*q == '\0')
				return 0;
			if (localeisutf8) {
				wc = get_wc(&q);
				/*
				 * A '?' does not match invalid UTF-8 but a
				 * '*' does, so backtrack.
				 */
				if (wc == 0)
					goto backtrack;
			} else
				wc = (unsigned char)*q++;
			break;
		case '*':
			c = *p;
			while (c == CTLQUOTEMARK || c == '*')
				c = *++p;
			/*
			 * If the pattern ends here, we know the string
			 * matches without needing to look at the rest of it.
			 */
			if (c == '\0')
				return 1;
			/*
			 * First try the shortest match for the '*' that
			 * could work. We can forget any earlier '*' since
			 * there is no way having it match more characters
			 * can help us, given that we are already here.
			 */
			bt_p = p;
			bt_q = q;
			break;
		case '[': {
			const char *endp;
			int invert, found;
			wchar_t chr;

			endp = p;
			if (*endp == '!' || *endp == '^')
				endp++;
			do {
				while (*endp == CTLQUOTEMARK)
					endp++;
				if (*endp == 0)
					goto dft;		/* no matching ] */
				if (*endp == CTLESC)
					endp++;
			} while (*++endp != ']');
			invert = 0;
			if (*p == '!' || *p == '^') {
				invert++;
				p++;
			}
			found = 0;
			if (squoted && *q == CTLESC)
				q++;
			if (*q == '\0')
				return 0;
			if (localeisutf8) {
				chr = get_wc(&q);
				if (chr == 0)
					goto backtrack;
			} else
				chr = (unsigned char)*q++;
			c = *p++;
			do {
				if (c == CTLQUOTEMARK)
					continue;
				if (c == '[' && *p == ':') {
					found |= match_charclass(p, chr, &end);
					if (end != NULL)
						p = end;
				}
				if (c == CTLESC)
					c = *p++;
				if (localeisutf8 && c & 0x80) {
					p--;
					wc = get_wc(&p);
					if (wc == 0) /* bad utf-8 */
						return 0;
				} else
					wc = (unsigned char)c;
				if (*p == '-' && p[1] != ']') {
					p++;
					while (*p == CTLQUOTEMARK)
						p++;
					if (*p == CTLESC)
						p++;
					if (localeisutf8) {
						wc2 = get_wc(&p);
						if (wc2 == 0) /* bad utf-8 */
							return 0;
					} else
						wc2 = (unsigned char)*p++;
					if (   collate_range_cmp(chr, wc) >= 0
					    && collate_range_cmp(chr, wc2) <= 0
					   )
						found = 1;
				} else {
					if (chr == wc)
						found = 1;
				}
			} while ((c = *p++) != ']');
			if (found == invert)
				goto backtrack;
			break;
		}
dft:	        default:
			if (squoted && *q == CTLESC)
				q++;
			if (*q == '\0')
				return 0;
			if (*q++ == c)
				break;
backtrack:
			/*
			 * If we have a mismatch (other than hitting the end
			 * of the string), go back to the last '*' seen and
			 * have it match one additional character.
			 */
			if (bt_p == NULL)
				return 0;
			if (squoted && *bt_q == CTLESC)
				bt_q++;
			if (*bt_q == '\0')
				return 0;
			bt_q++;
			p = bt_p;
			q = bt_q;
			break;
		}
	}
}
Ejemplo n.º 3
0
int CMacFindFile::pmatch(const char* pattern, const char* string)
{
    const char *p, *q;
    char c;

    p = pattern;
    q = string;
    for (;;) {
	switch (c = *p++) {
	case '\0':
	    goto breakloop;
	case '?':
	    if (*q++ == '\0')
		return 0;
	break;
	case '*':
	    c = *p;
	    if (c != '?' && c != '*' && c != '[') {
		while (*q != c) {
		    if (*q == '\0')
			return 0;
		    q++;
		}
	    }
	    do {
		if (pmatch(p, q))
		    return 1;
	    } while (*q++ != '\0');
	return 0;
	case '[': {
		const char *endp;
		int invert, found;
		char chr;

		endp = p;
		if (*endp == '!')
			endp++;
		for (;;) {
			if (*endp == '\0')
				goto dft;		/* no matching ] */
			if (*++endp == ']')
				break;
		}
		invert = 0;
		if (*p == '!') {
			invert++;
			p++;
		}
		found = 0;
		chr = *q++;
		if (chr == '\0')
			return 0;
		c = *p++;
		do {
		    if (*p == '-' && p[1] != ']') {
			p++;
#if 0
			if (   collate_range_cmp(chr, c) >= 0
			    && collate_range_cmp(chr, *p) <= 0
			   )
			    found = 1;
#endif
			p++;
		    } else {
			if (chr == c)
			    found = 1;
		    }
		} while ((c = *p++) != ']');
		if (found == invert)
		    return 0;
		break;
	    }
	    dft:
	    default:
		if (*q++ != c)
		    return 0;
	    break;
	}
    }
breakloop:
    if (*q != '\0')
	return 0;
    return 1;
}
Ejemplo n.º 4
0
STATIC int
pmatch(char *pattern, char *string, int squoted)
{
	char *p, *q;
	char c;

	p = pattern;
	q = string;
	for (;;) {
		switch (c = *p++) {
		case '\0':
			goto breakloop;
		case CTLESC:
			if (squoted && *q == CTLESC)
				q++;
			if (*q++ != *p++)
				return 0;
			break;
		case CTLQUOTEMARK:
			continue;
		case '?':
			if (squoted && *q == CTLESC)
				q++;
			if (*q++ == '\0')
				return 0;
			break;
		case '*':
			c = *p;
			while (c == CTLQUOTEMARK || c == '*')
				c = *++p;
			if (c != CTLESC &&  c != CTLQUOTEMARK &&
			    c != '?' && c != '*' && c != '[') {
				while (*q != c) {
					if (squoted && *q == CTLESC &&
					    q[1] == c)
						break;
					if (*q == '\0')
						return 0;
					if (squoted && *q == CTLESC)
						q++;
					q++;
				}
			}
			do {
				if (pmatch(p, q, squoted))
					return 1;
				if (squoted && *q == CTLESC)
					q++;
			} while (*q++ != '\0');
			return 0;
		case '[': {
			char *endp;
			int invert, found;
			char chr;

			endp = p;
			if (*endp == '!' || *endp == '^')
				endp++;
			for (;;) {
				while (*endp == CTLQUOTEMARK)
					endp++;
				if (*endp == '\0')
					goto dft;		/* no matching ] */
				if (*endp == CTLESC)
					endp++;
				if (*++endp == ']')
					break;
			}
			invert = 0;
			if (*p == '!' || *p == '^') {
				invert++;
				p++;
			}
			found = 0;
			chr = *q++;
			if (squoted && chr == CTLESC)
				chr = *q++;
			if (chr == '\0')
				return 0;
			c = *p++;
			do {
				if (c == CTLQUOTEMARK)
					continue;
				if (c == CTLESC)
					c = *p++;
				if (*p == '-' && p[1] != ']') {
					p++;
					while (*p == CTLQUOTEMARK)
						p++;
					if (*p == CTLESC)
						p++;
					if (   collate_range_cmp(chr, c) >= 0
					    && collate_range_cmp(chr, *p) <= 0
					   )
						found = 1;
					p++;
				} else {
					if (chr == c)
						found = 1;
				}
			} while ((c = *p++) != ']');
			if (found == invert)
				return 0;
			break;
		}
dft:	        default:
			if (squoted && *q == CTLESC)
				q++;
			if (*q++ != c)
				return 0;
			break;
		}
	}
breakloop:
	if (*q != '\0')
		return 0;
	return 1;
}