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