1 | /* > cmdline.c |
---|
2 | * Wrapper for GNU getopt which deals with standard options |
---|
3 | * Copyright (C) 1998 Olly Betts |
---|
4 | */ |
---|
5 | |
---|
6 | #ifdef HAVE_CONFIG_H |
---|
7 | #include <config.h> |
---|
8 | #endif |
---|
9 | |
---|
10 | #include <ctype.h> |
---|
11 | #include <stdio.h> |
---|
12 | #include <string.h> |
---|
13 | |
---|
14 | #include "cmdline.h" |
---|
15 | #include "filename.h" |
---|
16 | |
---|
17 | /* It might be useful to be able to disable all long options on small |
---|
18 | * platforms like pre-386 DOS and some PDAs... |
---|
19 | */ |
---|
20 | #if 0 |
---|
21 | # define getopt_long(ARGC, ARGV, STR, OPTS, PTR) getopt(ARGC, ARGV, STR) |
---|
22 | #endif |
---|
23 | |
---|
24 | /* |
---|
25 | * bad command line give: |
---|
26 | * <problem> |
---|
27 | * |
---|
28 | * <short syntax> |
---|
29 | * |
---|
30 | * --help gives: |
---|
31 | * <version> |
---|
32 | * |
---|
33 | * <short syntax> |
---|
34 | * |
---|
35 | * <table> |
---|
36 | * |
---|
37 | * <blurb> |
---|
38 | * |
---|
39 | * --version gives: |
---|
40 | * <version> |
---|
41 | */ |
---|
42 | |
---|
43 | /* |
---|
44 | * want to cope with optional/required parameters on long options |
---|
45 | * and also parameters on short options |
---|
46 | */ |
---|
47 | |
---|
48 | static const char newline_tabs[] = "\n\t\t\t\t"; |
---|
49 | |
---|
50 | static const char *argv0 = "<program>"; |
---|
51 | |
---|
52 | static void |
---|
53 | display_help(const struct help_msg *help, const struct option *opts) |
---|
54 | { |
---|
55 | while (help->opt) { |
---|
56 | const char *longopt = 0; |
---|
57 | int opt = help->opt; |
---|
58 | const struct option *o = 0; |
---|
59 | |
---|
60 | if (HLP_ISLONG(opt)) { |
---|
61 | o = opts + HLP_DECODELONG(opt); |
---|
62 | longopt = o->name; |
---|
63 | opt = o->val; |
---|
64 | } |
---|
65 | |
---|
66 | if (isalnum(opt)) |
---|
67 | printf(" -%c,", opt); |
---|
68 | else |
---|
69 | fputs(" ", stdout); |
---|
70 | |
---|
71 | if (longopt) { |
---|
72 | int len = strlen(longopt); |
---|
73 | printf(" --%s", longopt); |
---|
74 | if (o && o->has_arg) { |
---|
75 | const char *p; |
---|
76 | len += len + 1; |
---|
77 | |
---|
78 | if (o->has_arg == optional_argument) { |
---|
79 | putchar('['); |
---|
80 | len += 2; |
---|
81 | } |
---|
82 | |
---|
83 | putchar('='); |
---|
84 | |
---|
85 | for (p = longopt; *p ; p++) putchar(toupper(*p)); |
---|
86 | |
---|
87 | if (o->has_arg == optional_argument) putchar(']'); |
---|
88 | } |
---|
89 | len = (len >> 3) + 2; |
---|
90 | if (len > 4) len = 0; |
---|
91 | fputs(newline_tabs + len, stdout); |
---|
92 | } else { |
---|
93 | fputs(newline_tabs + 1, stdout); |
---|
94 | } |
---|
95 | |
---|
96 | puts(help->msg); |
---|
97 | help++; |
---|
98 | } |
---|
99 | /* FIXME: translate */ |
---|
100 | puts(" --help\t\t\tdisplay this help and exit\n" |
---|
101 | " --version\t\t\toutput version information and exit"); |
---|
102 | |
---|
103 | exit(0); |
---|
104 | } |
---|
105 | |
---|
106 | static void |
---|
107 | display_version(void) |
---|
108 | { |
---|
109 | printf("%s - "PACKAGE" "VERSION"\n", argv0); |
---|
110 | } |
---|
111 | |
---|
112 | static void |
---|
113 | display_syntax(void) |
---|
114 | { |
---|
115 | printf("\nSyntax: %s [OPTION]... [FILE]...\n", argv0); |
---|
116 | } |
---|
117 | |
---|
118 | extern int |
---|
119 | my_getopt_long(int argc, char *const *argv, const char *shortopts, |
---|
120 | const struct option *longopts, int *longind, |
---|
121 | const struct help_msg *help, int min_args) |
---|
122 | { |
---|
123 | int opt; |
---|
124 | |
---|
125 | argv0 = argv[0]; /* FIXME: tidy up argv0 (remove path and extension) */ |
---|
126 | |
---|
127 | opt = getopt_long(argc, argv, shortopts, longopts, longind); |
---|
128 | |
---|
129 | if (opt == EOF) { |
---|
130 | /* check minimum # of args given - if not give help message */ |
---|
131 | if (argc - optind < min_args) opt = HLP_HELP; |
---|
132 | } |
---|
133 | |
---|
134 | switch (opt) { |
---|
135 | case ':': /* parameter missing */ |
---|
136 | case '?': /* unknown opt, ambiguous match, or extraneous param */ |
---|
137 | /* getopt displays a message for us (unless we set opterr to 0) */ |
---|
138 | display_syntax(); |
---|
139 | exit(0); |
---|
140 | case HLP_VERSION: /* --version */ |
---|
141 | display_version(); |
---|
142 | exit(0); |
---|
143 | case HLP_HELP: /* --help */ |
---|
144 | display_version(); |
---|
145 | display_syntax(); |
---|
146 | putchar('\n'); |
---|
147 | display_help(help, longopts); |
---|
148 | exit(0); |
---|
149 | } |
---|
150 | return opt; |
---|
151 | } |
---|