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