Ejemplo n.º 1
0
static List *extractsinglematch(const char *subject, const char *pattern,
				const char *quoting, List *result) {
	int i;
	const char *s;

	if (!haswild(pattern, quoting) /* no wildcards, so no matches */
	    || !match(subject, pattern, quoting))
		return NULL;

	for (s = subject, i = 0; pattern[i] != '\0'; s++) {
		if (ISQUOTED(quoting, i))
			i++;
		else {
			int c = pattern[i++];
			switch (c) {
			    case '*': {
				const char *begin;
				if (pattern[i] == '\0')
					return mklist(mkstr(gcdup(s)), result);
				for (begin = s;; s++) {
					const char *q = TAILQUOTE(quoting, i);
					assert(*s != '\0');
					if (match(s, pattern + i, q)) {
						result = mklist(mkstr(gcndup(begin, s - begin)), result);
						return haswild(pattern + i, q)
							? extractsinglematch(s, pattern + i, q, result)
							: result;
					}
				}
			    }
			    case '[': {
				int j = rangematch(pattern + i, TAILQUOTE(quoting, i), *s);
				assert(j != RANGE_FAIL);
				if (j == RANGE_ERROR) {
					assert(*s == '[');
					break;
				}
				i += j;
			    }
			    /* FALLTHROUGH */
			    case '?':
				result = mklist(mkstr(str("%c", *s)), result);
				break;
			    default:
				break;
			}
		}
	}

	return result;
}
Ejemplo n.º 2
0
/* match -- match a single pattern against a single string. */
extern Boolean match(const char *s, const char *p, const char *q) {
	int i;
	if (q == QUOTED)
		return streq(s, p);
	for (i = 0;;) {
		int c = p[i++];
		if (c == '\0')
			return *s == '\0';
		else if (q == UNQUOTED || q[i - 1] == 'r') {
			switch (c) {
			case '?':
				if (*s++ == '\0')
					return FALSE;
				break;
			case '*':
				while (p[i] == '*' && (q == UNQUOTED || q[i] == 'r'))	/* collapse multiple stars */
					i++;
				if (p[i] == '\0') 	/* star at end of pattern? */
					return TRUE;
				while (*s != '\0')
					if (match(s++, p + i, TAILQUOTE(q, i)))
						return TRUE;
				return FALSE;
			case '[': {
				int j;
				if (*s == '\0')
					return FALSE;
				switch (j = rangematch(p + i, TAILQUOTE(q, i), *s)) {
				default:
					i += j;
					break;
				case RANGE_FAIL:
					return FALSE;
				case RANGE_ERROR:
					if (*s != '[')
						return FALSE;
				}
				s++;
				break;
			}
			default:
				if (c != *s++)
					return FALSE;
			}
		} else if (c != *s++)
			return FALSE;
	}
}