Compare commits

...

102 Commits

Author SHA1 Message Date
Dianne Skoll
9fee354e6c Update release notes. 2023-03-15 18:46:30 -04:00
Dianne Skoll
ec76554d41 Treat a null -k option as no -k option 2023-03-15 09:22:44 -04:00
Dianne Skoll
ddb0817c99 Make an empty -k option the same as no -k option. 2023-03-15 09:17:02 -04:00
Dianne Skoll
3d6ecd1f72 Prep for 04.02.04 release. 2023-03-14 12:03:00 -04:00
Dianne Skoll
e3ec6565e9 Add support for -k: option --- applies command only to *queued* reminders. 2023-03-13 15:16:24 -04:00
Dianne Skoll
8ed49ead7f Document that SPECIAL [type] means the same thing as [type] for type in MSG, MSF, RUN, CAL, PS and PSFILE. 2023-03-12 18:51:41 -04:00
Dianne Skoll
49fbca416f Fix typo 2023-03-08 16:06:33 -05:00
Dianne Skoll
82cd438fff Use -y as shorthand for --wrap. 2023-03-08 14:27:43 -05:00
Dianne Skoll
946e1bca38 Update help text to include --wrap, -x option. 2023-03-08 14:14:53 -05:00
Dianne Skoll
e40c81b5bf Add the "--wrap, -x" command-line parameter to rem2pdf
This "wraps" calendars that would normally require 6 rows so they only
require 5.  It does this by putting the last day or two in the *first*
row rather than the last.
2023-03-08 13:39:49 -05:00
Dianne Skoll
f23418480d Set up explict (row, col) -> Day mapping
This will make it easier to eventually implement a calendar-wrapping
feature that will avoid ever having to use 6 rows to display the
calendar.
2023-03-08 10:42:15 -05:00
Dianne Skoll
bb4df39c50 Add note to defs.rem about US holidays. 2023-03-08 09:25:29 -05:00
Dianne Skoll
5fec775863 Better DST rules. 2023-03-07 18:34:53 -05:00
Dianne Skoll
a85980fec2 Add rules for moving US federal holidays if they fall on a weekend. 2023-03-07 18:31:58 -05:00
Dianne Skoll
f3ea2962e6 Remove unused function definition. 2023-03-07 16:40:53 -05:00
Dianne Skoll
3a5af23ab6 Fix Thanksgiving definition. 2023-03-07 16:37:17 -05:00
Dianne Skoll
f9656edc51 Make "SPECIAL MSG" the same as "MSG" and same for MSF, RUN, PS and PSFILE
This lets us use variables to set the type of a REM command:

     SET t "MSG"
     REM SPECIAL [t] A message
     SET t "CAL"
     REM SPECIAL [t] A calendar message
     SET t "RUN"
     REM SPECIAL [t] /bin/some_cmd
2023-03-03 11:53:45 -05:00
Dianne Skoll
5134b47d47 Oops! Fix up broken tests. 2023-03-02 11:42:54 -05:00
Dianne Skoll
d4a183f3bf Add htmlstriptags function. 2023-03-02 11:40:03 -05:00
Dianne Skoll
87e392de6c Check for E_NOMEM conditions. 2023-03-02 09:43:56 -05:00
Dianne Skoll
afc1667e64 Implement htmlescape() built-in function. 2023-03-02 09:39:14 -05:00
Dianne Skoll
8d25270c43 Fix syntax of TkRemind command-line per Ian! D. Allen. 2023-03-02 08:39:14 -05:00
Dianne Skoll
929866a770 Use ^A as the split character rather than \ 2023-02-27 12:13:19 -05:00
Dianne Skoll
395bad96a7 Don't barf if -underlinefg is not available; don't lose whitespace in MOON message. 2023-02-27 10:40:59 -05:00
Dianne Skoll
cd7be006c9 Set timezone for tests so moon phases show up on predictable days. 2023-02-23 08:32:24 -05:00
Dianne Skoll
f658ba7ee7 Fix typo, pointed out by @jochensp 2023-02-22 16:18:21 -05:00
Dianne Skoll
7416f4c035 Output a diff of test.out and test.cmp if tests fail, but limit to 200 lines. 2023-02-22 16:04:17 -05:00
Dianne Skoll
2860159ff7 Add test for a fixed bug. 2023-02-22 10:02:18 -05:00
Dianne Skoll
64fa71ab09 Avoid segfault if we define a function on the command-line with -i 2023-02-22 09:57:09 -05:00
Dianne Skoll
ffbba7d4d1 Update WHATSNEW for 04.02.03 release. 2023-02-10 12:57:53 -05:00
Dianne Skoll
fdcc2d8acf Bump version to 04.02.03. 2023-02-09 09:31:28 -05:00
Dianne Skoll
f1aa4d16af Test for v == INT_MIN on entry to FAbs. 2023-02-09 08:51:20 -05:00
Dianne Skoll
a55c5580f3 Silence Perl::Critic warning. 2023-02-07 13:45:38 -05:00
Dianne Skoll
569e315306 Suppress some Perl::Critic warnings. 2023-02-07 13:45:08 -05:00
Dianne Skoll
acd641845d Update WHATSNEW 2023-02-07 13:07:54 -05:00
Dianne Skoll
6b7e6f6788 Another cppcheck cleanup. 2023-02-07 11:20:09 -05:00
Dianne Skoll
4248b9c624 Add "cppcheck" Makefile target. 2023-02-07 11:16:29 -05:00
Dianne Skoll
6de98d1357 A few more cppcheck cleanups. 2023-02-07 11:05:16 -05:00
Dianne Skoll
18f21693af Clean up some warnings from cppcheck static analyzer. 2023-02-07 10:28:02 -05:00
Dianne Skoll
6fa500a860 Issue sort-banner correctly for MSF-type reminders. 2023-02-02 14:45:54 -05:00
Dianne Skoll
941c02582e More details on TIME type, courtesy of Ian! D. Allen 2023-01-20 12:58:28 -05:00
Dianne Skoll
e56e3924d9 Clarify DURATION. 2023-01-20 12:33:14 -05:00
Dianne Skoll
d1384a8f69 Add #include <fcntl.h> to funcs.c.
Reported by Zoltan Puskas; see https://bugs.gentoo.org/889318
2023-01-20 08:15:30 -05:00
Dianne Skoll
0488d689aa Update tax day in include/holidays/us.rem 2023-01-19 13:15:50 -05:00
Dianne Skoll
988a94e669 Update WHATSNEW. 2023-01-16 09:23:34 -05:00
Dianne Skoll
ac7e93ac1c Allow REMIND_LANG to override language. 2023-01-15 21:09:54 -05:00
Dianne Skoll
bb7e9ee676 Add Greek holidays and language pack, courtesy of JeiEl <jarlaxl@freemail.gr> 2023-01-15 19:40:39 -05:00
Dianne Skoll
ac949ce7bd Proper definition for US tax day. 2023-01-14 14:26:38 -05:00
Dianne Skoll
0fa8eed11f Correct the US Tax Day calculation, courtesy of Tavis Ormandy 2023-01-14 12:38:25 -05:00
Dianne Skoll
df8694a128 Add orthodoxeaster function. 2023-01-09 15:12:18 -05:00
Dianne Skoll
13df3d96e5 Add JulianToGregorianOffset function. 2023-01-09 14:18:10 -05:00
Dianne Skoll
e345eb15f2 Update verison to 04.02.02 2023-01-01 16:54:23 -05:00
Dianne Skoll
e8b2872a87 Update docs 2023-01-01 16:52:52 -05:00
Dianne Skoll
2f196e3c9f Update copyright year. :) 2022-12-30 13:43:28 -05:00
Dianne Skoll
839b844a10 Correct some comments. 2022-12-26 16:26:07 -05:00
Dianne Skoll
0cea410529 Add a bunch of: "SPDX-License-Identifier: GPL-2.0-only" comments. 2022-12-26 14:24:33 -05:00
Dianne Skoll
90397ece64 Mark soleq as non-constant. 2022-12-26 11:54:24 -05:00
Dianne Skoll
0b95fc290c Tweak. 2022-12-25 10:01:18 -05:00
Dianne Skoll
9a4e8b6070 Better sorting. 2022-12-25 09:37:22 -05:00
Dianne Skoll
924fd16ade More pleaseing alignment. :) 2022-12-23 17:07:54 -05:00
Dianne Skoll
0815fe19cc Align astro output. 2022-12-23 15:43:09 -05:00
Dianne Skoll
7f445e1b66 Add more emojis 2022-12-23 13:56:00 -05:00
Dianne Skoll
31afc60af4 Set latitude and longitude in astro 2022-12-23 13:40:32 -05:00
Dianne Skoll
9d34a8aa42 Set $Latitude in astro 2022-12-23 13:39:19 -05:00
Dianne Skoll
91325ff489 Update "astro" example to include equinoxes and solstices. 2022-12-23 13:28:11 -05:00
Dianne Skoll
1f99d6df59 More docs on NOQUEUE 2022-12-23 13:06:58 -05:00
Dianne Skoll
8a608a06b8 Tweak man page. 2022-12-23 11:51:01 -05:00
Dianne Skoll
bb34474e59 Document return value of soleq() 2022-12-23 11:38:59 -05:00
Dianne Skoll
029c054489 Document soleq() and NOQUEUE. 2022-12-23 11:37:27 -05:00
Dianne Skoll
01400d0672 Test the one-arg form of soleq() 2022-12-23 11:14:49 -05:00
Dianne Skoll
a1eafb2c89 Add NOQUEUE modifier; reverse order of args to soleq and make second arg optional (defaults to today()) 2022-12-23 11:04:18 -05:00
Dianne Skoll
af88e393f9 Reverse oreder of soleq args. 2022-12-23 10:56:13 -05:00
Dianne Skoll
3a250ce765 Don't make tests depend on date they are run. 2022-12-22 22:12:14 -05:00
Dianne Skoll
d651ac40a8 Update comments. 2022-12-22 22:01:54 -05:00
Dianne Skoll
653324e220 Add include/seasons.rem 2022-12-22 21:51:45 -05:00
Dianne Skoll
e5c6703eaa Add function for solstice/equinox calculations. 2022-12-22 21:44:49 -05:00
Dianne Skoll
1596d9c76a Better comments. 2022-12-21 13:41:25 -05:00
Dianne Skoll
4aacf74e25 More renaming of jul -> dse 2022-12-21 13:35:12 -05:00
Dianne Skoll
ae58bc7c11 Better message. 2022-12-21 13:15:05 -05:00
Dianne Skoll
387125d983 Start fixing terminology: Julian becomes DSE
Remind's so-called "Julian" date is not a true Julian date.
It's really the number of days since the Remind Epoch, so rename
to DSE (Days Since Epoch)
2022-12-21 13:14:00 -05:00
Dianne Skoll
aa5f9297b2 Add tests for handling world-writable dirs and files. 2022-12-20 10:38:28 -05:00
Dianne Skoll
8c4a7e766f Don't read world-writable directories 2022-12-20 10:26:47 -05:00
Dianne Skoll
d7f32d3901 Better error indication if something goes wrong in ShowTodaysReminders. 2022-12-20 09:45:16 -05:00
Dianne Skoll
d4f09e2a31 Fix typo 2022-12-15 10:37:28 -05:00
Dianne Skoll
8b5fe4f2a0 Update WHATSNEW for 04.02.01 release. 2022-12-15 09:34:02 -05:00
Dianne Skoll
98fc4a917f Bump version to 04.02.01 2022-12-15 09:24:30 -05:00
Dianne Skoll
e633530a36 Fix stray %" 2022-11-15 08:24:52 -05:00
Dianne Skoll
bfea9915b9 Remove unnecessary %"...%" markers. 2022-11-14 12:37:17 -05:00
Clément Bœsch
d68ed6e75d Add French holidays courtesy of Clément Bœsch 2022-11-14 12:20:43 -05:00
Dianne Skoll
a22631d768 Document need for Noto Fonts in TkRemind. 2022-11-01 13:40:44 -04:00
Dianne Skoll
552bf84e33 Make test *not* depend on the current date... *sigh*. 2022-10-24 09:41:40 -04:00
Dianne Skoll
28d0251093 If we use "-m" in ExtraRemindArgs, set $MondayFirst in tkremind
Patch courtesy of Luís Henriques
2022-10-24 09:35:27 -04:00
Dianne Skoll
f3d969f658 Make sure we print the banner on each iteration of a command-line '*rep' 2022-10-20 18:21:57 -04:00
Dianne Skoll
2afe95d090 Fix typo in comment. 2022-10-18 17:25:59 -04:00
Dianne Skoll
3692a6b265 Avoid ambiguous local<->UTC conversions right around when the clocks change. 2022-10-17 09:58:32 -04:00
Dianne Skoll
8fc19358bb Double-up on "%" in a printf formatting string. 2022-10-17 08:29:38 -04:00
Dianne Skoll
c8f9773d83 Speed up FindFunc. 2022-10-14 13:53:50 -04:00
Dianne Skoll
e1091db82f Don't try to use -ffat-lto-objects with clang 2022-10-14 13:31:57 -04:00
Dianne Skoll
9f8ed13434 Remove a whole lot of unused / dead code. 2022-10-14 13:26:56 -04:00
Dianne Skoll
914f03d5eb Fix bad comment. 2022-10-14 11:45:04 -04:00
Dianne Skoll
a801f6d4ce Token names are already lower-case. 2022-10-14 11:43:36 -04:00
Dianne Skoll
fde5a7b4ca Can use strcmp rather than StrCmpI in FindOperator since they are not alphabetic 2022-10-14 11:41:11 -04:00
94 changed files with 3230 additions and 1985 deletions

View File

@@ -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 1992-2022 Dianne Skoll, except where noted in
2. REMIND is Copyright 1992-2023 Dianne Skoll, except where noted in
individual files.
3. DISTRIBUTION AND USE

View File

@@ -1,4 +1,5 @@
# Top-level Makefile for Remind.
# SPDX-License-Identifier: GPL-2.0-only
all: src/Makefile
@echo ""

9
README
View File

@@ -64,6 +64,15 @@ TkRemind requires Tcl/Tk and the tcllib library.
- On Arch Linux, you need tk and tcllib. The latter is available at
https://aur.archlinux.org/packages/tcllib
If the little arrows for "Previous Month" and "Next Month" do not display
correctly in TkRemind, you may need to install the Noto Fonts. Install
all of your distribution's Nonto Font-related packages.
- On Debian-like systems, install with:
apt install fonts-noto-core fonts-noto-color-emoji \
fonts-noto-extra fonts-noto-ui-core fonts-noto-ui-extra
==========================================================================
Contact info: mailto:dianne@skoll.ca
Home page: https://dianne.skoll.ca/projects/remind/

View File

@@ -1,5 +1,6 @@
#!/bin/sh
# -*-Mode: TCL;-*-
# SPDX-License-Identifier: GPL-2.0-only
#--------------------------------------------------------------
# BUILD.TK

16
configure vendored
View File

@@ -3975,7 +3975,14 @@ fi
if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
# Check for link-time optimization support
for f in -flto=auto -ffat-lto-objects; do
f=-flto=auto
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $f" >&5
$as_echo_n "checking whether $CC supports $f... " >&6; }
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
CFLAGS="$CFLAGS $f"
f=-ffat-lto-objects
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $f" >&5
$as_echo_n "checking whether $CC supports $f... " >&6; }
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
@@ -3986,7 +3993,10 @@ $as_echo "yes" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
done
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test "$ac_cv_perlartifacts" = "yes" ; then
@@ -4015,7 +4025,7 @@ _ACEOF
fi
done
VERSION=04.02.00
VERSION=04.02.04

View File

@@ -47,7 +47,12 @@ AC_HEADER_TIME
if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
# Check for link-time optimization support
for f in -flto=auto -ffat-lto-objects; do
f=-flto=auto
AC_MSG_CHECKING([whether $CC supports $f])
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
AC_MSG_RESULT([yes])
CFLAGS="$CFLAGS $f"
f=-ffat-lto-objects
AC_MSG_CHECKING([whether $CC supports $f])
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
AC_MSG_RESULT([yes])
@@ -55,7 +60,9 @@ if test "$GCC" = yes; then
else
AC_MSG_RESULT([no])
fi
done
else
AC_MSG_RESULT([no])
fi
fi
if test "$ac_cv_perlartifacts" = "yes" ; then
@@ -73,7 +80,7 @@ if test "$?" != 0 ; then
exit 1
fi
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
VERSION=04.02.00
VERSION=04.02.04
AC_SUBST(VERSION)
AC_SUBST(PERL)
AC_SUBST(PERLARTIFACTS)

View File

@@ -1,5 +1,135 @@
CHANGES TO REMIND
* VERSION 4.2 Patch 4 - 2023-03-15
- NEW FEATURE: Remind: Add "htmlescape" and "htmlstriptags" built-in
functions.
- NEW FEATURE: Rem2PDF: Add the "--wrap, -y" option to ensure that no
printed calendar takes up more than 5 rows. If a calendar would normally
require 6 rows, wrap it so the last day or two appear on the first
row instead of on a sixth row.
- NEW FEATURE: Remind: Improve the -k option to allow specification of
separate commands for immediately-issued vs. queued reminders. For
example:
remind '-kcmd1 %s' '-k:cmd2 %s' ...
will use "cmd1" for immediately-issued reminders and "cmd2" for queued
ones. If you only use '-k:cmd2 %s' then immediately-issued reminders
are simply printed as usual rather than being passed to a command.
- IMPROVEMENT: Remind: Make "SPECIAL MSG" the same as just "MSG" and
the same for MSF, RUN, PS and PSFILE. This effectively lets you use
expression-pasting to determine the type of a REM command; see the
remind(1) man page for details.
- MINOR IMPROVEMENT: If "make test" fails, output up to 200 lines of diff
so we can see immediately what failed.
- DOCUMENTATION FIX: Fix some typos; fix TkRemind syntax description.
- TEST FIX: Make tests run reliably regardless of local machine's time zone.
- BUG FIX: TkRemind: Don't crash if local installation of Tk lacks the
-underlinefg configuration option.
- BUG FIX: examples/defs.rem: Fix up US Thanksgiving example.
- BUG FIX: include/holidays/us.rem: Add logic for US holidays that are
observed on a Friday if the holiday is a Saturday, or on a Monday if the
holiday is a Sunday.
- BUG FIX: TkRemind: Don't cut off MOON text at the first white-space
character.
- BUG FIX: Remind: prevent functions defined on the command-line (as in
remind '-if(x)=whatever') from segfaulting.
* VERSION 4.2 Patch 3 - 2023-02-10
- NEW FEATURE: Remind: add the orthodoxeaster() function to return the
date of Orthodox Easter.
- IMPROVEMENT: Add Greek language support courtesy of JeiEl.
- IMPROVEMENT: Add Greek holiday file courtesy of JeiEl.
- IMPROVEMENT: Fix the Perl code (rem2pdf, rem2html) to silence Perl::Critic
warnings
- IMPROVEMENT: Many internal code tweaks to eliminate many cppcheck
static analysis warnings.
- DOCUMENTATION IMPROVEMENT: Clarify the distinction between a "time"
and a "duration" as suggested by Ian! D. Allen.
- BUG FIX: Remind: Fix incorrect interaction between sortbanner() and
MSF-type reminders. Bug found by Tim Chase.
- BUG FIX: examples/defs.rem: Fix the calculation of US Tax Day as per
Tavis Ormandy and Tim Chase. Also fixed in include/holidays/us.rem
- BUG FIX: Remind: Add missing #include <fcntl.h> to funcs.c
- BUG FIX: Remind: Fix undefined integer-overflow behavior in built-in abs()
function. Pointed out on IRC by "ubitux".
* VERSION 4.2 Patch 2 - 2023-01-01
- NEW FEATURE: Remind: Add the NOQUEUE modifier to the REM statement for
explicitly telling Remind not to queue a timed reminder.
- NEW FEATURE: Remind: Add soleq() function to return the DATETIME of
solstices and equinoxes. See $SysInclude/seasons.rem for an example
of how to use the function.
- MINOR IMPROVEMENT: Update examples/astro to include solstices and equinoxes.
- BUG FIX: TkRemind: Provide better error indication if showing today's
reminders fails on startup.
- BUG FIX: Remind: Refuse to read world-writable directories.
- BUG FIX: Tests depended on the actual date of the test run. This has
been fixed.
- INTERNAL CHANGE: Remind: Change inappropriately-named "Julian" variables
to "DSE" (= Days Since Epoch) since they weren't really holding true
Julian dates.
- INTERNAL CHANGE: Add "SPDX-License-Identifier" tags to most files.
* VERSION 4.2 Patch 1 - 2022-12-15
- MINOR IMPROVEMENT: TkRemind: If "Extra Remind Options" contains -m, make
TkRemind start the calendar with Monday instead of Sunday.
- MINOR IMPROVEMENT: Sample files: Add French holidays courtesy of
Clément Bœsch.
- MINOR IMPROVEMENT: A few performance fixes, likely not even noticeable in
most cases.
- MINOR FIXES: Fix misleading comments in the source code.
- MINOR FIX: Remove a bunch of dead code in the moon-phase routines.
- MINOR FIX: Remove unnecessary %"...%" markers in holidays/us.rem
- MINOR FIX: Don't use the -ffat-lto-objects command-line option if we're
compiling with Clang.
- MINOR FIX: Remind: Fix a broken printf-format string (need to double up on %
to get a literal % in the output.)
- BUG FIX: Make test suite pass regardless of the date on which it is run.
D'oh!!!
- BUG FIX: Make sure the banner gets printed each time through a "*N"
command-line option loop.
* VERSION 4.2 Patch 0 - 2022-10-14
- NEW FEATURE: remind: Allow weekdays to be globally-omitted. For example:
@@ -1864,7 +1994,7 @@ CHANGES TO REMIND
of Mikko Silvonen.
- Changed the date conversion routines to greatly speed up conversion from
Julian to yyyy/mm/dd form.
Days-since-epoch to yyyy/mm/dd form.
+ BUG FIXES:

View File

@@ -1,6 +1,7 @@
# Demo the columns() function
#
# Run as: remind -@2 alignment.rem
# SPDX-License-Identifier: GPL-2.0-only
SET $AddBlankLines 0
BANNER %

View File

@@ -2,6 +2,7 @@
#
# A little demo script that displays ANSI text attributes
# Not all attributes work on all terminals... your mileage may vary.
# SPDX-License-Identifier: GPL-2.0-only
remind -@2 - <<'EOF'

View File

@@ -3,34 +3,68 @@
# A little demo script that displays astronomical events
#
# Best used in a UTF-8 environment.
# SPDX-License-Identifier: GPL-2.0-only
remind -g -@2 - <<'EOF'
# Set this variable to 1 if your terminal has a dark background or 0 if
# it is light.
# it: light.
SET bg_dark 1
bg_dark=1
# Set your latitude and longitude correctly for Sunrise/Sunset/Equinox/Solstice
#
# The values below are for Ottawa, Ontario, Canada
latitude="45.420556"
longitude="-75.689722"
remind -g -ibg_dark="$bg_dark" "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
SET $AddBlankLines 0
BANNER %
MSG Today is [today()].%_
INCLUDE [$SysInclude]/ansitext.rem
MSG Today is [ansi_bold][$T][ansi_normal], being the [ord($T-date(year($T),1,1)+1)] day of [year($T)].%_
IF bg_dark
SPECIAL COLOR 255 255 0 Sunrise: 🌅 [sunrise()] today and [sunrise(today()+1)] tomorrow
SPECIAL COLOR 255 128 0 Sunset: 🌇 [sunset()] today and [sunset(today()+1)] tomorrow%_
SPECIAL COLOR 255 255 0 Sunrise: 🌅 [sunrise()] today and [sunrise($T+1)] tomorrow
SPECIAL COLOR 255 128 0 Sunset: 🌇 [sunset()] today and [sunset($T+1)] tomorrow%_
ENDIF
EOF
REM [moondate(0)] +60 SPECIAL COLOR 255 255 0 New moon: 🌑 [moondate(0)] (%b)
REM [moondate(1)] +60 SPECIAL COLOR 255 255 128 First Quarter: 🌓 [moondate(1)] (%b)
REM [moondate(2)] +60 SPECIAL COLOR 255 255 255 Full moon: 🌕 [moondate(2)] (%b)
REM [moondate(3)] +60 SPECIAL COLOR 255 255 128 Last Quarter: 🌗 [moondate(3)] (%b)
remind -g -ibg_dark="$bg_dark" "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
SET $AddBlankLines 0
BANNER %
IF bg_dark
REM [moondatetime(0)] +60 SPECIAL COLOR 255 255 0 New moon: 🌑 [$T] %3 (%b)
REM [moondatetime(1)] +60 SPECIAL COLOR 255 255 128 First Quarter: 🌓 [$T] %3 (%b)
REM [moondatetime(2)] +60 SPECIAL COLOR 255 255 255 Full moon: 🌕 [$T] %3 (%b)
REM [moondatetime(3)] +60 SPECIAL COLOR 255 255 128 Last Quarter: 🌗 [$T] %3 (%b)
ELSE
SPECIAL COLOR 128 128 0 Sunrise: 🌅 [sunrise()] today and [sunrise(today()+1)] tomorrow
SPECIAL COLOR 128 32 0 Sunset: 🌇 [sunset()] today and [sunset(today()+1)] tomorrow%_
SPECIAL COLOR 128 128 0 Sunrise: 🌅 [sunrise()] today and [sunrise($T+1)] tomorrow
SPECIAL COLOR 128 32 0 Sunset: 🌇 [sunset()] today and [sunset($T+1)] tomorrow%_
REM [moondate(0)] +60 SPECIAL COLOR 128 128 0 New moon: 🌑 [moondate(0)] (%b)
REM [moondate(1)] +60 SPECIAL COLOR 128 128 64 First Quarter: 🌓 [moondate(1)] (%b)
REM [moondate(2)] +60 SPECIAL COLOR 0 0 0 Full moon: 🌕 [moondate(2)] (%b)
REM [moondate(3)] +60 SPECIAL COLOR 128 128 64 Last Quarter: 🌗 [moondate(3)] (%b)
REM [moondatetime(0)] +60 SPECIAL COLOR 128 128 0 New moon: 🌑 [$T] %3 (%b)
REM [moondatetime(1)] +60 SPECIAL COLOR 128 128 64 First Quarter: 🌓 [$T] %3 (%b)
REM [moondatetime(2)] +60 SPECIAL COLOR 0 0 0 Full moon: 🌕 [$T] %3 (%b)
REM [moondatetime(3)] +60 SPECIAL COLOR 128 128 64 Last Quarter: 🌗 [$T] %3 (%b)
ENDIF
EOF
echo ""
remind -g -ibg_dark="$bg_dark" "-i\$Latitude=\"$latitude\"" "-i\$Longitude=\"$longitude\"" -q -@2 - "$@" <<'EOF'
SET $AddBlankLines 0
BANNER %
IF $LatDeg >= 0
REM [soleq(0)] +366 MSG Next Vernal Equinox: 🌼 [$T] %3 (%b)
REM [soleq(1)] +366 MSG Next Summer Solstice: 😎 [$T] %3 (%b)
REM [soleq(2)] +366 MSG Next Autumnal Equinox: 🍂 [$T] %3 (%b)
REM [soleq(3)] +366 MSG Next Winter Solstice: ❄️ [$T] %3 (%b)
ELSE
REM [soleq(0)] +366 MSG Next Autumnal Equinox: 🍂 [$T] %3 (%b)
REM [soleq(1)] +366 MSG Next Winter Solstice: ❄️ [$T] %3 (%b)
REM [soleq(2)] +366 MSG Next Vernal Equinox: 🌼 [$T] %3 (%b)
REM [soleq(3)] +366 MSG Next Summer Solstice: 😎 [$T] %3 (%b)
ENDIF
EOF

View File

