00001
00069 #include <grass/config.h>
00070
00071 #if defined(HAVE_LANGINFO_H)
00072 #include <langinfo.h>
00073 #endif
00074 #if defined(__MINGW32__) && defined(USE_NLS)
00075 #include <localcharset.h>
00076 #endif
00077
00078 #include <stdio.h>
00079 #include <stdlib.h>
00080 #include <string.h>
00081 #include <ctype.h>
00082 #include <unistd.h>
00083 #include <stdarg.h>
00084 #include <sys/types.h>
00085 #include <grass/gis.h>
00086 #include <grass/glocale.h>
00087 #include <grass/spawn.h>
00088
00089
00090 #define BAD_SYNTAX 1
00091 #define OUT_OF_RANGE 2
00092 #define MISSING_VALUE 3
00093 #define KEYLENGTH 64
00094
00095 static int interactive_ok = 1;
00096 static int n_opts = 0;
00097 static int n_flags = 0;
00098 static int overwrite = 0;
00099 static int quiet = 0;
00100
00101 static struct Flag first_flag;
00102 static struct Flag *current_flag;
00103
00104 static struct Option first_option;
00105 static struct Option *current_option;
00106
00107 static struct GModule module_info;
00108
00109 static const char *pgm_name = NULL;
00110
00111 struct Item
00112 {
00113 struct Option *option;
00114 struct Flag *flag;
00115 struct Item *next_item;
00116 };
00117
00118 static struct Item first_item;
00119 static struct Item *current_item;
00120 static int n_items = 0;
00121 static int show_options(int, const char *);
00122 static int show(const char *, int);
00123 static int set_flag(int);
00124 static int contains(const char *, int);
00125 static int is_option(const char *);
00126 static int set_option(char *);
00127 static int check_opts();
00128 static int check_an_opt(const char *, int, const char *, const char *);
00129 static int check_int(const char *, const char *);
00130 static int check_double(const char *, const char *);
00131 static int check_string(const char *, const char *);
00132 static int check_required(void);
00133 static int split_opts(void);
00134 static int check_multiple_opts(void);
00135 static int check_overwrite(void);
00136 static int interactive(const char *);
00137 static int interactive_flag(struct Flag *);
00138 static int interactive_option(struct Option *);
00139 static int gis_prompt(struct Option *, char *);
00140 static int split_gisprompt(const char *, char *, char *, char *);
00141
00142 static void G_gui(void);
00143 static void G_tcltk(void);
00144 static void G_usage_xml(void);
00145 static void G_usage_html(void);
00146 static void G_script(void);
00147
00148
00161 int G_disable_interactive(void)
00162 {
00163 interactive_ok = 0;
00164
00165 return 0;
00166 }
00167
00168
00182 struct Flag *G_define_flag(void)
00183 {
00184 struct Flag *flag;
00185 struct Item *item;
00186
00187
00188
00189 if (n_flags) {
00190 flag = (struct Flag *)G_malloc(sizeof(struct Flag));
00191 current_flag->next_flag = flag;
00192 }
00193 else
00194 flag = &first_flag;
00195
00196
00197
00198 G_zero((char *)flag, sizeof(struct Flag));
00199
00200 current_flag = flag;
00201 n_flags++;
00202
00203 if (n_items) {
00204 item = (struct Item *)G_malloc(sizeof(struct Item));
00205 current_item->next_item = item;
00206 }
00207 else
00208 item = &first_item;
00209
00210 G_zero((char *)item, sizeof(struct Item));
00211
00212 item->flag = flag;
00213 item->option = NULL;
00214
00215 current_item = item;
00216 n_items++;
00217
00218 return (flag);
00219 }
00220
00221
00238 struct Option *G_define_option(void)
00239 {
00240 struct Option *opt;
00241 struct Item *item;
00242
00243
00244
00245 if (n_opts) {
00246 opt = (struct Option *)G_malloc(sizeof(struct Option));
00247 current_option->next_opt = opt;
00248 }
00249 else
00250 opt = &first_option;
00251
00252
00253 G_zero((char *)opt, sizeof(struct Option));
00254
00255 opt->required = NO;
00256 opt->multiple = NO;
00257 opt->answer = NULL;
00258 opt->answers = NULL;
00259 opt->def = NULL;
00260 opt->checker = NULL;
00261 opt->options = NULL;
00262 opt->key_desc = NULL;
00263 opt->gisprompt = NULL;
00264 opt->label = NULL;
00265 opt->opts = NULL;
00266 opt->description = NULL;
00267 opt->descriptions = NULL;
00268 opt->guisection = NULL;
00269
00270 current_option = opt;
00271 n_opts++;
00272
00273 if (n_items) {
00274 item = (struct Item *)G_malloc(sizeof(struct Item));
00275 current_item->next_item = item;
00276 }
00277 else
00278 item = &first_item;
00279
00280 G_zero((char *)item, sizeof(struct Item));
00281
00282 item->option = opt;
00283 item->flag = NULL;
00284
00285 current_item = item;
00286 n_items++;
00287
00288 return (opt);
00289 }
00290
00291
00318 struct Option *G_define_standard_option(int opt)
00319 {
00320 struct Option *Opt;
00321
00322 Opt = G_define_option();
00323
00324 switch (opt) {
00325
00326 case G_OPT_WHERE:
00327 Opt->key = "where";
00328 Opt->type = TYPE_STRING;
00329 Opt->key_desc = "sql_query";
00330 Opt->required = NO;
00331 Opt->label = _("WHERE conditions of SQL statement without 'where' keyword");
00332 Opt->description = _("Example: income < 1000 and inhab >= 10000");
00333 break;
00334 case G_OPT_TABLE:
00335 Opt->key = "table";
00336 Opt->type = TYPE_STRING;
00337 Opt->key_desc = "name";
00338 Opt->required = NO;
00339 Opt->multiple = NO;
00340 Opt->description = _("Table name");
00341 Opt->gisprompt = "old_dbtable,dbtable,dbtable";
00342 break;
00343 case G_OPT_DRIVER:
00344 Opt->key = "driver";
00345 Opt->type = TYPE_STRING;
00346 Opt->key_desc = "name";
00347 Opt->required = NO;
00348 Opt->multiple = NO;
00349 Opt->description = _("Driver name");
00350 Opt->gisprompt = "old_dbdriver,dbdriver,dbdriver";
00351 break;
00352 case G_OPT_DATABASE:
00353 Opt->key = "database";
00354 Opt->type = TYPE_STRING;
00355 Opt->key_desc = "name";
00356 Opt->required = NO;
00357 Opt->multiple = NO;
00358 Opt->description = _("Database name");
00359 Opt->gisprompt = "old_dbname,dbname,dbname";
00360 break;
00361 case G_OPT_COLUMN:
00362 Opt->key = "column";
00363 Opt->type = TYPE_STRING;
00364 Opt->key_desc = "name";
00365 Opt->required = NO;
00366 Opt->multiple = NO;
00367 Opt->description = _("Name of attribute column");
00368 Opt->gisprompt = "old_dbcolumn,dbcolumn,dbcolumn";
00369 break;
00370 case G_OPT_COLUMNS:
00371 Opt->key = "columns";
00372 Opt->type = TYPE_STRING;
00373 Opt->key_desc = "name";
00374 Opt->required = NO;
00375 Opt->multiple = YES;
00376 Opt->description = _("Name of attribute column(s)");
00377 Opt->gisprompt = "old_dbcolumn,dbcolumn,dbcolumn";
00378 break;
00379
00380
00381 case G_OPT_I_GROUP:
00382 Opt->key = "group";
00383 Opt->type = TYPE_STRING;
00384 Opt->key_desc = "name";
00385 Opt->required = YES;
00386 Opt->gisprompt = "old,group,group";
00387 Opt->description = _("Name of input imagery group");
00388 break;
00389 case G_OPT_I_SUBGROUP:
00390 Opt->key = "subgroup";
00391 Opt->type = TYPE_STRING;
00392 Opt->key_desc = "name";
00393 Opt->required = YES;
00394 Opt->gisprompt = "old,subgroup,subgroup";
00395 Opt->description = _("Name of input imagery subgroup");
00396 break;
00397
00398
00399 case G_OPT_R_INPUT:
00400 Opt->key = "input";
00401 Opt->type = TYPE_STRING;
00402 Opt->key_desc = "name";
00403 Opt->required = YES;
00404 Opt->gisprompt = "old,cell,raster";
00405 Opt->description = _("Name of input raster map");
00406 break;
00407 case G_OPT_R_INPUTS:
00408 Opt->key = "input";
00409 Opt->type = TYPE_STRING;
00410 Opt->key_desc = "name";
00411 Opt->required = YES;
00412 Opt->multiple = YES;
00413 Opt->gisprompt = "old,cell,raster";
00414 Opt->description = _("Name of input raster map(s)");
00415 break;
00416 case G_OPT_R_OUTPUT:
00417 Opt->key = "output";
00418 Opt->type = TYPE_STRING;
00419 Opt->key_desc = "name";
00420 Opt->required = YES;
00421 Opt->gisprompt = "new,cell,raster";
00422 Opt->description = _("Name for output raster map");
00423 break;
00424 case G_OPT_R_MAP:
00425 Opt->key = "map";
00426 Opt->type = TYPE_STRING;
00427 Opt->key_desc = "name";
00428 Opt->required = YES;
00429 Opt->gisprompt = "old,cell,raster";
00430 Opt->description = _("Name of input raster map");
00431 break;
00432 case G_OPT_R_MAPS:
00433 Opt->key = "map";
00434 Opt->type = TYPE_STRING;
00435 Opt->key_desc = "name";
00436 Opt->required = YES;
00437 Opt->multiple = YES;
00438 Opt->gisprompt = "old,cell,raster";
00439 Opt->description = _("Name of input raster map(s)");
00440 break;
00441 case G_OPT_R_BASE:
00442 Opt->key = "base";
00443 Opt->type = TYPE_STRING;
00444 Opt->key_desc = "name";
00445 Opt->required = YES;
00446 Opt->gisprompt = "old,cell,raster";
00447 Opt->description = _("Name of base raster map");
00448 break;
00449 case G_OPT_R_COVER:
00450 Opt->key = "cover";
00451 Opt->type = TYPE_STRING;
00452 Opt->key_desc = "name";
00453 Opt->required = YES;
00454 Opt->gisprompt = "old,cell,raster";
00455 Opt->description = _("Name of cover raster map");
00456 break;
00457 case G_OPT_R_ELEV:
00458 Opt->key = "elevation";
00459 Opt->type = TYPE_STRING;
00460 Opt->key_desc = "name";
00461 Opt->required = YES;
00462 Opt->gisprompt = "old,cell,raster";
00463 Opt->description = _("Name of elevation raster map");
00464 break;
00465 case G_OPT_R_ELEVS:
00466 Opt->key = "elevation";
00467 Opt->type = TYPE_STRING;
00468 Opt->key_desc = "name";
00469 Opt->required = YES;
00470 Opt->multiple = YES;
00471 Opt->gisprompt = "old,cell,raster";
00472 Opt->description = _("Name of elevation raster map(s)");
00473 break;
00474
00475
00476 case G_OPT_R3_INPUT:
00477 Opt->key = "input";
00478 Opt->type = TYPE_STRING;
00479 Opt->key_desc = "name";
00480 Opt->required = YES;
00481 Opt->gisprompt = "old,grid3,3d-raster";
00482 Opt->description = _("Name of input raster3d map");
00483 break;
00484 case G_OPT_R3_INPUTS:
00485 Opt->key = "input";
00486 Opt->type = TYPE_STRING;
00487 Opt->key_desc = "name";
00488 Opt->required = YES;
00489 Opt->multiple = YES;
00490 Opt->gisprompt = "old,grid3,3d-raster";
00491 Opt->description = _("Name of input raster3d map(s)");
00492 break;
00493 case G_OPT_R3_OUTPUT:
00494 Opt->key = "output";
00495 Opt->type = TYPE_STRING;
00496 Opt->key_desc = "name";
00497 Opt->required = YES;
00498 Opt->gisprompt = "new,grid3,3d-raster";
00499 Opt->description = _("Name for output raster3d map");
00500 break;
00501 case G_OPT_R3_MAP:
00502 Opt->key = "map";
00503 Opt->type = TYPE_STRING;
00504 Opt->key_desc = "name";
00505 Opt->required = YES;
00506 Opt->gisprompt = "old,grid3,3d-raster";
00507 Opt->description = _("Name of input raster3d map");
00508 break;
00509 case G_OPT_R3_MAPS:
00510 Opt->key = "map";
00511 Opt->type = TYPE_STRING;
00512 Opt->key_desc = "name";
00513 Opt->required = YES;
00514 Opt->multiple = YES;
00515 Opt->gisprompt = "old,grid3,3d-raster";
00516 Opt->description = _("Name of input raster3d map(s)");
00517 break;
00518
00519
00520 case G_OPT_V_INPUT:
00521 Opt->key = "input";
00522 Opt->type = TYPE_STRING;
00523 Opt->key_desc = "name";
00524 Opt->required = YES;
00525 Opt->gisprompt = "old,vector,vector";
00526 Opt->description = _("Name of input vector map");
00527 break;
00528 case G_OPT_V_INPUTS:
00529 Opt->key = "input";
00530 Opt->type = TYPE_STRING;
00531 Opt->key_desc = "name";
00532 Opt->required = YES;
00533 Opt->multiple = YES;
00534 Opt->gisprompt = "old,vector,vector";
00535 Opt->description = _("Name of input vector map(s)");
00536 break;
00537 case G_OPT_V_OUTPUT:
00538 Opt->key = "output";
00539 Opt->type = TYPE_STRING;
00540 Opt->key_desc = "name";
00541 Opt->required = YES;
00542 Opt->gisprompt = "new,vector,vector";
00543 Opt->description = _("Name for output vector map");
00544 break;
00545 case G_OPT_V_MAP:
00546 Opt->key = "map";
00547 Opt->type = TYPE_STRING;
00548 Opt->key_desc = "name";
00549 Opt->required = YES;
00550 Opt->gisprompt = "old,vector,vector";
00551 Opt->description = _("Name of input vector map");
00552 break;
00553 case G_OPT_V_MAPS:
00554 Opt->key = "map";
00555 Opt->type = TYPE_STRING;
00556 Opt->key_desc = "name";
00557 Opt->required = YES;
00558 Opt->multiple = YES;
00559 Opt->gisprompt = "old,vector,vector";
00560 Opt->description = _("Name of input vector map(s)");
00561 break;
00562 case G_OPT_V_TYPE:
00563 Opt->key = "type";
00564 Opt->type = TYPE_STRING;
00565 Opt->required = NO;
00566 Opt->multiple = YES;
00567 Opt->answer = "point,line,boundary,centroid,area";
00568 Opt->options = "point,line,boundary,centroid,area";
00569 Opt->description = _("Feature type");
00570 break;
00571 case G_OPT_V_FIELD:
00572 Opt->key = "layer";
00573 Opt->type = TYPE_INTEGER;
00574 Opt->required = NO;
00575 Opt->answer = "1";
00576 Opt->label = _("Layer number");
00577 Opt->description =
00578 _("A single vector map can be connected to multiple database "
00579 "tables. This number determines which table to use.");
00580 Opt->gisprompt = "old_layer,layer,layer";
00581
00582 break;
00583 case G_OPT_V_CAT:
00584 Opt->key = "cat";
00585 Opt->type = TYPE_INTEGER;
00586 Opt->required = NO;
00587 Opt->description = _("Category value");
00588 break;
00589 case G_OPT_V_CATS:
00590 Opt->key = "cats";
00591 Opt->type = TYPE_STRING;
00592 Opt->key_desc = "range";
00593 Opt->required = NO;
00594 Opt->label = _("Category values");
00595 Opt->description = _("Example: 1,3,7-9,13");
00596 break;
00597 case G_OPT_V_ID:
00598 Opt->key = "id";
00599 Opt->type = TYPE_INTEGER;
00600 Opt->required = NO;
00601 Opt->description = _("Feature id");
00602 break;
00603 case G_OPT_V_IDS:
00604 Opt->key = "ids";
00605 Opt->type = TYPE_STRING;
00606 Opt->key_desc = "range";
00607 Opt->required = NO;
00608 Opt->label = _("Feature ids");
00609 Opt->description = _("Example: 1,3,7-9,13");
00610 break;
00611
00612
00613 case G_OPT_F_INPUT:
00614 Opt->key = "input";
00615 Opt->type = TYPE_STRING;
00616 Opt->key_desc = "name";
00617 Opt->required = YES;
00618 Opt->gisprompt = "old_file,file,input";
00619 Opt->description = _("Name of input file");
00620 break;
00621 case G_OPT_F_OUTPUT:
00622 Opt->key = "output";
00623 Opt->type = TYPE_STRING;
00624 Opt->key_desc = "name";
00625 Opt->required = YES;
00626 Opt->gisprompt = "new_file,file,output";
00627 Opt->description = _("Name for output file");
00628 break;
00629 case G_OPT_F_SEP:
00630 Opt->key = "fs";
00631 Opt->type = TYPE_STRING;
00632 Opt->key_desc = "character";
00633 Opt->required = NO;
00634 Opt->answer = "|";
00635 Opt->description = _("Field separator");
00636 break;
00637
00638
00639 case G_OPT_C_FG:
00640 Opt->key = "color";
00641 Opt->type = TYPE_STRING;
00642 Opt->key_desc = "name";
00643 Opt->required = NO;
00644 Opt->answer = DEFAULT_FG_COLOR;
00645 Opt->gisprompt = "old_color,color,color";
00646 Opt->label = _("Color");
00647 Opt->description = _("Either a standard color name or R:G:B triplet");
00648 break;
00649 case G_OPT_C_BG:
00650 Opt->key = "bgcolor";
00651 Opt->type = TYPE_STRING;
00652 Opt->key_desc = "name";
00653 Opt->required = NO;
00654 Opt->answer = DEFAULT_BG_COLOR;
00655 Opt->gisprompt = "old_color,color,color_none";
00656 Opt->label = _("Background color");
00657 Opt->description =
00658 _("Either a standard GRASS color, R:G:B triplet, or \"none\"");
00659 break;
00660 }
00661
00662 return (Opt);
00663 }
00664
00665
00672 struct GModule *G_define_module(void)
00673 {
00674 struct GModule *module;
00675
00676
00677
00678 module = &module_info;
00679
00680
00681
00682 G_zero((char *)module, sizeof(struct GModule));
00683
00684 return (module);
00685 }
00686
00687
00688
00724 int G_parser(int argc, char **argv)
00725 {
00726 int need_first_opt;
00727 int opt_checked = 0;
00728 int error;
00729 char *ptr, *tmp_name;
00730 int i;
00731 struct Option *opt;
00732 char force_gui = FALSE;
00733
00734 error = 0;
00735 need_first_opt = 1;
00736 i = strlen(tmp_name = G_store(argv[0]));
00737 while (--i >= 0) {
00738 if (G_is_dirsep(tmp_name[i])) {
00739 tmp_name += i + 1;
00740 break;
00741 }
00742 }
00743 G_basename(tmp_name, "exe");
00744 pgm_name = tmp_name;
00745
00746
00747
00748 opt = &first_option;
00749 while (opt != NULL) {
00750
00751 if (opt->options) {
00752 int cnt = 0;
00753 char **tokens, delm[2];
00754
00755 delm[0] = ',';
00756 delm[1] = '\0';
00757 tokens = G_tokenize(opt->options, delm);
00758
00759 i = 0;
00760 while (tokens[i]) {
00761 cnt++;
00762 i++;
00763 }
00764
00765 opt->opts =
00766 (const char **)G_calloc(cnt + 1, sizeof(const char *));
00767
00768 i = 0;
00769 while (tokens[i]) {
00770 opt->opts[i] = G_store(tokens[i]);
00771 i++;
00772 }
00773 G_free_tokens(tokens);
00774
00775 if (opt->descriptions) {
00776 delm[0] = ';';
00777
00778 opt->descs =
00779 (const char **)G_calloc(cnt + 1, sizeof(const char *));
00780 tokens = G_tokenize(opt->descriptions, delm);
00781
00782 i = 0;
00783 while (tokens[i]) {
00784 int j, found;
00785
00786 if (!tokens[i + 1])
00787 break;
00788
00789 j = 0;
00790 found = 0;
00791 while (opt->opts[j]) {
00792 if (strcmp(opt->opts[j], tokens[i]) == 0) {
00793 found = 1;
00794 break;
00795 }
00796 j++;
00797 }
00798 if (!found) {
00799 G_warning(_("BUG in descriptions, option '%s' in <%s> does not exist"),
00800 tokens[i], opt->key);
00801 }
00802 else {
00803 opt->descs[j] = G_store(tokens[i + 1]);
00804 }
00805
00806 i += 2;
00807 }
00808 G_free_tokens(tokens);
00809 }
00810 }
00811
00812
00813 if (opt->multiple && opt->answers && opt->answers[0]) {
00814 opt->answer = (char *)G_malloc(strlen(opt->answers[0]) + 1);
00815 strcpy(opt->answer, opt->answers[0]);
00816 for (i = 1; opt->answers[i]; i++) {
00817 opt->answer = (char *)G_realloc(opt->answer,
00818 strlen(opt->answer) +
00819 strlen(opt->answers[i]) + 2);
00820 strcat(opt->answer, ",");
00821 strcat(opt->answer, opt->answers[i]);
00822 }
00823 }
00824 opt->def = opt->answer;
00825 opt = opt->next_opt;
00826 }
00827
00828
00829
00830 if (argc < 2 && interactive_ok && isatty(0)) {
00831 if (getenv("GRASS_UI_TERM")) {
00832 interactive(argv[0]);
00833 opt_checked = 1;
00834
00835 }
00836 else {
00837 G_gui();
00838 return -1;
00839 }
00840 }
00841 else if (argc < 2 && isatty(0)) {
00842 G_usage();
00843 return -1;
00844 }
00845 else if (argc >= 2) {
00846
00847
00848 if (strcmp(argv[1], "help") == 0 ||
00849 strcmp(argv[1], "-help") == 0 || strcmp(argv[1], "--help") == 0) {
00850 G_usage();
00851 exit(EXIT_SUCCESS);
00852 }
00853
00854
00855
00856 if (strcmp(argv[1], "--interface-description") == 0) {
00857 G_usage_xml();
00858 exit(EXIT_SUCCESS);
00859 }
00860
00861
00862
00863 if (strcmp(argv[1], "--html-description") == 0) {
00864 G_usage_html();
00865 exit(EXIT_SUCCESS);
00866 }
00867
00868
00869
00870 if (strcmp(argv[1], "--tcltk") == 0) {
00871 G_tcltk();
00872 exit(EXIT_SUCCESS);
00873 }
00874
00875
00876
00877 if (strcmp(argv[1], "--script") == 0) {
00878 G_script();
00879 exit(EXIT_SUCCESS);
00880 }
00881
00882
00883
00884 while (--argc) {
00885 ptr = *(++argv);
00886
00887
00888 if (strcmp(ptr, "--o") == 0 || strcmp(ptr, "--overwrite") == 0) {
00889 overwrite = 1;
00890 }
00891
00892
00893 else if (strcmp(ptr, "--v") == 0 || strcmp(ptr, "--verbose") == 0) {
00894 char buff[32];
00895
00896
00897 module_info.verbose = G_verbose_max();
00898 sprintf(buff, "GRASS_VERBOSE=%d", G_verbose_max());
00899 putenv(G_store(buff));
00900 if (quiet == 1) {
00901 G_warning(_("Use either --quiet or --verbose flag, not both. Assuming --verbose."));
00902 }
00903 quiet = -1;
00904 }
00905
00906
00907 else if (strcmp(ptr, "--q") == 0 || strcmp(ptr, "--quiet") == 0) {
00908 char buff[32];
00909
00910
00911 module_info.verbose = G_verbose_min();
00912 sprintf(buff, "GRASS_VERBOSE=%d", G_verbose_min());
00913 putenv(G_store(buff));
00914 if (quiet == -1) {
00915 G_warning(_("Use either --quiet or --verbose flag, not both. Assuming --quiet."));
00916 }
00917 quiet = 1;
00918 }
00919
00920
00921 else if (strcmp(ptr, "--ui") == 0) {
00922 force_gui = TRUE;
00923 }
00924
00925
00926 else if (*ptr == '-') {
00927 while (*(++ptr))
00928 error += set_flag(*ptr);
00929
00930 }
00931
00932 else if (is_option(ptr)) {
00933 error += set_option(ptr);
00934 need_first_opt = 0;
00935 }
00936
00937
00938 else if (need_first_opt && n_opts) {
00939 first_option.answer = G_store(ptr);
00940 need_first_opt = 0;
00941 }
00942
00943
00944 else if (contains(ptr, '=') == 0) {
00945 fprintf(stderr, _("Sorry <%s> is not a valid option\n"), ptr);
00946 error = 1;
00947 }
00948
00949 }
00950 }
00951
00952
00953 if (force_gui) {
00954 G_gui();
00955 return -1;
00956 }
00957
00958
00959 split_opts();
00960
00961
00962 error += check_multiple_opts();
00963
00964
00965 if (!opt_checked)
00966 error += check_opts();
00967
00968
00969 error += check_required();
00970
00971
00972 if (error) {
00973 if (G_verbose() > G_verbose_min())
00974 G_usage();
00975 return -1;
00976 }
00977
00978 if (check_overwrite())
00979 return -1;
00980
00981 return (0);
00982 }
00983
00984
00985 static int uses_new_gisprompt(void)
00986 {
00987 struct Option *opt;
00988 char age[KEYLENGTH];
00989 char element[KEYLENGTH];
00990 char desc[KEYLENGTH];
00991
00992
00993
00994 if (n_opts) {
00995 opt = &first_option;
00996 while (opt != NULL) {
00997 if (opt->gisprompt) {
00998 split_gisprompt(opt->gisprompt, age, element, desc);
00999 if (strcmp(age, "new") == 0)
01000 return 1;
01001 }
01002 opt = opt->next_opt;
01003 }
01004 }
01005
01006 return 0;
01007 }
01008
01009
01032 int G_usage(void)
01033 {
01034 struct Option *opt;
01035 struct Flag *flag;
01036 char item[256];
01037 const char *key_desc;
01038 int maxlen;
01039 int len, n;
01040 int new_prompt = 0;
01041
01042 new_prompt = uses_new_gisprompt();
01043
01044 if (!pgm_name)
01045 pgm_name = G_program_name();
01046 if (!pgm_name)
01047 pgm_name = "??";
01048
01049 if (module_info.label || module_info.description) {
01050 fprintf(stderr, _("\nDescription:\n"));
01051 if (module_info.label)
01052 fprintf(stderr, " %s\n", module_info.label);
01053 if (module_info.description)
01054 fprintf(stderr, " %s\n", module_info.description);
01055 }
01056 if (module_info.keywords) {
01057 fprintf(stderr, _("\nKeywords:\n"));
01058 fprintf(stderr, " %s\n", module_info.keywords);
01059 }
01060
01061 fprintf(stderr, _("\nUsage:\n "));
01062
01063 len = show(pgm_name, 1);
01064
01065
01066
01067 if (n_flags) {
01068 item[0] = ' ';
01069 item[1] = '[';
01070 item[2] = '-';
01071 flag = &first_flag;
01072 for (n = 3; flag != NULL; n++, flag = flag->next_flag)
01073 item[n] = flag->key;
01074 item[n++] = ']';
01075 item[n] = 0;
01076 len = show(item, len);
01077 }
01078
01079 maxlen = 0;
01080 if (n_opts) {
01081 opt = &first_option;
01082 while (opt != NULL) {
01083 if (opt->key_desc != NULL)
01084 key_desc = opt->key_desc;
01085 else if (opt->type == TYPE_STRING)
01086 key_desc = "string";
01087 else
01088 key_desc = "value";
01089
01090 n = strlen(opt->key);
01091 if (n > maxlen)
01092 maxlen = n;
01093
01094 strcpy(item, " ");
01095 if (!opt->required)
01096 strcat(item, "[");
01097 strcat(item, opt->key);
01098 strcat(item, "=");
01099 strcat(item, key_desc);
01100 if (opt->multiple) {
01101 strcat(item, "[,");
01102 strcat(item, key_desc);
01103 strcat(item, ",...]");
01104 }
01105 if (!opt->required)
01106 strcat(item, "]");
01107
01108 len = show(item, len);
01109
01110 opt = opt->next_opt;
01111 }
01112 }
01113 if (new_prompt) {
01114 strcpy(item, " [--overwrite]");
01115 len = show(item, len);
01116 }
01117
01118 strcpy(item, " [--verbose]");
01119 len = show(item, len);
01120
01121 strcpy(item, " [--quiet]");
01122 len = show(item, len);
01123
01124
01125 fprintf(stderr, "\n");
01126
01127
01128
01129 fprintf(stderr, _("\nFlags:\n"));
01130
01131 if (n_flags) {
01132 flag = &first_flag;
01133 while (flag != NULL) {
01134 fprintf(stderr, " -%c ", flag->key);
01135
01136 if (flag->label) {
01137 fprintf(stderr, "%s\n", flag->label);
01138 if (flag->description)
01139 fprintf(stderr, " %s\n", flag->description);
01140
01141 }
01142 else if (flag->description) {
01143 fprintf(stderr, "%s\n", flag->description);
01144 }
01145
01146 flag = flag->next_flag;
01147 }
01148 }
01149
01150 if (new_prompt)
01151 fprintf(stderr, " --o %s\n",
01152 _("Allow output files to overwrite existing files"));
01153
01154 fprintf(stderr, " --v %s\n", _("Verbose module output"));
01155 fprintf(stderr, " --q %s\n", _("Quiet module output"));
01156
01157
01158
01159 if (n_opts) {
01160 fprintf(stderr, _("\nParameters:\n"));
01161 opt = &first_option;
01162 while (opt != NULL) {
01163 fprintf(stderr, " %*s ", maxlen, opt->key);
01164
01165 if (opt->label) {
01166 fprintf(stderr, "%s\n", opt->label);
01167 if (opt->description) {
01168 fprintf(stderr, " %*s %s\n",
01169 maxlen, " ", opt->description);
01170 }
01171 }
01172 else if (opt->description) {
01173 fprintf(stderr, "%s\n", opt->description);
01174 }
01175
01176 if (opt->options)
01177 show_options(maxlen, opt->options);
01178
01179
01180
01181
01182 if (opt->def)
01183 fprintf(stderr, _(" %*s default: %s\n"), maxlen, " ",
01184 opt->def);
01185
01186 if (opt->descs) {
01187 int i = 0;
01188
01189 while (opt->opts[i]) {
01190 if (opt->descs[i])
01191 fprintf(stderr, " %*s %s: %s\n",
01192 maxlen, " ", opt->opts[i], opt->descs[i]);
01193
01194 i++;
01195 }
01196 }
01197
01198 opt = opt->next_opt;
01199 }
01200 }
01201
01202 return 0;
01203 }
01204
01205
01213 static void print_escaped_for_xml(FILE * fp, const char *str)
01214 {
01215 for (; *str; str++) {
01216 switch (*str) {
01217 case '&':
01218 fputs("&", fp);
01219 break;
01220 case '<':
01221 fputs("<", fp);
01222 break;
01223 case '>':
01224 fputs(">", fp);
01225 break;
01226 default:
01227 fputc(*str, fp);
01228 }
01229 }
01230 }
01231
01232
01236 #define do_escape(c,escaped) case c: fputs(escaped,f);break
01237 static void print_escaped_for_html(FILE * f, const char *str)
01238 {
01239 const char *s;
01240
01241 for (s = str; *s; s++) {
01242 switch (*s) {
01243 do_escape('&', "&");
01244 do_escape('<', "<");
01245 do_escape('>', ">");
01246 do_escape('\n', "<br>");
01247 default:
01248 fputc(*s, f);
01249 }
01250 }
01251 }
01252
01253 #undef do_escape
01254
01258 static void G_usage_xml(void)
01259 {
01260 struct Option *opt;
01261 struct Flag *flag;
01262 char *type;
01263 char *s, *top;
01264 int i;
01265 char *encoding;
01266 int new_prompt = 0;
01267
01268 new_prompt = uses_new_gisprompt();
01269
01270
01271
01272 #if defined(HAVE_LANGINFO_H)
01273 encoding = nl_langinfo(CODESET);
01274 if (!encoding || strlen(encoding) == 0) {
01275 encoding = "UTF-8";
01276 }
01277 #elif defined(__MINGW32__) && defined(USE_NLS)
01278 encoding = locale_charset();
01279 if (!encoding || strlen(encoding) == 0) {
01280 encoding = "UTF-8";
01281 }
01282 #else
01283 encoding = "UTF-8";
01284 #endif
01285
01286 if (!pgm_name)
01287 pgm_name = G_program_name();
01288 if (!pgm_name)
01289 pgm_name = "??";
01290
01291 fprintf(stdout, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding);
01292 fprintf(stdout, "<!DOCTYPE task SYSTEM \"grass-interface.dtd\">\n");
01293
01294 fprintf(stdout, "<task name=\"%s\">\n", pgm_name);
01295
01296 if (module_info.label) {
01297 fprintf(stdout, "\t<label>\n\t\t");
01298 print_escaped_for_xml(stdout, module_info.label);
01299 fprintf(stdout, "\n\t</label>\n");
01300 }
01301
01302 if (module_info.description) {
01303 fprintf(stdout, "\t<description>\n\t\t");
01304 print_escaped_for_xml(stdout, module_info.description);
01305 fprintf(stdout, "\n\t</description>\n");
01306 }
01307
01308 if (module_info.keywords) {
01309 fprintf(stdout, "\t<keywords>\n\t\t");
01310 print_escaped_for_xml(stdout, module_info.keywords);
01311 fprintf(stdout, "\n\t</keywords>\n");
01312 }
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323 if (n_opts) {
01324 opt = &first_option;
01325 while (opt != NULL) {
01326
01327 switch (opt->type) {
01328 case TYPE_INTEGER:
01329 type = "integer";
01330 break;
01331 case TYPE_DOUBLE:
01332 type = "float";
01333 break;
01334 case TYPE_STRING:
01335 type = "string";
01336 break;
01337 default:
01338 type = "string";
01339 break;
01340 }
01341 fprintf(stdout, "\t<parameter "
01342 "name=\"%s\" "
01343 "type=\"%s\" "
01344 "required=\"%s\" "
01345 "multiple=\"%s\">\n",
01346 opt->key,
01347 type,
01348 opt->required == YES ? "yes" : "no",
01349 opt->multiple == YES ? "yes" : "no");
01350
01351 if (opt->label) {
01352 fprintf(stdout, "\t\t<label>\n\t\t\t");
01353 print_escaped_for_xml(stdout, opt->label);
01354 fprintf(stdout, "\n\t\t</label>\n");
01355 }
01356
01357 if (opt->description) {
01358 fprintf(stdout, "\t\t<description>\n\t\t\t");
01359 print_escaped_for_xml(stdout, opt->description);
01360 fprintf(stdout, "\n\t\t</description>\n");
01361 }
01362
01363 if (opt->key_desc) {
01364 fprintf(stdout, "\t\t<keydesc>\n");
01365 top = G_calloc(strlen(opt->key_desc) + 1, 1);
01366 strcpy(top, opt->key_desc);
01367 s = strtok(top, ",");
01368 for (i = 1; s != NULL; i++) {
01369 fprintf(stdout, "\t\t\t<item order=\"%d\">", i);
01370 print_escaped_for_xml(stdout, s);
01371 fprintf(stdout, "</item>\n");
01372 s = strtok(NULL, ",");
01373 }
01374 fprintf(stdout, "\t\t</keydesc>\n");
01375 G_free(top);
01376 }
01377
01378 if (opt->gisprompt) {
01379 const char *atts[] = { "age", "element", "prompt", NULL };
01380 top = G_calloc(strlen(opt->gisprompt) + 1, 1);
01381 strcpy(top, opt->gisprompt);
01382 s = strtok(top, ",");
01383 fprintf(stdout, "\t\t<gisprompt ");
01384 for (i = 0; s != NULL && atts[i] != NULL; i++) {
01385 fprintf(stdout, "%s=\"%s\" ", atts[i], s);
01386 s = strtok(NULL, ",");
01387 }
01388 fprintf(stdout, "/>\n");
01389 G_free(top);
01390 }
01391
01392 if (opt->def) {
01393 fprintf(stdout, "\t\t<default>\n\t\t\t");
01394 print_escaped_for_xml(stdout, opt->def);
01395 fprintf(stdout, "\n\t\t</default>\n");
01396 }
01397
01398 if (opt->options) {
01399
01400
01401
01402
01403 i = 0;
01404 fprintf(stdout, "\t\t<values>\n");
01405 while (opt->opts[i]) {
01406 fprintf(stdout, "\t\t\t<value>\n");
01407 fprintf(stdout, "\t\t\t\t<name>");
01408 print_escaped_for_xml(stdout, opt->opts[i]);
01409 fprintf(stdout, "</name>\n");
01410 if (opt->descs && opt->opts[i] && opt->descs[i]) {
01411 fprintf(stdout, "\t\t\t\t<description>");
01412 print_escaped_for_xml(stdout, opt->descs[i]);
01413 fprintf(stdout, "</description>\n");
01414 }
01415 fprintf(stdout, "\t\t\t</value>\n");
01416 i++;
01417 }
01418 fprintf(stdout, "\t\t</values>\n");
01419 }
01420 if (opt->guisection) {
01421 fprintf(stdout, "\t\t<guisection>\n\t\t\t");
01422 print_escaped_for_xml(stdout, opt->guisection);
01423 fprintf(stdout, "\n\t\t</guisection>\n");
01424 }
01425
01426
01427
01428
01429
01430 opt = opt->next_opt;
01431 fprintf(stdout, "\t</parameter>\n");
01432 }
01433 }
01434
01435
01436 if (n_flags) {
01437 flag = &first_flag;
01438 while (flag != NULL) {
01439 fprintf(stdout, "\t<flag name=\"%c\">\n", flag->key);
01440
01441 if (flag->label) {
01442 fprintf(stdout, "\t\t<label>\n\t\t\t");
01443 print_escaped_for_xml(stdout, flag->label);
01444 fprintf(stdout, "\n\t\t</label>\n");
01445 }
01446
01447 if (flag->description) {
01448 fprintf(stdout, "\t\t<description>\n\t\t\t");
01449 print_escaped_for_xml(stdout, flag->description);
01450 fprintf(stdout, "\n\t\t</description>\n");
01451 }
01452 if (flag->guisection) {
01453 fprintf(stdout, " \t\t<guisection>\n\t\t\t");
01454 print_escaped_for_xml(stdout, flag->guisection);
01455 fprintf(stdout, "\n\t\t</guisection>\n");
01456 }
01457 flag = flag->next_flag;
01458 fprintf(stdout, "\t</flag>\n");
01459 }
01460 }
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471 if (new_prompt) {
01472
01473 fprintf(stdout, "\t<flag name=\"%s\">\n", "overwrite");
01474 fprintf(stdout, "\t\t<description>\n\t\t\t");
01475 print_escaped_for_xml(stdout,
01476 _("Allow output files to overwrite existing files"));
01477 fprintf(stdout, "\n\t\t</description>\n");
01478 fprintf(stdout, "\t</flag>\n");
01479 }
01480
01481
01482 fprintf(stdout, "\t<flag name=\"%s\">\n", "verbose");
01483 fprintf(stdout, "\t\t<description>\n\t\t\t");
01484 print_escaped_for_xml(stdout, _("Verbose module output"));
01485 fprintf(stdout, "\n\t\t</description>\n");
01486 fprintf(stdout, "\t</flag>\n");
01487
01488
01489 fprintf(stdout, "\t<flag name=\"%s\">\n", "quiet");
01490 fprintf(stdout, "\t\t<description>\n\t\t\t");
01491 print_escaped_for_xml(stdout, _("Quiet module output"));
01492 fprintf(stdout, "\n\t\t</description>\n");
01493 fprintf(stdout, "\t</flag>\n");
01494
01495 fprintf(stdout, "</task>\n");
01496 }
01497
01501 static void G_usage_html(void)
01502 {
01503 struct Option *opt;
01504 struct Flag *flag;
01505 const char *type;
01506 int new_prompt = 0;
01507
01508 new_prompt = uses_new_gisprompt();
01509
01510 if (!pgm_name)
01511 pgm_name = G_program_name();
01512 if (!pgm_name)
01513 pgm_name = "??";
01514
01515 fprintf(stdout,
01516 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
01517 fprintf(stdout, "<html>\n<head>\n");
01518 fprintf(stdout, "<title>GRASS GIS manual: %s</title>\n", pgm_name);
01519 fprintf(stdout,
01520 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n");
01521 fprintf(stdout,
01522 "<link rel=\"stylesheet\" href=\"grassdocs.css\" type=\"text/css\">\n");
01523 fprintf(stdout, "</head>\n");
01524 fprintf(stdout, "<body bgcolor=\"white\">\n\n");
01525 fprintf(stdout,
01526 "<img src=\"grass_logo.png\" alt=\"GRASS logo\"><hr align=center size=6 noshade>\n\n");
01527 fprintf(stdout, "<h2>%s</h2>\n", _("NAME"));
01528 fprintf(stdout, "<em><b>%s</b></em> ", pgm_name);
01529
01530 if (module_info.label || module_info.description)
01531 fprintf(stdout, " - ");
01532
01533 if (module_info.label)
01534 fprintf(stdout, "%s<BR>\n", module_info.label);
01535
01536 if (module_info.description)
01537 fprintf(stdout, "%s\n", module_info.description);
01538
01539
01540 fprintf(stdout, "<h2>%s</h2>\n", _("KEYWORDS"));
01541 if (module_info.keywords) {
01542 fprintf(stdout, "%s", module_info.keywords);
01543 fprintf(stdout, "\n");
01544 }
01545 fprintf(stdout, "<h2>%s</h2>\n", _("SYNOPSIS"));
01546 fprintf(stdout, "<b>%s</b><br>\n", pgm_name);
01547 fprintf(stdout, "<b>%s help</b><br>\n", pgm_name);
01548
01549 fprintf(stdout, "<b>%s</b>", pgm_name);
01550
01551
01552
01553
01554 if (n_flags) {
01555 flag = &first_flag;
01556 fprintf(stdout, " [-<b>");
01557 while (flag != NULL) {
01558 fprintf(stdout, "%c", flag->key);
01559 flag = flag->next_flag;
01560 }
01561 fprintf(stdout, "</b>] ");
01562 }
01563 else
01564 fprintf(stdout, " ");
01565
01566 if (n_opts) {
01567 opt = &first_option;
01568
01569 while (opt != NULL) {
01570 if (opt->key_desc != NULL)
01571 type = opt->key_desc;
01572 else
01573 switch (opt->type) {
01574 case TYPE_INTEGER:
01575 type = "integer";
01576 break;
01577 case TYPE_DOUBLE:
01578 type = "float";
01579 break;
01580 case TYPE_STRING:
01581 type = "string";
01582 break;
01583 default:
01584 type = "string";
01585 break;
01586 }
01587 if (!opt->required)
01588 fprintf(stdout, " [");
01589 fprintf(stdout, "<b>%s</b>=<em>%s</em>", opt->key, type);
01590 if (opt->multiple) {
01591 fprintf(stdout, "[,<i>%s</i>,...]", type);
01592 }
01593 if (!opt->required)
01594 fprintf(stdout, "] ");
01595
01596 opt = opt->next_opt;
01597 fprintf(stdout, " ");
01598 }
01599 }
01600 if (new_prompt)
01601 fprintf(stdout, " [--<b>overwrite</b>] ");
01602
01603 fprintf(stdout, " [--<b>verbose</b>] ");
01604 fprintf(stdout, " [--<b>quiet</b>] ");
01605
01606 fprintf(stdout, "\n");
01607
01608
01609
01610 fprintf(stdout, "\n");
01611 if (n_flags || new_prompt) {
01612 flag = &first_flag;
01613 fprintf(stdout, "<h3>%s:</h3>\n", _("Flags"));
01614 fprintf(stdout, "<DL>\n");
01615 while (n_flags && flag != NULL) {
01616 fprintf(stdout, "<DT><b>-%c</b></DT>\n", flag->key);
01617
01618 if (flag->label) {
01619 fprintf(stdout, "<DD>");
01620 fprintf(stdout, "%s", flag->label);
01621 fprintf(stdout, "</DD>\n");
01622 }
01623
01624 if (flag->description) {
01625 fprintf(stdout, "<DD>");
01626 fprintf(stdout, "%s", flag->description);
01627 fprintf(stdout, "</DD>\n");
01628 }
01629
01630 flag = flag->next_flag;
01631 fprintf(stdout, "\n");
01632 }
01633 if (new_prompt) {
01634 fprintf(stdout, "<DT><b>--overwrite</b></DT>\n");
01635 fprintf(stdout, "<DD>%s</DD>\n",
01636 _("Allow output files to overwrite existing files"));
01637 }
01638
01639 fprintf(stdout, "<DT><b>--verbose</b></DT>\n");
01640 fprintf(stdout, "<DD>%s</DD>\n", _("Verbose module output"));
01641
01642 fprintf(stdout, "<DT><b>--quiet</b></DT>\n");
01643 fprintf(stdout, "<DD>%s</DD>\n", _("Quiet module output"));
01644
01645 fprintf(stdout, "</DL>\n");
01646 }
01647
01648 fprintf(stdout, "\n");
01649 if (n_opts) {
01650 opt = &first_option;
01651 fprintf(stdout, "<h3>%s:</h3>\n", _("Parameters"));
01652 fprintf(stdout, "<DL>\n");
01653
01654 while (opt != NULL) {
01655
01656 if (opt->key_desc != NULL)
01657 type = opt->key_desc;
01658 else
01659 switch (opt->type) {
01660 case TYPE_INTEGER:
01661 type = "integer";
01662 break;
01663 case TYPE_DOUBLE:
01664 type = "float";
01665 break;
01666 case TYPE_STRING:
01667 type = "string";
01668 break;
01669 default:
01670 type = "string";
01671 break;
01672 }
01673 fprintf(stdout, "<DT><b>%s</b>=<em>%s", opt->key, type);
01674 if (opt->multiple) {
01675 fprintf(stdout, "[,<i>%s</i>,...]", type);
01676 }
01677 fprintf(stdout, "</em></DT>\n");
01678
01679 if (opt->label) {
01680 fprintf(stdout, "<DD>");
01681 fprintf(stdout, "%s", opt->label);
01682 fprintf(stdout, "</DD>\n");
01683 }
01684 if (opt->description) {
01685 fprintf(stdout, "<DD>");
01686 print_escaped_for_html(stdout, opt->description);
01687 fprintf(stdout, "</DD>\n");
01688 }
01689
01690 if (opt->options) {
01691 fprintf(stdout, "<DD>%s: <em>", _("Options"));
01692 fprintf(stdout, "%s", opt->options);
01693 fprintf(stdout, "</em></DD>\n");
01694 }
01695
01696 if (opt->def) {
01697 fprintf(stdout, "<DD>%s: <em>", _("Default"));
01698 fprintf(stdout, "%s", opt->def);
01699 fprintf(stdout, "</em></DD>\n");
01700 }
01701
01702 if (opt->descs) {
01703 int i = 0;
01704
01705 while (opt->opts[i]) {
01706 if (opt->descs[i])
01707 fprintf(stdout, "<DD><b>%s</b>: %s</DD>\n",
01708 opt->opts[i], opt->descs[i]);
01709 i++;
01710 }
01711 }
01712
01713 opt = opt->next_opt;
01714 fprintf(stdout, "\n");
01715 }
01716 fprintf(stdout, "</DL>\n");
01717 }
01718
01719 fprintf(stdout, "</body>\n</html>\n");
01720 }
01721
01725 static void G_script(void)
01726 {
01727 FILE *fp = stdout;
01728 char *type;
01729
01730 fprintf(fp, "#!/bin/sh\n\n");
01731 fprintf(fp,
01732 "############################################################################\n");
01733 fprintf(fp, "#\n");
01734 fprintf(fp, "# MODULE: %s_wrapper\n", G_program_name());
01735 fprintf(fp, "# AUTHOR(S): %s\n", G_whoami());
01736 fprintf(fp, "# PURPOSE: \n");
01737 fprintf(fp, "# COPYRIGHT: (C) 2009 GRASS Development Team/%s\n",
01738 G_whoami());
01739 fprintf(fp, "#\n");
01740 fprintf(fp,
01741 "# This program is free software; you can redistribute it and/or modify\n");
01742 fprintf(fp,
01743 "# it under the terms of the GNU General Public License as published by\n");
01744 fprintf(fp,
01745 "# the Free Software Foundation; either version 2 of the License, or\n");
01746 fprintf(fp, "# (at your option) any later version.\n");
01747 fprintf(fp, "#\n");
01748 fprintf(fp,
01749 "# This program is distributed in the hope that it will be useful,\n");
01750 fprintf(fp,
01751 "# but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
01752 fprintf(fp,
01753 "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
01754 fprintf(fp, "# GNU General Public License for more details.\n");
01755 fprintf(fp, "#\n");
01756 fprintf(fp,
01757 "#############################################################################/\n");
01758
01759 fprintf(fp, "#%%Module\n");
01760 if (module_info.label)
01761 fprintf(fp, "#%% label: %s\n", module_info.label);
01762 if (module_info.description)
01763 fprintf(fp, "#%% description: %s\n", module_info.description);
01764 if (module_info.keywords)
01765 fprintf(fp, "#%% keywords: %s\n", module_info.keywords);
01766 fprintf(fp, "#%%End\n");
01767
01768 if (n_flags) {
01769 struct Flag *flag;
01770
01771 for (flag = &first_flag; flag; flag = flag->next_flag) {
01772 fprintf(fp, "#%%Flag\n");
01773 fprintf(fp, "#%% key: %c\n", flag->key);
01774 if (flag->label)
01775 fprintf(fp, "#%% label: %s\n", flag->label);
01776 if (flag->description)
01777 fprintf(fp, "#%% description: %s\n", flag->description);
01778 if (flag->guisection)
01779 fprintf(fp, "#%% guisection: %s\n", flag->guisection);
01780 fprintf(fp, "#%%End\n");
01781 }
01782 }
01783
01784 if (n_opts) {
01785 struct Option *opt;
01786
01787 for (opt = &first_option; opt; opt = opt->next_opt) {
01788 switch (opt->type) {
01789 case TYPE_INTEGER:
01790 type = "integer";
01791 break;
01792 case TYPE_DOUBLE:
01793 type = "double";
01794 break;
01795 case TYPE_STRING:
01796 type = "string";
01797 break;
01798 default:
01799 type = "string";
01800 break;
01801 }
01802
01803 fprintf(fp, "#%%Option\n");
01804 fprintf(fp, "#%% key: %s\n", opt->key);
01805 fprintf(fp, "#%% type: %s\n", type);
01806 fprintf(fp, "#%% required: %s\n", opt->required ? "yes" : "no");
01807 fprintf(fp, "#%% multiple: %s\n", opt->multiple ? "yes" : "no");
01808 if (opt->options)
01809 fprintf(fp, "#%% options: %s\n", opt->options);
01810 if (opt->key_desc)
01811 fprintf(fp, "#%% key_desc: %s\n", opt->key_desc);
01812 if (opt->label)
01813 fprintf(fp, "#%% label: %s\n", opt->label);
01814 if (opt->description)
01815 fprintf(fp, "#%% description: %s\n", opt->description);
01816 if (opt->descriptions)
01817 fprintf(fp, "#%% descriptions: %s\n", opt->descriptions);
01818 if (opt->answer)
01819 fprintf(fp, "#%% answer: %s\n", opt->answer);
01820 if (opt->gisprompt)
01821 fprintf(fp, "#%% gisprompt: %s\n", opt->gisprompt);
01822 if (opt->guisection)
01823 fprintf(fp, "#%% guisection: %s\n", opt->guisection);
01824 fprintf(fp, "#%%End\n");
01825 }
01826 }
01827
01828 fprintf(fp,
01829 "\nif [ -z \"$GISBASE\" ] ; then\n"
01830 " echo \"You must be in GRASS GIS to run this program.\" 1>&2\n"
01831 " exit 1\n"
01832 "fi\n"
01833 "\n"
01834 "if [ \"$1\" != \"@ARGS_PARSED@\" ] ; then\n"
01835 " exec g.parser \"$0\" \"$@\"\n"
01836 "fi\n" "\n" "# CODE GOES HERE\n" "\n");
01837 }
01838
01844 static void generate_tcl(FILE * fp)
01845 {
01846 int new_prompt = uses_new_gisprompt();
01847 const char *type;
01848 int optn;
01849
01850 fprintf(fp, "begin_dialog {%s} {\n", pgm_name);
01851 fprintf(fp, " label {%s}\n", module_info.label ? module_info.label : "");
01852 fprintf(fp, " desc {%s}\n",
01853 module_info.description ? module_info.description : "");
01854 fprintf(fp, " key {%s}\n",
01855 module_info.keywords ? module_info.keywords : "");
01856 fprintf(fp, "}\n");
01857
01858 optn = 1;
01859
01860 if (n_flags) {
01861 struct Flag *flag;
01862
01863 for (flag = &first_flag; flag; flag = flag->next_flag, optn++) {
01864 fprintf(fp, "add_flag %d {\n", optn);
01865 fprintf(fp, " name {%c}\n", flag->key);
01866 fprintf(fp, " desc {%s}\n", flag->description);
01867 fprintf(fp, " answer %d\n", flag->answer);
01868
01869
01870 fprintf(fp, " label {%s}\n", flag->label ? flag->label : "");
01871 fprintf(fp, " guisection {%s}\n",
01872 flag->guisection ? flag->guisection : "");
01873 fprintf(fp, "}\n");
01874 }
01875 }
01876
01877 if (n_opts) {
01878 struct Option *opt;
01879
01880 for (opt = &first_option; opt; opt = opt->next_opt, optn++) {
01881 if (opt->key_desc != NULL)
01882 type = opt->key_desc;
01883 else
01884 switch (opt->type) {
01885 case TYPE_INTEGER:
01886 type = "integer";
01887 break;
01888 case TYPE_DOUBLE:
01889 type = "float";
01890 break;
01891 case TYPE_STRING:
01892 type = "string";
01893 break;
01894 default:
01895 type = "string";
01896 break;
01897 }
01898
01899 fprintf(fp, "add_option %d {\n", optn);
01900 fprintf(fp, " name {%s}\n", opt->key);
01901 fprintf(fp, " type {%s}\n", type);
01902 fprintf(fp, " multi %d\n", opt->multiple);
01903 fprintf(fp, " desc {%s}\n", opt->description);
01904 fprintf(fp, " required %d\n", opt->required);
01905 fprintf(fp, " options {%s}\n", opt->options ? opt->options : "");
01906 fprintf(fp, " descs {%s}\n",
01907 opt->descriptions ? opt->descriptions : "");
01908 fprintf(fp, " answer {%s}\n", opt->answer ? opt->answer : "");
01909 fprintf(fp, " prompt {%s}\n",
01910 opt->gisprompt ? opt->gisprompt : "");
01911
01912
01913 fprintf(fp, " label {%s}\n", opt->label ? opt->label : "");
01914 fprintf(fp, " guisection {%s}\n",
01915 opt->guisection ? opt->guisection : "");
01916 fprintf(fp, "}\n");
01917 }
01918 }
01919
01920 if (new_prompt) {
01921 fprintf(fp, "add_xflag %d {\n", optn);
01922 fprintf(fp, " name {overwrite}\n");
01923 fprintf(fp, " desc {%s}\n",
01924 _("Allow output files to overwrite existing files"));
01925 fprintf(fp, " answer %d\n", overwrite);
01926 fprintf(fp, " label {%s}\n", _("Allow overwrite"));
01927 fprintf(fp, " guisection {}\n");
01928 fprintf(fp, "}\n");
01929 optn++;
01930 }
01931
01932 fprintf(fp, "add_xflag %d {\n", optn);
01933 fprintf(fp, " name {quiet}\n");
01934 fprintf(fp, " desc {%s}\n", _("Run with minimal output messages"));
01935 fprintf(fp, " answer %d\n", quiet);
01936 fprintf(fp, " label {%s}\n", _("Run quietly"));
01937 fprintf(fp, " guisection {}\n");
01938 fprintf(fp, "}\n");
01939 optn++;
01940
01941 fprintf(fp, "end_dialog %d\n", optn - 1);
01942 }
01943
01947 static void G_gui_tcltk(void)
01948 {
01949 FILE *fp;
01950
01951 if (!pgm_name)
01952 pgm_name = G_program_name();
01953 if (!pgm_name)
01954 pgm_name = "??";
01955
01956 #ifdef __MINGW32__
01957 if (getenv("GRASS_DEBUG_GUI"))
01958 fp = popen("tee gui_dump.tcl | \"%GRASS_WISH%\"", "w");
01959 else
01960 fp = popen("\"%GRASS_WISH%\"", "w");
01961 #else
01962 if (getenv("GRASS_DEBUG_GUI"))
01963 fp = popen("tee gui_dump.tcl | \"$GRASS_WISH\"", "w");
01964 else
01965 fp = popen("\"$GRASS_WISH\"", "w");
01966 #endif
01967
01968 if (!fp)
01969 G_fatal_error(_("Unable to spawn the 'wish' program"));
01970
01971 fprintf(fp, "source $env(GISBASE)/etc/gui.tcl\n");
01972
01973 generate_tcl(fp);
01974
01975 G_pclose(fp);
01976 }
01977
01981 static void G_gui_wx(void)
01982 {
01983 char script[GPATH_MAX];
01984
01985 if (!pgm_name)
01986 pgm_name = G_program_name();
01987 if (!pgm_name)
01988 G_fatal_error(_("Unable to determine program name"));
01989
01990 sprintf(script, "%s/etc/wxpython/gui_modules/menuform.py",
01991 getenv("GISBASE"));
01992 G_spawn(getenv("GRASS_PYTHON"), getenv("GRASS_PYTHON"), script, pgm_name, NULL);
01993 }
01994
02002 static void G_gui(void)
02003 {
02004
02005 char *gui = getenv("GRASS_GUI");
02006
02007 if (!gui) {
02008 gui = G_getenv("GRASS_GUI");
02009 }
02010
02011 if (gui && strcmp(gui, "wxpython") == 0)
02012 G_gui_wx();
02013 else
02014 G_gui_tcltk();
02015
02016 return;
02017 }
02018
02022 static void G_tcltk(void)
02023 {
02024 if (!pgm_name)
02025 pgm_name = G_program_name();
02026 if (!pgm_name)
02027 pgm_name = "??";
02028
02029 generate_tcl(stdout);
02030 }
02031
02032
02033
02034
02035
02036
02037
02038
02039 static int show_options(int maxlen, const char *str)
02040 {
02041 char *buff = G_store(str);
02042 char *p1, *p2;
02043 int totlen, len;
02044
02045 fprintf(stderr, _(" %*s options: "), maxlen, " ");
02046 totlen = maxlen + 13;
02047 p1 = buff;
02048 while ((p2 = G_index(p1, ','))) {
02049 *p2 = '\0';
02050 len = strlen(p1) + 1;
02051 if ((len + totlen) > 76) {
02052 totlen = maxlen + 13;
02053 fprintf(stderr, "\n %*s", maxlen + 13, " ");
02054 }
02055 fprintf(stderr, "%s,", p1);
02056 totlen += len;
02057 p1 = p2 + 1;
02058 }
02059 len = strlen(p1);
02060 if ((len + totlen) > 76)
02061 fprintf(stderr, "\n %*s", maxlen + 13, " ");
02062 fprintf(stderr, "%s\n", p1);
02063
02064 G_free(buff);
02065
02066 return 0;
02067 }
02068
02069 static int show(const char *item, int len)
02070 {
02071 int n;
02072
02073 n = strlen(item) + (len > 0);
02074 if (n + len > 76) {
02075 if (len)
02076 fprintf(stderr, "\n ");
02077 len = 0;
02078 }
02079 fprintf(stderr, "%s", item);
02080 return n + len;
02081 }
02082
02083 static int set_flag(int f)
02084 {
02085 struct Flag *flag;
02086
02087
02088
02089 if (!n_flags) {
02090 fprintf(stderr, _("Sorry, <%c> is not a valid flag\n"), f);
02091 return (1);
02092 }
02093
02094
02095
02096 flag = &first_flag;
02097 while (flag != NULL) {
02098 if (flag->key == f) {
02099 flag->answer = 1;
02100 return (0);
02101 }
02102 flag = flag->next_flag;
02103 }
02104
02105 fprintf(stderr, _("Sorry, <%c> is not a valid flag\n"), f);
02106 return (1);
02107 }
02108
02109
02110
02111
02112 static int contains(const char *s, int c)
02113 {
02114 while (*s) {
02115 if (*s == c)
02116 return (1);
02117 s++;
02118 }
02119 return (0);
02120 }
02121
02122 static int is_option(const char *string)
02123 {
02124 const char *p = strchr(string, '=');
02125
02126 if (!p)
02127 return 0;
02128 if (p == string)
02129 return 0;
02130 p--;
02131 if (!strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", *p))
02132 return 0;
02133
02134 return 1;
02135 }
02136
02137 static int set_option(char *string)
02138 {
02139 struct Option *at_opt = NULL;
02140 struct Option *opt = NULL;
02141 int got_one;
02142 size_t key_len;
02143 char the_key[KEYLENGTH];
02144 char *ptr;
02145
02146 for (ptr = the_key; *string != '='; ptr++, string++)
02147 *ptr = *string;
02148 *ptr = '\0';
02149 string++;
02150
02151
02152 got_one = 0;
02153 key_len = strlen(the_key);
02154 for (at_opt = &first_option; at_opt != NULL; at_opt = at_opt->next_opt) {
02155 if (at_opt->key == NULL || strncmp(the_key, at_opt->key, key_len))
02156 continue;
02157
02158 got_one++;
02159 opt = at_opt;
02160
02161
02162
02163 if (strlen(at_opt->key) == key_len) {
02164 opt = at_opt;
02165 got_one = 1;
02166 break;
02167 }
02168 }
02169
02170 if (got_one > 1) {
02171 fprintf(stderr, _("Sorry, <%s=> is ambiguous\n"), the_key);
02172 return (1);
02173 }
02174
02175
02176 if (got_one == 0) {
02177 fprintf(stderr, _("Sorry, <%s> is not a valid parameter\n"), the_key);
02178 return (1);
02179 }
02180
02181
02182 if (opt->count++) {
02183 opt->answer = (char *)G_realloc(opt->answer,
02184 strlen(opt->answer) + strlen(string) +
02185 2);
02186 strcat(opt->answer, ",");
02187 strcat(opt->answer, string);
02188 }
02189 else
02190 opt->answer = G_store(string);
02191 return (0);
02192 }
02193
02194 static int check_opts(void)
02195 {
02196 struct Option *opt;
02197 int error;
02198 int ans;
02199
02200 error = 0;
02201
02202 if (!n_opts)
02203 return (0);
02204
02205 opt = &first_option;
02206 while (opt != NULL) {
02207
02208
02209 if (opt->options && opt->answer) {
02210 if (opt->multiple == 0)
02211 error += check_an_opt(opt->key, opt->type,
02212 opt->options, opt->answer);
02213 else {
02214 for (ans = 0; opt->answers[ans] != '\0'; ans++)
02215 error += check_an_opt(opt->key, opt->type,
02216 opt->options, opt->answers[ans]);
02217 }
02218 }
02219
02220
02221
02222 if (opt->checker)
02223 error += opt->checker(opt->answer);
02224
02225 opt = opt->next_opt;
02226 }
02227 return (error);
02228 }
02229
02230 static int check_an_opt(const char *key, int type, const char *options,
02231 const char *answer)
02232 {
02233 int error;
02234
02235 error = 0;
02236
02237 switch (type) {
02238 case TYPE_INTEGER:
02239 error = check_int(answer, options);
02240 break;
02241 case TYPE_DOUBLE:
02242 error = check_double(answer, options);
02243 break;
02244 case TYPE_STRING:
02245 error = check_string(answer, options);
02246 break;
02247
02248
02249
02250
02251
02252 }
02253 switch (error) {
02254 case 0:
02255 break;
02256 case BAD_SYNTAX:
02257 fprintf(stderr,
02258 _("\nERROR: illegal range syntax for parameter <%s>\n"), key);
02259 fprintf(stderr, _(" Presented as: %s\n"), options);
02260 break;
02261 case OUT_OF_RANGE:
02262 fprintf(stderr,
02263 _("\nERROR: value <%s> out of range for parameter <%s>\n"),
02264 answer, key);
02265 fprintf(stderr, _(" Legal range: %s\n"), options);
02266 break;
02267 case MISSING_VALUE:
02268 fprintf(stderr, _("\nERROR: Missing value for parameter <%s>\n"),
02269 key);
02270 }
02271 return (error);
02272 }
02273
02274 static int check_int(const char *ans, const char *opts)
02275 {
02276 int d, lo, hi;
02277
02278 if (1 != sscanf(ans, "%d", &d))
02279 return (MISSING_VALUE);
02280
02281 if (contains(opts, '-')) {
02282 if (2 != sscanf(opts, "%d-%d", &lo, &hi))
02283 return (BAD_SYNTAX);
02284 if (d < lo || d > hi)
02285 return (OUT_OF_RANGE);
02286 else
02287 return (0);
02288 }
02289 else if (contains(opts, ',')) {
02290 for (;;) {
02291 if (1 != sscanf(opts, "%d", &lo))
02292 return (BAD_SYNTAX);
02293 if (d == lo)
02294 return (0);
02295 while (*opts != '\0' && *opts != ',')
02296 opts++;
02297 if (*opts == '\0')
02298 return (OUT_OF_RANGE);
02299 if (*(++opts) == '\0')
02300 return (OUT_OF_RANGE);
02301 }
02302 }
02303 else {
02304 if (1 != sscanf(opts, "%d", &lo))
02305 return (BAD_SYNTAX);
02306 if (d == lo)
02307 return (0);
02308 return (OUT_OF_RANGE);
02309 }
02310 }
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338 static int check_double(const char *ans, const char *opts)
02339 {
02340 double d, lo, hi;
02341
02342 if (1 != sscanf(ans, "%lf", &d))
02343 return (MISSING_VALUE);
02344
02345 if (contains(opts, '-')) {
02346 if (2 != sscanf(opts, "%lf-%lf", &lo, &hi))
02347 return (BAD_SYNTAX);
02348 if (d < lo || d > hi)
02349 return (OUT_OF_RANGE);
02350 else
02351 return (0);
02352 }
02353 else if (contains(opts, ',')) {
02354 for (;;) {
02355 if (1 != sscanf(opts, "%lf", &lo))
02356 return (BAD_SYNTAX);
02357 if (d == lo)
02358 return (0);
02359 while (*opts != '\0' && *opts != ',')
02360 opts++;
02361 if (*opts == '\0')
02362 return (OUT_OF_RANGE);
02363 if (*(++opts) == '\0')
02364 return (OUT_OF_RANGE);
02365 }
02366 }
02367 else {
02368 if (1 != sscanf(opts, "%lf", &lo))
02369 return (BAD_SYNTAX);
02370 if (d == lo)
02371 return (0);
02372 return (OUT_OF_RANGE);
02373 }
02374 }
02375
02376 static int check_string(const char *ans, const char *opts)
02377 {
02378 if (*opts == '\0')
02379 return (0);
02380
02381 if (contains(opts, ',')) {
02382 for (;;) {
02383 if ((!strncmp(ans, opts, strlen(ans)))
02384 && (*(opts + strlen(ans)) == ','
02385 || *(opts + strlen(ans)) == '\0'))
02386 return (0);
02387 while (*opts != '\0' && *opts != ',')
02388 opts++;
02389 if (*opts == '\0')
02390 return (OUT_OF_RANGE);
02391 if (*(++opts) == '\0')
02392 return (OUT_OF_RANGE);
02393 }
02394 }
02395 else {
02396 if (!strcmp(ans, opts))
02397 return (0);
02398 return (OUT_OF_RANGE);
02399 }
02400 }
02401
02402 static int check_required(void)
02403 {
02404 struct Option *opt;
02405 int err;
02406
02407 err = 0;
02408
02409 if (!n_opts)
02410 return (0);
02411
02412 opt = &first_option;
02413 while (opt != NULL) {
02414 if (opt->required && opt->answer == NULL) {
02415 fprintf(stderr,
02416 _("\nERROR: Required parameter <%s> not set:\n (%s).\n"),
02417 opt->key, (opt->label ? opt->label : opt->description) );
02418 err++;
02419 }
02420 opt = opt->next_opt;
02421 }
02422
02423 return (err);
02424 }
02425
02426 static int split_opts(void)
02427 {
02428 struct Option *opt;
02429 char *ptr1;
02430 char *ptr2;
02431 int allocated;
02432 int ans_num;
02433 int len;
02434
02435
02436 if (!n_opts)
02437 return 0;
02438
02439 opt = &first_option;
02440 while (opt != NULL) {
02441 if ( (opt->answer != NULL)) {
02442
02443 allocated = 10;
02444 opt->answers = (char **)G_malloc(allocated * sizeof(char *));
02445
02446 ans_num = 0;
02447 ptr1 = opt->answer;
02448 opt->answers[ans_num] = NULL;
02449
02450 for (;;) {
02451 for (len = 0, ptr2 = ptr1; *ptr2 != '\0' && *ptr2 != ',';
02452 ptr2++, len++) ;
02453
02454 if (len > 0) {
02455 opt->answers[ans_num] = (char *)G_malloc(len + 1);
02456 G_copy(opt->answers[ans_num], ptr1, len);
02457 opt->answers[ans_num][len] = 0;
02458
02459 ans_num++;
02460
02461 if (ans_num >= allocated) {
02462 allocated += 10;
02463 opt->answers =
02464 (char **)G_realloc((char *)opt->answers,
02465 allocated * sizeof(char *));
02466 }
02467
02468 opt->answers[ans_num] = NULL;
02469 }
02470
02471 if (*ptr2 == '\0')
02472 break;
02473
02474 ptr1 = ptr2 + 1;
02475
02476 if (*ptr1 == '\0')
02477 break;
02478 }
02479 }
02480 opt = opt->next_opt;
02481 }
02482
02483 return 0;
02484 }
02485
02486 static int check_multiple_opts(void)
02487 {
02488 struct Option *opt;
02489 const char *ptr;
02490 int n_commas;
02491 int n;
02492 int error;
02493
02494 if (!n_opts)
02495 return (0);
02496
02497 error = 0;
02498 opt = &first_option;
02499 while (opt != NULL) {
02500 if ((opt->answer != NULL) && (opt->key_desc != NULL)) {
02501
02502 n_commas = 1;
02503 for (ptr = opt->key_desc; *ptr != '\0'; ptr++)
02504 if (*ptr == ',')
02505 n_commas++;
02506
02507 for (n = 0; opt->answers[n] != '\0'; n++) ;
02508
02509 if (n % n_commas) {
02510 fprintf(stderr,
02511 _("\nERROR: option <%s> must be provided in multiples of %d\n"),
02512 opt->key, n_commas);
02513 fprintf(stderr, _(" You provided %d items:\n"), n);
02514 fprintf(stderr, " %s\n", opt->answer);
02515 error++;
02516 }
02517 }
02518 opt = opt->next_opt;
02519 }
02520 return (error);
02521 }
02522
02523
02524 static int check_overwrite(void)
02525 {
02526 struct Option *opt;
02527 char age[KEYLENGTH];
02528 char element[KEYLENGTH];
02529 char desc[KEYLENGTH];
02530 int error = 0;
02531 char *overstr;
02532 int over;
02533
02534 if (!n_opts)
02535 return (0);
02536
02537 over = 0;
02538
02539 if ((overstr = G__getenv("OVERWRITE"))) {
02540 over = atoi(overstr);
02541 }
02542
02543
02544 if ((overstr = getenv("GRASS_OVERWRITE"))) {
02545 if (atoi(overstr))
02546 over = 1;
02547 }
02548
02549 if (overwrite || over) {
02550 module_info.overwrite = 1;
02551
02552 putenv("GRASS_OVERWRITE=1");
02553
02554 return error;
02555 }
02556
02557 opt = &first_option;
02558 while (opt != NULL) {
02559 if ((opt->answer != NULL) && (opt->gisprompt != NULL)) {
02560 split_gisprompt(opt->gisprompt, age, element, desc);
02561
02562 if (strcmp(age, "new") == 0) {
02563 int i;
02564 for (i = 0; opt->answers[i]; i++) {
02565 if (G_find_file(element, opt->answers[i], G_mapset())) {
02566 if (!overwrite && !over) {
02567 if (G_info_format() != G_INFO_FORMAT_GUI) {
02568 fprintf(stderr,
02569 _("ERROR: option <%s>: <%s> exists.\n"),
02570 opt->key, opt->answers[i]);
02571 }
02572 else {
02573 fprintf(stderr,
02574 "GRASS_INFO_ERROR(%d,1): option <%s>: <%s> exists.\n",
02575 getpid(), opt->key, opt->answers[i]);
02576 fprintf(stderr, "GRASS_INFO_END(%d,1)\n",
02577 getpid());
02578 }
02579
02580 error = 1;
02581 }
02582 }
02583 }
02584 }
02585 }
02586 opt = opt->next_opt;
02587 }
02588
02589 return (error);
02590 }
02591
02592 static int interactive(const char *command)
02593 {
02594 struct Item *item;
02595
02596
02597
02598 if (!n_items) {
02599 fprintf(stderr, "PROGRAMMER ERROR: no flags or options\n");
02600 exit(EXIT_FAILURE);
02601 }
02602
02603 for (item = &first_item;;) {
02604 if (item->flag)
02605 interactive_flag(item->flag);
02606 else if (item->option)
02607 interactive_option(item->option);
02608 else
02609 break;
02610
02611 item = item->next_item;
02612
02613 if (item == NULL)
02614 break;
02615 }
02616
02617 return 0;
02618 }
02619
02620 static int interactive_flag(struct Flag *flag)
02621 {
02622 char buff[1024];
02623
02624 fprintf(stderr, _("\nFLAG: Set the following flag?\n"));
02625 sprintf(buff, " %s?", flag->description);
02626 flag->answer = G_yes(buff, 0);
02627
02628 return 0;
02629 }
02630
02631 static int interactive_option(struct Option *opt)
02632 {
02633 char buff[1024], *bptr;
02634 char buff2[1024];
02635 int set_one;
02636 int no_prompt;
02637
02638 fprintf(stderr, _("\nOPTION: %s\n"), opt->description);
02639 fprintf(stderr, _(" key: %s\n"), opt->key);
02640 if (opt->key_desc)
02641 fprintf(stderr, _(" format: %s\n"), opt->key_desc);
02642 if (opt->def)
02643 fprintf(stderr, _(" default: %s\n"), opt->def);
02644 fprintf(stderr, _("required: %s\n"), opt->required ? "YES" : "NO");
02645 if (opt->multiple)
02646 fprintf(stderr, _("multiple: %s\n"), opt->multiple ? "YES" : "NO");
02647 if (opt->options)
02648 fprintf(stderr, _(" options: %s\n"), opt->options);
02649
02650
02651
02652
02653 set_one = 0;
02654 for (;;) {
02655 *buff = '\0';
02656 if (opt->gisprompt)
02657 no_prompt = gis_prompt(opt, buff);
02658 else
02659 no_prompt = -1;
02660 if (no_prompt) {
02661 fprintf(stderr, _("enter option > "));
02662 if (fgets(buff, 1024, stdin) == 0)
02663 exit(EXIT_SUCCESS);;
02664 bptr = buff;
02665 while (*bptr) {
02666 if (*bptr == '\n')
02667 *bptr = '\0';
02668 bptr++;
02669 }
02670
02671 }
02672
02673 if (strlen(buff) != 0) {
02674 if (opt->options)
02675
02676 {
02677 if (check_an_opt(opt->key, opt->type, opt->options, buff)) {
02678 if (G_yes(_(" Try again? "), 1))
02679 continue;
02680 else
02681 exit(EXIT_FAILURE);
02682 }
02683 }
02684 if (opt->checker)
02685 if (opt->checker(buff)) {
02686 fprintf(stderr, _("Sorry, %s is not accepted.\n"), buff);
02687 *buff = '\0';
02688 if (G_yes(_(" Try again? "), 1))
02689 continue;
02690 else
02691 exit(EXIT_FAILURE);
02692 }
02693
02694 sprintf(buff2, "%s=%s", opt->key, buff);
02695 if (!opt->gisprompt) {
02696 fprintf(stderr, _("\nYou have chosen:\n %s\n"), buff2);
02697 if (G_yes(_("Is this correct? "), 1)) {
02698 set_option(buff2);
02699 set_one++;
02700 }
02701 }
02702 else {
02703 set_option(buff2);
02704 set_one++;
02705 }
02706 }
02707
02708 if ((strlen(buff) == 0) && opt->required && (set_one == 0))
02709 exit(EXIT_FAILURE);
02710 if ((strlen(buff) == 0) && (set_one > 0) && opt->multiple)
02711 break;
02712 if ((strlen(buff) == 0) && !opt->required)
02713 break;
02714 if ((set_one == 1) && !opt->multiple)
02715 break;
02716 }
02717 return (0);
02718 }
02719
02720 static int split_gisprompt(const char *gisprompt, char *age, char *element,
02721 char *desc)
02722 {
02723 const char *ptr1;
02724 char *ptr2;
02725
02726 for (ptr1 = gisprompt, ptr2 = age; *ptr1 != '\0'; ptr1++, ptr2++) {
02727 if (*ptr1 == ',')
02728 break;
02729 *ptr2 = *ptr1;
02730 }
02731 *ptr2 = '\0';
02732
02733 for (ptr1++, ptr2 = element; *ptr1 != '\0'; ptr1++, ptr2++) {
02734 if (*ptr1 == ',')
02735 break;
02736 *ptr2 = *ptr1;
02737 }
02738 *ptr2 = '\0';
02739
02740 for (ptr1++, ptr2 = desc; *ptr1 != '\0'; ptr1++, ptr2++) {
02741 if (*ptr1 == ',')
02742 break;
02743 *ptr2 = *ptr1;
02744 }
02745 *ptr2 = '\0';
02746
02747 return 0;
02748 }
02749
02750 static int gis_prompt(struct Option *opt, char *buff)
02751 {
02752 char age[KEYLENGTH];
02753 char element[KEYLENGTH];
02754 char desc[KEYLENGTH];
02755 char *ptr1;
02756
02757 split_gisprompt(opt->gisprompt, age, element, desc);
02758
02759
02760
02761 if (opt->answer)
02762 G_set_ask_return_msg(_("to accept the default"));
02763 if (!strcmp("old", age)) {
02764 ptr1 = G_ask_old("", buff, element, desc);
02765 if (ptr1) {
02766 strcpy(buff, G_fully_qualified_name(buff, ptr1));
02767 }
02768 }
02769 else if (!strcmp("new", age))
02770 ptr1 = G_ask_new("", buff, element, desc);
02771 else if (!strcmp("mapset", age))
02772 ptr1 = G_ask_in_mapset("", buff, element, desc);
02773 else if (!strcmp("any", age))
02774 ptr1 = G_ask_any("", buff, element, desc, 1);
02775 else if (!strcmp("old_file", age))
02776 ptr1 = G_ask_old_file("", buff, element, desc);
02777 else if (!strcmp("new_file", age))
02778 ptr1 = G_ask_new_file("", buff, element, desc);
02779 else {
02780 return -1;
02781 }
02782
02783 if (ptr1 == '\0')
02784 *buff = '\0';
02785
02786 return 0;
02787 }
02788
02797 char *G_recreate_command(void)
02798 {
02799 static char *buff;
02800 char flg[4];
02801 char *cur;
02802 const char *tmp;
02803 struct Flag *flag;
02804 struct Option *opt;
02805 int n, len, slen;
02806 int nalloced = 0;
02807
02808 G_debug(3, "G_recreate_command()");
02809
02810
02811
02812 buff = G_calloc(1024, sizeof(char));
02813 nalloced += 1024;
02814 tmp = G_program_name();
02815 len = strlen(tmp);
02816 if (len >= nalloced) {
02817 nalloced += (1024 > len) ? 1024 : len + 1;
02818 buff = G_realloc(buff, nalloced);
02819 }
02820 cur = buff;
02821 strcpy(cur, tmp);
02822 cur += len;
02823
02824 if (n_flags) {
02825 flag = &first_flag;
02826 while (flag != '\0') {
02827 if (flag->answer == 1) {
02828 flg[0] = ' ';
02829 flg[1] = '-';
02830 flg[2] = flag->key;
02831 flg[3] = '\0';
02832 slen = strlen(flg);
02833 if (len + slen >= nalloced) {
02834 nalloced +=
02835 (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
02836 buff = G_realloc(buff, nalloced);
02837 cur = buff + len;
02838 }
02839 strcpy(cur, flg);
02840 cur += slen;
02841 len += slen;
02842 }
02843 flag = flag->next_flag;
02844 }
02845 }
02846
02847 opt = &first_option;
02848 while (opt != '\0') {
02849 if (opt->answer != '\0' && opt->answers[0] != NULL) {
02850 slen = strlen(opt->key) + strlen(opt->answers[0]) + 4;
02851 if (len + slen >= nalloced) {
02852 nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
02853 buff = G_realloc(buff, nalloced);
02854 cur = buff + len;
02855 }
02856 strcpy(cur, " ");
02857 cur++;
02858 strcpy(cur, opt->key);
02859 cur = strchr(cur, '\0');
02860 strcpy(cur, "=");
02861 cur++;
02862 if (opt->type == TYPE_STRING) {
02863 strcpy(cur, "\"");
02864 cur++;
02865 }
02866 strcpy(cur, opt->answers[0]);
02867 cur = strchr(cur, '\0');
02868 len = cur - buff;
02869 for (n = 1; opt->answers[n] != NULL && opt->answers[n] != '\0';
02870 n++) {
02871 if (opt->answers[n] == NULL)
02872 break;
02873 slen = strlen(opt->answers[n]) + 2;
02874 if (len + slen >= nalloced) {
02875 nalloced +=
02876 (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
02877 buff = G_realloc(buff, nalloced);
02878 cur = buff + len;
02879 }
02880 strcpy(cur, ",");
02881 cur++;
02882 strcpy(cur, opt->answers[n]);
02883 cur = strchr(cur, '\0');
02884 len = cur - buff;
02885 }
02886 if (opt->type == TYPE_STRING) {
02887 strcpy(cur, "\"");
02888 cur++;
02889 len = cur - buff;
02890 }
02891 }
02892 opt = opt->next_opt;
02893 }
02894
02895 return (buff);
02896 }