Mercurial > hg > index.cgi
comparison lwlib/lw_cmdline.c @ 6:1e5e8ec406fb
Various output cleanups for --help and --usage in lw_cmdline
author | lost@l-w.ca |
---|---|
date | Sat, 22 Jan 2011 09:31:43 -0700 |
parents | 0e01d1343c02 |
children | fdc11ef4115b |
comparison
equal
deleted
inserted
replaced
5:0e01d1343c02 | 6:1e5e8ec406fb |
---|---|
26 #include "lw_alloc.h" | 26 #include "lw_alloc.h" |
27 | 27 |
28 #define ___lw_cmdline_c_seen___ | 28 #define ___lw_cmdline_c_seen___ |
29 #include "lw_cmdline.h" | 29 #include "lw_cmdline.h" |
30 | 30 |
31 #define DOCCOL 30 | |
32 #define LLEN 78 | |
33 | |
31 static struct lw_cmdline_options builtin[3] = | 34 static struct lw_cmdline_options builtin[3] = |
32 { | 35 { |
33 { "help", '?', 0, 0, "give this help list" }, | 36 { "help", '?', 0, 0, "give this help list" }, |
34 { "usage", 0, 0, 0, "give a short usage message" }, | 37 { "usage", 0, 0, 0, "give a short usage message" }, |
35 { "version", 'V', 0, 0, "print program version" } | 38 { "version", 'V', 0, 0, "print program version" } |
36 }; | 39 }; |
37 | 40 |
41 static int cmpr(const void *e1, const void *e2) | |
42 { | |
43 struct lw_cmdline_options **o1, **o2; | |
44 o1 = (struct lw_cmdline_options **)e1; | |
45 o2 = (struct lw_cmdline_options **)e2; | |
46 | |
47 return strcmp((*o1) -> name, (*o2) -> name); | |
48 } | |
49 | |
50 static int cmpr2(const void *e1, const void *e2) | |
51 { | |
52 struct lw_cmdline_options **o1, **o2; | |
53 o1 = (struct lw_cmdline_options **)e1; | |
54 o2 = (struct lw_cmdline_options **)e2; | |
55 | |
56 if ((*o1) -> key < ((*o2) -> key)) | |
57 return -1; | |
58 if ((*o1) -> key > ((*o2) -> key)) | |
59 return 1; | |
60 return 0; | |
61 } | |
62 | |
38 static void lw_cmdline_usage(struct lw_cmdline_parser *parser, char *name) | 63 static void lw_cmdline_usage(struct lw_cmdline_parser *parser, char *name) |
39 { | 64 { |
40 struct lw_cmdline_options **slist, **llist; | 65 struct lw_cmdline_options **slist, **llist; |
41 int nopt; | 66 int nopt; |
42 int i; | 67 int i; |
43 int t; | 68 int t; |
44 | 69 int col; |
70 | |
45 for (nopt = 0; parser -> options[nopt].name; nopt++) | 71 for (nopt = 0; parser -> options[nopt].name; nopt++) |
46 /* do nothing */ ; | 72 /* do nothing */ ; |
47 | 73 |
48 slist = lw_alloc(sizeof(struct lw_cmdline_options *) * (nopt + 3)); | 74 slist = lw_alloc(sizeof(struct lw_cmdline_options *) * (nopt + 3)); |
49 llist = lw_alloc(sizeof(struct lw_cmdline_options *) * (nopt + 3)); | 75 llist = lw_alloc(sizeof(struct lw_cmdline_options *) * (nopt + 3)); |
53 slist[i] = &(parser -> options[i]); | 79 slist[i] = &(parser -> options[i]); |
54 llist[i] = &(parser -> options[i]); | 80 llist[i] = &(parser -> options[i]); |
55 } | 81 } |
56 | 82 |
57 /* now sort the two lists */ | 83 /* now sort the two lists */ |
84 qsort(slist, nopt, sizeof(struct lw_cmdline_options *), cmpr2); | |
85 qsort(llist, nopt, sizeof(struct lw_cmdline_options *), cmpr); | |
58 | 86 |
59 /* now append the automatic options */ | 87 /* now append the automatic options */ |
60 slist[nopt] = &(builtin[0]); | 88 slist[nopt] = &(builtin[0]); |
61 slist[nopt + 1] = &(builtin[1]); | 89 slist[nopt + 1] = &(builtin[1]); |
62 slist[nopt + 2] = &(builtin[2]); | 90 slist[nopt + 2] = &(builtin[2]); |
66 llist[nopt + 2] = &(builtin[2]); | 94 llist[nopt + 2] = &(builtin[2]); |
67 | 95 |
68 /* now show the usage message */ | 96 /* now show the usage message */ |
69 printf("Usage: %s", name); | 97 printf("Usage: %s", name); |
70 | 98 |
99 col = 7 + strlen(name); | |
100 | |
71 /* print short options that take no args */ | 101 /* print short options that take no args */ |
72 t = 0; | 102 t = 0; |
73 for (i = 0; i < nopt + 3; i++) | 103 for (i = 0; i < nopt + 3; i++) |
74 { | 104 { |
75 if (slist[i]->key > 0x20 && slist[i]->key < 0x7f) | 105 if (slist[i]->key > 0x20 && slist[i]->key < 0x7f) |
78 { | 108 { |
79 if (!t) | 109 if (!t) |
80 { | 110 { |
81 printf(" [-"); | 111 printf(" [-"); |
82 t = 1; | 112 t = 1; |
113 col += 3; | |
83 } | 114 } |
84 printf("%c", slist[i]->key); | 115 printf("%c", slist[i]->key); |
116 col++; | |
85 } | 117 } |
86 } | 118 } |
87 } | 119 } |
88 if (t) | 120 if (t) |
121 { | |
122 col++; | |
89 printf("]"); | 123 printf("]"); |
124 } | |
90 | 125 |
91 /* print short options that take args */ | 126 /* print short options that take args */ |
92 for (i = 0; i < nopt + 3; i++) | 127 for (i = 0; i < nopt + 3; i++) |
93 { | 128 { |
94 if (slist[i]->key > 0x20 && slist[i]->key < 0x7f && slist[i] -> arg) | 129 if (slist[i]->key > 0x20 && slist[i]->key < 0x7f && slist[i] -> arg) |
95 { | 130 { |
96 if (slist[i]->flags & lw_cmdline_opt_optional) | 131 if (slist[i]->flags & lw_cmdline_opt_optional) |
97 { | 132 { |
133 t = 7 + strlen(slist[i] -> arg); | |
134 if (col + t > LLEN) | |
135 { | |
136 printf("\n "); | |
137 col = 7; | |
138 } | |
98 printf(" [-%c[%s]]", slist[i]->key, slist[i]->arg); | 139 printf(" [-%c[%s]]", slist[i]->key, slist[i]->arg); |
140 col += t; | |
99 } | 141 } |
100 else | 142 else |
101 { | 143 { |
144 t = 6 + strlen(slist[i] -> arg); | |
145 if (col + t > LLEN) | |
146 { | |
147 printf("\n "); | |
148 col = 7; | |
149 } | |
102 printf(" [-%c %s]", slist[i]->key, slist[i]->arg); | 150 printf(" [-%c %s]", slist[i]->key, slist[i]->arg); |
151 col += t; | |
103 } | 152 } |
104 } | 153 } |
105 } | 154 } |
106 | 155 |
107 /* print long options */ | 156 /* print long options */ |
108 for (i = 0; i < nopt + 3; i++) | 157 for (i = 0; i < nopt + 3; i++) |
109 { | 158 { |
110 if (llist[i]->arg) | 159 if (llist[i]->arg) |
111 { | 160 { |
112 printf(" [--%s=%s%s%s]", | 161 t = strlen(llist[i] -> name) + 6 + strlen(llist[i] -> arg); |
162 if (llist[i] -> flags & lw_cmdline_opt_optional) | |
163 t += 2; | |
164 if (col + t > LLEN) | |
165 { | |
166 printf("\n "); | |
167 col = 7; | |
168 } | |
169 printf(" [--%s%s=%s%s]", | |
113 llist[i] -> name, | 170 llist[i] -> name, |
114 (llist[i] -> flags & lw_cmdline_opt_optional) ? "[" : "", | 171 (llist[i] -> flags & lw_cmdline_opt_optional) ? "[" : "", |
115 llist[i] -> arg, | 172 llist[i] -> arg, |
116 (llist[i] -> flags & lw_cmdline_opt_optional) ? "]" : ""); | 173 (llist[i] -> flags & lw_cmdline_opt_optional) ? "]" : ""); |
174 col += t; | |
117 } | 175 } |
118 else | 176 else |
119 { | 177 { |
178 t = strlen(llist[i] -> name) + 5; | |
179 if (col + t > LLEN) | |
180 { | |
181 printf("\n "); | |
182 col = 7; | |
183 } | |
120 printf(" [--%s]", llist[i] -> name); | 184 printf(" [--%s]", llist[i] -> name); |
185 col += t; | |
121 } | 186 } |
122 } | 187 } |
123 | 188 |
124 /* print "non option" text */ | 189 /* print "non option" text */ |
125 if (parser -> args_doc) | 190 if (parser -> args_doc) |
126 { | 191 { |
192 if (col + strlen(parser -> args_doc) + 1 > LLEN) | |
193 { | |
194 printf("\n "); | |
195 } | |
127 printf(" %s", parser -> args_doc); | 196 printf(" %s", parser -> args_doc); |
128 } | 197 } |
129 printf("\n"); | 198 printf("\n"); |
130 | 199 |
131 /* clean up scratch lists */ | 200 /* clean up scratch lists */ |
138 struct lw_cmdline_options **llist; | 207 struct lw_cmdline_options **llist; |
139 int nopt; | 208 int nopt; |
140 int i; | 209 int i; |
141 int t; | 210 int t; |
142 char *tstr; | 211 char *tstr; |
212 int col = 0; | |
143 | 213 |
144 tstr = parser -> doc; | 214 tstr = parser -> doc; |
145 for (nopt = 0; parser -> options[nopt].name; nopt++) | 215 for (nopt = 0; parser -> options[nopt].name; nopt++) |
146 /* do nothing */ ; | 216 /* do nothing */ ; |
147 | 217 |
151 { | 221 { |
152 llist[i] = &(parser -> options[i]); | 222 llist[i] = &(parser -> options[i]); |
153 } | 223 } |
154 | 224 |
155 /* now sort the list */ | 225 /* now sort the list */ |
226 qsort(llist, nopt, sizeof(struct lw_cmdline_options *), cmpr); | |
156 | 227 |
157 /* now append the automatic options */ | 228 /* now append the automatic options */ |
158 llist[nopt] = &(builtin[0]); | 229 llist[nopt] = &(builtin[0]); |
159 llist[nopt + 1] = &(builtin[1]); | 230 llist[nopt + 1] = &(builtin[1]); |
160 llist[nopt + 2] = &(builtin[2]); | 231 llist[nopt + 2] = &(builtin[2]); |
180 } | 251 } |
181 else | 252 else |
182 { | 253 { |
183 printf(" "); | 254 printf(" "); |
184 } | 255 } |
256 col = 8 + strlen(llist[i] -> name); | |
185 | 257 |
186 printf("--%s", llist[i] -> name); | 258 printf("--%s", llist[i] -> name); |
187 if (llist[i] -> arg) | 259 if (llist[i] -> arg) |
188 { | 260 { |
189 if (llist[i] -> flags & lw_cmdline_opt_optional) | 261 if (llist[i] -> flags & lw_cmdline_opt_optional) |
190 { | 262 { |
191 printf("[=%s]", llist[i] -> arg); | 263 printf("[=%s]", llist[i] -> arg); |
264 col += 3 + strlen(llist[i] -> arg); | |
192 } | 265 } |
193 else | 266 else |
194 { | 267 { |
195 printf("=%s", llist[i] -> arg); | 268 printf("=%s", llist[i] -> arg); |
269 col += 1 + strlen(llist[i] -> arg); | |
196 } | 270 } |
197 } | 271 } |
198 if (llist[i] -> doc) | 272 if (llist[i] -> doc) |
199 { | 273 { |
200 printf("\t\t%s", llist[i] -> doc); | 274 char *s = llist[i] -> doc; |
275 char *s2; | |
276 | |
277 while (*s && isspace(*s)) | |
278 s++; | |
279 | |
280 if (col > DOCCOL) | |
281 { | |
282 fputc('\n', stdout); | |
283 col = 0; | |
284 } | |
285 while (*s) | |
286 { | |
287 while (col < (DOCCOL - 1)) | |
288 { | |
289 fputc(' ', stdout); | |
290 col++; | |
291 } | |
292 for (s2 = s; *s2 && !isspace(*s2); s2++) | |
293 /* do nothing */ ; | |
294 if ((col + (s2 - s) + 1) > LLEN && col >= DOCCOL) | |
295 { | |
296 /* next line */ | |
297 fputc('\n', stdout); | |
298 col = 0; | |
299 continue; | |
300 } | |
301 col++; | |
302 fputc(' ', stdout); | |
303 while (s != s2) | |
304 { | |
305 fputc(*s, stdout); | |
306 col++; | |
307 s++; | |
308 } | |
309 while (*s && isspace(*s)) | |
310 s++; | |
311 } | |
201 } | 312 } |
202 fputc('\n', stdout); | 313 fputc('\n', stdout); |
203 } | 314 } |
204 | 315 |
205 printf("\nMandatory or optional arguments to long options are also mandatory or optional\nfor any corresponding short options.\n"); | 316 printf("\nMandatory or optional arguments to long options are also mandatory or optional\nfor any corresponding short options.\n"); |