@@ -16,7 +16,8 @@
# "#PSSTUFF" for nifty PostScript examples #
# #
# This file is part of REMIND. #
# Copyright (C) 1992-2022 Dianne Skoll #
# Copyright (C) 1992-2023 Dianne Skoll #
# SPDX-License-Identifier: GPL-2.0-only
# #
#############################################################################
@@ -41,7 +42,6 @@ SET Week_1 1
SET Week_2 8
SET Week_3 15
SET Week_4 22
FSET _last(mo) "1 " + MON((mo%12)+1) + " --7"
#################################################################
# Function that removes a single leading zero from a string... #
@@ -125,6 +125,8 @@ REM Sat Sun SPECIAL SHADE 220
# The following holidays were provided by Dave Rickel #
# Modified by D. Skoll to give safe OMITs for moveable holidays #
# #
# NOTE: See include/holidays/us.rem for more up-to-date definitions #
# #
#############################################################################
SET SaveTrig $NumTrig
@@ -156,7 +158,24 @@ REM Last Sunday in October ++2 UNTIL 1 Jan 2007 MSG Daylight Saving Time - %"DST
REM First Sunday in November ++2 FROM 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b
REM Apr 1 MSG %"April Fool's%" Day
REM Mon Tue Wed Thu Fri Sat 15 Apr MSG %"Income tax%" due
# US Tax Day
PUSH-OMIT-CONTEXT
# Normal case: 16 April falls Mon-Fri
REM 16 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw >= 1 && $Tw <= 5] MSG Emancipation Day
# 16 April falls on Saturday: Observe on the 15th
REM 15 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Emancipation Day (observed)
# 16 April falls on Sunday: Observe on the 17th
REM 17 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Emancipation Day (observed)
# If you live in Maine or Massachussetts, uncomment the next line
# REM Third Monday in April SCANFROM -7 ADDOMIT MSG Patriots Day
REM Apr 15 OMIT Sat Sun AFTER MSG Tax Day
POP-OMIT-CONTEXT
REM May 5 MSG %"Cinco de Mayo%"
REM First Sat in May MSG %"Kentucky Derby%"
REM Second Sun in May MSG %"Mother's Day%"
@@ -171,7 +190,7 @@ REM Nov 11 MSG %"Veterans Day%"
REM Oct 30 MSG %"Mischief Night%"
REM Oct 31 MSG %"Halloween%"
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG %"Election Day%"
REM Last Thu in Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
REM Thu Nov [Week_4] SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
REM Fri Nov [Week_4+1] SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
OMIT Dec 24 MSG %"Christmas Eve%"
OMIT Dec 25 MSG %"Christmas%" Day

View File

@@ -2,7 +2,8 @@
# Not all sequences are supported by all terminals.
# This file is part of REMIND
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# SPDX-License-Identifier: GPL-2.0-only
if !defined("ansi_bold")
# Disable ANSI attributes in calandar mode

View File

@@ -1,4 +1,5 @@
# Canadian holidays
# SPDX-License-Identifier: GPL-2.0-only
OMIT 1 Jan MSG New Year's Day

20
include/holidays/fr.rem Normal file
View File

@@ -0,0 +1,20 @@
#
# France Holidays
#
# Source: Article L3133-1
# https://www.legifrance.gouv.fr/codes/section_lc/LEGITEXT000006072050/LEGISCTA000006178007/2016-08-10/
#
SET easter EASTERDATE($Uy)
REM Jan 1 MSG %"Jour de l'an%"
REM [easter+1] MSG %"Lundi de Pâques%"
REM May 1 MSG %"Fête du Travail%"
REM May 8 MSG %"Victoire des alliés%"
REM [easter+39] MSG %"Jeudi de l'Ascension%"
REM [easter+50] MSG %"Lundi de Pentecôte%"
REM Jul 14 MSG %"Fête nationale%"
REM Aug 15 MSG %"Assomption%"
REM Nov 1 MSG %"La Toussaint%"
REM Nov 11 MSG %"Armistice%"
REM Dec 25 MSG %"Noël%"

39
include/holidays/gr.rem Normal file
View File

@@ -0,0 +1,39 @@
# Greek national holidays
# ΑΡΓΙΕΣ (για όλους)
# fixed
REM 1 Jan MSG ΠΡΩΤΟΧΡΟΝΙΑ
REM 6 Jan MSG ΤΑ ΦΩΤΑ/ ΘΕΟΦΑΝΕΙΑ
REM 25 Mar MSG η 25η Μαρτίου
REM 15 Aug MSG 15Αύγουστος
REM 28 Oct MSG ΟΧΙ
REM 25 Dec MSG ΧΡΙΣΤΟΥΓΕΝΝΑ
REM 26 Dec MSG ΧΡΙΣΤΟΥΓΕΝΝΑ2
REM [orthodoxeaster($Uy)+1] ΔΕΥΤΕΡΑ ΤΟΥ ΠΑΣΧΑ
# May first is a national holiday except if Sunday, day of great week (week before easter) or Monday after easter, then
# minister decides moving that holiday. Here is a likely assumption of how this day might be moved.
# Uncomment following lines to enable.
set PM date($Uy,5,1)
# IF PM>=orthodoxeaster($Uy)-7 && PM<=orthodoxeaster($Uy)+1
# IF PM<orthodoxeaster($Uy)-3
# REM orthodoxeaster($Uy) -8 MSG πιθανόν ΕΡΓΑΤΙΚΗ Πρωτομαγιά
# ELSE
# REM [plusfunc(2)] MSG πιθανόν ΕΡΓΑΤΙΚΗ Πρωτομαγιά
# ENDIF
# ENDIF
# REM [PM] OMIT Sun AFTER MSG Πρωτομαγιά
REM 1 May MSG Πρωτομαγιά
# end of May 1 speculations
# The following are main national holidays per custom (observed by most but not all)
REM [orthodoxeaster($Uy)] -48 MSG Καθαρά Δευτέρα
REM [orthodoxeaster($Uy)] -2 MSG Μεγάλη Παρασκευή
REM [orthodoxeaster($Uy)] -1 MSG Μεγάλο Σάββατο
REM [orthodoxeaster($Uy)+50] MSG Αγίου Πνεύματος

View File

@@ -1,4 +1,5 @@
# Major Jewish Holidays
# SPDX-License-Identifier: GPL-2.0-only
# Set the variable InIsrael to 1 if you live in Israel. Otherwise,
# you get the Diaspora versions of Jewish holidays

View File

@@ -1,54 +1,82 @@
# US holidays
# This file is part of REMIND.
# Copyright (C) 1992-2022 Dianne Skoll
# Copyright (C) 1992-2023 Dianne Skoll
# SPDX-License-Identifier: GPL-2.0-only
REM [easterdate($Uy)-46] MSG %"Ash Wednesday%"
REM [easterdate($Uy)-7] MSG %"Palm Sunday%"
OMIT [easterdate($Uy)-2] MSG %"Good Friday%"
REM [easterdate($Uy)-46] MSG Ash Wednesday
REM [easterdate($Uy)-7] MSG Palm Sunday
OMIT [easterdate($Uy)-2] MSG Good Friday
OMIT [easterdate($Uy)] MSG %"Easter%" Sunday
REM [easterdate($Uy)+39] MSG %"Ascension Day%"
REM [easterdate($Uy)+49] MSG %"Pentecost%"
REM [easterdate($Uy)+39] MSG Ascension Day
REM [easterdate($Uy)+49] MSG Pentecost
# Some holidays are omitted, some are not. You may want to change
# which ones are omitted.
OMIT Jan 1 MSG %"New Year's Day%"
OMIT Jan 1 MSG New Year's Day
REM 31 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG New Year's Day (observed)
REM 2 Jan SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG New Year's Day (observed)
REM Third Monday in Jan MSG Martin Luther King - %"MLK Day%"
REM Feb 2 MSG %"Ground Hog Day%"
REM Feb 14 MSG %"Valentine's Day%"
REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG %"President's Day%"
REM Mar 17 MSG %"St. Patrick's Day%"
REM Feb 2 MSG Ground Hog Day
REM Feb 14 MSG Valentine's Day
REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG President's Day
REM Mar 17 MSG St. Patrick's Day
# These are accurate for most places in North America
REM MAYBE-UNCOMPUTABLE Sun November SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Ends
REM MAYBE-UNCOMPUTABLE Sun March SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Starts
REM MAYBE-UNCOMPUTABLE Sun November SATISFY [isdst($T) && !isdst($T+1)] MSG Daylight Saving Time Ends
REM MAYBE-UNCOMPUTABLE Sun March SATISFY [!isdst($T) && isdst($T+1)] MSG Daylight Saving Time Starts
REM Apr 1 MSG %"April Fool's%" Day
REM Mon Tue Wed Thu Fri Sat 15 Apr MSG %"Income tax%" due
REM May 5 MSG %"Cinco de Mayo%"
REM First Sat in May MSG %"Kentucky Derby%"
REM Second Sun in May MSG %"Mother's Day%"
REM Third Sat in May MSG %"Armed Forces Day%"
REM Last Monday in May SCANFROM -7 ADDOMIT MSG %"Memorial Day%"
REM Jun 14 MSG %"Flag Day%"
PUSH-OMIT-CONTEXT
# Normal case: 16 April falls Mon-Fri
REM 16 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw >= 1 && $Tw <= 5] MSG Emancipation Day
# 16 April falls on Saturday: Observe on the 15th
REM 15 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Emancipation Day (observed)
# 16 April falls on Sunday: Observe on the 17th
REM 17 Apr SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Emancipation Day (observed)
# If you live in Maine or Massachussetts, uncomment the next line
# REM Third Monday in April SCANFROM -7 ADDOMIT MSG Patriots Day
REM Apr 15 OMIT Sat Sun AFTER MSG %"Income tax%" due
POP-OMIT-CONTEXT
REM May 5 MSG Cinco de Mayo
REM First Sat in May MSG Kentucky Derby
REM Second Sun in May MSG Mother's Day
REM Third Sat in May MSG Armed Forces Day
REM Last Monday in May SCANFROM -7 ADDOMIT MSG Memorial Day
REM Jun 14 MSG Flag Day
OMIT 19 June MSG Juneteenth
REM 18 June SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Juneteenth (observed)
REM 20 June SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Juneteenth (observed)
REM July 4 SCANFROM -7 ADDOMIT MSG Independence Day
REM July 3 SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Independence Day (observed)
REM July 5 SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Independence Day (observed)
REM July 3 SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Independence Day (observed)
REM July 5 SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Independence Day (observed)
REM Third Sun in June MSG %"Father's Day%"
REM First Mon in Sep SCANFROM -7 ADDOMIT MSG %"Labor Day%"
REM Second Mon in Oct MSG %"Columbus Day / Indigenous Peoples' Day%"
REM Nov 11 MSG %"Veterans Day%"
REM Third Sun in June MSG Father's Day
REM First Mon in Sep SCANFROM -7 ADDOMIT MSG Labor Day
REM Second Mon in Oct MSG Columbus Day / Indigenous Peoples' Day
REM Oct 30 MSG %"Mischief Night%"
REM Oct 31 MSG %"Halloween%"
OMIT 11 Nov MSG Veterans Day
REM 10 Nov SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Veterans Day (observed)
REM 12 Nov SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Veterans Day (observed)
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG %"Election Day%"
REM Oct 30 MSG Mischief Night
REM Oct 31 MSG Halloween
REM Thu 22 Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG Election Day
REM Fri 23 Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
REM Thu 22 Nov SCANFROM -7 ADDOMIT MSG Thanksgiving Day
REM Fri 23 Nov SCANFROM -7 ADDOMIT MSG Thanksgiving (cont.)
REM Dec 24 MSG %"Christmas Eve%"
REM Dec 24 MSG Christmas Eve
OMIT Dec 25 MSG %"Christmas%" Day
REM 24 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==5] MSG Christmas (observed)
REM 26 Dec SCANFROM -7 ADDOMIT SATISFY [$Tw==1] MSG Christmas (observed)

View File

@@ -1,4 +1,9 @@
SET autolang getenv("LC_ALL")
# SPDX-License-Identifier: GPL-2.0-only
SET autolang getenv("REMIND_LANG")
IF autolang == ""
SET autolang getenv("LC_ALL")
ENDIF
IF autolang == ""
SET autolang getenv("LANGUAGE")
ENDIF

View File

@@ -1,6 +1,6 @@
# Support for the Danish language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Mogens Lynnerup.
SET $Sunday "Søndag"

View File

@@ -1,6 +1,6 @@
# Support for the German language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Wolfgang Thronicke
# Day names

View File

@@ -1,4 +1,4 @@
# Support for the English language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# Nothing to do for English since it is the default.

View File

@@ -1,6 +1,6 @@
# Support for the Spanish language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Rafa Couto <rafacouto@biogate.com>
SET $Sunday "Domingo"

View File

@@ -1,6 +1,6 @@
# Support for the Finnish language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Mikko Silvonen
SET $Sunday "sunnuntai"

View File

@@ -1,6 +1,6 @@
# Support for the French language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Laurent Duperval
SET $Sunday "dimanche"

83
include/lang/gr.rem Normal file
View File

@@ -0,0 +1,83 @@
# Support for the Hellenic (Greek) language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by jarlaxl lamat (jarlaxl@freemail.gr)
SET $Sunday "Κυριακή"
SET $Monday "Δευτέρα"
SET $Tuesday "Τρίτη"
SET $Wednesday "Τετάρτη"
SET $Thursday "Πέμπτη"
SET $Friday "Παρασκευή"
SET $Saturday "Σάββατο"
SET $January "Ιανουάρ."
SET $February "Φεβρουάρ."
SET $March "Μάρτ."
SET $April "Απρίλ."
SET $May "Μαι."
SET $June "Ιούν."
SET $July "Ιούλ."
SET $August "Αυγουστ."
SET $September "Σεπτέμβρ."
SET $October "Οκτώβρ."
SET $November "Νοέμβρ."
SET $December "Δεκέμβρ."
SET $Today "σήμερα"
SET $Tomorrow "αύριο"
BANNER Υπενθυμίσεις: %w, %d %m, %y%o:
SET $Am "πμ"
SET $Pm "μμ"
SET $Ago "πριν"
SET $Fromnow "από τώρα"
SET $On "την"
SET $Now "τώρα"
SET $At "στις"
SET $Minute "λεπτά"
SET $Hour "ώρες"
SET $Is "είναι"
SET $Was "ήταν"
SET $And "και"
SET $Hplu ""
SET $Mplu ""
FSET subst_bx(a, d, t) "σε " + (d - today()) + " ημέρες"
FSET subst_ordinal(d) "."
FSET subst_a_alt(d) wkday(d) + ", " + day(d) + ". " + mon(d) + " " + year(d)
FSET subst_ax(alt, d, t) iif(alt, subst_a_alt(d), $On + " " + subst_a_alt(d))
FSET subst_g_alt(d) wkday(d) + ", " + day(d) + ". " + mon(d)
FSET subst_gx(alt, d, t) iif(alt, subst_g_alt(d), $On + " " + subst_g_alt(d))
FSET subst_ux(alt, d, t) subst_ax(alt, d, t)
FSET subst_vx(alt, d, t) subst_gx(alt, d, t)
# Localization of various astronomical events
# Perihelion
SET earthseasons_Perihelion_str "Περιήλιον"
# Vernal equinox
SET earthseasons_EquinoxMar_str "Εαρινή ισημερία"
# Summer solstice
SET earthseasons_SolsticeJun_str "Θερινό ηλιοστάσιο"
# Aphelion
SET earthseasons_Aphelion_str "Αφήλιον"
# Autumnal Equinox
SET earthseasons_EquinoxSep_str "Φθινοπωρινή ισημερία"
# Winter Solstice
SET earthseasons_SolsticeDec_str "Χειμερινό ηλιοστάσιο"
# Daylight saving time starts
SET daylightST_starts_str "Έναρξη θέρους"
# Daylight saving time ends
SET daylightST_ends_str "Τέλος θέρους"

View File

@@ -1,6 +1,6 @@
# Support for the Icelanding language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Björn Davíðsson (bjossi@snerpa.is)
SET $Sunday "sunnudagur"

View File

@@ -1,6 +1,6 @@
# Support for the Italian language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Valerio Aimale
SET $Sunday "Domenica"

View File

@@ -1,6 +1,6 @@
# Support for the Dutch language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Willem Kasdorp and Erik-Jan Vens
SET $Sunday "zondag"

View File

@@ -1,6 +1,6 @@
# Support for the Norwegian language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Trygve Randen
SET $Sunday "Søndag"

View File

@@ -1,6 +1,6 @@
# Support for the Polish language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Jerzy Sobczyk
SET $Sunday "Niedziela"

View File

@@ -1,6 +1,6 @@
# Support for the (Brazilian) Portuguese language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Marco Paganini
SET $Sunday "domingo"

View File

@@ -1,6 +1,6 @@
# Support for the Romanian language.
# This file is part of REMIND.
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
# REMIND is Copyright (C) 1992-2023 by Dianne Skoll
# This file is derived from a translation by Liviu Daia
SET $Sunday "Duminică"

16
include/seasons.rem Normal file
View File

@@ -0,0 +1,16 @@
# Equinoxes and solstices
# SPDX-License-Identifier: GPL-2.0-only
IF $LatDeg >= 0
# Northern Hemisphere
REM NOQUEUE [soleq(0)] MSG %"Vernal Equinox%" is %3.
REM NOQUEUE [soleq(1)] MSG %"Summer Solstice%" is %3.
REM NOQUEUE [soleq(2)] MSG %"Autumnal Equinox%" is %3.
REM NOQUEUE [soleq(3)] MSG %"Winter Solstice%" is %3.
ELSE
# Southern Hemisphere
REM NOQUEUE [soleq(0)] MSG %"Autumnal Equinox%" is %3.
REM NOQUEUE [soleq(1)] MSG %"Winter Solstice%" is %3.
REM NOQUEUE [soleq(2)] MSG %"Vernal Equinox%" is %3.
REM NOQUEUE [soleq(3)] MSG %"Summer Solstice%" is %3.
ENDIF

View File

@@ -328,6 +328,18 @@ processes with the above technique. So be very careful. Because all
shell and whitespace characters are escaped, the program you execute
with the \fB\-k\fR option must be prepared to handle the entire
message as a single argument.
.PP
If you follow the \fB\-k\fR option with a colon, then the command is applied
only to queued timed reminders. Normal reminders are handled as usual.
In the above example, if you want normal reminders to simply be displayed
as usual, but queued reminders to be sent to notify-send, you could use:
.PP
.nf
remind '\-k:notify-send %s &' ...
.fi
.PP
You use both \fB\-k\fR\fIcmd1\fR and \fB\-k:\fR\fIcmd2\fR to use different
commands for queued versus non-queued reminders.
.RE
.TP
\fB\-z\fR[\fIn\fR] Runs \fBRemind\fR in the daemon mode. If \fIn\fR
@@ -464,6 +476,7 @@ Its syntax is:
[\fBSKIP\fR | \fBBEFORE\fR | \fBAFTER\fR]
[\fBOMIT\fR \fIomit_list\fR]
[\fBADDOMIT\fR]
[\fBNOQUEUE\fR]
[\fBOMITFUNC\fR \fIomit_function\fR]
[\fBAT\fR \fItime\fR [\fItdelta\fR] [\fItrepeat\fR]]
[\fBSCHED\fR \fIsched_function\fR]
@@ -1005,7 +1018,7 @@ By comparison, if we had used "\-\-1", the reminder would be triggered on
the last day of the month, regardless of the \fBOMIT\fR.
.PP
If you locally omit weekdays but also have globally-omitted weekdays, then
the list of ommitted weekdays is the union of the two. Consider this
the list of omitted weekdays is the union of the two. Consider this
example:
.PP
.nf
@@ -1100,7 +1113,11 @@ 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
the specified time.
the specified time. Note that if you use the \fBNOQUEUE\fR modifier
in the \fBREM\fR command, then this queueing and background activation
is \fInot\fR performed. \fBNOQUEUE\fR is useful if you want a time
to be associated with a reminder (eg, in the calendar) but are not
interested in a popup reminder happening at the specified time.
.PP
If the trigger date is \fInot\fR the same as the system date, the reminder
@@ -1210,11 +1227,25 @@ specifies the duration of an event. For example, if you have a
REM 5 March 2021 AT 1:00pm DURATION 90 MSG Meeting
.fi
.PP
Note that \fIduration\fR is specified either in hours and minutes as a
\fItime\fR, or in minutes as an \fIinteger\fR. If you specify a
duration of 00:00 or 0, then \fBRemind\fR behaves exactly as if no
\fBDURATION\fR at all had been present.
For long-duration reminders, it is convenient to use expressions
to simplify writing the DURATION. For example, if you are away
from 20 Feb 2023 through 23 Feb 2023 (a total of 4 days) you
could write:
.PP
.nf
REM 20 Feb AT 00:00 DURATION [4*24]:00 MSG away
REM 20 Feb AT 00:00 DURATION [4*24*60] MSG away
.fi
.PP
Note that \fIduration\fR is specified either as
\fIhours\fR:\fIminutes\fR or just as \fIminutes\fR specified as an
\fIinteger\fR.
.PP
If you specify a duration of 00:00 or 0, then \fBRemind\fR behaves
exactly as if no \fBDURATION\fR at all had been present. Although
durations specified as \fIhours\fR:\fIminutes\fR look superficially like a
time-of-day, they are not; the \fIhours\fR component is not limited
to the range 00-23.
.PP
.SH SYNTACTIC SUGAR FOR REM
@@ -1956,9 +1987,23 @@ somewhat comparable to a C character array, but more closely resembles
the string type in BASIC.
.TP
.B TIME
The \fBTIME\fR data type consists of times of the day. The \fBTIME\fR
data type is internally stored as an integer representing the number
of minutes since midnight.
The \fBTIME\fR data type is used for two different purposes: To represent
a time of day with one-minute precision or to represent a duration
with one-minute precision. The context of where a \fBTIME\fR is used
determines whether it is interpreted as a time of day or a duration.
.RS
.PP
In contexts where a \fBTIME\fR represents a time of day, it may range
from 00:00 to 23:59 and is stored internally as an integer from 0 to
1439 representing the number of minutes since midnight.
.PP
In contexts where a \fBTIME\fR represents a duration, there is no
upper limit on the hour component (beyond that imposed by the
restriction that a duration expressed in minutes must fit into the
signed integer type of your CPU architecture.) Internally, a duration
is stored as an integer number of minutes.
.RE
.TP
.B DATE
The \fBDATE\fR data type consists of dates (later than 1 January 1990.)
@@ -2001,6 +2046,15 @@ range from 1 to 12. Either a period or colon can be used to separate
the minutes from the hours. However, Remind will consistently output
times in 24-hour format using only one separator character. (The
output separator character is chosen at compile-time.)
.PP
If the \fBTIME\fR is used where \fBRemind\fR expects a time-of-day
(for example, in an \fBAT\fR clause), then it can be written in
24-hour format (ranging from 00:00 to 23:59) or 12-hour format
(ranging from 12:00am to 11:59pm). If the \fBTIME\fR is used where
\fBRemind\fR expects a duration, it must not have an \fIam\fR or
\fIpm\fR suffix and the hour can be as large as you want, so long
as the total number of minutes in the duration fits in a signed integer
variable.
.RE
.TP
.B DATE constants
@@ -2569,8 +2623,8 @@ can invoke Remind with the option \fB'\-i$SuppressLRM=1'\fR.
.B $SysInclude (read-only, STRING type)
A directory path containing standard reminder scripts. Currently,
Remind ships with some standard holiday files and language packs.
The value of \fB$SysInclude\fR is likely to be something like
"/usr/share/remind" or "/usr/local/share/remind"
The value of \fB$SysInclude\fR is "@prefix@/share/remind" on
this installation.
.TP
.B $T (read-only, DATE type)
Exactly equivalent to \fBtrigdate()\fR. (See BUILT-IN FUNCTIONS.)
@@ -2934,6 +2988,11 @@ If \fIarg\fR is an \fBINT\fR, then returns the date of Easter Sunday
for the specified year. If \fIarg\fR is a \fBDATE\fR or
\fBDATETIME\fR, then returns the date of the next Easter Sunday on or
after \fIarg\fR. (The time component of a datetime is ignored.)
.RS
.P
Note that \fBeasterdate\fR computes the Western Easter. For the Orthodox
Easter date, see \fBorthodoxeaster\fR.
.RE
.TP
.B evaltrig(s_trigger [,dq_start])
Evaluates \fItrigger\fR as if it were a REM or IFTRIG trigger specification
@@ -3027,6 +3086,16 @@ Support for Hebrew dates - see the section "THE HEBREW CALENDAR"
.B hour(tq_time)
Returns the hour component of \fItime\fR.
.TP
.B htmlescape(s_str)
Returns a modified copy of \fIstr\fR where "<" is replaced with
"&lt;"; ">" is replaced with "&gt;" and "&" is replaced with "&amp;"
.TP
.B htmlstriptags(s_str)
Returns a modified copy of \fIstr\fR where HTML tags are stripped
out. The stripping algorithm is fairly naive; the function starts
stripping characters when it encounters a "<" and it stops stripping
when it encounters a ">".
.TP
.B iif(si_test1, x_arg1, [si_test2, x_arg2,...], x_default)
If \fItest1\fR is not zero or the null string, returns \fIarg1\fR.
Otherwise, if \fItest2\fR is not zero or the null string, returns
@@ -3256,6 +3325,17 @@ the actual time, or a time supplied on the command line.
Returns a string that is the ordinal number \fInum\fR. For example,
\fBord(2)\fR returns "2nd", and \fBord(213)\fR returns "213th".
.TP
.B orthodoxeaster(dqi_arg)
If \fIarg\fR is an \fBINT\fR, then returns the date of Orthodox Easter Sunday
for the specified year. If \fIarg\fR is a \fBDATE\fR or
\fBDATETIME\fR, then returns the date of the next Orthodox Easter Sunday on or
after \fIarg\fR. (The time component of a datetime is ignored.)
.RS
.P
Note that \fBorthodoxeaster\fR computes the Orthodox Easter. For the Western
Easter date, see \fBeasterdate\fR.
.RE
.TP
.B ostype()
Returns "UNIX". Remind used to run on OS/2 and MS-DOS, but does not
any longer.
@@ -3431,6 +3511,28 @@ May 16 and 17. You can go backwards, too, so:
takes \fIa\fR back to 2009-05-13.
.RE
.TP
.B soleq(i_which [, dqi_start])
The \fBsoleq\fR function computes solstices and equinoxes. The \fIwhich\fR
parameter ranges from 0 to 3, and specifies which event we are interested
in: 0 is the March equinox; 1 is the June solstice; 2 is the September
equinox and 3 is the December solstice.
.RS
.PP
The optional \fIstart\fR parameter can either be an integer specifying the
year of the event we are interested in, or a \fBDATE\fR or \fBDATETIME\fR
object; if the latter, then \fBsoleq\fR returns the first event on or
after the date part of the \fIstart\fR parameter (it ignores the time
component if \fIstart\fR is a \fBDATETIME\fR.) If \fIstart\fR is
not supplied, then it defaults to \fBtoday()\fR.
.PP
The return value of \fBsoleq()\fR is a \fBDATETIME\fR object specifying
the date and time of the solstice or equinox in the local time zone. It
should be accurate to within 3 minues or so in the worst case.
.PP
See the included file \fB$SysInclude/seasons.rem\fR for examples of how
to use \fBsoleq()\fR.
.RE
.TP
.B stdout()
Returns a string representing where Remind's standard output is going.
The return values are one of the following: "TTY" if standard-output
@@ -3985,15 +4087,30 @@ You cannot use expression-pasting to determine the type (\fBMSG\fR,
\fBCAL\fR, etc.) of a \fBREM\fR command. You can paste expressions
before and after the \fBMSG\fR, etc. keywords, but cannot do something like
this:
.RS
.PP
.nf
REM ["12 Nov 1993 AT 13:05 " + "MSG" + " BOO!"]
REM ["12 Nov 1993 AT 13:05 " + "MSG" + " BOO!"]
.fi
.PP
.B COMMON PITFALLS IN EXPRESSION PASTING
However, as an escape hatch, the sequence \fBSPECIAL\fR \fItype\fR
means the same thing as just \fItype\fR where \fItype\fR is one
of MSG, MSF, RUN, CAL, PS and PSFILE. This lets you do something
like this:
.PP
Remember, when pasting in expressions, that extra spaces are not
inserted. Thus, something like:
.nf
SET type "MSG"
REM 12 Nov 2024 SPECIAL [type] Hello
.fi
.PP
You can use this to control the types of your reminders based on variables
you set, how Remind is invoked, etc.
.RE
.PP
.B COMMON PITFALLS WITH EXPRESSION PASTING
.PP
Remember that extra spaces are not inserted when an expression is
pasted. Thus, something like:
.PP
.nf
REM[expr]MSG[expr]

