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 <grass/gis.h>
00086 #include <grass/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  (char *prompt, char *name, char *element, char *desc)
00131 
00132 {
00133     return ask (prompt, name, element, desc, (char *) NULL, no_lister, NEW);
00134 }
00135 
00136 char *G_ask_new_ext  (char *prompt, char *name, char *element, char *desc, char *option, int (*lister)())
00137 
00138 {
00139     return ask (prompt, name, element, desc, option, lister, NEW);
00140 }
00141 
00142 
00160 char *G_ask_old  (char *prompt, char *name, char *element, char *desc)
00161 
00162 {
00163     return ask (prompt, name, element, desc, (char *) NULL, no_lister, OLD);
00164 }
00165 
00166 char *G_ask_old_ext  (char *prompt, char *name, char *element, char *desc, char *option, int (*lister)())
00167 
00168 {
00169     return ask (prompt, name, element, desc, option, lister, OLD);
00170 }
00171 
00172 
00190 char *G_ask_any  (char *prompt, char *name, char *element, char *desc, int  warn)
00191 
00192 {
00193     return ask (prompt, name, element, desc, (char *) NULL, no_lister, warn?ANY:ANY_NW);
00194 }
00195 
00196 char *G_ask_any_ext  (char *prompt, char *name, char *element, char *desc, int  warn, char *option, int (*lister)())
00197 
00198 {
00199     return ask (prompt, name, element, desc, option, lister, warn?ANY:ANY_NW);
00200 }
00201 
00202 
00220 char *
00221 G_ask_in_mapset  (char *prompt, char *name, char *element, char *desc)
00222 
00223 {
00224     return ask (prompt, name, element, desc, (char *) NULL, no_lister, PRJ);
00225 }
00226 
00227 char *
00228 G_ask_in_mapset_ext  (char *prompt, char *name, char *element, char *desc, char *option, int (*lister)())
00229 
00230 {
00231     return ask (prompt, name, element, desc, option, lister, PRJ);
00232 }
00233 
00234 
00247 char *
00248 G_ask_new_file  (char *prompt, char *name, char *element, char *desc)
00249 
00250 {
00251     /* element is a dummy parameter for this function */
00252     return ask (prompt, name, element, desc, (char *) NULL, no_lister, NEW_FILE);
00253 }
00254 
00255 /* do we need this function?
00256 char *
00257 G_ask_new_file_ext (prompt, name, element, desc, option, lister)
00258     char *prompt;
00259     char *name;
00260     char *element;
00261     char *desc;
00262     char *option;
00263     int (*lister)();
00264 {
00265     return ask (prompt, name, element, desc, option, lister, NEW_FILE);
00266 }
00267 */
00268 
00269 
00282 char *
00283 G_ask_old_file  (char *prompt, char *name, char *element, char *desc)
00284 
00285 {
00286     /* element is a dummy parameter for this function */
00287     return ask (prompt, name, element, desc, (char *) NULL, no_lister, OLD_FILE);
00288 }
00289 
00290 /* do we need this function?
00291 char *
00292 G_ask_old_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, OLD_FILE);
00301 }
00302 */
00303 
00304 
00316 int G_set_ask_return_msg (char *msg)
00317 {
00318     if (ask_return_msg) G_free (ask_return_msg);
00319     ask_return_msg = G_store (msg);
00320     clear_return_msg = 0;
00321 
00322     return 0;
00323 }
00324 
00325 
00336 char *G_get_ask_return_msg()
00337 {
00338     static char none[80];
00339         strcpy(none,_("to cancel request"));
00340     return (ask_return_msg == NULL ? none : ask_return_msg);
00341 }
00342 
00343 static char *ask (
00344     char *prompt,
00345     char *name,
00346     char *element,
00347     char *desc,
00348     char *option,
00349     int (*lister)(),
00350     int type)
00351 {
00352     char tmapset[256];
00353     char xname[512], xmapset[512];
00354     int  name_is_qualified;
00355     int  ok;
00356     char tprompt[256];
00357     char input[256];
00358     char *mapset;
00359     char *cur_mapset;
00360 
00361     G__check_gisinit();
00362 
00363     fflush (stdout);
00364 /* RETURN msg */
00365     if(clear_return_msg)
00366     {
00367         G_free (ask_return_msg);
00368         ask_return_msg = 0;
00369     }
00370     clear_return_msg = ask_return_msg ? 1 : 0;
00371 
00372 /* make sure option is valid */
00373     if (lister && (option == 0 || *option == 0))
00374         lister = 0;
00375 
00376 /* set name to NO NAME at outset */
00377     *name = 0;
00378 
00379 /*
00380  * if element description not given, make it the same as the
00381  * element name
00382  */
00383     if (desc == 0 || *desc == 0)
00384             desc = element;
00385 
00386 /*
00387  * if no prompt is given, build an approriate prompt
00388  */
00389     if (prompt == 0 || *prompt == 0)
00390     {
00391         switch (type)
00392         {
00393         case NEW:
00394         case NEW_FILE:
00395             sprintf(prompt = tprompt,_("Enter a new %s file name"), desc);
00396             break;
00397         case OLD:
00398         case PRJ:
00399         case OLD_FILE:
00400             sprintf(prompt = tprompt,_("Enter the name of an existing %s file"), desc);
00401             break;
00402         default:
00403             sprintf(prompt = tprompt,_("Enter %s file name"), desc);
00404             break;
00405         }
00406     }
00407 
00408 /*
00409  * get the current mapset name
00410  */
00411     cur_mapset = G_mapset();
00412 
00413     while (1)
00414     {
00415 /*
00416  * print the prompt and input the request
00417  */
00418         do{
00419             fprintf (stderr,"\n%s\n", prompt);
00420             /* no listing function implemented for old_file and new_file */
00421             if (type != OLD_FILE && type != NEW_FILE)
00422                 fprintf (stderr,_("Enter 'list' for a list of existing %s files\n"), desc);
00423             if (lister)
00424             {
00425                 fprintf (stderr,_("Enter 'list -f' for "));
00426                 if (option && *option)
00427                     fprintf (stderr,_("a list %s"), option);
00428                 else
00429                     fprintf (stderr,_("an extended list"));
00430                 fprintf (stderr,"\n");
00431             }
00432 
00433             fprintf (stderr,_("Hit RETURN %s\n"), G_get_ask_return_msg());
00434             fprintf (stderr,"> ");
00435         }
00436         while (!G_gets(input));
00437 
00438         G_strip (input);
00439         fprintf (stderr,"<%s>\n", input);
00440 
00441 /*
00442  * if the user just hit return (or blanks only)
00443  * return NULL
00444  */
00445         if (*input == 0)
00446             return 0;
00447 
00448         if (type == OLD_FILE || type == NEW_FILE)
00449         {
00450             int exist;
00451 
00452             exist = (access(input, 0) == 0);
00453             if (type == OLD_FILE && !exist)
00454             {
00455                 fprintf (stderr,_("\n** %s - not found **\n"), input);
00456                 continue;
00457             }
00458             if (type == NEW_FILE && exist)
00459             {
00460                 char question[200];
00461                 sprintf(question,
00462                         _("\n** %s exists. ok to overwrite? "), input);
00463                 if (!G_yes (question,0))
00464                         continue;
00465             }
00466             strcpy (name,input);
00467             return G_store (input);
00468         }
00469 /*
00470  * 'list' does a list without extension. if we are looking for a new
00471  * file only list the current mapset. Otherwise list all mapsets
00472  * in the mapset search list
00473  *
00474  * 0  not a list request
00475  * 1  list
00476  * 2  list -f
00477  * 3  list mapset
00478  * 4  list -f mapset
00479  */
00480   
00481         switch (parselist (input, lister?1:0, tmapset))
00482         {
00483         case 0:
00484             break;
00485         case 1:
00486             G_list_element (element, desc, type==OLD?"":cur_mapset, no_lister);
00487             continue;
00488         case 2:
00489             G_list_element (element, desc, type==OLD?"":cur_mapset, lister);
00490             continue;
00491         case 3:
00492             G_list_element (element, desc, tmapset, no_lister);
00493             continue;
00494         case 4:
00495             G_list_element (element, desc, tmapset, lister);
00496             continue;
00497         default:
00498             fprintf (stderr,"** illegal request **\n");
00499             continue;
00500         }
00501 
00502         if((name_is_qualified = G__name_is_fully_qualified (input, xname, xmapset)))
00503             ok = G_legal_filename (xname) >= 0;
00504         else
00505             ok = G_legal_filename (input) >= 0;
00506         if (!ok)
00507         {
00508             fprintf (stderr,_("\n**<%s> illegal name **\n"), input);
00509             continue;
00510         }
00511 /*
00512  * now look for the file.
00513  *
00514  * new files must be simple names
00515  * and must not exist in the current mapset
00516  */
00517         if (type != OLD)
00518         {
00519             if (name_is_qualified)
00520             {
00521                 if(strcmp (cur_mapset, xmapset) != 0)
00522                 {
00523                     fprintf (stderr,_("\n** %s - illegal request **\n"), input);
00524                     continue;
00525                 }
00526                 strcpy (input, xname);
00527             }
00528             mapset = G_find_file (element, input, cur_mapset);
00529             switch (type)
00530             {
00531             case NEW:
00532 
00533                 if (!mapset)
00534                 {
00535                     strcpy (name,input);
00536                     return cur_mapset;
00537                 }
00538                 fprintf (stderr,_("\n** %s - exists, select another name **\n"), input);
00539                 break;
00540 
00541             case ANY:
00542             case ANY_NW:
00543 
00544                 if (mapset && type == ANY)
00545                 {
00546                     char question[200];
00547                     sprintf(question,
00548                         _("\n** %s exists. ok to overwrite? "), input);
00549                     if (!G_yes (question,0))
00550                         break;
00551                 }
00552                 strcpy (name,input);
00553                 return cur_mapset;
00554 
00555             case PRJ:
00556 
00557                 if (mapset)
00558                 {
00559                     strcpy (name,input);
00560                     return cur_mapset;
00561                 }
00562                 fprintf (stderr,_("\n** %s - not found **\n"), input);
00563                 break;
00564 
00565             default:
00566                 G_fatal_error (_("ask: can't happen"));
00567             }
00568         }
00569 /*
00570  * old names can be simple or qualified
00571  * and must exist
00572  */
00573         else
00574         {
00575             mapset = G_find_file (element, input, "");
00576             if (mapset)
00577             {
00578                 if (name_is_qualified)
00579                     strcpy (name,xname);
00580                 else
00581                     strcpy (name,input);
00582                 return mapset;
00583             }
00584             fprintf (stderr,_("\n** %s - not found **\n"), input);
00585         }
00586     }
00587 
00588     return NULL;
00589 }
00590 
00591 static int parselist ( char *input, int option, char *mapset)
00592 {
00593     char list[30];
00594     char f1[30];
00595     char f2[30];
00596     char f3[30];
00597     int count;
00598 
00599     *list = *f1 = *f2 = 0;
00600     count = sscanf (input, "%s%s%s%s", list, f1, f2, f3);
00601     if (count < 1)
00602         return 0;
00603     if (strcmp (list, "list") != 0)
00604         return 0;
00605 
00606     if (count == 1) return 1;   /* list */
00607     if (count > 3)  return -1;  /* illegal */
00608 
00609     if (*f1 == '-')             /* list -f */
00610     {
00611         if (!option)
00612             return -1;
00613         if (f1[1] == 0 || f1[1] != 'f' || f1[2] != 0)
00614             return -1;
00615         if (count == 2)
00616             return 2;
00617         strcpy (mapset, f2);
00618             return 4;
00619     }
00620     if (count != 2)
00621         return -1;
00622     strcpy (mapset, f1);
00623     return 3;
00624 }

Generated on Wed Dec 19 14:59:05 2007 for GRASS by  doxygen 1.5.4