partial matching for long options
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@2447 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -101,55 +101,93 @@ arg_printusage (struct getargs *args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
arg_match(struct getargs *arg, char *argv)
|
arg_match_long(struct getargs *args, size_t num_args,
|
||||||
|
char *argv)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
char *optarg;
|
char *optarg;
|
||||||
int negate = 0;
|
int negate = 0;
|
||||||
if(arg->long_name) {
|
int partial_match = 0;
|
||||||
int len = strlen(arg->long_name);
|
struct getargs *partial = NULL;
|
||||||
if(strncmp(arg->long_name, argv, len))
|
struct getargs *current = NULL;
|
||||||
if(arg->type == arg_flag && strlen(argv) > 3 &&
|
int argv_len;
|
||||||
strncmp(arg->long_name, argv + 3, len) == 0){
|
char *p;
|
||||||
optarg = argv + 3 + len;
|
|
||||||
|
argv_len = strlen(argv);
|
||||||
|
p = strchr (argv, '=');
|
||||||
|
if (p != NULL)
|
||||||
|
argv_len = p - argv;
|
||||||
|
|
||||||
|
for (i = 0; i < num_args; ++i) {
|
||||||
|
if(args[i].long_name) {
|
||||||
|
int len = strlen(args[i].long_name);
|
||||||
|
|
||||||
|
if (strncmp (args[i].long_name, argv, len) == 0) {
|
||||||
|
current = &args[i];
|
||||||
|
optarg = argv + len;
|
||||||
|
break;
|
||||||
|
} else if (args[i].type == arg_flag
|
||||||
|
&& strncmp (argv, "no-", 3) == 0
|
||||||
|
&& strncmp (args[i].long_name, argv + 3, len) == 0) {
|
||||||
|
current = &args[i];
|
||||||
|
optarg = argv + len + 3;
|
||||||
|
negate = 1;
|
||||||
|
break;
|
||||||
|
} else if (strncmp (args[i].long_name, argv, argv_len) == 0) {
|
||||||
|
++partial_match;
|
||||||
|
partial = &args[i];
|
||||||
|
optarg = argv + argv_len;
|
||||||
|
} else if (args[i].type == arg_flag
|
||||||
|
&& strncmp (argv, "no-", 3) == 0
|
||||||
|
&& strncmp (args[i].long_name,
|
||||||
|
argv + 3,
|
||||||
|
argv_len - 3) == 0) {
|
||||||
|
++partial_match;
|
||||||
|
partial = &args[i];
|
||||||
|
optarg = argv + argv_len;
|
||||||
negate = 1;
|
negate = 1;
|
||||||
} else
|
|
||||||
return ARG_ERR_NO_MATCH;
|
|
||||||
else
|
|
||||||
optarg = argv + len;
|
|
||||||
|
|
||||||
if(*optarg != '=' && (arg->type != arg_flag && *optarg == 0))
|
|
||||||
return ARG_ERR_NO_MATCH;
|
|
||||||
switch(arg->type){
|
|
||||||
case arg_integer:
|
|
||||||
{
|
|
||||||
int tmp;
|
|
||||||
if(sscanf(optarg + 1, "%d", &tmp) != 1)
|
|
||||||
return ARG_ERR_BAD_ARG;
|
|
||||||
*(int*)arg->value = tmp;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case arg_string:
|
|
||||||
{
|
|
||||||
*(char**)arg->value = optarg + 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case arg_flag:
|
|
||||||
{
|
|
||||||
int *flag = arg->value;
|
|
||||||
if(*optarg == 0 ||
|
|
||||||
strcmp(optarg + 1, "yes") == 0 ||
|
|
||||||
strcmp(optarg + 1, "true") == 0){
|
|
||||||
*flag = !negate;
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
*flag = negate;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return ARG_ERR_BAD_ARG;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ARG_ERR_NO_MATCH;
|
if (current == NULL)
|
||||||
|
if (partial_match == 1)
|
||||||
|
current = partial;
|
||||||
|
else
|
||||||
|
return ARG_ERR_NO_MATCH;
|
||||||
|
|
||||||
|
if(*optarg != '=' && (current->type != arg_flag && *optarg == 0))
|
||||||
|
return ARG_ERR_NO_MATCH;
|
||||||
|
switch(current->type){
|
||||||
|
case arg_integer:
|
||||||
|
{
|
||||||
|
int tmp;
|
||||||
|
if(sscanf(optarg + 1, "%d", &tmp) != 1)
|
||||||
|
return ARG_ERR_BAD_ARG;
|
||||||
|
*(int*)current->value = tmp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case arg_string:
|
||||||
|
{
|
||||||
|
*(char**)current->value = optarg + 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case arg_flag:
|
||||||
|
{
|
||||||
|
int *flag = current->value;
|
||||||
|
if(*optarg == 0 ||
|
||||||
|
strcmp(optarg + 1, "yes") == 0 ||
|
||||||
|
strcmp(optarg + 1, "true") == 0){
|
||||||
|
*flag = !negate;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
*flag = negate;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ARG_ERR_BAD_ARG;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -167,11 +205,7 @@ getarg(struct getargs *args, size_t num_args,
|
|||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for(j = 0; j < num_args; j++){
|
ret = arg_match_long (args, num_args, argv[i] + 2);
|
||||||
ret = arg_match(&args[j], argv[i] + 2);
|
|
||||||
if(ret != ARG_ERR_NO_MATCH)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(ret)
|
if(ret)
|
||||||
return ret;
|
return ret;
|
||||||
}else{
|
}else{
|
||||||
|
Reference in New Issue
Block a user