| 128 | } |
| 129 | |
| 130 | static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p, |
| 131 | const struct option *opt, |
| 132 | enum opt_parsed flags, |
| 133 | const char **argp) |
| 134 | { |
| 135 | const char *arg; |
| 136 | const int unset = flags & OPT_UNSET; |
| 137 | |
| 138 | if (unset && p->opt) |
| 139 | return error(_("%s takes no value"), optname(opt, flags)); |
| 140 | if (unset && (opt->flags & PARSE_OPT_NONEG)) |
| 141 | return error(_("%s isn't available"), optname(opt, flags)); |
| 142 | if (!(flags & OPT_SHORT) && p->opt && (opt->flags & PARSE_OPT_NOARG)) |
| 143 | return error(_("%s takes no value"), optname(opt, flags)); |
| 144 | |
| 145 | switch (opt->type) { |
| 146 | case OPTION_LOWLEVEL_CALLBACK: |
| 147 | return opt->ll_callback(p, opt, NULL, unset); |
| 148 | |
| 149 | case OPTION_BIT: |
| 150 | { |
| 151 | intmax_t value = get_int_value(opt, flags); |
| 152 | if (unset) |
| 153 | value &= ~opt->defval; |
| 154 | else |
| 155 | value |= opt->defval; |
| 156 | return set_int_value(opt, flags, value); |
| 157 | } |
| 158 | |
| 159 | case OPTION_NEGBIT: |
| 160 | { |
| 161 | intmax_t value = get_int_value(opt, flags); |
| 162 | if (unset) |
| 163 | value |= opt->defval; |
| 164 | else |
| 165 | value &= ~opt->defval; |
| 166 | return set_int_value(opt, flags, value); |
| 167 | } |
| 168 | |
| 169 | case OPTION_BITOP: |
| 170 | { |
| 171 | intmax_t value = get_int_value(opt, flags); |
| 172 | if (unset) |
| 173 | BUG("BITOP can't have unset form"); |
| 174 | value &= ~opt->extra; |
| 175 | value |= opt->defval; |
| 176 | return set_int_value(opt, flags, value); |
| 177 | } |
| 178 | |
| 179 | case OPTION_COUNTUP: |
| 180 | { |
| 181 | size_t bits = CHAR_BIT * opt->precision; |
| 182 | intmax_t upper_bound = INTMAX_MAX >> (bitsizeof(intmax_t) - bits); |
| 183 | intmax_t value = get_int_value(opt, flags); |
| 184 | |
| 185 | if (value < 0) |
| 186 | value = 0; |
| 187 | if (unset) |
no test coverage detected