GRASS Programmer's Manual  6.4.2(2012)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 to 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->description = _("Field separator");
654  break;
655 
656  /* colors */
657  case G_OPT_C_FG:
658  Opt->key = "color";
659  Opt->type = TYPE_STRING;
660  Opt->key_desc = "name";
661  Opt->required = NO;
662  Opt->answer = DEFAULT_FG_COLOR;
663  Opt->gisprompt = "old_color,color,color";
664  Opt->label = _("Color");
665  Opt->description = _("Either a standard color name or R:G:B triplet");
666  break;
667  case G_OPT_C_BG:
668  Opt->key = "bgcolor";
669  Opt->type = TYPE_STRING;
670  Opt->key_desc = "name";
671  Opt->required = NO;
672  Opt->answer = DEFAULT_BG_COLOR;
673  Opt->gisprompt = "old_color,color,color_none";
674  Opt->label = _("Background color");
675  Opt->description =
676  _("Either a standard GRASS color, R:G:B triplet, or \"none\"");
677  break;
678  }
679 
680  return (Opt);
681 }
682 
683 
690 struct GModule *G_define_module(void)
691 {
692  struct GModule *module;
693 
694  /* Allocate memory */
695 
696  module = &module_info;
697 
698  /* Zero structure */
699 
700  G_zero((char *)module, sizeof(struct GModule));
701 
702  return (module);
703 }
704 
705 /* The main parsing routine */
706 
742 int G_parser(int argc, char **argv)
743 {
744  int need_first_opt;
745  int opt_checked = 0;
746  int error;
747  char *ptr, *tmp_name;
748  int i;
749  struct Option *opt;
750  char force_gui = FALSE;
751 
752  error = 0;
753  need_first_opt = 1;
754  i = strlen(tmp_name = G_store(argv[0]));
755  while (--i >= 0) {
756  if (G_is_dirsep(tmp_name[i])) {
757  tmp_name += i + 1;
758  break;
759  }
760  }
761  G_basename(tmp_name, "exe");
762  pgm_name = tmp_name;
763 
764  /* Stash default answers */
765 
766  opt = &first_option;
767  while (opt != NULL) {
768  /* Parse options */
769  if (opt->options) {
770  int cnt = 0;
771  char **tokens, delm[2];
772 
773  delm[0] = ',';
774  delm[1] = '\0';
775  tokens = G_tokenize(opt->options, delm);
776 
777  i = 0;
778  while (tokens[i]) {
779  cnt++;
780  i++;
781  }
782 
783  opt->opts =
784  (const char **)G_calloc(cnt + 1, sizeof(const char *));
785 
786  i = 0;
787  while (tokens[i]) {
788  opt->opts[i] = G_store(tokens[i]);
789  i++;
790  }
791  G_free_tokens(tokens);
792 
793  if (opt->descriptions) {
794  delm[0] = ';';
795 
796  opt->descs =
797  (const char **)G_calloc(cnt + 1, sizeof(const char *));
798  tokens = G_tokenize(opt->descriptions, delm);
799 
800  i = 0;
801  while (tokens[i]) {
802  int j, found;
803 
804  if (!tokens[i + 1])
805  break;
806 
807  j = 0;
808  found = 0;
809  while (opt->opts[j]) {
810  if (strcmp(opt->opts[j], tokens[i]) == 0) {
811  found = 1;
812  break;
813  }
814  j++;
815  }
816  if (!found) {
817  G_warning(_("BUG in descriptions, option '%s' in <%s> does not exist"),
818  tokens[i], opt->key);
819  }
820  else {
821  opt->descs[j] = G_store(tokens[i + 1]);
822  }
823 
824  i += 2;
825  }
826  G_free_tokens(tokens);
827  }
828  }
829 
830  /* Copy answer */
831  if (opt->multiple && opt->answers && opt->answers[0]) {
832  opt->answer = (char *)G_malloc(strlen(opt->answers[0]) + 1);
833  strcpy(opt->answer, opt->answers[0]);
834  for (i = 1; opt->answers[i]; i++) {
835  opt->answer = (char *)G_realloc(opt->answer,
836  strlen(opt->answer) +
837  strlen(opt->answers[i]) + 2);
838  strcat(opt->answer, ",");
839  strcat(opt->answer, opt->answers[i]);
840  }
841  }
842  opt->def = opt->answer;
843  opt = opt->next_opt;
844  }
845 
846  /* If there are NO arguments, go interactive */
847 
848  if (argc < 2 && interactive_ok && isatty(0)) {
849  if (getenv("GRASS_UI_TERM")) {
850  interactive(argv[0]);
851  opt_checked = 1;
852  /* all options have been already checked interactively */
853  }
854  else {
855  G_gui();
856  return -1;
857  }
858  }
859  else if (argc < 2 && isatty(0)) {
860  G_usage();
861  return -1;
862  }
863  else if (argc >= 2) {
864 
865  /* If first arg is "help" give a usage/syntax message */
866  if (strcmp(argv[1], "help") == 0 ||
867  strcmp(argv[1], "-help") == 0 || strcmp(argv[1], "--help") == 0) {
868  G_usage();
869  exit(EXIT_SUCCESS);
870  }
871 
872  /* If first arg is "--interface-description" then print out
873  * a xml description of the task */
874  if (strcmp(argv[1], "--interface-description") == 0) {
875  G_usage_xml();
876  exit(EXIT_SUCCESS);
877  }
878 
879  /* If first arg is "--html-description" then print out
880  * a html description of the task */
881  if (strcmp(argv[1], "--html-description") == 0) {
882  G_usage_html();
883  exit(EXIT_SUCCESS);
884  }
885 
886  /* If first arg is "--tcltk" then generate
887  * code for tcltkgrass */
888  if (strcmp(argv[1], "--tcltk") == 0) {
889  G_tcltk();
890  exit(EXIT_SUCCESS);
891  }
892 
893  /* If first arg is "--script" then then generate
894  * g.parser boilerplate */
895  if (strcmp(argv[1], "--script") == 0) {
896  G_script();
897  exit(EXIT_SUCCESS);
898  }
899 
900  /* Loop thru all command line arguments */
901 
902  while (--argc) {
903  ptr = *(++argv);
904 
905  if (strcmp(ptr, "help") == 0 ||
906  strcmp(ptr, "-help") == 0 || strcmp(ptr, "--help") == 0) {
907  G_usage();
908  exit(EXIT_SUCCESS);
909  }
910 
911  /* Overwrite option */
912  if (strcmp(ptr, "--o") == 0 || strcmp(ptr, "--overwrite") == 0) {
913  overwrite = 1;
914  }
915 
916  /* Verbose option */
917  else if (strcmp(ptr, "--v") == 0 || strcmp(ptr, "--verbose") == 0) {
918  char buff[32];
919 
920  /* print everything: max verbosity level */
921  module_info.verbose = G_verbose_max();
922  sprintf(buff, "GRASS_VERBOSE=%d", G_verbose_max());
923  putenv(G_store(buff));
924  if (quiet == 1) {
925  G_warning(_("Use either --quiet or --verbose flag, not both. Assuming --verbose."));
926  }
927  quiet = -1;
928  }
929 
930  /* Quiet option */
931  else if (strcmp(ptr, "--q") == 0 || strcmp(ptr, "--quiet") == 0) {
932  char buff[32];
933 
934  /* print nothing, but errors and warnings */
935  module_info.verbose = G_verbose_min();
936  sprintf(buff, "GRASS_VERBOSE=%d", G_verbose_min());
937  putenv(G_store(buff));
938  if (quiet == -1) {
939  G_warning(_("Use either --quiet or --verbose flag, not both. Assuming --quiet."));
940  }
941  quiet = 1; /* for passing to gui init */
942  }
943 
944  /* Force gui to come up */
945  else if (strcmp(ptr, "--ui") == 0) {
946  force_gui = TRUE;
947  }
948 
949  /* If we see a flag */
950  else if (*ptr == '-') {
951  while (*(++ptr))
952  error += set_flag(*ptr);
953 
954  }
955  /* If we see standard option format (option=val) */
956  else if (is_option(ptr)) {
957  error += set_option(ptr);
958  need_first_opt = 0;
959  }
960 
961  /* If we see the first option with no equal sign */
962  else if (need_first_opt && n_opts) {
963  first_option.answer = G_store(ptr);
964  first_option.count++;
965  need_first_opt = 0;
966  }
967 
968  /* If we see the non valid argument (no "=", just argument) */
969  else if (contains(ptr, '=') == 0) {
970  fprintf(stderr, _("Sorry <%s> is not a valid option\n"), ptr);
971  error = 1;
972  }
973 
974  }
975  }
976 
977  /* Split options where multiple answers are OK */
978  split_opts();
979 
980  /* Run the gui if it was specifically requested */
981  if (force_gui) {
982  G_gui();
983  return -1;
984  }
985 
986  /* Check multiple options */
987  error += check_multiple_opts();
988 
989  /* Check answers against options and check subroutines */
990  if (!opt_checked)
991  error += check_opts();
992 
993  /* Make sure all required options are set */
994  error += check_required();
995 
996  if (error) {
997  if (G_verbose() > G_verbose_min())
998  G_usage();
999  return -1;
1000  }
1001 
1002  if (check_overwrite())
1003  return -1;
1004 
1005  return (0);
1006 }
1007 
1008 
1009 static int uses_new_gisprompt(void)
1010 {
1011  struct Option *opt;
1012  char age[KEYLENGTH];
1013  char element[KEYLENGTH];
1014  char desc[KEYLENGTH];
1015 
1016  /* figure out if any of the options use a "new" gisprompt */
1017  /* This is to see if we should spit out the --o flag */
1018  if (n_opts) {
1019  opt = &first_option;
1020  while (opt != NULL) {
1021  if (opt->gisprompt) {
1022  split_gisprompt(opt->gisprompt, age, element, desc);
1023  if (strcmp(age, "new") == 0)
1024  return 1;
1025  }
1026  opt = opt->next_opt;
1027  }
1028  }
1029 
1030  return 0;
1031 }
1032 
1033 
1056 int G_usage(void)
1057 {
1058  struct Option *opt;
1059  struct Flag *flag;
1060  char item[256];
1061  const char *key_desc;
1062  int maxlen;
1063  int len, n;
1064  int new_prompt = 0;
1065 
1066  new_prompt = uses_new_gisprompt();
1067 
1068  if (!pgm_name) /* v.dave && r.michael */
1069  pgm_name = G_program_name();
1070  if (!pgm_name)
1071  pgm_name = "??";
1072 
1073  if (module_info.label || module_info.description) {
1074  fprintf(stderr, _("\nDescription:\n"));
1075  if (module_info.label)
1076  fprintf(stderr, " %s\n", module_info.label);
1077  if (module_info.description)
1078  fprintf(stderr, " %s\n", module_info.description);
1079  }
1080  if (module_info.keywords) {
1081  fprintf(stderr, _("\nKeywords:\n"));
1082  fprintf(stderr, " %s\n", module_info.keywords);
1083  }
1084 
1085  fprintf(stderr, _("\nUsage:\n "));
1086 
1087  len = show(pgm_name, 1);
1088 
1089  /* Print flags */
1090 
1091  if (n_flags) {
1092  item[0] = ' ';
1093  item[1] = '[';
1094  item[2] = '-';
1095  flag = &first_flag;
1096  for (n = 3; flag != NULL; n++, flag = flag->next_flag)
1097  item[n] = flag->key;
1098  item[n++] = ']';
1099  item[n] = 0;
1100  len = show(item, len);
1101  }
1102 
1103  maxlen = 0;
1104  if (n_opts) {
1105  opt = &first_option;
1106  while (opt != NULL) {
1107  if (opt->key_desc != NULL)
1108  key_desc = opt->key_desc;
1109  else if (opt->type == TYPE_STRING)
1110  key_desc = "string";
1111  else
1112  key_desc = "value";
1113 
1114  n = strlen(opt->key);
1115  if (n > maxlen)
1116  maxlen = n;
1117 
1118  strcpy(item, " ");
1119  if (!opt->required)
1120  strcat(item, "[");
1121  strcat(item, opt->key);
1122  strcat(item, "=");
1123  strcat(item, key_desc);
1124  if (opt->multiple) {
1125  strcat(item, "[,");
1126  strcat(item, key_desc);
1127  strcat(item, ",...]");
1128  }
1129  if (!opt->required)
1130  strcat(item, "]");
1131 
1132  len = show(item, len);
1133 
1134  opt = opt->next_opt;
1135  }
1136  }
1137  if (new_prompt) {
1138  strcpy(item, " [--overwrite]");
1139  len = show(item, len);
1140  }
1141 
1142  strcpy(item, " [--verbose]");
1143  len = show(item, len);
1144 
1145  strcpy(item, " [--quiet]");
1146  len = show(item, len);
1147 
1148 
1149  fprintf(stderr, "\n");
1150 
1151  /* Print help info for flags */
1152 
1153  fprintf(stderr, _("\nFlags:\n"));
1154 
1155  if (n_flags) {
1156  flag = &first_flag;
1157  while (flag != NULL) {
1158  fprintf(stderr, " -%c ", flag->key);
1159 
1160  if (flag->label) {
1161  fprintf(stderr, "%s\n", flag->label);
1162  if (flag->description)
1163  fprintf(stderr, " %s\n", flag->description);
1164 
1165  }
1166  else if (flag->description) {
1167  fprintf(stderr, "%s\n", flag->description);
1168  }
1169 
1170  flag = flag->next_flag;
1171  }
1172  }
1173 
1174  if (new_prompt)
1175  fprintf(stderr, " --o %s\n",
1176  _("Allow output files to overwrite existing files"));
1177 
1178  fprintf(stderr, " --v %s\n", _("Verbose module output"));
1179  fprintf(stderr, " --q %s\n", _("Quiet module output"));
1180 
1181  /* Print help info for options */
1182 
1183  if (n_opts) {
1184  fprintf(stderr, _("\nParameters:\n"));
1185  opt = &first_option;
1186  while (opt != NULL) {
1187  fprintf(stderr, " %*s ", maxlen, opt->key);
1188 
1189  if (opt->label) {
1190  fprintf(stderr, "%s\n", opt->label);
1191  if (opt->description) {
1192  fprintf(stderr, " %*s %s\n",
1193  maxlen, " ", opt->description);
1194  }
1195  }
1196  else if (opt->description) {
1197  fprintf(stderr, "%s\n", opt->description);
1198  }
1199 
1200  if (opt->options)
1201  show_options(maxlen, opt->options);
1202  /*
1203  fprintf (stderr, " %*s options: %s\n", maxlen, " ",
1204  _(opt->options)) ;
1205  */
1206  if (opt->def)
1207  fprintf(stderr, _(" %*s default: %s\n"), maxlen, " ",
1208  opt->def);
1209 
1210  if (opt->descs) {
1211  int i = 0;
1212 
1213  while (opt->opts[i]) {
1214  if (opt->descs[i])
1215  fprintf(stderr, " %*s %s: %s\n",
1216  maxlen, " ", opt->opts[i], opt->descs[i]);
1217 
1218  i++;
1219  }
1220  }
1221 
1222  opt = opt->next_opt;
1223  }
1224  }
1225 
1226  return 0;
1227 }
1228 
1229 
1237 static void print_escaped_for_xml(FILE * fp, const char *str)
1238 {
1239  for (; *str; str++) {
1240  switch (*str) {
1241  case '&':
1242  fputs("&amp;", fp);
1243  break;
1244  case '<':
1245  fputs("&lt;", fp);
1246  break;
1247  case '>':
1248  fputs("&gt;", fp);
1249  break;
1250  default:
1251  fputc(*str, fp);
1252  }
1253  }
1254 }
1255 
1256 
1260 #define do_escape(c,escaped) case c: fputs(escaped,f);break
1261 static void print_escaped_for_html(FILE * f, const char *str)
1262 {
1263  const char *s;
1264 
1265  for (s = str; *s; s++) {
1266  switch (*s) {
1267  do_escape('&', "&amp;");
1268  do_escape('<', "&lt;");
1269  do_escape('>', "&gt;");
1270  do_escape('\n', "<br>");
1271  default:
1272  fputc(*s, f);
1273  }
1274  }
1275 }
1276 
1277 #undef do_escape
1278 
1282 static void G_usage_xml(void)
1283 {
1284  struct Option *opt;
1285  struct Flag *flag;
1286  char *type;
1287  char *s, *top;
1288  int i;
1289  char *encoding;
1290  int new_prompt = 0;
1291 
1292  new_prompt = uses_new_gisprompt();
1293 
1294  /* gettext converts strings to encoding returned by nl_langinfo(CODESET) */
1295 
1296 #if defined(HAVE_LANGINFO_H)
1297  encoding = nl_langinfo(CODESET);
1298  if (!encoding || strlen(encoding) == 0) {
1299  encoding = "UTF-8";
1300  }
1301 #elif defined(__MINGW32__) && defined(USE_NLS)
1302  encoding = locale_charset();
1303  if (!encoding || strlen(encoding) == 0) {
1304  encoding = "UTF-8";
1305  }
1306 #else
1307  encoding = "UTF-8";
1308 #endif
1309 
1310  if (!pgm_name) /* v.dave && r.michael */
1311  pgm_name = G_program_name();
1312  if (!pgm_name)
1313  pgm_name = "??";
1314 
1315  fprintf(stdout, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding);
1316  fprintf(stdout, "<!DOCTYPE task SYSTEM \"grass-interface.dtd\">\n");
1317 
1318  fprintf(stdout, "<task name=\"%s\">\n", pgm_name);
1319 
1320  if (module_info.label) {
1321  fprintf(stdout, "\t<label>\n\t\t");
1322  print_escaped_for_xml(stdout, module_info.label);
1323  fprintf(stdout, "\n\t</label>\n");
1324  }
1325 
1326  if (module_info.description) {
1327  fprintf(stdout, "\t<description>\n\t\t");
1328  print_escaped_for_xml(stdout, module_info.description);
1329  fprintf(stdout, "\n\t</description>\n");
1330  }
1331 
1332  if (module_info.keywords) {
1333  fprintf(stdout, "\t<keywords>\n\t\t");
1334  print_escaped_for_xml(stdout, module_info.keywords);
1335  fprintf(stdout, "\n\t</keywords>\n");
1336  }
1337 
1338  /***** Don't use parameter-groups for now. We'll reimplement this later
1339  ***** when we have a concept of several mutually exclusive option
1340  ***** groups
1341  if (n_opts || n_flags)
1342  fprintf(stdout, "\t<parameter-group>\n");
1343  *****
1344  *****
1345  *****/
1346 
1347  if (n_opts) {
1348  opt = &first_option;
1349  while (opt != NULL) {
1350  /* TODO: make this a enumeration type? */
1351  switch (opt->type) {
1352  case TYPE_INTEGER:
1353  type = "integer";
1354  break;
1355  case TYPE_DOUBLE:
1356  type = "float";
1357  break;
1358  case TYPE_STRING:
1359  type = "string";
1360  break;
1361  default:
1362  type = "string";
1363  break;
1364  }
1365  fprintf(stdout, "\t<parameter "
1366  "name=\"%s\" "
1367  "type=\"%s\" "
1368  "required=\"%s\" "
1369  "multiple=\"%s\">\n",
1370  opt->key,
1371  type,
1372  opt->required == YES ? "yes" : "no",
1373  opt->multiple == YES ? "yes" : "no");
1374 
1375  if (opt->label) {
1376  fprintf(stdout, "\t\t<label>\n\t\t\t");
1377  print_escaped_for_xml(stdout, opt->label);
1378  fprintf(stdout, "\n\t\t</label>\n");
1379  }
1380 
1381  if (opt->description) {
1382  fprintf(stdout, "\t\t<description>\n\t\t\t");
1383  print_escaped_for_xml(stdout, opt->description);
1384  fprintf(stdout, "\n\t\t</description>\n");
1385  }
1386 
1387  if (opt->key_desc) {
1388  fprintf(stdout, "\t\t<keydesc>\n");
1389  top = G_calloc(strlen(opt->key_desc) + 1, 1);
1390  strcpy(top, opt->key_desc);
1391  s = strtok(top, ",");
1392  for (i = 1; s != NULL; i++) {
1393  fprintf(stdout, "\t\t\t<item order=\"%d\">", i);
1394  print_escaped_for_xml(stdout, s);
1395  fprintf(stdout, "</item>\n");
1396  s = strtok(NULL, ",");
1397  }
1398  fprintf(stdout, "\t\t</keydesc>\n");
1399  G_free(top);
1400  }
1401 
1402  if (opt->gisprompt) {
1403  const char *atts[] = { "age", "element", "prompt", NULL };
1404  top = G_calloc(strlen(opt->gisprompt) + 1, 1);
1405  strcpy(top, opt->gisprompt);
1406  s = strtok(top, ",");
1407  fprintf(stdout, "\t\t<gisprompt ");
1408  for (i = 0; s != NULL && atts[i] != NULL; i++) {
1409  fprintf(stdout, "%s=\"%s\" ", atts[i], s);
1410  s = strtok(NULL, ",");
1411  }
1412  fprintf(stdout, "/>\n");
1413  G_free(top);
1414  }
1415 
1416  if (opt->def) {
1417  fprintf(stdout, "\t\t<default>\n\t\t\t");
1418  print_escaped_for_xml(stdout, opt->def);
1419  fprintf(stdout, "\n\t\t</default>\n");
1420  }
1421 
1422  if (opt->options) {
1423  /* TODO:
1424  * add something like
1425  * <range min="xxx" max="xxx"/>
1426  * to <values> */
1427  i = 0;
1428  fprintf(stdout, "\t\t<values>\n");
1429  while (opt->opts[i]) {
1430  fprintf(stdout, "\t\t\t<value>\n");
1431  fprintf(stdout, "\t\t\t\t<name>");
1432  print_escaped_for_xml(stdout, opt->opts[i]);
1433  fprintf(stdout, "</name>\n");
1434  if (opt->descs && opt->opts[i] && opt->descs[i]) {
1435  fprintf(stdout, "\t\t\t\t<description>");
1436  print_escaped_for_xml(stdout, opt->descs[i]);
1437  fprintf(stdout, "</description>\n");
1438  }
1439  fprintf(stdout, "\t\t\t</value>\n");
1440  i++;
1441  }
1442  fprintf(stdout, "\t\t</values>\n");
1443  }
1444  if (opt->guisection) {
1445  fprintf(stdout, "\t\t<guisection>\n\t\t\t");
1446  print_escaped_for_xml(stdout, opt->guisection);
1447  fprintf(stdout, "\n\t\t</guisection>\n");
1448  }
1449  /* TODO:
1450  * - key_desc?
1451  * - there surely are some more. which ones?
1452  */
1453 
1454  opt = opt->next_opt;
1455  fprintf(stdout, "\t</parameter>\n");
1456  }
1457  }
1458 
1459 
1460  if (n_flags) {
1461  flag = &first_flag;
1462  while (flag != NULL) {
1463  fprintf(stdout, "\t<flag name=\"%c\">\n", flag->key);
1464 
1465  if (flag->label) {
1466  fprintf(stdout, "\t\t<label>\n\t\t\t");
1467  print_escaped_for_xml(stdout, flag->label);
1468  fprintf(stdout, "\n\t\t</label>\n");
1469  }
1470 
1471  if (flag->description) {
1472  fprintf(stdout, "\t\t<description>\n\t\t\t");
1473  print_escaped_for_xml(stdout, flag->description);
1474  fprintf(stdout, "\n\t\t</description>\n");
1475  }
1476  if (flag->guisection) {
1477  fprintf(stdout, " \t\t<guisection>\n\t\t\t");
1478  print_escaped_for_xml(stdout, flag->guisection);
1479  fprintf(stdout, "\n\t\t</guisection>\n");
1480  }
1481  flag = flag->next_flag;
1482  fprintf(stdout, "\t</flag>\n");
1483  }
1484  }
1485 
1486  /***** Don't use parameter-groups for now. We'll reimplement this later
1487  ***** when we have a concept of several mutually exclusive option
1488  ***** groups
1489  if (n_opts || n_flags)
1490  fprintf(stdout, "\t</parameter-group>\n");
1491  *****
1492  *****
1493  *****/
1494 
1495  if (new_prompt) {
1496  /* overwrite */
1497  fprintf(stdout, "\t<flag name=\"%s\">\n", "overwrite");
1498  fprintf(stdout, "\t\t<description>\n\t\t\t");
1499  print_escaped_for_xml(stdout,
1500  _("Allow output files to overwrite existing files"));
1501  fprintf(stdout, "\n\t\t</description>\n");
1502  fprintf(stdout, "\t</flag>\n");
1503  }
1504 
1505  /* verbose */
1506  fprintf(stdout, "\t<flag name=\"%s\">\n", "verbose");
1507  fprintf(stdout, "\t\t<description>\n\t\t\t");
1508  print_escaped_for_xml(stdout, _("Verbose module output"));
1509  fprintf(stdout, "\n\t\t</description>\n");
1510  fprintf(stdout, "\t</flag>\n");
1511 
1512  /* quiet */
1513  fprintf(stdout, "\t<flag name=\"%s\">\n", "quiet");
1514  fprintf(stdout, "\t\t<description>\n\t\t\t");
1515  print_escaped_for_xml(stdout, _("Quiet module output"));
1516  fprintf(stdout, "\n\t\t</description>\n");
1517  fprintf(stdout, "\t</flag>\n");
1518 
1519  fprintf(stdout, "</task>\n");
1520 }
1521 
1525 static void G_usage_html(void)
1526 {
1527  struct Option *opt;
1528  struct Flag *flag;
1529  const char *type;
1530  int new_prompt = 0;
1531 
1532  new_prompt = uses_new_gisprompt();
1533 
1534  if (!pgm_name) /* v.dave && r.michael */
1535  pgm_name = G_program_name();
1536  if (!pgm_name)
1537  pgm_name = "??";
1538 
1539  fprintf(stdout,
1540  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
1541  fprintf(stdout, "<html>\n<head>\n");
1542  fprintf(stdout, "<title>GRASS GIS manual: %s</title>\n", pgm_name);
1543  fprintf(stdout,
1544  "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n");
1545  fprintf(stdout,
1546  "<link rel=\"stylesheet\" href=\"grassdocs.css\" type=\"text/css\">\n");
1547  fprintf(stdout, "</head>\n");
1548  fprintf(stdout, "<body bgcolor=\"white\">\n\n");
1549  fprintf(stdout,
1550  "<img src=\"grass_logo.png\" alt=\"GRASS logo\"><hr align=center size=6 noshade>\n\n");
1551  fprintf(stdout, "<h2>%s</h2>\n", _("NAME"));
1552  fprintf(stdout, "<em><b>%s</b></em> ", pgm_name);
1553 
1554  if (module_info.label || module_info.description)
1555  fprintf(stdout, " - ");
1556 
1557  if (module_info.label)
1558  fprintf(stdout, "%s<BR>\n", module_info.label);
1559 
1560  if (module_info.description)
1561  fprintf(stdout, "%s\n", module_info.description);
1562 
1563 
1564  fprintf(stdout, "<h2>%s</h2>\n", _("KEYWORDS"));
1565  if (module_info.keywords) {
1566  fprintf(stdout, "%s", module_info.keywords);
1567  fprintf(stdout, "\n");
1568  }
1569  fprintf(stdout, "<h2>%s</h2>\n", _("SYNOPSIS"));
1570  fprintf(stdout, "<b>%s</b><br>\n", pgm_name);
1571  fprintf(stdout, "<b>%s help</b><br>\n", pgm_name);
1572 
1573  fprintf(stdout, "<b>%s</b>", pgm_name);
1574 
1575 
1576 
1577  /* print short version first */
1578  if (n_flags) {
1579  flag = &first_flag;
1580  fprintf(stdout, " [-<b>");
1581  while (flag != NULL) {
1582  fprintf(stdout, "%c", flag->key);
1583  flag = flag->next_flag;
1584  }
1585  fprintf(stdout, "</b>] ");
1586  }
1587  else
1588  fprintf(stdout, " ");
1589 
1590  if (n_opts) {
1591  opt = &first_option;
1592 
1593  while (opt != NULL) {
1594  if (opt->key_desc != NULL)
1595  type = opt->key_desc;
1596  else
1597  switch (opt->type) {
1598  case TYPE_INTEGER:
1599  type = "integer";
1600  break;
1601  case TYPE_DOUBLE:
1602  type = "float";
1603  break;
1604  case TYPE_STRING:
1605  type = "string";
1606  break;
1607  default:
1608  type = "string";
1609  break;
1610  }
1611  if (!opt->required)
1612  fprintf(stdout, " [");
1613  fprintf(stdout, "<b>%s</b>=<em>%s</em>", opt->key, type);
1614  if (opt->multiple) {
1615  fprintf(stdout, "[,<i>%s</i>,...]", type);
1616  }
1617  if (!opt->required)
1618  fprintf(stdout, "] ");
1619 
1620  opt = opt->next_opt;
1621  fprintf(stdout, " ");
1622  }
1623  }
1624  if (new_prompt)
1625  fprintf(stdout, " [--<b>overwrite</b>] ");
1626 
1627  fprintf(stdout, " [--<b>verbose</b>] ");
1628  fprintf(stdout, " [--<b>quiet</b>] ");
1629 
1630  fprintf(stdout, "\n");
1631 
1632 
1633  /* now long version */
1634  fprintf(stdout, "\n");
1635  if (n_flags || new_prompt) {
1636  flag = &first_flag;
1637  fprintf(stdout, "<h3>%s:</h3>\n", _("Flags"));
1638  fprintf(stdout, "<DL>\n");
1639  while (n_flags && flag != NULL) {
1640  fprintf(stdout, "<DT><b>-%c</b></DT>\n", flag->key);
1641 
1642  if (flag->label) {
1643  fprintf(stdout, "<DD>");
1644  fprintf(stdout, "%s", flag->label);
1645  fprintf(stdout, "</DD>\n");
1646  }
1647 
1648  if (flag->description) {
1649  fprintf(stdout, "<DD>");
1650  fprintf(stdout, "%s", flag->description);
1651  fprintf(stdout, "</DD>\n");
1652  }
1653 
1654  flag = flag->next_flag;
1655  fprintf(stdout, "\n");
1656  }
1657  if (new_prompt) {
1658  fprintf(stdout, "<DT><b>--overwrite</b></DT>\n");
1659  fprintf(stdout, "<DD>%s</DD>\n",
1660  _("Allow output files to overwrite existing files"));
1661  }
1662 
1663  fprintf(stdout, "<DT><b>--verbose</b></DT>\n");
1664  fprintf(stdout, "<DD>%s</DD>\n", _("Verbose module output"));
1665 
1666  fprintf(stdout, "<DT><b>--quiet</b></DT>\n");
1667  fprintf(stdout, "<DD>%s</DD>\n", _("Quiet module output"));
1668 
1669  fprintf(stdout, "</DL>\n");
1670  }
1671 
1672  fprintf(stdout, "\n");
1673  if (n_opts) {
1674  opt = &first_option;
1675  fprintf(stdout, "<h3>%s:</h3>\n", _("Parameters"));
1676  fprintf(stdout, "<DL>\n");
1677 
1678  while (opt != NULL) {
1679  /* TODO: make this a enumeration type? */
1680  if (opt->key_desc != NULL)
1681  type = opt->key_desc;
1682  else
1683  switch (opt->type) {
1684  case TYPE_INTEGER:
1685  type = "integer";
1686  break;
1687  case TYPE_DOUBLE:
1688  type = "float";
1689  break;
1690  case TYPE_STRING:
1691  type = "string";
1692  break;
1693  default:
1694  type = "string";
1695  break;
1696  }
1697  fprintf(stdout, "<DT><b>%s</b>=<em>%s", opt->key, type);
1698  if (opt->multiple) {
1699  fprintf(stdout, "[,<i>%s</i>,...]", type);
1700  }
1701  fprintf(stdout, "</em></DT>\n");
1702 
1703  if (opt->label) {
1704  fprintf(stdout, "<DD>");
1705  fprintf(stdout, "%s", opt->label);
1706  fprintf(stdout, "</DD>\n");
1707  }
1708  if (opt->description) {
1709  fprintf(stdout, "<DD>");
1710  print_escaped_for_html(stdout, opt->description);
1711  fprintf(stdout, "</DD>\n");
1712  }
1713 
1714  if (opt->options) {
1715  fprintf(stdout, "<DD>%s: <em>", _("Options"));
1716  fprintf(stdout, "%s", opt->options);
1717  fprintf(stdout, "</em></DD>\n");
1718  }
1719 
1720  if (opt->def) {
1721  fprintf(stdout, "<DD>%s: <em>", _("Default"));
1722  fprintf(stdout, "%s", opt->def);
1723  fprintf(stdout, "</em></DD>\n");
1724  }
1725 
1726  if (opt->descs) {
1727  int i = 0;
1728 
1729  while (opt->opts[i]) {
1730  if (opt->descs[i])
1731  fprintf(stdout, "<DD><b>%s</b>: %s</DD>\n",
1732  opt->opts[i], opt->descs[i]);
1733  i++;
1734  }
1735  }
1736 
1737  opt = opt->next_opt;
1738  fprintf(stdout, "\n");
1739  }
1740  fprintf(stdout, "</DL>\n");
1741  }
1742 
1743  fprintf(stdout, "</body>\n</html>\n");
1744 }
1745 
1749 static void G_script(void)
1750 {
1751  FILE *fp = stdout;
1752  char *type;
1753 
1754  fprintf(fp, "#!/bin/sh\n\n");
1755  fprintf(fp,
1756  "############################################################################\n");
1757  fprintf(fp, "#\n");
1758  fprintf(fp, "# MODULE: %s_wrapper\n", G_program_name());
1759  fprintf(fp, "# AUTHOR(S): %s\n", G_whoami());
1760  fprintf(fp, "# PURPOSE: \n");
1761  fprintf(fp, "# COPYRIGHT: (C) 2009 GRASS Development Team/%s\n",
1762  G_whoami());
1763  fprintf(fp, "#\n");
1764  fprintf(fp,
1765  "# This program is free software; you can redistribute it and/or modify\n");
1766  fprintf(fp,
1767  "# it under the terms of the GNU General Public License as published by\n");
1768  fprintf(fp,
1769  "# the Free Software Foundation; either version 2 of the License, or\n");
1770  fprintf(fp, "# (at your option) any later version.\n");
1771  fprintf(fp, "#\n");
1772  fprintf(fp,
1773  "# This program is distributed in the hope that it will be useful,\n");
1774  fprintf(fp,
1775  "# but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
1776  fprintf(fp,
1777  "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
1778  fprintf(fp, "# GNU General Public License for more details.\n");
1779  fprintf(fp, "#\n");
1780  fprintf(fp,
1781  "############################################################################\n");
1782 
1783  fprintf(fp, "#%%Module\n");
1784  if (module_info.label)
1785  fprintf(fp, "#%% label: %s\n", module_info.label);
1786  if (module_info.description)
1787  fprintf(fp, "#%% description: %s\n", module_info.description);
1788  if (module_info.keywords)
1789  fprintf(fp, "#%% keywords: %s\n", module_info.keywords);
1790  fprintf(fp, "#%%End\n");
1791 
1792  if (n_flags) {
1793  struct Flag *flag;
1794 
1795  for (flag = &first_flag; flag; flag = flag->next_flag) {
1796  fprintf(fp, "#%%Flag\n");
1797  fprintf(fp, "#%% key: %c\n", flag->key);
1798  if (flag->label)
1799  fprintf(fp, "#%% label: %s\n", flag->label);
1800  if (flag->description)
1801  fprintf(fp, "#%% description: %s\n", flag->description);
1802  if (flag->guisection)
1803  fprintf(fp, "#%% guisection: %s\n", flag->guisection);
1804  fprintf(fp, "#%%End\n");
1805  }
1806  }
1807 
1808  if (n_opts) {
1809  struct Option *opt;
1810 
1811  for (opt = &first_option; opt; opt = opt->next_opt) {
1812  switch (opt->type) {
1813  case TYPE_INTEGER:
1814  type = "integer";
1815  break;
1816  case TYPE_DOUBLE:
1817  type = "double";
1818  break;
1819  case TYPE_STRING:
1820  type = "string";
1821  break;
1822  default:
1823  type = "string";
1824  break;
1825  }
1826 
1827  fprintf(fp, "#%%Option\n");
1828  fprintf(fp, "#%% key: %s\n", opt->key);
1829  fprintf(fp, "#%% type: %s\n", type);
1830  fprintf(fp, "#%% required: %s\n", opt->required ? "yes" : "no");
1831  fprintf(fp, "#%% multiple: %s\n", opt->multiple ? "yes" : "no");
1832  if (opt->options)
1833  fprintf(fp, "#%% options: %s\n", opt->options);
1834  if (opt->key_desc)
1835  fprintf(fp, "#%% key_desc: %s\n", opt->key_desc);
1836  if (opt->label)
1837  fprintf(fp, "#%% label: %s\n", opt->label);
1838  if (opt->description)
1839  fprintf(fp, "#%% description: %s\n", opt->description);
1840  if (opt->descriptions)
1841  fprintf(fp, "#%% descriptions: %s\n", opt->descriptions);
1842  if (opt->answer)
1843  fprintf(fp, "#%% answer: %s\n", opt->answer);
1844  if (opt->gisprompt)
1845  fprintf(fp, "#%% gisprompt: %s\n", opt->gisprompt);
1846  if (opt->guisection)
1847  fprintf(fp, "#%% guisection: %s\n", opt->guisection);
1848  fprintf(fp, "#%%End\n");
1849  }
1850  }
1851 
1852  fprintf(fp,
1853  "\nif [ -z \"$GISBASE\" ] ; then\n"
1854  " echo \"You must be in GRASS GIS to run this program.\" 1>&2\n"
1855  " exit 1\n"
1856  "fi\n"
1857  "\n"
1858  "if [ \"$1\" != \"@ARGS_PARSED@\" ] ; then\n"
1859  " exec g.parser \"$0\" \"$@\"\n"
1860  "fi\n" "\n" "# CODE GOES HERE\n" "\n");
1861 }
1862 
1868 static void generate_tcl(FILE * fp)
1869 {
1870  int new_prompt = uses_new_gisprompt();
1871  const char *type;
1872  int optn;
1873 
1874  fprintf(fp, "begin_dialog {%s} {\n", pgm_name);
1875  fprintf(fp, " label {%s}\n", module_info.label ? module_info.label : "");
1876  fprintf(fp, " desc {%s}\n",
1877  module_info.description ? module_info.description : "");
1878  fprintf(fp, " key {%s}\n",
1879  module_info.keywords ? module_info.keywords : "");
1880  fprintf(fp, "}\n");
1881 
1882  optn = 1;
1883 
1884  if (n_flags) {
1885  struct Flag *flag;
1886 
1887  for (flag = &first_flag; flag; flag = flag->next_flag, optn++) {
1888  fprintf(fp, "add_flag %d {\n", optn);
1889  fprintf(fp, " name {%c}\n", flag->key);
1890  fprintf(fp, " desc {%s}\n", flag->description);
1891  fprintf(fp, " answer %d\n", flag->answer);
1892  /* It should be up to the gui as to what
1893  to do with the label and description */
1894  fprintf(fp, " label {%s}\n", flag->label ? flag->label : "");
1895  fprintf(fp, " guisection {%s}\n",
1896  flag->guisection ? flag->guisection : "");
1897  fprintf(fp, "}\n");
1898  }
1899  }
1900 
1901  if (n_opts) {
1902  struct Option *opt;
1903 
1904  for (opt = &first_option; opt; opt = opt->next_opt, optn++) {
1905  if (opt->key_desc != NULL)
1906  type = opt->key_desc;
1907  else
1908  switch (opt->type) {
1909  case TYPE_INTEGER:
1910  type = "integer";
1911  break;
1912  case TYPE_DOUBLE:
1913  type = "float";
1914  break;
1915  case TYPE_STRING:
1916  type = "string";
1917  break;
1918  default:
1919  type = "string";
1920  break;
1921  }
1922 
1923  fprintf(fp, "add_option %d {\n", optn);
1924  fprintf(fp, " name {%s}\n", opt->key);
1925  fprintf(fp, " type {%s}\n", type);
1926  fprintf(fp, " multi %d\n", opt->multiple);
1927  fprintf(fp, " desc {%s}\n", opt->description);
1928  fprintf(fp, " required %d\n", opt->required);
1929  fprintf(fp, " options {%s}\n", opt->options ? opt->options : "");
1930  fprintf(fp, " descs {%s}\n",
1931  opt->descriptions ? opt->descriptions : "");
1932  fprintf(fp, " answer {%s}\n", opt->answer ? opt->answer : "");
1933  fprintf(fp, " prompt {%s}\n",
1934  opt->gisprompt ? opt->gisprompt : "");
1935  /* It should be up to the gui as to what
1936  to do with the label and description */
1937  fprintf(fp, " label {%s}\n", opt->label ? opt->label : "");
1938  fprintf(fp, " guisection {%s}\n",
1939  opt->guisection ? opt->guisection : "");
1940  fprintf(fp, "}\n");
1941  }
1942  }
1943 
1944  if (new_prompt) {
1945  fprintf(fp, "add_xflag %d {\n", optn);
1946  fprintf(fp, " name {overwrite}\n");
1947  fprintf(fp, " desc {%s}\n",
1948  _("Allow output files to overwrite existing files"));
1949  fprintf(fp, " answer %d\n", overwrite);
1950  fprintf(fp, " label {%s}\n", _("Allow overwrite"));
1951  fprintf(fp, " guisection {}\n");
1952  fprintf(fp, "}\n");
1953  optn++;
1954  }
1955 
1956  fprintf(fp, "add_xflag %d {\n", optn);
1957  fprintf(fp, " name {quiet}\n");
1958  fprintf(fp, " desc {%s}\n", _("Run with minimal output messages"));
1959  fprintf(fp, " answer %d\n", quiet);
1960  fprintf(fp, " label {%s}\n", _("Run quietly"));
1961  fprintf(fp, " guisection {}\n");
1962  fprintf(fp, "}\n");
1963  optn++;
1964 
1965  fprintf(fp, "end_dialog %d\n", optn - 1);
1966 }
1967 
1971 static void G_gui_tcltk(void)
1972 {
1973  FILE *fp;
1974 
1975  if (!pgm_name)
1976  pgm_name = G_program_name();
1977  if (!pgm_name)
1978  pgm_name = "??";
1979 
1980 #ifdef __MINGW32__
1981  if (getenv("GRASS_DEBUG_GUI"))
1982  fp = popen("tee gui_dump.tcl | \"%GRASS_WISH%\"", "w");
1983  else
1984  fp = popen("\"%GRASS_WISH%\"", "w");
1985 #else
1986  if (getenv("GRASS_DEBUG_GUI"))
1987  fp = popen("tee gui_dump.tcl | \"$GRASS_WISH\"", "w");
1988  else
1989  fp = popen("\"$GRASS_WISH\"", "w");
1990 #endif
1991 
1992  if (!fp)
1993  G_fatal_error(_("Unable to spawn the 'wish' program"));
1994 
1995  fprintf(fp, "source $env(GISBASE)/etc/gui.tcl\n");
1996 
1997  generate_tcl(fp);
1998 
1999  pclose(fp);
2000 }
2001 
2005 static void G_gui_wx(void)
2006 {
2007  char script[GPATH_MAX];
2008 
2009  if (!pgm_name)
2010  pgm_name = G_program_name();
2011  if (!pgm_name)
2012  G_fatal_error(_("Unable to determine program name"));
2013 
2014  sprintf(script, "%s/etc/wxpython/gui_modules/menuform.py",
2015  getenv("GISBASE"));
2016  G_spawn(getenv("GRASS_PYTHON"), getenv("GRASS_PYTHON"), script, G_recreate_command(), NULL);
2017 }
2018 
2026 static void G_gui(void)
2027 {
2028  /* read environment variables first then internal GRASS variable */
2029  char *gui = getenv("GRASS_GUI");
2030 
2031  if (!gui) {
2032  gui = G_getenv("GRASS_GUI");
2033  }
2034 
2035  if (gui && (strcmp(gui, "tcltk") == 0 || strcmp(gui, "oldtcltk") == 0))
2036  G_gui_tcltk();
2037  else
2038  G_gui_wx();
2039 
2040  return;
2041 }
2042 
2046 static void G_tcltk(void)
2047 {
2048  if (!pgm_name)
2049  pgm_name = G_program_name();
2050  if (!pgm_name)
2051  pgm_name = "??";
2052 
2053  generate_tcl(stdout);
2054 }
2055 
2056 /**************************************************************************
2057  *
2058  * The remaining routines are all local (static) routines used to support
2059  * the parsing process.
2060  *
2061  **************************************************************************/
2062 
2063 static int show_options(int maxlen, const char *str)
2064 {
2065  char *buff = G_store(str);
2066  char *p1, *p2;
2067  int totlen, len;
2068 
2069  fprintf(stderr, _(" %*s options: "), maxlen, " ");
2070  totlen = maxlen + 13;
2071  p1 = buff;
2072  while ((p2 = G_index(p1, ','))) {
2073  *p2 = '\0';
2074  len = strlen(p1) + 1;
2075  if ((len + totlen) > 76) {
2076  totlen = maxlen + 13;
2077  fprintf(stderr, "\n %*s", maxlen + 13, " ");
2078  }
2079  fprintf(stderr, "%s,", p1);
2080  totlen += len;
2081  p1 = p2 + 1;
2082  }
2083  len = strlen(p1);
2084  if ((len + totlen) > 76)
2085  fprintf(stderr, "\n %*s", maxlen + 13, " ");
2086  fprintf(stderr, "%s\n", p1);
2087 
2088  G_free(buff);
2089 
2090  return 0;
2091 }
2092 
2093 static int show(const char *item, int len)
2094 {
2095  int n;
2096 
2097  n = strlen(item) + (len > 0);
2098  if (n + len > 76) {
2099  if (len)
2100  fprintf(stderr, "\n ");
2101  len = 0;
2102  }
2103  fprintf(stderr, "%s", item);
2104  return n + len;
2105 }
2106 
2107 static int set_flag(int f)
2108 {
2109  struct Flag *flag;
2110 
2111  /* Flag is not valid if there are no flags to set */
2112 
2113  if (!n_flags) {
2114  fprintf(stderr, _("Sorry, <%c> is not a valid flag\n"), f);
2115  return (1);
2116  }
2117 
2118  /* Find flag with corrrect keyword */
2119 
2120  flag = &first_flag;
2121  while (flag != NULL) {
2122  if (flag->key == f) {
2123  flag->answer = 1;
2124  return (0);
2125  }
2126  flag = flag->next_flag;
2127  }
2128 
2129  fprintf(stderr, _("Sorry, <%c> is not a valid flag\n"), f);
2130  return (1);
2131 }
2132 
2133 /* contents() is used to find things strings with characters like commas and
2134  * dashes.
2135  */
2136 static int contains(const char *s, int c)
2137 {
2138  while (*s) {
2139  if (*s == c)
2140  return (1);
2141  s++;
2142  }
2143  return (0);
2144 }
2145 
2146 static int is_option(const char *string)
2147 {
2148  const char *p = strchr(string, '=');
2149 
2150  if (!p)
2151  return 0;
2152  if (p == string)
2153  return 0;
2154  p--;
2155  if (!strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", *p))
2156  return 0;
2157 
2158  return 1;
2159 }
2160 
2161 static int set_option(char *string)
2162 {
2163  struct Option *at_opt = NULL;
2164  struct Option *opt = NULL;
2165  int got_one;
2166  size_t key_len;
2167  char the_key[KEYLENGTH];
2168  char *ptr;
2169 
2170  for (ptr = the_key; *string != '='; ptr++, string++)
2171  *ptr = *string;
2172  *ptr = '\0';
2173  string++;
2174 
2175  /* Find option with best keyword match */
2176  got_one = 0;
2177  key_len = strlen(the_key);
2178  for (at_opt = &first_option; at_opt != NULL; at_opt = at_opt->next_opt) {
2179  if (at_opt->key == NULL || strncmp(the_key, at_opt->key, key_len))
2180  continue;
2181 
2182  got_one++;
2183  opt = at_opt;
2184 
2185  /* changed 1/15/91 -dpg old code is in parser.old */
2186  /* overide ambiguous check, if we get an exact match */
2187  if (strlen(at_opt->key) == key_len) {
2188  opt = at_opt;
2189  got_one = 1;
2190  break;
2191  }
2192  }
2193 
2194  if (got_one > 1) {
2195  fprintf(stderr, _("Sorry, <%s=> is ambiguous\n"), the_key);
2196  return (1);
2197  }
2198 
2199  /* If there is no match, complain */
2200  if (got_one == 0) {
2201  fprintf(stderr, _("Sorry, <%s> is not a valid parameter\n"), the_key);
2202  return (1);
2203  }
2204 
2205  /* Allocate memory where answer is stored */
2206  if (opt->count++) {
2207  if (!opt->multiple) {
2208  fprintf(stderr, _("Option <%s> does not accept multiple answers\n"), the_key);
2209  return (1);
2210  }
2211  opt->answer = (char *)G_realloc(opt->answer,
2212  strlen(opt->answer) + strlen(string) +
2213  2);
2214  strcat(opt->answer, ",");
2215  strcat(opt->answer, string);
2216  }
2217  else
2218  opt->answer = G_store(string);
2219  return (0);
2220 }
2221 
2222 static int check_opts(void)
2223 {
2224  struct Option *opt;
2225  int error;
2226  int ans;
2227 
2228  error = 0;
2229 
2230  if (!n_opts)
2231  return (0);
2232 
2233  opt = &first_option;
2234  while (opt != NULL) {
2235  /* Check answer against options if any */
2236 
2237  if (opt->options && opt->answer) {
2238  if (opt->multiple == 0)
2239  error += check_an_opt(opt->key, opt->type,
2240  opt->options, opt->answer);
2241  else {
2242  for (ans = 0; opt->answers[ans] != '\0'; ans++)
2243  error += check_an_opt(opt->key, opt->type,
2244  opt->options, opt->answers[ans]);
2245  }
2246  }
2247 
2248  /* Check answer against user's check subroutine if any */
2249 
2250  if (opt->checker)
2251  error += opt->checker(opt->answer);
2252 
2253  opt = opt->next_opt;
2254  }
2255  return (error);
2256 }
2257 
2258 static int check_an_opt(const char *key, int type, const char *options,
2259  const char *answer)
2260 {
2261  int error;
2262 
2263  error = 0;
2264 
2265  switch (type) {
2266  case TYPE_INTEGER:
2267  error = check_int(answer, options);
2268  break;
2269  case TYPE_DOUBLE:
2270  error = check_double(answer, options);
2271  break;
2272  case TYPE_STRING:
2273  error = check_string(answer, options);
2274  break;
2275  /*
2276  case TYPE_COORDINATE:
2277  error = check_coor(answer,options) ;
2278  break ;
2279  */
2280  }
2281  switch (error) {
2282  case 0:
2283  break;
2284  case BAD_SYNTAX:
2285  fprintf(stderr,
2286  _("\nERROR: illegal range syntax for parameter <%s>\n"), key);
2287  fprintf(stderr, _(" Presented as: %s\n"), options);
2288  break;
2289  case OUT_OF_RANGE:
2290  fprintf(stderr,
2291  _("\nERROR: value <%s> out of range for parameter <%s>\n"),
2292  answer, key);
2293  fprintf(stderr, _(" Legal range: %s\n"), options);
2294  break;
2295  case MISSING_VALUE:
2296  fprintf(stderr, _("\nERROR: Missing value for parameter <%s>\n"),
2297  key);
2298  }
2299  return (error);
2300 }
2301 
2302 static int check_int(const char *ans, const char *opts)
2303 {
2304  int d, lo, hi;
2305 
2306  if (1 != sscanf(ans, "%d", &d))
2307  return (MISSING_VALUE);
2308 
2309  if (contains(opts, '-')) {
2310  if (2 != sscanf(opts, "%d-%d", &lo, &hi))
2311  return (BAD_SYNTAX);
2312  if (d < lo || d > hi)
2313  return (OUT_OF_RANGE);
2314  else
2315  return (0);
2316  }
2317  else if (contains(opts, ',')) {
2318  for (;;) {
2319  if (1 != sscanf(opts, "%d", &lo))
2320  return (BAD_SYNTAX);
2321  if (d == lo)
2322  return (0);
2323  while (*opts != '\0' && *opts != ',')
2324  opts++;
2325  if (*opts == '\0')
2326  return (OUT_OF_RANGE);
2327  if (*(++opts) == '\0')
2328  return (OUT_OF_RANGE);
2329  }
2330  }
2331  else {
2332  if (1 != sscanf(opts, "%d", &lo))
2333  return (BAD_SYNTAX);
2334  if (d == lo)
2335  return (0);
2336  return (OUT_OF_RANGE);
2337  }
2338 }
2339 
2340 /*
2341  static int
2342  check_coor(ans, opts)
2343  char *ans ;
2344  char *opts ;
2345  {
2346  double xd, xlo, xhi;
2347  double yd, ylo, yhi;
2348 
2349  if (1 != sscanf(ans,"%lf,%lf", &xd, &yd))
2350  return(MISSING_VALUE) ;
2351 
2352  if (contains(opts, '-'))
2353  {
2354  if (2 != sscanf(opts,"%lf-%lf,%lf-%lf",&xlo, &xhi, &ylo, &yhi))
2355  return(BAD_SYNTAX) ;
2356  if (xd < xlo || xd > xhi)
2357  return(OUT_OF_RANGE) ;
2358  if (yd < ylo || yd > yhi)
2359  return(OUT_OF_RANGE) ;
2360  return(0) ;
2361  }
2362  return(BAD_SYNTAX) ;
2363  }
2364  */
2365 
2366 static int check_double(const char *ans, const char *opts)
2367 {
2368  double d, lo, hi;
2369 
2370  if (1 != sscanf(ans, "%lf", &d))
2371  return (MISSING_VALUE);
2372 
2373  if (contains(opts, '-')) {
2374  if (2 != sscanf(opts, "%lf-%lf", &lo, &hi))
2375  return (BAD_SYNTAX);
2376  if (d < lo || d > hi)
2377  return (OUT_OF_RANGE);
2378  else
2379  return (0);
2380  }
2381  else if (contains(opts, ',')) {
2382  for (;;) {
2383  if (1 != sscanf(opts, "%lf", &lo))
2384  return (BAD_SYNTAX);
2385  if (d == lo)
2386  return (0);
2387  while (*opts != '\0' && *opts != ',')
2388  opts++;
2389  if (*opts == '\0')
2390  return (OUT_OF_RANGE);
2391  if (*(++opts) == '\0')
2392  return (OUT_OF_RANGE);
2393  }
2394  }
2395  else {
2396  if (1 != sscanf(opts, "%lf", &lo))
2397  return (BAD_SYNTAX);
2398  if (d == lo)
2399  return (0);
2400  return (OUT_OF_RANGE);
2401  }
2402 }
2403 
2404 static int check_string(const char *ans, const char *opts)
2405 {
2406  if (*opts == '\0')
2407  return (0);
2408 
2409  if (contains(opts, ',')) {
2410  for (;;) {
2411  if ((!strncmp(ans, opts, strlen(ans)))
2412  && (*(opts + strlen(ans)) == ','
2413  || *(opts + strlen(ans)) == '\0'))
2414  return (0);
2415  while (*opts != '\0' && *opts != ',')
2416  opts++;
2417  if (*opts == '\0')
2418  return (OUT_OF_RANGE);
2419  if (*(++opts) == '\0')
2420  return (OUT_OF_RANGE);
2421  }
2422  }
2423  else {
2424  if (!strcmp(ans, opts))
2425  return (0);
2426  return (OUT_OF_RANGE);
2427  }
2428 }
2429 
2430 static int check_required(void)
2431 {
2432  struct Option *opt;
2433  int err;
2434 
2435  err = 0;
2436 
2437  if (!n_opts)
2438  return (0);
2439 
2440  opt = &first_option;
2441  while (opt != NULL) {
2442  if (opt->required && opt->answer == NULL) {
2443  fprintf(stderr,
2444  _("ERROR: Required parameter <%s> not set:\n\t(%s)\n"),
2445  opt->key, (opt->label ? opt->label : opt->description) );
2446  err++;
2447  }
2448  opt = opt->next_opt;
2449  }
2450 
2451  return (err);
2452 }
2453 
2454 static int split_opts(void)
2455 {
2456  struct Option *opt;
2457  char *ptr1;
2458  char *ptr2;
2459  int allocated;
2460  int ans_num;
2461  int len;
2462 
2463 
2464  if (!n_opts)
2465  return 0;
2466 
2467  opt = &first_option;
2468  while (opt != NULL) {
2469  if ( /*opt->multiple && */ (opt->answer != NULL)) {
2470  /* Allocate some memory to store array of pointers */
2471  allocated = 10;
2472  opt->answers = (char **)G_malloc(allocated * sizeof(char *));
2473 
2474  ans_num = 0;
2475  ptr1 = opt->answer;
2476  opt->answers[ans_num] = NULL;
2477 
2478  for (;;) {
2479  for (len = 0, ptr2 = ptr1; *ptr2 != '\0' && *ptr2 != ',';
2480  ptr2++, len++) ;
2481 
2482  if (len > 0) { /* skip ,, */
2483  opt->answers[ans_num] = (char *)G_malloc(len + 1);
2484  G_copy(opt->answers[ans_num], ptr1, len);
2485  opt->answers[ans_num][len] = 0;
2486 
2487  ans_num++;
2488 
2489  if (ans_num >= allocated) {
2490  allocated += 10;
2491  opt->answers =
2492  (char **)G_realloc((char *)opt->answers,
2493  allocated * sizeof(char *));
2494  }
2495 
2496  opt->answers[ans_num] = NULL;
2497  }
2498 
2499  if (*ptr2 == '\0')
2500  break;
2501 
2502  ptr1 = ptr2 + 1;
2503 
2504  if (*ptr1 == '\0')
2505  break;
2506  }
2507  }
2508  opt = opt->next_opt;
2509  }
2510 
2511  return 0;
2512 }
2513 
2514 static int check_multiple_opts(void)
2515 {
2516  struct Option *opt;
2517  const char *ptr;
2518  int n_commas;
2519  int n;
2520  int error;
2521 
2522  if (!n_opts)
2523  return (0);
2524 
2525  error = 0;
2526  opt = &first_option;
2527  while (opt != NULL) {
2528  if ((opt->answer != NULL) && (opt->key_desc != NULL)) {
2529  /* count commas */
2530  n_commas = 1;
2531  for (ptr = opt->key_desc; *ptr != '\0'; ptr++)
2532  if (*ptr == ',')
2533  n_commas++;
2534  /* count items */
2535  for (n = 0; opt->answers[n] != '\0'; n++) ;
2536  /* if not correct multiple of items */
2537  if (n % n_commas) {
2538  fprintf(stderr,
2539  _("\nERROR: option <%s> must be provided in multiples of %d\n"),
2540  opt->key, n_commas);
2541  fprintf(stderr, _(" You provided %d items:\n"), n);
2542  fprintf(stderr, " %s\n", opt->answer);
2543  error++;
2544  }
2545  }
2546  opt = opt->next_opt;
2547  }
2548  return (error);
2549 }
2550 
2551 /* Check for all 'new' if element already exists */
2552 static int check_overwrite(void)
2553 {
2554  struct Option *opt;
2555  char age[KEYLENGTH];
2556  char element[KEYLENGTH];
2557  char desc[KEYLENGTH];
2558  int error = 0;
2559  char *overstr;
2560  int over;
2561 
2562  if (!n_opts)
2563  return (0);
2564 
2565  over = 0;
2566  /* Check the GRASS OVERWRITE variable */
2567  if ((overstr = G__getenv("OVERWRITE"))) {
2568  over = atoi(overstr);
2569  }
2570 
2571  /* Check the GRASS_OVERWRITE environment variable */
2572  if ((overstr = getenv("GRASS_OVERWRITE"))) {
2573  if (atoi(overstr))
2574  over = 1;
2575  }
2576 
2577  if (overwrite || over) {
2578  module_info.overwrite = 1;
2579  /* Set the environment so that programs run in a script also obey --o */
2580  putenv("GRASS_OVERWRITE=1");
2581  /* No need to check options for existing files if overwrite is true */
2582  return error;
2583  }
2584 
2585  opt = &first_option;
2586  while (opt != NULL) {
2587  if ((opt->answer != NULL) && (opt->gisprompt != NULL)) {
2588  split_gisprompt(opt->gisprompt, age, element, desc);
2589 
2590  if (strcmp(age, "new") == 0) {
2591  int i;
2592  for (i = 0; opt->answers[i]; i++) {
2593  if (G_find_file(element, opt->answers[i], G_mapset())) { /* found */
2594  if (!overwrite && !over) {
2595  if (G_info_format() != G_INFO_FORMAT_GUI) {
2596  fprintf(stderr,
2597  _("ERROR: option <%s>: <%s> exists.\n"),
2598  opt->key, opt->answers[i]);
2599  }
2600  else {
2601  fprintf(stderr,
2602  "GRASS_INFO_ERROR(%d,1): option <%s>: <%s> exists.\n",
2603  getpid(), opt->key, opt->answers[i]);
2604  fprintf(stderr, "GRASS_INFO_END(%d,1)\n",
2605  getpid());
2606  }
2607 
2608  error = 1;
2609  }
2610  }
2611  }
2612  }
2613  }
2614  opt = opt->next_opt;
2615  }
2616 
2617  return (error);
2618 }
2619 
2620 static int interactive(const char *command)
2621 {
2622  struct Item *item;
2623 
2624  /* Query for flags */
2625 
2626  if (!n_items) {
2627  fprintf(stderr, "PROGRAMMER ERROR: no flags or options\n");
2628  exit(EXIT_FAILURE);
2629  }
2630 
2631  for (item = &first_item;;) {
2632  if (item->flag)
2633  interactive_flag(item->flag);
2634  else if (item->option)
2635  interactive_option(item->option);
2636  else
2637  break;
2638 
2639  item = item->next_item;
2640 
2641  if (item == NULL)
2642  break;
2643  }
2644 
2645  return 0;
2646 }
2647 
2648 static int interactive_flag(struct Flag *flag)
2649 {
2650  char buff[1024];
2651 
2652  fprintf(stderr, _("\nFLAG: Set the following flag?\n"));
2653  sprintf(buff, " %s?", flag->description);
2654  flag->answer = G_yes(buff, 0);
2655 
2656  return 0;
2657 }
2658 
2659 static int interactive_option(struct Option *opt)
2660 {
2661  char buff[1024], *bptr;
2662  char buff2[1024];
2663  int set_one;
2664  int no_prompt;
2665 
2666  fprintf(stderr, _("\nOPTION: %s\n"), opt->description);
2667  fprintf(stderr, _(" key: %s\n"), opt->key);
2668  if (opt->key_desc)
2669  fprintf(stderr, _(" format: %s\n"), opt->key_desc);
2670  if (opt->def)
2671  fprintf(stderr, _(" default: %s\n"), opt->def);
2672  fprintf(stderr, _("required: %s\n"), opt->required ? "YES" : "NO");
2673  if (opt->multiple)
2674  fprintf(stderr, _("multiple: %s\n"), opt->multiple ? "YES" : "NO");
2675  if (opt->options)
2676  fprintf(stderr, _(" options: %s\n"), opt->options);
2677  /*
2678  show_options(0, opt->options) ;
2679  */
2680 
2681  set_one = 0;
2682  for (;;) {
2683  *buff = '\0';
2684  if (opt->gisprompt)
2685  no_prompt = gis_prompt(opt, buff);
2686  else
2687  no_prompt = -1;
2688  if (no_prompt) {
2689  fprintf(stderr, _("enter option > "));
2690  if (fgets(buff, 1024, stdin) == 0)
2691  exit(EXIT_SUCCESS);;
2692  bptr = buff; /* strip newline */
2693  while (*bptr) {
2694  if (*bptr == '\n')
2695  *bptr = '\0';
2696  bptr++;
2697  }
2698 
2699  }
2700 
2701  if (strlen(buff) != 0) {
2702  if (opt->options)
2703  /* then check option */
2704  {
2705  if (check_an_opt(opt->key, opt->type, opt->options, buff)) {
2706  if (G_yes(_(" Try again? "), 1))
2707  continue;
2708  else
2709  exit(EXIT_FAILURE);
2710  }
2711  }
2712  if (opt->checker)
2713  if (opt->checker(buff)) {
2714  fprintf(stderr, _("Sorry, %s is not accepted.\n"), buff);
2715  *buff = '\0';
2716  if (G_yes(_(" Try again? "), 1))
2717  continue;
2718  else
2719  exit(EXIT_FAILURE);
2720  }
2721 
2722  sprintf(buff2, "%s=%s", opt->key, buff);
2723  if (!opt->gisprompt) {
2724  fprintf(stderr, _("\nYou have chosen:\n %s\n"), buff2);
2725  if (G_yes(_("Is this correct? "), 1)) {
2726  set_option(buff2);
2727  set_one++;
2728  }
2729  }
2730  else {
2731  set_option(buff2);
2732  set_one++;
2733  }
2734  } /* if strlen(buf ) !=0 */
2735 
2736  if ((strlen(buff) == 0) && opt->required && (set_one == 0))
2737  exit(EXIT_FAILURE);
2738  if ((strlen(buff) == 0) && (set_one > 0) && opt->multiple)
2739  break;
2740  if ((strlen(buff) == 0) && !opt->required)
2741  break;
2742  if ((set_one == 1) && !opt->multiple)
2743  break;
2744  }
2745  return (0);
2746 }
2747 
2748 static int split_gisprompt(const char *gisprompt, char *age, char *element,
2749  char *desc)
2750 {
2751  const char *ptr1;
2752  char *ptr2;
2753 
2754  for (ptr1 = gisprompt, ptr2 = age; *ptr1 != '\0'; ptr1++, ptr2++) {
2755  if (*ptr1 == ',')
2756  break;
2757  *ptr2 = *ptr1;
2758  }
2759  *ptr2 = '\0';
2760 
2761  for (ptr1++, ptr2 = element; *ptr1 != '\0'; ptr1++, ptr2++) {
2762  if (*ptr1 == ',')
2763  break;
2764  *ptr2 = *ptr1;
2765  }
2766  *ptr2 = '\0';
2767 
2768  for (ptr1++, ptr2 = desc; *ptr1 != '\0'; ptr1++, ptr2++) {
2769  if (*ptr1 == ',')
2770  break;
2771  *ptr2 = *ptr1;
2772  }
2773  *ptr2 = '\0';
2774 
2775  return 0;
2776 }
2777 
2778 static int gis_prompt(struct Option *opt, char *buff)
2779 {
2780  char age[KEYLENGTH];
2781  char element[KEYLENGTH];
2782  char desc[KEYLENGTH];
2783  char *ptr1;
2784 
2785  split_gisprompt(opt->gisprompt, age, element, desc);
2786 
2787  /*********ptr1 points to current mapset description***********/
2788 
2789  if (opt->answer)
2790  G_set_ask_return_msg(_("to accept the default"));
2791  if (!strcmp("old", age)) {
2792  ptr1 = G_ask_old("", buff, element, desc);
2793  if (ptr1) {
2794  strcpy(buff, G_fully_qualified_name(buff, ptr1));
2795  }
2796  }
2797  else if (!strcmp("new", age))
2798  ptr1 = G_ask_new("", buff, element, desc);
2799  else if (!strcmp("mapset", age))
2800  ptr1 = G_ask_in_mapset("", buff, element, desc);
2801  else if (!strcmp("any", age))
2802  ptr1 = G_ask_any("", buff, element, desc, 1);
2803  else if (!strcmp("old_file", age)) /* file must exist */
2804  ptr1 = G_ask_old_file("", buff, element, desc);
2805  else if (!strcmp("new_file", age)) /* file shouldn't exist unless overwrite is enabled */
2806  ptr1 = G_ask_new_file("", buff, element, desc);
2807  else {
2808  return -1;
2809  }
2810 
2811  if (ptr1 == '\0')
2812  *buff = '\0';
2813 
2814  return 0;
2815 }
2816 
2826 {
2827  static char *buff;
2828  char flg[4];
2829  char *cur;
2830  const char *tmp;
2831  struct Flag *flag;
2832  struct Option *opt;
2833  int n, len, slen;
2834  int nalloced = 0;
2835 
2836  G_debug(3, "G_recreate_command()");
2837 
2838  /* Flag is not valid if there are no flags to set */
2839 
2840  buff = G_calloc(1024, sizeof(char));
2841  nalloced += 1024;
2842  tmp = G_program_name();
2843  len = strlen(tmp);
2844  if (len >= nalloced) {
2845  nalloced += (1024 > len) ? 1024 : len + 1;
2846  buff = G_realloc(buff, nalloced);
2847  }
2848  cur = buff;
2849  strcpy(cur, tmp);
2850  cur += len;
2851 
2852  if (n_flags) {
2853  flag = &first_flag;
2854  while (flag != '\0') {
2855  if (flag->answer == 1) {
2856  flg[0] = ' ';
2857  flg[1] = '-';
2858  flg[2] = flag->key;
2859  flg[3] = '\0';
2860  slen = strlen(flg);
2861  if (len + slen >= nalloced) {
2862  nalloced +=
2863  (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
2864  buff = G_realloc(buff, nalloced);
2865  cur = buff + len;
2866  }
2867  strcpy(cur, flg);
2868  cur += slen;
2869  len += slen;
2870  }
2871  flag = flag->next_flag;
2872  }
2873  }
2874 
2875  opt = &first_option;
2876  while (opt != '\0') {
2877  if (opt->answer != '\0' && opt->answers && opt->answers[0] != NULL) {
2878  slen = strlen(opt->key) + strlen(opt->answers[0]) + 4; /* +4 for: ' ' = " " */
2879  if (len + slen >= nalloced) {
2880  nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
2881  buff = G_realloc(buff, nalloced);
2882  cur = buff + len;
2883  }
2884  strcpy(cur, " ");
2885  cur++;
2886  strcpy(cur, opt->key);
2887  cur = strchr(cur, '\0');
2888  strcpy(cur, "=");
2889  cur++;
2890  if (opt->type == TYPE_STRING) {
2891  strcpy(cur, "\"");
2892  cur++;
2893  }
2894  strcpy(cur, opt->answers[0]);
2895  cur = strchr(cur, '\0');
2896  len = cur - buff;
2897  for (n = 1; opt->answers[n] != NULL && opt->answers[n] != '\0';
2898  n++) {
2899  if (opt->answers[n] == NULL)
2900  break;
2901  slen = strlen(opt->answers[n]) + 2; /* +2 for , " */
2902  if (len + slen >= nalloced) {
2903  nalloced +=
2904  (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
2905  buff = G_realloc(buff, nalloced);
2906  cur = buff + len;
2907  }
2908  strcpy(cur, ",");
2909  cur++;
2910  strcpy(cur, opt->answers[n]);
2911  cur = strchr(cur, '\0');
2912  len = cur - buff;
2913  }
2914  if (opt->type == TYPE_STRING) {
2915  strcpy(cur, "\"");
2916  cur++;
2917  len = cur - buff;
2918  }
2919  }
2920  opt = opt->next_opt;
2921  }
2922 
2923  return (buff);
2924 }