Example #1
0
File: misc.c Project: adtools/abcsh
int
gmatch(const char *s, const char *p, int isfile)
{
        const char *se, *pe;

        if (s == NULL || p == NULL)
                return 0;
        se = s + strlen(s);
        pe = p + strlen(p);
        /* isfile is false iff no syntax check has been done on
         * the pattern.  If check fails, just to a strcmp().
         */
        if (!isfile && !has_globbing(p, pe)) {
                int len = pe - p + 1;
                char tbuf[64];
                char *t = len <= sizeof(tbuf) ? tbuf :
                        (char *) alloc(len, ATEMP);
                debunk(t, p, len);
                return !strcmp(t, s);
        }
        return do_gmatch((const unsigned char *) s, (const unsigned char *) se,
                         (const unsigned char *) p, (const unsigned char *) pe);
}
Example #2
0
/*
 * int gmatch(string, pattern)
 * char *string, *pattern;
 *
 * Match a pattern as in sh(1).
 * pattern character are prefixed with MAGIC by expand.
 */
int
gmatchx(const char *s, const char *p, bool isfile)
{
	const char *se, *pe;
	char *pnew;
	int rv;

	if (s == NULL || p == NULL)
		return (0);

	se = s + strlen(s);
	pe = p + strlen(p);
	/*
	 * isfile is false iff no syntax check has been done on
	 * the pattern. If check fails, just to a strcmp().
	 */
	if (!isfile && !has_globbing(p, pe)) {
		size_t len = pe - p + 1;
		char tbuf[64];
		char *t = len <= sizeof(tbuf) ? tbuf : alloc(len, ATEMP);
		debunk(t, p, len);
		return (!strcmp(t, s));
	}

	/*
	 * since the do_gmatch() engine sucks so much, we must do some
	 * pattern simplifications
	 */
	pnew = simplify_gmatch_pattern((const unsigned char *)p);
	pe = pnew + strlen(pnew);

	rv = do_gmatch((const unsigned char *)s, (const unsigned char *)se,
	    (const unsigned char *)pnew, (const unsigned char *)pe);
	afree(pnew, ATEMP);
	return (rv);
}
Example #3
0
File: misc.c Project: adtools/abcsh
/* Function must return either 0 or 1 (assumed by code for 0x80|'!') */
static int
do_gmatch(const unsigned char *s, const unsigned char *se,
        const unsigned char *p, const unsigned char *pe)
{
        int sc, pc;
        const unsigned char *prest, *psub, *pnext;
        const unsigned char *srest;

        if (s == NULL || p == NULL)
                return 0;
        while (p < pe) {
                pc = *p++;
                sc = s < se ? *s : '\0';
                s++;
                if (!ISMAGIC(pc)) {
                        if (sc != pc)
                                return 0;
                        continue;
                }
                switch (*p++) {
                  case '[':
                        if (sc == 0 || (p = cclass(p, sc)) == NULL)
                                return 0;
                        break;

                  case '?':
                        if (sc == 0)
                                return 0;
                        break;

                  case '*':
                        if (p == pe)
                                return 1;
                        s--;
                        do {
                                if (do_gmatch(s, se, p, pe))
                                        return 1;
                        } while (s++ < se);
                        return 0;

                  /*
                   * [*+?@!](pattern|pattern|..)
                   *
                   * Not ifdef'd KSH as this is needed for ${..%..}, etc.
                   */
                  case 0x80|'+': /* matches one or more times */
                  case 0x80|'*': /* matches zero or more times */
                        if (!(prest = pat_scan(p, pe, 0)))
                                return 0;
                        s--;
                        /* take care of zero matches */
                        if (p[-1] == (0x80 | '*') &&
                                do_gmatch(s, se, prest, pe))
                                return 1;
                        for (psub = p; ; psub = pnext) {
                                pnext = pat_scan(psub, pe, 1);
                                for (srest = s; srest <= se; srest++) {
                                        if (do_gmatch(s, srest, psub, pnext - 2) &&
                                                (do_gmatch(srest, se, prest, pe) ||
                                                (s != srest && do_gmatch(srest,
                                                        se, p - 2, pe))))
                                                return 1;
                                }
                                if (pnext == prest)
                                        break;
                        }
                        return 0;

                  case 0x80|'?': /* matches zero or once */
                  case 0x80|'@': /* matches one of the patterns */
                  case 0x80|' ': /* simile for @ */
                        if (!(prest = pat_scan(p, pe, 0)))
                                return 0;
                        s--;
                        /* Take care of zero matches */
                        if (p[-1] == (0x80 | '?') &&
                                do_gmatch(s, se, prest, pe))
                                return 1;
                        for (psub = p; ; psub = pnext) {
                                pnext = pat_scan(psub, pe, 1);
                                srest = prest == pe ? se : s;
                                for (; srest <= se; srest++) {
                                        if (do_gmatch(s, srest, psub, pnext - 2) &&
                                                do_gmatch(srest, se, prest, pe))
                                                return 1;
                                }
                                if (pnext == prest)
                                        break;
                        }
                        return 0;

                  case 0x80|'!': /* matches none of the patterns */
                        if (!(prest = pat_scan(p, pe, 0)))
                                return 0;
                        s--;
                        for (srest = s; srest <= se; srest++) {
                                int matched = 0;

                                for (psub = p; ; psub = pnext) {
                                        pnext = pat_scan(psub, pe, 1);
                                        if (do_gmatch(s, srest, psub,
                                                pnext - 2))
                                        {
                                                matched = 1;
                                                break;
                                        }
                                        if (pnext == prest)
                                                break;
                                }
                                if (!matched &&
                                        do_gmatch(srest, se, prest, pe))
                                                return 1;
                        }
                        return 0;

                  default:
                        if (sc != p[-1])
                                return 0;
                        break;
                }
        }
        return s == se;
}