Returns 1 if argument consumed, 0 if all done, -1 on error. */
| 80 | |
| 81 | /* Returns 1 if argument consumed, 0 if all done, -1 on error. */ |
| 82 | int parse_one(int *argc, char *argv[], enum opt_type is_early, unsigned *offset, |
| 83 | void (*errlog)(const char *fmt, ...), bool unknown_ok) |
| 84 | { |
| 85 | unsigned arg, len; |
| 86 | const char *o, *optarg = NULL; |
| 87 | char *problem = NULL; |
| 88 | struct opt_table *ot; |
| 89 | |
| 90 | if (getenv("POSIXLY_CORRECT")) { |
| 91 | /* Don't find options after non-options. */ |
| 92 | arg = 1; |
| 93 | } else { |
| 94 | for (arg = 1; argv[arg]; arg++) { |
| 95 | if (argv[arg][0] == '-') |
| 96 | break; |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | if (!argv[arg] || argv[arg][0] != '-') |
| 101 | return 0; |
| 102 | |
| 103 | /* Special arg terminator option. */ |
| 104 | if (strcmp(argv[arg], "--") == 0) { |
| 105 | consume_option(argc, argv, arg); |
| 106 | return 0; |
| 107 | } |
| 108 | |
| 109 | /* Long options start with -- */ |
| 110 | if (argv[arg][1] == '-') { |
| 111 | assert(*offset == 0); |
| 112 | |
| 113 | ot = opt_find_long_extra(argv[arg]+2, &optarg, &len, &o); |
| 114 | if (!ot) { |
| 115 | if (unknown_ok) |
| 116 | goto ok; |
| 117 | return parse_err(errlog, argv[0], |
| 118 | argv[arg], strlen(argv[arg]), |
| 119 | "unrecognized option"); |
| 120 | } |
| 121 | |
| 122 | /* For error messages, we include the leading '--' */ |
| 123 | o -= 2; |
| 124 | len += 2; |
| 125 | } else { |
| 126 | ot = opt_find_short_extra(argv[arg][*offset + 1], &o); |
| 127 | if (!ot) { |
| 128 | if (unknown_ok) { |
| 129 | (*offset)++; |
| 130 | goto ok; |
| 131 | } |
| 132 | return parse_err(errlog, argv[0], |
| 133 | argv[arg], strlen(argv[arg]), |
| 134 | "unrecognized option"); |
| 135 | } |
| 136 | |
| 137 | (*offset)++; |
| 138 | /* For error messages, we include the leading '-' */ |
| 139 | o--; |
no test coverage detected