mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
142 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e3562e2e4 | ||
|
|
2020ae35c1 | ||
|
|
9418043bb6 | ||
|
|
e2f786580c | ||
|
|
5aabb20630 | ||
|
|
a3c9ac2457 | ||
|
|
80e3671f9b | ||
|
|
e8e4362839 | ||
|
|
61ac3ca6ed | ||
|
|
eaf982e1cc | ||
|
|
0c27503a83 | ||
|
|
5878c2a714 | ||
|
|
6aa4d681e8 | ||
|
|
790a9ee384 | ||
|
|
d091af6e5b | ||
|
|
3ca9a69100 | ||
|
|
f6253d0fca | ||
|
|
3e6233b6f0 | ||
|
|
0ee5efa4df | ||
|
|
d4ed89f5ba | ||
|
|
34c864a38c | ||
|
|
6d4c38126e | ||
|
|
59c434ce34 | ||
|
|
a550af8fa6 | ||
|
|
3399646896 | ||
|
|
00e85e5ca2 | ||
|
|
9867d3cf34 | ||
|
|
0f4326726a | ||
|
|
1d208400cd | ||
|
|
b9b7e0d42a | ||
|
|
93316d754c | ||
|
|
14b6e23eaa | ||
|
|
7ae7edcb42 | ||
|
|
20a558f817 | ||
|
|
5118ccd120 | ||
|
|
18c4ed1c6d | ||
|
|
62e1a467f5 | ||
|
|
0933cd83b1 | ||
|
|
1ed7c83b24 | ||
|
|
3bae02f27d | ||
|
|
3b485f0632 | ||
|
|
a023d9dc5d | ||
|
|
4ccdfac8b8 | ||
|
|
1c52718ef0 | ||
|
|
4dde2a4b9d | ||
|
|
24f923ecfc | ||
|
|
45c0ba5e8f | ||
|
|
bccfe94921 | ||
|
|
f7e83ed082 | ||
|
|
40b87eff60 | ||
|
|
a8607cb012 | ||
|
|
6caa404e59 | ||
|
|
13e1e19855 | ||
|
|
96d40b81df | ||
|
|
30e4a9fc50 | ||
|
|
6d0fbeed20 | ||
|
|
3f1aaeefd2 | ||
|
|
326604fe18 | ||
|
|
57e93553bf | ||
|
|
a5aa5d901b | ||
|
|
1e0d43b63c | ||
|
|
188efaebba | ||
|
|
b701dc575f | ||
|
|
c9ae1c82f0 | ||
|
|
13cea56cce | ||
|
|
6661f32faf | ||
|
|
f6ab660c5e | ||
|
|
523cfb7bf5 | ||
|
|
82a4ba777d | ||
|
|
8f02868486 | ||
|
|
12d8e8e948 | ||
|
|
f5f364507b | ||
|
|
d514389c39 | ||
|
|
52c615ff61 | ||
|
|
7d3e6b3a72 | ||
|
|
c4e5190ec2 | ||
|
|
f197f5ef9d | ||
|
|
153cbfe276 | ||
|
|
2d9bea444b | ||
|
|
2ae8e51bec | ||
|
|
05d1608081 | ||
|
|
d093e8dea3 | ||
|
|
f9fac22bbf | ||
|
|
9ecbfbb314 | ||
|
|
612f3e7f16 | ||
|
|
d22f9979a5 | ||
|
|
291f648d2e | ||
|
|
351088fd4b | ||
|
|
ed57f62911 | ||
|
|
53dcce6a91 | ||
|
|
d12d327e35 | ||
|
|
a2f760fb91 | ||
|
|
4a9b4ff6e4 | ||
|
|
ce6061a29b | ||
|
|
878a5d9bed | ||
|
|
d1b55bae8d | ||
|
|
c13817015f | ||
|
|
bf74ad1eb7 | ||
|
|
f2eb06c752 | ||
|
|
8172acf102 | ||
|
|
949e00219d | ||
|
|
1fd19b89e2 | ||
|
|
22d6c0583a | ||
|
|
12fac555b6 | ||
|
|
085b781114 | ||
|
|
c9d7fbf479 | ||
|
|
42f868db07 | ||
|
|
2996275ec4 | ||
|
|
5586198a0e | ||
|
|
d17c48e751 | ||
|
|
e08a6370ef | ||
|
|
7a319466cf | ||
|
|
4158ad5977 | ||
|
|
9b07eed26f | ||
|
|
05ead8c40d | ||
|
|
35e222967c | ||
|
|
83ca07d34f | ||
|
|
36f4bb852b | ||
|
|
9642303d05 | ||
|
|
a6144baff7 | ||
|
|
17985c59c3 | ||
|
|
719295ccd7 | ||
|
|
3d74389713 | ||
|
|
80c7244d64 | ||
|
|
db27be1469 | ||
|
|
d59fe832fd | ||
|
|
88ebdf275e | ||
|
|
a7a6f8b5f0 | ||
|
|
3e248c069e | ||
|
|
65cca1fd8f | ||
|
|
5a889043ba | ||
|
|
6d1fcdf246 | ||
|
|
3476b965ef | ||
|
|
0bba2dc3b3 | ||
|
|
e5c27f19f5 | ||
|
|
f9aa53433e | ||
|
|
5323245529 | ||
|
|
deb12ac7cd | ||
|
|
a1488d93ad | ||
|
|
65add3d32e | ||
|
|
8d6f5efa7b | ||
|
|
eb996a8146 |
@@ -3,7 +3,7 @@ THE REMIND COPYRIGHT
|
||||
1. REMIND refers to the entire set of files and documentation in the
|
||||
REMIND package.
|
||||
|
||||
2. REMIND is Copyright (C) 1992-2025 Dianne Skoll, except where noted in
|
||||
2. REMIND is Copyright (C) 1992-2026 Dianne Skoll, except where noted in
|
||||
individual files.
|
||||
|
||||
3. DISTRIBUTION AND USE
|
||||
|
||||
39
Makefile
39
Makefile
@@ -11,6 +11,33 @@ all: src/Makefile
|
||||
@echo ""
|
||||
@cd src && $(MAKE) all LANGDEF=$(LANGDEF)
|
||||
@$(MAKE) -C rem2pdf -f Makefile.top
|
||||
|
||||
uninstall-script:
|
||||
@echo "" >&2
|
||||
@echo "*****************************" >&2
|
||||
@echo "* *" >&2
|
||||
@echo "* Creating Uninstall Script *" >&2
|
||||
@echo "* *" >&2
|
||||
@echo "*****************************" >&2
|
||||
@echo "" >&2
|
||||
|
||||
@echo "#!/bin/sh"
|
||||
@echo "echo 'This script will uninstall Remind'"
|
||||
@echo "echo 'Enter y to uninstall Remind or anything else to abort'"
|
||||
@echo "read ans"
|
||||
@echo 'if test "$$ans" != "y" ; then'
|
||||
@echo " echo 'NOT uninstalling Remind'"
|
||||
@echo " exit 0"
|
||||
@echo "fi"
|
||||
@echo "echo 'Uninstalling Remind...'"
|
||||
-@rm -rf `pwd`/.uninstall-dir > /dev/null 2>&1
|
||||
@mkdir `pwd`/.uninstall-dir >&2
|
||||
@$(MAKE) install DESTDIR=`pwd`/.uninstall-dir >&2
|
||||
@cd `pwd`/.uninstall-dir && find . -type f | while read x ; do x=`echo $$x | sed -e 's|^\./|/|'`; echo "rm -f $$x"; done;
|
||||
@echo "echo 'Done'"
|
||||
-@rm -rf `pwd`/.uninstall-dir > /dev/null 2>&1
|
||||
|
||||
|
||||
install:
|
||||
@echo ""
|
||||
@echo "**********************************"
|
||||
@@ -19,9 +46,9 @@ install:
|
||||
@echo "* *"
|
||||
@echo "**********************************"
|
||||
@echo ""
|
||||
@$(MAKE) -C src install
|
||||
@$(MAKE) -C rem2html install
|
||||
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
|
||||
@$(MAKE) -C src install DESTDIR=$(DESTDIR)
|
||||
@$(MAKE) -C rem2html install DESTDIR=$(DESTDIR)
|
||||
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE) DESTDIR=$(DESTDIR)
|
||||
clean:
|
||||
-find . -name '*~' -exec rm {} \;
|
||||
-$(MAKE) -C src clean
|
||||
@@ -35,9 +62,9 @@ install-stripped:
|
||||
@echo "* *"
|
||||
@echo "**********************************"
|
||||
@echo ""
|
||||
@$(MAKE) -C src install-stripped
|
||||
@$(MAKE) -C rem2html install
|
||||
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
|
||||
@$(MAKE) -C src install-stripped DESTDIR=$(DESTDIR)
|
||||
@$(MAKE) -C rem2html install DESTDIR=$(DESTDIR)
|
||||
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE) DESTDIR=$(DESTDIR)
|
||||
|
||||
test: test-basic test-tz
|
||||
|
||||
|
||||
2
build.tk
2
build.tk
@@ -8,7 +8,7 @@
|
||||
# A cheesy graphical front-end for building and installing REMIND.
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 Dianne Skoll
|
||||
# Copyright (C) 1992-2026 Dianne Skoll
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
|
||||
|
||||
51
configure
vendored
51
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.72 for remind 06.01.07.
|
||||
# Generated by GNU Autoconf 2.72 for remind 06.02.02.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation,
|
||||
@@ -601,8 +601,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='remind'
|
||||
PACKAGE_TARNAME='remind'
|
||||
PACKAGE_VERSION='06.01.07'
|
||||
PACKAGE_STRING='remind 06.01.07'
|
||||
PACKAGE_VERSION='06.02.02'
|
||||
PACKAGE_STRING='remind 06.02.02'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL='https://dianne.skoll.ca/projects/remind/'
|
||||
|
||||
@@ -1258,7 +1258,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
'configure' configures remind 06.01.07 to adapt to many kinds of systems.
|
||||
'configure' configures remind 06.02.02 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1320,7 +1320,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of remind 06.01.07:";;
|
||||
short | recursive ) echo "Configuration of remind 06.02.02:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1408,7 +1408,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
remind configure 06.01.07
|
||||
remind configure 06.02.02
|
||||
generated by GNU Autoconf 2.72
|
||||
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
@@ -1871,7 +1871,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by remind $as_me 06.01.07, which was
|
||||
It was created by remind $as_me 06.02.02, which was
|
||||
generated by GNU Autoconf 2.72. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
@@ -4231,6 +4231,7 @@ U="`uname -s`"
|
||||
if test "$U" != "SunOS" -a "$GCC" = yes; then
|
||||
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
|
||||
# Check for link-time optimization support
|
||||
OLDCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -flto=auto"
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -flto=auto" >&5
|
||||
printf %s "checking whether $CC supports -flto=auto... " >&6; }
|
||||
@@ -4258,11 +4259,12 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lto" >&5
|
||||
printf "%s\n" "$lto" >&6; }
|
||||
if test "x$lto" != "xyes" ; then
|
||||
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
|
||||
CFLAGS="$OLDCFLAGS"
|
||||
else
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -ffat-lto-object" >&5
|
||||
printf %s "checking whether $CC supports -ffat-lto-object... " >&6; }
|
||||
CFLAGS="$CFLAGS -ffat-lto-objects"
|
||||
OLDCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror -ffat-lto-objects"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
int x = 1;
|
||||
@@ -4287,7 +4289,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lto" >&5
|
||||
printf "%s\n" "$lto" >&6; }
|
||||
if test "x$lto" != "xyes" ; then
|
||||
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes -flto=auto"
|
||||
CFLAGS="$OLDCFLAGS"
|
||||
else
|
||||
CFLAGS="$OLDCFLAGS -ffat-lto-objects"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -4312,24 +4316,12 @@ if test "$?" != 0 ; then
|
||||
echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!"
|
||||
exit 1
|
||||
fi
|
||||
ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup"
|
||||
if test "x$ac_cv_func_strdup" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_STRDUP 1" >>confdefs.h
|
||||
|
||||
if test "$ac_cv_header_wctype_h" != "yes" ; then
|
||||
echo "*** Remind requires the <wctype.h> header"
|
||||
exit 1
|
||||
fi
|
||||
ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp"
|
||||
if test "x$ac_cv_func_strcasecmp" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_STRCASECMP 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp"
|
||||
if test "x$ac_cv_func_strncasecmp" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_STRNCASECMP 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv"
|
||||
if test "x$ac_cv_func_setenv" = xyes
|
||||
then :
|
||||
@@ -4380,6 +4372,11 @@ then :
|
||||
fi
|
||||
|
||||
|
||||
if test "$ac_cv_func_mbstowcs" != "yes"; then
|
||||
echo "*** Remind requires the mbstowcs function"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION=$PACKAGE_VERSION
|
||||
CONFIG_CMD="$0$ac_configure_args_raw"
|
||||
CONFIG_CMD=`echo "$CONFIG_CMD" | sed -e 's/"/\\\\"/g'`
|
||||
@@ -4895,7 +4892,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by remind $as_me 06.01.07, which was
|
||||
This file was extended by remind $as_me 06.02.02, which was
|
||||
generated by GNU Autoconf 2.72. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -4960,7 +4957,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config='$ac_cs_config_escaped'
|
||||
ac_cs_version="\\
|
||||
remind config.status 06.01.07
|
||||
remind config.status 06.02.02
|
||||
configured by $0, generated by GNU Autoconf 2.72,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
25
configure.ac
25
configure.ac
@@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(remind, 06.01.07, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_INIT(remind, 06.02.02, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_CONFIG_SRCDIR([src/queue.c])
|
||||
|
||||
cat <<'EOF'
|
||||
@@ -50,6 +50,7 @@ U="`uname -s`"
|
||||
if test "$U" != "SunOS" -a "$GCC" = yes; then
|
||||
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
|
||||
# Check for link-time optimization support
|
||||
OLDCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -flto=auto"
|
||||
AC_MSG_CHECKING([whether $CC supports -flto=auto])
|
||||
AC_LINK_IFELSE(
|
||||
@@ -61,10 +62,11 @@ if test "$U" != "SunOS" -a "$GCC" = yes; then
|
||||
)
|
||||
AC_MSG_RESULT([$lto])
|
||||
if test "x$lto" != "xyes" ; then
|
||||
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
|
||||
CFLAGS="$OLDCFLAGS"
|
||||
else
|
||||
AC_MSG_CHECKING([whether $CC supports -ffat-lto-object])
|
||||
CFLAGS="$CFLAGS -ffat-lto-objects"
|
||||
OLDCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror -ffat-lto-objects"
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[int x = 1;]],
|
||||
@@ -74,7 +76,9 @@ if test "$U" != "SunOS" -a "$GCC" = yes; then
|
||||
)
|
||||
AC_MSG_RESULT([$lto])
|
||||
if test "x$lto" != "xyes" ; then
|
||||
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes -flto=auto"
|
||||
CFLAGS="$OLDCFLAGS"
|
||||
else
|
||||
CFLAGS="$OLDCFLAGS -ffat-lto-objects"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -99,7 +103,18 @@ if test "$?" != 0 ; then
|
||||
echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!"
|
||||
exit 1
|
||||
fi
|
||||
AC_CHECK_FUNCS(strdup strcasecmp strncasecmp setenv unsetenv glob mbstowcs setlocale initgroups inotify_init1 readline)
|
||||
|
||||
if test "$ac_cv_header_wctype_h" != "yes" ; then
|
||||
echo "*** Remind requires the <wctype.h> header"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups inotify_init1 readline)
|
||||
|
||||
if test "$ac_cv_func_mbstowcs" != "yes"; then
|
||||
echo "*** Remind requires the mbstowcs function"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION=$PACKAGE_VERSION
|
||||
CONFIG_CMD="$0$ac_configure_args_raw"
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
(defconst remind-keywords
|
||||
(sort
|
||||
(list "ADDOMIT" "AFTER" "AT" "BAN" "BANNER" "BEFORE" "CAL" "CLEAR"
|
||||
"CLEAR-OMIT-CONTEXT" "COMPLETE-THROUGH" "DEBUG" "DO" "DUMP" "DUMPVARS"
|
||||
"CLEAR-OMIT-CONTEXT" "COMPLETE-THROUGH" "COMPLETED-THROUGH" "DEBUG" "DO" "DUMP" "DUMPVARS"
|
||||
"DURATION" "ELSE" "ENDIF" "ERRMSG" "EXIT" "EXPR" "FIRST"
|
||||
"FLUSH" "FOURTH" "FRENAME" "FROM" "FSET" "FUNSET" "IF"
|
||||
"IFTRIG" "IN" "INC" "INCLUDE" "INCLUDECMD" "INFO" "LAST"
|
||||
@@ -131,7 +131,7 @@
|
||||
|
||||
(defconst remind-builtin-variables
|
||||
(sort
|
||||
(list " $AddBlankLines" "$Ago" "$Am" "$And" "$April" "$At" "$August"
|
||||
(list "$AddBlankLines" "$Ago" "$Am" "$And" "$April" "$At" "$August"
|
||||
"$CalcUTC" "$CalMode" "$CalType" "$Daemon" "$DateSep" "$DateTimeSep"
|
||||
"$December" "$DedupeReminders" "$DefaultColor" "$DefaultDelta"
|
||||
"$DefaultPrio" "$DefaultTDelta" "$DeltaOverride"
|
||||
@@ -148,7 +148,7 @@
|
||||
"$PrefixLineNo" "$PSCal" "$RunOff" "$Saturday" "$September"
|
||||
"$SimpleCal" "$SortByDate" "$SortByPrio" "$SortByTime" "$SubsIndent"
|
||||
"$Sunday" "$SuppressImplicitWarnings" "$SuppressLRM" "$SysInclude" "$T" "$Tb" "$Td"
|
||||
"$TerminalBackground" "$Thursday" "$TimeSep" "$TimetIs64bit" "$Tm" "$Today" "$TodoFilter"
|
||||
"$TerminalBackground" "$TerminalHyperlinks" "$Thursday" "$TimeSep" "$TimetIs64bit" "$Tm" "$Today" "$TodoFilter"
|
||||
"$Tomorrow" "$Tt" "$Tuesday" "$Tw" "$Ty" "$U" "$Ud" "$Um"
|
||||
"$UntimedFirst" "$Use256Colors" "$UseBGVTColors" "$UseTrueColors"
|
||||
"$UseVTColors" "$Uw" "$Uy" "$WarningLevel" "$Was" "$Wednesday")
|
||||
@@ -171,7 +171,7 @@
|
||||
"dusk" "easterdate" "escape" "eval" "evaltrig" "filedate" "filedatetime"
|
||||
"filedir" "filename" "getenv" "hebdate" "hebday" "hebmon" "hebyear" "hex"
|
||||
"hour" "htmlescape" "htmlstriptags" "iif" "index" "isany" "isconst" "isdst"
|
||||
"isleap" "isomitted" "language" "localtoutc" "lower" "max"
|
||||
"isleap" "isomitted" "ivritmon" "language" "localtoutc" "lower" "max"
|
||||
"mbasc" "mbindex" "mbstrlen" "mbsubstr" "min"
|
||||
"minsfromutc" "minute" "mon" "monnum" "moondate" "moondatetime"
|
||||
"moonphase" "moonrise" "moonrisedir" "moonset" "moonsetdir" "moontime"
|
||||
|
||||
140
docs/WHATSNEW
140
docs/WHATSNEW
@@ -1,5 +1,145 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 06.02.02 - 2026-01-10
|
||||
|
||||
- NEW FEATURE: remind: Turn reminders with a "Url:" INFO string into
|
||||
hyperlinks if you set the $TerminalHyperlinks system variable to 1.
|
||||
Note that your terminal must support the "OSC 8" hyperlink escape
|
||||
sequence; see
|
||||
https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
|
||||
for details.
|
||||
|
||||
For backward compatibility, the 'z' flag of the "-c" command-line
|
||||
option sets $TerminalHyperlinks to 1.
|
||||
|
||||
- NEW FEATURE: remind: Add another parameter to the "-w" option to
|
||||
remove blank lines between reminders, thereby making the calendar
|
||||
more compact.
|
||||
|
||||
- IMPROVEMENT: TkRemind: Make the window that pops up for background
|
||||
reminders obey the color options chosen under "Options..."
|
||||
|
||||
- CHANGE: remind: The header <wchar.h> and the functions mbstowcs and
|
||||
wcstombs are now mandatory. This should not affect any vaguely modern
|
||||
UNIX system.
|
||||
|
||||
- IMPROVEMENT: remind: Allow Hebrew spellings of Hebrew month names. For
|
||||
example, you can use "Iyar" or "אייר".
|
||||
|
||||
- IMPROVEMENT: remind: Allow different Hebrew transliterations of month names.
|
||||
For example, you can use "Shvat" or "Shevat". See the man page for
|
||||
the full list of possibilities.
|
||||
|
||||
- IMPROVEMENT: remind: Add the mbpad() function, which is the
|
||||
character-oriented counterpart to pad().
|
||||
|
||||
- MINOR NEW FEATURE: Add a "make uninstall-script" Makefile target. This
|
||||
generates a script that if run as root after "make install", will remove
|
||||
Remind.
|
||||
|
||||
- MINOR IMPROVEMENT: remind: Make COMPLETED-THROUGH a synonym for
|
||||
COMPLETE-THROUGH.
|
||||
|
||||
- BUG FIX: TkRemind: When we print a weekly calendar, make sure we start
|
||||
from the same date as the currently-displayed calendar.
|
||||
|
||||
- BUG FIX: remind: Fix an edge case where a REM command with a WARN function
|
||||
may not trigger on its actual trigger date.
|
||||
|
||||
- BUG FIX: include/holidays/jewish.rem: Split Chanukah into separate
|
||||
reminders to improve iCal export.
|
||||
|
||||
- DOC FIX: remind.1: Fix bad man page formatting.
|
||||
|
||||
- DOC FIX: Document that now() returns 00:00 in Calendar Mode.
|
||||
|
||||
* VERSION 06.02.01 - 2025-11-10
|
||||
|
||||
- BUG FIX: remind: Obey $ParseUntriggered in Calendar Mode. Before,
|
||||
$ParseUntriggered was always being treated as 1 in Calendar Mode.
|
||||
|
||||
- BUG FIX: TkRemind: Fix some buggy interactions between the Options
|
||||
dialog and the font chooser.
|
||||
|
||||
- TEST FIX: One test was consistently failing under MUSL, and it is
|
||||
not clear whether MUSL's or glibc's interpretation is correct.
|
||||
Remove that test so all tests pass under MUSL.
|
||||
|
||||
* VERSION 06.02.00 - 2025-11-03
|
||||
|
||||
- MAJOR NEW FEATURE: TkRemind: A new "View..." menu lets you choose a
|
||||
calendar view from the following choices: Entire month, 1 week, 2
|
||||
weeks or 4 weeks.
|
||||
|
||||
- NEW FEATURE: remind: The "z" flag for the "-c" option makes Remind
|
||||
turn reminders with a "Url:" INFO string into clickable hyperlinks.
|
||||
Note that your terminal must support the escape sequences at
|
||||
https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
|
||||
for this feature to work.
|
||||
|
||||
- IMPROVEMENT: TkRemind: The Print dialog now allows you to preview
|
||||
(and if you wish, adjust) the command used to print a calendar.
|
||||
|
||||
- IMPROVEMENT: TkRemind: The Agenda Mode window ("Show Today's
|
||||
Reminders") has navigation buttons for moving back or forward one
|
||||
day at a time.
|
||||
|
||||
- IMPROVEMENT: TkRemind: Add many keyboard shortcuts. All pop-up
|
||||
windows can be closed with Esc or Control-W. Other shortcuts are
|
||||
documented in the tkremind man page.
|
||||
|
||||
- CHANGE: TkRemind: If you hand-edit a reminder in the "Preview
|
||||
Reminder" dialog box, it is marked as non-editable by TkRemind.
|
||||
|
||||
- CHANGE: TkRemind: Remove support for rem2ps. All printing is now
|
||||
done using rem2pdf.
|
||||
|
||||
- IMPROVEMENT: remind: Improve error reporting if there's extraneous
|
||||
content after an expression.
|
||||
|
||||
- IMPROVEMENT: tests: test-rem was tweaked to allow testing of an
|
||||
installed Remind installation. This work was done by Jochen
|
||||
Sprickerhof.
|
||||
|
||||
- IMPROVEMENT: rem2pdf: When rendering weekly calendars, reduce the
|
||||
default size when drawing moons; if a day does not have a moon
|
||||
indicator, don't leave a big gap before the first reminder entry.
|
||||
|
||||
- IMPROVEMENT: rem2pdf: Draw moon phases left-aligned.
|
||||
|
||||
- IMPROVEMENT: rem2pdf: For weekly calendars with 4 weeks per page,
|
||||
make all of the boxes the same height.
|
||||
|
||||
- DOCUMENTATION IMPROVEMENT: remind: Document the INFO strings that
|
||||
back-ends should strive to support (Url:, Location: and
|
||||
Description:)
|
||||
|
||||
- BUG FIX: TkRemind: Bind the Home/End/PgUp/PgDn keys on the numeric
|
||||
keyboard for navigation.
|
||||
|
||||
- FIX: Don't enable -ffat-lto-objects on FreeBSD.
|
||||
|
||||
- BUG FIX: remind: Don't segfault if we can't open a .purged output
|
||||
file in purge mode.
|
||||
|
||||
- BUG FIX: rem2pdf: Make PANGO @x,y positioning consistent between
|
||||
weekly and monthly calendars. NOTE: If you use absolute PANGO
|
||||
positioning, you might need to adjust your script because positions
|
||||
are now relative to the centers of the grid lines.
|
||||
|
||||
* VERSION 06.01.08 - 2025-10-27
|
||||
|
||||
- BUG FIXES: tkremind: Fix many bugs with modal dialogs: Clicking too fast
|
||||
to launch them could cause error messages; closing them with the window
|
||||
manager "close" button rather than "Cancel" could cause errors. Thanks
|
||||
to Tug Williams for finding these bugs.
|
||||
|
||||
- MINOR NEW FEATURE: tkremind: The "Print" dialog has a "Show Command"
|
||||
button that lets you cut-and-paste the command tkremind would have used
|
||||
for printing. You can then customize it as you like.
|
||||
|
||||
- MINOR FIXES: remind: A few silly errors in the man page were fixed.
|
||||
|
||||
* VERSION 06.01.07 - 2025-10-23
|
||||
|
||||
- IMPROVEMENT: tkremind: Add a "help" button that pops up the TkRemind man
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
# "#PSSTUFF" for nifty PostScript examples #
|
||||
# #
|
||||
# This file is part of REMIND. #
|
||||
# Copyright (C) 1992-2025 Dianne Skoll #
|
||||
# Copyright (C) 1992-2026 Dianne Skoll #
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Not all sequences are supported by all terminals.
|
||||
|
||||
# This file is part of REMIND
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
if !defined("ansi_bold")
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
# Localize if we can
|
||||
IF access($SysInclude + "/translations/" + _("LANGID") + "/holidays/chinese-new-year.rem", "r") >= 0
|
||||
SYSINCLUDE translations/[_("LANGID")]/holidays/chinese-new-year.rem
|
||||
ENDIF
|
||||
|
||||
REM 1 Feb 2022 INFO "Url: https://en.wikipedia.org/wiki/Tiger_(zodiac)" MSG %"%(Chinese New Year) (%(Tiger))%" %! %b.
|
||||
REM 22 Jan 2023 INFO "Url: https://en.wikipedia.org/wiki/Rabbit_(zodiac)" MSG %"%(Chinese New Year) (%(Rabbit))%" %! %b.
|
||||
REM 10 Feb 2024 INFO "Url: https://en.wikipedia.org/wiki/Dragon_(zodiac)" MSG %"%(Chinese New Year) (%(Dragon))%" %! %b.
|
||||
|
||||
@@ -37,10 +37,19 @@ REM [hebdate(21, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Hoshana_Ra
|
||||
REM [hebdate(22, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Shemini_Atzeret" MSG %"Shemini Atzeret%" %! %b.
|
||||
REM [_h2I(22, "Tishrey")] INFO "Url: https://en.wikipedia.org/wiki/Simchat_Torah" MSG %"Simchat Torah%" %! %b.
|
||||
|
||||
# If the reminder has expired, $T can be zero, hence the
|
||||
# ($T || $U) below
|
||||
REM [hebdate(25, "Kislev",$U-9)] through [hebdate(25, "Kislev",$U-9)+7] \
|
||||
INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG %"Chanukah [($T || $U) - hebdate(25,"Kislev",$U-9) + 1]%" %! %b.
|
||||
# This reminder used to be done as a single reminder. I have split it
|
||||
# into 8 separate reminders because the "rem2dav" script uses
|
||||
# synthetic tags as UUIDs and it incorrectly coalesces the 8 days'
|
||||
# worth of reminders into a single 8-day reminder.
|
||||
|
||||
REM [hebdate(25, "Kislev", $U-9)] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG %"Chanukah 1%" %! %b.
|
||||
REM [hebdate(25, "Kislev", $U-9)+1] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG %"Chanukah 2%" %! %b.
|
||||
REM [hebdate(25, "Kislev", $U-9)+2] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG %"Chanukah 3%" %! %b.
|
||||
REM [hebdate(25, "Kislev", $U-9)+3] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG %"Chanukah 4%" %! %b.
|
||||
REM [hebdate(25, "Kislev", $U-9)+4] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG %"Chanukah 5%" %! %b.
|
||||
REM [hebdate(25, "Kislev", $U-9)+5] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG %"Chanukah 6%" %! %b.
|
||||
REM [hebdate(25, "Kislev", $U-9)+6] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG %"Chanukah 7%" %! %b.
|
||||
REM [hebdate(25, "Kislev", $U-9)+7] INFO "Url: https://en.wikipedia.org/wiki/Hanukkah" MSG %"Chanukah 8%" %! %b.
|
||||
|
||||
IF !Reform
|
||||
REM [hebdate(10, "Tevet")] INFO "Url: https://en.wikipedia.org/wiki/Tenth_of_Tevet" MSG %"Tzom Tevet%" %! %b.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the Catalan language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file was created by Eloi Torrents <eloitor@disroot.org>
|
||||
|
||||
TRANSLATE "LANGID" "ca"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the Danish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Mogens Lynnerup.
|
||||
|
||||
TRANSLATE "LANGID" "da"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the German language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Wolfgang Thronicke
|
||||
|
||||
TRANSLATE "LANGID" "de"
|
||||
@@ -73,34 +73,8 @@ FSET - subst_p(alt, d, t) iif(d == today()+1, "", "en")
|
||||
# Localization of various astronomical events
|
||||
|
||||
TRANSLATE "Perihelion" "Perihel"
|
||||
TRANSLATE "Vernal Equinox" "Frühlingsanfang"
|
||||
TRANSLATE "Summer Solstice" "Sommeranfang"
|
||||
TRANSLATE "Aphelion" "Aphel"
|
||||
TRANSLATE "Autumnal Equinox" "Herbstanfang"
|
||||
TRANSLATE "Winter Solstice" "Winteranfang"
|
||||
TRANSLATE "Daylight Saving Time Starts" "Beginn Sommerzeit"
|
||||
TRANSLATE "Daylight Saving Time Ends" "Ende Sommerzeit"
|
||||
|
||||
TRANSLATE "New Moon" "Neumond"
|
||||
TRANSLATE "First Quarter" "zunehmender Halbmond"
|
||||
TRANSLATE "Full Moon" "Vollmond"
|
||||
TRANSLATE "Last Quarter" "abnehmender Halbmond"
|
||||
|
||||
TRANSLATE "Chinese New Year" "Chinesisches Neujahr"
|
||||
TRANSLATE "Snake" "Schlange"
|
||||
TRANSLATE "Horse" "Pferd"
|
||||
TRANSLATE "Goat" "Ziege"
|
||||
TRANSLATE "Monkey" "Affe"
|
||||
TRANSLATE "Rooster" "Hahn"
|
||||
TRANSLATE "Dog" "Hund"
|
||||
TRANSLATE "Pig" "Schwein"
|
||||
TRANSLATE "Rat" "Ratte"
|
||||
TRANSLATE "Ox" "Ochse"
|
||||
TRANSLATE "Tiger" "Tiger"
|
||||
TRANSLATE "Rabbit" "Kaninchen"
|
||||
TRANSLATE "Dragon" "Drachen"
|
||||
|
||||
TRANSLATE "Sunrise" "Sonnenaufgang"
|
||||
TRANSLATE "Sunset" "Sonnenuntergang"
|
||||
|
||||
TRANSLATE "No reminders." "Keine Termine."
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Support for the English language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# Nothing to do for English since it is the default.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the Spanish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Rafa Couto <rafacouto@biogate.com>
|
||||
|
||||
TRANSLATE "LANGID" "es"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the Finnish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Mikko Silvonen
|
||||
|
||||
TRANSLATE "LANGID" "fi"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the French language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Laurent Duperval
|
||||
|
||||
TRANSLATE "LANGID" "fr"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the Hellenic (Greek) language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by jarlaxl lamat (jarlaxl@freemail.gr)
|
||||
|
||||
TRANSLATE "LANGID" "gr"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the Icelanding language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Björn Davíðsson (bjossi@snerpa.is)
|
||||
|
||||
TRANSLATE "LANGID" "is"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the Italian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Valerio Aimale
|
||||
|
||||
TRANSLATE "LANGID" "it"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the Dutch language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Willem Kasdorp and Erik-Jan Vens
|
||||
|
||||
TRANSLATE "LANGID" "nl"
|
||||
@@ -65,33 +65,6 @@ FSET - subst_s(a, d, t) iif(day(d) == 1 || day(d) == 8, "e", day(d) < 20, "de",
|
||||
|
||||
FSET - ordx(n) n + "e"
|
||||
|
||||
TRANSLATE "New Moon" "Nieuwe maan"
|
||||
TRANSLATE "First Quarter" "Eerste kwartier"
|
||||
TRANSLATE "Full Moon" "Volle maan"
|
||||
TRANSLATE "Last Quarter" "Laatste kwartier"
|
||||
|
||||
TRANSLATE "Vernal Equinox" "Lente-equinox"
|
||||
TRANSLATE "Summer Solstice" "Zomerzonnewende"
|
||||
TRANSLATE "Autumnal Equinox" "Herfst-equinox"
|
||||
TRANSLATE "Winter Solstice" "Winterzonnewende"
|
||||
|
||||
TRANSLATE "Chinese New Year" "Chinees Nieuwjaar"
|
||||
TRANSLATE "Snake" "Slang"
|
||||
TRANSLATE "Horse" "Paard"
|
||||
TRANSLATE "Goat" "Geit"
|
||||
TRANSLATE "Monkey" "Aap"
|
||||
TRANSLATE "Rooster" "Haan"
|
||||
TRANSLATE "Dog" "Hond"
|
||||
TRANSLATE "Pig" "Varken"
|
||||
TRANSLATE "Rat" "Rat"
|
||||
TRANSLATE "Ox" "Os"
|
||||
TRANSLATE "Tiger" "Tijger"
|
||||
TRANSLATE "Rabbit" "Konijn"
|
||||
TRANSLATE "Dragon" "Draak"
|
||||
|
||||
TRANSLATE "Sunrise" "Zonsopgang"
|
||||
TRANSLATE "Sunset" "Zonsondergang"
|
||||
|
||||
TRANSLATE "No reminders." "Geen herinneringen."
|
||||
|
||||
TRANSLATE "Daylight Saving Time Begins" "Daglicht-sparende tijd begint"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the Norwegian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Trygve Randen
|
||||
|
||||
TRANSLATE "LANGID" "no"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the Polish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Jerzy Sobczyk
|
||||
|
||||
TRANSLATE "LANGID" "pl"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the (Brazilian) Portuguese language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Marco Paganini
|
||||
|
||||
TRANSLATE "LANGID" "pt"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support for the Romanian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2026 by Dianne Skoll
|
||||
# This file is derived from a translation by Liviu Daia
|
||||
|
||||
TRANSLATE "LANGID" "ro"
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
# Moon phases
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
# Localize if we can
|
||||
IF access($SysInclude + "/translations/" + _("LANGID") + "/moonphases.rem", "r") >= 0
|
||||
SYSINCLUDE translations/[_("LANGID")]/moonphases.rem
|
||||
ENDIF
|
||||
|
||||
IF $CalMode || $PsCal
|
||||
REM [moondate(0)] INFO "Url: https://en.wikipedia.org/wiki/New_moon" SPECIAL MOON 0 -1 -1 [moontime(0)]
|
||||
REM [moondate(1)] INFO "Url: https://en.wikipedia.org/wiki/Lunar_phase" SPECIAL MOON 1 -1 -1 [moontime(1)]
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
# Equinoxes and solstices
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
# Localize if we can
|
||||
IF access($SysInclude + "/translations/" + _("LANGID") + "/seasons.rem", "r") >= 0
|
||||
SYSINCLUDE translations/[_("LANGID")]/seasons.rem
|
||||
ENDIF
|
||||
|
||||
IF $LatDeg >= 0
|
||||
# Northern Hemisphere
|
||||
REM NOQUEUE [soleq(0)] INFO "Url: https://en.wikipedia.org/wiki/March_equinox" MSG %"%(Vernal Equinox)%" [$Is] %3.
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
# Sunrise and sunset
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
# Localize if we can
|
||||
IF access($SysInclude + "/translations/" + _("LANGID") + "/sun.rem", "r") >= 0
|
||||
SYSINCLUDE translations/[_("LANGID")]/sun.rem
|
||||
ENDIF
|
||||
|
||||
IF !$CalMode && !$PsCal
|
||||
REM NOQUEUE AT [sunrise()] MSG %"%"%(Sunrise) %! %2.
|
||||
REM NOQUEUE AT [sunset()] MSG %"%"%(Sunset) %! %2.
|
||||
|
||||
17
include/translations/README.txt
Normal file
17
include/translations/README.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
The files here contain additional translations for various files
|
||||
distributed with Remind.
|
||||
|
||||
If you create a file in $SysInclude whose name is "myfile.rem", then
|
||||
you can enable translation by putting this at the top of your
|
||||
file:
|
||||
|
||||
#===================================================================
|
||||
# Localize if we can
|
||||
IF access($SysInclude + "/translations/" + _("LANGID") + "/myfile.rem", "r") >= 0
|
||||
SYSINCLUDE translations/[_("LANGID")]/myfile.rem
|
||||
ENDIF
|
||||
#===================================================================
|
||||
|
||||
Then you can localize your file by putting appropriate TRANSLATION directives
|
||||
in the file $SysInclude/translations/<LC>/myfile.rem where <LC> is the
|
||||
two-character language code.
|
||||
13
include/translations/de/holidays/chinese-new-year.rem
Normal file
13
include/translations/de/holidays/chinese-new-year.rem
Normal file
@@ -0,0 +1,13 @@
|
||||
TRANSLATE "Chinese New Year" "Chinesisches Neujahr"
|
||||
TRANSLATE "Snake" "Schlange"
|
||||
TRANSLATE "Horse" "Pferd"
|
||||
TRANSLATE "Goat" "Ziege"
|
||||
TRANSLATE "Monkey" "Affe"
|
||||
TRANSLATE "Rooster" "Hahn"
|
||||
TRANSLATE "Dog" "Hund"
|
||||
TRANSLATE "Pig" "Schwein"
|
||||
TRANSLATE "Rat" "Ratte"
|
||||
TRANSLATE "Ox" "Ochse"
|
||||
TRANSLATE "Tiger" "Tiger"
|
||||
TRANSLATE "Rabbit" "Kaninchen"
|
||||
TRANSLATE "Dragon" "Drachen"
|
||||
4
include/translations/de/moonphases.rem
Normal file
4
include/translations/de/moonphases.rem
Normal file
@@ -0,0 +1,4 @@
|
||||
TRANSLATE "New Moon" "Neumond"
|
||||
TRANSLATE "First Quarter" "zunehmender Halbmond"
|
||||
TRANSLATE "Full Moon" "Vollmond"
|
||||
TRANSLATE "Last Quarter" "abnehmender Halbmond"
|
||||
4
include/translations/de/seasons.rem
Normal file
4
include/translations/de/seasons.rem
Normal file
@@ -0,0 +1,4 @@
|
||||
TRANSLATE "Vernal Equinox" "Frühlingsanfang"
|
||||
TRANSLATE "Summer Solstice" "Sommeranfang"
|
||||
TRANSLATE "Autumnal Equinox" "Herbstanfang"
|
||||
TRANSLATE "Winter Solstice" "Winteranfang"
|
||||
2
include/translations/de/sun.rem
Normal file
2
include/translations/de/sun.rem
Normal file
@@ -0,0 +1,2 @@
|
||||
TRANSLATE "Sunrise" "Sonnenaufgang"
|
||||
TRANSLATE "Sunset" "Sonnenuntergang"
|
||||
13
include/translations/nl/holidays/chinese-new-year.rem
Normal file
13
include/translations/nl/holidays/chinese-new-year.rem
Normal file
@@ -0,0 +1,13 @@
|
||||
TRANSLATE "Chinese New Year" "Chinees Nieuwjaar"
|
||||
TRANSLATE "Snake" "Slang"
|
||||
TRANSLATE "Horse" "Paard"
|
||||
TRANSLATE "Goat" "Geit"
|
||||
TRANSLATE "Monkey" "Aap"
|
||||
TRANSLATE "Rooster" "Haan"
|
||||
TRANSLATE "Dog" "Hond"
|
||||
TRANSLATE "Pig" "Varken"
|
||||
TRANSLATE "Rat" "Rat"
|
||||
TRANSLATE "Ox" "Os"
|
||||
TRANSLATE "Tiger" "Tijger"
|
||||
TRANSLATE "Rabbit" "Konijn"
|
||||
TRANSLATE "Dragon" "Draak"
|
||||
4
include/translations/nl/moonphases.rem
Normal file
4
include/translations/nl/moonphases.rem
Normal file
@@ -0,0 +1,4 @@
|
||||
TRANSLATE "New Moon" "Nieuwe maan"
|
||||
TRANSLATE "First Quarter" "Eerste kwartier"
|
||||
TRANSLATE "Full Moon" "Volle maan"
|
||||
TRANSLATE "Last Quarter" "Laatste kwartier"
|
||||
4
include/translations/nl/seasons.rem
Normal file
4
include/translations/nl/seasons.rem
Normal file
@@ -0,0 +1,4 @@
|
||||
TRANSLATE "Vernal Equinox" "Lente-equinox"
|
||||
TRANSLATE "Summer Solstice" "Zomerzonnewende"
|
||||
TRANSLATE "Autumnal Equinox" "Herfst-equinox"
|
||||
TRANSLATE "Winter Solstice" "Winterzonnewende"
|
||||
2
include/translations/nl/sun.rem
Normal file
2
include/translations/nl/sun.rem
Normal file
@@ -0,0 +1,2 @@
|
||||
TRANSLATE "Sunrise" "Zonsopgang"
|
||||
TRANSLATE "Sunset" "Zonsondergang"
|
||||
115
man/remind.1.in
115
man/remind.1.in
@@ -102,6 +102,10 @@ flag also enables the use of the UNICODE "left-to-right" mark that
|
||||
can fix up formatting problems with right-to-left languages in the calendar
|
||||
display.
|
||||
.TP
|
||||
.B 'z'
|
||||
has the effect of setting the system variable \fB$TerminalHyperlinks\fR
|
||||
to 1. See the documentation of this variable in the section "SYSTEM VARIABLES"
|
||||
.TP
|
||||
.B 'c'
|
||||
causes \fBRemind\fR to use VT100 escape sequences to approximate
|
||||
SPECIAL COLOR reminders. Note that this flag is kept for
|
||||
@@ -161,7 +165,7 @@ foreground color of a reminder and the background color of a cell,
|
||||
then you know what you are doing.
|
||||
.RE
|
||||
.TP
|
||||
.B \-w\fR\fIcol\fR[,\fIpad\fR[,\fIspc\fR]]]
|
||||
.B \-w\fR\fIcol\fR[,\fIpad\fR[,\fIspc\fR[,\fIspc2\fR]]]]
|
||||
The \fB\-w\fR option specifies the output width, padding and spacing
|
||||
of the formatted calendar output. \fICol\fR specifies the number of
|
||||
columns in the output device. If \fIcol\fR is not specified, or is
|
||||
@@ -192,7 +196,9 @@ have many reminders on certain days that make your calendar too large
|
||||
to fit on a page, you can try reducing \fIpad\fR to make the empty
|
||||
boxes smaller. \fISpc\fR specifies how many blank lines to leave
|
||||
between the day number and the first reminder entry. It defaults to
|
||||
1.
|
||||
1. \fIspc2\fR may be 0 or 1 and it specifies whether or not blank
|
||||
lines should be printed in between reminders on the same day. The
|
||||
default is 1, which causes the blank lines to be printed.
|
||||
.PP
|
||||
Any of \fIcol\fR, \fIpad\fR or \fIspc\fR can be omitted, providing you
|
||||
provide the correct number of commas. Don't use any spaces in the option.
|
||||
@@ -1485,6 +1491,15 @@ and description of a reminder like this:
|
||||
MSG Engineering meeting
|
||||
.fi
|
||||
.PP
|
||||
While back-ends can choose which INFO strings to support, all back-ends
|
||||
should endeavor to support three standard ones: \fBLocation:\fR,
|
||||
\fBDescription:\fR and \fBUrl:\fR. TkRemind supports all three of these,
|
||||
turning reminders with a \fBUrl:\fR INFO string into hyper-links, and
|
||||
popping up information windows for the \fBLocation:\fR and \fBDescription:\fR
|
||||
INFO strings. \fBLocation:\fR and \fBUrl:\fR are self-explanatory;
|
||||
\fBDescription:\fR is meant for a longer, more in-depth description
|
||||
of the reminder than the summary that is normally displayed.
|
||||
.PP
|
||||
The \fBDURATION\fR keyword makes sense only for timed reminders; it
|
||||
specifies the duration of an event. For example, if you have a
|
||||
90-minute meeting starting at 1:00pm, you could use any of the following:
|
||||
@@ -1980,6 +1995,7 @@ reminding you of your 2027 taxes (starting 15 days before the due
|
||||
date.)
|
||||
.PP
|
||||
It is an error to specify COMPLETE-THROUGH without also specifying TODO.
|
||||
The keyword COMPLETED-THROUGH may be used as a synonym for COMPLETE-THROUGH.
|
||||
.PP
|
||||
.SH LIMITING REMINDERS ABOUT OVERDUE TODOS
|
||||
.PP
|
||||
@@ -3472,6 +3488,13 @@ 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.
|
||||
.TP
|
||||
.B $TerminalHyperlinks (INT type)
|
||||
If your terminal supports escape sequences to allow HTML-like
|
||||
anchors around text (see https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda), then you can set this variable to 1. \fBRemind\fR will then
|
||||
make any reminder with a "Url:" info string into a hyperlink in your
|
||||
terminal. By default, \fB$TerminalHyperlinks\fR is set to zero because
|
||||
not all terminals support this feature.
|
||||
.TP
|
||||
.B $WarningLevel (STRING type)
|
||||
As new versions of \fBRemind\fR are released, new warnings may be added.
|
||||
If your formerly-fine scripts suddenly start issuing warnings when you
|
||||
@@ -3833,9 +3856,10 @@ integer.
|
||||
.TP
|
||||
.B columns([s_arg])
|
||||
If called with no arguments, \fBcolumns()\fR behaves as follows:
|
||||
If standard output is a TTY, returns the width of the terminal in columns.
|
||||
If standard output is not a TTY, attempts to open "/dev/tty" to obtain
|
||||
the terminal size. If this fails, returns -1.
|
||||
If either standard output or standard error is a TTY, returns the
|
||||
width of the terminal in columns. If neither standard output nor
|
||||
standard error is a TTY, attempts to open "/dev/tty" to obtain the
|
||||
terminal size. If this fails, returns -1.
|
||||
.RS
|
||||
.PP
|
||||
If called with a single string argument, \fBcolumns(str)\fR returns
|
||||
@@ -4127,10 +4151,10 @@ Returns an \fBINT\fR that is the location of \fItarget\fR in the
|
||||
string \fIsearch\fR. Note that \fBindex\fR uses \fIbyte\fR positions,
|
||||
not character positions, so should not be used on non-ASCII strings. Use
|
||||
\fBmbindex\fR for non-ASCII strings.
|
||||
.RS
|
||||
.PP
|
||||
The first byte of a string is numbered 1. If \fItarget\fR does not
|
||||
exist in \fIsearch\fR, then 0 is returned.
|
||||
.RS
|
||||
.PP
|
||||
The optional parameter \fIstart\fR specifies the position in
|
||||
\fIsearch\fR at which to start looking for \fItarget\fR.
|
||||
@@ -4483,7 +4507,8 @@ to be considered \fInon-constant\fR. For details, see the section
|
||||
.TP
|
||||
.B now()
|
||||
Returns the current system time, as a \fBTIME\fR type. This may be
|
||||
the actual time, or a time supplied on the command line.
|
||||
the actual time, or a time supplied on the command line. Note that
|
||||
in Calendar Mode, \fBnow()\fR always returns 00:00.
|
||||
.TP
|
||||
.B ord(i_num)
|
||||
Returns a string that is the ordinal number \fInum\fR. For example,
|
||||
@@ -4514,8 +4539,8 @@ any longer.
|
||||
.TP
|
||||
.B pad(x_arg, s_padstr, i_len [, i_right])
|
||||
Converts the first argument \fIarg\fR to a string if necessary, and
|
||||
then if it is shorter than \fIlen\fR characters, pads to to
|
||||
\fIlen\fR characters using as many copies (including partial copies)
|
||||
then if it is shorter than \fIlen\fR bytes, pads to to
|
||||
\fIlen\fR bytes using as many copies (including partial copies)
|
||||
of \fIpadstr\fR as necessary. By default, the string is left-padded,
|
||||
but if \fIright\fR is supplied and non-zero, the string will
|
||||
be right-padded.
|
||||
@@ -4532,6 +4557,11 @@ Here are some examples:
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B mbpad(x_arg, s_padstr, i_len [, i_right])
|
||||
This is the multibyte counterpart to \fBpad\fR. The length is
|
||||
specified in characters rather than bytes. Use \fBmbpad\fR rather
|
||||
than \fBpad\fR if either of the strings contains non-ASCII characters.
|
||||
.TP
|
||||
.B plural(i_num [,s_str1 [,s_str2]])
|
||||
Can take from one to three arguments. If one argument is supplied, returns
|
||||
@@ -4610,7 +4640,7 @@ may return a time supplied on the command line.
|
||||
.B realnow()
|
||||
Returns the true time of day as provided by the operating system.
|
||||
This is in contrast to \fBnow()\fR, which may return a time supplied
|
||||
on the command line.
|
||||
on the command line, or 00:00 in Calendar Mode.
|
||||
.TP
|
||||
.B realtoday()
|
||||
Returns the date as provided by the operating system. This is in contrast to
|
||||
@@ -4618,9 +4648,10 @@ Returns the date as provided by the operating system. This is in contrast to
|
||||
in calendar mode, or if a date has been supplied on the command line.
|
||||
.TP
|
||||
.B rows()
|
||||
If standard output is a TTY, returns the height of the terminal in rows.
|
||||
If standard output is not a TTY, attempts to open "/dev/tty" to obtain
|
||||
the terminal size. If this fails, returns -1.
|
||||
If either standard output or standard error is a TTY, returns the
|
||||
height of the terminal in rows. If neither standard output nor
|
||||
standard error is a TTY, attempts to open "/dev/tty" to obtain the
|
||||
terminal size. If this fails, returns -1.
|
||||
.TP
|
||||
.B sgn(i_num)
|
||||
Returns \-1 if \fInum\fR is negative, 1 if \fInum\fR is positive,
|
||||
@@ -4808,9 +4839,9 @@ value of \fBcurrent()\fR. If a \fBDATE\fR rather than \fBDATETIME\fR
|
||||
is supplied, \fBRemind\fR uses a time part of 00:00.
|
||||
.TP
|
||||
.B today()
|
||||
Returns \fBRemind\fR's notion of "today." This may be the actual system
|
||||
date, or a date supplied on the command line, or the date of the
|
||||
calendar entry currently being computed.
|
||||
Returns \fBRemind\fR's notion of "today." This may be the actual
|
||||
system date, or a date supplied on the command line, or (in Calendar
|
||||
Mode) the date of the calendar entry currently being computed.
|
||||
.TP
|
||||
.B trig(s_1 [,s_2, ...])
|
||||
For each string argument s_\fIn\fR, \fBtrig\fR evaluates s_\fIn\fR
|
||||
@@ -5313,8 +5344,7 @@ expressions are evaluated only once, not recursively. Thus, writing:
|
||||
.fi
|
||||
.PP
|
||||
causes \fBRemind\fR to read the token "[a+b]". It does not interpret
|
||||
this as a pasted-in expression. In fact, the only way to get a literal
|
||||
left-bracket into a reminder is to use ["["].
|
||||
this as a pasted-in expression.
|
||||
.PP
|
||||
You can use expression pasting almost anywhere. However, there are a few
|
||||
exceptions:
|
||||
@@ -5601,8 +5631,6 @@ following example:
|
||||
# FSET -f(x) 2*x
|
||||
.fi
|
||||
.PP
|
||||
to define a function and suppress any "redefined function" warning.
|
||||
.PP
|
||||
.SH SAVING AND RESTORING FUNCTIONS
|
||||
.PP
|
||||
Occasionally, it is useful to redefine a function for a specific block of
|
||||
@@ -6907,14 +6935,43 @@ jahrzeits (anniversaries of deaths) and smachot (joyous occasions.)
|
||||
.PP
|
||||
.B THE HEBREW YEAR
|
||||
.PP
|
||||
The Hebrew year has 12 months, alternately 30 and 29 days long. The months
|
||||
are: Tishrey, Heshvan, Kislev, Tevet, Shvat, Adar, Nisan, Iyar, Sivan, Tamuz,
|
||||
Av and Elul. In Biblical times, the year started in Nisan, but Rosh Hashana
|
||||
(Jewish New Year) is now celebrated on the 1st and 2nd of Tishrey.
|
||||
The Hebrew year has 12 months, alternately 30 and 29 days long. The
|
||||
months are: Tishrey, Heshvan, Kislev, Tevet, Shvat, Adar, Nisan, Iyar,
|
||||
Sivan, Tamuz, Av and Elul. If you are in a UTF-8 locale, you can
|
||||
\fIalso\fR use the UTF-8-encoded Hebrew spellings for the month names,
|
||||
namely:
|
||||
.PP
|
||||
תשרי, חשוון, כסלו, טבת, שבט, אדר, ניסן, אייר, סיון, תמוז, אב, אלול.
|
||||
.PP
|
||||
In a cycle of 19 years, there are 7 leap years, being years 3, 6, 8, 11,
|
||||
14, 17 and 19 of the cycle. In a leap year, an extra month of 30 days
|
||||
is added before Adar. The two Adars are called Adar A and Adar B.
|
||||
is added before Adar. The two Adars are called Adar A and Adar B,
|
||||
or in Hebrew, 'אדר א and 'אדר ב.
|
||||
.PP
|
||||
\fBRemind\fR also permits the following alternative spellings for
|
||||
Hebrew month names:
|
||||
.TP
|
||||
.B Tishrey
|
||||
Can also be spelled Tishri or Tishrei
|
||||
.TP
|
||||
.B Heshvan
|
||||
Can also be spelled Cheshvan or Kheshvan
|
||||
.TP
|
||||
.B Shvat
|
||||
Can also be spelled Shevat
|
||||
.TP
|
||||
.B Tamuz
|
||||
Can also be spelled Tammuz
|
||||
.TP
|
||||
.B Adar A
|
||||
Can also be spelled Adar 1, Adar I, אדר א or אדר 1.
|
||||
.TP
|
||||
.B Adar B
|
||||
Can also be spelled Adar 2, Adar II, אדר ב or אדר 2.
|
||||
.TP
|
||||
.B Iyar
|
||||
Can also be spelled Iyyar.
|
||||
|
||||
.PP
|
||||
For certain religious reasons, the year cannot start on a Sunday, Wednesday
|
||||
or Friday. To adjust for this, a day is taken off Kislev or added to Heshvan.
|
||||
@@ -6944,6 +7001,11 @@ Thus, hebday('1993/04/12') returns 21.
|
||||
Returns the name of the Hebrew month corresponding to \fIdate\fR.
|
||||
For example, hebmon('1993/04/12') returns "Nisan".
|
||||
.TP
|
||||
.B ivritmon(d_date)
|
||||
Returns the name of the Hebrew month corresponding to \fIdate\fR,
|
||||
in UTF-8-encoded Hebrew script. For example, ivritmon('1993/04/12')
|
||||
returns "ניסן".
|
||||
.TP
|
||||
.B hebyear(d_date)
|
||||
Returns the Hebrew year corresponding to \fIdate\fR. For example,
|
||||
hebyear('1993/04/12') returns 5753.
|
||||
@@ -6957,7 +7019,8 @@ corresponding to the Hebrew date.
|
||||
The \fIday\fR parameter can range from 1 to 30, and specifies the day of
|
||||
the Hebrew month. The \fIhebmon\fR parameter is a string that must name
|
||||
one of the Hebrew months specified above. Note that the month must be spelled
|
||||
out in full, and use the English transliteration shown previously. You can
|
||||
out in full, and use either the English transliteration shown previously, or
|
||||
the Hebrew spelling \fIencoded in UTF-8\fR. You can
|
||||
also specify "Adar A" and "Adar B." Month names are not case-sensitive.
|
||||
.PP
|
||||
The \fIyrstart\fR parameter can either be a \fBDATE\fR or an \fBINT\fR. If
|
||||
|
||||
@@ -61,15 +61,32 @@ box appears completely full.
|
||||
.SH NAVIGATING
|
||||
To change to the previous or next month, click the \fB<\-\fR
|
||||
or \fB\->\fR button, respectively. You can also use the left/right arrow
|
||||
keys or PageUp/PageDown to navigate.
|
||||
keys or \fBPgUp\fR/\fBPgDn\fR to navigate.
|
||||
|
||||
To change back to the current month, click \fBToday\fR or press the
|
||||
Home key. To go to a specific month, click \fBGo To Date...\fR. This
|
||||
pops up a dialog box which allows you to select a month and enter a
|
||||
year. Once you've done this, click \fBGo\fR to go to the date, or
|
||||
\fBCancel\fR to cancel.
|
||||
\fBHome\fR key. To go to a specific month, click \fBGo To Date...\fR
|
||||
or press \fBg\fR. This pops up a dialog box which allows you to
|
||||
select a month and enter a year. Once you've done this, click
|
||||
\fBGo\fR to go to the date, or \fBCancel\fR to cancel. Note also that
|
||||
all pop-up windows in \fBTkRemind\fR can be dismissed by pressing
|
||||
\fBEsc\fR or \fBControl-w\fR.
|
||||
|
||||
To exit \fBTkRemind\fR, click \fBQuit\fR.
|
||||
To exit \fBTkRemind\fR, click \fBQuit\fR or press \fBControl-q\fR..
|
||||
|
||||
.SH CHANGING THE VIEW
|
||||
By default, \fBTkRemind\fR shows the calendar for an entire month.
|
||||
The \fBView...\fR menu lets you pick from the following choices: Display
|
||||
an entire month, or display one, two or four weeks' worth of reminders.
|
||||
If you change the view, \fBTkRemind\fR remembers the change and that
|
||||
view becomes the default view next time you start \fBTkRemind\fR
|
||||
|
||||
In the monthly view, the Next and Previous navigation buttons and keyboard
|
||||
shortcuts move by one month. In all other views, they move by one week.
|
||||
This is true even for views that display multiple weeks.
|
||||
|
||||
You can press the keys \fB1\fR, \fB2\fR, \fB4\fR or \fBm\fR over the
|
||||
main calendar window to change the view to one week, two weeks, four weeks
|
||||
or one month, respectively.
|
||||
|
||||
.SH ADDING REMINDERS
|
||||
To add a reminder, click button 1 in any day number in the calendar.
|
||||
@@ -127,23 +144,37 @@ reminder you entered using the \fBAdd Reminder...\fR dialog. You can
|
||||
edit the reminder, thereby gaining access to advanced features of
|
||||
\fBRemind\fR. You can also use it simply to play around and discover
|
||||
\fBRemind\fR's idioms for expressing different types of reminders.
|
||||
.PP
|
||||
\fBNOTE\fR: If you hand-edit a reminder, then that reminder will
|
||||
\fInot\fR be editable in TkRemind's graphical reminder dialog any more.
|
||||
You will have to hand-edit it to change it.
|
||||
|
||||
.SH SEEING A SINGLE DAY'S REMINDERS
|
||||
Right-click on any day number in the calendar to pop up a window with
|
||||
that day's reminders in Agenda Mode. You can left- or right-click the
|
||||
current date and time indicator at the bottom of the window to see today's
|
||||
reminders in Agenda Mode.
|
||||
current date and time indicator at the bottom of the calendar window
|
||||
to see today's reminders in Agenda Mode. You can also press \fBt\fR
|
||||
over the main calendar window to see today's reminders in Agenda Mode.
|
||||
|
||||
In the Agenda Mode display, hovering over a reminder will show ancillary
|
||||
information such as a Location, URL or Description. Clicking on a reminder
|
||||
will open an editor on the REM command that created the reminder.
|
||||
will open an editor on the REM command that created the reminder. You can
|
||||
also navigate in the Agenda Mode window one day at a time using the
|
||||
forward and back arrow buttons or left/right arrow keys or \fBPgUp\fR/\fBPgDn\fR.
|
||||
You can get back to today by clicking \fBToday\fR or pressing the
|
||||
\fBHome\fR key.
|
||||
|
||||
You can dismiss the Agenda Mode window by clicking \fBOK\fR or pressing
|
||||
the \fBEsc\fR key.
|
||||
|
||||
.SH PRINTING
|
||||
To print the current month's calendar, click \fBPrint...\fR on the
|
||||
main calendar window. This brings up the print dialog. Printing
|
||||
either produces a PostScript file or sends PostScript to a UNIX command.
|
||||
(If you have \fBrem2pdf\fR installed, you can choose to produce
|
||||
PDF output rather than PostScript.)
|
||||
main calendar window or press \fBp\fR or \fBControl-p\fR. This brings
|
||||
up the print dialog. Printing either produces a PostScript or PDF
|
||||
file, or sends PostScript or PDF to a UNIX command.
|
||||
|
||||
Note that you must have \fBrem2pdf\fR installed in order to be
|
||||
able to print.
|
||||
|
||||
Select the print destination by choosing either \fBTo file:\fR or
|
||||
\fBTo command:\fR in the print dialog. Press \fBBrowse...\fR to bring
|
||||
@@ -160,7 +191,7 @@ the directory.
|
||||
Select the appropriate paper size and orientation. Activate
|
||||
\fBFill page\fR if you want the calendar to fill the page. This should
|
||||
be the normal case unless you have many reminders in a particular
|
||||
day. (See the \fBRem2PS\fR or \fBrem2pdf\fR documentation.)
|
||||
day. (See the \fBrem2pdf\fR documentation.)
|
||||
|
||||
Finally, click \fBPrint\fR to print or \fBCancel\fR to cancel. Note
|
||||
that during printing, \fBRemind\fR is called with the
|
||||
@@ -168,6 +199,12 @@ that during printing, \fBRemind\fR is called with the
|
||||
option. If you are producing PDF output, then the option \fB-itkpdf=1\fR
|
||||
is also supplied to \fBRemind\fR.
|
||||
|
||||
If you click on \fBShow Command\fR rather than \fBPrint\fR, then
|
||||
\fBTkRemind\fR won't actually print anything. Instead, it will pop
|
||||
up a text window with the command that it \fIwould have used\fR to print
|
||||
the calendar. You can adjust the command as needed and then click \fBRun\fR
|
||||
to run the modified command. This lets you specify \fBrem2pdf\fR options
|
||||
that are not directly supported by \fBTkRemind\fR.
|
||||
|
||||
.SH EDITING REMINDERS
|
||||
|
||||
@@ -181,13 +218,11 @@ reminder entirely by selecting \fBDelete reminder\fR. The remaining
|
||||
buttons, \fBPreview reminder\fR and \fBCancel\fR operate identically
|
||||
to the dialog in "ADDING REMINDERS."
|
||||
|
||||
Note that if you edit a reminder (using \fBPreview reminder\fR),
|
||||
any edits you made are \fInot\fR retained in the dialog box. You
|
||||
should not attempt to edit such reminders; you have to retype them
|
||||
in the \fBPreview reminder\fR dialog.
|
||||
|
||||
If the reminder was not created with \fBTkRemind\fR, you can't edit
|
||||
it with \fBTkRemind\fR.
|
||||
Note that if you have hand-edited a reminder (using \fBPreview
|
||||
reminder\fR), or if the reminder was hand-created in the first place,
|
||||
then clicking on it will \fInot\fR pop up the TkRemind
|
||||
reminder-editing dialog. Instead, TkRemind will start up a text
|
||||
editor (if you have configured one) so you can hand-edit the reminder.
|
||||
|
||||
.SH USING A TEXT EDITOR
|
||||
|
||||
@@ -230,7 +265,8 @@ option of "turning off" the reminder for the rest of the day.
|
||||
.SH OPTIONS
|
||||
|
||||
The final button on the calendar window, \fBOptions\fR, lets you configure
|
||||
certain aspects of \fBTkRemind\fR. The configuration options are:
|
||||
certain aspects of \fBTkRemind\fR. You can also pop up the options
|
||||
window by pressing \fBo\fR. The configuration options are:
|
||||
|
||||
.TP
|
||||
.B Start up Iconified
|
||||
@@ -323,22 +359,6 @@ press \fBApply Options\fR to put them into effect, \fBSave Options\fR
|
||||
to put them into effect and save them in $HOME/.config/tkremindrc, or
|
||||
\fBCancel\fR to cancel any changes you made.
|
||||
|
||||
.SH KEYBOARD SHORTCUTS
|
||||
\fBTkRemind\fR's main window includes the following keyboard shortcuts:
|
||||
|
||||
.TP
|
||||
.B Ctrl-Q
|
||||
Quit
|
||||
.TP
|
||||
.B Left Arrow
|
||||
Previous Month
|
||||
.TP
|
||||
.B Right Arrow
|
||||
Next Month
|
||||
.TP
|
||||
.B Home
|
||||
Today
|
||||
|
||||
.SH IMMEDIATE UPDATES
|
||||
|
||||
If you are running \fBTkRemind\fR on Linux and \fBRemind\fR has been
|
||||
@@ -542,7 +562,7 @@ asynchronous status messages.
|
||||
.SH AUTHOR
|
||||
TkRemind was written by Dianne Skoll <dianne@skoll.ca>
|
||||
|
||||
\fBTkRemind\fR is Copyright (C) 1996-2025 by Dianne Skoll.
|
||||
\fBTkRemind\fR is Copyright (C) 1996-2026 by Dianne Skoll.
|
||||
|
||||
.SH FILES
|
||||
|
||||
@@ -553,5 +573,5 @@ $HOME/.config/tkremindrc -- \fBTkRemind\fR saved options.
|
||||
.SH HOME PAGE
|
||||
https://dianne.skoll.ca/projects/remind/
|
||||
.SH SEE ALSO
|
||||
\fBremind\fR, \fBrem2ps\fR, \fBrem2pdf\fR, \fBrem2html\fR
|
||||
\fBremind\fR, \fBrem2pdf\fR, \fBrem2html\fR
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ my $settings = {
|
||||
title_url => '',
|
||||
title_size => 14,
|
||||
header_size => 12,
|
||||
daynum_size => 14,
|
||||
daynum_size => -1,
|
||||
entry_size => 8,
|
||||
|
||||
border_size => 4,
|
||||
@@ -526,7 +526,9 @@ Specify the size of the header font in 1/72ndths of an inch. The default is 14.
|
||||
=item --daynum-size=I<n>
|
||||
|
||||
Specify the size of the day number font in 1/72ndths of an inch. The
|
||||
default is 14.
|
||||
default is 14 for monthly calendars or 10 for weekly calendars. (Weekly
|
||||
calendars don't have day numbers in the calendar boxes, but this setting
|
||||
is used to scale the size of moon phase indicators.)
|
||||
|
||||
=item --entry-size=I<n>
|
||||
|
||||
@@ -683,7 +685,10 @@ of the right side of the calendar box.
|
||||
A positive I<y> value positions the top edge of the text I<y> points
|
||||
below the top of the calendar box, while a negative I<y> value
|
||||
positions the bottom edge of the text I<y> points above the bottom of
|
||||
the calendar box.
|
||||
the calendar box. Note that the coordinates are relative to the center
|
||||
of the lines that delineate the boxes; you should use an I<x> value
|
||||
whose absolute value is at least 2 and a I<y> value whose absolute
|
||||
value is at least 4 to avoid colliding with the lines.
|
||||
|
||||
If you use absolutely-positioned text, it's up to you to make sure it
|
||||
doesn't overlap other text; B<rem2pdf> takes no special precautions to
|
||||
@@ -692,7 +697,7 @@ prevent this.
|
||||
As an example, this places Sunrise and Sunset times at the bottom left
|
||||
of each calendar box:
|
||||
|
||||
REM SPECIAL PANGO @1,-1 <span size="4800"><i>Rise [sunrise($U)] Set [sunset($U)]</i></span>
|
||||
REM SPECIAL PANGO @2,-4 <span size="4800"><i>Rise [sunrise($U)] Set [sunset($U)]</i></span>
|
||||
|
||||
(Note that Pango expresses font sizes in 1024's of a point, so a size of
|
||||
4800 works out to about 4.6 points.)
|
||||
|
||||
@@ -468,6 +468,9 @@ sub render
|
||||
{
|
||||
my ($self, $cr, $settings, $index, $total) = @_;
|
||||
|
||||
if ($settings->{daynum_size} < 0) {
|
||||
$settings->{daynum_size} = 14;
|
||||
}
|
||||
if ($settings->{svg} || $settings->{eps}) {
|
||||
if ($index > 1) {
|
||||
if ($index == 2) {
|
||||
@@ -628,7 +631,7 @@ sub col_box_coordinates
|
||||
$settings->{margin_left} + $cell * $col,
|
||||
$so_far,
|
||||
$settings->{margin_left} + $cell * ($col + 1),
|
||||
$so_far + $height + $settings->{border_size},
|
||||
$so_far + $height + 2* $settings->{border_size},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -663,7 +666,7 @@ sub draw_day
|
||||
$cr->set_source_rgb($shade->{r} / 255,
|
||||
$shade->{g} / 255,
|
||||
$shade->{b} / 255);
|
||||
$cr->rectangle($x1, $y1, $x2 - $x1, $y2 - $y1 + $settings->{border_size});
|
||||
$cr->rectangle($x1, $y1, $x2 - $x1, $y2 - $y1);
|
||||
$cr->fill();
|
||||
$cr->restore;
|
||||
}
|
||||
@@ -1111,6 +1114,9 @@ Remind::PDF::Weekly - render a weekly calendar
|
||||
sub render
|
||||
{
|
||||
my ($self, $cr, $settings, $index, $total) = @_;
|
||||
if ($settings->{daynum_size} < 0) {
|
||||
$settings->{daynum_size} = 10;
|
||||
}
|
||||
if ($settings->{svg} || $settings->{eps}) {
|
||||
if ($index > $settings->{weeks_per_page}) {
|
||||
if ($index == $settings->{weeks_per_page}+1) {
|
||||
@@ -1130,7 +1136,7 @@ sub render
|
||||
}
|
||||
}
|
||||
|
||||
$settings->{numbers_on_left} = 1;
|
||||
$settings->{numbers_on_left} = 0;
|
||||
# Set up bounding box
|
||||
if ($settings->{weeks_per_page} == 1) {
|
||||
$self->{bounding_box} = [
|
||||
@@ -1139,22 +1145,16 @@ sub render
|
||||
$settings->{width} - $settings->{margin_right},
|
||||
$settings->{height} - $settings->{margin_bottom}]
|
||||
} else {
|
||||
my $gap = $settings->{margin_top} * 0.5;
|
||||
my $total_height = $settings->{height} - $settings->{margin_top} - $settings->{margin_bottom};
|
||||
my $week_height = $total_height / $settings->{weeks_per_page};
|
||||
my $top_offset = (($index-1) % $settings->{weeks_per_page}) * $week_height;
|
||||
my $week_height = ($total_height - $gap * ($settings->{weeks_per_page}-1)) / $settings->{weeks_per_page};
|
||||
my $top_offset = ((($index-1) % $settings->{weeks_per_page}) * $week_height) + (($index-1) % $settings->{weeks_per_page}) * $gap;
|
||||
my $bot_offset = $top_offset + $week_height;
|
||||
$self->{bounding_box} =
|
||||
$self->{bounding_box} = [
|
||||
$settings->{margin_left},
|
||||
$settings->{margin_top} + $top_offset,
|
||||
$settings->{width} - $settings->{margin_right},
|
||||
$settings->{margin_top} + $bot_offset];
|
||||
if ($index != 1) {
|
||||
$self->{bounding_box}[1] += 0.25 * $settings->{margin_top};
|
||||
}
|
||||
if ($index != $settings->{weeks_per_page}) {
|
||||
$self->{bounding_box}[3] -= 0.25 * $settings->{margin_top};
|
||||
}
|
||||
$self->{bounding_box} = [
|
||||
$settings->{margin_left},
|
||||
$settings->{margin_top} + $top_offset,
|
||||
$settings->{width} - $settings->{margin_right},
|
||||
$settings->{margin_top} + $bot_offset];
|
||||
}
|
||||
$self->draw_headings($cr, $settings);
|
||||
for (my $i=0; $i<7; $i++) {
|
||||
@@ -1262,7 +1262,13 @@ sub draw_entries
|
||||
$layout->set_font_description($desc);
|
||||
my ($wid, $h) = $layout->get_pixel_size();
|
||||
|
||||
my $so_far = $box->[1] + $h + $settings->{border_size};
|
||||
my $so_far = $box->[1] + $settings->{border_size};
|
||||
foreach my $entry (@{$self->{entries}->[$i]}) {
|
||||
if ($entry->isa('Remind::PDF::Entry::moon')) {
|
||||
$so_far = $box->[1] + $h + $settings->{border_size};
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
my $box_height = $box->[3] - $box->[1];
|
||||
my $done = 0;
|
||||
|
||||
@@ -152,7 +152,7 @@ sub render
|
||||
|
||||
$cr->save();
|
||||
Remind::PDF->set_cr_color($cr, $settings->{daynum_color});
|
||||
$cr->move_to($x2 - $settings->{border_size}/2 - $wid, $y2 + $settings->{border_size} - $h);
|
||||
$cr->move_to($x2 - $settings->{border_size}/2 - $wid, $y2 - $h);
|
||||
my $url;
|
||||
if ($self->{info} && $self->{info}->{url}) {
|
||||
$url = $self->{info}->{url};
|
||||
|
||||
1286
scripts/tkremind.in
1286
scripts/tkremind.in
File diff suppressed because it is too large
Load Diff
208
src/calendar.c
208
src/calendar.c
@@ -5,7 +5,7 @@
|
||||
/* The code for generating a calendar. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -23,10 +23,8 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LANGINFO_H
|
||||
#include <langinfo.h>
|
||||
@@ -44,10 +42,8 @@ typedef struct cal_entry {
|
||||
char *text;
|
||||
char *raw_text;
|
||||
char const *pos;
|
||||
#ifdef REM_USE_WCHAR
|
||||
wchar_t *wc_text;
|
||||
wchar_t const *wc_pos;
|
||||
#endif
|
||||
int is_color;
|
||||
int r, g, b;
|
||||
int time;
|
||||
@@ -179,6 +175,17 @@ static char const *moonphase_emojis[] = {
|
||||
"\xF0\x9F\x8C\x97"
|
||||
};
|
||||
|
||||
/* Color weights for gamma-correction */
|
||||
unsigned char cwts[] = {
|
||||
0x46, 0x75, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20,
|
||||
0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x68, 0x6f, 0x62, 0x69, 0x63,
|
||||
0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52,
|
||||
0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x6e, 0x73, 0x2e,
|
||||
0x20, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x20, 0x72, 0x69, 0x67,
|
||||
0x68, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x68, 0x75, 0x6d,
|
||||
0x61, 0x6e, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2e
|
||||
};
|
||||
|
||||
/* Moon phases for each day 1-31, up to 32 chars per moon-phase string
|
||||
including termination \0 */
|
||||
static char moons[32][32];
|
||||
@@ -301,6 +308,7 @@ static void WriteTopCalLine (void);
|
||||
static void WriteBottomCalLine (void);
|
||||
static void WriteIntermediateCalLine (void);
|
||||
static void WriteCalDays (void);
|
||||
static char const *get_url(TrigInfo *infos);
|
||||
|
||||
static int
|
||||
DayOf(int dse)
|
||||
@@ -317,6 +325,9 @@ Backgroundize(int d)
|
||||
return;
|
||||
}
|
||||
|
||||
if (cwts[d] == 0) {
|
||||
return;
|
||||
}
|
||||
if (!UseBGVTColors) {
|
||||
return;
|
||||
}
|
||||
@@ -342,7 +353,6 @@ UnBackgroundize(int d)
|
||||
printf("%s", Decolorize());
|
||||
}
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
static void
|
||||
send_lrm(void)
|
||||
{
|
||||
@@ -357,7 +367,6 @@ send_lrm(void)
|
||||
printf("\xE2\x80\x8E");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static char const *
|
||||
despace(char const *s)
|
||||
@@ -514,7 +523,6 @@ static void PrintJSONKeyPairTime(char const *name, int t)
|
||||
|
||||
}
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
void PutWideChar(wchar_t const wc, DynamicBuffer *output)
|
||||
{
|
||||
char buf[MB_CUR_MAX+1];
|
||||
@@ -530,16 +538,11 @@ void PutWideChar(wchar_t const wc, DynamicBuffer *output)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static char const *
|
||||
get_month_abbrev(char const *mon)
|
||||
{
|
||||
static char buf[80];
|
||||
#ifndef REM_USE_WCHAR
|
||||
snprintf(buf, sizeof(buf), "%.3s", mon);
|
||||
return buf;
|
||||
#else
|
||||
char *s;
|
||||
wchar_t tmp_buf[128] = {0};
|
||||
wchar_t *ws;
|
||||
@@ -564,10 +567,8 @@ get_month_abbrev(char const *mon)
|
||||
}
|
||||
*s = 0;
|
||||
return buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
static int make_wchar_versions(CalEntry *e)
|
||||
{
|
||||
size_t len;
|
||||
@@ -584,7 +585,6 @@ static int make_wchar_versions(CalEntry *e)
|
||||
e->wc_pos = buf;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gon(void)
|
||||
{
|
||||
@@ -1337,14 +1337,6 @@ static int WriteCalendarRow(void)
|
||||
/***************************************************************/
|
||||
static void PrintLeft(char const *s, int width, char pad)
|
||||
{
|
||||
#ifndef REM_USE_WCHAR
|
||||
int len = strlen(s);
|
||||
int i;
|
||||
for (i=0; i<len && i<width; i++) {
|
||||
fputc(*(s+i), stdout);
|
||||
}
|
||||
while (i++ < width) putchar(pad);
|
||||
#else
|
||||
size_t len = mbstowcs(NULL, s, 0);
|
||||
int i;
|
||||
wchar_t static_buf[128];
|
||||
@@ -1395,8 +1387,6 @@ static void PrintLeft(char const *s, int width, char pad)
|
||||
i++;
|
||||
}
|
||||
if (buf != static_buf) free(buf);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1408,26 +1398,6 @@ static void PrintLeft(char const *s, int width, char pad)
|
||||
/***************************************************************/
|
||||
static void PrintCentered(char const *s, int width, char const *pad)
|
||||
{
|
||||
#ifndef REM_USE_WCHAR
|
||||
int len = strlen(s);
|
||||
int d = (width - len) / 2;
|
||||
int i;
|
||||
|
||||
for (i=0; i<d; i++) fputs(pad, stdout);
|
||||
for (i=0; i<width-d; i++) {
|
||||
if (*s) {
|
||||
if (isspace(*s)) {
|
||||
putchar(' ');
|
||||
s++;
|
||||
} else {
|
||||
putchar(*s++);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i=d+len; i<width; i++) fputs(pad, stdout);
|
||||
#else
|
||||
size_t len = mbstowcs(NULL, s, 0);
|
||||
int display_len;
|
||||
int i;
|
||||
@@ -1482,7 +1452,6 @@ static void PrintCentered(char const *s, int width, char const *pad)
|
||||
i++;
|
||||
}
|
||||
if (buf != static_buf) free(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1535,6 +1504,14 @@ static int WriteOneCalLine(int start_dse, int wd)
|
||||
return done;
|
||||
}
|
||||
|
||||
static void FreeCalEntry(CalEntry *e)
|
||||
{
|
||||
if (e->text) free(e->text);
|
||||
if (e->raw_text) free(e->raw_text);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* WriteOneColLine */
|
||||
@@ -1549,19 +1526,22 @@ static int WriteOneColLine(int col)
|
||||
char const *s;
|
||||
char const *space;
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
wchar_t const *ws;
|
||||
wchar_t const *wspace;
|
||||
int width;
|
||||
#endif
|
||||
|
||||
int clamp = 1;
|
||||
int numwritten = 0;
|
||||
int d = ColToDay[col];
|
||||
char const *url;
|
||||
|
||||
if (d && UseBGVTColors && bgcolor[d][0] != -1) {
|
||||
clamp = 0;
|
||||
}
|
||||
PRINTROW:
|
||||
url = get_url(e->infos);
|
||||
|
||||
/* Print as many characters as possible within the column */
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) {
|
||||
wspace = NULL;
|
||||
ws = e->wc_pos;
|
||||
@@ -1569,14 +1549,17 @@ static int WriteOneColLine(int col)
|
||||
/* If we're at the end, and there's another entry, do a blank
|
||||
line and move to next entry. */
|
||||
if (!*ws && e->next) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
if (CalSepLine) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
}
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e->raw_text);
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
free(e);
|
||||
return 1;
|
||||
FreeCalEntry(e);
|
||||
if (!CalSepLine) {
|
||||
e = CalColumn[col];
|
||||
goto PRINTROW;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the last space char within the column. */
|
||||
@@ -1605,6 +1588,9 @@ static int WriteOneColLine(int col)
|
||||
ColorizeEntry(e, clamp);
|
||||
}
|
||||
|
||||
if (url) {
|
||||
printf("\x1B]8;;%s\x1B\\", url);
|
||||
}
|
||||
/* If we couldn't find a space char, print what we have. */
|
||||
if (!wspace) {
|
||||
for (ws = e->wc_pos; numwritten < ColSpaces; ws++) {
|
||||
@@ -1639,6 +1625,9 @@ static int WriteOneColLine(int col)
|
||||
}
|
||||
}
|
||||
|
||||
if (url) {
|
||||
printf("\x1B]8;;\x1B\\");
|
||||
}
|
||||
/* Decolorize reminder if necessary, but keep any SHADE */
|
||||
if (UseVTColors && e->is_color) {
|
||||
printf("%s", Decolorize());
|
||||
@@ -1657,33 +1646,30 @@ static int WriteOneColLine(int col)
|
||||
/* If done, free memory if no next entry. */
|
||||
if (!*ws && !e->next) {
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e->raw_text);
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
free(e);
|
||||
FreeCalEntry(e);
|
||||
} else {
|
||||
e->wc_pos = ws;
|
||||
}
|
||||
if (CalColumn[col]) return 1; else return 0;
|
||||
} else {
|
||||
#endif
|
||||
space = NULL;
|
||||
s = e->pos;
|
||||
|
||||
/* If we're at the end, and there's another entry, do a blank
|
||||
line and move to next entry. */
|
||||
if (!*s && e->next) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
if (CalSepLine) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
}
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
#endif
|
||||
free(e->raw_text);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
free(e);
|
||||
return 1;
|
||||
FreeCalEntry(e);
|
||||
if (!CalSepLine) {
|
||||
e = CalColumn[col];
|
||||
fprintf(stderr, "BLOOP\n");
|
||||
goto PRINTROW;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the last space char within the column. */
|
||||
@@ -1738,20 +1724,12 @@ static int WriteOneColLine(int col)
|
||||
/* If done, free memory if no next entry. */
|
||||
if (!*s && !e->next) {
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
#endif
|
||||
free(e->raw_text);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
free(e);
|
||||
FreeCalEntry(e);
|
||||
} else {
|
||||
e->pos = s;
|
||||
}
|
||||
if (CalColumn[col]) return 1; else return 0;
|
||||
#ifdef REM_USE_WCHAR
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -2065,6 +2043,11 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
if (dse < 0 && !ParseUntriggered) {
|
||||
/* Expired */
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
} else {
|
||||
/* Calculate the trigger date */
|
||||
EnterTimezone(trig.tz);
|
||||
@@ -2077,6 +2060,11 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
if (dse < 0 && !ParseUntriggered) {
|
||||
/* Expired */
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust trigger date/time to time zone */
|
||||
@@ -2135,7 +2123,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
}
|
||||
}
|
||||
if (trig.typ == PASSTHRU_TYPE) {
|
||||
if (!PsCal && !StrCmpi(trig.passthru, "SHADE")) {
|
||||
if (!PsCal && !strcasecmp(trig.passthru, "SHADE")) {
|
||||
if (dse == DSEToday) {
|
||||
DBufInit(&obuf);
|
||||
r = DoSubst(p, &obuf, &trig, &tim, dse, CAL_MODE);
|
||||
@@ -2148,7 +2136,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
DBufFree(&obuf);
|
||||
}
|
||||
}
|
||||
if (!PsCal && !StrCmpi(trig.passthru, "WEEK")) {
|
||||
if (!PsCal && !strcasecmp(trig.passthru, "WEEK")) {
|
||||
if (dse == DSEToday) {
|
||||
DBufInit(&obuf);
|
||||
r = DoSubst(p, &obuf, &trig, &tim, dse, CAL_MODE);
|
||||
@@ -2161,11 +2149,11 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
DBufFree(&obuf);
|
||||
}
|
||||
}
|
||||
if (!PsCal && StrCmpi(trig.passthru, "COLOR") && StrCmpi(trig.passthru, "COLOUR") && StrCmpi(trig.passthru, "MOON")) {
|
||||
if (!PsCal && strcasecmp(trig.passthru, "COLOR") && strcasecmp(trig.passthru, "COLOUR") && strcasecmp(trig.passthru, "MOON")) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
if (!PsCal && !StrCmpi(trig.passthru, "MOON")) {
|
||||
if (!PsCal && !strcasecmp(trig.passthru, "MOON")) {
|
||||
if (dse == DSEToday) {
|
||||
DBufInit(&obuf);
|
||||
r = DoSubst(p, &obuf, &trig, &tim, dse, CAL_MODE);
|
||||
@@ -2178,8 +2166,8 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
DBufFree(&obuf);
|
||||
}
|
||||
}
|
||||
if (!StrCmpi(trig.passthru, "COLOR") ||
|
||||
!StrCmpi(trig.passthru, "COLOUR")) {
|
||||
if (!strcasecmp(trig.passthru, "COLOR") ||
|
||||
!strcasecmp(trig.passthru, "COLOUR")) {
|
||||
is_color = 1;
|
||||
/* Strip off the three color numbers */
|
||||
DBufFree(&buf);
|
||||
@@ -2243,8 +2231,8 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
/* Suppress time if it's not today or if it's a non-COLOR special */
|
||||
if (dse != DSEToday ||
|
||||
(trig.typ == PASSTHRU_TYPE &&
|
||||
StrCmpi(trig.passthru, "COLOUR") &&
|
||||
StrCmpi(trig.passthru, "COLOR"))) {
|
||||
strcasecmp(trig.passthru, "COLOUR") &&
|
||||
strcasecmp(trig.passthru, "COLOR"))) {
|
||||
if (DBufPuts(&obuf, SimpleTime(NO_TIME)) != OK) {
|
||||
DBufFree(&obuf);
|
||||
DBufFree(&raw_buf);
|
||||
@@ -2353,19 +2341,17 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
e->if_depth = get_if_pointer() - get_base_if_pointer();
|
||||
e->trig = trig;
|
||||
if (e->trig.tz) {
|
||||
e->trig.tz = StrDup(e->trig.tz);
|
||||
e->trig.tz = strdup(e->trig.tz);
|
||||
}
|
||||
e->tt = tim;
|
||||
#ifdef REM_USE_WCHAR
|
||||
e->wc_pos = NULL;
|
||||
e->wc_text = NULL;
|
||||
#endif
|
||||
e->is_color = is_color;
|
||||
e->r = col_r;
|
||||
e->g = col_g;
|
||||
e->b = col_b;
|
||||
e->text = StrDup(s);
|
||||
e->raw_text = StrDup(DBufValue(&raw_buf));
|
||||
e->text = strdup(s);
|
||||
e->raw_text = strdup(DBufValue(&raw_buf));
|
||||
DBufFree(&raw_buf);
|
||||
DBufFree(&obuf);
|
||||
DBufFree(&pre_buf);
|
||||
@@ -2377,9 +2363,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
FreeTrig(&trig);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
#ifdef REM_USE_WCHAR
|
||||
make_wchar_versions(e);
|
||||
#endif
|
||||
DBufInit(&(e->tags));
|
||||
DBufPuts(&(e->tags), DBufValue(&(trig.tags)));
|
||||
if (SynthesizeTags) {
|
||||
@@ -2462,6 +2446,34 @@ void WriteJSONTimeTrigger(TimeTrig const *tt)
|
||||
}
|
||||
}
|
||||
|
||||
static char const *
|
||||
get_url(TrigInfo *infos)
|
||||
{
|
||||
TrigInfo *ti = infos;
|
||||
char const *url;
|
||||
if (!TerminalHyperlinks) {
|
||||
/* Nope, not doing links in terminal */
|
||||
return NULL;
|
||||
}
|
||||
while (ti) {
|
||||
char const *colon = strchr(ti->info, ':');
|
||||
if (!colon) {
|
||||
ti = ti->next;
|
||||
continue;
|
||||
}
|
||||
if (!strncasecmp(ti->info, "url", colon-ti->info)) {
|
||||
url = colon+1;
|
||||
while (*url && isspace(*url)) {
|
||||
url++;
|
||||
}
|
||||
if (!*url) return NULL;
|
||||
return url;
|
||||
}
|
||||
ti = ti->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
WriteJSONInfoChain(TrigInfo *ti)
|
||||
{
|
||||
@@ -2655,7 +2667,7 @@ static void WriteSimpleEntryProtocol2(CalEntry *e)
|
||||
PrintJSONKeyPairInt("r", e->r);
|
||||
PrintJSONKeyPairInt("g", e->g);
|
||||
PrintJSONKeyPairInt("b", e->b);
|
||||
} else if (!StrCmpi(e->passthru, "SHADE")) {
|
||||
} else if (!strcasecmp(e->passthru, "SHADE")) {
|
||||
int r, g, b, n;
|
||||
n = sscanf(e->text, "%d %d %d", &r, &g, &b);
|
||||
if (n < 3) {
|
||||
@@ -2761,9 +2773,7 @@ static void WriteSimpleEntries(int col, int dse)
|
||||
free(e->text);
|
||||
free(e->raw_text);
|
||||
FreeTrigInfoChain(e->infos);
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) free(e->wc_text);
|
||||
#endif
|
||||
n = e->next;
|
||||
free(e);
|
||||
e = n;
|
||||
|
||||
@@ -27,9 +27,6 @@
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
/* Define to 1 if you have the `mbstowcs' function. */
|
||||
#undef HAVE_MBSTOWCS
|
||||
|
||||
/* Define to 1 if you have the `setenv' function. */
|
||||
#undef HAVE_SETENV
|
||||
|
||||
@@ -48,21 +45,12 @@
|
||||
/* Define to 1 if you have the `readline' function. */
|
||||
#undef HAVE_READLINE
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#undef HAVE_STRCASECMP
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strncasecmp' function. */
|
||||
#undef HAVE_STRNCASECMP
|
||||
|
||||
/* Define to 1 if you have the <sys/inotify.h> header file. */
|
||||
#undef HAVE_SYS_INOTIFY_H
|
||||
|
||||
@@ -84,9 +72,6 @@
|
||||
/* Define to 1 if you have the `unsetenv' function. */
|
||||
#undef HAVE_UNSETENV
|
||||
|
||||
/* Define to 1 if you have the <wctype.h> header file. */
|
||||
#undef HAVE_WCTYPE_H
|
||||
|
||||
/* Define to 1 if you have the <readline/history.h> header file. */
|
||||
#undef HAVE_READLINE_HISTORY_H
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* which you can customize. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -154,12 +154,6 @@
|
||||
#define PSBEGIN2 "# rem2ps2 begin"
|
||||
#define PSEND2 "# rem2ps2 end"
|
||||
|
||||
#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H)
|
||||
#define REM_USE_WCHAR 1
|
||||
#else
|
||||
#undef REM_USE_WCHAR
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_READLINE) && defined(HAVE_READLINE_READLINE_H)
|
||||
#define USE_READLINE 1
|
||||
#else
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* which you can customize. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -154,12 +154,6 @@
|
||||
#define PSBEGIN2 "# rem2ps2 begin"
|
||||
#define PSEND2 "# rem2ps2 end"
|
||||
|
||||
#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H)
|
||||
#define REM_USE_WCHAR 1
|
||||
#else
|
||||
#undef REM_USE_WCHAR
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_READLINE) && defined(HAVE_READLINE_READLINE_H)
|
||||
#define USE_READLINE 1
|
||||
#else
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Code to suppress duplicate reminders */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -101,7 +101,7 @@ InsertDedupeEntry(int trigger_date, int trigger_time, char const *body)
|
||||
}
|
||||
e->trigger_date = trigger_date;
|
||||
e->trigger_time = trigger_time;
|
||||
e->body = StrDup(body);
|
||||
e->body = strdup(body);
|
||||
if (!e->body) {
|
||||
free(e);
|
||||
return;
|
||||
|
||||
56
src/dorem.c
56
src/dorem.c
@@ -7,7 +7,7 @@
|
||||
/* commands. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -306,11 +306,11 @@ ensure_satnode_mentions_trigdate_aux(expr_node *node, int *mentioned)
|
||||
} else {
|
||||
name = node->u.value.v.str;
|
||||
}
|
||||
if (!StrCmpi(name, "T") ||
|
||||
!StrCmpi(name, "Td") ||
|
||||
!StrCmpi(name, "Tm") ||
|
||||
!StrCmpi(name, "Tw") ||
|
||||
!StrCmpi(name, "Ty")) {
|
||||
if (!strcasecmp(name, "T") ||
|
||||
!strcasecmp(name, "Td") ||
|
||||
!strcasecmp(name, "Tm") ||
|
||||
!strcasecmp(name, "Tw") ||
|
||||
!strcasecmp(name, "Ty")) {
|
||||
*mentioned = 1;
|
||||
return;
|
||||
}
|
||||
@@ -1120,7 +1120,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
if (r != OK) {
|
||||
return r;
|
||||
}
|
||||
trig->tz = StrDup(DBufValue(&buf));
|
||||
trig->tz = strdup(DBufValue(&buf));
|
||||
if (!trig->tz) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
@@ -1555,6 +1555,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig const *tim, int dse, int is
|
||||
DynamicBuffer pre_buf;
|
||||
char const *s;
|
||||
char const *msg_command = NULL;
|
||||
char const *url;
|
||||
Value v;
|
||||
|
||||
if (MsgCommand) {
|
||||
@@ -1576,14 +1577,14 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig const *tim, int dse, int is
|
||||
DBufInit(&calRow);
|
||||
DBufInit(&pre_buf);
|
||||
if (t->typ == RUN_TYPE && RunDisabled) return E_RUN_DISABLED;
|
||||
if ((t->typ == PASSTHRU_TYPE && StrCmpi(t->passthru, "COLOR") && StrCmpi(t->passthru, "COLOUR")) ||
|
||||
if ((t->typ == PASSTHRU_TYPE && strcasecmp(t->passthru, "COLOR") && strcasecmp(t->passthru, "COLOUR")) ||
|
||||
t->typ == CAL_TYPE ||
|
||||
t->typ == PS_TYPE ||
|
||||
t->typ == PSF_TYPE)
|
||||
return OK;
|
||||
|
||||
/* Handle COLOR types */
|
||||
if (t->typ == PASSTHRU_TYPE && (!StrCmpi(t->passthru, "COLOR") || !StrCmpi(t->passthru, "COLOUR"))) {
|
||||
if (t->typ == PASSTHRU_TYPE && (!strcasecmp(t->passthru, "COLOR") || !strcasecmp(t->passthru, "COLOUR"))) {
|
||||
/* Strip off three tokens */
|
||||
r = ParseToken(p, &buf);
|
||||
sscanf(DBufValue(&buf), "%d", &red);
|
||||
@@ -1830,9 +1831,16 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig const *tim, int dse, int is
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are sorting, just queue it up in the sort buffer */
|
||||
/* Get the url if terminal hyperlinks are enabled */
|
||||
if (TerminalHyperlinks) {
|
||||
url = FindTrigInfo(t, "url");
|
||||
} else {
|
||||
url = NULL;
|
||||
}
|
||||
|
||||
/* If we are sorting, just queue it up in the sort buffer */
|
||||
if (SortByDate) {
|
||||
if (InsertIntoSortBuffer(dse, tim->ttime, DBufValue(&buf),
|
||||
if (InsertIntoSortBuffer(dse, tim->ttime, url, DBufValue(&buf),
|
||||
t->typ, t->priority) == OK) {
|
||||
DBufFree(&buf);
|
||||
NumTriggered++;
|
||||
@@ -1855,14 +1863,20 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig const *tim, int dse, int is
|
||||
if (IsServerMode() && !strncmp(DBufValue(&buf), "NOTE endreminder", 16)) {
|
||||
printf(" %s", DBufValue(&buf));
|
||||
} else {
|
||||
if (url) {
|
||||
printf("\x1B]8;;%s\x1B\\", url);
|
||||
}
|
||||
printf("%s", DBufValue(&buf));
|
||||
if (url) {
|
||||
printf("\x1B]8;;\x1B\\");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSF_TYPE:
|
||||
FillParagraph(DBufValue(&buf), output);
|
||||
FillParagraph(url, DBufValue(&buf), output);
|
||||
break;
|
||||
|
||||
case RUN_TYPE:
|
||||
@@ -2269,7 +2283,9 @@ static int ShouldTriggerBasedOnWarn(Trigger const *t, int dse, int *err)
|
||||
while(iter++ <= max) {
|
||||
j--;
|
||||
*err = IsOmitted(j, t->localomit, t->omitfunc, &omit);
|
||||
if (*err) return 0;
|
||||
if (*err) {
|
||||
return (dse == DSEToday);
|
||||
}
|
||||
if (!omit) v.v.val++;
|
||||
if (!v.v.val) {
|
||||
break;
|
||||
@@ -2277,7 +2293,7 @@ static int ShouldTriggerBasedOnWarn(Trigger const *t, int dse, int *err)
|
||||
}
|
||||
if (iter > max) {
|
||||
Eprint("Delta: Bad OMITFUNC? %s", GetErr(E_CANT_TRIG));
|
||||
return 0;
|
||||
return (dse == DSEToday);
|
||||
}
|
||||
if (j == DSEToday) return 1;
|
||||
}
|
||||
@@ -2291,17 +2307,17 @@ void FixSpecialType(Trigger *t)
|
||||
}
|
||||
|
||||
/* Convert SPECIAL MSG / MSF / RUN / CAL to just plain MSG / MSF / etc */
|
||||
if (!StrCmpi(t->passthru, "MSG")) {
|
||||
if (!strcasecmp(t->passthru, "MSG")) {
|
||||
t->typ = MSG_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "MSF")) {
|
||||
} else if (!strcasecmp(t->passthru, "MSF")) {
|
||||
t->typ = MSF_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "RUN")) {
|
||||
} else if (!strcasecmp(t->passthru, "RUN")) {
|
||||
t->typ = RUN_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "CAL")) {
|
||||
} else if (!strcasecmp(t->passthru, "CAL")) {
|
||||
t->typ = CAL_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "PS")) {
|
||||
} else if (!strcasecmp(t->passthru, "PS")) {
|
||||
t->typ = PS_TYPE;
|
||||
} else if (!StrCmpi(t->passthru, "PSFILE")) {
|
||||
} else if (!strcasecmp(t->passthru, "PSFILE")) {
|
||||
t->typ = PSF_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* reminders are triggered. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
14
src/dynbuf.c
14
src/dynbuf.c
@@ -6,7 +6,7 @@
|
||||
/* buffers. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -17,6 +17,15 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static size_t NumMallocs = 0;
|
||||
static size_t BytesMalloced = 0;
|
||||
|
||||
void DBufGetMallocStats(size_t *num_mallocs, size_t *bytes_malloced)
|
||||
{
|
||||
*num_mallocs = NumMallocs;
|
||||
*bytes_malloced = BytesMalloced;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
%FUNCTION: DBufMakeRoom
|
||||
%ARGUMENTS:
|
||||
@@ -45,6 +54,9 @@ static int DBufMakeRoom(DynamicBuffer *dbuf, size_t n)
|
||||
buf = malloc(size);
|
||||
if (!buf) return E_NO_MEM;
|
||||
|
||||
NumMallocs++;
|
||||
BytesMalloced += size;
|
||||
|
||||
/* Copy contents */
|
||||
strcpy(buf, dbuf->buffer);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Declaration of functions for manipulating dynamic buffers */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -29,6 +29,8 @@ int DBufPuts(DynamicBuffer *dbuf, char const *str);
|
||||
void DBufFree(DynamicBuffer *dbuf);
|
||||
int DBufGets(DynamicBuffer *dbuf, FILE *fp);
|
||||
|
||||
void DBufGetMallocStats(size_t *num_mallocs, size_t *bytes_malloced);
|
||||
|
||||
#define DBufValue(bufPtr) ((bufPtr)->buffer)
|
||||
#define DBufLen(bufPtr) ((bufPtr)->len)
|
||||
|
||||
|
||||
15
src/err.h
15
src/err.h
@@ -5,7 +5,7 @@
|
||||
/* Error definitions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -134,9 +134,11 @@
|
||||
#define E_MAX_OVERDUE_WITHOUT_TODO 110
|
||||
#define E_TZ_SPECIFIED_TWICE 111
|
||||
#define E_TZ_NO_AT 112
|
||||
#define E_NO_MB 113
|
||||
#define E_BAD_MB_SEQ 114
|
||||
#define E_EXPR_NODES_EXCEEDED 115
|
||||
#define E_BAD_MB_SEQ 113
|
||||
#define E_EXPR_NODES_EXCEEDED 114
|
||||
#define E_EXPECTING_EOXPR 115
|
||||
#define E_EXPECTING_ATOM 116
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
#undef EXTERN
|
||||
#define EXTERN
|
||||
@@ -149,7 +151,6 @@
|
||||
#define STR2(X) #X
|
||||
|
||||
|
||||
#ifndef L_ERR_OVERRIDE
|
||||
EXTERN char *ErrMsg[]
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
@@ -267,13 +268,13 @@ EXTERN char *ErrMsg[]
|
||||
/* E_MAX_OVERDUE_WITHOUT_TODO */ "MAX-OVERDUE specified without TODO",
|
||||
/* E_TZ_SPECIFIED_TWICE */ "TZ specified twice",
|
||||
/* E_TZ_NO_AT */ "TZ specified for non-timed reminder",
|
||||
/* E_NO_MB */ "C library does not support multibyte characters",
|
||||
/* E_BAD_MB_SEQ */ "Invalid multibyte sequence",
|
||||
/* E_EXPR_NODES_EXCEEDED */ "Maximum expression complexity exceeded",
|
||||
/* E_EXPECTING_EOXPR */ "Expecting operator or end-of-expression",
|
||||
/* E_EXPECTING_ATOM */ "Expecting constant, variable, function call or (expression)",
|
||||
}
|
||||
#endif /* MK_GLOBALS */
|
||||
;
|
||||
#endif /* L_ERR_OVERRIDE */
|
||||
|
||||
EXTERN int NumErrs
|
||||
#ifdef MK_GLOBALS
|
||||
|
||||
54
src/expr.c
54
src/expr.c
@@ -12,7 +12,7 @@
|
||||
/* evaluated. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -170,6 +170,8 @@ static expr_node *expr_node_free_list = NULL;
|
||||
/* Maximum parse level before we bail (to avoid SEGV from filling stack)*/
|
||||
#define MAX_PARSE_LEVEL 2000
|
||||
|
||||
/* Legal punctuation characters in an expression */
|
||||
#define LEGAL_CHARS "+-*/%&|=<>!)"
|
||||
static int parse_level_high_water = 0;
|
||||
#define CHECK_PARSE_LEVEL() do { if (level > parse_level_high_water) { parse_level_high_water = level; if (level > MAX_PARSE_LEVEL) { *r = E_OP_STK_OVER; return NULL; } } } while(0)
|
||||
|
||||
@@ -2228,9 +2230,15 @@ static int set_constant_value(expr_node *atom)
|
||||
atom->u.value.v.val = val;
|
||||
return OK;
|
||||
}
|
||||
|
||||
atom->u.value.type = ERR_TYPE;
|
||||
Eprint("`%s': %s", DBufValue(&ExprBuf), GetErr(E_ILLEGAL_CHAR));
|
||||
return E_ILLEGAL_CHAR;
|
||||
if (strchr(LEGAL_CHARS, *s) != NULL) {
|
||||
r = E_EXPECTING_ATOM;
|
||||
} else {
|
||||
r = E_ILLEGAL_CHAR;
|
||||
}
|
||||
Eprint("`%s': %s", DBufValue(&ExprBuf), GetErr(r));
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -2248,7 +2256,7 @@ static int make_atom(expr_node *atom, Var *locals)
|
||||
/* Variable */
|
||||
if (isalpha(*s) || *s == '_') {
|
||||
while(v) {
|
||||
if (! StrinCmp(s, v->name, VAR_NAME_LEN)) {
|
||||
if (! strncasecmp(s, v->name, VAR_NAME_LEN)) {
|
||||
atom->type = N_LOCAL_VAR;
|
||||
atom->u.arg = i;
|
||||
return OK;
|
||||
@@ -2346,8 +2354,13 @@ static expr_node *parse_atom(char const **e, int *r, Var *locals, int level)
|
||||
*s != '$' &&
|
||||
*s != '"' &&
|
||||
*s != '\'') {
|
||||
Eprint("%s `%c'", GetErr(E_ILLEGAL_CHAR), *s);
|
||||
*r = E_ILLEGAL_CHAR;
|
||||
if (strchr(LEGAL_CHARS, *s) != NULL) {
|
||||
*r = E_EXPECTING_ATOM;
|
||||
Eprint("%s", GetErr(*r));
|
||||
} else {
|
||||
*r = E_ILLEGAL_CHAR;
|
||||
Eprint("%s `%c'", GetErr(*r), *s);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2759,9 +2772,24 @@ expr_node *parse_expression(char const **e, int *r, Var *locals)
|
||||
print_expr_tree(node, ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
if (**e && (**e != ']')) {
|
||||
orig = o2;
|
||||
}
|
||||
while (**e && isempty(**e)) {
|
||||
(*e)++;
|
||||
}
|
||||
if (**e && (**e != ']')) {
|
||||
if (DebugFlag & DB_PARSE_EXPR) {
|
||||
fprintf(ErrFp, " Unparsed: %s\n", *e);
|
||||
}
|
||||
if (*r == OK) {
|
||||
*r = E_EXPECTING_EOXPR;
|
||||
}
|
||||
}
|
||||
if (*r != OK) {
|
||||
if (node) {
|
||||
free_expr_tree(node);
|
||||
node = NULL;
|
||||
}
|
||||
}
|
||||
if (!SuppressErrorOutputInCatch) {
|
||||
if (*r == E_EXPECT_COMMA ||
|
||||
@@ -2771,9 +2799,11 @@ expr_node *parse_expression(char const **e, int *r, Var *locals)
|
||||
*r == E_2FEW_ARGS ||
|
||||
*r == E_PARSE_ERR ||
|
||||
*r == E_EOLN ||
|
||||
*r == E_EXPECTING_EOXPR ||
|
||||
*r == E_BAD_NUMBER ||
|
||||
*r == E_BAD_DATE ||
|
||||
*r == E_BAD_TIME ||
|
||||
*r == E_EXPECTING_ATOM ||
|
||||
*r == E_ILLEGAL_CHAR) {
|
||||
end_of_expr = find_end_of_expr(orig);
|
||||
while (**e && isempty(**e)) {
|
||||
@@ -2964,7 +2994,6 @@ int EvalExpr(char const **e, Value *v, ParsePtr p)
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
/* Truncate a wide-char string to MAX_PRT_LEN characters */
|
||||
static char const *truncate_string(char const *src)
|
||||
{
|
||||
@@ -2984,7 +3013,6 @@ static char const *truncate_string(char const *src)
|
||||
cbuf[MAX_PRT_LEN*8] = 0;
|
||||
return cbuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -3010,7 +3038,6 @@ char const *PrintValue (Value const *v, FILE *fp)
|
||||
}
|
||||
|
||||
if (v->type == STR_TYPE) {
|
||||
#ifdef REM_USE_WCHAR
|
||||
s = (unsigned char const *) truncate_string(v->v.str);
|
||||
if (s != (unsigned char const *) v->v.str) {
|
||||
max_str_put = INT_MAX;
|
||||
@@ -3018,9 +3045,6 @@ char const *PrintValue (Value const *v, FILE *fp)
|
||||
truncated = 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
s = (unsigned char const *) v->v.str;
|
||||
#endif
|
||||
PV_PUTC(fp, '"');
|
||||
for (y=0; y<max_str_put && *s; y++) {
|
||||
switch(*s) {
|
||||
@@ -3115,7 +3139,7 @@ int CopyValue(Value *dest, const Value *src)
|
||||
{
|
||||
dest->type = ERR_TYPE;
|
||||
if (src->type == STR_TYPE) {
|
||||
dest->v.str = StrDup(src->v.str);
|
||||
dest->v.str = strdup(src->v.str);
|
||||
if (!dest->v.str) return E_NO_MEM;
|
||||
} else {
|
||||
dest->v.val = src->v.val;
|
||||
@@ -3288,7 +3312,7 @@ int DoCoerce(char type, Value *v)
|
||||
default: return E_CANT_COERCE;
|
||||
}
|
||||
v->type = STR_TYPE;
|
||||
v->v.str = StrDup(coerce_buf);
|
||||
v->v.str = strdup(coerce_buf);
|
||||
if (!v->v.str) {
|
||||
v->type = ERR_TYPE;
|
||||
return E_NO_MEM;
|
||||
|
||||
17
src/files.c
17
src/files.c
@@ -7,7 +7,7 @@
|
||||
/* files. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -159,7 +159,7 @@ void SetCurrentFilename(char const *fname)
|
||||
fprintf(ErrFp, "Out of Memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
e->fname = StrDup(fname);
|
||||
e->fname = strdup(fname);
|
||||
if (!e->fname) {
|
||||
fprintf(ErrFp, "Out of Memory!\n");
|
||||
exit(1);
|
||||
@@ -225,8 +225,9 @@ static void OpenPurgeFile(char const *fname, char const *mode)
|
||||
if (!PurgeFP) {
|
||||
fprintf(ErrFp, tr("Cannot open `%s' for writing: %s"), DBufValue(&fname_buf), strerror(errno));
|
||||
fprintf(ErrFp, "\n");
|
||||
} else {
|
||||
set_cloexec(fileno(PurgeFP));
|
||||
}
|
||||
set_cloexec(fileno(PurgeFP));
|
||||
DBufFree(&fname_buf);
|
||||
}
|
||||
|
||||
@@ -558,7 +559,7 @@ static int CacheFile(char const *fname, int use_pclose)
|
||||
return E_NO_MEM;
|
||||
}
|
||||
cf->cache = NULL;
|
||||
cf->filename = StrDup(fname);
|
||||
cf->filename = strdup(fname);
|
||||
if (!cf->filename) {
|
||||
ShouldCache = 0;
|
||||
if (use_pclose) {
|
||||
@@ -626,7 +627,7 @@ static int CacheFile(char const *fname, int use_pclose)
|
||||
cl->next = NULL;
|
||||
cl->LineNo = LineNo;
|
||||
cl->LineNoStart = LineNoStart;
|
||||
cl->text = StrDup(s);
|
||||
cl->text = strdup(s);
|
||||
DBufFree(&LineBuffer);
|
||||
if (!cl->text) {
|
||||
DestroyCache(cf);
|
||||
@@ -873,7 +874,7 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
i->chain = NULL;
|
||||
if (!*dirname) return E_CANT_OPEN;
|
||||
|
||||
dir = StrDup(dirname);
|
||||
dir = strdup(dirname);
|
||||
if (!dir) return E_NO_MEM;
|
||||
|
||||
/* Strip trailing slashes off directory */
|
||||
@@ -915,7 +916,7 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
if (ShouldCache) {
|
||||
dc = malloc(sizeof(DirectoryFilenameChain));
|
||||
if (dc) {
|
||||
dc->dirname = StrDup(dir);
|
||||
dc->dirname = strdup(dir);
|
||||
if (!dc->dirname) {
|
||||
free(dc);
|
||||
dc = NULL;
|
||||
@@ -971,7 +972,7 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
ch->filename = StrDup(glob_buf.gl_pathv[r]);
|
||||
ch->filename = strdup(glob_buf.gl_pathv[r]);
|
||||
if (!ch->filename) {
|
||||
globfree(&glob_buf);
|
||||
FreeChain(i->chain);
|
||||
|
||||
197
src/funcs.c
197
src/funcs.c
@@ -6,7 +6,7 @@
|
||||
/* expressions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -18,11 +18,9 @@
|
||||
#define __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -34,8 +32,10 @@
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TERMIOS_H
|
||||
#ifdef __sun
|
||||
#include <sys/termios.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
@@ -133,12 +133,14 @@ static int FIsconst (expr_node *, Value *, Value *, int *);
|
||||
static int FIsdst (func_info *);
|
||||
static int FIsleap (func_info *);
|
||||
static int FIsomitted (func_info *);
|
||||
static int FIvritmon (func_info *);
|
||||
static int FLanguage (func_info *);
|
||||
static int FLocalToUTC (func_info *);
|
||||
static int FLower (func_info *);
|
||||
static int FMax (func_info *);
|
||||
static int FMbchar (func_info *);
|
||||
static int FMbindex (func_info *);
|
||||
static int FMbpad (func_info *);
|
||||
static int FMbstrlen (func_info *);
|
||||
static int FMbsubstr (func_info *);
|
||||
static int FMin (func_info *);
|
||||
@@ -318,12 +320,14 @@ BuiltinFunc Func[] = {
|
||||
{ "isdst", 0, 2, 0, FIsdst, NULL },
|
||||
{ "isleap", 1, 1, 1, FIsleap, NULL },
|
||||
{ "isomitted", 1, 1, 0, FIsomitted, NULL },
|
||||
{ "ivritmon", 1, 1, 0, FIvritmon, NULL },
|
||||
{ "language", 0, 0, 1, FLanguage, NULL },
|
||||
{ "localtoutc", 1, 1, 1, FLocalToUTC, NULL },
|
||||
{ "lower", 1, 1, 1, FLower, NULL },
|
||||
{ "max", 1, NO_MAX, 1, FMax, NULL },
|
||||
{ "mbchar", 1, NO_MAX, 1, FMbchar, NULL },
|
||||
{ "mbindex", 2, 3, 1, FMbindex, NULL },
|
||||
{ "mbpad", 3, 4, 1, FMbpad, NULL },
|
||||
{ "mbstrlen", 1, 1, 1, FMbstrlen, NULL },
|
||||
{ "mbsubstr", 2, 3, 1, FMbsubstr, NULL },
|
||||
{ "min", 1, NO_MAX, 1, FMin, NULL },
|
||||
@@ -446,7 +450,7 @@ static int RetStrVal(char const *s, func_info *info)
|
||||
RetVal.v.str = malloc(1);
|
||||
if (RetVal.v.str) *RetVal.v.str = 0;
|
||||
} else {
|
||||
RetVal.v.str = StrDup(s);
|
||||
RetVal.v.str = strdup(s);
|
||||
}
|
||||
|
||||
if (!RetVal.v.str) {
|
||||
@@ -504,7 +508,6 @@ static int FStrlen(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FMbstrlen(func_info *info)
|
||||
{
|
||||
#ifdef REM_USE_WCHAR
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
size_t l = mbstowcs(NULL, ARGSTR(0), 0);
|
||||
if (l == (size_t) -1) {
|
||||
@@ -514,9 +517,6 @@ static int FMbstrlen(func_info *info)
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = (int) l;
|
||||
return OK;
|
||||
#else
|
||||
return E_NO_MB;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -654,11 +654,11 @@ static int FCoerce(func_info *info)
|
||||
it won't be destroyed */
|
||||
DCOPYVAL(RetVal, ARG(1));
|
||||
|
||||
if (! StrCmpi(s, "int")) r = DoCoerce(INT_TYPE, &RetVal);
|
||||
else if (! StrCmpi(s, "date")) r = DoCoerce(DATE_TYPE, &RetVal);
|
||||
else if (! StrCmpi(s, "time")) r = DoCoerce(TIME_TYPE, &RetVal);
|
||||
else if (! StrCmpi(s, "string")) r = DoCoerce(STR_TYPE, &RetVal);
|
||||
else if (! StrCmpi(s, "datetime")) r = DoCoerce(DATETIME_TYPE, &RetVal);
|
||||
if (! strcasecmp(s, "int")) r = DoCoerce(INT_TYPE, &RetVal);
|
||||
else if (! strcasecmp(s, "date")) r = DoCoerce(DATE_TYPE, &RetVal);
|
||||
else if (! strcasecmp(s, "time")) r = DoCoerce(TIME_TYPE, &RetVal);
|
||||
else if (! strcasecmp(s, "string")) r = DoCoerce(STR_TYPE, &RetVal);
|
||||
else if (! strcasecmp(s, "datetime")) r = DoCoerce(DATETIME_TYPE, &RetVal);
|
||||
else {
|
||||
Eprint("coerce(): Invalid type `%s'", s);
|
||||
return E_CANT_COERCE;
|
||||
@@ -766,7 +766,6 @@ static int FHex(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FCodepoint(func_info *info)
|
||||
{
|
||||
#ifdef REM_USE_WCHAR
|
||||
wchar_t arr[2];
|
||||
size_t len;
|
||||
|
||||
@@ -780,9 +779,6 @@ static int FCodepoint(func_info *info)
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = (int) arr[0];
|
||||
return OK;
|
||||
#else
|
||||
return E_NO_MB;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -841,7 +837,6 @@ static int FChar(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FMbchar(func_info *info)
|
||||
{
|
||||
#ifdef REM_USE_WCHAR
|
||||
int i;
|
||||
size_t len;
|
||||
wchar_t *arr;
|
||||
@@ -887,9 +882,6 @@ static int FMbchar(func_info *info)
|
||||
RetVal.type = STR_TYPE;
|
||||
RetVal.v.str = s;
|
||||
return OK;
|
||||
#else
|
||||
return E_NO_MB;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1440,6 +1432,125 @@ static int FPad(func_info *info)
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FMbpad - multibyte version of Fpad */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int FMbpad(func_info *info)
|
||||
{
|
||||
int r;
|
||||
wchar_t *s;
|
||||
wchar_t *d;
|
||||
|
||||
size_t len;
|
||||
size_t len2;
|
||||
size_t wantlen;
|
||||
size_t i;
|
||||
|
||||
wchar_t *src;
|
||||
wchar_t *pad;
|
||||
wchar_t *dest;
|
||||
|
||||
char *result;
|
||||
ASSERT_TYPE(1, STR_TYPE);
|
||||
ASSERT_TYPE(2, INT_TYPE);
|
||||
if (Nargs == 4) {
|
||||
ASSERT_TYPE(3, INT_TYPE);
|
||||
}
|
||||
|
||||
if (ARG(0).type != STR_TYPE) {
|
||||
r = DoCoerce(STR_TYPE, &ARG(0));
|
||||
if (r != OK) return r;
|
||||
}
|
||||
|
||||
wantlen = ARGV(2);
|
||||
|
||||
/* Convert ARGV(0) and ARGV(1) to wide-char strings */
|
||||
len = mbstowcs(NULL, ARGSTR(0), 0);
|
||||
if (len == (size_t) -1) {
|
||||
return E_BAD_MB_SEQ;
|
||||
}
|
||||
|
||||
if (len >= wantlen) {
|
||||
DCOPYVAL(RetVal, ARG(0));
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (strlen(ARGSTR(1)) == 0) {
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
|
||||
if (MaxStringLen > 0 && wantlen > (size_t) MaxStringLen) {
|
||||
return E_STRING_TOO_LONG;
|
||||
}
|
||||
|
||||
src = calloc(len+1, sizeof(wchar_t));
|
||||
if (!src) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
(void) mbstowcs(src, ARGSTR(0), len+1);
|
||||
len2 = mbstowcs(NULL, ARGSTR(1), 0);
|
||||
if (len2 == (size_t) -1) {
|
||||
free(src);
|
||||
return E_BAD_MB_SEQ;
|
||||
}
|
||||
pad = calloc(len2+1, sizeof(wchar_t));
|
||||
if (!pad) {
|
||||
free(src);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
(void) mbstowcs(pad, ARGSTR(1), len2+1);
|
||||
|
||||
dest = calloc(wantlen+1, sizeof(wchar_t));
|
||||
if (!dest) {
|
||||
free(src);
|
||||
free(pad);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
d = dest;
|
||||
if (Nargs < 4 || !ARGV(3)) {
|
||||
/* Pad on the LEFT */
|
||||
s = pad;
|
||||
for (i=0; i<wantlen-len; i++) {
|
||||
*d++ = *s++;
|
||||
if (!*s) s = pad;
|
||||
}
|
||||
s = src;
|
||||
while (*s) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
} else {
|
||||
s = src;
|
||||
while (*s) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
s = pad;
|
||||
for (i=0; i<wantlen-len; i++) {
|
||||
*d++ = *s++;
|
||||
if (!*s) s = pad;
|
||||
}
|
||||
}
|
||||
|
||||
len = wcstombs(NULL, dest, 0);
|
||||
result = calloc(len+1, 1);
|
||||
if (!result) {
|
||||
free(src);
|
||||
free(pad);
|
||||
free(dest);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
(void) wcstombs(result, dest, len+1);
|
||||
|
||||
r = RetStrVal(result, info);
|
||||
free(result);
|
||||
free(src);
|
||||
free(pad);
|
||||
free(dest);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -2562,7 +2673,6 @@ static int FSubstr(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FMbsubstr(func_info *info)
|
||||
{
|
||||
#ifdef REM_USE_WCHAR
|
||||
wchar_t *str;
|
||||
wchar_t *s;
|
||||
wchar_t const *t;
|
||||
@@ -2617,9 +2727,6 @@ static int FMbsubstr(func_info *info)
|
||||
RetVal.v.str = converted;
|
||||
free( (void *) str);
|
||||
return OK;
|
||||
#else
|
||||
return E_NO_MB;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -2669,7 +2776,6 @@ static int FIndex(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FMbindex(func_info *info)
|
||||
{
|
||||
#ifdef REM_USE_WCHAR
|
||||
wchar_t *haystack;
|
||||
wchar_t *needle;
|
||||
wchar_t const *s;
|
||||
@@ -2722,9 +2828,6 @@ static int FMbindex(func_info *info)
|
||||
free( (void *) haystack);
|
||||
free( (void *) needle);
|
||||
return OK;
|
||||
#else
|
||||
return E_NO_MB;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -3080,6 +3183,26 @@ static int FHebmon(func_info *info)
|
||||
return RetStrVal(HebMonthName(m, y), info);
|
||||
}
|
||||
|
||||
static int FIvritmon(func_info *info)
|
||||
{
|
||||
int y, m, d, v;
|
||||
|
||||
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
|
||||
v = DATEPART(ARG(0));
|
||||
|
||||
if (v == CacheHebDse) {
|
||||
m = CacheHebMon;
|
||||
y = CacheHebYear;
|
||||
} else {
|
||||
DSEToHeb(v, &y, &m, &d);
|
||||
CacheHebDse = v;
|
||||
CacheHebYear = y;
|
||||
CacheHebMon = m;
|
||||
CacheHebDay = d;
|
||||
}
|
||||
return RetStrVal(IvritMonthName(m, y), info);
|
||||
}
|
||||
|
||||
static int FHebyear(func_info *info)
|
||||
{
|
||||
int y, m, d, v;
|
||||
@@ -3535,7 +3658,7 @@ static int UTCToLocalHelper(int datetime, int *ret)
|
||||
|
||||
old_tz = getenv("TZ");
|
||||
if (old_tz) {
|
||||
old_tz = StrDup(old_tz);
|
||||
old_tz = strdup(old_tz);
|
||||
if (!old_tz) return E_NO_MEM;
|
||||
}
|
||||
|
||||
@@ -4279,7 +4402,7 @@ int tz_convert(int year, int month, int day,
|
||||
/* backup old TZ env var */
|
||||
old_tz = getenv("TZ");
|
||||
if (old_tz) {
|
||||
old_tz = StrDup(old_tz);
|
||||
old_tz = strdup(old_tz);
|
||||
if (!old_tz) return E_NO_MEM;
|
||||
}
|
||||
if (tgt_tz == NULL || !*tgt_tz) {
|
||||
@@ -4766,10 +4889,13 @@ rows_or_cols(func_info *info, int want_rows)
|
||||
{
|
||||
struct winsize w;
|
||||
int fd = STDOUT_FILENO;
|
||||
|
||||
int opened = 0;
|
||||
|
||||
RetVal.type = INT_TYPE;
|
||||
if (!isatty(fd)) {
|
||||
/* Try STDERR fd if STDOUT fd is not a tty */
|
||||
fd = STDERR_FILENO;
|
||||
}
|
||||
if (!isatty(fd)) {
|
||||
fd = open("/dev/tty", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
@@ -4796,16 +4922,14 @@ static int FRows(func_info *info)
|
||||
}
|
||||
static int FColumns(func_info *info)
|
||||
{
|
||||
#ifdef REM_USE_WCHAR
|
||||
size_t len;
|
||||
wchar_t *buf, *s;
|
||||
int width;
|
||||
#endif
|
||||
|
||||
if (Nargs == 0) {
|
||||
return rows_or_cols(info, 0);
|
||||
}
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
#ifdef REM_USE_WCHAR
|
||||
len = mbstowcs(NULL, ARGSTR(0), 0);
|
||||
if (len == (size_t) -1) return E_NO_MEM;
|
||||
buf = calloc(len+1, sizeof(wchar_t));
|
||||
@@ -4833,9 +4957,6 @@ static int FColumns(func_info *info)
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = width;
|
||||
return OK;
|
||||
#else
|
||||
return E_BAD_TYPE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* The following sets of functions are for computing solstices and equinoxes.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/* globals.h and err.h */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/* MK_GLOBALS. Also contains useful macro definitions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -146,6 +146,7 @@ EXTERN int ArgC;
|
||||
EXTERN char const **ArgV;
|
||||
EXTERN INIT( int CalLines, CAL_LINES);
|
||||
EXTERN INIT( int CalPad, 1);
|
||||
EXTERN INIT( int CalSepLine, 1);
|
||||
EXTERN INIT( int UseVTChars, 0);
|
||||
EXTERN INIT( int UseBGVTColors, 0);
|
||||
EXTERN INIT( int UseUTF8Chars, 0);
|
||||
@@ -170,6 +171,10 @@ EXTERN INIT( double Latitude, DEFAULT_LATITUDE);
|
||||
|
||||
EXTERN INIT( char *Location, LOCATION);
|
||||
|
||||
/* Support hyperlinks in terminal emulators?
|
||||
https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
|
||||
*/
|
||||
EXTERN INIT( int TerminalHyperlinks, 0);
|
||||
/* UTC calculation stuff */
|
||||
EXTERN INIT( int MinsFromUTC, 0);
|
||||
EXTERN INIT( int CalculateUTC, 1);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Implementation of hash table. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Header file for hash-table related functions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Utility function to print hash table stats. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
90
src/hbcal.c
90
src/hbcal.c
@@ -5,7 +5,7 @@
|
||||
/* Support for the Hebrew calendar */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/* Derived from code written by Amos Shapir in 1978; revised */
|
||||
@@ -61,10 +61,58 @@
|
||||
#define ADAR2ADARA 1
|
||||
#define ADAR2BOTH 2
|
||||
|
||||
struct AltMonthName {
|
||||
char const *name;
|
||||
int mon;
|
||||
};
|
||||
|
||||
static char const *HebMonthNames[] = {
|
||||
"Tishrey", "Heshvan", "Kislev", "Tevet", "Shvat", "Adar A", "Adar B",
|
||||
"Nisan", "Iyar", "Sivan", "Tamuz", "Av", "Elul", "Adar"};
|
||||
|
||||
static char const *IvritMonthNames[] = {
|
||||
"תשרי",
|
||||
"חשוון",
|
||||
"כסלו",
|
||||
"טבת",
|
||||
"שבט",
|
||||
"אדר א'",
|
||||
"אדר ב'",
|
||||
"ניסן",
|
||||
"אייר",
|
||||
"סיון",
|
||||
"תמוז",
|
||||
"אב",
|
||||
"אלול",
|
||||
"אדר" };
|
||||
|
||||
/* Alternate spellings */
|
||||
static struct AltMonthName AltMonthSpellings[] = {
|
||||
{ "Tishri", TISHREY },
|
||||
{ "Tishrei", TISHREY },
|
||||
|
||||
{ "Cheshvan", HESHVAN },
|
||||
{ "Kheshvan", HESHVAN },
|
||||
|
||||
{ "Shevat", SHVAT },
|
||||
|
||||
{ "Tammuz", TAMUZ },
|
||||
|
||||
{ "Adar 1", ADARA },
|
||||
{ "Adar I", ADARA },
|
||||
{ "אדר א", ADARA },
|
||||
{ "אדר 1", ADARA },
|
||||
{ "אדר I", ADARA },
|
||||
|
||||
{ "Adar 2", ADARB },
|
||||
{ "Adar II", ADARB },
|
||||
{ "אדר ב", ADARB },
|
||||
{ "אדר 2", ADARB },
|
||||
{ "אדר II", ADARB },
|
||||
|
||||
{ "Iyyar", IYAR }
|
||||
};
|
||||
|
||||
static char MaxMonLen[] = {
|
||||
30, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 29};
|
||||
|
||||
@@ -245,14 +293,32 @@ int HebNameToNum(char const *mname)
|
||||
int i;
|
||||
int m=-1;
|
||||
|
||||
for (i=0; i<14; i++)
|
||||
if (!StrCmpi(mname, HebMonthNames[i])) {
|
||||
for (i=0; i<14; i++) {
|
||||
if (!strcasecmp(mname, HebMonthNames[i])) {
|
||||
m = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m == -1) {
|
||||
for (i=0; i<14; i++) {
|
||||
if (!strcmp(mname, IvritMonthNames[i])) {
|
||||
m = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Try the alternate spellings */
|
||||
if (m == -1) {
|
||||
for (i=0; i < (int) (sizeof(AltMonthSpellings) / sizeof(AltMonthSpellings[0])); i++) {
|
||||
if (!strcasecmp(mname, AltMonthSpellings[i].name)) {
|
||||
m = AltMonthSpellings[i].mon;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -270,6 +336,22 @@ char const *HebMonthName(int m, int y)
|
||||
else return HebMonthNames[m];
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* IvritMonthname */
|
||||
/* */
|
||||
/* Convert a Hebrew month's number to its name in Hebrew */
|
||||
/* script, given the year. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char const *IvritMonthName(int m, int y)
|
||||
{
|
||||
if (m != ADARA && m != ADARB) return IvritMonthNames[m];
|
||||
|
||||
if (!HebIsLeap[(y-1)%19]) return IvritMonthNames[ADAR];
|
||||
else return IvritMonthNames[m];
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetValidHebDate */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Logic for tracking the state of the IF... ELSE... ENDIF */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
26
src/init.c
26
src/init.c
@@ -7,7 +7,7 @@
|
||||
/* in normal mode. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -36,8 +36,10 @@
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TERMIOS_H
|
||||
#ifdef __sun
|
||||
#include <sys/termios.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include "types.h"
|
||||
@@ -194,7 +196,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
/* Initialize local time zone */
|
||||
LocalTimeZone = getenv("TZ");
|
||||
if (LocalTimeZone) {
|
||||
LocalTimeZone = StrDup(LocalTimeZone);
|
||||
LocalTimeZone = strdup(LocalTimeZone);
|
||||
if (!LocalTimeZone) {
|
||||
fprintf(stderr, "Out of memory!\n");
|
||||
exit(1);
|
||||
@@ -512,6 +514,11 @@ void InitRemind(int argc, char const *argv[])
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
if (*arg == 'z' || *arg == 'Z') {
|
||||
TerminalHyperlinks = 1;
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
if (*arg == 'c' || *arg == 'C') {
|
||||
UseVTColors = 1;
|
||||
arg++;
|
||||
@@ -642,8 +649,17 @@ void InitRemind(int argc, char const *argv[])
|
||||
}
|
||||
if (*arg == ',') {
|
||||
arg++;
|
||||
PARSENUM(CalPad, arg);
|
||||
if (CalPad > 20) CalPad = 20;
|
||||
if (*arg != ',') {
|
||||
PARSENUM(CalPad, arg);
|
||||
if (CalPad > 20) CalPad = 20;
|
||||
}
|
||||
if (*arg == ',') {
|
||||
arg++;
|
||||
PARSENUM(CalSepLine, arg);
|
||||
if (CalSepLine) {
|
||||
CalSepLine = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -845,7 +861,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
#ifndef L_USAGE_OVERRIDE
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s Copyright (C) 1992-2025 Dianne Skoll\n", VERSION);
|
||||
fprintf(ErrFp, "\nREMIND %s Copyright (C) 1992-2026 Dianne Skoll\n", VERSION);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
|
||||
39
src/main.c
39
src/main.c
@@ -6,7 +6,7 @@
|
||||
/* routines, etc. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -39,10 +39,8 @@
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef REM_USE_WCHAR
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
@@ -64,12 +62,17 @@ exitfunc(void)
|
||||
/* Kill any execution-time-limiter process */
|
||||
unlimit_execution_time();
|
||||
|
||||
size_t num_mallocs, bytes_malloced;
|
||||
|
||||
if (DebugFlag & DB_UNUSED_VARS) {
|
||||
DumpUnusedVars();
|
||||
}
|
||||
if (DebugFlag & DB_HASHSTATS) {
|
||||
fflush(stdout);
|
||||
fflush(ErrFp);
|
||||
DBufGetMallocStats(&num_mallocs, &bytes_malloced);
|
||||
fprintf(ErrFp, "DynBuf Mallocs: %lu mallocs; %lu bytes\n",
|
||||
(unsigned long) num_mallocs, (unsigned long) bytes_malloced);
|
||||
fprintf(ErrFp, "Variable hash table statistics:\n");
|
||||
dump_var_hash_stats();
|
||||
|
||||
@@ -1518,11 +1521,11 @@ int DoRun(ParsePtr p)
|
||||
if ( (r=ParseToken(p, &buf)) ) return r;
|
||||
|
||||
/* Only allow RUN ON in top-level script */
|
||||
if (! StrCmpi(DBufValue(&buf), "ON")) {
|
||||
if (! strcasecmp(DBufValue(&buf), "ON")) {
|
||||
if (TopLevel()) RunDisabled &= ~RUN_SCRIPT;
|
||||
}
|
||||
/* But allow RUN OFF anywhere */
|
||||
else if (! StrCmpi(DBufValue(&buf), "OFF"))
|
||||
else if (! strcasecmp(DBufValue(&buf), "OFF"))
|
||||
RunDisabled |= RUN_SCRIPT;
|
||||
else {
|
||||
DBufFree(&buf);
|
||||
@@ -1550,11 +1553,11 @@ int DoExpr(ParsePtr p)
|
||||
if ( (r=ParseToken(p, &buf)) ) return r;
|
||||
|
||||
/* Only allow EXPR ON in top-level script */
|
||||
if (! StrCmpi(DBufValue(&buf), "ON")) {
|
||||
if (! strcasecmp(DBufValue(&buf), "ON")) {
|
||||
if (TopLevel()) ExpressionEvaluationDisabled = 0;
|
||||
}
|
||||
/* But allow EXPR OFF anywhere */
|
||||
else if (! StrCmpi(DBufValue(&buf), "OFF"))
|
||||
else if (! strcasecmp(DBufValue(&buf), "OFF"))
|
||||
ExpressionEvaluationDisabled = 1;
|
||||
else {
|
||||
DBufFree(&buf);
|
||||
@@ -1730,7 +1733,6 @@ static char const *OutputEscapeSequences(char const *s, int print, DynamicBuffer
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
#define ISWBLANK(c) (iswspace(c) && (c) != '\n')
|
||||
static wchar_t const *OutputEscapeSequencesWS(wchar_t const *s, int print, DynamicBuffer *output)
|
||||
{
|
||||
@@ -1848,7 +1850,7 @@ FillParagraphWC(char const *s, DynamicBuffer *output)
|
||||
free(buf);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FillParagraph */
|
||||
@@ -1864,7 +1866,7 @@ FillParagraphWC(char const *s, DynamicBuffer *output)
|
||||
/* A macro safe ONLY if used with arg with no side effects! */
|
||||
#define ISBLANK(c) (isspace(c) && (c) != '\n')
|
||||
|
||||
void FillParagraph(char const *s, DynamicBuffer *output)
|
||||
void FillParagraph(char const *url, char const *s, DynamicBuffer *output)
|
||||
{
|
||||
|
||||
int line = 0;
|
||||
@@ -1881,11 +1883,16 @@ void FillParagraph(char const *s, DynamicBuffer *output)
|
||||
while(ISBLANK(*s)) s++;
|
||||
if (!*s) return;
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (url) {
|
||||
printf("\x1B]8;;%s\x1B\\", url);
|
||||
}
|
||||
|
||||
if (FillParagraphWC(s, output) == OK) {
|
||||
if (url) {
|
||||
printf("\x1B]8;;\x1B\\");
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Start formatting */
|
||||
while(1) {
|
||||
@@ -1899,6 +1906,9 @@ void FillParagraph(char const *s, DynamicBuffer *output)
|
||||
continue;
|
||||
}
|
||||
if (!*s) {
|
||||
if (url) {
|
||||
printf("\x1B]8;;\x1B\\");
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Over here, we're at the beginning of a line. Emit the correct
|
||||
@@ -1933,6 +1943,9 @@ void FillParagraph(char const *s, DynamicBuffer *output)
|
||||
len++;
|
||||
}
|
||||
if (s == t) {
|
||||
if (url) {
|
||||
printf("\x1B]8;;\x1B\\");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!pendspace || len+pendspace <= roomleft) {
|
||||
@@ -2122,7 +2135,7 @@ SaveLastTrigger(Trigger const *t)
|
||||
DBufInit(&(LastTrigger.tags));
|
||||
|
||||
if (LastTrigger.tz) {
|
||||
LastTrigger.tz = StrDup(LastTrigger.tz);
|
||||
LastTrigger.tz = strdup(LastTrigger.tz);
|
||||
}
|
||||
DBufPuts(&(LastTrigger.tags), DBufValue(&(t->tags)));
|
||||
TrigInfo *cur = t->infos;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Calculations for figuring out moon phases. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* the data structures for OMITted dates. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -501,6 +501,9 @@ int DoOmit(ParsePtr p)
|
||||
int
|
||||
AddGlobalOmit(int dse)
|
||||
{
|
||||
if (dse < 0) {
|
||||
return OK;
|
||||
}
|
||||
if (NumFullOmits == MAX_FULL_OMITS) return E_2MANY_FULL;
|
||||
if (!BexistsIntArray(FullOmitArray, NumFullOmits, dse)) {
|
||||
InsertIntoSortedArray(FullOmitArray, NumFullOmits, dse);
|
||||
|
||||
35
src/protos.h
35
src/protos.h
@@ -5,7 +5,7 @@
|
||||
/* Function Prototypes. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -13,20 +13,8 @@
|
||||
/* Suppress unused variable warnings */
|
||||
#define UNUSED(x) (void) x
|
||||
|
||||
#ifdef HAVE_STRDUP
|
||||
#define StrDup strdup
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRNCASECMP
|
||||
#define StrinCmp strncasecmp
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRCASECMP
|
||||
#define StrCmpi strcasecmp
|
||||
#endif
|
||||
|
||||
/* Define a string assignment macro - be careful!!! */
|
||||
#define STRSET(x, str) { if (x) free(x); (x) = StrDup(str); }
|
||||
#define STRSET(x, str) { if (x) free(x); (x) = strdup(str); }
|
||||
|
||||
/* Define a general malloc routine for creating pointers to objects */
|
||||
#define NEW(type) (malloc(sizeof(type)))
|
||||
@@ -131,18 +119,6 @@ int ComputeTriggerNoAdjustDuration (int today, Trigger *trig, TimeTrig const *ti
|
||||
int AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int save_in_globals);
|
||||
char *StrnCpy (char *dest, char const *source, int n);
|
||||
|
||||
#ifndef HAVE_STRNCASECMP
|
||||
int StrinCmp (char const *s1, char const *s2, int n);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
char *StrDup (char const *s);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASECMP
|
||||
int StrCmpi (char const *s1, char const *s2);
|
||||
#endif
|
||||
|
||||
void strtolower(char *s);
|
||||
|
||||
Var *FindVar (char const *str, int create);
|
||||
@@ -168,13 +144,14 @@ int ParseNonSpaceChar (ParsePtr p, int *err, int peek);
|
||||
unsigned int HashVal_preservecase(char const *str);
|
||||
int DateOK (int y, int m, int d);
|
||||
BuiltinFunc *FindBuiltinFunc (char const *name);
|
||||
int InsertIntoSortBuffer (int dse, int tim, char const *body, int typ, int prio);
|
||||
int InsertIntoSortBuffer (int dse, int tim, char const *url, char const *body, int typ, int prio);
|
||||
void IssueSortedReminders (void);
|
||||
UserFunc *FindUserFunc(char const *name);
|
||||
int UserFuncExists (char const *fn);
|
||||
void DSEToHeb (int dse, int *hy, int *hm, int *hd);
|
||||
int HebNameToNum (char const *mname);
|
||||
char const *HebMonthName (int m, int y);
|
||||
char const *IvritMonthName (int m, int y);
|
||||
int HebToDSE (int hy, int hm, int hd);
|
||||
int GetValidHebDate (int yin, int min, int din, int adarbehave, int *mout, int *dout, int yahr);
|
||||
int GetNextHebrewDate (int dsestart, int hm, int hd, int yahr, int adarbehave, int *ans);
|
||||
@@ -183,7 +160,7 @@ int GetSysVar (char const *name, Value *val);
|
||||
int SetSysVar (char const *name, Value *val);
|
||||
void DumpSysVarByName (char const *name);
|
||||
int CalcMinsFromUTC (int dse, int tim, int *mins, int *isdst);
|
||||
void FillParagraph (char const *s, DynamicBuffer *output);
|
||||
void FillParagraph (char const *url, char const *s, DynamicBuffer *output);
|
||||
void LocalToUTC (int locdate, int loctime, int *utcdate, int *utctime);
|
||||
void UTCToLocal (int utcdate, int utctime, int *locdate, int *loctime);
|
||||
int MoonPhase (int date, int time);
|
||||
@@ -224,12 +201,10 @@ void FixSpecialType(Trigger *trig);
|
||||
void WriteJSONTrigger(Trigger const *t, int include_tags);
|
||||
void WriteJSONTimeTrigger(TimeTrig const *tt);
|
||||
int GetOnceDate(void);
|
||||
#ifdef REM_USE_WCHAR
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
void PutWideChar(wchar_t const wc, DynamicBuffer *output);
|
||||
#endif
|
||||
|
||||
/* These functions are in utils.c and are used to detect overflow
|
||||
in various arithmetic operators. They have to be in separate
|
||||
|
||||
15
src/queue.c
15
src/queue.c
@@ -5,7 +5,7 @@
|
||||
/* Queue up reminders for subsequent execution. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -140,7 +140,7 @@ int QueueReminder(ParsePtr p, Trigger *trig,
|
||||
TimeTrig const *tim, char const *sched)
|
||||
{
|
||||
QueuedRem *qelem;
|
||||
|
||||
TrigInfo *ti;
|
||||
if (DontQueue ||
|
||||
trig->noqueue ||
|
||||
tim->ttime == NO_TIME ||
|
||||
@@ -155,7 +155,7 @@ int QueueReminder(ParsePtr p, Trigger *trig,
|
||||
qelem->red = DefaultColorR;
|
||||
qelem->green = DefaultColorG;
|
||||
qelem->blue = DefaultColorB;
|
||||
qelem->text = StrDup(p->pos); /* Guaranteed that parser is not nested. */
|
||||
qelem->text = strdup(p->pos); /* Guaranteed that parser is not nested. */
|
||||
if (!qelem->text) {
|
||||
free(qelem);
|
||||
return E_NO_MEM;
|
||||
@@ -169,8 +169,13 @@ int QueueReminder(ParsePtr p, Trigger *trig,
|
||||
qelem->tt = *tim;
|
||||
qelem->t = *trig;
|
||||
|
||||
/* Take over infos */
|
||||
trig->infos = NULL;
|
||||
/* Copy infos */
|
||||
qelem->t.infos = NULL;
|
||||
ti = trig->infos;
|
||||
while(ti) {
|
||||
(void) AppendTrigInfo(&qelem->t, ti->info);
|
||||
ti = ti->next;
|
||||
}
|
||||
|
||||
DBufInit(&(qelem->t.tags));
|
||||
DBufPuts(&(qelem->t.tags), DBufValue(&(trig->tags)));
|
||||
|
||||
52
src/rem2ps.c
52
src/rem2ps.c
@@ -5,7 +5,7 @@
|
||||
/* Print a PostScript calendar. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -154,24 +154,6 @@ put_escaped_string(char const *s)
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* StrCmpi */
|
||||
/* */
|
||||
/* Compare strings, case insensitive. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int StrCmpi(char const *s1, char const *s2)
|
||||
{
|
||||
int r;
|
||||
while (*s1 && *s2) {
|
||||
r = toupper(*s1) - toupper(*s2);
|
||||
if (r) return r;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return toupper(*s1) - toupper(*s2);
|
||||
}
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* Parse the new-style JSON intermediate format */
|
||||
@@ -229,18 +211,18 @@ JSONToCalEntry(DynamicBuffer const *buf)
|
||||
} else if (!strcmp(nm, "passthru")) {
|
||||
if (v->type == json_string) {
|
||||
s = v->u.string.ptr;
|
||||
if (!StrCmpi(s, "PostScript")) {
|
||||
if (!strcasecmp(s, "PostScript")) {
|
||||
c->special = SPECIAL_POSTSCRIPT;
|
||||
} else if (!StrCmpi(s, "SHADE")) {
|
||||
} else if (!strcasecmp(s, "SHADE")) {
|
||||
c->special = SPECIAL_SHADE;
|
||||
} else if (!StrCmpi(s, "MOON")) {
|
||||
} else if (!strcasecmp(s, "MOON")) {
|
||||
c->special = SPECIAL_MOON;
|
||||
} else if (!StrCmpi(s, "WEEK")) {
|
||||
} else if (!strcasecmp(s, "WEEK")) {
|
||||
c->special = SPECIAL_WEEK;
|
||||
} else if (!StrCmpi(s, "PSFile")) {
|
||||
} else if (!strcasecmp(s, "PSFile")) {
|
||||
c->special = SPECIAL_PSFILE;
|
||||
} else if (!StrCmpi(s, "COLOUR") ||
|
||||
!StrCmpi(s, "COLOR")) {
|
||||
} else if (!strcasecmp(s, "COLOUR") ||
|
||||
!strcasecmp(s, "COLOR")) {
|
||||
c->special = SPECIAL_COLOR;
|
||||
} else {
|
||||
c->special = SPECIAL_UNKNOWN;
|
||||
@@ -301,20 +283,20 @@ TextToCalEntry(DynamicBuffer *buf)
|
||||
strcpy(c->entry, startOfBody);
|
||||
|
||||
/* Save the type of SPECIAL */
|
||||
if (!StrCmpi(passthru, "PostScript")) {
|
||||
if (!strcasecmp(passthru, "PostScript")) {
|
||||
c->special = SPECIAL_POSTSCRIPT;
|
||||
} else if (!StrCmpi(passthru, "SHADE")) {
|
||||
} else if (!strcasecmp(passthru, "SHADE")) {
|
||||
c->special = SPECIAL_SHADE;
|
||||
} else if (!StrCmpi(passthru, "MOON")) {
|
||||
} else if (!strcasecmp(passthru, "MOON")) {
|
||||
c->special = SPECIAL_MOON;
|
||||
} else if (!StrCmpi(passthru, "WEEK")) {
|
||||
} else if (!strcasecmp(passthru, "WEEK")) {
|
||||
c->special = SPECIAL_WEEK;
|
||||
} else if (!StrCmpi(passthru, "PSFile")) {
|
||||
} else if (!strcasecmp(passthru, "PSFile")) {
|
||||
c->special = SPECIAL_PSFILE;
|
||||
} else if (!StrCmpi(passthru, "COLOUR") ||
|
||||
!StrCmpi(passthru, "COLOR")) {
|
||||
} else if (!strcasecmp(passthru, "COLOUR") ||
|
||||
!strcasecmp(passthru, "COLOR")) {
|
||||
c->special = SPECIAL_COLOR;
|
||||
} else if (StrCmpi(passthru, "*")) {
|
||||
} else if (strcasecmp(passthru, "*")) {
|
||||
c->special = SPECIAL_UNKNOWN;
|
||||
}
|
||||
return c;
|
||||
@@ -350,7 +332,7 @@ int main(int argc, char const *argv[])
|
||||
!strcmp(DBufValue(&buf), PSBEGIN2)) {
|
||||
if (!validfile) {
|
||||
if (Verbose) {
|
||||
fprintf(stderr, "Rem2PS: Version %s Copyright (C) 1992-2025 by Dianne Skoll\n\n", VERSION);
|
||||
fprintf(stderr, "Rem2PS: Version %s Copyright (C) 1992-2026 by Dianne Skoll\n\n", VERSION);
|
||||
fprintf(stderr, "Generating PostScript calendar\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Define the PostScript prologue */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -14,7 +14,7 @@ char *PSProlog1[] =
|
||||
{
|
||||
"% This file was produced by Remind and Rem2PS, written by",
|
||||
"% Dianne Skoll.",
|
||||
"% Remind and Rem2PS are Copyright (C) 1992-2025 Dianne Skoll.",
|
||||
"% Remind and Rem2PS are Copyright (C) 1992-2026 Dianne Skoll.",
|
||||
"/ISOLatin1Encoding where { pop save true }{ false } ifelse",
|
||||
" /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus",
|
||||
" StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute",
|
||||
|
||||
77
src/sort.c
77
src/sort.c
@@ -5,7 +5,7 @@
|
||||
/* Routines for sorting reminders by trigger date */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -25,6 +25,7 @@
|
||||
typedef struct sortrem {
|
||||
struct sortrem *next;
|
||||
char const *text;
|
||||
char const *url;
|
||||
int trigdate;
|
||||
int trigtime;
|
||||
int typ;
|
||||
@@ -34,7 +35,7 @@ typedef struct sortrem {
|
||||
/* The sorted reminder queue */
|
||||
static Sortrem *SortedQueue = (Sortrem *) NULL;
|
||||
|
||||
static Sortrem *MakeSortRem (int dse, int tim, char const *body, int typ, int prio);
|
||||
static Sortrem *MakeSortRem (int dse, int tim, char const *url, char const *body, int typ, int prio);
|
||||
static void IssueSortBanner (int dse);
|
||||
|
||||
/***************************************************************/
|
||||
@@ -44,23 +45,33 @@ static void IssueSortBanner (int dse);
|
||||
/* Create a new Sortrem entry - return NULL on failure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static Sortrem *MakeSortRem(int dse, int tim, char const *body, int typ, int prio)
|
||||
static Sortrem *MakeSortRem(int dse, int tim, char const *url, char const *body, int typ, int prio)
|
||||
{
|
||||
Sortrem *new = NEW(Sortrem);
|
||||
if (!new) return NULL;
|
||||
Sortrem *srem = NEW(Sortrem);
|
||||
if (!srem) return NULL;
|
||||
|
||||
new->text = StrDup(body);
|
||||
if (!new->text) {
|
||||
free(new);
|
||||
srem->text = strdup(body);
|
||||
if (!srem->text) {
|
||||
free(srem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new->trigdate = dse;
|
||||
new->trigtime = tim;
|
||||
new->typ = typ;
|
||||
new->priority = prio;
|
||||
new->next = NULL;
|
||||
return new;
|
||||
if (url) {
|
||||
srem->url = strdup(url);
|
||||
if (!srem->url) {
|
||||
free((char *) srem->text);
|
||||
free(srem);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
srem->url = NULL;
|
||||
}
|
||||
|
||||
srem->trigdate = dse;
|
||||
srem->trigtime = tim;
|
||||
srem->typ = typ;
|
||||
srem->priority = prio;
|
||||
srem->next = NULL;
|
||||
return srem;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -70,13 +81,13 @@ static Sortrem *MakeSortRem(int dse, int tim, char const *body, int typ, int pri
|
||||
/* Insert a reminder into the sort buffer */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int InsertIntoSortBuffer(int dse, int tim, char const *body, int typ, int prio)
|
||||
int InsertIntoSortBuffer(int dse, int tim, char const *url, char const *body, int typ, int prio)
|
||||
{
|
||||
Sortrem *new = MakeSortRem(dse, tim, body, typ, prio);
|
||||
Sortrem *srem = MakeSortRem(dse, tim, url, body, typ, prio);
|
||||
Sortrem *cur = SortedQueue, *prev = NULL;
|
||||
int ShouldGoAfter;
|
||||
|
||||
if (!new) {
|
||||
if (!srem) {
|
||||
Eprint("%s", GetErr(E_NO_MEM));
|
||||
IssueSortedReminders();
|
||||
SortByDate = 0;
|
||||
@@ -88,11 +99,11 @@ int InsertIntoSortBuffer(int dse, int tim, char const *body, int typ, int prio)
|
||||
|
||||
/* Find the correct place in the sorted list */
|
||||
if (!SortedQueue) {
|
||||
SortedQueue = new;
|
||||
SortedQueue = srem;
|
||||
return OK;
|
||||
}
|
||||
while (cur) {
|
||||
ShouldGoAfter = CompareRems(new->trigdate, new->trigtime, new->priority,
|
||||
ShouldGoAfter = CompareRems(srem->trigdate, srem->trigtime, srem->priority,
|
||||
cur->trigdate, cur->trigtime, cur->priority,
|
||||
SortByDate, SortByTime, SortByPrio, UntimedBeforeTimed);
|
||||
|
||||
@@ -101,22 +112,21 @@ int InsertIntoSortBuffer(int dse, int tim, char const *body, int typ, int prio)
|
||||
cur = cur->next;
|
||||
} else {
|
||||
if (prev) {
|
||||
prev->next = new;
|
||||
new->next = cur;
|
||||
prev->next = srem;
|
||||
srem->next = cur;
|
||||
} else {
|
||||
SortedQueue = new;
|
||||
new->next = cur;
|
||||
SortedQueue = srem;
|
||||
srem->next = cur;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
prev->next = new;
|
||||
new->next = cur; /* For safety - actually redundant */
|
||||
prev->next = srem;
|
||||
srem->next = cur; /* For safety - actually redundant */
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* IssueSortedReminders */
|
||||
@@ -141,7 +151,13 @@ void IssueSortedReminders(void)
|
||||
IssueSortBanner(cur->trigdate);
|
||||
olddate = cur->trigdate;
|
||||
}
|
||||
if (cur->url) {
|
||||
printf("\x1B]8;;%s\x1B\\", cur->url);
|
||||
}
|
||||
printf("%s", cur->text);
|
||||
if (cur->url) {
|
||||
printf("\x1B]8;;\x1B\\");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -150,7 +166,7 @@ void IssueSortedReminders(void)
|
||||
IssueSortBanner(cur->trigdate);
|
||||
olddate = cur->trigdate;
|
||||
}
|
||||
FillParagraph(cur->text, NULL);
|
||||
FillParagraph(cur->url, cur->text, NULL);
|
||||
break;
|
||||
|
||||
case RUN_TYPE:
|
||||
@@ -159,6 +175,9 @@ void IssueSortedReminders(void)
|
||||
}
|
||||
|
||||
free((char *) cur->text);
|
||||
if (cur->url) {
|
||||
free((char *) cur->url);
|
||||
}
|
||||
free(cur);
|
||||
cur = next;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* classifying the tokens parsed. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -48,6 +48,7 @@ Token TokArray[] = {
|
||||
{ "cal", 3, T_RemType, CAL_TYPE },
|
||||
{ "clear-omit-context", 5, T_Clr, 0 },
|
||||
{ "complete-through", 16, T_CompleteThrough, 0 },
|
||||
{ "completed-through", 17, T_CompleteThrough, 0 },
|
||||
{ "debug", 5, T_Debug, 0 },
|
||||
{ "december", 3, T_Month, 11 },
|
||||
{ "do", 2, T_IncludeR, 0 },
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* the TRANSLATE keyword. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -443,19 +443,19 @@ DoTranslate(ParsePtr p)
|
||||
r = ParseToken(p, &orig);
|
||||
if (r) return r;
|
||||
r = VerifyEoln(p);
|
||||
if (!StrCmpi(DBufValue(&orig), "dump")) {
|
||||
if (!strcasecmp(DBufValue(&orig), "dump")) {
|
||||
DBufFree(&orig);
|
||||
if (r) return r;
|
||||
DumpTranslationTable(stdout, 0);
|
||||
return OK;
|
||||
}
|
||||
if (!StrCmpi(DBufValue(&orig), "clear")) {
|
||||
if (!strcasecmp(DBufValue(&orig), "clear")) {
|
||||
DBufFree(&orig);
|
||||
if (r) return r;
|
||||
ClearTranslationTable();
|
||||
return OK;
|
||||
}
|
||||
if (!StrCmpi(DBufValue(&orig), "generate")) {
|
||||
if (!strcasecmp(DBufValue(&orig), "generate")) {
|
||||
DBufFree(&orig);
|
||||
if (r) return r;
|
||||
GenerateTranslationTemplate();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Routines for figuring out the trigger date of a reminder */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -738,7 +738,7 @@ NewTrigInfo(char const *i)
|
||||
return NULL;
|
||||
}
|
||||
ti->next = NULL;
|
||||
ti->info = StrDup(i);
|
||||
ti->info = strdup(i);
|
||||
if (!ti->info) {
|
||||
free(ti);
|
||||
return NULL;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Type definitions all dumped here. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* functions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -318,7 +318,7 @@ int DoFset(ParsePtr p)
|
||||
}
|
||||
/* If we've already seen this local variable, error */
|
||||
for (i=0; i<func->nargs; i++) {
|
||||
if (!StrinCmp(DBufValue(&buf), local_array[i].name, VAR_NAME_LEN)) {
|
||||
if (!strncasecmp(DBufValue(&buf), local_array[i].name, VAR_NAME_LEN)) {
|
||||
DBufFree(&buf);
|
||||
DestroyUserFunc(func);
|
||||
return E_REPEATED_ARG;
|
||||
@@ -393,7 +393,7 @@ int DoFset(ParsePtr p)
|
||||
return E_NO_MEM;
|
||||
}
|
||||
for (i=0; i<func->nargs; i++) {
|
||||
func->args[i] = StrDup(local_array[i].name);
|
||||
func->args[i] = strdup(local_array[i].name);
|
||||
if (!func->args[i]) {
|
||||
DestroyUserFunc(func);
|
||||
return E_NO_MEM;
|
||||
@@ -619,7 +619,7 @@ static UserFunc *clone_userfunc(char const *name, int *r)
|
||||
return NULL;
|
||||
}
|
||||
for (i=0; i<dest->nargs; i++) {
|
||||
dest->args[i] = StrDup(src->args[i]);
|
||||
dest->args[i] = strdup(src->args[i]);
|
||||
if (!dest->args[i]) {
|
||||
DestroyUserFunc(dest);
|
||||
return NULL;
|
||||
|
||||
63
src/utils.c
63
src/utils.c
@@ -5,7 +5,7 @@
|
||||
/* Useful utility functions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -140,67 +140,6 @@ char *StrnCpy(char *dest, char const *source, int n)
|
||||
return odest;
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRNCASECMP
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* StrinCmp - compare strings, case-insensitive */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int StrinCmp(char const *s1, char const *s2, int n)
|
||||
{
|
||||
register int r;
|
||||
while (n && *s1 && *s2) {
|
||||
n--;
|
||||
r = toupper(*s1) - toupper(*s2);
|
||||
if (r) return r;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
if (n) return (toupper(*s1) - toupper(*s2)); else return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* StrDup */
|
||||
/* */
|
||||
/* Like ANSI strdup */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char *StrDup(char const *s)
|
||||
{
|
||||
char *ret = malloc(strlen(s)+1);
|
||||
if (!ret) return NULL;
|
||||
strcpy(ret, s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASECMP
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* StrCmpi */
|
||||
/* */
|
||||
/* Compare strings, case insensitive. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int StrCmpi(char const *s1, char const *s2)
|
||||
{
|
||||
int r;
|
||||
while (*s1 && *s2) {
|
||||
r = toupper(*s1) - toupper(*s2);
|
||||
if (r) return r;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return toupper(*s1) - toupper(*s2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DateOK */
|
||||
|
||||
50
src/var.c
50
src/var.c
@@ -6,7 +6,7 @@
|
||||
/* user- and system-defined variables. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2026 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -52,7 +52,7 @@ static int VarCompareFunc(void const *a, void const *b)
|
||||
{
|
||||
Var *x = (Var *) a;
|
||||
Var *y = (Var *) b;
|
||||
return StrCmpi(x->name, y->name);
|
||||
return strcasecmp(x->name, y->name);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -220,15 +220,15 @@ static int warning_level_func(int do_set, Value *val)
|
||||
if (!strcmp(val->v.str, VERSION)) {
|
||||
WarningLevel = NULL;
|
||||
} else {
|
||||
WarningLevel = StrDup(val->v.str);
|
||||
WarningLevel = strdup(val->v.str);
|
||||
if (!WarningLevel) return E_NO_MEM;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
if (!WarningLevel) {
|
||||
val->v.str = StrDup(VERSION);
|
||||
val->v.str = strdup(VERSION);
|
||||
} else {
|
||||
val->v.str = StrDup(WarningLevel);
|
||||
val->v.str = strdup(WarningLevel);
|
||||
}
|
||||
if (!val->v.str) {
|
||||
return E_NO_MEM;
|
||||
@@ -257,14 +257,14 @@ static int oncefile_func(int do_set, Value *val)
|
||||
if (OnceFile) {
|
||||
free( (void *) OnceFile);
|
||||
}
|
||||
OnceFile = StrDup(val->v.str);
|
||||
OnceFile = strdup(val->v.str);
|
||||
if (!OnceFile) return E_NO_MEM;
|
||||
return OK;
|
||||
}
|
||||
if (!OnceFile) {
|
||||
val->v.str = StrDup("");
|
||||
val->v.str = strdup("");
|
||||
} else {
|
||||
val->v.str = StrDup(OnceFile);
|
||||
val->v.str = strdup(OnceFile);
|
||||
}
|
||||
if (!val->v.str) return E_NO_MEM;
|
||||
val->type = STR_TYPE;
|
||||
@@ -403,6 +403,14 @@ static int trig_wday_func(int do_set, Value *val)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Cache $Ud, $Um and $Uy */
|
||||
static int Ucached = -1;
|
||||
static int Udcached = -1;
|
||||
static int Umcached = -1;
|
||||
static int Uycached = -1;
|
||||
|
||||
#define FILL_U_CACHE(x) do { if (Ucached != x) { FromDSE(x, &Uycached, &Umcached, &Udcached); Ucached = x; } } while(0)
|
||||
|
||||
static int today_date_func(int do_set, Value *val)
|
||||
{
|
||||
UNUSED(do_set);
|
||||
@@ -412,31 +420,28 @@ static int today_date_func(int do_set, Value *val)
|
||||
}
|
||||
static int today_day_func(int do_set, Value *val)
|
||||
{
|
||||
int d;
|
||||
UNUSED(do_set);
|
||||
val->type = INT_TYPE;
|
||||
FromDSE(DSEToday, NULL, NULL, &d);
|
||||
val->v.val = d;
|
||||
FILL_U_CACHE(DSEToday);
|
||||
val->v.val = Udcached;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int today_mon_func(int do_set, Value *val)
|
||||
{
|
||||
int m;
|
||||
UNUSED(do_set);
|
||||
val->type = INT_TYPE;
|
||||
FromDSE(DSEToday, NULL, &m, NULL);
|
||||
val->v.val = m+1;
|
||||
FILL_U_CACHE(DSEToday);
|
||||
val->v.val = Umcached + 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int today_year_func(int do_set, Value *val)
|
||||
{
|
||||
int y;
|
||||
UNUSED(do_set);
|
||||
val->type = INT_TYPE;
|
||||
FromDSE(DSEToday, &y, NULL, NULL);
|
||||
val->v.val = y;
|
||||
FILL_U_CACHE(DSEToday);
|
||||
val->v.val = Uycached;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1109,6 +1114,7 @@ static SysVar SysVarArr[] = {
|
||||
{"Tb", 0, SPECIAL_TYPE, trig_base_func, 0, 0 },
|
||||
{"Td", 0, SPECIAL_TYPE, trig_day_func, 0, 0 },
|
||||
{"TerminalBackground", 0, SPECIAL_TYPE, terminal_bg_func, 0, 0 },
|
||||
{"TerminalHyperlinks", 1, INT_TYPE, &TerminalHyperlinks, 0, 1 },
|
||||
{"Thursday", 1, TRANS_TYPE, "Thursday", 0, 0 },
|
||||
{"TimeSep", 1, SPECIAL_TYPE, time_sep_func, 0, 0 },
|
||||
{"TimetIs64bit", 0, SPECIAL_TYPE, timet_is_64_func, 0, 0 },
|
||||
@@ -1397,9 +1403,9 @@ static int GetTranslatableVariable(SysVar const *v, Value *value)
|
||||
{
|
||||
char const *translated = tr((char const *) v->value);
|
||||
if (translated) {
|
||||
value->v.str = StrDup(translated);
|
||||
value->v.str = strdup(translated);
|
||||
} else {
|
||||
value->v.str = StrDup("");
|
||||
value->v.str = strdup("");
|
||||
}
|
||||
if (!value->v.str) return E_NO_MEM;
|
||||
value->type = STR_TYPE;
|
||||
@@ -1491,9 +1497,9 @@ int GetSysVar(char const *name, Value *val)
|
||||
return f(0, val);
|
||||
} else if (v->type == STR_TYPE) {
|
||||
if (! * (char **) v->value) {
|
||||
val->v.str = StrDup("");
|
||||
val->v.str = strdup("");
|
||||
} else {
|
||||
val->v.str = StrDup(*((char **) v->value));
|
||||
val->v.str = strdup(*((char **) v->value));
|
||||
}
|
||||
if (!val->v.str) return E_NO_MEM;
|
||||
} else {
|
||||
@@ -1524,7 +1530,7 @@ SysVar *FindSysVar(char const *name)
|
||||
int r;
|
||||
|
||||
while (top >= bottom) {
|
||||
r = StrCmpi(name, SysVarArr[mid].name);
|
||||
r = strcasecmp(name, SysVarArr[mid].name);
|
||||
if (!r) return &SysVarArr[mid];
|
||||
else if (r>0) bottom = mid+1;
|
||||
else top = mid-1;
|
||||
|
||||
@@ -80,6 +80,7 @@ CalMode
|
||||
CalType
|
||||
CalcMinsFromUTC
|
||||
CalcUTC
|
||||
Chanukah
|
||||
Clément
|
||||
Config
|
||||
Conover
|
||||
@@ -135,6 +136,7 @@ Emanuele
|
||||
EndSent
|
||||
EndSentIg
|
||||
EntrySize
|
||||
Esc
|
||||
Example2
|
||||
Expr
|
||||
ExpressionTimeLimit
|
||||
@@ -210,6 +212,7 @@ Joop
|
||||
Kamens
|
||||
Kasdorp
|
||||
Katan
|
||||
Kheshvan
|
||||
Kiefte
|
||||
Koningsdag
|
||||
Kristian
|
||||
@@ -243,6 +246,9 @@ MSC
|
||||
MSF
|
||||
MSGPREFIX
|
||||
MSGSUFFIX
|
||||
MUSL
|
||||
MUSL
|
||||
MUSL's
|
||||
Madsen
|
||||
Makefile
|
||||
Makefiles
|
||||
@@ -304,6 +310,8 @@ Pango
|
||||
ParseUntriggered
|
||||
Paulo
|
||||
Pelzl
|
||||
PgDn
|
||||
PgUp
|
||||
Philipp
|
||||
Pinard
|
||||
Plaser
|
||||
@@ -395,9 +403,11 @@ Tcl
|
||||
Td
|
||||
Terbeck
|
||||
TerminalBackground
|
||||
TerminalHyperlinks
|
||||
Thronicke
|
||||
TimeSep
|
||||
TimetIs64bit
|
||||
Tishrei
|
||||
Tishrey
|
||||
TitleSize
|
||||
Tk
|
||||
@@ -526,6 +536,7 @@ dev
|
||||
devel
|
||||
dfs
|
||||
dh
|
||||
dialogs
|
||||
difftime
|
||||
doesn
|
||||
dosubst
|
||||
@@ -588,6 +599,7 @@ gaa
|
||||
garbhol
|
||||
gcc
|
||||
getenv
|
||||
glibc's
|
||||
grey
|
||||
greyed
|
||||
gridline
|
||||
@@ -632,6 +644,7 @@ itkpdf
|
||||
itkprint
|
||||
itkremind
|
||||
ivar
|
||||
ivritmon
|
||||
j2
|
||||
jahr
|
||||
jahrzeit
|
||||
@@ -672,6 +685,8 @@ maxlen
|
||||
maybexs
|
||||
mbchar
|
||||
mbindex
|
||||
mbpad
|
||||
mbstowcs
|
||||
mbstrlen
|
||||
mbsubstr
|
||||
md
|
||||
@@ -819,6 +834,7 @@ soleq
|
||||
somefile
|
||||
sortbanner
|
||||
spc
|
||||
spc2
|
||||
spellintian
|
||||
src
|
||||
srczone
|
||||
@@ -939,6 +955,8 @@ varname
|
||||
ve
|
||||
w0
|
||||
wakeups
|
||||
wchar
|
||||
wcstombs
|
||||
weekno
|
||||
wfun
|
||||
whoami
|
||||
@@ -973,3 +991,20 @@ ziens
|
||||
zj
|
||||
zn
|
||||
één
|
||||
א
|
||||
אב
|
||||
אדר
|
||||
אדר
|
||||
אדר
|
||||
אייר
|
||||
אלול
|
||||
ב
|
||||
חשוון
|
||||
טבת
|
||||
כסלו
|
||||
ניסן
|
||||
ניסן
|
||||
סיון
|
||||
שבט
|
||||
תמוז
|
||||
תשרי
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# in the build directory.
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 Dianne Skoll
|
||||
# Copyright (C) 1992-2026 Dianne Skoll
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -27,13 +27,23 @@ if test `id -u` = 0 ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REMIND="../src/remind --flush -q"
|
||||
REMIND_CMD=${REMIND_CMD:-../src/remind}
|
||||
REM2PS=${REM2PS:-../src/rem2ps}
|
||||
REMIND="$REMIND_CMD --flush -q"
|
||||
OUT="../tests/test.out"
|
||||
CMP="../tests/test.cmp"
|
||||
# Set a known timezone so moon phases show up in predictable places
|
||||
TZ=UTC
|
||||
export TZ
|
||||
|
||||
# No localization, but we want a UTF-8 locale.
|
||||
LANG=C.UTF-8
|
||||
export LANG
|
||||
LC_ALL=C.UTF-8
|
||||
export LC_ALL
|
||||
|
||||
unset LC_PAPER
|
||||
|
||||
# Check if "grep" accepts "-a" flag
|
||||
echo TEST | grep -a TEST > /dev/null 2>&1
|
||||
if test $? = 0 ; then
|
||||
@@ -62,25 +72,6 @@ else
|
||||
DELAY=1
|
||||
fi
|
||||
|
||||
# If we're already in a utf-8 locale, do
|
||||
# nothing; otherwise, set LC_ALL
|
||||
OK=0
|
||||
if echo $LC_ALL | grep -i utf-8 > /dev/null 2>&1 ; then
|
||||
OK=1
|
||||
fi
|
||||
|
||||
if test -z "$LC_ALL" ; then
|
||||
if echo $LANG | grep -i utf-8 > /dev/null 2>&1 ; then
|
||||
export LC_ALL="$LANG"
|
||||
OK=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$OK" = 0 ; then
|
||||
export LC_ALL=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
fi
|
||||
|
||||
chmod 000 include_dir/04cantread.rem
|
||||
TEST_GETENV="foo bar baz" ; export TEST_GETENV
|
||||
echo "Test 1" > $OUT
|
||||
@@ -189,8 +180,8 @@ rm -f ../tests/purge_dir/*.rem.purged >> $OUT 2>&1
|
||||
|
||||
$REMIND ../tests/runtest.rem >> $OUT 2>&1
|
||||
|
||||
$REMIND -p ../tests/shade.rem 1 August 2009 | ../src/rem2ps -e -l -c3 >> $OUT 2>&1
|
||||
$REMIND -pp ../tests/shade.rem 1 August 2009 | ../src/rem2ps -e -l -c3 >> $OUT 2>&1
|
||||
$REMIND -p ../tests/shade.rem 1 August 2009 | "$REM2PS" -e -l -c3 >> $OUT 2>&1
|
||||
$REMIND -pp ../tests/shade.rem 1 August 2009 | "$REM2PS" -e -l -c3 >> $OUT 2>&1
|
||||
|
||||
TZ=America/Toronto $REMIND ../tests/sunmoon.rem 1 Jan 2011 >> $OUT 2>&1
|
||||
|
||||
@@ -507,8 +498,8 @@ $REMIND --version >> $OUT 2>&1
|
||||
# Test queueing. Because eventstart depends on the actual system
|
||||
# date, we use the --test flag to fake the date and time.
|
||||
# We can't use $REMIND here because it includes the -q flag.
|
||||
echo JSONQUEUE | ../src/remind --flush --test -z0 ../tests/queue1.rem >> $OUT 2>&1
|
||||
echo QUEUE | ../src/remind --flush --test -zj ../tests/queue1.rem >> $OUT 2>&1
|
||||
echo JSONQUEUE | "$REMIND_CMD" --flush --test -z0 ../tests/queue1.rem >> $OUT 2>&1
|
||||
echo QUEUE | "$REMIND_CMD" --flush --test -zj ../tests/queue1.rem >> $OUT 2>&1
|
||||
|
||||
# Test for leap year bug that was fixed
|
||||
$REMIND -dte - 28 Feb 2024 <<'EOF' >> $OUT 2>&1
|
||||
@@ -690,9 +681,18 @@ If hunspell is installed, its output (if any) follows...
|
||||
EOF
|
||||
|
||||
HUNSPELL="hunspell -d en_US -l -p manpage-personal-dict"
|
||||
|
||||
GOT_HUNSPELL=0
|
||||
$HUNSPELL /dev/null < /dev/null > /dev/null 2>&1
|
||||
if test $? = 0; then
|
||||
|
||||
# Hunspell runs. Do we have the en_US dictionary?
|
||||
if test $? = 0 ; then
|
||||
X=`(echo color; echo colour; echo returm) | hunspell -d en_US -l 2>/dev/null`
|
||||
X=`echo $X | sed -e 's/\n/ /g'`
|
||||
if test "$X" = "colour returm" ; then
|
||||
GOT_HUNSPELL=1
|
||||
fi
|
||||
fi
|
||||
if test "$GOT_HUNSPELL" = "1"; then
|
||||
echo "Spell-checking man pages, WHATSNEW and README.md"
|
||||
cat ../man/*.1 $PERLMANS | $HUNSPELL -n >> $OUT 2>&1
|
||||
cat ../docs/WHATSNEW | $HUNSPELL >> $OUT 2>&1
|
||||
@@ -950,7 +950,42 @@ REM 2025 Oct [1] MSG Expr but not nonconst [today()]
|
||||
REM 2025-10-01 MSG No expr seen [1+2]
|
||||
EOF
|
||||
|
||||
# Purge mode
|
||||
# Early exit from calendar processing
|
||||
$REMIND -p - 2026-01-01 <<'EOF' >> $OUT 2>&1
|
||||
REM 1 Jan 1994 MSG 1/0 = [1/0]
|
||||
EOF
|
||||
|
||||
# No early exit from calendar processing
|
||||
$REMIND -p - 2026-01-01 <<'EOF' >> $OUT 2>&1
|
||||
SET $ParseUntriggered 1
|
||||
REM 1 Jan 1994 MSG 1/0 = [1/0]
|
||||
EOF
|
||||
|
||||
# Calendars with hyperlinks
|
||||
$REMIND -w,0,0 -@2 -c - 1 Jan 2020 <<'EOF' >> $OUT 2>&1
|
||||
SET $TerminalHyperlinks 1
|
||||
REM 15 INFO "Url: https://dianne.skoll.ca" MSG Hello, linky!
|
||||
REM 16 INFO "Url: https://dianne.skoll.ca" MSF Hello, linky!
|
||||
REM 17 INFO "Url: https://dianne.skoll.ca" CAL Hello, linky!
|
||||
REM 18 INFO "Url: https://dianne.skoll.ca" SPECIAL COLOR 255 0 0 Hello, linky!
|
||||
EOF
|
||||
|
||||
# Turn off spacing between reminders, and test the 'z' -c flag.
|
||||
$REMIND -w,0,0,0 -@2 -cz - 1 Jan 2020 <<'EOF' >> $OUT 2>&1
|
||||
REM 15 INFO "Url: https://dianne.skoll.ca" MSG Hello, linky 1!
|
||||
REM 15 INFO "Url: https://dianne.skoll.ca" MSF Hello, linky 2!
|
||||
REM 15 INFO "Url: https://dianne.skoll.ca" CAL Hello, linky 3!
|
||||
REM 15 INFO "Url: https://dianne.skoll.ca" SPECIAL COLOR 255 0 0 Hello, linky 4!
|
||||
EOF
|
||||
|
||||
# Turn on spacing between reminders..
|
||||
$REMIND -w,0,0,1 -@2 -c - 1 Jan 2020 <<'EOF' >> $OUT 2>&1
|
||||
SET $TerminalHyperlinks 1
|
||||
REM 15 INFO "Url: https://dianne.skoll.ca" MSG Hello, linky 1!
|
||||
REM 15 INFO "Url: https://dianne.skoll.ca" MSF Hello, linky 2!
|
||||
REM 15 INFO "Url: https://dianne.skoll.ca" CAL Hello, linky 3!
|
||||
REM 15 INFO "Url: https://dianne.skoll.ca" SPECIAL COLOR 255 0 0 Hello, linky 4!
|
||||
EOF
|
||||
|
||||
cmp -s $OUT $CMP
|
||||
if [ "$?" = "0" ]; then
|
||||
|
||||
381
tests/test.cmp
381
tests/test.cmp
@@ -1046,7 +1046,7 @@ set a057 value("a05"+"6")
|
||||
"a05" + "6" => "a056"
|
||||
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
set a058 version()
|
||||
version() => "06.01.07"
|
||||
version() => "06.02.02"
|
||||
set a059 wkday(today())
|
||||
today() => 1991-02-16
|
||||
wkday(1991-02-16) => "Saturday"
|
||||
@@ -2609,7 +2609,7 @@ a056 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
a007 "1991-02-16"
|
||||
a057 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
a008 "11:44"
|
||||
a058 "06.01.07"
|
||||
a058 "06.02.02"
|
||||
a059 "Saturday"
|
||||
a010 12
|
||||
a060 6
|
||||
@@ -5040,8 +5040,9 @@ set a 7 * "Cabbage! "
|
||||
|
||||
# Should result in errors
|
||||
set pqxya 1+2)
|
||||
1 + 2 => 3
|
||||
../tests/test.rem(1014): Expecting end-of-line
|
||||
1+2)
|
||||
^-- here
|
||||
../tests/test.rem(1014): Expecting operator or end-of-expression
|
||||
|
||||
# Should result in an error
|
||||
REM Tue OMIT 2024-01-01 MSG Wookie
|
||||
@@ -5562,8 +5563,8 @@ REM SATISFY ""
|
||||
REM SATISFY [version() > "01.00.00"]
|
||||
../tests/test.rem(1074): SATISFY: expression has no reference to trigdate() or $T...
|
||||
../tests/test.rem(1074): Trig = Saturday, 16 February, 1991
|
||||
version() => "06.01.07"
|
||||
"06.01.07" > "01.00.00" => 1
|
||||
version() => "06.02.02"
|
||||
"06.02.02" > "01.00.00" => 1
|
||||
../tests/test.rem(1074): Trig(satisfied) = Saturday, 16 February, 1991
|
||||
REM SATISFY [max(x, max(x, 1, 2, 3), 4, 5, 6) * 5]
|
||||
../tests/test.rem(1075): SATISFY: expression has no reference to trigdate() or $T...
|
||||
@@ -16426,9 +16427,14 @@ eval("1/0") => 1 / 0 => Division by zero
|
||||
../tests/test.rem(1590): `/': Division by zero
|
||||
Division by zero
|
||||
set a eval("1 / / 2")
|
||||
eval("1 / / 2") => ../tests/test.rem(1591): Illegal character `/'
|
||||
eval("1 / / 2") => ../tests/test.rem(1591): Expecting constant, variable, function call or (expression)
|
||||
1 / / 2
|
||||
^-- here
|
||||
Expecting constant, variable, function call or (expression)
|
||||
set a eval("1 / # 2")
|
||||
eval("1 / # 2") => ../tests/test.rem(1592): Illegal character `#'
|
||||
1 / # 2
|
||||
^-- here
|
||||
Illegal character
|
||||
set a catch(eval("1 +"), 33)
|
||||
eval("1 +") => Unexpected end of line
|
||||
@@ -16438,7 +16444,10 @@ eval("1/0") => 1 / 0 => Division by zero
|
||||
Division by zero
|
||||
catch(*Division by zero*, 34) => 34
|
||||
set a catch(eval("1 / / 2"), 35)
|
||||
eval("1 / / 2") => Illegal character
|
||||
eval("1 / / 2") => Expecting constant, variable, function call or (expression)
|
||||
catch(*Expecting constant, variable, function call or (expression)*, 35) => 35
|
||||
set a catch(eval("1 / # 2"), 35)
|
||||
eval("1 / # 2") => Illegal character
|
||||
catch(*Illegal character*, 35) => 35
|
||||
|
||||
# Ensure RUN is disabled in eval
|
||||
@@ -16446,7 +16455,7 @@ set a shell("echo foo")
|
||||
shell("echo foo") => "foo"
|
||||
set a eval("shell(\"echo foo\")")
|
||||
eval("shell(\"echo foo\")") => shell("echo foo") => RUN disabled
|
||||
../tests/test.rem(1598): shell(): RUN disabled
|
||||
../tests/test.rem(1600): shell(): RUN disabled
|
||||
RUN disabled
|
||||
set a shell("echo foo")
|
||||
shell("echo foo") => "foo"
|
||||
@@ -16459,8 +16468,8 @@ Leaving UserFN i() => "foo"
|
||||
set a eval("i()")
|
||||
eval("i()") => Entering UserFN i()
|
||||
shell("echo foo") => RUN disabled
|
||||
../tests/test.rem(1603): shell(): RUN disabled
|
||||
../tests/test.rem(1601): [#0] In function `i'
|
||||
../tests/test.rem(1605): shell(): RUN disabled
|
||||
../tests/test.rem(1603): [#0] In function `i'
|
||||
Leaving UserFN i() => RUN disabled
|
||||
RUN disabled
|
||||
set a i()
|
||||
@@ -16473,19 +16482,19 @@ set b eval(a)
|
||||
a => "eval(\"1\")+ shell(\"ls\")"
|
||||
eval("eval(\"1\")+ shell(\"ls\")") => eval("1") => 1
|
||||
shell("ls") => RUN disabled
|
||||
../tests/test.rem(1607): shell(): RUN disabled
|
||||
../tests/test.rem(1609): shell(): RUN disabled
|
||||
RUN disabled
|
||||
|
||||
# "value" should use lazy evaluation
|
||||
set a value(4:33)
|
||||
value(04:33) => Type mismatch
|
||||
../tests/test.rem(1610): Type mismatch
|
||||
../tests/test.rem(1612): Type mismatch
|
||||
set a value('2020-01-01', 42)
|
||||
value(2020-01-01, ?) => Type mismatch
|
||||
../tests/test.rem(1611): Type mismatch
|
||||
../tests/test.rem(1613): Type mismatch
|
||||
set a value("nosuchvar")
|
||||
value("nosuchvar") => Undefined variable
|
||||
../tests/test.rem(1612): Undefined variable
|
||||
../tests/test.rem(1614): Undefined variable
|
||||
set a value("nosuchvar", 42)
|
||||
value("nosuchvar", 42) => 42
|
||||
set a value("a", 42)
|
||||
@@ -16495,11 +16504,11 @@ value("a") => 42
|
||||
DEBUG -x
|
||||
|
||||
DEBUG -e
|
||||
../tests/test.rem(1622): eval(): Too many recursive function calls
|
||||
../tests/test.rem(1624): eval(): Too many recursive function calls
|
||||
Base: 1991-02-09
|
||||
Base: 1991-02-09
|
||||
../tests/test.rem(1630): Expired
|
||||
../tests/test.rem(1631): Expired
|
||||
../tests/test.rem(1632): Expired
|
||||
../tests/test.rem(1633): Expired
|
||||
trigvalid = 1; trigdate = 1991-01-14
|
||||
trigvalid = 0; trigdate = 0
|
||||
daysinmon(2, 2000) => 29
|
||||
@@ -16511,36 +16520,36 @@ daysinmon("Feb", 2001) => 28
|
||||
daysinmon("March", 2000) => 31
|
||||
daysinmon("March", 2001) => 31
|
||||
daysinmon("Cabbage", 2001) => Invalid month name
|
||||
../tests/test.rem(1658): daysinmon(): Invalid month name
|
||||
../tests/test.rem(1660): daysinmon(): Invalid month name
|
||||
daysinmon(2000-02-14) => 29
|
||||
daysinmon(2001-02-14) => 28
|
||||
daysinmon(2000-04-14) => 30
|
||||
daysinmon(2001-04-14) => 30
|
||||
date(2020, "April", 15) => 2020-04-15
|
||||
date(2020, "Carrot", 12) => Invalid month name
|
||||
../tests/test.rem(1666): date(): Invalid month name
|
||||
../tests/test.rem(1668): date(): Invalid month name
|
||||
datetime(2020, "April", 13, 04:44) => 2020-04-13@04:44
|
||||
datetime(2020, "April", 13, 4, 44) => 2020-04-13@04:44
|
||||
datetime(2020, "Lettuce", 13, 04:44) => Invalid month name
|
||||
../tests/test.rem(1669): datetime(): Invalid month name
|
||||
../tests/test.rem(1671): datetime(): Invalid month name
|
||||
datetime(2020, "Lettuce", 13, 4, 44) => Invalid month name
|
||||
../tests/test.rem(1670): datetime(): Invalid month name
|
||||
../tests/test.rem(1672): datetime(): Invalid month name
|
||||
wkdaynum("Tue") => 2
|
||||
wkdaynum("Wednesday") => 3
|
||||
wkdaynum("telephone") => Invalid weekday name
|
||||
../tests/test.rem(1674): wkdaynum(): Invalid weekday name
|
||||
../tests/test.rem(1685): Cannot modify system variable: `$NumTrig'
|
||||
../tests/test.rem(1686): POP-VARS without matching PUSH-VARS
|
||||
../tests/test.rem(1676): wkdaynum(): Invalid weekday name
|
||||
../tests/test.rem(1687): Cannot modify system variable: `$NumTrig'
|
||||
../tests/test.rem(1688): POP-VARS without matching PUSH-VARS
|
||||
|
||||
FUNSET a
|
||||
FSET b(x, y) x*y
|
||||
FSET c() 33
|
||||
|
||||
set a a(2)
|
||||
../tests/test.rem(1695): Undefined function: `a'
|
||||
../tests/test.rem(1697): Undefined function: `a'
|
||||
set a b(2)
|
||||
b(?) => Not enough arguments
|
||||
../tests/test.rem(1696): b(): Not enough arguments
|
||||
../tests/test.rem(1698): b(): Not enough arguments
|
||||
set a b(2, 3)
|
||||
Entering UserFN b(2, 3)
|
||||
x => 2
|
||||
@@ -16562,7 +16571,7 @@ Entering UserFN a(2)
|
||||
Leaving UserFN a(2) => 42
|
||||
set a b(2)
|
||||
b(?) => Not enough arguments
|
||||
../tests/test.rem(1707): b(): Not enough arguments
|
||||
../tests/test.rem(1709): b(): Not enough arguments
|
||||
set a b(2, 3)
|
||||
Entering UserFN b(2, 3)
|
||||
x => 2
|
||||
@@ -16577,10 +16586,10 @@ Leaving UserFN c() => 66
|
||||
POP-FUNCS
|
||||
|
||||
set a a(2)
|
||||
../tests/test.rem(1713): Undefined function: `a'
|
||||
../tests/test.rem(1715): Undefined function: `a'
|
||||
set a b(2)
|
||||
b(?) => Not enough arguments
|
||||
../tests/test.rem(1714): b(): Not enough arguments
|
||||
../tests/test.rem(1716): b(): Not enough arguments
|
||||
set a b(2, 3)
|
||||
Entering UserFN b(2, 3)
|
||||
x => 2
|
||||
@@ -16595,7 +16604,7 @@ DEBUG -xe
|
||||
Overridden: subst_colon subst_bang subst_question subst_at subst_hash
|
||||
bad => "ÿ"
|
||||
mbstrlen("ÿ") => Invalid multibyte sequence
|
||||
../tests/test.rem(1734): mbstrlen(): Invalid multibyte sequence
|
||||
../tests/test.rem(1736): mbstrlen(): Invalid multibyte sequence
|
||||
bad => "ÿ"
|
||||
strlen("ÿ") => 1
|
||||
faces => "🙂🙂🙂🙂🙂xyzçççéfoo"
|
||||
@@ -16609,7 +16618,7 @@ index("🙂🙂🙂🙂🙂xyzçççéfoo", "ç") => 24
|
||||
bad => "ÿ"
|
||||
bad => "ÿ"
|
||||
mbindex("ÿ", "ÿ") => Invalid multibyte sequence
|
||||
../tests/test.rem(1742): mbindex(): Invalid multibyte sequence
|
||||
../tests/test.rem(1744): mbindex(): Invalid multibyte sequence
|
||||
faces => "🙂🙂🙂🙂🙂xyzçççéfoo"
|
||||
mbindex("🙂🙂🙂🙂🙂xyzçççéfoo", "ç", 11) => 11
|
||||
faces => "🙂🙂🙂🙂🙂xyzçççéfoo"
|
||||
@@ -16628,10 +16637,10 @@ faces => "🙂🙂🙂🙂🙂xyzçççéfoo"
|
||||
mbsubstr("🙂🙂🙂🙂🙂xyzçççéfoo", 2, 9) => "🙂🙂🙂🙂xyzç"
|
||||
bad => "ÿ"
|
||||
mbsubstr("ÿ", 1) => Invalid multibyte sequence
|
||||
../tests/test.rem(1754): mbsubstr(): Invalid multibyte sequence
|
||||
../tests/test.rem(1756): mbsubstr(): Invalid multibyte sequence
|
||||
bad => "ÿ"
|
||||
mbsubstr("ÿ", 1, 20) => Invalid multibyte sequence
|
||||
../tests/test.rem(1755): mbsubstr(): Invalid multibyte sequence
|
||||
../tests/test.rem(1757): mbsubstr(): Invalid multibyte sequence
|
||||
faces => "🙂🙂🙂🙂🙂xyzçççéfoo"
|
||||
substr("🙂🙂🙂🙂🙂xyzçççéfoo", 2) => "Ÿ™‚🙂🙂🙂🙂xyzçççéfoo"
|
||||
faces => "🙂🙂🙂🙂🙂xyzçççéfoo"
|
||||
@@ -16641,13 +16650,119 @@ codepoint("🙂🙂🙂🙂🙂xyzçççéfoo") => 128578
|
||||
mbchar(128578, 162, 122) => "🙂¢z"
|
||||
bad => "ÿ"
|
||||
codepoint("ÿ") => Invalid multibyte sequence
|
||||
../tests/test.rem(1762): codepoint(): Invalid multibyte sequence
|
||||
../tests/test.rem(1764): codepoint(): Invalid multibyte sequence
|
||||
codepoint("") => 0
|
||||
mbchar(0) => ""
|
||||
mbchar(0, 120) => Number too low
|
||||
../tests/test.rem(1765): mbchar(): Number too low
|
||||
../tests/test.rem(1767): mbchar(): Number too low
|
||||
mbchar(120, 0) => Number too low
|
||||
../tests/test.rem(1766): mbchar(): Number too low
|
||||
../tests/test.rem(1768): mbchar(): Number too low
|
||||
hebdate(1, "Tishrey") => 1991-09-09
|
||||
hebdate(1, "Tishri") => 1991-09-09
|
||||
hebdate(1, "Tishrei") => 1991-09-09
|
||||
hebdate(1, "תשרי") => 1991-09-09
|
||||
hebdate(1, "Cheshvan") => 1991-10-09
|
||||
hebdate(1, "Kheshvan") => 1991-10-09
|
||||
hebdate(1, "Heshvan") => 1991-10-09
|
||||
hebdate(1, "חשוון") => 1991-10-09
|
||||
hebdate(1, "Kislev") => 1991-11-08
|
||||
hebdate(1, "כסלו") => 1991-11-08
|
||||
hebdate(1, "Tevet") => 1991-12-08
|
||||
hebdate(1, "טבת") => 1991-12-08
|
||||
hebdate(1, "Shvat") => 1992-01-06
|
||||
hebdate(1, "Shevat") => 1992-01-06
|
||||
hebdate(1, "שבט") => 1992-01-06
|
||||
hebdate(1, "Adar A") => 1992-02-05
|
||||
hebdate(1, "Adar 1") => 1992-02-05
|
||||
hebdate(1, "Adar I") => 1992-02-05
|
||||
hebdate(1, "×<>דר ×<>'") => 1992-02-05
|
||||
hebdate(1, "×<>דר ×<>") => 1992-02-05
|
||||
hebdate(1, "×<>דר 1") => 1992-02-05
|
||||
hebdate(1, "×<>דר I") => 1992-02-05
|
||||
hebdate(1, "Adar B") => 1992-03-06
|
||||
hebdate(1, "Adar 2") => 1992-03-06
|
||||
hebdate(1, "Adar II") => 1992-03-06
|
||||
hebdate(1, "×<>דר ב'") => 1992-03-06
|
||||
hebdate(1, "×<>דר ב") => 1992-03-06
|
||||
hebdate(1, "×<>דר 2") => 1992-03-06
|
||||
hebdate(1, "×<>דר II") => 1992-03-06
|
||||
hebdate(1, "Nisan") => 1991-03-16
|
||||
hebdate(1, "× ×™×¡×Ÿ") => 1991-03-16
|
||||
hebdate(1, "Iyar") => 1991-04-15
|
||||
hebdate(1, "Iyyar") => 1991-04-15
|
||||
hebdate(1, "×<>ייר") => 1991-04-15
|
||||
hebdate(1, "Sivan") => 1991-05-14
|
||||
hebdate(1, "סיון") => 1991-05-14
|
||||
hebdate(1, "Tamuz") => 1991-06-13
|
||||
hebdate(1, "Tammuz") => 1991-06-13
|
||||
hebdate(1, "תמוז") => 1991-06-13
|
||||
hebdate(1, "Av") => 1991-07-12
|
||||
hebdate(1, "×<>ב") => 1991-07-12
|
||||
hebdate(1, "Elul") => 1991-08-11
|
||||
hebdate(1, "×<>לול") => 1991-08-11
|
||||
hebdate(1, "Adar") => 1992-03-06
|
||||
hebdate(1, "×<>דר") => 1992-03-06
|
||||
hebmon(1991-09-09) => "Tishrey"
|
||||
ivritmon(1991-09-09) => "תשרי"
|
||||
hebmon(1991-10-09) => "Heshvan"
|
||||
ivritmon(1991-10-09) => "חשוון"
|
||||
hebmon(1991-11-08) => "Kislev"
|
||||
ivritmon(1991-11-08) => "כסלו"
|
||||
hebmon(1991-12-08) => "Tevet"
|
||||
ivritmon(1991-12-08) => "טבת"
|
||||
hebmon(1992-01-06) => "Shvat"
|
||||
ivritmon(1992-01-06) => "שבט"
|
||||
hebmon(1992-02-05) => "Adar A"
|
||||
ivritmon(1992-02-05) => "×<>דר ×<>'"
|
||||
hebmon(1992-03-06) => "Adar B"
|
||||
ivritmon(1992-03-06) => "×<>דר ב'"
|
||||
hebmon(1991-03-16) => "Nisan"
|
||||
ivritmon(1991-03-16) => "× ×™×¡×Ÿ"
|
||||
hebmon(1991-04-15) => "Iyar"
|
||||
ivritmon(1991-04-15) => "×<>ייר"
|
||||
hebmon(1991-05-14) => "Sivan"
|
||||
ivritmon(1991-05-14) => "סיון"
|
||||
hebmon(1991-06-13) => "Tamuz"
|
||||
ivritmon(1991-06-13) => "תמוז"
|
||||
hebmon(1991-07-12) => "Av"
|
||||
ivritmon(1991-07-12) => "×<>ב"
|
||||
hebmon(1991-08-11) => "Elul"
|
||||
ivritmon(1991-08-11) => "×<>לול"
|
||||
mbpad("foo", "bar", 3) => "foo"
|
||||
mbpad("foo", "bar", 3, 1) => "foo"
|
||||
mbpad("foo", "bar", 8) => "barbafoo"
|
||||
mbpad("foo", "bar", 8, 1) => "foobarba"
|
||||
mbpad("foo", "🙂💩", 3) => "foo"
|
||||
mbpad("foo", "🙂💩", 3, 1) => "foo"
|
||||
mbpad("foo", "🙂💩", 8) => "🙂💩🙂💩🙂foo"
|
||||
mbpad("foo", "🙂💩", 8, 1) => "foo🙂💩🙂💩🙂"
|
||||
char(255) => "ÿ"
|
||||
bad => "ÿ"
|
||||
mbpad("foo", "ÿ", 3) => "foo"
|
||||
bad => "ÿ"
|
||||
mbpad("foo", "ÿ", 3, 1) => "foo"
|
||||
bad => "ÿ"
|
||||
mbpad("foo", "ÿ", 8) => Invalid multibyte sequence
|
||||
../tests/test.rem(1886): mbpad(): Invalid multibyte sequence
|
||||
bad => "ÿ"
|
||||
mbpad("foo", "ÿ", 8, 1) => Invalid multibyte sequence
|
||||
../tests/test.rem(1887): mbpad(): Invalid multibyte sequence
|
||||
bad => "ÿ"
|
||||
mbpad("ÿ", "bar", 0) => Invalid multibyte sequence
|
||||
../tests/test.rem(1888): mbpad(): Invalid multibyte sequence
|
||||
bad => "ÿ"
|
||||
mbpad("ÿ", "bar", 0, 1) => Invalid multibyte sequence
|
||||
../tests/test.rem(1889): mbpad(): Invalid multibyte sequence
|
||||
bad => "ÿ"
|
||||
mbpad("ÿ", "bar", 8) => Invalid multibyte sequence
|
||||
../tests/test.rem(1890): mbpad(): Invalid multibyte sequence
|
||||
bad => "ÿ"
|
||||
mbpad("ÿ", "bar", 8, 1) => Invalid multibyte sequence
|
||||
../tests/test.rem(1891): mbpad(): Invalid multibyte sequence
|
||||
]8;;https://dianne.skoll.ca\Hello, linky!
|
||||
]8;;\]8;;https://dianne.skoll.ca\Hello, linky!
|
||||
]8;;\]8;;https://dianne.skoll.ca\Hello, linky!
|
||||
]8;;\DynBuf Mallocs: 1120 mallocs; 31872640 bytes
|
||||
Variable hash table statistics:
|
||||
Entries: 100146; Buckets: 87719; Non-empty Buckets: 66303
|
||||
Maxlen: 5; Minlen: 0; Avglen: 1.142; Stddev: 0.878; Avg nonempty len: 1.510
|
||||
@@ -16669,7 +16784,7 @@ Expression nodes high-water: 302076
|
||||
Expression nodes leaked: 0
|
||||
Parse level high-water: 34
|
||||
Max expr node evaluations per line: 2001
|
||||
Total expression node evaluations: 106467
|
||||
Total expression node evaluations: 106733
|
||||
|
||||
Test 2
|
||||
|
||||
@@ -20648,7 +20763,7 @@ No reminders.
|
||||
<< /PageSize [612 792] >> setpagedevice
|
||||
% This file was produced by Remind and Rem2PS, written by
|
||||
% Dianne Skoll.
|
||||
% Remind and Rem2PS are Copyright (C) 1992-2025 Dianne Skoll.
|
||||
% Remind and Rem2PS are Copyright (C) 1992-2026 Dianne Skoll.
|
||||
/ISOLatin1Encoding where { pop save true }{ false } ifelse
|
||||
/ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus
|
||||
StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute
|
||||
@@ -21752,7 +21867,7 @@ showpage
|
||||
<< /PageSize [612 792] >> setpagedevice
|
||||
% This file was produced by Remind and Rem2PS, written by
|
||||
% Dianne Skoll.
|
||||
% Remind and Rem2PS are Copyright (C) 1992-2025 Dianne Skoll.
|
||||
% Remind and Rem2PS are Copyright (C) 1992-2026 Dianne Skoll.
|
||||
/ISOLatin1Encoding where { pop save true }{ false } ifelse
|
||||
/ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus
|
||||
StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute
|
||||
@@ -23707,7 +23822,7 @@ SECURITY: Won't read world-writable file or directory!
|
||||
Error reading include_dir/ww: Can't open file
|
||||
SECURITY: Won't read world-writable file or directory!
|
||||
Error reading include_dir/ww: No files matching *.rem
|
||||
06.01.07
|
||||
06.02.02
|
||||
Enabling test mode: This is meant for the acceptance test.
|
||||
Do not use --test in production.
|
||||
In test mode, the system time is fixed at 2025-01-06@19:00
|
||||
@@ -23905,7 +24020,9 @@ Parsed expression: 1||1
|
||||
Parsed expression: 2
|
||||
=> 2
|
||||
Unparsed: , 3
|
||||
../tests/expr.rem(15): Expecting end-of-line
|
||||
2, 3
|
||||
^-- here
|
||||
../tests/expr.rem(15): Expecting operator or end-of-expression
|
||||
Parsed expression: iif(0, "foo", 0, "bar", 1, "blech", 0, "quux", 1, "borhy", "wacka")
|
||||
=> (Iif 0 "foo" 0 "bar" 1 "blech" 0 "quux" 1 "borhy" "wacka")
|
||||
iif(0, ?, 0, ?, 1, "blech", ?, ?, ?, ?, ?) => "blech"
|
||||
@@ -23923,7 +24040,7 @@ max(6, 9, 50) => 50
|
||||
Parsed expression: max(1,
|
||||
=> Error: Illegal character
|
||||
Unparsed: ,1)
|
||||
,1)
|
||||
max(1,,1)
|
||||
^-- here
|
||||
Parsed expression: 5%0
|
||||
=> (% 5 0)
|
||||
@@ -24263,6 +24380,7 @@ Parsed expression: isany("foo", 1 + 1, 2:00 + 1, '2021-01-01' + 1, '2021-01-01@1
|
||||
"f" + "oo" => "foo"
|
||||
isany("foo", 2, 02:01, 2021-01-02, 2021-01-01@14:01, "foo", ?) => 1
|
||||
No reminders.
|
||||
DynBuf Mallocs: 21 mallocs; 6400 bytes
|
||||
Variable hash table statistics:
|
||||
Entries: 1; Buckets: 7; Non-empty Buckets: 1
|
||||
Maxlen: 1; Minlen: 0; Avglen: 0.143; Stddev: 0.350; Avg nonempty len: 1.000
|
||||
@@ -24284,7 +24402,7 @@ Expression nodes high-water: 499
|
||||
Expression nodes leaked: 0
|
||||
Parse level high-water: 2001
|
||||
Max expr node evaluations per line: 499
|
||||
Total expression node evaluations: 632
|
||||
Total expression node evaluations: 631
|
||||
-stdin-(14): Unmatched PUSH-OMIT-CONTEXT at -stdin-(7)
|
||||
-stdin-(14): Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT
|
||||
No reminders.
|
||||
@@ -24477,6 +24595,7 @@ cal
|
||||
clear
|
||||
clear-omit-context
|
||||
complete-through
|
||||
completed-through
|
||||
debug
|
||||
do
|
||||
dump
|
||||
@@ -24645,12 +24764,14 @@ isconst
|
||||
isdst
|
||||
isleap
|
||||
isomitted
|
||||
ivritmon
|
||||
language
|
||||
localtoutc
|
||||
lower
|
||||
max
|
||||
mbchar
|
||||
mbindex
|
||||
mbpad
|
||||
mbstrlen
|
||||
mbsubstr
|
||||
min
|
||||
@@ -24832,6 +24953,7 @@ $T
|
||||
$Tb
|
||||
$Td
|
||||
$TerminalBackground
|
||||
$TerminalHyperlinks
|
||||
$Thursday
|
||||
$TimeSep
|
||||
$TimetIs64bit
|
||||
@@ -24858,6 +24980,7 @@ $WarningLevel
|
||||
$Was
|
||||
$Wednesday
|
||||
No reminders.
|
||||
DynBuf Mallocs: 180071 mallocs; 42974784 bytes
|
||||
Variable hash table statistics:
|
||||
Entries: 1; Buckets: 7; Non-empty Buckets: 1
|
||||
Maxlen: 1; Minlen: 0; Avglen: 0.143; Stddev: 0.350; Avg nonempty len: 1.000
|
||||
@@ -25060,9 +25183,10 @@ TRANSLATE "MAX-OVERDUE specified twice" ""
|
||||
TRANSLATE "MAX-OVERDUE specified without TODO" ""
|
||||
TRANSLATE "TZ specified twice" ""
|
||||
TRANSLATE "TZ specified for non-timed reminder" ""
|
||||
TRANSLATE "C library does not support multibyte characters" ""
|
||||
TRANSLATE "Invalid multibyte sequence" ""
|
||||
TRANSLATE "Maximum expression complexity exceeded" ""
|
||||
TRANSLATE "Expecting operator or end-of-expression" ""
|
||||
TRANSLATE "Expecting constant, variable, function call or (expression)" ""
|
||||
|
||||
# Other Messages
|
||||
TRANSLATE "%s function `%s' defined at %s(%s) does not use its argument" ""
|
||||
@@ -39546,7 +39670,6 @@ trigger(2060-08-01@23:55, 1) => "1 August 2060 AT 19:55"
|
||||
utctolocal(2050-01-01@01:00) => 2049-12-31@20:00
|
||||
localtoutc(2050-12-31@23:44) => 2051-01-01@04:44
|
||||
localtoutc(2050-03-13@00:00) => 2050-03-13@05:00
|
||||
localtoutc(2050-03-13@02:00) => 2050-03-13@07:00
|
||||
localtoutc(2050-11-06@00:00) => 2050-11-06@04:00
|
||||
localtoutc(2050-11-06@02:00) => 2050-11-06@07:00
|
||||
utctolocal(2051-01-01@04:44) => 2050-12-31@23:44
|
||||
@@ -39658,6 +39781,14 @@ Fifth today
|
||||
Sixth on 2025-08-06
|
||||
Eighth on 2025-08-20
|
||||
Ninth today
|
||||
First on 2025-08-01
|
||||
Second on 2022-08-01
|
||||
Third on 2023-08-01
|
||||
Fourth on 2025-08-20
|
||||
Fifth today
|
||||
Sixth on 2025-08-06
|
||||
Eighth on 2025-08-20
|
||||
Ninth today
|
||||
Yup today
|
||||
Yup2 yesterday
|
||||
Yup3 on 2025-08-11
|
||||
@@ -39673,6 +39804,13 @@ Testing TODOS in calendar mode
|
||||
2025/08/01 * * * * First
|
||||
2025/08/01 * * * * Second
|
||||
2025/08/01 * * * * Third
|
||||
2025/08/01 * * * * First
|
||||
2025/08/01 * * * * Second
|
||||
2025/08/01 * * * * Third
|
||||
2025/08/06 * * * * Sixth
|
||||
2025/08/06 * * * * Seventh
|
||||
2025/08/06 * * * * Eighth
|
||||
2025/08/06 * * * * Ninth
|
||||
2025/08/06 * * * * Sixth
|
||||
2025/08/06 * * * * Seventh
|
||||
2025/08/06 * * * * Eighth
|
||||
@@ -39684,10 +39822,18 @@ Testing TODOS in calendar mode
|
||||
2025/08/13 * * * * Fifth
|
||||
2025/08/13 * * * * Eighth
|
||||
2025/08/13 * * * * Ninth
|
||||
2025/08/13 * * * * Fifth
|
||||
2025/08/13 * * * * Eighth
|
||||
2025/08/13 * * * * Ninth
|
||||
2025/08/13 * * * * Yup
|
||||
2025/08/20 * * * * Fourth
|
||||
2025/08/20 * * * * Eighth
|
||||
2025/08/20 * * * * Ninth
|
||||
2025/08/20 * * * * Fourth
|
||||
2025/08/20 * * * * Eighth
|
||||
2025/08/20 * * * * Ninth
|
||||
2025/08/27 * * * * Eighth
|
||||
2025/08/27 * * * * Ninth
|
||||
2025/08/27 * * * * Eighth
|
||||
2025/08/27 * * * * Ninth
|
||||
|
||||
@@ -39695,6 +39841,10 @@ Testing TODOS in calendar mode with completed todos hidden
|
||||
2025/08/01 * * * * First
|
||||
2025/08/01 * * * * Second
|
||||
2025/08/01 * * * * Third
|
||||
2025/08/01 * * * * First
|
||||
2025/08/01 * * * * Second
|
||||
2025/08/01 * * * * Third
|
||||
2025/08/06 * * * * Sixth
|
||||
2025/08/06 * * * * Sixth
|
||||
2025/08/09 * * * * Nope
|
||||
2025/08/10 * * * * Yup4
|
||||
@@ -39702,10 +39852,17 @@ Testing TODOS in calendar mode with completed todos hidden
|
||||
2025/08/12 * * * * Yup2
|
||||
2025/08/13 * * * * Fifth
|
||||
2025/08/13 * * * * Ninth
|
||||
2025/08/13 * * * * Fifth
|
||||
2025/08/13 * * * * Ninth
|
||||
2025/08/13 * * * * Yup
|
||||
2025/08/20 * * * * Fourth
|
||||
2025/08/20 * * * * Eighth
|
||||
2025/08/20 * * * * Ninth
|
||||
2025/08/20 * * * * Fourth
|
||||
2025/08/20 * * * * Eighth
|
||||
2025/08/20 * * * * Ninth
|
||||
2025/08/27 * * * * Eighth
|
||||
2025/08/27 * * * * Ninth
|
||||
2025/08/27 * * * * Eighth
|
||||
2025/08/27 * * * * Ninth
|
||||
Testing TODOS and JSON mode
|
||||
@@ -39718,10 +39875,18 @@ Testing TODOS and JSON mode
|
||||
{"date":"2025-08-06","filename":"../tests/todos.rem","lineno":9,"d":6,"m":8,"y":2025,"is_todo":1,"delta":7,"trigbase":"2025-08-6 ","priority":5000,"body":"Sixth on 2025-08-06"},
|
||||
{"date":"2025-08-20","filename":"../tests/todos.rem","lineno":11,"wd":["Wednesday"],"is_todo":1,"complete_through":"2025-08-13","delta":7,"priority":5000,"body":"Eighth on 2025-08-20"},
|
||||
{"date":"2025-08-13","filename":"../tests/todos.rem","lineno":12,"wd":["Wednesday"],"is_todo":1,"complete_through":"2025-08-12","delta":7,"priority":5000,"body":"Ninth today"},
|
||||
{"date":"2025-08-13","filename":"../tests/todos.rem","lineno":15,"d":13,"m":8,"y":2025,"is_todo":1,"trigbase":"2025-08-13","max_overdue":3,"priority":5000,"body":"Yup today"},
|
||||
{"date":"2025-08-12","filename":"../tests/todos.rem","lineno":16,"d":12,"m":8,"y":2025,"is_todo":1,"trigbase":"2025-08-12","max_overdue":3,"priority":5000,"body":"Yup2 yesterday"},
|
||||
{"date":"2025-08-11","filename":"../tests/todos.rem","lineno":17,"d":11,"m":8,"y":2025,"is_todo":1,"trigbase":"2025-08-11","max_overdue":3,"priority":5000,"body":"Yup3 on 2025-08-11"},
|
||||
{"date":"2025-08-10","filename":"../tests/todos.rem","lineno":18,"d":10,"m":8,"y":2025,"is_todo":1,"trigbase":"2025-08-10","max_overdue":3,"priority":5000,"body":"Yup4 on 2025-08-10"}
|
||||
{"date":"2025-08-01","filename":"../tests/todos.rem","lineno":14,"d":1,"m":8,"y":2025,"is_todo":1,"trigbase":"2025-08-1 ","priority":5000,"body":"First on 2025-08-01"},
|
||||
{"date":"2022-08-01","filename":"../tests/todos.rem","lineno":15,"d":1,"m":8,"is_todo":1,"complete_through":"2022-07-31","priority":5000,"body":"Second on 2022-08-01"},
|
||||
{"date":"2023-08-01","filename":"../tests/todos.rem","lineno":16,"d":1,"m":8,"is_todo":1,"complete_through":"2022-08-01","priority":5000,"body":"Third on 2023-08-01"},
|
||||
{"date":"2025-08-20","filename":"../tests/todos.rem","lineno":17,"d":20,"m":8,"y":2025,"is_todo":1,"delta":7,"trigbase":"2025-08-20","priority":5000,"body":"Fourth on 2025-08-20"},
|
||||
{"date":"2025-08-13","filename":"../tests/todos.rem","lineno":18,"d":13,"m":8,"y":2025,"is_todo":1,"delta":7,"trigbase":"2025-08-13","priority":5000,"body":"Fifth today"},
|
||||
{"date":"2025-08-06","filename":"../tests/todos.rem","lineno":19,"d":6,"m":8,"y":2025,"is_todo":1,"delta":7,"trigbase":"2025-08-6 ","priority":5000,"body":"Sixth on 2025-08-06"},
|
||||
{"date":"2025-08-20","filename":"../tests/todos.rem","lineno":21,"wd":["Wednesday"],"is_todo":1,"complete_through":"2025-08-13","delta":7,"priority":5000,"body":"Eighth on 2025-08-20"},
|
||||
{"date":"2025-08-13","filename":"../tests/todos.rem","lineno":22,"wd":["Wednesday"],"is_todo":1,"complete_through":"2025-08-12","delta":7,"priority":5000,"body":"Ninth today"},
|
||||
{"date":"2025-08-13","filename":"../tests/todos.rem","lineno":25,"d":13,"m":8,"y":2025,"is_todo":1,"trigbase":"2025-08-13","max_overdue":3,"priority":5000,"body":"Yup today"},
|
||||
{"date":"2025-08-12","filename":"../tests/todos.rem","lineno":26,"d":12,"m":8,"y":2025,"is_todo":1,"trigbase":"2025-08-12","max_overdue":3,"priority":5000,"body":"Yup2 yesterday"},
|
||||
{"date":"2025-08-11","filename":"../tests/todos.rem","lineno":27,"d":11,"m":8,"y":2025,"is_todo":1,"trigbase":"2025-08-11","max_overdue":3,"priority":5000,"body":"Yup3 on 2025-08-11"},
|
||||
{"date":"2025-08-10","filename":"../tests/todos.rem","lineno":28,"d":10,"m":8,"y":2025,"is_todo":1,"trigbase":"2025-08-10","max_overdue":3,"priority":5000,"body":"Yup4 on 2025-08-10"}
|
||||
]
|
||||
Testing proper redirection of RUN stdout in JSON mode... here's stdout
|
||||
[
|
||||
@@ -39845,6 +40010,7 @@ fib(24) = 46368
|
||||
-stdin-(13): `-': Maximum expression complexity exceeded
|
||||
-stdin-(3): [#0] In function `fib'
|
||||
[remaining call frames omitted]
|
||||
DynBuf Mallocs: 3 mallocs; 192 bytes
|
||||
Variable hash table statistics:
|
||||
Entries: 0; Buckets: 7; Non-empty Buckets: 0
|
||||
Maxlen: 0; Minlen: 0; Avglen: 0.000; Stddev: 0.000; Avg nonempty len: 0.000
|
||||
@@ -39870,6 +40036,7 @@ Total expression node evaluations: 3999940
|
||||
a = 493; hex(a) = 1ED
|
||||
hex(-1) = FFFFFFFF
|
||||
a = 32767; hex(a) = 7FFF
|
||||
DynBuf Mallocs: 5 mallocs; 320 bytes
|
||||
Variable hash table statistics:
|
||||
Entries: 1; Buckets: 7; Non-empty Buckets: 1
|
||||
Maxlen: 1; Minlen: 0; Avglen: 0.143; Stddev: 0.350; Avg nonempty len: 1.000
|
||||
@@ -39944,3 +40111,117 @@ REM 2025 Oct [a] MSG Nonconst IS set
|
||||
#!P: Next line has expired, but contains expression... please verify
|
||||
#!P: Expired: REM 2025 Oct [1] MSG Expr but not nonconst [today()]
|
||||
#!P: Expired: REM 2025-10-01 MSG No expr seen [1+2]
|
||||
# translations
|
||||
{"LANGID":"en"}
|
||||
# rem2ps begin
|
||||
January 2026 31 4 0
|
||||
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
|
||||
December 31
|
||||
February 28
|
||||
# rem2ps end
|
||||
# translations
|
||||
{"LANGID":"en"}
|
||||
# rem2ps begin
|
||||
January 2026 31 4 0
|
||||
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
|
||||
December 31
|
||||
February 28
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
-stdin-(2): `/': Division by zero
|
||||
# rem2ps end
|
||||
+----------------------------------------------------------------------------+
|
||||
| January 2020‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
| Sunday‎ | Monday‎ | Tuesday‎ |Wednesday‎ | Thursday‎ | Friday‎ | Saturday‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
| | | |1 ‎ |2 ‎ |3 ‎ |4 ‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|5 ‎ |6 ‎ |7 ‎ |8 ‎ |9 ‎ |10 ‎ |11 ‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|12 ‎ |13 ‎ |14 ‎ |15 ‎ |16 ‎ |17 ‎ |18 ‎ |
|
||||
| | | |]8;;https://dianne.skoll.ca\Hello,]8;;\‎ |]8;;https://dianne.skoll.ca\Hello,]8;;\‎ |]8;;https://dianne.skoll.ca\Hello,]8;;\‎ |[38;2;255;0;0m]8;;https://dianne.skoll.ca\Hello,]8;;\[0m‎ |
|
||||
| | | |]8;;https://dianne.skoll.ca\linky!]8;;\‎ |]8;;https://dianne.skoll.ca\linky!]8;;\‎ |]8;;https://dianne.skoll.ca\linky!]8;;\‎ |[38;2;255;0;0m]8;;https://dianne.skoll.ca\linky!]8;;\[0m‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|19 ‎ |20 ‎ |21 ‎ |22 ‎ |23 ‎ |24 ‎ |25 ‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|26 ‎ |27 ‎ |28 ‎ |29 ‎ |30 ‎ |31 ‎ | |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
+----------------------------------------------------------------------------+
|
||||
| January 2020‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
| Sunday‎ | Monday‎ | Tuesday‎ |Wednesday‎ | Thursday‎ | Friday‎ | Saturday‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
| | | |1 ‎ |2 ‎ |3 ‎ |4 ‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|5 ‎ |6 ‎ |7 ‎ |8 ‎ |9 ‎ |10 ‎ |11 ‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|12 ‎ |13 ‎ |14 ‎ |15 ‎ |16 ‎ |17 ‎ |18 ‎ |
|
||||
| | | |]8;;https://dianne.skoll.ca\Hello,]8;;\‎ | | | |
|
||||
| | | |]8;;https://dianne.skoll.ca\linky 1!]8;;\‎ | | | |
|
||||
| | | |]8;;https://dianne.skoll.ca\Hello,]8;;\‎ | | | |
|
||||
| | | |]8;;https://dianne.skoll.ca\linky 2!]8;;\‎ | | | |
|
||||
| | | |]8;;https://dianne.skoll.ca\Hello,]8;;\‎ | | | |
|
||||
| | | |]8;;https://dianne.skoll.ca\linky 3!]8;;\‎ | | | |
|
||||
| | | |[38;2;255;0;0m]8;;https://dianne.skoll.ca\Hello,]8;;\[0m‎ | | | |
|
||||
| | | |[38;2;255;0;0m]8;;https://dianne.skoll.ca\linky 4!]8;;\[0m‎ | | | |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|19 ‎ |20 ‎ |21 ‎ |22 ‎ |23 ‎ |24 ‎ |25 ‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|26 ‎ |27 ‎ |28 ‎ |29 ‎ |30 ‎ |31 ‎ | |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
+----------------------------------------------------------------------------+
|
||||
| January 2020‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
| Sunday‎ | Monday‎ | Tuesday‎ |Wednesday‎ | Thursday‎ | Friday‎ | Saturday‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
| | | |1 ‎ |2 ‎ |3 ‎ |4 ‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|5 ‎ |6 ‎ |7 ‎ |8 ‎ |9 ‎ |10 ‎ |11 ‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|12 ‎ |13 ‎ |14 ‎ |15 ‎ |16 ‎ |17 ‎ |18 ‎ |
|
||||
| | | |]8;;https://dianne.skoll.ca\Hello,]8;;\‎ | | | |
|
||||
| | | |]8;;https://dianne.skoll.ca\linky 1!]8;;\‎ | | | |
|
||||
| | | | | | | |
|
||||
| | | |]8;;https://dianne.skoll.ca\Hello,]8;;\‎ | | | |
|
||||
| | | |]8;;https://dianne.skoll.ca\linky 2!]8;;\‎ | | | |
|
||||
| | | | | | | |
|
||||
| | | |]8;;https://dianne.skoll.ca\Hello,]8;;\‎ | | | |
|
||||
| | | |]8;;https://dianne.skoll.ca\linky 3!]8;;\‎ | | | |
|
||||
| | | | | | | |
|
||||
| | | |[38;2;255;0;0m]8;;https://dianne.skoll.ca\Hello,]8;;\[0m‎ | | | |
|
||||
| | | |[38;2;255;0;0m]8;;https://dianne.skoll.ca\linky 4!]8;;\[0m‎ | | | |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|19 ‎ |20 ‎ |21 ‎ |22 ‎ |23 ‎ |24 ‎ |25 ‎ |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|26 ‎ |27 ‎ |28 ‎ |29 ‎ |30 ‎ |31 ‎ | |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
|
||||
130
tests/test.rem
130
tests/test.rem
@@ -1589,9 +1589,11 @@ dump -c a
|
||||
set a eval("1 +")
|
||||
set a eval("1/0")
|
||||
set a eval("1 / / 2")
|
||||
set a eval("1 / # 2")
|
||||
set a catch(eval("1 +"), 33)
|
||||
set a catch(eval("1/0"), 34)
|
||||
set a catch(eval("1 / / 2"), 35)
|
||||
set a catch(eval("1 / # 2"), 35)
|
||||
|
||||
# Ensure RUN is disabled in eval
|
||||
set a shell("echo foo")
|
||||
@@ -1765,7 +1767,135 @@ set a mbchar(0)
|
||||
set a mbchar(0, 120)
|
||||
set a mbchar(120, 0)
|
||||
|
||||
# Make sure trailing space doesn't cause a diagnostic.
|
||||
set a "foo"
|
||||
|
||||
# Hebrew dates
|
||||
|
||||
SET a hebdate(1, "Tishrey")
|
||||
SET a hebdate(1, "Tishri")
|
||||
SET a hebdate(1, "Tishrei")
|
||||
SET a hebdate(1, "תשרי")
|
||||
|
||||
SET a hebdate(1, "Cheshvan")
|
||||
SET a hebdate(1, "Kheshvan")
|
||||
SET a hebdate(1, "Heshvan")
|
||||
SET a hebdate(1, "חשוון")
|
||||
|
||||
SET a hebdate(1, "Kislev")
|
||||
SET a hebdate(1, "כסלו")
|
||||
|
||||
SET a hebdate(1, "Tevet")
|
||||
SET a hebdate(1, "טבת")
|
||||
|
||||
SET a hebdate(1, "Shvat")
|
||||
SET a hebdate(1, "Shevat")
|
||||
SET a hebdate(1, "שבט")
|
||||
|
||||
SET a hebdate(1, "Adar A")
|
||||
SET a hebdate(1, "Adar 1")
|
||||
SET a hebdate(1, "Adar I")
|
||||
SET a hebdate(1, "אדר א'")
|
||||
SET a hebdate(1, "אדר א")
|
||||
SET a hebdate(1, "אדר 1")
|
||||
SET a hebdate(1, "אדר I")
|
||||
|
||||
SET a hebdate(1, "Adar B")
|
||||
SET a hebdate(1, "Adar 2")
|
||||
SET a hebdate(1, "Adar II")
|
||||
SET a hebdate(1, "אדר ב'")
|
||||
SET a hebdate(1, "אדר ב")
|
||||
SET a hebdate(1, "אדר 2")
|
||||
SET a hebdate(1, "אדר II")
|
||||
|
||||
SET a hebdate(1, "Nisan")
|
||||
SET a hebdate(1, "ניסן")
|
||||
|
||||
SET a hebdate(1, "Iyar")
|
||||
SET a hebdate(1, "Iyyar")
|
||||
SET a hebdate(1, "אייר")
|
||||
|
||||
SET a hebdate(1, "Sivan")
|
||||
SET a hebdate(1, "סיון")
|
||||
|
||||
SET a hebdate(1, "Tamuz")
|
||||
SET a hebdate(1, "Tammuz")
|
||||
SET a hebdate(1, "תמוז")
|
||||
|
||||
SET a hebdate(1, "Av")
|
||||
SET a hebdate(1, "אב")
|
||||
|
||||
SET a hebdate(1, "Elul")
|
||||
SET a hebdate(1, "אלול")
|
||||
|
||||
SET a hebdate(1, "Adar")
|
||||
SET a hebdate(1, "אדר")
|
||||
|
||||
set a hebmon('1991-09-09')
|
||||
set a ivritmon('1991-09-09')
|
||||
|
||||
set a hebmon('1991-10-09')
|
||||
set a ivritmon('1991-10-09')
|
||||
|
||||
set a hebmon('1991-11-08')
|
||||
set a ivritmon('1991-11-08')
|
||||
|
||||
set a hebmon('1991-12-08')
|
||||
set a ivritmon('1991-12-08')
|
||||
|
||||
set a hebmon('1992-01-06')
|
||||
set a ivritmon('1992-01-06')
|
||||
|
||||
set a hebmon('1992-02-05')
|
||||
set a ivritmon('1992-02-05')
|
||||
|
||||
set a hebmon('1992-03-06')
|
||||
set a ivritmon('1992-03-06')
|
||||
|
||||
set a hebmon('1991-03-16')
|
||||
set a ivritmon('1991-03-16')
|
||||
|
||||
set a hebmon('1991-04-15')
|
||||
set a ivritmon('1991-04-15')
|
||||
|
||||
set a hebmon('1991-05-14')
|
||||
set a ivritmon('1991-05-14')
|
||||
|
||||
set a hebmon('1991-06-13')
|
||||
set a ivritmon('1991-06-13')
|
||||
|
||||
set a hebmon('1991-07-12')
|
||||
set a ivritmon('1991-07-12')
|
||||
|
||||
set a hebmon('1991-08-11')
|
||||
set a ivritmon('1991-08-11')
|
||||
|
||||
# mbpad
|
||||
|
||||
set a mbpad("foo", "bar", 3)
|
||||
set a mbpad("foo", "bar", 3, 1)
|
||||
set a mbpad("foo", "bar", 8)
|
||||
set a mbpad("foo", "bar", 8, 1)
|
||||
set a mbpad("foo", "🙂💩", 3)
|
||||
set a mbpad("foo", "🙂💩", 3, 1)
|
||||
set a mbpad("foo", "🙂💩", 8)
|
||||
set a mbpad("foo", "🙂💩", 8, 1)
|
||||
set bad char(255)
|
||||
set a mbpad("foo", bad, 3)
|
||||
set a mbpad("foo", bad, 3, 1)
|
||||
set a mbpad("foo", bad, 8)
|
||||
set a mbpad("foo", bad, 8, 1)
|
||||
set a mbpad(bad, "bar", 0)
|
||||
set a mbpad(bad, "bar", 0, 1)
|
||||
set a mbpad(bad, "bar", 8)
|
||||
set a mbpad(bad, "bar", 8, 1)
|
||||
|
||||
DEBUG -x
|
||||
SET $TerminalHyperlinks 1
|
||||
REM INFO "Url: https://dianne.skoll.ca" MSG Hello, linky!
|
||||
REM INFO "Url: https://dianne.skoll.ca" MSF Hello, linky!
|
||||
REM INFO "Url: https://dianne.skoll.ca" SPECIAL COLOR 255 0 0 Hello, linky!
|
||||
|
||||
# Don't want Remind to queue reminders
|
||||
EXIT
|
||||
|
||||
|
||||
@@ -11,6 +11,16 @@ REM TODO COMPLETE-THROUGH 2025-08-06 6 Aug 2025 +7 MSG %"Seventh%" %l
|
||||
REM TODO Wed +7 COMPLETE-THROUGH 2025-08-13 MSG %"Eighth%" %l
|
||||
REM TODO Wed +7 COMPLETE-THROUGH 2025-08-12 MSG %"Ninth%" %l
|
||||
|
||||
REM TODO 1 Aug 2025 MSG %"First%" %l
|
||||
REM TODO 1 Aug COMPLETED-THROUGH 2022-07-31 MSG %"Second%" %l
|
||||
REM TODO 1 Aug COMPLETED-THROUGH 2022-08-01 MSG %"Third%" %l
|
||||
REM TODO 20 Aug 2025 +7 MSG %"Fourth%" %l
|
||||
REM TODO 13 Aug 2025 +7 MSG %"Fifth%" %l
|
||||
REM TODO 6 Aug 2025 +7 MSG %"Sixth%" %l
|
||||
REM TODO COMPLETED-THROUGH 2025-08-06 6 Aug 2025 +7 MSG %"Seventh%" %l
|
||||
REM TODO Wed +7 COMPLETED-THROUGH 2025-08-13 MSG %"Eighth%" %l
|
||||
REM TODO Wed +7 COMPLETED-THROUGH 2025-08-12 MSG %"Ninth%" %l
|
||||
|
||||
# Test MAX-OVERDUE
|
||||
REM TODO 2025-08-13 MAX-OVERDUE 3 MSG %"Yup%" %l
|
||||
REM TODO 2025-08-12 MAX-OVERDUE 3 MSG %"Yup2%" %l
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# Use the output to verify your translations.
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 Dianne Skoll
|
||||
# Copyright (C) 1992-2026 Dianne Skoll
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -26,7 +26,9 @@ set a utctolocal('2050-01-01@01:00')
|
||||
set a localtoutc('2050-12-31@23:44')
|
||||
|
||||
set a localtoutc('2050-03-13@00:00')
|
||||
set a localtoutc('2050-03-13@02:00')
|
||||
# This next one fails on MUSL, so it's commented out.
|
||||
# We expect 2050-03-13@07:00 but MUSL gives 2050-03-13@06:00
|
||||
#set a localtoutc('2050-03-13@02:00')
|
||||
set a localtoutc('2050-11-06@00:00')
|
||||
set a localtoutc('2050-11-06@02:00')
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Makefile.in for installing WWW server calendar scripts
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
# The complete path to where the scripts actually live, as seen by
|
||||
# the UNIX operating system.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
# CAL_DISPATCH -- Shell script for CGI directory to dispatch calendar
|
||||
# commands.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# PostScript calendar shell script
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
echo "Content-type: application/pdf"
|
||||
echo
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# PostScript calendar shell script
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
echo "Content-type: application/postscript"
|
||||
echo
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Hebrew date shell script
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
echo Content-type: text/html
|
||||
echo ""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Hebrew date reminder file
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
BANNER %
|
||||
IF !$PSCAL
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# HTML calendar shell script
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
echo "Content-Type: text/html"
|
||||
echo ""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Hebrew PostScript calendar shell script
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
# Figure out the month: If day <= 20, use this month; otherwise, use
|
||||
# next month.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Hebrew PostScript calendar shell script
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
# Figure out the month: If day <= 20, use this month; otherwise, use
|
||||
# next month.
|
||||
|
||||
2
www/moon
2
www/moon
@@ -2,7 +2,7 @@
|
||||
# Moon shell script
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
echo Content-type: text/html
|
||||
echo
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# File for giving moon phase info.
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
set now now()
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Sunrise shell script
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
echo Content-type: text/html
|
||||
echo
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# File for giving sunrise info
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Copyright (C) 1992-2026 by Dianne Skoll
|
||||
|
||||
set now now()
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user