mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de03d0c02a | ||
|
|
3e6e3b6a34 | ||
|
|
bf48e31335 | ||
|
|
77c0beffb3 | ||
|
|
9a724d7618 | ||
|
|
1c20f54edb | ||
|
|
52b36d4503 | ||
|
|
0a82eadea6 | ||
|
|
0cd4fe67d1 | ||
|
|
9c31004b62 | ||
|
|
3431833be2 | ||
|
|
a98a4b9f72 | ||
|
|
4aaba4da88 | ||
|
|
98e37d8c54 | ||
|
|
4335aac7b2 | ||
|
|
695a2a3c2d | ||
|
|
47aa542d4f | ||
|
|
5b4d1ae264 | ||
|
|
721ccb9af9 | ||
|
|
ab1a6c412a | ||
|
|
c3a555942b | ||
|
|
0d15977875 | ||
|
|
0a7e6ee219 | ||
|
|
baf049662f | ||
|
|
fd5d9a479d | ||
|
|
01d3081f19 | ||
|
|
7841077fc6 | ||
|
|
2003c7a703 | ||
|
|
4a603ce60d | ||
|
|
caad7f5aa3 | ||
|
|
ea2312c0b2 | ||
|
|
c0c49be0b5 | ||
|
|
c0594811bf | ||
|
|
b7e13845b6 | ||
|
|
94b340305c | ||
|
|
f477757ac0 | ||
|
|
a8017c6fc7 | ||
|
|
aad746bca3 | ||
|
|
953ff8c49e | ||
|
|
b5258b1eb5 | ||
|
|
82733e817b | ||
|
|
86e94009a4 | ||
|
|
04ea056820 | ||
|
|
d6ee16cc13 | ||
|
|
ead660fe41 | ||
|
|
58e5ae15b0 | ||
|
|
85a8a4b016 | ||
|
|
c43eaec274 | ||
|
|
13fd54b990 | ||
|
|
a48b2ec02e | ||
|
|
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 |
@@ -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
|
||||
|
||||
|
||||
19
README.md
19
README.md
@@ -95,16 +95,9 @@ though I suspect it's entirely or almost entirely human-written.
|
||||
2. No AI-generated patches or other sorts of contributions to Remind
|
||||
will be accepted.
|
||||
|
||||
3. Remind's source code may not be used to train an AI model,
|
||||
including an LLM model, unless all of the output of said model is
|
||||
released under the GNU General Public License, version 2. If you use
|
||||
any of Remind's source code to train your model, then anything that
|
||||
the model produces is a derived product of Remind and must be licensed
|
||||
under the same terms as Remind.
|
||||
|
||||
---
|
||||
|
||||
Contact info: dianne@skoll.ca
|
||||
|
||||
Home page: [https://dianne.skoll.ca/projects/remind/](https://dianne.skoll.ca/projects/remind/)
|
||||
|
||||
3. It is not yet settled whether, if you train an AI model on this
|
||||
source code, the resulting model, and/or any outputs it produces, are
|
||||
derivative works of the code. But if they are, and do not fall under
|
||||
"fair use" or equivalent in your jurisdiction, then as with any other
|
||||
derivative work you may only distribute them under the terms of the
|
||||
GNU General Public License, version 2.
|
||||
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
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
|
||||
|
||||
41
configure
vendored
41
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.02.01.
|
||||
# Generated by GNU Autoconf 2.72 for remind 06.02.05.
|
||||
#
|
||||
#
|
||||
# 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.02.01'
|
||||
PACKAGE_STRING='remind 06.02.01'
|
||||
PACKAGE_VERSION='06.02.05'
|
||||
PACKAGE_STRING='remind 06.02.05'
|
||||
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.02.01 to adapt to many kinds of systems.
|
||||
'configure' configures remind 06.02.05 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.02.01:";;
|
||||
short | recursive ) echo "Configuration of remind 06.02.05:";;
|
||||
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.02.01
|
||||
remind configure 06.02.05
|
||||
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.02.01, which was
|
||||
It was created by remind $as_me 06.02.05, which was
|
||||
generated by GNU Autoconf 2.72. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
@@ -4316,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 :
|
||||
@@ -4384,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'`
|
||||
@@ -4899,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.02.01, which was
|
||||
This file was extended by remind $as_me 06.02.05, which was
|
||||
generated by GNU Autoconf 2.72. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -4964,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.02.01
|
||||
remind config.status 06.02.05
|
||||
configured by $0, generated by GNU Autoconf 2.72,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
15
configure.ac
15
configure.ac
@@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(remind, 06.02.01, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_INIT(remind, 06.02.05, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_CONFIG_SRCDIR([src/queue.c])
|
||||
|
||||
cat <<'EOF'
|
||||
@@ -103,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"
|
||||
|
||||
@@ -106,11 +106,12 @@
|
||||
"Syntax table for `remind-conf-mode'.")
|
||||
|
||||
;;; keyword sets
|
||||
|
||||
;;; MOON, WEEK, SHADE, COLOR and COLOUR are not really keywords,
|
||||
;;; but they are widely-supported SPECIALS, so I add them here.
|
||||
(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"
|
||||
@@ -120,7 +121,8 @@
|
||||
"PSFILE" "PUSH" "PUSH-FUNCS" "PUSH-VARS" "PUSH-OMIT-CONTEXT" "REM" "RETURN"
|
||||
"RUN" "SATISFY" "SCAN" "SCANFROM" "SCHED" "SECOND" "SET"
|
||||
"SKIP" "SPECIAL" "SYSINCLUDE" "TAG" "THIRD" "THROUGH" "TODO"
|
||||
"TRANSLATE" "TRANS" "TZ" "UNSET" "UNTIL" "WARN")
|
||||
"TRANSLATE" "TRANS" "TZ" "UNSET" "UNTIL" "WARN"
|
||||
"MOON" "WEEK" "SHADE" "COLOR" "COLOUR")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
|
||||
@@ -131,7 +133,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"
|
||||
@@ -145,10 +147,10 @@
|
||||
"$May" "$MinsFromUTC" "$Minute" "$Monday" "$Mplu" "$NextMode"
|
||||
"$November" "$Now" "$NumFullOmits" "$NumPartialOmits" "$NumQueued"
|
||||
"$NumTrig" "$October" "$On" "$OnceFile" "$ParseUntriggered" "$Pm"
|
||||
"$PrefixLineNo" "$PSCal" "$RunOff" "$Saturday" "$September"
|
||||
"$PrefixLineNo" "$PSCal" "$RunOff" "$Saturday" "$September" "$Shaded"
|
||||
"$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")
|
||||
@@ -165,26 +167,151 @@
|
||||
|
||||
(defconst remind-builtin-functions
|
||||
(sort
|
||||
(list "_" "abs" "access" "adawn" "adusk" "ampm" "ansicolor" "args" "asc"
|
||||
"baseyr" "catch" "catcherr" "char" "choose" "codepoint" "coerce" "columns" "const" "current" "date"
|
||||
"datepart" "datetime" "dawn" "day" "daysinmon" "defined" "dosubst"
|
||||
"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"
|
||||
"mbasc" "mbindex" "mbstrlen" "mbsubstr" "min"
|
||||
"minsfromutc" "minute" "mon" "monnum" "moondate" "moondatetime"
|
||||
"moonphase" "moonrise" "moonrisedir" "moonset" "moonsetdir" "moontime"
|
||||
"multitrig" "ndawn" "ndusk" "nonconst" "nonomitted" "now" "ord" "orthodoxeaster"
|
||||
"ostype" "pad" "plural" "psmoon" "psshade" "realcurrent" "realnow"
|
||||
"realtoday" "rows" "sgn" "shell" "shellescape" "slide" "soleq"
|
||||
"stdout" "strlen" "substr" "sunrise" "sunset" "time" "timepart"
|
||||
"timezone" "today" "trig" "trigback" "trigbase" "trigcompletethrough" "trigdate" "trigdatetime"
|
||||
"trigdelta" "trigduration" "trigeventduration" "trigeventstart" "trigeventstarttz"
|
||||
"trigfrom" "trigger" "triginfo" "trigistodo" "trigmaxoverdue" "trigpriority" "trigrep"
|
||||
"trigscanfrom" "trigtags" "trigtime" "trigtimedelta" "trigtimerep" "trigtimetz" "trigtz"
|
||||
"triguntil" "trigvalid" "typeof" "tzconvert" "upper" "utctolocal"
|
||||
"value" "version" "weekno" "wkday" "wkdaynum" "year"
|
||||
(list
|
||||
"_"
|
||||
"abs"
|
||||
"access"
|
||||
"adawn"
|
||||
"adusk"
|
||||
"ampm"
|
||||
"ansicolor"
|
||||
"args"
|
||||
"asc"
|
||||
"baseyr"
|
||||
"catch"
|
||||
"catcherr"
|
||||
"char"
|
||||
"choose"
|
||||
"codepoint"
|
||||
"coerce"
|
||||
"columns"
|
||||
"const"
|
||||
"current"
|
||||
"date"
|
||||
"datepart"
|
||||
"datetime"
|
||||
"dawn"
|
||||
"day"
|
||||
"daysinmon"
|
||||
"defined"
|
||||
"dosubst"
|
||||
"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"
|
||||
"ivritmon"
|
||||
"language"
|
||||
"localtoutc"
|
||||
"lower"
|
||||
"max"
|
||||
"mbasc"
|
||||
"mbindex"
|
||||
"mblower"
|
||||
"mbstrlen"
|
||||
"mbsubstr"
|
||||
"mbupper"
|
||||
"min"
|
||||
"minsfromutc"
|
||||
"minute"
|
||||
"mon"
|
||||
"monnum"
|
||||
"moondate"
|
||||
"moondatetime"
|
||||
"moonphase"
|
||||
"moonrise"
|
||||
"moonrisedir"
|
||||
"moonset"
|
||||
"moonsetdir"
|
||||
"moontime"
|
||||
"multitrig"
|
||||
"ndawn"
|
||||
"ndusk"
|
||||
"nonconst"
|
||||
"nonomitted"
|
||||
"now"
|
||||
"ord"
|
||||
"orthodoxeaster"
|
||||
"ostype"
|
||||
"pad"
|
||||
"plural"
|
||||
"psmoon"
|
||||
"psshade"
|
||||
"realcurrent"
|
||||
"realnow"
|
||||
"realtoday"
|
||||
"rows"
|
||||
"sgn"
|
||||
"shell"
|
||||
"shellescape"
|
||||
"slide"
|
||||
"soleq"
|
||||
"stdout"
|
||||
"strlen"
|
||||
"substr"
|
||||
"sunrise"
|
||||
"sunset"
|
||||
"time"
|
||||
"timepart"
|
||||
"timezone"
|
||||
"today"
|
||||
"trig"
|
||||
"trigback"
|
||||
"trigbase"
|
||||
"trigcompletethrough"
|
||||
"trigdate"
|
||||
"trigdatetime"
|
||||
"trigdelta"
|
||||
"trigduration"
|
||||
"trigeventduration"
|
||||
"trigeventstart"
|
||||
"trigeventstarttz"
|
||||
"trigfrom"
|
||||
"trigger"
|
||||
"triginfo"
|
||||
"trigistodo"
|
||||
"trigmaxoverdue"
|
||||
"trigpriority"
|
||||
"trigrep"
|
||||
"trigscanfrom"
|
||||
"trigtags"
|
||||
"trigtime"
|
||||
"trigtimedelta"
|
||||
"trigtimerep"
|
||||
"trigtimetz"
|
||||
"trigtz"
|
||||
"triguntil"
|
||||
"trigvalid"
|
||||
"typeof"
|
||||
"tzconvert"
|
||||
"upper"
|
||||
"utctolocal"
|
||||
"value"
|
||||
"version"
|
||||
"weekno"
|
||||
"wkday"
|
||||
"wkdaynum"
|
||||
"year"
|
||||
)
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
|
||||
126
docs/WHATSNEW
126
docs/WHATSNEW
@@ -1,5 +1,131 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 06.02.05 - 2026-03-02
|
||||
|
||||
- NEW FEATURE: rem2pdf: Add --avoid-overfull option. This makes the
|
||||
font size in a calendar box with many reminders smaller in an effort
|
||||
to fit everything neatly into the box.
|
||||
|
||||
- NEW FEATURE: rem2pdf: Add --entry-spacing option. This lets you
|
||||
adjust the spacing between entries in a calendar box. It defaults
|
||||
to one-half of the --border-size option. NOTE: In previous
|
||||
releases, --entry-spacing defaulted to the SAME size as
|
||||
--border-size, so unless you supply an --entry-spacing value to set
|
||||
it back, the PDF calendars produced by this version of rem2pdf will
|
||||
be slightly more compact than previous versions.
|
||||
|
||||
- DOCUMENTATION UPDATE: Clarify rules around use of Remind source code
|
||||
for training AI models.
|
||||
|
||||
- FIX: include/holidays/nz.rem: Fix spelling of "Auckland" and add
|
||||
Matariki. Fixes courtesy of Bart Joy.
|
||||
|
||||
* VERSION 06.02.04 - 2026-02-15
|
||||
|
||||
- IMPROVEMENT: remind: Add the mblower and mbupper functions, which are
|
||||
multibyte counterparts to lower and upper.
|
||||
|
||||
- MINOR NEW FEATURE: remind: Add the $Shaded system variable that counts
|
||||
how many times a "SPECIAL SHADE" reminder has triggered. See the
|
||||
man page for an example of how this can be useful.
|
||||
|
||||
- MINOR IMPROVEMENT: Make all programs that ship with Remind (remind,
|
||||
rem2ps, rem2pdf, rem2html and tkremind) accept a --version long option.
|
||||
|
||||
- CHANGE: remind: Remind used to warn if the POP-OMIT-CONTEXT, POP-VARS
|
||||
or POP-FUNCS command corresponding to the relevant PUSH command was
|
||||
in a different file than the PUSH command. But there are valid use
|
||||
cases for this, so Remind no longer emits the warning unless you use
|
||||
the "-dp" debugging flag.
|
||||
|
||||
* VERSION 06.02.03 - 2026-02-05
|
||||
|
||||
- NEW FEATURE: rem2html: Add a new --yaag option to produce a calendar
|
||||
in the "year-at-a-glance" format. This format features a table with
|
||||
an entire month in each row. Thanks to Robert Black for suggesting
|
||||
this and for helping out with the CSS.
|
||||
|
||||
- CHANGE: remind: If standard output is a TTY, then default
|
||||
$TerminalHyperlinks to 1
|
||||
|
||||
- CHANGE: remind: Increase the default value of $MaxSatIter from 1000
|
||||
to 10000, reflecting the higher speed of the new expression
|
||||
evaluation engine as well as the speed of modern CPUs.
|
||||
|
||||
- UPDATE: examples/remind.vim: Update the URL to point to maintained
|
||||
version.
|
||||
|
||||
- IMPROVEMENT: include/sun.rem: Add Wikipedia links for sunrise/sunset
|
||||
|
||||
- IMPROVEMENT: Add MOON, SHADE, WEEK, COLOR and COLOUR to the Emacs
|
||||
syntax highlighting keyword list.
|
||||
|
||||
- IMPROVEMENT: If an invalid value is assigned to a system variable,
|
||||
issue the error "Invalid value for system variable" rather than
|
||||
"Type mismatch"
|
||||
|
||||
- DOC FIX: Fix typo in man page
|
||||
|
||||
- BUG FIX: rem2html: Eliminate "use of uninitialized variable"
|
||||
warning.
|
||||
|
||||
- BUG FIX: remind: The "trigbase" JSON key in "remind -pp" output had
|
||||
an incorrectly-formatted value. This has been fixed; thanks to
|
||||
Georg Simon for reporting this bug.
|
||||
|
||||
* 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,
|
||||
|
||||
@@ -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
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
" Maintainer: Davide Alberani <da@erlug.linux.it>
|
||||
" Last Change: 02 Nov 2015 + 13 Mar 2022 by Dianne Skoll <dianne@skoll.ca>
|
||||
" Version: 0.7+dianne1
|
||||
" URL: http://ismito.it/vim/syntax/remind.vim
|
||||
" URL: https://github.com/alberanid/vim-config/blob/master/syntax/remind.vim
|
||||
"
|
||||
" remind is a sophisticated reminder service
|
||||
" you can download remind from:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -34,3 +34,36 @@ REM 27 December ADDOMIT SCANFROM -28 SATISFY [wkdaynum($T-2) == 0] MSG %"Christm
|
||||
REM 27 December ADDOMIT SCANFROM -28 SATISFY [wkdaynum($T-2) == 6] MSG %"Christmas Day (observed)%" %! %b.
|
||||
REM 28 December ADDOMIT SCANFROM -28 SATISFY [wkdaynum($T-2) == 0] MSG %"Boxing Day (observed)%" %! %b.
|
||||
REM 28 December ADDOMIT SCANFROM -28 SATISFY [wkdaynum($T-2) == 6] MSG %"Boxing Day (observed)%" %! %b.
|
||||
|
||||
# Matariki. Source:
|
||||
# https://www.legislation.govt.nz/act/public/2022/0014/23.0/LMS557893.html#LMS557893
|
||||
OMIT 2022-06-24 MSG Matariki
|
||||
OMIT 2023-07-14 MSG Matariki
|
||||
OMIT 2024-06-28 MSG Matariki
|
||||
OMIT 2025-06-20 MSG Matariki
|
||||
OMIT 2026-07-10 MSG Matariki
|
||||
OMIT 2027-06-25 MSG Matariki
|
||||
OMIT 2028-07-14 MSG Matariki
|
||||
OMIT 2029-07-06 MSG Matariki
|
||||
OMIT 2030-06-21 MSG Matariki
|
||||
OMIT 2031-07-11 MSG Matariki
|
||||
OMIT 2032-07-02 MSG Matariki
|
||||
OMIT 2033-06-24 MSG Matariki
|
||||
OMIT 2034-07-07 MSG Matariki
|
||||
OMIT 2035-06-29 MSG Matariki
|
||||
OMIT 2036-07-18 MSG Matariki
|
||||
OMIT 2037-07-10 MSG Matariki
|
||||
OMIT 2038-06-25 MSG Matariki
|
||||
OMIT 2039-07-15 MSG Matariki
|
||||
OMIT 2040-07-06 MSG Matariki
|
||||
OMIT 2041-07-19 MSG Matariki
|
||||
OMIT 2042-07-11 MSG Matariki
|
||||
OMIT 2043-07-03 MSG Matariki
|
||||
OMIT 2044-06-24 MSG Matariki
|
||||
OMIT 2045-07-07 MSG Matariki
|
||||
OMIT 2046-06-29 MSG Matariki
|
||||
OMIT 2047-07-19 MSG Matariki
|
||||
OMIT 2048-07-03 MSG Matariki
|
||||
OMIT 2049-06-25 MSG Matariki
|
||||
OMIT 2050-07-15 MSG Matariki
|
||||
OMIT 2051-06-30 MSG Matariki
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
# If you want the national holidays as well, you must
|
||||
# also SYSINCLUDE holidays/nz.rem
|
||||
|
||||
REM Monday 26 January ADDOMIT SCANFROM -28 MSG %"Aukland Anniversary Day%" %! %b.
|
||||
REM Monday 26 January ADDOMIT SCANFROM -28 MSG %"Auckland Anniversary Day%" %! %b.
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
# If you want the national holidays as well, you must
|
||||
# also SYSINCLUDE holidays/nz.rem
|
||||
|
||||
REM Monday 26 January ADDOMIT SCANFROM -28 MSG %"Aukland Anniversary Day%" %! %b.
|
||||
REM Monday 26 January ADDOMIT SCANFROM -28 MSG %"Auckland Anniversary Day%" %! %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,7 +1,12 @@
|
||||
# Sunrise and sunset
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
IF !$CalMode && !$PsCal
|
||||
REM NOQUEUE AT [sunrise()] MSG %"%"%(Sunrise) %! %2.
|
||||
REM NOQUEUE AT [sunset()] MSG %"%"%(Sunset) %! %2.
|
||||
# Localize if we can
|
||||
IF access($SysInclude + "/translations/" + _("LANGID") + "/sun.rem", "r") >= 0
|
||||
SYSINCLUDE translations/[_("LANGID")]/sun.rem
|
||||
ENDIF
|
||||
|
||||
IF !$CalMode && !$PsCal
|
||||
REM INFO "Url: https://en.wikipedia.org/wiki/Sunrise" NOQUEUE AT [sunrise()] MSG %"%"%(Sunrise) %! %2.
|
||||
REM INFO "Url: https://en.wikipedia.org/wiki/Sunset" NOQUEUE AT [sunset()] MSG %"%"%(Sunset) %! %2.
|
||||
ENDIF
|
||||
|
||||
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"
|
||||
@@ -21,6 +21,9 @@ render characters outside the ASCII character set, see
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\-version
|
||||
Print the version of \fBrem2ps\fR and exit.
|
||||
.TP
|
||||
.B \-v
|
||||
Be more verbose. This causes \fBrem2ps\fR to print progress messages
|
||||
to the standard error stream. Normally, it is silent.
|
||||
|
||||
176
man/remind.1.in
176
man/remind.1.in
@@ -1,6 +1,10 @@
|
||||
.TH REMIND 1 "@RELEASE_DATE@" "Remind" "VERSION @VERSION@"
|
||||
.SH NAME
|
||||
remind \- a sophisticated reminder service
|
||||
.SH THE BOOK OF REMIND
|
||||
This man page is a good \fIreference\fR for Remind. However, if you
|
||||
are a novice wishing to \fIlearn\fR Remind, I suggest downloading
|
||||
"The Book of Remind" from the Remind home page at https://dianne.skoll.ca/projects/remind/
|
||||
.SH SYNOPSIS
|
||||
.B remind [\fIoptions\fR] \fIfilename\fR [\fIdate\fR] [\fI*rep\fR] [\fItime\fR]
|
||||
.SH DESCRIPTION
|
||||
@@ -103,10 +107,8 @@ can fix up formatting problems with right-to-left languages in the calendar
|
||||
display.
|
||||
.TP
|
||||
.B 'z'
|
||||
causes \fBRemind\fR to use escape sequences to turn reminders with a
|
||||
"URL" info string into hyperlinks. In order to work, your terminal
|
||||
must support the escape sequences documented at
|
||||
https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
|
||||
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
|
||||
@@ -167,7 +169,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
|
||||
@@ -198,7 +200,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.
|
||||
@@ -349,6 +353,10 @@ Echo lines when displaying error messages
|
||||
.B f
|
||||
Trace the reading of reminder files
|
||||
.TP
|
||||
.B p
|
||||
Issue warnings if a POP-OMIT-CONTEXT, POP-VARS or POP-FUNCS matches
|
||||
a corresponding PUSH that is in a different file.
|
||||
.TP
|
||||
.B s
|
||||
Trace expression parsing and display the internal expression node
|
||||
tree. This is unlikely to be useful unless you are working on
|
||||
@@ -1360,7 +1368,7 @@ minutes. That is, 13:39 and 13.39 are equivalent.
|
||||
for a timed reminder is the same as the current system date, the
|
||||
reminder is queued for later activation. When \fBRemind\fR has
|
||||
finished processing the reminder file, it puts itself in the
|
||||
background, and activates timed reminders when the system time reached
|
||||
background, and activates timed reminders when the system time reaches
|
||||
the specified time. Note that if you use the \fBNOQUEUE\fR modifier
|
||||
in the \fBREM\fR command, then this queuing and background activation
|
||||
is \fInot\fR performed. \fBNOQUEUE\fR is useful if you want a time
|
||||
@@ -1995,6 +2003,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
|
||||
@@ -2587,16 +2596,13 @@ a sequence of more than one byte. For example, in a UTF-8 environment,
|
||||
the string "🙂" contains one character but four bytes. And the string
|
||||
"één" contains three characters but five bytes.
|
||||
.PP
|
||||
\fBRemind\fR has a set of functions
|
||||
that work on \fIbytes\fR, namely \fBindex\fR, \fBstrlen\fR and \fBsubstr\fR.
|
||||
These are not safe to use on multi-byte strings; instead use
|
||||
\fBmbindex\fR, \fBmbstrlen\fR and \fBmbsubstr\fR. If you know \fIfor sure\fR
|
||||
that a string contains only single-byte characters, then the byte-oriented
|
||||
versions may be used and are faster than the multi-byte versions.
|
||||
.PP
|
||||
Some ancient or embedded systems may lack the C library functions needed
|
||||
to deal with multi-byte strings. In that case, the \fBmb\fIxxx\fR functions
|
||||
all return an error.
|
||||
\fBRemind\fR has a set of functions that work on \fIbytes\fR, namely
|
||||
\fBindex\fR, \fBstrlen\fR and \fBsubstr\fR, and several more. These
|
||||
are not safe to use on multi-byte strings; instead use \fBmbindex\fR,
|
||||
\fBmbstrlen\fR and \fBmbsubstr\fR, and the \fBmb\fR variants of the
|
||||
others. If you know \fIfor sure\fR that a string contains only
|
||||
single-byte characters, then the byte-oriented versions may be used
|
||||
and are faster than the multi-byte versions.
|
||||
.RE
|
||||
.TP
|
||||
.B TIME
|
||||
@@ -2637,7 +2643,7 @@ The following examples illustrate constants in \fBRemind\fR expressions:
|
||||
12, 36, \-10, 0, 1209, 0x1F, 0xfe00 (the last two demonstrate the use of hexadecimal constants)
|
||||
.TP
|
||||
.B STRING constants
|
||||
"Hello there", "This is a test", "\\nHello\\tThere", ""
|
||||
"Hello there", "This is a test", "\\nHello\\tThere", "", "π is Cool! 🙂"
|
||||
.PP
|
||||
.RS
|
||||
Note that the empty string is represented by "". \fBRemind\fR supports
|
||||
@@ -3258,7 +3264,7 @@ near the beginning of the file and not change it after that.
|
||||
.TP
|
||||
.B $MaxSatIter
|
||||
The maximum number of iterations for the \fBSATISFY\fR clause
|
||||
(described later.) Must be at least 10.
|
||||
(described later.) Must be at least 10. The default value is 10,000.
|
||||
.TP
|
||||
.B $MaxStringLen
|
||||
A limit on the longest string that \fBRemind\fR will allow you
|
||||
@@ -3360,6 +3366,30 @@ If non-zero, then the \fB\-p\fR option was supplied on the command line.
|
||||
.B $RunOff (read-only)
|
||||
If non-zero, the \fBRUN\fR directives are disabled.
|
||||
.TP
|
||||
.B $Shaded (read-only)
|
||||
Returns the number of times a \fBSHADE\fR special reminder has triggered.
|
||||
\fIThis variable is set only in calendar mode, not agenda mode\fR. You
|
||||
can use this variable to avoid shading a calendar day that has already
|
||||
been shaded.
|
||||
.RS
|
||||
.PP
|
||||
For example, suppose you want to shade all calendar boxes yellow
|
||||
\fIif\fR any reminders have triggered on that day. But if a box has
|
||||
been explicitly shaded, you don't want to overwrite that shading.
|
||||
You could use something like this:
|
||||
.PP
|
||||
.nf
|
||||
SET n $NumTrig
|
||||
# Do all your reminders here...
|
||||
|
||||
# If anything has triggered and the box is
|
||||
# not already shaded, then shade it yellow
|
||||
IF $NumTrig > n && !$Shaded
|
||||
REM SPECIAL SHADE 255 255 128
|
||||
ENDIF
|
||||
.fi
|
||||
.RE
|
||||
.TP
|
||||
.B $SimpleCal (read-only)
|
||||
Set to a non-zero value if \fIeither\fR of the \fB\-p\fR or \fB\-s\fR
|
||||
command-line options was supplied.
|
||||
@@ -3487,6 +3517,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 1 if \fBRemind\fR's
|
||||
standard output is a terminal, or to 0 if it is not.
|
||||
.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
|
||||
@@ -3848,9 +3885,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
|
||||
@@ -4142,10 +4180,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.
|
||||
@@ -4214,8 +4252,15 @@ Given a \fBDATETIME\fR object interpreted in the local time zone, return
|
||||
a \fBDATETIME\fR object that expresses the same time in UTC.
|
||||
.TP
|
||||
.B lower(s_string)
|
||||
Returns a \fBSTRING\fR with all upper-case bytes in \fIstring\fR
|
||||
converted to lower-case. \fBNote:\fR This function works correctly
|
||||
only for ASCII strings. If you are using Unicode characters outside
|
||||
the ASCII set, use \fBmblower\fR instead.
|
||||
.TP
|
||||
.B mblower(s_string)
|
||||
Returns a \fBSTRING\fR with all upper-case characters in \fIstring\fR
|
||||
converted to lower-case.
|
||||
converted to lower-case. This function works correctly on any
|
||||
Unicode string.
|
||||
.TP
|
||||
.B max(x_arg1 [,x_arg2...)
|
||||
Can take any number of arguments, and returns the maximum. The arguments
|
||||
@@ -4498,7 +4543,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,
|
||||
@@ -4529,8 +4575,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.
|
||||
@@ -4547,6 +4593,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
|
||||
@@ -4625,7 +4676,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
|
||||
@@ -4633,9 +4684,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,
|
||||
@@ -4823,9 +4875,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
|
||||
@@ -5117,8 +5169,15 @@ of the time zone name.
|
||||
.PP
|
||||
.TP
|
||||
.B upper(s_string)
|
||||
Returns a \fBSTRING\fR with all lower-case bytes in \fIstring\fR
|
||||
converted to upper-case. \fBNote:\fR This function works correctly
|
||||
only for ASCII strings. If you are using Unicode characters outside
|
||||
the ASCII set, use \fBmbupper\fR instead.
|
||||
.TP
|
||||
.B mbupper(s_string)
|
||||
Returns a \fBSTRING\fR with all lower-case characters in \fIstring\fR
|
||||
converted to upper-case.
|
||||
converted to upper-case. This function works correctly on any
|
||||
Unicode string.
|
||||
.TP
|
||||
.B utctolocal(q_datetime)
|
||||
Given a \fBDATETIME\fR object interpreted in UTC, return a
|
||||
@@ -6919,14 +6978,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.
|
||||
@@ -6956,6 +7044,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.
|
||||
@@ -6969,7 +7062,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
|
||||
|
||||
@@ -18,10 +18,12 @@ binary. If you are using Tcl/Tk 8.5, you may also need either the Img
|
||||
or the tkpng extension to handle PNG images.
|
||||
|
||||
.SH COMMAND-LINE OPTIONS
|
||||
\fBTkRemind\fR itself has no command-line options. However, it passes
|
||||
any command-line argument starting with \fB\-\fR to \fBRemind\fR as an
|
||||
option. In addition, \fBTkRemind\fR will respect the \fB\-m\fR and
|
||||
\fB\-b1\fR options and adjust its appearance accordingly.
|
||||
\fBTkRemind\fR itself has only one command-line option:
|
||||
\fB\-\-version\fR, which makes it print the version of \fBTkRemind\fR
|
||||
and exit. Any other command-line argument starting with \fB\-\fR to
|
||||
\fBRemind\fR as an option. In addition, \fBTkRemind\fR will respect
|
||||
the \fB\-m\fR and \fB\-b1\fR options and adjust its appearance
|
||||
accordingly.
|
||||
.PP
|
||||
\fIRead_file\fR is the file from which \fBTkRemind\fR reads reminders.
|
||||
It is in standard \fBRemind\fR format. \fIWrite_file\fR is the file
|
||||
@@ -193,6 +195,12 @@ Select the appropriate paper size and orientation. Activate
|
||||
be the normal case unless you have many reminders in a particular
|
||||
day. (See the \fBrem2pdf\fR documentation.)
|
||||
|
||||
If you activate \fBAvoid over-full boxes\fR, then \fBTkRemind\fR
|
||||
will pass the \fB\-\-avoid\-overfull\fR option to \fBrem2pdf\fR. This
|
||||
will make it try to fit many reminders into a calendar box by shrinking
|
||||
the font. This option, if activated, also automatically activates
|
||||
\fBFill page\fR.
|
||||
|
||||
Finally, click \fBPrint\fR to print or \fBCancel\fR to cancel. Note
|
||||
that during printing, \fBRemind\fR is called with the
|
||||
\fB-itkremind=1\fR option and also an additional \fB-itkprint=1\fR
|
||||
@@ -562,7 +570,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
|
||||
|
||||
|
||||
@@ -96,6 +96,14 @@ without any E<lt>htmlE<gt> or E<lt>bodyE<gt> tags.
|
||||
Use I<title> as the content between E<lt>titleE<gt> and E<lt>/titleE<gt>
|
||||
tags.
|
||||
|
||||
=item --yaag
|
||||
|
||||
Instead of making 7-column tables for each month, show each month
|
||||
as a I<single> table row of 38 columns. This is the so-called
|
||||
"year-at-a-glance" format. You must use the "-ppp" option to
|
||||
C<remind> or the --yaag option will be ignored. And this format
|
||||
works best if you create a calendar for an entire year (so, starting
|
||||
in January and using "-ppp12" to get 12 months' worth of reminders.)
|
||||
|
||||
=item --prologue I<html_text>
|
||||
|
||||
@@ -188,6 +196,7 @@ Options:
|
||||
--title string What to put in <title>...</title> tags
|
||||
--prologue html_text Text to insert at the top of the body
|
||||
--epilogue html_text Text to insert at the end of the body
|
||||
--yaag Output one month per row for year-at-a-glance format
|
||||
EOM
|
||||
exit($exit_status);
|
||||
}
|
||||
@@ -218,6 +227,7 @@ sub parse_options
|
||||
"man",
|
||||
"utf8",
|
||||
"pngs",
|
||||
"yaag",
|
||||
"version",
|
||||
"stylesheet=s",
|
||||
"nostyle",
|
||||
@@ -316,6 +326,10 @@ sub parse_input
|
||||
if ($_ eq '[') {
|
||||
return parse_input_ppp();
|
||||
}
|
||||
if ($Options{yaag}) {
|
||||
$Options{yaag} = 0;
|
||||
print STDERR "Ignoring option --yaag: You must use remind -ppp for this option\n";
|
||||
}
|
||||
if (/# translations/) {
|
||||
slurp_translations();
|
||||
next;
|
||||
@@ -472,6 +486,10 @@ sub parse_input_ppp
|
||||
}
|
||||
if (exists($array->[0]{caltype}) &&
|
||||
$array->[0]{caltype} eq 'weekly') {
|
||||
if ($Options{yaag}) {
|
||||
$Options{yaag} = 0;
|
||||
print STDERR "Ignoring option --yaag for a weekly calendar\n";
|
||||
}
|
||||
emit_ppp_calendars($array, 'weekly');
|
||||
} else {
|
||||
emit_ppp_calendars($array, 'monthly');
|
||||
@@ -488,11 +506,51 @@ sub parse_input_ppp
|
||||
}
|
||||
}
|
||||
|
||||
sub print_yaag_weekday_row
|
||||
{
|
||||
my ($cal) = @_;
|
||||
print "<tr class=\"rem-yaag-weekday-row\">";
|
||||
print "<th class=\"rem-yaag-empty-header\"> </th>";
|
||||
my $ex;
|
||||
for (my $i=0; $i<37; $i++) {
|
||||
my $day;
|
||||
if ($cal->{mondayfirst}) {
|
||||
$day = $cal->{daynames}->[($i+1) % 7];
|
||||
} else {
|
||||
$day = $cal->{daynames}->[$i % 7];
|
||||
}
|
||||
if (($i % 7) == 6) {
|
||||
$ex = " rem-yaag-end-of-week";
|
||||
} else {
|
||||
$ex = "";
|
||||
}
|
||||
print "<th class=\"rem-yaag-weekday-header$ex\">$day</th>";
|
||||
}
|
||||
print "</tr>\n";
|
||||
}
|
||||
|
||||
sub emit_ppp_calendars
|
||||
{
|
||||
my ($array, $type) = @_;
|
||||
my $prev_year = 0;
|
||||
my $done_one = 0;
|
||||
foreach my $cal (@$array) {
|
||||
if ($Options{yaag}) {
|
||||
if ($cal->{year} != $prev_year) {
|
||||
$prev_year = $cal->{year};
|
||||
if ($done_one) {
|
||||
print "</table>\n";
|
||||
}
|
||||
print "<span class=\"year_heading\">$prev_year</span>\n";
|
||||
print "<table class=\"rem-yaag\">\n";
|
||||
print_yaag_weekday_row($cal);
|
||||
}
|
||||
}
|
||||
emit_one_ppp_calendar($cal, $type);
|
||||
$done_one = 1;
|
||||
}
|
||||
if ($done_one) {
|
||||
print "</table>\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -766,42 +824,79 @@ sub output_calendar
|
||||
|
||||
# Start the table
|
||||
my $class;
|
||||
if ($Options{nostyle}) {
|
||||
print '<table width="100%" border="1" cellspacing=\"0\"><caption>' .
|
||||
$Month . ' ' . $Year . '</caption>' . "\n";
|
||||
print '<tr>';
|
||||
$class = ' width="14%"';
|
||||
} else {
|
||||
if ($type eq 'monthly') {
|
||||
print '<table class="rem-cal"><caption class="rem-cal-caption">' .
|
||||
$Month . ' ' . $Year . '</caption>' . "\n";
|
||||
if (!$Options{yaag}) {
|
||||
if ($Options{nostyle}) {
|
||||
print '<table width="100%" border="1" cellspacing="0">';
|
||||
if ($type eq 'monthly') {
|
||||
print "<caption>$Month $Year </caption>";
|
||||
}
|
||||
print "\n<tr>";
|
||||
$class = ' width="14%"';
|
||||
} else {
|
||||
print '<table class="rem-cal">' . "\n";
|
||||
if ($type eq 'monthly') {
|
||||
print '<table class="rem-cal"><caption class="rem-cal-caption">' .
|
||||
$Month . ' ' . $Year . '</caption>' . "\n";
|
||||
} else {
|
||||
print '<table class="rem-cal">' . "\n";
|
||||
}
|
||||
print '<tr class="rem-cal-hdr-row">';
|
||||
$class = ' class="rem-cal-hdr"';
|
||||
}
|
||||
print '<tr class="rem-cal-hdr-row">';
|
||||
$class = ' class="rem-cal-hdr"';
|
||||
}
|
||||
if ($type eq 'monthly') {
|
||||
if (!$Mondayfirst) {
|
||||
print "<th$class>" . $Daynames[0] . '</th>';
|
||||
if ($type eq 'monthly') {
|
||||
if (!$Mondayfirst) {
|
||||
print "<th$class>" . $Daynames[0] . '</th>';
|
||||
}
|
||||
for (my $i=1; $i<7; $i++) {
|
||||
print "<th$class>" . $Daynames[$i] . '</th>';
|
||||
}
|
||||
if ($Mondayfirst) {
|
||||
print "<th$class>" . $Daynames[0] . '</th>';
|
||||
}
|
||||
} else {
|
||||
for (my $i=0; $i<7; $i++) {
|
||||
my $inf = $date_info->[$i];
|
||||
print "<th$class>" . $inf->{dayname} . "<br>" .
|
||||
$inf->{day} . ' ' .
|
||||
$inf->{month} . ' ' .
|
||||
$inf->{year} . '</th>';
|
||||
}
|
||||
}
|
||||
for (my $i=1; $i<7; $i++) {
|
||||
print "<th$class>" . $Daynames[$i] . '</th>';
|
||||
}
|
||||
if ($Mondayfirst) {
|
||||
print "<th$class>" . $Daynames[0] . '</th>';
|
||||
}
|
||||
} else {
|
||||
for (my $i=0; $i<7; $i++) {
|
||||
my $inf = $date_info->[$i];
|
||||
print "<th$class>" . $inf->{dayname} . "<br>" .
|
||||
$inf->{day} . ' ' .
|
||||
$inf->{month} . ' ' .
|
||||
$inf->{year} . '</th>';
|
||||
}
|
||||
}
|
||||
|
||||
print "</tr>\n";
|
||||
print "</tr>\n";
|
||||
} else {
|
||||
# For year-at-a-glance calendar, it's just a row
|
||||
print '<tr class="rem-yaag-cal-row">';
|
||||
print '<th class="rem-yaag-cal-hdr">' . $Month . "</th>\n";
|
||||
|
||||
my $cells_drawn = 0;
|
||||
# Print the blank ones
|
||||
for (my $i=0; $i<$first_col; $i++) {
|
||||
print "<td class=\"rem-yaag-cal-blank\"> </td>";
|
||||
$cells_drawn++;
|
||||
}
|
||||
|
||||
# All the entries
|
||||
for (my $day=1; $day <= $Numdays; $day++) {
|
||||
if (($cells_drawn % 7) == 6) {
|
||||
draw_day_cell($day, 1, $type, ' rem-yaag-end-of-week');
|
||||
} else {
|
||||
draw_day_cell($day, 1, $type);
|
||||
}
|
||||
$cells_drawn++;
|
||||
}
|
||||
|
||||
# And fill in the remaining ones
|
||||
while ($cells_drawn < 37) {
|
||||
if (($cells_drawn % 7) == 6) {
|
||||
print "<td class=\"rem-yaag-cal-blank rem-yaag-end-of-week\"> </td>";
|
||||
} else {
|
||||
print "<td class=\"rem-yaag-cal-blank\"> </td>";
|
||||
}
|
||||
$cells_drawn++;
|
||||
}
|
||||
print "</tr>\n";
|
||||
return;
|
||||
}
|
||||
# Start the calendar rows
|
||||
my $col = 0;
|
||||
if ($Options{nostyle}) {
|
||||
@@ -895,9 +990,10 @@ sub output_calendar
|
||||
|
||||
sub draw_day_cell
|
||||
{
|
||||
my($day, $number_of_rows, $type) = @_;
|
||||
my($day, $number_of_rows, $type, $extra_class) = @_;
|
||||
my $shade = $shades->[$day];
|
||||
my $week = '';
|
||||
$extra_class = '' unless defined($extra_class);
|
||||
if (exists($weeks->{$day})) {
|
||||
if ($weeks->{$day}->{url}) {
|
||||
$week = ' <a href="' . $weeks->{$day}->{url} . '">' . escape_html($weeks->{$day}->{body}) . '</a>';
|
||||
@@ -905,19 +1001,22 @@ sub draw_day_cell
|
||||
$week = ' ' . escape_html($weeks->{$day}->{body});
|
||||
}
|
||||
}
|
||||
my $class;
|
||||
if ($Options{nostyle}) {
|
||||
$class = $classes->[$day] || '';
|
||||
} else {
|
||||
$class = $classes->[$day] || "rem-cell rem-cell-$number_of_rows-rows";
|
||||
my $class = $classes->[$day] || '';
|
||||
if (!$Options{nostyle}) {
|
||||
$class .= ' ' if $class ne '';
|
||||
if ($Options{yaag}) {
|
||||
$class .= "rem-yaag-cell"
|
||||
} else {
|
||||
$class .= "rem-cell rem-cell-$number_of_rows-rows";
|
||||
}
|
||||
}
|
||||
if ($shade) {
|
||||
$shade = " style=\"background: $shade;\"";
|
||||
} else {
|
||||
$shade = "";
|
||||
}
|
||||
if ($class ne '') {
|
||||
print "<td class=\"$class\"$shade>\n";
|
||||
if ($class ne '' || $extra_class ne '') {
|
||||
print "<td class=\"$class$extra_class\"$shade>\n";
|
||||
} else {
|
||||
print "<td valign=\"top\" $shade>\n";
|
||||
}
|
||||
@@ -982,7 +1081,11 @@ sub draw_day_cell
|
||||
print "<div style=\"float: right\">$day$week</div>\n";
|
||||
print "<p> </p>\n";
|
||||
} else {
|
||||
print "<div class=\"rem-daynumber\">$day$week</div>\n";
|
||||
if ($Options{yaag}) {
|
||||
print "<div class=\"rem-yaag-daynumber\">$day$week</div>\n";
|
||||
} else {
|
||||
print "<div class=\"rem-daynumber\">$day$week</div>\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($Options{nostyle}) {
|
||||
@@ -1016,7 +1119,7 @@ if ($Options{help}) {
|
||||
system("perldoc $0");
|
||||
exit(0);
|
||||
} elsif ($Options{version}) {
|
||||
print "rem2html version $rem2html_version.\n";
|
||||
print "rem2html version $rem2html_version\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -1048,6 +1151,11 @@ table.rem-cal {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
span.year_heading {
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
font-size: 28pt;
|
||||
}
|
||||
|
||||
table.rem-sc-table {
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
font-size: 10pt;
|
||||
@@ -1073,14 +1181,6 @@ td.rem-empty, td.rem-cell, td.rem-small-calendar {
|
||||
border-width: 1px;
|
||||
vertical-align: top;
|
||||
}
|
||||
td.rem-today {
|
||||
width: 14%;
|
||||
height: 7em;
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
border-color: #EE3333;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.rem-cal {
|
||||
width: 100%;
|
||||
@@ -1116,5 +1216,84 @@ td.rem-sc-empty-cell, td.rem-sc-cell {
|
||||
caption.rem-sc-caption {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
table.rem-yaag {
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
font-size: 8pt;
|
||||
table-layout: fixed;
|
||||
cellspacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
td.rem-yaag-cell {
|
||||
height: 7em;
|
||||
border-style: solid;
|
||||
border-color: #adadad;
|
||||
border-width: 1px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
th.rem-yaag-weekday-header {
|
||||
font-weight: 100;
|
||||
font-size: 9pt;
|
||||
padding: 6px 0 0 6px;
|
||||
text-align:left;
|
||||
border-style: solid;
|
||||
border-color: #adadad;
|
||||
border-width: 1px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
td.rem-yaag-cal-blank {
|
||||
height: 7em;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #adadad;
|
||||
background-color: #d5d6d5;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
td.rem-yaag-end-of-week {
|
||||
border-right-width: 3;
|
||||
}
|
||||
|
||||
th.rem-yaag-end-of-week {
|
||||
border-right-width: 3;
|
||||
}
|
||||
|
||||
th.rem-yaag-cal-hdr {
|
||||
text-align: right;
|
||||
padding-top: 8px;
|
||||
padding-right: 5px;
|
||||
font-weight: 100;
|
||||
font-size: 9pt;
|
||||
border-style: solid;
|
||||
border-color: #adadad;
|
||||
border-width: 1px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
div.rem-yaag-daynumber {
|
||||
float: right;
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
tr.rem-yaag-cal-row:nth-child(3n+1) {
|
||||
border-bottom: 3px solid #000;
|
||||
}
|
||||
|
||||
.rem-yaag-weekday-row .rem-yaag-empty-header {
|
||||
height: 20pt;
|
||||
width: 70px !important;
|
||||
}
|
||||
|
||||
td.rem-today {
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
border-color: #EE3333;
|
||||
}
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ my $media_to_size = {
|
||||
};
|
||||
|
||||
my $help = 0;
|
||||
my $version = 0;
|
||||
|
||||
my $settings = {
|
||||
landscape => 0,
|
||||
@@ -41,7 +42,7 @@ my $settings = {
|
||||
media => 'Letter',
|
||||
width => 0,
|
||||
height => 0,
|
||||
|
||||
avoid_overfull_boxes => 0,
|
||||
title_font => 'Sans',
|
||||
header_font => 'Sans',
|
||||
daynum_font => 'Sans Bold Oblique',
|
||||
@@ -55,6 +56,7 @@ my $settings = {
|
||||
entry_size => 8,
|
||||
|
||||
border_size => 4,
|
||||
entry_spacing => -1,
|
||||
line_thickness => 1,
|
||||
|
||||
margin_top => 36,
|
||||
@@ -95,6 +97,7 @@ Options:
|
||||
--ps Output PostScript instead of PDF
|
||||
--eps Output encapsulated PostScript instead of PDF
|
||||
-cN Synonym for --small-calendars=N
|
||||
--avoid-overfull Shrink font size to avoid over-full boxes. Implies -e
|
||||
--left-numbers, -x Print day numbers on the left (monthly calendars only)
|
||||
--fill-page, -e Fill the entire page (monthly calendars only)
|
||||
--media=MEDIA, -mMEDIA Size for specified media
|
||||
@@ -111,6 +114,7 @@ Options:
|
||||
--header-size=S Specify size of font for weekday names
|
||||
--daynum-size=S Specify size of font for day numbers
|
||||
--entry-size=S Specify size of font for calendar entries
|
||||
--entry-spacing=S Specify extra spacing between calendar entries
|
||||
--border-size=S Specify size of gaps between items in 1/72nds of an inch
|
||||
--line-thickness=S Specify line thickness in 1/72nds of an inch
|
||||
--margin-top=S Specify top margin size in 1/72nds of an inch
|
||||
@@ -126,6 +130,7 @@ Options:
|
||||
--title-url=URL Link calendar title to URL
|
||||
--verbose, -v Print progress messages
|
||||
--help Display this help
|
||||
--version Print version and exit
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -137,6 +142,7 @@ my $ret = GetOptions('landscape|l' => \$settings->{landscape},
|
||||
'svg' => \$settings->{svg},
|
||||
'ps' => \$settings->{ps},
|
||||
'eps' => \$settings->{eps},
|
||||
'avoid-overfull' => \$settings->{avoid_overfull_boxes},
|
||||
'fill-page|e' => \$settings->{fill_entire_page},
|
||||
'weeks-per-page|p=i' => \$settings->{weeks_per_page},
|
||||
'media|m=s' => \$settings->{media},
|
||||
@@ -153,6 +159,7 @@ my $ret = GetOptions('landscape|l' => \$settings->{landscape},
|
||||
'header-size=f' => \$settings->{header_size},
|
||||
'daynum-size=f' => \$settings->{daynum_size},
|
||||
'entry-size=f' => \$settings->{entry_size},
|
||||
'entry-spacing=f' => \$settings->{entry_spacing},
|
||||
'border-size=f' => \$settings->{border_size},
|
||||
'line-thickness=f' => \$settings->{line_thickness},
|
||||
'margin-top=f' => \$settings->{margin_top},
|
||||
@@ -166,6 +173,7 @@ my $ret = GetOptions('landscape|l' => \$settings->{landscape},
|
||||
'header-color=s' => \$settings->{header_color},
|
||||
'daynum-color=s' => \$settings->{daynum_color},
|
||||
'smallcal-color=s' => \$settings->{smallcal_color},
|
||||
'version' => \$version,
|
||||
'help' => \$help
|
||||
);
|
||||
if (!$ret) {
|
||||
@@ -178,6 +186,20 @@ if ($help) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($version) {
|
||||
print "rem2pdf version $VERSION\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($settings->{entry_spacing} < 0) {
|
||||
$settings->{entry_spacing} = 0.5 * $settings->{border_size};
|
||||
}
|
||||
|
||||
|
||||
if ($settings->{avoid_overfull_boxes}) {
|
||||
$settings->{fill_entire_page} = 1;
|
||||
}
|
||||
|
||||
my $bad = 0;
|
||||
foreach my $setting (qw(bg_color line_color title_color header_color daynum_color smallcal_color)) {
|
||||
my $c = $settings->{$setting};
|
||||
@@ -280,6 +302,9 @@ if ($settings->{svg}) {
|
||||
$settings->{width}, $settings->{height});
|
||||
}
|
||||
|
||||
# Save original entry size
|
||||
$settings->{original_entry_size} = $settings->{entry_size};
|
||||
|
||||
# set_metadata not available in older versions of Cairo
|
||||
eval { $surface->set_metadata('title', 'Calendar'); };
|
||||
eval { $surface->set_metadata('author', 'Remind (https://dianne.skoll.ca/projects/remind/)'); };
|
||||
@@ -473,6 +498,12 @@ the default top-right.
|
||||
|
||||
Make the calendar fill the available space on the page.
|
||||
|
||||
=item --avoid-overfull
|
||||
|
||||
If a calendar box is going to overflow, try to make the entries fit by
|
||||
decreasing the font size. Using the --avoid-overfull option automatically
|
||||
enables the --fill-page option.
|
||||
|
||||
=item --media=I<media>, -mI<media>
|
||||
|
||||
Specify the paper size (Letter, A4, etc.) For a list of valid media sizes,
|
||||
@@ -541,6 +572,12 @@ Specify the size of the blank border between the contents of a calendar
|
||||
box and the centre of the lines surrounding it, in 1/72ndths of an inch.
|
||||
The default is 4.
|
||||
|
||||
=item --entry-spacing=I<n>
|
||||
|
||||
Specify the amount of extra space, in 1/72ndths of an inch, to leave
|
||||
between calendar entries in a given calendar box. The default is
|
||||
one-half of the --border-size value.
|
||||
|
||||
=item --line-thickness=I<n>
|
||||
|
||||
Specify the thickness of the lines drawn on the calendar. The default is 1.
|
||||
@@ -620,6 +657,14 @@ to print per page; it is an integer that can range from 1 to 4.
|
||||
Print (on STDERR) the name of the month and year for each month that
|
||||
is rendered.
|
||||
|
||||
=item --version
|
||||
|
||||
Print the version of rem2pdf and exit.
|
||||
|
||||
=item --help
|
||||
|
||||
Print a brief summary of rem2pdf usage.
|
||||
|
||||
=back
|
||||
|
||||
=head1 USAGE
|
||||
|
||||
@@ -608,7 +608,28 @@ sub draw_row
|
||||
for (my $col=0; $col<7; $col++) {
|
||||
my $day = $self->{daymap}->[$row]->[$col];
|
||||
next if ($day < 1);
|
||||
$self->draw_day($cr, $settings, $so_far, $day, $col, $height);
|
||||
if ($settings->{avoid_overfull_boxes}) {
|
||||
my $old_entry_size = $settings->{entry_size};
|
||||
my $old_spacing = $settings->{entry_spacing};
|
||||
my $drawn = 0;
|
||||
while ($settings->{entry_size} >= 2.0) {
|
||||
my $h = $self->draw_day($cr, $settings, $so_far, $day, $col, 0);
|
||||
if ($h <= $height) {
|
||||
$self->draw_day($cr, $settings, $so_far, $day, $col, $height);
|
||||
$drawn = 1;
|
||||
last;
|
||||
}
|
||||
$settings->{entry_size} -= 0.125;
|
||||
$settings->{entry_spacing} = $old_spacing * $settings->{entry_size} / $old_entry_size;
|
||||
}
|
||||
if (!$drawn) {
|
||||
$self->draw_day($cr, $settings, $so_far, $day, $col, $height);
|
||||
}
|
||||
$settings->{entry_size} = $old_entry_size;
|
||||
$settings->{entry_spacing} = $old_spacing;
|
||||
} else {
|
||||
$self->draw_day($cr, $settings, $so_far, $day, $col, $height);
|
||||
}
|
||||
}
|
||||
|
||||
return $so_far + $height + $settings->{border_size} * 2;
|
||||
@@ -717,8 +738,8 @@ sub draw_day
|
||||
next;
|
||||
}
|
||||
if ($done) {
|
||||
$so_far += $settings->{border_size};
|
||||
$entry_height += $settings->{border_size};
|
||||
$so_far += $settings->{entry_spacing};
|
||||
$entry_height += $settings->{entry_spacing};
|
||||
}
|
||||
$done = 1;
|
||||
my $h2 = $entry->render($self, $cr, $settings, $so_far, $day, $col, $height);
|
||||
|
||||
@@ -146,7 +146,7 @@ sub render
|
||||
my $layout = Pango::Cairo::create_layout($cr);
|
||||
|
||||
$layout->set_text(Encode::decode('UTF-8', $self->{body}));
|
||||
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . int(0.75 * $settings->{entry_size}) . 'px');
|
||||
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . int(0.75 * $settings->{original_entry_size}) . 'px');
|
||||
$layout->set_font_description($desc);
|
||||
my ($wid, $h) = $layout->get_pixel_size();
|
||||
|
||||
@@ -197,7 +197,7 @@ sub render
|
||||
my $layout;
|
||||
my $bodywidth = 0;
|
||||
if ($self->{fontsize} <= 0) {
|
||||
$self->{fontsize} = $settings->{entry_size};
|
||||
$self->{fontsize} = $settings->{original_entry_size};
|
||||
}
|
||||
if ($self->{size} <= 0) {
|
||||
$self->{size} = $settings->{daynum_size};
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# A cheesy graphical front/back end for Remind using Tcl/Tk
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2025 Dianne Skoll
|
||||
# Copyright (C) 1992-2026 Dianne Skoll
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -342,6 +342,9 @@ set Option(PrintOrient) landscape
|
||||
set OptDescr(PrintFill) "(0/1) If 1, fill entire page when printing"
|
||||
set Option(PrintFill) 1
|
||||
|
||||
set OptDescr(PrintAvoidOverfull) "(0/1) If 1, avoid over-full calendar boxes if possible"
|
||||
set Option(PrintAvoidOverfull) 0
|
||||
|
||||
set OptDescr(WrapCal) "(0/1) If 1, make printed calendars occupy at most 5 rows"
|
||||
set Option(WrapCal) 0
|
||||
|
||||
@@ -442,6 +445,10 @@ proc Initialize {} {
|
||||
set PSCmd "$Remind -itkremind=1 -itkprint=1 -pp%WEEKS% -l %EXTRA%"
|
||||
set i 0
|
||||
while {$i < $argc} {
|
||||
if {"[lindex $argv $i]" == "--version"} {
|
||||
puts "tkremind version @VERSION@"
|
||||
exit 0
|
||||
}
|
||||
if {[regexp -- {-[bgxim].*} [lindex $argv $i]]} {
|
||||
append CommandLine " [lindex $argv $i]"
|
||||
append PSCmd " [lindex $argv $i]"
|
||||
@@ -1754,7 +1761,8 @@ proc DoPrintHelper {} {
|
||||
radiobutton .p.landscape -text "Landscape" -variable Option(PrintOrient) -value landscape
|
||||
radiobutton .p.portrait -text "Portrait" -variable Option(PrintOrient) -value portrait
|
||||
|
||||
checkbutton .p.fill -text "Fill page" -variable Option(PrintFill)
|
||||
checkbutton .p.fill -text "Fill page" -variable Option(PrintFill) -command PrintFillButtonPressed
|
||||
checkbutton .p.avoid -text "Avoid over-full boxes" -variable Option(PrintAvoidOverfull) -command PrintAvoidOverfullButtonPressed
|
||||
checkbutton .p.wrap -text "Use at most 5 rows" -variable Option(WrapCal)
|
||||
checkbutton .p.right -text "Day numbers at top-right" -variable Option(PrintDaysRight)
|
||||
checkbutton .p.calendars -text "Print small calendars" -variable Option(PrintSmallCalendars)
|
||||
@@ -1766,7 +1774,7 @@ proc DoPrintHelper {} {
|
||||
wm protocol .p WM_DELETE_WINDOW { .p.cancel flash; .p.cancel invoke }
|
||||
pack .p.f1 .p.ff .p.f2 .p.f2a .p.f3 .p.f3a \
|
||||
-side top -fill both -expand 1 -anchor w
|
||||
pack .p.fill .p.wrap .p.right .p.calendars -in .p.f3a \
|
||||
pack .p.fill .p.avoid .p.wrap .p.right .p.calendars -in .p.f3a \
|
||||
-side top -anchor w -fill none -expand 0
|
||||
pack .p.f4 -side top -fill both -expand 1 -anchor w
|
||||
pack .p.f11 .p.f12 -in .p.f1 -side top -fill none -expand 0 -anchor w
|
||||
@@ -1820,15 +1828,17 @@ proc DoPrintHelper {} {
|
||||
set p $PSCmd
|
||||
if {"$Option(View)" == "Month"} {
|
||||
set p [regsub %WEEKS% $PSCmd ""]
|
||||
set sd 1
|
||||
} else {
|
||||
set p [regsub %WEEKS% $PSCmd "+[get_num_weeks]"]
|
||||
set sd $CurDay
|
||||
}
|
||||
if {$Option(PrintFormat) == "pdf"} {
|
||||
set p [regsub %EXTRA% $p "-itkpdf=1 $Option(ExtraRemindArgs)"]
|
||||
set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PDF --weeks-per-page=[get_num_weeks]"
|
||||
set cmd "$p $sd [lindex $MonthNames $CurMonth] $CurYear | $Rem2PDF --weeks-per-page=[get_num_weeks]"
|
||||
} else {
|
||||
set p [regsub %EXTRA% $p "-itkpdf=1 $Option(ExtraRemindArgs)"]
|
||||
set cmd "$p 1 [lindex $MonthNames $CurMonth] $CurYear | $Rem2PDF --ps --weeks-per-page=[get_num_weeks]"
|
||||
set cmd "$p $sd [lindex $MonthNames $CurMonth] $CurYear | $Rem2PDF --ps --weeks-per-page=[get_num_weeks]"
|
||||
}
|
||||
if {$Option(PrintSize) == "letter"} {
|
||||
append cmd " --media=Letter"
|
||||
@@ -1855,6 +1865,9 @@ proc DoPrintHelper {} {
|
||||
append cmd " -e"
|
||||
}
|
||||
|
||||
if {$Option(PrintAvoidOverfull)} {
|
||||
append cmd " --avoid-overfull"
|
||||
}
|
||||
if {!$Option(PrintDaysRight)} {
|
||||
append cmd " -x"
|
||||
}
|
||||
@@ -1877,6 +1890,19 @@ proc DoPrintHelper {} {
|
||||
}
|
||||
}
|
||||
|
||||
proc PrintFillButtonPressed {} {
|
||||
global Option
|
||||
if { ! $Option(PrintFill) && $Option(PrintAvoidOverfull) } {
|
||||
set Option(PrintAvoidOverfull) 0
|
||||
}
|
||||
}
|
||||
|
||||
proc PrintAvoidOverfullButtonPressed {} {
|
||||
global Option
|
||||
if { ! $Option(PrintFill) && $Option(PrintAvoidOverfull) } {
|
||||
set Option(PrintFill) 1
|
||||
}
|
||||
}
|
||||
proc ShowPrintCommand { cmd } {
|
||||
global Option
|
||||
catch { destroy .pc }
|
||||
@@ -3474,47 +3500,47 @@ proc IssueBackgroundReminder { body time now tag qid info } {
|
||||
|
||||
incr BgCounter
|
||||
set w .bg$BgCounter
|
||||
toplevel $w
|
||||
toplevel $w -background $Option(WinBackground)
|
||||
wm iconname $w "Reminder"
|
||||
wm title $w "Timed reminder ($time)"
|
||||
label $w.l -text "Reminder for $time issued at $now"
|
||||
message $w.msg -aspect 2000 -text $body -justify left -anchor w -font {-weight bold} -relief groove -bd 2
|
||||
frame $w.b
|
||||
label $w.l -text "Reminder for $time issued at $now" -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
message $w.msg -aspect 2000 -text $body -justify left -anchor w -font {-weight bold} -relief groove -bd 2 -foreground $Option(TextColor) -background $Option(WinBackground)
|
||||
frame $w.b -background $Option(WinBackground)
|
||||
|
||||
# Automatically shut down window after a minute if option says so
|
||||
set after_token [after 60000 [list ClosePopup $w "" $Option(MailAddr) $Option(AutoClose) "" $tag $body $time $qid]]
|
||||
|
||||
wm protocol $w WM_DELETE_WINDOW [list ClosePopup $w $after_token "" 1 "" $tag $body $time $qid]
|
||||
button $w.ok -text "OK" -command [list ClosePopup $w $after_token "" 1 "" $tag $body $time $qid]
|
||||
button $w.ok -text "OK" -foreground $Option(LabelColor) -background $Option(WinBackground) -command [list ClosePopup $w $after_token "" 1 "" $tag $body $time $qid]
|
||||
set tktag [extract_tktag $tag]
|
||||
if {$tktag != "*"} {
|
||||
button $w.kill -text "Delete this reminder completely" -command [list ClosePopup $w $after_token "" 1 "kill" $tag $body $time $qid]
|
||||
button $w.kill -text "Delete this reminder completely" -foreground $Option(LabelColor) -background $Option(WinBackground) -command [list ClosePopup $w $after_token "" 1 "kill" $tag $body $time $qid]
|
||||
}
|
||||
if {$qid != "*"} {
|
||||
button $w.nomore -text "Don't remind me again today" -command [list ClosePopup $w $after_token "" 1 "ignore" $tag $body $time $qid]
|
||||
button $w.nomore -text "Don't remind me again today" -foreground $Option(LabelColor) -background $Option(WinBackground) -command [list ClosePopup $w $after_token "" 1 "ignore" $tag $body $time $qid]
|
||||
}
|
||||
pack $w.l -side top
|
||||
pack $w.msg -side top -expand 1 -fill both -anchor w
|
||||
frame $w.f
|
||||
frame $w.f -background $Option(WinBackground)
|
||||
pack $w.f -side top -expand 1 -fill both
|
||||
set row 0
|
||||
if {[dict exists $info location]} {
|
||||
label $w.f.l1 -text "Location: " -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight bold}
|
||||
message $w.f.l2 -text [dict get $info location] -justify left -anchor w -aspect 2000 -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight normal}
|
||||
label $w.f.l1 -text "Location: " -foreground $Option(LabelColor) -background $Option(WinBackground) -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight bold}
|
||||
message $w.f.l2 -text [dict get $info location] -foreground $Option(TextColor) -background $Option(WinBackground) -justify left -anchor w -aspect 2000 -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight normal}
|
||||
grid $w.f.l1 -row $row -column 0 -sticky nw
|
||||
grid $w.f.l2 -row $row -column 1 -sticky new
|
||||
incr row
|
||||
}
|
||||
if {[dict exists $info description]} {
|
||||
label $w.f.m1 -text "Description: " -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight bold}
|
||||
message $w.f.m2 -text [dict get $info description] -justify left -anchor w -aspect 2000 -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight normal}
|
||||
label $w.f.m1 -text "Description: " -foreground $Option(LabelColor) -background $Option(WinBackground) -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight bold}
|
||||
message $w.f.m2 -text [dict get $info description] -foreground $Option(TextColor) -background $Option(WinBackground) -justify left -anchor w -aspect 2000 -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight normal}
|
||||
grid $w.f.m1 -row $row -column 0 -sticky nw
|
||||
grid $w.f.m2 -row $row -column 1 -sticky new
|
||||
incr row
|
||||
}
|
||||
if {[dict exists $info url]} {
|
||||
set url [dict get $info url]
|
||||
message $w.f.u -text $url -justify left -anchor w -aspect 2000 -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight normal -underline 0} -fg #0000F0
|
||||
message $w.f.u -text $url -foreground $Option(TextColor) -background $Option(WinBackground) -justify left -anchor w -aspect 2000 -padx 1 -pady 1 -highlightthickness 0 -relief flat -bd 0 -font {-weight normal -underline 0}
|
||||
grid $w.f.u -row $row -column 0 -columnspan 2 -sticky new
|
||||
bind $w.f.u <Button-1> [list exec xdg-open "$url"]
|
||||
bind $w.f.u <Button-2> [list exec xdg-open "$url"]
|
||||
@@ -3600,11 +3626,11 @@ proc main {} {
|
||||
font create BoldFont {*}[font actual TkDefaultFont] -weight bold
|
||||
|
||||
global AppendFile HighestTagSoFar DayNames
|
||||
catch {
|
||||
puts "\nTkRemind Copyright (C) 1996-2025 Dianne Skoll"
|
||||
}
|
||||
catch { SetFonts }
|
||||
Initialize
|
||||
catch {
|
||||
puts "\nTkRemind Copyright (C) 1996-2026 Dianne Skoll"
|
||||
}
|
||||
|
||||
# If no $ConfigFile file, create an empty one
|
||||
if {![file exists $ConfigFile]} {
|
||||
|
||||
178
src/calendar.c
178
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;
|
||||
@@ -99,9 +95,6 @@ static struct line_drawing UTF8Drawing = {
|
||||
"\xe2\x94\x80"
|
||||
};
|
||||
|
||||
static char const *start_link = "\x1B]8;;";
|
||||
static char const *end_link = "\x1B]8;;\x1B\\";
|
||||
|
||||
static char *VT100Colors[2][2][2][2] /* [Br][R][G][B] */ = {
|
||||
{
|
||||
/*** DIM COLORS ***/
|
||||
@@ -182,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];
|
||||
@@ -321,6 +325,9 @@ Backgroundize(int d)
|
||||
return;
|
||||
}
|
||||
|
||||
if (cwts[d] == 0) {
|
||||
return;
|
||||
}
|
||||
if (!UseBGVTColors) {
|
||||
return;
|
||||
}
|
||||
@@ -346,7 +353,6 @@ UnBackgroundize(int d)
|
||||
printf("%s", Decolorize());
|
||||
}
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
static void
|
||||
send_lrm(void)
|
||||
{
|
||||
@@ -361,7 +367,6 @@ send_lrm(void)
|
||||
printf("\xE2\x80\x8E");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static char const *
|
||||
despace(char const *s)
|
||||
@@ -518,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];
|
||||
@@ -534,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;
|
||||
@@ -568,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;
|
||||
@@ -588,7 +585,6 @@ static int make_wchar_versions(CalEntry *e)
|
||||
e->wc_pos = buf;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gon(void)
|
||||
{
|
||||
@@ -1341,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];
|
||||
@@ -1399,8 +1387,6 @@ static void PrintLeft(char const *s, int width, char pad)
|
||||
i++;
|
||||
}
|
||||
if (buf != static_buf) free(buf);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1412,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;
|
||||
@@ -1486,7 +1452,6 @@ static void PrintCentered(char const *s, int width, char const *pad)
|
||||
i++;
|
||||
}
|
||||
if (buf != static_buf) free(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1539,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 */
|
||||
@@ -1553,21 +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 = get_url(e->infos);
|
||||
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;
|
||||
@@ -1575,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. */
|
||||
@@ -1612,8 +1589,7 @@ static int WriteOneColLine(int col)
|
||||
}
|
||||
|
||||
if (url) {
|
||||
printf("%s", start_link);
|
||||
printf("%s\x1B\\", url);
|
||||
printf("\x1B]8;;%s\x1B\\", url);
|
||||
}
|
||||
/* If we couldn't find a space char, print what we have. */
|
||||
if (!wspace) {
|
||||
@@ -1650,7 +1626,7 @@ static int WriteOneColLine(int col)
|
||||
}
|
||||
|
||||
if (url) {
|
||||
printf("%s", end_link);
|
||||
printf("\x1B]8;;\x1B\\");
|
||||
}
|
||||
/* Decolorize reminder if necessary, but keep any SHADE */
|
||||
if (UseVTColors && e->is_color) {
|
||||
@@ -1670,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. */
|
||||
@@ -1751,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
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -2158,8 +2123,9 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
}
|
||||
}
|
||||
if (trig.typ == PASSTHRU_TYPE) {
|
||||
if (!PsCal && !StrCmpi(trig.passthru, "SHADE")) {
|
||||
if (dse == DSEToday) {
|
||||
if (!strcasecmp(trig.passthru, "SHADE") && dse == DSEToday) {
|
||||
Shaded++;
|
||||
if (!PsCal) {
|
||||
DBufInit(&obuf);
|
||||
r = DoSubst(p, &obuf, &trig, &tim, dse, CAL_MODE);
|
||||
if (r) {
|
||||
@@ -2171,7 +2137,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);
|
||||
@@ -2184,11 +2150,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);
|
||||
@@ -2201,8 +2167,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);
|
||||
@@ -2266,8 +2232,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);
|
||||
@@ -2376,19 +2342,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);
|
||||
@@ -2400,9 +2364,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) {
|
||||
@@ -2490,7 +2452,7 @@ get_url(TrigInfo *infos)
|
||||
{
|
||||
TrigInfo *ti = infos;
|
||||
char const *url;
|
||||
if (!LinksInTerminal) {
|
||||
if (!TerminalHyperlinks) {
|
||||
/* Nope, not doing links in terminal */
|
||||
return NULL;
|
||||
}
|
||||
@@ -2588,7 +2550,7 @@ void WriteJSONTrigger(Trigger const *t, int include_tags)
|
||||
PrintJSONKeyPairInt("rep", t->rep);
|
||||
}
|
||||
if (t->d != NO_DAY && t->m != NO_MON && t->y != NO_YR) {
|
||||
printf("\"trigbase\":\"%04d-%02d-%-2d\",",
|
||||
printf("\"trigbase\":\"%04d-%02d-%02d\",",
|
||||
t->y, t->m+1, t->d);
|
||||
}
|
||||
/* Local omit is an array of days from 0=monday to 6=sunday.
|
||||
@@ -2706,7 +2668,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) {
|
||||
@@ -2812,9 +2774,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)
|
||||
|
||||
|
||||
16
src/err.h
16
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,11 +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_EXPECTING_EOXPR 116
|
||||
#define E_EXPECTING_ATOM 117
|
||||
#define E_BAD_MB_SEQ 113
|
||||
#define E_EXPR_NODES_EXCEEDED 114
|
||||
#define E_EXPECTING_EOXPR 115
|
||||
#define E_EXPECTING_ATOM 116
|
||||
#define E_BAD_VAL_FOR_SYSVAR 117
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
#undef EXTERN
|
||||
@@ -152,7 +152,6 @@
|
||||
#define STR2(X) #X
|
||||
|
||||
|
||||
#ifndef L_ERR_OVERRIDE
|
||||
EXTERN char *ErrMsg[]
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
@@ -270,15 +269,14 @@ 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)",
|
||||
/* E_BAD_VAL_FOR_SYSVAR */ "Invalid value for system variable",
|
||||
}
|
||||
#endif /* MK_GLOBALS */
|
||||
;
|
||||
#endif /* L_ERR_OVERRIDE */
|
||||
|
||||
EXTERN int NumErrs
|
||||
#ifdef MK_GLOBALS
|
||||
|
||||
108
src/expr.c
108
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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -242,6 +242,31 @@ find_end_of_expr(char const *s)
|
||||
return e;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* node_str - get string associated with a node */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static char const *
|
||||
node_str(expr_node const *node)
|
||||
{
|
||||
switch(node->type) {
|
||||
case N_VARIABLE:
|
||||
case N_SYSVAR:
|
||||
case N_USER_FUNC:
|
||||
return node->u.value.v.str;
|
||||
|
||||
case N_SHORT_VAR:
|
||||
case N_SHORT_SYSVAR:
|
||||
case N_SHORT_USER_FUNC:
|
||||
case N_SHORT_STR:
|
||||
return node->u.name;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* alloc_expr_node - allocate an expr_node object */
|
||||
@@ -418,11 +443,7 @@ get_var(expr_node *node, Value *ans, int *nonconst)
|
||||
Var *v;
|
||||
char const *str;
|
||||
|
||||
if (node->type == N_SHORT_VAR) {
|
||||
str = node->u.name;
|
||||
} else {
|
||||
str = node->u.value.v.str;
|
||||
}
|
||||
str = node_str(node);
|
||||
v = FindVar(str, 0);
|
||||
if (!v) {
|
||||
Eprint("%s: `%s'", GetErr(E_NOSUCH_VAR), str);
|
||||
@@ -448,11 +469,7 @@ get_var(expr_node *node, Value *ans, int *nonconst)
|
||||
static int
|
||||
get_sysvar(expr_node const *node, Value *ans)
|
||||
{
|
||||
if (node->type == N_SHORT_SYSVAR) {
|
||||
return GetSysVar(node->u.name, ans);
|
||||
} else {
|
||||
return GetSysVar(node->u.value.v.str, ans);
|
||||
}
|
||||
return GetSysVar(node_str(node), ans);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -619,13 +636,9 @@ eval_builtin(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
static void
|
||||
debug_enter_userfunc(expr_node *node, Value *locals, int nargs)
|
||||
{
|
||||
char const *fname;
|
||||
int i;
|
||||
if (node->type == N_SHORT_USER_FUNC) {
|
||||
fname = node->u.name;
|
||||
} else {
|
||||
fname = node->u.value.v.str;
|
||||
}
|
||||
char const *fname = node_str(node);
|
||||
|
||||
fprintf(ErrFp, "%s %s(", GetErr(E_ENTER_FUN), fname);
|
||||
for (i=0; i<nargs; i++) {
|
||||
if (i) fprintf(ErrFp, ", ");
|
||||
@@ -645,13 +658,9 @@ debug_enter_userfunc(expr_node *node, Value *locals, int nargs)
|
||||
static void
|
||||
debug_exit_userfunc(expr_node *node, Value const *ans, int r, Value *locals, int nargs)
|
||||
{
|
||||
char const *fname;
|
||||
char const *fname = node_str(node);
|
||||
int i;
|
||||
if (node->type == N_SHORT_USER_FUNC) {
|
||||
fname = node->u.name;
|
||||
} else {
|
||||
fname = node->u.value.v.str;
|
||||
}
|
||||
|
||||
fprintf(ErrFp, "%s %s(", GetErr(E_LEAVE_FUN), fname);
|
||||
for (i=0; i<nargs; i++) {
|
||||
if (i) fprintf(ErrFp, ", ");
|
||||
@@ -702,12 +711,7 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
Value stack_locals[STACK_ARGS_MAX];
|
||||
|
||||
/* Get the function name */
|
||||
char const *fname;
|
||||
if (node->type == N_SHORT_USER_FUNC) {
|
||||
fname = node->u.name;
|
||||
} else {
|
||||
fname = node->u.value.v.str;
|
||||
}
|
||||
char const *fname = node_str(node);
|
||||
|
||||
/* Find the function */
|
||||
f = FindUserFunc(fname);
|
||||
@@ -913,13 +917,9 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
return CopyValue(ans, &(node->u.value));
|
||||
|
||||
case N_SHORT_VAR:
|
||||
r = get_var(node, ans, nonconst);
|
||||
DBG(debug_evaluation(ans, r, "%s", node->u.name));
|
||||
return r;
|
||||
|
||||
case N_VARIABLE:
|
||||
r = get_var(node, ans, nonconst);
|
||||
DBG(debug_evaluation(ans, r, "%s", node->u.value.v.str));
|
||||
DBG(debug_evaluation(ans, r, "%s", node_str(node)));
|
||||
return r;
|
||||
|
||||
case N_LOCAL_VAR:
|
||||
@@ -929,19 +929,12 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
return r;
|
||||
|
||||
case N_SHORT_SYSVAR:
|
||||
/* System var? Return it and note non-constant expression */
|
||||
nonconst_debug(*nonconst, tr("System variable `$%s' makes expression non-constant"), node->u.name);
|
||||
*nonconst = 1;
|
||||
r = get_sysvar(node, ans);
|
||||
DBG(debug_evaluation(ans, r, "$%s", node->u.name));
|
||||
return r;
|
||||
|
||||
case N_SYSVAR:
|
||||
/* System var? Return it and note non-constant expression */
|
||||
nonconst_debug(*nonconst, tr("System variable `$%s' makes expression non-constant"), node->u.value.v.str);
|
||||
nonconst_debug(*nonconst, tr("System variable `$%s' makes expression non-constant"), node_str(node));
|
||||
*nonconst = 1;
|
||||
r = get_sysvar(node, ans);
|
||||
DBG(debug_evaluation(ans, r, "$%s", node->u.value.v.str));
|
||||
DBG(debug_evaluation(ans, r, "$%s", node_str(node)));
|
||||
return r;
|
||||
|
||||
case N_BUILTIN_FUNC:
|
||||
@@ -952,8 +945,8 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
}
|
||||
return eval_builtin(node, locals, ans, nonconst);
|
||||
|
||||
case N_USER_FUNC:
|
||||
case N_SHORT_USER_FUNC:
|
||||
case N_USER_FUNC:
|
||||
/* User-defined function? Evaluate it */
|
||||
return eval_userfunc(node, locals, ans, nonconst);
|
||||
|
||||
@@ -2256,7 +2249,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;
|
||||
@@ -2869,16 +2862,12 @@ static void print_expr_tree(expr_node *node, FILE *fp)
|
||||
fprintf(fp, "\"%s\"", node->u.name);
|
||||
return;
|
||||
case N_SHORT_VAR:
|
||||
fprintf(fp, "%s", node->u.name);
|
||||
return;
|
||||
case N_VARIABLE:
|
||||
fprintf(fp, "%s", node->u.value.v.str);
|
||||
fprintf(fp, "%s", node_str(node));
|
||||
return;
|
||||
case N_SHORT_SYSVAR:
|
||||
fprintf(fp, "$%s", node->u.name);
|
||||
return;
|
||||
case N_SYSVAR:
|
||||
fprintf(fp, "$%s", node->u.value.v.str);
|
||||
fprintf(fp, "$%s", node_str(node));
|
||||
return;
|
||||
case N_LOCAL_VAR:
|
||||
fprintf(fp, "arg[%d]", node->u.arg);
|
||||
@@ -2892,13 +2881,8 @@ static void print_expr_tree(expr_node *node, FILE *fp)
|
||||
fprintf(fp, ")");
|
||||
return;
|
||||
case N_SHORT_USER_FUNC:
|
||||
fprintf(fp, "(%s", node->u.name);
|
||||
if (node->child) fprintf(fp, " ");
|
||||
print_kids(node, fp);
|
||||
fprintf(fp, ")");
|
||||
return;
|
||||
case N_USER_FUNC:
|
||||
fprintf(fp, "(%s", node->u.value.v.str);
|
||||
fprintf(fp, "(%s", node_str(node));
|
||||
if (node->child) fprintf(fp, " ");
|
||||
print_kids(node, fp);
|
||||
fprintf(fp, ")");
|
||||
@@ -2994,7 +2978,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)
|
||||
{
|
||||
@@ -3014,7 +2997,6 @@ static char const *truncate_string(char const *src)
|
||||
cbuf[MAX_PRT_LEN*8] = 0;
|
||||
return cbuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -3040,7 +3022,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;
|
||||
@@ -3048,9 +3029,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) {
|
||||
@@ -3145,7 +3123,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;
|
||||
@@ -3318,7 +3296,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;
|
||||
|
||||
14
src/files.c
14
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);
|
||||
@@ -559,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) {
|
||||
@@ -627,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);
|
||||
@@ -874,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 */
|
||||
@@ -916,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;
|
||||
@@ -972,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);
|
||||
|
||||
246
src/funcs.c
246
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>
|
||||
|
||||
@@ -135,14 +133,18 @@ 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 FMblower (func_info *);
|
||||
static int FMbpad (func_info *);
|
||||
static int FMbstrlen (func_info *);
|
||||
static int FMbsubstr (func_info *);
|
||||
static int FMbupper (func_info *);
|
||||
static int FMin (func_info *);
|
||||
static int FMinsfromutc (func_info *);
|
||||
static int FMinute (func_info *);
|
||||
@@ -320,14 +322,18 @@ 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 },
|
||||
{ "mblower", 1, 1, 1, FMblower, NULL },
|
||||
{ "mbpad", 3, 4, 1, FMbpad, NULL },
|
||||
{ "mbstrlen", 1, 1, 1, FMbstrlen, NULL },
|
||||
{ "mbsubstr", 2, 3, 1, FMbsubstr, NULL },
|
||||
{ "mbupper", 1, 1, 1, FMbupper, NULL },
|
||||
{ "min", 1, NO_MAX, 1, FMin, NULL },
|
||||
{ "minsfromutc", 0, 2, 0, FMinsfromutc, NULL },
|
||||
{ "minute", 1, 1, 1, FMinute, NULL },
|
||||
@@ -448,7 +454,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) {
|
||||
@@ -506,7 +512,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) {
|
||||
@@ -516,9 +521,6 @@ static int FMbstrlen(func_info *info)
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = (int) l;
|
||||
return OK;
|
||||
#else
|
||||
return E_NO_MB;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -656,11 +658,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;
|
||||
@@ -768,7 +770,6 @@ static int FHex(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FCodepoint(func_info *info)
|
||||
{
|
||||
#ifdef REM_USE_WCHAR
|
||||
wchar_t arr[2];
|
||||
size_t len;
|
||||
|
||||
@@ -782,9 +783,6 @@ static int FCodepoint(func_info *info)
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = (int) arr[0];
|
||||
return OK;
|
||||
#else
|
||||
return E_NO_MB;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -843,7 +841,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;
|
||||
@@ -889,9 +886,6 @@ static int FMbchar(func_info *info)
|
||||
RetVal.type = STR_TYPE;
|
||||
RetVal.v.str = s;
|
||||
return OK;
|
||||
#else
|
||||
return E_NO_MB;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1442,6 +1436,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;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -2564,7 +2677,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;
|
||||
@@ -2619,9 +2731,6 @@ static int FMbsubstr(func_info *info)
|
||||
RetVal.v.str = converted;
|
||||
free( (void *) str);
|
||||
return OK;
|
||||
#else
|
||||
return E_NO_MB;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -2671,7 +2780,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;
|
||||
@@ -2724,9 +2832,6 @@ static int FMbindex(func_info *info)
|
||||
free( (void *) haystack);
|
||||
free( (void *) needle);
|
||||
return OK;
|
||||
#else
|
||||
return E_NO_MB;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -3082,6 +3187,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;
|
||||
@@ -3537,7 +3662,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;
|
||||
}
|
||||
|
||||
@@ -4281,7 +4406,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) {
|
||||
@@ -4768,10 +4893,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) {
|
||||
@@ -4798,16 +4926,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));
|
||||
@@ -4835,9 +4961,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.
|
||||
@@ -5054,3 +5177,50 @@ print_builtinfunc_tokens(void)
|
||||
printf("%s\n", Func[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
static int mbupper_lower(func_info *info, int upper)
|
||||
{
|
||||
wchar_t *ws;
|
||||
char *s;
|
||||
size_t i, len;
|
||||
int r;
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
len = mbstowcs(NULL, ARGSTR(0), 0);
|
||||
if (len == (size_t) -1) {
|
||||
return E_BAD_MB_SEQ;
|
||||
}
|
||||
ws = calloc(len+1, sizeof(wchar_t));
|
||||
if (!ws) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
(void) mbstowcs(ws, ARGSTR(0), len+1);
|
||||
for (i=0; i<len; i++) {
|
||||
if (upper) {
|
||||
ws[i] = towupper(ws[i]);
|
||||
} else {
|
||||
ws[i] = towlower(ws[i]);
|
||||
}
|
||||
}
|
||||
len = wcstombs(NULL, ws, 0);
|
||||
s = calloc(len+1, 1);
|
||||
if (!s) {
|
||||
free(ws);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
(void) wcstombs(s, ws, len+1);
|
||||
r = RetStrVal(s, info);
|
||||
free(s);
|
||||
free(ws);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int FMblower(func_info *info)
|
||||
{
|
||||
return mbupper_lower(info, 0);
|
||||
}
|
||||
|
||||
static int FMbupper(func_info *info)
|
||||
{
|
||||
return mbupper_lower(info, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -106,7 +106,7 @@ EXTERN INIT( int DefaultPrio, NO_PRIORITY);
|
||||
EXTERN INIT( int SysTime, -1);
|
||||
EXTERN INIT( int LocalSysTime, -1);
|
||||
EXTERN INIT( int ParseUntriggered, 0);
|
||||
EXTERN INIT( int LinksInTerminal, 0);
|
||||
EXTERN INIT( int Shaded, 0);
|
||||
|
||||
EXTERN char const *InitialFile;
|
||||
EXTERN char const *LocalTimeZone;
|
||||
@@ -128,7 +128,7 @@ EXTERN INIT( int DefaultColorB, -1);
|
||||
EXTERN INIT( int DefaultColorG, -1);
|
||||
EXTERN INIT( int SynthesizeTags, 0);
|
||||
EXTERN INIT( int ScFormat, SC_AMPM);
|
||||
EXTERN INIT( int MaxSatIter, 1000);
|
||||
EXTERN INIT( int MaxSatIter, 10000);
|
||||
EXTERN INIT( int MaxStringLen, MAX_STR_LEN);
|
||||
EXTERN INIT( int UseStdin, 0);
|
||||
EXTERN INIT( int PurgeMode, 0);
|
||||
@@ -147,6 +147,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);
|
||||
@@ -171,6 +172,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, -1);
|
||||
/* 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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
37
src/init.c
37
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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -196,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);
|
||||
@@ -514,13 +514,13 @@ void InitRemind(int argc, char const *argv[])
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
if (*arg == 'c' || *arg == 'C') {
|
||||
UseVTColors = 1;
|
||||
if (*arg == 'z' || *arg == 'Z') {
|
||||
TerminalHyperlinks = 1;
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
if (*arg == 'z' || *arg == 'Z') {
|
||||
LinksInTerminal = 1;
|
||||
if (*arg == 'c' || *arg == 'C') {
|
||||
UseVTColors = 1;
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
@@ -649,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;
|
||||
@@ -659,6 +668,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
case 'D':
|
||||
while (*arg) {
|
||||
switch(*arg++) {
|
||||
case 'p': case 'P': DebugFlag |= DB_PUSHPOP; break;
|
||||
case 's': case 'S': DebugFlag |= DB_PARSE_EXPR; break;
|
||||
case 'h': case 'H': DebugFlag |= DB_HASHSTATS; break;
|
||||
case 'e': case 'E': DebugFlag |= DB_ECHO_LINE; break;
|
||||
@@ -840,6 +850,15 @@ void InitRemind(int argc, char const *argv[])
|
||||
(void) CalcMinsFromUTC(DSEToday, MinutesPastMidnight(0),
|
||||
&MinsFromUTC, NULL);
|
||||
}
|
||||
|
||||
/* If stdout is a tty, enable terminal hyperlinks by default */
|
||||
if (TerminalHyperlinks == -1) {
|
||||
if (isatty(STDOUT_FILENO)) {
|
||||
TerminalHyperlinks = 1;
|
||||
} else {
|
||||
TerminalHyperlinks = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -852,7 +871,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
|
||||
|
||||
46
src/main.c
46
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();
|
||||
|
||||
@@ -292,6 +295,7 @@ PerIterationInit(void)
|
||||
DefaultColorG = -1;
|
||||
DefaultColorB = -1;
|
||||
NumTriggered = 0;
|
||||
Shaded = 0;
|
||||
JSONLinesEmitted = 0;
|
||||
ClearLastTriggers();
|
||||
ClearDedupeTable();
|
||||
@@ -1385,6 +1389,12 @@ static int DoDebug(ParsePtr p)
|
||||
val = 0;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
case 'P':
|
||||
if (val) DebugFlag |= DB_PUSHPOP;
|
||||
else DebugFlag &= ~DB_PUSHPOP;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
if (val) DebugFlag |= DB_ECHO_LINE;
|
||||
@@ -1518,11 +1528,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 +1560,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 +1740,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 +1857,7 @@ FillParagraphWC(char const *s, DynamicBuffer *output)
|
||||
free(buf);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FillParagraph */
|
||||
@@ -1864,7 +1873,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 +1890,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 +1913,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 +1950,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 +2142,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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -176,8 +176,10 @@ int PopOmitContext(ParsePtr p)
|
||||
/* Remove the context from the stack */
|
||||
SavedOmitContexts = c->next;
|
||||
|
||||
if (c->filename && fname && strcmp(c->filename, fname)) {
|
||||
Wprint(tr("POP-OMIT-CONTEXT at %s:%d matches PUSH-OMIT-CONTEXT in different file: %s:%d"), fname, LineNo, c->filename, c->lineno);
|
||||
if (DebugFlag & DB_PUSHPOP) {
|
||||
if (c->filename && fname && strcmp(c->filename, fname)) {
|
||||
Wprint(tr("POP-OMIT-CONTEXT at %s:%d matches PUSH-OMIT-CONTEXT in different file: %s:%d"), fname, LineNo, c->filename, c->lineno);
|
||||
}
|
||||
}
|
||||
/* Free memory used by the saved context */
|
||||
if (c->partsave) free(c->partsave);
|
||||
|
||||
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)));
|
||||
|
||||
61
src/rem2ps.c
61
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");
|
||||
}
|
||||
}
|
||||
@@ -1003,6 +985,14 @@ static void Init(int argc, char const *argv[])
|
||||
|
||||
case 'e': FillPage = 1; break;
|
||||
|
||||
case '-':
|
||||
if (!strcmp(s, "version")) {
|
||||
printf("rem2ps version %s\n", VERSION);
|
||||
exit(0);
|
||||
}
|
||||
Usage("Unrecognized option");
|
||||
break;
|
||||
|
||||
default: Usage("Unrecognized option");
|
||||
}
|
||||
}
|
||||
@@ -1034,6 +1024,7 @@ void Usage(char const *s)
|
||||
fprintf(stderr, "-e Make calendar fill entire page\n");
|
||||
fprintf(stderr, "-x Put day numbers on left instead of right\n");
|
||||
fprintf(stderr, "-o[lrtb] marg Specify left, right, top and bottom margins\n");
|
||||
fprintf(stderr, "--version Print the version of rem2ps and exit\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
27
src/types.h
27
src/types.h
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -221,18 +221,19 @@ typedef Parser *ParsePtr; /* Pointer to parser structure */
|
||||
#define NO_MAX 127
|
||||
|
||||
/* DEFINES for debugging flags */
|
||||
#define DB_PRTLINE 0x001
|
||||
#define DB_PRTEXPR 0x002
|
||||
#define DB_PRTTRIG 0x004
|
||||
#define DB_DUMP_VARS 0x008
|
||||
#define DB_ECHO_LINE 0x010
|
||||
#define DB_TRACE_FILES 0x020
|
||||
#define DB_PARSE_EXPR 0x040
|
||||
#define DB_HASHSTATS 0x080
|
||||
#define DB_TRANSLATE 0x100
|
||||
#define DB_NONCONST 0x200
|
||||
#define DB_UNUSED_VARS 0x400
|
||||
#define DB_SWITCH_ZONE 0x800
|
||||
#define DB_PRTLINE 0x0001
|
||||
#define DB_PRTEXPR 0x0002
|
||||
#define DB_PRTTRIG 0x0004
|
||||
#define DB_DUMP_VARS 0x0008
|
||||
#define DB_ECHO_LINE 0x0010
|
||||
#define DB_TRACE_FILES 0x0020
|
||||
#define DB_PARSE_EXPR 0x0040
|
||||
#define DB_HASHSTATS 0x0080
|
||||
#define DB_TRANSLATE 0x0100
|
||||
#define DB_NONCONST 0x0200
|
||||
#define DB_UNUSED_VARS 0x0400
|
||||
#define DB_SWITCH_ZONE 0x0800
|
||||
#define DB_PUSHPOP 0x1000
|
||||
|
||||
/* Enumeration of the tokens */
|
||||
enum TokTypes
|
||||
|
||||
@@ -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;
|
||||
@@ -744,8 +744,10 @@ int PopUserFuncs(ParsePtr p)
|
||||
return E_POPF_NO_PUSH;
|
||||
}
|
||||
UserFuncStack = UserFuncStack->next;
|
||||
if (strcmp(pf->filename, GetCurrentFilename())) {
|
||||
Wprint(tr("POP-FUNCS at %s:%d matches PUSH-FUNCS in different file: %s:%d"), GetCurrentFilename(), LineNo, pf->filename, pf->lineno);
|
||||
if (DebugFlag & DB_PUSHPOP) {
|
||||
if (strcmp(pf->filename, GetCurrentFilename())) {
|
||||
Wprint(tr("POP-FUNCS at %s:%d matches PUSH-FUNCS in different file: %s:%d"), GetCurrentFilename(), LineNo, pf->filename, pf->lineno);
|
||||
}
|
||||
}
|
||||
for (i=0; i<pf->num_funcs; i++) {
|
||||
UserFunc *clone = pf->funcs[i];
|
||||
|
||||
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 */
|
||||
|
||||
67
src/var.c
67
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
|
||||
@@ -172,7 +172,7 @@ static int latitude_longitude_func(int do_set, Value *val, double *var, double m
|
||||
} else {
|
||||
if (val->type != STR_TYPE) return E_BAD_TYPE;
|
||||
x = strtod_in_c_locale(val->v.str, &endptr);
|
||||
if (*endptr) return E_BAD_TYPE;
|
||||
if (*endptr) return E_BAD_VAL_FOR_SYSVAR;
|
||||
}
|
||||
if (x < min) return E_2LOW;
|
||||
if (x > max) return E_2HIGH;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -461,7 +466,7 @@ static int datetime_sep_func(int do_set, Value *val)
|
||||
if (val->type != STR_TYPE) return E_BAD_TYPE;
|
||||
if (strcmp(val->v.str, "T") &&
|
||||
strcmp(val->v.str, "@")) {
|
||||
return E_BAD_TYPE;
|
||||
return E_BAD_VAL_FOR_SYSVAR;
|
||||
}
|
||||
DateTimeSep = val->v.str[0];
|
||||
return OK;
|
||||
@@ -507,7 +512,7 @@ static int default_color_func(int do_set, Value *val)
|
||||
}
|
||||
if (val->type != STR_TYPE) return E_BAD_TYPE;
|
||||
if (sscanf(val->v.str, "%d %d %d", &col_r, &col_g, &col_b) != 3) {
|
||||
return E_BAD_TYPE;
|
||||
return E_BAD_VAL_FOR_SYSVAR;
|
||||
}
|
||||
/* They either all have to be -1, or all between 0 and 255 */
|
||||
if (col_r == -1 && col_g == -1 && col_b == -1) {
|
||||
@@ -542,7 +547,7 @@ static int date_sep_func(int do_set, Value *val)
|
||||
if (val->type != STR_TYPE) return E_BAD_TYPE;
|
||||
if (strcmp(val->v.str, "/") &&
|
||||
strcmp(val->v.str, "-")) {
|
||||
return E_BAD_TYPE;
|
||||
return E_BAD_VAL_FOR_SYSVAR;
|
||||
}
|
||||
DateSep = val->v.str[0];
|
||||
return OK;
|
||||
@@ -561,7 +566,7 @@ static int time_sep_func(int do_set, Value *val)
|
||||
if (val->type != STR_TYPE) return E_BAD_TYPE;
|
||||
if (strcmp(val->v.str, ":") &&
|
||||
strcmp(val->v.str, ".")) {
|
||||
return E_BAD_TYPE;
|
||||
return E_BAD_VAL_FOR_SYSVAR;
|
||||
}
|
||||
TimeSep = val->v.str[0];
|
||||
return OK;
|
||||
@@ -1096,6 +1101,7 @@ static SysVar SysVarArr[] = {
|
||||
{"RunOff", 0, INT_TYPE, &RunDisabled, 0, 0 },
|
||||
{"Saturday", 1, TRANS_TYPE, "Saturday", 0, 0 },
|
||||
{"September", 1, TRANS_TYPE, "September", 0, 0 },
|
||||
{"Shaded" , 0, INT_TYPE, &Shaded, 0, 0 },
|
||||
{"SimpleCal", 0, INT_TYPE, &DoSimpleCalendar, 0, 0 },
|
||||
{"SortByDate", 0, INT_TYPE, &SortByDate, 0, 0 },
|
||||
{"SortByPrio", 0, INT_TYPE, &SortByPrio, 0, 0 },
|
||||
@@ -1109,6 +1115,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 },
|
||||
@@ -1337,8 +1344,10 @@ PopVars(ParsePtr p)
|
||||
return E_POPV_NO_PUSH;
|
||||
}
|
||||
VarStack = VarStack->next;
|
||||
if (strcmp(pv->filename, GetCurrentFilename())) {
|
||||
Wprint(tr("POP-VARS at %s:%d matches PUSH-VARS in different file: %s:%d"), GetCurrentFilename(), LineNo, pv->filename, pv->lineno);
|
||||
if (DebugFlag & DB_PUSHPOP) {
|
||||
if (strcmp(pv->filename, GetCurrentFilename())) {
|
||||
Wprint(tr("POP-VARS at %s:%d matches PUSH-VARS in different file: %s:%d"), GetCurrentFilename(), LineNo, pv->filename, pv->lineno);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pop the sysvars */
|
||||
@@ -1397,9 +1406,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 +1500,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 +1533,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;
|
||||
|
||||
@@ -76,10 +76,12 @@ COLOUR
|
||||
CONTEXTs
|
||||
CPAN
|
||||
CPP's
|
||||
CPUs
|
||||
CalMode
|
||||
CalType
|
||||
CalcMinsFromUTC
|
||||
CalcUTC
|
||||
Chanukah
|
||||
Clément
|
||||
Config
|
||||
Conover
|
||||
@@ -159,6 +161,7 @@ FreeBSD
|
||||
Fromnow
|
||||
GPL
|
||||
Gedalia
|
||||
Georg
|
||||
Getopt
|
||||
GhostView
|
||||
Gurman
|
||||
@@ -211,6 +214,7 @@ Joop
|
||||
Kamens
|
||||
Kasdorp
|
||||
Katan
|
||||
Kheshvan
|
||||
Kiefte
|
||||
Koningsdag
|
||||
Kristian
|
||||
@@ -253,6 +257,7 @@ Makefiles
|
||||
Marczykowski
|
||||
Marek
|
||||
Marinus
|
||||
Matariki
|
||||
MaxFullOmits
|
||||
MaxLateMinutes
|
||||
MaxPartialOmits
|
||||
@@ -401,9 +406,11 @@ Tcl
|
||||
Td
|
||||
Terbeck
|
||||
TerminalBackground
|
||||
TerminalHyperlinks
|
||||
Thronicke
|
||||
TimeSep
|
||||
TimetIs64bit
|
||||
Tishrei
|
||||
Tishrey
|
||||
TitleSize
|
||||
Tk
|
||||
@@ -537,6 +544,7 @@ difftime
|
||||
doesn
|
||||
dosubst
|
||||
doublequote
|
||||
dp
|
||||
dq
|
||||
dqi
|
||||
dqis
|
||||
@@ -640,6 +648,7 @@ itkpdf
|
||||
itkprint
|
||||
itkremind
|
||||
ivar
|
||||
ivritmon
|
||||
j2
|
||||
jahr
|
||||
jahrzeit
|
||||
@@ -680,8 +689,12 @@ maxlen
|
||||
maybexs
|
||||
mbchar
|
||||
mbindex
|
||||
mblower
|
||||
mbpad
|
||||
mbstowcs
|
||||
mbstrlen
|
||||
mbsubstr
|
||||
mbupper
|
||||
md
|
||||
memcpy
|
||||
messageBox
|
||||
@@ -745,6 +758,7 @@ noto
|
||||
nqueued
|
||||
nroff
|
||||
num
|
||||
nz
|
||||
ok
|
||||
oktober
|
||||
ol
|
||||
@@ -773,6 +787,7 @@ popen
|
||||
pp12
|
||||
pp3
|
||||
ppp
|
||||
ppp12
|
||||
pre
|
||||
preprocessor
|
||||
prev
|
||||
@@ -827,6 +842,7 @@ soleq
|
||||
somefile
|
||||
sortbanner
|
||||
spc
|
||||
spc2
|
||||
spellintian
|
||||
src
|
||||
srczone
|
||||
@@ -947,6 +963,8 @@ varname
|
||||
ve
|
||||
w0
|
||||
wakeups
|
||||
wchar
|
||||
wcstombs
|
||||
weekno
|
||||
wfun
|
||||
whoami
|
||||
@@ -967,6 +985,7 @@ xsiz
|
||||
xsiz1
|
||||
y1
|
||||
y2
|
||||
yaag
|
||||
year1
|
||||
year2
|
||||
yeardiff
|
||||
@@ -981,3 +1000,21 @@ ziens
|
||||
zj
|
||||
zn
|
||||
één
|
||||
π
|
||||
א
|
||||
אב
|
||||
אדר
|
||||
אדר
|
||||
אדר
|
||||
אייר
|
||||
אלול
|
||||
ב
|
||||
חשוון
|
||||
טבת
|
||||
כסלו
|
||||
ניסן
|
||||
ניסן
|
||||
סיון
|
||||
שבט
|
||||
תמוז
|
||||
תשרי
|
||||
|
||||
15
tests/shaded.rem
Normal file
15
tests/shaded.rem
Normal file
@@ -0,0 +1,15 @@
|
||||
REM Wed SPECIAL SHADE 255 0 0
|
||||
IF !$Shaded
|
||||
REM 15 SPECIAL SHADE 0 255 0
|
||||
ENDIF
|
||||
IF !$Shaded
|
||||
REM SATISFY [$Td % 4 == 0] SPECIAL SHADE 0 0 255
|
||||
ENDIF
|
||||
|
||||
IF !$Shaded
|
||||
REM Sunday SPECIAL SHADE 0 255 255
|
||||
ENDIF
|
||||
|
||||
IF !$Shaded
|
||||
REM SPECIAL SHADE 255 255 0
|
||||
ENDIF
|
||||
4
tests/test-pushpop1.rem
Normal file
4
tests/test-pushpop1.rem
Normal file
@@ -0,0 +1,4 @@
|
||||
PUSH-OMIT-CONTEXT
|
||||
PUSH-FUNCS a b c
|
||||
PUSH-VARS a b c
|
||||
DO test-pushpop2.rem
|
||||
4
tests/test-pushpop2.rem
Normal file
4
tests/test-pushpop2.rem
Normal file
@@ -0,0 +1,4 @@
|
||||
POP-VARS
|
||||
POP-FUNCS
|
||||
POP-OMIT-CONTEXT
|
||||
|
||||
@@ -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
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -35,10 +35,13 @@ 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
|
||||
@@ -69,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
|
||||
@@ -471,8 +455,8 @@ $REMIND -c ../tests/test-addomit.rem 1 Sep 2021 >> $OUT
|
||||
$REMIND -cu ../tests/utf-8.rem 1 Nov 2019 >> $OUT
|
||||
$REMIND -cu '-i$SuppressLRM=1' ../tests/utf-8.rem 1 Nov 2019 >> $OUT
|
||||
|
||||
TZ=America/Toronto $REMIND -dxe ../tests/tz.rem >> $OUT 2>&1
|
||||
TZ=Europe/Berlin $REMIND -dxe ../tests/tz.rem >> $OUT 2>&1
|
||||
TZ=America/Toronto $REMIND -dxe ../tests/tz.rem 2026-02-01 >> $OUT 2>&1
|
||||
TZ=Europe/Berlin $REMIND -dxe ../tests/tz.rem 2026-02-01 >> $OUT 2>&1
|
||||
|
||||
$REMIND ../tests/soleq.rem 1 April 2044 >> $OUT 2>&1
|
||||
|
||||
@@ -495,18 +479,18 @@ echo "REM May 22 +10 MSG Bar %b" | $REMIND -tz - 2023-05-21 >> $OUT 2>&1
|
||||
rm -rf include_dir/ww
|
||||
touch include_dir/ww
|
||||
chmod 0666 include_dir/ww
|
||||
$REMIND include_dir/ww >> $OUT 2>&1
|
||||
$REMIND include_dir/ww 2026-02-01 >> $OUT 2>&1
|
||||
rm -rf include_dir/ww
|
||||
|
||||
# World-writable directory
|
||||
mkdir -p include_dir/ww
|
||||
touch include_dir/ww/0.rem
|
||||
chmod 0777 include_dir/ww
|
||||
$REMIND include_dir/ww >> $OUT 2>&1
|
||||
$REMIND include_dir/ww 2026-02-01 >> $OUT 2>&1
|
||||
rm -rf include_dir/ww
|
||||
|
||||
# This segfaulted in 04.02.03
|
||||
$REMIND -h '-imsgprefix(x)="foo"' /dev/null >> $OUT 2>&1
|
||||
$REMIND -h '-imsgprefix(x)="foo"' /dev/null 2026-02-01 >> $OUT 2>&1
|
||||
|
||||
# Test --version long option
|
||||
$REMIND --version >> $OUT 2>&1
|
||||
@@ -601,19 +585,19 @@ EOF
|
||||
|
||||
(echo 'BANNER %'; echo 'REM 29 MSG No bug') | $REMIND -dt - 29 Feb 2024 >> $OUT 2>&1
|
||||
|
||||
$REMIND -ifoo - <<'EOF' >> $OUT 2>&1
|
||||
$REMIND -ifoo - 2026-02-01 <<'EOF' >> $OUT 2>&1
|
||||
BANNER %
|
||||
DUMP
|
||||
EOF
|
||||
|
||||
$REMIND '-i$AddBlankLines' - <<'EOF' >> $OUT 2>&1
|
||||
$REMIND '-i$AddBlankLines' - 2026-02-01 <<'EOF' >> $OUT 2>&1
|
||||
BANNER %
|
||||
DUMP $AddBlankLines
|
||||
EOF
|
||||
|
||||
$REMIND ../tests/expr.rem >> $OUT 2>&1
|
||||
$REMIND ../tests/expr.rem 2026-02-01 >> $OUT 2>&1
|
||||
|
||||
$REMIND - <<'EOF' >> $OUT 2>&1
|
||||
$REMIND - 2026-02-01 <<'EOF' >> $OUT 2>&1
|
||||
PUSH
|
||||
POP
|
||||
PUSH
|
||||
@@ -697,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
|
||||
@@ -716,7 +709,7 @@ echo "" >> $OUT
|
||||
$REMIND --print-tokens < /dev/null >> $OUT 2>&1
|
||||
|
||||
# Torture test #2
|
||||
$REMIND ../tests/torture2.rem >> $OUT 2>&1
|
||||
$REMIND ../tests/torture2.rem 2026-02-01 >> $OUT 2>&1
|
||||
|
||||
# Expression error-reporting
|
||||
$REMIND -de - 1 Feb 2024 <<'EOF' >> $OUT 2>&1
|
||||
@@ -817,10 +810,10 @@ REM Wed MSG Wookie
|
||||
EOF
|
||||
|
||||
# Test year-folding
|
||||
TZ=America/Toronto $REMIND -dx ../tests/yearfold.rem >> $OUT 2>&1
|
||||
TZ=America/Toronto $REMIND -dx ../tests/yearfold.rem 2026-02-01 >> $OUT 2>&1
|
||||
|
||||
# Test unused-variable debugging
|
||||
$REMIND -du - <<'EOF' >> $OUT 2>&1
|
||||
$REMIND -du - 2026-02-01 <<'EOF' >> $OUT 2>&1
|
||||
set a 1
|
||||
set b a*2
|
||||
set c "What"
|
||||
@@ -968,6 +961,39 @@ 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
|
||||
|
||||
# Test the $Shaded system variable
|
||||
$REMIND -pp ../tests/shaded.rem 2026-02-01 >> $OUT 2>&1
|
||||
|
||||
# Test the push/pop warnings
|
||||
$REMIND ../tests/test-pushpop1.rem 2026-01-01 >> $OUT 2>&1
|
||||
$REMIND -dp ../tests/test-pushpop1.rem 2026-01-01 >> $OUT 2>&1
|
||||
|
||||
cmp -s $OUT $CMP
|
||||
if [ "$?" = "0" ]; then
|
||||
echo "Remind: Acceptance tests ${GRN}PASSED${NRM}"
|
||||
|
||||
311
tests/test.cmp
311
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.02.01"
|
||||
version() => "06.02.05"
|
||||
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.02.01"
|
||||
a058 "06.02.05"
|
||||
a059 "Saturday"
|
||||
a010 12
|
||||
a060 6
|
||||
@@ -5563,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.02.01"
|
||||
"06.02.01" > "01.00.00" => 1
|
||||
version() => "06.02.05"
|
||||
"06.02.05" > "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...
|
||||
@@ -16657,6 +16657,121 @@ mbchar(0, 120) => Number too low
|
||||
../tests/test.rem(1767): mbchar(): Number too low
|
||||
mbchar(120, 0) => 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;;\../tests/test.rem(1900): Invalid value for system variable
|
||||
../tests/test.rem(1901): Invalid value for system variable
|
||||
../tests/test.rem(1902): Invalid value for system variable
|
||||
../tests/test.rem(1903): Invalid value for system variable
|
||||
../tests/test.rem(1904): Invalid value for system variable
|
||||
mbupper("öÖçÇéôñÑÉÊ") => "ÖÖÇÇÉÔÑÑÉÊ"
|
||||
mblower("öÖçÇéôñÑÉÊ") => "ööççéôññéê"
|
||||
upper("öÖçÇéôñÑÉÊ") => "öÖçÇéôñÑÉÊ"
|
||||
lower("öÖçÇéôñÑÉÊ") => "öÖçÇéôñÑÉÊ"
|
||||
DynBuf Mallocs: 1132 mallocs; 31873408 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
|
||||
@@ -16678,7 +16793,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: 106471
|
||||
Total expression node evaluations: 106746
|
||||
|
||||
Test 2
|
||||
|
||||
@@ -20657,7 +20772,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
|
||||
@@ -21761,7 +21876,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
|
||||
@@ -23716,7 +23831,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.02.01
|
||||
06.02.05
|
||||
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
|
||||
@@ -24274,6 +24389,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
|
||||
@@ -24488,6 +24604,7 @@ cal
|
||||
clear
|
||||
clear-omit-context
|
||||
complete-through
|
||||
completed-through
|
||||
debug
|
||||
do
|
||||
dump
|
||||
@@ -24656,14 +24773,18 @@ isconst
|
||||
isdst
|
||||
isleap
|
||||
isomitted
|
||||
ivritmon
|
||||
language
|
||||
localtoutc
|
||||
lower
|
||||
max
|
||||
mbchar
|
||||
mbindex
|
||||
mblower
|
||||
mbpad
|
||||
mbstrlen
|
||||
mbsubstr
|
||||
mbupper
|
||||
min
|
||||
minsfromutc
|
||||
minute
|
||||
@@ -24830,6 +24951,7 @@ $PSCal
|
||||
$RunOff
|
||||
$Saturday
|
||||
$September
|
||||
$Shaded
|
||||
$SimpleCal
|
||||
$SortByDate
|
||||
$SortByPrio
|
||||
@@ -24843,6 +24965,7 @@ $T
|
||||
$Tb
|
||||
$Td
|
||||
$TerminalBackground
|
||||
$TerminalHyperlinks
|
||||
$Thursday
|
||||
$TimeSep
|
||||
$TimetIs64bit
|
||||
@@ -24869,6 +24992,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
|
||||
@@ -25071,11 +25195,11 @@ 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)" ""
|
||||
TRANSLATE "Invalid value for system variable" ""
|
||||
|
||||
# Other Messages
|
||||
TRANSLATE "%s function `%s' defined at %s(%s) does not use its argument" ""
|
||||
@@ -39670,6 +39794,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
|
||||
@@ -39685,6 +39817,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
|
||||
@@ -39696,10 +39835,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
|
||||
|
||||
@@ -39707,6 +39854,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
|
||||
@@ -39714,26 +39865,41 @@ 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
|
||||
[
|
||||
{"date":"2025-08-01","filename":"../tests/todos.rem","lineno":4,"d":1,"m":8,"y":2025,"is_todo":1,"trigbase":"2025-08-1 ","priority":5000,"body":"First on 2025-08-01"},
|
||||
{"date":"2025-08-01","filename":"../tests/todos.rem","lineno":4,"d":1,"m":8,"y":2025,"is_todo":1,"trigbase":"2025-08-01","priority":5000,"body":"First on 2025-08-01"},
|
||||
{"date":"2022-08-01","filename":"../tests/todos.rem","lineno":5,"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":6,"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":7,"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":8,"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":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-06","filename":"../tests/todos.rem","lineno":9,"d":6,"m":8,"y":2025,"is_todo":1,"delta":7,"trigbase":"2025-08-06","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-01","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-06","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
|
||||
[
|
||||
@@ -39857,6 +40023,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
|
||||
@@ -39882,6 +40049,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
|
||||
@@ -39939,9 +40107,9 @@ devnull test b
|
||||
No reminders.
|
||||
[
|
||||
{"banner":"Reminders for Wednesday, 1st October, 2025:"},
|
||||
{"date":"2025-10-01","filename":"-stdin-","lineno":3,"d":1,"m":10,"y":2025,"is_todo":0,"trigbase":"2025-10-1 ","priority":5000,"body":"Nonconst NOT set 2025-10-01"},
|
||||
{"date":"2025-10-01","filename":"-stdin-","lineno":4,"nonconst_expr":1,"d":1,"m":10,"y":2025,"is_todo":0,"trigbase":"2025-10-1 ","priority":5000,"body":"Nonconst IS set 2025-10-01"},
|
||||
{"date":"2025-10-01","filename":"-stdin-","lineno":5,"nonconst_expr":1,"d":1,"m":10,"y":2025,"is_todo":0,"trigbase":"2025-10-1 ","priority":5000,"body":"Nonconst IS set"}
|
||||
{"date":"2025-10-01","filename":"-stdin-","lineno":3,"d":1,"m":10,"y":2025,"is_todo":0,"trigbase":"2025-10-01","priority":5000,"body":"Nonconst NOT set 2025-10-01"},
|
||||
{"date":"2025-10-01","filename":"-stdin-","lineno":4,"nonconst_expr":1,"d":1,"m":10,"y":2025,"is_todo":0,"trigbase":"2025-10-01","priority":5000,"body":"Nonconst IS set 2025-10-01"},
|
||||
{"date":"2025-10-01","filename":"-stdin-","lineno":5,"nonconst_expr":1,"d":1,"m":10,"y":2025,"is_todo":0,"trigbase":"2025-10-01","priority":5000,"body":"Nonconst IS set"}
|
||||
]
|
||||
# Nonconst-expr in trigger
|
||||
set $ParseUntriggered 1
|
||||
@@ -40003,3 +40171,110 @@ February 28
|
||||
-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 ‎ | |
|
||||
+----------+----------+----------+----------+----------+----------+----------+
|
||||
# translations
|
||||
{"LANGID":"en"}
|
||||
# rem2ps2 begin
|
||||
February 2026 28 0 0
|
||||
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
|
||||
January 31
|
||||
March 31
|
||||
{"date":"2026-02-01","filename":"../tests/shaded.rem","lineno":10,"passthru":"SHADE","wd":["Sunday"],"is_todo":0,"priority":5000,"if_depth":1,"r":0,"g":255,"b":255,"body":"0 255 255"}
|
||||
{"date":"2026-02-02","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-03","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-04","filename":"../tests/shaded.rem","lineno":1,"passthru":"SHADE","wd":["Wednesday"],"is_todo":0,"priority":5000,"r":255,"g":0,"b":0,"body":"255 0 0"}
|
||||
{"date":"2026-02-05","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-06","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-07","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-08","filename":"../tests/shaded.rem","lineno":6,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":0,"g":0,"b":255,"body":"0 0 255"}
|
||||
{"date":"2026-02-09","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-10","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-11","filename":"../tests/shaded.rem","lineno":1,"passthru":"SHADE","wd":["Wednesday"],"is_todo":0,"priority":5000,"r":255,"g":0,"b":0,"body":"255 0 0"}
|
||||
{"date":"2026-02-12","filename":"../tests/shaded.rem","lineno":6,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":0,"g":0,"b":255,"body":"0 0 255"}
|
||||
{"date":"2026-02-13","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-14","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-15","filename":"../tests/shaded.rem","lineno":3,"passthru":"SHADE","d":15,"is_todo":0,"priority":5000,"if_depth":1,"r":0,"g":255,"b":0,"body":"0 255 0"}
|
||||
{"date":"2026-02-16","filename":"../tests/shaded.rem","lineno":6,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":0,"g":0,"b":255,"body":"0 0 255"}
|
||||
{"date":"2026-02-17","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-18","filename":"../tests/shaded.rem","lineno":1,"passthru":"SHADE","wd":["Wednesday"],"is_todo":0,"priority":5000,"r":255,"g":0,"b":0,"body":"255 0 0"}
|
||||
{"date":"2026-02-19","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-20","filename":"../tests/shaded.rem","lineno":6,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":0,"g":0,"b":255,"body":"0 0 255"}
|
||||
{"date":"2026-02-21","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-22","filename":"../tests/shaded.rem","lineno":10,"passthru":"SHADE","wd":["Sunday"],"is_todo":0,"priority":5000,"if_depth":1,"r":0,"g":255,"b":255,"body":"0 255 255"}
|
||||
{"date":"2026-02-23","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-24","filename":"../tests/shaded.rem","lineno":6,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":0,"g":0,"b":255,"body":"0 0 255"}
|
||||
{"date":"2026-02-25","filename":"../tests/shaded.rem","lineno":1,"passthru":"SHADE","wd":["Wednesday"],"is_todo":0,"priority":5000,"r":255,"g":0,"b":0,"body":"255 0 0"}
|
||||
{"date":"2026-02-26","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-27","filename":"../tests/shaded.rem","lineno":14,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":255,"g":255,"b":0,"body":"255 255 0"}
|
||||
{"date":"2026-02-28","filename":"../tests/shaded.rem","lineno":6,"passthru":"SHADE","is_todo":0,"priority":5000,"if_depth":1,"r":0,"g":0,"b":255,"body":"0 0 255"}
|
||||
# rem2ps2 end
|
||||
No reminders.
|
||||
../tests/test-pushpop2.rem(1): POP-VARS at ../tests/test-pushpop2.rem:1 matches PUSH-VARS in different file: ../tests/test-pushpop1.rem:3
|
||||
../tests/test-pushpop2.rem(2): POP-FUNCS at ../tests/test-pushpop2.rem:2 matches PUSH-FUNCS in different file: ../tests/test-pushpop1.rem:2
|
||||
../tests/test-pushpop2.rem(3): POP-OMIT-CONTEXT at ../tests/test-pushpop2.rem:3 matches PUSH-OMIT-CONTEXT in different file: ../tests/test-pushpop1.rem:1
|
||||
No reminders.
|
||||
|
||||
141
tests/test.rem
141
tests/test.rem
@@ -1769,7 +1769,148 @@ 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!
|
||||
|
||||
# Bad values for system variables
|
||||
SET $Latitude "Cabbage"
|
||||
SET $Longitude "Carrots"
|
||||
SET $TimeSep "FOO"
|
||||
SET $DateSep "BAR"
|
||||
SET $DefaultColor "My oh my, what lovely eyes!"
|
||||
|
||||
# mbupper and mblower
|
||||
DEBUG +x
|
||||
SET a mbupper("öÖçÇéôñÑÉÊ")
|
||||
SET a mblower("öÖçÇéôñÑÉÊ")
|
||||
SET a upper("öÖçÇéôñÑÉÊ")
|
||||
SET a lower("öÖçÇéôñÑÉÊ")
|
||||
DEBUG -x
|
||||
|
||||
# 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
|
||||
#
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user