Compare commits

..

51 Commits

Author SHA1 Message Date
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
89 changed files with 1291 additions and 699 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.02

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.02
AC_SUBST(VERSION)
AC_SUBST(PERL)
AC_SUBST(PERLARTIFACTS)

View File

@@ -1,5 +1,59 @@
CHANGES TO REMIND
* 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 +1918,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
# #
#############################################################################

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%"

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,23 +1,24 @@
# 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 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
@@ -25,30 +26,30 @@ REM MAYBE-UNCOMPUTABLE Sun March SATISFY [isdst($T) != isdst($T+1)] MSG Daylight
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%"
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
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 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 Nov 11 MSG Veterans Day
REM Oct 30 MSG %"Mischief Night%"
REM Oct 31 MSG %"Halloween%"
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 Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG Election Day
REM Thu 22 Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
REM Thu 22 Nov SCANFROM -7 ADDOMIT MSG Thanksgiving Day
REM Fri 23 Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
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

View File

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

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"

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

@@ -464,6 +464,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]
@@ -1100,7 +1101,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
@@ -2569,8 +2574,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.)
@@ -3431,6 +3436,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

View File

@@ -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;

View File

@@ -1,4 +1,5 @@
#!@PERL@
# SPDX-License-Identifier: GPL-2.0-only
use strict;
use warnings;
use lib '@prefix@/lib/perl5';

