示例#1
0
文件: pathspec.c 项目: lznuaa/libgit2
/* build a vector of fnmatch patterns to evaluate efficiently */
int git_pathspec_init(
	git_vector *vspec, const git_strarray *strspec, git_pool *strpool)
{
	size_t i;

	memset(vspec, 0, sizeof(*vspec));

	if (!git_pathspec_is_interesting(strspec))
		return 0;

	if (git_vector_init(vspec, strspec->count, NULL) < 0)
		return -1;

	for (i = 0; i < strspec->count; ++i) {
		int ret;
		const char *pattern = strspec->strings[i];
		git_attr_fnmatch *match = git__calloc(1, sizeof(git_attr_fnmatch));
		if (!match)
			return -1;

		match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE;

		ret = git_attr_fnmatch__parse(match, strpool, NULL, &pattern);
		if (ret == GIT_ENOTFOUND) {
			git__free(match);
			continue;
		} else if (ret < 0)
			return ret;

		if (git_vector_insert(vspec, match) < 0)
			return -1;
	}

	return 0;
}
示例#2
0
int git_attr_file__parse_buffer(
	git_repository *repo, const char *buffer, git_attr_file *attrs)
{
	int error = 0;
	const char *scan = NULL;
	char *context = NULL;
	git_attr_rule *rule = NULL;

	assert(buffer && attrs);

	scan = buffer;

	/* if subdir file path, convert context for file paths */
	if (attrs->key && git__suffixcmp(attrs->key, "/" GIT_ATTR_FILE) == 0) {
		context = attrs->key + 2;
		context[strlen(context) - strlen(GIT_ATTR_FILE)] = '\0';
	}

	while (!error && *scan) {
		/* allocate rule if needed */
		if (!rule && !(rule = git__calloc(1, sizeof(git_attr_rule)))) {
			error = -1;
			break;
		}

		/* parse the next "pattern attr attr attr" line */
		if (!(error = git_attr_fnmatch__parse(
				&rule->match, attrs->pool, context, &scan)) &&
			!(error = git_attr_assignment__parse(
				repo, attrs->pool, &rule->assigns, &scan)))
		{
			if (rule->match.flags & GIT_ATTR_FNMATCH_MACRO)
				/* should generate error/warning if this is coming from any
				 * file other than .gitattributes at repo root.
				 */
				error = git_attr_cache__insert_macro(repo, rule);
			else
				error = git_vector_insert(&attrs->rules, rule);
		}

		/* if the rule wasn't a pattern, on to the next */
		if (error < 0) {
			git_attr_rule__clear(rule); /* reset rule contents */
			if (error == GIT_ENOTFOUND)
				error = 0;
		} else {
			rule = NULL; /* vector now "owns" the rule */
		}
	}

	git_attr_rule__free(rule);

	/* restore file path used for context */
	if (context)
		context[strlen(context)] = '.'; /* first char of GIT_ATTR_FILE */

	return error;
}
示例#3
0
int git_attr_file__parse_buffer(
	git_repository *repo, git_attr_file *attrs, const char *data)
{
	int error = 0;
	const char *scan = data, *context = NULL;
	git_attr_rule *rule = NULL;

	/* if subdir file path, convert context for file paths */
	if (attrs->entry &&
		git_path_root(attrs->entry->path) < 0 &&
		!git__suffixcmp(attrs->entry->path, "/" GIT_ATTR_FILE))
		context = attrs->entry->path;

	if (git_mutex_lock(&attrs->lock) < 0) {
		giterr_set(GITERR_OS, "Failed to lock attribute file");
		return -1;
	}

	while (!error && *scan) {
		/* allocate rule if needed */
		if (!rule && !(rule = git__calloc(1, sizeof(*rule)))) {
			error = -1;
			break;
		}

		rule->match.flags =
			GIT_ATTR_FNMATCH_ALLOWNEG | GIT_ATTR_FNMATCH_ALLOWMACRO;

		/* parse the next "pattern attr attr attr" line */
		if (!(error = git_attr_fnmatch__parse(
				&rule->match, &attrs->pool, context, &scan)) &&
			!(error = git_attr_assignment__parse(
				repo, &attrs->pool, &rule->assigns, &scan)))
		{
			if (rule->match.flags & GIT_ATTR_FNMATCH_MACRO)
				/* TODO: warning if macro found in file below repo root */
				error = git_attr_cache__insert_macro(repo, rule);
			else
				error = git_vector_insert(&attrs->rules, rule);
		}

		/* if the rule wasn't a pattern, on to the next */
		if (error < 0) {
			git_attr_rule__clear(rule); /* reset rule contents */
			if (error == GIT_ENOTFOUND)
				error = 0;
		} else {
			rule = NULL; /* vector now "owns" the rule */
		}
	}

	git_mutex_unlock(&attrs->lock);
	git_attr_rule__free(rule);

	return error;
}