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,"--v") == 0 || strcmp(ptr,"--verbose") == 0 )
00755 G_debug(1, "Verbose mode requested but not used in GRASS 6.2");
00756
00757
00758 else if ( strcmp(ptr,"--q") == 0 || strcmp(ptr,"--quiet") == 0 )
00759 G_debug(1, "Quiet mode requested but not used in GRASS 6.2");
00760
00761
00762 else if ( strcmp(ptr,"--ui") == 0 )
00763 {
00764 force_gui = TRUE;
00765 }
00766
00767
00768 else if(*ptr == '-')
00769 {
00770 while(*(++ptr))
00771 error += set_flag(*ptr) ;
00772
00773 }
00774
00775 else if (contains(ptr, '='))
00776 {
00777 error += set_option(ptr) ;
00778 need_first_opt = 0 ;
00779 }
00780
00781
00782 else if (need_first_opt && n_opts)
00783 {
00784 first_option.answer = G_store(ptr) ;
00785 need_first_opt = 0 ;
00786 }
00787
00788
00789 else if (contains(ptr, '=') == 0)
00790 {
00791 fprintf(stderr, _("Sorry <%s> is not a valid option\n"), ptr);
00792 error = 1;
00793 }
00794
00795 }
00796 }
00797
00798
00799 if (force_gui) {
00800 G_gui();
00801 return -1;
00802 }
00803
00804
00805 split_opts() ;
00806
00807
00808 error += check_multiple_opts() ;
00809
00810
00811 if(!opt_checked)
00812 error += check_opts() ;
00813
00814
00815 error += check_required() ;
00816
00817
00818 if(error)
00819 {
00820 G_usage();
00821 return -1;
00822 }
00823
00824 if ( check_overwrite () )
00825 return -1;
00826
00827 return(0) ;
00828 }
00829
00830
00831 static int uses_new_gisprompt (void)
00832 {
00833 struct Option *opt ;
00834 char age[KEYLENGTH] ;
00835 char element[KEYLENGTH] ;
00836 char desc[KEYLENGTH] ;
00837
00838
00839
00840 if(n_opts)
00841 {
00842 opt= &first_option;
00843 while(opt != NULL)
00844 {
00845 if ( opt->gisprompt )
00846 {
00847 split_gisprompt (opt->gisprompt, age, element, desc) ;
00848 if (strcmp (age, "new") == 0)
00849 return 1;
00850 }
00851 opt=opt->next_opt;
00852 }
00853 }
00854
00855 return 0;
00856 }
00857
00878 int G_usage (void)
00879 {
00880 struct Option *opt ;
00881 struct Flag *flag ;
00882 char item[256];
00883 char *key_desc;
00884 int maxlen;
00885 int len, n;
00886 int new_prompt = 0;
00887
00888 new_prompt = uses_new_gisprompt();
00889
00890 if (!pgm_name)
00891 pgm_name = G_program_name ();
00892 if (!pgm_name)
00893 pgm_name = "??";
00894
00895 if (module_info.description) {
00896 fprintf (stderr, _("\nDescription:\n"));
00897 fprintf (stderr, " %s\n", module_info.description);
00898 }
00899 if (module_info.keywords) {
00900 fprintf (stderr, _("\nKeywords:\n"));
00901 fprintf (stderr, " %s\n", module_info.keywords);
00902 }
00903
00904 fprintf (stderr, _("\nUsage:\n "));
00905
00906 len = show(pgm_name,1);
00907
00908
00909
00910 if(n_flags)
00911 {
00912 item[0] = ' ';
00913 item[1] = '[';
00914 item[2] = '-';
00915 flag= &first_flag;
00916 for(n = 3; flag != NULL; n++, flag = flag->next_flag)
00917 item[n] = flag->key;
00918 item[n++] = ']';
00919 item[n] = 0;
00920 len=show(item,len);
00921 }
00922
00923 maxlen = 0;
00924 if(n_opts)
00925 {
00926 opt= &first_option;
00927 while(opt != NULL)
00928 {
00929 if (opt->key_desc != NULL)
00930 key_desc = opt->key_desc;
00931 else if (opt->type == TYPE_STRING)
00932 key_desc = "string";
00933 else
00934 key_desc = "value";
00935
00936 n = strlen (opt->key);
00937 if (n > maxlen) maxlen = n;
00938
00939 strcpy(item," ");
00940 if(!opt->required )
00941 strcat (item, "[");
00942 strcat (item, opt->key);
00943 strcat (item, "=");
00944 strcat (item, key_desc);
00945 if (opt->multiple)
00946 {
00947 strcat(item,"[,");
00948 strcat(item,key_desc);
00949 strcat(item,",...]");
00950 }
00951 if(!opt->required )
00952 strcat(item,"]") ;
00953
00954 len = show(item,len);
00955
00956 opt = opt->next_opt ;
00957 }
00958 }
00959 if (new_prompt)
00960 {
00961 strcpy (item, " [--overwrite]");
00962 len=show(item,len);
00963 }
00964
00965 fprintf (stderr, "\n");
00966
00967
00968
00969 if(n_flags || new_prompt)
00970 fprintf (stderr, _("\nFlags:\n"));
00971
00972 if(n_flags)
00973 {
00974 flag= &first_flag;
00975 while(flag != NULL)
00976 {
00977 fprintf(stderr," -%c ", flag->key) ;
00978
00979 if ( flag->label ) {
00980 fprintf (stderr, "%s\n", flag->label );
00981 if ( flag->description )
00982 fprintf (stderr, " %s\n", flag->description);
00983
00984 } else if ( flag->description ) {
00985 fprintf (stderr, "%s\n", flag->description);
00986 }
00987
00988 flag = flag->next_flag ;
00989 }
00990 }
00991
00992 if (new_prompt)
00993 fprintf(stderr," --o %s\n", _("Force overwrite of output files")) ;
00994
00995
00996
00997
00998 if(n_opts)
00999 {
01000 fprintf (stderr, _("\nParameters:\n"));
01001 opt= &first_option;
01002 while(opt != NULL)
01003 {
01004 fprintf (stderr, " %*s ", maxlen, opt->key );
01005
01006 if ( opt->label ) {
01007 fprintf (stderr, "%s\n", opt->label );
01008 if ( opt->description )
01009 fprintf (stderr, " %*s\n", maxlen, opt->description);
01010
01011 } else if ( opt->description ) {
01012 fprintf (stderr, "%s\n", opt->description);
01013 }
01014
01015 if(opt->options)
01016 show_options(maxlen, opt->options) ;
01017
01018
01019
01020
01021 if(opt->def)
01022 fprintf (stderr, _(" %*s default: %s\n"), maxlen, " ",
01023 opt->def) ;
01024
01025 if(opt->descs) {
01026 int i = 0;
01027
01028 while ( opt->opts[i] ) {
01029 fprintf (stderr, " %*s %s: ", maxlen, " ", opt->opts[i] );
01030
01031 if ( opt->descs[i] )
01032 fprintf (stderr, "%s\n", opt->descs[i] );
01033
01034 i++;
01035 }
01036 }
01037
01038 opt = opt->next_opt ;
01039 }
01040 }
01041
01042 return 0;
01043 }
01044
01045 void print_escaped_for_xml (FILE * fp, char * str) {
01046 for (;*str;str++) {
01047 switch (*str) {
01048 case '&':
01049 fputs("&", fp);
01050 break;
01051 case '<':
01052 fputs("<", fp);
01053 break;
01054 case '>':
01055 fputs(">", fp);
01056 break;
01057 default:
01058 fputc(*str, fp);
01059 }
01060 }
01061 }
01062
01063 static void G_usage_xml (void)
01064 {
01065 struct Option *opt ;
01066 struct Flag *flag ;
01067 char *type;
01068 char *s, *top;
01069 int i;
01070 char *encoding;
01071
01072
01073
01074 #if defined(HAVE_LANGINFO_H)
01075 encoding = nl_langinfo (CODESET);
01076 if ( !encoding || strlen( encoding ) == 0 ) {
01077 encoding = "UTF-8";
01078 }
01079 #else
01080 encoding = "UTF-8";
01081 #endif
01082
01083 if (!pgm_name)
01084 pgm_name = G_program_name ();
01085 if (!pgm_name)
01086 pgm_name = "??";
01087
01088 fprintf(stdout, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding);
01089 fprintf(stdout, "<!DOCTYPE task SYSTEM \"grass-interface.dtd\">\n");
01090
01091 fprintf(stdout, "<task name=\"%s\">\n", pgm_name);
01092
01093 if (module_info.label) {
01094 fprintf(stdout, "\t<label>\n\t\t");
01095 print_escaped_for_xml (stdout, module_info.label);
01096 fprintf(stdout, "\n\t</label>\n");
01097 }
01098
01099 if (module_info.description) {
01100 fprintf(stdout, "\t<description>\n\t\t");
01101 print_escaped_for_xml (stdout, module_info.description);
01102 fprintf(stdout, "\n\t</description>\n");
01103 }
01104
01105 if (module_info.keywords) {
01106 fprintf(stdout, "\t<keywords>\n\t\t");
01107 print_escaped_for_xml (stdout, module_info.keywords);
01108 fprintf(stdout, "\n\t</keywords>\n");
01109 }
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120 if(n_opts)
01121 {
01122 opt= &first_option;
01123 while(opt != NULL)
01124 {
01125
01126 switch (opt->type) {
01127 case TYPE_INTEGER:
01128 type = "integer";
01129 break ;
01130 case TYPE_DOUBLE:
01131 type = "float";
01132 break ;
01133 case TYPE_STRING:
01134 type = "string";
01135 break ;
01136 default:
01137 type = "string";
01138 break;
01139 }
01140 fprintf (stdout, "\t<parameter "
01141 "name=\"%s\" "
01142 "type=\"%s\" "
01143 "required=\"%s\" "
01144 "multiple=\"%s\">\n",
01145 opt->key,
01146 type,
01147 opt->required == YES ? "yes" : "no",
01148 opt->multiple == YES ? "yes" : "no");
01149
01150 if (opt->label) {
01151 fprintf(stdout, "\t\t<label>\n\t\t\t");
01152 print_escaped_for_xml(stdout, opt->label);
01153 fprintf(stdout, "\n\t\t</label>\n");
01154 }
01155
01156 if (opt->description) {
01157 fprintf(stdout, "\t\t<description>\n\t\t\t");
01158 print_escaped_for_xml(stdout, opt->description);
01159 fprintf(stdout, "\n\t\t</description>\n");
01160 }
01161
01162 if (opt->key_desc)
01163 {
01164 fprintf (stdout, "\t\t<keydesc>\n");
01165 top = G_calloc (strlen (opt->key_desc) + 1, 1);
01166 strcpy (top, opt->key_desc);
01167 s = strtok (top, ",");
01168 for (i = 1; s != NULL; i++)
01169 {
01170 fprintf (stdout, "\t\t\t<item order=\"%d\">", i);
01171 print_escaped_for_xml (stdout, s);
01172 fprintf (stdout, "</item>\n");
01173 s = strtok (NULL, ",");
01174 }
01175 fprintf (stdout, "\t\t</keydesc>\n");
01176 G_free (top);
01177 }
01178
01179 if (opt->gisprompt)
01180 {
01181 const char *atts[] = {"age", "element", "prompt", NULL};
01182 top = G_calloc (strlen (opt->gisprompt) + 1, 1);
01183 strcpy (top, opt->gisprompt);
01184 s = strtok (top, ",");
01185 fprintf (stdout, "\t\t<gisprompt ");
01186 for (i = 0; s != NULL && atts[i] != NULL; i++)
01187 {
01188 fprintf (stdout, "%s=\"%s\" ", atts[i], s);
01189 s = strtok (NULL, ",");
01190 }
01191 fprintf (stdout, "/>\n");
01192 G_free (top);
01193 }
01194
01195 if(opt->def) {
01196 fprintf(stdout, "\t\t\t<default>\n\t\t\t");
01197 print_escaped_for_xml(stdout, opt->def);
01198 fprintf(stdout, "\n\t\t\t</default>\n");
01199 }
01200
01201 if(opt->options) {
01202 i = 0;
01203 fprintf(stdout, "\t\t<values>\n");
01204 while ( opt->opts[i] ) {
01205 fprintf(stdout, "\t\t\t<value>\n");
01206 fprintf(stdout, "\t\t\t\t<name>");
01207 print_escaped_for_xml(stdout, opt->opts[i]);
01208 fprintf(stdout, "</name>\n");
01209 if(opt->descs && opt->opts[i]) {
01210 fprintf(stdout, "\t\t\t\t<description>");
01211 print_escaped_for_xml(stdout, opt->descs[i]);
01212 fprintf(stdout, "</description>");
01213 }
01214 fprintf(stdout, "\t\t\t</value>\n");
01215 i++;
01216 }
01217 fprintf(stdout, "\t\t</values>\n");
01218 }
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228 opt = opt->next_opt ;
01229 fprintf (stdout, "\t</parameter>\n");
01230 }
01231 }
01232
01233
01234 if(n_flags)
01235 {
01236 flag= &first_flag;
01237 while(flag != NULL)
01238 {
01239 fprintf (stdout, "\t<flag name=\"%c\">\n", flag->key);
01240
01241 if (flag->label) {
01242 fprintf(stdout, "\t\t<label>\n\t\t\t");
01243 print_escaped_for_xml(stdout, flag->label);
01244 fprintf(stdout, "\n\t\t</label>\n");
01245 }
01246
01247 if (flag->description) {
01248 fprintf(stdout, "\t\t<description>\n\t\t\t");
01249 print_escaped_for_xml(stdout, flag->description);
01250 fprintf(stdout, "\n\t\t</description>\n");
01251 }
01252 flag = flag->next_flag ;
01253 fprintf (stdout, "\t</flag>\n");
01254 }
01255 }
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266 fprintf(stdout, "</task>\n");
01267 }
01268
01269 static void G_usage_html (void)
01270 {
01271 struct Option *opt ;
01272 struct Flag *flag ;
01273 char *type;
01274 char *newbuf;
01275 int new_prompt = 0;
01276
01277 new_prompt = uses_new_gisprompt();
01278
01279 if (!pgm_name)
01280 pgm_name = G_program_name ();
01281 if (!pgm_name)
01282 pgm_name = "??";
01283
01284 fprintf(stdout, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
01285 fprintf(stdout, "<html>\n<head>\n");
01286 fprintf(stdout, "<title>%s</title>\n", pgm_name);
01287 fprintf(stdout, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n");
01288 fprintf(stdout, "<link rel=\"stylesheet\" href=\"grassdocs.css\" type=\"text/css\">\n");
01289 fprintf(stdout, "</head>\n");
01290 fprintf(stdout, "<body bgcolor=\"white\">\n\n");
01291 fprintf(stdout, "<img src=\"grass.smlogo.gif\" alt=\"GRASS logo\"><hr align=center size=6 noshade>\n\n");
01292 fprintf(stdout, "<h2>NAME</h2>\n");
01293 fprintf(stdout, "<em><b>%s</b></em> ", pgm_name);
01294
01295 if (module_info.description) {
01296 fprintf(stdout, " - ");
01297 fprintf(stdout, "%s", module_info.description);
01298 fprintf(stdout, "\n");
01299 }
01300
01301 fprintf(stdout, "<h2>KEYWORDS</h2>\n");
01302 if (module_info.keywords) {
01303 fprintf(stdout, "%s", module_info.keywords);
01304 fprintf(stdout, "\n");
01305 }
01306 fprintf(stdout, "<h2>SYNOPSIS</h2>\n");
01307 fprintf(stdout, "<b>%s</b><br>\n", pgm_name);
01308 fprintf(stdout, "<b>%s help</b><br>\n", pgm_name);
01309
01310 fprintf(stdout, "<b>%s</b>", pgm_name);
01311
01312
01313
01314
01315 if(n_flags)
01316 {
01317 flag= &first_flag;
01318 fprintf(stdout, " [-<b>");
01319 while(flag != NULL)
01320 {
01321 fprintf (stdout, "%c", flag->key);
01322 flag = flag->next_flag ;
01323 }
01324 fprintf(stdout, "</b>] ");
01325 }
01326 else
01327 fprintf(stdout, " ");
01328
01329 if(n_opts)
01330 {
01331 opt= &first_option;
01332
01333 while(opt != NULL)
01334 {
01335 if (opt->key_desc != NULL)
01336 type = opt->key_desc;
01337 else switch (opt->type) {
01338 case TYPE_INTEGER:
01339 type = "integer";
01340 break ;
01341 case TYPE_DOUBLE:
01342 type = "float";
01343 break ;
01344 case TYPE_STRING:
01345 type = "string";
01346 break ;
01347 default:
01348 type = "string";
01349 break;
01350 }
01351 if( !opt->required )
01352 fprintf(stdout," [");
01353 fprintf(stdout,
01354 "<b>%s</b>=<em>%s</em>", opt->key, type);
01355 if (opt->multiple)
01356 {
01357 fprintf(stdout,"[,<i>%s</i>,...]", type);
01358 }
01359 if( !opt->required )
01360 fprintf(stdout,"] ");
01361
01362 opt = opt->next_opt ;
01363 fprintf(stdout," ");
01364 }
01365 }
01366 if (new_prompt)
01367 {
01368 fprintf(stdout, " [--<b>overwrite</b>] ");
01369 }
01370 fprintf(stdout, "\n");
01371
01372
01373
01374 fprintf(stdout, "\n");
01375 if(n_flags || new_prompt)
01376 {
01377 flag= &first_flag;
01378 fprintf(stdout, "<h3>Flags:</h3>\n");
01379 fprintf(stdout, "<DL>\n");
01380 while(n_flags && flag != NULL )
01381 {
01382 fprintf (stdout, "<DT><b>-%c</b></DT>\n", flag->key);
01383
01384 if ( flag->label ) {
01385 fprintf(stdout, "<DD>");
01386 fprintf(stdout, "%s", flag->label);
01387 fprintf(stdout, "</DD>\n");
01388 }
01389
01390 if (flag->description) {
01391 fprintf(stdout, "<DD>");
01392 fprintf(stdout, "%s", flag->description);
01393 fprintf(stdout, "</DD>\n");
01394 }
01395
01396 flag = flag->next_flag ;
01397 fprintf (stdout, "\n");
01398 }
01399 if (new_prompt)
01400 {
01401 fprintf(stdout, "<DT><b>--overwrite</b></DT>\n");
01402 fprintf(stdout, "<DD>Force overwrite of output files</DD>");
01403 }
01404 fprintf(stdout, "</DL>\n");
01405 }
01406
01407 fprintf(stdout, "\n");
01408 if(n_opts)
01409 {
01410 opt= &first_option;
01411 fprintf(stdout, "<h3>Parameters:</h3>\n");
01412 fprintf(stdout, "<DL>\n");
01413
01414 while(opt != NULL)
01415 {
01416
01417 if (opt->key_desc != NULL)
01418 type = opt->key_desc;
01419 else switch (opt->type) {
01420 case TYPE_INTEGER:
01421 type = "integer";
01422 break ;
01423 case TYPE_DOUBLE:
01424 type = "float";
01425 break ;
01426 case TYPE_STRING:
01427 type = "string";
01428 break ;
01429 default:
01430 type = "string";
01431 break;
01432 }
01433 fprintf(stdout,
01434 "<DT><b>%s</b>=<em>%s", opt->key, type);
01435 if (opt->multiple) {
01436 fprintf(stdout,"[,<i>%s</i>,...]", type);
01437 }
01438 fprintf(stdout,"</em></DT>\n");
01439
01440 if ( opt->label ) {
01441 fprintf(stdout, "<DD>");
01442 fprintf(stdout, "%s", opt->label);
01443 fprintf(stdout, "</DD>\n");
01444 }
01445 if (opt->description) {
01446 fprintf(stdout, "<DD>");
01447 newbuf = G_str_replace(opt->description, "\n","<br>");
01448 if (newbuf) {
01449 fprintf(stdout, "%s", newbuf);
01450 G_free(newbuf);
01451 } else
01452 fprintf(stdout, "%s", opt->description);
01453 fprintf(stdout, "</DD>\n");
01454
01455 }
01456
01457 if(opt->options) {
01458 fprintf(stdout, "<DD>Options: <em>");
01459 fprintf(stdout, "%s", opt->options);
01460 fprintf(stdout, "</em></DD>\n");
01461 }
01462
01463 if(opt->def) {
01464 fprintf(stdout, "<DD>Default: <em>");
01465 fprintf(stdout, "%s", opt->def);
01466 fprintf(stdout, "</em></DD>\n");
01467 }
01468
01469 if(opt->descs) {
01470 int i = 0;
01471
01472 while ( opt->opts[i] ) {
01473 fprintf(stdout, "<DD><b>%s</b>: ", opt->opts[i]);
01474
01475 if ( opt->descs[i] )
01476 fprintf (stdout, "%s", opt->descs[i] );
01477
01478 fprintf(stdout, "</DD>\n");
01479
01480 i++;
01481 }
01482 }
01483
01484 opt = opt->next_opt ;
01485 fprintf (stdout, "\n");
01486 }
01487 fprintf(stdout, "</DL>\n");
01488 }
01489
01490 fprintf(stdout, "</body>\n</html>\n");
01491 }
01492
01493 static void generate_tcl(FILE *fp)
01494 {
01495 int new_prompt = uses_new_gisprompt();
01496 char *type;
01497 int optn;
01498
01499 fprintf(fp, "begin_dialog {%s} {\n", pgm_name);
01500 fprintf(fp, " label {%s}\n", module_info.label ? module_info.label : "");
01501 fprintf(fp, " desc {%s}\n", module_info.description ? module_info.description : "");
01502 fprintf(fp, " key {%s}\n", module_info.keywords ? module_info.keywords : "");
01503 fprintf(fp, "}\n");
01504
01505 optn = 1;
01506
01507 if (n_flags)
01508 {
01509 struct Flag *flag;
01510
01511 for (flag = &first_flag; flag; flag = flag->next_flag, optn++) {
01512 fprintf(fp, "add_flag %d {\n", optn);
01513 fprintf(fp, " name {%c}\n", flag->key);
01514 fprintf(fp, " desc {%s}\n", flag->description);
01515 fprintf(fp, " answer %d\n", flag->answer);
01516
01517
01518 fprintf(fp, " label {%s}\n", flag->label ? flag->label : "");
01519 fprintf(fp, " guisection {%s}\n", flag->guisection ? flag->guisection : "");
01520 fprintf(fp, "}\n");
01521 }
01522 }
01523
01524 if (n_opts)
01525 {
01526 struct Option *opt;
01527
01528 for (opt = &first_option; opt; opt = opt->next_opt, optn++)
01529 {
01530 if (opt->key_desc != NULL)
01531 type = opt->key_desc;
01532 else switch (opt->type)
01533 {
01534 case TYPE_INTEGER:
01535 type = "integer";
01536 break;
01537 case TYPE_DOUBLE:
01538 type = "float";
01539 break;
01540 case TYPE_STRING:
01541 type = "string";
01542 break;
01543 default:
01544 type = "string";
01545 break;
01546 }
01547
01548 fprintf(fp, "add_option %d {\n", optn);
01549 fprintf(fp, " name {%s}\n", opt->key);
01550 fprintf(fp, " type {%s}\n", type);
01551 fprintf(fp, " multi %d\n", opt->multiple);
01552 fprintf(fp, " desc {%s}\n", opt->description);
01553 fprintf(fp, " required %d\n", opt->required);
01554 fprintf(fp, " options {%s}\n", opt->options ? opt->options : "");
01555 fprintf(fp, " answer {%s}\n", opt->answer ? opt->answer : "");
01556 fprintf(fp, " prompt {%s}\n", opt->gisprompt ? opt->gisprompt : "");
01557
01558
01559 fprintf(fp, " label {%s}\n", opt->label ? opt->label : "");
01560 fprintf(fp, " guisection {%s}\n", opt->guisection ? opt->guisection : "");
01561 fprintf(fp, "}\n");
01562 }
01563 }
01564
01565 if (new_prompt)
01566 {
01567 fprintf(fp, "add_xflag %d {\n", optn);
01568 fprintf(fp, " name {overwrite}\n");
01569 fprintf(fp, " desc {Force overwrite of output files}\n");
01570 fprintf(fp, " answer %d\n", overwrite);
01571 fprintf(fp, " label {Overwrite}\n");
01572 fprintf(fp, " guisection {}\n");
01573 fprintf(fp, "}\n");
01574 optn++;
01575 }
01576
01577 fprintf(fp, "end_dialog %d\n", optn - 1);
01578 }
01579
01580
01581 static void G_gui (void)
01582 {
01583 FILE *fp;
01584
01585 if (!pgm_name)
01586 pgm_name = G_program_name ();
01587 if (!pgm_name)
01588 pgm_name = "??";
01589
01590 if (getenv("GRASS_DEBUG_GUI"))
01591 fp = popen("tee gui_dump.tcl | $GRASS_WISH", "w");
01592 else
01593 fp = popen("$GRASS_WISH", "w");
01594
01595 if (!fp)
01596 G_fatal_error("unable to spawn wish");
01597
01598 fprintf(fp, "source $env(GISBASE)/etc/gui.tcl\n");
01599
01600 generate_tcl(fp);
01601
01602 pclose(fp);
01603 }
01604
01605
01606 static void G_tcltk (void)
01607 {
01608 if (!pgm_name)
01609 pgm_name = G_program_name ();
01610 if (!pgm_name)
01611 pgm_name = "??";
01612
01613 generate_tcl(stdout);
01614 }
01615
01616
01617
01618
01619
01620
01621
01622
01623 static int show_options(int maxlen,char *str)
01624 {
01625 char buff[1024] ;
01626 char *p1, *p2 ;
01627 int totlen, len ;
01628
01629 strcpy(buff, str) ;
01630 fprintf (stderr, _(" %*s options: "), maxlen, " ") ;
01631 totlen = maxlen + 13 ;
01632 p1 = buff ;
01633 while( (p2 = G_index(p1, ',')) )
01634 {
01635 *p2 = '\0' ;
01636 len = strlen(p1) + 1 ;
01637 if ((len + totlen) > 76)
01638 {
01639 totlen = maxlen + 13 ;
01640 fprintf(stderr, "\n %*s", maxlen + 13, " ") ;
01641 }
01642 fprintf (stderr, "%s,", p1) ;
01643 totlen += len ;
01644 p1 = p2 + 1 ;
01645 }
01646 len = strlen(p1) ;
01647 if ((len + totlen) > 76 )
01648 fprintf(stderr, "\n %*s", maxlen + 13, " ") ;
01649 fprintf (stderr, "%s\n", p1) ;
01650
01651 return 0;
01652 }
01653
01654 static int show (const char *item, int len)
01655 {
01656 int n;
01657
01658 n = strlen (item)+(len>0);
01659 if (n + len > 76)
01660 {
01661 if (len)
01662 fprintf (stderr, "\n ");
01663 len = 0;
01664 }
01665 fprintf (stderr, "%s", item);
01666 return n+len;
01667 }
01668
01669 static int set_flag (int f)
01670 {
01671 struct Flag *flag ;
01672
01673
01674
01675 if(!n_flags)
01676 {
01677 fprintf(stderr,_("Sorry, <%c> is not a valid flag\n"), f) ;
01678 return(1) ;
01679 }
01680
01681
01682
01683 flag= &first_flag;
01684 while(flag != NULL)
01685 {
01686 if( flag->key == f)
01687 {
01688 flag->answer = 1 ;
01689 return(0) ;
01690 }
01691 flag = flag->next_flag ;
01692 }
01693
01694 fprintf(stderr,_("Sorry, <%c> is not a valid flag\n"), f) ;
01695 return(1) ;
01696 }
01697
01698
01699
01700
01701 static int contains (char *s, int c)
01702 {
01703 while(*s)
01704 {
01705 if(*s == c)
01706 return(1) ;
01707 s++ ;
01708 }
01709 return(0) ;
01710 }
01711
01712 static int set_option (char *string)
01713 {
01714 struct Option *at_opt = NULL;
01715 struct Option *opt = NULL;
01716 int got_one ;
01717 size_t key_len ;
01718 char the_key[KEYLENGTH] ;
01719 char *ptr ;
01720
01721 for(ptr=the_key; *string!='='; ptr++, string++)
01722 *ptr = *string ;
01723 *ptr = '\0' ;
01724 string++ ;
01725
01726
01727 got_one = 0 ;
01728 key_len = strlen(the_key) ;
01729 for(at_opt= &first_option; at_opt != NULL; at_opt=at_opt->next_opt)
01730 {
01731 if (strncmp(the_key,at_opt->key,key_len))
01732 continue ;
01733
01734 got_one++;
01735 opt = at_opt ;
01736
01737
01738
01739 if (strlen (at_opt->key) == key_len)
01740 {
01741 opt = at_opt;
01742 got_one = 1;
01743 break;
01744 }
01745 }
01746
01747 if (got_one > 1)
01748 {
01749 fprintf(stderr,_("Sorry, <%s=> is ambiguous\n"), the_key) ;
01750 return(1) ;
01751 }
01752
01753
01754 if(got_one == 0)
01755 {
01756 fprintf(stderr,_("Sorry, <%s> is not a valid parameter\n"),
01757 the_key) ;
01758 return(1) ;
01759 }
01760
01761
01762 if (opt->count++)
01763 {
01764 opt->answer = (char *)G_realloc (opt->answer,
01765 strlen (opt->answer)+strlen(string)+2);
01766 strcat (opt->answer, ",");
01767 strcat (opt->answer, string);
01768 }
01769 else
01770 opt->answer = G_store(string) ;
01771 return(0) ;
01772 }
01773
01774 static int check_opts (void)
01775 {
01776 struct Option *opt ;
01777 int error ;
01778 int ans ;
01779
01780 error = 0 ;
01781
01782 if(! n_opts)
01783 return(0) ;
01784
01785 opt= &first_option;
01786 while(opt != NULL)
01787 {
01788
01789
01790 if(opt->options && opt->answer)
01791 {
01792 if(opt->multiple == 0)
01793 error += check_an_opt(opt->key, opt->type,
01794 opt->options, opt->answer) ;
01795 else
01796 {
01797 for(ans=0; opt->answers[ans] != '\0'; ans++)
01798 error += check_an_opt(opt->key, opt->type,
01799 opt->options, opt->answers[ans]) ;
01800 }
01801 }
01802
01803
01804
01805 if(opt->checker)
01806 error += opt->checker(opt->answer) ;
01807
01808 opt = opt->next_opt ;
01809 }
01810 return(error) ;
01811 }
01812
01813 static int check_an_opt (char *key, int type, char *options, char *answer)
01814 {
01815 int error ;
01816
01817 error = 0 ;
01818
01819 switch(type)
01820 {
01821 case TYPE_INTEGER:
01822 error = check_int(answer,options) ;
01823 break ;
01824 case TYPE_DOUBLE:
01825 error = check_double(answer,options) ;
01826 break ;
01827 case TYPE_STRING:
01828 error = check_string(answer,options) ;
01829 break ;
01830
01831
01832
01833
01834
01835 }
01836 switch(error)
01837 {
01838 case 0:
01839 break ;
01840 case BAD_SYNTAX:
01841 fprintf(stderr,_("\nError: illegal range syntax for parameter <%s>\n"),
01842 key) ;
01843 fprintf(stderr,_(" Presented as: %s\n"), options) ;
01844 break ;
01845 case OUT_OF_RANGE:
01846 fprintf(stderr,_("\nError: value <%s> out of range for parameter <%s>\n"),
01847 answer, key) ;
01848 fprintf(stderr,_(" Legal range: %s\n"), options) ;
01849 break ;
01850 case MISSING_VALUE:
01851 fprintf(stderr,_("\nError: Missing value for parameter <%s>\n"),
01852 key) ;
01853 }
01854 return(error) ;
01855 }
01856
01857 static int check_int (char *ans, char *opts)
01858 {
01859 int d, lo, hi;
01860
01861 if (1 != sscanf(ans,"%d", &d))
01862 return(MISSING_VALUE) ;
01863
01864 if (contains(opts, '-'))
01865 {
01866 if (2 != sscanf(opts,"%d-%d",&lo, &hi))
01867 return(BAD_SYNTAX) ;
01868 if (d < lo || d > hi)
01869 return(OUT_OF_RANGE) ;
01870 else
01871 return(0) ;
01872 }
01873 else if (contains(opts, ','))
01874 {
01875 for(;;)
01876 {
01877 if (1 != sscanf(opts,"%d",&lo))
01878 return(BAD_SYNTAX) ;
01879 if (d == lo)
01880 return(0) ;
01881 while(*opts != '\0' && *opts != ',')
01882 opts++ ;
01883 if (*opts == '\0')
01884 return(OUT_OF_RANGE) ;
01885 if (*(++opts) == '\0')
01886 return(OUT_OF_RANGE) ;
01887 }
01888 }
01889 else
01890 {
01891 if (1 != sscanf(opts,"%d",&lo))
01892 return(BAD_SYNTAX) ;
01893 if (d == lo)
01894 return(0) ;
01895 return(OUT_OF_RANGE) ;
01896 }
01897 }
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925 static int check_double (char *ans, char *opts)
01926 {
01927 double d, lo, hi;
01928
01929 if (1 != sscanf(ans,"%lf", &d))
01930 return(MISSING_VALUE) ;
01931
01932 if (contains(opts, '-'))
01933 {
01934 if (2 != sscanf(opts,"%lf-%lf",&lo, &hi))
01935 return(BAD_SYNTAX) ;
01936 if (d < lo || d > hi)
01937 return(OUT_OF_RANGE) ;
01938 else
01939 return(0) ;
01940 }
01941 else if (contains(opts, ','))
01942 {
01943 for(;;)
01944 {
01945 if (1 != sscanf(opts,"%lf",&lo))
01946 return(BAD_SYNTAX) ;
01947 if (d == lo)
01948 return(0) ;
01949 while(*opts != '\0' && *opts != ',')
01950 opts++ ;
01951 if (*opts == '\0')
01952 return(OUT_OF_RANGE) ;
01953 if (*(++opts) == '\0')
01954 return(OUT_OF_RANGE) ;
01955 }
01956 }
01957 else
01958 {
01959 if (1 != sscanf(opts,"%lf",&lo))
01960 return(BAD_SYNTAX) ;
01961 if (d == lo)
01962 return(0) ;
01963 return(OUT_OF_RANGE) ;
01964 }
01965 }
01966
01967 static int check_string (char *ans, char *opts)
01968 {
01969 if (*opts == '\0')
01970 return(0) ;
01971
01972 if (contains(opts, ','))
01973 {
01974 for(;;)
01975 {
01976 if ((! strncmp(ans, opts, strlen(ans)))
01977 && ( *(opts+strlen(ans)) == ','
01978 || *(opts+strlen(ans)) == '\0'))
01979 return(0) ;
01980 while(*opts != '\0' && *opts != ',')
01981 opts++ ;
01982 if (*opts == '\0')
01983 return(OUT_OF_RANGE) ;
01984 if (*(++opts) == '\0')
01985 return(OUT_OF_RANGE) ;
01986 }
01987 }
01988 else
01989 {
01990 if (! strcmp(ans, opts))
01991 return(0) ;
01992 return(OUT_OF_RANGE) ;
01993 }
01994 }
01995
01996 static int check_required (void)
01997 {
01998 struct Option *opt ;
01999 int err ;
02000
02001 err = 0 ;
02002
02003 if(! n_opts)
02004 return(0) ;
02005
02006 opt= &first_option;
02007 while(opt != NULL)
02008 {
02009 if(opt->required && opt->answer == NULL)
02010 {
02011 fprintf(stderr,_("\nERROR: Required parameter <%s> not set:\n (%s).\n"),
02012 opt->key, opt->description) ;
02013 err++ ;
02014 }
02015 opt = opt->next_opt ;
02016 }
02017
02018 return(err) ;
02019 }
02020
02021 static int split_opts (void)
02022 {
02023 struct Option *opt ;
02024 char *ptr1 ;
02025 char *ptr2 ;
02026 int allocated ;
02027 int ans_num ;
02028 int len ;
02029
02030
02031 if(! n_opts)
02032 return 0;
02033
02034 opt= &first_option;
02035 while(opt != NULL)
02036 {
02037 if ((opt->answer != NULL))
02038 {
02039
02040 allocated = 10 ;
02041 opt->answers = (char **)G_malloc(allocated * sizeof(char *)) ;
02042
02043 ans_num = 0 ;
02044 ptr1 = opt->answer ;
02045 opt->answers[ans_num] = NULL ;
02046
02047 for(;;)
02048 {
02049 for(len=0, ptr2=ptr1; *ptr2 != '\0' && *ptr2 != ','; ptr2++, len++)
02050 ;
02051
02052 if (len > 0)
02053 {
02054 opt->answers[ans_num]=(char *)G_malloc(len+1) ;
02055 G_copy(opt->answers[ans_num], ptr1, len) ;
02056 opt->answers[ans_num][len] = 0;
02057
02058 ans_num++ ;
02059
02060 if(ans_num >= allocated)
02061 {
02062 allocated += 10 ;
02063 opt->answers =
02064 (char **)G_realloc((char *)opt->answers,
02065 allocated * sizeof(char *)) ;
02066 }
02067
02068 opt->answers[ans_num] = NULL ;
02069 }
02070
02071 if(*ptr2 == '\0')
02072 break ;
02073
02074 ptr1 = ptr2+1 ;
02075
02076 if(*ptr1 == '\0')
02077 break ;
02078 }
02079 }
02080 opt = opt->next_opt ;
02081 }
02082
02083 return 0;
02084 }
02085
02086 static int check_multiple_opts (void)
02087 {
02088 struct Option *opt ;
02089 char *ptr ;
02090 int n_commas ;
02091 int n ;
02092 int error ;
02093
02094 if(! n_opts)
02095 return (0) ;
02096
02097 error = 0 ;
02098 opt= &first_option;
02099 while(opt != NULL)
02100 {
02101 if ((opt->answer != NULL) && (opt->key_desc != NULL))
02102 {
02103
02104 n_commas = 1 ;
02105 for(ptr=opt->key_desc; *ptr!='\0'; ptr++)
02106 if (*ptr == ',')
02107 n_commas++ ;
02108
02109 for(n=0;opt->answers[n] != '\0';n++)
02110 ;
02111
02112 if(n % n_commas)
02113 {
02114 fprintf(stderr,_("\nError: option <%s> must be provided in multiples of %d\n"),
02115 opt->key, n_commas) ;
02116 fprintf(stderr,_(" You provided %d items:\n"), n) ;
02117 fprintf(stderr," %s\n", opt->answer) ;
02118 error++ ;
02119 }
02120 }
02121 opt = opt->next_opt ;
02122 }
02123 return(error) ;
02124 }
02125
02126
02127 static int check_overwrite (void)
02128 {
02129 struct Option *opt ;
02130 char age[KEYLENGTH] ;
02131 char element[KEYLENGTH] ;
02132 char desc[KEYLENGTH] ;
02133 int error = 0;
02134 char *overstr;
02135 int over;
02136
02137 if(! n_opts)
02138 return (0) ;
02139
02140 over = 0;
02141
02142 if ( (overstr = G__getenv ( "OVERWRITE" )) ) {
02143 over = atoi ( overstr );
02144 }
02145
02146
02147 if ( (overstr = getenv ( "GRASS_OVERWRITE" )) ) {
02148 if (atoi ( overstr ))
02149 over = 1;
02150 }
02151
02152 if ( overwrite || over ) {
02153 module_info.overwrite = 1;
02154
02155 putenv("GRASS_OVERWRITE=1");
02156
02157 return error;
02158 }
02159
02160 opt= &first_option;
02161 while(opt != NULL)
02162 {
02163 if ((opt->answer != NULL) && (opt->gisprompt != NULL))
02164 {
02165 split_gisprompt (opt->gisprompt, age, element, desc);
02166
02167 if ( strcmp(age,"new") == 0 ) {
02168 if ( G_find_file (element, opt->answer, G_mapset()) )
02169 {
02170 if ( !overwrite && !over ) {
02171 fprintf(stderr,_("Error: option <%s>: <%s> exists.\n"),
02172 opt->key, opt->answer );
02173
02174 error = 1;
02175 }
02176 }
02177 }
02178 }
02179 opt = opt->next_opt ;
02180 }
02181
02182 return(error) ;
02183 }
02184
02185 static int interactive( char *command)
02186 {
02187 struct Item *item ;
02188
02189
02190
02191 if(!n_items)
02192 {
02193 fprintf(stderr,"Programmer error: no flags or options\n") ;
02194 exit(EXIT_FAILURE) ;
02195 }
02196
02197 for (item= &first_item ;;)
02198 {
02199 if (item->flag)
02200 interactive_flag(item->flag) ;
02201 else if (item->option)
02202 interactive_option(item->option) ;
02203 else
02204 break ;
02205
02206 item=item->next_item ;
02207
02208 if (item == NULL)
02209 break ;
02210 }
02211
02212 return 0;
02213 }
02214
02215 static int interactive_flag( struct Flag *flag )
02216 {
02217 char buff[1024] ;
02218 fprintf(stderr, _("\nFLAG: Set the following flag?\n")) ;
02219 sprintf(buff," %s?", flag->description) ;
02220 flag->answer = G_yes(buff, 0) ;
02221
02222 return 0;
02223 }
02224
02225 static int interactive_option(struct Option *opt )
02226 {
02227 char buff[1024],*bptr ;
02228 char buff2[1024] ;
02229 int set_one ;
02230 int no_prompt ;
02231
02232 fprintf(stderr,_("\nOPTION: %s\n"), opt->description) ;
02233 fprintf(stderr,_(" key: %s\n"), opt->key) ;
02234 if (opt->key_desc)
02235 fprintf(stderr,_(" format: %s\n"), opt->key_desc) ;
02236 if (opt->def)
02237 fprintf(stderr,_(" default: %s\n"), opt->def) ;
02238 fprintf(stderr,_("required: %s\n"), opt->required ? "YES" : "NO") ;
02239 if (opt->multiple)
02240 fprintf(stderr,_("multiple: %s\n"), opt->multiple ? "YES" : "NO") ;
02241 if (opt->options)
02242 fprintf(stderr,_(" options: %s\n"), opt->options) ;
02243
02244
02245
02246
02247 set_one = 0 ;
02248 for(;;)
02249 {
02250 *buff='\0' ;
02251 if(opt->gisprompt)
02252 no_prompt = gis_prompt(opt, buff) ;
02253 else
02254 no_prompt = -1;
02255 if (no_prompt)
02256 {
02257 fprintf(stderr,_("enter option > ")) ;
02258 if(fgets(buff,1024,stdin) == 0) exit(EXIT_SUCCESS); ;
02259 bptr = buff;
02260 while(*bptr) {if(*bptr=='\n') *bptr='\0'; bptr++;}
02261
02262 }
02263
02264 if(strlen(buff) != 0)
02265 {
02266 if(opt->options)
02267
02268 {
02269 if (check_an_opt(opt->key, opt->type, opt->options, buff))
02270 {
02271 if (G_yes(_(" Try again? "), 1))
02272 continue ;
02273 else
02274 exit(EXIT_FAILURE) ;
02275 }
02276 }
02277 if (opt->checker)
02278 if (opt->checker(buff))
02279 {
02280 fprintf(stderr,_("Sorry, %s is not accepted.\n"), buff) ;
02281 *buff = '\0' ;
02282 if (G_yes(_(" Try again? "), 1))
02283 continue ;
02284 else
02285 exit(EXIT_FAILURE) ;
02286 }
02287
02288 sprintf(buff2,"%s=%s", opt->key, buff) ;
02289 if(! opt->gisprompt)
02290 {
02291 fprintf(stderr,_("\nYou have chosen:\n %s\n"), buff2) ;
02292 if (G_yes(_("Is this correct? "), 1))
02293 {
02294 set_option(buff2) ;
02295 set_one++ ;
02296 }
02297 }
02298 else
02299 {
02300 set_option(buff2) ;
02301 set_one++ ;
02302 }
02303 }
02304
02305 if ((strlen(buff) == 0) && opt->required && (set_one == 0))
02306 exit(EXIT_FAILURE) ;
02307 if ((strlen(buff) == 0) && (set_one > 0) && opt->multiple )
02308 break ;
02309 if ((strlen(buff) == 0) && !opt->required)
02310 break ;
02311 if ((set_one == 1) && !opt->multiple)
02312 break ;
02313 }
02314 return(0) ;
02315 }
02316
02317 static int split_gisprompt (const char *gisprompt, char *age, char *element, char *desc)
02318 {
02319 const char *ptr1 ;
02320 char *ptr2 ;
02321
02322 for(ptr1=gisprompt,ptr2=age; *ptr1!='\0'; ptr1++, ptr2++)
02323 {
02324 if (*ptr1 == ',')
02325 break ;
02326 *ptr2 = *ptr1 ;
02327 }
02328 *ptr2 = '\0' ;
02329
02330 for(ptr1++, ptr2=element; *ptr1!='\0'; ptr1++, ptr2++)
02331 {
02332 if (*ptr1 == ',')
02333 break ;
02334 *ptr2 = *ptr1 ;
02335 }
02336 *ptr2 = '\0' ;
02337
02338 for(ptr1++, ptr2=desc; *ptr1!='\0'; ptr1++, ptr2++)
02339 {
02340 if (*ptr1 == ',')
02341 break ;
02342 *ptr2 = *ptr1 ;
02343 }
02344 *ptr2 = '\0' ;
02345
02346 return 0 ;
02347 }
02348
02349 static int gis_prompt (struct Option *opt, char *buff)
02350 {
02351 char age[KEYLENGTH] ;
02352 char element[KEYLENGTH] ;
02353 char desc[KEYLENGTH] ;
02354 char *ptr1 ;
02355
02356 split_gisprompt ( opt->gisprompt, age, element, desc );
02357
02358
02359
02360 if (opt->answer)
02361 G_set_ask_return_msg (_("to accept the default"));
02362 if (! strcmp("old",age))
02363 {
02364 ptr1 = G_ask_old("", buff, element, desc) ;
02365 if (ptr1)
02366 {
02367 strcpy (buff, G_fully_qualified_name(buff,ptr1));
02368 }
02369 }
02370 else if (! strcmp("new",age))
02371 ptr1 = G_ask_new("", buff, element, desc) ;
02372 else if (! strcmp("mapset",age))
02373 ptr1 = G_ask_in_mapset("", buff, element, desc) ;
02374 else if (! strcmp("any",age))
02375 ptr1 = G_ask_any("", buff, element, desc, 1) ;
02376 else if (! strcmp("old_file",age))
02377 ptr1 = G_ask_old_file("", buff, element, desc) ;
02378 else if (! strcmp("new_file",age))
02379 ptr1 = G_ask_new_file("", buff, element, desc) ;
02380 else if (! strcmp("color",age))
02381
02382
02383 return -1;
02384 else
02385 {
02386 fprintf(stderr,"\nPROGRAMMER ERROR: first item in gisprompt is <%s>\n", age) ;
02387 fprintf(stderr," Must be either new, old, mapset, any, old_file, new_file, or color\n") ;
02388 return -1;
02389 }
02390 if (ptr1 == '\0')
02391 *buff = '\0';
02392
02393 return 0;
02394 }
02395
02396 char *G_recreate_command (void)
02397 {
02398 static char *buff;
02399 char flg[4] ;
02400 char *cur;
02401 const char *tmp;
02402 struct Flag *flag ;
02403 struct Option *opt ;
02404 int n , len, slen;
02405 int nalloced = 0;
02406
02407 G_debug ( 3, "G_recreate_command()");
02408
02409
02410
02411 buff = G_calloc (1024, sizeof(char));
02412 nalloced += 1024;
02413 tmp = G_program_name();
02414 len = strlen (tmp);
02415 if (len >= nalloced)
02416 {
02417 nalloced += (1024 > len) ? 1024 : len + 1;
02418 buff = G_realloc (buff, nalloced);
02419 }
02420 cur = buff;
02421 strcpy (cur, tmp);
02422 cur += len;
02423
02424 if(n_flags)
02425 {
02426 flag= &first_flag;
02427 while(flag != '\0')
02428 {
02429 if( flag->answer == 1 )
02430 {
02431 flg[0] = ' '; flg[1] = '-'; flg[2] = flag->key; flg[3] = '\0';
02432 slen = strlen (flg);
02433 if (len + slen >= nalloced)
02434 {
02435 nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
02436 buff = G_realloc (buff, nalloced);
02437 cur = buff + len;
02438 }
02439 strcpy (cur, flg);
02440 cur += slen;
02441 len += slen;
02442 }
02443 flag = flag->next_flag ;
02444 }
02445 }
02446
02447 opt= &first_option;
02448 while(opt != '\0')
02449 {
02450 if ( opt->answer != '\0' && opt->answers[0] != NULL )
02451 {
02452 slen = strlen (opt->key) + strlen (opt->answers[0]) + 4;
02453 if (len + slen >= nalloced)
02454 {
02455 nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
02456 buff = G_realloc (buff, nalloced);
02457 cur = buff + len;
02458 }
02459 strcpy (cur, " ");
02460 cur++;
02461 strcpy (cur, opt->key);
02462 cur = strchr (cur, '\0');
02463 strcpy (cur, "=");
02464 cur++;
02465 if ( opt->type == TYPE_STRING ) {
02466 strcpy (cur, "\"");
02467 cur++;
02468 }
02469 strcpy (cur, opt->answers[0]);
02470 cur = strchr (cur, '\0');
02471 len = cur - buff;
02472 for(n=1; opt->answers[n] != NULL && opt->answers[n] != '\0';n++)
02473 {
02474 if ( opt->answers[n] == NULL ) break;
02475 slen = strlen (opt->answers[n]) + 2;
02476 if (len + slen >= nalloced)
02477 {
02478 nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
02479 buff = G_realloc (buff, nalloced);
02480 cur = buff + len;
02481 }
02482 strcpy (cur, ",");
02483 cur++;
02484 strcpy (cur, opt->answers[n]);
02485 cur = strchr(cur, '\0');
02486 len = cur - buff;
02487 }
02488 if ( opt->type == TYPE_STRING ) {
02489 strcpy (cur, "\"");
02490 cur++;
02491 len = cur - buff;
02492 }
02493 }
02494 opt = opt->next_opt ;
02495 }
02496
02497 return(buff) ;
02498 }
02499