Ejemplo n.º 1
0
END_TEST

START_TEST(test_dm_match)
{
	int i;
	char *candidate = "MyName is SAMMY @ and I am a SLUG!";
	char *badpatterns[] = {
		"hello", "*hello", "*hello*", "hello*",
		"*hello", "*hello*", "hello*", "?", NULL };
	char *goodpatterns[] = {
		"*", "*and*", "*SLUG!", "My*", "????My*",
		"MyName ?? *", "??Name*", "*SLUG?", NULL };

	for (i = 0; badpatterns[i] != NULL; i++) {
		fail_unless(match_glob(badpatterns[i], candidate)
			== NULL, "test_dm_match failed on a bad pattern:"
			" [%s]", badpatterns[i]);
	}

	for (i = 0; goodpatterns[i] != NULL; i++) {
		fail_unless(match_glob(goodpatterns[i], candidate)
			== candidate, "test_dm_match failed on a good pattern:"
			" [%s]", goodpatterns[i]);
	}

}
Ejemplo n.º 2
0
bool match_glob(const char* name, const char* pattern)
{
    while (*pattern != '\0') {
        if (*pattern == '*') {
            if (pattern[1] == '\0')
                return true;
            const char *here = name;
            while (*name != '\0')
                ++name;
            while (name != here) {
                if (match_glob(name, pattern))
                    return true;
                --name;
            }
        }
        else {
            if (*name != *pattern)
                return false;
            ++name;
        }
        ++pattern;
    }
    // if we are here (*pattern == '\0')
    return *name == '\0';
}
Ejemplo n.º 3
0
/*
 * Match $str against an extended glob $pattern, like:
 * "alpha:be(t:l)a:g*a:d???a:ep(x(xx:yy)y:z*z)silon:sig(ma:)",
 * where parenthesis denote grouping and colons delimit alternatives.
 *
 * This implementation was found at least as fast as mainstream
 * library routines while being way smarter.  The slightly less
 * flexible match_glob() "backend" beat them all, to death.
 * (These results are all for non-overcomplicated patterns
 * like "libg*2.0.*" which don't require too much backtracking.)
 *
 * match_glob():		   7.748s
 * match_eglob():		  18.083s
 * fnmatch():			  17.928s
 * g_pattern_match_string():	  16.391s
 * g_pattern_match_simple():	1:22.820s
 */
