GRASS Programmer's Manual  6.4.4(2014)-r
parser.c
Go to the documentation of this file.
1 
78 #include <grass/config.h>
79 
80 #if defined(HAVE_LANGINFO_H)
81 #include <langinfo.h>
82 #endif
83 #if defined(__MINGW32__) && defined(USE_NLS)
84 #include <localcharset.h>
85 #endif
86 
87 #include <stdio.h>
88 #include <stdlib.h>
89 #include <string.h>
90 #include <ctype.h>
91 #include <unistd.h>
92 #include <stdarg.h>
93 #include <sys/types.h>
94 #include <grass/gis.h>
95 #include <grass/glocale.h>
96 #include <grass/spawn.h>
97 
98 
99 #define BAD_SYNTAX 1
100 #define OUT_OF_RANGE 2
101 #define MISSING_VALUE 3
102 #define KEYLENGTH 64
103 
104 static int interactive_ok = 1;
105 static int n_opts = 0;
106 static int n_flags = 0;
107 static int overwrite = 0;
108 static int quiet = 0;
109 
110 static struct Flag first_flag; /* First flag in a linked list */
111 static struct Flag *current_flag; /* Pointer for traversing list */
112 
113 static struct Option first_option;
114 static struct Option *current_option;
115 
116 static struct GModule module_info; /* general information on the corresponding module */
117 
118 static const char *pgm_name = NULL;
119 
120 struct Item
121 {
122  struct Option *option;
123  struct Flag *flag;
124  struct Item *next_item;
125 };
126 
127 static struct Item first_item;
128 static struct Item *current_item;
129 static int n_items = 0;
130 static int show_options(int, const char *);
131 static int show(const char *, int);
132 static int set_flag(int);
133 static int contains(const char *, int);
134 static int is_option(const char *);
135 static int set_option(char *);
136 static int check_opts();
137 static int check_an_opt(const char *, int, const char *, const char *);
138 static int check_int(const char *, const char *);
139 static int check_double(const char *, const char *);
140 static int check_string(const char *, const char *);
141 static int check_required(void);
142 static int split_opts(void);
143 static int check_multiple_opts(void);
144 static int check_overwrite(void);
145 static int interactive(const char *);
146 static int interactive_flag(struct Flag *);
147 static int interactive_option(struct Option *);
148 static int gis_prompt(struct Option *, char *);
149 static int split_gisprompt(const char *, char *, char *, char *);
150 
151 static void G_gui(void);
152 static void G_tcltk(void);
153 static void G_usage_xml(void);
154 static void G_usage_html(void);
155 static void G_script(void);
156 
157 
171 {
172  interactive_ok = 0;
173 
174  return 0;
175 }
176 
177 
191 struct Flag *G_define_flag(void)
192 {
193  struct Flag *flag;
194  struct Item *item;
195 
196  /* Allocate memory if not the first flag */
197 
198  if (n_flags) {
199  flag = (struct Flag *)G_malloc(sizeof(struct Flag));
200  current_flag->next_flag = flag;
201  }
202  else
203  flag = &first_flag;
204 
205  /* Zero structure */
206 
207  G_zero((char *)flag, sizeof(struct Flag));
208 
209  current_flag = flag;
210  n_flags++;
211 
212  if (n_items) {
213  item = (struct Item *)G_malloc(sizeof(struct Item));
214  current_item->next_item = item;
215  }
216  else
217  item = &first_item;
218 
219  G_zero((char *)item, sizeof(struct Item));
220 
221  item->flag = flag;
222  item->option = NULL;
223 
224  current_item = item;
225  n_items++;
226 
227  return (flag);
228 }
229 
230 
247 struct Option *G_define_option(void)
248 {
249  struct Option *opt;
250  struct Item *item;
251 
252  /* Allocate memory if not the first option */
253 
254  if (n_opts) {
255  opt = (struct Option *)G_malloc(sizeof(struct Option));
256  current_option->next_opt = opt;
257  }
258  else
259  opt = &first_option;
260 
261  /* Zero structure */
262  G_zero((char *)opt, sizeof(struct Option));
263 
264  opt->required = NO;
265  opt->multiple = NO;
266  opt->answer = NULL;
267  opt->answers = NULL;
268  opt->def = NULL;
269  opt->checker = NULL;
270  opt->options = NULL;
271  opt->key_desc = NULL;
272  opt->gisprompt = NULL;
273  opt->label = NULL;
274  opt->opts = NULL;
275  opt->description = NULL;
276  opt->descriptions = NULL;
277  opt->guisection = NULL;
278 
279  current_option = opt;
280  n_opts++;
281 
282  if (n_items) {
283  item = (struct Item *)G_malloc(sizeof(struct Item));
284  current_item->next_item = item;
285  }
286  else
287  item = &first_item;
288 
289  G_zero((char *)item, sizeof(struct Item));
290 
291  item->option = opt;
292  item->flag = NULL;
293 
294  current_item = item;
295  n_items++;
296 
297  return (opt);
298 }
299 
300 
327 struct Option *G_define_standard_option(int opt)
328 {
329  struct Option *Opt;
330 
331  Opt = G_define_option();
332 
333  switch (opt) {
334  /* Database options (change to G_OPT_DB_*?) */
335  case G_OPT_WHERE:
336  Opt->key = "where";
337  Opt->type = TYPE_STRING;
338  Opt->key_desc = "sql_query";
339  Opt->required = NO;
340  Opt->label = _("WHERE conditions of SQL statement without 'where' keyword");
341  Opt->description = _("Example: income < 1000 and inhab >= 10000");
342  break;
343  case G_OPT_TABLE:
344  Opt->key = "table";
345  Opt->type = TYPE_STRING;
346  Opt->key_desc = "name";
347  Opt->required = NO;
348  Opt->multiple = NO;
349  Opt->description = _("Table name");
350  Opt->gisprompt = "old_dbtable,dbtable,dbtable";
351  break;
352  case G_OPT_DRIVER:
353  Opt->key = "driver";
354  Opt->type = TYPE_STRING;
355  Opt->key_desc = "name";
356  Opt->required = NO;
357  Opt->multiple = NO;
358  Opt->description = _("Driver name");
359  Opt->gisprompt = "old_dbdriver,dbdriver,dbdriver";
360  break;
361  case G_OPT_DATABASE:
362  Opt->key = "database";
363  Opt->type = TYPE_STRING;
364  Opt->key_desc = "name";
365  Opt->required = NO;
366  Opt->multiple = NO;
367  Opt->description = _("Database name");
368  Opt->gisprompt = "old_dbname,dbname,dbname";
369  break;
370  case G_OPT_COLUMN:
371  Opt->key = "column";
372  Opt->type = TYPE_STRING;
373  Opt->key_desc = "name";
374  Opt->required = NO;
375  Opt->multiple = NO;
376  Opt->description = _("Name of attribute column");
377  Opt->gisprompt = "old_dbcolumn,dbcolumn,dbcolumn";
378  break;
379  case G_OPT_COLUMNS:
380  Opt->key = "columns";
381  Opt->type = TYPE_STRING;
382  Opt->key_desc = "name";
383  Opt->required = NO;
384  Opt->multiple = YES;
385  Opt->description = _("Name of attribute column(s)");
386  Opt->gisprompt = "old_dbcolumn,dbcolumn,dbcolumn";
387  break;
388 
389  /* imagery group */
390  case G_OPT_I_GROUP:
391  Opt->key = "group";
392  Opt->type = TYPE_STRING;
393  Opt->key_desc = "name";
394  Opt->required = YES;
395  Opt->gisprompt = "old,group,group";
396  Opt->description = _("Name of input imagery group");
397  break;
398  case G_OPT_I_SUBGROUP:
399  Opt->key = "subgroup";
400  Opt->type = TYPE_STRING;
401  Opt->key_desc = "name";
402  Opt->required = YES;
403  Opt->gisprompt = "old,subgroup,subgroup";
404  Opt->description = _("Name of input imagery subgroup");
405  break;
406 
407  /* raster maps */
408  case G_OPT_R_INPUT:
409  Opt->key = "input";
410  Opt->type = TYPE_STRING;
411  Opt->key_desc = "name";
412  Opt->required = YES;
413  Opt->gisprompt = "old,cell,raster";
414  Opt->description = _("Name of input raster map");
415  break;
416  case G_OPT_R_INPUTS:
417  Opt->key = "input";
418  Opt->type = TYPE_STRING;
419  Opt->key_desc = "name";
420  Opt->required = YES;
421  Opt->multiple = YES;
422  Opt->gisprompt = "old,cell,raster";
423  Opt->description = _("Name of input raster map(s)");
424  break;
425  case G_OPT_R_OUTPUT:
426  Opt->key = "output";
427  Opt->type = TYPE_STRING;
428  Opt->key_desc = "name";
429  Opt->required = YES;
430  Opt->gisprompt = "new,cell,raster";
431  Opt->description = _("Name for output raster map");
432  break;
433  case G_OPT_R_MAP:
434  Opt->key = "map";
435  Opt->type = TYPE_STRING;
436  Opt->key_desc = "name";
437  Opt->required = YES;
438  Opt->gisprompt = "old,cell,raster";
439  Opt->description = _("Name of input raster map");
440  break;
441  case G_OPT_R_MAPS:
442  Opt->key = "map";
443  Opt->type = TYPE_STRING;
444  Opt->key_desc = "name";
445  Opt->required = YES;
446  Opt->multiple = YES;
447  Opt->gisprompt = "old,cell,raster";
448  Opt->description = _("Name of input raster map(s)");
449  break;
450  case G_OPT_R_BASE:
451  Opt->key = "base";
452  Opt->type = TYPE_STRING;
453  Opt->key_desc = "name";
454  Opt->required = YES;
455  Opt->gisprompt = "old,cell,raster";
456  Opt->description = _("Name of base raster map");
457  break;
458  case G_OPT_R_COVER:
459  Opt->key = "cover";
460  Opt->type = TYPE_STRING;
461  Opt->key_desc = "name";
462  Opt->required = YES;
463  Opt->gisprompt = "old,cell,raster";
464  Opt->description = _("Name of cover raster map");
465  break;
466  case G_OPT_R_ELEV:
467  Opt->key = "elevation";
468  Opt->type = TYPE_STRING;
469  Opt->key_desc = "name";
470  Opt->required = YES;
471  Opt->gisprompt = "old,cell,raster";
472  Opt->description = _("Name of elevation raster map");
473  break;
474  case G_OPT_R_ELEVS:
475  Opt->key = "elevation";
476  Opt->type = TYPE_STRING;
477  Opt->key_desc = "name";
478  Opt->required = YES;
479  Opt->multiple = YES;
480  Opt->gisprompt = "old,cell,raster";
481  Opt->description = _("Name of elevation raster map(s)");
482  break;
483 
484  /*g3d maps */
485  case G_OPT_R3_INPUT:
486  Opt->key = "input";
487  Opt->type = TYPE_STRING;
488  Opt->key_desc = "name";
489  Opt->required = YES;
490  Opt->gisprompt = "old,grid3,3d-raster";
491  Opt->description = _("Name of input raster3d map");
492  break;
493  case G_OPT_R3_INPUTS:
494  Opt->key = "input";
495  Opt->type = TYPE_STRING;
496  Opt->key_desc = "name";
497  Opt->required = YES;
498  Opt->multiple = YES;
499  Opt->gisprompt = "old,grid3,3d-raster";
500  Opt->description = _("Name of input raster3d map(s)");
501  break;
502  case G_OPT_R3_OUTPUT:
503  Opt->key = "output";
504  Opt->type = TYPE_STRING;
505  Opt->key_desc = "name";
506  Opt->required = YES;
507  Opt->gisprompt = "new,grid3,3d-raster";
508  Opt->description = _("Name for output raster3d map");
509  break;
510  case G_OPT_R3_MAP:
511  Opt->key = "map";
512  Opt->type = TYPE_STRING;
513  Opt->key_desc = "name";
514  Opt->required = YES;
515  Opt->gisprompt = "old,grid3,3d-raster";
516  Opt->description = _("Name of input raster3d map");
517  break;
518  case G_OPT_R3_MAPS:
519  Opt->key = "map";
520  Opt->type = TYPE_STRING;
521  Opt->key_desc = "name";
522  Opt->required = YES;
523  Opt->multiple = YES;
524  Opt->gisprompt = "old,grid3,3d-raster";
525  Opt->description = _("Name of input raster3d map(s)");
526  break;
527 
528  /*vector maps */
529  case G_OPT_V_INPUT:
530  Opt->key = "input";
531  Opt->type = TYPE_STRING;
532  Opt->key_desc = "name";
533  Opt->required = YES;
534  Opt->gisprompt = "old,vector,vector";
535  Opt->description = _("Name of input vector map");
536  break;
537  case G_OPT_V_INPUTS:
538  Opt->key = "input";
539  Opt->type = TYPE_STRING;
540  Opt->key_desc = "name";
541  Opt->required = YES;
542  Opt->multiple = YES;
543  Opt->gisprompt = "old,vector,vector";
544  Opt->description = _("Name of input vector map(s)");
545  break;
546  case G_OPT_V_OUTPUT:
547  Opt->key = "output";
548  Opt->type = TYPE_STRING;
549  Opt->key_desc = "name";
550  Opt->required = YES;
551  Opt->gisprompt = "new,vector,vector";
552  Opt->description = _("Name for output vector map");
553  break;
554  case G_OPT_V_MAP:
555  Opt->key = "map";
556  Opt->type = TYPE_STRING;
557  Opt->key_desc = "name";
558  Opt->required = YES;
559  Opt->gisprompt = "old,vector,vector";
560  Opt->description = _("Name of input vector map");
561  break;
562  case G_OPT_V_MAPS:
563  Opt->key = "map";
564  Opt->type = TYPE_STRING;
565  Opt->key_desc = "name";
566  Opt->required = YES;
567  Opt->multiple = YES;
568  Opt->gisprompt = "old,vector,vector";
569  Opt->description = _("Name of input vector map(s)");
570  break;
571  case G_OPT_V_TYPE:
572  Opt->key = "type";
573  Opt->type = TYPE_STRING;
574  Opt->required = NO;
575  Opt->multiple = YES;
576  Opt->answer = "point,line,boundary,centroid,area";
577  Opt->options = "point,line,boundary,centroid,area";
578  Opt->description = _("Feature type");
579  break;
580  case G_OPT_V3_TYPE:
581  Opt->key = "type";
582  Opt->type = TYPE_STRING;
583  Opt->required = NO;
584  Opt->multiple = YES;
585  Opt->answer = "point,line,boundary,centroid,area,face,kernel";
586  Opt->options = "point,line,boundary,centroid,area,face,kernel";
587  Opt->description = _("Feature type");
588  break;
589  case G_OPT_V_FIELD:
590  Opt->key = "layer";
591  Opt->type = TYPE_INTEGER;
592  Opt->required = NO;
593  Opt->answer = "1";
594  Opt->label = _("Layer number");
595  Opt->description =
596  _("A single vector map can be connected to multiple database "
597  "tables. This number determines which table to use.");
598  Opt->gisprompt = "old_layer,layer,layer";
599 
600  break;
601  case G_OPT_V_CAT:
602  Opt->key = "cat";
603  Opt->type = TYPE_INTEGER;
604  Opt->required = NO;
605  Opt->description = _("Category value");
606  break;
607  case G_OPT_V_CATS:
608  Opt->key = "cats";
609  Opt->type = TYPE_STRING;
610  Opt->key_desc = "range";
611  Opt->required = NO;
612  Opt->label = _("Category values");
613  Opt->description = _("Example: 1,3,7-9,13");
614  break;
615  case G_OPT_V_ID:
616  Opt->key = "id";
617  Opt->type = TYPE_INTEGER;
618  Opt->required = NO;
619  Opt->description = _("Feature id");
620  break;
621  case G_OPT_V_IDS:
622  Opt->key = "ids";
623  Opt->type = TYPE_STRING;
624  Opt->key_desc = "range";
625  Opt->required = NO;
626  Opt->label = _("Feature ids");
627  Opt->description = _("Example: 1,3,7-9,13");
628  break;
629 
630  /* files */
631  case G_OPT_F_INPUT:
632  Opt->key = "input";
633  Opt->type = TYPE_STRING;
634  Opt->key_desc = "name";
635  Opt->required = YES;
636  Opt->gisprompt = "old_file,file,input";
637  Opt->description = _("Name of input file");
638  break;
639  case G_OPT_F_OUTPUT:
640  Opt->key = "output";
641  Opt->type = TYPE_STRING;
642  Opt->key_desc = "name";
643  Opt->required = YES;
644  Opt->gisprompt = "new_file,file,output";
645  Opt->description = _("Name for output file");
646  break;
647  case G_OPT_F_SEP:
648  Opt->key = "fs";
649  Opt->type = TYPE_STRING;
650  Opt->key_desc = "character";
651  Opt->required = NO;
652  Opt->answer = "|";
653  Opt->label = _("Field separator");
654  Opt->description = _("Special characters: newline, space, comma, tab");
655  break;
656 
657  /* colors */
658  case G_OPT_C_FG:
659  Opt->key = "color";
660  Opt->type = TYPE_STRING;
661  Opt->key_desc = "name";
662  Opt->required = NO;
663  Opt->answer = DEFAULT_FG_COLOR;
664  Opt->gisprompt = "old_color,color,color";
665  Opt->label = _("Color");
666  Opt->description = _("Either a standard color name or R:G:B triplet");
667  break;
668  case G_OPT_C_BG:
669  Opt->key = "bgcolor";
670  Opt->type = TYPE_STRING;
671  Opt->key_desc = "name";
672  Opt->required = NO;
673  Opt->answer = DEFAULT_BG_COLOR;
674  Opt->gisprompt = "old_color,color,color_none";
675  Opt->label = _("Background color");
676  Opt->description =
677  _("Either a standard GRASS color, R:G:B triplet, or \"none\"");
678  break;
679  }
680 
681  return (Opt);
682 }
683 
684 
691 struct GModule *G_define_module(void)
692 {
693  struct GModule *module;
694 
695  /* Allocate memory */
696 
697  module = &module_info;
698 
699  /* Zero structure */
700 
701  G_zero((char *)module, sizeof(struct GModule));
702 
703  return (module);
704 }
705 
706 /* The main parsing routine */
707 
743 int G_parser(int argc, char **argv)
744 {
745  int need_first_opt;
746  int opt_checked = 0;
747  int error;
748  char *ptr, *tmp_name;
749  int i;
750  struct Option *opt;
751  char force_gui = FALSE;
752 
753  error = 0;
754  need_first_opt = 1;
755  i = strlen(tmp_name = G_store(argv[0]));
756  while (--i >= 0) {
757  if (G_is_dirsep(tmp_name[i])) {
758  tmp_name += i + 1;
759  break;
760  }
761  }
762  G_basename(tmp_name, "exe");
763  pgm_name = tmp_name;
764 
765  /* Stash default answers */
766 
767  opt = &first_option;
768  while (opt != NULL) {
769  /* Parse options */
770  if (opt->options) {
771  int cnt = 0;
772  char **tokens, delm[2];
773 
774  delm[0] = ',';
775  delm[1] = '\0';
776  tokens = G_tokenize(opt->options, delm);
777 
778  i = 0;
779  while (tokens[i]) {
780  cnt++;
781  i++;
782  }
783 
784  opt->opts =
785  (const char **)G_calloc(cnt + 1, sizeof(const char *));
786 
787  i = 0;
788  while (tokens[i]) {
789  opt->opts[i] = G_store(tokens[i]);
790  i++;
791  }
792  G_free_tokens(tokens);
793 
794  if (opt->descriptions) {
795  delm[0] = ';';
796 
797  opt->descs =
798  (const char **)G_calloc(cnt + 1, sizeof(const char *));
799  tokens = G_tokenize(opt->descriptions, delm);
800 
801  i = 0;
802  while (tokens[i]) {
803  int j, found;
804 
805  if (!tokens[i + 1])
806  break;
807 
808  j = 0;
809  found = 0;
810  while (opt->opts[j]) {
811  if (strcmp(opt->opts[j], tokens[i]) == 0) {
812  found = 1;
813  break;
814  }
815  j++;
816  }
817  if (!found) {
818  G_warning(_("BUG in descriptions, option '%s' in <%s> does not exist"),
819  tokens[i], opt->key);
820  }
821  else {
822  opt->descs[j] = G_store(tokens[i + 1]);
823  }
824 
825  i += 2;
826  }
827  G_free_tokens(tokens);
828  }
829  }
830 
831  /* Copy answer */
832  if (opt->multiple && opt->answers && opt->answers[0]) {
833  opt->answer = (char *)G_malloc(strlen(opt->answers[0]) + 1);
834  strcpy(opt->answer, opt->answers[0]);
835  for (i = 1; opt->answers[i]; i++) {
836  opt->answer = (char *)G_realloc(opt->answer,
837  strlen(opt->answer) +
838  strlen(opt->answers[i]) + 2);
839  strcat(opt->answer, ",");
840  strcat(opt->answer, opt->answers[i]);
841  }
842  }
843  opt->def = opt->answer;
844  opt = opt->next_opt;
845  }
846 
847  /* If there are NO arguments, go interactive */
848 
849  if (argc < 2 && interactive_ok && isatty(0)) {
850  if (getenv("GRASS_UI_TERM")) {
851  interactive(argv[0]);
852  opt_checked = 1;
853  /* all options have been already checked interactively */
854  }
855  else {
856  G_gui();
857  return -1;
858  }
859  }
860  else if (argc < 2 && isatty(0)) {
861  G_usage();
862  return -1;
863  }
864  else if (argc >= 2) {
865 
866  /* If first arg is "help" give a usage/syntax message */
867  if (strcmp(argv[1], "help") == 0 ||
868  strcmp(argv[1], "-help") == 0 || strcmp(argv[1], "--help") == 0) {
869  G_usage();
870  exit(EXIT_SUCCESS);
871  }
872 
873  /* If first arg is "--interface-description" then print out
874  * a xml description of the task */
875  if (strcmp(argv[1], "--interface-description") == 0) {
876  G_usage_xml();
877  exit(EXIT_SUCCESS);
878  }
879 
880  /* If first arg is "--html-description" then print out
881  * a html description of the task */
882  if (strcmp(argv[1], "--html-description") == 0) {
883  G_usage_html();
884  exit(EXIT_SUCCESS);
885  }
886 
887  /* If first arg is "--tcltk" then generate
888  * code for tcltkgrass */
889  if (strcmp(argv[1], "--tcltk") == 0) {
890  G_tcltk();
891  exit(EXIT_SUCCESS);
892  }
893 
894  /* If first arg is "--script" then then generate
895  * g.parser boilerplate */
896  if (strcmp(argv[1], "--script") == 0) {
897  G_script();
898  exit(EXIT_SUCCESS);
899  }
900 
901  /* Loop thru all command line arguments */
902 
903  while (--argc) {
904  ptr = *(++argv);
905 
906  if (strcmp(ptr, "help") == 0 ||
907  strcmp(ptr, "-help") == 0 || strcmp(ptr, "--help") == 0) {
908  G_usage();
909  exit(EXIT_SUCCESS);
910  }
911 
912  /* Overwrite option */
913  if (strcmp(ptr, "--o") == 0 || strcmp(ptr, "--overwrite") == 0) {
914  overwrite = 1;
915  }
916 
917  /* Verbose option */
918  else if (strcmp(ptr, "--v") == 0 || strcmp(ptr, "--verbose") == 0) {
919  char buff[32];
920 
921  /* print everything: max verbosity level */
922  module_info.verbose = G_verbose_max();
923  sprintf(buff, "GRASS_VERBOSE=%d", G_verbose_max());
924  putenv(G_store(buff));
925  if (quiet == 1) {
926  G_warning(_("Use either --quiet or --verbose flag, not both. Assuming --verbose."));
927  }
928  quiet = -1;
929  }
930 
931  /* Quiet option */
932  else if (strcmp(ptr, "--q") == 0 || strcmp(ptr, "--quiet") == 0) {
933  char buff[32];
934 
935  /* print nothing, but errors and warnings */
936  module_info.verbose = G_verbose_min();
937  sprintf(buff, "GRASS_VERBOSE=%d", G_verbose_min());
938  putenv(G_store(buff));
939  if (quiet == -1) {
940  G_warning(_("Use either --quiet or --verbose flag, not both. Assuming --quiet."));
941  }
942  quiet = 1; /* for passing to gui init */
943  }
944 
945  /* Force gui to come up */
946  else if (strcmp(ptr, "--ui") == 0) {
947  force_gui = TRUE;
948  }
949 
950  /* If we see a flag */
951  else if (*ptr == '-') {
952  while (*(++ptr))
953  error += set_flag(*ptr);
954 
955  }
956  /* If we see standard option format (option=val) */
957  else if (is_option(ptr)) {
958  error += set_option(ptr);
959  need_first_opt = 0;
960  }
961 
962  /* If we see the first option with no equal sign */
963  else if (need_first_opt && n_opts) {
964  first_option.answer = G_store(ptr);
965  first_option.count++;
966  need_first_opt = 0;
967  }
968 
969  /* If we see the non valid argument (no "=", just argument) */
970  else if (contains(ptr, '=') == 0) {
971  fprintf(stderr, _("Sorry <%s> is not a valid option\n"), ptr);
972  error = 1;
973  }
974 
975  }
976  }
977 
978  /* Split options where multiple answers are OK */
979  split_opts();
980 
981  /* Run the gui if it was specifically requested */
982  if (force_gui) {
983  G_gui();
984  return -1;
985  }
986 
987  /* Check multiple options */
988  error += check_multiple_opts();
989 
990  /* Check answers against options and check subroutines */
991  if (!opt_checked)
992  error += check_opts();
993 
994  /* Make sure all required options are set */
995  error += check_required();
996 
997  if (error) {
998  if (G_verbose() > G_verbose_min())
999  G_usage();
1000  return -1;
1001  }
1002 
1003  if (check_overwrite())
1004  return -1;
1005 
1006  return (0);
1007 }
1008 
1009 
1010 static int uses_new_gisprompt(void)
1011 {
1012  struct Option *opt;
1013  char age[KEYLENGTH];
1014  char element[KEYLENGTH];
1015  char desc[KEYLENGTH];
1016 
1017  /* figure out if any of the options use a "new" gisprompt */
1018  /* This is to see if we should spit out the --o flag */
1019  if (n_opts) {
1020  opt = &first_option;
1021  while (opt != NULL) {
1022  if (opt->gisprompt) {
1023  split_gisprompt(opt->gisprompt, age, element, desc);
1024  if (strcmp(age, "new") == 0)
1025  return 1;
1026  }
1027  opt = opt->next_opt;
1028  }
1029  }
1030 
1031  return 0;
1032 }
1033 
1034 
1057 int G_usage(void)
1058 {
1059  struct Option *opt;
1060  struct Flag *flag;
1061  char item[256];
1062  const char *key_desc;
1063  int maxlen;
1064  int len, n;
1065  int new_prompt = 0;
1066 
1067  new_prompt = uses_new_gisprompt();
1068 
1069  if (!pgm_name) /* v.dave && r.michael */
1070  pgm_name = G_program_name();
1071  if (!pgm_name)
1072  pgm_name = "??";
1073 
1074  if (module_info.label || module_info.description) {
1075  fprintf(stderr, _("\nDescription:\n"));
1076  if (module_info.label)
1077  fprintf(stderr, " %s\n", module_info.label);
1078  if (module_info.description)
1079  fprintf(stderr, " %s\n", module_info.description);
1080  }
1081  if (module_info.keywords) {
1082  fprintf(stderr, _("\nKeywords:\n"));
1083  fprintf(stderr, " %s\n", module_info.keywords);
1084  }
1085 
1086  fprintf(stderr, _("\nUsage:\n "));
1087 
1088  len = show(pgm_name, 1);
1089 
1090  /* Print flags */
1091 
1092  if (n_flags) {
1093  item[0] = ' ';
1094  item[1] = '[';
1095  item[2] = '-';
1096  flag = &first_flag;
1097  for (n = 3; flag != NULL; n++, flag = flag->next_flag)
1098  item[n] = flag->key;
1099  item[n++] = ']';
1100  item[n] = 0;
1101  len = show(item, len);
1102  }
1103 
1104  maxlen = 0;
1105  if (n_opts) {
1106  opt = &first_option;
1107  while (opt != NULL) {
1108  if (opt->key_desc != NULL)
1109  key_desc = opt->key_desc;
1110  else if (opt->type == TYPE_STRING)
1111  key_desc = "string";
1112  else
1113  key_desc = "value";
1114 
1115  n = strlen(opt->key);
1116  if (n > maxlen)
1117  maxlen = n;
1118 
1119  strcpy(item, " ");
1120  if (!opt->required)
1121  strcat(item, "[");
1122  strcat(item, opt->key);
1123  strcat(item, "=");
1124  strcat(item, key_desc);
1125  if (opt->multiple) {
1126  strcat(item, "[,");
1127  strcat(item, key_desc);
1128  strcat(item, ",...]");
1129  }
1130  if (!opt->required)
1131  strcat(item, "]");
1132 
1133  len = show(item, len);
1134 
1135  opt = opt->next_opt;
1136  }
1137  }
1138  if (new_prompt) {
1139  strcpy(item, " [--overwrite]");
1140  len = show(item, len);
1141  }
1142 
1143  strcpy(item, " [--verbose]");
1144  len = show(item, len);
1145 
1146  strcpy(item, " [--quiet]");
1147  len = show(item, len);
1148 
1149 
1150  fprintf(stderr, "\n");
1151 
1152  /* Print help info for flags */
1153 
1154  fprintf(stderr, _("\nFlags:\n"));
1155 
1156  if (n_flags) {
1157  flag = &first_flag;
1158  while (flag != NULL) {
1159  fprintf(stderr, " -%c ", flag->key);
1160 
1161  if (flag->label) {
1162  fprintf(stderr, "%s\n", flag->label);
1163  if (flag->description)
1164  fprintf(stderr, " %s\n", flag->description);
1165 
1166  }
1167  else if (flag->description) {
1168  fprintf(stderr, "%s\n", flag->description);
1169  }
1170 
1171  flag = flag->next_flag;
1172  }
1173  }
1174 
1175  if (new_prompt)
1176  fprintf(stderr, " --o %s\n",
1177  _("Allow output files to overwrite existing files"));
1178 
1179  fprintf(stderr, " --v %s\n", _("Verbose module output"));
1180  fprintf(stderr, " --q %s\n", _("Quiet module output"));
1181 
1182  /* Print help info for options */
1183 
1184  if (n_opts) {
1185  fprintf(stderr, _("\nParameters:\n"));
1186  opt = &first_option;
1187  while (opt != NULL) {
1188  fprintf(stderr, " %*s ", maxlen, opt->key);
1189 
1190  if (opt->label) {
1191  fprintf(stderr, "%s\n", opt->label);
1192  if (opt->description) {
1193  fprintf(stderr, " %*s %s\n",
1194  maxlen, " ", opt->description);
1195  }
1196  }
1197  else if (opt->description) {
1198  fprintf(stderr, "%s\n", opt->description);
1199  }
1200 
1201  if (opt->options)
1202  show_options(maxlen, opt->options);
1203  /*
1204  fprintf (stderr, " %*s options: %s\n", maxlen, " ",
1205  _(opt->options)) ;
1206  */
1207  if (opt->def)
1208  fprintf(stderr, _(" %*s default: %s\n"), maxlen, " ",
1209  opt->def);
1210 
1211  if (opt->descs) {
1212  int i = 0;
1213 
1214  while (opt->opts[i]) {
1215  if (opt->descs[i])
1216  fprintf(stderr, " %*s %s: %s\n",
1217  maxlen, " ", opt->opts[i], opt->descs[i]);
1218 
1219  i++;
1220  }
1221  }
1222 
1223  opt = opt->next_opt;
1224  }
1225  }
1226 
1227  return 0;
1228 }
1229 
1230 
1238 static void print_escaped_for_xml(FILE * fp, const char *str)
1239 {
1240  for (; *str; str++) {
1241  switch (*str) {
1242  case '&':
1243  fputs("&amp;", fp);
1244  break;
1245  case '<':
1246  fputs("&lt;", fp);
1247  break;
1248  case '>':
1249  fputs("&gt;", fp);
1250  break;
1251  default:
1252  fputc(*str, fp);
1253  }
1254  }
1255 }
1256 
1257 
1261 #define do_escape(c,escaped) case c: fputs(escaped,f);break
1262 static void print_escaped_for_html(FILE * f, const char *str)
1263 {
1264  const char *s;
1265 
1266  for (s = str; *s; s++) {
1267  switch (*s) {
1268  do_escape('&', "&amp;");
1269  do_escape('<', "&lt;");
1270  do_escape('>', "&gt;");
1271  do_escape('\n', "<br>");
1272  default:
1273  fputc(*s, f);
1274  }
1275  }
1276 }
1277 
1278 #undef do_escape
1279 
1283 static void G_usage_xml(void)
1284 {
1285  struct Option *opt;
1286  struct Flag *flag;
1287  char *type;
1288  char *s, *top;
1289  int i;
1290  char *encoding;
1291  int new_prompt = 0;
1292 
1293  new_prompt = uses_new_gisprompt();
1294 
1295  /* gettext converts strings to encoding returned by nl_langinfo(CODESET) */
1296 
1297 #if defined(HAVE_LANGINFO_H)
1298  encoding = nl_langinfo(CODESET);
1299  if (!encoding || strlen(encoding) == 0) {
1300  encoding = "UTF-8";
1301  }
1302 #elif defined(__MINGW32__) && defined(USE_NLS)
1303  encoding = locale_charset();
1304  if (!encoding || strlen(encoding) == 0) {
1305  encoding = "UTF-8";
1306  }
1307 #else
1308  encoding = "UTF-8";
1309 #endif
1310 
1311  if (!pgm_name) /* v.dave && r.michael */
1312  pgm_name = G_program_name();
1313  if (!pgm_name)
1314  pgm_name = "??";
1315 
1316  fprintf(stdout, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding);
1317  fprintf(stdout, "<!DOCTYPE task SYSTEM \"grass-interface.dtd\">\n");
1318 
1319  fprintf(stdout, "<task name=\"%s\">\n", pgm_name);
1320 
1321  if (module_info.label) {
1322  fprintf(stdout, "\t<label>\n\t\t");
1323  print_escaped_for_xml(stdout, module_info.label);
1324  fprintf(stdout, "\n\t</label>\n");
1325  }
1326 
1327  if (module_info.description) {
1328  fprintf(stdout, "\t<description>\n\t\t");
1329  print_escaped_for_xml(stdout, module_info.description);
1330  fprintf(stdout, "\n\t</description>\n");
1331  }
1332 
1333  if (module_info.keywords) {
1334  fprintf(stdout, "\t<keywords>\n\t\t");
1335  print_escaped_for_xml(stdout, module_info.keywords);
1336  fprintf(stdout, "\n\t</keywords>\n");
1337  }
1338 
1339  /***** Don't use parameter-groups for now. We'll reimplement this later
1340  ***** when we have a concept of several mutually exclusive option
1341  ***** groups
1342  if (n_opts || n_flags)
1343  fprintf(stdout, "\t<parameter-group>\n");
1344  *****
1345  *****
1346  *****/
1347 
1348  if (n_opts) {
1349  opt = &first_option;
1350  while (opt != NULL) {
1351  /* TODO: make this a enumeration type? */
1352  switch (opt->type) {
1353  case TYPE_INTEGER:
1354  type = "integer";
1355  break;
1356  case TYPE_DOUBLE:
1357  type = "float";
1358  break;
1359  case TYPE_STRING:
1360  type = "string";
1361  break;
1362  default:
1363  type = "string";
1364  break;
1365  }
1366  fprintf(stdout, "\t<parameter "
1367  "name=\"%s\" "
1368  "type=\"%s\" "
1369  "required=\"%s\" "
1370  "multiple=\"%s\">\n",
1371  opt->key,
1372  type,
1373  opt->required == YES ? "yes" : "no",
1374  opt->multiple == YES ? "yes" : "no");
1375 
1376  if (opt->label) {
1377  fprintf(stdout, "\t\t<label>\n\t\t\t");
1378  print_escaped_for_xml(stdout, opt->label);
1379  fprintf(stdout, "\n\t\t</label>\n");
1380  }
1381 
1382  if (opt->description) {
1383  fprintf(stdout, "\t\t<description>\n\t\t\t");
1384  print_escaped_for_xml(stdout, opt->description);
1385  fprintf(stdout, "\n\t\t</description>\n");
1386  }
1387 
1388  if (opt->key_desc) {
1389  fprintf(stdout, "\t\t<keydesc>\n");
1390  top = G_calloc(strlen(opt->key_desc) + 1, 1);
1391  strcpy(top, opt->key_desc);
1392  s = strtok(top, ",");
1393  for (i = 1; s != NULL; i++) {
1394  fprintf(stdout, "\t\t\t<item order=\"%d\">", i);
1395  print_escaped_for_xml(stdout, s);
1396  fprintf(stdout, "</item>\n");
1397  s = strtok(NULL, ",");
1398  }
1399  fprintf(stdout, "\t\t</keydesc>\n");
1400  G_free(top);
1401  }
1402 
1403  if (opt->gisprompt) {
1404  const char *atts[] = { "age", "element", "prompt", NULL };
1405  top = G_calloc(strlen(opt->gisprompt) + 1, 1);
1406  strcpy(top, opt->gisprompt);
1407  s = strtok(top, ",");
1408  fprintf(stdout, "\t\t<gisprompt ");
1409  for (i = 0; s != NULL && atts[i] != NULL; i++) {
1410  fprintf(stdout, "%s=\"%s\" ", atts[i], s);
1411  s = strtok(NULL, ",");
1412  }
1413  fprintf(stdout, "/>\n");
1414  G_free(top);
1415  }
1416 
1417  if (opt->def) {
1418  fprintf(stdout, "\t\t<default>\n\t\t\t");
1419  print_escaped_for_xml(stdout, opt->def);
1420  fprintf(stdout, "\n\t\t</default>\n");
1421  }
1422 
1423  if (opt->options) {
1424  /* TODO:
1425  * add something like
1426  * <range min="xxx" max="xxx"/>
1427  * to <values> */
1428  i = 0;
1429  fprintf(stdout, "\t\t<values>\n");
1430  while (opt->opts[i]) {
1431  fprintf(stdout, "\t\t\t<value>\n");
1432  fprintf(stdout, "\t\t\t\t<name>");
1433  print_escaped_for_xml(stdout, opt->opts[i]);
1434  fprintf(stdout, "</name>\n");
1435  if (opt->descs && opt->opts[i] && opt->descs[i]) {
1436  fprintf(stdout, "\t\t\t\t<description>");
1437  print_escaped_for_xml(stdout, opt->descs[i]);
1438  fprintf(stdout, "</description>\n");
1439  }
1440  fprintf(stdout, "\t\t\t</value>\n");
1441  i++;
1442  }
1443  fprintf(stdout, "\t\t</values>\n");
1444  }
1445  if (opt->guisection) {
1446  fprintf(stdout, "\t\t<guisection>\n\t\t\t");
1447  print_escaped_for_xml(stdout, opt->guisection);
1448  fprintf(stdout, "\n\t\t</guisection>\n");
1449  }
1450  /* TODO:
1451  * - key_desc?
1452  * - there surely are some more. which ones?
1453  */
1454 
1455  opt = opt->next_opt;
1456  fprintf(stdout, "\t</parameter>\n");
1457  }
1458  }
1459 
1460 
1461  if (n_flags) {
1462  flag = &first_flag;
1463  while (flag != NULL) {
1464  fprintf(stdout, "\t<flag name=\"%c\">\n", flag->key);
1465 
1466  if (flag->label) {
1467  fprintf(stdout, "\t\t<label>\n\t\t\t");
1468  print_escaped_for_xml(stdout, flag->label);
1469  fprintf(stdout, "\n\t\t</label>\n");
1470  }
1471 
1472  if (flag->description) {
1473  fprintf(stdout, "\t\t<description>\n\t\t\t");
1474  print_escaped_for_xml(stdout, flag->description);
1475  fprintf(stdout, "\n\t\t</description>\n");
1476  }
1477  if (flag->guisection) {
1478  fprintf(stdout, " \t\t<guisection>\n\t\t\t");
1479  print_escaped_for_xml(stdout, flag->guisection);
1480  fprintf(stdout, "\n\t\t</guisection>\n");
1481  }
1482  flag = flag->next_flag;
1483  fprintf(stdout, "\t</flag>\n");
1484  }
1485  }
1486 
1487  /***** Don't use parameter-groups for now. We'll reimplement this later
1488  ***** when we have a concept of several mutually exclusive option
1489  ***** groups
1490  if (n_opts || n_flags)
1491  fprintf(stdout, "\t</parameter-group>\n");
1492  *****
1493  *****
1494  *****/
1495 
1496  if (new_prompt) {
1497  /* overwrite */
1498  fprintf(stdout, "\t<flag name=\"%s\">\n", "overwrite");
1499  fprintf(stdout, "\t\t<description>\n\t\t\t");
1500  print_escaped_for_xml(stdout,
1501  _("Allow output files to overwrite existing files"));
1502  fprintf(stdout, "\n\t\t</description>\n");
1503  fprintf(stdout, "\t</flag>\n");
1504  }
1505 
1506  /* verbose */
1507  fprintf(stdout, "\t<flag name=\"%s\">\n", "verbose");
1508  fprintf(stdout, "\t\t<description>\n\t\t\t");
1509  print_escaped_for_xml(stdout, _("Verbose module output"));
1510  fprintf(stdout, "\n\t\t</description>\n");
1511  fprintf(stdout, "\t</flag>\n");
1512 
1513  /* quiet */
1514  fprintf(stdout, "\t<flag name=\"%s\">\n", "quiet");
1515  fprintf(stdout, "\t\t<description>\n\t\t\t");
1516  print_escaped_for_xml(stdout, _("Quiet module output"));
1517  fprintf(stdout, "\n\t\t</description>\n");
1518  fprintf(stdout, "\t</flag>\n");
1519 
1520  fprintf(stdout, "</task>\n");
1521 }
1522 
1526 static void G_usage_html(void)
1527 {
1528  struct Option *opt;
1529  struct Flag *flag;
1530  const char *type;
1531  int new_prompt = 0;
1532 
1533  new_prompt = uses_new_gisprompt();
1534 
1535  if (!pgm_name) /* v.dave && r.michael */
1536  pgm_name = G_program_name();
1537  if (!pgm_name)
1538  pgm_name = "??";
1539 
1540  fprintf(stdout,
1541  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
1542  fprintf(stdout, "<html>\n<head>\n");
1543  fprintf(stdout, "<title>GRASS GIS manual: %s</title>\n", pgm_name);
1544  fprintf(stdout,
1545  "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n");
1546  fprintf(stdout,
1547  "<link rel=\"stylesheet\" href=\"grassdocs.css\" type=\"text/css\">\n");
1548  fprintf(stdout, "</head>\n");
1549  fprintf(stdout, "<body bgcolor=\"white\">\n\n");
1550  fprintf(stdout,
1551  "<img src=\"grass_logo.png\" alt=\"GRASS logo\"><hr align=center size=6 noshade>\n\n");
1552  fprintf(stdout, "<h2>%s</h2>\n", _("NAME"));
1553  fprintf(stdout, "<em><b>%s</b></em> ", pgm_name);
1554 
1555  if (module_info.label || module_info.description)
1556  fprintf(stdout, " - ");
1557 
1558  if (module_info.label)
1559  fprintf(stdout, "%s<BR>\n", module_info.label);
1560 
1561  if (module_info.description)
1562  fprintf(stdout, "%s\n", module_info.description);
1563 
1564 
1565  fprintf(stdout, "<h2>%s</h2>\n", _("KEYWORDS"));
1566  if (module_info.keywords) {
1567  fprintf(stdout, "%s", module_info.keywords);
1568  fprintf(stdout, "\n");
1569  }
1570  fprintf(stdout, "<h2>%s</h2>\n", _("SYNOPSIS"));
1571  fprintf(stdout, "<b>%s</b><br>\n", pgm_name);
1572  fprintf(stdout, "<b>%s help</b><br>\n", pgm_name);
1573 
1574  fprintf(stdout, "<b>%s</b>", pgm_name);
1575 
1576 
1577 
1578  /* print short version first */
1579  if (n_flags) {
1580  flag = &first_flag;
1581  fprintf(stdout, " [-<b>");
1582  while (flag != NULL) {
1583  fprintf(stdout, "%c", flag->key);
1584  flag = flag->next_flag;
1585  }
1586  fprintf(stdout, "</b>] ");
1587  }
1588  else
1589  fprintf(stdout, " ");
1590 
1591  if (n_opts) {
1592  opt = &first_option;
1593 
1594  while (opt != NULL) {
1595  if (opt->key_desc != NULL)
1596  type = opt->key_desc;
1597  else
1598  switch (opt->type) {
1599  case TYPE_INTEGER:
1600  type = "integer";
1601  break;
1602  case TYPE_DOUBLE:
1603  type = "float";
1604  break;
1605  case TYPE_STRING:
1606  type = "string";
1607  break;
1608  default:
1609  type = "string";
1610  break;
1611  }
1612  if (!opt->required)
1613  fprintf(stdout, " [");
1614  fprintf(stdout, "<b>%s</b>=<em>%s</em>", opt->key, type);
1615  if (opt->multiple) {
1616  fprintf(stdout, "[,<i>%s</i>,...]", type);
1617  }
1618  if (!opt->required)
1619  fprintf(stdout, "] ");
1620 
1621  opt = opt->next_opt;
1622  fprintf(stdout, " ");
1623  }
1624  }
1625  if (new_prompt)
1626  fprintf(stdout, " [--<b>overwrite</b>] ");
1627 
1628  fprintf(stdout, " [--<b>verbose</b>] ");
1629  fprintf(stdout, " [--<b>quiet</b>] ");
1630 
1631  fprintf(stdout, "\n");
1632 
1633 
1634  /* now long version */
1635  fprintf(stdout, "\n");
1636  if (n_flags || new_prompt) {
1637  flag = &first_flag;
1638  fprintf(stdout, "<h3>%s:</h3>\n", _("Flags"));
1639  fprintf(stdout, "<DL>\n");
1640  while (n_flags && flag != NULL) {
1641  fprintf(stdout, "<DT><b>-%c</b></DT>\n", flag->key);
1642 
1643  if (flag->label) {
1644  fprintf(stdout, "<DD>");
1645  fprintf(stdout, "%s", flag->label);
1646  fprintf(stdout, "</DD>\n");
1647  }
1648 
1649  if (flag->description) {
1650  fprintf(stdout, "<DD>");
1651  fprintf(stdout, "%s", flag->description);
1652  fprintf(stdout, "</DD>\n");
1653  }
1654 
1655  flag = flag->next_flag;
1656  fprintf(stdout, "\n");
1657  }
1658  if (new_prompt) {
1659  fprintf(stdout, "<DT><b>--overwrite</b></DT>\n");
1660  fprintf(stdout, "<DD>%s</DD>\n",
1661  _("Allow output files to overwrite existing files"));
1662  }
1663 
1664  fprintf(stdout, "<DT><b>--verbose</b></DT>\n");
1665  fprintf(stdout, "<DD>%s</DD>\n", _("Verbose module output"));
1666 
1667  fprintf(stdout, "<DT><b>--quiet</b></DT>\n");
1668  fprintf(stdout, "<DD>%s</DD>\n", _("Quiet module output"));
1669 
1670  fprintf(stdout, "</DL>\n");
1671  }
1672 
1673  fprintf(stdout, "\n");
1674  if (n_opts) {
1675  opt = &first_option;
1676  fprintf(stdout, "<h3>%s:</h3>\n", _("Parameters"));
1677  fprintf(stdout, "<DL>\n");
1678 
1679  while (opt != NULL) {
1680  /* TODO: make this a enumeration type? */
1681  if (opt->key_desc != NULL)
1682  type = opt->key_desc;
1683  else
1684  switch (opt->type) {
1685  case TYPE_INTEGER:
1686  type = "integer";
1687  break;
1688  case TYPE_DOUBLE:
1689  type = "float";
1690  break;
1691  case TYPE_STRING:
1692  type = "string";
1693  break;
1694  default:
1695  type = "string";
1696  break;
1697  }
1698  fprintf(stdout, "<DT><b>%s</b>=<em>%s", opt->key, type);
1699  if (opt->multiple) {
1700  fprintf(stdout, "[,<i>%s</i>,...]", type);
1701  }
1702  fprintf(stdout, "</em></DT>\n");
1703 
1704  if (opt->label) {
1705  fprintf(stdout, "<DD>");
1706  fprintf(stdout, "%s", opt->label);
1707  fprintf(stdout, "</DD>\n");
1708  }
1709  if (opt->description) {
1710  fprintf(stdout, "<DD>");
1711  print_escaped_for_html(stdout, opt->description);
1712  fprintf(stdout, "</DD>\n");
1713  }
1714 
1715  if (opt->options) {
1716  fprintf(stdout, "<DD>%s: <em>", _("Options"));
1717  fprintf(stdout, "%s", opt->options);
1718  fprintf(stdout, "</em></DD>\n");
1719  }
1720 
1721  if (opt->def) {
1722  fprintf(stdout, "<DD>%s: <em>", _("Default"));
1723  fprintf(stdout, "%s", opt->def);
1724  fprintf(stdout, "</em></DD>\n");
1725  }
1726 
1727  if (opt->descs) {
1728  int i = 0;
1729 
1730  while (opt->opts[i]) {
1731  if (opt->descs[i])
1732  fprintf(stdout, "<DD><b>%s</b>: %s</DD>\n",
1733  opt->opts[i], opt->descs[i]);
1734  i++;
1735  }
1736  }
1737 
1738  opt = opt->next_opt;
1739  fprintf(stdout, "\n");
1740  }
1741  fprintf(stdout, "</DL>\n");
1742  }
1743 
1744  fprintf(stdout, "</body>\n</html>\n");
1745 }
1746 
1750 static void G_script(void)
1751 {
1752  FILE *fp = stdout;
1753  char *type;
1754 
1755  fprintf(fp, "#!/bin/sh\n\n");
1756  fprintf(fp,
1757  "############################################################################\n");
1758  fprintf(fp, "#\n");
1759  fprintf(fp, "# MODULE: %s_wrapper\n", G_program_name());
1760  fprintf(fp, "# AUTHOR(S): %s\n", G_whoami());
1761  fprintf(fp, "# PURPOSE: \n");
1762  fprintf(fp, "# COPYRIGHT: (C) 2009 GRASS Development Team/%s\n",
1763  G_whoami());
1764  fprintf(fp, "#\n");
1765  fprintf(fp,
1766  "# This program is free software; you can redistribute it and/or modify\n");
1767  fprintf(fp,
1768  "# it under the terms of the GNU General Public License as published by\n");
1769  fprintf(fp,
1770  "# the Free Software Foundation; either version 2 of the License, or\n");
1771  fprintf(fp, "# (at your option) any later version.\n");
1772  fprintf(fp, "#\n");
1773  fprintf(fp,
1774  "# This program is distributed in the hope that it will be useful,\n");
1775  fprintf(fp,
1776  "# but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
1777  fprintf(fp,
1778  "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
1779  fprintf(fp, "# GNU General Public License for more details.\n");
1780  fprintf(fp, "#\n");
1781  fprintf(fp,
1782  "############################################################################\n");
1783 
1784  fprintf(fp, "#%%Module\n");
1785  if (module_info.label)
1786  fprintf(fp, "#%% label: %s\n", module_info.label);
1787  if (module_info.description)
1788  fprintf(fp, "#%% description: %s\n", module_info.description);
1789  if (module_info.keywords)
1790  fprintf(fp, "#%% keywords: %s\n", module_info.keywords);
1791  fprintf(fp, "#%%End\n");
1792 
1793  if (n_flags) {
1794  struct Flag *flag;
1795 
1796  for (flag = &first_flag; flag; flag = flag->next_flag) {
1797  fprintf(fp, "#%%Flag\n");
1798  fprintf(fp, "#%% key: %c\n", flag->key);
1799  if (flag->label)
1800  fprintf(fp, "#%% label: %s\n", flag->label);
1801  if (flag->description)
1802  fprintf(fp, "#%% description: %s\n", flag->description);
1803  if (flag->guisection)
1804  fprintf(fp, "#%% guisection: %s\n", flag->guisection);
1805  fprintf(fp, "#%%End\n");
1806  }
1807  }
1808 
1809  if (n_opts) {
1810  struct Option *opt;
1811 
1812  for (opt = &first_option; opt; opt = opt->next_opt) {
1813  switch (opt->type) {
1814  case TYPE_INTEGER:
1815  type = "integer";
1816  break;
1817  case TYPE_DOUBLE:
1818  type = "double";
1819  break;
1820  case TYPE_STRING:
1821  type = "string";
1822  break;
1823  default:
1824  type = "string";
1825  break;
1826  }
1827 
1828  fprintf(fp, "#%%Option\n");
1829  fprintf(fp, "#%% key: %s\n", opt->key);
1830  fprintf(fp, "#%% type: %s\n", type);
1831  fprintf(fp, "#%% required: %s\n", opt->required ? "yes" : "no");
1832  fprintf(fp, "#%% multiple: %s\n", opt->multiple ? "yes" : "no");
1833  if (opt->options)
1834  fprintf(fp, "#%% options: %s\n", opt->options);
1835  if (opt->key_desc)
1836  fprintf(fp, "#%% key_desc: %s\n", opt->key_desc);
1837  if (opt->label)
1838  fprintf(fp, "#%% label: %s\n", opt->label);
1839  if (opt->description)
1840  fprintf(fp, "#%% description: %s\n", opt->description);
1841  if (opt->descriptions)
1842  fprintf(fp, "#%% descriptions: %s\n", opt->descriptions);
1843  if (opt->answer)
1844  fprintf(fp, "#%% answer: %s\n", opt->answer);
1845  if (opt->gisprompt)
1846  fprintf(fp, "#%% gisprompt: %s\n", opt->gisprompt);
1847  if (opt->guisection)
1848  fprintf(fp, "#%% guisection: %s\n", opt->guisection);
1849  fprintf(fp, "#%%End\n");
1850  }
1851  }
1852 
1853  fprintf(fp,
1854  "\nif [ -z \"$GISBASE\" ] ; then\n"
1855  " echo \"You must be in GRASS GIS to run this program.\" 1>&2\n"
1856  " exit 1\n"
1857  "fi\n"
1858  "\n"
1859  "if [ \"$1\" != \"@ARGS_PARSED@\" ] ; then\n"
1860  " exec g.parser \"$0\" \"$@\"\n"
1861  "fi\n" "\n" "# CODE GOES HERE\n" "\n");
1862 }
1863 
1869 static void generate_tcl(FILE * fp)
1870 {
1871  int new_prompt = uses_new_gisprompt();
1872  const char *type;
1873  int optn;
1874 
1875  fprintf(fp, "begin_dialog {%s} {\n", pgm_name);
1876  fprintf(fp, " label {%s}\n", module_info.label ? module_info.label : "");
1877  fprintf(fp, " desc {%s}\n",
1878  module_info.description ? module_info.description : "");
1879  fprintf(fp, " key {%s}\n",
1880  module_info.keywords ? module_info.keywords : "");
1881  fprintf(fp, "}\n");
1882 
1883  optn = 1;
1884 
1885  if (n_flags) {
1886  struct Flag *flag;
1887 
1888  for (flag = &first_flag; flag; flag = flag->next_flag, optn++) {
1889  fprintf(fp, "add_flag %d {\n", optn);
1890  fprintf(fp, " name {%c}\n", flag->key);
1891  fprintf(fp, " desc {%s}\n", flag->description);
1892  fprintf(fp, " answer %d\n", flag->answer);
1893  /* It should be up to the gui as to what
1894  to do with the label and description */
1895  fprintf(fp, " label {%s}\n", flag->label ? flag->label : "");
1896  fprintf(fp, " guisection {%s}\n",
1897  flag->guisection ? flag->guisection : "");
1898  fprintf(fp, "}\n");
1899  }
1900  }
1901 
1902  if (n_opts) {
1903  struct Option *opt;
1904 
1905  for (opt = &first_option; opt; opt = opt->next_opt, optn++) {
1906  if (opt->key_desc != NULL)
1907  type = opt->key_desc;
1908  else
1909  switch (opt->type) {
1910  case TYPE_INTEGER:
1911  type = "integer";
1912  break;
1913  case TYPE_DOUBLE:
1914  type = "float";
1915  break;
1916  case TYPE_STRING:
1917  type = "string";
1918  break;
1919  default:
1920  type = "string";
1921  break;
1922  }
1923 
1924  fprintf(fp, "add_option %d {\n", optn);
1925  fprintf(fp, " name {%s}\n", opt->key);
1926  fprintf(fp, " type {%s}\n", type);
1927  fprintf(fp, " multi %d\n", opt->multiple);
1928  fprintf(fp, " desc {%s}\n", opt->description);
1929  fprintf(fp, " required %d\n", opt->required);
1930  fprintf(fp, " options {%s}\n", opt->options ? opt->options : "");
1931  fprintf(fp, " descs {%s}\n",
1932  opt->descriptions ? opt->descriptions : "");
1933  fprintf(fp, " answer {%s}\n", opt->answer ? opt->answer : "");
1934  fprintf(fp, " prompt {%s}\n",
1935  opt->gisprompt ? opt->gisprompt : "");
1936  /* It should be up to the gui as to what
1937  to do with the label and description */
1938  fprintf(fp, " label {%s}\n", opt->label ? opt->label : "");
1939  fprintf(fp, " guisection {%s}\n",
1940  opt->guisection ? opt->guisection : "");
1941  fprintf(fp, "}\n");
1942  }
1943  }
1944 
1945  if (new_prompt) {
1946  fprintf(fp, "add_xflag %d {\n", optn);
1947  fprintf(fp, " name {overwrite}\n");
1948  fprintf(fp, " desc {%s}\n",
1949  _("Allow output files to overwrite existing files"));
1950  fprintf(fp, " answer %d\n", overwrite);
1951  fprintf(fp, " label {%s}\n", _("Allow overwrite"));
1952  fprintf(fp, " guisection {}\n");
1953  fprintf(fp, "}\n");
1954  optn++;
1955  }
1956 
1957  fprintf(fp, "add_xflag %d {\n", optn);
1958  fprintf(fp, " name {quiet}\n");
1959  fprintf(fp, " desc {%s}\n", _("Run with minimal output messages"));
1960  fprintf(fp, " answer %d\n", quiet);
1961  fprintf(fp, " label {%s}\n", _("Run quietly"));
1962  fprintf(fp, " guisection {}\n");
1963  fprintf(fp, "}\n");
1964  optn++;
1965 
1966  fprintf(fp, "end_dialog %d\n", optn - 1);
1967 }
1968 
1972 static void G_gui_tcltk(void)
1973 {
1974  FILE *fp;
1975 
1976  if (!pgm_name)
1977  pgm_name = G_program_name();
1978  if (!pgm_name)
1979  pgm_name = "??";
1980 
1981 #ifdef __MINGW32__
1982  if (getenv("GRASS_DEBUG_GUI"))
1983  fp = popen("tee gui_dump.tcl | \"%GRASS_WISH%\"", "w");
1984  else
1985  fp = popen("\"%GRASS_WISH%\"", "w");
1986 #else
1987  if (getenv("GRASS_DEBUG_GUI"))
1988  fp = popen("tee gui_dump.tcl | \"$GRASS_WISH\"", "w");
1989  else
1990  fp = popen("\"$GRASS_WISH\"", "w");
1991 #endif
1992 
1993  if (!fp)
1994  G_fatal_error(_("Unable to spawn the 'wish' program"));
1995 
1996  fprintf(fp, "source $env(GISBASE)/etc/gui.tcl\n");
1997 
1998  generate_tcl(fp);
1999 
2000  pclose(fp);
2001 }
2002 
2006 static void G_gui_wx(void)
2007 {
2008  char script[GPATH_MAX];
2009 
2010  if (!pgm_name)
2011  pgm_name = G_program_name();
2012  if (!pgm_name)
2013  G_fatal_error(_("Unable to determine program name"));
2014 
2015  sprintf(script, "%s/etc/wxpython/gui_core/forms.py",
2016  getenv("GISBASE"));
2017  G_spawn(getenv("GRASS_PYTHON"), getenv("GRASS_PYTHON"), script, G_recreate_command(), NULL);
2018 }
2019 
2027 static void G_gui(void)
2028 {
2029  /* read environment variables first then internal GRASS variable */
2030  char *gui = getenv("GRASS_GUI");
2031 
2032  if (!gui) {
2033  gui = G_getenv("GRASS_GUI");
2034  }
2035 
2036  if (gui && (strcmp(gui, "tcltk") == 0 || strcmp(gui, "oldtcltk") == 0))
2037  G_gui_tcltk();
2038  else
2039  G_gui_wx();
2040 
2041  return;
2042 }
2043 
2047 static void G_tcltk(void)
2048 {
2049  if (!pgm_name)
2050  pgm_name = G_program_name();
2051  if (!pgm_name)
2052  pgm_name = "??";
2053 
2054  generate_tcl(stdout);
2055 }
2056 
2057 /**************************************************************************
2058  *
2059  * The remaining routines are all local (static) routines used to support
2060  * the parsing process.
2061  *
2062  **************************************************************************/
2063 
2064 static int show_options(int maxlen, const char *str)
2065 {
2066  char *buff = G_store(str);
2067  char *p1, *p2;
2068  int totlen, len;
2069 
2070  fprintf(stderr, _(" %*s options: "), maxlen, " ");
2071  totlen = maxlen + 13;
2072  p1 = buff;
2073  while ((p2 = G_index(p1, ','))) {
2074  *p2 = '\0';
2075  len = strlen(p1) + 1;
2076  if ((len + totlen) > 76) {
2077  totlen = maxlen + 13;
2078  fprintf(stderr, "\n %*s", maxlen + 13, " ");
2079  }
2080  fprintf(stderr, "%s,", p1);
2081  totlen += len;
2082  p1 = p2 + 1;
2083  }
2084  len = strlen(p1);
2085  if ((len + totlen) > 76)
2086  fprintf(stderr, "\n %*s", maxlen + 13, " ");
2087  fprintf(stderr, "%s\n", p1);
2088 
2089  G_free(buff);
2090 
2091  return 0;
2092 }
2093 
2094 static int show(const char *item, int len)
2095 {
2096  int n;
2097 
2098  n = strlen(item) + (len > 0);
2099  if (n + len > 76) {
2100  if (len)
2101  fprintf(stderr, "\n ");
2102  len = 0;
2103  }
2104  fprintf(stderr, "%s", item);
2105  return n + len;
2106 }
2107 
2108 static int set_flag(int f)
2109 {
2110  struct Flag *flag;
2111 
2112  /* Flag is not valid if there are no flags to set */
2113 
2114  if (!n_flags) {
2115  fprintf(stderr, _("Sorry, <%c> is not a valid flag\n"), f);
2116  return (1);
2117  }
2118 
2119  /* Find flag with corrrect keyword */
2120 
2121  flag = &first_flag;
2122  while (flag != NULL) {
2123  if (flag->key == f) {
2124  flag->answer = 1;
2125  return (0);
2126  }
2127  flag = flag->next_flag;
2128  }
2129 
2130  fprintf(stderr, _("Sorry, <%c> is not a valid flag\n"), f);
2131  return (1);
2132 }
2133 
2134 /* contents() is used to find things strings with characters like commas and
2135  * dashes.
2136  */
2137 static int contains(const char *s, int c)
2138 {
2139  while (*s) {
2140  if (*s == c)
2141  return (1);
2142  s++;
2143  }
2144  return (0);
2145 }
2146 
2147 static int is_option(const char *string)
2148 {
2149  const char *p = strchr(string, '=');
2150 
2151  if (!p)
2152  return 0;
2153  if (p == string)
2154  return 0;
2155  p--;
2156  if (!strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", *p))
2157  return 0;
2158 
2159  return 1;
2160 }
2161 
2162 static int set_option(char *string)
2163 {
2164  struct Option *at_opt = NULL;
2165  struct Option *opt = NULL;
2166  int got_one;
2167  size_t key_len;
2168  char the_key[KEYLENGTH];
2169  char *ptr;
2170 
2171  for (ptr = the_key; *string != '='; ptr++, string++)
2172  *ptr = *string;
2173  *ptr = '\0';
2174  string++;
2175 
2176  /* Find option with best keyword match */
2177  got_one = 0;
2178  key_len = strlen(the_key);
2179  for (at_opt = &first_option; at_opt != NULL; at_opt = at_opt->next_opt) {
2180  if (at_opt->key == NULL || strncmp(the_key, at_opt->key, key_len))
2181  continue;
2182 
2183  got_one++;
2184  opt = at_opt;
2185 
2186  /* changed 1/15/91 -dpg old code is in parser.old */
2187  /* overide ambiguous check, if we get an exact match */
2188  if (strlen(at_opt->key) == key_len) {
2189  opt = at_opt;
2190  got_one = 1;
2191  break;
2192  }
2193  }
2194 
2195  if (got_one > 1) {
2196  fprintf(stderr, _("Sorry, <%s=> is ambiguous\n"), the_key);
2197  return (1);
2198  }
2199 
2200  /* If there is no match, complain */
2201  if (got_one == 0) {
2202  fprintf(stderr, _("Sorry, <%s> is not a valid parameter\n"), the_key);
2203  return (1);
2204  }
2205 
2206  /* Allocate memory where answer is stored */
2207  if (opt->count++) {
2208  if (!opt->multiple) {
2209  fprintf(stderr, _("Option <%s> does not accept multiple answers\n"), the_key);
2210  return (1);
2211  }
2212  opt->answer = (char *)G_realloc(opt->answer,
2213  strlen(opt->answer) + strlen(string) +
2214  2);
2215  strcat(opt->answer, ",");
2216  strcat(opt->answer, string);
2217  }
2218  else
2219  opt->answer = G_store(string);
2220  return (0);
2221 }
2222 
2223 static int check_opts(void)
2224 {
2225  struct Option *opt;
2226  int error;
2227  int ans;
2228 
2229  error = 0;
2230 
2231  if (!n_opts)
2232  return (0);
2233 
2234  opt = &first_option;
2235  while (opt != NULL) {
2236  /* Check answer against options if any */
2237 
2238  if (opt->options && opt->answer) {
2239  if (opt->multiple == 0)
2240  error += check_an_opt(opt->key, opt->type,
2241  opt->options, opt->answer);
2242  else {
2243  for (ans = 0; opt->answers[ans] != '\0'; ans++)
2244  error += check_an_opt(opt->key, opt->type,
2245  opt->options, opt->answers[ans]);
2246  }
2247  }
2248 
2249  /* Check answer against user's check subroutine if any */
2250 
2251  if (opt->checker)
2252  error += opt->checker(opt->answer);
2253 
2254  opt = opt->next_opt;
2255  }
2256  return (error);
2257 }
2258 
2259 static int check_an_opt(const char *key, int type, const char *options,
2260  const char *answer)
2261 {
2262  int error;
2263 
2264  error = 0;
2265 
2266  switch (type) {
2267  case TYPE_INTEGER:
2268  error = check_int(answer, options);
2269  break;
2270  case TYPE_DOUBLE:
2271  error = check_double(answer, options);
2272  break;
2273  case TYPE_STRING:
2274  error = check_string(answer, options);
2275  break;
2276  /*
2277  case TYPE_COORDINATE:
2278  error = check_coor(answer,options) ;
2279  break ;
2280  */
2281  }
2282  switch (error) {
2283  case 0:
2284  break;
2285  case BAD_SYNTAX:
2286  fprintf(stderr,
2287  _("\nERROR: illegal range syntax for parameter <%s>\n"), key);
2288  fprintf(stderr, _(" Presented as: %s\n"), options);
2289  break;
2290  case OUT_OF_RANGE:
2291  fprintf(stderr,
2292  _("\nERROR: value <%s> out of range for parameter <%s>\n"),
2293  answer, key);
2294  fprintf(stderr, _(" Legal range: %s\n"), options);
2295  break;
2296  case MISSING_VALUE:
2297  fprintf(stderr, _("\nERROR: Missing value for parameter <%s>\n"),
2298  key);
2299  }
2300  return (error);
2301 }
2302 
2303 static int check_int(const char *ans, const char *opts)
2304 {
2305  int d, lo, hi;
2306 
2307  if (1 != sscanf(ans, "%d", &d))
2308  return (MISSING_VALUE);
2309 
2310  if (contains(opts, '-')) {
2311  if (2 != sscanf(opts, "%d-%d", &lo, &hi))
2312  return (BAD_SYNTAX);
2313  if (d < lo || d > hi)
2314  return (OUT_OF_RANGE);
2315  else
2316  return (0);
2317  }
2318  else if (contains(opts, ',')) {
2319  for (;;) {
2320  if (1 != sscanf(opts, "%d", &lo))
2321  return (BAD_SYNTAX);
2322  if (d == lo)
2323  return (0);
2324  while (*opts != '\0' && *opts != ',')
2325  opts++;
2326  if (*opts == '\0')
2327  return (OUT_OF_RANGE);
2328  if (*(++opts) == '\0')
2329  return (OUT_OF_RANGE);
2330  }
2331  }
2332  else {
2333  if (1 != sscanf(opts, "%d", &lo))
2334  return (BAD_SYNTAX);
2335  if (d == lo)
2336  return (0);
2337  return (OUT_OF_RANGE);
2338  }
2339 }
2340 
2341 /*
2342  static int
2343  check_coor(ans, opts)
2344  char *ans ;
2345  char *opts ;
2346  {
2347  double xd, xlo, xhi;
2348  double yd, ylo, yhi;
2349 
2350  if (1 != sscanf(ans,"%lf,%lf", &xd, &yd))
2351  return(MISSING_VALUE) ;
2352 
2353  if (contains(opts, '-'))
2354  {
2355  if (2 != sscanf(opts,"%lf-%lf,%lf-%lf",&xlo, &xhi, &ylo, &yhi))
2356  return(BAD_SYNTAX) ;
2357  if (xd < xlo || xd > xhi)
2358  return(OUT_OF_RANGE) ;
2359  if (yd < ylo || yd > yhi)
2360  return(OUT_OF_RANGE) ;
2361  return(0) ;
2362  }
2363  return(BAD_SYNTAX) ;
2364  }
2365  */
2366 
2367 static int check_double(const char *ans, const char *opts)
2368 {
2369  double d, lo, hi;
2370 
2371  if (1 != sscanf(ans, "%lf", &d))
2372  return (MISSING_VALUE);
2373 
2374  if (contains(opts, '-')) {
2375  if (2 != sscanf(opts, "%lf-%lf", &lo, &hi))
2376  return (BAD_SYNTAX);
2377  if (d < lo || d > hi)
2378  return (OUT_OF_RANGE);
2379  else
2380  return (0);
2381  }
2382  else if (contains(opts, ',')) {
2383  for (;;) {
2384  if (1 != sscanf(opts, "%lf", &lo))
2385  return (BAD_SYNTAX);
2386  if (d == lo)
2387  return (0);
2388  while (*opts != '\0' && *opts != ',')
2389  opts++;
2390  if (*opts == '\0')
2391  return (OUT_OF_RANGE);
2392  if (*(++opts) == '\0')
2393  return (OUT_OF_RANGE);
2394  }
2395  }
2396  else {
2397  if (1 != sscanf(opts, "%lf", &lo))
2398  return (BAD_SYNTAX);
2399  if (d == lo)
2400  return (0);
2401  return (OUT_OF_RANGE);
2402  }
2403 }
2404 
2405 static int check_string(const char *ans, const char *opts)
2406 {
2407  if (*opts == '\0')
2408  return (0);
2409 
2410  if (contains(opts, ',')) {
2411  for (;;) {
2412  if ((!strncmp(ans, opts, strlen(ans)))
2413  && (*(opts + strlen(ans)) == ','
2414  || *(opts + strlen(ans)) == '\0'))
2415  return (0);
2416  while (*opts != '\0' && *opts != ',')
2417  opts++;
2418  if (*opts == '\0')
2419  return (OUT_OF_RANGE);
2420  if (*(++opts) == '\0')
2421  return (OUT_OF_RANGE);
2422  }
2423  }
2424  else {
2425  if (!strcmp(ans, opts))
2426  return (0);
2427  return (OUT_OF_RANGE);
2428  }
2429 }
2430 
2431 static int check_required(void)
2432 {
2433  struct Option *opt;
2434  int err;
2435 
2436  err = 0;
2437 
2438  if (!n_opts)
2439  return (0);
2440 
2441  opt = &first_option;
2442  while (opt != NULL) {
2443  if (opt->required && opt->answer == NULL) {
2444  fprintf(stderr,
2445  _("ERROR: Required parameter <%s> not set:\n\t(%s)\n"),
2446  opt->key, (opt->label ? opt->label : opt->description) );
2447  err++;
2448  }
2449  opt = opt->next_opt;
2450  }
2451 
2452  return (err);
2453 }
2454 
2455 static int split_opts(void)
2456 {
2457  struct Option *opt;
2458  char *ptr1;
2459  char *ptr2;
2460  int allocated;
2461  int ans_num;
2462  int len;
2463 
2464 
2465  if (!n_opts)
2466  return 0;
2467 
2468  opt = &first_option;
2469  while (opt != NULL) {
2470  if ( /*opt->multiple && */ (opt->answer != NULL)) {
2471  /* Allocate some memory to store array of pointers */
2472  allocated = 10;
2473  opt->answers = (char **)G_malloc(allocated * sizeof(char *));
2474 
2475  ans_num = 0;
2476  ptr1 = opt->answer;
2477  opt->answers[ans_num] = NULL;
2478 
2479  for (;;) {
2480  for (len = 0, ptr2 = ptr1; *ptr2 != '\0' && *ptr2 != ',';
2481  ptr2++, len++) ;
2482 
2483  if (len > 0) { /* skip ,, */
2484  opt->answers[ans_num] = (char *)G_malloc(len + 1);
2485  G_copy(opt->answers[ans_num], ptr1, len);
2486  opt->answers[ans_num][len] = 0;
2487 
2488  ans_num++;
2489 
2490  if (ans_num >= allocated) {
2491  allocated += 10;
2492  opt->answers =
2493  (char **)G_realloc((char *)opt->answers,
2494  allocated * sizeof(char *));
2495  }
2496 
2497  opt->answers[ans_num] = NULL;
2498  }
2499 
2500  if (*ptr2 == '\0')
2501  break;
2502 
2503  ptr1 = ptr2 + 1;
2504 
2505  if (*ptr1 == '\0')
2506  break;
2507  }
2508  }
2509  opt = opt->next_opt;
2510  }
2511 
2512  return 0;
2513 }
2514 
2515 static int check_multiple_opts(void)
2516 {
2517  struct Option *opt;
2518  const char *ptr;
2519  int n_commas;
2520  int n;
2521  int error;
2522 
2523  if (!n_opts)
2524  return (0);
2525 
2526  error = 0;
2527  opt = &first_option;
2528  while (opt != NULL) {
2529  if ((opt->answer != NULL) && (opt->key_desc != NULL)) {
2530  /* count commas */
2531  n_commas = 1;
2532  for (ptr = opt->key_desc; *ptr != '\0'; ptr++)
2533  if (*ptr == ',')
2534  n_commas++;
2535  /* count items */
2536  for (n = 0; opt->answers[n] != '\0'; n++) ;
2537  /* if not correct multiple of items */
2538  if (n % n_commas) {
2539  fprintf(stderr,
2540  _("\nERROR: option <%s> must be provided in multiples of %d\n"),
2541  opt->key, n_commas);
2542  fprintf(stderr, _(" You provided %d items:\n"), n);
2543  fprintf(stderr, " %s\n", opt->answer);
2544  error++;
2545  }
2546  }
2547  opt = opt->next_opt;
2548  }
2549  return (error);
2550 }
2551 
2552 /* Check for all 'new' if element already exists */
2553 static int check_overwrite(void)
2554 {
2555  struct Option *opt;
2556  char age[KEYLENGTH];
2557  char element[KEYLENGTH];
2558  char desc[KEYLENGTH];
2559  int error = 0;
2560  char *overstr;
2561  int over;
2562 
2563  if (!n_opts)
2564  return (0);
2565 
2566  over = 0;
2567  /* Check the GRASS OVERWRITE variable */
2568  if ((overstr = G__getenv("OVERWRITE"))) {
2569  over = atoi(overstr);
2570  }
2571 
2572  /* Check the GRASS_OVERWRITE environment variable */
2573  if ((overstr = getenv("GRASS_OVERWRITE"))) {
2574  if (atoi(overstr))
2575  over = 1;
2576  }
2577 
2578  if (overwrite || over) {
2579  module_info.overwrite = 1;
2580  /* Set the environment so that programs run in a script also obey --o */
2581  putenv("GRASS_OVERWRITE=1");
2582  /* No need to check options for existing files if overwrite is true */
2583  return error;
2584  }
2585 
2586  opt = &first_option;
2587  while (opt != NULL) {
2588  if ((opt->answer != NULL) && (opt->gisprompt != NULL)) {
2589  split_gisprompt(opt->gisprompt, age, element, desc);
2590 
2591  if (strcmp(age, "new") == 0) {
2592  int i;
2593  for (i = 0; opt->answers[i]; i++) {
2594  if (G_find_file(element, opt->answers[i], G_mapset())) { /* found */
2595  if (!overwrite && !over) {
2596  if (G_info_format() != G_INFO_FORMAT_GUI) {
2597  fprintf(stderr,
2598  _("ERROR: option <%s>: <%s> exists.\n"),
2599  opt->key, opt->answers[i]);
2600  }
2601  else {
2602  fprintf(stderr,
2603  "GRASS_INFO_ERROR(%d,1): option <%s>: <%s> exists.\n",
2604  getpid(), opt->key, opt->answers[i]);
2605  fprintf(stderr, "GRASS_INFO_END(%d,1)\n",
2606  getpid());
2607  }
2608 
2609  error = 1;
2610  }
2611  }
2612  }
2613  }
2614  }
2615  opt = opt->next_opt;
2616  }
2617 
2618  return (error);
2619 }
2620 
2621 static int interactive(const char *command)
2622 {
2623  struct Item *item;
2624 
2625  /* Query for flags */
2626 
2627  if (!n_items) {
2628  fprintf(stderr, "PROGRAMMER ERROR: no flags or options\n");
2629  exit(EXIT_FAILURE);
2630  }
2631 
2632  for (item = &first_item;;) {
2633  if (item->flag)
2634  interactive_flag(item->flag);
2635  else if (item->option)
2636  interactive_option(item->option);
2637  else
2638  break;
2639 
2640  item = item->next_item;
2641 
2642  if (item == NULL)
2643  break;
2644  }
2645 
2646  return 0;
2647 }
2648 
2649 static int interactive_flag(struct Flag *flag)
2650 {
2651  char buff[1024];
2652 
2653  fprintf(stderr, _("\nFLAG: Set the following flag?\n"));
2654  sprintf(buff, " %s?", flag->description);
2655  flag->answer = G_yes(buff, 0);
2656 
2657  return 0;
2658 }
2659 
2660 static int interactive_option(struct Option *opt)
2661 {
2662  char buff[1024], *bptr;
2663  char buff2[1024];
2664  int set_one;
2665  int no_prompt;
2666 
2667  fprintf(stderr, _("\nOPTION: %s\n"), opt->description);
2668  fprintf(stderr, _(" key: %s\n"), opt->key);
2669  if (opt->key_desc)
2670  fprintf(stderr, _(" format: %s\n"), opt->key_desc);
2671  if (opt->def)
2672  fprintf(stderr, _(" default: %s\n"), opt->def);
2673  fprintf(stderr, _("required: %s\n"), opt->required ? "YES" : "NO");
2674  if (opt->multiple)
2675  fprintf(stderr, _("multiple: %s\n"), opt->multiple ? "YES" : "NO");
2676  if (opt->options)
2677  fprintf(stderr, _(" options: %s\n"), opt->options);
2678  /*
2679  show_options(0, opt->options) ;
2680  */
2681 
2682  set_one = 0;
2683  for (;;) {
2684  *buff = '\0';
2685  if (opt->gisprompt)
2686  no_prompt = gis_prompt(opt, buff);
2687  else
2688  no_prompt = -1;
2689  if (no_prompt) {
2690  fprintf(stderr, _("enter option > "));
2691  if (fgets(buff, 1024, stdin) == 0)
2692  exit(EXIT_SUCCESS);;
2693  bptr = buff; /* strip newline */
2694  while (*bptr) {
2695  if (*bptr == '\n')
2696  *bptr = '\0';
2697  bptr++;
2698  }
2699 
2700  }
2701 
2702  if (strlen(buff) != 0) {
2703  if (opt->options)
2704  /* then check option */
2705  {
2706  if (check_an_opt(opt->key, opt->type, opt->options, buff)) {
2707  if (G_yes(_(" Try again? "), 1))
2708  continue;
2709  else
2710  exit(EXIT_FAILURE);
2711  }
2712  }
2713  if (opt->checker)
2714  if (opt->checker(buff)) {
2715  fprintf(stderr, _("Sorry, %s is not accepted.\n"), buff);
2716  *buff = '\0';
2717  if (G_yes(_(" Try again? "), 1))
2718  continue;
2719  else
2720  exit(EXIT_FAILURE);
2721  }
2722 
2723  sprintf(buff2, "%s=%s", opt->key, buff);
2724  if (!opt->gisprompt) {
2725  fprintf(stderr, _("\nYou have chosen:\n %s\n"), buff2);
2726  if (G_yes(_("Is this correct? "), 1)) {
2727  set_option(buff2);
2728  set_one++;
2729  }
2730  }
2731  else {
2732  set_option(buff2);
2733  set_one++;
2734  }
2735  } /* if strlen(buf ) !=0 */
2736 
2737  if ((strlen(buff) == 0) && opt->required && (set_one == 0))
2738  exit(EXIT_FAILURE);
2739  if ((strlen(buff) == 0) && (set_one > 0) && opt->multiple)
2740  break;
2741  if ((strlen(buff) == 0) && !opt->required)
2742  break;
2743  if ((set_one == 1) && !opt->multiple)
2744  break;
2745  }
2746  return (0);
2747 }
2748 
2749 static int split_gisprompt(const char *gisprompt, char *age, char *element,
2750  char *desc)
2751 {
2752  const char *ptr1;
2753  char *ptr2;
2754 
2755  for (ptr1 = gisprompt, ptr2 = age; *ptr1 != '\0'; ptr1++, ptr2++) {
2756  if (*ptr1 == ',')
2757  break;
2758  *ptr2 = *ptr1;
2759  }
2760  *ptr2 = '\0';
2761 
2762  for (ptr1++, ptr2 = element; *ptr1 != '\0'; ptr1++, ptr2++) {
2763  if (*ptr1 == ',')
2764  break;
2765  *ptr2 = *ptr1;
2766  }
2767  *ptr2 = '\0';
2768 
2769  for (ptr1++, ptr2 = desc; *ptr1 != '\0'; ptr1++, ptr2++) {
2770  if (*ptr1 == ',')
2771  break;
2772  *ptr2 = *ptr1;
2773  }
2774  *ptr2 = '\0';
2775 
2776  return 0;
2777 }
2778 
2779 static int gis_prompt(struct Option *opt, char *buff)
2780 {
2781  char age[KEYLENGTH];
2782  char element[KEYLENGTH];
2783  char desc[KEYLENGTH];
2784  char *ptr1;
2785 
2786  split_gisprompt(opt->gisprompt, age, element, desc);
2787 
2788  /*********ptr1 points to current mapset description***********/
2789 
2790  if (opt->answer)
2791  G_set_ask_return_msg(_("to accept the default"));
2792  if (!strcmp("old", age)) {
2793  ptr1 = G_ask_old("", buff, element, desc);
2794  if (ptr1) {
2795  strcpy(buff, G_fully_qualified_name(buff, ptr1));
2796  }
2797  }
2798  else if (!strcmp("new", age))
2799  ptr1 = G_ask_new("", buff, element, desc);
2800  else if (!strcmp("mapset", age))
2801  ptr1 = G_ask_in_mapset("", buff, element, desc);
2802  else if (!strcmp("any", age))
2803  ptr1 = G_ask_any("", buff, element, desc, 1);
2804  else if (!strcmp("old_file", age)) /* file must exist */
2805  ptr1 = G_ask_old_file("", buff, element, desc);
2806  else if (!strcmp("new_file", age)) /* file shouldn't exist unless overwrite is enabled */
2807  ptr1 = G_ask_new_file("", buff, element, desc);
2808  else {
2809  return -1;
2810  }
2811 
2812  if (ptr1 == '\0')
2813  *buff = '\0';
2814 
2815  return 0;
2816 }
2817 
2827 {
2828  static char *buff;
2829  char flg[4];
2830  char *cur;
2831  const char *tmp;
2832  struct Flag *flag;
2833  struct Option *opt;
2834  int n, len, slen;
2835  int nalloced = 0;
2836 
2837  G_debug(3, "G_recreate_command()");
2838 
2839  /* Flag is not valid if there are no flags to set */
2840 
2841  buff = G_calloc(1024, sizeof(char));
2842  nalloced += 1024;
2843  tmp = G_program_name();
2844  len = strlen(tmp);
2845  if (len >= nalloced) {
2846  nalloced += (1024 > len) ? 1024 : len + 1;
2847  buff = G_realloc(buff, nalloced);
2848  }
2849  cur = buff;
2850  strcpy(cur, tmp);
2851  cur += len;
2852 
2853  if (n_flags) {
2854  flag = &first_flag;
2855  while (flag != '\0') {
2856  if (flag->answer == 1) {
2857  flg[0] = ' ';
2858  flg[1] = '-';
2859  flg[2] = flag->key;
2860  flg[3] = '\0';
2861  slen = strlen(flg);
2862  if (len + slen >= nalloced) {
2863  nalloced +=
2864  (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
2865  buff = G_realloc(buff, nalloced);
2866  cur = buff + len;
2867  }
2868  strcpy(cur, flg);
2869  cur += slen;
2870  len += slen;
2871  }
2872  flag = flag->next_flag;
2873  }
2874  }
2875 
2876  opt = &first_option;
2877  while (opt != '\0') {
2878  if (opt->answer != '\0' && opt->answers && opt->answers[0] != NULL) {
2879  slen = strlen(opt->key) + strlen(opt->answers[0]) + 4; /* +4 for: ' ' = " " */
2880  if (len + slen >= nalloced) {
2881  nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
2882  buff = G_realloc(buff, nalloced);
2883  cur = buff + len;
2884  }
2885  strcpy(cur, " ");
2886  cur++;
2887  strcpy(cur, opt->key);
2888  cur = strchr(cur, '\0');
2889  strcpy(cur, "=");
2890  cur++;
2891  if (opt->type == TYPE_STRING) {
2892  strcpy(cur, "\"");
2893  cur++;
2894  }
2895  strcpy(cur, opt->answers[0]);
2896  cur = strchr(cur, '\0');
2897  len = cur - buff;
2898  for (n = 1; opt->answers[n] != NULL && opt->answers[n] != '\0';
2899  n++) {
2900  if (opt->answers[n] == NULL)
2901  break;
2902  slen = strlen(opt->answers[n]) + 2; /* +2 for , " */
2903  if (len + slen >= nalloced) {
2904  nalloced +=
2905  (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
2906  buff = G_realloc(buff, nalloced);
2907  cur = buff + len;
2908  }
2909  strcpy(cur, ",");
2910  cur++;
2911  strcpy(cur, opt->answers[n]);
2912  cur = strchr(cur, '\0');
2913  len = cur - buff;
2914  }
2915  if (opt->type == TYPE_STRING) {
2916  strcpy(cur, "\"");
2917  cur++;
2918  len = cur - buff;
2919  }
2920  }
2921  opt = opt->next_opt;
2922  }
2923 
2924  return (buff);
2925 }
char * G_mapset(void)
current mapset name
Definition: mapset.c:31
#define MISSING_VALUE
Definition: parser.c:101
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
#define KEYLENGTH
Definition: parser.c:102
struct Option * G_define_standard_option(int opt)
Create standardised Option structure.
Definition: parser.c:327
char * G__getenv(const char *name)
Get environment variable.
Definition: env.c:312
#define NULL
Definition: strings.c:26
char * G_store(const char *s)
Copy string to allocated memory.
Definition: store.c:32
def error(msg)
Display an error message using g.message -e
Definition: core.py:370
int G_free_tokens(char **tokens)
Free memory allocated to tokens.
Definition: gis/token.c:98
#define FALSE
Definition: dbfopen.c:117
struct GModule * G_define_module(void)
Initializes a new module.
Definition: parser.c:691
char * G_index(const char *str, int delim)
delimiter
Definition: gis/index.c:16
int G_copy(void *a, const void *b, int n)
Copies n bytes starting at address b into address a.
Definition: gis/copy.c:30
int G_yes(const char *question, int dflt)
Ask a yes/no question.
Definition: yes.c:39
char * G_ask_in_mapset(const char *prompt, char *name, char *element, char *desc)
prompt for existing database file
Definition: ask.c:222
int G_set_ask_return_msg(const char *msg)
set Hit RETURN msg
Definition: ask.c:316
int G_disable_interactive(void)
Disables the ability of the parser to operate interactively.
Definition: parser.c:170
char ** G_tokenize(const char *buf, const char *delim)
Tokenize string.
Definition: gis/token.c:33
#define do_escape(c, escaped)
Format text for HTML output.
Definition: parser.c:1261
char * G_ask_new(const char *prompt, char *name, char *element, char *desc)
prompt for new database file
Definition: ask.c:132
list command
Definition: render.py:1305
char * G_recreate_command(void)
Creates command to run non-interactive.
Definition: parser.c:2826
Definition: parser.c:120
struct Flag * G_define_flag(void)
Initializes a Flag struct.
Definition: parser.c:191
int G_warning(const char *msg,...)
Print a warning message to stderr.
char * G_getenv(const char *name)
Get environment variable.
Definition: env.c:267
char * getenv()
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition: symbol/read.c:220
int G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:29
int G_parser(int argc, char **argv)
Parse command line.
Definition: parser.c:743
struct Option * G_define_option(void)
Initializes an Option struct.
Definition: parser.c:247
int G_verbose_max(void)
Get max verbosity level.
Definition: verbose.c:68
#define TRUE
Definition: dbfopen.c:118
char * G_ask_old(const char *prompt, char *name, char *element, char *desc)
prompt for existing database file
Definition: ask.c:161
#define BAD_SYNTAX
Definition: parser.c:99
int G_info_format(void)
Get current message format.
flag
Definition: tools.py:1403
struct Item * next_item
Definition: parser.c:124
char * G_basename(char *filename, const char *desired_ext)
Truncates filename to the base part (before the last '.') if it matches the extension, otherwise leaves it unchanged.
Definition: basename.c:37
const char * G_program_name(void)
return module name
Definition: progrm_nme.c:33
int G_verbose(void)
Get current verbosity level.
Definition: verbose.c:45
char * G_whoami(void)
Gets user's name.
Definition: gis/whoami.c:40
struct Flag * flag
Definition: parser.c:123
char * G_ask_any(const char *prompt, char *name, char *element, char *desc, int warn)
prompt for any valid file name
Definition: ask.c:190
char * G_ask_new_file(const char *prompt, char *name, char *element, char *desc)
prompt for new file
Definition: ask.c:247
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
char * G_ask_old_file(const char *prompt, char *name, char *element, char *desc)
prompt for existing file
Definition: ask.c:282
char * G_fully_qualified_name(const char *name, const char *mapset)
fully qualified file name
Definition: nme_in_mps.c:118
int G_verbose_min(void)
Get min verbosity level.
Definition: verbose.c:92
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. returns the mapset name whe...
Definition: find_file.c:159
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
struct Option * option
Definition: parser.c:122
#define OUT_OF_RANGE
Definition: parser.c:100
int G_is_dirsep(char c)
Checks if a specified character is a valid directory separator character on the host system...
Definition: paths.c:35
int G_usage(void)
Command line help/usage message.
Definition: parser.c:1057
int G_spawn(const char *command,...)
Spawn new process based on command.
Definition: spawn.c:914