Change behaviour: OMITFUNC ignores local/global OMIT context. Only sane

way to solve garbage-day problem; also allows for more flexibility.
This commit is contained in:
David F. Skoll
2008-08-31 10:29:28 -04:00
parent 6845e72fd5
commit a67d9e2524
5 changed files with 63 additions and 30 deletions

View File

@@ -804,33 +804,35 @@ return a non-zero integer if the date is considered "omitted" and 0
otherwise. Here's an example:
.PP
.nf
FSET _third(x) (day(x) % 3)
REM OMIT Sat Sun OMITFUNC _third AFTER MSG Working day divisible by 3
FSET _third(x) (day(x) % 3) || \\
(wkdaynum(x) == 0) || \\
(wkdaynum(x) == 6)
REM OMITFUNC _third AFTER MSG Working day divisible by 3
.fi
.PP
In the example above, the reminder is triggered every Monday to Friday whose
day-of-month number is divisible by three. Here's how it works:
.TP
.B o
The \fBOMIT Sat Sun\fR portion causes weekends to be considered "omitted"
.TP
.B o
The \fBOMITFUNC _third\fR portion causes all days for which \fB_third(x)\fR
returns non-zero to be considered "omitted". This causes all days whose
day-of-month number is \fInot\fR a multiple of three to be omitted.
day-of-month number is \fInot\fR a multiple of three to be omitted. Note
that _third also returns non-zero if the weekday is Sunday or Saturday.
.TP
.B o
The \fBAFTER\fR keyword causes the reminder to be moved after a block of
omitted days.
.PP
The combination of omitted days and AFTER keyword causes the reminder to
The combination of OMITFUNC and AFTER keyword causes the reminder to
be issued on all days whose day-of-month number is divisible by three,
but not on Saturday or Sunday.
.PP
As the previous example shows, you can combine \fBOMIT\fR and
\fBOMITFUNC\fR and their list of "omitted" days accumulate. In addition,
any globally omitted days (specified by the \fBOMIT\fR command described
later) are also included in the list of "omitted" days.
Note that if you use \fBOMITFUNC\fR, then a local \fBOMIT\fR is
\fIignored\fR as are \fIall global OMITs\fR. If you want to omit specific
weekdays, your omit function will need to test for them specifically. If
you want to take into account the global \BOMIT\fR context, then your omit
function will need to test for that explicitly (using the \fBisomitted()\fR
function.)
.PP
Note that an incorrect \fBOMITFUNC\fR might cause all days to be considered
omitted. For that reason, when \fBRemind\fR searches through omitted days,

View File

@@ -258,6 +258,10 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
case T_Omit:
DBufFree(&buf);
if (trig->omitfunc[0]) {
Eprint("Warning: OMIT is ignored if you use OMITFUNC");
}
r = ParseLocalOmit(s, trig);
if (r) return r;
break;
@@ -268,6 +272,9 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
return OK;
case T_OmitFunc:
if (trig->localomit) {
Eprint("Warning: OMIT is ignored if you use OMITFUNC");
}
r=ParseToken(s, &buf);
if (r) return r;
StrnCpy(trig->omitfunc, DBufValue(&buf), VAR_NAME_LEN);

View File

@@ -185,18 +185,11 @@ int IsOmitted(int jul, int localomit, char const *omitfunc)
{
int y, m, d;
/* Is it omitted because of local omits? */
if (localomit & (1 << (jul % 7))) return 1;
/* Is it omitted because of fully-specified omits? */
if (BexistsIntArray(FullOmitArray, NumFullOmits, jul)) return 1;
/* Get the syndrome */
FromJulian(jul, &y, &m, &d);
if (BexistsIntArray(PartialOmitArray, NumPartialOmits, (m << 5) + d))
return 1;
/* Is it omitted because of omitfunc? */
/* If we have an omitfunc, we *only* use it and ignore local/global
OMITs */
if (omitfunc && *omitfunc && UserFuncExists(omitfunc)) {
char expr[VAR_NAME_LEN + 32];
char const *s;
@@ -211,8 +204,18 @@ int IsOmitted(int jul, int localomit, char const *omitfunc)
return 1;
}
}
return 0;
}
/* Is it omitted because of local omits? */
if (localomit & (1 << (jul % 7))) return 1;
/* Is it omitted because of fully-specified omits? */
if (BexistsIntArray(FullOmitArray, NumFullOmits, jul)) return 1;
if (BexistsIntArray(PartialOmitArray, NumPartialOmits, (m << 5) + d))
return 1;
/* Not omitted */
return 0;
}

View File

