Compare commits

...

52 Commits

Author SHA1 Message Date
Dianne Skoll
732ce8283f Update docs. 2022-03-11 21:47:50 -05:00
Dianne Skoll
122bd3e07e Add comment 2022-03-11 21:27:33 -05:00
Dianne Skoll
0ac5cbb837 Properly cope with two of the same moon phase in a given month. 2022-03-11 21:26:22 -05:00
Dianne Skoll
7f3d4812a8 Add Lastday and Lastworkday syntactic sugar 2022-03-11 21:11:16 -05:00
Dianne Skoll
e1fa11c94c Add the First/Second/Third/Fourth/Last syntactic sugar and the
~N/~~N forms of "back"
2022-03-11 20:53:52 -05:00
Dianne Skoll
c06c65acf1 Properly apply options in the right order. 2022-03-11 19:57:20 -05:00
Dianne Skoll
a84fa0bc8f Add canned "Light Theme" and "Dark Theme" buttons. 2022-03-11 19:46:40 -05:00
Dianne Skoll
054648e02b More display tweakage. 2022-03-11 14:35:39 -05:00
Dianne Skoll
9548041334 Tweak display; make keyboard traversal better. 2022-03-11 14:29:07 -05:00
Dianne Skoll
da306f2900 Tweak wording 2022-03-11 13:46:43 -05:00
Dianne Skoll
26587aea02 Give more control over TkRemind colors. 2022-03-11 13:38:11 -05:00
Dianne Skoll
adc86e0f00 Allow setting of "Today" highlight color. 2022-03-10 11:53:00 -05:00
Dianne Skoll
a9ed5f075e Document that trig() and SATISFY should not be mixed. 2022-03-05 11:35:55 -05:00
Dianne Skoll
21e30c980e Test multiple-argument version of trig() 2022-03-04 17:29:23 -05:00
Dianne Skoll
a657b2e55a Update man page. 2022-03-04 15:40:39 -05:00
Dianne Skoll
ff8c55b8b6 Rename "wouldtrig" to just "trig" 2022-03-04 15:38:07 -05:00
Dianne Skoll
eb36c5bca0 Allow wouldtrig() to take an arbitrary number of args; document it. 2022-03-04 15:24:52 -05:00
Dianne Skoll
89173ce1ee Allow logical operators to accept any non-string operands.
Make wouldtrig() return a date.
2022-03-04 14:59:17 -05:00
Dianne Skoll
5d115ba3e3 Document actual behavior of IF command. 2022-03-04 14:58:49 -05:00
Dianne Skoll
7e3adeb9c9 Make wouldtrig return the trigger date (as an INT, coercable to a date)
Update man page.
2022-03-04 12:28:13 -05:00
Dianne Skoll
080cda86fa Document new || and && return values. 2022-03-04 12:12:49 -05:00
Dianne Skoll
6274cbad52 Make || return first true val and && return last val if first val is true. 2022-03-04 12:11:25 -05:00
Dianne Skoll
85c4ad821d Add note about Remind lacking short-circuit logical operators. 2022-03-04 11:45:37 -05:00
Dianne Skoll
b758a2fea8 Tweak formatting. 2022-03-04 11:40:46 -05:00
Dianne Skoll
6619cc7ca4 Add wouldtrig tests. 2022-03-04 11:33:03 -05:00
Dianne Skoll
961f7a8a62 Document wouldtrig() 2022-03-04 11:21:14 -05:00
Dianne Skoll
905287901f Add zero-argument form of wouldtrig. 2022-03-04 11:16:33 -05:00
Dianne Skoll
669be7bf57 Add wouldtrig function. 2022-03-04 11:00:09 -05:00
Dianne Skoll
9b8eb2dc4c Support calling EvalExpr recursively 2022-03-04 10:49:20 -05:00
Dianne Skoll
00ab7b196d Set default of $MaxSatIter to 1000 instead of 150.
Computers are much faster than when Remind was first written;
we can handle a much higher limit.
2022-03-04 08:18:49 -05:00
Dianne Skoll
f616be4bdd Add comment about operator precedence. 2022-03-04 08:16:58 -05:00
Dianne Skoll
8ae9ce8523 Tweak man page. 2022-03-02 15:30:56 -05:00
Dianne Skoll
6d2bbbd7e2 Another diagnostic message. 2022-03-02 15:25:27 -05:00
Dianne Skoll
1453be83b2 Add more diagnostics for bad UNTIL dates. 2022-03-02 15:17:03 -05:00
Dianne Skoll
8659131be2 Use proper keyword in error message. 2022-03-02 14:43:11 -05:00
Dianne Skoll
0276ce322d Diagnose if UNTIL is earlier than start date unless there is a nonconst expr 2022-03-02 09:11:01 -05:00
Dianne Skoll
b36c99a34b Move successful exit to one spot. 2022-03-02 09:01:33 -05:00
Dianne Skoll
ad575f1485 Proper check for overfull box. 2022-03-01 16:15:00 -05:00
Dianne Skoll
a9162f1472 Proper calculation for warning of overfull box. 2022-03-01 16:12:55 -05:00
Dianne Skoll
221e2554a9 Prep for 03.04.01 release. 2022-02-23 11:09:39 -05:00
Dianne Skoll
04ec6c3695 Update TodayDay, TodayMonth and TodayYear in Initialize, in case date has rolled over 2022-02-15 10:04:30 -05:00
Dianne Skoll
b1594980fc Add --disable-perl-build-artifacts flag to configure. 2022-02-13 10:42:50 -05:00
Dianne Skoll
024a8ef38d Double-check that chosen font size for small calendars won't overflow box. 2022-02-13 10:33:21 -05:00
Dianne Skoll
b281051421 Don't overflow small calendar box. 2022-02-12 23:30:08 -05:00
Dianne Skoll
aa1b275b51 Support INSTALL_BASE 2022-02-11 10:55:59 -05:00
Dianne Skoll
c22ca68857 Support INSTALL_BASE env var 2022-02-11 10:39:31 -05:00
Dianne Skoll
3804ce3fe3 Prep for 03.04.00 release. 2022-02-10 17:15:01 -05:00
Dianne Skoll
0977f1db04 Don't export the 'php' directory. 2022-02-10 10:07:41 -05:00
Dianne Skoll
83c97934c9 Fix typo 2022-02-09 09:43:11 -05:00
Dianne Skoll
44c9d74caa Preserve #include "custom.h" in config.h.in. Patch due to Jochen Sprickerhof 2022-02-09 09:10:47 -05:00
Dianne Skoll
172f56754a Fix groff errors - patch from Jochen Sprickerhof 2022-02-09 08:59:58 -05:00
Dianne Skoll
dc184cc713 Don't fail "make clean" in src - patch from Jochen Sprickerhof. 2022-02-09 08:58:47 -05:00
25 changed files with 1213 additions and 290 deletions

3
.gitattributes vendored
View File

@@ -1,4 +1,5 @@
.gitignore export-ignore
.gitattributes export-ignore
remind.php export-ignore
sync-to-dianne-git export-ignore
sync-to-dianne-git export-ignore
php export-ignore

View File

@@ -20,10 +20,10 @@ install:
@echo ""
@$(MAKE) -C src install
@$(MAKE) -C rem2html install
@$(MAKE) -C rem2pdf -f Makefile.top install
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
clean:
find . -name '*~' -exec rm {} \;
$(MAKE) -C src clean
-$(MAKE) -C src clean
-$(MAKE) -C rem2pdf clean
test:

28
configure vendored
View File

@@ -622,6 +622,7 @@ ac_includes_default="\
ac_header_list=
ac_subst_vars='LTLIBOBJS
LIBOBJS
PERLARTIFACTS
VERSION
EGREP
GREP
@@ -681,6 +682,7 @@ SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_perl_build_artifacts
'
ac_precious_vars='build_alias
host_alias
@@ -1305,6 +1307,13 @@ if test -n "$ac_init_help"; then
cat <<\_ACEOF
Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-perl-build-artifacts
Disable perllocal.pod and .packlist generation
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
@@ -2292,6 +2301,16 @@ EOF
ac_config_headers="$ac_config_headers src/config.h"
# Check whether --enable-perl-build-artifacts was given.
if test "${enable_perl_build_artifacts+set}" = set; then :
enableval=$enable_perl_build_artifacts; ac_cv_perlartifacts=$enableval
else
ac_cv_perlartifacts=yes
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3957,6 +3976,12 @@ if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
fi
if test "$ac_cv_perlartifacts" = "yes" ; then
PERLARTIFACTS=
else
PERLARTIFACTS='NO_PACKLIST=1 NO_PERLLOCAL=1'
fi
for ac_func in setenv unsetenv glob mbstowcs setlocale initgroups
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
@@ -3969,7 +3994,8 @@ _ACEOF
fi
done
VERSION=03.04.00
VERSION=03.04.02
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf"

View File

