GRASS GIS 7 Programmer's Manual  7.9.dev(2020)-f4bc66038
parser.c
Go to the documentation of this file.
1 /*!
2  * \file lib/gis/parser.c
3  *
4  * \brief GIS Library - Argument parsing functions.
5  *
6  * Parses the command line provided through argc and argv. Example:
7  * Assume the previous calls:
8  *
9  \code
10  opt1 = G_define_option() ;
11  opt1->key = "map",
12  opt1->type = TYPE_STRING,
13  opt1->required = YES,
14  opt1->checker = sub,
15  opt1->description= "Name of an existing raster map" ;
16 
17  opt2 = G_define_option() ;
18  opt2->key = "color",
19  opt2->type = TYPE_STRING,
20  opt2->required = NO,
21  opt2->answer = "white",
22  opt2->options = "red,orange,blue,white,black",
23  opt2->description= "Color used to display the map" ;
24 
25  opt3 = G_define_option() ;
26  opt3->key = "number",
27  opt3->type = TYPE_DOUBLE,
28  opt3->required = NO,
29  opt3->answer = "12345.67",
30  opt3->options = "0-99999",
31  opt3->description= "Number to test parser" ;
32  \endcode
33  *
34  * G_parser() will respond to the following command lines as described:
35  *
36  \verbatim
37  command (No command line arguments)
38  \endverbatim
39  * Parser enters interactive mode.
40  *
41  \verbatim
42  command map=map.name
43  \endverbatim
44  * Parser will accept this line. Map will be set to "map.name", the
45  * 'a' and 'b' flags will remain off and the num option will be set
46  * to the default of 5.
47  *
48  \verbatim
49  command -ab map=map.name num=9
50  command -a -b map=map.name num=9
51  command -ab map.name num=9
52  command map.name num=9 -ab
53  command num=9 -a map=map.name -b
54  \endverbatim
55  * These are all treated as acceptable and identical. Both flags are
56  * set to on, the map option is "map.name" and the num option is "9".
57  * Note that the "map=" may be omitted from the command line if it
58  * is part of the first option (flags do not count).
59  *
60  \verbatim
61  command num=12
62  \endverbatim
63  * This command line is in error in two ways. The user will be told
64  * that the "map" option is required and also that the number 12 is
65  * out of range. The acceptable range (or list) will be printed.
66  *
67  * Overview table: <a href="parser_standard_options.html">Parser standard options</a>
68  *
69  * (C) 2001-2015 by the GRASS Development Team
70  *
71  * This program is free software under the GNU General Public License
72  * (>=v2). Read the file COPYING that comes with GRASS for details.
73  *
74  * \author Original author CERL
75  * \author Soeren Gebbert added Dec. 2009 WPS process_description document
76  */
77 
78 #include <stdio.h>
79 #include <stdlib.h>
80 #include <string.h>
81 #include <unistd.h>
82 
83 #include <grass/gis.h>
84 #include <grass/spawn.h>
85 #include <grass/glocale.h>
86 
87 #include "parser_local_proto.h"
88 
89 enum opt_error {
93  AMBIGUOUS = 4,
95 };
96 
97 
98 #define MAX_MATCHES 50
99 
100 /* initialize the global struct */
101 struct state state;
102 struct state *st = &state;
103 
104 /* local prototypes */
105 static void set_flag(int);
106 static int contains(const char *, int);
107 static int valid_option_name(const char *);
108 static int is_option(const char *);
109 static int match_option_1(const char *, const char *);
110 static int match_option(const char *, const char *);
111 static void set_option(const char *);
112 static void check_opts(void);
113 static void check_an_opt(const char *, int, const char *, const char **, char **);
114 static int check_int(const char *, const char **);
115 static int check_double(const char *, const char **);
116 static int check_string(const char *, const char **, int *);
117 static void check_required(void);
118 static void split_opts(void);
119 static void check_multiple_opts(void);
120 static int check_overwrite(void);
121 static void define_keywords(void);
122 static int module_gui_wx(void);
123 static void append_error(const char *);
124 static const char *get_renamed_option(const char *);
125 
126 /*!
127  * \brief Disables the ability of the parser to operate interactively.
128  *
129  * When a user calls a command with no arguments on the command line,
130  * the parser will enter its own standardized interactive session in
131  * which all flags and options are presented to the user for input. A
132  * call to G_disable_interactive() disables the parser's interactive
133  * prompting.
134  *
135  */
136 
138 {
139  st->no_interactive = 1;
140 }
141 
142 /*!
143  * \brief Initializes a Flag struct.
144  *
145  * Allocates memory for the Flag structure and returns a pointer to
146  * this memory.
147  *
148  * Flags are always represented by single letters. A user "turns them
149  * on" at the command line using a minus sign followed by the
150  * character representing the flag.
151  *
152  * \return Pointer to a Flag struct
153  */
154 struct Flag *G_define_flag(void)
155 {
156  struct Flag *flag;
157  struct Item *item;
158 
159  /* Allocate memory if not the first flag */
160 
161  if (st->n_flags) {
162  flag = G_malloc(sizeof(struct Flag));
163  st->current_flag->next_flag = flag;
164  }
165  else
166  flag = &st->first_flag;
167 
168  /* Zero structure */
169 
170  G_zero(flag, sizeof(struct Flag));
171 
172  st->current_flag = flag;
173  st->n_flags++;
174 
175  if (st->n_items) {
176  item = G_malloc(sizeof(struct Item));
177  st->current_item->next_item = item;
178  }
179  else
180  item = &st->first_item;
181 
182  G_zero(item, sizeof(struct Item));
183 
184  item->flag = flag;
185  item->option = NULL;
186 
187  st->current_item = item;
188  st->n_items++;
189 
190  return (flag);
191 }
192 
193 /*!
194  * \brief Initializes an Option struct.
195  *
196  * Allocates memory for the Option structure and returns a pointer to
197  * this memory.
198  *
199  * Options are provided by user on command line using the standard
200  * format: <i>key=value</i>. Options identified as REQUIRED must be
201  * specified by user on command line. The option string can either
202  * specify a range of values (e.g. "10-100") or a list of acceptable
203  * values (e.g. "red,orange,yellow"). Unless the option string is
204  * NULL, user provided input will be evaluated against this string.
205  *
206  * \return pointer to an Option struct
207  */
208 struct Option *G_define_option(void)
209 {
210  struct Option *opt;
211  struct Item *item;
212 
213  /* Allocate memory if not the first option */
214 
215  if (st->n_opts) {
216  opt = G_malloc(sizeof(struct Option));
217  st->current_option->next_opt = opt;
218  }
219  else
220  opt = &st->first_option;
221 
222  /* Zero structure */
223  G_zero(opt, sizeof(struct Option));
224 
225  opt->required = NO;
226  opt->multiple = NO;
227 
228  st->current_option = opt;
229  st->n_opts++;
230 
231  if (st->n_items) {
232  item = G_malloc(sizeof(struct Item));
233  st->current_item->next_item = item;
234  }
235  else
236  item = &st->first_item;
237 
238  G_zero(item, sizeof(struct Item));
239 
240  item->option = opt;
241 
242  st->current_item = item;
243  st->n_items++;
244 
245  return (opt);
246 }
247 
248 /*!
249  * \brief Initializes a new module.
250  *
251  * \return pointer to a GModule struct
252  */
254 {
255  struct GModule *module;
256 
257  /* Allocate memory */
258  module = &st->module_info;
259 
260  /* Zero structure */
261  G_zero(module, sizeof(struct GModule));
262 
263  /* Allocate keywords array */
264  define_keywords();
265 
266  return (module);
267 }
268 
269 /*!
270  * \brief Parse command line.
271  *
272  * The command line parameters <i>argv</i> and the number of
273  * parameters <i>argc</i> from the main() routine are passed directly
274  * to G_parser(). G_parser() accepts the command line input entered by
275  * the user, and parses this input according to the input options
276  * and/or flags that were defined by the programmer.
277  *
278  * <b>Note:</b> The only functions which can legitimately be called
279  * before G_parser() are:
280  *
281  * - G_gisinit()
282  * - G_no_gisinit()
283  * - G_define_module()
284  * - G_define_flag()
285  * - G_define_option()
286  * - G_define_standard_flag()
287  * - G_define_standard_option()
288  * - G_disable_interactive()
289  * - G_option_exclusive()
290  * - G_option_required()
291  * - G_option_requires()
292  * - G_option_requires_all()
293  * - G_option_excludes()
294  * - G_option_collective()
295  *
296  * The usual order a module calls functions is:
297  *
298  * 1. G_gisinit()
299  * 2. G_define_module()
300  * 3. G_define_standard_flag()
301  * 4. G_define_standard_option()
302  * 5. G_define_flag()
303  * 6. G_define_option()
304  * 7. G_option_exclusive()
305  * 8. G_option_required()
306  * 9. G_option_requires()
307  * 10. G_option_requires_all()
308  * 11. G_option_excludes()
309  * 12. G_option_collective()
310  * 13. G_parser()
311  *
312  * \param argc number of arguments
313  * \param argv argument list
314  *
315  * \return 0 on success
316  * \return -1 on error and calls G_usage()
317  */
318 int G_parser(int argc, char **argv)
319 {
320  int need_first_opt;
321  int opt_checked = 0;
322  const char *gui_envvar;
323  char *ptr, *tmp_name, *err;
324  int i;
325  struct Option *opt;
326  char force_gui = FALSE;
327  int print_json = 0;
328 
329  err = NULL;
330  need_first_opt = 1;
331  tmp_name = G_store(argv[0]);
332  st->pgm_path = tmp_name;
333  st->n_errors = 0;
334  st->error = NULL;
335  st->module_info.verbose = G_verbose_std();
336  i = strlen(tmp_name);
337  while (--i >= 0) {
338  if (G_is_dirsep(tmp_name[i])) {
339  tmp_name += i + 1;
340  break;
341  }
342  }
343  G_basename(tmp_name, "exe");
344  st->pgm_name = tmp_name;
345 
346  if (!st->module_info.label && !st->module_info.description)
347  G_warning(_("Bug in UI description. Missing module description"));
348 
349  /* Stash default answers */
350 
351  opt = &st->first_option;
352  while (st->n_opts && opt) {
353  if (opt->required)
354  st->has_required = 1;
355 
356  if (!opt->key)
357  G_warning(_("Bug in UI description. Missing option key"));
358  if (!valid_option_name(opt->key))
359  G_warning(_("Bug in UI description. Option key <%s> is not valid"), opt->key);
360  if (!opt->label && !opt->description)
361  G_warning(_("Bug in UI description. Description for option <%s> missing"), opt->key ? opt->key : "?");
362 
363  /* Parse options */
364  if (opt->options) {
365  int cnt = 0;
366  char **tokens, delm[2];
367 
368  delm[0] = ',';
369  delm[1] = '\0';
370  tokens = G_tokenize(opt->options, delm);
371 
372  i = 0;
373  while (tokens[i]) {
374  G_chop(tokens[i]);
375  cnt++;
376  i++;
377  }
378 
379  opt->opts = G_calloc(cnt + 1, sizeof(const char *));
380 
381  i = 0;
382  while (tokens[i]) {
383  opt->opts[i] = G_store(tokens[i]);
384  i++;
385  }
386  G_free_tokens(tokens);
387 
388  if (opt->descriptions) {
389  delm[0] = ';';
390 
391  opt->descs = G_calloc(cnt + 1, sizeof(const char *));
392  tokens = G_tokenize(opt->descriptions, delm);
393 
394  i = 0;
395  while (tokens[i]) {
396  int j, found;
397 
398  if (!tokens[i + 1])
399  break;
400 
401  G_chop(tokens[i]);
402 
403  j = 0;
404  found = 0;
405  while (opt->opts[j]) {
406  if (strcmp(opt->opts[j], tokens[i]) == 0) {
407  found = 1;
408  break;
409  }
410  j++;
411  }
412  if (!found) {
413  G_warning(_("Bug in UI description. Option '%s' in <%s> does not exist"),
414  tokens[i], opt->key);
415  }
416  else {
417  opt->descs[j] = G_store(tokens[i + 1]);
418  }
419 
420  i += 2;
421  }
422  G_free_tokens(tokens);
423  }
424  }
425 
426  /* Copy answer */
427  if (opt->multiple && opt->answers && opt->answers[0]) {
428  opt->answer = G_malloc(strlen(opt->answers[0]) + 1);
429  strcpy(opt->answer, opt->answers[0]);
430  for (i = 1; opt->answers[i]; i++) {
431  opt->answer = G_realloc(opt->answer,
432  strlen(opt->answer) +
433  strlen(opt->answers[i]) + 2);
434  strcat(opt->answer, ",");
435  strcat(opt->answer, opt->answers[i]);
436  }
437  }
438  opt->def = opt->answer;
439  opt = opt->next_opt;
440  }
441 
442  /* If there are NO arguments, go interactive */
443  gui_envvar = G_getenv_nofatal("GUI");
444  if (argc < 2 && (st->has_required || G__has_required_rule())
445  && !st->no_interactive && isatty(0) &&
446  (gui_envvar && G_strcasecmp(gui_envvar, "text") != 0)) {
447  if (module_gui_wx() == 0)
448  return -1;
449  }
450 
451  if (argc < 2 && st->has_required && isatty(0)) {
452  G_usage();
453  return -1;
454  }
455  else if (argc >= 2) {
456 
457  /* If first arg is "help" give a usage/syntax message */
458  if (strcmp(argv[1], "help") == 0 ||
459  strcmp(argv[1], "-help") == 0 || strcmp(argv[1], "--help") == 0) {
460  G_usage();
461  exit(EXIT_SUCCESS);
462  }
463 
464  /* If first arg is "--help-text" give a usage/syntax message
465  * with machine-readable sentinels */
466  if (strcmp(argv[1], "--help-text") == 0) {
467  G__usage_text();
468  exit(EXIT_SUCCESS);
469  }
470 
471  /* If first arg is "--interface-description" then print out
472  * a xml description of the task */
473  if (strcmp(argv[1], "--interface-description") == 0) {
474  G__usage_xml();
475  exit(EXIT_SUCCESS);
476  }
477 
478  /* If first arg is "--html-description" then print out
479  * a html description of the task */
480  if (strcmp(argv[1], "--html-description") == 0) {
481  G__usage_html();
482  exit(EXIT_SUCCESS);
483  }
484 
485  /* If first arg is "--rst-description" then print out
486  * a reStructuredText description of the task */
487  if (strcmp(argv[1], "--rst-description") == 0) {
488  G__usage_rest();
489  exit(EXIT_SUCCESS);
490  }
491 
492  /* If first arg is "--wps-process-description" then print out
493  * the wps process description of the task */
494  if (strcmp(argv[1], "--wps-process-description") == 0) {
496  exit(EXIT_SUCCESS);
497  }
498 
499  /* If first arg is "--script" then then generate
500  * g.parser boilerplate */
501  if (strcmp(argv[1], "--script") == 0) {
502  G__script();
503  exit(EXIT_SUCCESS);
504  }
505 
506  /* Loop through all command line arguments */
507 
508  while (--argc) {
509  ptr = *(++argv);
510 
511  if (strcmp(ptr, "help") == 0 || strcmp(ptr, "--h") == 0 ||
512  strcmp(ptr, "-help") == 0 || strcmp(ptr, "--help") == 0) {
513  G_usage();
514  exit(EXIT_SUCCESS);
515  }
516 
517  /* JSON print option */
518  if (strcmp(ptr, "--json") == 0) {
519  print_json = 1;
520  continue;
521  }
522 
523  /* Overwrite option */
524  if (strcmp(ptr, "--o") == 0 || strcmp(ptr, "--overwrite") == 0) {
525  st->overwrite = 1;
526  }
527 
528  /* Verbose option */
529  else if (strcmp(ptr, "--v") == 0 || strcmp(ptr, "--verbose") == 0) {
530  char buff[32];
531 
532  /* print everything: max verbosity level */
533  st->module_info.verbose = G_verbose_max();
534  sprintf(buff, "GRASS_VERBOSE=%d", G_verbose_max());
535  putenv(G_store(buff));
536  if (st->quiet == 1) {
537  G_warning(_("Use either --quiet or --verbose flag, not both. Assuming --verbose."));
538  }
539  st->quiet = -1;
540  }
541 
542  /* Quiet option */
543  else if (strcmp(ptr, "--q") == 0 || strcmp(ptr, "--quiet") == 0) {
544  char buff[32];
545 
546  /* print nothing, but errors and warnings */
547  st->module_info.verbose = G_verbose_min();
548  sprintf(buff, "GRASS_VERBOSE=%d", G_verbose_min());
549  putenv(G_store(buff));
550  if (st->quiet == -1) {
551  G_warning(_("Use either --quiet or --verbose flag, not both. Assuming --quiet."));
552  }
553  st->quiet = 1; /* for passing to gui init */
554  }
555 
556  /* Super quiet option */
557  else if (strcmp(ptr, "--qq") == 0 ) {
558  char buff[32];
559 
560  /* print nothing, but errors */
561  st->module_info.verbose = G_verbose_min();
562  sprintf(buff, "GRASS_VERBOSE=%d", G_verbose_min());
563  putenv(G_store(buff));
565  if (st->quiet == -1) {
566  G_warning(_("Use either --qq or --verbose flag, not both. Assuming --qq."));
567  }
568  st->quiet = 1; /* for passing to gui init */
569  }
570 
571  /* Force gui to come up */
572  else if (strcmp(ptr, "--ui") == 0) {
573  force_gui = TRUE;
574  }
575 
576  /* If we see a flag */
577  else if (*ptr == '-') {
578  while (*(++ptr))
579  set_flag(*ptr);
580 
581  }
582  /* If we see standard option format (option=val) */
583  else if (is_option(ptr)) {
584  set_option(ptr);
585  need_first_opt = 0;
586  }
587 
588  /* If we see the first option with no equal sign */
589  else if (need_first_opt && st->n_opts) {
590  st->first_option.answer = G_store(ptr);
591  st->first_option.count++;
592  need_first_opt = 0;
593  }
594 
595  /* If we see the non valid argument (no "=", just argument) */
596  else {
597  G_asprintf(&err, _("Sorry <%s> is not a valid option"), ptr);
598  append_error(err);
599  }
600 
601  }
602  }
603 
604  /* Split options where multiple answers are OK */
605  split_opts();
606 
607  /* Run the gui if it was specifically requested */
608  if (force_gui) {
609  if (module_gui_wx() != 0)
610  G_fatal_error(_("Your installation doesn't include GUI, exiting."));
611  return -1;
612  }
613 
614  /* Check multiple options */
615  check_multiple_opts();
616 
617  /* Check answers against options and check subroutines */
618  if (!opt_checked)
619  check_opts();
620 
621  /* Make sure all required options are set */
622  if (!st->suppress_required)
623  check_required();
624 
626 
627  if (st->n_errors > 0) {
628  if (G_verbose() > -1) {
629  if (G_verbose() > G_verbose_min())
630  G_usage();
631  fprintf(stderr, "\n");
632  for (i = 0; i < st->n_errors; i++) {
633  fprintf(stderr, "%s: %s\n", _("ERROR"), st->error[i]);
634  }
635  }
636  return -1;
637  }
638 
639  /* Print the JSON definition of the command and exit */
640  if(print_json == 1) {
641  G__json();
642  exit(EXIT_SUCCESS);
643  }
644 
645  if (!st->suppress_overwrite) {
646  if (check_overwrite())
647  return -1;
648  }
649 
650  return 0;
651 }
652 
653 /*!
654  * \brief Creates command to run non-interactive.
655  *
656  * Creates a command-line that runs the current command completely
657  * non-interactive.
658  *
659  * \param original_path TRUE if original path should be used, FALSE for
660  * stripped and clean name of the module
661  * \return pointer to a char string
662  */
663 char *recreate_command(int original_path)
664 {
665  char *buff;
666  char flg[4];
667  char *cur;
668  const char *tmp;
669  struct Flag *flag;
670  struct Option *opt;
671  int n, len, slen;
672  int nalloced = 0;
673 
674  G_debug(3, "G_recreate_command()");
675 
676  /* Flag is not valid if there are no flags to set */
677 
678  buff = G_calloc(1024, sizeof(char));
679  nalloced += 1024;
680  if (original_path)
681  tmp = G_original_program_name();
682  else
683  tmp = G_program_name();
684  len = strlen(tmp);
685  if (len >= nalloced) {
686  nalloced += (1024 > len) ? 1024 : len + 1;
687  buff = G_realloc(buff, nalloced);
688  }
689  cur = buff;
690  strcpy(cur, tmp);
691  cur += len;
692 
693  if (st->overwrite) {
694  slen = strlen(" --overwrite");
695  if (len + slen >= nalloced) {
696  nalloced += (1024 > len) ? 1024 : len + 1;
697  buff = G_realloc(buff, nalloced);
698  }
699  strcpy(cur, " --overwrite");
700  cur += slen;
701  len += slen;
702  }
703 
704  if (st->module_info.verbose != G_verbose_std()) {
705  char *sflg;
706  if (st->module_info.verbose == G_verbose_max())
707  sflg = " --verbose";
708  else
709  sflg = " --quiet";
710 
711  slen = strlen(sflg);
712  if (len + slen >= nalloced) {
713  nalloced += (1024 > len) ? 1024 : len + 1;
714  buff = G_realloc(buff, nalloced);
715  }
716  strcpy(cur, sflg);
717  cur += slen;
718  len += slen;
719  }
720 
721  if (st->n_flags) {
722  flag = &st->first_flag;
723  while (flag) {
724  if (flag->answer == 1) {
725  flg[0] = ' ';
726  flg[1] = '-';
727  flg[2] = flag->key;
728  flg[3] = '\0';
729  slen = strlen(flg);
730  if (len + slen >= nalloced) {
731  nalloced +=
732  (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
733  buff = G_realloc(buff, nalloced);
734  cur = buff + len;
735  }
736  strcpy(cur, flg);
737  cur += slen;
738  len += slen;
739  }
740  flag = flag->next_flag;
741  }
742  }
743 
744  opt = &st->first_option;
745  while (st->n_opts && opt) {
746  if (opt->answer && opt->answer[0] == '\0') { /* answer = "" */
747  slen = strlen(opt->key) + 4; /* +4 for: ' ' = " " */
748  if (len + slen >= nalloced) {
749  nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
750  buff = G_realloc(buff, nalloced);
751  cur = buff + len;
752  }
753  strcpy(cur, " ");
754  cur++;
755  strcpy(cur, opt->key);
756  cur = strchr(cur, '\0');
757  strcpy(cur, "=");
758  cur++;
759  if (opt->type == TYPE_STRING) {
760  strcpy(cur, "\"\"");
761  cur += 2;
762  }
763  len = cur - buff;
764  } else if (opt->answer && opt->answers && opt->answers[0]) {
765  slen = strlen(opt->key) + strlen(opt->answers[0]) + 4; /* +4 for: ' ' = " " */
766  if (len + slen >= nalloced) {
767  nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
768  buff = G_realloc(buff, nalloced);
769  cur = buff + len;
770  }
771  strcpy(cur, " ");
772  cur++;
773  strcpy(cur, opt->key);
774  cur = strchr(cur, '\0');
775  strcpy(cur, "=");
776  cur++;
777  if (opt->type == TYPE_STRING) {
778  strcpy(cur, "\"");
779  cur++;
780  }
781  strcpy(cur, opt->answers[0]);
782  cur = strchr(cur, '\0');
783  len = cur - buff;
784  for (n = 1; opt->answers[n]; n++) {
785  if (!opt->answers[n])
786  break;
787  slen = strlen(opt->answers[n]) + 2; /* +2 for , " */
788  if (len + slen >= nalloced) {
789  nalloced +=
790  (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
791  buff = G_realloc(buff, nalloced);
792  cur = buff + len;
793  }
794  strcpy(cur, ",");
795  cur++;
796  strcpy(cur, opt->answers[n]);
797  cur = strchr(cur, '\0');
798  len = cur - buff;
799  }
800  if (opt->type == TYPE_STRING) {
801  strcpy(cur, "\"");
802  cur++;
803  len = cur - buff;
804  }
805  }
806  opt = opt->next_opt;
807  }
808 
809  return buff;
810 }
811 
812 /*!
813  * \brief Creates command to run non-interactive.
814  *
815  * Creates a command-line that runs the current command completely
816  * non-interactive.
817  *
818  * \return pointer to a char string
819  */
821 {
822  return recreate_command(FALSE);
823 }
824 
825 /* TODO: update to docs of these 3 functions to whatever general purpose
826  * they have now. */
827 /*!
828  * \brief Creates command to run non-interactive.
829  *
830  * Creates a command-line that runs the current command completely
831  * non-interactive.
832  *
833  * This gives the same as G_recreate_command() but the original path
834  * from the command line is used instead of the module name only.
835  *
836  * \return pointer to a char string
837  */
839 {
840  return recreate_command(TRUE);
841 }
842 
843 /*!
844  \brief Add keyword to the list
845 
846  \param keyword keyword string
847 */
848 void G_add_keyword(const char *keyword)
849 {
850  if (st->n_keys >= st->n_keys_alloc) {
851  st->n_keys_alloc += 10;
852  st->module_info.keywords = G_realloc(st->module_info.keywords,
853  st->n_keys_alloc * sizeof(char *));
854  }
855 
856  st->module_info.keywords[st->n_keys++] = G_store(keyword);
857 }
858 
859 /*!
860  \brief Set keywords from the string
861 
862  \param keywords keywords separated by commas
863 */
864 void G_set_keywords(const char *keywords)
865 {
866  char **tokens = G_tokenize(keywords, ",");
867  st->module_info.keywords = (const char **)tokens;
868  st->n_keys = st->n_keys_alloc = G_number_of_tokens(tokens);
869 }
870 
871 
873 {
874  struct Option *opt;
875  char age[KEYLENGTH];
876  char element[KEYLENGTH];
877  char desc[KEYLENGTH];
878 
879  if (st->module_info.overwrite)
880  return 1;
881 
882  /* figure out if any of the options use a "new" gisprompt */
883  /* This is to see if we should spit out the --o flag */
884  if (st->n_opts) {
885  opt = &st->first_option;
886  while (opt) {
887  if (opt->gisprompt) {
888  G__split_gisprompt(opt->gisprompt, age, element, desc);
889  if (strcmp(age, "new") == 0)
890  return 1;
891  }
892  opt = opt->next_opt;
893  }
894  }
895 
896  return 0;
897 }
898 
899 /*!
900  \brief Print list of keywords (internal use only)
901 
902  If <em>format</em> function is NULL then list of keywords is printed
903  comma-separated.
904 
905  \param[out] fd file where to print
906  \param format pointer to print function
907 */
908 void G__print_keywords(FILE *fd, void (*format)(FILE *, const char *))
909 {
910  int i;
911 
912  for(i = 0; i < st->n_keys; i++) {
913  if (!format) {
914  fprintf(fd, "%s", st->module_info.keywords[i]);
915  }
916  else {
917  format(fd, st->module_info.keywords[i]);
918  }
919  if (i < st->n_keys - 1)
920  fprintf(fd, ", ");
921  }
922 
923  fflush(fd);
924 }
925 
926 /*!
927  \brief Get overwrite value
928 
929  \return 1 overwrite enabled
930  \return 0 overwrite disabled
931 */
933 {
934  return st->module_info.overwrite;
935 }
936 
937 void define_keywords(void)
938 {
939  st->n_keys = 0;
940  st->n_keys_alloc = 0;
941 }
942 
943 /**************************************************************************
944  *
945  * The remaining routines are all local (static) routines used to support
946  * the parsing process.
947  *
948  **************************************************************************/
949 
950 /*!
951  \brief Invoke GUI dialog
952 */
953 int module_gui_wx(void)
954 {
955  char script[GPATH_MAX];
956 
957  /* TODO: the 4 following lines seems useless */
958  if (!st->pgm_path)
959  st->pgm_path = G_program_name();
960  if (!st->pgm_path)
961  G_fatal_error(_("Unable to determine program name"));
962 
963  sprintf(script, "%s/gui/wxpython/gui_core/forms.py",
964  getenv("GISBASE"));
965  if (access(script, F_OK) != -1)
966  G_spawn(getenv("GRASS_PYTHON"), getenv("GRASS_PYTHON"),
968  else
969  return -1;
970 
971  return 0;
972 }
973 
974 void set_flag(int f)
975 {
976  struct Flag *flag;
977  char *err;
978 
979  err = NULL;
980 
981  /* Flag is not valid if there are no flags to set */
982  if (!st->n_flags) {
983  G_asprintf(&err, _("%s: Sorry, <%c> is not a valid flag"), G_program_name(), f);
984  append_error(err);
985  return;
986  }
987 
988  /* Find flag with corrrect keyword */
989  flag = &st->first_flag;
990  while (flag) {
991  if (flag->key == f) {
992  flag->answer = 1;
993  if (flag->suppress_required)
994  st->suppress_required = 1;
995  if (flag->suppress_overwrite)
996  st->suppress_overwrite = 1;
997  return;
998  }
999  flag = flag->next_flag;
1000  }
1001 
1002  G_asprintf(&err, _("%s: Sorry, <%c> is not a valid flag"), G_program_name(), f);
1003  append_error(err);
1004 }
1005 
1006 /* contents() is used to find things strings with characters like commas and
1007  * dashes.
1008  */
1009 int contains(const char *s, int c)
1010 {
1011  while (*s) {
1012  if (*s == c)
1013  return TRUE;
1014  s++;
1015  }
1016  return FALSE;
1017 }
1018 
1019 int valid_option_name(const char *string)
1020 {
1021  int m = strlen(string);
1022  int n = strspn(string, "abcdefghijklmnopqrstuvwxyz0123456789_");
1023 
1024  if (!m)
1025  return 0;
1026 
1027  if (m != n)
1028  return 0;
1029 
1030  if (string[m-1] == '_')
1031  return 0;
1032 
1033  return 1;
1034 }
1035 
1036 int is_option(const char *string)
1037 {
1038  int n = strspn(string, "abcdefghijklmnopqrstuvwxyz0123456789_");
1039 
1040  return n > 0 && string[n] == '=' && string[0] != '_' && string[n-1] != '_';
1041 }
1042 
1043 int match_option_1(const char *string, const char *option)
1044 {
1045  const char *next;
1046 
1047  if (*string == '\0')
1048  return 1;
1049 
1050  if (*option == '\0')
1051  return 0;
1052 
1053  if (*string == *option && match_option_1(string + 1, option + 1))
1054  return 1;
1055 
1056  if (*option == '_' && match_option_1(string, option + 1))
1057  return 1;
1058 
1059  next = strchr(option, '_');
1060  if (!next)
1061  return 0;
1062 
1063  if (*string == '_')
1064  return match_option_1(string + 1, next + 1);
1065 
1066  return match_option_1(string, next + 1);
1067 }
1068 
1069 int match_option(const char *string, const char *option)
1070 {
1071  return (*string == *option)
1072  && match_option_1(string + 1, option + 1);
1073 }
1074 
1075 void set_option(const char *string)
1076 {
1077  struct Option *at_opt = NULL;
1078  struct Option *opt = NULL;
1079  size_t key_len;
1080  char the_key[KEYLENGTH];
1081  char *ptr, *err;
1082  struct Option *matches[MAX_MATCHES];
1083  int found = 0;
1084 
1085  err = NULL;
1086 
1087  for (ptr = the_key; *string != '='; ptr++, string++)
1088  *ptr = *string;
1089  *ptr = '\0';
1090  string++;
1091 
1092  /* an empty string is not a valid answer, skip */
1093  if (! *string)
1094  return;
1095 
1096  /* Find option with best keyword match */
1097  key_len = strlen(the_key);
1098  for (at_opt = &st->first_option; at_opt; at_opt = at_opt->next_opt) {
1099  if (!at_opt->key)
1100  continue;
1101 
1102  if (strcmp(the_key, at_opt->key) == 0) {
1103  matches[0] = at_opt;
1104  found = 1;
1105  break;
1106  }
1107 
1108  if (strncmp(the_key, at_opt->key, key_len) == 0 ||
1109  match_option(the_key, at_opt->key)) {
1110  if (found >= MAX_MATCHES)
1111  G_fatal_error("Too many matches (limit %d)", MAX_MATCHES);
1112  matches[found++] = at_opt;
1113  }
1114  }
1115 
1116  if (found > 1) {
1117  int shortest = 0;
1118  int length = strlen(matches[0]->key);
1119  int prefix = 1;
1120  int i;
1121  for (i = 1; i < found; i++) {
1122  int len = strlen(matches[i]->key);
1123  if (len < length) {
1124  length = len;
1125  shortest = i;
1126  }
1127  }
1128  for (i = 0; prefix && i < found; i++)
1129  if (strncmp(matches[i]->key, matches[shortest]->key, length) != 0)
1130  prefix = 0;
1131  if (prefix) {
1132  matches[0] = matches[shortest];
1133  found = 1;
1134  }
1135  else {
1136  G_asprintf(&err, _("%s: Sorry, <%s=> is ambiguous"), G_program_name(), the_key);
1137  append_error(err);
1138  for (i = 0; i < found; i++) {
1139  G_asprintf(&err, _("Option <%s=> matches"), matches[i]->key);
1140  append_error(err);
1141  }
1142  return;
1143  }
1144  }
1145 
1146  if (found)
1147  opt = matches[0];
1148 
1149  /* First, check if key has been renamed in GRASS 7 */
1150  if (found == 0) {
1151  const char *renamed_key = NULL;
1152 
1153  renamed_key = get_renamed_option(the_key);
1154  if (renamed_key) {
1155  for (at_opt = &st->first_option; at_opt; at_opt = at_opt->next_opt) {
1156  if (strcmp(renamed_key, at_opt->key) == 0) {
1157  G_warning(_("Please update the usage of <%s>: "
1158  "option <%s> has been renamed to <%s>"),
1159  G_program_name(), the_key, renamed_key);
1160  opt = at_opt;
1161  found = 1;
1162  break;
1163  }
1164  }
1165  }
1166  }
1167 
1168  /* If there is no match, complain */
1169  if (found == 0) {
1170  G_asprintf(&err, _("%s: Sorry, <%s> is not a valid parameter"), G_program_name(), the_key);
1171  append_error(err);
1172  return;
1173  }
1174 
1175  if (getenv("GRASS_FULL_OPTION_NAMES") && strcmp(the_key, opt->key) != 0)
1176  G_warning(_("<%s> is an abbreviation for <%s>"), the_key, opt->key);
1177 
1178  /* Allocate memory where answer is stored */
1179  if (opt->count++) {
1180  if (!opt->multiple) {
1181  G_asprintf(&err, _("Option <%s> does not accept multiple answers"), opt->key);
1182  append_error(err);
1183  }
1184  opt->answer = G_realloc(opt->answer,
1185  strlen(opt->answer) + strlen(string) + 2);
1186  strcat(opt->answer, ",");
1187  strcat(opt->answer, string);
1188  }
1189  else
1190  opt->answer = G_store(string);
1191 }
1192 
1193 void check_opts(void)
1194 {
1195  struct Option *opt;
1196  int ans;
1197 
1198  if (!st->n_opts)
1199  return;
1200 
1201  opt = &st->first_option;
1202  while (opt) {
1203  /* Check answer against options if any */
1204 
1205  if (opt->answer) {
1206  if (opt->multiple == 0)
1207  check_an_opt(opt->key, opt->type,
1208  opt->options, opt->opts, &opt->answer);
1209  else {
1210  for (ans = 0; opt->answers[ans] != '\0'; ans++)
1211  check_an_opt(opt->key, opt->type,
1212  opt->options, opt->opts, &opt->answers[ans]);
1213  }
1214  }
1215 
1216  /* Check answer against user's check subroutine if any */
1217 
1218  if (opt->checker)
1219  opt->checker(opt->answer);
1220 
1221  opt = opt->next_opt;
1222  }
1223 }
1224 
1225 void check_an_opt(const char *key, int type, const char *options,
1226  const char **opts, char **answerp)
1227 {
1228  const char *answer = *answerp;
1229  int error;
1230  char *err;
1231  int found;
1232 
1233  error = 0;
1234  err = NULL;
1235  found = 0;
1236 
1237  switch (type) {
1238  case TYPE_INTEGER:
1239  error = check_int(answer, opts);
1240  break;
1241  case TYPE_DOUBLE:
1242  error = check_double(answer, opts);
1243  break;
1244  case TYPE_STRING:
1245  error = check_string(answer, opts, &found);
1246  break;
1247  }
1248  switch (error) {
1249  case 0:
1250  break;
1251  case BAD_SYNTAX:
1252  G_asprintf(&err,
1253  _("Illegal range syntax for parameter <%s>\n"
1254  "\tPresented as: %s"), key, options);
1255  append_error(err);
1256  break;
1257  case OUT_OF_RANGE:
1258  G_asprintf(&err,
1259  _("Value <%s> out of range for parameter <%s>\n"
1260  "\tLegal range: %s"), answer, key, options);
1261  append_error(err);
1262  break;
1263  case MISSING_VALUE:
1264  G_asprintf(&err,
1265  _("Missing value for parameter <%s>"),
1266  key);
1267  append_error(err);
1268  break;
1269  case AMBIGUOUS:
1270  G_asprintf(&err,
1271  _("Value <%s> ambiguous for parameter <%s>\n"
1272  "\tValid options: %s"), answer, key, options);
1273  append_error(err);
1274  break;
1275  case REPLACED:
1276  *answerp = G_store(opts[found]);
1277  error = 0;
1278  break;
1279  }
1280 }
1281 
1282 int check_int(const char *ans, const char **opts)
1283 {
1284  int d, i;
1285 
1286  /* "-" is reserved for standard input */
1287  if (strcmp(ans, "-") == 0)
1288  return 0;
1289 
1290  if (sscanf(ans, "%d", &d) != 1)
1291  return MISSING_VALUE;
1292 
1293  if (!opts)
1294  return 0;
1295 
1296  for (i = 0; opts[i]; i++) {
1297  const char *opt = opts[i];
1298  int lo, hi;
1299 
1300  if (contains(opt, '-')) {
1301  if (sscanf(opt, "%d-%d", &lo, &hi) == 2) {
1302  if (d >= lo && d <= hi)
1303  return 0;
1304  }
1305  else if (sscanf(opt, "-%d", &hi) == 1) {
1306  if (d <= hi)
1307  return 0;
1308  }
1309  else if (sscanf(opt, "%d-", &lo) == 1) {
1310  if (d >= lo)
1311  return 0;
1312  }
1313  else
1314  return BAD_SYNTAX;
1315  }
1316  else {
1317  if (sscanf(opt, "%d", &lo) == 1) {
1318  if (d == lo)
1319  return 0;
1320  }
1321  else
1322  return BAD_SYNTAX;
1323  }
1324  }
1325 
1326  return OUT_OF_RANGE;
1327 }
1328 
1329 int check_double(const char *ans, const char **opts)
1330 {
1331  double d;
1332  int i;
1333 
1334  /* "-" is reserved for standard input */
1335  if (strcmp(ans, "-") == 0)
1336  return 0;
1337 
1338  if (sscanf(ans, "%lf", &d) != 1)
1339  return MISSING_VALUE;
1340 
1341  if (!opts)
1342  return 0;
1343 
1344  for (i = 0; opts[i]; i++) {
1345  const char *opt = opts[i];
1346  double lo, hi;
1347 
1348  if (contains(opt, '-')) {
1349  if (sscanf(opt, "%lf-%lf", &lo, &hi) == 2) {
1350  if (d >= lo && d <= hi)
1351  return 0;
1352  }
1353  else if (sscanf(opt, "-%lf", &hi) == 1) {
1354  if (d <= hi)
1355  return 0;
1356  }
1357  else if (sscanf(opt, "%lf-", &lo) == 1) {
1358  if (d >= lo)
1359  return 0;
1360  }
1361  else
1362  return BAD_SYNTAX;
1363  }
1364  else {
1365  if (sscanf(opt, "%lf", &lo) == 1) {
1366  if (d == lo)
1367  return 0;
1368  }
1369  else
1370  return BAD_SYNTAX;
1371  }
1372  }
1373 
1374  return OUT_OF_RANGE;
1375 }
1376 
1377 int check_string(const char *ans, const char **opts, int *result)
1378 {
1379  int len = strlen(ans);
1380  int found = 0;
1381  int matches[MAX_MATCHES];
1382  int i;
1383 
1384  if (!opts)
1385  return 0;
1386 
1387  for (i = 0; opts[i]; i++) {
1388  if (strcmp(ans, opts[i]) == 0)
1389  return 0;
1390  if (strncmp(ans, opts[i], len) == 0 || match_option(ans, opts[i])) {
1391  if (found >= MAX_MATCHES)
1392  G_fatal_error("too many matches (limit %d)", MAX_MATCHES);
1393  matches[found++] = i;
1394  }
1395  }
1396 
1397  if (found > 1) {
1398  int shortest = 0;
1399  int length = strlen(opts[matches[0]]);
1400  int prefix = 1;
1401  int i;
1402  for (i = 1; i < found; i++) {
1403  int len = strlen(opts[matches[i]]);
1404  if (len < length) {
1405  length = len;
1406  shortest = i;
1407  }
1408  }
1409  for (i = 0; prefix && i < found; i++)
1410  if (strncmp(opts[matches[i]], opts[matches[shortest]], length) != 0)
1411  prefix = 0;
1412  if (prefix) {
1413  matches[0] = matches[shortest];
1414  found = 1;
1415  }
1416  }
1417 
1418  if (found == 1)
1419  *result = matches[0];
1420 
1421  if (found > 0 && getenv("GRASS_FULL_OPTION_NAMES") && strcmp(ans, opts[matches[0]]) != 0)
1422  G_warning(_("<%s> is an abbreviation for <%s>"), ans, opts[matches[0]]);
1423 
1424  switch (found) {
1425  case 0: return OUT_OF_RANGE;
1426  case 1: return REPLACED;
1427  default: return AMBIGUOUS;
1428  }
1429 }
1430 
1431 void check_required(void)
1432 {
1433  struct Option *opt;
1434  char *err;
1435 
1436  err = NULL;
1437 
1438  if (!st->n_opts)
1439  return;
1440 
1441  opt = &st->first_option;
1442  while (opt) {
1443  if (opt->required && !opt->answer) {
1444  G_asprintf(&err, _("Required parameter <%s> not set:\n"
1445  "\t(%s)"),
1446  opt->key, (opt->label ? opt->label : opt->description));
1447  append_error(err);
1448  }
1449  opt = opt->next_opt;
1450  }
1451 }
1452 
1453 void split_opts(void)
1454 {
1455  struct Option *opt;
1456  const char *ptr1;
1457  const char *ptr2;
1458  int allocated;
1459  int ans_num;
1460  int len;
1461 
1462 
1463  if (!st->n_opts)
1464  return;
1465 
1466  opt = &st->first_option;
1467  while (opt) {
1468  if ( /*opt->multiple && */ opt->answer) {
1469  /* Allocate some memory to store array of pointers */
1470  allocated = 10;
1471  opt->answers = G_malloc(allocated * sizeof(char *));
1472 
1473  ans_num = 0;
1474  ptr1 = opt->answer;
1475  opt->answers[ans_num] = NULL;
1476 
1477  for (;;) {
1478  for (len = 0, ptr2 = ptr1; *ptr2 != '\0' && *ptr2 != ',';
1479  ptr2++, len++) ;
1480 
1481  if (len > 0) { /* skip ,, */
1482  opt->answers[ans_num] = G_malloc(len + 1);
1483  memcpy(opt->answers[ans_num], ptr1, len);
1484  opt->answers[ans_num][len] = 0;
1485 
1486  ans_num++;
1487 
1488  if (ans_num >= allocated) {
1489  allocated += 10;
1490  opt->answers = G_realloc(opt->answers,
1491  allocated * sizeof(char *));
1492  }
1493 
1494  opt->answers[ans_num] = NULL;
1495  }
1496 
1497  if (*ptr2 == '\0')
1498  break;
1499 
1500  ptr1 = ptr2 + 1;
1501 
1502  if (*ptr1 == '\0')
1503  break;
1504  }
1505  }
1506  opt = opt->next_opt;
1507  }
1508 }
1509 
1510 void check_multiple_opts(void)
1511 {
1512  struct Option *opt;
1513  const char *ptr;
1514  int n_commas;
1515  int n;
1516  char *err;
1517 
1518  if (!st->n_opts)
1519  return;
1520 
1521  err = NULL;
1522  opt = &st->first_option;
1523  while (opt) {
1524  /* "-" is reserved from standard input/output */
1525  if (opt->answer && strcmp(opt->answer, "-") && opt->key_desc) {
1526  /* count commas */
1527  n_commas = 1;
1528  for (ptr = opt->key_desc; *ptr != '\0'; ptr++)
1529  if (*ptr == ',')
1530  n_commas++;
1531  /* count items */
1532  for (n = 0; opt->answers[n] != '\0'; n++) ;
1533  /* if not correct multiple of items */
1534  if (n % n_commas) {
1535  G_asprintf(&err,
1536  _("Option <%s> must be provided in multiples of %d\n"
1537  "\tYou provided %d item(s): %s"),
1538  opt->key, n_commas, n, opt->answer);
1539  append_error(err);
1540 
1541  }
1542  }
1543  opt = opt->next_opt;
1544  }
1545 }
1546 
1547 /* Check for all 'new' if element already exists */
1548 int check_overwrite(void)
1549 {
1550  struct Option *opt;
1551  char age[KEYLENGTH];
1552  char element[KEYLENGTH];
1553  char desc[KEYLENGTH];
1554  int error = 0;
1555  const char *overstr;
1556  int over;
1557 
1558  st->module_info.overwrite = 0;
1559 
1560  if (!st->n_opts)
1561  return (0);
1562 
1563  over = 0;
1564  /* Check the GRASS OVERWRITE variable */
1565  if ((overstr = G_getenv_nofatal("OVERWRITE"))) {
1566  over = atoi(overstr);
1567  }
1568 
1569  /* Check the GRASS_OVERWRITE environment variable */
1570  if ((overstr = getenv("GRASS_OVERWRITE"))) {
1571  if (atoi(overstr))
1572  over = 1;
1573  }
1574 
1575  if (st->overwrite || over) {
1576  st->module_info.overwrite = 1;
1577  /* Set the environment so that programs run in a script also obey --o */
1578  putenv("GRASS_OVERWRITE=1");
1579  /* No need to check options for existing files if overwrite is true */
1580  return error;
1581  }
1582 
1583  opt = &st->first_option;
1584  while (opt) {
1585  if (opt->answer && opt->gisprompt) {
1586  G__split_gisprompt(opt->gisprompt, age, element, desc);
1587 
1588  if (strcmp(age, "new") == 0) {
1589  int i;
1590  char found;
1591 
1592  for (i = 0; opt->answers[i]; i++) {
1593  found = FALSE;
1594  if (strcmp(element, "file") == 0) {
1595  if (access(opt->answers[i], F_OK) == 0)
1596  found = TRUE;
1597  }
1598  else if (strcmp(element, "mapset") != 0) {
1599  /* TODO: also other elements should be
1600  probably skipped */
1601  if (G_find_file(element, opt->answers[i], G_mapset())) {
1602  found = TRUE;
1603  }
1604  }
1605 
1606  if (found) { /* found */
1607  if (!st->overwrite && !over) {
1608  if (G_verbose() > -1) {
1609  if (G_info_format() != G_INFO_FORMAT_GUI) {
1610  fprintf(stderr, _("ERROR: "));
1611  fprintf(stderr,
1612  _("option <%s>: <%s> exists. To overwrite, use the --overwrite flag"),
1613  opt->key, opt->answers[i]);
1614  fprintf(stderr, "\n");
1615  }
1616  else {
1617  fprintf(stderr, "GRASS_INFO_ERROR(%d,1): ", getpid());
1618  fprintf(stderr,
1619  _("option <%s>: <%s> exists. To overwrite, use the --overwrite flag"),
1620  opt->key, opt->answers[i]);
1621  fprintf(stderr, "\n");
1622  fprintf(stderr, "GRASS_INFO_END(%d,1)\n",
1623  getpid());
1624  }
1625  }
1626  error = 1;
1627  }
1628  }
1629  }
1630  }
1631  }
1632  opt = opt->next_opt;
1633  }
1634 
1635  return (error);
1636 }
1637 
1638 void G__split_gisprompt(const char *gisprompt, char *age, char *element,
1639  char *desc)
1640 {
1641  const char *ptr1;
1642  char *ptr2;
1643 
1644  for (ptr1 = gisprompt, ptr2 = age; *ptr1 != '\0'; ptr1++, ptr2++) {
1645  if (*ptr1 == ',')
1646  break;
1647  *ptr2 = *ptr1;
1648  }
1649  *ptr2 = '\0';
1650 
1651  for (ptr1++, ptr2 = element; *ptr1 != '\0'; ptr1++, ptr2++) {
1652  if (*ptr1 == ',')
1653  break;
1654  *ptr2 = *ptr1;
1655  }
1656  *ptr2 = '\0';
1657 
1658  for (ptr1++, ptr2 = desc; *ptr1 != '\0'; ptr1++, ptr2++) {
1659  if (*ptr1 == ',')
1660  break;
1661  *ptr2 = *ptr1;
1662  }
1663  *ptr2 = '\0';
1664 }
1665 
1666 void append_error(const char *msg)
1667 {
1668  st->error = G_realloc(st->error, sizeof(char *) * (st->n_errors + 1));
1669  st->error[st->n_errors++] = G_store(msg);
1670 }
1671 
1672 const char *get_renamed_option(const char *key)
1673 {
1674  const char *pgm, *key_new;
1675  char *pgm_key;
1676 
1677  if (!st->renamed_options) {
1678  /* read renamed options from file (renamed_options) */
1679  char path[GPATH_MAX];
1680 
1681  G_snprintf(path, GPATH_MAX, "%s/etc/renamed_options", G_gisbase());
1682  st->renamed_options = G_read_key_value_file(path);
1683  }
1684 
1685  /* try to check global changes first */
1686  key_new = G_find_key_value(key, st->renamed_options);
1687  if (key_new)
1688  return key_new;
1689 
1690  /* then check module-relevant changes */
1691  pgm = G_program_name();
1692  pgm_key = (char *) G_malloc (strlen(pgm) + strlen(key) + 2);
1693  G_asprintf(&pgm_key, "%s|%s", pgm, key);
1694 
1695  key_new = G_find_key_value(pgm_key, st->renamed_options);
1696  G_free(pgm_key);
1697 
1698  return key_new;
1699 }
1700 
1701 /*!
1702  \brief Get separator string from the option.
1703 
1704  Calls G_fatal_error() on error. Allocated string can be later freed
1705  by G_free().
1706 
1707  \code
1708  char *fs;
1709  struct Option *opt_fs;
1710 
1711  opt_fs = G_define_standard_option(G_OPT_F_SEP);
1712 
1713  if (G_parser(argc, argv))
1714  exit(EXIT_FAILURE);
1715 
1716  fs = G_option_to_separator(opt_fs);
1717  \endcode
1718 
1719  \param option pointer to separator option
1720 
1721  \return allocated string with separator
1722 */
1723 char* G_option_to_separator(const struct Option *option)
1724 {
1725  char* sep;
1726 
1727  if (option->gisprompt == NULL ||
1728  strcmp(option->gisprompt, "old,separator,separator") != 0)
1729  G_fatal_error(_("%s= is not a separator option"), option->key);
1730 
1731  if (option->answer == NULL)
1732  G_fatal_error(_("No separator given for %s="), option->key);
1733 
1734  if (strcmp(option->answer, "pipe") == 0)
1735  sep = G_store("|");
1736  else if (strcmp(option->answer, "comma") == 0)
1737  sep = G_store(",");
1738  else if (strcmp(option->answer, "space") == 0)
1739  sep = G_store(" ");
1740  else if (strcmp(option->answer, "tab") == 0 ||
1741  strcmp(option->answer, "\\t") == 0)
1742  sep = G_store("\t");
1743  else if (strcmp(option->answer, "newline") == 0 ||
1744  strcmp(option->answer, "\\n") == 0)
1745  sep = G_store("\n");
1746  else
1747  sep = G_store(option->answer);
1748 
1749  G_debug(3, "G_option_to_separator(): key = %s -> sep = '%s'",
1750  option->key, sep);
1751 
1752  return sep;
1753 }
1754 
1755 /*!
1756  \brief Get an input/output file pointer from the option. If the file name is
1757  omitted or '-', it returns either stdin or stdout based on the gisprompt.
1758 
1759  Calls G_fatal_error() on error. File pointer can be later closed by
1760  G_close_option_file().
1761 
1762  \code
1763  FILE *fp_input;
1764  FILE *fp_output;
1765  struct Option *opt_input;
1766  struct Option *opt_output;
1767 
1768  opt_input = G_define_standard_option(G_OPT_F_INPUT);
1769  opt_output = G_define_standard_option(G_OPT_F_OUTPUT);
1770 
1771  if (G_parser(argc, argv))
1772  exit(EXIT_FAILURE);
1773 
1774  fp_input = G_open_option_file(opt_input);
1775  fp_output = G_open_option_file(opt_output);
1776  ...
1777  G_close_option_file(fp_input);
1778  G_close_option_file(fp_output);
1779  \endcode
1780 
1781  \param option pointer to a file option
1782 
1783  \return file pointer
1784 */
1785 FILE *G_open_option_file(const struct Option *option)
1786 {
1787  int stdinout;
1788  FILE *fp;
1789 
1790  stdinout = !option->answer || !*(option->answer) ||
1791  strcmp(option->answer, "-") == 0;
1792 
1793  if (option->gisprompt == NULL)
1794  G_fatal_error(_("%s= is not a file option"), option->key);
1795  else if (option->multiple)
1796  G_fatal_error(_("Opening multiple files not supported for %s="),
1797  option->key);
1798  else if (strcmp(option->gisprompt, "old,file,file") == 0) {
1799  if (stdinout)
1800  fp = stdin;
1801  else if ((fp = fopen(option->answer, "r")) == NULL)
1802  G_fatal_error(_("Unable to open %s file <%s>"),
1803  option->key, option->answer);
1804  } else if (strcmp(option->gisprompt, "new,file,file") == 0) {
1805  if (stdinout)
1806  fp = stdout;
1807  else if ((fp = fopen(option->answer, "w")) == NULL)
1808  G_fatal_error(_("Unable to create %s file <%s>"),
1809  option->key, option->answer);
1810  } else
1811  G_fatal_error(_("%s= is not a file option"), option->key);
1812 
1813  return fp;
1814 }
1815 
1816 /*!
1817  \brief Close an input/output file returned by G_open_option_file(). If the
1818  file pointer is stdin, stdout, or stderr, nothing happens.
1819 
1820  \param file pointer
1821 */
1822 void G_close_option_file(FILE *fp)
1823 {
1824  if (fp != stdin && fp != stdout && fp != stderr)
1825  fclose(fp);
1826 }
int G__uses_new_gisprompt(void)
Definition: parser.c:872
const char ** opts
Definition: gis.h:535
int G_info_format(void)
Get current message format.
Definition: gis/error.c:532
#define TRUE
Definition: gis.h:56
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
Definition: strings.c:46
#define NO
Definition: gis.h:161
int G__has_required_rule(void)
Checks if there is any rule RULE_REQUIRED (internal use only).
void G__usage_html(void)
Print module usage description in HTML format.
Definition: parser_html.c:29
#define TYPE_DOUBLE
Definition: gis.h:158
const char * G_find_key_value(const char *key, const struct Key_Value *kv)
Find given key (case sensitive)
Definition: key_value1.c:84
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:149
const char * G_original_program_name(void)
Return original path of the executed program.
Definition: progrm_nme.c:46
int count
Definition: gis.h:549
char * G__json(void)
This function generates actinia JSON process chain building blocks from the command line arguments th...
Definition: parser_json.c:184
char answer
Definition: gis.h:560
void G__usage_xml(void)
Print module usage description in XML format.
struct GModule * G_define_module(void)
Initializes a new module.
Definition: parser.c:253
const char * G_find_file(const char *element, char *name, const char *mapset)
Searches for a file from the mapset search list or in a specified mapset.
Definition: find_file.c:203
char * recreate_command(int original_path)
Creates command to run non-interactive.
Definition: parser.c:663
const char * descriptions
Definition: gis.h:539
void G__usage_rest(void)
Print module usage description in reStructuredText format.
Definition: parser_rest.c:29
char ** G_tokenize(const char *buf, const char *delim)
Tokenize string.
Definition: gis/token.c:48
char * G_store(const char *s)
Copy string to allocated memory.
Definition: strings.c:86
#define TYPE_STRING
Definition: gis.h:159
void G__check_option_rules(void)
Check for option rules (internal use only)
int G_asprintf(char **out, const char *fmt,...)
Definition: asprintf.c:70
int G_get_overwrite()
Get overwrite value.
Definition: parser.c:932
Structure that stores module info.
Definition: gis.h:574
#define NULL
Definition: ccmath.h:32
char * G_chop(char *line)
Chop leading and trailing white spaces.
Definition: strings.c:286
void G__usage_text(void)
Definition: parser_help.c:53
char * G_option_to_separator(const struct Option *option)
Get separator string from the option.
Definition: parser.c:1723
char * G_recreate_command(void)
Creates command to run non-interactive.
Definition: parser.c:820
char * G_recreate_command_original_path(void)
Creates command to run non-interactive.
Definition: parser.c:838
struct Flag * G_define_flag(void)
Initializes a Flag struct.
Definition: parser.c:154
#define G_INFO_FORMAT_GUI
Definition: gis.h:357
const char * def
Definition: gis.h:542
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:160
int G_snprintf(char *str, size_t size, const char *fmt,...)
snprintf() clone.
Definition: snprintf.c:43
Definition: lidar.h:89
void G_close_option_file(FILE *fp)
Close an input/output file returned by G_open_option_file(). If the file pointer is stdin...
Definition: parser.c:1822
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition: symbol/read.c:220
const char * description
Definition: gis.h:538
int G_suppress_warnings(int flag)
Suppress printing a warning message to stderr.
Definition: gis/error.c:223
#define TYPE_INTEGER
Definition: gis.h:157
int type
Definition: gis.h:531
struct state * st
Definition: parser.c:102
struct Key_Value * G_read_key_value_file(const char *file)
Read key/values pairs from file.
Definition: key_value3.c:53
int G_number_of_tokens(char **tokens)
Return number of tokens.
Definition: gis/token.c:185
int G_parser(int argc, char **argv)
Parse command line.
Definition: parser.c:318
struct Option * G_define_option(void)
Initializes an Option struct.
Definition: parser.c:208
int G_verbose_max(void)
Get max verbosity level.
Definition: verbose.c:76
#define FALSE
Definition: gis.h:60
char * answer
Definition: gis.h:541
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
const char * G_getenv_nofatal(const char *name)
Get environment variable.
Definition: env.c:381
int multiple
Definition: gis.h:533
void G_set_keywords(const char *keywords)
Set keywords from the string.
Definition: parser.c:864
Structure that stores flag info.
Definition: gis.h:557
void G__script(void)
Generate Python script-like output.
Definition: parser_script.c:24
char key
Definition: gis.h:559
int required
Definition: gis.h:532
char * G_basename(char *filename, const char *desired_ext)
Truncates filename to the base part (before the last &#39;.&#39;) if it matches the extension, otherwise leaves it unchanged.
Definition: basename.c:38
#define GPATH_MAX
Definition: gis.h:167
char suppress_overwrite
Definition: gis.h:562
const char * G_program_name(void)
Return module name.
Definition: progrm_nme.c:28
int G_verbose_std(void)
Get standard verbosity level.
Definition: verbose.c:86
struct Flag * next_flag
Definition: gis.h:566
int G_verbose(void)
Get current verbosity level.
Definition: verbose.c:55
const char * label
Definition: gis.h:537
const char ** descs
Definition: gis.h:540
void G_usage(void)
Command line help/usage message.
Definition: parser_help.c:48
void G__split_gisprompt(const char *gisprompt, char *age, char *element, char *desc)
Definition: parser.c:1638
FILE * G_open_option_file(const struct Option *option)
Get an input/output file pointer from the option. If the file name is omitted or &#39;-&#39;, it returns either stdin or stdout based on the gisprompt.
Definition: parser.c:1785
char suppress_required
Definition: gis.h:561
void G_disable_interactive(void)
Disables the ability of the parser to operate interactively.
Definition: parser.c:137
#define MAX_MATCHES
Definition: parser.c:98
Definition: path.h:16
void G_free_tokens(char **tokens)
Free memory allocated to tokens.
Definition: gis/token.c:204
Structure that stores option information.
Definition: gis.h:528
#define _(str)
Definition: glocale.h:13
int G_verbose_min(void)
Get min verbosity level.
Definition: verbose.c:96
int(* checker)(const char *)
Definition: gis.h:548
char ** answers
Definition: gis.h:543
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
const char * key
Definition: gis.h:530
const char * gisprompt
Definition: gis.h:545
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:23
void G__print_keywords(FILE *fd, void(*format)(FILE *, const char *))
Print list of keywords (internal use only)
Definition: parser.c:908
void G_add_keyword(const char *keyword)
Add keyword to the list.
Definition: parser.c:848
const char * options
Definition: gis.h:534
int G_is_dirsep(char c)
Checks if a specified character is a valid directory separator character on the host system...
Definition: paths.c:45
void G__wps_print_process_description(void)
Print the WPS 1.0.0 process description XML document to stdout.
Definition: parser_wps.c:140
char * getenv()
struct state state
Definition: parser.c:101
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition: gisbase.c:41
const char * key_desc
Definition: gis.h:536
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
opt_error
Definition: parser.c:89
struct Option * next_opt
Definition: gis.h:544
int G_spawn(const char *command,...)
Spawn new process based on command.
Definition: spawn.c:924