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