]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/contrib/rdma/krping/getopt.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / contrib / rdma / krping / getopt.c
1 /*
2  * lifted from fs/ncpfs/getopt.c
3  *
4  */
5 #include <sys/cdefs.h>
6 __FBSDID("$FreeBSD$");
7
8 #include <sys/ctype.h>
9 #include <sys/param.h>
10 #include <sys/libkern.h>
11 #include "getopt.h"
12
13 /**
14  *      krping_getopt - option parser
15  *      @caller: name of the caller, for error messages
16  *      @options: the options string
17  *      @opts: an array of &struct option entries controlling parser operations
18  *      @optopt: output; will contain the current option
19  *      @optarg: output; will contain the value (if one exists)
20  *      @flag: output; may be NULL; should point to a long for or'ing flags
21  *      @value: output; may be NULL; will be overwritten with the integer value
22  *              of the current argument.
23  *
24  *      Helper to parse options on the format used by mount ("a=b,c=d,e,f").
25  *      Returns opts->val if a matching entry in the 'opts' array is found,
26  *      0 when no more tokens are found, -1 if an error is encountered.
27  */
28 int krping_getopt(const char *caller, char **options, 
29                   const struct krping_option *opts, char **optopt, 
30                   char **optarg, unsigned long *value)
31 {
32         char *token;
33         char *val;
34
35         do {
36                 if ((token = strsep(options, ",")) == NULL)
37                         return 0;
38         } while (*token == '\0');
39         if (optopt)
40                 *optopt = token;
41
42         if ((val = strchr (token, '=')) != NULL) {
43                 *val++ = 0;
44         }
45         *optarg = val;
46         for (; opts->name; opts++) {
47                 if (!strcmp(opts->name, token)) {
48                         if (!val) {
49                                 if (opts->has_arg & OPT_NOPARAM) {
50                                         return opts->val;
51                                 }
52                                 printf("%s: the %s option requires "
53                                        "an argument\n", caller, token);
54                                 return -EINVAL;
55                         }
56                         if (opts->has_arg & OPT_INT) {
57                                 char* v;
58
59                                 *value = strtoul(val, &v, 0);
60                                 if (!*v) {
61                                         return opts->val;
62                                 }
63                                 printf("%s: invalid numeric value "
64                                        "in %s=%s\n", caller, token, val);
65                                 return -EDOM;
66                         }
67                         if (opts->has_arg & OPT_STRING) {
68                                 return opts->val;
69                         }
70                         printf("%s: unexpected argument %s to the "
71                                "%s option\n", caller, val, token);
72                         return -EINVAL;
73                 }
74         }
75         printf("%s: Unrecognized option %s\n", caller, token);
76         return -EOPNOTSUPP;
77 }