[GRASS-SVN] r61039 - grass/branches/releasebranch_7_0/general/g.mlist

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Jun 28 16:00:29 PDT 2014


Author: hcho
Date: 2014-06-28 16:00:29 -0700 (Sat, 28 Jun 2014)
New Revision: 61039

Modified:
   grass/branches/releasebranch_7_0/general/g.mlist/Makefile
   grass/branches/releasebranch_7_0/general/g.mlist/main.c
Log:
g.mlist: backport from trunk

Modified: grass/branches/releasebranch_7_0/general/g.mlist/Makefile
===================================================================
--- grass/branches/releasebranch_7_0/general/g.mlist/Makefile	2014-06-28 22:18:06 UTC (rev 61038)
+++ grass/branches/releasebranch_7_0/general/g.mlist/Makefile	2014-06-28 23:00:29 UTC (rev 61039)
@@ -2,8 +2,10 @@
 
 PGM = g.mlist
 
-LIBES = $(MANAGELIB) $(GISLIB)
-DEPENDENCIES = $(MANAGEDEP) $(GISDEP)
+LIBES = $(MANAGELIB) $(GISLIB) $(RASTERLIB) $(RASTER3DLIB) $(VECTORLIB)
+DEPENDENCIES = $(MANAGEDEP) $(GISDEP) $(RASTERDEP) $(RASTER3DDEP) $(VECTORDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
 
 include $(MODULE_TOPDIR)/include/Make/Module.make
 

Modified: grass/branches/releasebranch_7_0/general/g.mlist/main.c
===================================================================
--- grass/branches/releasebranch_7_0/general/g.mlist/main.c	2014-06-28 22:18:06 UTC (rev 61038)
+++ grass/branches/releasebranch_7_0/general/g.mlist/main.c	2014-06-28 23:00:29 UTC (rev 61039)
@@ -21,14 +21,25 @@
 #include <unistd.h>
 #include <string.h>
 #include <grass/gis.h>
+#include <grass/raster3d.h>
+#include <grass/vector.h>
 #include <grass/manage.h>
 #include <grass/glocale.h>
 #include <grass/spawn.h>
 
+enum {
+    TYPE_RAST,
+    TYPE_RAST3D,
+    TYPE_VECT,
+    TYPE_3DVIEW,
+    TYPE_OTHERS
+};
+
 static int any = 0;
 
-static void make_list(FILE *, const struct list *, const char *, const char *,
-		      int, int, int);
+static void make_list(FILE *, const struct list *, const char *,
+		      const char *, int, int, struct Cell_head *);
+static int region_overlaps(struct Cell_head *, const char *, const char *, int);
 
 int main(int argc, char *argv[])
 {
@@ -40,6 +51,7 @@
 	struct Option *exclude;
 	struct Option *separator;
 	struct Option *mapset;
+	struct Option *region;
 	struct Option *output;
     } opt;
     struct
@@ -51,11 +63,14 @@
 	struct Flag *pretty;
 	struct Flag *full;
     } flag;
-    int i, n, all, num_types, nlist;
-    void *filter = NULL, *exclude = NULL;
+    int i, j, n, all, num_types, nlist;
+    void *filter, *exclude;
+    struct Popen pager;
     FILE *fp;
     const char *mapset;
     char *separator;
+    int use_region;
+    struct Cell_head window;
 
     G_gisinit(argv[0]);
 
@@ -64,8 +79,8 @@
     G_add_keyword(_("map management"));
     G_add_keyword(_("list"));
     module->description =
-	_("Lists available GRASS data base files "
-	  "of the user-specified data type optionally using the search pattern.");
+	_("Lists available GRASS data base files of "
+	  "the user-specified data type optionally using the search pattern.");
 
     M_read_list(FALSE, &nlist);
 
@@ -73,7 +88,7 @@
     opt.type->multiple = YES;
     opt.type->options = M_get_options(TRUE);
     opt.type->descriptions = M_get_option_desc(TRUE);
-    
+
     opt.pattern = G_define_option();
     opt.pattern->key = "pattern";
     opt.pattern->type = TYPE_STRING;
@@ -91,12 +106,19 @@
     opt.exclude->guisection = _("Pattern");
 
     opt.mapset = G_define_standard_option(G_OPT_M_MAPSET);
+    opt.mapset->multiple = YES;
     opt.mapset->label =
 	_("Name of mapset to list (default: current search path)");
-
+    opt.mapset->description =
+	_("'.' for current mapset; '*' for all mapsets in location");
     opt.separator = G_define_standard_option(G_OPT_F_SEP);
     opt.separator->answer = "newline";
 
