Compare commits

...

31 Commits

Author SHA1 Message Date
Dianne Skoll bf2aabd610 Update release notes. 2024-08-28 15:42:23 -04:00
Dianne Skoll c019221d15 Add diagnostics for missing/bad subst_XXX functions. 2024-08-28 15:15:34 -04:00
Dianne Skoll b7bd6faf07 Warn if SCHED/WARN/OMITFUNC functions take wrong number of args. 2024-08-28 15:02:22 -04:00
Dianne Skoll 80d58220fe In warnings, give file/lineno where function is defined. 2024-08-28 14:59:13 -04:00
Dianne Skoll cd8624e176 Tweak diagnostic messages. 2024-08-28 14:35:49 -04:00
Dianne Skoll 8515fb7ddd Update / clarify manual. 2024-08-28 14:28:34 -04:00
Dianne Skoll 84f9f4ae0a Update tests. 2024-08-28 14:23:14 -04:00
Dianne Skoll e201ebcfa4 Document that logical operators can take any type; add tests. 2024-08-28 14:22:07 -04:00
Dianne Skoll 4e15c3ec35 Remove an optimization that was interfering with expression debugging. 2024-08-28 14:21:44 -04:00
Dianne Skoll 1adccf9b1f Add tests for SCHED/WARN/OMITFUNC functions that don't use their argument. 2024-08-28 13:54:47 -04:00
Dianne Skoll a1aa5c2ad9 Change wording of warning slightly. 2024-08-28 13:54:40 -04:00
Dianne Skoll 1e0d650737 Fix tests. 2024-08-28 13:49:34 -04:00
Dianne Skoll 553d092ca8 Diagnost if WARN/SCHED/OMITFUNC functions don't reference their argument. 2024-08-28 13:49:17 -04:00
Dianne Skoll dc62841517 Fix accidental broken commit. :( 2024-08-28 13:45:42 -04:00
Dianne Skoll 326e7bfc53 Document calendar back-end handling of %_ 2024-08-28 13:23:54 -04:00
Dianne Skoll b9dc7c16ad Use /s modifier on regex. 2024-08-28 13:09:18 -04:00
Dianne Skoll abd54b016b Add tests for newlines in calendars. 2024-08-28 12:56:53 -04:00
Dianne Skoll db02b54067 Collapse multiple whitespace; convert newlines to "<br />" in HTML output. 2024-08-28 12:52:39 -04:00
Dianne Skoll 40a78dfbbb Collapse multiple newlines after all other processing. 2024-08-28 12:52:29 -04:00
Dianne Skoll c860b46baa Collapse multiple runs of whitespace 2024-08-28 12:52:07 -04:00
Dianne Skoll 1458ba8856 Clean up whitespace runs in rem2pdf.
Remind unit tests / tests (push) Successful in 45s
2024-08-28 10:44:41 -04:00
Dianne Skoll 7b9b6ebc96 Preserve %_ newlines in "-C" mode. 2024-08-28 10:14:06 -04:00
Dianne Skoll 7ee4073c7a Document warning on function redefinitiion.
Remind unit tests / tests (push) Successful in 26s
2024-08-27 21:43:46 -04:00
Dianne Skoll 8c072cd9b6 Add a warning if a function is redefined. 2024-08-27 21:41:45 -04:00
Dianne Skoll b794a45c3f Add more SATISFY diagnostics.
Remind unit tests / tests (push) Successful in 34s
2024-08-27 15:02:11 -04:00
Dianne Skoll 98e491ed1d Remove some left-over debugging code. 2024-08-27 15:01:59 -04:00
Dianne Skoll c397cc06da Rewrite code to avoid need to pass address of "mentioned" variable.
Remind unit tests / tests (push) Successful in 30s
2024-08-27 11:33:41 -04:00
Dianne Skoll 8616236b3c Document that SATISFY clauses that don't mention trigdate are diagnosed. 2024-08-27 11:26:13 -04:00
Dianne Skoll 702704af1a Make sure SATISFY expressions are either constant or mention trigdate. 2024-08-27 11:22:42 -04:00
Dianne Skoll a0d1b19050 Fix typo in comment.
Remind unit tests / tests (push) Successful in 39s
2024-08-23 15:08:35 -04:00
Dianne Skoll a5c8ae491c Add test for diagnosing function definitions with too many arguments. 2024-08-23 15:05:24 -04:00
14 changed files with 1047 additions and 95 deletions
+40
View File
@@ -1,5 +1,45 @@
CHANGES TO REMIND
* 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
+57 -16
View File
@@ -1570,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",
@@ -2189,8 +2217,8 @@ also to \fBDATETIME\fR constants.
.PP
.B ZERO VALUES
.PP
The non-string types all have an associated \fIzero\fR value, which is
treated as "false" by the IF command and the logical operators. The
All types have an associated \fIzero value\fR, which is
treated as \fIfalse\fR by the IF command and the logical operators. The
zero values are:
.PP
.RS
@@ -2202,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
@@ -2228,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
@@ -2333,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
@@ -4534,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
@@ -4667,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:
+21 -3
View File
@@ -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) = @_;
+12
View File
@@ -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);
+7
View File
@@ -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"
+2 -4
View File
@@ -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++;
}
+130
View File
@@ -32,6 +32,127 @@ 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 int
ensure_satnode_mentions_trigdate_aux(expr_node *node)
{
char const *name;
expr_node *other;
if (!node) {
return 0;
}
if (node->type == N_BUILTIN_FUNC) {
name = node->u.builtin_func->name;
if (!strcmp(name, "trigdate") ||
!strcmp(name, "trigdatetime")) {
return 1;
}
} 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")) {
return 1;
}
}
if (ensure_satnode_mentions_trigdate_aux(node->child)) {
return 1;
}
other = node->sibling;
while (other) {
if (ensure_satnode_mentions_trigdate_aux(other)) {
return 1;
}
other = other->sibling;
}
return 0;
}
static void ensure_satnode_mentions_trigdate(expr_node *node)
{
int mentioned;
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;
}
mentioned = ensure_satnode_mentions_trigdate_aux(node);
if (!mentioned) {
Wprint("SATISFY: expression has no reference to trigdate() or $T...");
}
}
static int
ComputeTrigDuration(TimeTrig *t)
{
@@ -595,6 +716,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;
}
@@ -1287,6 +1413,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) {
+32 -7
View File
@@ -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), " ");
+1 -1
View File
@@ -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",
+24 -32
View File
@@ -1367,7 +1367,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)
@@ -1394,17 +1394,23 @@ static int logical_not(expr_node *node, Value *locals, Value *ans, int *nonconst
{
int r;
Value v1;
int truthy;
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;
if (v1.type == STR_TYPE) {
if (*(v1.v.str)) {
truthy = 1;
} else {
truthy = 0;
}
} else {
truthy = v1.v.val;
}
ans->type = INT_TYPE;
ans->v.val = !(v1.v.val);
ans->v.val = !(truthy);
DBG(debug_evaluation_unop(ans, OK, &v1, "!"));
DestroyValue(v1);
return OK;
}
@@ -1446,6 +1452,8 @@ static int logical_binop(expr_node *node, Value *locals, Value *ans, int *noncon
Value v;
char const *opname = (is_and) ? "&&" : "||";
int truthy;
/* Evaluate first arg */
int r = evaluate_expr_node(node->child, locals, &v, nonconst);
@@ -1453,21 +1461,25 @@ static int logical_binop(expr_node *node, Value *locals, Value *ans, int *noncon
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 (*(v.v.str)) {
truthy = 1;
} else {
truthy = 0;
}
} else {
truthy = v.v.val;
}
if (is_and) {
/* If first arg is false, return it */
if (!v.v.val) {
if (!truthy) {
*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) {
*ans = v;
DBG(debug_evaluation_binop(ans, OK, &v, NULL, opname));
return OK;
@@ -1476,12 +1488,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 +2175,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);
+3
View File
@@ -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 '(' */
+3
View File
@@ -583,6 +583,9 @@ 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
+612 -32
View File
@@ -783,10 +783,12 @@ Leaving UserFN _ofunc(1991-02-28) => 0
# omitfunc ignores local/global omits
fset _ofunc(x) 0
../tests/test.rem(223): Function _ofunc redefined (previously defined at ../tests/test.rem:218)
OMIT 1 March
OMIT 2 March 1991
REM 1 March OMIT Sun OMITFUNC _ofunc AFTER MSG Should trigger 1 March
../tests/test.rem(226): Warning: OMIT is ignored if you use OMITFUNC
../tests/test.rem(226): OMITFUNC function `_ofunc' defined at ../tests/test.rem:223 does not use its argument
Entering UserFN _ofunc(1991-02-15)
Leaving UserFN _ofunc(1991-02-15) => 0
Entering UserFN _ofunc(1991-03-01)
@@ -862,6 +864,7 @@ set $Location "Ottawa"
set $MaxSatIter 150
set $MaxStringLen 65535
set $MinsFromUTC -300
- 300 => -300
set $SubsIndent 0
set $TimeSep ":"
@@ -869,12 +872,14 @@ set $LatDeg 30
set $LatMin 30
set $LatSec 0
set $LongDeg -25
- 25 => -25
set $LongMin 15
set $LongSec 0
set a000 abs(1)
abs(1) => 1
set a001 abs(-1)
- 1 => -1
abs(-1) => 1
set a002 asc("foo")
asc("foo") => 102
@@ -991,6 +996,7 @@ plural(2, "ies") => "iess"
set a046 plural(2, "y", "ies")
plural(2, "y", "ies") => "ies"
set a047 sgn(-2)
- 2 => -2
sgn(-2) => -1
set a048 shell("echo foo")
shell("echo foo") => "foo"
@@ -1227,6 +1233,7 @@ OMIT 1991-03-11
set a082 slide('1991-03-01', 7, "Sat", "Sun")
slide(1991-03-01, 7, "Sat", "Sun") => 1991-03-13
set a083 slide('1991-04-01', -7, "Sat")
- 7 => -7
slide(1991-04-01, -7, "Sat") => 1991-03-24
set a084 nonomitted('1991-03-01', '1991-03-13', "Sat", "Sun")
nonomitted(1991-03-01, 1991-03-13, "Sat", "Sun") => 7
@@ -3847,6 +3854,7 @@ $IntMin => -2147483648
../tests/test.rem(774): `-': Number too high
set a $IntMax - (-1)
$IntMax => 2147483647
- 1 => -1
2147483647 - -1 => Number too high
../tests/test.rem(775): `-': Number too high
set a $IntMax + 1
@@ -3860,6 +3868,7 @@ $IntMax => 2147483647
../tests/test.rem(777): `+': Number too high
set a $IntMin + (-1)
$IntMin => -2147483648
- 1 => -1
-2147483648 + -1 => Number too high
../tests/test.rem(778): `+': Number too high
set a $IntMin + $IntMin
@@ -3897,13 +3906,16 @@ $IntMax => 2147483647
../tests/test.rem(785): `*': Number too high
set a $IntMin / (-1)
$IntMin => -2147483648
- 1 => -1
-2147483648 / -1 => Number too high
../tests/test.rem(786): `/': Number too high
set a $IntMin * (-1)
$IntMin => -2147483648
- 1 => -1
-2147483648 * -1 => Number too high
../tests/test.rem(787): `*': Number too high
set a (-1) * $IntMin
- 1 => -1
$IntMin => -2147483648
-1 * -2147483648 => Number too high
../tests/test.rem(788): `*': Number too high
@@ -3954,7 +3966,8 @@ psmoon(0) => ../tests/test.rem(809): psmoon() is deprecated; use SPECIAL MOON in
FSET _f(x) 0
SET tmp evaltrig("Wed SKIP OMITFUNC _f",date(1992,1,8))
date(1992, 1, 8) => 1992-01-08
evaltrig("Wed SKIP OMITFUNC _f", 1992-01-08) => Entering UserFN _f(1992-01-08)
evaltrig("Wed SKIP OMITFUNC _f", 1992-01-08) => ../tests/test.rem(813): OMITFUNC function `_f' defined at ../tests/test.rem:812 does not use its argument
Entering UserFN _f(1992-01-08)
Leaving UserFN _f(1992-01-08) => 0
../tests/test.rem(813): Trig = Wednesday, 8 January, 1992
1992-01-08
@@ -3999,6 +4012,7 @@ ENDIF
# Trig with a good warnfunc
FSET w(x) choose(x, 5, 3, 1, 0)
../tests/test.rem(828): Function w redefined (previously defined at ../tests/test.rem:822)
# Short-circuit operators
IF trig("sun warn w") || trig("thu warn w")
@@ -4936,6 +4950,29 @@ Leaving UserFN subst_custom(0, 1991-02-16, 12:13) => "Custom: a=0; d=1991-02-16;
Bad: Custom: a=0; d=1991-02-16; t=12:13
REM MSG Undefined: %{nopity_nope_nope}
../tests/test.rem(925): Trig = Saturday, 16 February, 1991
../tests/test.rem(925): No substition function `subst_nopity_nope_nope' defined
Undefined:
# Bad substitution functions
FSET subst_bad() "foo"
REM MSG %{bad}
../tests/test.rem(929): Trig = Saturday, 16 February, 1991
../tests/test.rem(929): Function `subst_bad' defined at ../tests/test.rem:928 should take 3 arguments, but actually takes 0
FSET subst_ampm(a, b, c, d, e, f, g) "wookie"
REM AT 11:00 MSG %2
../tests/test.rem(933): Trig = Saturday, 16 February, 1991 AT 11:00
../tests/test.rem(933): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(933): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
at 11:00am
# Test FUNSET
FSET square(x) x*x
SET a square(5)
@@ -4950,27 +4987,33 @@ FUNSET circle square rectangle
# Should fail
SET a square(5)
../tests/test.rem(933): Undefined function: `square'
../tests/test.rem(943): Undefined function: `square'
# htmlescape
set a htmlescape("foo")
htmlescape("foo") => "foo"
REM MSG [a]
../tests/test.rem(937): Trig = Saturday, 16 February, 1991
../tests/test.rem(947): Trig = Saturday, 16 February, 1991
../tests/test.rem(947): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(947): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
a => "foo"
foo
set a htmlescape("<&>")
htmlescape("<&>") => "&lt;&amp;&gt;"
REM MSG [a]
../tests/test.rem(939): Trig = Saturday, 16 February, 1991
../tests/test.rem(949): Trig = Saturday, 16 February, 1991
../tests/test.rem(949): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(949): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
a => "&lt;&amp;&gt;"
&lt;&amp;&gt;
set a htmlescape("@&^#*@&^##$*&@><><@#@#><@#>%%_#$foobarquux")
htmlescape("@&^#*@&^##$*&@><><@#@#><@#>%%_#$foobarqu"...) => "@&amp;^#*@&amp;^##$*&amp;@&gt;&lt;&gt;&l"...
REM MSG [a]
../tests/test.rem(941): Trig = Saturday, 16 February, 1991
../tests/test.rem(951): Trig = Saturday, 16 February, 1991
../tests/test.rem(951): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(951): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
a => "@&amp;^#*@&amp;^##$*&amp;@&gt;&lt;&gt;&l"...
@&amp;^#*@&amp;^##$*&amp;@&gt;&lt;&gt;&lt;@#@#&gt;&lt;@#&gt;%_#$foobarquux
@@ -4989,22 +5032,24 @@ htmlstriptags("<img src=\"foo\">") => ""
# $ParseUntriggered
REM 2 Jan 1990 MSG ["bad_expr" / 2]
../tests/test.rem(951): Expired
../tests/test.rem(961): Expired
"bad_expr" / 2 => Type mismatch
../tests/test.rem(951): `/': Type mismatch
../tests/test.rem(961): `/': Type mismatch
SET $ParseUntriggered 0
REM 2 Jan 1990 MSG ["bad_expr" / 2]
../tests/test.rem(953): Expired
../tests/test.rem(963): Expired
SET $ParseUntriggered 1
# String multiplication
set a "low" * (-1)
- 1 => -1
"low" * -1 => Number too low
../tests/test.rem(958): `*': Number too low
../tests/test.rem(968): `*': Number too low
set a (-1) * "low"
- 1 => -1
-1 * "low" => Number too low
../tests/test.rem(959): `*': Number too low
../tests/test.rem(969): `*': Number too low
set a "zero" * 0
"zero" * 0 => ""
@@ -5019,10 +5064,10 @@ set a 10000000 * ""
# Too long for default limits
set a "wookie" * 1000000
"wookie" * 1000000 => String too long
../tests/test.rem(968): `*': String too long
../tests/test.rem(978): `*': String too long
set a 1000000 * "wookie"
1000000 * "wookie" => String too long
../tests/test.rem(969): `*': String too long
../tests/test.rem(979): `*': String too long
set a "Cabbage! " * 7
"Cabbage! " * 7 => "Cabbage! Cabbage! Cabbage! Cabbage! Cabb"...
@@ -5032,70 +5077,523 @@ set a 7 * "Cabbage! "
# Should result in errors
set pqxya 1+2)
1 + 2 => 3
../tests/test.rem(975): Expecting end-of-line
../tests/test.rem(985): Expecting end-of-line
# Should result in an error
REM Tue OMIT 2024-01-01 MSG Wookie
../tests/test.rem(978): Expecting weekday name
../tests/test.rem(988): Expecting weekday name
# No error
REM Tue OMIT Wed 2024-01-01 MSG Blort
../tests/test.rem(981): Trig = Tuesday, 2 January, 2024
../tests/test.rem(991): Trig = Tuesday, 2 January, 2024
# Make sure trigtime() is not reset between invocations
REM Tue AT 16:00 DURATION 30 MSG Thing One
../tests/test.rem(984): Trig = Tuesday, 19 February, 1991 AT 16:00 DURATION 00:30
../tests/test.rem(994): Trig = Tuesday, 19 February, 1991 AT 16:00 DURATION 00:30
REM [$T] AT [trigtime()+trigduration()] DURATION 15 MSG Thing Two
$T => 1991-02-19
trigtime() => 16:00
trigduration() => 00:30
16:00 + 00:30 => 16:30
../tests/test.rem(985): Trig = Tuesday, 19 February, 1991 AT 16:30 DURATION 00:15
../tests/test.rem(995): Trig = Tuesday, 19 February, 1991 AT 16:30 DURATION 00:15
REM [$T] AT [$Tt+trigduration()] DURATION 30 MSG Thing Three
$T => 1991-02-19
$Tt => 16:30
trigduration() => 00:15
16:30 + 00:15 => 16:45
../tests/test.rem(986): Trig = Tuesday, 19 February, 1991 AT 16:45 DURATION 00:30
../tests/test.rem(996): Trig = Tuesday, 19 February, 1991 AT 16:45 DURATION 00:30
REM [$T] AT [trigtime()+trigduration()] DURATION 10 MSG Last Thing
$T => 1991-02-19
trigtime() => 16:45
trigduration() => 00:30
16:45 + 00:30 => 17:15
../tests/test.rem(987): Trig = Tuesday, 19 February, 1991 AT 17:15 DURATION 00:10
../tests/test.rem(997): Trig = Tuesday, 19 February, 1991 AT 17:15 DURATION 00:10
# Make sure trigtime is not reset during parsing
REM Tue AT 16:00 MSG blort
../tests/test.rem(990): Trig = Tuesday, 19 February, 1991 AT 16:00
../tests/test.rem(1000): Trig = Tuesday, 19 February, 1991 AT 16:00
REM Tue AT 10:00 DURATION [$Tt] MSG blort
$Tt => 16:00
../tests/test.rem(991): Trig = Tuesday, 19 February, 1991 AT 10:00 DURATION 16:00
../tests/test.rem(991): Trig = Tuesday, 19 February, 1991 AT 10:00 DURATION 16:00
../tests/test.rem(1001): Trig = Tuesday, 19 February, 1991 AT 10:00 DURATION 16:00
../tests/test.rem(1001): Trig = Tuesday, 19 February, 1991 AT 10:00 DURATION 16:00
REM Tue AT 16:00 MSG blort
../tests/test.rem(992): Trig = Tuesday, 19 February, 1991 AT 16:00
../tests/test.rem(1002): Trig = Tuesday, 19 February, 1991 AT 16:00
REM Tue AT 10:00 DURATION [trigtime()] MSG blort
trigtime() => 16:00
../tests/test.rem(993): Trig = Tuesday, 19 February, 1991 AT 10:00 DURATION 16:00
../tests/test.rem(993): Trig = Tuesday, 19 February, 1991 AT 10:00 DURATION 16:00
../tests/test.rem(1003): Trig = Tuesday, 19 February, 1991 AT 10:00 DURATION 16:00
../tests/test.rem(1003): Trig = Tuesday, 19 February, 1991 AT 10:00 DURATION 16:00
# Make sure shellescape does not mangle UTF-8 characters
msg [shellescape("😆")]
../tests/test.rem(996): Trig = Saturday, 16 February, 1991
../tests/test.rem(1006): Trig = Saturday, 16 February, 1991
../tests/test.rem(1006): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1006): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
shellescape("😆") => "😆"
😆
This should be diagnosed as implicitly being REM
../tests/test.rem(998): Unrecognized command; interpreting as REM
../tests/test.rem(998): Trig = Saturday, 16 February, 1991
../tests/test.rem(1008): Unrecognized command; interpreting as REM
../tests/test.rem(1008): Trig = Saturday, 16 February, 1991
../tests/test.rem(1008): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1008): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
This should be diagnosed as implicitly being REM
REM This should be diganosed as implicitly being MSG-type
../tests/test.rem(999): Missing REM type; assuming MSG
../tests/test.rem(999): Trig = Saturday, 16 February, 1991
../tests/test.rem(1009): Missing REM type; assuming MSG
../tests/test.rem(1009): Trig = Saturday, 16 February, 1991
../tests/test.rem(1009): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1009): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
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
../tests/test.rem(1018): Function f redefined (previously defined at ../tests/test.rem:1015)
../tests/test.rem(1018): Too many arguments
# Check that SATISFY expressions that don't reference trigdate are diagnosed
# These should all NOT be diagnosed
set x 3
REM SATISFY 1
../tests/test.rem(1024): Trig = Saturday, 16 February, 1991
../tests/test.rem(1024): Trig(satisfied) = Saturday, 16 February, 1991
REM SATISFY trigdate() > '1990-01-01'
../tests/test.rem(1025): Trig = Saturday, 16 February, 1991
trigdate() => 1991-02-16
1991-02-16 > 1990-01-01 => 1
../tests/test.rem(1025): Trig(satisfied) = Saturday, 16 February, 1991
REM AT 23:59 SATISFY trigdatetime() > '1990-01-01@12:00'
../tests/test.rem(1026): Trig = Saturday, 16 February, 1991 AT 23:59
trigdatetime() => 1991-02-16@23:59
1991-02-16@23:59 > 1990-01-01@12:00 => 1
../tests/test.rem(1026): Trig(satisfied) = Saturday, 16 February, 1991 AT 23:59
REM SATISFY $T > '1990-01-01'
../tests/test.rem(1027): Trig = Saturday, 16 February, 1991
$T => 1991-02-16
1991-02-16 > 1990-01-01 => 1
../tests/test.rem(1027): Trig(satisfied) = Saturday, 16 February, 1991
REM SATISFY $Ty > 1990
../tests/test.rem(1028): Trig = Saturday, 16 February, 1991
$Ty => 1991
1991 > 1990 => 1
../tests/test.rem(1028): Trig(satisfied) = Saturday, 16 February, 1991
REM SATISFY $Tm > 0
../tests/test.rem(1029): Trig = Saturday, 16 February, 1991
$Tm => 2
2 > 0 => 1
../tests/test.rem(1029): Trig(satisfied) = Saturday, 16 February, 1991
REM SATISFY $Td > 0
../tests/test.rem(1030): Trig = Saturday, 16 February, 1991
$Td => 16
16 > 0 => 1
../tests/test.rem(1030): Trig(satisfied) = Saturday, 16 February, 1991
REM SATISFY $Tw > -1
../tests/test.rem(1031): Trig = Saturday, 16 February, 1991
$Tw => 6
- 1 => -1
6 > -1 => 1
../tests/test.rem(1031): Trig(satisfied) = Saturday, 16 February, 1991
REM SATISFY [max(x, max(x, 1, 2, 3), 4, 5, 6) * max(5, $Td)]
../tests/test.rem(1032): Trig = Saturday, 16 February, 1991
x => 3
x => 3
max(3, 1, 2, 3) => 3
max(3, 3, 4, 5, 6) => 6
$Td => 16
max(5, 16) => 16
6 * 16 => 96
../tests/test.rem(1032): Trig(satisfied) = Saturday, 16 February, 1991
# These should be diagnosed
REM SATISFY 0
../tests/test.rem(1035): SATISFY: constant 0 will never be true
../tests/test.rem(1035): Trig = Saturday, 16 February, 1991
../tests/test.rem(1035): Trig = Sunday, 17 February, 1991
../tests/test.rem(1035): Trig = Monday, 18 February, 1991
../tests/test.rem(1035): Trig = Tuesday, 19 February, 1991
../tests/test.rem(1035): Trig = Wednesday, 20 February, 1991
../tests/test.rem(1035): Trig = Thursday, 21 February, 1991
../tests/test.rem(1035): Trig = Friday, 22 February, 1991
../tests/test.rem(1035): Trig = Saturday, 23 February, 1991
../tests/test.rem(1035): Trig = Sunday, 24 February, 1991
../tests/test.rem(1035): Trig = Monday, 25 February, 1991
../tests/test.rem(1035): Trig = Tuesday, 26 February, 1991
../tests/test.rem(1035): Trig = Wednesday, 27 February, 1991
../tests/test.rem(1035): Trig = Thursday, 28 February, 1991
../tests/test.rem(1035): Trig = Friday, 1 March, 1991
../tests/test.rem(1035): Trig = Saturday, 2 March, 1991
../tests/test.rem(1035): Trig = Sunday, 3 March, 1991
../tests/test.rem(1035): Trig = Monday, 4 March, 1991
../tests/test.rem(1035): Trig = Tuesday, 5 March, 1991
../tests/test.rem(1035): Trig = Wednesday, 6 March, 1991
../tests/test.rem(1035): Trig = Thursday, 7 March, 1991
../tests/test.rem(1035): Trig = Friday, 8 March, 1991
../tests/test.rem(1035): Trig = Saturday, 9 March, 1991
../tests/test.rem(1035): Trig = Sunday, 10 March, 1991
../tests/test.rem(1035): Trig = Monday, 11 March, 1991
../tests/test.rem(1035): Trig = Tuesday, 12 March, 1991
../tests/test.rem(1035): Trig = Wednesday, 13 March, 1991
../tests/test.rem(1035): Trig = Thursday, 14 March, 1991
../tests/test.rem(1035): Trig = Friday, 15 March, 1991
../tests/test.rem(1035): Trig = Saturday, 16 March, 1991
../tests/test.rem(1035): Trig = Sunday, 17 March, 1991
../tests/test.rem(1035): Trig = Monday, 18 March, 1991
../tests/test.rem(1035): Trig = Tuesday, 19 March, 1991
../tests/test.rem(1035): Trig = Wednesday, 20 March, 1991
../tests/test.rem(1035): Trig = Thursday, 21 March, 1991
../tests/test.rem(1035): Trig = Friday, 22 March, 1991
../tests/test.rem(1035): Trig = Saturday, 23 March, 1991
../tests/test.rem(1035): Trig = Sunday, 24 March, 1991
../tests/test.rem(1035): Trig = Monday, 25 March, 1991
../tests/test.rem(1035): Trig = Tuesday, 26 March, 1991
../tests/test.rem(1035): Trig = Wednesday, 27 March, 1991
../tests/test.rem(1035): Trig = Thursday, 28 March, 1991
../tests/test.rem(1035): Trig = Friday, 29 March, 1991
../tests/test.rem(1035): Trig = Saturday, 30 March, 1991
../tests/test.rem(1035): Trig = Sunday, 31 March, 1991
../tests/test.rem(1035): Trig = Monday, 1 April, 1991
../tests/test.rem(1035): Trig = Tuesday, 2 April, 1991
../tests/test.rem(1035): Trig = Wednesday, 3 April, 1991
../tests/test.rem(1035): Trig = Thursday, 4 April, 1991
../tests/test.rem(1035): Trig = Friday, 5 April, 1991
../tests/test.rem(1035): Trig = Saturday, 6 April, 1991
../tests/test.rem(1035): Trig = Sunday, 7 April, 1991
../tests/test.rem(1035): Trig = Monday, 8 April, 1991
../tests/test.rem(1035): Trig = Tuesday, 9 April, 1991
../tests/test.rem(1035): Trig = Wednesday, 10 April, 1991
../tests/test.rem(1035): Trig = Thursday, 11 April, 1991
../tests/test.rem(1035): Trig = Friday, 12 April, 1991
../tests/test.rem(1035): Trig = Saturday, 13 April, 1991
../tests/test.rem(1035): Trig = Sunday, 14 April, 1991
../tests/test.rem(1035): Trig = Monday, 15 April, 1991
../tests/test.rem(1035): Trig = Tuesday, 16 April, 1991
../tests/test.rem(1035): Trig = Wednesday, 17 April, 1991
../tests/test.rem(1035): Trig = Thursday, 18 April, 1991
../tests/test.rem(1035): Trig = Friday, 19 April, 1991
../tests/test.rem(1035): Trig = Saturday, 20 April, 1991
../tests/test.rem(1035): Trig = Sunday, 21 April, 1991
../tests/test.rem(1035): Trig = Monday, 22 April, 1991
../tests/test.rem(1035): Trig = Tuesday, 23 April, 1991
../tests/test.rem(1035): Trig = Wednesday, 24 April, 1991
../tests/test.rem(1035): Trig = Thursday, 25 April, 1991
../tests/test.rem(1035): Trig = Friday, 26 April, 1991
../tests/test.rem(1035): Trig = Saturday, 27 April, 1991
../tests/test.rem(1035): Trig = Sunday, 28 April, 1991
../tests/test.rem(1035): Trig = Monday, 29 April, 1991
../tests/test.rem(1035): Trig = Tuesday, 30 April, 1991
../tests/test.rem(1035): Trig = Wednesday, 1 May, 1991
../tests/test.rem(1035): Trig = Thursday, 2 May, 1991
../tests/test.rem(1035): Trig = Friday, 3 May, 1991
../tests/test.rem(1035): Trig = Saturday, 4 May, 1991
../tests/test.rem(1035): Trig = Sunday, 5 May, 1991
../tests/test.rem(1035): Trig = Monday, 6 May, 1991
../tests/test.rem(1035): Trig = Tuesday, 7 May, 1991
../tests/test.rem(1035): Trig = Wednesday, 8 May, 1991
../tests/test.rem(1035): Trig = Thursday, 9 May, 1991
../tests/test.rem(1035): Trig = Friday, 10 May, 1991
../tests/test.rem(1035): Trig = Saturday, 11 May, 1991
../tests/test.rem(1035): Trig = Sunday, 12 May, 1991
../tests/test.rem(1035): Trig = Monday, 13 May, 1991
../tests/test.rem(1035): Trig = Tuesday, 14 May, 1991
../tests/test.rem(1035): Trig = Wednesday, 15 May, 1991
../tests/test.rem(1035): Trig = Thursday, 16 May, 1991
../tests/test.rem(1035): Trig = Friday, 17 May, 1991
../tests/test.rem(1035): Trig = Saturday, 18 May, 1991
../tests/test.rem(1035): Trig = Sunday, 19 May, 1991
../tests/test.rem(1035): Trig = Monday, 20 May, 1991
../tests/test.rem(1035): Trig = Tuesday, 21 May, 1991
../tests/test.rem(1035): Trig = Wednesday, 22 May, 1991
../tests/test.rem(1035): Trig = Thursday, 23 May, 1991
../tests/test.rem(1035): Trig = Friday, 24 May, 1991
../tests/test.rem(1035): Trig = Saturday, 25 May, 1991
../tests/test.rem(1035): Trig = Sunday, 26 May, 1991
../tests/test.rem(1035): Trig = Monday, 27 May, 1991
../tests/test.rem(1035): Trig = Tuesday, 28 May, 1991
../tests/test.rem(1035): Trig = Wednesday, 29 May, 1991
../tests/test.rem(1035): Trig = Thursday, 30 May, 1991
../tests/test.rem(1035): Trig = Friday, 31 May, 1991
../tests/test.rem(1035): Trig = Saturday, 1 June, 1991
../tests/test.rem(1035): Trig = Sunday, 2 June, 1991
../tests/test.rem(1035): Trig = Monday, 3 June, 1991
../tests/test.rem(1035): Trig = Tuesday, 4 June, 1991
../tests/test.rem(1035): Trig = Wednesday, 5 June, 1991
../tests/test.rem(1035): Trig = Thursday, 6 June, 1991
../tests/test.rem(1035): Trig = Friday, 7 June, 1991
../tests/test.rem(1035): Trig = Saturday, 8 June, 1991
../tests/test.rem(1035): Trig = Sunday, 9 June, 1991
../tests/test.rem(1035): Trig = Monday, 10 June, 1991
../tests/test.rem(1035): Trig = Tuesday, 11 June, 1991
../tests/test.rem(1035): Trig = Wednesday, 12 June, 1991
../tests/test.rem(1035): Trig = Thursday, 13 June, 1991
../tests/test.rem(1035): Trig = Friday, 14 June, 1991
../tests/test.rem(1035): Trig = Saturday, 15 June, 1991
../tests/test.rem(1035): Trig = Sunday, 16 June, 1991
../tests/test.rem(1035): Trig = Monday, 17 June, 1991
../tests/test.rem(1035): Trig = Tuesday, 18 June, 1991
../tests/test.rem(1035): Trig = Wednesday, 19 June, 1991
../tests/test.rem(1035): Trig = Thursday, 20 June, 1991
../tests/test.rem(1035): Trig = Friday, 21 June, 1991
../tests/test.rem(1035): Trig = Saturday, 22 June, 1991
../tests/test.rem(1035): Trig = Sunday, 23 June, 1991
../tests/test.rem(1035): Trig = Monday, 24 June, 1991
../tests/test.rem(1035): Trig = Tuesday, 25 June, 1991
../tests/test.rem(1035): Trig = Wednesday, 26 June, 1991
../tests/test.rem(1035): Trig = Thursday, 27 June, 1991
../tests/test.rem(1035): Trig = Friday, 28 June, 1991
../tests/test.rem(1035): Trig = Saturday, 29 June, 1991
../tests/test.rem(1035): Trig = Sunday, 30 June, 1991
../tests/test.rem(1035): Trig = Monday, 1 July, 1991
../tests/test.rem(1035): Trig = Tuesday, 2 July, 1991
../tests/test.rem(1035): Trig = Wednesday, 3 July, 1991
../tests/test.rem(1035): Trig = Thursday, 4 July, 1991
../tests/test.rem(1035): Trig = Friday, 5 July, 1991
../tests/test.rem(1035): Trig = Saturday, 6 July, 1991
../tests/test.rem(1035): Trig = Sunday, 7 July, 1991
../tests/test.rem(1035): Trig = Monday, 8 July, 1991
../tests/test.rem(1035): Trig = Tuesday, 9 July, 1991
../tests/test.rem(1035): Trig = Wednesday, 10 July, 1991
../tests/test.rem(1035): Trig = Thursday, 11 July, 1991
../tests/test.rem(1035): Trig = Friday, 12 July, 1991
../tests/test.rem(1035): Trig = Saturday, 13 July, 1991
../tests/test.rem(1035): Trig = Sunday, 14 July, 1991
../tests/test.rem(1035): Trig = Monday, 15 July, 1991
../tests/test.rem(1035): Can't compute trigger
REM SATSIFY ""
../tests/test.rem(1036): Missing REM type; assuming MSG
../tests/test.rem(1036): Trig = Saturday, 16 February, 1991
../tests/test.rem(1036): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1036): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
SATSIFY ""
REM SATISFY [version() > "01.00.00"]
../tests/test.rem(1037): SATISFY: expression has no reference to trigdate() or $T...
../tests/test.rem(1037): Trig = Saturday, 16 February, 1991
version() => "05.00.03"
"05.00.03" > "01.00.00" => 1
../tests/test.rem(1037): Trig(satisfied) = Saturday, 16 February, 1991
REM SATISFY [max(x, max(x, 1, 2, 3), 4, 5, 6) * 5]
../tests/test.rem(1038): SATISFY: expression has no reference to trigdate() or $T...
../tests/test.rem(1038): Trig = Saturday, 16 February, 1991
x => 3
x => 3
max(3, 1, 2, 3) => 3
max(3, 3, 4, 5, 6) => 6
6 * 5 => 30
../tests/test.rem(1038): Trig(satisfied) = Saturday, 16 February, 1991
FSET gg(x) 0
REM WARN gg MSG Wookie
../tests/test.rem(1041): WARN function `gg' defined at ../tests/test.rem:1040 does not use its argument
../tests/test.rem(1041): Trig = Saturday, 16 February, 1991
Entering UserFN gg(1)
Leaving UserFN gg(1) => 0
../tests/test.rem(1041): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1041): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
Wookie
REM AT 11:00 SCHED gg MSG blork
../tests/test.rem(1042): SCHED function `gg' defined at ../tests/test.rem:1040 does not use its argument
../tests/test.rem(1042): Trig = Saturday, 16 February, 1991 AT 11:00
../tests/test.rem(1042): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1042): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
blork
REM OMITFUNC gg MSG hehe
../tests/test.rem(1043): OMITFUNC function `gg' defined at ../tests/test.rem:1040 does not use its argument
../tests/test.rem(1043): Trig = Saturday, 16 February, 1991
../tests/test.rem(1043): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1043): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
hehe
FSET gg(x,y,z) 0
../tests/test.rem(1045): Function gg redefined (previously defined at ../tests/test.rem:1040)
REM WARN gg MSG Wookie
../tests/test.rem(1046): WARN function `gg' defined at ../tests/test.rem:1045 should take 1 argument but actually takes 3
../tests/test.rem(1046): Trig = Saturday, 16 February, 1991
../tests/test.rem(1046): Undefined WARN function: `gg'
../tests/test.rem(1046): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1046): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
Wookie
REM AT 11:00 SCHED gg MSG blork
../tests/test.rem(1047): SCHED function `gg' defined at ../tests/test.rem:1045 should take 1 argument but actually takes 3
../tests/test.rem(1047): Trig = Saturday, 16 February, 1991 AT 11:00
../tests/test.rem(1047): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1047): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
blork
REM OMITFUNC gg MSG hehe
../tests/test.rem(1048): OMITFUNC function `gg' defined at ../tests/test.rem:1045 should take 1 argument but actually takes 3
../tests/test.rem(1048): Trig = Saturday, 16 February, 1991
../tests/test.rem(1048): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1048): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
hehe
FSET gg() 0
../tests/test.rem(1050): Function gg redefined (previously defined at ../tests/test.rem:1045)
REM WARN gg MSG Wookie
../tests/test.rem(1051): WARN function `gg' defined at ../tests/test.rem:1050 should take 1 argument but actually takes 0
../tests/test.rem(1051): Trig = Saturday, 16 February, 1991
../tests/test.rem(1051): Undefined WARN function: `gg'
../tests/test.rem(1051): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1051): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
Wookie
REM AT 11:00 SCHED gg MSG blork
../tests/test.rem(1052): SCHED function `gg' defined at ../tests/test.rem:1050 should take 1 argument but actually takes 0
../tests/test.rem(1052): Trig = Saturday, 16 February, 1991 AT 11:00
../tests/test.rem(1052): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1052): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
blork
REM OMITFUNC gg MSG hehe
../tests/test.rem(1053): OMITFUNC function `gg' defined at ../tests/test.rem:1050 should take 1 argument but actually takes 0
../tests/test.rem(1053): Trig = Saturday, 16 February, 1991
../tests/test.rem(1053): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1053): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
hehe
FSET gg(x) x-x
../tests/test.rem(1055): Function gg redefined (previously defined at ../tests/test.rem:1050)
REM WARN gg MSG Wookie
../tests/test.rem(1056): Trig = Saturday, 16 February, 1991
Entering UserFN gg(1)
x => 1
x => 1
1 - 1 => 0
Leaving UserFN gg(1) => 0
../tests/test.rem(1056): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1056): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
Wookie
REM AT 11:00 SCHED gg MSG blork
../tests/test.rem(1057): Trig = Saturday, 16 February, 1991 AT 11:00
../tests/test.rem(1057): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1057): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
blork
REM OMITFUNC gg MSG hehe
../tests/test.rem(1058): Trig = Saturday, 16 February, 1991
../tests/test.rem(1058): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1058): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
hehe
REM WARN not_defined MSG Wookie
../tests/test.rem(1060): Trig = Saturday, 16 February, 1991
../tests/test.rem(1060): Undefined WARN function: `not_defined'
../tests/test.rem(1060): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1060): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
Wookie
REM AT 11:00 SCHED not_defined MSG blork
../tests/test.rem(1061): Undefined SCHED function: `not_defined'
../tests/test.rem(1061): Trig = Saturday, 16 February, 1991 AT 11:00
../tests/test.rem(1061): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1061): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
blork
REM OMITFUNC not_defined MSG hehe
../tests/test.rem(1062): Undefined OMITFUNC function: `not_defined'
../tests/test.rem(1062): Trig = Saturday, 16 February, 1991
../tests/test.rem(1062): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
../tests/test.rem(1062): Function `subst_ampm' defined at ../tests/test.rem:931 should take 1 argument, but actually takes 7
hehe
### Strings in logical operators
SET logstr "" && 7
"" && ? => ""
SET logstr "foo" && 7
"foo" && 7 => 7
SET logstr "" && ""
"" && ? => ""
SET logstr "foo" && ""
"foo" && "" => ""
SET logstr "" && "bar"
"" && ? => ""
SET logstr "foo" && "bar"
"foo" && "bar" => "bar"
SET logstr "" && '2023-02-01'
"" && ? => ""
SET logstr "foo" && '2023-02-01'
"foo" && 2023-02-01 => 2023-02-01
SET logstr "" || 7
"" || 7 => 7
SET logstr "foo" || 7
"foo" || ? => "foo"
SET logstr "" || ""
"" || "" => ""
SET logstr "foo" || ""
"foo" || ? => "foo"
SET logstr "" || "bar"
"" || "bar" => "bar"
SET logstr "foo" || "bar"
"foo" || ? => "foo"
SET logstr "" || '2023-02-01'
"" || 2023-02-01 => 2023-02-01
SET logstr "foo" || '2023-02-01'
"foo" || ? => "foo"
set xyz ! 0
! 0 => 1
set xyz ! 1
! 1 => 0
set xyz ! 2
! 2 => 0
set xyz ! date(baseyr(), 1, 1)
baseyr() => 1990
date(1990, 1, 1) => 1990-01-01
! 1990-01-01 => 1
set xyz ! date(baseyr(), 1, 2)
baseyr() => 1990
date(1990, 1, 2) => 1990-01-02
! 1990-01-02 => 0
set xyz ! '2024-01-01'
! 2024-01-01 => 0
set xyz ! datetime(baseyr(), 1, 1, 00:00)
baseyr() => 1990
datetime(1990, 1, 1, 00:00) => 1990-01-01@00:00
! 1990-01-01@00:00 => 1
set xyz ! datetime(baseyr(), 1, 1, 00:01)
baseyr() => 1990
datetime(1990, 1, 1, 00:01) => 1990-01-01@00:01
! 1990-01-01@00:01 => 0
set xyz ! datetime(baseyr(), 1, 2, 12:30)
baseyr() => 1990
datetime(1990, 1, 2, 12:30) => 1990-01-02@12:30
! 1990-01-02@12:30 => 0
set xyz ! '2024-01-01@11:47'
! 2024-01-01@11:47 => 0
set xyz ! 00:00
! 00:00 => 1
set xyz ! 00:01
! 00:01 => 0
set xyz ! 23:59
! 23:59 => 0
set xyz ! ""
! "" => 1
set xyz ! "foo"
! "foo" => 0
set xyz ! "0"
! "0" => 0
# Don't want Remind to queue reminders
EXIT
@@ -11155,6 +11653,38 @@ Reminders for Sunday, 1st January, 2012:
2
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
-stdin-(1): Undefined OMITFUNC function: `foo'
# rem2ps2 begin
January 2012 31 0 0
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
@@ -12187,13 +12717,15 @@ $IntMin => -2147483648
- -2147483648 => Number too low
../tests/expr.rem(27): `-': Number too low
Parsed expression: $IntMin / -1
=> (/ $IntMin -1)
=> (/ $IntMin (- 1))
$IntMin => -2147483648
- 1 => -1
-2147483648 / -1 => Number too high
../tests/expr.rem(29): `/': Number too high
Parsed expression: $IntMin % -1
=> (% $IntMin -1)
=> (% $IntMin (- 1))
$IntMin => -2147483648
- 1 => -1
-2147483648 % -1 => Number too high
../tests/expr.rem(30): `%': Number too high
Parsed expression: (7+5)*(8+2)/(9-4)
@@ -12542,3 +13074,51 @@ No reminders.
No reminders.
# This is a timestamp file used by Remind to track ONCE reminders.
# Do not edit or delete it.
+----------------------------------------------------------------------------+
| September 2024 |
+----------+----------+----------+----------+----------+----------+----------+
| Sunday | Monday | Tuesday |Wednesday | Thursday | Friday | Saturday |
+----------+----------+----------+----------+----------+----------+----------+
|1 |2 |3 |4 |5 |6 |7 |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
+----------+----------+----------+----------+----------+----------+----------+
|8 |9 |10 |11 |12 |13 |14 |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
+----------+----------+----------+----------+----------+----------+----------+
|15 |16 |17 |18 |19 |20 |21 |
| | | | | | | |
| |foo | | | | | |
| |bar | | | | | |
| |baz wookie| | | | | |
| |quux apple| | | | | |
| |blech | | | | | |
| | | | | | | |
| |ANOTHER | | | | | |
+----------+----------+----------+----------+----------+----------+----------+
|22 |23 |24 |25 |26 |27 |28 |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
+----------+----------+----------+----------+----------+----------+----------+
|29 |30 | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
+----------+----------+----------+----------+----------+----------+----------+
+103
View File
@@ -922,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)
@@ -998,6 +1008,99 @@ 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)]
# 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"
# Don't want Remind to queue reminders
EXIT