@@ -14,6 +14,12 @@ EOF
AC_CONFIG_HEADER(src/config.h)
AC_ARG_ENABLE(perl-build-artifacts,
[ --disable-perl-build-artifacts
Disable perllocal.pod and .packlist generation], ac_cv_perlartifacts=$enableval, ac_cv_perlartifacts=yes)
AH_BOTTOM([#include <custom.h>])
dnl Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
@@ -44,9 +50,16 @@ if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
fi
if test "$ac_cv_perlartifacts" = "yes" ; then
PERLARTIFACTS=
else
PERLARTIFACTS='NO_PACKLIST=1 NO_PERLLOCAL=1'
fi
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
VERSION=03.04.00
VERSION=03.04.02
AC_SUBST(VERSION)
AC_SUBST(PERL)
AC_SUBST(PERLARTIFACTS)
AC_OUTPUT(src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf)
chmod a+x rem2pdf/bin/rem2pdf

View File

@@ -1,6 +1,77 @@
CHANGES TO REMIND
* VERSION 3.4 Patch 0 - 2022-??-??
* VERSION 3.4 Patch 2 - 2022-??-??
- NEW FEATURE: remind: Add syntactic sugar to simplify some common
types of reminders. See "SYNTACTIC SUGAR FOR REM" in the remind
man page. Based on suggestions from Ian! D. Allen.
- NEW FEATURE: remind: Add the "trig" function to allow more
expressiveness when creating triggers. See man page for details.
- IMPROVEMENT: tkremind: Tweak the calendar display; improve ability to
customize colors, including supplying two built-in themes. Based on
patch and suggestion from Paulo (last name unknown).
- CHANGE: remind: Increase $MaxSatIter default to 1000 instead of 150.
Computers are much faster than when I first wrote remind and they
can handle this higher limit easily. The higher limit also enables
certain reasonable reminders that failed in the past because of the
low SATISFY iteration limit.
- CHANGE: remind: The "||" operator now returns the value of the first
non-zero operand rather than just returning 1 or 0. Similarly, "&&"
returns 0 if either operand is false or the value of the last
operand if both operands are true.
NOTE POTENTIAL INCOMPATIBILITY: Remind scripts that depend on ||
and && always returning exactly one of 1 or 0 may need
adjustment.
- CHANGE: The || and && operators can accept any non-STRING type as long
as both operands have the same type. The "false" values are defined
as follows; true values are any other value:
INT: 0
TIME: 00:00
DATE: '1990-01-01' (the Remind epoch)
DATETIME: '1990-01-01@00:00' (the Remind epoch)
- IMPROVEMENT: remind: Issue diagnostics if an UNTIL or THROUGH date
is earlier than any possible trigger date, as well as an UNTIL date
with a fully-specified date and no repeat ("*N"). Suggestion from
Ian! D. Allen.
- BUG FIX: tkremind: If the same moon phase appeared twice in a month,
TkRemind would not display the first occurrence correctly. This has
been fixed.
- BUG FIX: remind: The IF command documentation didn't reflect how it
actually worked; now it does.
- BUG FIX: remind: Use correct UNTIL/THROUGH keyword in error message.
- BUG FIX: rem2pdf: Correct the calculation that warns about an over-full
calendar box. Problem noted by Jonathan Kamens.
* VERSION 3.4 Patch 1 - 2022-02-23
- MINOR IMPROVEMENT: Support the INSTALL_BASE environment variable for
installing rem2pdf in a non-standard location like your home directory.
This is passed in to rem2pdf's Makefile at build and install time.
- MINOR IMPROVEMENT: ./configure: Add --disable-perl-build-artifacts flag
to avoid installation of perllocal.pod and .packlist files.
- BUG FIX: tkremind: If the system date rolls over, update the display
to correctly highlight the current date. This worked in older versions
of Remind, but was broken by 03.04.00.
- BUG FIX: rem2pdf: The small calendar font would sometimes be scaled
incorrectly so the small calendar overflowed the box. This has been
fixed.
* VERSION 3.4 Patch 0 - 2022-02-10
- MAJOR CHANGE: Remind and its helpers (except for rem2ps) fully support
UTF-8. If your system locale is a UTF-8 locale and your terminal
@@ -42,6 +113,9 @@ CHANGES TO REMIND
- CLEANUP: remind: C source code: Remove various unused or obsolete macros.
- BUG FIXES: Minor fixups to groff source and Makefiles courtesy of
Jochen Sprickerhof.
- BUG FIX: Properly support formatting of double-wide characters in the
terminal mode "remind -c" calendar.

View File

@@ -267,7 +267,7 @@ calendar output.
.TP
\fB\-x\fR[\fIn\fR]
Sets the iteration limit for the \fBSATISFY\fR clause of a \fBREM\fR
command. Defaults to 150.
command. Defaults to 1000.
.TP
\fB\-k\fR\fIcmd\fR
Instead of simply printing \fBMSG\fR-type
@@ -814,7 +814,8 @@ could be specified as:
However, events that do not repeat daily, weekly, monthly or yearly require
another approach. The \fIrepeat\fR component of the \fBREM\fR command
fills this need. To use it, you must completely specify a date (year, month
and day, and optionally weekday.) The \fIrepeat\fR component is an asterisk
and day, and optionally weekday); this is the start date of the
repetition period. The \fIrepeat\fR component is an asterisk
followed by a number specifying the repetition period in days.
.PP
For example, suppose you get paid every second Wednesday, and your
@@ -824,12 +825,12 @@ last payday was Wednesday, 28 October, 1992. You can use:
REM 28 Oct 1992 *14 MSG Payday
.fi
.PP
This issues the reminder every 14 days, starting from the calculated trigger
date. You can use \fIdelta\fR and \fIback\fR with \fIrepeat.\fR Note,
however, that the \fIback\fR is used only to compute the initial
trigger date; thereafter, the reminder repeats with the specified
This issues the reminder every 14 days, starting from 28 Oct 1992.
You can use \fIdelta\fR and \fIback\fR with \fIrepeat.\fR Note,
however, that the \fIback\fR is used only to compute the starting
date; thereafter, the reminder repeats with the specified
period. Similarly, if you specify a weekday, it is used only to calculate
the initial date, and does not affect the repetition period.
the starting date, and does not affect the repetition period.
.PP
.B SCANFROM \fRand\fB FROM
.PP
@@ -1152,6 +1153,84 @@ Note that \fIduration\fR is specified either in hours and minutes as a
duration of 00:00 or 0, then \fBRemind\fR behaves exactly as if no
\fBDURATION\fR at all had been present.
.PP
.SH SYNTACTIC SUGAR FOR REM
.PP
The REM command has syntactic sugar to let you express common
reminders. The following pairs of reminders are equivalent:
.PP
.nf
REM First Monday April MSG Foo
REM Mon 1 April MSG Foo
REM Second Monday May MSG Bar
REM Mon 8 May MSG Bar
REM Third Monday MSG Third Monday of every month
REM Mon 15 MSG Third Monday of every month
REM Fourth Sunday June 2025 MSG Fourth Sunday in June 2025
REM Sun 22 June 2025 MSG Fourth Sunday in June 2025
REM Last Monday MSG Last Monday of every month
REM Mon 1 --7 MSG Last Monday of every month
REM Last Monday April MSG Last Monday of every April
REM Mon 1 May --7 MSG Last Monday of every April
REM Last Monday December 2025 MSG Last Monday of Dec 2025
REM Monday 1 Jan 2026 --7 MSG Last Monday of Dec 2025
.fi
.PP
Note that \fBLast\fR effectively adjusts the month and year, if necessary, to
make the reminder trigger on the correct date.
.PP
The keyword \fBIN\fR is completely ignored, so you can write (for example):
.PP
.nf
REM Second Monday in May MSG foo
REM Last Monday in December 2025 MSG Bar
.fi
.PP
An alternate form of \fIback\fR makes writing reminders easier.
The following groups of reminders are equivalent:
.PP
.nf
REM ~~1 MSG Last day of every month
REM Lastday MSG Last day of every month
REM 1 --1 MSG Last day of every month
REM May ~~1 MSG Last day of May
REM Lastday May MSG Last day of May
REM 1 June --1 MSG Last day of May
REM Dec 2025 ~~1 MSG Last day of December 2025
REM Lastday Dec 2025 MSG Last day of December 2025
REM 1 Jan 2026 --1 MSG Last day of December 2025
REM Apr ~1 OMIT SAT SUN MSG Last workday of April
REM Lastworkday April OMIT SAT SUN MSG Last workday of April
REM 1 May -1 OMIT SAT SUN MSG Last workday of April
REM Apr ~~7 MSG Seventh-last day of April
REM 1 May --7 MSG Seventh-last day of April
REM Apr ~2 OMIT SAT SUN MSG Second-last workday of April
REM 1 May -2 OMIT SAT SUN MSG Second-last workday of April
.fi
.PP
As we see, "Lastday" is equivalent to ~~1 and "Lastworkday" to ~1.
.PP
Note that the First/Second/Third/Fourth/Last keywords and the ~ and ~~ form
of \fIback\fR imply a value for the day of the month; as such, they cannot
be combined with a day. Additionally, First/Second/Third/Fourth/Last
must have at least one weekday name. The following are illegal:
.PP
.nf
REM First Monday 3 June MSG Huh?
REM April 3 ~~1 MSG What?
REM Second June MSG Where's the weekday???
.fi
.PP
.SH THE SUBSTITUTION FILTER
.PP
@@ -1828,7 +1907,7 @@ quotes \fImust\fR be supplied. This distinguishes date constants
from division or subtraction of integers. Examples:
.PP
.RS
\'1993/02/22', '1992-12-25', '1999/01/01'
\(aq1993/02/22', '1992-12-25', '1999/01/01'
.PP
Note that \fBDATE\fR values are \fIprinted\fR
without the quotes. Although either '-' or '/' is accepted as a date
@@ -1846,13 +1925,33 @@ constants with the addition of an "@HH:MM" part, optionally followed
by "am" or "pm". For example:
.PP
.RS
\'2008-04-05@23:11', '1999/02/03@14:06', '2001-04-07@08:30', '2020-01-01@3:20pm'
\(aq2008-04-05@23:11', '1999/02/03@14:06', '2001-04-07@08:30', '2020-01-01@3:20pm'
.PP
\fBDATETIME\fR values are printed without the quotes. Notes about date
and time separator characters for \fBDATE\fR and \fBTIME\fR constants apply
also to \fBDATETIME\fR constants.
.RE
.PP
.B ZERO VALUES
.PP
The non-string types all have an associated \fIzero\fR value, which is
treated as "false" by the IF command and the logical operators. The
zero values are:
.PP
.RS
.PP
\fBINT\fR - 0
.PP
\fBDATE\fR - '1990-01-01'
.PP
\fBTIME\fR - 00:00
.PP
\fBDATETIME\fR - '1990-01-01@00:00'
.RE
.PP
Additionally, for the purpose of the IF command (but \fInot\fR the
logical operators) the empty string "" is considered a false value.
.PP
.B OPERATORS
.PP
\fBRemind\fR has the following operators. Operators on the same line
@@ -1976,14 +2075,16 @@ If the operands are not of the same type, == returns 0 and != returns
.RE
.TP
.B &&
This is the logical AND operator. Both of its operands must be of
type \fBINT\fR. It returns 1 if both operands are non-zero, and 0
otherwise.
This is the logical AND operator. Both of its operands must be of the
same type and must not be \fBSTRING\fR type. Returns the second
operand if both operands are non-zero. Otherwise, returns a zero
of the same type as the operands.
.TP
.B ||
This is the logical OR operator. Both of its operands must be of
type \fBINT\fR. It returns 1 if either operand is non-zero, and 0
otherwise.
the same type and must not be of \fBSTRING\fR type. It returns
the first operand that is non-zero; if both operands are zero, then
returns a zero of the same type as the operands.
.PP
.B NOTES
.PP
@@ -2418,7 +2519,7 @@ Returns the time of "astronomical twilight" on the specified \fIdate\fR. If
.TP
.B ampm(tq_time [,s_am [,s_pm]])
Returns a \fBSTRING\fR that is the result of converting \fItime\fR
(which is either a \fBTIME\R or a \fBDATETIME\fR object) to "AM/PM"
(which is either a \fBTIME\fR or a \fBDATETIME\fR object) to "AM/PM"
format. The optional arguments \fIam\fR and \fIpm\fR are the strings
to append in the AM and PM case, respectively; they default to "AM"
and "PM". The function obeys the system variables $DateSep,
@@ -3116,6 +3217,114 @@ Returns \fBRemind\fR's notion of "today." This may be the actual system
date, or a date supplied on the command line, or the date of the
calendar entry currently being computed.
.TP
.B trig(s_1 [,s_2, ...])
For each string argument s_\fIn\fR, \fBtrig\fR evaluates s_\fIn\fR
as if it were a REM or IFTRIG trigger
specification. If the trigger would trigger today, then the trigger
date is returned and no further triggers are evaluated. If none
of the triggers would trigger today, then the zero date
1990-01-01 is returned.
.RS
\fBtrig\fR also has a zero-argument form; this returns the trigger
date of the \fImost recent\fR \fBtrig\fR function that returned a
non-zero trigger date.
.PP
\fBtrig\fR can be used to make more sophisticated versions of
\fBIFTRIG\fR. For example, if you have meetings every Monday in
June and July, and you want warnings 3 days in advance, you
could use:
.nf
REM [trig("Mon Jun +3", "Mon July +3")] +3 MSG Meeting %b
.fi
.PP
NOTE: We need to repeat the +3 delta outside of the \fBtrig\fR
function for advance warning to work properly. This is because
\fBtrig\fR returns a date constant (the trigger date) and the
REM command does not know the details of \fBtrig\fR's arguments.
.PP
Note that because \fBRemind\fR does not have short-circuit logical
operators, something like:
.PP
.nf
SET a trig("Mon +7") || trig("Fri +7")
.fi
would set the value of trig() to the date of the following
Thursday. Even though trig("Mon +7") always returns true,
the logical-OR operator still evaluates trig("Fri +7") which
\fIalso\fR returns true and sets \fBtrig()\fR.
.PP
You can work around the lack of a short-circuit logical-OR as follows:
If \fBtrig\fR returns a true value, the specific value it returns
can be coerced to a DATE which is the trigger date. So the following code:
.PP
.nf
SET a trig("Mon +4") || trig("Fri +4")
IF a
REM [a] +4 MSG [wkday($T)] %b.
ENDIF
.fi
.PP
would operate as follows:
.PP
.nf
On Monday: Monday today.
On Tuesday: Friday in 3 days' time.
On Wednesday: Friday in 2 days' time.
On Thursday: Monday in 4 days' time.
On Friday: Monday in 3 days' time.
On Saturday: Monday in 2 days' time.
On Sunday: Monday tomorrow.
.fi
.PP
Compare with the following:
.PP
.nf
SET a trig("Mon +4") || trig("Fri +4")
IF a
REM [trig()] +4 MSG [wkday($T)] %b.
ENDIF
.fi
.PP
which yields:
.PP
.nf
On Monday: Friday in 4 days' time.
On Tuesday: Friday in 3 days' time.
On Wednesday: Friday in 2 days' time.
On Thursday: Friday tomorrow.
On Friday: Friday today.
On Saturday: Monday in 2 days' time.
On Sunday: Monday tomorrow.
.fi
.PP
That is because \fBtrig()\fR returns the trigger date of
the \fIlast\fR trig function that returns true,
whereas the value of \fBa\fR is the trigger date of the \fIfirst\fR
trig function that returns true.
.PP
\fBImportant Note\fR: Because \fBtrig()\fR always returns an absolute
date, it will \fBnot\fR work properly with a \fBSATISFY\fR clause.
Consider this reminder:
.PP
.nf
REM [trig("Mar", "Apr")] SATISFY [$Td == 15] MSG 15 Mar or April
.fi
.PP
If we run \fBRemind\fR on 5 March 2022, we might expect the trigger
date to be calculated as 15 March 2022... but that's not what happens.
Instead, the \fBtrig\fR function is evaluated first, and it returns
2022-03-05. So as far as \fBRemind\fR is concerned, the REM statement
becomes:
.PP
.nf
REM 2022-03-05 SATISFY [$Td == 15] MSG 15 Mar or April
.fi
.PP
and the SATISFY expression is never true. So: \fIDo not mix
trig() and SATISFY\fR.
.RE
.TP
.B trigdate()
Returns the calculated trigger date of the last \fBREM\fR
or \fBIFTRIG\fR command. If used
@@ -3532,12 +3741,12 @@ Note that the commands are shown indented for clarity. Also, the \fBELSE\fR
portion can be omitted. \fBIF\fR commands can be nested up to a small limit,
probably around 8 or 16 levels of nesting, depending on your system.
.PP
If the \fIexpr\fR evaluates to a non-zero \fBINT\fR, or a non-null
\fBSTRING\fR, then the \fBIF\fR portion is considered true, and the
\fIt-commands\fR are executed. If \fIexpr\fR evaluates to zero or
null, then the \fIf-commands\fR (if the \fBELSE\fR portion is present)
are executed. If \fIexpr\fR is not of type \fBINT\fR or \fBSTRING\fR,
then it is an error.
If the \fIexpr\fR evaluates to a non-zero \fBINT\fR, a \fBDATE\fR that
is not 1990-01-01, a \fBTIME\fR that is not 00:00, a \fBDATETIME\fR
that is not 1990-01-01@00:00, or a non-null \fBSTRING\fR, then the
\fBIF\fR portion is considered true, and the \fIt-commands\fR are
executed. If \fIexpr\fR evaluates to zero or null, then the
\fIf-commands\fR (if the \fBELSE\fR portion is present) are executed.
.PP
Examples:
.PP

View File

@@ -68,7 +68,7 @@ and newmoon.png, which are expected to live in C<--imgbase>.
=item --stylesheet I<url.css>
Use I<url.css> as the stylesheet. If this option is used,
I<url.css> is interpreted relative to B<imgbase> I<unless> it start
I<url.css> is interpreted relative to B<imgbase> I<unless> it starts
with a "/".
=item --nostyle

View File

@@ -29,7 +29,9 @@ install:
if test $$? != 0 ; then echo "Not installing rem2pdf; missing $$m"; exit 0; fi; \
done; \
echo "Installing rem2pdf"; \
if test "$(prefix)" = "/usr" ; then \
if test "$(INSTALL_BASE)" != "" ; then \
$(MAKE) install DESTDIR=$(DESTDIR) "INSTALL_BASE=$(INSTALL_BASE)" && exit 0; \
elif test "$(prefix)" = "/usr" ; then \
$(MAKE) install DESTDIR=$(DESTDIR) INSTALLDIRS=vendor && exit 0; \
else \
$(MAKE) install DESTDIR=$(DESTDIR) && exit 0; \
@@ -37,4 +39,4 @@ install:
exit 1;
Makefile: Makefile.PL
$(PERL) Makefile.PL || true
$(PERL) Makefile.PL @PERLARTIFACTS@ INSTALL_BASE=$(INSTALL_BASE) || true

View File

@@ -637,7 +637,7 @@ sub draw_day
$so_far += $h2;
}
if ($height) {
if ($entry_height > $height) {
if ($h + $entry_height + 2 * $settings->{border_size} > $height) {
print STDERR "WARNING: overfull box at $day " . $self->{monthname} . ' ' . $self->{year} . "\n";
$entry_height = $height;
}
@@ -753,24 +753,13 @@ sub draw_small_calendar
$last_day_on_row += 7;
$rows++;
}
my $layout = Pango::Cairo::create_layout($cr);
my $desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . '10px');
$layout->set_font_description($desc);
$layout->set_text('88 88 88 88 88 88 88');
my ($wid, $h) = $layout->get_pixel_size();
$h += 1;
$h *= ($rows + 2); # row for month name; row for day names
my $font_size = $self->calculate_small_calendar_font_size($cr, $width, $height, $settings, $rows);
my $scale = $width / $wid;
if (($height / $h) < $scale) {
$scale = $height / $h;
}
my $font_size = int($scale * 10);
$layout = Pango::Cairo::create_layout($cr);
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
my $layout = Pango::Cairo::create_layout($cr);
my $desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
$layout->set_font_description($desc);
$layout->set_text('88 ');
($wid, $h) = $layout->get_pixel_size();
my ($wid, $h) = $layout->get_pixel_size();
$h += 1;
# Month name
@@ -824,6 +813,43 @@ sub draw_small_calendar
}
}
sub calculate_small_calendar_font_size
{
my ($self, $cr, $width, $height, $settings, $rows) = @_;
my $layout = Pango::Cairo::create_layout($cr);
my $desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . '10px');
$layout->set_font_description($desc);
$layout->set_text('88 88 88 88 88 88 88');
my ($wid, $h) = $layout->get_pixel_size();
$h += 1;
$h *= ($rows + 2); # row for month name; row for day names
my $scale = $width / $wid;
if (($height / $h) < $scale) {
$scale = $height / $h;
}
my $font_size = int($scale * 10);
# Check
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
$layout->set_font_description($desc);
$layout->set_text('88 88 88 88 88 88 88');
($wid, $h) = $layout->get_pixel_size();
$h += 1;
$h *= ($rows + 2); # row for month name; row for day names
$scale = $width / $wid;
if (($height / $h) < $scale) {
$scale = $height / $h;
}
if ($scale < 1) { # Font size is too big
$font_size--;
}
return $font_size;
}
package Remind::PDF::Multi;
=head1 NAME

