mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 06:18:47 +02:00
Compare commits
63 Commits
05.00.02-B
...
05.00.04
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d801408933 | ||
|
|
79b3da3820 | ||
|
|
ed021d3f46 | ||
|
|
27d0fda280 | ||
|
|
ef12da4ec6 | ||
|
|
7b098e95ad | ||
|
|
7d13f4b09e | ||
|
|
cecdfe6ade | ||
|
|
216bbd6378 | ||
|
|
30e2e9c633 | ||
|
|
bf2aabd610 | ||
|
|
c019221d15 | ||
|
|
b7bd6faf07 | ||
|
|
80d58220fe | ||
|
|
cd8624e176 | ||
|
|
8515fb7ddd | ||
|
|
84f9f4ae0a | ||
|
|
e201ebcfa4 | ||
|
|
4e15c3ec35 | ||
|
|
1adccf9b1f | ||
|
|
a1aa5c2ad9 | ||
|
|
1e0d650737 | ||
|
|
553d092ca8 | ||
|
|
dc62841517 | ||
|
|
326e7bfc53 | ||
|
|
b9dc7c16ad | ||
|
|
abd54b016b | ||
|
|
db02b54067 | ||
|
|
40a78dfbbb | ||
|
|
c860b46baa | ||
|
|
1458ba8856 | ||
|
|
7b9b6ebc96 | ||
|
|
7ee4073c7a | ||
|
|
8c072cd9b6 | ||
|
|
b794a45c3f | ||
|
|
98e491ed1d | ||
|
|
c397cc06da | ||
|
|
8616236b3c | ||
|
|
702704af1a | ||
|
|
a0d1b19050 | ||
|
|
a5c8ae491c | ||
|
|
b3cf741d15 | ||
|
|
0b28dde9c7 | ||
|
|
5a3980b5b8 | ||
|
|
a8e33118d6 | ||
|
|
2223277f64 | ||
|
|
c72413e3c1 | ||
|
|
fa1033db6f | ||
|
|
61e3edd2ac | ||
|
|
093c97ff91 | ||
|
|
6e64b175aa | ||
|
|
09dba4bc94 | ||
|
|
2e443ac5b7 | ||
|
|
59a8c88178 | ||
|
|
40eab03d84 | ||
|
|
e993bf59cf | ||
|
|
c6de5a2c8f | ||
|
|
51cc939d0c | ||
|
|
c857192e6d | ||
|
|
4591c2b181 | ||
|
|
7843a1b2ba | ||
|
|
649481cf01 | ||
|
|
c253bdfcbe |
18
configure
vendored
18
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.71 for remind 05.00.01.
|
||||
# Generated by GNU Autoconf 2.71 for remind 05.00.04.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
|
||||
@@ -608,8 +608,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='remind'
|
||||
PACKAGE_TARNAME='remind'
|
||||
PACKAGE_VERSION='05.00.01'
|
||||
PACKAGE_STRING='remind 05.00.01'
|
||||
PACKAGE_VERSION='05.00.04'
|
||||
PACKAGE_STRING='remind 05.00.04'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL='https://dianne.skoll.ca/projects/remind/'
|
||||
|
||||
@@ -1264,7 +1264,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures remind 05.00.01 to adapt to many kinds of systems.
|
||||
\`configure' configures remind 05.00.04 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1326,7 +1326,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of remind 05.00.01:";;
|
||||
short | recursive ) echo "Configuration of remind 05.00.04:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1414,7 +1414,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
remind configure 05.00.01
|
||||
remind configure 05.00.04
|
||||
generated by GNU Autoconf 2.71
|
||||
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
@@ -1864,7 +1864,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by remind $as_me 05.00.01, which was
|
||||
It was created by remind $as_me 05.00.04, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
@@ -4703,7 +4703,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by remind $as_me 05.00.01, which was
|
||||
This file was extended by remind $as_me 05.00.04, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -4768,7 +4768,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config='$ac_cs_config_escaped'
|
||||
ac_cs_version="\\
|
||||
remind config.status 05.00.01
|
||||
remind config.status 05.00.04
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(remind, 05.00.01, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_INIT(remind, 05.00.04, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_CONFIG_SRCDIR([src/queue.c])
|
||||
|
||||
cat <<'EOF'
|
||||
|
||||
@@ -1,6 +1,57 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 5.0 Patch 2 - 2024-07-??
|
||||
* VERSION 5.0 Patch 4 - 2024-08-29
|
||||
|
||||
* IMPROVEMENT: remind: When checking if a SATISFY expression refers to the
|
||||
trigger date, look recursively at any user-defined functions it calls.
|
||||
This reduces spurious warnings.
|
||||
|
||||
* CHANGE: remind: Allow any type to be used as the test argument for IIF.
|
||||
|
||||
* IMPROVEMENT: remind man page: Clarify how various types are treated
|
||||
in boolean context.
|
||||
|
||||
* VERSION 5.0 Patch 3 - 2024-08-28
|
||||
|
||||
* IMPROVEMENT: remind: Preserve newlines ("%_" sequences) in calendar
|
||||
mode in most cases. See the remind man page for details.
|
||||
|
||||
* IMPROVEMENT: rem2pdf: rem2pdf can now produce PostScript and
|
||||
Encapsulated PostScript output in addition to PDF and SVG.
|
||||
|
||||
* IMPROVEMENT: remind: Emit warnings if a subst_XXX function takes the
|
||||
wrong number of arguments, or for custom sequences, if the function
|
||||
is not defined.
|
||||
|
||||
* IMPROVEMENT: remind: Emit warnings if WARN/SCHED/OMITFUNC functions
|
||||
do not reference their argument.
|
||||
|
||||
* IMPROVEMENT: remind: Allow strings to be used with logical
|
||||
operators. The empty string "" is considered false and all other
|
||||
strings are considered true.
|
||||
|
||||
* IMPROVEMENT: remind: Emit warnings for lines that are implicitly
|
||||
treated as REM commands; add warnings for REM commands that are
|
||||
implicitly treated as MSG-type reminders.
|
||||
|
||||
* IMPROVEMENT: remind: Add an optional fourth argument to the built-in
|
||||
ampm() function that specifies not to suppress a leading zero in the
|
||||
hour component.
|
||||
|
||||
* IMPROVEMENT: remind: If a SATISFY expression is not constant and
|
||||
doesn't reference the trigger date somehow, issue a warning.
|
||||
|
||||
* IMPROVEMENT: remind: Add a warning if a user-defined function is
|
||||
redefined. If you do have a use-case that requires you to redefine
|
||||
a function, simply FUNSET it first before FSETting it for the second
|
||||
time.
|
||||
|
||||
* DOCUMENTATION FIX: Clarify man pages and remove some information that
|
||||
has become incorrect as Remind has evolved.
|
||||
|
||||
* BUG FIX: Fix typos in man pages
|
||||
|
||||
* VERSION 5.0 Patch 2 - 2024-07-26
|
||||
|
||||
* IMPROVEMENT: Remind: Revamp how ONCE works. You can now set a
|
||||
special variable $OnceFile to be the path to a timestamp file. The
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
# Cut and paste as desired! Also, near the end, there are a bunch of #
|
||||
# holiday definitions for the U.S. #
|
||||
# #
|
||||
# *** NOTE *** #
|
||||
# #
|
||||
# This file is simply a grab-bag of examples. It is NOT meant to be #
|
||||
# included as-is in a live reminder file. #
|
||||
# #
|
||||
# Some examples provided by George M. Sipe <gsipe@pyratl.ga.pyramid.com> #
|
||||
# #
|
||||
# U.S. holidays provided by Dave Rickel <drickel@sjc.mentorg.com> #
|
||||
@@ -305,51 +310,51 @@ FSET _PastMon(x, y) IIF(WKDAYNUM(_h2(x,y))!=1, _h2(x,y), _h2(x,y)+1)
|
||||
SET InIsrael VALUE("InIsrael", 0)
|
||||
SET Reform VALUE("Reform", 0)
|
||||
|
||||
[_h(1, "Tishrey")] ++4 MSG %"Rosh Hashana 1%" is %b.
|
||||
REM [_h(1, "Tishrey")] ++4 MSG %"Rosh Hashana 1%" is %b.
|
||||
|
||||
# No RH-2 or Tzom Gedalia in Reform
|
||||
IF !Reform
|
||||
[_h(2, "Tishrey")] ++4 MSG %"Rosh Hashana 2%" is %b.
|
||||
[_PastSat(3, "Tishrey")] ++4 MSG %"Tzom Gedalia%" is %b.
|
||||
REM [_h(2, "Tishrey")] ++4 MSG %"Rosh Hashana 2%" is %b.
|
||||
REM [_PastSat(3, "Tishrey")] ++4 MSG %"Tzom Gedalia%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(10, "Tishrey")] ++4 MSG %"Yom Kippur%" is %b.
|
||||
[_h(15, "Tishrey")] ++4 MSG %"Sukkot 1%" is %b.
|
||||
REM [_h(10, "Tishrey")] ++4 MSG %"Yom Kippur%" is %b.
|
||||
REM [_h(15, "Tishrey")] ++4 MSG %"Sukkot 1%" is %b.
|
||||
|
||||
IF !InIsrael
|
||||
[_h(16, "Tishrey")] MSG %"Sukkot 2%"
|
||||
REM [_h(16, "Tishrey")] MSG %"Sukkot 2%"
|
||||
ENDIF
|
||||
|
||||
[_h(21, "Tishrey")] ++4 MSG %"Hoshana Rabba%" is %b.
|
||||
[_h(22, "Tishrey")] ++4 MSG %"Shemini Atzeret%" is %b.
|
||||
REM [_h(21, "Tishrey")] ++4 MSG %"Hoshana Rabba%" is %b.
|
||||
REM [_h(22, "Tishrey")] ++4 MSG %"Shemini Atzeret%" is %b.
|
||||
|
||||
IF InIsrael
|
||||
[_h(22, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
REM [_h(22, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
ELSE
|
||||
[_h(23, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
REM [_h(23, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
ENDIF
|
||||
|
||||
# Because Kislev can change length, we must be more careful about Chanukah
|
||||
FSET _chan(x) HEBDATE(24, "Kislev", $U-9)+x
|
||||
[_chan(1)] ++4 MSG %"Chanukah 1%" is %b.
|
||||
[_chan(2)] MSG %"Chanukah 2%"
|
||||
[_chan(3)] MSG %"Chanukah 3%"
|
||||
[_chan(4)] MSG %"Chanukah 4%"
|
||||
[_chan(5)] MSG %"Chanukah 5%"
|
||||
[_chan(6)] MSG %"Chanukah 6%"
|
||||
[_chan(7)] MSG %"Chanukah 7%"
|
||||
[_chan(8)] MSG %"Chanukah 8%"
|
||||
REM [_chan(1)] ++4 MSG %"Chanukah 1%" is %b.
|
||||
REM [_chan(2)] MSG %"Chanukah 2%"
|
||||
REM [_chan(3)] MSG %"Chanukah 3%"
|
||||
REM [_chan(4)] MSG %"Chanukah 4%"
|
||||
REM [_chan(5)] MSG %"Chanukah 5%"
|
||||
REM [_chan(6)] MSG %"Chanukah 6%"
|
||||
REM [_chan(7)] MSG %"Chanukah 7%"
|
||||
REM [_chan(8)] MSG %"Chanukah 8%"
|
||||
|
||||
# Not sure about Reform's position on the next one.
|
||||
IF !Reform
|
||||
# 10 Tevet will never be a Saturday, so whether or not to
|
||||
# move it is moot. (Thanks to Art Werschulz.)
|
||||
[_h(10, "Tevet")] MSG %"Tzom Tevet%" is %b.
|
||||
REM [_h(10, "Tevet")] MSG %"Tzom Tevet%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(15, "Shvat")] ++4 MSG %"Tu B'Shvat%" is %b.
|
||||
[_h(14, "Adar A")] ++4 MSG %"Purim Katan%" is %b.
|
||||
[_h(15, "Adar A")] ++4 MSG %"Shushan Purim Katan%" is %b.
|
||||
REM [_h(15, "Shvat")] ++4 MSG %"Tu B'Shvat%" is %b.
|
||||
REM [_h(14, "Adar A")] ++4 MSG %"Purim Katan%" is %b.
|
||||
REM [_h(15, "Adar A")] ++4 MSG %"Shushan Purim Katan%" is %b.
|
||||
|
||||
# If Purim is on Sunday, then Fast of Esther is 11 Adar.
|
||||
IF WKDAYNUM(_h2(13, "Adar")) != 6
|
||||
@@ -357,18 +362,18 @@ IF WKDAYNUM(_h2(13, "Adar")) != 6
|
||||
ELSE
|
||||
REM [_h2(11, "Adar")] ++4 MSG %"Fast of Esther%" is %b.
|
||||
ENDIF
|
||||
[_h(14, "Adar")] ++4 MSG %"Purim%" is %b.
|
||||
[_h(15, "Adar")] ++4 MSG %"Shushan Purim%" is %b.
|
||||
[_h(15, "Nisan")] ++4 MSG %"Pesach%" is %b.
|
||||
REM [_h(14, "Adar")] ++4 MSG %"Purim%" is %b.
|
||||
REM [_h(15, "Adar")] ++4 MSG %"Shushan Purim%" is %b.
|
||||
REM [_h(15, "Nisan")] ++4 MSG %"Pesach%" is %b.
|
||||
|
||||
IF !InIsrael
|
||||
[_h(16, "Nisan")] MSG %"Pesach 2%"
|
||||
REM [_h(16, "Nisan")] MSG %"Pesach 2%"
|
||||
ENDIF
|
||||
|
||||
[_h(21, "Nisan")] MSG %"Pesach 7%"
|
||||
REM [_h(21, "Nisan")] MSG %"Pesach 7%"
|
||||
|
||||
IF !InIsrael && !Reform
|
||||
[_h(22, "Nisan")] MSG %"Pesach 8%"
|
||||
REM [_h(22, "Nisan")] MSG %"Pesach 8%"
|
||||
ENDIF
|
||||
|
||||
REM [_PastSun(27, "Nisan")] SATISFY 1
|
||||
@@ -384,36 +389,36 @@ ENDIF
|
||||
# Thursday. If 4 Iyar is a Sunday, then Yom Hazikaron
|
||||
# moves to 5 Iyar and Yom Ha'atzmaut to 6 Iyar.
|
||||
IF WKDAYNUM(_h2(4, "Iyar")) == 4 || WKDAYNUM(_h2(4, "Iyar")) == 5
|
||||
[_h(2, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b.
|
||||
[_h(3, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
REM [_h(2, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b.
|
||||
REM [_h(3, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
ELSE
|
||||
IF WKDAYNUM(_h2(4, "Iyar")) == 0
|
||||
[_h(5, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b.
|
||||
[_h(6, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
REM [_h(5, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b.
|
||||
REM [_h(6, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
ELSE
|
||||
[_h(4, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b.
|
||||
[_h(5, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
REM [_h(4, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b.
|
||||
REM [_h(5, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
# Not sure about Reform's position on Lag B'Omer
|
||||
IF !Reform
|
||||
[_h(18, "Iyar")] ++4 MSG %"Lag B'Omer%" is %b.
|
||||
REM [_h(18, "Iyar")] ++4 MSG %"Lag B'Omer%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(28, "Iyar")] ++4 MSG %"Yom Yerushalayim%" is %b.
|
||||
[_h(6, "Sivan")] ++4 MSG %"Shavuot%" is %b.
|
||||
REM [_h(28, "Iyar")] ++4 MSG %"Yom Yerushalayim%" is %b.
|
||||
REM [_h(6, "Sivan")] ++4 MSG %"Shavuot%" is %b.
|
||||
|
||||
IF !InIsrael && !Reform
|
||||
[_h(7, "Sivan")] MSG %"Shavuot 2%"
|
||||
REM [_h(7, "Sivan")] MSG %"Shavuot 2%"
|
||||
ENDIF
|
||||
|
||||
# Fairly sure Reform Jews don't observe the next two
|
||||
IF !Reform
|
||||
# Tzom Tamuz and Tish'a B'Av are moved to Sunday if they normally
|
||||
# fall on a Saturday
|
||||
[_PastSat(17, "Tamuz")] ++4 MSG %"Tzom Tammuz%" is %b.
|
||||
[_PastSat(9, "Av")] ++4 MSG %"Tish'a B'Av%" is %b.
|
||||
REM [_PastSat(17, "Tamuz")] ++4 MSG %"Tzom Tammuz%" is %b.
|
||||
REM [_PastSat(9, "Av")] ++4 MSG %"Tish'a B'Av%" is %b.
|
||||
ENDIF
|
||||
|
||||
# Counting the omer - do the whole spiel, i.e:
|
||||
|
||||
@@ -10,7 +10,7 @@ REM 28 Oct MSG ΟΧΙ
|
||||
REM 25 Dec MSG ΧΡΙΣΤΟΥΓΕΝΝΑ
|
||||
REM 26 Dec MSG ΧΡΙΣΤΟΥΓΕΝΝΑ2
|
||||
|
||||
REM [orthodoxeaster($Uy)+1] ΔΕΥΤΕΡΑ ΤΟΥ ΠΑΣΧΑ
|
||||
REM [orthodoxeaster($Uy)+1] MSG ΔΕΥΤΕΡΑ ΤΟΥ ΠΑΣΧΑ
|
||||
|
||||
|
||||
# May first is a national holiday except if Sunday, day of great week (week before easter) or Monday after easter, then
|
||||
|
||||
@@ -19,50 +19,50 @@ FSET _BackTwoSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)-2)
|
||||
SET InIsrael VALUE("InIsrael", 0)
|
||||
SET Reform VALUE("Reform", 0)
|
||||
|
||||
[_h(1, "Tishrey")] ++4 MSG %"Rosh Hashana 1%" is %b.
|
||||
REM [_h(1, "Tishrey")] ++4 MSG %"Rosh Hashana 1%" is %b.
|
||||
|
||||
# No RH-2 or Tzom Gedalia in Reform
|
||||
IF !Reform
|
||||
[_h(2, "Tishrey")] ++4 MSG %"Rosh Hashana 2%" is %b.
|
||||
[_PastSat(3, "Tishrey")] ++4 MSG %"Tzom Gedalia%" is %b.
|
||||
REM [_h(2, "Tishrey")] ++4 MSG %"Rosh Hashana 2%" is %b.
|
||||
REM [_PastSat(3, "Tishrey")] ++4 MSG %"Tzom Gedalia%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(10, "Tishrey")] ++4 MSG %"Yom Kippur%" is %b.
|
||||
[_h(15, "Tishrey")] ++4 MSG %"Sukkot 1%" is %b.
|
||||
REM [_h(10, "Tishrey")] ++4 MSG %"Yom Kippur%" is %b.
|
||||
REM [_h(15, "Tishrey")] ++4 MSG %"Sukkot 1%" is %b.
|
||||
|
||||
IF !InIsrael
|
||||
[_h(16, "Tishrey")] MSG %"Sukkot 2%"
|
||||
REM [_h(16, "Tishrey")] MSG %"Sukkot 2%"
|
||||
ENDIF
|
||||
|
||||
[_h(21, "Tishrey")] ++4 MSG %"Hoshana Rabba%" is %b.
|
||||
[_h(22, "Tishrey")] ++4 MSG %"Shemini Atzeret%" is %b.
|
||||
REM [_h(21, "Tishrey")] ++4 MSG %"Hoshana Rabba%" is %b.
|
||||
REM [_h(22, "Tishrey")] ++4 MSG %"Shemini Atzeret%" is %b.
|
||||
|
||||
IF InIsrael
|
||||
[_h(22, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
REM [_h(22, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
ELSE
|
||||
[_h(23, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
REM [_h(23, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
ENDIF
|
||||
|
||||
# Because Kislev can change length, we must be more careful about Chanukah
|
||||
FSET _chan(x) HEBDATE(24, "Kislev", $U-9)+x
|
||||
[_chan(1)] ++4 MSG %"Chanukah 1%" is %b.
|
||||
[_chan(2)] MSG %"Chanukah 2%"
|
||||
[_chan(3)] MSG %"Chanukah 3%"
|
||||
[_chan(4)] MSG %"Chanukah 4%"
|
||||
[_chan(5)] MSG %"Chanukah 5%"
|
||||
[_chan(6)] MSG %"Chanukah 6%"
|
||||
[_chan(7)] MSG %"Chanukah 7%"
|
||||
[_chan(8)] MSG %"Chanukah 8%"
|
||||
REM [_chan(1)] ++4 MSG %"Chanukah 1%" is %b.
|
||||
REM [_chan(2)] MSG %"Chanukah 2%"
|
||||
REM [_chan(3)] MSG %"Chanukah 3%"
|
||||
REM [_chan(4)] MSG %"Chanukah 4%"
|
||||
REM [_chan(5)] MSG %"Chanukah 5%"
|
||||
REM [_chan(6)] MSG %"Chanukah 6%"
|
||||
REM [_chan(7)] MSG %"Chanukah 7%"
|
||||
REM [_chan(8)] MSG %"Chanukah 8%"
|
||||
|
||||
# Not sure about Reform's position on the next one.
|
||||
IF !Reform
|
||||
# 10 Tevet will never be a Saturday, so whether or not to
|
||||
# move it is moot. (Thanks to Art Werschulz.)
|
||||
[_h(10, "Tevet")] MSG %"Tzom Tevet%" is %b.
|
||||
REM [_h(10, "Tevet")] MSG %"Tzom Tevet%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(15, "Shvat")] ++4 MSG %"Tu B'Shvat%" is %b.
|
||||
[_h(14, "Adar A")] ++4 MSG %"Purim Katan%" is %b.
|
||||
REM [_h(15, "Shvat")] ++4 MSG %"Tu B'Shvat%" is %b.
|
||||
REM [_h(14, "Adar A")] ++4 MSG %"Purim Katan%" is %b.
|
||||
|
||||
# If Purim is on Sunday, then Fast of Esther is 11 Adar.
|
||||
IF WKDAYNUM(_h2(13, "Adar")) != 6
|
||||
@@ -70,39 +70,39 @@ IF WKDAYNUM(_h2(13, "Adar")) != 6
|
||||
ELSE
|
||||
REM [_h2(11, "Adar")] ++4 MSG %"Fast of Esther%" is %b.
|
||||
ENDIF
|
||||
[_h(14, "Adar")] ++4 MSG %"Purim%" is %b.
|
||||
[_h(15, "Nisan")] ++4 MSG %"Pesach%" is %b.
|
||||
REM [_h(14, "Adar")] ++4 MSG %"Purim%" is %b.
|
||||
REM [_h(15, "Nisan")] ++4 MSG %"Pesach%" is %b.
|
||||
|
||||
IF !InIsrael
|
||||
[_h(16, "Nisan")] MSG %"Pesach 2%"
|
||||
REM [_h(16, "Nisan")] MSG %"Pesach 2%"
|
||||
ENDIF
|
||||
|
||||
[_h(21, "Nisan")] MSG %"Pesach 7%"
|
||||
REM [_h(21, "Nisan")] MSG %"Pesach 7%"
|
||||
|
||||
IF !InIsrael && !Reform
|
||||
[_h(22, "Nisan")] MSG %"Pesach 8%"
|
||||
REM [_h(22, "Nisan")] MSG %"Pesach 8%"
|
||||
ENDIF
|
||||
|
||||
[_h(27, "Nisan")] ++4 MSG %"Yom HaShoah%" is %b.
|
||||
[_BackTwoFri(4, "Iyar")] ++4 MSG %"Yom HaZikaron%" is %b.
|
||||
[_BackTwoSat(5, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
REM [_h(27, "Nisan")] ++4 MSG %"Yom HaShoah%" is %b.
|
||||
REM [_BackTwoFri(4, "Iyar")] ++4 MSG %"Yom HaZikaron%" is %b.
|
||||
REM [_BackTwoSat(5, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
|
||||
# Not sure about Reform's position on Lag B'Omer
|
||||
IF !Reform
|
||||
[_h(18, "Iyar")] ++4 MSG %"Lag B'Omer%" is %b.
|
||||
REM [_h(18, "Iyar")] ++4 MSG %"Lag B'Omer%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(28, "Iyar")] ++4 MSG %"Yom Yerushalayim%" is %b.
|
||||
[_h(6, "Sivan")] ++4 MSG %"Shavuot%" is %b.
|
||||
REM [_h(28, "Iyar")] ++4 MSG %"Yom Yerushalayim%" is %b.
|
||||
REM [_h(6, "Sivan")] ++4 MSG %"Shavuot%" is %b.
|
||||
|
||||
IF !InIsrael && !Reform
|
||||
[_h(7, "Sivan")] MSG %"Shavuot 2%"
|
||||
REM [_h(7, "Sivan")] MSG %"Shavuot 2%"
|
||||
ENDIF
|
||||
|
||||
# Fairly sure Reform Jews don't observe the next two
|
||||
IF !Reform
|
||||
# Tzom Tamuz and Tish'a B'Av are moved to Sunday if they normally
|
||||
# fall on a Saturday
|
||||
[_PastSat(17, "Tamuz")] ++4 MSG %"Tzom Tammuz%" is %b.
|
||||
[_PastSat(9, "Av")] ++4 MSG %"Tish'a B'Av%" is %b.
|
||||
REM [_PastSat(17, "Tamuz")] ++4 MSG %"Tzom Tammuz%" is %b.
|
||||
REM [_PastSat(9, "Av")] ++4 MSG %"Tish'a B'Av%" is %b.
|
||||
ENDIF
|
||||
|
||||
@@ -525,9 +525,9 @@ contains the back value. If the "back" value was \-n, the value will
|
||||
be positive; if it was \-\-n, the value will be negative.
|
||||
.TP
|
||||
.B delta \fIn\fR
|
||||
If the reminder contained a "delta" clause (\+n or \+\+n), this key
|
||||
contains the delta value. If the "delta" value was \+n, the value will
|
||||
be positive; if it was \+\+n, the value will be negative.
|
||||
If the reminder contained a "delta" clause (+n or ++n), this key
|
||||
contains the delta value. If the "delta" value was +n, the value will
|
||||
be positive; if it was ++n, the value will be negative.
|
||||
.TP
|
||||
.B rep \fIn\fR
|
||||
If the reminder contained a "repeat" clause (*n), this key contains
|
||||
|
||||
152
man/remind.1.in
152
man/remind.1.in
@@ -240,13 +240,13 @@ regardless of the \fIdelta\fR supplied for each reminder.
|
||||
.B \-t\fR\fIn\fR
|
||||
If you supply a number \fIn\fR after the \fB\-t\fR option, then
|
||||
\fBRemind\fR pretends that echo \fBREM\fR command has a delta
|
||||
of \+\+\fIn\fR, regardless of any existing delta.
|
||||
of ++\fIn\fR, regardless of any existing delta.
|
||||
.TP
|
||||
.B \-tz\fR
|
||||
If you supply the letter \fBz\fR after the \fB\-t\fR option, then
|
||||
\fBRemind\fR sets all REM statements' deltas to zero, regardless of the
|
||||
value supplied in the REM statement itself. In effect, this disables
|
||||
all deltas of the form \fB\+\fIn\fR and \fB\+\+\fIn\fR.
|
||||
all deltas of the form \fB+\fIn\fR and \fB++\fIn\fR.
|
||||
.TP
|
||||
.B \-tt\fR[\fIn\fR]
|
||||
The \fB-tt\fR option causes \fBRemind\fR to assume a default delta of
|
||||
@@ -463,7 +463,7 @@ information.
|
||||
\fBRemind\fR supports the following long options, which \fIare\fR
|
||||
case-sensitive:
|
||||
|
||||
.RP
|
||||
.PP
|
||||
.B \-\-version
|
||||
The \fB\-\-version\fR option causes \fBRemind\fR to print its version number
|
||||
to standard output and then exit.
|
||||
@@ -555,12 +555,15 @@ Its syntax is:
|
||||
The parts of the \fBREM\fR command can be specified in any order, except
|
||||
that the \fIbody\fR must come immediately after the \fBMSG\fR,
|
||||
\fBRUN\fR, \fBCAL\fR, \fBPS\fR, \fBPSFILE\fR or \fBSATISFY\fR keyword.
|
||||
The portion of the \fBREM\fR command before the \fBMSG\fR, \fBMSF\fR
|
||||
\fBRUN\fR, \fBCAL\fR or \fBSATISFY\fR clause is called a
|
||||
\fItrigger\fR.
|
||||
.PP
|
||||
The \fBREM\fR token is optional, providing that the remainder
|
||||
of the command cannot be mistaken for another \fBRemind\fR command
|
||||
such as \fBOMIT\fR or \fBRUN\fR. The portion of the \fBREM\fR command
|
||||
before the \fBMSG\fR, \fBMSF\fR \fBRUN\fR, \fBCAL\fR or \fBSATISFY\fR clause
|
||||
is called a \fItrigger\fR.
|
||||
In earlier versions of \fBRemind\fR, the \fBREM\fR token was optional
|
||||
providing that the remainder of the command cannot be mistaken for
|
||||
another \fBRemind\fR command. However, this use is deprecated and will
|
||||
now cause a warning to be issued. All of your reminder lines should
|
||||
be written to start with the REM command.
|
||||
.PP
|
||||
.B "MSG, MSF, RUN, CAL, SPECIAL, PS and PSFILE"
|
||||
.PP
|
||||
@@ -573,14 +576,16 @@ used the \fB\-k\fR command-line option, then \fBMSG\fR-type reminders are
|
||||
passed to the appropriate program. Note that the options \fB\-c\fR,
|
||||
\fB\-s\fR, \fB\-p\fR and \fB\-n\fR disable the \fB\-k\fR option.
|
||||
.PP
|
||||
Note that you can omit the reminder type, in which case it
|
||||
defaults to \fBMSG\fR. So you can write:
|
||||
Earlier versions of \fBRemind\fR let you omit the reminder type,
|
||||
in which case it defaulted to \fBMSG\fR. However, this usage is
|
||||
deprecated and will cause a warning. Something like:
|
||||
.PP
|
||||
.nf
|
||||
6 January Dianne's Birthday
|
||||
REM 6 January Dianne's Birthday
|
||||
.fi
|
||||
.PP
|
||||
although this is not recommended.
|
||||
will issue the warning "Missing REM type; assuming MSG"
|
||||
|
||||
.PP
|
||||
The \fBMSF\fR keyword is almost the same as the \fBMSG\fR keyword,
|
||||
except that the reminder is formatted to fit into a paragraph-like
|
||||
@@ -1051,7 +1056,7 @@ will be updated, and the \fBONCE\fR keyword will not operate properly.
|
||||
You can fix this by setting a timestamp file for \fBRemind\fR to track
|
||||
the last-run date; see the documentation of \fB$OnceFile\fR in the
|
||||
\fBSYSTEM VARIABLES\fR section. If you use standard input as your
|
||||
\fBRemind\fR input file, then you \fImust\fR use \B$OnceFile\fR for the
|
||||
\fBRemind\fR input file, then you \fImust\fR use \fB$OnceFile\fR for the
|
||||
\fBONCE\fR keyword to work properly.
|
||||
.PP
|
||||
If you start \fBRemind\fR with the \fB\-o\fR option, then the \fBONCE\fR
|
||||
@@ -1565,7 +1570,35 @@ is replaced with "\fIyy\fR", the last two digits of the year.
|
||||
.TP
|
||||
.B %_
|
||||
(percent-underscore) is replaced with a newline. You can use this to
|
||||
achieve multi-line reminders.
|
||||
achieve multi-line reminders. Note that calendar back-ends vary in
|
||||
how they handle multi-line reminders:
|
||||
.RS
|
||||
.TP
|
||||
.B o
|
||||
Running \fBremind -c\fR preserves newlines in the terminal calendar output.
|
||||
.TP
|
||||
.B o
|
||||
\fBrem2pdf\fR preserves newlines if \fBremind\fR is invoked with the \fB\-pp\fR
|
||||
or \fB\-ppp\fR option.
|
||||
.TP
|
||||
.B o
|
||||
\fBrem2html\fR preserves newlines if \fBremind\fR is invoked with the
|
||||
\fB\-pp\fR option.
|
||||
.TP
|
||||
.B o
|
||||
\fBtkremind\fR preserves newlines.\fR
|
||||
.TP
|
||||
.B o
|
||||
\fBrem2ps\fR converts newlines to spaces. But \fBrem2ps\fR is deprecated;
|
||||
use \fBrem2pdf\fR instead.
|
||||
.TP
|
||||
.B o
|
||||
The "simple calendar" formats (ie, \fBremind\fR's \fB\-s\fR, \fB\-n\fR and
|
||||
\fB\-p\fR options) convert newlines to spaces.
|
||||
.PP
|
||||
All calendar back-ends collapse multiple spaces to a single space and
|
||||
multiple newlines to a single newline.
|
||||
.RE
|
||||
.TP
|
||||
.B %1
|
||||
is replaced with "now", "\fIm\fR minutes from now", "\fIm\fR minutes ago",
|
||||
@@ -1699,7 +1732,7 @@ or:
|
||||
The \fBOMIT\fR command is used to "globally" omit certain days
|
||||
(usually holidays). These globally-omitted days are skipped by the
|
||||
"\-" and "+" forms of \fIback\fR and \fIdelta\fR, but not by the
|
||||
"\-\-" and "\+\+" forms. Some examples:
|
||||
"\-\-" and "++" forms. Some examples:
|
||||
.PP
|
||||
.nf
|
||||
OMIT Saturday Sunday
|
||||
@@ -1995,6 +2028,10 @@ your INCLUDECMD uses expression-pasting that results in differences depending
|
||||
on the value of \fBtoday()\fR, then each \fIunique\fR version of the
|
||||
command will be executed once.
|
||||
.PP
|
||||
If a given reminder file contains more than one identical
|
||||
\fBINCLUDECMD\fR, only the first one will actually be executed. All
|
||||
subsequent identical ones will use the cached output from the first one.
|
||||
.PP
|
||||
|
||||
.SH THE BANNER COMMAND
|
||||
.PP
|
||||
@@ -2178,11 +2215,11 @@ and time separator characters for \fBDATE\fR and \fBTIME\fR constants apply
|
||||
also to \fBDATETIME\fR constants.
|
||||
.RE
|
||||
.PP
|
||||
.B ZERO VALUES
|
||||
.B ZERO VALUES AND TRUE/FALSE
|
||||
.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:
|
||||
All types have an associated \fIzero value\fR, which is treated as
|
||||
\fIfalse\fR by the IF command, the IIF function, and the logical
|
||||
operators. The zero values are:
|
||||
.PP
|
||||
.RS
|
||||
.PP
|
||||
@@ -2193,10 +2230,11 @@ zero values are:
|
||||
\fBTIME\fR - 00:00
|
||||
.PP
|
||||
\fBDATETIME\fR - '1990-01-01@00:00'
|
||||
.PP
|
||||
\fBSTRING\fR - "" (the empty string)
|
||||
.RE
|
||||
.PP
|
||||
Additionally, for the purpose of the IF command (but \fInot\fR the
|
||||
logical operators) the empty string "" is considered a false value.
|
||||
Any value other than the \fIzero value\fR is treated as \fItrue\fR.
|
||||
.PP
|
||||
.B OPERATORS
|
||||
.PP
|
||||
@@ -2219,8 +2257,8 @@ C operators.
|
||||
.PP
|
||||
.TP
|
||||
.B !
|
||||
Logical negation. Can be applied to an \fBINT\fR type. If the operand
|
||||
is non-zero, returns zero. Otherwise, returns 1.
|
||||
Logical negation. Can be applied to any type. If the operand
|
||||
is non-zero, returns 0. Otherwise, returns 1.
|
||||
.TP
|
||||
.B \-
|
||||
Unary minus. Can be applied to an \fBINT\fR. Returns the negative
|
||||
@@ -2324,15 +2362,16 @@ If the operands are not of the same type, == returns 0 and != returns
|
||||
.RE
|
||||
.TP
|
||||
.B &&
|
||||
This is the logical AND operator. Neither of its operands can be
|
||||
\fBSTRING\fR type. Returns the second operand if both operands are
|
||||
non-zero. Otherwise, returns whichever operand is zero.
|
||||
This is the logical AND operator. Returns the second operand if both
|
||||
operands are non-zero. Otherwise, returns whichever operand is zero.
|
||||
Operands can be any type and "zero" is interpreted as appropriate for
|
||||
each operand's type.
|
||||
.TP
|
||||
.B ||
|
||||
This is the logical OR operator. Neither of its operands can be
|
||||
\fBSTRING\fR type. It returns the first operand that is non-zero; if
|
||||
both operands are zero, then returns the second operand.
|
||||
|
||||
This is the logical OR operator. It returns the first operand that is
|
||||
non-zero; if both operands are zero, then returns the second operand.
|
||||
Operands can be any type and "zero" is interpreted as appropriate for
|
||||
each operand's type.
|
||||
.PP
|
||||
.B NOTES
|
||||
.PP
|
||||
@@ -2900,18 +2939,25 @@ is supplied, only the date component is used.
|
||||
Returns the time of "astronomical twilight" on the specified \fIdate\fR. If
|
||||
\fIdate\fR is omitted, defaults to \fBtoday()\fR.
|
||||
.TP
|
||||
.B ampm(tq_time [,s_am [,s_pm]])
|
||||
.B ampm(tq_time [,s_am [,s_pm [,i_lz]]])
|
||||
Returns a \fBSTRING\fR that is the result of converting \fItime\fR
|
||||
(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,
|
||||
$TimeSep and $DateTimeSep when formatting its output. For example:
|
||||
and "PM". The optional argument \fIlz\fR specifies whether or not
|
||||
the hour should be padded to two digits with a leading zero. If \fIlz\fR is
|
||||
zero, then a leading 0 is not added; otherwise, the hour is padded out to
|
||||
two digits with a leading zero. If not supplied, \fIlz\fR defaults to zero.
|
||||
.RS
|
||||
.PP
|
||||
The function obeys the system variables $DateSep, $TimeSep and
|
||||
$DateTimeSep when formatting its output. Here are some examples of
|
||||
its output:
|
||||
.PP
|
||||
.nf
|
||||
ampm(0:22) returns "12:22AM"
|
||||
ampm(17:45, "am", "pm") returns "5:45pm"
|
||||
ampm(17:45, "am", "pm", 1) returns "05:45pm"
|
||||
ampm('2020-03-14@21:34') returns "2020-03-14@9:34PM"
|
||||
.fi
|
||||
.PP
|
||||
@@ -3271,14 +3317,14 @@ out. The stripping algorithm is fairly naive; the function starts
|
||||
stripping characters when it encounters a "<" and it stops stripping
|
||||
when it encounters a ">".
|
||||
.TP
|
||||
.B iif(si_test1, x_arg1, [si_test2, x_arg2,...], x_default)
|
||||
If \fItest1\fR is not zero or the null string, returns \fIarg1\fR.
|
||||
Otherwise, if \fItest2\fR is not zero or the null string, returns
|
||||
\fIarg2\fR, and so on. If all of the \fItest\fR arguments are false,
|
||||
returns \fIdefault\fR. Note that all arguments are \fIalways\fR evaluated.
|
||||
This function accepts an odd number of arguments - note that prior to version
|
||||
03.00.05 of \fBRemind\fR, it accepted 3 arguments only. The 3-argument
|
||||
version of \fBiif()\fR is compatible with previous versions of \fBRemind\fR.
|
||||
.B iif(x_test1, x_arg1, [x_test2, x_arg2,...], x_default)
|
||||
If \fItest1\fR is true, returns \fIarg1\fR. Otherwise, if \fItest2\fR
|
||||
is true, returns \fIarg2\fR, and so on. If all of the \fItest\fR
|
||||
arguments are false, returns \fIdefault\fR. Note that all arguments
|
||||
are \fIalways\fR evaluated. This function accepts an odd number of
|
||||
arguments - note that prior to version 03.00.05 of \fBRemind\fR, it
|
||||
accepted 3 arguments only. The 3-argument version of \fBiif()\fR is
|
||||
compatible with previous versions of \fBRemind\fR.
|
||||
.TP
|
||||
.B index(s_search, s_target [,i_start)
|
||||
Returns an \fBINT\fR that is the location of \fItarget\fR in the
|
||||
@@ -4493,11 +4539,10 @@ The above sequence sets y to 1, which is the global value of x.
|
||||
.TP
|
||||
o
|
||||
User-defined functions may call other functions, including other user-defined
|
||||
functions. However, recursive calls are not allowed.
|
||||
.TP
|
||||
o
|
||||
User-defined functions are not syntax-checked when they are defined; parsing
|
||||
occurs only when they are called.
|
||||
functions. Recursive calls are allowed, but they must terminate (for
|
||||
example, by using a short-circuit operator or function that breaks the
|
||||
recursion) or an error will result after a certain maximum number of
|
||||
recursive calls (by default, 1000.)
|
||||
.TP
|
||||
o
|
||||
If a user-defined function has the same name as a built-in function,
|
||||
@@ -4519,6 +4564,11 @@ or thirdfunc will exist. \fBRemind\fR does not issue an error if you
|
||||
try to \fBFUNSET\fR a nonexistent user-defined function; it simply
|
||||
does nothing in that case.
|
||||
.PP
|
||||
If you define a user-defined function and then later on redefine it,
|
||||
\fBRemind\fR will issue a warning. If you do not want this warning,
|
||||
then use \fBFUNSET\fR to remove the existing definition before you
|
||||
redefine the function.
|
||||
.PP
|
||||
.SH PRECISE SCHEDULING
|
||||
.PP
|
||||
The \fBWARN\fR keyword allows precise control over advance warning in
|
||||
@@ -4652,8 +4702,14 @@ the error message "Can't compute trigger" is issued. Otherwise,
|
||||
\fBtrigvalid()\fR is set to 1.
|
||||
.PP
|
||||
This is really useful only if \fIexpr\fR involves a call to the
|
||||
\fBtrigdate()\fR or related functions; otherwise, \fIexpr\fR will not change as
|
||||
\fBRemind\fR iterates.
|
||||
\fBtrigdate()\fR or related functions or system variables; otherwise,
|
||||
\fIexpr\fR will not change as \fBRemind\fR iterates. In fact, if
|
||||
\fIexpr\fR is not a constant and does not call \fBtrigdate()\fR or
|
||||
related functions or system variables, then \fBRemind\fR will issue a
|
||||
warning. If you have a user-defined function that calls
|
||||
\fBtrigdate()\fR, this can result in an unwanted warning. In that
|
||||
case, pass \fBtrigdate()\fR or some related function or system
|
||||
variable into your user-defined function from the SATISFY expression.
|
||||
.PP
|
||||
An example of the usefulness of \fBSATISFY\fR: Suppose you wish to
|
||||
be warned of every Friday the 13th. Your first attempt may be:
|
||||
|
||||
@@ -266,7 +266,7 @@ Useful strings might be "emacs +%d %s" or "gvim +%d %s"
|
||||
.TP
|
||||
.B Extra Argument for Remind
|
||||
This specifies any extra arguments that should be passed to Remind
|
||||
when \BTkRemind\fR invokes \fBremind\fR. Unless you know what
|
||||
when \fBTkRemind\fR invokes \fBremind\fR. Unless you know what
|
||||
you are doing, leave this blank.
|
||||
|
||||
.TP
|
||||
|
||||
@@ -374,19 +374,37 @@ sub parse_input
|
||||
($1 % 256), ($1 % 256), ($1 % 256));
|
||||
}
|
||||
} elsif ($special eq 'COLOR' || $special eq 'COLOUR') {
|
||||
if ($body =~ /(\d+)\s+(\d+)\s+(\d+)\s+(.*)$/) {
|
||||
if ($body =~ /(\d+)\s+(\d+)\s+(\d+)\s+(.*)$/s) {
|
||||
my($r, $g, $b, $text) = ($1, $2, $3, $4);
|
||||
my $color = sprintf("style=\"color: #%02X%02X%02X;\"",
|
||||
$r % 256, $g % 256, $b % 256);
|
||||
push(@{$days->[$d]}, "<p$class $color>" . escape_html($text) . '</p>');
|
||||
push(@{$days->[$d]}, "<p$class $color>" . fix_whitespace(escape_html($text)) . '</p>');
|
||||
}
|
||||
} elsif ($special eq '*') {
|
||||
push(@{$days->[$d]}, "<p$class>" . escape_html($body) . '</p>');
|
||||
push(@{$days->[$d]}, "<p$class>" . fix_whitespace(escape_html($body)) . '</p>');
|
||||
}
|
||||
}
|
||||
return $found_data;
|
||||
}
|
||||
|
||||
sub fix_whitespace
|
||||
{
|
||||
my ($text) = @_;
|
||||
|
||||
# Collapse multiple spaces/tabs to a single space
|
||||
$text =~ s/[ \t]+/ /gs;
|
||||
|
||||
# Remove whitespace before/after newlines
|
||||
$text =~ s/\s+\n/\n/gs;
|
||||
$text =~ s/\n\s+/\n/gs;
|
||||
# Collapse multiple newlines to a single newline
|
||||
$text =~ s/\n+/\n/gs;
|
||||
|
||||
# Convert newlines to <br />
|
||||
$text =~ s|\n|<br />|g;
|
||||
return $text;
|
||||
}
|
||||
|
||||
sub small_calendar
|
||||
{
|
||||
my($month, $monlen, $url, $first_col) = @_;
|
||||
|
||||
@@ -61,6 +61,8 @@ my $settings = {
|
||||
margin_left => 36,
|
||||
margin_right => 36,
|
||||
svg => 0,
|
||||
ps => 0,
|
||||
eps => 0,
|
||||
verbose => 0,
|
||||
};
|
||||
|
||||
@@ -81,6 +83,8 @@ Options:
|
||||
--landscape, -l Print in landscape orientation
|
||||
--small-calendars=N Choose location for small calendars
|
||||
--svg Output SVG instead of PDF
|
||||
--ps Output PostScript instead of PDF
|
||||
--eps Output encapsulated PostScript instead of PDF
|
||||
-cN Synonym for --small-calendars=N
|
||||
--left-numbers, -x Print day numbers on the left
|
||||
--fill-page, -e Fill the entire page
|
||||
@@ -114,6 +118,8 @@ my $ret = GetOptions('landscape|l' => \$settings->{landscape},
|
||||
'small-calendars|c=i' => \$settings->{small_calendars},
|
||||
'left-numbers|x' => \$settings->{numbers_on_left},
|
||||
'svg' => \$settings->{svg},
|
||||
'ps' => \$settings->{ps},
|
||||
'eps' => \$settings->{eps},
|
||||
'fill-page|e' => \$settings->{fill_entire_page},
|
||||
'media|m=s' => \$settings->{media},
|
||||
'width|w=i' => \$settings->{width},
|
||||
@@ -178,6 +184,17 @@ if ($settings->{landscape}) {
|
||||
$settings->{height} = $tmp;
|
||||
}
|
||||
|
||||
if ($settings->{svg} && $settings->{ps} ||
|
||||
$settings->{svg} && $settings->{eps} ||
|
||||
$settings->{eps} && $settings->{ps}) {
|
||||
print STDERR "Only one of --eps, --ps or --svg may be used.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ($settings->{eps}) {
|
||||
$settings->{ps} = 1;
|
||||
}
|
||||
|
||||
# Don't read from a terminal
|
||||
if (-t STDIN) { ## no critic
|
||||
print STDERR "I can't read data from a terminal. Please run like this:\n";
|
||||
@@ -193,6 +210,17 @@ my $surface;
|
||||
if ($settings->{svg}) {
|
||||
$surface = Cairo::SvgSurface->create_for_stream(sub { print $_[1] unless $errored_out; }, undef,
|
||||
$settings->{width}, $settings->{height});
|
||||
} elsif ($settings->{ps}) {
|
||||
if ($settings->{landscape}) {
|
||||
$surface = Cairo::PsSurface->create_for_stream(sub { print $_[1] unless $errored_out; }, undef,
|
||||
$settings->{height}, $settings->{width});
|
||||
} else {
|
||||
$surface = Cairo::PsSurface->create_for_stream(sub { print $_[1] unless $errored_out; }, undef,
|
||||
$settings->{width}, $settings->{height});
|
||||
}
|
||||
if ($settings->{eps}) {
|
||||
$surface->set_eps(1);
|
||||
}
|
||||
} else {
|
||||
$surface = Cairo::PdfSurface->create_for_stream(sub { print $_[1] unless $errored_out; }, undef,
|
||||
$settings->{width}, $settings->{height});
|
||||
@@ -204,11 +232,26 @@ eval { $surface->set_metadata('author', 'Remind (https://dianne.skoll.ca/project
|
||||
eval { $surface->set_metadata('creator', 'rem2pdf (https://dianne.skoll.ca/projects/remind/)'); };
|
||||
eval { $surface->set_metadata('subject', 'Calendar'); };
|
||||
|
||||
if ($settings->{ps}) {
|
||||
$surface->dsc_comment('%%Title: Calendar');
|
||||
$surface->dsc_comment('%%Producer: rem2pdf (https://dianne.skoll.ca/projects/remind/)');
|
||||
$surface->dsc_comment('%%PageOrientation: ' . (($settings->{landscape}) ? 'Landscape' : 'Portrait'));
|
||||
$surface->dsc_begin_setup();
|
||||
}
|
||||
|
||||
my $cr = Cairo::Context->create($surface);
|
||||
$cr->set_line_width($settings->{line_thickness});
|
||||
if ($settings->{ps} && $settings->{landscape}) {
|
||||
$cr->translate(0, $settings->{width});
|
||||
$cr->rotate(-1.5707963267949); # Rotate -90 degrees
|
||||
}
|
||||
|
||||
my $warned = 0;
|
||||
while(1) {
|
||||
if ($settings->{ps}) {
|
||||
$surface->dsc_begin_page_setup();
|
||||
$surface->dsc_comment('%%PageOrientation: ' . (($settings->{landscape}) ? 'Landscape' : 'Portrait'));
|
||||
}
|
||||
my ($obj, $err) = Remind::PDF->create_from_stream(*STDIN,
|
||||
{color => 1,
|
||||
shade => 1,
|
||||
@@ -224,9 +267,9 @@ while(1) {
|
||||
}
|
||||
last;
|
||||
}
|
||||
if ($settings->{svg} && $done_one) {
|
||||
if (($settings->{eps} || $settings->{svg}) && $done_one) {
|
||||
if (!$warned) {
|
||||
print STDERR "WARNING: --svg can only output one page; ignoring subsequent\nmonths in a multi-month calendar.\n";
|
||||
print STDERR "WARNING: --eps and --svg can only output one page; ignoring subsequent\nmonths in a multi-month calendar.\n";
|
||||
$warned = 1;
|
||||
}
|
||||
next;
|
||||
@@ -289,18 +332,22 @@ __END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
rem2pdf - draw a PDF or SVG calendar from Remind output
|
||||
rem2pdf - draw a PDF, SVG or PostScript calendar from Remind output
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
remind -pp [options] file | rem2pdf [options] > output.pdf
|
||||
remind -pp [options] file | rem2pdf --svg [options] > output.svg
|
||||
remind -pp [options] file | rem2pdf --ps [options] > output.ps
|
||||
remind -pp [options] file | rem2pdf --eps [options] > output.eps
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<rem2pdf> reads the standard input, which should be the results of
|
||||
running B<remind> with the B<-p>, B<-pp> or B<-ppp> options. It emits
|
||||
PDF or SVG code that draws a calendar to standard output.
|
||||
PDF, SVG or PostScript code that draws a calendar to standard output. (The
|
||||
addition of support for SVG and PostScript means that rem2pdf is increasingly
|
||||
misnamed...)
|
||||
|
||||
B<rem2pdf> uses the Pango text formatting library (L<https://pango.gnome.org/>)
|
||||
and the Cairo graphics library (L<https://www.cairographics.org/>) to produce
|
||||
@@ -315,6 +362,16 @@ output at all.
|
||||
|
||||
=over
|
||||
|
||||
=item --ps
|
||||
|
||||
Output PostScript instead of PDF.
|
||||
|
||||
=item --eps
|
||||
|
||||
Output Encapsulated PostScript instead of PDF. In this case, you
|
||||
should feed C<rem2pdf> only one month's worth of calendar data,
|
||||
because it cannot create a multi-page encapsulated PostScript file.
|
||||
|
||||
=item --svg
|
||||
|
||||
Output SVG instead of PDF. In this case, you should feed C<rem2pdf>
|
||||
|
||||
@@ -85,6 +85,18 @@ sub render
|
||||
} else {
|
||||
$body = $self->{body};
|
||||
}
|
||||
|
||||
# Clean up the body:
|
||||
|
||||
# Collapse multiple spaces/tabs to a single space
|
||||
$body =~ s/[ \t]+/ /gs;
|
||||
|
||||
# Remove whitespace before/after newlines
|
||||
$body =~ s/\s+\n/\n/gs;
|
||||
$body =~ s/\n\s+/\n/gs;
|
||||
# Collapse multiple newlines to a single newline
|
||||
$body =~ s/\n+/\n/gs;
|
||||
|
||||
$layout->set_text(Encode::decode('UTF-8', $body));
|
||||
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . $settings->{entry_size} . 'px');
|
||||
$layout->set_font_description($desc);
|
||||
|
||||
@@ -319,7 +319,7 @@ set Option(PrintMargins) 36pt
|
||||
set OptDescr(PrintSmallCalendars) "(0/1) If 1, print small calendars in PostScript output"
|
||||
set Option(PrintSmallCalendars) 1
|
||||
|
||||
set OptDescr(PrintFormat) "Print format: pdf or ps"
|
||||
set OptDescr(PrintFormat) "Print format: pdf, ps or ps1 - ps1 means PostScript using rem2pdf"
|
||||
set Option(PrintFormat) ps
|
||||
|
||||
set WarningHeaders [list "# Lines starting with REM TAG TKTAGnnn ... were created by tkremind" "# Do not edit them by hand or results may be unpredictable."]
|
||||
@@ -1217,6 +1217,13 @@ proc FillCalWindow {} {
|
||||
continue
|
||||
}
|
||||
.cal.t$n configure -state normal
|
||||
|
||||
# Canonicalize spaces and newlines
|
||||
set stuff [regsub -all {[ \t]+} $stuff " "]
|
||||
set stuff [regsub -all {[ \t]+\n} $stuff "\n"]
|
||||
set stuff [regsub -all {\n[ \t]} $stuff "\n"]
|
||||
set stuff [regsub -all {\n+} $stuff "\n"]
|
||||
|
||||
if {[regexp {TKTAG([0-9]+)} $tag all tagno] && "$fntag" != "x"} {
|
||||
.cal.t$n insert end [string trim $stuff] [list REM TAGGED "TKTAG$tagno" "date_$date" $extratags $fntag]
|
||||
.cal.t$n tag bind "TKTAG$tagno" <Enter> "TaggedEnter .cal.t$n"
|
||||
@@ -1333,7 +1340,8 @@ proc DoPrint {} {
|
||||
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
|
||||
radiobutton .p.ps -text "PostScript (using rem2ps)" -variable Option(PrintFormat) -value ps
|
||||
radiobutton .p.ps1 -text "PostScript (using rem2pdf)" -variable Option(PrintFormat) -value ps1
|
||||
}
|
||||
|
||||
label .p.size -text "Paper Size:"
|
||||
@@ -1350,7 +1358,7 @@ proc DoPrint {} {
|
||||
radiobutton .p.portrait -text "Portrait" -variable Option(PrintOrient) -value portrait
|
||||
|
||||
checkbutton .p.fill -text "Fill page" -variable Option(PrintFill)
|
||||
checkbutton .p.wrap -text "Use at most 5 rows (PDF only)" -variable Option(WrapCal)
|
||||
checkbutton .p.wrap -text "Use at most 5 rows (rem2pdf only)" -variable Option(WrapCal)
|
||||
checkbutton .p.right -text "Day numbers at top-right" -variable Option(PrintDaysRight)
|
||||
checkbutton .p.encoding -text "ISO 8859-1 PostScript encoding" -variable Option(PrintEncoding)
|
||||
checkbutton .p.calendars -text "Print small calendars" -variable Option(PrintSmallCalendars)
|
||||
@@ -1374,7 +1382,7 @@ proc DoPrint {} {
|
||||
pack .p.tofile .p.filename .p.browse -in .p.f11 -side left -fill none -expand 0 -anchor w
|
||||
pack .p.tocmd .p.command -in .p.f12 -side left -fill none -expand 0 -anchor w
|
||||
if { $HaveRem2PDF } {
|
||||
pack .p.format .p.pdf .p.ps -in .p.ff -side top -fill none -expand 0 -anchor w
|
||||
pack .p.format .p.pdf .p.ps .p.ps1 -in .p.ff -side top -fill none -expand 0 -anchor w
|
||||
}
|
||||
pack .p.size .p.letter .p.a4 -in .p.f2 -side top -fill none -expand 0 -anchor w
|
||||
pack .p.margin .p.24pt .p.36pt .p.48pt -in .p.f2a -side top -anchor w -fill none -expand 0
|
||||
@@ -1422,6 +1430,9 @@ proc DoPrint {} {
|
||||
if {$HaveRem2PDF && $Option(PrintFormat) == "pdf"} {
|
||||
set p [regsub @EXTRA@ $PSCmd "-itkpdf=1 $Option(ExtraRemindArgs)"]
|
||||
set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PDF"
|
||||
} elseif {$HaveRem2PDF && $Option(PrintFormat) == "ps1"} {
|
||||
set p [regsub @EXTRA@ $PSCmd "-itkpdf=1 $Option(ExtraRemindArgs)"]
|
||||
set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PDF --ps"
|
||||
} else {
|
||||
set p [regsub @EXTRA@ $PSCmd $Option(ExtraRemindArgs)]
|
||||
set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PS"
|
||||
@@ -1463,7 +1474,7 @@ proc DoPrint {} {
|
||||
}
|
||||
|
||||
if {$Option(WrapCal)} {
|
||||
if {$Option(PrintFormat) == "pdf"} {
|
||||
if {$Option(PrintFormat) == "pdf" || $Option(PrintFormat) == "ps1"} {
|
||||
append cmd " --wrap"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,13 +758,11 @@ SetMoonEntry(int dse, char const *moon)
|
||||
if (sscanf(moon, "%d %*d %*d %27[^\x01]", &phase, msg) < 4) {
|
||||
if (sscanf(moon, "%d", &phase) != 1) {
|
||||
/* Malformed MOON special; ignore */
|
||||
fprintf(stderr, "Oops 1\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (phase < 0 || phase > 3) {
|
||||
/* Bad phase */
|
||||
fprintf(stderr, "Oops 2\n");
|
||||
return;
|
||||
}
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
@@ -1414,7 +1412,7 @@ static int WriteOneColLine(int col)
|
||||
/* Find the last space char within the column. */
|
||||
width = 0;
|
||||
while (width <= ColSpaces) {
|
||||
if (!*ws) {
|
||||
if (!*ws || *ws == '\n') {
|
||||
wspace = ws;
|
||||
break;
|
||||
}
|
||||
@@ -1520,7 +1518,7 @@ static int WriteOneColLine(int col)
|
||||
|
||||
/* Find the last space char within the column. */
|
||||
while (s - e->pos <= ColSpaces) {
|
||||
if (!*s) {space = s; break;}
|
||||
if (!*s || *s == '\n') {space = s; break;}
|
||||
if (isspace(*s)) space = s;
|
||||
s++;
|
||||
}
|
||||
@@ -1683,7 +1681,10 @@ static void GenerateCalEntries(int col)
|
||||
/* Note: Since the parser hasn't been used yet, we don't */
|
||||
/* need to destroy it here. */
|
||||
|
||||
default: CreateParser(CurLine, &p);
|
||||
default:
|
||||
Wprint("Unrecognized command; interpreting as REM");
|
||||
WarnedAboutImplicit = 1;
|
||||
CreateParser(CurLine, &p);
|
||||
r=DoCalRem(&p, col);
|
||||
break;
|
||||
}
|
||||
|
||||
159
src/dorem.c
159
src/dorem.c
@@ -32,6 +32,152 @@ static int ParseUntil (ParsePtr s, Trigger *t, int type);
|
||||
static int ShouldTriggerBasedOnWarn (Trigger *t, int dse, int *err);
|
||||
static int ComputeTrigDuration(TimeTrig *t);
|
||||
|
||||
static int
|
||||
ensure_expr_references_first_local_arg(expr_node *node)
|
||||
{
|
||||
expr_node *other;
|
||||
|
||||
if (!node) {
|
||||
return 0;
|
||||
}
|
||||
if (node->type == N_LOCAL_VAR && node->u.arg == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (ensure_expr_references_first_local_arg(node->child)) {
|
||||
return 1;
|
||||
}
|
||||
other = node->sibling;
|
||||
while (other) {
|
||||
if (ensure_expr_references_first_local_arg(other)) {
|
||||
return 1;
|
||||
}
|
||||
other = other->sibling;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
check_trigger_function(char const *fname, char const *type)
|
||||
{
|
||||
UserFunc *f;
|
||||
if (!*fname) {
|
||||
return;
|
||||
}
|
||||
f = FindUserFunc(fname);
|
||||
if (!f) {
|
||||
if (strcmp(type, "WARN")) {
|
||||
/* Undefined WARN functions are diagnosed elsewhere... */
|
||||
Wprint("Undefined %s function: `%s'", type, fname);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (f->nargs != 1) {
|
||||
Wprint("%s function `%s' defined at %s:%d should take 1 argument but actually takes %d", type, fname, f->filename, f->lineno, f->nargs);
|
||||
return;
|
||||
}
|
||||
if (ensure_expr_references_first_local_arg(f->node)) {
|
||||
return;
|
||||
}
|
||||
Wprint("%s function `%s' defined at %s:%d does not use its argument", type, fname, f->filename, f->lineno);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_satnode_mentions_trigdate_aux(expr_node *node, int *mentioned)
|
||||
{
|
||||
char const *name;
|
||||
expr_node *other;
|
||||
UserFunc *f;
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
if (*mentioned) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->type == N_BUILTIN_FUNC) {
|
||||
name = node->u.builtin_func->name;
|
||||
if (!strcmp(name, "trigdate") ||
|
||||
!strcmp(name, "trigdatetime")) {
|
||||
*mentioned = 1;
|
||||
return;
|
||||
}
|
||||
} else if (node->type == N_SHORT_SYSVAR || node->type == N_SYSVAR) {
|
||||
if (node->type == N_SHORT_SYSVAR) {
|
||||
name = node->u.name;
|
||||
} else {
|
||||
name = node->u.value.v.str;
|
||||
}
|
||||
if (!StrCmpi(name, "T") ||
|
||||
!StrCmpi(name, "Td") ||
|
||||
!StrCmpi(name, "Tm") ||
|
||||
!StrCmpi(name, "Tw") ||
|
||||
!StrCmpi(name, "Ty")) {
|
||||
*mentioned = 1;
|
||||
return;
|
||||
}
|
||||
} else if (node->type == N_SHORT_USER_FUNC || node->type == N_USER_FUNC) {
|
||||
if (node->type == N_SHORT_USER_FUNC) {
|
||||
name = node->u.name;
|
||||
} else {
|
||||
name = node->u.value.v.str;
|
||||
}
|
||||
f = FindUserFunc(name);
|
||||
if (f && !f->recurse_flag) {
|
||||
f->recurse_flag = 1;
|
||||
ensure_satnode_mentions_trigdate_aux(f->node, mentioned);
|
||||
f->recurse_flag = 0;
|
||||
if (*mentioned) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ensure_satnode_mentions_trigdate_aux(node->child, mentioned);
|
||||
if (*mentioned) {
|
||||
return;
|
||||
}
|
||||
other = node->sibling;
|
||||
while (other) {
|
||||
ensure_satnode_mentions_trigdate_aux(other, mentioned);
|
||||
if (*mentioned) {
|
||||
return;
|
||||
}
|
||||
other = other->sibling;
|
||||
}
|
||||
}
|
||||
|
||||
static void ensure_satnode_mentions_trigdate(expr_node *node)
|
||||
{
|
||||
int mentioned = 0;
|
||||
char const *str;
|
||||
if (node->type == N_CONSTANT || node->type == N_SHORT_STR) {
|
||||
if (node->type == N_CONSTANT) {
|
||||
if (node->u.value.type == INT_TYPE) {
|
||||
if (node->u.value.v.val == 0) {
|
||||
Wprint("SATISFY: constant 0 will never be true");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (node->u.value.type != STR_TYPE) {
|
||||
return;
|
||||
}
|
||||
str = node->u.value.v.str;
|
||||
} else {
|
||||
str = node->u.name;
|
||||
}
|
||||
if (!*str) {
|
||||
Wprint("SATISFY: constant \"\" will never be true");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ensure_satnode_mentions_trigdate_aux(node, &mentioned);
|
||||
if (!mentioned) {
|
||||
Wprint("SATISFY: expression has no reference to trigdate() or $T...");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ComputeTrigDuration(TimeTrig *t)
|
||||
{
|
||||
@@ -540,6 +686,10 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
DBufFree(&buf);
|
||||
trig->typ = MSG_TYPE;
|
||||
if (s->isnested) return E_CANT_NEST_RTYPE;
|
||||
if (!WarnedAboutImplicit) {
|
||||
Wprint("Missing REM type; assuming MSG");
|
||||
WarnedAboutImplicit = 1;
|
||||
}
|
||||
parsing = 0;
|
||||
break;
|
||||
}
|
||||
@@ -591,6 +741,11 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
trig->scanfrom = DSEToday;
|
||||
}
|
||||
|
||||
/* Check that any SCHED / WARN / OMITFUNC functions refer to
|
||||
their arguments */
|
||||
check_trigger_function(trig->sched, "SCHED");
|
||||
check_trigger_function(trig->warn, "WARN");
|
||||
check_trigger_function(trig->omitfunc, "OMITFUNC");
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1283,6 +1438,10 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
if (!sat_node) {
|
||||
return E_SWERR;
|
||||
}
|
||||
|
||||
/* Diagnose if SAT_NODE does not reference trigdate */
|
||||
ensure_satnode_mentions_trigdate(sat_node);
|
||||
|
||||
iter = 0;
|
||||
start = trig->scanfrom;
|
||||
while (iter++ < MaxSatIter) {
|
||||
|
||||
@@ -31,6 +31,19 @@
|
||||
|
||||
#define SHIP_OUT(s) if(DBufPuts(dbuf, s) != OK) return E_NO_MEM
|
||||
|
||||
static int
|
||||
check_subst_args(UserFunc *f, int n)
|
||||
{
|
||||
if (!f) {
|
||||
return 0;
|
||||
}
|
||||
if (f->nargs == n) {
|
||||
return 1;
|
||||
}
|
||||
Wprint("Function `%s' defined at %s:%d should take %d argument%s, but actually takes %d",
|
||||
f->name, f->filename, f->lineno, n, (n == 1 ? "" : "s"), f->nargs);
|
||||
return 0;
|
||||
}
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoSubst */
|
||||
@@ -67,6 +80,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
int altmode;
|
||||
int r;
|
||||
Value v;
|
||||
UserFunc *func;
|
||||
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
|
||||
@@ -100,7 +114,8 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
L_AMPM_OVERRIDE (pm, h)
|
||||
#else
|
||||
r = -1;
|
||||
if (UserFuncExists("subst_ampm") == 1) {
|
||||
func = FindUserFunc("subst_ampm");
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
snprintf(s, sizeof(s), "subst_ampm(%d)", h);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
@@ -129,7 +144,8 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
L_AMPM_OVERRIDE (cpm, ch)
|
||||
#else
|
||||
r = -1;
|
||||
if (UserFuncExists("subst_ampm") == 1) {
|
||||
func = FindUserFunc("subst_ampm");
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
snprintf(s, sizeof(s), "subst_ampm(%d)", ch);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
@@ -154,7 +170,8 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
#ifdef L_ORDINAL_OVERRIDE
|
||||
L_ORDINAL_OVERRIDE;
|
||||
#else
|
||||
if (UserFuncExists("subst_ordinal") == 1) {
|
||||
func = FindUserFunc("subst_ordinal");
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
snprintf(s, sizeof(s), "subst_ordinal(%d)", d);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
@@ -250,7 +267,13 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
if (!c) {
|
||||
Wprint("Warning: Unterminated %%{...} substitution sequence");
|
||||
}
|
||||
if (UserFuncExists(s) != 3) {
|
||||
func = FindUserFunc(s);
|
||||
if (!func) {
|
||||
Wprint("No substition function `%s' defined", s);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!check_subst_args(func, 3)) {
|
||||
continue;
|
||||
}
|
||||
snprintf(ss, sizeof(s) - (ss-s), "(%d,'%04d-%02d-%02d',%02d:%02d)",
|
||||
@@ -270,7 +293,8 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
done = 0;
|
||||
snprintf(uf, sizeof(uf), "subst_%c", tolower(c));
|
||||
if (UserFuncExists(uf) == 3) {
|
||||
func = FindUserFunc(uf);
|
||||
if (func && check_subst_args(func, 3)) {
|
||||
snprintf(s, sizeof(s), "subst_%c(%d,'%04d-%02d-%02d',%02d:%02d)",
|
||||
tolower(c), altmode ? 1 : 0, y, m+1, d, h, min);
|
||||
expr = (char const *) s;
|
||||
@@ -345,7 +369,8 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
|
||||
if (!done) {
|
||||
snprintf(uf, sizeof(uf), "subst_%cx", tolower(c));
|
||||
if (UserFuncExists(uf) == 3) {
|
||||
func = FindUserFunc(uf);
|
||||
if (func && check_subst_args(func, 3)) {
|
||||
snprintf(s, sizeof(s), "subst_%cx(%d,'%04d-%02d-%02d',%02d:%02d)",
|
||||
tolower(c), altmode ? 1 : 0, y, m+1, d, h, min);
|
||||
expr = (char const *) s;
|
||||
@@ -797,7 +822,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
break;
|
||||
|
||||
case '_':
|
||||
if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !(MsgCommand && *MsgCommand))) {
|
||||
if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || DoCalendar || (mode != CAL_MODE && mode != ADVANCE_MODE && !(MsgCommand && *MsgCommand))) {
|
||||
snprintf(s, sizeof(s), "%s", NL);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), " ");
|
||||
|
||||
@@ -204,7 +204,7 @@ EXTERN char *ErrMsg[]
|
||||
/* E_ERR_READING */ "Error reading",
|
||||
/* E_EXPECTING_EOL */ "Expecting end-of-line",
|
||||
/* E_BAD_HEBDATE */ "Invalid Hebrew date",
|
||||
/* E_IIF_ODD */ "IIF needs odd number of arguments",
|
||||
/* E_IIF_ODD */ "iif(): odd number of arguments required",
|
||||
/* E_MISS_ENDIF */ "Warning: Missing ENDIF",
|
||||
/* E_EXPECT_COMMA */ "Expecting comma",
|
||||
/* E_WD_TWICE */ "Weekday specified twice",
|
||||
@@ -241,7 +241,7 @@ EXTERN char *ErrMsg[]
|
||||
/* E_NOREMINDERS */ "No reminders.",
|
||||
/* M_QUEUED */ "%d reminder(s) queued for later today.\n",
|
||||
/* E_EXPECTING_NUMBER */ "Expecting number",
|
||||
/* M_BAD_WARN_FUNC */ "Bad function in WARN clause",
|
||||
/* M_BAD_WARN_FUNC */ "Undefined WARN function",
|
||||
/* E_CANT_CONVERT_TZ */ "Can't convert between time zones",
|
||||
/* E_NO_MATCHING_REMS */ "No files matching *.rem",
|
||||
/* E_STRING_TOO_LONG */ "String too long",
|
||||
|
||||
68
src/expr.c
68
src/expr.c
@@ -425,8 +425,14 @@ eval_builtin(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
Value stack_args[STACK_ARGS_MAX];
|
||||
|
||||
/* Check that we have the right number of argumens */
|
||||
if (node->num_kids < f->minargs) return E_2FEW_ARGS;
|
||||
if (node->num_kids > f->maxargs && f->maxargs != NO_MAX) return E_2MANY_ARGS;
|
||||
if (node->num_kids < f->minargs) {
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2FEW_ARGS]);
|
||||
return E_2FEW_ARGS;
|
||||
}
|
||||
if (node->num_kids > f->maxargs && f->maxargs != NO_MAX) {
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2MANY_ARGS]);
|
||||
return E_2MANY_ARGS;
|
||||
}
|
||||
|
||||
/* If this is a new-style function that knows about expr_nodes,
|
||||
let it evaluate itself */
|
||||
@@ -622,10 +628,12 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
/* Make sure we have the right number of arguments */
|
||||
if (node->num_kids < f->nargs) {
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, ErrMsg[E_2FEW_ARGS]));
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2FEW_ARGS]);
|
||||
return E_2FEW_ARGS;
|
||||
}
|
||||
if (node->num_kids > f->nargs) {
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, ErrMsg[E_2MANY_ARGS]));
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2MANY_ARGS]);
|
||||
return E_2MANY_ARGS;
|
||||
}
|
||||
|
||||
@@ -1367,7 +1375,7 @@ static int divide_or_mod(expr_node *node, Value *locals, Value *ans, int *noncon
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* domod - evaluate the "%" operator */
|
||||
/* do_mod - evaluate the "%" operator */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int do_mod(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
@@ -1397,14 +1405,10 @@ static int logical_not(expr_node *node, Value *locals, Value *ans, int *nonconst
|
||||
|
||||
r = evaluate_expr_node(node->child, locals, &v1, nonconst);
|
||||
if (r != OK) return r;
|
||||
if (v1.type != INT_TYPE) {
|
||||
DBG(debug_evaluation_unop(ans, E_BAD_TYPE, &v1, "!"));
|
||||
DestroyValue(v1);
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
ans->type = INT_TYPE;
|
||||
ans->v.val = !(v1.v.val);
|
||||
ans->v.val = !truthy(&v1);
|
||||
DBG(debug_evaluation_unop(ans, OK, &v1, "!"));
|
||||
DestroyValue(v1);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1452,22 +1456,16 @@ static int logical_binop(expr_node *node, Value *locals, Value *ans, int *noncon
|
||||
/* Bail on error */
|
||||
if (r != OK) return r;
|
||||
|
||||
if (v.type == STR_TYPE) {
|
||||
DBG(debug_evaluation_binop(ans, E_BAD_TYPE, &v, NULL, opname));
|
||||
DestroyValue(v);
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
|
||||
if (is_and) {
|
||||
/* If first arg is false, return it */
|
||||
if (!v.v.val) {
|
||||
if (!truthy(&v)) {
|
||||
*ans = v;
|
||||
DBG(debug_evaluation_binop(ans, OK, &v, NULL, opname));
|
||||
return OK;
|
||||
}
|
||||
} else {
|
||||
/* If first arg is true, return it */
|
||||
if (v.v.val) {
|
||||
if (truthy(&v)) {
|
||||
*ans = v;
|
||||
DBG(debug_evaluation_binop(ans, OK, &v, NULL, opname));
|
||||
return OK;
|
||||
@@ -1476,12 +1474,8 @@ static int logical_binop(expr_node *node, Value *locals, Value *ans, int *noncon
|
||||
|
||||
/* Otherwise, evaluate and return second arg */
|
||||
r = evaluate_expr_node(node->child->sibling, locals, ans, nonconst);
|
||||
if (r == OK && ans->type == STR_TYPE) {
|
||||
DBG(debug_evaluation_binop(ans, E_BAD_TYPE, &v, ans, opname));
|
||||
DestroyValue(*ans);
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
DBG(debug_evaluation_binop(ans, r, &v, ans, opname));
|
||||
DestroyValue(v);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -2167,22 +2161,6 @@ static expr_node *parse_factor(char const **e, int *r, Var *locals, int level)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If the child is a constant int, optimize! */
|
||||
if (node->type == N_CONSTANT &&
|
||||
node->u.value.type == INT_TYPE) {
|
||||
if (op == '-') {
|
||||
if (node->u.value.v.val == INT_MIN) {
|
||||
*r = E_2LOW;
|
||||
return free_expr_tree(node);
|
||||
}
|
||||
node->u.value.v.val = -node->u.value.v.val;
|
||||
} else {
|
||||
node->u.value.v.val = !node->u.value.v.val;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Not a constant int; we need to add a node */
|
||||
factor_node = alloc_expr_node(r);
|
||||
if (!factor_node) {
|
||||
free_expr_tree(node);
|
||||
@@ -3076,3 +3054,17 @@ void print_expr_nodes_stats(void)
|
||||
fprintf(stderr, " Expression nodes leaked: %d\n", ExprNodesUsed);
|
||||
fprintf(stderr, " Parse level high-water: %d\n", parse_level_high_water);
|
||||
}
|
||||
|
||||
/* Return 1 if a value is "true" for its type, 0 if "false" */
|
||||
int truthy(Value const *v)
|
||||
{
|
||||
if (v->type == STR_TYPE) {
|
||||
if (v->v.str && *(v->v.str)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (v->v.val != 0);
|
||||
}
|
||||
|
||||
15
src/files.c
15
src/files.c
@@ -102,6 +102,13 @@ static int CheckSafetyAux (struct stat *statbuf);
|
||||
static int PopFile (void);
|
||||
static int IncludeCmd(char const *);
|
||||
|
||||
static void
|
||||
got_a_fresh_line(void)
|
||||
{
|
||||
FreshLine = 1;
|
||||
WarnedAboutImplicit = 0;
|
||||
}
|
||||
|
||||
void set_cloexec(FILE *fp)
|
||||
{
|
||||
int flags;
|
||||
@@ -182,7 +189,7 @@ int ReadLine(void)
|
||||
CurLine = CLine->text;
|
||||
LineNo = CLine->LineNo;
|
||||
CLine = CLine->next;
|
||||
FreshLine = 1;
|
||||
got_a_fresh_line();
|
||||
clear_callstack();
|
||||
if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
|
||||
return OK;
|
||||
@@ -283,7 +290,7 @@ static int ReadLineFromFile(int use_pclose)
|
||||
CurLine = DBufValue(&LineBuffer);
|
||||
}
|
||||
|
||||
FreshLine = 1;
|
||||
got_a_fresh_line();
|
||||
clear_callstack();
|
||||
if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
|
||||
return OK;
|
||||
@@ -849,7 +856,7 @@ static int IncludeCmd(char const *cmd)
|
||||
char const *fname;
|
||||
int old_flag;
|
||||
|
||||
FreshLine = 1;
|
||||
got_a_fresh_line();
|
||||
clear_callstack();
|
||||
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
@@ -968,7 +975,7 @@ int IncludeFile(char const *fname)
|
||||
int oldRunDisabled;
|
||||
struct stat statbuf;
|
||||
|
||||
FreshLine = 1;
|
||||
got_a_fresh_line();
|
||||
clear_callstack();
|
||||
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
54
src/funcs.c
54
src/funcs.c
@@ -231,7 +231,7 @@ BuiltinFunc Func[] = {
|
||||
{ "access", 2, 2, 0, FAccess, NULL },
|
||||
{ "adawn", 0, 1, 0, FADawn, NULL},
|
||||
{ "adusk", 0, 1, 0, FADusk, NULL},
|
||||
{ "ampm", 1, 3, 1, FAmpm, NULL },
|
||||
{ "ampm", 1, 4, 1, FAmpm, NULL },
|
||||
{ "ansicolor", 1, 5, 1, FAnsicolor, NULL },
|
||||
{ "args", 1, 1, 0, FArgs, NULL },
|
||||
{ "asc", 1, 1, 1, FAsc, NULL },
|
||||
@@ -945,6 +945,8 @@ static int FAmpm(func_info *info)
|
||||
char const *pm = "PM";
|
||||
char const *ampm = NULL;
|
||||
|
||||
int include_leading_zero = 0;
|
||||
|
||||
char outbuf[128];
|
||||
|
||||
if (ARG(0).type != DATETIME_TYPE && ARG(0).type != TIME_TYPE) {
|
||||
@@ -959,6 +961,10 @@ static int FAmpm(func_info *info)
|
||||
if (Nargs >= 3) {
|
||||
ASSERT_TYPE(2, STR_TYPE);
|
||||
pm = ARGSTR(2);
|
||||
if (Nargs >= 4) {
|
||||
ASSERT_TYPE(3, INT_TYPE);
|
||||
include_leading_zero = ARGV(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
h = TIMEPART(ARG(0)) / 60;
|
||||
@@ -973,9 +979,17 @@ static int FAmpm(func_info *info)
|
||||
}
|
||||
} else {
|
||||
if (ARG(0).type == DATETIME_TYPE) {
|
||||
snprintf(outbuf, sizeof(outbuf), "%04d%c%02d%c%02d%c%d%c%02d", yr, DateSep, mo+1, DateSep, da, DateTimeSep, h, TimeSep, m);
|
||||
if (include_leading_zero) {
|
||||
snprintf(outbuf, sizeof(outbuf), "%04d%c%02d%c%02d%c%02d%c%02d", yr, DateSep, mo+1, DateSep, da, DateTimeSep, h, TimeSep, m);
|
||||
} else {
|
||||
snprintf(outbuf, sizeof(outbuf), "%04d%c%02d%c%02d%c%d%c%02d", yr, DateSep, mo+1, DateSep, da, DateTimeSep, h, TimeSep, m);
|
||||
}
|
||||
} else {
|
||||
snprintf(outbuf, sizeof(outbuf), "%d%c%02d", h, TimeSep, m);
|
||||
if (include_leading_zero) {
|
||||
snprintf(outbuf, sizeof(outbuf), "%02d%c%02d", h, TimeSep, m);
|
||||
} else {
|
||||
snprintf(outbuf, sizeof(outbuf), "%d%c%02d", h, TimeSep, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
ampm = am;
|
||||
@@ -984,9 +998,17 @@ static int FAmpm(func_info *info)
|
||||
h -= 12;
|
||||
}
|
||||
if (ARG(0).type == DATETIME_TYPE) {
|
||||
snprintf(outbuf, sizeof(outbuf), "%04d%c%02d%c%02d%c%d%c%02d", yr, DateSep, mo+1, DateSep, da, DateTimeSep, h, TimeSep, m);
|
||||
if (include_leading_zero) {
|
||||
snprintf(outbuf, sizeof(outbuf), "%04d%c%02d%c%02d%c%02d%c%02d", yr, DateSep, mo+1, DateSep, da, DateTimeSep, h, TimeSep, m);
|
||||
} else {
|
||||
snprintf(outbuf, sizeof(outbuf), "%04d%c%02d%c%02d%c%d%c%02d", yr, DateSep, mo+1, DateSep, da, DateTimeSep, h, TimeSep, m);
|
||||
}
|
||||
} else {
|
||||
snprintf(outbuf, sizeof(outbuf), "%d%c%02d", h, TimeSep, m);
|
||||
if (include_leading_zero) {
|
||||
snprintf(outbuf, sizeof(outbuf), "%02d%c%02d", h, TimeSep, m);
|
||||
} else {
|
||||
snprintf(outbuf, sizeof(outbuf), "%d%c%02d", h, TimeSep, m);
|
||||
}
|
||||
}
|
||||
ampm = pm;
|
||||
}
|
||||
@@ -1262,6 +1284,7 @@ static int FChoose(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
PUT(ErrMsg[E_BAD_TYPE]);
|
||||
OUT();
|
||||
}
|
||||
Eprint("choose(): %s", ErrMsg[E_BAD_TYPE]);
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
n = v.v.val;
|
||||
@@ -1952,7 +1975,6 @@ static int FIndex(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FIif(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
{
|
||||
int istrue;
|
||||
int r;
|
||||
int done;
|
||||
Value v;
|
||||
@@ -1992,26 +2014,8 @@ static int FIif(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
done = 1;
|
||||
PUT(PrintValue(&v, NULL));
|
||||
}
|
||||
if (v.type != STR_TYPE && v.type != INT_TYPE) {
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
cur = cur->sibling;
|
||||
while(cur) {
|
||||
PUT(", ?");
|
||||
cur = cur->sibling;
|
||||
}
|
||||
PUT(") => ");
|
||||
PUT(ErrMsg[E_BAD_TYPE]);
|
||||
OUT();
|
||||
}
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
|
||||
if (v.type == INT_TYPE) {
|
||||
istrue = v.v.val;
|
||||
} else {
|
||||
istrue = *(v.v.str);
|
||||
}
|
||||
if (istrue) {
|
||||
if (truthy(&v)) {
|
||||
r = evaluate_expr_node(cur->sibling, locals, ans, nonconst);
|
||||
if (r == OK && (DebugFlag & DB_PRTEXPR)) {
|
||||
PUT(", ");
|
||||
|
||||
@@ -49,6 +49,7 @@ EXTERN int CurMon;
|
||||
EXTERN int CurYear;
|
||||
EXTERN int LineNo;
|
||||
EXTERN int FreshLine;
|
||||
EXTERN int WarnedAboutImplicit;
|
||||
EXTERN uid_t TrustedUsers[MAX_TRUSTED_USERS];
|
||||
|
||||
EXTERN INIT( int MaxLateMinutes, 0);
|
||||
|
||||
13
src/main.c
13
src/main.c
@@ -83,6 +83,8 @@ static void sigxcpu(int sig)
|
||||
int r = write(STDERR_FILENO, "\n\nmax-execution-time exceeded.\n\n", 32);
|
||||
|
||||
/* Pretend to use r to avoid compiler warning */
|
||||
/* cppcheck-suppress duplicateExpression */
|
||||
/* cppcheck-suppress knownArgument */
|
||||
_exit(1 + (r-r));
|
||||
}
|
||||
|
||||
@@ -351,9 +353,16 @@ static void DoReminders(void)
|
||||
break;
|
||||
|
||||
|
||||
/* If we don't recognize the command, do a REM by default */
|
||||
/* If we don't recognize the command, do a REM by default, but warn */
|
||||
|
||||
default: DestroyParser(&p); CreateParser(CurLine, &p); purge_handled = 1; r=DoRem(&p); break;
|
||||
default:
|
||||
Wprint("Unrecognized command; interpreting as REM");
|
||||
WarnedAboutImplicit = 1;
|
||||
DestroyParser(&p);
|
||||
CreateParser(CurLine, &p);
|
||||
purge_handled = 1;
|
||||
r=DoRem(&p);
|
||||
break;
|
||||
|
||||
}
|
||||
if (r && (!Hush || r != E_RUN_DISABLED)) {
|
||||
|
||||
@@ -61,6 +61,8 @@ expr_node *parse_expression(char const **e, int *r, Var *locals);
|
||||
|
||||
int evaluate_expression(expr_node *node, Value *locals, Value *ans, int *nonconst);
|
||||
int evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst);
|
||||
int truthy(Value const *v);
|
||||
|
||||
void print_expr_tree(expr_node *node, FILE *fp);
|
||||
void unlimit_execution_time(void);
|
||||
expr_node *free_expr_tree(expr_node *node);
|
||||
|
||||
@@ -317,5 +317,6 @@ typedef struct udf_struct {
|
||||
int nargs;
|
||||
char const *filename;
|
||||
int lineno;
|
||||
int recurse_flag;
|
||||
} UserFunc;
|
||||
|
||||
|
||||
@@ -129,6 +129,9 @@ int DoFset(ParsePtr p)
|
||||
/* We already have it! Our work here is done. */
|
||||
return OK;
|
||||
}
|
||||
/* Warn about redefinition */
|
||||
Wprint("Function %s redefined (previously defined at %s:%d)",
|
||||
existing->name, existing->filename, existing->lineno);
|
||||
}
|
||||
|
||||
/* Should be followed by '(' */
|
||||
@@ -157,6 +160,7 @@ int DoFset(ParsePtr p)
|
||||
return E_NO_MEM;
|
||||
}
|
||||
func->lineno = LineNo;
|
||||
func->recurse_flag = 0;
|
||||
StrnCpy(func->name, DBufValue(&buf), VAR_NAME_LEN);
|
||||
DBufFree(&buf);
|
||||
if (!Hush) {
|
||||
@@ -244,7 +248,7 @@ int DoFset(ParsePtr p)
|
||||
|
||||
/* Save the argument names */
|
||||
if (func->nargs) {
|
||||
func->args = calloc(sizeof(char *), func->nargs);
|
||||
func->args = calloc(func->nargs, sizeof(char *));
|
||||
for (i=0; i<func->nargs; i++) {
|
||||
func->args[i] = StrDup(local_array[i].name);
|
||||
if (!func->args[i]) {
|
||||
|
||||
@@ -2,5 +2,5 @@ FSET msgprefix(x) "Priority: " + x + "; Filename: " + filename() + ": "
|
||||
|
||||
REM at 23:56 MSG foo
|
||||
REM PRIORITY 42 at 23:57 MSG bar
|
||||
REM PRIORITY 999 at 23:58 MSQ quux
|
||||
REM PRIORITY 999 at 23:58 MSG quux
|
||||
DO queue2.rem
|
||||
|
||||
@@ -9,10 +9,10 @@ set $LatMin 24
|
||||
set $LatSec 0
|
||||
|
||||
IF $PSCAL
|
||||
[trigger(moondate(0))] SPECIAL MOON 0 -1 -1 [moontime(0)]
|
||||
[trigger(moondate(1))] SPECIAL MOON 1 -1 -1 [moontime(1)]
|
||||
[trigger(moondate(2))] SPECIAL MOON 2 -1 -1 [moontime(2)]
|
||||
[trigger(moondate(3))] SPECIAL MOON 3 -1 -1 [moontime(3)]
|
||||
REM [trigger(moondate(0))] SPECIAL MOON 0 -1 -1 [moontime(0)]
|
||||
REM [trigger(moondate(1))] SPECIAL MOON 1 -1 -1 [moontime(1)]
|
||||
REM [trigger(moondate(2))] SPECIAL MOON 2 -1 -1 [moontime(2)]
|
||||
REM [trigger(moondate(3))] SPECIAL MOON 3 -1 -1 [moontime(3)]
|
||||
ENDIF
|
||||
|
||||
REM 4 PS (First-Bit-Of-PS)
|
||||
|
||||
@@ -583,8 +583,20 @@ rm -f ../tests/once.timestamp
|
||||
tail +2 ../tests/once.timestamp >> ../tests/test.out 2>&1
|
||||
rm -f ../tests/once.timestamp
|
||||
|
||||
# Newlines in calendar output
|
||||
(echo 'REM 16 MSG foo%_bar%_baz wookie quux apple %_ %_ %_ blech'; echo "REM 16 MSG ANOTHER") | ../src/remind -c -w80 - 1 sep 2024 >> ../tests/test.out 2>&1
|
||||
|
||||
# Remove references to SysInclude, which is build-specific
|
||||
grep -F -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out
|
||||
|
||||
# If "man" accepts the --warnings flag, test all the man pages.
|
||||
man man | grep -e --warnings > /dev/null 2>&1
|
||||
if test $? = 0 ; then
|
||||
for i in ../man/*.1 ; do
|
||||
man --warnings=w $i 2>>../tests/test.out 1>/dev/null
|
||||
done
|
||||
fi
|
||||
|
||||
cmp -s ../tests/test.out ../tests/test.cmp
|
||||
if [ "$?" = "0" ]; then
|
||||
echo "Remind: Acceptance test PASSED"
|
||||
|
||||
1199
tests/test.cmp
1199
tests/test.cmp
File diff suppressed because one or more lines are too long
246
tests/test.rem
246
tests/test.rem
@@ -33,7 +33,7 @@ fset _h(x, y) trigger(hebdate(x,y))
|
||||
|
||||
# Test case from Remind mailing list
|
||||
set mltest "a b"
|
||||
INCLUDECMD printf 'REM %s\n' [mltest]
|
||||
INCLUDECMD printf 'REM MSG %s\n' [mltest]
|
||||
|
||||
# Disabling RUN in an !includecmd
|
||||
INCLUDECMD !echo MSG foo
|
||||
@@ -49,38 +49,38 @@ INCLUDECMD echo MSG foo
|
||||
RUN ON
|
||||
INCLUDECMD echo MSG foo
|
||||
|
||||
[_h(1, "Tishrey")] MSG Rosh Hashana 1
|
||||
[_h(2, "Tishrey")] MSG Rosh Hashana 2
|
||||
[_h(3, "Tishrey")] MSG Tzom Gedalia
|
||||
[_h(10, "Tishrey")] MSG Yom Kippur
|
||||
[_h(15, "Tishrey")] MSG Sukkot 1
|
||||
[_h(25, "Kislev")] MSG Channuka
|
||||
[_h(10, "Tevet")] MSG Asara B'Tevet
|
||||
[_h(15, "Shvat")] MSG Tu B'Shvat
|
||||
[_h(15, "Adar A")] MSG Purim Katan
|
||||
[_h(14, "Adar")] MSG Purim
|
||||
[_h(15, "Nisan")] MSG Pesach
|
||||
[_h(27, "Nisan")] MSG Yom HaShoah
|
||||
[_h(4, "Iyar")] MSG Yom HaZikaron
|
||||
[_h(5, "Iyar")] MSG Yom Ha'atzmaut
|
||||
[_h(28, "Iyar")] MSG Yom Yerushalayim
|
||||
[_h(6, "Sivan")] MSG Shavuot
|
||||
[_h(9, "Av")] MSG Tish'a B'Av
|
||||
REM [_h(1, "Tishrey")] MSG Rosh Hashana 1
|
||||
REM [_h(2, "Tishrey")] MSG Rosh Hashana 2
|
||||
REM [_h(3, "Tishrey")] MSG Tzom Gedalia
|
||||
REM [_h(10, "Tishrey")] MSG Yom Kippur
|
||||
REM [_h(15, "Tishrey")] MSG Sukkot 1
|
||||
REM [_h(25, "Kislev")] MSG Channuka
|
||||
REM [_h(10, "Tevet")] MSG Asara B'Tevet
|
||||
REM [_h(15, "Shvat")] MSG Tu B'Shvat
|
||||
REM [_h(15, "Adar A")] MSG Purim Katan
|
||||
REM [_h(14, "Adar")] MSG Purim
|
||||
REM [_h(15, "Nisan")] MSG Pesach
|
||||
REM [_h(27, "Nisan")] MSG Yom HaShoah
|
||||
REM [_h(4, "Iyar")] MSG Yom HaZikaron
|
||||
REM [_h(5, "Iyar")] MSG Yom Ha'atzmaut
|
||||
REM [_h(28, "Iyar")] MSG Yom Yerushalayim
|
||||
REM [_h(6, "Sivan")] MSG Shavuot
|
||||
REM [_h(9, "Av")] MSG Tish'a B'Av
|
||||
|
||||
# Test some jahrzeit cases
|
||||
fset _i(x,y,z,a) trigger(hebdate(x,y,z,a))
|
||||
[_i(30, "Heshvan", today(), 5759)] MSG Complete-Complete
|
||||
[_i(30, "Heshvan", today(), 5760)] MSG Complete-Defective
|
||||
[_i(30, "Heshvan", today(), 5761)] MSG Illegal
|
||||
REM [_i(30, "Heshvan", today(), 5759)] MSG Complete-Complete
|
||||
REM [_i(30, "Heshvan", today(), 5760)] MSG Complete-Defective
|
||||
REM [_i(30, "Heshvan", today(), 5761)] MSG Illegal
|
||||
|
||||
[_i(30, "Kislev", today(), 5759)] MSG Complete-Complete
|
||||
[_i(30, "Kislev", today(), 5760)] MSG Complete-Defective
|
||||
[_i(30, "Kislev", today(), 5761)] MSG Illegal
|
||||
REM [_i(30, "Kislev", today(), 5759)] MSG Complete-Complete
|
||||
REM [_i(30, "Kislev", today(), 5760)] MSG Complete-Defective
|
||||
REM [_i(30, "Kislev", today(), 5761)] MSG Illegal
|
||||
|
||||
[_i(30, "Adar A", today(), 5755)] MSG Leap
|
||||
[_i(30, "Adar A", today(), 5756)] MSG Illegal
|
||||
[_i(29, "Adar A", today(), 5755)] MSG Leap
|
||||
[_i(29, "Adar A", today(), 5756)] MSG Illegal
|
||||
REM [_i(30, "Adar A", today(), 5755)] MSG Leap
|
||||
REM [_i(30, "Adar A", today(), 5756)] MSG Illegal
|
||||
REM [_i(29, "Adar A", today(), 5755)] MSG Leap
|
||||
REM [_i(29, "Adar A", today(), 5756)] MSG Illegal
|
||||
|
||||
# This causes a parse error on version 03.01.01
|
||||
REM 1990-01-01 SATISFY 1
|
||||
@@ -238,8 +238,8 @@ CLEAR-OMIT-CONTEXT
|
||||
|
||||
REM tag ill,egal MSG bad tag
|
||||
REM MSG The tags are: [trigtags()]
|
||||
REM TAG foo The tags are: [trigtags()]
|
||||
REM TAG foo TAG bar TAG quux TAG znort TAG cabbage The tags are: [trigtags()]
|
||||
REM TAG foo MSG The tags are: [trigtags()]
|
||||
REM TAG foo TAG bar TAG quux TAG znort TAG cabbage MSG The tags are: [trigtags()]
|
||||
REM MSG The tags are: [trigtags()]
|
||||
|
||||
# Test ADDOMIT
|
||||
@@ -559,11 +559,11 @@ 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 1992-01-01 UNTIL 1991-12-31 MSG Diagnosed
|
||||
REM MON SCANFROM 1992-01-01 UNTIL 1991-12-31 MSG Diagnosed
|
||||
|
||||
REM MON FROM [x] UNTIL 1991-12-31 Not diagnosed
|
||||
REM MON SCANFROM [x] UNTIL 1991-12-31 Not diagnosed
|
||||
REM MON FROM [x] UNTIL 1991-12-31 MSG Not diagnosed
|
||||
REM MON SCANFROM [x] UNTIL 1991-12-31 MSG Not diagnosed
|
||||
|
||||
REM 1992-01-01 UNTIL 1992-02-02 MSG Diagnosed
|
||||
REM [x] UNTIL 1992-02-02 MSG Diagnosed
|
||||
@@ -575,7 +575,7 @@ OMIT December 25 MSG X
|
||||
OMIT 26 Dec 2010 THROUGH 27 Dec 2010 MSG This is not legal
|
||||
OMIT DUMP
|
||||
# Regression test for bugfix in Hebrew calendar Adar jahrzeit
|
||||
[_i(14, "Adar", today(), 5761)] MSG Purim
|
||||
REM [_i(14, "Adar", today(), 5761)] MSG Purim
|
||||
|
||||
# Regression test for bug found by Larry Hynes
|
||||
REM SATISFY [day(trigdate()-25) == 14] MSG Foo
|
||||
@@ -708,6 +708,56 @@ set x ampm(21:12) + ""
|
||||
set x ampm(22:12) + ""
|
||||
set x ampm(23:12) + ""
|
||||
|
||||
set x ampm(0:12,"AM", "PM", 1) + ""
|
||||
set x ampm(1:12,"AM", "PM", 1) + ""
|
||||
set x ampm(2:12,"AM", "PM", 1) + ""
|
||||
set x ampm(3:12,"AM", "PM", 1) + ""
|
||||
set x ampm(4:12,"AM", "PM", 1) + ""
|
||||
set x ampm(5:12,"AM", "PM", 1) + ""
|
||||
set x ampm(6:12,"AM", "PM", 1) + ""
|
||||
set x ampm(7:12,"AM", "PM", 1) + ""
|
||||
set x ampm(8:12,"AM", "PM", 1) + ""
|
||||
set x ampm(9:12,"AM", "PM", 1) + ""
|
||||
set x ampm(10:12,"AM", "PM", 1) + ""
|
||||
set x ampm(11:12,"AM", "PM", 1) + ""
|
||||
set x ampm(12:12,"AM", "PM", 1) + ""
|
||||
set x ampm(13:12,"AM", "PM", 1) + ""
|
||||
set x ampm(14:12,"AM", "PM", 1) + ""
|
||||
set x ampm(15:12,"AM", "PM", 1) + ""
|
||||
set x ampm(16:12,"AM", "PM", 1) + ""
|
||||
set x ampm(17:12,"AM", "PM", 1) + ""
|
||||
set x ampm(18:12,"AM", "PM", 1) + ""
|
||||
set x ampm(19:12,"AM", "PM", 1) + ""
|
||||
set x ampm(20:12,"AM", "PM", 1) + ""
|
||||
set x ampm(21:12,"AM", "PM", 1) + ""
|
||||
set x ampm(22:12,"AM", "PM", 1) + ""
|
||||
set x ampm(23:12,"AM", "PM", 1) + ""
|
||||
|
||||
set x ampm(0:02,"AM", "PM", 0) + ""
|
||||
set x ampm(0:02,"AM", "PM", 0) + ""
|
||||
set x ampm(2:02,"AM", "PM", 0) + ""
|
||||
set x ampm(3:02,"AM", "PM", 0) + ""
|
||||
set x ampm(4:02,"AM", "PM", 0) + ""
|
||||
set x ampm(5:02,"AM", "PM", 0) + ""
|
||||
set x ampm(6:02,"AM", "PM", 0) + ""
|
||||
set x ampm(7:02,"AM", "PM", 0) + ""
|
||||
set x ampm(8:02,"AM", "PM", 0) + ""
|
||||
set x ampm(9:02,"AM", "PM", 0) + ""
|
||||
set x ampm(00:02,"AM", "PM", 0) + ""
|
||||
set x ampm(00:02,"AM", "PM", 0) + ""
|
||||
set x ampm(02:02,"AM", "PM", 0) + ""
|
||||
set x ampm(03:02,"AM", "PM", 0) + ""
|
||||
set x ampm(04:02,"AM", "PM", 0) + ""
|
||||
set x ampm(05:02,"AM", "PM", 0) + ""
|
||||
set x ampm(06:02,"AM", "PM", 0) + ""
|
||||
set x ampm(07:02,"AM", "PM", 0) + ""
|
||||
set x ampm(08:02,"AM", "PM", 0) + ""
|
||||
set x ampm(09:02,"AM", "PM", 0) + ""
|
||||
set x ampm(20:02,"AM", "PM", 0) + ""
|
||||
set x ampm(20:02,"AM", "PM", 0) + ""
|
||||
set x ampm(22:02,"AM", "PM", 0) + ""
|
||||
set x ampm(23:02,"AM", "PM", 0) + ""
|
||||
|
||||
# Coerce with am/pm
|
||||
set x coerce("TIME", "12:45am")
|
||||
set x coerce("TIME", "12:45")
|
||||
@@ -777,7 +827,7 @@ ENDIF
|
||||
# Trig with a good warnfunc
|
||||
FSET w(x) choose(x, 5, 3, 1, 0)
|
||||
|
||||
Short-circuit operators
|
||||
# Short-circuit operators
|
||||
IF trig("sun warn w") || trig("thu warn w")
|
||||
REM [trig()] +5 MSG Foo %b
|
||||
ENDIF
|
||||
@@ -872,6 +922,16 @@ REM MSG Here: %{custom}
|
||||
REM MSG There: %*{custom}
|
||||
REM MSG Bad: %{custom
|
||||
|
||||
REM MSG Undefined: %{nopity_nope_nope}
|
||||
|
||||
# Bad substitution functions
|
||||
FSET subst_bad() "foo"
|
||||
REM MSG %{bad}
|
||||
|
||||
FSET subst_ampm(a, b, c, d, e, f, g) "wookie"
|
||||
|
||||
REM AT 11:00 MSG %2
|
||||
|
||||
# Test FUNSET
|
||||
FSET square(x) x*x
|
||||
SET a square(5)
|
||||
@@ -945,6 +1005,120 @@ REM Tue AT 10:00 DURATION [trigtime()] MSG blort
|
||||
# Make sure shellescape does not mangle UTF-8 characters
|
||||
msg [shellescape("😆")]
|
||||
|
||||
This should be diagnosed as implicitly being REM
|
||||
REM This should be diganosed as implicitly being MSG-type
|
||||
|
||||
# Check that user-defined functions with too many arguments are
|
||||
# correctly diagnosed.
|
||||
|
||||
# This should be OK
|
||||
FSET f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61, a62, a63) 3
|
||||
|
||||
# This should give an error
|
||||
FSET f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61, a62, a63, a64) 3
|
||||
|
||||
# Check that SATISFY expressions that don't reference trigdate are diagnosed
|
||||
|
||||
# These should all NOT be diagnosed
|
||||
set x 3
|
||||
REM SATISFY 1
|
||||
REM SATISFY trigdate() > '1990-01-01'
|
||||
REM AT 23:59 SATISFY trigdatetime() > '1990-01-01@12:00'
|
||||
REM SATISFY $T > '1990-01-01'
|
||||
REM SATISFY $Ty > 1990
|
||||
REM SATISFY $Tm > 0
|
||||
REM SATISFY $Td > 0
|
||||
REM SATISFY $Tw > -1
|
||||
REM SATISFY [max(x, max(x, 1, 2, 3), 4, 5, 6) * max(5, $Td)]
|
||||
|
||||
FSET references_t(x) $T != x
|
||||
REM SATISFY references_t($U)
|
||||
|
||||
FSET recursive_t(x) iif(x==0, recursive_t(1), references_t($U))
|
||||
|
||||
REM SATISFY recursive_t(0)
|
||||
REM SATISFY recursive_t(2)
|
||||
|
||||
# These should be diagnosed
|
||||
REM SATISFY 0
|
||||
REM SATSIFY ""
|
||||
REM SATISFY [version() > "01.00.00"]
|
||||
REM SATISFY [max(x, max(x, 1, 2, 3), 4, 5, 6) * 5]
|
||||
|
||||
FSET gg(x) 0
|
||||
REM WARN gg MSG Wookie
|
||||
REM AT 11:00 SCHED gg MSG blork
|
||||
REM OMITFUNC gg MSG hehe
|
||||
|
||||
FSET gg(x,y,z) 0
|
||||
REM WARN gg MSG Wookie
|
||||
REM AT 11:00 SCHED gg MSG blork
|
||||
REM OMITFUNC gg MSG hehe
|
||||
|
||||
FSET gg() 0
|
||||
REM WARN gg MSG Wookie
|
||||
REM AT 11:00 SCHED gg MSG blork
|
||||
REM OMITFUNC gg MSG hehe
|
||||
|
||||
FSET gg(x) x-x
|
||||
REM WARN gg MSG Wookie
|
||||
REM AT 11:00 SCHED gg MSG blork
|
||||
REM OMITFUNC gg MSG hehe
|
||||
|
||||
REM WARN not_defined MSG Wookie
|
||||
REM AT 11:00 SCHED not_defined MSG blork
|
||||
REM OMITFUNC not_defined MSG hehe
|
||||
|
||||
### Strings in logical operators
|
||||
SET logstr "" && 7
|
||||
SET logstr "foo" && 7
|
||||
SET logstr "" && ""
|
||||
SET logstr "foo" && ""
|
||||
SET logstr "" && "bar"
|
||||
SET logstr "foo" && "bar"
|
||||
SET logstr "" && '2023-02-01'
|
||||
SET logstr "foo" && '2023-02-01'
|
||||
|
||||
SET logstr "" || 7
|
||||
SET logstr "foo" || 7
|
||||
SET logstr "" || ""
|
||||
SET logstr "foo" || ""
|
||||
SET logstr "" || "bar"
|
||||
SET logstr "foo" || "bar"
|
||||
SET logstr "" || '2023-02-01'
|
||||
SET logstr "foo" || '2023-02-01'
|
||||
|
||||
set xyz ! 0
|
||||
set xyz ! 1
|
||||
set xyz ! 2
|
||||
|
||||
set xyz ! date(baseyr(), 1, 1)
|
||||
set xyz ! date(baseyr(), 1, 2)
|
||||
set xyz ! '2024-01-01'
|
||||
|
||||
set xyz ! datetime(baseyr(), 1, 1, 00:00)
|
||||
set xyz ! datetime(baseyr(), 1, 1, 00:01)
|
||||
set xyz ! datetime(baseyr(), 1, 2, 12:30)
|
||||
set xyz ! '2024-01-01@11:47'
|
||||
|
||||
set xyz ! 00:00
|
||||
set xyz ! 00:01
|
||||
set xyz ! 23:59
|
||||
|
||||
set xyz ! ""
|
||||
set xyz ! "foo"
|
||||
set xyz ! "0"
|
||||
|
||||
# Test error messages for function calls with too many / too few args
|
||||
|
||||
set zxk version(1)
|
||||
set zxk max()
|
||||
|
||||
fset dooby(x) 1
|
||||
set zxk dooby()
|
||||
set zxk dooby(1, 2)
|
||||
set zxk dooby(1)
|
||||
|
||||
# Don't want Remind to queue reminders
|
||||
EXIT
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
MSG ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский
|
||||
MSG עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית
|
||||
REM MSG ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский
|
||||
REM MSG עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית
|
||||
|
||||
Wed MSG With tabs and spaces
|
||||
REM Wed MSG With tabs and spaces
|
||||
|
||||
REM [moondate(0)] MSG 🌑
|
||||
REM [moondate(1)] MSG 🌓 woo
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[moondate(0)] SPECIAL MOON 0
|
||||
[moondate(1)] SPECIAL MOON 1
|
||||
[moondate(2)] SPECIAL MOON 2
|
||||
[moondate(3)] SPECIAL MOON 3
|
||||
REM [moondate(0)] SPECIAL MOON 0
|
||||
REM [moondate(1)] SPECIAL MOON 1
|
||||
REM [moondate(2)] SPECIAL MOON 2
|
||||
REM [moondate(3)] SPECIAL MOON 3
|
||||
REM Monday SPECIAL WEEK (W[weekno()])
|
||||
|
||||
@@ -9,8 +9,8 @@ IF !$PSCAL
|
||||
|
||||
FSET msgsuffix(x) "<P>"
|
||||
|
||||
MSG The Hebrew date for today, %d %m, %y, is [_hstr(today())]. %
|
||||
MSG And the Hebrew date for tomorrow is [_hstr(today()+1)]. %
|
||||
REM MSG The Hebrew date for today, %d %m, %y, is [_hstr(today())]. %
|
||||
REM MSG And the Hebrew date for tomorrow is [_hstr(today()+1)]. %
|
||||
|
||||
fset msgprefix(x) iif($NumTrig==OldTrig, "<H2>Upcoming Holidays</H2>"+char(13,10),"")
|
||||
set oldtrig $numtrig
|
||||
@@ -51,40 +51,40 @@ FSET _PastSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, \
|
||||
SET InIsrael VALUE("InIsrael", 0)
|
||||
SET Reform VALUE("Reform", 0)
|
||||
|
||||
[_h(1, "Tishrey")] ++12 MSG %"Rosh Hashana 1%" is %b.
|
||||
REM [_h(1, "Tishrey")] ++12 MSG %"Rosh Hashana 1%" is %b.
|
||||
|
||||
# No RH-2 or Tzom Gedalia in Reform
|
||||
IF !Reform
|
||||
[_h(2, "Tishrey")] ++12 MSG %"Rosh Hashana 2%" is %b.
|
||||
[_PastSat(3, "Tishrey")] ++12 MSG %"Tzom Gedalia%" is %b.
|
||||
REM [_h(2, "Tishrey")] ++12 MSG %"Rosh Hashana 2%" is %b.
|
||||
REM [_PastSat(3, "Tishrey")] ++12 MSG %"Tzom Gedalia%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(10, "Tishrey")] ++12 MSG %"Yom Kippur%" is %b.
|
||||
[_h(15, "Tishrey")] ++12 MSG %"Sukkot 1%" is %b.
|
||||
REM [_h(10, "Tishrey")] ++12 MSG %"Yom Kippur%" is %b.
|
||||
REM [_h(15, "Tishrey")] ++12 MSG %"Sukkot 1%" is %b.
|
||||
|
||||
IF !InIsrael
|
||||
[_h(16, "Tishrey")] MSG %"Sukkot 2%"
|
||||
REM [_h(16, "Tishrey")] MSG %"Sukkot 2%"
|
||||
ENDIF
|
||||
|
||||
[_h(21, "Tishrey")] ++12 MSG %"Hoshana Rabba%" is %b.
|
||||
[_h(22, "Tishrey")] ++12 MSG %"Shemini Atzeret%" is %b.
|
||||
REM [_h(21, "Tishrey")] ++12 MSG %"Hoshana Rabba%" is %b.
|
||||
REM [_h(22, "Tishrey")] ++12 MSG %"Shemini Atzeret%" is %b.
|
||||
|
||||
IF InIsrael
|
||||
[_h(22, "Tishrey")] ++12 MSG %"Simchat Torah%" is %b.
|
||||
REM [_h(22, "Tishrey")] ++12 MSG %"Simchat Torah%" is %b.
|
||||
ELSE
|
||||
[_h(23, "Tishrey")] ++12 MSG %"Simchat Torah%" is %b.
|
||||
REM [_h(23, "Tishrey")] ++12 MSG %"Simchat Torah%" is %b.
|
||||
ENDIF
|
||||
|
||||
# Because Kislev can change length, we must be more careful about Chanukah
|
||||
FSET _chan(x) TRIGGER(HEBDATE(24, "Kislev", today()-9)+x)
|
||||
[_chan(1)] ++12 MSG %"Chanukah 1%" is %b.
|
||||
[_chan(2)] MSG %"Chanukah 2%"
|
||||
[_chan(3)] MSG %"Chanukah 3%"
|
||||
[_chan(4)] MSG %"Chanukah 4%"
|
||||
[_chan(5)] MSG %"Chanukah 5%"
|
||||
[_chan(6)] MSG %"Chanukah 6%"
|
||||
[_chan(7)] MSG %"Chanukah 7%"
|
||||
[_chan(8)] MSG %"Chanukah 8%"
|
||||
REM [_chan(1)] ++12 MSG %"Chanukah 1%" is %b.
|
||||
REM [_chan(2)] MSG %"Chanukah 2%"
|
||||
REM [_chan(3)] MSG %"Chanukah 3%"
|
||||
REM [_chan(4)] MSG %"Chanukah 4%"
|
||||
REM [_chan(5)] MSG %"Chanukah 5%"
|
||||
REM [_chan(6)] MSG %"Chanukah 6%"
|
||||
REM [_chan(7)] MSG %"Chanukah 7%"
|
||||
REM [_chan(8)] MSG %"Chanukah 8%"
|
||||
|
||||
# Not sure about Reform's position on the next one.
|
||||
IF !Reform
|
||||
@@ -92,8 +92,8 @@ IF !Reform
|
||||
REM [_PastSat(10, "Tevet")] MSG %"Tzom Tevet%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(15, "Shvat")] ++12 MSG %"Tu B'Shvat%" is %b.
|
||||
[_h(15, "Adar A")] ++12 MSG %"Purim Katan%" is %b.
|
||||
REM [_h(15, "Shvat")] ++12 MSG %"Tu B'Shvat%" is %b.
|
||||
REM [_h(15, "Adar A")] ++12 MSG %"Purim Katan%" is %b.
|
||||
|
||||
# If Purim is on Sunday, then Fast of Esther is 11 Adar.
|
||||
IF WKDAYNUM(_h2(13, "Adar")) != 6
|
||||
@@ -101,41 +101,41 @@ IF WKDAYNUM(_h2(13, "Adar")) != 6
|
||||
ELSE
|
||||
REM [TRIGGER(_h2(11, "Adar"))] ++12 MSG %"Fast of Esther%" is %b.
|
||||
ENDIF
|
||||
[_h(14, "Adar")] ++12 MSG %"Purim%" is %b.
|
||||
[_h(15, "Nisan")] ++12 MSG %"Pesach%" is %b.
|
||||
REM [_h(14, "Adar")] ++12 MSG %"Purim%" is %b.
|
||||
REM [_h(15, "Nisan")] ++12 MSG %"Pesach%" is %b.
|
||||
|
||||
IF !InIsrael
|
||||
[_h(16, "Nisan")] MSG %"Pesach 2%" is %b.
|
||||
REM [_h(16, "Nisan")] MSG %"Pesach 2%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(21, "Nisan")] MSG %"Pesach 7%" is %b.
|
||||
REM [_h(21, "Nisan")] MSG %"Pesach 7%" is %b.
|
||||
|
||||
IF !InIsrael && !Reform
|
||||
[_h(22, "Nisan")] MSG %"Pesach 8%" is %b.
|
||||
REM [_h(22, "Nisan")] MSG %"Pesach 8%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(27, "Nisan")] ++12 MSG %"Yom HaShoah%" is %b.
|
||||
[_h(4, "Iyar")] ++12 MSG %"Yom HaZikaron%" is %b.
|
||||
[_h(5, "Iyar")] ++12 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
REM [_h(27, "Nisan")] ++12 MSG %"Yom HaShoah%" is %b.
|
||||
REM [_h(4, "Iyar")] ++12 MSG %"Yom HaZikaron%" is %b.
|
||||
REM [_h(5, "Iyar")] ++12 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
|
||||
# Not sure about Reform's position on Lag B'Omer
|
||||
IF !Reform
|
||||
[_h(18, "Iyar")] ++12 MSG %"Lag B'Omer%" is %b.
|
||||
REM [_h(18, "Iyar")] ++12 MSG %"Lag B'Omer%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(28, "Iyar")] ++12 MSG %"Yom Yerushalayim%" is %b.
|
||||
[_h(6, "Sivan")] ++12 MSG %"Shavuot%" is %b.
|
||||
REM [_h(28, "Iyar")] ++12 MSG %"Yom Yerushalayim%" is %b.
|
||||
REM [_h(6, "Sivan")] ++12 MSG %"Shavuot%" is %b.
|
||||
|
||||
IF !InIsrael && !Reform
|
||||
[_h(7, "Sivan")] MSG %"Shavuot 2%" is %b.
|
||||
REM [_h(7, "Sivan")] MSG %"Shavuot 2%" is %b.
|
||||
ENDIF
|
||||
|
||||
# Fairly sure Reform Jews don't observe the next two
|
||||
IF !Reform
|
||||
# Tzom Tamuz and Tish'a B'Av are moved to Sunday if they normally
|
||||
# fall on a Saturday
|
||||
[_PastSat(17, "Tamuz")] ++12 MSG %"Tzom Tammuz%" is %b.
|
||||
[_PastSat(9, "Av")] ++12 MSG %"Tish'a B'Av%" is %b.
|
||||
REM [_PastSat(17, "Tamuz")] ++12 MSG %"Tzom Tammuz%" is %b.
|
||||
REM [_PastSat(9, "Av")] ++12 MSG %"Tish'a B'Av%" is %b.
|
||||
ENDIF
|
||||
|
||||
fset msgprefix(x) ""
|
||||
|
||||
Reference in New Issue
Block a user