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