mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
36 Commits
03.03.00
...
03.03.01-B
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85f96e2e01 | ||
|
|
47331cd919 | ||
|
|
d9f18ed6a7 | ||
|
|
efa4816371 | ||
|
|
2dc8c63adb | ||
|
|
c3c1781021 | ||
|
|
cd39480a98 | ||
|
|
281a1a206e | ||
|
|
cbff2a7bf2 | ||
|
|
2a08be8fd0 | ||
|
|
0826678209 | ||
|
|
f2e421bfa5 | ||
|
|
ce53a9b91a | ||
|
|
b166b1cf82 | ||
|
|
d09fbb03b2 | ||
|
|
7a835f3b10 | ||
|
|
6b991cdf9c | ||
|
|
018e9d0323 | ||
|
|
f499ae096f | ||
|
|
725e046a15 | ||
|
|
275b1f62b6 | ||
|
|
6e58dea198 | ||
|
|
ad4e62c8c3 | ||
|
|
a5768d55d8 | ||
|
|
7db49971c8 | ||
|
|
45ca6631ac | ||
|
|
d51944f36c | ||
|
|
037c79fb0f | ||
|
|
993373414f | ||
|
|
38a0a9992a | ||
|
|
a82bbe3776 | ||
|
|
a32ba217ba | ||
|
|
d322cf54ac | ||
|
|
b1d07a231d | ||
|
|
97851a08e6 | ||
|
|
8547b30a8f |
@@ -3,7 +3,7 @@ THE REMIND COPYRIGHT
|
||||
1. REMIND refers to the entire set of files and documentation in the
|
||||
REMIND package.
|
||||
|
||||
2. REMIND is Copyright 1992-2018 Dianne Skoll, except where noted in
|
||||
2. REMIND is Copyright 1992-2020 Dianne Skoll, except where noted in
|
||||
individual files.
|
||||
|
||||
3. DISTRIBUTION AND USE
|
||||
|
||||
2
configure
vendored
2
configure
vendored
@@ -3991,7 +3991,7 @@ _ACEOF
|
||||
fi
|
||||
done
|
||||
|
||||
VERSION=03.03.00
|
||||
VERSION=03.03.01
|
||||
|
||||
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h"
|
||||
|
||||
|
||||
@@ -75,6 +75,6 @@ if test "$GCC" = yes; then
|
||||
fi
|
||||
|
||||
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale)
|
||||
VERSION=03.03.00
|
||||
VERSION=03.03.01
|
||||
AC_SUBST(VERSION)
|
||||
AC_OUTPUT(src/Makefile www/Makefile src/version.h)
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 3.3 Patch 1 - 2020-XX-XX
|
||||
|
||||
- CHANGE: For overlapping multi-day events, issue a reminder for the
|
||||
most *recent* event rather than the earliest event. NOTE INCOMPATIBILITY:
|
||||
This is a behavior change!
|
||||
|
||||
- CHANGE: Do not convert 90-99 to 1990-1999 when parsing numbers to recognize
|
||||
years. NOTE INCOMPATIBILITY: This is a behavior change!
|
||||
|
||||
- CHANGE: Revert change to -y option that included filename and line number
|
||||
in the hash.
|
||||
|
||||
- CHANGE: Retain newlines (produced by %_) in JSON output.
|
||||
|
||||
- FIX: Document $FormWidth system variable
|
||||
|
||||
- FIX: Highlight today's date in "remind -c" output
|
||||
|
||||
- IMPROVEMENT: Allow times to be specified either in 24-hour mode
|
||||
(HH:MM or HH.MM) or AM/PM mode (HH:MMam; HH:MMpm, etc.)
|
||||
|
||||
- IMPROVEMENT: Allow DURATION to be specified as a time (1:30) or a
|
||||
number of minutes (90).
|
||||
|
||||
- IMPROVEMENT: If terminal size can be determined, set $FormWidth to
|
||||
terminal width - 8; if not, set $FormWidth to 72.
|
||||
|
||||
- MINOR IMPROVEMENT: Add the "ampm()" built-in function.
|
||||
|
||||
* Version 3.3 Patch 0 - 2020-01-31
|
||||
|
||||
- FIX: rem2ps: Add a %%PageBoundingBox: document structuring convention
|
||||
|
||||
103
man/remind.1
103
man/remind.1
@@ -334,14 +334,15 @@ If you supply a \fIdate\fR on the command line, it must consist of
|
||||
of the month, and \fIyear\fR is a year (all 4 digits) from 1990 to
|
||||
about 2075. You can leave out the \fIday\fR, which then defaults to 1.
|
||||
.PP
|
||||
If you do supply a \fIdate\fR on the command line, then \fBRemind\fR uses
|
||||
it, rather than the actual system date, as its notion of "today."
|
||||
This lets you create calendars for future months, or test to see
|
||||
how your reminders will be triggered in the future. Similarly,
|
||||
you can supply a \fItime\fR (in 24-hour format -- for example, 17:15) to
|
||||
set \fBRemind\fR's notion of "now" to a particular time. Supplying
|
||||
a \fItime\fR on the command line also implicitly enables the \fB\-q\fR
|
||||
option and disables the \fB\-z\fR option.
|
||||
If you do supply a \fIdate\fR on the command line, then \fBRemind\fR
|
||||
uses it, rather than the actual system date, as its notion of "today."
|
||||
This lets you create calendars for future months, or test to see how
|
||||
your reminders will be triggered in the future. Similarly, you can
|
||||
supply a \fItime\fR to set \fBRemind\fR's notion of "now" to a
|
||||
particular time. Supplying a \fItime\fR on the command line also
|
||||
implicitly enables the \fB\-q\fR option and disables the \fB\-z\fR
|
||||
option. The \fItime\fR may be specified in 24-hour format (eg, 13:20)
|
||||
or common "AM/PM" format (1:20pm).
|
||||
.PP
|
||||
If you would rather specify the date more succinctly, you can supply
|
||||
it as YYYY-MM-DD or YYYY/MM/DD. You can even supply a date and
|
||||
@@ -517,7 +518,7 @@ characters must be used. The following are examples of the various parts of a
|
||||
JANUARY, feb, March, ApR, may, Aug
|
||||
.TP
|
||||
.I year:
|
||||
1990, 1993, 2030, 95 (interpreted as 1995). The year can range
|
||||
1990, 1993, 2030. The year can range
|
||||
from 1990 to 2075.
|
||||
.TP
|
||||
.I weekday:
|
||||
@@ -967,8 +968,13 @@ it terminates the search after the \fBSATISFY\fR iteration limit
|
||||
.PP
|
||||
Timed reminders are those that have an \fBAT\fR keyword followed
|
||||
by a \fItime\fR and optional \fItdelta\fR and \fItrepeat\fR. The \fItime\fR
|
||||
must be specified in 24-hour format, with 0:00 representing midnight,
|
||||
mau be specified in 24-hour format, with 0:00 representing midnight,
|
||||
12:00 representing noon, and 23:59 representing one minute to midnight.
|
||||
Alternatively, it may be specified in common "AM/PM" format; in this case,
|
||||
the hour must range from 1 to 12. 12:00am represents midnight, 12:00pm
|
||||
represents noon, and 11:59pm represents one minute to midnight. The "am"
|
||||
and "pm" portions are case-insensitive and the "m" is optional.
|
||||
.PP
|
||||
You can use either a colon or a period to separate the hours from the
|
||||
minutes. That is, 13:39 and 13.39 are equivalent.
|
||||
.PP
|
||||
@@ -995,7 +1001,7 @@ The following reminder will be triggered on Thursdays and Fridays,
|
||||
but will only be queued on Fridays:
|
||||
.PP
|
||||
.nf
|
||||
REM Fri ++1 AT 13:00 MSG Lunch at 1pm Friday.
|
||||
REM Fri ++1 AT 1:00PM MSG Lunch at 1pm Friday.
|
||||
.fi
|
||||
.PP
|
||||
The \fItdelta\fR and \fItrepeat\fR have the same form as a \fIrepeat\fR
|
||||
@@ -1077,15 +1083,21 @@ to each distinct REM command.
|
||||
.PP
|
||||
The \fBDURATION\fR keyword makes sense only for timed reminders; it
|
||||
specifies the duration of an event. For example, if you have a
|
||||
90-minute meeting starting at 1:00pm, you could use:
|
||||
90-minute meeting starting at 1:00pm, you could use any of the following:
|
||||
.PP
|
||||
.nf
|
||||
REM 5 March 1999 AT 13:00 DURATION 1:30 MSG Meeting
|
||||
REM 5 March 2021 AT 13:00 DURATION 1:30 MSG Meeting
|
||||
REM 5 March 2021 AT 13:00 DURATION 90 MSG Meeting
|
||||
REM 5 March 2021 AT 1:00pm DURATION 1:30 MSG Meeting
|
||||
REM 5 March 2021 AT 1:00pm DURATION 90 MSG Meeting
|
||||
.fi
|
||||
.PP
|
||||
Note that \fIduration\fR is specified in hours and minutes. If you
|
||||
specify a duration of 00:00, then \fBRemind\fR behaves exactly as if
|
||||
no \fBDURATION\fR at all had been present.
|
||||
|
||||
Note that \fIduration\fR is specified either in hours and minutes as a
|
||||
\fItime\fR, or in minutes as an \fIinteger\fR. If you specify a
|
||||
duration of 00:00 or 0, then \fBRemind\fR behaves exactly as if no
|
||||
\fBDURATION\fR at all had been present.
|
||||
|
||||
.PP
|
||||
.SH THE SUBSTITUTION FILTER
|
||||
.PP
|
||||
@@ -1665,13 +1677,15 @@ in C.
|
||||
.RE
|
||||
.TP
|
||||
.B TIME constants
|
||||
12:33, 0:01, 14:15, 16:42, 12.16, 13.00, 1.11
|
||||
12:33, 0:01, 14:15, 16:42, 12.16, 13.00, 1.11, 4:30PM, 12:20am
|
||||
.PP
|
||||
.RS
|
||||
Note that \fBTIME\fR constants are written in 24-hour format. Either the
|
||||
period or colon can be used to separate the minutes from the hours.
|
||||
However, Remind will consistently output times using only one separator
|
||||
character. (The output separator character is chosen at compile-time.)
|
||||
Note that \fBTIME\fR constants may be written in 24-hour format or in
|
||||
common "AM/PM" format. If you use "AM/PM" format, then the hour can
|
||||
range from 1 to 12. Either a period or colon can be used to separate
|
||||
the minutes from the hours. However, Remind will consistently output
|
||||
times in 24-hour format using only one separator character. (The
|
||||
output separator character is chosen at compile-time.)
|
||||
.RE
|
||||
.TP
|
||||
.B DATE constants
|
||||
@@ -1694,11 +1708,12 @@ versions prior to 03.00.02 did not support the '-' date separator.
|
||||
.RE
|
||||
.TP
|
||||
.B DATETIME constants
|
||||
\fBDATETIME\fR constants are expressed similarly to \fBDATE\fR constants
|
||||
with the addition of an "@HH:MM" part. For example:
|
||||
\fBDATETIME\fR constants are expressed similarly to \fBDATE\fR
|
||||
constants with the addition of an "@HH:MM" part, optionally followed
|
||||
by "am" or "pm". For example:
|
||||
.PP
|
||||
.RS
|
||||
\'2008-04-05@23:11', '1999/02/03@14:06', '2001-04-07@08:30'
|
||||
\'2008-04-05@23:11', '1999/02/03@14:06', '2001-04-07@08:30', '2020-01-01@3:20pm'
|
||||
.PP
|
||||
\fBDATETIME\fR values are printed without the quotes. Notes about date
|
||||
and time separator characters for \fBDATE\fR and \fBTIME\fR constants apply
|
||||
@@ -2011,9 +2026,11 @@ for years greater than 2037.
|
||||
.TP
|
||||
.B $FormWidth
|
||||
The maximum width of each line of text for formatting \fBMSF\fR-type
|
||||
reminders. The default is 72. If an \fBMSF\fR-type reminder contains
|
||||
a word too long to fit in this width, it will not be truncated - the
|
||||
width limit will be ignored.
|
||||
reminders. The default is the width of the terminal in columns, minus
|
||||
8, but clamped at a minimum of 20 and a maximum of 500. If standard
|
||||
output is not a terminal, then the default is 72.If an \fBMSF\fR-type
|
||||
reminder contains a word too long to fit in this width, it will not be
|
||||
truncated - the width limit will be ignored.
|
||||
.TP
|
||||
.B $HushMode (read-only)
|
||||
If non-zero, then the \fB\-h\fR option was supplied on the command line.
|
||||
@@ -2206,6 +2223,23 @@ 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]])
|
||||
Returns a \fBSTRING\fR that is the result of converting \fItime\fR
|
||||
(which is either a \fBTIME\R or a \fBDATETIME\fR object) to "AM/PM"
|
||||
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:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
ampm(0:22) returns "12:22AM"
|
||||
ampm(17:45, "am", "pm") returns "5:45pm"
|
||||
ampm('2020-03-14@21:34') returns "2020-03-14@9:34PM"
|
||||
.fi
|
||||
.PP
|
||||
.RE
|
||||
.TP
|
||||
.B args(s_fname)
|
||||
Returns the number of arguments expected by the user-defined function
|
||||
\fIfname\fR, or \-1 if no such user-defined function exists. Note that
|
||||
@@ -3115,12 +3149,12 @@ is an implementation artifact.
|
||||
.B SELF-OVERLAPPING EVENTS
|
||||
.PP
|
||||
A multi-day event has the possibility of "overlapping itself". When this
|
||||
happens, \fBRemind\fR prefers the \fIearlier\fR event (only one copy of
|
||||
happens, \fBRemind\fR prefers the \fIlater\fR event (only one copy of
|
||||
an event is ever triggered for a given date.) Consider this example:
|
||||
.PP
|
||||
.nf
|
||||
#!/bin/sh
|
||||
remind - '*4' 11 Feb 1991 <<'EOF'
|
||||
remind - '*5' 10 Feb 1991 <<'EOF'
|
||||
|
||||
BANNER %
|
||||
REM MON at 0:00 DURATION 192:0 MSG [today()] [trigeventstart()] [trigduration()]%
|
||||
@@ -3131,17 +3165,16 @@ an event is ever triggered for a given date.) Consider this example:
|
||||
The output is:
|
||||
.PP
|
||||
.nf
|
||||
1991-02-11 1991-02-04@00:00 24:00
|
||||
1991-02-10 1991-02-04@00:00 48:00
|
||||
1991-02-11 1991-02-11@00:00 192:00
|
||||
1991-02-12 1991-02-11@00:00 168:00
|
||||
1991-02-13 1991-02-11@00:00 144:00
|
||||
1991-02-14 1991-02-11@00:00 120:00
|
||||
.fi
|
||||
.PP
|
||||
Although 1991-02-11 is a Monday (which should cause the event to be
|
||||
triggered, the 8-day-long event that started on 1991-02-04 \fIhas not
|
||||
finished yet\fR, so that is the one that is triggered. The next day,
|
||||
the event starting on 1991-02-04 \fIhas\fR finished, so the 1991-02-11
|
||||
event triggers, with a remaining duration of 168:00, or 7 days.
|
||||
Although the event from 1991-02-04 still has 24 hours left on 1991-02-11,
|
||||
the fresh occurrence on 1991-02-11 takes precedences and is the one that
|
||||
is triggered.
|
||||
.PP
|
||||
I do not recommend constructing self-overlapping multi-day events.
|
||||
.PP
|
||||
|
||||
@@ -582,7 +582,7 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
|
||||
proc DoQueue {} {
|
||||
global DaemonFile
|
||||
puts $DaemonFile "QUEUE"
|
||||
puts $DaemonFile "JSONQUEUE"
|
||||
flush $DaemonFile
|
||||
}
|
||||
|
||||
@@ -2418,18 +2418,19 @@ proc ShowQueue { file } {
|
||||
grid columnconfigure $w 1 -weight 0
|
||||
grid rowconfigure $w 0 -weight 1
|
||||
grid rowconfigure $w 1 -weight 0
|
||||
set did 0
|
||||
CenterWindow $w .
|
||||
while (1) {
|
||||
# We should only get one line
|
||||
gets $file line
|
||||
if {$line == "NOTE endqueue"} {
|
||||
if {$line == "NOTE ENDJSONQUEUE"} {
|
||||
break
|
||||
}
|
||||
set did 1
|
||||
$w.t insert end "$line\n"
|
||||
}
|
||||
if {!$did} {
|
||||
$w.t insert end "*** Queue is empty ***\n"
|
||||
if {[catch {set obj [::json::json2dict $line]}]} {
|
||||
continue;
|
||||
}
|
||||
foreach q $obj {
|
||||
$w.t insert end "$q\n"
|
||||
}
|
||||
}
|
||||
$w.t configure -state disabled
|
||||
}
|
||||
@@ -2456,7 +2457,7 @@ proc DaemonReadable { file } {
|
||||
scan $line "NOTE reminder %s %s %s" time now tag
|
||||
IssueBackgroundReminder $file $time $now $tag
|
||||
}
|
||||
"NOTE queue" {
|
||||
"NOTE JSONQUEUE" {
|
||||
ShowQueue $file
|
||||
}
|
||||
"NOTE newdate" {
|
||||
|
||||
@@ -86,7 +86,7 @@ distro:
|
||||
gpg --detach-sign -u dianne@skoll.ca remind-$(VERSION).tar.gz
|
||||
|
||||
beta-tgz:
|
||||
cd .. && git archive --worktree-attributes --format=tar --prefix=remind-$(VERSION)/ HEAD > src/remind-$(VERSION)-BETA-$(BETA).tar
|
||||
cd .. && git archive --worktree-attributes --format=tar --prefix=remind-$(VERSION)-BETA-$(BETA)/ HEAD > src/remind-$(VERSION)-BETA-$(BETA).tar
|
||||
gzip -f -v -9 remind-$(VERSION)-BETA-$(BETA).tar
|
||||
gpg --detach-sign -u dianne@skoll.ca remind-$(VERSION)-BETA-$(BETA).tar.gz
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ static void WriteBottomCalLine (void);
|
||||
static void WriteIntermediateCalLine (void);
|
||||
static void WriteCalDays (void);
|
||||
|
||||
static void PrintJSONString(char const *s)
|
||||
void PrintJSONString(char const *s)
|
||||
{
|
||||
while (*s) {
|
||||
switch(*s) {
|
||||
@@ -262,14 +262,14 @@ static void PrintJSONString(char const *s)
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintJSONKeyPairInt(char const *name, int val)
|
||||
void PrintJSONKeyPairInt(char const *name, int val)
|
||||
{
|
||||
printf("\"");
|
||||
PrintJSONString(name);
|
||||
printf("\":%d, ", val);
|
||||
}
|
||||
|
||||
static void PrintJSONKeyPairString(char const *name, char const *val)
|
||||
void PrintJSONKeyPairString(char const *name, char const *val)
|
||||
{
|
||||
/* If value is blank, skip it! */
|
||||
if (!val || !*val) {
|
||||
@@ -283,7 +283,7 @@ static void PrintJSONKeyPairString(char const *name, char const *val)
|
||||
printf("\", ");
|
||||
}
|
||||
|
||||
static void PrintJSONKeyPairDate(char const *name, int jul)
|
||||
void PrintJSONKeyPairDate(char const *name, int jul)
|
||||
{
|
||||
int y, m, d;
|
||||
if (jul == NO_DATE) {
|
||||
@@ -297,7 +297,7 @@ static void PrintJSONKeyPairDate(char const *name, int jul)
|
||||
|
||||
}
|
||||
|
||||
static void PrintJSONKeyPairDateTime(char const *name, int dt)
|
||||
void PrintJSONKeyPairDateTime(char const *name, int dt)
|
||||
{
|
||||
int y, m, d, h, i, k;
|
||||
if (dt == NO_TIME) {
|
||||
@@ -315,6 +315,21 @@ static void PrintJSONKeyPairDateTime(char const *name, int dt)
|
||||
|
||||
}
|
||||
|
||||
void PrintJSONKeyPairTime(char const *name, int t)
|
||||
{
|
||||
int h, i;
|
||||
if (t == NO_TIME) {
|
||||
/* Skip it! */
|
||||
return;
|
||||
}
|
||||
h = t / 60;
|
||||
i = t % 60;
|
||||
printf("\"");
|
||||
PrintJSONString(name);
|
||||
printf("\":\"%02d:%02d\", ", h, i);
|
||||
|
||||
}
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
static void PutWideChar(wchar_t const wc)
|
||||
{
|
||||
@@ -495,7 +510,7 @@ ComputeCalWidth(int x)
|
||||
return 80;
|
||||
}
|
||||
if (w.ws_col < 71) {
|
||||
return 80;
|
||||
return 71;
|
||||
}
|
||||
return w.ws_col;
|
||||
}
|
||||
@@ -778,8 +793,13 @@ static int WriteCalendarRow(void)
|
||||
if (i < wd || d+i-wd>DaysInMonth(m, y))
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
else {
|
||||
sprintf(buf, "%d", d+i-wd);
|
||||
PrintLeft(buf, ColSpaces, ' ');
|
||||
sprintf(buf, "%d ", d+i-wd);
|
||||
if (OrigJul+i == RealToday) {
|
||||
PrintLeft(buf, ColSpaces-1, '*');
|
||||
PutChar(' ');
|
||||
} else {
|
||||
PrintLeft(buf, ColSpaces, ' ');
|
||||
}
|
||||
}
|
||||
gon();
|
||||
DRAW(tb);
|
||||
@@ -2081,8 +2101,6 @@ char const *SynthesizeTag(void)
|
||||
unsigned char buf[16];
|
||||
static char out[128];
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, (unsigned char *) FileName, strlen(FileName));
|
||||
MD5Update(&ctx, (unsigned char *) &LineNo, sizeof(LineNo));
|
||||
MD5Update(&ctx, (unsigned char *) CurLine, strlen(CurLine));
|
||||
MD5Final(buf, &ctx);
|
||||
sprintf(out, "__syn__%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
|
||||
19
src/dorem.c
19
src/dorem.c
@@ -417,6 +417,9 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
switch(tok.type) {
|
||||
case T_Time:
|
||||
case T_LongTime:
|
||||
case T_Year:
|
||||
case T_Day:
|
||||
case T_Number:
|
||||
if (tok.val != 0) {
|
||||
tim->duration = tok.val;
|
||||
} else {
|
||||
@@ -1099,10 +1102,24 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
iter = 0;
|
||||
start = trig->scanfrom;
|
||||
while (iter++ < MaxSatIter) {
|
||||
jul = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1);
|
||||
jul = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1, 0);
|
||||
if (r) {
|
||||
if (r == E_CANT_TRIG) return OK; else return r;
|
||||
}
|
||||
if (jul != start && trig->duration_days) {
|
||||
jul = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1, trig->duration_days);
|
||||
if (r) {
|
||||
if (r == E_CANT_TRIG) return OK; else return r;
|
||||
}
|
||||
} else if (jul == start) {
|
||||
if (tt->ttime != NO_TIME) {
|
||||
trig->eventstart = MINUTES_PER_DAY * r + tt->ttime;
|
||||
if (tt->duration != NO_TIME) {
|
||||
trig->eventduration = tt->duration;
|
||||
}
|
||||
}
|
||||
SaveAllTriggerInfo(trig, tt, jul, tt->ttime, 1);
|
||||
}
|
||||
if (jul == -1) {
|
||||
return E_EXPIRED;
|
||||
}
|
||||
|
||||
@@ -644,10 +644,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
break;
|
||||
|
||||
case '_':
|
||||
if (mode != CAL_MODE && mode != ADVANCE_MODE && !MsgCommand)
|
||||
if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !MsgCommand)) {
|
||||
sprintf(s, "%s", NL);
|
||||
else
|
||||
} else {
|
||||
sprintf(s, " ");
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
|
||||
101
src/expr.c
101
src/expr.c
@@ -492,6 +492,7 @@ static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
|
||||
{
|
||||
int len;
|
||||
int h, m, r;
|
||||
int ampm = 0;
|
||||
|
||||
if (*s == '\"') { /* It's a literal string "*/
|
||||
len = strlen(s)-1;
|
||||
@@ -532,7 +533,27 @@ static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
|
||||
m += *s - '0';
|
||||
s++;
|
||||
}
|
||||
/* Check for p[m] or a[m] */
|
||||
if (*s == 'A' || *s == 'a' || *s == 'P' || *s == 'p') {
|
||||
ampm = tolower(*s);
|
||||
s++;
|
||||
if (*s == 'm' || *s == 'M') {
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if (*s || h>23 || m>59) return E_BAD_TIME;
|
||||
if (ampm) {
|
||||
if (h < 1 || h > 12) return E_BAD_TIME;
|
||||
if (ampm == 'a') {
|
||||
if (h == 12) {
|
||||
h = 0;
|
||||
}
|
||||
} else if (ampm == 'p') {
|
||||
if (h < 12) {
|
||||
h += 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
v->type = TIME_TYPE;
|
||||
v->v.val = h*60 + m;
|
||||
return OK;
|
||||
@@ -701,26 +722,12 @@ int DoCoerce(char type, Value *v)
|
||||
return OK;
|
||||
|
||||
case STR_TYPE:
|
||||
h = 0;
|
||||
m = 0;
|
||||
s = v->v.str;
|
||||
if (!isdigit(*s)) return E_CANT_COERCE;
|
||||
while (isdigit(*s)) {
|
||||
h *= 10;
|
||||
h += *s++ - '0';
|
||||
}
|
||||
if (*s != ':' && *s != '.' && *s != TimeSep)
|
||||
return E_CANT_COERCE;
|
||||
s++;
|
||||
if (!isdigit(*s)) return E_CANT_COERCE;
|
||||
while (isdigit(*s)) {
|
||||
m *= 10;
|
||||
m += *s++ - '0';
|
||||
}
|
||||
if (*s || h>23 || m>59) return E_CANT_COERCE;
|
||||
if (ParseLiteralTime(&s, &i)) return E_CANT_COERCE;
|
||||
if (*s) return E_CANT_COERCE;
|
||||
v->type = TIME_TYPE;
|
||||
free(v->v.str);
|
||||
v->v.val = h*60+m;
|
||||
v->v.val = i;
|
||||
return OK;
|
||||
|
||||
default: return E_CANT_COERCE;
|
||||
@@ -1222,6 +1229,48 @@ int CopyValue(Value *dest, const Value *src)
|
||||
return OK;
|
||||
}
|
||||
|
||||
int ParseLiteralTime(char const **s, int *tim)
|
||||
{
|
||||
int h=0;
|
||||
int m=0;
|
||||
int ampm=0;
|
||||
if (!isdigit(**s)) return E_BAD_TIME;
|
||||
while(isdigit(**s)) {
|
||||
h *= 10;
|
||||
h += *(*s)++ - '0';
|
||||
}
|
||||
if (**s != ':' && **s != '.' && **s != TimeSep) return E_BAD_TIME;
|
||||
(*s)++;
|
||||
if (!isdigit(**s)) return E_BAD_TIME;
|
||||
while(isdigit(**s)) {
|
||||
m *= 10;
|
||||
m += *(*s)++ - '0';
|
||||
}
|
||||
/* Check for p[m] or a[m] */
|
||||
if (**s == 'A' || **s == 'a' || **s == 'P' || **s == 'p') {
|
||||
ampm = tolower(**s);
|
||||
(*s)++;
|
||||
if (**s == 'm' || **s == 'M') {
|
||||
(*s)++;
|
||||
}
|
||||
}
|
||||
if (h>23 || m>59) return E_BAD_TIME;
|
||||
if (ampm) {
|
||||
if (h < 1 || h > 12) return E_BAD_TIME;
|
||||
if (ampm == 'a') {
|
||||
if (h == 12) {
|
||||
h = 0;
|
||||
}
|
||||
} else if (ampm == 'p') {
|
||||
if (h < 12) {
|
||||
h += 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
*tim = h * 60 + m;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseLiteralDate */
|
||||
@@ -1233,10 +1282,9 @@ int CopyValue(Value *dest, const Value *src)
|
||||
int ParseLiteralDate(char const **s, int *jul, int *tim)
|
||||
{
|
||||
int y, m, d;
|
||||
int hour, min;
|
||||
int r;
|
||||
|
||||
y=0; m=0; d=0;
|
||||
hour=0; min=0;
|
||||
|
||||
*tim = NO_TIME;
|
||||
if (!isdigit(**s)) return E_BAD_DATE;
|
||||
@@ -1266,20 +1314,9 @@ int ParseLiteralDate(char const **s, int *jul, int *tim)
|
||||
/* Do we have a time part as well? */
|
||||
if (**s == ' ' || **s == '@' || **s == 'T' || **s == 't') {
|
||||
(*s)++;
|
||||
while(isdigit(**s)) {
|
||||
hour *= 10;
|
||||
hour += *(*s)++ - '0';
|
||||
}
|
||||
if (**s != ':' && **s != '.' && **s != TimeSep) return E_BAD_TIME;
|
||||
(*s)++;
|
||||
while(isdigit(**s)) {
|
||||
min *= 10;
|
||||
min += *(*s)++ - '0';
|
||||
}
|
||||
if (hour > 23 || min > 59) return E_BAD_TIME;
|
||||
*tim = hour * 60 + min;
|
||||
r = ParseLiteralTime(s, tim);
|
||||
if (r != OK) return r;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
72
src/funcs.c
72
src/funcs.c
@@ -57,6 +57,7 @@ static int FADawn (func_info *);
|
||||
static int FADusk (func_info *);
|
||||
static int FAbs (func_info *);
|
||||
static int FAccess (func_info *);
|
||||
static int FAmpm (func_info *);
|
||||
static int FArgs (func_info *);
|
||||
static int FAsc (func_info *);
|
||||
static int FBaseyr (func_info *);
|
||||
@@ -206,6 +207,7 @@ BuiltinFunc Func[] = {
|
||||
{ "access", 2, 2, 0, FAccess },
|
||||
{ "adawn", 0, 1, 0, FADawn},
|
||||
{ "adusk", 0, 1, 0, FADusk},
|
||||
{ "ampm", 1, 3, 1, FAmpm },
|
||||
{ "args", 1, 1, 0, FArgs },
|
||||
{ "asc", 1, 1, 1, FAsc },
|
||||
{ "baseyr", 0, 0, 1, FBaseyr },
|
||||
@@ -886,6 +888,76 @@ static int FSgn(func_info *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FAmpm - return a time as a string with "AM" or "PM" suffix */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int FAmpm(func_info *info)
|
||||
{
|
||||
int h, m;
|
||||
int yr=0, mo=0, da=0;
|
||||
|
||||
char const *am = "AM";
|
||||
char const *pm = "PM";
|
||||
char const *ampm = NULL;
|
||||
|
||||
char outbuf[128];
|
||||
|
||||
if (ARG(0).type != DATETIME_TYPE && ARG(0).type != TIME_TYPE) {
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
if (HASDATE(ARG(0))) {
|
||||
FromJulian(DATEPART(ARG(0)), &yr, &mo, &da);
|
||||
}
|
||||
if (Nargs >= 2) {
|
||||
ASSERT_TYPE(1, STR_TYPE);
|
||||
am = ARGSTR(1);
|
||||
if (Nargs >= 3) {
|
||||
ASSERT_TYPE(2, STR_TYPE);
|
||||
pm = ARGSTR(2);
|
||||
}
|
||||
}
|
||||
h = TIMEPART(ARG(0)) / 60;
|
||||
m = TIMEPART(ARG(0)) % 60;
|
||||
if (h <= 11) {
|
||||
/* AM */
|
||||
if (h == 0) {
|
||||
if (ARG(0).type == DATETIME_TYPE) {
|
||||
snprintf(outbuf, sizeof(outbuf), "%04d%c%02d%c%02d%c12%c%02d", yr, DateSep, mo+1, DateSep, da, DateTimeSep, TimeSep, m);
|
||||
} else {
|
||||
snprintf(outbuf, sizeof(outbuf), "12%c%02d", TimeSep, m);
|
||||
}
|
||||
} 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);
|
||||
} else {
|
||||
snprintf(outbuf, sizeof(outbuf), "%d%c%02d", h, TimeSep, m);
|
||||
}
|
||||
}
|
||||
ampm = am;
|
||||
} else {
|
||||
if (h > 12) {
|
||||
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);
|
||||
} else {
|
||||
snprintf(outbuf, sizeof(outbuf), "%d%c%02d", h, TimeSep, m);
|
||||
}
|
||||
ampm = pm;
|
||||
}
|
||||
RetVal.type = STR_TYPE;
|
||||
RetVal.v.str = malloc(strlen(outbuf) + strlen(ampm) + 1);
|
||||
if (!RetVal.v.str) {
|
||||
RetVal.type = ERR_TYPE;
|
||||
return E_NO_MEM;
|
||||
}
|
||||
strcpy(RetVal.v.str, outbuf);
|
||||
strcat(RetVal.v.str, ampm);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FOrd - returns a string containing ordinal number. */
|
||||
|
||||
12
src/init.c
12
src/init.c
@@ -23,6 +23,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
@@ -147,6 +148,17 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
jul = NO_DATE;
|
||||
|
||||
/* If stdout is a terminal, initialize $FormWidth to terminal width-8,
|
||||
but clamp to [20, 500] */
|
||||
if (isatty(STDOUT_FILENO)) {
|
||||
struct winsize w;
|
||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0) {
|
||||
FormWidth = w.ws_col - 8;
|
||||
if (FormWidth < 20) FormWidth = 20;
|
||||
if (FormWidth > 500) FormWidth = 500;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize global dynamic buffers */
|
||||
DBufInit(&Banner);
|
||||
DBufInit(&LineBuffer);
|
||||
|
||||
10
src/main.c
10
src/main.c
@@ -1370,6 +1370,16 @@ ClearLastTriggers(void)
|
||||
LastTimeTrig.duration = NO_TIME;
|
||||
}
|
||||
|
||||
void
|
||||
SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigtime, int valid)
|
||||
{
|
||||
SaveLastTrigger(t);
|
||||
SaveLastTimeTrig(tt);
|
||||
LastTriggerDate = trigdate;
|
||||
LastTriggerTime = trigtime;
|
||||
LastTrigValid = valid;
|
||||
}
|
||||
|
||||
void
|
||||
SaveLastTrigger(Trigger const *t)
|
||||
{
|
||||
|
||||
11
src/protos.h
11
src/protos.h
@@ -37,6 +37,7 @@ int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int jul, int *err);
|
||||
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul, int mode);
|
||||
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int jul, int tim);
|
||||
int ParseLiteralDate (char const **s, int *jul, int *tim);
|
||||
int ParseLiteralTime (char const **s, int *tim);
|
||||
int EvalExpr (char const **e, Value *v, ParsePtr p);
|
||||
int DoCoerce (char type, Value *v);
|
||||
void PrintValue (Value *v, FILE *fp);
|
||||
@@ -89,7 +90,7 @@ char const *FindInitialToken (Token *tok, char const *s);
|
||||
void FindToken (char const *s, Token *tok);
|
||||
void FindNumericToken (char const *s, Token *t);
|
||||
int ComputeTrigger (int today, Trigger *trig, TimeTrig *tim, int *err, int save_in_globals);
|
||||
int ComputeTriggerNoAdjustDuration (int today, Trigger *trig, TimeTrig *tim, int *err, int save_in_globals);
|
||||
int ComputeTriggerNoAdjustDuration (int today, Trigger *trig, TimeTrig *tim, int *err, int save_in_globals, int duration_days);
|
||||
int AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int save_in_globals);
|
||||
int ComputeScanStart(int today, Trigger *trig, TimeTrig *tt);
|
||||
char *StrnCpy (char *dest, char const *source, int n);
|
||||
@@ -148,6 +149,14 @@ char const *SynthesizeTag(void);
|
||||
void ClearLastTriggers(void);
|
||||
void SaveLastTrigger(Trigger const *t);
|
||||
void SaveLastTimeTrig(TimeTrig const *t);
|
||||
void SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigtime, int valid);
|
||||
|
||||
void PerIterationInit(void);
|
||||
char const *Decolorize(int r, int g, int b);
|
||||
char const *Colorize(int r, int g, int b);
|
||||
void PrintJSONString(char const *s);
|
||||
void PrintJSONKeyPairInt(char const *name, int val);
|
||||
void PrintJSONKeyPairString(char const *name, char const *val);
|
||||
void PrintJSONKeyPairDate(char const *name, int jul);
|
||||
void PrintJSONKeyPairDateTime(char const *name, int dt);
|
||||
void PrintJSONKeyPairTime(char const *name, int t);
|
||||
|
||||
75
src/queue.c
75
src/queue.c
@@ -246,11 +246,7 @@ void HandleQueuedReminders(void)
|
||||
|
||||
/* Set up global variables so some functions like trigdate()
|
||||
and trigtime() work correctly */
|
||||
LastTriggerDate = JulianToday;
|
||||
LastTriggerTime = q->tt.ttime;
|
||||
LastTrigValid = 1;
|
||||
SaveLastTrigger(&(q->t));
|
||||
SaveLastTimeTrig(&(q->tt));
|
||||
SaveAllTriggerInfo(&(q->t), &(q->tt), JulianToday, q->tt.ttime, 1);
|
||||
(void) TriggerReminder(&p, &trig, &q->tt, JulianToday);
|
||||
if (Daemon < 0) {
|
||||
printf("NOTE endreminder\n");
|
||||
@@ -452,6 +448,70 @@ static int CalculateNextTimeUsingSched(QueuedRem *q)
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump the queue in JSON format */
|
||||
static void
|
||||
json_queue(QueuedRem const *q)
|
||||
{
|
||||
int done = 0;
|
||||
printf("[");
|
||||
while(q) {
|
||||
if (q->tt.nexttime == NO_TIME) {
|
||||
q = q->next;
|
||||
continue;
|
||||
}
|
||||
if (done) {
|
||||
printf(",");
|
||||
}
|
||||
done = 1;
|
||||
printf("{");
|
||||
switch(q->typ) {
|
||||
case NO_TYPE: PrintJSONKeyPairString("type", "NO_TYPE"); break;
|
||||
case MSG_TYPE: PrintJSONKeyPairString("type", "MSG_TYPE"); break;
|
||||
case RUN_TYPE: PrintJSONKeyPairString("type", "RUN_TYPE"); break;
|
||||
case CAL_TYPE: PrintJSONKeyPairString("type", "CAL_TYPE"); break;
|
||||
case SAT_TYPE: PrintJSONKeyPairString("type", "SAT_TYPE"); break;
|
||||
case PS_TYPE: PrintJSONKeyPairString("type", "PS_TYPE"); break;
|
||||
case PSF_TYPE: PrintJSONKeyPairString("type", "PSF_TYPE"); break;
|
||||
case MSF_TYPE: PrintJSONKeyPairString("type", "MSF_TYPE"); break;
|
||||
case PASSTHRU_TYPE: PrintJSONKeyPairString("type", "PASSTHRU_TYPE"); break;
|
||||
default: PrintJSONKeyPairString("type", "?"); break;
|
||||
}
|
||||
PrintJSONKeyPairInt("rundisabled", q->RunDisabled);
|
||||
PrintJSONKeyPairInt("ntrig", q->ntrig);
|
||||
PrintJSONKeyPairTime("ttime", q->tt.ttime);
|
||||
PrintJSONKeyPairTime("nextttime", q->tt.nexttime);
|
||||
PrintJSONKeyPairInt("delta", q->tt.delta);
|
||||
if (q->tt.rep != NO_TIME) {
|
||||
PrintJSONKeyPairInt("rep", q->tt.rep);
|
||||
}
|
||||
if (q->tt.duration != NO_TIME) {
|
||||
PrintJSONKeyPairInt("duration", q->tt.duration);
|
||||
}
|
||||
if (q->passthru[0]) {
|
||||
PrintJSONKeyPairString("passthru", q->passthru);
|
||||
}
|
||||
if (q->sched[0]) {
|
||||
PrintJSONKeyPairString("sched", q->sched);
|
||||
}
|
||||
if (DBufLen(&(q->tags))) {
|
||||
PrintJSONKeyPairString("tags", DBufValue(&(q->tags)));
|
||||
}
|
||||
|
||||
/* Last one is a special case - no trailing comma */
|
||||
printf("\"");
|
||||
PrintJSONString("body");
|
||||
printf("\":\"");
|
||||
if (q->text) {
|
||||
PrintJSONString(q->text);
|
||||
} else {
|
||||
PrintJSONString("");
|
||||
}
|
||||
printf("\"}");
|
||||
q = q->next;
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DaemonWait */
|
||||
@@ -536,6 +596,11 @@ static void DaemonWait(unsigned int sleeptime)
|
||||
}
|
||||
printf("NOTE endqueue\n");
|
||||
fflush(stdout);
|
||||
} else if (!strcmp(cmdLine, "JSONQUEUE\n")) {
|
||||
printf("NOTE JSONQUEUE\n");
|
||||
json_queue(QueueHead);
|
||||
printf("NOTE ENDJSONQUEUE\n");
|
||||
fflush(stdout);
|
||||
} else if (!strcmp(cmdLine, "REREAD\n")) {
|
||||
printf("NOTE reread\n");
|
||||
fflush(stdout);
|
||||
|
||||
29
src/token.c
29
src/token.c
@@ -257,6 +257,7 @@ void FindNumericToken(char const *s, Token *t)
|
||||
{
|
||||
int mult = 1, hour, min;
|
||||
char const *s_orig = s;
|
||||
int ampm = 0;
|
||||
|
||||
t->type = T_Illegal;
|
||||
t->val = 0;
|
||||
@@ -284,10 +285,6 @@ void FindNumericToken(char const *s, Token *t)
|
||||
like Jan 6, 1998 */
|
||||
if (*s == ',') {
|
||||
s++;
|
||||
/* Special hack - convert years between 90 and
|
||||
99 to 1990 and 1999 */
|
||||
if (t->val >= 90 && t->val <= 99) t->val += 1900;
|
||||
|
||||
/* Classify the number we've got */
|
||||
if (t->val >= BASE && t->val <= BASE+YR_RANGE) t->type = T_Year;
|
||||
else if (t->val >= 1 && t->val <= 31) t->type = T_Day;
|
||||
@@ -299,7 +296,29 @@ void FindNumericToken(char const *s, Token *t)
|
||||
s++;
|
||||
hour = t->val;
|
||||
PARSENUM(min, s);
|
||||
if (*s || min > 59) return; /* Illegal time */
|
||||
if (min > 59) return; /* Illegal time */
|
||||
/* Check for p[m] or a[m] */
|
||||
if (*s == 'A' || *s == 'a' || *s == 'P' || *s == 'p') {
|
||||
ampm = tolower(*s);
|
||||
s++;
|
||||
if (*s == 'm' || *s == 'M') {
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if (*s) return; /* Illegal time */
|
||||
if (ampm) {
|
||||
if (hour < 1 || hour > 12) return;
|
||||
if (ampm == 'a') {
|
||||
if (hour == 12) {
|
||||
hour = 0;
|
||||
}
|
||||
} else if (ampm == 'p') {
|
||||
if (hour < 12) {
|
||||
hour += 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t->val = hour*60 + min; /* Convert to minutes past midnight */
|
||||
if (hour <= 23) {
|
||||
t->type = T_Time;
|
||||
|
||||
@@ -454,11 +454,7 @@ AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int sav
|
||||
|
||||
}
|
||||
if (save_in_globals) {
|
||||
LastTriggerTime = tim->ttime;
|
||||
SaveLastTimeTrig(tim);
|
||||
SaveLastTrigger(trig);
|
||||
LastTriggerDate = r;
|
||||
LastTrigValid = 1;
|
||||
SaveAllTriggerInfo(trig, tim, r, tim->ttime, 1);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -474,10 +470,29 @@ AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int sav
|
||||
int ComputeTrigger(int today, Trigger *trig, TimeTrig *tim,
|
||||
int *err, int save_in_globals)
|
||||
{
|
||||
int r = ComputeTriggerNoAdjustDuration(today, trig, tim, err, save_in_globals);
|
||||
int r = ComputeTriggerNoAdjustDuration(today, trig, tim, err, save_in_globals, 0);
|
||||
if (*err != OK) {
|
||||
return r;
|
||||
}
|
||||
if (r == today) {
|
||||
if (tim->ttime != NO_TIME) {
|
||||
trig->eventstart = MINUTES_PER_DAY * r + tim->ttime;
|
||||
if (tim->duration != NO_TIME) {
|
||||
trig->eventduration = tim->duration;
|
||||
}
|
||||
}
|
||||
if (save_in_globals) {
|
||||
SaveAllTriggerInfo(trig, tim, r, tim->ttime, 1);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
if (trig->duration_days) {
|
||||
r = ComputeTriggerNoAdjustDuration(today, trig, tim, err, save_in_globals, trig->duration_days);
|
||||
if (*err != OK) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
r = AdjustTriggerForDuration(today, r, trig, tim, save_in_globals);
|
||||
return r;
|
||||
}
|
||||
@@ -491,10 +506,10 @@ int ComputeTrigger(int today, Trigger *trig, TimeTrig *tim,
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
int *err, int save_in_globals)
|
||||
int *err, int save_in_globals, int duration_days)
|
||||
{
|
||||
int nattempts = 0,
|
||||
start = today - trig->duration_days,
|
||||
start = today - duration_days,
|
||||
nextstart = 0,
|
||||
y, m, d, omit,
|
||||
result;
|
||||
@@ -561,7 +576,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
}
|
||||
|
||||
/** FIXME: Fix bad interaction with SATISFY... need to rethink!!! */
|
||||
if (result+trig->duration_days >= today &&
|
||||
if (result+duration_days >= today &&
|
||||
(trig->skip != SKIP_SKIP || !omit)) {
|
||||
if (save_in_globals) {
|
||||
LastTriggerDate = result; /* Save in global var */
|
||||
|
||||
@@ -657,7 +657,7 @@ static SysVar SysVarArr[] = {
|
||||
{"EndSentIg", 1, STR_TYPE, &EndSentIg, 0, 0 },
|
||||
{"FirstIndent", 1, INT_TYPE, &FirstIndent, 0, 132 },
|
||||
{"FoldYear", 1, INT_TYPE, &FoldYear, 0, 1 },
|
||||
{"FormWidth", 1, INT_TYPE, &FormWidth, 20, 132 },
|
||||
{"FormWidth", 1, INT_TYPE, &FormWidth, 20, 500 },
|
||||
{"HushMode", 0, INT_TYPE, &Hush, 0, 0 },
|
||||
{"IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 0, 0 },
|
||||
{"InfDelta", 0, INT_TYPE, &InfiniteDelta, 0, 0 },
|
||||
|
||||
477
tests/test.cmp
477
tests/test.cmp
@@ -857,7 +857,7 @@ set a057 value("a05"+"6")
|
||||
"a05" + "6" => "a056"
|
||||
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
set a058 version()
|
||||
version() => "03.03.00"
|
||||
version() => "03.03.01"
|
||||
set a059 wkday(today())
|
||||
today() => 1991-02-16
|
||||
wkday(1991-02-16) => "Saturday"
|
||||
@@ -1098,7 +1098,7 @@ trigtimerep() => 0
|
||||
set a105 trigduration()
|
||||
trigduration() => -1
|
||||
|
||||
REM 2010-09-03 +3 -4 UNTIL 2012-01-01 PRIORITY 7 *14 AT 14:41 +15 *2 DURATION 3:33 MSG foo
|
||||
REM 2010-09-03 +3 -4 UNTIL 2012-01-01 PRIORITY 7 *14 AT 14:41 +15 *2 DURATION 213 MSG foo
|
||||
../tests/test.rem(340): Trig = Monday, 30 August, 2010 AT 14:41 DURATION 03:33
|
||||
set a106 trigback()
|
||||
trigback() => 4
|
||||
@@ -1156,6 +1156,7 @@ set a129 23:30 + '2019-02-02@16:44'
|
||||
|
||||
# Multi-day reminder
|
||||
REM 13 AT 16:00 DURATION 72:00 MSG 72-hour event
|
||||
../tests/test.rem(371): Trig = Wednesday, 13 March, 1991 AT 16:00 DURATION 72:00
|
||||
../tests/test.rem(371): Trig = Wednesday, 13 February, 1991 AT 16:00 DURATION 72:00
|
||||
../tests/test.rem(371): Trig(adj) = Saturday, 16 February, 1991 AT 00:00 DURATION 16:00
|
||||
72-hour event
|
||||
@@ -1215,7 +1216,7 @@ dump
|
||||
a109 2012-01-01
|
||||
a128 2018-02-03@16:45
|
||||
a039 "February"
|
||||
a058 "03.03.00"
|
||||
a058 "03.03.01"
|
||||
a077 "1992 92
|
||||
"
|
||||
a096 -4
|
||||
@@ -1351,49 +1352,489 @@ trigger(1991-02-28) => "28 February 1991"
|
||||
Leaving UserFN _i() => "28 February 1991"
|
||||
../tests/test.rem(387): Trig = Thursday, 28 February, 1991
|
||||
|
||||
# Regression test for bug found by Larry Hynes
|
||||
REM SATISFY [day(trigdate()-25) == 14] MSG Foo
|
||||
../tests/test.rem(390): Trig = Saturday, 16 February, 1991
|
||||
trigdate() => 1991-02-16
|
||||
1991-02-16 - 25 => 1991-01-22
|
||||
day(1991-01-22) => 22
|
||||
22 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Sunday, 17 February, 1991
|
||||
trigdate() => 1991-02-17
|
||||
1991-02-17 - 25 => 1991-01-23
|
||||
day(1991-01-23) => 23
|
||||
23 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Monday, 18 February, 1991
|
||||
trigdate() => 1991-02-18
|
||||
1991-02-18 - 25 => 1991-01-24
|
||||
day(1991-01-24) => 24
|
||||
24 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Tuesday, 19 February, 1991
|
||||
trigdate() => 1991-02-19
|
||||
1991-02-19 - 25 => 1991-01-25
|
||||
day(1991-01-25) => 25
|
||||
25 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Wednesday, 20 February, 1991
|
||||
trigdate() => 1991-02-20
|
||||
1991-02-20 - 25 => 1991-01-26
|
||||
day(1991-01-26) => 26
|
||||
26 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Thursday, 21 February, 1991
|
||||
trigdate() => 1991-02-21
|
||||
1991-02-21 - 25 => 1991-01-27
|
||||
day(1991-01-27) => 27
|
||||
27 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Friday, 22 February, 1991
|
||||
trigdate() => 1991-02-22
|
||||
1991-02-22 - 25 => 1991-01-28
|
||||
day(1991-01-28) => 28
|
||||
28 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Saturday, 23 February, 1991
|
||||
trigdate() => 1991-02-23
|
||||
1991-02-23 - 25 => 1991-01-29
|
||||
day(1991-01-29) => 29
|
||||
29 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Sunday, 24 February, 1991
|
||||
trigdate() => 1991-02-24
|
||||
1991-02-24 - 25 => 1991-01-30
|
||||
day(1991-01-30) => 30
|
||||
30 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Monday, 25 February, 1991
|
||||
trigdate() => 1991-02-25
|
||||
1991-02-25 - 25 => 1991-01-31
|
||||
day(1991-01-31) => 31
|
||||
31 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Tuesday, 26 February, 1991
|
||||
trigdate() => 1991-02-26
|
||||
1991-02-26 - 25 => 1991-02-01
|
||||
day(1991-02-01) => 1
|
||||
1 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Wednesday, 27 February, 1991
|
||||
trigdate() => 1991-02-27
|
||||
1991-02-27 - 25 => 1991-02-02
|
||||
day(1991-02-02) => 2
|
||||
2 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Thursday, 28 February, 1991
|
||||
trigdate() => 1991-02-28
|
||||
1991-02-28 - 25 => 1991-02-03
|
||||
day(1991-02-03) => 3
|
||||
3 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Friday, 1 March, 1991
|
||||
trigdate() => 1991-03-01
|
||||
1991-03-01 - 25 => 1991-02-04
|
||||
day(1991-02-04) => 4
|
||||
4 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Saturday, 2 March, 1991
|
||||
trigdate() => 1991-03-02
|
||||
1991-03-02 - 25 => 1991-02-05
|
||||
day(1991-02-05) => 5
|
||||
5 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Sunday, 3 March, 1991
|
||||
trigdate() => 1991-03-03
|
||||
1991-03-03 - 25 => 1991-02-06
|
||||
day(1991-02-06) => 6
|
||||
6 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Monday, 4 March, 1991
|
||||
trigdate() => 1991-03-04
|
||||
1991-03-04 - 25 => 1991-02-07
|
||||
day(1991-02-07) => 7
|
||||
7 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Tuesday, 5 March, 1991
|
||||
trigdate() => 1991-03-05
|
||||
1991-03-05 - 25 => 1991-02-08
|
||||
day(1991-02-08) => 8
|
||||
8 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Wednesday, 6 March, 1991
|
||||
trigdate() => 1991-03-06
|
||||
1991-03-06 - 25 => 1991-02-09
|
||||
day(1991-02-09) => 9
|
||||
9 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Thursday, 7 March, 1991
|
||||
trigdate() => 1991-03-07
|
||||
1991-03-07 - 25 => 1991-02-10
|
||||
day(1991-02-10) => 10
|
||||
10 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Friday, 8 March, 1991
|
||||
trigdate() => 1991-03-08
|
||||
1991-03-08 - 25 => 1991-02-11
|
||||
day(1991-02-11) => 11
|
||||
11 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Saturday, 9 March, 1991
|
||||
trigdate() => 1991-03-09
|
||||
1991-03-09 - 25 => 1991-02-12
|
||||
day(1991-02-12) => 12
|
||||
12 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Sunday, 10 March, 1991
|
||||
trigdate() => 1991-03-10
|
||||
1991-03-10 - 25 => 1991-02-13
|
||||
day(1991-02-13) => 13
|
||||
13 == 14 => 0
|
||||
../tests/test.rem(390): Trig = Monday, 11 March, 1991
|
||||
trigdate() => 1991-03-11
|
||||
1991-03-11 - 25 => 1991-02-14
|
||||
day(1991-02-14) => 14
|
||||
14 == 14 => 1
|
||||
../tests/test.rem(390): Trig(satisfied) = Monday, 11 March, 1991
|
||||
|
||||
# Check combo of SATISFY and long-duration events
|
||||
REM 14 SATISFY [$Tw == 4] MSG Thursday, the 14th
|
||||
../tests/test.rem(390): Trig = Thursday, 14 March, 1991
|
||||
../tests/test.rem(393): Trig = Thursday, 14 March, 1991
|
||||
$Tw => 4
|
||||
4 == 4 => 1
|
||||
../tests/test.rem(390): Trig(satisfied) = Thursday, 14 March, 1991
|
||||
../tests/test.rem(393): Trig(satisfied) = Thursday, 14 March, 1991
|
||||
REM 14 AT 16:00 DURATION 8:00 SATISFY [$Tw == 4] MSG Thursday, the 14th
|
||||
../tests/test.rem(391): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 08:00
|
||||
../tests/test.rem(394): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 08:00
|
||||
$Tw => 4
|
||||
4 == 4 => 1
|
||||
../tests/test.rem(391): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 08:00
|
||||
../tests/test.rem(394): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 08:00
|
||||
REM 14 AT 16:00 DURATION 8:01 SATISFY [$Tw == 4] MSG Thursday, the 14th
|
||||
../tests/test.rem(392): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 08:01
|
||||
../tests/test.rem(395): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 08:01
|
||||
../tests/test.rem(395): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 08:01
|
||||
$Tw => 4
|
||||
4 == 4 => 1
|
||||
../tests/test.rem(392): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 08:01
|
||||
../tests/test.rem(395): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 08:01
|
||||
REM 14 AT 16:00 DURATION 32:00 SATISFY [$Tw == 4] MSG Thursday, the 14th
|
||||
../tests/test.rem(393): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 32:00
|
||||
../tests/test.rem(396): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 32:00
|
||||
../tests/test.rem(396): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 32:00
|
||||
$Tw => 4
|
||||
4 == 4 => 1
|
||||
../tests/test.rem(393): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 32:00
|
||||
../tests/test.rem(396): Trig(satisfied) = Thursday, 14 March, 1991 AT 16:00 DURATION 32:00
|
||||
REM 14 AT 16:00 DURATION 32:01 SATISFY [$Tw == 4] MSG Thursday, the 14th
|
||||
../tests/test.rem(394): Trig = Thursday, 14 February, 1991 AT 16:00 DURATION 32:01
|
||||
../tests/test.rem(397): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 32:01
|
||||
../tests/test.rem(397): Trig = Thursday, 14 February, 1991 AT 16:00 DURATION 32:01
|
||||
$Tw => 4
|
||||
4 == 4 => 1
|
||||
../tests/test.rem(394): Trig(adj) = Saturday, 16 February, 1991 AT 00:00 DURATION 00:01
|
||||
../tests/test.rem(394): Trig(satisfied) = Saturday, 16 February, 1991 AT 00:00 DURATION 00:01
|
||||
../tests/test.rem(397): Trig(adj) = Saturday, 16 February, 1991 AT 00:00 DURATION 00:01
|
||||
../tests/test.rem(397): Trig(satisfied) = Saturday, 16 February, 1991 AT 00:00 DURATION 00:01
|
||||
Thursday, the 14th
|
||||
|
||||
REM 14 AT 16:00 DURATION 40:00 SATISFY [$Tw == 4] MSG Thursday, the 14th
|
||||
../tests/test.rem(395): Trig = Thursday, 14 February, 1991 AT 16:00 DURATION 40:00
|
||||
../tests/test.rem(398): Trig = Thursday, 14 March, 1991 AT 16:00 DURATION 40:00
|
||||
../tests/test.rem(398): Trig = Thursday, 14 February, 1991 AT 16:00 DURATION 40:00
|
||||
$Tw => 4
|
||||
4 == 4 => 1
|
||||
../tests/test.rem(395): Trig(adj) = Saturday, 16 February, 1991 AT 00:00 DURATION 08:00
|
||||
../tests/test.rem(395): Trig(satisfied) = Saturday, 16 February, 1991 AT 00:00 DURATION 08:00
|
||||
../tests/test.rem(398): Trig(adj) = Saturday, 16 February, 1991 AT 00:00 DURATION 08:00
|
||||
../tests/test.rem(398): Trig(satisfied) = Saturday, 16 February, 1991 AT 00:00 DURATION 08:00
|
||||
Thursday, the 14th
|
||||
|
||||
|
||||
# This is now an error
|
||||
REM DURATION 15:00 MSG Should fail... need AT if you have DURATION.
|
||||
../tests/test.rem(398): Cannot specify DURATION without specifying AT
|
||||
../tests/test.rem(401): Cannot specify DURATION without specifying AT
|
||||
|
||||
# Parsing of AM/PM times
|
||||
REM AT 0:00am MSG foo 0a
|
||||
../tests/test.rem(404): Expecting time after AT
|
||||
REM AT 1:00AM MSG foo 1a
|
||||
../tests/test.rem(405): Trig = Saturday, 16 February, 1991 AT 01:00
|
||||
foo 1a
|
||||
|
||||
REM AT 2:00am MSG foo 2a
|
||||
../tests/test.rem(406): Trig = Saturday, 16 February, 1991 AT 02:00
|
||||
foo 2a
|
||||
|
||||
REM AT 3:00AM MSG foo 3a
|
||||
../tests/test.rem(407): Trig = Saturday, 16 February, 1991 AT 03:00
|
||||
foo 3a
|
||||
|
||||
REM AT 4:00am MSG foo 4a
|
||||
../tests/test.rem(408): Trig = Saturday, 16 February, 1991 AT 04:00
|
||||
foo 4a
|
||||
|
||||
REM AT 5:00AM MSG foo 5a
|
||||
../tests/test.rem(409): Trig = Saturday, 16 February, 1991 AT 05:00
|
||||
foo 5a
|
||||
|
||||
REM AT 6:00am MSG foo 6a
|
||||
../tests/test.rem(410): Trig = Saturday, 16 February, 1991 AT 06:00
|
||||
foo 6a
|
||||
|
||||
REM AT 7:00AM MSG foo 7a
|
||||
../tests/test.rem(411): Trig = Saturday, 16 February, 1991 AT 07:00
|
||||
foo 7a
|
||||
|
||||
REM AT 8:00am MSG foo 8a
|
||||
../tests/test.rem(412): Trig = Saturday, 16 February, 1991 AT 08:00
|
||||
foo 8a
|
||||
|
||||
REM AT 9:00AM MSG foo 9a
|
||||
../tests/test.rem(413): Trig = Saturday, 16 February, 1991 AT 09:00
|
||||
foo 9a
|
||||
|
||||
REM AT 10:00am MSG foo 10a
|
||||
../tests/test.rem(414): Trig = Saturday, 16 February, 1991 AT 10:00
|
||||
foo 10a
|
||||
|
||||
REM AT 11:00AM MSG foo 11a
|
||||
../tests/test.rem(415): Trig = Saturday, 16 February, 1991 AT 11:00
|
||||
foo 11a
|
||||
|
||||
REM AT 12:00am MSG foo 12a
|
||||
../tests/test.rem(416): Trig = Saturday, 16 February, 1991 AT 00:00
|
||||
foo 12a
|
||||
|
||||
REM AT 13:00AM MSG foo 13a
|
||||
../tests/test.rem(417): Expecting time after AT
|
||||
REM AT 0:00pm MSG foo 0p
|
||||
../tests/test.rem(418): Expecting time after AT
|
||||
REM AT 1:00PM MSG foo 1p
|
||||
../tests/test.rem(419): Trig = Saturday, 16 February, 1991 AT 13:00
|
||||
foo 1p
|
||||
|
||||
REM AT 2:00pm MSG foo 2p
|
||||
../tests/test.rem(420): Trig = Saturday, 16 February, 1991 AT 14:00
|
||||
foo 2p
|
||||
|
||||
REM AT 3:00PM MSG foo 3p
|
||||
../tests/test.rem(421): Trig = Saturday, 16 February, 1991 AT 15:00
|
||||
foo 3p
|
||||
|
||||
REM AT 4:00pm MSG foo 4p
|
||||
../tests/test.rem(422): Trig = Saturday, 16 February, 1991 AT 16:00
|
||||
foo 4p
|
||||
|
||||
REM AT 5:00PM MSG foo 5p
|
||||
../tests/test.rem(423): Trig = Saturday, 16 February, 1991 AT 17:00
|
||||
foo 5p
|
||||
|
||||
REM AT 6:00pm MSG foo 6p
|
||||
../tests/test.rem(424): Trig = Saturday, 16 February, 1991 AT 18:00
|
||||
foo 6p
|
||||
|
||||
REM AT 7:00PM MSG foo 7p
|
||||
../tests/test.rem(425): Trig = Saturday, 16 February, 1991 AT 19:00
|
||||
foo 7p
|
||||
|
||||
REM AT 8:00pm MSG foo 8p
|
||||
../tests/test.rem(426): Trig = Saturday, 16 February, 1991 AT 20:00
|
||||
foo 8p
|
||||
|
||||
REM AT 9:00PM MSG foo 9p
|
||||
../tests/test.rem(427): Trig = Saturday, 16 February, 1991 AT 21:00
|
||||
foo 9p
|
||||
|
||||
REM AT 10:00pm MSG foo 10p
|
||||
../tests/test.rem(428): Trig = Saturday, 16 February, 1991 AT 22:00
|
||||
foo 10p
|
||||
|
||||
REM AT 11:00PM MSG foo 11p
|
||||
../tests/test.rem(429): Trig = Saturday, 16 February, 1991 AT 23:00
|
||||
foo 11p
|
||||
|
||||
REM AT 12:00pm MSG foo 12p
|
||||
../tests/test.rem(430): Trig = Saturday, 16 February, 1991 AT 12:00
|
||||
foo 12p
|
||||
|
||||
REM AT 13:00PM MSG foo 13p
|
||||
../tests/test.rem(431): Expecting time after AT
|
||||
|
||||
DEBUG +x
|
||||
SET x 0:00am + 0
|
||||
../tests/test.rem(434): Ill-formed time
|
||||
SET x 1:00AM + 0
|
||||
01:00 + 0 => 01:00
|
||||
SET x 2:00am + 0
|
||||
02:00 + 0 => 02:00
|
||||
SET x 3:00AM + 0
|
||||
03:00 + 0 => 03:00
|
||||
SET x 4:00am + 0
|
||||
04:00 + 0 => 04:00
|
||||
SET x 5:00AM + 0
|
||||
05:00 + 0 => 05:00
|
||||
SET x 6:00am + 0
|
||||
06:00 + 0 => 06:00
|
||||
SET x 7:00AM + 0
|
||||
07:00 + 0 => 07:00
|
||||
SET x 8:00am + 0
|
||||
08:00 + 0 => 08:00
|
||||
SET x 9:00AM + 0
|
||||
09:00 + 0 => 09:00
|
||||
SET x 10:00am + 0
|
||||
10:00 + 0 => 10:00
|
||||
SET x 11:00AM + 0
|
||||
11:00 + 0 => 11:00
|
||||
SET x 12:00am + 0
|
||||
00:00 + 0 => 00:00
|
||||
SET x 13:00AM + 0
|
||||
../tests/test.rem(447): Ill-formed time
|
||||
|
||||
SET x 0:00pm + 0
|
||||
../tests/test.rem(449): Ill-formed time
|
||||
SET x 1:00PM + 0
|
||||
13:00 + 0 => 13:00
|
||||
SET x 2:00pm + 0
|
||||
14:00 + 0 => 14:00
|
||||
SET x 3:00PM + 0
|
||||
15:00 + 0 => 15:00
|
||||
SET x 4:00pm + 0
|
||||
16:00 + 0 => 16:00
|
||||
SET x 5:00PM + 0
|
||||
17:00 + 0 => 17:00
|
||||
SET x 6:00pm + 0
|
||||
18:00 + 0 => 18:00
|
||||
SET x 7:00PM + 0
|
||||
19:00 + 0 => 19:00
|
||||
SET x 8:00pm + 0
|
||||
20:00 + 0 => 20:00
|
||||
SET x 9:00PM + 0
|
||||
21:00 + 0 => 21:00
|
||||
SET x 10:00pm + 0
|
||||
22:00 + 0 => 22:00
|
||||
SET x 11:00PM + 0
|
||||
23:00 + 0 => 23:00
|
||||
SET x 12:00pm + 0
|
||||
12:00 + 0 => 12:00
|
||||
SET x 13:00PM + 0
|
||||
../tests/test.rem(462): Ill-formed time
|
||||
|
||||
SET x '2015-02-03@0:00am' + 0
|
||||
../tests/test.rem(464): Ill-formed time
|
||||
SET x '2015-02-03@1:00AM' + 0
|
||||
2015-02-03@01:00 + 0 => 2015-02-03@01:00
|
||||
SET x '2015-02-03@2:00am' + 0
|
||||
2015-02-03@02:00 + 0 => 2015-02-03@02:00
|
||||
SET x '2015-02-03@3:00AM' + 0
|
||||
2015-02-03@03:00 + 0 => 2015-02-03@03:00
|
||||
SET x '2015-02-03@4:00am' + 0
|
||||
2015-02-03@04:00 + 0 => 2015-02-03@04:00
|
||||
SET x '2015-02-03@5:00AM' + 0
|
||||
2015-02-03@05:00 + 0 => 2015-02-03@05:00
|
||||
SET x '2015-02-03@6:00am' + 0
|
||||
2015-02-03@06:00 + 0 => 2015-02-03@06:00
|
||||
SET x '2015-02-03@7:00AM' + 0
|
||||
2015-02-03@07:00 + 0 => 2015-02-03@07:00
|
||||
SET x '2015-02-03@8:00am' + 0
|
||||
2015-02-03@08:00 + 0 => 2015-02-03@08:00
|
||||
SET x '2015-02-03@9:00AM' + 0
|
||||
2015-02-03@09:00 + 0 => 2015-02-03@09:00
|
||||
SET x '2015-02-03@10:00am' + 0
|
||||
2015-02-03@10:00 + 0 => 2015-02-03@10:00
|
||||
SET x '2015-02-03@11:00AM' + 0
|
||||
2015-02-03@11:00 + 0 => 2015-02-03@11:00
|
||||
SET x '2015-02-03@12:00am' + 0
|
||||
2015-02-03@00:00 + 0 => 2015-02-03@00:00
|
||||
SET x '2015-02-03@13:00AM' + 0
|
||||
../tests/test.rem(477): Ill-formed time
|
||||
|
||||
SET x '2015-02-03@0:00pm' + 0
|
||||
../tests/test.rem(479): Ill-formed time
|
||||
SET x '2015-02-03@1:00PM' + 0
|
||||
2015-02-03@13:00 + 0 => 2015-02-03@13:00
|
||||
SET x '2015-02-03@2:00pm' + 0
|
||||
2015-02-03@14:00 + 0 => 2015-02-03@14:00
|
||||
SET x '2015-02-03@3:00PM' + 0
|
||||
2015-02-03@15:00 + 0 => 2015-02-03@15:00
|
||||
SET x '2015-02-03@4:00pm' + 0
|
||||
2015-02-03@16:00 + 0 => 2015-02-03@16:00
|
||||
SET x '2015-02-03@5:00PM' + 0
|
||||
2015-02-03@17:00 + 0 => 2015-02-03@17:00
|
||||
SET x '2015-02-03@6:00pm' + 0
|
||||
2015-02-03@18:00 + 0 => 2015-02-03@18:00
|
||||
SET x '2015-02-03@7:00PM' + 0
|
||||
2015-02-03@19:00 + 0 => 2015-02-03@19:00
|
||||
SET x '2015-02-03@8:00pm' + 0
|
||||
2015-02-03@20:00 + 0 => 2015-02-03@20:00
|
||||
SET x '2015-02-03@9:00PM' + 0
|
||||
2015-02-03@21:00 + 0 => 2015-02-03@21:00
|
||||
SET x '2015-02-03@10:00pm' + 0
|
||||
2015-02-03@22:00 + 0 => 2015-02-03@22:00
|
||||
SET x '2015-02-03@11:00PM' + 0
|
||||
2015-02-03@23:00 + 0 => 2015-02-03@23:00
|
||||
SET x '2015-02-03@12:00pm' + 0
|
||||
2015-02-03@12:00 + 0 => 2015-02-03@12:00
|
||||
SET x '2015-02-03@13:00PM' + 0
|
||||
../tests/test.rem(492): Ill-formed time
|
||||
|
||||
# Test the ampm function
|
||||
set x ampm(0:12) + ""
|
||||
ampm(00:12) => "12:12AM"
|
||||
"12:12AM" + "" => "12:12AM"
|
||||
set x ampm(1:12) + ""
|
||||
ampm(01:12) => "1:12AM"
|
||||
"1:12AM" + "" => "1:12AM"
|
||||
set x ampm(2:12) + ""
|
||||
ampm(02:12) => "2:12AM"
|
||||
"2:12AM" + "" => "2:12AM"
|
||||
set x ampm(3:12) + ""
|
||||
ampm(03:12) => "3:12AM"
|
||||
"3:12AM" + "" => "3:12AM"
|
||||
set x ampm(4:12) + ""
|
||||
ampm(04:12) => "4:12AM"
|
||||
"4:12AM" + "" => "4:12AM"
|
||||
set x ampm(5:12) + ""
|
||||
ampm(05:12) => "5:12AM"
|
||||
"5:12AM" + "" => "5:12AM"
|
||||
set x ampm(6:12) + ""
|
||||
ampm(06:12) => "6:12AM"
|
||||
"6:12AM" + "" => "6:12AM"
|
||||
set x ampm(7:12) + ""
|
||||
ampm(07:12) => "7:12AM"
|
||||
"7:12AM" + "" => "7:12AM"
|
||||
set x ampm(8:12) + ""
|
||||
ampm(08:12) => "8:12AM"
|
||||
"8:12AM" + "" => "8:12AM"
|
||||
set x ampm(9:12) + ""
|
||||
ampm(09:12) => "9:12AM"
|
||||
"9:12AM" + "" => "9:12AM"
|
||||
set x ampm(10:12) + ""
|
||||
ampm(10:12) => "10:12AM"
|
||||
"10:12AM" + "" => "10:12AM"
|
||||
set x ampm(11:12) + ""
|
||||
ampm(11:12) => "11:12AM"
|
||||
"11:12AM" + "" => "11:12AM"
|
||||
set x ampm(12:12) + ""
|
||||
ampm(12:12) => "12:12PM"
|
||||
"12:12PM" + "" => "12:12PM"
|
||||
set x ampm(13:12) + ""
|
||||
ampm(13:12) => "1:12PM"
|
||||
"1:12PM" + "" => "1:12PM"
|
||||
set x ampm(14:12) + ""
|
||||
ampm(14:12) => "2:12PM"
|
||||
"2:12PM" + "" => "2:12PM"
|
||||
set x ampm(15:12) + ""
|
||||
ampm(15:12) => "3:12PM"
|
||||
"3:12PM" + "" => "3:12PM"
|
||||
set x ampm(16:12) + ""
|
||||
ampm(16:12) => "4:12PM"
|
||||
"4:12PM" + "" => "4:12PM"
|
||||
set x ampm(17:12) + ""
|
||||
ampm(17:12) => "5:12PM"
|
||||
"5:12PM" + "" => "5:12PM"
|
||||
set x ampm(18:12) + ""
|
||||
ampm(18:12) => "6:12PM"
|
||||
"6:12PM" + "" => "6:12PM"
|
||||
set x ampm(19:12) + ""
|
||||
ampm(19:12) => "7:12PM"
|
||||
"7:12PM" + "" => "7:12PM"
|
||||
set x ampm(20:12) + ""
|
||||
ampm(20:12) => "8:12PM"
|
||||
"8:12PM" + "" => "8:12PM"
|
||||
set x ampm(21:12) + ""
|
||||
ampm(21:12) => "9:12PM"
|
||||
"9:12PM" + "" => "9:12PM"
|
||||
set x ampm(22:12) + ""
|
||||
ampm(22:12) => "10:12PM"
|
||||
"10:12PM" + "" => "10:12PM"
|
||||
set x ampm(23:12) + ""
|
||||
ampm(23:12) => "11:12PM"
|
||||
"11:12PM" + "" => "11:12PM"
|
||||
|
||||
# Coerce with am/pm
|
||||
set x coerce("TIME", "12:45am")
|
||||
coerce("TIME", "12:45am") => 00:45
|
||||
set x coerce("TIME", "12:45")
|
||||
coerce("TIME", "12:45") => 12:45
|
||||
set x coerce("TIME", "1:45pm")
|
||||
coerce("TIME", "1:45pm") => 13:45
|
||||
set x coerce("DATETIME", "2020-05-05@12:45am")
|
||||
coerce("DATETIME", "2020-05-05@12:45am") => 2020-05-05@00:45
|
||||
set x coerce("DATETIME", "2020-05-05@12:45")
|
||||
coerce("DATETIME", "2020-05-05@12:45") => 2020-05-05@12:45
|
||||
set x coerce("DATETIME", "2020-05-05@1:45pm")
|
||||
coerce("DATETIME", "2020-05-05@1:45pm") => 2020-05-05@13:45
|
||||
|
||||
# Don't want Remind to queue reminders
|
||||
EXIT
|
||||
|
||||
Test 2
|
||||
|
||||
|
||||
133
tests/test.rem
133
tests/test.rem
@@ -337,7 +337,7 @@ set a103 trigtimedelta()
|
||||
set a104 trigtimerep()
|
||||
set a105 trigduration()
|
||||
|
||||
REM 2010-09-03 +3 -4 UNTIL 2012-01-01 PRIORITY 7 *14 AT 14:41 +15 *2 DURATION 3:33 MSG foo
|
||||
REM 2010-09-03 +3 -4 UNTIL 2012-01-01 PRIORITY 7 *14 AT 14:41 +15 *2 DURATION 213 MSG foo
|
||||
set a106 trigback()
|
||||
set a107 trigdelta()
|
||||
set a108 trigrep()
|
||||
@@ -386,6 +386,9 @@ OMIT DUMP
|
||||
# Regression test for bugfix in Hebrew calendar Adar jahrzeit
|
||||
[_i(14, "Adar", today(), 5761)] MSG Purim
|
||||
|
||||
# Regression test for bug found by Larry Hynes
|
||||
REM SATISFY [day(trigdate()-25) == 14] MSG Foo
|
||||
|
||||
# Check combo of SATISFY and long-duration events
|
||||
REM 14 SATISFY [$Tw == 4] MSG Thursday, the 14th
|
||||
REM 14 AT 16:00 DURATION 8:00 SATISFY [$Tw == 4] MSG Thursday, the 14th
|
||||
@@ -397,6 +400,134 @@ REM 14 AT 16:00 DURATION 40:00 SATISFY [$Tw == 4] MSG Thursday, the 14th
|
||||
# This is now an error
|
||||
REM DURATION 15:00 MSG Should fail... need AT if you have DURATION.
|
||||
|
||||
# Parsing of AM/PM times
|
||||
REM AT 0:00am MSG foo 0a
|
||||
REM AT 1:00AM MSG foo 1a
|
||||
REM AT 2:00am MSG foo 2a
|
||||
REM AT 3:00AM MSG foo 3a
|
||||
REM AT 4:00am MSG foo 4a
|
||||
REM AT 5:00AM MSG foo 5a
|
||||
REM AT 6:00am MSG foo 6a
|
||||
REM AT 7:00AM MSG foo 7a
|
||||
REM AT 8:00am MSG foo 8a
|
||||
REM AT 9:00AM MSG foo 9a
|
||||
REM AT 10:00am MSG foo 10a
|
||||
REM AT 11:00AM MSG foo 11a
|
||||
REM AT 12:00am MSG foo 12a
|
||||
REM AT 13:00AM MSG foo 13a
|
||||
REM AT 0:00pm MSG foo 0p
|
||||
REM AT 1:00PM MSG foo 1p
|
||||
REM AT 2:00pm MSG foo 2p
|
||||
REM AT 3:00PM MSG foo 3p
|
||||
REM AT 4:00pm MSG foo 4p
|
||||
REM AT 5:00PM MSG foo 5p
|
||||
REM AT 6:00pm MSG foo 6p
|
||||
REM AT 7:00PM MSG foo 7p
|
||||
REM AT 8:00pm MSG foo 8p
|
||||
REM AT 9:00PM MSG foo 9p
|
||||
REM AT 10:00pm MSG foo 10p
|
||||
REM AT 11:00PM MSG foo 11p
|
||||
REM AT 12:00pm MSG foo 12p
|
||||
REM AT 13:00PM MSG foo 13p
|
||||
|
||||
DEBUG +x
|
||||
SET x 0:00am + 0
|
||||
SET x 1:00AM + 0
|
||||
SET x 2:00am + 0
|
||||
SET x 3:00AM + 0
|
||||
SET x 4:00am + 0
|
||||
SET x 5:00AM + 0
|
||||
SET x 6:00am + 0
|
||||
SET x 7:00AM + 0
|
||||
SET x 8:00am + 0
|
||||
SET x 9:00AM + 0
|
||||
SET x 10:00am + 0
|
||||
SET x 11:00AM + 0
|
||||
SET x 12:00am + 0
|
||||
SET x 13:00AM + 0
|
||||
|
||||
SET x 0:00pm + 0
|
||||
SET x 1:00PM + 0
|
||||
SET x 2:00pm + 0
|
||||
SET x 3:00PM + 0
|
||||
SET x 4:00pm + 0
|
||||
SET x 5:00PM + 0
|
||||
SET x 6:00pm + 0
|
||||
SET x 7:00PM + 0
|
||||
SET x 8:00pm + 0
|
||||
SET x 9:00PM + 0
|
||||
SET x 10:00pm + 0
|
||||
SET x 11:00PM + 0
|
||||
SET x 12:00pm + 0
|
||||
SET x 13:00PM + 0
|
||||
|
||||
SET x '2015-02-03@0:00am' + 0
|
||||
SET x '2015-02-03@1:00AM' + 0
|
||||
SET x '2015-02-03@2:00am' + 0
|
||||
SET x '2015-02-03@3:00AM' + 0
|
||||
SET x '2015-02-03@4:00am' + 0
|
||||
SET x '2015-02-03@5:00AM' + 0
|
||||
SET x '2015-02-03@6:00am' + 0
|
||||
SET x '2015-02-03@7:00AM' + 0
|
||||
SET x '2015-02-03@8:00am' + 0
|
||||
SET x '2015-02-03@9:00AM' + 0
|
||||
SET x '2015-02-03@10:00am' + 0
|
||||
SET x '2015-02-03@11:00AM' + 0
|
||||
SET x '2015-02-03@12:00am' + 0
|
||||
SET x '2015-02-03@13:00AM' + 0
|
||||
|
||||
SET x '2015-02-03@0:00pm' + 0
|
||||
SET x '2015-02-03@1:00PM' + 0
|
||||
SET x '2015-02-03@2:00pm' + 0
|
||||
SET x '2015-02-03@3:00PM' + 0
|
||||
SET x '2015-02-03@4:00pm' + 0
|
||||
SET x '2015-02-03@5:00PM' + 0
|
||||
SET x '2015-02-03@6:00pm' + 0
|
||||
SET x '2015-02-03@7:00PM' + 0
|
||||
SET x '2015-02-03@8:00pm' + 0
|
||||
SET x '2015-02-03@9:00PM' + 0
|
||||
SET x '2015-02-03@10:00pm' + 0
|
||||
SET x '2015-02-03@11:00PM' + 0
|
||||
SET x '2015-02-03@12:00pm' + 0
|
||||
SET x '2015-02-03@13:00PM' + 0
|
||||
|
||||
# Test the ampm function
|
||||
set x ampm(0:12) + ""
|
||||
set x ampm(1:12) + ""
|
||||
set x ampm(2:12) + ""
|
||||
set x ampm(3:12) + ""
|
||||
set x ampm(4:12) + ""
|
||||
set x ampm(5:12) + ""
|
||||
set x ampm(6:12) + ""
|
||||
set x ampm(7:12) + ""
|
||||
set x ampm(8:12) + ""
|
||||
set x ampm(9:12) + ""
|
||||
set x ampm(10:12) + ""
|
||||
set x ampm(11:12) + ""
|
||||
set x ampm(12:12) + ""
|
||||
set x ampm(13:12) + ""
|
||||
set x ampm(14:12) + ""
|
||||
set x ampm(15:12) + ""
|
||||
set x ampm(16:12) + ""
|
||||
set x ampm(17:12) + ""
|
||||
set x ampm(18:12) + ""
|
||||
set x ampm(19:12) + ""
|
||||
set x ampm(20:12) + ""
|
||||
set x ampm(21:12) + ""
|
||||
set x ampm(22:12) + ""
|
||||
set x ampm(23:12) + ""
|
||||
|
||||
# Coerce with am/pm
|
||||
set x coerce("TIME", "12:45am")
|
||||
set x coerce("TIME", "12:45")
|
||||
set x coerce("TIME", "1:45pm")
|
||||
set x coerce("DATETIME", "2020-05-05@12:45am")
|
||||
set x coerce("DATETIME", "2020-05-05@12:45")
|
||||
set x coerce("DATETIME", "2020-05-05@1:45pm")
|
||||
|
||||
# Don't want Remind to queue reminders
|
||||
EXIT
|
||||
|
||||
__EOF__
|
||||
REM This line should not even be seen
|
||||
And you can put whatever you like here.
|
||||
|
||||
Reference in New Issue
Block a user