Blame examples/common.c

Packit Service 20376f
/*
Packit Service 20376f
 * Utilities library for libgit2 examples
Packit Service 20376f
 *
Packit Service 20376f
 * Written by the libgit2 contributors
Packit Service 20376f
 *
Packit Service 20376f
 * To the extent possible under law, the author(s) have dedicated all copyright
Packit Service 20376f
 * and related and neighboring rights to this software to the public domain
Packit Service 20376f
 * worldwide. This software is distributed without any warranty.
Packit Service 20376f
 *
Packit Service 20376f
 * You should have received a copy of the CC0 Public Domain Dedication along
Packit Service 20376f
 * with this software. If not, see
Packit Service 20376f
 * <http://creativecommons.org/publicdomain/zero/1.0/>.
Packit Service 20376f
 */
Packit Service 20376f
Packit Service 20376f
#include "common.h"
Packit Service 20376f
Packit Service 20376f
void check_lg2(int error, const char *message, const char *extra)
Packit Service 20376f
{
Packit Service 20376f
	const git_error *lg2err;
Packit Service 20376f
	const char *lg2msg = "", *lg2spacer = "";
Packit Service 20376f
Packit Service 20376f
	if (!error)
Packit Service 20376f
		return;
Packit Service 20376f
Packit Service 20376f
	if ((lg2err = giterr_last()) != NULL && lg2err->message != NULL) {
Packit Service 20376f
		lg2msg = lg2err->message;
Packit Service 20376f
		lg2spacer = " - ";
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	if (extra)
Packit Service 20376f
		fprintf(stderr, "%s '%s' [%d]%s%s\n",
Packit Service 20376f
			message, extra, error, lg2spacer, lg2msg);
Packit Service 20376f
	else
Packit Service 20376f
		fprintf(stderr, "%s [%d]%s%s\n",
Packit Service 20376f
			message, error, lg2spacer, lg2msg);
Packit Service 20376f
Packit Service 20376f
	exit(1);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void fatal(const char *message, const char *extra)
Packit Service 20376f
{
Packit Service 20376f
	if (extra)
Packit Service 20376f
		fprintf(stderr, "%s %s\n", message, extra);
Packit Service 20376f
	else
Packit Service 20376f
		fprintf(stderr, "%s\n", message);
Packit Service 20376f
Packit Service 20376f
	exit(1);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
size_t is_prefixed(const char *str, const char *pfx)
Packit Service 20376f
{
Packit Service 20376f
	size_t len = strlen(pfx);
Packit Service 20376f
	return strncmp(str, pfx, len) ? 0 : len;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
int optional_str_arg(
Packit Service 20376f
	const char **out, struct args_info *args, const char *opt, const char *def)
Packit Service 20376f
{
Packit Service 20376f
	const char *found = args->argv[args->pos];
Packit Service 20376f
	size_t len = is_prefixed(found, opt);
Packit Service 20376f
Packit Service 20376f
	if (!len)
Packit Service 20376f
		return 0;
Packit Service 20376f
Packit Service 20376f
	if (!found[len]) {
Packit Service 20376f
		if (args->pos + 1 == args->argc) {
Packit Service 20376f
			*out = def;
Packit Service 20376f
			return 1;
Packit Service 20376f
		}
Packit Service 20376f
		args->pos += 1;
Packit Service 20376f
		*out = args->argv[args->pos];
Packit Service 20376f
		return 1;
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	if (found[len] == '=') {
Packit Service 20376f
		*out = found + len + 1;
Packit Service 20376f
		return 1;
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	return 0;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
int match_str_arg(
Packit Service 20376f
	const char **out, struct args_info *args, const char *opt)
Packit Service 20376f
{
Packit Service 20376f
	const char *found = args->argv[args->pos];
Packit Service 20376f
	size_t len = is_prefixed(found, opt);
Packit Service 20376f
Packit Service 20376f
	if (!len)
Packit Service 20376f
		return 0;
Packit Service 20376f
Packit Service 20376f
	if (!found[len]) {
Packit Service 20376f
		if (args->pos + 1 == args->argc)
Packit Service 20376f
			fatal("expected value following argument", opt);
Packit Service 20376f
		args->pos += 1;
Packit Service 20376f
		*out = args->argv[args->pos];
Packit Service 20376f
		return 1;
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	if (found[len] == '=') {
Packit Service 20376f
		*out = found + len + 1;
Packit Service 20376f
		return 1;
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	return 0;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static const char *match_numeric_arg(struct args_info *args, const char *opt)
Packit Service 20376f
{
Packit Service 20376f
	const char *found = args->argv[args->pos];
Packit Service 20376f
	size_t len = is_prefixed(found, opt);
Packit Service 20376f
Packit Service 20376f
	if (!len)
Packit Service 20376f
		return NULL;
Packit Service 20376f
Packit Service 20376f
	if (!found[len]) {
Packit Service 20376f
		if (args->pos + 1 == args->argc)
Packit Service 20376f
			fatal("expected numeric value following argument", opt);
Packit Service 20376f
		args->pos += 1;
Packit Service 20376f
		found = args->argv[args->pos];
Packit Service 20376f
	} else {
Packit Service 20376f
		found = found + len;
Packit Service 20376f
		if (*found == '=')
Packit Service 20376f
			found++;
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	return found;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
int match_uint16_arg(
Packit Service 20376f
	uint16_t *out, struct args_info *args, const char *opt)
Packit Service 20376f
{
Packit Service 20376f
	const char *found = match_numeric_arg(args, opt);
Packit Service 20376f
	uint16_t val;
Packit Service 20376f
	char *endptr = NULL;
Packit Service 20376f
Packit Service 20376f
	if (!found)
Packit Service 20376f
		return 0;
Packit Service 20376f
Packit Service 20376f
	val = (uint16_t)strtoul(found, &endptr, 0);
Packit Service 20376f
	if (!endptr || *endptr != '\0')
Packit Service 20376f
		fatal("expected number after argument", opt);
Packit Service 20376f
Packit Service 20376f
	if (out)
Packit Service 20376f
		*out = val;
Packit Service 20376f
	return 1;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
int match_uint32_arg(
Packit Service 20376f
	uint32_t *out, struct args_info *args, const char *opt)
Packit Service 20376f
{
Packit Service 20376f
	const char *found = match_numeric_arg(args, opt);
Packit Service 20376f
	uint16_t val;
Packit Service 20376f
	char *endptr = NULL;
Packit Service 20376f
Packit Service 20376f
	if (!found)
Packit Service 20376f
		return 0;
Packit Service 20376f
Packit Service 20376f
	val = (uint32_t)strtoul(found, &endptr, 0);
Packit Service 20376f
	if (!endptr || *endptr != '\0')
Packit Service 20376f
		fatal("expected number after argument", opt);
Packit Service 20376f
Packit Service 20376f
	if (out)
Packit Service 20376f
		*out = val;
Packit Service 20376f
	return 1;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
static int match_int_internal(
Packit Service 20376f
	int *out, const char *str, int allow_negative, const char *opt)
Packit Service 20376f
{
Packit Service 20376f
	char *endptr = NULL;
Packit Service 20376f
	int	  val = (int)strtol(str, &endptr, 10);
Packit Service 20376f
Packit Service 20376f
	if (!endptr || *endptr != '\0')
Packit Service 20376f
		fatal("expected number", opt);
Packit Service 20376f
	else if (val < 0 && !allow_negative)
Packit Service 20376f
		fatal("negative values are not allowed", opt);
Packit Service 20376f
Packit Service 20376f
	if (out)
Packit Service 20376f
		*out = val;
Packit Service 20376f
Packit Service 20376f
	return 1;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
int is_integer(int *out, const char *str, int allow_negative)
Packit Service 20376f
{
Packit Service 20376f
	return match_int_internal(out, str, allow_negative, NULL);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
int match_int_arg(
Packit Service 20376f
	int *out, struct args_info *args, const char *opt, int allow_negative)
Packit Service 20376f
{
Packit Service 20376f
	const char *found = match_numeric_arg(args, opt);
Packit Service 20376f
	if (!found)
Packit Service 20376f
		return 0;
Packit Service 20376f
	return match_int_internal(out, found, allow_negative, opt);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
int diff_output(
Packit Service 20376f
	const git_diff_delta *d,
Packit Service 20376f
	const git_diff_hunk *h,
Packit Service 20376f
	const git_diff_line *l,
Packit Service 20376f
	void *p)
Packit Service 20376f
{
Packit Service 20376f
	FILE *fp = (FILE*)p;
Packit Service 20376f
Packit Service 20376f
	(void)d; (void)h;
Packit Service 20376f
Packit Service 20376f
	if (!fp)
Packit Service 20376f
		fp = stdout;
Packit Service 20376f
Packit Service 20376f
	if (l->origin == GIT_DIFF_LINE_CONTEXT ||
Packit Service 20376f
		l->origin == GIT_DIFF_LINE_ADDITION ||
Packit Service 20376f
		l->origin == GIT_DIFF_LINE_DELETION)
Packit Service 20376f
		fputc(l->origin, fp);
Packit Service 20376f
Packit Service 20376f
	fwrite(l->content, 1, l->content_len, fp);
Packit Service 20376f
Packit Service 20376f
	return 0;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
void treeish_to_tree(
Packit Service 20376f
	git_tree **out, git_repository *repo, const char *treeish)
Packit Service 20376f
{
Packit Service 20376f
	git_object *obj = NULL;
Packit Service 20376f
Packit Service 20376f
	check_lg2(
Packit Service 20376f
		git_revparse_single(&obj, repo, treeish),
Packit Service 20376f
		"looking up object", treeish);
Packit Service 20376f
Packit Service 20376f
	check_lg2(
Packit Service 20376f
		git_object_peel((git_object **)out, obj, GIT_OBJ_TREE),
Packit Service 20376f
		"resolving object to tree", treeish);
Packit Service 20376f
Packit Service 20376f
	git_object_free(obj);
Packit Service 20376f
}
Packit Service 20376f