1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "apr_errno.h" 18#include "apr_general.h" 19#include "apr_getopt.h" 20#include "apr_strings.h" 21#include "testutil.h" 22 23static void format_arg(char *str, char option, const char *arg) 24{ 25 if (arg) { 26 apr_snprintf(str, 8196, "%soption: %c with %s\n", str, option, arg); 27 } 28 else { 29 apr_snprintf(str, 8196, "%soption: %c\n", str, option); 30 } 31} 32 33static void unknown_arg(void *str, const char *err, ...) 34{ 35 va_list va; 36 37 va_start(va, err); 38 apr_vsnprintf(str, 8196, err, va); 39 va_end(va); 40} 41 42static void no_options_found(abts_case *tc, void *data) 43{ 44 int largc = 5; 45 const char * const largv[] = {"testprog", "-a", "-b", "-c", "-d"}; 46 apr_getopt_t *opt; 47 apr_status_t rv; 48 char ch; 49 const char *optarg; 50 char str[8196]; 51 52 str[0] = '\0'; 53 rv = apr_getopt_init(&opt, p, largc, largv); 54 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 55 56 while (apr_getopt(opt, "abcd", &ch, &optarg) == APR_SUCCESS) { 57 switch (ch) { 58 case 'a': 59 case 'b': 60 case 'c': 61 case 'd': 62 default: 63 format_arg(str, ch, optarg); 64 } 65 } 66 ABTS_STR_EQUAL(tc, "option: a\n" 67 "option: b\n" 68 "option: c\n" 69 "option: d\n", str); 70} 71 72static void no_options(abts_case *tc, void *data) 73{ 74 int largc = 5; 75 const char * const largv[] = {"testprog", "-a", "-b", "-c", "-d"}; 76 apr_getopt_t *opt; 77 apr_status_t rv; 78 char ch; 79 const char *optarg; 80 char str[8196]; 81 82 str[0] = '\0'; 83 rv = apr_getopt_init(&opt, p, largc, largv); 84 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 85 86 opt->errfn = unknown_arg; 87 opt->errarg = str; 88 89 while (apr_getopt(opt, "efgh", &ch, &optarg) == APR_SUCCESS) { 90 switch (ch) { 91 case 'a': 92 case 'b': 93 case 'c': 94 case 'd': 95 format_arg(str, ch, optarg); 96 break; 97 default: 98 break; 99 } 100 } 101 ABTS_STR_EQUAL(tc, "testprog: illegal option -- a\n", str); 102} 103 104static void required_option(abts_case *tc, void *data) 105{ 106 int largc = 3; 107 const char * const largv[] = {"testprog", "-a", "foo"}; 108 apr_getopt_t *opt; 109 apr_status_t rv; 110 char ch; 111 const char *optarg; 112 char str[8196]; 113 114 str[0] = '\0'; 115 rv = apr_getopt_init(&opt, p, largc, largv); 116 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 117 118 opt->errfn = unknown_arg; 119 opt->errarg = str; 120 121 while (apr_getopt(opt, "a:", &ch, &optarg) == APR_SUCCESS) { 122 switch (ch) { 123 case 'a': 124 format_arg(str, ch, optarg); 125 break; 126 default: 127 break; 128 } 129 } 130 ABTS_STR_EQUAL(tc, "option: a with foo\n", str); 131} 132 133static void required_option_notgiven(abts_case *tc, void *data) 134{ 135 int largc = 2; 136 const char * const largv[] = {"testprog", "-a"}; 137 apr_getopt_t *opt; 138 apr_status_t rv; 139 char ch; 140 const char *optarg; 141 char str[8196]; 142 143 str[0] = '\0'; 144 rv = apr_getopt_init(&opt, p, largc, largv); 145 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 146 147 opt->errfn = unknown_arg; 148 opt->errarg = str; 149 150 while (apr_getopt(opt, "a:", &ch, &optarg) == APR_SUCCESS) { 151 switch (ch) { 152 case 'a': 153 format_arg(str, ch, optarg); 154 break; 155 default: 156 break; 157 } 158 } 159 ABTS_STR_EQUAL(tc, "testprog: option requires an argument -- a\n", str); 160} 161 162static void optional_option(abts_case *tc, void *data) 163{ 164 int largc = 3; 165 const char * const largv[] = {"testprog", "-a", "foo"}; 166 apr_getopt_t *opt; 167 apr_status_t rv; 168 char ch; 169 const char *optarg; 170 char str[8196]; 171 172 str[0] = '\0'; 173 rv = apr_getopt_init(&opt, p, largc, largv); 174 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 175 176 opt->errfn = unknown_arg; 177 opt->errarg = str; 178 179 while (apr_getopt(opt, "a::", &ch, &optarg) == APR_SUCCESS) { 180 switch (ch) { 181 case 'a': 182 format_arg(str, ch, optarg); 183 break; 184 default: 185 break; 186 } 187 } 188 ABTS_STR_EQUAL(tc, "option: a with foo\n", str); 189} 190 191static void optional_option_notgiven(abts_case *tc, void *data) 192{ 193 int largc = 2; 194 const char * const largv[] = {"testprog", "-a"}; 195 apr_getopt_t *opt; 196 apr_status_t rv; 197 char ch; 198 const char *optarg; 199 char str[8196]; 200 201 str[0] = '\0'; 202 rv = apr_getopt_init(&opt, p, largc, largv); 203 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 204 205 opt->errfn = unknown_arg; 206 opt->errarg = str; 207 208 while (apr_getopt(opt, "a::", &ch, &optarg) == APR_SUCCESS) { 209 switch (ch) { 210 case 'a': 211 format_arg(str, ch, optarg); 212 break; 213 default: 214 break; 215 } 216 } 217#if 0 218/* Our version of getopt doesn't allow for optional arguments. */ 219 ABTS_STR_EQUAL(tc, "option: a\n", str); 220#endif 221 ABTS_STR_EQUAL(tc, "testprog: option requires an argument -- a\n", str); 222} 223 224abts_suite *testgetopt(abts_suite *suite) 225{ 226 suite = ADD_SUITE(suite) 227 228 abts_run_test(suite, no_options, NULL); 229 abts_run_test(suite, no_options_found, NULL); 230 abts_run_test(suite, required_option, NULL); 231 abts_run_test(suite, required_option_notgiven, NULL); 232 abts_run_test(suite, optional_option, NULL); 233 abts_run_test(suite, optional_option_notgiven, NULL); 234 235 return suite; 236} 237