GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ask.c
Go to the documentation of this file.
1 
2 /****************************************************************
3 * These routines prompt the user for names of GIS data files
4 *
5 * G_ask_new (prompt, name, element, desc)
6 * G_ask_old (prompt, name, element, desc)
7 * G_ask_any (prompt, name, element, desc, warn)
8 * G_ask_in_mapset (prompt, name, element, desc)
9 * G_ask_new_file (prompt, name, element, desc)
10 * G_ask_old_file (prompt, name, element, desc)
11 *
12 * G_ask_new_ext (prompt, name, element, desc, option, lister)
13 * G_ask_old_ext (prompt, name, element, desc, option, lister)
14 * G_ask_any_ext (prompt, name, element, desc, warn, option, lister)
15 * G_ask_in_mapset_ext (prompt, name, element, desc, option, lister)
16 *
17 * char *prompt prompt to be printed. can be "" in which
18 * case an appropriate prompt will be printed.
19 * char *name buffer to hold the name input by the user
20 * char *element GIS data element - "cell", "vect", etc.
21 * char *desc a description of element. Used for prompting
22 * and listing. Will be set to element if given as ""
23 * (eg, if element is "vect", set desc = "vector")
24 * char *option list option. a description of the option.
25 * (eg, "with utms" will prompt as follows:
26 * list -f for a list with utms)
27 * int (*lister)() subroutine to return text for -f option.
28 *
29 *
30 * G_ask_new() requires the user to enter the name of a file
31 * which does not exist in the current mapset
32 * (but which may exist in other mapsets).
33 *
34 * G_ask_old() requires the user to enter the name of a file
35 * which already exists.
36 *
37 * G_ask_in_mapset() requires the user to enter the name of a file
38 * which exists in the current mapset
39 *
40 * G_ask_any() accepts any legal filename. Optionally warns user
41 * if the file exists in the current mapset.
42 *
43 * G_ask_new_file() requires the user to enter the name of a new file.
44 *
45 * G_ask_old_file() requires the user to enter the name of any existing file.
46 *
47 * returns:
48 * char * mapset where file was found, or
49 * mapset where file is to be created
50 * NULL user hit RETURN to cancel the request
51 *
52 * note:
53 * These routines have a 'list' function built in. If a list -f
54 * option is also desired, create a lister() routine, and
55 * use G_ask_xxx_ext(). The lister() routine will be called as
56 * follows:
57 *
58 * lister (name, mapset, buf)
59 *
60 * char *name name of file
61 * char *mapset mapset to where file lives
62 * char *buf buffer to hold description.
63 * lister() should copy into buf.
64 * buf will be large (about 400 bytes)
65 * but only first 60 chars will be displayed
66 *
67 *
68 * for each mapset, lister() will be called once with
69 * name set to the empty string "" in order to get an title for the
70 * list. Set buf to null to suppress title, otherwise copy title
71 * into buf. The title will start above the text for the files.
72 *
73 * then for each file in each mapset, lister() will be called
74 * to obtain infomation about the file.
75 *
76 * also:
77 * G_set_ask_return_msg (msg) char *msg;
78 * can be used to change the hit RETURN to cancel request message
79 * displayed during the ask prompting.
80 *
81 * G_get_ask_return_msg() will return the msg.
82 ******************************************************************/
83 #include <string.h>
84 #include <stdlib.h>
85 #include <unistd.h>
86 #include <grass/gis.h>
87 #include <grass/glocale.h>
88 
89 /*
90  * OLD references any mapset
91  * NEW, ANY, PRJ are for the current mapset only
92  *
93  * OLD means must exist in some mapset
94  * NEW means must not exist in current mapset
95  * ANY means just get a name. If file exists, (optionally) warn user.
96  * PRJ means must exist in current mapset
97  */
98 
99 #define OLD 0
100 #define NEW 1
101 #define PRJ 2
102 #define ANY 3
103 #define ANY_NW 4
104 #define OLD_FILE 5
105 #define NEW_FILE 6
106 
107 static char *ask_return_msg = 0;
108 static char clear_return_msg = 0;
109 static int (*no_lister) () = 0;
110 static int parselist(const char *, int, char *);
111 static char *ask(const char *, char *, char *, char *, char *, int (*)(),
112  int);
113 
114 
132 char *G_ask_new(const char *prompt, char *name, char *element, char *desc)
133 {
134  return ask(prompt, name, element, desc, (char *)NULL, no_lister, NEW);
135 }
136 
137 char *G_ask_new_ext(const char *prompt, char *name, char *element, char *desc,
138  char *option, int (*lister) ())
139 {
140  return ask(prompt, name, element, desc, option, lister, NEW);
141 }
142 
143 
161 char *G_ask_old(const char *prompt, char *name, char *element, char *desc)
162 {
163  return ask(prompt, name, element, desc, (char *)NULL, no_lister, OLD);
164 }
165 
166 char *G_ask_old_ext(const char *prompt, char *name, char *element, char *desc,
167  char *option, int (*lister) ())
168 {
169  return ask(prompt, name, element, desc, option, lister, OLD);
170 }
171 
172 
190 char *G_ask_any(const char *prompt, char *name, char *element, char *desc,
191  int warn)
192 {
193  return ask(prompt, name, element, desc, (char *)NULL, no_lister,
194  warn ? ANY : ANY_NW);
195 }
196 
197 char *G_ask_any_ext(const char *prompt, char *name, char *element, char *desc,
198  int warn, char *option, int (*lister) ())
199 {
200  return ask(prompt, name, element, desc, option, lister,
201  warn ? ANY : ANY_NW);
202 }
203 
204 
222 char *G_ask_in_mapset(const char *prompt, char *name, char *element,
223  char *desc)
224 {
225  return ask(prompt, name, element, desc, (char *)NULL, no_lister, PRJ);
226 }
227 
228 char *G_ask_in_mapset_ext(const char *prompt, char *name, char *element,
229  char *desc, char *option, int (*lister) ())
230 {
231  return ask(prompt, name, element, desc, option, lister, PRJ);
232 }
233 
234 
247 char *G_ask_new_file(const char *prompt, char *name, char *element,
248  char *desc)
249 {
250  /* element is a dummy parameter for this function */
251  return ask(prompt, name, element, desc, (char *)NULL, no_lister,
252  NEW_FILE);
253 }
254 
255 /* do we need this function?
256  char *
257  G_ask_new_file_ext (prompt, name, element, desc, option, lister)
258  char *prompt;
259  char *name;
260  char *element;
261  char *desc;
262  char *option;
263  int (*lister)();
264  {
265  return ask (prompt, name, element, desc, option, lister, NEW_FILE);
266  }
267  */
268 
269 
282 char *G_ask_old_file(const char *prompt, char *name, char *element,
283  char *desc)
284 {
285  /* element is a dummy parameter for this function */
286  return ask(prompt, name, element, desc, (char *)NULL, no_lister,
287  OLD_FILE);
288 }
289 
290 /* do we need this function?
291  char *
292  G_ask_old_file_ext (prompt, name, element, desc, option, lister)
293  char *prompt;
294  char *name;
295  char *element;
296  char *desc;
297  char *option;
298  int (*lister)();
299  {
300  return ask (prompt, name, element, desc, option, lister, OLD_FILE);
301  }
302  */
303 
304 
316 int G_set_ask_return_msg(const char *msg)
317 {
318  if (ask_return_msg)
319  G_free(ask_return_msg);
320  ask_return_msg = G_store(msg);
321  clear_return_msg = 0;
322 
323  return 0;
324 }
325 
326 
338 {
339  static char none[80];
340 
341  strcpy(none, _("to cancel request"));
342  return (ask_return_msg == NULL ? none : ask_return_msg);
343 }
344 
345 static char *ask(const char *prompt,
346  char *name,
347  char *element,
348  char *desc, char *option, int (*lister) (), int type)
349 {
350  char tmapset[GMAPSET_MAX];
351  char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
352  int name_is_qualified;
353  int ok;
354  char tprompt[256];
355  char input[256];
356  char *mapset;
357  char *cur_mapset;
358 
360 
361  fflush(stdout);
362  /* RETURN msg */
363  if (clear_return_msg) {
364  G_free(ask_return_msg);
365  ask_return_msg = 0;
366  }
367  clear_return_msg = ask_return_msg ? 1 : 0;
368 
369  /* make sure option is valid */
370  if (lister && (option == 0 || *option == 0))
371  lister = 0;
372 
373  /* set name to NO NAME at outset */
374  *name = 0;
375 
376  /*
377  * if element description not given, make it the same as the
378  * element name
379  */
380  if (desc == 0 || *desc == 0)
381  desc = element;
382 
383  /*
384  * if no prompt is given, build an approriate prompt
385  */
386  if (prompt == 0 || *prompt == 0) {
387  switch (type) {
388  case NEW:
389  case NEW_FILE:
390  sprintf(tprompt, _("Enter a new %s file name"), desc);
391  prompt = tprompt;
392  break;
393  case OLD:
394  case PRJ:
395  case OLD_FILE:
396  sprintf(tprompt, _("Enter the name of an existing %s file"),
397  desc);
398  prompt = tprompt;
399  break;
400  default:
401  sprintf(tprompt, _("Enter %s file name"), desc);
402  prompt = tprompt;
403  break;
404  }
405  }
406 
407  /*
408  * get the current mapset name
409  */
410  cur_mapset = G_mapset();
411 
412  while (1) {
413  /*
414  * print the prompt and input the request
415  */
416  do {
417  fprintf(stderr, "\n%s\n", prompt);
418  /* no listing function implemented for old_file and new_file */
419  if (type != OLD_FILE && type != NEW_FILE)
420  fprintf(stderr,
421  _("Enter 'list' for a list of existing %s files\n"),
422  desc);
423  if (lister) {
424  fprintf(stderr, _("Enter 'list -f' for "));
425  if (option && *option)
426  fprintf(stderr, _("a list %s"), option);
427  else
428  fprintf(stderr, _("an extended list"));
429  fprintf(stderr, "\n");
430  }
431 
432  fprintf(stderr, _("Hit RETURN %s\n"), G_get_ask_return_msg());
433  fprintf(stderr, "> ");
434  }
435  while (!G_gets(input));
436 
437  G_strip(input);
438  fprintf(stderr, "<%s>\n", input);
439 
440  /*
441  * if the user just hit return (or blanks only)
442  * return NULL
443  */
444  if (*input == 0)
445  return 0;
446 
447  if (type == OLD_FILE || type == NEW_FILE) {
448  int exist;
449 
450  exist = (access(input, 0) == 0);
451  if (type == OLD_FILE && !exist) {
452  fprintf(stderr, _("\n** %s - not found **\n"), input);
453  continue;
454  }
455  if (type == NEW_FILE && exist) {
456  char question[200];
457 
458  sprintf(question,
459  _("\n** %s exists. ok to overwrite? "), input);
460  if (!G_yes(question, 0))
461  continue;
462  }
463  strcpy(name, input);
464  return G_store(input);
465  }
466  /*
467  * 'list' does a list without extension. if we are looking for a new
468  * file only list the current mapset. Otherwise list all mapsets
469  * in the mapset search list
470  *
471  * 0 not a list request
472  * 1 list
473  * 2 list -f
474  * 3 list mapset
475  * 4 list -f mapset
476  */
477 
478  switch (parselist(input, lister ? 1 : 0, tmapset)) {
479  case 0:
480  break;
481  case 1:
482  G_list_element(element, desc, type == OLD ? "" : cur_mapset,
483  no_lister);
484  continue;
485  case 2:
486  G_list_element(element, desc, type == OLD ? "" : cur_mapset,
487  lister);
488  continue;
489  case 3:
490  G_list_element(element, desc, tmapset, no_lister);
491  continue;
492  case 4:
493  G_list_element(element, desc, tmapset, lister);
494  continue;
495  default:
496  fprintf(stderr, "** illegal request **\n");
497  continue;
498  }
499 
500  if ((name_is_qualified =
501  G__name_is_fully_qualified(input, xname, xmapset)))
502  ok = G_legal_filename(xname) >= 0;
503  else
504  ok = G_legal_filename(input) >= 0;
505  if (!ok) {
506  fprintf(stderr, _("\n**<%s> illegal name **\n"), input);
507  continue;
508  }
509  /*
510  * now look for the file.
511  *
512  * new files must be simple names
513  * and must not exist in the current mapset
514  */
515  if (type != OLD) {
516  if (name_is_qualified) {
517  if (strcmp(cur_mapset, xmapset) != 0) {
518  fprintf(stderr, _("\n** %s - illegal request **\n"),
519  input);
520  continue;
521  }
522  strcpy(input, xname);
523  }
524  mapset = G_find_file(element, input, cur_mapset);
525  switch (type) {
526  case NEW:
527 
528  if (!mapset) {
529  strcpy(name, input);
530  return cur_mapset;
531  }
532  fprintf(stderr,
533  _("\n** %s - exists, select another name **\n"),
534  input);
535  break;
536 
537  case ANY:
538  case ANY_NW:
539 
540  if (mapset && type == ANY) {
541  char question[200];
542 
543  sprintf(question,
544  _("\n** %s exists. ok to overwrite? "), input);
545  if (!G_yes(question, 0))
546  break;
547  }
548  strcpy(name, input);
549  return cur_mapset;
550 
551  case PRJ:
552 
553  if (mapset) {
554  strcpy(name, input);
555  return cur_mapset;
556  }
557  fprintf(stderr, _("\n** %s - not found **\n"), input);
558  break;
559 
560  default:
561  G_fatal_error(_("ask: can't happen"));
562  }
563  }
564  /*
565  * old names can be simple or qualified
566  * and must exist
567  */
568  else {
569  mapset = G_find_file(element, input, "");
570  if (mapset) {
571  if (name_is_qualified)
572  strcpy(name, xname);
573  else
574  strcpy(name, input);
575  return mapset;
576  }
577  fprintf(stderr, _("\n** %s - not found **\n"), input);
578  }
579  }
580 
581  return NULL;
582 }
583 
584 static int parselist(const char *input, int option, char *mapset)
585 {
586  char list[GNAME_MAX];
587  char f1[GMAPSET_MAX];
588  char f2[GMAPSET_MAX];
589  char f3[GMAPSET_MAX];
590  int count;
591 
592  *list = *f1 = *f2 = 0;
593  count = sscanf(input, "%s%s%s%s", list, f1, f2, f3);
594  if (count < 1)
595  return 0;
596  if (strcmp(list, "list") != 0)
597  return 0;
598 
599  if (count == 1)
600  return 1; /* list */
601  if (count > 3)
602  return -1; /* illegal */
603 
604  if (*f1 == '-') { /* list -f */
605  if (!option)
606  return -1;
607  if (f1[1] == 0 || f1[1] != 'f' || f1[2] != 0)
608  return -1;
609  if (count == 2)
610  return 2;
611  strcpy(mapset, f2);
612  return 4;
613  }
614  if (count != 2)
615  return -1;
616  strcpy(mapset, f1);
617  return 3;
618 }
char * G_mapset(void)
current mapset name
Definition: mapset.c:31
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
#define NEW_FILE
Definition: ask.c:105
char * G_store(const char *s)
Copy string to allocated memory.
Definition: store.c:32
char xmapset[512]
Definition: g3dcats.c:89
int G_gets(char *buf)
Definition: gets.c:39
string name
Definition: render.py:1314
int G_yes(const char *question, int dflt)
Ask a yes/no question.
Definition: yes.c:39
char * G_ask_in_mapset(const char *prompt, char *name, char *element, char *desc)
prompt for existing database file
Definition: ask.c:222
int G_set_ask_return_msg(const char *msg)
set Hit RETURN msg
Definition: ask.c:316
int count
char * G_get_ask_return_msg()
get Hit RETURN msg
Definition: ask.c:337
char * G_ask_new(const char *prompt, char *name, char *element, char *desc)
prompt for new database file
Definition: ask.c:132
#define OLD_FILE
Definition: ask.c:104
char * G_ask_old_ext(const char *prompt, char *name, char *element, char *desc, char *option, int(*lister)())
Definition: ask.c:166
#define OLD
Definition: ask.c:99
int G_list_element(const char *element, const char *desc, const char *mapset, int(*lister)(const char *, const char *, const char *))
General purpose list function.
Definition: gis/list.c:60
char * G_ask_old(const char *prompt, char *name, char *element, char *desc)
prompt for existing database file
Definition: ask.c:161
int G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition: strings.c:389
int
Definition: g3dcolor.c:48
#define ANY_NW
Definition: ask.c:103
return NULL
Definition: dbfopen.c:1394
char * G_ask_any(const char *prompt, char *name, char *element, char *desc, int warn)
prompt for any valid file name
Definition: ask.c:190
tuple msg
Definition: wxnviz.py:32
char * G_ask_new_file(const char *prompt, char *name, char *element, char *desc)
prompt for new file
Definition: ask.c:247
char * G_ask_old_file(const char *prompt, char *name, char *element, char *desc)
prompt for existing file
Definition: ask.c:282
#define ANY
Definition: ask.c:102
char * G_find_file(const char *element, char *name, const char *mapset)
searches for a file from the mapset search list or in a specified mapset. returns the mapset name whe...
Definition: find_file.c:159
char * G_ask_in_mapset_ext(const char *prompt, char *name, char *element, char *desc, char *option, int(*lister)())
Definition: ask.c:228
int G__check_gisinit(void)
Checks to see if GIS engine is initialized.
Definition: gisinit.c:109
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: Vlib/snap.c:46
char * G_ask_any_ext(const char *prompt, char *name, char *element, char *desc, int warn, char *option, int(*lister)())
Definition: ask.c:197
char xname[512]
Definition: g3dcats.c:89
#define PRJ
Definition: ask.c:101
char * G_ask_new_ext(const char *prompt, char *name, char *element, char *desc, char *option, int(*lister)())
Definition: ask.c:137
int G__name_is_fully_qualified(const char *fullname, char *name, char *mapset)
Check if map name is fully qualified (map @ mapset)
Definition: nme_in_mps.c:57