For our records, I'm attaching a new g.mlist main.c, which supports
multiple mapsets. I removed -p/-f and mapset=* mutual exclusiveness, but it
seems to have a problem with M_do_list when there are a small number of
maps in a previous mapset, but there are many in the current one.

For example, let's say there are only 3 maps in mapset a, but 100 in mapset
b. M_do_list(.., a) would be scrolled up by M_do_list(.., b) because the
pager doesn't pause for mapset a, but does for mapset b. Effectively,
g.mlist mapset=a,b looks as if it only shows maps in mapset b, but
actually, maps in a were displayed, but scrolled up.

The current trunk version doesn't have this problem because M_do_list is
called once and it takes care of all the maps in the current search path at
once.

I think it's little more work to fix it. or just leave g.mlist as is.



On Sun, Jun 8, 2014 at 8:30 AM, Vaclav Petras <wenzesl...@gmail.com> wrote:

>
>
>
> On Sun, Jun 8, 2014 at 7:10 AM, Huidae Cho <gras...@gmail.com> wrote:
>
>> Non-existent mapset fixed in r60749.
>>
>> Thanks. I can confirm that it works. Now we need the test for it.
>
> On Fri, Jun 6, 2014 at 12:18 PM, Vaclav Petras <wenzesl...@gmail.com>
> wrote:
>
>>
>> By the way, is multiple for mapset a planned feature? Or it is too much?
>> Pattern for mapset seems too much for sure.
>>
>
>  On Sun, Jun 8, 2014 at 7:10 AM, Huidae Cho <gras...@gmail.com> wrote:
>
>> Multiple mapsets is not too much, but do we need it?
>>
>
> I don't know. I asked because I just automatically tried that syntax
> because I used `pattern="something,some_*"` syntax recently.
>
>
>> Also, if we implement multiple mapsets, it would be better semantically
>> to change "mapset=.." to "mapset=*" for all mapsets in the current
>> location. Martin, do you mind if I change mapset=.. to mapset=*?
>>
>> I would say that in any case, * fits more with the other options,
> although * is also used also for null values (besides nv and others).
>
>
--- main.c      2014-06-08 08:56:48.270462030 -0400
+++ new/main.c  2014-06-08 08:58:37.024455899 -0400
@@ -27,8 +27,8 @@
 
 static int any = 0;
 
