Compare commits

...

10 Commits

Author SHA1 Message Date
Dianne Skoll
1acb343cf3 Use UTC instead of Universal. Apparently, "Universal" is not...er... universally installed. 2025-10-09 11:41:15 -04:00
Dianne Skoll
b5b00468cc Update WHATSNEW. 2025-10-09 11:25:15 -04:00
Dianne Skoll
5042621073 Bump version to 06.01.05 2025-10-09 11:04:03 -04:00
Dianne Skoll
e2152b1e82 Add semi-exhaustive TZ tests. 2025-10-09 10:23:59 -04:00
Dianne Skoll
4adfc4b20e Clarify man page. 2025-10-09 09:30:49 -04:00
Dianne Skoll
6a4a1ab2d5 Add more TZ tests. 2025-10-08 23:17:10 -04:00
Dianne Skoll
a19b79951e Fix more TZ bugs; warn if TZ name looks suspicious. 2025-10-08 23:07:37 -04:00
Dianne Skoll
21f5462657 On systems that have /usr/share/zoneinfo (Linux and FreeBSD, for example) attempt to validate TZ time zone names. 2025-10-08 22:05:49 -04:00
Dianne Skoll
b3f03e3e0c Fix a few problems found by spellintian. 2025-10-08 13:16:41 -04:00
Dianne Skoll
593d367eaa Fix spelling errors. 2025-10-08 12:45:00 -04:00
14 changed files with 2820 additions and 27 deletions

18
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.72 for remind 06.01.04.
# Generated by GNU Autoconf 2.72 for remind 06.01.05.
#
#
# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation,
@@ -601,8 +601,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='remind'
PACKAGE_TARNAME='remind'
PACKAGE_VERSION='06.01.04'
PACKAGE_STRING='remind 06.01.04'
PACKAGE_VERSION='06.01.05'
PACKAGE_STRING='remind 06.01.05'
PACKAGE_BUGREPORT=''
PACKAGE_URL='https://dianne.skoll.ca/projects/remind/'
@@ -1258,7 +1258,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 06.01.04 to adapt to many kinds of systems.
'configure' configures remind 06.01.05 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1320,7 +1320,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of remind 06.01.04:";;
short | recursive ) echo "Configuration of remind 06.01.05:";;
esac
cat <<\_ACEOF
@@ -1408,7 +1408,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
remind configure 06.01.04
remind configure 06.01.05
generated by GNU Autoconf 2.72
Copyright (C) 2023 Free Software Foundation, Inc.
@@ -1871,7 +1871,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 06.01.04, which was
It was created by remind $as_me 06.01.05, which was
generated by GNU Autoconf 2.72. Invocation command line was
$ $0$ac_configure_args_raw
@@ -4848,7 +4848,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 06.01.04, which was
This file was extended by remind $as_me 06.01.05, which was
generated by GNU Autoconf 2.72. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -4913,7 +4913,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 06.01.04
remind config.status 06.01.05
configured by $0, generated by GNU Autoconf 2.72,
with options \\"\$ac_cs_config\\"

View File

