GRASS 8 Programmer's Manual 8.6.0dev(2026)-09ad2796ff
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 size_t name_index = strlen(tmp_name);
337 while (name_index > 0) {
338 name_index--;
340 tmp_name += name_index + 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 (opt->key && !valid_option_name(opt->key))
360 G_warning(_("Bug in UI description. Option key <%s> is not valid"),
361 opt->key);
362 if (!opt->label && !opt->description)
363 G_warning(
364 _("Bug in UI description. Description for option <%s> missing"),
365 opt->key ? opt->key : "?");
366
367 /* Parse options */
368 if (opt->options) {
369 int cnt = 0;
370 char **tokens, delm[2];
371
372 delm[0] = ',';
373 delm[1] = '\0';
374 tokens = G_tokenize(opt->options, delm);
375
376 i = 0;
377 while (tokens[i]) {
378 G_chop(tokens[i]);
379 cnt++;
380 i++;
381 }
382
383 opt->opts = G_calloc(cnt + 1, sizeof(const char *));
384
385 i = 0;
386 while (tokens[i]) {
387 opt->opts[i] = G_store(tokens[i]);
388 i++;
389 }
391
392 if (opt->descriptions) {
393 delm[0] = ';';
394
395 opt->descs = G_calloc(cnt + 1, sizeof(const char *));
396 tokens = G_tokenize(opt->descriptions, delm);
397
398 i = 0;
399 while (tokens[i]) {
400 int j, found;
401
402 if (!tokens[i + 1])
403 break;
404
405 G_chop(tokens[i]);
406
407 j = 0;
408 found = 0;
409 while (opt->opts[j]) {
410 if (strcmp(opt->opts[j], tokens[i]) == 0) {
411 found = 1;
412 break;
413 }
414 j++;
415 }
416 if (!found) {
417 G_warning(_("Bug in UI description. Option '%s' in "
418 "<%s> does not exist"),
419 tokens[i], opt->key);
420 }
421 else {
422 opt->descs[j] = G_store(tokens[i + 1]);
423 }
424
425 i += 2;
426 }
428 }
429 }
430
431 /* Copy answer */
432 if (opt->multiple && opt->answers && opt->answers[0]) {
433 opt->answer = G_malloc(strlen(opt->answers[0]) + 1);
434 strcpy(opt->answer, opt->answers[0]);
435 for (i = 1; opt->answers[i]; i++) {
436 opt->answer =
437 G_realloc(opt->answer, strlen(opt->answer) +
438 strlen(opt->answers[i]) + 2);
439 strcat(opt->answer, ",");
440 strcat(opt->answer, opt->answers[i]);
441 }
442 }
443 opt->def = opt->answer;
444 opt = opt->next_opt;
445 }
446
447 /* If there are NO arguments, go interactive */
449 if (argc < 2 && (st->has_required || G__has_required_rule()) &&
450 !st->no_interactive && isatty(0) &&
451 (gui_envvar && G_strcasecmp(gui_envvar, "text") != 0)) {
452 if (module_gui_wx() == 0)
453 return -1;
454 }
455
457 G_usage();
458 return -1;
459 }
460 else if (argc >= 2) {
461
462 /* If first arg is "help" give a usage/syntax message */
463 if (strcmp(argv[1], "help") == 0 || strcmp(argv[1], "-help") == 0 ||
464 strcmp(argv[1], "--help") == 0) {
465 G_usage();
467 }
468
469 /* If first arg is "--help-text" give a usage/syntax message
470 * with machine-readable sentinels */
471 if (strcmp(argv[1], "--help-text") == 0) {
474 }
475
476 /* If first arg is "--interface-description" then print out
477 * an xml description of the task */
478 if (strcmp(argv[1], "--interface-description") == 0) {
479 G__usage_xml();
481 }
482
483 /* If first arg is "--html-description" then print out
484 * a html description of the task */
485 if (strcmp(argv[1], "--html-description") == 0) {
488 }
489
490 /* If first arg is "--rst-description" then print out
491 * a reStructuredText description of the task */
492 if (strcmp(argv[1], "--rst-description") == 0) {
495 }
496
497 /* If first arg is "--md-description" then print out
498 * a Markdown description of the task */
499 if (strcmp(argv[1], "--md-description") == 0) {
502 }
503
504 /* If first arg is "--wps-process-description" then print out
505 * the wps process description of the task */
506 if (strcmp(argv[1], "--wps-process-description") == 0) {
509 }
510
511 /* If first arg is "--script" then then generate
512 * g.parser boilerplate */
513 if (strcmp(argv[1], "--script") == 0) {
514 G__script();
516 }
517
518 /* Loop through all command line arguments */
519
520 while (--argc) {
521 ptr = *(++argv);
522
523 if (strcmp(ptr, "help") == 0 || strcmp(ptr, "--h") == 0 ||
524 strcmp(ptr, "-help") == 0 || strcmp(ptr, "--help") == 0) {
525 G_usage();
527 }
528
529 /* JSON print option */
530 if (strcmp(ptr, "--json") == 0) {
531 print_json = 1;
532 continue;
533 }
534
535 /* Overwrite option */
536 if (strcmp(ptr, "--o") == 0 || strcmp(ptr, "--overwrite") == 0) {
537 st->overwrite = 1;
538 }
539
540 /* Verbose option */
541 else if (strcmp(ptr, "--v") == 0 || strcmp(ptr, "--verbose") == 0) {
542 char buff[32];
543
544 /* print everything: max verbosity level */
545 st->module_info.verbose = G_verbose_max();
546 snprintf(buff, sizeof(buff), "GRASS_VERBOSE=%d",
547 G_verbose_max());
548 putenv(G_store(buff));
549 if (st->quiet == 1) {
550 G_warning(_("Use either --quiet or --verbose flag, not "
551 "both. Assuming --verbose."));
552 }
553 st->quiet = -1;
554 }
555
556 /* Quiet option */
557 else if (strcmp(ptr, "--q") == 0 || strcmp(ptr, "--quiet") == 0) {
558 char buff[32];
559
560 /* print nothing, but errors and warnings */
561 st->module_info.verbose = G_verbose_min();
562 snprintf(buff, sizeof(buff), "GRASS_VERBOSE=%d",
563 G_verbose_min());
564 putenv(G_store(buff));
565 if (st->quiet == -1) {
566 G_warning(_("Use either --quiet or --verbose flag, not "
567 "both. Assuming --quiet."));
568 }
569 st->quiet = 1; /* for passing to gui init */
570 }
571
572 /* Super quiet option */
573 else if (strcmp(ptr, "--qq") == 0) {
574 char buff[32];
575
576 /* print nothing, but errors */
577 st->module_info.verbose = G_verbose_min();
578 snprintf(buff, sizeof(buff), "GRASS_VERBOSE=%d",
579 G_verbose_min());
580 putenv(G_store(buff));
582 if (st->quiet == -1) {
583 G_warning(_("Use either --qq or --verbose flag, not both. "
584 "Assuming --qq."));
585 }
586 st->quiet = 1; /* for passing to gui init */
587 }
588
589 /* Force gui to come up */
590 else if (strcmp(ptr, "--ui") == 0) {
591 force_gui = TRUE;
592 }
593
594 /* If we see a flag */
595 else if (*ptr == '-') {
596 while (*(++ptr))
597 set_flag(*ptr);
598 }
599 /* If we see standard option format (option=val) */
600 else if (is_option(ptr)) {
601 set_option(ptr);
602 need_first_opt = 0;
603 }
604
605 /* If we see the first option with no equal sign */
606 else if (need_first_opt && st->n_opts) {
607 st->first_option.answer = G_store(ptr);
608 st->first_option.count++;
609 need_first_opt = 0;
610 }
611
612 /* If we see the non valid argument (no "=", just argument) */
613 else {
614 G_asprintf(&err, _("Sorry <%s> is not a valid option"), ptr);
615 append_error(err);
616 }
617 }
618 }
619
620 /* Split options where multiple answers are OK */
621 split_opts();
622
623 /* Run the gui if it was specifically requested */
624 if (force_gui) {
625 if (module_gui_wx() != 0)
626 G_fatal_error(_("Your installation doesn't include GUI, exiting."));
627 return -1;
628 }
629
630 /* Check multiple options */
631 check_multiple_opts();
632
633 /* Check answers against options and check subroutines */
634 if (!opt_checked)
635 check_opts();
636
637 /* Make sure all required options are set */
638 if (!st->suppress_required)
639 check_required();
640
642
643 if (st->n_errors > 0) {
644 if (G_verbose() > -1) {
645 if (G_verbose() > G_verbose_min())
646 G_usage();
647 fprintf(stderr, "\n");
648 for (i = 0; i < st->n_errors; i++) {
649 fprintf(stderr, "%s: %s\n", _("ERROR"), st->error[i]);
650 }
651 }
652 return -1;
653 }
654
655 /* Print the JSON definition of the command and exit */
656 if (print_json == 1) {
657 G__json();
659 }
660
661 if (!st->suppress_overwrite) {
662 if (check_overwrite())
663 return -1;
664 }
665
666 return 0;
667}
668
669/*!
670 * \brief Creates command to run non-interactive.
671 *
672 * Creates a command-line that runs the current command completely
673 * non-interactive.
674 *
675 * \param original_path TRUE if original path should be used, FALSE for
676 * stripped and clean name of the module
677 * \return pointer to a char string
678 */
680{
681 char *buff;
682 char flg[4];
683 char *cur;
684 const char *tmp;
685 struct Flag *flag;
686 struct Option *opt;
687 int n;
688 size_t len, slen;
689 size_t nalloced = 0;
690
691 G_debug(3, "G_recreate_command()");
692
693 /* Flag is not valid if there are no flags to set */
694
695 buff = G_calloc(1024, sizeof(char));
696 nalloced += 1024;
697 if (original_path)
699 else
700 tmp = G_program_name();
701 len = strlen(tmp);
702 if (len >= nalloced) {
703 nalloced += (1024 > len) ? 1024 : len + 1;
704 buff = G_realloc(buff, nalloced);
705 }
706 cur = buff;
707 strcpy(cur, tmp);
708 cur += len;
709
710 if (st->overwrite) {
711 slen = strlen(" --overwrite");
712 if (len + slen >= nalloced) {
713 nalloced += (1024 > len) ? 1024 : len + 1;
714 buff = G_realloc(buff, nalloced);
715 }
716 strcpy(cur, " --overwrite");
717 cur += slen;
718 len += slen;
719 }
720
721 if (st->module_info.verbose != G_verbose_std()) {
722 char *sflg;
723
724 if (st->module_info.verbose == G_verbose_max())
725 sflg = " --verbose";
726 else
727 sflg = " --quiet";
728
729 slen = strlen(sflg);
730 if (len + slen >= nalloced) {
731 nalloced += (1024 > len) ? 1024 : len + 1;
732 buff = G_realloc(buff, nalloced);
733 }
734 strcpy(cur, sflg);
735 cur += slen;
736 len += slen;
737 }
738
739 if (st->n_flags) {
740 flag = &st->first_flag;
741 while (flag) {
742 if (flag->answer == 1) {
743 flg[0] = ' ';
744 flg[1] = '-';
745 flg[2] = flag->key;
746 flg[3] = '\0';
747 slen = strlen(flg);
748 if (len + slen >= nalloced) {
749 nalloced +=
750 (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
751 buff = G_realloc(buff, nalloced);
752 cur = buff + len;
753 }
754 strcpy(cur, flg);
755 cur += slen;
756 len += slen;
757 }
758 flag = flag->next_flag;
759 }
760 }
761
762 opt = &st->first_option;
763 while (st->n_opts && opt) {
764 if (opt->answer && opt->answer[0] == '\0') { /* answer = "" */
765 slen = strlen(opt->key) + 4; /* +4 for: ' ' = " " */
766 if (len + slen >= nalloced) {
767 nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
768 buff = G_realloc(buff, nalloced);
769 cur = buff + len;
770 }
771 strcpy(cur, " ");
772 cur++;
773 strcpy(cur, opt->key);
774 cur = strchr(cur, '\0');
775 strcpy(cur, "=");
776 cur++;
777 if (opt->type == TYPE_STRING) {
778 strcpy(cur, "\"\"");
779 cur += 2;
780 }
781 len = cur - buff;
782 }
783 else if (opt->answer && opt->answers && opt->answers[0]) {
784 slen = strlen(opt->key) + strlen(opt->answers[0]) +
785 4; /* +4 for: ' ' = " " */
786 if (len + slen >= nalloced) {
787 nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
788 buff = G_realloc(buff, nalloced);
789 cur = buff + len;
790 }
791 strcpy(cur, " ");
792 cur++;
793 strcpy(cur, opt->key);
794 cur = strchr(cur, '\0');
795 strcpy(cur, "=");
796 cur++;
797 if (opt->type == TYPE_STRING) {
798 strcpy(cur, "\"");
799 cur++;
800 }
801 strcpy(cur, opt->answers[0]);
802 cur = strchr(cur, '\0');
803 len = cur - buff;
804 for (n = 1; opt->answers[n]; n++) {
805 if (!opt->answers[n])
806 break;
807 slen = strlen(opt->answers[n]) + 2; /* +2 for , " */
808 if (len + slen >= nalloced) {
809 nalloced +=
810 (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
811 buff = G_realloc(buff, nalloced);
812 cur = buff + len;
813 }
814 strcpy(cur, ",");
815 cur++;
816 strcpy(cur, opt->answers[n]);
817 cur = strchr(cur, '\0');
818 len = cur - buff;
819 }
820 if (opt->type == TYPE_STRING) {
821 strcpy(cur, "\"");
822 cur++;
823 len = cur - buff;
824 }
825 }
826 opt = opt->next_opt;
827 }
828
829 return buff;
830}
831
832/*!
833 * \brief Creates command to run non-interactive.
834 *
835 * Creates a command-line that runs the current command completely
836 * non-interactive.
837 *
838 * \return pointer to a char string
839 */
841{
842 return recreate_command(FALSE);
843}
844
845/* TODO: update to docs of these 3 functions to whatever general purpose
846 * they have now. */
847/*!
848 * \brief Creates command to run non-interactive.
849 *
850 * Creates a command-line that runs the current command completely
851 * non-interactive.
852 *
853 * This gives the same as G_recreate_command() but the original path
854 * from the command line is used instead of the module name only.
855 *
856 * \return pointer to a char string
857 */
859{
860 return recreate_command(TRUE);
861}
862
863/*!
864 \brief Add keyword to the list
865
866 \param keyword keyword string
867 */
868void G_add_keyword(const char *keyword)
869{
870 if (st->n_keys >= st->n_keys_alloc) {
871 st->n_keys_alloc += 10;
872 st->module_info.keywords = G_realloc(st->module_info.keywords,
873 st->n_keys_alloc * sizeof(char *));
874 }
875
876 st->module_info.keywords[st->n_keys++] = G_store(keyword);
877}
878
879/*!
880 \brief Set keywords from the string
881
882 \param keywords keywords separated by commas
883 */
884void G_set_keywords(const char *keywords)
885{
886 char **tokens = G_tokenize(keywords, ",");
887
888 st->module_info.keywords = (const char **)tokens;
889 st->n_keys = st->n_keys_alloc = G_number_of_tokens(tokens);
890}
891
893{
894 struct Option *opt;
895 char age[KEYLENGTH];
896 char element[KEYLENGTH];
897 char desc[KEYLENGTH];
898
899 if (st->module_info.overwrite)
900 return 1;
901
902 /* figure out if any of the options use a "new" gisprompt */
903 /* This is to see if we should spit out the --o flag */
904 if (st->n_opts) {
905 opt = &st->first_option;
906 while (opt) {
907 if (opt->gisprompt) {
908 G__split_gisprompt(opt->gisprompt, age, element, desc);
909 if (strcmp(age, "new") == 0)
910 return 1;
911 }
912 opt = opt->next_opt;
913 }
914 }
915
916 return 0;
917}
918
919/*!
920 \brief Print list of keywords (internal use only)
921
922 If <em>format</em> function is NULL then list of keywords is printed
923 comma-separated.
924
925 \param[out] fd file where to print
926 \param format pointer to print function
927 \param newline TRUE to include newline
928 */
929void G__print_keywords(FILE *fd, void (*format)(FILE *, const char *),
930 int newline)
931{
932 int i;
933
934 for (i = 0; i < st->n_keys; i++) {
935 if (!format) {
936 fprintf(fd, "%s", st->module_info.keywords[i]);
937 }
938 else {
939 format(fd, st->module_info.keywords[i]);
940 }
941 if (i < st->n_keys - 1) {
942 fprintf(fd, ",");
943 if (!newline)
944 fprintf(fd, " ");
945 }
946 if (newline)
947 fprintf(fd, "\n");
948 }
949
950 fflush(fd);
951}
952
953/*!
954 \brief Get overwrite value
955
956 \return 1 overwrite enabled
957 \return 0 overwrite disabled
958 */
960{
961 return st->module_info.overwrite;
962}
963
964void define_keywords(void)
965{
966 st->n_keys = 0;
967 st->n_keys_alloc = 0;
968}
969
970/**************************************************************************
971 *
972 * The remaining routines are all local (static) routines used to support
973 * the parsing process.
974 *
975 **************************************************************************/
976
977/*!
978 \brief Invoke GUI dialog
979 */
980int module_gui_wx(void)
981{
982 char script[GPATH_MAX];
983
984 /* TODO: the 4 following lines seems useless */
985 if (!st->pgm_path)
986 st->pgm_path = G_program_name();
987 if (!st->pgm_path)
988 G_fatal_error(_("Unable to determine program name"));
989
990 const char *wxdir = getenv("GRASS_GUIWXDIR");
991 if (!wxdir)
992 G_fatal_error(_("Incomplete GRASS session: Variable '%s' not set"),
993 "GRASS_GUIWXDIR");
994
995 snprintf(script, GPATH_MAX, "%s/gui_core/forms.py", wxdir);
996 if (access(script, F_OK) != -1)
997 G_spawn(getenv("GRASS_PYTHON"), getenv("GRASS_PYTHON"), script,
999 else
1000 return -1;
1001
1002 return 0;
1003}
1004
1005void set_flag(int f)
1006{
1007 struct Flag *flag;
1008 char *key, *err;
1009 const char *renamed_key;
1010
1011 err = NULL;
1012
1013 /* Flag is not valid if there are no flags to set */
1014 if (!st->n_flags) {
1015 G_asprintf(&err, _("%s: Sorry, <%c> is not a valid flag"),
1016 G_program_name(), f);
1017 append_error(err);
1018 return;
1019 }
1020
1021 /* Find flag with correct keyword */
1022 flag = &st->first_flag;
1023 while (flag) {
1024 if (flag->key == f) {
1025 flag->answer = 1;
1026 if (flag->suppress_required)
1027 st->suppress_required = 1;
1028 if (flag->suppress_overwrite)
1029 st->suppress_overwrite = 1;
1030 return;
1031 }
1032 flag = flag->next_flag;
1033 }
1034
1035 /* First, check if key has been renamed */
1036 G_asprintf(&key, "-%c", f);
1037 renamed_key = get_renamed_option(key);
1038 G_free(key);
1039
1040 if (renamed_key) {
1041 /* if renamed to a new flag */
1042 if (*renamed_key == '-') {
1043 /* if renamed to a long flag */
1044 if (renamed_key[1] == '-') {
1045 if (strcmp(renamed_key, "--overwrite") == 0) {
1046 /* this is a special case for -? to --overwrite */
1047 G_warning(_("Please update the usage of <%s>: "
1048 "flag <%c> has been renamed to <%s>"),
1050 st->overwrite = 1;
1051 }
1052 else {
1053 /* long flags other than --overwrite are usually specific to
1054 * GRASS internals, just print an error and let's not
1055 * support them */
1056 G_asprintf(&err,
1057 _("Please update the usage of <%s>: "
1058 "flag <%c> has been renamed to <%s>"),
1060 append_error(err);
1061 }
1062 return;
1063 }
1064 /* if renamed to a short flag */
1065 for (flag = &st->first_flag; flag; flag = flag->next_flag) {
1066 if (renamed_key[1] == flag->key) {
1067 G_warning(_("Please update the usage of <%s>: "
1068 "flag <%c> has been renamed to <%s>"),
1070 flag->answer = 1;
1071 if (flag->suppress_required)
1072 st->suppress_required = 1;
1073 if (flag->suppress_overwrite)
1074 st->suppress_overwrite = 1;
1075 return;
1076 }
1077 }
1078 }
1079 else {
1080 /* if renamed to a new option (no option value given but will be
1081 * required), fatal error */
1082 struct Option *opt = NULL;
1083 for (opt = &st->first_option; opt; opt = opt->next_opt) {
1084 if (strcmp(renamed_key, opt->key) == 0) {
1085 G_asprintf(&err,
1086 _("Please update the usage of <%s>: "
1087 "flag <%c> has been renamed to option <%s>"),
1089 append_error(err);
1090 return;
1091 }
1092 }
1093 }
1094 }
1095
1096 G_asprintf(&err, _("%s: Sorry, <%c> is not a valid flag"), G_program_name(),
1097 f);
1098 append_error(err);
1099}
1100
1101/* contents() is used to find things strings with characters like commas and
1102 * dashes.
1103 */
1104int contains(const char *s, int c)
1105{
1106 while (*s) {
1107 if (*s == c)
1108 return TRUE;
1109 s++;
1110 }
1111 return FALSE;
1112}
1113
1114int valid_option_name(const char *string)
1115{
1116 size_t m = strlen(string);
1117 size_t n = strspn(string, "abcdefghijklmnopqrstuvwxyz0123456789_");
1118
1119 if (!m)
1120 return 0;
1121
1122 if (m != n)
1123 return 0;
1124
1125 if (string[m - 1] == '_')
1126 return 0;
1127
1128 return 1;
1129}
1130
1131int is_option(const char *string)
1132{
1133 size_t n = strspn(string, "abcdefghijklmnopqrstuvwxyz0123456789_");
1134
1135 return n > 0 && string[n] == '=' && string[0] != '_' &&
1136 string[n - 1] != '_';
1137}
1138
1139int match_option_1(const char *string, const char *option)
1140{
1141 const char *next;
1142
1143 if (*string == '\0')
1144 return 1;
1145
1146 if (*option == '\0')
1147 return 0;
1148
1149 if (*string == *option && match_option_1(string + 1, option + 1))
1150 return 1;
1151
1152 if (*option == '_' && match_option_1(string, option + 1))
1153 return 1;
1154
1155 next = strchr(option, '_');
1156 if (!next)
1157 return 0;
1158
1159 if (*string == '_')
1160 return match_option_1(string + 1, next + 1);
1161
1162 return match_option_1(string, next + 1);
1163}
1164
1165int match_option(const char *string, const char *option)
1166{
1167 return (*string == *option) && match_option_1(string + 1, option + 1);
1168}
1169
1170void set_option(const char *string)
1171{
1172 struct Option *at_opt = NULL;
1173 struct Option *opt = NULL;
1174 size_t key_len;
1175 char the_key[KEYLENGTH];
1176 char *ptr, *err;
1177 struct Option *matches[MAX_MATCHES];
1178 int found = 0;
1179
1180 err = NULL;
1181
1182 for (ptr = the_key; *string != '='; ptr++, string++)
1183 *ptr = *string;
1184 *ptr = '\0';
1185 string++;
1186
1187 /* an empty string is not a valid answer, skip */
1188 if (!*string)
1189 return;
1190
1191 /* Find option with best keyword match */
1193 for (at_opt = &st->first_option; at_opt; at_opt = at_opt->next_opt) {
1194 if (!at_opt->key)
1195 continue;
1196
1197 if (strcmp(the_key, at_opt->key) == 0) {
1198 matches[0] = at_opt;
1199 found = 1;
1200 break;
1201 }
1202
1203 if (strncmp(the_key, at_opt->key, key_len) == 0 ||
1204 match_option(the_key, at_opt->key)) {
1205 if (found >= MAX_MATCHES)
1206 G_fatal_error("Too many matches (limit %d)", MAX_MATCHES);
1207 matches[found++] = at_opt;
1208 }
1209 }
1210
1211 if (found > 1) {
1212 int shortest = 0;
1213 size_t length = strlen(matches[0]->key);
1214 int prefix = 1;
1215 int i;
1216
1217 for (i = 1; i < found; i++) {
1218 size_t len = strlen(matches[i]->key);
1219
1220 if (len < length) {
1221 length = len;
1222 shortest = i;
1223 }
1224 }
1225 for (i = 0; prefix && i < found; i++)
1226 if (strncmp(matches[i]->key, matches[shortest]->key, length) != 0)
1227 prefix = 0;
1228 if (prefix) {
1229 matches[0] = matches[shortest];
1230 found = 1;
1231 }
1232 else {
1233 G_asprintf(&err, _("%s: Sorry, <%s=> is ambiguous"),
1235 append_error(err);
1236 for (i = 0; i < found; i++) {
1237 G_asprintf(&err, _("Option <%s=> matches"), matches[i]->key);
1238 append_error(err);
1239 }
1240 return;
1241 }
1242 }
1243
1244 if (found)
1245 opt = matches[0];
1246
1247 /* First, check if key has been renamed */
1248 if (found == 0) {
1249 const char *renamed_key = get_renamed_option(the_key);
1250
1251 if (renamed_key) {
1252 /* if renamed to a new flag (option value given but will be lost),
1253 * fatal error */
1254 if (*renamed_key == '-') {
1255 if (renamed_key[1] == '-')
1256 G_asprintf(&err,
1257 _("Please update the usage of <%s>: "
1258 "option <%s> has been renamed to flag <%s>"),
1260 else
1261 G_asprintf(&err,
1262 _("Please update the usage of <%s>: "
1263 "option <%s> has been renamed to flag <%c>"),
1265 append_error(err);
1266 return;
1267 }
1268
1269 /* if renamed to a new option */
1270 for (at_opt = &st->first_option; at_opt;
1271 at_opt = at_opt->next_opt) {
1272 if (strcmp(renamed_key, at_opt->key) == 0) {
1273 G_warning(_("Please update the usage of <%s>: "
1274 "option <%s> has been renamed to <%s>"),
1276 opt = at_opt;
1277 found = 1;
1278 break;
1279 }
1280 }
1281 }
1282 }
1283
1284 /* If there is no match, complain */
1285 if (found == 0) {
1286 G_asprintf(&err, _("%s: Sorry, <%s> is not a valid parameter"),
1288 append_error(err);
1289 return;
1290 }
1291
1292 if (getenv("GRASS_FULL_OPTION_NAMES") && strcmp(the_key, opt->key) != 0)
1293 G_warning(_("<%s> is an abbreviation for <%s>"), the_key, opt->key);
1294
1295 /* Allocate memory where answer is stored */
1296 if (opt->count++) {
1297 if (!opt->multiple) {
1298 G_asprintf(&err, _("Option <%s> does not accept multiple answers"),
1299 opt->key);
1300 append_error(err);
1301 }
1302 opt->answer =
1303 G_realloc(opt->answer, strlen(opt->answer) + strlen(string) + 2);
1304 strcat(opt->answer, ",");
1305 strcat(opt->answer, string);
1306 }
1307 else
1308 opt->answer = G_store(string);
1309}
1310
1311void check_opts(void)
1312{
1313 struct Option *opt;
1314 int ans;
1315
1316 if (!st->n_opts)
1317 return;
1318
1319 opt = &st->first_option;
1320 while (opt) {
1321 /* Check answer against options if any */
1322
1323 if (opt->answer) {
1324 if (opt->multiple == 0)
1325 check_an_opt(opt->key, opt->type, opt->options, opt->opts,
1326 &opt->answer);
1327 else {
1328 for (ans = 0; opt->answers[ans] != NULL; ans++)
1329 check_an_opt(opt->key, opt->type, opt->options, opt->opts,
1330 &opt->answers[ans]);
1331 }
1332 }
1333
1334 /* Check answer against user's check subroutine if any */
1335
1336 if (opt->checker)
1337 opt->checker(opt->answer);
1338
1339 opt = opt->next_opt;
1340 }
1341}
1342
1343void check_an_opt(const char *key, int type, const char *options,
1344 const char **opts, char **answerp)
1345{
1346 const char *answer = *answerp;
1347 int error;
1348 char *err;
1349 int found;
1350
1351 error = 0;
1352 err = NULL;
1353 found = 0;
1354
1355 switch (type) {
1356 case TYPE_INTEGER:
1357 error = check_int(answer, opts);
1358 break;
1359 case TYPE_DOUBLE:
1360 error = check_double(answer, opts);
1361 break;
1362 case TYPE_STRING:
1363 error = check_string(answer, opts, &found);
1364 break;
1365 }
1366 switch (error) {
1367 case 0:
1368 break;
1369 case BAD_SYNTAX:
1370 G_asprintf(&err,
1371 _("Illegal range syntax for parameter <%s>\n"
1372 "\tPresented as: %s"),
1373 key, options);
1374 append_error(err);
1375 break;
1376 case OUT_OF_RANGE:
1377 G_asprintf(&err,
1378 _("Value <%s> out of range for parameter <%s>\n"
1379 "\tLegal range: %s"),
1380 answer, key, options);
1381 append_error(err);
1382 break;
1383 case MISSING_VALUE:
1384 G_asprintf(&err, _("Missing value for parameter <%s>"), key);
1385 append_error(err);
1386 break;
1387 case INVALID_VALUE:
1388 G_asprintf(&err, _("Invalid value <%s> for parameter <%s>"), answer,
1389 key);
1390 append_error(err);
1391 break;
1392 case AMBIGUOUS:
1393 G_asprintf(&err,
1394 _("Value <%s> ambiguous for parameter <%s>\n"
1395 "\tValid options: %s"),
1396 answer, key, options);
1397 append_error(err);
1398 break;
1399 case REPLACED:
1401 error = 0;
1402 break;
1403 }
1404}
1405
1406int check_int(const char *ans, const char **opts)
1407{
1408 int d, i;
1409
1410 /* "-" is reserved for standard input */
1411 if (strcmp(ans, "-") == 0)
1412 return 0;
1413
1414 if (!ans || !*ans)
1415 return MISSING_VALUE;
1416
1417 if (sscanf(ans, "%d", &d) != 1)
1418 return INVALID_VALUE;
1419
1420 if (!opts)
1421 return 0;
1422
1423 for (i = 0; opts[i]; i++) {
1424 const char *opt = opts[i];
1425 int lo, hi;
1426
1427 if (contains(opt, '-')) {
1428 if (sscanf(opt, "%d-%d", &lo, &hi) == 2) {
1429 if (d >= lo && d <= hi)
1430 return 0;
1431 }
1432 else if (sscanf(opt, "-%d", &hi) == 1) {
1433 if (d <= hi)
1434 return 0;
1435 }
1436 else if (sscanf(opt, "%d-", &lo) == 1) {
1437 if (d >= lo)
1438 return 0;
1439 }
1440 else
1441 return BAD_SYNTAX;
1442 }
1443 else {
1444 if (sscanf(opt, "%d", &lo) == 1) {
1445 if (d == lo)
1446 return 0;
1447 }
1448 else
1449 return BAD_SYNTAX;
1450 }
1451 }
1452
1453 return OUT_OF_RANGE;
1454}
1455
1456int check_double(const char *ans, const char **opts)
1457{
1458 double d;
1459 int i;
1460
1461 /* "-" is reserved for standard input */
1462 if (strcmp(ans, "-") == 0)
1463 return 0;
1464
1465 if (!ans || !*ans)
1466 return MISSING_VALUE;
1467
1468 if (sscanf(ans, "%lf", &d) != 1)
1469 return INVALID_VALUE;
1470
1471 if (!opts)
1472 return 0;
1473
1474 for (i = 0; opts[i]; i++) {
1475 const char *opt = opts[i];
1476 double lo, hi;
1477
1478 if (contains(opt, '-')) {
1479 if (sscanf(opt, "%lf-%lf", &lo, &hi) == 2) {
1480 if (d >= lo && d <= hi)
1481 return 0;
1482 }
1483 else if (sscanf(opt, "-%lf", &hi) == 1) {
1484 if (d <= hi)
1485 return 0;
1486 }
1487 else if (sscanf(opt, "%lf-", &lo) == 1) {
1488 if (d >= lo)
1489 return 0;
1490 }
1491 else
1492 return BAD_SYNTAX;
1493 }
1494 else {
1495 if (sscanf(opt, "%lf", &lo) == 1) {
1496 if (d == lo)
1497 return 0;
1498 }
1499 else
1500 return BAD_SYNTAX;
1501 }
1502 }
1503
1504 return OUT_OF_RANGE;
1505}
1506
1507int check_string(const char *ans, const char **opts, int *result)
1508{
1509 size_t len = strlen(ans);
1510 int found = 0;
1511 int matches[MAX_MATCHES];
1512 int i;
1513
1514 if (!opts)
1515 return 0;
1516
1517 for (i = 0; opts[i]; i++) {
1518 if (strcmp(ans, opts[i]) == 0)
1519 return 0;
1520 if (strncmp(ans, opts[i], len) == 0 || match_option(ans, opts[i])) {
1521 if (found >= MAX_MATCHES)
1522 G_fatal_error("too many matches (limit %d)", MAX_MATCHES);
1523 matches[found++] = i;
1524 }
1525 }
1526
1527 if (found > 1) {
1528 int shortest = 0;
1529 size_t length = strlen(opts[matches[0]]);
1530 int prefix = 1;
1531
1532 for (i = 1; i < found; i++) {
1533 size_t lengthi = strlen(opts[matches[i]]);
1534
1535 if (lengthi < length) {
1536 length = lengthi;
1537 shortest = i;
1538 }
1539 }
1540 for (i = 0; prefix && i < found; i++)
1541 if (strncmp(opts[matches[i]], opts[matches[shortest]], length) != 0)
1542 prefix = 0;
1543 if (prefix) {
1544 matches[0] = matches[shortest];
1545 found = 1;
1546 }
1547 }
1548
1549 if (found == 1)
1550 *result = matches[0];
1551
1552 if (found > 0 && getenv("GRASS_FULL_OPTION_NAMES") &&
1553 strcmp(ans, opts[matches[0]]) != 0)
1554 G_warning(_("<%s> is an abbreviation for <%s>"), ans, opts[matches[0]]);
1555
1556 switch (found) {
1557 case 0:
1558 return OUT_OF_RANGE;
1559 case 1:
1560 return REPLACED;
1561 default:
1562 return AMBIGUOUS;
1563 }
1564}
1565
1566void check_required(void)
1567{
1568 struct Option *opt;
1569 char *err;
1570
1571 err = NULL;
1572
1573 if (!st->n_opts)
1574 return;
1575
1576 opt = &st->first_option;
1577 while (opt) {
1578 if (opt->required && !opt->answer) {
1579 G_asprintf(&err,
1580 _("Required parameter <%s> not set:\n"
1581 "\t(%s)"),
1582 opt->key, (opt->label ? opt->label : opt->description));
1583 append_error(err);
1584 }
1585 opt = opt->next_opt;
1586 }
1587}
1588
1589void split_opts(void)
1590{
1591 struct Option *opt;
1592 const char *ptr1;
1593 const char *ptr2;
1594 int allocated;
1595 int ans_num;
1596 int len;
1597
1598 if (!st->n_opts)
1599 return;
1600
1601 opt = &st->first_option;
1602 while (opt) {
1603 if (/*opt->multiple && */ opt->answer) {
1604 /* Allocate some memory to store array of pointers */
1605 allocated = 10;
1606 opt->answers = G_malloc(allocated * sizeof(char *));
1607
1608 ans_num = 0;
1609 ptr1 = opt->answer;
1610 opt->answers[ans_num] = NULL;
1611
1612 for (;;) {
1613 for (len = 0, ptr2 = ptr1; *ptr2 != '\0' && *ptr2 != ',';
1614 ptr2++, len++)
1615 ;
1616
1617 if (len > 0) { /* skip ,, */
1618 opt->answers[ans_num] = G_malloc(len + 1);
1619 memcpy(opt->answers[ans_num], ptr1, len);
1620 opt->answers[ans_num][len] = 0;
1621
1622 ans_num++;
1623
1624 if (ans_num >= allocated) {
1625 allocated += 10;
1626 opt->answers =
1627 G_realloc(opt->answers, allocated * sizeof(char *));
1628 }
1629
1630 opt->answers[ans_num] = NULL;
1631 }
1632
1633 if (*ptr2 == '\0')
1634 break;
1635
1636 ptr1 = ptr2 + 1;
1637
1638 if (*ptr1 == '\0')
1639 break;
1640 }
1641 }
1642 opt = opt->next_opt;
1643 }
1644}
1645
1646void check_multiple_opts(void)
1647{
1648 struct Option *opt;
1649 const char *ptr;
1650 int n_commas;
1651 int n;
1652 char *err;
1653
1654 if (!st->n_opts)
1655 return;
1656
1657 err = NULL;
1658 opt = &st->first_option;
1659 while (opt) {
1660 /* "-" is reserved from standard input/output */
1661 if (opt->answer && strcmp(opt->answer, "-") && opt->key_desc) {
1662 /* count commas */
1663 n_commas = 1;
1664 for (ptr = opt->key_desc; *ptr != '\0'; ptr++)
1665 if (*ptr == ',')
1666 n_commas++;
1667 /* count items */
1668 for (n = 0; opt->answers[n] != NULL; n++)
1669 ;
1670 /* if not correct multiple of items */
1671 if (n % n_commas) {
1672 G_asprintf(&err,
1673 _("Option <%s> must be provided in multiples of %d\n"
1674 "\tYou provided %d item(s): %s"),
1675 opt->key, n_commas, n, opt->answer);
1676 append_error(err);
1677 }
1678 }
1679 opt = opt->next_opt;
1680 }
1681}
1682
1683/* Check for all 'new' if element already exists */
1684int check_overwrite(void)
1685{
1686 struct Option *opt;
1687 char age[KEYLENGTH];
1688 char element[KEYLENGTH];
1689 char desc[KEYLENGTH];
1690 int error = 0;
1691 const char *overstr;
1692 int over;
1693
1694 st->module_info.overwrite = 0;
1695
1696 if (!st->n_opts)
1697 return (0);
1698
1699 over = 0;
1700 /* Check the GRASS OVERWRITE variable */
1701 if ((overstr = G_getenv_nofatal("OVERWRITE"))) {
1702 over = atoi(overstr);
1703 }
1704
1705 /* Check the GRASS_OVERWRITE environment variable */
1706 if ((overstr = getenv("GRASS_OVERWRITE"))) {
1707 if (atoi(overstr))
1708 over = 1;
1709 }
1710
1711 if (st->overwrite || over) {
1712 st->module_info.overwrite = 1;
1713 /* Set the environment so that programs run in a script also obey --o */
1714 putenv("GRASS_OVERWRITE=1");
1715 /* No need to check options for existing files if overwrite is true */
1716 return error;
1717 }
1718
1719 opt = &st->first_option;
1720 while (opt) {
1721 if (opt->answer && opt->gisprompt) {
1722 G__split_gisprompt(opt->gisprompt, age, element, desc);
1723
1724 if (strcmp(age, "new") == 0) {
1725 int i;
1726 char found;
1727
1728 for (i = 0; opt->answers[i]; i++) {
1729 found = FALSE;
1730 if (strcmp(element, "file") == 0) {
1731 if (access(opt->answers[i], F_OK) == 0)
1732 found = TRUE;
1733 }
1734 else if (strcmp(element, "mapset") != 0) {
1735 /* TODO: also other elements should be
1736 probably skipped */
1737 if (G_find_file(element, opt->answers[i], G_mapset())) {
1738 found = TRUE;
1739 }
1740 }
1741
1742 if (found) { /* found */
1743 if (!st->overwrite && !over) {
1744 if (G_verbose() > -1) {
1746 fprintf(stderr, _("ERROR: "));
1748 _("option <%s>: <%s> exists. To "
1749 "overwrite, use the --overwrite "
1750 "flag"),
1751 opt->key, opt->answers[i]);
1752 fprintf(stderr, "\n");
1753 }
1754 else {
1755 fprintf(stderr, "GRASS_INFO_ERROR(%d,1): ",
1756 getpid());
1758 _("option <%s>: <%s> exists. To "
1759 "overwrite, use the --overwrite "
1760 "flag"),
1761 opt->key, opt->answers[i]);
1762 fprintf(stderr, "\n");
1763 fprintf(stderr, "GRASS_INFO_END(%d,1)\n",
1764 getpid());
1765 }
1766 }
1767 error = 1;
1768 }
1769 }
1770 }
1771 }
1772 }
1773 opt = opt->next_opt;
1774 }
1775
1776 return (error);
1777}
1778
1779void G__split_gisprompt(const char *gisprompt, char *age, char *element,
1780 char *desc)
1781{
1782 const char *ptr1;
1783 char *ptr2;
1784
1785 for (ptr1 = gisprompt, ptr2 = age; *ptr1 != '\0'; ptr1++, ptr2++) {
1786 if (*ptr1 == ',')
1787 break;
1788 *ptr2 = *ptr1;
1789 }
1790 *ptr2 = '\0';
1791
1792 for (ptr1++, ptr2 = element; *ptr1 != '\0'; ptr1++, ptr2++) {
1793 if (*ptr1 == ',')
1794 break;
1795 *ptr2 = *ptr1;
1796 }
1797 *ptr2 = '\0';
1798
1799 for (ptr1++, ptr2 = desc; *ptr1 != '\0'; ptr1++, ptr2++) {
1800 if (*ptr1 == ',')
1801 break;
1802 *ptr2 = *ptr1;
1803 }
1804 *ptr2 = '\0';
1805}
1806
1807void append_error(const char *msg)
1808{
1809 st->error = G_realloc(st->error, sizeof(char *) * (st->n_errors + 1));
1810 st->error[st->n_errors++] = G_store(msg);
1811}
1812
1813const char *get_renamed_option(const char *key)
1814{
1815 const char *pgm, *key_new;
1816 char *pgm_key;
1817
1818 if (!st->renamed_options) {
1819 /* read renamed options from file (renamed_options) */
1820 char path[GPATH_MAX];
1821
1822 snprintf(path, GPATH_MAX, "%s/renamed_options", G_etc_dir());
1823 st->renamed_options = G_read_key_value_file(path);
1824 }
1825
1826 /* try to check global changes first */
1827 key_new = G_find_key_value(key, st->renamed_options);
1828 if (key_new)
1829 return key_new;
1830
1831 /* then check module-relevant changes */
1832 pgm = G_program_name();
1833 pgm_key = (char *)G_malloc(strlen(pgm) + strlen(key) + 2);
1834 G_asprintf(&pgm_key, "%s|%s", pgm, key);
1835
1836 key_new = G_find_key_value(pgm_key, st->renamed_options);
1837 G_free(pgm_key);
1838
1839 return key_new;
1840}
1841
1842/*!
1843 \brief Get separator string from the option.
1844
1845 Calls G_fatal_error() on error. Allocated string can be later freed
1846 by G_free().
1847
1848 \code
1849 char *fs;
1850 struct Option *opt_fs;
1851
1852 opt_fs = G_define_standard_option(G_OPT_F_SEP);
1853
1854 if (G_parser(argc, argv))
1855 exit(EXIT_FAILURE);
1856
1857 fs = G_option_to_separator(opt_fs);
1858 \endcode
1859
1860 \param option pointer to separator option
1861
1862 \return allocated string with separator
1863 */
1865{
1866 char *sep;
1867
1868 if (option->gisprompt == NULL ||
1869 strcmp(option->gisprompt, "old,separator,separator") != 0)
1870 G_fatal_error(_("%s= is not a separator option"), option->key);
1871
1872 if (option->answer == NULL)
1873 G_fatal_error(_("No separator given for %s="), option->key);
1874
1875 if (strcmp(option->answer, "pipe") == 0)
1876 sep = G_store("|");
1877 else if (strcmp(option->answer, "comma") == 0)
1878 sep = G_store(",");
1879 else if (strcmp(option->answer, "space") == 0)
1880 sep = G_store(" ");
1881 else if (strcmp(option->answer, "tab") == 0 ||
1882 strcmp(option->answer, "\\t") == 0)
1883 sep = G_store("\t");
1884 else if (strcmp(option->answer, "newline") == 0 ||
1885 strcmp(option->answer, "\\n") == 0)
1886 sep = G_store("\n");
1887 else
1888 sep = G_store(option->answer);
1889
1890 G_debug(3, "G_option_to_separator(): key = %s -> sep = '%s'", option->key,
1891 sep);
1892
1893 return sep;
1894}
1895
1896/*!
1897 \brief Get an input/output file pointer from the option. If the file name is
1898 omitted or '-', it returns either stdin or stdout based on the gisprompt.
1899
1900 Calls G_fatal_error() on error. File pointer can be later closed by
1901 G_close_option_file().
1902
1903 \code
1904 FILE *fp_input;
1905 FILE *fp_output;
1906 struct Option *opt_input;
1907 struct Option *opt_output;
1908
1909 opt_input = G_define_standard_option(G_OPT_F_INPUT);
1910 opt_output = G_define_standard_option(G_OPT_F_OUTPUT);
1911
1912 if (G_parser(argc, argv))
1913 exit(EXIT_FAILURE);
1914
1915 fp_input = G_open_option_file(opt_input);
1916 fp_output = G_open_option_file(opt_output);
1917 ...
1918 G_close_option_file(fp_input);
1919 G_close_option_file(fp_output);
1920 \endcode
1921
1922 \param option pointer to a file option
1923
1924 \return file pointer
1925 */
1927{
1928 int stdinout;
1929 FILE *fp;
1930
1931 stdinout = !option->answer || !*(option->answer) ||
1932 strcmp(option->answer, "-") == 0;
1933
1934 if (option->gisprompt == NULL)
1935 G_fatal_error(_("%s= is not a file option"), option->key);
1936 else if (option->multiple)
1937 G_fatal_error(_("Opening multiple files not supported for %s="),
1938 option->key);
1939 else if (strcmp(option->gisprompt, "old,file,file") == 0) {
1940 if (stdinout)
1941 fp = stdin;
1942 else if ((fp = fopen(option->answer, "r")) == NULL)
1943 G_fatal_error(_("Unable to open %s file <%s>: %s"), option->key,
1944 option->answer, strerror(errno));
1945 }
1946 else if (strcmp(option->gisprompt, "new,file,file") == 0) {
1947 if (stdinout)
1948 fp = stdout;
1949 else if ((fp = fopen(option->answer, "w")) == NULL)
1950 G_fatal_error(_("Unable to create %s file <%s>: %s"), option->key,
1951 option->answer, strerror(errno));
1952 }
1953 else
1954 G_fatal_error(_("%s= is not a file option"), option->key);
1955
1956 return fp;
1957}
1958
1959/*!
1960 \brief Close an input/output file returned by G_open_option_file(). If the
1961 file pointer is stdin, stdout, or stderr, nothing happens.
1962
1963 \param fp file pointer
1964 */
1966{
1967 if (fp != stdin && fp != stdout && fp != stderr)
1968 fclose(fp);
1969}
#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_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
const char * G_etc_dir(void)
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:46
char * G_chop(char *)
Chop leading and trailing white spaces.
Definition strings.c:331
char * G_store(const char *)
Copy string to allocated memory.
Definition strings.c:86
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:394
#define TYPE_STRING
Definition gis.h:190
#define GPATH_MAX
Definition gis.h:198
#define TYPE_INTEGER
Definition gis.h:188
#define NO
Definition gis.h:192
#define TRUE
Definition gis.h:77
#define FALSE
Definition gis.h:81
#define TYPE_DOUBLE
Definition gis.h:189
#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:929
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:884
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:1926
int G__uses_new_gisprompt(void)
Definition parser.c:892
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:868
int G_get_overwrite(void)
Get overwrite value.
Definition parser.c:959
char * G_option_to_separator(const struct Option *option)
Get separator string from the option.
Definition parser.c:1864
char * recreate_command(int original_path)
Creates command to run non-interactive.
Definition parser.c:679
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:1965
char * G_recreate_command(void)
Creates command to run non-interactive.
Definition parser.c:840
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:858
struct state * st
Definition parser.c:102
void G__split_gisprompt(const char *gisprompt, char *age, char *element, char *desc)
Definition parser.c:1779
#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:593
char key
Definition gis.h:594
Structure that stores module info.
Definition gis.h:610
Structure that stores option information.
Definition gis.h:562
const char * key
Definition gis.h:563
const char ** opts
Definition gis.h:568
const char * gisprompt
Definition gis.h:580
int type
Definition gis.h:564
const char * description
Definition gis.h:571
char * answer
Definition gis.h:576
const char * options
Definition gis.h:567
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