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