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