mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 14:59:20 +02:00
Compare commits
219 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b86245c4c6 | ||
|
|
499fcfad41 | ||
|
|
bddbbf061b | ||
|
|
05136f4cf0 | ||
|
|
e62e3d5d03 | ||
|
|
595fdaa4a4 | ||
|
|
133febc2c1 | ||
|
|
f8c6d7ff6c | ||
|
|
db3341db91 | ||
|
|
8cbcd3ec01 | ||
|
|
4c6512e9b6 | ||
|
|
4769789a8f | ||
|
|
b4a8cb085c | ||
|
|
4f816d52fd | ||
|
|
94b3a0248d | ||
|
|
5fbf1d82e4 | ||
|
|
55eb3ebe95 | ||
|
|
2afa3c5558 | ||
|
|
30d9a42db2 | ||
|
|
74d357b84d | ||
|
|
09c98a93ec | ||
|
|
ed89ab7c04 | ||
|
|
27c74be02b | ||
|
|
8f22ab39dc | ||
|
|
795c53f4ce | ||
|
|
3fd18a9cc0 | ||
|
|
a5afb4a87e | ||
|
|
379fc4542d | ||
|
|
538ef6c8ce | ||
|
|
95c7e8856c | ||
|
|
95523c8f10 | ||
|
|
97b53d5e40 | ||
|
|
fb688850b1 | ||
|
|
5b1bad2650 | ||
|
|
e5ff132c5e | ||
|
|
a0830ad23c | ||
|
|
9290f53466 | ||
|
|
e5711032bd | ||
|
|
08e3c1d5a2 | ||
|
|
29c579a301 | ||
|
|
61f55bceee | ||
|
|
6586fae3eb | ||
|
|
d5a86f3e4f | ||
|
|
96551ccaa4 | ||
|
|
c83ee86d10 | ||
|
|
c913306cbd | ||
|
|
03d385df97 | ||
|
|
61fcc1b275 | ||
|
|
26977a4ac0 | ||
|
|
28acd05215 | ||
|
|
be4eed8b20 | ||
|
|
cdb0850373 | ||
|
|
0d55e04284 | ||
|
|
f4cce54b70 | ||
|
|
2dc6ca44f1 | ||
|
|
d1d833f0f3 | ||
|
|
1d44577ce9 | ||
|
|
1be7c2d6d7 | ||
|
|
b1f418ee42 | ||
|
|
72b0bf96fe | ||
|
|
3388849fa5 | ||
|
|
dc9650d5fa | ||
|
|
8eb40ae748 | ||
|
|
89184f1d0f | ||
|
|
e899c790b9 | ||
|
|
bd6d695020 | ||
|
|
20d4626a71 | ||
|
|
8ff94c5031 | ||
|
|
ee185a0eeb | ||
|
|
06f8932efd | ||
|
|
1dc627148c | ||
|
|
3cdde5351f | ||
|
|
6e93b8a73d | ||
|
|
267e8533cf | ||
|
|
d3bfb0a28f | ||
|
|
5a31bc7058 | ||
|
|
746bde71bd | ||
|
|
b274ac635c | ||
|
|
9e0a74e583 | ||
|
|
0f782f7697 | ||
|
|
8efde3e9af | ||
|
|
3bf3137dc4 | ||
|
|
63ec32d28d | ||
|
|
d2f4177cdb | ||
|
|
1d958fb7a8 | ||
|
|
fcd580d42e | ||
|
|
34dab68805 | ||
|
|
216dd03922 | ||
|
|
5eef9ac621 | ||
|
|
6b798d5f7c | ||
|
|
22ccce0934 | ||
|
|
fe2af14952 | ||
|
|
8e99ed27e7 | ||
|
|
bb12362cc8 | ||
|
|
1bfc630a64 | ||
|
|
987983f8ae | ||
|
|
657a6118aa | ||
|
|
43e7e6ec7f | ||
|
|
b8b3c19fbf | ||
|
|
69298c96a5 | ||
|
|
7356138872 | ||
|
|
616966f5df | ||
|
|
a59e277c21 | ||
|
|
740ae2c3e9 | ||
|
|
25b7a40f2b | ||
|
|
2beaab1a2f | ||
|
|
60793d53c6 | ||
|
|
4f869c8c81 | ||
|
|
8955180a35 | ||
|
|
a30cbf5797 | ||
|
|
b2bd6109dc | ||
|
|
9455ec48d7 | ||
|
|
f751f5defa | ||
|
|
994edbebbe | ||
|
|
70959b791c | ||
|
|
524ece5119 | ||
|
|
6334bd61b6 | ||
|
|
2e56edd557 | ||
|
|
8cae1d21cd | ||
|
|
1de6ed16eb | ||
|
|
860cb94f41 | ||
|
|
6b505704e9 | ||
|
|
167631451d | ||
|
|
fa5180b94d | ||
|
|
ae01d7be43 | ||
|
|
d5ce39ade1 | ||
|
|
a043dfe8b9 | ||
|
|
7cfb75e3b3 | ||
|
|
a18f0d982f | ||
|
|
0e2dc805c2 | ||
|
|
4c1e11df2c | ||
|
|
76776d054a | ||
|
|
45ebd05cb6 | ||
|
|
0203ce3979 | ||
|
|
72d10178bf | ||
|
|
96f4e26d53 | ||
|
|
4fd86f1b6a | ||
|
|
2f3ee0aec3 | ||
|
|
a5dde31160 | ||
|
|
b45428df05 | ||
|
|
d938763643 | ||
|
|
e4e2157622 | ||
|
|
04b349c6c7 | ||
|
|
7fe3eb7391 | ||
|
|
c1992b577a | ||
|
|
632283d47f | ||
|
|
1d9e46997c | ||
|
|
861ce34022 | ||
|
|
32e8db322d | ||
|
|
3df2b72175 | ||
|
|
e7ac4f95be | ||
|
|
e7ed69287b | ||
|
|
2e80417f53 | ||
|
|
ee435d2bb9 | ||
|
|
bb516946be | ||
|
|
81157e1cb5 | ||
|
|
51dfd707a2 | ||
|
|
7c3bf8601b | ||
|
|
714195efe5 | ||
|
|
eaeca2d09b | ||
|
|
ffa3b13437 | ||
|
|
2551e98d11 | ||
|
|
1bfd7761bc | ||
|
|
de9cb1d0a3 | ||
|
|
b2d32b514a | ||
|
|
6e53fd6924 | ||
|
|
8296d2b962 | ||
|
|
d6e66ee1e6 | ||
|
|
a49532b9c5 | ||
|
|
57d87f4caf | ||
|
|
ec9b30c616 | ||
|
|
27d8a62ab6 | ||
|
|
5077814c4a | ||
|
|
ca795a352a | ||
|
|
e59fc36458 | ||
|
|
39e3657539 | ||
|
|
6031f70701 | ||
|
|
3567c9e55f | ||
|
|
26de4e3fd3 | ||
|
|
cd65c6144d | ||
|
|
d32edbbb1f | ||
|
|
eae48a5538 | ||
|
|
63eba104d9 | ||
|
|
ae64961735 | ||
|
|
f7bb91320c | ||
|
|
c11071a859 | ||
|
|
53cbcc22db | ||
|
|
af9dcec3e9 | ||
|
|
d5a4b0d235 | ||
|
|
3b870403d9 | ||
|
|
284d822884 | ||
|
|
d881a26ad0 | ||
|
|
8519edde29 | ||
|
|
a30c467c48 | ||
|
|
887cd83ebe | ||
|
|
242d787ca2 | ||
|
|
5dd2cf7356 | ||
|
|
5efb70909d | ||
|
|
a60d466774 | ||
|
|
1c01f36271 | ||
|
|
3718632551 | ||
|
|
e8f3d5ff9f | ||
|
|
d77e27942d | ||
|
|
734cc61489 | ||
|
|
44d489d3d2 | ||
|
|
3e36ffa9ff | ||
|
|
12104a96b1 | ||
|
|
8ab8d65a15 | ||
|
|
f7a8122cef | ||
|
|
77d9bbb7d6 | ||
|
|
623def52fd | ||
|
|
d088e35142 | ||
|
|
5821e55eb8 | ||
|
|
1ee989c65d | ||
|
|
62388fb21f | ||
|
|
13571f84af | ||
|
|
03fdc06b65 | ||
|
|
4bce675ae6 | ||
|
|
7b64623115 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,6 +16,7 @@ man/remind.1
|
|||||||
man/tkremind.1
|
man/tkremind.1
|
||||||
pm_to_blib
|
pm_to_blib
|
||||||
rem2html/Makefile
|
rem2html/Makefile
|
||||||
|
rem2html/rem2html
|
||||||
rem2html/rem2html.1
|
rem2html/rem2html.1
|
||||||
rem2pdf/Makefile.PL
|
rem2pdf/Makefile.PL
|
||||||
rem2pdf/Makefile.old
|
rem2pdf/Makefile.old
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ THE REMIND COPYRIGHT
|
|||||||
1. REMIND refers to the entire set of files and documentation in the
|
1. REMIND refers to the entire set of files and documentation in the
|
||||||
REMIND package.
|
REMIND package.
|
||||||
|
|
||||||
2. REMIND is Copyright 1992-2023 Dianne Skoll, except where noted in
|
2. REMIND is Copyright 1992-2024 Dianne Skoll, except where noted in
|
||||||
individual files.
|
individual files.
|
||||||
|
|
||||||
3. DISTRIBUTION AND USE
|
3. DISTRIBUTION AND USE
|
||||||
@@ -16,7 +16,7 @@ individual files.
|
|||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
675 Mass Ave, Cambridge, MA 02139, USA
|
51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -44,7 +44,7 @@ test:
|
|||||||
@$(MAKE) -C src -s test
|
@$(MAKE) -C src -s test
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f config.cache config.log config.status src/Makefile src/config.h tests/test.out www/Makefile rem2pdf/Makefile.top rem2pdf/Makefile.old rem2pdf/Makefile rem2pdf/Makefile.PL rem2pdf/bin/rem2pdf
|
rm -f config.cache config.log config.status src/Makefile src/config.h tests/test.out www/Makefile rem2pdf/Makefile.top rem2pdf/Makefile.old rem2pdf/Makefile rem2pdf/Makefile.PL rem2pdf/bin/rem2pdf rem2html/rem2html
|
||||||
|
|
||||||
src/Makefile: src/Makefile.in
|
src/Makefile: src/Makefile.in
|
||||||
./configure
|
./configure
|
||||||
|
|||||||
26
build.tk
Normal file → Executable file
26
build.tk
Normal file → Executable file
@@ -27,10 +27,10 @@ exec wish "$0" "$@"
|
|||||||
proc SetConfigDefaults {} {
|
proc SetConfigDefaults {} {
|
||||||
global Config
|
global Config
|
||||||
set Config(LAT_DEG) 45
|
set Config(LAT_DEG) 45
|
||||||
set Config(LAT_MIN) 24
|
set Config(LAT_MIN) 25
|
||||||
set Config(LAT_SEC) 14
|
set Config(LAT_SEC) 14
|
||||||
set Config(LON_DEG) 75
|
set Config(LON_DEG) 75
|
||||||
set Config(LON_MIN) 39
|
set Config(LON_MIN) 41
|
||||||
set Config(LON_SEC) 23
|
set Config(LON_SEC) 23
|
||||||
set Config(LOCATION) "Ottawa"
|
set Config(LOCATION) "Ottawa"
|
||||||
set Config(DEFAULT_PAGE) "Letter"
|
set Config(DEFAULT_PAGE) "Letter"
|
||||||
@@ -53,7 +53,7 @@ proc SetConfigDefaults {} {
|
|||||||
# Pops up an error dialog; then calls exit.
|
# Pops up an error dialog; then calls exit.
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
proc Bail { msg } {
|
proc Bail { msg } {
|
||||||
tk_dialog .err "Remind Configuration Error" $msg error 0 "Bummer"
|
tk_messageBox -message "Remind Build Error" -detail $msg -icon error -type ok
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,8 +190,8 @@ proc CreateLocationDialog { w } {
|
|||||||
|
|
||||||
grid $w.north $w.west
|
grid $w.north $w.west
|
||||||
grid $w.south $w.east
|
grid $w.south $w.east
|
||||||
grid $w.loclab -sticky e
|
grid $w.loclab -sticky e
|
||||||
grid $w.location -sticky nsew -row 6 -column 1
|
grid $w.location -sticky nsew -row 8 -column 1
|
||||||
}
|
}
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
@@ -293,9 +293,9 @@ proc BuildRemind {} {
|
|||||||
|
|
||||||
.msgs insert end "\n>>> Creating src/custom.h...\n\n" green
|
.msgs insert end "\n>>> Creating src/custom.h...\n\n" green
|
||||||
CreateCustomH
|
CreateCustomH
|
||||||
.msgs insert end ">>> Calling `./configure'...\n\n" green
|
.msgs insert end "\n>>> Calling `./configure'...\n\n" green
|
||||||
CallConfigure
|
CallConfigure
|
||||||
.msgs insert end ">>> Calling `make'...\n\n" green
|
.msgs insert end "\n>>> Calling `make'...\n\n" green
|
||||||
CallMake
|
CallMake
|
||||||
.msgs insert end "\n----------------------------------------------\n\n"
|
.msgs insert end "\n----------------------------------------------\n\n"
|
||||||
.msgs insert end "Remind" red
|
.msgs insert end "Remind" red
|
||||||
@@ -447,12 +447,12 @@ proc CreateCustomH {} {
|
|||||||
"#define DEFAULT_LATITUDE *" {
|
"#define DEFAULT_LATITUDE *" {
|
||||||
set lat [expr $LAT_DEG + ($LAT_MIN/60.0) + ($LAT_SEC/3600.0)];
|
set lat [expr $LAT_DEG + ($LAT_MIN/60.0) + ($LAT_SEC/3600.0)];
|
||||||
puts $out "#define DEFAULT_LATITUDE $lat"
|
puts $out "#define DEFAULT_LATITUDE $lat"
|
||||||
.msgs insert end "#define DEFAULT_LATITUDE $lat"
|
.msgs insert end "#define DEFAULT_LATITUDE $lat\n"
|
||||||
}
|
}
|
||||||
"#define DEFAULT_LONGITUDE *" {
|
"#define DEFAULT_LONGITUDE *" {
|
||||||
set lon [expr -1.0 * ($LON_DEG + ($LON_MIN/60.0) + ($LON_SEC/3600.0))]
|
set lon [expr -1.0 * ($LON_DEG + ($LON_MIN/60.0) + ($LON_SEC/3600.0))]
|
||||||
puts $out "#define DEFAULT_LONGITUDE $lon"
|
puts $out "#define DEFAULT_LONGITUDE $lon"
|
||||||
.msgs insert end "#define DEFAULT_LONGITUDE $lon"
|
.msgs insert end "#define DEFAULT_LONGITUDE $lon\n"
|
||||||
}
|
}
|
||||||
"#define LOCATION *" {
|
"#define LOCATION *" {
|
||||||
puts $out "#define LOCATION \"$Config(LOCATION)\""
|
puts $out "#define LOCATION \"$Config(LOCATION)\""
|
||||||
@@ -506,7 +506,13 @@ proc CallMake {} {
|
|||||||
"Icelandic" { set lang ICELANDIC }
|
"Icelandic" { set lang ICELANDIC }
|
||||||
default { set lang ENGLISH }
|
default { set lang ENGLISH }
|
||||||
}
|
}
|
||||||
RunCommand "make \"LANGDEF=-DLANG=$lang\""
|
set nproc 0
|
||||||
|
catch { set nproc [exec nproc] }
|
||||||
|
if { $nproc != 0 } {
|
||||||
|
RunCommand "make -j $nproc \"LANGDEF=-DLANG=$lang\""
|
||||||
|
} else {
|
||||||
|
RunCommand "make \"LANGDEF=-DLANG=$lang\""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
136
configure
vendored
136
configure
vendored
@@ -1511,6 +1511,39 @@ fi
|
|||||||
|
|
||||||
} # ac_fn_c_try_link
|
} # ac_fn_c_try_link
|
||||||
|
|
||||||
|
# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
|
||||||
|
# -------------------------------------------------------
|
||||||
|
# Tests whether HEADER exists and can be compiled using the include files in
|
||||||
|
# INCLUDES, setting the cache variable VAR accordingly.
|
||||||
|
ac_fn_c_check_header_compile ()
|
||||||
|
{
|
||||||
|
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
|
||||||
|
printf %s "checking for $2... " >&6; }
|
||||||
|
if eval test \${$3+y}
|
||||||
|
then :
|
||||||
|
printf %s "(cached) " >&6
|
||||||
|
else $as_nop
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
$4
|
||||||
|
#include <$2>
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_compile "$LINENO"
|
||||||
|
then :
|
||||||
|
eval "$3=yes"
|
||||||
|
else $as_nop
|
||||||
|
eval "$3=no"
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||||
|
fi
|
||||||
|
eval ac_res=\$$3
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||||
|
printf "%s\n" "$ac_res" >&6; }
|
||||||
|
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
|
||||||
|
|
||||||
|
} # ac_fn_c_check_header_compile
|
||||||
|
|
||||||
# ac_fn_c_try_run LINENO
|
# ac_fn_c_try_run LINENO
|
||||||
# ----------------------
|
# ----------------------
|
||||||
# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
|
# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
|
||||||
@@ -1743,39 +1776,6 @@ rm -f conftest.val
|
|||||||
|
|
||||||
} # ac_fn_c_compute_int
|
} # ac_fn_c_compute_int
|
||||||
|
|
||||||
# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
|
|
||||||
# -------------------------------------------------------
|
|
||||||
# Tests whether HEADER exists and can be compiled using the include files in
|
|
||||||
# INCLUDES, setting the cache variable VAR accordingly.
|
|
||||||
ac_fn_c_check_header_compile ()
|
|
||||||
{
|
|
||||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
|
||||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
|
|
||||||
printf %s "checking for $2... " >&6; }
|
|
||||||
if eval test \${$3+y}
|
|
||||||
then :
|
|
||||||
printf %s "(cached) " >&6
|
|
||||||
else $as_nop
|
|
||||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
||||||
/* end confdefs.h. */
|
|
||||||
$4
|
|
||||||
#include <$2>
|
|
||||||
_ACEOF
|
|
||||||
if ac_fn_c_try_compile "$LINENO"
|
|
||||||
then :
|
|
||||||
eval "$3=yes"
|
|
||||||
else $as_nop
|
|
||||||
eval "$3=no"
|
|
||||||
fi
|
|
||||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
|
||||||
fi
|
|
||||||
eval ac_res=\$$3
|
|
||||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
|
||||||
printf "%s\n" "$ac_res" >&6; }
|
|
||||||
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
|
|
||||||
|
|
||||||
} # ac_fn_c_check_header_compile
|
|
||||||
|
|
||||||
# ac_fn_c_check_func LINENO FUNC VAR
|
# ac_fn_c_check_func LINENO FUNC VAR
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
# Tests whether FUNC exists, setting the cache variable VAR accordingly
|
# Tests whether FUNC exists, setting the cache variable VAR accordingly
|
||||||
@@ -2449,8 +2449,8 @@ as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
|
|||||||
as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
|
as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
|
||||||
as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
|
as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
|
||||||
as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
|
as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
|
||||||
as_fn_append ac_header_c_list " utime.h utime_h HAVE_UTIME_H"
|
|
||||||
as_fn_append ac_header_c_list " sys/time.h sys_time_h HAVE_SYS_TIME_H"
|
as_fn_append ac_header_c_list " sys/time.h sys_time_h HAVE_SYS_TIME_H"
|
||||||
|
as_fn_append ac_header_c_list " utime.h utime_h HAVE_UTIME_H"
|
||||||
|
|
||||||
# Auxiliary files required by this configure script.
|
# Auxiliary files required by this configure script.
|
||||||
ac_aux_files="install-sh"
|
ac_aux_files="install-sh"
|
||||||
@@ -3872,7 +3872,6 @@ then :
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
ac_header= ac_cache=
|
ac_header= ac_cache=
|
||||||
for ac_item in $ac_header_c_list
|
for ac_item in $ac_header_c_list
|
||||||
do
|
do
|
||||||
@@ -3902,6 +3901,9 @@ then :
|
|||||||
printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
|
printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# The cast to long int works around a bug in the HP C Compiler
|
# The cast to long int works around a bug in the HP C Compiler
|
||||||
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||||
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
||||||
@@ -3968,6 +3970,39 @@ printf "%s\n" "$ac_cv_sizeof_unsigned_long" >&6; }
|
|||||||
printf "%s\n" "#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long" >>confdefs.h
|
printf "%s\n" "#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler
|
||||||
|
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||||
|
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
||||||
|
# This bug is HP SR number 8606223364.
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5
|
||||||
|
printf %s "checking size of time_t... " >&6; }
|
||||||
|
if test ${ac_cv_sizeof_time_t+y}
|
||||||
|
then :
|
||||||
|
printf %s "(cached) " >&6
|
||||||
|
else $as_nop
|
||||||
|
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t" "$ac_includes_default"
|
||||||
|
then :
|
||||||
|
|
||||||
|
else $as_nop
|
||||||
|
if test "$ac_cv_type_time_t" = yes; then
|
||||||
|
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||||
|
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||||
|
as_fn_error 77 "cannot compute sizeof (time_t)
|
||||||
|
See \`config.log' for more details" "$LINENO" 5; }
|
||||||
|
else
|
||||||
|
ac_cv_sizeof_time_t=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5
|
||||||
|
printf "%s\n" "$ac_cv_sizeof_time_t" >&6; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
printf "%s\n" "#define SIZEOF_TIME_T $ac_cv_sizeof_time_t" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ac_fn_c_check_header_compile "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default"
|
ac_fn_c_check_header_compile "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default"
|
||||||
if test "x$ac_cv_header_sys_types_h" = xyes
|
if test "x$ac_cv_header_sys_types_h" = xyes
|
||||||
@@ -3999,6 +4034,12 @@ then :
|
|||||||
printf "%s\n" "#define HAVE_LANGINFO_H 1" >>confdefs.h
|
printf "%s\n" "#define HAVE_LANGINFO_H 1" >>confdefs.h
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
ac_fn_c_check_header_compile "$LINENO" "sys/inotify.h" "ac_cv_header_sys_inotify_h" "$ac_includes_default"
|
||||||
|
if test "x$ac_cv_header_sys_inotify_h" = xyes
|
||||||
|
then :
|
||||||
|
printf "%s\n" "#define HAVE_SYS_INOTIFY_H 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
|
||||||
@@ -4093,23 +4134,20 @@ printf "%s\n" "#define HAVE_UTIME_NULL 1" >>confdefs.h
|
|||||||
fi
|
fi
|
||||||
rm -f conftest.data
|
rm -f conftest.data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if test "$GCC" = yes; then
|
if test "$GCC" = yes; then
|
||||||
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
|
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
|
||||||
# Check for link-time optimization support
|
# Check for link-time optimization support
|
||||||
f=-flto=auto
|
f=-flto=auto
|
||||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $f" >&5
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $f" >&5
|
||||||
printf %s "checking whether $CC supports $f... " >&6; }
|
printf %s "checking whether $CC supports $f... " >&6; }
|
||||||
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
|
if $CC -Werror -E $f - < /dev/null > /dev/null 2>&1 ; then
|
||||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
printf "%s\n" "yes" >&6; }
|
printf "%s\n" "yes" >&6; }
|
||||||
CFLAGS="$CFLAGS $f"
|
CFLAGS="$CFLAGS $f"
|
||||||
f=-ffat-lto-objects
|
f=-ffat-lto-objects
|
||||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $f" >&5
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $f" >&5
|
||||||
printf %s "checking whether $CC supports $f... " >&6; }
|
printf %s "checking whether $CC supports $f... " >&6; }
|
||||||
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
|
if $CC -Werror -E $f - < /dev/null > /dev/null 2>&1 ; then
|
||||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
printf "%s\n" "yes" >&6; }
|
printf "%s\n" "yes" >&6; }
|
||||||
CFLAGS="$CFLAGS $f"
|
CFLAGS="$CFLAGS $f"
|
||||||
@@ -4123,6 +4161,12 @@ printf "%s\n" "no" >&6; }
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$ac_cv_sizeof_time_t" = "4" ; then
|
||||||
|
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: time_t is 32-bits on this system; attempting to use 64-bit time_t" >&5
|
||||||
|
printf "%s\n" "$as_me: time_t is 32-bits on this system; attempting to use 64-bit time_t" >&6;}
|
||||||
|
CFLAGS="$CFLAGS -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64"
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$ac_cv_perlartifacts" = "yes" ; then
|
if test "$ac_cv_perlartifacts" = "yes" ; then
|
||||||
PERLARTIFACTS=
|
PERLARTIFACTS=
|
||||||
else
|
else
|
||||||
@@ -4173,13 +4217,20 @@ then :
|
|||||||
printf "%s\n" "#define HAVE_INITGROUPS 1" >>confdefs.h
|
printf "%s\n" "#define HAVE_INITGROUPS 1" >>confdefs.h
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
ac_fn_c_check_func "$LINENO" "inotify_init1" "ac_cv_func_inotify_init1"
|
||||||
|
if test "x$ac_cv_func_inotify_init1" = xyes
|
||||||
|
then :
|
||||||
|
printf "%s\n" "#define HAVE_INOTIFY_INIT1 1" >>confdefs.h
|
||||||
|
|
||||||
VERSION=04.02.06
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
VERSION=04.03.04
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1"
|
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile rem2html/rem2html rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1"
|
||||||
|
|
||||||
cat >confcache <<\_ACEOF
|
cat >confcache <<\_ACEOF
|
||||||
# This file is a shell script that caches the results of configure
|
# This file is a shell script that caches the results of configure
|
||||||
@@ -4871,6 +4922,7 @@ do
|
|||||||
"www/Makefile") CONFIG_FILES="$CONFIG_FILES www/Makefile" ;;
|
"www/Makefile") CONFIG_FILES="$CONFIG_FILES www/Makefile" ;;
|
||||||
"src/version.h") CONFIG_FILES="$CONFIG_FILES src/version.h" ;;
|
"src/version.h") CONFIG_FILES="$CONFIG_FILES src/version.h" ;;
|
||||||
"rem2html/Makefile") CONFIG_FILES="$CONFIG_FILES rem2html/Makefile" ;;
|
"rem2html/Makefile") CONFIG_FILES="$CONFIG_FILES rem2html/Makefile" ;;
|
||||||
|
"rem2html/rem2html") CONFIG_FILES="$CONFIG_FILES rem2html/rem2html" ;;
|
||||||
"rem2pdf/Makefile.PL") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.PL" ;;
|
"rem2pdf/Makefile.PL") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.PL" ;;
|
||||||
"rem2pdf/Makefile.top") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.top" ;;
|
"rem2pdf/Makefile.top") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.top" ;;
|
||||||
"rem2pdf/bin/rem2pdf") CONFIG_FILES="$CONFIG_FILES rem2pdf/bin/rem2pdf" ;;
|
"rem2pdf/bin/rem2pdf") CONFIG_FILES="$CONFIG_FILES rem2pdf/bin/rem2pdf" ;;
|
||||||
|
|||||||
23
configure.in
23
configure.in
@@ -30,32 +30,32 @@ AC_PATH_PROG([PERL], [perl])
|
|||||||
|
|
||||||
dnl Checks for libraries.
|
dnl Checks for libraries.
|
||||||
AC_CHECK_LIB(m, sqrt)
|
AC_CHECK_LIB(m, sqrt)
|
||||||
|
AC_CHECK_HEADERS_ONCE([sys/time.h])
|
||||||
|
|
||||||
dnl Integer sizes
|
dnl Integer sizes
|
||||||
AC_CHECK_SIZEOF(unsigned int)
|
AC_CHECK_SIZEOF(unsigned int)
|
||||||
AC_CHECK_SIZEOF(unsigned long)
|
AC_CHECK_SIZEOF(unsigned long)
|
||||||
|
AC_CHECK_SIZEOF(time_t)
|
||||||
|
|
||||||
dnl Checks for header files.
|
dnl Checks for header files.
|
||||||
AC_CHECK_HEADERS(sys/types.h glob.h wctype.h locale.h langinfo.h)
|
AC_CHECK_HEADERS(sys/types.h glob.h wctype.h locale.h langinfo.h sys/inotify.h)
|
||||||
|
|
||||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
AC_STRUCT_TM
|
AC_STRUCT_TM
|
||||||
|
|
||||||
dnl Checks for library functions.
|
dnl Checks for library functions.
|
||||||
AC_FUNC_UTIME_NULL
|
AC_FUNC_UTIME_NULL
|
||||||
AC_CHECK_HEADERS_ONCE([sys/time.h])
|
|
||||||
|
|
||||||
if test "$GCC" = yes; then
|
if test "$GCC" = yes; then
|
||||||
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
|
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
|
||||||
# Check for link-time optimization support
|
# Check for link-time optimization support
|
||||||
f=-flto=auto
|
f=-flto=auto
|
||||||
AC_MSG_CHECKING([whether $CC supports $f])
|
AC_MSG_CHECKING([whether $CC supports $f])
|
||||||
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
|
if $CC -Werror -E $f - < /dev/null > /dev/null 2>&1 ; then
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
CFLAGS="$CFLAGS $f"
|
CFLAGS="$CFLAGS $f"
|
||||||
f=-ffat-lto-objects
|
f=-ffat-lto-objects
|
||||||
AC_MSG_CHECKING([whether $CC supports $f])
|
AC_MSG_CHECKING([whether $CC supports $f])
|
||||||
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
|
if $CC -Werror -E $f - < /dev/null > /dev/null 2>&1 ; then
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
CFLAGS="$CFLAGS $f"
|
CFLAGS="$CFLAGS $f"
|
||||||
else
|
else
|
||||||
@@ -66,6 +66,12 @@ if test "$GCC" = yes; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl If sizeof(time_t) is 4, try to get 64-bit time_t
|
||||||
|
if test "$ac_cv_sizeof_time_t" = "4" ; then
|
||||||
|
AC_MSG_NOTICE([time_t is 32-bits on this system; attempting to use 64-bit time_t])
|
||||||
|
CFLAGS="$CFLAGS -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64"
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$ac_cv_perlartifacts" = "yes" ; then
|
if test "$ac_cv_perlartifacts" = "yes" ; then
|
||||||
PERLARTIFACTS=
|
PERLARTIFACTS=
|
||||||
else
|
else
|
||||||
@@ -80,12 +86,13 @@ if test "$?" != 0 ; then
|
|||||||
echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!"
|
echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
|
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups inotify_init1)
|
||||||
VERSION=04.02.06
|
|
||||||
|
VERSION=04.03.04
|
||||||
AC_SUBST(VERSION)
|
AC_SUBST(VERSION)
|
||||||
AC_SUBST(PERL)
|
AC_SUBST(PERL)
|
||||||
AC_SUBST(PERLARTIFACTS)
|
AC_SUBST(PERLARTIFACTS)
|
||||||
AC_SUBST(RELEASE_DATE)
|
AC_SUBST(RELEASE_DATE)
|
||||||
AC_CONFIG_FILES([src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1])
|
AC_CONFIG_FILES([src/Makefile www/Makefile src/version.h rem2html/Makefile rem2html/rem2html rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
chmod a+x rem2pdf/bin/rem2pdf
|
chmod a+x rem2pdf/bin/rem2pdf
|
||||||
|
|||||||
@@ -19,8 +19,7 @@
|
|||||||
|
|
||||||
;; You should have received a copy of the GNU General Public License
|
;; You should have received a copy of the GNU General Public License
|
||||||
;; along with this program; if not, write to the Free Software
|
;; along with this program; if not, write to the Free Software
|
||||||
;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
|
||||||
;; 02111-1307, USA.
|
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
|
||||||
@@ -514,6 +513,7 @@ Acts on the region or places point where it needs to be."
|
|||||||
(set (make-local-variable 'comment-start) ";")
|
(set (make-local-variable 'comment-start) ";")
|
||||||
(set (make-local-variable 'comment-start) "#")
|
(set (make-local-variable 'comment-start) "#")
|
||||||
(set (make-local-variable 'comment-end) "\n")
|
(set (make-local-variable 'comment-end) "\n")
|
||||||
|
(set (make-local-variable 'comment-end-skip) "[ \t]*\\(\\s>\\||#\\)")
|
||||||
(set (make-local-variable 'skeleton-end-hook) nil) ; so the skeletons will not automatically go to a new line.
|
(set (make-local-variable 'skeleton-end-hook) nil) ; so the skeletons will not automatically go to a new line.
|
||||||
(set (make-local-variable 'fill-column) '100);cause I was having problems with autofill.
|
(set (make-local-variable 'fill-column) '100);cause I was having problems with autofill.
|
||||||
(set (make-local-variable 'indent-line-function) 'remind-indent-line)
|
(set (make-local-variable 'indent-line-function) 'remind-indent-line)
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ Norman Walsh.
|
|||||||
#!/usr/local/bin/wish
|
#!/usr/local/bin/wish
|
||||||
wm withdraw .
|
wm withdraw .
|
||||||
after 15000 { destroy . ; exit }
|
after 15000 { destroy . ; exit }
|
||||||
tk_dialog .d { Message } $argv warning 0 { OK }
|
tk_messageBox -message Message -detail $argv -icon info -type ok
|
||||||
destroy .
|
destroy .
|
||||||
exit
|
exit
|
||||||
-------------- Cut Here ---------- Cut Here ---------- Cut Here -------------
|
-------------- Cut Here ---------- Cut Here ---------- Cut Here -------------
|
||||||
|
|||||||
218
docs/WHATSNEW
218
docs/WHATSNEW
@@ -1,5 +1,223 @@
|
|||||||
CHANGES TO REMIND
|
CHANGES TO REMIND
|
||||||
|
|
||||||
|
* VERSION 4.3 Patch 4 - 2024-03-25
|
||||||
|
|
||||||
|
* NEW FEATURE: remind: Add the new "multitrig" function, which is how "trig"
|
||||||
|
should have worked in the first place. See man page for details.
|
||||||
|
|
||||||
|
* IMPROVEMENT: tkremind: Make errors in your reminders file stand out more
|
||||||
|
prominently.
|
||||||
|
|
||||||
|
* IMPROVEMENT: tkremind: If you click on an error in the "Errors..." popup,
|
||||||
|
tkremind will open a text editor on the offending file and line.
|
||||||
|
|
||||||
|
* IMPROVEMENT: tkremind: Format the "Queue..." output better and make queue
|
||||||
|
items clickable; clicking on a queue item opens a text editor on the
|
||||||
|
corresponding file and line.
|
||||||
|
|
||||||
|
* IMPROVEMENT: Add a standard [$SysInclude]/moonphases.rem file to display
|
||||||
|
moon phases on your calendar.
|
||||||
|
|
||||||
|
* IMPROVEMENT: Clean up the demo code in www/ and add PDF output.
|
||||||
|
|
||||||
|
* BUG FIX: tkremind: Correctly handle filenames containing spaces and other
|
||||||
|
characters that tend to confuse the shell.
|
||||||
|
|
||||||
|
* BUG FIX: tkremind: Raise dialog boxes after errors so that they
|
||||||
|
remain visible.
|
||||||
|
|
||||||
|
* CLEANUP: tkremind: Remove some dead code.
|
||||||
|
|
||||||
|
* VERSION 4.3 Patch 3 - 2024-03-18
|
||||||
|
|
||||||
|
* IMPROVEMENT: tkremind: Update icon to include a white border so it shows
|
||||||
|
up better on dark backgrounds.
|
||||||
|
|
||||||
|
* IMPROVEMENT: C code: Fix a number of cppcheck static-analysis warnings.
|
||||||
|
|
||||||
|
* IMPROVEMENT: remind: Update the "-zj" protocol to include a queue-id for
|
||||||
|
each queued reminder and add the DEL client command to delete a specific
|
||||||
|
item from the queue. Used by tkremind to implement "don't remind me about
|
||||||
|
this again today."
|
||||||
|
|
||||||
|
* MINOR NEW FEATURE: Add a "-ds" debugging flag to print out expression-parsing
|
||||||
|
stack high-water marks on exit. This esoteric feature is of no use to
|
||||||
|
anyone but the Remind author.
|
||||||
|
|
||||||
|
* IMPROVEMENT: tkremind: Stop using the deprecated tk_dialog command in favor
|
||||||
|
of the newer tk_messageBox command.
|
||||||
|
|
||||||
|
* IMPROVEMENT: remind: In server mode, try to minimize redraws by
|
||||||
|
consuming inotify events until at least 0.2s elapses without an
|
||||||
|
event appearing.
|
||||||
|
|
||||||
|
* BUG FIX: tkremind: The "Don't remind me about this again today" feature
|
||||||
|
was unreliable and only worked for reminders created with TkRemind itself.
|
||||||
|
It has been made more reliable and works with any reminder.
|
||||||
|
|
||||||
|
* BUG FIX: remind: Make it a syntax error if a local OMIT in a REM statement
|
||||||
|
is not followed by at least one weekday name.
|
||||||
|
|
||||||
|
* VERSION 4.3 Patch 2 - 2024-03-01
|
||||||
|
|
||||||
|
- BUG FIX: remind: Fix a logic error when implementing the RUN command in
|
||||||
|
server mode. As it turns out, the error is harmless, but it's best to do
|
||||||
|
things correctly.
|
||||||
|
|
||||||
|
- BUG FIX: The Makefile would install the tkremind.png and tkremind.desktop
|
||||||
|
files in the wrong location. This has been fixed.
|
||||||
|
|
||||||
|
* VERSION 4.3 Patch 1 - 2024-02-29
|
||||||
|
|
||||||
|
- BUG FIX: tests: "make test" could fail because of a bad test. This
|
||||||
|
has been fixed. There are no actual code changes to any of the programs
|
||||||
|
in Remind compared to 04.03.00.
|
||||||
|
|
||||||
|
* VERSION 4.3 Patch 0 - 2024-02-29
|
||||||
|
|
||||||
|
- IMPROVEMENT: remind: If Remind is compiled on a system that supports
|
||||||
|
inotify, then in server mode (-z0 or -zj) it monitors the reminders file
|
||||||
|
and restarts itself if it detects a change, and also notifies the client.
|
||||||
|
Moving inotify support directly into Remind means that tkremind no longer
|
||||||
|
has to invoke a separate inotifywait process.
|
||||||
|
|
||||||
|
- IMPROVEMENT: remind: Set the CLOEXEC flag on files we open so we
|
||||||
|
don't leak file descriptors to programs that we run. While I don't
|
||||||
|
think there's a security issue here (any program you run can do
|
||||||
|
anything as your userid anyway) it's best to be clean and tidy.
|
||||||
|
|
||||||
|
- IMPROVEMENT: remind: Add localization for the Catalan language, courtesy
|
||||||
|
of Eloi Torrents.
|
||||||
|
|
||||||
|
- IMPROVEMENT: tkremind: Add a .desktop file and icon so TkRemind can be
|
||||||
|
integrated into the desktop menu system, courtesy of Eloi Torrents.
|
||||||
|
|
||||||
|
- CHANGE: Add a new server mode with the "-zj" flag. This is just
|
||||||
|
like "-z0" except it uses JSON messages to communicate with the
|
||||||
|
client rather than an ad-hoc protocol. The "-z0" mode is still
|
||||||
|
supported, but is deprecated.
|
||||||
|
|
||||||
|
- CHANGE: In server mode (-z0 or -zj) any RUN-type reminders, or message
|
||||||
|
commands of the "-kcommand" type are run with standard input and standard
|
||||||
|
output connected to /dev/null. NOTE INCOMPATIBILITY: If you previously
|
||||||
|
relied on RUN-type reminders to pop up reminders in TkRemind, they no
|
||||||
|
longer do. If you want this, you'll have to get the command that you
|
||||||
|
run to pop up its own window with "xmessage" or something similar.
|
||||||
|
|
||||||
|
- IMPROVEMENT: tkremind: Make the "Go to date..." dialog non-modal.
|
||||||
|
|
||||||
|
- CHANGE: remind: Allow the argument to easterdate() and
|
||||||
|
orthodoxeaster() to be omitted, in which case it defaults to
|
||||||
|
today().
|
||||||
|
|
||||||
|
- BUG FIX: Miscellaneous man page fixes.
|
||||||
|
|
||||||
|
- BUG FIX: Fix a leap-year edge-case. The reminder: REM 29 MSG whatever
|
||||||
|
was not triggered on Feb 29 of leap years.
|
||||||
|
|
||||||
|
- BUG FIX: rem2html: Make the version of rem2html track the version of
|
||||||
|
Remind. Noted by Ian! D. Allen.
|
||||||
|
|
||||||
|
* VERSION 4.2 Patch 9 - 2024-02-04
|
||||||
|
|
||||||
|
- CHANGE: remind: Do not attempt to guess terminal background color on
|
||||||
|
startup. Only obtain it as needed. This can prevent mojibake from
|
||||||
|
appearing on terminals that don't support the color query escape
|
||||||
|
sequence.
|
||||||
|
|
||||||
|
- IMPROVEMENT: remind: Add new system variables $NumFullOmits,
|
||||||
|
$MaxFullOmits, $NumPartialOmits and $MaxPartialOmits.
|
||||||
|
|
||||||
|
- IMPROVEMENT: remind: Issue a warning if someone OMITs every possible date.
|
||||||
|
|
||||||
|
- IMPROVEMENT: remind: In several error messages complaining about limits
|
||||||
|
being exceeded, include the actual limit in the error message. Clarify
|
||||||
|
the man page regarding limits on the number of OMITs.
|
||||||
|
|
||||||
|
- MINOR NEW FEATURE: remind: The expression STRING * INT or INT * STRING
|
||||||
|
is now accepted and yields a string that is INT concatenations of the
|
||||||
|
original STRING. In this case, INT must be non-negative and the total
|
||||||
|
string length can't exceed $MaxStringLen.
|
||||||
|
|
||||||
|
- DOCUMENTATION: Add "Astronomical Algorithms" by Jean Meeus to bibliography.
|
||||||
|
|
||||||
|
- DOCUMENTATION FIX: Update address of the Free Software Foundation in the
|
||||||
|
license file.
|
||||||
|
|
||||||
|
- DOCUMENTATION: Note that rem2ps is deprecated and will not received any
|
||||||
|
new features. Further development will happen on rem2pdf.
|
||||||
|
|
||||||
|
- BUG FIX: Preserve the filename() and priority context for queued reminders.
|
||||||
|
Previously, the filename information was lost and the priority was
|
||||||
|
coming from uninitialized memory (yikes!). bug found by Alexander
|
||||||
|
Möller.
|
||||||
|
|
||||||
|
- BUG FIX: build.tk: Various minor improvements.
|
||||||
|
|
||||||
|
- BUG FIX: remind: In server mode, if we de-queue a reminder without
|
||||||
|
triggering it, issue a "NOTE queued %d" message to update the
|
||||||
|
client's notion of the queue size.
|
||||||
|
|
||||||
|
- BUG FIX: tkremind: Fix typo found by Lorenzo Bazzanini.
|
||||||
|
|
||||||
|
* VERSION 4.2 Patch 8 - 2023-12-14
|
||||||
|
|
||||||
|
- NEW FEATURE: Add the $MaxLateMinutes system variable. This suppresses
|
||||||
|
a queued time reminder if the current time is more than $MaxLateMinutes
|
||||||
|
past the trigger time. (This typically only occurs if the computer
|
||||||
|
has been suspended/hibernated and then resumed.)
|
||||||
|
|
||||||
|
- IMPROVEMENT: tkremind: If an error occurs during printing, catch it
|
||||||
|
and change the Queue... button to Errors... (the same way errors in
|
||||||
|
reminder files are handled.)
|
||||||
|
|
||||||
|
- IMPROVEMENT: rem2html: add the --utf8 flag to set the HTML charset to
|
||||||
|
UTF-8.
|
||||||
|
|
||||||
|
- MINOR IMPROVEMENTS: Refactor some of the C code; use symbolic exit
|
||||||
|
statuses and file descriptors for stdin/stdout/stderr where possible.
|
||||||
|
|
||||||
|
- BUG FIX: configure.in: Use better option detection so we don't use the
|
||||||
|
unsupported option -ffat-lto-objects if compiling with clang instead of gcc.
|
||||||
|
|
||||||
|
- BUG FIXES: Many fixes to man pages, some by Jochen Sprickerhof
|
||||||
|
|
||||||
|
- MINOR BUG FIX: If Remind puts itself in the background, only close
|
||||||
|
stdout/stderr if they are not associated with a terminal. If
|
||||||
|
we close a descriptor, dup /dev/null onto it.
|
||||||
|
|
||||||
|
- MINOR BUG FIX: Catch SIGCONT when running in daemon/background mode.
|
||||||
|
This forces the select() call to be interrupted so we can update the
|
||||||
|
sleep time. This really only matters if the computer or the background
|
||||||
|
Remind process is suspended and then resumed.
|
||||||
|
|
||||||
|
* VERSION 4.2 Patch 7 - 2023-10-09
|
||||||
|
|
||||||
|
- IMPROVEMENT: remind: On 32-bit systems, attempt to use a 64-bit time_t
|
||||||
|
if the C library supports that. This lets Remind work properly with
|
||||||
|
dates after 2038 in the few cases it has to call mktime() internally.
|
||||||
|
|
||||||
|
- MINOR NEW FEATURE: remind: Attempt to obtain the terminal background
|
||||||
|
color using an OSC sequence. This normally only happens if standard
|
||||||
|
output is a terminal, but can be forced with the '-@..,t' option.
|
||||||
|
|
||||||
|
- MINOR NEW FEATURE: remind: Add "--version" long option to print out
|
||||||
|
Remind's version and exit.
|
||||||
|
|
||||||
|
- MINOR IMPROVEMENT: tkremind: Use a higher-resolution PNG image for
|
||||||
|
the icon.
|
||||||
|
|
||||||
|
- MINOR IMPROVEMENT: remind-conf-mode.el: Update highlighting rules
|
||||||
|
courtesy of Bill Benedetto
|
||||||
|
|
||||||
|
- MINOR CHANGE: Make AT optional. If we encounter a TIME in a REM
|
||||||
|
command, implicitly begin an AT clause.
|
||||||
|
|
||||||
|
- DOCUMENTATION: Many minor fixes and improvements courtesy of Dan Jacobson.
|
||||||
|
|
||||||
|
- BUG FIX: Make "-w0" set the calendar width based on standard output
|
||||||
|
rather than setting it to zero and causing an infinite loop.
|
||||||
|
|
||||||
* VERSION 4.2 Patch 6 - 2023-09-12
|
* VERSION 4.2 Patch 6 - 2023-09-12
|
||||||
|
|
||||||
- NEW FEATURE: remind: The "nonomitted()" function takes an optional
|
- NEW FEATURE: remind: The "nonomitted()" function takes an optional
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ FSET center(x) pad("", " ", (columns() - columns(x))/2) + x
|
|||||||
FSET right(x) pad("", " ", columns() - columns(x)) + x
|
FSET right(x) pad("", " ", columns() - columns(x)) + x
|
||||||
|
|
||||||
MSG This is left-aligned.
|
MSG This is left-aligned.
|
||||||
MSG [ansicolor(0,255,0)]This is also left-aligned.[ansicolor("")]
|
MSG [ansicolor(0,255,0)]🌕 🌕 🌕 🌕 This is also left-aligned.[ansicolor("")]
|
||||||
|
|
||||||
MSG [center("This is centered.")]
|
MSG [center("This is centered.")]
|
||||||
MSG [ansicolor(255,255,0) + center("🌕 🌕 🌕 🌕 This is also centered. ") + ansicolor("")]
|
MSG [ansicolor(255,255,0) + center("🌕 🌕 🌕 🌕 This is also centered. ") + ansicolor("")]
|
||||||
|
|||||||
@@ -8,15 +8,13 @@
|
|||||||
# Set this variable to 1 if your terminal has a dark background or 0 if
|
# Set this variable to 1 if your terminal has a dark background or 0 if
|
||||||
# it: light.
|
# it: light.
|
||||||
|
|
||||||
bg_dark=1
|
|
||||||
|
|
||||||
# Set your latitude and longitude correctly for Sunrise/Sunset/Equinox/Solstice
|
# Set your latitude and longitude correctly for Sunrise/Sunset/Equinox/Solstice
|
||||||
#
|
#
|
||||||
# The values below are for Ottawa, Ontario, Canada
|
# The values below are for Ottawa, Ontario, Canada
|
||||||
latitude="45.420556"
|
latitude="45.420556"
|
||||||
longitude="-75.689722"
|
longitude="-75.689722"
|
||||||
|
|
||||||
remind -g -ibg_dark="$bg_dark" "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
|
remind -g "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
|
||||||
SET $AddBlankLines 0
|
SET $AddBlankLines 0
|
||||||
BANNER %
|
BANNER %
|
||||||
|
|
||||||
@@ -24,24 +22,25 @@ INCLUDE [$SysInclude]/ansitext.rem
|
|||||||
|
|
||||||
MSG Today is [ansi_bold][$T][ansi_normal], being the [ord($T-date(year($T),1,1)+1)] day of [year($T)].%_
|
MSG Today is [ansi_bold][$T][ansi_normal], being the [ord($T-date(year($T),1,1)+1)] day of [year($T)].%_
|
||||||
|
|
||||||
IF bg_dark
|
IF $TerminalBackground == 0
|
||||||
SPECIAL COLOR 255 255 0 Sunrise: 🌅 [sunrise()] today and [sunrise($T+1)] tomorrow
|
SPECIAL COLOR 255 255 0 Sunrise: 🌅 [sunrise()] today and [sunrise($T+1)] tomorrow
|
||||||
SPECIAL COLOR 255 128 0 Sunset: 🌇 [sunset()] today and [sunset($T+1)] tomorrow%_
|
SPECIAL COLOR 255 128 0 Sunset: 🌇 [sunset()] today and [sunset($T+1)] tomorrow%_
|
||||||
|
ELSE
|
||||||
|
SPECIAL COLOR 128 128 0 Sunrise: 🌅 [sunrise()] today and [sunrise($T+1)] tomorrow
|
||||||
|
SPECIAL COLOR 128 32 0 Sunset: 🌇 [sunset()] today and [sunset($T+1)] tomorrow%_
|
||||||
|
|
||||||
ENDIF
|
ENDIF
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
remind -g -ibg_dark="$bg_dark" "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
|
remind -g "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
|
||||||
SET $AddBlankLines 0
|
SET $AddBlankLines 0
|
||||||
BANNER %
|
BANNER %
|
||||||
IF bg_dark
|
IF $TerminalBackground == 0
|
||||||
REM [moondatetime(0)] +60 SPECIAL COLOR 255 255 0 New moon: 🌑 [$T] %3 (%b)
|
REM [moondatetime(0)] +60 SPECIAL COLOR 255 255 0 New moon: 🌑 [$T] %3 (%b)
|
||||||
REM [moondatetime(1)] +60 SPECIAL COLOR 255 255 128 First Quarter: 🌓 [$T] %3 (%b)
|
REM [moondatetime(1)] +60 SPECIAL COLOR 255 255 128 First Quarter: 🌓 [$T] %3 (%b)
|
||||||
REM [moondatetime(2)] +60 SPECIAL COLOR 255 255 255 Full moon: 🌕 [$T] %3 (%b)
|
REM [moondatetime(2)] +60 SPECIAL COLOR 255 255 255 Full moon: 🌕 [$T] %3 (%b)
|
||||||
REM [moondatetime(3)] +60 SPECIAL COLOR 255 255 128 Last Quarter: 🌗 [$T] %3 (%b)
|
REM [moondatetime(3)] +60 SPECIAL COLOR 255 255 128 Last Quarter: 🌗 [$T] %3 (%b)
|
||||||
ELSE
|
ELSE
|
||||||
SPECIAL COLOR 128 128 0 Sunrise: 🌅 [sunrise()] today and [sunrise($T+1)] tomorrow
|
|
||||||
SPECIAL COLOR 128 32 0 Sunset: 🌇 [sunset()] today and [sunset($T+1)] tomorrow%_
|
|
||||||
|
|
||||||
REM [moondatetime(0)] +60 SPECIAL COLOR 128 128 0 New moon: 🌑 [$T] %3 (%b)
|
REM [moondatetime(0)] +60 SPECIAL COLOR 128 128 0 New moon: 🌑 [$T] %3 (%b)
|
||||||
REM [moondatetime(1)] +60 SPECIAL COLOR 128 128 64 First Quarter: 🌓 [$T] %3 (%b)
|
REM [moondatetime(1)] +60 SPECIAL COLOR 128 128 64 First Quarter: 🌓 [$T] %3 (%b)
|
||||||
REM [moondatetime(2)] +60 SPECIAL COLOR 0 0 0 Full moon: 🌕 [$T] %3 (%b)
|
REM [moondatetime(2)] +60 SPECIAL COLOR 0 0 0 Full moon: 🌕 [$T] %3 (%b)
|
||||||
@@ -51,7 +50,7 @@ EOF
|
|||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
remind -g -ibg_dark="$bg_dark" "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
|
remind -g "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
|
||||||
SET $AddBlankLines 0
|
SET $AddBlankLines 0
|
||||||
BANNER %
|
BANNER %
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
# "#PSSTUFF" for nifty PostScript examples #
|
# "#PSSTUFF" for nifty PostScript examples #
|
||||||
# #
|
# #
|
||||||
# This file is part of REMIND. #
|
# This file is part of REMIND. #
|
||||||
# Copyright (C) 1992-2023 Dianne Skoll #
|
# Copyright (C) 1992-2024 Dianne Skoll #
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
# #
|
# #
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# Not all sequences are supported by all terminals.
|
# Not all sequences are supported by all terminals.
|
||||||
|
|
||||||
# This file is part of REMIND
|
# This file is part of REMIND
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
if !defined("ansi_bold")
|
if !defined("ansi_bold")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# US holidays
|
# US holidays
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# Copyright (C) 1992-2023 Dianne Skoll
|
# Copyright (C) 1992-2024 Dianne Skoll
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
REM [easterdate($Uy)-46] MSG Ash Wednesday
|
REM [easterdate($Uy)-46] MSG Ash Wednesday
|
||||||
|
|||||||
53
include/lang/ca.rem
Normal file
53
include/lang/ca.rem
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# Support for the Catalan language.
|
||||||
|
# This file is part of REMIND.
|
||||||
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
|
# This file was created by Eloi Torrents <eloitor@disroot.org>
|
||||||
|
|
||||||
|
SET $Monday "dilluns"
|
||||||
|
SET $Tuesday "dimarts"
|
||||||
|
SET $Wednesday "dimecres"
|
||||||
|
SET $Thursday "dijous"
|
||||||
|
SET $Friday "divendres"
|
||||||
|
SET $Saturday "dissabte"
|
||||||
|
SET $Sunday "diumenge"
|
||||||
|
|
||||||
|
SET $January "gener"
|
||||||
|
SET $February "febrer"
|
||||||
|
SET $March "març"
|
||||||
|
SET $April "abril"
|
||||||
|
SET $May "maig"
|
||||||
|
SET $June "juny"
|
||||||
|
SET $July "juliol"
|
||||||
|
SET $August "agost"
|
||||||
|
SET $September "setembre"
|
||||||
|
SET $October "octubre"
|
||||||
|
SET $November "novembre"
|
||||||
|
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")
|
||||||
|
|
||||||
|
# 1 d'abril vs 1 de maig.
|
||||||
|
FSET subst_sx(a,d,t) iif(isany(substr(mon(d), 1, 1), "a", "o") , "d'", "de")
|
||||||
|
FSET subst_ordinal(d) ""
|
||||||
|
|
||||||
|
BANNER Agenda pel %w, %d %s %m de %y%o:
|
||||||
|
|
||||||
|
SET $Am "am"
|
||||||
|
SET $Pm "pm"
|
||||||
|
|
||||||
|
SET $Ago "fa"
|
||||||
|
SET $Fromnow "des d'avui"
|
||||||
|
SET $On "el dia"
|
||||||
|
SET $Now "ara"
|
||||||
|
SET $At "a les"
|
||||||
|
|
||||||
|
SET $Minute "minut"
|
||||||
|
SET $Mplu "s"
|
||||||
|
SET $Hour "hora"
|
||||||
|
FSET subst_hours(h) iif(h==1, "1 hora", h + " hores")
|
||||||
|
|
||||||
|
SET $Is "és"
|
||||||
|
SET $Was "va ser"
|
||||||
|
SET $And "i"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the Danish language.
|
# Support for the Danish language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Mogens Lynnerup.
|
# This file is derived from a translation by Mogens Lynnerup.
|
||||||
|
|
||||||
SET $Sunday "Søndag"
|
SET $Sunday "Søndag"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the German language.
|
# Support for the German language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Wolfgang Thronicke
|
# This file is derived from a translation by Wolfgang Thronicke
|
||||||
|
|
||||||
# Day names
|
# Day names
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Support for the English language.
|
# Support for the English language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# Nothing to do for English since it is the default.
|
# Nothing to do for English since it is the default.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the Spanish language.
|
# Support for the Spanish language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Rafa Couto <rafacouto@biogate.com>
|
# This file is derived from a translation by Rafa Couto <rafacouto@biogate.com>
|
||||||
|
|
||||||
SET $Sunday "Domingo"
|
SET $Sunday "Domingo"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the Finnish language.
|
# Support for the Finnish language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Mikko Silvonen
|
# This file is derived from a translation by Mikko Silvonen
|
||||||
|
|
||||||
SET $Sunday "sunnuntai"
|
SET $Sunday "sunnuntai"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the French language.
|
# Support for the French language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Laurent Duperval
|
# This file is derived from a translation by Laurent Duperval
|
||||||
|
|
||||||
SET $Sunday "dimanche"
|
SET $Sunday "dimanche"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the Hellenic (Greek) language.
|
# Support for the Hellenic (Greek) language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by jarlaxl lamat (jarlaxl@freemail.gr)
|
# This file is derived from a translation by jarlaxl lamat (jarlaxl@freemail.gr)
|
||||||
|
|
||||||
SET $Sunday "Κυριακή"
|
SET $Sunday "Κυριακή"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the Icelanding language.
|
# Support for the Icelanding language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Björn Davíðsson (bjossi@snerpa.is)
|
# This file is derived from a translation by Björn Davíðsson (bjossi@snerpa.is)
|
||||||
|
|
||||||
SET $Sunday "sunnudagur"
|
SET $Sunday "sunnudagur"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the Italian language.
|
# Support for the Italian language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Valerio Aimale
|
# This file is derived from a translation by Valerio Aimale
|
||||||
|
|
||||||
SET $Sunday "Domenica"
|
SET $Sunday "Domenica"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the Dutch language.
|
# Support for the Dutch language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Willem Kasdorp and Erik-Jan Vens
|
# This file is derived from a translation by Willem Kasdorp and Erik-Jan Vens
|
||||||
|
|
||||||
SET $Sunday "zondag"
|
SET $Sunday "zondag"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the Norwegian language.
|
# Support for the Norwegian language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Trygve Randen
|
# This file is derived from a translation by Trygve Randen
|
||||||
|
|
||||||
SET $Sunday "Søndag"
|
SET $Sunday "Søndag"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the Polish language.
|
# Support for the Polish language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Jerzy Sobczyk
|
# This file is derived from a translation by Jerzy Sobczyk
|
||||||
|
|
||||||
SET $Sunday "Niedziela"
|
SET $Sunday "Niedziela"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the (Brazilian) Portuguese language.
|
# Support for the (Brazilian) Portuguese language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Marco Paganini
|
# This file is derived from a translation by Marco Paganini
|
||||||
|
|
||||||
SET $Sunday "domingo"
|
SET $Sunday "domingo"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Support for the Romanian language.
|
# Support for the Romanian language.
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
|
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||||
# This file is derived from a translation by Liviu Daia
|
# This file is derived from a translation by Liviu Daia
|
||||||
|
|
||||||
SET $Sunday "Duminică"
|
SET $Sunday "Duminică"
|
||||||
|
|||||||
14
include/moonphases.rem
Normal file
14
include/moonphases.rem
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Moon phases
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
IF $CalMode || $PsCal
|
||||||
|
REM [moondate(0)] SPECIAL MOON 0 -1 -1 [moontime(0)]
|
||||||
|
REM [moondate(1)] SPECIAL MOON 1 -1 -1 [moontime(1)]
|
||||||
|
REM [moondate(2)] SPECIAL MOON 2 -1 -1 [moontime(2)]
|
||||||
|
REM [moondate(3)] SPECIAL MOON 3 -1 -1 [moontime(3)]
|
||||||
|
ELSE
|
||||||
|
REM NOQUEUE [moondatetime(0)] MSG New Moon (%2)
|
||||||
|
REM NOQUEUE [moondatetime(1)] MSG First Quarter (%2)
|
||||||
|
REM NOQUEUE [moondatetime(2)] MSG Full Moon (%2)
|
||||||
|
REM NOQUEUE [moondatetime(3)] MSG Last Quarter (%2)
|
||||||
|
ENDIF
|
||||||
@@ -19,4 +19,4 @@ Remind was written by Dianne Skoll <dianne@skoll.ca>
|
|||||||
.SH HOME PAGE
|
.SH HOME PAGE
|
||||||
https://dianne.skoll.ca/projects/remind/
|
https://dianne.skoll.ca/projects/remind/
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
\fBremind\fR
|
\fBremind\fR(1)
|
||||||
|
|||||||
@@ -5,22 +5,25 @@ rem2ps \- draw a PostScript calendar from Remind output
|
|||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B rem2ps [\fIoptions\fR]
|
.B rem2ps [\fIoptions\fR]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\fBRem2ps\fR reads the standard input, which should be the results of
|
\fBrem2ps\fR reads the standard input, which should be the results of
|
||||||
running \fBRemind\fR with the \fB\-p\fR or \fB\-pp\fR option. It
|
running \fBRemind\fR with the \fB\-p\fR or \fB\-pp\fR option. It
|
||||||
emits PostScript code (which draws a calendar) to the standard output.
|
emits PostScript code (which draws a calendar) to the standard output.
|
||||||
.PP
|
.PP
|
||||||
See the section "Rem2PS Input Format" for details about the \fB\-p\fR
|
Although \fBrem2ps\fR will be maintained, no new features will be added
|
||||||
|
to it. Instead, all new development will continue on \fBrem2pdf\fR.
|
||||||
|
.PP
|
||||||
|
See the section "REM2PS INPUT FORMAT" for details about the \fB\-p\fR
|
||||||
data. This may be useful if you wish to create other \fBRemind\fR
|
data. This may be useful if you wish to create other \fBRemind\fR
|
||||||
back-ends.
|
back-ends.
|
||||||
.PP
|
.PP
|
||||||
Note that \fBRem2PS\fR does not handle UTF-8 input. If you need to
|
Note that \fBrem2ps\fR does not handle UTF-8 input. If you need to
|
||||||
render characters outside the ASCII character set, see
|
render characters outside the ASCII character set, see
|
||||||
\fBrem2pdf\fR instead.
|
\fBrem2pdf\fR instead.
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B \-v
|
.B \-v
|
||||||
Be more verbose. This causes \fBRem2ps\fR to print progress messages
|
Be more verbose. This causes \fBrem2ps\fR to print progress messages
|
||||||
to the standard error stream. Normally, it is silent.
|
to the standard error stream. Normally, it is silent.
|
||||||
.TP
|
.TP
|
||||||
.B \-p file
|
.B \-p file
|
||||||
@@ -133,7 +136,7 @@ numbers.
|
|||||||
|
|
||||||
.PP
|
.PP
|
||||||
Type "rem2ps \-m help" for a list of available media. Note that the media
|
Type "rem2ps \-m help" for a list of available media. Note that the media
|
||||||
type (and all \fBRem2ps\fR options) are case-sensitive. If you don't use
|
type (and all \fBrem2ps\fR options) are case-sensitive. If you don't use
|
||||||
the \fB\-m\fR option, the media defaults to a compiled-in default - this
|
the \fB\-m\fR option, the media defaults to a compiled-in default - this
|
||||||
is usually Letter for North America and A4 for Europe. The "\-m help"
|
is usually Letter for North America and A4 for Europe. The "\-m help"
|
||||||
option will display the compiled-in default.
|
option will display the compiled-in default.
|
||||||
@@ -193,8 +196,8 @@ for good output:
|
|||||||
rem2ps \-ol 72 \-sh 12
|
rem2ps \-ol 72 \-sh 12
|
||||||
.fi
|
.fi
|
||||||
.SH USAGE
|
.SH USAGE
|
||||||
To use \fBRem2ps\fR, you should pipe the output of \fBRemind\fR with the \fB\-p\fR
|
To use \fBrem2ps\fR, you should pipe the output of \fBRemind\fR with the \fB\-p\fR
|
||||||
option to \fBRem2ps\fR, and then send the result to a printer. This is most easily
|
option to \fBrem2ps\fR, and then send the result to a printer. This is most easily
|
||||||
illustrated with examples:
|
illustrated with examples:
|
||||||
.PP
|
.PP
|
||||||
.nf
|
.nf
|
||||||
@@ -228,10 +231,10 @@ calendar entries. This border is normally blank space.
|
|||||||
.TP
|
.TP
|
||||||
BoxWidth and BoxHeight
|
BoxWidth and BoxHeight
|
||||||
The width and height of the calendar box, from center-to-center of the
|
The width and height of the calendar box, from center-to-center of the
|
||||||
black gridlines.
|
black grid lines.
|
||||||
.TP
|
.TP
|
||||||
InBoxHeight
|
InBoxHeight
|
||||||
The height from the center of the bottom black gridline to the top
|
The height from the center of the bottom black grid line to the top
|
||||||
of the regular calendar entry area. The space from here to the top
|
of the regular calendar entry area. The space from here to the top
|
||||||
of the box is used only to draw the day number.
|
of the box is used only to draw the day number.
|
||||||
.TP
|
.TP
|
||||||
@@ -260,7 +263,7 @@ PostScript files. Always test your PostScript thoroughly with a PostScript
|
|||||||
viewer before sending it to the printer. You should not use any document
|
viewer before sending it to the printer. You should not use any document
|
||||||
structuring comments in your PostScript code.
|
structuring comments in your PostScript code.
|
||||||
.PP
|
.PP
|
||||||
In addition, prior to drawing a calendar page, \fBRem2ps\fR emits
|
In addition, prior to drawing a calendar page, \fBrem2ps\fR emits
|
||||||
the following PostScript code:
|
the following PostScript code:
|
||||||
.PP
|
.PP
|
||||||
.nf
|
.nf
|
||||||
@@ -320,14 +323,14 @@ For an example, create a file called "myprolog" whose contents are:
|
|||||||
} bind def
|
} bind def
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
Use that file with the \fBRem2ps\fR \fB\-p\fR option to create calendars
|
Use that file with the \fBrem2ps\fR \fB\-p\fR option to create calendars
|
||||||
with the year and month in large grey letters in the background of the
|
with the year and month in large gray letters in the background of the
|
||||||
calendar.
|
calendar.
|
||||||
.PP
|
.PP
|
||||||
.SH REM2PS INPUT FORMAT (-P OPTION)
|
.SH REM2PS INPUT FORMAT (-P OPTION)
|
||||||
The \fB\-p\fR option is an older, simpler interchange format used by
|
The \fB\-p\fR option is an older, simpler interchange format used by
|
||||||
\fBRemind\fR to communicate with back-ends. New back-ends are
|
\fBRemind\fR to communicate with back-ends. New back-ends are
|
||||||
encoraged to support the new \fB\-pp\fR format preferably, though they
|
encouraged to support the new \fB\-pp\fR format preferably, though they
|
||||||
are encouraged to support the older \fB\-p\fR format as well if the
|
are encouraged to support the older \fB\-p\fR format as well if the
|
||||||
older format contains enough information for them to work properly.
|
older format contains enough information for them to work properly.
|
||||||
.PP
|
.PP
|
||||||
@@ -380,7 +383,7 @@ been set to "-". The consistent use of "/" is designed to ease parsing.
|
|||||||
.PP
|
.PP
|
||||||
\fIspecial\fR is a string used
|
\fIspecial\fR is a string used
|
||||||
for "out-of-band" communication with back-ends. If the reminder
|
for "out-of-band" communication with back-ends. If the reminder
|
||||||
is a normal reminder, \fIspecial\fR is "*". The \fBRem2PS\fR
|
is a normal reminder, \fIspecial\fR is "*". The \fBrem2ps\fR
|
||||||
back-end understands the specials \fBPostScript\fR and \fBPSFile\fR.
|
back-end understands the specials \fBPostScript\fR and \fBPSFile\fR.
|
||||||
Other back-ends may understand other specials. A back end should
|
Other back-ends may understand other specials. A back end should
|
||||||
\fIsilently ignore\fR a reminder with a special it doesn't understand.
|
\fIsilently ignore\fR a reminder with a special it doesn't understand.
|
||||||
@@ -458,7 +461,7 @@ JSON object. The keys that may be present in the JSON object are as
|
|||||||
follows:
|
follows:
|
||||||
.TP
|
.TP
|
||||||
.B date \fIYYYY-MM-DD\fR
|
.B date \fIYYYY-MM-DD\fR
|
||||||
The \fbdate\fR key will \fIalways\fR be present; it is the trigger date
|
The \fBdate\fR key will \fIalways\fR be present; it is the trigger date
|
||||||
of the reminder expressed as a string in the format \fIYYYY-MM-DD\fR
|
of the reminder expressed as a string in the format \fIYYYY-MM-DD\fR
|
||||||
.TP
|
.TP
|
||||||
.B filename \fIf\fR
|
.B filename \fIf\fR
|
||||||
@@ -674,17 +677,17 @@ is desired.
|
|||||||
|
|
||||||
|
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Rem2PS was written by Dianne Skoll <dianne@skoll.ca>
|
rem2ps was written by Dianne Skoll <dianne@skoll.ca>
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
All \fBRem2ps\fR options are case-sensitive, unlike \fBRemind\fR.
|
All \fBrem2ps\fR options are case-sensitive, unlike \fBRemind\fR.
|
||||||
Any time you supply
|
Any time you supply
|
||||||
a font name or size, line thickness, or border width, it is treated as a
|
a font name or size, line thickness, or border width, it is treated as a
|
||||||
string and sent straight to the PostScript interpreter. Thus, if you
|
string and sent straight to the PostScript interpreter. Thus, if you
|
||||||
supply invalid fonts or sizes, \fBRem2ps\fR will not complain, but the
|
supply invalid fonts or sizes, \fBrem2ps\fR will not complain, but the
|
||||||
resulting PostScript output will probably not work.
|
resulting PostScript output will probably not work.
|
||||||
.PP
|
.PP
|
||||||
You should ensure that the values you supply for margin widths are sensible.
|
You should ensure that the values you supply for margin widths are sensible.
|
||||||
If they are too big for the media size, \fBRem2ps\fR will not complain,
|
If they are too big for the media size, \fBrem2ps\fR will not complain,
|
||||||
but again, the PostScript output will probably not work.
|
but again, the PostScript output will probably not work.
|
||||||
.SH HOME PAGE
|
.SH HOME PAGE
|
||||||
https://dianne.skoll.ca/projects/remind/
|
https://dianne.skoll.ca/projects/remind/
|
||||||
|
|||||||
223
man/remind.1.in
223
man/remind.1.in
@@ -28,6 +28,10 @@ Anything after the __EOF__ marker is completely ignored.
|
|||||||
\fBRemind\fR has a slew of options. If you're new to the program,
|
\fBRemind\fR has a slew of options. If you're new to the program,
|
||||||
ignore them for now and skip to the section "REMINDER FILES".
|
ignore them for now and skip to the section "REMINDER FILES".
|
||||||
.TP
|
.TP
|
||||||
|
.B \-\-version
|
||||||
|
The \fB\-\-version\fR option causes \fBRemind\fR to print its version number
|
||||||
|
to standard output and then exit.
|
||||||
|
.TP
|
||||||
.B \-n
|
.B \-n
|
||||||
The \fB\-n\fR option causes \fBRemind\fR to print the \fBnext\fR occurrence
|
The \fB\-n\fR option causes \fBRemind\fR to print the \fBnext\fR occurrence
|
||||||
of each reminder in a simple calendar format. You can sort this by
|
of each reminder in a simple calendar format. You can sort this by
|
||||||
@@ -62,7 +66,7 @@ causes \fBRemind\fR to display reminders on the calendar on the
|
|||||||
day they actually occur \fIas well as\fR on any preceding days
|
day they actually occur \fIas well as\fR on any preceding days
|
||||||
specified by the reminder's \fIdelta\fR. This \fIalso\fR causes
|
specified by the reminder's \fIdelta\fR. This \fIalso\fR causes
|
||||||
\fBRemind\fR to include text outside %"...%" sequences that would
|
\fBRemind\fR to include text outside %"...%" sequences that would
|
||||||
otherwise be removed (though the actual %" markers themseves are removed.)
|
otherwise be removed (though the actual %" markers themselves are removed.) \"" Add comment to avoid Emacs highlighting problems
|
||||||
.TP
|
.TP
|
||||||
.B 'l'
|
.B 'l'
|
||||||
causes \fBRemind\fR to use VT100 line-drawing characters to draw
|
causes \fBRemind\fR to use VT100 line-drawing characters to draw
|
||||||
@@ -105,11 +109,18 @@ If the optional \fIm\fR parameter is supplied following a comma, then
|
|||||||
\fIm\fR=0 tells \fBRemind\fR that the terminal background is dark, and
|
\fIm\fR=0 tells \fBRemind\fR that the terminal background is dark, and
|
||||||
\fBRemind\fR will brighten up dark colors to make them visible. If
|
\fBRemind\fR will brighten up dark colors to make them visible. If
|
||||||
\fIm\fR=1, then \fBRemind\fR assumes the terminal background is light
|
\fIm\fR=1, then \fBRemind\fR assumes the terminal background is light
|
||||||
and it will darken bright colors to make them visible. If no \fIm\fR
|
and it will darken bright colors to make them visible. If \fIm\fR is
|
||||||
is supplied, or it is supplied as \fIm\fR=2, then \fBRemind\fR does
|
specified as 2, then \fBRemind\fR does not perform any adjustments,
|
||||||
not perform any adjustments, and some reminders may be hard or
|
and some reminders may be hard or impossible to see if the color is
|
||||||
impossible to see if the color is too close to the terminal background
|
too close to the terminal background color. If you supply the letter
|
||||||
color.
|
\fBt\fR rather than a number, then Remind attempts to guess the background
|
||||||
|
color of the terminal, \fIeven if\fR stdout is not a terminal.
|
||||||
|
.PP
|
||||||
|
On startup, if the standard output is a terminal, \fBRemind\fR
|
||||||
|
attempts to determine if the terminal background is dark or light by
|
||||||
|
sending a special escape sequence to determine the background color.
|
||||||
|
The \fIm\fR parameter can override this check (or force it if
|
||||||
|
\fIm\fR is given as \fBt\fR.)
|
||||||
.PP
|
.PP
|
||||||
If the optional \fIb\fR parameter is supplied following a comma, then
|
If the optional \fIb\fR parameter is supplied following a comma, then
|
||||||
\fIb=0\fR tells \fBRemind\fR to ignore SPECIAL SHADE reminders (the
|
\fIb=0\fR tells \fBRemind\fR to ignore SPECIAL SHADE reminders (the
|
||||||
@@ -225,7 +236,7 @@ regardless of the \fIdelta\fR supplied for each reminder.
|
|||||||
.B \-t\fR\fIn\fR
|
.B \-t\fR\fIn\fR
|
||||||
If you supply a number \fIn\fR after the \fB\-t\fR option, then
|
If you supply a number \fIn\fR after the \fB\-t\fR option, then
|
||||||
\fBRemind\fR pretends that echo \fBREM\fR command has a delta
|
\fBRemind\fR pretends that echo \fBREM\fR command has a delta
|
||||||
of \+\+\fIn\fR, regardles of any existing delta.
|
of \+\+\fIn\fR, regardless of any existing delta.
|
||||||
.TP
|
.TP
|
||||||
.B \-tz\fR
|
.B \-tz\fR
|
||||||
If you supply the letter \fBz\fR after the \fB\-t\fR option, then
|
If you supply the letter \fBz\fR after the \fB\-t\fR option, then
|
||||||
@@ -289,6 +300,11 @@ Echo lines when displaying error messages
|
|||||||
.TP
|
.TP
|
||||||
.B f
|
.B f
|
||||||
Trace the reading of reminder files
|
Trace the reading of reminder files
|
||||||
|
.TP
|
||||||
|
.B s
|
||||||
|
Upon exit, print the high-water mark of the operator and value stacks
|
||||||
|
used for expression-parsing. This is unlikely to be useful unless
|
||||||
|
you're intimately familiar with Remind's source code.
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
\fB\-g\fR[\fBa|d\fR[\fBa|d\fR[\fBa|d\fR[\fBa|d\fR]]]]
|
\fB\-g\fR[\fBa|d\fR[\fBa|d\fR[\fBa|d\fR[\fBa|d\fR]]]]
|
||||||
@@ -357,9 +373,12 @@ defaults to 1, and can range from 1 to 60. Note that the use of the
|
|||||||
\fB\-z\fR option also enables the \fB\-f\fR option.
|
\fB\-z\fR option also enables the \fB\-f\fR option.
|
||||||
.PP
|
.PP
|
||||||
.RS
|
.RS
|
||||||
If you supply the option \fB\-z0\fR, \fBRemind\fR runs in a
|
If you supply the option \fB\-zj\fR, \fBRemind\fR runs in a
|
||||||
special mode called \fBserver mode\fR. This is documented
|
special mode called \fBserver mode\fR. This is documented
|
||||||
in the tkremind man page; see tkremind(1).
|
in the tkremind man page; see tkremind(1). The older server mode
|
||||||
|
option \fB\-z0\fR still works, but is deprecated; it uses an ad-hoc
|
||||||
|
method to communicate with the client rather than using JSON to communicate
|
||||||
|
with the client.
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
\fB\-u\fR\fIname\fR
|
\fB\-u\fR\fIname\fR
|
||||||
@@ -610,6 +629,11 @@ The following examples show how date specifications are interpreted.
|
|||||||
.PP
|
.PP
|
||||||
1. Null date specification - the reminder is triggered every day.
|
1. Null date specification - the reminder is triggered every day.
|
||||||
The trigger date for a specific run is simply the current system date.
|
The trigger date for a specific run is simply the current system date.
|
||||||
|
For example:
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
REM MSG This is triggered every time Remind runs
|
||||||
|
.fi
|
||||||
.PP
|
.PP
|
||||||
2. Only
|
2. Only
|
||||||
.I day
|
.I day
|
||||||
@@ -1122,7 +1146,7 @@ reminder is queued for later activation. When \fBRemind\fR has
|
|||||||
finished processing the reminder file, it puts itself in the
|
finished processing the reminder file, it puts itself in the
|
||||||
background, and activates timed reminders when the system time reached
|
background, and activates timed reminders when the system time reached
|
||||||
the specified time. Note that if you use the \fBNOQUEUE\fR modifier
|
the specified time. Note that if you use the \fBNOQUEUE\fR modifier
|
||||||
in the \fBREM\fR command, then this queueing and background activation
|
in the \fBREM\fR command, then this queuing and background activation
|
||||||
is \fInot\fR performed. \fBNOQUEUE\fR is useful if you want a time
|
is \fInot\fR performed. \fBNOQUEUE\fR is useful if you want a time
|
||||||
to be associated with a reminder (eg, in the calendar) but are not
|
to be associated with a reminder (eg, in the calendar) but are not
|
||||||
interested in a popup reminder happening at the specified time.
|
interested in a popup reminder happening at the specified time.
|
||||||
@@ -1194,7 +1218,9 @@ in the bodies of timed reminders, then when the timed reminders are
|
|||||||
activated, the variables and functions have the definitions that were
|
activated, the variables and functions have the definitions that were
|
||||||
in effect at the end of the reminder script. These definitions may
|
in effect at the end of the reminder script. These definitions may
|
||||||
\fInot\fR necessarily be those that were in effect at the time the reminder
|
\fInot\fR necessarily be those that were in effect at the time the reminder
|
||||||
was queued.
|
was queued. In addition, the OMIT context is whatever was in effect at
|
||||||
|
the end of the reminder script, which may not necessarily be the same
|
||||||
|
as when the \fBREM\fR command was first processed.
|
||||||
.PP
|
.PP
|
||||||
.B THE SCHED AND WARN KEYWORDS
|
.B THE SCHED AND WARN KEYWORDS
|
||||||
.PP
|
.PP
|
||||||
@@ -1688,6 +1714,11 @@ For example, the following sequences are equivalent:
|
|||||||
OMIT 3 Jan 2011 THROUGH 5 Jan 2011
|
OMIT 3 Jan 2011 THROUGH 5 Jan 2011
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
|
Note that \fBRemind\fR has a compiled-in limit to the number of full
|
||||||
|
OMITs. If you omit a range of \fIN\fR fully-specified (ie, year
|
||||||
|
included) days, then \fIN\fR full OMITs are used up. Trying to omit a
|
||||||
|
very large range may result in the error "Too many full OMITs"
|
||||||
|
.PP
|
||||||
You can make a THROUGH \fBOMIT\fR do double-duty as a \fBREM\fR command as
|
You can make a THROUGH \fBOMIT\fR do double-duty as a \fBREM\fR command as
|
||||||
long as both dates are fully specified
|
long as both dates are fully specified
|
||||||
.PP
|
.PP
|
||||||
@@ -1790,7 +1821,7 @@ will begin reading from standard input.
|
|||||||
.PP
|
.PP
|
||||||
If you specify a \fIdirectory\fR as the argument to \fBINCLUDE\fR, then
|
If you specify a \fIdirectory\fR as the argument to \fBINCLUDE\fR, then
|
||||||
\fBRemind\fR will process all files in that directory that match the shell
|
\fBRemind\fR will process all files in that directory that match the shell
|
||||||
patterm "*.rem". The files are processed in sorted order; the sort order
|
pattern "*.rem". The files are processed in sorted order; the sort order
|
||||||
matches that used by the shell when it expands "*.rem".
|
matches that used by the shell when it expands "*.rem".
|
||||||
.PP
|
.PP
|
||||||
Note that the file specified by an \fBINCLUDE\fR command is interpreted
|
Note that the file specified by an \fBINCLUDE\fR command is interpreted
|
||||||
@@ -2146,7 +2177,10 @@ Unary minus. Can be applied to an \fBINT\fR. Returns the negative
|
|||||||
of the operand.
|
of the operand.
|
||||||
.TP
|
.TP
|
||||||
.B *
|
.B *
|
||||||
Multiplication. Returns the product of two \fBINT\fRs.
|
Multiplication. Returns the product of two \fBINT\fRs. Alternatively, if
|
||||||
|
one argument is a \fBSTRING\fR and the other an \fBINT\fR, returns a
|
||||||
|
\fBSTRING\fR consisting of the INT number of repeats of the original STRING.
|
||||||
|
In this case, the INT argument cannot be negative.
|
||||||
.TP
|
.TP
|
||||||
.B /
|
.B /
|
||||||
Integer division. Returns the quotient of two \fBINT\fRs, discarding the
|
Integer division. Returns the quotient of two \fBINT\fRs, discarding the
|
||||||
@@ -2398,6 +2432,10 @@ is normally 0, but can be set with the \fB\-tt\fR option or explicitly
|
|||||||
set in your script. If \fB$DefaultDelta\fR is non-zero, you can use an
|
set in your script. If \fB$DefaultDelta\fR is non-zero, you can use an
|
||||||
explicit delta of +0 in an AT clause to countermand the default delta.
|
explicit delta of +0 in an AT clause to countermand the default delta.
|
||||||
.TP
|
.TP
|
||||||
|
.B $DeltaOverride (read-only)
|
||||||
|
If non-zero, corresponds to the \fIn\fR argument given to a
|
||||||
|
\fB\-t\fR\fIn\fR command-line option.
|
||||||
|
.TP
|
||||||
.B $DontFork (read-only)
|
.B $DontFork (read-only)
|
||||||
If non-zero, then the \fB\-c\fR option was supplied on the command line.
|
If non-zero, then the \fB\-c\fR option was supplied on the command line.
|
||||||
.TP
|
.TP
|
||||||
@@ -2464,7 +2502,8 @@ or a date different from today's true date was supplied. If non-zero,
|
|||||||
then \fBONCE\fR directives will be ignored.
|
then \fBONCE\fR directives will be ignored.
|
||||||
.TP
|
.TP
|
||||||
.B $InfDelta (read-only)
|
.B $InfDelta (read-only)
|
||||||
If non-zero, then the \fB\-t\fR option was supplied on the command line.
|
If non-zero, then the \fB\-t\fR option was supplied on the command line,
|
||||||
|
with no \fIn\fR argument.
|
||||||
.TP
|
.TP
|
||||||
.B $IntMax (read-only)
|
.B $IntMax (read-only)
|
||||||
The largest representable \fBINT\fR. On a machine with 32-bit signed integers
|
The largest representable \fBINT\fR. On a machine with 32-bit signed integers
|
||||||
@@ -2541,6 +2580,24 @@ updates \fB$LongDeg\fR, \fB$LongMin\fR and \fB$LongSec\fR. Similar
|
|||||||
rules apply to \fB$Latitude\fR, \fB$LatDeg\fR, \fB$LatMin\fR and \fB$LatSec\fR.
|
rules apply to \fB$Latitude\fR, \fB$LatDeg\fR, \fB$LatMin\fR and \fB$LatSec\fR.
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
|
.B $MaxLateMinutes
|
||||||
|
This variable controls how \fBRemind\fR reacts to a computer being suspended
|
||||||
|
and then woken. Normally, if a timed reminder is queued and then the
|
||||||
|
computer suspended, and then the computer is woken \fIafter\fR the
|
||||||
|
timed reminder's trigger time, \fBRemind\fR will triger the timer anyway,
|
||||||
|
despite the fact that the trigger time has already passed.
|
||||||
|
.RS
|
||||||
|
.PP
|
||||||
|
If you set \fB$MaxLateMinutes\fR to a non-zero integer between 1 and 1440,
|
||||||
|
then \fBRemind\fR will \fInot\fR trigger a timed reminder whose trigger
|
||||||
|
time is more than \fB$MaxLateMinutes\fR minutes in the past.
|
||||||
|
.PP
|
||||||
|
Note that \fBRemind\fR uses the value of \fB$MaxLateMinutes\fR that is in
|
||||||
|
effect when it has finished reading the reminder file and puts itself in
|
||||||
|
the background. Generally, you should set \fB$MaxLateMinutes\fR once
|
||||||
|
near the beginning of the file and not change it after that.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
.B $MaxSatIter
|
.B $MaxSatIter
|
||||||
The maximum number of iterations for the \fBSATISFY\fR clause
|
The maximum number of iterations for the \fBSATISFY\fR clause
|
||||||
(described later.) Must be at least 10.
|
(described later.) Must be at least 10.
|
||||||
@@ -2549,7 +2606,9 @@ The maximum number of iterations for the \fBSATISFY\fR clause
|
|||||||
A limit on the longest string that \fBRemind\fR will allow you
|
A limit on the longest string that \fBRemind\fR will allow you
|
||||||
to create. The default is 65535. If you set \fB$MaxStringLen\fR to 0
|
to create. The default is 65535. If you set \fB$MaxStringLen\fR to 0
|
||||||
or to -1, then \fBremind\fR will allow you to create arbitrarily-long
|
or to -1, then \fBremind\fR will allow you to create arbitrarily-long
|
||||||
strings, at least until it runs out of memory.
|
strings, at least until it runs out of memory. We do not recommend
|
||||||
|
setting \fB$MaxStringLen\fR to 0 or -1 because it is very easy to write
|
||||||
|
code that DOSes \fBRemind\fR in that case.
|
||||||
.TP
|
.TP
|
||||||
.B $MinsFromUTC
|
.B $MinsFromUTC
|
||||||
The number of minutes between Universal Time Coordinated and local time. If
|
The number of minutes between Universal Time Coordinated and local time. If
|
||||||
@@ -2564,6 +2623,18 @@ must also set \fB$CalcUTC\fR to 0 with the \fB\-i\fR option.
|
|||||||
.B $NextMode (read-only)
|
.B $NextMode (read-only)
|
||||||
If non-zero, then the \fB\-n\fR option was supplied on the command line.
|
If non-zero, then the \fB\-n\fR option was supplied on the command line.
|
||||||
.TP
|
.TP
|
||||||
|
.B $MaxFullOmits (read-only)
|
||||||
|
The maximum number of full OMITs allowed (a compiled-in constant.)
|
||||||
|
.TP
|
||||||
|
.B $MaxPartialOmits (read-only)
|
||||||
|
The maximum number of partial OMITs allowed (a compiled-in constant.)
|
||||||
|
.TP
|
||||||
|
.B $NumFullOmits (read-only)
|
||||||
|
The number of full OMITs in the current OMIT context.
|
||||||
|
.TP
|
||||||
|
.B $NumPartialOmits (read-only)
|
||||||
|
The number of partial OMITs in the current OMIT context.
|
||||||
|
.TP
|
||||||
.B $NumQueued (read-only)
|
.B $NumQueued (read-only)
|
||||||
Contains the number of reminders queued so far for background
|
Contains the number of reminders queued so far for background
|
||||||
timed triggering.
|
timed triggering.
|
||||||
@@ -2708,9 +2779,13 @@ Set to 1 if the \fB\-@1\fR option was used; 0 otherwise.
|
|||||||
Set to 1 if the \fB\-@2\fR option was used; 0 otherwise.
|
Set to 1 if the \fB\-@2\fR option was used; 0 otherwise.
|
||||||
.TP
|
.TP
|
||||||
.B $TerminalBackground (read-only)
|
.B $TerminalBackground (read-only)
|
||||||
Returns -1 if the terminal background color was not specified,
|
Returns -1 if the terminal background color could not be determined, 0
|
||||||
0 if it was specified as dark with the \fB\-@,0\fR option or
|
if it was found to be dark (or was specified as dark with the
|
||||||
1 if it was specified as light with the \fB\-@,1\fR option.
|
\fB\-@,0\fR option) or 1 if it was found to be light (or specified as
|
||||||
|
light with the \fB\-@,1\fR option.) The terminal background is considered
|
||||||
|
to be "dark" if the average of the red, green and blue components is
|
||||||
|
at most 85 out of 255, and if the maximum of any component is at most
|
||||||
|
128 out of 255.
|
||||||
.PP
|
.PP
|
||||||
Note: If any of the calendar modes are in effect, then the
|
Note: If any of the calendar modes are in effect, then the
|
||||||
values of $Daemon, $DontFork, $DontTrigAts, $DontQueue, $HushMode,
|
values of $Daemon, $DontFork, $DontTrigAts, $DontQueue, $HushMode,
|
||||||
@@ -3013,11 +3088,12 @@ will produce undefined results.
|
|||||||
Returns the time of "civil twilight" on the specified \fIdate\fR. If
|
Returns the time of "civil twilight" on the specified \fIdate\fR. If
|
||||||
\fIdate\fR is omitted, defaults to \fBtoday()\fR.
|
\fIdate\fR is omitted, defaults to \fBtoday()\fR.
|
||||||
.TP
|
.TP
|
||||||
.B easterdate(dqi_arg)
|
.B easterdate([dqi_arg])
|
||||||
If \fIarg\fR is an \fBINT\fR, then returns the date of Easter Sunday
|
If \fIarg\fR is an \fBINT\fR, then returns the date of Easter Sunday
|
||||||
for the specified year. If \fIarg\fR is a \fBDATE\fR or
|
for the specified year. If \fIarg\fR is a \fBDATE\fR or
|
||||||
\fBDATETIME\fR, then returns the date of the next Easter Sunday on or
|
\fBDATETIME\fR, then returns the date of the next Easter Sunday on or
|
||||||
after \fIarg\fR. (The time component of a datetime is ignored.)
|
after \fIarg\fR. (The time component of a datetime is ignored.) If \fIarg\fR
|
||||||
|
is omitted, then it defaults to \fBtoday()\fR.
|
||||||
.RS
|
.RS
|
||||||
.P
|
.P
|
||||||
Note that \fBeasterdate\fR computes the Western Easter. For the Orthodox
|
Note that \fBeasterdate\fR computes the Western Easter. For the Orthodox
|
||||||
@@ -3279,6 +3355,62 @@ which default to \fBtoday()\fR and midnight, respectively. The returned
|
|||||||
value is an integer from 0 to 359, representing the phase of the moon
|
value is an integer from 0 to 359, representing the phase of the moon
|
||||||
in degrees. 0 is a new moon, 180 is a full moon, 90 is first-quarter, etc.
|
in degrees. 0 is a new moon, 180 is a full moon, 90 is first-quarter, etc.
|
||||||
.TP
|
.TP
|
||||||
|
.B multitrig(s_trig1 [,s_trig2, [... s_trigN]])
|
||||||
|
\fBmultitrig\fR evaluates each string as a trigger, similar to \fBevaltrig\fR,
|
||||||
|
and returns the \fIearliest\fR trigger date that is on or after \fBtoday()\fR.
|
||||||
|
\fBmultitrig\fR is similar to \fBtrig\fR but has the following difference:
|
||||||
|
.RS
|
||||||
|
.PP
|
||||||
|
\fBtrig\fR returns the \fIfirst\fR trigger date that would have triggered today,
|
||||||
|
whereas \fBmultitrig\fR returns the \fIearliest\fR trigger date later than
|
||||||
|
today, regardless of whether it would have triggered today.
|
||||||
|
.PP
|
||||||
|
If no trigger can be computed that is later than \fBtoday()\fR, then
|
||||||
|
\fBmultitrig\fR returns 1990-01-01.
|
||||||
|
.PP
|
||||||
|
Consider the following examples, assuming that today is Sunday, 24 March 2024:
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
# Returns 1990-01-01 because neither would trigger today
|
||||||
|
SET a trig("Mon", "Wed")
|
||||||
|
|
||||||
|
# Returns 2024-03-25 because it's the earlier trigger date
|
||||||
|
SET a multitrig("Mon", "Wed")
|
||||||
|
|
||||||
|
# Returns 2024-03-27 because it's the first that would trigger today
|
||||||
|
SET a trig("Wed +3", "Mon +3")
|
||||||
|
|
||||||
|
# Returns 2024-03-25 because it's the earlier trigger date
|
||||||
|
SET a multitrig("Wed +3", "Mon +3")
|
||||||
|
|
||||||
|
# Returns 1990-01-01 because all triggers have expired
|
||||||
|
SET a multitrig("2000", "2022", "1998", "2023")
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
In general, \fBmultitrig\fR works better with the Remind algorithm than
|
||||||
|
\fBtrig\fR and should be used most of the time. As an example, this
|
||||||
|
reminder is issued at the end of each quarter:
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
REM [multitrig("Mar 31", "Jun 30", "Sep 30", "Dec 31")] +7 MSG \\
|
||||||
|
%"End of [ord($Tm/3)] quarter%" is %b.
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
If you want the last working day of each quarter, you could use:
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
PUSH-OMIT-CONTEXT
|
||||||
|
OMIT Sat Sun
|
||||||
|
REM [multitrig("Mar ~1", "Jun ~1", "Sep ~1", "Dec ~1")] +7 MSG \\
|
||||||
|
%"Last working day of [ord($Tm/3)] quarter%" is %b.
|
||||||
|
POP-OMIT-CONTEXT
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Note that unlike \fBevaltrig\fR, \fBmultitrig\fR always returns a \fBDATE\fR
|
||||||
|
and never a \fBDATETIME\fR. Including an \fBAT\fR clause in a trigger
|
||||||
|
supplied to \fBmultitrig\fR will result in an error.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
.B ndawn([dq_date])
|
.B ndawn([dq_date])
|
||||||
Returns the time of "nautical dawn" on the specified \fIdate\fR. If
|
Returns the time of "nautical dawn" on the specified \fIdate\fR. If
|
||||||
\fIdate\fR is omitted, defaults to \fBtoday()\fR. If a \fIdatetime\fR object
|
\fIdate\fR is omitted, defaults to \fBtoday()\fR. If a \fIdatetime\fR object
|
||||||
@@ -3294,7 +3426,7 @@ This function returns the number of \fInon-\fRomitted days between
|
|||||||
counted. \fIend\fR is never counted.
|
counted. \fIend\fR is never counted.
|
||||||
.RS
|
.RS
|
||||||
.PP
|
.PP
|
||||||
Note that if \fIend\fR is less than \ffIstart\fR, the arguments
|
Note that if \fIend\fR is less than \fIstart\fR, the arguments
|
||||||
are effectively swapped, so counting always begins from the older
|
are effectively swapped, so counting always begins from the older
|
||||||
date.
|
date.
|
||||||
.PP
|
.PP
|
||||||
@@ -3339,7 +3471,7 @@ reminder will label day numbers in a calendar:
|
|||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
Obviously, the answer you get from \fBnonomitted\fR depends on the global
|
Obviously, the answer you get from \fBnonomitted\fR depends on the global
|
||||||
OMIT context. If you use moveable OMITs, you may get inconsistent results.
|
OMIT context. If you use movable OMITs, you may get inconsistent results.
|
||||||
.PP
|
.PP
|
||||||
Here is a more complex use for \fBnonomitted\fR. My garbage collection
|
Here is a more complex use for \fBnonomitted\fR. My garbage collection
|
||||||
follows two interleaved 14-day cycles: One Friday, garbage and paper
|
follows two interleaved 14-day cycles: One Friday, garbage and paper
|
||||||
@@ -3372,11 +3504,12 @@ the actual time, or a time supplied on the command line.
|
|||||||
Returns a string that is the ordinal number \fInum\fR. For example,
|
Returns a string that is the ordinal number \fInum\fR. For example,
|
||||||
\fBord(2)\fR returns "2nd", and \fBord(213)\fR returns "213th".
|
\fBord(2)\fR returns "2nd", and \fBord(213)\fR returns "213th".
|
||||||
.TP
|
.TP
|
||||||
.B orthodoxeaster(dqi_arg)
|
.B orthodoxeaster([dqi_arg])
|
||||||
If \fIarg\fR is an \fBINT\fR, then returns the date of Orthodox Easter Sunday
|
If \fIarg\fR is an \fBINT\fR, then returns the date of Orthodox Easter Sunday
|
||||||
for the specified year. If \fIarg\fR is a \fBDATE\fR or
|
for the specified year. If \fIarg\fR is a \fBDATE\fR or
|
||||||
\fBDATETIME\fR, then returns the date of the next Orthodox Easter Sunday on or
|
\fBDATETIME\fR, then returns the date of the next Orthodox Easter Sunday on or
|
||||||
after \fIarg\fR. (The time component of a datetime is ignored.)
|
after \fIarg\fR. (The time component of a datetime is ignored.) If \fIarg\fR
|
||||||
|
is omitted, then it defaults to \fBtoday()\fR.
|
||||||
.RS
|
.RS
|
||||||
.P
|
.P
|
||||||
Note that \fBorthodoxeaster\fR computes the Orthodox Easter. For the Western
|
Note that \fBorthodoxeaster\fR computes the Orthodox Easter. For the Western
|
||||||
@@ -3597,7 +3730,7 @@ not supplied, then it defaults to \fBtoday()\fR.
|
|||||||
.PP
|
.PP
|
||||||
The return value of \fBsoleq()\fR is a \fBDATETIME\fR object specifying
|
The return value of \fBsoleq()\fR is a \fBDATETIME\fR object specifying
|
||||||
the date and time of the solstice or equinox in the local time zone. It
|
the date and time of the solstice or equinox in the local time zone. It
|
||||||
should be accurate to within 3 minues or so in the worst case.
|
should be accurate to within 3 minutes or so in the worst case.
|
||||||
.PP
|
.PP
|
||||||
See the included file \fB$SysInclude/seasons.rem\fR for examples of how
|
See the included file \fB$SysInclude/seasons.rem\fR for examples of how
|
||||||
to use \fBsoleq()\fR.
|
to use \fBsoleq()\fR.
|
||||||
@@ -4304,7 +4437,7 @@ Dean was born in 1984. The above example, on 1 November 1992, would print:
|
|||||||
Similarly, the function is useful in anniversary reminders. For example:
|
Similarly, the function is useful in anniversary reminders. For example:
|
||||||
.PP
|
.PP
|
||||||
.nf
|
.nf
|
||||||
REM 4 June MSG [since(1989)] anniversary of the Tiananmen Square massacre
|
REM 4 June MSG [since(1989)] anniversary of the Tienanmen Square massacre
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
Notes:
|
Notes:
|
||||||
@@ -5188,7 +5321,7 @@ A number of system variables let you translate various phrases
|
|||||||
to other languages. These system variables are:
|
to other languages. These system variables are:
|
||||||
.PP
|
.PP
|
||||||
.TP
|
.TP
|
||||||
.B $Monday, $Tuesday, $Wednesday, $Thursday, $Friday, $Saturday
|
.B $Monday, $Tuesday, $Wednesday, $Thursday, $Friday, $Saturday, $Sunday
|
||||||
Set each of these system variables to a string representing the corresponding
|
Set each of these system variables to a string representing the corresponding
|
||||||
day's name in your language. Strings must be valid UTF-8 strings.
|
day's name in your language. Strings must be valid UTF-8 strings.
|
||||||
.TP
|
.TP
|
||||||
@@ -5291,7 +5424,7 @@ as:
|
|||||||
.PP
|
.PP
|
||||||
You can define your own substitution sequences in addition to the built-in
|
You can define your own substitution sequences in addition to the built-in
|
||||||
ones as follows: If you define a function named \fBsubst_\fIname\fB(alt, date, time)\fR, then the sequence \fB%{name}\fR calls the function with \fBalt\fR
|
ones as follows: If you define a function named \fBsubst_\fIname\fB(alt, date, time)\fR, then the sequence \fB%{name}\fR calls the function with \fBalt\fR
|
||||||
set to 0 and \fBdate\fR and \fRtime\fR to the trigger date and time,
|
set to 0 and \fBdate\fR and \fBtime\fR to the trigger date and time,
|
||||||
respectively. The \fB%{name}\fR sequence is replaced with whatever the
|
respectively. The \fB%{name}\fR sequence is replaced with whatever the
|
||||||
function returns. The sequence \fB%*{name}\fR is similar, but calls
|
function returns. The sequence \fB%*{name}\fR is similar, but calls
|
||||||
the function with \fBalt\fR set to 1.
|
the function with \fBalt\fR set to 1.
|
||||||
@@ -5494,13 +5627,13 @@ the anniversary of a death is. The following rules are used:
|
|||||||
o
|
o
|
||||||
If the death occurred on 30 Heshvan, and Heshvan in the year after the
|
If the death occurred on 30 Heshvan, and Heshvan in the year after the
|
||||||
death is \fIchaser\fR, then the jahrzeit is observed on 29 Heshvan in years
|
death is \fIchaser\fR, then the jahrzeit is observed on 29 Heshvan in years
|
||||||
when Heshvan is \fIchaser\fR. Otherwise, the yahrzeit is observed on 1
|
when Heshvan is \fIchaser\fR. Otherwise, the jahrzeit is observed on 1
|
||||||
Kislev when Heshvan is \fIchaser\fR.
|
Kislev when Heshvan is \fIchaser\fR.
|
||||||
.TP
|
.TP
|
||||||
o
|
o
|
||||||
If the death occurred on 30 Kislev, and Kislev in the year after the
|
If the death occurred on 30 Kislev, and Kislev in the year after the
|
||||||
death is \fIchaser\fR, then the jahrzeit is observed on 29 Kislev in years
|
death is \fIchaser\fR, then the jahrzeit is observed on 29 Kislev in years
|
||||||
when Kislev is \fIchaser\fR. Otherwise, the yahrzeit is observed on 1
|
when Kislev is \fIchaser\fR. Otherwise, the jahrzeit is observed on 1
|
||||||
Tevet when Kislev is \fIchaser\fR.
|
Tevet when Kislev is \fIchaser\fR.
|
||||||
.TP
|
.TP
|
||||||
o
|
o
|
||||||
@@ -5525,7 +5658,7 @@ The \fBSPECIAL\fR keyword is used to transmit "out-of-band" information
|
|||||||
to \fBRemind\fR backends, such as \fBtkremind\fR or \fBRem2PS\fR.
|
to \fBRemind\fR backends, such as \fBtkremind\fR or \fBRem2PS\fR.
|
||||||
They are used only when piping data from a \fBremind \-p\fR line.
|
They are used only when piping data from a \fBremind \-p\fR line.
|
||||||
(Note that the COLOR special is an exception; it downgrades to the
|
(Note that the COLOR special is an exception; it downgrades to the
|
||||||
equivalent of MSG in \fBremind's\fR normal mode of operation.)
|
equivalent of MSG in \fBRemind's\fR normal mode of operation.)
|
||||||
.PP
|
.PP
|
||||||
The various \fBSPECIAL\fRs recognized are particular for each
|
The various \fBSPECIAL\fRs recognized are particular for each
|
||||||
backend; however, there are four \fBSPECIAL\fRs that all backends
|
backend; however, there are four \fBSPECIAL\fRs that all backends
|
||||||
@@ -5816,6 +5949,25 @@ components, then \fBRemind\fR will correctly compute a trigger date, even
|
|||||||
if it happens to be before the start of scanning.
|
if it happens to be before the start of scanning.
|
||||||
Note that this behaviour is not true for
|
Note that this behaviour is not true for
|
||||||
versions of \fBRemind\fR prior to 03.00.01.
|
versions of \fBRemind\fR prior to 03.00.01.
|
||||||
|
.SH FILES
|
||||||
|
.PP
|
||||||
|
The traditional location of your reminders file or directory is:
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
$HOME/.reminders
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
where \fB$HOME\fR is your home directory.
|
||||||
|
.PP
|
||||||
|
Remind ships with some preinstalled files for holidays and language
|
||||||
|
packs. These are located in the following directory:
|
||||||
|
.PP
|
||||||
|
.nf
|
||||||
|
@prefix@/share/remind/
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Do not hard-code the above directory in your reminder files. Instead,
|
||||||
|
use the value of the $SysInclude system variable.
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
.PP
|
.PP
|
||||||
Dianne Skoll <dianne@skoll.ca> wrote \fBRemind\fR. The moon code
|
Dianne Skoll <dianne@skoll.ca> wrote \fBRemind\fR. The moon code
|
||||||
@@ -5863,9 +6015,11 @@ Liviu Daia
|
|||||||
Rafa Couto
|
Rafa Couto
|
||||||
.PP
|
.PP
|
||||||
\fBIcelandic\fR --
|
\fBIcelandic\fR --
|
||||||
Bj\(:orn Dav\('i\[Sd]sson
|
Bj\[:o]rn Daví\[Sd]sson
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
.PP
|
.PP
|
||||||
|
If you find a bug in Remind, please report it to: dianne@skoll.ca
|
||||||
|
.PP
|
||||||
There's no good reason why read-only system variables are not
|
There's no good reason why read-only system variables are not
|
||||||
implemented as functions, or why functions like \fBversion()\fR, etc.
|
implemented as functions, or why functions like \fBversion()\fR, etc.
|
||||||
are not implemented as read-only system variables.
|
are not implemented as read-only system variables.
|
||||||
@@ -5886,8 +6040,13 @@ Almanac Office, USNO.
|
|||||||
.PP
|
.PP
|
||||||
Richard Siegel and Michael and Sharon Strassfeld, \fIThe First Jewish
|
Richard Siegel and Michael and Sharon Strassfeld, \fIThe First Jewish
|
||||||
Catalog\fR, Jewish Publication Society of America.
|
Catalog\fR, Jewish Publication Society of America.
|
||||||
|
.PP
|
||||||
|
Jean Meeus, \fIAstronomical Algorithms, Second Edition\fR, Willmann-Bell, Inc.
|
||||||
|
|
||||||
.SH HOME PAGE
|
.SH HOME PAGE
|
||||||
https://dianne.skoll.ca/projects/remind/
|
https://dianne.skoll.ca/projects/remind/
|
||||||
|
.SH MAILING LIST
|
||||||
|
https://dianne.skoll.ca/mailman/listinfo/remind-fans
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.PP
|
.PP
|
||||||
\fBrem\fR(1), \fBrem2ps\fR(1), \fBrem2pdf\fR(1), \fBtkremind\fR(1), \fBrem2html\fR(1)
|
\fBrem\fR(1), \fBrem2ps\fR(1), \fBrem2pdf\fR(1), \fBtkremind\fR(1), \fBrem2html\fR(1)
|
||||||
|
|||||||
@@ -184,7 +184,9 @@ on the reminder.
|
|||||||
If there are any errors in your reminder file, the "Queue..." button
|
If there are any errors in your reminder file, the "Queue..." button
|
||||||
changes to "Errors...". Click on "Errors..." to see the Remind error
|
changes to "Errors...". Click on "Errors..." to see the Remind error
|
||||||
output. Click "OK" to close the error window; this makes the button
|
output. Click "OK" to close the error window; this makes the button
|
||||||
in the main TkRemind window to revert to "Queue..."
|
in the main TkRemind window to revert to "Queue..." You can click on
|
||||||
|
any error message to open an editor on the file and line number that
|
||||||
|
caused the error.
|
||||||
|
|
||||||
.SH BACKGROUND REMINDERS
|
.SH BACKGROUND REMINDERS
|
||||||
|
|
||||||
@@ -192,7 +194,7 @@ If you create "timed" reminders, \fBTkRemind\fR will queue them in
|
|||||||
the background and pop up boxes as they are triggered. Additionally,
|
the background and pop up boxes as they are triggered. Additionally,
|
||||||
if you created the reminder using \fBTkRemind\fR, you will be given the
|
if you created the reminder using \fBTkRemind\fR, you will be given the
|
||||||
option of "turning off" the reminder for the rest of the day.
|
option of "turning off" the reminder for the rest of the day.
|
||||||
\fBTkRemind\fR achieves queueing of background reminders by running
|
\fBTkRemind\fR achieves queuing of background reminders by running
|
||||||
\fBRemind\fR in \fIserver mode\fR, described later.
|
\fBRemind\fR in \fIserver mode\fR, described later.
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
@@ -301,11 +303,11 @@ Today
|
|||||||
|
|
||||||
.SH IMMEDIATE UPDATES
|
.SH IMMEDIATE UPDATES
|
||||||
|
|
||||||
If you are running \fBTkRemind\fR on Linux and have the
|
If you are running \fBTkRemind\fR on Linux and \fBRemind\fR has been
|
||||||
\fBinotifywait\fR program installed (part of the \fBinotify-tools\fR
|
compiled with \fBinotify\fR(7) support, then \fBTkRemind\fR redraws
|
||||||
or similar package), then \fBTkRemind\fR redraws the calendar window
|
the calendar window \fIimmediately\fR if \fB$HOME/.reminders\fR
|
||||||
\fIimmediately\fR if \fB$HOME/.reminders\fR changes (or, if it is a
|
changes (or, if it is a directory, any files in that directory
|
||||||
directory, any files in that directory change.)
|
change.)
|
||||||
.PP
|
.PP
|
||||||
This lets \fBTkRemind\fR react immediately to hand-edited reminders or
|
This lets \fBTkRemind\fR react immediately to hand-edited reminders or
|
||||||
to reminder files that are imported from another calendar system (for example,
|
to reminder files that are imported from another calendar system (for example,
|
||||||
@@ -366,60 +368,110 @@ your hand-edited files in a separate \fB*.rem\fR file than \fBTkRemind\fR's
|
|||||||
|
|
||||||
\fBRemind\fR has a special mode for interacting with programs like
|
\fBRemind\fR has a special mode for interacting with programs like
|
||||||
\fBTkRemind\fR. This mode is called \fIserver mode\fR and is
|
\fBTkRemind\fR. This mode is called \fIserver mode\fR and is
|
||||||
selected by supplying the \fB\-z0\fR option to \fBRemind\fR.
|
selected by supplying the \fB\-zj\fR option to \fBRemind\fR.
|
||||||
|
|
||||||
In server mode, \fBRemind\fR operates similar to daemon mode, except
|
In server mode, \fBRemind\fR operates similar to daemon mode, except
|
||||||
it reads commands (one per line)
|
it reads commands (one per line) from standard input and writes status
|
||||||
from standard input and writes status lines to standard output.
|
lines to standard output. Each status line is a JSON object.
|
||||||
|
|
||||||
The commands accepted in server mode are:
|
The commands accepted in server mode are:
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
EXIT
|
EXIT
|
||||||
Terminate the \fBRemind\fR process. EOF on standard input does the
|
Terminate the \fBRemind\fR process. EOF on standard input does the
|
||||||
same thing.
|
same thing. \fBRemind\fR exits immediately without printing
|
||||||
|
a JSON status line.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
STATUS
|
STATUS
|
||||||
Return the number of queued reminders.
|
Return the number of queued reminders. The JSON object looks
|
||||||
|
something like this:
|
||||||
|
.nf
|
||||||
|
|
||||||
|
{"response":"queued","nqueued":n,"command":"STATUS"}
|
||||||
|
|
||||||
|
.fi
|
||||||
|
where \fIn\fR is the number of reminders queued.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
QUEUE or JSONQUEUE
|
||||||
|
Returns the contents of the queue. The JSON object looks something
|
||||||
|
like this:
|
||||||
|
.nf
|
||||||
|
|
||||||
|
{"response":"queue","queue":[ ... ],"command":"QUEUE"}
|
||||||
|
|
||||||
|
.fi
|
||||||
|
The value of the \fBqueue\fR key is an array of JSON objects, each
|
||||||
|
representing a queued reminder.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
DEL \fIqid\fR
|
||||||
|
Delete the reminder with queue-id \fIqid\fR from the queue.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
REREAD
|
REREAD
|
||||||
Re-read the reminder file
|
Re-read the reminder file. Returns the following status line:
|
||||||
|
|
||||||
|
.nf
|
||||||
|
|
||||||
|
{"response":"reread","command":"REREAD"}
|
||||||
|
|
||||||
|
.fi
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
The status lines written are as follows:
|
Additional status lines written are as follows:
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
NOTE reminder \fItime\fR \fItag\fR
|
.nf
|
||||||
Signifies the beginning of a timed reminder whose trigger time is
|
|
||||||
\fItime\fR with tag \fItag\fR. If the reminder has no tag, an
|
|
||||||
asterisk is supplied for \fItag\fR. All lines following this line
|
|
||||||
are the body of the reminder, until the line \fBNOTE endreminder\fR
|
|
||||||
is transmitted.
|
|
||||||
|
|
||||||
|
{"response":"reminder","ttime":tt,"now":now,"tags":tags,"qid":qid,"body":body}
|
||||||
|
|
||||||
|
.fi
|
||||||
|
In this line, \fItt\fR is the trigger time of the reminder (expressed
|
||||||
|
as a string), \fInow\fR is the current time, \fItags\fR (if present)
|
||||||
|
is the tag or tags associated with the reminder, and \fIbody\fR is the
|
||||||
|
body of the reminder. This response causes \fBTkRemind\fR to pop up a
|
||||||
|
reminder notification. \fIqid\fR is a unique identifier for this
|
||||||
|
reminder. You may delete it from the queue by sending a \fBDEL\fR
|
||||||
|
\fIqid\fR command to the server. Note that \fIqid\fRs are not stable
|
||||||
|
across re-reads; if \fBRemind\fR restarts itself to re-read the reminder
|
||||||
|
file, then the \fIqid\fR values are likely to change, and any reminder
|
||||||
|
deleted with a \fBDEL\fR \fIqid\fR command is likely to be re-queued.
|
||||||
.TP
|
.TP
|
||||||
NOTE newdate
|
.nf
|
||||||
|
|
||||||
|
{"response":"newdate"}
|
||||||
|
|
||||||
|
.fi
|
||||||
|
|
||||||
This line is emitted whenever \fBRemind\fR has detected a rollover of
|
This line is emitted whenever \fBRemind\fR has detected a rollover of
|
||||||
the system date. The front-end program should redraw its calendar
|
the system date. The front-end program should redraw its calendar
|
||||||
or take whatever other action is needed.
|
or take whatever other action is needed.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
NOTE reread
|
.nf
|
||||||
This line is emitted whenever the number of reminders in \fBRemind\fR's
|
|
||||||
queue changes because of a date rollover or a \fBREREAD\fR command.
|
|
||||||
The front-end should issue a \fBSTATUS\fR command in response to this
|
|
||||||
message.
|
|
||||||
|
|
||||||
.TP
|
{"response":"reread","command":"inotify"}
|
||||||
NOTE queued \fIn\fR
|
|
||||||
This line is emitted in response to a \fBSTATUS\fR command. The number
|
.fi
|
||||||
\fIn\fR is the number of reminders in the queue.
|
|
||||||
|
If \fBRemind\fR was compiled with support for \fBinotify\fR(7), then
|
||||||
|
if it detects a change to the top-level reminder file or directory,
|
||||||
|
it issues the above response. The front-end should redraw its
|
||||||
|
calendar since this response indicates that a change has been made
|
||||||
|
to the reminder file or directory.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
Please note that \fBRemind\fR can write a status message \fIat any time\fR
|
||||||
|
and not just in response to a command sent to its standard input. Therefore,
|
||||||
|
a program that runs \fBRemind\fR in server mode must be prepared to handle
|
||||||
|
asynchronous status messages.
|
||||||
|
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
TkRemind was written by Dianne Skoll <dianne@skoll.ca>
|
TkRemind was written by Dianne Skoll <dianne@skoll.ca>
|
||||||
|
|
||||||
\fBTkRemind\fR is Copyright 1996-2023 by Dianne Skoll.
|
\fBTkRemind\fR is Copyright 1996-2024 by Dianne Skoll.
|
||||||
|
|
||||||
.SH FILES
|
.SH FILES
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ use warnings;
|
|||||||
|
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
use JSON::MaybeXS;
|
use JSON::MaybeXS;
|
||||||
|
use Encode;
|
||||||
|
|
||||||
my %Options;
|
my %Options;
|
||||||
|
|
||||||
my $rem2html_version = '2.1';
|
my $rem2html_version = '@VERSION@';
|
||||||
|
|
||||||
my($days, $shades, $moons, $classes, $Month, $Year, $Numdays, $Firstwkday, $Mondayfirst, $weeks,
|
my($days, $shades, $moons, $classes, $Month, $Year, $Numdays, $Firstwkday, $Mondayfirst, $weeks,
|
||||||
@Daynames, $Nextmon, $Nextlen, $Prevmon, $Prevlen);
|
@Daynames, $Nextmon, $Nextlen, $Prevmon, $Prevlen);
|
||||||
@@ -44,6 +45,11 @@ Print usage information
|
|||||||
|
|
||||||
Print version
|
Print version
|
||||||
|
|
||||||
|
=item --utf8
|
||||||
|
|
||||||
|
Assume standard input is encoded in UTF-8; write UTF-8 data to standard
|
||||||
|
output.
|
||||||
|
|
||||||
=item --backurl I<url>
|
=item --backurl I<url>
|
||||||
|
|
||||||
When producing the small calendar for the previous month, make the
|
When producing the small calendar for the previous month, make the
|
||||||
@@ -154,6 +160,7 @@ Usage: remind -pp ... | rem2html [options]
|
|||||||
Options:
|
Options:
|
||||||
|
|
||||||
--help, -h Print usage information
|
--help, -h Print usage information
|
||||||
|
--utf8 Assume UTF-8 input and write UTF-8 output
|
||||||
--man Show man page (requires "perldoc")
|
--man Show man page (requires "perldoc")
|
||||||
--version Print version
|
--version Print version
|
||||||
--backurl url Make the title on the previous month's small calendar
|
--backurl url Make the title on the previous month's small calendar
|
||||||
@@ -197,6 +204,7 @@ sub parse_options
|
|||||||
local $SIG{__WARN__} = sub { print STDERR "$TIDY_PROGNAME: $_[0]\n"; };
|
local $SIG{__WARN__} = sub { print STDERR "$TIDY_PROGNAME: $_[0]\n"; };
|
||||||
if (!GetOptions(\%Options, "help|h",
|
if (!GetOptions(\%Options, "help|h",
|
||||||
"man",
|
"man",
|
||||||
|
"utf8",
|
||||||
"pngs",
|
"pngs",
|
||||||
"version",
|
"version",
|
||||||
"stylesheet=s",
|
"stylesheet=s",
|
||||||
@@ -216,13 +224,22 @@ sub parse_options
|
|||||||
if ($stylesheet) {
|
if ($stylesheet) {
|
||||||
$Options{stylesheet} = smoosh($Options{imgbase}, $stylesheet);
|
$Options{stylesheet} = smoosh($Options{imgbase}, $stylesheet);
|
||||||
}
|
}
|
||||||
|
if ($Options{utf8}) {
|
||||||
|
binmode(STDIN, ':encoding(UTF-8)');
|
||||||
|
binmode(STDOUT, ':encoding(UTF-8)');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub start_output
|
sub start_output
|
||||||
{
|
{
|
||||||
return if ($Options{tableonly});
|
return if ($Options{tableonly});
|
||||||
|
|
||||||
print("<html>\n<head>\n<title>" . $Options{title} . "</title>\n");
|
print("<html>\n<head>\n");
|
||||||
|
if ($Options{utf8}) {
|
||||||
|
print '<meta charset="UTF-8">' . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
print("<title>" . $Options{title} . "</title>\n");
|
||||||
if (!$Options{nostyle}) {
|
if (!$Options{nostyle}) {
|
||||||
if ($Options{stylesheet}) {
|
if ($Options{stylesheet}) {
|
||||||
print('<link rel="stylesheet" type="text/css" href="' .
|
print('<link rel="stylesheet" type="text/css" href="' .
|
||||||
@@ -310,7 +327,12 @@ sub parse_input
|
|||||||
($y, $m, $d, $special, $tag, $duration, $time, $body) =
|
($y, $m, $d, $special, $tag, $duration, $time, $body) =
|
||||||
($1, $2, $3, $4, $5, $6, $7, $8);
|
($1, $2, $3, $4, $5, $6, $7, $8);
|
||||||
} elsif (/\{/) {
|
} elsif (/\{/) {
|
||||||
my $obj = decode_json($_);
|
my $obj;
|
||||||
|
if ($Options{utf8}) {
|
||||||
|
$obj = decode_json(encode('UTF-8', $_, Encode::FB_DEFAULT));
|
||||||
|
} else {
|
||||||
|
$obj = decode_json($_);
|
||||||
|
}
|
||||||
next unless ($obj->{date} =~ /^(\d+)-(\d+)-(\d+)$/);
|
next unless ($obj->{date} =~ /^(\d+)-(\d+)-(\d+)$/);
|
||||||
$y = $1;
|
$y = $1;
|
||||||
$m = $2;
|
$m = $2;
|
||||||
15
resources/tkremind.desktop
Executable file
15
resources/tkremind.desktop
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Exec=tkremind
|
||||||
|
StartupNotify=true
|
||||||
|
Icon=tkremind
|
||||||
|
Terminal=false
|
||||||
|
Name=tkremind
|
||||||
|
Comment=TkRemind Calendar Program
|
||||||
|
Categories=Office;Calendar;
|
||||||
|
Keywords=Calendar;remind;
|
||||||
|
Keywords[ca]=Calendari;remind;
|
||||||
|
Keywords[de]=Kalender;remind;
|
||||||
|
Keywords[en_GB]=Calendar;remind;
|
||||||
|
Keywords[es]=Calendario;remind;
|
||||||
|
|
||||||
BIN
resources/tkremind.png
Normal file
BIN
resources/tkremind.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
633
scripts/tkremind
633
scripts/tkremind
File diff suppressed because it is too large
Load Diff
@@ -63,6 +63,15 @@ install: all
|
|||||||
done
|
done
|
||||||
-mkdir -p $(DESTDIR)$(datarootdir)/remind || true
|
-mkdir -p $(DESTDIR)$(datarootdir)/remind || true
|
||||||
cp -R ../include/* $(DESTDIR)$(datarootdir)/remind
|
cp -R ../include/* $(DESTDIR)$(datarootdir)/remind
|
||||||
|
-mkdir -p $(DESTDIR)$(prefix)/share/pixmaps
|
||||||
|
-mkdir -p $(DESTDIR)$(prefix)/share/applications
|
||||||
|
$(INSTALL_DATA) $(srcdir)/../resources/tkremind.png $(DESTDIR)$(prefix)/share/pixmaps
|
||||||
|
$(INSTALL_PROGRAM) $(srcdir)/../resources/tkremind.desktop $(DESTDIR)$(prefix)/share/applications
|
||||||
|
-if test "$(DESTDIR)" = ""; then \
|
||||||
|
update-desktop-database < /dev/null > /dev/null 2>&1 ; \
|
||||||
|
xdg-icon-resource install --novendor --size 64 $(DESTDIR)$(prefix)/share/pixmaps/tkremind.png < /dev/null > /dev/null 2>&1; \
|
||||||
|
xdg-desktop-menu install --novendor $(DESTDIR)$(prefix)/share/applications/tkremind.desktop < /dev/null > /dev/null 2>&1 ; \
|
||||||
|
fi
|
||||||
|
|
||||||
install-stripped: install
|
install-stripped: install
|
||||||
strip $(DESTDIR)$(bindir)/remind || true
|
strip $(DESTDIR)$(bindir)/remind || true
|
||||||
@@ -71,9 +80,6 @@ install-stripped: install
|
|||||||
clean:
|
clean:
|
||||||
rm -f *.o *~ core *.bak $(PROGS)
|
rm -f *.o *~ core *.bak $(PROGS)
|
||||||
|
|
||||||
cppcheck:
|
|
||||||
cppcheck --force --enable=all --suppress=variableScope --suppress=ConfigurationNotChecked *.c
|
|
||||||
|
|
||||||
clobber:
|
clobber:
|
||||||
rm -f *.o *~ remind rem2ps test.out core *.bak
|
rm -f *.o *~ remind rem2ps test.out core *.bak
|
||||||
|
|
||||||
@@ -83,6 +89,9 @@ depend:
|
|||||||
# The next targets are not very useful to you. I use them to build
|
# The next targets are not very useful to you. I use them to build
|
||||||
# distributions, etc.
|
# distributions, etc.
|
||||||
|
|
||||||
|
cppcheck:
|
||||||
|
cppcheck -j`nproc` --force --enable=all --suppress=ConfigurationNotChecked --suppress=unmatchedSuppression --suppress=variableScope --inline-suppr .
|
||||||
|
|
||||||
# Build a tar file based on all files checked into git.
|
# Build a tar file based on all files checked into git.
|
||||||
distro:
|
distro:
|
||||||
cd .. && git archive --worktree-attributes --format=tar --prefix=remind-$(VERSION)/ HEAD > src/remind-$(VERSION).tar
|
cd .. && git archive --worktree-attributes --format=tar --prefix=remind-$(VERSION)/ HEAD > src/remind-$(VERSION).tar
|
||||||
|
|||||||
225
src/calendar.c
225
src/calendar.c
@@ -5,7 +5,7 @@
|
|||||||
/* The code for generating a calendar. */
|
/* The code for generating a calendar. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -475,7 +475,7 @@ void PrintJSONKeyPairTime(char const *name, int t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef REM_USE_WCHAR
|
#ifdef REM_USE_WCHAR
|
||||||
void PutWideChar(wchar_t const wc)
|
void PutWideChar(wchar_t const wc, DynamicBuffer *output)
|
||||||
{
|
{
|
||||||
char buf[MB_CUR_MAX+1];
|
char buf[MB_CUR_MAX+1];
|
||||||
int len;
|
int len;
|
||||||
@@ -483,7 +483,11 @@ void PutWideChar(wchar_t const wc)
|
|||||||
len = wctomb(buf, wc);
|
len = wctomb(buf, wc);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
buf[len] = 0;
|
buf[len] = 0;
|
||||||
fputs(buf, stdout);
|
if (output) {
|
||||||
|
DBufPuts(output, buf);
|
||||||
|
} else {
|
||||||
|
fputs(buf, stdout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -556,11 +560,11 @@ static void goff(void)
|
|||||||
static void
|
static void
|
||||||
ClampColor(int *r, int *g, int *b)
|
ClampColor(int *r, int *g, int *b)
|
||||||
{
|
{
|
||||||
if (TerminalBackground == TERMINAL_BACKGROUND_UNKNOWN) {
|
if (GetTerminalBackground() == TERMINAL_BACKGROUND_UNKNOWN) {
|
||||||
/* No special clamping if terminal background is unknown */
|
/* No special clamping if terminal background is unknown */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (TerminalBackground == TERMINAL_BACKGROUND_DARK) {
|
if (GetTerminalBackground() == TERMINAL_BACKGROUND_DARK) {
|
||||||
if (*r <= 64 && *g <= 64 && *b <= 64) {
|
if (*r <= 64 && *g <= 64 && *b <= 64) {
|
||||||
int max = *r;
|
int max = *r;
|
||||||
double factor;
|
double factor;
|
||||||
@@ -579,7 +583,7 @@ ClampColor(int *r, int *g, int *b)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (TerminalBackground == TERMINAL_BACKGROUND_LIGHT) {
|
if (GetTerminalBackground() == TERMINAL_BACKGROUND_LIGHT) {
|
||||||
if (*r > 191 && *g > 191 && *b > 191) {
|
if (*r > 191 && *g > 191 && *b > 191) {
|
||||||
int min = *r;
|
int min = *r;
|
||||||
if (*g < min) min = *g;
|
if (*g < min) min = *g;
|
||||||
@@ -667,11 +671,11 @@ Colorize(int r, int g, int b, int bg, int clamp)
|
|||||||
if (b > 64) b = 1;
|
if (b > 64) b = 1;
|
||||||
else b = 0;
|
else b = 0;
|
||||||
|
|
||||||
if (clamp && TerminalBackground == TERMINAL_BACKGROUND_DARK && !bg) {
|
if (clamp && GetTerminalBackground() == TERMINAL_BACKGROUND_DARK && !bg) {
|
||||||
/* Convert black-on-black to grey */
|
/* Convert black-on-black to grey */
|
||||||
if (!r && !g && !b) return VT100Colors[1][0][0][0];
|
if (!r && !g && !b) return VT100Colors[1][0][0][0];
|
||||||
}
|
}
|
||||||
if (clamp && TerminalBackground == TERMINAL_BACKGROUND_LIGHT && !bg) {
|
if (clamp && GetTerminalBackground() == TERMINAL_BACKGROUND_LIGHT && !bg) {
|
||||||
/* Convert white-on-white to grey */
|
/* Convert white-on-white to grey */
|
||||||
if (r && g && b) return VT100Colors[1][0][0][0];
|
if (r && g && b) return VT100Colors[1][0][0][0];
|
||||||
}
|
}
|
||||||
@@ -1037,7 +1041,7 @@ static void DoCalendarOneMonth(void)
|
|||||||
printf("\"entries\":[\n");
|
printf("\"entries\":[\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (WriteCalendarRow()) continue;
|
while (WriteCalendarRow()) /* continue */;
|
||||||
|
|
||||||
if (PsCal == PSCAL_LEVEL1) {
|
if (PsCal == PSCAL_LEVEL1) {
|
||||||
printf("%s\n", PSEND);
|
printf("%s\n", PSEND);
|
||||||
@@ -1218,7 +1222,7 @@ static void PrintLeft(char const *s, int width, char pad)
|
|||||||
if (!buf) {
|
if (!buf) {
|
||||||
/* Uh-oh... cannot recover */
|
/* Uh-oh... cannot recover */
|
||||||
fprintf(stderr, "%s\n", ErrMsg[E_NO_MEM]);
|
fprintf(stderr, "%s\n", ErrMsg[E_NO_MEM]);
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void) mbstowcs(buf, s, len+1);
|
(void) mbstowcs(buf, s, len+1);
|
||||||
@@ -1227,7 +1231,7 @@ static void PrintLeft(char const *s, int width, char pad)
|
|||||||
ws = buf;
|
ws = buf;
|
||||||
for (i=0; i<width;) {
|
for (i=0; i<width;) {
|
||||||
if (*ws) {
|
if (*ws) {
|
||||||
PutWideChar(*ws++);
|
PutWideChar(*ws++, NULL);
|
||||||
i+= wcwidth(*ws);
|
i+= wcwidth(*ws);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -1235,7 +1239,7 @@ static void PrintLeft(char const *s, int width, char pad)
|
|||||||
}
|
}
|
||||||
/* Mop up any potential combining characters */
|
/* Mop up any potential combining characters */
|
||||||
while (*ws && wcwidth(*ws) == 0) {
|
while (*ws && wcwidth(*ws) == 0) {
|
||||||
PutWideChar(*ws++);
|
PutWideChar(*ws++, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Possibly send lrm control sequence */
|
/* Possibly send lrm control sequence */
|
||||||
@@ -1297,7 +1301,7 @@ static void PrintCentered(char const *s, int width, char *pad)
|
|||||||
if (!buf) {
|
if (!buf) {
|
||||||
/* Uh-oh... cannot recover */
|
/* Uh-oh... cannot recover */
|
||||||
fprintf(stderr, "%s\n", ErrMsg[E_NO_MEM]);
|
fprintf(stderr, "%s\n", ErrMsg[E_NO_MEM]);
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void) mbstowcs(buf, s, len+1);
|
(void) mbstowcs(buf, s, len+1);
|
||||||
@@ -1308,7 +1312,7 @@ static void PrintCentered(char const *s, int width, char *pad)
|
|||||||
for (i=0; i<d; i++) fputs(pad, stdout);
|
for (i=0; i<d; i++) fputs(pad, stdout);
|
||||||
for (i=0; i<width; i++) {
|
for (i=0; i<width; i++) {
|
||||||
if (*ws) {
|
if (*ws) {
|
||||||
PutWideChar(*ws++);
|
PutWideChar(*ws++, NULL);
|
||||||
if (wcwidth(*ws) == 0) {
|
if (wcwidth(*ws) == 0) {
|
||||||
/* Don't count this character... it's zero-width */
|
/* Don't count this character... it's zero-width */
|
||||||
i--;
|
i--;
|
||||||
@@ -1319,7 +1323,7 @@ static void PrintCentered(char const *s, int width, char *pad)
|
|||||||
}
|
}
|
||||||
/* Mop up any potential combining characters */
|
/* Mop up any potential combining characters */
|
||||||
while (*ws && wcwidth(*ws) == 0) {
|
while (*ws && wcwidth(*ws) == 0) {
|
||||||
PutWideChar(*ws++);
|
PutWideChar(*ws++, NULL);
|
||||||
}
|
}
|
||||||
/* Possibly send lrm control sequence */
|
/* Possibly send lrm control sequence */
|
||||||
send_lrm();
|
send_lrm();
|
||||||
@@ -1448,7 +1452,7 @@ static int WriteOneColLine(int col)
|
|||||||
}
|
}
|
||||||
numwritten += wcwidth(*ws);
|
numwritten += wcwidth(*ws);
|
||||||
}
|
}
|
||||||
PutWideChar(*ws);
|
PutWideChar(*ws, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e->wc_pos = ws;
|
e->wc_pos = ws;
|
||||||
@@ -1463,7 +1467,7 @@ static int WriteOneColLine(int col)
|
|||||||
if (wcwidth(*ws) > 0) {
|
if (wcwidth(*ws) > 0) {
|
||||||
numwritten += wcwidth(*ws);
|
numwritten += wcwidth(*ws);
|
||||||
}
|
}
|
||||||
PutWideChar(*ws);
|
PutWideChar(*ws, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1603,7 +1607,7 @@ static void GenerateCalEntries(int col)
|
|||||||
r=IncludeFile(InitialFile);
|
r=IncludeFile(InitialFile);
|
||||||
if (r) {
|
if (r) {
|
||||||
fprintf(ErrFp, "%s %s: %s\n", ErrMsg[E_ERR_READING], InitialFile, ErrMsg[r]);
|
fprintf(ErrFp, "%s %s: %s\n", ErrMsg[E_ERR_READING], InitialFile, ErrMsg[r]);
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
@@ -1611,7 +1615,7 @@ static void GenerateCalEntries(int col)
|
|||||||
if (r == E_EOF) return;
|
if (r == E_EOF) return;
|
||||||
if (r) {
|
if (r) {
|
||||||
Eprint("%s: %s", ErrMsg[E_ERR_READING], ErrMsg[r]);
|
Eprint("%s: %s", ErrMsg[E_ERR_READING], ErrMsg[r]);
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
s = FindInitialToken(&tok, CurLine);
|
s = FindInitialToken(&tok, CurLine);
|
||||||
|
|
||||||
@@ -2211,10 +2215,114 @@ static void WriteSimpleEntryProtocol1(CalEntry *e)
|
|||||||
printf("%s\n", e->text);
|
printf("%s\n", e->text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WriteJSONTimeTrigger(TimeTrig const *tt)
|
||||||
|
{
|
||||||
|
PrintJSONKeyPairTime("time", tt->ttime);
|
||||||
|
PrintJSONKeyPairTime("nexttime", tt->nexttime);
|
||||||
|
PrintJSONKeyPairInt("tdelta", tt->delta);
|
||||||
|
PrintJSONKeyPairInt("trep", tt->rep);
|
||||||
|
if (tt->duration != NO_TIME) {
|
||||||
|
PrintJSONKeyPairInt("duration", tt->duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteJSONTrigger(Trigger const *t, int include_tags, int today)
|
||||||
|
{
|
||||||
|
/* wd is an array of days from 0=monday to 6=sunday.
|
||||||
|
We convert to array of strings */
|
||||||
|
if (t->wd != NO_WD) {
|
||||||
|
printf("\"wd\":[");
|
||||||
|
int done = 0;
|
||||||
|
int i;
|
||||||
|
for (i=0; i<7; i++) {
|
||||||
|
if (t->wd & (1 << i)) {
|
||||||
|
if (done) {
|
||||||
|
printf(",");
|
||||||
|
}
|
||||||
|
done = 1;
|
||||||
|
printf("\"%s\"", EnglishDayName[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("],");
|
||||||
|
}
|
||||||
|
if (t->d != NO_DAY) {
|
||||||
|
PrintJSONKeyPairInt("d", t->d);
|
||||||
|
}
|
||||||
|
if (t->m != NO_MON) {
|
||||||
|
PrintJSONKeyPairInt("m", t->m+1);
|
||||||
|
}
|
||||||
|
if (t->y != NO_YR) {
|
||||||
|
PrintJSONKeyPairInt("y", t->y);
|
||||||
|
}
|
||||||
|
if (t->back) {
|
||||||
|
PrintJSONKeyPairInt("back", t->back);
|
||||||
|
}
|
||||||
|
if (t->delta) {
|
||||||
|
PrintJSONKeyPairInt("delta", t->delta);
|
||||||
|
}
|
||||||
|
if (t->rep) {
|
||||||
|
PrintJSONKeyPairInt("rep", t->rep);
|
||||||
|
}
|
||||||
|
/* Local omit is an array of days from 0=monday to 6=sunday.
|
||||||
|
We convert to array of strings */
|
||||||
|
if (t->localomit != NO_WD) {
|
||||||
|
printf("\"localomit\":[");
|
||||||
|
int done = 0;
|
||||||
|
int i;
|
||||||
|
for (i=0; i<7; i++) {
|
||||||
|
if (t->localomit & (1 << i)) {
|
||||||
|
if (done) {
|
||||||
|
printf(",");
|
||||||
|
}
|
||||||
|
done = 1;
|
||||||
|
printf("\"%s\"", EnglishDayName[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("],");
|
||||||
|
}
|
||||||
|
switch(t->skip) {
|
||||||
|
case SKIP_SKIP:
|
||||||
|
PrintJSONKeyPairString("skip", "SKIP");
|
||||||
|
break;
|
||||||
|
case BEFORE_SKIP:
|
||||||
|
PrintJSONKeyPairString("skip", "BEFORE");
|
||||||
|
break;
|
||||||
|
case AFTER_SKIP:
|
||||||
|
PrintJSONKeyPairString("skip", "AFTER");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PrintJSONKeyPairDate("until", t->until);
|
||||||
|
if (t->once != NO_ONCE) {
|
||||||
|
PrintJSONKeyPairInt("once", t->once);
|
||||||
|
}
|
||||||
|
if (t->scanfrom != today) {
|
||||||
|
PrintJSONKeyPairDate("scanfrom", t->scanfrom);
|
||||||
|
}
|
||||||
|
PrintJSONKeyPairDate("from", t->from);
|
||||||
|
PrintJSONKeyPairInt("priority", t->priority);
|
||||||
|
PrintJSONKeyPairDateTime("eventstart", t->eventstart);
|
||||||
|
if (t->eventduration != NO_TIME) {
|
||||||
|
PrintJSONKeyPairInt("eventduration", t->eventduration);
|
||||||
|
}
|
||||||
|
if (t->maybe_uncomputable) {
|
||||||
|
PrintJSONKeyPairInt("maybe_uncomputable", 1);
|
||||||
|
}
|
||||||
|
if (t->noqueue) {
|
||||||
|
PrintJSONKeyPairInt("noqueue", 1);
|
||||||
|
}
|
||||||
|
PrintJSONKeyPairString("sched", t->sched);
|
||||||
|
PrintJSONKeyPairString("warn", t->warn);
|
||||||
|
PrintJSONKeyPairString("omitfunc", t->omitfunc);
|
||||||
|
if (t->addomit) {
|
||||||
|
PrintJSONKeyPairInt("addomit", 1);
|
||||||
|
}
|
||||||
|
if (include_tags) {
|
||||||
|
PrintJSONKeyPairString("tags", DBufValue(&(t->tags)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
|
static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
|
||||||
{
|
{
|
||||||
int done = 0;
|
|
||||||
char const *s;
|
char const *s;
|
||||||
if (DoPrefixLineNo) {
|
if (DoPrefixLineNo) {
|
||||||
PrintJSONKeyPairString("filename", e->filename);
|
PrintJSONKeyPairString("filename", e->filename);
|
||||||
@@ -2234,88 +2342,13 @@ static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
|
|||||||
PrintJSONKeyPairInt("trep", e->tt.rep);
|
PrintJSONKeyPairInt("trep", e->tt.rep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e->trig.eventduration != NO_TIME) {
|
WriteJSONTrigger(&e->trig, 0, today);
|
||||||
PrintJSONKeyPairInt("eventduration", e->trig.eventduration);
|
|
||||||
}
|
|
||||||
/* wd is an array of days from 0=monday to 6=sunday.
|
|
||||||
We convert to array of strings */
|
|
||||||
if (e->trig.wd != NO_WD) {
|
|
||||||
printf("\"wd\":[");
|
|
||||||
done = 0;
|
|
||||||
int i;
|
|
||||||
for (i=0; i<7; i++) {
|
|
||||||
if (e->trig.wd & (1 << i)) {
|
|
||||||
if (done) {
|
|
||||||
printf(",");
|
|
||||||
}
|
|
||||||
done = 1;
|
|
||||||
printf("\"%s\"", EnglishDayName[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("],");
|
|
||||||
}
|
|
||||||
if (e->trig.d != NO_DAY) {
|
|
||||||
PrintJSONKeyPairInt("d", e->trig.d);
|
|
||||||
}
|
|
||||||
if (e->trig.m != NO_MON) {
|
|
||||||
PrintJSONKeyPairInt("m", e->trig.m+1);
|
|
||||||
}
|
|
||||||
if (e->trig.y != NO_YR) {
|
|
||||||
PrintJSONKeyPairInt("y", e->trig.y);
|
|
||||||
}
|
|
||||||
PrintJSONKeyPairDateTime("eventstart", e->trig.eventstart);
|
|
||||||
if (e->trig.back) {
|
|
||||||
PrintJSONKeyPairInt("back", e->trig.back);
|
|
||||||
}
|
|
||||||
if (e->trig.delta) {
|
|
||||||
PrintJSONKeyPairInt("delta", e->trig.delta);
|
|
||||||
}
|
|
||||||
if (e->trig.rep) {
|
|
||||||
PrintJSONKeyPairInt("rep", e->trig.rep);
|
|
||||||
}
|
|
||||||
if (e->nonconst_expr) {
|
if (e->nonconst_expr) {
|
||||||
PrintJSONKeyPairInt("nonconst_expr", e->nonconst_expr);
|
PrintJSONKeyPairInt("nonconst_expr", e->nonconst_expr);
|
||||||
}
|
}
|
||||||
if (e->if_depth) {
|
if (e->if_depth) {
|
||||||
PrintJSONKeyPairInt("if_depth", e->if_depth);
|
PrintJSONKeyPairInt("if_depth", e->if_depth);
|
||||||
}
|
}
|
||||||
switch(e->trig.skip) {
|
|
||||||
case SKIP_SKIP:
|
|
||||||
PrintJSONKeyPairString("skip", "SKIP");
|
|
||||||
break;
|
|
||||||
case BEFORE_SKIP:
|
|
||||||
PrintJSONKeyPairString("skip", "BEFORE");
|
|
||||||
break;
|
|
||||||
case AFTER_SKIP:
|
|
||||||
PrintJSONKeyPairString("skip", "AFTER");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Local omit is an array of days from 0=monday to 6=sunday.
|
|
||||||
We convert to array of strings */
|
|
||||||
if (e->trig.localomit != NO_WD) {
|
|
||||||
printf("\"localomit\":[");
|
|
||||||
done = 0;
|
|
||||||
int i;
|
|
||||||
for (i=0; i<7; i++) {
|
|
||||||
if (e->trig.localomit & (1 << i)) {
|
|
||||||
if (done) {
|
|
||||||
printf(",");
|
|
||||||
}
|
|
||||||
done = 1;
|
|
||||||
printf("\"%s\"", EnglishDayName[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("],");
|
|
||||||
}
|
|
||||||
PrintJSONKeyPairDate("until", e->trig.until);
|
|
||||||
if (e->trig.once != NO_ONCE) {
|
|
||||||
PrintJSONKeyPairInt("once", e->trig.once);
|
|
||||||
}
|
|
||||||
if (e->trig.scanfrom != today) {
|
|
||||||
PrintJSONKeyPairDate("scanfrom", e->trig.scanfrom);
|
|
||||||
}
|
|
||||||
PrintJSONKeyPairDate("from", e->trig.from);
|
|
||||||
PrintJSONKeyPairInt("priority", e->trig.priority);
|
|
||||||
|
|
||||||
if (e->is_color) {
|
if (e->is_color) {
|
||||||
PrintJSONKeyPairInt("r", e->r);
|
PrintJSONKeyPairInt("r", e->r);
|
||||||
|
|||||||
@@ -10,6 +10,9 @@
|
|||||||
/* Define if you have the <sys/types.h> header file. */
|
/* Define if you have the <sys/types.h> header file. */
|
||||||
#undef HAVE_SYS_TYPES_H
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/inotify.h> header file. */
|
||||||
|
#undef HAVE_SYS_INOTIFY_H
|
||||||
|
|
||||||
/* Define if you have the <glob.h> header file */
|
/* Define if you have the <glob.h> header file */
|
||||||
#undef HAVE_GLOB_H
|
#undef HAVE_GLOB_H
|
||||||
|
|
||||||
@@ -17,6 +20,8 @@
|
|||||||
|
|
||||||
#undef HAVE_LOCALE_H
|
#undef HAVE_LOCALE_H
|
||||||
|
|
||||||
|
#undef HAVE_INOTIFY_INIT1
|
||||||
|
|
||||||
#undef HAVE_LANGINFO_H
|
#undef HAVE_LANGINFO_H
|
||||||
|
|
||||||
#undef HAVE_GLOB
|
#undef HAVE_GLOB
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* which you can customize. */
|
/* which you can customize. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
|
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
#define VAL_STACK_SIZE 1000
|
#define VAL_STACK_SIZE 100
|
||||||
|
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */
|
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* which you can customize. */
|
/* which you can customize. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
|
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
#define VAL_STACK_SIZE 1000
|
#define VAL_STACK_SIZE 100
|
||||||
|
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */
|
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */
|
||||||
|
|||||||
62
src/dorem.c
62
src/dorem.c
@@ -7,7 +7,7 @@
|
|||||||
/* commands. */
|
/* commands. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -192,7 +192,7 @@ int DoRem(ParsePtr p)
|
|||||||
|
|
||||||
r = OK;
|
r = OK;
|
||||||
if (ShouldTriggerReminder(&trig, &tim, dse, &err)) {
|
if (ShouldTriggerReminder(&trig, &tim, dse, &err)) {
|
||||||
if ( (r=TriggerReminder(p, &trig, &tim, dse, 0)) ) {
|
if ( (r=TriggerReminder(p, &trig, &tim, dse, 0, NULL)) ) {
|
||||||
FreeTrig(&trig);
|
FreeTrig(&trig);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -350,6 +350,16 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
|||||||
if (r) return r;
|
if (r) return r;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* A time implicitly introduces an AT if AT is not explicit */
|
||||||
|
case T_Time:
|
||||||
|
DBufFree(&buf);
|
||||||
|
if (tim->ttime != NO_TIME) return E_TIME_TWICE;
|
||||||
|
tim->ttime = tok.val;
|
||||||
|
r = ParseTimeTrig(s, tim, save_in_globals);
|
||||||
|
if (r) return r;
|
||||||
|
trig->duration_days = ComputeTrigDuration(tim);
|
||||||
|
break;
|
||||||
|
|
||||||
case T_At:
|
case T_At:
|
||||||
DBufFree(&buf);
|
DBufFree(&buf);
|
||||||
r=ParseTimeTrig(s, tim, save_in_globals);
|
r=ParseTimeTrig(s, tim, save_in_globals);
|
||||||
@@ -669,6 +679,9 @@ static int ParseLocalOmit(ParsePtr s, Trigger *t)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (t->localomit == NO_WD) {
|
||||||
|
return E_EXPECTING_WEEKDAY;
|
||||||
|
}
|
||||||
PushToken(DBufValue(&buf), s);
|
PushToken(DBufValue(&buf), s);
|
||||||
DBufFree(&buf);
|
DBufFree(&buf);
|
||||||
return OK;
|
return OK;
|
||||||
@@ -900,7 +913,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
|||||||
/* Trigger the reminder if it's a RUN or MSG 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)
|
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued, DynamicBuffer *output)
|
||||||
{
|
{
|
||||||
int r, y, m, d;
|
int r, y, m, d;
|
||||||
char PrioExpr[VAR_NAME_LEN+25];
|
char PrioExpr[VAR_NAME_LEN+25];
|
||||||
@@ -967,7 +980,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
|||||||
}
|
}
|
||||||
/* If it's a MSG-type reminder, and no -k option was used, issue the banner. */
|
/* 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)
|
if ((t->typ == MSG_TYPE || t->typ == MSF_TYPE)
|
||||||
&& !DidMsgReminder && !NextMode && !msg_command) {
|
&& !DidMsgReminder && !NextMode && !msg_command && !is_queued) {
|
||||||
DidMsgReminder = 1;
|
DidMsgReminder = 1;
|
||||||
if (!DoSubstFromString(DBufValue(&Banner), &buf,
|
if (!DoSubstFromString(DBufValue(&Banner), &buf,
|
||||||
DSEToday, NO_TIME) &&
|
DSEToday, NO_TIME) &&
|
||||||
@@ -1034,11 +1047,18 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
|||||||
return E_NO_MEM;
|
return E_NO_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s%s%s\n", DBufValue(&calRow), DBufValue(&pre_buf), DBufValue(&buf));
|
r = OK;
|
||||||
|
if (output) {
|
||||||
|
if (DBufPuts(output, DBufValue(&calRow)) != OK) r = E_NO_MEM;
|
||||||
|
if (DBufPuts(output, DBufValue(&pre_buf)) != OK) r = E_NO_MEM;
|
||||||
|
if (DBufPuts(output, DBufValue(&buf)) != OK) r = E_NO_MEM;
|
||||||
|
} else {
|
||||||
|
printf("%s%s%s\n", DBufValue(&calRow), DBufValue(&pre_buf), DBufValue(&buf));
|
||||||
|
}
|
||||||
DBufFree(&buf);
|
DBufFree(&buf);
|
||||||
DBufFree(&pre_buf);
|
DBufFree(&pre_buf);
|
||||||
DBufFree(&calRow);
|
DBufFree(&calRow);
|
||||||
return OK;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Correct colors */
|
/* Correct colors */
|
||||||
@@ -1134,18 +1154,27 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
|||||||
case MSG_TYPE:
|
case MSG_TYPE:
|
||||||
case PASSTHRU_TYPE:
|
case PASSTHRU_TYPE:
|
||||||
if (msg_command) {
|
if (msg_command) {
|
||||||
DoMsgCommand(msg_command, DBufValue(&buf));
|
DoMsgCommand(msg_command, DBufValue(&buf), is_queued);
|
||||||
} else {
|
} else {
|
||||||
printf("%s", DBufValue(&buf));
|
if (output) {
|
||||||
|
DBufPuts(output, DBufValue(&buf));
|
||||||
|
} else {
|
||||||
|
/* Add a space before "NOTE endreminder" */
|
||||||
|
if (IsServerMode() && !strncmp(DBufValue(&buf), "NOTE endreminder", 16)) {
|
||||||
|
printf(" %s", DBufValue(&buf));
|
||||||
|
} else {
|
||||||
|
printf("%s", DBufValue(&buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSF_TYPE:
|
case MSF_TYPE:
|
||||||
FillParagraph(DBufValue(&buf));
|
FillParagraph(DBufValue(&buf), output);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RUN_TYPE:
|
case RUN_TYPE:
|
||||||
System(DBufValue(&buf));
|
System(DBufValue(&buf), is_queued);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* Unknown/illegal type? */
|
default: /* Unknown/illegal type? */
|
||||||
@@ -1184,7 +1213,7 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int dse, int *err)
|
|||||||
if (DontIssueAts > 1) {
|
if (DontIssueAts > 1) {
|
||||||
/* If two or more -a options, then *DO* issue ats that are in the
|
/* If two or more -a options, then *DO* issue ats that are in the
|
||||||
future */
|
future */
|
||||||
if (tim->ttime < SystemTime(0) / 60) {
|
if (tim->ttime < MinutesPastMidnight(0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1192,13 +1221,6 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int dse, int *err)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't trigger "old" timed reminders */
|
|
||||||
/*** REMOVED...
|
|
||||||
if (dse == DSEToday &&
|
|
||||||
tim->ttime != NO_TIME &&
|
|
||||||
tim->ttime < SystemTime(0) / 60) return 0;
|
|
||||||
*** ...UNTIL HERE */
|
|
||||||
|
|
||||||
/* If "infinite delta" option is chosen, always trigger future reminders */
|
/* If "infinite delta" option is chosen, always trigger future reminders */
|
||||||
if (InfiniteDelta || NextMode) return 1;
|
if (InfiniteDelta || NextMode) return 1;
|
||||||
|
|
||||||
@@ -1379,7 +1401,7 @@ static int ParsePriority(ParsePtr s, Trigger *t)
|
|||||||
/* Execute the '-k' command, escaping shell chars in message. */
|
/* Execute the '-k' command, escaping shell chars in message. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
int DoMsgCommand(char const *cmd, char const *msg)
|
int DoMsgCommand(char const *cmd, char const *msg, int is_queued)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
int i, l;
|
int i, l;
|
||||||
@@ -1416,7 +1438,7 @@ int DoMsgCommand(char const *cmd, char const *msg)
|
|||||||
}
|
}
|
||||||
r = OK;
|
r = OK;
|
||||||
|
|
||||||
System(DBufValue(&execBuffer));
|
System(DBufValue(&execBuffer), is_queued);
|
||||||
|
|
||||||
finished:
|
finished:
|
||||||
DBufFree(&buf);
|
DBufFree(&buf);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* reminders are triggered. */
|
/* reminders are triggered. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -46,11 +46,11 @@
|
|||||||
int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode)
|
int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode)
|
||||||
{
|
{
|
||||||
int diff = dse - DSEToday;
|
int diff = dse - DSEToday;
|
||||||
int curtime = SystemTime(0) / 60;
|
int curtime = MinutesPastMidnight(0);
|
||||||
int err, done;
|
int err, done;
|
||||||
int c;
|
int c;
|
||||||
int d, m, y;
|
int d, m, y;
|
||||||
int tim = tt->ttime;
|
int tim = NO_TIME;
|
||||||
int h, min, hh, ch, cmin, chh;
|
int h, min, hh, ch, cmin, chh;
|
||||||
int i;
|
int i;
|
||||||
char const *pm, *cpm;
|
char const *pm, *cpm;
|
||||||
@@ -72,6 +72,9 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
|||||||
|
|
||||||
FromDSE(dse, &y, &m, &d);
|
FromDSE(dse, &y, &m, &d);
|
||||||
|
|
||||||
|
if (tt) {
|
||||||
|
tim = tt->ttime;
|
||||||
|
}
|
||||||
if (tim == NO_TIME) tim = curtime;
|
if (tim == NO_TIME) tim = curtime;
|
||||||
tdiff = tim - curtime;
|
tdiff = tim - curtime;
|
||||||
adiff = ABS(tdiff);
|
adiff = ABS(tdiff);
|
||||||
@@ -894,7 +897,7 @@ int DoSubstFromString(char const *source, DynamicBuffer *dbuf,
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (dse == NO_DATE) dse=DSEToday;
|
if (dse == NO_DATE) dse=DSEToday;
|
||||||
if (tim == NO_TIME) tim=SystemTime(0)/60;
|
if (tim == NO_TIME) tim=MinutesPastMidnight(0);
|
||||||
CreateParser(source, &tempP);
|
CreateParser(source, &tempP);
|
||||||
tempP.allownested = 0;
|
tempP.allownested = 0;
|
||||||
tempTrig.typ = MSG_TYPE;
|
tempTrig.typ = MSG_TYPE;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* buffers. */
|
/* buffers. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* Declaration of functions for manipulating dynamic buffers */
|
/* Declaration of functions for manipulating dynamic buffers */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
17
src/err.h
17
src/err.h
@@ -5,7 +5,7 @@
|
|||||||
/* Error definitions. */
|
/* Error definitions. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -121,6 +121,8 @@
|
|||||||
#define E_STRING_TOO_LONG 101
|
#define E_STRING_TOO_LONG 101
|
||||||
#define E_TIME_TWICE 102
|
#define E_TIME_TWICE 102
|
||||||
#define E_DURATION_NO_AT 103
|
#define E_DURATION_NO_AT 103
|
||||||
|
#define E_EXPECTING_WEEKDAY 104
|
||||||
|
|
||||||
#ifdef MK_GLOBALS
|
#ifdef MK_GLOBALS
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#define EXTERN
|
#define EXTERN
|
||||||
@@ -129,6 +131,10 @@
|
|||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define STR(X) STR2(X)
|
||||||
|
#define STR2(X) #X
|
||||||
|
|
||||||
|
|
||||||
#ifndef L_ERR_OVERRIDE
|
#ifndef L_ERR_OVERRIDE
|
||||||
EXTERN char *ErrMsg[]
|
EXTERN char *ErrMsg[]
|
||||||
|
|
||||||
@@ -165,7 +171,7 @@ EXTERN char *ErrMsg[]
|
|||||||
"Number too high",
|
"Number too high",
|
||||||
"Number too low",
|
"Number too low",
|
||||||
"Can't open file",
|
"Can't open file",
|
||||||
"INCLUDE nested too deeply",
|
"INCLUDE nested too deeply (max. " STR(INCLUDE_NEST) ")",
|
||||||
"Parse error",
|
"Parse error",
|
||||||
"Can't compute trigger",
|
"Can't compute trigger",
|
||||||
"Too many nested IFs",
|
"Too many nested IFs",
|
||||||
@@ -189,8 +195,8 @@ EXTERN char *ErrMsg[]
|
|||||||
"Day specified twice",
|
"Day specified twice",
|
||||||
"Unknown token",
|
"Unknown token",
|
||||||
"Must specify month in OMIT command",
|
"Must specify month in OMIT command",
|
||||||
"Too many partial OMITs",
|
"Too many partial OMITs (max. " STR(MAX_PARTIAL_OMITS) ")",
|
||||||
"Too many full OMITs",
|
"Too many full OMITs (max. " STR(MAX_FULL_OMITS) ")",
|
||||||
"Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT",
|
"Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT",
|
||||||
"Error reading",
|
"Error reading",
|
||||||
"Expecting end-of-line",
|
"Expecting end-of-line",
|
||||||
@@ -237,7 +243,8 @@ EXTERN char *ErrMsg[]
|
|||||||
"No files matching *.rem",
|
"No files matching *.rem",
|
||||||
"String too long",
|
"String too long",
|
||||||
"Time specified twice",
|
"Time specified twice",
|
||||||
"Cannot specify DURATION without specifying AT"
|
"Cannot specify DURATION without specifying AT",
|
||||||
|
"Expecting weekday name"
|
||||||
}
|
}
|
||||||
#endif /* MK_GLOBALS */
|
#endif /* MK_GLOBALS */
|
||||||
;
|
;
|
||||||
|
|||||||
75
src/expr.c
75
src/expr.c
@@ -5,7 +5,7 @@
|
|||||||
/* This file contains routines to parse and evaluate */
|
/* This file contains routines to parse and evaluate */
|
||||||
/* expressions. */
|
/* expressions. */
|
||||||
/* */
|
/* */
|
||||||
/* Copyright 1992-2023 by Dianne Skoll */
|
/* Copyright 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -87,10 +87,11 @@ extern BuiltinFunc Func[];
|
|||||||
|
|
||||||
static Operator OpStack[OP_STACK_SIZE];
|
static Operator OpStack[OP_STACK_SIZE];
|
||||||
static int OpStackPtr = 0;
|
static int OpStackPtr = 0;
|
||||||
|
static int OpStackHiWater = 0;
|
||||||
/* ValStack can't be static - needed by funcs.c */
|
/* ValStack can't be static - needed by funcs.c */
|
||||||
Value ValStack[VAL_STACK_SIZE];
|
Value ValStack[VAL_STACK_SIZE];
|
||||||
int ValStackPtr = 0;
|
int ValStackPtr = 0;
|
||||||
|
int ValStackHiWater = 0;
|
||||||
|
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
/* */
|
/* */
|
||||||
@@ -944,7 +945,8 @@ static int Subtract(void)
|
|||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
static int Multiply(void)
|
static int Multiply(void)
|
||||||
{
|
{
|
||||||
Value v1, v2;
|
Value v1, v2, v3;
|
||||||
|
char *ptr;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
PopValStack(v2);
|
PopValStack(v2);
|
||||||
@@ -964,6 +966,61 @@ static int Multiply(void)
|
|||||||
PushValStack(v1);
|
PushValStack(v1);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* String times int means repeat the string that many times */
|
||||||
|
if ((v1.type == INT_TYPE && v2.type == STR_TYPE) ||
|
||||||
|
(v1.type == STR_TYPE && v2.type == INT_TYPE)) {
|
||||||
|
int rep = (v1.type == INT_TYPE ? v1.v.val : v2.v.val);
|
||||||
|
char const *str = (v1.type == INT_TYPE ? v2.v.str : v1.v.str);
|
||||||
|
int l;
|
||||||
|
|
||||||
|
/* Can't multiply by a negative number */
|
||||||
|
if (rep < 0) {
|
||||||
|
return E_2LOW;
|
||||||
|
}
|
||||||
|
if (rep == 0 || !str || !*str) {
|
||||||
|
/* Empty string */
|
||||||
|
DestroyValue(v1); DestroyValue(v2);
|
||||||
|
v3.type = STR_TYPE;
|
||||||
|
v3.v.str = malloc(1);
|
||||||
|
if (!v3.v.str) {
|
||||||
|
return E_NO_MEM;
|
||||||
|
}
|
||||||
|
*v3.v.str = 0;
|
||||||
|
PushValStack(v3);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the new value */
|
||||||
|
l = (int) strlen(str);
|
||||||
|
if (l * rep < 0) {
|
||||||
|
DestroyValue(v1); DestroyValue(v2);
|
||||||
|
return E_STRING_TOO_LONG;
|
||||||
|
}
|
||||||
|
if ((unsigned long) l * (unsigned long) rep >= (unsigned long) INT_MAX) {
|
||||||
|
DestroyValue(v1); DestroyValue(v2);
|
||||||
|
return E_STRING_TOO_LONG;
|
||||||
|
}
|
||||||
|
if (MaxStringLen > 0 && ((unsigned long) l * (unsigned long) rep) > (unsigned long)MaxStringLen) {
|
||||||
|
DestroyValue(v1); DestroyValue(v2);
|
||||||
|
return E_STRING_TOO_LONG;
|
||||||
|
}
|
||||||
|
v3.type = STR_TYPE;
|
||||||
|
v3.v.str = malloc(l * rep + 1);
|
||||||
|
if (!v3.v.str) {
|
||||||
|
DestroyValue(v1); DestroyValue(v2);
|
||||||
|
return E_NO_MEM;
|
||||||
|
}
|
||||||
|
*v3.v.str = 0;
|
||||||
|
ptr = v3.v.str;
|
||||||
|
for (int i=0; i<rep; i++) {
|
||||||
|
strcat(ptr, str);
|
||||||
|
ptr += l;
|
||||||
|
}
|
||||||
|
DestroyValue(v1); DestroyValue(v2);
|
||||||
|
PushValStack(v3);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
DestroyValue(v1); DestroyValue(v2);
|
DestroyValue(v1); DestroyValue(v2);
|
||||||
return E_BAD_TYPE;
|
return E_BAD_TYPE;
|
||||||
}
|
}
|
||||||
@@ -1429,3 +1486,11 @@ int FnPopValStack(Value *val)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugExitFunc(void)
|
||||||
|
{
|
||||||
|
if (DebugFlag & DB_EXPR_STACKS) {
|
||||||
|
fprintf(stderr, "Operator stack high water: %d\n", OpStackHiWater);
|
||||||
|
fprintf(stderr, " Value stack high water: %d\n", ValStackHiWater);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
34
src/expr.h
34
src/expr.h
@@ -5,19 +5,20 @@
|
|||||||
/* Contains a few definitions used by expression evaluator. */
|
/* Contains a few definitions used by expression evaluator. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|
||||||
/* Define the types of values */
|
/* Define the types of values */
|
||||||
#define ERR_TYPE 0
|
#define ERR_TYPE 0
|
||||||
#define INT_TYPE 1
|
#define INT_TYPE 1
|
||||||
#define TIME_TYPE 2
|
#define TIME_TYPE 2
|
||||||
#define DATE_TYPE 3
|
#define DATE_TYPE 3
|
||||||
#define STR_TYPE 4
|
#define STR_TYPE 4
|
||||||
#define DATETIME_TYPE 5
|
#define DATETIME_TYPE 5
|
||||||
#define SPECIAL_TYPE 6 /* Only for system variables */
|
#define SPECIAL_TYPE 6 /* Only for system variables */
|
||||||
|
#define CONST_INT_TYPE 7 /* Only for system variables */
|
||||||
|
|
||||||
/* Define stuff for parsing expressions */
|
/* Define stuff for parsing expressions */
|
||||||
#define BEG_OF_EXPR '['
|
#define BEG_OF_EXPR '['
|
||||||
@@ -32,10 +33,8 @@
|
|||||||
for speed. BEWARE: These macros invoke return if an error happens ! */
|
for speed. BEWARE: These macros invoke return if an error happens ! */
|
||||||
|
|
||||||
#define PushOpStack(op) \
|
#define PushOpStack(op) \
|
||||||
if (OpStackPtr >= OP_STACK_SIZE) \
|
do { if (OpStackPtr >= OP_STACK_SIZE) return E_OP_STK_OVER; \
|
||||||
return E_OP_STK_OVER; \
|
else { OpStack[OpStackPtr++] = (op); if (OpStackPtr > OpStackHiWater) OpStackHiWater = OpStackPtr; } } while(0)
|
||||||
else \
|
|
||||||
OpStack[OpStackPtr++] = (op)
|
|
||||||
|
|
||||||
#define PopOpStack(op) \
|
#define PopOpStack(op) \
|
||||||
if (OpStackPtr <= 0) \
|
if (OpStackPtr <= 0) \
|
||||||
@@ -44,10 +43,13 @@ else \
|
|||||||
(op) = OpStack[--OpStackPtr]
|
(op) = OpStack[--OpStackPtr]
|
||||||
|
|
||||||
#define PushValStack(val) \
|
#define PushValStack(val) \
|
||||||
if (ValStackPtr >= VAL_STACK_SIZE) \
|
do { if (ValStackPtr >= VAL_STACK_SIZE) { \
|
||||||
return E_VA_STK_OVER; \
|
DestroyValue(val); \
|
||||||
else \
|
return E_VA_STK_OVER; \
|
||||||
ValStack[ValStackPtr++] = (val)
|
} else { \
|
||||||
|
ValStack[ValStackPtr++] = (val); \
|
||||||
|
if (ValStackPtr > ValStackHiWater) ValStackHiWater = ValStackPtr; \
|
||||||
|
} } while (0);
|
||||||
|
|
||||||
#define PopValStack(val) \
|
#define PopValStack(val) \
|
||||||
if (ValStackPtr <= 0) \
|
if (ValStackPtr <= 0) \
|
||||||
|
|||||||
24
src/files.c
24
src/files.c
@@ -7,7 +7,7 @@
|
|||||||
/* files. */
|
/* files. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -42,8 +42,8 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Convenient macros for closing files */
|
/* Convenient macros for closing files */
|
||||||
#define FCLOSE(fp) (((fp)&&((fp)!=stdin)) ? (fclose(fp),(fp)=NULL) : ((fp)=NULL))
|
#define FCLOSE(fp) ((((fp)!=stdin)) ? (fclose(fp),(fp)=NULL) : ((fp)=NULL))
|
||||||
#define PCLOSE(fp) (((fp)&&((fp)!=stdin)) ? (pclose(fp),(fp)=NULL) : ((fp)=NULL))
|
#define PCLOSE(fp) ((((fp)!=stdin)) ? (pclose(fp),(fp)=NULL) : ((fp)=NULL))
|
||||||
|
|
||||||
/* Define the structures needed by the file caching system */
|
/* Define the structures needed by the file caching system */
|
||||||
typedef struct cache {
|
typedef struct cache {
|
||||||
@@ -100,6 +100,18 @@ static int CheckSafety (void);
|
|||||||
static int CheckSafetyAux (struct stat *statbuf);
|
static int CheckSafetyAux (struct stat *statbuf);
|
||||||
static int PopFile (void);
|
static int PopFile (void);
|
||||||
static int IncludeCmd(char const *);
|
static int IncludeCmd(char const *);
|
||||||
|
|
||||||
|
void set_cloexec(int fd)
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
flags = fcntl(fd, F_GETFD);
|
||||||
|
if (flags >= 0) {
|
||||||
|
flags |= FD_CLOEXEC;
|
||||||
|
fcntl(fd, F_SETFD, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void OpenPurgeFile(char const *fname, char const *mode)
|
static void OpenPurgeFile(char const *fname, char const *mode)
|
||||||
{
|
{
|
||||||
DynamicBuffer fname_buf;
|
DynamicBuffer fname_buf;
|
||||||
@@ -123,6 +135,7 @@ static void OpenPurgeFile(char const *fname, char const *mode)
|
|||||||
if (!PurgeFP) {
|
if (!PurgeFP) {
|
||||||
fprintf(ErrFp, "Cannot open `%s' for writing: %s\n", DBufValue(&fname_buf), strerror(errno));
|
fprintf(ErrFp, "Cannot open `%s' for writing: %s\n", DBufValue(&fname_buf), strerror(errno));
|
||||||
}
|
}
|
||||||
|
set_cloexec(fileno(PurgeFP));
|
||||||
DBufFree(&fname_buf);
|
DBufFree(&fname_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,6 +340,7 @@ int OpenFile(char const *fname)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fp = fopen(fname, "r");
|
fp = fopen(fname, "r");
|
||||||
|
if (fp) set_cloexec(fileno(fp));
|
||||||
if (DebugFlag & DB_TRACE_FILES) {
|
if (DebugFlag & DB_TRACE_FILES) {
|
||||||
fprintf(ErrFp, "Reading `%s': Opening file on disk\n", fname);
|
fprintf(ErrFp, "Reading `%s': Opening file on disk\n", fname);
|
||||||
}
|
}
|
||||||
@@ -346,6 +360,7 @@ int OpenFile(char const *fname)
|
|||||||
if (strcmp(fname, "-")) {
|
if (strcmp(fname, "-")) {
|
||||||
fp = fopen(fname, "r");
|
fp = fopen(fname, "r");
|
||||||
if (!fp || !CheckSafety()) return E_CANT_OPEN;
|
if (!fp || !CheckSafety()) return E_CANT_OPEN;
|
||||||
|
set_cloexec(fileno(fp));
|
||||||
if (PurgeMode) OpenPurgeFile(fname, "w");
|
if (PurgeMode) OpenPurgeFile(fname, "w");
|
||||||
} else {
|
} else {
|
||||||
fp = stdin;
|
fp = stdin;
|
||||||
@@ -542,6 +557,7 @@ static int PopFile(void)
|
|||||||
if (strcmp(i->filename, "-")) {
|
if (strcmp(i->filename, "-")) {
|
||||||
fp = fopen(i->filename, "r");
|
fp = fopen(i->filename, "r");
|
||||||
if (!fp || !CheckSafety()) return E_CANT_OPEN;
|
if (!fp || !CheckSafety()) return E_CANT_OPEN;
|
||||||
|
set_cloexec(fileno(fp));
|
||||||
if (PurgeMode) OpenPurgeFile(i->filename, "a");
|
if (PurgeMode) OpenPurgeFile(i->filename, "a");
|
||||||
} else {
|
} else {
|
||||||
fp = stdin;
|
fp = stdin;
|
||||||
|
|||||||
136
src/funcs.c
136
src/funcs.c
@@ -6,11 +6,10 @@
|
|||||||
/* expressions. */
|
/* expressions. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@@ -66,8 +65,6 @@ static int FAbs (func_info *);
|
|||||||
static int FAccess (func_info *);
|
static int FAccess (func_info *);
|
||||||
static int FAmpm (func_info *);
|
static int FAmpm (func_info *);
|
||||||
static int FAnsicolor (func_info *);
|
static int FAnsicolor (func_info *);
|
||||||
static int FTrig (func_info *);
|
|
||||||
static int FIsAny (func_info *);
|
|
||||||
static int FArgs (func_info *);
|
static int FArgs (func_info *);
|
||||||
static int FAsc (func_info *);
|
static int FAsc (func_info *);
|
||||||
static int FBaseyr (func_info *);
|
static int FBaseyr (func_info *);
|
||||||
@@ -101,6 +98,7 @@ static int FHtmlEscape (func_info *);
|
|||||||
static int FHtmlStriptags (func_info *);
|
static int FHtmlStriptags (func_info *);
|
||||||
static int FIif (func_info *);
|
static int FIif (func_info *);
|
||||||
static int FIndex (func_info *);
|
static int FIndex (func_info *);
|
||||||
|
static int FIsAny (func_info *);
|
||||||
static int FIsdst (func_info *);
|
static int FIsdst (func_info *);
|
||||||
static int FIsleap (func_info *);
|
static int FIsleap (func_info *);
|
||||||
static int FIsomitted (func_info *);
|
static int FIsomitted (func_info *);
|
||||||
@@ -117,6 +115,7 @@ static int FMoondate (func_info *);
|
|||||||
static int FMoondatetime (func_info *);
|
static int FMoondatetime (func_info *);
|
||||||
static int FMoonphase (func_info *);
|
static int FMoonphase (func_info *);
|
||||||
static int FMoontime (func_info *);
|
static int FMoontime (func_info *);
|
||||||
|
static int FMultiTrig (func_info *);
|
||||||
static int FNDawn (func_info *);
|
static int FNDawn (func_info *);
|
||||||
static int FNDusk (func_info *);
|
static int FNDusk (func_info *);
|
||||||
static int FNonomitted (func_info *);
|
static int FNonomitted (func_info *);
|
||||||
@@ -134,6 +133,7 @@ static int FRealtoday (func_info *);
|
|||||||
static int FRows (func_info *);
|
static int FRows (func_info *);
|
||||||
static int FSgn (func_info *);
|
static int FSgn (func_info *);
|
||||||
static int FShell (func_info *);
|
static int FShell (func_info *);
|
||||||
|
static int FShellescape (func_info *);
|
||||||
static int FSlide (func_info *);
|
static int FSlide (func_info *);
|
||||||
static int FSoleq (func_info *);
|
static int FSoleq (func_info *);
|
||||||
static int FStdout (func_info *);
|
static int FStdout (func_info *);
|
||||||
@@ -156,9 +156,9 @@ static int FTrigeventstart (func_info *);
|
|||||||
static int FTrigfrom (func_info *);
|
static int FTrigfrom (func_info *);
|
||||||
static int FTrigger (func_info *);
|
static int FTrigger (func_info *);
|
||||||
static int FTrigpriority (func_info *);
|
static int FTrigpriority (func_info *);
|
||||||
static int FTrigtags (func_info *);
|
|
||||||
static int FTrigrep (func_info *);
|
static int FTrigrep (func_info *);
|
||||||
static int FTrigscanfrom (func_info *);
|
static int FTrigscanfrom (func_info *);
|
||||||
|
static int FTrigtags (func_info *);
|
||||||
static int FTrigtime (func_info *);
|
static int FTrigtime (func_info *);
|
||||||
static int FTrigtimedelta (func_info *);
|
static int FTrigtimedelta (func_info *);
|
||||||
static int FTrigtimerep (func_info *);
|
static int FTrigtimerep (func_info *);
|
||||||
@@ -166,15 +166,14 @@ static int FTriguntil (func_info *);
|
|||||||
static int FTrigvalid (func_info *);
|
static int FTrigvalid (func_info *);
|
||||||
static int FTypeof (func_info *);
|
static int FTypeof (func_info *);
|
||||||
static int FTzconvert (func_info *);
|
static int FTzconvert (func_info *);
|
||||||
static int FUpper (func_info *);
|
|
||||||
static int FUTCToLocal (func_info *);
|
static int FUTCToLocal (func_info *);
|
||||||
|
static int FUpper (func_info *);
|
||||||
static int FValue (func_info *);
|
static int FValue (func_info *);
|
||||||
static int FVersion (func_info *);
|
static int FVersion (func_info *);
|
||||||
static int FWeekno (func_info *);
|
static int FWeekno (func_info *);
|
||||||
static int FWkday (func_info *);
|
static int FWkday (func_info *);
|
||||||
static int FWkdaynum (func_info *);
|
static int FWkdaynum (func_info *);
|
||||||
static int FYear (func_info *);
|
static int FYear (func_info *);
|
||||||
static int FShellescape (func_info *);
|
|
||||||
|
|
||||||
static int CleanUpAfterFunc (func_info *);
|
static int CleanUpAfterFunc (func_info *);
|
||||||
static int CheckArgs (BuiltinFunc *f, int nargs);
|
static int CheckArgs (BuiltinFunc *f, int nargs);
|
||||||
@@ -195,6 +194,7 @@ static int CacheHebYear, CacheHebMon, CacheHebDay;
|
|||||||
/* We need access to the value stack */
|
/* We need access to the value stack */
|
||||||
extern Value ValStack[];
|
extern Value ValStack[];
|
||||||
extern int ValStackPtr;
|
extern int ValStackPtr;
|
||||||
|
extern int ValStackHiWater;
|
||||||
|
|
||||||
/* Macro for accessing arguments from the value stack - args are numbered
|
/* Macro for accessing arguments from the value stack - args are numbered
|
||||||
from 0 to (Nargs - 1) */
|
from 0 to (Nargs - 1) */
|
||||||
@@ -251,7 +251,7 @@ BuiltinFunc Func[] = {
|
|||||||
{ "defined", 1, 1, 0, FDefined },
|
{ "defined", 1, 1, 0, FDefined },
|
||||||
{ "dosubst", 1, 3, 0, FDosubst },
|
{ "dosubst", 1, 3, 0, FDosubst },
|
||||||
{ "dusk", 0, 1, 0, FDusk },
|
{ "dusk", 0, 1, 0, FDusk },
|
||||||
{ "easterdate", 1, 1, 0, FEasterdate },
|
{ "easterdate", 0, 1, 0, FEasterdate },
|
||||||
{ "evaltrig", 1, 2, 0, FEvalTrig },
|
{ "evaltrig", 1, 2, 0, FEvalTrig },
|
||||||
{ "filedate", 1, 1, 0, FFiledate },
|
{ "filedate", 1, 1, 0, FFiledate },
|
||||||
{ "filedatetime", 1, 1, 0, FFiledatetime },
|
{ "filedatetime", 1, 1, 0, FFiledatetime },
|
||||||
@@ -284,12 +284,13 @@ BuiltinFunc Func[] = {
|
|||||||
{ "moondatetime", 1, 3, 0, FMoondatetime },
|
{ "moondatetime", 1, 3, 0, FMoondatetime },
|
||||||
{ "moonphase", 0, 2, 0, FMoonphase },
|
{ "moonphase", 0, 2, 0, FMoonphase },
|
||||||
{ "moontime", 1, 3, 0, FMoontime },
|
{ "moontime", 1, 3, 0, FMoontime },
|
||||||
|
{ "multitrig", 1, NO_MAX, 0, FMultiTrig },
|
||||||
{ "ndawn", 0, 1, 0, FNDawn},
|
{ "ndawn", 0, 1, 0, FNDawn},
|
||||||
{ "ndusk", 0, 1, 0, FNDusk},
|
{ "ndusk", 0, 1, 0, FNDusk},
|
||||||
{ "nonomitted", 2, NO_MAX, 0, FNonomitted },
|
{ "nonomitted", 2, NO_MAX, 0, FNonomitted },
|
||||||
{ "now", 0, 0, 0, FNow },
|
{ "now", 0, 0, 0, FNow },
|
||||||
{ "ord", 1, 1, 1, FOrd },
|
{ "ord", 1, 1, 1, FOrd },
|
||||||
{ "orthodoxeaster",1, 1, 0, FOrthodoxeaster },
|
{ "orthodoxeaster",0, 1, 0, FOrthodoxeaster },
|
||||||
{ "ostype", 0, 0, 1, FOstype },
|
{ "ostype", 0, 0, 1, FOstype },
|
||||||
{ "pad", 3, 4, 1, FPad },
|
{ "pad", 3, 4, 1, FPad },
|
||||||
{ "plural", 1, 3, 1, FPlural },
|
{ "plural", 1, 3, 1, FPlural },
|
||||||
@@ -1421,28 +1422,28 @@ static int FRealtoday(func_info *info)
|
|||||||
static int FNow(func_info *info)
|
static int FNow(func_info *info)
|
||||||
{
|
{
|
||||||
RetVal.type = TIME_TYPE;
|
RetVal.type = TIME_TYPE;
|
||||||
RETVAL = (int) ( SystemTime(0) / 60L );
|
RETVAL = MinutesPastMidnight(0);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int FRealnow(func_info *info)
|
static int FRealnow(func_info *info)
|
||||||
{
|
{
|
||||||
RetVal.type = TIME_TYPE;
|
RetVal.type = TIME_TYPE;
|
||||||
RETVAL = (int) ( SystemTime(1) / 60L );
|
RETVAL = MinutesPastMidnight(1);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int FCurrent(func_info *info)
|
static int FCurrent(func_info *info)
|
||||||
{
|
{
|
||||||
RetVal.type = DATETIME_TYPE;
|
RetVal.type = DATETIME_TYPE;
|
||||||
RETVAL = DSEToday * MINUTES_PER_DAY + (SystemTime(0) / 60);
|
RETVAL = DSEToday * MINUTES_PER_DAY + MinutesPastMidnight(0);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int FRealCurrent(func_info *info)
|
static int FRealCurrent(func_info *info)
|
||||||
{
|
{
|
||||||
RetVal.type = DATETIME_TYPE;
|
RetVal.type = DATETIME_TYPE;
|
||||||
RETVAL = RealToday * MINUTES_PER_DAY + (SystemTime(1) / 60);
|
RETVAL = RealToday * MINUTES_PER_DAY + MinutesPastMidnight(1);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2364,13 +2365,17 @@ static int FEasterdate(func_info *info)
|
|||||||
{
|
{
|
||||||
int y, m, d;
|
int y, m, d;
|
||||||
int g, c, x, z, e, n;
|
int g, c, x, z, e, n;
|
||||||
if (ARG(0).type == INT_TYPE) {
|
if (Nargs == 0) {
|
||||||
y = ARGV(0);
|
FromDSE(DSEToday, &y, &m, &d);
|
||||||
if (y < BASE) return E_2LOW;
|
} else {
|
||||||
else if (y > BASE+YR_RANGE) return E_2HIGH;
|
if (ARG(0).type == INT_TYPE) {
|
||||||
} else if (HASDATE(ARG(0))) {
|
y = ARGV(0);
|
||||||
FromDSE(DATEPART(ARG(0)), &y, &m, &d); /* We just want the year */
|
if (y < BASE) return E_2LOW;
|
||||||
} else return E_BAD_TYPE;
|
else if (y > BASE+YR_RANGE) return E_2HIGH;
|
||||||
|
} else if (HASDATE(ARG(0))) {
|
||||||
|
FromDSE(DATEPART(ARG(0)), &y, &m, &d); /* We just want the year */
|
||||||
|
} else return E_BAD_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
g = (y % 19) + 1; /* golden number */
|
g = (y % 19) + 1; /* golden number */
|
||||||
@@ -2409,13 +2414,17 @@ static int FOrthodoxeaster(func_info *info)
|
|||||||
{
|
{
|
||||||
int y, m, d;
|
int y, m, d;
|
||||||
int a, b, c, dd, e, f, dse;
|
int a, b, c, dd, e, f, dse;
|
||||||
if (ARG(0).type == INT_TYPE) {
|
if (Nargs == 0) {
|
||||||
y = ARGV(0);
|
FromDSE(DSEToday, &y, &m, &d);
|
||||||
if (y < BASE) return E_2LOW;
|
} else {
|
||||||
else if (y > BASE+YR_RANGE) return E_2HIGH;
|
if (ARG(0).type == INT_TYPE) {
|
||||||
} else if (HASDATE(ARG(0))) {
|
y = ARGV(0);
|
||||||
FromDSE(DATEPART(ARG(0)), &y, &m, &d); /* We just want the year */
|
if (y < BASE) return E_2LOW;
|
||||||
} else return E_BAD_TYPE;
|
else if (y > BASE+YR_RANGE) return E_2HIGH;
|
||||||
|
} else if (HASDATE(ARG(0))) {
|
||||||
|
FromDSE(DATEPART(ARG(0)), &y, &m, &d); /* We just want the year */
|
||||||
|
} else return E_BAD_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
a = y % 4;
|
a = y % 4;
|
||||||
@@ -2492,7 +2501,7 @@ static int FTimezone(func_info *info)
|
|||||||
|
|
||||||
if (Nargs == 0) {
|
if (Nargs == 0) {
|
||||||
dse = DSEToday;
|
dse = DSEToday;
|
||||||
now = (SystemTime(0) / 60);
|
now = MinutesPastMidnight(0);
|
||||||
} else {
|
} else {
|
||||||
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
|
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
|
||||||
dse = DATEPART(ARG(0));
|
dse = DATEPART(ARG(0));
|
||||||
@@ -3512,6 +3521,57 @@ FEvalTrig(func_info *info)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
FMultiTrig(func_info *info)
|
||||||
|
{
|
||||||
|
Parser p;
|
||||||
|
Trigger trig;
|
||||||
|
TimeTrig tim;
|
||||||
|
int dse;
|
||||||
|
int r;
|
||||||
|
int i;
|
||||||
|
int earliest = -1;
|
||||||
|
|
||||||
|
RetVal.type = DATE_TYPE;
|
||||||
|
RETVAL = 0;
|
||||||
|
|
||||||
|
for (i=0; i<Nargs; i++) {
|
||||||
|
ASSERT_TYPE(i, STR_TYPE);
|
||||||
|
}
|
||||||
|
for (i=0; i<Nargs; i++) {
|
||||||
|
CreateParser(ARGSTR(i), &p);
|
||||||
|
p.allownested = 0;
|
||||||
|
r = ParseRem(&p, &trig, &tim, 0);
|
||||||
|
if (r) {
|
||||||
|
DestroyParser(&p);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
if (trig.typ != NO_TYPE) {
|
||||||
|
DestroyParser(&p);
|
||||||
|
FreeTrig(&trig);
|
||||||
|
return E_PARSE_ERR;
|
||||||
|
}
|
||||||
|
if (tim.ttime != NO_TIME) {
|
||||||
|
Eprint("Cannot use AT clause in multitrig() function");
|
||||||
|
return E_PARSE_ERR;
|
||||||
|
}
|
||||||
|
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
|
||||||
|
DestroyParser(&p);
|
||||||
|
|
||||||
|
if (r != E_CANT_TRIG) {
|
||||||
|
if (dse < earliest || earliest < 0) {
|
||||||
|
earliest = dse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeTrig(&trig);
|
||||||
|
}
|
||||||
|
if (earliest >= 0) {
|
||||||
|
RETVAL = earliest;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int LastTrig = 0;
|
static int LastTrig = 0;
|
||||||
static int
|
static int
|
||||||
FTrig(func_info *info)
|
FTrig(func_info *info)
|
||||||
@@ -3549,20 +3609,18 @@ FTrig(func_info *info)
|
|||||||
return E_PARSE_ERR;
|
return E_PARSE_ERR;
|
||||||
}
|
}
|
||||||
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
|
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
|
||||||
|
DestroyParser(&p);
|
||||||
|
|
||||||
if (r == E_CANT_TRIG) {
|
if (r == E_CANT_TRIG) {
|
||||||
DestroyParser(&p);
|
|
||||||
FreeTrig(&trig);
|
FreeTrig(&trig);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ShouldTriggerReminder(&trig, &tim, dse, &r)) {
|
if (ShouldTriggerReminder(&trig, &tim, dse, &r)) {
|
||||||
LastTrig = dse;
|
LastTrig = dse;
|
||||||
RETVAL = dse;
|
RETVAL = dse;
|
||||||
DestroyParser(&p);
|
|
||||||
FreeTrig(&trig);
|
FreeTrig(&trig);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
DestroyParser(&p);
|
|
||||||
FreeTrig(&trig);
|
FreeTrig(&trig);
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
@@ -3574,6 +3632,8 @@ rows_or_cols(func_info *info, int want_rows)
|
|||||||
struct winsize w;
|
struct winsize w;
|
||||||
int fd = STDOUT_FILENO;
|
int fd = STDOUT_FILENO;
|
||||||
|
|
||||||
|
int opened = 0;
|
||||||
|
|
||||||
RetVal.type = INT_TYPE;
|
RetVal.type = INT_TYPE;
|
||||||
if (!isatty(fd)) {
|
if (!isatty(fd)) {
|
||||||
fd = open("/dev/tty", O_RDONLY);
|
fd = open("/dev/tty", O_RDONLY);
|
||||||
@@ -3581,6 +3641,7 @@ rows_or_cols(func_info *info, int want_rows)
|
|||||||
RETVAL = -1;
|
RETVAL = -1;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
opened = 1;
|
||||||
}
|
}
|
||||||
if (ioctl(fd, TIOCGWINSZ, &w) == 0) {
|
if (ioctl(fd, TIOCGWINSZ, &w) == 0) {
|
||||||
if (want_rows) RETVAL = w.ws_row;
|
if (want_rows) RETVAL = w.ws_row;
|
||||||
@@ -3588,7 +3649,7 @@ rows_or_cols(func_info *info, int want_rows)
|
|||||||
} else {
|
} else {
|
||||||
RETVAL = -1;
|
RETVAL = -1;
|
||||||
}
|
}
|
||||||
if (fd != STDOUT_FILENO) {
|
if (opened) {
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
@@ -3672,11 +3733,8 @@ mean_december_solstice(double y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Cosine of an angle specified in degrees */
|
/* Cosine of an angle specified in degrees */
|
||||||
static double
|
#define PI_BY_180 0.01745329251994329576923690768
|
||||||
cosd(double degrees)
|
#define cosd(theta) cos( (theta) * PI_BY_180)
|
||||||
{
|
|
||||||
return cos((degrees / 180.0) * 3.14159265358979);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Astronomical Algorithms by Meeus, p. 179
|
/* Astronomical Algorithms by Meeus, p. 179
|
||||||
These weird periodic components refine the mean solstice/equinox dates
|
These weird periodic components refine the mean solstice/equinox dates
|
||||||
@@ -3757,7 +3815,7 @@ solstice_equinox_for_year(int y, int which)
|
|||||||
j -= 2447892.50000; /* This is the Julian date of midnight, 1 Jan 1990 UTC */
|
j -= 2447892.50000; /* This is the Julian date of midnight, 1 Jan 1990 UTC */
|
||||||
int dse = (int) j;
|
int dse = (int) j;
|
||||||
|
|
||||||
int min = floor((j - (double) dse) * MINUTES_PER_DAY);
|
int min = (int) floor((j - (double) dse) * MINUTES_PER_DAY);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Convert from UTC to local time */
|
/* Convert from UTC to local time */
|
||||||
@@ -3805,8 +3863,10 @@ FSoleq(func_info *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = solstice_equinox_for_year(y, which);
|
ret = solstice_equinox_for_year(y, which);
|
||||||
|
if (ret < 0) return E_MKTIME_PROBLEM;
|
||||||
if (dse != NO_DATE && (ret / MINUTES_PER_DAY) < dse) {
|
if (dse != NO_DATE && (ret / MINUTES_PER_DAY) < dse) {
|
||||||
ret = solstice_equinox_for_year(y+1, which);
|
ret = solstice_equinox_for_year(y+1, which);
|
||||||
|
if (ret < 0) return E_MKTIME_PROBLEM;
|
||||||
}
|
}
|
||||||
RetVal.type = DATETIME_TYPE;
|
RetVal.type = DATETIME_TYPE;
|
||||||
RETVAL = ret;
|
RETVAL = ret;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
/* globals.h and err.h */
|
/* globals.h and err.h */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ EXTERN FILE *ErrFp;
|
|||||||
#define IsLeapYear(y) (((y) % 4) ? 0 : ((!((y) % 100) && ((y) % 400)) ? 0 : 1 ))
|
#define IsLeapYear(y) (((y) % 4) ? 0 : ((!((y) % 100) && ((y) % 400)) ? 0 : 1 ))
|
||||||
#define DaysInMonth(m, y) ((m) != 1 ? MonthDays[m] : 28 + IsLeapYear(y))
|
#define DaysInMonth(m, y) ((m) != 1 ? MonthDays[m] : 28 + IsLeapYear(y))
|
||||||
|
|
||||||
#define DestroyValue(x) (void) (((x).type == STR_TYPE && (x).v.str) ? (free((x).v.str),(x).v.str = NULL,(x).type = ERR_TYPE) : 0)
|
#define DestroyValue(x) do { if ((x).type == STR_TYPE && (x).v.str) { free((x).v.str); (x).v.str = NULL; } (x).type = ERR_TYPE; } while (0)
|
||||||
|
|
||||||
EXTERN int DSEToday;
|
EXTERN int DSEToday;
|
||||||
EXTERN int RealToday;
|
EXTERN int RealToday;
|
||||||
@@ -50,6 +50,7 @@ EXTERN int LineNo;
|
|||||||
EXTERN int FreshLine;
|
EXTERN int FreshLine;
|
||||||
EXTERN uid_t TrustedUsers[MAX_TRUSTED_USERS];
|
EXTERN uid_t TrustedUsers[MAX_TRUSTED_USERS];
|
||||||
|
|
||||||
|
EXTERN INIT( int MaxLateMinutes, 0);
|
||||||
EXTERN INIT( int NumTrustedUsers, 0);
|
EXTERN INIT( int NumTrustedUsers, 0);
|
||||||
EXTERN INIT( char const *MsgCommand, NULL);
|
EXTERN INIT( char const *MsgCommand, NULL);
|
||||||
EXTERN INIT( char const *QueuedMsgCommand, NULL);
|
EXTERN INIT( char const *QueuedMsgCommand, NULL);
|
||||||
@@ -78,7 +79,7 @@ EXTERN INIT( int SortByDate, 0);
|
|||||||
EXTERN INIT( int SortByPrio, 0);
|
EXTERN INIT( int SortByPrio, 0);
|
||||||
EXTERN INIT( int UntimedBeforeTimed, 0);
|
EXTERN INIT( int UntimedBeforeTimed, 0);
|
||||||
EXTERN INIT( int DefaultPrio, NO_PRIORITY);
|
EXTERN INIT( int DefaultPrio, NO_PRIORITY);
|
||||||
EXTERN INIT( long SysTime, -1L);
|
EXTERN INIT( int SysTime, -1);
|
||||||
EXTERN INIT( int ParseUntriggered, 1);
|
EXTERN INIT( int ParseUntriggered, 1);
|
||||||
|
|
||||||
EXTERN char const *InitialFile;
|
EXTERN char const *InitialFile;
|
||||||
@@ -91,6 +92,7 @@ EXTERN INIT( int DontQueue, 0);
|
|||||||
EXTERN INIT( int NumQueued, 0);
|
EXTERN INIT( int NumQueued, 0);
|
||||||
EXTERN INIT( int DontIssueAts, 0);
|
EXTERN INIT( int DontIssueAts, 0);
|
||||||
EXTERN INIT( int Daemon, 0);
|
EXTERN INIT( int Daemon, 0);
|
||||||
|
EXTERN INIT( int DaemonJSON, 0);
|
||||||
EXTERN INIT( char DateSep, DATESEP);
|
EXTERN INIT( char DateSep, DATESEP);
|
||||||
EXTERN INIT( char TimeSep, TIMESEP);
|
EXTERN INIT( char TimeSep, TIMESEP);
|
||||||
EXTERN INIT( char DateTimeSep, DATETIMESEP);
|
EXTERN INIT( char DateTimeSep, DATETIMESEP);
|
||||||
@@ -101,7 +103,7 @@ EXTERN INIT( int SynthesizeTags, 0);
|
|||||||
EXTERN INIT( int ScFormat, SC_AMPM);
|
EXTERN INIT( int ScFormat, SC_AMPM);
|
||||||
EXTERN INIT( int MaxSatIter, 1000);
|
EXTERN INIT( int MaxSatIter, 1000);
|
||||||
EXTERN INIT( int MaxStringLen, MAX_STR_LEN);
|
EXTERN INIT( int MaxStringLen, MAX_STR_LEN);
|
||||||
EXTERN INIT( char *FileName, NULL);
|
EXTERN INIT( char *FileName, NULL);
|
||||||
EXTERN INIT( int UseStdin, 0);
|
EXTERN INIT( int UseStdin, 0);
|
||||||
EXTERN INIT( int PurgeMode, 0);
|
EXTERN INIT( int PurgeMode, 0);
|
||||||
EXTERN INIT( int PurgeIncludeDepth, 0);
|
EXTERN INIT( int PurgeIncludeDepth, 0);
|
||||||
@@ -156,6 +158,9 @@ EXTERN INIT( char *EndSentIg, "\"')]}>");
|
|||||||
EXTERN DynamicBuffer Banner;
|
EXTERN DynamicBuffer Banner;
|
||||||
EXTERN DynamicBuffer LineBuffer;
|
EXTERN DynamicBuffer LineBuffer;
|
||||||
EXTERN DynamicBuffer ExprBuf;
|
EXTERN DynamicBuffer ExprBuf;
|
||||||
|
|
||||||
|
extern int NumFullOmits, NumPartialOmits;
|
||||||
|
|
||||||
/* List of months */
|
/* List of months */
|
||||||
EXTERN char *EnglishMonthName[]
|
EXTERN char *EnglishMonthName[]
|
||||||
#ifdef MK_GLOBALS
|
#ifdef MK_GLOBALS
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* Support for the Hebrew calendar */
|
/* Support for the Hebrew calendar */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/* Derived from code written by Amos Shapir in 1978; revised */
|
/* Derived from code written by Amos Shapir in 1978; revised */
|
||||||
|
|||||||
203
src/init.c
203
src/init.c
@@ -7,7 +7,7 @@
|
|||||||
/* in normal mode. */
|
/* in normal mode. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -25,10 +25,11 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
#ifdef HAVE_INITGROUPS
|
#ifdef HAVE_INITGROUPS
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
@@ -40,6 +41,14 @@
|
|||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "err.h"
|
#include "err.h"
|
||||||
|
|
||||||
|
static int should_guess_terminal_background = 1;
|
||||||
|
|
||||||
|
static void guess_terminal_background(int *r, int *g, int *b);
|
||||||
|
static int tty_init(int fd);
|
||||||
|
static void tty_raw(int fd);
|
||||||
|
static void tty_reset(int fd);
|
||||||
|
|
||||||
|
static void ProcessLongOption(char const *arg);
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
*
|
*
|
||||||
* Command line options recognized:
|
* Command line options recognized:
|
||||||
@@ -69,6 +78,7 @@
|
|||||||
* t = Display trigger dates
|
* t = Display trigger dates
|
||||||
* v = Dump variables at end
|
* v = Dump variables at end
|
||||||
* l = Display entire line in error messages
|
* l = Display entire line in error messages
|
||||||
|
* s = Display expression-parsing stack usage before exit
|
||||||
* -e = Send messages normally sent to stderr to stdout instead
|
* -e = Send messages normally sent to stderr to stdout instead
|
||||||
* -z[n] = Daemon mode waking up every n (def 1) minutes.
|
* -z[n] = Daemon mode waking up every n (def 1) minutes.
|
||||||
* -bn = Time format for cal (0, 1, or 2)
|
* -bn = Time format for cal (0, 1, or 2)
|
||||||
@@ -219,7 +229,7 @@ void InitRemind(int argc, char const *argv[])
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Invoked with a NULL argv[0]; bailing because that's just plain bizarre.\n");
|
fprintf(stderr, "Invoked with a NULL argv[0]; bailing because that's just plain bizarre.\n");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse the command-line options */
|
/* Parse the command-line options */
|
||||||
@@ -243,6 +253,11 @@ void InitRemind(int argc, char const *argv[])
|
|||||||
while(*arg) arg++;
|
while(*arg) arg++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '-':
|
||||||
|
ProcessLongOption(arg);
|
||||||
|
while(*arg) arg++;
|
||||||
|
break;
|
||||||
|
|
||||||
case '@':
|
case '@':
|
||||||
UseVTColors = 1;
|
UseVTColors = 1;
|
||||||
if (*arg) {
|
if (*arg) {
|
||||||
@@ -259,16 +274,24 @@ void InitRemind(int argc, char const *argv[])
|
|||||||
if (*arg == ',') {
|
if (*arg == ',') {
|
||||||
arg++;
|
arg++;
|
||||||
if (*arg != ',') {
|
if (*arg != ',') {
|
||||||
PARSENUM(x, arg);
|
if (*arg == 't') {
|
||||||
if (x == 0) {
|
arg++;
|
||||||
TerminalBackground = TERMINAL_BACKGROUND_DARK;
|
should_guess_terminal_background = 2;
|
||||||
} else if (x == 1) {
|
|
||||||
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
|
|
||||||
} else if (x == 2) {
|
|
||||||
TerminalBackground = TERMINAL_BACKGROUND_UNKNOWN;
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(ErrFp, "%s: -@n,m,b: m must be 0, 1 or 2 (assuming 2)\n",
|
PARSENUM(x, arg);
|
||||||
argv[0]);
|
if (x == 0) {
|
||||||
|
should_guess_terminal_background = 0;
|
||||||
|
TerminalBackground = TERMINAL_BACKGROUND_DARK;
|
||||||
|
} else if (x == 1) {
|
||||||
|
should_guess_terminal_background = 0;
|
||||||
|
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
|
||||||
|
} else if (x == 2) {
|
||||||
|
should_guess_terminal_background = 0;
|
||||||
|
TerminalBackground = TERMINAL_BACKGROUND_UNKNOWN;
|
||||||
|
} else {
|
||||||
|
fprintf(ErrFp, "%s: -@n,m,b: m must be t, 0, 1 or 2 (assuming 2)\n",
|
||||||
|
argv[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -403,7 +426,11 @@ void InitRemind(int argc, char const *argv[])
|
|||||||
case 'z':
|
case 'z':
|
||||||
case 'Z':
|
case 'Z':
|
||||||
DontFork = 1;
|
DontFork = 1;
|
||||||
if (*arg == '0') {
|
if (*arg == 'j' || *arg == 'J') {
|
||||||
|
while (*arg) arg++;
|
||||||
|
Daemon = -1;
|
||||||
|
DaemonJSON = 1;
|
||||||
|
} else if (*arg == '0') {
|
||||||
PARSENUM(Daemon, arg);
|
PARSENUM(Daemon, arg);
|
||||||
if (Daemon == 0) Daemon = -1;
|
if (Daemon == 0) Daemon = -1;
|
||||||
else if (Daemon < 1) Daemon = 1;
|
else if (Daemon < 1) Daemon = 1;
|
||||||
@@ -537,7 +564,7 @@ void InitRemind(int argc, char const *argv[])
|
|||||||
arg++;
|
arg++;
|
||||||
/* -wt means get width from /dev/tty */
|
/* -wt means get width from /dev/tty */
|
||||||
ttyfd = open("/dev/tty", O_RDONLY);
|
ttyfd = open("/dev/tty", O_RDONLY);
|
||||||
if (!ttyfd) {
|
if (ttyfd < 0) {
|
||||||
fprintf(stderr, "%s: `-wt': Cannot open /dev/tty: %s\n",
|
fprintf(stderr, "%s: `-wt': Cannot open /dev/tty: %s\n",
|
||||||
argv[0], strerror(errno));
|
argv[0], strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
@@ -548,7 +575,12 @@ void InitRemind(int argc, char const *argv[])
|
|||||||
PARSENUM(CalWidth, arg);
|
PARSENUM(CalWidth, arg);
|
||||||
if (CalWidth != 0 && CalWidth < 71) CalWidth = 71;
|
if (CalWidth != 0 && CalWidth < 71) CalWidth = 71;
|
||||||
if (CalWidth == 0) {
|
if (CalWidth == 0) {
|
||||||
CalWidth = -1;
|
/* Cal width of 0 means obtain from stdout */
|
||||||
|
if (isatty(STDOUT_FILENO)) {
|
||||||
|
InitCalWidthAndFormWidth(STDOUT_FILENO);
|
||||||
|
} else {
|
||||||
|
CalWidth = 80;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FormWidth = CalWidth - 8;
|
FormWidth = CalWidth - 8;
|
||||||
if (FormWidth < 20) FormWidth = 20;
|
if (FormWidth < 20) FormWidth = 20;
|
||||||
@@ -573,6 +605,7 @@ void InitRemind(int argc, char const *argv[])
|
|||||||
case 'D':
|
case 'D':
|
||||||
while (*arg) {
|
while (*arg) {
|
||||||
switch(*arg++) {
|
switch(*arg++) {
|
||||||
|
case 's': case 'S': DebugFlag |= DB_EXPR_STACKS; break;
|
||||||
case 'e': case 'E': DebugFlag |= DB_ECHO_LINE; break;
|
case 'e': case 'E': DebugFlag |= DB_ECHO_LINE; break;
|
||||||
case 'x': case 'X': DebugFlag |= DB_PRTEXPR; break;
|
case 'x': case 'X': DebugFlag |= DB_PRTEXPR; break;
|
||||||
case 't': case 'T': DebugFlag |= DB_PRTTRIG; break;
|
case 't': case 'T': DebugFlag |= DB_PRTTRIG; break;
|
||||||
@@ -726,7 +759,7 @@ void InitRemind(int argc, char const *argv[])
|
|||||||
|
|
||||||
/* Figure out the offset from UTC */
|
/* Figure out the offset from UTC */
|
||||||
if (CalculateUTC)
|
if (CalculateUTC)
|
||||||
(void) CalcMinsFromUTC(DSEToday, SystemTime(0)/60,
|
(void) CalcMinsFromUTC(DSEToday, MinutesPastMidnight(0),
|
||||||
&MinsFromUTC, NULL);
|
&MinsFromUTC, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -740,7 +773,7 @@ void InitRemind(int argc, char const *argv[])
|
|||||||
#ifndef L_USAGE_OVERRIDE
|
#ifndef L_USAGE_OVERRIDE
|
||||||
void Usage(void)
|
void Usage(void)
|
||||||
{
|
{
|
||||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2023 Dianne Skoll\n", VERSION, L_LANGNAME);
|
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||||
#ifdef BETA
|
#ifdef BETA
|
||||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -958,3 +991,139 @@ AddTrustedUser(char const *username)
|
|||||||
NumTrustedUsers++;
|
NumTrustedUsers++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ProcessLongOption(char const *arg)
|
||||||
|
{
|
||||||
|
if (!strcmp(arg, "version")) {
|
||||||
|
printf("%s\n", VERSION);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
fprintf(ErrFp, "%s: Unknown long option --%s\n", ArgV[0], arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
guess_terminal_background(int *r, int *g, int *b)
|
||||||
|
{
|
||||||
|
int ttyfd;
|
||||||
|
struct pollfd p;
|
||||||
|
unsigned int rr, gg, bb;
|
||||||
|
char buf[128];
|
||||||
|
int n;
|
||||||
|
|
||||||
|
*r = -1;
|
||||||
|
*g = -1;
|
||||||
|
*b = -1;
|
||||||
|
|
||||||
|
/* Don't guess if stdout not a terminal unless asked to by @,t */
|
||||||
|
if (should_guess_terminal_background != 2) {
|
||||||
|
if (!isatty(STDOUT_FILENO)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttyfd = open("/dev/tty", O_RDWR);
|
||||||
|
if (ttyfd < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isatty(ttyfd)) {
|
||||||
|
/* Not a TTY: Can't guess the color */
|
||||||
|
close(ttyfd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tty_init(ttyfd)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tty_raw(ttyfd);
|
||||||
|
n = write(ttyfd, "\033]11;?\033\\", 8);
|
||||||
|
|
||||||
|
if (n != 8) {
|
||||||
|
/* write failed... WTF? Not much we can do */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait up to 0.1s for terminal to respond */
|
||||||
|
p.fd = ttyfd;
|
||||||
|
p.events = POLLIN;
|
||||||
|
if (poll(&p, 1, 100) < 0) {
|
||||||
|
tty_reset(ttyfd);
|
||||||
|
close(ttyfd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!(p.revents & POLLIN)) {
|
||||||
|
tty_reset(ttyfd);
|
||||||
|
close(ttyfd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
n = read(ttyfd, buf, 127);
|
||||||
|
if (n <= 0) {
|
||||||
|
tty_reset(ttyfd);
|
||||||
|
close(ttyfd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tty_reset(ttyfd);
|
||||||
|
buf[n+1] = 0;
|
||||||
|
if (n < 25) {
|
||||||
|
/* Too short */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sscanf(buf+5, "rgb:%x/%x/%x", &rr, &gg, &bb) != 3) {
|
||||||
|
/* Couldn't scan color codes */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*r = (int) ((rr >> 8) & 255);
|
||||||
|
*g = (int) ((gg >> 8) & 255);
|
||||||
|
*b = (int) ((bb >> 8) & 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct termios orig_termios;
|
||||||
|
|
||||||
|
static int
|
||||||
|
tty_init(int fd)
|
||||||
|
{
|
||||||
|
if (tcgetattr(fd, &orig_termios) < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tty_raw(int fd)
|
||||||
|
{
|
||||||
|
struct termios raw;
|
||||||
|
|
||||||
|
raw = orig_termios;
|
||||||
|
|
||||||
|
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
|
||||||
|
raw.c_oflag &= ~(OPOST);
|
||||||
|
raw.c_cflag |= (CS8);
|
||||||
|
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
|
||||||
|
|
||||||
|
/* put terminal in raw mode after flushing */
|
||||||
|
tcsetattr(fd,TCSAFLUSH,&raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tty_reset(int fd)
|
||||||
|
{
|
||||||
|
tcsetattr(fd, TCSAFLUSH, &orig_termios);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
GetTerminalBackground(void)
|
||||||
|
{
|
||||||
|
int r, g, b;
|
||||||
|
if (should_guess_terminal_background) {
|
||||||
|
guess_terminal_background(&r, &g, &b);
|
||||||
|
if (r >= 0 && g >= 0 && b >= 0) {
|
||||||
|
if (r+g+b <= 85*3 && r <= 128 && g <= 128 && b <= 128) {
|
||||||
|
TerminalBackground = TERMINAL_BACKGROUND_DARK;
|
||||||
|
} else {
|
||||||
|
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
should_guess_terminal_background = 0;
|
||||||
|
}
|
||||||
|
return TerminalBackground;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* Header file for language support for various languages. */
|
/* Header file for language support for various languages. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* */
|
/* */
|
||||||
/* REMIND is Copyright (C) 1992-2023 by Dianne Skoll */
|
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* This file is Copyright (C) 1993 by Mogens Lynnerup. */
|
/* This file is Copyright (C) 1993 by Mogens Lynnerup. */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
/* Further corrections by Erik-Jan Vens */
|
/* Further corrections by Erik-Jan Vens */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* Support for the English language. */
|
/* Support for the English language. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* This file is Copyright (C) 1993-1998 by Mikko Silvonen. */
|
/* This file is Copyright (C) 1993-1998 by Mikko Silvonen. */
|
||||||
/* REMIND is Copyright (C) 1992-2023 by Dianne Skoll */
|
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -245,7 +245,8 @@ EXTERN char *ErrMsg[] =
|
|||||||
"No files matching *.rem",
|
"No files matching *.rem",
|
||||||
"String too long",
|
"String too long",
|
||||||
"Time specified twice",
|
"Time specified twice",
|
||||||
"Cannot specify DURATION without specifying AT"
|
"Cannot specify DURATION without specifying AT".
|
||||||
|
"Odotettu viikonpäivän nimi"
|
||||||
};
|
};
|
||||||
#endif /* MK_GLOBALS */
|
#endif /* MK_GLOBALS */
|
||||||
|
|
||||||
@@ -254,7 +255,7 @@ EXTERN char *ErrMsg[] =
|
|||||||
#define L_USAGE_OVERRIDE 1
|
#define L_USAGE_OVERRIDE 1
|
||||||
void Usage(void)
|
void Usage(void)
|
||||||
{
|
{
|
||||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2023 Dianne Skoll\n", VERSION, L_LANGNAME);
|
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||||
#ifdef BETA
|
#ifdef BETA
|
||||||
fprintf(ErrFp, ">>>> BETAVERSIO <<<<\n");
|
fprintf(ErrFp, ">>>> BETAVERSIO <<<<\n");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* */
|
/* */
|
||||||
/* REMIND is Copyright (C) 1992-2023 by Dianne Skoll */
|
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* This file is Copyright (C) 1993 by Laurent Duperval and */
|
/* This file is Copyright (C) 1993 by Laurent Duperval and */
|
||||||
/* Dianne Skoll. */
|
/* Dianne Skoll. */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
@@ -219,7 +219,8 @@ EXTERN char *ErrMsg[] =
|
|||||||
"No files matching *.rem",
|
"No files matching *.rem",
|
||||||
"String too long",
|
"String too long",
|
||||||
"Time specified twice",
|
"Time specified twice",
|
||||||
"Cannot specify DURATION without specifying AT"
|
"Cannot specify DURATION without specifying AT",
|
||||||
|
"Nom du jour de la semaine attendu",
|
||||||
};
|
};
|
||||||
#endif /* MK_GLOBALS */
|
#endif /* MK_GLOBALS */
|
||||||
|
|
||||||
@@ -228,7 +229,7 @@ EXTERN char *ErrMsg[] =
|
|||||||
#define L_USAGE_OVERRIDE 1
|
#define L_USAGE_OVERRIDE 1
|
||||||
void Usage(void)
|
void Usage(void)
|
||||||
{
|
{
|
||||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2023 Dianne Skoll\n", VERSION, L_LANGNAME);
|
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||||
#ifdef BETA
|
#ifdef BETA
|
||||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
/* I don't speak German. */
|
/* I don't speak German. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* Support for the Icelandic language. */
|
/* Support for the Icelandic language. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
|
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* It is Copyright (C) 1996 by Valerio Aimale */
|
/* It is Copyright (C) 1996 by Valerio Aimale */
|
||||||
/* */
|
/* */
|
||||||
/* Remind is copyright (C) 1992-2023 by Dianne Skoll */
|
/* Remind is copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* This file is Copyright (C) 1993 by Trygve Randen. */
|
/* This file is Copyright (C) 1993 by Trygve Randen. */
|
||||||
/* Remind is Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Remind is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
/* Polish. */
|
/* Polish. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -235,7 +235,8 @@ EXTERN char *ErrMsg[] =
|
|||||||
"No files matching *.rem",
|
"No files matching *.rem",
|
||||||
"String too long",
|
"String too long",
|
||||||
"Time specified twice",
|
"Time specified twice",
|
||||||
"Cannot specify DURATION without specifying AT"
|
"Cannot specify DURATION without specifying AT",
|
||||||
|
"Oczekiwana nazwa dnia tygodnia"
|
||||||
};
|
};
|
||||||
#endif /* MK_GLOBALS */
|
#endif /* MK_GLOBALS */
|
||||||
|
|
||||||
@@ -244,7 +245,7 @@ EXTERN char *ErrMsg[] =
|
|||||||
#define L_USAGE_OVERRIDE 1
|
#define L_USAGE_OVERRIDE 1
|
||||||
void Usage(void)
|
void Usage(void)
|
||||||
{
|
{
|
||||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2023 Dianne Skoll\n", VERSION, L_LANGNAME);
|
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||||
#ifdef BETA
|
#ifdef BETA
|
||||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* */
|
/* */
|
||||||
/* REMIND is Copyright (C) 1992-2023 by Dianne Skoll */
|
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* This file is Copyright (C) 1996 by Marco Paganini and */
|
/* This file is Copyright (C) 1996 by Marco Paganini and */
|
||||||
/* Dianne Skoll. */
|
/* Dianne Skoll. */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
@@ -244,7 +244,8 @@ EXTERN char *ErrMsg[] =
|
|||||||
"No files matching *.rem",
|
"No files matching *.rem",
|
||||||
"String too long",
|
"String too long",
|
||||||
"Time specified twice",
|
"Time specified twice",
|
||||||
"Cannot specify DURATION without specifying AT"
|
"Cannot specify DURATION without specifying AT",
|
||||||
|
"Esperando nome do dia da semana",
|
||||||
};
|
};
|
||||||
#endif /* MK_GLOBALS */
|
#endif /* MK_GLOBALS */
|
||||||
|
|
||||||
@@ -253,7 +254,7 @@ EXTERN char *ErrMsg[] =
|
|||||||
#define L_USAGE_OVERRIDE 1
|
#define L_USAGE_OVERRIDE 1
|
||||||
void Usage(void)
|
void Usage(void)
|
||||||
{
|
{
|
||||||
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2023 Dianne Skoll\n", VERSION, L_LANGNAME);
|
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||||
#ifdef BETA
|
#ifdef BETA
|
||||||
fprintf(ErrFp, ">>>> VERSAO BETA <<<<\n");
|
fprintf(ErrFp, ">>>> VERSAO BETA <<<<\n");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* */
|
/* */
|
||||||
/* REMIND is Copyright (C) 1992-2023 by Dianne Skoll */
|
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* This file is Copyright (C) 1996-1998 by Liviu Daia */
|
/* This file is Copyright (C) 1996-1998 by Liviu Daia */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* Author: Rafa Couto <rafacouto@biogate.com> */
|
/* Author: Rafa Couto <rafacouto@biogate.com> */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
157
src/main.c
157
src/main.c
@@ -6,7 +6,7 @@
|
|||||||
/* routines, etc. */
|
/* routines, etc. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
#define _XOPEN_SOURCE 600
|
#define _XOPEN_SOURCE 600
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -45,6 +47,9 @@
|
|||||||
|
|
||||||
static void DoReminders(void);
|
static void DoReminders(void);
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
/** **/
|
/** **/
|
||||||
@@ -71,6 +76,8 @@ int main(int argc, char *argv[])
|
|||||||
DBufInit(&(LastTrigger.tags));
|
DBufInit(&(LastTrigger.tags));
|
||||||
ClearLastTriggers();
|
ClearLastTriggers();
|
||||||
|
|
||||||
|
atexit(DebugExitFunc);
|
||||||
|
|
||||||
if (DoCalendar || (DoSimpleCalendar && (!NextMode || PsCal))) {
|
if (DoCalendar || (DoSimpleCalendar && (!NextMode || PsCal))) {
|
||||||
ProduceCalendar();
|
ProduceCalendar();
|
||||||
return 0;
|
return 0;
|
||||||
@@ -181,14 +188,14 @@ static void DoReminders(void)
|
|||||||
|
|
||||||
if (FileAccessDate < 0) {
|
if (FileAccessDate < 0) {
|
||||||
fprintf(ErrFp, "%s: `%s': %s.\n", ErrMsg[E_CANTACCESS], InitialFile, strerror(errno));
|
fprintf(ErrFp, "%s: `%s': %s.\n", ErrMsg[E_CANTACCESS], InitialFile, strerror(errno));
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
r=IncludeFile(InitialFile);
|
r=IncludeFile(InitialFile);
|
||||||
if (r) {
|
if (r) {
|
||||||
fprintf(ErrFp, "%s %s: %s\n", ErrMsg[E_ERR_READING],
|
fprintf(ErrFp, "%s %s: %s\n", ErrMsg[E_ERR_READING],
|
||||||
InitialFile, ErrMsg[r]);
|
InitialFile, ErrMsg[r]);
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
@@ -196,7 +203,7 @@ static void DoReminders(void)
|
|||||||
if (r == E_EOF) return;
|
if (r == E_EOF) return;
|
||||||
if (r) {
|
if (r) {
|
||||||
Eprint("%s: %s", ErrMsg[E_ERR_READING], ErrMsg[r]);
|
Eprint("%s: %s", ErrMsg[E_ERR_READING], ErrMsg[r]);
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
s = FindInitialToken(&tok, CurLine);
|
s = FindInitialToken(&tok, CurLine);
|
||||||
|
|
||||||
@@ -585,8 +592,8 @@ int EvaluateExpr(ParsePtr p, Value *v)
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (p->isnested) return E_PARSE_ERR; /* Can't nest expressions */
|
if (p->isnested) return E_PARSE_ERR; /* Can't nest expressions */
|
||||||
while (isempty(*p->pos)) (p->pos)++;
|
|
||||||
if (!p->pos) return E_PARSE_ERR; /* Missing expression */
|
if (!p->pos) return E_PARSE_ERR; /* Missing expression */
|
||||||
|
while (isempty(*p->pos)) (p->pos)++;
|
||||||
if (*p->pos == BEG_OF_EXPR) {
|
if (*p->pos == BEG_OF_EXPR) {
|
||||||
(p->pos)++;
|
(p->pos)++;
|
||||||
bracketed = 1;
|
bracketed = 1;
|
||||||
@@ -747,19 +754,32 @@ int PushToken(char const *tok, ParsePtr p)
|
|||||||
/* Return the system time in seconds past midnight */
|
/* Return the system time in seconds past midnight */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
long SystemTime(int realtime)
|
int SystemTime(int realtime)
|
||||||
{
|
{
|
||||||
time_t tloc;
|
time_t now;
|
||||||
struct tm *t;
|
struct tm *t;
|
||||||
|
|
||||||
if (!realtime && (SysTime != -1L)) return SysTime;
|
if (!realtime && (SysTime != -1)) return SysTime;
|
||||||
|
|
||||||
(void) time(&tloc);
|
now = time(NULL);
|
||||||
t = localtime(&tloc);
|
t = localtime(&now);
|
||||||
return (long) t->tm_hour * 3600L + (long) t->tm_min * 60L +
|
return t->tm_hour * 3600L + t->tm_min * 60L +
|
||||||
(long) t->tm_sec;
|
t->tm_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************/
|
||||||
|
/* */
|
||||||
|
/* MinutesPastMidnight */
|
||||||
|
/* */
|
||||||
|
/* Return the system time in minutes past midnight */
|
||||||
|
/* */
|
||||||
|
/***************************************************************/
|
||||||
|
int MinutesPastMidnight(int realtime)
|
||||||
|
{
|
||||||
|
return (SystemTime(realtime) / 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* SystemDate */
|
/* SystemDate */
|
||||||
@@ -771,11 +791,11 @@ long SystemTime(int realtime)
|
|||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
int SystemDate(int *y, int *m, int *d)
|
int SystemDate(int *y, int *m, int *d)
|
||||||
{
|
{
|
||||||
time_t tloc;
|
time_t now;
|
||||||
struct tm *t;
|
struct tm *t;
|
||||||
|
|
||||||
(void) time(&tloc);
|
now = time(NULL);
|
||||||
t = localtime(&tloc);
|
t = localtime(&now);
|
||||||
|
|
||||||
*d = t->tm_mday;
|
*d = t->tm_mday;
|
||||||
*m = t->tm_mon;
|
*m = t->tm_mon;
|
||||||
@@ -998,6 +1018,12 @@ int DoDebug(ParsePtr p)
|
|||||||
else DebugFlag &= ~DB_ECHO_LINE;
|
else DebugFlag &= ~DB_ECHO_LINE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
if (val) DebugFlag |= DB_EXPR_STACKS;
|
||||||
|
else DebugFlag &= ~DB_EXPR_STACKS;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
if (val) DebugFlag |= DB_PRTEXPR;
|
if (val) DebugFlag |= DB_PRTEXPR;
|
||||||
@@ -1238,19 +1264,19 @@ int CalcMinsFromUTC(int dse, int tim, int *mins, int *isdst)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char const *OutputEscapeSequences(char const *s, int print)
|
static char const *OutputEscapeSequences(char const *s, int print, DynamicBuffer *output)
|
||||||
{
|
{
|
||||||
while (*s == 0x1B && *(s+1) == '[') {
|
while (*s == 0x1B && *(s+1) == '[') {
|
||||||
if (print) putchar(*s);
|
if (print) OUTPUT(*s);
|
||||||
s++;
|
s++;
|
||||||
if (print) putchar(*s);
|
if (print) OUTPUT(*s);
|
||||||
s++;
|
s++;
|
||||||
while (*s && (*s < 0x40 || *s > 0x7E)) {
|
while (*s && (*s < 0x40 || *s > 0x7E)) {
|
||||||
if (print) putchar(*s);
|
if (print) OUTPUT(*s);
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
if (*s) {
|
if (*s) {
|
||||||
if (print) putchar(*s);
|
if (print) OUTPUT(*s);
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1259,19 +1285,19 @@ static char const *OutputEscapeSequences(char const *s, int print)
|
|||||||
|
|
||||||
#ifdef REM_USE_WCHAR
|
#ifdef REM_USE_WCHAR
|
||||||
#define ISWBLANK(c) (iswspace(c) && (c) != '\n')
|
#define ISWBLANK(c) (iswspace(c) && (c) != '\n')
|
||||||
static wchar_t const *OutputEscapeSequencesWS(wchar_t const *s, int print)
|
static wchar_t const *OutputEscapeSequencesWS(wchar_t const *s, int print, DynamicBuffer *output)
|
||||||
{
|
{
|
||||||
while (*s == 0x1B && *(s+1) == '[') {
|
while (*s == 0x1B && *(s+1) == '[') {
|
||||||
if (print) PutWideChar(*s);
|
if (print) PutWideChar(*s, output);
|
||||||
s++;
|
s++;
|
||||||
if (print) PutWideChar(*s);
|
if (print) PutWideChar(*s, output);
|
||||||
s++;
|
s++;
|
||||||
while (*s && (*s < 0x40 || *s > 0x7E)) {
|
while (*s && (*s < 0x40 || *s > 0x7E)) {
|
||||||
if (print) PutWideChar(*s);
|
if (print) PutWideChar(*s, output);
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
if (*s) {
|
if (*s) {
|
||||||
if (print) PutWideChar(*s);
|
if (print) PutWideChar(*s, output);
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1280,7 +1306,7 @@ static wchar_t const *OutputEscapeSequencesWS(wchar_t const *s, int print)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
FillParagraphWCAux(wchar_t const *s)
|
FillParagraphWCAux(wchar_t const *s, DynamicBuffer *output)
|
||||||
{
|
{
|
||||||
int line = 0;
|
int line = 0;
|
||||||
int i, j;
|
int i, j;
|
||||||
@@ -1295,7 +1321,7 @@ FillParagraphWCAux(wchar_t const *s)
|
|||||||
|
|
||||||
/* If it's a carriage return, output it and start new paragraph */
|
/* If it's a carriage return, output it and start new paragraph */
|
||||||
if (*s == '\n') {
|
if (*s == '\n') {
|
||||||
putchar('\n');
|
OUTPUT('\n');
|
||||||
s++;
|
s++;
|
||||||
line = 0;
|
line = 0;
|
||||||
while(ISWBLANK(*s)) s++;
|
while(ISWBLANK(*s)) s++;
|
||||||
@@ -1308,7 +1334,7 @@ FillParagraphWCAux(wchar_t const *s)
|
|||||||
number of spaces */
|
number of spaces */
|
||||||
j = line ? SubsIndent : FirstIndent;
|
j = line ? SubsIndent : FirstIndent;
|
||||||
for (i=0; i<j; i++) {
|
for (i=0; i<j; i++) {
|
||||||
putchar(' ');
|
OUTPUT(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the amount of room left on this line */
|
/* Calculate the amount of room left on this line */
|
||||||
@@ -1321,7 +1347,7 @@ FillParagraphWCAux(wchar_t const *s)
|
|||||||
if (*s == '\n') break;
|
if (*s == '\n') break;
|
||||||
while(1) {
|
while(1) {
|
||||||
t = s;
|
t = s;
|
||||||
s = OutputEscapeSequencesWS(s, 1);
|
s = OutputEscapeSequencesWS(s, 1, output);
|
||||||
if (s == t) break;
|
if (s == t) break;
|
||||||
while(ISWBLANK(*s)) s++;
|
while(ISWBLANK(*s)) s++;
|
||||||
}
|
}
|
||||||
@@ -1329,7 +1355,7 @@ FillParagraphWCAux(wchar_t const *s)
|
|||||||
len = 0;
|
len = 0;
|
||||||
while(*s && !iswspace(*s)) {
|
while(*s && !iswspace(*s)) {
|
||||||
if (*s == 0x1B && *(s+1) == '[') {
|
if (*s == 0x1B && *(s+1) == '[') {
|
||||||
s = OutputEscapeSequencesWS(s, 0);
|
s = OutputEscapeSequencesWS(s, 0, output);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
len += wcwidth(*s);
|
len += wcwidth(*s);
|
||||||
@@ -1340,17 +1366,17 @@ FillParagraphWCAux(wchar_t const *s)
|
|||||||
}
|
}
|
||||||
if (!pendspace || len+pendspace <= roomleft) {
|
if (!pendspace || len+pendspace <= roomleft) {
|
||||||
for (i=0; i<pendspace; i++) {
|
for (i=0; i<pendspace; i++) {
|
||||||
putchar(' ');
|
OUTPUT(' ');
|
||||||
}
|
}
|
||||||
while(t < s) {
|
while(t < s) {
|
||||||
PutWideChar(*t);
|
PutWideChar(*t, output);
|
||||||
if (strchr(EndSent, *t)) doublespace = 2;
|
if (strchr(EndSent, *t)) doublespace = 2;
|
||||||
else if (!strchr(EndSentIg, *t)) doublespace = 1;
|
else if (!strchr(EndSentIg, *t)) doublespace = 1;
|
||||||
t++;
|
t++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s = t;
|
s = t;
|
||||||
putchar('\n');
|
OUTPUT('\n');
|
||||||
line++;
|
line++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1361,7 +1387,7 @@ FillParagraphWCAux(wchar_t const *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
FillParagraphWC(char const *s)
|
FillParagraphWC(char const *s, DynamicBuffer *output)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
wchar_t *buf;
|
wchar_t *buf;
|
||||||
@@ -1371,7 +1397,7 @@ FillParagraphWC(char const *s)
|
|||||||
buf = calloc(len+1, sizeof(wchar_t));
|
buf = calloc(len+1, sizeof(wchar_t));
|
||||||
if (!buf) return E_NO_MEM;
|
if (!buf) return E_NO_MEM;
|
||||||
(void) mbstowcs(buf, s, len+1);
|
(void) mbstowcs(buf, s, len+1);
|
||||||
FillParagraphWCAux(buf);
|
FillParagraphWCAux(buf, output);
|
||||||
free(buf);
|
free(buf);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -1391,7 +1417,7 @@ FillParagraphWC(char const *s)
|
|||||||
/* A macro safe ONLY if used with arg with no side effects! */
|
/* A macro safe ONLY if used with arg with no side effects! */
|
||||||
#define ISBLANK(c) (isspace(c) && (c) != '\n')
|
#define ISBLANK(c) (isspace(c) && (c) != '\n')
|
||||||
|
|
||||||
void FillParagraph(char const *s)
|
void FillParagraph(char const *s, DynamicBuffer *output)
|
||||||
{
|
{
|
||||||
|
|
||||||
int line = 0;
|
int line = 0;
|
||||||
@@ -1409,7 +1435,7 @@ void FillParagraph(char const *s)
|
|||||||
if (!*s) return;
|
if (!*s) return;
|
||||||
|
|
||||||
#ifdef REM_USE_WCHAR
|
#ifdef REM_USE_WCHAR
|
||||||
if (FillParagraphWC(s) == OK) {
|
if (FillParagraphWC(s, output) == OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1419,7 +1445,7 @@ void FillParagraph(char const *s)
|
|||||||
|
|
||||||
/* If it's a carriage return, output it and start new paragraph */
|
/* If it's a carriage return, output it and start new paragraph */
|
||||||
if (*s == '\n') {
|
if (*s == '\n') {
|
||||||
putchar('\n');
|
OUTPUT('\n');
|
||||||
s++;
|
s++;
|
||||||
line = 0;
|
line = 0;
|
||||||
while(ISBLANK(*s)) s++;
|
while(ISBLANK(*s)) s++;
|
||||||
@@ -1432,7 +1458,7 @@ void FillParagraph(char const *s)
|
|||||||
number of spaces */
|
number of spaces */
|
||||||
j = line ? SubsIndent : FirstIndent;
|
j = line ? SubsIndent : FirstIndent;
|
||||||
for (i=0; i<j; i++) {
|
for (i=0; i<j; i++) {
|
||||||
putchar(' ');
|
OUTPUT(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the amount of room left on this line */
|
/* Calculate the amount of room left on this line */
|
||||||
@@ -1445,7 +1471,7 @@ void FillParagraph(char const *s)
|
|||||||
if (*s == '\n') break;
|
if (*s == '\n') break;
|
||||||
while(1) {
|
while(1) {
|
||||||
t = s;
|
t = s;
|
||||||
s = OutputEscapeSequences(s, 1);
|
s = OutputEscapeSequences(s, 1, output);
|
||||||
if (s == t) break;
|
if (s == t) break;
|
||||||
while(ISBLANK(*s)) s++;
|
while(ISBLANK(*s)) s++;
|
||||||
}
|
}
|
||||||
@@ -1453,7 +1479,7 @@ void FillParagraph(char const *s)
|
|||||||
len = 0;
|
len = 0;
|
||||||
while(*s && !isspace(*s)) {
|
while(*s && !isspace(*s)) {
|
||||||
if (*s == 0x1B && *(s+1) == '[') {
|
if (*s == 0x1B && *(s+1) == '[') {
|
||||||
s = OutputEscapeSequences(s, 0);
|
s = OutputEscapeSequences(s, 0, output);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
s++;
|
s++;
|
||||||
@@ -1464,17 +1490,17 @@ void FillParagraph(char const *s)
|
|||||||
}
|
}
|
||||||
if (!pendspace || len+pendspace <= roomleft) {
|
if (!pendspace || len+pendspace <= roomleft) {
|
||||||
for (i=0; i<pendspace; i++) {
|
for (i=0; i<pendspace; i++) {
|
||||||
putchar(' ');
|
OUTPUT(' ');
|
||||||
}
|
}
|
||||||
while(t < s) {
|
while(t < s) {
|
||||||
putchar(*t);
|
OUTPUT(*t);
|
||||||
if (strchr(EndSent, *t)) doublespace = 2;
|
if (strchr(EndSent, *t)) doublespace = 2;
|
||||||
else if (!strchr(EndSentIg, *t)) doublespace = 1;
|
else if (!strchr(EndSentIg, *t)) doublespace = 1;
|
||||||
t++;
|
t++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s = t;
|
s = t;
|
||||||
putchar('\n');
|
OUTPUT('\n');
|
||||||
line++;
|
line++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1638,12 +1664,51 @@ SaveLastTimeTrig(TimeTrig const *t)
|
|||||||
memcpy(&LastTimeTrig, t, sizeof(LastTimeTrig));
|
memcpy(&LastTimeTrig, t, sizeof(LastTimeTrig));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrapper to ignore warnings about ignoring return value of system() */
|
/* Wrapper to ignore warnings about ignoring return value of system()
|
||||||
|
Also redirects stdin and stdout to /dev/null for queued reminders */
|
||||||
|
|
||||||
void
|
void
|
||||||
System(char const *cmd)
|
System(char const *cmd, int is_queued)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
pid_t kid;
|
||||||
|
int fd;
|
||||||
|
int status;
|
||||||
|
int do_exit = 0;
|
||||||
|
if (is_queued && IsServerMode()) {
|
||||||
|
do_exit = 1;
|
||||||
|
/* Server mode... redirect stdin and stdout to /dev/null */
|
||||||
|
kid = fork();
|
||||||
|
if (kid == (pid_t) -1) {
|
||||||
|
/* Fork failed... nothing we can do */
|
||||||
|
return;
|
||||||
|
} else if (kid == 0) {
|
||||||
|
/* In the child */
|
||||||
|
(void) close(STDIN_FILENO);
|
||||||
|
(void) close(STDOUT_FILENO);
|
||||||
|
fd = open("/dev/null", O_RDONLY);
|
||||||
|
if (fd >= 0 && fd != STDIN_FILENO) {
|
||||||
|
dup2(fd, STDIN_FILENO);
|
||||||
|
close(STDIN_FILENO);
|
||||||
|
}
|
||||||
|
fd = open("/dev/null", O_WRONLY);
|
||||||
|
if (fd >= 0 && fd != STDOUT_FILENO) {
|
||||||
|
dup2(fd, STDOUT_FILENO);
|
||||||
|
close(STDOUT_FILENO);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* In the parent */
|
||||||
|
while (waitpid(kid, &status, 0) != kid) /* continue */ ;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* This is the child process or original if we never forked */
|
||||||
r = system(cmd);
|
r = system(cmd);
|
||||||
|
if (do_exit) {
|
||||||
|
/* In the child process, so exit! */
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* Calculations for figuring out moon phases. */
|
/* Calculations for figuring out moon phases. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -412,7 +412,7 @@ static double phase(double pdate,
|
|||||||
Day = pdate - epoch; /* Date within epoch */
|
Day = pdate - epoch; /* Date within epoch */
|
||||||
N = fixangle((360 / 365.2422) * Day); /* Mean anomaly of the Sun */
|
N = fixangle((360 / 365.2422) * Day); /* Mean anomaly of the Sun */
|
||||||
M = fixangle(N + elonge - elongp); /* Convert from perigee
|
M = fixangle(N + elonge - elongp); /* Convert from perigee
|
||||||
co-ordinates to epoch 1980.0 */
|
coordinates to epoch 1980.0 */
|
||||||
Ec = kepler(M, eccent); /* Solve equation of Kepler */
|
Ec = kepler(M, eccent); /* Solve equation of Kepler */
|
||||||
Ec = sqrt((1 + eccent) / (1 - eccent)) * tan(Ec / 2);
|
Ec = sqrt((1 + eccent) / (1 - eccent)) * tan(Ec / 2);
|
||||||
Ec = 2 * todeg(atan(Ec)); /* 1 anomaly */
|
Ec = 2 * todeg(atan(Ec)); /* 1 anomaly */
|
||||||
|
|||||||
11
src/omit.c
11
src/omit.c
@@ -6,7 +6,7 @@
|
|||||||
/* the data structures for OMITted dates. */
|
/* the data structures for OMITted dates. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
#include "err.h"
|
#include "err.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
|
|
||||||
static int BexistsIntArray (int array[], int num, int key);
|
static int BexistsIntArray (int const array[], int num, int key);
|
||||||
static void InsertIntoSortedArray (int *array, int num, int key);
|
static void InsertIntoSortedArray (int *array, int num, int key);
|
||||||
|
|
||||||
/* Arrays for the global omits */
|
/* Arrays for the global omits */
|
||||||
@@ -32,7 +32,7 @@ static int PartialOmitArray[MAX_PARTIAL_OMITS];
|
|||||||
/* WeekdayOmits is declared in global.h */
|
/* WeekdayOmits is declared in global.h */
|
||||||
|
|
||||||
/* How many of each omit types do we have? */
|
/* How many of each omit types do we have? */
|
||||||
static int NumFullOmits, NumPartialOmits;
|
int NumFullOmits, NumPartialOmits;
|
||||||
|
|
||||||
/* The structure for saving and restoring OMIT contexts */
|
/* The structure for saving and restoring OMIT contexts */
|
||||||
typedef struct omitcontext {
|
typedef struct omitcontext {
|
||||||
@@ -251,7 +251,7 @@ int IsOmitted(int dse, int localomit, char const *omitfunc, int *omit)
|
|||||||
/* element is found, 0 otherwise. */
|
/* element is found, 0 otherwise. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
static int BexistsIntArray(int array[], int num, int key)
|
static int BexistsIntArray(int const array[], int num, int key)
|
||||||
{
|
{
|
||||||
int top=num-1, bot=0, mid;
|
int top=num-1, bot=0, mid;
|
||||||
|
|
||||||
@@ -445,6 +445,9 @@ int DoOmit(ParsePtr p)
|
|||||||
if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
|
if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
|
||||||
InsertIntoSortedArray(PartialOmitArray, NumPartialOmits, syndrome);
|
InsertIntoSortedArray(PartialOmitArray, NumPartialOmits, syndrome);
|
||||||
NumPartialOmits++;
|
NumPartialOmits++;
|
||||||
|
if (NumPartialOmits == 366) {
|
||||||
|
Wprint("You have OMITted everything! The space-time continuum is at risk.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (mc == m[1] && dc == d[1]) {
|
if (mc == m[1] && dc == d[1]) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
27
src/protos.h
27
src/protos.h
@@ -5,7 +5,7 @@
|
|||||||
/* Function Prototypes. */
|
/* Function Prototypes. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -22,6 +22,9 @@
|
|||||||
/* Characters to ignore */
|
/* Characters to ignore */
|
||||||
#define isempty(c) (isspace(c) || ((c) == '\\'))
|
#define isempty(c) (isspace(c) || ((c) == '\\'))
|
||||||
|
|
||||||
|
#define IsServerMode() (Daemon < 0)
|
||||||
|
#define ShouldFork (!DontFork)
|
||||||
|
|
||||||
#include "dynbuf.h"
|
#include "dynbuf.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
@@ -35,7 +38,7 @@ int DoRem (ParsePtr p);
|
|||||||
int DoFlush (ParsePtr p);
|
int DoFlush (ParsePtr p);
|
||||||
void DoExit (ParsePtr p);
|
void DoExit (ParsePtr p);
|
||||||
int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals);
|
int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals);
|
||||||
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued);
|
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 ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int dse, int *err);
|
||||||
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode);
|
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode);
|
||||||
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int dse, int tim);
|
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int dse, int tim);
|
||||||
@@ -71,7 +74,8 @@ void OutputLine (FILE *fp);
|
|||||||
void CreateParser (char const *s, ParsePtr p);
|
void CreateParser (char const *s, ParsePtr p);
|
||||||
void DestroyParser (ParsePtr p);
|
void DestroyParser (ParsePtr p);
|
||||||
int PushToken (char const *tok, ParsePtr p);
|
int PushToken (char const *tok, ParsePtr p);
|
||||||
long SystemTime (int realtime);
|
int SystemTime (int realtime);
|
||||||
|
int MinutesPastMidnight (int realtime);
|
||||||
int SystemDate (int *y, int *m, int *d);
|
int SystemDate (int *y, int *m, int *d);
|
||||||
int DoIf (ParsePtr p);
|
int DoIf (ParsePtr p);
|
||||||
int DoElse (ParsePtr p);
|
int DoElse (ParsePtr p);
|
||||||
@@ -104,7 +108,7 @@ char *StrDup (char const *s);
|
|||||||
int StrCmpi (char const *s1, char const *s2);
|
int StrCmpi (char const *s1, char const *s2);
|
||||||
Var *FindVar (char const *str, int create);
|
Var *FindVar (char const *str, int create);
|
||||||
int DeleteVar (char const *str);
|
int DeleteVar (char const *str);
|
||||||
int SetVar (char const *str, Value *val);
|
int SetVar (char const *str, Value const *val);
|
||||||
int GetVarValue (char const *str, Value *val, Var *locals, ParsePtr p);
|
int GetVarValue (char const *str, Value *val, Var *locals, ParsePtr p);
|
||||||
int DoSet (Parser *p);
|
int DoSet (Parser *p);
|
||||||
int DoUnset (Parser *p);
|
int DoUnset (Parser *p);
|
||||||
@@ -114,7 +118,7 @@ void DestroyVars (int all);
|
|||||||
int PreserveVar (char const *name);
|
int PreserveVar (char const *name);
|
||||||
int DoPreserve (Parser *p);
|
int DoPreserve (Parser *p);
|
||||||
int DoSatRemind (Trigger *trig, TimeTrig *tt, ParsePtr p);
|
int DoSatRemind (Trigger *trig, TimeTrig *tt, ParsePtr p);
|
||||||
int DoMsgCommand (char const *cmd, char const *msg);
|
int DoMsgCommand (char const *cmd, char const *msg, int is_queued);
|
||||||
int ParseNonSpaceChar (ParsePtr p, int *err, int peek);
|
int ParseNonSpaceChar (ParsePtr p, int *err, int peek);
|
||||||
unsigned int HashVal (char const *str);
|
unsigned int HashVal (char const *str);
|
||||||
int DateOK (int y, int m, int d);
|
int DateOK (int y, int m, int d);
|
||||||
@@ -138,7 +142,7 @@ int GetSysVar (char const *name, Value *val);
|
|||||||
int SetSysVar (char const *name, Value *val);
|
int SetSysVar (char const *name, Value *val);
|
||||||
void DumpSysVarByName (char const *name);
|
void DumpSysVarByName (char const *name);
|
||||||
int CalcMinsFromUTC (int dse, int tim, int *mins, int *isdst);
|
int CalcMinsFromUTC (int dse, int tim, int *mins, int *isdst);
|
||||||
void FillParagraph (char const *s);
|
void FillParagraph (char const *s, DynamicBuffer *output);
|
||||||
void LocalToUTC (int locdate, int loctime, int *utcdate, int *utctime);
|
void LocalToUTC (int locdate, int loctime, int *utcdate, int *utctime);
|
||||||
void UTCToLocal (int utcdate, int utctime, int *locdate, int *loctime);
|
void UTCToLocal (int utcdate, int utctime, int *locdate, int *loctime);
|
||||||
int MoonPhase (int date, int time);
|
int MoonPhase (int date, int time);
|
||||||
@@ -164,23 +168,30 @@ void PrintJSONKeyPairString(char const *name, char const *val);
|
|||||||
void PrintJSONKeyPairDate(char const *name, int dse);
|
void PrintJSONKeyPairDate(char const *name, int dse);
|
||||||
void PrintJSONKeyPairDateTime(char const *name, int dt);
|
void PrintJSONKeyPairDateTime(char const *name, int dt);
|
||||||
void PrintJSONKeyPairTime(char const *name, int t);
|
void PrintJSONKeyPairTime(char const *name, int t);
|
||||||
void System(char const *cmd);
|
void System(char const *cmd, int queued);
|
||||||
int ShellEscape(char const *in, DynamicBuffer *out);
|
int ShellEscape(char const *in, DynamicBuffer *out);
|
||||||
int AddGlobalOmit(int dse);
|
int AddGlobalOmit(int dse);
|
||||||
void set_lat_and_long_from_components(void);
|
void set_lat_and_long_from_components(void);
|
||||||
void set_components_from_lat_and_long(void);
|
void set_components_from_lat_and_long(void);
|
||||||
|
|
||||||
|
void DebugExitFunc(void);
|
||||||
|
|
||||||
|
int GetTerminalBackground(void);
|
||||||
|
|
||||||
char const *get_day_name(int wkday);
|
char const *get_day_name(int wkday);
|
||||||
char const *get_month_name(int mon);
|
char const *get_month_name(int mon);
|
||||||
|
|
||||||
|
void set_cloexec(int fd);
|
||||||
int push_call(char const *filename, char const *func, int lineno);
|
int push_call(char const *filename, char const *func, int lineno);
|
||||||
void clear_callstack(void);
|
void clear_callstack(void);
|
||||||
int print_callstack(FILE *fp);
|
int print_callstack(FILE *fp);
|
||||||
void pop_call(void);
|
void pop_call(void);
|
||||||
void FixSpecialType(Trigger *trig);
|
void FixSpecialType(Trigger *trig);
|
||||||
|
void WriteJSONTrigger(Trigger const *t, int include_tags, int today);
|
||||||
|
void WriteJSONTimeTrigger(TimeTrig const *tt);
|
||||||
#ifdef REM_USE_WCHAR
|
#ifdef REM_USE_WCHAR
|
||||||
#define _XOPEN_SOURCE 600
|
#define _XOPEN_SOURCE 600
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
void PutWideChar(wchar_t const wc);
|
void PutWideChar(wchar_t const wc, DynamicBuffer *output);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
541
src/queue.c
541
src/queue.c
@@ -5,7 +5,7 @@
|
|||||||
/* Queue up reminders for subsequent execution. */
|
/* Queue up reminders for subsequent execution. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -24,16 +24,35 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "err.h"
|
#include "err.h"
|
||||||
#include "protos.h"
|
#include "protos.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
|
|
||||||
|
#undef USE_INOTIFY
|
||||||
|
#if defined(HAVE_SYS_INOTIFY_H) && defined(HAVE_INOTIFY_INIT1)
|
||||||
|
#define USE_INOTIFY 1
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
|
||||||
|
int watch_fd = -1;
|
||||||
|
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 */
|
/* List structure for holding queued reminders */
|
||||||
typedef struct queuedrem {
|
typedef struct queuedrem {
|
||||||
struct queuedrem *next;
|
struct queuedrem *next;
|
||||||
@@ -41,16 +60,18 @@ typedef struct queuedrem {
|
|||||||
int RunDisabled;
|
int RunDisabled;
|
||||||
int ntrig;
|
int ntrig;
|
||||||
char const *text;
|
char const *text;
|
||||||
|
char const *fname;
|
||||||
|
int lineno;
|
||||||
char passthru[PASSTHRU_LEN+1];
|
char passthru[PASSTHRU_LEN+1];
|
||||||
char sched[VAR_NAME_LEN+1];
|
char sched[VAR_NAME_LEN+1];
|
||||||
DynamicBuffer tags;
|
|
||||||
Trigger t;
|
Trigger t;
|
||||||
TimeTrig tt;
|
TimeTrig tt;
|
||||||
} QueuedRem;
|
} QueuedRem;
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
|
|
||||||
static QueuedRem *QueueHead;
|
static QueuedRem *QueueHead = NULL;
|
||||||
|
static QueuedFilename *Files = NULL;
|
||||||
static time_t FileModTime;
|
static time_t FileModTime;
|
||||||
static struct stat StatBuf;
|
static struct stat StatBuf;
|
||||||
|
|
||||||
@@ -61,6 +82,105 @@ static int CalculateNextTimeUsingSched (QueuedRem *q);
|
|||||||
static void DaemonWait (struct timeval *sleep_tv);
|
static void DaemonWait (struct timeval *sleep_tv);
|
||||||
static void reread (void);
|
static void reread (void);
|
||||||
static void PrintQueue(void);
|
static void PrintQueue(void);
|
||||||
|
static char const *QueueFilename(char const *fname);
|
||||||
|
|
||||||
|
static void chomp(DynamicBuffer *buf)
|
||||||
|
{
|
||||||
|
char *s = DBufValue(buf);
|
||||||
|
int l = DBufLen(buf);
|
||||||
|
while (l) {
|
||||||
|
if (s[l-1] == '\n') {
|
||||||
|
s[l-1] = 0;
|
||||||
|
DBufLen(buf)--;
|
||||||
|
l--;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char const *SimpleTimeNoSpace(int tim)
|
||||||
|
{
|
||||||
|
char *s = (char *) SimpleTime(tim);
|
||||||
|
if (s && *s) {
|
||||||
|
size_t l = strlen(s);
|
||||||
|
if (l > 0 && s[l-1] == ' ') {
|
||||||
|
s[l-1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
QueuedRem *q = QueueHead;
|
||||||
|
QueuedRem *next;
|
||||||
|
if (!q) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (q == qid) {
|
||||||
|
QueueHead = q->next;
|
||||||
|
if (q->text) free((void *) q->text);
|
||||||
|
free(q);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while(q->next) {
|
||||||
|
next = q->next;
|
||||||
|
if (q->next == qid) {
|
||||||
|
q->next = q->next->next;
|
||||||
|
if (next->text) free((void *) next->text);
|
||||||
|
free(next);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
q = q->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void del_reminder_ul(unsigned long qid) {
|
||||||
|
del_reminder((QueuedRem *) qid);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
/* */
|
/* */
|
||||||
@@ -71,7 +191,7 @@ static void PrintQueue(void);
|
|||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
int QueueReminder(ParsePtr p, Trigger *trig,
|
int QueueReminder(ParsePtr p, Trigger *trig,
|
||||||
TimeTrig *tim, char const *sched)
|
TimeTrig *tim, char const *sched)
|
||||||
{
|
{
|
||||||
QueuedRem *qelem;
|
QueuedRem *qelem;
|
||||||
|
|
||||||
@@ -79,7 +199,7 @@ int QueueReminder(ParsePtr p, Trigger *trig,
|
|||||||
trig->noqueue ||
|
trig->noqueue ||
|
||||||
tim->ttime == NO_TIME ||
|
tim->ttime == NO_TIME ||
|
||||||
trig->typ == CAL_TYPE ||
|
trig->typ == CAL_TYPE ||
|
||||||
tim->ttime < SystemTime(0) / 60 ||
|
tim->ttime < MinutesPastMidnight(0) ||
|
||||||
((trig->typ == RUN_TYPE) && RunDisabled)) return OK;
|
((trig->typ == RUN_TYPE) && RunDisabled)) return OK;
|
||||||
|
|
||||||
qelem = NEW(QueuedRem);
|
qelem = NEW(QueuedRem);
|
||||||
@@ -91,25 +211,84 @@ int QueueReminder(ParsePtr p, Trigger *trig,
|
|||||||
free(qelem);
|
free(qelem);
|
||||||
return E_NO_MEM;
|
return E_NO_MEM;
|
||||||
}
|
}
|
||||||
|
qelem->fname = QueueFilename(FileName);
|
||||||
|
if (!qelem->fname) {
|
||||||
|
free((void *) qelem->text);
|
||||||
|
free(qelem);
|
||||||
|
return E_NO_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
qelem->lineno = LineNo;
|
||||||
NumQueued++;
|
NumQueued++;
|
||||||
qelem->typ = trig->typ;
|
qelem->typ = trig->typ;
|
||||||
strcpy(qelem->passthru, trig->passthru);
|
strcpy(qelem->passthru, trig->passthru);
|
||||||
qelem->tt = *tim;
|
qelem->tt = *tim;
|
||||||
qelem->t = *trig;
|
qelem->t = *trig;
|
||||||
DBufInit(&(qelem->t.tags));
|
DBufInit(&(qelem->t.tags));
|
||||||
|
DBufPuts(&(qelem->t.tags), DBufValue(&(trig->tags)));
|
||||||
|
if (SynthesizeTags) {
|
||||||
|
AppendTag(&(qelem->t.tags), SynthesizeTag());
|
||||||
|
}
|
||||||
qelem->next = QueueHead;
|
qelem->next = QueueHead;
|
||||||
qelem->RunDisabled = RunDisabled;
|
qelem->RunDisabled = RunDisabled;
|
||||||
qelem->ntrig = 0;
|
qelem->ntrig = 0;
|
||||||
strcpy(qelem->sched, sched);
|
strcpy(qelem->sched, sched);
|
||||||
DBufInit(&(qelem->tags));
|
|
||||||
DBufPuts(&(qelem->tags), DBufValue(&(trig->tags)));
|
|
||||||
if (SynthesizeTags) {
|
|
||||||
AppendTag(&(qelem->tags), SynthesizeTag());
|
|
||||||
}
|
|
||||||
QueueHead = qelem;
|
QueueHead = qelem;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
maybe_close(int fd)
|
||||||
|
{
|
||||||
|
int new_fd;
|
||||||
|
/* Don't close descriptors connected to a TTY, except for stdin */
|
||||||
|
if (fd && isatty(fd)) return;
|
||||||
|
|
||||||
|
(void) close(fd);
|
||||||
|
if (fd != STDIN_FILENO) {
|
||||||
|
new_fd = open("/dev/null", O_WRONLY);
|
||||||
|
} else {
|
||||||
|
new_fd = open("/dev/null", O_RDONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the open failed... well... not much we can do */
|
||||||
|
if (new_fd < 0) return;
|
||||||
|
|
||||||
|
/* If we got back the same fd as what we just closed, aces! */
|
||||||
|
if (fd == new_fd) return;
|
||||||
|
|
||||||
|
(void) dup2(new_fd, fd);
|
||||||
|
(void) close(new_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SigContHandler(int d)
|
||||||
|
{
|
||||||
|
UNUSED(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_num_queued(void)
|
||||||
|
{
|
||||||
|
int nqueued = 0;
|
||||||
|
QueuedRem *q = QueueHead;
|
||||||
|
while(q) {
|
||||||
|
if (q->tt.nexttime != NO_TIME) {
|
||||||
|
nqueued++;
|
||||||
|
}
|
||||||
|
q = q->next;
|
||||||
|
}
|
||||||
|
if (DaemonJSON) {
|
||||||
|
printf("{");
|
||||||
|
PrintJSONKeyPairString("response", "queued");
|
||||||
|
PrintJSONKeyPairInt("nqueued", nqueued);
|
||||||
|
printf("\"command\":\"STATUS\"}\n");
|
||||||
|
} else {
|
||||||
|
printf("NOTE queued %d\n", nqueued);
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* HandleQueuedReminders */
|
/* HandleQueuedReminders */
|
||||||
@@ -123,17 +302,20 @@ void HandleQueuedReminders(void)
|
|||||||
int TimeToSleep;
|
int TimeToSleep;
|
||||||
unsigned SleepTime;
|
unsigned SleepTime;
|
||||||
Parser p;
|
Parser p;
|
||||||
Trigger trig;
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timeval sleep_tv;
|
struct timeval sleep_tv;
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
char qid[64];
|
||||||
/* Suppress the BANNER from being issued */
|
|
||||||
DidMsgReminder = 1;
|
|
||||||
|
|
||||||
/* Turn off sorting -- otherwise, TriggerReminder has no effect! */
|
/* Turn off sorting -- otherwise, TriggerReminder has no effect! */
|
||||||
SortByDate = 0;
|
SortByDate = 0;
|
||||||
|
|
||||||
|
/* Free FileName if necessary */
|
||||||
|
if (FileName) {
|
||||||
|
free(FileName);
|
||||||
|
FileName = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* If we are not connected to a tty, then we must close the
|
/* If we are not connected to a tty, then we must close the
|
||||||
* standard file descriptors. This is to prevent someone
|
* standard file descriptors. This is to prevent someone
|
||||||
* doing:
|
* doing:
|
||||||
@@ -143,9 +325,10 @@ void HandleQueuedReminders(void)
|
|||||||
* processed correctly are RUN commands, provided they mail
|
* processed correctly are RUN commands, provided they mail
|
||||||
* the result back or use their own resource (as a window).
|
* the result back or use their own resource (as a window).
|
||||||
*/
|
*/
|
||||||
if (!DontFork && (!isatty(1) || !isatty(2))) {
|
if (ShouldFork) {
|
||||||
close(1);
|
maybe_close(STDIN_FILENO);
|
||||||
close(2);
|
maybe_close(STDOUT_FILENO);
|
||||||
|
maybe_close(STDERR_FILENO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're a daemon, get the mod time of initial file */
|
/* If we're a daemon, get the mod time of initial file */
|
||||||
@@ -160,17 +343,24 @@ void HandleQueuedReminders(void)
|
|||||||
/* Initialize the queue - initialize all the entries time of issue */
|
/* Initialize the queue - initialize all the entries time of issue */
|
||||||
|
|
||||||
while (q) {
|
while (q) {
|
||||||
q->tt.nexttime = (int) (SystemTime(1)/60 - 1);
|
q->tt.nexttime = MinutesPastMidnight(1) - 1;
|
||||||
q->tt.nexttime = CalculateNextTime(q);
|
q->tt.nexttime = CalculateNextTime(q);
|
||||||
q = q->next;
|
q = q->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DontFork || Daemon) {
|
if (ShouldFork || Daemon) {
|
||||||
sa.sa_handler = SigIntHandler;
|
sa.sa_handler = SigIntHandler;
|
||||||
sa.sa_flags = 0;
|
sa.sa_flags = 0;
|
||||||
(void) sigaction(SIGINT, &sa, NULL);
|
(void) sigaction(SIGINT, &sa, NULL);
|
||||||
|
sa.sa_handler = SigContHandler;
|
||||||
|
(void) sigaction(SIGCONT, &sa, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_INOTIFY
|
||||||
|
if (IsServerMode()) {
|
||||||
|
watch_fd = setup_inotify_watch();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* Sit in a loop, issuing reminders when necessary */
|
/* Sit in a loop, issuing reminders when necessary */
|
||||||
while(1) {
|
while(1) {
|
||||||
q = FindNextReminder();
|
q = FindNextReminder();
|
||||||
@@ -179,7 +369,7 @@ void HandleQueuedReminders(void)
|
|||||||
if (!q && !Daemon) break;
|
if (!q && !Daemon) break;
|
||||||
|
|
||||||
if (Daemon && !q) {
|
if (Daemon && !q) {
|
||||||
if (Daemon < 0) {
|
if (IsServerMode()) {
|
||||||
/* Sleep until midnight */
|
/* Sleep until midnight */
|
||||||
TimeToSleep = MINUTES_PER_DAY*60 - SystemTime(1);
|
TimeToSleep = MINUTES_PER_DAY*60 - SystemTime(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -198,7 +388,7 @@ void HandleQueuedReminders(void)
|
|||||||
|
|
||||||
/* Wake up once a minute to recalibrate sleep time in
|
/* Wake up once a minute to recalibrate sleep time in
|
||||||
case of laptop hibernation */
|
case of laptop hibernation */
|
||||||
if (Daemon < 0) {
|
if (IsServerMode()) {
|
||||||
/* Wake up on the next exact minute */
|
/* Wake up on the next exact minute */
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
sleep_tv.tv_sec = 60 - (tv.tv_sec % 60);
|
sleep_tv.tv_sec = 60 - (tv.tv_sec % 60);
|
||||||
@@ -209,6 +399,8 @@ void HandleQueuedReminders(void)
|
|||||||
sleep_tv.tv_usec = 0;
|
sleep_tv.tv_usec = 0;
|
||||||
}
|
}
|
||||||
DaemonWait(&sleep_tv);
|
DaemonWait(&sleep_tv);
|
||||||
|
/* A DEL command might have deleted our queued reminder! */
|
||||||
|
q = FindNextReminder();
|
||||||
} else {
|
} else {
|
||||||
sleep(SleepTime);
|
sleep(SleepTime);
|
||||||
}
|
}
|
||||||
@@ -222,14 +414,14 @@ void HandleQueuedReminders(void)
|
|||||||
if (!Daemon) {
|
if (!Daemon) {
|
||||||
int y, m, d;
|
int y, m, d;
|
||||||
if (RealToday != SystemDate(&y, &m, &d)) {
|
if (RealToday != SystemDate(&y, &m, &d)) {
|
||||||
exit(0);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Daemon > 0 && SleepTime) CheckInitialFile();
|
if (Daemon > 0 && SleepTime) CheckInitialFile();
|
||||||
|
|
||||||
if (Daemon && !q) {
|
if (Daemon && !q) {
|
||||||
if (Daemon < 0) {
|
if (IsServerMode()) {
|
||||||
/* Sleep until midnight */
|
/* Sleep until midnight */
|
||||||
TimeToSleep = MINUTES_PER_DAY*60 - SystemTime(1);
|
TimeToSleep = MINUTES_PER_DAY*60 - SystemTime(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -244,31 +436,55 @@ void HandleQueuedReminders(void)
|
|||||||
/* Do NOT trigger the reminder if tt.nexttime is more than a
|
/* Do NOT trigger the reminder if tt.nexttime is more than a
|
||||||
minute in the past. This can happen if the clock is
|
minute in the past. This can happen if the clock is
|
||||||
changed or a laptop awakes from hibernation.
|
changed or a laptop awakes from hibernation.
|
||||||
However, DO trigger if tt.nexttime == tt.ttime so all
|
However, DO trigger if tt.nexttime == tt.ttime and we're
|
||||||
|
within MaxLateTrigger minutes so all
|
||||||
queued reminders are triggered at least once. */
|
queued reminders are triggered at least once. */
|
||||||
if ((SystemTime(1) - (q->tt.nexttime * 60) <= 60) ||
|
if ((SystemTime(1) - (q->tt.nexttime * 60) <= 60) ||
|
||||||
(q->tt.nexttime == q->tt.ttime)) {
|
(q->tt.nexttime == q->tt.ttime &&
|
||||||
|
(MaxLateMinutes == 0 || SystemTime(1) - (q->tt.nexttime * 60) <= 60 * MaxLateMinutes))) {
|
||||||
/* Trigger the reminder */
|
/* Trigger the reminder */
|
||||||
CreateParser(q->text, &p);
|
CreateParser(q->text, &p);
|
||||||
trig.typ = q->typ;
|
|
||||||
strcpy(trig.passthru, q->passthru);
|
|
||||||
RunDisabled = q->RunDisabled;
|
RunDisabled = q->RunDisabled;
|
||||||
if (Daemon < 0) {
|
if (IsServerMode() && q->typ != RUN_TYPE) {
|
||||||
printf("NOTE reminder %s",
|
if (DaemonJSON) {
|
||||||
SimpleTime(q->tt.ttime));
|
printf("{\"response\":\"reminder\",");
|
||||||
printf("%s", SimpleTime(SystemTime(1)/60));
|
snprintf(qid, sizeof(qid), "%lx", (unsigned long) q);
|
||||||
if (!*DBufValue(&q->tags)) {
|
PrintJSONKeyPairString("qid", qid);
|
||||||
printf("*\n");
|
PrintJSONKeyPairString("ttime", SimpleTimeNoSpace(q->tt.ttime));
|
||||||
} else {
|
PrintJSONKeyPairString("now", SimpleTimeNoSpace(MinutesPastMidnight(1)));
|
||||||
printf("%s\n", DBufValue(&(q->tags)));
|
PrintJSONKeyPairString("tags", DBufValue(&q->t.tags));
|
||||||
}
|
} else {
|
||||||
|
printf("NOTE reminder %s",
|
||||||
|
SimpleTime(q->tt.ttime));
|
||||||
|
printf("%s", SimpleTime(MinutesPastMidnight(1)));
|
||||||
|
if (!*DBufValue(&q->t.tags)) {
|
||||||
|
printf("*\n");
|
||||||
|
} else {
|
||||||
|
printf("%s\n", DBufValue(&(q->t.tags)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up global variables so some functions like trigdate()
|
/* Set up global variables so some functions like trigdate()
|
||||||
and trigtime() work correctly */
|
and trigtime() work correctly */
|
||||||
SaveAllTriggerInfo(&(q->t), &(q->tt), DSEToday, q->tt.ttime, 1);
|
SaveAllTriggerInfo(&(q->t), &(q->tt), DSEToday, q->tt.ttime, 1);
|
||||||
(void) TriggerReminder(&p, &trig, &q->tt, DSEToday, 1);
|
FileName = (char *) q->fname;
|
||||||
if (Daemon < 0) {
|
if (DaemonJSON) {
|
||||||
|
DynamicBuffer out;
|
||||||
|
DBufInit(&out);
|
||||||
|
(void) TriggerReminder(&p, &q->t, &q->tt, DSEToday, 1, &out);
|
||||||
|
if (q->typ != RUN_TYPE) {
|
||||||
|
printf("\"body\":\"");
|
||||||
|
chomp(&out);
|
||||||
|
PrintJSONString(DBufValue(&out));
|
||||||
|
printf("\"}\n");
|
||||||
|
}
|
||||||
|
DBufFree(&out);
|
||||||
|
} else {
|
||||||
|
(void) TriggerReminder(&p, &q->t, &q->tt, DSEToday, 1, NULL);
|
||||||
|
}
|
||||||
|
FileName = NULL;
|
||||||
|
if (IsServerMode() && !DaemonJSON && q->typ != RUN_TYPE) {
|
||||||
printf("NOTE endreminder\n");
|
printf("NOTE endreminder\n");
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@@ -277,8 +493,26 @@ void HandleQueuedReminders(void)
|
|||||||
|
|
||||||
/* Calculate the next trigger time */
|
/* Calculate the next trigger time */
|
||||||
q->tt.nexttime = CalculateNextTime(q);
|
q->tt.nexttime = CalculateNextTime(q);
|
||||||
|
|
||||||
|
if (q->tt.nexttime != NO_TIME) {
|
||||||
|
/* If trigger time is way in the past because computer has been
|
||||||
|
suspended or hibernated, remove from queue */
|
||||||
|
if (q->tt.ttime < MinutesPastMidnight(1) - MaxLateMinutes &&
|
||||||
|
q->tt.nexttime < MinutesPastMidnight(1) - MaxLateMinutes) {
|
||||||
|
q->tt.nexttime = NO_TIME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If queued reminder has expired, actually remove it from queue
|
||||||
|
and update status */
|
||||||
|
if (q->tt.nexttime == NO_TIME) {
|
||||||
|
del_reminder(q);
|
||||||
|
if (IsServerMode()) {
|
||||||
|
print_num_queued();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -474,7 +708,11 @@ static void
|
|||||||
json_queue(QueuedRem const *q)
|
json_queue(QueuedRem const *q)
|
||||||
{
|
{
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
if (DaemonJSON) {
|
||||||
|
printf("{\"response\":\"queue\",\"queue\":");
|
||||||
|
}
|
||||||
printf("[");
|
printf("[");
|
||||||
|
char idbuf[64];
|
||||||
while(q) {
|
while(q) {
|
||||||
if (q->tt.nexttime == NO_TIME) {
|
if (q->tt.nexttime == NO_TIME) {
|
||||||
q = q->next;
|
q = q->next;
|
||||||
@@ -485,6 +723,14 @@ json_queue(QueuedRem const *q)
|
|||||||
}
|
}
|
||||||
done = 1;
|
done = 1;
|
||||||
printf("{");
|
printf("{");
|
||||||
|
WriteJSONTrigger(&(q->t), 1, DSEToday);
|
||||||
|
WriteJSONTimeTrigger(&(q->tt));
|
||||||
|
snprintf(idbuf, sizeof(idbuf), "%lx", (unsigned long) q);
|
||||||
|
PrintJSONKeyPairString("qid", idbuf);
|
||||||
|
PrintJSONKeyPairInt("rundisabled", q->RunDisabled);
|
||||||
|
PrintJSONKeyPairInt("ntrig", q->ntrig);
|
||||||
|
PrintJSONKeyPairString("filename", q->fname);
|
||||||
|
PrintJSONKeyPairInt("lineno", q->lineno);
|
||||||
switch(q->typ) {
|
switch(q->typ) {
|
||||||
case NO_TYPE: PrintJSONKeyPairString("type", "NO_TYPE"); break;
|
case NO_TYPE: PrintJSONKeyPairString("type", "NO_TYPE"); break;
|
||||||
case MSG_TYPE: PrintJSONKeyPairString("type", "MSG_TYPE"); break;
|
case MSG_TYPE: PrintJSONKeyPairString("type", "MSG_TYPE"); break;
|
||||||
@@ -497,26 +743,6 @@ json_queue(QueuedRem const *q)
|
|||||||
case PASSTHRU_TYPE: PrintJSONKeyPairString("type", "PASSTHRU_TYPE"); break;
|
case PASSTHRU_TYPE: PrintJSONKeyPairString("type", "PASSTHRU_TYPE"); break;
|
||||||
default: PrintJSONKeyPairString("type", "?"); break;
|
default: PrintJSONKeyPairString("type", "?"); break;
|
||||||
}
|
}
|
||||||
PrintJSONKeyPairInt("rundisabled", q->RunDisabled);
|
|
||||||
PrintJSONKeyPairInt("ntrig", q->ntrig);
|
|
||||||
PrintJSONKeyPairTime("ttime", q->tt.ttime);
|
|
||||||
PrintJSONKeyPairTime("nextttime", q->tt.nexttime);
|
|
||||||
PrintJSONKeyPairInt("delta", q->tt.delta);
|
|
||||||
if (q->tt.rep != NO_TIME) {
|
|
||||||
PrintJSONKeyPairInt("rep", q->tt.rep);
|
|
||||||
}
|
|
||||||
if (q->tt.duration != NO_TIME) {
|
|
||||||
PrintJSONKeyPairInt("duration", q->tt.duration);
|
|
||||||
}
|
|
||||||
if (q->passthru[0]) {
|
|
||||||
PrintJSONKeyPairString("passthru", q->passthru);
|
|
||||||
}
|
|
||||||
if (q->sched[0]) {
|
|
||||||
PrintJSONKeyPairString("sched", q->sched);
|
|
||||||
}
|
|
||||||
if (DBufLen(&(q->tags))) {
|
|
||||||
PrintJSONKeyPairString("tags", DBufValue(&(q->tags)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Last one is a special case - no trailing comma */
|
/* Last one is a special case - no trailing comma */
|
||||||
printf("\"");
|
printf("\"");
|
||||||
@@ -530,7 +756,12 @@ json_queue(QueuedRem const *q)
|
|||||||
printf("\"}");
|
printf("\"}");
|
||||||
q = q->next;
|
q = q->next;
|
||||||
}
|
}
|
||||||
printf("]\n");
|
printf("]");
|
||||||
|
if (DaemonJSON) {
|
||||||
|
printf(",\"command\":\"QUEUE\"}\n");
|
||||||
|
} else {
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -545,15 +776,28 @@ static void DaemonWait(struct timeval *sleep_tv)
|
|||||||
fd_set readSet;
|
fd_set readSet;
|
||||||
int retval;
|
int retval;
|
||||||
int y, m, d;
|
int y, m, d;
|
||||||
|
int max = 1;
|
||||||
char cmdLine[256];
|
char cmdLine[256];
|
||||||
|
|
||||||
FD_ZERO(&readSet);
|
FD_ZERO(&readSet);
|
||||||
FD_SET(0, &readSet);
|
FD_SET(0, &readSet);
|
||||||
retval = select(1, &readSet, NULL, NULL, sleep_tv);
|
|
||||||
|
#ifdef USE_INOTIFY
|
||||||
|
if (watch_fd >= 0) {
|
||||||
|
FD_SET(watch_fd, &readSet);
|
||||||
|
if (watch_fd > max-1)
|
||||||
|
max = watch_fd+1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
retval = select(max, &readSet, NULL, NULL, sleep_tv);
|
||||||
|
|
||||||
/* If date has rolled around, restart */
|
/* If date has rolled around, restart */
|
||||||
if (RealToday != SystemDate(&y, &m, &d)) {
|
if (RealToday != SystemDate(&y, &m, &d)) {
|
||||||
printf("NOTE newdate\nNOTE reread\n");
|
if (DaemonJSON) {
|
||||||
|
printf("{\"response\":\"newdate\"}\n{\"response\":\"reread\",\"command\":\"newdate\"}\n");
|
||||||
|
} else {
|
||||||
|
printf("NOTE newdate\nNOTE reread\n");
|
||||||
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
reread();
|
reread();
|
||||||
}
|
}
|
||||||
@@ -561,70 +805,108 @@ static void DaemonWait(struct timeval *sleep_tv)
|
|||||||
/* If nothing readable or interrupted system call, return */
|
/* If nothing readable or interrupted system call, return */
|
||||||
if (retval <= 0) return;
|
if (retval <= 0) return;
|
||||||
|
|
||||||
|
/* If inotify watch descriptor is readable, handle it */
|
||||||
|
#ifdef USE_INOTIFY
|
||||||
|
if (watch_fd >= 0) {
|
||||||
|
if (FD_ISSET(watch_fd, &readSet)) {
|
||||||
|
consume_inotify_events(watch_fd);
|
||||||
|
if (DaemonJSON) {
|
||||||
|
printf("{\"response\":\"reread\",\"command\":\"inotify\"}\n");
|
||||||
|
} else {
|
||||||
|
/* In deprecated server mode, we need to spit out
|
||||||
|
a NOTE newdate to force the front-end to redraw
|
||||||
|
the calendar */
|
||||||
|
printf("NOTE newdate\nNOTE reread\n");
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
reread();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* If stdin not readable, return */
|
/* If stdin not readable, return */
|
||||||
if (!FD_ISSET(0, &readSet)) return;
|
if (!FD_ISSET(0, &readSet)) return;
|
||||||
|
|
||||||
/* If EOF on stdin, exit */
|
/* If EOF on stdin, exit */
|
||||||
if (feof(stdin)) {
|
if (feof(stdin)) {
|
||||||
exit(0);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a line from stdin and interpret it */
|
/* Read a line from stdin and interpret it */
|
||||||
if (!fgets(cmdLine, sizeof(cmdLine), stdin)) {
|
if (!fgets(cmdLine, sizeof(cmdLine), stdin)) {
|
||||||
exit(0);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(cmdLine, "EXIT\n")) {
|
if (!strcmp(cmdLine, "EXIT\n")) {
|
||||||
exit(0);
|
exit(EXIT_SUCCESS);
|
||||||
} else if (!strcmp(cmdLine, "STATUS\n")) {
|
} else if (!strcmp(cmdLine, "STATUS\n")) {
|
||||||
int nqueued = 0;
|
print_num_queued();
|
||||||
QueuedRem *q = QueueHead;
|
|
||||||
while(q) {
|
|
||||||
if (q->tt.nexttime != NO_TIME) {
|
|
||||||
nqueued++;
|
|
||||||
}
|
|
||||||
q = q->next;
|
|
||||||
}
|
|
||||||
printf("NOTE queued %d\n", nqueued);
|
|
||||||
fflush(stdout);
|
|
||||||
} else if (!strcmp(cmdLine, "QUEUE\n")) {
|
} else if (!strcmp(cmdLine, "QUEUE\n")) {
|
||||||
printf("NOTE queue\n");
|
if (DaemonJSON) {
|
||||||
QueuedRem *q = QueueHead;
|
json_queue(QueueHead);
|
||||||
while (q) {
|
} else {
|
||||||
if (q->tt.nexttime != NO_TIME) {
|
printf("NOTE queue\n");
|
||||||
switch (q->typ) {
|
QueuedRem *q = QueueHead;
|
||||||
case NO_TYPE: printf("NO_TYPE "); break;
|
while (q) {
|
||||||
case MSG_TYPE: printf("MSG_TYPE "); break;
|
if (q->tt.nexttime != NO_TIME) {
|
||||||
case RUN_TYPE: printf("RUN_TYPE "); break;
|
switch (q->typ) {
|
||||||
case CAL_TYPE: printf("CAL_TYPE "); break;
|
case NO_TYPE: printf("NO_TYPE"); break;
|
||||||
case SAT_TYPE: printf("SAT_TYPE "); break;
|
case MSG_TYPE: printf("MSG_TYPE"); break;
|
||||||
case PS_TYPE: printf("PS_TYPE "); break;
|
case RUN_TYPE: printf("RUN_TYPE"); break;
|
||||||
case PSF_TYPE: printf("PSF_TYPE "); break;
|
case CAL_TYPE: printf("CAL_TYPE"); break;
|
||||||
case MSF_TYPE: printf("MSF_TYPE "); break;
|
case SAT_TYPE: printf("SAT_TYPE"); break;
|
||||||
case PASSTHRU_TYPE: printf("PASSTHRU_TYPE "); break;
|
case PS_TYPE: printf("PS_TYPE"); break;
|
||||||
default: printf("? "); break;
|
case PSF_TYPE: printf("PSF_TYPE"); break;
|
||||||
}
|
case MSF_TYPE: printf("MSF_TYPE"); break;
|
||||||
printf("RunDisabled=%d ntrig=%d ttime=%02d:%02d nexttime=%02d:%02d delta=%d rep=%d duration=%d ", q->RunDisabled, q->ntrig, q->tt.ttime/60, q->tt.ttime % 60, q->tt.nexttime / 60, q->tt.nexttime % 60, q->tt.delta, (q->tt.rep != NO_TIME ? q->tt.rep : -1), (q->tt.duration != NO_TIME ? q->tt.duration : -1));
|
case PASSTHRU_TYPE: printf("PASSTHRU_TYPE"); break;
|
||||||
printf("%s %s %s\n",
|
default: printf("?"); break;
|
||||||
(q->passthru[0] ? q->passthru : "*"),
|
}
|
||||||
(q->sched[0] ? q->sched : "*"),
|
printf(" RunDisabled=%d ntrig=%d ttime=%02d:%02d nexttime=%02d:%02d delta=%d rep=%d duration=%d ", q->RunDisabled, q->ntrig, q->tt.ttime/60, q->tt.ttime % 60, q->tt.nexttime / 60, q->tt.nexttime % 60, q->tt.delta, (q->tt.rep != NO_TIME ? q->tt.rep : -1), (q->tt.duration != NO_TIME ? q->tt.duration : -1));
|
||||||
q->text ? q->text : "NULL");
|
printf("%s %s %s\n",
|
||||||
|
(q->passthru[0] ? q->passthru : "*"),
|
||||||
|
(q->sched[0] ? q->sched : "*"),
|
||||||
|
q->text ? q->text : "NULL");
|
||||||
|
}
|
||||||
|
q = q->next;
|
||||||
}
|
}
|
||||||
q = q->next;
|
printf("NOTE endqueue\n");
|
||||||
}
|
}
|
||||||
printf("NOTE endqueue\n");
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
} else if (!strcmp(cmdLine, "JSONQUEUE\n")) {
|
} else if (!strcmp(cmdLine, "JSONQUEUE\n")) {
|
||||||
printf("NOTE JSONQUEUE\n");
|
if (!DaemonJSON) {
|
||||||
|
printf("NOTE JSONQUEUE\n");
|
||||||
|
}
|
||||||
json_queue(QueueHead);
|
json_queue(QueueHead);
|
||||||
printf("NOTE ENDJSONQUEUE\n");
|
if (!DaemonJSON) {
|
||||||
|
printf("NOTE ENDJSONQUEUE\n");
|
||||||
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
} else if (!strcmp(cmdLine, "REREAD\n")) {
|
} else if (!strcmp(cmdLine, "REREAD\n")) {
|
||||||
printf("NOTE reread\n");
|
if (DaemonJSON) {
|
||||||
|
printf("{\"response\":\"reread\",\"command\":\"REREAD\"}\n");
|
||||||
|
} else {
|
||||||
|
printf("NOTE reread\n");
|
||||||
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
reread();
|
reread();
|
||||||
|
} else if (!strncmp(cmdLine, "DEL ", 4)) {
|
||||||
|
unsigned long qid;
|
||||||
|
if (sscanf(cmdLine, "DEL %lx", &qid) == 1) {
|
||||||
|
del_reminder_ul(qid);
|
||||||
|
}
|
||||||
|
print_num_queued();
|
||||||
|
fflush(stdout);
|
||||||
} else {
|
} else {
|
||||||
printf("ERR Invalid daemon command: %s", cmdLine);
|
if (DaemonJSON) {
|
||||||
|
size_t l = strlen(cmdLine);
|
||||||
|
if (l && cmdLine[l-1] == '\n') {
|
||||||
|
cmdLine[l-1] = 0;
|
||||||
|
}
|
||||||
|
printf("{\"response\":\"error\",\"error\":\"Unknown command\",\"command\":\"");
|
||||||
|
PrintJSONString(cmdLine);
|
||||||
|
printf("\"}\n");
|
||||||
|
} else {
|
||||||
|
printf("ERR Invalid daemon command: %s", cmdLine);
|
||||||
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -641,3 +923,56 @@ static void reread(void)
|
|||||||
execvp(ArgV[0], (char **) ArgV);
|
execvp(ArgV[0], (char **) ArgV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_INOTIFY
|
||||||
|
static void consume_inotify_events(int fd)
|
||||||
|
{
|
||||||
|
char buf[sizeof(struct inotify_event) + NAME_MAX + 1];
|
||||||
|
int n;
|
||||||
|
|
||||||
|
struct timespec sleeptime;
|
||||||
|
|
||||||
|
int slept = 0;
|
||||||
|
/* Consume all the inotify events */
|
||||||
|
while(1) {
|
||||||
|
n = read(fd, buf, sizeof(buf));
|
||||||
|
if (n > 0) {
|
||||||
|
/* Something new since we slept */
|
||||||
|
slept = 0;
|
||||||
|
}
|
||||||
|
if (n < 0) {
|
||||||
|
if (errno == EINTR) continue;
|
||||||
|
if (slept) {
|
||||||
|
/* Nothing new since we slept */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
slept = 1;
|
||||||
|
/* HACK: sleep for 0.2 seconds to let multiple events queue up so we
|
||||||
|
only do a single reread */
|
||||||
|
sleeptime.tv_sec = 0;
|
||||||
|
sleeptime.tv_nsec = 200000000;
|
||||||
|
nanosleep(&sleeptime, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int setup_inotify_watch(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
/* Don't inotify_watch stdin */
|
||||||
|
if (!strcmp(InitialFile, "-")) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||||
|
if (fd < 0) {
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
if (inotify_add_watch(fd, InitialFile, IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO) < 0) {
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
28
src/rem2ps.c
28
src/rem2ps.c
@@ -5,7 +5,7 @@
|
|||||||
/* Print a PostScript calendar. */
|
/* Print a PostScript calendar. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -186,19 +186,19 @@ JSONToCalEntry(DynamicBuffer *buf)
|
|||||||
val = json_parse(DBufValue(buf), DBufLen(buf));
|
val = json_parse(DBufValue(buf), DBufLen(buf));
|
||||||
if (!val) {
|
if (!val) {
|
||||||
fprintf(stderr, "Unable to parse JSON line `%s'\n", DBufValue(buf));
|
fprintf(stderr, "Unable to parse JSON line `%s'\n", DBufValue(buf));
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val->type != json_object) {
|
if (val->type != json_object) {
|
||||||
fprintf(stderr, "Expecting JSON object; found `%s'\n",
|
fprintf(stderr, "Expecting JSON object; found `%s'\n",
|
||||||
DBufValue(buf));
|
DBufValue(buf));
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
c = NEW(CalEntry);
|
c = NEW(CalEntry);
|
||||||
if (!c) {
|
if (!c) {
|
||||||
fprintf(stderr, "malloc failed - aborting.\n");
|
fprintf(stderr, "malloc failed - aborting.\n");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
c->next = NULL;
|
c->next = NULL;
|
||||||
c->special = SPECIAL_NORMAL;
|
c->special = SPECIAL_NORMAL;
|
||||||
@@ -221,7 +221,7 @@ JSONToCalEntry(DynamicBuffer *buf)
|
|||||||
c->entry = malloc(strlen(s)+1);
|
c->entry = malloc(strlen(s)+1);
|
||||||
if (!c->entry) {
|
if (!c->entry) {
|
||||||
fprintf(stderr, "malloc failed - aborting.\n");
|
fprintf(stderr, "malloc failed - aborting.\n");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
strcpy(c->entry, s);
|
strcpy(c->entry, s);
|
||||||
got_body = 1;
|
got_body = 1;
|
||||||
@@ -253,7 +253,7 @@ JSONToCalEntry(DynamicBuffer *buf)
|
|||||||
|
|
||||||
if (!got_body || !got_date) {
|
if (!got_body || !got_date) {
|
||||||
fprintf(stderr, "Could not parse line `%s'\n", DBufValue(buf));
|
fprintf(stderr, "Could not parse line `%s'\n", DBufValue(buf));
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -272,7 +272,7 @@ TextToCalEntry(DynamicBuffer *buf)
|
|||||||
CalEntry *c = NEW(CalEntry);
|
CalEntry *c = NEW(CalEntry);
|
||||||
if (!c) {
|
if (!c) {
|
||||||
fprintf(stderr, "malloc failed - aborting.\n");
|
fprintf(stderr, "malloc failed - aborting.\n");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
c->next = NULL;
|
c->next = NULL;
|
||||||
c->special = SPECIAL_NORMAL;
|
c->special = SPECIAL_NORMAL;
|
||||||
@@ -296,7 +296,7 @@ TextToCalEntry(DynamicBuffer *buf)
|
|||||||
c->entry = malloc(strlen(startOfBody) + 1);
|
c->entry = malloc(strlen(startOfBody) + 1);
|
||||||
if (!c->entry) {
|
if (!c->entry) {
|
||||||
fprintf(stderr, "malloc failed - aborting.\n");
|
fprintf(stderr, "malloc failed - aborting.\n");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
strcpy(c->entry, startOfBody);
|
strcpy(c->entry, startOfBody);
|
||||||
|
|
||||||
@@ -343,14 +343,14 @@ int main(int argc, char *argv[])
|
|||||||
DBufGets(&buf, stdin);
|
DBufGets(&buf, stdin);
|
||||||
if (first_line && (!strcmp(DBufValue(&buf), "["))) {
|
if (first_line && (!strcmp(DBufValue(&buf), "["))) {
|
||||||
fprintf(stderr, "Rem2PS: It appears that you have invoked Remind with the -ppp option.\n Please use either -p or -pp, but not -ppp.\n");
|
fprintf(stderr, "Rem2PS: It appears that you have invoked Remind with the -ppp option.\n Please use either -p or -pp, but not -ppp.\n");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
first_line = 0;
|
first_line = 0;
|
||||||
if (!strcmp(DBufValue(&buf), PSBEGIN) ||
|
if (!strcmp(DBufValue(&buf), PSBEGIN) ||
|
||||||
!strcmp(DBufValue(&buf), PSBEGIN2)) {
|
!strcmp(DBufValue(&buf), PSBEGIN2)) {
|
||||||
if (!validfile) {
|
if (!validfile) {
|
||||||
if (Verbose) {
|
if (Verbose) {
|
||||||
fprintf(stderr, "Rem2PS: Version %s Copyright 1992-2023 by Dianne Skoll\n\n", VERSION);
|
fprintf(stderr, "Rem2PS: Version %s Copyright 1992-2024 by Dianne Skoll\n\n", VERSION);
|
||||||
fprintf(stderr, "Generating PostScript calendar\n");
|
fprintf(stderr, "Generating PostScript calendar\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -361,7 +361,7 @@ int main(int argc, char *argv[])
|
|||||||
if (!validfile) {
|
if (!validfile) {
|
||||||
fprintf(stderr, "Rem2PS: Couldn't find any calendar data - are you\n");
|
fprintf(stderr, "Rem2PS: Couldn't find any calendar data - are you\n");
|
||||||
fprintf(stderr, " sure you fed me input produced by remind -p ...?\n");
|
fprintf(stderr, " sure you fed me input produced by remind -p ...?\n");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
printf("%%%%Trailer\n");
|
printf("%%%%Trailer\n");
|
||||||
printf("%%%%Pages: %d\n", validfile);
|
printf("%%%%Pages: %d\n", validfile);
|
||||||
@@ -486,7 +486,7 @@ void DoPsCal(void)
|
|||||||
while(1) {
|
while(1) {
|
||||||
if (feof(stdin)) {
|
if (feof(stdin)) {
|
||||||
fprintf(stderr, "Input from REMIND is corrupt!\n");
|
fprintf(stderr, "Input from REMIND is corrupt!\n");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBufGets(&buf, stdin);
|
DBufGets(&buf, stdin);
|
||||||
@@ -952,7 +952,7 @@ void Init(int argc, char *argv[])
|
|||||||
fprintf(stderr, " WxHin Specify size in inches (W and H are decimal numbers)\n");
|
fprintf(stderr, " WxHin Specify size in inches (W and H are decimal numbers)\n");
|
||||||
fprintf(stderr, " WxHcm Specify size in centimetres (W and H are decimal numbers)\n");
|
fprintf(stderr, " WxHcm Specify size in centimetres (W and H are decimal numbers)\n");
|
||||||
fprintf(stderr, "Default media type is %s\n", DefaultPage[0].name);
|
fprintf(stderr, "Default media type is %s\n", DefaultPage[0].name);
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1033,7 +1033,7 @@ void Usage(char const *s)
|
|||||||
fprintf(stderr, "-e Make calendar fill entire page\n");
|
fprintf(stderr, "-e Make calendar fill entire page\n");
|
||||||
fprintf(stderr, "-x Put day numbers on left instead of right\n");
|
fprintf(stderr, "-x Put day numbers on left instead of right\n");
|
||||||
fprintf(stderr, "-o[lrtb] marg Specify left, right, top and bottom margins\n");
|
fprintf(stderr, "-o[lrtb] marg Specify left, right, top and bottom margins\n");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* Define the PostScript prologue */
|
/* Define the PostScript prologue */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -14,7 +14,7 @@ char *PSProlog1[] =
|
|||||||
{
|
{
|
||||||
"% This file was produced by Remind and Rem2PS, written by",
|
"% This file was produced by Remind and Rem2PS, written by",
|
||||||
"% Dianne Skoll.",
|
"% Dianne Skoll.",
|
||||||
"% Remind and Rem2PS are Copyright 1992-2023 Dianne Skoll.",
|
"% Remind and Rem2PS are Copyright 1992-2024 Dianne Skoll.",
|
||||||
"/ISOLatin1Encoding where { pop save true }{ false } ifelse",
|
"/ISOLatin1Encoding where { pop save true }{ false } ifelse",
|
||||||
" /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus",
|
" /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus",
|
||||||
" StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute",
|
" StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* Routines for sorting reminders by trigger date */
|
/* Routines for sorting reminders by trigger date */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -136,7 +136,7 @@ void IssueSortedReminders(void)
|
|||||||
switch(cur->typ) {
|
switch(cur->typ) {
|
||||||
case MSG_TYPE:
|
case MSG_TYPE:
|
||||||
if (MsgCommand && *MsgCommand) {
|
if (MsgCommand && *MsgCommand) {
|
||||||
DoMsgCommand(MsgCommand, cur->text);
|
DoMsgCommand(MsgCommand, cur->text, 0);
|
||||||
} else {
|
} else {
|
||||||
if (cur->trigdate != olddate) {
|
if (cur->trigdate != olddate) {
|
||||||
IssueSortBanner(cur->trigdate);
|
IssueSortBanner(cur->trigdate);
|
||||||
@@ -151,11 +151,11 @@ void IssueSortedReminders(void)
|
|||||||
IssueSortBanner(cur->trigdate);
|
IssueSortBanner(cur->trigdate);
|
||||||
olddate = cur->trigdate;
|
olddate = cur->trigdate;
|
||||||
}
|
}
|
||||||
FillParagraph(cur->text);
|
FillParagraph(cur->text, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RUN_TYPE:
|
case RUN_TYPE:
|
||||||
System(cur->text);
|
System(cur->text, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* classifying the tokens parsed. */
|
/* classifying the tokens parsed. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* Routines for figuring out the trigger date of a reminder */
|
/* Routines for figuring out the trigger date of a reminder */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -72,7 +72,10 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
|
|||||||
m++;
|
m++;
|
||||||
if (m == 12) { m = 0; y++; }
|
if (m == 12) { m = 0; y++; }
|
||||||
}
|
}
|
||||||
while (trig->d > DaysInMonth(m, trig->y)) m++;
|
while (trig->d > DaysInMonth(m, y)) {
|
||||||
|
m++;
|
||||||
|
if (m == 12) { m = 0; y++; }
|
||||||
|
}
|
||||||
j = DSE(y, m, trig->d);
|
j = DSE(y, m, trig->d);
|
||||||
return j;
|
return j;
|
||||||
|
|
||||||
@@ -241,6 +244,7 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
|
|||||||
|
|
||||||
case GOT_WD+GOT_MON+GOT_YR:
|
case GOT_WD+GOT_MON+GOT_YR:
|
||||||
if (y > trig->y || (y == trig->y && m > trig->m)) return -1;
|
if (y > trig->y || (y == trig->y && m > trig->m)) return -1;
|
||||||
|
/* cppcheck-suppress knownConditionTrueFalse */
|
||||||
if (trig->y > y || (trig->y == y && trig->m > m)) {
|
if (trig->y > y || (trig->y == y && trig->m > m)) {
|
||||||
j = DSE(trig->y, trig->m, 1);
|
j = DSE(trig->y, trig->m, 1);
|
||||||
ADVANCE_TO_WD(j, trig->wd);
|
ADVANCE_TO_WD(j, trig->wd);
|
||||||
@@ -324,8 +328,11 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
start--;
|
start--;
|
||||||
|
if (start < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (iter > MaxSatIter) {
|
if (start < 0 || iter > MaxSatIter) {
|
||||||
/* omitfunc must have returned "true" too often */
|
/* omitfunc must have returned "true" too often */
|
||||||
*err = E_CANT_TRIG;
|
*err = E_CANT_TRIG;
|
||||||
return -2;
|
return -2;
|
||||||
@@ -388,6 +395,10 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
simple--;
|
simple--;
|
||||||
|
if (simple < 0) {
|
||||||
|
*err = E_CANT_TRIG;
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (iter > MaxSatIter) {
|
if (iter > MaxSatIter) {
|
||||||
*err = E_CANT_TRIG;
|
*err = E_CANT_TRIG;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* Type definitions all dumped here. */
|
/* Type definitions all dumped here. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -150,6 +150,7 @@ typedef Parser *ParsePtr; /* Pointer to parser structure */
|
|||||||
#define DB_DUMP_VARS 8
|
#define DB_DUMP_VARS 8
|
||||||
#define DB_ECHO_LINE 16
|
#define DB_ECHO_LINE 16
|
||||||
#define DB_TRACE_FILES 32
|
#define DB_TRACE_FILES 32
|
||||||
|
#define DB_EXPR_STACKS 64
|
||||||
|
|
||||||
/* Enumeration of the tokens */
|
/* Enumeration of the tokens */
|
||||||
enum TokTypes
|
enum TokTypes
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* functions. */
|
/* functions. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -349,7 +349,9 @@ int CallUserFunc(char const *name, int nargs, ParsePtr p)
|
|||||||
|
|
||||||
/* Skip the opening bracket, if there's one */
|
/* Skip the opening bracket, if there's one */
|
||||||
while (isempty(*s)) s++;
|
while (isempty(*s)) s++;
|
||||||
if (*s == BEG_OF_EXPR) s++;
|
if (*s == BEG_OF_EXPR) {
|
||||||
|
s++;
|
||||||
|
}
|
||||||
push_call(f->filename, f->name, f->lineno);
|
push_call(f->filename, f->name, f->lineno);
|
||||||
h = Evaluate(&s, f->locals, p);
|
h = Evaluate(&s, f->locals, p);
|
||||||
if (h == OK) {
|
if (h == OK) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* Useful utility functions. */
|
/* Useful utility functions. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -36,6 +36,11 @@ char *StrnCpy(char *dest, char const *source, int n)
|
|||||||
{
|
{
|
||||||
char *odest = dest;
|
char *odest = dest;
|
||||||
|
|
||||||
|
if (n <= 0) {
|
||||||
|
*dest = 0;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
while (n-- && (*dest++ = *source++)) ;
|
while (n-- && (*dest++ = *source++)) ;
|
||||||
if (*(dest-1)) *dest = 0;
|
if (*(dest-1)) *dest = 0;
|
||||||
return odest;
|
return odest;
|
||||||
@@ -108,7 +113,7 @@ int DateOK(int y, int m, int d)
|
|||||||
m > 11 ||
|
m > 11 ||
|
||||||
y > BASE + YR_RANGE ||
|
y > BASE + YR_RANGE ||
|
||||||
d > DaysInMonth(m, y) ) return 0;
|
d > DaysInMonth(m, y) ) return 0;
|
||||||
else return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Functions designed to defeat gcc optimizer */
|
/* Functions designed to defeat gcc optimizer */
|
||||||
|
|||||||
46
src/var.c
46
src/var.c
@@ -6,7 +6,7 @@
|
|||||||
/* user- and system-defined variables. */
|
/* user- and system-defined variables. */
|
||||||
/* */
|
/* */
|
||||||
/* This file is part of REMIND. */
|
/* This file is part of REMIND. */
|
||||||
/* Copyright (C) 1992-2023 by Dianne Skoll */
|
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
@@ -167,6 +167,13 @@ static int latitude_func(int do_set, Value *val)
|
|||||||
return latitude_longitude_func(do_set, val, &Latitude, -90.0, 90.0);
|
return latitude_longitude_func(do_set, val, &Latitude, -90.0, 90.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int terminal_bg_func(int do_set, Value *val)
|
||||||
|
{
|
||||||
|
UNUSED(do_set);
|
||||||
|
val->type = INT_TYPE;
|
||||||
|
val->v.val = GetTerminalBackground();
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int trig_date_func(int do_set, Value *val)
|
static int trig_date_func(int do_set, Value *val)
|
||||||
{
|
{
|
||||||
@@ -473,7 +480,7 @@ int DeleteVar(char const *str)
|
|||||||
/* Set the indicate variable to the specified value. */
|
/* Set the indicate variable to the specified value. */
|
||||||
/* */
|
/* */
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
int SetVar(char const *str, Value *val)
|
int SetVar(char const *str, Value const *val)
|
||||||
{
|
{
|
||||||
Var *v = FindVar(str, 1);
|
Var *v = FindVar(str, 1);
|
||||||
|
|
||||||
@@ -525,7 +532,9 @@ int DoSet (Parser *p)
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
DynamicBuffer buf;
|
DynamicBuffer buf;
|
||||||
|
DynamicBuffer buf2;
|
||||||
DBufInit(&buf);
|
DBufInit(&buf);
|
||||||
|
DBufInit(&buf2);
|
||||||
|
|
||||||
r = ParseIdentifier(p, &buf);
|
r = ParseIdentifier(p, &buf);
|
||||||
if (r) return r;
|
if (r) return r;
|
||||||
@@ -541,6 +550,13 @@ int DoSet (Parser *p)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = ParseToken(p, &buf2);
|
||||||
|
if (r) return r;
|
||||||
|
if (DBufLen(&buf2)) {
|
||||||
|
DBufFree(&buf2);
|
||||||
|
return E_EXPECTING_EOL;
|
||||||
|
}
|
||||||
|
DBufFree(&buf2);
|
||||||
if (*DBufValue(&buf) == '$') r = SetSysVar(DBufValue(&buf)+1, &v);
|
if (*DBufValue(&buf) == '$') r = SetSysVar(DBufValue(&buf)+1, &v);
|
||||||
else r = SetVar(DBufValue(&buf), &v);
|
else r = SetVar(DBufValue(&buf), &v);
|
||||||
if (buf.len > VAR_NAME_LEN) {
|
if (buf.len > VAR_NAME_LEN) {
|
||||||
@@ -762,10 +778,14 @@ typedef struct {
|
|||||||
char modifiable;
|
char modifiable;
|
||||||
int type;
|
int type;
|
||||||
void *value;
|
void *value;
|
||||||
int min;
|
int min; /* Or const-value */
|
||||||
int max;
|
int max;
|
||||||
} SysVar;
|
} SysVar;
|
||||||
|
|
||||||
|
/* Macro to access "min" but as a constval. Just to make source more
|
||||||
|
readable */
|
||||||
|
#define constval min
|
||||||
|
|
||||||
/* If the type of a sys variable is STR_TYPE, then min is redefined
|
/* If the type of a sys variable is STR_TYPE, then min is redefined
|
||||||
to be a flag indicating whether or not the value has been malloc'd. */
|
to be a flag indicating whether or not the value has been malloc'd. */
|
||||||
#define been_malloced min
|
#define been_malloced min
|
||||||
@@ -825,6 +845,9 @@ static SysVar SysVarArr[] = {
|
|||||||
{"LongMin", 1, SPECIAL_TYPE, longmin_func, 0, 0 },
|
{"LongMin", 1, SPECIAL_TYPE, longmin_func, 0, 0 },
|
||||||
{"LongSec", 1, SPECIAL_TYPE, longsec_func, 0, 0 },
|
{"LongSec", 1, SPECIAL_TYPE, longsec_func, 0, 0 },
|
||||||
{"March", 1, STR_TYPE, &DynamicMonthName[2], 0, 0 },
|
{"March", 1, STR_TYPE, &DynamicMonthName[2], 0, 0 },
|
||||||
|
{"MaxFullOmits", 0, CONST_INT_TYPE, NULL, MAX_FULL_OMITS, 0},
|
||||||
|
{"MaxLateMinutes", 1, INT_TYPE, &MaxLateMinutes, 0, 1440 },
|
||||||
|
{"MaxPartialOmits",0, CONST_INT_TYPE, NULL, MAX_PARTIAL_OMITS, 0},
|
||||||
{"MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY },
|
{"MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY },
|
||||||
{"MaxStringLen", 1, INT_TYPE, &MaxStringLen, -1, ANY },
|
{"MaxStringLen", 1, INT_TYPE, &MaxStringLen, -1, ANY },
|
||||||
{"May", 1, STR_TYPE, &DynamicMonthName[4], 0, 0 },
|
{"May", 1, STR_TYPE, &DynamicMonthName[4], 0, 0 },
|
||||||
@@ -835,6 +858,8 @@ static SysVar SysVarArr[] = {
|
|||||||
{"NextMode", 0, INT_TYPE, &NextMode, 0, 0 },
|
{"NextMode", 0, INT_TYPE, &NextMode, 0, 0 },
|
||||||
{"November", 1, STR_TYPE, &DynamicMonthName[10],0, 0 },
|
{"November", 1, STR_TYPE, &DynamicMonthName[10],0, 0 },
|
||||||
{"Now", 1, STR_TYPE, &DynamicNow, 0, 0 },
|
{"Now", 1, STR_TYPE, &DynamicNow, 0, 0 },
|
||||||
|
{"NumFullOmits", 0, INT_TYPE, &NumFullOmits, 0, 0 },
|
||||||
|
{"NumPartialOmits",0, INT_TYPE, &NumPartialOmits, 0, 0 },
|
||||||
{"NumQueued", 0, INT_TYPE, &NumQueued, 0, 0 },
|
{"NumQueued", 0, INT_TYPE, &NumQueued, 0, 0 },
|
||||||
{"NumTrig", 0, INT_TYPE, &NumTriggered, 0, 0 },
|
{"NumTrig", 0, INT_TYPE, &NumTriggered, 0, 0 },
|
||||||
{"October", 1, STR_TYPE, &DynamicMonthName[9], 0, 0 },
|
{"October", 1, STR_TYPE, &DynamicMonthName[9], 0, 0 },
|
||||||
@@ -856,7 +881,7 @@ static SysVar SysVarArr[] = {
|
|||||||
{"SysInclude", 0, STR_TYPE, &SysDir, 0, 0 },
|
{"SysInclude", 0, STR_TYPE, &SysDir, 0, 0 },
|
||||||
{"T", 0, SPECIAL_TYPE, trig_date_func, 0, 0 },
|
{"T", 0, SPECIAL_TYPE, trig_date_func, 0, 0 },
|
||||||
{"Td", 0, SPECIAL_TYPE, trig_day_func, 0, 0 },
|
{"Td", 0, SPECIAL_TYPE, trig_day_func, 0, 0 },
|
||||||
{"TerminalBackground", 0, INT_TYPE, &TerminalBackground, 0, 0 },
|
{"TerminalBackground", 0, SPECIAL_TYPE, terminal_bg_func, 0, 0 },
|
||||||
{"Thursday", 1, STR_TYPE, &DynamicDayName[3], 0, 0 },
|
{"Thursday", 1, STR_TYPE, &DynamicDayName[3], 0, 0 },
|
||||||
{"TimeSep", 1, SPECIAL_TYPE, time_sep_func, 0, 0 },
|
{"TimeSep", 1, SPECIAL_TYPE, time_sep_func, 0, 0 },
|
||||||
{"Tm", 0, SPECIAL_TYPE, trig_mon_func, 0, 0 },
|
{"Tm", 0, SPECIAL_TYPE, trig_mon_func, 0, 0 },
|
||||||
@@ -894,13 +919,13 @@ int SetSysVar(char const *name, Value *value)
|
|||||||
int r;
|
int r;
|
||||||
SysVar *v = FindSysVar(name);
|
SysVar *v = FindSysVar(name);
|
||||||
if (!v) return E_NOSUCH_VAR;
|
if (!v) return E_NOSUCH_VAR;
|
||||||
if (v->type != SPECIAL_TYPE &&
|
|
||||||
v->type != value->type) return E_BAD_TYPE;
|
|
||||||
if (!v->modifiable) {
|
if (!v->modifiable) {
|
||||||
Eprint("%s: `$%s'", ErrMsg[E_CANT_MODIFY], name);
|
Eprint("%s: `$%s'", ErrMsg[E_CANT_MODIFY], name);
|
||||||
return E_CANT_MODIFY;
|
return E_CANT_MODIFY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (v->type != SPECIAL_TYPE &&
|
||||||
|
v->type != value->type) return E_BAD_TYPE;
|
||||||
if (v->type == SPECIAL_TYPE) {
|
if (v->type == SPECIAL_TYPE) {
|
||||||
SysVarFunc f = (SysVarFunc) v->value;
|
SysVarFunc f = (SysVarFunc) v->value;
|
||||||
r = f(1, value);
|
r = f(1, value);
|
||||||
@@ -941,6 +966,11 @@ int GetSysVar(char const *name, Value *val)
|
|||||||
|
|
||||||
val->type = ERR_TYPE;
|
val->type = ERR_TYPE;
|
||||||
if (!v) return E_NOSUCH_VAR;
|
if (!v) return E_NOSUCH_VAR;
|
||||||
|
if (v->type == CONST_INT_TYPE) {
|
||||||
|
val->v.val = v->constval;
|
||||||
|
val->type = INT_TYPE;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
if (v->type == SPECIAL_TYPE) {
|
if (v->type == SPECIAL_TYPE) {
|
||||||
SysVarFunc f = (SysVarFunc) v->value;
|
SysVarFunc f = (SysVarFunc) v->value;
|
||||||
return f(0, val);
|
return f(0, val);
|
||||||
@@ -1034,7 +1064,9 @@ static void DumpSysVar(char const *name, const SysVar *v)
|
|||||||
if (name) strcat(buffer, name); else strcat(buffer, v->name);
|
if (name) strcat(buffer, name); else strcat(buffer, v->name);
|
||||||
fprintf(ErrFp, "%16s ", buffer);
|
fprintf(ErrFp, "%16s ", buffer);
|
||||||
if (v) {
|
if (v) {
|
||||||
if (v->type == SPECIAL_TYPE) {
|
if (v->type == CONST_INT_TYPE) {
|
||||||
|
fprintf(ErrFp, "%d\n", v->constval);
|
||||||
|
} else if (v->type == SPECIAL_TYPE) {
|
||||||
SysVarFunc f = (SysVarFunc) v->value;
|
SysVarFunc f = (SysVarFunc) v->value;
|
||||||
f(0, &vtmp);
|
f(0, &vtmp);
|
||||||
PrintValue(&vtmp, ErrFp);
|
PrintValue(&vtmp, ErrFp);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ MSG UseVTColors is: [$UseVTColors]%
|
|||||||
MSG Use256Colors is: [$Use256Colors]%
|
MSG Use256Colors is: [$Use256Colors]%
|
||||||
MSG UseTrueColors is: [$UseTrueColors]%
|
MSG UseTrueColors is: [$UseTrueColors]%
|
||||||
MSG UseBGVTColors is: [$UseBGVTColors]%
|
MSG UseBGVTColors is: [$UseBGVTColors]%
|
||||||
set n ansicolor("")]
|
set n ansicolor("")
|
||||||
MSG This is [ansicolor(0,255,0)]green[n], [ansicolor("255 0 0")]red[n] and [ansicolor("0 0 255")]blue[n] text.%
|
MSG This is [ansicolor(0,255,0)]green[n], [ansicolor("255 0 0")]red[n] and [ansicolor("0 0 255")]blue[n] text.%
|
||||||
MSG This is [ansicolor(0,0,0)][ansicolor(0,255,0,1)]black text on a green background[n]%
|
MSG This is [ansicolor(0,0,0)][ansicolor(0,255,0,1)]black text on a green background[n]%
|
||||||
MSG This is [ansicolor(0,0,0,0,1)]clamped black text[n]%
|
MSG This is [ansicolor(0,0,0,0,1)]clamped black text[n]%
|
||||||
|
|||||||
6
tests/queue1.rem
Normal file
6
tests/queue1.rem
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
FSET msgprefix(x) "Priority: " + x + "; Filename: " + filename() + ": "
|
||||||
|
|
||||||
|
REM at 23:56 MSG foo
|
||||||
|
REM PRIORITY 42 at 23:57 MSG bar
|
||||||
|
REM PRIORITY 999 at 23:58 MSQ quux
|
||||||
|
DO queue2.rem
|
||||||
1
tests/queue2.rem
Normal file
1
tests/queue2.rem
Normal file
@@ -0,0 +1 @@
|
|||||||
|
REM at 23:59 PRIORITY 2 MSG XXXX
|
||||||
106
tests/test-rem
106
tests/test-rem
@@ -7,7 +7,7 @@
|
|||||||
# in the build directory.
|
# in the build directory.
|
||||||
#
|
#
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# Copyright (C) 1992-2023 Dianne Skoll
|
# Copyright (C) 1992-2024 Dianne Skoll
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -31,6 +31,15 @@ fi
|
|||||||
TZ=UTC
|
TZ=UTC
|
||||||
export TZ
|
export TZ
|
||||||
|
|
||||||
|
RESULT=`(echo 'BANNER %'; echo 'IF now() > 23:55'; echo 'MSG late%'; echo 'ENDIF') | ../src/remind -h -`
|
||||||
|
|
||||||
|
if test "$RESULT" = "late" ; then
|
||||||
|
echo ""
|
||||||
|
echo "*** Please do not run the test suite between 23:55 and 00:00 UTC; it will fail."
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# If we're already in a utf-8 locale, do
|
# If we're already in a utf-8 locale, do
|
||||||
# nothing; otherwise, set LC_ALL
|
# nothing; otherwise, set LC_ALL
|
||||||
OK=0
|
OK=0
|
||||||
@@ -56,6 +65,8 @@ echo "Test 1" > ../tests/test.out
|
|||||||
echo "" >> ../tests/test.out
|
echo "" >> ../tests/test.out
|
||||||
../src/remind -e -dxte ../tests/test.rem 16 feb 1991 12:13 >> ../tests/test.out 2>&1
|
../src/remind -e -dxte ../tests/test.rem 16 feb 1991 12:13 >> ../tests/test.out 2>&1
|
||||||
echo "" >> ../tests/test.out
|
echo "" >> ../tests/test.out
|
||||||
|
echo 'set a 1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+2*3))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))' | ../src/remind -ds - 16 feb 1991 12:13 >> ../tests/test.out 2>&1
|
||||||
|
echo "" >> ../tests/test.out
|
||||||
echo "Test 2" >> ../tests/test.out
|
echo "Test 2" >> ../tests/test.out
|
||||||
echo "" >> ../tests/test.out
|
echo "" >> ../tests/test.out
|
||||||
../src/remind -p -l ../tests/test2.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
../src/remind -p -l ../tests/test2.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||||
@@ -437,6 +448,99 @@ rm -rf include_dir/ww
|
|||||||
# This segfaulted in 04.02.03
|
# This segfaulted in 04.02.03
|
||||||
../src/remind -h '-imsgprefix(x)="foo"' /dev/null >> ../tests/test.out 2>&1
|
../src/remind -h '-imsgprefix(x)="foo"' /dev/null >> ../tests/test.out 2>&1
|
||||||
|
|
||||||
|
# Test --version long option
|
||||||
|
../src/remind --version >> ../tests/test.out 2>&1
|
||||||
|
|
||||||
|
# Test queueing. Because eventstart depends on the actual system
|
||||||
|
# date, we have to convert it to some constant (in this case,
|
||||||
|
# VOLATILE) so that tests are not dependent on the system date.
|
||||||
|
echo JSONQUEUE | ../src/remind -z0 ../tests/queue1.rem 2>&1 | sed -e 's/"eventstart":"................"/"eventstart":"VOLATILE"/g' | sed -e 's/"qid":"[0-9a-f]*",//g' >> ../tests/test.out 2>&1
|
||||||
|
echo QUEUE | ../src/remind -zj ../tests/queue1.rem 2>&1 | sed -e 's/"eventstart":"................"/"eventstart":"VOLATILE"/g' | sed -e 's/"qid":"[0-9a-f]*",//g' >> ../tests/test.out 2>&1
|
||||||
|
|
||||||
|
# Test for leap year bug that was fixed
|
||||||
|
../src/remind -dte - 28 Feb 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||||
|
BANNER %
|
||||||
|
REM 29 MSG One
|
||||||
|
REM 29 Feb MSG two
|
||||||
|
REM 29 2024 MSG three
|
||||||
|
REM 29 Feb 2024 MSG four
|
||||||
|
REM Thursday 29 MSG One
|
||||||
|
REM Thursday 29 Feb MSG two
|
||||||
|
REM Thursday 29 2024 MSG three
|
||||||
|
REM Thursday 29 Feb 2024 MSG four
|
||||||
|
REM Wednesday 29 MSG One
|
||||||
|
REM Wednesday 29 Feb MSG two
|
||||||
|
REM Wednesday 29 2024 MSG three
|
||||||
|
REM Wednesday 29 Feb 2024 MSG four
|
||||||
|
REM Friday 29 MSG One
|
||||||
|
REM Friday 29 Feb MSG two
|
||||||
|
REM Friday 29 2024 MSG three
|
||||||
|
REM Friday 29 Feb 2024 MSG four
|
||||||
|
EOF
|
||||||
|
|
||||||
|
../src/remind -dte - 1 Mar 2024 <<'EOF' >> ../tests/test.out 2>&1
|
||||||
|
BANNER %
|
||||||
|
REM 29 MSG One
|
||||||
|
REM 29 Feb MSG two
|
||||||
|
REM 29 2024 MSG three
|
||||||
|
REM 29 Feb 2024 MSG four
|
||||||
|
REM Thursday 29 MSG One
|
||||||
|
REM Thursday 29 Feb MSG two
|
||||||
|
REM Thursday 29 2024 MSG three
|
||||||
|
REM Thursday 29 Feb 2024 MSG four
|
||||||
|
REM Wednesday 29 MSG One
|
||||||
|
REM Wednesday 29 Feb MSG two
|
||||||
|
REM Wednesday 29 2024 MSG three
|
||||||
|
REM Wednesday 29 Feb 2024 MSG four
|
||||||
|
REM Friday 29 MSG One
|
||||||
|
REM Friday 29 Feb MSG two
|
||||||
|
REM Friday 29 2024 MSG three
|
||||||
|
REM Friday 29 Feb 2024 MSG four
|
||||||
|
EOF
|
||||||
|
|
||||||
|
../src/remind -dte - 28 Feb 2025 <<'EOF' >> ../tests/test.out 2>&1
|
||||||
|
BANNER %
|
||||||
|
REM 29 MSG One
|
||||||
|
REM 29 Feb MSG two
|
||||||
|
REM 29 2025 MSG three
|
||||||
|
REM 29 Feb 2025 MSG four
|
||||||
|
REM Thursday 29 MSG One
|
||||||
|
REM Thursday 29 Feb MSG two
|
||||||
|
REM Thursday 29 2025 MSG three
|
||||||
|
REM Thursday 29 Feb 2025 MSG four
|
||||||
|
REM Wednesday 29 MSG One
|
||||||
|
REM Wednesday 29 Feb MSG two
|
||||||
|
REM Wednesday 29 2025 MSG three
|
||||||
|
REM Wednesday 29 Feb 2025 MSG four
|
||||||
|
REM Friday 29 MSG One
|
||||||
|
REM Friday 29 Feb MSG two
|
||||||
|
REM Friday 29 2025 MSG three
|
||||||
|
REM Friday 29 Feb 2025 MSG four
|
||||||
|
EOF
|
||||||
|
|
||||||
|
../src/remind -dte - 1 Mar 2025 <<'EOF' >> ../tests/test.out 2>&1
|
||||||
|
BANNER %
|
||||||
|
REM 29 MSG One
|
||||||
|
REM 29 Feb MSG two
|
||||||
|
REM 29 2025 MSG three
|
||||||
|
REM 29 Feb 2025 MSG four
|
||||||
|
REM Thursday 29 MSG One
|
||||||
|
REM Thursday 29 Feb MSG two
|
||||||
|
REM Thursday 29 2025 MSG three
|
||||||
|
REM Thursday 29 Feb 2025 MSG four
|
||||||
|
REM Wednesday 29 MSG One
|
||||||
|
REM Wednesday 29 Feb MSG two
|
||||||
|
REM Wednesday 29 2025 MSG three
|
||||||
|
REM Wednesday 29 Feb 2025 MSG four
|
||||||
|
REM Friday 29 MSG One
|
||||||
|
REM Friday 29 Feb MSG two
|
||||||
|
REM Friday 29 2025 MSG three
|
||||||
|
REM Friday 29 Feb 2025 MSG four
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
(echo 'BANNER %'; echo 'REM 29 MSG No bug') | ../src/remind -dt - 29 Feb 2024 >> ../tests/test.out 2>&1
|
||||||
|
|
||||||
# Remove references to SysInclude, which is build-specific
|
# Remove references to SysInclude, which is build-specific
|
||||||
grep -F -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out
|
grep -F -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out
|
||||||
cmp -s ../tests/test.out ../tests/test.cmp
|
cmp -s ../tests/test.out ../tests/test.cmp
|
||||||
|
|||||||
1422
tests/test.cmp
1422
tests/test.cmp
File diff suppressed because one or more lines are too long
@@ -381,9 +381,11 @@ msg [a076]%
|
|||||||
set a077 dosubst("%*Y %*Z", '1992/5/5')
|
set a077 dosubst("%*Y %*Z", '1992/5/5')
|
||||||
msg [a077]%
|
msg [a077]%
|
||||||
set a078 easterdate(today())
|
set a078 easterdate(today())
|
||||||
|
set a078 easterdate()
|
||||||
set a079 easterdate(1992)
|
set a079 easterdate(1992)
|
||||||
set a080 easterdate(1995)
|
set a080 easterdate(1995)
|
||||||
set a078 orthodoxeaster(today())
|
set a078 orthodoxeaster(today())
|
||||||
|
set a078 orthodoxeaster()
|
||||||
set a079 orthodoxeaster(1992)
|
set a079 orthodoxeaster(1992)
|
||||||
set a080 orthodoxeaster(1995)
|
set a080 orthodoxeaster(1995)
|
||||||
set a080 orthodoxeaster(2023)
|
set a080 orthodoxeaster(2023)
|
||||||
@@ -782,6 +784,15 @@ ENDIF
|
|||||||
REM [trig("Mon", "Tue", "Wed", "Sat")] MSG foo
|
REM [trig("Mon", "Tue", "Wed", "Sat")] MSG foo
|
||||||
REM [trig("Mon", "Tue", "Wed")] MSG bar
|
REM [trig("Mon", "Tue", "Wed")] MSG bar
|
||||||
|
|
||||||
|
# Multitrig
|
||||||
|
REM [multitrig("10", "17")] MSG multitrig-1
|
||||||
|
REM [multitrig("Feb 15", "Mar 20")] MSG multitrig-2
|
||||||
|
REM [multitrig("Oct 7 1992", "1991")] MSG multitrig-3
|
||||||
|
REM [multitrig("16 Feb AFTER OMIT Sat Sun", "29 March")] MSG multitrig-4
|
||||||
|
REM [multitrig("2", "3", "5", "7")] MSG multitrig-5
|
||||||
|
REM [multitrig("15 SCANFROM -7", "14 SCANFROM -7")] MSG multitrig-6
|
||||||
|
REM [multitrig("15 SCANFROM -7", "14 SCANFROM -7")] SCANFROM -7 MSG multitrig-7
|
||||||
|
|
||||||
# The new syntactic sugar
|
# The new syntactic sugar
|
||||||
REM First Monday January MSG x
|
REM First Monday January MSG x
|
||||||
REM Second Tuesday in April MSG x
|
REM Second Tuesday in April MSG x
|
||||||
@@ -882,11 +893,38 @@ set a htmlstriptags("this is > whut <b>foo</b>")
|
|||||||
set a htmlstriptags("<img src=\"foo\">")
|
set a htmlstriptags("<img src=\"foo\">")
|
||||||
|
|
||||||
# $ParseUntriggered
|
# $ParseUntriggered
|
||||||
REM 2 Jan 1990 MSG ["bad_expr" * 2]
|
REM 2 Jan 1990 MSG ["bad_expr" / 2]
|
||||||
SET $ParseUntriggered 0
|
SET $ParseUntriggered 0
|
||||||
REM 2 Jan 1990 MSG ["bad_expr" * 2]
|
REM 2 Jan 1990 MSG ["bad_expr" / 2]
|
||||||
SET $ParseUntriggered 1
|
SET $ParseUntriggered 1
|
||||||
|
|
||||||
|
# String multiplication
|
||||||
|
|
||||||
|
set a "low" * (-1)
|
||||||
|
set a (-1) * "low"
|
||||||
|
|
||||||
|
set a "zero" * 0
|
||||||
|
set a 0 * "zero"
|
||||||
|
|
||||||
|
set a "" * 10000000
|
||||||
|
set a 10000000 * ""
|
||||||
|
|
||||||
|
# Too long for default limits
|
||||||
|
set a "wookie" * 1000000
|
||||||
|
set a 1000000 * "wookie"
|
||||||
|
|
||||||
|
set a "Cabbage! " * 7
|
||||||
|
set a 7 * "Cabbage! "
|
||||||
|
|
||||||
|
# Should result in errors
|
||||||
|
set pqxya 1+2)
|
||||||
|
|
||||||
|
# Should result in an error
|
||||||
|
REM Tue OMIT 2024-01-01 MSG Wookie
|
||||||
|
|
||||||
|
# No error
|
||||||
|
REM Tue OMIT Wed 2024-01-01 MSG Blort
|
||||||
|
|
||||||
# Don't want Remind to queue reminders
|
# Don't want Remind to queue reminders
|
||||||
EXIT
|
EXIT
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
# Use the output to verify your translations.
|
# Use the output to verify your translations.
|
||||||
#
|
#
|
||||||
# This file is part of REMIND.
|
# This file is part of REMIND.
|
||||||
# Copyright (C) 1992-2023 Dianne Skoll
|
# Copyright (C) 1992-2024 Dianne Skoll
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
#
|
#
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ CGIDIR = /cgi-bin
|
|||||||
# The complete path to the directory containing the HTML file "calendar.html".
|
# The complete path to the directory containing the HTML file "calendar.html".
|
||||||
# This is a sample file containing links to all the scripts. This path
|
# This is a sample file containing links to all the scripts. This path
|
||||||
# should be the path as seen by the UNIX operating system
|
# should be the path as seen by the UNIX operating system
|
||||||
HTMLDIR = /var/www/remind
|
HTMLDIR = /var/www/html/remind
|
||||||
|
|
||||||
# Where you stick images and CSS files, as seen by UNIX
|
# Where you stick images and CSS files, as seen by UNIX
|
||||||
IMAGEDIR = /var/www/remind/resources
|
IMAGEDIR = /var/www/html/remind/resources
|
||||||
|
|
||||||
# Where images and CSS files are, as seen by web browsers
|
# Where images and CSS files are, as seen by web browsers
|
||||||
IMAGEBASE = /remind/resources
|
IMAGEBASE = /remind/resources
|
||||||
@@ -32,6 +32,7 @@ datarootdir=@datarootdir@
|
|||||||
# Where do Remind and Rem2PS executables live?
|
# Where do Remind and Rem2PS executables live?
|
||||||
REMIND = $(bindir)/remind
|
REMIND = $(bindir)/remind
|
||||||
REM2PS = $(bindir)/rem2ps
|
REM2PS = $(bindir)/rem2ps
|
||||||
|
REM2PDF = $(bindir)/rem2pdf
|
||||||
REM2HTML = $(bindir)/rem2html
|
REM2HTML = $(bindir)/rem2html
|
||||||
# If your Web server requires CGI programs to have a .cgi suffix, use
|
# If your Web server requires CGI programs to have a .cgi suffix, use
|
||||||
# the next line. Otherwise, comment it out
|
# the next line. Otherwise, comment it out
|
||||||
@@ -46,6 +47,7 @@ SEDSCRIPT = -e 's@%CGIDIR%@$(CGIDIR)@g' \
|
|||||||
-e 's@%REMIND%@$(REMIND)@g' \
|
-e 's@%REMIND%@$(REMIND)@g' \
|
||||||
-e 's@%IMAGEBASE%@$(IMAGEBASE)@g' \
|
-e 's@%IMAGEBASE%@$(IMAGEBASE)@g' \
|
||||||
-e 's@%REM2PS%@$(REM2PS)@g' \
|
-e 's@%REM2PS%@$(REM2PS)@g' \
|
||||||
|
-e 's@%REM2PDF%@$(REM2PDF)@g' \
|
||||||
-e 's@%REM2HTML%@$(REM2HTML)@g' \
|
-e 's@%REM2HTML%@$(REM2HTML)@g' \
|
||||||
-e 's@cal_dispatch@cal_dispatch$(CGISUFFIX)@g' \
|
-e 's@cal_dispatch@cal_dispatch$(CGISUFFIX)@g' \
|
||||||
|
|
||||||
@@ -57,7 +59,8 @@ all:
|
|||||||
install:
|
install:
|
||||||
-mkdir -p $(DESTDIR)$(SCRIPTDIR)
|
-mkdir -p $(DESTDIR)$(SCRIPTDIR)
|
||||||
-mkdir -p $(DESTDIR)$(HTMLDIR)
|
-mkdir -p $(DESTDIR)$(HTMLDIR)
|
||||||
cp calps hebdate hebps hebhtml moon sunrise sunset $(DESTDIR)$(SCRIPTDIR)
|
cp calps calpdf hebps hebpdf hebhtml moon sunrise sunset $(DESTDIR)$(SCRIPTDIR)
|
||||||
|
sed $(SEDSCRIPT) < hebdate > $(DESTDIR)$(SCRIPTDIR)/hebdate
|
||||||
sed $(SEDSCRIPT) < cal_dispatch-DIST > $(DESTDIR)$(SCRIPTDIR)/cal_dispatch$(CGISUFFIX)
|
sed $(SEDSCRIPT) < cal_dispatch-DIST > $(DESTDIR)$(SCRIPTDIR)/cal_dispatch$(CGISUFFIX)
|
||||||
sed $(SEDSCRIPT) < hebdate.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/hebdate.rem
|
sed $(SEDSCRIPT) < hebdate.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/hebdate.rem
|
||||||
sed $(SEDSCRIPT) < moon.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/moon.rem
|
sed $(SEDSCRIPT) < moon.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/moon.rem
|
||||||
@@ -73,14 +76,14 @@ install:
|
|||||||
chmod 644 $(DESTDIR)$(SCRIPTDIR)/blank.rem
|
chmod 644 $(DESTDIR)$(SCRIPTDIR)/blank.rem
|
||||||
chmod 644 $(DESTDIR)$(HTMLDIR)/calendar.html
|
chmod 644 $(DESTDIR)$(HTMLDIR)/calendar.html
|
||||||
chmod 755 $(DESTDIR)$(SCRIPTDIR)/cal_dispatch$(CGISUFFIX)
|
chmod 755 $(DESTDIR)$(SCRIPTDIR)/cal_dispatch$(CGISUFFIX)
|
||||||
chmod 755 $(DESTDIR)$(SCRIPTDIR)/calps $(DESTDIR)$(SCRIPTDIR)/hebdate \
|
chmod 755 $(DESTDIR)$(SCRIPTDIR)/calpdf $(DESTDIR)$(SCRIPTDIR)/calps $(DESTDIR)$(SCRIPTDIR)/hebdate \
|
||||||
$(DESTDIR)$(SCRIPTDIR)/hebps $(DESTDIR)$(SCRIPTDIR)/moon \
|
$(DESTDIR)$(SCRIPTDIR)/hebps $(DESTDIR)$(SCRIPTDIR)/hebpdf $(DESTDIR)$(SCRIPTDIR)/moon \
|
||||||
$(DESTDIR)$(SCRIPTDIR)/sunrise $(DESTDIR)$(SCRIPTDIR)/sunset \
|
$(DESTDIR)$(SCRIPTDIR)/sunrise $(DESTDIR)$(SCRIPTDIR)/sunset \
|
||||||
$(DESTDIR)$(SCRIPTDIR)/hebhtml \
|
$(DESTDIR)$(SCRIPTDIR)/hebhtml \
|
||||||
|
|
||||||
-mkdir -p $(DESTDIR)$(IMAGEDIR)
|
-mkdir -p $(DESTDIR)$(IMAGEDIR)
|
||||||
cp rem-default.css *.png $(DESTDIR)$(IMAGEDIR)
|
cp calendar.css rem-default.css *.png $(DESTDIR)$(IMAGEDIR)
|
||||||
chmod 644 $(DESTDIR)$(IMAGEDIR)/rem-default.css $(DESTDIR)$(IMAGEDIR)/*.png
|
chmod 644 $(DESTDIR)$(IMAGEDIR)/calendar.css $(DESTDIR)$(IMAGEDIR)/rem-default.css $(DESTDIR)$(IMAGEDIR)/*.png
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ export REMIND
|
|||||||
REM2PS=%REM2PS%
|
REM2PS=%REM2PS%
|
||||||
export REM2PS
|
export REM2PS
|
||||||
|
|
||||||
|
# Set REM2PDF to the full pathname of the rem2pdf executable
|
||||||
|
REM2PDF=%REM2PDF%
|
||||||
|
export REM2PDF
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
#
|
#
|
||||||
# Don't change anything after this.
|
# Don't change anything after this.
|
||||||
@@ -56,6 +60,10 @@ case "$1" in
|
|||||||
exec $DIR/calps
|
exec $DIR/calps
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
calpdf)
|
||||||
|
exec $DIR/calpdf
|
||||||
|
;;
|
||||||
|
|
||||||
moon)
|
moon)
|
||||||
exec $DIR/moon
|
exec $DIR/moon
|
||||||
;;
|
;;
|
||||||
@@ -64,6 +72,10 @@ case "$1" in
|
|||||||
exec $DIR/hebps
|
exec $DIR/hebps
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
hebpdf)
|
||||||
|
exec $DIR/hebpdf
|
||||||
|
;;
|
||||||
|
|
||||||
hebhtml)
|
hebhtml)
|
||||||
if [ "$2" = "" -o "$3" = "" ] ; then
|
if [ "$2" = "" -o "$3" = "" ] ; then
|
||||||
exec $DIR/hebhtml
|
exec $DIR/hebhtml
|
||||||
|
|||||||
41
www/calendar.css
Normal file
41
www/calendar.css
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
html, body {
|
||||||
|
padding: 0px;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-family: "Open Sans", Arial, sans-serif
|
||||||
|
background: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, .h1 {
|
||||||
|
font-size: 1.75rem; }
|
||||||
|
|
||||||
|
h2, .h2 {
|
||||||
|
font-size: 1.5rem; }
|
||||||
|
|
||||||
|
h3, .h3 {
|
||||||
|
font-size: 1.25rem; }
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #1a0dab;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #1a0dab;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #ff0000;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<HTML>
|
<HTML>
|
||||||
<!-- Sample HTML file with links to the calendar stuff -->
|
<!-- Sample HTML file with links to the calendar stuff -->
|
||||||
<HEAD>
|
<HEAD>
|
||||||
<TITLE>Remind Calendar Server</TITLE>
|
<TITLE>Remind Calendar Server</TITLE>
|
||||||
|
<LINK rel="stylesheet" href="%IMAGEBASE%/calendar.css">
|
||||||
</HEAD>
|
</HEAD>
|
||||||
|
|
||||||
<BODY>
|
<BODY>
|
||||||
@@ -15,10 +16,14 @@ Sunset Information</a><P>
|
|||||||
Moon Phase Information</a><P>
|
Moon Phase Information</a><P>
|
||||||
<a HREF="%CGIDIR%/cal_dispatch?calps">
|
<a HREF="%CGIDIR%/cal_dispatch?calps">
|
||||||
Blank PostScript Calendar</a> (Approximately 20kB)<P>
|
Blank PostScript Calendar</a> (Approximately 20kB)<P>
|
||||||
|
<a HREF="%CGIDIR%/cal_dispatch?calpdf">
|
||||||
|
Blank PDF Calendar</a> (Approximately 15kB)<P>
|
||||||
<a HREF="%CGIDIR%/cal_dispatch?hebdate">
|
<a HREF="%CGIDIR%/cal_dispatch?hebdate">
|
||||||
Today's Hebrew Date</a><P>
|
Today's Hebrew Date</a><P>
|
||||||
<a HREF="%CGIDIR%/cal_dispatch?hebps">
|
<a HREF="%CGIDIR%/cal_dispatch?hebps">
|
||||||
PostScript Calendar with Jewish Holidays</a> (Approximately 35 kB)<P>
|
PostScript Calendar with Jewish Holidays</a> (Approximately 35 kB)<P>
|
||||||
|
<a HREF="%CGIDIR%/cal_dispatch?hebpdf">
|
||||||
|
PDF Calendar with Jewish Holidays</a> (Approximately 20 kB)<P>
|
||||||
<a HREF="%CGIDIR%/cal_dispatch?hebhtml">
|
<a HREF="%CGIDIR%/cal_dispatch?hebhtml">
|
||||||
HTML Calendar with Jewish Holidays</a>
|
HTML Calendar with Jewish Holidays</a>
|
||||||
<HR>
|
<HR>
|
||||||
|
|||||||
11
www/calpdf
Normal file
11
www/calpdf
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# PostScript calendar shell script
|
||||||
|
#
|
||||||
|
# This file is part of REMIND.
|
||||||
|
# Copyright (C) 1992-2018 by Dianne Skoll
|
||||||
|
|
||||||
|
echo "Content-type: application/pdf"
|
||||||
|
echo
|
||||||
|
|
||||||
|
$REMIND -p $DIR/blank.rem | $REM2PDF -e -c3 -l
|
||||||
|
exit 0
|
||||||
@@ -11,6 +11,7 @@ cat <<EOM
|
|||||||
<HTML>
|
<HTML>
|
||||||
<HEAD>
|
<HEAD>
|
||||||
<TITLE>Hebrew date</TITLE>
|
<TITLE>Hebrew date</TITLE>
|
||||||
|
<LINK rel="stylesheet" href="%IMAGEBASE%/calendar.css">
|
||||||
</HEAD>
|
</HEAD>
|
||||||
<BODY>
|
<BODY>
|
||||||
|
|
||||||
|
|||||||
@@ -165,13 +165,15 @@ ENDIF
|
|||||||
IF !$PSCAL
|
IF !$PSCAL
|
||||||
REM 20 ++40 msg Also available: <a HREF="%CGIDIR%/cal_dispatch?hebps">a PostScript calendar</a> (about 35KB) for %m %y, complete with Hebrew dates, Jewish holidays, and moon phases for [$Location].
|
REM 20 ++40 msg Also available: <a HREF="%CGIDIR%/cal_dispatch?hebps">a PostScript calendar</a> (about 35KB) for %m %y, complete with Hebrew dates, Jewish holidays, and moon phases for [$Location].
|
||||||
REM 20 ++40 msg And: <a HREF="%CGIDIR%/cal_dispatch?hebhtml">an HTML version</a> of the above.
|
REM 20 ++40 msg And: <a HREF="%CGIDIR%/cal_dispatch?hebhtml">an HTML version</a> of the above.
|
||||||
|
REM 20 ++40 msg And: <a HREF="%CGIDIR%/cal_dispatch?hebpdf">a PDF version</a> of the above.
|
||||||
ELSE
|
ELSE
|
||||||
[trigger(moondate(0))] SPECIAL MOON 0
|
REM [moondate(0)] SPECIAL MOON 0
|
||||||
[trigger(moondate(1))] SPECIAL MOON 1
|
REM [moondate(1)] SPECIAL MOON 1
|
||||||
[trigger(moondate(2))] SPECIAL MOON 2
|
REM [moondate(2)] SPECIAL MOON 2
|
||||||
[trigger(moondate(3))] SPECIAL MOON 3
|
REM [moondate(3)] SPECIAL MOON 3
|
||||||
REM PS Border Border moveto /DayFont findfont 10 scalefont setfont ([hebday(today())] [hebmon(today())]) show
|
REM PS Border Border moveto /DayFont findfont 10 scalefont setfont ([hebday($U)] [hebmon($U)]) show
|
||||||
REM SPECIAL HTML <P>[hebday(today())] [hebmon(today())]</P>
|
REM SPECIAL HTML <P>[hebday($U)] [hebmon($U)]</P>
|
||||||
|
REM SPECIAL PANGO @4,-1 <span size="6400"><i>[hebday($U)] [hebmon($U)]</i></span>
|
||||||
|
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
|
|||||||
17
www/hebpdf
Normal file
17
www/hebpdf
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Hebrew PostScript calendar shell script
|
||||||
|
#
|
||||||
|
# This file is part of REMIND.
|
||||||
|
# Copyright (C) 1992-2018 by Dianne Skoll
|
||||||
|
|
||||||
|
# Figure out the month: If day <= 20, use this month; otherwise, use
|
||||||
|
# next month.
|
||||||
|
echo "Content-type: application/pdf"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
$REMIND - <<EOR
|
||||||
|
BANNER %
|
||||||
|
REM 20 ++40 RUN $REMIND -iHTML=0 -p $DIR/hebdate.rem %m %y | $REM2PDF -e -c3 -l
|
||||||
|
EOR
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -9,6 +9,7 @@ banner %
|
|||||||
|
|
||||||
MSG <HEAD>%
|
MSG <HEAD>%
|
||||||
MSG <TITLE>Moon over [$Location]</TITLE>%
|
MSG <TITLE>Moon over [$Location]</TITLE>%
|
||||||
|
MSG <LINK rel="stylesheet" href="%IMAGEBASE%/calendar.css">%
|
||||||
MSG </HEAD>%
|
MSG </HEAD>%
|
||||||
|
|
||||||
MSG <BODY>
|
MSG <BODY>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user