GCC Code Coverage Report


Directory: lib/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 87 / 0 / 87
Functions: 100.0% 3 / 0 / 3
Branches: 89.5% 77 / 0 / 86

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