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 {
90     BAD_SYNTAX    = 1,
91     OUT_OF_RANGE  = 2,
92     MISSING_VALUE = 3,
93     INVALID_VALUE = 4,
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 
G_disable_interactive(void)138 void G_disable_interactive(void)
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  */
G_define_flag(void)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  */
G_define_option(void)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  */
G_define_module(void)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  */
G_parser(int argc,char ** argv)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) {
496 	    G__wps_print_process_description();
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));
565                 G_suppress_warnings(TRUE);
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 
626     G__check_option_rules();
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  */
recreate_command(int original_path)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  */
G_recreate_command(void)821 char *G_recreate_command(void)
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  */
G_recreate_command_original_path(void)839 char *G_recreate_command_original_path(void)
840 {
841     return recreate_command(TRUE);
842 }
843 
844 /*!
845   \brief Add keyword to the list
846 
847   \param keyword keyword string
848 */
G_add_keyword(const char * keyword)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 */
G_set_keywords(const char * keywords)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 
G__uses_new_gisprompt(void)873 int G__uses_new_gisprompt(void)
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 */
G__print_keywords(FILE * fd,void (* format)(FILE *,const char *))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 */
G_get_overwrite()933 int G_get_overwrite()
934 {
935     return st->module_info.overwrite;
936 }
937 
define_keywords(void)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 */
module_gui_wx(void)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"),
968                 script, G_recreate_command_original_path(), NULL);
969     else
970         return -1;
971 
972     return 0;
973 }
974 
set_flag(int f)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  */
contains(const char * s,int c)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 
valid_option_name(const char * string)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 
is_option(const char * string)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 
match_option_1(const char * string,const char * option)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 
match_option(const char * string,const char * option)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 
set_option(const char * string)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 
check_opts(void)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 
check_an_opt(const char * key,int type,const char * options,const char ** opts,char ** answerp)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 
check_int(const char * ans,const char ** opts)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 
check_double(const char * ans,const char ** opts)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 
check_string(const char * ans,const char ** opts,int * result)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 
check_required(void)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 
split_opts(void)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 
check_multiple_opts(void)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 */
check_overwrite(void)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 
G__split_gisprompt(const char * gisprompt,char * age,char * element,char * desc)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 
append_error(const char * msg)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 
get_renamed_option(const char * key)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 */
G_option_to_separator(const struct Option * option)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 */
G_open_option_file(const struct Option * option)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 */
G_close_option_file(FILE * fp)1836 void G_close_option_file(FILE *fp)
1837 {
1838     if (fp != stdin && fp != stdout && fp != stderr)
1839 	fclose(fp);
1840 }
1841