mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
288 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5baf102bfe | ||
|
|
c9002d5b54 | ||
|
|
ac3ee7e22b | ||
|
|
f366037b8d | ||
|
|
a46488a50d | ||
|
|
f91a1a2d65 | ||
|
|
2ac8fb50e1 | ||
|
|
7df826f635 | ||
|
|
f8ce7b51da | ||
|
|
35ee94ca6b | ||
|
|
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 | ||
|
|
119e954e9e | ||
|
|
6aa07edffd | ||
|
|
bdb9ad1a5d | ||
|
|
05384fe7cf | ||
|
|
6125001e55 | ||
|
|
78b307e387 | ||
|
|
460d0a8d88 | ||
|
|
add35377ad | ||
|
|
fccd9ed42e | ||
|
|
a49ecccb34 | ||
|
|
ae9fe78817 | ||
|
|
dbc5576312 | ||
|
|
6cbbebceaf | ||
|
|
4dc27ca7f5 | ||
|
|
d8f97ce0f1 | ||
|
|
0e1a80f2bd | ||
|
|
4a7f703ab5 | ||
|
|
101de948b2 | ||
|
|
0e2d382b33 | ||
|
|
a6c5c3cb90 | ||
|
|
da573929ee | ||
|
|
5217d9b675 | ||
|
|
79a87c6f1a | ||
|
|
cde5ffc84a | ||
|
|
6ef323a4f0 | ||
|
|
8331ea2991 | ||
|
|
db28648d9d | ||
|
|
1a5915bba9 | ||
|
|
94a50fa22c | ||
|
|
fad6076568 | ||
|
|
287039ac40 | ||
|
|
8523218ef2 | ||
|
|
fdaaf2b57a | ||
|
|
19eac9b8d5 | ||
|
|
cda4877229 | ||
|
|
0976cd64f3 | ||
|
|
10f7889ef2 | ||
|
|
2391ff4bc7 | ||
|
|
d21ae56deb | ||
|
|
773980afa6 | ||
|
|
46a80da0e1 | ||
|
|
23516aebcb | ||
|
|
b48ce0b245 | ||
|
|
e4c090374d | ||
|
|
39fcbb72fd | ||
|
|
5f2bf48752 | ||
|
|
9e5354fcb8 | ||
|
|
49bdd135f7 | ||
|
|
f9a6aba81d | ||
|
|
175772d959 | ||
|
|
2f03c75826 | ||
|
|
d617000e95 | ||
|
|
04dee13996 | ||
|
|
ebcf6fd534 | ||
|
|
c7c58e20f3 | ||
|
|
a66ca7cce7 | ||
|
|
35cae5f97c | ||
|
|
6d86d88037 | ||
|
|
89f60358c6 | ||
|
|
781e5a6acd | ||
|
|
1b5d34e5e6 | ||
|
|
cb5fa62022 | ||
|
|
9d6ce5b674 | ||
|
|
1cdd9531a5 | ||
|
|
da4633fab3 | ||
|
|
aeff3606d2 | ||
|
|
2af36b7241 | ||
|
|
a7a22d20a2 | ||
|
|
3fdbf8b3bc | ||
|
|
a7696d659c | ||
|
|
865ebae6f8 | ||
|
|
f21f8ee8d0 | ||
|
|
76b7736266 | ||
|
|
0769e3e9cb | ||
|
|
d9ab9e91b5 | ||
|
|
9199ed5cf7 | ||
|
|
68a4b23b6f | ||
|
|
814dd51270 | ||
|
|
59fdf70732 | ||
|
|
24ed30fee0 | ||
|
|
86dcd9ce89 | ||
|
|
4915dc1e8d | ||
|
|
8c4cff22a5 | ||
|
|
50850134f6 | ||
|
|
a5de77cc91 | ||
|
|
87e4ed23bf | ||
|
|
0fe1d1591e | ||
|
|
dfb137085a | ||
|
|
143cdecb9e | ||
|
|
183ccf9d1c | ||
|
|
56ad4efb1a | ||
|
|
f4805a443b | ||
|
|
977aa3d6cf | ||
|
|
fe7ac980e5 | ||
|
|
aebab73dfa | ||
|
|
9bd0055d4d | ||
|
|
d944ceb32d | ||
|
|
3eadb3f767 | ||
|
|
be8a0621d1 | ||
|
|
235f947dd1 | ||
|
|
93dddec24a | ||
|
|
c13b721550 | ||
|
|
1c961dca83 | ||
|
|
700ac85e54 | ||
|
|
e20a14109a | ||
|
|
a3703173e2 | ||
|
|
7325375ccd | ||
|
|
4b898b2ba1 | ||
|
|
aa3760bc04 | ||
|
|
ea5e8c90ff | ||
|
|
609b68ab21 | ||
|
|
c3ab2a15cf | ||
|
|
418b050b1c | ||
|
|
4ab8897577 | ||
|
|
9613417a2e | ||
|
|
f808a2963d | ||
|
|
96a4dc3189 | ||
|
|
3c60285466 | ||
|
|
6fed350e1f | ||
|
|
9f220555af | ||
|
|
005ccef953 | ||
|
|
578c98c865 | ||
|
|
64bf3381c6 | ||
|
|
02ade6fc58 | ||
|
|
2954fca8d8 | ||
|
|
8356dacf2a | ||
|
|
4fd145cf4e | ||
|
|
1af2bdf8f1 | ||
|
|
9b98e65e01 | ||
|
|
0f83b98698 | ||
|
|
4fd62f9894 | ||
|
|
cc06592fe0 | ||
|
|
21d28ebfc3 | ||
|
|
b300422cdb | ||
|
|
37e09f4671 | ||
|
|
b6e53341c8 | ||
|
|
896fcf1d7f | ||
|
|
72155329f2 | ||
|
|
36c7db510a | ||
|
|
d4aa73747d | ||
|
|
3ed657b708 | ||
|
|
0441c0263b | ||
|
|
c40d4ee672 | ||
|
|
96f2d6537a | ||
|
|
dc777c95df | ||
|
|
3090d77346 | ||
|
|
157d2821f3 | ||
|
|
71d2da19a8 | ||
|
|
516b9c81b3 | ||
|
|
58d0e38f1a | ||
|
|
68d487ade9 | ||
|
|
9d42879170 | ||
|
|
db70aabc97 | ||
|
|
c8f55ef60b | ||
|
|
44b50fc6be | ||
|
|
a69a96529b | ||
|
|
f4e5cc63a6 | ||
|
|
136122b1db | ||
|
|
4cc63b1548 | ||
|
|
9390b4335b | ||
|
|
1fcf11a816 | ||
|
|
c4107e6a6f | ||
|
|
ab03232341 | ||
|
|
51a65841cd | ||
|
|
5035deaff1 | ||
|
|
09caa8988a | ||
|
|
9624b1045c | ||
|
|
102748397f | ||
|
|
f852f7e7e5 | ||
|
|
8d88192483 | ||
|
|
a6ca571fe5 | ||
|
|
2af783a58d | ||
|
|
af2daa7a87 | ||
|
|
c5bc459dd9 | ||
|
|
edf26eaa14 | ||
|
|
7e5dc26ee5 | ||
|
|
4c2b6031cd | ||
|
|
af8c1630c3 | ||
|
|
0ec43d570c | ||
|
|
1df8b12e71 | ||
|
|
3fb10fe946 | ||
|
|
e11dbcf52a | ||
|
|
88cc25e53f | ||
|
|
0c93e045bd | ||
|
|
99e5b3f43d | ||
|
|
f0f0cec2d3 | ||
|
|
70a97a8fe5 | ||
|
|
8a6857b787 | ||
|
|
95b82a4457 | ||
|
|
8fd39e477f | ||
|
|
3118f8d2a4 | ||
|
|
acf570512d | ||
|
|
cf2114e2ef | ||
|
|
357f7105bd | ||
|
|
e7094b71c2 | ||
|
|
8a3db4cba1 | ||
|
|
b33a3191f5 | ||
|
|
caa900d38d | ||
|
|
1d3c1f006f | ||
|
|
633812d961 | ||
|
|
ec8cae6d4b | ||
|
|
5019d54379 | ||
|
|
56e4f14a2f | ||
|
|
af5854d0c6 | ||
|
|
43d0066780 | ||
|
|
de2d15009f | ||
|
|
8ca5c7e56e | ||
|
|
bd6218d7e2 | ||
|
|
5d822e294d | ||
|
|
1e3657b728 | ||
|
|
a309af731f | ||
|
|
31c8893a2a | ||
|
|
e3a6c65983 | ||
|
|
1355b99560 | ||
|
|
21904e708f | ||
|
|
e4a6a5cf01 | ||
|
|
098cf4707a | ||
|
|
1be6ff23fb | ||
|
|
4db201945c | ||
|
|
6aa217044b | ||
|
|
c64d939237 | ||
|
|
398100c6e3 | ||
|
|
3fb1db0880 | ||
|
|
76bf57af60 | ||
|
|
a8fc88be17 | ||
|
|
a50f40d652 | ||
|
|
71b3564c03 | ||
|
|
a35de17b00 | ||
|
|
ab44f93f37 | ||
|
|
ab69fee895 | ||
|
|
db31214060 | ||
|
|
758e2c1a9d | ||
|
|
ed7c5103ff | ||
|
|
4590e746c5 | ||
|
|
bc8ce3e2cc |
3
Makefile
3
Makefile
@@ -42,6 +42,9 @@ install-stripped:
|
||||
test:
|
||||
@$(MAKE) -C src -s test
|
||||
|
||||
cppcheck:
|
||||
@$(MAKE) -C src cppcheck
|
||||
|
||||
distclean: clean
|
||||
-rm -f config.cache config.log config.status src/Makefile src/version.h src/config.h tests/test.out www/Makefile rem2pdf/Makefile.top rem2pdf/Makefile.old rem2pdf/Makefile rem2pdf/Makefile.PL rem2pdf/bin/rem2pdf rem2html/rem2html
|
||||
-rm -f man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1 scripts/tkremind
|
||||
|
||||
50
README.md
50
README.md
@@ -6,10 +6,14 @@ the GNU General Public License, Vesion 2.
|
||||
|
||||
## Prerequisites:
|
||||
|
||||
remind and rem2ps have no prerequisites beyond the standard C library and
|
||||
the standard math library.
|
||||
### Remind and Rem2PS
|
||||
|
||||
rem2html requires the JSON::MaybeXS Perl module and rem2pdf
|
||||
**remind** and **rem2ps** have no prerequisites beyond the standard C
|
||||
library and the standard math library.
|
||||
|
||||
### Rem2HTML and Rem2PDF
|
||||
|
||||
**rem2html** requires the JSON::MaybeXS Perl module and **rem2pdf**
|
||||
requires the JSON::MaybeXS, Pango and Cairo Perl modules.
|
||||
|
||||
- On Debian-like systems, these prerequisites may be installed with:
|
||||
@@ -24,7 +28,9 @@ requires the JSON::MaybeXS, Pango and Cairo Perl modules.
|
||||
|
||||
- On Arch linux, you need `pango-perl`, `cairo-perl` and `perl-json-maybexs`
|
||||
|
||||
TkRemind requires Tcl/Tk and the tcllib library.
|
||||
### TkRemind
|
||||
|
||||
**tkremind** requires Tcl/Tk and the tcllib library.
|
||||
|
||||
- On Debian-like systems, install with:
|
||||
|
||||
@@ -45,7 +51,8 @@ all of your distribution's Noto Font-related packages.
|
||||
|
||||
## Installation
|
||||
|
||||
Remind can be installed with the usual:
|
||||
Assuming you have a normal C development environment installed, Remind
|
||||
can be installed with the usual:
|
||||
|
||||
`./configure && make && make test && sudo make install`
|
||||
|
||||
@@ -55,6 +62,39 @@ edit custom.h on your behalf:
|
||||
|
||||
`wish ./build.tk`
|
||||
|
||||
## Usage
|
||||
|
||||
Remind is a large and complex program. You can read the full manual page
|
||||
with:
|
||||
|
||||
`man remind`
|
||||
|
||||
after installation. However, the man page is long and detailed and is
|
||||
more of a reference than an introduction. You can get an overview
|
||||
with a [slide deck](https://dianne.skoll.ca/projects/remind/download/remind-oclug.pdf)
|
||||
I made a while back. There's also a (long) [YouTube video](https://www.youtube.com/watch?v=0SNgvsDvx7M) that serves as an
|
||||
introduction to Remind.
|
||||
|
||||
## A Note about AI
|
||||
|
||||
1. No part of Remind was written using AI of any type.<br><br>
|
||||
I certify that all of the C, Perl and Tcl code in Remind was written
|
||||
by a human being. I certify that all code in `.rem` files other than
|
||||
ones under `include/holidays` was written by a human being. The code
|
||||
under `include/holidays` was derived from the Python "holidays" library
|
||||
and I have no direct knowledge of the provenance of that library,
|
||||
though I suspect it's entirely or almost entirely human-written.
|
||||
|
||||
2. No AI-generated patches or other sorts of contributions to Remind
|
||||
will be accepted.
|
||||
|
||||
3. Remind's source code may not be used to train an AI model,
|
||||
including an LLM model, unless all of the output of said model is
|
||||
released under the GNU General Public License, version 2. If you use
|
||||
any of Remind's source code to train your model, then anything that
|
||||
the model produces is a derived product of Remind and must be licensed
|
||||
under the same terms as Remind.
|
||||
|
||||
---
|
||||
|
||||
Contact info: dianne@skoll.ca
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(remind, 05.03.07, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_INIT(remind, 06.00.01, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_CONFIG_SRCDIR([src/queue.c])
|
||||
|
||||
cat <<'EOF'
|
||||
@@ -30,7 +30,8 @@ AC_PATH_PROG([PERL], [perl])
|
||||
|
||||
dnl Checks for libraries.
|
||||
AC_CHECK_LIB(m, sqrt)
|
||||
AC_CHECK_HEADERS_ONCE([sys/time.h stdint.h])
|
||||
AC_CHECK_LIB(readline, readline)
|
||||
AC_CHECK_HEADERS_ONCE([sys/time.h stdint.h readline/readline.h readline/history.h])
|
||||
|
||||
dnl Integer sizes
|
||||
AC_CHECK_SIZEOF(unsigned int)
|
||||
@@ -84,7 +85,7 @@ if test "$?" != 0 ; then
|
||||
echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!"
|
||||
exit 1
|
||||
fi
|
||||
AC_CHECK_FUNCS(strdup strcasecmp strncasecmp setenv unsetenv glob mbstowcs setlocale initgroups inotify_init1)
|
||||
AC_CHECK_FUNCS(strdup strcasecmp strncasecmp setenv unsetenv glob mbstowcs setlocale initgroups inotify_init1 readline)
|
||||
|
||||
VERSION=$PACKAGE_VERSION
|
||||
CONFIG_CMD="$0$ac_configure_args_raw"
|
||||
|
||||
@@ -110,15 +110,17 @@
|
||||
(defconst remind-keywords
|
||||
(sort
|
||||
(list "ADDOMIT" "AFTER" "AT" "BAN" "BANNER" "BEFORE" "CAL" "CLEAR"
|
||||
"CLEAR-OMIT-CONTEXT" "DEBUG" "DO" "DUMP" "DUMPVARS" "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" "MSG"
|
||||
"NOQUEUE" "OMIT" "OMITFUNC" "ONCE" "POP" "POP-OMIT-CONTEXT" "PRESERVE"
|
||||
"PRIORITY" "PS" "PSFILE" "PUSH" "PUSH-OMIT-CONTEXT" "REM" "RUN"
|
||||
"SATISFY" "SCAN" "SCANFROM" "SCHED" "SECOND" "SET" "SKIP" "SPECIAL"
|
||||
"SYSINCLUDE" "TAG" "THIRD" "THROUGH" "TRANSLATE" "TRANS" "UNSET"
|
||||
"UNTIL" "WARN")
|
||||
"CLEAR-OMIT-CONTEXT" "COMPLETE-THROUGH" "DEBUG" "DO" "DUMP" "DUMPVARS"
|
||||
"DURATION" "ELSE" "ENDIF" "ERRMSG" "EXIT" "EXPR" "FIRST"
|
||||
"FLUSH" "FOURTH" "FRENAME" "FROM" "FSET" "FUNSET" "IF"
|
||||
"IFTRIG" "IN" "INC" "INCLUDE" "INCLUDECMD" "INFO" "LAST"
|
||||
"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"
|
||||
"RUN" "SATISFY" "SCAN" "SCANFROM" "SCHED" "SECOND" "SET"
|
||||
"SKIP" "SPECIAL" "SYSINCLUDE" "TAG" "THIRD" "THROUGH" "TODO"
|
||||
"TRANSLATE" "TRANS" "UNSET" "UNTIL" "WARN")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
|
||||
@@ -135,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"
|
||||
@@ -145,8 +147,8 @@
|
||||
"$NumTrig" "$October" "$On" "$OnceFile" "$ParseUntriggered" "$Pm"
|
||||
"$PrefixLineNo" "$PSCal" "$RunOff" "$Saturday" "$September"
|
||||
"$SimpleCal" "$SortByDate" "$SortByPrio" "$SortByTime" "$SubsIndent"
|
||||
"$Sunday" "$SuppressImplicitWarnings" "$SuppressLRM" "$SysInclude" "$T" "$Td"
|
||||
"$TerminalBackground" "$Thursday" "$TimeSep" "$TimetIs64bit" "$Tm" "$Today"
|
||||
"$Sunday" "$SuppressImplicitWarnings" "$SuppressLRM" "$SysInclude" "$T" "$Tb" "$Td"
|
||||
"$TerminalBackground" "$Thursday" "$TimeSep" "$TimetIs64bit" "$Tm" "$Today" "$TodoFilter"
|
||||
"$Tomorrow" "$Tt" "$Tuesday" "$Tw" "$Ty" "$U" "$Ud" "$Um"
|
||||
"$UntimedFirst" "$Use256Colors" "$UseBGVTColors" "$UseTrueColors"
|
||||
"$UseVTColors" "$Uw" "$Uy" "$Was" "$Wednesday")
|
||||
@@ -164,21 +166,21 @@
|
||||
(defconst remind-builtin-functions
|
||||
(sort
|
||||
(list "_" "abs" "access" "adawn" "adusk" "ampm" "ansicolor" "args" "asc"
|
||||
"baseyr" "char" "choose" "coerce" "columns" "current" "date"
|
||||
"baseyr" "catch" "catcherr" "char" "choose" "coerce" "columns" "const" "current" "date"
|
||||
"datepart" "datetime" "dawn" "day" "daysinmon" "defined" "dosubst"
|
||||
"dusk" "easterdate" "escape" "evaltrig" "filedate" "filedatetime"
|
||||
"dusk" "easterdate" "escape" "eval" "evaltrig" "filedate" "filedatetime"
|
||||
"filedir" "filename" "getenv" "hebdate" "hebday" "hebmon" "hebyear"
|
||||
"hour" "htmlescape" "htmlstriptags" "iif" "index" "isany" "isdst"
|
||||
"hour" "htmlescape" "htmlstriptags" "iif" "index" "isany" "isconst" "isdst"
|
||||
"isleap" "isomitted" "language" "localtoutc" "lower" "max" "min"
|
||||
"minsfromutc" "minute" "mon" "monnum" "moondate" "moondatetime"
|
||||
"moonphase" "moonrise" "moonrisedir" "moonset" "moonsetdir" "moontime"
|
||||
"multitrig" "ndawn" "ndusk" "nonomitted" "now" "ord" "orthodoxeaster"
|
||||
"multitrig" "ndawn" "ndusk" "nonconst" "nonomitted" "now" "ord" "orthodoxeaster"
|
||||
"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" "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"
|
||||
|
||||
208
docs/WHATSNEW
208
docs/WHATSNEW
@@ -1,5 +1,205 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 6.0 Patch 1 - 2025-08-19
|
||||
|
||||
- NEW FEATURE: remind: Add readline support if input is taken from stdin
|
||||
(ie, "remind -"). This gives you full editing support if you run
|
||||
Remind interactively.
|
||||
|
||||
- BUG FIX: remind: Fix buffer overflow in DUMPVARS command.
|
||||
Thanks to Jochen Sprickerhof for helping me find this bug.
|
||||
|
||||
* 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
|
||||
of them even once they are in the past, unless you specifically mark
|
||||
them as completed.
|
||||
|
||||
- MAJOR NEW FEATURE: remind: The --json long option causes Remind to
|
||||
output JSON in Agenda Mode instead of the normal text output. See
|
||||
tkremind for an example of how a front-end can use this output.
|
||||
|
||||
- MINOR NEW FEATURE: remind: The RETURN statement can be used to skip
|
||||
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
|
||||
easily mark them completed. You can right-click on a day number
|
||||
to get a window with Agenda Mode reminders for that day.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Language packs can define an ordx(n)
|
||||
function that localizes ord(n). If this function is defined, then
|
||||
ord(n) automatically calls it rather than using its built-in English
|
||||
localization. Appropriate ordx(n) definitions have been added to
|
||||
all language packs.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: The %b substitution sequence handles
|
||||
dates in the past (because of TODOs). The %! sequence considers
|
||||
both date and time, and can be used with non-timed reminders. The
|
||||
new %? sequence is similar to %!, but outputs "are" and "were"
|
||||
instead of "is" and "was". The new %*! and %*? sequences are
|
||||
similar to %! and %?, but compare the trigger date to realtoday()
|
||||
instead of to today().
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Downgrade a SPECIAL COLOR... with
|
||||
out-of-range color values to a normal MSG-type reminder.
|
||||
|
||||
- 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.
|
||||
|
||||
- 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
|
||||
analogous PUSH-FUNCS / POP-FUNCS commands. These let you localize
|
||||
changes to variables and functions and help with writing more modular
|
||||
reminder files.
|
||||
|
||||
- INTERNAL CHANGES: Clean up the code following recommendations from
|
||||
an updated "cppcheck" executable.
|
||||
|
||||
* VERSION 5.4 Patch 2 - 2025-07-16
|
||||
|
||||
- MINOR CHANGE: remind: Allow daysinmon() to take a DATE or DATETIME
|
||||
argument.
|
||||
|
||||
- MINOR CHANGE: remind: All functions that want an integer month number
|
||||
will now also accept a string naming the month.
|
||||
|
||||
- UPDATE: include/holidays/chinese-new-year.rem: Add dates for Chinese
|
||||
New Year for 2051 through 2100.
|
||||
|
||||
- BUG FIX: remind: Set trigdate() correctly for a fully-specified
|
||||
date, even if it's in the past, as the manual documented. Bug
|
||||
found by Tim Chase.
|
||||
|
||||
- DOCUMENTATION FIX: rem2html: Document the correct Perl module
|
||||
prerequisites.
|
||||
|
||||
- CODE FIXES: remind: Various minor improvements to the code with
|
||||
no user-visible changes.
|
||||
|
||||
* VERSION 5.4 Patch 1 - 2025-06-15
|
||||
|
||||
- MAJOR BUG FIX: remind: In some circumstances, a REM command could
|
||||
yield a trigger date after its UNTIL date, rather than recognizing it
|
||||
as having expired. This has been fixed. Bug found by Ian! D. Allen.
|
||||
|
||||
- BUG FIX: rem2pdf: Support the COLOUR special (as well as COLOR).
|
||||
|
||||
- MINOR IMPROVEMENT: Add include/utils/add-html-anchors.rem. You can
|
||||
INCLUDE this file to get HTML anchors added to every calendar day
|
||||
by rem2html.
|
||||
|
||||
- DOCUMENTATION: Add NOTE-ABOUT-AI.txt
|
||||
|
||||
* VERSION 5.4 Patch 0 - 2025-06-03
|
||||
|
||||
- MAJOR IMPROVEMENT: remind: Track which expressions and variables
|
||||
Remind can prove to its satisfaction are "constant" - that is, that
|
||||
will always have the same value on any Remind run as long as the
|
||||
files are not edited. This allows "Purge Mode" to purge more
|
||||
reminders than before.
|
||||
|
||||
See the new remind(1) man page section "NON-CONSTANT EXPRESSIONS"
|
||||
|
||||
- MINOR NEW FEATURE: remind: add the "nonconst" built-in function (to
|
||||
force an expression to be interpreted as non-constant), the "const"
|
||||
function to force an expression to be interpreted as constant, and
|
||||
the "isconst" function to test if an expression is constant.
|
||||
|
||||
- MINOR NEW FEATURE: remind: Add eval() built-in function that takes a
|
||||
string argument and evaluates it as an expression. For safety, the
|
||||
"shell" function is disabled inside an eval().
|
||||
|
||||
- MINOR NEW FEATURE: remind: add the "u" debugging flag to warn you if
|
||||
you set a variable that is not subsequently used.
|
||||
|
||||
- MINOR NEW FEATURE: remind: Add the trigbase() function and
|
||||
corresponding $Tb system variable. See the remind(1) man page for
|
||||
details.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: make value("var", default) evaluate the
|
||||
second argument lazily: If "var" is defined, then the second
|
||||
argument is never evaluated.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Add syntax for redefining a function without
|
||||
issuing a warning. The syntax:
|
||||
|
||||
FSET - func(x) expr
|
||||
|
||||
is equivalent to:
|
||||
|
||||
FUNSET func
|
||||
FSET func(x) expr
|
||||
|
||||
- MINOR IMPROVEMENT: include/holidays: Update a bunch of files to use
|
||||
isany(n, a, b, c) rather than (n == a || n == b || n == c)
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Make $Tu a synonym for triguntil().
|
||||
|
||||
- MINOR IMPROVEMENT: remind: If coerce() fails, issue a more detailed
|
||||
error message.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Using Hush mode "-h" with purge mode "-j"
|
||||
suppresses the normal purge-mode diagnostics about reminders that
|
||||
might not be purged. Instead, only the "#!P: Expired" purge-mode
|
||||
lines are emitted.
|
||||
|
||||
- NEW FEATURE: remind: Add the catch() built-in function. This lets
|
||||
you catch errors in expression evaluation. For example:
|
||||
catch(2/0, "oops") returns "oops". The catcherr() function returns
|
||||
the error message from the last catch() expression that failed, in
|
||||
this case "Division by zero".
|
||||
|
||||
- IMPROVEMENT: remind: Remind can handle dates that require UTC to
|
||||
Local conversion (and vice-versa) for years greater than 2038, even
|
||||
on systems with a 32-bit time_t.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Allow the argument to monnum() to be a
|
||||
string, in which case it's parsed as a month name and the
|
||||
corresponding month number returned.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Allow the argument to wkdaynum() to be a
|
||||
string, in which case it's parsed as a weekday name and the
|
||||
corresponding weekday number returned.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Make the expression parser optimize away
|
||||
the unary "-" and "!" operators when followed by an integer constant.
|
||||
|
||||
- BUG FIX: tests: Don't use the obsolete "tail +2" syntax in test-rem.
|
||||
Fix courtesy of Dick Marinus.
|
||||
|
||||
* VERSION 5.3 Patch 7 - 2025-05-06
|
||||
|
||||
- IMPROVEMENT: examples/astro: Make moonrise/moonset appear after
|
||||
@@ -1437,10 +1637,10 @@ CHANGES TO REMIND
|
||||
- NEW FEATURE: Add "-u+username" variant to tell Remind to switch users to
|
||||
"username" without disabling RUN directives. Idea courtesy of Ian! D. Allen
|
||||
|
||||
- CHANGE: rem2html: rem2html has been moved out of the www/ directory into
|
||||
its own rem2html/ directory. If your system has the prerequisites
|
||||
(namely Perl, Getopt::Long and JSON::Any) then rem2html will be installed
|
||||
by "make install".
|
||||
- CHANGE: rem2html: rem2html has been moved out of the www/ directory
|
||||
into its own rem2html/ directory. If your system has the
|
||||
prerequisites (namely Perl, Getopt::Long and JSON::MaybeXS) then
|
||||
rem2html will be installed by "make install".
|
||||
|
||||
- CHANGE: Remove "cm2rem". It was about 20 years obsolete.
|
||||
|
||||
|
||||
@@ -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 ""
|
||||
@@ -28,7 +28,7 @@ if !defined("ansi_bold")
|
||||
set ansi_underline2 char(27) + "[21m"
|
||||
set ansi_overline char(27) + "[53m"
|
||||
endif
|
||||
preserve ansi_normal ansi_bold ansi_faint ansi_italic ansi_underline2 ansi_reverse ansi_strikeout ansi_underline2 ansi_overline
|
||||
preserve ansi_normal ansi_bold ansi_faint ansi_italic ansi_underline ansi_reverse ansi_strikeout ansi_underline2 ansi_overline
|
||||
endif
|
||||
|
||||
# Example: REM MSG I must [ansi_bold]emphasize[ansi_normal] \
|
||||
|
||||
@@ -38,10 +38,10 @@ You can use the following trick if you would like (for example) 7 days'
|
||||
advance warning of holidays:
|
||||
|
||||
# Save old definition (if any) of msgsuffix
|
||||
FRENAME msgsuffix saved_msgsuffix
|
||||
PUSH-FUNCS msgsuffix
|
||||
|
||||
# Save old value of $DefaultDelta
|
||||
SET old_delta $DefaultDelta
|
||||
PUSH-VARS $DefaultDelta
|
||||
|
||||
# We want 7 days' advance warning
|
||||
SET $DefaultDelta 7
|
||||
@@ -57,6 +57,9 @@ advance warning of holidays:
|
||||
SYSINCLUDE holidays/us.rem
|
||||
SYSINCLUDE holidays/us/ny.rem
|
||||
|
||||
# Restore old version of msgsuffix and $DefaultDelta
|
||||
FRENAME saved_msgsuffix msgsuffix
|
||||
SET $DefaultDelta old_delta
|
||||
# Restore old value $DefaultDelta
|
||||
POP-VARS
|
||||
|
||||
# Restore old version of msgsuffix
|
||||
POP-FUNCS
|
||||
|
||||
|
||||
@@ -6,28 +6,28 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Festat e Vitit të Ri
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Festat e Vitit të Ri (ditë pushimi e shtyrë)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Festat e Vitit të Ri (ditë pushimi e shtyrë)
|
||||
OMIT 2 January MSG Festat e Vitit të Ri
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 2))==0 || wkdaynum(date($Ty, 1, 2))==6] MSG Festat e Vitit të Ri (ditë pushimi e shtyrë)
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 2)), 0, 6)] MSG Festat e Vitit të Ri (ditë pushimi e shtyrë)
|
||||
OMIT 14 March MSG Dita e Verës
|
||||
REM 14 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 14))==0 || wkdaynum(date($Ty, 3, 14))==6] MSG Dita e Verës (ditë pushimi e shtyrë)
|
||||
REM 14 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 14)), 0, 6)] MSG Dita e Verës (ditë pushimi e shtyrë)
|
||||
OMIT 22 March MSG Dita e Nevruzit
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 22))==0 || wkdaynum(date($Ty, 3, 22))==6] MSG Dita e Nevruzit (ditë pushimi e shtyrë)
|
||||
REM 31 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 31))==0 || wkdaynum(date($Ty, 3, 31))==6] MSG E diela e Pashkëve Katolike (ditë pushimi e shtyrë)
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 22)), 0, 6)] MSG Dita e Nevruzit (ditë pushimi e shtyrë)
|
||||
REM 31 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 31)), 0, 6)] MSG E diela e Pashkëve Katolike (ditë pushimi e shtyrë)
|
||||
OMIT [easterdate($Uy)] MSG E diela e Pashkëve Katolike
|
||||
OMIT [easterdate($Uy)] MSG E diela e Pashkëve Ortodokse
|
||||
OMIT 1 May MSG Dita Ndërkombëtare e Punëtorëve
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Dita Ndërkombëtare e Punëtorëve (ditë pushimi e shtyrë)
|
||||
REM 5 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 5))==0 || wkdaynum(date($Ty, 5, 5))==6] MSG E diela e Pashkëve Ortodokse (ditë pushimi e shtyrë)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Dita Ndërkombëtare e Punëtorëve (ditë pushimi e shtyrë)
|
||||
REM 5 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 5)), 0, 6)] MSG E diela e Pashkëve Ortodokse (ditë pushimi e shtyrë)
|
||||
OMIT 5 September MSG Dita e Shenjtërimit të Shenjt Terezës
|
||||
REM 5 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 9, 5))==0 || wkdaynum(date($Ty, 9, 5))==6] MSG Dita e Shenjtërimit të Shenjt Terezës (ditë pushimi e shtyrë)
|
||||
REM 5 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 9, 5)), 0, 6)] MSG Dita e Shenjtërimit të Shenjt Terezës (ditë pushimi e shtyrë)
|
||||
OMIT 22 November MSG Dita e Alfabetit
|
||||
REM 22 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 22))==0 || wkdaynum(date($Ty, 11, 22))==6] MSG Dita e Alfabetit (ditë pushimi e shtyrë)
|
||||
REM 22 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 11, 22)), 0, 6)] MSG Dita e Alfabetit (ditë pushimi e shtyrë)
|
||||
OMIT 28 November MSG Dita Flamurit dhe e Pavarësisë
|
||||
REM 28 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 28))==0 || wkdaynum(date($Ty, 11, 28))==6] MSG Dita Flamurit dhe e Pavarësisë (ditë pushimi e shtyrë)
|
||||
REM 28 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 11, 28)), 0, 6)] MSG Dita Flamurit dhe e Pavarësisë (ditë pushimi e shtyrë)
|
||||
OMIT 29 November MSG Dita e Çlirimit
|
||||
REM 29 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 29))==0 || wkdaynum(date($Ty, 11, 29))==6] MSG Dita e Çlirimit (ditë pushimi e shtyrë)
|
||||
REM 29 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 11, 29)), 0, 6)] MSG Dita e Çlirimit (ditë pushimi e shtyrë)
|
||||
OMIT 8 December MSG Dita Kombëtare e Rinisë
|
||||
REM 8 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 8))==0 || wkdaynum(date($Ty, 12, 8))==6] MSG Dita Kombëtare e Rinisë (ditë pushimi e shtyrë)
|
||||
REM 8 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 8)), 0, 6)] MSG Dita Kombëtare e Rinisë (ditë pushimi e shtyrë)
|
||||
OMIT 25 December MSG Krishtlindjet
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Krishtlindjet (ditë pushimi e shtyrë)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Krishtlindjet (ditë pushimi e shtyrë)
|
||||
|
||||
@@ -6,36 +6,36 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Yeni il bayramı
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Yeni il bayramı (müşahidə olunur)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Yeni il bayramı (müşahidə olunur)
|
||||
OMIT 2 January MSG Yeni il bayramı
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 2))==0 || wkdaynum(date($Ty, 1, 2))==6] MSG Yeni il bayramı (müşahidə olunur)
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 2)), 0, 6)] MSG Yeni il bayramı (müşahidə olunur)
|
||||
OMIT 20 January MSG Ümumxalq hüzn günü
|
||||
OMIT 8 March MSG Qadınlar günü
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 8))==0 || wkdaynum(date($Ty, 3, 8))==6] MSG Qadınlar günü (müşahidə olunur)
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 8)), 0, 6)] MSG Qadınlar günü (müşahidə olunur)
|
||||
OMIT 20 March MSG Novruz bayramı
|
||||
REM 20 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 20))==0 || wkdaynum(date($Ty, 3, 20))==6] MSG Novruz bayramı (müşahidə olunur)
|
||||
REM 20 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 20)), 0, 6)] MSG Novruz bayramı (müşahidə olunur)
|
||||
OMIT 21 March MSG Novruz bayramı
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 21))==0 || wkdaynum(date($Ty, 3, 21))==6] MSG Novruz bayramı (müşahidə olunur)
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 21)), 0, 6)] MSG Novruz bayramı (müşahidə olunur)
|
||||
OMIT 22 March MSG Novruz bayramı
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 22))==0 || wkdaynum(date($Ty, 3, 22))==6] MSG Novruz bayramı (müşahidə olunur)
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 22)), 0, 6)] MSG Novruz bayramı (müşahidə olunur)
|
||||
OMIT 23 March MSG Novruz bayramı
|
||||
REM 23 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 23))==0 || wkdaynum(date($Ty, 3, 23))==6] MSG Novruz bayramı (müşahidə olunur)
|
||||
REM 23 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 23)), 0, 6)] MSG Novruz bayramı (müşahidə olunur)
|
||||
OMIT 24 March MSG Novruz bayramı
|
||||
REM 24 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 24))==0 || wkdaynum(date($Ty, 3, 24))==6] MSG Novruz bayramı (müşahidə olunur)
|
||||
REM 24 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 24)), 0, 6)] MSG Novruz bayramı (müşahidə olunur)
|
||||
OMIT 9 May MSG Faşizm üzərində qələbə günü
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 9))==0 || wkdaynum(date($Ty, 5, 9))==6] MSG Faşizm üzərində qələbə günü (müşahidə olunur)
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 9)), 0, 6)] MSG Faşizm üzərində qələbə günü (müşahidə olunur)
|
||||
OMIT 28 May MSG Müstəqillik Günü
|
||||
REM 28 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 28))==0 || wkdaynum(date($Ty, 5, 28))==6] MSG Müstəqillik Günü (müşahidə olunur)
|
||||
REM 28 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 28)), 0, 6)] MSG Müstəqillik Günü (müşahidə olunur)
|
||||
OMIT 15 June MSG Azərbaycan xalqının milli qurtuluş günü
|
||||
REM 15 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 15))==0 || wkdaynum(date($Ty, 6, 15))==6] MSG Azərbaycan xalqının milli qurtuluş günü (müşahidə olunur)
|
||||
REM 15 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 15)), 0, 6)] MSG Azərbaycan xalqının milli qurtuluş günü (müşahidə olunur)
|
||||
OMIT 26 June MSG Azərbaycan Respublikasının Silahlı Qüvvələri günü
|
||||
REM 26 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 26))==0 || wkdaynum(date($Ty, 6, 26))==6] MSG Azərbaycan Respublikasının Silahlı Qüvvələri günü (müşahidə olunur)
|
||||
REM 26 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 26)), 0, 6)] MSG Azərbaycan Respublikasının Silahlı Qüvvələri günü (müşahidə olunur)
|
||||
OMIT 8 November MSG Zəfər Günü
|
||||
REM 8 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 8))==0 || wkdaynum(date($Ty, 11, 8))==6] MSG Zəfər Günü (müşahidə olunur)
|
||||
REM 8 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 11, 8)), 0, 6)] MSG Zəfər Günü (müşahidə olunur)
|
||||
OMIT 9 November MSG Azərbaycan Respublikasının Dövlət bayrağı günü
|
||||
REM 9 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 9))==0 || wkdaynum(date($Ty, 11, 9))==6] MSG Azərbaycan Respublikasının Dövlət bayrağı günü (müşahidə olunur)
|
||||
REM 9 November OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 11, 9)), 0, 6)] MSG Azərbaycan Respublikasının Dövlət bayrağı günü (müşahidə olunur)
|
||||
OMIT 31 December MSG Dünya azərbaycanlılarının həmrəyliyi günü
|
||||
REM 31 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 31))==0 || wkdaynum(date($Ty, 12, 31))==6] MSG Dünya azərbaycanlılarının həmrəyliyi günü (müşahidə olunur)
|
||||
REM 31 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 31)), 0, 6)] MSG Dünya azərbaycanlılarının həmrəyliyi günü (müşahidə olunur)
|
||||
|
||||
# Optional holidays
|
||||
REM 27 September MSG Anım Günü
|
||||
|
||||
@@ -6,29 +6,29 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Нова година
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Нова година (почивен ден)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Нова година (почивен ден)
|
||||
OMIT 3 March MSG Ден на Освобождението на България от османско иго
|
||||
REM 3 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 3))==0 || wkdaynum(date($Ty, 3, 3))==6] MSG Ден на Освобождението на България от османско иго (почивен ден)
|
||||
REM 3 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 3)), 0, 6)] MSG Ден на Освобождението на България от османско иго (почивен ден)
|
||||
OMIT [orthodoxeaster($Uy)-2] MSG Велики петък
|
||||
OMIT [orthodoxeaster($Uy)-1] MSG Велика събота
|
||||
OMIT [orthodoxeaster($Uy)] MSG Великден
|
||||
OMIT [orthodoxeaster($Uy)+1] MSG Великден
|
||||
OMIT 1 May MSG Ден на труда и на международната работническа солидарност
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Ден на труда и на международната работническа солидарност (почивен ден)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Ден на труда и на международната работническа солидарност (почивен ден)
|
||||
OMIT 6 May MSG Гергьовден, Ден на храбростта и Българската армия
|
||||
REM 6 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 6))==0 || wkdaynum(date($Ty, 5, 6))==6] MSG Гергьовден, Ден на храбростта и Българската армия (почивен ден)
|
||||
REM 6 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 6)), 0, 6)] MSG Гергьовден, Ден на храбростта и Българската армия (почивен ден)
|
||||
OMIT 24 May MSG Ден на светите братя Кирил и Методий, на българската азбука, просвета и култура и на славянската книжовност
|
||||
REM 24 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 24))==0 || wkdaynum(date($Ty, 5, 24))==6] MSG Ден на светите братя Кирил и Методий, на българската азбука, просвета и култура и на славянската книжовност (почивен ден)
|
||||
REM 24 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 24)), 0, 6)] MSG Ден на светите братя Кирил и Методий, на българската азбука, просвета и култура и на славянската книжовност (почивен ден)
|
||||
OMIT 6 September MSG Ден на Съединението
|
||||
REM 6 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 9, 6))==0 || wkdaynum(date($Ty, 9, 6))==6] MSG Ден на Съединението (почивен ден)
|
||||
REM 6 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 9, 6)), 0, 6)] MSG Ден на Съединението (почивен ден)
|
||||
OMIT 22 September MSG Ден на Независимостта на България
|
||||
REM 22 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 9, 22))==0 || wkdaynum(date($Ty, 9, 22))==6] MSG Ден на Независимостта на България (почивен ден)
|
||||
REM 22 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 9, 22)), 0, 6)] MSG Ден на Независимостта на България (почивен ден)
|
||||
OMIT 24 December MSG Бъдни вечер
|
||||
REM 24 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 24))==0 || wkdaynum(date($Ty, 12, 24))==6] MSG Бъдни вечер (почивен ден)
|
||||
REM 24 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 24)), 0, 6)] MSG Бъдни вечер (почивен ден)
|
||||
OMIT 25 December MSG Рождество Христово
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Рождество Христово (почивен ден)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Рождество Христово (почивен ден)
|
||||
OMIT 26 December MSG Рождество Христово
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 26))==0 || wkdaynum(date($Ty, 12, 26))==6] MSG Рождество Христово (почивен ден)
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 26)), 0, 6)] MSG Рождество Христово (почивен ден)
|
||||
|
||||
# Optional holidays
|
||||
REM 1 November MSG Ден на народните будители
|
||||
|
||||
@@ -28,3 +28,53 @@ REM 26 Jan 2047 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %
|
||||
REM 14 Feb 2048 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 2 Feb 2049 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 23 Jan 2050 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 11 Feb 2051 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 1 Feb 2052 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 19 Feb 2053 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 8 Feb 2054 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||
REM 28 Jan 2055 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||
REM 15 Feb 2056 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||
REM 4 Feb 2057 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||
REM 24 Jan 2058 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 12 Feb 2059 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 2 Feb 2060 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 21 Jan 2061 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 9 Feb 2062 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 29 Jan 2063 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 17 Feb 2064 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 5 Feb 2065 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 26 Jan 2066 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||
REM 14 Feb 2067 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||
REM 3 Feb 2068 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||
REM 23 Jan 2069 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||
REM 11 Feb 2070 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 31 Jan 2071 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 19 Feb 2072 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 7 Feb 2073 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 27 Jan 2074 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 15 Feb 2075 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 5 Feb 2076 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 24 Jan 2077 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 12 Feb 2078 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||
REM 2 Feb 2079 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||
REM 22 Jan 2080 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||
REM 9 Feb 2081 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||
REM 29 Jan 2082 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 17 Feb 2083 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 6 Feb 2084 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 26 Jan 2085 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 14 Feb 2086 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 3 Feb 2087 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 24 Jan 2088 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 10 Feb 2089 INFO "Url: https://en.wikipedia.org/wiki/Rooster_(zodiac)" MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 30 Jan 2090 INFO "Url: https://en.wikipedia.org/wiki/Dog_(zodiac)" MSG %(Chinese New Year) (%(Dog))
|
||||
REM 18 Feb 2091 INFO "Url: https://en.wikipedia.org/wiki/Pig_(zodiac)" MSG %(Chinese New Year) (%(Pig))
|
||||
REM 7 Feb 2092 INFO "Url: https://en.wikipedia.org/wiki/Rat_(zodiac)" MSG %(Chinese New Year) (%(Rat))
|
||||
REM 27 Jan 2093 INFO "Url: https://en.wikipedia.org/wiki/Ox_(zodiac)" MSG %(Chinese New Year) (%(Ox))
|
||||
REM 15 Feb 2094 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 5 Feb 2095 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 25 Jan 2096 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 12 Feb 2097 INFO "Url: https://en.wikipedia.org/wiki/Snake_(zodiac)" MSG %(Chinese New Year) (%(Snake))
|
||||
REM 1 Feb 2098 INFO "Url: https://en.wikipedia.org/wiki/Horse_(zodiac)" MSG %(Chinese New Year) (%(Horse))
|
||||
REM 21 Jan 2099 INFO "Url: https://en.wikipedia.org/wiki/Goat_(zodiac)" MSG %(Chinese New Year) (%(Goat))
|
||||
REM 9 Feb 2100 INFO "Url: https://en.wikipedia.org/wiki/Monkey_(zodiac)" MSG %(Chinese New Year) (%(Monkey))
|
||||
|
||||
@@ -26,7 +26,7 @@ REM 29 June ADDOMIT SCANFROM -28 SATISFY [$Tw != 2 && $Tw != 3 && $Tw != 4 && $T
|
||||
REM 2 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 29)) == 5] MSG San Pedro y San Pablo
|
||||
OMIT 16 July MSG Virgen del Carmen
|
||||
OMIT 15 August MSG Asunción de la Virgen
|
||||
REM 17 September ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 5] MSG Fiestas Patrias
|
||||
REM 17 September ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 1, 5)] MSG Fiestas Patrias
|
||||
OMIT 18 September MSG Día de la Independencia
|
||||
OMIT 19 September MSG Día de las Glorias del Ejército
|
||||
REM 20 September ADDOMIT SCANFROM -28 SATISFY [$Tw == 5] MSG Fiestas Patrias
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG New Year's Day
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG New Year's Day (observed)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG New Year's Day (observed)
|
||||
OMIT 11 February MSG Youth Day
|
||||
REM 11 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 11))==0 || wkdaynum(date($Ty, 2, 11))==6] MSG Youth Day (observed)
|
||||
REM 11 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 11)), 0, 6)] MSG Youth Day (observed)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT 1 May MSG Labour Day
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Labour Day (observed)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Labour Day (observed)
|
||||
OMIT 20 May MSG National Day
|
||||
REM 20 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 20))==0 || wkdaynum(date($Ty, 5, 20))==6] MSG National Day (observed)
|
||||
REM 20 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 20)), 0, 6)] MSG National Day (observed)
|
||||
OMIT [easterdate($Uy)+39] MSG Ascension Day
|
||||
OMIT 15 August MSG Assumption Day
|
||||
REM 15 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 8, 15))==0 || wkdaynum(date($Ty, 8, 15))==6] MSG Assumption Day (observed)
|
||||
REM 15 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 8, 15)), 0, 6)] MSG Assumption Day (observed)
|
||||
OMIT 25 December MSG Christmas Day
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Christmas Day (observed)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Christmas Day (observed)
|
||||
|
||||
@@ -17,7 +17,7 @@ REM [orthodoxeaster($Uy)+1] MSG ΔΕΥΤΕΡΑ ΤΟΥ ΠΑΣΧΑ
|
||||
# minister decides moving that holiday. Here is a likely assumption of how this day might be moved.
|
||||
# Uncomment following lines to enable.
|
||||
|
||||
set PM date($Uy,5,1)
|
||||
# set PM date($Uy,5,1)
|
||||
# IF PM>=orthodoxeaster($Uy)-7 && PM<=orthodoxeaster($Uy)+1
|
||||
# IF PM<orthodoxeaster($Uy)-3
|
||||
# REM orthodoxeaster($Uy) -8 MSG πιθανόν ΕΡΓΑΤΙΚΗ Πρωτομαγιά
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG The first day of January
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG The first day of January (observed)
|
||||
REM 4 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4))==0 || wkdaynum(date($Ty, 4, 4))==6] MSG Ching Ming Festival (observed)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG The first day of January (observed)
|
||||
REM 4 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 4)), 0, 6)] MSG Ching Ming Festival (observed)
|
||||
OMIT 1 May MSG Labour Day
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Labour Day (observed)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Labour Day (observed)
|
||||
OMIT 1 July MSG Hong Kong Special Administrative Region Establishment Day
|
||||
REM 1 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 1))==0 || wkdaynum(date($Ty, 7, 1))==6] MSG Hong Kong Special Administrative Region Establishment Day (observed)
|
||||
REM 1 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 7, 1)), 0, 6)] MSG Hong Kong Special Administrative Region Establishment Day (observed)
|
||||
OMIT 1 October MSG National Day
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 1))==0 || wkdaynum(date($Ty, 10, 1))==6] MSG National Day (observed)
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 1)), 0, 6)] MSG National Day (observed)
|
||||
OMIT 25 December MSG Christmas Day
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Christmas Day (observed)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Christmas Day (observed)
|
||||
OMIT 26 December MSG The first weekday after Christmas Day
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 26))==0 || wkdaynum(date($Ty, 12, 26))==6] MSG The first weekday after Christmas Day (observed)
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 26)), 0, 6)] MSG The first weekday after Christmas Day (observed)
|
||||
|
||||
# Optional holidays
|
||||
REM [easterdate($Uy)-2] MSG Good Friday
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG New Year's Day
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG New Year's Day (substitute day)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG New Year's Day (substitute day)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT [easterdate($Uy)+1] MSG Easter Monday
|
||||
REM First Monday in May ADDOMIT SCANFROM -28 MSG May Bank Holiday
|
||||
@@ -14,6 +14,6 @@ REM 9 May ADDOMIT SCANFROM -28 SATISFY [$Tw != 0] MSG Liberation Day
|
||||
REM Last Monday in May ADDOMIT SCANFROM -28 MSG Spring Bank Holiday
|
||||
REM Last Monday in August ADDOMIT SCANFROM -28 MSG Summer Bank Holiday
|
||||
OMIT 25 December MSG Christmas Day
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Christmas Day (substitute day)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Christmas Day (substitute day)
|
||||
OMIT 26 December MSG Boxing Day
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 26))==0 || wkdaynum(date($Ty, 12, 26))==6] MSG Boxing Day (substitute day)
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 26)), 0, 6)] MSG Boxing Day (substitute day)
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
# Major Jewish Holidays
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
# Save variables and functions that we will mess with
|
||||
PUSH-VARS InIsrael IncludeIsraeliHolidays Reform
|
||||
PUSH-FUNCS _chan _h2 _PastSat _BackTwoFri _BackTwoSat
|
||||
|
||||
# Set the variable InIsrael to 1 if you live in Israel. Otherwise,
|
||||
# you get the Diaspora versions of Jewish holidays
|
||||
SET InIsrael value("InIsrael", 0)
|
||||
|
||||
# Set this if you want to include holidays that are not really
|
||||
# Jewish religious holidays, but simply Israeli holidays
|
||||
SET IncludeIsraeliHolidays value("IncludeIsraeliHolidays", 0)
|
||||
|
||||
# Set the variable Reform to 1 if you want the Reform version of the
|
||||
# Jewish calendar. Otherwise, you get the traditional version
|
||||
SET Reform value("Reform", 0)
|
||||
@@ -14,9 +22,6 @@ FSET _h2(x, y) HEBDATE(x, y, $U-7)
|
||||
FSET _PastSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)+1)
|
||||
FSET _BackTwoFri(x, y) IIF(WKDAYNUM(_h2(x,y))!=5, _h2(x,y), _h2(x,y)-2)
|
||||
FSET _BackTwoSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)-2)
|
||||
# Default values in case InIsrael and Reform are not set
|
||||
SET InIsrael VALUE("InIsrael", 0)
|
||||
SET Reform VALUE("Reform", 0)
|
||||
|
||||
REM [hebdate(1, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Rosh_Hashanah" MSG Rosh Hashana 1
|
||||
|
||||
@@ -83,15 +88,18 @@ IF !InIsrael && !Reform
|
||||
ENDIF
|
||||
|
||||
REM [hebdate(27, "Nisan")] INFO "Url: https://en.wikipedia.org/wiki/Yom_HaShoah" MSG Yom HaShoah
|
||||
REM [_BackTwoFri(4, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Yom_HaZikaron" MSG Yom HaZikaron
|
||||
REM [_BackTwoSat(5, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Independence_Day_(Israel)" MSG Yom Ha'atzmaut
|
||||
|
||||
IF IncludeIsraeliHolidays
|
||||
REM [_BackTwoFri(4, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Yom_HaZikaron" MSG Yom HaZikaron
|
||||
REM [_BackTwoSat(5, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Independence_Day_(Israel)" MSG Yom Ha'atzmaut
|
||||
REM [hebdate(28, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Jerusalem_Day" MSG Yom Yerushalayim
|
||||
ENDIF
|
||||
|
||||
# Not sure about Reform's position on Lag B'Omer
|
||||
IF !Reform
|
||||
REM [hebdate(18, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Lag_BaOmer" MSG Lag B'Omer
|
||||
ENDIF
|
||||
|
||||
REM [hebdate(28, "Iyar")] INFO "Url: https://en.wikipedia.org/wiki/Jerusalem_Day" MSG Yom Yerushalayim
|
||||
REM [hebdate(6, "Sivan")] INFO "Url: https://en.wikipedia.org/wiki/Shavuot" MSG Shavuot
|
||||
|
||||
IF !InIsrael && !Reform
|
||||
@@ -105,3 +113,7 @@ IF !Reform
|
||||
REM [_PastSat(17, "Tamuz")] INFO "Url: https://en.wikipedia.org/wiki/Seventeenth_of_Tammuz" MSG Tzom Tammuz
|
||||
REM [_PastSat(9, "Av")] INFO "Url: https://en.wikipedia.org/wiki/Tisha_B%27Av" MSG Tish'a B'Av
|
||||
ENDIF
|
||||
|
||||
# Tidy up
|
||||
POP-FUNCS
|
||||
POP-VARS
|
||||
|
||||
@@ -6,29 +6,29 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Жаңа жыл
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Жаңа жыл (қайта белгіленген демалыс)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Жаңа жыл (қайта белгіленген демалыс)
|
||||
OMIT 2 January MSG Жаңа жыл
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 2))==0 || wkdaynum(date($Ty, 1, 2))==6] MSG Жаңа жыл (қайта белгіленген демалыс)
|
||||
REM 2 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 2)), 0, 6)] MSG Жаңа жыл (қайта белгіленген демалыс)
|
||||
OMIT 7 January MSG Православиелік Рождество
|
||||
OMIT 8 March MSG Халықаралық әйелдер күні
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 8))==0 || wkdaynum(date($Ty, 3, 8))==6] MSG Халықаралық әйелдер күні (қайта белгіленген демалыс)
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 8)), 0, 6)] MSG Халықаралық әйелдер күні (қайта белгіленген демалыс)
|
||||
OMIT 21 March MSG Наурыз мейрамы
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 21))==0 || wkdaynum(date($Ty, 3, 21))==6] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 21)), 0, 6)] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
OMIT 22 March MSG Наурыз мейрамы
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 22))==0 || wkdaynum(date($Ty, 3, 22))==6] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
REM 22 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 22)), 0, 6)] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
OMIT 23 March MSG Наурыз мейрамы
|
||||
REM 23 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 23))==0 || wkdaynum(date($Ty, 3, 23))==6] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
REM 23 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 23)), 0, 6)] MSG Наурыз мейрамы (қайта белгіленген демалыс)
|
||||
OMIT 1 May MSG Қазақстан халқының бірлігі мерекесі
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Қазақстан халқының бірлігі мерекесі (қайта белгіленген демалыс)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Қазақстан халқының бірлігі мерекесі (қайта белгіленген демалыс)
|
||||
OMIT 7 May MSG Отан Қорғаушы күні
|
||||
REM 7 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 7))==0 || wkdaynum(date($Ty, 5, 7))==6] MSG Отан Қорғаушы күні (қайта белгіленген демалыс)
|
||||
REM 7 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 7)), 0, 6)] MSG Отан Қорғаушы күні (қайта белгіленген демалыс)
|
||||
OMIT 9 May MSG Жеңіс күні
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 9))==0 || wkdaynum(date($Ty, 5, 9))==6] MSG Жеңіс күні (қайта белгіленген демалыс)
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 9)), 0, 6)] MSG Жеңіс күні (қайта белгіленген демалыс)
|
||||
OMIT 6 July MSG Астана күні
|
||||
REM 6 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 6))==0 || wkdaynum(date($Ty, 7, 6))==6] MSG Астана күні (қайта белгіленген демалыс)
|
||||
REM 6 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 7, 6)), 0, 6)] MSG Астана күні (қайта белгіленген демалыс)
|
||||
OMIT 30 August MSG Қазақстан Республикасының Конституциясы күні
|
||||
REM 30 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 8, 30))==0 || wkdaynum(date($Ty, 8, 30))==6] MSG Қазақстан Республикасының Конституциясы күні (қайта белгіленген демалыс)
|
||||
REM 30 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 8, 30)), 0, 6)] MSG Қазақстан Республикасының Конституциясы күні (қайта белгіленген демалыс)
|
||||
OMIT 25 October MSG Республика күні
|
||||
REM 25 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 25))==0 || wkdaynum(date($Ty, 10, 25))==6] MSG Республика күні (қайта белгіленген демалыс)
|
||||
REM 25 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 25)), 0, 6)] MSG Республика күні (қайта белгіленген демалыс)
|
||||
OMIT 16 December MSG Тəуелсіздік күні
|
||||
REM 16 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 16))==0 || wkdaynum(date($Ty, 12, 16))==6] MSG Тəуелсіздік күні (қайта белгіленген демалыс)
|
||||
REM 16 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 16)), 0, 6)] MSG Тəуелсіздік күні (қайта белгіленген демалыс)
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG ວັນປີໃໝ່ສາກົນ
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG ພັກຊົດເຊີຍວັນປີໃໝ່ສາກົນ
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG ພັກຊົດເຊີຍວັນປີໃໝ່ສາກົນ
|
||||
OMIT 8 March MSG ວັນແມ່ຍິງສາກົນ
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 8))==0 || wkdaynum(date($Ty, 3, 8))==6] MSG ພັກຊົດເຊີຍວັນແມ່ຍິງສາກົນ
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 8)), 0, 6)] MSG ພັກຊົດເຊີຍວັນແມ່ຍິງສາກົນ
|
||||
OMIT 13 April MSG ບຸນປີໃໝ່ລາວ
|
||||
REM 13 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 13))==0 || wkdaynum(date($Ty, 4, 13))==6] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
REM 13 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 13)), 0, 6)] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
OMIT 14 April MSG ບຸນປີໃໝ່ລາວ
|
||||
REM 14 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 14))==0 || wkdaynum(date($Ty, 4, 14))==6] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
REM 14 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 14)), 0, 6)] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
OMIT 15 April MSG ບຸນປີໃໝ່ລາວ
|
||||
REM 15 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 15))==0 || wkdaynum(date($Ty, 4, 15))==6] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
REM 15 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 15)), 0, 6)] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
OMIT 16 April MSG ບຸນປີໃໝ່ລາວ
|
||||
REM 16 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 16))==0 || wkdaynum(date($Ty, 4, 16))==6] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
REM 16 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 16)), 0, 6)] MSG ພັກຊົດເຊີຍບຸນປີໃໝ່ລາວ
|
||||
OMIT 1 May MSG ວັນກຳມະກອນສາກົນ
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG ພັກຊົດເຊີຍວັນກຳມະກອນສາກົນ
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG ພັກຊົດເຊີຍວັນກຳມະກອນສາກົນ
|
||||
OMIT 2 December MSG ວັນຊາດ
|
||||
REM 2 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 2))==0 || wkdaynum(date($Ty, 12, 2))==6] MSG ພັກຊົດເຊີຍວັນຊາດ
|
||||
REM 2 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 2)), 0, 6)] MSG ພັກຊົດເຊີຍວັນຊາດ
|
||||
|
||||
# Optional holidays
|
||||
REM 20 January MSG ວັນສ້າງຕັ້ງກອງທັບປະຊາຊົນລາວ
|
||||
@@ -37,7 +37,7 @@ REM 15 August MSG ວັນລັດຖະທໍາມະນູນແຫ່ງ
|
||||
REM 23 August MSG ວັນຍຶດອຳນາດທົ່ວປະເທດ
|
||||
REM 7 October MSG ວັນຄູແຫ່ງຊາດ
|
||||
REM 7 October MSG ວັນສ້າງຕັ້ງທະນາຄານແຫ່ງ ສປປ ລາວ
|
||||
REM 7 October OMIT SAT SUN AFTER SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 7))==0 || wkdaynum(date($Ty, 10, 7))==6] MSG ພັກຊົດເຊີຍວັນສ້າງຕັ້ງທະນາຄານແຫ່ງ ສປປ ລາວ
|
||||
REM 7 October OMIT SAT SUN AFTER SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 7)), 0, 6)] MSG ພັກຊົດເຊີຍວັນສ້າງຕັ້ງທະນາຄານແຫ່ງ ສປປ ລາວ
|
||||
REM 12 October MSG ວັນປະກາດເອກະລາດ
|
||||
REM 13 December MSG ວັນຄ້າຍວັນເກີດ ທ່ານ ປະທານ ໄກສອນ ພົມວິຫານ
|
||||
REM 27 December SCANFROM -28 SATISFY [$Tw >= 3 && $Tw <= 5] MSG ສາມວັນລັດຖະການສຸດທ້າຍຂອງທຸກໆປີ
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
# [$SysInclude]/holidays/my/
|
||||
|
||||
OMIT 1 May MSG Hari Pekerja
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Cuti Hari Pekerja
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Cuti Hari Pekerja
|
||||
REM First Monday in June ADDOMIT SCANFROM -28 MSG Hari Keputeraan Rasmi Seri Paduka Baginda Yang di-Pertuan Agong
|
||||
REM 3 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 3))==0 || wkdaynum(date($Ty, 6, 3))==6] MSG Cuti Hari Keputeraan Rasmi Seri Paduka Baginda Yang di-Pertuan Agong
|
||||
REM 3 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 3)), 0, 6)] MSG Cuti Hari Keputeraan Rasmi Seri Paduka Baginda Yang di-Pertuan Agong
|
||||
OMIT 31 August MSG Hari Kebangsaan
|
||||
REM 31 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 8, 31))==0 || wkdaynum(date($Ty, 8, 31))==6] MSG Cuti Hari Kebangsaan
|
||||
REM 31 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 8, 31)), 0, 6)] MSG Cuti Hari Kebangsaan
|
||||
OMIT 16 September MSG Hari Malaysia
|
||||
OMIT 25 December MSG Hari Krismas
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Cuti Hari Krismas
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Cuti Hari Krismas
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 20 February MSG Hari Pengisytiharan Tarikh Kemerdekaan
|
||||
REM 20 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 20))==0 || wkdaynum(date($Ty, 2, 20))==6] MSG Cuti Hari Pengisytiharan Tarikh Kemerdekaan
|
||||
REM 20 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 20)), 0, 6)] MSG Cuti Hari Pengisytiharan Tarikh Kemerdekaan
|
||||
OMIT 24 August MSG Hari Jadi Yang di-Pertua Negeri Melaka
|
||||
REM 24 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 8, 24))==0 || wkdaynum(date($Ty, 8, 24))==6] MSG Cuti Hari Jadi Yang di-Pertua Negeri Melaka
|
||||
REM 24 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 8, 24)), 0, 6)] MSG Cuti Hari Jadi Yang di-Pertua Negeri Melaka
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 14 January MSG Hari Keputeraan Yang di-Pertuan Besar Negeri Sembilan
|
||||
REM 14 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 14))==0 || wkdaynum(date($Ty, 1, 14))==6] MSG Cuti Hari Keputeraan Yang di-Pertuan Besar Negeri Sembilan
|
||||
REM 14 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 14)), 0, 6)] MSG Cuti Hari Keputeraan Yang di-Pertuan Besar Negeri Sembilan
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 22 May MSG Hari Hol Sultan Pahang
|
||||
OMIT 30 July MSG Hari Keputeraan Sultan Pahang
|
||||
REM 30 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 30))==0 || wkdaynum(date($Ty, 7, 30))==6] MSG Cuti Hari Keputeraan Sultan Pahang
|
||||
REM 30 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 7, 30)), 0, 6)] MSG Cuti Hari Keputeraan Sultan Pahang
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 7 July MSG Hari Ulang Tahun Perisytiharan Tapak Warisan Dunia
|
||||
REM Second Saturday in July ADDOMIT SCANFROM -28 MSG Hari Jadi Yang di-Pertua Negeri Pulau Pinang
|
||||
REM 13 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 13))==0 || wkdaynum(date($Ty, 7, 13))==6] MSG Cuti Hari Jadi Yang di-Pertua Negeri Pulau Pinang
|
||||
REM 13 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 7, 13)), 0, 6)] MSG Cuti Hari Jadi Yang di-Pertua Negeri Pulau Pinang
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
REM First Friday in November ADDOMIT SCANFROM -28 MSG Hari Keputeraan Sultan Perak
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 17 May MSG Hari Ulang Tahun Keputeraan Raja Perlis
|
||||
REM 17 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 17))==0 || wkdaynum(date($Ty, 5, 17))==6] MSG Cuti Hari Ulang Tahun Keputeraan Raja Perlis
|
||||
REM 17 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 17)), 0, 6)] MSG Cuti Hari Ulang Tahun Keputeraan Raja Perlis
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 11 December MSG Hari Keputeraan Sultan Selangor
|
||||
REM 11 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 11))==0 || wkdaynum(date($Ty, 12, 11))==6] MSG Cuti Hari Keputeraan Sultan Selangor
|
||||
REM 11 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 11)), 0, 6)] MSG Cuti Hari Keputeraan Sultan Selangor
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 4 March MSG Hari Ulang Tahun Pertabalan Sultan Terengganu
|
||||
REM 4 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 4))==0 || wkdaynum(date($Ty, 3, 4))==6] MSG Cuti Hari Ulang Tahun Pertabalan Sultan Terengganu
|
||||
REM 4 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 4)), 0, 6)] MSG Cuti Hari Ulang Tahun Pertabalan Sultan Terengganu
|
||||
OMIT 26 April MSG Hari Keputeraan Sultan Terengganu
|
||||
REM 26 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 26))==0 || wkdaynum(date($Ty, 4, 26))==6] MSG Cuti Hari Keputeraan Sultan Terengganu
|
||||
REM 26 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 26)), 0, 6)] MSG Cuti Hari Keputeraan Sultan Terengganu
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT 30 May MSG Pesta Kaamatan
|
||||
OMIT 31 May MSG Pesta Kaamatan
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT 1 June MSG Perayaan Hari Gawai Dayak
|
||||
REM 1 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 1))==0 || wkdaynum(date($Ty, 6, 1))==6] MSG Cuti Perayaan Hari Gawai Dayak
|
||||
REM 1 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 1)), 0, 6)] MSG Cuti Perayaan Hari Gawai Dayak
|
||||
OMIT 2 June MSG Perayaan Hari Gawai Dayak
|
||||
REM 2 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 2))==0 || wkdaynum(date($Ty, 6, 2))==6] MSG Cuti Perayaan Hari Gawai Dayak
|
||||
REM 2 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 2)), 0, 6)] MSG Cuti Perayaan Hari Gawai Dayak
|
||||
OMIT 22 July MSG Hari Kemerdekaan Sarawak
|
||||
REM 22 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 22))==0 || wkdaynum(date($Ty, 7, 22))==6] MSG Cuti Hari Kemerdekaan Sarawak
|
||||
REM 22 July OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 7, 22)), 0, 6)] MSG Cuti Hari Kemerdekaan Sarawak
|
||||
REM Second Saturday in October ADDOMIT SCANFROM -28 MSG Hari Jadi Yang di-Pertua Negeri Sarawak
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 1 February MSG Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 1))==0 || wkdaynum(date($Ty, 2, 1))==6] MSG Cuti Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 1)), 0, 6)] MSG Cuti Hari Wilayah Persekutuan
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 1 February MSG Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 1))==0 || wkdaynum(date($Ty, 2, 1))==6] MSG Cuti Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 1)), 0, 6)] MSG Cuti Hari Wilayah Persekutuan
|
||||
OMIT 30 May MSG Pesta Kaamatan
|
||||
OMIT 31 May MSG Pesta Kaamatan
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
# also SYSINCLUDE holidays/my.rem
|
||||
|
||||
OMIT 1 January MSG Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Cuti Tahun Baharu
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Cuti Tahun Baharu
|
||||
OMIT 1 February MSG Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 1))==0 || wkdaynum(date($Ty, 2, 1))==6] MSG Cuti Hari Wilayah Persekutuan
|
||||
REM 1 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 1)), 0, 6)] MSG Cuti Hari Wilayah Persekutuan
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG New Year's Day
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG New Year's Day (observed)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG New Year's Day (observed)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT [easterdate($Uy)+1] MSG Easter Monday
|
||||
OMIT 1 May MSG Workers' Day
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Workers' Day (observed)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Workers' Day (observed)
|
||||
OMIT 12 June MSG Democracy Day
|
||||
REM 12 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 12))==0 || wkdaynum(date($Ty, 6, 12))==6] MSG Democracy Day (observed)
|
||||
REM 12 June OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 6, 12)), 0, 6)] MSG Democracy Day (observed)
|
||||
OMIT 1 October MSG Independence Day
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 1))==0 || wkdaynum(date($Ty, 10, 1))==6] MSG Independence Day (observed)
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 1)), 0, 6)] MSG Independence Day (observed)
|
||||
OMIT 25 December MSG Christmas Day
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Christmas Day (observed)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Christmas Day (observed)
|
||||
OMIT 26 December MSG Boxing Day
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 26))==0 || wkdaynum(date($Ty, 12, 26))==6] MSG Boxing Day (observed)
|
||||
REM 26 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 26)), 0, 6)] MSG Boxing Day (observed)
|
||||
|
||||
@@ -20,7 +20,6 @@ OMIT 26 December MSG Tweede Kerstdag
|
||||
|
||||
# Optional holidays
|
||||
REM [easterdate($Uy)-2] MSG Goede Vrijdag
|
||||
|
||||
# Bevrijdingsdag is a holiday every 5th year.
|
||||
# Hence the two reminders below
|
||||
REM 5 May SATISFY [$Ty % 5 != 0] MSG Bevrijdingsdag
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG New Year's Day
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG New Year's Day (observed)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG New Year's Day (observed)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT 1 May MSG Labour Day
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Labour Day (observed)
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Labour Day (observed)
|
||||
OMIT 9 August MSG National Day
|
||||
REM 9 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 8, 9))==0 || wkdaynum(date($Ty, 8, 9))==6] MSG National Day (observed)
|
||||
REM 9 August OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 8, 9)), 0, 6)] MSG National Day (observed)
|
||||
OMIT 25 December MSG Christmas Day
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 25))==0 || wkdaynum(date($Ty, 12, 25))==6] MSG Christmas Day (observed)
|
||||
REM 25 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 25)), 0, 6)] MSG Christmas Day (observed)
|
||||
|
||||
@@ -15,7 +15,7 @@ OMIT 6 April MSG วันจักรี
|
||||
REM 7 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 6)) == 0] MSG ชดเชยวันจักรี
|
||||
REM 8 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 6)) == 6] MSG ชดเชยวันจักรี
|
||||
OMIT 13 April MSG วันสงกรานต์
|
||||
REM 13 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 13))==0 || wkdaynum(date($Ty, 4, 13))==6] MSG ชดเชยวันสงกรานต์
|
||||
REM 13 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 13)), 0, 6)] MSG ชดเชยวันสงกรานต์
|
||||
OMIT 14 April MSG วันสงกรานต์
|
||||
OMIT 15 April MSG วันสงกรานต์
|
||||
OMIT 1 May MSG วันแรงงานแห่งชาติ
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG 中華民國開國紀念日
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG 中華民國開國紀念日(慶祝)
|
||||
REM 1 January OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG 中華民國開國紀念日(慶祝)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG 中華民國開國紀念日(慶祝)
|
||||
REM 1 January OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG 中華民國開國紀念日(慶祝)
|
||||
OMIT 28 February MSG 和平紀念日
|
||||
REM 28 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 28))==0 || wkdaynum(date($Ty, 2, 28))==6] MSG 和平紀念日(慶祝)
|
||||
REM 28 February OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 28))==0 || wkdaynum(date($Ty, 2, 28))==6] MSG 和平紀念日(慶祝)
|
||||
REM 28 February OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 28)), 0, 6)] MSG 和平紀念日(慶祝)
|
||||
REM 28 February OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 2, 28)), 0, 6)] MSG 和平紀念日(慶祝)
|
||||
REM 2 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 0] MSG 兒童節(慶祝)
|
||||
REM 3 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 2] MSG 兒童節(慶祝)
|
||||
REM 3 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 3] MSG 兒童節(慶祝)
|
||||
REM 3 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 5] MSG 兒童節(慶祝)
|
||||
REM 3 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 6] MSG 兒童節(慶祝)
|
||||
OMIT 4 April MSG 兒童節
|
||||
REM 4 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4))==0 || wkdaynum(date($Ty, 4, 4))==6] MSG 清明節(慶祝)
|
||||
REM 4 April OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4))==0 || wkdaynum(date($Ty, 4, 4))==6] MSG 清明節(慶祝)
|
||||
REM 4 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 4)), 0, 6)] MSG 清明節(慶祝)
|
||||
REM 4 April OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 4)), 0, 6)] MSG 清明節(慶祝)
|
||||
REM 5 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 1] MSG 兒童節(慶祝)
|
||||
REM 5 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 4)) == 4] MSG 兒童節(慶祝)
|
||||
OMIT 10 October MSG 中華民國國慶日
|
||||
REM 10 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 10))==0 || wkdaynum(date($Ty, 10, 10))==6] MSG 中華民國國慶日(慶祝)
|
||||
REM 10 October OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 10))==0 || wkdaynum(date($Ty, 10, 10))==6] MSG 中華民國國慶日(慶祝)
|
||||
REM 10 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 10)), 0, 6)] MSG 中華民國國慶日(慶祝)
|
||||
REM 10 October OMIT SAT SUN BEFORE ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 10)), 0, 6)] MSG 中華民國國慶日(慶祝)
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
REM Fourth Monday in April ADDOMIT SCANFROM -28 MSG State Holiday
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG State Holiday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [$TW == 4 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 2 || $Tw == 4] MSG Washington's Birthday
|
||||
REM 26 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 2 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 5, 4)] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 1, 2, 4)] MSG Washington's Birthday
|
||||
REM 26 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 2, 5)] MSG Washington's Birthday
|
||||
|
||||
@@ -14,6 +14,6 @@ OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
REM Tuesday 2 May ADDOMIT SCANFROM -28 MSG Primary Election Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG Lincoln's Birthday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [$TW == 4 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 2 || $Tw == 4] MSG Washington's Birthday
|
||||
REM 26 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 2 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 5, 4)] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 1, 2, 4)] MSG Washington's Birthday
|
||||
REM 26 December ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 2, 5)] MSG Washington's Birthday
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Yangi yil
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Yangi yil (ko‘chirilgan)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Yangi yil (ko‘chirilgan)
|
||||
OMIT 8 March MSG Xotin-qizlar kuni
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 8))==0 || wkdaynum(date($Ty, 3, 8))==6] MSG Xotin-qizlar kuni (ko‘chirilgan)
|
||||
REM 8 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 8)), 0, 6)] MSG Xotin-qizlar kuni (ko‘chirilgan)
|
||||
OMIT 21 March MSG Navro‘z bayrami
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 21))==0 || wkdaynum(date($Ty, 3, 21))==6] MSG Navro‘z bayrami (ko‘chirilgan)
|
||||
REM 21 March OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 3, 21)), 0, 6)] MSG Navro‘z bayrami (ko‘chirilgan)
|
||||
OMIT 9 May MSG Xotira va qadrlash kuni
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 9))==0 || wkdaynum(date($Ty, 5, 9))==6] MSG Xotira va qadrlash kuni (ko‘chirilgan)
|
||||
REM 9 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 9)), 0, 6)] MSG Xotira va qadrlash kuni (ko‘chirilgan)
|
||||
OMIT 1 September MSG Mustaqillik kuni
|
||||
REM 1 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 9, 1))==0 || wkdaynum(date($Ty, 9, 1))==6] MSG Mustaqillik kuni (ko‘chirilgan)
|
||||
REM 1 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 9, 1)), 0, 6)] MSG Mustaqillik kuni (ko‘chirilgan)
|
||||
OMIT 1 October MSG O‘qituvchi va murabbiylar kuni
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 10, 1))==0 || wkdaynum(date($Ty, 10, 1))==6] MSG O‘qituvchi va murabbiylar kuni (ko‘chirilgan)
|
||||
REM 1 October OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 10, 1)), 0, 6)] MSG O‘qituvchi va murabbiylar kuni (ko‘chirilgan)
|
||||
OMIT 8 December MSG O‘zbekiston Respublikasi Konstitutsiyasi kuni
|
||||
REM 8 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 12, 8))==0 || wkdaynum(date($Ty, 12, 8))==6] MSG O‘zbekiston Respublikasi Konstitutsiyasi kuni (ko‘chirilgan)
|
||||
REM 8 December OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 12, 8)), 0, 6)] MSG O‘zbekiston Respublikasi Konstitutsiyasi kuni (ko‘chirilgan)
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
# See important caveats in the README file in this directory.
|
||||
|
||||
OMIT 1 January MSG Tết Dương lịch
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 1, 1))==0 || wkdaynum(date($Ty, 1, 1))==6] MSG Tết Dương lịch (nghỉ bù)
|
||||
REM 1 January OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 1, 1)), 0, 6)] MSG Tết Dương lịch (nghỉ bù)
|
||||
OMIT 30 April MSG Ngày Chiến thắng
|
||||
REM 30 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 30))==0 || wkdaynum(date($Ty, 4, 30))==6] MSG Ngày Chiến thắng (nghỉ bù)
|
||||
REM 30 April OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 4, 30)), 0, 6)] MSG Ngày Chiến thắng (nghỉ bù)
|
||||
OMIT 1 May MSG Ngày Quốc tế Lao động
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 1))==0 || wkdaynum(date($Ty, 5, 1))==6] MSG Ngày Quốc tế Lao động (nghỉ bù)
|
||||
REM 1 September ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 2 || $Tw == 4 || $Tw == 5] MSG Quốc khánh
|
||||
REM 1 May OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 5, 1)), 0, 6)] MSG Ngày Quốc tế Lao động (nghỉ bù)
|
||||
REM 1 September ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 1, 2, 4, 5)] MSG Quốc khánh
|
||||
OMIT 2 September MSG Quốc khánh
|
||||
REM 2 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 9, 2))==0 || wkdaynum(date($Ty, 9, 2))==6] MSG Quốc khánh (nghỉ bù)
|
||||
REM 3 September ADDOMIT SCANFROM -28 SATISFY [$Tw == 2 || $Tw == 5 || $Tw == 1] MSG Quốc khánh
|
||||
REM 2 September OMIT SAT SUN AFTER ADDOMIT SCANFROM -28 SATISFY [isany(wkdaynum(date($Ty, 9, 2)), 0, 6)] MSG Quốc khánh (nghỉ bù)
|
||||
REM 3 September ADDOMIT SCANFROM -28 SATISFY [isany($Tw, 2, 5, 1)] MSG Quốc khánh
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
if !defined("__autolang__")
|
||||
SET __autolang__ 1
|
||||
PRESERVE __autolang__
|
||||
SET autolang getenv("REMIND_LANG")
|
||||
if defined("__autolang__")
|
||||
RETURN
|
||||
endif
|
||||
|
||||
IF autolang == ""
|
||||
SET autolang getenv("LC_ALL")
|
||||
ENDIF
|
||||
IF autolang == ""
|
||||
SET autolang getenv("LANGUAGE")
|
||||
ENDIF
|
||||
IF autolang == ""
|
||||
SET autolang getenv("LANG")
|
||||
ENDIF
|
||||
SET __autolang__ 1
|
||||
PRESERVE __autolang__
|
||||
|
||||
IF autolang != ""
|
||||
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 5)) + ".rem", "r") == 0
|
||||
SYSINCLUDE lang/[lower(substr(autolang, 1, 5))].rem
|
||||
ELSE
|
||||
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 2)) + ".rem", "r") == 0
|
||||
SYSINCLUDE lang/[lower(substr(autolang, 1, 2))].rem
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
UNSET autolang
|
||||
PUSH-VARS autolang
|
||||
SET autolang getenv("REMIND_LANG")
|
||||
|
||||
IF autolang == ""
|
||||
SET autolang getenv("LC_ALL")
|
||||
ENDIF
|
||||
IF autolang == ""
|
||||
SET autolang getenv("LANGUAGE")
|
||||
ENDIF
|
||||
IF autolang == ""
|
||||
SET autolang getenv("LANG")
|
||||
ENDIF
|
||||
|
||||
IF autolang != ""
|
||||
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 5)) + ".rem", "r") == 0
|
||||
SYSINCLUDE lang/[lower(substr(autolang, 1, 5))].rem
|
||||
ELSE
|
||||
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 2)) + ".rem", "r") == 0
|
||||
SYSINCLUDE lang/[lower(substr(autolang, 1, 2))].rem
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
POP-VARS
|
||||
|
||||
|
||||
@@ -28,7 +28,12 @@ SET $December "desembre"
|
||||
|
||||
SET $Today "avui"
|
||||
SET $Tomorrow "demà"
|
||||
FSET subst_bx(a,d,t) iif(d==today()+2, "demà passat", "d'aquí " + (d-today()) + " dies")
|
||||
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")
|
||||
|
||||
# 1 d'abril vs 1 de maig.
|
||||
FSET subst_sx(a,d,t) iif(isany(substr(mon(d), 1, 1), "a", "o") , "d'", "de")
|
||||
|
||||
@@ -29,6 +29,11 @@ SET $December "December"
|
||||
SET $Today "i dag"
|
||||
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:
|
||||
|
||||
SET $Am "am"
|
||||
@@ -51,13 +56,14 @@ SET $Mplu "ter"
|
||||
|
||||
FSET subst_ampm(h) iif(h<5, " om natten", h < 12, " om formiddagen", h < 18, " om eftermiddagen", " om aftenen")
|
||||
FSET subst_ordinal(d) "."
|
||||
FSET ordx(n) n + "."
|
||||
|
||||
FSET subst_p(alt, d, t) iif(d==today()+1, "", "e")
|
||||
FSET zeropad(s, len) pad(s, "0", len)
|
||||
FSET subst_a_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) + " " + year(d)
|
||||
FSET subst_ax(alt, d, t) iif(alt, subst_a_alt(d), $On + " " + subst_a_alt(d))
|
||||
|
||||
FSET subst_bx(a, d, t) "om " + (d-today()) + " dage"
|
||||
FSET subst_bx(a, d, t) iif(d >= today(), "om " + (d-today()) + " dage", "for " + (today()-d) + " dage siden")
|
||||
|
||||
FSET subst_ex(alt, d, t) "den " + zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2) + $DateSep + zeropad(year(d), 4)
|
||||
FSET subst_fx(alt, d, t) "den " + zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2) + $DateSep + zeropad(year(d), 4)
|
||||
|
||||
@@ -31,6 +31,11 @@ SET $December "Dezember"
|
||||
SET $Today "heute"
|
||||
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:
|
||||
|
||||
@@ -51,11 +56,12 @@ SET $Fromnow "von heute"
|
||||
|
||||
FSET subst_ampm(h) iif(h<5, " nachts", h<12, " vormittags", h<=17, " nachmittags", " abends")
|
||||
FSET subst_ordinal(d) "."
|
||||
FSET ordx(n) n + "."
|
||||
|
||||
FSET subst_a_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) + " " + year(d)
|
||||
FSET subst_ax(alt, d, t) iif(alt, subst_a_alt(d), $On + " " + subst_a_alt(d))
|
||||
|
||||
FSET subst_bx(a, d, t) "in " + (d-today()) + " Tagen"
|
||||
FSET subst_bx(a, d, t) iif(d >= today(), "in " + (d-today()) + " Tagen", "vor " + (today()-d) + " Tagen")
|
||||
|
||||
FSET subst_g_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d)
|
||||
FSET subst_gx(alt, d, t) iif(alt, subst_g_alt(d), $On + " " + subst_g_alt(d))
|
||||
|
||||
@@ -29,6 +29,11 @@ SET $December "Diciembre"
|
||||
SET $Today "hoy"
|
||||
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:
|
||||
|
||||
SET $Am "am"
|
||||
@@ -47,4 +52,4 @@ SET $And "y"
|
||||
SET $Hplu "s"
|
||||
SET $Mplu "s"
|
||||
|
||||
FSET subst_bx(a, d, t) "dentro de " + (d-today()) + " días"
|
||||
FSET subst_bx(a, d, t) iif(d >= today(), "dentro de " + (d-today()) + " días", "hace " + (today()-d) + " dias")
|
||||
|
||||
@@ -29,6 +29,11 @@ SET $December "joulukuu"
|
||||
SET $Today "tänään"
|
||||
SET $Tomorrow "huomenna"
|
||||
|
||||
TRANSLATE "yesterday" "eilen"
|
||||
TRANSLATE "are" "ovat"
|
||||
TRANSLATE "were" "olivat"
|
||||
TRANSLATE "done" "suoritettu"
|
||||
|
||||
BANNER Viestit %wna %d. %mta %y%o:
|
||||
|
||||
SET $Am " ap."
|
||||
@@ -52,11 +57,12 @@ SET $Mplu "a"
|
||||
FSET zeropad(s, len) pad(s, "0", len)
|
||||
|
||||
FSET subst_ordinal(d) iif(d==1, ":senä", d==2, ":sena", (d%10)==2||(d%10)==3||(d%10)==6||(d%10)==8, ":ntena", ":ntenä")
|
||||
FSET ordx(d) d + subst_ordinal(d)
|
||||
|
||||
FSET subst_a_alt(d, o, p) wkday(d) + o + " " + day(d) + ". " + mon(d) + p + " " + year(d)
|
||||
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d, "", ""), subst_a_alt(d, $On, "ta"))
|
||||
|
||||
FSET subst_bx(a, d, t) (d-today()) + " päivän kuluttua"
|
||||
FSET subst_bx(a, d, t) iif(d >= today(), (d-today()) + " päivän kuluttua", (today()-d) + " päivää sitten")
|
||||
FSET subst_cx(a, d, t) iif(a, wkday(d), wkday(d) + $On)
|
||||
|
||||
FSET subst_ex(a, d, t) zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2) + $DateSep + zeropad(year(d), 4)
|
||||
|
||||
@@ -28,6 +28,12 @@ SET $December "décembre"
|
||||
|
||||
SET $Today "aujourd'hui"
|
||||
SET $Tomorrow "demain"
|
||||
|
||||
TRANSLATE "yesterday" "hier"
|
||||
TRANSLATE "are" "sont"
|
||||
TRANSLATE "were" "étaient"
|
||||
TRANSLATE "done" "accomplie"
|
||||
|
||||
SET $On "le"
|
||||
SET $At "à"
|
||||
SET $Now "maintenant"
|
||||
@@ -46,6 +52,7 @@ BANNER Rappels pour %w, %d%s %m, %y%o:
|
||||
|
||||
# Ordinal for a day (English would be "st", "nd", "rd", "th")
|
||||
FSET subst_ordinal(d) iif(d == 1, "er", "")
|
||||
FSET ordx(n) n + iif(n == 1, "er", "e")
|
||||
|
||||
# "%d hours", "%d minutes", or "%d hours and %d minutes"
|
||||
FSET subst_tdiff(hdiff, mdiff) iif(hdiff==0&&mdiff==0, $Now, \
|
||||
@@ -56,13 +63,14 @@ FSET subst_1(alt, date, time) iif(time == now(), "maintenant", \
|
||||
time > now(), "dans " + subst_tdiff((time-now())/60, (time-now())%60), \
|
||||
"il y a " + subst_tdiff ((now()-time)/60, (now()-time)%60))
|
||||
|
||||
FSET subst_bx(alt, date, time) "dans " + (date-today()) + " jours"
|
||||
FSET subst_bx(alt, date, time) iif(date >= today(), "dans " + (date-today()) + " jours", "il y a " + (today()-date) + " jours")
|
||||
FSET subst_j_alt(date) wkday(date) + ", " + day(date) + subst_ordinal(day(date)) + " " + mon(date) + ", " + year(date)
|
||||
FSET subst_jx(alt, date, time) iif(alt, subst_j_alt(date), $On + " " + subst_j_alt(date))
|
||||
|
||||
FSET subst_k_alt(date) wkday(date) + ", " + day(date) + subst_ordinal(day(date)) + " " + mon(date)
|
||||
FSET subst_kx(alt, date, time) iif(alt, subst_k_alt(date), $On + " " + subst_k_alt(date))
|
||||
|
||||
|
||||
TRANSLATE "Missing ']'" "']' manquant"
|
||||
TRANSLATE "Missing quote" "Apostrophe manquant"
|
||||
TRANSLATE "Expression too complex" "Expression trop complexe"
|
||||
|
||||
@@ -29,6 +29,11 @@ SET $December "Δεκέμβρ."
|
||||
SET $Today "σήμερα"
|
||||
SET $Tomorrow "αύριο"
|
||||
|
||||
TRANSLATE "yesterday" "εχθές"
|
||||
TRANSLATE "are" "είναι"
|
||||
TRANSLATE "were" "ήταν"
|
||||
TRANSLATE "done" "ολοκληρώθηκε"
|
||||
|
||||
BANNER Υπενθυμίσεις: %w, %d %m, %y%o:
|
||||
|
||||
SET $Am "πμ"
|
||||
@@ -49,8 +54,9 @@ SET $And "και"
|
||||
SET $Hplu ""
|
||||
SET $Mplu ""
|
||||
|
||||
FSET subst_bx(a, d, t) "σε " + (d - today()) + " ημέρες"
|
||||
FSET subst_bx(a, d, t) iif(d >= today(), "σε " + (d - today()) + " ημέρες", "πριν από " + (today()-d) + " ημέρες")
|
||||
FSET subst_ordinal(d) "."
|
||||
FSET ordx(d) d + "."
|
||||
FSET subst_a_alt(d) wkday(d) + ", " + day(d) + ". " + mon(d) + " " + year(d)
|
||||
FSET subst_ax(alt, d, t) iif(alt, subst_a_alt(d), $On + " " + subst_a_alt(d))
|
||||
FSET subst_g_alt(d) wkday(d) + ", " + day(d) + ". " + mon(d)
|
||||
|
||||
@@ -29,6 +29,11 @@ SET $December "desember"
|
||||
SET $Today "í dag"
|
||||
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:
|
||||
|
||||
SET $Am "fh"
|
||||
@@ -49,5 +54,5 @@ SET $And "og"
|
||||
SET $Hplu "ir"
|
||||
SET $Mplu "r"
|
||||
|
||||
FSET subst_bx(a, d, t) "eftir " + (d - today()) + " daga"
|
||||
FSET subst_bx(a, d, t) iif(d >= today(), "eftir " + (d - today()) + " daga", "fyrir " + (today()-d) + " dögum")
|
||||
fset subst_p(a, d, t) iif(d == today()+1, "", "a")
|
||||
|
||||
@@ -29,6 +29,11 @@ SET $December "Dicembre"
|
||||
SET $Today "oggi"
|
||||
SET $Tomorrow "domani"
|
||||
|
||||
TRANSLATE "yesterday" "Ieri"
|
||||
TRANSLATE "are" "sono"
|
||||
TRANSLATE "were" "erano"
|
||||
TRANSLATE "done" "completato"
|
||||
|
||||
BANNER Promemoria per %w, %d %m %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
@@ -48,7 +53,7 @@ SET $And "e"
|
||||
SET $Hplu "a"
|
||||
SET $Mplu "i"
|
||||
|
||||
FSET subst_bx(a, d, t) "fra " + (d-today()) + " giorni"
|
||||
FSET subst_bx(a, d, t) iif(d >= today(), "fra " + (d-today()) + " giorni", (today()-d) + " giorni fa")
|
||||
FSET subst_p(a, d, t) iif(d==today()+1, "o", "i")
|
||||
FSET subst_q(a, d, t) iif(d==today()+1, "a", "e")
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@ SET $December "december"
|
||||
|
||||
SET $Today "vandaag"
|
||||
SET $Tomorrow "morgen"
|
||||
TRANSLATE "yesterday" "gisteren"
|
||||
TRANSLATE "are" "zijn"
|
||||
TRANSLATE "were" "waren"
|
||||
TRANSLATE "done" "voltooid"
|
||||
|
||||
BANNER Herinneringen voor %w, %d %m, %y%o:
|
||||
|
||||
@@ -55,9 +59,12 @@ FSET subst_1b(hdiff, mdiff) iif(hdiff==0, subst_minutes(mdiff), mdiff==0, subst_
|
||||
FSET subst_minutes(m) iif(m==1, "1 minuut", m + " minuten")
|
||||
FSET subst_hours(h) iif(h==1, "1 uur", h + " uren")
|
||||
|
||||
FSET subst_bx(a, d, t) "over " + (d-today()) + " dagen"
|
||||
FSET subst_bx(a, d, t) iif (d == today()+2, "overmorgen", d+2 == today(), "eergisteren", d >= today(), "over " + (d-today()) + " dagen", (today()-d) + " dagen geleden")
|
||||
|
||||
FSET subst_s(a, d, t) iif(day(d) == 1 || day(d) == 8, "e", day(d) < 20, "de", "te")
|
||||
|
||||
FSET ordx(n) n + "e"
|
||||
|
||||
TRANSLATE "New Moon" "Nieuwe maan"
|
||||
TRANSLATE "First Quarter" "Eerste kwartier"
|
||||
TRANSLATE "Full Moon" "Volle maan"
|
||||
|
||||
@@ -29,6 +29,11 @@ SET $December "Desember"
|
||||
SET $Today "i dag"
|
||||
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:
|
||||
|
||||
SET $Am "am"
|
||||
@@ -48,8 +53,9 @@ SET $And "og"
|
||||
SET $Hplu "r"
|
||||
SET $Mplu "er"
|
||||
|
||||
FSET subst_bx(a, d, t) "om " + (d-today()) + " dager"
|
||||
FSET subst_bx(a, d, t) iif(d >= today(), "om " + (d-today()) + " dager", "for " + (today()-d) + " dager siden")
|
||||
FSET subst_ordinal(d) "."
|
||||
FSET ordx(n) n + "."
|
||||
|
||||
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d), $On + " " + subst_a_alt(d))
|
||||
FSET subst_a_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) + " " + year(d)
|
||||
|
||||
@@ -29,6 +29,11 @@ SET $December "Grudzień"
|
||||
SET $Today "dzisiaj"
|
||||
SET $Tomorrow "jutro"
|
||||
|
||||
TRANSLATE "yesterday" "wczoraj"
|
||||
TRANSLATE "are" "są"
|
||||
TRANSLATE "were" "byli"
|
||||
TRANSLATE "done" "ukończone"
|
||||
|
||||
BANNER Terminarz na %w, %d. %m %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
@@ -53,7 +58,7 @@ FSET subst_ordinal(d) ""
|
||||
|
||||
FSET subst_a_alt(d) wkday(d) + ", " + day(d) + ". " + mon(d) + " " + year(d)
|
||||
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d), $On + " " + subst_a_alt(d))
|
||||
FSET subst_bx(a, d, t) "za " + (d-today()) + " dni"
|
||||
FSET subst_bx(a, d, t) iif(d >= today(), "za " + (d-today()) + " dni", (today()-d) + " dni temu")
|
||||
FSET subst_g_alt(d) wkday(d) + ", " + day(d) + ". " + mon(d)
|
||||
FSET subst_gx(a, d, t) iif(a, subst_g_alt(d), $On + " " + subst_g_alt(d))
|
||||
FSET subst_ux(a, d, t) subst_ax(a, d, t)
|
||||
|
||||
@@ -29,6 +29,11 @@ SET $December "dezembro"
|
||||
SET $Today "hoje"
|
||||
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:
|
||||
|
||||
SET $Am "am"
|
||||
@@ -53,7 +58,7 @@ FSET subst_ordinal(d) ""
|
||||
FSET subst_on_wd(d) iif(wkdaynum(d) == 1 || wkdaynum(d) == 2, "no", "na")
|
||||
|
||||
FSET subst_a_alt(d) wkday(d) + ", " + day(d) + " de " + mon(d) + " de " + year(d)
|
||||
FSET subst_bx(a, d, t) "em " + (d-today()) + " dias"
|
||||
FSET subst_bx(a, d, t) iif(d >= today(), "em " + (d-today()) + " dias", "há " + (today()-d) + " dias")
|
||||
FSET subst_c_alt(d) wkday(d)
|
||||
FSET subst_g_alt(d) wkday(d) + ", " + day(d) + " " + mon(d)
|
||||
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d), subst_on_wd(d) + " " + subst_a_alt(d))
|
||||
|
||||
@@ -28,6 +28,10 @@ SET $December "Decembrie"
|
||||
|
||||
SET $Today "astăzi"
|
||||
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:
|
||||
|
||||
@@ -49,7 +53,7 @@ SET $Mplu "e"
|
||||
SET $Hplu "e"
|
||||
SET $And "şi"
|
||||
|
||||
FSET subst_bx(a, d, t) "peste " + (d-today()) + " zile"
|
||||
FSET subst_bx(a, d, t) iif(d >= today(), "peste " + (d-today()) + " zile", "acume " + (today()-d) + " zile")
|
||||
|
||||
FSET subst_ampm(h) iif(h<4, " noaptea", h<12, " dimineaţa", h<18, " după-amiaza", " seara")
|
||||
FSET subst_ordinal(d) ""
|
||||
|
||||
@@ -59,93 +59,92 @@ REM NOQUEUE [utctolocal('2036-08-07@00:57')] DURATION 231 MSG Total Lunar Eclips
|
||||
REM NOQUEUE [utctolocal('2037-01-31@12:22')] DURATION 197 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2037-07-27@02:34')] DURATION 192 MSG Partial Lunar Eclipse
|
||||
# The following will only work on systems with 64-bit time_t
|
||||
IF $TimetIs64bit
|
||||
REM NOQUEUE [utctolocal('2039-06-06@17:25')] DURATION 179 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2039-11-30@15:13')] DURATION 206 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2040-05-26@10:01')] DURATION 211 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2040-11-18@17:14')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2041-05-16@00:13')] DURATION 58 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2041-11-08@03:48')] DURATION 91 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2043-03-25@12:43')] DURATION 215 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2043-09-19@00:07')] DURATION 206 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2044-03-13@17:53')] DURATION 209 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2044-09-07@09:36')] DURATION 206 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2046-01-22@12:36')] DURATION 50 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2046-07-18@00:07')] DURATION 115 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2047-01-12@23:40')] DURATION 209 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2047-07-07@08:45')] DURATION 218 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2048-01-01@05:05')] DURATION 215 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2048-06-26@00:41')] DURATION 160 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2050-05-06@20:48')] DURATION 206 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2050-10-30@01:44')] DURATION 193 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2051-04-26@00:24')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2051-10-19@17:28')] DURATION 204 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2052-10-08@10:13')] DURATION 63 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2054-02-22@05:09')] DURATION 201 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2054-08-18@07:32')] DURATION 226 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2055-02-11@21:05')] DURATION 199 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2055-08-07@09:10')] DURATION 203 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2057-06-17@01:00')] DURATION 169 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2057-12-11@23:10')] DURATION 204 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2058-06-06@17:27')] DURATION 214 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2058-11-30@01:24')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2059-05-27@07:05')] DURATION 97 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2059-11-19@12:10')] DURATION 99 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2061-04-04@20:07')] DURATION 210 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2061-09-29@07:55')] DURATION 203 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2062-03-25@01:46')] DURATION 212 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2062-09-18@16:46')] DURATION 212 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2063-03-14@15:43')] DURATION 41 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2064-02-02@21:26')] DURATION 42 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2064-07-28@07:13')] DURATION 75 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2065-01-22@08:12')] DURATION 209 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2065-07-17@15:58')] DURATION 217 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2066-01-11@13:15')] DURATION 215 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2066-07-07@08:03')] DURATION 171 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2068-05-17@04:01')] DURATION 199 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2068-11-09@10:10')] DURATION 190 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2069-05-06@07:15')] DURATION 226 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2069-10-30@01:50')] DURATION 206 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2070-10-19@18:08')] DURATION 82 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2072-03-04@13:41')] DURATION 200 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2072-08-28@14:13')] DURATION 220 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2073-02-22@05:43')] DURATION 199 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2073-08-17@15:55')] DURATION 211 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2075-06-28@08:35')] DURATION 157 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2075-12-22@07:12')] DURATION 203 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2076-06-17@00:50')] DURATION 215 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2076-12-10@09:42')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2077-06-06@13:55')] DURATION 125 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2077-11-29@20:41')] DURATION 105 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2079-04-16@03:26')] DURATION 204 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2079-10-10@15:49')] DURATION 198 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2080-04-04@09:34')] DURATION 214 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2080-09-29@00:01')] DURATION 218 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2081-03-25@23:46')] DURATION 67 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2082-02-13@06:14')] DURATION 25 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2083-02-02@16:40')] DURATION 208 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2083-07-29@23:16')] DURATION 213 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2084-01-22@21:22')] DURATION 216 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2084-07-17@15:25')] DURATION 182 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2086-05-28@11:06')] DURATION 190 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2086-11-20@18:43')] DURATION 188 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2087-05-17@13:57')] DURATION 231 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2087-11-10@10:19')] DURATION 207 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2088-05-05@15:35')] DURATION 77 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2088-10-30@02:14')] DURATION 93 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2090-03-15@22:07')] DURATION 197 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2090-09-08@21:03')] DURATION 213 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2091-03-05@14:15')] DURATION 201 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2091-08-29@22:47')] DURATION 217 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2093-07-08@16:10')] DURATION 142 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2094-01-01@15:16')] DURATION 202 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2094-06-28@08:11')] DURATION 216 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2094-12-21@18:03')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2095-06-17@20:44')] DURATION 147 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2095-12-11@05:17')] DURATION 109 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2097-04-26@10:37')] DURATION 196 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2097-10-21@23:50')] DURATION 195 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2098-04-15@17:14')] DURATION 215 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2098-10-10@07:26')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2099-04-05@07:44')] DURATION 88 MSG Partial Lunar Eclipse
|
||||
ENDIF
|
||||
REM NOQUEUE [utctolocal('2039-06-06@17:25')] DURATION 179 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2039-11-30@15:13')] DURATION 206 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2040-05-26@10:01')] DURATION 211 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2040-11-18@17:14')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2041-05-16@00:13')] DURATION 58 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2041-11-08@03:48')] DURATION 91 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2043-03-25@12:43')] DURATION 215 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2043-09-19@00:07')] DURATION 206 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2044-03-13@17:53')] DURATION 209 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2044-09-07@09:36')] DURATION 206 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2046-01-22@12:36')] DURATION 50 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2046-07-18@00:07')] DURATION 115 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2047-01-12@23:40')] DURATION 209 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2047-07-07@08:45')] DURATION 218 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2048-01-01@05:05')] DURATION 215 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2048-06-26@00:41')] DURATION 160 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2050-05-06@20:48')] DURATION 206 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2050-10-30@01:44')] DURATION 193 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2051-04-26@00:24')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2051-10-19@17:28')] DURATION 204 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2052-10-08@10:13')] DURATION 63 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2054-02-22@05:09')] DURATION 201 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2054-08-18@07:32')] DURATION 226 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2055-02-11@21:05')] DURATION 199 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2055-08-07@09:10')] DURATION 203 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2057-06-17@01:00')] DURATION 169 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2057-12-11@23:10')] DURATION 204 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2058-06-06@17:27')] DURATION 214 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2058-11-30@01:24')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2059-05-27@07:05')] DURATION 97 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2059-11-19@12:10')] DURATION 99 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2061-04-04@20:07')] DURATION 210 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2061-09-29@07:55')] DURATION 203 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2062-03-25@01:46')] DURATION 212 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2062-09-18@16:46')] DURATION 212 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2063-03-14@15:43')] DURATION 41 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2064-02-02@21:26')] DURATION 42 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2064-07-28@07:13')] DURATION 75 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2065-01-22@08:12')] DURATION 209 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2065-07-17@15:58')] DURATION 217 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2066-01-11@13:15')] DURATION 215 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2066-07-07@08:03')] DURATION 171 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2068-05-17@04:01')] DURATION 199 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2068-11-09@10:10')] DURATION 190 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2069-05-06@07:15')] DURATION 226 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2069-10-30@01:50')] DURATION 206 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2070-10-19@18:08')] DURATION 82 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2072-03-04@13:41')] DURATION 200 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2072-08-28@14:13')] DURATION 220 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2073-02-22@05:43')] DURATION 199 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2073-08-17@15:55')] DURATION 211 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2075-06-28@08:35')] DURATION 157 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2075-12-22@07:12')] DURATION 203 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2076-06-17@00:50')] DURATION 215 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2076-12-10@09:42')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2077-06-06@13:55')] DURATION 125 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2077-11-29@20:41')] DURATION 105 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2079-04-16@03:26')] DURATION 204 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2079-10-10@15:49')] DURATION 198 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2080-04-04@09:34')] DURATION 214 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2080-09-29@00:01')] DURATION 218 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2081-03-25@23:46')] DURATION 67 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2082-02-13@06:14')] DURATION 25 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2083-02-02@16:40')] DURATION 208 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2083-07-29@23:16')] DURATION 213 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2084-01-22@21:22')] DURATION 216 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2084-07-17@15:25')] DURATION 182 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2086-05-28@11:06')] DURATION 190 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2086-11-20@18:43')] DURATION 188 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2087-05-17@13:57')] DURATION 231 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2087-11-10@10:19')] DURATION 207 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2088-05-05@15:35')] DURATION 77 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2088-10-30@02:14')] DURATION 93 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2090-03-15@22:07')] DURATION 197 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2090-09-08@21:03')] DURATION 213 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2091-03-05@14:15')] DURATION 201 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2091-08-29@22:47')] DURATION 217 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2093-07-08@16:10')] DURATION 142 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2094-01-01@15:16')] DURATION 202 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2094-06-28@08:11')] DURATION 216 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2094-12-21@18:03')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2095-06-17@20:44')] DURATION 147 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2095-12-11@05:17')] DURATION 109 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2097-04-26@10:37')] DURATION 196 MSG Partial Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2097-10-21@23:50')] DURATION 195 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2098-04-15@17:14')] DURATION 215 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2098-10-10@07:26')] DURATION 221 MSG Total Lunar Eclipse
|
||||
REM NOQUEUE [utctolocal('2099-04-05@07:44')] DURATION 88 MSG Partial Lunar Eclipse
|
||||
|
||||
|
||||
@@ -92,148 +92,147 @@ REM NOQUEUE [utctolocal('2037-01-16@09:49')] MSG Partial Solar Eclipse centered
|
||||
REM NOQUEUE [utctolocal('2037-07-13@02:41')] MSG Total Solar Eclipse centered at 24.8°S 139.1°E
|
||||
|
||||
# The following will only work on systems with 64-bit time_t
|
||||
IF $TimetIs64bit
|
||||
REM NOQUEUE [utctolocal('2038-01-05@13:47')] MSG Annular Solar Eclipse centered at 2.1°N 25.4°W
|
||||
REM NOQUEUE [utctolocal('2038-07-02@13:33')] MSG Annular Solar Eclipse centered at 25.4°N 21.9°W
|
||||
REM NOQUEUE [utctolocal('2038-12-26@01:00')] MSG Total Solar Eclipse centered at 40.3°S 164.0°E
|
||||
REM NOQUEUE [utctolocal('2039-06-21@17:13')] MSG Annular Solar Eclipse centered at 78.9°N 102.1°W
|
||||
REM NOQUEUE [utctolocal('2039-12-15@16:24')] MSG Total Solar Eclipse centered at 80.9°S 172.8°E
|
||||
REM NOQUEUE [utctolocal('2040-05-11@03:43')] MSG Partial Solar Eclipse centered at 62.8°S 174.4°E
|
||||
REM NOQUEUE [utctolocal('2040-11-04@19:09')] MSG Partial Solar Eclipse centered at 62.2°N 53.4°W
|
||||
REM NOQUEUE [utctolocal('2041-04-30@11:52')] MSG Total Solar Eclipse centered at 9.6°S 12.2°E
|
||||
REM NOQUEUE [utctolocal('2041-10-25@01:36')] MSG Annular Solar Eclipse centered at 9.9°N 162.9°E
|
||||
REM NOQUEUE [utctolocal('2042-04-20@02:17')] MSG Total Solar Eclipse centered at 27.0°N 137.3°E
|
||||
REM NOQUEUE [utctolocal('2042-10-14@02:01')] MSG Annular Solar Eclipse centered at 23.7°S 137.8°E
|
||||
REM NOQUEUE [utctolocal('2043-04-09@18:58')] MSG Total (non-central) Solar Eclipse centered at 61.3°N 152.0°E
|
||||
REM NOQUEUE [utctolocal('2043-10-03@03:02')] MSG Annular (non-central) Solar Eclipse centered at 61.0°S 35.3°E
|
||||
REM NOQUEUE [utctolocal('2044-02-28@20:25')] MSG Annular Solar Eclipse centered at 62.2°S 25.6°W
|
||||
REM NOQUEUE [utctolocal('2044-08-23@01:17')] MSG Total Solar Eclipse centered at 64.3°N 120.4°W
|
||||
REM NOQUEUE [utctolocal('2045-02-16@23:56')] MSG Annular Solar Eclipse centered at 28.3°S 166.2°W
|
||||
REM NOQUEUE [utctolocal('2045-08-12@17:43')] MSG Total Solar Eclipse centered at 25.9°N 78.5°W
|
||||
REM NOQUEUE [utctolocal('2046-02-05@23:06')] MSG Annular Solar Eclipse centered at 4.8°N 171.4°W
|
||||
REM NOQUEUE [utctolocal('2046-08-02@10:21')] MSG Total Solar Eclipse centered at 12.7°S 15.2°E
|
||||
REM NOQUEUE [utctolocal('2047-01-26@01:33')] MSG Partial Solar Eclipse centered at 62.9°N 111.7°E
|
||||
REM NOQUEUE [utctolocal('2047-06-23@10:53')] MSG Partial Solar Eclipse centered at 65.8°N 178.0°W
|
||||
REM NOQUEUE [utctolocal('2047-07-22@22:36')] MSG Partial Solar Eclipse centered at 63.4°S 160.2°E
|
||||
REM NOQUEUE [utctolocal('2047-12-16@23:50')] MSG Partial Solar Eclipse centered at 66.4°S 6.6°W
|
||||
REM NOQUEUE [utctolocal('2048-06-11@12:59')] MSG Annular Solar Eclipse centered at 63.7°N 11.5°W
|
||||
REM NOQUEUE [utctolocal('2048-12-05@15:35')] MSG Total Solar Eclipse centered at 46.1°S 56.4°W
|
||||
REM NOQUEUE [utctolocal('2049-05-31@14:00')] MSG Annular Solar Eclipse centered at 15.3°N 29.9°W
|
||||
REM NOQUEUE [utctolocal('2049-11-25@05:34')] MSG Hybrid Solar Eclipse centered at 3.8°S 95.2°E
|
||||
REM NOQUEUE [utctolocal('2050-05-20@20:43')] MSG Hybrid Solar Eclipse centered at 40.1°S 123.7°W
|
||||
REM NOQUEUE [utctolocal('2050-11-14@13:31')] MSG Partial Solar Eclipse centered at 69.5°N 1.0°E
|
||||
REM NOQUEUE [utctolocal('2051-04-11@02:11')] MSG Partial Solar Eclipse centered at 71.6°N 32.2°E
|
||||
REM NOQUEUE [utctolocal('2051-10-04@21:02')] MSG Partial Solar Eclipse centered at 72.0°S 117.7°E
|
||||
REM NOQUEUE [utctolocal('2052-03-30@18:32')] MSG Total Solar Eclipse centered at 22.4°N 102.5°W
|
||||
REM NOQUEUE [utctolocal('2052-09-22@23:39')] MSG Annular Solar Eclipse centered at 25.7°S 175.0°E
|
||||
REM NOQUEUE [utctolocal('2053-03-20@07:08')] MSG Annular Solar Eclipse centered at 23.0°S 83.0°E
|
||||
REM NOQUEUE [utctolocal('2053-09-12@09:34')] MSG Total Solar Eclipse centered at 21.5°N 41.7°E
|
||||
REM NOQUEUE [utctolocal('2054-03-09@12:34')] MSG Partial Solar Eclipse centered at 72.0°S 97.9°E
|
||||
REM NOQUEUE [utctolocal('2054-08-03@18:04')] MSG Partial Solar Eclipse centered at 69.8°S 121.3°W
|
||||
REM NOQUEUE [utctolocal('2054-09-02@01:10')] MSG Partial Solar Eclipse centered at 71.7°N 82.3°W
|
||||
REM NOQUEUE [utctolocal('2055-01-27@17:54')] MSG Partial Solar Eclipse centered at 69.5°N 112.2°W
|
||||
REM NOQUEUE [utctolocal('2055-07-24@09:58')] MSG Total Solar Eclipse centered at 33.3°S 25.8°E
|
||||
REM NOQUEUE [utctolocal('2056-01-16@22:17')] MSG Annular Solar Eclipse centered at 3.9°N 153.5°W
|
||||
REM NOQUEUE [utctolocal('2056-07-12@20:22')] MSG Annular Solar Eclipse centered at 19.4°N 123.7°W
|
||||
REM NOQUEUE [utctolocal('2057-01-05@09:48')] MSG Total Solar Eclipse centered at 39.2°S 35.2°E
|
||||
REM NOQUEUE [utctolocal('2057-07-01@23:40')] MSG Annular Solar Eclipse centered at 71.5°N 176.2°W
|
||||
REM NOQUEUE [utctolocal('2057-12-26@01:15')] MSG Total Solar Eclipse centered at 84.9°S 21.8°E
|
||||
REM NOQUEUE [utctolocal('2058-05-22@10:39')] MSG Partial Solar Eclipse centered at 63.5°S 61.1°E
|
||||
REM NOQUEUE [utctolocal('2058-06-21@00:20')] MSG Partial Solar Eclipse centered at 65.9°N 9.9°E
|
||||
REM NOQUEUE [utctolocal('2058-11-16@03:23')] MSG Partial Solar Eclipse centered at 62.9°N 174.2°E
|
||||
REM NOQUEUE [utctolocal('2059-05-11@19:22')] MSG Total Solar Eclipse centered at 10.7°S 100.4°W
|
||||
REM NOQUEUE [utctolocal('2059-11-05@09:18')] MSG Annular Solar Eclipse centered at 8.7°N 47.1°E
|
||||
REM NOQUEUE [utctolocal('2060-04-30@10:10')] MSG Total Solar Eclipse centered at 28.0°N 20.9°E
|
||||
REM NOQUEUE [utctolocal('2060-10-24@09:24')] MSG Annular Solar Eclipse centered at 25.8°S 28.1°E
|
||||
REM NOQUEUE [utctolocal('2061-04-20@02:57')] MSG Total Solar Eclipse centered at 64.5°N 59.2°E
|
||||
REM NOQUEUE [utctolocal('2061-10-13@10:32')] MSG Annular Solar Eclipse centered at 62.1°S 54.4°W
|
||||
REM NOQUEUE [utctolocal('2062-03-11@04:26')] MSG Partial Solar Eclipse centered at 61.0°S 147.1°W
|
||||
REM NOQUEUE [utctolocal('2062-09-03@08:54')] MSG Partial Solar Eclipse centered at 61.3°N 150.3°E
|
||||
REM NOQUEUE [utctolocal('2063-02-28@07:43')] MSG Annular Solar Eclipse centered at 25.2°S 77.7°E
|
||||
REM NOQUEUE [utctolocal('2063-08-24@01:22')] MSG Total Solar Eclipse centered at 25.6°N 168.4°E
|
||||
REM NOQUEUE [utctolocal('2064-02-17@07:00')] MSG Annular Solar Eclipse centered at 7.0°N 69.7°E
|
||||
REM NOQUEUE [utctolocal('2064-08-12@17:46')] MSG Total Solar Eclipse centered at 10.9°S 96.0°W
|
||||
REM NOQUEUE [utctolocal('2065-02-05@09:52')] MSG Partial Solar Eclipse centered at 62.2°N 21.9°W
|
||||
REM NOQUEUE [utctolocal('2065-07-03@17:34')] MSG Partial Solar Eclipse centered at 64.8°N 71.9°E
|
||||
REM NOQUEUE [utctolocal('2065-08-02@05:34')] MSG Partial Solar Eclipse centered at 62.7°S 46.5°E
|
||||
REM NOQUEUE [utctolocal('2065-12-27@08:40')] MSG Partial Solar Eclipse centered at 65.4°S 149.2°W
|
||||
REM NOQUEUE [utctolocal('2066-06-22@19:26')] MSG Annular Solar Eclipse centered at 70.1°N 96.4°W
|
||||
REM NOQUEUE [utctolocal('2066-12-17@00:24')] MSG Total Solar Eclipse centered at 47.4°S 175.8°E
|
||||
REM NOQUEUE [utctolocal('2067-06-11@20:42')] MSG Annular Solar Eclipse centered at 21.0°N 130.2°W
|
||||
REM NOQUEUE [utctolocal('2067-12-06@14:04')] MSG Hybrid Solar Eclipse centered at 6.0°S 32.4°W
|
||||
REM NOQUEUE [utctolocal('2068-05-31@03:57')] MSG Total Solar Eclipse centered at 31.0°S 123.2°E
|
||||
REM NOQUEUE [utctolocal('2068-11-24@21:32')] MSG Partial Solar Eclipse centered at 68.5°N 131.1°W
|
||||
REM NOQUEUE [utctolocal('2069-04-21@10:11')] MSG Partial Solar Eclipse centered at 71.0°N 101.3°W
|
||||
REM NOQUEUE [utctolocal('2069-05-20@17:53')] MSG Partial Solar Eclipse centered at 68.8°S 69.9°W
|
||||
REM NOQUEUE [utctolocal('2069-10-15@04:20')] MSG Partial Solar Eclipse centered at 71.6°S 5.5°W
|
||||
REM NOQUEUE [utctolocal('2070-04-11@02:36')] MSG Total Solar Eclipse centered at 29.1°N 135.1°E
|
||||
REM NOQUEUE [utctolocal('2070-10-04@07:09')] MSG Annular Solar Eclipse centered at 32.8°S 60.4°E
|
||||
REM NOQUEUE [utctolocal('2071-03-31@15:01')] MSG Annular Solar Eclipse centered at 16.7°S 37.0°W
|
||||
REM NOQUEUE [utctolocal('2071-09-23@17:20')] MSG Total Solar Eclipse centered at 14.2°N 76.7°W
|
||||
REM NOQUEUE [utctolocal('2072-03-19@20:11')] MSG Partial Solar Eclipse centered at 72.2°S 30.4°W
|
||||
REM NOQUEUE [utctolocal('2072-09-12@08:59')] MSG Total Solar Eclipse centered at 69.8°N 102.0°E
|
||||
REM NOQUEUE [utctolocal('2073-02-07@01:56')] MSG Partial Solar Eclipse centered at 70.5°N 114.9°E
|
||||
REM NOQUEUE [utctolocal('2073-08-03@17:15')] MSG Total Solar Eclipse centered at 43.2°S 89.4°W
|
||||
REM NOQUEUE [utctolocal('2074-01-27@06:44')] MSG Annular Solar Eclipse centered at 6.6°N 78.8°E
|
||||
REM NOQUEUE [utctolocal('2074-07-24@03:11')] MSG Annular Solar Eclipse centered at 12.8°N 133.7°E
|
||||
REM NOQUEUE [utctolocal('2075-01-16@18:36')] MSG Total Solar Eclipse centered at 37.2°S 94.1°W
|
||||
REM NOQUEUE [utctolocal('2075-07-13@06:06')] MSG Annular Solar Eclipse centered at 63.1°N 95.2°E
|
||||
REM NOQUEUE [utctolocal('2076-01-06@10:07')] MSG Total Solar Eclipse centered at 87.2°S 173.7°W
|
||||
REM NOQUEUE [utctolocal('2076-06-01@17:31')] MSG Partial Solar Eclipse centered at 64.4°S 51.2°W
|
||||
REM NOQUEUE [utctolocal('2076-07-01@06:51')] MSG Partial Solar Eclipse centered at 67.0°N 98.1°W
|
||||
REM NOQUEUE [utctolocal('2076-11-26@11:43')] MSG Partial Solar Eclipse centered at 63.7°N 40.1°E
|
||||
REM NOQUEUE [utctolocal('2077-05-22@02:46')] MSG Total Solar Eclipse centered at 13.1°S 148.3°E
|
||||
REM NOQUEUE [utctolocal('2077-11-15@17:08')] MSG Annular Solar Eclipse centered at 7.8°N 70.8°W
|
||||
REM NOQUEUE [utctolocal('2078-05-11@17:57')] MSG Total Solar Eclipse centered at 28.1°N 93.7°W
|
||||
REM NOQUEUE [utctolocal('2078-11-04@16:56')] MSG Annular Solar Eclipse centered at 27.8°S 83.3°W
|
||||
REM NOQUEUE [utctolocal('2079-05-01@10:50')] MSG Total Solar Eclipse centered at 66.2°N 46.3°W
|
||||
REM NOQUEUE [utctolocal('2079-10-24@18:11')] MSG Annular Solar Eclipse centered at 63.4°S 160.6°W
|
||||
REM NOQUEUE [utctolocal('2080-03-21@12:20')] MSG Partial Solar Eclipse centered at 60.9°S 85.9°E
|
||||
REM NOQUEUE [utctolocal('2080-09-13@16:38')] MSG Partial Solar Eclipse centered at 61.1°N 25.8°E
|
||||
REM NOQUEUE [utctolocal('2081-03-10@15:24')] MSG Annular Solar Eclipse centered at 22.4°S 36.7°W
|
||||
REM NOQUEUE [utctolocal('2081-09-03@09:08')] MSG Total Solar Eclipse centered at 24.6°N 53.6°E
|
||||
REM NOQUEUE [utctolocal('2082-02-27@14:47')] MSG Annular Solar Eclipse centered at 9.4°N 47.1°W
|
||||
REM NOQUEUE [utctolocal('2082-08-24@01:16')] MSG Total Solar Eclipse centered at 10.3°S 151.8°E
|
||||
REM NOQUEUE [utctolocal('2083-02-16@18:07')] MSG Partial Solar Eclipse centered at 61.6°N 154.1°W
|
||||
REM NOQUEUE [utctolocal('2083-07-15@00:14')] MSG Partial Solar Eclipse centered at 64.0°N 37.7°W
|
||||
REM NOQUEUE [utctolocal('2083-08-13@12:35')] MSG Partial Solar Eclipse centered at 62.1°S 67.5°W
|
||||
REM NOQUEUE [utctolocal('2084-01-07@17:30')] MSG Partial Solar Eclipse centered at 64.4°S 68.5°E
|
||||
REM NOQUEUE [utctolocal('2084-07-03@01:50')] MSG Annular Solar Eclipse centered at 75.0°N 169.1°W
|
||||
REM NOQUEUE [utctolocal('2084-12-27@09:14')] MSG Total Solar Eclipse centered at 47.3°S 47.7°E
|
||||
REM NOQUEUE [utctolocal('2085-06-22@03:21')] MSG Annular Solar Eclipse centered at 26.2°N 131.3°E
|
||||
REM NOQUEUE [utctolocal('2085-12-16@22:38')] MSG Annular Solar Eclipse centered at 7.3°S 160.8°W
|
||||
REM NOQUEUE [utctolocal('2086-06-11@11:07')] MSG Total Solar Eclipse centered at 23.2°S 12.5°E
|
||||
REM NOQUEUE [utctolocal('2086-12-06@05:39')] MSG Partial Solar Eclipse centered at 67.4°N 96.2°E
|
||||
REM NOQUEUE [utctolocal('2087-05-02@18:05')] MSG Partial Solar Eclipse centered at 70.3°N 127.6°E
|
||||
REM NOQUEUE [utctolocal('2087-06-01@01:27')] MSG Partial Solar Eclipse centered at 67.8°S 165.4°E
|
||||
REM NOQUEUE [utctolocal('2087-10-26@11:47')] MSG Partial Solar Eclipse centered at 71.0°S 130.5°W
|
||||
REM NOQUEUE [utctolocal('2088-04-21@10:32')] MSG Total Solar Eclipse centered at 36.0°N 15.1°E
|
||||
REM NOQUEUE [utctolocal('2088-10-14@14:48')] MSG Annular Solar Eclipse centered at 39.7°S 56.0°W
|
||||
REM NOQUEUE [utctolocal('2089-04-10@22:45')] MSG Annular Solar Eclipse centered at 10.2°S 154.8°W
|
||||
REM NOQUEUE [utctolocal('2089-10-04@01:15')] MSG Total Solar Eclipse centered at 7.4°N 162.8°E
|
||||
REM NOQUEUE [utctolocal('2090-03-31@03:38')] MSG Partial Solar Eclipse centered at 72.1°S 156.3°W
|
||||
REM NOQUEUE [utctolocal('2090-09-23@16:57')] MSG Total Solar Eclipse centered at 60.7°N 40.5°W
|
||||
REM NOQUEUE [utctolocal('2091-02-18@09:55')] MSG Partial Solar Eclipse centered at 71.2°N 17.8°W
|
||||
REM NOQUEUE [utctolocal('2091-08-15@00:35')] MSG Total Solar Eclipse centered at 55.6°S 150.5°E
|
||||
REM NOQUEUE [utctolocal('2092-02-07@15:10')] MSG Annular Solar Eclipse centered at 9.9°N 48.7°W
|
||||
REM NOQUEUE [utctolocal('2092-08-03@10:00')] MSG Annular Solar Eclipse centered at 5.6°N 30.3°E
|
||||
REM NOQUEUE [utctolocal('2093-01-27@03:22')] MSG Total Solar Eclipse centered at 34.1°S 136.4°E
|
||||
REM NOQUEUE [utctolocal('2093-07-23@12:32')] MSG Annular Solar Eclipse centered at 54.6°N 1.3°E
|
||||
REM NOQUEUE [utctolocal('2094-01-16@18:59')] MSG Total Solar Eclipse centered at 84.8°S 10.6°W
|
||||
REM NOQUEUE [utctolocal('2094-06-13@00:22')] MSG Partial Solar Eclipse centered at 65.3°S 163.6°W
|
||||
REM NOQUEUE [utctolocal('2094-07-12@13:25')] MSG Partial Solar Eclipse centered at 68.0°N 152.8°E
|
||||
REM NOQUEUE [utctolocal('2094-12-07@20:06')] MSG Partial Solar Eclipse centered at 64.7°N 95.0°W
|
||||
REM NOQUEUE [utctolocal('2095-06-02@10:08')] MSG Total Solar Eclipse centered at 16.7°S 37.2°E
|
||||
REM NOQUEUE [utctolocal('2095-11-27@01:03')] MSG Annular Solar Eclipse centered at 7.2°N 169.8°E
|
||||
REM NOQUEUE [utctolocal('2096-05-22@01:37')] MSG Total Solar Eclipse centered at 27.3°N 153.4°E
|
||||
REM NOQUEUE [utctolocal('2096-11-15@00:36')] MSG Annular Solar Eclipse centered at 29.7°S 163.3°E
|
||||
REM NOQUEUE [utctolocal('2097-05-11@18:35')] MSG Total Solar Eclipse centered at 67.4°N 149.5°W
|
||||
REM NOQUEUE [utctolocal('2097-11-04@02:01')] MSG Annular Solar Eclipse centered at 65.8°S 86.8°E
|
||||
REM NOQUEUE [utctolocal('2098-04-01@20:03')] MSG Partial Solar Eclipse centered at 61.0°S 38.1°W
|
||||
REM NOQUEUE [utctolocal('2098-09-25@00:31')] MSG Partial Solar Eclipse centered at 61.1°N 101.0°W
|
||||
REM NOQUEUE [utctolocal('2098-10-24@10:36')] MSG Partial Solar Eclipse centered at 61.8°S 95.5°W
|
||||
REM NOQUEUE [utctolocal('2099-03-21@22:55')] MSG Annular Solar Eclipse centered at 20.0°S 149.0°W
|
||||
REM NOQUEUE [utctolocal('2099-09-14@16:58')] MSG Total Solar Eclipse centered at 23.4°N 62.8°W
|
||||
REM NOQUEUE [utctolocal('2100-03-10@22:28')] MSG Annular Solar Eclipse centered at 12.0°N 162.4°W
|
||||
REM NOQUEUE [utctolocal('2100-09-04@08:49')] MSG Total Solar Eclipse centered at 10.5°S 39.0°E
|
||||
ENDIF
|
||||
REM NOQUEUE [utctolocal('2038-01-05@13:47')] MSG Annular Solar Eclipse centered at 2.1°N 25.4°W
|
||||
REM NOQUEUE [utctolocal('2038-07-02@13:33')] MSG Annular Solar Eclipse centered at 25.4°N 21.9°W
|
||||
REM NOQUEUE [utctolocal('2038-12-26@01:00')] MSG Total Solar Eclipse centered at 40.3°S 164.0°E
|
||||
REM NOQUEUE [utctolocal('2039-06-21@17:13')] MSG Annular Solar Eclipse centered at 78.9°N 102.1°W
|
||||
REM NOQUEUE [utctolocal('2039-12-15@16:24')] MSG Total Solar Eclipse centered at 80.9°S 172.8°E
|
||||
REM NOQUEUE [utctolocal('2040-05-11@03:43')] MSG Partial Solar Eclipse centered at 62.8°S 174.4°E
|
||||
REM NOQUEUE [utctolocal('2040-11-04@19:09')] MSG Partial Solar Eclipse centered at 62.2°N 53.4°W
|
||||
REM NOQUEUE [utctolocal('2041-04-30@11:52')] MSG Total Solar Eclipse centered at 9.6°S 12.2°E
|
||||
REM NOQUEUE [utctolocal('2041-10-25@01:36')] MSG Annular Solar Eclipse centered at 9.9°N 162.9°E
|
||||
REM NOQUEUE [utctolocal('2042-04-20@02:17')] MSG Total Solar Eclipse centered at 27.0°N 137.3°E
|
||||
REM NOQUEUE [utctolocal('2042-10-14@02:01')] MSG Annular Solar Eclipse centered at 23.7°S 137.8°E
|
||||
REM NOQUEUE [utctolocal('2043-04-09@18:58')] MSG Total (non-central) Solar Eclipse centered at 61.3°N 152.0°E
|
||||
REM NOQUEUE [utctolocal('2043-10-03@03:02')] MSG Annular (non-central) Solar Eclipse centered at 61.0°S 35.3°E
|
||||
REM NOQUEUE [utctolocal('2044-02-28@20:25')] MSG Annular Solar Eclipse centered at 62.2°S 25.6°W
|
||||
REM NOQUEUE [utctolocal('2044-08-23@01:17')] MSG Total Solar Eclipse centered at 64.3°N 120.4°W
|
||||
REM NOQUEUE [utctolocal('2045-02-16@23:56')] MSG Annular Solar Eclipse centered at 28.3°S 166.2°W
|
||||
REM NOQUEUE [utctolocal('2045-08-12@17:43')] MSG Total Solar Eclipse centered at 25.9°N 78.5°W
|
||||
REM NOQUEUE [utctolocal('2046-02-05@23:06')] MSG Annular Solar Eclipse centered at 4.8°N 171.4°W
|
||||
REM NOQUEUE [utctolocal('2046-08-02@10:21')] MSG Total Solar Eclipse centered at 12.7°S 15.2°E
|
||||
REM NOQUEUE [utctolocal('2047-01-26@01:33')] MSG Partial Solar Eclipse centered at 62.9°N 111.7°E
|
||||
REM NOQUEUE [utctolocal('2047-06-23@10:53')] MSG Partial Solar Eclipse centered at 65.8°N 178.0°W
|
||||
REM NOQUEUE [utctolocal('2047-07-22@22:36')] MSG Partial Solar Eclipse centered at 63.4°S 160.2°E
|
||||
REM NOQUEUE [utctolocal('2047-12-16@23:50')] MSG Partial Solar Eclipse centered at 66.4°S 6.6°W
|
||||
REM NOQUEUE [utctolocal('2048-06-11@12:59')] MSG Annular Solar Eclipse centered at 63.7°N 11.5°W
|
||||
REM NOQUEUE [utctolocal('2048-12-05@15:35')] MSG Total Solar Eclipse centered at 46.1°S 56.4°W
|
||||
REM NOQUEUE [utctolocal('2049-05-31@14:00')] MSG Annular Solar Eclipse centered at 15.3°N 29.9°W
|
||||
REM NOQUEUE [utctolocal('2049-11-25@05:34')] MSG Hybrid Solar Eclipse centered at 3.8°S 95.2°E
|
||||
REM NOQUEUE [utctolocal('2050-05-20@20:43')] MSG Hybrid Solar Eclipse centered at 40.1°S 123.7°W
|
||||
REM NOQUEUE [utctolocal('2050-11-14@13:31')] MSG Partial Solar Eclipse centered at 69.5°N 1.0°E
|
||||
REM NOQUEUE [utctolocal('2051-04-11@02:11')] MSG Partial Solar Eclipse centered at 71.6°N 32.2°E
|
||||
REM NOQUEUE [utctolocal('2051-10-04@21:02')] MSG Partial Solar Eclipse centered at 72.0°S 117.7°E
|
||||
REM NOQUEUE [utctolocal('2052-03-30@18:32')] MSG Total Solar Eclipse centered at 22.4°N 102.5°W
|
||||
REM NOQUEUE [utctolocal('2052-09-22@23:39')] MSG Annular Solar Eclipse centered at 25.7°S 175.0°E
|
||||
REM NOQUEUE [utctolocal('2053-03-20@07:08')] MSG Annular Solar Eclipse centered at 23.0°S 83.0°E
|
||||
REM NOQUEUE [utctolocal('2053-09-12@09:34')] MSG Total Solar Eclipse centered at 21.5°N 41.7°E
|
||||
REM NOQUEUE [utctolocal('2054-03-09@12:34')] MSG Partial Solar Eclipse centered at 72.0°S 97.9°E
|
||||
REM NOQUEUE [utctolocal('2054-08-03@18:04')] MSG Partial Solar Eclipse centered at 69.8°S 121.3°W
|
||||
REM NOQUEUE [utctolocal('2054-09-02@01:10')] MSG Partial Solar Eclipse centered at 71.7°N 82.3°W
|
||||
REM NOQUEUE [utctolocal('2055-01-27@17:54')] MSG Partial Solar Eclipse centered at 69.5°N 112.2°W
|
||||
REM NOQUEUE [utctolocal('2055-07-24@09:58')] MSG Total Solar Eclipse centered at 33.3°S 25.8°E
|
||||
REM NOQUEUE [utctolocal('2056-01-16@22:17')] MSG Annular Solar Eclipse centered at 3.9°N 153.5°W
|
||||
REM NOQUEUE [utctolocal('2056-07-12@20:22')] MSG Annular Solar Eclipse centered at 19.4°N 123.7°W
|
||||
REM NOQUEUE [utctolocal('2057-01-05@09:48')] MSG Total Solar Eclipse centered at 39.2°S 35.2°E
|
||||
REM NOQUEUE [utctolocal('2057-07-01@23:40')] MSG Annular Solar Eclipse centered at 71.5°N 176.2°W
|
||||
REM NOQUEUE [utctolocal('2057-12-26@01:15')] MSG Total Solar Eclipse centered at 84.9°S 21.8°E
|
||||
REM NOQUEUE [utctolocal('2058-05-22@10:39')] MSG Partial Solar Eclipse centered at 63.5°S 61.1°E
|
||||
REM NOQUEUE [utctolocal('2058-06-21@00:20')] MSG Partial Solar Eclipse centered at 65.9°N 9.9°E
|
||||
REM NOQUEUE [utctolocal('2058-11-16@03:23')] MSG Partial Solar Eclipse centered at 62.9°N 174.2°E
|
||||
REM NOQUEUE [utctolocal('2059-05-11@19:22')] MSG Total Solar Eclipse centered at 10.7°S 100.4°W
|
||||
REM NOQUEUE [utctolocal('2059-11-05@09:18')] MSG Annular Solar Eclipse centered at 8.7°N 47.1°E
|
||||
REM NOQUEUE [utctolocal('2060-04-30@10:10')] MSG Total Solar Eclipse centered at 28.0°N 20.9°E
|
||||
REM NOQUEUE [utctolocal('2060-10-24@09:24')] MSG Annular Solar Eclipse centered at 25.8°S 28.1°E
|
||||
REM NOQUEUE [utctolocal('2061-04-20@02:57')] MSG Total Solar Eclipse centered at 64.5°N 59.2°E
|
||||
REM NOQUEUE [utctolocal('2061-10-13@10:32')] MSG Annular Solar Eclipse centered at 62.1°S 54.4°W
|
||||
REM NOQUEUE [utctolocal('2062-03-11@04:26')] MSG Partial Solar Eclipse centered at 61.0°S 147.1°W
|
||||
REM NOQUEUE [utctolocal('2062-09-03@08:54')] MSG Partial Solar Eclipse centered at 61.3°N 150.3°E
|
||||
REM NOQUEUE [utctolocal('2063-02-28@07:43')] MSG Annular Solar Eclipse centered at 25.2°S 77.7°E
|
||||
REM NOQUEUE [utctolocal('2063-08-24@01:22')] MSG Total Solar Eclipse centered at 25.6°N 168.4°E
|
||||
REM NOQUEUE [utctolocal('2064-02-17@07:00')] MSG Annular Solar Eclipse centered at 7.0°N 69.7°E
|
||||
REM NOQUEUE [utctolocal('2064-08-12@17:46')] MSG Total Solar Eclipse centered at 10.9°S 96.0°W
|
||||
REM NOQUEUE [utctolocal('2065-02-05@09:52')] MSG Partial Solar Eclipse centered at 62.2°N 21.9°W
|
||||
REM NOQUEUE [utctolocal('2065-07-03@17:34')] MSG Partial Solar Eclipse centered at 64.8°N 71.9°E
|
||||
REM NOQUEUE [utctolocal('2065-08-02@05:34')] MSG Partial Solar Eclipse centered at 62.7°S 46.5°E
|
||||
REM NOQUEUE [utctolocal('2065-12-27@08:40')] MSG Partial Solar Eclipse centered at 65.4°S 149.2°W
|
||||
REM NOQUEUE [utctolocal('2066-06-22@19:26')] MSG Annular Solar Eclipse centered at 70.1°N 96.4°W
|
||||
REM NOQUEUE [utctolocal('2066-12-17@00:24')] MSG Total Solar Eclipse centered at 47.4°S 175.8°E
|
||||
REM NOQUEUE [utctolocal('2067-06-11@20:42')] MSG Annular Solar Eclipse centered at 21.0°N 130.2°W
|
||||
REM NOQUEUE [utctolocal('2067-12-06@14:04')] MSG Hybrid Solar Eclipse centered at 6.0°S 32.4°W
|
||||
REM NOQUEUE [utctolocal('2068-05-31@03:57')] MSG Total Solar Eclipse centered at 31.0°S 123.2°E
|
||||
REM NOQUEUE [utctolocal('2068-11-24@21:32')] MSG Partial Solar Eclipse centered at 68.5°N 131.1°W
|
||||
REM NOQUEUE [utctolocal('2069-04-21@10:11')] MSG Partial Solar Eclipse centered at 71.0°N 101.3°W
|
||||
REM NOQUEUE [utctolocal('2069-05-20@17:53')] MSG Partial Solar Eclipse centered at 68.8°S 69.9°W
|
||||
REM NOQUEUE [utctolocal('2069-10-15@04:20')] MSG Partial Solar Eclipse centered at 71.6°S 5.5°W
|
||||
REM NOQUEUE [utctolocal('2070-04-11@02:36')] MSG Total Solar Eclipse centered at 29.1°N 135.1°E
|
||||
REM NOQUEUE [utctolocal('2070-10-04@07:09')] MSG Annular Solar Eclipse centered at 32.8°S 60.4°E
|
||||
REM NOQUEUE [utctolocal('2071-03-31@15:01')] MSG Annular Solar Eclipse centered at 16.7°S 37.0°W
|
||||
REM NOQUEUE [utctolocal('2071-09-23@17:20')] MSG Total Solar Eclipse centered at 14.2°N 76.7°W
|
||||
REM NOQUEUE [utctolocal('2072-03-19@20:11')] MSG Partial Solar Eclipse centered at 72.2°S 30.4°W
|
||||
REM NOQUEUE [utctolocal('2072-09-12@08:59')] MSG Total Solar Eclipse centered at 69.8°N 102.0°E
|
||||
REM NOQUEUE [utctolocal('2073-02-07@01:56')] MSG Partial Solar Eclipse centered at 70.5°N 114.9°E
|
||||
REM NOQUEUE [utctolocal('2073-08-03@17:15')] MSG Total Solar Eclipse centered at 43.2°S 89.4°W
|
||||
REM NOQUEUE [utctolocal('2074-01-27@06:44')] MSG Annular Solar Eclipse centered at 6.6°N 78.8°E
|
||||
REM NOQUEUE [utctolocal('2074-07-24@03:11')] MSG Annular Solar Eclipse centered at 12.8°N 133.7°E
|
||||
REM NOQUEUE [utctolocal('2075-01-16@18:36')] MSG Total Solar Eclipse centered at 37.2°S 94.1°W
|
||||
REM NOQUEUE [utctolocal('2075-07-13@06:06')] MSG Annular Solar Eclipse centered at 63.1°N 95.2°E
|
||||
REM NOQUEUE [utctolocal('2076-01-06@10:07')] MSG Total Solar Eclipse centered at 87.2°S 173.7°W
|
||||
REM NOQUEUE [utctolocal('2076-06-01@17:31')] MSG Partial Solar Eclipse centered at 64.4°S 51.2°W
|
||||
REM NOQUEUE [utctolocal('2076-07-01@06:51')] MSG Partial Solar Eclipse centered at 67.0°N 98.1°W
|
||||
REM NOQUEUE [utctolocal('2076-11-26@11:43')] MSG Partial Solar Eclipse centered at 63.7°N 40.1°E
|
||||
REM NOQUEUE [utctolocal('2077-05-22@02:46')] MSG Total Solar Eclipse centered at 13.1°S 148.3°E
|
||||
REM NOQUEUE [utctolocal('2077-11-15@17:08')] MSG Annular Solar Eclipse centered at 7.8°N 70.8°W
|
||||
REM NOQUEUE [utctolocal('2078-05-11@17:57')] MSG Total Solar Eclipse centered at 28.1°N 93.7°W
|
||||
REM NOQUEUE [utctolocal('2078-11-04@16:56')] MSG Annular Solar Eclipse centered at 27.8°S 83.3°W
|
||||
REM NOQUEUE [utctolocal('2079-05-01@10:50')] MSG Total Solar Eclipse centered at 66.2°N 46.3°W
|
||||
REM NOQUEUE [utctolocal('2079-10-24@18:11')] MSG Annular Solar Eclipse centered at 63.4°S 160.6°W
|
||||
REM NOQUEUE [utctolocal('2080-03-21@12:20')] MSG Partial Solar Eclipse centered at 60.9°S 85.9°E
|
||||
REM NOQUEUE [utctolocal('2080-09-13@16:38')] MSG Partial Solar Eclipse centered at 61.1°N 25.8°E
|
||||
REM NOQUEUE [utctolocal('2081-03-10@15:24')] MSG Annular Solar Eclipse centered at 22.4°S 36.7°W
|
||||
REM NOQUEUE [utctolocal('2081-09-03@09:08')] MSG Total Solar Eclipse centered at 24.6°N 53.6°E
|
||||
REM NOQUEUE [utctolocal('2082-02-27@14:47')] MSG Annular Solar Eclipse centered at 9.4°N 47.1°W
|
||||
REM NOQUEUE [utctolocal('2082-08-24@01:16')] MSG Total Solar Eclipse centered at 10.3°S 151.8°E
|
||||
REM NOQUEUE [utctolocal('2083-02-16@18:07')] MSG Partial Solar Eclipse centered at 61.6°N 154.1°W
|
||||
REM NOQUEUE [utctolocal('2083-07-15@00:14')] MSG Partial Solar Eclipse centered at 64.0°N 37.7°W
|
||||
REM NOQUEUE [utctolocal('2083-08-13@12:35')] MSG Partial Solar Eclipse centered at 62.1°S 67.5°W
|
||||
REM NOQUEUE [utctolocal('2084-01-07@17:30')] MSG Partial Solar Eclipse centered at 64.4°S 68.5°E
|
||||
REM NOQUEUE [utctolocal('2084-07-03@01:50')] MSG Annular Solar Eclipse centered at 75.0°N 169.1°W
|
||||
REM NOQUEUE [utctolocal('2084-12-27@09:14')] MSG Total Solar Eclipse centered at 47.3°S 47.7°E
|
||||
REM NOQUEUE [utctolocal('2085-06-22@03:21')] MSG Annular Solar Eclipse centered at 26.2°N 131.3°E
|
||||
REM NOQUEUE [utctolocal('2085-12-16@22:38')] MSG Annular Solar Eclipse centered at 7.3°S 160.8°W
|
||||
REM NOQUEUE [utctolocal('2086-06-11@11:07')] MSG Total Solar Eclipse centered at 23.2°S 12.5°E
|
||||
REM NOQUEUE [utctolocal('2086-12-06@05:39')] MSG Partial Solar Eclipse centered at 67.4°N 96.2°E
|
||||
REM NOQUEUE [utctolocal('2087-05-02@18:05')] MSG Partial Solar Eclipse centered at 70.3°N 127.6°E
|
||||
REM NOQUEUE [utctolocal('2087-06-01@01:27')] MSG Partial Solar Eclipse centered at 67.8°S 165.4°E
|
||||
REM NOQUEUE [utctolocal('2087-10-26@11:47')] MSG Partial Solar Eclipse centered at 71.0°S 130.5°W
|
||||
REM NOQUEUE [utctolocal('2088-04-21@10:32')] MSG Total Solar Eclipse centered at 36.0°N 15.1°E
|
||||
REM NOQUEUE [utctolocal('2088-10-14@14:48')] MSG Annular Solar Eclipse centered at 39.7°S 56.0°W
|
||||
REM NOQUEUE [utctolocal('2089-04-10@22:45')] MSG Annular Solar Eclipse centered at 10.2°S 154.8°W
|
||||
REM NOQUEUE [utctolocal('2089-10-04@01:15')] MSG Total Solar Eclipse centered at 7.4°N 162.8°E
|
||||
REM NOQUEUE [utctolocal('2090-03-31@03:38')] MSG Partial Solar Eclipse centered at 72.1°S 156.3°W
|
||||
REM NOQUEUE [utctolocal('2090-09-23@16:57')] MSG Total Solar Eclipse centered at 60.7°N 40.5°W
|
||||
REM NOQUEUE [utctolocal('2091-02-18@09:55')] MSG Partial Solar Eclipse centered at 71.2°N 17.8°W
|
||||
REM NOQUEUE [utctolocal('2091-08-15@00:35')] MSG Total Solar Eclipse centered at 55.6°S 150.5°E
|
||||
REM NOQUEUE [utctolocal('2092-02-07@15:10')] MSG Annular Solar Eclipse centered at 9.9°N 48.7°W
|
||||
REM NOQUEUE [utctolocal('2092-08-03@10:00')] MSG Annular Solar Eclipse centered at 5.6°N 30.3°E
|
||||
REM NOQUEUE [utctolocal('2093-01-27@03:22')] MSG Total Solar Eclipse centered at 34.1°S 136.4°E
|
||||
REM NOQUEUE [utctolocal('2093-07-23@12:32')] MSG Annular Solar Eclipse centered at 54.6°N 1.3°E
|
||||
REM NOQUEUE [utctolocal('2094-01-16@18:59')] MSG Total Solar Eclipse centered at 84.8°S 10.6°W
|
||||
REM NOQUEUE [utctolocal('2094-06-13@00:22')] MSG Partial Solar Eclipse centered at 65.3°S 163.6°W
|
||||
REM NOQUEUE [utctolocal('2094-07-12@13:25')] MSG Partial Solar Eclipse centered at 68.0°N 152.8°E
|
||||
REM NOQUEUE [utctolocal('2094-12-07@20:06')] MSG Partial Solar Eclipse centered at 64.7°N 95.0°W
|
||||
REM NOQUEUE [utctolocal('2095-06-02@10:08')] MSG Total Solar Eclipse centered at 16.7°S 37.2°E
|
||||
REM NOQUEUE [utctolocal('2095-11-27@01:03')] MSG Annular Solar Eclipse centered at 7.2°N 169.8°E
|
||||
REM NOQUEUE [utctolocal('2096-05-22@01:37')] MSG Total Solar Eclipse centered at 27.3°N 153.4°E
|
||||
REM NOQUEUE [utctolocal('2096-11-15@00:36')] MSG Annular Solar Eclipse centered at 29.7°S 163.3°E
|
||||
REM NOQUEUE [utctolocal('2097-05-11@18:35')] MSG Total Solar Eclipse centered at 67.4°N 149.5°W
|
||||
REM NOQUEUE [utctolocal('2097-11-04@02:01')] MSG Annular Solar Eclipse centered at 65.8°S 86.8°E
|
||||
REM NOQUEUE [utctolocal('2098-04-01@20:03')] MSG Partial Solar Eclipse centered at 61.0°S 38.1°W
|
||||
REM NOQUEUE [utctolocal('2098-09-25@00:31')] MSG Partial Solar Eclipse centered at 61.1°N 101.0°W
|
||||
REM NOQUEUE [utctolocal('2098-10-24@10:36')] MSG Partial Solar Eclipse centered at 61.8°S 95.5°W
|
||||
REM NOQUEUE [utctolocal('2099-03-21@22:55')] MSG Annular Solar Eclipse centered at 20.0°S 149.0°W
|
||||
REM NOQUEUE [utctolocal('2099-09-14@16:58')] MSG Total Solar Eclipse centered at 23.4°N 62.8°W
|
||||
REM NOQUEUE [utctolocal('2100-03-10@22:28')] MSG Annular Solar Eclipse centered at 12.0°N 162.4°W
|
||||
REM NOQUEUE [utctolocal('2100-09-04@08:49')] MSG Total Solar Eclipse centered at 10.5°S 39.0°E
|
||||
|
||||
|
||||
5
include/utils/add-html-anchors.rem
Normal file
5
include/utils/add-html-anchors.rem
Normal file
@@ -0,0 +1,5 @@
|
||||
# Add HTML anchors to each day box.
|
||||
# This adds anchors: <a id="YYYY-MM-DD" name="YYYY-MM-DD"></a>
|
||||
# to each calendar box in an HTML calendar.
|
||||
|
||||
REM SPECIAL HTML <a id="[$T]" name="[$T]"></a>
|
||||
@@ -544,6 +544,7 @@ will produce the following \fBinfo\fR hash:
|
||||
"summary" : "None"
|
||||
},
|
||||
.fi
|
||||
.PP
|
||||
.RE
|
||||
.TP
|
||||
.B time \fIt\fR
|
||||
@@ -581,6 +582,11 @@ If the reminder contained a "delta" clause (+n or ++n), this key
|
||||
contains the delta value. If the "delta" value was +n, the value will
|
||||
be positive; if it was ++n, the value will be negative.
|
||||
.TP
|
||||
.B trigbase "\fIdate\fR"
|
||||
If the reminder included all of the day, month and year components, then
|
||||
\fBtrigbase\fR is the date made from those components, expressed in
|
||||
the format \fIYYYY-MM-DD\fR.
|
||||
.TP
|
||||
.B rep \fIn\fR
|
||||
If the reminder contained a "repeat" clause (*n), this key contains
|
||||
the repeat value.
|
||||
@@ -617,14 +623,27 @@ will be present. Its value will be a string of the form YYYY-MM-DD.
|
||||
If the reminder contains a ONCE keyword, this key will be present
|
||||
with a value of 1.
|
||||
.TP
|
||||
.B scanfrom \fIYYYY-MM-DD\fR
|
||||
.B scanfrom \fIYYYY-MM-DD\fR or \fBscanfrom\fR \fI-n\fR
|
||||
If the reminder contains a SCANFROM keyword, this key will be present
|
||||
and its value will be a string of the form YYYY-MM-DD.
|
||||
and its value will be a string of the form YYYY-MM-DD for an absolute
|
||||
SCANFROM, or a negative integer of the form -n for a relative scanfrom
|
||||
.TP
|
||||
.B from \fIYYYY-MM-DD\fR
|
||||
If the reminder contains a FROM keyword, this key will be present
|
||||
and its value will be a string of the form YYYY-MM-DD.
|
||||
.TP
|
||||
.B is_todo \fIflag\fR
|
||||
If the reminder is a TODO reminder, then \fIflag\fR will be the integer
|
||||
1. Otherwise, it will be the integer zero.
|
||||
.TP
|
||||
.B complete_through \fIYYYY-MM-DD\fR
|
||||
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.
|
||||
@@ -666,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
|
||||
|
||||
901
man/remind.1.in
901
man/remind.1.in
File diff suppressed because it is too large
Load Diff
@@ -20,18 +20,16 @@ or the tkpng extension to handle PNG images.
|
||||
|
||||
.SH COMMAND-LINE OPTIONS
|
||||
\fBTkRemind\fR itself has no command-line options. However, it passes
|
||||
certain options on to \fBRemind\fR. The options it passes are
|
||||
\fB\-b\fR, \fB\-g\fR, \fB\-x\fR, \fB\-i\fR and \fB\-m\fR. See the
|
||||
\fBRemind\fR man page for details about the options. Note that
|
||||
\fBTkRemind\fR will respect the \fB\-m\fR and \fB\-b1\fR options and
|
||||
adjust its appearance accordingly.
|
||||
|
||||
any command-line argument starting with \fB\-\fR to \fBRemind\fR as an
|
||||
option. In addition, \fBTkRemind\fR will respect the \fB\-m\fR and
|
||||
\fB\-b1\fR options and adjust its appearance accordingly.
|
||||
.PP
|
||||
\fIRead_file\fR is the file from which \fBTkRemind\fR reads reminders.
|
||||
It is in standard \fBRemind\fR format. \fIWrite_file\fR is the file
|
||||
to which \fBTkRemind\fR writes reminders which you add using the GUI.
|
||||
If \fIRead_file\fR is omitted, it defaults to \fB$HOME/.reminders\fR.
|
||||
If \fIWrite_file\fR is omitted, it defaults to \fIRead_file\fR.
|
||||
|
||||
.PP
|
||||
You may wish to have a different \fIWrite_file\fR from \fIRead_file\fR if
|
||||
you want to collect all of \fBTkRemind\fR's reminders in one place. Suppose
|
||||
your main file is \fI$HOME/.reminders\fR and you want \fBTkRemind\fR to put
|
||||
@@ -96,10 +94,19 @@ The fourth control specifies which days \fBRemind\fR considers
|
||||
as part of the weekend. This can affect the interpretation of "weekday"
|
||||
in the second and third types of reminders.
|
||||
|
||||
The fifth control associates a time with the reminder.
|
||||
You can also specify advance notice, possibly repeating.
|
||||
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 specifies what \fBRemind\fR should do if a reminder
|
||||
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.
|
||||
|
||||
Enter the body of the reminder into the \fBSummary:\fR text entry. If
|
||||
@@ -121,6 +128,16 @@ edit the reminder, thereby gaining access to advanced features of
|
||||
\fBRemind\fR. You can also use it simply to play around and discover
|
||||
\fBRemind\fR's idioms for expressing different types of reminders.
|
||||
|
||||
.SH SEEING A SINGLE DAY'S REMINDERS
|
||||
Right-click on any day number in the calendar to pop up a window with
|
||||
that day's reminders in Agenda Mode. You can left- or right-click the
|
||||
current date and time indicator at the bottom of the window to see today's
|
||||
reminders in Agenda Mode.
|
||||
|
||||
In the Agenda Mode display, hovering over a reminder will show ancillary
|
||||
information such as a Location, URL or Description. Clicking on a reminder
|
||||
will open an editor on the REM command that created the reminder.
|
||||
|
||||
.SH PRINTING
|
||||
To print the current month's calendar, click \fBPrint...\fR on the
|
||||
main calendar window. This brings up the print dialog. Printing
|
||||
@@ -280,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.
|
||||
|
||||
@@ -4,7 +4,7 @@ REM2HTML
|
||||
rem2html is a Perl script that transforms the output of `remind -pp
|
||||
...' to HTML. Type `perl rem2html --help' for usage information.
|
||||
|
||||
rem2html requires the Perl modules `JSON::Any' and `Getopt::Long'. It
|
||||
rem2html requires the Perl modules `JSON::MaybeXS' and `Getopt::Long'. It
|
||||
will not be installed unless you have those modules as well as Perl
|
||||
itself.
|
||||
|
||||
|
||||
@@ -265,6 +265,7 @@ while(1) {
|
||||
}
|
||||
my ($obj, $err) = Remind::PDF->create_from_stream(*STDIN,
|
||||
{color => 1,
|
||||
colour => 1,
|
||||
shade => 1,
|
||||
moon => 1,
|
||||
pango => 1,
|
||||
|
||||
@@ -517,7 +517,7 @@ sub render
|
||||
}
|
||||
}
|
||||
|
||||
if ($so_far > $settings->{height} - $settings->{margin_bottom}) {
|
||||
if ($so_far > $settings->{height} - $settings->{margin_bottom} + 1) {
|
||||
print STDERR "WARNING: overfull calendar box\n";
|
||||
}
|
||||
# The vertical lines
|
||||
@@ -583,7 +583,7 @@ sub draw_row
|
||||
$self->draw_day($cr, $settings, $so_far, $day, $col, $height);
|
||||
}
|
||||
|
||||
return $so_far + $height + $settings->{border_size};
|
||||
return $so_far + $height + $settings->{border_size} * 2;
|
||||
}
|
||||
|
||||
=head2 col_box_coordinates($so_far, $col, $height, $settings)
|
||||
|
||||
@@ -158,11 +158,6 @@ if {[catch {package require json}]} {
|
||||
missing_tcllib json
|
||||
}
|
||||
|
||||
if {$tcl_platform(platform) == "windows"} {
|
||||
tk_messageBox -message "Please do not port Remind to Windows" -icon error -type ok
|
||||
exit 1
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# GetRemindVersion
|
||||
# Arguments:
|
||||
@@ -317,6 +312,8 @@ set TodayDay [string trim [clock format $now -format %e]]
|
||||
set CurMonth $TodayMonth
|
||||
set CurYear $TodayYear
|
||||
|
||||
set DateOfEventBeingEdited ""
|
||||
|
||||
# Reminder option types and skip types
|
||||
set OptionType 1
|
||||
set SkipType 1
|
||||
@@ -364,8 +361,8 @@ set HighestTagSoFar 0
|
||||
# Check Remind version
|
||||
set ver [GetRemindVersion]
|
||||
|
||||
if {"$ver" < "04.03.03"} {
|
||||
tk_messageBox -message "This version of TkRemind requires Remind version 04.03.03 or newer; you have version $ver" -icon error -type ok
|
||||
if {"$ver" < "06.00.00"} {
|
||||
tk_messageBox -message "This version of TkRemind requires Remind version 06.00.00 or newer; you have version $ver" -icon error -type ok
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -447,7 +444,10 @@ proc Initialize {} {
|
||||
if {"[lindex $argv $i]" == "-b1"} {
|
||||
set TwentyFourHourMode 1
|
||||
}
|
||||
} else {
|
||||
} elseif { [regexp -- {-.*} [lindex $argv $i]]} {
|
||||
append CommandLine " [lindex $argv $i]"
|
||||
append PSCmd " [lindex $argv $i]"
|
||||
} else {
|
||||
break
|
||||
}
|
||||
incr i
|
||||
@@ -583,7 +583,7 @@ proc CreateCalFrame { w dayNames } {
|
||||
text $w.t$f -width 12 -height $h -bd 0 -spacing3 3 -wrap word -relief flat \
|
||||
-state disabled -takefocus 0 -cursor {} -font CalboxFont -foreground $Option(TextColor) -background $Option(BackgroundColor) \
|
||||
-highlightthickness 0
|
||||
frame $w.f$f -padx 0 -pady 0 -highlightthickness 0 -relief flat -bd 0
|
||||
frame $w.f$f -padx 0 -pady 0 -highlightthickness 0 -relief flat -bd 0 -background $Option(BackgroundColor)
|
||||
$w.t$f tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$f"
|
||||
$w.t$f tag bind REM <ButtonPress-2> "OpenUrl $w.t$f"
|
||||
$w.t$f tag bind REM <ButtonPress-3> "FireEditor $w.t$f"
|
||||
@@ -650,7 +650,8 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
raise $w.t$i
|
||||
set d [expr $i-$first+1]
|
||||
$w.l$i configure -text $d -state normal -relief flat \
|
||||
-command "ModifyDay $d $firstDay" -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
-command "ModifyDay $d $firstDay" -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
bind $w.l$i <ButtonPress-3> [list ShowSpecificDayReminders $d]
|
||||
balloon_add_help $w.l$i "Add a reminder..."
|
||||
$w.t$i configure -relief sunken -takefocus 1 -state normal -foreground $Option(TextColor) -background $Option(BackgroundColor)
|
||||
$w.t$i delete 1.0 end
|
||||
@@ -753,7 +754,13 @@ proc CreateCalWindow { dayNames } {
|
||||
button .b.quit -text {Quit} -command {Quit} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
balloon_add_help .b.quit "Quit TkRemind"
|
||||
label .b.status -text "" -width 25 -relief flat -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
|
||||
bind .b.status <ButtonPress-1> [list ShowTodaysReminders 1 ""]
|
||||
bind .b.status <ButtonPress-3> [list ShowTodaysReminders 1 ""]
|
||||
balloon_add_help .b.status "Show Today's Reminders"
|
||||
label .b.nqueued -text "" -width 20 -relief flat -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
|
||||
balloon_add_help .b.nqueued "See the queue of pending reminders (debugging purposes only)"
|
||||
bind .b.nqueued <ButtonPress-1> [list DoQueue]
|
||||
bind .b.nqueued <ButtonPress-3> [list DoQueue]
|
||||
pack .b.prev .b.this .b.next .b.goto .b.print .b.options .b.queue .b.quit -side left -fill both -padx 1
|
||||
pack .b.status -side left -fill both -expand 1 -padx 1
|
||||
pack .b.nqueued -side left -fill both -padx 1
|
||||
@@ -968,6 +975,7 @@ proc CancelOptions { } {
|
||||
global Option
|
||||
font configure CalboxFont {*}$Option(CalboxFont)
|
||||
font configure HeadingFont {*}$Option(HeadingFont)
|
||||
font configure BoldFont {*}$Option(HeadingFont) -weight bold
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
@@ -1025,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)
|
||||
@@ -1039,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)
|
||||
}
|
||||
@@ -1105,6 +1113,7 @@ proc LoadOptions {} {
|
||||
}
|
||||
font configure CalboxFont {*}$Option(CalboxFont)
|
||||
font configure HeadingFont {*}$Option(HeadingFont)
|
||||
font configure BoldFont {*}$Option(HeadingFont) -weight bold
|
||||
}
|
||||
|
||||
|
||||
@@ -1180,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
|
||||
}
|
||||
|
||||
@@ -1376,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
|
||||
@@ -1694,6 +1703,39 @@ proc Quit {} {
|
||||
}
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# ShowSpecificDayReminders - show reminders for a specific day
|
||||
# Arguments:
|
||||
# d - day whose reminders should be shown
|
||||
#---------------------------------------------------------------------------
|
||||
proc ShowSpecificDayReminders { d } {
|
||||
global CurYear CurMonth
|
||||
set date [format "%04d-%02d-%02d" $CurYear [expr 1 + $CurMonth] $d]
|
||||
ShowTodaysReminders 1 $date
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
proc complete_through_today { w } {
|
||||
global DateOfEventBeingEdited
|
||||
$w.complete_through delete 0 end
|
||||
if {"$DateOfEventBeingEdited" != ""} {
|
||||
$w.complete_through insert end $DateOfEventBeingEdited
|
||||
} else {
|
||||
$w.complete_through insert end [clock format [clock seconds] -format %Y-%m-%d]
|
||||
}
|
||||
return -code break
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# CreateModifyDialog -- create dialog for adding a reminder
|
||||
# Arguments:
|
||||
@@ -1707,7 +1749,9 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
|
||||
# Set up: Year, Month, Day, WeekdayName
|
||||
global CurYear CurMonth EnglishDayNames MonthNames OptionType SkipType
|
||||
global ModifyDialogResult TwentyFourHourMode
|
||||
global ModifyDialogResult TwentyFourHourMode DateOfEventBeingEdited
|
||||
|
||||
set DateOfEventBeingEdited ""
|
||||
|
||||
set OptionType 1
|
||||
set SkipType 1
|
||||
@@ -1724,12 +1768,13 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
frame $w.adv -bd 4
|
||||
frame $w.weekend -bd 4
|
||||
frame $w.durationbox -bd 4
|
||||
frame $w.todobox
|
||||
frame $w.time -bd 4
|
||||
frame $w.hol -bd 4
|
||||
frame $w.msg
|
||||
frame $w.buttons
|
||||
pack $w.o1 $w.o2 $w.o3 -side top -anchor w -in $w.o
|
||||
pack $w.o $w.exp $w.adv $w.weekend $w.time $w.durationbox $w.hol $w.msg -side top -anchor w -pady 4 -expand 0 -fill both
|
||||
pack $w.o $w.exp $w.adv $w.weekend $w.time $w.durationbox $w.todobox $w.hol $w.msg -side top -anchor w -pady 4 -expand 0 -fill both
|
||||
pack $w.msg -side top -anchor w -pady 4 -padx 4 -expand true -fill both
|
||||
pack $w.buttons -side top -anchor w -pady 4 -expand 0 -fill x
|
||||
|
||||
@@ -1919,6 +1964,20 @@ 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]
|
||||
|
||||
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 <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"
|
||||
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:"
|
||||
radiobutton $w.issue -variable SkipType -value 1 -text "Issue reminder as usual"
|
||||
@@ -1930,7 +1989,7 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
# TEXT ENTRY
|
||||
label $w.msglab -text "Summary: "
|
||||
entry $w.entry
|
||||
balloon_add_help $w.entry "Enter the text of the reminder"
|
||||
balloon_add_help $w.entry "Enter the text of the reminder (required)"
|
||||
grid $w.msglab -row 0 -column 0 -in $w.msg -sticky e
|
||||
grid $w.entry -row 0 -column 1 -in $w.msg -sticky nsew
|
||||
|
||||
@@ -1987,7 +2046,7 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
#***********************************************************************
|
||||
proc RemindDialogToOptions { w } {
|
||||
global OptionType SkipType repbut expbut advbut advcount
|
||||
global timebut timeadvbut timerepbut durationbut
|
||||
global timebut timeadvbut timerepbut durationbut todobut
|
||||
global dSaturday dSunday dMonday dTuesday dWednesday dThursday dFriday
|
||||
set ans {}
|
||||
lappend ans "-global-OptionType" $OptionType
|
||||
@@ -2021,10 +2080,12 @@ proc RemindDialogToOptions { w } {
|
||||
#***********************************************************************
|
||||
proc OptionsToRemindDialog { w opts } {
|
||||
global OptionType SkipType repbut expbut advbut advcount
|
||||
global timebut timeadvbut timerepbut TwentyFourHourMode durationbut
|
||||
global dSaturday dSunday dMonday dTuesday dWednesday dThursday dFriday
|
||||
global timebut timeadvbut timerepbut TwentyFourHourMode durationbut todobut
|
||||
global dSaturday dSunday dMonday dTuesday dWednesday dThursday dFriday DateOfEventBeingEdited
|
||||
set hour ""
|
||||
set ampm ""
|
||||
$w.complete_through configure -state normal
|
||||
$w.max_overdue configure -state normal
|
||||
foreach {flag value} $opts {
|
||||
switch -glob -- $flag {
|
||||
"-text-*" {
|
||||
@@ -2072,6 +2133,7 @@ proc OptionsToRemindDialog { w opts } {
|
||||
}
|
||||
}
|
||||
}
|
||||
toggle_complete_through $w
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -2163,6 +2225,7 @@ proc ModifyDay {d firstDay} {
|
||||
wm iconname .mod "Add Reminder"
|
||||
tkwait visibility .mod
|
||||
set oldFocus [focus]
|
||||
toggle_complete_through .mod
|
||||
while {1} {
|
||||
grab .mod
|
||||
raise .mod
|
||||
@@ -2243,7 +2306,7 @@ proc CreateReminder {w} {
|
||||
set body [string trim [$w.entry get]]
|
||||
|
||||
if {"$body" == ""} {
|
||||
error "Blank body in reminder"
|
||||
error "Summary is required"
|
||||
}
|
||||
|
||||
set DidOmit 0
|
||||
@@ -2251,7 +2314,7 @@ proc CreateReminder {w} {
|
||||
# Delegate the first part to CreateReminder1, CreateReminder2, or
|
||||
# CreateReminder3
|
||||
global OptionType SkipType repbut expbut advbut advcount
|
||||
global timebut timeadvbut timerepbut durationbut
|
||||
global timebut timeadvbut timerepbut durationbut todobut
|
||||
|
||||
set rem [CreateReminder$OptionType $w]
|
||||
|
||||
@@ -2299,6 +2362,17 @@ proc CreateReminder {w} {
|
||||
}
|
||||
}
|
||||
|
||||
if {$todobut} {
|
||||
append rem " TODO"
|
||||
set ct [string trim [$w.complete_through get]]
|
||||
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} {
|
||||
append rem " SKIP"
|
||||
@@ -2845,14 +2919,15 @@ proc RestartBackgroundRemindDaemon {} {
|
||||
# Dumps the debugging queue listing
|
||||
#---------------------------------------------------------------------------
|
||||
proc ShowQueue { queue } {
|
||||
global Option
|
||||
set w .queuedbg
|
||||
catch { destroy $w }
|
||||
toplevel $w
|
||||
toplevel $w -background $Option(WinBackground)
|
||||
wm title $w "Queue (Debugging Output)"
|
||||
wm iconname $w "Queue Dbg"
|
||||
text $w.t -fg black -bg white -width 80 -height 30 -wrap word -yscrollcommand "$w.sb set"
|
||||
text $w.t -fg black -bg white -width 80 -height 30 -wrap word -yscrollcommand "$w.sb set" -foreground $Option(TextColor) -background $Option(BackgroundColor) -font CalBoxFont
|
||||
scrollbar $w.sb -orient vertical -command "$w.text yview"
|
||||
button $w.ok -text "OK" -command "destroy $w"
|
||||
button $w.ok -text "OK" -command "destroy $w" -foreground $Option(TextColor) -background $Option(BackgroundColor) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
grid $w.t -row 0 -column 0 -sticky nsew
|
||||
grid $w.sb -row 0 -column 1 -sticky ns
|
||||
grid $w.ok -row 1 -column 0 -sticky w
|
||||
@@ -2864,7 +2939,6 @@ proc ShowQueue { queue } {
|
||||
set obj [lsort -command sort_q $queue]
|
||||
set did 0
|
||||
$w.t tag configure grey -background "#DDDDDD" -selectbackground "#999999"
|
||||
set toggle 0
|
||||
foreach q $obj {
|
||||
if { $did > 0 } {
|
||||
$w.t insert end "\n"
|
||||
@@ -2887,24 +2961,17 @@ proc ShowQueue { queue } {
|
||||
}
|
||||
foreach key [list time nexttime body] {
|
||||
set r [dict get $q $key]
|
||||
if { $toggle != 0 } {
|
||||
$w.t insert end "$key=$r" [list grey $fntag]
|
||||
if {"$key" != "body"} {
|
||||
$w.t insert end "; " [list grey $fntag]
|
||||
}
|
||||
} else {
|
||||
$w.t insert end "$key=$r" [list $fntag]
|
||||
if {"$key" != "body"} {
|
||||
$w.t insert end "; " [list $fntag]
|
||||
}
|
||||
$w.t insert end "$key=$r" [list $fntag]
|
||||
if {"$key" != "body"} {
|
||||
$w.t insert end "; " [list $fntag]
|
||||
}
|
||||
}
|
||||
$w.t insert end "\n"
|
||||
set toggle [expr 1 - $toggle]
|
||||
set did 1
|
||||
}
|
||||
if { $did == 0 } {
|
||||
$w.t insert end "(Queue is empty)\n"
|
||||
$w.t tag configure bold -font BoldFont
|
||||
$w.t insert end "(Queue is empty)\n" bold
|
||||
} else {
|
||||
$w.t insert end "\n\nClick on a queue item to open an editor on the corresponding REM command.\n"
|
||||
}
|
||||
@@ -2968,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 {
|
||||
@@ -3014,7 +3081,7 @@ proc DaemonReadable { file } {
|
||||
catch { unset Ignore }
|
||||
Initialize
|
||||
FillCalWindow
|
||||
ShowTodaysReminders
|
||||
ShowTodaysReminders 0 ""
|
||||
}
|
||||
"reread" {
|
||||
if {[dict exists $obj command]} {
|
||||
@@ -3195,6 +3262,7 @@ proc main {} {
|
||||
|
||||
font create CalboxFont {*}[font actual TkFixedFont]
|
||||
font create HeadingFont {*}[font actual TkDefaultFont]
|
||||
font create BoldFont {*}[font actual TkDefaultFont] -weight bold
|
||||
|
||||
global AppendFile HighestTagSoFar DayNames
|
||||
catch {
|
||||
@@ -3212,7 +3280,7 @@ proc main {} {
|
||||
}
|
||||
FindConfigFile
|
||||
LoadOptions
|
||||
ShowTodaysReminders
|
||||
ShowTodaysReminders 0 ""
|
||||
ScanForTags $AppendFile
|
||||
CreateCalWindow $DayNames
|
||||
FillCalWindow
|
||||
@@ -3284,6 +3352,9 @@ proc ReadTaggedOptions { tag date } {
|
||||
}
|
||||
}
|
||||
|
||||
if {[dict exists $obj date]} {
|
||||
lappend ans -global-DateOfEventBeingEdited $date
|
||||
}
|
||||
if {[dict exists $obj d]} {
|
||||
lappend ans -text-day1 [dict get $obj d]
|
||||
lappend ans -text-day2 [dict get $obj d]
|
||||
@@ -3509,6 +3580,24 @@ proc ReadTaggedOptions { tag date } {
|
||||
lappend ans -entry-entry [dict get $obj body]
|
||||
}
|
||||
|
||||
# Is this a TODO?
|
||||
if {[dict exists $obj is_todo]} {
|
||||
lappend ans -global-todobut [dict get $obj is_todo]
|
||||
} else {
|
||||
lappend ans -global-todobut 0
|
||||
}
|
||||
if {[dict exists $obj complete_through]} {
|
||||
lappend ans -entry-complete_through [dict get $obj complete_through]
|
||||
} else {
|
||||
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
|
||||
@@ -3684,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
|
||||
}
|
||||
@@ -3750,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
|
||||
|
||||
@@ -3818,7 +3907,7 @@ proc EditTaggedReminder { w } {
|
||||
wm title .mod "TkRemind Edit Reminder..."
|
||||
wm iconname .mod "Edit Reminder"
|
||||
OptionsToRemindDialog .mod $opts
|
||||
|
||||
toggle_complete_through .mod
|
||||
tkwait visibility .mod
|
||||
set oldFocus [focus]
|
||||
while {1} {
|
||||
@@ -4166,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 }
|
||||
@@ -4230,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
|
||||
@@ -4240,47 +4329,67 @@ proc DisplayTimeContinuously {} {
|
||||
}
|
||||
|
||||
|
||||
proc daily_rem_enter { lines } {
|
||||
global Balloon
|
||||
balloon_cancel_timer
|
||||
set Balloon(HelpId) [after $Balloon(HelpTime) [list details_popup $lines]]
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: ShowTodaysReminders
|
||||
# %ARGUMENTS:
|
||||
# None
|
||||
# force -- if true, show today's reminders even if option is disabled.
|
||||
# date -- if non-blank, show reminders for specified date rather than today.
|
||||
# %RETURNS:
|
||||
# Nothing
|
||||
# %DESCRIPTION:
|
||||
# Shows all of today's non-timed reminders in a window
|
||||
#***********************************************************************
|
||||
proc ShowTodaysReminders {} {
|
||||
proc ShowTodaysReminders { force date } {
|
||||
global Option
|
||||
global Remind
|
||||
global ReminderFile
|
||||
global TwentyFourHourMode
|
||||
if {!$Option(ShowTodaysReminders)} {
|
||||
if {!$force && !$Option(ShowTodaysReminders)} {
|
||||
return
|
||||
}
|
||||
|
||||
set w .today
|
||||
catch { destroy $w }
|
||||
toplevel $w
|
||||
wm title $w "Today's Reminders"
|
||||
toplevel $w -background $Option(WinBackground)
|
||||
if {"$date" == ""} {
|
||||
set wtitle "Today's Reminders"
|
||||
} else {
|
||||
set wtitle "Reminders for $date"
|
||||
}
|
||||
wm iconname $w "Reminders"
|
||||
text $w.text -width 80 -height 20 -wrap word -yscrollcommand "$w.sb set"
|
||||
text $w.text -width 80 -height 20 -wrap word -yscrollcommand "$w.sb set" -foreground $Option(TextColor) -background $Option(BackgroundColor) -font CalboxFont -spacing1 3
|
||||
scrollbar $w.sb -orient vertical -command "$w.text yview"
|
||||
button $w.ok -text "OK" -command "destroy $w"
|
||||
button $w.ok -text "OK" -command "destroy $w" -foreground $Option(TextColor) -background $Option(BackgroundColor) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
|
||||
grid $w.text -row 0 -column 0 -sticky nsew
|
||||
grid $w.sb -row 0 -column 1 -sticky ns
|
||||
grid $w.ok -row 1 -column 0 -sticky w
|
||||
|
||||
grid rowconfigure $w 0 -weight 1
|
||||
grid rowconfigure $w 1 -weight 0
|
||||
grid columnconfigure $w 0 -weight 1
|
||||
grid columnconfigure $w 1 -weight 0
|
||||
CenterWindow $w .
|
||||
|
||||
# Grab the reminders
|
||||
set stuff ""
|
||||
set cmdline "|$Remind -itkremind=1 -g -q -r "
|
||||
set cmdline "|$Remind -itkremind=1 --json -q -r "
|
||||
if {$TwentyFourHourMode} {
|
||||
append cmdline "-b1 "
|
||||
}
|
||||
append cmdline $Option(ExtraRemindArgs);
|
||||
append cmdline " $ReminderFile 2>@1"
|
||||
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>/dev/null"
|
||||
set f [open $cmdline r]
|
||||
while {[gets $f line] >= 0} {
|
||||
append stuff "$line\n"
|
||||
@@ -4290,12 +4399,163 @@ proc ShowTodaysReminders {} {
|
||||
$w.text insert end $stuff
|
||||
$w.text insert end "\n"
|
||||
$w.text insert end $err
|
||||
} else {
|
||||
$w.text insert end $stuff
|
||||
$w.text configure -state disabled
|
||||
return
|
||||
}
|
||||
|
||||
if {[catch {set arr [::json::json2dict $stuff]} err]} {
|
||||
$w.text insert end "Error converting JSON\n\n"
|
||||
$w.text insert end $err
|
||||
$w.text configure -state disabled
|
||||
return
|
||||
}
|
||||
|
||||
# If first element is banner, set window title
|
||||
set first [lindex $arr 0]
|
||||
$w.text tag configure bold -font BoldFont
|
||||
if {"[lindex $first 0]" == "banner"} {
|
||||
set banner [lindex $first 1]
|
||||
# Trim trailing colon
|
||||
set wtitle [string trimright $banner ":"]
|
||||
set arr [lreplace $arr 0 0]
|
||||
$w.text insert end "$banner" bold
|
||||
$w.text insert end "\n\n"
|
||||
}
|
||||
|
||||
# At this point, we can set the window title
|
||||
wm title $w $wtitle
|
||||
|
||||
# If first element is no reminders, FINE.
|
||||
set first [lindex $arr 0]
|
||||
if {"[lindex $first 0]" == "noreminders"} {
|
||||
$w.text insert end [lindex $first 1] bold
|
||||
$w.text insert end "\n"
|
||||
$w.text configure -state disabled
|
||||
return
|
||||
}
|
||||
|
||||
set arr [lsort -command compare_reminders $arr]
|
||||
set old_date {}
|
||||
set did_a_date 0
|
||||
set t_index 0
|
||||
foreach thing $arr {
|
||||
incr t_index
|
||||
set mydate [dict get $thing date]
|
||||
if {"$mydate" != "$old_date"} {
|
||||
if {"$old_date" != ""} {
|
||||
$w.text insert end "\n"
|
||||
}
|
||||
if {$did_a_date || "$mydate" != "$date"} {
|
||||
$w.text insert end "> $mydate\n" bold
|
||||
set did_a_date 1
|
||||
}
|
||||
}
|
||||
set old_date $mydate
|
||||
set tags [list "l_$t_index"]
|
||||
if {[dict exists $thing r] && [dict exists $thing g] && [dict exists $thing g]} {
|
||||
set r [dict get $thing r]
|
||||
set g [dict get $thing g]
|
||||
set b [dict get $thing b]
|
||||
if {$r > 255} {
|
||||
set r 255
|
||||
} elseif {$r < 0} {
|
||||
set r 0
|
||||
}
|
||||
if {$g > 255} {
|
||||
set g 255
|
||||
} elseif {$g < 0} {
|
||||
set g 0
|
||||
}
|
||||
if {$b > 255} {
|
||||
set b 255
|
||||
} elseif {$b < 0} {
|
||||
set b 0
|
||||
}
|
||||
set color [format "%02X%02X%02X" $r $g $b]
|
||||
lappend tags "clr$color"
|
||||
$w.text tag configure "clr$color" -foreground "#$color"
|
||||
}
|
||||
|
||||
set help_lines {}
|
||||
if {[dict exists $thing info]} {
|
||||
set info [dict get $thing info]
|
||||
if {[dict exists $info location]} {
|
||||
lappend help_lines [list "Location:" [dict get $info location]]
|
||||
}
|
||||
if {[dict exists $info description]} {
|
||||
lappend help_lines [list "Description:" [dict get $info description]]
|
||||
}
|
||||
if {[dict exists $info url]} {
|
||||
lappend help_lines [list "URL:" "Middle-click to open [dict get $info url]"]
|
||||
$w.text tag bind "l_$t_index" <ButtonPress-2> [list exec xdg-open [dict get $info url]]
|
||||
}
|
||||
}
|
||||
if {[llength $help_lines] >= 1} {
|
||||
$w.text tag bind "l_$t_index" <Enter> +[list daily_rem_enter $help_lines]
|
||||
$w.text tag bind "l_$t_index" <Leave> +[list details_leave $w]
|
||||
}
|
||||
if {[dict exists $thing filename]} {
|
||||
set fname [dict get $thing filename]
|
||||
# Don't make INCLUDECMD output editable
|
||||
if {![string match "*|" $fname]} {
|
||||
if {[dict exists $thing lineno_start]} {
|
||||
set l [dict get $thing lineno_start]
|
||||
} else {
|
||||
set l [dict get $thing lineno]
|
||||
}
|
||||
set fntag [string cat "FILE_" $l "_" $fname]
|
||||
$w.text tag bind "l_$t_index" <Enter> +[list $w.text tag configure "l_$t_index" -underline 1]
|
||||
$w.text tag bind "l_$t_index" <Leave> +[list $w.text tag configure "l_$t_index" -underline 0]
|
||||
$w.text tag bind "l_$t_index" <ButtonPress-1> [list FireEditor $w.text $fntag]
|
||||
$w.text tag bind "l_$t_index" <ButtonPress-3> [list FireEditor $w.text $fntag]
|
||||
}
|
||||
}
|
||||
$w.text insert end [dict get $thing body] $tags
|
||||
$w.text insert end "\n"
|
||||
}
|
||||
|
||||
#$w.text insert end "\n\n$stuff\n"
|
||||
$w.text configure -state disabled
|
||||
}
|
||||
|
||||
proc compare_reminders { a b } {
|
||||
set a_date [dict get $a date]
|
||||
set b_date [dict get $b date]
|
||||
#puts "Comparing $a_date $b_date"
|
||||
if {"$a_date" < "$b_date"} {
|
||||
return -1
|
||||
}
|
||||
if {"$a_date" > "$b_date"} {
|
||||
return 1
|
||||
}
|
||||
|
||||
if {[dict exists $a time]} {
|
||||
set a_time [dict get $a time]
|
||||
} else {
|
||||
set a_time 1441
|
||||
}
|
||||
if {[dict exists $b time]} {
|
||||
set b_time [dict get $b time]
|
||||
} else {
|
||||
set b_time 1441
|
||||
}
|
||||
if {$a_time < $b_time} {
|
||||
return -1
|
||||
}
|
||||
if {$a_time > $b_time} {
|
||||
return 1
|
||||
}
|
||||
set a_prio [dict get $a priority]
|
||||
set b_prio [dict get $b priority]
|
||||
if {$a_prio < $b_prio} {
|
||||
return -1
|
||||
}
|
||||
if {$a_prio > $b_prio} {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: InteractiveDeleteReminder
|
||||
# %ARGUMENTS:
|
||||
@@ -4516,6 +4776,7 @@ proc ChooseHeadingFont {} {
|
||||
proc SetHeadingFont {font} {
|
||||
global tmpOpt
|
||||
font configure HeadingFont {*}[font actual $font]
|
||||
font configure BoldFont {*}$Option(HeadingFont) -weight bold
|
||||
set tmpOpt(HeadingFont) [font actual $font]
|
||||
raise .opt
|
||||
}
|
||||
@@ -4616,13 +4877,13 @@ proc set_button_to_errors {} {
|
||||
}
|
||||
|
||||
proc ShowErrors {} {
|
||||
global RemindErrors
|
||||
global RemindErrors Option
|
||||
set w ".errors"
|
||||
catch { destroy $w }
|
||||
toplevel $w
|
||||
text $w.t -width 80 -height 30 -wrap word -yscrollcommand "$w.sb set"
|
||||
toplevel $w -background $Option(WinBackground)
|
||||
text $w.t -width 80 -height 30 -wrap word -yscrollcommand "$w.sb set" -foreground $Option(TextColor) -background $Option(BackgroundColor) -font CalBoxFont
|
||||
scrollbar $w.sb -orient vertical -command "$w.t yview"
|
||||
button $w.ok -text OK -command DoneShowingErrors
|
||||
button $w.ok -text OK -command DoneShowingErrors -foreground $Option(TextColor) -background $Option(BackgroundColor) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
grid $w.t -row 0 -column 0 -sticky nsew
|
||||
grid $w.sb -row 0 -column 1 -sticky ns
|
||||
grid $w.ok -row 1 -column 0 -stick w
|
||||
|
||||
@@ -28,8 +28,9 @@ MANS= $(srcdir)/../man/rem2ps.1 $(srcdir)/../man/remind.1 \
|
||||
|
||||
REMINDSRCS= calendar.c dedupe.c dynbuf.c dorem.c dosubst.c expr.c \
|
||||
files.c funcs.c globals.c hashtab.c hashtab_stats.c \
|
||||
hbcal.c init.c main.c md5.c moon.c omit.c queue.c \
|
||||
sort.c token.c trans.c trigger.c userfns.c utils.c var.c
|
||||
hbcal.c ifelse.c init.c main.c md5.c moon.c omit.c \
|
||||
queue.c sort.c token.c trans.c trigger.c userfns.c \
|
||||
utils.c var.c
|
||||
|
||||
XLATSRC= xlat.c
|
||||
|
||||
@@ -45,10 +46,12 @@ test: all
|
||||
.c.o:
|
||||
@CC@ -c @CPPFLAGS@ @CFLAGS@ @DEFS@ $(CEXTRA) -DSYSDIR=$(datarootdir)/remind -I. -I$(srcdir) $<
|
||||
|
||||
# Extract all tr() strings into a file. NOTE: SOURCE CODE MUST NOT HAVE
|
||||
# MORE THAN ONE tr() PER LINE!!!
|
||||
xlat.c: $(REMINDSRCS)
|
||||
@echo "#include <stddef.h>" > xlat.c
|
||||
@echo "char const *translatables[] = {" >> xlat.c
|
||||
@cat $(REMINDSRCS) | grep 'tr(".*")' | sed -e 's/.*tr."/"/' -e 's/").*/"/' | LANG=C LC_ALL=C sort | uniq | grep -E -v '^"(am|at|from now|hour|minute|now|on|pm|today|tomorrow|was)"$$' | sed -e 's/^/ /' -e 's/$$/,/' >> xlat.c
|
||||
@cat $(REMINDSRCS) | grep 'tr(".*")' | sed -e 's/.*tr."/"/' -e 's/").*/"/' | LANG=C LC_ALL=C sort | uniq | grep -E -v '^"(ago|am|and|at|from now|is|hour|minute|now|on|pm|today|tomorrow|was)"$$' | sed -e 's/^/ /' -e 's/$$/,/' >> xlat.c
|
||||
@echo " NULL" >> xlat.c
|
||||
@echo "};" >> xlat.c
|
||||
|
||||
@@ -101,7 +104,7 @@ depend:
|
||||
# distributions, etc.
|
||||
|
||||
cppcheck:
|
||||
cppcheck -j`nproc` -v --force --enable=all --suppress=ConfigurationNotChecked --suppress=unmatchedSuppression --suppress=variableScope --inline-suppr .
|
||||
cppcheck -j`nproc` -v --force --enable=all --suppress=missingIncludeSystem --suppress=ConfigurationNotChecked --suppress=unmatchedSuppression --suppress=variableScope --inline-suppr --check-level=exhaustive .
|
||||
|
||||
# Build a tar file based on all files checked into git.
|
||||
distro:
|
||||
|
||||
129
src/calendar.c
129
src/calendar.c
@@ -55,7 +55,7 @@ typedef struct cal_entry {
|
||||
DynamicBuffer tags;
|
||||
char passthru[PASSTHRU_LEN+1];
|
||||
int duration;
|
||||
char *filename;
|
||||
char const *filename;
|
||||
int lineno;
|
||||
int lineno_start;
|
||||
Trigger trig;
|
||||
@@ -279,6 +279,7 @@ static int DidAMonth;
|
||||
static int DidAWeek;
|
||||
static int DidADay;
|
||||
|
||||
static char const *CalendarTime(int tim, int duration);
|
||||
static void ColorizeEntry(CalEntry const *e, int clamp);
|
||||
static void SortCol (CalEntry **col);
|
||||
static void DoCalendarOneWeek (int nleft);
|
||||
@@ -288,7 +289,7 @@ static int WriteCalendarRow (void);
|
||||
static void WriteWeekHeaderLine (void);
|
||||
static void WritePostHeaderLine (void);
|
||||
static void PrintLeft (char const *s, int width, char pad);
|
||||
static void PrintCentered (char const *s, int width, char *pad);
|
||||
static void PrintCentered (char const *s, int width, char const *pad);
|
||||
static int WriteOneCalLine (int dse, int wd);
|
||||
static int WriteOneColLine (int col);
|
||||
static void GenerateCalEntries (int col);
|
||||
@@ -380,7 +381,7 @@ despace(char const *s)
|
||||
return buf;
|
||||
}
|
||||
|
||||
void PrintJSONChar(char c) {
|
||||
static void PrintJSONChar(char c) {
|
||||
switch(c) {
|
||||
case '\b': printf("\\b"); break;
|
||||
case '\f': printf("\\f"); break;
|
||||
@@ -422,7 +423,7 @@ void PrintJSONString(char const *s)
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJSONStringLC(char const *s)
|
||||
static void PrintJSONStringLC(char const *s)
|
||||
{
|
||||
while (*s) {
|
||||
switch(*s) {
|
||||
@@ -466,7 +467,7 @@ void PrintJSONKeyPairString(char const *name, char const *val)
|
||||
printf("\",");
|
||||
}
|
||||
|
||||
void PrintJSONKeyPairDate(char const *name, int dse)
|
||||
static void PrintJSONKeyPairDate(char const *name, int dse)
|
||||
{
|
||||
int y, m, d;
|
||||
if (dse == NO_DATE) {
|
||||
@@ -480,7 +481,7 @@ void PrintJSONKeyPairDate(char const *name, int dse)
|
||||
|
||||
}
|
||||
|
||||
void PrintJSONKeyPairDateTime(char const *name, int dt)
|
||||
static void PrintJSONKeyPairDateTime(char const *name, int dt)
|
||||
{
|
||||
int y, m, d, h, i, k;
|
||||
if (dt == NO_TIME) {
|
||||
@@ -498,7 +499,7 @@ void PrintJSONKeyPairDateTime(char const *name, int dt)
|
||||
|
||||
}
|
||||
|
||||
void PrintJSONKeyPairTime(char const *name, int t)
|
||||
static void PrintJSONKeyPairTime(char const *name, int t)
|
||||
{
|
||||
int h, i;
|
||||
if (t == NO_TIME) {
|
||||
@@ -646,7 +647,7 @@ Colorize256(int r, int g, int b, int bg, int clamp)
|
||||
int best = -1;
|
||||
int best_dist = 0;
|
||||
int dist;
|
||||
struct xterm256_colors *cur;
|
||||
struct xterm256_colors const *cur;
|
||||
size_t i;
|
||||
|
||||
if (clamp) {
|
||||
@@ -757,7 +758,7 @@ InitMoonsAndShades(void)
|
||||
static void
|
||||
SetShadeEntry(int dse, char const *shade)
|
||||
{
|
||||
int y, m, d;
|
||||
int d;
|
||||
int r, g, b;
|
||||
/* Don't bother if we're not doing SHADE specials */
|
||||
if (!UseBGVTColors) {
|
||||
@@ -774,7 +775,7 @@ SetShadeEntry(int dse, char const *shade)
|
||||
if (r < 0 || g < 0 || b < 0 || r > 255 || g > 255 || b > 255) {
|
||||
return;
|
||||
}
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
FromDSE(dse, NULL, NULL, &d);
|
||||
bgcolor[d][0] = r;
|
||||
bgcolor[d][1] = g;
|
||||
bgcolor[d][2] = b;
|
||||
@@ -784,7 +785,7 @@ static void
|
||||
SetMoonEntry(int dse, char const *moon)
|
||||
{
|
||||
int phase;
|
||||
int y, m, d;
|
||||
int d;
|
||||
char msg[28];
|
||||
|
||||
/* Don't bother unless it's utf-8 */
|
||||
@@ -803,7 +804,7 @@ SetMoonEntry(int dse, char const *moon)
|
||||
/* Bad phase */
|
||||
return;
|
||||
}
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
FromDSE(dse, NULL, NULL, &d);
|
||||
if (msg[0]) {
|
||||
snprintf(moons[d], sizeof(moons[d]), "%s %s", moonphase_emojis[phase], msg);
|
||||
} else {
|
||||
@@ -1387,7 +1388,7 @@ static void PrintLeft(char const *s, int width, char pad)
|
||||
/* Center a piece of text */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static void PrintCentered(char const *s, int width, char *pad)
|
||||
static void PrintCentered(char const *s, int width, char const *pad)
|
||||
{
|
||||
#ifndef REM_USE_WCHAR
|
||||
int len = strlen(s);
|
||||
@@ -1476,13 +1477,13 @@ static void PrintCentered(char const *s, int width, char *pad)
|
||||
static int WriteOneCalLine(int start_dse, int wd)
|
||||
{
|
||||
int done = 1, i;
|
||||
int y, m, d;
|
||||
int d;
|
||||
|
||||
gon();
|
||||
DRAW(tb);
|
||||
goff();
|
||||
for (i=0; i<7; i++) {
|
||||
FromDSE(start_dse+i, &y, &m, &d);
|
||||
FromDSE(start_dse+i, NULL, NULL, &d);
|
||||
d -= wd;
|
||||
if (CalColumn[i]) {
|
||||
Backgroundize(ColToDay[i]);
|
||||
@@ -1539,7 +1540,6 @@ static int WriteOneColLine(int col)
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e->raw_text);
|
||||
free(e->filename);
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
free(e);
|
||||
@@ -1626,7 +1626,6 @@ static int WriteOneColLine(int col)
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e->raw_text);
|
||||
free(e->filename);
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
free(e);
|
||||
@@ -1645,7 +1644,6 @@ static int WriteOneColLine(int col)
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e->filename);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
#endif
|
||||
@@ -1708,7 +1706,6 @@ static int WriteOneColLine(int col)
|
||||
if (!*s && !e->next) {
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e->filename);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
#endif
|
||||
@@ -1757,12 +1754,13 @@ static void GenerateCalEntries(int col)
|
||||
s = FindInitialToken(&tok, CurLine);
|
||||
|
||||
/* Should we ignore it? */
|
||||
if (NumIfs &&
|
||||
tok.type != T_If &&
|
||||
if (tok.type != T_If &&
|
||||
tok.type != T_Else &&
|
||||
tok.type != T_EndIf &&
|
||||
tok.type != T_IfTrig &&
|
||||
ShouldIgnoreLine())
|
||||
tok.type != T_Set &&
|
||||
tok.type != T_Fset &&
|
||||
should_ignore_line())
|
||||
{
|
||||
/* DO NOTHING */
|
||||
}
|
||||
@@ -1779,6 +1777,7 @@ static void GenerateCalEntries(int col)
|
||||
case T_ErrMsg: r=DoErrMsg(&p); break;
|
||||
case T_Rem: r=DoCalRem(&p, col); break;
|
||||
case T_If: r=DoIf(&p); break;
|
||||
case T_Return: r=DoReturn(&p); break;
|
||||
case T_IfTrig: r=DoIfTrig(&p); break;
|
||||
case T_Else: r=DoElse(&p); break;
|
||||
case T_EndIf: r=DoEndif(&p); break;
|
||||
@@ -1808,6 +1807,18 @@ static void GenerateCalEntries(int col)
|
||||
break;
|
||||
case T_Pop: r=PopOmitContext(&p); break;
|
||||
case T_Push: r=PushOmitContext(&p); break;
|
||||
case T_PushVars:
|
||||
r=PushVars(&p);
|
||||
break;
|
||||
case T_PopVars:
|
||||
r=PopVars(&p);
|
||||
break;
|
||||
case T_PushFuncs:
|
||||
r=PushUserFuncs(&p);
|
||||
break;
|
||||
case T_PopFuncs:
|
||||
r=PopUserFuncs(&p);
|
||||
break;
|
||||
case T_Preserve: r=DoPreserve(&p); break;
|
||||
case T_Expr: r = DoExpr(&p); break;
|
||||
case T_Translate: r = DoTranslate(&p); break;
|
||||
@@ -2008,7 +2019,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
}
|
||||
} else {
|
||||
/* Calculate the trigger date */
|
||||
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
|
||||
dse = ComputeTrigger(get_scanfrom(&trig), &trig, &tim, &r, 1);
|
||||
if (r) {
|
||||
if (r == E_CANT_TRIG && trig.maybe_uncomputable) {
|
||||
r = OK;
|
||||
@@ -2039,6 +2050,13 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Filter unwanted events/todos */
|
||||
if ((TodoFilter == ONLY_TODOS && !trig.is_todo) ||
|
||||
(TodoFilter == ONLY_EVENTS && trig.is_todo)) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Save nonconst_expr flag */
|
||||
nonconst_expr = p->nonconst_expr;
|
||||
/* Convert PS and PSF to PASSTHRU */
|
||||
@@ -2138,14 +2156,18 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
}
|
||||
(void) sscanf(DBufValue(&pre_buf), "%d %d %d",
|
||||
&col_r, &col_g, &col_b);
|
||||
if (col_r < 0) col_r = 0;
|
||||
else if (col_r > 255) col_r = 255;
|
||||
if (col_g < 0) col_g = 0;
|
||||
else if (col_g > 255) col_g = 255;
|
||||
if (col_b < 0) col_b = 0;
|
||||
else if (col_b > 255) col_b = 255;
|
||||
if (!PsCal && !DoSimpleCalendar) {
|
||||
if (col_r < 0 || col_g < 0 || col_b < 0 ||
|
||||
col_r > 255 || col_g > 255 || col_b > 255) {
|
||||
is_color = 0;
|
||||
col_r = -1;
|
||||
col_g = -1;
|
||||
col_b = -1;
|
||||
trig.passthru[0] = 0;
|
||||
DBufFree(&pre_buf);
|
||||
} else {
|
||||
if (!PsCal && !DoSimpleCalendar) {
|
||||
DBufFree(&pre_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2275,7 +2297,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
}
|
||||
e->infos = NULL;
|
||||
e->nonconst_expr = nonconst_expr;
|
||||
e->if_depth = NumIfs;
|
||||
e->if_depth = get_if_pointer() - get_base_if_pointer();
|
||||
e->trig = trig;
|
||||
e->tt = tim;
|
||||
#ifdef REM_USE_WCHAR
|
||||
@@ -2316,17 +2338,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
FreeTrig(&trig);
|
||||
e->duration = tim.duration;
|
||||
e->priority = trig.priority;
|
||||
e->filename = StrDup(FileName);
|
||||
if(!e->filename) {
|
||||
FreeTrigInfoChain(e->infos);
|
||||
if (e->text) free(e->text);
|
||||
if (e->raw_text) free(e->raw_text);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
#endif
|
||||
free(e);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
e->filename = GetCurrentFilename();
|
||||
e->lineno = LineNo;
|
||||
e->lineno_start = LineNoStart;
|
||||
|
||||
@@ -2355,7 +2367,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void WriteSimpleEntryProtocol1(CalEntry *e)
|
||||
static void WriteSimpleEntryProtocol1(CalEntry const *e)
|
||||
{
|
||||
if (e->passthru[0]) {
|
||||
printf(" %s", e->passthru);
|
||||
@@ -2426,7 +2438,7 @@ WriteJSONInfoChain(TrigInfo *ti)
|
||||
}
|
||||
printf("},");
|
||||
}
|
||||
void WriteJSONTrigger(Trigger const *t, int include_tags, int today)
|
||||
void WriteJSONTrigger(Trigger const *t, int include_tags)
|
||||
{
|
||||
/* wd is an array of days from 0=monday to 6=sunday.
|
||||
We convert to array of strings */
|
||||
@@ -2454,6 +2466,8 @@ void WriteJSONTrigger(Trigger const *t, int include_tags, int today)
|
||||
if (t->y != NO_YR) {
|
||||
PrintJSONKeyPairInt("y", t->y);
|
||||
}
|
||||
PrintJSONKeyPairInt("is_todo", t->is_todo);
|
||||
PrintJSONKeyPairDate("complete_through", t->complete_through);
|
||||
if (t->back) {
|
||||
PrintJSONKeyPairInt("back", t->back);
|
||||
}
|
||||
@@ -2463,6 +2477,10 @@ void WriteJSONTrigger(Trigger const *t, int include_tags, int today)
|
||||
if (t->rep) {
|
||||
PrintJSONKeyPairInt("rep", t->rep);
|
||||
}
|
||||
if (t->d != NO_DAY && t->m != NO_MON && t->y != NO_YR) {
|
||||
printf("\"trigbase\":\"%04d-%02d-%-2d\",",
|
||||
t->y, t->m+1, t->d);
|
||||
}
|
||||
/* Local omit is an array of days from 0=monday to 6=sunday.
|
||||
We convert to array of strings */
|
||||
if (t->localomit != NO_WD) {
|
||||
@@ -2495,8 +2513,15 @@ void WriteJSONTrigger(Trigger const *t, int include_tags, int today)
|
||||
if (t->once != NO_ONCE) {
|
||||
PrintJSONKeyPairInt("once", t->once);
|
||||
}
|
||||
if (t->scanfrom != today) {
|
||||
PrintJSONKeyPairDate("scanfrom", t->scanfrom);
|
||||
if (t->scanfrom != NO_SCANFROM) {
|
||||
if (t->scanfrom >= 0) {
|
||||
PrintJSONKeyPairDate("scanfrom", t->scanfrom);
|
||||
} else {
|
||||
PrintJSONKeyPairInt("scanfrom", t->scanfrom);
|
||||
}
|
||||
}
|
||||
if (t->max_overdue >= 0) {
|
||||
PrintJSONKeyPairInt("max_overdue", t->max_overdue);
|
||||
}
|
||||
PrintJSONKeyPairDate("from", t->from);
|
||||
PrintJSONKeyPairInt("priority", t->priority);
|
||||
@@ -2524,7 +2549,7 @@ void WriteJSONTrigger(Trigger const *t, int include_tags, int today)
|
||||
}
|
||||
}
|
||||
|
||||
static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
|
||||
static void WriteSimpleEntryProtocol2(CalEntry *e)
|
||||
{
|
||||
char const *s;
|
||||
if (DoPrefixLineNo) {
|
||||
@@ -2551,7 +2576,7 @@ static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
|
||||
PrintJSONKeyPairInt("trep", e->tt.rep);
|
||||
}
|
||||
}
|
||||
WriteJSONTrigger(&e->trig, 0, today);
|
||||
WriteJSONTrigger(&e->trig, 0);
|
||||
if (e->nonconst_expr) {
|
||||
PrintJSONKeyPairInt("nonconst_expr", e->nonconst_expr);
|
||||
}
|
||||
@@ -2656,7 +2681,7 @@ static void WriteSimpleEntries(int col, int dse)
|
||||
}
|
||||
DidADay = 1;
|
||||
printf("{\"date\":\"%04d-%02d-%02d\",", y, m+1, d);
|
||||
WriteSimpleEntryProtocol2(e, dse);
|
||||
WriteSimpleEntryProtocol2(e);
|
||||
printf("}");
|
||||
if (PsCal != PSCAL_LEVEL3) {
|
||||
printf("\n");
|
||||
@@ -2668,7 +2693,6 @@ static void WriteSimpleEntries(int col, int dse)
|
||||
|
||||
free(e->text);
|
||||
free(e->raw_text);
|
||||
free(e->filename);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
@@ -2792,7 +2816,7 @@ static void WriteCalDays(void)
|
||||
/* This takes into account duration */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char const *
|
||||
static char const *
|
||||
CalendarTime(int tim, int duration)
|
||||
{
|
||||
static char buf[128];
|
||||
@@ -2890,7 +2914,8 @@ char const *SimpleTime(int tim)
|
||||
if (h == 0) hh=12;
|
||||
else if (h > 12) hh=h-12;
|
||||
else hh=h;
|
||||
snprintf(buf, sizeof(buf), "%d%c%02d%.64s ", hh, TimeSep, min, (h>=12) ? tr("pm") : tr("am"));
|
||||
snprintf(buf, sizeof(buf), "%d%c%02d%.64s ", hh, TimeSep, min, (h>=12) ? tr("pm") :
|
||||
tr("am"));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `readline' function. */
|
||||
#undef HAVE_READLINE
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#undef HAVE_STRCASECMP
|
||||
|
||||
@@ -81,6 +84,12 @@
|
||||
/* Define to 1 if you have the <wctype.h> header file. */
|
||||
#undef HAVE_WCTYPE_H
|
||||
|
||||
/* Define to 1 if you have the <readline/history.h> header file. */
|
||||
#undef HAVE_READLINE_HISTORY_H
|
||||
|
||||
/* Define to 1 if you have the <readline/readline.h> header file. */
|
||||
#undef HAVE_READLINE_READLINE_H
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
|
||||
18
src/custom.h
18
src/custom.h
@@ -108,12 +108,6 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define INCLUDE_NEST 9
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* IF_NEST: How many nested IFs do we handle? Maximum is the number */
|
||||
/* of bits in an int, divided by two. Beware! */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define IF_NEST (4*sizeof(unsigned int))
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many attempts to resolve a weird date spec? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
@@ -165,3 +159,15 @@
|
||||
#else
|
||||
#undef REM_USE_WCHAR
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_READLINE) && defined(HAVE_READLINE_READLINE_H)
|
||||
#define USE_READLINE 1
|
||||
#else
|
||||
#undef USE_READLINE
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_READLINE) && defined(HAVE_READLINE_READLINE_H) && defined(HAVE_READLINE_HISTORY_H)
|
||||
#define USE_READLINE_HISTORY 1
|
||||
#else
|
||||
#undef USE_READLINE_HISTORY
|
||||
#endif
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
/* The default values are initially set to the city hall in Ottawa, */
|
||||
/* Ontario, Canada. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define DEFAULT_LATITUDE 45.420556
|
||||
#define DEFAULT_LONGITUDE -75.689722
|
||||
#define DEFAULT_LATITUDE 45.42055555555555
|
||||
#define DEFAULT_LONGITUDE -75.68944444444445
|
||||
#define LOCATION "Ottawa"
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
@@ -108,12 +108,6 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define INCLUDE_NEST 9
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* IF_NEST: How many nested IFs do we handle? Maximum is the number */
|
||||
/* of bits in an int, divided by two. Beware! */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define IF_NEST (4*sizeof(unsigned int))
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many attempts to resolve a weird date spec? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
@@ -165,3 +159,15 @@
|
||||
#else
|
||||
#undef REM_USE_WCHAR
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_READLINE) && defined(HAVE_READLINE_READLINE_H)
|
||||
#define USE_READLINE 1
|
||||
#else
|
||||
#undef USE_READLINE
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_READLINE) && defined(HAVE_READLINE_READLINE_H) && defined(HAVE_READLINE_HISTORY_H)
|
||||
#define USE_READLINE_HISTORY 1
|
||||
#else
|
||||
#undef USE_READLINE_HISTORY
|
||||
#endif
|
||||
|
||||
12
src/dedupe.c
12
src/dedupe.c
@@ -28,9 +28,9 @@ typedef struct dedupe_entry {
|
||||
|
||||
static hash_table DedupeTable;
|
||||
|
||||
static unsigned int DedupeHashFunc(void *x)
|
||||
static unsigned int DedupeHashFunc(void const *x)
|
||||
{
|
||||
DedupeEntry *e = (DedupeEntry *) x;
|
||||
DedupeEntry const *e = (DedupeEntry const *) x;
|
||||
unsigned int hashval = (unsigned int) e->trigger_date;
|
||||
if (e->trigger_time != NO_TIME) {
|
||||
hashval += (unsigned int) e->trigger_time;
|
||||
@@ -39,10 +39,10 @@ static unsigned int DedupeHashFunc(void *x)
|
||||
return hashval;
|
||||
}
|
||||
|
||||
static int CompareDedupes(void *x, void *y)
|
||||
static int CompareDedupes(void const *x, void const *y)
|
||||
{
|
||||
DedupeEntry *a = (DedupeEntry *) x;
|
||||
DedupeEntry *b = (DedupeEntry *) y;
|
||||
DedupeEntry const *a = (DedupeEntry const *) x;
|
||||
DedupeEntry const *b = (DedupeEntry const *) y;
|
||||
if (a->trigger_date != b->trigger_date) return a->trigger_date - b->trigger_date;
|
||||
if (a->trigger_time != b->trigger_time) return a->trigger_time - b->trigger_time;
|
||||
return strcmp(a->body, b->body);
|
||||
@@ -122,7 +122,7 @@ InsertDedupeEntry(int trigger_date, int trigger_time, char const *body)
|
||||
int
|
||||
ShouldDedupe(int trigger_date, int trigger_time, char const *body)
|
||||
{
|
||||
DedupeEntry *e = FindDedupeEntry(trigger_date, trigger_time, body);
|
||||
DedupeEntry const *e = FindDedupeEntry(trigger_date, trigger_time, body);
|
||||
|
||||
if (e) {
|
||||
return 1;
|
||||
|
||||
570
src/dorem.c
570
src/dorem.c
@@ -29,8 +29,82 @@ static int ParseLocalOmit (ParsePtr s, Trigger *t);
|
||||
static int ParseScanFrom (ParsePtr s, Trigger *t, int type);
|
||||
static int ParsePriority (ParsePtr s, Trigger *t);
|
||||
static int ParseUntil (ParsePtr s, Trigger *t, int type);
|
||||
static int ShouldTriggerBasedOnWarn (Trigger *t, int dse, int *err);
|
||||
static int ComputeTrigDuration(TimeTrig *t);
|
||||
static int ShouldTriggerBasedOnWarn (Trigger const *t, int dse, int *err);
|
||||
static int ComputeTrigDuration(TimeTrig const *t);
|
||||
|
||||
void remove_trailing_newlines(DynamicBuffer *buf)
|
||||
{
|
||||
char *s = (char *) DBufValue(buf) + DBufLen(buf) - 1;
|
||||
while (s >= DBufValue(buf)) {
|
||||
if (*s == '\n') {
|
||||
*s = 0;
|
||||
s--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
static int todo_filtered(Trigger const *t)
|
||||
{
|
||||
if (t->is_todo && TodoFilter == ONLY_EVENTS) return 1;
|
||||
if (!t->is_todo && TodoFilter == ONLY_TODOS) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_raw_scanfrom(Trigger const *t)
|
||||
{
|
||||
if (t->from != NO_DATE) {
|
||||
if (t->from > DSEToday) return t->from;
|
||||
return DSEToday;
|
||||
}
|
||||
if (t->scanfrom == NO_SCANFROM) return NO_SCANFROM;
|
||||
if (t->scanfrom > 0) return t->scanfrom;
|
||||
|
||||
/* Relative SCANFROM is negative, so subtract from today() */
|
||||
return DSEToday + t->scanfrom;
|
||||
}
|
||||
|
||||
int
|
||||
get_scanfrom(Trigger const *t)
|
||||
{
|
||||
int calmode = (DoSimpleCalendar || DoCalendar) ? 1 : 0;
|
||||
|
||||
/* TODOs are treated just like events in calendar mode */
|
||||
if (!calmode && t->is_todo && t->from != NO_DATE) {
|
||||
if (t->complete_through != NO_DATE) {
|
||||
if (t->complete_through+1 > t->from) {
|
||||
return t->complete_through+1;
|
||||
} else {
|
||||
return t->from;
|
||||
}
|
||||
} else {
|
||||
return t->from;
|
||||
}
|
||||
}
|
||||
if (get_raw_scanfrom(t) != NO_SCANFROM) {
|
||||
if (!calmode && t->complete_through != NO_DATE) {
|
||||
if (t->complete_through+1 > get_raw_scanfrom(t)) {
|
||||
return t->complete_through+1;
|
||||
} else {
|
||||
return get_raw_scanfrom(t);
|
||||
}
|
||||
} else {
|
||||
return get_raw_scanfrom(t);
|
||||
}
|
||||
}
|
||||
if (!calmode) {
|
||||
if (t->complete_through != NO_DATE) {
|
||||
return t->complete_through+1;
|
||||
}
|
||||
if (t->is_todo) {
|
||||
/* TODO with no COMPLETE-THROUGH.
|
||||
Scan from the beginning of time */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return DSEToday;
|
||||
}
|
||||
|
||||
static int
|
||||
ensure_expr_references_first_local_arg(expr_node *node)
|
||||
@@ -179,7 +253,7 @@ static void ensure_satnode_mentions_trigdate(expr_node *node)
|
||||
|
||||
|
||||
static int
|
||||
ComputeTrigDuration(TimeTrig *t)
|
||||
ComputeTrigDuration(TimeTrig const *t)
|
||||
{
|
||||
if (t->ttime == NO_TIME ||
|
||||
t->duration == NO_TIME) {
|
||||
@@ -213,13 +287,30 @@ int DoRem(ParsePtr p)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (trig.complete_through != NO_DATE && !trig.is_todo) {
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
FreeTrig(&trig);
|
||||
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) {
|
||||
PurgeEchoLine("%s\n%s\n", "#!P! Cannot parse next line", CurLine);
|
||||
if (!Hush) {
|
||||
PurgeEchoLine("%s\n", "#!P! Cannot parse next line");
|
||||
}
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
FreeTrig(&trig);
|
||||
return E_EOLN;
|
||||
}
|
||||
if (trig.typ == SAT_TYPE) {
|
||||
PurgeEchoLine("%s\n", "#!P: Cannot purge SATISFY-type reminders");
|
||||
if (!Hush) {
|
||||
PurgeEchoLine("%s\n", "#!P: Cannot purge SATISFY-type reminders");
|
||||
}
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
r=DoSatRemind(&trig, &tim, p);
|
||||
if (r) {
|
||||
@@ -281,10 +372,12 @@ int DoRem(ParsePtr p)
|
||||
}
|
||||
} else {
|
||||
/* Calculate the trigger date */
|
||||
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
|
||||
dse = ComputeTrigger(get_scanfrom(&trig), &trig, &tim, &r, 1);
|
||||
if (r) {
|
||||
if (PurgeMode) {
|
||||
PurgeEchoLine("%s: %s\n", "#!P! Problem calculating trigger date", GetErr(r));
|
||||
if (!Hush) {
|
||||
PurgeEchoLine("%s: %s\n", "#!P! Problem calculating trigger date", GetErr(r));
|
||||
}
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
if (r == E_CANT_TRIG && trig.maybe_uncomputable) {
|
||||
@@ -304,14 +397,18 @@ int DoRem(ParsePtr p)
|
||||
}
|
||||
}
|
||||
if (PurgeMode) {
|
||||
if (trig.expired || dse < DSEToday) {
|
||||
if (trig.expired || (!trig.is_todo && dse < DSEToday)) {
|
||||
if (p->expr_happened) {
|
||||
if (p->nonconst_expr) {
|
||||
PurgeEchoLine("%s\n", "#!P: Next line may have expired, but contains non-constant expression");
|
||||
PurgeEchoLine("%s\n", "#!P: or a relative SCANFROM clause");
|
||||
if (!Hush) {
|
||||
PurgeEchoLine("%s\n", "#!P: Next line may have expired, but contains non-constant expression");
|
||||
PurgeEchoLine("%s\n", "#!P: or a relative SCANFROM clause");
|
||||
}
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
} else {
|
||||
PurgeEchoLine("%s\n", "#!P: Next line has expired, but contains expression... please verify");
|
||||
if (!Hush) {
|
||||
PurgeEchoLine("%s\n", "#!P: Next line has expired, but contains expression... please verify");
|
||||
}
|
||||
PurgeEchoLine("#!P: Expired: %s\n", CurLine);
|
||||
}
|
||||
} else {
|
||||
@@ -328,8 +425,11 @@ int DoRem(ParsePtr p)
|
||||
if (dse == DSEToday &&
|
||||
!(!IgnoreOnce &&
|
||||
trig.once != NO_ONCE &&
|
||||
GetOnceDate() == DSEToday))
|
||||
QueueReminder(p, &trig, &tim, trig.sched);
|
||||
GetOnceDate() == DSEToday)) {
|
||||
if (!todo_filtered(&trig)) {
|
||||
QueueReminder(p, &trig, &tim, trig.sched);
|
||||
}
|
||||
}
|
||||
/* If we're in daemon mode, do nothing over here */
|
||||
if (Daemon) {
|
||||
FreeTrig(&trig);
|
||||
@@ -338,7 +438,72 @@ int DoRem(ParsePtr p)
|
||||
|
||||
r = OK;
|
||||
if (ShouldTriggerReminder(&trig, &tim, dse, &err)) {
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, dse, 0, NULL)) ) {
|
||||
/* Filter unwanted events/todos */
|
||||
if (todo_filtered(&trig)) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (JSONMode) {
|
||||
DynamicBuffer body;
|
||||
int y, m, d;
|
||||
int if_depth = get_if_pointer() - get_base_if_pointer();
|
||||
DBufInit(&body);
|
||||
int red=-1, green=-1, blue=-1;
|
||||
r=TriggerReminder(p, &trig, &tim, dse, 0, &body, &red, &green, &blue);
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
/* Remove trailing newlines from body */
|
||||
remove_trailing_newlines(&body);
|
||||
|
||||
if (!*DBufValue(&body)) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
if (JSONLinesEmitted) {
|
||||
printf("},\n");
|
||||
}
|
||||
JSONLinesEmitted++;
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
printf("{\"date\":\"%04d-%02d-%02d\",", y, m+1, d);
|
||||
PrintJSONKeyPairString("filename", GetCurrentFilename());
|
||||
PrintJSONKeyPairInt("lineno", LineNo);
|
||||
if (LineNoStart != LineNo) {
|
||||
PrintJSONKeyPairInt("lineno_start", LineNoStart);
|
||||
}
|
||||
PrintJSONKeyPairString("passthru", trig.passthru);
|
||||
if (trig.duration_days) {
|
||||
PrintJSONKeyPairInt("duration", trig.duration_days);
|
||||
}
|
||||
if (tim.ttime != NO_TIME) {
|
||||
PrintJSONKeyPairInt("time", tim.ttime);
|
||||
}
|
||||
if (p->nonconst_expr) {
|
||||
PrintJSONKeyPairInt("nonconst_expr", 1);
|
||||
}
|
||||
if (if_depth) {
|
||||
PrintJSONKeyPairInt("if_depth", if_depth);
|
||||
}
|
||||
if (tim.delta) {
|
||||
PrintJSONKeyPairInt("tdelta", tim.delta);
|
||||
}
|
||||
if (tim.rep) {
|
||||
PrintJSONKeyPairInt("trep", tim.rep);
|
||||
}
|
||||
if (red >= 0 && red <= 255 && green >= 0 && green <= 255 && blue >=0 && blue <= 255) {
|
||||
PrintJSONKeyPairInt("r", red);
|
||||
PrintJSONKeyPairInt("g", green);
|
||||
PrintJSONKeyPairInt("b", blue);
|
||||
}
|
||||
|
||||
WriteJSONTrigger(&trig, 1);
|
||||
printf("\"body\":\"");
|
||||
PrintJSONString(DBufValue(&body));
|
||||
printf("\"");
|
||||
} else {
|
||||
r=TriggerReminder(p, &trig, &tim, dse, 0, NULL, NULL, NULL, NULL);
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
@@ -358,6 +523,106 @@ int DoRem(ParsePtr p)
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetFullDate - get a full date, either YYYY-MM-DD or */
|
||||
/* YEAR MON DAY */
|
||||
/* */
|
||||
/* Returns OK on success or an error code on failure. Sets */
|
||||
/* *dse on success. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int GetFullDate(ParsePtr s, char const *prefix, int *dse)
|
||||
{
|
||||
Token tok;
|
||||
DynamicBuffer buf;
|
||||
int y = NO_YR, m = NO_MON, d = NO_DAY;
|
||||
int r;
|
||||
*dse = NO_DATE;
|
||||
|
||||
DBufInit(&buf);
|
||||
|
||||
while(1) {
|
||||
r = ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
switch(tok.type) {
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", prefix, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
y = tok.val;
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
DBufFree(&buf);
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", prefix, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
m = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
DBufFree(&buf);
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", prefix, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
d = tok.val;
|
||||
break;
|
||||
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", prefix, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", prefix, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", prefix, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
if (*dse != NO_DATE) {
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
*dse = tok.val;
|
||||
/* We're done here! */
|
||||
return OK;
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return -tok.val;
|
||||
}
|
||||
if (*dse == NO_DATE && (y == NO_YR || m == NO_MON || d == NO_DAY)) {
|
||||
Eprint("%s: %s", prefix, GetErr(E_INCOMPLETE));
|
||||
DBufFree(&buf);
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
if (*dse != NO_DATE) {
|
||||
PushToken(DBufValue(&buf), s);
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
}
|
||||
if (!DateOK(y, m, d)) {
|
||||
DBufFree(&buf);
|
||||
return E_BAD_DATE;
|
||||
}
|
||||
*dse = DSE(y, m, d);
|
||||
PushToken(DBufValue(&buf), s);
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseRem */
|
||||
@@ -372,6 +637,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
DynamicBuffer buf;
|
||||
Token tok;
|
||||
int y, m, d;
|
||||
int dse;
|
||||
int seen_delta = 0;
|
||||
|
||||
DBufInit(&buf);
|
||||
@@ -390,7 +656,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
trig->addomit = 0;
|
||||
trig->noqueue = 0;
|
||||
trig->typ = NO_TYPE;
|
||||
trig->scanfrom = NO_DATE;
|
||||
trig->scanfrom = NO_SCANFROM;
|
||||
trig->from = NO_DATE;
|
||||
trig->priority = DefaultPrio;
|
||||
trig->sched[0] = 0;
|
||||
@@ -407,6 +673,9 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
tim->rep = NO_REP;
|
||||
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;
|
||||
|
||||
@@ -419,6 +688,11 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
/* Figure out what we've got */
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
switch(tok.type) {
|
||||
case T_Todo:
|
||||
if (trig->is_todo) return E_TODO_TWICE;
|
||||
trig->is_todo = 1;
|
||||
break;
|
||||
|
||||
case T_In:
|
||||
/* Completely ignored */
|
||||
DBufFree(&buf);
|
||||
@@ -491,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);
|
||||
@@ -545,6 +838,13 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
case T_CompleteThrough:
|
||||
if (trig->complete_through != NO_DATE) return E_COMPLETE_THROUGH_TWICE;
|
||||
r = GetFullDate(s, "COMPLETE-THROUGH", &dse);
|
||||
if (r != OK) return r;
|
||||
trig->complete_through = dse;
|
||||
break;
|
||||
|
||||
case T_Until:
|
||||
DBufFree(&buf);
|
||||
r=ParseUntil(s, trig, tok.type);
|
||||
@@ -638,6 +938,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
strtolower(trig->omitfunc);
|
||||
/* An OMITFUNC counts as a nonconst_expr! */
|
||||
s->expr_happened = 1;
|
||||
nonconst_debug(s->nonconst_expr, tr("OMITFUNC counts as a non-constant expression"));
|
||||
s->nonconst_expr = 1;
|
||||
DBufFree(&buf);
|
||||
break;
|
||||
@@ -755,8 +1056,8 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
if (trig->until != NO_UNTIL && trig->until < trig->from) {
|
||||
Wprint(tr("Warning: UNTIL/THROUGH date earlier than FROM date"));
|
||||
}
|
||||
} else if (trig->scanfrom != NO_DATE) {
|
||||
if (trig->until != NO_UNTIL && trig->until < trig->scanfrom) {
|
||||
} else if (get_raw_scanfrom(trig) != NO_SCANFROM) {
|
||||
if (trig->until != NO_UNTIL && trig->until < get_raw_scanfrom(trig)) {
|
||||
Wprint(tr("Warning: UNTIL/THROUGH date earlier than SCANFROM date"));
|
||||
}
|
||||
}
|
||||
@@ -766,11 +1067,6 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
Wprint(tr("Warning: Useless use of UNTIL with fully-specified date and no *rep"));
|
||||
}
|
||||
|
||||
/* Set scanfrom to default if not set explicitly */
|
||||
if (trig->scanfrom == NO_DATE) {
|
||||
trig->scanfrom = DSEToday;
|
||||
}
|
||||
|
||||
/* Check that any SCHED / WARN / OMITFUNC functions refer to
|
||||
their arguments */
|
||||
check_trigger_function(trig->sched, "SCHED");
|
||||
@@ -872,93 +1168,25 @@ static int ParseLocalOmit(ParsePtr s, Trigger *t)
|
||||
/***************************************************************/
|
||||
static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
{
|
||||
int y = NO_YR,
|
||||
m = NO_MON,
|
||||
d = NO_DAY;
|
||||
|
||||
char const *which;
|
||||
int dse;
|
||||
|
||||
if (type == T_Until) {
|
||||
which = "UNTIL";
|
||||
} else {
|
||||
which = "THROUGH";
|
||||
}
|
||||
Token tok;
|
||||
int r;
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
|
||||
if (t->until != NO_UNTIL) return E_UNTIL_TWICE;
|
||||
|
||||
while(1) {
|
||||
r = ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
switch(tok.type) {
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", which, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
y = tok.val;
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
DBufFree(&buf);
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", which, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
m = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
DBufFree(&buf);
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", which, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
d = tok.val;
|
||||
break;
|
||||
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", which, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", which, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", which, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
FromDSE(tok.val, &y, &m, &d);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return -tok.val;
|
||||
}
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
|
||||
Eprint("%s: %s", which, GetErr(E_INCOMPLETE));
|
||||
DBufFree(&buf);
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
if (!DateOK(y, m, d)) {
|
||||
DBufFree(&buf);
|
||||
return E_BAD_DATE;
|
||||
}
|
||||
t->until = DSE(y, m, d);
|
||||
PushToken(DBufValue(&buf), s);
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
}
|
||||
int r = GetFullDate(s, which, &dse);
|
||||
if (r != OK) {
|
||||
return r;
|
||||
}
|
||||
|
||||
t->until = dse;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -968,12 +1196,9 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
/***************************************************************/
|
||||
static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
{
|
||||
int y = NO_YR,
|
||||
m = NO_MON,
|
||||
d = NO_DAY;
|
||||
|
||||
Token tok;
|
||||
int r;
|
||||
int y = NO_YR, m = NO_MON, d = NO_DAY;
|
||||
Token tok;
|
||||
DynamicBuffer buf;
|
||||
char const *word;
|
||||
|
||||
@@ -984,8 +1209,8 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
word = "FROM";
|
||||
}
|
||||
|
||||
if (t->scanfrom != NO_DATE) return E_SCAN_TWICE;
|
||||
|
||||
if (t->scanfrom != NO_SCANFROM) return E_SCAN_TWICE;
|
||||
if (t->from != NO_DATE) return E_SCAN_TWICE;
|
||||
while(1) {
|
||||
r = ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
@@ -1032,8 +1257,12 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
Eprint("%s: %s", word, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
FromDSE(tok.val, &y, &m, &d);
|
||||
break;
|
||||
if (type == FROM_TYPE) {
|
||||
t->from = tok.val;
|
||||
} else {
|
||||
t->scanfrom = tok.val;
|
||||
}
|
||||
return OK;
|
||||
|
||||
case T_Back:
|
||||
DBufFree(&buf);
|
||||
@@ -1053,14 +1282,14 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
Eprint("%s: %s", word, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
if (tok.val < 0) {
|
||||
if (tok.val > 0) {
|
||||
tok.val = -tok.val;
|
||||
}
|
||||
FromDSE(DSEToday - tok.val, &y, &m, &d);
|
||||
/* Don't purge reminders with a relative scanfrom */
|
||||
t->scanfrom = tok.val;
|
||||
s->expr_happened = 1;
|
||||
nonconst_debug(s->nonconst_expr, tr("Relative SCANFROM counts as a non-constant expression"));
|
||||
s->nonconst_expr = 1;
|
||||
break;
|
||||
return OK;
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
@@ -1077,14 +1306,10 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
DBufFree(&buf);
|
||||
return E_BAD_DATE;
|
||||
}
|
||||
t->scanfrom = DSE(y, m, d);
|
||||
if (type == FROM_TYPE) {
|
||||
t->from = t->scanfrom;
|
||||
if (t->scanfrom < DSEToday) {
|
||||
t->scanfrom = DSEToday;
|
||||
}
|
||||
t->from = DSE(y, m, d);
|
||||
} else {
|
||||
t->from = NO_DATE;
|
||||
t->scanfrom = DSE(y, m, d);
|
||||
}
|
||||
|
||||
PushToken(DBufValue(&buf), s);
|
||||
@@ -1102,7 +1327,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
/* Trigger the reminder if it's a RUN or MSG type. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued, DynamicBuffer *output)
|
||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig const *tim, int dse, int is_queued, DynamicBuffer *output, int *rr, int *gg, int *bb)
|
||||
{
|
||||
int r, y, m, d;
|
||||
int adjusted_for_newline = 0;
|
||||
@@ -1167,17 +1392,37 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
||||
DBufFree(&buf);
|
||||
if (r) return r;
|
||||
t->typ = MSG_TYPE;
|
||||
|
||||
if (red < 0 || green < 0 || blue < 0 || red > 255 || green > 255 || blue > 255) {
|
||||
red = -1;
|
||||
green = -1;
|
||||
blue = -1;
|
||||
t->passthru[0] = 0;
|
||||
}
|
||||
}
|
||||
/* If it's a MSG-type reminder, and no -k option was used, issue the banner. */
|
||||
if ((t->typ == MSG_TYPE || t->typ == MSF_TYPE)
|
||||
&& !DidMsgReminder && !NextMode && !msg_command && !is_queued) {
|
||||
DynamicBuffer buf2;
|
||||
DBufInit(&buf2);
|
||||
DidMsgReminder = 1;
|
||||
if (!DoSubstFromString(DBufValue(&Banner), &buf,
|
||||
if (!DoSubstFromString(DBufValue(&Banner), &buf2,
|
||||
DSEToday, NO_TIME) &&
|
||||
DBufLen(&buf)) {
|
||||
printf("%s\n", DBufValue(&buf));
|
||||
DBufLen(&buf2)) {
|
||||
if (!JSONMode) {
|
||||
printf("%s\n", DBufValue(&buf2));
|
||||
} else {
|
||||
if (JSONLinesEmitted) {
|
||||
printf("},\n");
|
||||
}
|
||||
JSONLinesEmitted++;
|
||||
printf("{\"banner\":\"");
|
||||
remove_trailing_newlines(&buf2);
|
||||
PrintJSONString(DBufValue(&buf2));
|
||||
printf("\"");
|
||||
}
|
||||
}
|
||||
DBufFree(&buf);
|
||||
DBufFree(&buf2);
|
||||
}
|
||||
|
||||
/* If it's NextMode, process as a ADVANCE_MODE-type entry, and issue
|
||||
@@ -1252,7 +1497,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
||||
}
|
||||
|
||||
/* Correct colors */
|
||||
if (UseVTColors) {
|
||||
if (JSONMode || UseVTColors) {
|
||||
if (red == -1 && green == -1 && blue == -1) {
|
||||
if (DefaultColorR != -1 && DefaultColorG != -1 && DefaultColorB != -1) {
|
||||
red = DefaultColorR;
|
||||
@@ -1266,6 +1511,17 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
||||
if (green > 255) green = 255;
|
||||
if (blue > 255) blue = 255;
|
||||
}
|
||||
if (rr) *rr = red;
|
||||
if (gg) *gg = green;
|
||||
if (bb) *bb = blue;
|
||||
|
||||
/* Don't ANSI-colorize JSON output! */
|
||||
if (JSONMode) {
|
||||
is_color = 0;
|
||||
red = -1;
|
||||
green = -1;
|
||||
blue = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Put the substituted string into the substitution buffer */
|
||||
@@ -1414,16 +1670,44 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
||||
/* triggered. Sets *err non-zero in event of an error. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int dse, int *err)
|
||||
int ShouldTriggerReminder(Trigger const *t, TimeTrig const *tim, int dse, int *err)
|
||||
{
|
||||
int r, omit;
|
||||
int calmode = (DoSimpleCalendar || DoCalendar) ? 1 : 0;
|
||||
if (HideCompletedTodos) calmode = 0;
|
||||
|
||||
*err = 0;
|
||||
|
||||
/* Handle the ONCE modifier in the reminder. */
|
||||
if (!IgnoreOnce && t->once !=NO_ONCE && GetOnceDate() == DSEToday)
|
||||
return 0;
|
||||
|
||||
if (dse < DSEToday) return 0;
|
||||
/* TODOs are handled differently */
|
||||
if (t->is_todo && !calmode) {
|
||||
/* Do NOT trigger if TODO has been completed through today (or later) */
|
||||
if (t->complete_through != NO_DATE && t->complete_through >= DSEToday && dse <= t->complete_through) {
|
||||
return 0;
|
||||
}
|
||||
/* 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 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 */
|
||||
} else {
|
||||
/* We're complete as of trigger date */
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (dse < DSEToday) return 0;
|
||||
}
|
||||
|
||||
/* Don't trigger timed reminders if DontIssueAts is true, and if the
|
||||
reminder is for today */
|
||||
@@ -1517,7 +1801,7 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
ensure_satnode_mentions_trigdate(sat_node);
|
||||
|
||||
iter = 0;
|
||||
start = trig->scanfrom;
|
||||
start = get_scanfrom(trig);
|
||||
while (iter++ < MaxSatIter) {
|
||||
dse = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1, 0);
|
||||
if (r) {
|
||||
@@ -1541,6 +1825,8 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
}
|
||||
if (dse == -1) {
|
||||
free_expr_tree(sat_node);
|
||||
LastTrigValid = 0;
|
||||
LastTriggerDate = -1;
|
||||
return E_EXPIRED;
|
||||
}
|
||||
r = evaluate_expression(sat_node, NULL, &v, &nonconst);
|
||||
@@ -1554,12 +1840,12 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
}
|
||||
if ((v.type == INT_TYPE && v.v.val) ||
|
||||
(v.type == STR_TYPE && *v.v.str)) {
|
||||
AdjustTriggerForDuration(trig->scanfrom, dse, trig, tt, 1);
|
||||
AdjustTriggerForDuration(get_scanfrom(trig), dse, trig, tt, 1);
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
int y, m, d;
|
||||
FromDSE(LastTriggerDate, &y, &m, &d);
|
||||
fprintf(ErrFp, "%s(%s): Trig(satisfied) = %s, %d %s, %d",
|
||||
FileName, line_range(LineNoStart, LineNo),
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo),
|
||||
get_day_name(LastTriggerDate % 7),
|
||||
d,
|
||||
get_month_name(m),
|
||||
@@ -1689,7 +1975,7 @@ finished:
|
||||
/* function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
||||
static int ShouldTriggerBasedOnWarn(Trigger const *t, int dse, int *err)
|
||||
{
|
||||
char buffer[VAR_NAME_LEN+32];
|
||||
int i;
|
||||
@@ -1697,6 +1983,32 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
||||
int r, omit;
|
||||
Value v;
|
||||
int lastReturnVal = 0; /* Silence compiler warning */
|
||||
int calmode = (DoSimpleCalendar || DoCalendar) ? 1 : 0;
|
||||
|
||||
/* TODOs are handled differently */
|
||||
if (t->is_todo && !calmode) {
|
||||
/* Do NOT trigger if TODO has been completed through today (or later) */
|
||||
if (t->complete_through != NO_DATE && t->complete_through >= DSEToday) {
|
||||
return 0;
|
||||
}
|
||||
/* 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 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 */
|
||||
} else {
|
||||
/* We're complete as of trigger date */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no proper function exists, barf... */
|
||||
if (UserFuncExists(t->warn) != 1) {
|
||||
|
||||
129
src/dosubst.c
129
src/dosubst.c
@@ -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)
|
||||
{
|
||||
@@ -54,9 +87,11 @@ check_subst_args(UserFunc *f, int n)
|
||||
/* If mode==ADVANCE_MODE, ignore %" but don't add newline */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode)
|
||||
int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int dse, int mode)
|
||||
{
|
||||
int diff = dse - DSEToday;
|
||||
int rdiff = dse - RealToday;
|
||||
int bangdiff = diff;
|
||||
int curtime = MinutesPastMidnight(0);
|
||||
int err, done;
|
||||
int c;
|
||||
@@ -67,12 +102,13 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
char const *pm, *cpm;
|
||||
int tdiff, adiff, mdiff, hdiff;
|
||||
char const *mplu, *hplu, *when, *plu;
|
||||
char const *is, *was;
|
||||
int has_quote = 0;
|
||||
char *ss;
|
||||
char const *expr;
|
||||
char *os;
|
||||
char s[256];
|
||||
char uf[32];
|
||||
char const *substname;
|
||||
char mypm[64];
|
||||
char mycpm[64];
|
||||
char myplu[64];
|
||||
@@ -98,7 +134,8 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
mplu = (mdiff == 1 ? "" : DynamicMplu);
|
||||
hplu = (hdiff == 1 ? "" : DynamicHplu);
|
||||
|
||||
when = (tdiff < 0) ? tr("ago") : tr("from now");
|
||||
when = (tdiff < 0) ? tr("ago") :
|
||||
tr("from now");
|
||||
|
||||
h = tim / 60;
|
||||
min = tim % 60;
|
||||
@@ -108,7 +145,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
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);
|
||||
@@ -122,7 +159,8 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
pm = (h < 12) ? tr("am") : tr("pm");
|
||||
pm = (h < 12) ? tr("am") :
|
||||
tr("pm");
|
||||
}
|
||||
|
||||
hh = (h == 12 || h == 0) ? 12 : h % 12;
|
||||
@@ -135,7 +173,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
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);
|
||||
@@ -149,7 +187,8 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
cpm = (h < 12) ? tr("am") : tr("pm");
|
||||
cpm = (h < 12) ? tr("am") :
|
||||
tr("pm");
|
||||
}
|
||||
chh = (ch == 0 || ch == 12) ? 12 : ch % 12;
|
||||
|
||||
@@ -157,7 +196,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
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);
|
||||
@@ -321,7 +360,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
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) {
|
||||
@@ -334,13 +373,17 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
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)) {
|
||||
@@ -358,7 +401,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
}
|
||||
|
||||
if (diff <= 1) {
|
||||
if (abs(diff) <= 1) {
|
||||
switch(UPPER(c)) {
|
||||
case 'A':
|
||||
case 'B':
|
||||
@@ -373,7 +416,9 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
case 'L':
|
||||
case 'U':
|
||||
case 'V':
|
||||
snprintf(s, sizeof(s), "%s", (diff ? tr("tomorrow") : tr("today")));
|
||||
snprintf(s, sizeof(s), "%s", (diff == 1 ? tr("tomorrow") :
|
||||
diff == -1 ? tr("yesterday") :
|
||||
tr("today")));
|
||||
SHIP_OUT(s);
|
||||
done = 1;
|
||||
break;
|
||||
@@ -384,13 +429,17 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
|
||||
|
||||
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)) {
|
||||
@@ -408,7 +457,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
}
|
||||
if (origtime == NO_TIME) {
|
||||
if ((c >= '0' && c <= '9') || (c == '!')) {
|
||||
if ((c >= '0' && c <= '9')) {
|
||||
Wprint(tr("`%%%c' substitution sequence should not be used without an AT clause"), c);
|
||||
}
|
||||
}
|
||||
@@ -426,7 +475,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
snprintf(s, sizeof(s), "in %d days' time", diff);
|
||||
if (diff > 0) {
|
||||
snprintf(s, sizeof(s), "in %d days' time", diff);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%d days ago", -diff);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
@@ -605,6 +658,12 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
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"));
|
||||
@@ -614,7 +673,8 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
snprintf(s, sizeof(s), "%d %s%s %s", hdiff, tr("hour"), hplu, when);
|
||||
else
|
||||
snprintf(s, sizeof(s), "%d %s%s %s %d %s%s %s", hdiff, tr("hour"), hplu,
|
||||
tr("and"), mdiff, tr("minute"), mplu, when);
|
||||
tr("and"), mdiff,
|
||||
tr("minute"), mplu, when);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
@@ -672,7 +732,26 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
break;
|
||||
|
||||
case '!':
|
||||
snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? tr("is") : tr("was")));
|
||||
case '?':
|
||||
if (c == '!') {
|
||||
is = tr("is");
|
||||
was = tr("was");
|
||||
} else {
|
||||
is = tr("are");
|
||||
was = tr("were");
|
||||
}
|
||||
if (altmode) {
|
||||
bangdiff = rdiff;
|
||||
} else {
|
||||
bangdiff = diff;
|
||||
}
|
||||
if (bangdiff > 0) {
|
||||
snprintf(s, sizeof(s), "%s", is);
|
||||
} else if (bangdiff < 0) {
|
||||
snprintf(s, sizeof(s), "%s", was);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? is : was));
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
|
||||
38
src/err.h
38
src/err.h
@@ -23,25 +23,25 @@
|
||||
#define E_MISS_END 1
|
||||
#define E_MISS_QUOTE 2
|
||||
#define E_OP_STK_OVER 3
|
||||
/* #define E_VA_STK_OVER 4 */
|
||||
#define E_CANT_PARSE_MONTH 4
|
||||
#define E_MISS_RIGHT_PAREN 5
|
||||
#define E_UNDEF_FUNC 6
|
||||
#define E_ILLEGAL_CHAR 7
|
||||
/* #define E_EXPECTING_BINOP 8 */
|
||||
#define E_CANT_PARSE_WKDAY 8
|
||||
#define E_NO_MEM 9
|
||||
#define E_BAD_NUMBER 10
|
||||
/* #define E_OP_STK_UNDER 11 */
|
||||
/* #define E_VA_STK_UNDER 12 */
|
||||
#define E_PUSHV_NO_POP 11
|
||||
#define E_POPV_NO_PUSH 12
|
||||
#define E_CANT_COERCE 13
|
||||
#define E_BAD_TYPE 14
|
||||
#define E_DATE_OVER 15
|
||||
/* #define E_STACK_ERR 16 */
|
||||
#define E_POPF_NO_PUSH 16
|
||||
#define E_DIV_ZERO 17
|
||||
#define E_NOSUCH_VAR 18
|
||||
#define E_EOLN 19
|
||||
#define E_EOF 20
|
||||
#define E_IO_ERR 21
|
||||
/* #define E_LINE_2_LONG 22 */
|
||||
#define E_PUSHF_NO_POP 22
|
||||
#define E_SWERR 23
|
||||
#define E_BAD_DATE 24
|
||||
#define E_2FEW_ARGS 25
|
||||
@@ -76,7 +76,7 @@
|
||||
#define E_DAY_TWICE 52
|
||||
#define E_UNKNOWN_TOKEN 53
|
||||
#define E_SPEC_MON 54
|
||||
/* #define E_2MANY_PART 55 */
|
||||
#define E_TODO_TWICE 55
|
||||
#define E_2MANY_FULL 56
|
||||
#define E_PUSH_NOPOP 57
|
||||
#define E_ERR_READING 58
|
||||
@@ -114,7 +114,7 @@
|
||||
#define E_MISS_EQ 90
|
||||
#define E_MISS_VAR 91
|
||||
#define E_MISS_EXPR 92
|
||||
/* #define M_CANTSET_ACCESS 93 */
|
||||
#define E_COMPLETE_THROUGH_TWICE 93
|
||||
#define M_I_OPTION 94
|
||||
#define E_NOREMINDERS 95
|
||||
#define M_QUEUED 96
|
||||
@@ -129,6 +129,9 @@
|
||||
#define E_REPEATED_ARG 105
|
||||
#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
|
||||
@@ -151,25 +154,25 @@ EXTERN char *ErrMsg[]
|
||||
/* E_MISS_END */ "Missing ']'",
|
||||
/* E_MISS_QUOTE */ "Missing quote",
|
||||
/* E_OP_STK_OVER */ "Expression too complex",
|
||||
/* E_VA_STK_OVER */ "",
|
||||
/* E_CANT_PARSE_MONTH */ "Invalid month name",
|
||||
/* E_MISS_RIGHT_PAREN */ "Missing ')'",
|
||||
/* E_UNDEF_FUNC */ "Undefined function",
|
||||
/* E_ILLEGAL_CHAR */ "Illegal character",
|
||||
/* E_EXPECTING_BINOP */ "Expecting binary operator",
|
||||
/* E_CANT_PARSE_WKDAY*/ "Invalid weekday name",
|
||||
/* E_NO_MEM */ "Out of memory",
|
||||
/* E_BAD_NUMBER */ "Ill-formed number",
|
||||
/* E_OP_STK_UNDER */ "",
|
||||
/* E_VA_STK_UNDER */ "",
|
||||
/* E_PUSHV_NO_POP */ "Warning: PUSH-VARS without matching POP-VARS",
|
||||
/* E_POPV_NO_PUSH */ "POP-VARS without matching PUSH-VARS",
|
||||
/* E_CANT_COERCE */ "Can't coerce",
|
||||
/* E_BAD_TYPE */ "Type mismatch",
|
||||
/* E_DATE_OVER */ "Date overflow",
|
||||
/* E_STACK_ERR */ "",
|
||||
/* E_POPF_NO_PUSH */ "POP-FUNCS without matching PUSH-FUNCS",
|
||||
/* E_DIV_ZERO */ "Division by zero",
|
||||
/* E_NOSUCH_VAR */ "Undefined variable",
|
||||
/* E_EOLN */ "Unexpected end of line",
|
||||
/* E_EOF */ "Unexpected end of file",
|
||||
/* E_IO_ERR */ "I/O error",
|
||||
/* E_LINE_2_LONG */ "",
|
||||
/* E_PUSHF_NO_POP */ "Warning: PUSH-FUNCS without matching POP-FUNCS",
|
||||
/* E_SWERR */ "Internal error",
|
||||
/* E_BAD_DATE */ "Bad date specification",
|
||||
/* E_2FEW_ARGS */ "Not enough arguments",
|
||||
@@ -202,7 +205,7 @@ EXTERN char *ErrMsg[]
|
||||
/* E_DAY_TWICE */ "Day specified twice",
|
||||
/* E_UNKNOWN_TOKEN */ "Unknown token",
|
||||
/* E_SPEC_MON */ "Must specify month in OMIT command",
|
||||
/* E_2MANY_PART */ "",
|
||||
/* E_TODO_TWICE */ "TODO specified twice",
|
||||
/* E_2MANY_FULL */ "Too many full OMITs (max. " STR(MAX_FULL_OMITS) ")",
|
||||
/* E_PUSH_NOPOP */ "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT",
|
||||
/* E_ERR_READING */ "Error reading",
|
||||
@@ -240,7 +243,7 @@ EXTERN char *ErrMsg[]
|
||||
/* E_MISS_EQ */ "Missing '=' sign",
|
||||
/* E_MISS_VAR */ "Missing variable name",
|
||||
/* E_MISS_EXPR */ "Missing expression",
|
||||
/* M_CANTSET_ACCESS */ "",
|
||||
/* E_COMPLETE_THROUGH_TWICE */ "COMPLETE-THROUGH specified twice",
|
||||
/* M_I_OPTION */ "Remind: '-i' option: %s",
|
||||
/* E_NOREMINDERS */ "No reminders.",
|
||||
/* M_QUEUED */ "%d reminder(s) queued for later today.",
|
||||
@@ -255,6 +258,9 @@ EXTERN char *ErrMsg[]
|
||||
/* E_REPEATED_ARG */ "Duplicate argument name",
|
||||
/* 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 */
|
||||
;
|
||||
|
||||
264
src/expr.c
264
src/expr.c
@@ -191,6 +191,7 @@ static int ExprNodesUsed = 0;
|
||||
/* Forward references */
|
||||
static expr_node * parse_expression_aux(char const **e, int *r, Var *locals, int level);
|
||||
static char const *get_operator_name(expr_node *node);
|
||||
static void print_expr_tree(expr_node *node, FILE *fp);
|
||||
|
||||
/* This is super-skanky... we keep track of the currently-executing
|
||||
user-defined function in a global var */
|
||||
@@ -410,13 +411,27 @@ debug_evaluation_unop(Value *ans, int r, Value *v1, char const *fmt, ...)
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int
|
||||
get_var(expr_node *node, Value *ans)
|
||||
get_var(expr_node *node, Value *ans, int *nonconst)
|
||||
{
|
||||
Var *v;
|
||||
char const *str;
|
||||
|
||||
if (node->type == N_SHORT_VAR) {
|
||||
return GetVarValue(node->u.name, ans);
|
||||
str = node->u.name;
|
||||
} else {
|
||||
return GetVarValue(node->u.value.v.str, ans);
|
||||
str = node->u.value.v.str;
|
||||
}
|
||||
v = FindVar(str, 0);
|
||||
if (!v) {
|
||||
Eprint("%s: `%s'", GetErr(E_NOSUCH_VAR), str);
|
||||
return E_NOSUCH_VAR;
|
||||
}
|
||||
v->used_since_set = 1;
|
||||
if (!v->is_constant) {
|
||||
nonconst_debug(*nonconst, tr("Global variable `%s' makes expression non-constant"), str);
|
||||
*nonconst = 1;
|
||||
}
|
||||
return CopyValue(ans, &(v->v));
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -429,7 +444,7 @@ get_var(expr_node *node, Value *ans)
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int
|
||||
get_sysvar(expr_node *node, Value *ans)
|
||||
get_sysvar(expr_node const *node, Value *ans)
|
||||
{
|
||||
if (node->type == N_SHORT_SYSVAR) {
|
||||
return GetSysVar(node->u.name, ans);
|
||||
@@ -474,16 +489,24 @@ eval_builtin(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
return E_2MANY_ARGS;
|
||||
}
|
||||
|
||||
if (FuncRecursionLevel >= MAX_RECURSION_LEVEL) {
|
||||
return E_RECURSIVE;
|
||||
}
|
||||
|
||||
/* If this is a new-style function that knows about expr_nodes,
|
||||
let it evaluate itself */
|
||||
if (f->newfunc) {
|
||||
return node->u.builtin_func->newfunc(node, locals, ans, nonconst);
|
||||
FuncRecursionLevel++;
|
||||
r = node->u.builtin_func->newfunc(node, locals, ans, nonconst);
|
||||
FuncRecursionLevel--;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* It's an old-style function, so we need to simulate the
|
||||
old function call API by building up a bundle of evaluated
|
||||
arguments */
|
||||
info.nargs = node->num_kids;
|
||||
info.nonconst = 0;
|
||||
|
||||
if (info.nargs) {
|
||||
if (info.nargs <= STACK_ARGS_MAX) {
|
||||
@@ -534,11 +557,26 @@ eval_builtin(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
}
|
||||
fprintf(ErrFp, ") => ");
|
||||
}
|
||||
FuncRecursionLevel++;
|
||||
r = f->func(&info);
|
||||
FuncRecursionLevel--;
|
||||
|
||||
/* Propagate non-constness */
|
||||
if (info.nonconst) {
|
||||
nonconst_debug(*nonconst, tr("Non-constant built-in function `%s' makes expression non-constant"), f->name);
|
||||
*nonconst = 1;
|
||||
}
|
||||
if (r == OK) {
|
||||
/* All went well; copy the result destructively */
|
||||
(*ans) = info.retval;
|
||||
|
||||
/* 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"));
|
||||
}
|
||||
*nonconst = 0;
|
||||
}
|
||||
/* Don't allow retval to be destroyed! */
|
||||
info.retval.type = ERR_TYPE;
|
||||
}
|
||||
@@ -656,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];
|
||||
@@ -734,14 +773,24 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
FuncRecursionLevel++;
|
||||
|
||||
if (!f->is_constant) {
|
||||
nonconst_debug(*nonconst, tr("User function `%s' defined in non-constant context makes expression non-constant"), f->name);
|
||||
*nonconst = 1;
|
||||
}
|
||||
/* Add a call to the call stack for better error messages */
|
||||
pushed = push_call(f->filename, f->name, f->lineno, f->lineno_start);
|
||||
|
||||
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) {
|
||||
@@ -792,7 +841,7 @@ evaluate_expression(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int CopyShortStr(Value *ans, expr_node *node)
|
||||
static int CopyShortStr(Value *ans, expr_node const *node)
|
||||
{
|
||||
size_t len = strlen(node->u.name);
|
||||
ans->v.str = malloc(len+1);
|
||||
@@ -853,16 +902,12 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
return CopyValue(ans, &(node->u.value));
|
||||
|
||||
case N_SHORT_VAR:
|
||||
/* Global var? Return it and note non-constant expression */
|
||||
*nonconst = 1;
|
||||
r = get_var(node, ans);
|
||||
r = get_var(node, ans, nonconst);
|
||||
DBG(debug_evaluation(ans, r, "%s", node->u.name));
|
||||
return r;
|
||||
|
||||
case N_VARIABLE:
|
||||
/* Global var? Return it and note non-constant expression */
|
||||
*nonconst = 1;
|
||||
r = get_var(node, ans);
|
||||
r = get_var(node, ans, nonconst);
|
||||
DBG(debug_evaluation(ans, r, "%s", node->u.value.v.str));
|
||||
return r;
|
||||
|
||||
@@ -874,6 +919,7 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
case N_SHORT_SYSVAR:
|
||||
/* System var? Return it and note non-constant expression */
|
||||
nonconst_debug(*nonconst, tr("System variable `$%s' makes expression non-constant"), node->u.name);
|
||||
*nonconst = 1;
|
||||
r = get_sysvar(node, ans);
|
||||
DBG(debug_evaluation(ans, r, "$%s", node->u.name));
|
||||
@@ -881,6 +927,7 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
case N_SYSVAR:
|
||||
/* System var? Return it and note non-constant expression */
|
||||
nonconst_debug(*nonconst, tr("System variable `$%s' makes expression non-constant"), node->u.value.v.str);
|
||||
*nonconst = 1;
|
||||
r = get_sysvar(node, ans);
|
||||
DBG(debug_evaluation(ans, r, "$%s", node->u.value.v.str));
|
||||
@@ -889,6 +936,7 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
case N_BUILTIN_FUNC:
|
||||
/* Built-in function? Evaluate and note non-constant where applicable */
|
||||
if (!node->u.builtin_func->is_constant) {
|
||||
nonconst_debug(*nonconst, tr("Non-constant built-in function `%s' makes expression non-constant"), node->u.builtin_func->name);
|
||||
*nonconst = 1;
|
||||
}
|
||||
return eval_builtin(node, locals, ans, nonconst);
|
||||
@@ -1795,6 +1843,78 @@ expr_node * free_expr_tree(expr_node *node)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* clone_expr_tree */
|
||||
/* */
|
||||
/* Clone an entire expr_tree. The clone shares no memory */
|
||||
/* with the original. Returns NULL and sets *r on failure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
expr_node * clone_expr_tree(expr_node const *src, int *r)
|
||||
{
|
||||
int rc;
|
||||
expr_node *dest = alloc_expr_node(r);
|
||||
if (!dest) return NULL;
|
||||
|
||||
dest->type = src->type;
|
||||
dest->num_kids = src->num_kids;
|
||||
switch(dest->type) {
|
||||
case N_FREE:
|
||||
case N_ERROR:
|
||||
*r = E_SWERR;
|
||||
free_expr_tree(dest);
|
||||
return NULL;
|
||||
|
||||
case N_CONSTANT:
|
||||
case N_VARIABLE:
|
||||
case N_SYSVAR:
|
||||
case N_USER_FUNC:
|
||||
rc = CopyValue(&(dest->u.value), &(src->u.value));
|
||||
if (rc != OK) {
|
||||
*r = rc;
|
||||
free_expr_tree(dest);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case N_SHORT_STR:
|
||||
case N_SHORT_VAR:
|
||||
case N_SHORT_SYSVAR:
|
||||
case N_SHORT_USER_FUNC:
|
||||
strcpy(dest->u.name, src->u.name);
|
||||
break;
|
||||
|
||||
case N_LOCAL_VAR:
|
||||
dest->u.arg = src->u.arg;
|
||||
break;
|
||||
|
||||
case N_BUILTIN_FUNC:
|
||||
dest->u.builtin_func = src->u.builtin_func;
|
||||
break;
|
||||
|
||||
case N_OPERATOR:
|
||||
dest->u.operator_func = src->u.operator_func;
|
||||
break;
|
||||
}
|
||||
|
||||
if (src->child) {
|
||||
dest->child = clone_expr_tree(src->child, r);
|
||||
if (!dest->child) {
|
||||
free_expr_tree(dest);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (src->sibling) {
|
||||
dest->sibling = clone_expr_tree(src->sibling, r);
|
||||
if (!dest->sibling) {
|
||||
free_expr_tree(dest);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* set_long_name - set a long name in an expr_node */
|
||||
@@ -2144,8 +2264,7 @@ static int make_atom(expr_node *atom, Var *locals)
|
||||
/* */
|
||||
/* Parse an atom. */
|
||||
/* */
|
||||
/* ATOM: '+' ATOM | */
|
||||
/* '(' EXPR ')' | */
|
||||
/* ATOM: '(' EXPR ')' | */
|
||||
/* CONSTANT | */
|
||||
/* VAR | */
|
||||
/* FUNCTION_CALL */
|
||||
@@ -2159,18 +2278,6 @@ static expr_node *parse_atom(char const **e, int *r, Var *locals, int level)
|
||||
*r = PEEK_TOKEN();
|
||||
if (*r != OK) return NULL;
|
||||
|
||||
/* Ignore unary-plus operators */
|
||||
while (TOKEN_IS("+")) {
|
||||
*r = GET_TOKEN();
|
||||
if (*r != OK) {
|
||||
return NULL;
|
||||
}
|
||||
*r = PEEK_TOKEN();
|
||||
if (*r != OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (TOKEN_IS("(")) {
|
||||
/* Parenthesiszed expession: '(' EXPR ')' */
|
||||
|
||||
@@ -2238,6 +2345,7 @@ static expr_node *parse_atom(char const **e, int *r, Var *locals, int level)
|
||||
/* */
|
||||
/* FACTOR_EXP: '-' FACTOR_EXP | */
|
||||
/* '!' FACTOR_EXP | */
|
||||
/* '+' FACTOR_EXP */
|
||||
/* ATOM */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -2251,11 +2359,13 @@ static expr_node *parse_factor(char const **e, int *r, Var *locals, int level)
|
||||
if (*r != OK) {
|
||||
return NULL;
|
||||
}
|
||||
if (TOKEN_IS("!") || TOKEN_IS("-")) {
|
||||
if (TOKEN_IS("!") || TOKEN_IS("-") || TOKEN_IS("+")) {
|
||||
if (TOKEN_IS("!")) {
|
||||
op = '!';
|
||||
} else {
|
||||
} else if (TOKEN_IS("-")) {
|
||||
op = '-';
|
||||
} else {
|
||||
op = '+';
|
||||
}
|
||||
/* Pull off the peeked token */
|
||||
GET_TOKEN();
|
||||
@@ -2264,6 +2374,20 @@ static expr_node *parse_factor(char const **e, int *r, Var *locals, int level)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Ignore unary plus operator */
|
||||
if (op == '+') {
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Optimize '-' or '!' followed by integer constant */
|
||||
if (node->type == N_CONSTANT &&node->u.value.type == INT_TYPE) {
|
||||
if (op == '-') {
|
||||
node->u.value.v.val = - node->u.value.v.val;
|
||||
} else {
|
||||
node->u.value.v.val = ! node->u.value.v.val;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
factor_node = alloc_expr_node(r);
|
||||
if (!factor_node) {
|
||||
free_expr_tree(node);
|
||||
@@ -2569,7 +2693,7 @@ static expr_node *parse_expression_aux(char const **e, int *r, Var *locals, int
|
||||
/* */
|
||||
/* parse_expression - top-level expression-parsing function */
|
||||
/* */
|
||||
/* *e points to string being parsed; *e will be updates */
|
||||
/* *e points to string being parsed; *e will be updated */
|
||||
/* r points to a location for the return code (OK or an error) */
|
||||
/* locals is an array of local function arguments, if any */
|
||||
/* */
|
||||
@@ -2605,36 +2729,38 @@ expr_node *parse_expression(char const **e, int *r, Var *locals)
|
||||
fprintf(ErrFp, " Unparsed: %s\n", *e);
|
||||
}
|
||||
}
|
||||
if (*r == E_EXPECT_COMMA ||
|
||||
*r == E_MISS_RIGHT_PAREN ||
|
||||
*r == E_EXPECTING_EOL ||
|
||||
*r == E_2MANY_ARGS ||
|
||||
*r == E_2FEW_ARGS ||
|
||||
*r == E_PARSE_ERR ||
|
||||
*r == E_EOLN ||
|
||||
*r == E_BAD_NUMBER ||
|
||||
*r == E_BAD_DATE ||
|
||||
*r == E_BAD_TIME ||
|
||||
*r == E_ILLEGAL_CHAR) {
|
||||
end_of_expr = find_end_of_expr(orig);
|
||||
while (**e && isempty(**e)) {
|
||||
(*e)++;
|
||||
}
|
||||
while (*orig && ((orig < end_of_expr) || (orig <= *e))) {
|
||||
if (*orig == '\n') {
|
||||
fprintf(ErrFp, " ");
|
||||
} else {
|
||||
fprintf(ErrFp, "%c", *orig);
|
||||
if (!SuppressErrorOutputInCatch) {
|
||||
if (*r == E_EXPECT_COMMA ||
|
||||
*r == E_MISS_RIGHT_PAREN ||
|
||||
*r == E_EXPECTING_EOL ||
|
||||
*r == E_2MANY_ARGS ||
|
||||
*r == E_2FEW_ARGS ||
|
||||
*r == E_PARSE_ERR ||
|
||||
*r == E_EOLN ||
|
||||
*r == E_BAD_NUMBER ||
|
||||
*r == E_BAD_DATE ||
|
||||
*r == E_BAD_TIME ||
|
||||
*r == E_ILLEGAL_CHAR) {
|
||||
end_of_expr = find_end_of_expr(orig);
|
||||
while (**e && isempty(**e)) {
|
||||
(*e)++;
|
||||
}
|
||||
orig++;
|
||||
while (*orig && ((orig < end_of_expr) || (orig <= *e))) {
|
||||
if (*orig == '\n') {
|
||||
fprintf(ErrFp, " ");
|
||||
} else {
|
||||
fprintf(ErrFp, "%c", *orig);
|
||||
}
|
||||
orig++;
|
||||
}
|
||||
fprintf(ErrFp, "\n");
|
||||
orig = o2;
|
||||
while (*orig && (orig < *e || isspace(*orig))) {
|
||||
orig++;
|
||||
fprintf(ErrFp, " ");
|
||||
}
|
||||
fprintf(ErrFp, "^-- %s\n", tr("here"));
|
||||
}
|
||||
fprintf(ErrFp, "\n");
|
||||
orig = o2;
|
||||
while (*orig && (orig < *e || isspace(*orig))) {
|
||||
orig++;
|
||||
fprintf(ErrFp, " ");
|
||||
}
|
||||
fprintf(ErrFp, "^-- %s\n", tr("here"));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -2666,7 +2792,7 @@ static void print_kids(expr_node *node, FILE *fp)
|
||||
/* file. Used for debugging (the "-ds" flag.) */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void print_expr_tree(expr_node *node, FILE *fp)
|
||||
static void print_expr_tree(expr_node *node, FILE *fp)
|
||||
{
|
||||
if (!node) {
|
||||
return;
|
||||
@@ -2750,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. */
|
||||
/* */
|
||||
@@ -2915,7 +3061,7 @@ int CopyValue(Value *dest, const Value *src)
|
||||
/* 4:00PM */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ParseLiteralTime(char const **s, int *tim)
|
||||
static int ParseLiteralTime(char const **s, int *tim)
|
||||
{
|
||||
int h=0;
|
||||
int m=0;
|
||||
|
||||
214
src/files.c
214
src/files.c
@@ -20,6 +20,7 @@
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef TM_IN_SYS_TIME
|
||||
#include <sys/time.h>
|
||||
@@ -40,6 +41,13 @@
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
#ifdef USE_READLINE
|
||||
#include <readline/readline.h>
|
||||
#endif
|
||||
#ifdef USE_READLINE_HISTORY
|
||||
#include <readline/history.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Convenient macros for closing files */
|
||||
#define FCLOSE(fp) ((((fp)!=stdin)) ? (fclose(fp),(fp)=NULL) : ((fp)=NULL))
|
||||
@@ -79,18 +87,27 @@ typedef struct {
|
||||
FilenameChain *chain;
|
||||
int LineNo;
|
||||
int LineNoStart;
|
||||
unsigned int IfFlags;
|
||||
int NumIfs;
|
||||
int IfLinenos[IF_NEST];
|
||||
int base_if_pointer;
|
||||
long offset;
|
||||
CachedLine *CLine;
|
||||
int ownedByMe;
|
||||
} IncludeStruct;
|
||||
|
||||
typedef struct fn_entry {
|
||||
struct hash_link link;
|
||||
char const *fname;
|
||||
} FilenameHashEntry;
|
||||
|
||||
/* A hash table to hold unique copies of all the filenames we process */
|
||||
static hash_table FilenameHashTable;
|
||||
|
||||
static CachedFile *CachedFiles = (CachedFile *) NULL;
|
||||
static CachedLine *CLine = (CachedLine *) NULL;
|
||||
static DirectoryFilenameChain *CachedDirectoryChains = NULL;
|
||||
|
||||
/* Current filename */
|
||||
static char const *FileName = NULL;
|
||||
|
||||
static FILE *fp;
|
||||
|
||||
static IncludeStruct IStack[INCLUDE_NEST];
|
||||
@@ -104,6 +121,67 @@ static int CheckSafetyAux (struct stat *statbuf);
|
||||
static int PopFile (void);
|
||||
static int IncludeCmd(char const *);
|
||||
|
||||
static unsigned int FnHashFunc(void const *x)
|
||||
{
|
||||
FilenameHashEntry const *e = (FilenameHashEntry const *) x;
|
||||
return HashVal_preservecase(e->fname);
|
||||
}
|
||||
|
||||
static int FnCompareFunc(void const *a, void const *b)
|
||||
{
|
||||
FilenameHashEntry const *e1 = (FilenameHashEntry const *) a;
|
||||
FilenameHashEntry const *e2 = (FilenameHashEntry const *) b;
|
||||
return strcmp(e1->fname, e2->fname);
|
||||
}
|
||||
|
||||
void InitFiles(void)
|
||||
{
|
||||
if (hash_table_init(&FilenameHashTable, offsetof(FilenameHashEntry, link),
|
||||
FnHashFunc, FnCompareFunc) < 0) {
|
||||
fprintf(ErrFp, "Unable to initialize filename hash table: Out of memory. Exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
#ifdef USE_READLINE_HISTORY
|
||||
using_history();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetCurrentFilename(char const *fname)
|
||||
{
|
||||
FilenameHashEntry *e;
|
||||
FilenameHashEntry candidate;
|
||||
candidate.fname = fname;
|
||||
|
||||
e = (FilenameHashEntry *) hash_table_find(&FilenameHashTable, &candidate);
|
||||
if (!e) {
|
||||
e = NEW(FilenameHashEntry);
|
||||
if (!e) {
|
||||
fprintf(ErrFp, "Out of Memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
e->fname = strdup(fname);
|
||||
if (!e->fname) {
|
||||
fprintf(ErrFp, "Out of Memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
hash_table_insert(&FilenameHashTable, e);
|
||||
}
|
||||
FileName = e->fname;
|
||||
}
|
||||
|
||||
char const *GetCurrentFilename(void)
|
||||
{
|
||||
if (FileName) {
|
||||
if (!strcmp(FileName, "-")) {
|
||||
return "-stdin-";
|
||||
} else {
|
||||
return FileName;
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
got_a_fresh_line(void)
|
||||
{
|
||||
@@ -111,17 +189,14 @@ got_a_fresh_line(void)
|
||||
WarnedAboutImplicit = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +225,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);
|
||||
}
|
||||
|
||||
@@ -215,6 +290,11 @@ static int ReadLineFromFile(int use_pclose)
|
||||
int l;
|
||||
char copy_buffer[4096];
|
||||
size_t n;
|
||||
int force_eof = 0;
|
||||
|
||||
#ifdef USE_READLINE
|
||||
int read_some = 0;
|
||||
#endif
|
||||
|
||||
DynamicBuffer buf;
|
||||
|
||||
@@ -223,17 +303,51 @@ static int ReadLineFromFile(int use_pclose)
|
||||
|
||||
LineNoStart = LineNo+1;
|
||||
while(fp) {
|
||||
#ifdef USE_READLINE
|
||||
if (fileno(fp) == STDIN_FILENO && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
|
||||
char *lin;
|
||||
if (should_ignore_line()) {
|
||||
if (read_some) {
|
||||
lin = readline("Rem...? ");
|
||||
} else {
|
||||
lin = readline("Remind? ");
|
||||
}
|
||||
} else {
|
||||
if (read_some) {
|
||||
lin = readline("Rem...> ");
|
||||
} else {
|
||||
lin = readline("Remind> ");
|
||||
}
|
||||
}
|
||||
if (lin) {
|
||||
read_some = 1;
|
||||
DBufFree(&buf);
|
||||
if (DBufPuts(&buf, lin) != OK) {
|
||||
free(lin);
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
free(lin);
|
||||
force_eof = 0;
|
||||
} else {
|
||||
force_eof = 1;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
if (DBufGets(&buf, fp) != OK) {
|
||||
DBufFree(&LineBuffer);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
#ifdef USE_READLINE
|
||||
}
|
||||
#endif
|
||||
LineNo++;
|
||||
if (ferror(fp)) {
|
||||
DBufFree(&buf);
|
||||
DBufFree(&LineBuffer);
|
||||
return E_IO_ERR;
|
||||
}
|
||||
if (feof(fp)) {
|
||||
if (feof(fp) || force_eof) {
|
||||
if (use_pclose) {
|
||||
PCLOSE(fp);
|
||||
} else {
|
||||
@@ -295,6 +409,9 @@ static int ReadLineFromFile(int use_pclose)
|
||||
CurLine = DBufValue(&LineBuffer);
|
||||
}
|
||||
|
||||
#ifdef USE_READLINE_HISTORY
|
||||
add_history(CurLine);
|
||||
#endif
|
||||
got_a_fresh_line();
|
||||
clear_callstack();
|
||||
if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
|
||||
@@ -313,7 +430,7 @@ static int ReadLineFromFile(int use_pclose)
|
||||
/* ShouldCache is 1, cache the file */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int OpenFile(char const *fname)
|
||||
static int OpenFile(char const *fname)
|
||||
{
|
||||
CachedFile *h = CachedFiles;
|
||||
int r;
|
||||
@@ -334,7 +451,7 @@ int OpenFile(char const *fname)
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
CLine = h->cache;
|
||||
STRSET(FileName, fname);
|
||||
SetCurrentFilename(fname);
|
||||
LineNo = 0;
|
||||
LineNoStart = 0;
|
||||
if (!h->ownedByMe) {
|
||||
@@ -359,7 +476,9 @@ 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");
|
||||
@@ -381,7 +500,7 @@ 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;
|
||||
@@ -389,7 +508,7 @@ int OpenFile(char const *fname)
|
||||
}
|
||||
}
|
||||
}
|
||||
STRSET(FileName, fname);
|
||||
SetCurrentFilename(fname);
|
||||
LineNo = 0;
|
||||
LineNoStart = 0;
|
||||
if (FileName) return OK; else return E_NO_MEM;
|
||||
@@ -546,15 +665,9 @@ static int NextChainedFile(IncludeStruct *i)
|
||||
static int PopFile(void)
|
||||
{
|
||||
IncludeStruct *i;
|
||||
int j;
|
||||
|
||||
if (!Hush && NumIfs) {
|
||||
Eprint("%s", GetErr(E_MISS_ENDIF));
|
||||
for (j=NumIfs-1; j >=0; j--) {
|
||||
fprintf(ErrFp, tr("%s(%d): IF without ENDIF"), FileName, IfLinenos[j]);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
}
|
||||
pop_excess_ifs(FileName);
|
||||
|
||||
if (!IStackPtr) return E_EOF;
|
||||
i = &IStack[IStackPtr-1];
|
||||
|
||||
@@ -574,12 +687,10 @@ static int PopFile(void)
|
||||
|
||||
LineNo = i->LineNo;
|
||||
LineNoStart = i->LineNoStart;
|
||||
IfFlags = i->IfFlags;
|
||||
memcpy(IfLinenos, i->IfLinenos, IF_NEST);
|
||||
NumIfs = i->NumIfs;
|
||||
set_base_if_pointer(i->base_if_pointer);
|
||||
CLine = i->CLine;
|
||||
fp = NULL;
|
||||
STRSET(FileName, i->filename);
|
||||
SetCurrentFilename(i->filename);
|
||||
if (!i->ownedByMe) {
|
||||
RunDisabled |= RUN_NOTOWNER;
|
||||
} else {
|
||||
@@ -590,7 +701,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;
|
||||
@@ -599,7 +710,6 @@ static int PopFile(void)
|
||||
if (fp != stdin)
|
||||
(void) fseek(fp, i->offset, 0); /* Trust that it works... */
|
||||
}
|
||||
free((char *) i->filename);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -904,21 +1014,11 @@ static int IncludeCmd(char const *cmd)
|
||||
}
|
||||
fname = DBufValue(&buf);
|
||||
|
||||
if (FileName) {
|
||||
i->filename = StrDup(FileName);
|
||||
if (!i->filename) {
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
} else {
|
||||
i->filename = NULL;
|
||||
}
|
||||
i->filename = FileName;
|
||||
i->ownedByMe = 1;
|
||||
i->LineNo = LineNo;
|
||||
i->LineNoStart = LineNo;
|
||||
i->NumIfs = NumIfs;
|
||||
i->IfFlags = IfFlags;
|
||||
memcpy(i->IfLinenos, IfLinenos, IF_NEST);
|
||||
i->base_if_pointer = get_base_if_pointer();
|
||||
i->CLine = CLine;
|
||||
i->offset = -1L;
|
||||
i->chain = NULL;
|
||||
@@ -927,8 +1027,8 @@ static int IncludeCmd(char const *cmd)
|
||||
FCLOSE(fp);
|
||||
}
|
||||
IStackPtr++;
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
|
||||
set_base_if_pointer(get_if_pointer());
|
||||
|
||||
/* If the file is cached, use it */
|
||||
h = CachedFiles;
|
||||
@@ -939,7 +1039,7 @@ static int IncludeCmd(char const *cmd)
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
CLine = h->cache;
|
||||
STRSET(FileName, fname);
|
||||
SetCurrentFilename(fname);
|
||||
DBufFree(&buf);
|
||||
LineNo = 0;
|
||||
LineNoStart = 0;
|
||||
@@ -991,7 +1091,7 @@ static int IncludeCmd(char const *cmd)
|
||||
CLine = CachedFiles->cache;
|
||||
LineNo = 0;
|
||||
LineNoStart = 0;
|
||||
STRSET(FileName, fname);
|
||||
SetCurrentFilename(fname);
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
}
|
||||
@@ -1020,17 +1120,10 @@ int IncludeFile(char const *fname)
|
||||
if (IStackPtr >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
if (FileName) {
|
||||
i->filename = StrDup(FileName);
|
||||
if (!i->filename) return E_NO_MEM;
|
||||
} else {
|
||||
i->filename = NULL;
|
||||
}
|
||||
i->filename = FileName;
|
||||
i->LineNo = LineNo;
|
||||
i->LineNoStart = LineNoStart;
|
||||
i->NumIfs = NumIfs;
|
||||
i->IfFlags = IfFlags;
|
||||
memcpy(i->IfLinenos, IfLinenos, IF_NEST);
|
||||
i->base_if_pointer = get_base_if_pointer();
|
||||
i->CLine = CLine;
|
||||
i->offset = -1L;
|
||||
i->chain = NULL;
|
||||
@@ -1045,8 +1138,7 @@ int IncludeFile(char const *fname)
|
||||
}
|
||||
|
||||
IStackPtr++;
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
set_base_if_pointer(get_if_pointer());
|
||||
|
||||
#ifdef HAVE_GLOB
|
||||
/* If it's a directory, set up the glob chain here. */
|
||||
@@ -1110,7 +1202,7 @@ int IncludeFile(char const *fname)
|
||||
int GetAccessDate(char const *file)
|
||||
{
|
||||
struct stat statbuf;
|
||||
struct tm *t1;
|
||||
struct tm const *t1;
|
||||
|
||||
if (stat(file, &statbuf)) return -1;
|
||||
t1 = localtime(&(statbuf.st_atime));
|
||||
|
||||
600
src/funcs.c
600
src/funcs.c
File diff suppressed because it is too large
Load Diff
@@ -35,6 +35,10 @@ EXTERN FILE *ErrFp;
|
||||
|
||||
#define MINUTES_PER_DAY 1440
|
||||
|
||||
#define TODOS_AND_EVENTS 0
|
||||
#define ONLY_TODOS 1
|
||||
#define ONLY_EVENTS 2
|
||||
|
||||
#define DaysInYear(y) (((y) % 4) ? 365 : ((!((y) % 100) && ((y) % 400)) ? 365 : 366 ))
|
||||
#define IsLeapYear(y) (((y) % 4) ? 0 : ((!((y) % 100) && ((y) % 400)) ? 0 : 1 ))
|
||||
#define DaysInMonth(m, y) ((m) != 1 ? MonthDays[m] : 28 + IsLeapYear(y))
|
||||
@@ -52,6 +56,8 @@ EXTERN int FreshLine;
|
||||
EXTERN int WarnedAboutImplicit;
|
||||
EXTERN uid_t TrustedUsers[MAX_TRUSTED_USERS];
|
||||
|
||||
EXTERN INIT( int JSONMode, 0);
|
||||
EXTERN INIT( int JSONLinesEmitted, 0);
|
||||
EXTERN INIT( int MaxLateMinutes, 0);
|
||||
EXTERN INIT( int NumTrustedUsers, 0);
|
||||
EXTERN INIT( char const *MsgCommand, NULL);
|
||||
@@ -61,6 +67,7 @@ EXTERN INIT( int DebugFlag, 0);
|
||||
EXTERN INIT( int DoCalendar, 0);
|
||||
EXTERN INIT( int DoSimpleCalendar, 0);
|
||||
EXTERN INIT( int DoSimpleCalDelta, 0);
|
||||
EXTERN INIT( int HideCompletedTodos, 0);
|
||||
EXTERN INIT( int DoPrefixLineNo, 0);
|
||||
EXTERN INIT( int MondayFirst, 0);
|
||||
EXTERN INIT( int AddBlankLines, 1);
|
||||
@@ -72,6 +79,7 @@ EXTERN INIT( int CalMonths, 0);
|
||||
EXTERN INIT( char const *CalType, "none");
|
||||
EXTERN INIT( int Hush, 0);
|
||||
EXTERN INIT( int NextMode, 0);
|
||||
EXTERN INIT( int TodoFilter, TODOS_AND_EVENTS);
|
||||
EXTERN INIT( int InfiniteDelta, 0);
|
||||
EXTERN INIT( int DefaultTDelta, 0);
|
||||
EXTERN INIT( int DefaultDelta, NO_DELTA);
|
||||
@@ -113,14 +121,10 @@ EXTERN INIT( int SynthesizeTags, 0);
|
||||
EXTERN INIT( int ScFormat, SC_AMPM);
|
||||
EXTERN INIT( int MaxSatIter, 1000);
|
||||
EXTERN INIT( int MaxStringLen, MAX_STR_LEN);
|
||||
EXTERN INIT( char *FileName, NULL);
|
||||
EXTERN INIT( int UseStdin, 0);
|
||||
EXTERN INIT( int PurgeMode, 0);
|
||||
EXTERN INIT( int PurgeIncludeDepth, 0);
|
||||
EXTERN INIT( FILE *PurgeFP, NULL);
|
||||
EXTERN INIT( int NumIfs, 0);
|
||||
EXTERN INIT( unsigned int IfFlags, 0);
|
||||
EXTERN INIT( int IfLinenos[IF_NEST], {0});
|
||||
EXTERN INIT( int LastTrigValid, 0);
|
||||
EXTERN Trigger LastTrigger;
|
||||
EXTERN TimeTrig LastTimeTrig;
|
||||
@@ -143,6 +147,9 @@ EXTERN INIT( int UseTrueColors, 0);
|
||||
EXTERN INIT( int TerminalBackground, TERMINAL_BACKGROUND_UNKNOWN);
|
||||
EXTERN INIT( int DedupeReminders, 0);
|
||||
|
||||
/* Suppress ALL error output during a catch() */
|
||||
EXTERN INIT( int SuppressErrorOutputInCatch, 0);
|
||||
|
||||
/* Latitude and longitude */
|
||||
EXTERN INIT( int LatDeg, 0);
|
||||
EXTERN INIT( int LatMin, 0);
|
||||
@@ -244,3 +251,6 @@ EXTERN int SuppressLRM
|
||||
|
||||
/* Translatable messages */
|
||||
extern char const *translatables[];
|
||||
|
||||
/* Array for "folding" years to similar years */
|
||||
extern int FoldArray[2][7];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HASHTAB_STATS.C */
|
||||
/* HASHTAB.C */
|
||||
/* */
|
||||
/* Implementation of hash table. */
|
||||
/* */
|
||||
@@ -99,8 +99,8 @@ static size_t bucket_choices[] = {
|
||||
int
|
||||
hash_table_init(hash_table *t,
|
||||
size_t link_offset,
|
||||
unsigned int (*hashfunc)(void *x),
|
||||
int (*compare)(void *a, void *b))
|
||||
unsigned int (*hashfunc)(void const *x),
|
||||
int (*compare)(void const *a, void const *b))
|
||||
{
|
||||
t->bucket_choice_index = 0;
|
||||
t->num_entries = 0;
|
||||
@@ -141,7 +141,7 @@ hash_table_free(hash_table *t)
|
||||
* \return The number of items in the hash table
|
||||
*/
|
||||
size_t
|
||||
hash_table_num_entries(hash_table *t)
|
||||
hash_table_num_entries(hash_table const *t)
|
||||
{
|
||||
return t->num_entries;
|
||||
}
|
||||
@@ -154,7 +154,7 @@ hash_table_num_entries(hash_table *t)
|
||||
* \return The number of buckets in the hash table
|
||||
*/
|
||||
size_t
|
||||
hash_table_num_buckets(hash_table *t)
|
||||
hash_table_num_buckets(hash_table const *t)
|
||||
{
|
||||
if (t->bucket_choice_index >= NUM_BUCKET_CHOICES) {
|
||||
return 0;
|
||||
@@ -321,7 +321,7 @@ hash_table_find(hash_table *t, void *candidate)
|
||||
*
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
static int
|
||||
hash_table_delete_helper(hash_table *t, void *item, int resize_ok)
|
||||
{
|
||||
if (!item) {
|
||||
|
||||
@@ -34,8 +34,8 @@ typedef struct {
|
||||
size_t num_entries; /**< Number of entries in the hash table */
|
||||
size_t hash_link_offset; /**< Offset of the struct hash_link in the container */
|
||||
void **buckets; /**< Array of buckets */
|
||||
unsigned int (*hashfunc)(void *x); /**< Pointer to the hashing function */
|
||||
int (*compare)(void *a, void *b); /**< Pointer to the comparison function */
|
||||
unsigned int (*hashfunc)(void const *x); /**< Pointer to the hashing function */
|
||||
int (*compare)(void const *a, void const *b); /**< Pointer to the comparison function */
|
||||
} hash_table;
|
||||
|
||||
/**
|
||||
@@ -56,11 +56,11 @@ struct hash_table_stats {
|
||||
|
||||
int hash_table_init(hash_table *t,
|
||||
size_t link_offset,
|
||||
unsigned int (*hashfunc)(void *x),
|
||||
int (*compare)(void *a, void *b));
|
||||
unsigned int (*hashfunc)(void const *x),
|
||||
int (*compare)(void const *a, void const *b));
|
||||
void hash_table_free(hash_table *t);
|
||||
size_t hash_table_num_entries(hash_table *t);
|
||||
size_t hash_table_num_buckets(hash_table *t);
|
||||
size_t hash_table_num_entries(hash_table const *t);
|
||||
size_t hash_table_num_buckets(hash_table const *t);
|
||||
size_t hash_table_chain_len(hash_table *t, size_t i);
|
||||
int hash_table_insert(hash_table *t, void *item);
|
||||
void *hash_table_find(hash_table *t, void *candidate);
|
||||
@@ -68,7 +68,6 @@ int hash_table_delete(hash_table *t, void *item);
|
||||
int hash_table_delete_no_resize(hash_table *t, void *item);
|
||||
void *hash_table_next(hash_table *t, void *cur);
|
||||
void hash_table_dump_stats(hash_table *t, FILE *fp);
|
||||
void hash_table_get_stats(hash_table *t, struct hash_table_stats *stat);
|
||||
|
||||
/**
|
||||
* \brief Iterate over all items in a hash table
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
static void hash_table_get_stats(hash_table *t, struct hash_table_stats *stat);
|
||||
|
||||
/**
|
||||
* \brief Dump hash table statistics to a stdio FILE
|
||||
*
|
||||
@@ -53,7 +55,7 @@ hash_table_dump_stats(hash_table *t, FILE *fp)
|
||||
* \param t A pointer to a hash_table object
|
||||
* \param stat A pointer to a hash_table_stats object that will be filled in
|
||||
*/
|
||||
void
|
||||
static void
|
||||
hash_table_get_stats(hash_table *t, struct hash_table_stats *stat)
|
||||
{
|
||||
size_t n = hash_table_num_buckets(t);
|
||||
|
||||
10
src/hbcal.c
10
src/hbcal.c
@@ -70,6 +70,8 @@ static char MaxMonLen[] = {
|
||||
|
||||
static char HebIsLeap[] = {0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1};
|
||||
|
||||
static long DaysToHebYear(int y);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* RoshHashana */
|
||||
@@ -78,7 +80,7 @@ static char HebIsLeap[] = {0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1};
|
||||
/* Hebrew year. (ie, 5751, not 1990) */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int RoshHashana(int i)
|
||||
static int RoshHashana(int i)
|
||||
{
|
||||
long j;
|
||||
j = DaysToHebYear(i-3744) - CORRECTION;
|
||||
@@ -93,7 +95,7 @@ int RoshHashana(int i)
|
||||
/* from new moon before Tishrey 1 5701. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
long DaysToHebYear(int y)
|
||||
static long DaysToHebYear(int y)
|
||||
{
|
||||
long m, nm, dw, s, l;
|
||||
|
||||
@@ -126,7 +128,7 @@ long DaysToHebYear(int y)
|
||||
/* */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DaysInHebYear(int y)
|
||||
static int DaysInHebYear(int y)
|
||||
{
|
||||
long thisyear, nextyear;
|
||||
|
||||
@@ -143,7 +145,7 @@ int DaysInHebYear(int y)
|
||||
/* given the LENGTH of the Hebrew year. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char const *DaysInHebMonths(int ylen)
|
||||
static char const *DaysInHebMonths(int ylen)
|
||||
{
|
||||
static char monlen[14] =
|
||||
{30, 29, 30, 29, 30, 0, 29, 30, 29, 30, 29, 30, 29, 29};
|
||||
|
||||
236
src/ifelse.c
Normal file
236
src/ifelse.c
Normal file
@@ -0,0 +1,236 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* IFELSE.C */
|
||||
/* */
|
||||
/* Logic for tracking the state of the IF... ELSE... ENDIF */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
/* Allow up to 64 levels if IF...ELSE nesting across all files */
|
||||
#define IF_NEST 64
|
||||
|
||||
/* Points to the next unused IF entry structure */
|
||||
static int if_pointer = 0;
|
||||
|
||||
/* The base pointer for the current file */
|
||||
static int base_pointer = 0;
|
||||
|
||||
/* True if a "RETURN" statement was encountered in current file */
|
||||
static int return_encountered = 0;
|
||||
|
||||
/*
|
||||
* The current state of the IF...ELSE...ENDIF context is stored in
|
||||
* an array of "ifentry" objects, from the outermost to the
|
||||
* innermost.
|
||||
*
|
||||
* The if_true element is true of the IF expression was true; false
|
||||
* otherwise.
|
||||
*
|
||||
* The before_else element is true if the current line is after
|
||||
* the IF but before any ELSE; false otherwise.
|
||||
*
|
||||
* The was_constant element is true if the IF expression was constant.
|
||||
*
|
||||
* Each time a new file is INCLUDed, we reset the base pointer to the
|
||||
* current location of the if_pointer.
|
||||
*/
|
||||
|
||||
typedef struct ifentry_struct {
|
||||
int lineno;
|
||||
unsigned char if_true;
|
||||
unsigned char before_else;
|
||||
unsigned char was_constant;
|
||||
} ifentry;
|
||||
|
||||
static ifentry IfArray[IF_NEST];
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* push_if - push an if entry onto the stack. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int
|
||||
push_if(int is_true, int was_constant)
|
||||
{
|
||||
if (if_pointer >= IF_NEST) {
|
||||
return E_NESTED_IF;
|
||||
}
|
||||
IfArray[if_pointer].if_true = is_true;
|
||||
IfArray[if_pointer].before_else = 1;
|
||||
IfArray[if_pointer].was_constant = was_constant;
|
||||
IfArray[if_pointer].lineno = LineNo;
|
||||
if_pointer++;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* if_stack_full - returns OK or E_NESTED_IF */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int
|
||||
if_stack_full(void)
|
||||
{
|
||||
if (if_pointer >= IF_NEST) {
|
||||
return E_NESTED_IF;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* encounter_else - note that the most-recently-pushed IF */
|
||||
/* has encountered an ELSE */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int
|
||||
encounter_else(void)
|
||||
{
|
||||
if (if_pointer <= base_pointer) {
|
||||
return E_ELSE_NO_IF;
|
||||
}
|
||||
if (!IfArray[if_pointer-1].before_else) {
|
||||
return E_ELSE_NO_IF;
|
||||
}
|
||||
|
||||
IfArray[if_pointer-1].before_else = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoReturn - handle the RETURN command */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int
|
||||
DoReturn(ParsePtr p)
|
||||
{
|
||||
int r = VerifyEoln(p);
|
||||
return_encountered = 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* encounter_endif - note that the most-recently-pushed IF */
|
||||
/* has encountered an ENDIF */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int
|
||||
encounter_endif(void)
|
||||
{
|
||||
if (if_pointer <= base_pointer) {
|
||||
return E_ENDIF_NO_IF;
|
||||
}
|
||||
if_pointer--;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* get_base_if_pointer - get the current base_pointer */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int
|
||||
get_base_if_pointer(void)
|
||||
{
|
||||
return base_pointer;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* get_if_pointer - get the current if_pointer */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int
|
||||
get_if_pointer(void)
|
||||
{
|
||||
return if_pointer;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* set_base_if_pointer - set the base_pointer to n */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void
|
||||
set_base_if_pointer(int n)
|
||||
{
|
||||
base_pointer = n;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* should_ignore_line - return 1 if current line should be */
|
||||
/* ignored. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int
|
||||
should_ignore_line(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (return_encountered) {
|
||||
return 1;
|
||||
}
|
||||
for (i=base_pointer; i<if_pointer; i++) {
|
||||
if (( IfArray[i].if_true && !IfArray[i].before_else) ||
|
||||
(!IfArray[i].if_true && IfArray[i].before_else)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* in_constant_context - return true if we're in a "constant" */
|
||||
/* assignment context. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int
|
||||
in_constant_context(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<if_pointer; i++) {
|
||||
if (!IfArray[i].was_constant) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* pop_excess_ifs - pop excess IFs from the stack, printing */
|
||||
/* error messages as needed. */
|
||||
/* Also resets return_encountered */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void
|
||||
pop_excess_ifs(char const *fname)
|
||||
{
|
||||
return_encountered = 0;
|
||||
if (if_pointer <= base_pointer) {
|
||||
return;
|
||||
}
|
||||
if (!Hush) {
|
||||
Eprint("%s", GetErr(E_MISS_ENDIF));
|
||||
}
|
||||
while(if_pointer > base_pointer) {
|
||||
if (!Hush) {
|
||||
fprintf(ErrFp, tr("%s(%d): IF without ENDIF"), fname, IfArray[if_pointer-1].lineno);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
if_pointer--;
|
||||
}
|
||||
}
|
||||
69
src/init.c
69
src/init.c
@@ -186,6 +186,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
InitUserFunctions();
|
||||
|
||||
InitTranslationTable();
|
||||
InitFiles();
|
||||
|
||||
/* If stdout is a terminal, initialize $FormWidth to terminal width-8,
|
||||
but clamp to [20, 500] */
|
||||
@@ -635,7 +636,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
while (*arg) {
|
||||
switch(*arg++) {
|
||||
case 's': case 'S': DebugFlag |= DB_PARSE_EXPR; break;
|
||||
case 'h': case 'H': DebugFlag |= DB_HASHSTATS; break;
|
||||
case 'h': case 'H': DebugFlag |= DB_HASHSTATS; break;
|
||||
case 'e': case 'E': DebugFlag |= DB_ECHO_LINE; break;
|
||||
case 'x': case 'X': DebugFlag |= DB_PRTEXPR; break;
|
||||
case 't': case 'T': DebugFlag |= DB_PRTTRIG; break;
|
||||
@@ -643,6 +644,8 @@ void InitRemind(int argc, char const *argv[])
|
||||
case 'l': case 'L': DebugFlag |= DB_PRTLINE; break;
|
||||
case 'f': case 'F': DebugFlag |= DB_TRACE_FILES; break;
|
||||
case 'q': case 'Q': DebugFlag |= DB_TRANSLATE; break;
|
||||
case 'n': case 'N': DebugFlag |= DB_NONCONST; break;
|
||||
case 'u': case 'U': DebugFlag |= DB_UNUSED_VARS; break;
|
||||
default:
|
||||
fprintf(ErrFp, GetErr(M_BAD_DB_FLAG), *(arg-1));
|
||||
fprintf(ErrFp, "\n");
|
||||
@@ -795,6 +798,15 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
}
|
||||
|
||||
/* JSON mode turns off sorting */
|
||||
if (JSONMode) {
|
||||
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 */
|
||||
if (CalculateUTC) {
|
||||
(void) CalcMinsFromUTC(DSEToday, MinutesPastMidnight(0),
|
||||
@@ -835,7 +847,7 @@ void Usage(void)
|
||||
fprintf(ErrFp, " -q Don't queue timed reminders\n");
|
||||
fprintf(ErrFp, " -f Trigger timed reminders by staying in foreground\n");
|
||||
fprintf(ErrFp, " -z[n] Enter daemon mode, waking every n (1) minutes.\n");
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline f=tracefiles\n");
|
||||
fprintf(ErrFp, " -d... Debug: See man page for details\n");
|
||||
fprintf(ErrFp, " -e Divert messages normally sent to stderr to stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Time format for cal: 0=am/pm, 1=24hr, 2=none\n");
|
||||
fprintf(ErrFp, " -x[n] Iteration limit for SATISFY clause (def=1000)\n");
|
||||
@@ -845,6 +857,16 @@ void Usage(void)
|
||||
fprintf(ErrFp, " -m Start calendar with Monday rather than Sunday\n");
|
||||
fprintf(ErrFp, " -y Synthesize tags for tagless reminders\n");
|
||||
fprintf(ErrFp, " -j[n] Run in 'purge' mode. [n = INCLUDE depth]\n");
|
||||
fprintf(ErrFp, "\nLong Options:\n");
|
||||
fprintf(ErrFp, " --version Print Remind version\n");
|
||||
fprintf(ErrFp, " --hide-completed-todos Don't show completed todos on calendar\n");
|
||||
fprintf(ErrFp, " --only-todos Only issue TODO reminders\n");
|
||||
fprintf(ErrFp, " --only-events Do not issue TODO reminders\n");
|
||||
fprintf(ErrFp, " --json Use JSON output instead of plain-text\n");
|
||||
fprintf(ErrFp, " --max-execution-time=n Limit execution time to n seconds\n");
|
||||
fprintf(ErrFp, " --print-config-cmd Print ./configure cmd used to build Remind\n");
|
||||
fprintf(ErrFp, " --print-errs Print all possible error messages\n");
|
||||
fprintf(ErrFp, " --print-tokens Print all possible Remind tokens\n");
|
||||
fprintf(ErrFp, "\nRemind home page: %s\n", PACKAGE_URL);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -1003,7 +1025,7 @@ static void InitializeVar(char const *str)
|
||||
}
|
||||
val.type = INT_TYPE;
|
||||
val.v.val = 0;
|
||||
r = SetVar(varname, &val);
|
||||
r = SetVar(varname, &val, 1);
|
||||
if (!r) {
|
||||
r = PreserveVar(varname);
|
||||
}
|
||||
@@ -1014,11 +1036,6 @@ static void InitializeVar(char const *str)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*varname) {
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_VAR));
|
||||
fprintf(ErrFp, "\n");
|
||||
return;
|
||||
}
|
||||
expr = str+1;
|
||||
if (!*expr) {
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_EXPR));
|
||||
@@ -1043,7 +1060,7 @@ static void InitializeVar(char const *str)
|
||||
return;
|
||||
}
|
||||
|
||||
r=SetVar(varname, &val);
|
||||
r=SetVar(varname, &val, 1);
|
||||
if (r) {
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
fprintf(ErrFp, "\n");
|
||||
@@ -1060,7 +1077,7 @@ static void InitializeVar(char const *str)
|
||||
static void
|
||||
AddTrustedUser(char const *username)
|
||||
{
|
||||
struct passwd *pwent;
|
||||
struct passwd const *pwent;
|
||||
if (NumTrustedUsers >= MAX_TRUSTED_USERS) {
|
||||
fprintf(ErrFp, "Too many trusted users (%d max)\n",
|
||||
MAX_TRUSTED_USERS);
|
||||
@@ -1133,6 +1150,33 @@ 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;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(arg, "version")) {
|
||||
printf("%s\n", VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
@@ -1151,6 +1195,11 @@ ProcessLongOption(char const *arg)
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (!strcmp(arg, "hide-completed-todos")) {
|
||||
HideCompletedTodos = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(arg, "print-tokens")) {
|
||||
print_remind_tokens();
|
||||
print_builtinfunc_tokens();
|
||||
|
||||
27
src/json.c
27
src/json.c
@@ -47,19 +47,8 @@
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifndef JSON_INT_T_OVERRIDDEN
|
||||
#if defined(_MSC_VER)
|
||||
/* https://docs.microsoft.com/en-us/cpp/cpp/data-type-ranges */
|
||||
#define JSON_INT_MAX 9223372036854775807LL
|
||||
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
/* C99 */
|
||||
#define JSON_INT_MAX INT_FAST64_MAX
|
||||
#else
|
||||
/* C89 */
|
||||
#include <limits.h>
|
||||
#define JSON_INT_MAX LONG_MAX
|
||||
#endif
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#define JSON_INT_MAX LONG_MAX
|
||||
|
||||
#ifndef JSON_INT_MAX
|
||||
#define JSON_INT_MAX (json_int_t)(((unsigned json_int_t)(-1)) / (unsigned json_int_t)2);
|
||||
@@ -69,6 +58,8 @@ typedef unsigned int json_uchar;
|
||||
|
||||
const struct _json_value json_value_none;
|
||||
|
||||
static void json_value_free_ex (json_settings * settings, json_value * value);
|
||||
|
||||
static unsigned char hex_value (json_char c)
|
||||
{
|
||||
if (isdigit((unsigned char)c))
|
||||
@@ -252,10 +243,10 @@ static const long
|
||||
flag_block_comment = 1 << 14,
|
||||
flag_num_got_decimal = 1 << 15;
|
||||
|
||||
json_value * json_parse_ex (json_settings * settings,
|
||||
const json_char * json,
|
||||
size_t length,
|
||||
char * error_buf)
|
||||
static json_value * json_parse_ex (json_settings const * settings,
|
||||
const json_char * json,
|
||||
size_t length,
|
||||
char * error_buf)
|
||||
{
|
||||
char error [json_error_max];
|
||||
const json_char * end;
|
||||
@@ -999,7 +990,7 @@ json_value * json_parse (const json_char * json, size_t length)
|
||||
return json_parse_ex (&settings, json, length, 0);
|
||||
}
|
||||
|
||||
void json_value_free_ex (json_settings * settings, json_value * value)
|
||||
static void json_value_free_ex (json_settings * settings, json_value * value)
|
||||
{
|
||||
json_value * cur_value;
|
||||
|
||||
|
||||
12
src/json.h
12
src/json.h
@@ -266,21 +266,9 @@ json_value * json_parse (const json_char * json,
|
||||
size_t length);
|
||||
|
||||
#define json_error_max 128
|
||||
json_value * json_parse_ex (json_settings * settings,
|
||||
const json_char * json,
|
||||
size_t length,
|
||||
char * error);
|
||||
|
||||
void json_value_free (json_value *);
|
||||
|
||||
|
||||
/* Not usually necessary, unless you used a custom mem_alloc and now want to
|
||||
* use a custom mem_free.
|
||||
*/
|
||||
void json_value_free_ex (json_settings * settings,
|
||||
json_value *);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
319
src/main.c
319
src/main.c
@@ -50,16 +50,23 @@
|
||||
#include "err.h"
|
||||
|
||||
static void DoReminders(void);
|
||||
static int DoDebug(ParsePtr p);
|
||||
static void ClearLastTriggers(void);
|
||||
static int DoBanner(ParsePtr p);
|
||||
static void SaveLastTimeTrig(TimeTrig const *t);
|
||||
|
||||
/* Macro for simplifying common block so as not to litter code */
|
||||
#define OUTPUT(c) do { if (output) { DBufPutc(output, c); } else { putchar(c); } } while(0)
|
||||
|
||||
void
|
||||
static void
|
||||
exitfunc(void)
|
||||
{
|
||||
/* Kill any execution-time-limiter process */
|
||||
unlimit_execution_time();
|
||||
|
||||
if (DebugFlag & DB_UNUSED_VARS) {
|
||||
DumpUnusedVars();
|
||||
}
|
||||
if (DebugFlag & DB_HASHSTATS) {
|
||||
fflush(stdout);
|
||||
fflush(ErrFp);
|
||||
@@ -165,19 +172,60 @@ int main(int argc, char *argv[])
|
||||
ShouldCache = (Iterations > 1);
|
||||
|
||||
while (Iterations--) {
|
||||
if (JSONMode) {
|
||||
printf("[\n");
|
||||
}
|
||||
PerIterationInit();
|
||||
DoReminders();
|
||||
|
||||
if (DebugFlag & DB_DUMP_VARS) {
|
||||
DumpVarTable();
|
||||
DumpVarTable(0);
|
||||
DumpSysVarByName(NULL);
|
||||
}
|
||||
|
||||
if (!Hush) {
|
||||
if (DestroyOmitContexts(1))
|
||||
if (DestroyOmitContexts(1)) {
|
||||
FreshLine = 1;
|
||||
Eprint("%s", GetErr(E_PUSH_NOPOP));
|
||||
}
|
||||
if (EmptyVarStack(1)) {
|
||||
FreshLine = 1;
|
||||
Eprint("%s", GetErr(E_PUSHV_NO_POP));
|
||||
}
|
||||
if (EmptyUserFuncStack(1)) {
|
||||
FreshLine = 1;
|
||||
Eprint("%s", GetErr(E_PUSHF_NO_POP));
|
||||
}
|
||||
if (!Daemon && !NextMode && !NumTriggered && !NumQueued) {
|
||||
printf("%s\n", GetErr(E_NOREMINDERS));
|
||||
if (!JSONMode) {
|
||||
printf("%s\n", GetErr(E_NOREMINDERS));
|
||||
} else {
|
||||
if (!DidMsgReminder) {
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
/* Do a banner in JSON mode*/
|
||||
if (!DoSubstFromString(DBufValue(&Banner), &buf,
|
||||
DSEToday, NO_TIME) &&
|
||||
DBufLen(&buf)) {
|
||||
if (JSONLinesEmitted) {
|
||||
printf("},\n");
|
||||
}
|
||||
JSONLinesEmitted++;
|
||||
printf("{\"banner\":\"");
|
||||
remove_trailing_newlines(&buf);
|
||||
PrintJSONString(DBufValue(&buf));
|
||||
printf("\"");
|
||||
}
|
||||
DBufFree(&buf);
|
||||
}
|
||||
if (JSONLinesEmitted) {
|
||||
printf("},\n");
|
||||
}
|
||||
printf("{\"noreminders\":\"");
|
||||
PrintJSONString(GetErr(E_NOREMINDERS));
|
||||
printf("\"");
|
||||
JSONLinesEmitted++;
|
||||
}
|
||||
} else if (!Daemon && !NextMode && !NumTriggered) {
|
||||
printf(GetErr(M_QUEUED), NumQueued);
|
||||
printf("\n");
|
||||
@@ -187,6 +235,12 @@ int main(int argc, char *argv[])
|
||||
/* If there are sorted reminders, handle them */
|
||||
if (SortByDate) IssueSortedReminders();
|
||||
|
||||
if (JSONMode) {
|
||||
if (JSONLinesEmitted) {
|
||||
printf("}\n");
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
/* If there are any background reminders queued up, handle them */
|
||||
if (NumQueued || Daemon) {
|
||||
|
||||
@@ -228,11 +282,14 @@ PerIterationInit(void)
|
||||
{
|
||||
ClearGlobalOmits();
|
||||
DestroyOmitContexts(1);
|
||||
EmptyVarStack(1);
|
||||
EmptyUserFuncStack(1);
|
||||
DestroyVars(0);
|
||||
DefaultColorR = -1;
|
||||
DefaultColorG = -1;
|
||||
DefaultColorB = -1;
|
||||
NumTriggered = 0;
|
||||
JSONLinesEmitted = 0;
|
||||
ClearLastTriggers();
|
||||
ClearDedupeTable();
|
||||
}
|
||||
@@ -283,12 +340,13 @@ static void DoReminders(void)
|
||||
s = FindInitialToken(&tok, CurLine);
|
||||
|
||||
/* Should we ignore it? */
|
||||
if (NumIfs &&
|
||||
tok.type != T_If &&
|
||||
if (tok.type != T_If &&
|
||||
tok.type != T_Else &&
|
||||
tok.type != T_EndIf &&
|
||||
tok.type != T_IfTrig &&
|
||||
ShouldIgnoreLine())
|
||||
tok.type != T_Set &&
|
||||
tok.type != T_Fset &&
|
||||
should_ignore_line())
|
||||
{
|
||||
/*** IGNORE THE LINE ***/
|
||||
if (PurgeMode) {
|
||||
@@ -313,6 +371,7 @@ static void DoReminders(void)
|
||||
case T_Rem: r=DoRem(&p); purge_handled = 1; break;
|
||||
case T_ErrMsg: r=DoErrMsg(&p); break;
|
||||
case T_If: r=DoIf(&p); break;
|
||||
case T_Return: r=DoReturn(&p); break;
|
||||
case T_IfTrig: r=DoIfTrig(&p); break;
|
||||
case T_Else: r=DoElse(&p); break;
|
||||
case T_EndIf: r=DoEndif(&p); break;
|
||||
@@ -358,6 +417,18 @@ static void DoReminders(void)
|
||||
case T_Pop: r=PopOmitContext(&p); break;
|
||||
case T_Preserve: r=DoPreserve(&p); break;
|
||||
case T_Push: r=PushOmitContext(&p); break;
|
||||
case T_PushVars:
|
||||
r=PushVars(&p);
|
||||
break;
|
||||
case T_PopVars:
|
||||
r=PopVars(&p);
|
||||
break;
|
||||
case T_PushFuncs:
|
||||
r=PushUserFuncs(&p);
|
||||
break;
|
||||
case T_PopFuncs:
|
||||
r=PopUserFuncs(&p);
|
||||
break;
|
||||
case T_Expr: r = DoExpr(&p); break;
|
||||
case T_Translate: r = DoTranslate(&p); break;
|
||||
case T_RemType: if (tok.val == RUN_TYPE) {
|
||||
@@ -393,7 +464,9 @@ static void DoReminders(void)
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
} else {
|
||||
if (r) {
|
||||
PurgeEchoLine("#!P! Could not parse next line: %s\n", GetErr(r));
|
||||
if (!Hush) {
|
||||
PurgeEchoLine("#!P! Could not parse next line: %s\n", GetErr(r));
|
||||
}
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
}
|
||||
@@ -453,6 +526,15 @@ void FromDSE(int dse, int *y, int *m, int *d)
|
||||
try_yr--;
|
||||
try_dse -= DaysInYear(try_yr);
|
||||
}
|
||||
if (y) {
|
||||
*y = try_yr;
|
||||
}
|
||||
|
||||
/* If all we want is the year, we can quit here */
|
||||
if (!d && !m) {
|
||||
return;
|
||||
}
|
||||
|
||||
dse -= try_dse;
|
||||
|
||||
t = DaysInMonth(try_mon, try_yr);
|
||||
@@ -461,9 +543,6 @@ void FromDSE(int dse, int *y, int *m, int *d)
|
||||
try_mon++;
|
||||
t = DaysInMonth(try_mon, try_yr);
|
||||
}
|
||||
if (y) {
|
||||
*y = try_yr;
|
||||
}
|
||||
if (m) {
|
||||
*m = try_mon;
|
||||
}
|
||||
@@ -896,21 +975,17 @@ void Wprint(char const *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
||||
char const *fname = GetCurrentFilename();
|
||||
if (SuppressErrorOutputInCatch) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* We can't use line_range because caller might have used it */
|
||||
if (FileName) {
|
||||
if (strcmp(FileName, "-")) {
|
||||
if (LineNoStart == LineNo) {
|
||||
(void) fprintf(ErrFp, "%s(%d): ", FileName, LineNo);
|
||||
} else {
|
||||
(void) fprintf(ErrFp, "%s(%d:%d): ", FileName, LineNoStart, LineNo);
|
||||
}
|
||||
if (fname) {
|
||||
if (LineNoStart == LineNo) {
|
||||
(void) fprintf(ErrFp, "%s(%d): ", fname, LineNo);
|
||||
} else {
|
||||
if (LineNoStart == LineNo) {
|
||||
(void) fprintf(ErrFp, "-stdin-(%d): ", LineNo);
|
||||
} else {
|
||||
(void) fprintf(ErrFp, "-stdin-(%d:%d): ", LineNoStart, LineNo);
|
||||
}
|
||||
(void) fprintf(ErrFp, "%s(%d:%d): ", fname, LineNoStart, LineNo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -928,20 +1003,27 @@ void Wprint(char const *fmt, ...)
|
||||
void Eprint(char const *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char const *fname;
|
||||
|
||||
/* Check if more than one error msg. from this line */
|
||||
if (!FreshLine && !ShowAllErrors) return;
|
||||
|
||||
if (!FileName) {
|
||||
if (SuppressErrorOutputInCatch) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(FileName, "-")) {
|
||||
fname = FileName;
|
||||
} else {
|
||||
fname = "-stdin-";
|
||||
if (should_ignore_line()) {
|
||||
return;
|
||||
}
|
||||
|
||||
char const *fname = GetCurrentFilename();
|
||||
if (!fname) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (LineNo < 1) {
|
||||
/* Not yet processing a file */
|
||||
return;
|
||||
}
|
||||
/* Check if more than one error msg. from this line */
|
||||
if (!FreshLine && !ShowAllErrors) return;
|
||||
|
||||
if (FreshLine) {
|
||||
/* We can't use line_range because caller might have used it */
|
||||
if (LineNo == LineNoStart) {
|
||||
@@ -1052,7 +1134,7 @@ int PushToken(char const *tok, ParsePtr p)
|
||||
int SystemTime(int realtime)
|
||||
{
|
||||
time_t now;
|
||||
struct tm *t;
|
||||
struct tm const *t;
|
||||
|
||||
if (!realtime && (SysTime != -1)) return SysTime;
|
||||
|
||||
@@ -1092,7 +1174,7 @@ int MinutesPastMidnight(int realtime)
|
||||
int SystemDate(int *y, int *m, int *d)
|
||||
{
|
||||
time_t now;
|
||||
struct tm *t;
|
||||
struct tm const *t;
|
||||
|
||||
/* In test mode, always return 6 January 2025 */
|
||||
if (TestMode) {
|
||||
@@ -1122,32 +1204,29 @@ int DoIf(ParsePtr p)
|
||||
{
|
||||
Value v;
|
||||
int r;
|
||||
unsigned syndrome;
|
||||
|
||||
if ((size_t) NumIfs >= IF_NEST) return E_NESTED_IF;
|
||||
if (if_stack_full()) {
|
||||
return E_NESTED_IF;
|
||||
}
|
||||
|
||||
if (ShouldIgnoreLine()) syndrome = IF_TRUE | BEFORE_ELSE;
|
||||
else {
|
||||
if (should_ignore_line()) {
|
||||
push_if(1, 1);
|
||||
return OK;
|
||||
} else {
|
||||
if ( (r = EvaluateExpr(p, &v)) ) {
|
||||
syndrome = IF_TRUE | BEFORE_ELSE;
|
||||
Eprint("%s", GetErr(r));
|
||||
push_if(1, 0);
|
||||
} else
|
||||
if (truthy(&v)) {
|
||||
syndrome = IF_TRUE | BEFORE_ELSE;
|
||||
push_if(1, !p->nonconst_expr);
|
||||
} else {
|
||||
syndrome = IF_FALSE | BEFORE_ELSE;
|
||||
if (PurgeMode) {
|
||||
push_if(0, !p->nonconst_expr);
|
||||
if (PurgeMode && !Hush) {
|
||||
PurgeEchoLine("%s\n", "#!P: The next IF evaluated false...");
|
||||
PurgeEchoLine("%s\n", "#!P: REM statements in IF block not checked for purging.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IfLinenos[NumIfs] = LineNo;
|
||||
NumIfs++;
|
||||
IfFlags &= ~(IF_MASK << (2*NumIfs - 2));
|
||||
IfFlags |= syndrome << (2 * NumIfs - 2);
|
||||
if (ShouldIgnoreLine()) return OK;
|
||||
return VerifyEoln(p);
|
||||
}
|
||||
|
||||
@@ -1159,21 +1238,16 @@ int DoIf(ParsePtr p)
|
||||
/***************************************************************/
|
||||
int DoElse(ParsePtr p)
|
||||
{
|
||||
unsigned syndrome;
|
||||
int was_ignoring = should_ignore_line();
|
||||
|
||||
int was_ignoring = ShouldIgnoreLine();
|
||||
|
||||
if (!NumIfs) return E_ELSE_NO_IF;
|
||||
|
||||
syndrome = IfFlags >> (2 * NumIfs - 2);
|
||||
|
||||
if ((syndrome & IF_ELSE_MASK) == AFTER_ELSE) return E_ELSE_NO_IF;
|
||||
|
||||
IfFlags |= AFTER_ELSE << (2 * NumIfs - 2);
|
||||
if (PurgeMode && ShouldIgnoreLine() && !was_ignoring) {
|
||||
int r = encounter_else();
|
||||
if (PurgeMode && should_ignore_line() && !was_ignoring && !Hush) {
|
||||
PurgeEchoLine("%s\n", "#!P: The previous IF evaluated true.");
|
||||
PurgeEchoLine("%s\n", "#!P: REM statements in ELSE block not checked for purging");
|
||||
}
|
||||
if (r != OK) {
|
||||
return r;
|
||||
}
|
||||
return VerifyEoln(p);
|
||||
}
|
||||
|
||||
@@ -1184,8 +1258,10 @@ int DoElse(ParsePtr p)
|
||||
/***************************************************************/
|
||||
int DoEndif(ParsePtr p)
|
||||
{
|
||||
if (!NumIfs) return E_ENDIF_NO_IF;
|
||||
NumIfs--;
|
||||
int r = encounter_endif();
|
||||
if (r != OK) {
|
||||
return r;
|
||||
}
|
||||
return VerifyEoln(p);
|
||||
}
|
||||
|
||||
@@ -1199,67 +1275,46 @@ int DoEndif(ParsePtr p)
|
||||
int DoIfTrig(ParsePtr p)
|
||||
{
|
||||
int r, err;
|
||||
unsigned syndrome;
|
||||
Trigger trig;
|
||||
TimeTrig tim;
|
||||
int dse;
|
||||
|
||||
|
||||
if ((size_t) NumIfs >= IF_NEST) return E_NESTED_IF;
|
||||
if (ShouldIgnoreLine()) syndrome = IF_TRUE | BEFORE_ELSE;
|
||||
else {
|
||||
if (if_stack_full()) {
|
||||
return E_NESTED_IF;
|
||||
}
|
||||
|
||||
if (should_ignore_line()) {
|
||||
push_if(1, 0);
|
||||
return OK;
|
||||
} else {
|
||||
if ( (r=ParseRem(p, &trig, &tim)) ) return r;
|
||||
if (trig.typ != NO_TYPE) return E_PARSE_ERR;
|
||||
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
|
||||
dse = ComputeTrigger(get_scanfrom(&trig), &trig, &tim, &r, 1);
|
||||
if (r) {
|
||||
if (r != E_CANT_TRIG || !trig.maybe_uncomputable) {
|
||||
if (!Hush || r != E_RUN_DISABLED) {
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
syndrome = IF_FALSE | BEFORE_ELSE;
|
||||
}
|
||||
else {
|
||||
push_if(0, 0);
|
||||
} else {
|
||||
if (ShouldTriggerReminder(&trig, &tim, dse, &err)) {
|
||||
syndrome = IF_TRUE | BEFORE_ELSE;
|
||||
push_if(1, 0);
|
||||
} else {
|
||||
syndrome = IF_FALSE | BEFORE_ELSE;
|
||||
push_if(0, 0);
|
||||
if (PurgeMode && !Hush) {
|
||||
PurgeEchoLine("%s\n", "#!P: The next IFTRIG did not trigger.");
|
||||
PurgeEchoLine("%s\n", "#!P: REM statements in IFTRIG block not checked for purging.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (syndrome == (IF_FALSE | BEFORE_ELSE) && PurgeMode) {
|
||||
PurgeEchoLine("%s\n", "#!P: The next IFTRIG did not trigger.");
|
||||
PurgeEchoLine("%s\n", "#!P: REM statements in IFTRIG block not checked for purging.");
|
||||
}
|
||||
FreeTrig(&trig);
|
||||
}
|
||||
NumIfs++;
|
||||
IfFlags &= ~(IF_MASK << (2*NumIfs - 2));
|
||||
IfFlags |= syndrome << (2 * NumIfs - 2);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ShouldIgnoreLine - given the current state of the IF */
|
||||
/* stack, should we ignore the current line? */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ShouldIgnoreLine(void)
|
||||
{
|
||||
register int i, syndrome;
|
||||
|
||||
/* Algorithm - go from outer to inner, and if any should be ignored, then
|
||||
ignore the whole. */
|
||||
|
||||
for (i=0; i<NumIfs; i++) {
|
||||
syndrome = (IfFlags >> (i*2)) & IF_MASK;
|
||||
if (syndrome == IF_TRUE+AFTER_ELSE ||
|
||||
syndrome == IF_FALSE+BEFORE_ELSE) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* VerifyEoln */
|
||||
@@ -1293,7 +1348,7 @@ int VerifyEoln(ParsePtr p)
|
||||
/* Set the debug options under program control. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoDebug(ParsePtr p)
|
||||
static int DoDebug(ParsePtr p)
|
||||
{
|
||||
int err;
|
||||
int ch;
|
||||
@@ -1373,6 +1428,17 @@ int DoDebug(ParsePtr p)
|
||||
if (val) DebugFlag |= DB_TRACE_FILES;
|
||||
else DebugFlag &= ~DB_TRACE_FILES;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
case 'N':
|
||||
if (val) DebugFlag |= DB_NONCONST;
|
||||
else DebugFlag &= ~DB_NONCONST;
|
||||
break;
|
||||
case 'u':
|
||||
case 'U':
|
||||
if (val) DebugFlag |= DB_UNUSED_VARS;
|
||||
else DebugFlag &= ~DB_UNUSED_VARS;
|
||||
break;
|
||||
default:
|
||||
Wprint(GetErr(M_BAD_DB_FLAG), ch);
|
||||
break;
|
||||
@@ -1388,7 +1454,7 @@ int DoDebug(ParsePtr p)
|
||||
/* reminder is issued. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoBanner(ParsePtr p)
|
||||
static int DoBanner(ParsePtr p)
|
||||
{
|
||||
int err;
|
||||
int c;
|
||||
@@ -1510,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);
|
||||
@@ -1560,10 +1635,10 @@ int DoErrMsg(ParsePtr p)
|
||||
non-leap year beginning on Wednesday, and FoldArray[1][5] is a
|
||||
leap year beginning on Saturday. Used to fold back dates which
|
||||
are too high for the standard Unix representation.
|
||||
NOTE: This implies that you cannot set BASE > 2001!!!!! */
|
||||
static int FoldArray[2][7] = {
|
||||
{2001, 2002, 2003, 2009, 2010, 2005, 2006},
|
||||
{2024, 2008, 2020, 2004, 2016, 2000, 2012}
|
||||
NOTE: This implies that you cannot set BASE > 2012!!!!! */
|
||||
int FoldArray[2][7] = {
|
||||
{2035, 2030, 2031, 2026, 2027, 2033, 2034},
|
||||
{2024, 2036, 2020, 2032, 2016, 2028, 2012}
|
||||
};
|
||||
|
||||
int CalcMinsFromUTC(int dse, int tim, int *mins, int *isdst)
|
||||
@@ -1572,7 +1647,8 @@ int CalcMinsFromUTC(int dse, int tim, int *mins, int *isdst)
|
||||
/* Convert dse and tim to an Unix tm struct */
|
||||
int yr, mon, day;
|
||||
int tdiff;
|
||||
struct tm local, utc, *temp;
|
||||
struct tm local, utc;
|
||||
struct tm const * temp;
|
||||
time_t loc_t, utc_t;
|
||||
int isdst_tmp;
|
||||
|
||||
@@ -1581,7 +1657,7 @@ int CalcMinsFromUTC(int dse, int tim, int *mins, int *isdst)
|
||||
/* If the year is greater than 2037, some Unix machines have problems.
|
||||
Fold it back to a "similar" year and trust that the UTC calculations
|
||||
are still valid... */
|
||||
if (FoldYear && yr>2037) {
|
||||
if (yr > 2037 && (FoldYear || (sizeof(time_t) < (64/CHAR_BIT)))) {
|
||||
dse = DSE(yr, 0, 1);
|
||||
yr = FoldArray[IsLeapYear(yr)][dse%7];
|
||||
}
|
||||
@@ -1966,7 +2042,7 @@ FreeTrig(Trigger *t)
|
||||
t->infos = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
ClearLastTriggers(void)
|
||||
{
|
||||
LastTrigger.expired = 0;
|
||||
@@ -1989,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
|
||||
@@ -2001,9 +2081,11 @@ SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigt
|
||||
{
|
||||
SaveLastTrigger(t);
|
||||
SaveLastTimeTrig(tt);
|
||||
LastTriggerDate = trigdate;
|
||||
if (trigdate != -1) {
|
||||
LastTriggerDate = trigdate;
|
||||
LastTrigValid = valid;
|
||||
}
|
||||
LastTriggerTime = trigtime;
|
||||
LastTrigValid = valid;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2024,7 +2106,7 @@ SaveLastTrigger(Trigger const *t)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SaveLastTimeTrig(TimeTrig const *t)
|
||||
{
|
||||
memcpy(&LastTimeTrig, t, sizeof(LastTimeTrig));
|
||||
@@ -2068,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);
|
||||
@@ -2131,6 +2218,14 @@ int GetOnceDate(void)
|
||||
return OnceDate;
|
||||
}
|
||||
|
||||
char const *GetEnglishErr(int r)
|
||||
{
|
||||
if (r < 0 || r >= NumErrs) {
|
||||
r = E_SWERR;
|
||||
}
|
||||
return ErrMsg[r];
|
||||
}
|
||||
|
||||
char const *GetErr(int r)
|
||||
{
|
||||
char const *msg;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "md5.h"
|
||||
|
||||
static void byteReverse(unsigned char *buf, unsigned longs);
|
||||
static void MD5Transform(uint32 buf[4], uint32 const in[16]);
|
||||
|
||||
/*
|
||||
* Note: this code is harmless on little-endian machines.
|
||||
@@ -163,7 +164,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
void MD5Transform(uint32 buf[4], uint32 const in[16])
|
||||
static void MD5Transform(uint32 buf[4], uint32 const in[16])
|
||||
{
|
||||
register uint32 a, b, c, d;
|
||||
|
||||
|
||||
@@ -29,6 +29,5 @@ void MD5Init(struct MD5Context *context);
|
||||
void MD5Update(struct MD5Context *context, unsigned char const *buf,
|
||||
unsigned len);
|
||||
void MD5Final(unsigned char digest[16], struct MD5Context *context);
|
||||
void MD5Transform(uint32 buf[4], uint32 const in[16]);
|
||||
|
||||
#endif /* !MD5_H */
|
||||
|
||||
@@ -636,7 +636,7 @@ static time_t time_t_from_dse(int dse)
|
||||
|
||||
static int datetime_from_time_t(time_t t)
|
||||
{
|
||||
struct tm *local;
|
||||
struct tm const *local;
|
||||
int ans;
|
||||
|
||||
/* Round to nearest minute */
|
||||
@@ -665,7 +665,7 @@ static double interpolate(double f0, double f1, double f2, double p)
|
||||
|
||||
/* Moon position using fundamental arguments
|
||||
Van Flandern & Pulkkinen, 1979) */
|
||||
void moon_position(double dayOffset, double *ra, double *declination, double *distance)
|
||||
static void moon_position(double dayOffset, double *ra, double *declination, double *distance)
|
||||
{
|
||||
double l = 0.606434 + 0.03660110129 * dayOffset;
|
||||
double m = 0.374897 + 0.03629164709 * dayOffset;
|
||||
|
||||
32
src/omit.c
32
src/omit.c
@@ -36,7 +36,7 @@ int NumFullOmits, NumPartialOmits;
|
||||
/* The structure for saving and restoring OMIT contexts */
|
||||
typedef struct omitcontext {
|
||||
struct omitcontext *next;
|
||||
char *filename;
|
||||
char const *filename;
|
||||
int lineno;
|
||||
int numfull, numpart;
|
||||
int *fullsave;
|
||||
@@ -98,7 +98,6 @@ int DestroyOmitContexts(int print_unmatched)
|
||||
num++;
|
||||
if (c->fullsave) free(c->fullsave);
|
||||
if (c->partsave) free(c->partsave);
|
||||
if (c->filename) free(c->filename);
|
||||
d = c->next;
|
||||
free(c);
|
||||
c = d;
|
||||
@@ -122,28 +121,19 @@ int PushOmitContext(ParsePtr p)
|
||||
context = NEW(OmitContext);
|
||||
if (!context) return E_NO_MEM;
|
||||
|
||||
if (FileName) {
|
||||
context->filename = StrDup(FileName);
|
||||
} else {
|
||||
context->filename = StrDup("");
|
||||
}
|
||||
if (!context->filename) {
|
||||
free(context);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
context->filename = GetCurrentFilename();
|
||||
context->lineno = LineNo;
|
||||
|
||||
context->numfull = NumFullOmits;
|
||||
context->numpart = NumPartialOmits;
|
||||
context->weekdaysave = WeekdayOmits;
|
||||
context->fullsave = malloc(NumFullOmits * sizeof(int));
|
||||
if (NumFullOmits && !context->fullsave) {
|
||||
free(context->filename);
|
||||
free(context);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
context->partsave = malloc(NumPartialOmits * sizeof(int));
|
||||
if (NumPartialOmits && !context->partsave) {
|
||||
free(context->filename);
|
||||
if (context->fullsave) {
|
||||
free(context->fullsave);
|
||||
}
|
||||
@@ -172,6 +162,7 @@ int PopOmitContext(ParsePtr p)
|
||||
{
|
||||
|
||||
OmitContext *c = SavedOmitContexts;
|
||||
char const *fname = GetCurrentFilename();
|
||||
|
||||
if (!c) return E_POP_NO_PUSH;
|
||||
NumFullOmits = c->numfull;
|
||||
@@ -185,13 +176,12 @@ int PopOmitContext(ParsePtr p)
|
||||
/* Remove the context from the stack */
|
||||
SavedOmitContexts = c->next;
|
||||
|
||||
if (c->filename && FileName && strcmp(c->filename, FileName)) {
|
||||
Wprint(tr("POP-OMIT-CONTEXT at %s:%d matches PUSH-OMIT-CONTEXT in different file: %s:%d"), FileName, LineNo, c->filename, c->lineno);
|
||||
if (c->filename && fname && strcmp(c->filename, fname)) {
|
||||
Wprint(tr("POP-OMIT-CONTEXT at %s:%d matches PUSH-OMIT-CONTEXT in different file: %s:%d"), fname, LineNo, c->filename, c->lineno);
|
||||
}
|
||||
/* Free memory used by the saved context */
|
||||
if (c->partsave) free(c->partsave);
|
||||
if (c->fullsave) free(c->fullsave);
|
||||
if (c->filename) free(c->filename);
|
||||
free(c);
|
||||
|
||||
return VerifyEoln(p);
|
||||
@@ -249,7 +239,7 @@ int IsOmitted(int dse, int localomit, char const *omitfunc, int *omit)
|
||||
return OK;
|
||||
}
|
||||
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
FromDSE(dse, NULL, &m, &d);
|
||||
if (BexistsIntArray(PartialOmitArray, NumPartialOmits, (m << 5) + d)) {
|
||||
*omit = 1;
|
||||
return OK;
|
||||
@@ -522,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");
|
||||
|
||||
74
src/protos.h
74
src/protos.h
@@ -47,32 +47,30 @@ int DoFrename (ParsePtr p);
|
||||
void UnsetAllUserFuncs(void);
|
||||
void ProduceCalendar (void);
|
||||
char const *SimpleTime (int tim);
|
||||
char const *CalendarTime (int tim, int duration);
|
||||
int DoRem (ParsePtr p);
|
||||
int DoFlush (ParsePtr p);
|
||||
void DoExit (ParsePtr p);
|
||||
int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim);
|
||||
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued, DynamicBuffer *output);
|
||||
int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int dse, int *err);
|
||||
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode);
|
||||
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig const *tim, int dse, int is_queued, DynamicBuffer *output, int *r, int *g, int *b);
|
||||
int ShouldTriggerReminder (Trigger const *t, TimeTrig const *tim, int dse, int *err);
|
||||
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig const *tt, int dse, int mode);
|
||||
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int dse, int tim);
|
||||
int ParseLiteralDateOrTime (char const **s, int *dse, int *tim);
|
||||
int ParseLiteralTime (char const **s, int *tim);
|
||||
expr_node *parse_expression(char const **e, int *r, Var *locals);
|
||||
|
||||
int evaluate_expression(expr_node *node, Value *locals, Value *ans, int *nonconst);
|
||||
int evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst);
|
||||
int truthy(Value const *v);
|
||||
|
||||
void print_expr_tree(expr_node *node, FILE *fp);
|
||||
void unlimit_execution_time(void);
|
||||
expr_node *free_expr_tree(expr_node *node);
|
||||
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);
|
||||
int ReadLine (void);
|
||||
int OpenFile (char const *fname);
|
||||
int DoInclude (ParsePtr p, enum TokTypes tok);
|
||||
int DoIncludeCmd (ParsePtr p);
|
||||
int IncludeFile (char const *fname);
|
||||
@@ -106,11 +104,9 @@ int SystemDate (int *y, int *m, int *d);
|
||||
int DoIf (ParsePtr p);
|
||||
int DoElse (ParsePtr p);
|
||||
int DoEndif (ParsePtr p);
|
||||
int DoReturn (ParsePtr p);
|
||||
int DoIfTrig (ParsePtr p);
|
||||
int ShouldIgnoreLine (void);
|
||||
int VerifyEoln (ParsePtr p);
|
||||
int DoDebug (ParsePtr p);
|
||||
int DoBanner (ParsePtr p);
|
||||
int DoRun (ParsePtr p);
|
||||
int DoExpr (ParsePtr p);
|
||||
int DoTranslate (ParsePtr p);
|
||||
@@ -124,13 +120,12 @@ int PushOmitContext (ParsePtr p);
|
||||
int PopOmitContext (ParsePtr p);
|
||||
int IsOmitted (int dse, int localomit, char const *omitfunc, int *omit);
|
||||
int DoOmit (ParsePtr p);
|
||||
int QueueReminder (ParsePtr p, Trigger *trig, TimeTrig *tim, char const *sched);
|
||||
int QueueReminder (ParsePtr p, Trigger *trig, TimeTrig const *tim, char const *sched);
|
||||
void HandleQueuedReminders (void);
|
||||
char const *FindInitialToken (Token *tok, char const *s);
|
||||
void FindToken (char const *s, Token *tok);
|
||||
void FindNumericToken (char const *s, Token *t);
|
||||
int ComputeTrigger (int today, Trigger *trig, TimeTrig *tim, int *err, int save_in_globals);
|
||||
int ComputeTriggerNoAdjustDuration (int today, Trigger *trig, TimeTrig *tim, int *err, int save_in_globals, int duration_days);
|
||||
int ComputeTriggerNoAdjustDuration (int today, Trigger *trig, TimeTrig const *tim, int *err, int save_in_globals, int duration_days);
|
||||
int AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int save_in_globals);
|
||||
char *StrnCpy (char *dest, char const *source, int n);
|
||||
|
||||
@@ -150,20 +145,24 @@ void strtolower(char *s);
|
||||
|
||||
Var *FindVar (char const *str, int create);
|
||||
SysVar *FindSysVar (char const *name);
|
||||
int DeleteVar (char const *str);
|
||||
int SetVar (char const *str, Value const *val);
|
||||
int GetVarValue (char const *str, Value *val);
|
||||
int SetVar (char const *str, Value const *val, int nonconst_expr);
|
||||
int DoSet (Parser *p);
|
||||
int DoUnset (Parser *p);
|
||||
int DoDump (ParsePtr p);
|
||||
void DumpVarTable (void);
|
||||
int PushVars(ParsePtr p);
|
||||
int EmptyVarStack(int print_unmatched);
|
||||
int PopVars(ParsePtr p);
|
||||
int PushUserFuncs(ParsePtr p);
|
||||
int EmptyUserFuncStack(int print_unmatched);
|
||||
int PopUserFuncs(ParsePtr p);
|
||||
void DumpVarTable (int dump_constness);
|
||||
void DumpUnusedVars(void);
|
||||
void DestroyVars (int all);
|
||||
int PreserveVar (char const *name);
|
||||
int DoPreserve (Parser *p);
|
||||
int DoSatRemind (Trigger *trig, TimeTrig *tt, ParsePtr p);
|
||||
int DoMsgCommand (char const *cmd, char const *msg, int is_queued);
|
||||
int ParseNonSpaceChar (ParsePtr p, int *err, int peek);
|
||||
unsigned int HashVal_ignorecase(char const *str);
|
||||
unsigned int HashVal_preservecase(char const *str);
|
||||
int DateOK (int y, int m, int d);
|
||||
BuiltinFunc *FindBuiltinFunc (char const *name);
|
||||
@@ -174,10 +173,6 @@ int UserFuncExists (char const *fn);
|
||||
void DSEToHeb (int dse, int *hy, int *hm, int *hd);
|
||||
int HebNameToNum (char const *mname);
|
||||
char const *HebMonthName (int m, int y);
|
||||
int RoshHashana (int i);
|
||||
long DaysToHebYear (int y);
|
||||
int DaysInHebYear (int y);
|
||||
char const *DaysInHebMonths (int ylen);
|
||||
int HebToDSE (int hy, int hm, int hd);
|
||||
int GetValidHebDate (int yin, int min, int din, int adarbehave, int *mout, int *dout, int yahr);
|
||||
int GetNextHebrewDate (int dsestart, int hm, int hd, int yahr, int adarbehave, int *ans);
|
||||
@@ -198,9 +193,7 @@ void PurgeEchoLine(char const *fmt, ...);
|
||||
void FreeTrig(Trigger *t);
|
||||
void AppendTag(DynamicBuffer *buf, char const *s);
|
||||
char const *SynthesizeTag(void);
|
||||
void ClearLastTriggers(void);
|
||||
void SaveLastTrigger(Trigger const *t);
|
||||
void SaveLastTimeTrig(TimeTrig const *t);
|
||||
void SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigtime, int valid);
|
||||
|
||||
void PerIterationInit(void);
|
||||
@@ -209,13 +202,9 @@ char const *Colorize(int r, int g, int b, int bg, int clamp);
|
||||
void PrintJSONString(char const *s);
|
||||
void PrintJSONKeyPairInt(char const *name, int val);
|
||||
void PrintJSONKeyPairString(char const *name, char const *val);
|
||||
void PrintJSONKeyPairDate(char const *name, int dse);
|
||||
void PrintJSONKeyPairDateTime(char const *name, int dt);
|
||||
void PrintJSONKeyPairTime(char const *name, int t);
|
||||
void System(char const *cmd, int queued);
|
||||
int ShellEscape(char const *in, DynamicBuffer *out);
|
||||
int AddGlobalOmit(int dse);
|
||||
void set_lat_and_long_from_components(void);
|
||||
void set_components_from_lat_and_long(void);
|
||||
|
||||
void DebugExitFunc(void);
|
||||
@@ -225,13 +214,12 @@ int GetTerminalBackground(void);
|
||||
char const *get_day_name(int wkday);
|
||||
char const *get_month_name(int mon);
|
||||
|
||||
void set_cloexec(FILE *fp);
|
||||
int push_call(char const *filename, char const *func, int lineno, int lineno_start);
|
||||
void clear_callstack(void);
|
||||
int print_callstack(FILE *fp);
|
||||
void pop_call(void);
|
||||
void FixSpecialType(Trigger *trig);
|
||||
void WriteJSONTrigger(Trigger const *t, int include_tags, int today);
|
||||
void WriteJSONTrigger(Trigger const *t, int include_tags);
|
||||
void WriteJSONTimeTrigger(TimeTrig const *tt);
|
||||
int GetOnceDate(void);
|
||||
#ifdef REM_USE_WCHAR
|
||||
@@ -268,20 +256,18 @@ void InitDedupeTable(void);
|
||||
void InitVars(void);
|
||||
void InitUserFunctions(void);
|
||||
void InitTranslationTable(void);
|
||||
void InitFiles(void);
|
||||
char const *GetTranslatedString(char const *orig);
|
||||
int GetTranslatedStringTryingVariants(char const *orig, DynamicBuffer *out);
|
||||
char const *GetErr(int r);
|
||||
char const *GetEnglishErr(int r);
|
||||
char const *tr(char const *s);
|
||||
void print_escaped_string(FILE *fp, char const *s);
|
||||
void print_escaped_string_helper(FILE *fp, char const *s, int esc_for_remind, int json);
|
||||
void GenerateSysvarTranslationTemplates(void);
|
||||
void TranslationTemplate(char const *msg);
|
||||
TrigInfo *NewTrigInfo(char const *i);
|
||||
void FreeTrigInfo(TrigInfo *ti);
|
||||
void FreeTrigInfoChain(TrigInfo *ti);
|
||||
int AppendTrigInfo(Trigger *t, char const *info);
|
||||
int TrigInfoHeadersAreTheSame(char const *i1, char const *i2);
|
||||
int TrigInfoIsValid(char const *info);
|
||||
char const *FindTrigInfo(Trigger *t, char const *header);
|
||||
void WriteJSONInfoChain(TrigInfo *ti);
|
||||
char const *line_range(int lineno_start, int lineno);
|
||||
@@ -289,3 +275,23 @@ int GetMoonrise(int dse);
|
||||
int GetMoonset(int dse);
|
||||
int GetMoonrise_angle(int dse);
|
||||
int GetMoonset_angle(int dse);
|
||||
#define nonconst_debug(nc, ...) do { if ((DebugFlag & DB_NONCONST) && !nc) { Wprint(__VA_ARGS__); } } while(0)
|
||||
|
||||
/* if-else handling */
|
||||
int push_if(int is_true, int was_constant);
|
||||
int if_stack_full(void);
|
||||
int encounter_else(void);
|
||||
int encounter_endif(void);
|
||||
int get_base_if_pointer(void);
|
||||
int get_if_pointer(void);
|
||||
void set_base_if_pointer(int n);
|
||||
int should_ignore_line(void);
|
||||
int in_constant_context(void);
|
||||
void pop_excess_ifs(char const *fname);
|
||||
|
||||
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);
|
||||
|
||||
97
src/queue.c
97
src/queue.c
@@ -12,12 +12,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* Solaris needs this to get select() prototype */
|
||||
#ifdef __sun__
|
||||
#define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
/* We only want object code generated if we have queued reminders */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
@@ -45,13 +39,6 @@ static void consume_inotify_events(int fd);
|
||||
static int setup_inotify_watch(void);
|
||||
#endif
|
||||
|
||||
/* A list of filenames associated with queued reminders */
|
||||
typedef struct queuedfname {
|
||||
struct queuedfname *next;
|
||||
char const *fname;
|
||||
} QueuedFilename;
|
||||
|
||||
|
||||
/* List structure for holding queued reminders */
|
||||
typedef struct queuedrem {
|
||||
struct queuedrem *next;
|
||||
@@ -72,7 +59,6 @@ typedef struct queuedrem {
|
||||
/* Global variables */
|
||||
|
||||
static QueuedRem *QueueHead = NULL;
|
||||
static QueuedFilename *Files = NULL;
|
||||
static time_t FileModTime;
|
||||
static struct stat StatBuf;
|
||||
|
||||
@@ -83,7 +69,6 @@ static int CalculateNextTimeUsingSched (QueuedRem *q);
|
||||
static void ServerWait (struct timeval *sleep_tv);
|
||||
static void reread (void);
|
||||
static void PrintQueue(void);
|
||||
static char const *QueueFilename(char const *fname);
|
||||
|
||||
static void chomp(DynamicBuffer *buf)
|
||||
{
|
||||
@@ -100,7 +85,7 @@ static void chomp(DynamicBuffer *buf)
|
||||
}
|
||||
}
|
||||
|
||||
char const *SimpleTimeNoSpace(int tim)
|
||||
static char const *SimpleTimeNoSpace(int tim)
|
||||
{
|
||||
char *s = (char *) SimpleTime(tim);
|
||||
if (s && *s) {
|
||||
@@ -112,49 +97,7 @@ char const *SimpleTimeNoSpace(int tim)
|
||||
return s;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* QueueFilename */
|
||||
/* */
|
||||
/* Add fname to the list of queued filenames if it's not */
|
||||
/* already present. Either way, return a pointer to the */
|
||||
/* filename. Returns NULL if out of memory */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static QueuedFilename *last_file_found = NULL;
|
||||
static char const *QueueFilename(char const *fname)
|
||||
{
|
||||
QueuedFilename *elem = Files;
|
||||
|
||||
/* Optimization: We are very likely in the same file as
|
||||
before... */
|
||||
if (last_file_found && !strcmp(fname, last_file_found->fname)) {
|
||||
return last_file_found->fname;
|
||||
}
|
||||
|
||||
/* No such luck; search the list */
|
||||
while(elem) {
|
||||
if (!strcmp(elem->fname, fname)) {
|
||||
last_file_found = elem;
|
||||
return elem->fname;
|
||||
}
|
||||
elem = elem->next;
|
||||
}
|
||||
/* Not found... queue it */
|
||||
elem = NEW(QueuedFilename);
|
||||
if (!elem) return NULL;
|
||||
elem->fname = StrDup(fname);
|
||||
if (!elem->fname) {
|
||||
free(elem);
|
||||
return NULL;
|
||||
}
|
||||
elem->next = Files;
|
||||
Files = elem;
|
||||
last_file_found = elem;
|
||||
return elem->fname;
|
||||
}
|
||||
|
||||
static void del_reminder(QueuedRem *qid)
|
||||
static void del_reminder(QueuedRem const *qid)
|
||||
{
|
||||
QueuedRem *q = QueueHead;
|
||||
QueuedRem *next;
|
||||
@@ -194,7 +137,7 @@ static void del_reminder_ul(unsigned long qid) {
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int QueueReminder(ParsePtr p, Trigger *trig,
|
||||
TimeTrig *tim, char const *sched)
|
||||
TimeTrig const *tim, char const *sched)
|
||||
{
|
||||
QueuedRem *qelem;
|
||||
|
||||
@@ -217,13 +160,7 @@ int QueueReminder(ParsePtr p, Trigger *trig,
|
||||
free(qelem);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
qelem->fname = QueueFilename(FileName);
|
||||
if (!qelem->fname) {
|
||||
free((void *) qelem->text);
|
||||
free(qelem);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
qelem->fname = GetCurrentFilename();
|
||||
qelem->lineno = LineNo;
|
||||
qelem->lineno_start = LineNoStart;
|
||||
NumQueued++;
|
||||
@@ -272,7 +209,7 @@ maybe_close(int fd)
|
||||
(void) close(new_fd);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SigContHandler(int d)
|
||||
{
|
||||
UNUSED(d);
|
||||
@@ -327,12 +264,6 @@ void HandleQueuedReminders(void)
|
||||
/* Turn off sorting -- otherwise, TriggerReminder has no effect! */
|
||||
SortByDate = 0;
|
||||
|
||||
/* Free FileName if necessary */
|
||||
if (FileName) {
|
||||
free(FileName);
|
||||
FileName = NULL;
|
||||
}
|
||||
|
||||
/* We don't need to keep the dedupe table around */
|
||||
ClearDedupeTable();
|
||||
|
||||
@@ -464,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\",");
|
||||
@@ -495,7 +425,7 @@ void HandleQueuedReminders(void)
|
||||
/* Set up global variables so some functions like trigdate()
|
||||
and trigtime() work correctly */
|
||||
SaveAllTriggerInfo(&(q->t), &(q->tt), DSEToday, q->tt.ttime, 1);
|
||||
FileName = (char *) q->fname;
|
||||
SetCurrentFilename(q->fname);
|
||||
DefaultColorR = q->red;
|
||||
DefaultColorG = q->green;
|
||||
DefaultColorB = q->blue;
|
||||
@@ -505,7 +435,7 @@ void HandleQueuedReminders(void)
|
||||
if (DaemonJSON) {
|
||||
DynamicBuffer out;
|
||||
DBufInit(&out);
|
||||
(void) TriggerReminder(&p, &tcopy, &q->tt, DSEToday, 1, &out);
|
||||
(void) TriggerReminder(&p, &tcopy, &q->tt, DSEToday, 1, &out, NULL, NULL, NULL);
|
||||
if (q->typ != RUN_TYPE) {
|
||||
printf("\"body\":\"");
|
||||
chomp(&out);
|
||||
@@ -514,9 +444,8 @@ void HandleQueuedReminders(void)
|
||||
}
|
||||
DBufFree(&out);
|
||||
} else {
|
||||
(void) TriggerReminder(&p, &tcopy, &q->tt, DSEToday, 1, NULL);
|
||||
(void) TriggerReminder(&p, &tcopy, &q->tt, DSEToday, 1, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
FileName = NULL;
|
||||
if (IsServerMode() && !DaemonJSON && q->typ != RUN_TYPE) {
|
||||
printf("NOTE endreminder\n");
|
||||
}
|
||||
@@ -710,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;
|
||||
@@ -774,7 +705,7 @@ json_queue(QueuedRem const *q)
|
||||
}
|
||||
done = 1;
|
||||
printf("{");
|
||||
WriteJSONTrigger(&(q->t), 1, DSEToday);
|
||||
WriteJSONTrigger(&(q->t), 1);
|
||||
WriteJSONTimeTrigger(&(q->tt));
|
||||
if (TestMode) {
|
||||
snprintf(idbuf, sizeof(idbuf), "42424242");
|
||||
|
||||
44
src/rem2ps.c
44
src/rem2ps.c
@@ -131,16 +131,16 @@ int LeftMarg, RightMarg, TopMarg, BotMarg;
|
||||
int FillPage;
|
||||
int Verbose = 0;
|
||||
|
||||
void Init (int argc, char *argv[]);
|
||||
void Usage (char const *s);
|
||||
void DoPsCal (void);
|
||||
int DoQueuedPs (void);
|
||||
void DoSmallCal (char const *m, int days, int first, int col, int which);
|
||||
void WriteProlog (void);
|
||||
void WriteCalEntry (void);
|
||||
void WriteOneEntry (CalEntry *c);
|
||||
void GetSmallLocations (void);
|
||||
char const *EatToken(char const *in, char *out, int maxlen);
|
||||
static void Init (int argc, char const *argv[]);
|
||||
static void Usage (char const *s);
|
||||
static void DoPsCal (void);
|
||||
static int DoQueuedPs (void);
|
||||
static void DoSmallCal (char const *m, int days, int first, int col, int which);
|
||||
static void WriteProlog (void);
|
||||
static void WriteCalEntry (void);
|
||||
static void WriteOneEntry (CalEntry const *c);
|
||||
static void GetSmallLocations (void);
|
||||
static char const *EatToken(char const *in, char *out, int maxlen);
|
||||
|
||||
static void
|
||||
put_escaped_string(char const *s)
|
||||
@@ -161,7 +161,7 @@ put_escaped_string(char const *s)
|
||||
/* Compare strings, case insensitive. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int StrCmpi(char const *s1, char const *s2)
|
||||
static int StrCmpi(char const *s1, char const *s2)
|
||||
{
|
||||
int r;
|
||||
while (*s1 && *s2) {
|
||||
@@ -178,7 +178,7 @@ int StrCmpi(char const *s1, char const *s2)
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static CalEntry *
|
||||
JSONToCalEntry(DynamicBuffer *buf)
|
||||
JSONToCalEntry(DynamicBuffer const *buf)
|
||||
{
|
||||
CalEntry *c;
|
||||
json_value *val;
|
||||
@@ -325,7 +325,7 @@ TextToCalEntry(DynamicBuffer *buf)
|
||||
/* MAIN PROGRAM */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
/* If stdin is a tty - probably wrong. */
|
||||
|
||||
@@ -375,7 +375,7 @@ int main(int argc, char *argv[])
|
||||
/* DoPsCal - emit PostScript for the calendar. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void DoPsCal(void)
|
||||
static void DoPsCal(void)
|
||||
{
|
||||
char month[40], year[40];
|
||||
char prevm[40], nextm[40];
|
||||
@@ -595,7 +595,7 @@ void DoPsCal(void)
|
||||
/* WriteProlog - write the PostScript prologue */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void WriteProlog(void)
|
||||
static void WriteProlog(void)
|
||||
{
|
||||
int i;
|
||||
int x = CurPage->xsize;
|
||||
@@ -702,7 +702,7 @@ void WriteProlog(void)
|
||||
/* WriteCalEntry - write all entries for one day */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void WriteCalEntry(void)
|
||||
static void WriteCalEntry(void)
|
||||
{
|
||||
CalEntry *c = CurEntries;
|
||||
CalEntry *d;
|
||||
@@ -789,7 +789,7 @@ void WriteCalEntry(void)
|
||||
/* WriteOneEntry - write an entry for one day */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void WriteOneEntry(CalEntry *c)
|
||||
static void WriteOneEntry(CalEntry const *c)
|
||||
{
|
||||
int ch, i;
|
||||
char const *s = c->entry;
|
||||
@@ -851,7 +851,7 @@ void WriteOneEntry(CalEntry *c)
|
||||
/* Init - set up parameters */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void Init(int argc, char *argv[])
|
||||
static void Init(int argc, char const *argv[])
|
||||
{
|
||||
char const *s;
|
||||
char const *t;
|
||||
@@ -1043,7 +1043,7 @@ void Usage(char const *s)
|
||||
/* month. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void DoSmallCal(char const *m, int days, int first, int col, int which)
|
||||
static void DoSmallCal(char const *m, int days, int first, int col, int which)
|
||||
{
|
||||
/* Do the small calendar */
|
||||
int i, j;
|
||||
@@ -1097,7 +1097,7 @@ void DoSmallCal(char const *m, int days, int first, int col, int which)
|
||||
/* DoQueuedPs - do the queued PS and PSFILE reminders. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoQueuedPs(void)
|
||||
static int DoQueuedPs(void)
|
||||
{
|
||||
int i;
|
||||
int HadPS = 0;
|
||||
@@ -1305,7 +1305,7 @@ int DoQueuedPs(void)
|
||||
/* Set up the locations for the small calendars. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void GetSmallLocations(void)
|
||||
static void GetSmallLocations(void)
|
||||
{
|
||||
char c;
|
||||
char const *s = SmallLocation;
|
||||
@@ -1370,7 +1370,7 @@ void GetSmallLocations(void)
|
||||
/* Read a space-delimited token into an output buffer. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char const *EatToken(char const *in, char *out, int maxlen)
|
||||
static char const *EatToken(char const *in, char *out, int maxlen)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
||||
27
src/token.c
27
src/token.c
@@ -27,11 +27,11 @@
|
||||
executes 'return' if an initial non-numeric char is found. */
|
||||
#define PARSENUM(var, string) \
|
||||
if (!isdigit(*(string))) return; \
|
||||
var = 0; \
|
||||
(var) = 0; \
|
||||
while (isdigit(*(string))) { \
|
||||
var *= 10; \
|
||||
var += *(string) - '0'; \
|
||||
string++; \
|
||||
(var) *= 10; \
|
||||
(var) += *(string) - '0'; \
|
||||
(string)++; \
|
||||
}
|
||||
|
||||
/* The big array holding all recognized (literal) tokens in reminder file.
|
||||
@@ -46,7 +46,8 @@ Token TokArray[] = {
|
||||
{ "banner", 3, T_Banner, 0 },
|
||||
{ "before", 6, T_Skip, BEFORE_SKIP },
|
||||
{ "cal", 3, T_RemType, CAL_TYPE },
|
||||
{ "clear-omit-context", 5, T_Clr, 0 },
|
||||
{ "clear-omit-context", 5, T_Clr, 0 },
|
||||
{ "complete-through", 16, T_CompleteThrough, 0 },
|
||||
{ "debug", 5, T_Debug, 0 },
|
||||
{ "december", 3, T_Month, 11 },
|
||||
{ "do", 2, T_IncludeR, 0 },
|
||||
@@ -79,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 },
|
||||
@@ -90,13 +92,18 @@ Token TokArray[] = {
|
||||
{ "omit", 4, T_Omit, 0 },
|
||||
{ "omitfunc", 8, T_OmitFunc, 0 },
|
||||
{ "once", 4, T_Once, 0 },
|
||||
{ "pop-funcs", 9, T_PopFuncs, 0 },
|
||||
{ "pop-omit-context", 3, T_Pop, 0 },
|
||||
{ "pop-vars", 8, T_PopVars, 0 },
|
||||
{ "preserve", 8, T_Preserve, 0 },
|
||||
{ "priority", 8, T_Priority, 0 },
|
||||
{ "ps", 2, T_RemType, PS_TYPE },
|
||||
{ "psfile", 6, T_RemType, PSF_TYPE },
|
||||
{ "psfile", 6, T_RemType, PSF_TYPE },
|
||||
{ "push-funcs", 10, T_PushFuncs, 0 },
|
||||
{ "push-omit-context", 4, T_Push, 0 },
|
||||
{ "push-vars", 9, T_PushVars, 0 },
|
||||
{ "rem", 3, T_Rem, 0 },
|
||||
{ "return", 6, T_Return, 0 },
|
||||
{ "run", 3, T_RemType, RUN_TYPE },
|
||||
{ "satisfy", 7, T_RemType, SAT_TYPE },
|
||||
{ "saturday", 3, T_WkDay, 5 },
|
||||
@@ -113,6 +120,7 @@ Token TokArray[] = {
|
||||
{ "third", 5, T_Ordinal, 2 },
|
||||
{ "through", 7, T_Through, 0 },
|
||||
{ "thursday", 3, T_WkDay, 3 },
|
||||
{ "todo", 4, T_Todo, 0 },
|
||||
{ "translate", 5, T_Translate, 0 },
|
||||
{ "tuesday", 3, T_WkDay, 1 },
|
||||
{ "unset", 5, T_UnSet, 0 },
|
||||
@@ -122,6 +130,7 @@ Token TokArray[] = {
|
||||
};
|
||||
|
||||
static int TokStrCmp (Token const *t, char const *s);
|
||||
static void FindNumericToken(char const *s, Token *t);
|
||||
|
||||
static void
|
||||
init_token(Token *t)
|
||||
@@ -247,7 +256,7 @@ void FindToken(char const *s, Token *tok)
|
||||
/* Rep - *n */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void FindNumericToken(char const *s, Token *t)
|
||||
static void FindNumericToken(char const *s, Token *t)
|
||||
{
|
||||
int mult = 1, hour, min;
|
||||
char const *s_orig = s;
|
||||
@@ -443,7 +452,7 @@ static int TokStrCmp(Token const *t, char const *s)
|
||||
}
|
||||
|
||||
static void
|
||||
print_token(Token *tok)
|
||||
print_token(Token const *tok)
|
||||
{
|
||||
if (tok->MinLen < (int) strlen(tok->name)) {
|
||||
printf("%.*s\n", tok->MinLen, tok->name);
|
||||
@@ -455,7 +464,7 @@ void
|
||||
print_remind_tokens(void)
|
||||
{
|
||||
int i;
|
||||
Token *tok;
|
||||
Token const *tok;
|
||||
int num = (int) (sizeof(TokArray) / sizeof(TokArray[0]));
|
||||
printf("# Remind Tokens\n\n");
|
||||
for (i=0; i<num; i++) {
|
||||
|
||||
20
src/trans.c
20
src/trans.c
@@ -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 */
|
||||
@@ -272,17 +280,17 @@ DumpTranslationTable(FILE *fp, int json)
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
HashXlateItem(void *x)
|
||||
HashXlateItem(void const *x)
|
||||
{
|
||||
XlateItem *item = (XlateItem *) x;
|
||||
XlateItem const *item = (XlateItem const *) x;
|
||||
return HashVal_preservecase(item->orig);
|
||||
}
|
||||
|
||||
static int
|
||||
CompareXlateItems(void *a, void *b)
|
||||
CompareXlateItems(void const *a, void const *b)
|
||||
{
|
||||
XlateItem *i = (XlateItem *) a;
|
||||
XlateItem *j = (XlateItem *) b;
|
||||
XlateItem const *i = (XlateItem const *) a;
|
||||
XlateItem const *j = (XlateItem const *) b;
|
||||
return strcmp(i->orig, j->orig);
|
||||
}
|
||||
|
||||
@@ -339,7 +347,7 @@ InsertTranslation(char const *orig, char const *translated)
|
||||
char const *
|
||||
GetTranslatedString(char const *orig)
|
||||
{
|
||||
XlateItem *item = FindTranslation(orig);
|
||||
XlateItem const *item = FindTranslation(orig);
|
||||
if (!item) return NULL;
|
||||
return item->translated;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,10 @@
|
||||
|
||||
static int DSEYear(int dse);
|
||||
static int DSEMonth(int dse);
|
||||
static int NextSimpleTrig(int startdate, Trigger *trig, int *err);
|
||||
static int NextSimpleTrig(int startdate, Trigger const *trig, int *err);
|
||||
static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart);
|
||||
static int TrigInfoIsValid(char const *info);
|
||||
static int TrigInfoHeadersAreTheSame(char const *i1, char const *i2);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -44,7 +46,7 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
/* so that dates with a REP can be handled properly. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
|
||||
static int NextSimpleTrig(int startdate, Trigger const *trig, int *err)
|
||||
{
|
||||
int typ = 0;
|
||||
int d, m, y, j, d2, m2, y2;
|
||||
@@ -309,16 +311,28 @@ static int DSEYear(int dse)
|
||||
static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart)
|
||||
{
|
||||
int simple, mod, omit;
|
||||
int calmode = (DoSimpleCalendar || DoCalendar) ? 1 : 0;
|
||||
if (HideCompletedTodos) calmode = 0;
|
||||
|
||||
/* First: Have we passed the UNTIL date? */
|
||||
if (trig->until != NO_UNTIL &&
|
||||
/* First: Have we passed the UNTIL date? */
|
||||
if (!trig->is_todo &&
|
||||
trig->until != NO_UNTIL &&
|
||||
trig->until < start) {
|
||||
trig->expired = 1;
|
||||
return -1; /* expired */
|
||||
}
|
||||
|
||||
/* Next: If it's an "AFTER"-type skip, back up
|
||||
until we're at the start of a block of holidays */
|
||||
/* If it's a TODO and complete_through is past today, we're good */
|
||||
if (!calmode &&
|
||||
trig->is_todo &&
|
||||
trig->complete_through != NO_DATE &&
|
||||
trig->complete_through >= start) {
|
||||
trig->expired = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Next: If it's an "AFTER"-type skip, back up
|
||||
until we're at the start of a block of holidays */
|
||||
if (trig->skip == AFTER_SKIP) {
|
||||
int iter = 0;
|
||||
while (iter++ <= MaxSatIter) {
|
||||
@@ -339,16 +353,16 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the next simple trigger */
|
||||
/* Find the next simple trigger */
|
||||
simple = NextSimpleTrig(start, trig, err);
|
||||
|
||||
/* Problems? */
|
||||
/* Problems? */
|
||||
if (*err || (simple == -1)) return -1;
|
||||
|
||||
/* Suggested starting point for next attempt */
|
||||
/* Suggested starting point for next attempt */
|
||||
*nextstart = simple+1;
|
||||
|
||||
/* If there's a BACK, back up... */
|
||||
/* If there's a BACK, back up... */
|
||||
if (trig->back != NO_BACK) {
|
||||
mod = trig->back;
|
||||
if (mod < 0) {
|
||||
@@ -376,7 +390,7 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's a REP, calculate the next occurrence */
|
||||
/* If there's a REP, calculate the next occurrence */
|
||||
if (trig->rep != NO_REP) {
|
||||
if (simple < start) {
|
||||
mod = (start - simple) / trig->rep;
|
||||
@@ -385,7 +399,7 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
}
|
||||
|
||||
/* If it's a "BEFORE"-type skip, back up */
|
||||
/* If it's a "BEFORE"-type skip, back up */
|
||||
if (trig->skip == BEFORE_SKIP) {
|
||||
int iter = 0;
|
||||
while(iter++ <= MaxSatIter) {
|
||||
@@ -406,7 +420,7 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
}
|
||||
|
||||
/* If it's an "AFTER"-type skip, jump ahead */
|
||||
/* If it's an "AFTER"-type skip, jump ahead */
|
||||
if (trig->skip == AFTER_SKIP) {
|
||||
int iter = 0;
|
||||
while (iter++ <= MaxSatIter) {
|
||||
@@ -423,7 +437,12 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the date */
|
||||
/* If we've passed the UNTIL, then it's expired */
|
||||
if (trig->until != NO_UNTIL && simple > trig->until) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the date */
|
||||
return simple;
|
||||
}
|
||||
|
||||
@@ -453,7 +472,7 @@ AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int sav
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
FromDSE(r, &y, &m, &d);
|
||||
fprintf(ErrFp, "%s(%s): Trig(adj) = %s, %d %s, %d",
|
||||
FileName, line_range(LineNoStart, LineNo),
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo),
|
||||
get_day_name(r % 7),
|
||||
d,
|
||||
get_month_name(m),
|
||||
@@ -524,7 +543,7 @@ int ComputeTrigger(int today, Trigger *trig, TimeTrig *tim,
|
||||
/* duration. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig const *tim,
|
||||
int *err, int save_in_globals, int duration_days)
|
||||
{
|
||||
int nattempts = 0,
|
||||
@@ -536,6 +555,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
trig->expired = 0;
|
||||
if (save_in_globals) {
|
||||
LastTrigValid = 0;
|
||||
LastTriggerDate = -1;
|
||||
}
|
||||
|
||||
/* Assume everything works */
|
||||
@@ -574,14 +594,13 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
|
||||
while (nattempts++ < TRIG_ATTEMPTS) {
|
||||
result = GetNextTriggerDate(trig, start, err, &nextstart);
|
||||
|
||||
/* If there's an error, die immediately */
|
||||
if (*err) return -1;
|
||||
if (result == -1) {
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%s): %s\n",
|
||||
FileName, line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -604,7 +623,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
FromDSE(result, &y, &m, &d);
|
||||
fprintf(ErrFp, "%s(%s): Trig = %s, %d %s, %d",
|
||||
FileName, line_range(LineNoStart, LineNo),
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo),
|
||||
get_day_name(result % 7),
|
||||
d,
|
||||
get_month_name(m),
|
||||
@@ -630,8 +649,9 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
trig->rep == NO_REP) {
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%s): %s\n",
|
||||
FileName, line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
|
||||
FromDSE(result, &y, &m, &d);
|
||||
fprintf(ErrFp, "%s(%s): %s: %04d-%02d-%02d\n",
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo), GetErr(E_EXPIRED), y, m+1, d);
|
||||
}
|
||||
if (save_in_globals) {
|
||||
LastTriggerDate = result;
|
||||
@@ -656,7 +676,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%s): %s\n",
|
||||
FileName, line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -677,7 +697,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
/* Returns NULL if memory allocation fails. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
TrigInfo *
|
||||
static TrigInfo *
|
||||
NewTrigInfo(char const *i)
|
||||
{
|
||||
TrigInfo *ti = malloc(sizeof(TrigInfo));
|
||||
@@ -701,7 +721,7 @@ NewTrigInfo(char const *i)
|
||||
/* Free a TrigInfo objects. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void
|
||||
static void
|
||||
FreeTrigInfo(TrigInfo *ti)
|
||||
{
|
||||
if (ti->info) {
|
||||
@@ -768,7 +788,7 @@ AppendTrigInfo(Trigger *t, char const *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
TrigInfoHeadersAreTheSame(char const *i1, char const *i2)
|
||||
{
|
||||
char const *c1 = strchr(i1, ':');
|
||||
@@ -779,7 +799,7 @@ TrigInfoHeadersAreTheSame(char const *i1, char const *i2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
TrigInfoIsValid(char const *info)
|
||||
{
|
||||
char const *t;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user