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