static int match_eglob(char const *pattern, char const *str)
{
	do
		if (match_glob(pattern, str))
			return 1;
	while ((pattern = find_end_of_glob(pattern, ':')) != NULL);
	return 0;
} /* match_eglob */
Ejemplo n.º 4
0
/* Like match_eglob(), but doesn't support top-level alterations. */
static int match_glob(char const *pattern, char const *str)
{
	 /* The very basic idea is due to BWK from the Beautiful Code. */
	for (;;)
	{
		switch (*pattern)
		{
		case '(':
			/* Let match_eglob() sort it out. */
			pattern++;
			return match_eglob(pattern, str);
		case ')':
			/* Like below. */
			pattern++;
			break;
		case ':':
			/* An alternative matched, continue right after
			 * the alteration. */
			if ((pattern = find_end_of_glob(pattern, ')')) != NULL)
				break;
		case '\0':
			return !*str;

		case '*':
			/* Try to ignore more and more characters of $str
			 * until we're out of them. */
			pattern++;
			do
				if (match_glob(pattern, str))
					return 1;
			while (*str++);
			return 0;

		case '?':
			if (!*str++)
				return 0;
			pattern++;
			break;
		default:
			if (*str++ != *pattern++)
				return 0;
			break;
		} /* switch */
	} /* for */
} /* match_glob */
Ejemplo n.º 5
0
int
pkg_info(struct pkg_info info)
{
	unsigned int cur;
	int retval;
	struct pkg **pkgs;

	retval = 1;
	pkgs = NULL;

	/* -e package name */
	if (info.check_package != NULL) {
		struct pkg *pkg;
		pkg = pkg_db_get_package(info.db, info.check_package);
		if (pkg != NULL) {
			pkg_free(pkg);
			return 0;
		}
		return 1;
	}

	/* -W <filename> */
	if (info.search_file != NULL) {
		struct stat sb;

		if (stat(info.search_file, &sb) != 0) {
			/* XXX */
			return 1;
		}
		pkgs = pkg_db_get_installed_match_count(info.db,
		    pkg_match_by_file, 1, (const void *)info.search_file);
		if (info.quiet == 0)
			printf("The following installed package(s) has %s "
			    "origin:\n", info.origin);
		printf("%s\n", pkg_get_name(pkgs[0]));
		return 0;
	}

	/* -O <origin> */
	if (info.origin != NULL) {
		unsigned int pos;
		pkgs = pkg_db_get_installed_match(info.db, pkg_match_by_origin,
		    (const void *)info.origin);
		if (info.quiet == 0)
			printf("The following installed package(s) has %s "
			    "origin:\n", info.origin);
		for (pos = 0; pkgs[pos] != NULL; pos++) {
			printf("%s\n", pkg_get_name(pkgs[pos]));
		}
		return 0;
	}
	
	switch(info.match_type) {
	case MATCH_ALL:
	case MATCH_GLOB:
	case MATCH_NGLOB:
	case MATCH_REGEX:
	case MATCH_EREGEX:
		/* Display all packages installed */
		if (info.match_type == MATCH_ALL)
			pkgs = pkg_db_get_installed(info.db);
		else if (info.match_type == MATCH_REGEX ||
		         info.match_type == MATCH_EREGEX)
			pkgs = match_regex(info.db, (const char**)info.pkgs,
			    (info.match_type == MATCH_EREGEX));
		else if (info.match_type == MATCH_GLOB ||
		         info.match_type == MATCH_NGLOB)
			pkgs = match_glob(info.db, (const char**)info.pkgs,
			    (info.match_type == MATCH_GLOB));
		else
			errx(1, "ERROR: Inconsistancy in pkg_info");

		/* Sort the packages and display them */
		if (pkgs == NULL) {
			/* XXX Error message */
			return 1;
		}
		for (cur = 0; pkgs[cur] != NULL; cur++)
			continue;
		qsort(pkgs, cur, sizeof(struct pkg *), pkg_compare);
		for (cur = 0; pkgs[cur] != NULL; cur++) {
			show(info.db, pkgs[cur], info.flags, info.quiet,
			    info.seperator, info.use_blocksize);
		}
		retval = 0;
		break;
	case MATCH_EXACT:
		/* Only match the exact names given */
		retval = 0;
		
		for (cur = 0; info.pkgs[cur] != NULL; cur++) {
			struct pkg *pkg;

			pkg = pkg_db_get_package(info.db, info.pkgs[cur]);
			if (pkg != NULL)
				show(info.db, pkg, info.flags, info.quiet,
				    info.seperator, info.use_blocksize);
			else {
				warnx("pkg_info: can't find package '%s' "
				    "installed or in a file!", info.pkgs[cur]);
				retval = 1;
			}
		}
		break;
	}
	if (pkgs != NULL)
		pkg_list_free(pkgs);
	return retval;
}
Ejemplo n.º 6
0
static gboolean
test_match_glob(void)
{
    gboolean ok = TRUE;
    struct {
	char *expr, *str;
	gboolean should_match;
    } tests[] = {
	/* literal, unanchored matching */
	{ "a", "a", TRUE },

	{ "abc", "abc", TRUE },
	{ "abc", "abcd", FALSE },
	{ "abc", "dabc", FALSE },
	{ "abc", "/usr/bin/abc", FALSE },

	{ "*.txt", "foo.txt", TRUE },
	{ "*.txt", ".txt", TRUE },
	{ "*.txt", "txt", FALSE },

	{ "?.txt", "X.txt", TRUE },
	{ "?.txt", ".txt", FALSE },
	{ "?.txt", "XY.txt", FALSE },

	{ "?*.txt", ".txt", FALSE },
	{ "?*.txt", "a.txt", TRUE },
	{ "?*.txt", "aa.txt", TRUE },
	{ "?*.txt", "aaa.txt", TRUE },

	{ "foo.[tT][xX][tT]", "foo.txt", TRUE },
	{ "foo.[tT][xX][tT]", "foo.TXt", TRUE },
	{ "foo.[tT][xX][tT]", "foo.TXT", TRUE },
	{ "foo.[tT][xX][tT]", "foo.TaT", FALSE },

	{ "foo.[tT][!yY][tT]", "foo.TXt", TRUE },
	{ "foo.[tT][!yY][tT]", "foo.TXT", TRUE },
	{ "foo.[tT][!yY][tT]", "foo.TyT", FALSE },

	{ "foo\\\\", "foo", FALSE },
	{ "foo\\\\", "foo\\", TRUE },
	{ "foo\\\\", "foo\\\\", FALSE },

	{ "(){}+.^$|", "(){}+.^$|", TRUE },

	{ "/usr/bin/*", "/usr/bin/tar", TRUE },
	{ "/usr/bin/*", "/usr/bin/local/tar", FALSE },
	{ "/usr/bin/*", "/usr/sbin/tar", FALSE },
	{ "/usr/bin/*", "/opt/usr/bin/tar", FALSE },

	{ "/usr?bin", "/usr/bin", FALSE },
	{ "/usr*bin", "/usr/bin", FALSE },

	{ NULL, NULL, FALSE },
    }, *t;

    for (t = tests; t->expr; t++) {
	gboolean matched = match_glob(t->expr, t->str);
	if (!!matched != !!t->should_match) {
	    ok = FALSE;
	    if (t->should_match) {
		g_fprintf(stderr, "%s should have matched glob %s\n",
			t->str, t->expr);
	    } else {
		g_fprintf(stderr, "%s unexpectedly matched glob %s\n",
			t->str, t->expr);
	    }
	}
    }

    return ok;
}