@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(remind, 06.01.04, , , https://dianne.skoll.ca/projects/remind/)
AC_INIT(remind, 06.01.05, , , https://dianne.skoll.ca/projects/remind/)
AC_CONFIG_SRCDIR([src/queue.c])
cat <<'EOF'

View File

@@ -1,5 +1,18 @@
CHANGES TO REMIND
* VERSION 6.1 Patch 5 - 2025-10-09
- BUG FIX: remind: Yet another bug in TZ handling was fixed. I hope this
is the final TZ bug; the test suite has had a large number of TZ tests
added.
- IMPROVEMENT: remind: If the directory /usr/share/zoneinfo exists, Remind
warns about time zone names that look invalid. You can override the
warning by prefixing your time zone name with "!" if you want to use
non-file-based time zone names like "UTC+0400".
- MINOR IMPROVEMENTS: A couple of man page typos were fixed.
* VERSION 6.1 Patch 4 - 2025-10-08
- BUG FIX: remind: In calendar mode, reminders that specify a TZ zone

View File

@@ -160,7 +160,7 @@ Helvetica-BoldOblique.
.RE
.TP
\fB\-s\fR[\fBthed\fR] \fIsize\fR
Set the size (in points) of the text for the the calendar title,
Set the size (in points) of the text for the calendar title,
day-of-week headings, the calendar entries, and the day numbers,
respectively. \fISize\fR must be a decimal number. The default sizes
are equivalent to specifying:
@@ -205,7 +205,7 @@ illustrated with examples:
.fi
.PP
That example creates a blank calendar for the entire year of 1994, and
sends it the the printer named "laser."
sends it to the printer named "laser."
.PP
.nf
remind \-p ~/.reminders | rem2ps \-l \-sd 18 > cal.ps
@@ -581,7 +581,7 @@ If an AT clause was present, this key contains the event start time in
the format \fIYYYY-MM-DD\fRT\fIHH:MM\fR in the \fIsystem default time zone\fR.
.TP
.B eventstart_in_tz \fIdt\fR
If a TZ clause was present, this key containes the event start time in
If a TZ clause was present, this key contains the event start time in
the format \fIYYYY-MM-DD\fRT\fIHH:MM\fR in the \fItime zone specified
by TZ\fR.
.TP

View File

@@ -2264,9 +2264,20 @@ adjusted to Thursday, 14 May 2026 at 06:59 UTC because of the
time zone adjustment.
.PP
If you use an invalid time zone name after the \fBTZ\fR keyword,
results are undefined. Unfortunately, \fBRemind\fR cannot diagnose
this error becase the C library \fBtzset()\fR function has no
error return.
results are undefined. As mentioned previously, time zone names
\fIare\fR case-sensitive; America/Toronto is valid, but
america/toronto is not.
.PP
If you are on a system that stores time zone data in
/usr/share/zoneinfo, then \fBRemind\fR will attempt to validate the
time zone name and will warn you if it appears to be invalid. If you
want to specify a time zone that lacks a file under
/usr/share/zoneinfo anyway, and want to suppress the warning, prefix
the time zone name with "!". For example:
.PP
.nf
REM Thursday AT 14:45 TZ !EST+5EDT,M3.2.0/2,M11.1.0/2 MSG Old TZ format
.fi
.PP
In a reminder with the \fBTZ\fR keyword, OMIT dates are evaluated in
the specified time zone. Here's an example: Suppose the local time zone

View File

@@ -110,7 +110,7 @@ The seventh control specifies what \fBRemind\fR should do if a reminder
falls on a holiday or weekend.
Enter the body of the reminder into the \fBSummary:\fR text entry. If
you want, you can enter a location, a URL, and and longer description
you want, you can enter a location, a URL, and a longer description
in the \fBLocation:\fR, \fBURL:\fR and \fBDescription:\fR boxes. If
you enter anything here, they will be added as \fBINFO\fR items to the
reminder.

View File

@@ -143,6 +143,7 @@ void EnterTimezone(char const *tz)
CurYear = tm.tm_year + 1900;
DSEToday = DSE(CurYear, CurMon, CurDay);
/* Adjust DSEToday back by a day if midnight in our time zone requires it */
if (SysTime < LocalSysTime) {
DSEToday--;
@@ -1264,6 +1265,20 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
check_trigger_function(trig->warn, "WARN");
check_trigger_function(trig->omitfunc, "OMITFUNC");
}
/* Check that TZ looks plausible */
if (trig->tz && (*trig->tz != '!')) {
warn_if_timezone_bad(trig->tz);
}
/* Remove leading ! from TZ spec */
if (trig->tz && *trig->tz == '!') {
char *s = (char *) trig->tz;
while (*s) {
*s = *(s+1);
s++;
}
}
return OK;
}

View File

@@ -304,3 +304,5 @@ int AdjustTriggerForTimeZone(Trigger *trig, int dse, TimeTrig *tim);
void EnterTimezone(char const *tz);
void ExitTimezone(char const *tz);
int warning_level(char const *which);
void warn_if_timezone_bad(char const *tz);

View File

@@ -621,11 +621,15 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig const *tim
if (trig->tz) {
TimeTrig copy = *tim;
int new_result;
int force_retry = 0;
ExitTimezone(trig->tz);
new_result = AdjustTriggerForTimeZone(trig, result, &copy);
if (trig->scanfrom == NO_SCANFROM && new_result < DSEToday) {
force_retry = 1;
}
EnterTimezone(trig->tz);
if (result + duration_days >= today &&
new_result + duration_days < today) {
if (force_retry ||
(result + duration_days >= today &&new_result + duration_days < today)) {
/* If we are not making progress, then give up: It's expired */
if (nextstart <= save_nextstart) {
trig->expired = 1;

View File

@@ -28,10 +28,31 @@ static char const DontEscapeMe[] =
#include <ctype.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "types.h"
#include "globals.h"
#include "protos.h"
static int HaveZoneinfoDir = -1;
#define ZONE_DIR "/usr/share/zoneinfo"
static int have_zoneinfo_dir(void)
{
struct stat sb;
if (HaveZoneinfoDir < 0) {
if (stat(ZONE_DIR, &sb) < 0) {
HaveZoneinfoDir = 0;
} else if ((sb.st_mode & S_IFMT) != S_IFDIR) {
HaveZoneinfoDir = 0;
} else {
HaveZoneinfoDir = 1;
}
}
return HaveZoneinfoDir;
}
/* Call this instead of system() so if called ignores return code,
we don't get a compiler warning. Also redirect stdin to /dev/null */
int system1(char const *cmd)
@@ -378,3 +399,34 @@ warning_level(char const *which)
if (!WarningLevel) return 1;
return strcmp(WarningLevel, which) >= 0;
}
void
warn_if_timezone_bad(char const *tz)
{
DynamicBuffer zfile;
struct stat sb;
int r;
if (!tz) {
return;
}
if (*tz == '!') {
return;
}
if (!have_zoneinfo_dir()) {
return;
}
DBufInit(&zfile);
DBufPuts(&zfile, ZONE_DIR);
DBufPuts(&zfile, "/");
DBufPuts(&zfile, tz);
r = stat(DBufValue(&zfile), &sb);
DBufFree(&zfile);
if (r < 0) {
if (warning_level("06.01.05")) {
Wprint(tr("No time zone file found for TZ `%s'... is it valid?"),
tz);
}
}
}

View File

@@ -31,7 +31,7 @@ REMIND="../src/remind --flush -q"
OUT="../tests/test.out"
CMP="../tests/test.cmp"
# Set a known timezone so moon phases show up in predictable places
TZ=Universal
TZ=UTC
export TZ
# Colorize output iff stdout is a tty

View File

@@ -1,4 +1,7 @@
#!/bin/sh
export LC_ALL=C.UTF-8
export LANG=C.UTF-8
DIR=`dirname $0`
cd $DIR
if test $? != 0 ; then
@@ -143,9 +146,9 @@ TZ=America/Los_Angeles $REMIND - 2026-01-01 <<'EOF' >> $OUT 2>&1
BANNER %
SET $AddBlankLines 0
REM AT 13:33 TZ America/Los_Angeles TZ Universal MSG Whatsup? %*l %3.
REM AT 13:33 TZ America/Los_Angeles TZ UTC MSG Whatsup? %*l %3.
REM AT 13:33 TZ "" TZ America/Los_Angeles MSG Whatsup? %*l %3.
REM TZ Universal MSG Borked
REM TZ UTC MSG Borked
EOF
TZ=America/Toronto $REMIND -dx - 2025-09-01@01:00 <<'EOF' >> $OUT 2>&1
@@ -190,6 +193,68 @@ TZ=America/Toronto $REMIND -s - 2025-10-01 <<'EOF' >> $OUT 2>&1
REM Wednesday AT 14:00 TZ Australia/Sydney MSG 2PM Sydney
EOF
echo "" >> $OUT
# Every day and a SATISFY reminder
TZ=America/Toronto $REMIND -s - 2025-10-01 <<'EOF' >> $OUT 2>&1
REM AT 04:44 TZ America/Los_Angeles MSG 04:44 every day in L.A.
REM 2 AT 05:00 TZ America/Los_Angeles MSG 05:00 on 2nd in L.A.
REM Wed AT 06:00 TZ America/Los_Angeles MSG 06:00 on Wed in L.A.
REM Wed AT 23:00 TZ America/Los_Angeles MSG 23:00 on Wed in L.A.
REM AT 09:00 TZ America/Los_Angeles SATISFY [!($Td % 3)] MSG 09:00 every third day in L.A.
REM AT 22:00 TZ America/Los_Angeles SATISFY [!($Td % 3)] MSG 22:00 every third day in L.A.
EOF
echo "" >> $OUT
# And the inverse
TZ=America/Los_Angeles $REMIND -s - 2025-10-01 <<'EOF' >> $OUT 2>&1
REM AT 04:44 TZ America/Toronto MSG 04:44 every day in T.O.
REM 2 AT 05:00 TZ America/Toronto MSG 05:00 on 2nd in T.O.
REM Wed AT 06:00 TZ America/Toronto MSG 06:00 on Wed in T.O.
REM Wed AT 01:00 TZ America/Toronto MSG 01:00 on Wed in T.O.
REM AT 09:00 TZ America/Toronto SATISFY [!($Td % 3)] MSG 09:00 every third day in T.O.
REM AT 02:00 TZ America/Toronto SATISFY [!($Td % 3)] MSG 02:00 every third day in T.O.
EOF
# Semi-exhaustive checking...
OFFSETS="-12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12"
cat <<'EOF' >> $OUT
NOTE NOTE NOTE: The notation UTC+n denotes a time zone n hours
WEST of UTC, and UTC-n denotes a time zone n hours EAST of
UTC... the opposite of what you might think. The zone
UTC+1 is two hours EARLIER than UTC-1.
EOF
for src in $OFFSETS; do
srczone="UTC$src"
for dst in $OFFSETS ; do
dstzone="UTC$dst"
(echo 'BANNER %'; echo "REM AT 00:00 TZ !$dstzone MSG 00:00 at $dstzone in [getenv(\"TZ\")] is %3, %r %m; diff=[(\$Tt-00:00)/60]") | TZ=$srczone $REMIND '-i$addblanklines=0' - 2025-10-09@12:00 >> $OUT 2>&1
done
done
for src in $OFFSETS; do
srczone="UTC$src"
for dst in $OFFSETS ; do
dstzone="UTC$dst"
(echo 'BANNER %'; echo "REM AT 12:00 TZ !$dstzone MSG 12:00 at $dstzone in [getenv(\"TZ\")] is %3, %r %m; diff=[(\$Tt-12:00)/60]") | TZ=$srczone $REMIND '-i$addblanklines=0' - 2025-10-09@12:00 >> $OUT 2>&1
done
done
for src in $OFFSETS; do
srczone="UTC$src"
for dst in $OFFSETS ; do
dstzone="UTC$dst"
(echo 'BANNER %'; echo "REM 11 ++10 AT 00:00 TZ !$dstzone MSG 00:00 on 11th at $dstzone in [getenv(\"TZ\")] is %3, %r %m; diff=[(trigdatetime()-'2025-10-11@00:00')/60]") | TZ=$srczone $REMIND '-i$addblanklines=0' - 2025-10-09@12:00 >> $OUT 2>&1
done
done
for src in $OFFSETS; do
srczone="UTC$src"
for dst in $OFFSETS ; do
dstzone="UTC$dst"
(echo 'BANNER %'; echo "REM 11 ++10 AT 12:00 TZ !$dstzone MSG 12:00 on 11th at $dstzone in [getenv(\"TZ\")] is %3, %r %m; diff=[(trigdatetime()-'2025-10-11@12:00')/60]") | TZ=$srczone $REMIND '-i$addblanklines=0' - 2025-10-09@12:00 >> $OUT 2>&1
done
done
cmp -s $OUT $CMP
if [ "$?" = "0" ] ; then
echo "Remind: Time zone tests ${GRN}PASSED${NRM}"

View File

@@ -1046,7 +1046,7 @@ set a057 value("a05"+"6")
"a05" + "6" => "a056"
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
set a058 version()
version() => "06.01.04"
version() => "06.01.05"
set a059 wkday(today())
today() => 1991-02-16
wkday(1991-02-16) => "Saturday"
@@ -2609,7 +2609,7 @@ a056 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
a007 "1991-02-16"
a057 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
a008 "11:44"
a058 "06.01.04"
a058 "06.01.05"
a059 "Saturday"
a010 12
a060 6
@@ -5562,8 +5562,8 @@ REM SATISFY ""
REM SATISFY [version() > "01.00.00"]
../tests/test.rem(1074): SATISFY: expression has no reference to trigdate() or $T...
../tests/test.rem(1074): Trig = Saturday, 16 February, 1991
version() => "06.01.04"
"06.01.04" > "01.00.00" => 1
version() => "06.01.05"
"06.01.05" > "01.00.00" => 1
../tests/test.rem(1074): Trig(satisfied) = Saturday, 16 February, 1991
REM SATISFY [max(x, max(x, 1, 2, 3), 4, 5, 6) * 5]
../tests/test.rem(1075): SATISFY: expression has no reference to trigdate() or $T...
@@ -23707,7 +23707,7 @@ SECURITY: Won't read world-writable file or directory!
Error reading include_dir/ww: Can't open file
SECURITY: Won't read world-writable file or directory!
Error reading include_dir/ww: No files matching *.rem
06.01.04
06.01.05
Enabling test mode: This is meant for the acceptance test.
Do not use --test in production.
In test mode, the system time is fixed at 2025-01-06@19:00
@@ -25088,6 +25088,7 @@ TRANSLATE "Invalid translation: Both original and translated must have the same
TRANSLATE "Missing REM type; assuming MSG" ""
TRANSLATE "No Adar A in %d" ""
TRANSLATE "No substition function `%s' defined" ""
TRANSLATE "No time zone file found for TZ `%s'... is it valid?" ""
TRANSLATE "Non-constant built-in function `%s' makes expression non-constant" ""
TRANSLATE "Non-constant expression converted to constant by `const' built-in function" ""
TRANSLATE "Nonexistence of global variable `%s' makes value() non-constant" ""

File diff suppressed because it is too large Load Diff