mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 06:18:47 +02:00
Compare commits
43 Commits
06.00.00-B
...
06.00.00
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2a3468e04 | ||
|
|
4ff2064452 | ||
|
|
8e00bd5acc | ||
|
|
86f65e11bb | ||
|
|
0c9ec11fce | ||
|
|
07dcaec176 | ||
|
|
e87849256b | ||
|
|
fd8ecd88a8 | ||
|
|
5e36a6563a | ||
|
|
274a2bf067 | ||
|
|
4aa737e542 | ||
|
|
6474f4e0b6 | ||
|
|
7b7b861399 | ||
|
|
5cb0e82be2 | ||
|
|
d9a4bd19f2 | ||
|
|
1004946d26 | ||
|
|
d877a6cb48 | ||
|
|
3eea329b32 | ||
|
|
7bf23912ae | ||
|
|
6ae0340137 | ||
|
|
0e48ace855 | ||
|
|
d1f1ddf5b7 | ||
|
|
5f9e227dc8 | ||
|
|
b770676cb6 | ||
|
|
5ee415c2fb | ||
|
|
6c2a4b66fd | ||
|
|
6c2d65c08e | ||
|
|
cd2dc3bea3 | ||
|
|
b1b80316ab | ||
|
|
f04835cf6f | ||
|
|
fb19ea6b7e | ||
|
|
e2d7796d4a | ||
|
|
de2ec1aa7b | ||
|
|
b9fb215d9d | ||
|
|
a62ed0e0c5 | ||
|
|
eceb5e3f82 | ||
|
|
d5aa93ae57 | ||
|
|
a66da78b4a | ||
|
|
af69f54bff | ||
|
|
a000a7f17e | ||
|
|
582f388500 | ||
|
|
7762f4f2d6 | ||
|
|
31c9b2afb7 |
@@ -114,7 +114,7 @@
|
||||
"DURATION" "ELSE" "ENDIF" "ERRMSG" "EXIT" "EXPR" "FIRST"
|
||||
"FLUSH" "FOURTH" "FRENAME" "FROM" "FSET" "FUNSET" "IF"
|
||||
"IFTRIG" "IN" "INC" "INCLUDE" "INCLUDECMD" "INFO" "LAST"
|
||||
"LASTDAY" "LASTWORKDAY" "MAYBE" "MAYBE-UNCOMPUTABLE" "MSF"
|
||||
"LASTDAY" "LASTWORKDAY" "MAX-OVERDUE" "MAYBE" "MAYBE-UNCOMPUTABLE" "MSF"
|
||||
"MSG" "NOQUEUE" "OMIT" "OMITFUNC" "ONCE" "POP"
|
||||
"POP-OMIT-CONTEXT" "POP-FUNCS" "POP-VARS" "PRESERVE" "PRIORITY" "PS"
|
||||
"PSFILE" "PUSH" "PUSH-FUNCS" "PUSH-VARS" "PUSH-OMIT-CONTEXT" "REM" "RETURN"
|
||||
@@ -137,8 +137,8 @@
|
||||
"$DefaultPrio" "$DefaultTDelta" "$DeltaOverride"
|
||||
"$DontFork" "$DontQueue" "$DontTrigAts" "$EndSent" "$EndSentIg"
|
||||
"$ExpressionTimeLimit" "$February" "$FirstIndent" "$FoldYear"
|
||||
"$FormWidth" "$Friday" "$Fromnow" "$Hour" "$Hplu" "$HushMode"
|
||||
"$IgnoreOnce" "$InfDelta" "$IntMax" "$IntMin" "$Is" "$January" "$July"
|
||||
"$FormWidth" "$Friday" "$Fromnow" "$HideCompletedTodos" "$Hour" "$Hplu" "$HushMode"
|
||||
"$IgnoreOnce" "$InfDelta" "$IntMax" "$IntMin" "$Is" "$January" "$JSONMode" "$July"
|
||||
"$June" "$LatDeg" "$Latitude" "$LatMin" "$LatSec" "$Location"
|
||||
"$LongDeg" "$Longitude" "$LongMin" "$LongSec" "$March" "$MaxFullOmits"
|
||||
"$MaxLateMinutes" "$MaxPartialOmits" "$MaxSatIter" "$MaxStringLen"
|
||||
@@ -148,7 +148,7 @@
|
||||
"$PrefixLineNo" "$PSCal" "$RunOff" "$Saturday" "$September"
|
||||
"$SimpleCal" "$SortByDate" "$SortByPrio" "$SortByTime" "$SubsIndent"
|
||||
"$Sunday" "$SuppressImplicitWarnings" "$SuppressLRM" "$SysInclude" "$T" "$Tb" "$Td"
|
||||
"$TerminalBackground" "$Thursday" "$TimeSep" "$TimetIs64bit" "$Tm" "$Today"
|
||||
"$TerminalBackground" "$Thursday" "$TimeSep" "$TimetIs64bit" "$Tm" "$Today" "$TodoFilter"
|
||||
"$Tomorrow" "$Tt" "$Tuesday" "$Tw" "$Ty" "$U" "$Ud" "$Um"
|
||||
"$UntimedFirst" "$Use256Colors" "$UseBGVTColors" "$UseTrueColors"
|
||||
"$UseVTColors" "$Uw" "$Uy" "$Was" "$Wednesday")
|
||||
@@ -178,9 +178,9 @@
|
||||
"ostype" "pad" "plural" "psmoon" "psshade" "realcurrent" "realnow"
|
||||
"realtoday" "rows" "sgn" "shell" "shellescape" "slide" "soleq"
|
||||
"stdout" "strlen" "substr" "sunrise" "sunset" "time" "timepart"
|
||||
"timezone" "today" "trig" "trigback" "trigbase" "trigdate" "trigdatetime"
|
||||
"timezone" "today" "trig" "trigback" "trigbase" "trigcompletethrough" "trigdate" "trigdatetime"
|
||||
"trigdelta" "trigduration" "trigeventduration" "trigeventstart"
|
||||
"trigfrom" "trigger" "triginfo" "trigpriority" "trigrep"
|
||||
"trigfrom" "trigger" "triginfo" "trigistodo" "trigmaxoverdue" "trigpriority" "trigrep"
|
||||
"trigscanfrom" "trigtags" "trigtime" "trigtimedelta" "trigtimerep"
|
||||
"triguntil" "trigvalid" "typeof" "tzconvert" "upper" "utctolocal"
|
||||
"value" "version" "weekno" "wkday" "wkdaynum" "year"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 6.0 Patch 0 - 2025-??-??
|
||||
* VERSION 6.0 Patch 0 - 2025-08-18
|
||||
|
||||
- MAJOR NEW FEATURE: remind: Introduction of TODOs. These are similar
|
||||
to normal reminders, but (in Agenda Mode) you keep getting reminded
|
||||
@@ -15,6 +15,16 @@ CHANGES TO REMIND
|
||||
the rest of the current file. Useful for early exit from an
|
||||
INCLUDEd file.
|
||||
|
||||
- MINOR NEW FEATURE: remind: Allow the %:, %!, %?, %@ and %#
|
||||
substitution sequences to be overridden by defining the functions
|
||||
subst_colon, subst_bang, subst_question, subst_at and subst_hash,
|
||||
respectively.
|
||||
|
||||
- SAFETY IMPROVEMENT: remind: If a function is defined in a context
|
||||
where RUN is disabled, disable RUN during the evaluation of the
|
||||
function. Also disable RUN for all subst_XXX callbacks and the
|
||||
ordx(n) callback.
|
||||
|
||||
- MAJOR IMPROVEMENTS: tkremind: TkRemind has been given an overhaul.
|
||||
The "Show Queue" and "Show Today's Reminders" windows now respect
|
||||
the color scheme. TkRemind lets you create TODO reminders and
|
||||
@@ -41,13 +51,24 @@ CHANGES TO REMIND
|
||||
- MINOR IMPROVEMENT: include/lang/nl.rem: Use "eergisteren" for "2
|
||||
days ago" and "overmorgen" for "in 2 days' time."
|
||||
|
||||
- MINOR IMPROVEMENT: tkremind: TkRemind now passes all command-line options
|
||||
back to Remind.
|
||||
- MINOR IMPROVEMENT: tkremind: TkRemind now passes all command-line
|
||||
options back to Remind.
|
||||
|
||||
- TEST IMPROVEMENT: remind: Add --flush option and use it in tests to
|
||||
have more predictable interleaving of stdout/stderr output.
|
||||
|
||||
- BUG FIX: tkremind: In a couple of places, the "eval" command was used
|
||||
where the intention was to use "catch". I blame Perl...
|
||||
|
||||
- BUG FIX: remind: SCANFROM and FROM are separated out internally, and
|
||||
in the JSON output, the original FROM or SCANFROM value is
|
||||
preserved, including relative SCANFROMs.
|
||||
|
||||
- BUG FIX: tkremind: Remove some extraneous semicolons.
|
||||
|
||||
- DOCUMENTATION FIX: Fix some man-page format directive errors;
|
||||
tweak wording in several pages.
|
||||
|
||||
* VERSION 5.5 Patch 0 - 2025-07-28
|
||||
|
||||
- NEW FEATURE: remind: Add the PUSH-VARS / POP-VARS commands and the
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
if !defined("ansi_bold")
|
||||
# Disable ANSI attributes in calandar mode
|
||||
if $CalMode
|
||||
# Disable ANSI attributes in calendar mode or JSON mode
|
||||
if $CalMode || $PSCal || $JSONMode
|
||||
set ansi_normal ""
|
||||
set ansi_bold ""
|
||||
set ansi_faint ""
|
||||
|
||||
@@ -31,6 +31,7 @@ SET $Tomorrow "demà"
|
||||
TRANSLATE "yesterday" "ahir"
|
||||
TRANSLATE "are" "són"
|
||||
TRANSLATE "were" "eren"
|
||||
TRANSLATE "done" "completada"
|
||||
|
||||
FSET subst_bx(a,d,t) iif(d==today()+2, "demà passat", d >= today(), "d'aquí " + (d-today()) + " dies", "fa " + (today()-d) + " dies")
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ SET $Tomorrow "i morgen"
|
||||
TRANSLATE "yesterday" "i går"
|
||||
TRANSLATE "are" "er"
|
||||
TRANSLATE "were" "var"
|
||||
TRANSLATE "done" "fuldført"
|
||||
|
||||
BANNER Påmindelse for %w, %d. %m, %y%o:
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ SET $Tomorrow "morgen"
|
||||
TRANSLATE "yesterday" "gestern"
|
||||
TRANSLATE "are" "sind"
|
||||
TRANSLATE "were" "waren"
|
||||
TRANSLATE "done" "abgeschlossen"
|
||||
|
||||
# Banner
|
||||
BANNER Termine für %w, den %d. %m %y%o:
|
||||
|
||||
@@ -32,6 +32,7 @@ SET $Tomorrow "mañana"
|
||||
TRANSLATE "yesterday" "ayer"
|
||||
TRANSLATE "are" "son"
|
||||
TRANSLATE "were" "eran"
|
||||
TRANSLATE "done" "completada"
|
||||
|
||||
BANNER Agenda para el %w, %d%s %m, %y%o:
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ SET $Tomorrow "huomenna"
|
||||
TRANSLATE "yesterday" "eilen"
|
||||
TRANSLATE "are" "ovat"
|
||||
TRANSLATE "were" "olivat"
|
||||
TRANSLATE "done" "suoritettu"
|
||||
|
||||
BANNER Viestit %wna %d. %mta %y%o:
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ SET $Tomorrow "demain"
|
||||
TRANSLATE "yesterday" "hier"
|
||||
TRANSLATE "are" "sont"
|
||||
TRANSLATE "were" "étaient"
|
||||
TRANSLATE "done" "accomplie"
|
||||
|
||||
SET $On "le"
|
||||
SET $At "à"
|
||||
|
||||
@@ -32,6 +32,7 @@ SET $Tomorrow "αύριο"
|
||||
TRANSLATE "yesterday" "εχθές"
|
||||
TRANSLATE "are" "είναι"
|
||||
TRANSLATE "were" "ήταν"
|
||||
TRANSLATE "done" "ολοκληρώθηκε"
|
||||
|
||||
BANNER Υπενθυμίσεις: %w, %d %m, %y%o:
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ SET $Tomorrow "á morgun"
|
||||
TRANSLATE "yesterday" "í gær"
|
||||
TRANSLATE "are" "eru"
|
||||
TRANSLATE "were" "voru"
|
||||
TRANSLATE "done" "lokið"
|
||||
|
||||
BANNER Minnisatriði: %w, %d%s %m, %y%o:
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ SET $Tomorrow "domani"
|
||||
TRANSLATE "yesterday" "Ieri"
|
||||
TRANSLATE "are" "sono"
|
||||
TRANSLATE "were" "erano"
|
||||
TRANSLATE "done" "completato"
|
||||
|
||||
BANNER Promemoria per %w, %d %m %y%o:
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ SET $Tomorrow "morgen"
|
||||
TRANSLATE "yesterday" "gisteren"
|
||||
TRANSLATE "are" "zijn"
|
||||
TRANSLATE "were" "waren"
|
||||
TRANSLATE "done" "voltooid"
|
||||
|
||||
BANNER Herinneringen voor %w, %d %m, %y%o:
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ SET $Tomorrow "i morgen"
|
||||
TRANSLATE "yesterday" "i går"
|
||||
TRANSLATE "are" "er"
|
||||
TRANSLATE "were" "var"
|
||||
TRANSLATE "done" "fullført"
|
||||
|
||||
BANNER Påminnelse for %w, %d. %m, %y%o:
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ SET $Tomorrow "jutro"
|
||||
TRANSLATE "yesterday" "wczoraj"
|
||||
TRANSLATE "are" "są"
|
||||
TRANSLATE "were" "byli"
|
||||
TRANSLATE "done" "ukończone"
|
||||
|
||||
BANNER Terminarz na %w, %d. %m %y%o:
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ SET $Tomorrow "amanhã"
|
||||
TRANSLATE "yesterday" "ontem"
|
||||
TRANSLATE "are" "são"
|
||||
TRANSLATE "were" "eram"
|
||||
TRANSLATE "done" "concluída"
|
||||
|
||||
BANNER Avisos para %w, %d de %m de %y%o:
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ SET $Tomorrow "mâine"
|
||||
TRANSLATE "yesterday" "ieri"
|
||||
TRANSLATE "are" "sunt"
|
||||
TRANSLATE "were" "au fost"
|
||||
TRANSLATE "done" "finalizată"
|
||||
|
||||
BANNER Reamintiri pentru %w, %d %m %y%o:
|
||||
|
||||
|
||||
@@ -544,6 +544,7 @@ will produce the following \fBinfo\fR hash:
|
||||
"summary" : "None"
|
||||
},
|
||||
.fi
|
||||
.PP
|
||||
.RE
|
||||
.TP
|
||||
.B time \fIt\fR
|
||||
@@ -639,6 +640,10 @@ If the reminder is a TODO reminder, then \fIflag\fR will be the integer
|
||||
If the reminder has a COMPLETE-THROUGH date, then this key will be present
|
||||
and its value will be a string of the form YYYY-MM-DD.
|
||||
.TP
|
||||
.B max_overdue \fIn\fR
|
||||
If the reminder has a MAX-OVERDUE clause, then this key will be present and
|
||||
its value will be the integer argument to MAX-OVERDUE.
|
||||
.TP
|
||||
.B priority \fIn\fR
|
||||
The priority of the reminder. Always present; if no PRIORITY keyword
|
||||
is specified, then a reminder has a default priority of 5000.
|
||||
@@ -680,8 +685,8 @@ emits the line:
|
||||
However, back-ends should keep reading until EOF in case more data for
|
||||
subsequent months is forthcoming.
|
||||
.PP
|
||||
|
||||
.SH REM2PS PURE JSON INPUT FORMAT (-PPP OR -P+ OPTION)
|
||||
.PP
|
||||
\fBRemind \-ppp\fR and \fBremind \-p+\fR emit \fIpure JSON\fR output.
|
||||
The format is as follows:
|
||||
.PP
|
||||
|
||||
112
man/remind.1.in
112
man/remind.1.in
@@ -551,9 +551,13 @@ Do not issue TODO-type reminders.
|
||||
.B \-\-json
|
||||
In Agenda Mode, output JSON instead of the normal text-mode output.
|
||||
\fB\-\-json\fR also disables sorting (the \fB-g\fR option) and
|
||||
disables queueing (the \fB-q\fR option). See the section
|
||||
"AGENDA MODE JSON OUTPUT" for more details. The \fB\-\-json\fR option
|
||||
is ignored in Calendar Mode.
|
||||
disables queueing (the \fB-q\fR option). See the section "AGENDA MODE
|
||||
JSON OUTPUT" for more details. The \fB\-\-json\fR option is ignored
|
||||
in Calendar Mode. Note that in JSON mode, the output from any
|
||||
\fBRUN\fR-type reminder that would normally appear on standard output
|
||||
is redirected to standard error instead; this is so that \fBRUN\fR-type
|
||||
reminders don't mess up the output and cause invalid JSON to be produced
|
||||
on standard output.
|
||||
.TP
|
||||
.B \-\-print-errs
|
||||
The \fB\-\-print-errs\fR option causes \fBRemind\fR to print all
|
||||
@@ -614,6 +618,11 @@ queued reminders, the time limit is reset to no limit.
|
||||
.B \-\-test
|
||||
The \fB\-\-test\fR long option is only for use by the acceptance tests
|
||||
run by "make test". Do not use this option in production.
|
||||
.TP
|
||||
.B \-\-flush
|
||||
The \fB\-\-flush\fR long option makes \fBRemind\fR's standard output
|
||||
and standard error streams unbuffered. It is mostly used for testing and
|
||||
should probably not be used in production.
|
||||
.SH REMINDER FILES
|
||||
.PP
|
||||
\fBRemind\fR uses scripts to control its operation. You can use any
|
||||
@@ -668,6 +677,7 @@ Its syntax is:
|
||||
[\fIdelta\fR]
|
||||
[\fIrepeat\fR]
|
||||
[\fBTODO\fR]
|
||||
[\fBMAX-OVERDUE\fR \fIn\fR]
|
||||
[\fBCOMPLETE-THROUGH\fR \fIcomplete_date\fR]
|
||||
[\fBPRIORITY\fR \fIprio\fR]
|
||||
[\fBSKIP\fR | \fBBEFORE\fR | \fBAFTER\fR]
|
||||
@@ -1821,13 +1831,13 @@ is replaced with "s" if the value produced by \fB%7\fR is not 1.
|
||||
.TP
|
||||
.B %!
|
||||
is replaced with "is" if the current date and time is before the
|
||||
trigger date and the \fBAT\fR time, or "was" if it is after. The %!
|
||||
trigger date and the \fBAT\fR time, or "was" if it is after. The \fB%!\fR
|
||||
sequence may be used in a non-timed reminder, in which case only dates
|
||||
are compared.
|
||||
.TP
|
||||
.B %?
|
||||
is replaced with "are" if the current date and time is before the
|
||||
trigger date and the \fBAT\fR time, or "were" if it is after. The %!
|
||||
trigger date and the \fBAT\fR time, or "were" if it is after. The \fB%?\fR
|
||||
sequence may be used in a non-timed reminder, in which case only dates
|
||||
are compared.
|
||||
.TP
|
||||
@@ -1837,9 +1847,17 @@ is similar to \fB%2\fR but displays the current time.
|
||||
.B %#
|
||||
is similar to \fB%3\fR but displays the current time.
|
||||
.TP
|
||||
.B %:
|
||||
is replaced with " (done)" for a TODO reminder whose trigger date
|
||||
is on or after its COMPLETE-THROUGH date. It is replaced with the empty
|
||||
string in any other situation. Note that because \fBRemind\fR does not
|
||||
display completed TODO reminders in Agenda Mode, this escape sequence
|
||||
is really only useful in Calendar Mode.
|
||||
.TP
|
||||
.B
|
||||
%"
|
||||
(percent-doublequote - ") is removed. This sequence is not
|
||||
.\" "
|
||||
(percent-doublequote) is removed. This sequence is not
|
||||
used by the substitution filter,
|
||||
but is used to tell \fBRemind\fR which text to include in a calendar
|
||||
entry when the \fB\-c\fR, \fB\-s\fR or \fB\-p\fR option is chosen.
|
||||
@@ -1863,12 +1881,12 @@ sequences.
|
||||
.TP
|
||||
o
|
||||
The a, c, e, f, g, h, i, j, k, l, u, v, 2, and 3 substitutions may
|
||||
be preceded by an asterisk (for example, %*c) which causes the word
|
||||
be preceded by an asterisk (for example, \fB%*c\fR) which causes the word
|
||||
"at" or "on" that would normally be included in the output to be
|
||||
omitted.
|
||||
.TP
|
||||
o
|
||||
The ! and ? substitutions may be preceded by an asterisk (%*! or %*?),
|
||||
The ! and ? substitutions may be preceded by an asterisk (\fB%*!\fR or \fB%*?\fR),
|
||||
in which case the comparison is made between the trigger date and
|
||||
realtoday() instead of today().
|
||||
.TP
|
||||
@@ -1944,7 +1962,7 @@ which recurrences have been completed. For example:
|
||||
Canadian income taxes must be filed every 30 April. The above command
|
||||
will remind you to pay taxes in 2026. If you don't update the
|
||||
COMPLETE-THROUGH date, then after 30 April 2026, \fBRemind\fR will
|
||||
keep reminding you until the end of time that my taxes were due on 30
|
||||
keep reminding you until the end of time that your taxes were due on 30
|
||||
April 2026. To indicate that you've paid them, simply update the
|
||||
COMPLETE-THROUGH date to 2026-04-30 and then \fBRemind\fR will start
|
||||
reminding you of your 2027 taxes (starting 15 days before the due
|
||||
@@ -1952,6 +1970,26 @@ date.)
|
||||
.PP
|
||||
It is an error to specify COMPLETE-THROUGH without also specifying TODO.
|
||||
.PP
|
||||
.SH LIMITING REMINDERS ABOUT OVERDUE TODOS
|
||||
.PP
|
||||
Although \fBRemind\fR is happy to keep reminding you about overdue
|
||||
TODOs for hundreds of years, for some things this may be pointless.
|
||||
If you want \fBRemind\fR to \fIstop\fR nagging you about an overdue
|
||||
TODO after a certain number of days, use the MAX-OVERDUE \fIn\fR clause.
|
||||
In this case, \fBRemind\fR stops reminding you of a TODO that is overdue
|
||||
by more than \fIn\fR days. Here is an example.
|
||||
.PP
|
||||
.nf
|
||||
REM TODO 2025-08-13 ++5 MAX-OVERDUE 5 MSG Task: %b.
|
||||
.fi
|
||||
.PP
|
||||
\fBRemind\fR \fIstarts\fR reminding you of the task on 2025-08-08,
|
||||
because of the ++5 back value. It keeps reminding you of the task
|
||||
after the due date. However, the last time it will remind you
|
||||
will be on 2025-08-18, because of the MAX-OVERDUE clause. Starting
|
||||
on 2025-08-19, \fBRemind\fR will no longer remind you of the task
|
||||
since it's probably pointless---it has passed the MAX-OVERDUE period.
|
||||
.PP
|
||||
.SH MORE DETAILS ABOUT TODOS
|
||||
.PP
|
||||
TODOs are treated specially only in Agenda Mode. In Calendar Mode,
|
||||
@@ -2842,6 +2880,7 @@ reminders to detect duplicates. Consider the following example:
|
||||
REM Wednesday MSG Hello
|
||||
SET $DedupeReminders 1
|
||||
REM Wednesday MSG Hello
|
||||
.fi
|
||||
.PP
|
||||
Every Wednesday, \fBRemind\fR will issue \fItwo\fR "Hello" reminders.
|
||||
Because $DedupeReminders was 0 when the first "Hello" was issued, it
|
||||
@@ -2858,6 +2897,7 @@ have been done. Consider the following:
|
||||
REM MSG [a]
|
||||
set a "foo"
|
||||
REM MSG [a]
|
||||
.fi
|
||||
.PP
|
||||
The first REM will trigger and print "foo". The second will trigger and
|
||||
print "bar". The third will not trigger because it's a duplicate of the
|
||||
@@ -2969,6 +3009,10 @@ 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 $HideCompletedTodos (read-only)
|
||||
If non-zero, then the \fB\-\-hide-completed-todos\fR option was supplied
|
||||
on the command line.
|
||||
.TP
|
||||
.B $HushMode (read-only)
|
||||
If non-zero, then the \fB\-h\fR option was supplied on the command line.
|
||||
.TP
|
||||
@@ -3056,6 +3100,9 @@ updates \fB$LongDeg\fR, \fB$LongMin\fR and \fB$LongSec\fR. Similar
|
||||
rules apply to \fB$Latitude\fR, \fB$LatDeg\fR, \fB$LatMin\fR and \fB$LatSec\fR.
|
||||
.RE
|
||||
.TP
|
||||
.B $JSONMode (read-only)
|
||||
If non-zero, then the \fB\-\-json\fR command-line option was supplied.
|
||||
.TP
|
||||
.B $MaxLateMinutes
|
||||
This variable controls how \fBRemind\fR reacts to a computer being suspended
|
||||
and then woken. Normally, if a timed reminder is queued and then the
|
||||
@@ -3259,6 +3306,11 @@ This variable returns 1 if the internal C \fBtime_t\fR type is at least
|
||||
to represent dates after about 2038, and \fBRemind\fR will use a workaround to avoid
|
||||
problems. See also the section "MACHINES WITH A 32-BIT TIME_T TYPE"
|
||||
.TP
|
||||
.B $TodoFilter (read-only)
|
||||
If 0, then both events and TODOs are being output. If 1, then the
|
||||
\fB\-\-only-todos\fR command-line option was supplied. If 2, then
|
||||
the \fB\-\-only-events\fR command-line option was spplied.
|
||||
.TP
|
||||
.B $UntimedFirst (read-only)
|
||||
Set to 1 if the \fB\-g\fR option is used with a fourth sort character
|
||||
of "d"; set to 0 otherwise.
|
||||
@@ -3741,7 +3793,7 @@ for the specified year. If \fIarg\fR is a \fBDATE\fR or
|
||||
after \fIarg\fR. (The time component of a datetime is ignored.) If \fIarg\fR
|
||||
is omitted, then it defaults to \fBtoday()\fR.
|
||||
.RS
|
||||
.P
|
||||
.PP
|
||||
Note that \fBeasterdate\fR computes the Western Easter. For the Orthodox
|
||||
Easter date, see \fBorthodoxeaster\fR.
|
||||
.RE
|
||||
@@ -4261,7 +4313,7 @@ Returns a string that is the ordinal number \fInum\fR. For example,
|
||||
In order to help with localization, if you define a function called
|
||||
\fBordx\fR that takes a single parameter, then calling
|
||||
\fBord\fR(\fIn\fR) invokes \fBordx\fR(\fIn\fR) and returns whatever
|
||||
it does.
|
||||
it does. During the callback to \fBordx\fR, \fBRUN\fR will be disabled.
|
||||
.RE
|
||||
.TP
|
||||
.B orthodoxeaster([dqi_arg])
|
||||
@@ -4271,7 +4323,7 @@ for the specified year. If \fIarg\fR is a \fBDATE\fR or
|
||||
after \fIarg\fR. (The time component of a datetime is ignored.) If \fIarg\fR
|
||||
is omitted, then it defaults to \fBtoday()\fR.
|
||||
.RS
|
||||
.P
|
||||
.PP
|
||||
Note that \fBorthodoxeaster\fR computes the Orthodox Easter. For the Western
|
||||
Easter date, see \fBeasterdate\fR.
|
||||
.RE
|
||||
@@ -4742,6 +4794,18 @@ the empty string to variable b:
|
||||
.PP
|
||||
.RE
|
||||
.TP
|
||||
.B trigistodo()
|
||||
Returns 1 if the last \fRREM\fR command was a \fBTODO\fR type or 0 if not.
|
||||
.TP
|
||||
.B trigcompletethrough()
|
||||
Returns a \fBDATE\fR object that is the COMPLETE-THROUGH date of the most
|
||||
recent \fBREM\fR command. If there was no COMPLETE-THROUGH date,
|
||||
returns the \fBINT\fR 0.
|
||||
.TP
|
||||
.B trigmaxoverdue()
|
||||
Returns an \fBINT\fR that is the MAX-OVERDUE value of the most recent \fBREM\fR
|
||||
command. If there was no MAX-OVERDUE clause, returns -1.
|
||||
.TP
|
||||
.B trigger(d_date [,t_time [,i_utcflag]]) \fRor\fB trigger(q_datetime [,i_utcflag])
|
||||
Returns a string suitable for use in a \fBREM\fR command or a
|
||||
\fBSCANFROM\fR or UNTIL clause, allowing you to calculate trigger
|
||||
@@ -5266,6 +5330,13 @@ it is ignored and the built-in function is used. To prevent conflicts
|
||||
with future versions of \fBRemind\fR (which may define more built-in
|
||||
functions), you may wish to name all user-defined functions beginning
|
||||
with an underscore.
|
||||
.TP
|
||||
o
|
||||
If a user-defined function is defined in a context where \fBRUN\fR is
|
||||
disabled, then whenever that function is called, \fBRUN\fR will be disabled
|
||||
during its evaluation, \fIeven if\fR it is called from a context where
|
||||
\fBRUN\fR is enabled.
|
||||
|
||||
.PP
|
||||
To delete a user-defined function, use \fBFUNSET\fR. This takes a
|
||||
space-separated list of user-defined functions to delete. For
|
||||
@@ -6432,6 +6503,20 @@ as:
|
||||
FSET subst_bx(a,d,t) iif(d==today()+2, "the day after tomorrow", 0)
|
||||
.fi
|
||||
.PP
|
||||
You can override substitution sequences that are not alphanumeric as follows:
|
||||
.RS
|
||||
.PP
|
||||
Override %: with \fBsubst_colon\fR
|
||||
.PP
|
||||
Override %! with \fBsubst_bang\fR
|
||||
.PP
|
||||
Override %? with \fBsubst_question\fR
|
||||
.PP
|
||||
Override %@ with \fBsubst_at\fR
|
||||
.PP
|
||||
Override %# with \fBsubst_hash\fR
|
||||
.RE
|
||||
.PP
|
||||
You can define your own substitution sequences in addition to the built-in
|
||||
ones as follows: If you define a function named \fBsubst_\fIname\fB(alt, date, time)\fR, then the sequence \fB%{name}\fR calls the function with \fBalt\fR
|
||||
set to 0 and \fBdate\fR and \fBtime\fR to the trigger date and time,
|
||||
@@ -6443,6 +6528,9 @@ If you use a \fB%{name}\fR sequence and the function \fBsubst_\fIname\fR is
|
||||
not defined or returns an error, then \fB%{name}\fR is replaced with the
|
||||
empty string.
|
||||
.PP
|
||||
Note that when \fBRemind\fR invokes any callback function for a
|
||||
substitution sequence, \fBRUN\fR will be disabled.
|
||||
.PP
|
||||
.SH THE TRANSLATION TABLE
|
||||
.PP
|
||||
To assist with localizing reminder files, \fBRemind\fR maintains a
|
||||
|
||||
@@ -98,10 +98,13 @@ The fifth group of controls associates a time and possible duration
|
||||
with the reminder. You can also specify advance notice, possibly
|
||||
repeating.
|
||||
|
||||
The sixth control allows you to specify whether the reminder is a TODO,
|
||||
and if so, its completion date. Double-clicking in the "Complete through"
|
||||
field automatically fills in the date of the calendar entry. Otherwise,
|
||||
enter a possible completion date in the form YYYY-MM-DD.
|
||||
The sixth control allows you to specify whether the reminder is a
|
||||
TODO, and if so, its completion date. Typing a slash "/" in the
|
||||
"Complete through:" field automatically fills in the date of the
|
||||
calendar entry. Otherwise, enter a completion date in the form
|
||||
YYYY-MM-DD. You can also enter a number in the "Max overdue days:"
|
||||
field to limit how many days past the due date \fBRemind\fR will keep
|
||||
reminding you of the TODO.
|
||||
|
||||
The seventh control specifies what \fBRemind\fR should do if a reminder
|
||||
falls on a holiday or weekend.
|
||||
@@ -294,12 +297,12 @@ IP address of your SMTP server here.
|
||||
.TP
|
||||
.B Text Editor
|
||||
This specifies a text editor to invoke when a reminder is right-clicked.
|
||||
The characters "%d" are replaced with the lined number of the file
|
||||
containing the reminder, and "%s" are replaced with the file name.
|
||||
The sequence "%d" is replaced with the line number of the file
|
||||
containing the reminder, and "%s" is replaced with the file name.
|
||||
Useful strings might be "emacs +%d %s" or "gvim +%d %s"
|
||||
|
||||
.TP
|
||||
.B Extra Argument for Remind
|
||||
.B Extra Arguments for Remind
|
||||
This specifies any extra arguments that should be passed to Remind
|
||||
when \fBTkRemind\fR invokes \fBremind\fR. Unless you know what
|
||||
you are doing, leave this blank.
|
||||
|
||||
@@ -1033,7 +1033,7 @@ proc SaveOptions { w } {
|
||||
set n [expr $i*7]
|
||||
for {set j 0} {$j < 7} {incr j} {
|
||||
set f [expr $n+$j]
|
||||
.cal.l$f configure -anchor $Option(DayAnchor);
|
||||
.cal.l$f configure -anchor $Option(DayAnchor)
|
||||
}
|
||||
}
|
||||
.b.status configure -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
@@ -1047,8 +1047,8 @@ proc SaveOptions { w } {
|
||||
.b.queue configure -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
.b.quit configure -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
.b.options configure -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
. configure -background $Option(LineColor);
|
||||
.h configure -background $Option(LineColor);
|
||||
. configure -background $Option(LineColor)
|
||||
.h configure -background $Option(LineColor)
|
||||
.cal configure -background $Option(LineColor)
|
||||
.b configure -background $Option(LineColor)
|
||||
}
|
||||
@@ -1189,7 +1189,7 @@ proc FillCalWindow {} {
|
||||
gets $file line
|
||||
set DayNames {}
|
||||
foreach day $line {
|
||||
set day [regsub -all {_} $day " "];
|
||||
set day [regsub -all {_} $day " "]
|
||||
lappend DayNames $day
|
||||
}
|
||||
|
||||
@@ -1385,7 +1385,7 @@ proc ThisMonth {} {
|
||||
|
||||
# Do nothing if already there
|
||||
if { $CurMonth == $TodayMonth && $CurYear == $TodayYear } {
|
||||
return 0;
|
||||
return 0
|
||||
}
|
||||
set CurMonth $TodayMonth
|
||||
set CurYear $TodayYear
|
||||
@@ -1718,8 +1718,10 @@ proc toggle_complete_through { w } {
|
||||
global todobut
|
||||
if {$todobut} {
|
||||
$w.complete_through configure -state normal
|
||||
$w.max_overdue configure -state normal
|
||||
} else {
|
||||
$w.complete_through configure -state disabled
|
||||
$w.max_overdue configure -state disabled
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1731,6 +1733,7 @@ proc complete_through_today { w } {
|
||||
} else {
|
||||
$w.complete_through insert end [clock format [clock seconds] -format %Y-%m-%d]
|
||||
}
|
||||
return -code break
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -1962,15 +1965,18 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
pack $w.durationbut $w.durationh $w.durationcolon $w.durationm -side left -anchor w -in $w.durationbox
|
||||
|
||||
# TODO?
|
||||
checkbutton $w.todobut -text "This is a TODO " -command [list toggle_complete_through $w]
|
||||
checkbutton $w.todobut -text "This is a TODO " -command [list toggle_complete_through $w]
|
||||
|
||||
balloon_add_help $w.todobut "Select if this is a TODO-type reminder"
|
||||
$w.todobut deselect
|
||||
label $w.lcomplete -text "Complete through: "
|
||||
entry $w.complete_through -width 20
|
||||
bind $w.complete_through <Double-Button-1> [list complete_through_today $w]
|
||||
bind $w.complete_through <KeyPress-slash> [list complete_through_today $w]
|
||||
balloon_add_help $w.complete_through "Enter the date of completed TODO in the form YYYY-MM-DD"
|
||||
pack $w.todobut $w.lcomplete $w.complete_through -side left -anchor w -in $w.todobox
|
||||
label $w.loverdue -text "Max overdue days: "
|
||||
entry $w.max_overdue -width 6
|
||||
balloon_add_help $w.max_overdue "Enter the maximum number of days Remind should nag you about an overdue TODO"
|
||||
pack $w.todobut $w.lcomplete $w.complete_through $w.loverdue $w.max_overdue -side left -anchor w -in $w.todobox
|
||||
|
||||
# SKIP TYPE
|
||||
label $w.labhol -text "On holidays or weekends:"
|
||||
@@ -2079,6 +2085,7 @@ proc OptionsToRemindDialog { w opts } {
|
||||
set hour ""
|
||||
set ampm ""
|
||||
$w.complete_through configure -state normal
|
||||
$w.max_overdue configure -state normal
|
||||
foreach {flag value} $opts {
|
||||
switch -glob -- $flag {
|
||||
"-text-*" {
|
||||
@@ -2361,6 +2368,10 @@ proc CreateReminder {w} {
|
||||
if {"$ct" != ""} {
|
||||
append rem " COMPLETE-THROUGH $ct"
|
||||
}
|
||||
set mo [string trim [$w.max_overdue get]]
|
||||
if {"$mo" != ""} {
|
||||
append rem " MAX-OVERDUE $mo"
|
||||
}
|
||||
}
|
||||
global SkipType
|
||||
if {$SkipType == 2} {
|
||||
@@ -3024,10 +3035,10 @@ proc DaemonReadable { file } {
|
||||
return
|
||||
}
|
||||
if {[catch {set obj [::json::json2dict $line]}]} {
|
||||
return;
|
||||
return
|
||||
}
|
||||
if {![dict exists $obj response]} {
|
||||
return;
|
||||
return
|
||||
}
|
||||
set response [dict get $obj response]
|
||||
switch -- $response {
|
||||
@@ -3581,6 +3592,12 @@ proc ReadTaggedOptions { tag date } {
|
||||
lappend ans -entry-complete_through ""
|
||||
}
|
||||
|
||||
if {[dict exists $obj max_overdue]} {
|
||||
lappend ans -entry-max_overdue [dict get $obj max_overdue]
|
||||
} else {
|
||||
lappend ans -entry-max_overdue ""
|
||||
}
|
||||
|
||||
# Figure out the reminder type
|
||||
if {[dict exists $obj rep]} {
|
||||
# Repeat must be type 1
|
||||
@@ -3756,7 +3773,7 @@ proc EditableEnter { w } {
|
||||
if {"$c" != ""} {
|
||||
$w tag configure $tag -underline 1
|
||||
# underlinefg not supported on older versions of Tk
|
||||
eval { $w tag configure $tag -underlinefg $c }
|
||||
catch { $w tag configure $tag -underlinefg $c }
|
||||
} else {
|
||||
$w tag configure $tag -underline 1
|
||||
}
|
||||
@@ -3822,7 +3839,7 @@ proc details_enter { w } {
|
||||
lappend lines [list "URL:" "Middle-click to open [dict get $info url]"]
|
||||
}
|
||||
if {[llength $lines] < 1} {
|
||||
return;
|
||||
return
|
||||
}
|
||||
balloon_cancel_timer
|
||||
|
||||
@@ -4238,7 +4255,7 @@ proc DisplayTime {} {
|
||||
# .moon_last
|
||||
#***********************************************************************
|
||||
proc CreateMoonWindows {} {
|
||||
global Option;
|
||||
global Option
|
||||
catch { destroy .moon_new }
|
||||
catch { destroy .moon_first }
|
||||
catch { destroy .moon_full }
|
||||
@@ -4302,7 +4319,7 @@ proc DisplayTimeContinuously {} {
|
||||
DisplayTime
|
||||
|
||||
# Reap any zombies
|
||||
eval { exec true }
|
||||
catch { exec true }
|
||||
|
||||
set secs [clock format [clock seconds] -format "%S"]
|
||||
# Doh -- don't interpret as an octal number if leading zero
|
||||
@@ -4365,14 +4382,14 @@ proc ShowTodaysReminders { force date } {
|
||||
if {$TwentyFourHourMode} {
|
||||
append cmdline "-b1 "
|
||||
}
|
||||
append cmdline $Option(ExtraRemindArgs);
|
||||
append cmdline $Option(ExtraRemindArgs)
|
||||
append cmdline " $ReminderFile"
|
||||
if {"$date" != ""} {
|
||||
append cmdline " $date"
|
||||
} else {
|
||||
set date [clock format [clock seconds] -format "%Y-%m-%d" -locale C]
|
||||
}
|
||||
append cmdline " 2>@1"
|
||||
append cmdline " 2>/dev/null"
|
||||
set f [open $cmdline r]
|
||||
while {[gets $f line] >= 0} {
|
||||
append stuff "$line\n"
|
||||
@@ -4531,10 +4548,10 @@ proc compare_reminders { a b } {
|
||||
set a_prio [dict get $a priority]
|
||||
set b_prio [dict get $b priority]
|
||||
if {$a_prio < $b_prio} {
|
||||
return -1;
|
||||
return -1
|
||||
}
|
||||
if {$a_prio > $b_prio} {
|
||||
return 1;
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -2520,6 +2520,9 @@ void WriteJSONTrigger(Trigger const *t, int include_tags)
|
||||
PrintJSONKeyPairInt("scanfrom", t->scanfrom);
|
||||
}
|
||||
}
|
||||
if (t->max_overdue >= 0) {
|
||||
PrintJSONKeyPairInt("max_overdue", t->max_overdue);
|
||||
}
|
||||
PrintJSONKeyPairDate("from", t->from);
|
||||
PrintJSONKeyPairInt("priority", t->priority);
|
||||
PrintJSONKeyPairDateTime("eventstart", t->eventstart);
|
||||
|
||||
42
src/dorem.c
42
src/dorem.c
@@ -293,6 +293,12 @@ int DoRem(ParsePtr p)
|
||||
return E_COMPLETE_WITHOUT_TODO;
|
||||
}
|
||||
|
||||
if (trig.max_overdue >= 0 && !trig.is_todo) {
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
FreeTrig(&trig);
|
||||
return E_MAX_OVERDUE_WITHOUT_TODO;
|
||||
}
|
||||
|
||||
if (trig.typ == NO_TYPE) {
|
||||
if (!Hush) {
|
||||
PurgeEchoLine("%s\n", "#!P! Cannot parse next line");
|
||||
@@ -668,6 +674,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
tim->duration = NO_TIME;
|
||||
trig->need_wkday = 0;
|
||||
trig->is_todo = 0;
|
||||
trig->max_overdue = -1;
|
||||
trig->complete_through = NO_DATE;
|
||||
trig->adj_for_last = 0;
|
||||
trig->infos = NULL;
|
||||
@@ -758,6 +765,25 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
trig->skip = tok.val;
|
||||
break;
|
||||
|
||||
case T_MaxOverdue:
|
||||
if (trig->max_overdue >= 0) return E_MAX_OVERDUE_TWICE;
|
||||
DBufFree(&buf);
|
||||
r = ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
DBufFree(&buf);
|
||||
if (tok.type == T_Illegal) {
|
||||
return -tok.val;
|
||||
}
|
||||
if (tok.type != T_Day && tok.type != T_Year && tok.type != T_Number) {
|
||||
return E_EXPECTING_NUMBER;
|
||||
}
|
||||
if (tok.val < 0) {
|
||||
return E_2LOW;
|
||||
}
|
||||
trig->max_overdue = tok.val;
|
||||
break;
|
||||
|
||||
case T_Priority:
|
||||
DBufFree(&buf);
|
||||
r=ParsePriority(s, trig);
|
||||
@@ -1664,8 +1690,14 @@ int ShouldTriggerReminder(Trigger const *t, TimeTrig const *tim, int dse, int *e
|
||||
}
|
||||
/* DO trigger if has not been completed through trigger date */
|
||||
if (t->complete_through == NO_DATE || t->complete_through < dse) {
|
||||
/* Trigger date is in the past - overdue */
|
||||
/* Trigger date is in the past - overdue, Trigger unless we're
|
||||
more than max_overdue days late */
|
||||
if (dse < DSEToday) {
|
||||
if (t->max_overdue >= 0) {
|
||||
if (dse + t->max_overdue < DSEToday) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* Trigger date in future - use normal Remind rules */
|
||||
@@ -1961,8 +1993,14 @@ static int ShouldTriggerBasedOnWarn(Trigger const *t, int dse, int *err)
|
||||
}
|
||||
/* DO trigger if has not been completed through trigger date */
|
||||
if (t->complete_through == NO_DATE || t->complete_through < dse) {
|
||||
/* Trigger date is in the past - overdue */
|
||||
/* Trigger date is in the past - overdue, Trigger unless we're
|
||||
more than max_overdue days late */
|
||||
if (dse < DSEToday) {
|
||||
if (t->max_overdue >= 0) {
|
||||
if (dse + t->max_overdue < DSEToday) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* Trigger date in future - use normal Remind rules */
|
||||
|
||||
@@ -31,6 +31,39 @@
|
||||
|
||||
#define SHIP_OUT(s) if(DBufPuts(dbuf, s) != OK) return E_NO_MEM
|
||||
|
||||
static char const *
|
||||
get_function_override(int c, int addx)
|
||||
{
|
||||
static char func[32];
|
||||
|
||||
if (isalnum(c) || c == '_') {
|
||||
if (addx) {
|
||||
snprintf(func, sizeof(func), "subst_%cx", tolower(c));
|
||||
} else {
|
||||
snprintf(func, sizeof(func), "subst_%c", tolower(c));
|
||||
}
|
||||
return func;
|
||||
}
|
||||
if (addx) {
|
||||
switch(c) {
|
||||
case ':': return "subst_colonx";
|
||||
case '!': return "subst_bangx";
|
||||
case '?': return "subst_questionx";
|
||||
case '@': return "subst_atx";
|
||||
case '#': return "subst_hashx";
|
||||
}
|
||||
} else {
|
||||
switch(c) {
|
||||
case ':': return "subst_colon";
|
||||
case '!': return "subst_bang";
|
||||
case '?': return "subst_question";
|
||||
case '@': return "subst_at";
|
||||
case '#': return "subst_hash";
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
check_subst_args(UserFunc *f, int n)
|
||||
{
|
||||
@@ -75,7 +108,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int
|
||||
char const *expr;
|
||||
char *os;
|
||||
char s[256];
|
||||
char uf[32];
|
||||
char const *substname;
|
||||
char mypm[64];
|
||||
char mycpm[64];
|
||||
char myplu[64];
|
||||
@@ -112,7 +145,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
snprintf(s, sizeof(s), "subst_ampm(%d)", h);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
r = EvalExprRunDisabled(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
snprintf(mypm, sizeof(mypm), "%s", v.v.str);
|
||||
@@ -140,7 +173,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
snprintf(s, sizeof(s), "subst_ampm(%d)", ch);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
r = EvalExprRunDisabled(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
snprintf(mycpm, sizeof(mycpm), "%s", v.v.str);
|
||||
@@ -163,7 +196,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
snprintf(s, sizeof(s), "subst_ordinal(%d)", d);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
r = EvalExprRunDisabled(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
snprintf(myplu, sizeof(myplu), "%s", v.v.str);
|
||||
@@ -327,7 +360,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int
|
||||
snprintf(ss, sizeof(s) - (ss-s), "(%d,'%04d-%02d-%02d',%02d:%02d)",
|
||||
altmode ? 1 : 0, y, m+1, d, h, min);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
r = EvalExprRunDisabled(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
if (DBufPuts(dbuf, v.v.str) != OK) {
|
||||
@@ -340,13 +373,17 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int
|
||||
continue;
|
||||
}
|
||||
done = 0;
|
||||
snprintf(uf, sizeof(uf), "subst_%c", tolower(c));
|
||||
func = FindUserFunc(uf);
|
||||
substname = get_function_override(c, 0);
|
||||
if (substname) {
|
||||
func = FindUserFunc(substname);
|
||||
} else {
|
||||
func = NULL;
|
||||
}
|
||||
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);
|
||||
snprintf(s, sizeof(s), "%s(%d,'%04d-%02d-%02d',%02d:%02d)",
|
||||
substname, altmode ? 1 : 0, y, m+1, d, h, min);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
r = EvalExprRunDisabled(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (v.type != INT_TYPE || v.v.val != 0) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
@@ -392,13 +429,17 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int
|
||||
|
||||
|
||||
if (!done) {
|
||||
snprintf(uf, sizeof(uf), "subst_%cx", tolower(c));
|
||||
func = FindUserFunc(uf);
|
||||
substname = get_function_override(c, 1);
|
||||
if (substname) {
|
||||
func = FindUserFunc(substname);
|
||||
} else {
|
||||
func = NULL;
|
||||
}
|
||||
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);
|
||||
snprintf(s, sizeof(s), "%s(%d,'%04d-%02d-%02d',%02d:%02d)",
|
||||
substname, altmode ? 1 : 0, y, m+1, d, h, min);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
r = EvalExprRunDisabled(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (v.type != INT_TYPE || v.v.val != 0) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
@@ -617,6 +658,12 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case ':':
|
||||
if (t->is_todo && t->complete_through != NO_DATE && t->complete_through >= dse) {
|
||||
snprintf(s, sizeof(s), " (%s)", tr("done"));
|
||||
SHIP_OUT(s);
|
||||
}
|
||||
break;
|
||||
case '1':
|
||||
if (tdiff == 0)
|
||||
snprintf(s, sizeof(s), "%s", tr("now"));
|
||||
|
||||
@@ -130,6 +130,8 @@
|
||||
#define E_EXPR_DISABLED 106
|
||||
#define E_TIME_EXCEEDED 107
|
||||
#define E_COMPLETE_WITHOUT_TODO 108
|
||||
#define E_MAX_OVERDUE_TWICE 109
|
||||
#define E_MAX_OVERDUE_WITHOUT_TODO 110
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
#undef EXTERN
|
||||
@@ -257,6 +259,8 @@ EXTERN char *ErrMsg[]
|
||||
/* E_EXPR_DISABLED */ "Expression evaluation is disabled",
|
||||
/* E_TIME_EXCEEDED */ "Time limit for expression evaluation exceeded",
|
||||
/* E_COMPLETE_WITHOUT_TODO */ "COMPLETE-THROUGH specified without TODO",
|
||||
/* E_MAX_OVERDUE_TWICE */ "MAX-OVERDUE specified twice",
|
||||
/* E_MAX_OVERDUE_WITHOUT_TODO */ "MAX-OVERDUE specified without TODO",
|
||||
}
|
||||
#endif /* MK_GLOBALS */
|
||||
;
|
||||
|
||||
29
src/expr.c
29
src/expr.c
@@ -570,7 +570,7 @@ eval_builtin(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
/* All went well; copy the result destructively */
|
||||
(*ans) = info.retval;
|
||||
|
||||
/* Special case of const cunction */
|
||||
/* Special case of const function */
|
||||
if (!strcmp(f->name, "const")) {
|
||||
if (*nonconst) {
|
||||
nonconst_debug(0, tr("Non-constant expression converted to constant by `const' built-in function"));
|
||||
@@ -694,6 +694,7 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
Value *new_locals = NULL;
|
||||
expr_node *kid;
|
||||
int i, r, j, pushed;
|
||||
int old_rundisabled;
|
||||
|
||||
/* If we have <= STACK_ARGS_MAX, store them on the stack here */
|
||||
Value stack_locals[STACK_ARGS_MAX];
|
||||
@@ -781,9 +782,15 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
DBG(debug_enter_userfunc(node, new_locals, f->nargs));
|
||||
|
||||
old_rundisabled = RunDisabled;
|
||||
if (f->run_disabled) {
|
||||
RunDisabled |= RUN_UF;
|
||||
}
|
||||
/* Evaluate the function's expr_node tree */
|
||||
r = evaluate_expr_node(f->node, new_locals, ans, nonconst);
|
||||
|
||||
RunDisabled = old_rundisabled;
|
||||
|
||||
DBG(debug_exit_userfunc(node, ans, r, new_locals, f->nargs));
|
||||
|
||||
if (r != OK) {
|
||||
@@ -2869,9 +2876,29 @@ static char const *get_operator_name(expr_node *node)
|
||||
else return "UNKNOWN_OPERATOR";
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* EvalExprRunDisabled - parse and evaluate an expression */
|
||||
/* */
|
||||
/* Evaluate an expression. Return 0 if OK, non-zero if error */
|
||||
/* Put the result into value pointed to by v. During */
|
||||
/* evaluation, RUN will be disabled */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int EvalExprRunDisabled(char const **e, Value *v, ParsePtr p)
|
||||
{
|
||||
int old_run_disabled = RunDisabled;
|
||||
int r;
|
||||
RunDisabled |= RUN_CB;
|
||||
r = EvalExpr(e, v, p);
|
||||
RunDisabled = old_run_disabled;
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* EvalExpr - parse and evaluate an expression. */
|
||||
/* */
|
||||
/* Evaluate an expression. Return 0 if OK, non-zero if error */
|
||||
/* Put the result into value pointed to by v. */
|
||||
/* */
|
||||
|
||||
25
src/files.c
25
src/files.c
@@ -179,17 +179,14 @@ got_a_fresh_line(void)
|
||||
WarnedAboutImplicit = 0;
|
||||
}
|
||||
|
||||
static void set_cloexec(FILE *fp)
|
||||
void set_cloexec(int fd)
|
||||
{
|
||||
int flags;
|
||||
int fd;
|
||||
if (fp) {
|
||||
fd = fileno(fp);
|
||||
flags = fcntl(fd, F_GETFD);
|
||||
if (flags >= 0) {
|
||||
flags |= FD_CLOEXEC;
|
||||
fcntl(fd, F_SETFD, flags);
|
||||
}
|
||||
|
||||
flags = fcntl(fd, F_GETFD);
|
||||
if (flags >= 0) {
|
||||
flags |= FD_CLOEXEC;
|
||||
fcntl(fd, F_SETFD, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +215,7 @@ static void OpenPurgeFile(char const *fname, char const *mode)
|
||||
fprintf(ErrFp, tr("Cannot open `%s' for writing: %s"), DBufValue(&fname_buf), strerror(errno));
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
set_cloexec(PurgeFP);
|
||||
set_cloexec(fileno(PurgeFP));
|
||||
DBufFree(&fname_buf);
|
||||
}
|
||||
|
||||
@@ -427,7 +424,9 @@ static int OpenFile(char const *fname)
|
||||
}
|
||||
} else {
|
||||
fp = fopen(fname, "r");
|
||||
set_cloexec(fp);
|
||||
if (fp) {
|
||||
set_cloexec(fileno(fp));
|
||||
}
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, tr("Reading `%s': Opening file on disk"), fname);
|
||||
fprintf(ErrFp, "\n");
|
||||
@@ -449,7 +448,7 @@ static int OpenFile(char const *fname)
|
||||
if (strcmp(fname, "-")) {
|
||||
fp = fopen(fname, "r");
|
||||
if (!fp || !CheckSafety()) return E_CANT_OPEN;
|
||||
set_cloexec(fp);
|
||||
set_cloexec(fileno(fp));
|
||||
if (PurgeMode) OpenPurgeFile(fname, "w");
|
||||
} else {
|
||||
fp = stdin;
|
||||
@@ -650,7 +649,7 @@ static int PopFile(void)
|
||||
if (strcmp(i->filename, "-")) {
|
||||
fp = fopen(i->filename, "r");
|
||||
if (!fp || !CheckSafety()) return E_CANT_OPEN;
|
||||
set_cloexec(fp);
|
||||
set_cloexec(fileno(fp));
|
||||
if (PurgeMode) OpenPurgeFile(i->filename, "a");
|
||||
} else {
|
||||
fp = stdin;
|
||||
|
||||
53
src/funcs.c
53
src/funcs.c
@@ -173,6 +173,7 @@ static int FToday (func_info *);
|
||||
static int FTrig (func_info *);
|
||||
static int FTrigback (func_info *);
|
||||
static int FTrigbase (func_info *info);
|
||||
static int FTrigcompletethrough (func_info *);
|
||||
static int FTrigdate (func_info *);
|
||||
static int FTrigdatetime (func_info *);
|
||||
static int FTrigdelta (func_info *);
|
||||
@@ -182,6 +183,8 @@ static int FTrigeventduration(func_info *);
|
||||
static int FTrigeventstart (func_info *);
|
||||
static int FTrigfrom (func_info *);
|
||||
static int FTrigger (func_info *);
|
||||
static int FTrigistodo (func_info *);
|
||||
static int FTrigmaxoverdue (func_info *);
|
||||
static int FTrigpriority (func_info *);
|
||||
static int FTrigrep (func_info *);
|
||||
static int FTrigscanfrom (func_info *);
|
||||
@@ -347,6 +350,7 @@ BuiltinFunc Func[] = {
|
||||
{ "trig", 0, NO_MAX, 0, FTrig, NULL },
|
||||
{ "trigback", 0, 0, 0, FTrigback, NULL },
|
||||
{ "trigbase", 0, 0, 0, FTrigbase, NULL },
|
||||
{ "trigcompletethrough", 0, 0, 0, FTrigcompletethrough, NULL },
|
||||
{ "trigdate", 0, 0, 0, FTrigdate, NULL },
|
||||
{ "trigdatetime", 0, 0, 0, FTrigdatetime, NULL },
|
||||
{ "trigdelta", 0, 0, 0, FTrigdelta, NULL },
|
||||
@@ -356,6 +360,8 @@ BuiltinFunc Func[] = {
|
||||
{ "trigfrom", 0, 0, 0, FTrigfrom, NULL },
|
||||
{ "trigger", 1, 3, 0, FTrigger, NULL },
|
||||
{ "triginfo", 1, 1, 0, FTriginfo, NULL },
|
||||
{ "trigistodo", 0, 0, 0, FTrigistodo, NULL },
|
||||
{ "trigmaxoverdue", 0, 0, 0, FTrigmaxoverdue, NULL },
|
||||
{ "trigpriority", 0, 0, 0, FTrigpriority, NULL },
|
||||
{ "trigrep", 0, 0, 0, FTrigrep, NULL },
|
||||
{ "trigscanfrom", 0, 0, 0, FTrigscanfrom, NULL },
|
||||
@@ -1159,11 +1165,14 @@ static int FOrd(func_info *info)
|
||||
ASSERT_TYPE(0, INT_TYPE);
|
||||
|
||||
if (!in_ford && UserFuncExists("ordx") == 1) {
|
||||
/* Can't use EvalExprRunDisabled here because we need
|
||||
the nonconst result */
|
||||
expr_node *n;
|
||||
int r;
|
||||
char const *e = buf;
|
||||
Value val;
|
||||
int nonconst;
|
||||
int old_rundisabled;
|
||||
|
||||
val.type = ERR_TYPE;
|
||||
snprintf(buf, sizeof(buf), "ordx(%d)", ARGV(0));
|
||||
@@ -1172,7 +1181,10 @@ static int FOrd(func_info *info)
|
||||
return r;
|
||||
}
|
||||
in_ford = 1;
|
||||
old_rundisabled = RunDisabled;
|
||||
RunDisabled |= RUN_CB;
|
||||
r = evaluate_expr_node(n, NULL, &val, &nonconst);
|
||||
RunDisabled = old_rundisabled;
|
||||
in_ford = 0;
|
||||
free_expr_tree(n);
|
||||
if (r != OK) {
|
||||
@@ -1897,6 +1909,32 @@ static int FTrigback(func_info *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FTrigcompletethrough(func_info *info)
|
||||
{
|
||||
if (!LastTrigger.is_todo || LastTrigger.complete_through == NO_DATE) {
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = 0;
|
||||
return OK;
|
||||
}
|
||||
RetVal.type = DATE_TYPE;
|
||||
RETVAL = LastTrigger.complete_through;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FTrigistodo(func_info *info)
|
||||
{
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = LastTrigger.is_todo;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FTrigmaxoverdue(func_info *info)
|
||||
{
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = LastTrigger.max_overdue;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FTrigdelta(func_info *info)
|
||||
{
|
||||
RetVal.type = INT_TYPE;
|
||||
@@ -4124,7 +4162,7 @@ FEval(func_info *info)
|
||||
{
|
||||
expr_node *n;
|
||||
int r;
|
||||
int run_was_enabled = 0;
|
||||
int old_run_disabled;
|
||||
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
char const *e = ARGSTR(0);
|
||||
@@ -4136,14 +4174,13 @@ FEval(func_info *info)
|
||||
}
|
||||
|
||||
/* Disable shell() command in eval */
|
||||
if (! (RunDisabled & RUN_IN_EVAL)) {
|
||||
run_was_enabled = 1;
|
||||
RunDisabled |= RUN_IN_EVAL;
|
||||
}
|
||||
old_run_disabled = RunDisabled;
|
||||
RunDisabled |= RUN_IN_EVAL;
|
||||
|
||||
r = evaluate_expr_node(n, NULL, &(info->retval), &(info->nonconst));
|
||||
if (run_was_enabled) {
|
||||
RunDisabled &= ~RUN_IN_EVAL;
|
||||
}
|
||||
|
||||
RunDisabled = old_run_disabled;
|
||||
|
||||
free_expr_tree(n);
|
||||
return r;
|
||||
}
|
||||
|
||||
15
src/init.c
15
src/init.c
@@ -803,6 +803,8 @@ void InitRemind(int argc, char const *argv[])
|
||||
SortByTime = SORT_NONE;
|
||||
SortByDate = SORT_NONE;
|
||||
SortByPrio = SORT_NONE;
|
||||
/* Make sure we don't blat errors to stdout! */
|
||||
ErrFp = stderr;
|
||||
}
|
||||
|
||||
/* Figure out the offset from UTC */
|
||||
@@ -1149,13 +1151,26 @@ ProcessLongOption(char const *arg)
|
||||
return;
|
||||
}
|
||||
if (!strcmp(arg, "only-todos")) {
|
||||
if (TodoFilter == ONLY_EVENTS) {
|
||||
fprintf(ErrFp, "remind: Cannot combine --only-todos and --only-events\n");
|
||||
exit(1);
|
||||
}
|
||||
TodoFilter = ONLY_TODOS;
|
||||
return;
|
||||
}
|
||||
if (!strcmp(arg, "only-events")) {
|
||||
if (TodoFilter == ONLY_TODOS) {
|
||||
fprintf(ErrFp, "remind: Cannot combine --only-todos and --only-events\n");
|
||||
exit(1);
|
||||
}
|
||||
TodoFilter = ONLY_EVENTS;
|
||||
return;
|
||||
}
|
||||
if (!strcmp(arg, "flush")) {
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
return;
|
||||
}
|
||||
if (!strcmp(arg, "json")) {
|
||||
JSONMode = 1;
|
||||
DontQueue = 1;
|
||||
|
||||
20
src/main.c
20
src/main.c
@@ -1576,6 +1576,15 @@ void DoExit(ParsePtr p)
|
||||
|
||||
if (PurgeMode) return;
|
||||
|
||||
if (JSONMode) {
|
||||
if (JSONLinesEmitted) {
|
||||
printf("}\n");
|
||||
}
|
||||
/* Close the reminder list */
|
||||
printf("]\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
r = EvaluateExpr(p, &v);
|
||||
if (r || v.type != INT_TYPE) exit(99);
|
||||
exit(v.v.val);
|
||||
@@ -2056,11 +2065,15 @@ ClearLastTriggers(void)
|
||||
LastTrigger.warn[0] = 0;
|
||||
LastTrigger.omitfunc[0] = 0;
|
||||
LastTrigger.passthru[0] = 0;
|
||||
LastTrigger.is_todo = 0;
|
||||
LastTrigger.complete_through = NO_DATE;
|
||||
LastTrigger.max_overdue = -1;
|
||||
FreeTrig(&LastTrigger);
|
||||
LastTimeTrig.ttime = NO_TIME;
|
||||
LastTimeTrig.delta = NO_DELTA;
|
||||
LastTimeTrig.rep = NO_REP;
|
||||
LastTimeTrig.duration = NO_TIME;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2137,7 +2150,12 @@ System(char const *cmd, int is_queued)
|
||||
}
|
||||
}
|
||||
/* This is the child process or original if we never forked */
|
||||
(void) system(cmd);
|
||||
if (JSONMode) {
|
||||
|
||||
(void) system_to_stderr(cmd);
|
||||
} else {
|
||||
(void) system(cmd);
|
||||
}
|
||||
if (do_exit) {
|
||||
/* In the child process, so exit! */
|
||||
exit(0);
|
||||
|
||||
@@ -512,6 +512,14 @@ DumpOmits(void)
|
||||
{
|
||||
int i;
|
||||
int y, m, d;
|
||||
|
||||
/* Do nothing in --json mode */
|
||||
if (JSONMode) {
|
||||
return;
|
||||
}
|
||||
if (PurgeMode) {
|
||||
return;
|
||||
}
|
||||
printf("Global Full OMITs (%d of maximum allowed %d):\n", NumFullOmits, MAX_FULL_OMITS);
|
||||
if (!NumFullOmits) {
|
||||
printf("\tNone.\n");
|
||||
|
||||
@@ -66,6 +66,7 @@ void unlimit_execution_time(void);
|
||||
expr_node *free_expr_tree(expr_node *node);
|
||||
expr_node *clone_expr_tree(expr_node const *node, int *r);
|
||||
int EvalExpr (char const **e, Value *v, ParsePtr p);
|
||||
int EvalExprRunDisabled(char const **e, Value *v, ParsePtr p);
|
||||
int DoCoerce (char type, Value *v);
|
||||
char const *PrintValue (Value *v, FILE *fp);
|
||||
int CopyValue (Value *dest, const Value *src);
|
||||
@@ -292,3 +293,5 @@ void SetCurrentFilename(char const *fname);
|
||||
char const *GetCurrentFilename(void);
|
||||
int get_scanfrom(Trigger const *t);
|
||||
void remove_trailing_newlines(DynamicBuffer *buf);
|
||||
void set_cloexec(int fd);
|
||||
int system_to_stderr(char const *cmd);
|
||||
|
||||
@@ -395,7 +395,6 @@ void HandleQueuedReminders(void)
|
||||
(MaxLateMinutes == 0 || SystemTime(1) - (q->tt.nexttime * 60) <= 60 * MaxLateMinutes))) {
|
||||
/* Trigger the reminder */
|
||||
CreateParser(q->text, &p);
|
||||
RunDisabled = q->RunDisabled;
|
||||
if (IsServerMode() && q->typ != RUN_TYPE) {
|
||||
if (DaemonJSON) {
|
||||
printf("{\"response\":\"reminder\",");
|
||||
@@ -640,13 +639,15 @@ static int CalculateNextTimeUsingSched(QueuedRem *q)
|
||||
return NO_TIME;
|
||||
}
|
||||
|
||||
RunDisabled = q->RunDisabled; /* Don't want weird scheduling functions
|
||||
to be a security hole! */
|
||||
while(1) {
|
||||
char exprBuf[VAR_NAME_LEN+32];
|
||||
snprintf(exprBuf, sizeof(exprBuf), "%s(%d)", q->sched, q->ntrig);
|
||||
s = exprBuf;
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
if (q->RunDisabled) {
|
||||
r = EvalExprRunDisabled(&s, &v, NULL);
|
||||
} else {
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
}
|
||||
if (r) {
|
||||
q->sched[0] = 0;
|
||||
return NO_TIME;
|
||||
|
||||
@@ -80,6 +80,7 @@ Token TokArray[] = {
|
||||
{ "lastday", 7, T_BackAdj, -1 },
|
||||
{ "lastworkday", 11, T_BackAdj, 1 },
|
||||
{ "march", 3, T_Month, 2 },
|
||||
{ "max-overdue", 11, T_MaxOverdue, 0 },
|
||||
{ "may", 3, T_Month, 4 },
|
||||
{ "maybe-uncomputable", 5, T_MaybeUncomputable, 0},
|
||||
{ "monday", 3, T_WkDay, 0 },
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@@ -63,6 +64,9 @@ GenerateTranslationTemplate(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (JSONMode) {
|
||||
return;
|
||||
}
|
||||
printf("# Translation table template\n\n");
|
||||
|
||||
printf("TRANSLATE \"LANGID\" ");
|
||||
@@ -233,6 +237,10 @@ DumpTranslationTable(FILE *fp, int json)
|
||||
XlateItem *item;
|
||||
int done = 0;
|
||||
char const *t;
|
||||
|
||||
if (fileno(fp) == STDOUT_FILENO && JSONMode) {
|
||||
return;
|
||||
}
|
||||
if (!json) {
|
||||
fprintf(fp, "# Translation table\n");
|
||||
/* Always to LANGID first */
|
||||
|
||||
@@ -145,6 +145,7 @@ typedef struct {
|
||||
int maybe_uncomputable; /* Suppress "can't compute trigger" warnings */
|
||||
int addomit; /* Add trigger date to global OMITs */
|
||||
int noqueue; /* Don't queue even if timed */
|
||||
int max_overdue; /* Stop warning if TODO is too far overdue */
|
||||
char sched[VAR_NAME_LEN+1]; /* Scheduling function */
|
||||
char warn[VAR_NAME_LEN+1]; /* Warning function */
|
||||
char omitfunc[VAR_NAME_LEN+1]; /* OMITFUNC function */
|
||||
@@ -234,7 +235,7 @@ enum TokTypes
|
||||
T_Else, T_Empty, T_EndIf, T_ErrMsg, T_Exit, T_Expr, T_Flush,
|
||||
T_Frename, T_Fset, T_Funset, T_If, T_IfTrig, T_In, T_Include,
|
||||
T_IncludeCmd, T_IncludeR, T_IncludeSys, T_Info, T_LastBack,
|
||||
T_LongTime, T_MaybeUncomputable, T_Month, T_NoQueue, T_Number,
|
||||
T_LongTime, T_MaxOverdue, T_MaybeUncomputable, T_Month, T_NoQueue, T_Number,
|
||||
T_Omit, T_OmitFunc, T_Once, T_Ordinal, T_Pop, T_PopFuncs, T_PopVars,
|
||||
T_Preserve, T_Priority, T_Push, T_PushFuncs, T_PushVars, T_Rem,
|
||||
T_RemType, T_Rep, T_Return, T_Scanfrom, T_Sched, T_Set, T_Skip, T_Tag,
|
||||
@@ -262,6 +263,8 @@ typedef struct {
|
||||
#define RUN_SCRIPT 0x02
|
||||
#define RUN_NOTOWNER 0x04
|
||||
#define RUN_IN_EVAL 0x08
|
||||
#define RUN_UF 0x10 /* A user-function defined with RUN OFF */
|
||||
#define RUN_CB 0x20 /* A callback */
|
||||
|
||||
/* Flags for the SimpleCalendar format */
|
||||
#define SC_AMPM 0 /* Time shown as 3:00am, etc. */
|
||||
@@ -316,6 +319,7 @@ typedef struct udf_struct {
|
||||
int lineno_start;
|
||||
int recurse_flag;
|
||||
int been_pushed;
|
||||
int run_disabled;
|
||||
} UserFunc;
|
||||
|
||||
/* A pushed systtem variable */
|
||||
|
||||
@@ -275,6 +275,11 @@ int DoFset(ParsePtr p)
|
||||
func->lineno_start = LineNoStart;
|
||||
func->recurse_flag = 0;
|
||||
func->been_pushed = 0;
|
||||
if (RunDisabled) {
|
||||
func->run_disabled = 1;
|
||||
} else {
|
||||
func->run_disabled = 0;
|
||||
}
|
||||
if (in_constant_context()) {
|
||||
func->is_constant = 1;
|
||||
} else {
|
||||
|
||||
38
src/utils.c
38
src/utils.c
@@ -17,6 +17,7 @@ static char const DontEscapeMe[] =
|
||||
#include "err.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
@@ -30,6 +31,43 @@ static char const DontEscapeMe[] =
|
||||
#include "globals.h"
|
||||
#include "protos.h"
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* system_to_stderr */
|
||||
/* */
|
||||
/* Run system(...) but with stdout redirected to stderr */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int system_to_stderr(char const *cmd)
|
||||
{
|
||||
int stdout_dup = dup(STDOUT_FILENO);
|
||||
int r;
|
||||
|
||||
if (stdout_dup < 0) {
|
||||
perror("dup");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Duplicate STDERR onto STDOUT */
|
||||
if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
|
||||
(void) close(stdout_dup);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set close-on-exec flag on stdout_dup */
|
||||
set_cloexec(stdout_dup);
|
||||
|
||||
r = system(cmd);
|
||||
|
||||
/* Restore original stdout */
|
||||
/* If this dup2 fails... there's not a whole lot we can do. */
|
||||
(void) dup2(stdout_dup, STDOUT_FILENO);
|
||||
if (STDOUT_FILENO != stdout_dup) {
|
||||
(void) close(stdout_dup);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* StrnCpy */
|
||||
|
||||
@@ -761,6 +761,7 @@ int DoDump(ParsePtr p)
|
||||
int dump_constness = 0;
|
||||
|
||||
if (PurgeMode) return OK;
|
||||
if (JSONMode) return OK;
|
||||
|
||||
DBufInit(&buf);
|
||||
r = ParseToken(p, &buf);
|
||||
@@ -992,6 +993,7 @@ static SysVar SysVarArr[] = {
|
||||
{"FormWidth", 1, INT_TYPE, &FormWidth, 20, 500 },
|
||||
{"Friday", 1, TRANS_TYPE, "Friday", 0, 0 },
|
||||
{"Fromnow", 1, TRANS_TYPE, "from now", 0, 0 },
|
||||
{"HideCompletedTodos", 0, INT_TYPE, &HideCompletedTodos, 0, 0 },
|
||||
{"Hour", 1, TRANS_TYPE, "hour", 0, 0 },
|
||||
{"Hplu", 1, STR_TYPE, &DynamicHplu, 0, 0 },
|
||||
{"HushMode", 0, INT_TYPE, &Hush, 0, 0 },
|
||||
@@ -1001,6 +1003,7 @@ static SysVar SysVarArr[] = {
|
||||
{"IntMin", 0, INT_TYPE, &IntMin, 0, 0 },
|
||||
{"Is", 1, TRANS_TYPE, "is", 0, 0 },
|
||||
{"January", 1, TRANS_TYPE, "January", 0, 0 },
|
||||
{"JSONMode", 0, INT_TYPE, &JSONMode, 0, 0 },
|
||||
{"July", 1, TRANS_TYPE, "July", 0, 0 },
|
||||
{"June", 1, TRANS_TYPE, "June", 0, 0 },
|
||||
{"LatDeg", 1, SPECIAL_TYPE, latdeg_func, 0, 0 },
|
||||
@@ -1058,6 +1061,7 @@ static SysVar SysVarArr[] = {
|
||||
{"TimetIs64bit", 0, SPECIAL_TYPE, timet_is_64_func, 0, 0 },
|
||||
{"Tm", 0, SPECIAL_TYPE, trig_mon_func, 0, 0 },
|
||||
{"Today", 1, TRANS_TYPE, "today", 0, 0 },
|
||||
{"TodoFilter", 0, INT_TYPE, &TodoFilter, 0, 0 },
|
||||
{"Tomorrow", 1, TRANS_TYPE, "tomorrow", 0, 0 },
|
||||
{"Tt", 0, SPECIAL_TYPE, trig_time_func, 0, 0 },
|
||||
{"Tu", 0, SPECIAL_TYPE, trig_until_func, 0, 0 },
|
||||
|
||||
5
tests/json-redirect.rem
Normal file
5
tests/json-redirect.rem
Normal file
@@ -0,0 +1,5 @@
|
||||
BANNER %
|
||||
SET $AddBlankLines 0
|
||||
REM MSG Hello
|
||||
REM RUN echo This is executed by the shell.
|
||||
REM MSG Goodbye
|
||||
44
tests/safety.rem
Normal file
44
tests/safety.rem
Normal file
@@ -0,0 +1,44 @@
|
||||
BANNER %
|
||||
SET $AddBlankLines 0
|
||||
|
||||
FSET danger(x) shell("echo oops")
|
||||
|
||||
RUN OFF
|
||||
FSET safe(x) shell("echo nope")
|
||||
FSET safe2(x) danger(x)
|
||||
RUN ON
|
||||
|
||||
DEBUG +x
|
||||
set a danger(1)
|
||||
set b safe(1)
|
||||
set c safe2(1)
|
||||
|
||||
PUSH-FUNCS safe
|
||||
FSET safe(x) shell("echo this will work")
|
||||
SET b safe(1)
|
||||
POP-FUNCS
|
||||
SET b safe(1)
|
||||
|
||||
FRENAME safe gloopy
|
||||
FRENAME danger bork
|
||||
set a bork(1)
|
||||
set b gloopy(1)
|
||||
FRENAME gloopy safe
|
||||
FRENAME bork danger
|
||||
|
||||
RUN OFF
|
||||
set a danger(1)
|
||||
set b safe(1)
|
||||
set b safe2(1)
|
||||
|
||||
RUN ON
|
||||
|
||||
DEBUG -x
|
||||
FSET subst_b(a, b, c) shell("echo nooooo....")
|
||||
|
||||
REM MSG [subst_b(1, 2, 3)]
|
||||
FLUSH
|
||||
REM MSG %b
|
||||
FLUSH
|
||||
REM MSG [subst_b(1, 2, 3)]
|
||||
FLUSH
|
||||
285
tests/test-rem
285
tests/test-rem
@@ -59,87 +59,87 @@ chmod 000 include_dir/04cantread.rem
|
||||
TEST_GETENV="foo bar baz" ; export TEST_GETENV
|
||||
echo "Test 1" > ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -e -dxte ../tests/test.rem 16 feb 1991 12:13 2>&1 | grep -v 'TimetIs64bit' >> ../tests/test.out
|
||||
../src/remind --flush -e -dxte ../tests/test.rem 16 feb 1991 12:13 2>&1 | grep -v 'TimetIs64bit' >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
echo "Test 2" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -p -l ../tests/test2.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -p -l ../tests/test2.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
echo "" >> ../tests/test.out
|
||||
echo "Test 3" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -s ../tests/test2.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -s ../tests/test2.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
echo "" >> ../tests/test.out
|
||||
echo "Test 4" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -sa ../tests/test2.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -sa ../tests/test2.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
echo "Test 5" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -p -l -b0 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -p -l -b0 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
echo "Test 6" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -p -l -b1 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -p -l -b1 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
echo "Test 7" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -p -l -b2 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -p -l -b2 ../tests/test3.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "Test 8" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -df -p -l -b2 ../tests/include_dir 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -df -p -l -b2 ../tests/include_dir 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "Test 9" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -df -p -l -b2 ../tests/nonexistent_include_dir 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind -df -p -l -b2 ../tests/include_dir_no_rems 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind -df -p -l -b2 ../tests/include_test.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -df -p -l -b2 ../tests/nonexistent_include_dir 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -df -p -l -b2 ../tests/include_dir_no_rems 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -df -p -l -b2 ../tests/include_test.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
|
||||
chmod 644 include_dir/04cantread.rem
|
||||
|
||||
# Feb 29 bug
|
||||
echo "Feb 29 Bug Test" >> ../tests/test.out
|
||||
echo 'REM Sun 29 Feb MSG [$T]' | ../src/remind -dt - 1 feb 2021 >> ../tests/test.out 2>&1
|
||||
echo 'REM Sun 29 Feb MSG [$T]' | ../src/remind --flush -dt - 1 feb 2021 >> ../tests/test.out 2>&1
|
||||
|
||||
# Day Weekday Year out-of-year bug
|
||||
echo "Mon 31 Dec Bug Test" >> ../tests/test.out
|
||||
echo 'REM Mon 31 2021 MSG [$T]' | ../src/remind -dt - 31 dec 2021 >> ../tests/test.out 2>&1
|
||||
echo 'REM Mon 31 2021 MSG [$T]' | ../src/remind --flush -dt - 31 dec 2021 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "Color Test" >> ../tests/test.out
|
||||
../src/remind -ccl ../tests/colors.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -ccl ../tests/colors.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "ANSI Color Test" >> ../tests/test.out
|
||||
../src/remind ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@2 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@0,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@1,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@2,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@2,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@0,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@1,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@2,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@0,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@1,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@2,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@0,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@1,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -@2,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
|
||||
echo '$AddBlankLines test' >> ../tests/test.out
|
||||
../src/remind ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind '-i$AddBlankLines=1' ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind '-i$AddBlankLines=0' ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush '-i$AddBlankLines=1' ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush '-i$AddBlankLines=0' ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "MON WKDAY DAY across year test" >> ../tests/test.out
|
||||
echo 'REM Mon 29 Dec MSG x' | ../src/remind -dt - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
echo 'REM Mon 29 Dec MSG x' | ../src/remind --flush -dt - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "Sort Test" >> ../tests/test.out
|
||||
(echo "REM AT 12:00 MSG Untimed"; echo "REM MSG Timed") | ../src/remind -q -gaaa - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
(echo "REM AT 12:00 MSG Untimed"; echo "REM MSG Timed") | ../src/remind -q -gaaad - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
(echo "REM AT 12:00 MSG Untimed"; echo "REM MSG Timed") | ../src/remind --flush -q -gaaa - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
(echo "REM AT 12:00 MSG Untimed"; echo "REM MSG Timed") | ../src/remind --flush -q -gaaad - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "Purge Test" >> ../tests/test.out
|
||||
../src/remind -j999 ../tests/purge_dir/f1.rem 3 Feb 2012 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -j999 ../tests/purge_dir/f1.rem 3 Feb 2012 >> ../tests/test.out 2>&1
|
||||
echo "F1" >> ../tests/test.out
|
||||
cat ../tests/purge_dir/f1.rem.purged >> ../tests/test.out
|
||||
echo "F2" >> ../tests/test.out
|
||||
@@ -150,7 +150,7 @@ cat ../tests/purge_dir/f3.rem.purged >> ../tests/test.out
|
||||
rm -f ../tests/purge_dir/*.rem.purged >> ../tests/test.out 2>&1
|
||||
|
||||
echo "Hush Purge Test" >> ../tests/test.out
|
||||
../src/remind -h -j999 ../tests/purge_dir/f1.rem 3 Feb 2012 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -h -j999 ../tests/purge_dir/f1.rem 3 Feb 2012 >> ../tests/test.out 2>&1
|
||||
echo "F1" >> ../tests/test.out
|
||||
cat ../tests/purge_dir/f1.rem.purged >> ../tests/test.out
|
||||
echo "F2" >> ../tests/test.out
|
||||
@@ -160,22 +160,22 @@ cat ../tests/purge_dir/f3.rem.purged >> ../tests/test.out
|
||||
|
||||
rm -f ../tests/purge_dir/*.rem.purged >> ../tests/test.out 2>&1
|
||||
|
||||
../src/remind ../tests/runtest.rem >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/runtest.rem >> ../tests/test.out 2>&1
|
||||
|
||||
../src/remind -p ../tests/shade.rem 1 August 2009 | ../src/rem2ps -e -l -c3 >> ../tests/test.out 2>&1
|
||||
../src/remind -pp ../tests/shade.rem 1 August 2009 | ../src/rem2ps -e -l -c3 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -p ../tests/shade.rem 1 August 2009 | ../src/rem2ps -e -l -c3 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -pp ../tests/shade.rem 1 August 2009 | ../src/rem2ps -e -l -c3 >> ../tests/test.out 2>&1
|
||||
|
||||
TZ=America/Toronto ../src/remind ../tests/sunmoon.rem 1 Jan 2011 >> ../tests/test.out 2>&1
|
||||
TZ=America/Toronto ../src/remind --flush ../tests/sunmoon.rem 1 Jan 2011 >> ../tests/test.out 2>&1
|
||||
|
||||
# Test -a vs -aa
|
||||
../src/remind -q -a - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -q -a - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
REM 1 Jan 2012 AT 8:00 MSG 8am: Should not show up
|
||||
REM 1 Jan 2012 AT 9:00 MSG 9am: Should not show up
|
||||
REM 1 Jan 2012 AT 10:00 MSG 10am: Should not show up
|
||||
MSG [$DontTrigAts]
|
||||
EOF
|
||||
|
||||
../src/remind -q -a -a - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -q -a -a - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
REM 1 Jan 2012 AT 8:00 MSG 8am: Should not show up
|
||||
REM 1 Jan 2012 AT 9:00 MSG 9am: Should show up
|
||||
REM 1 Jan 2012 AT 10:00 MSG 10am: Should show up
|
||||
@@ -183,12 +183,12 @@ MSG [$DontTrigAts]
|
||||
EOF
|
||||
|
||||
# OMITFUNC should indicate nonconst_expr
|
||||
../src/remind -pp - 1 jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -pp - 1 jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
REM Mon OMITFUNC foo MSG bar
|
||||
EOF
|
||||
|
||||
# Test default color
|
||||
../src/remind -pppq - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -pppq - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
REM 2 MSG Normal
|
||||
SET $DefaultColor "255 0 0"
|
||||
REM 3 \
|
||||
@@ -201,7 +201,7 @@ SET $DefaultColor \
|
||||
EOF
|
||||
|
||||
# Test default color with weekly calendar
|
||||
../src/remind -pq+ - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -pq+ - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
REM 2 MSG Normal
|
||||
SET $DefaultColor "255 0 0"
|
||||
REM 3 MSG %"Red%" on the calendar!
|
||||
@@ -212,18 +212,18 @@ SET $DefaultColor "256 0 0"
|
||||
EOF
|
||||
|
||||
# Test stdout
|
||||
../src/remind - 1 jan 2012 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush - 1 jan 2012 <<'EOF' >> ../tests/test.out 2>&1
|
||||
BANNER %
|
||||
MSG STDOUT is a: [stdout()]%
|
||||
EOF
|
||||
|
||||
../src/remind - 1 jan 2012 <<'EOF' 2>&1 | cat >> ../tests/test.out
|
||||
../src/remind --flush - 1 jan 2012 <<'EOF' 2>&1 | cat >> ../tests/test.out
|
||||
BANNER %
|
||||
MSG STDOUT is a: [stdout()]%
|
||||
EOF
|
||||
|
||||
# Test -@ option
|
||||
../src/remind -w,0,0 -@0,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -w,0,0 -@0,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
SET $SuppressLRM 1
|
||||
rem 1 SPECIAL COLOR 0 0 0 BLACK
|
||||
rem 2 SPECIAL COLOR 0 0 65 BLUE
|
||||
@@ -246,7 +246,7 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
|
||||
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
|
||||
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
|
||||
EOF
|
||||
../src/remind -w,0,0 -@0,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -w,0,0 -@0,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
SET $SuppressLRM 1
|
||||
rem 1 SPECIAL COLOR 0 0 0 BLACK
|
||||
rem 2 SPECIAL COLOR 0 0 65 BLUE
|
||||
@@ -269,7 +269,7 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
|
||||
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
|
||||
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
|
||||
EOF
|
||||
../src/remind -w,0,0 -@0,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -w,0,0 -@0,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
SET $SuppressLRM 1
|
||||
rem 1 SPECIAL COLOR 0 0 0 BLACK
|
||||
rem 2 SPECIAL COLOR 0 0 65 BLUE
|
||||
@@ -292,7 +292,7 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
|
||||
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
|
||||
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
|
||||
EOF
|
||||
../src/remind -w,0,0 -@1,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -w,0,0 -@1,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
SET $SuppressLRM 1
|
||||
rem 1 SPECIAL COLOR 0 0 0 BLACK
|
||||
rem 2 SPECIAL COLOR 0 0 65 BLUE
|
||||
@@ -315,7 +315,7 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
|
||||
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
|
||||
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
|
||||
EOF
|
||||
../src/remind -w,0,0 -@1,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -w,0,0 -@1,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
SET $SuppressLRM 1
|
||||
rem 1 SPECIAL COLOR 0 0 0 BLACK
|
||||
rem 2 SPECIAL COLOR 0 0 65 BLUE
|
||||
@@ -338,7 +338,7 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
|
||||
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
|
||||
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
|
||||
EOF
|
||||
../src/remind -w,0,0 -@1,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -w,0,0 -@1,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
SET $SuppressLRM 1
|
||||
rem 1 SPECIAL COLOR 0 0 0 BLACK
|
||||
rem 2 SPECIAL COLOR 0 0 65 BLUE
|
||||
@@ -361,7 +361,7 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
|
||||
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
|
||||
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
|
||||
EOF
|
||||
../src/remind -w,0,0 -@2,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -w,0,0 -@2,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
SET $SuppressLRM 1
|
||||
rem 1 SPECIAL COLOR 0 0 0 BLACK
|
||||
rem 2 SPECIAL COLOR 0 0 65 BLUE
|
||||
@@ -384,7 +384,7 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
|
||||
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
|
||||
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
|
||||
EOF
|
||||
../src/remind -w,0,0 -@2,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -w,0,0 -@2,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
SET $SuppressLRM 1
|
||||
rem 1 SPECIAL COLOR 0 0 0 BLACK
|
||||
rem 2 SPECIAL COLOR 0 0 65 BLUE
|
||||
@@ -407,7 +407,7 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
|
||||
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
|
||||
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
|
||||
EOF
|
||||
../src/remind -w,0,0 -@2,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -w,0,0 -@2,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
|
||||
SET $SuppressLRM 1
|
||||
rem 1 SPECIAL COLOR 0 0 0 BLACK
|
||||
rem 2 SPECIAL COLOR 0 0 65 BLUE
|
||||
@@ -431,59 +431,59 @@ rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
|
||||
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
|
||||
EOF
|
||||
|
||||
../src/remind -w128 -c ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
../src/remind -c ../tests/test-addomit.rem 1 Sep 2021 >> ../tests/test.out
|
||||
../src/remind --flush -w128 -c ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
../src/remind --flush -c ../tests/test-addomit.rem 1 Sep 2021 >> ../tests/test.out
|
||||
|
||||
../src/remind -cu ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
../src/remind -cu '-i$SuppressLRM=1' ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
../src/remind --flush -cu ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
../src/remind --flush -cu '-i$SuppressLRM=1' ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
|
||||
TZ=America/Toronto ../src/remind -dxe ../tests/tz.rem >> ../tests/test.out 2>&1
|
||||
TZ=Europe/Berlin ../src/remind -dxe ../tests/tz.rem >> ../tests/test.out 2>&1
|
||||
TZ=America/Toronto ../src/remind --flush -dxe ../tests/tz.rem >> ../tests/test.out 2>&1
|
||||
TZ=Europe/Berlin ../src/remind --flush -dxe ../tests/tz.rem >> ../tests/test.out 2>&1
|
||||
|
||||
../src/remind ../tests/soleq.rem 1 April 2044 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/soleq.rem 1 April 2044 >> ../tests/test.out 2>&1
|
||||
|
||||
# Test that banner is printed on every iteration
|
||||
echo "MSG Should be three banners." | ../src/remind - 2022-10-20 '*3' >> ../tests/test.out 2>&1
|
||||
echo "MSG Should be three banners." | ../src/remind --flush - 2022-10-20 '*3' >> ../tests/test.out 2>&1
|
||||
|
||||
# Test the -tn option
|
||||
echo "REM May 23 +10 MSG Orange %b" | ../src/remind - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 +10 MSG Quux %b" | ../src/remind -t1 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 +10 MSG Cabbage %b" | ../src/remind -t2 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 MSG Banana %b" | ../src/remind - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 MSG Carrot %b" | ../src/remind -t1 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 MSG Apple %b" | ../src/remind -t2 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 +10 MSG Orange %b" | ../src/remind --flush - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 +10 MSG Quux %b" | ../src/remind --flush -t1 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 +10 MSG Cabbage %b" | ../src/remind --flush -t2 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 MSG Banana %b" | ../src/remind --flush - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 MSG Carrot %b" | ../src/remind --flush -t1 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 23 MSG Apple %b" | ../src/remind --flush -t2 - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
|
||||
# Test the -tz option
|
||||
echo "REM May 22 +10 MSG Foo %b" | ../src/remind - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 22 +10 MSG Bar %b" | ../src/remind -tz - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 22 +10 MSG Foo %b" | ../src/remind --flush - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
echo "REM May 22 +10 MSG Bar %b" | ../src/remind --flush -tz - 2023-05-21 >> ../tests/test.out 2>&1
|
||||
|
||||
# World-writable file
|
||||
rm -rf include_dir/ww
|
||||
touch include_dir/ww
|
||||
chmod 0666 include_dir/ww
|
||||
../src/remind include_dir/ww >> ../tests/test.out 2>&1
|
||||
../src/remind --flush include_dir/ww >> ../tests/test.out 2>&1
|
||||
rm -rf include_dir/ww
|
||||
|
||||
# World-writable directory
|
||||
mkdir -p include_dir/ww
|
||||
touch include_dir/ww/0.rem
|
||||
chmod 0777 include_dir/ww
|
||||
../src/remind include_dir/ww >> ../tests/test.out 2>&1
|
||||
../src/remind --flush include_dir/ww >> ../tests/test.out 2>&1
|
||||
rm -rf include_dir/ww
|
||||
|
||||
# This segfaulted in 04.02.03
|
||||
../src/remind -h '-imsgprefix(x)="foo"' /dev/null >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -h '-imsgprefix(x)="foo"' /dev/null >> ../tests/test.out 2>&1
|
||||
|
||||
# Test --version long option
|
||||
../src/remind --version >> ../tests/test.out 2>&1
|
||||
../src/remind --flush --version >> ../tests/test.out 2>&1
|
||||
|
||||
# Test queueing. Because eventstart depends on the actual system
|
||||
# date, we use the --test flag to fake the date and time.
|
||||
echo JSONQUEUE | ../src/remind --test -z0 ../tests/queue1.rem >> ../tests/test.out 2>&1
|
||||
echo QUEUE | ../src/remind --test -zj ../tests/queue1.rem >> ../tests/test.out 2>&1
|
||||
echo JSONQUEUE | ../src/remind --flush --test -z0 ../tests/queue1.rem >> ../tests/test.out 2>&1
|
||||
echo QUEUE | ../src/remind --flush --test -zj ../tests/queue1.rem >> ../tests/test.out 2>&1
|
||||
|
||||
# Test for leap year bug that was fixed
|
||||
../src/remind -dte - 28 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -dte - 28 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
BANNER %
|
||||
REM 29 MSG One
|
||||
REM 29 Feb MSG two
|
||||
@@ -503,7 +503,7 @@ REM Friday 29 2024 MSG three
|
||||
REM Friday 29 Feb 2024 MSG four
|
||||
EOF
|
||||
|
||||
../src/remind -dte - 1 Mar 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -dte - 1 Mar 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
BANNER %
|
||||
REM 29 MSG One
|
||||
REM 29 Feb MSG two
|
||||
@@ -523,7 +523,7 @@ REM Friday 29 2024 MSG three
|
||||
REM Friday 29 Feb 2024 MSG four
|
||||
EOF
|
||||
|
||||
../src/remind -dte - 28 Feb 2025 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -dte - 28 Feb 2025 <<'EOF' >> ../tests/test.out 2>&1
|
||||
BANNER %
|
||||
REM 29 MSG One
|
||||
REM 29 Feb MSG two
|
||||
@@ -543,7 +543,7 @@ REM Friday 29 2025 MSG three
|
||||
REM Friday 29 Feb 2025 MSG four
|
||||
EOF
|
||||
|
||||
../src/remind -dte - 1 Mar 2025 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -dte - 1 Mar 2025 <<'EOF' >> ../tests/test.out 2>&1
|
||||
BANNER %
|
||||
REM 29 MSG One
|
||||
REM 29 Feb MSG two
|
||||
@@ -564,21 +564,21 @@ REM Friday 29 Feb 2025 MSG four
|
||||
EOF
|
||||
|
||||
|
||||
(echo 'BANNER %'; echo 'REM 29 MSG No bug') | ../src/remind -dt - 29 Feb 2024 >> ../tests/test.out 2>&1
|
||||
(echo 'BANNER %'; echo 'REM 29 MSG No bug') | ../src/remind --flush -dt - 29 Feb 2024 >> ../tests/test.out 2>&1
|
||||
|
||||
../src/remind -ifoo - <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -ifoo - <<'EOF' >> ../tests/test.out 2>&1
|
||||
BANNER %
|
||||
DUMP
|
||||
EOF
|
||||
|
||||
../src/remind '-i$AddBlankLines' - <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush '-i$AddBlankLines' - <<'EOF' >> ../tests/test.out 2>&1
|
||||
BANNER %
|
||||
DUMP
|
||||
EOF
|
||||
|
||||
../src/remind ../tests/expr.rem >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/expr.rem >> ../tests/test.out 2>&1
|
||||
|
||||
../src/remind - <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush - <<'EOF' >> ../tests/test.out 2>&1
|
||||
PUSH
|
||||
POP
|
||||
PUSH
|
||||
@@ -594,48 +594,53 @@ PUSH
|
||||
POP
|
||||
EOF
|
||||
|
||||
../src/remind ../tests/if1.rem 2020-03-03 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/if1.rem 2020-03-03 >> ../tests/test.out 2>&1
|
||||
|
||||
# Test ONCE with a timestamp file
|
||||
rm -f ../tests/once.timestamp
|
||||
../src/remind ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
../src/remind ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
../src/remind ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
tail -n+2 ../tests/once.timestamp >> ../tests/test.out 2>&1
|
||||
rm -f ../tests/once.timestamp
|
||||
|
||||
../src/remind - < ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
../src/remind - < ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
../src/remind - < ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
../src/remind --flush - < ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
../src/remind --flush - < ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
../src/remind --flush - < ../tests/test-once.rem >> ../tests/test.out 2>&1
|
||||
tail -n+2 ../tests/once.timestamp >> ../tests/test.out 2>&1
|
||||
rm -f ../tests/once.timestamp
|
||||
|
||||
# Newlines in calendar output
|
||||
(echo 'SET $SuppressLRM 1'; echo 'REM 16 MSG foo%_bar%_baz wookie quux apple %_ %_ %_ blech'; echo "REM 16 MSG ANOTHER") | ../src/remind -c -w80 - 1 sep 1990 >> ../tests/test.out 2>&1
|
||||
(echo 'SET $SuppressLRM 1'; echo 'REM 16 MSG foo%_bar%_baz wookie quux apple %_ %_ %_ blech'; echo "REM 16 MSG ANOTHER") | ../src/remind --flush -c -w80 - 1 sep 1990 >> ../tests/test.out 2>&1
|
||||
|
||||
# Dedupe feature
|
||||
../src/remind -c ../tests/dedupe.rem 1 November 2023 >> ../tests/test.out 2>&1
|
||||
../src/remind -q ../tests/dedupe.rem 8 November 2023 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -c ../tests/dedupe.rem 1 November 2023 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -q ../tests/dedupe.rem 8 November 2023 >> ../tests/test.out 2>&1
|
||||
|
||||
# Remove references to SysInclude, which is build-specific
|
||||
grep -F -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out
|
||||
|
||||
# If "man" accepts the --warnings flag, test all the man pages.
|
||||
RUNMAN=0
|
||||
man man | grep -e --warnings > /dev/null 2>&1
|
||||
if test $? = 0 ; then
|
||||
for i in ../man/*.1 ; do
|
||||
man --warnings=w $i 2>>../tests/test.out 1>/dev/null
|
||||
done
|
||||
if test "$?" = 0 ; then
|
||||
RUNMAN=1
|
||||
fi
|
||||
for i in ../man/*.1 ; do
|
||||
echo "Checking $i..." >> ../tests/test.out
|
||||
if test "$RUNMAN" = 1 ; then
|
||||
man --warnings=w $i 2>>../tests/test.out 1>/dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
# Test --print-tokens long option
|
||||
../src/remind --print-tokens < /dev/null >> ../tests/test.out 2>&1
|
||||
../src/remind --flush --print-tokens < /dev/null >> ../tests/test.out 2>&1
|
||||
|
||||
# Torture test #2
|
||||
../src/remind ../tests/torture2.rem >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/torture2.rem >> ../tests/test.out 2>&1
|
||||
|
||||
# Expression error-reporting
|
||||
../src/remind -de - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -de - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
set a 8 * "]]]" & 6
|
||||
msg [8 * "]]]" & 6] is weird
|
||||
set a 9 *
|
||||
@@ -643,13 +648,13 @@ set a 9 * ]
|
||||
EOF
|
||||
|
||||
# Translation template generateion
|
||||
../src/remind -h - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -h - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
TRANSLATE GENERATE
|
||||
EOF
|
||||
|
||||
# Make sure stupidly-long translations of "am" and "pm" can't cause a
|
||||
# segmentation fault
|
||||
../src/remind -c - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -c - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
TRANS "am" "alsdkjalksdj alksjd alksdj alksjd laksjd laksjd laksjd laksjd laksjd laksjd laksjd laksjd lkasjd laksjd laksjd lkajs dlkajs dlkasj dlkasjd lkajsd lkajs dlkasjd lkasj dlkajsd lkasjd lkasjd laksjd laksjd laksjd alskdj alskdj alksdj alksdj alskdj alksdj aslkdj"
|
||||
TRANS "pm" "oiwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwjwwwwwwwwwwwwwwwjwpqoejkpqwojepqowjepqojwepqowjepqowjepqowjepqowjepqowjepqowjepqojwepqowjepqowjepqowjepqowjepqowjeqpweoj"
|
||||
|
||||
@@ -658,12 +663,12 @@ REM WED AT 13:00 MSG blah
|
||||
EOF
|
||||
|
||||
# The INFO keyword
|
||||
../src/remind -pp - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -pp - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
REM Wed INFO "Location: here" INFO "Summary: Nope" MSG Meeting [triginfo("location")] %<summary> %<nonexist> [triginfo("cabbage")]
|
||||
EOF
|
||||
|
||||
# Invalid info strings
|
||||
../src/remind - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
REM Thu INFO "Invalid" MSG wookie
|
||||
REM Fri INFO ": foo" MSG blat
|
||||
REM Sun INFO "foo bar baz : blork" MSG uua
|
||||
@@ -673,7 +678,7 @@ REM Sat INFO "Location: here" INFO "location: there" MSG blort
|
||||
EOF
|
||||
|
||||
# Test parsing of quoted strings and the "escape" function
|
||||
../src/remind - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush - 1 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||
BANNER %
|
||||
SET $AddBlankLines 0
|
||||
TRANSLATE "foo" "test: \\\" \a\b\f\\n\r\t\v\x3\x1b haha"
|
||||
@@ -703,40 +708,40 @@ set a "\x00P"
|
||||
EOF
|
||||
|
||||
# Test diagnostics when using a timed substitution without an AT clause
|
||||
../src/remind - 1 Feb 2024 1:00 <<EOF >> ../tests/test.out 2>&1
|
||||
../src/remind --flush - 1 Feb 2024 1:00 <<EOF >> ../tests/test.out 2>&1
|
||||
REM MSG %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 hahaha
|
||||
EOF
|
||||
|
||||
# Test translate table dumping
|
||||
../src/remind - 1 Feb 2024 <<EOF >> ../tests/test.out 2>&1
|
||||
../src/remind --flush - 1 Feb 2024 <<EOF >> ../tests/test.out 2>&1
|
||||
TRANSLATE "\x03" "BREAK"
|
||||
TRANSLATE DUMP
|
||||
EOF
|
||||
|
||||
../src/remind -ppp - 1 Feb 2024 <<EOF >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -ppp - 1 Feb 2024 <<EOF >> ../tests/test.out 2>&1
|
||||
TRANSLATE "\x03" "BREAK"
|
||||
EOF
|
||||
|
||||
# SCANFROM should be preserved even if it is today
|
||||
../src/remind -ppp - 1 Feb 2024 <<EOF >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -ppp - 1 Feb 2024 <<EOF >> ../tests/test.out 2>&1
|
||||
REM SCANFROM 2024-02-01 MSG Preserve SCANFROM
|
||||
EOF
|
||||
# Languages
|
||||
for i in ../include/lang/??.rem ; do
|
||||
../src/remind -r -q "-ii=\"$i\"" ../tests/tstlang.rem 1 Feb 2024 13:34 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -r -q "-ii=\"$i\"" ../tests/tstlang.rem 1 Feb 2024 13:34 >> ../tests/test.out 2>&1
|
||||
done
|
||||
|
||||
# Fix for $DefaultColor bug with remind -s
|
||||
../src/remind -s - 1 Feb 2024 >> ../tests/test.out 2>&1 <<'EOF'
|
||||
../src/remind --flush -s - 1 Feb 2024 >> ../tests/test.out 2>&1 <<'EOF'
|
||||
SET $DefaultColor "255 0 0"
|
||||
REM Wed MSG Wookie
|
||||
EOF
|
||||
|
||||
# Test year-folding
|
||||
TZ=America/Toronto ../src/remind -dx ../tests/yearfold.rem >> ../tests/test.out 2>&1
|
||||
TZ=America/Toronto ../src/remind --flush -dx ../tests/yearfold.rem >> ../tests/test.out 2>&1
|
||||
|
||||
# Test unused-variable debugging
|
||||
../src/remind -du - <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -du - <<'EOF' >> ../tests/test.out 2>&1
|
||||
set a 1
|
||||
set b a*2
|
||||
set c "What"
|
||||
@@ -751,24 +756,44 @@ unset y
|
||||
EOF
|
||||
|
||||
# Test RETURN statement
|
||||
../src/remind ../tests/ret1.rem 4 June 2000 >> ../tests/test.out 2>&1
|
||||
../src/remind ../tests/ret1.rem 5 June 2000 >> ../tests/test.out 2>&1
|
||||
../src/remind ../tests/ret1.rem 7 June 2000 >> ../tests/test.out 2>&1
|
||||
../src/remind -s ../tests/ret1.rem 1 June 2000 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/ret1.rem 4 June 2000 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/ret1.rem 5 June 2000 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/ret1.rem 7 June 2000 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -s ../tests/ret1.rem 1 June 2000 >> ../tests/test.out 2>&1
|
||||
|
||||
# Make sure all the include files are ok
|
||||
find ../include -type f -name '*.rem' | while read x; do ../src/remind -du -n $x 1 Jan 2024 2>>../tests/test.out 1>/dev/null; done
|
||||
find ../include -type f -name '*.rem' | while read x; do ../src/remind --flush -du -n $x 1 Jan 2024 2>>../tests/test.out 1>/dev/null; done
|
||||
|
||||
# Test todos
|
||||
echo "" >> ../tests/test.out 2>&1
|
||||
echo "Testing TODOS in agenda mode" >> ../tests/test.out 2>&1
|
||||
../src/remind ../tests/todos.rem 2025-08-13 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush ../tests/todos.rem 2025-08-13 >> ../tests/test.out 2>&1
|
||||
echo "" >> ../tests/test.out 2>&1
|
||||
echo "Testing TODOS in calendar mode" >> ../tests/test.out 2>&1
|
||||
../src/remind -s ../tests/todos.rem 2025-08-13 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -s ../tests/todos.rem 2025-08-13 >> ../tests/test.out 2>&1
|
||||
echo "" >> ../tests/test.out 2>&1
|
||||
echo "Testing TODOS in calendar mode with completed todos hidden" >> ../tests/test.out 2>&1
|
||||
../src/remind -s --hide-completed-todos ../tests/todos.rem 2025-08-13 >> ../tests/test.out 2>&1
|
||||
../src/remind --flush -s --hide-completed-todos ../tests/todos.rem 2025-08-13 >> ../tests/test.out 2>&1
|
||||
echo "Testing TODOS and JSON mode" >> ../tests/test.out 2>&1
|
||||
../src/remind --flush --json ../tests/todos.rem 2025-08-13 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "Testing proper redirection of RUN stdout in JSON mode... here's stdout" >> ../tests/test.out 2>&1
|
||||
../src/remind --flush --json ../tests/json-redirect.rem 1 Jan 2025 >> ../tests/test.out 2>/dev/null
|
||||
|
||||
echo "... and here is stderr" >> ../tests/test.out 2>&1
|
||||
../src/remind --flush --json ../tests/json-redirect.rem 1 Jan 2025 > /dev/null 2>> ../tests/test.out
|
||||
|
||||
# Test %: substitution sequence in all the languages
|
||||
for i in ../include/lang/??.rem ; do
|
||||
../src/remind --flush "-ii=\"$i\"" -p - 2025-08-13 <<'EOF' 2>&1 | grep 2025/ >> ../tests/test.out
|
||||
DO [i]
|
||||
REM TODO 2025-08-13 MSG %(LANGID) Task1%:
|
||||
REM TODO 2025-08-13 COMPLETE-THROUGH 2025-08-12 MSG %(LANGID) Task2%:
|
||||
REM TODO 2025-08-13 COMPLETE-THROUGH 2025-08-13 MSG %(LANGID) Task3%:
|
||||
EOF
|
||||
done
|
||||
|
||||
../src/remind --flush -q ../tests/safety.rem 2025-08-13 >> ../tests/test.out 2>&1
|
||||
|
||||
cmp -s ../tests/test.out ../tests/test.cmp
|
||||
if [ "$?" = "0" ]; then
|
||||
|
||||
1507
tests/test.cmp
1507
tests/test.cmp
File diff suppressed because it is too large
Load Diff
@@ -1707,6 +1707,15 @@ set a c()
|
||||
|
||||
DEBUG -xe
|
||||
|
||||
fset subst_colon(a, b, c) "subst_colon"
|
||||
fset subst_bang(a, b, c) "subst_bang"
|
||||
fset subst_question(a, b, c) "subst_question"
|
||||
fset subst_at(a, b, c) "subst_at"
|
||||
fset subst_hash(a, b, c) "subst_hash"
|
||||
|
||||
REM MSG Overridden: %: %! %? %@ %#
|
||||
|
||||
|
||||
# Don't want Remind to queue reminders
|
||||
EXIT
|
||||
|
||||
|
||||
@@ -10,3 +10,23 @@ REM TODO 6 Aug 2025 +7 MSG %"Sixth%" %l
|
||||
REM TODO COMPLETE-THROUGH 2025-08-06 6 Aug 2025 +7 MSG %"Seventh%" %l
|
||||
REM TODO Wed +7 COMPLETE-THROUGH 2025-08-13 MSG %"Eighth%" %l
|
||||
REM TODO Wed +7 COMPLETE-THROUGH 2025-08-12 MSG %"Ninth%" %l
|
||||
|
||||
# Test MAX-OVERDUE
|
||||
REM TODO 2025-08-13 MAX-OVERDUE 3 MSG %"Yup%" %l
|
||||
REM TODO 2025-08-12 MAX-OVERDUE 3 MSG %"Yup2%" %l
|
||||
REM TODO 2025-08-11 MAX-OVERDUE 3 MSG %"Yup3%" %l
|
||||
REM TODO 2025-08-10 MAX-OVERDUE 3 MSG %"Yup4%" %l
|
||||
REM TODO 2025-08-9 MAX-OVERDUE 3 MSG %"Nope%" %l
|
||||
|
||||
IF !$JSONMode
|
||||
REM TODO 2025-09-09 COMPLETE-THROUGH 2024-12-31 MAX-OVERDUE 3 MSG %"Nope%" %l
|
||||
debug +x
|
||||
set a trigistodo()
|
||||
set a trigcompletethrough()
|
||||
set a trigmaxoverdue()
|
||||
REM 2025-09-09 MSG blork
|
||||
set a trigistodo()
|
||||
set a trigcompletethrough()
|
||||
set a trigmaxoverdue()
|
||||
debug -x
|
||||
ENDIF
|
||||
Reference in New Issue
Block a user