+    opt.region = G_define_standard_option(G_OPT_M_REGION);
+    opt.region->label = _("Name of saved region for map search (default: not restricted)");
+    opt.region->description =
+	_("'.' for current region; '*' for default region");
+
     opt.output = G_define_standard_option(G_OPT_F_OUTPUT);
     opt.output->required = NO;
     opt.output->label = _("Name for output file");
@@ -118,7 +140,7 @@
     flag.type->key = 't';
     flag.type->description = _("Print data types");
     flag.type->guisection = _("Print");
-    
+
     flag.mapset = G_define_flag();
     flag.mapset->key = 'm';
     flag.mapset->description = _("Print fully-qualified map names (including mapsets)");
@@ -137,46 +159,97 @@
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
-    if (opt.output->answer && flag.pretty->answer)
-	G_fatal_error(_("output= and -p are mutually exclusive"));
+    if ((flag.pretty->answer || flag.full->answer) && opt.output->answer)
+        G_fatal_error(_("-%c/-%c and %s= are mutually exclusive"),
+		      flag.pretty->key, flag.full->key, opt.output->key);
 
-    if (opt.output->answer && flag.full->answer)
-	G_fatal_error(_("output= and -f are mutually exclusive"));
+    if ((flag.pretty->answer || flag.full->answer) && opt.region->answer)
+        G_fatal_error(_("-%c/-%c and %s= are mutually exclusive"),
+		      flag.pretty->key, flag.full->key, opt.region->key);
 
-    if (flag.type->answer && flag.pretty->answer)
-	G_fatal_error(_("-t and -p are mutually exclusive"));
+    if ((flag.pretty->answer || flag.full->answer) &&
+	(flag.mapset->answer || flag.type->answer))
+	G_fatal_error(_("-%c/-%c and -%c/-%c are mutually exclusive"),
+		      flag.pretty->key, flag.full->key,
+		      flag.mapset->key, flag.type->key);
 
-    if (flag.type->answer && flag.full->answer)
-	G_fatal_error(_("-t and -f are mutually exclusive"));
+    if (flag.pretty->answer && flag.full->answer)
+	G_fatal_error(_("-%c and -%c are mutually exclusive"),
+		      flag.pretty->key, flag.full->key);
 
-    if (flag.full->answer && flag.pretty->answer)
-	G_fatal_error(_("-f and -p are mutually exclusive"));
-
     if (flag.regex->answer && flag.extended->answer)
-	G_fatal_error(_("-r and -e are mutually exclusive"));
+	G_fatal_error(_("-%c and -%c are mutually exclusive"),
+		      flag.regex->key, flag.extended->key);
 
     if (opt.pattern->answer) {
 	if (flag.regex->answer || flag.extended->answer)
-	    filter = G_ls_regex_filter(opt.pattern->answer, 0, (int) flag.extended->answer);
-	else
-	    filter = G_ls_glob_filter(opt.pattern->answer, 0);
+	    filter = G_ls_regex_filter(opt.pattern->answer, 0,
+			    	       (int)flag.extended->answer);
+	else {
+	    /* handle individual map names */
+	    if (strchr(opt.pattern->answer, ',')) {
+		char *pattern;
+
+		pattern = (char *)G_malloc(strlen(opt.pattern->answer) + 3);
+		sprintf(pattern, "{%s}", opt.pattern->answer);
+
+		filter = G_ls_glob_filter(pattern, 0);
+	    }
+	    else
+		filter = G_ls_glob_filter(opt.pattern->answer, 0);
+	}
+	if (!filter)
+	    G_fatal_error(_("Unable to compile pattern <%s>"),
+			  opt.pattern->answer);
     }
+    else
+	filter = NULL;
 
     if (opt.exclude->answer) {
 	if (flag.regex->answer || flag.extended->answer)
-	    exclude = G_ls_regex_filter(opt.exclude->answer, 1, (int) flag.extended->answer);
-	else
-	    exclude = G_ls_glob_filter(opt.exclude->answer, 1);
+	    exclude = G_ls_regex_filter(opt.exclude->answer, 1,
+			    		(int)flag.extended->answer);
+	else {
+	    /* handle individual map names */
+	    if (strchr(opt.exclude->answer, ',')) {
+		char *pattern;
+
+		pattern = (char *)G_malloc(strlen(opt.exclude->answer) + 3);
+		sprintf(pattern, "{%s}", opt.exclude->answer);
+
+		exclude = G_ls_glob_filter(pattern, 1);
+	    }
+	    else
+		exclude = G_ls_glob_filter(opt.exclude->answer, 1);
+	}
+	if (!exclude)
+	    G_fatal_error(_("Unable to compile pattern <%s>"),
+			  opt.exclude->answer);
     }
