[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Some questions about argp
From: |
Herbert Euler |
Subject: |
Some questions about argp |
Date: |
Wed, 01 Aug 2007 09:44:54 +0800 |
Hello,
I have some questions on the argp implementation. Please take a look
at them. Thanks.
1. On ARGP_KEY_ARGS
The document of this macro, in the libc document, says:
`ARGP_KEY_ARGS'
If a parser function returns `ARGP_ERR_UNKNOWN' for
`ARGP_KEY_ARG', it is immediately called again with the key
`ARGP_KEY_ARGS', which has a similar meaning, but is slightly more
convenient for consuming all remaining arguments. ARG is 0, and
the tail of the argument vector may be found at `STATE->argv +
STATE->next'. If success is returned for this key, and
`STATE->next' is unchanged, all remaining arguments are considered
to have been consumed. Otherwise, the amount by which
`STATE->next' has been adjusted indicates how many were used.
Here's an example that uses both, for different args:
If I do not understand wrong, the document implies that if some parser
changes the value of `STATE->next', then not all of the remaining
arguments will be marked as being consumed. But the function
parser_parse_arg seems not to handle ARGP_KEY_ARGS this way:
if (key == ARGP_KEY_ARGS)
/* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't
changed by the user, *all* arguments should be considered
consumed. */
parser->state.next = parser->state.argc;
This implementation will mark all of the remaining arguments as
already consumed, no matter whether the called parser changes
`STATE->next'.
The attached argp-test1.c verifies this conclusion:
address@hidden tmp]$ gcc -o argp-test argp-test1.c
address@hidden tmp]$ ./argp-test a b c
Parsing a
address@hidden tmp]$
Do I understand wrong, or is there something wrong in
parser_parse_arg?
2. On the input passed in by the user
The following code in the function parser_init shows that only the
first child in a group will get the input in certain conditions:
if (!group->parser
&& group->argp->children && group->argp->children->argp)
/* For the special case where no parsing function is supplied for an
argp, propagate its input to its first child, if any (this just
makes very simple wrapper argps more convenient). */
group->child_inputs[0] = group->input;
And the attached "argp-test2.c" verifies this behavior:
address@hidden tmp]$ gcc -o argp-test argp-test2.c
address@hidden tmp]$ ./argp-test a
key = 0x1000003 In child1_parser: input-data
key = 0x1000003 In child2_parser: (null)
key = 0x0 In child1_parser: input-data
key = 0x1000006 In child1_parser: input-data
key = 0x0 In child2_parser: (null)
key = 0x1000002 In child1_parser: input-data
key = 0x1000001 In child2_parser: (null)
key = 0x1000001 In child1_parser: input-data
key = 0x1000004 In child2_parser: (null)
key = 0x1000004 In child1_parser: input-data
key = 0x1000007 In child2_parser: (null)
key = 0x1000007 In child1_parser: input-data
address@hidden tmp]$
If other children in the group need the input, we have to propagate it
to them. Why not make it avaliable to all of the children by default?
What do I miss here?
3. On the key of long alias options
The VALs of long alias options are set in convert_options:
/* we add a disambiguating code to all the user's
values (which is removed before we actually call
the function to parse the value); this means that
the user loses use of the high 8 bits in all his
values (the sign of the lower bits is preserved
however)... */
cvt->long_end->val =
((opt->key | real->key) & USER_MASK)
+ (((group - cvt->parser->groups) + 1) << USER_BITS);
(opt->key | real->key) here makes KEYs in the original alias argps
meaningless. For example, in the attached argp-test3.c, we have:
static const struct argp_option my_argp_options[] =
{
{ "real", 'r', NULL, 0, "a real option", 0, },
{ "alias", 'a', NULL, OPTION_ALIAS, "an alias option", 0, },
{ 0, 0, 0, 0, 0, 0, },
};
But in the parser, the KEY argument is not set to 'a' when the user
provides the option "--alias", it is set to 's' (= ('r' | 'a')):
address@hidden tmp]$ gcc -o argp-test argp-test3.c
address@hidden tmp]$ ./argp-test --alias
key =
key = s
argp-test: --alias: (PROGRAM ERROR) Option should have been recognized!?
Try `argp-test --help' or `argp-test --usage' for more information.
address@hidden tmp]$
Perhaps I should define a constant for the options "real" and "alias",
as follows:
enum { REAL_OPTION = 'r', };
static const struct argp_option my_argp_options[] =
{
{ "real", REAL_OPTION, NULL, 0, "a real option", 0, },
{ "alias", REAL_OPTION, NULL, OPTION_ALIAS, "an alias option", 0, },
{ 0, 0, 0, 0, 0, 0, },
};
But why do we bitwise-or the keys? I don't see any benefits in it,
what do I miss?
4. On `STATE->arg_num'
This member seems to be group-specific, i.e. it is the number of
arguments processed by the current group. Its document says:
`unsigned arg_num'
While calling a parsing function with the KEY argument
`ARGP_KEY_ARG', this represents the number of the current arg,
starting at 0. It is incremented after each `ARGP_KEY_ARG'
call returns. At all other times, this is the number of
`ARGP_KEY_ARG' arguments that have been processed.
I'm a bit confused about the term "the number of the current arg".
What does this term mean? Yes, this member is very rarely used.
Perhaps this is not a question. ;-)
Regards,
Guanpeng Xu
_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE!
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
argp-test1.c
Description: Binary data
argp-test2.c
Description: Binary data
argp-test3.c
Description: Binary data
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Some questions about argp,
Herbert Euler <=