-static void make_list(FILE *, const struct list *, const char *, const char *,
-                     int, int, int);
+static void make_list(int, int, FILE *, const struct list *, const char *,
+                     const char *, int, int);
 
 int main(int argc, char *argv[])
 {
@@ -56,6 +56,7 @@
     FILE *fp;
     const char *mapset;
     char *separator;
+    int list_format;
 
     G_gisinit(argv[0]);
 
@@ -91,6 +92,7 @@
     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");
@@ -204,23 +206,6 @@
     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();   /* current mapset */
-    else if (strcmp(mapset, "*") == 0) {
-        if (flag.pretty->answer || flag.full->answer)
-            G_fatal_error(_("-%c/-%c and %s=%s are mutually exclusive"),
-                          flag.pretty->key, flag.full->key, opt.mapset->key,
-                         mapset);
-        mapset = NULL;         /* all mapsets */
-    }
-    else if ((i = G__mapset_permissions(mapset)) == -1)
-       G_fatal_error(_("Mapset <%s> does not exist"), mapset);
-    else if (i == 0)
-       G_warning(_("Permission denied for mapset <%s>. "
-                   "Trying to list files..."), mapset);
-
     for (i = 0; opt.type->answers[i]; i++) {
        if (strcmp(opt.type->answers[i], "all") == 0)
            break;
@@ -234,30 +219,50 @@
        num_types = i;
     }
 
+    if (flag.full->answer)
+       list_format = 0;
+    else if (flag.pretty->answer)
+       list_format = 1;
+    else
+       list_format = 2;
+
     for (i = 0; i < num_types; i++) {
        const struct list *elem;
+       int j;
 
        n = all ? i : M_get_element(opt.type->answers[i]);
-
        elem = M_get_list(n);
 
-       if (flag.full->answer) {
-           char lister[GPATH_MAX];
-
-           sprintf(lister, "%s/etc/lister/%s", G_gisbase(), elem->element[0]);
-
-           G_debug(3, "lister CMD: %s", lister);
-
-           if (access(lister, X_OK) == 0)      /* execute permission? */
-               G_spawn(lister, lister, mapset, NULL);
-           else
-               M_do_list(n, mapset);
+       if (opt.mapset->answers && opt.mapset->answers[0]) {
+           for (j = 0; (mapset = opt.mapset->answers[j]); j++) {
+               if (strcmp(mapset, "*") == 0) {
+                   /* all mapsets from current location */
+                   int k;
+                   char **ms;
+                   
+                   ms = G_get_available_mapsets();
+                   for (k = 0; (mapset = ms[k]); k++) {
+                           make_list(list_format, n,
+                                     fp, elem, mapset, separator,
+                                     flag.type->answer, flag.mapset->answer);
+                   }
+                   continue;
+               }
+               else if (strcmp(mapset, ".") == 0)
+                   mapset = G_mapset();
+
+               make_list(list_format, n,
+                         fp, elem, mapset, separator, flag.type->answer,
+                         flag.mapset->answer);
+           }
+       }
+       else {
+           /* mapsets from search path only */
+           for (j = 0; (mapset = G_get_mapset_name(j)); j++)
+               make_list(list_format, n,
+                         fp, elem, mapset, separator, flag.type->answer,
+                         flag.mapset->answer);
        }
-       else if (flag.pretty->answer)
-           M_do_list(n, mapset);
-       else
-           make_list(fp, elem, mapset, separator, flag.type->answer,
-                     flag.mapset->answer, mapset && *mapset);
     }
 
     if (any)
@@ -274,10 +279,11 @@
     exit(EXIT_SUCCESS);
 }
 
-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)
+static void make_list(int list_format, int n,
+                     FILE *fp, const struct list *elem, const char *mapset,
+                     const char *separator, int add_type, int add_mapset)
 {
+    static int first_mapset = 1;
     char path[GPATH_MAX];
     const char *element = elem->element[0];
     const char *alias = elem->alias;
@@ -285,23 +291,28 @@
     int count;
     int i;
 
-    if (!mapset) {
-        /* all mapsets from current location */
-        int n;
-        char **ms;
-        ms = G_get_available_mapsets();
-        for (n = 0; ms[n]; n++) {
-            make_list(fp, elem, ms[n], separator, add_type, add_mapset,
-                     n == 0);
-        }
-        return;
+    if ((i = G__mapset_permissions(mapset)) == -1)
+       G_fatal_error(_("Mapset <%s> does not exist"), mapset);
+    else if (i == 0)
+       G_warning(_("Permission denied for mapset <%s>. "
+                   "Trying to list files..."), mapset);
+
+    if (list_format == 0) {
+       char lister[GPATH_MAX];
+
+       sprintf(lister, "%s/etc/lister/%s", G_gisbase(), elem->element[0]);
+
+       G_debug(3, "lister CMD: %s", lister);
+
+       if (access(lister, X_OK) == 0)  /* execute permission? */
+           G_spawn(lister, lister, mapset, NULL);
+       else
+           M_do_list(n, mapset);
+       return;
     }
-    else if (!*mapset) {
-        /* mapsets from search path only */
-       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);
+
+    if (list_format == 1) {
+       M_do_list(n, mapset);
        return;
     }
 
@@ -334,7 +345,7 @@
 
        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;
@@ -349,7 +360,8 @@
 
     G_suppress_warnings(0);
     fflush(fp);
-    
+
     G_free(list);
-}
 
+    first_mapset = 0;
+}
/****************************************************************************
 *
 * MODULE:       g.mlist
 *
 * AUTHOR(S):    Huidae Cho
 * 		 Based on general/manage/cmd/list.c by Michael Shapiro.
 *
 * PURPOSE:      Lists available GRASS data base files of the
 *               user-specified data type to standard output
 *
 * COPYRIGHT:    (C) 1999-2014 by the GRASS Development Team
 *
 *               This program is free software under the GNU General Public
 *               License (>=v2). Read the file COPYING that comes with GRASS
 *               for details.
 *
 *****************************************************************************/

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <grass/gis.h>
#include <grass/manage.h>
#include <grass/glocale.h>
#include <grass/spawn.h>

static int any = 0;

static void make_list(int, int, FILE *, const struct list *, const char *,
		      const char *, int, int);

