[GRASS-dev] [GRASS-SVN] r60703 - in grass/trunk: display/d.vect general/g.gisenv gui/wxpython/animation lib/python/temporal raster/r.colors raster/r.external raster/r.in.bin raster/r.mapcalc raster/r.neighbors raster/r.out.bin raster/r.quant raster/r.resamp.filter raster/r.series raster/r.series.accumulate raster/r.series.interp raster/r.stats.quantile vector/v.colors vector/v.external.out

Anna Petrášová kratochanna at gmail.com
Tue Jul 22 10:53:10 PDT 2014


On Wed, Jun 25, 2014 at 2:09 AM, Huidae Cho <grass4u at gmail.com> wrote:

> We also need to add option_rules or something to g.parser so that python
> scripts can have access to these functions. Something like:
>
> #%option_rules
> #% exclusive: -a, -b
> #% requires_all: opt1, opt2, -a
> #%end
>
>
>
>
> On Fri, Jun 20, 2014 at 9:59 PM, Huidae Cho <grass4u at gmail.com> wrote:
>
>> G_option_excludes() works for me.
>>
>>
>> On Fri, Jun 20, 2014 at 7:58 PM, Glynn Clements <glynn at gclements.plus.com
>> > wrote:
>>
>>>
>>> Huidae Cho wrote:
>>>
>>> > I assume G__check_option_rules() is supposed to be called by
>>> G_parser().
>>> > Then, instead of calling G_fatal_error, it should append errors to
>>> > st->errors.
>>>
>>> Okay; I presume that the intent is so that it will report all errors,
>>> not just the first.
>>>
>>> > If so... for g.mlist we can define two different versions of
>>> > rules:
>>> >
>>> > This version prints more correct errors because only present
>>> options/flags
>>> > will be displayed in errors, but too much typing.
>>> >     G_option_exclusive(flag.regex, flag.extended, NULL);
>>> >     G_option_exclusive(flag.pretty, flag.full, NULL);
>>> >     G_option_exclusive(flag.pretty, opt.output, NULL);
>>> >     G_option_exclusive(flag.pretty, flag.mapset, NULL);
>>> >     G_option_exclusive(flag.pretty, flag.type, NULL);
>>> >     G_option_exclusive(flag.full, opt.output, NULL);
>>> >     G_option_exclusive(flag.full, flag.mapset, NULL);
>>> >     G_option_exclusive(flag.full, flag.type, NULL);
>>> >
>>> > This version is shorter, but -p -f will print three errors including
>>> > options/flags not present.
>>> >     G_option_exclusive(flag.regex, flag.extended, NULL);
>>> >     G_option_exclusive(flag.pretty, flag.full, opt.output, NULL);
>>> >     G_option_exclusive(flag.pretty, flag.full, flag.mapset, NULL);
>>> >     G_option_exclusive(flag.pretty, flag.full, flag.type, NULL);
>>> >
>>> > Can we implement something like
>>> > G_option_exclusive(pretty, full, G_option_or(output, mapset, type))
>>> > ?
>>>
>>> I'd rather stick to "flat" rules rather than heading in the direction
>>> of generalised boolean expressions.
>>>
>>> Not because it's hard to implement, but because it makes it harder to
>>> utilise the information.
>>>
>>> The next logical step is to include the rules in the
>>> --interface-description output so that the GUI can convey the
>>> relationships to the user. E.g. mutually-exclusive options might use
>>> radio buttons, or greying-out excluded options. Options which are
>>> required by another option could be marked as "required" when a value
>>> is given for the first option. And so on.
>>>
>>> Realistically, that requires that the rules belong to a finite set of
>>> patterns.
>>>
>>> > pretty, full, and any of output, mapset, and type are mutually
>>> exclusive,
>>> > but output, mapset, and type are not exclusive.
>>>
>>> How about another rule type:
>>>
>>> >     G_option_excludes(flag.pretty, opt.output, flag.mapset, flag.type,
>>> NULL);
>>> >     G_option_excludes(flag.full,   opt.output, flag.mapset, flag.type,
>>> NULL);
>>>
>>> where the first option excludes all remaining options.
>>>
>>> This is essentially the negation of G_option_requires().
>>>
>>> --
>>> Glynn Clements <glynn at gclements.plus.com>
>>>
>>
>>
>
> _______________________________________________
> grass-dev mailing list
> grass-dev at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/grass-dev
>


Hi,

is this new API now stable enough to be actually used in C modules? Should
we start to replace the manual checks in modules with these functions? BTW,
documentation is still missing.

I attached a patch which should fix this ticket [1]: when user doesn't type
any command arguments and the module has no explicitly required options
(like g.region), it checks if there is any RULE_REQUIRED and if yes, it
opens GUI dialog.

Also I would consider a little bit better error message, the name of the
option is not very visible in the sentence. Perhaps using quotes or <>
around the option would help. Also, "Option myoption1 requires at least one
of myoption2" sounds weird, perhaps there should be special handling of
cases when there is just one option required. These are just details.

Thanks,
Anna


[1]http://trac.osgeo.org/grass/ticket/1778
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/grass-dev/attachments/20140722/be5c30bd/attachment.html>
-------------- next part --------------
Index: lib/gis/parser.c
===================================================================
--- lib/gis/parser.c	(revision 61322)
+++ lib/gis/parser.c	(working copy)
@@ -419,7 +419,8 @@
 
     /* If there are NO arguments, go interactive */
 
-    if (argc < 2 && st->has_required && !st->no_interactive && isatty(0)) {
+    if (argc < 2 && (st->has_required || G__has_required_rule())
+        && !st->no_interactive && isatty(0)) {
 	module_gui_wx();
 	return -1;
     }
Index: lib/gis/parser_local_proto.h
===================================================================
--- lib/gis/parser_local_proto.h	(revision 61322)
+++ lib/gis/parser_local_proto.h	(working copy)
@@ -56,6 +56,7 @@
 
 void G__check_option_rules(void);
 void G__describe_option_rules(void);
+int G__has_required_rule(void);
 
 #endif
 
Index: lib/gis/parser_dependencies.c
===================================================================
--- lib/gis/parser_dependencies.c	(revision 61322)
+++ lib/gis/parser_dependencies.c	(working copy)
@@ -372,3 +372,15 @@
 	}
     }
 }
+
+int G__has_required_rule(void)
+{
+    int i;
+
+    for (i = 0; i < rules.count; i++) {
+	const struct rule *rule = &((const struct rule *) rules.data)[i];
+	if (rule->type == RULE_REQUIRED)
+	    return TRUE;
+    }
+    return FALSE;
+}


More information about the grass-dev mailing list