ask.c

Go to the documentation of this file.
00001 /****************************************************************
00002 * These routines prompt the user for names of GIS data files
00003 *
00004 * G_ask_new           (prompt, name, element, desc)
00005 * G_ask_old           (prompt, name, element, desc)
00006 * G_ask_any           (prompt, name, element, desc, warn)
00007 * G_ask_in_mapset     (prompt, name, element, desc)
00008 * G_ask_new_file      (prompt, name, element, desc)
00009 * G_ask_old_file      (prompt, name, element, desc)
00010 *
00011 * G_ask_new_ext       (prompt, name, element, desc, option, lister)
00012 * G_ask_old_ext       (prompt, name, element, desc, option, lister)
00013 * G_ask_any_ext       (prompt, name, element, desc, warn, option, lister)
00014 * G_ask_in_mapset_ext (prompt, name, element, desc, option, lister)
00015 *
00016 *   char *prompt      prompt to be printed. can be "" in which
00017 *                     case an appropriate prompt will be printed.
00018 *   char *name        buffer to hold the name input by the user
00019 *   char *element     GIS data element - "cell", "vect", etc.
00020 *   char *desc        a description of element.  Used for prompting
00021 *                     and listing. Will be set to element if given as ""
00022 *                     (eg, if element is "vect", set desc = "vector")
00023 *   char *option      list option. a description of the option.
00024 *                     (eg, "with utms" will prompt as follows:
00025 *                     list -f for a list with utms)
00026 *   int (*lister)()   subroutine to return text for -f option.
00027 *
00028 *
00029 * G_ask_new() requires the user to enter the name of a file
00030 *             which does not exist in the current mapset
00031 *             (but which may exist in other mapsets).
00032 *
00033 * G_ask_old() requires the user to enter the name of a file
00034 *             which already exists.
00035 *
00036 * G_ask_in_mapset() requires the user to enter the name of a file
00037 *                   which exists in the current mapset
00038 *
00039 * G_ask_any() accepts any legal filename. Optionally warns user
00040 *             if the file exists in the current mapset.
00041 *
00042 * G_ask_new_file() requires the user to enter the name of a new file.
00043 *
00044 * G_ask_old_file() requires the user to enter the name of any existing file.
00045 *
00046 * returns:
00047 *   char *    mapset where file was found, or
00048 *             mapset where file is to be created
00049 *   NULL      user hit RETURN to cancel the request
00050 *
00051 * note:
00052 *  These routines have a 'list' function built in.  If a list -f
00053 *  option is also desired, create a lister() routine, and
00054 *  use G_ask_xxx_ext(). The lister() routine will be called as
00055 *  follows:
00056 *
00057 *       lister (name, mapset, buf)
00058 *
00059 *       char *name        name of file 
00060 *       char *mapset      mapset to where file lives
00061 *       char *buf         buffer to hold description.
00062 *                         lister() should copy into buf.
00063 *                         buf will be large (about 400 bytes)
00064 *                         but only first 60 chars will be displayed
00065 *
00066 *
00067 *  for each mapset, lister() will be called once with
00068 *  name set to the empty string "" in order to get an title for the
00069 *  list.  Set buf to null to suppress title, otherwise copy title
00070 *  into buf.  The title will start above the text for the files.
00071 *
00072 *  then for each file in each mapset, lister() will be called
00073 *  to obtain infomation about the file.
00074 *
00075 * also:
00076 *   G_set_ask_return_msg (msg) char *msg;
00077 *   can be used to change the hit RETURN to cancel request message
00078 *   displayed during the ask prompting.
00079 *
00080 *   G_get_ask_return_msg() will return the msg.
00081 ******************************************************************/
00082 #include <string.h>
00083 #include <stdlib.h>
00084 #include <unistd.h>
00085 #include "gis.h"
00086 #include "glocale.h"
00087 
00088 /*
00089  * OLD references any mapset
00090  * NEW, ANY, PRJ are for the current mapset only
00091  *
00092  * OLD means must exist in some mapset
00093  * NEW means must not exist in current mapset
00094  * ANY means just get a name. If file exists, (optionally) warn user.
00095  * PRJ means must exist in current mapset
00096  */
00097 
00098 #define OLD 0
00099 #define NEW 1
00100 #define PRJ 2
00101 #define ANY 3
00102 #define ANY_NW 4
00103 #define OLD_FILE 5
00104 #define NEW_FILE 6
00105 
00106 static char *ask_return_msg = 0 ;
00107 static char clear_return_msg = 0 ;
00108 static int (*no_lister)() = 0 ;
00109 static int parselist(char *, int , char *);
00110 static char *ask( char *,char *,char *,char *,char *, int (*)(),int );
00111 
00112 
00130 char *G_ask_new (prompt, name, element, desc)
00131     char *prompt;
00132     char *name;
00133     char *element;
00134     char *desc;
00135 {
00136     return ask (prompt, name, element, desc, (char *) NULL, no_lister, NEW);
00137 }
00138 
00139 char *G_ask_new_ext (prompt, name, element, desc, option, lister)
00140     char *prompt;
00141     char *name;
00142     char *element;
00143     char *desc;
00144     char *option;
00145     int (*lister)();
00146 {
00147     return ask (prompt, name, element, desc, option, lister, NEW);
00148 }
00149 
00150 
00168 char *G_ask_old (prompt, name, element, desc)
00169     char *prompt;
00170     char *name;
00171     char *element;
00172     char *desc;
00173 {
00174     return ask (prompt, name, element, desc, (char *) NULL, no_lister, OLD);
00175 }
00176 
00177 char *G_ask_old_ext (prompt, name, element, desc, option, lister)
00178     char *prompt;
00179     char *name;
00180     char *element;
00181     char *desc;
00182     char *option;
00183     int (*lister)();
00184 {
00185     return ask (prompt, name, element, desc, option, lister, OLD);
00186 }
00187 
00188 
00206 char *G_ask_any (prompt, name, element, desc, warn)
00207     char *prompt;
00208     char *name;
00209     char *element;
00210     char *desc;
00211 {
00212     return ask (prompt, name, element, desc, (char *) NULL, no_lister, warn?ANY:ANY_NW);
00213 }
00214 
00215 char *G_ask_any_ext (prompt, name, element, desc, warn, option, lister)
00216     char *prompt;
00217     char *name;
00218     char *element;
00219     char *desc;
00220     char *option;
00221     int (*lister)();
00222 {
00223     return ask (prompt, name, element, desc, option, lister, warn?ANY:ANY_NW);
00224 }
00225 
00226 
00244 char *
00245 G_ask_in_mapset (prompt, name, element, desc)
00246     char *prompt;
00247     char *name;
00248     char *element;
00249     char *desc;
00250 {
00251     return ask (prompt, name, element, desc, (char *) NULL, no_lister, PRJ);
00252 }
00253 
00254 char *
00255 G_ask_in_mapset_ext (prompt, name, element, desc, option, lister)
00256     char *prompt;
00257     char *name;
00258     char *element;
00259     char *desc;
00260     char *option;
00261     int (*lister)();
00262 {
00263     return ask (prompt, name, element, desc, option, lister, PRJ);
00264 }
00265 
00266 
00279 char *
00280 G_ask_new_file (prompt, name, element, desc)
00281     char *prompt;
00282     char *name;
00283     char *element;
00284     char *desc;
00285 {
00286     /* element is a dummy parameter for this function */
00287     return ask (prompt, name, element, desc, (char *) NULL, no_lister, NEW_FILE);
00288 }
00289 
00290 /* do we need this function?
00291 char *
00292 G_ask_new_file_ext (prompt, name, element, desc, option, lister)
00293     char *prompt;
00294     char *name;
00295     char *element;
00296     char *desc;
00297     char *option;
00298     int (*lister)();
00299 {
00300     return ask (prompt, name, element, desc, option, lister, NEW_FILE);
00301 }
00302 */
00303 
00304 
00317 char *
00318 G_ask_old_file (prompt, name, element, desc)
00319     char *prompt;
00320     char *name;
00321     char *element;
00322     char *desc;
00323 {
00324     /* element is a dummy parameter for this function */
00325     return ask (prompt, name, element, desc, (char *) NULL, no_lister, OLD_FILE);
00326 }
00327 
00328 /* do we need this function?
00329 char *
00330 G_ask_old_file_ext (prompt, name, element, desc, option, lister)
00331     char *prompt;
00332     char *name;
00333     char *element;
00334     char *desc;
00335     char *option;
00336     int (*lister)();
00337 {
00338     return ask (prompt, name, element, desc, option, lister, OLD_FILE);
00339 }
00340 */
00341 
00342 
00354 int G_set_ask_return_msg (char *msg)
00355 {
00356     if (ask_return_msg) free (ask_return_msg);
00357     ask_return_msg = G_store (msg);
00358     clear_return_msg = 0;
00359 
00360     return 0;
00361 }
00362 
00363 
00374 char *G_get_ask_return_msg()
00375 {
00376     static char none[80];
00377         strcpy(none,_("to cancel request"));
00378     return (ask_return_msg == NULL ? none : ask_return_msg);
00379 }
00380 
00381 static char *ask (
00382     char *prompt,
00383     char *name,
00384     char *element,
00385     char *desc,
00386     char *option,
00387     int (*lister)(),
00388     int type)
00389 {
00390     char tmapset[256];
00391     char xname[512], xmapset[512];
00392     int  name_is_qualified;
00393     int  ok;
00394     char tprompt[256];
00395     char input[256];
00396     char *mapset;
00397     char *cur_mapset;
00398 
00399     G__check_gisinit();
00400 
00401     fflush (stdout);
00402 /* RETURN msg */
00403     if(clear_return_msg)
00404     {
00405         free (ask_return_msg);
00406         ask_return_msg = 0;
00407     }
00408     clear_return_msg = ask_return_msg ? 1 : 0;
00409 
00410 /* make sure option is valid */
00411     if (lister && (option == 0 || *option == 0))
00412         lister = 0;
00413 
00414 /* set name to NO NAME at outset */
00415     *name = 0;
00416 
00417 /*
00418  * if element description not given, make it the same as the
00419  * element name
00420  */
00421     if (desc == 0 || *desc == 0)
00422             desc = element;
00423 
00424 /*
00425  * if no prompt is given, build an approriate prompt
00426  */
00427     if (prompt == 0 || *prompt == 0)
00428     {
00429         switch (type)
00430         {
00431         case NEW:
00432         case NEW_FILE:
00433             sprintf(prompt = tprompt,_("Enter a new %s file name"), desc);
00434             break;
00435         case OLD:
00436         case PRJ:
00437         case OLD_FILE:
00438             sprintf(prompt = tprompt,_("Enter the name of an existing %s file"), desc);
00439             break;
00440         default:
00441             sprintf(prompt = tprompt,_("Enter %s file name"), desc);
00442             break;
00443         }
00444     }
00445 
00446 /*
00447  * get the current mapset name
00448  */
00449     cur_mapset = G_mapset();
00450 
00451     while (1)
00452     {
00453 /*
00454  * print the prompt and input the request
00455  */
00456         do{
00457             fprintf (stderr,"\n%s\n", prompt);
00458             /* no listing function implemented for old_file and new_file */
00459             if (type != OLD_FILE && type != NEW_FILE)
00460                 fprintf (stderr,_("Enter 'list' for a list of existing %s files\n"), desc);
00461             if (lister)
00462             {
00463                 fprintf (stderr,_("Enter 'list -f' for "));
00464                 if (option && *option)
00465                     fprintf (stderr,_("a list %s"), option);
00466                 else
00467                     fprintf (stderr,_("an extended list"));
00468                 fprintf (stderr,"\n");
00469             }
00470 
00471             fprintf (stderr,_("Hit RETURN %s\n"), G_get_ask_return_msg());
00472             fprintf (stderr,"> ");
00473         }
00474         while (!G_gets(input));
00475 
00476         G_strip (input);
00477         fprintf (stderr,"<%s>\n", input);
00478 
00479 /*
00480  * if the user just hit return (or blanks only)
00481  * return NULL
00482  */
00483         if (*input == 0)
00484             return 0;
00485 
00486         if (type == OLD_FILE || type == NEW_FILE)
00487         {
00488             int exist;
00489 
00490             exist = (access(input, 0) == 0);
00491             if (type == OLD_FILE && !exist)
00492             {
00493                 fprintf (stderr,_("\n** %s - not found **\n"), input);
00494                 continue;
00495             }
00496             if (type == NEW_FILE && exist)
00497             {
00498                 char question[200];
00499                 sprintf(question,
00500                         _("\n** %s exists. ok to overwrite? "), input);
00501                 if (!G_yes (question,0))
00502                         continue;
00503             }
00504             strcpy (name,input);
00505             return G_store (input);
00506         }
00507 /*
00508  * 'list' does a list without extension. if we are looking for a new
00509  * file only list the current mapset. Otherwise list all mapsets
00510  * in the mapset search list
00511  *
00512  * 0  not a list request
00513  * 1  list
00514  * 2  list -f
00515  * 3  list mapset
00516  * 4  list -f mapset
00517  */
00518   
00519         switch (parselist (input, lister?1:0, tmapset))
00520         {
00521         case 0:
00522             break;
00523         case 1:
00524             G_list_element (element, desc, type==OLD?"":cur_mapset, no_lister);
00525             continue;
00526         case 2:
00527             G_list_element (element, desc, type==OLD?"":cur_mapset, lister);
00528             continue;
00529         case 3:
00530             G_list_element (element, desc, tmapset, no_lister);
00531             continue;
00532         case 4:
00533             G_list_element (element, desc, tmapset, lister);
00534             continue;
00535         default:
00536             fprintf (stderr,"** illegal request **\n");
00537             continue;
00538         }
00539 
00540         if((name_is_qualified = G__name_is_fully_qualified (input, xname, xmapset)))
00541             ok = G_legal_filename (xname) >= 0;
00542         else
00543             ok = G_legal_filename (input) >= 0;
00544         if (!ok)
00545         {
00546             fprintf (stderr,_("\n**<%s> illegal name **\n"), input);
00547             continue;
00548         }
00549 /*
00550  * now look for the file.
00551  *
00552  * new files must be simple names
00553  * and must not exist in the current mapset
00554  */
00555         if (type != OLD)
00556         {
00557             if (name_is_qualified)
00558             {
00559                 if(strcmp (cur_mapset, xmapset) != 0)
00560                 {
00561                     fprintf (stderr,_("\n** %s - illegal request **\n"), input);
00562                     continue;
00563                 }
00564                 strcpy (input, xname);
00565             }
00566             mapset = G_find_file (element, input, cur_mapset);
00567             switch (type)
00568             {
00569             case NEW:
00570 
00571                 if (!mapset)
00572                 {
00573                     strcpy (name,input);
00574                     return cur_mapset;
00575                 }
00576                 fprintf (stderr,_("\n** %s - exists, select another name **\n"), input);
00577                 break;
00578 
00579             case ANY:
00580             case ANY_NW:
00581 
00582                 if (mapset && type == ANY)
00583                 {
00584                     char question[200];
00585                     sprintf(question,
00586                         _("\n** %s exists. ok to overwrite? "), input);
00587                     if (!G_yes (question,0))
00588                         break;
00589                 }
00590                 strcpy (name,input);
00591                 return cur_mapset;
00592 
00593             case PRJ:
00594 
00595                 if (mapset)
00596                 {
00597                     strcpy (name,input);
00598                     return cur_mapset;
00599                 }
00600                 fprintf (stderr,_("\n** %s - not found **\n"), input);
00601                 break;
00602 
00603             default:
00604                 G_fatal_error (_("ask: can't happen"));
00605             }
00606         }
00607 /*
00608  * old names can be simple or qualified
00609  * and must exist
00610  */
00611         else
00612         {
00613             mapset = G_find_file (element, input, "");
00614             if (mapset)
00615             {
00616                 if (name_is_qualified)
00617                     strcpy (name,xname);
00618                 else
00619                     strcpy (name,input);
00620                 return mapset;
00621             }
00622             fprintf (stderr,_("\n** %s - not found **\n"), input);
00623         }
00624     }
00625 
00626     return NULL;
00627 }
00628 
00629 static int parselist ( char *input, int option, char *mapset)
00630 {
00631     char list[30];
00632     char f1[30];
00633     char f2[30];
00634     char f3[30];
00635     int count;
00636 
00637     *list = *f1 = *f2 = 0;
00638     count = sscanf (input, "%s%s%s%s", list, f1, f2, f3);
00639     if (count < 1)
00640         return 0;
00641     if (strcmp (list, "list") != 0)
00642         return 0;
00643 
00644     if (count == 1) return 1;   /* list */
00645     if (count > 3)  return -1;  /* illegal */
00646 
00647     if (*f1 == '-')             /* list -f */
00648     {
00649         if (!option)
00650             return -1;
00651         if (f1[1] == 0 || f1[1] != 'f' || f1[2] != 0)
00652             return -1;
00653         if (count == 2)
00654             return 2;
00655         strcpy (mapset, f2);
00656             return 4;
00657     }
00658     if (count != 2)
00659         return -1;
00660     strcpy (mapset, f1);
00661     return 3;
00662 }

Generated on Sat Jul 22 22:06:14 2006 for GRASS by  doxygen 1.4.7