View File

@@ -3,7 +3,7 @@
.SH NAME
tkremind \- graphical front-end to Remind calendar program
.SH SYNOPSIS
.B tkremind \fR[\fIoptions\fR] [\fIread_file\fR] [\fIwrite_file\fR] [\fIconfig_file\fR]
.B tkremind \fR[\fIoptions\fR] [\fIread_file\fR [\fIwrite_file\fR [\fIconfig_file\fR]]]
.SH DESCRIPTION
\fBTkRemind\fR is a graphical front-end to the \fBRemind\fR program.
It provides a friendly graphical interface which allows you to view
@@ -419,7 +419,7 @@ This line is emitted in response to a \fBSTATUS\fR command. The number
.SH AUTHOR
TkRemind was written by Dianne Skoll <dianne@skoll.ca>
\fBTkRemind\fR is Copyright 1996-2022 by Dianne Skoll.
\fBTkRemind\fR is Copyright 1996-2023 by Dianne Skoll.
.SH FILES

View File

@@ -1,4 +1,5 @@
#!perl
# SPDX-License-Identifier: GPL-2.0-only
use strict;
use warnings;
@@ -686,7 +687,7 @@ if ($Options{help}) {
exit(0);
}
if (-t STDIN) {
if (-t STDIN) { ## no critic
print STDERR "$TIDY_PROGNAME: Input should not come from a terminal.\n\n";
usage(1);
}

View File

@@ -1,4 +1,5 @@
#!@PERL@
# SPDX-License-Identifier: GPL-2.0-only
use strict;
use warnings;
use lib '@prefix@/lib/perl5';
@@ -36,7 +37,7 @@ my $settings = {
numbers_on_left => 0,
small_calendars => 0,
fill_entire_page => 0,
wrap_calendar => 0,
media => 'Letter',
width => 0,
height => 0,
@@ -85,6 +86,7 @@ Options:
--media=MEDIA, -mMEDIA Size for specified media
--width=W, -wW Specify media width in 1/72nds of an inch
--height=H, -hH Specify media height in 1/72nds of an inch
--wrap, -y Make calendar fit in at most 5 rows
--title-font=FONT Specify font for calendar title
--header-font=FONT Specify font for weekday names
--daynum-font=FONT Specify font for day numbers
@@ -113,6 +115,7 @@ my $ret = GetOptions('landscape|l' => \$settings->{landscape},
'fill-page|e' => \$settings->{fill_entire_page},
'media|m=s' => \$settings->{media},
'width|w=i' => \$settings->{width},
'wrap|y' => \$settings->{wrap_calendar},
'height|h=i' => \$settings->{height},
'title-font=s' => \$settings->{title_font},
'header-font=s' => \$settings->{header_font},
@@ -174,7 +177,7 @@ if ($settings->{landscape}) {
}
# Don't read from a terminal
if (-t STDIN) {
if (-t STDIN) { ## no critic
print STDERR "I can't read data from a terminal. Please run like this:\n";
print STDERR " remind -pp [options] filename | $me [options] > out.pdf\n";
exit(1);
@@ -248,20 +251,21 @@ sub set_media
sub set_media_from_file
{
my ($fn) = @_;
if (!open(IN, '<', $fn)) {
my $IN;
if (!open($IN, '<', $fn)) {
return 0;
}
while(<IN>) {
while(<$IN>) {
chomp;
s/^\s+//;
s/\s+$//;
next if ($_ eq '');
next if ($_ =~ /^#/);
my $m = $_;
close(IN);
close($IN);
return set_media($m);
}
close(IN);
close($IN);
return 0;
}
@@ -429,6 +433,14 @@ The default is 36.
The size of the margin at the right of the page in 1/72ths of an inch.
The default is 36.
=item --wrap, -y
Modify the calendar so that if it would normally require 6 rows to print,
then the last day (or last two days, as needed) are moved to the
first row of the calendar, and adjust the small calendar positions
as needed. This results in a calendar that only requires 5 rows, but
with the last day or two appearing in the I<first> row.
=item --verbose, -v
Print (on STDERR) the name of the month and year for each month that

View File

@@ -1,4 +1,5 @@
package Remind::PDF;
# SPDX-License-Identifier: GPL-2.0-only
use strict;
use warnings;
@@ -109,7 +110,6 @@ sub read_one_month
$self->{daysinnextmonth} = 0;
$self->{prevmonthyear} = 0;
$self->{nextmonthyear} = 0;
for (my $i=0; $i<=31; $i++) {
$self->{entries}->[$i] = [];
}
@@ -133,7 +133,7 @@ sub read_one_month
$line = $in->getline();
chomp($line);
if ($line =~ /^\S+ \S+ \S+ \S+ \S+ \S+ \S+$/) {
@{$self->{daynames}} = map { s/_/ /g; $_; } (split(/ /, $line));
@{$self->{daynames}} = map { s/_/ /g; $_; } (split(/ /, $line)); ## no critic
} else {
return (undef, "Cannot interpret line: $line");
}
@@ -212,7 +212,7 @@ hash keys found in the newer "remind -pp" JSON output.
sub parse_oldstyle_line
{
my ($self, $line) = @_;
return undef unless $line =~ m|^(\d+)/(\d+)/(\d+) (\S+) (\S+) (\S+) (\S+) (.*)$|;
return unless $line =~ m|^(\d+)/(\d+)/(\d+) (\S+) (\S+) (\S+) (\S+) (.*)$|;
my $hash = {
date => "$1-$2-$3",
@@ -243,6 +243,143 @@ sub parse_oldstyle_line
return $hash;
}
=head2 setup_daymap
Set up the array that maps ($row, $col) to day number (or -1
for rows/cols out of range.)
=cut
sub setup_daymap
{
my ($self, $settings) = @_;
# First column
my $first_col = $self->{firstwkday};
if ($self->{mondayfirst}) {
$first_col--;
if ($first_col < 0) {
$first_col = 6;
}
}
# Last column
my $last_col = ($first_col + $self->{daysinmonth} - 1) % 7;
# Number of rows
my $rows = 1;
my $last_day_on_row = 7 - $first_col;
while ($last_day_on_row < $self->{daysinmonth}) {
$last_day_on_row += 7;
$rows++;
}
# Add a row for small calendars if necessary
if (($settings->{small_calendars} != 0) && ($first_col == 0) && ($last_col == 6)) {
$rows++;
$self->{extra_row} = 1;
} else {
$self->{extra_row} = 0;
}
$self->{rows} = $rows;
$self->{daymap} = [];
$self->{first_col} = $first_col;
$self->{last_col} = $last_col;
for (my $row=0; $row<$rows; $row++) {
for (my $col=0; $col < 7; $col++) {
$self->{daymap}->[$row]->[$col] = -1;
}
}
$self->{nextcal_row} = -1;
$self->{prevcal_row} = -1;
$self->{nextcal_col} = 6;
$self->{prevcal_col} = 0;
# Figure out where to draw the small calendars
my $extra_row = $self->{extra_row};
if ($settings->{small_calendars} == 1) {
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
$self->{prevcal_row} = $rows-1;
$self->{prevcal_col} = 5;
$self->{nextcal_row} = $rows-1;
$self->{nextcal_col} = 6;
} else {
$self->{prevcal_row} = 0;
$self->{prevcal_col} = 0;
$self->{nextcal_row} = 0;
$self->{nextcal_col} = 1;
}
} elsif ($settings->{small_calendars} == 2) {
if ($first_col >= 2) {
$self->{prevcal_row} = 0;
$self->{prevcal_col} = 0;
$self->{nextcal_row} = 0;
$self->{nextcal_col} = 1;
} else {
$self->{prevcal_row} = $rows-1;
$self->{prevcal_col} = 5;
$self->{nextcal_row} = $rows-1;
$self->{nextcal_col} = 6;
}
} elsif ($settings->{small_calendars} == 3) {
if ($first_col >= 1 && $last_col <= 5) {
$self->{prevcal_row} = 0;
$self->{prevcal_col} = 0;
$self->{nextcal_row} = $rows-1;
$self->{nextcal_col} = 6;
} else {
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
$self->{prevcal_row} = $rows-1;
$self->{prevcal_col} = 5;
$self->{nextcal_row} = $rows-1;
$self->{nextcal_col} = 6;
} else {
$self->{prevcal_row} = 0;
$self->{prevcal_col} = 0;
$self->{nextcal_row} = 0;
$self->{nextcal_col} = 1;
}
}
}
my $col = $first_col;
my $row = 0;
my $day = 1;
while ($day <= $self->{daysinmonth}) {
$self->{daymap}->[$row]->[$col] = $day;
$day++;
$col++;
if ($col > 6) {
$row++;
$col = 0;
}
}
# Check if we should wrap the calendar
if ($self->{rows} == 6 && $settings->{wrap_calendar}) {
# Move everything in the last row to the first row
my $occupied_col = 0;
for (my $col=0; $col<7; $col++) {
if ($self->{daymap}->[5]->[$col] > 0) {
$self->{daymap}->[0]->[$col] = $self->{daymap}->[5]->[$col];
$occupied_col = $col;
} else {
last;
}
}
if ($settings->{small_calendars}) {
$self->{prevcal_row} = 0;
$self->{prevcal_col} = $occupied_col+1;
$self->{nextcal_row} = 0;
$self->{nextcal_col} = $occupied_col+2;
for (my $col = 6; $col > 0; $col--) {
if ($self->{daymap}->[0]->[$col] < 0) {
$self->{nextcal_col} = $col;
last;
}
}
}
$self->{rows} = 5;
}
}
=head2 read_one_month_pp($in, $specials_accepted)
This function reads one month's worth of data from the file handle
@@ -328,6 +465,7 @@ sub render
{
my ($self, $cr, $settings) = @_;
$self->setup_daymap($settings);
$self->{horiz_lines} = [];
$cr->set_line_cap('square');
my $so_far = $self->draw_title($cr, $settings);
@@ -346,111 +484,25 @@ sub render
$self->{remaining_space} = $settings->{height} - $settings->{margin_bottom} - $so_far;
$self->{minimum_row_height} = $self->{remaining_space} / 9;
# First column
my $first_col = $self->{firstwkday};
if ($self->{mondayfirst}) {
$first_col--;
if ($first_col < 0) {
$first_col = 6;
}
}
# Last column
my $last_col = ($first_col + $self->{daysinmonth} - 1) % 7;
# Number of rows
my $rows = 1;
my $last_day_on_row = 7 - $first_col;
while ($last_day_on_row < $self->{daysinmonth}) {
$last_day_on_row += 7;
$rows++;
}
my $extra_row = 0;
# Add a row for small calendars if necessary
if (($settings->{small_calendars} != 0) && ($first_col == 0) && ($last_col == 6)) {
$rows++;
$extra_row++;
}
# Figure out where to draw the small calendars
my $prevcal_top = 0;
my $nextcal_top = 0;
my $prevcal_bottom = 0;
my $nextcal_bottom = 0;
if ($settings->{small_calendars} == 1) {
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
$prevcal_bottom = 1;
$nextcal_bottom = 1;
} else {
$prevcal_top = 1;
$nextcal_top = 1;
}
} elsif ($settings->{small_calendars} == 2) {
if ($first_col >= 2) {
$prevcal_top = 1;
$nextcal_top = 1;
} else {
$prevcal_bottom = 1;
$nextcal_bottom = 1;
}
} elsif ($settings->{small_calendars} == 3) {
if ($first_col >= 1 && $last_col <= 5) {
$prevcal_top = 1;
$nextcal_bottom = 1;
} else {
if ($last_col <= 4 || ($last_col == 6 && $extra_row)) {
$prevcal_bottom = 1;
$nextcal_bottom = 1;
} else {
$prevcal_top = 1;
$nextcal_top = 1;
}
}
}
# Row height if we are filling the page
$self->{row_height} = $self->{remaining_space} / $rows;
$self->{row_height} = $self->{remaining_space} / $self->{rows};
my ($start_col, $start_day);
for (my $row = 0; $row < $rows; $row++) {
if ($row == 0) {
$start_day = 1;
$start_col = $first_col;
} else {
$start_col = 0;
}
for (my $row = 0; $row < $self->{rows}; $row++) {
my $old_so_far = $so_far;
$so_far = $self->draw_row($cr, $settings, $so_far, $row, $start_day, $start_col);
$start_day += 7 - $start_col;
$so_far = $self->draw_row($cr, $settings, $so_far, $row);
push(@{$self->{horiz_lines}}, $so_far);
if ($row == 0) {
if ($prevcal_top) {
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 0, $so_far - $old_so_far, $settings);
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
$settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($first_col + 35 - $self->{daysinprevmonth}) % 7);
}
if ($nextcal_top) {
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 1, $so_far - $old_so_far, $settings);
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
$settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($last_col + 1) % 7);
}
} elsif ($row == $rows-1) {
if ($prevcal_bottom) {
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 5, $so_far - $old_so_far, $settings);
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
$settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($first_col + 35 - $self->{daysinprevmonth}) % 7);
}
if ($nextcal_bottom) {
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, 6, $so_far - $old_so_far, $settings);
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
$settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($last_col + 1) % 7);
}
if ($row == $self->{prevcal_row}) {
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, $self->{prevcal_col}, $so_far - $old_so_far, $settings);
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
$settings, $self->{prevmonthname}, $self->{daysinprevmonth}, ($self->{first_col} + 35 - $self->{daysinprevmonth}) % 7);
}
if ($row == $self->{nextcal_row}) {
my ($x1, $y1, $x2, $y2) = $self->col_box_coordinates($old_so_far, $self->{nextcal_col}, $so_far - $old_so_far, $settings);
$self->draw_small_calendar($cr, $x1 + $settings->{border_size}, $y1 + $settings->{border_size},
$x2 - $x1 - 2*$settings->{border_size}, $y2 - $y1 - 2*$settings->{border_size},
$settings, $self->{nextmonthname}, $self->{daysinnextmonth}, ($self->{last_col} + 1) % 7);
}
}
@@ -494,23 +546,18 @@ calendar row.
=cut
sub draw_row
{
my ($self, $cr, $settings, $so_far, $row, $start_day, $start_col) = @_;
my ($self, $cr, $settings, $so_far, $row) = @_;
my $col = $start_col;
my $day = $start_day;
my $height = 0;
# Preview them to figure out the row height...
if (!$settings->{fill_entire_page}) {
while ($col < 7) {
for (my $col=0; $col<7; $col++) {
my $day = $self->{daymap}->[$row]->[$col];
next if ($day < 1);
my $h = $self->draw_day($cr, $settings, $so_far, $day, $col, 0);
$height = $h if ($h > $height);
$day++;
$col++;
last if ($day > $self->{daysinmonth});
}
$col = $start_col;
$day = $start_day;
} else {
$height = $self->{row_height} - $settings->{border_size} * 2;
}
@@ -519,10 +566,10 @@ sub draw_row
$height = $self->{minimum_row_height};
}
# Now draw for real
while ($col < 7 && $day <= $self->{daysinmonth}) {
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);
$day++;
$col++;
}
return $so_far + $height + $settings->{border_size};
@@ -907,7 +954,7 @@ sub create_from_stream
return(undef, 'Unable to parse JSON stream');
}
=head2 Remind::PDF::Multi->create_from_stream($json, $specials_accepted)
=head2 Remind::PDF::Multi->create_from_json($json, $specials_accepted)
This method takes data from a JSON string <$json>. C<$specials_accepted>
is a hashref of SPECIAL reminder types to accept; the key is the name of the

View File

@@ -1,4 +1,5 @@
package Remind::PDF::Entry;
# SPDX-License-Identifier: GPL-2.0-only
use strict;
use warnings;

View File