View File

@@ -127,6 +127,12 @@ set OptDescr(BackgroundColor) "Default background color of calendar boxes"
set Option(TextColor) "#000000"
set OptDescr(TextColor) "Default text color in calendar boxes"
set Option(TodayColor) "#00C0C0"
set OptDescr(TodayColor) "Background color for today heading"
set Option(LineColor) "#000000"
set OptDescr(LineColor) "Color of gridlines on calendar"
set Option(LabelColor) "#000000"
set OptDescr(LabelColor) "Default label color for headings"
@@ -282,7 +288,17 @@ proc is_warning_header { line } {
proc Initialize {} {
global DayNames argc argv CommandLine ReminderFile AppendFile Remind PSCmd
global MondayFirst TwentyFourHourMode ReminderFileModTime
global TodayDay TodayMonth TodayYear
global Option ConfigFile
# In case date has rolled over, recalculate Today* values
set now [clock seconds]
set TodayMonth [expr [string trim [clock format $now -format %N]] - 1]
set TodayYear [clock format $now -format %Y]
set TodayDay [string trim [clock format $now -format %e]]
set CommandLine "|$Remind -itkremind=1 -pp -y -l EXTRA"
set PSCmd "$Remind -itkremind=1 -itkprint=1 -pp -l EXTRA"
set i 0
@@ -449,7 +465,7 @@ proc CreateCalFrame { w dayNames } {
}
global MondayFirst
frame $w -background $Option(WinBackground)
frame $w -background $Option(LineColor)
for {set i 0} {$i < 7} {incr i} {
if {$MondayFirst} {
set index [expr ($i+1)%7]
@@ -457,28 +473,31 @@ proc CreateCalFrame { w dayNames } {
set index $i
}
label $w.day$i -border 1 -text [lindex $dayNames $index] -justify center -font HeadingFont -foreground $Option(LabelColor) -background $Option(WinBackground)
grid configure $w.day$i -row 0 -column $i -sticky ew
label $w.day$i -bd 0 -text [lindex $dayNames $index] -justify center -font HeadingFont -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
grid configure $w.day$i -row 0 -column $i -sticky ew -padx 1 -pady 1
}
for {set i 0} {$i < 6} {incr i} {
set n [expr $i*7]
for {set j 0} {$j < 7} {incr j} {
set f [expr $n+$j]
button $w.l$f -text "" -justify center -command "" \
-state disabled -relief flat -border 0 -padx 0 -pady 0 -font HeadingFont
text $w.t$f -width 12 -height $h -border 1 -spacing3 3 -wrap word -relief flat \
-state disabled -takefocus 0 -cursor {} -font CalboxFont -foreground $Option(TextColor) -background $Option(BackgroundColor)
-state disabled -relief flat -bd 0 -padx 0 -pady 0 -font HeadingFont -highlightthickness 1
text $w.t$f -width 12 -height $h -bd 0 -spacing3 3 -wrap word -relief flat \
-state disabled -takefocus 0 -cursor {} -font CalboxFont -foreground $Option(TextColor) -background $Option(BackgroundColor) \
-highlightthickness 0
frame $w.f$f -padx 0 -pady 0 -highlightthickness 0 -relief flat -bd 0
$w.t$f tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$f"
$w.t$f tag bind REM <ButtonPress-3> "FireEditor $w.t$f"
grid configure $w.l$f -row [expr $i*2+1] -column $j -sticky ew
grid configure $w.t$f -row [expr $i*2+2] -column $j -sticky nsew
pack $w.l$f -in $w.f$f -side top -expand 0 -fill x
pack $w.t$f -in $w.f$f -side top -expand 1 -fill both
grid configure $w.f$f -row [expr $i+1] -column $j -sticky nsew -padx 1 -pady 1
}
}
for {set i 0} {$i < 7} {incr i} {
grid columnconfigure $w $i -weight 1
}
for {set i 2} {$i < 14} {incr i 2} {
for {set i 1} {$i < 7} {incr i} {
grid rowconfigure $w $i -weight 1
}
}
@@ -504,8 +523,12 @@ proc ConfigureCalFrame { w firstDay numDays } {
set last [expr $offset+$numDays]
for {set i 0} {$i < $first} {incr i} {
grid $w.l$i $w.t$i
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground)
grid $w.f$i
pack $w.l$i -in $w.f$i -side top -expand 0 -fill x
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
raise $w.l$i
raise $w.t$i
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
$w.l$i configure -state disabled
balloon_add_help $w.l$i ""
$w.t$i configure -relief flat -takefocus 0 -state normal -background $Option(WinBackground)
@@ -515,13 +538,17 @@ proc ConfigureCalFrame { w firstDay numDays } {
}
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled
$w.t$i configure -state disabled -takefocus 0
}
for {set i $first} {$i <= $last} {incr i} {
grid $w.l$i $w.t$i
grid $w.f$i
pack $w.l$i -in $w.f$i -side top -expand 0 -fill x
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
raise $w.l$i
raise $w.t$i
set d [expr $i-$first+1]
$w.l$i configure -text $d -state normal -relief flat \
-command "ModifyDay $d $firstDay" -foreground $Option(LabelColor) -background $Option(WinBackground)
-command "ModifyDay $d $firstDay" -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help $w.l$i "Add a reminder..."
$w.t$i configure -relief sunken -takefocus 1 -state normal -foreground $Option(TextColor) -background $Option(BackgroundColor)
$w.t$i delete 1.0 end
@@ -530,23 +557,27 @@ proc ConfigureCalFrame { w firstDay numDays } {
}
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled
$w.t$i configure -state disabled -takefocus 0
}
set forgetIt 0
for {set i [expr $last+1]} {$i < 42} {incr i} {
if {$i%7 == 0} {
set forgetIt 1
}
set row [expr ($i/7)*2+1]
set row [expr ($i/7)+1]
if {$forgetIt} {
grid remove $w.l$i $w.t$i
grid remove $w.f$i
grid rowconfigure $w $row -weight 0
grid rowconfigure $w [expr $row+1] -weight 0
} else {
grid $w.l$i $w.t$i
grid $w.f$i
pack $w.l$i -in $w.f$i -side top -expand 0 -fill x
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
raise $w.l$i
raise $w.t$i
grid rowconfigure $w [expr $row+1] -weight 1
}
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground)
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
$w.l$i configure -state disabled
balloon_add_help $w.l$i ""
$w.t$i configure -relief flat -takefocus 0 -state normal -background $Option(WinBackground)
@@ -556,11 +587,11 @@ proc ConfigureCalFrame { w firstDay numDays } {
}
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled
$w.t$i configure -state disabled -takefocus 0
}
if { $CurMonth == $TodayMonth && $CurYear == $TodayYear } {
set n [expr $TodayDay + $offset]
$w.l$n configure -background "#00c0c0"
$w.l$n configure -background $Option(TodayColor)
}
}
@@ -577,36 +608,36 @@ proc DoQueue {} {
#---------------------------------------------------------------------------
proc CreateCalWindow { dayNames } {
global Option
frame .h -background $Option(WinBackground);
label .h.title -text "" -justify center -pady 1 -border 1 -relief raised -font HeadingFont -background $Option(WinBackground) -foreground $Option(LabelColor)
pack .h.title -side top -fill x
frame .h -background $Option(LineColor)
label .h.title -text "" -justify center -pady 2 -bd 0 -relief flat -font HeadingFont -background $Option(WinBackground) -foreground $Option(LabelColor)
pack .h.title -side top -fill x -pady 1 -padx 1
pack .h -side top -expand 0 -fill x
. configure -background $Option(LineColor)
CreateCalFrame .cal $dayNames
frame .b -background $Option(WinBackground);
button .b.prev -text "\u2b9c" -command {MoveMonth -1} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
frame .b -background $Option(LineColor)
button .b.prev -text "\u2b9c" -command {MoveMonth -1} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.prev "Go to previous month"
button .b.this -text {Today} -command {ThisMonth} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.this -text {Today} -command {ThisMonth} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.this "Go to this month"
button .b.next -text "\u2b9e" -command {MoveMonth 1} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.next -text "\u2b9e" -command {MoveMonth 1} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.next "Go to next month"
button .b.goto -text {Go To Date...} -command {GotoDialog} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.goto -text {Go To Date...} -command {GotoDialog} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.goto "Go to a specific date"
button .b.print -text {Print...} -command {DoPrint} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
balloon_add_help .b.print "Print a PostScript calendar"
button .b.queue -text {Queue...} -command {DoQueue} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
balloon_add_help .b.queue "See the queue of pending reminders (debugging purposes only)"
button .b.quit -text {Quit} -command {Quit} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
balloon_add_help .b.quit "Quit TkRemind"
button .b.options -text {Options...} -command EditOptions -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
button .b.print -text {Print...} -command {DoPrint} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.print "Print a PostScript or PDF calendar"
button .b.options -text {Options...} -command EditOptions -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.options "Set TkRemind options"
label .b.status -text "" -width 25 -relief sunken -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
label .b.nqueued -text "" -width 20 -relief sunken -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
pack .b.prev .b.this .b.next .b.goto .b.print .b.options .b.queue .b.quit -side left -fill both
pack .b.status -side left -fill both -expand 1
pack .b.nqueued -side left -fill both
pack .b -side bottom -fill x -expand 0
button .b.queue -text {Queue...} -command {DoQueue} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.queue "See the queue of pending reminders (debugging purposes only)"
button .b.quit -text {Quit} -command {Quit} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
balloon_add_help .b.quit "Quit TkRemind"
label .b.status -text "" -width 25 -relief flat -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
label .b.nqueued -text "" -width 20 -relief flat -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
pack .b.prev .b.this .b.next .b.goto .b.print .b.options .b.queue .b.quit -side left -fill both -padx 1
pack .b.status -side left -fill both -expand 1 -padx 1
pack .b.nqueued -side left -fill both -padx 1
pack .b -side bottom -fill x -expand 0 -pady 1
pack .cal -side top -fill both -expand 1
wm title . "TkRemind"
wm iconname . ""
@@ -689,7 +720,7 @@ proc EditOptions {} {
pack $w.cmd -in $w.rf -side left -expand 1 -fill x
$w.cmd insert 0 $tmpOpt(RunCmd)
frame $w.sep3 -border 1 -relief sunken
frame $w.sep3 -bd 1 -relief sunken
# E-mail reminder if popup not dismissed
frame $w.eml
label $w.lab_email_address -text "E-mail reminders here if popup not dismissed:" -anchor w -justify left
@@ -734,6 +765,12 @@ proc EditOptions {} {
label $w.bgcolor -text " Background color:"
button $w.bbgcolor -background $Option(BackgroundColor) -command [list PickColor BackgroundColor $w.bbgcolor] -text ...
label $w.tbgcolor -text "Color for highlighting \"today\":"
button $w.tbbgcolor -background $Option(TodayColor) -command [list PickColor TodayColor $w.tbbgcolor] -text ...
label $w.gridcolor -text " Gridline color:"
button $w.gridbcolor -background $Option(LineColor) -command [list PickColor LineColor $w.gridbcolor] -text ...
grid $w.textcolor $w.btextcolor $w.bgcolor $w.bbgcolor -in $w.colors1
grid $w.bgcolor $w.bbgcolor -in $w.colors1
@@ -742,11 +779,12 @@ proc EditOptions {} {
label $w.wincolor -text " Window color:"
button $w.bwincolor -background $Option(WinBackground) -command [list PickColor WinBackground $w.bwincolor] -text ...
grid $w.headcolor $w.bheadcolor $w.wincolor $w.bwincolor -in $w.colors1
grid $w.tbgcolor $w.tbbgcolor $w.gridcolor $w.gridbcolor -in $w.colors1
grid columnconfigure $w.colors1 0 -weight 1
grid columnconfigure $w.colors1 2 -weight 1
frame $w.sep1 -border 1 -relief sunken
frame $w.sep2 -border 1 -relief sunken
frame $w.sep1 -bd 1 -relief sunken
frame $w.sep2 -bd 1 -relief sunken
checkbutton $w.feed \
-text "Feed popped-up reminder to command's standard input" \
@@ -770,10 +808,12 @@ proc EditOptions {} {
pack $w.colors1 -in $w.f -side top -expand 0 -fill x
pack $w.sep2 -in $w.f -side top -expand 0 -fill x -ipady 1
button $w.default -text "Light Theme" -command [list set_default_colors $w]
button $w.dark -text "Dark Theme" -command [list set_dark_colors $w]
button $w.save -text "Save Options" -command "SaveOptions $w; destroy $w"
button $w.cancel -text "Cancel" -command "CancelOptions; destroy $w"
wm protocol $w WM_DELETE_WINDOW "CancelOptions; destroy $w"
pack $w.save $w.cancel -in $w.b -side left -expand 0 -fill x
pack $w.default $w.dark $w.save $w.cancel -in $w.b -side left -expand 0 -fill x
CenterWindow $w .
}
@@ -845,6 +885,10 @@ proc SaveOptions { w } {
.b.queue configure -foreground $Option(LabelColor) -background $Option(WinBackground)
.b.quit configure -foreground $Option(LabelColor) -background $Option(WinBackground)
.b.options configure -foreground $Option(LabelColor) -background $Option(WinBackground)
. configure -background $Option(LineColor);
.h configure -background $Option(LineColor);
.cal configure -background $Option(LineColor)
.b configure -background $Option(LineColor)
}
proc WriteOptionsToFile {} {
@@ -1032,7 +1076,7 @@ proc FillCalWindow {} {
continue
}
"MOON" {
DoMoonSpecial $n $stuff $fntag
DoMoonSpecial $n $stuff $fntag $day
continue
}
"COLOUR" -
@@ -1057,7 +1101,7 @@ proc FillCalWindow {} {
set extratags "clr$color"
.cal.t$n configure -state normal
.cal.t$n tag configure $extratags -foreground "#$color"
.cal.t$n configure -state disabled
.cal.t$n configure -state disabled -takefocus 0
set stuff $rest
set type "COLOR"
}
@@ -1083,7 +1127,7 @@ proc FillCalWindow {} {
}
}
.cal.t$n insert end "\n"
.cal.t$n configure -state disabled
.cal.t$n configure -state disabled -takefocus 0
}
set problem [catch { close $file } errmsg]
@@ -1152,13 +1196,13 @@ proc DoPrint {} {
toplevel .p
wm title .p "TkRemind Print..."
wm iconname .p "Print..."
frame .p.f1 -relief sunken -border 2
frame .p.f1 -relief sunken -bd 2
frame .p.f11
frame .p.f12
frame .p.f2 -relief sunken -border 2
frame .p.f2a -relief sunken -border 2
frame .p.f3 -relief sunken -border 2
frame .p.f3a -relief sunken -border 2
frame .p.f2 -relief sunken -bd 2
frame .p.f2a -relief sunken -bd 2
frame .p.f3 -relief sunken -bd 2
frame .p.f3a -relief sunken -bd 2
frame .p.f4
radiobutton .p.tofile -text "To file: " -variable Option(PrintDest) -value file
@@ -1169,7 +1213,7 @@ proc DoPrint {} {
.p.command insert end "lpr"
if { $HaveRem2PDF } {
frame .p.ff -relief sunken -border 2
frame .p.ff -relief sunken -bd 2
label .p.format -text "Output Format:"
radiobutton .p.pdf -text "PDF" -variable Option(PrintFormat) -value pdf
radiobutton .p.ps -text "PostScript" -variable Option(PrintFormat) -value ps
@@ -1451,16 +1495,16 @@ proc CreateModifyDialog {w day firstDay args} {
set month [lindex $MonthNames $CurMonth]
set wkday [lindex $EnglishDayNames [expr ($day+$firstDay-1) % 7]]
frame $w.o -border 4 -relief ridge
frame $w.o1 -border 4
frame $w.o2 -border 4
frame $w.o3 -border 4
frame $w.exp -border 4
frame $w.adv -border 4
frame $w.weekend -border 4
frame $w.durationbox -border 4
frame $w.time -border 4
frame $w.hol -border 4
frame $w.o -bd 4 -relief ridge
frame $w.o1 -bd 4
frame $w.o2 -bd 4
frame $w.o3 -bd 4
frame $w.exp -bd 4
frame $w.adv -bd 4
frame $w.weekend -bd 4
frame $w.durationbox -bd 4
frame $w.time -bd 4
frame $w.hol -bd 4
frame $w.msg
frame $w.buttons
pack $w.o1 $w.o2 $w.o3 -side top -anchor w -in $w.o
@@ -3530,7 +3574,7 @@ proc DoShadeSpecial { n r g b } {
# %DESCRIPTION:
# Handles the "MOON" special -- draws a moon symbol
#***********************************************************************
proc DoMoonSpecial { n stuff fntag } {
proc DoMoonSpecial { n stuff fntag day } {
set msg ""
set num [scan $stuff "%d %d %d %s" phase junk1 junk2 msg]
if {$num < 1} {
@@ -3539,11 +3583,27 @@ proc DoMoonSpecial { n stuff fntag } {
if {$phase < 0 || $phase > 3} {
return
}
switch -exact -- $phase {
0 { set win .moon_new }
1 { set win .moon_first }
2 { set win .moon_full }
3 { set win .moon_last }
# We need two sets of moon phase windows. There can be
# two of a given phase in the same month, but Tk does
# not allow the same embedded window in two separate
# text boxes. So we use this hack to make sure
# we use a different window if the same moon phase
# happens twice in a month.
if { $day < 16 } {
switch -exact -- $phase {
0 { set win .moon_new }
1 { set win .moon_first }
2 { set win .moon_full }
3 { set win .moon_last }
}
} else {
switch -exact -- $phase {
0 { set win .moon_new2 }
1 { set win .moon_first2 }
2 { set win .moon_full2 }
3 { set win .moon_last2 }
}
}
.cal.t$n configure -state normal
.cal.t$n window create 1.0 -window $win
@@ -3569,7 +3629,7 @@ proc DoMoonSpecial { n stuff fntag } {
.cal.t$n tag bind $fntag <ButtonPress-1> "FireEditor .cal.t$n $fntag"
}
}
.cal.t$n configure -state disabled
.cal.t$n configure -state disabled -takefocus 0
}
#***********************************************************************
# %PROCEDURE: DisplayTime
@@ -3607,6 +3667,11 @@ proc CreateMoonWindows {} {
catch { destroy .moon_full }
catch { destroy .moon_last }
catch { destroy .moon_new2 }
catch { destroy .moon_first2}
catch { destroy .moon_full2 }
catch { destroy .moon_last2 }
set extra 1
#set wid [font measure CalboxFont 0]
set wid [font metrics CalboxFont -ascent]
@@ -3633,10 +3698,29 @@ proc CreateMoonWindows {} {
.moon_last create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
.moon_last create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 270 -extent 180 -outline {}
canvas .moon_new2 -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_new2 create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
canvas .moon_first2 -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_first2 create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
.moon_first2 create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 90 -extent 180 -outline {}
canvas .moon_full2 -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_full2 create oval $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -width 1
canvas .moon_last2 -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
.moon_last2 create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
.moon_last2 create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 270 -extent 180 -outline {}
balloon_add_help .moon_new "New Moon"
balloon_add_help .moon_first "First Quarter"
balloon_add_help .moon_full "Full Moon"
balloon_add_help .moon_last "Last Quarter"
balloon_add_help .moon_new2 "New Moon"
balloon_add_help .moon_first2 "First Quarter"
balloon_add_help .moon_full2 "Full Moon"
balloon_add_help .moon_last2 "Last Quarter"
}
#***********************************************************************
@@ -3996,4 +4080,38 @@ proc FindConfigFile {} {
set ConfigFile "~/.tkremindrc"
}
proc set_default_colors { w } {
global tmpOpt
set tmpOpt(BackgroundColor) "#d9d9d9"
set tmpOpt(LabelColor) "#000000"
set tmpOpt(LineColor) "#000000"
set tmpOpt(TextColor) "#000000"
set tmpOpt(TodayColor) "#00C0C0"
set tmpOpt(WinBackground) "#d9d9d9"
update_color_buttons $w
}
proc set_dark_colors { w } {
global tmpOpt
set tmpOpt(BackgroundColor) "#000000"
set tmpOpt(LabelColor) "#00ffff"
set tmpOpt(LineColor) "#0080fc"
set tmpOpt(TextColor) "#ffffff"
set tmpOpt(TodayColor) "#b000b6"
set tmpOpt(WinBackground) "#000000"
update_color_buttons $w
}
proc update_color_buttons { w } {
global tmpOpt
$w.bbgcolor configure -background $tmpOpt(BackgroundColor)
$w.bheadcolor configure -background $tmpOpt(LabelColor)
$w.gridbcolor configure -background $tmpOpt(LineColor)
$w.btextcolor configure -background $tmpOpt(TextColor)
$w.tbbgcolor configure -background $tmpOpt(TodayColor)
$w.bwincolor configure -background $tmpOpt(WinBackground)
}
# Rem2PS program to execute -- supply full path if you want
main

View File

@@ -116,7 +116,7 @@
/*---------------------------------------------------------------------*/
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
/*---------------------------------------------------------------------*/
#define VAL_STACK_SIZE 500
#define VAL_STACK_SIZE 1000
/*---------------------------------------------------------------------*/
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */

View File

@@ -116,7 +116,7 @@
/*---------------------------------------------------------------------*/
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
/*---------------------------------------------------------------------*/
#define VAL_STACK_SIZE 500
#define VAL_STACK_SIZE 1000
/*---------------------------------------------------------------------*/
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */

View File

@@ -28,7 +28,7 @@ static int ParseTimeTrig (ParsePtr s, TimeTrig *tim, int save_in_globals);
static int ParseLocalOmit (ParsePtr s, Trigger *t);
static int ParseScanFrom (ParsePtr s, Trigger *t, int type);
static int ParsePriority (ParsePtr s, Trigger *t);
static int ParseUntil (ParsePtr s, Trigger *t);
static int ParseUntil (ParsePtr s, Trigger *t, int type);
static int ShouldTriggerBasedOnWarn (Trigger *t, int jul, int *err);
static int ComputeTrigDuration(TimeTrig *t);
@@ -237,11 +237,15 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
tim->delta = DefaultTDelta;
tim->rep = NO_REP;
tim->duration = NO_TIME;
trig->need_wkday = 0;
trig->adj_for_last = 0;
if (save_in_globals) {
LastTriggerTime = NO_TIME;
}
while(1) {
int parsing = 1;
while(parsing) {
/* Read space-delimited string */
r = ParseToken(s, &buf);
if (r) return r;
@@ -249,6 +253,25 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
/* Figure out what we've got */
FindToken(DBufValue(&buf), &tok);
switch(tok.type) {
case T_In:
/* Completely ignored */
DBufFree(&buf);
break;
case T_Ordinal:
DBufFree(&buf);
if (trig->d != NO_DAY) return E_DAY_TWICE;
if (tok.val < 0) {
if (trig->back != NO_BACK) return E_BACK_TWICE;
trig->back = -7;
trig->d = 1;
trig->adj_for_last = 1;
} else {
trig->d = 1 + 7 * tok.val;
}
trig->need_wkday = 1;
break;
case T_Date:
DBufFree(&buf);
if (trig->d != NO_DAY) return E_DAY_TWICE;
@@ -322,7 +345,6 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
DBufFree(&buf);
trig->typ = tok.val;
if (s->isnested) return E_CANT_NEST_RTYPE;
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
if (trig->typ == PASSTHRU_TYPE) {
r = ParseToken(s, &buf);
if (r) return r;
@@ -332,19 +354,20 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
}
StrnCpy(trig->passthru, DBufValue(&buf), PASSTHRU_LEN);
}
return OK;
parsing = 0;
break;
case T_Through:
DBufFree(&buf);
if (trig->rep != NO_REP) return E_REP_TWICE;
trig->rep = 1;
r = ParseUntil(s, trig);
r = ParseUntil(s, trig, tok.type);
if (r) return r;
break;
case T_Until:
DBufFree(&buf);
r=ParseUntil(s, trig);
r=ParseUntil(s, trig, tok.type);
if (r) return r;
break;
@@ -378,6 +401,15 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
trig->back = tok.val;
break;
case T_BackAdj:
DBufFree(&buf);
if (trig->back != NO_BACK) return E_BACK_TWICE;
if (trig->d != NO_DAY) return E_DAY_TWICE;
trig->back = tok.val;
trig->d = 1;
trig->adj_for_last = 1;
break;
case T_Once:
DBufFree(&buf);
if (trig->once != NO_ONCE) return E_ONCE_TWICE;
@@ -401,8 +433,8 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
case T_Empty:
DBufFree(&buf);
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
return OK;
parsing = 0;
break;
case T_OmitFunc:
if (trig->localomit) {
@@ -474,10 +506,58 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
DBufFree(&buf);
trig->typ = MSG_TYPE;
if (s->isnested) return E_CANT_NEST_RTYPE;
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
return OK;
parsing = 0;
break;
}
}
if (trig->need_wkday && trig->wd == NO_WD) {
Eprint("Weekday name(s) required");
return E_PARSE_ERR;
}
/* Adjust month and possibly year */
if (trig->adj_for_last) {
if (trig->m != NO_MON) {
trig->m++;
if (trig->m >= 12) {
trig->m = 0;
if (trig->y != NO_YR) {
trig->y++;
}
}
}
trig->adj_for_last = 0;
}
/* Check for some warning conditions */
if (!s->nonconst_expr) {
if (trig->y != NO_YR && trig->m != NO_MON && trig->d != NO_DAY && trig->until != NO_UNTIL) {
if (Julian(trig->y, trig->m, trig->d) > trig->until) {
Eprint("Warning: UNTIL/THROUGH date earlier than start date");
}
}
if (trig->from != NO_DATE) {
if (trig->until != NO_UNTIL && trig->until < trig->from) {
Eprint("Warning: UNTIL/THROUGH date earlier than FROM date");
}
} else if (trig->scanfrom != NO_DATE) {
if (trig->until != NO_UNTIL && trig->until < trig->scanfrom) {
Eprint("Warning: UNTIL/THROUGH date earlier than SCANFROM date");
}
}
}
if (trig->y != NO_YR && trig->m != NO_MON && trig->d != NO_DAY && trig->until != NO_UNTIL && trig->rep == NO_REP) {
Eprint("Warning: Useless use of UNTIL with fully-specified date and no *rep");
}
/* Set scanfrom to default if not set explicitly */
if (trig->scanfrom == NO_DATE) {
trig->scanfrom = JulianToday;
}
return OK;
}
/***************************************************************/
@@ -568,12 +648,18 @@ static int ParseLocalOmit(ParsePtr s, Trigger *t)
/* ParseUntil - parse the UNTIL portion of a reminder */
/* */
/***************************************************************/
static int ParseUntil(ParsePtr s, Trigger *t)
static int ParseUntil(ParsePtr s, Trigger *t, int type)
{
int y = NO_YR,
m = NO_MON,
d = NO_DAY;
char const *which;
if (type == T_Until) {
which = "UNTIL";
} else {
which = "THROUGH";
}
Token tok;
int r;
DynamicBuffer buf;
@@ -589,7 +675,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Year:
DBufFree(&buf);
if (y != NO_YR) {
Eprint("UNTIL: %s", ErrMsg[E_YR_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
return E_YR_TWICE;
}
y = tok.val;
@@ -598,7 +684,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Month:
DBufFree(&buf);
if (m != NO_MON) {
Eprint("UNTIL: %s", ErrMsg[E_MON_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
return E_MON_TWICE;
}
m = tok.val;
@@ -607,7 +693,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Day:
DBufFree(&buf);
if (d != NO_DAY) {
Eprint("UNTIL: %s", ErrMsg[E_DAY_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
return E_DAY_TWICE;
}
d = tok.val;
@@ -616,15 +702,15 @@ static int ParseUntil(ParsePtr s, Trigger *t)
case T_Date:
DBufFree(&buf);
if (y != NO_YR) {
Eprint("UNTIL: %s", ErrMsg[E_YR_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
return E_YR_TWICE;
}
if (m != NO_MON) {
Eprint("UNTIL: %s", ErrMsg[E_MON_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
return E_MON_TWICE;
}
if (d != NO_DAY) {
Eprint("UNTIL: %s", ErrMsg[E_DAY_TWICE]);
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
return E_DAY_TWICE;
}
FromJulian(tok.val, &y, &m, &d);
@@ -632,7 +718,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
default:
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
Eprint("UNTIL: %s", ErrMsg[E_INCOMPLETE]);
Eprint("%s: %s", which, ErrMsg[E_INCOMPLETE]);
DBufFree(&buf);
return E_INCOMPLETE;
}

View File

@@ -44,21 +44,32 @@ static int MakeValue (char const *s, Value *v, Var *locals, ParsePtr p);
/* Binary operators - all left-associative */
/* Operator precedence:
* Highest: Unary - Unary !
* / %
* + -
* < <= > >=
* == !=
* &&
* Lowest: ||
*
*/
/* Make SURE they are sorted lexically... this may die on an EBCDIC
system... */
Operator BinOp[] = {
{ "!=", 15, BIN_OP, NotEqual },
{ "%", 20, BIN_OP, Mod },
{ "%", 20, BIN_OP, Mod },
{ "&&", 14, BIN_OP, LogAND },
{ "*", 20, BIN_OP, Multiply },
{ "+", 18, BIN_OP, Add },
{ "-", 18, BIN_OP, Subtract },
{ "/", 20, BIN_OP, Divide },
{ "<", 16, BIN_OP, LessThan },
{ "*", 20, BIN_OP, Multiply },
{ "+", 18, BIN_OP, Add },
{ "-", 18, BIN_OP, Subtract },
{ "/", 20, BIN_OP, Divide },
{ "<", 16, BIN_OP, LessThan },
{ "<=", 16, BIN_OP, LessOrEqual },
{ "==", 15, BIN_OP, EqualTo },
{ ">", 16, BIN_OP, GreaterThan },
{ ">", 16, BIN_OP, GreaterThan },
{ ">=", 16, BIN_OP, GreaterOrEqual },
{ "||", 12, BIN_OP, LogOR },
};
@@ -66,8 +77,8 @@ Operator BinOp[] = {
/* These ones must be sorted too. */
Operator UnOp[] = {
{ "!", 22, UN_OP, LogNot },
{ "-", 22, UN_OP, UnMinus },
{ "!", 22, UN_OP, LogNot },
{ "-", 22, UN_OP, UnMinus },
};
#define NUM_UN_OPS (sizeof(UnOp) / sizeof(Operator))
@@ -75,7 +86,8 @@ extern BuiltinFunc Func[];
Operator OpStack[OP_STACK_SIZE];
Value ValStack[VAL_STACK_SIZE];
int OpStackPtr, ValStackPtr;
int OpStackPtr = 0;
int ValStackPtr = 0;
/***************************************************************/
/* */
@@ -115,12 +127,13 @@ static int DebugPerform(Operator *op)
/* Clean the stack after an error occurs. */
/* */
/***************************************************************/
static void CleanStack(void)
static void CleanStack(int old_op_stack_ptr, int old_val_stack_ptr)
{
int i;
for (i=0; i<ValStackPtr; i++) DestroyValue(ValStack[i]);
ValStackPtr = 0;
for (i=old_val_stack_ptr; i<ValStackPtr; i++) DestroyValue(ValStack[i]);
ValStackPtr = old_val_stack_ptr;
OpStackPtr = old_op_stack_ptr;
}
/***************************************************************/
@@ -306,8 +319,8 @@ int EvalExpr(char const **e, Value *v, ParsePtr p)
{
int r;
OpStackPtr = 0;
ValStackPtr = 0;
int old_op_stack_ptr = OpStackPtr;
int old_val_stack_ptr = ValStackPtr;
r = Evaluate(e, NULL, p);
@@ -316,11 +329,15 @@ int EvalExpr(char const **e, Value *v, ParsePtr p)
DBufFree(&ExprBuf);
if (r) {
CleanStack();
CleanStack(old_op_stack_ptr, old_val_stack_ptr);
/* fprintf(stderr, "O=%d V=%d\n", OpStackPtr, ValStackPtr); */
return r;
}
*v = *ValStack;
ValStack[0].type = ERR_TYPE;
OpStackPtr = old_op_stack_ptr;
ValStackPtr = old_val_stack_ptr;
*v = ValStack[old_val_stack_ptr];
ValStack[old_val_stack_ptr].type = ERR_TYPE;
/* fprintf(stderr, "O=%d V=%d\n", OpStackPtr, ValStackPtr); */
return r;
}
@@ -1108,13 +1125,16 @@ static int LogOR(void)
return r;
}
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
v1.v.val = (v1.v.val || v2.v.val) ? 1 : 0;
PushValStack(v1);
return OK;
if (v1.type != v2.type || v1.type == STR_TYPE || v2.type == STR_TYPE) {
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
}
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
if (v1.v.val == 0) {
v1.v.val = v2.v.val;
}
PushValStack(v1);
return OK;
}
/***************************************************************/
@@ -1135,13 +1155,15 @@ static int LogAND(void)
return r;
}
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
v1.v.val = (v1.v.val && v2.v.val) ? 1 : 0;
PushValStack(v1);
return OK;
if (v1.type != v2.type || v1.type == STR_TYPE || v2.type == STR_TYPE) {
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
}
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
if (v1.v.val != 0) {
v1.v.val = v2.v.val;
}
PushValStack(v1);
return OK;
}
/***************************************************************/

View File

@@ -58,6 +58,7 @@ static int FADusk (func_info *);
static int FAbs (func_info *);
static int FAccess (func_info *);
static int FAmpm (func_info *);
static int FTrig (func_info *);
static int FIsAny (func_info *);
static int FArgs (func_info *);
static int FAsc (func_info *);
@@ -126,6 +127,7 @@ static int FSunset (func_info *);
static int FTime (func_info *);
static int FTimepart (func_info *);
static int FToday (func_info *);
static int FTrig (func_info *);
static int FTrigback (func_info *);
static int FTrigdate (func_info *);
static int FTrigdatetime (func_info *);
@@ -279,6 +281,7 @@ BuiltinFunc Func[] = {
{ "time", 2, 2, 1, FTime },
{ "timepart", 1, 1, 1, FTimepart },
{ "today", 0, 0, 0, FToday },
{ "trig", 0, NO_MAX, 0, FTrig },
{ "trigback", 0, 0, 0, FTrigback },
{ "trigdate", 0, 0, 0, FTrigdate },
{ "trigdatetime", 0, 0, 0, FTrigdatetime },
@@ -2971,8 +2974,12 @@ FEvalTrig(func_info *info)
CreateParser(ARGSTR(0), &p);
p.allownested = 0;
r = ParseRem(&p, &trig, &tim, 0);
if (r) return r;
if (r) {
DestroyParser(&p);
return r;
}
if (trig.typ != NO_TYPE) {
DestroyParser(&p);
FreeTrig(&trig);
return E_PARSE_ERR;
}
@@ -2990,6 +2997,7 @@ FEvalTrig(func_info *info)
jul = -1;
}
FreeTrig(&trig);
DestroyParser(&p);
if (r) return r;
if (jul < 0) {
RetVal.type = INT_TYPE;
@@ -3003,3 +3011,59 @@ FEvalTrig(func_info *info)
}
return OK;
}
static int LastTrig = 0;
static int
FTrig(func_info *info)
{
Parser p;
Trigger trig;
TimeTrig tim;
int jul;
int r;
int i;
RetVal.type = DATE_TYPE;
if (Nargs == 0) {
RETVAL = LastTrig;
return OK;
}
for (i=0; i<Nargs; i++) {
ASSERT_TYPE(i, STR_TYPE);
}
RETVAL = 0;
for (i=0; i<Nargs; i++) {
CreateParser(ARGSTR(i), &p);
p.allownested = 0;
r = ParseRem(&p, &trig, &tim, 0);
if (r) {
DestroyParser(&p);
return r;
}
if (trig.typ != NO_TYPE) {
DestroyParser(&p);
FreeTrig(&trig);
return E_PARSE_ERR;
}
jul = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
if (r == E_CANT_TRIG) {
DestroyParser(&p);
FreeTrig(&trig);
continue;
}
if (ShouldTriggerReminder(&trig, &tim, jul, &r)) {
LastTrig = jul;
RETVAL = jul;
DestroyParser(&p);
FreeTrig(&trig);
return OK;
}
DestroyParser(&p);
FreeTrig(&trig);
}
return OK;
}

View File

@@ -88,7 +88,7 @@ EXTERN INIT( int DefaultColorB, -1);
EXTERN INIT( int DefaultColorG, -1);
EXTERN INIT( int SynthesizeTags, 0);
EXTERN INIT( int ScFormat, SC_AMPM);
EXTERN INIT( int MaxSatIter, 150);
EXTERN INIT( int MaxSatIter, 1000);
EXTERN INIT( int MaxStringLen, MAX_STR_LEN);
EXTERN INIT( char *FileName, NULL);
EXTERN INIT( int UseStdin, 0);

View File

@@ -698,7 +698,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline f=tracefiles\n");
fprintf(ErrFp, " -e Divert messages normally sent to stderr to stdout\n");
fprintf(ErrFp, " -b[n] Time format for cal: 0=am/pm, 1=24hr, 2=none\n");
fprintf(ErrFp, " -x[n] Iteration limit for SATISFY clause (def=150)\n");
fprintf(ErrFp, " -x[n] Iteration limit for SATISFY clause (def=1000)\n");
fprintf(ErrFp, " -kcmd Run `cmd' for MSG-type reminders\n");
fprintf(ErrFp, " -g[dddd] Sort reminders by date, time, priority, and 'timedness'\n");
fprintf(ErrFp, " -ivar=val Initialize var to val and preserve var\n");

View File

@@ -283,7 +283,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Virheenetsintä: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Ohjaa virhetulostus stdout-vuohon\n");
fprintf(ErrFp, " -b[n] Ajan ilmaisu: 0=ap/ip, 1=24 tuntia, 2=ei aikoja\n");
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 150)\n");
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 1000)\n");
fprintf(ErrFp, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
fprintf(ErrFp, " -g[ddd] Lajittele viestit päiväyksen, ajan ja tärkeyden mukaan\n");
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja säilytä var\n");

View File

@@ -258,7 +258,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Envoyer les messages de stderr à stdout\n");
fprintf(ErrFp, " -b[n] Formats de l'heure pour le calendrier: 0=am/pm, 1=24hr, 2=aucun\n");
fprintf(ErrFp, " -x[n] Limite d'itérations pour la clause SATISFY (def=150)\n");
fprintf(ErrFp, " -x[n] Limite d'itérations pour la clause SATISFY (def=1000)\n");
fprintf(ErrFp, " -kcmd Exécuter 'cmd' pour les rappels de type MSG\n");
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorité avant d'émettre\n");
fprintf(ErrFp, " -ivar=val Initialiser var à val et conserver var\n");

View File

@@ -270,7 +270,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Odpluskwianie: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Komunikaty o błędach skieruj na stdout\n");
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=żaden\n");
fprintf(ErrFp, " -x[n] Limit powtórzeń klauzuli SATISFY (domyślnie=150)\n");
fprintf(ErrFp, " -x[n] Limit powtórzeń klauzuli SATISFY (domyślnie=1000)\n");
fprintf(ErrFp, " -kcmd Wywołaj 'cmd' dla przypomnień typu MSG\n");
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia według daty, czasu i priorytetu\n");
fprintf(ErrFp, " -ivar=val Zainicjuj zmienną var wartościa val i zachowaj ja\n");

View File

@@ -283,7 +283,7 @@ void Usage(void)
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trigger v=dumpvars l=showline\n");
fprintf(ErrFp, " -e Desvia mensagens normalmente enviadas a stderr para stdout\n");
fprintf(ErrFp, " -b[n] Formato da hora para o cal: 0=am/pm, 1=24hr, 2=nenhum\n");
fprintf(ErrFp, " -x[n] Limite de iteracoes para a clausula SATISFY (default=150)\n");
fprintf(ErrFp, " -x[n] Limite de iteracoes para a clausula SATISFY (default=1000)\n");
fprintf(ErrFp, " -kcmd Executa `cmd' para os compromissos com MSG\n");
fprintf(ErrFp, " -g[ddd] Classifica compromissos por data, hora e prioridade antes de exibir\n");
fprintf(ErrFp, " -ivar=val Inicializa (e preserva) variavel var com val\n");

View File

@@ -43,30 +43,36 @@ Token TokArray[] = {
{ "at", 2, T_At, 0 },
{ "august", 3, T_Month, 7 },
{ "banner", 3, T_Banner, 0 },
{ "before", 3, T_Skip, BEFORE_SKIP },
{ "before", 3, T_Skip, BEFORE_SKIP },
{ "cal", 3, T_RemType, CAL_TYPE },
{ "clear-omit-context", 5, T_Clr, 0 },
{ "debug", 5, T_Debug, 0 },
{ "debug", 5, T_Debug, 0 },
{ "december", 3, T_Month, 11 },
{ "do", 2, T_IncludeR, 0 },
{ "dumpvars", 4, T_Dumpvars, 0 },
{ "dumpvars", 4, T_Dumpvars, 0 },
{ "duration", 3, T_Duration, 0 },
{ "else", 4, T_Else, 0 },
{ "else", 4, T_Else, 0 },
{ "endif", 5, T_EndIf, 0 },
{ "errmsg", 6, T_ErrMsg, 0 },
{ "errmsg", 6, T_ErrMsg, 0 },
{ "exit", 4, T_Exit, 0 },
{ "february", 3, T_Month, 1 },
{ "first", 5, T_Ordinal, 0 },
{ "flush", 5, T_Flush, 0 },
{ "fourth", 6, T_Ordinal, 3 },
{ "friday", 3, T_WkDay, 4 },
{ "from", 4, T_Scanfrom, FROM_TYPE },
{ "fset", 4, T_Fset, 0 },
{ "if", 2, T_If, 0 },
{ "iftrig", 6, T_IfTrig, 0 },
{ "in", 2, T_In, 0 },
{ "include", 3, T_Include, 0 },
{ "includecmd", 10, T_IncludeCmd, 0 },
{ "january", 3, T_Month, 0 },
{ "july", 3, T_Month, 6 },
{ "june", 3, T_Month, 5 },
{ "last", 4, T_Ordinal, -1 },
{ "lastday", 7, T_BackAdj, -1 },
{ "lastworkday", 11, T_BackAdj, 1 },
{ "march", 3, T_Month, 2 },
{ "may", 3, T_Month, 4 },
{ "maybe-uncomputable", 5, T_MaybeUncomputable, 0},
@@ -90,12 +96,14 @@ Token TokArray[] = {
{ "saturday", 3, T_WkDay, 5 },
{ "scanfrom", 4, T_Scanfrom, SCANFROM_TYPE },
{ "sched", 5, T_Sched, 0 },
{ "second", 6, T_Ordinal, 1 },
{ "september", 3, T_Month, 8 },
{ "set", 3, T_Set, 0 },
{ "skip", 3, T_Skip, SKIP_SKIP },
{ "special", 7, T_RemType, PASSTHRU_TYPE },
{ "sunday", 3, T_WkDay, 6 },
{ "tag", 3, T_Tag, 0 },
{ "third", 5, T_Ordinal, 2 },
{ "through", 7, T_Through, 0 },
{ "thursday", 3, T_WkDay, 3 },
{ "tuesday", 3, T_WkDay, 1 },
@@ -325,6 +333,14 @@ void FindNumericToken(char const *s, Token *t)
t->type = T_Back;
t->val *= mult;
return;
} else if (*s == '~') {
s++;
if (*s == '~') { mult = -1; s++; }
PARSENUM(t->val, s);
if (*s) return; /* Illegal token if followed by non-numeric char */
t->type = T_BackAdj;
t->val *= mult;
return;
}
return; /* Unknown token type */
}

View File

@@ -69,6 +69,8 @@ typedef struct {
int once;
int scanfrom;
int from;
int adj_for_last; /* Adjust month/year for use of LAST */
int need_wkday; /* Set if we *need* a weekday */
int priority;
int duration_days; /* Duration converted to days to search */
int eventstart; /* Original event start (datetime) */
@@ -157,7 +159,8 @@ enum TokTypes
T_AddOmit,
T_WkDay,
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_BackAdj,
T_Once,
T_Empty,
T_Comment,
@@ -175,7 +178,10 @@ enum TokTypes
T_LongTime,
T_OmitFunc,
T_Through,
T_MaybeUncomputable
T_MaybeUncomputable,
T_Ordinal,
T_In,
T_LastBack
};
/* The structure of a token */

View File

@@ -1020,7 +1020,7 @@ set a057 value("a05"+"6")
"a05" + "6" => "a056"
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
set a058 version()
version() => "03.04.00"
version() => "03.04.02"
set a059 wkday(today())
today() => 1991-02-16
wkday(1991-02-16) => "Saturday"
@@ -2589,7 +2589,7 @@ a086 4
a109 2012-01-01
a128 2018-02-03@16:45
a039 "February"
a058 "03.04.00"
a058 "03.04.02"
a077 "1992 92
"
a096 -4
@@ -3067,16 +3067,50 @@ msg [$Wednesday]%
$Wednesday => "Wednesday"
Wednesday
# Diagnose until before start date, only for non-constant expressions and
# fully-specified start date
REM Mon 1992 UNTIL 1991-01-01 MSG Not diagnosed - not fully-specified start
../tests/test.rem(529): Expired
REM 1992-01-01 *1 UNTIL 1991-12-31 MSG Diagnosed
../tests/test.rem(530): Warning: UNTIL/THROUGH date earlier than start date
../tests/test.rem(530): Trig = Wednesday, 1 January, 1992
set x '1992-01-01'
REM [x] *1 UNTIL 1991-12-31 MSG Not diagnosed - nonconst expression
x => 1992-01-01
../tests/test.rem(532): Trig = Wednesday, 1 January, 1992
REM MON FROM 1992-01-01 UNTIL 1991-12-31 Diagnosed
../tests/test.rem(534): Warning: UNTIL/THROUGH date earlier than FROM date
../tests/test.rem(534): Expired
REM MON SCANFROM 1992-01-01 UNTIL 1991-12-31 Diagnosed
../tests/test.rem(535): Warning: UNTIL/THROUGH date earlier than SCANFROM date
../tests/test.rem(535): Expired
REM MON FROM [x] UNTIL 1991-12-31 Not diagnosed
x => 1992-01-01
../tests/test.rem(537): Expired
REM MON SCANFROM [x] UNTIL 1991-12-31 Not diagnosed
x => 1992-01-01
../tests/test.rem(538): Expired
REM 1992-01-01 UNTIL 1992-02-02 MSG Diagnosed
../tests/test.rem(540): Warning: Useless use of UNTIL with fully-specified date and no *rep
../tests/test.rem(540): Trig = Wednesday, 1 January, 1992
REM [x] UNTIL 1992-02-02 MSG Diagnosed
x => 1992-01-01
../tests/test.rem(541): Warning: Useless use of UNTIL with fully-specified date and no *rep
../tests/test.rem(541): Trig = Wednesday, 1 January, 1992
dump $aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Variable Value
$aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: Name too long
OMIT 2010-09-03 THROUGH 2010-09-15
OMIT December 25 MSG X
../tests/test.rem(529): Trig = Wednesday, 25 December, 1991
../tests/test.rem(545): Trig = Wednesday, 25 December, 1991
# Next should give a parse error
OMIT 26 Dec 2010 THROUGH 27 Dec 2010 MSG This is not legal
../tests/test.rem(531): Trig = Sunday, 26 December, 2010
../tests/test.rem(547): Trig = Sunday, 26 December, 2010
OMIT DUMP
Global Full OMITs (16 of maximum allowed 1000):
1991-03-11
@@ -3108,287 +3142,287 @@ a => 5761
hebdate(14, "Adar", 1991-02-16, 5761) => 1991-02-28
trigger(1991-02-28) => "28 February 1991"
Leaving UserFN _i() => "28 February 1991"
../tests/test.rem(534): Trig = Thursday, 28 February, 1991
../tests/test.rem(550): Trig = Thursday, 28 February, 1991
# Regression test for bug found by Larry Hynes
REM SATISFY [day(trigdate()-25) == 14] MSG Foo
../tests/test.rem(537): Trig = Saturday, 16 February, 1991
../tests/test.rem(553): Trig = Saturday, 16 February, 1991
trigdate() => 1991-02-16
1991-02-16 - 25 => 1991-01-22
day(1991-01-22) => 22
22 == 14 => 0
../tests/test.rem(537): Trig = Sunday, 17 February, 1991
../tests/test.rem(553): Trig = Sunday, 17 February, 1991
trigdate() => 1991-02-17
1991-02-17 - 25 => 1991-01-23
day(1991-01-23) => 23
23 == 14 => 0
../tests/test.rem(537): Trig = Monday, 18 February, 1991
../tests/test.rem(553): Trig = Monday, 18 February, 1991
trigdate() => 1991-02-18
1991-02-18 - 25 => 1991-01-24
day(1991-01-24) => 24
24 == 14 => 0
../tests/test.rem(537): Trig = Tuesday, 19 February, 1991
../tests/test.rem(553): Trig = Tuesday, 19 February, 1991
trigdate() => 1991-02-19
1991-02-19 - 25 => 1991-01-25
day(1991-01-25) => 25
25 == 14 => 0
../tests/test.rem(537): Trig = Wednesday, 20 February, 1991
../tests/test.rem(553): Trig = Wednesday, 20 February, 1991
trigdate() => 1991-02-20
1991-02-20 - 25 => 1991-01-26
day(1991-01-26) => 26
26 == 14 => 0
../tests/test.rem(537): Trig = Thursday, 21 February, 1991
../tests/test.rem(553): Trig = Thursday, 21 February, 1991
trigdate() => 1991-02-21
1991-02-21 - 25 => 1991-01-27
day(1991-01-27) => 27
27 == 14 => 0
../tests/test.rem(537): Trig = Friday, 22 February, 1991
../tests/test.rem(553): Trig = Friday, 22 February, 1991
trigdate() => 1991-02-22
1991-02-22 - 25 => 1991-01-28
day(1991-01-28) => 28
28 == 14 => 0
../tests/test.rem(537): Trig = Saturday, 23 February, 1991
../tests/test.rem(553): Trig = Saturday, 23 February, 1991
trigdate() => 1991-02-23
1991-02-23 - 25 => 1991-01-29
day(1991-01-29) => 29
29 == 14 => 0
../tests/test.rem(537): Trig = Sunday, 24 February, 1991
../tests/test.rem(553): Trig = Sunday, 24 February, 1991
trigdate() => 1991-02-24
1991-02-24 - 25 => 1991-01-30
day(1991-01-30) => 30
30 == 14 => 0
../tests/test.rem(537): Trig = Monday, 25 February, 1991
../tests/test.rem(553): Trig = Monday, 25 February, 1991
trigdate() => 1991-02-25
1991-02-25 - 25 => 1991-01-31
day(1991-01-31) => 31
31 == 14 => 0
../tests/test.rem(537): Trig = Tuesday, 26 February, 1991
../tests/test.rem(553): Trig = Tuesday, 26 February, 1991
trigdate() => 1991-02-26
1991-02-26 - 25 => 1991-02-01
day(1991-02-01) => 1
1 == 14 => 0
../tests/test.rem(537): Trig = Wednesday, 27 February, 1991
../tests/test.rem(553): Trig = Wednesday, 27 February, 1991
trigdate() => 1991-02-27
1991-02-27 - 25 => 1991-02-02
day(1991-02-02) => 2
2 == 14 => 0
../tests/test.rem(537): Trig = Thursday, 28 February, 1991
../tests/test.rem(553): Trig = Thursday, 28 February, 1991
trigdate() => 1991-02-28
1991-02-28 - 25 => 1991-02-03
day(1991-02-03) => 3
3 == 14 => 0
../tests/test.rem(537): Trig = Friday, 1 March, 1991
../tests/test.rem(553): Trig = Friday, 1 March, 1991
trigdate() => 1991-03-01
1991-03-01 - 25 => 1991-02-04
day(1991-02-04) => 4
4 == 14 => 0
../tests/test.rem(537): Trig = Saturday, 2 March, 1991
../tests/test.rem(553): Trig = Saturday, 2 March, 1991
trigdate() => 1991-03-02
1991-03-02 - 25 => 1991-02-05
day(1991-02-05) => 5
5 == 14 => 0
../tests/test.rem(537): Trig = Sunday, 3 March, 1991
../tests/test.rem(553): Trig = Sunday, 3 March, 1991
trigdate() => 1991-03-03
1991-03-03 - 25 => 1991-02-06
day(1991-02-06) => 6
6 == 14 => 0
../tests/test.rem(537): Trig = Monday, 4 March, 1991
../tests/test.rem(553): Trig = Monday, 4 March, 1991
trigdate() => 1991-03-04
1991-03-04 - 25 => 1991-02-07
day(1991-02-07) => 7
7 == 14 => 0
../tests/test.rem(537): Trig = Tuesday, 5 March, 1991
../tests/test.rem(553): Trig = Tuesday, 5 March, 1991
trigdate() => 1991-03-05
1991-03-05 - 25 => 1991-02-08
day(1991-02-08) => 8
8 == 14 => 0
../tests/test.rem(537): Trig = Wednesday, 6 March, 1991
../tests/test.rem(553): Trig = Wednesday, 6 March, 1991
trigdate() => 1991-03-06
1991-03-06 - 25 => 1991-02-09
day(1991-02-09) => 9
9 == 14 => 0
../tests/test.rem(537): Trig = Thursday, 7 March, 1991
../tests/test.rem(553): Trig = Thursday, 7 March, 1991
trigdate() => 1991-03-07
1991-03-07 - 25 => 1991-02-10
day(1991-02-10) => 10
10 == 14 => 0
../tests/test.rem(537): Trig = Friday, 8 March, 1991
../tests/test.rem(553): Trig = Friday, 8 March, 1991
trigdate() => 1991-03-08
1991-03-08 - 25 => 1991-02-11
day(1991-02-11) => 11
11 == 14 => 0
../tests/test.rem(537): Trig = Saturday, 9 March, 1991
../tests/test.rem(553): Trig = Saturday, 9 March, 1991
trigdate() => 1991-03-09
1991-03-09 - 25 => 1991-02-12
day(1991-02-12) => 12
12 == 14 => 0
../tests/test.rem(537): Trig = Sunday, 10 March, 1991
../tests/test.rem(553): Trig = Sunday, 10 March, 1991
trigdate() => 1991-03-10
1991-03-10 - 25 => 1991-02-13
day(1991-02-13) => 13
13 == 14 => 0
../tests/test.rem(537): Trig = Monday, 11 March, 1991
../tests/test.rem(553): Trig = Monday, 11 March, 1991
trigdate() => 1991-03-11
1991-03-11 - 25 => 1991-02-14
day(1991-02-14) => 14
14 == 14 => 1
../tests/test.rem(537): Trig(satisfied) = Monday, 11 March, 1991
../tests/test.rem(553): Trig(satisfied) = Monday, 11 March, 1991
# Check combo of SATISFY and long-duration events
REM 14 SATISFY [$Tw == 4] MSG Thursday, the 14th
../tests/test.rem(540): Trig = Thursday, 14 March, 1991
../tests/test.rem(556): Trig = Thursday, 14 March, 1991
$Tw => 4
4 == 4 => 1
../tests/test.rem(540): Trig(satisfied) = Thursday, 14 March, 1991
../tests/test.rem(556): Trig(satisfied) = Thursday, 14 March, 1991
REM 14 AT 16:00 DURATION 8:00 SATISFY [$Tw == 4] MSG Thursday, the 14th
../tests/test.rem(541): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 08:00
../tests/test.rem(557): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 08:00
$Tw => 4
4 == 4 => 1
../tests/test.rem(541): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 08:00
../tests/test.rem(557): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 08:00
REM 14 AT 16:00 DURATION 8:01 SATISFY [$Tw == 4] MSG Thursday, the 14th
../tests/test.rem(542): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 08:01
../tests/test.rem(542): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 08:01
../tests/test.rem(558): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 08:01
../tests/test.rem(558): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 08:01
$Tw => 4
4 == 4 => 1
../tests/test.rem(542): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 08:01
../tests/test.rem(558): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 08:01
REM 14 AT 16:00 DURATION 32:00 SATISFY [$Tw == 4] MSG Thursday, the 14th
../tests/test.rem(543): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 32:00
../tests/test.rem(543): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 32:00
../tests/test.rem(559): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 32:00
../tests/test.rem(559): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 32:00
$Tw => 4
4 == 4 => 1
../tests/test.rem(543): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 32:00
../tests/test.rem(559): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 32:00
REM 14 AT 16:00 DURATION 32:01 SATISFY [$Tw == 4] MSG Thursday, the 14th
../tests/test.rem(544): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 32:01
../tests/test.rem(544): Trig = Thursday, 14 February, 1991 AT 16:00 DURATION 32:01
../tests/test.rem(560): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 32:01
../tests/test.rem(560): Trig = Thursday, 14 February, 1991 AT 16:00 DURATION 32:01
$Tw => 4
4 == 4 => 1
../tests/test.rem(544): Trig(adj) = Saturday, 16 February, 1991 AT 00:00 DURATION 00:01
../tests/test.rem(544): Trig(satisfied) = Saturday, 16 February, 1991 AT 00:00 DURATION 00:01
../tests/test.rem(560): Trig(adj) = Saturday, 16 February, 1991 AT 00:00 DURATION 00:01
../tests/test.rem(560): Trig(satisfied) = Saturday, 16 February, 1991 AT 00:00 DURATION 00:01
Thursday, the 14th
REM 14 AT 16:00 DURATION 40:00 SATISFY [$Tw == 4] MSG Thursday, the 14th
../tests/test.rem(545): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 40:00
../tests/test.rem(545): Trig = Thursday, 14 February, 1991 AT 16:00 DURATION 40:00
../tests/test.rem(561): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 40:00
../tests/test.rem(561): Trig = Thursday, 14 February, 1991 AT 16:00 DURATION 40:00
$Tw => 4
4 == 4 => 1
../tests/test.rem(545): Trig(adj) = Saturday, 16 February, 1991 AT 00:00 DURATION 08:00
../tests/test.rem(545): Trig(satisfied) = Saturday, 16 February, 1991 AT 00:00 DURATION 08:00
../tests/test.rem(561): Trig(adj) = Saturday, 16 February, 1991 AT 00:00 DURATION 08:00
../tests/test.rem(561): Trig(satisfied) = Saturday, 16 February, 1991 AT 00:00 DURATION 08:00
Thursday, the 14th
# This is now an error
REM DURATION 15:00 MSG Should fail... need AT if you have DURATION.
../tests/test.rem(548): Cannot specify DURATION without specifying AT
../tests/test.rem(564): Cannot specify DURATION without specifying AT
# Parsing of AM/PM times
REM AT 0:00am MSG foo 0a
../tests/test.rem(551): Expecting time after AT
../tests/test.rem(567): Expecting time after AT
REM AT 1:00AM MSG foo 1a
../tests/test.rem(552): Trig = Saturday, 16 February, 1991 AT 01:00
../tests/test.rem(568): Trig = Saturday, 16 February, 1991 AT 01:00
foo 1a
REM AT 2:00am MSG foo 2a
../tests/test.rem(553): Trig = Saturday, 16 February, 1991 AT 02:00
../tests/test.rem(569): Trig = Saturday, 16 February, 1991 AT 02:00
foo 2a
REM AT 3:00AM MSG foo 3a
../tests/test.rem(554): Trig = Saturday, 16 February, 1991 AT 03:00
../tests/test.rem(570): Trig = Saturday, 16 February, 1991 AT 03:00
foo 3a
REM AT 4:00am MSG foo 4a
../tests/test.rem(555): Trig = Saturday, 16 February, 1991 AT 04:00
../tests/test.rem(571): Trig = Saturday, 16 February, 1991 AT 04:00
foo 4a
REM AT 5:00AM MSG foo 5a
../tests/test.rem(556): Trig = Saturday, 16 February, 1991 AT 05:00
../tests/test.rem(572): Trig = Saturday, 16 February, 1991 AT 05:00
foo 5a
REM AT 6:00am MSG foo 6a
../tests/test.rem(557): Trig = Saturday, 16 February, 1991 AT 06:00
../tests/test.rem(573): Trig = Saturday, 16 February, 1991 AT 06:00
foo 6a
REM AT 7:00AM MSG foo 7a
../tests/test.rem(558): Trig = Saturday, 16 February, 1991 AT 07:00
../tests/test.rem(574): Trig = Saturday, 16 February, 1991 AT 07:00
foo 7a
REM AT 8:00am MSG foo 8a
../tests/test.rem(559): Trig = Saturday, 16 February, 1991 AT 08:00
../tests/test.rem(575): Trig = Saturday, 16 February, 1991 AT 08:00
foo 8a
REM AT 9:00AM MSG foo 9a
../tests/test.rem(560): Trig = Saturday, 16 February, 1991 AT 09:00
../tests/test.rem(576): Trig = Saturday, 16 February, 1991 AT 09:00
foo 9a
REM AT 10:00am MSG foo 10a
../tests/test.rem(561): Trig = Saturday, 16 February, 1991 AT 10:00
../tests/test.rem(577): Trig = Saturday, 16 February, 1991 AT 10:00
foo 10a
REM AT 11:00AM MSG foo 11a
../tests/test.rem(562): Trig = Saturday, 16 February, 1991 AT 11:00
../tests/test.rem(578): Trig = Saturday, 16 February, 1991 AT 11:00
foo 11a
REM AT 12:00am MSG foo 12a
../tests/test.rem(563): Trig = Saturday, 16 February, 1991 AT 00:00
../tests/test.rem(579): Trig = Saturday, 16 February, 1991 AT 00:00
foo 12a
REM AT 13:00AM MSG foo 13a
../tests/test.rem(564): Expecting time after AT
../tests/test.rem(580): Expecting time after AT
REM AT 0:00pm MSG foo 0p
../tests/test.rem(565): Expecting time after AT
../tests/test.rem(581): Expecting time after AT
REM AT 1:00PM MSG foo 1p
../tests/test.rem(566): Trig = Saturday, 16 February, 1991 AT 13:00
../tests/test.rem(582): Trig = Saturday, 16 February, 1991 AT 13:00
foo 1p
REM AT 2:00pm MSG foo 2p
../tests/test.rem(567): Trig = Saturday, 16 February, 1991 AT 14:00
../tests/test.rem(583): Trig = Saturday, 16 February, 1991 AT 14:00
foo 2p
REM AT 3:00PM MSG foo 3p
../tests/test.rem(568): Trig = Saturday, 16 February, 1991 AT 15:00
../tests/test.rem(584): Trig = Saturday, 16 February, 1991 AT 15:00
foo 3p
REM AT 4:00pm MSG foo 4p
../tests/test.rem(569): Trig = Saturday, 16 February, 1991 AT 16:00
../tests/test.rem(585): Trig = Saturday, 16 February, 1991 AT 16:00
foo 4p
REM AT 5:00PM MSG foo 5p
../tests/test.rem(570): Trig = Saturday, 16 February, 1991 AT 17:00
../tests/test.rem(586): Trig = Saturday, 16 February, 1991 AT 17:00
foo 5p
REM AT 6:00pm MSG foo 6p
../tests/test.rem(571): Trig = Saturday, 16 February, 1991 AT 18:00
../tests/test.rem(587): Trig = Saturday, 16 February, 1991 AT 18:00
foo 6p
REM AT 7:00PM MSG foo 7p
../tests/test.rem(572): Trig = Saturday, 16 February, 1991 AT 19:00
../tests/test.rem(588): Trig = Saturday, 16 February, 1991 AT 19:00
foo 7p
REM AT 8:00pm MSG foo 8p
../tests/test.rem(573): Trig = Saturday, 16 February, 1991 AT 20:00
../tests/test.rem(589): Trig = Saturday, 16 February, 1991 AT 20:00
foo 8p
REM AT 9:00PM MSG foo 9p
../tests/test.rem(574): Trig = Saturday, 16 February, 1991 AT 21:00
../tests/test.rem(590): Trig = Saturday, 16 February, 1991 AT 21:00
foo 9p
REM AT 10:00pm MSG foo 10p
../tests/test.rem(575): Trig = Saturday, 16 February, 1991 AT 22:00
../tests/test.rem(591): Trig = Saturday, 16 February, 1991 AT 22:00
foo 10p
REM AT 11:00PM MSG foo 11p
../tests/test.rem(576): Trig = Saturday, 16 February, 1991 AT 23:00
../tests/test.rem(592): Trig = Saturday, 16 February, 1991 AT 23:00
foo 11p
REM AT 12:00pm MSG foo 12p
../tests/test.rem(577): Trig = Saturday, 16 February, 1991 AT 12:00
../tests/test.rem(593): Trig = Saturday, 16 February, 1991 AT 12:00
foo 12p
REM AT 13:00PM MSG foo 13p
../tests/test.rem(578): Expecting time after AT
../tests/test.rem(594): Expecting time after AT
DEBUG +x
SET x 0:00am + 0
../tests/test.rem(581): Ill-formed time
../tests/test.rem(597): Ill-formed time
SET x 1:00AM + 0
01:00 + 0 => 01:00
SET x 2:00am + 0
@@ -3414,10 +3448,10 @@ SET x 11:00AM + 0
SET x 12:00am + 0
00:00 + 0 => 00:00
SET x 13:00AM + 0
../tests/test.rem(594): Ill-formed time
../tests/test.rem(610): Ill-formed time
SET x 0:00pm + 0
../tests/test.rem(596): Ill-formed time
../tests/test.rem(612): Ill-formed time
SET x 1:00PM + 0
13:00 + 0 => 13:00
SET x 2:00pm + 0
@@ -3443,10 +3477,10 @@ SET x 11:00PM + 0
SET x 12:00pm + 0
12:00 + 0 => 12:00
SET x 13:00PM + 0
../tests/test.rem(609): Ill-formed time
../tests/test.rem(625): Ill-formed time
SET x '2015-02-03@0:00am' + 0
../tests/test.rem(611): Ill-formed time
../tests/test.rem(627): Ill-formed time
SET x '2015-02-03@1:00AM' + 0
2015-02-03@01:00 + 0 => 2015-02-03@01:00
SET x '2015-02-03@2:00am' + 0
@@ -3472,10 +3506,10 @@ SET x '2015-02-03@11:00AM' + 0
SET x '2015-02-03@12:00am' + 0
2015-02-03@00:00 + 0 => 2015-02-03@00:00
SET x '2015-02-03@13:00AM' + 0
../tests/test.rem(624): Ill-formed time
../tests/test.rem(640): Ill-formed time
SET x '2015-02-03@0:00pm' + 0
../tests/test.rem(626): Ill-formed time
../tests/test.rem(642): Ill-formed time
SET x '2015-02-03@1:00PM' + 0
2015-02-03@13:00 + 0 => 2015-02-03@13:00
SET x '2015-02-03@2:00pm' + 0
@@ -3501,7 +3535,7 @@ SET x '2015-02-03@11:00PM' + 0
SET x '2015-02-03@12:00pm' + 0
2015-02-03@12:00 + 0 => 2015-02-03@12:00
SET x '2015-02-03@13:00PM' + 0
../tests/test.rem(639): Ill-formed time
../tests/test.rem(655): Ill-formed time
# Test the ampm function
set x ampm(0:12) + ""
@@ -3597,88 +3631,88 @@ coerce("DATETIME", "2020-05-05@1:45pm") => 2020-05-05@13:45
set a $IntMin - 1
$IntMin => -2147483648
-2147483648 - 1 => Number too high
../tests/test.rem(678): `-': Number too high
../tests/test.rem(694): `-': Number too high
set a $IntMin - $IntMax
$IntMin => -2147483648
$IntMax => 2147483647
-2147483648 - 2147483647 => Number too high
../tests/test.rem(679): `-': Number too high
../tests/test.rem(695): `-': Number too high
set a $IntMax - $IntMin
$IntMax => 2147483647
$IntMin => -2147483648
2147483647 - -2147483648 => Number too high
../tests/test.rem(680): `-': Number too high
../tests/test.rem(696): `-': Number too high
set a $IntMax - (-1)
$IntMax => 2147483647
- 1 => -1
2147483647 - -1 => Number too high
../tests/test.rem(681): `-': Number too high
../tests/test.rem(697): `-': Number too high
set a $IntMax + 1
$IntMax => 2147483647
2147483647 + 1 => Number too high
../tests/test.rem(682): `+': Number too high
../tests/test.rem(698): `+': Number too high
set a $IntMax + $IntMax
$IntMax => 2147483647
$IntMax => 2147483647
2147483647 + 2147483647 => Number too high
../tests/test.rem(683): `+': Number too high
../tests/test.rem(699): `+': Number too high
set a $IntMin + (-1)
$IntMin => -2147483648
- 1 => -1
-2147483648 + -1 => Number too high
../tests/test.rem(684): `+': Number too high
../tests/test.rem(700): `+': Number too high
set a $IntMin + $IntMin
$IntMin => -2147483648
$IntMin => -2147483648
-2147483648 + -2147483648 => Number too high
../tests/test.rem(685): `+': Number too high
../tests/test.rem(701): `+': Number too high
set a $IntMax * 2
$IntMax => 2147483647
2147483647 * 2 => Number too high
../tests/test.rem(686): `*': Number too high
../tests/test.rem(702): `*': Number too high
set a $IntMax * $IntMax
$IntMax => 2147483647
$IntMax => 2147483647
2147483647 * 2147483647 => Number too high
../tests/test.rem(687): `*': Number too high
../tests/test.rem(703): `*': Number too high
set a $IntMax * $IntMin
$IntMax => 2147483647
$IntMin => -2147483648
2147483647 * -2147483648 => Number too high
../tests/test.rem(688): `*': Number too high
../tests/test.rem(704): `*': Number too high
set a $IntMin * 2
$IntMin => -2147483648
-2147483648 * 2 => Number too high
../tests/test.rem(689): `*': Number too high
../tests/test.rem(705): `*': Number too high
set a $IntMin * $IntMin
$IntMin => -2147483648
$IntMin => -2147483648
-2147483648 * -2147483648 => Number too high
../tests/test.rem(690): `*': Number too high
../tests/test.rem(706): `*': Number too high
set a $IntMin * $IntMax
$IntMin => -2147483648
$IntMax => 2147483647
-2147483648 * 2147483647 => Number too high
../tests/test.rem(691): `*': Number too high
../tests/test.rem(707): `*': Number too high
set a $IntMin / (-1)
$IntMin => -2147483648
- 1 => -1
-2147483648 / -1 => Number too high
../tests/test.rem(692): `/': Number too high
../tests/test.rem(708): `/': Number too high
set a $IntMin * (-1)
$IntMin => -2147483648
- 1 => -1
-2147483648 * -1 => Number too high
../tests/test.rem(693): `*': Number too high
../tests/test.rem(709): `*': Number too high
set a (-1) * $IntMin
- 1 => -1
$IntMin => -2147483648
-1 * -2147483648 => Number too high
../tests/test.rem(694): `*': Number too high
../tests/test.rem(710): `*': Number too high
set a abs($IntMin)
$IntMin => -2147483648
abs(-2147483648) => Number too high
../tests/test.rem(695): Number too high
../tests/test.rem(711): Number too high
# The "isany" function
set a isany(1)
@@ -3705,19 +3739,169 @@ set a shellescape(" !\"#$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ
shellescape(" !"#$%%&'()*+,-./0123456789:;<=>?@ABCDEF"...) => "\ \!\"\#\$\%\%\&\'\(\)\*+,-./0123456789\"...
msg [a]
../tests/test.rem(711): Trig = Saturday, 16 February, 1991
../tests/test.rem(727): Trig = Saturday, 16 February, 1991
a => "\ \!\"\#\$\%\%\&\'\(\)\*+,-./0123456789\"...
\ \!\"\#\$\\\&\'\(\)\*+,-./0123456789\:\;\<=\>\?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_\`abcdefghijklmnopqrstuvwxyz\{\|\}\~
# Deprecated functions
set x psshade(50)
psshade(50) => ../tests/test.rem(714): psshade() is deprecated; use SPECIAL SHADE instead.
psshade(50) => ../tests/test.rem(730): psshade() is deprecated; use SPECIAL SHADE instead.
"/_A LineWidth 2 div def _A _A moveto Box"...
set x psmoon(0)
psmoon(0) => ../tests/test.rem(715): psmoon() is deprecated; use SPECIAL MOON instead.
psmoon(0) => ../tests/test.rem(731): psmoon() is deprecated; use SPECIAL MOON instead.
"gsave 0 setgray newpath Border DaySize 2"...
# Trig
IF trig("sun +1") || trig("thu +1")
trig("sun +1") => ../tests/test.rem(734): Trig = Sunday, 17 February, 1991
1991-02-17
trig("thu +1") => ../tests/test.rem(734): Trig = Thursday, 21 February, 1991
1990-01-01
1991-02-17 || 1990-01-01 => 1991-02-17
REM [trig()] +1 MSG Foo %b
trig() => 1991-02-17
../tests/test.rem(735): Trig = Sunday, 17 February, 1991
Foo tomorrow
ENDIF
# Trig with a bad warnfunc
FSET w(x) x/0
IF trig("sun warn w") || trig("thu warn w")
trig("sun warn w") => ../tests/test.rem(740): Trig = Sunday, 17 February, 1991
Entering UserFN w(1)
x => 1
1 / 0 => Division by zero
../tests/test.rem(740): `/': Division by zero
Leaving UserFN w() => Division by zero
1990-01-01
trig("thu warn w") => ../tests/test.rem(740): Trig = Thursday, 21 February, 1991
Entering UserFN w(1)
x => 1
1 / 0 => Division by zero
Leaving UserFN w() => Division by zero
1990-01-01
1990-01-01 || 1990-01-01 => 1990-01-01
REM [trig()] +1 MSG Foo %b
ENDIF
# Trig with a good warnfunc
FSET w(x) choose(x, 5, 3, 1, 0)
# Ugh. This is where short-circuit logical operators
# would really come in handy.
IF trig("sun warn w") || trig("thu warn w")
trig("sun warn w") => ../tests/test.rem(749): Trig = Sunday, 17 February, 1991
Entering UserFN w(1)
x => 1
choose(1, 5, 3, 1, 0) => 5
Leaving UserFN w() => 5
Entering UserFN w(2)
x => 2
choose(2, 5, 3, 1, 0) => 3
Leaving UserFN w() => 3
Entering UserFN w(3)
x => 3
choose(3, 5, 3, 1, 0) => 1
Leaving UserFN w() => 1
1991-02-17
trig("thu warn w") => ../tests/test.rem(749): Trig = Thursday, 21 February, 1991
Entering UserFN w(1)
x => 1
choose(1, 5, 3, 1, 0) => 5
Leaving UserFN w() => 5
1991-02-21
1991-02-17 || 1991-02-21 => 1991-02-17
REM [trig()] +5 MSG Foo %b
trig() => 1991-02-21
../tests/test.rem(750): Trig = Thursday, 21 February, 1991
Foo in 5 days' time
ENDIF
REM [trig("Mon", "Tue", "Wed", "Sat")] MSG foo
trig("Mon", "Tue", "Wed", "Sat") => ../tests/test.rem(753): Trig = Monday, 18 February, 1991
../tests/test.rem(753): Trig = Tuesday, 19 February, 1991
../tests/test.rem(753): Trig = Wednesday, 20 February, 1991
../tests/test.rem(753): Trig = Saturday, 16 February, 1991
1991-02-16
../tests/test.rem(753): Trig = Saturday, 16 February, 1991
foo
REM [trig("Mon", "Tue", "Wed")] MSG bar
trig("Mon", "Tue", "Wed") => ../tests/test.rem(754): Trig = Monday, 18 February, 1991
../tests/test.rem(754): Trig = Tuesday, 19 February, 1991
../tests/test.rem(754): Trig = Wednesday, 20 February, 1991
1990-01-01
../tests/test.rem(754): Expired
# The new syntactic sugar
REM First Monday January MSG x
../tests/test.rem(757): Trig = Monday, 6 January, 1992
REM Second Tuesday in April MSG x
../tests/test.rem(758): Trig = Tuesday, 9 April, 1991
REM Third Wednesday in October MSG x
../tests/test.rem(759): Trig = Wednesday, 16 October, 1991
REM Fourth Friday in July MSG x
../tests/test.rem(760): Trig = Friday, 26 July, 1991
REM Last Tuesday in August MSG x
../tests/test.rem(761): Trig = Tuesday, 27 August, 1991
REM Last Sunday in December MSG x
../tests/test.rem(762): Trig = Sunday, 29 December, 1991
REM First Monday January 2000 MSG x
../tests/test.rem(764): Trig = Monday, 3 January, 2000
REM Second Tuesday in April 2000 MSG x
../tests/test.rem(765): Trig = Tuesday, 11 April, 2000
REM Third Wednesday in October 2000 MSG x
../tests/test.rem(766): Trig = Wednesday, 18 October, 2000
REM Fourth Friday in July 2000 MSG x
../tests/test.rem(767): Trig = Friday, 28 July, 2000
REM Last Tuesday in August 2000 MSG x
../tests/test.rem(768): Trig = Tuesday, 29 August, 2000
REM Last Sunday in December 2000 MSG x
../tests/test.rem(769): Trig = Sunday, 31 December, 2000
REM January ~~1 MSG y
../tests/test.rem(771): Trig = Friday, 31 January, 1992
REM February ~~1 MSG y
../tests/test.rem(772): Trig = Thursday, 28 February, 1991
REM February ~~2 MSG y
../tests/test.rem(773): Trig = Wednesday, 27 February, 1991
REM February ~~3 MSG y
../tests/test.rem(774): Trig = Tuesday, 26 February, 1991
REM February ~~8 MSG y
../tests/test.rem(775): Trig = Thursday, 21 February, 1991
REM February ~~20 MSG y
../tests/test.rem(776): Trig = Monday, 10 February, 1992
PUSH
OMIT 31 March
REM March ~1 MSG y
../tests/test.rem(779): Trig = Saturday, 30 March, 1991
REM March ~~1 MSG y
../tests/test.rem(780): Trig = Sunday, 31 March, 1991
REM Lastday March MSG y
../tests/test.rem(781): Trig = Sunday, 31 March, 1991
REM Lastworkday March MSG y
../tests/test.rem(782): Trig = Saturday, 30 March, 1991
POP
REM Dec 2000 ~~1 MSG y
../tests/test.rem(784): Trig = Sunday, 31 December, 2000
REM Dec 2000 ~~2 MSG y
../tests/test.rem(785): Trig = Saturday, 30 December, 2000
REM Dec 2000 ~~3 MSG y
../tests/test.rem(786): Trig = Friday, 29 December, 2000
REM Dec 2000 ~~7 MSG y
../tests/test.rem(787): Trig = Monday, 25 December, 2000
REM Jan 2001 ~~1 MSG y
../tests/test.rem(788): Trig = Wednesday, 31 January, 2001
REM Lastday April 2022 OMIT SAT SUN MSG foo
../tests/test.rem(790): Trig = Saturday, 30 April, 2022
REM Lastworkday April 2022 OMIT SAT SUN MSG foo
../tests/test.rem(791): Trig = Friday, 29 April, 2022
# Don't want Remind to queue reminders
EXIT

View File

@@ -524,6 +524,22 @@ msg [$Uw]%
msg [$Uy]%
msg [$Wednesday]%
# Diagnose until before start date, only for non-constant expressions and
# fully-specified start date
REM Mon 1992 UNTIL 1991-01-01 MSG Not diagnosed - not fully-specified start
REM 1992-01-01 *1 UNTIL 1991-12-31 MSG Diagnosed
set x '1992-01-01'
REM [x] *1 UNTIL 1991-12-31 MSG Not diagnosed - nonconst expression
REM MON FROM 1992-01-01 UNTIL 1991-12-31 Diagnosed
REM MON SCANFROM 1992-01-01 UNTIL 1991-12-31 Diagnosed
REM MON FROM [x] UNTIL 1991-12-31 Not diagnosed
REM MON SCANFROM [x] UNTIL 1991-12-31 Not diagnosed
REM 1992-01-01 UNTIL 1992-02-02 MSG Diagnosed
REM [x] UNTIL 1992-02-02 MSG Diagnosed
dump $aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
OMIT 2010-09-03 THROUGH 2010-09-15
OMIT December 25 MSG X
@@ -714,6 +730,66 @@ msg [a]
set x psshade(50)
set x psmoon(0)
# Trig
IF trig("sun +1") || trig("thu +1")
REM [trig()] +1 MSG Foo %b
ENDIF
# Trig with a bad warnfunc
FSET w(x) x/0
IF trig("sun warn w") || trig("thu warn w")
REM [trig()] +1 MSG Foo %b
ENDIF
# Trig with a good warnfunc
FSET w(x) choose(x, 5, 3, 1, 0)
# Ugh. This is where short-circuit logical operators
# would really come in handy.
IF trig("sun warn w") || trig("thu warn w")
REM [trig()] +5 MSG Foo %b
ENDIF
REM [trig("Mon", "Tue", "Wed", "Sat")] MSG foo
REM [trig("Mon", "Tue", "Wed")] MSG bar
# The new syntactic sugar
REM First Monday January MSG x
REM Second Tuesday in April MSG x
REM Third Wednesday in October MSG x
REM Fourth Friday in July MSG x
REM Last Tuesday in August MSG x
REM Last Sunday in December MSG x
REM First Monday January 2000 MSG x
REM Second Tuesday in April 2000 MSG x
REM Third Wednesday in October 2000 MSG x
REM Fourth Friday in July 2000 MSG x
REM Last Tuesday in August 2000 MSG x
REM Last Sunday in December 2000 MSG x
REM January ~~1 MSG y
REM February ~~1 MSG y
REM February ~~2 MSG y
REM February ~~3 MSG y
REM February ~~8 MSG y
REM February ~~20 MSG y
PUSH
OMIT 31 March
REM March ~1 MSG y
REM March ~~1 MSG y
REM Lastday March MSG y
REM Lastworkday March MSG y
POP
REM Dec 2000 ~~1 MSG y
REM Dec 2000 ~~2 MSG y
REM Dec 2000 ~~3 MSG y
REM Dec 2000 ~~7 MSG y
REM Jan 2001 ~~1 MSG y
REM Lastday April 2022 OMIT SAT SUN MSG foo
REM Lastworkday April 2022 OMIT SAT SUN MSG foo
# Don't want Remind to queue reminders
EXIT