GRASS GIS 8 Programmer's Manual 8.2.1RC1(2022)-exported
parser_help.c
Go to the documentation of this file.
1/*!
2 \file lib/gis/parser_help.c
3
4 \brief GIS Library - Argument parsing functions (help)
5
6 (C) 2001-2009, 2011 by the GRASS Development Team
7
8 This program is free software under the GNU General Public License
9 (>=v2). Read the file COPYING that comes with GRASS for details.
10
11 \author Original author CERL
12 \author Soeren Gebbert added Dec. 2009 WPS process_description document
13*/
14
15#include <stdio.h>
16#include <string.h>
17#include <stdlib.h>
18
19#include <grass/gis.h>
20#include <grass/glocale.h>
21
22#include "parser_local_proto.h"
23
24static void usage(FILE *fp, int markers);
25static void show_options(FILE *fp, int maxlen, const char *str);
26static int show(FILE *fp, const char *item, int len);
27
28/*!
29 \brief Command line help/usage message.
30
31 Calls to G_usage() allow the programmer to print the usage
32 message at any time. This will explain the allowed and required
33 command line input to the user. This description is given according
34 to the programmer's definitions for options and flags. This function
35 becomes useful when the user enters options and/or flags on the
36 command line that are syntactically valid to the parser, but
37 functionally invalid for the command (e.g. an invalid file name.)
38
39 For example, the parser logic doesn't directly support grouping
40 options. If two options be specified together or not at all, the
41 parser must be told that these options are not required and the
42 programmer must check that if one is specified the other must be as
43 well. If this additional check fails, then G_parser() will succeed,
44 but the programmer can then call G_usage() to print the standard
45 usage message and print additional information about how the two
46 options work together.
47*/
48void G_usage(void)
49{
50 usage(stderr, 0);
51}
52
53void G__usage_text(void)
54{
55 usage(stdout, 1);
56}
57
58static void usage(FILE *fp, int markers)
59{
60 struct Option *opt;
61 struct Flag *flag;
62 char item[256];
63 const char *key_desc;
64 int maxlen;
65 int len, n;
66 int new_prompt = 0;
67 int extensive = 0; /* include also less important parts */
68 int standard = 0; /* include also standard flags */
69 int detailed = 0; /* details for each flag and option */
70
71 new_prompt = G__uses_new_gisprompt();
72
73 if (!st->pgm_name) /* v.dave && r.michael */
74 st->pgm_name = G_program_name();
75 if (!st->pgm_name)
76 st->pgm_name = "??";
77
78 if (st->module_info.label || st->module_info.description) {
79 if (extensive)
80 fprintf(fp, "\n");
81 if (markers)
82 fprintf(fp, "{{{DESCRIPTION}}}\n");
83 if (extensive) {
84 fprintf(fp, "%s\n", _("Description:"));
85 if (st->module_info.label)
86 fprintf(fp, " %s\n", st->module_info.label);
87 if (st->module_info.description)
88 fprintf(fp, " %s\n", st->module_info.description);
89 }
90 else {
91 /* print label, if no label, try description */
92 /* no leading space without heading */
93 if (st->module_info.label)
94 fprintf(fp, "%s\n", st->module_info.label);
95 else if (st->module_info.description)
96 fprintf(fp, "%s\n", st->module_info.description);
97 }
98 }
99 if (extensive && st->module_info.keywords) {
100 fprintf(fp, "\n");
101 if (markers)
102 fprintf(fp, "{{{KEYWORDS}}}\n");
103 fprintf(fp, "%s\n ", _("Keywords:"));
105 fprintf(fp, "\n");
106 }
107
108 fprintf(fp, "\n");
109 if (markers)
110 fprintf(fp, "{{{USAGE}}}\n");
111 fprintf(fp, "%s\n ", _("Usage:"));
112
113 len = show(fp, st->pgm_name, 1);
114
115 /* Print flags */
116
117 if (st->n_flags) {
118 item[0] = ' ';
119 item[1] = '[';
120 item[2] = '-';
121 flag = &st->first_flag;
122 for (n = 3; flag != NULL; n++, flag = flag->next_flag)
123 item[n] = flag->key;
124 item[n++] = ']';
125 item[n] = 0;
126 len = show(fp, item, len);
127 }
128
129 maxlen = 0;
130 if (st->n_opts) {
131 opt = &st->first_option;
132 while (opt != NULL) {
133 if (opt->key_desc != NULL)
134 key_desc = opt->key_desc;
135 else if (opt->type == TYPE_STRING)
136 key_desc = "string";
137 else
138 key_desc = "value";
139
140 if (!opt->key) {
141 fprintf(stderr, "\n%s\n", _("ERROR: Option key not defined"));
142 exit(EXIT_FAILURE);
143 }
144 n = strlen(opt->key);
145 if (n > maxlen)
146 maxlen = n;
147
148 strcpy(item, " ");
149 if (!opt->required)
150 strcat(item, "[");
151 strcat(item, opt->key);
152 strcat(item, "=");
153 strcat(item, key_desc);
154 if (opt->multiple) {
155 strcat(item, "[,");
156 strcat(item, key_desc);
157 strcat(item, ",...]");
158 }
159 if (!opt->required)
160 strcat(item, "]");
161
162 len = show(fp, item, len);
163
164 opt = opt->next_opt;
165 }
166 }
167 if (new_prompt) {
168 strcpy(item, " [--overwrite]");
169 len = show(fp, item, len);
170 }
171
172 strcpy(item, " [--help]");
173 len = show(fp, item, len);
174
175 strcpy(item, " [--verbose]");
176 len = show(fp, item, len);
177
178 strcpy(item, " [--quiet]");
179 len = show(fp, item, len);
180
181 strcpy(item, " [--ui]");
182 len = show(fp, item, len);
183
184 fprintf(fp, "\n");
185
186 /* Print help info for flags */
187
188 /* Show section only when there are flags.
189 * There are always the standard flags if we are printing those.
190 * There is no use case for the markers, so no way to decide if
191 * the marker for flags is mandatory and should be empty if it is
192 * okay for it to be missing like in the current implementation.
193 */
194 if (st->n_flags || standard) {
195 fprintf(fp, "\n");
196 if (markers)
197 fprintf(fp, "{{{FLAGS}}}\n");
198 fprintf(fp, "%s\n", _("Flags:"));
199 }
200
201 if (st->n_flags) {
202 flag = &st->first_flag;
203 while (flag != NULL) {
204 fprintf(fp, " -%c ", flag->key);
205
206 if (flag->label) {
207 fprintf(fp, "%s\n", flag->label);
208 if (detailed && flag->description)
209 fprintf(fp, " %s\n", flag->description);
210
211 }
212 else if (flag->description) {
213 fprintf(fp, "%s\n", flag->description);
214 }
215
216 flag = flag->next_flag;
217 }
218 }
219
220 if (standard) {
221 if (new_prompt)
222 fprintf(fp, " --o %s\n",
223 _("Allow output files to overwrite existing files"));
224
225 fprintf(fp, " --h %s\n", _("Print usage summary"));
226 fprintf(fp, " --v %s\n", _("Verbose module output"));
227 fprintf(fp, " --q %s\n", _("Quiet module output"));
228 fprintf(fp, " --qq %s\n", _("Super quiet module output"));
229 fprintf(fp, " --ui %s\n", _("Force launching GUI dialog"));
230 }
231
232 /* Print help info for options */
233
234 if (st->n_opts) {
235 fprintf(fp, "\n");
236 if (markers)
237 fprintf(fp, "{{{PARAMETERS}}}\n");
238 fprintf(fp, "%s\n", _("Parameters:"));
239 opt = &st->first_option;
240 while (opt != NULL) {
241 fprintf(fp, " %*s ", maxlen, opt->key);
242
243 if (opt->label) {
244 fprintf(fp, "%s\n", opt->label);
245 if (detailed && opt->description) {
246 fprintf(fp, " %*s %s\n",
247 maxlen, " ", opt->description);
248 }
249 }
250 else if (opt->description) {
251 fprintf(fp, "%s\n", opt->description);
252 }
253
254 if (opt->options)
255 show_options(fp, maxlen, opt->options);
256 /*
257 fprintf (fp, " %*s options: %s\n", maxlen, " ",
258 _(opt->options)) ;
259 */
260 if (opt->def)
261 fprintf(fp, _(" %*s default: %s\n"), maxlen, " ",
262 opt->def);
263
264 if (detailed && opt->descs) {
265 int i = 0;
266
267 while (opt->opts[i]) {
268 if (opt->descs[i])
269 fprintf(fp, " %*s %s: %s\n",
270 maxlen, " ", opt->opts[i], opt->descs[i]);
271
272 i++;
273 }
274 }
275
276 opt = opt->next_opt;
277 }
278 }
279}
280
281static void show_options(FILE *fp, int maxlen, const char *str)
282{
283 char *buff = G_store(str);
284 char *p1, *p2;
285 int totlen, len;
286
287 fprintf(fp, _(" %*s options: "), maxlen, " ");
288 totlen = maxlen + 13;
289 p1 = buff;
290 while ((p2 = strchr(p1, ','))) {
291 *p2 = '\0';
292 len = strlen(p1) + 1;
293 if ((len + totlen) > 76) {
294 totlen = maxlen + 13;
295 fprintf(fp, "\n %*s", maxlen + 13, " ");
296 }
297 fprintf(fp, "%s,", p1);
298 totlen += len;
299 p1 = p2 + 1;
300 }
301 len = strlen(p1);
302 if ((len + totlen) > 76)
303 fprintf(fp, "\n %*s", maxlen + 13, " ");
304 fprintf(fp, "%s\n", p1);
305
306 G_free(buff);
307}
308
309static int show(FILE *fp, const char *item, int len)
310{
311 int n;
312
313 n = strlen(item) + (len > 0);
314 if (n + len > 76) {
315 if (len)
316 fprintf(fp, "\n ");
317 len = 0;
318 }
319 fprintf(fp, "%s", item);
320 return n + len;
321}
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
#define NULL
Definition: ccmath.h:32
int G__uses_new_gisprompt(void)
Definition: parser.c:874
struct state * st
Definition: parser.c:104
void G__print_keywords(FILE *fd, void(*format)(FILE *, const char *))
Print list of keywords (internal use only)
Definition: parser.c:910
void G_usage(void)
Command line help/usage message.
Definition: parser_help.c:48
void G__usage_text(void)
Definition: parser_help.c:53
const char * G_program_name(void)
Return module name.
Definition: progrm_nme.c:28
char * G_store(const char *s)
Copy string to allocated memory.
Definition: strings.c:87