mirror of
				https://git.proxmox.com/git/libgit2
				synced 2025-11-04 04:38:58 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			198 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "common.h"
 | 
						|
#include "args.h"
 | 
						|
 | 
						|
size_t is_prefixed(const char *str, const char *pfx)
 | 
						|
{
 | 
						|
	size_t len = strlen(pfx);
 | 
						|
	return strncmp(str, pfx, len) ? 0 : len;
 | 
						|
}
 | 
						|
 | 
						|
int optional_str_arg(
 | 
						|
	const char **out, struct args_info *args, const char *opt, const char *def)
 | 
						|
{
 | 
						|
	const char *found = args->argv[args->pos];
 | 
						|
	size_t len = is_prefixed(found, opt);
 | 
						|
 | 
						|
	if (!len)
 | 
						|
		return 0;
 | 
						|
 | 
						|
	if (!found[len]) {
 | 
						|
		if (args->pos + 1 == args->argc) {
 | 
						|
			*out = def;
 | 
						|
			return 1;
 | 
						|
		}
 | 
						|
		args->pos += 1;
 | 
						|
		*out = args->argv[args->pos];
 | 
						|
		return 1;
 | 
						|
	}
 | 
						|
 | 
						|
	if (found[len] == '=') {
 | 
						|
		*out = found + len + 1;
 | 
						|
		return 1;
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int match_str_arg(
 | 
						|
	const char **out, struct args_info *args, const char *opt)
 | 
						|
{
 | 
						|
	const char *found = args->argv[args->pos];
 | 
						|
	size_t len = is_prefixed(found, opt);
 | 
						|
 | 
						|
	if (!len)
 | 
						|
		return 0;
 | 
						|
 | 
						|
	if (!found[len]) {
 | 
						|
		if (args->pos + 1 == args->argc)
 | 
						|
			fatal("expected value following argument", opt);
 | 
						|
		args->pos += 1;
 | 
						|
		*out = args->argv[args->pos];
 | 
						|
		return 1;
 | 
						|
	}
 | 
						|
 | 
						|
	if (found[len] == '=') {
 | 
						|
		*out = found + len + 1;
 | 
						|
		return 1;
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static const char *match_numeric_arg(struct args_info *args, const char *opt)
 | 
						|
{
 | 
						|
	const char *found = args->argv[args->pos];
 | 
						|
	size_t len = is_prefixed(found, opt);
 | 
						|
 | 
						|
	if (!len)
 | 
						|
		return NULL;
 | 
						|
 | 
						|
	if (!found[len]) {
 | 
						|
		if (args->pos + 1 == args->argc)
 | 
						|
			fatal("expected numeric value following argument", opt);
 | 
						|
		args->pos += 1;
 | 
						|
		found = args->argv[args->pos];
 | 
						|
	} else {
 | 
						|
		found = found + len;
 | 
						|
		if (*found == '=')
 | 
						|
			found++;
 | 
						|
	}
 | 
						|
 | 
						|
	return found;
 | 
						|
}
 | 
						|
 | 
						|
int match_uint16_arg(
 | 
						|
	uint16_t *out, struct args_info *args, const char *opt)
 | 
						|
{
 | 
						|
	const char *found = match_numeric_arg(args, opt);
 | 
						|
	uint16_t val;
 | 
						|
	char *endptr = NULL;
 | 
						|
 | 
						|
	if (!found)
 | 
						|
		return 0;
 | 
						|
 | 
						|
	val = (uint16_t)strtoul(found, &endptr, 0);
 | 
						|
	if (!endptr || *endptr != '\0')
 | 
						|
		fatal("expected number after argument", opt);
 | 
						|
 | 
						|
	if (out)
 | 
						|
		*out = val;
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
int match_uint32_arg(
 | 
						|
	uint32_t *out, struct args_info *args, const char *opt)
 | 
						|
{
 | 
						|
	const char *found = match_numeric_arg(args, opt);
 | 
						|
	uint16_t val;
 | 
						|
	char *endptr = NULL;
 | 
						|
 | 
						|
	if (!found)
 | 
						|
		return 0;
 | 
						|
 | 
						|
	val = (uint32_t)strtoul(found, &endptr, 0);
 | 
						|
	if (!endptr || *endptr != '\0')
 | 
						|
		fatal("expected number after argument", opt);
 | 
						|
 | 
						|
	if (out)
 | 
						|
		*out = val;
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static int match_int_internal(
 | 
						|
	int *out, const char *str, int allow_negative, const char *opt)
 | 
						|
{
 | 
						|
	char *endptr = NULL;
 | 
						|
	int	  val = (int)strtol(str, &endptr, 10);
 | 
						|
 | 
						|
	if (!endptr || *endptr != '\0')
 | 
						|
		fatal("expected number", opt);
 | 
						|
	else if (val < 0 && !allow_negative)
 | 
						|
		fatal("negative values are not allowed", opt);
 | 
						|
 | 
						|
	if (out)
 | 
						|
		*out = val;
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
int match_bool_arg(int *out, struct args_info *args, const char *opt)
 | 
						|
{
 | 
						|
	const char *found = args->argv[args->pos];
 | 
						|
 | 
						|
	if (!strcmp(found, opt)) {
 | 
						|
		*out = 1;
 | 
						|
		return 1;
 | 
						|
	}
 | 
						|
 | 
						|
	if (!strncmp(found, "--no-", strlen("--no-")) &&
 | 
						|
	    !strcmp(found + strlen("--no-"), opt + 2)) {
 | 
						|
		*out = 0;
 | 
						|
		return 1;
 | 
						|
	}
 | 
						|
 | 
						|
	*out = -1;
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int is_integer(int *out, const char *str, int allow_negative)
 | 
						|
{
 | 
						|
	return match_int_internal(out, str, allow_negative, NULL);
 | 
						|
}
 | 
						|
 | 
						|
int match_int_arg(
 | 
						|
	int *out, struct args_info *args, const char *opt, int allow_negative)
 | 
						|
{
 | 
						|
	const char *found = match_numeric_arg(args, opt);
 | 
						|
	if (!found)
 | 
						|
		return 0;
 | 
						|
	return match_int_internal(out, found, allow_negative, opt);
 | 
						|
}
 | 
						|
 | 
						|
int match_arg_separator(struct args_info *args)
 | 
						|
{
 | 
						|
	if (args->opts_done)
 | 
						|
		return 1;
 | 
						|
 | 
						|
	if (strcmp(args->argv[args->pos], "--") != 0)
 | 
						|
		return 0;
 | 
						|
 | 
						|
	args->opts_done = 1;
 | 
						|
	args->pos++;
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
void strarray_from_args(git_strarray *array, struct args_info *args)
 | 
						|
{
 | 
						|
	size_t i;
 | 
						|
 | 
						|
	array->count = args->argc - args->pos;
 | 
						|
	array->strings = calloc(array->count, sizeof(char *));
 | 
						|
	assert(array->strings != NULL);
 | 
						|
 | 
						|
	for (i = 0; args->pos < args->argc; ++args->pos) {
 | 
						|
		array->strings[i++] = args->argv[args->pos];
 | 
						|
	}
 | 
						|
	args->pos = args->argc;
 | 
						|
}
 |