コード例 #1
0
/*
 * pattern matching function for filenames.  Each occurrence of the *
 * pattern causes a recursion level.
 */
static  int
match(const char *name, const Char *pat, const Char *patend, int m_not)
{
    int ok, negate_range;
    Char c;

    while (pat < patend) {
	size_t lwk;
	__Char wc, wk;

	c = *pat; /* Only for M_MASK bits */
	pat += One_Char_mbtowc(&wc, pat, MB_LEN_MAX);
	lwk = one_mbtowc(&wk, name, MB_LEN_MAX);
	switch (c & M_MASK) {
	case M_ALL:
	    while (pat < patend && (*pat & M_MASK) == M_ALL)  /* eat consecutive '*' */
		pat += One_Char_mbtowc(&wc, pat, MB_LEN_MAX);
	    if (pat == patend)
	        return (1);
	    while (!match(name, pat, patend, m_not)) {
		if (*name == EOS)
		    return (0);
		name += lwk;
		lwk = one_mbtowc(&wk, name, MB_LEN_MAX);
	    }
	    return (1);
	case M_ONE:
	    if (*name == EOS)
		return (0);
	    name += lwk;
	    break;
	case M_SET:
	    ok = 0;
	    if (*name == EOS)
		return (0);
	    name += lwk;
	    if ((negate_range = ((*pat & M_MASK) == m_not)) != 0)
		++pat;
	    while ((*pat & M_MASK) != M_END) {
		pat += One_Char_mbtowc(&wc, pat, MB_LEN_MAX);
		if ((*pat & M_MASK) == M_RNG) {
		    __Char wc2;

		    pat++;
		    pat += One_Char_mbtowc(&wc2, pat, MB_LEN_MAX);
		    if (globcharcoll(wc, wk, 0) <= 0 &&
			globcharcoll(wk, wc2, 0) <= 0)
			ok = 1;
		} else if (wc == wk)
		    ok = 1;
	    }
	    pat += One_Char_mbtowc(&wc, pat, MB_LEN_MAX);
	    if (ok == negate_range)
		return (0);
	    break;
	default:
	    if (*name == EOS || samecase(wk) != samecase(wc))
		return (0);
	    name += lwk;
	    break;
	}
    }
    return (*name == EOS);
}
コード例 #2
0
ファイル: sh.glob.c プロジェクト: 2014-class/freerouter
/* t_pmatch():
 *	Return 2 on exact match, 	
 *	Return 1 on substring match.
 *	Return 0 on no match.
 *	*estr will point to the end of the longest exact or substring match.
 */
int
t_pmatch(const Char *string, const Char *pattern, const Char **estr, int cs)
{
    Char stringc, patternc, rangec;
    int     match, negate_range;
    const Char *pestr, *nstring;

    for (nstring = string;; string = nstring) {
	stringc = *nstring++ & TRIM;
	patternc = *pattern++ & TRIM;
	switch (patternc) {
	case '\0':
	    *estr = string;
	    return (stringc == '\0' ? 2 : 1);
	case '?':
	    if (stringc == 0)
		return (0);
	    break;
	case '*':
	    if (!*pattern) {
		*estr = Strend(string);
		return (2);
	    }
	    pestr = NULL;

	    for (;;) {
		switch(t_pmatch(string, pattern, estr, cs)) {
		case 0:
		    break;
		case 1:
		    pestr = *estr;/*FIXME: does not guarantee longest match */
		    break;
		case 2:
		    return 2;
		default:
		    abort();	/* Cannot happen */
		}
		stringc = *string++ & TRIM;
		if (!stringc)
		    break;
	    }

	    if (pestr) {
		*estr = pestr;
		return 1;
	    }
	    else
		return 0;

	case '[':
	    match = 0;
	    if ((negate_range = (*pattern == '^')) != 0)
		pattern++;
	    while ((rangec = *pattern++ & TRIM) != '\0') {
		if (rangec == ']')
		    break;
		if (match)
		    continue;
		if (*pattern == '-' && pattern[1] != ']') {
		    Char rangec2;
		    pattern++;
		    rangec2 = *pattern++ & TRIM;
		    match = (globcharcoll(stringc, rangec2, 0) <= 0 &&
			globcharcoll(rangec, stringc, 0) <= 0);
		}
		else 
		    match = (stringc == rangec);
	    }
	    if (rangec == '\0')
		stderror(ERR_NAME | ERR_MISSING, ']');
	    if ((!match) && (stringc == '\0'))
		return (0);
	    if (match == negate_range)
		return (0);
	    break;
	default:
	    if (cs ? patternc  != stringc
		: Tolower(patternc) != Tolower(stringc))
		return (0);
	    break;
	}
    }
}