@@ -1,5 +1,6 @@
#!/bin/sh
# -*-Mode: TCL;-*-
# SPDX-License-Identifier: GPL-2.0-only
#--------------------------------------------------------------
# TKREMIND
@@ -7,7 +8,7 @@
# A cheesy graphical front/back end for Remind using Tcl/Tk
#
# This file is part of REMIND.
# Copyright (C) 1992-2022 Dianne Skoll
# Copyright (C) 1992-2023 Dianne Skoll
#
#--------------------------------------------------------------
@@ -239,6 +240,9 @@ set Option(PrintOrient) landscape
set OptDescr(PrintFill) "(0/1) If 1, fill entire page when printing"
set Option(PrintFill) 1
set OptDescr(WrapCal) "(0/1) If 1, make printed calendars occupy at most 5 rows"
set Option(WrapCal) 0
set OptDescr(PrintDaysRight) "(0/1) If 1, put day numbers in the top-right of each calendar box"
set Option(PrintDaysRight) 1
@@ -955,6 +959,7 @@ proc WriteOptionsToFile {} {
#***********************************************************************
proc LoadOptions {} {
global Option ConfigFile
global MondayFirst
set problem [catch {set f [open "$ConfigFile" "r"]}]
if {$problem} {
return
@@ -974,6 +979,9 @@ proc LoadOptions {} {
set Option($key) $val
}
close $f
if {[regexp -- {-m.*} $Option(ExtraRemindArgs)]} {
set MondayFirst 1
}
font configure CalboxFont {*}$Option(CalboxFont)
font configure HeadingFont {*}$Option(HeadingFont)
}
@@ -1285,6 +1293,7 @@ proc DoPrint {} {
radiobutton .p.portrait -text "Portrait" -variable Option(PrintOrient) -value portrait
checkbutton .p.fill -text "Fill page" -variable Option(PrintFill)
checkbutton .p.wrap -text "Use at most 5 rows (PDF only)" -variable Option(WrapCal)
checkbutton .p.right -text "Day numbers at top-right" -variable Option(PrintDaysRight)
checkbutton .p.encoding -text "ISO 8859-1 PostScript encoding" -variable Option(PrintEncoding)
checkbutton .p.calendars -text "Print small calendars" -variable Option(PrintSmallCalendars)
@@ -1295,12 +1304,14 @@ proc DoPrint {} {
if {$HaveRem2PDF} {
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.encoding .p.calendars -in .p.f3a \
-side top -anchor w -fill none -expand 0
} else {
pack .p.f1 .p.f2 .p.f2a .p.f3 .p.f3a \
-side top -fill both -expand 1 -anchor w
}
pack .p.fill .p.right .p.encoding .p.calendars -in .p.f3a \
pack .p.fill .p.right .p.encoding .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
pack .p.tofile .p.filename .p.browse -in .p.f11 -side left -fill none -expand 0 -anchor w
@@ -1393,6 +1404,11 @@ proc DoPrint {} {
}
}
if {$Option(WrapCal)} {
if {$Option(PrintFormat) == "pdf"} {
append cmd " --wrap"
}
}
if {$Option(PrintOrient) == "landscape"} {
append cmd " -l"
}
@@ -3321,7 +3337,9 @@ proc EditableEnter { w } {
set c [$w tag cget $ctag -foreground]
}
if {"$c" != ""} {
$w tag configure $tag -underline 1 -underlinefg $c
$w tag configure $tag -underline 1
# underlinefg not supported on older versions of Tk
eval { $w tag configure $tag -underlinefg $c }
} else {
$w tag configure $tag -underline 1
}
@@ -3628,7 +3646,9 @@ proc DoShadeSpecial { n r g b } {
#***********************************************************************
proc DoMoonSpecial { n stuff fntag day } {
set msg ""
set num [scan $stuff "%d %d %d %s" phase junk1 junk2 msg]
# Yes, this is gross, but the odds of ctrl-A appearing
# in the text associated with a MOON are small.
set num [scan $stuff {%d %d %d %[^]} phase junk1 junk2 msg]
if {$num < 1} {
return
}
@@ -3819,13 +3839,19 @@ proc ShowTodaysReminders {} {
append cmdline "-b1 "
}
append cmdline $Option(ExtraRemindArgs);
append cmdline " $ReminderFile 2>/dev/null"
append cmdline " $ReminderFile 2>@1"
set f [open $cmdline r]
while {[gets $f line] >= 0} {
append stuff "$line\n"
}
close $f
$w.text insert end $stuff
if {[catch { close $f } err]} {
$w.text insert end "Error running Remind\n\n"
$w.text insert end $stuff
$w.text insert end "\n"
$w.text insert end $err
} else {
$w.text insert end $stuff
}
$w.text configure -state disabled
}
@@ -3913,7 +3939,7 @@ proc InotifyReadable { fp } {
catch { set num [gets $fp line] }
if {$num < 0} {
catch { exec kill [pid $fp] }
close $fp
catch { close $fp }
return
}
ScheduleUpdateForChanges

View File

@@ -71,6 +71,9 @@ install-stripped: install
clean:
rm -f *.o *~ core *.bak $(PROGS)
cppcheck:
cppcheck --force --enable=all --suppress=variableScope --suppress=ConfigurationNotChecked *.c
clobber:
rm -f *.o *~ remind rem2ps test.out core *.bak

View File

@@ -5,7 +5,8 @@
/* The code for generating a calendar. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -286,23 +287,23 @@ static void WriteWeekHeaderLine (void);
static void WritePostHeaderLine (void);
static void PrintLeft (char const *s, int width, char pad);
static void PrintCentered (char const *s, int width, char *pad);
static int WriteOneCalLine (int jul, int wd);
static int WriteOneCalLine (int dse, int wd);
static int WriteOneColLine (int col);
static void GenerateCalEntries (int col);
static void WriteCalHeader (void);
static void WriteCalTrailer (void);
static int DoCalRem (ParsePtr p, int col);
static void WriteSimpleEntries (int col, int jul);
static void WriteSimpleEntries (int col, int dse);
static void WriteTopCalLine (void);
static void WriteBottomCalLine (void);
static void WriteIntermediateCalLine (void);
static void WriteCalDays (void);
static int
DayOf(int jul)
DayOf(int dse)
{
int d;
FromJulian(jul, NULL, NULL, &d);
FromDSE(dse, NULL, NULL, &d);
return d;
}
@@ -426,14 +427,14 @@ void PrintJSONKeyPairString(char const *name, char const *val)
printf("\",");
}
void PrintJSONKeyPairDate(char const *name, int jul)
void PrintJSONKeyPairDate(char const *name, int dse)
{
int y, m, d;
if (jul == NO_DATE) {
if (dse == NO_DATE) {
/* Skip it! */
return;
}
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
printf("\"");
PrintJSONString(name);
printf("\":\"%04d-%02d-%02d\",", y, m+1, d);
@@ -448,7 +449,7 @@ void PrintJSONKeyPairDateTime(char const *name, int dt)
return;
}
i = dt / MINUTES_PER_DAY;
FromJulian(i, &y, &m, &d);
FromDSE(i, &y, &m, &d);
k = dt % MINUTES_PER_DAY;
h = k / 60;
i = k % 60;
@@ -496,7 +497,7 @@ get_month_abbrev(char const *mon)
return buf;
#else
char *s;
wchar_t tmp_buf[128];
wchar_t tmp_buf[128] = {0};
wchar_t *ws;
int i;
int len;
@@ -620,7 +621,6 @@ Colorize256(int r, int g, int b, int bg, int clamp)
best = (int) i;
}
}
cur = &XTerm256Colors[best];
if (bg) {
sprintf(buf, "\x1B[48;5;%dm", best);
} else {
@@ -714,7 +714,7 @@ InitMoonsAndShades(void)
}
static void
SetShadeEntry(int jul, char const *shade)
SetShadeEntry(int dse, char const *shade)
{
int y, m, d;
int r, g, b;
@@ -733,14 +733,14 @@ SetShadeEntry(int jul, char const *shade)
if (r < 0 || g < 0 || b < 0 || r > 255 || g > 255 || b > 255) {
return;
}
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
bgcolor[d][0] = r;
bgcolor[d][1] = g;
bgcolor[d][2] = b;
}
static void
SetMoonEntry(int jul, char const *moon)
SetMoonEntry(int dse, char const *moon)
{
int phase;
int y, m, d;
@@ -764,7 +764,7 @@ SetMoonEntry(int jul, char const *moon)
fprintf(stderr, "Oops 2\n");
return;
}
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
if (msg[0]) {
snprintf(moons[d], sizeof(moons[d]), "%s %s", moonphase_emojis[phase], msg);
} else {
@@ -806,8 +806,8 @@ void ProduceCalendar(void)
/* Run the file once to get potentially-overridden day names */
if (CalMonths) {
FromJulian(JulianToday, &y, &m, &d);
JulianToday = Julian(y, m, 1);
FromDSE(DSEToday, &y, &m, &d);
DSEToday = DSE(y, m, 1);
GenerateCalEntries(-1);
DidAMonth = 0;
if (PsCal == PSCAL_LEVEL3) {
@@ -822,8 +822,8 @@ void ProduceCalendar(void)
}
return;
} else {
if (MondayFirst) JulianToday -= (JulianToday%7);
else JulianToday -= ((JulianToday+1)%7);
if (MondayFirst) DSEToday -= (DSEToday%7);
else DSEToday -= ((DSEToday+1)%7);
GenerateCalEntries(-1);
@@ -851,26 +851,26 @@ static void DoCalendarOneWeek(int nleft)
int y, m, d, done, i, l, wd;
char buf[128];
int LinesWritten = 0;
int OrigJul = JulianToday;
int OrigDse = DSEToday;
InitMoonsAndShades();
/* Fill in the column entries */
for (i=0; i<7; i++) {
ColToDay[i] = DayOf(JulianToday);
ColToDay[i] = DayOf(DSEToday);
GenerateCalEntries(i);
JulianToday++;
DSEToday++;
}
/* Figure out weekday of first column */
if (MondayFirst) wd = JulianToday % 7;
else wd = (JulianToday + 1) % 7;
if (MondayFirst) wd = DSEToday % 7;
else wd = (DSEToday + 1) % 7;
/* Output the entries */
/* If it's "Simple Calendar" format, do it simply... */
if (DoSimpleCalendar) {
for (i=0; i<7; i++) {
WriteSimpleEntries(i, OrigJul+i-wd);
WriteSimpleEntries(i, OrigDse+i-wd);
}
return;
}
@@ -880,7 +880,7 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
FromJulian(OrigJul+i, &y, &m, &d);
FromDSE(OrigDse+i, &y, &m, &d);
char const *mon = get_month_name(m);
if (moons[d][0]) {
if (weeks[d][0]) {
@@ -895,7 +895,7 @@ static void DoCalendarOneWeek(int nleft)
snprintf(buf, sizeof(buf), "%d %s ", d, get_month_abbrev(mon));
}
}
if (OrigJul+i == RealToday) {
if (OrigDse+i == RealToday) {
if (UseVTColors) {
printf("\x1B[1m"); /* Bold */
}
@@ -931,7 +931,7 @@ static void DoCalendarOneWeek(int nleft)
/* Write the body lines */
done = 0;
while (!done) {
done = WriteOneCalLine(OrigJul, wd);
done = WriteOneCalLine(OrigDse, wd);
LinesWritten++;
}
@@ -978,7 +978,7 @@ static void DoCalendarOneMonth(void)
DidADay = 0;
if (PsCal) {
FromJulian(JulianToday, &y, &m, &d);
FromDSE(DSEToday, &y, &m, &d);
if (PsCal == PSCAL_LEVEL1) {
printf("%s\n", PSBEGIN);
} else if (PsCal == PSCAL_LEVEL2) {
@@ -991,7 +991,7 @@ static void DoCalendarOneMonth(void)
}
if (PsCal < PSCAL_LEVEL3) {
printf("%s %d %d %d %d\n",
despace(get_month_name(m)), y, DaysInMonth(m, y), (JulianToday+1) % 7,
despace(get_month_name(m)), y, DaysInMonth(m, y), (DSEToday+1) % 7,
MondayFirst);
for (i=0; i<7; i++) {
j=(i+6)%7;
@@ -1006,7 +1006,7 @@ static void DoCalendarOneMonth(void)
PrintJSONKeyPairString("monthname", get_month_name(m));
PrintJSONKeyPairInt("year", y);
PrintJSONKeyPairInt("daysinmonth", DaysInMonth(m, y));
PrintJSONKeyPairInt("firstwkday", (JulianToday+1) % 7);
PrintJSONKeyPairInt("firstwkday", (DSEToday+1) % 7);
PrintJSONKeyPairInt("mondayfirst", MondayFirst);
printf("\"daynames\":[\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"],",
get_day_name(6), get_day_name(0), get_day_name(1), get_day_name(2),
@@ -1064,14 +1064,14 @@ static int WriteCalendarRow(void)
int y, m, d, wd, i, l;
int done;
char buf[81];
int OrigJul = JulianToday;
int OrigDse = DSEToday;
int LinesWritten = 0;
int moreleft;
/* Get the date of the first day */
FromJulian(JulianToday, &y, &m, &d);
if (!MondayFirst) wd = (JulianToday + 1) % 7;
else wd = JulianToday % 7;
FromDSE(DSEToday, &y, &m, &d);
if (!MondayFirst) wd = (DSEToday + 1) % 7;
else wd = DSEToday % 7;
for (i=0; i<7; i++) {
ColToDay[i] = 0;
@@ -1081,8 +1081,8 @@ static int WriteCalendarRow(void)
for (i=wd; i<7; i++) {
if (d+i-wd > DaysInMonth(m, y)) break;
GenerateCalEntries(i);
ColToDay[i] = DayOf(JulianToday);
JulianToday++;
ColToDay[i] = DayOf(DSEToday);
DSEToday++;
}
/* Output the entries */
@@ -1090,7 +1090,7 @@ static int WriteCalendarRow(void)
/* If it's "Simple Calendar" format, do it simply... */
if (DoSimpleCalendar) {
for (i=wd; i<7 && d+i-wd<=DaysInMonth(m, y); i++) {
WriteSimpleEntries(i, OrigJul+i-wd);
WriteSimpleEntries(i, OrigDse+i-wd);
}
return (d+7-wd <= DaysInMonth(m, y));
}
@@ -1117,7 +1117,7 @@ static int WriteCalendarRow(void)
snprintf(buf, sizeof(buf), "%d ", d+i-wd);
}
}
if (Julian(y, m, d+i-wd) == RealToday) {
if (DSE(y, m, d+i-wd) == RealToday) {
if (UseVTColors) {
printf("\x1B[1m"); /* Bold */
}
@@ -1153,7 +1153,7 @@ static int WriteCalendarRow(void)
/* Write the body lines */
done = 0;
while (!done) {
done = WriteOneCalLine(OrigJul, wd);
done = WriteOneCalLine(OrigDse, wd);
LinesWritten++;
}
@@ -1336,7 +1336,7 @@ static void PrintCentered(char const *s, int width, char *pad)
/* Write a single line. */
/* */
/***************************************************************/
static int WriteOneCalLine(int start_jul, int wd)
static int WriteOneCalLine(int start_dse, int wd)
{
int done = 1, i;
int y, m, d;
@@ -1345,7 +1345,7 @@ static int WriteOneCalLine(int start_jul, int wd)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
FromJulian(start_jul+i, &y, &m, &d);
FromDSE(start_dse+i, &y, &m, &d);
d -= wd;
if (CalColumn[i]) {
Backgroundize(ColToDay[i]);
@@ -1702,7 +1702,7 @@ static void WriteCalHeader(void)
char buf[80];
int y, m, d;
FromJulian(JulianToday, &y, &m, &d);
FromDSE(DSEToday, &y, &m, &d);
sprintf(buf, "%s %d", get_month_name(m), y);
WriteTopCalLine();
@@ -1745,7 +1745,7 @@ static int DoCalRem(ParsePtr p, int col)
TimeTrig tim;
Value v;
int r, err;
int jul;
int dse;
CalEntry *CurCol;
CalEntry *e;
char const *s, *s2;
@@ -1830,6 +1830,10 @@ static int DoCalRem(ParsePtr p, int col)
DBufFree(&buf);
}
trig.typ = tok.val;
/* Convert some SPECIALs back to plain types */
FixSpecialType(&trig);
if (trig.typ == MSG_TYPE ||
trig.typ == CAL_TYPE ||
trig.typ == MSF_TYPE) {
@@ -1843,14 +1847,14 @@ static int DoCalRem(ParsePtr p, int col)
col_b = DefaultColorB;
}
}
jul = LastTriggerDate;
dse = LastTriggerDate;
if (!LastTrigValid) {
FreeTrig(&trig);
return OK;
}
} else {
/* Calculate the trigger date */
jul = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
if (r) {
if (r == E_CANT_TRIG && trig.maybe_uncomputable) {
r = OK;
@@ -1862,7 +1866,7 @@ static int DoCalRem(ParsePtr p, int col)
/* Add to global OMITs if so indicated */
if (trig.addomit) {
r = AddGlobalOmit(jul);
r = AddGlobalOmit(dse);
if (r) {
FreeTrig(&trig);
return r;
@@ -1907,28 +1911,28 @@ static int DoCalRem(ParsePtr p, int col)
}
if (trig.typ == PASSTHRU_TYPE) {
if (!PsCal && !StrCmpi(trig.passthru, "SHADE")) {
if (jul == JulianToday) {
if (dse == DSEToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
r = DoSubst(p, &obuf, &trig, &tim, dse, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
SetShadeEntry(jul, DBufValue(&obuf));
SetShadeEntry(dse, DBufValue(&obuf));
DBufFree(&obuf);
}
}
if (!PsCal && !StrCmpi(trig.passthru, "WEEK")) {
if (jul == JulianToday) {
if (dse == DSEToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
r = DoSubst(p, &obuf, &trig, &tim, dse, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
sscanf(DBufValue(&obuf), "%31[^\x01]", weeks[DayOf(jul)]);
sscanf(DBufValue(&obuf), "%31[^\x01]", weeks[DayOf(dse)]);
DBufFree(&obuf);
}
}
@@ -1937,15 +1941,15 @@ static int DoCalRem(ParsePtr p, int col)
return OK;
}
if (!PsCal && !StrCmpi(trig.passthru, "MOON")) {
if (jul == JulianToday) {
if (dse == DSEToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
r = DoSubst(p, &obuf, &trig, &tim, dse, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
SetMoonEntry(jul, DBufValue(&obuf));
SetMoonEntry(dse, DBufValue(&obuf));
DBufFree(&obuf);
}
}
@@ -1994,9 +1998,9 @@ static int DoCalRem(ParsePtr p, int col)
/* If trigger date == today, add it to the current entry */
DBufInit(&obuf);
if ((jul == JulianToday) ||
if ((dse == DSEToday) ||
(DoSimpleCalDelta &&
ShouldTriggerReminder(&trig, &tim, jul, &err))) {
ShouldTriggerReminder(&trig, &tim, dse, &err))) {
NumTriggered++;
/* The parse_ptr should not be nested, but just in case... */
@@ -2010,7 +2014,7 @@ static int DoCalRem(ParsePtr p, int col)
}
if (DoSimpleCalendar || tim.ttime != NO_TIME) {
/* Suppress time if it's not today or if it's a non-COLOR special */
if (jul != JulianToday ||
if (dse != DSEToday ||
(trig.typ == PASSTHRU_TYPE &&
StrCmpi(trig.passthru, "COLOUR") &&
StrCmpi(trig.passthru, "COLOR"))) {
@@ -2055,10 +2059,10 @@ static int DoCalRem(ParsePtr p, int col)
/* In -sa mode, run in ADVANCE mode if we're triggering
* before the actual date */
if (jul != JulianToday) {
r = DoSubst(p, &obuf, &trig, &tim, jul, ADVANCE_MODE);
if (dse != DSEToday) {
r = DoSubst(p, &obuf, &trig, &tim, dse, ADVANCE_MODE);
} else {
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
r = DoSubst(p, &obuf, &trig, &tim, dse, CAL_MODE);
}
if (r) {
DBufFree(&pre_buf);
@@ -2159,7 +2163,7 @@ static int DoCalRem(ParsePtr p, int col)
e->passthru[0] = 0;
}
e->pos = e->text;
if (jul == JulianToday) {
if (dse == DSEToday) {
e->time = tim.ttime;
} else {
e->time = NO_TIME;
@@ -2385,13 +2389,13 @@ static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
/* Write entries in 'simple calendar' format. */
/* */
/***************************************************************/
static void WriteSimpleEntries(int col, int jul)
static void WriteSimpleEntries(int col, int dse)
{
CalEntry *e = CalColumn[col];
CalEntry *n;
int y, m, d;
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
while(e) {
if (DoPrefixLineNo) {
if (PsCal != PSCAL_LEVEL2 && PsCal != PSCAL_LEVEL3) {
@@ -2406,7 +2410,7 @@ static void WriteSimpleEntries(int col, int jul)
}
DidADay = 1;
printf("{\"date\":\"%04d-%02d-%02d\",", y, m+1, d);
WriteSimpleEntryProtocol2(e, jul);
WriteSimpleEntryProtocol2(e, dse);
printf("}");
if (PsCal != PSCAL_LEVEL3) {
printf("\n");

View File

@@ -6,7 +6,8 @@
/* which you can customize. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -6,7 +6,8 @@
/* which you can customize. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -7,7 +7,8 @@
/* commands. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -29,7 +30,7 @@ static int ParseLocalOmit (ParsePtr s, Trigger *t);
static int ParseScanFrom (ParsePtr s, Trigger *t, int type);
static int ParsePriority (ParsePtr s, Trigger *t);
static int ParseUntil (ParsePtr s, Trigger *t, int type);
static int ShouldTriggerBasedOnWarn (Trigger *t, int jul, int *err);
static int ShouldTriggerBasedOnWarn (Trigger *t, int dse, int *err);
static int ComputeTrigDuration(TimeTrig *t);
static int
@@ -55,7 +56,7 @@ int DoRem(ParsePtr p)
Trigger trig;
TimeTrig tim;
int r, err;
int jul;
int dse;
DynamicBuffer buf;
Token tok;
@@ -122,16 +123,20 @@ int DoRem(ParsePtr p)
}
StrnCpy(trig.passthru, DBufValue(&buf), PASSTHRU_LEN);
DBufFree(&buf);
}
trig.typ = tok.val;
jul = LastTriggerDate;
}
trig.typ = tok.val;
/* Convert some SPECIALs back to plain types */
FixSpecialType(&trig);
dse = LastTriggerDate;
if (!LastTrigValid || PurgeMode) {
FreeTrig(&trig);
return OK;
}
} else {
/* Calculate the trigger date */
jul = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
if (r) {
if (PurgeMode) {
PurgeEchoLine("%s: %s\n", "#!P! Problem calculating trigger date", ErrMsg[r]);
@@ -147,14 +152,14 @@ int DoRem(ParsePtr p)
/* Add to global OMITs if so indicated */
if (trig.addomit) {
r = AddGlobalOmit(jul);
r = AddGlobalOmit(dse);
if (r) {
FreeTrig(&trig);
return r;
}
}
if (PurgeMode) {
if (trig.expired || jul < JulianToday) {
if (trig.expired || dse < DSEToday) {
if (p->expr_happened) {
if (p->nonconst_expr) {
PurgeEchoLine("%s\n", "#!P: Next line may have expired, but contains non-constant expression");
@@ -174,10 +179,10 @@ int DoRem(ParsePtr p)
}
/* Queue the reminder, if necessary */
if (jul == JulianToday &&
if (dse == DSEToday &&
!(!IgnoreOnce &&
trig.once != NO_ONCE &&
FileAccessDate == JulianToday))
FileAccessDate == DSEToday))
QueueReminder(p, &trig, &tim, trig.sched);
/* If we're in daemon mode, do nothing over here */
if (Daemon) {
@@ -186,8 +191,8 @@ int DoRem(ParsePtr p)
}
r = OK;
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
if ( (r=TriggerReminder(p, &trig, &tim, jul)) ) {
if (ShouldTriggerReminder(&trig, &tim, dse, &err)) {
if ( (r=TriggerReminder(p, &trig, &tim, dse, 0)) ) {
FreeTrig(&trig);
return r;
}
@@ -234,6 +239,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
trig->skip = NO_SKIP;
trig->once = NO_ONCE;
trig->addomit = 0;
trig->noqueue = 0;
trig->typ = NO_TYPE;
trig->scanfrom = NO_DATE;
trig->from = NO_DATE;
@@ -291,7 +297,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
if (trig->d != NO_DAY) return E_DAY_TWICE;
if (trig->m != NO_MON) return E_MON_TWICE;
if (trig->y != NO_YR) return E_YR_TWICE;
FromJulian(tok.val, &y, &m, &d);
FromDSE(tok.val, &y, &m, &d);
trig->y = y;
trig->m = m;
trig->d = d;
@@ -302,7 +308,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
if (trig->d != NO_DAY) return E_DAY_TWICE;
if (trig->m != NO_MON) return E_MON_TWICE;
if (trig->y != NO_YR) return E_YR_TWICE;
FromJulian(tok.val / MINUTES_PER_DAY, &y, &m, &d);
FromDSE(tok.val / MINUTES_PER_DAY, &y, &m, &d);
trig->y = y;
trig->m = m;
trig->d = d;
@@ -368,6 +374,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
}
StrnCpy(trig->passthru, DBufValue(&buf), PASSTHRU_LEN);
}
FixSpecialType(trig);
parsing = 0;
break;
@@ -435,6 +442,11 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
trig->addomit = 1;
break;
case T_NoQueue:
DBufFree(&buf);
trig->noqueue = 1;
break;
case T_Omit:
DBufFree(&buf);
if (trig->omitfunc[0]) {
@@ -552,7 +564,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
/* Check for some warning conditions */
if (!s->nonconst_expr) {
if (trig->y != NO_YR && trig->m != NO_MON && trig->d != NO_DAY && trig->until != NO_UNTIL) {
if (Julian(trig->y, trig->m, trig->d) > trig->until) {
if (DSE(trig->y, trig->m, trig->d) > trig->until) {
Wprint("Warning: UNTIL/THROUGH date earlier than start date");
}
}
@@ -573,7 +585,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
/* Set scanfrom to default if not set explicitly */
if (trig->scanfrom == NO_DATE) {
trig->scanfrom = JulianToday;
trig->scanfrom = DSEToday;
}
return OK;
@@ -732,7 +744,7 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
return E_DAY_TWICE;
}
FromJulian(tok.val, &y, &m, &d);
FromDSE(tok.val, &y, &m, &d);
break;
default:
@@ -745,7 +757,7 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
DBufFree(&buf);
return E_BAD_DATE;
}
t->until = Julian(y, m, d);
t->until = DSE(y, m, d);
PushToken(DBufValue(&buf), s);
DBufFree(&buf);
return OK;
@@ -824,7 +836,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
Eprint("%s: %s", word, ErrMsg[E_DAY_TWICE]);
return E_DAY_TWICE;
}
FromJulian(tok.val, &y, &m, &d);
FromDSE(tok.val, &y, &m, &d);
break;
case T_Back:
@@ -848,7 +860,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
if (tok.val < 0) {
tok.val = -tok.val;
}
FromJulian(JulianToday - tok.val, &y, &m, &d);
FromDSE(DSEToday - tok.val, &y, &m, &d);
break;
default:
@@ -861,11 +873,11 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
DBufFree(&buf);
return E_BAD_DATE;
}
t->scanfrom = Julian(y, m, d);
t->scanfrom = DSE(y, m, d);
if (type == FROM_TYPE) {
t->from = t->scanfrom;
if (t->scanfrom < JulianToday) {
t->scanfrom = JulianToday;
if (t->scanfrom < DSEToday) {
t->scanfrom = DSEToday;
}
} else {
t->from = NO_DATE;
@@ -886,7 +898,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
/* Trigger the reminder if it's a RUN or MSG type. */
/* */
/***************************************************************/
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued)
{
int r, y, m, d;
char PrioExpr[VAR_NAME_LEN+25];
@@ -894,8 +906,21 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
DynamicBuffer buf, calRow;
DynamicBuffer pre_buf;
char const *s;
char const *msg_command = NULL;
Value v;
if (MsgCommand) {
msg_command = MsgCommand;
}
if (is_queued && QueuedMsgCommand) {
msg_command = QueuedMsgCommand;
}
/* A null command is no command */
if (msg_command && !*msg_command) {
msg_command = NULL;
}
int red = -1, green = -1, blue = -1;
int is_color = 0;
@@ -940,10 +965,10 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
}
/* If it's a MSG-type reminder, and no -k option was used, issue the banner. */
if ((t->typ == MSG_TYPE || t->typ == MSF_TYPE)
&& !DidMsgReminder && !NextMode && !MsgCommand) {
&& !DidMsgReminder && !NextMode && !msg_command) {
DidMsgReminder = 1;
if (!DoSubstFromString(DBufValue(&Banner), &buf,
JulianToday, NO_TIME) &&
DSEToday, NO_TIME) &&
DBufLen(&buf)) {
printf("%s\n", DBufValue(&buf));
}
@@ -953,13 +978,13 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
/* If it's NextMode, process as a ADVANCE_MODE-type entry, and issue
simple-calendar format. */
if (NextMode) {
if ( (r=DoSubst(p, &buf, t, tim, jul, ADVANCE_MODE)) ) return r;
if ( (r=DoSubst(p, &buf, t, tim, dse, ADVANCE_MODE)) ) return r;
if (!DBufLen(&buf)) {
DBufFree(&buf);
DBufFree(&pre_buf);
return OK;
}
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
sprintf(tmpBuf, "%04d/%02d/%02d ", y, m+1, d);
if (DBufPuts(&calRow, tmpBuf) != OK) {
DBufFree(&calRow);
@@ -1058,7 +1083,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
if (is_color) {
DBufPuts(&buf, Colorize(red, green, blue, 0, 1));
}
if ( (r=DoSubst(p, &buf, t, tim, jul, NORMAL_MODE)) ) return r;
if ( (r=DoSubst(p, &buf, t, tim, dse, NORMAL_MODE)) ) return r;
if (t->typ != RUN_TYPE) {
if (UserFuncExists("msgsuffix") == 1) {
sprintf(PrioExpr, "msgsuffix(%d)", t->priority);
@@ -1084,7 +1109,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
DBufPuts(&buf, Decolorize());
}
if ((!MsgCommand && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {
if ((!msg_command && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {
if (DBufPutc(&buf, '\n') != OK) {
DBufFree(&buf);
return E_NO_MEM;
@@ -1093,7 +1118,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
/* If we are sorting, just queue it up in the sort buffer */
if (SortByDate) {
if (InsertIntoSortBuffer(jul, tim->ttime, DBufValue(&buf),
if (InsertIntoSortBuffer(dse, tim->ttime, DBufValue(&buf),
t->typ, t->priority) == OK) {
DBufFree(&buf);
NumTriggered++;
@@ -1106,8 +1131,8 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
switch(t->typ) {
case MSG_TYPE:
case PASSTHRU_TYPE:
if (MsgCommand) {
DoMsgCommand(MsgCommand, DBufValue(&buf));
if (msg_command) {
DoMsgCommand(msg_command, DBufValue(&buf));
} else {
printf("%s", DBufValue(&buf));
}
@@ -1140,20 +1165,20 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
/* triggered. Sets *err non-zero in event of an error. */
/* */
/***************************************************************/
int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul, int *err)
int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int dse, int *err)
{
int r, omit;
*err = 0;
/* Handle the ONCE modifier in the reminder. */
if (!IgnoreOnce && t->once !=NO_ONCE && FileAccessDate == JulianToday)
if (!IgnoreOnce && t->once !=NO_ONCE && FileAccessDate == DSEToday)
return 0;
if (jul < JulianToday) return 0;
if (dse < DSEToday) return 0;
/* Don't trigger timed reminders if DontIssueAts is true, and if the
reminder is for today */
if (jul == JulianToday && DontIssueAts && tim->ttime != NO_TIME) {
if (dse == DSEToday && DontIssueAts && tim->ttime != NO_TIME) {
if (DontIssueAts > 1) {
/* If two or more -a options, then *DO* issue ats that are in the
future */
@@ -1167,7 +1192,7 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul, int *err)
/* Don't trigger "old" timed reminders */
/*** REMOVED...
if (jul == JulianToday &&
if (dse == DSEToday &&
tim->ttime != NO_TIME &&
tim->ttime < SystemTime(0) / 60) return 0;
*** ...UNTIL HERE */
@@ -1178,28 +1203,28 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul, int *err)
/* If there's a "warn" function, it overrides any deltas */
if (t->warn[0] != 0) {
if (DeltaOffset) {
if (jul <= JulianToday + DeltaOffset) {
if (dse <= DSEToday + DeltaOffset) {
return 1;
}
}
return ShouldTriggerBasedOnWarn(t, jul, err);
return ShouldTriggerBasedOnWarn(t, dse, err);
}
/* Move back by delta days, if any */
if (t->delta != NO_DELTA) {
if (t->delta < 0)
jul = jul + t->delta;
dse = dse + t->delta;
else {
int iter = 0;
int max = MaxSatIter;
r = t->delta;
if (max < r*2) max = r*2;
while(iter++ < max) {
if (!r || (jul <= JulianToday)) {
if (!r || (dse <= DSEToday)) {
break;
}
jul--;
*err = IsOmitted(jul, t->localomit, t->omitfunc, &omit);
dse--;
*err = IsOmitted(dse, t->localomit, t->omitfunc, &omit);
if (*err) return 0;
if (!omit) r--;
}
@@ -1212,7 +1237,7 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul, int *err)
}
/* Should we trigger the reminder? */
return (jul <= JulianToday + DeltaOffset);
return (dse <= DSEToday + DeltaOffset);
}
/***************************************************************/
@@ -1224,7 +1249,7 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul, int *err)
/***************************************************************/
int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
{
int iter, jul, r, start;
int iter, dse, r, start;
Value v;
char const *s;
char const *t;
@@ -1233,25 +1258,25 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
iter = 0;
start = trig->scanfrom;
while (iter++ < MaxSatIter) {
jul = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1, 0);
dse = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1, 0);
if (r) {
if (r == E_CANT_TRIG) return OK; else return r;
}
if (jul != start && trig->duration_days) {
jul = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1, trig->duration_days);
if (dse != start && trig->duration_days) {
dse = ComputeTriggerNoAdjustDuration(start, trig, tt, &r, 1, trig->duration_days);
if (r) {
if (r == E_CANT_TRIG) return OK; else return r;
}
} else if (jul == start) {
} else if (dse == start) {
if (tt->ttime != NO_TIME) {
trig->eventstart = MINUTES_PER_DAY * r + tt->ttime;
if (tt->duration != NO_TIME) {
trig->eventduration = tt->duration;
}
}
SaveAllTriggerInfo(trig, tt, jul, tt->ttime, 1);
SaveAllTriggerInfo(trig, tt, dse, tt->ttime, 1);
}
if (jul == -1) {
if (dse == -1) {
return E_EXPIRED;
}
s = p->pos;
@@ -1261,10 +1286,10 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
if (v.type != INT_TYPE && v.type != STR_TYPE) return E_BAD_TYPE;
if ((v.type == INT_TYPE && v.v.val) ||
(v.type == STR_TYPE && *v.v.str)) {
AdjustTriggerForDuration(trig->scanfrom, jul, trig, tt, 1);
AdjustTriggerForDuration(trig->scanfrom, dse, trig, tt, 1);
if (DebugFlag & DB_PRTTRIG) {
int y, m, d;
FromJulian(LastTriggerDate, &y, &m, &d);
FromDSE(LastTriggerDate, &y, &m, &d);
fprintf(ErrFp, "%s(%d): Trig(satisfied) = %s, %d %s, %d",
FileName, LineNo,
get_day_name(LastTriggerDate % 7),
@@ -1286,10 +1311,10 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
return OK;
}
p->pos = s;
if (jul+trig->duration_days < start) {
if (dse+trig->duration_days < start) {
start++;
} else {
start = jul+trig->duration_days+1;
start = dse+trig->duration_days+1;
}
}
p->pos = t;
@@ -1396,7 +1421,7 @@ finished:
/* function. */
/* */
/***************************************************************/
static int ShouldTriggerBasedOnWarn(Trigger *t, int jul, int *err)
static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
{
char buffer[VAR_NAME_LEN+32];
int i;
@@ -1408,7 +1433,7 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int jul, int *err)
/* If no proper function exists, barf... */
if (UserFuncExists(t->warn) != 1) {
Eprint("%s: `%s'", ErrMsg[M_BAD_WARN_FUNC], t->warn);
return (jul == JulianToday);
return (dse == DSEToday);
}
for (i=1; ; i++) {
sprintf(buffer, "%s(%d)", t->warn, i);
@@ -1417,28 +1442,28 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int jul, int *err)
if (r) {
Eprint("%s: `%s': %s", ErrMsg[M_BAD_WARN_FUNC],
t->warn, ErrMsg[r]);
return (jul == JulianToday);
return (dse == DSEToday);
}
if (v.type != INT_TYPE) {
DestroyValue(v);
Eprint("%s: `%s': %s", ErrMsg[M_BAD_WARN_FUNC],
t->warn, ErrMsg[E_BAD_TYPE]);
return (jul == JulianToday);
return (dse == DSEToday);
}
/* If absolute value of return is not monotonically
decreasing, exit */
if (i > 1 && abs(v.v.val) >= lastReturnVal) {
return (jul == JulianToday);
return (dse == DSEToday);
}
lastReturnVal = abs(v.v.val);
/* Positive values: Just subtract. Negative values:
skip omitted days. */
if (v.v.val >= 0) {
if (JulianToday + v.v.val == jul) return 1;
if (DSEToday + v.v.val == dse) return 1;
} else {
int j = jul;
int j = dse;
int iter = 0;
int max = MaxSatIter;
if (max < v.v.val * 2) max = v.v.val*2;
@@ -1455,7 +1480,29 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int jul, int *err)
Eprint("Delta: Bad OMITFUNC? %s", ErrMsg[E_CANT_TRIG]);
return 0;
}
if (j == JulianToday) return 1;
if (j == DSEToday) return 1;
}
}
}
void FixSpecialType(Trigger *t)
{
if (t->typ != PASSTHRU_TYPE) {
return;
}
/* Convert SPECIAL MSG / MSF / RUN / CAL to just plain MSG / MSF / etc */
if (!StrCmpi(t->passthru, "MSG")) {
t->typ = MSG_TYPE;
} else if (!StrCmpi(t->passthru, "MSF")) {
t->typ = MSF_TYPE;
} else if (!StrCmpi(t->passthru, "RUN")) {
t->typ = RUN_TYPE;
} else if (!StrCmpi(t->passthru, "CAL")) {
t->typ = CAL_TYPE;
} else if (!StrCmpi(t->passthru, "PS")) {
t->typ = PS_TYPE;
} else if (!StrCmpi(t->passthru, "PSFILE")) {
t->typ = PSF_TYPE;
}
}

View File

@@ -6,7 +6,8 @@
/* reminders are triggered. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -42,9 +43,9 @@
/* If mode==ADVANCE_MODE, ignore %" but don't add newline */
/* */
/***************************************************************/
int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul, int mode)
int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode)
{
int diff = jul - JulianToday;
int diff = dse - DSEToday;
int curtime = SystemTime(0) / 60;
int err, done;
int c;
@@ -69,7 +70,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
int r;
Value v;
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
if (tim == NO_TIME) tim = curtime;
tdiff = tim - curtime;
@@ -195,7 +196,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
mode != CAL_MODE &&
mode != ADVANCE_MODE &&
t->typ != RUN_TYPE &&
!MsgCommand) {
!(MsgCommand && *MsgCommand)) {
if (DBufPutc(dbuf, '\n') != OK) return E_NO_MEM;
}
break;
@@ -244,7 +245,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
}
}
if (!c) {
Wprint("Warning: Unterminated %{...} substitution sequence");
Wprint("Warning: Unterminated %%{...} substitution sequence");
}
if (UserFuncExists(s) != 3) {
continue;
@@ -362,464 +363,464 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
Eprint("%s", ErrMsg[r]);
}
}
switch(UPPER(c)) {
case 'A':
#ifdef L_A_OVER
L_A_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d %s, %d", get_day_name(dse%7), d,
get_month_name(m), y);
} else {
snprintf(s, sizeof(s), "%s %s, %d %s, %d", DynamicOn, get_day_name(dse%7), d,
get_month_name(m), y);
}
#endif
SHIP_OUT(s);
break;
case 'B':
#ifdef L_B_OVER
L_B_OVER
#else
snprintf(s, sizeof(s), L_INXDAYS, diff);
#endif
SHIP_OUT(s);
break;
case 'C':
#ifdef L_C_OVER
L_C_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
} else {
snprintf(s, sizeof(s), "%s %s", DynamicOn, get_day_name(dse%7));
}
#endif
SHIP_OUT(s);
break;
case 'D':
#ifdef L_D_OVER
L_D_OVER
#else
snprintf(s, sizeof(s), "%d", d);
#endif
SHIP_OUT(s);
break;
case 'E':
#ifdef L_E_OVER
L_E_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", d, DateSep,
m+1, DateSep, y);
} else {
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, d, DateSep,
m+1, DateSep, y);
}
#endif
SHIP_OUT(s);
break;
case 'F':
#ifdef L_F_OVER
L_F_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
} else {
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, m+1, DateSep, d, DateSep, y);
}
#endif
SHIP_OUT(s);
break;
case 'G':
#ifdef L_G_OVER
L_G_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d %s", get_day_name(dse%7), d, get_month_name(m));
} else {
snprintf(s, sizeof(s), "%s %s, %d %s", DynamicOn, get_day_name(dse%7), d, get_month_name(m));
}
#endif
SHIP_OUT(s);
break;
case 'H':
#ifdef L_H_OVER
L_H_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d", d, DateSep, m+1);
} else {
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, d, DateSep, m+1);
}
#endif
SHIP_OUT(s);
break;
case 'I':
#ifdef L_I_OVER
L_I_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d", m+1, DateSep, d);
} else {
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, m+1, DateSep, d);
}
#endif
SHIP_OUT(s);
break;
case 'J':
#ifdef L_J_OVER
L_J_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %s %d%s, %d", get_day_name(dse%7),
get_month_name(m), d, plu, y);
} else {
snprintf(s, sizeof(s), "%s %s, %s %d%s, %d", DynamicOn, get_day_name(dse%7),
get_month_name(m), d, plu, y);
}
#endif
SHIP_OUT(s);
break;
case 'K':
#ifdef L_K_OVER
L_K_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %s %d%s", get_day_name(dse%7),
get_month_name(m), d, plu);
} else {
snprintf(s, sizeof(s), "%s %s, %s %d%s", DynamicOn, get_day_name(dse%7),
get_month_name(m), d, plu);
}
#endif
SHIP_OUT(s);
break;
case 'L':
#ifdef L_L_OVER
L_L_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
} else {
snprintf(s, sizeof(s), "%s %04d%c%02d%c%02d", DynamicOn, y, DateSep, m+1, DateSep, d);
}
#endif
SHIP_OUT(s);
break;
case 'M':
#ifdef L_M_OVER
L_M_OVER
#else
snprintf(s, sizeof(s), "%s", get_month_name(m));
#endif
SHIP_OUT(s);
break;
case 'N':
#ifdef L_N_OVER
L_N_OVER
#else
snprintf(s, sizeof(s), "%d", m+1);
#endif
SHIP_OUT(s);
break;
case 'O':
#ifdef L_O_OVER
L_O_OVER
#else
if (RealToday == DSEToday) snprintf(s, sizeof(s), " (%s)", DynamicToday);
else *s = 0;
#endif
SHIP_OUT(s);
break;
case 'P':
#ifdef L_P_OVER
L_P_OVER
#else
snprintf(s, sizeof(s), "%s", (diff == 1 ? "" : L_PLURAL));
#endif
SHIP_OUT(s);
break;
case 'Q':
#ifdef L_Q_OVER
L_Q_OVER
#else
snprintf(s, sizeof(s), "%s", (diff == 1 ? "'s" : "s'"));
#endif
SHIP_OUT(s);
break;
case 'R':
#ifdef L_R_OVER
L_R_OVER
#else
snprintf(s, sizeof(s), "%02d", d);
#endif
SHIP_OUT(s);
break;
case 'S':
#ifdef L_S_OVER
L_S_OVER
#else
snprintf(s, sizeof(s), "%s", plu);
#endif
SHIP_OUT(s);
break;
case 'T':
#ifdef L_T_OVER
L_T_OVER
#else
snprintf(s, sizeof(s), "%02d", m+1);
#endif
SHIP_OUT(s);
break;
case 'U':
#ifdef L_U_OVER
L_U_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d%s %s, %d", get_day_name(dse%7), d,
plu, get_month_name(m), y);
} else {
snprintf(s, sizeof(s), "%s %s, %d%s %s, %d", DynamicOn, get_day_name(dse%7), d,
plu, get_month_name(m), y);
}
#endif
SHIP_OUT(s);
break;
case 'V':
#ifdef L_V_OVER
L_V_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d%s %s", get_day_name(dse%7), d, plu,
get_month_name(m));
} else {
snprintf(s, sizeof(s), "%s %s, %d%s %s", DynamicOn, get_day_name(dse%7), d, plu,
get_month_name(m));
}
#endif
SHIP_OUT(s);
break;
case 'W':
#ifdef L_W_OVER
L_W_OVER
#else
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
#endif
SHIP_OUT(s);
break;
case 'X':
#ifdef L_X_OVER
L_X_OVER
#else
snprintf(s, sizeof(s), "%d", diff);
#endif
SHIP_OUT(s);
break;
case 'Y':
#ifdef L_Y_OVER
L_Y_OVER
#else
snprintf(s, sizeof(s), "%d", y);
#endif
SHIP_OUT(s);
break;
case 'Z':
#ifdef L_Z_OVER
L_Z_OVER
#else
snprintf(s, sizeof(s), "%d", y % 100);
#endif
SHIP_OUT(s);
break;
case '1':
#ifdef L_1_OVER
L_1_OVER
#else
if (tdiff == 0)
snprintf(s, sizeof(s), "%s", DynamicNow);
else if (hdiff == 0)
snprintf(s, sizeof(s), "%d %s%s %s", mdiff, DynamicMinute, mplu, when);
else if (mdiff == 0)
snprintf(s, sizeof(s), "%d %s%s %s", hdiff, DynamicHour, hplu, when);
else
snprintf(s, sizeof(s), "%d %s%s %s %d %s%s %s", hdiff, DynamicHour, hplu,
DynamicAnd, mdiff, DynamicMinute, mplu, when);
#endif
SHIP_OUT(s);
break;
case '2':
#ifdef L_2_OVER
L_2_OVER
#else
if (altmode == '*') {
snprintf(s, sizeof(s), "%d%c%02d%s", hh, TimeSep, min, pm);
} else {
snprintf(s, sizeof(s), "%s %d%c%02d%s", DynamicAt, hh, TimeSep, min, pm);
}
#endif
SHIP_OUT(s);
break;
case '3':
#ifdef L_3_OVER
L_3_OVER
#else
if (altmode == '*') {
snprintf(s, sizeof(s), "%02d%c%02d", h, TimeSep, min);
} else {
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicAt, h, TimeSep, min);
}
#endif
SHIP_OUT(s);
break;
case '4':
#ifdef L_4_OVER
L_4_OVER
#else
snprintf(s, sizeof(s), "%d", tdiff);
#endif
SHIP_OUT(s);
break;
case '5':
#ifdef L_5_OVER
L_5_OVER
#else
snprintf(s, sizeof(s), "%d", adiff);
#endif
SHIP_OUT(s);
break;
case '6':
#ifdef L_6_OVER
L_6_OVER
#else
snprintf(s, sizeof(s), "%s", when);
#endif
SHIP_OUT(s);
break;
case '7':
#ifdef L_7_OVER
L_7_OVER
#else
snprintf(s, sizeof(s), "%d", hdiff);
#endif
SHIP_OUT(s);
break;
case '8':
#ifdef L_8_OVER
L_8_OVER
#else
snprintf(s, sizeof(s), "%d", mdiff);
#endif
SHIP_OUT(s);
break;
case '9':
#ifdef L_9_OVER
L_9_OVER
#else
snprintf(s, sizeof(s), "%s", mplu);
#endif
SHIP_OUT(s);
break;
case '0':
#ifdef L_0_OVER
L_0_OVER
#else
snprintf(s, sizeof(s), "%s", hplu);
#endif
SHIP_OUT(s);
break;
case '!':
#ifdef L_BANG_OVER
L_BANG_OVER
#else
snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? DynamicIs : DynamicWas));
#endif
SHIP_OUT(s);
break;
case '@':
#ifdef L_AT_OVER
L_AT_OVER
#else
snprintf(s, sizeof(s), "%d%c%02d%s", chh, TimeSep, cmin, cpm);
#endif
SHIP_OUT(s);
break;
case '#':
#ifdef L_HASH_OVER
L_HASH_OVER
#else
snprintf(s, sizeof(s), "%02d%c%02d", ch, TimeSep, cmin);
#endif
SHIP_OUT(s);
break;
case '_':
if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !(MsgCommand && *MsgCommand))) {
snprintf(s, sizeof(s), "%s", NL);
} else {
snprintf(s, sizeof(s), " ");
}
SHIP_OUT(s);
break;
case QUOTE_MARKER:
/* Swallow any QUOTE_MARKERs which may somehow creep in... */
break;
case '"':
if (DontSuppressQuoteMarkers) {
if (DBufPutc(dbuf, '%') != OK) return E_NO_MEM;
if (DBufPutc(dbuf, c) != OK) return E_NO_MEM;
} else {
if (DBufPutc(dbuf, QUOTE_MARKER) != OK) return E_NO_MEM;
has_quote = 1;
}
break;
default:
if (DBufPutc(dbuf, c) != OK) return E_NO_MEM;
}
}
if (!done) switch(UPPER(c)) {
case 'A':
#ifdef L_A_OVER
L_A_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d %s, %d", get_day_name(jul%7), d,
get_month_name(m), y);
} else {
snprintf(s, sizeof(s), "%s %s, %d %s, %d", DynamicOn, get_day_name(jul%7), d,
get_month_name(m), y);
}
#endif
SHIP_OUT(s);
break;
case 'B':
#ifdef L_B_OVER
L_B_OVER
#else
snprintf(s, sizeof(s), L_INXDAYS, diff);
#endif
SHIP_OUT(s);
break;
case 'C':
#ifdef L_C_OVER
L_C_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s", get_day_name(jul%7));
} else {
snprintf(s, sizeof(s), "%s %s", DynamicOn, get_day_name(jul%7));
}
#endif
SHIP_OUT(s);
break;
case 'D':
#ifdef L_D_OVER
L_D_OVER
#else
snprintf(s, sizeof(s), "%d", d);
#endif
SHIP_OUT(s);
break;
case 'E':
#ifdef L_E_OVER
L_E_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", d, DateSep,
m+1, DateSep, y);
} else {
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, d, DateSep,
m+1, DateSep, y);
}
#endif
SHIP_OUT(s);
break;
case 'F':
#ifdef L_F_OVER
L_F_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
} else {
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, m+1, DateSep, d, DateSep, y);
}
#endif
SHIP_OUT(s);
break;
case 'G':
#ifdef L_G_OVER
L_G_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d %s", get_day_name(jul%7), d, get_month_name(m));
} else {
snprintf(s, sizeof(s), "%s %s, %d %s", DynamicOn, get_day_name(jul%7), d, get_month_name(m));
}
#endif
SHIP_OUT(s);
break;
case 'H':
#ifdef L_H_OVER
L_H_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d", d, DateSep, m+1);
} else {
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, d, DateSep, m+1);
}
#endif
SHIP_OUT(s);
break;
case 'I':
#ifdef L_I_OVER
L_I_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%02d%c%02d", m+1, DateSep, d);
} else {
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, m+1, DateSep, d);
}
#endif
SHIP_OUT(s);
break;
case 'J':
#ifdef L_J_OVER
L_J_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %s %d%s, %d", get_day_name(jul%7),
get_month_name(m), d, plu, y);
} else {
snprintf(s, sizeof(s), "%s %s, %s %d%s, %d", DynamicOn, get_day_name(jul%7),
get_month_name(m), d, plu, y);
}
#endif
SHIP_OUT(s);
break;
case 'K':
#ifdef L_K_OVER
L_K_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %s %d%s", get_day_name(jul%7),
get_month_name(m), d, plu);
} else {
snprintf(s, sizeof(s), "%s %s, %s %d%s", DynamicOn, get_day_name(jul%7),
get_month_name(m), d, plu);
}
#endif
SHIP_OUT(s);
break;
case 'L':
#ifdef L_L_OVER
L_L_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
} else {
snprintf(s, sizeof(s), "%s %04d%c%02d%c%02d", DynamicOn, y, DateSep, m+1, DateSep, d);
}
#endif
SHIP_OUT(s);
break;
case 'M':
#ifdef L_M_OVER
L_M_OVER
#else
snprintf(s, sizeof(s), "%s", get_month_name(m));
#endif
SHIP_OUT(s);
break;
case 'N':
#ifdef L_N_OVER
L_N_OVER
#else
snprintf(s, sizeof(s), "%d", m+1);
#endif
SHIP_OUT(s);
break;
case 'O':
#ifdef L_O_OVER
L_O_OVER
#else
if (RealToday == JulianToday) snprintf(s, sizeof(s), " (%s)", DynamicToday);
else *s = 0;
#endif
SHIP_OUT(s);
break;
case 'P':
#ifdef L_P_OVER
L_P_OVER
#else
snprintf(s, sizeof(s), "%s", (diff == 1 ? "" : L_PLURAL));
#endif
SHIP_OUT(s);
break;
case 'Q':
#ifdef L_Q_OVER
L_Q_OVER
#else
snprintf(s, sizeof(s), "%s", (diff == 1 ? "'s" : "s'"));
#endif
SHIP_OUT(s);
break;
case 'R':
#ifdef L_R_OVER
L_R_OVER
#else
snprintf(s, sizeof(s), "%02d", d);
#endif
SHIP_OUT(s);
break;
case 'S':
#ifdef L_S_OVER
L_S_OVER
#else
snprintf(s, sizeof(s), "%s", plu);
#endif
SHIP_OUT(s);
break;
case 'T':
#ifdef L_T_OVER
L_T_OVER
#else
snprintf(s, sizeof(s), "%02d", m+1);
#endif
SHIP_OUT(s);
break;
case 'U':
#ifdef L_U_OVER
L_U_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d%s %s, %d", get_day_name(jul%7), d,
plu, get_month_name(m), y);
} else {
snprintf(s, sizeof(s), "%s %s, %d%s %s, %d", DynamicOn, get_day_name(jul%7), d,
plu, get_month_name(m), y);
}
#endif
SHIP_OUT(s);
break;
case 'V':
#ifdef L_V_OVER
L_V_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d%s %s", get_day_name(jul%7), d, plu,
get_month_name(m));
} else {
snprintf(s, sizeof(s), "%s %s, %d%s %s", DynamicOn, get_day_name(jul%7), d, plu,
get_month_name(m));
}
#endif
SHIP_OUT(s);
break;
case 'W':
#ifdef L_W_OVER
L_W_OVER
#else
snprintf(s, sizeof(s), "%s", get_day_name(jul%7));
#endif
SHIP_OUT(s);
break;
case 'X':
#ifdef L_X_OVER
L_X_OVER
#else
snprintf(s, sizeof(s), "%d", diff);
#endif
SHIP_OUT(s);
break;
case 'Y':
#ifdef L_Y_OVER
L_Y_OVER
#else
snprintf(s, sizeof(s), "%d", y);
#endif
SHIP_OUT(s);
break;
case 'Z':
#ifdef L_Z_OVER
L_Z_OVER
#else
snprintf(s, sizeof(s), "%d", y % 100);
#endif
SHIP_OUT(s);
break;
case '1':
#ifdef L_1_OVER
L_1_OVER
#else
if (tdiff == 0)
snprintf(s, sizeof(s), "%s", DynamicNow);
else if (hdiff == 0)
snprintf(s, sizeof(s), "%d %s%s %s", mdiff, DynamicMinute, mplu, when);
else if (mdiff == 0)
snprintf(s, sizeof(s), "%d %s%s %s", hdiff, DynamicHour, hplu, when);
else
snprintf(s, sizeof(s), "%d %s%s %s %d %s%s %s", hdiff, DynamicHour, hplu,
DynamicAnd, mdiff, DynamicMinute, mplu, when);
#endif
SHIP_OUT(s);
break;
case '2':
#ifdef L_2_OVER
L_2_OVER
#else
if (altmode == '*') {
snprintf(s, sizeof(s), "%d%c%02d%s", hh, TimeSep, min, pm);
} else {
snprintf(s, sizeof(s), "%s %d%c%02d%s", DynamicAt, hh, TimeSep, min, pm);
}
#endif
SHIP_OUT(s);
break;
case '3':
#ifdef L_3_OVER
L_3_OVER
#else
if (altmode == '*') {
snprintf(s, sizeof(s), "%02d%c%02d", h, TimeSep, min);
} else {
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicAt, h, TimeSep, min);
}
#endif
SHIP_OUT(s);
break;
case '4':
#ifdef L_4_OVER
L_4_OVER
#else
snprintf(s, sizeof(s), "%d", tdiff);
#endif
SHIP_OUT(s);
break;
case '5':
#ifdef L_5_OVER
L_5_OVER
#else
snprintf(s, sizeof(s), "%d", adiff);
#endif
SHIP_OUT(s);
break;
case '6':
#ifdef L_6_OVER
L_6_OVER
#else
snprintf(s, sizeof(s), "%s", when);
#endif
SHIP_OUT(s);
break;
case '7':
#ifdef L_7_OVER
L_7_OVER
#else
snprintf(s, sizeof(s), "%d", hdiff);
#endif
SHIP_OUT(s);
break;
case '8':
#ifdef L_8_OVER
L_8_OVER
#else
snprintf(s, sizeof(s), "%d", mdiff);
#endif
SHIP_OUT(s);
break;
case '9':
#ifdef L_9_OVER
L_9_OVER
#else
snprintf(s, sizeof(s), "%s", mplu);
#endif
SHIP_OUT(s);
break;
case '0':
#ifdef L_0_OVER
L_0_OVER
#else
snprintf(s, sizeof(s), "%s", hplu);
#endif
SHIP_OUT(s);
break;
case '!':
#ifdef L_BANG_OVER
L_BANG_OVER
#else
snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? DynamicIs : DynamicWas));
#endif
SHIP_OUT(s);
break;
case '@':
#ifdef L_AT_OVER
L_AT_OVER
#else
snprintf(s, sizeof(s), "%d%c%02d%s", chh, TimeSep, cmin, cpm);
#endif
SHIP_OUT(s);
break;
case '#':
#ifdef L_HASH_OVER
L_HASH_OVER
#else
snprintf(s, sizeof(s), "%02d%c%02d", ch, TimeSep, cmin);
#endif
SHIP_OUT(s);
break;
case '_':
if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !MsgCommand)) {
snprintf(s, sizeof(s), "%s", NL);
} else {
snprintf(s, sizeof(s), " ");
}
SHIP_OUT(s);
break;
case QUOTE_MARKER:
/* Swallow any QUOTE_MARKERs which may somehow creep in... */
break;
case '"':
if (DontSuppressQuoteMarkers) {
if (DBufPutc(dbuf, '%') != OK) return E_NO_MEM;
if (DBufPutc(dbuf, c) != OK) return E_NO_MEM;
} else {
if (DBufPutc(dbuf, QUOTE_MARKER) != OK) return E_NO_MEM;
has_quote = 1;
}
break;
default:
if (DBufPutc(dbuf, c) != OK) return E_NO_MEM;
}
if (isupper(c)) {
os = DBufValue(dbuf);
os += strlen(os) - strlen(s);
@@ -885,21 +886,21 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
/* */
/***************************************************************/
int DoSubstFromString(char const *source, DynamicBuffer *dbuf,
int jul, int tim)
int dse, int tim)
{
Trigger tempTrig;
TimeTrig tempTime;
Parser tempP;
int r;
if (jul == NO_DATE) jul=JulianToday;
if (dse == NO_DATE) dse=DSEToday;
if (tim == NO_TIME) tim=SystemTime(0)/60;
CreateParser(source, &tempP);
tempP.allownested = 0;
tempTrig.typ = MSG_TYPE;
tempTime.ttime = tim;
r = DoSubst(&tempP, dbuf, &tempTrig, &tempTime, jul, NORMAL_MODE);
r = DoSubst(&tempP, dbuf, &tempTrig, &tempTime, dse, NORMAL_MODE);
DestroyParser(&tempP);
return r;
}