+    else
+	exclude = NULL;
 
     separator = G_option_to_separator(opt.separator);
-    fp = G_open_option_file(opt.output);
 
-    if ((mapset = opt.mapset->answer) == NULL)
-	mapset = "";
-    else if (strcmp(mapset, ".") == 0)
-	mapset = G_mapset();
+    if (opt.region->answer) {
+	use_region = 1;
 
+	if (strcmp(opt.region->answer, "*") == 0)
+	    G_get_default_window(&window);
+	else if (strcmp(opt.region->answer, ".") == 0)
+	    G_get_window(&window);
+	else {
+	    char name[GNAME_MAX], mapset[GMAPSET_MAX];
+
+	    if (G_name_is_fully_qualified(opt.region->answer, name, mapset))
+		G__get_window(&window, "windows", name, mapset);
+	    else
+		G__get_window(&window, "windows", opt.region->answer, "");
+	}
+    }
+    else
+	use_region = 0;
+
     for (i = 0; opt.type->answers[i]; i++) {
 	if (strcmp(opt.type->answers[i], "all") == 0)
 	    break;
@@ -190,11 +263,37 @@
 	num_types = i;
     }
 
+    if (opt.mapset->answers && opt.mapset->answers[0]) {
+	G_create_alt_search_path();
+	for (i = 0; (mapset = opt.mapset->answers[i]); i++) {
+	    if (strcmp(mapset, "*") == 0) {
+		/* all mapsets from current location */
+		char **ms;
+
+		ms = G_get_available_mapsets();
+		for (j = 0; (mapset = ms[j]); j++)
+		    G_add_mapset_to_search_path(mapset);
+		continue;
+	    }
+	    else if (strcmp(mapset, ".") == 0)
+		mapset = G_mapset();
+	    else if (G__mapset_permissions(mapset) == -1)
+		G_fatal_error(_("Mapset <%s> does not exist"), mapset);
+	    G_add_mapset_to_search_path(mapset);
+	}
+    }
+
+    if (flag.pretty->answer || flag.full->answer) {
+	fp = G_open_pager(&pager);
+	dup2(fileno(fp), STDOUT_FILENO);
+    }
+    else
+	fp = G_open_option_file(opt.output);
+
     for (i = 0; i < num_types; i++) {
 	const struct list *elem;
 
 	n = all ? i : M_get_element(opt.type->answers[i]);
-
 	elem = M_get_list(n);
 
 	if (flag.full->answer) {
@@ -204,23 +303,30 @@
 
 	    G_debug(3, "lister CMD: %s", lister);
 
-	    if (access(lister, 1) == 0) {	/* execute permission? */
+	    if (access(lister, X_OK) == 0)	/* execute permission? */
 		G_spawn(lister, lister, mapset, NULL);
-		continue;
-	    }
+	    else
+		M_do_list(n, "");
 	}
 	else if (flag.pretty->answer)
-	    G_list_element(elem->element[0], elem->alias, mapset, NULL);
-	else
-	    make_list(fp, elem, mapset, separator, flag.type->answer,
-		      flag.mapset->answer, mapset && *mapset);
+	    M_do_list(n, "");
+	else {
+	    for (j = 0; (mapset = G_get_mapset_name(j)); j++)
+		make_list(fp, elem, mapset, separator, flag.type->answer,
+			  flag.mapset->answer, use_region ? &window : NULL);
+	}
     }
 
-    if (any)
-	fprintf(fp, "\n");
+    if (flag.pretty->answer || flag.full->answer) {
+	fclose(stdout);
+	G_close_pager(&pager);
+    }
+    else {
+	if (any)
+	    fprintf(fp, "\n");
+	G_close_option_file(fp);
+    }
 
-    G_close_option_file(fp);
-
     if (filter)
 	G_free_ls_filter(filter);
 
