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