View File

@@ -6,7 +6,8 @@
/* buffers. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -5,7 +5,8 @@
/* Declaration of functions for manipulating dynamic buffers */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -5,7 +5,8 @@
/* Error definitions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -5,7 +5,8 @@
/* This file contains routines to parse and evaluate */
/* expressions. */
/* */
/* Copyright 1992-2022 by Dianne Skoll */
/* Copyright 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -375,12 +376,10 @@ int Evaluate(char const **s, Var *locals, ParsePtr p)
DBufFree(&ExprBuf);
r = Evaluate(s, locals, p); /* Leaves the last parsed token in ExprBuf */
if (r) return r;
r = OK;
if (*DBufValue(&ExprBuf) != ')') {
if (*DBufValue(&ExprBuf) != ')') {
DBufFree(&ExprBuf);
return E_MISS_RIGHT_PAREN;
}
if (r) return r;
} else if (*DBufValue(&ExprBuf) == '+') {
continue; /* Ignore unary + */
}
@@ -662,13 +661,13 @@ int DoCoerce(char type, Value *v)
case TIME_TYPE: sprintf(coerce_buf, "%02d%c%02d", v->v.val / 60,
TimeSep, v->v.val % 60);
break;
case DATE_TYPE: FromJulian(v->v.val, &y, &m, &d);
case DATE_TYPE: FromDSE(v->v.val, &y, &m, &d);
sprintf(coerce_buf, "%04d%c%02d%c%02d",
y, DateSep, m+1, DateSep, d);
break;
case DATETIME_TYPE:
i = v->v.val / MINUTES_PER_DAY;
FromJulian(i, &y, &m, &d);
FromDSE(i, &y, &m, &d);
k = v->v.val % MINUTES_PER_DAY;
h = k / 60;
i = k % 60;
@@ -1194,9 +1193,9 @@ static int LogNot(void)
/***************************************************************/
/* */
/* FindFunc */
/* FindOperator */
/* */
/* Find a function. */
/* Find an operator. */
/* */
/***************************************************************/
Operator *FindOperator(char const *name, Operator where[], int num)
@@ -1205,7 +1204,7 @@ Operator *FindOperator(char const *name, Operator where[], int num)
int mid, r;
while (top >= bot) {
mid = (top + bot) / 2;
r = StrCmpi(name, where[mid].name);
r = strcmp(name, where[mid].name);
if (!r) return &where[mid];
else if (r > 0) bot = mid+1;
else top = mid-1;
@@ -1213,6 +1212,20 @@ Operator *FindOperator(char const *name, Operator where[], int num)
return NULL;
}
/* Compare two strings case-insensitively, where we KNOW
that the second string is definitely lower-case */
static int strcmp_lcfirst(char const *s1, char const *s2)
{
int r;
while (*s1 && *s2) {
r = tolower(*s1) - *s2;
if (r) return r;
s1++;
s2++;
}
return tolower(*s1) - *s2;
}
/***************************************************************/
/* */
/* FindFunc */
@@ -1226,7 +1239,7 @@ BuiltinFunc *FindFunc(char const *name, BuiltinFunc where[], int num)
int mid, r;
while (top >= bot) {
mid = (top + bot) / 2;
r = StrCmpi(name, where[mid].name);
r = strcmp_lcfirst(name, where[mid].name);
if (!r) return &where[mid];
else if (r > 0) bot = mid+1;
else top = mid-1;
@@ -1276,11 +1289,11 @@ void PrintValue (Value *v, FILE *fp)
else if (v->type == TIME_TYPE) fprintf(fp, "%02d%c%02d", v->v.val / 60,
TimeSep, v->v.val % 60);
else if (v->type == DATE_TYPE) {
FromJulian(v->v.val, &y, &m, &d);
FromDSE(v->v.val, &y, &m, &d);
fprintf(fp, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
}
else if (v->type == DATETIME_TYPE) {
FromJulian(v->v.val / MINUTES_PER_DAY, &y, &m, &d);
FromDSE(v->v.val / MINUTES_PER_DAY, &y, &m, &d);
fprintf(fp, "%04d%c%02d%c%02d%c%02d%c%02d", y, DateSep, m+1, DateSep, d, DateTimeSep,
(v->v.val % MINUTES_PER_DAY) / 60, TimeSep, (v->v.val % MINUTES_PER_DAY) % 60);
}
@@ -1353,11 +1366,11 @@ int ParseLiteralTime(char const **s, int *tim)
/* */
/* ParseLiteralDate */
/* */
/* Parse a literal date or datetime. Return result in jul */
/* Parse a literal date or datetime. Return result in dse */
/* and tim; update s. */
/* */
/***************************************************************/
int ParseLiteralDate(char const **s, int *jul, int *tim)
int ParseLiteralDate(char const **s, int *dse, int *tim)
{
int y, m, d;
int r;
@@ -1387,7 +1400,7 @@ int ParseLiteralDate(char const **s, int *jul, int *tim)
}
if (!DateOK(y, m, d)) return E_BAD_DATE;
*jul = Julian(y, m, d);
*dse = DSE(y, m, d);
/* Do we have a time part as well? */
if (**s == ' ' || **s == '@' || **s == 'T' || **s == 't') {

View File

@@ -5,7 +5,8 @@
/* Contains a few definitions used by expression evaluator. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -7,7 +7,8 @@
/* files. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -96,6 +97,7 @@ static int ReadLineFromFile (int use_pclose);
static int CacheFile (char const *fname, int use_pclose);
static void DestroyCache (CachedFile *cf);
static int CheckSafety (void);
static int CheckSafetyAux (struct stat *statbuf);
static int PopFile (void);
static int IncludeCmd(char const *);
static void OpenPurgeFile(char const *fname, char const *mode)
@@ -971,6 +973,11 @@ int IncludeFile(char const *fname)
if (stat(fname, &statbuf) == 0) {
FilenameChain *fc;
if (S_ISDIR(statbuf.st_mode)) {
/* Check safety */
if (!CheckSafetyAux(&statbuf)) {
PopFile();
return E_NO_MATCHING_REMS;
}
if (SetupGlobChain(fname, i) == OK) { /* Glob succeeded */
if (!i->chain) { /* Oops... no matching files */
if (!Hush) {
@@ -1031,7 +1038,7 @@ int GetAccessDate(char const *file)
if (t1->tm_year + 1900 < BASE)
return 0;
else
return Julian(t1->tm_year+1900, t1->tm_mon, t1->tm_mday);
return DSE(t1->tm_year+1900, t1->tm_mon, t1->tm_mday);
}
/***************************************************************/
@@ -1084,8 +1091,8 @@ int TopLevel(void)
/* CheckSafety */
/* */
/* Returns 1 if current file is safe to read; 0 otherwise. */
/* Currently only meaningful for UNIX. If we are running as */
/* root, we refuse to open files not owned by root. */
/* If we are running as root, we refuse to open files not */
/* owned by root. */
/* We also reject world-writable files, no matter */
/* who we're running as. */
/* As a side effect, if we don't own the file, or it's not */
@@ -1105,25 +1112,44 @@ static int CheckSafety(void)
return 0;
}
if (!CheckSafetyAux(&statbuf)) {
fclose(fp);
fp = NULL;
return 0;
}
return 1;
}
/***************************************************************/
/* */
/* CheckSafetyAux */
/* */
/* Returns 1 if file whos info is in statbuf is safe to read; */
/* 0 otherwise. If we are running as */
/* root, we refuse to open files not owned by root. */
/* We also reject world-writable files, no matter */
/* who we're running as. */
/* As a side effect, if we don't own the file, or it's not */
/* owned by a trusted user, we disable RUN */
/***************************************************************/
static int CheckSafetyAux(struct stat *statbuf)
{
/* Under UNIX, take extra precautions if running as root */
if (!geteuid()) {
/* Reject files not owned by root or group/world writable */
if (statbuf.st_uid != 0) {
fprintf(ErrFp, "SECURITY: Won't read non-root-owned file when running as root!\n");
fclose(fp);
fp = NULL;
if (statbuf->st_uid != 0) {
fprintf(ErrFp, "SECURITY: Won't read non-root-owned file or directory when running as root!\n");
return 0;
}
}
/* Sigh... /dev/null is usually world-writable, so ignore devices,
FIFOs, sockets, etc. */
if (!S_ISREG(statbuf.st_mode)) {
if (!S_ISREG(statbuf->st_mode) && !S_ISDIR(statbuf->st_mode)) {
return 1;
}
if ((statbuf.st_mode & S_IWOTH)) {
fprintf(ErrFp, "SECURITY: Won't read world-writable file!\n");
fclose(fp);
fp = NULL;
if ((statbuf->st_mode & S_IWOTH)) {
fprintf(ErrFp, "SECURITY: Won't read world-writable file or directory!\n");
return 0;
}
@@ -1131,13 +1157,13 @@ static int CheckSafety(void)
/* Assume unsafe */
RunDisabled |= RUN_NOTOWNER;
if (statbuf.st_uid == geteuid()) {
if (statbuf->st_uid == geteuid()) {
/* Owned by me... safe */
RunDisabled &= ~RUN_NOTOWNER;
} else {
int i;
for (i=0; i<NumTrustedUsers; i++) {
if (statbuf.st_uid == TrustedUsers[i]) {
if (statbuf->st_uid == TrustedUsers[i]) {
/* Owned by a trusted user... safe */
RunDisabled &= ~RUN_NOTOWNER;
break;

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,8 @@
/* globals.h and err.h */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -8,6 +8,7 @@
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -38,9 +39,9 @@ EXTERN FILE *ErrFp;
#define IsLeapYear(y) (((y) % 4) ? 0 : ((!((y) % 100) && ((y) % 400)) ? 0 : 1 ))
#define DaysInMonth(m, y) ((m) != 1 ? MonthDays[m] : 28 + IsLeapYear(y))
#define DestroyValue(x) (void) (((x).type == STR_TYPE && (x).v.str) ? (free((x).v.str),(x).type = ERR_TYPE) : 0)
#define DestroyValue(x) (void) (((x).type == STR_TYPE && (x).v.str) ? (free((x).v.str),(x).v.str = NULL,(x).type = ERR_TYPE) : 0)
EXTERN int JulianToday;
EXTERN int DSEToday;
EXTERN int RealToday;
EXTERN int CurDay;
EXTERN int CurMon;
@@ -51,6 +52,7 @@ EXTERN uid_t TrustedUsers[MAX_TRUSTED_USERS];
EXTERN INIT( int NumTrustedUsers, 0);
EXTERN INIT( char const *MsgCommand, NULL);
EXTERN INIT( char const *QueuedMsgCommand, NULL);
EXTERN INIT( int ShowAllErrors, 0);
EXTERN INIT( int DebugFlag, 0);
EXTERN INIT( int DoCalendar, 0);

View File

@@ -5,7 +5,8 @@
/* Support for the Hebrew calendar */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/* Derived from code written by Amos Shapir in 1978; revised */
/* 1985. */
@@ -67,7 +68,7 @@ static char HebIsLeap[] = {0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1};
/* */
/* RoshHashana */
/* */
/* Return the Julian date for Rosh Hashana of specified */
/* Return DSE date for Rosh Hashana of specified */
/* Hebrew year. (ie, 5751, not 1990) */
/* */
/***************************************************************/
@@ -155,14 +156,14 @@ char const *DaysInHebMonths(int ylen)
/***************************************************************/
/* */
/* HebToJul */
/* HebToDSE */
/* */
/* Convert a Hebrew date to Julian. */
/* Convert a Hebrew date to DSE. */
/* Hebrew months range from 0-12, but Adar A has 0 length in */
/* non-leap-years. */
/* */
/***************************************************************/
int HebToJul(int hy, int hm, int hd)
int HebToDSE(int hy, int hm, int hd)
{
int ylen;
char const *monlens;
@@ -188,39 +189,39 @@ int HebToJul(int hy, int hm, int hd)
/***************************************************************/
/* */
/* JulToHeb */
/* DSEToHeb */
/* */
/* Convert a Julian date to Hebrew. */
/* Convert a DSE to Hebrew. */
/* Hebrew months range from 0-12, but Adar A has 0 length in */
/* non-leap-years. */
/* */
/***************************************************************/
void JulToHeb(int jul, int *hy, int *hm, int *hd)
void DSEToHeb(int dse, int *hy, int *hm, int *hd)
{
int y, m, d;
int rh;
int ylen;
char const *monlen;
/* Get the common year */
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
y += 3763; /* Over-estimate a bit to be on the safe side below... */
/* Find the RH just before desired date */
while ((rh=RoshHashana(y))>jul) y--;
while ((rh=RoshHashana(y))>dse) y--;
/* Got the year - now find the month */
jul -= rh;
dse -= rh;
ylen = DaysInHebYear(y);
monlen = DaysInHebMonths(ylen);
m = 0;
while((jul >= monlen[m]) || !monlen[m]) {
jul -= monlen[m];
while((dse >= monlen[m]) || !monlen[m]) {
dse -= monlen[m];
m++;
}
*hy = y;
*hm = m;
*hd = jul+1;
*hd = dse+1;
}
/***************************************************************/
@@ -389,20 +390,20 @@ int GetValidHebDate(int yin, int min, int din, int adarbehave,
/* Returns 0 for success, non-zero for failure. */
/* */
/***************************************************************/
int GetNextHebrewDate(int julstart, int hm, int hd,
int GetNextHebrewDate(int dsestart, int hm, int hd,
int jahr, int adarbehave, int *ans)
{
int r, yout, mout, dout, jul=1;
int r, yout, mout, dout, dse=1;
int adarflag = adarbehave;
/* I initialize jul above to stop gcc from complaining about
/* I initialize dse above to stop gcc from complaining about
possible use of uninitialized variable. You can take it
out if the small inefficiency really bothers you. */
/* If adarbehave == ADAR2BOTH, set adarflag to ADAR2ADARA for now */
if (adarbehave == ADAR2BOTH) adarflag = ADAR2ADARA;
JulToHeb(julstart, &yout, &mout, &dout);
DSEToHeb(dsestart, &yout, &mout, &dout);
r = 1;
while(r) {
@@ -419,9 +420,9 @@ int GetNextHebrewDate(int julstart, int hm, int hd,
} else yout++;
continue;
}
jul = HebToJul(yout, mout, dout);
if (jul < 0) return E_DATE_OVER;
if (jul >= julstart) break;
dse = HebToDSE(yout, mout, dout);
if (dse < 0) return E_DATE_OVER;
if (dse >= dsestart) break;
else {
if (adarbehave == ADAR2BOTH && hm == ADAR) {
if (adarflag == ADAR2ADARA) {
@@ -434,7 +435,7 @@ int GetNextHebrewDate(int julstart, int hm, int hd,
r=1; /* Force loop to continue */
}
}
*ans = jul;
*ans = dse;
return OK;
}

View File

@@ -7,7 +7,8 @@
/* in normal mode. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -164,10 +165,10 @@ void InitRemind(int argc, char const *argv[])
char const *s;
int weeks;
int x;
int jul;
int dse;
int ttyfd;
jul = NO_DATE;
dse = NO_DATE;
/* If stdout is a terminal, initialize $FormWidth to terminal width-8,
but clamp to [20, 500] */
@@ -199,8 +200,8 @@ void InitRemind(int argc, char const *argv[])
fprintf(ErrFp, ErrMsg[M_BAD_SYS_DATE], BASE);
exit(EXIT_FAILURE);
}
JulianToday = RealToday;
FromJulian(JulianToday, &CurYear, &CurMon, &CurDay);
DSEToday = RealToday;
FromDSE(DSEToday, &CurYear, &CurMon, &CurDay);
/* Initialize Latitude and Longitude */
set_components_from_lat_and_long();
@@ -599,7 +600,12 @@ void InitRemind(int argc, char const *argv[])
case 'k':
case 'K':
MsgCommand = arg;
if (*arg == ':') {
arg++;
QueuedMsgCommand = arg;
} else {
MsgCommand = arg;
}
while (*arg) arg++; /* Chew up remaining chars in this arg */
break;
@@ -638,30 +644,30 @@ void InitRemind(int argc, char const *argv[])
case T_DateTime:
if (SysTime != -1L) Usage();
if (m != NO_MON || d != NO_DAY || y != NO_YR || jul != NO_DATE) Usage();
if (m != NO_MON || d != NO_DAY || y != NO_YR || dse != NO_DATE) Usage();
SysTime = (tok.val % MINUTES_PER_DAY) * 60;
DontQueue = 1;
Daemon = 0;
jul = tok.val / MINUTES_PER_DAY;
dse = tok.val / MINUTES_PER_DAY;
break;
case T_Date:
if (m != NO_MON || d != NO_DAY || y != NO_YR || jul != NO_DATE) Usage();
jul = tok.val;
if (m != NO_MON || d != NO_DAY || y != NO_YR || dse != NO_DATE) Usage();
dse = tok.val;
break;
case T_Month:
if (m != NO_MON || jul != NO_DATE) Usage();
if (m != NO_MON || dse != NO_DATE) Usage();
else m = tok.val;
break;
case T_Day:
if (d != NO_DAY || jul != NO_DATE) Usage();
if (d != NO_DAY || dse != NO_DATE) Usage();
else d = tok.val;
break;
case T_Year:
if (y != NO_YR || jul != NO_DATE) Usage();
if (y != NO_YR || dse != NO_DATE) Usage();
else y = tok.val;
break;
@@ -681,8 +687,8 @@ void InitRemind(int argc, char const *argv[])
Daemon = 0;
}
if (jul != NO_DATE) {
FromJulian(jul, &y, &m, &d);
if (dse != NO_DATE) {
FromDSE(dse, &y, &m, &d);
}
/* Must supply date in the form: day, mon, yr OR mon, yr */
if (m != NO_MON || y != NO_YR || d != NO_DAY) {
@@ -700,22 +706,22 @@ void InitRemind(int argc, char const *argv[])
fprintf(ErrFp, "%s", BadDate);
Usage();
}
JulianToday = Julian(y, m, d);
if (JulianToday == -1) {
DSEToday = DSE(y, m, d);
if (DSEToday == -1) {
fprintf(ErrFp, "%s", BadDate);
Usage();
}
CurYear = y;
CurMon = m;
CurDay = d;
if (JulianToday != RealToday) IgnoreOnce = 1;
if (DSEToday != RealToday) IgnoreOnce = 1;
}
}
/* Figure out the offset from UTC */
if (CalculateUTC)
(void) CalcMinsFromUTC(JulianToday, SystemTime(0)/60,
(void) CalcMinsFromUTC(DSEToday, SystemTime(0)/60,
&MinsFromUTC, NULL);
}
@@ -729,7 +735,7 @@ void InitRemind(int argc, char const *argv[])
#ifndef L_USAGE_OVERRIDE
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2023 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif

View File

@@ -249,7 +249,7 @@ json_value * json_parse_ex (json_settings * settings,
const json_char * end;
json_value * top, * root, * alloc = 0;
json_state state = { 0 };
long flags = 0;
long flags;
double num_digits = 0, num_e = 0;
double num_fraction = 0;
@@ -299,7 +299,7 @@ json_value * json_parse_ex (json_settings * settings,
if (flags & flag_string)
{
if (!b)
{ sprintf (error, "Unexpected EOF in string (at %d:%d)", line_and_col);
{ sprintf (error, "Unexpected EOF in string (at %u:%u)", line_and_col);
goto e_failed;
}
@@ -325,7 +325,7 @@ json_value * json_parse_ex (json_settings * settings,
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
{
sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col);
sprintf (error, "Invalid character value `%c` (at %u:%u)", b, line_and_col);
goto e_failed;
}
@@ -342,7 +342,7 @@ json_value * json_parse_ex (json_settings * settings,
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
{
sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col);
sprintf (error, "Invalid character value `%c` (at %u:%u)", b, line_and_col);
goto e_failed;
}
@@ -472,7 +472,7 @@ json_value * json_parse_ex (json_settings * settings,
if (flags & flag_block_comment)
{
if (!b)
{ sprintf (error, "%d:%d: Unexpected EOF in block comment", line_and_col);
{ sprintf (error, "%u:%u: Unexpected EOF in block comment", line_and_col);
goto e_failed;
}
@@ -488,12 +488,12 @@ json_value * json_parse_ex (json_settings * settings,
else if (b == '/')
{
if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
{ sprintf (error, "%d:%d: Comment not allowed here", line_and_col);
{ sprintf (error, "%u:%u: Comment not allowed here", line_and_col);
goto e_failed;
}
if (++ state.ptr == end)
{ sprintf (error, "%d:%d: EOF unexpected", line_and_col);
{ sprintf (error, "%u:%u: EOF unexpected", line_and_col);
goto e_failed;
}
@@ -508,7 +508,7 @@ json_value * json_parse_ex (json_settings * settings,
continue;
default:
sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", line_and_col, b);
sprintf (error, "%u:%u: Unexpected `%c` in comment opening sequence", line_and_col, b);
goto e_failed;
};
}
@@ -526,7 +526,7 @@ json_value * json_parse_ex (json_settings * settings,
default:
sprintf (error, "%d:%d: Trailing garbage: `%c`",
sprintf (error, "%u:%u: Trailing garbage: `%c`",
state.cur_line, state.cur_col, b);
goto e_failed;
@@ -545,7 +545,7 @@ json_value * json_parse_ex (json_settings * settings,
if (top && top->type == json_array)
flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
else
{ sprintf (error, "%d:%d: Unexpected ]", line_and_col);
{ sprintf (error, "%u:%u: Unexpected ]", line_and_col);
goto e_failed;
}
@@ -561,7 +561,7 @@ json_value * json_parse_ex (json_settings * settings,
}
else
{
sprintf (error, "%d:%d: Expected , before %c",
sprintf (error, "%u:%u: Expected , before %c",
state.cur_line, state.cur_col, b);
goto e_failed;
@@ -576,7 +576,7 @@ json_value * json_parse_ex (json_settings * settings,
}
else
{
sprintf (error, "%d:%d: Expected : before %c",
sprintf (error, "%u:%u: Expected : before %c",
state.cur_line, state.cur_col, b);
goto e_failed;
@@ -702,7 +702,7 @@ json_value * json_parse_ex (json_settings * settings,
continue;
}
else
{ sprintf (error, "%d:%d: Unexpected %c when seeking value", line_and_col, b);
{ sprintf (error, "%u:%u: Unexpected %c when seeking value", line_and_col, b);
goto e_failed;
}
};
@@ -722,7 +722,7 @@ json_value * json_parse_ex (json_settings * settings,
case '"':
if (flags & flag_need_comma)
{ sprintf (error, "%d:%d: Expected , before \"", line_and_col);
{ sprintf (error, "%u:%u: Expected , before \"", line_and_col);
goto e_failed;
}
@@ -747,7 +747,7 @@ json_value * json_parse_ex (json_settings * settings,
}
/* FALLTHROUGH */
default:
sprintf (error, "%d:%d: Unexpected `%c` in object", line_and_col, b);
sprintf (error, "%u:%u: Unexpected `%c` in object", line_and_col, b);
goto e_failed;
};
@@ -765,7 +765,7 @@ json_value * json_parse_ex (json_settings * settings,
if (! (flags & flag_num_e))
{
if (flags & flag_num_zero)
{ sprintf (error, "%d:%d: Unexpected `0` before `%c`", line_and_col, b);
{ sprintf (error, "%u:%u: Unexpected `0` before `%c`", line_and_col, b);
goto e_failed;
}
@@ -814,7 +814,7 @@ json_value * json_parse_ex (json_settings * settings,
else if (b == '.' && top->type == json_integer)
{
if (!num_digits)
{ sprintf (error, "%d:%d: Expected digit before `.`", line_and_col);
{ sprintf (error, "%u:%u: Expected digit before `.`", line_and_col);
goto e_failed;
}
@@ -831,7 +831,7 @@ json_value * json_parse_ex (json_settings * settings,
if (top->type == json_double)
{
if (!num_digits)
{ sprintf (error, "%d:%d: Expected digit after `.`", line_and_col);
{ sprintf (error, "%u:%u: Expected digit after `.`", line_and_col);
goto e_failed;
}
@@ -857,11 +857,11 @@ json_value * json_parse_ex (json_settings * settings,
else
{
if (!num_digits)
{ sprintf (error, "%d:%d: Expected digit after `e`", line_and_col);
{ sprintf (error, "%u:%u: Expected digit after `e`", line_and_col);
goto e_failed;
}
top->u.dbl *= pow (10.0, (flags & flag_num_e_negative ? - num_e : num_e));
top->u.dbl *= pow (10.0, ((flags & flag_num_e_negative) ? - num_e : num_e));
}
if (flags & flag_num_negative)
@@ -942,7 +942,7 @@ json_value * json_parse_ex (json_settings * settings,
e_unknown_value:
sprintf (error, "%d:%d: Unknown value", line_and_col);
sprintf (error, "%u:%u: Unknown value", line_and_col);
goto e_failed;
e_alloc_failure:
@@ -952,7 +952,7 @@ e_alloc_failure:
e_overflow:
sprintf (error, "%d:%d: Too long (caught overflow)", line_and_col);
sprintf (error, "%u:%u: Too long (caught overflow)", line_and_col);
goto e_failed;
e_failed:

View File

@@ -5,7 +5,8 @@
/* Header file for language support for various languages. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -6,8 +6,9 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2023 by Dianne Skoll */
/* This file is Copyright (C) 1993 by Mogens Lynnerup. */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -80,10 +81,10 @@
#define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<5) ? " om natten" : " om formiddagen" : (hour > 17) ? " om aftenen" : " om eftermiddagen";
#define L_ORDINAL_OVERRIDE plu = ".";
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
#define L_E_OVER sprintf(s, "den %02d%c%02d%c%04d", d, DateSep, m+1, DateSep, y);
#define L_F_OVER sprintf(s, "den %02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); }
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
#define L_H_OVER sprintf(s, "den %02d%c%02d", d, DateSep, m+1);
#define L_I_OVER sprintf(s, "den %02d%c%02d", m+1, DateSep, d);
#define L_U_OVER L_A_OVER

View File

@@ -11,7 +11,8 @@
/* Further corrections by Erik-Jan Vens */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -5,7 +5,8 @@
/* Support for the English language. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -11,7 +11,8 @@
/* */
/* This file is part of REMIND. */
/* This file is Copyright (C) 1993-1998 by Mikko Silvonen. */
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -103,19 +104,19 @@
default: plu = ":ntenä"; break; \
} \
}
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s%s %d. %s%s %d", DayName[jul%7], L_ON, d, MonthName[m], L_PARTIT, y); }
#define L_C_OVER if (altmode == '*') { sprintf(s, "%s", DayName[jul%7]); } else { sprintf(s, "%s%s", DayName[jul%7], L_ON); }
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s%s %d. %s%s %d", DayName[dse%7], L_ON, d, MonthName[m], L_PARTIT, y); }
#define L_C_OVER if (altmode == '*') { sprintf(s, "%s", DayName[dse%7]); } else { sprintf(s, "%s%s", DayName[dse%7], L_ON); }
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DateSep, m+1, DateSep, y);
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s%s %d. %s%s", DayName[jul%7], L_ON, d, MonthName[m], L_PARTIT); }
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s%s %d. %s%s", DayName[dse%7], L_ON, d, MonthName[m], L_PARTIT); }
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1);
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d);
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s %d", DayName[jul%7], MonthName[m], d, plu, y); } else { sprintf(s, "%s%s %sn %d%s %d", DayName[jul%7], L_ON, MonthName[m], d, plu, y); }
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s", DayName[jul%7], MonthName[m], d, plu); } else { sprintf(s, "%s%s %sn %d%s", DayName[jul%7], L_ON, MonthName[m], d, plu); }
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s %d", DayName[dse%7], MonthName[m], d, plu, y); } else { sprintf(s, "%s%s %sn %d%s %d", DayName[dse%7], L_ON, MonthName[m], d, plu, y); }
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s", DayName[dse%7], MonthName[m], d, plu); } else { sprintf(s, "%s%s %sn %d%s", DayName[dse%7], L_ON, MonthName[m], d, plu); }
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
#define L_Q_OVER sprintf(s, "n");
#define L_U_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s %d", DayName[jul%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s%s %d%s %s%s %d", DayName[jul%7], L_ON, d, plu, MonthName[m], L_PARTIT, y); }
#define L_V_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s", DayName[jul%7], d, plu, MonthName[m]); } else { sprintf(s, "%s%s %d%s %s%s", DayName[jul%7], L_ON, d, plu, MonthName[m], L_PARTIT); }
#define L_U_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s %d", DayName[dse%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s%s %d%s %s%s %d", DayName[dse%7], L_ON, d, plu, MonthName[m], L_PARTIT, y); }
#define L_V_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s", DayName[dse%7], d, plu, MonthName[m]); } else { sprintf(s, "%s%s %d%s %s%s", DayName[dse%7], L_ON, d, plu, MonthName[m], L_PARTIT); }
#define L_1_OVER \
if (tdiff == 0) \
sprintf(s, "%s", L_NOW); \
@@ -253,7 +254,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2023 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETAVERSIO <<<<\n");
#endif

View File

@@ -8,9 +8,10 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2023 by Dianne Skoll */
/* This file is Copyright (C) 1993 by Laurent Duperval and */
/* Dianne Skoll. */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -106,9 +107,9 @@ else if (tdiff < 0) { \
sprintf(s, "dans %d heure%s et %d minute%s", hdiff, hplu, mdiff, mplu); \
}
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s, %d", DayName[jul%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s %s, %d%s %s, %d", L_ON, DayName[jul%7], d, plu, MonthName[m], y); }
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s, %d", DayName[dse%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s %s, %d%s %s, %d", L_ON, DayName[dse%7], d, plu, MonthName[m], y); }
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s", DayName[jul%7], d, plu, MonthName[m]); } else { sprintf(s, "%s %s, %d%s %s", L_ON, DayName[jul%7], d, plu, MonthName[m]); }
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s", DayName[dse%7], d, plu, MonthName[m]); } else { sprintf(s, "%s %s, %d%s %s", L_ON, DayName[dse%7], d, plu, MonthName[m]); }
/* The next ones are used only when MK_GLOBALS is set */
#ifdef MK_GLOBALS
@@ -227,7 +228,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2023 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif

View File

@@ -9,7 +9,8 @@
/* I don't speak German. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -81,7 +82,7 @@
See the file dosubst.c for more info. */
#define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<5) ? " nachts" : " vormittags" : (hour > 17) ? " abends" : " nachmittags";
#define L_ORDINAL_OVERRIDE plu = ".";
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); }
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
#define L_U_OVER L_A_OVER
#define L_V_OVER L_G_OVER

View File

@@ -5,8 +5,9 @@
/* Support for the Icelandic language. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -7,7 +7,8 @@
/* This file is part of REMIND. */
/* It is Copyright (C) 1996 by Valerio Aimale */
/* */
/* Remind is copyright (C) 1992-2022 by Dianne Skoll */
/* Remind is copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -84,30 +85,30 @@
#define L_HPLU_OVER hplu = (hdiff == 1 ? "a" : "e");
#define L_MPLU_OVER mplu = (mdiff == 1 ? "o" : "i");
#define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d,\
#define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d,\
MonthName[m], y);
#define L_C_OVER sprintf(s, "%s", DayName[jul%7]);
#define L_C_OVER sprintf(s, "%s", DayName[dse%7]);
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DateSep,\
m+1, DateSep, y);
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
#define L_G_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]);
#define L_G_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, MonthName[m]);
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1);
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d);
#define L_J_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, \
#define L_J_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d, \
MonthName[m], y);
#define L_K_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, \
#define L_K_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, \
MonthName[m]);
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
#define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, \
#define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d, \
MonthName[m], y);
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, \
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, \
MonthName[m]);

View File

@@ -6,7 +6,8 @@
/* */
/* This file is part of REMIND. */
/* This file is Copyright (C) 1993 by Trygve Randen. */
/* Remind is Copyright (C) 1992-2022 by Dianne Skoll */
/* Remind is Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -77,7 +78,7 @@
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
See the file dosubst.c for more info. */
#define L_ORDINAL_OVERRIDE plu = ".";
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); }
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
#define L_U_OVER L_A_OVER
#define L_V_OVER L_G_OVER

View File

@@ -9,7 +9,8 @@
/* Polish. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -95,8 +96,8 @@ ampm = (hour<12) ? \
: (hour<22) ? " wieczorem" \
: " w nocy";
#define L_ORDINAL_OVERRIDE plu = "";
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); }
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
#define L_U_OVER L_A_OVER
#define L_V_OVER L_G_OVER
@@ -243,7 +244,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2023 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif

View File

@@ -8,9 +8,10 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2023 by Dianne Skoll */
/* This file is Copyright (C) 1996 by Marco Paganini and */
/* Dianne Skoll. */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -88,26 +89,26 @@
#define _ON_WEEKDAY(x) ((x % 7) < 2) ? "no" : "na"
#define L_A_OVER \
sprintf(s, "%s %s, %d de %s de %d", _ON_WEEKDAY(jul), DayName[jul%7], d, MonthName[m], y);
sprintf(s, "%s %s, %d de %s de %d", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m], y);
#define L_C_OVER \
sprintf(s, "%s %s", _ON_WEEKDAY(jul), DayName[jul%7]);
sprintf(s, "%s %s", _ON_WEEKDAY(dse), DayName[dse%7]);
#define L_G_OVER \
sprintf(s, "%s %s, %d %s", _ON_WEEKDAY(jul), DayName[jul%7], d, MonthName[m]);
sprintf(s, "%s %s, %d %s", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m]);
#define L_J_OVER \
sprintf(s, "%s %s, %d de %s de %d", _ON_WEEKDAY(jul), DayName[jul%7], d, MonthName[m], y);
sprintf(s, "%s %s, %d de %s de %d", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m], y);
#define L_K_OVER \
sprintf(s, "%s %s, %d de %s", _ON_WEEKDAY(jul), DayName[jul%7], d, MonthName[m]);
sprintf(s, "%s %s, %d de %s", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m]);
/* Portuguese does not use some suffixes, some some %u and %j are the same */
#define L_U_OVER \
sprintf(s, "%s %s, %d de %s de %d", _ON_WEEKDAY(jul), DayName[jul%7], d, MonthName[m], y);
sprintf(s, "%s %s, %d de %s de %d", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m], y);
#define L_V_OVER \
sprintf(s, "%s %s, %d de %s", _ON_WEEKDAY(jul), DayName[jul%7], d, MonthName[m]);
sprintf(s, "%s %s, %d de %s", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m]);
#define L_1_OVER \
{ \
@@ -252,7 +253,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2023 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> VERSAO BETA <<<<\n");
#endif

View File

@@ -8,8 +8,9 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2023 by Dianne Skoll */
/* This file is Copyright (C) 1996-1998 by Liviu Daia */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -84,14 +85,14 @@
#define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<4) ? " noaptea" : " dimineaţa" : (hour > 17) ? " seara" : " după-amiaza";
#define L_ORDINAL_OVERRIDE plu = "";
#define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, MonthName[m], y);
#define L_C_OVER sprintf(s, "%s", DayName[jul%7]);
#define L_G_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]);
#define L_J_OVER sprintf(s, "%s, %s %d, %d", DayName[jul%7], MonthName[m], d, y);
#define L_K_OVER sprintf(s, "%s, %s %d", DayName[jul%7], MonthName[m], d);
#define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d, MonthName[m], y);
#define L_C_OVER sprintf(s, "%s", DayName[dse%7]);
#define L_G_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, MonthName[m]);
#define L_J_OVER sprintf(s, "%s, %s %d, %d", DayName[dse%7], MonthName[m], d, y);
#define L_K_OVER sprintf(s, "%s, %s %d", DayName[dse%7], MonthName[m], d);
#define L_S_OVER
#define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, MonthName[m], y);
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]);
#define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d, MonthName[m], y);
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, MonthName[m]);
#define L_1_OVER \
if (tdiff == 0) \
sprintf(s, L_NOW); \

View File

@@ -7,7 +7,8 @@
/* Author: Rafa Couto <rafacouto@biogate.com> */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/

View File

@@ -6,7 +6,8 @@
/* routines, etc. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -131,7 +132,7 @@ int main(int argc, char *argv[])
}
if (Iterations) {
PerIterationInit();
JulianToday++;
DSEToday++;
}
}
return 0;
@@ -176,10 +177,12 @@ static void DoReminders(void)
Parser p;
int purge_handled;
DidMsgReminder = 0;
if (!UseStdin) {
FileAccessDate = GetAccessDate(InitialFile);
} else {
FileAccessDate = JulianToday;
FileAccessDate = DSEToday;
}
if (FileAccessDate < 0) {
@@ -315,13 +318,16 @@ static void DoReminders(void)
/***************************************************************/
/* */
/* Julian */
/* DSE */
/* */
/* Given day, month, year, return Julian date in days since */
/* DSE stands for "Days Since Epoch"; the Remind epoch is */
/* midnight on 1990-01-01 */
/* */
/* Given day, month, year, return DSE date in days since */
/* 1 January 1990. */
/* */
/***************************************************************/
int Julian(int year, int month, int day)
int DSE(int year, int month, int day)
{
int y1 = BASE-1, y2 = year-1;
@@ -335,15 +341,15 @@ int Julian(int year, int month, int day)
/***************************************************************/
/* */
/* FromJulian */
/* FromDSE */
/* */
/* Convert a Julian date to year, month, day. You may supply */
/* Convert a DSE date to year, month, day. You may supply */
/* NULL for y, m or d if you're not interested in that value */
/* */
/***************************************************************/
void FromJulian(int jul, int *y, int *m, int *d)
void FromDSE(int dse, int *y, int *m, int *d)
{
int try_yr = (jul / 365) + BASE;
int try_yr = (dse / 365) + BASE;
int try_mon = 0;
int t;
@@ -353,17 +359,17 @@ void FromJulian(int jul, int *y, int *m, int *d)
int y100 = (y2 / 100) - (y1 / 100); /* Don't count multiples of 100... */
int y400 = (y2 / 400) - (y1 / 400); /* ... but do count multiples of 400 */
int try_jul= 365 * (try_yr-BASE) + y4 - y100 + y400;
int try_dse= 365 * (try_yr-BASE) + y4 - y100 + y400;
while (try_jul > jul) {
while (try_dse > dse) {
try_yr--;
try_jul -= DaysInYear(try_yr);
try_dse -= DaysInYear(try_yr);
}
jul -= try_jul;
dse -= try_dse;
t = DaysInMonth(try_mon, try_yr);
while (jul >= t) {
jul -= t;
while (dse >= t) {
dse -= t;
try_mon++;
t = DaysInMonth(try_mon, try_yr);
}
@@ -374,11 +380,28 @@ void FromJulian(int jul, int *y, int *m, int *d)
*m = try_mon;
}
if (d) {
*d = jul + 1;
*d = dse + 1;
}
return;
}
int JulianToGregorianOffset(int y, int m)
{
int offset = 13;
int centuries;
int four_centuries;
if (y >= 2100) {
centuries = (y - 2000) / 100;
four_centuries = (y - 2000) / 400;
offset += centuries - four_centuries;
if (!(y%100) && (y % 400)) {
if (m < 2) {
offset--; /* Offset increments in March */
}
}
}
return offset;
}
/***************************************************************/
/* */
/* ParseChar */
@@ -747,7 +770,7 @@ long SystemTime(int realtime)
/* */
/* SystemDate */
/* */
/* Obtains today's date. Returns Julian date or -1 for */
/* Obtains today's date. Returns DSE date or -1 for */
/* failure. (Failure happens if sys date is before BASE */
/* year.) */
/* */
@@ -764,7 +787,7 @@ int SystemDate(int *y, int *m, int *d)
*m = t->tm_mon;
*y = t->tm_year + 1900;
return Julian(*y, *m, *d);
return DSE(*y, *m, *d);
}
@@ -857,7 +880,7 @@ int DoIfTrig(ParsePtr p)
unsigned syndrome;
Trigger trig;
TimeTrig tim;
int jul;
int dse;
if ((size_t) NumIfs >= IF_NEST) return E_NESTED_IF;
@@ -865,7 +888,7 @@ int DoIfTrig(ParsePtr p)
else {
if ( (r=ParseRem(p, &trig, &tim, 1)) ) return r;
if (trig.typ != NO_TYPE) return E_PARSE_ERR;
jul = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
if (r) {
if (r != E_CANT_TRIG || !trig.maybe_uncomputable) {
if (!Hush || r != E_RUN_DISABLED) {
@@ -875,7 +898,7 @@ int DoIfTrig(ParsePtr p)
syndrome = IF_FALSE | BEFORE_ELSE;
}
else {
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
if (ShouldTriggerReminder(&trig, &tim, dse, &err)) {
syndrome = IF_TRUE | BEFORE_ELSE;
} else {
syndrome = IF_FALSE | BEFORE_ELSE;
@@ -1139,7 +1162,7 @@ int DoErrMsg(ParsePtr p)
DBufInit(&buf);
t.typ = MSG_TYPE;
tt.ttime = SystemTime(0) / 60;
if ( (r=DoSubst(p, &buf, &t, &tt, JulianToday, NORMAL_MODE)) ) {
if ( (r=DoSubst(p, &buf, &t, &tt, DSEToday, NORMAL_MODE)) ) {
return r;
}
s = DBufValue(&buf);
@@ -1169,24 +1192,24 @@ static int FoldArray[2][7] = {
{2024, 2008, 2020, 2004, 2016, 2000, 2012}
};
int CalcMinsFromUTC(int jul, int tim, int *mins, int *isdst)
int CalcMinsFromUTC(int dse, int tim, int *mins, int *isdst)
{
/* Convert jul and tim to an Unix tm struct */
/* Convert dse and tim to an Unix tm struct */
int yr, mon, day;
int tdiff;
struct tm local, utc, *temp;
time_t loc_t, utc_t;
int isdst_tmp;
FromJulian(jul, &yr, &mon, &day);
FromDSE(dse, &yr, &mon, &day);
/* If the year is greater than 2037, some Unix machines have problems.
Fold it back to a "similar" year and trust that the UTC calculations
are still valid... */
if (FoldYear && yr>2037) {
jul = Julian(yr, 0, 1);
yr = FoldArray[IsLeapYear(yr)][jul%7];
dse = DSE(yr, 0, 1);
yr = FoldArray[IsLeapYear(yr)][dse%7];
}
local.tm_sec = 0;
local.tm_min = tim % 60;
@@ -1628,7 +1651,7 @@ System(char const *cmd)
int r;
r = system(cmd);
if (r == 0) {
r = 1;
return;
}
}

View File

@@ -5,7 +5,8 @@
/* Calculations for figuring out moon phases. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -143,7 +144,7 @@ static double phase (double, double *, double *, double *, double *, double *, d
/* */
/* jdate */
/* */
/* Convert a date and time to Julian day and fraction. */
/* Convert a date and time to DSE day and fraction. */
/* */
/***************************************************************/
static long jdate(int y, int mon, int day)
@@ -400,9 +401,9 @@ static double phase(double pdate,
double *suangdia)
{
double Day, N, M, Ec, Lambdasun, ml, MM, MN, Ev, Ae, A3, MmP,
mEc, A4, lP, V, lPP, NP, y, x, Lambdamoon,
MoonAge, MoonPhase,
double Day, N, M, Ec, Lambdasun, ml, MM, Ev, Ae, A3, MmP,
mEc, A4, lP, V, lPP,
MoonAge, Phase,
MoonDist, MoonDFrac, MoonAng,
F, SunDist, SunAng;
@@ -431,9 +432,6 @@ static double phase(double pdate,
/* Moon's mean anomaly */
MM = fixangle(ml - 0.1114041 * Day - mmlongp);
/* Moon's ascending node mean longitude */
MN = fixangle(mlnode - 0.0529539 * Day);
/* Evection */
Ev = 1.2739 * sin(torad(2 * (ml - Lambdasun) - MM));
@@ -461,26 +459,13 @@ static double phase(double pdate,
/* 1 longitude */
lPP = lP + V;
/* Corrected longitude of the node */
NP = MN - 0.16 * sin(torad(M));
/* Y inclination coordinate */
y = sin(torad(lPP - NP)) * cos(torad(minc));
/* X inclination coordinate */
x = cos(torad(lPP - NP));
/* Ecliptic longitude */
Lambdamoon = todeg(atan2(y, x));
Lambdamoon += NP;
/* Calculation of the phase of the Moon */
/* Age of the Moon in degrees */
MoonAge = lPP - Lambdasun;
/* Phase of the Moon */
MoonPhase = (1 - cos(torad(MoonAge))) / 2;
Phase = (1 - cos(torad(MoonAge))) / 2;
/* Calculate distance of moon from the centre of the Earth */
@@ -492,7 +477,7 @@ static double phase(double pdate,
MoonDFrac = MoonDist / msmax;
MoonAng = mangsiz / MoonDFrac;
if(pphase) *pphase = MoonPhase;
if(pphase) *pphase = Phase;
if(mage) *mage = synmonth * (fixangle(MoonAge) / 360.0);
if(dist) *dist = MoonDist;
if(angdia) *angdia = MoonAng;
@@ -520,10 +505,10 @@ int MoonPhase(int date, int time)
LocalToUTC(date, time, &utcd, &utct);
/* Convert from Remind representation to year/mon/day */
FromJulian(utcd, &y, &m, &d);
FromDSE(utcd, &y, &m, &d);
/* Convert to a true Julian date -- sorry for the name clashes! */
jd = jtime(y, m, d, (utct / 60), (utct % 60), 0);
/* Convert to a Julian date */
jd = jtime(y, m, d, (utct / 60), (utct % 60), 0);
/* Calculate moon phase */
mp = 360.0 * phase(jd, NULL, NULL, NULL, NULL, NULL, NULL);
@@ -553,8 +538,8 @@ void HuntPhase(int startdate, int starttim, int phas, int *date, int *time)
LocalToUTC(startdate, starttim, &utcd, &utct);
/* Convert from Remind representation to year/mon/day */
FromJulian(utcd, &y, &m, &d);
/* Convert to a true Julian date -- sorry for the name clashes! */
FromDSE(utcd, &y, &m, &d);
/* Convert to a true Julian date */
jdorig = jtime(y, m, d, (utct / 60), (utct % 60), 0);
jd = jdorig - 45.0;
nt1 = meanphase(jd, 0.0, &k1);
@@ -572,7 +557,7 @@ void HuntPhase(int startdate, int starttim, int phas, int *date, int *time)
jyear(jd, &y, &m, &d);
jhms(jd, &h, &min, &s);
d1 = Julian(y, m, d);
d1 = DSE(y, m, d);
t1 = h*60 + min;
UTCToLocal(d1, t1, date, time);
}

View File

@@ -6,7 +6,8 @@
/* the data structures for OMITted dates. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -187,7 +188,7 @@ int PopOmitContext(ParsePtr p)
/* OK or an error code. */
/* */
/***************************************************************/
int IsOmitted(int jul, int localomit, char const *omitfunc, int *omit)
int IsOmitted(int dse, int localomit, char const *omitfunc, int *omit)
{
int y, m, d;
@@ -199,7 +200,7 @@ int IsOmitted(int jul, int localomit, char const *omitfunc, int *omit)
int r;
Value v;
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
sprintf(expr, "%s('%04d-%02d-%02d')",
omitfunc, y, m+1, d);
s = expr;
@@ -214,24 +215,24 @@ int IsOmitted(int jul, int localomit, char const *omitfunc, int *omit)
}
/* Is it omitted because of local omits? */
if (localomit & (1 << (jul % 7))) {
if (localomit & (1 << (dse % 7))) {
*omit = 1;
return OK;
}
/* Is it omitted because of global weekday omits? */
if (WeekdayOmits & (1 << (jul % 7))) {
if (WeekdayOmits & (1 << (dse % 7))) {
*omit = 1;
return OK;
}
/* Is it omitted because of fully-specified omits? */
if (BexistsIntArray(FullOmitArray, NumFullOmits, jul)) {
if (BexistsIntArray(FullOmitArray, NumFullOmits, dse)) {
*omit = 1;
return OK;
}
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
if (BexistsIntArray(PartialOmitArray, NumPartialOmits, (m << 5) + d)) {
*omit = 1;
return OK;
@@ -333,7 +334,7 @@ int DoOmit(ParsePtr p)
if (y[seen_through] != NO_YR) return E_YR_TWICE;
if (m[seen_through] != NO_MON) return E_MON_TWICE;
if (d[seen_through] != NO_DAY) return E_DAY_TWICE;
FromJulian(tok.val, &y[seen_through], &m[seen_through], &d[seen_through]);
FromDSE(tok.val, &y[seen_through], &m[seen_through], &d[seen_through]);
break;
case T_Year:
@@ -457,8 +458,8 @@ int DoOmit(ParsePtr p)
/* Full OMITs */
if (d[0] > DaysInMonth(m[0], y[0])) return E_BAD_DATE;
if (d[1] > DaysInMonth(m[1], y[1])) return E_BAD_DATE;
start = Julian(y[0], m[0], d[0]);
end = Julian(y[1], m[1], d[1]);
start = DSE(y[0], m[0], d[0]);
end = DSE(y[1], m[1], d[1]);
if (end < start) {
Eprint("Error: THROUGH date earlier than start date");
return E_BAD_DATE;
@@ -479,11 +480,11 @@ int DoOmit(ParsePtr p)
}
int
AddGlobalOmit(int jul)
AddGlobalOmit(int dse)
{
if (NumFullOmits == MAX_FULL_OMITS) return E_2MANY_FULL;
if (!BexistsIntArray(FullOmitArray, NumFullOmits, jul)) {
InsertIntoSortedArray(FullOmitArray, NumFullOmits, jul);
if (!BexistsIntArray(FullOmitArray, NumFullOmits, dse)) {
InsertIntoSortedArray(FullOmitArray, NumFullOmits, dse);
NumFullOmits++;
}
return OK;
@@ -499,7 +500,7 @@ DumpOmits(void)
printf("\tNone.\n");
} else {
for (i=0; i<NumFullOmits; i++) {
FromJulian(FullOmitArray[i], &y, &m, &d);
FromDSE(FullOmitArray[i], &y, &m, &d);
printf("\t%04d%c%02d%c%02d\n",
y, DateSep, m+1, DateSep, d);
}

View File

@@ -5,7 +5,8 @@
/* Function Prototypes. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -34,11 +35,11 @@ int DoRem (ParsePtr p);
int DoFlush (ParsePtr p);
void DoExit (ParsePtr p);
int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals);
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int jul);
int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int jul, int *err);
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul, int mode);
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int jul, int tim);
int ParseLiteralDate (char const **s, int *jul, int *tim);
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queued);
int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int dse, int *err);
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse, int mode);
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int dse, int tim);
int ParseLiteralDate (char const **s, int *dse, int *tim);
int ParseLiteralTime (char const **s, int *tim);
int EvalExpr (char const **e, Value *v, ParsePtr p);
int DoCoerce (char type, Value *v);
@@ -50,13 +51,14 @@ int DoInclude (ParsePtr p, enum TokTypes tok);
int DoIncludeCmd (ParsePtr p);
int IncludeFile (char const *fname);
int GetAccessDate (char const *file);
int SetAccessDate (char const *fname, int jul);
int SetAccessDate (char const *fname, int dse);
int TopLevel (void);
int CallFunc (BuiltinFunc *f, int nargs);
void InitRemind (int argc, char const *argv[]);
void Usage (void);
int Julian (int year, int month, int day);
void FromJulian (int jul, int *y, int *m, int *d);
int DSE (int year, int month, int day);
void FromDSE (int dse, int *y, int *m, int *d);
int JulianToGregorianOffset(int y, int m);
int ParseChar (ParsePtr p, int *err, int peek);
int ParseToken (ParsePtr p, DynamicBuffer *dbuf);
int ParseIdentifier (ParsePtr p, DynamicBuffer *dbuf);
@@ -86,7 +88,7 @@ int DoClear (ParsePtr p);
int DestroyOmitContexts (void);
int PushOmitContext (ParsePtr p);
int PopOmitContext (ParsePtr p);
int IsOmitted (int jul, int localomit, char const *omitfunc, int *omit);
int IsOmitted (int dse, int localomit, char const *omitfunc, int *omit);
int DoOmit (ParsePtr p);
int QueueReminder (ParsePtr p, Trigger *trig, TimeTrig *tim, char const *sched);
void HandleQueuedReminders (void);
@@ -96,9 +98,7 @@ void FindNumericToken (char const *s, Token *t);
int ComputeTrigger (int today, Trigger *trig, TimeTrig *tim, int *err, int save_in_globals);
int ComputeTriggerNoAdjustDuration (int today, Trigger *trig, TimeTrig *tim, int *err, int save_in_globals, int duration_days);
int AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int save_in_globals);
int ComputeScanStart(int today, Trigger *trig, TimeTrig *tt);
char *StrnCpy (char *dest, char const *source, int n);
int StrMatch (char const *s1, char const *s2, int n);
int StrinCmp (char const *s1, char const *s2, int n);
char *StrDup (char const *s);
int StrCmpi (char const *s1, char const *s2);
@@ -120,24 +120,24 @@ unsigned int HashVal (char const *str);
int DateOK (int y, int m, int d);
Operator *FindOperator (char const *name, Operator where[], int num);
BuiltinFunc *FindFunc (char const *name, BuiltinFunc where[], int num);
int InsertIntoSortBuffer (int jul, int tim, char const *body, int typ, int prio);
int InsertIntoSortBuffer (int dse, int tim, char const *body, int typ, int prio);
void IssueSortedReminders (void);
int UserFuncExists (char const *fn);
void JulToHeb (int jul, int *hy, int *hm, int *hd);
void DSEToHeb (int dse, int *hy, int *hm, int *hd);
int HebNameToNum (char const *mname);
char const *HebMonthName (int m, int y);
int RoshHashana (int i);
long DaysToHebYear (int y);
int DaysInHebYear (int y);
char const *DaysInHebMonths (int ylen);
int HebToJul (int hy, int hm, int hd);
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 julstart, int hm, int hd, int yahr, int adarbehave, int *ans);
int GetNextHebrewDate (int dsestart, int hm, int hd, int yahr, int adarbehave, int *ans);
int ComputeJahr (int y, int m, int d, int *ans);
int GetSysVar (char const *name, Value *val);
int SetSysVar (char const *name, Value *val);
void DumpSysVarByName (char const *name);
int CalcMinsFromUTC (int jul, int tim, int *mins, int *isdst);
int CalcMinsFromUTC (int dse, int tim, int *mins, int *isdst);
void FillParagraph (char const *s);
void LocalToUTC (int locdate, int loctime, int *utcdate, int *utctime);
void UTCToLocal (int utcdate, int utctime, int *locdate, int *loctime);
@@ -161,12 +161,12 @@ char const *Colorize(int r, int g, int b, int bg, int clamp);
void PrintJSONString(char const *s);
void PrintJSONKeyPairInt(char const *name, int val);
void PrintJSONKeyPairString(char const *name, char const *val);
void PrintJSONKeyPairDate(char const *name, int jul);
void PrintJSONKeyPairDate(char const *name, int dse);
void PrintJSONKeyPairDateTime(char const *name, int dt);
void PrintJSONKeyPairTime(char const *name, int t);
void System(char const *cmd);
int ShellEscape(char const *in, DynamicBuffer *out);
int AddGlobalOmit(int jul);
int AddGlobalOmit(int dse);
void set_lat_and_long_from_components(void);
void set_components_from_lat_and_long(void);
@@ -175,9 +175,9 @@ char const *get_month_name(int mon);
int push_call(char const *filename, char const *func, int lineno);
void clear_callstack(void);
int have_callstack(void);
int print_callstack(FILE *fp);
void pop_call(void);
void FixSpecialType(Trigger *trig);
#ifdef REM_USE_WCHAR
#define _XOPEN_SOURCE 600
#include <wctype.h>

View File

@@ -5,7 +5,8 @@
/* Queue up reminders for subsequent execution. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -75,6 +76,7 @@ int QueueReminder(ParsePtr p, Trigger *trig,
QueuedRem *qelem;
if (DontQueue ||
trig->noqueue ||
tim->ttime == NO_TIME ||
trig->typ == CAL_TYPE ||
tim->ttime < SystemTime(0) / 60 ||
@@ -264,8 +266,8 @@ void HandleQueuedReminders(void)
/* Set up global variables so some functions like trigdate()
and trigtime() work correctly */
SaveAllTriggerInfo(&(q->t), &(q->tt), JulianToday, q->tt.ttime, 1);
(void) TriggerReminder(&p, &trig, &q->tt, JulianToday);
SaveAllTriggerInfo(&(q->t), &(q->tt), DSEToday, q->tt.ttime, 1);
(void) TriggerReminder(&p, &trig, &q->tt, DSEToday, 1);
if (Daemon < 0) {
printf("NOTE endreminder\n");
}

View File

@@ -5,7 +5,8 @@
/* Print a PostScript calendar. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -349,7 +350,7 @@ int main(int argc, char *argv[])
!strcmp(DBufValue(&buf), PSBEGIN2)) {
if (!validfile) {
if (Verbose) {
fprintf(stderr, "Rem2PS: Version %s Copyright 1992-2022 by Dianne Skoll\n\n", VERSION);
fprintf(stderr, "Rem2PS: Version %s Copyright 1992-2023 by Dianne Skoll\n\n", VERSION);
fprintf(stderr, "Generating PostScript calendar\n");
}
}
@@ -389,7 +390,7 @@ void DoPsCal(void)
month */
DBufInit(&buf);
DBufGets(&buf, stdin);
sscanf(DBufValue(&buf), "%s %s %d %d %d", month, year, &days, &wkday,
sscanf(DBufValue(&buf), "%39s %39s %d %d %d", month, year, &days, &wkday,
&MondayFirst);
/* Replace underscores in month name with spaces */
@@ -421,9 +422,9 @@ void DoPsCal(void)
}
DBufGets(&buf, stdin);
sscanf(DBufValue(&buf), "%s %d", prevm, &prevdays);
sscanf(DBufValue(&buf), "%39s %d", prevm, &prevdays);
DBufGets(&buf, stdin);
sscanf(DBufValue(&buf), "%s %d", nextm, &nextdays);
sscanf(DBufValue(&buf), "%39s %d", nextm, &nextdays);
/* Replace underscores with spaces in names of next/prev month */
s = prevm;

View File

@@ -5,7 +5,8 @@
/* Define the PostScript prologue */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -13,7 +14,7 @@ char *PSProlog1[] =
{
"% This file was produced by Remind and Rem2PS, written by",
"% Dianne Skoll.",
"% Remind and Rem2PS are Copyright 1992-2022 Dianne Skoll.",
"% Remind and Rem2PS are Copyright 1992-2023 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",

View File

@@ -5,7 +5,8 @@
/* Routines for sorting reminders by trigger date */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -34,8 +35,8 @@ typedef struct sortrem {
/* The sorted reminder queue */
static Sortrem *SortedQueue = (Sortrem *) NULL;
static Sortrem *MakeSortRem (int jul, int tim, char const *body, int typ, int prio);
static void IssueSortBanner (int jul);
static Sortrem *MakeSortRem (int dse, int tim, char const *body, int typ, int prio);
static void IssueSortBanner (int dse);
/***************************************************************/
/* */
@@ -44,7 +45,7 @@ static void IssueSortBanner (int jul);
/* Create a new Sortrem entry - return NULL on failure. */
/* */
/***************************************************************/
static Sortrem *MakeSortRem(int jul, int tim, char const *body, int typ, int prio)
static Sortrem *MakeSortRem(int dse, int tim, char const *body, int typ, int prio)
{
Sortrem *new = NEW(Sortrem);
if (!new) return NULL;
@@ -55,7 +56,7 @@ static Sortrem *MakeSortRem(int jul, int tim, char const *body, int typ, int pri
return NULL;
}
new->trigdate = jul;
new->trigdate = dse;
new->trigtime = tim;
new->typ = typ;
new->priority = prio;
@@ -70,9 +71,9 @@ static Sortrem *MakeSortRem(int jul, int tim, char const *body, int typ, int pri
/* Insert a reminder into the sort buffer */
/* */
/***************************************************************/
int InsertIntoSortBuffer(int jul, int tim, char const *body, int typ, int prio)
int InsertIntoSortBuffer(int dse, int tim, char const *body, int typ, int prio)
{
Sortrem *new = MakeSortRem(jul, tim, body, typ, prio);
Sortrem *new = MakeSortRem(dse, tim, body, typ, prio);
Sortrem *cur = SortedQueue, *prev = NULL;
int ShouldGoAfter;
@@ -134,7 +135,7 @@ void IssueSortedReminders(void)
next = cur->next;
switch(cur->typ) {
case MSG_TYPE:
if (MsgCommand) {
if (MsgCommand && *MsgCommand) {
DoMsgCommand(MsgCommand, cur->text);
} else {
if (cur->trigdate != olddate) {
@@ -146,6 +147,10 @@ void IssueSortedReminders(void)
break;
case MSF_TYPE:
if (cur->trigdate != olddate) {
IssueSortBanner(cur->trigdate);
olddate = cur->trigdate;
}
FillParagraph(cur->text);
break;
@@ -168,7 +173,7 @@ void IssueSortedReminders(void)
/* defined to take one argument. */
/* */
/***************************************************************/
static void IssueSortBanner(int jul)
static void IssueSortBanner(int dse)
{
char BanExpr[64];
int y, m, d;
@@ -178,13 +183,13 @@ static void IssueSortBanner(int jul)
if (UserFuncExists("sortbanner") != 1) return;
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
sprintf(BanExpr, "sortbanner('%04d/%02d/%02d')", y, m+1, d);
y = EvalExpr(&s, &v, NULL);
if (y) return;
if (DoCoerce(STR_TYPE, &v)) return;
DBufInit(&buf);
if (!DoSubstFromString(v.v.str, &buf, jul, NO_TIME)) {
if (!DoSubstFromString(v.v.str, &buf, dse, NO_TIME)) {
if (*DBufValue(&buf)) printf("%s\n", DBufValue(&buf));
DBufFree(&buf);
}

View File

@@ -6,7 +6,8 @@
/* classifying the tokens parsed. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -80,6 +81,7 @@ Token TokArray[] = {
{ "monday", 3, T_WkDay, 0 },
{ "msf", 3, T_RemType, MSF_TYPE },
{ "msg", 3, T_RemType, MSG_TYPE },
{ "noqueue", 7, T_NoQueue, 0 },
{ "november", 3, T_Month, 10 },
{ "october", 3, T_Month, 9 },
{ "omit", 3, T_Omit, 0 },
@@ -239,16 +241,16 @@ void FindNumericToken(char const *s, Token *t)
/* If we hit a '-' or a '/', we may have a date or a datetime */
if (*s == '-' || *s == '/') {
char const *p = s_orig;
int jul, tim;
if (ParseLiteralDate(&p, &jul, &tim) == OK) {
int dse, tim;
if (ParseLiteralDate(&p, &dse, &tim) == OK) {
if (*p) return;
if (tim == NO_TIME) {
t->type = T_Date;
t->val = jul;
t->val = dse;
return;
}
t->type = T_DateTime;
t->val = MINUTES_PER_DAY * jul + tim;
t->val = MINUTES_PER_DAY * dse + tim;
}
return;
}
@@ -256,7 +258,6 @@ void FindNumericToken(char const *s, Token *t)
/* If we hit a comma, swallow it. This allows stuff
like Jan 6, 1998 */
if (*s == ',') {
s++;
/* Classify the number we've got */
if (t->val >= BASE && t->val <= BASE+YR_RANGE) t->type = T_Year;
else if (t->val >= 1 && t->val <= 31) t->type = T_Day;
@@ -355,7 +356,8 @@ static int TokStrCmp(Token const *t, char const *s)
register int r;
char const *tk = t->name;
while(*tk && *s && !(*s == ',' && *(s+1) == 0)) {
r = tolower(*tk) - tolower(*s);
/* t->name is already lower-case */
r = *tk - tolower(*s);
tk++;
s++;
if (r) return r;
@@ -363,5 +365,5 @@ static int TokStrCmp(Token const *t, char const *s)
/* Ignore trailing commas on s */
if (!*s || (*s == ',' && !*(s+1))) return 0;
return (tolower(*tk) - tolower(*s));
return (*tk - tolower(*s));
}

View File

@@ -5,7 +5,8 @@
/* Routines for figuring out the trigger date of a reminder */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -26,8 +27,8 @@
#define ADVANCE_TO_WD(x, wd) while (! ((wd) & (1 << ((x)%7)))) (x)++
static int JYear(int jul);
static int JMonth(int jul);
static int DSEYear(int dse);
static int DSEMonth(int dse);
static int NextSimpleTrig(int startdate, Trigger *trig, int *err);
static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart);
@@ -39,7 +40,7 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
/* ONLY the day of week, day, month and year components. */
/* Normally, returns -1 if the trigger has expired. As a */
/* special case, if D, M, Y [WD] are specified, returns the */
/* Julian date, regardless of whether it's expired. This is */
/* DSE date, regardless of whether it's expired. This is */
/* so that dates with a REP can be handled properly. */
/* */
/***************************************************************/
@@ -49,7 +50,7 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
int d, m, y, j, d2, m2, y2;
*err = 0;
FromJulian(startdate, &y, &m, &d);
FromDSE(startdate, &y, &m, &d);
d2 = d;
m2 = m;
y2 = y;
@@ -72,17 +73,17 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
if (m == 12) { m = 0; y++; }
}
while (trig->d > DaysInMonth(m, trig->y)) m++;
j = Julian(y, m, trig->d);
j = DSE(y, m, trig->d);
return j;
case GOT_MON:
if (m == trig->m) return startdate;
else if (m > trig->m) return Julian(y+1, trig->m, 1);
else return Julian(y, trig->m, 1);
else if (m > trig->m) return DSE(y+1, trig->m, 1);
else return DSE(y, trig->m, 1);
case GOT_YR:
if (y == trig->y) return startdate;
else if (y < trig->y) return Julian(trig->y, 0, 1);
else if (y < trig->y) return DSE(trig->y, 0, 1);
else return -1;
case GOT_DAY+GOT_MON:
@@ -94,10 +95,10 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
if (m > trig->m || (m == trig->m && d > trig->d)) y++;
/* Take care of Feb. 29 */
while (trig->d > DaysInMonth(trig->m, y)) y++;
return Julian(y, trig->m, trig->d);
return DSE(y, trig->m, trig->d);
case GOT_DAY+GOT_YR:
if (y < trig->y) return Julian(trig->y, 0, trig->d);
if (y < trig->y) return DSE(trig->y, 0, trig->d);
else if (y > trig->y) return -1;
if (d > trig->d) {
@@ -105,37 +106,37 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
if (m == 12) return -1;
}
while (trig->d > DaysInMonth(m, trig->y)) m++;
return Julian(trig->y, m, trig->d);
return DSE(trig->y, m, trig->d);
case GOT_MON+GOT_YR:
if (y > trig->y || (y == trig->y && m > trig->m)) return -1;
if (y < trig->y) return Julian(trig->y, trig->m, 1);
if (y < trig->y) return DSE(trig->y, trig->m, 1);
if (m == trig->m) return startdate;
return Julian(trig->y, trig->m, 1);
return DSE(trig->y, trig->m, 1);
case GOT_DAY+GOT_MON+GOT_YR:
if (trig->d > DaysInMonth(trig->m, trig->y)) {
*err = E_BAD_DATE;
return -1;
}
return Julian(trig->y, trig->m, trig->d);
return DSE(trig->y, trig->m, trig->d);
case GOT_YR+GOT_WD:
if (y > trig->y) return -1;
if (y < trig->y) j = Julian(trig->y, 0, 1);
if (y < trig->y) j = DSE(trig->y, 0, 1);
else j = startdate;
ADVANCE_TO_WD(j, trig->wd);
if (JYear(j) > trig->y) return -1;
if (DSEYear(j) > trig->y) return -1;
return j;
case GOT_MON+GOT_WD:
if (m == trig->m) {
j = startdate;
ADVANCE_TO_WD(j, trig->wd);
if (JMonth(j) == trig->m) return j;
if (DSEMonth(j) == trig->m) return j;
}
if (m >= trig->m) j = Julian(y+1, trig->m, 1);
else j = Julian(y, trig->m, 1);
if (m >= trig->m) j = DSE(y+1, trig->m, 1);
else j = DSE(y, trig->m, 1);
ADVANCE_TO_WD(j, trig->wd);
return j; /* Guaranteed to be within the month */
@@ -146,7 +147,7 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
/* If there are fewer days in previous month, no match */
if (trig->d <= DaysInMonth(m2, y2)) {
j = Julian(y2, m2, trig->d);
j = DSE(y2, m2, trig->d);
ADVANCE_TO_WD(j, trig->wd);
if (j >= startdate) return j;
@@ -155,7 +156,7 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
/* Try this month */
if (trig->d <= DaysInMonth(m, y)) {
j = Julian(y, m, trig->d);
j = DSE(y, m, trig->d);
ADVANCE_TO_WD(j, trig->wd);
if (j >= startdate) return j;
}
@@ -164,18 +165,18 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
m2 = m+1;
if (m2 > 11) { m2 = 0; y++; }
while (trig->d > DaysInMonth(m2, y)) m2++;
j = Julian(y, m2, trig->d);
j = DSE(y, m2, trig->d);
ADVANCE_TO_WD(j, trig->wd);
return j;
case GOT_WD+GOT_YR+GOT_DAY:
if (y > trig->y+1 || (y > trig->y && m>0)) return -1;
if (y > trig->y) {
j = Julian(trig->y, 11, trig->d);
j = DSE(trig->y, 11, trig->d);
ADVANCE_TO_WD(j, trig->wd);
if (j >= startdate) return j;
} else if (y < trig->y) {
j = Julian(trig->y, 0, trig->d);
j = DSE(trig->y, 0, trig->d);
ADVANCE_TO_WD(j, trig->wd);
return j;
} else {
@@ -183,17 +184,17 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
if (m > 0) {
m2 = m-1;
while (trig->d > DaysInMonth(m2, trig->y)) m2--;
j = Julian(trig->y, m2, trig->d);
j = DSE(trig->y, m2, trig->d);
ADVANCE_TO_WD(j, trig->wd);
if (JYear(j) > trig->y) return -1;
if (DSEYear(j) > trig->y) return -1;
if (j >= startdate) return j;
}
}
/* Try this month */
if (trig->d <= DaysInMonth(m, trig->y)) {
j = Julian(trig->y, m, trig->d);
j = DSE(trig->y, m, trig->d);
ADVANCE_TO_WD(j, trig->wd);
if (JYear(j) > trig->y) return -1;
if (DSEYear(j) > trig->y) return -1;
if (j >= startdate) return j;
}
@@ -201,9 +202,9 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
if (m == 11) return -1;
m++;
while (trig->d > DaysInMonth(m, trig->d)) m++;
j = Julian(trig->y, m, trig->d);
j = DSE(trig->y, m, trig->d);
ADVANCE_TO_WD(j, trig->wd);
if (JYear(j) > trig->y) return -1;
if (DSEYear(j) > trig->y) return -1;
return j;
case GOT_DAY+GOT_MON+GOT_WD:
@@ -220,34 +221,34 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
while (trig->d > DaysInMonth(trig->m, y)) y++;
/* Try last year */
j = Julian(y, trig->m, trig->d);
j = DSE(y, trig->m, trig->d);
ADVANCE_TO_WD(j, trig->wd);
if (j >= startdate) return j;
/* Try this year */
y++;
while (trig->d > DaysInMonth(trig->m, y)) y++;
j = Julian(y, trig->m, trig->d);
j = DSE(y, trig->m, trig->d);
ADVANCE_TO_WD(j, trig->wd);
if (j >= startdate) return j;
/* Must be next year */
y++;
while (trig->d > DaysInMonth(trig->m, y)) y++;
j = Julian(y, trig->m, trig->d);
j = DSE(y, trig->m, trig->d);
ADVANCE_TO_WD(j, trig->wd);
return j;
case GOT_WD+GOT_MON+GOT_YR:
if (y > trig->y || (y == trig->y && m > trig->m)) return -1;
if (trig->y > y || (trig->y == y && trig->m > m)) {
j = Julian(trig->y, trig->m, 1);
j = DSE(trig->y, trig->m, 1);
ADVANCE_TO_WD(j, trig->wd);
return j;
} else {
j = startdate;
ADVANCE_TO_WD(j, trig->wd);
FromJulian(j, &y2, &m2, &d2);
FromDSE(j, &y2, &m2, &d2);
if (m2 == trig->m) return j; else return -1;
}
@@ -256,7 +257,7 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
*err = E_BAD_DATE;
return -1;
}
j = Julian(trig->y, trig->m, trig->d);
j = DSE(trig->y, trig->m, trig->d);
ADVANCE_TO_WD(j, trig->wd);
return j;
@@ -269,25 +270,25 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
/***************************************************************/
/* */
/* JMonth - Given a Julian date, what's the month? */
/* DSEMonth - Given a DSE date, what's the month? */
/* */
/***************************************************************/
static int JMonth(int jul)
static int DSEMonth(int dse)
{
int y, m, d;
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
return m;
}
/***************************************************************/
/* */
/* JYear - Given a Julian date, what's the year? */
/* DSEYear - Given a DSE date, what's the year? */
/* */
/***************************************************************/
static int JYear(int jul)
static int DSEYear(int dse)
{
int y, m, d;
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
return y;
}
@@ -297,7 +298,7 @@ static int JYear(int jul)
/* */
/* Given a trigger, compute the next trigger date. */
/* */
/* Returns the Julian date of next trigger, -1 if */
/* Returns the DSE date of next trigger, -1 if */
/* expired, -2 if can't compute trigger date. */
/* */
/***************************************************************/
@@ -439,7 +440,7 @@ AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int sav
/* Change trigger date to today */
r = today;
if (DebugFlag & DB_PRTTRIG) {
FromJulian(r, &y, &m, &d);
FromDSE(r, &y, &m, &d);
fprintf(ErrFp, "%s(%d): Trig(adj) = %s, %d %s, %d",
FileName, LineNo,
get_day_name(r % 7),
@@ -590,7 +591,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
LastTrigValid = 1;
}
if (DebugFlag & DB_PRTTRIG) {
FromJulian(result, &y, &m, &d);
FromDSE(result, &y, &m, &d);
fprintf(ErrFp, "%s(%d): Trig = %s, %d %s, %d",
FileName, LineNo,
get_day_name(result % 7),
@@ -621,12 +622,10 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
fprintf(ErrFp, "%s(%d): %s\n",
FileName, LineNo, ErrMsg[E_EXPIRED]);
}
if (result != -1) {
if (save_in_globals) {
LastTriggerDate = result;
LastTrigValid = 1;
}
}
if (save_in_globals) {
LastTriggerDate = result;
LastTrigValid = 1;
}
return -1;
}
@@ -639,12 +638,10 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
/* Keep scanning... unless there's no point in doing it.*/
if (nextstart <= start) {
if (result != -1) {
if (save_in_globals) {
LastTriggerDate = result;
LastTrigValid = 1;
}
}
if (save_in_globals) {
LastTriggerDate = result;
LastTrigValid = 1;
}
trig->expired = 1;
if (DebugFlag & DB_PRTTRIG) {
fprintf(ErrFp, "%s(%d): %s\n",
@@ -661,40 +658,3 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
return -1;
}
/***************************************************************/
/* */
/* ComputeScanStart */
/* */
/* Figure out where to start scan from by examining SCANFROM */
/* and DURATION */
/* */
/***************************************************************/
int
ComputeScanStart(int today, Trigger *trig, TimeTrig *tt)
{
int minutes, days;
/* If we don't have a time/duration, just use scanfrom */
if (tt->ttime == NO_TIME ||
tt->duration == NO_TIME) {
if (trig->scanfrom == NO_DATE) {
return today;
}
return trig->scanfrom;
}
/* Calculate time-based SCANFROM */
minutes = tt->ttime + tt->duration - 1;
/* Figure out how many days to scan backwards from */
days = minutes / MINUTES_PER_DAY;
if (trig->scanfrom != NO_DATE) {
if (trig->scanfrom <= today - days) {
return trig->scanfrom;
} else {
return today - days;
}
}
return today - days;
}

View File

@@ -5,7 +5,8 @@
/* Type definitions all dumped here. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -77,6 +78,7 @@ typedef struct {
int eventduration; /* Original event duration (minutes) */
int maybe_uncomputable; /* Suppress "can't compute trigger" warnings */
int addomit; /* Add trigger date to global OMITs */
int noqueue; /* Don't queue even if timed */
char sched[VAR_NAME_LEN+1]; /* Scheduling function */
char warn[VAR_NAME_LEN+1]; /* Warning function */
char omitfunc[VAR_NAME_LEN+1]; /* OMITFUNC function */
@@ -156,7 +158,7 @@ enum TokTypes
T_Rem, T_Push, T_Pop, T_Preserve, T_Include, T_IncludeR, T_IncludeCmd, T_If, T_Else, T_EndIf,
T_IfTrig, T_ErrMsg,
T_Set, T_UnSet, T_Fset, T_Funset, T_Omit, T_Banner, T_Exit,
T_AddOmit,
T_AddOmit, T_NoQueue,
T_WkDay,
T_Month, T_Time, T_Date, T_DateTime,
T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta,

View File

@@ -6,7 +6,8 @@
/* functions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -55,7 +56,7 @@ static void DestroyLocalVals (UserFunc *f);
/***************************************************************/
/* */
/* DoFset */
/* DoFunset */
/* */
/* Undefine a user-defined function - the FUNSET command. */
/* */
@@ -123,8 +124,13 @@ int DoFset(ParsePtr p)
DBufFree(&buf);
return E_NO_MEM;
}
func->filename = StrDup(FileName);
if (FileName) {
func->filename = StrDup(FileName);
} else {
func->filename = StrDup("[cmdline]");
}
if (!func->filename) {
free(func);
return E_NO_MEM;
}
func->lineno = LineNo;
@@ -181,7 +187,7 @@ int DoFset(ParsePtr p)
/* Allow an optional = sign: FSET f(x) = x*x */
c = ParseNonSpaceChar(p, &r, 1);
if (c == '=') {
c = ParseNonSpaceChar(p, &r, 0);
(void) ParseNonSpaceChar(p, &r, 0);
}
/* Copy the text over */
if (p->isnested) {

View File

@@ -5,7 +5,8 @@
/* Useful utility functions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -40,22 +41,6 @@ char *StrnCpy(char *dest, char const *source, int n)
return odest;
}
/***************************************************************/
/* */
/* StrMatch */
/* */
/* Checks that two strings match (case-insensitive) to at */
/* least the specified number of characters, or the length */
/* of the first string, whichever is greater. */
/* */
/***************************************************************/
int StrMatch(char const *s1, char const *s2, int n)
{
int l;
if ((l = strlen(s1)) < n) return 0;
return !StrinCmp(s1, s2, l);
}
/***************************************************************/
/* */
/* StrinCmp - compare strings, case-insensitive */
@@ -222,13 +207,6 @@ clear_callstack(void)
callstack = NULL;
}
int
have_callstack(void)
{
if (callstack) return 1;
return 0;
}
static void
print_callstack_aux(FILE *fp, cs *entry)
{

View File

@@ -6,7 +6,8 @@
/* user- and system-defined variables. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2022 by Dianne Skoll */
/* Copyright (C) 1992-2023 by Dianne Skoll */
/* SPDX-License-Identifier: GPL-2.0-only */
/* */
/***************************************************************/
@@ -189,7 +190,7 @@ static int trig_day_func(int do_set, Value *val)
return OK;
}
FromJulian(LastTriggerDate, &y, &m, &d);
FromDSE(LastTriggerDate, &y, &m, &d);
val->v.val = d;
return OK;
}
@@ -204,7 +205,7 @@ static int trig_mon_func(int do_set, Value *val)
return OK;
}
FromJulian(LastTriggerDate, &y, &m, &d);
FromDSE(LastTriggerDate, &y, &m, &d);
val->v.val = m+1;
return OK;
}
@@ -219,7 +220,7 @@ static int trig_year_func(int do_set, Value *val)
return OK;
}
FromJulian(LastTriggerDate, &y, &m, &d);
FromDSE(LastTriggerDate, &y, &m, &d);
val->v.val = y;
return OK;
}
@@ -241,7 +242,7 @@ static int today_date_func(int do_set, Value *val)
{
UNUSED(do_set);
val->type = DATE_TYPE;
val->v.val = JulianToday;
val->v.val = DSEToday;
return OK;
}
static int today_day_func(int do_set, Value *val)
@@ -249,7 +250,7 @@ static int today_day_func(int do_set, Value *val)
int y, m, d;
UNUSED(do_set);
val->type = INT_TYPE;
FromJulian(JulianToday, &y, &m, &d);
FromDSE(DSEToday, &y, &m, &d);
val->v.val = d;
return OK;
}
@@ -259,7 +260,7 @@ static int today_mon_func(int do_set, Value *val)
int y, m, d;
UNUSED(do_set);
val->type = INT_TYPE;
FromJulian(JulianToday, &y, &m, &d);
FromDSE(DSEToday, &y, &m, &d);
val->v.val = m+1;
return OK;
}
@@ -269,7 +270,7 @@ static int today_year_func(int do_set, Value *val)
int y, m, d;
UNUSED(do_set);
val->type = INT_TYPE;
FromJulian(JulianToday, &y, &m, &d);
FromDSE(DSEToday, &y, &m, &d);
val->v.val = y;
return OK;
}
@@ -278,7 +279,7 @@ static int today_wday_func(int do_set, Value *val)
{
UNUSED(do_set);
val->type = INT_TYPE;
val->v.val = (JulianToday + 1) % 7;
val->v.val = (DSEToday + 1) % 7;
return OK;
}

43
tests/soleq.rem Normal file
View File

@@ -0,0 +1,43 @@
BANNER Solstice/Equinox Tests
SET $AddBlankLines 0
# Test solstice and equinox functions
MSG March Solstice 2022 is [localtoutc(soleq(0,2022))] UTC
MSG June Equinox 2022 is [localtoutc(soleq(1,2022))] UTC
MSG September Solstice 2022 is [localtoutc(soleq(2,2022))] UTC
MSG December Equinox 2022 is [localtoutc(soleq(3,2022))] UTC
MSG March Solstice 2023 is [localtoutc(soleq(0,2023))] UTC
MSG June Equinox 2023 is [localtoutc(soleq(1,2023))] UTC
MSG September Solstice 2023 is [localtoutc(soleq(2,2023))] UTC
MSG December Equinox 2023 is [localtoutc(soleq(3,2023))] UTC
MSG March Solstice 2024 is [localtoutc(soleq(0,2024))] UTC
MSG June Equinox 2024 is [localtoutc(soleq(1,2024))] UTC
MSG September Solstice 2024 is [localtoutc(soleq(2,2024))] UTC
MSG December Equinox 2024 is [localtoutc(soleq(3,2024))] UTC
MSG March Solstice 2025 is [localtoutc(soleq(0,2025))] UTC
MSG June Equinox 2025 is [localtoutc(soleq(1,2025))] UTC
MSG September Solstice 2025 is [localtoutc(soleq(2,2025))] UTC
MSG December Equinox 2025 is [localtoutc(soleq(3,2025))] UTC
MSG March Solstice 2026 is [localtoutc(soleq(0,2026))] UTC
MSG June Equinox 2026 is [localtoutc(soleq(1,2026))] UTC
MSG September Solstice 2026 is [localtoutc(soleq(2,2026))] UTC
MSG December Equinox 2026 is [localtoutc(soleq(3,2026))] UTC
MSG March Solstice 2030 is [localtoutc(soleq(0,2030))] UTC
MSG June Equinox 2030 is [localtoutc(soleq(1,2030))] UTC
MSG September Solstice 2030 is [localtoutc(soleq(2,2030))] UTC
MSG December Equinox 2030 is [localtoutc(soleq(3,2030))] UTC
MSG March Solstice 2050 is [localtoutc(soleq(0,2050))] UTC
MSG June Equinox 2050 is [localtoutc(soleq(1,2050))] UTC
MSG September Solstice 2050 is [localtoutc(soleq(2,2050))] UTC
MSG December Equinox 2050 is [localtoutc(soleq(3,2050))] UTC
MSG Next March Solstice is [localtoutc(soleq(0))] UTC
MSG Next June Equinox is [localtoutc(soleq(1))] UTC
MSG Next September Solstice is [localtoutc(soleq(2))] UTC
MSG Next December Equinox is [localtoutc(soleq(3))] UTC

View File

@@ -7,7 +7,8 @@
# in the build directory.
#
# This file is part of REMIND.
# Copyright (C) 1992-2022 Dianne Skoll
# Copyright (C) 1992-2023 Dianne Skoll
# SPDX-License-Identifier: GPL-2.0-only
# ---------------------------------------------------------------------------
DIR=`dirname $0`
@@ -26,6 +27,10 @@ if test `id -u` = 0 ; then
exit 1
fi
# Set a known timezone so moon phases show up in predictable places
TZ=UTC
export TZ
# If we're already in a utf-8 locale, do
# nothing; otherwise, set LC_ALL
OK=0
@@ -398,6 +403,28 @@ EOF
TZ=America/Toronto ../src/remind -dxe ../tests/tz.rem >> ../tests/test.out 2>&1
TZ=Europe/Berlin ../src/remind -dxe ../tests/tz.rem >> ../tests/test.out 2>&1
../src/remind ../tests/soleq.rem 1 April 2044 >> ../tests/test.out 2>&1
# Test that banner is printed on every iteration
echo "MSG Should be three banners." | ../src/remind - 2022-10-20 '*3' >> ../tests/test.out 2>&1
# World-writable file
rm -rf include_dir/ww
touch include_dir/ww
chmod 0666 include_dir/ww
../src/remind include_dir/ww >> ../tests/test.out 2>&1
rm -rf include_dir/ww
# World-writable directory
mkdir -p include_dir/ww
touch include_dir/ww/0.rem
chmod 0777 include_dir/ww
../src/remind include_dir/ww >> ../tests/test.out 2>&1
rm -rf include_dir/ww
# This segfaulted in 04.02.03
../src/remind -h '-imsgprefix(x)="foo"' /dev/null >> ../tests/test.out 2>&1
# Remove references to SysInclude, which is build-specific
grep -F -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out
cmp -s ../tests/test.out ../tests/test.cmp
@@ -408,6 +435,11 @@ else
echo "Remind: Acceptance test FAILED"
echo ""
echo "Examine the file test.out to see where it differs from the"
echo "reference file test.cmp."
echo "reference file test.cmp. Here are the first 200 lines of"
echo "diff -u test.out test.cmp"
echo ""
diff -u ../tests/test.out ../tests/test.cmp | head -n 200
echo ""
exit 1
fi

File diff suppressed because one or more lines are too long

View File

@@ -383,6 +383,14 @@ msg [a077]%
set a078 easterdate(today())
set a079 easterdate(1992)
set a080 easterdate(1995)
set a078 orthodoxeaster(today())
set a079 orthodoxeaster(1992)
set a080 orthodoxeaster(1995)
set a080 orthodoxeaster(2023)
set a080 orthodoxeaster(2024)
set a080 orthodoxeaster(2025)
set a080 orthodoxeaster(2026)
set a080 orthodoxeaster(2027)
set a081 ""
OMIT 1991-03-11
set a082 slide('1991-03-01', 7, "Sat", "Sun")
@@ -858,6 +866,21 @@ FUNSET circle square rectangle
# Should fail
SET a square(5)
# htmlescape
set a htmlescape("foo")
REM MSG [a]
set a htmlescape("<&>")
REM MSG [a]
set a htmlescape("@&^#*@&^##$*&@><><@#@#><@#>%%_#$foobarquux")
REM MSG [a]
# htmlstriptags
set a htmlstriptags("foobar")
set a htmlstriptags("This is <b>bold</b>")
set a htmlstriptags("This is <unclosed whut?")
set a htmlstriptags("this is > whut <b>foo</b>")
set a htmlstriptags("<img src=\"foo\">")
# Don't want Remind to queue reminders
EXIT

View File

@@ -11,7 +11,8 @@
# Use the output to verify your translations.
#
# This file is part of REMIND.
# Copyright (C) 1992-2022 Dianne Skoll
# Copyright (C) 1992-2023 Dianne Skoll
# SPDX-License-Identifier: GPL-2.0-only
#
# ---------------------------------------------------------------------------

View File

@@ -1,30 +1,30 @@
# Test conversion between local time and UTC
set a localtoutc('2022-01-01@12:00')
set a localtoutc('2022-03-13@02:59')
set a localtoutc('2022-03-13@03:00')
set a localtoutc('2022-03-13@03:01')
set a localtoutc('2022-03-13@03:59')
set a localtoutc('2022-03-13@04:00')
set a localtoutc('2022-03-13@04:01')
set a localtoutc('2022-06-01@12:00')
set a localtoutc('2022-11-06@01:59')
set a localtoutc('2022-11-06@02:00')
set a localtoutc('2022-11-06@02:01')
set a localtoutc('2022-11-06@02:59')
set a localtoutc('2022-11-06@03:00')
set a localtoutc('2022-11-06@03:01')
set a localtoutc('2022-12-01@12:00')
set b utctolocal('2022-01-01@17:00')
set b utctolocal('2022-03-13@06:00')
set b utctolocal('2022-03-13@06:01')
set b utctolocal('2022-03-13@06:59')
set b utctolocal('2022-03-13@07:01')
set b utctolocal('2022-03-13@07:59')
set b utctolocal('2022-03-13@07:00')
set b utctolocal('2022-03-13@07:01')
set b utctolocal('2022-03-13@07:59')
set b utctolocal('2022-06-01@16:00')
set b utctolocal('2022-11-06@05:59')
set b utctolocal('2022-11-06@06:00')
set b utctolocal('2022-11-06@06:01')
set b utctolocal('2022-11-06@06:59')
set b utctolocal('2022-11-06@03:59')
set b utctolocal('2022-11-06@07:00')
set b utctolocal('2022-11-06@07:01')
set b utctolocal('2022-12-01@17:00')
set b utctolocal('2022-11-06@07:59')
set b utctolocal('2022-11-06@08:00')
set b utctolocal('2022-11-06@08:01')
set b utctolocal('2022-12-01@18:00')
set c timezone('2022-07-01')
set c timezone('2022-12-01')

View File

@@ -3,6 +3,7 @@
#
# This file is part of REMIND.
# Copyright (C) 1992-2018 by Dianne Skoll
# SPDX-License-Identifier: GPL-2.0-only
echo Content-type: text/html
echo

View File

@@ -2,6 +2,7 @@
#
# This file is part of REMIND.
# Copyright (C) 1992-2018 by Dianne Skoll
# SPDX-License-Identifier: GPL-2.0-only
set now now()