summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libgnu/argp-parse.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/libgnu/argp-parse.c b/libgnu/argp-parse.c
index 3f723bc8..dc3106e7 100644
--- a/libgnu/argp-parse.c
+++ b/libgnu/argp-parse.c
@@ -740,12 +740,15 @@ parser_parse_opt (struct parser *parser, int opt, char *val)
}
}
else
- /* A long option. We use shifts instead of masking for extracting
- the user value in order to preserve the sign. */
- err =
- group_parse (&parser->groups[group_key - 1], &parser->state,
- (opt << GROUP_BITS) >> GROUP_BITS,
- parser->opt_data.optarg);
+ {
+ uint maskable = (uint)(opt < 0 ? -opt : opt);
+ maskable = (maskable << GROUP_BITS) >> GROUP_BITS;
+ int masked = opt < 0 ? -(int)maskable : (int)maskable;
+
+ err =
+ group_parse (&parser->groups[group_key - 1], &parser->state,
+ masked, parser->opt_data.optarg);
+ }
if (err == EBADKEY)
/* At least currently, an option not recognized is an error in the