core_validate.c
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include <string.h> | ||
| 2 | |||
| 3 | #include "ap_internal.h" | ||
| 4 | |||
| 5 | 822 | static bool has_value(const ap_parsed_arg *parsed) { | |
| 6 | 822 | return parsed->values.count > 0; | |
| 7 | } | ||
| 8 | |||
| 9 | 464 | static int check_choices(const ap_arg_def *def, const ap_parsed_arg *parsed, | |
| 10 | ap_error *err) { | ||
| 11 | int i; | ||
| 12 | int j; | ||
| 13 | char label[96]; | ||
| 14 |
3/4✓ Branch 0 taken 18 times.
✓ Branch 1 taken 446 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
|
464 | if (!def->opts.choices.items || def->opts.choices.count <= 0) { |
| 15 | 446 | return 0; | |
| 16 | } | ||
| 17 | |||
| 18 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 16 times.
|
22 | for (i = 0; i < parsed->values.count; i++) { |
| 19 | 6 | bool found = false; | |
| 20 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
|
12 | for (j = 0; j < def->opts.choices.count; j++) { |
| 21 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
|
10 | if (strcmp(parsed->values.items[i], def->opts.choices.items[j]) == 0) { |
| 22 | 4 | found = true; | |
| 23 | 4 | break; | |
| 24 | } | ||
| 25 | } | ||
| 26 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
|
6 | if (!found) { |
| 27 | 2 | ap_error_label_for_arg(def, label, sizeof(label)); | |
| 28 | 2 | ap_error_set(err, AP_ERR_INVALID_CHOICE, ap_error_argument_name(def), | |
| 29 | 2 | "invalid choice '%s' for %s", parsed->values.items[i], | |
| 30 | label); | ||
| 31 | 2 | return -1; | |
| 32 | } | ||
| 33 | } | ||
| 34 | 16 | return 0; | |
| 35 | } | ||
| 36 | |||
| 37 | 276 | int ap_validate_args(const ap_parser *parser, const ap_parsed_arg *parsed, | |
| 38 | ap_error *err) { | ||
| 39 | int i; | ||
| 40 | 276 | bool help_requested = false; | |
| 41 | |||
| 42 |
2/2✓ Branch 0 taken 840 times.
✓ Branch 1 taken 266 times.
|
1106 | for (i = 0; i < parser->defs_count; i++) { |
| 43 | 840 | const ap_arg_def *def = &parser->defs[i]; | |
| 44 |
2/2✓ Branch 0 taken 334 times.
✓ Branch 1 taken 506 times.
|
840 | if (def->opts.action == AP_ACTION_STORE_TRUE && |
| 45 |
4/4✓ Branch 0 taken 276 times.
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 266 times.
|
334 | strcmp(def->dest, "help") == 0 && parsed[i].seen) { |
| 46 | 10 | help_requested = true; | |
| 47 | 10 | break; | |
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 266 times.
|
276 | if (help_requested) { |
| 52 | 10 | return 0; | |
| 53 | } | ||
| 54 | |||
| 55 |
2/2✓ Branch 0 taken 822 times.
✓ Branch 1 taken 246 times.
|
1068 | for (i = 0; i < parser->defs_count; i++) { |
| 56 | 822 | const ap_arg_def *def = &parser->defs[i]; | |
| 57 | 822 | const ap_parsed_arg *p = &parsed[i]; | |
| 58 | 822 | bool has_parsed_value = has_value(p); | |
| 59 | char label[96]; | ||
| 60 | |||
| 61 |
2/2✓ Branch 0 taken 498 times.
✓ Branch 1 taken 324 times.
|
822 | if (def->opts.action == AP_ACTION_STORE_TRUE || |
| 62 |
2/2✓ Branch 0 taken 496 times.
✓ Branch 1 taken 2 times.
|
498 | def->opts.action == AP_ACTION_STORE_FALSE || |
| 63 |
2/2✓ Branch 0 taken 482 times.
✓ Branch 1 taken 14 times.
|
496 | def->opts.action == AP_ACTION_COUNT || |
| 64 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 478 times.
|
482 | def->opts.action == AP_ACTION_STORE_CONST) { |
| 65 |
3/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 340 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
344 | if (def->opts.required && !p->seen) { |
| 66 | 4 | ap_error_label_for_arg(def, label, sizeof(label)); | |
| 67 | 4 | ap_error_set(err, AP_ERR_MISSING_REQUIRED, ap_error_argument_name(def), | |
| 68 | "%s is required", label); | ||
| 69 | 20 | return -1; | |
| 70 | } | ||
| 71 | 340 | continue; | |
| 72 | } | ||
| 73 | |||
| 74 |
2/2✓ Branch 0 taken 66 times.
✓ Branch 1 taken 412 times.
|
478 | if (def->opts.required) { |
| 75 |
2/2✓ Branch 0 taken 64 times.
✓ Branch 1 taken 2 times.
|
66 | if (def->is_optional) { |
| 76 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 58 times.
|
64 | if (!p->seen) { |
| 77 | 6 | ap_error_label_for_arg(def, label, sizeof(label)); | |
| 78 | 6 | ap_error_set(err, AP_ERR_MISSING_REQUIRED, | |
| 79 | ap_error_argument_name(def), "%s is required", label); | ||
| 80 | 6 | return -1; | |
| 81 | } | ||
| 82 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | } else if (!has_parsed_value) { |
| 83 | 2 | ap_error_label_for_arg(def, label, sizeof(label)); | |
| 84 | 2 | ap_error_set(err, AP_ERR_MISSING_REQUIRED, ap_error_argument_name(def), | |
| 85 | "%s is required", label); | ||
| 86 | 2 | return -1; | |
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 |
6/6✓ Branch 0 taken 418 times.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 210 times.
✓ Branch 3 taken 208 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 208 times.
|
470 | if (def->opts.nargs == AP_NARGS_ONE && p->seen && !has_parsed_value) { |
| 91 | 2 | ap_error_label_for_arg(def, label, sizeof(label)); | |
| 92 | 2 | ap_error_set(err, AP_ERR_MISSING_VALUE, ap_error_argument_name(def), | |
| 93 | "%s requires a value", label); | ||
| 94 | 2 | return -1; | |
| 95 | } | ||
| 96 | |||
| 97 |
3/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 464 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
468 | if (def->opts.nargs == AP_NARGS_ONE_OR_MORE && p->seen && |
| 98 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | !has_parsed_value) { |
| 99 | 2 | ap_error_label_for_arg(def, label, sizeof(label)); | |
| 100 | 2 | ap_error_set(err, AP_ERR_INVALID_NARGS, ap_error_argument_name(def), | |
| 101 | "%s requires at least one value", label); | ||
| 102 | 2 | return -1; | |
| 103 | } | ||
| 104 | |||
| 105 |
3/4✓ Branch 0 taken 14 times.
✓ Branch 1 taken 452 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
466 | if (def->opts.nargs == AP_NARGS_FIXED && p->values.count > 0 && |
| 106 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
|
14 | p->values.count != def->opts.nargs_count) { |
| 107 | 2 | ap_error_label_for_arg(def, label, sizeof(label)); | |
| 108 | 2 | ap_error_set(err, AP_ERR_INVALID_NARGS, ap_error_argument_name(def), | |
| 109 | "%s requires exactly %d values", label, | ||
| 110 | 2 | def->opts.nargs_count); | |
| 111 | 2 | return -1; | |
| 112 | } | ||
| 113 | |||
| 114 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 462 times.
|
464 | if (check_choices(def, p, err) != 0) { |
| 115 | 2 | return -1; | |
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 240 times.
|
250 | for (i = 0; i < parser->mutex_groups_count; i++) { |
| 120 | 10 | const ap_mutex_group_def *group = &parser->mutex_groups[i]; | |
| 121 | int j; | ||
| 122 | 10 | int seen_count = 0; | |
| 123 | 10 | const char *first_name = NULL; | |
| 124 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 10 times.
|
26 | for (j = 0; j < group->arg_count; j++) { |
| 125 | 16 | const ap_arg_def *def = &parser->defs[group->arg_indexes[j]]; | |
| 126 | 16 | const ap_parsed_arg *p = &parsed[group->arg_indexes[j]]; | |
| 127 |
3/4✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
16 | bool active = p->seen || p->values.count > 0; |
| 128 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
|
16 | if (!active) { |
| 129 | 6 | continue; | |
| 130 | } | ||
| 131 | 10 | seen_count++; | |
| 132 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
|
10 | if (!first_name) { |
| 133 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | first_name = def->is_optional ? def->flags[0] : def->dest; |
| 134 | } | ||
| 135 | } | ||
| 136 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
|
10 | if (seen_count > 1) { |
| 137 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | ap_error_set(err, AP_ERR_INVALID_DEFINITION, first_name ? first_name : "", |
| 138 | "mutually exclusive arguments cannot be used together"); | ||
| 139 | 4 | return -1; | |
| 140 | } | ||
| 141 |
3/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
6 | if (group->required && seen_count == 0) { |
| 142 | 2 | ap_error_set(err, AP_ERR_MISSING_REQUIRED, "", | |
| 143 | "one argument from a mutually exclusive group is required"); | ||
| 144 | 2 | return -1; | |
| 145 | } | ||
| 146 | } | ||
| 147 | 240 | return 0; | |
| 148 | } | ||
| 149 |