mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 06:48:47 +02:00
Compare commits
52 Commits
03.04.00-R
...
03.04.02-B
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
732ce8283f | ||
|
|
122bd3e07e | ||
|
|
0ac5cbb837 | ||
|
|
7f3d4812a8 | ||
|
|
e1fa11c94c | ||
|
|
c06c65acf1 | ||
|
|
a84fa0bc8f | ||
|
|
054648e02b | ||
|
|
9548041334 | ||
|
|
da306f2900 | ||
|
|
26587aea02 | ||
|
|
adc86e0f00 | ||
|
|
a9ed5f075e | ||
|
|
21e30c980e | ||
|
|
a657b2e55a | ||
|
|
ff8c55b8b6 | ||
|
|
eb36c5bca0 | ||
|
|
89173ce1ee | ||
|
|
5d115ba3e3 | ||
|
|
7e3adeb9c9 | ||
|
|
080cda86fa | ||
|
|
6274cbad52 | ||
|
|
85c4ad821d | ||
|
|
b758a2fea8 | ||
|
|
6619cc7ca4 | ||
|
|
961f7a8a62 | ||
|
|
905287901f | ||
|
|
669be7bf57 | ||
|
|
9b8eb2dc4c | ||
|
|
00ab7b196d | ||
|
|
f616be4bdd | ||
|
|
8ae9ce8523 | ||
|
|
6d2bbbd7e2 | ||
|
|
1453be83b2 | ||
|
|
8659131be2 | ||
|
|
0276ce322d | ||
|
|
b36c99a34b | ||
|
|
ad575f1485 | ||
|
|
a9162f1472 | ||
|
|
221e2554a9 | ||
|
|
04ec6c3695 | ||
|
|
b1594980fc | ||
|
|
024a8ef38d | ||
|
|
b281051421 | ||
|
|
aa1b275b51 | ||
|
|
c22ca68857 | ||
|
|
3804ce3fe3 | ||
|
|
0977f1db04 | ||
|
|
83c97934c9 | ||
|
|
44c9d74caa | ||
|
|
172f56754a | ||
|
|
dc184cc713 |
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -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
|
||||
|
||||
4
Makefile
4
Makefile
@@ -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
28
configure
vendored
@@ -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"
|
||||
|
||||
15
configure.in
15
configure.in
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
251
man/remind.1
251
man/remind.1
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
266
scripts/tkremind
266
scripts/tkremind
@@ -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
|
||||
|
||||
@@ -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? */
|
||||
|
||||
@@ -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? */
|
||||
|
||||
122
src/dorem.c
122
src/dorem.c
@@ -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;
|
||||
}
|
||||
|
||||
82
src/expr.c
82
src/expr.c
@@ -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;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
66
src/funcs.c
66
src/funcs.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
26
src/token.c
26
src/token.c
@@ -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 */
|
||||
}
|
||||
|
||||
10
src/types.h
10
src/types.h
@@ -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 */
|
||||
|
||||
396
tests/test.cmp
396
tests/test.cmp
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user