Compare commits

...

17 Commits

Author SHA1 Message Date
David F. Skoll
e18b4ed119 Update copyright. 2009-05-31 13:06:05 -04:00
David F. Skoll
51f6ffc093 Document changes. 2009-05-31 13:05:05 -04:00
David F. Skoll
72de7c6b14 Make CallFunc and built-in functions re-entrant. 2009-05-26 22:35:57 -04:00
David F. Skoll
bd4785d631 Remove spurious trigger() function calls from examples.
Bump version to 3.1.7
2009-05-16 10:56:12 -04:00
David F. Skoll
cb08f12470 Add another test. 2009-05-16 10:47:54 -04:00
David F. Skoll
04146db69b More man page updates. 2009-05-16 10:47:10 -04:00
David F. Skoll
d3fe045a39 Make slide function diagnose "Can't OMIT every weekday" 2009-05-16 10:42:43 -04:00
David F. Skoll
2be1e16087 Add some tests. 2009-05-16 10:30:25 -04:00
David F. Skoll
051e44ae3e Update man page. 2009-05-16 10:22:43 -04:00
David F. Skoll
6d5ae7a258 Allow short-hand date specs after UNTIL and SCANFROM.
Start updating man page.
2009-05-16 10:07:57 -04:00
David F. Skoll
2e69e140eb Accept a T_Date or T_DateTime on cmdline to set now() and today(). 2009-05-12 22:46:01 -04:00
David F. Skoll
516c4e2c39 Allow literal dates and datetimes in REM and OMIT statements.
This lets us avoid cluttering up files with [trigger(expr)]; we can
use [expr] directly.
2009-05-09 16:41:15 -04:00
David F. Skoll
b58ed62000 Simplify. 2009-05-09 00:17:11 -04:00
David F. Skoll
c685818783 Use macro to refer to RetVal.v.val 2009-05-09 00:10:45 -04:00
David F. Skoll
3e20ce56c9 Add the slide(date, amt [,localomits]) built-in function. 2009-05-09 00:07:59 -04:00
David F. Skoll
dd8d67f659 Update man page. 2009-02-03 23:11:50 -05:00
David F. Skoll
5ef4061819 Let Remind accept a date of the form YYYY-MM-DD on cmdline. 2009-02-03 23:08:27 -05:00
18 changed files with 709 additions and 405 deletions

2
configure vendored
View File

@@ -5284,7 +5284,7 @@ _ACEOF
fi fi
done done
VERSION=03.01.06 VERSION=03.01.07
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h" ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h"

View File

@@ -45,6 +45,6 @@ if test "$GCC" = yes; then
fi fi
AC_CHECK_FUNCS(setenv unsetenv glob) AC_CHECK_FUNCS(setenv unsetenv glob)
VERSION=03.01.06 VERSION=03.01.07
AC_SUBST(VERSION) AC_SUBST(VERSION)
AC_OUTPUT(src/Makefile www/Makefile src/version.h) AC_OUTPUT(src/Makefile www/Makefile src/version.h)

View File

@@ -1,5 +1,14 @@
CHANGES TO REMIND CHANGES TO REMIND
* Version 3.1 Patch 7 - 2009-05-31
- ENHANCEMENT: Wherever you could write "day Mon year", the parser now
accepts "YYYY-MM-DD". This applies on the command-line and to the
REM and OMIT keywords. You can avoid wrapping date calculations in
the trigger() function in many cases.
- ENHANCEMENT: New slide() built-in function eases some complicated reminders.
* Version 3.1 Patch 6 - 2008-11-16 * Version 3.1 Patch 6 - 2008-11-16
- MAJOR ENHANCEMENT: A new OMITFUNC clause gives you additional - MAJOR ENHANCEMENT: A new OMITFUNC clause gives you additional

View File

