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 <[email protected]> wrote:
>
>
>
> On Sun, Jun 8, 2014 at 7:10 AM, Huidae Cho <[email protected]> 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 <[email protected]>
> 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 <[email protected]> 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
[email protected]
http://lists.osgeo.org/mailman/listinfo/grass-dev