View File

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

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
#
#--------------------------------------------------------------
@@ -955,6 +956,7 @@ proc WriteOptionsToFile {} {
#***********************************************************************
proc LoadOptions {} {
global Option ConfigFile
global MondayFirst
set problem [catch {set f [open "$ConfigFile" "r"]}]
if {$problem} {
return
@@ -974,6 +976,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)
}
@@ -3819,13 +3824,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 +3924,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

@@ -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;
@@ -714,7 +715,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 +734,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 +765,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 +807,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 +823,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 +852,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 +881,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 +896,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 +932,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 +979,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 +992,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 +1007,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 +1065,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 +1082,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 +1091,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 +1118,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 +1154,7 @@ static int WriteCalendarRow(void)
/* Write the body lines */
done = 0;
while (!done) {
done = WriteOneCalLine(OrigJul, wd);
done = WriteOneCalLine(OrigDse, wd);
LinesWritten++;
}
@@ -1336,7 +1337,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 +1346,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 +1703,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 +1746,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;
@@ -1843,14 +1844,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 +1863,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 +1908,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 +1938,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 +1995,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 +2011,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 +2056,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 +2160,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 +2386,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 +2407,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;
@@ -124,14 +125,14 @@ int DoRem(ParsePtr p)
DBufFree(&buf);
}
trig.typ = tok.val;
jul = LastTriggerDate;
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 +148,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 +175,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 +187,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)) ) {
FreeTrig(&trig);
return r;
}
@@ -234,6 +235,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 +293,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 +304,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;
@@ -435,6 +437,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 +559,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 +580,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 +739,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 +752,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 +831,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 +855,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 +868,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 +893,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 r, y, m, d;
char PrioExpr[VAR_NAME_LEN+25];
@@ -943,7 +950,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
&& !DidMsgReminder && !NextMode && !MsgCommand) {
DidMsgReminder = 1;
if (!DoSubstFromString(DBufValue(&Banner), &buf,
JulianToday, NO_TIME) &&
DSEToday, NO_TIME) &&
DBufLen(&buf)) {
printf("%s\n", DBufValue(&buf));
}
@@ -953,13 +960,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 +1065,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);
@@ -1093,7 +1100,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++;
@@ -1140,20 +1147,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 +1174,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 +1185,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 +1219,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 +1231,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 +1240,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 +1268,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 +1293,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 +1403,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 +1415,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 +1424,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 +1462,7 @@ 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;
}
}
}

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;
@@ -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;
@@ -370,10 +371,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_A_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d %s, %d", get_day_name(jul%7), d,
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(jul%7), d,
snprintf(s, sizeof(s), "%s %s, %d %s, %d", DynamicOn, get_day_name(dse%7), d,
get_month_name(m), y);
}
#endif
@@ -394,9 +395,9 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_C_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s", get_day_name(jul%7));
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
} else {
snprintf(s, sizeof(s), "%s %s", DynamicOn, get_day_name(jul%7));
snprintf(s, sizeof(s), "%s %s", DynamicOn, get_day_name(dse%7));
}
#endif
SHIP_OUT(s);
@@ -444,9 +445,9 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
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));
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(jul%7), d, get_month_name(m));
snprintf(s, sizeof(s), "%s %s, %d %s", DynamicOn, get_day_name(dse%7), d, get_month_name(m));
}
#endif
SHIP_OUT(s);
@@ -483,10 +484,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_J_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %s %d%s, %d", get_day_name(jul%7),
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(jul%7),
snprintf(s, sizeof(s), "%s %s, %s %d%s, %d", DynamicOn, get_day_name(dse%7),
get_month_name(m), d, plu, y);
}
#endif
@@ -498,10 +499,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_K_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %s %d%s", get_day_name(jul%7),
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(jul%7),
snprintf(s, sizeof(s), "%s %s, %s %d%s", DynamicOn, get_day_name(dse%7),
get_month_name(m), d, plu);
}
#endif
@@ -543,7 +544,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_O_OVER
L_O_OVER
#else
if (RealToday == JulianToday) snprintf(s, sizeof(s), " (%s)", DynamicToday);
if (RealToday == DSEToday) snprintf(s, sizeof(s), " (%s)", DynamicToday);
else *s = 0;
#endif
SHIP_OUT(s);
@@ -599,10 +600,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_U_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d%s %s, %d", get_day_name(jul%7), d,
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(jul%7), d,
snprintf(s, sizeof(s), "%s %s, %d%s %s, %d", DynamicOn, get_day_name(dse%7), d,
plu, get_month_name(m), y);
}
#endif
@@ -614,10 +615,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
L_V_OVER
#else
if (altmode == '*' || !strcmp(DynamicOn, "")) {
snprintf(s, sizeof(s), "%s, %d%s %s", get_day_name(jul%7), d, plu,
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(jul%7), d, plu,
snprintf(s, sizeof(s), "%s %s, %d%s %s", DynamicOn, get_day_name(dse%7), d, plu,
get_month_name(m));
}
#endif
@@ -628,7 +629,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
#ifdef L_W_OVER
L_W_OVER
#else
snprintf(s, sizeof(s), "%s", get_day_name(jul%7));
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
#endif
SHIP_OUT(s);
break;
@@ -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 */
/* */
/***************************************************************/
@@ -662,13 +663,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 +1195,9 @@ static int LogNot(void)
/***************************************************************/
/* */
/* FindFunc */
/* FindOperator */
/* */
/* Find a function. */
/* Find an operator. */
/* */
/***************************************************************/
Operator *FindOperator(char const *name, Operator where[], int num)
@@ -1205,7 +1206,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 +1214,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 +1241,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 +1291,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 +1368,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 +1402,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;

View File

@@ -6,7 +6,8 @@
/* expressions. */
/* */
/* 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 */
/* */
/***************************************************************/
@@ -59,6 +60,9 @@
#define Nargs (info->nargs)
#define RetVal (info->retval)
static int
solstice_equinox_for_year(int y, int which);
/* Function prototypes */
static int FADawn (func_info *);
static int FADusk (func_info *);
@@ -132,6 +136,7 @@ static int FRows (func_info *);
static int FSgn (func_info *);
static int FShell (func_info *);
static int FSlide (func_info *);
static int FSoleq (func_info *);
static int FStdout (func_info *);
static int FStrlen (func_info *);
static int FSubstr (func_info *);
@@ -174,7 +179,7 @@ static int FShellescape (func_info *);
static int CleanUpAfterFunc (func_info *);
static int CheckArgs (BuiltinFunc *f, int nargs);
static int SunStuff (int rise, double cosz, int jul);
static int SunStuff (int rise, double cosz, int dse);
static int tz_set_tz (char const *tz);
/* "Overload" the struct Operator definition */
@@ -182,10 +187,10 @@ static int tz_set_tz (char const *tz);
/* Caches for extracting months, days, years from dates - may
improve performance slightly. */
static int CacheJul = -1;
static int CacheDse = -1;
static int CacheYear, CacheMon, CacheDay;
static int CacheHebJul = -1;
static int CacheHebDse = -1;
static int CacheHebYear, CacheHebMon, CacheHebDay;
/* We need access to the value stack */
@@ -296,6 +301,7 @@ BuiltinFunc Func[] = {
{ "shell", 1, 2, 0, FShell },
{ "shellescape", 1, 1, 1, FShellescape },
{ "slide", 2, NO_MAX, 0, FSlide },
{ "soleq", 1, 2, 0, FSoleq },
{ "stdout", 0, 0, 1, FStdout },
{ "strlen", 1, 1, 1, FStrlen },
{ "substr", 2, 3, 1, FSubstr },
@@ -493,7 +499,7 @@ static int FDate(func_info *info)
/* Any arg can be a date (in which case we use the corresponding
component) or an integer */
if (HASDATE(ARG(0))) {
FromJulian(DATEPART(ARG(0)), &ytemp, &mtemp, &dtemp);
FromDSE(DATEPART(ARG(0)), &ytemp, &mtemp, &dtemp);
y = ytemp;
} else {
ASSERT_TYPE(0, INT_TYPE);
@@ -501,7 +507,7 @@ static int FDate(func_info *info)
}
if (HASDATE(ARG(1))) {
FromJulian(DATEPART(ARG(1)), &ytemp, &mtemp, &dtemp);
FromDSE(DATEPART(ARG(1)), &ytemp, &mtemp, &dtemp);
m = mtemp;
} else {
ASSERT_TYPE(1, INT_TYPE);
@@ -509,7 +515,7 @@ static int FDate(func_info *info)
}
if (HASDATE(ARG(2))) {
FromJulian(DATEPART(ARG(2)), &ytemp, &mtemp, &dtemp);
FromDSE(DATEPART(ARG(2)), &ytemp, &mtemp, &dtemp);
d = dtemp;
} else {
ASSERT_TYPE(2, INT_TYPE);
@@ -520,7 +526,7 @@ static int FDate(func_info *info)
return E_BAD_DATE;
}
RetVal.type = DATE_TYPE;
RETVAL = Julian(y, m, d);
RETVAL = DSE(y, m, d);
return OK;
}
@@ -563,7 +569,7 @@ static int FDateTime(func_info *info)
d = ARGV(2);
if (!DateOK(y, m, d)) return E_BAD_DATE;
RETVAL = Julian(y, m, d) * MINUTES_PER_DAY + ARGV(3);
RETVAL = DSE(y, m, d) * MINUTES_PER_DAY + ARGV(3);
return OK;
case 5:
if (ARG(0).type != INT_TYPE ||
@@ -579,7 +585,7 @@ static int FDateTime(func_info *info)
if (ARGV(3) < 0 || ARGV(4) < 0) return E_2LOW;
if (ARGV(3) > 23 || ARGV(4) > 59) return E_2HIGH;
RETVAL = Julian(y, m, d) * MINUTES_PER_DAY + ARGV(3) * 60 + ARGV(4);
RETVAL = DSE(y, m, d) * MINUTES_PER_DAY + ARGV(3) * 60 + ARGV(4);
return OK;
default:
@@ -742,11 +748,11 @@ static int FDay(func_info *info)
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
v = DATEPART(ARG(0));
if (v == CacheJul)
if (v == CacheDse)
d = CacheDay;
else {
FromJulian(v, &y, &m, &d);
CacheJul = v;
FromDSE(v, &y, &m, &d);
CacheDse = v;
CacheYear = y;
CacheMon = m;
CacheDay = d;
@@ -762,11 +768,11 @@ static int FMonnum(func_info *info)
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
v = DATEPART(ARG(0));
if (v == CacheJul)
if (v == CacheDse)
m = CacheMon;
else {
FromJulian(v, &y, &m, &d);
CacheJul = v;
FromDSE(v, &y, &m, &d);
CacheDse = v;
CacheYear = y;
CacheMon = m;
CacheDay = d;
@@ -782,11 +788,11 @@ static int FYear(func_info *info)
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
v = DATEPART(ARG(0));
if (v == CacheJul)
if (v == CacheDse)
y = CacheYear;
else {
FromJulian(v, &y, &m, &d);
CacheJul = v;
FromDSE(v, &y, &m, &d);
CacheDse = v;
CacheYear = y;
CacheMon = m;
CacheDay = d;
@@ -838,11 +844,11 @@ static int FMon(func_info *info)
if (m > 11) return E_2HIGH;
} else {
v = DATEPART(ARG(0));
if (v == CacheJul)
if (v == CacheDse)
m = CacheMon;
else {
FromJulian(v, &y, &m, &d);
CacheJul = v;
FromDSE(v, &y, &m, &d);
CacheDse = v;
CacheYear = y;
CacheMon = m;
CacheDay = d;
@@ -1027,7 +1033,7 @@ static int FAmpm(func_info *info)
return E_BAD_TYPE;
}
if (HASDATE(ARG(0))) {
FromJulian(DATEPART(ARG(0)), &yr, &mo, &da);
FromDSE(DATEPART(ARG(0)), &yr, &mo, &da);
}
if (Nargs >= 2) {
ASSERT_TYPE(1, STR_TYPE);
@@ -1382,7 +1388,7 @@ static int FStdout(func_info *info)
static int FToday(func_info *info)
{
RetVal.type = DATE_TYPE;
RETVAL = JulianToday;
RETVAL = DSEToday;
return OK;
}
@@ -1410,7 +1416,7 @@ static int FRealnow(func_info *info)
static int FCurrent(func_info *info)
{
RetVal.type = DATETIME_TYPE;
RETVAL = JulianToday * MINUTES_PER_DAY + (SystemTime(0) / 60);
RETVAL = DSEToday * MINUTES_PER_DAY + (SystemTime(0) / 60);
return OK;
}
@@ -1689,7 +1695,7 @@ static int FIsleap(func_info *info)
/* If it's a date, extract the year */
if (HASDATE(ARG(0)))
FromJulian(DATEPART(ARG(0)), &y, &m, &d);
FromDSE(DATEPART(ARG(0)), &y, &m, &d);
else
y = ARGV(0);
@@ -1749,7 +1755,7 @@ static int FTrigger(func_info *info)
}
}
FromJulian(date, &y, &m, &d);
FromDSE(date, &y, &m, &d);
if (tim != NO_TIME) {
sprintf(buf, "%d %s %d AT %02d:%02d", d, EnglishMonthName[m], y,
tim/60, tim%60);
@@ -2080,21 +2086,21 @@ static int FArgs(func_info *info)
/***************************************************************/
static int FDosubst(func_info *info)
{
int jul, tim, r;
int dse, tim, r;
DynamicBuffer buf;
DBufInit(&buf);
jul = NO_DATE;
dse = NO_DATE;
tim = NO_TIME;
ASSERT_TYPE(0, STR_TYPE);
if (Nargs >= 2) {
if (ARG(1).type == DATETIME_TYPE) {
jul = DATEPART(ARG(1));
dse = DATEPART(ARG(1));
tim = TIMEPART(ARG(1));
} else {
ASSERT_TYPE(1, DATE_TYPE);
jul = ARGV(1);
dse = ARGV(1);
}
if (Nargs >= 3) {
if (ARG(1).type == DATETIME_TYPE) {
@@ -2105,7 +2111,7 @@ static int FDosubst(func_info *info)
}
}
if ((r=DoSubstFromString(ARGSTR(0), &buf, jul, tim))) return r;
if ((r=DoSubstFromString(ARGSTR(0), &buf, dse, tim))) return r;
r = RetStrVal(DBufValue(&buf), info);
DBufFree(&buf);
return r;
@@ -2133,7 +2139,7 @@ static int FHebdate(func_info *info)
mon = HebNameToNum(ARGSTR(1));
if (mon < 0) return E_BAD_HEBDATE;
if (Nargs == 2) {
r = GetNextHebrewDate(JulianToday, mon, day, 0, 0, &ans);
r = GetNextHebrewDate(DSEToday, mon, day, 0, 0, &ans);
if (r) return r;
RetVal.type = DATE_TYPE;
RETVAL = ans;
@@ -2161,7 +2167,7 @@ static int FHebdate(func_info *info)
year = ARGV(2);
r = GetValidHebDate(year, mon, day, 0, &mout, &dout, jahr);
if (r) return r;
r = HebToJul(year, mout, dout);
r = HebToDSE(year, mout, dout);
if (r<0) return E_DATE_OVER;
RETVAL = r;
RetVal.type = DATE_TYPE;
@@ -2181,11 +2187,11 @@ static int FHebday(func_info *info)
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
v = DATEPART(ARG(0));
if (v == CacheHebJul)
if (v == CacheHebDse)
d = CacheHebDay;
else {
JulToHeb(v, &y, &m, &d);
CacheHebJul = v;
DSEToHeb(v, &y, &m, &d);
CacheHebDse = v;
CacheHebYear = y;
CacheHebMon = m;
CacheHebDay = d;
@@ -2202,12 +2208,12 @@ static int FHebmon(func_info *info)
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
v = DATEPART(ARG(0));
if (v == CacheHebJul) {
if (v == CacheHebDse) {
m = CacheHebMon;
y = CacheHebYear;
} else {
JulToHeb(v, &y, &m, &d);
CacheHebJul = v;
DSEToHeb(v, &y, &m, &d);
CacheHebDse = v;
CacheHebYear = y;
CacheHebMon = m;
CacheHebDay = d;
@@ -2222,11 +2228,11 @@ static int FHebyear(func_info *info)
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
v = DATEPART(ARG(0));
if (v == CacheHebJul)
if (v == CacheHebDse)
y = CacheHebYear;
else {
JulToHeb(v, &y, &m, &d);
CacheHebJul = v;
DSEToHeb(v, &y, &m, &d);
CacheHebDse = v;
CacheHebYear = y;
CacheHebMon = m;
CacheHebDay = d;
@@ -2258,7 +2264,7 @@ static int FEasterdate(func_info *info)
if (y < BASE) return E_2LOW;
else if (y > BASE+YR_RANGE) return E_2HIGH;
} else if (HASDATE(ARG(0))) {
FromJulian(DATEPART(ARG(0)), &y, &m, &d); /* We just want the year */
FromDSE(DATEPART(ARG(0)), &y, &m, &d); /* We just want the year */
} else return E_BAD_TYPE;
do {
@@ -2281,7 +2287,7 @@ static int FEasterdate(func_info *info)
}
RetVal.type = DATE_TYPE;
RETVAL = Julian(y, m, d);
RETVAL = DSE(y, m, d);
y++; } while (HASDATE(ARG(0)) && RETVAL < DATEPART(ARG(0)));
return OK;
@@ -2307,15 +2313,15 @@ static int FMinsfromutc(func_info *info)
static int FTimeStuff(int wantmins, func_info *info)
{
int jul, tim;
int dse, tim;
int mins, dst;
jul = JulianToday;
dse = DSEToday;
tim = 0;
if (Nargs >= 1) {
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
jul = DATEPART(ARG(0));
dse = DATEPART(ARG(0));
if (HASTIME(ARG(0))) {
tim = TIMEPART(ARG(0));
}
@@ -2326,7 +2332,7 @@ static int FTimeStuff(int wantmins, func_info *info)
}
}
if (CalcMinsFromUTC(jul, tim, &mins, &dst)) return E_MKTIME_PROBLEM;
if (CalcMinsFromUTC(dse, tim, &mins, &dst)) return E_MKTIME_PROBLEM;
RetVal.type = INT_TYPE;
if (wantmins) RETVAL = mins; else RETVAL = dst;
@@ -2335,24 +2341,24 @@ static int FTimeStuff(int wantmins, func_info *info)
static int FTimezone(func_info *info)
{
int yr, mon, day, hr, min, jul, now;
int yr, mon, day, hr, min, dse, now;
struct tm local, *withzone;
time_t t;
char buf[64];
if (Nargs == 0) {
jul = JulianToday;
dse = DSEToday;
now = (SystemTime(0) / 60);
} else {
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
jul = DATEPART(ARG(0));
dse = DATEPART(ARG(0));
if (HASTIME(ARG(0))) {
now = TIMEPART(ARG(0));
} else {
now = 0;
}
}
FromJulian(jul, &yr, &mon, &day);
FromDSE(dse, &yr, &mon, &day);
hr = now / 60;
min = now % 60;
@@ -2374,13 +2380,13 @@ static int FTimezone(func_info *info)
static int FLocalToUTC(func_info *info)
{
int yr, mon, day, hr, min, jul;
int yr, mon, day, hr, min, dse;
time_t loc_t;
struct tm local, *utc;
ASSERT_TYPE(0, DATETIME_TYPE);
FromJulian(DATEPART(ARG(0)), &yr, &mon, &day);
FromDSE(DATEPART(ARG(0)), &yr, &mon, &day);
hr = TIMEPART(ARG(0))/60;
min = TIMEPART(ARG(0))%60;
@@ -2398,23 +2404,22 @@ static int FLocalToUTC(func_info *info)
}
utc = gmtime(&loc_t);
jul = Julian(utc->tm_year+1900, utc->tm_mon, utc->tm_mday);
dse = DSE(utc->tm_year+1900, utc->tm_mon, utc->tm_mday);
RetVal.type = DATETIME_TYPE;
RETVAL = MINUTES_PER_DAY * jul + utc->tm_hour*60 + utc->tm_min;
RETVAL = MINUTES_PER_DAY * dse + utc->tm_hour*60 + utc->tm_min;
return OK;
}
static int FUTCToLocal(func_info *info)
static int UTCToLocalHelper(int datetime, int *ret)
{
int yr, mon, day, hr, min, jul;
int yr, mon, day, hr, min, dse;
time_t utc_t;
struct tm *local, utc;
char const *old_tz;
ASSERT_TYPE(0, DATETIME_TYPE);
FromJulian(DATEPART(ARG(0)), &yr, &mon, &day);
hr = TIMEPART(ARG(0))/60;
min = TIMEPART(ARG(0))%60;
FromDSE(datetime / MINUTES_PER_DAY, &yr, &mon, &day);
hr = (datetime % MINUTES_PER_DAY) / 60;
min = (datetime % MINUTES_PER_DAY) % 60;
old_tz = getenv("TZ");
@@ -2436,9 +2441,25 @@ static int FUTCToLocal(func_info *info)
}
local = localtime(&utc_t);
jul = Julian(local->tm_year+1900, local->tm_mon, local->tm_mday);
dse = DSE(local->tm_year+1900, local->tm_mon, local->tm_mday);
*ret = MINUTES_PER_DAY * dse + local->tm_hour*60 + local->tm_min;
return OK;
}
static int FUTCToLocal(func_info *info)
{
int ret;
int r;
ASSERT_TYPE(0, DATETIME_TYPE);
r = UTCToLocalHelper(ARGV(0), &ret);
if (r != 0) {
return r;
}
RetVal.type = DATETIME_TYPE;
RETVAL = MINUTES_PER_DAY * jul + local->tm_hour*60 + local->tm_min;
RETVAL = ret;
return OK;
}
@@ -2460,7 +2481,7 @@ static int FUTCToLocal(func_info *info)
#define DEGRAD (PI/180.0)
#define RADDEG (180.0/PI)
static int SunStuff(int rise, double cosz, int jul)
static int SunStuff(int rise, double cosz, int dse)
{
int mins, hours;
int year, mon, day;
@@ -2470,7 +2491,7 @@ static int SunStuff(int rise, double cosz, int jul)
/* Get offset from UTC */
if (CalculateUTC) {
if (CalcMinsFromUTC(jul, 12*60, &mins, NULL)) {
if (CalcMinsFromUTC(dse, 12*60, &mins, NULL)) {
Eprint(ErrMsg[E_MKTIME_PROBLEM]);
return NO_TIME;
}
@@ -2480,10 +2501,10 @@ static int SunStuff(int rise, double cosz, int jul)
longdeg = -Longitude;
latitude = DEGRAD * Latitude;
FromJulian(jul, &year, &mon, &day);
FromDSE(dse, &year, &mon, &day);
/* Following formula on page B6 exactly... */
t = (double) jul;
t = (double) dse;
if (rise) {
t += (6.0 + longdeg/15.0) / 24.0;
} else {
@@ -2570,7 +2591,7 @@ static int SunStuff(int rise, double cosz, int jul)
/***************************************************************/
static int FSun(int rise, func_info *info)
{
int jul = JulianToday;
int dse = DSEToday;
/* Assignment below is not necessary, but it silences
a GCC warning about a possibly-uninitialized variable */
double cosz = 0.0;
@@ -2591,10 +2612,10 @@ static int FSun(int rise, func_info *info)
}
if (Nargs >= 1) {
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
jul = DATEPART(ARG(0));
dse = DATEPART(ARG(0));
}
r = SunStuff(rise % 2, cosz, jul);
r = SunStuff(rise % 2, cosz, dse);
if (r == NO_TIME) {
RETVAL = 0;
RetVal.type = INT_TYPE;
@@ -2670,7 +2691,7 @@ static int FFiledate(func_info *info)
if (t1->tm_year + 1900 < BASE)
RETVAL=0;
else
RETVAL=Julian(t1->tm_year+1900, t1->tm_mon, t1->tm_mday);
RETVAL=DSE(t1->tm_year+1900, t1->tm_mon, t1->tm_mday);
return OK;
}
@@ -2701,7 +2722,7 @@ static int FFiledatetime(func_info *info)
if (t1->tm_year + 1900 < BASE)
RETVAL=0;
else
RETVAL = MINUTES_PER_DAY * Julian(t1->tm_year+1900, t1->tm_mon, t1->tm_mday) + t1->tm_hour * 60 + t1->tm_min;
RETVAL = MINUTES_PER_DAY * DSE(t1->tm_year+1900, t1->tm_mon, t1->tm_mday) + t1->tm_hour * 60 + t1->tm_min;
return OK;
}
@@ -2859,7 +2880,7 @@ static int FMoonphase(func_info *info)
switch(Nargs) {
case 0:
date = JulianToday;
date = DSEToday;
time = 0;
break;
case 1:
@@ -2914,7 +2935,7 @@ static int MoonStuff(int type_wanted, func_info *info)
int startdate, starttim;
int d, t;
startdate = JulianToday;
startdate = DSEToday;
starttim = 0;
ASSERT_TYPE(0, INT_TYPE);
@@ -3090,14 +3111,14 @@ static int tz_convert(int year, int month, int day,
static int FTzconvert(func_info *info)
{
int year, month, day, hour, minute, r;
int jul, tim;
int dse, tim;
struct tm tm;
if (ARG(0).type != DATETIME_TYPE ||
ARG(1).type != STR_TYPE) return E_BAD_TYPE;
if (Nargs == 3 && ARG(2).type != STR_TYPE) return E_BAD_TYPE;
FromJulian(DATEPART(ARG(0)), &year, &month, &day);
FromDSE(DATEPART(ARG(0)), &year, &month, &day);
r = TIMEPART(ARG(0));
hour = r / 60;
@@ -3113,10 +3134,10 @@ static int FTzconvert(func_info *info)
if (r == -1) return E_CANT_CONVERT_TZ;
jul = Julian(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday);
dse = DSE(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday);
tim = tm.tm_hour * 60 + tm.tm_min;
RetVal.type = DATETIME_TYPE;
RETVAL = jul * MINUTES_PER_DAY + tim;
RETVAL = dse * MINUTES_PER_DAY + tim;
return OK;
}
@@ -3204,7 +3225,7 @@ FNonomitted(func_info *info)
static int
FWeekno(func_info *info)
{
int jul = JulianToday;
int dse = DSEToday;
int wkstart = 0; /* Week start on Monday */
int daystart = 29; /* First week starts on wkstart on or after Dec. 29 */
int monstart;
@@ -3214,7 +3235,7 @@ FWeekno(func_info *info)
if (Nargs >= 1) {
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
jul = DATEPART(ARG(0));
dse = DATEPART(ARG(0));
}
if (Nargs >= 2) {
ASSERT_TYPE(1, INT_TYPE);
@@ -3241,31 +3262,31 @@ FWeekno(func_info *info)
monstart = 11;
}
FromJulian(jul, &y, &m, &d);
FromDSE(dse, &y, &m, &d);
/* Try this year */
candidate = Julian(y, monstart, daystart);
candidate = DSE(y, monstart, daystart);
while((candidate % 7) != wkstart) candidate++;
if (candidate <= jul) {
RETVAL = ((jul - candidate) / 7) + 1;
if (candidate <= dse) {
RETVAL = ((dse - candidate) / 7) + 1;
return OK;
}
if (y-1 < BASE) return E_DATE_OVER;
/* Must be last year */
candidate = Julian(y-1, monstart, daystart);
candidate = DSE(y-1, monstart, daystart);
while((candidate % 7) != wkstart) candidate++;
if (candidate <= jul) {
RETVAL = ((jul - candidate) / 7) + 1;
if (candidate <= dse) {
RETVAL = ((dse - candidate) / 7) + 1;
return OK;
}
if (y-2 < BASE) return E_DATE_OVER;
/* Holy cow! */
candidate = Julian(y-2, monstart, daystart);
candidate = DSE(y-2, monstart, daystart);
while((candidate % 7) != wkstart) candidate++;
RETVAL = ((jul - candidate) / 7) + 1;
RETVAL = ((dse - candidate) / 7) + 1;
return OK;
}
@@ -3275,7 +3296,7 @@ FEvalTrig(func_info *info)
Parser p;
Trigger trig;
TimeTrig tim;
int jul, scanfrom;
int dse, scanfrom;
int r;
ASSERT_TYPE(0, STR_TYPE);
@@ -3299,30 +3320,30 @@ FEvalTrig(func_info *info)
return E_PARSE_ERR;
}
if (scanfrom == NO_DATE) {
jul = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
} else {
/* Hokey... */
if (trig.scanfrom != JulianToday) {
if (trig.scanfrom != DSEToday) {
Wprint("Warning: SCANFROM is ignored in two-argument form of evaltrig()");
}
jul = ComputeTrigger(scanfrom, &trig, &tim, &r, 0);
dse = ComputeTrigger(scanfrom, &trig, &tim, &r, 0);
}
if (r == E_CANT_TRIG && trig.maybe_uncomputable) {
r = 0;
jul = -1;
dse = -1;
}
FreeTrig(&trig);
DestroyParser(&p);
if (r) return r;
if (jul < 0) {
if (dse < 0) {
RetVal.type = INT_TYPE;
RETVAL = jul;
RETVAL = dse;
} else if (tim.ttime == NO_TIME) {
RetVal.type = DATE_TYPE;
RETVAL = jul;
RETVAL = dse;
} else {
RetVal.type = DATETIME_TYPE;
RETVAL = (MINUTES_PER_DAY * jul) + tim.ttime;
RETVAL = (MINUTES_PER_DAY * dse) + tim.ttime;
}
return OK;
}
@@ -3334,7 +3355,7 @@ FTrig(func_info *info)
Parser p;
Trigger trig;
TimeTrig tim;
int jul;
int dse;
int r;
int i;
@@ -3363,16 +3384,16 @@ FTrig(func_info *info)
FreeTrig(&trig);
return E_PARSE_ERR;
}
jul = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
if (r == E_CANT_TRIG) {
DestroyParser(&p);
FreeTrig(&trig);
continue;
}
if (ShouldTriggerReminder(&trig, &tim, jul, &r)) {
LastTrig = jul;
RETVAL = jul;
if (ShouldTriggerReminder(&trig, &tim, dse, &r)) {
LastTrig = dse;
RETVAL = dse;
DestroyParser(&p);
FreeTrig(&trig);
return OK;
@@ -3456,3 +3477,174 @@ static int FColumns(func_info *info)
return E_BAD_TYPE;
#endif
}
/* The following sets of functions are for computing solstices and equinoxes.
They are based on the algorithms described in "Astronomical Algorithms",
second edition, by Jean Meeus. ISBN 0-943396-61-1 */
/* The following are taken from Astronomical Algorithms, 2nd ed., page 178 */
static double
mean_march_equinox(double y)
{
return 2451623.80984 + 365242.37404*y + 0.05169*y*y - 0.00411*y*y*y - 0.00057*y*y*y*y;
}
static double
mean_june_solstice(double y)
{
return 2451716.56767 + 365241.62603*y + 0.00325*y*y + 0.00888*y*y*y - 0.00030*y*y*y*y;
}
static double
mean_september_equinox(double y)
{
return 2451810.21715 + 365242.01767*y - 0.11575*y*y + 0.00337*y*y*y + 0.00078*y*y*y*y;
}
static double
mean_december_solstice(double y)
{
return 2451900.05952 + 365242.74049*y - 0.06223*y*y - 0.00823*y*y*y + 0.00032*y*y*y*y;
}
/* Cosine of an angle specified in degrees */
static double
cosd(double degrees)
{
return cos((degrees / 180.0) * 3.14159265358979);
}
/* Astronomical Algorithms by Meeus, p. 179
These weird periodic components refine the mean solstice/equinox dates
calculated with the simpler degree-4 polynomials above */
static double
meeus_periodic_components(double t)
{
return
485 * cosd(324.96 + 1934.136 * t) +
203 * cosd(337.23 + 32964.467 * t) +
199 * cosd(342.08 + 20.186 * t) +
182 * cosd( 27.85 + 445267.112 * t) +
156 * cosd( 73.14 + 45036.886 * t) +
136 * cosd(171.52 + 22518.443 * t) +
77 * cosd(222.54 + 65928.934 * t) +
74 * cosd(296.72 + 3034.906 * t) +
70 * cosd(243.58 + 9037.513 * t) +
58 * cosd(119.81 + 33718.147 * t) +
52 * cosd(297.17 + 150.678 * t) +
50 * cosd( 21.02 + 2281.226 * t) +
45 * cosd(247.54 + 29929.562 * t) +
44 * cosd(325.15 + 31555.956 * t) +
29 * cosd( 60.93 + 4443.417 * t) +
18 * cosd(155.12 + 67555.328 * t) +
17 * cosd(288.79 + 4562.452 * t) +
16 * cosd(198.04 + 62894.029 * t) +
14 * cosd(199.76 + 31436.921 * t) +
12 * cosd( 95.39 + 14577.848 * t) +
12 * cosd(287.11 + 31931.756 * t) +
12 * cosd(320.81 + 34777.259 * t) +
9 * cosd(227.73 + 1222.114 * t) +
8 * cosd( 15.45 + 16859.074 * t);
}
static double
julian_solstice_equinox(int y, int which)
{
double jde0;
double dy;
double t, w, dlambda, s;
dy = ((double) y - 2000.0) / 1000.0;
switch(which) {
case 0:
jde0 = mean_march_equinox(dy);
break;
case 1:
jde0 = mean_june_solstice(dy);
break;
case 2:
jde0 = mean_september_equinox(dy);
break;
case 3:
jde0 = mean_december_solstice(dy);
break;
default:
return -1.0;
}
t = (jde0 - 2451545.0) / 36525.0;
w = 35999.373 * t - 2.47;
dlambda = 1 + 0.0334 * cosd(w) + 0.0007 * cosd(2*w);
s = meeus_periodic_components(t);
return jde0 + (0.00001 * s) / dlambda;
}
/* Returns a value suitable for a datetime object. Assumes that BASE = 1990*/
static int
solstice_equinox_for_year(int y, int which)
{
double j = julian_solstice_equinox(y, which);
if (j < 0) {
return -1;
}
j -= 2447892.50000; /* This is the Julian date of midnight, 1 Jan 1990 UTC */
int dse = (int) j;
int min = floor((j - (double) dse) * MINUTES_PER_DAY);
int ret;
/* Convert from UTC to local time */
if (UTCToLocalHelper(dse * MINUTES_PER_DAY + min, &ret) != OK) {
return -1;
}
return ret;
}
/* Solstice / equinox function */
static int
FSoleq(func_info *info)
{
int y, dse, which, ret;
RetVal.type = ERR_TYPE;
dse = NO_DATE;
ASSERT_TYPE(0, INT_TYPE);
which = ARGV(0);
if (which < 0) {
return E_2LOW;
} else if (which > 3) {
return E_2HIGH;
}
if (Nargs > 1) {
if (ARG(1).type == INT_TYPE) {
y = ARGV(1);
if (y < BASE) {
return E_2LOW;
} else if (y > BASE+YR_RANGE) {
return E_2HIGH;
}
} else if (HASDATE(ARG(1))) {
dse = DATEPART(ARG(1));
FromDSE(dse, &y, NULL, NULL); /* We just want the year */
} else {
return E_BAD_TYPE;
}
} else {
/* If no second argument, default to today */
dse = DSEToday;
FromDSE(dse, &y, NULL, NULL); /* We just want the year */
}
ret = solstice_equinox_for_year(y, which);
if (dse != NO_DATE && (ret / MINUTES_PER_DAY) < dse) {
ret = solstice_equinox_for_year(y+1, which);
}
RetVal.type = DATETIME_TYPE;
RETVAL = ret;
return OK;
}

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 */
/* */
/***************************************************************/
@@ -40,7 +41,7 @@ EXTERN FILE *ErrFp;
#define DestroyValue(x) (void) (((x).type == STR_TYPE && (x).v.str) ? (free((x).v.str),(x).type = ERR_TYPE) : 0)
EXTERN int JulianToday;
EXTERN int DSEToday;
EXTERN int RealToday;
EXTERN int CurDay;
EXTERN int CurMon;

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();
@@ -638,30 +639,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 +682,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 +701,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 +730,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

@@ -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,7 +380,7 @@ void FromJulian(int jul, int *y, int *m, int *d)
*m = try_mon;
}
if (d) {
*d = jul + 1;
*d = dse + 1;
}
return;
}
@@ -747,7 +753,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 +770,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 +863,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 +871,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 +881,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 +1145,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 +1175,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;

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,8 +401,8 @@ 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,
double Day, N, M, Ec, Lambdasun, ml, MM, Ev, Ae, A3, MmP,
mEc, A4, lP, V, lPP,
MoonAge, MoonPhase,
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,19 +459,6 @@ 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 */
@@ -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 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,13 @@ 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 ParseChar (ParsePtr p, int *err, int peek);
int ParseToken (ParsePtr p, DynamicBuffer *dbuf);
int ParseIdentifier (ParsePtr p, DynamicBuffer *dbuf);
@@ -86,7 +87,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);
@@ -120,24 +121,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 +162,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);

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);
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");
}
}

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;
@@ -168,7 +169,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 +179,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;
}
@@ -355,7 +357,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 +366,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),

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. */
/* */

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 */
/* */
/***************************************************************/

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`
@@ -398,6 +399,25 @@ 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
# 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
@@ -411,3 +431,4 @@ else
echo "reference file test.cmp."
exit 1
fi

View File

@@ -1060,7 +1060,7 @@ set a057 value("a05"+"6")
"a05" + "6" => "a056"
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
set a058 version()
version() => "04.02.00"
version() => "04.02.02"
set a059 wkday(today())
today() => 1991-02-16
wkday(1991-02-16) => "Saturday"
@@ -2627,7 +2627,7 @@ a086 4
a109 2012-01-01
a128 2018-02-03@16:45
a039 "February"
a058 "04.02.00"
a058 "04.02.02"
a077 "1992 92\n"
a096 -4
a119 -1
@@ -7498,7 +7498,7 @@ No reminders.
<< /PageSize [612 792] >> setpagedevice
% 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
@@ -8602,7 +8602,7 @@ showpage
<< /PageSize [612 792] >> setpagedevice
% 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
@@ -10334,20 +10334,20 @@ STDOUT is a: PIPE
set a localtoutc('2022-01-01@12:00')
localtoutc(2022-01-01@12:00) => 2022-01-01@17:00
set a localtoutc('2022-03-13@02:59')
localtoutc(2022-03-13@02:59) => 2022-03-13@07:59
set a localtoutc('2022-03-13@03:00')
localtoutc(2022-03-13@03:00) => 2022-03-13@07:00
set a localtoutc('2022-03-13@03:01')
localtoutc(2022-03-13@03:01) => 2022-03-13@07:01
set a localtoutc('2022-03-13@03:59')
localtoutc(2022-03-13@03:59) => 2022-03-13@07:59
set a localtoutc('2022-03-13@04:00')
localtoutc(2022-03-13@04:00) => 2022-03-13@08:00
set a localtoutc('2022-03-13@04:01')
localtoutc(2022-03-13@04:01) => 2022-03-13@08:01
set a localtoutc('2022-06-01@12:00')
localtoutc(2022-06-01@12:00) => 2022-06-01@16:00
set a localtoutc('2022-11-06@01:59')
localtoutc(2022-11-06@01:59) => 2022-11-06@05:59
set a localtoutc('2022-11-06@02:00')
localtoutc(2022-11-06@02:00) => 2022-11-06@07:00
set a localtoutc('2022-11-06@02:01')
localtoutc(2022-11-06@02:01) => 2022-11-06@07:01
set a localtoutc('2022-11-06@02:59')
localtoutc(2022-11-06@02:59) => 2022-11-06@07:59
set a localtoutc('2022-11-06@03:00')
localtoutc(2022-11-06@03:00) => 2022-11-06@08:00
set a localtoutc('2022-11-06@03:01')
localtoutc(2022-11-06@03:01) => 2022-11-06@08:01
set a localtoutc('2022-12-01@12:00')
localtoutc(2022-12-01@12:00) => 2022-12-01@17:00
@@ -10355,10 +10355,10 @@ set b utctolocal('2022-01-01@17:00')
utctolocal(2022-01-01@17:00) => 2022-01-01@12:00
set b utctolocal('2022-03-13@06:00')
utctolocal(2022-03-13@06:00) => 2022-03-13@01:00
set b utctolocal('2022-03-13@06:01')
utctolocal(2022-03-13@06:01) => 2022-03-13@01:01
set b utctolocal('2022-03-13@06:59')
utctolocal(2022-03-13@06:59) => 2022-03-13@01:59
set b utctolocal('2022-03-13@07:01')
utctolocal(2022-03-13@07:01) => 2022-03-13@03:01
set b utctolocal('2022-03-13@07:59')
utctolocal(2022-03-13@07:59) => 2022-03-13@03:59
set b utctolocal('2022-03-13@07:00')
utctolocal(2022-03-13@07:00) => 2022-03-13@03:00
set b utctolocal('2022-03-13@07:01')
@@ -10367,20 +10367,20 @@ set b utctolocal('2022-03-13@07:59')
utctolocal(2022-03-13@07:59) => 2022-03-13@03:59
set b utctolocal('2022-06-01@16:00')
utctolocal(2022-06-01@16:00) => 2022-06-01@12:00
set b utctolocal('2022-11-06@05:59')
utctolocal(2022-11-06@05:59) => 2022-11-06@01:59
set b utctolocal('2022-11-06@06:00')
utctolocal(2022-11-06@06:00) => 2022-11-06@01:00
set b utctolocal('2022-11-06@06:01')
utctolocal(2022-11-06@06:01) => 2022-11-06@01:01
set b utctolocal('2022-11-06@06:59')
utctolocal(2022-11-06@06:59) => 2022-11-06@01:59
set b utctolocal('2022-11-06@03:59')
utctolocal(2022-11-06@03:59) => 2022-11-05@23:59
set b utctolocal('2022-11-06@07:00')
utctolocal(2022-11-06@07:00) => 2022-11-06@02:00
set b utctolocal('2022-11-06@07:01')
utctolocal(2022-11-06@07:01) => 2022-11-06@02:01
set b utctolocal('2022-12-01@17:00')
utctolocal(2022-12-01@17:00) => 2022-12-01@12:00
set b utctolocal('2022-11-06@07:59')
utctolocal(2022-11-06@07:59) => 2022-11-06@02:59
set b utctolocal('2022-11-06@08:00')
utctolocal(2022-11-06@08:00) => 2022-11-06@03:00
set b utctolocal('2022-11-06@08:01')
utctolocal(2022-11-06@08:01) => 2022-11-06@03:01
set b utctolocal('2022-12-01@18:00')
utctolocal(2022-12-01@18:00) => 2022-12-01@13:00
set c timezone('2022-07-01')
timezone(2022-07-01) => "EDT"
@@ -10392,20 +10392,20 @@ No reminders.
set a localtoutc('2022-01-01@12:00')
localtoutc(2022-01-01@12:00) => 2022-01-01@11:00
set a localtoutc('2022-03-13@02:59')
localtoutc(2022-03-13@02:59) => 2022-03-13@01:59
set a localtoutc('2022-03-13@03:00')
localtoutc(2022-03-13@03:00) => 2022-03-13@02:00
set a localtoutc('2022-03-13@03:01')
localtoutc(2022-03-13@03:01) => 2022-03-13@02:01
set a localtoutc('2022-03-13@03:59')
localtoutc(2022-03-13@03:59) => 2022-03-13@02:59
set a localtoutc('2022-03-13@04:00')
localtoutc(2022-03-13@04:00) => 2022-03-13@03:00
set a localtoutc('2022-03-13@04:01')
localtoutc(2022-03-13@04:01) => 2022-03-13@03:01
set a localtoutc('2022-06-01@12:00')
localtoutc(2022-06-01@12:00) => 2022-06-01@10:00
set a localtoutc('2022-11-06@01:59')
localtoutc(2022-11-06@01:59) => 2022-11-06@00:59
set a localtoutc('2022-11-06@02:00')
localtoutc(2022-11-06@02:00) => 2022-11-06@01:00
set a localtoutc('2022-11-06@02:01')
localtoutc(2022-11-06@02:01) => 2022-11-06@01:01
set a localtoutc('2022-11-06@02:59')
localtoutc(2022-11-06@02:59) => 2022-11-06@01:59
set a localtoutc('2022-11-06@03:00')
localtoutc(2022-11-06@03:00) => 2022-11-06@02:00
set a localtoutc('2022-11-06@03:01')
localtoutc(2022-11-06@03:01) => 2022-11-06@02:01
set a localtoutc('2022-12-01@12:00')
localtoutc(2022-12-01@12:00) => 2022-12-01@11:00
@@ -10413,10 +10413,10 @@ set b utctolocal('2022-01-01@17:00')
utctolocal(2022-01-01@17:00) => 2022-01-01@18:00
set b utctolocal('2022-03-13@06:00')
utctolocal(2022-03-13@06:00) => 2022-03-13@07:00
set b utctolocal('2022-03-13@06:01')
utctolocal(2022-03-13@06:01) => 2022-03-13@07:01
set b utctolocal('2022-03-13@06:59')
utctolocal(2022-03-13@06:59) => 2022-03-13@07:59
set b utctolocal('2022-03-13@07:01')
utctolocal(2022-03-13@07:01) => 2022-03-13@08:01
set b utctolocal('2022-03-13@07:59')
utctolocal(2022-03-13@07:59) => 2022-03-13@08:59
set b utctolocal('2022-03-13@07:00')
utctolocal(2022-03-13@07:00) => 2022-03-13@08:00
set b utctolocal('2022-03-13@07:01')
@@ -10425,20 +10425,20 @@ set b utctolocal('2022-03-13@07:59')
utctolocal(2022-03-13@07:59) => 2022-03-13@08:59
set b utctolocal('2022-06-01@16:00')
utctolocal(2022-06-01@16:00) => 2022-06-01@18:00
set b utctolocal('2022-11-06@05:59')
utctolocal(2022-11-06@05:59) => 2022-11-06@06:59
set b utctolocal('2022-11-06@06:00')
utctolocal(2022-11-06@06:00) => 2022-11-06@07:00
set b utctolocal('2022-11-06@06:01')
utctolocal(2022-11-06@06:01) => 2022-11-06@07:01
set b utctolocal('2022-11-06@06:59')
utctolocal(2022-11-06@06:59) => 2022-11-06@07:59
set b utctolocal('2022-11-06@03:59')
utctolocal(2022-11-06@03:59) => 2022-11-06@04:59
set b utctolocal('2022-11-06@07:00')
utctolocal(2022-11-06@07:00) => 2022-11-06@08:00
set b utctolocal('2022-11-06@07:01')
utctolocal(2022-11-06@07:01) => 2022-11-06@08:01
set b utctolocal('2022-12-01@17:00')
utctolocal(2022-12-01@17:00) => 2022-12-01@18:00
set b utctolocal('2022-11-06@07:59')
utctolocal(2022-11-06@07:59) => 2022-11-06@08:59
set b utctolocal('2022-11-06@08:00')
utctolocal(2022-11-06@08:00) => 2022-11-06@09:00
set b utctolocal('2022-11-06@08:01')
utctolocal(2022-11-06@08:01) => 2022-11-06@09:01
set b utctolocal('2022-12-01@18:00')
utctolocal(2022-12-01@18:00) => 2022-12-01@19:00
set c timezone('2022-07-01')
timezone(2022-07-01) => "CEST"
@@ -10446,3 +10446,53 @@ set c timezone('2022-12-01')
timezone(2022-12-01) => "CET"
No reminders.
Solstice/Equinox Tests
March Solstice 2022 is 2022-03-20@15:34 UTC
June Equinox 2022 is 2022-06-21@09:14 UTC
September Solstice 2022 is 2022-09-23@01:05 UTC
December Equinox 2022 is 2022-12-21@21:49 UTC
March Solstice 2023 is 2023-03-20@21:25 UTC
June Equinox 2023 is 2023-06-21@14:58 UTC
September Solstice 2023 is 2023-09-23@06:51 UTC
December Equinox 2023 is 2023-12-22@03:28 UTC
March Solstice 2024 is 2024-03-20@03:07 UTC
June Equinox 2024 is 2024-06-20@20:52 UTC
September Solstice 2024 is 2024-09-22@12:44 UTC
December Equinox 2024 is 2024-12-21@09:21 UTC
March Solstice 2025 is 2025-03-20@09:02 UTC
June Equinox 2025 is 2025-06-21@02:43 UTC
September Solstice 2025 is 2025-09-22@18:20 UTC
December Equinox 2025 is 2025-12-21@15:04 UTC
March Solstice 2026 is 2026-03-20@14:46 UTC
June Equinox 2026 is 2026-06-21@08:26 UTC
September Solstice 2026 is 2026-09-23@00:06 UTC
December Equinox 2026 is 2026-12-21@20:51 UTC
March Solstice 2030 is 2030-03-20@13:53 UTC
June Equinox 2030 is 2030-06-21@07:32 UTC
September Solstice 2030 is 2030-09-22@23:28 UTC
December Equinox 2030 is 2030-12-21@20:10 UTC
March Solstice 2050 is 2050-03-20@10:21 UTC
June Equinox 2050 is 2050-06-21@03:34 UTC
September Solstice 2050 is 2050-09-22@19:29 UTC
December Equinox 2050 is 2050-12-21@16:39 UTC
Next March Solstice is 2045-03-20@05:08 UTC
Next June Equinox is 2044-06-20@16:51 UTC
Next September Solstice is 2044-09-22@08:49 UTC
Next December Equinox is 2044-12-21@05:45 UTC
Reminders for Thursday, 20th October, 2022:
Should be three banners.
Reminders for Friday, 21st October, 2022:
Should be three banners.
Reminders for Saturday, 22nd October, 2022:
Should be three banners.
SECURITY: Won't read world-writable file or directory!
Can't open file: include_dir/ww
Error reading include_dir/ww: Can't open file
SECURITY: Won't read world-writable file or directory!
Error reading include_dir/ww: No files matching *.rem

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()