@@ -658,6 +658,20 @@ day(1991-02-28) => 28
Leaving UserFN _ofunc() => 0
../tests/test.rem(170): Trig = Thursday, 28 February, 1991
# omitfunc ignores local/global omits
fset _ofunc(x) 0
OMIT 1 March
OMIT 2 March 1991
REM 1 March OMIT Sun OMITFUNC _ofunc AFTER MSG Should trigger 1 March
../tests/test.rem(176): Warning: OMIT is ignored if you use OMITFUNC
Entering UserFN _ofunc(1991-02-15)
Leaving UserFN _ofunc() => 0
Entering UserFN _ofunc(1991-03-01)
Leaving UserFN _ofunc() => 0
../tests/test.rem(176): Trig = Friday, 1 March, 1991
REM 1 March OMIT Sun AFTER MSG Should trigger 4 March
../tests/test.rem(177): Trig = Monday, 4 March, 1991
set a000 abs(1)
abs(1) => 1
set a001 abs(-1)
@@ -680,7 +694,7 @@ set a008 coerce("string", 11:44)
coerce("string", 11:44) => "11:44"
set a009 coerce("int", "badnews")
coerce("int", "badnews") => Can't coerce
../tests/test.rem(181): Can't coerce
../tests/test.rem(188): Can't coerce
set a010 coerce("int", "12")
coerce("int", "12") => 12
set a011 coerce("int", 11:44)
@@ -692,7 +706,7 @@ set a013 date(1992, 2, 2)
date(1992, 2, 2) => 1992-02-02
set a014 date(1993, 2, 29)
date(1993, 2, 29) => Bad date specification
../tests/test.rem(186): Bad date specification
../tests/test.rem(193): Bad date specification
set a015 day(today())
today() => 1991-02-16
day(1991-02-16) => 16
@@ -787,15 +801,15 @@ strlen("sadjflkhsldkfhsdlfjhk") => 21
set a050 substr(a049, 2)
a049 => 21
substr(21, 2) => Type mismatch
../tests/test.rem(224): Type mismatch
../tests/test.rem(231): Type mismatch
set a051 substr(a050, 2, 6)
a050 => ../tests/test.rem(225): Undefined variable: a050
a050 => ../tests/test.rem(232): Undefined variable: a050
set a052 time(1+2, 3+4)
1 + 2 => 3
3 + 4 => 7
time(3, 7) => 03:07
rem 10 jan 1992 AT 11:22 CAL
../tests/test.rem(227): Trig = Friday, 10 January, 1992
../tests/test.rem(234): Trig = Friday, 10 January, 1992
set a053 trigdate()
trigdate() => 1992-01-10
set a054 trigtime()
@@ -887,31 +901,31 @@ y => 11:33
x => "foo"
y => 11:33
"foo" * 11:33 => Type mismatch
../tests/test.rem(250): `*': Type mismatch
../tests/test.rem(257): `*': Type mismatch
Leaving UserFN h() => Type mismatch
set a074 dosubst("%a %b %c %d %e %f %g %h", '1992/5/5')
dosubst("%a %b %c %d %e %f %g %h", 1992-05-05) => "on Tuesday, 5 May, 1992 in 444 days' tim"...
msg [a074]%
../tests/test.rem(252): Trig = Saturday, 16 February, 1991
../tests/test.rem(259): Trig = Saturday, 16 February, 1991
a074 => "on Tuesday, 5 May, 1992 in 444 days' tim"...
on Tuesday, 5 May, 1992 in 444 days' time on Tuesday 5 on 05-05-1992 on 05-05-1992 on Tuesday, 5 May on 05-05
set a075 dosubst("%i %j %k %l %m %n %o %p", '1992/5/5')
dosubst("%i %j %k %l %m %n %o %p", 1992-05-05) => "on 05-05 on Tuesday, May 5th, 1992 on Tu"...
msg [a075]%
../tests/test.rem(254): Trig = Saturday, 16 February, 1991
../tests/test.rem(261): Trig = Saturday, 16 February, 1991
a075 => "on 05-05 on Tuesday, May 5th, 1992 on Tu"...
on 05-05 on Tuesday, May 5th, 1992 on Tuesday, May 5th on 1992-05-05 May 5 s
set a076 dosubst("%q %r %s %t %u %v %w %x", '1992/5/5')
dosubst("%q %r %s %t %u %v %w %x", 1992-05-05) => "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
msg [a076]%
../tests/test.rem(256): Trig = Saturday, 16 February, 1991
../tests/test.rem(263): Trig = Saturday, 16 February, 1991
a076 => "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
s' 05 th 05 on Tuesday, 5th May, 1992 on Tuesday, 5th May Tuesday 444
set a077 dosubst("%y %z", '1992/5/5')
dosubst("%y %z", 1992-05-05) => "1992 92
"
msg [a077]%
../tests/test.rem(258): Trig = Saturday, 16 February, 1991
../tests/test.rem(265): Trig = Saturday, 16 February, 1991
a077 => "1992 92
"
1992 92

View File

@@ -169,6 +169,13 @@ fset _ofunc(x) (day(x) < 7 || day(x) % 2)
REM 1 March OMITFUNC _ofunc AFTER MSG OmitFunc Test
REM 8 March OMITFUNC _ofunc -1 MSG OmitFunc Test 2
# omitfunc ignores local/global omits
fset _ofunc(x) 0
OMIT 1 March
OMIT 2 March 1991
REM 1 March OMIT Sun OMITFUNC _ofunc AFTER MSG Should trigger 1 March
REM 1 March OMIT Sun AFTER MSG Should trigger 4 March
set a000 abs(1)
set a001 abs(-1)
set a002 asc("foo")