00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 #include <grass/config.h>
00116
00117 #if defined(HAVE_LANGINFO_H)
00118 #include <langinfo.h>
00119 #endif
00120
00121 #include <stdio.h>
00122 #include <stdlib.h>
00123 #include <string.h>
00124 #include <ctype.h>
00125 #include <unistd.h>
00126 #include <stdarg.h>
00127 #include <grass/gis.h>
00128 #include <grass/glocale.h>
00129
00130 #define BAD_SYNTAX 1
00131 #define OUT_OF_RANGE 2
00132 #define MISSING_VALUE 3
00133 #define KEYLENGTH 64
00134
00135 static int interactive_ok = 1 ;
00136 static int n_opts = 0 ;
00137 static int n_flags = 0 ;
00138 static int overwrite = 0 ;
00139
00140 static struct Flag first_flag;
00141 static struct Flag *current_flag;
00142
00143 static struct Option first_option ;
00144 static struct Option *current_option ;
00145
00146 static struct GModule module_info;
00147
00148 static const char *pgm_name = NULL;
00149
00150 struct Item
00151 {
00152 struct Option *option ;
00153 struct Flag *flag ;
00154 struct Item *next_item ;
00155 } ;
00156
00157 static struct Item first_item ;
00158 static struct Item *current_item ;
00159 static int n_items = 0 ;
00160 static int show_options(int ,char *);
00161 static int show(const char *,int);
00162 static int set_flag (int);
00163 static int contains (char *,int);
00164 static int set_option( char *);
00165 static int check_opts();
00166 static int check_an_opt( char *, int , char *,char *);
00167 static int check_int(char *, char *);
00168 static int check_double( char *, char *);
00169 static int check_string( char *, char *);
00170 static int check_required();
00171 static int split_opts();
00172 static int check_multiple_opts();
00173 static int check_overwrite();
00174 static int interactive( char *);
00175 static int interactive_flag( struct Flag *);
00176 static int interactive_option( struct Option *);
00177 static int gis_prompt( struct Option *, char *);
00178 static int split_gisprompt (const char *, char *, char *, char *);
00179
00180 static void G_gui (void);
00181 static void G_tcltk (void);
00182 static void G_usage_xml (void);
00183 static void G_usage_html (void);
00184
00185
00199 int
00200 G_disable_interactive (void)
00201 {
00202 interactive_ok = 0 ;
00203
00204 return 0;
00205 }
00206
00207
00218 struct Flag *
00219 G_define_flag (void)
00220 {
00221 struct Flag *flag ;
00222 struct Item *item ;
00223
00224
00225
00226 if (n_flags)
00227 {
00228 flag = (struct Flag *)G_malloc(sizeof(struct Flag)) ;
00229 current_flag->next_flag = flag ;
00230 }
00231 else
00232 flag = &first_flag ;
00233
00234
00235
00236 G_zero ((char *) flag, sizeof(struct Flag));
00237
00238 current_flag = flag ;
00239 n_flags++ ;
00240
00241 if (n_items)
00242 {
00243 item = (struct Item *)G_malloc(sizeof(struct Item)) ;
00244 current_item->next_item = item ;
00245 }
00246 else
00247 item = &first_item ;
00248
00249 G_zero ((char *) item, sizeof(struct Item));
00250
00251 item->flag = flag ;
00252 item->option = NULL ;
00253
00254 current_item = item ;
00255 n_items++ ;
00256
00257 return(flag) ;
00258 }
00259
00269 struct Option *
00270 G_define_option (void)
00271 {
00272 struct Option *opt ;
00273 struct Item *item ;
00274
00275
00276
00277 if (n_opts)
00278 {
00279 opt = (struct Option *)G_malloc(sizeof(struct Option)) ;
00280 current_option->next_opt = opt ;
00281 }
00282 else
00283 opt = &first_option ;
00284
00285
00286 G_zero ((char *) opt, sizeof(struct Option));
00287
00288 opt->required = NO ;
00289 opt->multiple = NO ;
00290 opt->answer = NULL ;
00291 opt->answers = NULL ;
00292 opt->def = NULL ;
00293 opt->checker = NULL ;
00294 opt->options = NULL ;
00295 opt->key_desc = NULL ;
00296 opt->gisprompt = NULL ;
00297 opt->label = NULL ;
00298 opt->opts = NULL ;
00299 opt->description = NULL ;
00300 opt->descriptions = NULL ;
00301 opt->guisection = NULL ;
00302
00303 current_option = opt ;
00304 n_opts++ ;
00305
00306 if (n_items)
00307 {
00308 item = (struct Item *)G_malloc(sizeof(struct Item)) ;
00309 current_item->next_item = item ;
00310 }
00311 else
00312 item = &first_item ;
00313
00314 G_zero ((char *) item, sizeof(struct Item));
00315
00316 item->option = opt ;
00317 item->flag = NULL ;
00318
00319 current_item = item ;
00320 n_items++ ;
00321
00322 return(opt) ;
00323 }
00324
00325
00342 struct Option *
00343 G_define_standard_option (int opt)
00344 {
00345 struct Option *Opt;
00346
00347 Opt = G_define_option();
00348
00349 switch ( opt ) {
00350 case G_OPT_WHERE:
00351 Opt->key = "where";
00352 Opt->type = TYPE_STRING;
00353 Opt->key_desc = "sql_query";
00354 Opt->required = NO;
00355 Opt->description = _("WHERE conditions of SQL statement without 'where' keyword. (example: income < 1000 and inhab >= 10000)");
00356 break;
00357
00358
00359 case G_OPT_R_INPUT:
00360 Opt->key = "input";
00361 Opt->type = TYPE_STRING;
00362 Opt->key_desc = "name";
00363 Opt->required = YES;
00364 Opt->gisprompt = "old,cell,raster";
00365 Opt->description = _("Name of input raster map");
00366 break;
00367 case G_OPT_R_INPUTS:
00368 Opt->key = "input";
00369 Opt->type = TYPE_STRING;
00370 Opt->key_desc = "name";
00371 Opt->required = YES;
00372 Opt->multiple = YES;
00373 Opt->gisprompt = "old,cell,raster";
00374 Opt->description = _("Name of input raster map(s)");
00375 break;
00376 case G_OPT_R_OUTPUT:
00377 Opt->key = "output";
00378 Opt->type = TYPE_STRING;
00379 Opt->key_desc = "name";
00380 Opt->required = YES;
00381 Opt->gisprompt = "new,cell,raster";
00382 Opt->description = _("Name for output raster map");
00383 break;
00384 case G_OPT_R_MAP:
00385 Opt->key = "map";
00386 Opt->type = TYPE_STRING;
00387 Opt->key_desc = "name";
00388 Opt->required = YES;
00389 Opt->gisprompt = "old,cell,raster";
00390 Opt->description = _("Name of input raster map");
00391 break;
00392 case G_OPT_R_MAPS:
00393 Opt->key = "map";
00394 Opt->type = TYPE_STRING;
00395 Opt->key_desc = "name";
00396 Opt->required = YES;
00397 Opt->multiple = YES;
00398 Opt->gisprompt = "old,cell,raster";
00399 Opt->description = _("Name of input raster map(s)");
00400 break;
00401 case G_OPT_R_BASE:
00402 Opt->key = "base";
00403 Opt->type = TYPE_STRING;
00404 Opt->key_desc = "name";
00405 Opt->required = YES;
00406 Opt->gisprompt = "old,cell,raster";
00407 Opt->description = _("Name of base raster map");
00408 break;
00409 case G_OPT_R_COVER:
00410 Opt->key = "cover";
00411 Opt->type = TYPE_STRING;
00412 Opt->key_desc = "name";
00413 Opt->required = YES;
00414 Opt->gisprompt = "old,cell,raster";
00415 Opt->description = _("Name of cover raster map");
00416 break;
00417 case G_OPT_R_ELEV:
00418 Opt->key = "elevation";
00419 Opt->type = TYPE_STRING;
00420 Opt->key_desc = "name";
00421 Opt->required = YES;
00422 Opt->gisprompt = "old,cell,raster";
00423 Opt->description = _("Name of elevation raster map");
00424 break;
00425 case G_OPT_R_ELEVS:
00426 Opt->key = "elevation";
00427 Opt->type = TYPE_STRING;
00428 Opt->key_desc = "name";
00429 Opt->required = YES;
00430 Opt->multiple = YES;
00431 Opt->gisprompt = "old,cell,raster";
00432 Opt->description = _("Name of elevation raster map(s)");
00433 break;
00434
00435
00436 case G_OPT_R3_INPUT:
00437 Opt->key = "input";
00438 Opt->type = TYPE_STRING;
00439 Opt->key_desc = "name";
00440 Opt->required = YES;
00441 Opt->gisprompt = "old,grid3,3d-raster";
00442 Opt->description = _("Name of input raster3d map");
00443 break;
00444 case G_OPT_R3_INPUTS:
00445 Opt->key = "input";
00446 Opt->type = TYPE_STRING;
00447 Opt->key_desc = "name";
00448 Opt->required = YES;
00449 Opt->multiple = YES;
00450 Opt->gisprompt = "old,grid3,3d-raster";
00451 Opt->description = _("Name of input raster3d map(s)");
00452 break;
00453 case G_OPT_R3_OUTPUT:
00454 Opt->key = "output";
00455 Opt->type = TYPE_STRING;
00456 Opt->key_desc = "name";
00457 Opt->required = YES;
00458 Opt->gisprompt = "new,grid3,3d-raster";
00459 Opt->description = _("Name for output raster3d map");
00460 break;
00461
00462
00463 case G_OPT_V_INPUT:
00464 Opt->key = "input";
00465 Opt->type = TYPE_STRING;
00466 Opt->key_desc = "name";
00467 Opt->required = YES;
00468 Opt->gisprompt = "old,vector,vector";
00469 Opt->description = _("Name of input vector map");
00470 break;
00471 case G_OPT_V_OUTPUT:
00472 Opt->key = "output";
00473 Opt->type = TYPE_STRING;
00474 Opt->key_desc = "name";
00475 Opt->required = YES;
00476 Opt->gisprompt = "new,vector,vector";
00477 Opt->description = _("Name for output vector map");
00478 break;
00479 case G_OPT_V_MAP:
00480 Opt->key = "map";
00481 Opt->type = TYPE_STRING;
00482 Opt->key_desc = "name";
00483 Opt->required = YES;
00484 Opt->gisprompt = "old,vector,vector";
00485 Opt->description = _("Name of input vector map");
00486 break;
00487 case G_OPT_V_TYPE:
00488 Opt->key = "type";
00489 Opt->type = TYPE_STRING;
00490 Opt->required = NO;
00491 Opt->multiple = YES;
00492 Opt->answer = "point,line,boundary,centroid,area";
00493 Opt->options = "point,line,boundary,centroid,area";
00494 Opt->description = _("Type");
00495 break;
00496 case G_OPT_V_FIELD:
00497 Opt->key = "layer";
00498 Opt->type = TYPE_INTEGER;
00499 Opt->required = NO;
00500 Opt->answer = "1";
00501 Opt->description = _("Layer number");
00502 break;
00503 case G_OPT_V_CAT:
00504 Opt->key = "cat";
00505 Opt->type = TYPE_INTEGER;
00506 Opt->required = NO;
00507 Opt->description = _("Category value");
00508 break;
00509 case G_OPT_V_CATS:
00510 Opt->key = "cats";
00511 Opt->type = TYPE_STRING;
00512 Opt->key_desc = "range";
00513 Opt->required = NO;
00514 Opt->label = _("Category values");
00515 Opt->description = _("Example: 1,3,7-9,13");
00516 break;
00517
00518
00519 case G_OPT_F_INPUT:
00520 Opt->key = "input";
00521 Opt->type = TYPE_STRING;
00522 Opt->key_desc = "name";
00523 Opt->required = YES;
00524 Opt->gisprompt = "old_file,file,input";
00525 Opt->description = _("Name of input file");
00526 break;
00527 case G_OPT_F_OUTPUT:
00528 Opt->key = "output";
00529 Opt->type = TYPE_STRING;
00530 Opt->key_desc = "name";
00531 Opt->required = YES;
00532 Opt->gisprompt = "new_file,file,output";
00533 Opt->description = _("Name for output file");
00534 break;
00535 case G_OPT_F_SEP:
00536 Opt->key = "fs";
00537 Opt->type = TYPE_STRING;
00538 Opt->key_desc = "character";
00539 Opt->required = NO;
00540 Opt->answer = "|";
00541 Opt->description = _("Field separator");
00542 break;
00543 }
00544
00545 return(Opt);
00546 }
00547
00548 struct GModule *
00549 G_define_module (void)
00550 {
00551 struct GModule *module ;
00552
00553
00554
00555 module = &module_info;
00556
00557
00558
00559 G_zero ((char *) module, sizeof(struct GModule));
00560
00561 return(module) ;
00562 }
00563
00564
00565
00585 int G_parser (int argc, char **argv)
00586 {
00587 int need_first_opt ;
00588 int opt_checked = 0;
00589 int error ;
00590 char *ptr ;
00591 int i;
00592 struct Option *opt ;
00593 char force_gui = FALSE;
00594
00595 error = 0 ;
00596 need_first_opt = 1 ;
00597 i = strlen(pgm_name = argv[0]) ;
00598 while (--i >= 0)
00599 {
00600 if (pgm_name[i] == '/')
00601 {
00602 pgm_name += i+1;
00603 break;
00604 }
00605 }
00606
00607
00608
00609 opt= &first_option;
00610 while(opt != NULL)
00611 {
00612
00613 if(opt->options)
00614 {
00615 int cnt = 0;
00616 char **tokens, delm[2];
00617
00618 delm[0] = ','; delm[1] = '\0';
00619 tokens = G_tokenize ( opt->options, delm );
00620
00621 i = 0;
00622 while ( tokens[i] ) {
00623 cnt++;
00624 i++;
00625 }
00626
00627 opt->opts = (char **)G_calloc( cnt+1, sizeof(char*) );
00628
00629 i = 0;
00630 while ( tokens[i] ) {
00631 opt->opts[i] = G_store ( tokens[i] );
00632 i++;
00633 }
00634 G_free_tokens ( tokens );
00635
00636 if(opt->descriptions ) {
00637 delm[0] = ';';
00638
00639 opt->descs = (char **)G_calloc( cnt+1, sizeof(char*) );
00640 tokens = G_tokenize ( opt->descriptions, delm );
00641
00642 i = 0;
00643 while ( tokens[i] ) {
00644 int j, found;
00645
00646 if ( !tokens[i+1] ) break;
00647
00648 j = 0; found = 0;
00649 while ( opt->opts[j] ) {
00650 if ( strcmp(opt->opts[j],tokens[i]) == 0 ) {
00651 found = 1;
00652 break;
00653 }
00654 j++;
00655 }
00656 if ( !found ) {
00657 G_warning ( "BUG in descriptions, option %s in %s does not exist",
00658 tokens[i], opt->key );
00659 } else {
00660 opt->descs[j] = G_store ( tokens[i+1] );
00661 }
00662
00663 i += 2;
00664 }
00665 G_free_tokens ( tokens );
00666 }
00667 }
00668
00669
00670 if(opt->multiple && opt->answers && opt->answers[0])
00671 {
00672 opt->answer = (char *)G_malloc(strlen(opt->answers[0])+1);
00673 strcpy(opt->answer, opt->answers[0]);
00674 for(i=1; opt->answers[i]; i++)
00675 {
00676 opt->answer = (char *)G_realloc (opt->answer,
00677 strlen(opt->answer)+
00678 strlen(opt->answers[i])+2);
00679 strcat(opt->answer, ",");
00680 strcat(opt->answer, opt->answers[i]);
00681 }
00682 }
00683 opt->def = opt->answer ;
00684 opt = opt->next_opt ;
00685 }
00686
00687
00688
00689 if (argc < 2 && interactive_ok && isatty(0) )
00690 {
00691 if (getenv("GRASS_UI_TERM")) {
00692 interactive(argv[0]) ;
00693 opt_checked = 1;
00694
00695 } else {
00696 G_gui();
00697 return -1;
00698 }
00699 }
00700 else if (argc < 2 && isatty(0))
00701 {
00702 G_usage();
00703 return -1;
00704 }
00705 else if (argc >= 2)
00706 {
00707
00708
00709 if (strcmp(argv[1],"help") == 0 ||
00710 strcmp(argv[1], "-help") == 0 ||
00711 strcmp(argv[1], "--help") == 0)
00712 {
00713 G_usage();
00714 exit(EXIT_SUCCESS);
00715 }
00716
00717
00718
00719 if (strcmp(argv[1],"--interface-description") == 0)
00720 {
00721 G_usage_xml();
00722 exit(EXIT_SUCCESS);
00723 }
00724
00725
00726
00727 if (strcmp(argv[1],"--html-description") == 0)
00728 {
00729 G_usage_html();
00730 exit(EXIT_SUCCESS);
00731 }
00732
00733
00734
00735 if (strcmp(argv[1],"--tcltk") == 0)
00736 {
00737 G_tcltk();
00738 exit(EXIT_SUCCESS);
00739 }
00740
00741
00742
00743 while(--argc)
00744 {
00745 ptr = *(++argv) ;
00746
00747
00748 if ( strcmp(ptr,"--o") == 0 || strcmp(ptr,"--overwrite") == 0 )
00749 {
00750 overwrite = 1;
00751 }
00752
00753
00754 else if ( strcmp(ptr,"--ui") == 0 )
00755 {
00756 force_gui = TRUE;
00757 }
00758
00759
00760 else if(*ptr == '-')
00761 {
00762 while(*(++ptr))
00763 error += set_flag(*ptr) ;
00764
00765 }
00766
00767 else if (contains(ptr, '='))
00768 {
00769 error += set_option(ptr) ;
00770 need_first_opt = 0 ;
00771 }
00772
00773
00774 else if (need_first_opt && n_opts)
00775 {
00776 first_option.answer = G_store(ptr) ;
00777 need_first_opt = 0 ;
00778 }
00779
00780
00781 else if (contains(ptr, '=') == 0)
00782 {
00783 fprintf(stderr, _("Sorry <%s> is not a valid option\n"), ptr);
00784 error = 1;
00785 }
00786
00787 }
00788 }
00789
00790
00791 if (force_gui) {
00792 G_gui();
00793 return -1;
00794 }
00795
00796
00797 split_opts() ;
00798
00799
00800 error += check_multiple_opts() ;
00801
00802
00803 if(!opt_checked)
00804 error += check_opts() ;
00805
00806
00807 error += check_required() ;
00808
00809
00810 if(error)
00811 {
00812 G_usage();
00813 return -1;
00814 }
00815
00816 if ( check_overwrite () )
00817 return -1;
00818
00819 return(0) ;
00820 }
00821
00822
00823 static int uses_new_gisprompt (void)
00824 {
00825 struct Option *opt ;
00826 char age[KEYLENGTH] ;
00827 char element[KEYLENGTH] ;
00828 char desc[KEYLENGTH] ;
00829
00830
00831
00832 if(n_opts)
00833 {
00834 opt= &first_option;
00835 while(opt != NULL)
00836 {
00837 if ( opt->gisprompt )
00838 {
00839 split_gisprompt (opt->gisprompt, age, element, desc) ;
00840 if (strcmp (age, "new") == 0)
00841 return 1;
00842 }
00843 opt=opt->next_opt;
00844 }
00845 }
00846
00847 return 0;
00848 }
00849
00870 int G_usage (void)
00871 {
00872 struct Option *opt ;
00873 struct Flag *flag ;
00874 char item[256];
00875 char *key_desc;
00876 int maxlen;
00877 int len, n;
00878 int new_prompt = 0;
00879
00880 new_prompt = uses_new_gisprompt();
00881
00882 if (!pgm_name)
00883 pgm_name = G_program_name ();
00884 if (!pgm_name)
00885 pgm_name = "??";
00886
00887 if (module_info.description) {
00888 fprintf (stderr, _("\nDescription:\n"));
00889 fprintf (stderr, " %s\n", module_info.description);
00890 }
00891 if (module_info.keywords) {
00892 fprintf (stderr, _("\nKeywords:\n"));
00893 fprintf (stderr, " %s\n", module_info.keywords);
00894 }
00895
00896 fprintf (stderr, _("\nUsage:\n "));
00897
00898 len = show(pgm_name,1);
00899
00900
00901
00902 if(n_flags)
00903 {
00904 item[0] = ' ';
00905 item[1] = '[';
00906 item[2] = '-';
00907 flag= &first_flag;
00908 for(n = 3; flag != NULL; n++, flag = flag->next_flag)
00909 item[n] = flag->key;
00910 item[n++] = ']';
00911 item[n] = 0;
00912 len=show(item,len);
00913 }
00914
00915 maxlen = 0;
00916 if(n_opts)
00917 {
00918 opt= &first_option;
00919 while(opt != NULL)
00920 {
00921 if (opt->key_desc != NULL)
00922 key_desc = opt->key_desc;
00923 else if (opt->type == TYPE_STRING)
00924 key_desc = "string";
00925 else
00926 key_desc = "value";
00927
00928 n = strlen (opt->key);
00929 if (n > maxlen) maxlen = n;
00930
00931 strcpy(item," ");
00932 if(!opt->required )
00933 strcat (item, "[");
00934 strcat (item, opt->key);
00935 strcat (item, "=");
00936 strcat (item, key_desc);
00937 if (opt->multiple)
00938 {
00939 strcat(item,"[,");
00940 strcat(item,key_desc);
00941 strcat(item,",...]");
00942 }
00943 if(!opt->required )
00944 strcat(item,"]") ;
00945
00946 len = show(item,len);
00947
00948 opt = opt->next_opt ;
00949 }
00950 }
00951 if (new_prompt)
00952 {
00953 strcpy (item, " [--overwrite]");
00954 len=show(item,len);
00955 }
00956
00957 fprintf (stderr, "\n");
00958
00959
00960
00961 if(n_flags || new_prompt)
00962 fprintf (stderr, _("\nFlags:\n"));
00963
00964 if(n_flags)
00965 {
00966 flag= &first_flag;
00967 while(flag != NULL)
00968 {
00969 fprintf(stderr," -%c ", flag->key) ;
00970
00971 if ( flag->label ) {
00972 fprintf (stderr, "%s\n", flag->label );
00973 if ( flag->description )
00974 fprintf (stderr, " %s\n", flag->description);
00975
00976 } else if ( flag->description ) {
00977 fprintf (stderr, "%s\n", flag->description);
00978 }
00979
00980 flag = flag->next_flag ;
00981 }
00982 }
00983
00984 if (new_prompt)
00985 fprintf(stderr," --o %s\n", _("Force overwrite of output files")) ;
00986
00987
00988
00989
00990 if(n_opts)
00991 {
00992 fprintf (stderr, _("\nParameters:\n"));
00993 opt= &first_option;
00994 while(opt != NULL)
00995 {
00996 fprintf (stderr, " %*s ", maxlen, opt->key );
00997
00998 if ( opt->label ) {
00999 fprintf (stderr, "%s\n", opt->label );
01000 if ( opt->description )
01001 fprintf (stderr, " %*s\n", maxlen, opt->description);
01002
01003 } else if ( opt->description ) {
01004 fprintf (stderr, "%s\n", opt->description);
01005 }
01006
01007 if(opt->options)
01008 show_options(maxlen, opt->options) ;
01009
01010
01011
01012
01013 if(opt->def)
01014 fprintf (stderr, _(" %*s default: %s\n"), maxlen, " ",
01015 opt->def) ;
01016
01017 if(opt->descs) {
01018 int i = 0;
01019
01020 while ( opt->opts[i] ) {
01021 fprintf (stderr, " %*s %s: ", maxlen, " ", opt->opts[i] );
01022
01023 if ( opt->descs[i] )
01024 fprintf (stderr, "%s\n", opt->descs[i] );
01025
01026 i++;
01027 }
01028 }
01029
01030 opt = opt->next_opt ;
01031 }
01032 }
01033
01034 return 0;
01035 }
01036
01037 void print_escaped_for_xml (FILE * fp, char * str) {
01038 for (;*str;str++) {
01039 switch (*str) {
01040 case '&':
01041 fputs("&", fp);
01042 break;
01043 case '<':
01044 fputs("<", fp);
01045 break;
01046 case '>':
01047 fputs(">", fp);
01048 break;
01049 default:
01050 fputc(*str, fp);
01051 }
01052 }
01053 }
01054
01055 static void G_usage_xml (void)
01056 {
01057 struct Option *opt ;
01058 struct Flag *flag ;
01059 char *type;
01060 char *s, *top;
01061 int i;
01062 char *encoding;
01063
01064
01065
01066 #if defined(HAVE_LANGINFO_H)
01067 encoding = nl_langinfo (CODESET);
01068 if ( !encoding || strlen( encoding ) == 0 ) {
01069 encoding = "UTF-8";
01070 }
01071 #else
01072 encoding = "UTF-8";
01073 #endif
01074
01075 if (!pgm_name)
01076 pgm_name = G_program_name ();
01077 if (!pgm_name)
01078 pgm_name = "??";
01079
01080 fprintf(stdout, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding);
01081 fprintf(stdout, "<!DOCTYPE task SYSTEM \"grass-interface.dtd\">\n");
01082
01083 fprintf(stdout, "<task name=\"%s\">\n", pgm_name);
01084
01085 if (module_info.label) {
01086 fprintf(stdout, "\t<label>\n\t\t");
01087 print_escaped_for_xml (stdout, module_info.label);
01088 fprintf(stdout, "\n\t</label>\n");
01089 }
01090
01091 if (module_info.description) {
01092 fprintf(stdout, "\t<description>\n\t\t");
01093 print_escaped_for_xml (stdout, module_info.description);
01094 fprintf(stdout, "\n\t</description>\n");
01095 }
01096
01097 if (module_info.keywords) {
01098 fprintf(stdout, "\t<keywords>\n\t\t");
01099 print_escaped_for_xml (stdout, module_info.keywords);
01100 fprintf(stdout, "\n\t</keywords>\n");
01101 }
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112 if(n_opts)
01113 {
01114 opt= &first_option;
01115 while(opt != NULL)
01116 {
01117
01118 switch (opt->type) {
01119 case TYPE_INTEGER:
01120 type = "integer";
01121 break ;
01122 case TYPE_DOUBLE:
01123 type = "float";
01124 break ;
01125 case TYPE_STRING:
01126 type = "string";
01127 break ;
01128 default:
01129 type = "string";
01130 break;
01131 }
01132 fprintf (stdout, "\t<parameter "
01133 "name=\"%s\" "
01134 "type=\"%s\" "
01135 "required=\"%s\" "
01136 "multiple=\"%s\">\n",
01137 opt->key,
01138 type,
01139 opt->required == YES ? "yes" : "no",
01140 opt->multiple == YES ? "yes" : "no");
01141
01142 if (opt->label) {
01143 fprintf(stdout, "\t\t<label>\n\t\t\t");
01144 print_escaped_for_xml(stdout, opt->label);
01145 fprintf(stdout, "\n\t\t</label>\n");
01146 }
01147
01148 if (opt->description) {
01149 fprintf(stdout, "\t\t<description>\n\t\t\t");
01150 print_escaped_for_xml(stdout, opt->description);
01151 fprintf(stdout, "\n\t\t</description>\n");
01152 }
01153
01154 if (opt->key_desc)
01155 {
01156 fprintf (stdout, "\t\t<keydesc>\n");
01157 top = G_calloc (strlen (opt->key_desc) + 1, 1);
01158 strcpy (top, opt->key_desc);
01159 s = strtok (top, ",");
01160 for (i = 1; s != NULL; i++)
01161 {
01162 fprintf (stdout, "\t\t\t<item order=\"%d\">", i);
01163 print_escaped_for_xml (stdout, s);
01164 fprintf (stdout, "</item>\n");
01165 s = strtok (NULL, ",");
01166 }
01167 fprintf (stdout, "\t\t</keydesc>\n");
01168 G_free (top);
01169 }
01170
01171 if (opt->gisprompt)
01172 {
01173 const char *atts[] = {"age", "element", "prompt", NULL};
01174 top = G_calloc (strlen (opt->gisprompt) + 1, 1);
01175 strcpy (top, opt->gisprompt);
01176 s = strtok (top, ",");
01177 fprintf (stdout, "\t\t<gisprompt ");
01178 for (i = 0; s != NULL && atts[i] != NULL; i++)
01179 {
01180 fprintf (stdout, "%s=\"%s\" ", atts[i], s);
01181 s = strtok (NULL, ",");
01182 }
01183 fprintf (stdout, "/>\n");
01184 G_free (top);
01185 }
01186
01187 if(opt->def) {
01188 fprintf(stdout, "\t\t\t<default>\n\t\t\t");
01189 print_escaped_for_xml(stdout, opt->def);
01190 fprintf(stdout, "\n\t\t\t</default>\n");
01191 }
01192
01193 if(opt->options) {
01194 i = 0;
01195 fprintf(stdout, "\t\t<values>\n");
01196 while ( opt->opts[i] ) {
01197 fprintf(stdout, "\t\t\t<value>\n");
01198 fprintf(stdout, "\t\t\t\t<name>");
01199 print_escaped_for_xml(stdout, opt->opts[i]);
01200 fprintf(stdout, "</name>\n");
01201 if(opt->descs && opt->opts[i]) {
01202 fprintf(stdout, "\t\t\t\t<description>");
01203 print_escaped_for_xml(stdout, opt->descs[i]);
01204 fprintf(stdout, "</description>");
01205 }
01206 fprintf(stdout, "\t\t\t</value>\n");
01207 i++;
01208 }
01209 fprintf(stdout, "\t\t</values>\n");
01210 }
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220 opt = opt->next_opt ;
01221 fprintf (stdout, "\t</parameter>\n");
01222 }
01223 }
01224
01225
01226 if(n_flags)
01227 {
01228 flag= &first_flag;
01229 while(flag != NULL)
01230 {
01231 fprintf (stdout, "\t<flag name=\"%c\">\n", flag->key);
01232
01233 if (flag->label) {
01234 fprintf(stdout, "\t\t<label>\n\t\t\t");
01235 print_escaped_for_xml(stdout, flag->label);
01236 fprintf(stdout, "\n\t\t</label>\n");
01237 }
01238
01239 if (flag->description) {
01240 fprintf(stdout, "\t\t<description>\n\t\t\t");
01241 print_escaped_for_xml(stdout, flag->description);
01242 fprintf(stdout, "\n\t\t</description>\n");
01243 }
01244 flag = flag->next_flag ;
01245 fprintf (stdout, "\t</flag>\n");
01246 }
01247 }
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258 fprintf(stdout, "</task>\n");
01259 }
01260
01261 static void G_usage_html (void)
01262 {
01263 struct Option *opt ;
01264 struct Flag *flag ;
01265 char *type;
01266 char *newbuf;
01267 int new_prompt = 0;
01268
01269 new_prompt = uses_new_gisprompt();
01270
01271 if (!pgm_name)
01272 pgm_name = G_program_name ();
01273 if (!pgm_name)
01274 pgm_name = "??";
01275
01276 fprintf(stdout, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
01277 fprintf(stdout, "<html>\n<head>\n");
01278 fprintf(stdout, "<title>%s</title>\n", pgm_name);
01279 fprintf(stdout, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n");
01280 fprintf(stdout, "<link rel=\"stylesheet\" href=\"grassdocs.css\" type=\"text/css\">\n");
01281 fprintf(stdout, "</head>\n");
01282 fprintf(stdout, "<body bgcolor=\"white\">\n\n");
01283 fprintf(stdout, "<img src=\"grass.smlogo.gif\" alt=\"GRASS logo\"><hr align=center size=6 noshade>\n\n");
01284 fprintf(stdout, "<h2>NAME</h2>\n");
01285 fprintf(stdout, "<em><b>%s</b></em> ", pgm_name);
01286
01287 if (module_info.description) {
01288 fprintf(stdout, " - ");
01289 fprintf(stdout, "%s", module_info.description);
01290 fprintf(stdout, "\n");
01291 }
01292
01293 fprintf(stdout, "<h2>KEYWORDS</h2>\n");
01294 if (module_info.keywords) {
01295 fprintf(stdout, "%s", module_info.keywords);
01296 fprintf(stdout, "\n");
01297 }
01298 fprintf(stdout, "<h2>SYNOPSIS</h2>\n");
01299 fprintf(stdout, "<b>%s</b><br>\n", pgm_name);
01300 fprintf(stdout, "<b>%s help</b><br>\n", pgm_name);
01301
01302 fprintf(stdout, "<b>%s</b>", pgm_name);
01303
01304
01305
01306
01307 if(n_flags)
01308 {
01309 flag= &first_flag;
01310 fprintf(stdout, " [-<b>");
01311 while(flag != NULL)
01312 {
01313 fprintf (stdout, "%c", flag->key);
01314 flag = flag->next_flag ;
01315 }
01316 fprintf(stdout, "</b>] ");
01317 }
01318 else
01319 fprintf(stdout, " ");
01320
01321 if(n_opts)
01322 {
01323 opt= &first_option;
01324
01325 while(opt != NULL)
01326 {
01327 if (opt->key_desc != NULL)
01328 type = opt->key_desc;
01329 else switch (opt->type) {
01330 case TYPE_INTEGER:
01331 type = "integer";
01332 break ;
01333 case TYPE_DOUBLE:
01334 type = "float";
01335 break ;
01336 case TYPE_STRING:
01337 type = "string";
01338 break ;
01339 default:
01340 type = "string";
01341 break;
01342 }
01343 if( !opt->required )
01344 fprintf(stdout," [");
01345 fprintf(stdout,
01346 "<b>%s</b>=<em>%s</em>", opt->key, type);
01347 if (opt->multiple)
01348 {
01349 fprintf(stdout,"[,<i>%s</i>,...]", type);
01350 }
01351 if( !opt->required )
01352 fprintf(stdout,"] ");
01353
01354 opt = opt->next_opt ;
01355 fprintf(stdout," ");
01356 }
01357 }
01358 if (new_prompt)
01359 {
01360 fprintf(stdout, " [--<b>overwrite</b>] ");
01361 }
01362 fprintf(stdout, "\n");
01363
01364
01365
01366 fprintf(stdout, "\n");
01367 if(n_flags || new_prompt)
01368 {
01369 flag= &first_flag;
01370 fprintf(stdout, "<h3>Flags:</h3>\n");
01371 fprintf(stdout, "<DL>\n");
01372 while(n_flags && flag != NULL )
01373 {
01374 fprintf (stdout, "<DT><b>-%c</b></DT>\n", flag->key);
01375
01376 if ( flag->label ) {
01377 fprintf(stdout, "<DD>");
01378 fprintf(stdout, "%s", flag->label);
01379 fprintf(stdout, "</DD>\n");
01380 }
01381
01382 if (flag->description) {
01383 fprintf(stdout, "<DD>");
01384 fprintf(stdout, "%s", flag->description);
01385 fprintf(stdout, "</DD>\n");
01386 }
01387
01388 flag = flag->next_flag ;
01389 fprintf (stdout, "\n");
01390 }
01391 if (new_prompt)
01392 {
01393 fprintf(stdout, "<DT><b>--overwrite</b></DT>\n");
01394 fprintf(stdout, "<DD>Force overwrite of output files</DD>");
01395 }
01396 fprintf(stdout, "</DL>\n");
01397 }
01398
01399 fprintf(stdout, "\n");
01400 if(n_opts)
01401 {
01402 opt= &first_option;
01403 fprintf(stdout, "<h3>Parameters:</h3>\n");
01404 fprintf(stdout, "<DL>\n");
01405
01406 while(opt != NULL)
01407 {
01408
01409 if (opt->key_desc != NULL)
01410 type = opt->key_desc;
01411 else switch (opt->type) {
01412 case TYPE_INTEGER:
01413 type = "integer";
01414 break ;
01415 case TYPE_DOUBLE:
01416 type = "float";
01417 break ;
01418 case TYPE_STRING:
01419 type = "string";
01420 break ;
01421 default:
01422 type = "string";
01423 break;
01424 }
01425 fprintf(stdout,
01426 "<DT><b>%s</b>=<em>%s", opt->key, type);
01427 if (opt->multiple) {
01428 fprintf(stdout,"[,<i>%s</i>,...]", type);
01429 }
01430 fprintf(stdout,"</em></DT>\n");
01431
01432 if ( opt->label ) {
01433 fprintf(stdout, "<DD>");
01434 fprintf(stdout, "%s", opt->label);
01435 fprintf(stdout, "</DD>\n");
01436 }
01437 if (opt->description) {
01438 fprintf(stdout, "<DD>");
01439 newbuf = G_str_replace(opt->description, "\n","<br>");
01440 if (newbuf) {
01441 fprintf(stdout, "%s", newbuf);
01442 G_free(newbuf);
01443 } else
01444 fprintf(stdout, "%s", opt->description);
01445 fprintf(stdout, "</DD>\n");
01446
01447 }
01448
01449 if(opt->options) {
01450 fprintf(stdout, "<DD>Options: <em>");
01451 fprintf(stdout, "%s", opt->options);
01452 fprintf(stdout, "</em></DD>\n");
01453 }
01454
01455 if(opt->def) {
01456 fprintf(stdout, "<DD>Default: <em>");
01457 fprintf(stdout, "%s", opt->def);
01458 fprintf(stdout, "</em></DD>\n");
01459 }
01460
01461 if(opt->descs) {
01462 int i = 0;
01463
01464 while ( opt->opts[i] ) {
01465 fprintf(stdout, "<DD><b>%s</b>: ", opt->opts[i]);
01466
01467 if ( opt->descs[i] )
01468 fprintf (stdout, "%s", opt->descs[i] );
01469
01470 fprintf(stdout, "</DD>\n");
01471
01472 i++;
01473 }
01474 }
01475
01476 opt = opt->next_opt ;
01477 fprintf (stdout, "\n");
01478 }
01479 fprintf(stdout, "</DL>\n");
01480 }
01481
01482 fprintf(stdout, "</body>\n</html>\n");
01483 }
01484
01485 static void generate_tcl(FILE *fp)
01486 {
01487 int new_prompt = uses_new_gisprompt();
01488 char *type;
01489 int optn;
01490
01491 fprintf(fp, "begin_dialog {%s} {\n", pgm_name);
01492 fprintf(fp, " label {%s}\n", module_info.label ? module_info.label : "");
01493 fprintf(fp, " desc {%s}\n", module_info.description ? module_info.description : "");
01494 fprintf(fp, " key {%s}\n", module_info.keywords ? module_info.keywords : "");
01495 fprintf(fp, "}\n");
01496
01497 optn = 1;
01498
01499 if (n_flags)
01500 {
01501 struct Flag *flag;
01502
01503 for (flag = &first_flag; flag; flag = flag->next_flag, optn++) {
01504 fprintf(fp, "add_flag %d {\n", optn);
01505 fprintf(fp, " name {%c}\n", flag->key);
01506 fprintf(fp, " desc {%s}\n", flag->description);
01507 fprintf(fp, " answer %d\n", flag->answer);
01508
01509
01510 fprintf(fp, " label {%s}\n", flag->label ? flag->label : "");
01511 fprintf(fp, " guisection {%s}\n", flag->guisection ? flag->guisection : "");
01512 fprintf(fp, "}\n");
01513 }
01514 }
01515
01516 if (n_opts)
01517 {
01518 struct Option *opt;
01519
01520 for (opt = &first_option; opt; opt = opt->next_opt, optn++)
01521 {
01522 if (opt->key_desc != NULL)
01523 type = opt->key_desc;
01524 else switch (opt->type)
01525 {
01526 case TYPE_INTEGER:
01527 type = "integer";
01528 break;
01529 case TYPE_DOUBLE:
01530 type = "float";
01531 break;
01532 case TYPE_STRING:
01533 type = "string";
01534 break;
01535 default:
01536 type = "string";
01537 break;
01538 }
01539
01540 fprintf(fp, "add_option %d {\n", optn);
01541 fprintf(fp, " name {%s}\n", opt->key);
01542 fprintf(fp, " type {%s}\n", type);
01543 fprintf(fp, " multi %d\n", opt->multiple);
01544 fprintf(fp, " desc {%s}\n", opt->description);
01545 fprintf(fp, " required %d\n", opt->required);
01546 fprintf(fp, " options {%s}\n", opt->options ? opt->options : "");
01547 fprintf(fp, " answer {%s}\n", opt->answer ? opt->answer : "");
01548 fprintf(fp, " prompt {%s}\n", opt->gisprompt ? opt->gisprompt : "");
01549
01550
01551 fprintf(fp, " label {%s}\n", opt->label ? opt->label : "");
01552 fprintf(fp, " guisection {%s}\n", opt->guisection ? opt->guisection : "");
01553 fprintf(fp, "}\n");
01554 }
01555 }
01556
01557 if (new_prompt)
01558 {
01559 fprintf(fp, "add_xflag %d {\n", optn);
01560 fprintf(fp, " name {overwrite}\n");
01561 fprintf(fp, " desc {Force overwrite of output files}\n");
01562 fprintf(fp, " answer %d\n", overwrite);
01563 fprintf(fp, " label {Overwrite}\n");
01564 fprintf(fp, " guisection {}\n");
01565 fprintf(fp, "}\n");
01566 optn++;
01567 }
01568
01569 fprintf(fp, "end_dialog %d\n", optn - 1);
01570 }
01571
01572
01573 static void G_gui (void)
01574 {
01575 FILE *fp;
01576
01577 if (!pgm_name)
01578 pgm_name = G_program_name ();
01579 if (!pgm_name)
01580 pgm_name = "??";
01581
01582 if (getenv("GRASS_DEBUG_GUI"))
01583 fp = popen("tee gui_dump.tcl | $GRASS_WISH", "w");
01584 else
01585 fp = popen("$GRASS_WISH", "w");
01586
01587 if (!fp)
01588 G_fatal_error("unable to spawn wish");
01589
01590 fprintf(fp, "source $env(GISBASE)/etc/gui.tcl\n");
01591
01592 generate_tcl(fp);
01593
01594 pclose(fp);
01595 }
01596
01597
01598 static void G_tcltk (void)
01599 {
01600 if (!pgm_name)
01601 pgm_name = G_program_name ();
01602 if (!pgm_name)
01603 pgm_name = "??";
01604
01605 generate_tcl(stdout);
01606 }
01607
01608
01609
01610
01611
01612
01613
01614
01615 static int show_options(int maxlen,char *str)
01616 {
01617 char buff[1024] ;
01618 char *p1, *p2 ;
01619 int totlen, len ;
01620
01621 strcpy(buff, str) ;
01622 fprintf (stderr, _(" %*s options: "), maxlen, " ") ;
01623 totlen = maxlen + 13 ;
01624 p1 = buff ;
01625 while( (p2 = G_index(p1, ',')) )
01626 {
01627 *p2 = '\0' ;
01628 len = strlen(p1) + 1 ;
01629 if ((len + totlen) > 76)
01630 {
01631 totlen = maxlen + 13 ;
01632 fprintf(stderr, "\n %*s", maxlen + 13, " ") ;
01633 }
01634 fprintf (stderr, "%s,", p1) ;
01635 totlen += len ;
01636 p1 = p2 + 1 ;
01637 }
01638 len = strlen(p1) ;
01639 if ((len + totlen) > 76 )
01640 fprintf(stderr, "\n %*s", maxlen + 13, " ") ;
01641 fprintf (stderr, "%s\n", p1) ;
01642
01643 return 0;
01644 }
01645
01646 static int show (const char *item, int len)
01647 {
01648 int n;
01649
01650 n = strlen (item)+(len>0);
01651 if (n + len > 76)
01652 {
01653 if (len)
01654 fprintf (stderr, "\n ");
01655 len = 0;
01656 }
01657 fprintf (stderr, "%s", item);
01658 return n+len;
01659 }
01660
01661 static int set_flag (int f)
01662 {
01663 struct Flag *flag ;
01664
01665
01666
01667 if(!n_flags)
01668 {
01669 fprintf(stderr,_("Sorry, <%c> is not a valid flag\n"), f) ;
01670 return(1) ;
01671 }
01672
01673
01674
01675 flag= &first_flag;
01676 while(flag != NULL)
01677 {
01678 if( flag->key == f)
01679 {
01680 flag->answer = 1 ;
01681 return(0) ;
01682 }
01683 flag = flag->next_flag ;
01684 }
01685
01686 fprintf(stderr,_("Sorry, <%c> is not a valid flag\n"), f) ;
01687 return(1) ;
01688 }
01689
01690
01691
01692
01693 static int contains (char *s, int c)
01694 {
01695 while(*s)
01696 {
01697 if(*s == c)
01698 return(1) ;
01699 s++ ;
01700 }
01701 return(0) ;
01702 }
01703
01704 static int set_option (char *string)
01705 {
01706 struct Option *at_opt = NULL;
01707 struct Option *opt = NULL;
01708 int got_one ;
01709 size_t key_len ;
01710 char the_key[KEYLENGTH] ;
01711 char *ptr ;
01712
01713 for(ptr=the_key; *string!='='; ptr++, string++)
01714 *ptr = *string ;
01715 *ptr = '\0' ;
01716 string++ ;
01717
01718
01719 got_one = 0 ;
01720 key_len = strlen(the_key) ;
01721 for(at_opt= &first_option; at_opt != NULL; at_opt=at_opt->next_opt)
01722 {
01723 if (strncmp(the_key,at_opt->key,key_len))
01724 continue ;
01725
01726 got_one++;
01727 opt = at_opt ;
01728
01729
01730
01731 if (strlen (at_opt->key) == key_len)
01732 {
01733 opt = at_opt;
01734 got_one = 1;
01735 break;
01736 }
01737 }
01738
01739 if (got_one > 1)
01740 {
01741 fprintf(stderr,_("Sorry, <%s=> is ambiguous\n"), the_key) ;
01742 return(1) ;
01743 }
01744
01745
01746 if(got_one == 0)
01747 {
01748 fprintf(stderr,_("Sorry, <%s> is not a valid parameter\n"),
01749 the_key) ;
01750 return(1) ;
01751 }
01752
01753
01754 if (opt->count++)
01755 {
01756 opt->answer = (char *)G_realloc (opt->answer,
01757 strlen (opt->answer)+strlen(string)+2);
01758 strcat (opt->answer, ",");
01759 strcat (opt->answer, string);
01760 }
01761 else
01762 opt->answer = G_store(string) ;
01763 return(0) ;
01764 }
01765
01766 static int check_opts (void)
01767 {
01768 struct Option *opt ;
01769 int error ;
01770 int ans ;
01771
01772 error = 0 ;
01773
01774 if(! n_opts)
01775 return(0) ;
01776
01777 opt= &first_option;
01778 while(opt != NULL)
01779 {
01780
01781
01782 if(opt->options && opt->answer)
01783 {
01784 if(opt->multiple == 0)
01785 error += check_an_opt(opt->key, opt->type,
01786 opt->options, opt->answer) ;
01787 else
01788 {
01789 for(ans=0; opt->answers[ans] != '\0'; ans++)
01790 error += check_an_opt(opt->key, opt->type,
01791 opt->options, opt->answers[ans]) ;
01792 }
01793 }
01794
01795
01796
01797 if(opt->checker)
01798 error += opt->checker(opt->answer) ;
01799
01800 opt = opt->next_opt ;
01801 }
01802 return(error) ;
01803 }
01804
01805 static int check_an_opt (char *key, int type, char *options, char *answer)
01806 {
01807 int error ;
01808
01809 error = 0 ;
01810
01811 switch(type)
01812 {
01813 case TYPE_INTEGER:
01814 error = check_int(answer,options) ;
01815 break ;
01816 case TYPE_DOUBLE:
01817 error = check_double(answer,options) ;
01818 break ;
01819 case TYPE_STRING:
01820 error = check_string(answer,options) ;
01821 break ;
01822
01823
01824
01825
01826
01827 }
01828 switch(error)
01829 {
01830 case 0:
01831 break ;
01832 case BAD_SYNTAX:
01833 fprintf(stderr,_("\nError: illegal range syntax for parameter <%s>\n"),
01834 key) ;
01835 fprintf(stderr,_(" Presented as: %s\n"), options) ;
01836 break ;
01837 case OUT_OF_RANGE:
01838 fprintf(stderr,_("\nError: value <%s> out of range for parameter <%s>\n"),
01839 answer, key) ;
01840 fprintf(stderr,_(" Legal range: %s\n"), options) ;
01841 break ;
01842 case MISSING_VALUE:
01843 fprintf(stderr,_("\nError: Missing value for parameter <%s>\n"),
01844 key) ;
01845 }
01846 return(error) ;
01847 }
01848
01849 static int check_int (char *ans, char *opts)
01850 {
01851 int d, lo, hi;
01852
01853 if (1 != sscanf(ans,"%d", &d))
01854 return(MISSING_VALUE) ;
01855
01856 if (contains(opts, '-'))
01857 {
01858 if (2 != sscanf(opts,"%d-%d",&lo, &hi))
01859 return(BAD_SYNTAX) ;
01860 if (d < lo || d > hi)
01861 return(OUT_OF_RANGE) ;
01862 else
01863 return(0) ;
01864 }
01865 else if (contains(opts, ','))
01866 {
01867 for(;;)
01868 {
01869 if (1 != sscanf(opts,"%d",&lo))
01870 return(BAD_SYNTAX) ;
01871 if (d == lo)
01872 return(0) ;
01873 while(*opts != '\0' && *opts != ',')
01874 opts++ ;
01875 if (*opts == '\0')
01876 return(OUT_OF_RANGE) ;
01877 if (*(++opts) == '\0')
01878 return(OUT_OF_RANGE) ;
01879 }
01880 }
01881 else
01882 {
01883 if (1 != sscanf(opts,"%d",&lo))
01884 return(BAD_SYNTAX) ;
01885 if (d == lo)
01886 return(0) ;
01887 return(OUT_OF_RANGE) ;
01888 }
01889 }
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917 static int check_double (char *ans, char *opts)
01918 {
01919 double d, lo, hi;
01920
01921 if (1 != sscanf(ans,"%lf", &d))
01922 return(MISSING_VALUE) ;
01923
01924 if (contains(opts, '-'))
01925 {
01926 if (2 != sscanf(opts,"%lf-%lf",&lo, &hi))
01927 return(BAD_SYNTAX) ;
01928 if (d < lo || d > hi)
01929 return(OUT_OF_RANGE) ;
01930 else
01931 return(0) ;
01932 }
01933 else if (contains(opts, ','))
01934 {
01935 for(;;)
01936 {
01937 if (1 != sscanf(opts,"%lf",&lo))
01938 return(BAD_SYNTAX) ;
01939 if (d == lo)
01940 return(0) ;
01941 while(*opts != '\0' && *opts != ',')
01942 opts++ ;
01943 if (*opts == '\0')
01944 return(OUT_OF_RANGE) ;
01945 if (*(++opts) == '\0')
01946 return(OUT_OF_RANGE) ;
01947 }
01948 }
01949 else
01950 {
01951 if (1 != sscanf(opts,"%lf",&lo))
01952 return(BAD_SYNTAX) ;
01953 if (d == lo)
01954 return(0) ;
01955 return(OUT_OF_RANGE) ;
01956 }
01957 }
01958
01959 static int check_string (char *ans, char *opts)
01960 {
01961 if (*opts == '\0')
01962 return(0) ;
01963
01964 if (contains(opts, ','))
01965 {
01966 for(;;)
01967 {
01968 if ((! strncmp(ans, opts, strlen(ans)))
01969 && ( *(opts+strlen(ans)) == ','
01970 || *(opts+strlen(ans)) == '\0'))
01971 return(0) ;
01972 while(*opts != '\0' && *opts != ',')
01973 opts++ ;
01974 if (*opts == '\0')
01975 return(OUT_OF_RANGE) ;
01976 if (*(++opts) == '\0')
01977 return(OUT_OF_RANGE) ;
01978 }
01979 }
01980 else
01981 {
01982 if (! strcmp(ans, opts))
01983 return(0) ;
01984 return(OUT_OF_RANGE) ;
01985 }
01986 }
01987
01988 static int check_required (void)
01989 {
01990 struct Option *opt ;
01991 int err ;
01992
01993 err = 0 ;
01994
01995 if(! n_opts)
01996 return(0) ;
01997
01998 opt= &first_option;
01999 while(opt != NULL)
02000 {
02001 if(opt->required && opt->answer == NULL)
02002 {
02003 fprintf(stderr,_("\nERROR: Required parameter <%s> not set:\n (%s).\n"),
02004 opt->key, opt->description) ;
02005 err++ ;
02006 }
02007 opt = opt->next_opt ;
02008 }
02009
02010 return(err) ;
02011 }
02012
02013 static int split_opts (void)
02014 {
02015 struct Option *opt ;
02016 char *ptr1 ;
02017 char *ptr2 ;
02018 int allocated ;
02019 int ans_num ;
02020 int len ;
02021
02022
02023 if(! n_opts)
02024 return 0;
02025
02026 opt= &first_option;
02027 while(opt != NULL)
02028 {
02029 if ((opt->answer != NULL))
02030 {
02031
02032 allocated = 10 ;
02033 opt->answers = (char **)G_malloc(allocated * sizeof(char *)) ;
02034
02035 ans_num = 0 ;
02036 ptr1 = opt->answer ;
02037 opt->answers[ans_num] = NULL ;
02038
02039 for(;;)
02040 {
02041 for(len=0, ptr2=ptr1; *ptr2 != '\0' && *ptr2 != ','; ptr2++, len++)
02042 ;
02043
02044 if (len > 0)
02045 {
02046 opt->answers[ans_num]=(char *)G_malloc(len+1) ;
02047 G_copy(opt->answers[ans_num], ptr1, len) ;
02048 opt->answers[ans_num][len] = 0;
02049
02050 ans_num++ ;
02051
02052 if(ans_num >= allocated)
02053 {
02054 allocated += 10 ;
02055 opt->answers =
02056 (char **)G_realloc((char *)opt->answers,
02057 allocated * sizeof(char *)) ;
02058 }
02059
02060 opt->answers[ans_num] = NULL ;
02061 }
02062
02063 if(*ptr2 == '\0')
02064 break ;
02065
02066 ptr1 = ptr2+1 ;
02067
02068 if(*ptr1 == '\0')
02069 break ;
02070 }
02071 }
02072 opt = opt->next_opt ;
02073 }
02074
02075 return 0;
02076 }
02077
02078 static int check_multiple_opts (void)
02079 {
02080 struct Option *opt ;
02081 char *ptr ;
02082 int n_commas ;
02083 int n ;
02084 int error ;
02085
02086 if(! n_opts)
02087 return (0) ;
02088
02089 error = 0 ;
02090 opt= &first_option;
02091 while(opt != NULL)
02092 {
02093 if ((opt->answer != NULL) && (opt->key_desc != NULL))
02094 {
02095
02096 n_commas = 1 ;
02097 for(ptr=opt->key_desc; *ptr!='\0'; ptr++)
02098 if (*ptr == ',')
02099 n_commas++ ;
02100
02101 for(n=0;opt->answers[n] != '\0';n++)
02102 ;
02103
02104 if(n % n_commas)
02105 {
02106 fprintf(stderr,_("\nError: option <%s> must be provided in multiples of %d\n"),
02107 opt->key, n_commas) ;
02108 fprintf(stderr,_(" You provided %d items:\n"), n) ;
02109 fprintf(stderr," %s\n", opt->answer) ;
02110 error++ ;
02111 }
02112 }
02113 opt = opt->next_opt ;
02114 }
02115 return(error) ;
02116 }
02117
02118
02119 static int check_overwrite (void)
02120 {
02121 struct Option *opt ;
02122 char age[KEYLENGTH] ;
02123 char element[KEYLENGTH] ;
02124 char desc[KEYLENGTH] ;
02125 int error = 0;
02126 char *overstr;
02127 int over;
02128
02129 if(! n_opts)
02130 return (0) ;
02131
02132 over = 0;
02133
02134 if ( (overstr = G__getenv ( "OVERWRITE" )) ) {
02135 over = atoi ( overstr );
02136 }
02137
02138
02139 if ( (overstr = getenv ( "GRASS_OVERWRITE" )) ) {
02140 if (atoi ( overstr ))
02141 over = 1;
02142 }
02143
02144 if ( overwrite || over ) {
02145 module_info.overwrite = 1;
02146
02147 putenv("GRASS_OVERWRITE=1");
02148
02149 return error;
02150 }
02151
02152 opt= &first_option;
02153 while(opt != NULL)
02154 {
02155 if ((opt->answer != NULL) && (opt->gisprompt != NULL))
02156 {
02157 split_gisprompt (opt->gisprompt, age, element, desc);
02158
02159 if ( strcmp(age,"new") == 0 ) {
02160 if ( G_find_file (element, opt->answer, G_mapset()) )
02161 {
02162 if ( !overwrite && !over ) {
02163 fprintf(stderr,_("Error: option <%s>: <%s> exists.\n"),
02164 opt->key, opt->answer );
02165
02166 error = 1;
02167 }
02168 }
02169 }
02170 }
02171 opt = opt->next_opt ;
02172 }
02173
02174 return(error) ;
02175 }
02176
02177 static int interactive( char *command)
02178 {
02179 struct Item *item ;
02180
02181
02182
02183 if(!n_items)
02184 {
02185 fprintf(stderr,"Programmer error: no flags or options\n") ;
02186 exit(EXIT_FAILURE) ;
02187 }
02188
02189 for (item= &first_item ;;)
02190 {
02191 if (item->flag)
02192 interactive_flag(item->flag) ;
02193 else if (item->option)
02194 interactive_option(item->option) ;
02195 else
02196 break ;
02197
02198 item=item->next_item ;
02199
02200 if (item == NULL)
02201 break ;
02202 }
02203
02204 return 0;
02205 }
02206
02207 static int interactive_flag( struct Flag *flag )
02208 {
02209 char buff[1024] ;
02210 fprintf(stderr, _("\nFLAG: Set the following flag?\n")) ;
02211 sprintf(buff," %s?", flag->description) ;
02212 flag->answer = G_yes(buff, 0) ;
02213
02214 return 0;
02215 }
02216
02217 static int interactive_option(struct Option *opt )
02218 {
02219 char buff[1024],*bptr ;
02220 char buff2[1024] ;
02221 int set_one ;
02222 int no_prompt ;
02223
02224 fprintf(stderr,_("\nOPTION: %s\n"), opt->description) ;
02225 fprintf(stderr,_(" key: %s\n"), opt->key) ;
02226 if (opt->key_desc)
02227 fprintf(stderr,_(" format: %s\n"), opt->key_desc) ;
02228 if (opt->def)
02229 fprintf(stderr,_(" default: %s\n"), opt->def) ;
02230 fprintf(stderr,_("required: %s\n"), opt->required ? "YES" : "NO") ;
02231 if (opt->multiple)
02232 fprintf(stderr,_("multiple: %s\n"), opt->multiple ? "YES" : "NO") ;
02233 if (opt->options)
02234 fprintf(stderr,_(" options: %s\n"), opt->options) ;
02235
02236
02237
02238
02239 set_one = 0 ;
02240 for(;;)
02241 {
02242 *buff='\0' ;
02243 if(opt->gisprompt)
02244 no_prompt = gis_prompt(opt, buff) ;
02245 else
02246 no_prompt = -1;
02247 if (no_prompt)
02248 {
02249 fprintf(stderr,_("enter option > ")) ;
02250 if(fgets(buff,1024,stdin) == 0) exit(EXIT_SUCCESS); ;
02251 bptr = buff;
02252 while(*bptr) {if(*bptr=='\n') *bptr='\0'; bptr++;}
02253
02254 }
02255
02256 if(strlen(buff) != 0)
02257 {
02258 if(opt->options)
02259
02260 {
02261 if (check_an_opt(opt->key, opt->type, opt->options, buff))
02262 {
02263 if (G_yes(_(" Try again? "), 1))
02264 continue ;
02265 else
02266 exit(EXIT_FAILURE) ;
02267 }
02268 }
02269 if (opt->checker)
02270 if (opt->checker(buff))
02271 {
02272 fprintf(stderr,_("Sorry, %s is not accepted.\n"), buff) ;
02273 *buff = '\0' ;
02274 if (G_yes(_(" Try again? "), 1))
02275 continue ;
02276 else
02277 exit(EXIT_FAILURE) ;
02278 }
02279
02280 sprintf(buff2,"%s=%s", opt->key, buff) ;
02281 if(! opt->gisprompt)
02282 {
02283 fprintf(stderr,_("\nYou have chosen:\n %s\n"), buff2) ;
02284 if (G_yes(_("Is this correct? "), 1))
02285 {
02286 set_option(buff2) ;
02287 set_one++ ;
02288 }
02289 }
02290 else
02291 {
02292 set_option(buff2) ;
02293 set_one++ ;
02294 }
02295 }
02296
02297 if ((strlen(buff) == 0) && opt->required && (set_one == 0))
02298 exit(EXIT_FAILURE) ;
02299 if ((strlen(buff) == 0) && (set_one > 0) && opt->multiple )
02300 break ;
02301 if ((strlen(buff) == 0) && !opt->required)
02302 break ;
02303 if ((set_one == 1) && !opt->multiple)
02304 break ;
02305 }
02306 return(0) ;
02307 }
02308
02309 static int split_gisprompt (const char *gisprompt, char *age, char *element, char *desc)
02310 {
02311 const char *ptr1 ;
02312 char *ptr2 ;
02313
02314 for(ptr1=gisprompt,ptr2=age; *ptr1!='\0'; ptr1++, ptr2++)
02315 {
02316 if (*ptr1 == ',')
02317 break ;
02318 *ptr2 = *ptr1 ;
02319 }
02320 *ptr2 = '\0' ;
02321
02322 for(ptr1++, ptr2=element; *ptr1!='\0'; ptr1++, ptr2++)
02323 {
02324 if (*ptr1 == ',')
02325 break ;
02326 *ptr2 = *ptr1 ;
02327 }
02328 *ptr2 = '\0' ;
02329
02330 for(ptr1++, ptr2=desc; *ptr1!='\0'; ptr1++, ptr2++)
02331 {
02332 if (*ptr1 == ',')
02333 break ;
02334 *ptr2 = *ptr1 ;
02335 }
02336 *ptr2 = '\0' ;
02337
02338 return 0 ;
02339 }
02340
02341 static int gis_prompt (struct Option *opt, char *buff)
02342 {
02343 char age[KEYLENGTH] ;
02344 char element[KEYLENGTH] ;
02345 char desc[KEYLENGTH] ;
02346 char *ptr1 ;
02347
02348 split_gisprompt ( opt->gisprompt, age, element, desc );
02349
02350
02351
02352 if (opt->answer)
02353 G_set_ask_return_msg (_("to accept the default"));
02354 if (! strcmp("old",age))
02355 {
02356 ptr1 = G_ask_old("", buff, element, desc) ;
02357 if (ptr1)
02358 {
02359 strcpy (buff, G_fully_qualified_name(buff,ptr1));
02360 }
02361 }
02362 else if (! strcmp("new",age))
02363 ptr1 = G_ask_new("", buff, element, desc) ;
02364 else if (! strcmp("mapset",age))
02365 ptr1 = G_ask_in_mapset("", buff, element, desc) ;
02366 else if (! strcmp("any",age))
02367 ptr1 = G_ask_any("", buff, element, desc, 1) ;
02368 else if (! strcmp("old_file",age))
02369 ptr1 = G_ask_old_file("", buff, element, desc) ;
02370 else if (! strcmp("new_file",age))
02371 ptr1 = G_ask_new_file("", buff, element, desc) ;
02372 else if (! strcmp("color",age))
02373
02374
02375 return -1;
02376 else
02377 {
02378 fprintf(stderr,"\nPROGRAMMER ERROR: first item in gisprompt is <%s>\n", age) ;
02379 fprintf(stderr," Must be either new, old, mapset, any, old_file, new_file, or color\n") ;
02380 return -1;
02381 }
02382 if (ptr1 == '\0')
02383 *buff = '\0';
02384
02385 return 0;
02386 }
02387
02388 char *G_recreate_command (void)
02389 {
02390 static char *buff;
02391 char flg[4] ;
02392 char *cur;
02393 const char *tmp;
02394 struct Flag *flag ;
02395 struct Option *opt ;
02396 int n , len, slen;
02397 int nalloced = 0;
02398
02399 G_debug ( 3, "G_recreate_command()");
02400
02401
02402
02403 buff = G_calloc (1024, sizeof(char));
02404 nalloced += 1024;
02405 tmp = G_program_name();
02406 len = strlen (tmp);
02407 if (len >= nalloced)
02408 {
02409 nalloced += (1024 > len) ? 1024 : len + 1;
02410 buff = G_realloc (buff, nalloced);
02411 }
02412 cur = buff;
02413 strcpy (cur, tmp);
02414 cur += len;
02415
02416 if(n_flags)
02417 {
02418 flag= &first_flag;
02419 while(flag != '\0')
02420 {
02421 if( flag->answer == 1 )
02422 {
02423 flg[0] = ' '; flg[1] = '-'; flg[2] = flag->key; flg[3] = '\0';
02424 slen = strlen (flg);
02425 if (len + slen >= nalloced)
02426 {
02427 nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
02428 buff = G_realloc (buff, nalloced);
02429 cur = buff + len;
02430 }
02431 strcpy (cur, flg);
02432 cur += slen;
02433 len += slen;
02434 }
02435 flag = flag->next_flag ;
02436 }
02437 }
02438
02439 opt= &first_option;
02440 while(opt != '\0')
02441 {
02442 if ( opt->answer != '\0' && opt->answers[0] != NULL )
02443 {
02444 slen = strlen (opt->key) + strlen (opt->answers[0]) + 4;
02445 if (len + slen >= nalloced)
02446 {
02447 nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
02448 buff = G_realloc (buff, nalloced);
02449 cur = buff + len;
02450 }
02451 strcpy (cur, " ");
02452 cur++;
02453 strcpy (cur, opt->key);
02454 cur = strchr (cur, '\0');
02455 strcpy (cur, "=");
02456 cur++;
02457 if ( opt->type == TYPE_STRING ) {
02458 strcpy (cur, "\"");
02459 cur++;
02460 }
02461 strcpy (cur, opt->answers[0]);
02462 cur = strchr (cur, '\0');
02463 len = cur - buff;
02464 for(n=1; opt->answers[n] != NULL && opt->answers[n] != '\0';n++)
02465 {
02466 if ( opt->answers[n] == NULL ) break;
02467 slen = strlen (opt->answers[n]) + 2;
02468 if (len + slen >= nalloced)
02469 {
02470 nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
02471 buff = G_realloc (buff, nalloced);
02472 cur = buff + len;
02473 }
02474 strcpy (cur, ",");
02475 cur++;
02476 strcpy (cur, opt->answers[n]);
02477 cur = strchr(cur, '\0');
02478 len = cur - buff;
02479 }
02480 if ( opt->type == TYPE_STRING ) {
02481 strcpy (cur, "\"");
02482 cur++;
02483 len = cur - buff;
02484 }
02485 }
02486 opt = opt->next_opt ;
02487 }
02488
02489 return(buff) ;
02490 }
02491