@@ -27,8 +27,8 @@ RUN OFF
################################################ ################################################
# Ensure required version of remind is used... # # Ensure required version of remind is used... #
################################################ ################################################
IF version() < "03.01.02" IF version() < "03.01.07"
ERRMSG This file requires at least version 03.01.02 of Remind.% ERRMSG This file requires at least version 03.01.07 of Remind.%
ERRMSG This version is version [version()]. ERRMSG This version is version [version()].
EXIT EXIT
ENDIF ENDIF
@@ -95,11 +95,8 @@ SET Week_3 15
SET Week_4 22 SET Week_4 22
FSET _last(mo) "1 " + MON((mo%12)+1) + " --7" FSET _last(mo) "1 " + MON((mo%12)+1) + " --7"
# Shorthand for commonly used expression...
FSET _trig() TRIGGER(TRIGDATE())
# Handy function to provide SCANFROM dates... # Handy function to provide SCANFROM dates...
FSET _back(days) TRIGGER(TODAY()-days) FSET _back(days) TODAY()-days
########################################################### ###########################################################
# Function which returns a string in "am/pm" format based # # Function which returns a string in "am/pm" format based #
@@ -169,14 +166,14 @@ FSET _mail(from, subj) "fastmail -f " + \
REM 4 July SCANFROM [_back(7)] SATISFY 1 REM 4 July SCANFROM [_back(7)] SATISFY 1
IF WKDAYNUM(TRIGDATE()) == Sat IF WKDAYNUM(TRIGDATE()) == Sat
REM [TRIGGER(TRIGDATE())] MSG Independence day (actual) REM [TRIGDATE()] MSG Independence day (actual)
OMIT [TRIGGER(TRIGDATE()-1)] MSG Independence day (observed) OMIT [TRIGDATE()-1] MSG Independence day (observed)
ELSE ELSE
IF WKDAYNUM(TRIGDATE()) == Sun IF WKDAYNUM(TRIGDATE()) == Sun
REM [TRIGGER(TRIGDATE())] MSG Independence day (actual) REM [TRIGDATE()] MSG Independence day (actual)
OMIT [TRIGGER(TRIGDATE()+1)] MSG Independence day (observed) OMIT [TRIGDATE()+1] MSG Independence day (observed)
ELSE ELSE
OMIT [TRIGGER(TRIGDATE())] MSG Independence day OMIT [TRIGDATE()] MSG Independence day
ENDIF ENDIF
ENDIF ENDIF
@@ -197,7 +194,7 @@ REM Mon 8 SATISFY 1
# But only actually trigger the delayed meeting if the previous # But only actually trigger the delayed meeting if the previous
# Monday was a holiday # Monday was a holiday
IF ISOMITTED(TRIGDATE()-7) IF ISOMITTED(TRIGDATE()-7)
REM [TRIGGER(TRIGDATE())] MSG Delayed meeting REM [TRIGDATE()] MSG Delayed meeting
ENDIF ENDIF
############################################################################ ############################################################################
@@ -288,12 +285,12 @@ REM Sat Sun SPECIAL SHADE 220
SET SaveTrig $NumTrig SET SaveTrig $NumTrig
SET easter EASTERDATE(YEAR(TODAY())) SET easter EASTERDATE(YEAR(TODAY()))
REM [TRIGGER(easter-46)] MSG %"Ash Wednesday%" REM [easter-46] MSG %"Ash Wednesday%"
REM [TRIGGER(easter-7)] MSG %"Palm Sunday%" REM [easter-7] MSG %"Palm Sunday%"
OMIT [TRIGGER(easter-2)] MSG %"Good Friday%" OMIT [easter-2] MSG %"Good Friday%"
OMIT [TRIGGER(easter)] MSG %"Easter%" Sunday OMIT [easter] MSG %"Easter%" Sunday
REM [TRIGGER(easter+39)] MSG %"Ascension Day%" REM [easter+39] MSG %"Ascension Day%"
REM [TRIGGER(easter+49)] MSG %"Pentecost%" REM [easter+49] MSG %"Pentecost%"
# Some holidays are omitted, some are not. You may want to change # Some holidays are omitted, some are not. You may want to change
# which ones are omitted - use the general forms shown below. # which ones are omitted - use the general forms shown below.
@@ -305,7 +302,7 @@ REM Mon Jan [Week_3] MSG Martin Luther King - %"MLK Day%"
REM Feb 2 MSG %"Ground Hog Day%" REM Feb 2 MSG %"Ground Hog Day%"
REM Feb 14 MSG %"Valentine's%" Day REM Feb 14 MSG %"Valentine's%" Day
REM Mon Feb [Week_3] SCANFROM [_back(7)] SATISFY 1 REM Mon Feb [Week_3] SCANFROM [_back(7)] SATISFY 1
OMIT [_trig()] MSG %"President's Day%" OMIT [trigdate()] MSG %"President's Day%"
REM Mar 17 MSG %"St. Patrick's%" Day REM Mar 17 MSG %"St. Patrick's%" Day
# The DST rules are accurate for most locations in # The DST rules are accurate for most locations in
@@ -320,11 +317,11 @@ REM Sat May [Week_1] MSG %"Kentucky Derby%"
REM Sun May [Week_2] MSG %"Mother's Day%" REM Sun May [Week_2] MSG %"Mother's Day%"
REM Sat May [Week_3] MSG %"Armed Forces Day%" REM Sat May [Week_3] MSG %"Armed Forces Day%"
REM Mon [_last(May)] SCANFROM [_back(7)] SATISFY 1 REM Mon [_last(May)] SCANFROM [_back(7)] SATISFY 1
OMIT [_trig()] MSG %"Memorial Day%" OMIT [trigdate()] MSG %"Memorial Day%"
REM Jun 14 MSG %"Flag Day%" REM Jun 14 MSG %"Flag Day%"
REM Sun Jun [Week_3] MSG %"Father's Day%" REM Sun Jun [Week_3] MSG %"Father's Day%"
REM Mon Sep [Week_1] SCANFROM [_back(7)] SATISFY 1 REM Mon Sep [Week_1] SCANFROM [_back(7)] SATISFY 1
OMIT [_trig()] MSG %"Labor Day%" OMIT [trigdate()] MSG %"Labor Day%"
REM Mon Oct [Week_2] MSG %"Columbus Day%" REM Mon Oct [Week_2] MSG %"Columbus Day%"
REM Nov 11 MSG %"Veterans Day%" REM Nov 11 MSG %"Veterans Day%"
@@ -339,9 +336,9 @@ REM Tue Nov 2 SCANFROM [_back(7)] \
SATISFY [(YEAR(TRIGDATE()) % 4) == 0] \ SATISFY [(YEAR(TRIGDATE()) % 4) == 0] \
MSG %"Election%" Day MSG %"Election%" Day
REM Thu Nov [Week_4] SCANFROM [_back(7)] SATISFY 1 REM Thu Nov [Week_4] SCANFROM [_back(7)] SATISFY 1
OMIT [_trig()] MSG %"Thanksgiving%" Day OMIT [trigdate()] MSG %"Thanksgiving%" Day
REM Fri Nov [Week_4+1] SCANFROM [_back(7)] SATISFY 1 REM Fri Nov [Week_4+1] SCANFROM [_back(7)] SATISFY 1
OMIT [_trig()] MSG %"Thanksgiving%" (cont.) OMIT [trigdate()] MSG %"Thanksgiving%" (cont.)
OMIT Dec 24 MSG %"Christmas Eve%" OMIT Dec 24 MSG %"Christmas Eve%"
OMIT Dec 25 MSG %"Christmas%" Day OMIT Dec 25 MSG %"Christmas%" Day
@@ -379,10 +376,10 @@ REM PS Border Border moveto \
([hebday(today())] [hebmon(today())]) show ([hebday(today())] [hebmon(today())]) show
# Fill in the phases of the moon on the PostScript calendar # Fill in the phases of the moon on the PostScript calendar
[trigger(moondate(0))] SPECIAL MOON 0 [moondate(0)] SPECIAL MOON 0
[trigger(moondate(1))] SPECIAL MOON 1 [moondate(1)] SPECIAL MOON 1
[trigger(moondate(2))] SPECIAL MOON 2 [moondate(2)] SPECIAL MOON 2
[trigger(moondate(3))] SPECIAL MOON 3 [moondate(3)] SPECIAL MOON 3
# The following example puts sunrise and sunset times in PostScript in the # The following example puts sunrise and sunset times in PostScript in the
# calendar - the sizes are hard-coded, however, and work best in landscape. # calendar - the sizes are hard-coded, however, and work best in landscape.
@@ -435,11 +432,11 @@ SET InIsrael 0
SET Reform 0 SET Reform 0
# Convenient function definition to save typing # Convenient function definition to save typing
FSET _h(x, y) TRIGGER(HEBDATE(x,y)) FSET _h(x, y) HEBDATE(x,y)
FSET _h2(x, y) HEBDATE(x, y, TODAY()-7) FSET _h2(x, y) HEBDATE(x, y, TODAY()-7)
FSET _PastSat(x, y) TRIGGER(IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)+1)) FSET _PastSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)+1)
FSET _PastSun(x, y) TRIGGER(IIF(WKDAYNUM(_h2(x,y))!=0, _h2(x,y), _h2(x,y)+1)) FSET _PastSun(x, y) IIF(WKDAYNUM(_h2(x,y))!=0, _h2(x,y), _h2(x,y)+1)
FSET _PastMon(x, y) TRIGGER(IIF(WKDAYNUM(_h2(x,y))!=1, _h2(x,y), _h2(x,y)+1)) FSET _PastMon(x, y) IIF(WKDAYNUM(_h2(x,y))!=1, _h2(x,y), _h2(x,y)+1)
# Default values in case InIsrael and Reform are not set # Default values in case InIsrael and Reform are not set
SET InIsrael VALUE("InIsrael", 0) SET InIsrael VALUE("InIsrael", 0)
@@ -470,7 +467,7 @@ ELSE
ENDIF ENDIF
# Because Kislev can change length, we must be more careful about Chanukah # Because Kislev can change length, we must be more careful about Chanukah
FSET _chan(x) TRIGGER(HEBDATE(24, "Kislev", today()-9)+x) FSET _chan(x) HEBDATE(24, "Kislev", today()-9)+x
[_chan(1)] ++4 MSG %"Chanukah 1%" is %b. [_chan(1)] ++4 MSG %"Chanukah 1%" is %b.
[_chan(2)] MSG %"Chanukah 2%" [_chan(2)] MSG %"Chanukah 2%"
[_chan(3)] MSG %"Chanukah 3%" [_chan(3)] MSG %"Chanukah 3%"
@@ -493,9 +490,9 @@ ENDIF
# If Purim is on Sunday, then Fast of Esther is 11 Adar. # If Purim is on Sunday, then Fast of Esther is 11 Adar.
IF WKDAYNUM(_h2(13, "Adar")) != 6 IF WKDAYNUM(_h2(13, "Adar")) != 6
REM [TRIGGER(_h2(13, "Adar"))] ++4 MSG %"Fast of Esther%" is %b. REM [_h2(13, "Adar")] ++4 MSG %"Fast of Esther%" is %b.
ELSE ELSE
REM [TRIGGER(_h2(11, "Adar"))] ++4 MSG %"Fast of Esther%" is %b. REM [_h2(11, "Adar")] ++4 MSG %"Fast of Esther%" is %b.
ENDIF ENDIF
[_h(14, "Adar")] ++4 MSG %"Purim%" is %b. [_h(14, "Adar")] ++4 MSG %"Purim%" is %b.
[_h(15, "Adar")] ++4 MSG %"Shushan Purim%" is %b. [_h(15, "Adar")] ++4 MSG %"Shushan Purim%" is %b.
@@ -521,7 +518,7 @@ IF WKDAYNUM(_h2(4, "Iyar")) == 5
[_h(2, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b. [_h(2, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b.
[_h(3, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b. [_h(3, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
ELSE ELSE
IF WKDAYNUM(_h2, 4, "Iyar") == 0 IF WKDAYNUM(_h2(4, "Iyar")) == 0
[_h(5, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b. [_h(5, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b.
[_h(6, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b. [_h(6, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
ELSE ELSE

View File

@@ -286,6 +286,10 @@ set \fBRemind\fR's notion of "now" to a particular time. Supplying
a \fItime\fR on the command line also implicitly enables the \fB\-q\fR a \fItime\fR on the command line also implicitly enables the \fB\-q\fR
option and disables the \fB\-z\fR option. option and disables the \fB\-z\fR option.
.PP .PP
If you would rather specify the date more succinctly, you can supply
it as YYYY-MM-DD or YYYY/MM/DD. You can even supply a date and
time on the command line as one argument: YYYY-MM-DD@HH:MM.
.PP
In addition, you can supply a \fIrepeat\fR parameter, which has the In addition, you can supply a \fIrepeat\fR parameter, which has the
form *\fInum\fR. This causes \fBRemind\fR to be run \fInum\fR times, form *\fInum\fR. This causes \fBRemind\fR to be run \fInum\fR times,
with the date incrementing on each iteration. You may have to enclose with the date incrementing on each iteration. You may have to enclose
@@ -306,7 +310,7 @@ very simple and almost immediately understandable:
to the baroque and obscure: to the baroque and obscure:
.PP .PP
.nf .nf
REM [trigger(date(thisyear, 1, 1) + 180)] ++5 OMIT \\ REM [date(thisyear, 1, 1) + 180] ++5 OMIT \\
sat sun BEFORE MSG [ord(thisyear-1980)] payment due %b! sat sun BEFORE MSG [ord(thisyear-1980)] payment due %b!
.fi .fi
.PP .PP
@@ -633,6 +637,37 @@ the
.I weekday .I weekday
constraints. constraints.
.PP .PP
.B SHORT-HAND DATE SPECIFICATIONS
.PP
In addition to spelling out the day, month and year separately, you
can specify YYYY-MM-DD or YYYY/MM/DD. For example, the following statements
are equivalent:
.PP
.nf
REM 5 June 2010 MSG Cool!
REM 2010-06-05 MSG Cool!
.fi
.PP
You can also specify a date and time as YYYY-MM-DD@HH:MM. These
statements are equivalent:
.PP
.nf
REM 19 Dec 2010 AT 16:45 MSG Hi
REM 2010-12-19@16:45 MSG Hi
.fi
.PP
There's one subtlety with short-hand date specifications: The following
statements are \fInot\fR equivalent:
.PP
.nf
REM 19 Dec 2010 AT 16:45 +60 MSG Hi
REM 2010-12-19@16:45 +60 MSG Hi
.fi
.PP
In the second statement, the "+60" is a \fIdelta\fR that applies to the
date rather than a \fItdelta\fR that applies to the time. We recommend
explicitly using the AT keyword with timed reminders.
.PP
.B BACKWARD SCANNING .B BACKWARD SCANNING
.PP .PP
Sometimes, it is necessary to specify a date as being a set amount of Sometimes, it is necessary to specify a date as being a set amount of
@@ -730,7 +765,7 @@ Another example: Suppose you have jury duty from 30 November 1992 until
of your jury duty, as well as 2 days ahead of time: of your jury duty, as well as 2 days ahead of time:
.PP .PP
.nf .nf
REM 30 Nov 1992 *1 +2 UNTIL 4 Dec 1992 MSG Jury duty REM 1992-11-30 *1 +2 UNTIL 1992-12-04 MSG Jury duty
.fi .fi
.PP .PP
Note that the \fIrepeat\fR of *1 is necessary; without it, the reminder Note that the \fIrepeat\fR of *1 is necessary; without it, the reminder
@@ -1257,6 +1292,14 @@ must create an \fBOMIT\fR command for each year. (Later, in the
description of expressions and some of the more advanced features of description of expressions and some of the more advanced features of
\fBRemind\fR, you will see how to automate this for some cases.) \fBRemind\fR, you will see how to automate this for some cases.)
.PP .PP
As with the REM command, you can use shorthand specifiers for dates;
the following are equivalent:
.PP
.nf
OMIT 7 Sep 1992
OMIT 1992-09-07
.fi
.PP
For convenience, you can use a \fIdelta\fR and \fBMSG\fR or \fBRUN\fR For convenience, you can use a \fIdelta\fR and \fBMSG\fR or \fBRUN\fR
keyword in the \fBOMIT\fR command. The following sequences are exactly keyword in the \fBOMIT\fR command. The following sequences are exactly
equivalent: equivalent:
@@ -2458,10 +2501,10 @@ For example, the following four lines place moon symbols on the PostScript
calendar: calendar:
.PP .PP
.nf .nf
REM [trigger(moondate(0))] PS [psmoon(0)] REM [moondate(0)] PS [psmoon(0)]
REM [trigger(moondate(1))] PS [psmoon(1)] REM [moondate(1)] PS [psmoon(1)]
REM [trigger(moondate(2))] PS [psmoon(2)] REM [moondate(2)] PS [psmoon(2)]
REM [trigger(moondate(3))] PS [psmoon(3)] REM [moondate(3)] PS [psmoon(3)]
.fi .fi
.PP .PP
If \fInote\fR is specified, the text is used to annotate the moon If \fInote\fR is specified, the text is used to annotate the moon
@@ -2474,7 +2517,7 @@ does not check for this.) For example, if you want the time of each new
moon displayed, you could use this in your reminder script: moon displayed, you could use this in your reminder script:
.PP .PP
.nf .nf
REM [trigger(moondate(0))] PS [psmoon(0, -1, moontime(0)+"")] REM [moondate(0)] PS [psmoon(0, -1, moontime(0)+"")]
.fi .fi
.PP .PP
Note how the time is coerced to a string by concatenating the null string. Note how the time is coerced to a string by concatenating the null string.
@@ -2534,6 +2577,31 @@ If \fImaxlen\fR is specified, then \fBshell()\fR returns the first
output from \fIcmd\fR is returned. output from \fIcmd\fR is returned.
.RE .RE
.TP .TP
.B slide(d_start, i_amt [,s_wkday...])
This function is the inverse of \fBnonomitted\fR. It adds \fIamt\fR
days (which can be negative) to \fIstart\fR, \fInot counting omitted days\fR.
The optional \fIwkday\fR arguments are additional weekday names to omit.
.RS
.PP
Consider this example:
.PP
.nf
OMIT 14 May 2009
SET a slide('2009-05-13', 5, "Sat", "Sun")
.fi
.PP
In this case, \fIa\fR is set to 2009-05-21. That's because we slide forward
by 5 days, not including Thursday, May 14 or Saturday and Sunday,
May 16 and 17. You can go backwards, too, so:
.PP
.nf
OMIT 14 May 2009
SET a slide('2009-05-21', -5, "Sat", "Sun")
.fi
.PP
takes \fIa\fR back to 2009-05-13.
.RE
.TP
.B strlen(s_str) .B strlen(s_str)
Returns the length of \fIstr\fR. Returns the length of \fIstr\fR.
.TP .TP
@@ -2590,15 +2658,18 @@ triggerable \fBREM\fR command had an \fBAT\fR clause. If there was no
returns the integer 0. returns the integer 0.
.TP .TP
.B trigger(d_date [,t_time [,i_utcflag]]) \fRor\fB trigger(q_datetime [,i_utcflag]) .B trigger(d_date [,t_time [,i_utcflag]]) \fRor\fB trigger(q_datetime [,i_utcflag])
Returns a string suitable for use in a \fBREM\fR command, allowing you Returns a string suitable for use in a \fBREM\fR command or a SCANFROM
to calculate trigger dates in advance. (See the section "Expression or UNTIL clause, allowing you to calculate trigger dates in advance.
pasting" for more information.) Note that \fBtrigger()\fR Note that in earlier versions of \fBRemind\fR, \fBtrigger\fR was
\fIalways\fR returns its result in English, even for foreign-language required to convert a date into something the \fBREM\fR command could
versions of \fBRemind\fR. This is to avoid problems with certain C consume. However, in this version of \fBRemind\fR, you can omit it.
libraries that do not handle accented characters properly. Normally, Note that \fBtrigger()\fR \fIalways\fR returns its result in English,
the \fIdate\fR and \fItime\fR are the local date and time; however, if even for foreign-language versions of \fBRemind\fR. This is to avoid
\fIutcflag\fR is non-zero, the \fIdate\fR and \fItime\fR are problems with certain C libraries that do not handle accented
interpreted as UTC times, and are converted to local time. Examples: characters properly. Normally, the \fIdate\fR and \fItime\fR are the
local date and time; however, if \fIutcflag\fR is non-zero, the
\fIdate\fR and \fItime\fR are interpreted as UTC times, and are
converted to local time. Examples:
.RS .RS
.PP .PP
trigger('1993/04/01') trigger('1993/04/01')
@@ -2712,10 +2783,10 @@ you can "paste" an expression in. To do this, surround the expression
with square brackets. For example: with square brackets. For example:
.PP .PP
.nf .nf
REM [trigger(mydate)] MSG foo REM [mydate] MSG foo
.fi .fi
.PP .PP
This evaluates the expression "trigger(mydate)", where "mydate" is This evaluates the expression "mydate", where "mydate" is
presumably some pre-computed variable, and then "pastes" the result presumably some pre-computed variable, and then "pastes" the result
into the command-line for the parser to process. into the command-line for the parser to process.
.PP .PP
@@ -3095,7 +3166,7 @@ more complicated sequence:
.nf .nf
REM 13 SATISFY wkdaynum(trigdate()) == 5 REM 13 SATISFY wkdaynum(trigdate()) == 5
IF trigvalid() IF trigvalid()
REM [trigger(trigdate())] +2 MSG \\ REM [trigdate()] +2 MSG \\
Friday the 13th is %b. Friday the 13th is %b.
ENDIF ENDIF
.fi .fi
@@ -3103,8 +3174,7 @@ more complicated sequence:
Let's see how this works. The \fBSATISFY\fR clause iterates through Let's see how this works. The \fBSATISFY\fR clause iterates through
all the 13ths of successive months, until a trigger date is found whose all the 13ths of successive months, until a trigger date is found whose
day-of-week is Friday (== 5). If a valid date was found, we use the day-of-week is Friday (== 5). If a valid date was found, we use the
calculated trigger date (converted into a trigger format with the calculated trigger date to set up the next reminder.
\fBtrigger()\fR function) to set up the next reminder.
.PP .PP
We could also have written: We could also have written:
.PP .PP
@@ -3123,7 +3193,7 @@ could use:
.nf .nf
# Note: SATISFY 1 is an idiom for "do nothing" # Note: SATISFY 1 is an idiom for "do nothing"
REM Mon 1 Sept SATISFY 1 REM Mon 1 Sept SATISFY 1
OMIT [trigger(trigdate())] OMIT [trigdate()]
.fi .fi
.PP .PP
\fBCAVEAT:\fR This \fIonly\fR omits the \fInext\fR Labour Day, not \fBCAVEAT:\fR This \fIonly\fR omits the \fInext\fR Labour Day, not
@@ -3890,10 +3960,10 @@ in calendars produced by \fBRem2PS\fR, \fBtkremind\fR and \fBrem2html\fR.)
The \fBMOON\fR special replaces the \fBpsmoon()\fR function. Use it The \fBMOON\fR special replaces the \fBpsmoon()\fR function. Use it
like this: like this:
.nf .nf
REM [trigger(moondate(0))] SPECIAL MOON 0 REM [moondate(0)] SPECIAL MOON 0
REM [trigger(moondate(1))] SPECIAL MOON 1 REM [moondate(1)] SPECIAL MOON 1
REM [trigger(moondate(2))] SPECIAL MOON 2 REM [moondate(2)] SPECIAL MOON 2
REM [trigger(moondate(3))] SPECIAL MOON 3 REM [moondate(3)] SPECIAL MOON 3
.fi .fi
These draw little moons on the various calendars. The complete syntax These draw little moons on the various calendars. The complete syntax
of the \fBMOON\fR special is as follows: of the \fBMOON\fR special is as follows:
@@ -4022,7 +4092,7 @@ This example puts an entry in each box of a calendar showing the number
.nf .nf
REM Tue 2 Nov SATISFY (year(trigdate())%4) == 0 REM Tue 2 Nov SATISFY (year(trigdate())%4) == 0
IF trigvalid() IF trigvalid()
REM [trigger(trigdate())] ++5 MSG \\ REM [trigdate()] ++5 MSG \\
U.S. Presidential Election!! U.S. Presidential Election!!
ENDIF ENDIF
.fi .fi
@@ -4073,8 +4143,8 @@ in September. It can move over a range of 7 days. Consider the
following sequence: following sequence:
.PP .PP
.nf .nf
REM Mon 1 Sept SCANFROM [trigger(today()-7)] SATISFY 1 REM Mon 1 Sept SCANFROM [today()-7] SATISFY 1
OMIT [trigger(trigdate())] OMIT [trigdate()]
REM Mon AFTER MSG Hello REM Mon AFTER MSG Hello
.fi .fi
@@ -4104,7 +4174,7 @@ will trigger on Mondays and Thursdays between 23 July 2007 and
the reminder above as follows: the reminder above as follows:
.PP .PP
.nf .nf
REM Mon Thu SCANFROM [trigger(max(today(), '2007-07-23'))] \\ REM Mon Thu SCANFROM [max(today(), '2007-07-23')] \\
UNTIL 2 Aug 2007 MSG Test UNTIL 2 Aug 2007 MSG Test
.fi .fi
.PP .PP

View File

@@ -8,7 +8,7 @@
# #
# This file is part of REMIND. # This file is part of REMIND.
# Copyright (C) 1992-1998 David F. Skoll # Copyright (C) 1992-1998 David F. Skoll
# Copyright (C) 1999-2008 Roaring Penguin Software Inc. # Copyright (C) 1999-2009 Roaring Penguin Software Inc.
# #
#-------------------------------------------------------------- #--------------------------------------------------------------
@@ -2271,7 +2271,7 @@ proc main {} {
global AppendFile HighestTagSoFar DayNames global AppendFile HighestTagSoFar DayNames
catch { catch {
puts "\nTkRemind Copyright (C) 1996-1998 David F. Skoll" puts "\nTkRemind Copyright (C) 1996-1998 David F. Skoll"
puts "Copyright (C) 1999-2008 Roaring Penguin Software Inc." puts "Copyright (C) 1999-2009 Roaring Penguin Software Inc."
} }
catch { SetFonts } catch { SetFonts }
LoadOptions LoadOptions

View File

@@ -127,6 +127,8 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
DynamicBuffer buf; DynamicBuffer buf;
Token tok; Token tok;
int y, m, d;
DBufInit(&buf); DBufInit(&buf);
trig->y = NO_YR; trig->y = NO_YR;
@@ -164,6 +166,32 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
/* Figure out what we've got */ /* Figure out what we've got */
FindToken(DBufValue(&buf), &tok); FindToken(DBufValue(&buf), &tok);
switch(tok.type) { switch(tok.type) {
case T_Date:
DBufFree(&buf);
if (trig->d != NO_DAY) return E_DAY_TWICE;
if (trig->m != NO_MON) return E_MON_TWICE;
if (trig->y != NO_YR) return E_YR_TWICE;
FromJulian(tok.val, &y, &m, &d);
trig->y = y;
trig->m = m;
trig->d = d;
break;
case T_DateTime:
DBufFree(&buf);
if (trig->d != NO_DAY) return E_DAY_TWICE;
if (trig->m != NO_MON) return E_MON_TWICE;
if (trig->y != NO_YR) return E_YR_TWICE;
FromJulian(tok.val / MINUTES_PER_DAY, &y, &m, &d);
trig->y = y;
trig->m = m;
trig->d = d;
tim->ttime = (tok.val % MINUTES_PER_DAY);
if (save_in_globals) {
LastTriggerTime = tim->ttime;
}
break;
case T_WkDay: case T_WkDay:
DBufFree(&buf); DBufFree(&buf);
if (trig->wd & (1 << tok.val)) return E_WD_TWICE; if (trig->wd & (1 << tok.val)) return E_WD_TWICE;
@@ -462,6 +490,23 @@ static int ParseUntil(ParsePtr s, Trigger *t)
d = tok.val; d = tok.val;
break; break;
case T_Date:
DBufFree(&buf);
if (y != NO_YR) {
Eprint("UNTIL: %s", ErrMsg[E_YR_TWICE]);
return E_YR_TWICE;
}
if (m != NO_MON) {
Eprint("UNTIL: %s", ErrMsg[E_MON_TWICE]);
return E_MON_TWICE;
}
if (d != NO_DAY) {
Eprint("UNTIL: %s", ErrMsg[E_DAY_TWICE]);
return E_DAY_TWICE;
}
FromJulian(tok.val, &y, &m, &d);
break;
default: default:
if (y == NO_YR || m == NO_MON || d == NO_DAY) { if (y == NO_YR || m == NO_MON || d == NO_DAY) {
Eprint("UNTIL: %s", ErrMsg[E_INCOMPLETE]); Eprint("UNTIL: %s", ErrMsg[E_INCOMPLETE]);
@@ -537,6 +582,23 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
d = tok.val; d = tok.val;
break; break;
case T_Date:
DBufFree(&buf);
if (y != NO_YR) {
Eprint("%s: %s", word, ErrMsg[E_YR_TWICE]);
return E_YR_TWICE;
}
if (m != NO_MON) {
Eprint("%s: %s", word, ErrMsg[E_MON_TWICE]);
return E_MON_TWICE;
}
if (d != NO_DAY) {
Eprint("%s: %s", word, ErrMsg[E_DAY_TWICE]);
return E_DAY_TWICE;
}
FromJulian(tok.val, &y, &m, &d);
break;
default: default:
if (y == NO_YR || m == NO_MON || d == NO_DAY) { if (y == NO_YR || m == NO_MON || d == NO_DAY) {
Eprint("%s: %s", word, ErrMsg[E_INCOMPLETE]); Eprint("%s: %s", word, ErrMsg[E_INCOMPLETE]);

View File

@@ -42,7 +42,6 @@ static int Multiply(void), Divide(void), Mod(void), Add(void),
Compare(int); Compare(int);
static int MakeValue (char const *s, Value *v, Var *locals); static int MakeValue (char const *s, Value *v, Var *locals);
static int ParseLiteralDate (char const **s, int *jul, int *tim);
/* Binary operators - all left-associative */ /* Binary operators - all left-associative */
@@ -73,9 +72,7 @@ Operator UnOp[] = {
}; };
#define NUM_UN_OPS (sizeof(UnOp) / sizeof(Operator)) #define NUM_UN_OPS (sizeof(UnOp) / sizeof(Operator))
/* Functions have the same definitions as operators, except the prec field extern BuiltinFunc Func[];
is used to indicate how many arguments are needed. */
extern Operator Func[];
Operator OpStack[OP_STACK_SIZE]; Operator OpStack[OP_STACK_SIZE];
Value ValStack[VAL_STACK_SIZE]; Value ValStack[VAL_STACK_SIZE];
@@ -333,7 +330,8 @@ int Evaluate(char const **s, Var *locals)
{ {
int OpBase, ValBase; int OpBase, ValBase;
int r; int r;
Operator *f; Operator *o;
BuiltinFunc *f;
int args; /* Number of function arguments */ int args; /* Number of function arguments */
Operator op, op2; Operator op, op2;
Value va; Value va;
@@ -410,10 +408,10 @@ int Evaluate(char const **s, Var *locals)
if (r) return r; if (r) return r;
} }
} else { /* Unary operator */ } else { /* Unary operator */
f = FindFunc(DBufValue(&ExprBuf), UnOp, NUM_UN_OPS); o = FindOperator(DBufValue(&ExprBuf), UnOp, NUM_UN_OPS);
if (f) { if (o) {
DBufFree(&ExprBuf); DBufFree(&ExprBuf);
PushOpStack(*f); PushOpStack(*o);
continue; /* Still looking for an atomic vlue */ continue; /* Still looking for an atomic vlue */
} else if (!ISID(*DBufValue(&ExprBuf)) && } else if (!ISID(*DBufValue(&ExprBuf)) &&
*DBufValue(&ExprBuf) != '$' && *DBufValue(&ExprBuf) != '$' &&
@@ -459,13 +457,13 @@ int Evaluate(char const **s, Var *locals)
return OK; return OK;
} }
/* Must be a binary operator */ /* Must be a binary operator */
f = FindFunc(DBufValue(&ExprBuf), BinOp, NUM_BIN_OPS); o = FindOperator(DBufValue(&ExprBuf), BinOp, NUM_BIN_OPS);
DBufFree(&ExprBuf); DBufFree(&ExprBuf);
if (!f) return E_EXPECTING_BINOP; if (!o) return E_EXPECTING_BINOP;
/* While operators of higher or equal precedence are on the stack, /* While operators of higher or equal precedence are on the stack,
pop them off and evaluate */ pop them off and evaluate */
while (OpStackPtr > OpBase && OpStack[OpStackPtr-1].prec >= f->prec) { while (OpStackPtr > OpBase && OpStack[OpStackPtr-1].prec >= o->prec) {
PopOpStack(op2); PopOpStack(op2);
if (r) return r; if (r) return r;
if (DebugFlag & DB_PRTEXPR) if (DebugFlag & DB_PRTEXPR)
@@ -477,7 +475,7 @@ int Evaluate(char const **s, Var *locals)
return r; return r;
} }
} }
PushOpStack(*f); PushOpStack(*o);
} }
} }
@@ -1126,7 +1124,28 @@ static int LogNot(void)
/* Find a function. */ /* Find a function. */
/* */ /* */
/***************************************************************/ /***************************************************************/
Operator *FindFunc(char const *name, Operator where[], int num) Operator *FindOperator(char const *name, Operator where[], int num)
{
int top=num-1, bot=0;
int mid, r;
while (top >= bot) {
mid = (top + bot) / 2;
r = StrCmpi(name, where[mid].name);
if (!r) return &where[mid];
else if (r > 0) bot = mid+1;
else top = mid-1;
}
return NULL;
}
/***************************************************************/
/* */
/* FindFunc */
/* */
/* Find a function. */
/* */
/***************************************************************/
BuiltinFunc *FindFunc(char const *name, BuiltinFunc where[], int num)
{ {
int top=num-1, bot=0; int top=num-1, bot=0;
int mid, r; int mid, r;
@@ -1202,7 +1221,7 @@ int CopyValue(Value *dest, const Value *src)
/* and tim; update s. */ /* and tim; update s. */
/* */ /* */
/***************************************************************/ /***************************************************************/
static int ParseLiteralDate(char const **s, int *jul, int *tim) int ParseLiteralDate(char const **s, int *jul, int *tim)
{ {
int y, m, d; int y, m, d;
int hour, min; int hour, min;

File diff suppressed because it is too large Load Diff

View File

@@ -133,6 +133,11 @@ void InitRemind(int argc, char const *argv[])
char const *s; char const *s;
int weeks; int weeks;
int jul, tim;
jul = NO_DATE;
tim = NO_TIME;
/* Initialize global dynamic buffers */ /* Initialize global dynamic buffers */
DBufInit(&Banner); DBufInit(&Banner);
DBufInit(&LineBuffer); DBufInit(&LineBuffer);
@@ -480,18 +485,32 @@ void InitRemind(int argc, char const *argv[])
} }
break; break;
case T_DateTime:
if (SysTime != -1L) Usage();
if (m != NO_MON || d != NO_DAY || y != NO_YR || jul != NO_DATE) Usage();
SysTime = (tok.val % MINUTES_PER_DAY) * 60;
DontQueue = 1;
Daemon = 0;
jul = tok.val / MINUTES_PER_DAY;
break;
case T_Date:
if (m != NO_MON || d != NO_DAY || y != NO_YR || jul != NO_DATE) Usage();
jul = tok.val;
break;
case T_Month: case T_Month:
if (m != NO_MON) Usage(); if (m != NO_MON || jul != NO_DATE) Usage();
else m = tok.val; else m = tok.val;
break; break;
case T_Day: case T_Day:
if (d != NO_DAY) Usage(); if (d != NO_DAY || jul != NO_DATE) Usage();
else d = tok.val; else d = tok.val;
break; break;
case T_Year: case T_Year:
if (y != NO_YR) Usage(); if (y != NO_YR || jul != NO_DATE) Usage();
else y = tok.val; else y = tok.val;
break; break;
@@ -500,7 +519,8 @@ void InitRemind(int argc, char const *argv[])
else rep = tok.val; else rep = tok.val;
break; break;
default: Usage(); default:
Usage();
} }
} }
@@ -510,6 +530,9 @@ void InitRemind(int argc, char const *argv[])
Daemon = 0; Daemon = 0;
} }
if (jul != NO_DATE) {
FromJulian(jul, &y, &m, &d);
}
/* Must supply date in the form: day, mon, yr OR mon, yr */ /* Must supply date in the form: day, mon, yr OR mon, yr */
if (m != NO_MON || y != NO_YR || d != NO_DAY) { if (m != NO_MON || y != NO_YR || d != NO_DAY) {
if (m == NO_MON || y == NO_YR) { if (m == NO_MON || y == NO_YR) {
@@ -555,7 +578,7 @@ void InitRemind(int argc, char const *argv[])
void Usage(void) void Usage(void)
{ {
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1998 David F. Skoll\n", VERSION, L_LANGNAME); fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1998 David F. Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "Copyright 1999-2008 Roaring Penguin Software Inc.\n"); fprintf(ErrFp, "Copyright 1999-2009 Roaring Penguin Software Inc.\n");
#ifdef BETA #ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n"); fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif #endif

View File

@@ -7,7 +7,7 @@
/* */ /* */
/* This file is part of REMIND. */ /* This file is part of REMIND. */
/* Copyright (C) 1992-1998 by David F. Skoll */ /* Copyright (C) 1992-1998 by David F. Skoll */
/* Copyright (C) 1999-2000 by Roaring Penguin Software Inc. */ /* Copyright (C) 1999-2009 by Roaring Penguin Software Inc. */
/* */ /* */
/***************************************************************/ /***************************************************************/

View File

@@ -294,6 +294,14 @@ int DoOmit(ParsePtr p)
if ( (r=ParseToken(p, &buf)) ) return r; if ( (r=ParseToken(p, &buf)) ) return r;
FindToken(DBufValue(&buf), &tok); FindToken(DBufValue(&buf), &tok);
switch (tok.type) { switch (tok.type) {
case T_Date:
DBufFree(&buf);
if (y != NO_YR) return E_YR_TWICE;
if (m != NO_MON) return E_MON_TWICE;
if (d != NO_DAY) return E_DAY_TWICE;
FromJulian(tok.val, &y, &m, &d);
break;
case T_Year: case T_Year:
DBufFree(&buf); DBufFree(&buf);
if (y != NO_YR) return E_YR_TWICE; if (y != NO_YR) return E_YR_TWICE;
@@ -311,7 +319,7 @@ int DoOmit(ParsePtr p)
if (d != NO_DAY) return E_DAY_TWICE; if (d != NO_DAY) return E_DAY_TWICE;
d = tok.val; d = tok.val;
break; break;
case T_Delta: case T_Delta:
DBufFree(&buf); DBufFree(&buf);
break; break;

View File

@@ -31,6 +31,7 @@ int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int jul);
int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int jul, int *err); int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int jul, int *err);
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul, int mode); int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul, int mode);
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int jul, int tim); int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int jul, int tim);
int ParseLiteralDate (char const **s, int *jul, int *tim);
int EvalExpr (char const **e, Value *v); int EvalExpr (char const **e, Value *v);
int DoCoerce (char type, Value *v); int DoCoerce (char type, Value *v);
void PrintValue (Value *v, FILE *fp); void PrintValue (Value *v, FILE *fp);
@@ -42,7 +43,7 @@ int IncludeFile (char const *fname);
int GetAccessDate (char const *file); int GetAccessDate (char const *file);
int SetAccessDate (char const *fname, int jul); int SetAccessDate (char const *fname, int jul);
int TopLevel (void); int TopLevel (void);
int CallFunc (Operator *f, int nargs); int CallFunc (BuiltinFunc *f, int nargs);
void InitRemind (int argc, char const *argv[]); void InitRemind (int argc, char const *argv[]);
void Usage (void); void Usage (void);
int Julian (int year, int month, int day); int Julian (int year, int month, int day);
@@ -104,7 +105,8 @@ int DoMsgCommand (char const *cmd, char const *msg);
int ParseNonSpaceChar (ParsePtr p, int *err, int peek); int ParseNonSpaceChar (ParsePtr p, int *err, int peek);
unsigned int HashVal (char const *str); unsigned int HashVal (char const *str);
int DateOK (int y, int m, int d); int DateOK (int y, int m, int d);
Operator *FindFunc (char const *name, Operator where[], int num); Operator *FindOperator (char const *name, Operator where[], int num);
BuiltinFunc *FindFunc (char const *name, BuiltinFunc where[], int num);
int InsertIntoSortBuffer (int jul, int tim, char const *body, int typ, int prio); int InsertIntoSortBuffer (int jul, int tim, char const *body, int typ, int prio);
void IssueSortedReminders (void); void IssueSortedReminders (void);
int UserFuncExists (char const *fn); int UserFuncExists (char const *fn);

View File

@@ -256,12 +256,30 @@ void FindToken(char const *s, Token *tok)
void FindNumericToken(char const *s, Token *t) void FindNumericToken(char const *s, Token *t)
{ {
int mult = 1, hour, min; int mult = 1, hour, min;
char const *s_orig = s;
t->type = T_Illegal; t->type = T_Illegal;
t->val = 0; t->val = 0;
if (isdigit(*s)) { if (isdigit(*s)) {
PARSENUM(t->val, s); PARSENUM(t->val, s);
/* If we hit a '-' or a '/', we may have a date or a datetime */
if (*s == '-' || *s == '/') {
char const *p = s_orig;
int jul, tim;
if (ParseLiteralDate(&p, &jul, &tim) == OK) {
if (*p) return;
if (tim == NO_TIME) {
t->type = T_Date;
t->val = jul;
return;
}
t->type = T_DateTime;
t->val = MINUTES_PER_DAY * jul + tim;
}
return;
}
/* If we hit a comma, swallow it. This allows stuff /* If we hit a comma, swallow it. This allows stuff
like Jan 6, 1998 */ like Jan 6, 1998 */
if (*s == ',') { if (*s == ',') {

View File

@@ -30,6 +30,20 @@ typedef struct {
int (*func)(void); int (*func)(void);
} Operator; } Operator;
/* Structure for passing in Nargs and out RetVal from functions */
typedef struct {
int nargs;
Value retval;
} func_info;
/* Define the type of user-functions */
typedef struct {
char const *name;
char minargs;
char maxargs;
int (*func)(func_info *);
} BuiltinFunc;
/* Define the structure of a variable */ /* Define the structure of a variable */
typedef struct var { typedef struct var {
struct var *next; struct var *next;
@@ -133,7 +147,7 @@ enum TokTypes
T_IfTrig, T_ErrMsg, T_IfTrig, T_ErrMsg,
T_Set, T_UnSet, T_Fset, T_Omit, T_Banner, T_Exit, T_Set, T_UnSet, T_Fset, T_Omit, T_Banner, T_Exit,
T_WkDay, T_WkDay,
T_Month, T_Time, T_Month, T_Time, T_Date, T_DateTime,
T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta, T_Back, T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta, T_Back,
T_Once, T_Once,
T_Empty, T_Empty,

View File

@@ -40,7 +40,7 @@ static UserFunc *FuncHash[FUNC_HASH_SIZE];
/* Access to built-in functions */ /* Access to built-in functions */
extern int NumFuncs; extern int NumFuncs;
extern Operator Func[]; extern BuiltinFunc Func[];
/* We need access to the expression evaluation stack */ /* We need access to the expression evaluation stack */
extern Value ValStack[]; extern Value ValStack[];

View File

@@ -672,6 +672,16 @@ Leaving UserFN _ofunc() => 0
REM 1 March OMIT Sun AFTER MSG Should trigger 4 March REM 1 March OMIT Sun AFTER MSG Should trigger 4 March
../tests/test.rem(177): Trig = Monday, 4 March, 1991 ../tests/test.rem(177): Trig = Monday, 4 March, 1991
# Test shorthand reminders
REM 1991-02-28 MSG Feb 28
../tests/test.rem(180): Trig = Thursday, 28 February, 1991
REM 1991/02/28@14:45 MSG Feb 28
../tests/test.rem(181): Trig = Thursday, 28 February, 1991
REM Wed UNTIL 1991-01-01 MSG Expired
../tests/test.rem(182): Expired
REM Wed SCANFROM 1991-02-26 MSG SCANFROM
../tests/test.rem(183): Trig = Wednesday, 27 February, 1991
set a000 abs(1) set a000 abs(1)
abs(1) => 1 abs(1) => 1
set a001 abs(-1) set a001 abs(-1)
@@ -694,7 +704,7 @@ set a008 coerce("string", 11:44)
coerce("string", 11:44) => "11:44" coerce("string", 11:44) => "11:44"
set a009 coerce("int", "badnews") set a009 coerce("int", "badnews")
coerce("int", "badnews") => Can't coerce coerce("int", "badnews") => Can't coerce
../tests/test.rem(188): Can't coerce ../tests/test.rem(194): Can't coerce
set a010 coerce("int", "12") set a010 coerce("int", "12")
coerce("int", "12") => 12 coerce("int", "12") => 12
set a011 coerce("int", 11:44) set a011 coerce("int", 11:44)
@@ -706,7 +716,7 @@ set a013 date(1992, 2, 2)
date(1992, 2, 2) => 1992-02-02 date(1992, 2, 2) => 1992-02-02
set a014 date(1993, 2, 29) set a014 date(1993, 2, 29)
date(1993, 2, 29) => Bad date specification date(1993, 2, 29) => Bad date specification
../tests/test.rem(193): Bad date specification ../tests/test.rem(199): Bad date specification
set a015 day(today()) set a015 day(today())
today() => 1991-02-16 today() => 1991-02-16
day(1991-02-16) => 16 day(1991-02-16) => 16
@@ -801,15 +811,15 @@ strlen("sadjflkhsldkfhsdlfjhk") => 21
set a050 substr(a049, 2) set a050 substr(a049, 2)
a049 => 21 a049 => 21
substr(21, 2) => Type mismatch substr(21, 2) => Type mismatch
../tests/test.rem(231): Type mismatch ../tests/test.rem(237): Type mismatch
set a051 substr(a050, 2, 6) set a051 substr(a050, 2, 6)
a050 => ../tests/test.rem(232): Undefined variable: a050 a050 => ../tests/test.rem(238): Undefined variable: a050
set a052 time(1+2, 3+4) set a052 time(1+2, 3+4)
1 + 2 => 3 1 + 2 => 3
3 + 4 => 7 3 + 4 => 7
time(3, 7) => 03:07 time(3, 7) => 03:07
rem 10 jan 1992 AT 11:22 CAL rem 10 jan 1992 AT 11:22 CAL
../tests/test.rem(234): Trig = Friday, 10 January, 1992 ../tests/test.rem(240): Trig = Friday, 10 January, 1992
set a053 trigdate() set a053 trigdate()
trigdate() => 1992-01-10 trigdate() => 1992-01-10
set a054 trigtime() set a054 trigtime()
@@ -822,7 +832,7 @@ set a057 value("a05"+"6")
"a05" + "6" => "a056" "a05" + "6" => "a056"
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH" value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
set a058 version() set a058 version()
version() => "03.01.06" version() => "03.01.07"
set a059 wkday(today()) set a059 wkday(today())
today() => 1991-02-16 today() => 1991-02-16
wkday(1991-02-16) => "Saturday" wkday(1991-02-16) => "Saturday"
@@ -901,31 +911,31 @@ y => 11:33
x => "foo" x => "foo"
y => 11:33 y => 11:33
"foo" * 11:33 => Type mismatch "foo" * 11:33 => Type mismatch
../tests/test.rem(257): `*': Type mismatch ../tests/test.rem(263): `*': Type mismatch
Leaving UserFN h() => Type mismatch Leaving UserFN h() => Type mismatch
set a074 dosubst("%a %b %c %d %e %f %g %h", '1992/5/5') 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"... dosubst("%a %b %c %d %e %f %g %h", 1992-05-05) => "on Tuesday, 5 May, 1992 in 444 days' tim"...
msg [a074]% msg [a074]%
../tests/test.rem(259): Trig = Saturday, 16 February, 1991 ../tests/test.rem(265): Trig = Saturday, 16 February, 1991
a074 => "on Tuesday, 5 May, 1992 in 444 days' tim"... 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 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') 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"... dosubst("%i %j %k %l %m %n %o %p", 1992-05-05) => "on 05-05 on Tuesday, May 5th, 1992 on Tu"...
msg [a075]% msg [a075]%
../tests/test.rem(261): Trig = Saturday, 16 February, 1991 ../tests/test.rem(267): Trig = Saturday, 16 February, 1991
a075 => "on 05-05 on Tuesday, May 5th, 1992 on Tu"... 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 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') 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"... dosubst("%q %r %s %t %u %v %w %x", 1992-05-05) => "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
msg [a076]% msg [a076]%
../tests/test.rem(263): Trig = Saturday, 16 February, 1991 ../tests/test.rem(269): Trig = Saturday, 16 February, 1991
a076 => "s' 05 th 05 on Tuesday, 5th May, 1992 on"... 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 s' 05 th 05 on Tuesday, 5th May, 1992 on Tuesday, 5th May Tuesday 444
set a077 dosubst("%y %z", '1992/5/5') set a077 dosubst("%y %z", '1992/5/5')
dosubst("%y %z", 1992-05-05) => "1992 92 dosubst("%y %z", 1992-05-05) => "1992 92
" "
msg [a077]% msg [a077]%
../tests/test.rem(265): Trig = Saturday, 16 February, 1991 ../tests/test.rem(271): Trig = Saturday, 16 February, 1991
a077 => "1992 92 a077 => "1992 92
" "
1992 92 1992 92
@@ -937,6 +947,16 @@ easterdate(1992) => 1992-04-19
set a080 easterdate(1995) set a080 easterdate(1995)
easterdate(1995) => 1995-04-16 easterdate(1995) => 1995-04-16
set a081 "" set a081 ""
OMIT 1991-03-11
set a082 slide('1991-03-01', 7, "Sat", "Sun")
slide(1991-03-01, 7, "Sat", "Sun") => 1991-03-13
set a083 slide('1991-04-01', -7, "Sat")
- 7 => -7
slide(1991-04-01, -7, "Sat") => 1991-03-24
set a084 nonomitted('1991-03-01', '1991-03-13', "Sat", "Sun")
nonomitted(1991-03-01, 1991-03-13, "Sat", "Sun") => 7
set a085 nonomitted('1991-03-24', '1991-04-01', "Sat")
nonomitted(1991-03-24, 1991-04-01, "Sat") => 7
dump dump
Variable Value Variable Value
@@ -948,6 +968,7 @@ dump
a027 0 a027 0
a046 "ies" a046 "ies"
a065 1 a065 1
a084 7
a018 1 a018 1
a037 1991-02-15 a037 1991-02-15
a056 "SDFJHSDF KSJDFH KJSDFH KSJDFH" a056 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
@@ -955,6 +976,7 @@ dump
a028 1 a028 1
a047 -1 a047 -1
a066 0 a066 0
a085 7
a019 0 a019 0
a038 33 a038 33
a057 "SDFJHSDF KSJDFH KJSDFH KSJDFH" a057 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
@@ -963,7 +985,7 @@ dump
a048 "foo" a048 "foo"
a067 "INT" a067 "INT"
a039 "February" a039 "February"
a058 "03.01.06" a058 "03.01.07"
a077 "1992 92 a077 "1992 92
" "
a049 21 a049 21
@@ -1011,6 +1033,7 @@ dump
a025 4 a025 4
a044 "s" a044 "s"
a063 0 a063 0
a082 1991-03-13
a016 28 a016 28
a035 1 a035 1
a054 11:22 a054 11:22
@@ -1018,6 +1041,7 @@ dump
a026 7 a026 7
a045 "iess" a045 "iess"
a064 1 a064 1
a083 1991-03-24
Test 2 Test 2

View File

@@ -176,6 +176,12 @@ OMIT 2 March 1991
REM 1 March OMIT Sun OMITFUNC _ofunc AFTER MSG Should trigger 1 March REM 1 March OMIT Sun OMITFUNC _ofunc AFTER MSG Should trigger 1 March
REM 1 March OMIT Sun AFTER MSG Should trigger 4 March REM 1 March OMIT Sun AFTER MSG Should trigger 4 March
# Test shorthand reminders
REM 1991-02-28 MSG Feb 28
REM 1991/02/28@14:45 MSG Feb 28
REM Wed UNTIL 1991-01-01 MSG Expired
REM Wed SCANFROM 1991-02-26 MSG SCANFROM
set a000 abs(1) set a000 abs(1)
set a001 abs(-1) set a001 abs(-1)
set a002 asc("foo") set a002 asc("foo")
@@ -267,4 +273,9 @@ set a078 easterdate(today())
set a079 easterdate(1992) set a079 easterdate(1992)
set a080 easterdate(1995) set a080 easterdate(1995)
set a081 "" set a081 ""
OMIT 1991-03-11
set a082 slide('1991-03-01', 7, "Sat", "Sun")
set a083 slide('1991-04-01', -7, "Sat")
set a084 nonomitted('1991-03-01', '1991-03-13', "Sat", "Sun")
set a085 nonomitted('1991-03-24', '1991-04-01', "Sat")
dump dump