@@ -232,22 +338,17 @@
 
 static void make_list(FILE *fp, const struct list *elem, const char *mapset,
 		      const char *separator, int add_type, int add_mapset,
-		      int single_mapset)
+		      struct Cell_head *window)
 {
+    static int first_mapset = 1;
     char path[GPATH_MAX];
-    const char *element = elem->element[0];
-    const char *alias = elem->alias;
+    const char *element, *alias;
     char **list;
-    int count;
-    int i;
+    int count, first, i;
+    int type;
 
-    if (!mapset || !*mapset) {
-	int n;
-	for (n = 0; mapset = G_get_mapset_name(n), mapset; n++)
-	    make_list(fp, elem, mapset, separator, add_type, add_mapset,
-		      n == 0);
-	return;
-    }
+    element = elem->element[0];
+    alias = elem->alias;
 
     G_file_name(path, element, "", mapset);
     if (access(path, 0) != 0)
@@ -256,29 +357,52 @@
     if ((list = G__ls(path, &count)) == NULL)
 	return;
 
-    if (count > 0) {
-	if (any)
-	    fprintf(fp, "%s", separator);
-	if (fp == stdout)
-	    G_message(_("%s available in mapset <%s>:"), elem->text, mapset);
-    }
+    if (strcmp(alias, "rast") == 0)
+	type = TYPE_RAST;
+    else if (strcmp(alias, "rast3d") == 0)
+	type = TYPE_RAST3D;
+    else if (strcmp(alias, "vect") == 0)
+	type = TYPE_VECT;
+    else if (strcmp(alias, "3dview") == 0)
+	type = TYPE_3DVIEW;
+    else
+	type = TYPE_OTHERS;
 
     /* Suppress "... found in more mapsets" warnings from G_find_file2. */
     G_suppress_warnings(1);
 
+    first = 1;
     for (i = 0; i < count; i++) {
 	char *name = list[i];
 	int need_mapset = 0;
 
+	/* If region= is used, read the map region. */
+	if (window) {
+	    /* If the map region doesn't overlap with the input region, don't
+	     * print the map. */
+	    if (!region_overlaps(window, name, mapset, type))
+		continue;
+	}
+
+        if (first) {
+	    first = 0;
+
+	    if (any)
+		fprintf(fp, "%s", separator);
+	    if (fp == stdout && isatty(STDOUT_FILENO))
+		G_message(_("%s available in mapset <%s>:"),
+			  elem->text, mapset);
+	}
+
 	if (any && i != 0)
 	    fprintf(fp, "%s", separator);
-	
+
 	if (add_type)
 	    fprintf(fp, "%s/", alias);
 
 	fprintf(fp, "%s", name);
 
-	if (!add_mapset && !single_mapset) {
+	if (!add_mapset && !first_mapset) {
 	    const char *mapset2 = G_find_file2(element, name, "");
             if (mapset2)
                 need_mapset = strcmp(mapset, mapset2) != 0;
@@ -293,7 +417,80 @@
 
     G_suppress_warnings(0);
     fflush(fp);
-    
+
     G_free(list);
+
+    first_mapset = 0;
 }
 
+static int region_overlaps(struct Cell_head *window, const char *name,
+			   const char *mapset, int type)
+{
+    int has_region;
+    struct Cell_head map_window;
+    RASTER3D_Region region3d;
+    struct Map_info Map;
+    struct bound_box box;
+    int ret;
+    struct G_3dview view3d;
+
+    switch (type) {
+    case TYPE_RAST:
+	Rast_get_cellhd(name, mapset, &map_window);
+	has_region = 1;
+	break;
+    case TYPE_RAST3D:
+	if (Rast3d_read_region_map(name, mapset, &region3d) < 0)
+	    G_fatal_error(_("Unable to read header of 3D raster map <%s@%s>"),
+			  name, mapset);
+	Rast3d_region_to_cell_head(&region3d, &map_window);
+	has_region = 1;
+	break;
+    case TYPE_VECT:
+	Vect_set_open_level(2);
+	if (Vect_open_old(&Map, name, mapset) < 2)
+	    G_fatal_error(_("Unable to open vector map <%s@%s> on topological level"),
+			  name, mapset);
+	Vect_get_map_box(&Map, &box);
+	Vect_close(&Map);
+
+	map_window.north = box.N;
+	map_window.south = box.S;
+	map_window.west = box.W;
+	map_window.east = box.E;
+	has_region = 1;
+	break;
+    case TYPE_3DVIEW:
+	if ((ret = G_get_3dview(name, mapset, &view3d)) < 0)
+	    G_fatal_error(_("Unable to read 3dview file <%s@%s>"),
+			  name, mapset);
+	if (ret == 0) {
+	    G_warning(_("No region support in an old 3dview file <%s@%s>. Listing anyway"),
+		      name, mapset);
+	    has_region = 0;
+	}
+	else {
+	    map_window.north = view3d.vwin.north;
+	    map_window.south = view3d.vwin.south;
+	    map_window.west = view3d.vwin.west;
+	    map_window.east = view3d.vwin.east;
+	    has_region = 1;
+	}
+	break;
+    default:
+	has_region = 0;
+	break;
+    }
+
+    /* If an element doesn't have a concept of region at all, return 1 so we
+     * can always print it. */
+    if (!has_region)
+	return 1;
+
+    /* If the map region is outside the input region, return 0. Otherwise
+     * return 1 */
+    return !(window->north <= map_window.south ||
+	     window->south >= map_window.north ||
+	     window->west >= map_window.east ||
+	     window->east <= map_window.west);
+}



More information about the grass-commit mailing list