GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-112dd97adf
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 
24 static void usage(FILE *fp, int markers);
25 static void show_options(FILE *fp, int maxlen, const char *str);
26 static 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  */
48 void G_usage(void)
49 {
50  usage(stderr, 0);
51 }
52 
53 void G__usage_text(void)
54 {
55  usage(stdout, 1);
56 }
57 
58 static 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  else if (flag->description) {
212  fprintf(fp, "%s\n", flag->description);
213  }
214 
215  flag = flag->next_flag;
216  }
217  }
218 
219  if (standard) {
220  if (new_prompt)
221  fprintf(fp, " --o %s\n",
222  _("Allow output files to overwrite existing files"));
223 
224  fprintf(fp, " --h %s\n", _("Print usage summary"));
225  fprintf(fp, " --v %s\n", _("Verbose module output"));
226  fprintf(fp, " --q %s\n", _("Quiet module output"));
227  fprintf(fp, " --qq %s\n", _("Super quiet module output"));
228  fprintf(fp, " --ui %s\n", _("Force launching GUI dialog"));
229  }
230 
231  /* Print help info for options */
232 
233  if (st->n_opts) {
234  fprintf(fp, "\n");
235  if (markers)
236  fprintf(fp, "{{{PARAMETERS}}}\n");
237  fprintf(fp, "%s\n", _("Parameters:"));
238  opt = &st->first_option;
239  while (opt != NULL) {
240  fprintf(fp, " %*s ", maxlen, opt->key);
241 
242  if (opt->label) {
243  fprintf(fp, "%s\n", opt->label);
244  if (detailed && opt->description) {
245  fprintf(fp, " %*s %s\n", maxlen, " ", opt->description);
246  }
247  }
248  else if (opt->description) {
249  fprintf(fp, "%s\n", opt->description);
250  }
251 
252  if (opt->options)
253  show_options(fp, maxlen, opt->options);
254  /*
255  fprintf (fp, " %*s options: %s\n", maxlen, " ",
256  _(opt->options)) ;
257  */
258  if (opt->def)
259  fprintf(fp, _(" %*s default: %s\n"), maxlen, " ", opt->def);
260 
261  if (detailed && opt->descs) {
262  int i = 0;
263 
264  while (opt->opts[i]) {
265  if (opt->descs[i])
266  fprintf(fp, " %*s %s: %s\n", maxlen, " ",
267  opt->opts[i], opt->descs[i]);
268 
269  i++;
270  }
271  }
272 
273  opt = opt->next_opt;
274  }
275  }
276 }
277 
278 static void show_options(FILE *fp, int maxlen, const char *str)
279 {
280  char *buff = G_store(str);
281  char *p1, *p2;
282  int totlen, len;
283 
284  fprintf(fp, _(" %*s options: "), maxlen, " ");
285  totlen = maxlen + 13;
286  p1 = buff;
287  while ((p2 = strchr(p1, ','))) {
288  *p2 = '\0';
289  len = strlen(p1) + 1;
290  if ((len + totlen) > 76) {
291  totlen = maxlen + 13;
292  fprintf(fp, "\n %*s", maxlen + 13, " ");
293  }
294  fprintf(fp, "%s,", p1);
295  totlen += len;
296  p1 = p2 + 1;
297  }
298  len = strlen(p1);
299  if ((len + totlen) > 76)
300  fprintf(fp, "\n %*s", maxlen + 13, " ");
301  fprintf(fp, "%s\n", p1);
302 
303  G_free(buff);
304 }
305 
306 static int show(FILE *fp, const char *item, int len)
307 {
308  int n;
309 
310  n = strlen(item) + (len > 0);
311  if (n + len > 76) {
312  if (len)
313  fprintf(fp, "\n ");
314  len = 0;
315  }
316  fprintf(fp, "%s", item);
317  return n + len;
318 }
#define NULL
Definition: ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
const char * G_program_name(void)
Return module name.
Definition: progrm_nme.c:28
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
#define TYPE_STRING
Definition: gis.h:186
#define FALSE
Definition: gis.h:83
#define _(str)
Definition: glocale.h:10
void G__print_keywords(FILE *fd, void(*format)(FILE *, const char *), int newline)
Print list of keywords (internal use only)
Definition: parser.c:927
int G__uses_new_gisprompt(void)
Definition: parser.c:890
struct state * st
Definition: parser.c:104
void G_usage(void)
Command line help/usage message.
Definition: parser_help.c:48
void G__usage_text(void)
Definition: parser_help.c:53
#define strcpy
Definition: parson.c:62
Structure that stores flag info.
Definition: gis.h:585
struct Flag * next_flag
Definition: gis.h:594
Structure that stores option information.
Definition: gis.h:554
const char * key
Definition: gis.h:555
struct Option * next_opt
Definition: gis.h:571
const char * key_desc
Definition: gis.h:561
const char ** opts
Definition: gis.h:560
const char * label
Definition: gis.h:562
int type
Definition: gis.h:556
const char * def
Definition: gis.h:569
const char * description
Definition: gis.h:563
int required
Definition: gis.h:557
const char ** descs
Definition: gis.h:566
const char * options
Definition: gis.h:559
int multiple
Definition: gis.h:558