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