On Monday 05 May 2003 00:19, Kjetil Torgrim Homme wrote:
<snip>
I don't agree that ${year} is a system variable.
Granted it's not a clean-cut one, but see below.
> I think an explicit action to set them is easier to handle
> than a multitude of variables which can change as side-effects.
But they _do_ change as side effects. You can't go and pretend
they don't.
I wouldn't say it's a side effect, SETDATE is quite explicit.
nothing else will change the variables.
<snip>
It's a side-effect of executing setdate. I call this a side-effect,
since it's not an explicit "set".
> SET "hour" "${_internal_startup_hour}";
<snip>
${_internal_startup_hour} doesn't exist...
So how can SET "hour" ${_internal_startup_hour}" work?
> what actions can influence ${_imapflags}? how will its value
> change?
${#imapflags} is (if resolved) a space-separated list of imap
flags. The order of flags in ${#imapflags} is undefined (it's
conceptually a set).
so
if string :matches "${#imapflags}" "*\\Answered*\\Flagged*" {
...
}
may or may not match even if both flags are set.
Correct.
(easily fixed, just
specify lexical sorting of the "set" at all times.)
I always wondered why imapflags didn't include a flag test. It should,
esp. if one considers the include extension where a included script
doesn't know what it's parent has already done and might want to know.
addflag
- adds the flags given as arg to #imapflags then
- removes all duplicates.
removeflag
- removes all flags given as arg from #imapflags
wouldn't it be better to make generic functions for this?
addflag "flag" "\\Flagged";
changes ${flag}. you'd now use
keep :flags "${flag}";
rather than
keep :globalflags;
and
keep :flags "${flag} \\Flagged";
instead of
keep :globalflags_plus "\\Flagged";
some scripts may become more verbose, but the complexity of the
IMAPFLAGS is decreased, IMO. (ADDFLAG and REMOVEFLAG could move to a
separate extension.)
One could always add the feature to accept multiple flags per string
argument, so you can use
set "myflags" "${#imapflags}" # save away
# ...
setflags "${myflags}" # restore
I fact, you already used that feature in the code above. Also, keep in
mind that imapflags implementations already exist and you can imagine
what a confusion would arise if addflags' et al. syntax would be
changed.
setflag
- clears #imapflags
- executes addflag <args>
what would SETFLAG "${#imapflags}" do? just one of those things
which need to be clarified.
With the above feature, it would be a no-op.
mark
- equivalent to addflag "\\Flagged"
unmark
- equivalent to removeflag "\\Flagged"
what is the rationale for MARK and UNMARK? according to the draft
these actions are _not_ equivalent to ADDFLAG "\\Flagged".
But IIRC, it's suggested they are. However, this is nitpicking again,
since it's clear that the exact (un)mark semantics are
implementation-defined. I've just chosen the obvious one.
Summary:
There are two issues, let's separate them:
1. Should set be allowed to act on system variables?
I hope to have made it clear that that's a bad idea.
I strongly agree!
:-)
2. Should system variables be prefixed?
Well, why _not_? If it makes set's job easier to determine if
something is read-only or not? If it makes system variable
references more explicit?
I don't want to introduce system variables at all. I haven't seen a
compelling case for adding them.
Ok, here's what I think are properties of system variables, why they are
needed and why they should be prefixed:
1. System variables are implicitly changed by certain commands and vice
versa: the value of system variables affects certain commands.
Examples: ${#imapflags} is changed by {add,remove,set}flags,
{un,}mark. It implicitly affects keep, fileinto and a
potential "flags" test.
A ${#currentdate} variable may affect the to-be-defined
date test.
This is the most visible property of system variables, though in
itself alone it doesn't require system variables to be handled
specially.
2. They are read-only to "set".
Examples: ${#imapflags} should be written to only by the imapflags
actions.
${#currentdate} should never be written to.
So the set action needs to raise an error if the script author tries
to assign to a system variable. That begs the question of how set
should know what is a system variable and what isn't. You could keep
a list of system variables, which is complicated by the fact that (as
you said) it should be perfectly OK to use the name of a system
variable as long as the corresponding extension is not "required".
But apart from the fact that you forgot about the include extension
(where variables have global, but require'd extensions local scope),
it would be much easier (for user _and_ engine) if system variables
had a common prefix to detect them.
3. They may represent concepts that are not naturally represented as
strings.
Examples: ${#imapflags} is a set of imap flags, not a string.
${#currentdate} is a number or struct tm or whatever, not a
string.
There are many issues if you allow ${#imapflags} to be "set" by the
user (duplicate or invalid flags, ordering issues). However, it's a
variable (remember that imapflags was what prompted a variables
extension in the first place, even if you were not personally driven
by that) and there was objection to define extensions that have any
kind of "internal variable" (as imapflags once called it) without
first having variables for Sieve in general.
It is, however, potentially very useful to allow interpolation into
strings, and a system variable declaration must specify the string
representation to use. I've already given an example for
${#imapflags}, ${#currentdate} could be interpolated in rfc2822
format.
So system variables could be handled internally in their natural
representation, with a string representation being required only on
expansion into strings, which should be pretty rare.
4. Their values may not be computed with Sieve.
You said setdate would be a macro for a list of set's. But it isn't.
You can't represent setdate "+0200" like that.
E.g. a hypothetical ${#envelope_sender} system variable would not be
a good idea, since you can always obtain that by using the
matches-set idiom:
if :envelope :all :matches "from" "*" {
set "myenvelopesender" "${1}";
}
5. Their values may not be available from the message.
Example: ${#currentdate}
I now agree that ${year} as specified is not a proper system variable.
Here's a proposal for a date test (which is important to have in it own
right) that makes setdate superfluous by using the matches-set idiom to
explicitly set the setdate variables:
if date :current :timezone "+0200" :hour :matches "*" {
set "${hour}" "${1}";
}
where the date test syntax would be:
date [COMPARATOR] WHICH [TIMEZONE] [DATE-PART] [MATCH-TYPE]
<key-list: string-list>
WHICH := ":current" / ":received" / ":sent"
/ ( ":header" <headerfield: string-list> )
DATE-PART := ":weekday" / ":day" / ":month" / ":year"
/ ":hour" / ":minute" / ":second" / ":numericzone"
/ ":all" / ... ; ":all" is default
TIMEZONE := ":timezone" <timezone: string>
; server's local timezone is default for :current,
timezone specified in the header is default for :received, :sent
and :header.
Together with the relational extension and a rfc822-date comparator, you
could check for dates:
if allof( date :comparator "rfc822-date"
:current :value "ge" "Tue, 06 May 2003 14:02:33 +0200",
date :comparator "rfc822-date"
:current :all :value "le" "Tue, 13 May 2003 14:04:05 +0200" )
{
vacation "blah, blubb";
}
And for those that want "old" setdate:
set "setdate_timezone" "CEST"
include :global "setdate";
where "setdate" includes the matches-set idioms:
--begin datevariables--
require [ "variables", "dates" ];
if date :current :timezone "${datevariables_get_timezone}"
:year :matches "*" {
set "year" "${1}";
}
if date ... # and so on for any other setdate variable
--end datevariables--
In this scenario, ${#currentdate} would be a system variable with all
properties as defined above: It affects the date :current test, is
read-only, it's natural representation is not a string, it's value
can't be computed with Sieve and it can't be extracted from the
message.
Marc
--
Ein Grundrecht auf Sicherheit steht bewusst nicht in der Verfassung.
-- Sabine Leutheusser-Schnarrenberger (ehem. Bundesjustizministerin)
pgpVczfI47Kpn.pgp
Description: signature