mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 22:38:37 +02:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e345eb15f2 | ||
|
|
e8b2872a87 | ||
|
|
2f196e3c9f | ||
|
|
839b844a10 | ||
|
|
0cea410529 | ||
|
|
90397ece64 | ||
|
|
0b95fc290c | ||
|
|
9a4e8b6070 | ||
|
|
924fd16ade | ||
|
|
0815fe19cc | ||
|
|
7f445e1b66 | ||
|
|
31afc60af4 | ||
|
|
9d34a8aa42 | ||
|
|
91325ff489 | ||
|
|
1f99d6df59 | ||
|
|
8a608a06b8 | ||
|
|
bb34474e59 | ||
|
|
029c054489 | ||
|
|
01400d0672 | ||
|
|
a1eafb2c89 | ||
|
|
af88e393f9 | ||
|
|
3a250ce765 | ||
|
|
d651ac40a8 | ||
|
|
653324e220 | ||
|
|
e5c6703eaa | ||
|
|
1596d9c76a | ||
|
|
4aacf74e25 | ||
|
|
ae58bc7c11 | ||
|
|
387125d983 | ||
|
|
aa5f9297b2 | ||
|
|
8c4a7e766f | ||
|
|
d7f32d3901 | ||
|
|
d4f09e2a31 |
@@ -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
|
||||
|
||||
1
Makefile
1
Makefile
@@ -1,4 +1,5 @@
|
||||
# Top-level Makefile for Remind.
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
all: src/Makefile
|
||||
@echo ""
|
||||
|
||||
1
build.tk
1
build.tk
@@ -1,5 +1,6 @@
|
||||
#!/bin/sh
|
||||
# -*-Mode: TCL;-*-
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#--------------------------------------------------------------
|
||||
# BUILD.TK
|
||||
|
||||
2
configure
vendored
2
configure
vendored
@@ -4025,7 +4025,7 @@ _ACEOF
|
||||
fi
|
||||
done
|
||||
|
||||
VERSION=04.02.01
|
||||
VERSION=04.02.02
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ if test "$?" != 0 ; then
|
||||
exit 1
|
||||
fi
|
||||
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
|
||||
VERSION=04.02.01
|
||||
VERSION=04.02.02
|
||||
AC_SUBST(VERSION)
|
||||
AC_SUBST(PERL)
|
||||
AC_SUBST(PERLARTIFACTS)
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
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
|
||||
@@ -17,7 +42,8 @@ CHANGES TO REMIND
|
||||
|
||||
- MINOR FIX: Remove unnecessary %"...%" markers in holidays/us.rem
|
||||
|
||||
- MINOR FIX: Don't use the -ffat-lto-objects if we're compiling with Clang.
|
||||
- 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.)
|
||||
@@ -1892,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:
|
||||
|
||||
|
||||
@@ -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 %
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Canadian holidays
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
OMIT 1 Jan MSG New Year's Day
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# 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
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
SET autolang getenv("LC_ALL")
|
||||
IF autolang == ""
|
||||
SET autolang getenv("LANGUAGE")
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
16
include/seasons.rem
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!perl
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!@PERL@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
use strict;
|
||||
use warnings;
|
||||
use lib '@prefix@/lib/perl5';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package Remind::PDF;
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package Remind::PDF::Entry;
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
|
||||
@@ -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
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -3823,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
|
||||
}
|
||||
|
||||
@@ -3917,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
|
||||
|
||||
129
src/calendar.c
129
src/calendar.c
@@ -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");
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
125
src/dorem.c
125
src/dorem.c
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
17
src/expr.c
17
src/expr.c
@@ -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;
|
||||
@@ -1290,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);
|
||||
}
|
||||
@@ -1367,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;
|
||||
@@ -1401,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') {
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
56
src/files.c
56
src/files.c
@@ -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;
|
||||
|
||||
402
src/funcs.c
402
src/funcs.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
45
src/hbcal.c
45
src/hbcal.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
39
src/init.c
39
src/init.c
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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); \
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
60
src/main.c
60
src/main.c
@@ -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;
|
||||
@@ -181,7 +182,7 @@ static void DoReminders(void)
|
||||
if (!UseStdin) {
|
||||
FileAccessDate = GetAccessDate(InitialFile);
|
||||
} else {
|
||||
FileAccessDate = JulianToday;
|
||||
FileAccessDate = DSEToday;
|
||||
}
|
||||
|
||||
if (FileAccessDate < 0) {
|
||||
@@ -317,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;
|
||||
|
||||
@@ -337,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;
|
||||
|
||||
@@ -355,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);
|
||||
}
|
||||
@@ -376,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;
|
||||
}
|
||||
@@ -749,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.) */
|
||||
/* */
|
||||
@@ -766,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -859,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;
|
||||
@@ -867,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) {
|
||||
@@ -877,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;
|
||||
@@ -1141,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);
|
||||
@@ -1171,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;
|
||||
|
||||
17
src/moon.c
17
src/moon.c
@@ -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)
|
||||
@@ -504,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);
|
||||
@@ -537,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);
|
||||
@@ -556,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);
|
||||
}
|
||||
|
||||
29
src/omit.c
29
src/omit.c
@@ -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);
|
||||
}
|
||||
|
||||
35
src/protos.h
35
src/protos.h
@@ -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);
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
21
src/sort.c
21
src/sort.c
@@ -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);
|
||||
}
|
||||
|
||||
12
src/token.c
12
src/token.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
19
src/var.c
19
src/var.c
@@ -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
43
tests/soleq.rem
Normal 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
|
||||
@@ -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,9 +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
|
||||
@@ -414,3 +431,4 @@ else
|
||||
echo "reference file test.cmp."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -1060,7 +1060,7 @@ set a057 value("a05"+"6")
|
||||
"a05" + "6" => "a056"
|
||||
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
set a058 version()
|
||||
version() => "04.02.01"
|
||||
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.01"
|
||||
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
|
||||
@@ -10446,6 +10446,39 @@ 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.
|
||||
@@ -10458,3 +10491,8 @@ 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
|
||||
|
||||
@@ -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
|
||||
#
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user