int main(int argc, char *argv[])
{
    struct GModule *module;
    struct
    {
	struct Option *type;
	struct Option *pattern;
	struct Option *exclude;
	struct Option *separator;
	struct Option *mapset;
	struct Option *output;
    } opt;
    struct
    {
	struct Flag *regex;
	struct Flag *extended;
	struct Flag *type;
	struct Flag *mapset;
	struct Flag *pretty;
	struct Flag *full;
    } flag;
    int i, n, all, num_types, nlist;
    void *filter, *exclude;
    FILE *fp;
    const char *mapset;
    char *separator;
    int list_format;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("general"));
    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.");

    M_read_list(FALSE, &nlist);

    opt.type = G_define_standard_option(G_OPT_M_DATATYPE);
    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;
    opt.pattern->required = NO;
    opt.pattern->multiple = NO;
    opt.pattern->description = _("Map name search pattern (default: all)");
    opt.pattern->guisection = _("Pattern");

    opt.exclude = G_define_option();
    opt.exclude->key = "exclude";
    opt.exclude->type = TYPE_STRING;
    opt.exclude->required = NO;
    opt.exclude->multiple = NO;
    opt.exclude->description = _("Map name exclusion pattern (default: none)");
    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.output = G_define_standard_option(G_OPT_F_OUTPUT);
    opt.output->required = NO;
    opt.output->label = _("Name for output file");
    opt.output->description = _("If not given or '-' then standard output");

    flag.regex = G_define_flag();
    flag.regex->key = 'r';
    flag.regex->description =
	_("Use basic regular expressions instead of wildcards");
    flag.regex->guisection = _("Pattern");

    flag.extended = G_define_flag();
    flag.extended->key = 'e';
    flag.extended->description =
	_("Use extended regular expressions instead of wildcards");
    flag.extended->guisection = _("Pattern");

    flag.type = G_define_flag();
    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)");
    flag.mapset->guisection = _("Print");

    flag.pretty = G_define_flag();
    flag.pretty->key = 'p';
    flag.pretty->description = _("Pretty printing in human readable format");
    flag.pretty->guisection = _("Print");

    flag.full = G_define_flag();
    flag.full->key = 'f';
    flag.full->description = _("Verbose listing (also list map titles)");
    flag.full->guisection = _("Print");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    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 ((flag.pretty->answer || flag.full->answer) && flag.type->answer)
	G_fatal_error(_("-%c/-%c and -%c are mutually exclusive"),
		      flag.pretty->key, flag.full->key, flag.type->key);

    if (flag.pretty->answer && flag.full->answer)
	G_fatal_error(_("-%c and -%c are mutually exclusive"),
		      flag.pretty->key, flag.full->key);

    if (flag.regex->answer && flag.extended->answer)
	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 {
	    /* 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 {
	    /* 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);

    for (i = 0; opt.type->answers[i]; i++) {
	if (strcmp(opt.type->answers[i], "all") == 0)
	    break;
    }
    if (opt.type->answers[i]) {
	all = 1;
	num_types = nlist;
    }
    else {
	all = 0;
	num_types = i;
    }

    if (flag.full->answer)
	list_format = 0;
    else if (flag.pretty->answer)
	list_format = 1;
    else
	list_format = 2;

    for (i = 0; i < num_types; i++) {
	const struct list *elem;
	int j;

	n = all ? i : M_get_element(opt.type->answers[i]);
	elem = M_get_list(n);

	if (opt.mapset->answers && opt.mapset->answers[0]) {
	    for (j = 0; (mapset = opt.mapset->answers[j]); j++) {
		if (strcmp(mapset, "*") == 0) {
		    /* all mapsets from current location */
		    int k;
		    char **ms;
		    
		    ms = G_get_available_mapsets();
		    for (k = 0; (mapset = ms[k]); k++) {
			    make_list(list_format, n,
				      fp, elem, mapset, separator,
				      flag.type->answer, flag.mapset->answer);
		    }
		    continue;
		}
		else if (strcmp(mapset, ".") == 0)
		    mapset = G_mapset();

		make_list(list_format, n,
			  fp, elem, mapset, separator, flag.type->answer,
			  flag.mapset->answer);
	    }
	}
	else {
	    /* mapsets from search path only */
	    for (j = 0; (mapset = G_get_mapset_name(j)); j++)
		make_list(list_format, n,
			  fp, elem, mapset, separator, flag.type->answer,
			  flag.mapset->answer);
	}
    }

    if (any)
	fprintf(fp, "\n");

    G_close_option_file(fp);

    if (filter)
	G_free_ls_filter(filter);

    if (exclude)
	G_free_ls_filter(exclude);

    exit(EXIT_SUCCESS);
}

static void make_list(int list_format, int n,
		      FILE *fp, const struct list *elem, const char *mapset,
		      const char *separator, int add_type, int add_mapset)
{
    static int first_mapset = 1;
    char path[GPATH_MAX];
    const char *element = elem->element[0];
    const char *alias = elem->alias;
    char **list;
    int count;
    int i;

    if ((i = G__mapset_permissions(mapset)) == -1)
	G_fatal_error(_("Mapset <%s> does not exist"), mapset);
    else if (i == 0)
	G_warning(_("Permission denied for mapset <%s>. "
		    "Trying to list files..."), mapset);

    if (list_format == 0) {
	char lister[GPATH_MAX];

	sprintf(lister, "%s/etc/lister/%s", G_gisbase(), elem->element[0]);

	G_debug(3, "lister CMD: %s", lister);

	if (access(lister, X_OK) == 0)	/* execute permission? */
	    G_spawn(lister, lister, mapset, NULL);
	else
	    M_do_list(n, mapset);
	return;
    }

    if (list_format == 1) {
	M_do_list(n, mapset);
	return;
    }

    G_file_name(path, element, "", mapset);
    if (access(path, 0) != 0)
	return;

    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);
    }

    /* Suppress "... found in more mapsets" warnings from G_find_file2. */
    G_suppress_warnings(1);

    for (i = 0; i < count; i++) {
	char *name = list[i];
	int need_mapset = 0;

	if (any && i != 0)
	    fprintf(fp, "%s", separator);
	
	if (add_type)
	    fprintf(fp, "%s/", alias);

	fprintf(fp, "%s", name);

	if (!add_mapset && !first_mapset) {
	    const char *mapset2 = G_find_file2(element, name, "");
            if (mapset2)
                need_mapset = strcmp(mapset, mapset2) != 0;
	}
	if (add_mapset || need_mapset)
	    fprintf(fp, "@%s", mapset);

	G_free(name);

	any++;
    }

    G_suppress_warnings(0);
    fflush(fp);

    G_free(list);

    first_mapset = 0;
}
_______________________________________________
grass-dev mailing list
grass-dev@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/grass-dev

Reply via email to