mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
143 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aef5b353cd | ||
|
|
8a99c29533 | ||
|
|
0bf2b0772a | ||
|
|
a033a48acd | ||
|
|
0feb81c8cc | ||
|
|
1850607542 | ||
|
|
213138a7b7 | ||
|
|
562cec3dc8 | ||
|
|
18b57d26b4 | ||
|
|
c80d72f623 | ||
|
|
2739a41651 | ||
|
|
5a56f4c61b | ||
|
|
77080ff600 | ||
|
|
c4aa21ff51 | ||
|
|
34c513ba3b | ||
|
|
35c16a060a | ||
|
|
69dedc577f | ||
|
|
a7d8f3c887 | ||
|
|
800a4b15b2 | ||
|
|
3e981fd8be | ||
|
|
7c530d3068 | ||
|
|
58f9cf641b | ||
|
|
53906035fe | ||
|
|
4804325863 | ||
|
|
5f5e7054f4 | ||
|
|
078dba1e98 | ||
|
|
8ebec9584c | ||
|
|
2504b39be2 | ||
|
|
e394f402f8 | ||
|
|
5a2914f6c7 | ||
|
|
a19b009f7c | ||
|
|
6373ae8ca5 | ||
|
|
b8c4786b33 | ||
|
|
4e7cfc20ce | ||
|
|
0c9a35a584 | ||
|
|
5e333f6162 | ||
|
|
af8b4e6df1 | ||
|
|
3fa798523a | ||
|
|
53001f9fbc | ||
|
|
9cd76eae84 | ||
|
|
c8295b6251 | ||
|
|
3c95245407 | ||
|
|
3362c7226c | ||
|
|
356b562d75 | ||
|
|
6eebcdc39d | ||
|
|
5a80d63060 | ||
|
|
c7ca1b4baa | ||
|
|
dc89a6fba9 | ||
|
|
f83fec5563 | ||
|
|
9c38161430 | ||
|
|
68f5fe1d10 | ||
|
|
bc7c57e53b | ||
|
|
88aacb3905 | ||
|
|
a894076bfc | ||
|
|
82e068fcca | ||
|
|
a119d97539 | ||
|
|
01afb63a3d | ||
|
|
54fccabdfe | ||
|
|
ba4d44664f | ||
|
|
d76c5499b5 | ||
|
|
84e8244e48 | ||
|
|
92a6115a5c | ||
|
|
b98e336e9e | ||
|
|
ffcd21446e | ||
|
|
af9ca68d99 | ||
|
|
71db7168a1 | ||
|
|
54f284c43f | ||
|
|
0ab93f2dea | ||
|
|
3d97f87bcd | ||
|
|
dcfa6d8ef8 | ||
|
|
52dd5332f4 | ||
|
|
7b5fafe1ab | ||
|
|
929af71a10 | ||
|
|
abf7c74ff2 | ||
|
|
5b9d9a67b2 | ||
|
|
16ca2ade23 | ||
|
|
d3e6c81a3a | ||
|
|
13ae49d3cd | ||
|
|
78adc9f61d | ||
|
|
a622d4fad4 | ||
|
|
6c0e7b4ff5 | ||
|
|
28e0599380 | ||
|
|
87445f639c | ||
|
|
af6e159eaa | ||
|
|
bffa28e258 | ||
|
|
1781f84d84 | ||
|
|
ed6e65182e | ||
|
|
f5cc0ec686 | ||
|
|
a2c818f96c | ||
|
|
0bbbaaf3d9 | ||
|
|
1c81d4cae3 | ||
|
|
56c684087b | ||
|
|
9500a929ea | ||
|
|
585d45e4a1 | ||
|
|
67d1d1366d | ||
|
|
f4018892e8 | ||
|
|
ffd309f89d | ||
|
|
286babc1bf | ||
|
|
cc3c0040e9 | ||
|
|
b33a1ee98b | ||
|
|
99706741bb | ||
|
|
df73a74503 | ||
|
|
c747ebebb4 | ||
|
|
6b412062c2 | ||
|
|
27b688f82c | ||
|
|
4c314ff81c | ||
|
|
d2955ec733 | ||
|
|
480216db9e | ||
|
|
9dbb0de7e6 | ||
|
|
9f9ae77895 | ||
|
|
d9796e72e5 | ||
|
|
e0b0d043c6 | ||
|
|
fe4499ab72 | ||
|
|
e50d583659 | ||
|
|
6b05d772f0 | ||
|
|
84dd73f023 | ||
|
|
00dca8b70f | ||
|
|
c4bc145cd9 | ||
|
|
bd614c1cde | ||
|
|
1446ac0552 | ||
|
|
26ded447ab | ||
|
|
a4ccb0738e | ||
|
|
27a1b449bd | ||
|
|
1443282859 | ||
|
|
4a2d707654 | ||
|
|
fd2a61928c | ||
|
|
a05d9eefc9 | ||
|
|
6f230e81bd | ||
|
|
973019c4c7 | ||
|
|
cb712ad7e7 | ||
|
|
be7c67b6fd | ||
|
|
a933c8bc69 | ||
|
|
087fbfd8e6 | ||
|
|
ff641d7990 | ||
|
|
54e788b765 | ||
|
|
4283feff31 | ||
|
|
062a84b758 | ||
|
|
d161a8ff1a | ||
|
|
0df4a79531 | ||
|
|
1b26e39e2f | ||
|
|
c63c4cf07e | ||
|
|
586b3565f0 | ||
|
|
877aaed1a1 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -23,7 +23,6 @@ rem2pdf/Makefile.old
|
||||
rem2pdf/Makefile.top
|
||||
rem2pdf/bin/rem2pdf
|
||||
scripts/tkremind
|
||||
set-irc-topic
|
||||
src/*.tar.gz*
|
||||
src/Makefile
|
||||
src/config.h
|
||||
|
||||
@@ -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-2024 Dianne Skoll, except where noted in
|
||||
2. REMIND is Copyright (C) 1992-2025 Dianne Skoll, except where noted in
|
||||
individual files.
|
||||
|
||||
3. DISTRIBUTION AND USE
|
||||
|
||||
78
README
78
README
@@ -1,78 +0,0 @@
|
||||
REMIND
|
||||
|
||||
Remind is a full-featured calendar/alarm program. Copying policy is
|
||||
in the file "COPYRIGHT" in this directory.
|
||||
|
||||
Installation notes for various operating systems are in "docs". See
|
||||
the appropriate README file for installation on your system.
|
||||
|
||||
Manual pages are in "man".
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Quick UNIX installation instructions for the very impatient:
|
||||
|
||||
If you have Tcl/Tk (wish 4.1 or higher) installed and are running X Windows:
|
||||
--------------------------------------------------------------
|
||||
|
||||
1) Type: wish ./build.tk from this directory. Fill in the various
|
||||
options and hit "Build Remind"
|
||||
|
||||
2) Type: "make install" -- you may need to be root to do this.
|
||||
|
||||
If you do NOT have Tcl/Tk or are NOT running X Windows:
|
||||
-------------------------------------------------------
|
||||
|
||||
1) Edit the file "src/custom.h" according to your preferences.
|
||||
|
||||
2) Edit the file "src/lang.h" to choose a language.
|
||||
|
||||
3) Type: "./configure" (You can supply options; type "./configure --help"
|
||||
for details.)
|
||||
|
||||
4) Type: "make"
|
||||
|
||||
5) Type: "make install" -- you may need to be root to do this.
|
||||
|
||||
PREREQUISITES:
|
||||
--------------
|
||||
|
||||
Remind and rem2ps have no prerequisites beyond the standard C library and
|
||||
the standard math library.
|
||||
|
||||
Rem2HTML requires the JSON::MaybeXS Perl module.
|
||||
Rem2PDF requires the JSON::MaybeXS, Pango and Cairo Perl modules.
|
||||
|
||||
- On Debian-like systems, these prerequisites may be installed with:
|
||||
|
||||
apt install libjson-maybexs-perl libpango-perl libcairo-perl
|
||||
|
||||
- On RPM-based systems, you need perl-Pango, perl-Cairo and perl-JSON-MaybeXS
|
||||
|
||||
- On Gentoo, you need dev-perl/Pango, dev-perl/Cairo and dev-perl/JSON-MaybeXS.
|
||||
|
||||
- On Arch linux, you need pango-perl, cairo-perl and perl-json-maybexs
|
||||
|
||||
TkRemind requires Tcl/Tk and the tcllib library.
|
||||
|
||||
- On Debian-like systems, install with:
|
||||
|
||||
apt install tcl tk tcllib
|
||||
|
||||
- On RPM-based systems, you need tcl, tk and tcllib
|
||||
|
||||
- On Arch Linux, you need tk and tcllib. The latter is available at
|
||||
https://aur.archlinux.org/packages/tcllib
|
||||
|
||||
If the little arrows for "Previous Month" and "Next Month" do not display
|
||||
correctly in TkRemind, you may need to install the Noto Fonts. Install
|
||||
all of your distribution's Nonto Font-related packages.
|
||||
|
||||
- On Debian-like systems, install with:
|
||||
|
||||
apt install fonts-noto-core fonts-noto-color-emoji \
|
||||
fonts-noto-extra fonts-noto-ui-core fonts-noto-ui-extra
|
||||
|
||||
==========================================================================
|
||||
Contact info: mailto:dianne@skoll.ca
|
||||
Home page: https://dianne.skoll.ca/projects/remind/
|
||||
63
README.md
Normal file
63
README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# REMIND
|
||||
|
||||
Remind is a full-featured calendar/alarm program. Copying policy is
|
||||
in the file "COPYRIGHT" included with the source; Remind is licensed under
|
||||
the GNU General Public License, Vesion 2.
|
||||
|
||||
## Prerequisites:
|
||||
|
||||
`remind` and `rem2ps` have no prerequisites beyond the standard C library and
|
||||
the standard math library.
|
||||
|
||||
`rem2html` requires the `JSON::MaybeXS` Perl module and `rem2pdf`
|
||||
requires the `JSON::MaybeXS`, `Pango` and `Cairo` Perl modules.
|
||||
|
||||
- On Debian-like systems, these prerequisites may be installed with:
|
||||
|
||||
`apt install libjson-maybexs-perl libpango-perl libcairo-perl`
|
||||
|
||||
- On RPM-based systems, you need `perl-Pango`, `perl-Cairo` and
|
||||
`perl-JSON-MaybeXS`
|
||||
|
||||
- On Gentoo, you need `dev-perl/Pango`, `dev-perl/Cairo` and
|
||||
`dev-perl/JSON-MaybeXS`.
|
||||
|
||||
- On Arch linux, you need `pango-perl`, `cairo-perl` and `perl-json-maybexs`
|
||||
|
||||
TkRemind requires Tcl/Tk and the `tcllib` library.
|
||||
|
||||
- On Debian-like systems, install with:
|
||||
|
||||
`apt install tcl tk tcllib`
|
||||
|
||||
- On RPM-based systems, you need `tcl`, `tk` and `tcllib`
|
||||
|
||||
- On Arch Linux, you need `tk` and `tcllib`. The latter is available at
|
||||
https://aur.archlinux.org/packages/tcllib
|
||||
|
||||
If the little arrows for "Previous Month" and "Next Month" do not display
|
||||
correctly in TkRemind, you may need to install the Noto Fonts. Install
|
||||
all of your distribution's Nonto Font-related packages.
|
||||
|
||||
- On Debian-like systems, install with:
|
||||
|
||||
`apt install fonts-noto-core fonts-noto-color-emoji fonts-noto-extra fonts-noto-ui-core fonts-noto-ui-extra`
|
||||
|
||||
## Installation
|
||||
|
||||
Remind can be installed with the usual:
|
||||
|
||||
`./configure && make && make test && sudo make install`
|
||||
|
||||
You can edit `custom.h` to configure some aspects of Remind. Or, if
|
||||
you have Tcl/Tk installed, you can use the graphical build tool to
|
||||
edit `custom.h` on your behalf:
|
||||
|
||||
`wish ./build.tk`
|
||||
|
||||
---
|
||||
|
||||
Contact info: dianne@skoll.ca
|
||||
|
||||
Home page: [https://dianne.skoll.ca/projects/remind/](https://dianne.skoll.ca/projects/remind/)
|
||||
|
||||
56
build.tk
56
build.tk
@@ -8,7 +8,7 @@
|
||||
# A cheesy graphical front-end for building and installing REMIND.
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2018 Dianne Skoll
|
||||
# Copyright (C) 1992-2025 Dianne Skoll
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -40,7 +40,6 @@ proc SetConfigDefaults {} {
|
||||
set Config(TIMESEP) ":"
|
||||
set Config(NORTHERN_HEMISPHERE) 1
|
||||
set Config(WESTERN_HEMISPHERE) 1
|
||||
set Config(LANGUAGE) "English"
|
||||
set Config(INST_DIR) "/usr/local/bin"
|
||||
set Config(MAN_DIR) "/usr/local/share/man"
|
||||
}
|
||||
@@ -242,32 +241,6 @@ proc CreateOptionsDialog { w } {
|
||||
|
||||
grid configure $w.timelabel -row 2 -column 0 -sticky e
|
||||
grid configure $w.time -row 2 -column 1 -sticky nsew
|
||||
|
||||
label $w.langlabel -text "Language: "
|
||||
menubutton $w.lang -text $Config(LANGUAGE) -indicatoron 1 -relief raised \
|
||||
-menu $w.lang.menu
|
||||
menu $w.lang.menu -tearoff 0
|
||||
foreach lang {
|
||||
"Brazilian Portuguese"
|
||||
"Danish"
|
||||
"Dutch"
|
||||
"English"
|
||||
"Finnish"
|
||||
"French"
|
||||
"German"
|
||||
"Italian"
|
||||
"Norwegian"
|
||||
"Polish"
|
||||
"Romanian"
|
||||
"Spanish"
|
||||
"Icelandic"
|
||||
} {
|
||||
$w.lang.menu add command -label $lang -command [list $w.lang configure -text $lang]
|
||||
}
|
||||
|
||||
grid configure $w.langlabel -row 3 -column 0 -sticky e
|
||||
grid configure $w.lang -row 3 -column 1 -sticky nsew
|
||||
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
@@ -491,32 +464,16 @@ proc CreateCustomH {} {
|
||||
# %RETURNS:
|
||||
# Nothing
|
||||
# %DESCRIPTION:
|
||||
# Runs "make" with appropriate language definitions
|
||||
# Runs "make"
|
||||
#***********************************************************************
|
||||
proc CallMake {} {
|
||||
global Options
|
||||
set lang [$Options.lang cget -text]
|
||||
switch -- $lang {
|
||||
"German" { set lang GERMAN }
|
||||
"Dutch" { set lang DUTCH }
|
||||
"Finnish" { set lang FINNISH }
|
||||
"French" { set lang FRENCH }
|
||||
"Norwegian" { set lang NORWEGIAN }
|
||||
"Danish" { set lang DANISH }
|
||||
"Polish" { set lang POLISH }
|
||||
"Brazilian Portuguese" { set lang BRAZPORT }
|
||||
"Italian" { set lang ITALIAN }
|
||||
"Romanian" { set lang ROMANIAN }
|
||||
"Spanish" { set lang SPANISH }
|
||||
"Icelandic" { set lang ICELANDIC }
|
||||
default { set lang ENGLISH }
|
||||
}
|
||||
set nproc 0
|
||||
catch { set nproc [exec nproc] }
|
||||
if { $nproc != 0 } {
|
||||
RunCommand "make -j $nproc \"LANGDEF=-DLANG=$lang\""
|
||||
RunCommand "make -j $nproc"
|
||||
} else {
|
||||
RunCommand "make \"LANGDEF=-DLANG=$lang\""
|
||||
RunCommand "make"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -530,7 +487,7 @@ proc CallMake {} {
|
||||
# Michael McLennan, Bell Labs Innovations for Lucent Technologies
|
||||
# Addison-Wesley Professional Computing Series
|
||||
# ======================================================================
|
||||
# Copyright (c) 1996-1997 Lucent Technologies Inc. and Mark Harrison
|
||||
# Copyright (C) 1996-1997 Lucent Technologies Inc. and Mark Harrison
|
||||
# ======================================================================
|
||||
|
||||
option add *Tabnotebook.tabs.background #666666 widgetDefault
|
||||
@@ -644,7 +601,7 @@ proc tabnotebook_display {win name} {
|
||||
# Michael McLennan, Bell Labs Innovations for Lucent Technologies
|
||||
# Addison-Wesley Professional Computing Series
|
||||
# ======================================================================
|
||||
# Copyright (c) 1996-1997 Lucent Technologies Inc. and Mark Harrison
|
||||
# Copyright (C) 1996-1997 Lucent Technologies Inc. and Mark Harrison
|
||||
# ======================================================================
|
||||
|
||||
option add *Notebook.borderWidth 2 widgetDefault
|
||||
@@ -786,7 +743,6 @@ proc SetConfigFromRemind {} {
|
||||
QueryRemind $rem LOCATION {$Location}
|
||||
QueryRemind $rem DATESEP {$DateSep}
|
||||
QueryRemind $rem TIMESEP {$TimeSep}
|
||||
QueryRemind $rem LANGUAGE {language()}
|
||||
|
||||
set $Config(LAT_MIN) [expr abs($Config(LAT_MIN))]
|
||||
set $Config(LAT_SEC) [expr abs($Config(LAT_SEC))]
|
||||
|
||||
18
configure
vendored
18
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.71 for remind 05.01.01.
|
||||
# Generated by GNU Autoconf 2.71 for remind 05.02.02.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
|
||||
@@ -608,8 +608,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='remind'
|
||||
PACKAGE_TARNAME='remind'
|
||||
PACKAGE_VERSION='05.01.01'
|
||||
PACKAGE_STRING='remind 05.01.01'
|
||||
PACKAGE_VERSION='05.02.02'
|
||||
PACKAGE_STRING='remind 05.02.02'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL='https://dianne.skoll.ca/projects/remind/'
|
||||
|
||||
@@ -1265,7 +1265,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures remind 05.01.01 to adapt to many kinds of systems.
|
||||
\`configure' configures remind 05.02.02 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1327,7 +1327,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of remind 05.01.01:";;
|
||||
short | recursive ) echo "Configuration of remind 05.02.02:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1415,7 +1415,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
remind configure 05.01.01
|
||||
remind configure 05.02.02
|
||||
generated by GNU Autoconf 2.71
|
||||
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
@@ -1865,7 +1865,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by remind $as_me 05.01.01, which was
|
||||
It was created by remind $as_me 05.02.02, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
@@ -4710,7 +4710,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by remind $as_me 05.01.01, which was
|
||||
This file was extended by remind $as_me 05.02.02, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -4775,7 +4775,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config='$ac_cs_config_escaped'
|
||||
ac_cs_version="\\
|
||||
remind config.status 05.01.01
|
||||
remind config.status 05.02.02
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(remind, 05.01.01, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_INIT(remind, 05.02.02, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_CONFIG_SRCDIR([src/queue.c])
|
||||
|
||||
cat <<'EOF'
|
||||
|
||||
@@ -117,7 +117,8 @@
|
||||
"NOQUEUE" "OMIT" "OMITFUNC" "ONCE" "POP" "POP-OMIT-CONTEXT" "PRESERVE"
|
||||
"PRIORITY" "PS" "PSFILE" "PUSH" "PUSH-OMIT-CONTEXT" "REM" "RUN"
|
||||
"SATISFY" "SCAN" "SCANFROM" "SCHED" "SECOND" "SET" "SKIP" "SPECIAL"
|
||||
"TAG" "THIRD" "THROUGH" "UNSET" "UNTIL" "WARN")
|
||||
"SYSINCLUDE" "TAG" "THIRD" "THROUGH" "TRANSLATE" "TRANS" "UNSET"
|
||||
"UNTIL" "WARN")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
|
||||
@@ -129,8 +130,8 @@
|
||||
(defconst remind-builtin-variables
|
||||
(sort
|
||||
(list " $AddBlankLines" "$Ago" "$Am" "$And" "$April" "$At" "$August"
|
||||
"$CalcUTC" "$CalMode" "$Daemon" "$DateSep" "$DateTimeSep" "$December"
|
||||
"$DedupeReminders" "$DefaultColor" "$DefaultDelta"
|
||||
"$CalcUTC" "$CalMode" "$CalType" "$Daemon" "$DateSep" "$DateTimeSep"
|
||||
"$December" "$DedupeReminders" "$DefaultColor" "$DefaultDelta"
|
||||
"$DefaultPrio" "$DefaultTDelta" "$DeltaOverride"
|
||||
"$DontFork" "$DontQueue" "$DontTrigAts" "$EndSent" "$EndSentIg"
|
||||
"$ExpressionTimeLimit" "$February" "$FirstIndent" "$FoldYear"
|
||||
@@ -162,7 +163,7 @@
|
||||
|
||||
(defconst remind-builtin-functions
|
||||
(sort
|
||||
(list "abs" "access" "adawn" "adusk" "ampm" "ansicolor" "args" "asc"
|
||||
(list "_" "abs" "access" "adawn" "adusk" "ampm" "ansicolor" "args" "asc"
|
||||
"baseyr" "char" "choose" "coerce" "columns" "current" "date"
|
||||
"datepart" "datetime" "dawn" "day" "daysinmon" "defined" "dosubst"
|
||||
"dusk" "easterdate" "evaltrig" "filedate" "filedatetime" "filedir"
|
||||
@@ -188,21 +189,21 @@
|
||||
(defvar remind-conf-command-face 'remind-conf-command-face
|
||||
"Remind commands.")
|
||||
(defface remind-conf-command-face
|
||||
'((t :foreground "SeaGreen4" :bold t))
|
||||
'((t :foreground "#FF8080"))
|
||||
"Font Lock mode face used to highlight commands."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-conf-keyword-face 'remind-conf-keyword-face
|
||||
"Remind keywords.")
|
||||
(defface remind-conf-keyword-face
|
||||
'((t :foreground "blue violet"))
|
||||
'((t :foreground "#FFFF80"))
|
||||
"Font Lock mode face used to highlight keywords."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-conf-substitutes-face 'remind-conf-substitutes-face
|
||||
"Remind substitutes.")
|
||||
(defface remind-conf-substitutes-face
|
||||
'((t :foreground "blue2"))
|
||||
'((t :foreground "#8080FF"))
|
||||
"Font Lock mode face used to highlight substitutes."
|
||||
:group 'remind-conf)
|
||||
|
||||
@@ -216,7 +217,7 @@
|
||||
(defvar remind-conf-variable-face 'remind-conf-variable-face
|
||||
"Remind variable.")
|
||||
(defface remind-conf-variable-face
|
||||
'((t :foreground "DeepPink2" :bold t))
|
||||
'((t :foreground "#FF8080" :bold t))
|
||||
"Font Lock mode face used to highlight commands."
|
||||
:group 'remind-conf)
|
||||
|
||||
@@ -237,14 +238,14 @@
|
||||
(defvar remind-comment-face 'remind-comment-face
|
||||
"Remind comments.")
|
||||
(defface remind-comment-face
|
||||
'((t :foreground "brown"))
|
||||
'((t :foreground "#FF7F24"))
|
||||
"Font-lock face for highlighting comments."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-string-face 'remind-string-face
|
||||
"Remind strings.")
|
||||
(defface remind-string-face
|
||||
'((t :foreground "tomato"))
|
||||
'((t :foreground "#FF7FE0"))
|
||||
"Font lock mode face used to highlight strings."
|
||||
:group 'remind-conf)
|
||||
|
||||
@@ -296,11 +297,11 @@
|
||||
(defconst remind-conf-font-lock-keywords-1
|
||||
(list
|
||||
'("^\s*[\;\#].*$" . remind-comment-face)
|
||||
'("\"[^\"]*\"" . remind-string-face)
|
||||
'(remind-keywords-matcher . remind-conf-keyword-face)
|
||||
'("%[\"_]" . font-lock-warning-face)
|
||||
'("\\(%[a-mops-w]\\)" . remind-conf-substitutes-face)
|
||||
'("\"[^\"]*\"" . remind-string-face))
|
||||
"Minimal font-locking for `remind-conf-mode'.")
|
||||
'("\\(%[a-z]\\)" . remind-conf-substitutes-face)
|
||||
"Minimal font-locking for `remind-conf-mode'."))
|
||||
|
||||
(defconst remind-conf-font-lock-keywords-2
|
||||
(append remind-conf-font-lock-keywords-1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
REMIND version 3.2 for UNIX
|
||||
Remind for UNIX and Linux
|
||||
|
||||
REMIND is a sophisticated alarm/calendar program. Details are given
|
||||
Remind is a sophisticated alarm/calendar program. Details are given
|
||||
in the man page, "remind.1".
|
||||
|
||||
INSTALLING REMIND:
|
||||
@@ -19,88 +19,13 @@ If you do NOT have Tcl/Tk or are NOT running X11:
|
||||
|
||||
1) Edit the file "src/custom.h" according to your preferences.
|
||||
|
||||
2) Edit the file "src/lang.h" to choose a language.
|
||||
2) Type: "make"
|
||||
|
||||
3) Type: "make"
|
||||
|
||||
4) Type: "make install" -- you may need to be root to do this.
|
||||
3) Type: "make install" -- you may need to be root to do this.
|
||||
|
||||
The subdirectory "www" contains scripts for making a nice calendar
|
||||
web server. See the files README and Makefile in that directory.
|
||||
|
||||
The file "examples/defs.rem" has some sample Remind definitions and
|
||||
commands, as well as U.S. and Jewish holidays.
|
||||
|
||||
OTHER LANGUAGE SUPPORT
|
||||
|
||||
Remind has support for languages other than English. See the file
|
||||
"src/lang.h" for details. The language support may vary - you can change
|
||||
only the substitution filter, or you can translate all of the usage
|
||||
instructions and error messages as well. See "src/langs/french.h" for an
|
||||
example of the latter.
|
||||
|
||||
To compile Remind for a non-english language, look at the constants
|
||||
defined in "src/lang.h". Then, to compile Remind for Italian (as an
|
||||
example), type:
|
||||
|
||||
make "LANGDEF=-DLANG=ITALIAN"
|
||||
|
||||
If you add support for a non-English language, Remind will accept both the
|
||||
English and non-English names of months and weekdays in an input script.
|
||||
However, you should not rely on this feature if you want to write portable
|
||||
Remind scripts.
|
||||
|
||||
At a minimum, you should support month and day names in the foreign
|
||||
language, and should modify the substitution filter appropriately.
|
||||
If you are truly diligent, you can translate usage and error messages
|
||||
too.
|
||||
|
||||
Take a look at the files "src/langs/english.h" and
|
||||
"src/langs/german.h" if you want to add support for your favourite
|
||||
language. If you do add another language to Remind, please let me
|
||||
know! Here are the basic guidelines:
|
||||
|
||||
- Your language file should be called "src/langs/lxxx.h", where lxxx
|
||||
is the first 8 characters of the ENGLISH name of your language.
|
||||
|
||||
- Your language file should define L_LANGNAME to be the full English
|
||||
name of your language, with the first letter capitalized and the rest
|
||||
lower-case.
|
||||
|
||||
- You can test your language file with the script "tests/tstlang.rem"
|
||||
|
||||
- Your localized strings must be encoded using UTF-8.
|
||||
|
||||
RELEASE NOTES -- miscellaneous info that couldn't go anywhere else!
|
||||
|
||||
1. POPUP REMINDERS
|
||||
|
||||
If you're running under X11 and you have the Tcl tools, you can create
|
||||
simple pop-up reminders by creating the following Tcl script called
|
||||
'popup'. It pops a message on to the screen and waits for you to
|
||||
press the 'OK' button. If you don't press the OK button within 15
|
||||
seconds, it exits anyway. To use it, you can use the '-k' option for
|
||||
Remind as follows:
|
||||
|
||||
remind "-kpopup '%s'&" .reminders
|
||||
|
||||
Or use the following in your Remind script:
|
||||
|
||||
REM AT 17:00 RUN popup 'Time to go home.' &
|
||||
|
||||
This Tcl script is a slightly modified version of one submitted by
|
||||
Norman Walsh.
|
||||
|
||||
-------------- Cut Here ---------- Cut Here ---------- Cut Here -------------
|
||||
#!/usr/local/bin/wish
|
||||
wm withdraw .
|
||||
after 15000 { destroy . ; exit }
|
||||
tk_messageBox -message Message -detail $argv -icon info -type ok
|
||||
destroy .
|
||||
exit
|
||||
-------------- Cut Here ---------- Cut Here ---------- Cut Here -------------
|
||||
|
||||
|
||||
--
|
||||
Dianne Skoll <dianne@skoll.ca>
|
||||
https://dianne.skoll.ca/projects/remind/
|
||||
|
||||
@@ -1,5 +1,87 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 5.2 Patch 2 - 2025-01-06
|
||||
|
||||
- NEW FEATURE: remind: The "-p+" option lets you produce weekly calendars;
|
||||
so far, the rem2pdf and rem2html back-ends support rendering of weekly
|
||||
calendars.
|
||||
|
||||
- NEW FEATURE: remind: The $CalType system variable indicates the type of
|
||||
calendar being produced; its value is one of "monthly", "weekly",
|
||||
or "none". "none" signifies agenda mode rather than calendar mode.
|
||||
|
||||
- IMPROVEMENT: remind: Warn if a POP-OMIT-CONTEXT matches a
|
||||
PUSH-OMIT-CONTEXT that is in a different file.
|
||||
|
||||
- CHANGE: remind: Split the "-ds" debug option into two separate options:
|
||||
"-ds" for debugging expression-parsing and "-dh" for printing hash
|
||||
table statistics on exit.
|
||||
|
||||
* VERSION 5.2 Patch 1 - 2024-12-16
|
||||
|
||||
- BUG FIX: remind: Fix a logic error that only showed itself on big-endian
|
||||
architectures. Found thanks to Debian testing and a notification from
|
||||
Jochen Sprickerhof.
|
||||
|
||||
* VERSION 5.2 Patch 0 - 2024-12-16
|
||||
|
||||
- MAJOR NEW FEATURE: remind: Add the TRANSLATE command, the _()
|
||||
built-in function and the %(...) substitution sequence. These allow
|
||||
you to localize your reminder files more easily. The translation table
|
||||
is also made available to back-ends like rem2pdf and tkremind,
|
||||
which they can use as they see fit.
|
||||
|
||||
- MINOR FEATURE: tkremind, rem2html: Localize the names of the moon
|
||||
phases.
|
||||
|
||||
- MAJOR CHANGE: remind: Remind used to support compile-time localization
|
||||
into different languages (French, English, etc.) That compile-time
|
||||
support has been removed and all localization is now done at run-time.
|
||||
|
||||
- NEW FEATURE: remind: In JSON daemon mode (-zj), the front-end can
|
||||
request translation table entries from the Remind daemon, allowing the
|
||||
front-end to localize messages.
|
||||
|
||||
- UPDATE: Update national holidays following update to upstream Python
|
||||
library.
|
||||
|
||||
- MINOR FEATURE: Add standard include/sun.rem file for sunrise/sunset.
|
||||
|
||||
- MINOR FEATURE: The SYSINCLUDE command has been added. The command:
|
||||
|
||||
SYSINCLUDE foo/bar.rem
|
||||
|
||||
is equivalent to:
|
||||
|
||||
INCLUDE [$SysInclude]/foo/bar.rem
|
||||
|
||||
- MINOR IMPROVEMENT: Allow INCLUDE, DO and SYSINCLUDE to include files with
|
||||
spaces in their names; in this case, you have to put the filename inside
|
||||
double-quotes.
|
||||
|
||||
- IMPROVEMENT: remind: Refuse to open subdirectories named "*.rem"
|
||||
under a top-level directory rather than trying and failing with a
|
||||
confusing error.
|
||||
|
||||
- IMPROVEMENT: contrib/remind-conf-mode: Fix a few bugs and choose colors
|
||||
that are easier on the eyes.
|
||||
|
||||
- IMPROVEMENT: remind: Remind used to have three completely separate
|
||||
hash table implementations. They have all been replaced with a single
|
||||
implementation; this new implementation adapts the hash table size based
|
||||
on the number of entries and is dramatically faster than the old code
|
||||
when there are a large number of entries.
|
||||
|
||||
- MINOR FIXES: remind: Fix typos in comments; use memcpy to copy OMIT
|
||||
contexts internally.
|
||||
|
||||
- BUG FIX: remind: Actually allow the documented 9 levels of INCLUDE
|
||||
rather than 8.
|
||||
|
||||
- BUG FIX: remind: If an INCLUDE statement failed inside an IF statement,
|
||||
Remind would print spurious errors about unmatched IF/ENDIF. This has
|
||||
been fixed.
|
||||
|
||||
* VERSION 5.1 Patch 1 - 2024-11-18
|
||||
|
||||
- BUG FIX: Fix a bug in test-rem that could have caused test failures.
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
# "#PSSTUFF" for nifty PostScript examples #
|
||||
# #
|
||||
# This file is part of REMIND. #
|
||||
# Copyright (C) 1992-2024 Dianne Skoll #
|
||||
# Copyright (C) 1992-2025 Dianne Skoll #
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Not all sequences are supported by all terminals.
|
||||
|
||||
# This file is part of REMIND
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
if !defined("ansi_bold")
|
||||
|
||||
@@ -54,8 +54,8 @@ advance warning of holidays:
|
||||
FSET msgsuffix(x) char(8) + dosubst(" is %b.%", $T)
|
||||
|
||||
# Include your holiday files here...
|
||||
INCLUDE [$SysInclude]/holidays/us.rem
|
||||
INCLUDE [$SysInclude]/holidays/us/ny.rem
|
||||
SYSINCLUDE holidays/us.rem
|
||||
SYSINCLUDE holidays/us/ny.rem
|
||||
|
||||
# Restore old version of msgsuffix and $DefaultDelta
|
||||
FRENAME saved_msgsuffix msgsuffix
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
REM 1 Feb 2022 MSG Chinese New Year (Tiger)
|
||||
REM 22 Jan 2023 MSG Chinese New Year (Rabbit)
|
||||
REM 10 Feb 2024 MSG Chinese New Year (Dragon)
|
||||
REM 29 Jan 2025 MSG Chinese New Year (Snake)
|
||||
REM 17 Feb 2026 MSG Chinese New Year (Horse)
|
||||
REM 6 Feb 2027 MSG Chinese New Year (Goat)
|
||||
REM 26 Jan 2028 MSG Chinese New Year (Monkey)
|
||||
REM 13 Feb 2029 MSG Chinese New Year (Rooster)
|
||||
REM 3 Feb 2030 MSG Chinese New Year (Dog)
|
||||
REM 23 Jan 2031 MSG Chinese New Year (Pig)
|
||||
REM 11 Feb 2032 MSG Chinese New Year (Rat)
|
||||
REM 31 Jan 2033 MSG Chinese New Year (Ox)
|
||||
REM 19 Feb 2034 MSG Chinese New Year (Tiger)
|
||||
REM 8 Feb 2035 MSG Chinese New Year (Rabbit)
|
||||
REM 28 Jan 2036 MSG Chinese New Year (Dragon)
|
||||
REM 15 Feb 2037 MSG Chinese New Year (Snake)
|
||||
REM 4 Feb 2038 MSG Chinese New Year (Horse)
|
||||
REM 24 Jan 2039 MSG Chinese New Year (Goat)
|
||||
REM 12 Feb 2040 MSG Chinese New Year (Monkey)
|
||||
REM 1 Feb 2041 MSG Chinese New Year (Rooster)
|
||||
REM 22 Jan 2042 MSG Chinese New Year (Dog)
|
||||
REM 10 Feb 2043 MSG Chinese New Year (Pig)
|
||||
REM 30 Jan 2044 MSG Chinese New Year (Rat)
|
||||
REM 17 Feb 2045 MSG Chinese New Year (Ox)
|
||||
REM 6 Feb 2046 MSG Chinese New Year (Tiger)
|
||||
REM 26 Jan 2047 MSG Chinese New Year (Rabbit)
|
||||
REM 14 Feb 2048 MSG Chinese New Year (Dragon)
|
||||
REM 2 Feb 2049 MSG Chinese New Year (Snake)
|
||||
REM 23 Jan 2050 MSG Chinese New Year (Horse)
|
||||
REM 1 Feb 2022 MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 22 Jan 2023 MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 10 Feb 2024 MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 29 Jan 2025 MSG %(Chinese New Year) (%(Snake))
|
||||
REM 17 Feb 2026 MSG %(Chinese New Year) (%(Horse))
|
||||
REM 6 Feb 2027 MSG %(Chinese New Year) (%(Goat))
|
||||
REM 26 Jan 2028 MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 13 Feb 2029 MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 3 Feb 2030 MSG %(Chinese New Year) (%(Dog))
|
||||
REM 23 Jan 2031 MSG %(Chinese New Year) (%(Pig))
|
||||
REM 11 Feb 2032 MSG %(Chinese New Year) (%(Rat))
|
||||
REM 31 Jan 2033 MSG %(Chinese New Year) (%(Ox))
|
||||
REM 19 Feb 2034 MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 8 Feb 2035 MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 28 Jan 2036 MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 15 Feb 2037 MSG %(Chinese New Year) (%(Snake))
|
||||
REM 4 Feb 2038 MSG %(Chinese New Year) (%(Horse))
|
||||
REM 24 Jan 2039 MSG %(Chinese New Year) (%(Goat))
|
||||
REM 12 Feb 2040 MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 1 Feb 2041 MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 22 Jan 2042 MSG %(Chinese New Year) (%(Dog))
|
||||
REM 10 Feb 2043 MSG %(Chinese New Year) (%(Pig))
|
||||
REM 30 Jan 2044 MSG %(Chinese New Year) (%(Rat))
|
||||
REM 17 Feb 2045 MSG %(Chinese New Year) (%(Ox))
|
||||
REM 6 Feb 2046 MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 26 Jan 2047 MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 14 Feb 2048 MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 2 Feb 2049 MSG %(Chinese New Year) (%(Snake))
|
||||
REM 23 Jan 2050 MSG %(Chinese New Year) (%(Horse))
|
||||
|
||||
@@ -19,3 +19,4 @@ OMIT 24 September MSG ទិវាប្រកាសរដ្ឋធម្មន
|
||||
OMIT 15 October MSG ទិវាប្រារព្ឋពិធីគោរពព្រះវិញ្ញាណក្ខន្ឋ ព្រះករុណា ព្រះបាទសម្តេចព្រះ នរោត្តម សីហនុ ព្រះមហាវីរក្សត្រ ព្រះវររាជបិតាឯករាជ្យ បូរណភាពទឹកដី និងឯកភាពជាតិខ្មែរ ព្រះបរមរតនកោដ្ឋ
|
||||
OMIT 29 October MSG ព្រះរាជពិធីគ្រងព្រះបរមរាជសម្បត្តិ របស់ ព្រះករុណា ព្រះបាទសម្តេចព្រះបរមនាថ នរោត្តម សីហមុនី ព្រះមហាក្សត្រនៃព្រះរាជាណាចក្រកម្ពុជា
|
||||
OMIT 9 November MSG ពិធីបុណ្យឯករាជ្យជាតិ
|
||||
OMIT 29 December MSG ទិវាសន្តិភាពនៅកម្ពុជា
|
||||
|
||||
@@ -24,7 +24,6 @@ REM 3 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 4)) == 6] MSG Ind
|
||||
OMIT 4 July MSG Independence Day
|
||||
REM 5 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 4)) == 0] MSG Independence Day (observed)
|
||||
REM First Monday in September ADDOMIT SCANFROM -28 MSG Labor Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM 10 November ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 11)) == 6] MSG Veterans Day (observed)
|
||||
OMIT 11 November MSG Veterans Day
|
||||
REM 12 November ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 11)) == 0] MSG Veterans Day (observed)
|
||||
|
||||
@@ -16,4 +16,5 @@ REM 18 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 17)) == 0] MSG
|
||||
REM 15 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 16)) == 6] MSG Manu'a Islands Cession Day (observed)
|
||||
OMIT 16 July MSG Manu'a Islands Cession Day
|
||||
REM 17 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 16)) == 0] MSG Manu'a Islands Cession Day (observed)
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Second Sunday in October ADDOMIT SCANFROM -28 MSG White Sunday
|
||||
|
||||
@@ -11,3 +11,4 @@
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Third Monday in January ADDOMIT SCANFROM -28 MSG Dr. Martin Luther King Jr. / Civil Rights Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -14,3 +14,4 @@ REM 11 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 6] M
|
||||
OMIT 12 February MSG Lincoln's Birthday
|
||||
REM 13 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 0] MSG Lincoln's Birthday (observed)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Fourth Monday in April ADDOMIT SCANFROM -28 MSG State Holiday
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG State Holiday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [$TW == 4 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 2 || $Tw == 4] MSG Washington's Birthday
|
||||
|
||||
@@ -11,3 +11,4 @@
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Third Monday in January ADDOMIT SCANFROM -28 MSG Martin Luther King Jr. / Idaho Human Rights Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -14,3 +14,4 @@ REM 11 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 6] M
|
||||
OMIT 12 February MSG Lincoln's Birthday
|
||||
REM 13 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 0] MSG Lincoln's Birthday (observed)
|
||||
REM First Monday in March ADDOMIT SCANFROM -28 MSG Casimir Pulaski Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
REM Tuesday 2 May ADDOMIT SCANFROM -28 MSG Primary Election Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG Lincoln's Birthday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [$TW == 4 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 2 || $Tw == 4] MSG Washington's Birthday
|
||||
|
||||
@@ -14,3 +14,4 @@ OMIT 17 March MSG Evacuation Day
|
||||
REM 18 March ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 17)) == 0] MSG Evacuation Day (observed)
|
||||
REM 19 March ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 17)) == 6] MSG Evacuation Day (observed)
|
||||
REM Third Monday in April ADDOMIT SCANFROM -28 MSG Patriots' Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -10,4 +10,5 @@
|
||||
# If you want the national holidays as well, you must
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG American Indian Heritage Day
|
||||
|
||||
@@ -13,3 +13,4 @@
|
||||
REM 7 May ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 8)) == 6] MSG Truman Day (observed)
|
||||
OMIT 8 May MSG Truman Day
|
||||
REM 9 May ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 8)) == 0] MSG Truman Day (observed)
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
13
include/holidays/us/mt.rem
Normal file
13
include/holidays/us/mt.rem
Normal file
@@ -0,0 +1,13 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Holiday file for subdivision MT in United States
|
||||
# Derived from the Python holidays project at
|
||||
# https://github.com/vacanza/holidays
|
||||
#
|
||||
# Note that this file includes only the holidays for
|
||||
# the specific subdivision MT.
|
||||
# See important caveats in the file ../README
|
||||
#
|
||||
# If you want the national holidays as well, you must
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
@@ -14,3 +14,4 @@ REM 11 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 6] M
|
||||
OMIT 12 February MSG Lincoln's Birthday
|
||||
REM 13 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 0] MSG Lincoln's Birthday (observed)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -14,3 +14,4 @@ REM 11 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 6] M
|
||||
OMIT 12 February MSG Lincoln's Birthday
|
||||
REM 13 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 0] MSG Lincoln's Birthday (observed)
|
||||
OMIT 15 February MSG Susan B. Anthony Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
13
include/holidays/us/oh.rem
Normal file
13
include/holidays/us/oh.rem
Normal file
@@ -0,0 +1,13 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Holiday file for subdivision OH in United States
|
||||
# Derived from the Python holidays project at
|
||||
# https://github.com/vacanza/holidays
|
||||
#
|
||||
# Note that this file includes only the holidays for
|
||||
# the specific subdivision OH.
|
||||
# See important caveats in the file ../README
|
||||
#
|
||||
# If you want the national holidays as well, you must
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
@@ -10,4 +10,5 @@
|
||||
# If you want the national holidays as well, you must
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG Day After Thanksgiving
|
||||
|
||||
@@ -13,3 +13,4 @@
|
||||
REM 23 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 24)) == 6] MSG Pioneer Day (observed)
|
||||
OMIT 24 July MSG Pioneer Day
|
||||
REM 25 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 24)) == 0] MSG Pioneer Day (observed)
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -13,4 +13,5 @@
|
||||
REM 19 June ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 20)) == 6] MSG West Virginia Day (observed)
|
||||
OMIT 20 June MSG West Virginia Day
|
||||
REM 21 June ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 20)) == 0] MSG West Virginia Day (observed)
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG Day After Thanksgiving
|
||||
|
||||
@@ -16,10 +16,10 @@ if !defined("__autolang__")
|
||||
|
||||
IF autolang != ""
|
||||
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 5)) + ".rem", "r") == 0
|
||||
INCLUDE [$SysInclude]/lang/[lower(substr(autolang, 1, 5))].rem
|
||||
SYSINCLUDE lang/[lower(substr(autolang, 1, 5))].rem
|
||||
ELSE
|
||||
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 2)) + ".rem", "r") == 0
|
||||
INCLUDE [$SysInclude]/lang/[lower(substr(autolang, 1, 2))].rem
|
||||
SYSINCLUDE lang/[lower(substr(autolang, 1, 2))].rem
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the Catalan language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file was created by Eloi Torrents <eloitor@disroot.org>
|
||||
|
||||
TRANSLATE "LANGID" "ca"
|
||||
|
||||
SET $Monday "dilluns"
|
||||
SET $Tuesday "dimarts"
|
||||
SET $Wednesday "dimecres"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the Danish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Mogens Lynnerup.
|
||||
|
||||
TRANSLATE "LANGID" "da"
|
||||
|
||||
SET $Sunday "Søndag"
|
||||
SET $Monday "Mandag"
|
||||
SET $Tuesday "Tirsdag"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the German language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Wolfgang Thronicke
|
||||
|
||||
TRANSLATE "LANGID" "de"
|
||||
|
||||
# Day names
|
||||
SET $Sunday "Sonntag"
|
||||
SET $Monday "Montag"
|
||||
@@ -64,28 +66,35 @@ FSET subst_p(alt, d, t) iif(d == today()+1, "", "en")
|
||||
|
||||
# Localization of various astronomical events
|
||||
|
||||
# Perihelion
|
||||
SET earthseasons_Perihelion_str "Perihel"
|
||||
TRANSLATE "Perihelion" "Perihel"
|
||||
TRANSLATE "Vernal Equinox" "Frühlingsanfang"
|
||||
TRANSLATE "Summer Solstice" "Sommeranfang"
|
||||
TRANSLATE "Aphelion" "Aphel"
|
||||
TRANSLATE "Autumnal Equinox" "Herbstanfang"
|
||||
TRANSLATE "Winter Solstice" "Winteranfang"
|
||||
TRANSLATE "Daylight Saving Time Starts" "Beginn Sommerzeit"
|
||||
TRANSLATE "Daylight Saving Time Ends" "Ende Sommerzeit"
|
||||
|
||||
# Vernal equinox
|
||||
SET earthseasons_EquinoxMar_str "Frühlingsanfang"
|
||||
TRANSLATE "New Moon" "Neumond"
|
||||
TRANSLATE "First Quarter" "zunehmender Halbmond"
|
||||
TRANSLATE "Full Moon" "Vollmond"
|
||||
TRANSLATE "Last Quarter" "abnehmender Halbmond"
|
||||
|
||||
# Summer solstice
|
||||
SET earthseasons_SolsticeJun_str "Sommeranfang"
|
||||
TRANSLATE "Chinese New Year" "Chinesisches Neujahr"
|
||||
TRANSLATE "Snake" "Schlange"
|
||||
TRANSLATE "Horse" "Pferd"
|
||||
TRANSLATE "Goat" "Ziege"
|
||||
TRANSLATE "Monkey" "Affe"
|
||||
TRANSLATE "Rooster" "Hahn"
|
||||
TRANSLATE "Dog" "Hund"
|
||||
TRANSLATE "Pig" "Schwein"
|
||||
TRANSLATE "Rat" "Ratte"
|
||||
TRANSLATE "Ox" "Ochse"
|
||||
TRANSLATE "Tiger" "Tiger"
|
||||
TRANSLATE "Rabbit" "Kaninchen"
|
||||
TRANSLATE "Dragon" "Drachen"
|
||||
|
||||
# Aphelion
|
||||
SET earthseasons_Aphelion_str "Aphel"
|
||||
TRANSLATE "Sunrise" "Sonnenaufgang"
|
||||
TRANSLATE "Sunset" "Sonnenuntergang"
|
||||
|
||||
# Autumnal Equinox
|
||||
SET earthseasons_EquinoxSep_str "Herbstanfang"
|
||||
|
||||
# Winter Solstice
|
||||
SET earthseasons_SolsticeDec_str "Winteranfang"
|
||||
|
||||
# Daylight saving time starts
|
||||
SET daylightST_starts_str "Beginn Sommerzeit"
|
||||
|
||||
# Daylight saving time ends
|
||||
SET daylightST_ends_str "Ende Sommerzeit"
|
||||
|
||||
PRESERVE earthseasons_Perihelion_str earthseasons_EquinoxMar_str earthseasons_SolsticeJun_str earthseasons_Aphelion_str earthseasons_EquinoxSep_str earthseasons_SolsticeDec_str daylightST_starts_str daylightST_ends_str
|
||||
TRANSLATE "No reminders." "Keine Termine."
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Support for the English language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# Nothing to do for English since it is the default.
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the Spanish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Rafa Couto <rafacouto@biogate.com>
|
||||
|
||||
TRANSLATE "LANGID" "es"
|
||||
|
||||
SET $Sunday "Domingo"
|
||||
SET $Monday "Lunes"
|
||||
SET $Tuesday "Martes"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the Finnish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Mikko Silvonen
|
||||
|
||||
TRANSLATE "LANGID" "fi"
|
||||
|
||||
SET $Sunday "sunnuntai"
|
||||
SET $Monday "maanantai"
|
||||
SET $Tuesday "tiistai"
|
||||
@@ -92,3 +94,103 @@ FSET subst_hour_past(h) iif(h==0, "", h + " " + $Hour + iif(h==1, " ", $Hplu + "
|
||||
FSET subst_min_past(m) iif(m==0, "", m + " " + $Minute + iif(m==1, " ", $Mplu + " "))
|
||||
FSET subst_hour_future(h) iif(h==0, "", h + " tunnin ")
|
||||
FSET subst_min_future(m) iif(m==0, "", m + " minuutin ")
|
||||
|
||||
TRANSLATE "Missing ']'" "Puuttuva ']'"
|
||||
TRANSLATE "Missing quote" "Puuttuva lainausmerkki"
|
||||
TRANSLATE "Expression too complex" "Liian monimutkainen lauseke"
|
||||
TRANSLATE "Missing ')'" "Puuttuva ')'"
|
||||
TRANSLATE "Undefined function" "Määrittelemätön funktio"
|
||||
TRANSLATE "Illegal character" "Virheellinen merkki"
|
||||
TRANSLATE "Expecting binary operator" "Kaksipaikkainen operaattori puuttuu"
|
||||
TRANSLATE "Out of memory" "Muisti loppui"
|
||||
TRANSLATE "Ill-formed number" "Virheellinen luku"
|
||||
TRANSLATE "Can't coerce" "Tyyppimuunnos ei onnistu"
|
||||
TRANSLATE "Type mismatch" "Virheellinen tyyppi"
|
||||
TRANSLATE "Date overflow" "Liian suuri päiväys"
|
||||
TRANSLATE "Division by zero" "Jako nollalla"
|
||||
TRANSLATE "Undefined variable" "Määrittelemätön funktio"
|
||||
TRANSLATE "Unexpected end of line" "Odottamaton rivin loppu"
|
||||
TRANSLATE "Unexpected end of file" "Odottamaton tiedoston loppu"
|
||||
TRANSLATE "I/O error" "Syöttö- tai tulostusvirhe"
|
||||
TRANSLATE "Internal error" "Sisäinen virhe"
|
||||
TRANSLATE "Bad date specification" "Virheellinen päiväys"
|
||||
TRANSLATE "Not enough arguments" "Liian vähän argumentteja"
|
||||
TRANSLATE "Too many arguments" "Liian paljon argumentteja"
|
||||
TRANSLATE "Ill-formed time" "Virheellinen aika"
|
||||
TRANSLATE "Number too high" "Liian suuri luku"
|
||||
TRANSLATE "Number too low" "Liian pieni luku"
|
||||
TRANSLATE "Can't open file" "Tiedoston avaus ei onnistu"
|
||||
TRANSLATE "INCLUDE nested too deeply (max. 9)" "Liian monta sisäkkäistä INCLUDEa"
|
||||
TRANSLATE "Parse error" "Jäsennysvirhe"
|
||||
TRANSLATE "Can't compute trigger" "Laukaisuhetken laskenta ei onnistu"
|
||||
TRANSLATE "Too many nested IFs" "Liian monta sisäkkäistä IF-lausetta"
|
||||
TRANSLATE "ELSE with no matching IF" "ELSE ilman IF-lausetta"
|
||||
TRANSLATE "ENDIF with no matching IF" "ENDIF ilman IF-lausetta"
|
||||
TRANSLATE "Can't OMIT every weekday" "Kaikkia viikonpäiviä ei voi jättää pois"
|
||||
TRANSLATE "Extraneous token(s) on line" "Ylimääräisiä merkkejä rivillä"
|
||||
TRANSLATE "POP-OMIT-CONTEXT without matching PUSH-OMIT-CONTEXT" "POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia"
|
||||
TRANSLATE "RUN disabled" "RUN-lauseen käyttö estetty"
|
||||
TRANSLATE "Domain error" "Arvoaluevirhe"
|
||||
TRANSLATE "Invalid identifier" "Virheellinen tunniste"
|
||||
TRANSLATE "Too many recursive function calls" "Liian monta rekursiivista toimintopuhelua"
|
||||
TRANSLATE "Cannot modify system variable" "Järjestelmämuuttujan muuttaminen ei onnistu"
|
||||
TRANSLATE "C library function can't represent date/time" "C-kirjastofunktio ei pysty esittämään päiväystä tai aikaa"
|
||||
TRANSLATE "Attempt to redefine built-in function" "Sisäisen funktion määritelmää yritettiin muuttaa"
|
||||
TRANSLATE "Can't nest function definition in expression" "Lausekkeessa ei voi olla sisäkkäisiä funktiomääritelmiä"
|
||||
TRANSLATE "Must fully specify date to use repeat factor" "Päiväyksen täytyy olla täydellinen toistokertoimessa"
|
||||
TRANSLATE "Year specified twice" "Vuosi annettu kahdesti"
|
||||
TRANSLATE "Month specified twice" "Kuukausi annettu kahdesti"
|
||||
TRANSLATE "Day specified twice" "Päivä annettu kahdesti"
|
||||
TRANSLATE "Unknown token" "Tuntematon sana tai merkki"
|
||||
TRANSLATE "Must specify month in OMIT command" "OMIT-komennossa on annettava kuukausi"
|
||||
TRANSLATE "Too many full OMITs (max. 1000)" "Liian monta täydellistä OMIT-komentoa"
|
||||
TRANSLATE "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT" "Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia"
|
||||
TRANSLATE "Error reading" "Virhe tiedoston luvussa"
|
||||
TRANSLATE "Expecting end-of-line" "Pilkku puuttuu"
|
||||
TRANSLATE "Invalid Hebrew date" "Virheellinen juutalainen päiväys"
|
||||
TRANSLATE "iif(): odd number of arguments required" "IIF vaatii parittoman määrän argumentteja"
|
||||
TRANSLATE "Warning: Missing ENDIF" "Varoitus: puuttuva ENDIF"
|
||||
TRANSLATE "Expecting comma" "Pilkku puuttuu"
|
||||
TRANSLATE "Weekday specified twice" "Viikonpäivä annettu kahdesti"
|
||||
TRANSLATE "Only use one of BEFORE, AFTER or SKIP" "Käytä vain yhtä komennoista BEFORE, AFTER ja SKIP"
|
||||
TRANSLATE "Can't nest MSG, MSF, RUN, etc. in expression" "Sisäkkäisiä MSG-, MSF- ja RUN-lauseita ei voi käyttää lausekkeessa"
|
||||
TRANSLATE "Repeat value specified twice" "Toistokerroin annettu kahdesti"
|
||||
TRANSLATE "Delta value specified twice" "Delta-arvo annettu kahdesti"
|
||||
TRANSLATE "Back value specified twice" "Peruutusarvo annettu kahdesti"
|
||||
TRANSLATE "ONCE keyword used twice. (Hah.)" "ONCE-avainsanaa käytetty kahdesti. (Hah.)"
|
||||
TRANSLATE "Expecting time after AT" "AT-sanan perästä puuttuu aika"
|
||||
TRANSLATE "THROUGH/UNTIL keyword used twice" "THROUGH/UNTIL-sanaa käytetty kahdesti"
|
||||
TRANSLATE "Incomplete date specification" "Epätäydellinen päiväys"
|
||||
TRANSLATE "FROM/SCANFROM keyword used twice" "FROM/SCANFROM-sanaa käytetty kahdesti"
|
||||
TRANSLATE "Variable" "Muuttuja"
|
||||
TRANSLATE "Value" "Arvo"
|
||||
TRANSLATE "*UNDEFINED*" "*MÄÄRITTELEMÄTÖN*"
|
||||
TRANSLATE "Entering UserFN" "Siirrytään funktioon"
|
||||
TRANSLATE "Leaving UserFN" "Poistutaan funktiosta"
|
||||
TRANSLATE "Expired" "Vanhentunut"
|
||||
TRANSLATE "fork() failed - can't do queued reminders" "fork() epäonnistui - jonomuistutukset eivät toimi"
|
||||
TRANSLATE "Can't access file" "Tiedoston avaus ei onnistu"
|
||||
TRANSLATE "Illegal system date: Year is less than %d\n" "Virheellinen järjestelmäpäiväys: vuosi on vähemmän kuin %d\n"
|
||||
TRANSLATE "Unknown debug flag '%c'\n" "Tuntematon virheenetsintätarkenne '%c'\n"
|
||||
TRANSLATE "Unknown option '%c'\n" "Tuntematon tarkenne '%c'\n"
|
||||
TRANSLATE "Unknown user '%s'\n" "Tuntematon käyttäjä '%s'\n"
|
||||
TRANSLATE "Could not change gid to %d\n" "Ryhmänumeron vaihto %d:ksi ei onnistunut\n"
|
||||
TRANSLATE "Could not change uid to %d\n" "Käyttäjänumeron vaihto %d:ksi ei onnistunut\n"
|
||||
TRANSLATE "Out of memory for environment\n" "Muisti ei riitä ympäristölle\n"
|
||||
TRANSLATE "Missing '=' sign" "Puuttuva '='-merkki"
|
||||
TRANSLATE "Missing variable name" "Puuttuva muuttujanimi"
|
||||
TRANSLATE "Missing expression" "Puuttuva lauseke"
|
||||
TRANSLATE "Remind: '-i' option: %s\n" "Remind: tarkenne '-i': %s\n"
|
||||
TRANSLATE "No reminders." "Ei viestejä."
|
||||
TRANSLATE "%d reminder(s) queued for later today.\n" "%d viesti(ä) tämän päivän jonossa.\n"
|
||||
TRANSLATE "Expecting number" "Numero puuttuu"
|
||||
TRANSLATE "Undefined WARN function" "Virheellinen funktio WARN-lausekkeessa"
|
||||
TRANSLATE "Can't convert between time zones" "Aikavyöhykkeiden välillä ei voi muuntaa"
|
||||
TRANSLATE "No files matching *.rem" "Ei tiedostoja, jotka vastaavat *.rem"
|
||||
TRANSLATE "String too long" "Merkkijono liian kauan"
|
||||
TRANSLATE "Time specified twice" "Aika määritetty kahdesti"
|
||||
TRANSLATE "Cannot specify DURATION without specifying AT" "Ei voi määrittää DURATION määrittelemättä AT"
|
||||
TRANSLATE "Expecting weekday name" "Odotettu viikonpäivän nimi"
|
||||
TRANSLATE "Duplicate argument name" "Päällekkäinen argumentin nimi"
|
||||
TRANSLATE "Expression evaluation is disabled" "Lausekkeiden arviointi on poistettu käytöstä"
|
||||
TRANSLATE "Time limit for expression evaluation exceeded" "Ilmaisun arvioinnin aikaraja ylitti"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the French language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Laurent Duperval
|
||||
|
||||
TRANSLATE "LANGID" "fr"
|
||||
|
||||
SET $Sunday "dimanche"
|
||||
SET $Monday "lundi"
|
||||
SET $Tuesday "mardi"
|
||||
@@ -60,3 +62,101 @@ FSET subst_jx(alt, date, time) iif(alt, subst_j_alt(date), $On + " " + subst_j_a
|
||||
|
||||
FSET subst_k_alt(date) wkday(date) + ", " + day(date) + subst_ordinal(day(date)) + " " + mon(date)
|
||||
FSET subst_kx(alt, date, time) iif(alt, subst_k_alt(date), $On + " " + subst_k_alt(date))
|
||||
|
||||
TRANSLATE "Missing ']'" "']' manquant"
|
||||
TRANSLATE "Missing quote" "Apostrophe manquant"
|
||||
TRANSLATE "Expression too complex" "Expression trop complexe"
|
||||
TRANSLATE "Missing ')'" "')' manquante"
|
||||
TRANSLATE "Undefined function" "Fonction non-définie"
|
||||
TRANSLATE "Illegal character" "Caractère illégal"
|
||||
TRANSLATE "Expecting binary operator" "Opérateur binaire attendu"
|
||||
TRANSLATE "Out of memory" "Manque de mémoire"
|
||||
TRANSLATE "Ill-formed number" "Nombre mal formé"
|
||||
TRANSLATE "Can't coerce" "Impossible de convertir"
|
||||
TRANSLATE "Type mismatch" "Types non-équivalents"
|
||||
TRANSLATE "Date overflow" "Débordement de date"
|
||||
TRANSLATE "Division by zero" "Division par zéro"
|
||||
TRANSLATE "Undefined variable" "Variable non définie"
|
||||
TRANSLATE "Unexpected end of line" "Fin de ligne non attendue"
|
||||
TRANSLATE "Unexpected end of file" "Fin de fichier non attendue"
|
||||
TRANSLATE "I/O error" "Erreur I/O"
|
||||
TRANSLATE "Internal error" "Erreur interne"
|
||||
TRANSLATE "Bad date specification" "Mauvaise date spécifiée"
|
||||
TRANSLATE "Not enough arguments" "Pas assez d'arguments"
|
||||
TRANSLATE "Too many arguments" "Trop d'arguments"
|
||||
TRANSLATE "Ill-formed time" "Heure mal formée"
|
||||
TRANSLATE "Number too high" "Nombre trop élevé"
|
||||
TRANSLATE "Number too low" "Nombre trop bas"
|
||||
TRANSLATE "Can't open file" "Impossible d'ouvrir le fichier"
|
||||
TRANSLATE "INCLUDE nested too deeply (max. 9)" "Trop d'INCLUDE imbriqués"
|
||||
TRANSLATE "Parse error" "Erreur d'analyse"
|
||||
TRANSLATE "Can't compute trigger" "Impossible de calculer le déclenchement"
|
||||
TRANSLATE "Too many nested IFs" "Trop de IF imbriqués"
|
||||
TRANSLATE "ELSE with no matching IF" "ELSE sans IF correspondant"
|
||||
TRANSLATE "ENDIF with no matching IF" "ENDIF sans IF correspondant"
|
||||
TRANSLATE "Can't OMIT every weekday" "Impossible d'omettre (OMIT) tous les jours"
|
||||
TRANSLATE "Extraneous token(s) on line" "Elément(s) étranger(s) sur la ligne"
|
||||
TRANSLATE "POP-OMIT-CONTEXT without matching PUSH-OMIT-CONTEXT" "POP-OMIT-CONTEXT sans PUSH-OMIT-CONTEXT correspondant"
|
||||
TRANSLATE "RUN disabled" "RUN déactivé"
|
||||
TRANSLATE "Domain error" "Erreur de domaine"
|
||||
TRANSLATE "Invalid identifier" "Identificateur invalide"
|
||||
TRANSLATE "Too many recursive function calls" "Trop d'appels de fonctions récursives"
|
||||
TRANSLATE "Cannot modify system variable" "Impossible de modifier une variable système"
|
||||
TRANSLATE "C library function can't represent date/time" "Fonction de la librairie C ne peut représenter la date/l'heure"
|
||||
TRANSLATE "Attempt to redefine built-in function" "Tentative de redéfinition d'une fonction intrinsèque"
|
||||
TRANSLATE "Can't nest function definition in expression" "Impossible d'imbriquer une définition de fonction dans une expression"
|
||||
TRANSLATE "Must fully specify date to use repeat factor" "Pour utiliser le facteur de répétition la date doit être spécifiée au complet"
|
||||
TRANSLATE "Year specified twice" "Année spécifiée deux fois"
|
||||
TRANSLATE "Month specified twice" "Mois spécifié deux fois"
|
||||
TRANSLATE "Day specified twice" "Jour spécifié deux fois"
|
||||
TRANSLATE "Unknown token" "Elément inconnu"
|
||||
TRANSLATE "Must specify month in OMIT command" "Mois doit être spécifiés dans commande OMIT"
|
||||
TRANSLATE "Too many full OMITs (max. 1000)" "Trop de OMITs complets"
|
||||
TRANSLATE "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT" "Attention: PUSH-OMIT-CONTEXT sans POP-OMIT-CONTEXT correspondant"
|
||||
TRANSLATE "Error reading" "Erreur à la lecture du fichier"
|
||||
TRANSLATE "Expecting end-of-line" "Fin de ligne attendue"
|
||||
TRANSLATE "Invalid Hebrew date" "Date hébreuse invalide"
|
||||
TRANSLATE "iif(): odd number of arguments required" "IIF demande nombre d'arguments impair"
|
||||
TRANSLATE "Warning: Missing ENDIF" "Attention: ENDIF manquant"
|
||||
TRANSLATE "Expecting comma" "Virgule attendue"
|
||||
TRANSLATE "Weekday specified twice" "Jour de la semaine spécifié deux fois"
|
||||
TRANSLATE "Only use one of BEFORE, AFTER or SKIP" "Utiliser un seul parmi BEFORE, AFTER ou SKIP"
|
||||
TRANSLATE "Can't nest MSG, MSF, RUN, etc. in expression" "Impossible d'imbriquer MSG, MSF, RUN, etc. dans une expression"
|
||||
TRANSLATE "Repeat value specified twice" "Valeur de répétition spécifiée deux fois"
|
||||
TRANSLATE "Delta value specified twice" "Valeur delta spécifiée deux fois"
|
||||
TRANSLATE "Back value specified twice" "Valeur de retour spécifiée deux fois"
|
||||
TRANSLATE "ONCE keyword used twice. (Hah.)" "Mot-clé ONCE utilisé deux fois. (Hah.)"
|
||||
TRANSLATE "Expecting time after AT" "Heure attendue après AT"
|
||||
TRANSLATE "THROUGH/UNTIL keyword used twice" "Mot-clé THROUGH/UNTIL utilisé deux fois"
|
||||
TRANSLATE "Incomplete date specification" "Spécification de date incomplète"
|
||||
TRANSLATE "FROM/SCANFROM keyword used twice" "Mot-clé FROM/SCANFROM utilisé deux fois"
|
||||
TRANSLATE "Variable" "Variable"
|
||||
TRANSLATE "Value" "Valeur"
|
||||
TRANSLATE "*UNDEFINED*" "*NON-DEFINI*"
|
||||
TRANSLATE "Entering UserFN" "Entrée dans UserFN"
|
||||
TRANSLATE "Leaving UserFN" "Sortie de UserFN"
|
||||
TRANSLATE "Expired" "Expiré"
|
||||
TRANSLATE "fork() failed - can't do queued reminders" "fork() échoué - impossible de faire les appels en queue"
|
||||
TRANSLATE "Can't access file" "Impossible d'accéder au fichier"
|
||||
TRANSLATE "Illegal system date: Year is less than %d\n" "Date système illégale: Année est inférieure à %d\n"
|
||||
TRANSLATE "Unknown debug flag '%c'\n" "Option de déverminage inconnue '%c'\n"
|
||||
TRANSLATE "Unknown option '%c'\n" "Option inconnue '%c'\n"
|
||||
TRANSLATE "Unknown user '%s'\n" "Usager inconnu '%s'\n"
|
||||
TRANSLATE "Could not change gid to %d\n" "Impossible de changer gid pour %d\n"
|
||||
TRANSLATE "Could not change uid to %d\n" "Impossible de changer uid pour %d\n"
|
||||
TRANSLATE "Out of memory for environment\n" "Manque de mémoire pour environnement\n"
|
||||
TRANSLATE "Missing '=' sign" "Signe '=' manquant"
|
||||
TRANSLATE "Missing variable name" "Nom de variable absent"
|
||||
TRANSLATE "Missing expression" "Expression absente"
|
||||
TRANSLATE "%d reminder(s) queued for later today.\n" "%d rappel(s) en file pour aujourd'hui.\n"
|
||||
TRANSLATE "Expecting number" "Nombre attendu"
|
||||
TRANSLATE "Undefined WARN function" "Fonction illégale après WARN"
|
||||
TRANSLATE "Can't convert between time zones" "Impossible de convertir entre les fuseaux horaires"
|
||||
TRANSLATE "No files matching *.rem" "Aucun fichier correspondant à *.rem"
|
||||
TRANSLATE "String too long" "Chaîne trop longue"
|
||||
TRANSLATE "Time specified twice" "Heure spécifiée deux fois"
|
||||
TRANSLATE "Cannot specify DURATION without specifying AT" "Impossible de spécifier DURATION sans spécifier AT"
|
||||
TRANSLATE "Expecting weekday name" "Nom du jour de la semaine attendu"
|
||||
TRANSLATE "Duplicate argument name" "Nom de l'argument en double"
|
||||
TRANSLATE "Expression evaluation is disabled" "L'évaluation de l'expression est désactivée"
|
||||
TRANSLATE "Time limit for expression evaluation exceeded" "Délai d'évaluation de l'expression dépassé"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the Hellenic (Greek) language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by jarlaxl lamat (jarlaxl@freemail.gr)
|
||||
|
||||
TRANSLATE "LANGID" "gr"
|
||||
|
||||
SET $Sunday "Κυριακή"
|
||||
SET $Monday "Δευτέρα"
|
||||
SET $Tuesday "Τρίτη"
|
||||
@@ -56,30 +58,11 @@ FSET subst_gx(alt, d, t) iif(alt, subst_g_alt(d), $On + " " + subst_g_alt(d))
|
||||
FSET subst_ux(alt, d, t) subst_ax(alt, d, t)
|
||||
FSET subst_vx(alt, d, t) subst_gx(alt, d, t)
|
||||
|
||||
# Localization of various astronomical events
|
||||
|
||||
# Perihelion
|
||||
SET earthseasons_Perihelion_str "Περιήλιον"
|
||||
|
||||
# Vernal equinox
|
||||
SET earthseasons_EquinoxMar_str "Εαρινή ισημερία"
|
||||
|
||||
# Summer solstice
|
||||
SET earthseasons_SolsticeJun_str "Θερινό ηλιοστάσιο"
|
||||
|
||||
# Aphelion
|
||||
SET earthseasons_Aphelion_str "Αφήλιον"
|
||||
|
||||
# Autumnal Equinox
|
||||
SET earthseasons_EquinoxSep_str "Φθινοπωρινή ισημερία"
|
||||
|
||||
# Winter Solstice
|
||||
SET earthseasons_SolsticeDec_str "Χειμερινό ηλιοστάσιο"
|
||||
|
||||
# Daylight saving time starts
|
||||
SET daylightST_starts_str "Έναρξη θέρους"
|
||||
|
||||
# Daylight saving time ends
|
||||
SET daylightST_ends_str "Τέλος θέρους"
|
||||
|
||||
PRESERVE earthseasons_Perihelion_str earthseasons_EquinoxMar_str earthseasons_SolsticeJun_str earthseasons_Aphelion_str earthseasons_EquinoxSep_str earthseasons_SolsticeDec_str daylightST_starts_str daylightST_ends_str
|
||||
TRANSLATE "Perihelion" "Περιήλιον"
|
||||
TRANSLATE "Vernal Equinox" "Εαρινή ισημερία"
|
||||
TRANSLATE "Summer Solstice" "Θερινό ηλιοστάσιο"
|
||||
TRANSLATE "Aphelion" "Αφήλιον"
|
||||
TRANSLATE "Autumnal Equinox" "Φθινοπωρινή ισημερία"
|
||||
TRANSLATE "Winter Solstice" "Χειμερινό ηλιοστάσιο"
|
||||
TRANSLATE "Daylight Saving Time Starts" "Έναρξη θέρους"
|
||||
TRANSLATE "Daylight Saving Time Ends" "Τέλος θέρους"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the Icelanding language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Björn Davíðsson (bjossi@snerpa.is)
|
||||
|
||||
TRANSLATE "LANGID" "is"
|
||||
|
||||
SET $Sunday "sunnudagur"
|
||||
SET $Monday "mánudagur"
|
||||
SET $Tuesday "þriðjudagur"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the Italian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Valerio Aimale
|
||||
|
||||
TRANSLATE "LANGID" "it"
|
||||
|
||||
SET $Sunday "Domenica"
|
||||
SET $Monday "Lunedì"
|
||||
SET $Tuesday "Martedì"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the Dutch language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Willem Kasdorp and Erik-Jan Vens
|
||||
|
||||
TRANSLATE "LANGID" "nl"
|
||||
|
||||
SET $Sunday "zondag"
|
||||
SET $Monday "maandag"
|
||||
SET $Tuesday "dinsdag"
|
||||
@@ -27,7 +29,7 @@ SET $December "december"
|
||||
SET $Today "vandaag"
|
||||
SET $Tomorrow "morgen"
|
||||
|
||||
BANNER Herinneringen voor %w, %d%s %m, %y%o:
|
||||
BANNER Herinneringen voor %w, %d %m, %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
SET $Pm "pm"
|
||||
@@ -54,3 +56,33 @@ FSET subst_minutes(m) iif(m==1, "1 minuut", m + " minuten")
|
||||
FSET subst_hours(h) iif(h==1, "1 uur", h + " uren")
|
||||
|
||||
FSET subst_bx(a, d, t) "over " + (d-today()) + " dagen"
|
||||
|
||||
FSET subst_s(a, d, t) iif(day(d) == 1 || day(d) == 8, "e", day(d) < 20, "de", "te")
|
||||
TRANSLATE "New Moon" "Nieuwe maan"
|
||||
TRANSLATE "First Quarter" "Eerste kwartier"
|
||||
TRANSLATE "Full Moon" "Volle maan"
|
||||
TRANSLATE "Last Quarter" "Laatste kwartier"
|
||||
|
||||
TRANSLATE "Vernal Equinox" "Lente-equinox"
|
||||
TRANSLATE "Summer Solstice" "Zomerzonnewende"
|
||||
TRANSLATE "Autumnal Equinox" "Herfst-equinox"
|
||||
TRANSLATE "Winter Solstice" "Winterzonnewende"
|
||||
|
||||
TRANSLATE "Chinese New Year" "Chinees Nieuwjaar"
|
||||
TRANSLATE "Snake" "Slang"
|
||||
TRANSLATE "Horse" "Paard"
|
||||
TRANSLATE "Goat" "Geit"
|
||||
TRANSLATE "Monkey" "Aap"
|
||||
TRANSLATE "Rooster" "Haan"
|
||||
TRANSLATE "Dog" "Hond"
|
||||
TRANSLATE "Pig" "Varken"
|
||||
TRANSLATE "Rat" "Rat"
|
||||
TRANSLATE "Ox" "Os"
|
||||
TRANSLATE "Tiger" "Tijger"
|
||||
TRANSLATE "Rabbit" "Konijn"
|
||||
TRANSLATE "Dragon" "Draak"
|
||||
|
||||
TRANSLATE "Sunrise" "Zonsopgang"
|
||||
TRANSLATE "Sunset" "Zonsondergang"
|
||||
|
||||
TRANSLATE "No reminders." "Geen herinneringen."
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the Norwegian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Trygve Randen
|
||||
|
||||
TRANSLATE "LANGID" "no"
|
||||
|
||||
SET $Sunday "Søndag"
|
||||
SET $Monday "Mandag"
|
||||
SET $Tuesday "Tirsdag"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the Polish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Jerzy Sobczyk
|
||||
|
||||
TRANSLATE "LANGID" "pl"
|
||||
|
||||
SET $Sunday "Niedziela"
|
||||
SET $Monday "Poniedziałek"
|
||||
SET $Tuesday "Wtorek"
|
||||
@@ -67,3 +69,104 @@ FSET subst_1past(diff) iif(diff/60==0, subst_1min(diff%60), diff%60==0, subst_1h
|
||||
|
||||
FSET subst_1min(m) m + " " + $Minute + subst_pl_plu(m)
|
||||
FSET subst_1h(h) h + " " + $Hour + subst_pl_plu(h)
|
||||
|
||||
TRANSLATE "Ok" "OK"
|
||||
TRANSLATE "Missing ']'" "Brakujący ']'"
|
||||
TRANSLATE "Missing quote" "Brakujący nawias"
|
||||
TRANSLATE "Expression too complex" "Zbyt skomplikowane wyrażenie"
|
||||
TRANSLATE "Missing ')'" "Brakujący ')'"
|
||||
TRANSLATE "Undefined function" "Nie zdefiniowana funkcja"
|
||||
TRANSLATE "Illegal character" "Nielegalny znak"
|
||||
TRANSLATE "Expecting binary operator" "Spodziewany operator binarny"
|
||||
TRANSLATE "Out of memory" "Brak pamięci"
|
||||
TRANSLATE "Ill-formed number" "Niepoprawny numer"
|
||||
TRANSLATE "Can't coerce" "Niemożliwa konwersja"
|
||||
TRANSLATE "Type mismatch" "Błąd typu"
|
||||
TRANSLATE "Date overflow" "Nadmiar daty"
|
||||
TRANSLATE "Division by zero" "Dzielenie przez zero"
|
||||
TRANSLATE "Undefined variable" "Niezdefiniowana zmienna"
|
||||
TRANSLATE "Unexpected end of line" "Niespodziewany koniec linii"
|
||||
TRANSLATE "Unexpected end of file" "Niespodziewany koniec pliku"
|
||||
TRANSLATE "I/O error" "Błąd wejscia/wyjscia"
|
||||
TRANSLATE "Internal error" "Błąd wewnętrzny"
|
||||
TRANSLATE "Bad date specification" "Zła specyfikacja daty"
|
||||
TRANSLATE "Not enough arguments" "Za mało argumentów"
|
||||
TRANSLATE "Too many arguments" "Za dużo argumentów"
|
||||
TRANSLATE "Ill-formed time" "Nieprawidłowy czas"
|
||||
TRANSLATE "Number too high" "Liczba za duża"
|
||||
TRANSLATE "Number too low" "Liczba za mała"
|
||||
TRANSLATE "Can't open file" "Nie mogę otworzyć pliku"
|
||||
TRANSLATE "INCLUDE nested too deeply (max. 9)" "Zbyt zagnieżdżone INCLUDE"
|
||||
TRANSLATE "Parse error" "Błąd składniowy"
|
||||
TRANSLATE "Can't compute trigger" "Nie mogę obliczyć przypomnienia"
|
||||
TRANSLATE "Too many nested IFs" "Zbyt zagnieżdżone IF"
|
||||
TRANSLATE "ELSE with no matching IF" "ELSE bez IF do pary"
|
||||
TRANSLATE "ENDIF with no matching IF" "ENDIF bez IF do pary"
|
||||
TRANSLATE "Can't OMIT every weekday" "Nie mogę ominąć (OMIT) wszystkich dni"
|
||||
TRANSLATE "Extraneous token(s) on line" "Niespodziewany wyraz w lini"
|
||||
TRANSLATE "POP-OMIT-CONTEXT without matching PUSH-OMIT-CONTEXT" "POP-OMIT-CONTEXT bez PUSH-OMIT-CONTEXT"
|
||||
TRANSLATE "RUN disabled" "Komenda RUN zablokowana"
|
||||
TRANSLATE "Domain error" "Błąd dziedziny"
|
||||
TRANSLATE "Invalid identifier" "Niepoprawny identyfikator"
|
||||
TRANSLATE "Too many recursive function calls" "Wykryto rekursywne wywołanie funkcji"
|
||||
TRANSLATE "Cannot modify system variable" "Nie mogę zmienić zmiennej systemowej"
|
||||
TRANSLATE "C library function can't represent date/time" "Funkcja biblioteki C nie może reprezentowac daty/czasu"
|
||||
TRANSLATE "Attempt to redefine built-in function" "Próba redefinicji funkcji wbudowanej"
|
||||
TRANSLATE "Can't nest function definition in expression" "Nie wolno zagnieżdżać definicji funkcji w wyrażeniu"
|
||||
TRANSLATE "Must fully specify date to use repeat factor" "Aby użyc powtórzenia trzeba w pełni wyspecyfikować datę"
|
||||
TRANSLATE "Year specified twice" "Rok podany dwókrotnie"
|
||||
TRANSLATE "Month specified twice" "Miesiąc podany dwókrotnie"
|
||||
TRANSLATE "Day specified twice" "Dzień podany dwókrotnie"
|
||||
TRANSLATE "Unknown token" "Nieznane słowo"
|
||||
TRANSLATE "Must specify month in OMIT command" "W komendzie OMIT trzeba podać miesiąc"
|
||||
TRANSLATE "Too many full OMITs (max. 1000)" "Za dużo pełnych komend OMIT"
|
||||
TRANSLATE "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT" "Ostrzeżenie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT"
|
||||
TRANSLATE "Error reading" "Błąd odczytu pliku"
|
||||
TRANSLATE "Expecting end-of-line" "Oczekiwany koniec linii"
|
||||
TRANSLATE "Invalid Hebrew date" "Błędna data hebrajska"
|
||||
TRANSLATE "iif(): odd number of arguments required" "IIF wymaga nieparzystej liczby argumentów"
|
||||
TRANSLATE "Warning: Missing ENDIF" "Ostrzeżenie: Brakujacy ENDIF"
|
||||
TRANSLATE "Expecting comma" "Oczekiwany przecinek"
|
||||
TRANSLATE "Weekday specified twice" "Dzień tygodnia podany dwókrotnie"
|
||||
TRANSLATE "Only use one of BEFORE, AFTER or SKIP" "Dozwolone tylko jedno z: BEFORE, AFTER i SKIP"
|
||||
TRANSLATE "Can't nest MSG, MSF, RUN, etc. in expression" "Nie można zagnieżdżać MSG, MSF, RUN, itp. w wyrażeniu"
|
||||
TRANSLATE "Repeat value specified twice" "Wartość powtorzenia podana dwókrotnie"
|
||||
TRANSLATE "Delta value specified twice" "Wartość różnicy podana dwókrotnie"
|
||||
TRANSLATE "Back value specified twice" "Wartość cofnięcia podana dwókrotnie"
|
||||
TRANSLATE "ONCE keyword used twice. (Hah.)" "Słowo ONCE użyte dwókrotnie."
|
||||
TRANSLATE "Expecting time after AT" "Po AT oczekiwany jest czas"
|
||||
TRANSLATE "THROUGH/UNTIL keyword used twice" "Słowo THROUGH/UNTIL użyte dwókrotnie"
|
||||
TRANSLATE "Incomplete date specification" "Niekompletna specyfikacja daty"
|
||||
TRANSLATE "FROM/SCANFROM keyword used twice" "Słowo FROM/SCANFROM użyte dwókrotnie"
|
||||
TRANSLATE "Variable" "Zmienna"
|
||||
TRANSLATE "Value" "Wartość"
|
||||
TRANSLATE "*UNDEFINED*" "*NIE ZDEFINIOWANE*"
|
||||
TRANSLATE "Entering UserFN" "Początek UserFN"
|
||||
TRANSLATE "Leaving UserFN" "Koniec UserFN"
|
||||
TRANSLATE "Expired" "Przemineło"
|
||||
TRANSLATE "fork() failed - can't do queued reminders" "Niepowodzenie w funkcji fork() - nie mogę kolejkować przypomnień"
|
||||
TRANSLATE "Can't access file" "Nie ma dostępu do pliku"
|
||||
TRANSLATE "Illegal system date: Year is less than %d\n" "Błędna data systemowa: Rok mniejszy niż %d\n"
|
||||
TRANSLATE "Unknown debug flag '%c'\n" "Nieznana flaga odpluskwiania '%c'\n"
|
||||
TRANSLATE "Unknown option '%c'\n" "Nieznana opcja '%c'\n"
|
||||
TRANSLATE "Unknown user '%s'\n" "Nieznany użytkownik '%s'\n"
|
||||
TRANSLATE "Could not change gid to %d\n" "Nie mogę zmienić gid na %d\n"
|
||||
TRANSLATE "Could not change uid to %d\n" "Nie mogę zmienić uid na %d\n"
|
||||
TRANSLATE "Out of memory for environment\n" "Brak pamięci na zmienne środowiska\n"
|
||||
TRANSLATE "Missing '=' sign" "Brak znaku '='"
|
||||
TRANSLATE "Missing variable name" "Brak nazwy zmiennej"
|
||||
TRANSLATE "Missing expression" "Brak wyrażenia"
|
||||
TRANSLATE "Remind: '-i' option: %s\n" "Remind: '-i' option: %s\n"
|
||||
TRANSLATE "No reminders." "Brak przypomnień."
|
||||
TRANSLATE "%d reminder(s) queued for later today.\n" "%d Przypomnienia zakolejkowane na później.\n"
|
||||
TRANSLATE "Expecting number" "Spodziewana liczba"
|
||||
TRANSLATE "Undefined WARN function" "Nielegalna funkcja w klauzuli WARN:"
|
||||
TRANSLATE "Can't convert between time zones" "Nie można konwertować między strefami czasowymi"
|
||||
TRANSLATE "No files matching *.rem" "Brak dopasowania plików *.rem"
|
||||
TRANSLATE "String too long" "Ciąg za długo:"
|
||||
TRANSLATE "Time specified twice" "Czas określony dwukrotnie:"
|
||||
TRANSLATE "Cannot specify DURATION without specifying AT" "Nie można określić DURATION bez AT"
|
||||
TRANSLATE "Expecting weekday name" "Oczekiwana nazwa dnia tygodnia"
|
||||
TRANSLATE "Duplicate argument name" "Zduplikowana nazwa argumentu"
|
||||
TRANSLATE "Expression evaluation is disabled" "Ocena wyrażeń jest wyłączona"
|
||||
TRANSLATE "Time limit for expression evaluation exceeded" "Przekroczono limit czasu na ocenę wyrażenia"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the (Brazilian) Portuguese language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Marco Paganini
|
||||
|
||||
TRANSLATE "LANGID" "pt"
|
||||
|
||||
SET $Sunday "domingo"
|
||||
SET $Monday "segunda"
|
||||
SET $Tuesday "terça"
|
||||
@@ -67,3 +69,103 @@ FSET subst_1(a, d, t) iif(t==now(), $Now, t>now(), "em " + subst_1help(t-now()),
|
||||
FSET subst_1help(diff) iif(diff/60==0, subst_mplu(diff%60), diff%60==0, subst_hplu(diff/60), subst_hplu(diff/60) + " " + $And + " " + subst_mplu(diff%60))
|
||||
FSET subst_mplu(m) iif(m==1, "1 " + $Minute, m + " " + $Minute + $Mplu)
|
||||
FSET subst_hplu(h) iif(h==1, "1 " + $Hour, h + " " + $Hour + $Hplu)
|
||||
|
||||
TRANSLATE "Missing ']'" "Falta um ']'"
|
||||
TRANSLATE "Missing quote" "Falta uma aspa"
|
||||
TRANSLATE "Expression too complex" "Expressao muito complexa"
|
||||
TRANSLATE "Missing ')'" "Falta um ')'"
|
||||
TRANSLATE "Undefined function" "Funcao nao definida"
|
||||
TRANSLATE "Illegal character" "Caracter ilegal"
|
||||
TRANSLATE "Expecting binary operator" "Esperando operador binario"
|
||||
TRANSLATE "Out of memory" "Sem memoria"
|
||||
TRANSLATE "Ill-formed number" "Numero mal-formado"
|
||||
TRANSLATE "Can't coerce" "Nao consigo fazer 'coerce'"
|
||||
TRANSLATE "Type mismatch" "Type mismatch"
|
||||
TRANSLATE "Date overflow" "Overflow na data"
|
||||
TRANSLATE "Division by zero" "Divisao por zero"
|
||||
TRANSLATE "Undefined variable" "Variavel nao definida"
|
||||
TRANSLATE "Unexpected end of line" "Fim da linha nao esperado"
|
||||
TRANSLATE "Unexpected end of file" "Fim de arquivo nao esperado"
|
||||
TRANSLATE "I/O error" "Erro de I/O"
|
||||
TRANSLATE "Internal error" "Erro interno"
|
||||
TRANSLATE "Bad date specification" "Especificacao de data invalida"
|
||||
TRANSLATE "Not enough arguments" "Argumentos insuficientes"
|
||||
TRANSLATE "Too many arguments" "Argumentos em excesso"
|
||||
TRANSLATE "Ill-formed time" "Hora mal-formada"
|
||||
TRANSLATE "Number too high" "Numero muito grande"
|
||||
TRANSLATE "Number too low" "Numero muito pequeno"
|
||||
TRANSLATE "Can't open file" "Nao consigo abrir o arquivo"
|
||||
TRANSLATE "INCLUDE nested too deeply (max. 9)" "Ninho de INCLUDEs muito profundo"
|
||||
TRANSLATE "Parse error" "Erro de parsing"
|
||||
TRANSLATE "Can't compute trigger" "Nao consigo computar o 'trigger'"
|
||||
TRANSLATE "Too many nested IFs" "Muitos IFs aninhados"
|
||||
TRANSLATE "ELSE with no matching IF" "ELSE sem o IF correspondente"
|
||||
TRANSLATE "ENDIF with no matching IF" "ENDIF sem o IF correspondente"
|
||||
TRANSLATE "Can't OMIT every weekday" "Nao se pode usar OMIT para todos os dias da semana"
|
||||
TRANSLATE "Extraneous token(s) on line" "Token nao reconhecido na linha"
|
||||
TRANSLATE "POP-OMIT-CONTEXT without matching PUSH-OMIT-CONTEXT" "POP-OMIT-CONTEXT sem PUSH-OMIT-CONTEXT correspondente"
|
||||
TRANSLATE "RUN disabled" "RUN desabilitado"
|
||||
TRANSLATE "Domain error" "Erro de dominio"
|
||||
TRANSLATE "Invalid identifier" "Identificados invalido"
|
||||
TRANSLATE "Too many recursive function calls" "Muitas chamadas de função recursiva"
|
||||
TRANSLATE "Cannot modify system variable" "Nao posso modificar variavel de sistema"
|
||||
TRANSLATE "C library function can't represent date/time" "Funcao da biblioteca C nao pode representar data/hora"
|
||||
TRANSLATE "Attempt to redefine built-in function" "Tentativa de redefinir funcao interna"
|
||||
TRANSLATE "Can't nest function definition in expression" "Nao e' possivel aninhar definicao de funcao em expressao"
|
||||
TRANSLATE "Must fully specify date to use repeat factor" "Data deve ser completamente especificada para usar o fator de REPEAT"
|
||||
TRANSLATE "Year specified twice" "Ano especificado duas vezes"
|
||||
TRANSLATE "Month specified twice" "Mes especificado duas vezes"
|
||||
TRANSLATE "Day specified twice" "Dia especificado duas vezes"
|
||||
TRANSLATE "Unknown token" "Token desconhecido"
|
||||
TRANSLATE "Must specify month in OMIT command" "O mes deve ser especificados no comando OMIT"
|
||||
TRANSLATE "Too many full OMITs (max. 1000)" "Muitos OMITs full"
|
||||
TRANSLATE "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT" "Aviso: PUSH-OMIT-CONTEXT sem POP-OMIT-CONTEXT correspondente"
|
||||
TRANSLATE "Error reading" "Erro na leitura do arquivo"
|
||||
TRANSLATE "Expecting end-of-line" "Aguardando fim do arquivo"
|
||||
TRANSLATE "Invalid Hebrew date" "Data hebraica invalida"
|
||||
TRANSLATE "iif(): odd number of arguments required" "IIF necessita de numero impar de argumentos"
|
||||
TRANSLATE "Warning: Missing ENDIF" "Warning: ENDIF faltando"
|
||||
TRANSLATE "Expecting comma" "Esperando virgula"
|
||||
TRANSLATE "Weekday specified twice" "Dia da semana especificado duas vezes"
|
||||
TRANSLATE "Only use one of BEFORE, AFTER or SKIP" "Use apenas um de BEFORE, AFTER ou SKIP"
|
||||
TRANSLATE "Can't nest MSG, MSF, RUN, etc. in expression" "Nao e possivel aninhar MSG, MSF, RUN, etc. em expressoes"
|
||||
TRANSLATE "Repeat value specified twice" "Valor de Repeat especificado duas vezes"
|
||||
TRANSLATE "Delta value specified twice" "Valor de Delta especificado duas vezes"
|
||||
TRANSLATE "Back value specified twice" "Valor de Back especificado duas vezes"
|
||||
TRANSLATE "ONCE keyword used twice. (Hah.)" "ONCE usado duas vezes (Eheheh)"
|
||||
TRANSLATE "Expecting time after AT" "Esperando hora apos AT"
|
||||
TRANSLATE "THROUGH/UNTIL keyword used twice" "Keyword THROUGH/UNTIL usada duas vezes"
|
||||
TRANSLATE "Incomplete date specification" "Especificacao de data incompleta"
|
||||
TRANSLATE "FROM/SCANFROM keyword used twice" "Keyword FROM/SCANFROM usada duas vezes"
|
||||
TRANSLATE "Variable" "Variavel"
|
||||
TRANSLATE "Value" "Valor"
|
||||
TRANSLATE "*UNDEFINED*" "*INDEFINIDO*"
|
||||
TRANSLATE "Entering UserFN" "Entrando UserFN"
|
||||
TRANSLATE "Leaving UserFN" "Saindo UserFN"
|
||||
TRANSLATE "Expired" "Expirou"
|
||||
TRANSLATE "fork() failed - can't do queued reminders" "fork() falhou - Nao posso processar compromissos na fila"
|
||||
TRANSLATE "Can't access file" "Nao consigo acessar o arquivo"
|
||||
TRANSLATE "Illegal system date: Year is less than %d\n" "Data do sistema ilegal: Ano e menor que %d\n"
|
||||
TRANSLATE "Unknown debug flag '%c'\n" "Flag de debug desconhecido '%c'\n"
|
||||
TRANSLATE "Unknown option '%c'\n" "Opcao desconhecida '%c'\n"
|
||||
TRANSLATE "Unknown user '%s'\n" "Usuario desconhecido '%s'\n"
|
||||
TRANSLATE "Could not change gid to %d\n" "Nao consigo mudar gid para %d\n"
|
||||
TRANSLATE "Could not change uid to %d\n" "Nao consigo mudar uid para %d\n"
|
||||
TRANSLATE "Out of memory for environment\n" "Sem memoria para o environment\n"
|
||||
TRANSLATE "Missing '=' sign" "Falta o sinal de '='"
|
||||
TRANSLATE "Missing variable name" "Falta o nome da variavel"
|
||||
TRANSLATE "Missing expression" "Falta a expressao"
|
||||
TRANSLATE "Remind: '-i' option: %s\n" "Remind: '-i' opcao: %s\n"
|
||||
TRANSLATE "No reminders." "Sem compromissos."
|
||||
TRANSLATE "%d reminder(s) queued for later today.\n" "%d compromisso(s) colocados na fila para mais tarde.\n"
|
||||
TRANSLATE "Expecting number" "Esperando numero"
|
||||
TRANSLATE "Undefined WARN function" "Funcao ilegal na clausula WARN"
|
||||
TRANSLATE "Can't convert between time zones" "Não consigo converter entre fusos horários"
|
||||
TRANSLATE "No files matching *.rem" "Nenhum arquivo correspondente *.rem"
|
||||
TRANSLATE "String too long" "String muito longa"
|
||||
TRANSLATE "Time specified twice" "Tempo especificado duas vezes"
|
||||
TRANSLATE "Cannot specify DURATION without specifying AT" "Não é possível especificar DURATION sem especificar AT"
|
||||
TRANSLATE "Expecting weekday name" "Esperando nome do dia da semana"
|
||||
TRANSLATE "Duplicate argument name" "Nome de argumento duplicado"
|
||||
TRANSLATE "Expression evaluation is disabled" "A avaliação da expressão está desabilitada"
|
||||
TRANSLATE "Time limit for expression evaluation exceeded" "Limite de tempo para avaliação de expressão excedido"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Support for the Romanian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# REMIND is Copyright (C) 1992-2025 by Dianne Skoll
|
||||
# This file is derived from a translation by Liviu Daia
|
||||
|
||||
TRANSLATE "LANGID" "ro"
|
||||
|
||||
SET $Sunday "Duminică"
|
||||
SET $Monday "Luni"
|
||||
SET $Tuesday "Marți"
|
||||
|
||||
@@ -7,8 +7,8 @@ IF $CalMode || $PsCal
|
||||
REM [moondate(2)] SPECIAL MOON 2 -1 -1 [moontime(2)]
|
||||
REM [moondate(3)] SPECIAL MOON 3 -1 -1 [moontime(3)]
|
||||
ELSE
|
||||
REM NOQUEUE [moondatetime(0)] MSG New Moon (%2)
|
||||
REM NOQUEUE [moondatetime(1)] MSG First Quarter (%2)
|
||||
REM NOQUEUE [moondatetime(2)] MSG Full Moon (%2)
|
||||
REM NOQUEUE [moondatetime(3)] MSG Last Quarter (%2)
|
||||
REM NOQUEUE [moondatetime(0)] MSG %(New Moon) (%2)
|
||||
REM NOQUEUE [moondatetime(1)] MSG %(First Quarter) (%2)
|
||||
REM NOQUEUE [moondatetime(2)] MSG %(Full Moon) (%2)
|
||||
REM NOQUEUE [moondatetime(3)] MSG %(Last Quarter) (%2)
|
||||
ENDIF
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
|
||||
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.
|
||||
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.
|
||||
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
|
||||
|
||||
7
include/sun.rem
Normal file
7
include/sun.rem
Normal file
@@ -0,0 +1,7 @@
|
||||
# Sunrise and sunset
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
IF !$CalMode && !$PsCal
|
||||
REM NOQUEUE AT [sunrise()] MSG %"%"%(Sunrise) %! %2.
|
||||
REM NOQUEUE AT [sunset()] MSG %"%"%(Sunset) %! %2.
|
||||
ENDIF
|
||||
110
man/rem2ps.1.in
110
man/rem2ps.1.in
@@ -336,6 +336,18 @@ older format contains enough information for them to work properly.
|
||||
.PP
|
||||
\fBRemind \-p\fR sends the following lines to standard output.
|
||||
The information is designed to be easily parsed by back-end programs:
|
||||
.TP
|
||||
.B # translations
|
||||
This line signifies that the next line will be the translation table.
|
||||
The line following \fB# translations\fR is a JSON object (on a single
|
||||
line) containing all of the entries of the translation table. Back-ends that
|
||||
are not interested in the translation table can simply read and discard
|
||||
the next line.
|
||||
.RS
|
||||
If \fBRemind\fR sends data for multiple months, then only the first month
|
||||
will include the translation table.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B # rem2ps begin
|
||||
This line signifies the start of calendar data. Back-ends can search
|
||||
@@ -435,6 +447,16 @@ each reminder as a one-off event.
|
||||
.PP
|
||||
The lines emitted by \fBremind \-pp\fR are as follows:
|
||||
.TP
|
||||
.B # translations
|
||||
This line signifies that the next line will be the translation table.
|
||||
The line following \fB# translations\fR is a JSON object (on a single
|
||||
line) containing all of the entries of the translation table. Back-ends that
|
||||
are not interested in the translation table can simply read and discard
|
||||
.RS
|
||||
If \fBRemind\fR sends data for multiple months, then only the first month
|
||||
will include the translation table.
|
||||
.RE
|
||||
.TP
|
||||
.B # rem2ps2 begin
|
||||
This line signifies the start of calendar data. Back-ends can search
|
||||
for it to verify they are being fed correct information. Note the
|
||||
@@ -615,66 +637,100 @@ However, back-ends should keep reading until EOF in case more data for
|
||||
subsequent months is forthcoming.
|
||||
.PP
|
||||
|
||||
.SH REM2PS PURE JSON INPUT FORMAT (-PPP OPTION)
|
||||
\fBRemind \-ppp\fR emits \fIpure JSON\fR output. The format is
|
||||
as follows:
|
||||
.SH REM2PS PURE JSON INPUT FORMAT (-PPP OR -P+ OPTION)
|
||||
\fBRemind \-ppp\fR and \fBremind \-p+\fR emit \fIpure JSON\fR output.
|
||||
The format is as follows:
|
||||
.PP
|
||||
\fBRemind\fR outputs a JSON array. Each element of the array is a
|
||||
\fImonth descriptor\fR.
|
||||
\fImonth descriptor\fR or a \fIweek descriptor\fR in the case of
|
||||
\fBremind \-p+\fR.
|
||||
.PP
|
||||
Each month descriptor is a JSON object with the following elements:
|
||||
Each descriptor is a JSON object with the following elements:
|
||||
.TP
|
||||
.B caltype \fItype\fR
|
||||
The calendar type, either \fBmonthly\fR or \fBweekly\fR. Older versions
|
||||
of \fBRemind\fR did not include a \fBcaltype\fR element, so a missing
|
||||
\fBcaltype\fR should be treated as \fBmonthly\fR.
|
||||
.TP
|
||||
.B monthname \fIname\fR
|
||||
The name of the month.
|
||||
The name of the month. Present in monthly calendar types only.
|
||||
.TP
|
||||
.B year \fIyyyy\fR
|
||||
The year.
|
||||
The year. Present in monthly calendar types only.
|
||||
.TP
|
||||
.B daysinmonnth \fIn\fR
|
||||
The number of days in the current month.
|
||||
The number of days in the current month. Present in monthly calendar types only.
|
||||
.TP
|
||||
.B firstwkday \fIn\fR
|
||||
The weekday of the first day of the month (0 = Sunday, 1 = Monday, 6 = Saturday).
|
||||
The weekday of the first day of the month (0 = Sunday, 1 = Monday, 6 = Saturday). Present in monthly calendar types only.
|
||||
.TP
|
||||
.B mondayfirst \fIn\fR
|
||||
An indicator of whether or not the calendar week should start with
|
||||
Sunday (n=0) or Monday (n=1).
|
||||
Sunday (n=0) or Monday (n=1). Present in monthly calendar types only.
|
||||
.TP
|
||||
.B daynames \fR[\fIdays\fR]
|
||||
A seven-element array of day names; each element is a string representing
|
||||
the names of the days from Sunday through Saturday.
|
||||
the names of the days from Sunday through Saturday. Present in monthly calendar types only.
|
||||
.TP
|
||||
.B prevmonthname \fIname\fR
|
||||
The name of the previous month.
|
||||
The name of the previous month. Present in monthly calendar types only.
|
||||
.TP
|
||||
.B daysinprevmonth \fIn\fR
|
||||
The number of days in the previous month.
|
||||
The number of days in the previous month. Present in monthly calendar types only.
|
||||
.TP
|
||||
.B prevmonthyear \fIyyyy\fR
|
||||
The year of the previous month. (The same as \fByear\fR unless the current
|
||||
month is January.)
|
||||
month is January.) Present in monthly calendar types only.
|
||||
.TP
|
||||
.B nextmonthname \fIname\fR
|
||||
The name of the following month.
|
||||
The name of the following month. Present in monthly calendar types only.
|
||||
.TP
|
||||
.B daysinnextmonth \fIn\fR
|
||||
The number of days in the following month.
|
||||
The number of days in the following month. Present in monthly calendar types only.
|
||||
.TP
|
||||
.B nextmonthyear \fIyyyy\fR
|
||||
The year of the following month. (The same as \fByear\fR unless the
|
||||
current month is December.)
|
||||
current month is December.) Present in monthly calendar types only.
|
||||
.TP
|
||||
.B translations \fR{\fIobject\fR}
|
||||
A complete dump of the Remind translation table. In output for multiple
|
||||
months or weeks, the translation table is included only with the first month
|
||||
or week. Present in both weekly and monthly calendar types.
|
||||
.TP
|
||||
.B entries \fR[\fIarray\fR]
|
||||
The \fBentries\fR key consists of an array of calendar entries; each
|
||||
entry is a JSON object that has the same format as described in the
|
||||
\fBCALENDAR ENTRIES\fR section in the \fB\-PP FORMAT\fR section,
|
||||
\fIwith the following difference\fR: In \fB\-PP\fR mode, if a reminder
|
||||
has \fB%"\fR markers, only the text between the markers
|
||||
is included in the \fBbody\fR element. In \fB\-PPP\fR mode, the
|
||||
entire text \fIincluding\fR the \fB%"\fR markers is included and it's up to
|
||||
the back-end to extract the portion between the markers if that
|
||||
is desired.
|
||||
|
||||
The \fBentries\fR key, present in both weekly and monthly calendar
|
||||
types, consists of an array of calendar entries; each entry is a JSON
|
||||
object that has the same format as described in the \fBCALENDAR
|
||||
ENTRIES\fR section in the \fB\-PP FORMAT\fR section, \fIwith the
|
||||
following difference\fR: In \fB\-PP\fR mode, if a reminder has
|
||||
\fB%"\fR markers, only the text between the markers is included in the
|
||||
\fBbody\fR element. In \fB\-PPP\fR mode, the entire text
|
||||
\fIincluding\fR the \fB%"\fR markers is included and it's up to the
|
||||
back-end to extract the portion between the markers if that is
|
||||
desired.
|
||||
.TP
|
||||
.B dates \fR[\fIarray\fR]
|
||||
The \fBdates\fR key, present in weekly calendar types only,
|
||||
contains seven entries; one for each column in the weekly
|
||||
calendar. Each entry is a JSON object containing the following
|
||||
key/value pairs:
|
||||
.RS
|
||||
.TP
|
||||
.B date \fR\fIYYYY-MM-DD\fR
|
||||
The date of the column.
|
||||
.TP
|
||||
.B day \fR\fIDD\fR
|
||||
The day number of the column.
|
||||
.TP
|
||||
.B dayname \fR\fIweekday_name\fR
|
||||
The name of the weekday (possibly localized).
|
||||
.TP
|
||||
.B month \fR\fImonth_name\fR
|
||||
The name of the month (possibly localized).
|
||||
.TP
|
||||
.B year \fR\fIYYYY\fR
|
||||
The year.
|
||||
.RE
|
||||
|
||||
.SH AUTHOR
|
||||
rem2ps was written by Dianne Skoll <dianne@skoll.ca>
|
||||
|
||||
280
man/remind.1.in
280
man/remind.1.in
@@ -14,11 +14,12 @@ If \fIfilename\fR is specified as a single dash '-', then \fBRemind\fR
|
||||
takes its input from standard input.
|
||||
|
||||
.PP
|
||||
If \fIfilename\fR happens to
|
||||
be a directory rather than a plain file, then \fBRemind\fR reads all of
|
||||
the files in that directory that match the pattern "*.rem". The files
|
||||
are read in sorted order; the sort order may depend on your locale, but
|
||||
should match the sort order used by the shell to expand "*.rem".
|
||||
If \fIfilename\fR happens to be a directory rather than a plain file,
|
||||
then \fBRemind\fR reads all of the files (but not any subdirectories!)
|
||||
in that directory that match the pattern "*.rem". The files are read
|
||||
in sorted order; the sort order may depend on your locale, but should
|
||||
match the sort order used by the shell to expand "*.rem".
|
||||
|
||||
.PP
|
||||
\fBRemind\fR reads its files starting from the beginning to the end, or
|
||||
until it encounters a line whose sole content is "__EOF__" (without the quotes.)
|
||||
@@ -181,12 +182,18 @@ If you immediately follow the \fBs\fR with the letter
|
||||
day they actually occur \fIas well as\fR on any preceding days specified
|
||||
by the reminder's \fIdelta\fR.
|
||||
.TP
|
||||
.B \-p\fR[\fBa\fR][\fBp\fR][\fBp\fR][\fBq\fR]\fIn\fR
|
||||
.B \-p\fR[\fBa\fR][\fBp\fR][\fBp\fR][\fBq\fR][+]\fIn\fR
|
||||
The \fB\-p\fR option is very similar to the \fB\-s\fR option, except
|
||||
that the output contains additional information for use by the
|
||||
that the output contains additional information for use by a back-end such as the
|
||||
\fBRem2PS\fR program, which creates a PostScript calendar, and various
|
||||
other back-end programs. For this
|
||||
option, \fIn\fR cannot start with "+"; it must specify a number of months.
|
||||
other back-end programs. If \fIn\fR starts with "+", then it specifies
|
||||
a number of weeks rather than a number of months, and back-ends are expected
|
||||
to produce weekly calendars. Note that not all back-ends support
|
||||
weekly calendars; currently, only \fBrem2pdf\fR does. Specifying a weekly
|
||||
calendar implicitly enables the pure JSON interchange format, similar
|
||||
to \fB\-ppp\fR.
|
||||
.RS
|
||||
.PP
|
||||
The format of the \fB\-p\fR output is described in the \fBrem2ps(1)\fR
|
||||
man page. If you immediately follow the \fBp\fR with the letter
|
||||
\fBa\fR, then \fBRemind\fR displays reminders on the calendar on the
|
||||
@@ -199,7 +206,6 @@ three p's, as in \fB\-ppp\fR, then \fBRemind\fR uses a pure JSON
|
||||
format, again documented in \fBrem2ps(1)\fR. If you include a \fBq\fR
|
||||
letter with this option, then the normal calendar-mode substitution filter
|
||||
is disabled and the %"...%" sequences are preserved in the output.
|
||||
.RS
|
||||
.PP
|
||||
The \fB\-p\fR, \fB\-pp\fR and \fB\-ppp\fR options implicitly enable
|
||||
the \fB\-o\fR option.
|
||||
@@ -309,6 +315,9 @@ Trace the reading of reminder files
|
||||
Trace expression parsing and display the internal expression node
|
||||
tree. This is unlikely to be useful unless you are working on
|
||||
\fBRemind\fR's expression evaluation engine.
|
||||
.TP
|
||||
.B h
|
||||
Dump hash-table statistics on exit.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-g\fR[\fBa|d\fR[\fBa|d\fR[\fBa|d\fR[\fBa|d\fR]]]]
|
||||
@@ -468,6 +477,20 @@ case-sensitive:
|
||||
The \fB\-\-version\fR option causes \fBRemind\fR to print its version number
|
||||
to standard output and then exit.
|
||||
.TP
|
||||
.B \-\-print-errs
|
||||
The \fB\-\-print-errs\fR option causes \fBRemind\fR to print all possible
|
||||
error messages to standard output and then exit. The messages are printed
|
||||
in a format suitable for the first argument of a TRANSLATE command. If
|
||||
you TRANSLATE the error messages, then \fBRemind\fR will use the translated
|
||||
versions when outputting error and warning messages.
|
||||
.RS
|
||||
.PP
|
||||
Note that if an untranslated message contains printf-style formatting
|
||||
sequences like "%s" or "%d", then the translated message \fImust\fR
|
||||
contain the same sequences in the same order, or \fBRemind\fR will
|
||||
ignore it and use the original untranslated message.
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-print-config-cmd
|
||||
This option causes \fBRemind\fR to print the exact \fB./configure\fR
|
||||
command that was used when \fBRemind\fR was built. You can use this
|
||||
@@ -1195,7 +1218,7 @@ The command:
|
||||
REM ... whatever ... ADDOMIT MSG Foo
|
||||
.fi
|
||||
.PP
|
||||
is identical in behaviour to the sequence:
|
||||
is identical in behavior to the sequence:
|
||||
.PP
|
||||
.nf
|
||||
REM ... whatever ... SATISFY 1
|
||||
@@ -1597,6 +1620,10 @@ is replaced with "\fIyear\fR", the year of the trigger date.
|
||||
.B %z
|
||||
is replaced with "\fIyy\fR", the last two digits of the year.
|
||||
.TP
|
||||
.B %(\fIany_text\fR\fB)
|
||||
is replaced with the lookup of \fIany_text\fR in the translation table.
|
||||
It is the equivalent of [_("any_text")] but is more convenient to type.
|
||||
.TP
|
||||
.B %_
|
||||
(percent-underscore) is replaced with a newline. You can use this to
|
||||
achieve multi-line reminders. Note that calendar back-ends vary in
|
||||
@@ -1905,30 +1932,30 @@ the first day of the month. The local \fBOMIT\fR keyword causes the
|
||||
Finally, the \fBAFTER\fR keyword will keep moving the reminder forward
|
||||
until it has passed any holidays specified with global \fBOMIT\fR
|
||||
commands.
|
||||
.SH THE DO AND INCLUDE COMMANDS
|
||||
.SH THE DO, INCLUDE AND SYSINCLUDE COMMANDS
|
||||
.PP
|
||||
\fBRemind\fR allows you to include other files in your reminder script,
|
||||
similar to the C preprocessor #include directive. For example, your
|
||||
system administrator may maintain a file of holidays or system-wide
|
||||
reminders. You can include these in your reminder script as follows:
|
||||
similar to the C preprocessor #include directive. For example, you
|
||||
might organize different reminders into different files like this:
|
||||
.PP
|
||||
.nf
|
||||
INCLUDE /usr/share/remind/holidays
|
||||
INCLUDE /usr/share/remind/reminders
|
||||
INCLUDE holidays.rem
|
||||
INCLUDE birthdays.rem
|
||||
INCLUDE "quote files with spaces.rem"
|
||||
.fi
|
||||
.PP
|
||||
(The actual pathnames vary from system to system - ask your system
|
||||
administrator.)
|
||||
.PP
|
||||
\fBINCLUDE\fR files can be nested up to a depth of 8.
|
||||
\fBINCLUDE\fR files can be nested up to a depth of 8. As shown above, if a
|
||||
filename has spaces in it (not recommended!) you can use double-quotes
|
||||
around the filename.
|
||||
.PP
|
||||
If you specify a filename of "-" in the \fBINCLUDE\fR command, \fBRemind\fR
|
||||
will begin reading from standard input.
|
||||
.PP
|
||||
If you specify a \fIdirectory\fR as the argument to \fBINCLUDE\fR, then
|
||||
\fBRemind\fR will process all files in that directory that match the shell
|
||||
pattern "*.rem". The files are processed in sorted order; the sort order
|
||||
matches that used by the shell when it expands "*.rem".
|
||||
If you specify a \fIdirectory\fR as the argument to \fBINCLUDE\fR,
|
||||
then \fBRemind\fR will process all files (but not subdirectories!) in
|
||||
that directory that match the shell pattern "*.rem". The files are
|
||||
processed in sorted order; the sort order matches that used by the
|
||||
shell when it expands "*.rem".
|
||||
.PP
|
||||
Note that the file specified by an \fBINCLUDE\fR command is interpreted
|
||||
relative to the \fIcurrent working directory of the Remind process\fR.
|
||||
@@ -1961,6 +1988,11 @@ symbolic link itself, \fBDO\fR will fail. \fBRemind\fR does \fInot\fR
|
||||
resolve the real path of symbolic links, so you should avoid using
|
||||
symbolic links to files.
|
||||
.PP
|
||||
The \fBSYSINCLUDE\fR command is similar to \fBDO\fR, but it looks for
|
||||
relative pathnames under the system directory containing standard reminder
|
||||
scripts. For this version of \fBRemind\fR, the system directory is
|
||||
"@prefix@/share/remind".
|
||||
.PP
|
||||
.SH THE RUN COMMAND
|
||||
.PP
|
||||
If you include other files in your reminder script, you may not always
|
||||
@@ -2037,7 +2069,7 @@ Note that if RUN is disabled, then INCLUDECMD will fail with the error
|
||||
message "RUN disabled"
|
||||
.PP
|
||||
INCLUDECMD passes the rest of the line to \fBpopen\fR(3), meaning that
|
||||
the command is executed by the shell. As such, shell metacharacters
|
||||
the command is executed by the shell. As such, shell meta-characters
|
||||
may need escaping or arguments quoting, depending on what you're trying
|
||||
to do. Remind itself does not perform any modification of the command
|
||||
line (apart from the normal [expr] expression-pasting mechanism).
|
||||
@@ -2489,7 +2521,7 @@ The following system variables are defined. Those marked
|
||||
All system variables hold values of type \fBINT\fR, unless otherwise
|
||||
specified.
|
||||
.TP
|
||||
.B $AddBlankLines
|
||||
.B $AddBlankLines
|
||||
If set to 1 (the default), then \fBRemind\fR normally prints a blank
|
||||
line after the banner and each reminder. (This can be suppressed by
|
||||
ending the reminder or banner with a single percent sign.) If
|
||||
@@ -2510,12 +2542,17 @@ Universal Time Coordinated in the \fB$MinsFromUTC\fR system variable.
|
||||
.B $CalMode (read-only)
|
||||
If non-zero, then the \fB\-c\fR option was supplied on the command line.
|
||||
.TP
|
||||
.B $CalType (read-only, STRING type)
|
||||
If the \fB\-c\fR, \fB\-s\fR or \fB\-p\fR command-line options were
|
||||
used, then this variable has the value "monthly". If \fB\-c+\fR,
|
||||
\fB\-s+\fR or \fB\-p+\fR were used, then "weekly". Otherwise, "none".
|
||||
.TP
|
||||
.B $Daemon (read-only)
|
||||
If "daemon mode" \fB\-z\fR was invoked, contains the number of
|
||||
minutes between wakeups. If not running in daemon mode, contains
|
||||
0. In server mode (either \fB-z0\fR or \fB-zj\fR), contains -1.
|
||||
.TP
|
||||
.B $DateSep
|
||||
.B $DateSep (STRING type)
|
||||
This variable can be set only to "/" or "-". It holds the character
|
||||
used to separate portions of a date when \fBRemind\fR prints a DATE or
|
||||
DATETIME value.
|
||||
@@ -2570,7 +2607,7 @@ print "bar". The third will not trigger because it's a duplicate of the
|
||||
first "foo".
|
||||
.RE
|
||||
.TP
|
||||
.B $DefaultColor
|
||||
.B $DefaultColor (STRING type)
|
||||
This variable can be set to a string that has the form of three
|
||||
space-separated numbers. Each number must be an integer from 0 to
|
||||
255, or all three numbers must be -1. The default value of
|
||||
@@ -2765,7 +2802,7 @@ rules apply to \fB$Latitude\fR, \fB$LatDeg\fR, \fB$LatMin\fR and \fB$LatSec\fR.
|
||||
This variable controls how \fBRemind\fR reacts to a computer being suspended
|
||||
and then woken. Normally, if a timed reminder is queued and then the
|
||||
computer suspended, and then the computer is woken \fIafter\fR the
|
||||
timed reminder's trigger time, \fBRemind\fR will triger the timer anyway,
|
||||
timed reminder's trigger time, \fBRemind\fR will trigger the timer anyway,
|
||||
despite the fact that the trigger time has already passed.
|
||||
.RS
|
||||
.PP
|
||||
@@ -2947,7 +2984,7 @@ Equivalent to \fByear(trigdate())\fR.
|
||||
.B $Tt (read-only, TIME type)
|
||||
Equivalent to \fBtrigtime()\fR.
|
||||
.TP
|
||||
.B $TimeSep
|
||||
.B $TimeSep (STRING type)
|
||||
This variable can be set only to ":" or ".". It holds the character
|
||||
used to separate portions of a time when \fBRemind\fR prints a TIME or
|
||||
DATETIME value.
|
||||
@@ -3016,6 +3053,41 @@ an underscore and an identifier naming the argument.
|
||||
.PP
|
||||
The built-in functions are:
|
||||
.TP
|
||||
.B _(s_message)
|
||||
Returns the translation table entry for \fImessage\fR. If there is no
|
||||
such translation table entry, then returns \fImessage\fR unmodified.
|
||||
For example, consider this sequence:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
TRANSLATE "Goodbye" "Tot ziens"
|
||||
SET a _("Goodbye")
|
||||
.fi
|
||||
.PP
|
||||
After those two lines have been executed, the variable \fBa\fR will be
|
||||
set to "Tot ziens". See the section THE TRANSLATION TABLE for more
|
||||
information.
|
||||
.PP
|
||||
In the body of a reminder, the substitution sequence
|
||||
\fB%(\fItext\fR\fB)\fR is (almost) the equivalent of
|
||||
\fB[_("\fItext\fR\fB")]\fR. Therefore, the following reminders are
|
||||
almost equivalent:
|
||||
.PP
|
||||
.nf
|
||||
|
||||
REM MSG %(Goodbye)
|
||||
REM MSG [_("Goodbye")]
|
||||
.fi
|
||||
.PP
|
||||
The only difference is that if _("Goodbye") contains a \fB%\fR sign,
|
||||
then that result will be run through the substitution filter, whereas
|
||||
in the first reminder, it will not. That is because the second
|
||||
\fBREM\fR command performs expression pasting followed by a
|
||||
substitution filter pass, while the first one performs the translation
|
||||
as part of the substitution filter (and does not make a second
|
||||
substitution filter pass.)
|
||||
.RE
|
||||
.TP
|
||||
.B abs(i_num)
|
||||
Returns the absolute value of \fInum\fR.
|
||||
.TP
|
||||
@@ -3472,12 +3544,13 @@ date part is used.) Note that any local \fBOMIT\fR or \fBOMITFUNC\fR
|
||||
clauses are \fInot\fR taken into account by this function.
|
||||
.TP
|
||||
.B language()
|
||||
Returns a \fBSTRING\fR naming the language supported by \fBRemind\fR.
|
||||
(See "SUPPORT FOR OTHER LANGUAGES") By default, \fBRemind\fR is compiled
|
||||
to support English messages, so this function returns "English". For
|
||||
other languages, this function will return the English name of the
|
||||
language (e.g. "German") Note that \fBlanguage()\fR is not available
|
||||
in versions of \fBRemind\fR prior to 03.00.02.
|
||||
Returns a \fBSTRING\fR naming the compiled-in language supported by
|
||||
\fBRemind\fR. Remind used to support compiled-in support for other
|
||||
languages, but now all localization is done at run-time. As such,
|
||||
this function always returns "English". However, the expression
|
||||
\fB_("LANGID")\fR returns the two-character ISO 639 language code
|
||||
of any language pack in effect, assuming the language pack author has
|
||||
written the localization correctly!
|
||||
.TP
|
||||
.B localtoutc(q_datetime)
|
||||
Given a \fBDATETIME\fR object interpreted in the local time zone, return
|
||||
@@ -3967,7 +4040,10 @@ output is not going to a TTY.
|
||||
.TP
|
||||
.B strlen(s_str)
|
||||
Returns the length of \fIstr\fR. If the length of \fIstr\fR is too large
|
||||
to represent as an integer, emits a "Number too high" error.
|
||||
to represent as an integer, emits a "Number too high" error. Note that
|
||||
\fBstrlen\fR returns the number of \fIbytes\fR in the string, not the
|
||||
number of \fIcharacters\fR. These numbers are the same for ASCII strings,
|
||||
but may be different for UTF-8 strings.
|
||||
.TP
|
||||
.B substr(s_str, i_start [,i_end])
|
||||
Returns a \fBSTRING\fR consisting of all characters in \fIstr\fR from
|
||||
@@ -5521,22 +5597,13 @@ error messages. For an example of this, define the following:
|
||||
.PP
|
||||
.SH COMPILE-TIME SUPPORT FOR OTHER LANGUAGES
|
||||
.PP
|
||||
Your version of \fBRemind\fR may have been compiled to support a
|
||||
language other than English. This support may or may not be complete -
|
||||
for example, all error and usage messages may still be in English.
|
||||
However, at a minimum, non-English versions of \fBRemind\fR will
|
||||
output names of months and weekdays in the selected language. Also,
|
||||
the substitution mechanism will substitute constructs suitable for the
|
||||
selected language rather than for English.
|
||||
.PP
|
||||
Note that a non-English version of \fBRemind\fR will accept \fIonly\fR
|
||||
English names of weekdays and months in a reminder script.
|
||||
Remind used to support compile-time localization to other languages,
|
||||
but no longer does. All localization is now done at run-time.
|
||||
.PP
|
||||
.SH RUN-TIME SUPPORT FOR OTHER LANGUAGES
|
||||
.PP
|
||||
\fBRemind\fR has run-time support for other languages, and it is
|
||||
expected that compile-time support will be deprecated in favour of
|
||||
run-time support.
|
||||
\fBRemind\fR has run-time support for other languages, and
|
||||
compile-time support has been removed in favour of run-time support.
|
||||
.PP
|
||||
A number of system variables let you translate various phrases
|
||||
to other languages. These system variables are:
|
||||
@@ -5550,7 +5617,7 @@ day's name in your language. Strings must be valid UTF-8 strings.
|
||||
Set each of these system variables to a string representing the corresponding
|
||||
month's name in your language. Strings must be valid UTF-8 strings.
|
||||
.TP
|
||||
.B $Ago, $Am, $And, $At, $Hour, $Is, $Minute, $Now, $On, $Pm, $Was
|
||||
.B $Ago, $Am, $And, $At, $Hour, $Is, $Minute, $Now, $On, $Pm, $Today, $Tomorrow, $Was
|
||||
Set each of these system variables to the translation of the corresponding
|
||||
English word into your language. Note that \fB$Am\fR and \fB$Pm\fR should
|
||||
be the translations of "AM" and "PM" (morning and afternoon time indicators)
|
||||
@@ -5654,6 +5721,92 @@ If you use a \fB%{name}\fR sequence and the function \fBsubst_\fIname\fR is
|
||||
not defined or returns an error, then \fB%{name}\fR is replaced with the
|
||||
empty string.
|
||||
.PP
|
||||
.SH THE TRANSLATION TABLE
|
||||
.PP
|
||||
To assist with localizing reminder files, \fBRemind\fR maintains a
|
||||
table of translations. This is simple a lookup table that maps one
|
||||
string (the original string) to a new string (the translated string.)
|
||||
When \fBRemind\fR starts executing, the translation table is empty.
|
||||
.PP
|
||||
To add a message to the translation table, use the \fBTRANSLATE\fR
|
||||
command (which may be abbreviated to \fBTRANS\fR.) The \fBTRANSLATE\fR
|
||||
command must be followed by two quoted strings, separated from each
|
||||
other and from the command by whitespace. For example, a Dutch
|
||||
language file might contain something like this:
|
||||
.PP
|
||||
.nf
|
||||
TRANSLATE "New Moon" "Nieuwe maan"
|
||||
TRANSLATE "First Quarter" "Eerste kwartier"
|
||||
TRANSLATE "Full Moon" "Volle maan"
|
||||
TRANSLATE "Last Quarter" "Laatste kwartier"
|
||||
.fi
|
||||
.PP
|
||||
To actually use the translation table, make use of the \fB_\fR built-in
|
||||
function, as follows:
|
||||
.PP
|
||||
.nf
|
||||
REM NOQUEUE [moondatetime(0)] MSG [_("New Moon")] (%2)
|
||||
REM NOQUEUE [moondatetime(1)] MSG [_("First Quarter")] (%2)
|
||||
REM NOQUEUE [moondatetime(2)] MSG [_("Full Moon")] (%2)
|
||||
REM NOQUEUE [moondatetime(3)] MSG [_("Last Quarter")] (%2)
|
||||
.fi
|
||||
.PP
|
||||
By using \fBTRANSLATE\fR and \fB_\fR judiciously, you can make your
|
||||
reminder files easy to translate.
|
||||
.PP
|
||||
\fBTRANSLATE\fR has three additional forms: If it is followed
|
||||
by \fIone\fR quoted string instead of two, then \fBRemind\fR deletes the
|
||||
translation table entry for that string. If it is followed by
|
||||
the keyword \fBDUMP\fR, then \fBRemind\fR dumps all translation table entries
|
||||
to standard output. And if it is followed by \fBCLEAR\fR, then
|
||||
\fBRemind\fR deletes all of the translation table entries.
|
||||
.PP
|
||||
Note that if you \fBSET\fR various translation-related system
|
||||
variables such as \fB$Monday\fR, \fB$December\fR, \fB$Ago\fR, etc,
|
||||
then \fBRemind\fR \fIalso\fR makes a corresponding translation
|
||||
table entry automatically. This is done for all of the translation-related
|
||||
system variables \fIexcept for\fR \fB$Hplu\fR and \fB$Mplu\fR.
|
||||
.PP
|
||||
The converse applies too; creating a translation table for
|
||||
"December" automatically sets \fB$December\fR. And if you invoke
|
||||
\fBTRANSLATE CLEAR\fR, then all translation-related system variables
|
||||
are set to their default values as well.
|
||||
.PP
|
||||
The translation table always contains a special entry \fBLANGID\fR whose
|
||||
default value is \fBen\fR. Translators are encouraged to add a \fBLANGID\fR
|
||||
entry in their language files; the value should be the two-characters
|
||||
ISO 639 language code.
|
||||
.PP
|
||||
For example, if you write a translation file for the Dutch language,
|
||||
add this line:
|
||||
.PP
|
||||
.nf
|
||||
TRANSLATE "LANGID" "nl"
|
||||
.fi
|
||||
.PP
|
||||
Scripts can use \fB_("LANGID")\fR to query the translation language that is
|
||||
in effect.
|
||||
.PP
|
||||
The \fB_()\fR function uses the following procedure to obtain the translation
|
||||
for a string:
|
||||
.RS
|
||||
.TP
|
||||
1
|
||||
Look for an exact match. If found, return.
|
||||
.TP
|
||||
2
|
||||
If the original string had an upper-case letter, search for the
|
||||
all-lower-case equivalent. If found, make the first letter of the
|
||||
result upper-case and return.
|
||||
.TP
|
||||
3
|
||||
If the original string started with a lower-case letter, search
|
||||
for an equivalent whose first letter is upper-case and the rest lower-case.
|
||||
If found, make the first letter of the result lower-case and return.
|
||||
.TP
|
||||
4
|
||||
No translation was found. Return the original string.
|
||||
.RE
|
||||
.SH LANGUAGE PACKS
|
||||
.PP
|
||||
\fBRemind\fR ships with a number of language packs, which are simply reminder
|
||||
@@ -5668,14 +5821,14 @@ To use a language pack (in this example, de.rem), simply place this at
|
||||
the top of your reminders file:
|
||||
.PP
|
||||
.nf
|
||||
INCLUDE [$SysInclude]/lang/de.rem
|
||||
SYSINCLUDE lang/de.rem
|
||||
.fi
|
||||
.PP
|
||||
If you want \fBRemind\fR to try to find the language pack appropriate
|
||||
for your locale settings, use:
|
||||
.PP
|
||||
.nf
|
||||
INCLUDE [$SysInclude]/lang/auto.rem
|
||||
SYSINCLUDE lang/auto.rem
|
||||
.fi
|
||||
.PP
|
||||
You are encouraged to study the language packs to see how to translate
|
||||
@@ -6187,16 +6340,15 @@ Do not hard-code the above directory in your reminder files. Instead,
|
||||
use the value of the $SysInclude system variable.
|
||||
.SH AUTHOR
|
||||
.PP
|
||||
Dianne Skoll <dianne@skoll.ca> wrote \fBRemind\fR. The moon code
|
||||
was copied largely unmodified from "moontool" by John Walker. The
|
||||
sunrise and sunset functions use ideas from programs by Michael
|
||||
Schwartz and Marc T. Kaufman. The Hebrew calendar support was taken
|
||||
from "hdate" by Amos Shapir. OS/2 support was done by Darrel
|
||||
Hankerson, Russ Herman, and Norman Walsh. The supported
|
||||
languages and their translators are listed below. Languages marked
|
||||
"complete" support error messages and usage instructions in that
|
||||
language; all others only support the substitution filter mechanism
|
||||
and month/day names.
|
||||
Dianne Skoll <dianne@skoll.ca> wrote \fBRemind\fR. The moon code was
|
||||
copied largely unmodified from "moontool" by John Walker. The sunrise
|
||||
and sunset functions use ideas from programs by Michael Schwartz and
|
||||
Marc T. Kaufman. The Hebrew calendar support was taken from "hdate"
|
||||
by Amos Shapir. OS/2 support was done by Darrel Hankerson, Russ
|
||||
Herman, and Norman Walsh. The supported languages and their
|
||||
translators are listed below. Languages marked "complete" support
|
||||
error messages in that language; all others only support the
|
||||
substitution filter mechanism and month/day names.
|
||||
.PP
|
||||
\fBGerman\fR --
|
||||
Wolfgang Thronicke
|
||||
|
||||
@@ -413,6 +413,39 @@ like this:
|
||||
The value of the \fBqueue\fR key is an array of JSON objects, each
|
||||
representing a queued reminder.
|
||||
|
||||
.TP
|
||||
TRANSLATE Any string goes here
|
||||
Returns the translation of "Any string goes here" according to \fBRemind\fR's
|
||||
translation table. Note that there must be exactly one space after
|
||||
TRANSLATE and before the string you wish to translate. The JSON object
|
||||
that results from "TRANSLATE New Moon" might look like this:
|
||||
.nf
|
||||
|
||||
{"response":"translate","translation":{"New Moon":"Nieuwe maan"},"command":"TRANSLATE"}
|
||||
|
||||
.fi
|
||||
As you see, the value of the \fBtranslation\fR key is an object whose
|
||||
key is the original text and value is the translated text. A
|
||||
front-end can use TRANSLATE do its own localization; for example,
|
||||
TkRemind uses it to localize the moon phase popup window for the
|
||||
SPECIAL MOON display.
|
||||
.RS
|
||||
.PP
|
||||
If the argument to TRANSLATE is not in the translation table, then
|
||||
\fBRemind\fR \fIwill not issue any response at all\fR to the TRANSLATE command.
|
||||
.RE
|
||||
.TP
|
||||
TRANSLATE_DUMP
|
||||
Returns the contents of the translation table. The JSON object looks
|
||||
like this:
|
||||
.nf
|
||||
|
||||
{"response":"translate_dump","table":{...},"command":"TRANSLATE_DUMP"}
|
||||
|
||||
.fi
|
||||
The value of the \fBtable\fR key is a dictionary of original-to-translated
|
||||
strings.
|
||||
|
||||
.TP
|
||||
DEL \fIqid\fR
|
||||
Delete the reminder with queue-id \fIqid\fR from the queue.
|
||||
@@ -479,7 +512,7 @@ asynchronous status messages.
|
||||
.SH AUTHOR
|
||||
TkRemind was written by Dianne Skoll <dianne@skoll.ca>
|
||||
|
||||
\fBTkRemind\fR is Copyright 1996-2024 by Dianne Skoll.
|
||||
\fBTkRemind\fR is Copyright (C) 1996-2025 by Dianne Skoll.
|
||||
|
||||
.SH FILES
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ use Encode;
|
||||
|
||||
my %Options;
|
||||
|
||||
my $Translations = {};
|
||||
|
||||
my $rem2html_version = '@VERSION@';
|
||||
|
||||
my($days, $shades, $moons, $classes, $Month, $Year, $Numdays, $Firstwkday, $Mondayfirst, $weeks,
|
||||
@@ -18,18 +20,20 @@ my($days, $shades, $moons, $classes, $Month, $Year, $Numdays, $Firstwkday, $Mond
|
||||
my $TIDY_PROGNAME = $0;
|
||||
$TIDY_PROGNAME =~ s|^.*/||;
|
||||
|
||||
# rem2html -- convert the output of "remind -pp" to HTML
|
||||
# rem2html -- convert the output of "remind -pp" or "remind -ppp" to HTML
|
||||
|
||||
=head1 NAME
|
||||
|
||||
rem2html - Convert the output of "remind -pp" to HTML
|
||||
rem2html - Convert the output of "remind -pp" or "remind -ppp" to HTML
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
remind -ppp [remind_options] file | rem2html [options]
|
||||
|
||||
remind -pp [remind_options] file | rem2html [options]
|
||||
|
||||
You can also use the old interchange format as below, but the -pp
|
||||
version is preferred.
|
||||
or -ppp versions are preferred.
|
||||
|
||||
remind -p [remind_options] file | rem2html [options]
|
||||
|
||||
@@ -153,9 +157,10 @@ sub usage
|
||||
$exit_status = 1;
|
||||
}
|
||||
print STDERR <<"EOM";
|
||||
$TIDY_PROGNAME: Produce an HTML calendar from the output of "remind -pp"
|
||||
$TIDY_PROGNAME: Produce an HTML calendar from the output of "remind -pp[p]"
|
||||
|
||||
Usage: remind -pp [remind_options] file | rem2html [options]
|
||||
or: remind -ppp [remind_options] file | rem2html [options]
|
||||
|
||||
Options:
|
||||
|
||||
@@ -265,6 +270,31 @@ sub end_output
|
||||
print("</body>\n</html>\n");
|
||||
}
|
||||
|
||||
sub slurp_translations
|
||||
{
|
||||
my $line;
|
||||
|
||||
$line = <STDIN>;
|
||||
chomp $line;
|
||||
eval {
|
||||
if ($Options{utf8}) {
|
||||
$Translations = decode_json(encode('UTF-8', $line, Encode::FB_DEFAULT));
|
||||
} else {
|
||||
$Translations = decode_json($line);
|
||||
}
|
||||
};
|
||||
if ($@) {
|
||||
$Translations = {};
|
||||
}
|
||||
}
|
||||
|
||||
sub t
|
||||
{
|
||||
my ($str) = @_;
|
||||
return $Translations->{$str} if exists($Translations->{$str});
|
||||
return $str;
|
||||
}
|
||||
|
||||
sub parse_input
|
||||
{
|
||||
undef $days;
|
||||
@@ -275,8 +305,15 @@ sub parse_input
|
||||
|
||||
my $found_data = 0;
|
||||
while(<STDIN>) {
|
||||
chomp;
|
||||
last if /^\# rem2ps2? begin$/;
|
||||
chomp;
|
||||
if ($_ eq '[') {
|
||||
return parse_input_ppp();
|
||||
}
|
||||
if (/# translations/) {
|
||||
slurp_translations();
|
||||
next;
|
||||
}
|
||||
last if /^\# rem2ps2? begin$/;
|
||||
}
|
||||
|
||||
my $line;
|
||||
@@ -387,6 +424,159 @@ sub parse_input
|
||||
return $found_data;
|
||||
}
|
||||
|
||||
sub parse_input_ppp
|
||||
{
|
||||
my $json = "[\n";
|
||||
my $curlies = 0;
|
||||
my $did_a_calendar = 0;
|
||||
while(<STDIN>) {
|
||||
$json .= $_;
|
||||
$curlies++ if ($_ eq "{\n");
|
||||
$curlies-- if ($_ eq "}\n");
|
||||
$curlies-- if ($_ eq "},\n");
|
||||
if ($_ eq "]\n" && !$curlies) {
|
||||
my $array;
|
||||
eval {
|
||||
if ($Options{utf8}) {
|
||||
$array = decode_json(encode('UTF-8', $json, Encode::FB_DEFAULT));
|
||||
} else {
|
||||
$array = decode_json($json);
|
||||
}
|
||||
};
|
||||
if (!$array) {
|
||||
print STDERR "Could not decode JSON.\n";
|
||||
exit(1);
|
||||
}
|
||||
if (!$did_a_calendar) {
|
||||
start_output();
|
||||
$did_a_calendar = 1;
|
||||
}
|
||||
if (exists($array->[0]{caltype}) &&
|
||||
$array->[0]{caltype} eq 'weekly') {
|
||||
emit_ppp_calendars($array, 'weekly');
|
||||
} else {
|
||||
emit_ppp_calendars($array, 'monthly');
|
||||
}
|
||||
$json = '';
|
||||
}
|
||||
}
|
||||
if (!$did_a_calendar) {
|
||||
print STDERR "$TIDY_PROGNAME: Could not find any calendar data on STDIN.\n";
|
||||
exit(1);
|
||||
} else {
|
||||
end_output();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
sub emit_ppp_calendars
|
||||
{
|
||||
my ($array, $type) = @_;
|
||||
foreach my $cal (@$array) {
|
||||
emit_one_ppp_calendar($cal, $type);
|
||||
}
|
||||
}
|
||||
|
||||
sub emit_one_ppp_calendar
|
||||
{
|
||||
my ($c, $type) = @_;
|
||||
|
||||
undef $days;
|
||||
undef $shades;
|
||||
undef $moons;
|
||||
undef $classes;
|
||||
undef $weeks;
|
||||
|
||||
my $dates_to_day_index;
|
||||
my $cols_to_date_info;
|
||||
if (exists($c->{translations})) {
|
||||
$Translations = $c->{translations};
|
||||
}
|
||||
if ($type eq 'monthly') {
|
||||
$Month = $c->{monthname};
|
||||
$Year = $c->{year};
|
||||
$Numdays = $c->{daysinmonth};
|
||||
$Firstwkday = $c->{firstwkday};
|
||||
$Mondayfirst = $c->{mondayfirst};
|
||||
@Daynames = @{$c->{daynames}};
|
||||
$Prevmon = $c->{prevmonthname};
|
||||
$Prevlen = $c->{daysinprevmonth};
|
||||
$Nextmon = $c->{nextmonthname};
|
||||
$Nextlen = $c->{daysinnextmonth};
|
||||
} else {
|
||||
my $idx = 0;
|
||||
$Numdays = 7;
|
||||
foreach my $date (@{$c->{dates}}) {
|
||||
$Daynames[$idx] = $date->{dayname};
|
||||
$dates_to_day_index->{$date->{date}} = $idx;
|
||||
$cols_to_date_info->[$idx] = $date;
|
||||
$idx++;
|
||||
}
|
||||
}
|
||||
|
||||
my $class;
|
||||
if ($Options{nostyle}) {
|
||||
$class = '';
|
||||
} else {
|
||||
$class = ' class="rem-entry"';
|
||||
}
|
||||
foreach my $obj (@{$c->{entries}}) {
|
||||
next unless ($obj->{date} =~ /^(\d+)-(\d+)-(\d+)$/);
|
||||
my $y = $1;
|
||||
my $m = $2;
|
||||
my $d = $3;
|
||||
my $col;
|
||||
if ($type eq 'weekly') {
|
||||
$col = $dates_to_day_index->{$obj->{date}};
|
||||
} else {
|
||||
$col = $d;
|
||||
$col =~ s/^0+//;
|
||||
}
|
||||
my $special = $obj->{passthru} || '*';
|
||||
my $tag = $obj->{tags} || '*';
|
||||
my $duration = $obj->{duration} || '*';
|
||||
my $time = $obj->{time} || '*';
|
||||
my $body = $obj->{body};
|
||||
$special = uc($special);
|
||||
if ($special eq 'HTML') {
|
||||
push(@{$days->[$col]}, $body);
|
||||
} elsif ($special eq 'HTMLCLASS') {
|
||||
$classes->[$col] = $body;
|
||||
} elsif ($special eq 'WEEK') {
|
||||
$body =~ s/^\s+//;
|
||||
$body =~ s/\s+$//;
|
||||
$weeks->{$col} = $body;
|
||||
} elsif ($special eq 'MOON') {
|
||||
if ($body =~ /(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) {
|
||||
my ($phase, $moonsize, $fontsize, $msg) = ($1, $2, $3, $4);
|
||||
$moons->[$col]->{'phase'} = $phase;
|
||||
$moons->[$col]->{'msg'} = $msg;
|
||||
} elsif ($body =~ /(\S+)/) {
|
||||
$moons->[$col]->{'phase'} = $1;
|
||||
$moons->[$col]->{'msg'} = '';
|
||||
}
|
||||
} elsif ($special eq 'SHADE') {
|
||||
if ($body =~ /(\d+)\s+(\d+)\s+(\d+)/) {
|
||||
$shades->[$col] = sprintf("#%02X%02X%02X",
|
||||
($1 % 256), ($2 % 256), ($3 % 256));
|
||||
} elsif ($body =~ /(\d+)/) {
|
||||
$shades->[$col] = sprintf("#%02X%02X%02X",
|
||||
($1 % 256), ($1 % 256), ($1 % 256));
|
||||
}
|
||||
} elsif ($special eq 'COLOR' || $special eq 'COLOUR') {
|
||||
if ($body =~ /(\d+)\s+(\d+)\s+(\d+)\s+(.*)$/s) {
|
||||
my($r, $g, $b, $text) = ($1, $2, $3, $4);
|
||||
my $color = sprintf("style=\"color: #%02X%02X%02X;\"",
|
||||
$r % 256, $g % 256, $b % 256);
|
||||
push(@{$days->[$col]}, "<p$class $color>" . fix_whitespace(escape_html($text)) . '</p>');
|
||||
}
|
||||
} elsif ($special eq '*') {
|
||||
push(@{$days->[$col]}, "<p$class>" . fix_whitespace(escape_html($body)) . '</p>');
|
||||
}
|
||||
}
|
||||
output_calendar($type, $cols_to_date_info);
|
||||
}
|
||||
|
||||
sub fix_whitespace
|
||||
{
|
||||
my ($text) = @_;
|
||||
@@ -492,23 +682,33 @@ sub small_calendar
|
||||
sub output_calendar
|
||||
{
|
||||
# Which column is 1st of month in?
|
||||
my $first_col = $Firstwkday;
|
||||
if ($Mondayfirst) {
|
||||
$first_col--;
|
||||
if ($first_col < 0) {
|
||||
$first_col = 6;
|
||||
}
|
||||
}
|
||||
my ($type, $date_info) = @_;
|
||||
|
||||
# Last column
|
||||
my $last_col = ($first_col + $Numdays - 1) % 7;
|
||||
my ($first_col, $last_col, $number_of_rows);
|
||||
|
||||
# Figure out how many rows
|
||||
my $number_of_rows = int(($first_col + $Numdays ) / 7 + 0.999);
|
||||
if ($type eq 'monthly') {
|
||||
$first_col = $Firstwkday;
|
||||
if ($Mondayfirst) {
|
||||
$first_col--;
|
||||
if ($first_col < 0) {
|
||||
$first_col = 6;
|
||||
}
|
||||
}
|
||||
|
||||
# Add a row for small calendars if necessary
|
||||
if ($first_col == 0 && $last_col == 6) {
|
||||
# Last column
|
||||
$last_col = ($first_col + $Numdays - 1) % 7;
|
||||
|
||||
# Figure out how many rows
|
||||
$number_of_rows = int(($first_col + $Numdays ) / 7 + 0.999);
|
||||
|
||||
# Add a row for small calendars if necessary
|
||||
if ($first_col == 0 && $last_col == 6) {
|
||||
$number_of_rows++;
|
||||
}
|
||||
} else {
|
||||
$first_col = 0;
|
||||
$last_col = 6;
|
||||
$number_of_rows = 1;
|
||||
}
|
||||
|
||||
# Start the table
|
||||
@@ -519,22 +719,36 @@ sub output_calendar
|
||||
print '<tr>';
|
||||
$class = ' width="14%"';
|
||||
} else {
|
||||
print '<table class="rem-cal"><caption class="rem-cal-caption">' .
|
||||
$Month . ' ' . $Year . '</caption>' . "\n";
|
||||
if ($type eq 'monthly') {
|
||||
print '<table class="rem-cal"><caption class="rem-cal-caption">' .
|
||||
$Month . ' ' . $Year . '</caption>' . "\n";
|
||||
} else {
|
||||
print '<table class="rem-cal">' . "\n";
|
||||
}
|
||||
print '<tr class="rem-cal-hdr-row">';
|
||||
$class = ' class="rem-cal-hdr"';
|
||||
}
|
||||
if (!$Mondayfirst) {
|
||||
print "<th$class>" . $Daynames[0] . '</th>';
|
||||
if ($type eq 'monthly') {
|
||||
if (!$Mondayfirst) {
|
||||
print "<th$class>" . $Daynames[0] . '</th>';
|
||||
}
|
||||
for (my $i=1; $i<7; $i++) {
|
||||
print "<th$class>" . $Daynames[$i] . '</th>';
|
||||
}
|
||||
if ($Mondayfirst) {
|
||||
print "<th$class>" . $Daynames[0] . '</th>';
|
||||
}
|
||||
} else {
|
||||
for (my $i=0; $i<7; $i++) {
|
||||
my $inf = $date_info->[$i];
|
||||
print "<th$class>" . $inf->{dayname} . "<br>" .
|
||||
$inf->{day} . ' ' .
|
||||
$inf->{month} . ' ' .
|
||||
$inf->{year} . '</th>';
|
||||
}
|
||||
}
|
||||
for (my $i=1; $i<7; $i++) {
|
||||
print "<th$class>" . $Daynames[$i] . '</th>';
|
||||
}
|
||||
if ($Mondayfirst) {
|
||||
print "<th$class>" . $Daynames[0] . '</th>';
|
||||
}
|
||||
print "</tr>\n";
|
||||
|
||||
print "</tr>\n";
|
||||
# Start the calendar rows
|
||||
my $col = 0;
|
||||
if ($Options{nostyle}) {
|
||||
@@ -542,16 +756,18 @@ sub output_calendar
|
||||
} else {
|
||||
print "<tr class=\"rem-cal-row rem-cal-row-$number_of_rows-rows\">\n";
|
||||
}
|
||||
if ($first_col > 0) {
|
||||
small_calendar($Prevmon, $Prevlen, $Options{backurl},
|
||||
($Firstwkday - $Prevlen + 35) % 7);
|
||||
$col++;
|
||||
}
|
||||
if ($type eq 'monthly') {
|
||||
if ($first_col > 0) {
|
||||
small_calendar($Prevmon, $Prevlen, $Options{backurl},
|
||||
($Firstwkday - $Prevlen + 35) % 7);
|
||||
$col++;
|
||||
}
|
||||
|
||||
if ($last_col == 6 && $first_col > 0) {
|
||||
small_calendar($Nextmon, $Nextlen, $Options{forwurl},
|
||||
($Firstwkday + $Numdays) % 7);
|
||||
$col++;
|
||||
if ($last_col == 6 && $first_col > 0) {
|
||||
small_calendar($Nextmon, $Nextlen, $Options{forwurl},
|
||||
($Firstwkday + $Numdays) % 7);
|
||||
$col++;
|
||||
}
|
||||
}
|
||||
if ($Options{nostyle}) {
|
||||
$class = ' width="14%"';
|
||||
@@ -564,7 +780,7 @@ sub output_calendar
|
||||
}
|
||||
|
||||
for (my $day=1; $day<=$Numdays; $day++) {
|
||||
draw_day_cell($day, $number_of_rows);
|
||||
draw_day_cell($day, $number_of_rows, $type);
|
||||
$col++;
|
||||
if ($col == 7) {
|
||||
$col = 0;
|
||||
@@ -579,32 +795,33 @@ sub output_calendar
|
||||
}
|
||||
}
|
||||
|
||||
if ($col) {
|
||||
while ($col < 7) {
|
||||
if ($col == 5) {
|
||||
if ($first_col == 0) {
|
||||
small_calendar($Prevmon, $Prevlen, $Options{backurl},
|
||||
($Firstwkday - $Prevlen + 35) % 7);
|
||||
} else {
|
||||
print("<td$class> </td>\n");
|
||||
}
|
||||
} elsif ($col == 6) {
|
||||
small_calendar($Nextmon, $Nextlen, $Options{forwurl},
|
||||
($Firstwkday + $Numdays) % 7);
|
||||
} else {
|
||||
print("<td$class> </td>\n");
|
||||
}
|
||||
$col++;
|
||||
}
|
||||
print "</tr>\n";
|
||||
}
|
||||
if ($type eq 'monthly') {
|
||||
if ($col) {
|
||||
while ($col < 7) {
|
||||
if ($col == 5) {
|
||||
if ($first_col == 0) {
|
||||
small_calendar($Prevmon, $Prevlen, $Options{backurl},
|
||||
($Firstwkday - $Prevlen + 35) % 7);
|
||||
} else {
|
||||
print("<td$class> </td>\n");
|
||||
}
|
||||
} elsif ($col == 6) {
|
||||
small_calendar($Nextmon, $Nextlen, $Options{forwurl},
|
||||
($Firstwkday + $Numdays) % 7);
|
||||
} else {
|
||||
print("<td$class> </td>\n");
|
||||
}
|
||||
$col++;
|
||||
}
|
||||
print "</tr>\n";
|
||||
}
|
||||
|
||||
# Add a row for small calendars if they were not yet done!
|
||||
if ($first_col == 0 && $last_col == 6) {
|
||||
# Add a row for small calendars if they were not yet done!
|
||||
if ($first_col == 0 && $last_col == 6) {
|
||||
if ($Options{nostyle}) {
|
||||
print "<tr>\n";
|
||||
print "<tr>\n";
|
||||
} else {
|
||||
print "<tr class=\"rem-cal-row rem-cal-row-$number_of_rows-rows\">\n";
|
||||
print "<tr class=\"rem-cal-row rem-cal-row-$number_of_rows-rows\">\n";
|
||||
}
|
||||
small_calendar($Prevmon, $Prevlen, $Options{backurl},
|
||||
($Firstwkday - $Prevlen + 35) % 7);
|
||||
@@ -614,14 +831,18 @@ sub output_calendar
|
||||
small_calendar($Nextmon, $Nextlen, $Options{forwurl},
|
||||
($Firstwkday + $Numdays) % 7);
|
||||
print("</tr>\n");
|
||||
}
|
||||
}
|
||||
# End the table
|
||||
print "</table>\n";
|
||||
if ($type eq 'weekly') {
|
||||
print " <br />\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub draw_day_cell
|
||||
{
|
||||
my($day, $number_of_rows) = @_;
|
||||
my($day, $number_of_rows, $type) = @_;
|
||||
my $shade = $shades->[$day];
|
||||
my $week = '';
|
||||
if (exists($weeks->{$day})) {
|
||||
@@ -659,7 +880,7 @@ sub draw_day_cell
|
||||
} else {
|
||||
$img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAC6SURBVDiNpdNNbsIwFATgL0HKolchHKBX6yFaBOEyoPYUabvOIVKJRaCL2JX5TRNGGvnJ8ozGz89cYoElPvET+BX2yivn/1Bggw5HHMKa1h2qcPZC/JEIhvh+brIZIY6sorhMYo9hh3KGFzzfa84NZNjDt9OG/ZcH1BlaPE1IAG0+URhxzNGESKPFaHJs9Q0Ziww7HnvGeXSrJhis0jiFfjwnj3I0WRv+TKtr4hQl3lDrZ6QN9Wt654hfWfGDmBpUwDkAAAAASUVORK5CYII=';
|
||||
}
|
||||
$title = 'New Moon';
|
||||
$title = escape_html(t('New Moon'));
|
||||
$alt = 'new';
|
||||
} elsif ($phase == 1) {
|
||||
if ($Options{pngs}) {
|
||||
@@ -667,7 +888,7 @@ sub draw_day_cell
|
||||
} else {
|
||||
$img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADfSURBVDiNndM9TsNAFATgzy5yjZSAE85JBygETgENUPF3iBCitHAFQkcIhZ/Ryn9gRlrZmp2Z3ef3TBOHOMULPrDBMrhpi/4HI5xjix2+4nmJRbx/Yh7ahvkpRPVV4QDXwT3UQy46zGkAZDgK/iytefvHgCrkJsqZUH6cLnNbABSxd5Jhhf1IbkMXv8Qux7hH1Ic1xvk/jBWy6gavumvtwx7ectwZXkKh7MA95XgObeOtpI2U4zl0kGbpxgiPvwQUcXLrKFchc82f6Ur0PK49azOnmOI4TBu84zm4SV38DeIVYkrYJyNbAAAAAElFTkSuQmCC';
|
||||
}
|
||||
$title = 'First Quarter';
|
||||
$title = escape_html(t('First Quarter'));
|
||||
$alt = '1st';
|
||||
} elsif ($phase == 2) {
|
||||
if ($Options{pngs}) {
|
||||
@@ -676,7 +897,7 @@ sub draw_day_cell
|
||||
$img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADlSURBVDiNrdNBUsJAEAXQlyw4hq4hwWPqTixET6ELkZ16CcAq7oFLqXExjaYgQVNlV/Viev7/6XT/4TjGuME7PiLXUatb8N8xwB12SFjiIXIZtU/MAntEfgvQE4YtHxhiHpjXQ5H7uLhEcaLLAleBvd0Xx9Ha/BdyU+Q5OBV5OKmj7a4YBWdSyNPe4aKHAHkzqcQZNj3JgnNexqE8heyIAulffuFF3kTfIVbBVeu/xoXGGsn2TLJJ/mqkafNiINszySYZdbS90GHlvcgsWktY4TFy7ecxTdvIzahxHQLbyFXUqkPwF2ASRNYgB/PXAAAAAElFTkSuQmCC';
|
||||
}
|
||||
$alt = 'full';
|
||||
$title = 'Full Moon';
|
||||
$title = escape_html(t('Full Moon'));
|
||||
} else {
|
||||
if ($Options{pngs}) {
|
||||
$img = smoosh($Options{imgbase}, 'lastquarter.png');
|
||||
@@ -684,7 +905,7 @@ sub draw_day_cell
|
||||
$img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADmSURBVDiNndMxTsNAEIXhzy5yCyQ6FAgcE7oQheQWUAAl5BIkREoZrgB0GFNkHBl7bURGsryaee/3jHeXdpxjghU+8InXyI0S+n0MMEeBEi+4jfV3vAvMQtsyL0J0j2GtViaeRRMyj8IlsgY8BSijE2Kur/hy09wHKMJrEolhwtwHKDHOsI4OLnoAXfl1jiNsOkR9keE4P8D4q4scbzg5xIxtjie709f1E7siC+9+Gx/8fxvPKtEsklcJSBdgWhcN8ByFR5z+AWgd5QpyE+OUWOJO+zJNU+Z6jHAdgHe7K73CuD5zFT9nCmRDIssCaAAAAABJRU5ErkJggg==';
|
||||
}
|
||||
$alt = 'last';
|
||||
$title = 'Last Quarter';
|
||||
$title = escape_html(t('Last Quarter'));
|
||||
}
|
||||
if ($Options{nostyle}) {
|
||||
print("<div style=\"float: left\"><img border=\"0\" width=\"16\" height=\"16\" alt=\"$alt\" title=\"$title\" src=\"$img\">$msg</div>");
|
||||
@@ -693,11 +914,20 @@ sub draw_day_cell
|
||||
}
|
||||
}
|
||||
|
||||
if ($Options{nostyle}) {
|
||||
print "<div style=\"float: right\">$day$week</div>\n";
|
||||
print "<p> </p>\n";
|
||||
if ($type eq 'monthly') {
|
||||
if ($Options{nostyle}) {
|
||||
print "<div style=\"float: right\">$day$week</div>\n";
|
||||
print "<p> </p>\n";
|
||||
} else {
|
||||
print "<div class=\"rem-daynumber\">$day$week</div>\n";
|
||||
}
|
||||
} else {
|
||||
print "<div class=\"rem-daynumber\">$day$week</div>\n";
|
||||
if ($Options{nostyle}) {
|
||||
print "<div style=\"float: right\">$week</div>\n";
|
||||
print "<p> </p>\n";
|
||||
} else {
|
||||
print "<div class=\"rem-daynumber\">$week</div>\n";
|
||||
}
|
||||
}
|
||||
if ($days->[$day]) {
|
||||
print(join("\n", @{$days->[$day]}));
|
||||
@@ -737,7 +967,7 @@ while(1) {
|
||||
last if (!parse_input());
|
||||
start_output() unless $found_something;
|
||||
$found_something = 1;
|
||||
output_calendar();
|
||||
output_calendar('monthly', undef);
|
||||
}
|
||||
if ($found_something) {
|
||||
end_output();
|
||||
|
||||
@@ -64,6 +64,8 @@ my $settings = {
|
||||
ps => 0,
|
||||
eps => 0,
|
||||
verbose => 0,
|
||||
|
||||
weeks_per_page => 1,
|
||||
};
|
||||
|
||||
my $me = $0;
|
||||
@@ -81,17 +83,18 @@ Usage: remind -pp [options] filename | $me [options] > out.pdf
|
||||
Options:
|
||||
|
||||
--landscape, -l Print in landscape orientation
|
||||
--small-calendars=N Choose location for small calendars
|
||||
--small-calendars=N Location for small calendars (monthly calendars only)
|
||||
--svg Output SVG instead of PDF
|
||||
--ps Output PostScript instead of PDF
|
||||
--eps Output encapsulated PostScript instead of PDF
|
||||
-cN Synonym for --small-calendars=N
|
||||
--left-numbers, -x Print day numbers on the left
|
||||
--fill-page, -e Fill the entire page
|
||||
--left-numbers, -x Print day numbers on the left (monthly calendars only)
|
||||
--fill-page, -e Fill the entire page (monthly calendars only)
|
||||
--media=MEDIA, -mMEDIA Size for specified media
|
||||
--width=W, -wW Specify media width in 1/72nds of an inch
|
||||
--height=H, -hH Specify media height in 1/72nds of an inch
|
||||
--wrap, -y Make calendar fit in at most 5 rows
|
||||
--wrap, -y Make calendar fit in 5 rows (monthly calendars only)
|
||||
--weeks-per-page=N, -pN Number of weeks per page (weekly calendars only)
|
||||
--title-font=FONT Specify font for calendar title
|
||||
--header-font=FONT Specify font for weekday names
|
||||
--daynum-font=FONT Specify font for day numbers
|
||||
@@ -121,6 +124,7 @@ my $ret = GetOptions('landscape|l' => \$settings->{landscape},
|
||||
'ps' => \$settings->{ps},
|
||||
'eps' => \$settings->{eps},
|
||||
'fill-page|e' => \$settings->{fill_entire_page},
|
||||
'weeks-per-page|p=i' => \$settings->{weeks_per_page},
|
||||
'media|m=s' => \$settings->{media},
|
||||
'width|w=i' => \$settings->{width},
|
||||
'wrap|y' => \$settings->{wrap_calendar},
|
||||
@@ -153,6 +157,12 @@ if ($help) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($settings->{weeks_per_page} < 1) {
|
||||
$settings->{weeks_per_page} = 1;}
|
||||
elsif ($settings->{weeks_per_page} > 4) {
|
||||
$settings->{weeks_per_page} = 4;
|
||||
}
|
||||
|
||||
if ($settings->{width} <= 0 ||
|
||||
$settings->{height} <= 0) {
|
||||
my $size = $media_to_size->{ucfirst($settings->{media})};
|
||||
@@ -247,6 +257,7 @@ if ($settings->{ps} && $settings->{landscape}) {
|
||||
}
|
||||
|
||||
my $warned = 0;
|
||||
my $index = 0;
|
||||
while(1) {
|
||||
if ($settings->{ps}) {
|
||||
$surface->dsc_begin_page_setup();
|
||||
@@ -267,14 +278,8 @@ while(1) {
|
||||
}
|
||||
last;
|
||||
}
|
||||
if (($settings->{eps} || $settings->{svg}) && $done_one) {
|
||||
if (!$warned) {
|
||||
print STDERR "WARNING: --eps and --svg can only output one page; ignoring subsequent\nmonths in a multi-month calendar.\n";
|
||||
$warned = 1;
|
||||
}
|
||||
next;
|
||||
}
|
||||
$obj->render($cr, $settings);
|
||||
$index++;
|
||||
$obj->render($cr, $settings, $index, -1);
|
||||
$done_one = 1;
|
||||
}
|
||||
|
||||
@@ -392,7 +397,7 @@ month. Possible values for I<n> are:
|
||||
|
||||
=item Z<>0
|
||||
|
||||
Do not draw any small calendares
|
||||
Do not draw any small calendars
|
||||
|
||||
=item Z<>1
|
||||
|
||||
@@ -521,6 +526,11 @@ first row of the calendar, and adjust the small calendar positions
|
||||
as needed. This results in a calendar that only requires 5 rows, but
|
||||
with the last day or two appearing in the I<first> row.
|
||||
|
||||
=item --weeks-per-page=I<n>, -pI<n>.
|
||||
|
||||
This option is only used for weekly calendars. I<n> is the number of weeks
|
||||
to print per page; it is an integer that can range from 1 to 4.
|
||||
|
||||
=item --verbose, -v
|
||||
|
||||
Print (on STDERR) the name of the month and year for each month that
|
||||
@@ -563,6 +573,12 @@ it is syntactically correct. If you use invalid Pango markup, the
|
||||
Pango library will print a warning and B<rem2pdf> will not render any
|
||||
output for the invalid reminder.
|
||||
|
||||
=head1 WEEKLY CALENDARS
|
||||
|
||||
B<rem2pdf> will produce weekly calendars if you invoke B<remind> with the
|
||||
B<-p+> option. the B<--weeks-per-page> option specifies how many
|
||||
weeks' worth of reminders to print per page, and can range from 1 to 4.
|
||||
|
||||
=head1 ABSOLUTELY-POSITIONED TEXT
|
||||
|
||||
If your B<PANGO> special reminder starts with C<@I<x>,I<y>> where I<x>
|
||||
|
||||
@@ -62,6 +62,9 @@ sub create_from_hash
|
||||
{
|
||||
my ($class, $hash, $specials_accepted) = @_;
|
||||
|
||||
if (exists($hash->{caltype}) && ($hash->{caltype} eq 'weekly')) {
|
||||
return Remind::PDF::Weekly->create_from_hash($hash, $specials_accepted);
|
||||
}
|
||||
bless $hash, $class;
|
||||
|
||||
my $filtered_entries = [];
|
||||
@@ -463,8 +466,16 @@ C<rem2pdf> for the contents of C<$settings>
|
||||
=cut
|
||||
sub render
|
||||
{
|
||||
my ($self, $cr, $settings) = @_;
|
||||
my ($self, $cr, $settings, $index, $total) = @_;
|
||||
|
||||
if ($settings->{svg} || $settings->{eps}) {
|
||||
if ($index > 1) {
|
||||
if ($index == 2) {
|
||||
print STDERR "WARNING: --svg/--eps can only output one page; ignoring subsequent\nmonths in a multi-month calendar.\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
$self->setup_daymap($settings);
|
||||
$self->{horiz_lines} = [];
|
||||
$cr->set_line_cap('square');
|
||||
@@ -525,7 +536,7 @@ sub render
|
||||
}
|
||||
|
||||
if ($settings->{verbose}) {
|
||||
print STDERR "remdp2f: Rendered " . $self->{monthname} . ' ' . $self->{year} . "\n";
|
||||
print STDERR "rem2pdf: Rendered " . $self->{monthname} . ' ' . $self->{year} . "\n";
|
||||
}
|
||||
# Done this page
|
||||
$cr->show_page();
|
||||
@@ -1008,20 +1019,260 @@ as were read from the C<remind -ppp> stream
|
||||
sub render
|
||||
{
|
||||
my ($self, $cr, $settings) = @_;
|
||||
my $done = 0;
|
||||
my $warned = 0;
|
||||
my $index = 0;
|
||||
my $total = scalar(@{$self->{entries}});
|
||||
|
||||
foreach my $e (@{$self->{entries}}) {
|
||||
if ($settings->{svg} && $done) {
|
||||
if (!$warned) {
|
||||
print STDERR "WARNING: --svg can only output one page; ignoring subsequent\nmonths in a multi-month calendar.\n";
|
||||
$warned = 1;
|
||||
$index++;
|
||||
$e->render($cr, $settings, $index, $total);
|
||||
}
|
||||
}
|
||||
|
||||
package Remind::PDF::Weekly;
|
||||
use base qw(Remind::PDF);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Remind::PDF::Weekly - render a weekly calendar
|
||||
|
||||
=cut
|
||||
|
||||
sub render
|
||||
{
|
||||
my ($self, $cr, $settings, $index, $total) = @_;
|
||||
if ($settings->{svg} || $settings->{eps}) {
|
||||
if ($index > $settings->{weeks_per_page}) {
|
||||
if ($index == $settings->{weeks_per_page}+1) {
|
||||
print STDERR "WARNING: --svg/--eps can only output one page; ignoring subsequent pages.\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$settings->{numbers_on_left} = 1;
|
||||
# Set up bounding box
|
||||
if ($settings->{weeks_per_page} == 1) {
|
||||
$self->{bounding_box} = [
|
||||
$settings->{margin_left},
|
||||
$settings->{margin_top},
|
||||
$settings->{width} - $settings->{margin_right},
|
||||
$settings->{height} - $settings->{margin_bottom}]
|
||||
} else {
|
||||
my $total_height = $settings->{height} - $settings->{margin_top} - $settings->{margin_bottom};
|
||||
my $week_height = $total_height / $settings->{weeks_per_page};
|
||||
my $top_offset = (($index-1) % $settings->{weeks_per_page}) * $week_height;
|
||||
my $bot_offset = $top_offset + $week_height;
|
||||
$self->{bounding_box} =
|
||||
$self->{bounding_box} = [
|
||||
$settings->{margin_left},
|
||||
$settings->{margin_top} + $top_offset,
|
||||
$settings->{width} - $settings->{margin_right},
|
||||
$settings->{margin_top} + $bot_offset];
|
||||
if ($index != 1) {
|
||||
$self->{bounding_box}[1] += 0.25 * $settings->{margin_top};
|
||||
}
|
||||
if ($index != $settings->{weeks_per_page}) {
|
||||
$self->{bounding_box}[3] -= 0.25 * $settings->{margin_top};
|
||||
}
|
||||
}
|
||||
$self->draw_headings($cr, $settings);
|
||||
for (my $i=0; $i<7; $i++) {
|
||||
$self->draw_entries($cr, $settings, $i);
|
||||
}
|
||||
$self->draw_lines($cr, $settings);
|
||||
if ($index == $total || ($index % $settings->{weeks_per_page}) == 0) {
|
||||
$cr->show_page();
|
||||
}
|
||||
|
||||
if ($settings->{verbose}) {
|
||||
print STDERR "rem2pdf: Rendered " . $self->{dates}->[0]->{date} . " to " . $self->{dates}->[6]->{date} . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub draw_headings
|
||||
{
|
||||
my ($self, $cr, $settings) = @_;
|
||||
my $ymax = 0;
|
||||
my $cell = ($settings->{width} - $settings->{margin_left} - $settings->{margin_right})/7;
|
||||
|
||||
for (my $i=0; $i<7; $i++) {
|
||||
my $date = $self->{dates}[$i];
|
||||
my $month = $date->{month};
|
||||
my $year = $date->{year};
|
||||
my $day = $date->{day};
|
||||
my $dayname = $date->{dayname};
|
||||
|
||||
my $layout = Pango::Cairo::create_layout($cr);
|
||||
$layout->set_text(Encode::decode('UTF-8', $dayname));
|
||||
|
||||
my $desc = Pango::FontDescription->from_string($settings->{header_font} . ' ' . $settings->{header_size} . 'px');
|
||||
$layout->set_font_description($desc);
|
||||
|
||||
my ($wid, $h) = $layout->get_pixel_size();
|
||||
$cr->save;
|
||||
$cr->move_to($settings->{margin_left} + $i * $cell + $cell/2 - $wid/2, $self->{bounding_box}[1]);
|
||||
Pango::Cairo::show_layout($cr, $layout);
|
||||
$cr->restore();
|
||||
|
||||
$layout = Pango::Cairo::create_layout($cr);
|
||||
$layout->set_text(Encode::decode('UTF-8', $day . " " . $month . " " . $year));
|
||||
my $es = $settings->{entry_size};
|
||||
if ($es > 8) {
|
||||
$es = 8;
|
||||
}
|
||||
$desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . $es . 'px');
|
||||
$layout->set_font_description($desc);
|
||||
|
||||
my ($wid2, $h2) = $layout->get_pixel_size();
|
||||
$cr->save;
|
||||
$cr->move_to($settings->{margin_left} + $i * $cell + $cell/2 - $wid2/2, $self->{bounding_box}[1] + $h);
|
||||
Pango::Cairo::show_layout($cr, $layout);
|
||||
$cr->restore();
|
||||
|
||||
if ($h + $h2 > $ymax) {
|
||||
$ymax = $h + $h2;
|
||||
}
|
||||
}
|
||||
$self->{heading_bottom_y} = $ymax + $self->{bounding_box}[1];
|
||||
}
|
||||
|
||||
sub draw_entries
|
||||
{
|
||||
my ($self, $cr, $settings, $i) = @_;
|
||||
|
||||
my $cell = ($settings->{width} - $settings->{margin_left} - $settings->{margin_right})/7;
|
||||
|
||||
# Coordinates of box from line-to-line
|
||||
my $l2l_box = [$i * $cell + $settings->{margin_left},
|
||||
$self->{heading_bottom_y},
|
||||
($i+1) * $cell + $settings->{margin_left},
|
||||
$self->{bounding_box}[3]];
|
||||
|
||||
# Coordinates of drawing-space box
|
||||
my $box = [$l2l_box->[0] + $settings->{border_size},
|
||||
$l2l_box->[1] + $settings->{border_size},
|
||||
$l2l_box->[2] - $settings->{border_size},
|
||||
$l2l_box->[3] - $settings->{border_size}];
|
||||
|
||||
$self->{l2l_box} = $l2l_box;
|
||||
$self->{box} = $box;
|
||||
|
||||
# Do shading, if any
|
||||
my $shade = $self->find_last_special('shade', $self->{entries}->[$i]);
|
||||
if ($shade) {
|
||||
$cr->save;
|
||||
$cr->set_source_rgb($shade->{r} / 255,
|
||||
$shade->{g} / 255,
|
||||
$shade->{b} / 255);
|
||||
$cr->rectangle($l2l_box->[0], $l2l_box->[1],
|
||||
$l2l_box->[2] - $l2l_box->[0],
|
||||
$l2l_box->[3] - $l2l_box->[1]);
|
||||
$cr->fill();
|
||||
$cr->restore;
|
||||
}
|
||||
|
||||
# Get the "day number" size to leave room for moon and week specials
|
||||
my $layout = Pango::Cairo::create_layout($cr);
|
||||
$layout->set_text("31");
|
||||
my $desc = Pango::FontDescription->from_string($settings->{daynum_font} . ' ' . $settings->{daynum_size} . 'px');
|
||||
|
||||
$layout->set_font_description($desc);
|
||||
my ($wid, $h) = $layout->get_pixel_size();
|
||||
|
||||
my $so_far = $box->[1] + $h + $settings->{border_size};
|
||||
|
||||
my $box_height = $box->[3] - $box->[1];
|
||||
my $done = 0;
|
||||
foreach my $entry (@{$self->{entries}->[$i]}) {
|
||||
# Moon and week should not adjust height
|
||||
if ($entry->isa('Remind::PDF::Entry::moon') ||
|
||||
$entry->isa('Remind::PDF::Entry::week')) {
|
||||
$entry->render($self, $cr, $settings, $box->[1], $i, $i, $box_height);
|
||||
next;
|
||||
}
|
||||
|
||||
# An absolutely-positioned Pango markup should not adjust height
|
||||
# either
|
||||
if ($entry->isa('Remind::PDF::Entry::pango') &&
|
||||
defined($entry->{atx}) && defined($entry->{aty})) {
|
||||
$entry->render($self, $cr, $settings, $box->[1], $i, $i, $box_height);
|
||||
next;
|
||||
}
|
||||
|
||||
# Shade is done already
|
||||
if ($entry->isa('Remind::PDF::Entry::shade')) {
|
||||
next;
|
||||
}
|
||||
if ($done) {
|
||||
$so_far += $settings->{border_size};
|
||||
}
|
||||
$done = 1;
|
||||
$e->render($cr, $settings);
|
||||
my $h2 = $entry->render($self, $cr, $settings, $so_far, $i, $i, $box_height);
|
||||
$so_far += $h2;
|
||||
}
|
||||
}
|
||||
|
||||
sub col_box_coordinates
|
||||
{
|
||||
|
||||
my ($self, $so_far, $col, $height, $settings) = @_;
|
||||
return (@{$self->{l2l_box}});
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub draw_lines
|
||||
{
|
||||
my ($self, $cr, $settings) = @_;
|
||||
|
||||
# Top horizonal line
|
||||
$cr->move_to($self->{bounding_box}[0], $self->{bounding_box}[1]);
|
||||
$cr->line_to($self->{bounding_box}[2], $self->{bounding_box}[1]);
|
||||
$cr->stroke();
|
||||
|
||||
# Horizontal line below headings
|
||||
$cr->move_to($self->{bounding_box}[0], $self->{heading_bottom_y});
|
||||
$cr->line_to($self->{bounding_box}[2], $self->{heading_bottom_y});
|
||||
$cr->stroke();
|
||||
|
||||
# Bottom horizontal line
|
||||
$cr->move_to($self->{bounding_box}[0], $self->{bounding_box}[3]);
|
||||
$cr->line_to($self->{bounding_box}[2], $self->{bounding_box}[3]);
|
||||
$cr->stroke();
|
||||
|
||||
# Vertical lines
|
||||
my $w = ($settings->{width} - $settings->{margin_left} - $settings->{margin_right})/7;
|
||||
for (my $i=0; $i<=7; $i++) {
|
||||
my $x = $settings->{margin_left} + ($i * $w);
|
||||
$cr->move_to($x, $self->{bounding_box}[1]);
|
||||
$cr->line_to($x, $self->{bounding_box}[3]);
|
||||
$cr->stroke();
|
||||
}
|
||||
}
|
||||
|
||||
sub create_from_hash
|
||||
{
|
||||
my ($class, $hash, $specials_accepted) = @_;
|
||||
bless $hash, $class;
|
||||
|
||||
my $filtered_entries = [];
|
||||
my $date_to_index;
|
||||
for (my $i=0; $i<7; $i++) {
|
||||
$date_to_index->{$hash->{dates}[$i]->{date}} = $i;
|
||||
}
|
||||
|
||||
for (my $i=0; $i<7; $i++) {
|
||||
$filtered_entries->[$i] = [];
|
||||
}
|
||||
foreach my $e (@{$hash->{entries}}) {
|
||||
if ($hash->accept_special($e, $specials_accepted)) {
|
||||
my $index = $date_to_index->{$e->{date}};
|
||||
push(@{$filtered_entries->[$index]}, Remind::PDF::Entry->new_from_hash($e));
|
||||
}
|
||||
}
|
||||
$hash->{entries} = $filtered_entries;
|
||||
return $hash;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# A cheesy graphical front/back end for Remind using Tcl/Tk
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2024 Dianne Skoll
|
||||
# Copyright (C) 1992-2025 Dianne Skoll
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -30,6 +30,8 @@ catch {
|
||||
set Hostname [exec hostname]
|
||||
}
|
||||
|
||||
set Translations [dict create]
|
||||
|
||||
global env
|
||||
set HOME $env(HOME)
|
||||
|
||||
@@ -696,6 +698,21 @@ proc DoQueue {} {
|
||||
flush $DaemonFile
|
||||
}
|
||||
|
||||
proc DoTranslate {} {
|
||||
global DaemonFile
|
||||
global Translations
|
||||
|
||||
# Clear out any existing translations
|
||||
set Translations [dict create]
|
||||
|
||||
# Get just the translations we can use
|
||||
puts $DaemonFile "TRANSLATE New Moon"
|
||||
puts $DaemonFile "TRANSLATE Full Moon"
|
||||
puts $DaemonFile "TRANSLATE First Quarter"
|
||||
puts $DaemonFile "TRANSLATE Last Quarter"
|
||||
flush $DaemonFile
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# CreateCalWindow -- create the calendar window.
|
||||
# Arguments:
|
||||
@@ -703,6 +720,7 @@ proc DoQueue {} {
|
||||
#---------------------------------------------------------------------------
|
||||
proc CreateCalWindow { dayNames } {
|
||||
global Option
|
||||
|
||||
frame .h -background $Option(LineColor)
|
||||
label .h.title -text "" -justify center -pady 2 -bd 0 -relief flat -font HeadingFont -background $Option(WinBackground) -foreground $Option(LabelColor)
|
||||
pack .h.title -side top -fill x -pady 1 -padx 1
|
||||
@@ -2702,7 +2720,8 @@ proc StartBackgroundRemindDaemon {} {
|
||||
} else {
|
||||
fileevent $DaemonFile readable "DaemonReadable $DaemonFile"
|
||||
puts $DaemonFile "STATUS"
|
||||
flush $DaemonFile
|
||||
DoTranslate
|
||||
ScheduleUpdateForChanges
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2826,6 +2845,33 @@ proc sort_q { a b } {
|
||||
return 0
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# AddTranslation
|
||||
# Arguments:
|
||||
# obj - a dictionary of the form old:new
|
||||
# Returns:
|
||||
# nothing
|
||||
# Description:
|
||||
# Updates the Translations dict object
|
||||
#---------------------------------------------------------------------------
|
||||
proc AddTranslation { obj } {
|
||||
global Translations
|
||||
set Translations [dict merge $Translations $obj]
|
||||
ScheduleUpdateForChanges
|
||||
}
|
||||
|
||||
proc t { str } {
|
||||
global Translations
|
||||
set trans ""
|
||||
catch {
|
||||
set trans [dict get $Translations $str]
|
||||
}
|
||||
if {"$trans" == ""} {
|
||||
return $str
|
||||
}
|
||||
return $trans
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# DaemonReadable
|
||||
# Arguments:
|
||||
@@ -2851,6 +2897,9 @@ proc DaemonReadable { file } {
|
||||
}
|
||||
set response [dict get $obj response]
|
||||
switch -- $response {
|
||||
"translate" {
|
||||
AddTranslation [dict get $obj translation]
|
||||
}
|
||||
"queued" {
|
||||
set n [dict get $obj nqueued]
|
||||
if {$n == 1} {
|
||||
@@ -2888,7 +2937,9 @@ proc DaemonReadable { file } {
|
||||
if {[dict exists $obj command]} {
|
||||
set cmd [dict get $obj command]
|
||||
if {"$cmd" == "inotify"} {
|
||||
FillCalWindow
|
||||
# Update our translations if file has changed
|
||||
DoTranslate
|
||||
ScheduleUpdateForChanges
|
||||
}
|
||||
}
|
||||
puts $file "STATUS"
|
||||
@@ -3035,7 +3086,7 @@ proc main {} {
|
||||
|
||||
global AppendFile HighestTagSoFar DayNames
|
||||
catch {
|
||||
puts "\nTkRemind Copyright (C) 1996-2024 Dianne Skoll"
|
||||
puts "\nTkRemind Copyright (C) 1996-2025 Dianne Skoll"
|
||||
}
|
||||
catch { SetFonts }
|
||||
Initialize
|
||||
@@ -3617,14 +3668,14 @@ proc UpdateForChanges {} {
|
||||
RestartBackgroundRemindDaemon
|
||||
}
|
||||
|
||||
# Schedule an update for 100ms in the future.
|
||||
# Schedule an update for 250ms in the future.
|
||||
# That way, if we get a rapid succession of
|
||||
# change notifications, we (probably) only
|
||||
# end up doing one call to UpdateForChanges
|
||||
proc ScheduleUpdateForChanges {} {
|
||||
global TimerUpdateForChanges
|
||||
catch { after cancel $TimerUpdateForChanges }
|
||||
set TimerUpdateForChanges [after 100 UpdateForChanges]
|
||||
set TimerUpdateForChanges [after 250 UpdateForChanges]
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
@@ -3929,27 +3980,27 @@ proc CreateMoonWindows {} {
|
||||
foreach win {.moon_new .moon_new2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
balloon_add_help $win "New Moon"
|
||||
balloon_add_help $win [t "New Moon"]
|
||||
}
|
||||
|
||||
foreach win {.moon_first .moon_first2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
$win create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 90 -extent 180 -outline {}
|
||||
balloon_add_help $win "First Quarter"
|
||||
balloon_add_help $win [t "First Quarter"]
|
||||
}
|
||||
|
||||
foreach win {.moon_full .moon_full2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -width 1
|
||||
balloon_add_help $win "Full Moon"
|
||||
balloon_add_help $win [t "Full Moon"]
|
||||
}
|
||||
|
||||
foreach win {.moon_last .moon_last2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
$win create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 270 -extent 180 -outline {}
|
||||
balloon_add_help $win "Last Quarter"
|
||||
balloon_add_help $win [t "Last Quarter"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@ MANS= $(srcdir)/../man/rem2ps.1 $(srcdir)/../man/remind.1 \
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
REMINDSRCS= calendar.c dedupe.c dynbuf.c dorem.c dosubst.c expr.c \
|
||||
files.c funcs.c globals.c hbcal.c init.c main.c md5.c \
|
||||
moon.c omit.c queue.c sort.c token.c trigger.c \
|
||||
userfns.c utils.c var.c
|
||||
files.c funcs.c globals.c hashtab.c hashtab_stats.c \
|
||||
hbcal.c init.c main.c md5.c moon.c omit.c queue.c \
|
||||
sort.c token.c trans.c trigger.c userfns.c utils.c var.c
|
||||
|
||||
REMINDHDRS=config.h custom.h dynbuf.h err.h globals.h lang.h \
|
||||
REMINDHDRS=config.h custom.h dynbuf.h err.h globals.h hashtab.h \
|
||||
md5.h protos.h rem2ps.h types.h version.h
|
||||
REMINDOBJS= $(REMINDSRCS:.c=.o)
|
||||
|
||||
@@ -41,7 +41,7 @@ test: all
|
||||
@sh ../tests/test-rem
|
||||
|
||||
.c.o:
|
||||
@CC@ -c @CPPFLAGS@ @CFLAGS@ @DEFS@ $(CEXTRA) $(LANGDEF) -DSYSDIR=$(datarootdir)/remind -I. -I$(srcdir) $<
|
||||
@CC@ -c @CPPFLAGS@ @CFLAGS@ @DEFS@ $(CEXTRA) -DSYSDIR=$(datarootdir)/remind -I. -I$(srcdir) $<
|
||||
|
||||
$(REMINDOBJS): $(REMINDHDRS)
|
||||
|
||||
@@ -92,7 +92,7 @@ depend:
|
||||
# distributions, etc.
|
||||
|
||||
cppcheck:
|
||||
cppcheck -j`nproc` --force --enable=all --suppress=ConfigurationNotChecked --suppress=unmatchedSuppression --suppress=variableScope --inline-suppr .
|
||||
cppcheck -j`nproc` -v --force --enable=all --suppress=ConfigurationNotChecked --suppress=unmatchedSuppression --suppress=variableScope --inline-suppr .
|
||||
|
||||
# Build a tar file based on all files checked into git.
|
||||
distro:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* The code for generating a calendar. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
|
||||
#include "lang.h"
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "globals.h"
|
||||
@@ -275,6 +274,7 @@ static int ColToDay[7];
|
||||
static int ColSpaces;
|
||||
|
||||
static int DidAMonth;
|
||||
static int DidAWeek;
|
||||
static int DidADay;
|
||||
|
||||
static void ColorizeEntry(CalEntry const *e, int clamp);
|
||||
@@ -835,12 +835,33 @@ void ProduceCalendar(void)
|
||||
WriteIntermediateCalLine();
|
||||
}
|
||||
|
||||
while (CalWeeks--)
|
||||
DidAWeek = 0;
|
||||
if (PsCal == PSCAL_LEVEL3) {
|
||||
printf("[\n");
|
||||
}
|
||||
while (CalWeeks--) {
|
||||
DoCalendarOneWeek(CalWeeks);
|
||||
DidAWeek = 1;
|
||||
}
|
||||
if (PsCal == PSCAL_LEVEL3) {
|
||||
printf("\n]\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SendTranslationTable(int pslevel)
|
||||
{
|
||||
if (pslevel < PSCAL_LEVEL3) {
|
||||
printf("# translations\n");
|
||||
}
|
||||
DumpTranslationTable(stdout, 1);
|
||||
if (pslevel < PSCAL_LEVEL3) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoCalendarOneWeek */
|
||||
@@ -871,9 +892,33 @@ static void DoCalendarOneWeek(int nleft)
|
||||
/* Output the entries */
|
||||
/* If it's "Simple Calendar" format, do it simply... */
|
||||
if (DoSimpleCalendar) {
|
||||
if (PsCal == PSCAL_LEVEL3) {
|
||||
if (DidAWeek) {
|
||||
printf(",\n");
|
||||
}
|
||||
printf("{\n\"caltype\":\"weekly\",");
|
||||
if (!DidAWeek) {
|
||||
printf("\"translations\":");
|
||||
SendTranslationTable(PsCal);
|
||||
printf(",");
|
||||
}
|
||||
printf("\"dates\":[");
|
||||
for (i=0; i<7; i++) {
|
||||
if (i != 0) {
|
||||
printf(",");
|
||||
}
|
||||
FromDSE(OrigDse+i-wd, &y, &m, &d);
|
||||
printf("{\"dayname\":\"%s\",\"date\":\"%04d-%02d-%02d\",\"year\":%d,\"month\":\"%s\",\"day\":%d}", get_day_name((OrigDse+i-wd)%7),y, m+1, d, y, get_month_name(m), d);
|
||||
}
|
||||
printf("],\"entries\":[");
|
||||
}
|
||||
DidADay = 0;
|
||||
for (i=0; i<7; i++) {
|
||||
WriteSimpleEntries(i, OrigDse+i-wd);
|
||||
}
|
||||
if (PsCal == PSCAL_LEVEL3) {
|
||||
printf("\n]\n}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -985,14 +1030,25 @@ static void DoSimpleCalendarOneMonth(void)
|
||||
if (PsCal) {
|
||||
FromDSE(DSEToday, &y, &m, &d);
|
||||
if (PsCal == PSCAL_LEVEL1) {
|
||||
if (!DidAMonth) {
|
||||
SendTranslationTable(PsCal);
|
||||
}
|
||||
printf("%s\n", PSBEGIN);
|
||||
} else if (PsCal == PSCAL_LEVEL2) {
|
||||
if (!DidAMonth) {
|
||||
SendTranslationTable(PsCal);
|
||||
}
|
||||
printf("%s\n", PSBEGIN2);
|
||||
} else {
|
||||
if (DidAMonth) {
|
||||
printf(",\n");
|
||||
}
|
||||
printf("{\n");
|
||||
if (!DidAMonth) {
|
||||
printf("\"translations\":");
|
||||
SendTranslationTable(PsCal);
|
||||
printf(",");
|
||||
}
|
||||
}
|
||||
if (PsCal < PSCAL_LEVEL3) {
|
||||
printf("%s %d %d %d %d\n",
|
||||
@@ -1008,6 +1064,7 @@ static void DoSimpleCalendarOneMonth(void)
|
||||
}
|
||||
printf("\n");
|
||||
} else {
|
||||
PrintJSONKeyPairString("caltype", "monthly");
|
||||
PrintJSONKeyPairString("monthname", get_month_name(m));
|
||||
PrintJSONKeyPairInt("year", y);
|
||||
PrintJSONKeyPairInt("daysinmonth", DaysInMonth(m, y));
|
||||
@@ -1250,7 +1307,7 @@ static void PrintLeft(char const *s, int width, char pad)
|
||||
buf = calloc(len+1, sizeof(wchar_t));
|
||||
if (!buf) {
|
||||
/* Uh-oh... cannot recover */
|
||||
fprintf(stderr, "%s\n", ErrMsg[E_NO_MEM]);
|
||||
fprintf(ErrFp, "%s\n", GetErr(E_NO_MEM));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@@ -1335,7 +1392,7 @@ static void PrintCentered(char const *s, int width, char *pad)
|
||||
buf = calloc(len+1, sizeof(wchar_t));
|
||||
if (!buf) {
|
||||
/* Uh-oh... cannot recover */
|
||||
fprintf(stderr, "%s\n", ErrMsg[E_NO_MEM]);
|
||||
fprintf(ErrFp, "%s\n", GetErr(E_NO_MEM));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@@ -1645,7 +1702,7 @@ static void GenerateCalEntries(int col)
|
||||
|
||||
r=IncludeFile(InitialFile);
|
||||
if (r) {
|
||||
fprintf(ErrFp, "%s %s: %s\n", ErrMsg[E_ERR_READING], InitialFile, ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s %s: %s\n", GetErr(E_ERR_READING), InitialFile, GetErr(r));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -1653,7 +1710,7 @@ static void GenerateCalEntries(int col)
|
||||
r = ReadLine();
|
||||
if (r == E_EOF) return;
|
||||
if (r) {
|
||||
Eprint("%s: %s", ErrMsg[E_ERR_READING], ErrMsg[r]);
|
||||
Eprint("%s: %s", GetErr(E_ERR_READING), GetErr(r));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
s = FindInitialToken(&tok, CurLine);
|
||||
@@ -1686,6 +1743,7 @@ static void GenerateCalEntries(int col)
|
||||
case T_EndIf: r=DoEndif(&p); break;
|
||||
|
||||
case T_Include:
|
||||
case T_IncludeSys:
|
||||
case T_IncludeR: r=DoInclude(&p, tok.type); break;
|
||||
|
||||
case T_IncludeCmd: r=DoIncludeCmd(&p); break;
|
||||
@@ -1711,6 +1769,7 @@ static void GenerateCalEntries(int col)
|
||||
case T_Push: r=PushOmitContext(&p); break;
|
||||
case T_Preserve: r=DoPreserve(&p); break;
|
||||
case T_Expr: r = DoExpr(&p); break;
|
||||
case T_Translate: r = DoTranslate(&p); break;
|
||||
case T_RemType: if (tok.val == RUN_TYPE) {
|
||||
r=DoRun(&p);
|
||||
break;
|
||||
@@ -1733,7 +1792,7 @@ static void GenerateCalEntries(int col)
|
||||
r=DoCalRem(&p, col);
|
||||
break;
|
||||
}
|
||||
if (r && (!Hush || r != E_RUN_DISABLED)) Eprint("%s", ErrMsg[r]);
|
||||
if (r && (!Hush || r != E_RUN_DISABLED)) Eprint("%s", GetErr(r));
|
||||
|
||||
/* Destroy the parser - free up resources it may be tying up */
|
||||
DestroyParser(&p);
|
||||
@@ -2297,7 +2356,7 @@ void WriteJSONTrigger(Trigger const *t, int include_tags, int today)
|
||||
printf(",");
|
||||
}
|
||||
done = 1;
|
||||
printf("\"%s\"", EnglishDayName[i]);
|
||||
printf("\"%s\"", DayName[i]);
|
||||
}
|
||||
}
|
||||
printf("],");
|
||||
@@ -2332,7 +2391,7 @@ void WriteJSONTrigger(Trigger const *t, int include_tags, int today)
|
||||
printf(",");
|
||||
}
|
||||
done = 1;
|
||||
printf("\"%s\"", EnglishDayName[i]);
|
||||
printf("\"%s\"", DayName[i]);
|
||||
}
|
||||
}
|
||||
printf("],");
|
||||
@@ -2683,14 +2742,14 @@ CalendarTime(int tim, int duration)
|
||||
}
|
||||
|
||||
if (h >= 12) {
|
||||
ampm1 = DynamicPm;
|
||||
ampm1 = tr("pm");
|
||||
} else {
|
||||
ampm1 = DynamicAm;
|
||||
ampm1 = tr("am");
|
||||
}
|
||||
if (h2 >= 12) {
|
||||
ampm2 = DynamicPm;
|
||||
ampm2 = tr("pm");
|
||||
} else {
|
||||
ampm2 = DynamicAm;
|
||||
ampm2 = tr("am");
|
||||
}
|
||||
if (!days) {
|
||||
if (!strcmp(ampm1, ampm2)) {
|
||||
@@ -2737,7 +2796,7 @@ char const *SimpleTime(int tim)
|
||||
if (h == 0) hh=12;
|
||||
else if (h > 12) hh=h-12;
|
||||
else hh=h;
|
||||
sprintf(buf, "%d%c%02d%s ", hh, TimeSep, min, (h>=12) ? DynamicPm : DynamicAm);
|
||||
sprintf(buf, "%d%c%02d%s ", hh, TimeSep, min, (h>=12) ? tr("pm") : tr("am"));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $language_map = {
|
||||
en => 'ENGLISH',
|
||||
de => 'GERMAN',
|
||||
nl => 'DUTCH',
|
||||
fi => 'FINNISH',
|
||||
fr => 'FRENCH',
|
||||
'no' => 'NORWEGIAN',
|
||||
da => 'DANISH',
|
||||
pl => 'POLISH',
|
||||
is => 'ICELANDIC',
|
||||
pt => 'BRAZPORT',
|
||||
it => 'ITALIAN',
|
||||
ro => 'ROMANIAN',
|
||||
es => 'SPANISH',
|
||||
};
|
||||
|
||||
if (!$ARGV[0]) {
|
||||
print STDERR "Usage: $0 lang_code\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
my $lang = $ARGV[0];
|
||||
my $rc = 0;
|
||||
if ($lang eq 'all') {
|
||||
foreach my $l (sort(keys(%$language_map))) {
|
||||
if (check($l)) {
|
||||
$rc = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$rc = check($lang);
|
||||
}
|
||||
|
||||
exit($rc);
|
||||
|
||||
sub check
|
||||
{
|
||||
my ($lang) = @_;
|
||||
if (!exists($language_map->{$lang})) {
|
||||
print STDERR "$lang is not a valid language.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
my $flag = $language_map->{$lang};
|
||||
print STDERR "Testing for: $lang - $flag.\n";
|
||||
my_sys("make clean > /dev/null 2>&1") && die("make clean failed");
|
||||
my_sys("make -j18 all LANGDEF=-DLANG=$flag > /dev/null 2>&1") && die("make all failed");
|
||||
my_sys("./remind -q -r ../tests/tstlang.rem 2022-03-23 11:44 > test-$lang-compiled.out 2>&1");
|
||||
|
||||
my_sys("make clean > /dev/null 2>&1") && die("make clean failed");
|
||||
my_sys("make -j18 all > /dev/null 2>&1") && die("make all failed");
|
||||
my_sys("./remind -q -r -ii=\\\"../include/lang/$lang.rem\\\" ../tests/tstlang.rem 2022-03-23 11:44 > test-$lang-runtime.out 2>&1");
|
||||
|
||||
my $rc = my_sys("cmp test-$lang-compiled.out test-$lang-runtime.out > /dev/null 2>&1");
|
||||
if ($rc == 0) {
|
||||
print STDERR "Congrats! Compiled and runtime language output matches for $lang.\n";
|
||||
} else {
|
||||
print STDERR "Whoops. Compiled and runtime language output differs for $lang.\n"
|
||||
}
|
||||
return $rc;
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
||||
sub my_sys
|
||||
{
|
||||
#print STDERR "Running: " . join(' ', @_) . "\n";
|
||||
return system(@_);
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
/* which you can customize. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -22,8 +22,8 @@
|
||||
/* The default values are initially set to the city hall in Ottawa, */
|
||||
/* Ontario, Canada. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define DEFAULT_LATITUDE 45.420556
|
||||
#define DEFAULT_LONGITUDE -75.689722
|
||||
#define DEFAULT_LATITUDE 45.42055555555555
|
||||
#define DEFAULT_LONGITUDE -75.68944444444445
|
||||
#define LOCATION "Ottawa"
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* which you can customize. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
118
src/dedupe.c
118
src/dedupe.c
@@ -5,7 +5,7 @@
|
||||
/* Code to suppress duplicate reminders */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -16,16 +16,37 @@
|
||||
#include "protos.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define DEDUPE_HASH_SLOTS 31
|
||||
typedef struct dedupe_entry {
|
||||
struct dedupe_entry *next;
|
||||
struct hash_link link;
|
||||
int trigger_date;
|
||||
int trigger_time;
|
||||
char const *body;
|
||||
} DedupeEntry;
|
||||
|
||||
static DedupeEntry *DedupeTable[DEDUPE_HASH_SLOTS];
|
||||
static hash_table DedupeTable;
|
||||
|
||||
static unsigned int DedupeHashFunc(void *x)
|
||||
{
|
||||
DedupeEntry *e = (DedupeEntry *) x;
|
||||
unsigned int hashval = (unsigned int) e->trigger_date;
|
||||
if (e->trigger_time != NO_TIME) {
|
||||
hashval += (unsigned int) e->trigger_time;
|
||||
}
|
||||
hashval += HashVal_preservecase(e->body);
|
||||
return hashval;
|
||||
}
|
||||
|
||||
static int CompareDedupes(void *x, void *y)
|
||||
{
|
||||
DedupeEntry *a = (DedupeEntry *) x;
|
||||
DedupeEntry *b = (DedupeEntry *) y;
|
||||
if (a->trigger_date != b->trigger_date) return a->trigger_date - b->trigger_date;
|
||||
if (a->trigger_time != b->trigger_time) return a->trigger_time - b->trigger_time;
|
||||
return strcmp(a->body, b->body);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -43,24 +64,6 @@ FreeDedupeEntry(DedupeEntry *e)
|
||||
free(e);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetDedupeBucket */
|
||||
/* */
|
||||
/* Get the bucket for a given date and body */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static unsigned int
|
||||
GetDedupeBucket(int trigger_date, int trigger_time, char const *body)
|
||||
{
|
||||
unsigned int bucket = trigger_date;
|
||||
if (trigger_time != NO_TIME) {
|
||||
bucket += trigger_time;
|
||||
}
|
||||
bucket += HashVal(body);
|
||||
return bucket % DEDUPE_HASH_SLOTS;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindDedupeEntry */
|
||||
@@ -72,19 +75,12 @@ static DedupeEntry *
|
||||
FindDedupeEntry(int trigger_date, int trigger_time, char const *body)
|
||||
{
|
||||
DedupeEntry *e;
|
||||
|
||||
unsigned int bucket = GetDedupeBucket(trigger_date, trigger_time, body);
|
||||
|
||||
e = DedupeTable[bucket];
|
||||
while(e) {
|
||||
if (e->trigger_date == trigger_date &&
|
||||
e->trigger_time == trigger_time &&
|
||||
!strcmp(body, e->body)) {
|
||||
return e;
|
||||
}
|
||||
e = e->next;
|
||||
}
|
||||
return NULL;
|
||||
DedupeEntry candidate;
|
||||
candidate.body = body;
|
||||
candidate.trigger_date = trigger_date;
|
||||
candidate.trigger_time = trigger_time;
|
||||
e = hash_table_find(&DedupeTable, &candidate);
|
||||
return e;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -99,8 +95,6 @@ InsertDedupeEntry(int trigger_date, int trigger_time, char const *body)
|
||||
{
|
||||
DedupeEntry *e;
|
||||
|
||||
unsigned int bucket = GetDedupeBucket(trigger_date, trigger_time, body);
|
||||
|
||||
e = malloc(sizeof(DedupeEntry));
|
||||
if (!e) {
|
||||
return; /* No error checking... what can we do? */
|
||||
@@ -113,8 +107,7 @@ InsertDedupeEntry(int trigger_date, int trigger_time, char const *body)
|
||||
return;
|
||||
}
|
||||
|
||||
e->next = DedupeTable[bucket];
|
||||
DedupeTable[bucket] = e;
|
||||
hash_table_insert(&DedupeTable, e);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -149,16 +142,18 @@ void
|
||||
ClearDedupeTable(void)
|
||||
{
|
||||
DedupeEntry *e, *next;
|
||||
for (int i=0; i<DEDUPE_HASH_SLOTS; i++) {
|
||||
e = DedupeTable[i];
|
||||
while (e) {
|
||||
next = e->next;
|
||||
FreeDedupeEntry(e);
|
||||
e = next;
|
||||
}
|
||||
DedupeTable[i] = NULL;
|
||||
|
||||
e = hash_table_next(&DedupeTable, NULL);
|
||||
while(e) {
|
||||
next = hash_table_next(&DedupeTable, e);
|
||||
hash_table_delete_no_resize(&DedupeTable, e);
|
||||
FreeDedupeEntry(e);
|
||||
e = next;
|
||||
}
|
||||
hash_table_free(&DedupeTable);
|
||||
InitDedupeTable();
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* InitDedupeTable */
|
||||
@@ -169,31 +164,16 @@ ClearDedupeTable(void)
|
||||
void
|
||||
InitDedupeTable(void)
|
||||
{
|
||||
for (int i=0; i<DEDUPE_HASH_SLOTS; i++) {
|
||||
DedupeTable[i] = NULL;
|
||||
if (hash_table_init(&DedupeTable,
|
||||
offsetof(DedupeEntry, link),
|
||||
DedupeHashFunc, CompareDedupes) < 0) {
|
||||
fprintf(ErrFp, "Unable to initialize function hash table: Out of memory. Exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
get_dedupe_hash_stats(int *total, int *maxlen, double *avglen)
|
||||
dump_dedupe_hash_stats(void)
|
||||
{
|
||||
int len;
|
||||
int i;
|
||||
DedupeEntry *e;
|
||||
|
||||
*maxlen = 0;
|
||||
*total = 0;
|
||||
for (i=0; i<DEDUPE_HASH_SLOTS; i++) {
|
||||
len = 0;
|
||||
e = DedupeTable[i];
|
||||
while (e) {
|
||||
len++;
|
||||
(*total)++;
|
||||
e = e->next;
|
||||
}
|
||||
if (len > *maxlen) {
|
||||
*maxlen = len;
|
||||
}
|
||||
}
|
||||
*avglen = (double) *total / (double) DEDUPE_HASH_SLOTS;
|
||||
hash_table_dump_stats(&DedupeTable, ErrFp);
|
||||
}
|
||||
|
||||
62
src/dorem.c
62
src/dorem.c
@@ -7,7 +7,7 @@
|
||||
/* commands. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -284,7 +284,7 @@ int DoRem(ParsePtr p)
|
||||
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
|
||||
if (r) {
|
||||
if (PurgeMode) {
|
||||
PurgeEchoLine("%s: %s\n", "#!P! Problem calculating trigger date", ErrMsg[r]);
|
||||
PurgeEchoLine("%s: %s\n", "#!P! Problem calculating trigger date", GetErr(r));
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
if (r == E_CANT_TRIG && trig.maybe_uncomputable) {
|
||||
@@ -698,7 +698,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", ErrMsg[-tok.val], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return -tok.val;
|
||||
}
|
||||
@@ -808,7 +808,7 @@ static int ParseTimeTrig(ParsePtr s, TimeTrig *tim)
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", ErrMsg[-tok.val], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return -tok.val;
|
||||
}
|
||||
@@ -887,7 +887,7 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
y = tok.val;
|
||||
@@ -896,7 +896,7 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
case T_Month:
|
||||
DBufFree(&buf);
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
m = tok.val;
|
||||
@@ -905,7 +905,7 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
case T_Day:
|
||||
DBufFree(&buf);
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
d = tok.val;
|
||||
@@ -914,15 +914,15 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
FromDSE(tok.val, &y, &m, &d);
|
||||
@@ -930,12 +930,12 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", ErrMsg[-tok.val], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return -tok.val;
|
||||
}
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_INCOMPLETE]);
|
||||
Eprint("%s: %s", which, GetErr(E_INCOMPLETE));
|
||||
DBufFree(&buf);
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
@@ -984,7 +984,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
y = tok.val;
|
||||
@@ -993,7 +993,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
case T_Month:
|
||||
DBufFree(&buf);
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
m = tok.val;
|
||||
@@ -1002,7 +1002,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
case T_Day:
|
||||
DBufFree(&buf);
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
d = tok.val;
|
||||
@@ -1011,15 +1011,15 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
FromDSE(tok.val, &y, &m, &d);
|
||||
@@ -1028,19 +1028,19 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
case T_Back:
|
||||
DBufFree(&buf);
|
||||
if (type != SCANFROM_TYPE) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_INCOMPLETE]);
|
||||
Eprint("%s: %s", word, GetErr(E_INCOMPLETE));
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
if (tok.val < 0) {
|
||||
@@ -1054,12 +1054,12 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", ErrMsg[-tok.val], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return -tok.val;
|
||||
}
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_INCOMPLETE]);
|
||||
Eprint("%s: %s", word, GetErr(E_INCOMPLETE));
|
||||
DBufFree(&buf);
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
@@ -1471,7 +1471,7 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int dse, int *err)
|
||||
}
|
||||
if (iter > max) {
|
||||
*err = E_CANT_TRIG;
|
||||
Eprint("Delta: Bad OMITFUNC? %s", ErrMsg[E_CANT_TRIG]);
|
||||
Eprint("Delta: Bad OMITFUNC? %s", GetErr(E_CANT_TRIG));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1690,7 +1690,7 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
||||
|
||||
/* If no proper function exists, barf... */
|
||||
if (UserFuncExists(t->warn) != 1) {
|
||||
Eprint("%s: `%s'", ErrMsg[M_BAD_WARN_FUNC], t->warn);
|
||||
Eprint("%s: `%s'", GetErr(M_BAD_WARN_FUNC), t->warn);
|
||||
return (dse == DSEToday);
|
||||
}
|
||||
for (i=1; ; i++) {
|
||||
@@ -1698,14 +1698,14 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
||||
s = buffer;
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
if (r) {
|
||||
Eprint("%s: `%s': %s", ErrMsg[M_BAD_WARN_FUNC],
|
||||
t->warn, ErrMsg[r]);
|
||||
Eprint("%s: `%s': %s", GetErr(M_BAD_WARN_FUNC),
|
||||
t->warn, GetErr(r));
|
||||
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]);
|
||||
Eprint("%s: `%s': %s", GetErr(M_BAD_WARN_FUNC),
|
||||
t->warn, GetErr(E_BAD_TYPE));
|
||||
return (dse == DSEToday);
|
||||
}
|
||||
|
||||
@@ -1735,7 +1735,7 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
||||
}
|
||||
}
|
||||
if (iter > max) {
|
||||
Eprint("Delta: Bad OMITFUNC? %s", ErrMsg[E_CANT_TRIG]);
|
||||
Eprint("Delta: Bad OMITFUNC? %s", GetErr(E_CANT_TRIG));
|
||||
return 0;
|
||||
}
|
||||
if (j == DSEToday) return 1;
|
||||
|
||||
489
src/dosubst.c
489
src/dosubst.c
@@ -6,7 +6,7 @@
|
||||
/* reminders are triggered. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -93,26 +93,14 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
mdiff = adiff % 60;
|
||||
hdiff = adiff / 60;
|
||||
|
||||
#ifdef L_MPLU_OVER
|
||||
L_MPLU_OVER
|
||||
#else /* L_MPLU_OVER */
|
||||
mplu = (mdiff == 1 ? "" : DynamicMplu);
|
||||
#endif /* L_MPLU_OVER */
|
||||
|
||||
#ifdef L_HPLU_OVER
|
||||
L_HPLU_OVER
|
||||
#else /* L_HPLU_OVER */
|
||||
hplu = (hdiff == 1 ? "" : DynamicHplu);
|
||||
#endif /* L_HPLU_OVER */
|
||||
|
||||
when = (tdiff < 0) ? DynamicAgo : DynamicFromnow;
|
||||
when = (tdiff < 0) ? tr("ago") : tr("from now");
|
||||
|
||||
h = tim / 60;
|
||||
min = tim % 60;
|
||||
|
||||
#ifdef L_AMPM_OVERRIDE
|
||||
L_AMPM_OVERRIDE (pm, h)
|
||||
#else
|
||||
r = -1;
|
||||
func = FindUserFunc("subst_ampm");
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
@@ -128,21 +116,18 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
pm = (h < 12) ? DynamicAm : DynamicPm;
|
||||
pm = (h < 12) ? tr("am") : tr("pm");
|
||||
}
|
||||
#endif
|
||||
|
||||
hh = (h == 12) ? 12 : h % 12;
|
||||
|
||||
ch = curtime / 60;
|
||||
cmin = curtime % 60;
|
||||
|
||||
#ifdef L_AMPM_OVERRIDE
|
||||
L_AMPM_OVERRIDE (cpm, ch)
|
||||
#else
|
||||
r = -1;
|
||||
func = FindUserFunc("subst_ampm");
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
@@ -158,18 +143,14 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
cpm = (h < 12) ? DynamicAm : DynamicPm;
|
||||
cpm = (h < 12) ? tr("am") : tr("pm");
|
||||
}
|
||||
#endif
|
||||
chh = (ch == 12) ? 12 : ch % 12;
|
||||
|
||||
#ifdef L_ORDINAL_OVERRIDE
|
||||
L_ORDINAL_OVERRIDE;
|
||||
#else
|
||||
func = FindUserFunc("subst_ordinal");
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
snprintf(s, sizeof(s), "subst_ordinal(%d)", d);
|
||||
@@ -184,7 +165,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
@@ -202,7 +183,6 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
default: plu = "th"; break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
@@ -235,6 +215,36 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
if (c == '(') {
|
||||
DynamicBuffer orig;
|
||||
DynamicBuffer translated;
|
||||
DBufInit(&orig);
|
||||
DBufInit(&translated);
|
||||
while(1) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(&orig);
|
||||
return err;
|
||||
}
|
||||
if (!c || c == ')') {
|
||||
break;
|
||||
}
|
||||
DBufPutc(&orig, c);
|
||||
}
|
||||
if (!c) {
|
||||
Wprint("Warning: Unterminated %%(...) substitution sequence");
|
||||
}
|
||||
err = OK;
|
||||
if (GetTranslatedStringTryingVariants(DBufValue(&orig), &translated)) {
|
||||
err = DBufPuts(dbuf, DBufValue(&translated));
|
||||
} else {
|
||||
err = DBufPuts(dbuf, DBufValue(&orig));
|
||||
}
|
||||
DBufFree(&orig);
|
||||
DBufFree(&translated);
|
||||
if (err) return err;
|
||||
continue;
|
||||
}
|
||||
if (c == '*') {
|
||||
altmode = c;
|
||||
c = ParseChar(p, &err, 0);
|
||||
@@ -312,52 +322,26 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
|
||||
if (diff <= 1) {
|
||||
switch(UPPER(c)) {
|
||||
#ifndef L_NOTOMORROW_A
|
||||
case 'A':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_B
|
||||
case 'B':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_C
|
||||
case 'C':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_E
|
||||
case 'E':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_F
|
||||
case 'F':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_G
|
||||
case 'G':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_H
|
||||
case 'H':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_I
|
||||
case 'I':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_J
|
||||
case 'J':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_K
|
||||
case 'K':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_L
|
||||
case 'L':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_U
|
||||
case 'U':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_V
|
||||
case 'V':
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", (diff ? DynamicTomorrow: DynamicToday));
|
||||
snprintf(s, sizeof(s), "%s", (diff ? tr("tomorrow") : tr("today")));
|
||||
SHIP_OUT(s);
|
||||
done = 1;
|
||||
break;
|
||||
@@ -388,436 +372,279 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
switch(UPPER(c)) {
|
||||
case 'A':
|
||||
#ifdef L_A_OVER
|
||||
L_A_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d %s, %d", get_day_name(dse%7), d,
|
||||
get_month_name(m), y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d %s, %d", DynamicOn, get_day_name(dse%7), d,
|
||||
get_month_name(m), y);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
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", tr("on"), get_day_name(dse%7), d,
|
||||
get_month_name(m), y);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
#ifdef L_B_OVER
|
||||
L_B_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), L_INXDAYS, diff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "in %d days' time", diff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
#ifdef L_C_OVER
|
||||
L_C_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s", DynamicOn, get_day_name(dse%7));
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s", tr("on"), get_day_name(dse%7));
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
#ifdef L_D_OVER
|
||||
L_D_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", d);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", d);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
#ifdef L_E_OVER
|
||||
L_E_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", d, DateSep,
|
||||
m+1, DateSep, y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, d, DateSep,
|
||||
m+1, DateSep, y);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", d, DateSep,
|
||||
m+1, DateSep, y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", tr("on"), d, DateSep,
|
||||
m+1, DateSep, y);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
#ifdef L_F_OVER
|
||||
L_F_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, m+1, DateSep, d, DateSep, y);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", tr("on"), m+1, DateSep, d, DateSep, y);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
#ifdef L_G_OVER
|
||||
L_G_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d %s", get_day_name(dse%7), d, get_month_name(m));
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d %s", DynamicOn, get_day_name(dse%7), d, get_month_name(m));
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
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", tr("on"), get_day_name(dse%7), d, get_month_name(m));
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
#ifdef L_H_OVER
|
||||
L_H_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", d, DateSep, m+1);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, d, DateSep, m+1);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", d, DateSep, m+1);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", tr("on"), d, DateSep, m+1);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
#ifdef L_I_OVER
|
||||
L_I_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", m+1, DateSep, d);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, m+1, DateSep, d);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", m+1, DateSep, d);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", tr("on"), m+1, DateSep, d);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
#ifdef L_J_OVER
|
||||
L_J_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %s %d%s, %d", get_day_name(dse%7),
|
||||
get_month_name(m), d, plu, y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %s %d%s, %d", DynamicOn, get_day_name(dse%7),
|
||||
get_month_name(m), d, plu, y);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
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", tr("on"), get_day_name(dse%7),
|
||||
get_month_name(m), d, plu, y);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
#ifdef L_K_OVER
|
||||
L_K_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %s %d%s", get_day_name(dse%7),
|
||||
get_month_name(m), d, plu);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %s %d%s", DynamicOn, get_day_name(dse%7),
|
||||
get_month_name(m), d, plu);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
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", tr("on"), get_day_name(dse%7),
|
||||
get_month_name(m), d, plu);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
#ifdef L_L_OVER
|
||||
L_L_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %04d%c%02d%c%02d", DynamicOn, y, DateSep, m+1, DateSep, d);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %04d%c%02d%c%02d", tr("on"), y, DateSep, m+1, DateSep, d);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
#ifdef L_M_OVER
|
||||
L_M_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", get_month_name(m));
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", get_month_name(m));
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
#ifdef L_N_OVER
|
||||
L_N_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", m+1);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", m+1);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
#ifdef L_O_OVER
|
||||
L_O_OVER
|
||||
#else
|
||||
if (RealToday == DSEToday) snprintf(s, sizeof(s), " (%s)", DynamicToday);
|
||||
else *s = 0;
|
||||
#endif
|
||||
if (RealToday == DSEToday) snprintf(s, sizeof(s), " (%s)", tr("today"));
|
||||
else *s = 0;
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
#ifdef L_P_OVER
|
||||
L_P_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", (diff == 1 ? "" : L_PLURAL));
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", (diff == 1 ? "" : "s"));
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
#ifdef L_Q_OVER
|
||||
L_Q_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", (diff == 1 ? "'s" : "s'"));
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", (diff == 1 ? "'s" : "s'"));
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
#ifdef L_R_OVER
|
||||
L_R_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%02d", d);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%02d", d);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
#ifdef L_S_OVER
|
||||
L_S_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", plu);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", plu);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
#ifdef L_T_OVER
|
||||
L_T_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%02d", m+1);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%02d", m+1);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
#ifdef L_U_OVER
|
||||
L_U_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d%s %s, %d", get_day_name(dse%7), d,
|
||||
plu, get_month_name(m), y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d%s %s, %d", DynamicOn, get_day_name(dse%7), d,
|
||||
plu, get_month_name(m), y);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
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", tr("on"), get_day_name(dse%7), d,
|
||||
plu, get_month_name(m), y);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
#ifdef L_V_OVER
|
||||
L_V_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d%s %s", get_day_name(dse%7), d, plu,
|
||||
get_month_name(m));
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d%s %s", DynamicOn, get_day_name(dse%7), d, plu,
|
||||
get_month_name(m));
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
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", tr("on"), get_day_name(dse%7), d, plu,
|
||||
get_month_name(m));
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
#ifdef L_W_OVER
|
||||
L_W_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
#ifdef L_X_OVER
|
||||
L_X_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", diff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", diff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
#ifdef L_Y_OVER
|
||||
L_Y_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", y);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", y);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
#ifdef L_Z_OVER
|
||||
L_Z_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", y % 100);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", y % 100);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '1':
|
||||
#ifdef L_1_OVER
|
||||
L_1_OVER
|
||||
#else
|
||||
if (tdiff == 0)
|
||||
snprintf(s, sizeof(s), "%s", DynamicNow);
|
||||
else if (hdiff == 0)
|
||||
snprintf(s, sizeof(s), "%d %s%s %s", mdiff, DynamicMinute, mplu, when);
|
||||
else if (mdiff == 0)
|
||||
snprintf(s, sizeof(s), "%d %s%s %s", hdiff, DynamicHour, hplu, when);
|
||||
else
|
||||
snprintf(s, sizeof(s), "%d %s%s %s %d %s%s %s", hdiff, DynamicHour, hplu,
|
||||
DynamicAnd, mdiff, DynamicMinute, mplu, when);
|
||||
#endif
|
||||
if (tdiff == 0)
|
||||
snprintf(s, sizeof(s), "%s", tr("now"));
|
||||
else if (hdiff == 0)
|
||||
snprintf(s, sizeof(s), "%d %s%s %s", mdiff, tr("minute"), mplu, when);
|
||||
else if (mdiff == 0)
|
||||
snprintf(s, sizeof(s), "%d %s%s %s", hdiff, tr("hour"), hplu, when);
|
||||
else
|
||||
snprintf(s, sizeof(s), "%d %s%s %s %d %s%s %s", hdiff, tr("hour"), hplu,
|
||||
tr("and"), mdiff, tr("minute"), mplu, when);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '2':
|
||||
#ifdef L_2_OVER
|
||||
L_2_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
snprintf(s, sizeof(s), "%d%c%02d%s", hh, TimeSep, min, pm);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %d%c%02d%s", DynamicAt, hh, TimeSep, min, pm);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*') {
|
||||
snprintf(s, sizeof(s), "%d%c%02d%s", hh, TimeSep, min, pm);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %d%c%02d%s", tr("at"), hh, TimeSep, min, pm);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '3':
|
||||
#ifdef L_3_OVER
|
||||
L_3_OVER
|
||||
#else
|
||||
|
||||
if (altmode == '*') {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", h, TimeSep, min);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicAt, h, TimeSep, min);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*') {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", h, TimeSep, min);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", tr("at"), h, TimeSep, min);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '4':
|
||||
#ifdef L_4_OVER
|
||||
L_4_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", tdiff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", tdiff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '5':
|
||||
#ifdef L_5_OVER
|
||||
L_5_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", adiff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", adiff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '6':
|
||||
#ifdef L_6_OVER
|
||||
L_6_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", when);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", when);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '7':
|
||||
#ifdef L_7_OVER
|
||||
L_7_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", hdiff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", hdiff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '8':
|
||||
#ifdef L_8_OVER
|
||||
L_8_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", mdiff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", mdiff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '9':
|
||||
#ifdef L_9_OVER
|
||||
L_9_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", mplu);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", mplu);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '0':
|
||||
#ifdef L_0_OVER
|
||||
L_0_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", hplu);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", hplu);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '!':
|
||||
#ifdef L_BANG_OVER
|
||||
L_BANG_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? DynamicIs : DynamicWas));
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? tr("is") : tr("was")));
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '@':
|
||||
#ifdef L_AT_OVER
|
||||
L_AT_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d%c%02d%s", chh, TimeSep, cmin, cpm);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d%c%02d%s", chh, TimeSep, cmin, cpm);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '#':
|
||||
#ifdef L_HASH_OVER
|
||||
L_HASH_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", ch, TimeSep, cmin);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", ch, TimeSep, cmin);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
@@ -914,7 +741,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoSubstFromString(char const *source, DynamicBuffer *dbuf,
|
||||
int dse, int tim)
|
||||
int dse, int tim)
|
||||
{
|
||||
Trigger tempTrig;
|
||||
TimeTrig tempTime;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* buffers. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Declaration of functions for manipulating dynamic buffers */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
44
src/err.h
44
src/err.h
@@ -5,7 +5,7 @@
|
||||
/* Error definitions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -13,31 +13,35 @@
|
||||
/* Note that not all of the "errors" are really errors - some are just
|
||||
messages for information purposes. Constants beginning with M_ should
|
||||
never be returned as error indicators - they should only be used to
|
||||
index the ErrMsg array. */
|
||||
index the ErrMsg array.
|
||||
|
||||
Some #defines are commented out; these are former error codes that are
|
||||
no longer used. They are left as placeholders because renumbering
|
||||
everything wouild be too tedious */
|
||||
|
||||
#define OK 0
|
||||
#define E_MISS_END 1
|
||||
#define E_MISS_QUOTE 2
|
||||
#define E_OP_STK_OVER 3
|
||||
#define E_VA_STK_OVER 4
|
||||
/* #define E_VA_STK_OVER 4 */
|
||||
#define E_MISS_RIGHT_PAREN 5
|
||||
#define E_UNDEF_FUNC 6
|
||||
#define E_ILLEGAL_CHAR 7
|
||||
#define E_EXPECTING_BINOP 8
|
||||
/* #define E_EXPECTING_BINOP 8 */
|
||||
#define E_NO_MEM 9
|
||||
#define E_BAD_NUMBER 10
|
||||
#define E_OP_STK_UNDER 11
|
||||
#define E_VA_STK_UNDER 12
|
||||
/* #define E_OP_STK_UNDER 11 */
|
||||
/* #define E_VA_STK_UNDER 12 */
|
||||
#define E_CANT_COERCE 13
|
||||
#define E_BAD_TYPE 14
|
||||
#define E_DATE_OVER 15
|
||||
#define E_STACK_ERR 16
|
||||
/* #define E_STACK_ERR 16 */
|
||||
#define E_DIV_ZERO 17
|
||||
#define E_NOSUCH_VAR 18
|
||||
#define E_EOLN 19
|
||||
#define E_EOF 20
|
||||
#define E_IO_ERR 21
|
||||
#define E_LINE_2_LONG 22
|
||||
/* #define E_LINE_2_LONG 22 */
|
||||
#define E_SWERR 23
|
||||
#define E_BAD_DATE 24
|
||||
#define E_2FEW_ARGS 25
|
||||
@@ -72,7 +76,7 @@
|
||||
#define E_DAY_TWICE 52
|
||||
#define E_UNKNOWN_TOKEN 53
|
||||
#define E_SPEC_MON 54
|
||||
#define E_2MANY_PART 55
|
||||
/* #define E_2MANY_PART 55 */
|
||||
#define E_2MANY_FULL 56
|
||||
#define E_PUSH_NOPOP 57
|
||||
#define E_ERR_READING 58
|
||||
@@ -110,7 +114,7 @@
|
||||
#define E_MISS_EQ 90
|
||||
#define E_MISS_VAR 91
|
||||
#define E_MISS_EXPR 92
|
||||
#define M_CANTSET_ACCESS 93
|
||||
/* #define M_CANTSET_ACCESS 93 */
|
||||
#define M_I_OPTION 94
|
||||
#define E_NOREMINDERS 95
|
||||
#define M_QUEUED 96
|
||||
@@ -147,25 +151,25 @@ EXTERN char *ErrMsg[]
|
||||
/* E_MISS_END */ "Missing ']'",
|
||||
/* E_MISS_QUOTE */ "Missing quote",
|
||||
/* E_OP_STK_OVER */ "Expression too complex",
|
||||
/* E_VA_STK_OVER */ "Expression too complex - too many operands",
|
||||
/* E_VA_STK_OVER */ "",
|
||||
/* E_MISS_RIGHT_PAREN */ "Missing ')'",
|
||||
/* E_UNDEF_FUNC */ "Undefined function",
|
||||
/* E_ILLEGAL_CHAR */ "Illegal character",
|
||||
/* E_EXPECTING_BINOP */ "Expecting binary operator",
|
||||
/* E_NO_MEM */ "Out of memory",
|
||||
/* E_BAD_NUMBER */ "Ill-formed number",
|
||||
/* E_OP_STK_UNDER */ "Op stack underflow - internal error",
|
||||
/* E_VA_STK_UNDER */ "Va stack underflow - internal error",
|
||||
/* E_OP_STK_UNDER */ "",
|
||||
/* E_VA_STK_UNDER */ "",
|
||||
/* E_CANT_COERCE */ "Can't coerce",
|
||||
/* E_BAD_TYPE */ "Type mismatch",
|
||||
/* E_DATE_OVER */ "Date overflow",
|
||||
/* E_STACK_ERR */ "Stack error - internal error",
|
||||
/* E_STACK_ERR */ "",
|
||||
/* E_DIV_ZERO */ "Division by zero",
|
||||
/* E_NOSUCH_VAR */ "Undefined variable",
|
||||
/* E_EOLN */ "Unexpected end of line",
|
||||
/* E_EOF */ "Unexpected end of file",
|
||||
/* E_IO_ERR */ "I/O error",
|
||||
/* E_LINE_2_LONG */ "Line too long",
|
||||
/* E_LINE_2_LONG */ "",
|
||||
/* E_SWERR */ "Internal error",
|
||||
/* E_BAD_DATE */ "Bad date specification",
|
||||
/* E_2FEW_ARGS */ "Not enough arguments",
|
||||
@@ -198,7 +202,7 @@ EXTERN char *ErrMsg[]
|
||||
/* E_DAY_TWICE */ "Day specified twice",
|
||||
/* E_UNKNOWN_TOKEN */ "Unknown token",
|
||||
/* E_SPEC_MON */ "Must specify month in OMIT command",
|
||||
/* E_2MANY_PART */ "Too many partial OMITs (max. " STR(MAX_PARTIAL_OMITS) ")",
|
||||
/* E_2MANY_PART */ "",
|
||||
/* E_2MANY_FULL */ "Too many full OMITs (max. " STR(MAX_FULL_OMITS) ")",
|
||||
/* E_PUSH_NOPOP */ "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT",
|
||||
/* E_ERR_READING */ "Error reading",
|
||||
@@ -236,7 +240,7 @@ EXTERN char *ErrMsg[]
|
||||
/* E_MISS_EQ */ "Missing '=' sign",
|
||||
/* E_MISS_VAR */ "Missing variable name",
|
||||
/* E_MISS_EXPR */ "Missing expression",
|
||||
/* M_CANTSET_ACCESS */ "Can't reset access date of %s\n",
|
||||
/* M_CANTSET_ACCESS */ "",
|
||||
/* M_I_OPTION */ "Remind: '-i' option: %s\n",
|
||||
/* E_NOREMINDERS */ "No reminders.",
|
||||
/* M_QUEUED */ "%d reminder(s) queued for later today.\n",
|
||||
@@ -255,3 +259,9 @@ EXTERN char *ErrMsg[]
|
||||
#endif /* MK_GLOBALS */
|
||||
;
|
||||
#endif /* L_ERR_OVERRIDE */
|
||||
|
||||
EXTERN int NumErrs
|
||||
#ifdef MK_GLOBALS
|
||||
= sizeof(ErrMsg) / sizeof(ErrMsg[0])
|
||||
#endif
|
||||
;
|
||||
|
||||
84
src/expr.c
84
src/expr.c
@@ -12,7 +12,7 @@
|
||||
/* evaluated. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -282,7 +282,7 @@ debug_evaluation(Value *ans, int r, char const *fmt, ...)
|
||||
vfprintf(ErrFp, fmt, argptr);
|
||||
fprintf(ErrFp, " => ");
|
||||
if (r != OK) {
|
||||
fprintf(ErrFp, "%s\n", ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s\n", GetErr(r));
|
||||
} else {
|
||||
PrintValue(ans, ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
@@ -321,7 +321,7 @@ debug_evaluation_binop(Value *ans, int r, Value *v1, Value *v2, char const *fmt,
|
||||
}
|
||||
fprintf(ErrFp, " => ");
|
||||
if (r != OK) {
|
||||
fprintf(ErrFp, "%s\n", ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s\n", GetErr(r));
|
||||
} else {
|
||||
PrintValue(ans, ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
@@ -353,7 +353,7 @@ debug_evaluation_unop(Value *ans, int r, Value *v1, char const *fmt, ...)
|
||||
}
|
||||
fprintf(ErrFp, " => ");
|
||||
if (r != OK) {
|
||||
fprintf(ErrFp, "%s\n", ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s\n", GetErr(r));
|
||||
} else {
|
||||
PrintValue(ans, ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
@@ -426,11 +426,11 @@ eval_builtin(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
/* Check that we have the right number of argumens */
|
||||
if (node->num_kids < f->minargs) {
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2FEW_ARGS]);
|
||||
Eprint("%s(): %s", f->name, GetErr(E_2FEW_ARGS));
|
||||
return E_2FEW_ARGS;
|
||||
}
|
||||
if (node->num_kids > f->maxargs && f->maxargs != NO_MAX) {
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2MANY_ARGS]);
|
||||
Eprint("%s(): %s", f->name, GetErr(E_2MANY_ARGS));
|
||||
return E_2MANY_ARGS;
|
||||
}
|
||||
|
||||
@@ -506,14 +506,14 @@ eval_builtin(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
/* Debug */
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (r) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s", GetErr(r));
|
||||
} else {
|
||||
PrintValue(ans, ErrFp);
|
||||
}
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
if (r != OK) {
|
||||
Eprint("%s(): %s", f->name, ErrMsg[r]);
|
||||
Eprint("%s(): %s", f->name, GetErr(r));
|
||||
}
|
||||
/* Clean up */
|
||||
if (info.args) {
|
||||
@@ -546,7 +546,7 @@ debug_enter_userfunc(expr_node *node, Value *locals, int nargs)
|
||||
} else {
|
||||
fname = node->u.value.v.str;
|
||||
}
|
||||
fprintf(ErrFp, "%s %s(", ErrMsg[E_ENTER_FUN], fname);
|
||||
fprintf(ErrFp, "%s %s(", GetErr(E_ENTER_FUN), fname);
|
||||
for (i=0; i<nargs; i++) {
|
||||
if (i) fprintf(ErrFp, ", ");
|
||||
PrintValue(&(locals[i]), ErrFp);
|
||||
@@ -572,7 +572,7 @@ debug_exit_userfunc(expr_node *node, Value *ans, int r, Value *locals, int nargs
|
||||
} else {
|
||||
fname = node->u.value.v.str;
|
||||
}
|
||||
fprintf(ErrFp, "%s %s(", ErrMsg[E_LEAVE_FUN], fname);
|
||||
fprintf(ErrFp, "%s %s(", GetErr(E_LEAVE_FUN), fname);
|
||||
for (i=0; i<nargs; i++) {
|
||||
if (i) fprintf(ErrFp, ", ");
|
||||
PrintValue(&(locals[i]), ErrFp);
|
||||
@@ -581,7 +581,7 @@ debug_exit_userfunc(expr_node *node, Value *ans, int r, Value *locals, int nargs
|
||||
if (r == OK) {
|
||||
PrintValue(ans, ErrFp);
|
||||
} else {
|
||||
fprintf(ErrFp, "%s", ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s", GetErr(r));
|
||||
}
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
@@ -621,19 +621,19 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
/* Bail if function does not exist */
|
||||
if (!f) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_UNDEF_FUNC], fname);
|
||||
Eprint("%s: `%s'", GetErr(E_UNDEF_FUNC), fname);
|
||||
return E_UNDEF_FUNC;
|
||||
}
|
||||
|
||||
/* Make sure we have the right number of arguments */
|
||||
if (node->num_kids < f->nargs) {
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, ErrMsg[E_2FEW_ARGS]));
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2FEW_ARGS]);
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, GetErr(E_2FEW_ARGS)));
|
||||
Eprint("%s(): %s", f->name, GetErr(E_2FEW_ARGS));
|
||||
return E_2FEW_ARGS;
|
||||
}
|
||||
if (node->num_kids > f->nargs) {
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, ErrMsg[E_2MANY_ARGS]));
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2MANY_ARGS]);
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, GetErr(E_2MANY_ARGS)));
|
||||
Eprint("%s(): %s", f->name, GetErr(E_2MANY_ARGS));
|
||||
return E_2MANY_ARGS;
|
||||
}
|
||||
|
||||
@@ -643,7 +643,7 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
/* Too many args to fit on stack; put on heap */
|
||||
new_locals = malloc(node->num_kids * sizeof(Value));
|
||||
if (!new_locals) {
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, ErrMsg[E_NO_MEM]));
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, GetErr(E_NO_MEM)));
|
||||
return E_NO_MEM;
|
||||
}
|
||||
} else {
|
||||
@@ -694,7 +694,7 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
if (r != OK) {
|
||||
/* We print the error here in order to get the call stack trace */
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
|
||||
if (pushed == OK) pop_call();
|
||||
@@ -850,7 +850,7 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
/* Operator? Evaluate it */
|
||||
r = node->u.operator_func(node, locals, ans, nonconst);
|
||||
if (r != OK) {
|
||||
Eprint("`%s': %s", get_operator_name(node), ErrMsg[r]);
|
||||
Eprint("`%s': %s", get_operator_name(node), GetErr(r));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -1541,7 +1541,7 @@ static int parse_expr_token(DynamicBuffer *buf, char const **in)
|
||||
}
|
||||
(*in)++;
|
||||
} else {
|
||||
Eprint("%s `%c' (did you mean `%c%c'?)", ErrMsg[E_PARSE_ERR], c, c, c);
|
||||
Eprint("%s `%c' (did you mean `%c%c'?)", GetErr(E_PARSE_ERR), c, c, c);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
return OK;
|
||||
@@ -1633,10 +1633,10 @@ static int parse_expr_token(DynamicBuffer *buf, char const **in)
|
||||
|
||||
if (!ISID(c) && c != '$') {
|
||||
if (!c) {
|
||||
Eprint("%s", ErrMsg[E_EOLN]);
|
||||
Eprint("%s", GetErr(E_EOLN));
|
||||
return E_EOLN;
|
||||
}
|
||||
Eprint("%s `%c'", ErrMsg[E_ILLEGAL_CHAR], c);
|
||||
Eprint("%s `%c'", GetErr(E_ILLEGAL_CHAR), c);
|
||||
return E_ILLEGAL_CHAR;
|
||||
}
|
||||
|
||||
@@ -1831,7 +1831,7 @@ static expr_node * parse_function_call(char const **e, int *r, Var *locals, int
|
||||
return free_expr_tree(node);
|
||||
}
|
||||
if (TOKEN_IS(")")) {
|
||||
Eprint("%s `)'", ErrMsg[E_PARSE_ERR]);
|
||||
Eprint("%s `)'", GetErr(E_PARSE_ERR));
|
||||
*r = E_PARSE_ERR;
|
||||
return free_expr_tree(node);
|
||||
}
|
||||
@@ -1859,7 +1859,7 @@ static expr_node * parse_function_call(char const **e, int *r, Var *locals, int
|
||||
if (*r != OK) {
|
||||
if (node->type == N_BUILTIN_FUNC) {
|
||||
f = node->u.builtin_func;
|
||||
Eprint("%s: %s", f->name, ErrMsg[*r]);
|
||||
Eprint("%s: %s", f->name, GetErr(*r));
|
||||
}
|
||||
return free_expr_tree(node);
|
||||
}
|
||||
@@ -1881,7 +1881,7 @@ static int set_constant_value(expr_node *atom)
|
||||
atom->type = N_CONSTANT;
|
||||
|
||||
if (!*s) {
|
||||
Eprint("%s", ErrMsg[E_EOLN]);
|
||||
Eprint("%s", GetErr(E_EOLN));
|
||||
return E_EOLN;
|
||||
}
|
||||
ampm = 0;
|
||||
@@ -1905,15 +1905,15 @@ static int set_constant_value(expr_node *atom)
|
||||
} else if (*s == '\'') { /* It's a literal date */
|
||||
s++;
|
||||
if ((r=ParseLiteralDateOrTime(&s, &dse, &tim)) != 0) {
|
||||
Eprint("%s: %s", ErrMsg[r], DBufValue(&ExprBuf));
|
||||
Eprint("%s: %s", GetErr(r), DBufValue(&ExprBuf));
|
||||
return r;
|
||||
}
|
||||
if (*s != '\'') {
|
||||
if (dse != NO_DATE) {
|
||||
Eprint("%s: %s", ErrMsg[E_BAD_DATE], DBufValue(&ExprBuf));
|
||||
Eprint("%s: %s", GetErr(E_BAD_DATE), DBufValue(&ExprBuf));
|
||||
return E_BAD_DATE;
|
||||
} else {
|
||||
Eprint("%s: %s", ErrMsg[E_BAD_TIME], DBufValue(&ExprBuf));
|
||||
Eprint("%s: %s", GetErr(E_BAD_TIME), DBufValue(&ExprBuf));
|
||||
return E_BAD_TIME;
|
||||
}
|
||||
}
|
||||
@@ -1944,7 +1944,7 @@ static int set_constant_value(expr_node *atom)
|
||||
if (*s == ':' || *s == '.' || *s == TimeSep) { /* Must be a literal time */
|
||||
s++;
|
||||
if (!isdigit(*s)) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_BAD_TIME], DBufValue(&ExprBuf));
|
||||
Eprint("%s: `%s'", GetErr(E_BAD_TIME), DBufValue(&ExprBuf));
|
||||
return E_BAD_TIME;
|
||||
}
|
||||
h = val;
|
||||
@@ -1963,12 +1963,12 @@ static int set_constant_value(expr_node *atom)
|
||||
}
|
||||
}
|
||||
if (*s || h>23 || m>59) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_BAD_TIME], DBufValue(&ExprBuf));
|
||||
Eprint("%s: `%s'", GetErr(E_BAD_TIME), DBufValue(&ExprBuf));
|
||||
return E_BAD_TIME;
|
||||
}
|
||||
if (ampm) {
|
||||
if (h < 1 || h > 12) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_BAD_TIME], DBufValue(&ExprBuf));
|
||||
Eprint("%s: `%s'", GetErr(E_BAD_TIME), DBufValue(&ExprBuf));
|
||||
return E_BAD_TIME;
|
||||
}
|
||||
if (ampm == 'a') {
|
||||
@@ -1987,7 +1987,7 @@ static int set_constant_value(expr_node *atom)
|
||||
}
|
||||
/* Not a time - must be a number */
|
||||
if (*s) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_BAD_NUMBER], DBufValue(&ExprBuf));
|
||||
Eprint("%s: `%s'", GetErr(E_BAD_NUMBER), DBufValue(&ExprBuf));
|
||||
return E_BAD_NUMBER;
|
||||
}
|
||||
atom->u.value.type = INT_TYPE;
|
||||
@@ -1995,7 +1995,7 @@ static int set_constant_value(expr_node *atom)
|
||||
return OK;
|
||||
}
|
||||
atom->u.value.type = ERR_TYPE;
|
||||
Eprint("`%s': %s", DBufValue(&ExprBuf), ErrMsg[E_ILLEGAL_CHAR]);
|
||||
Eprint("`%s': %s", DBufValue(&ExprBuf), GetErr(E_ILLEGAL_CHAR));
|
||||
return E_ILLEGAL_CHAR;
|
||||
}
|
||||
|
||||
@@ -2019,7 +2019,7 @@ static int make_atom(expr_node *atom, Var *locals)
|
||||
atom->u.arg = i;
|
||||
return OK;
|
||||
}
|
||||
v = v->next;
|
||||
v = v->link.next;
|
||||
i++;
|
||||
}
|
||||
if (strlen(s) < SHORT_NAME_BUF) {
|
||||
@@ -2037,7 +2037,7 @@ static int make_atom(expr_node *atom, Var *locals)
|
||||
/* System Variable */
|
||||
if (*(s) == '$' && isalpha(*(s+1))) {
|
||||
if (!FindSysVar(s+1)) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_NOSUCH_VAR], s);
|
||||
Eprint("%s: `%s'", GetErr(E_NOSUCH_VAR), s);
|
||||
return E_NOSUCH_VAR;
|
||||
}
|
||||
if (strlen(s+1) < SHORT_NAME_BUF) {
|
||||
@@ -2117,7 +2117,7 @@ static expr_node *parse_atom(char const **e, int *r, Var *locals, int level)
|
||||
/* Check that it's a valid ID or constant */
|
||||
s = DBufValue(&ExprBuf);
|
||||
if (!*s) {
|
||||
Eprint("%s", ErrMsg[E_EOLN]);
|
||||
Eprint("%s", GetErr(E_EOLN));
|
||||
*r = E_EOLN;
|
||||
return NULL;
|
||||
}
|
||||
@@ -2126,7 +2126,7 @@ static expr_node *parse_atom(char const **e, int *r, Var *locals, int level)
|
||||
*s != '$' &&
|
||||
*s != '"' &&
|
||||
*s != '\'') {
|
||||
Eprint("%s `%c'", ErrMsg[E_ILLEGAL_CHAR], *s);
|
||||
Eprint("%s `%c'", GetErr(E_ILLEGAL_CHAR), *s);
|
||||
*r = E_ILLEGAL_CHAR;
|
||||
return NULL;
|
||||
}
|
||||
@@ -2512,7 +2512,7 @@ expr_node *parse_expression(char const **e, int *r, Var *locals)
|
||||
}
|
||||
putc('\n', ErrFp);
|
||||
if (*r != OK) {
|
||||
fprintf(ErrFp, " => Error: %s\n", ErrMsg[*r]);
|
||||
fprintf(ErrFp, " => Error: %s\n", GetErr(*r));
|
||||
} else {
|
||||
fprintf(ErrFp, " => ");
|
||||
print_expr_tree(node, ErrFp);
|
||||
@@ -3088,10 +3088,10 @@ int DoCoerce(char type, Value *v)
|
||||
/***************************************************************/
|
||||
void print_expr_nodes_stats(void)
|
||||
{
|
||||
fprintf(stderr, " Expression nodes allocated: %d\n", ExprNodesAllocated);
|
||||
fprintf(stderr, "Expression nodes high-water: %d\n", ExprNodesHighWater);
|
||||
fprintf(stderr, " Expression nodes leaked: %d\n", ExprNodesUsed);
|
||||
fprintf(stderr, " Parse level high-water: %d\n", parse_level_high_water);
|
||||
fprintf(ErrFp, " Expression nodes allocated: %d\n", ExprNodesAllocated);
|
||||
fprintf(ErrFp, "Expression nodes high-water: %d\n", ExprNodesHighWater);
|
||||
fprintf(ErrFp, " Expression nodes leaked: %d\n", ExprNodesUsed);
|
||||
fprintf(ErrFp, " Parse level high-water: %d\n", parse_level_high_water);
|
||||
}
|
||||
|
||||
/* Return 1 if a value is "true" for its type, 0 if "false" */
|
||||
|
||||
69
src/files.c
69
src/files.c
@@ -7,7 +7,7 @@
|
||||
/* files. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -519,7 +519,7 @@ static int NextChainedFile(IncludeStruct *i)
|
||||
if (OpenFile(cur->filename) == OK) {
|
||||
return OK;
|
||||
} else {
|
||||
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], cur->filename);
|
||||
Eprint("%s: %s", GetErr(E_CANT_OPEN), cur->filename);
|
||||
}
|
||||
}
|
||||
return E_EOF;
|
||||
@@ -537,7 +537,7 @@ static int PopFile(void)
|
||||
int j;
|
||||
|
||||
if (!Hush && NumIfs) {
|
||||
Eprint("%s", ErrMsg[E_MISS_ENDIF]);
|
||||
Eprint("%s", GetErr(E_MISS_ENDIF));
|
||||
for (j=NumIfs-1; j >=0; j--) {
|
||||
fprintf(ErrFp, "%s(%d): IF without ENDIF\n", FileName, IfLinenos[j]);
|
||||
}
|
||||
@@ -608,16 +608,25 @@ int DoInclude(ParsePtr p, enum TokTypes tok)
|
||||
DBufInit(&buf);
|
||||
DBufInit(&fullname);
|
||||
DBufInit(&path);
|
||||
if ( (r=ParseToken(p, &buf)) ) return r;
|
||||
if ( (r=ParseTokenOrQuotedString(p, &buf)) ) return r;
|
||||
e = VerifyEoln(p);
|
||||
if (e) Eprint("%s", ErrMsg[e]);
|
||||
if (e) Eprint("%s", GetErr(e));
|
||||
|
||||
if (tok == T_IncludeR && *(DBufValue(&buf)) != '/') {
|
||||
if ((tok == T_IncludeR || tok == T_IncludeSys) &&
|
||||
*(DBufValue(&buf)) != '/') {
|
||||
/* Relative include: Include relative to dir
|
||||
containing current file */
|
||||
if (DBufPuts(&path, FileName) != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto bailout;
|
||||
if (tok == T_IncludeR) {
|
||||
if (DBufPuts(&path, FileName) != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto bailout;
|
||||
}
|
||||
} else {
|
||||
if (DBufPuts(&path, SysDir) != OK ||
|
||||
DBufPutc(&path, '/') != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto bailout;
|
||||
}
|
||||
}
|
||||
if (DBufLen(&path) == 0) {
|
||||
s = DBufValue(&buf);
|
||||
@@ -650,9 +659,6 @@ int DoInclude(ParsePtr p, enum TokTypes tok)
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
|
||||
bailout:
|
||||
DBufFree(&buf);
|
||||
DBufFree(&path);
|
||||
@@ -713,8 +719,6 @@ int DoIncludeCmd(ParsePtr p)
|
||||
return r;
|
||||
}
|
||||
DBufFree(&buf);
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -726,6 +730,8 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
size_t l;
|
||||
int r;
|
||||
glob_t glob_buf;
|
||||
struct stat sb;
|
||||
|
||||
DirectoryFilenameChain *dc = CachedDirectoryChains;
|
||||
|
||||
i->chain = NULL;
|
||||
@@ -808,6 +814,16 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
|
||||
/* Add the files to the chain backwards to preserve sort order */
|
||||
for (r=glob_buf.gl_pathc-1; r>=0; r--) {
|
||||
if (stat(glob_buf.gl_pathv[r], &sb) < 0) {
|
||||
/* Couldn't stat the file... fuggedaboutit */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Don't add directories */
|
||||
if (S_ISDIR(sb.st_mode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FilenameChain *ch = malloc(sizeof(FilenameChain));
|
||||
if (!ch) {
|
||||
globfree(&glob_buf);
|
||||
@@ -816,8 +832,6 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
/* TODO: stat the file and only add if it's a plain file and
|
||||
readable by us */
|
||||
ch->filename = StrDup(glob_buf.gl_pathv[r]);
|
||||
if (!ch->filename) {
|
||||
globfree(&glob_buf);
|
||||
@@ -858,7 +872,7 @@ static int IncludeCmd(char const *cmd)
|
||||
|
||||
got_a_fresh_line();
|
||||
clear_callstack();
|
||||
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
if (IStackPtr >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
/* Use "cmd|" as the filename */
|
||||
@@ -895,6 +909,8 @@ static int IncludeCmd(char const *cmd)
|
||||
FCLOSE(fp);
|
||||
}
|
||||
IStackPtr++;
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
|
||||
/* If the file is cached, use it */
|
||||
h = CachedFiles;
|
||||
@@ -931,6 +947,7 @@ static int IncludeCmd(char const *cmd)
|
||||
fp2 = popen(cmd, "r");
|
||||
}
|
||||
if (!fp2) {
|
||||
PopFile();
|
||||
DBufFree(&buf);
|
||||
return E_CANT_OPEN;
|
||||
}
|
||||
@@ -977,7 +994,7 @@ int IncludeFile(char const *fname)
|
||||
|
||||
got_a_fresh_line();
|
||||
clear_callstack();
|
||||
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
if (IStackPtr >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
if (FileName) {
|
||||
@@ -1004,6 +1021,8 @@ int IncludeFile(char const *fname)
|
||||
}
|
||||
|
||||
IStackPtr++;
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
|
||||
#ifdef HAVE_GLOB
|
||||
/* If it's a directory, set up the glob chain here. */
|
||||
@@ -1018,7 +1037,7 @@ int IncludeFile(char const *fname)
|
||||
if (SetupGlobChain(fname, i) == OK) { /* Glob succeeded */
|
||||
if (!i->chain) { /* Oops... no matching files */
|
||||
if (!Hush) {
|
||||
Eprint("%s: %s", fname, ErrMsg[E_NO_MATCHING_REMS]);
|
||||
Eprint("%s: %s", fname, GetErr(E_NO_MATCHING_REMS));
|
||||
}
|
||||
PopFile();
|
||||
return E_NO_MATCHING_REMS;
|
||||
@@ -1032,14 +1051,14 @@ int IncludeFile(char const *fname)
|
||||
if (!OpenFile(fc->filename)) {
|
||||
return OK;
|
||||
}
|
||||
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], fc->filename);
|
||||
Eprint("%s: %s", GetErr(E_CANT_OPEN), fc->filename);
|
||||
RunDisabled = oldRunDisabled;
|
||||
}
|
||||
/* Couldn't open anything... bail */
|
||||
return PopFile();
|
||||
} else {
|
||||
if (!Hush) {
|
||||
Eprint("%s: %s", fname, ErrMsg[E_NO_MATCHING_REMS]);
|
||||
Eprint("%s: %s", fname, GetErr(E_NO_MATCHING_REMS));
|
||||
}
|
||||
}
|
||||
return E_NO_MATCHING_REMS;
|
||||
@@ -1053,7 +1072,7 @@ int IncludeFile(char const *fname)
|
||||
return OK;
|
||||
}
|
||||
RunDisabled = oldRunDisabled;
|
||||
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], fname);
|
||||
Eprint("%s: %s", GetErr(E_CANT_OPEN), fname);
|
||||
/* Ugh! We failed! */
|
||||
PopFile();
|
||||
return E_CANT_OPEN;
|
||||
@@ -1149,6 +1168,12 @@ static int CheckSafety(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CheckSafetyAux(&statbuf)) {
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
|
||||
57
src/funcs.c
57
src/funcs.c
@@ -6,7 +6,7 @@
|
||||
/* expressions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -68,6 +68,7 @@ static int
|
||||
solstice_equinox_for_year(int y, int which);
|
||||
|
||||
/* Function prototypes */
|
||||
static int F_ (func_info *);
|
||||
static int FADawn (func_info *);
|
||||
static int FADusk (func_info *);
|
||||
static int FAbs (func_info *);
|
||||
@@ -210,8 +211,8 @@ static int CacheHebYear, CacheHebMon, CacheHebDay;
|
||||
/* Macro for getting time part of a time or datetime value */
|
||||
#define TIMEPART(x) ((x).type == TIME_TYPE ? (x).v.val : ((x).v.val % MINUTES_PER_DAY))
|
||||
|
||||
#define HASDATE(x) ((x).type == DATE_TYPE || (x).type == DATETIME_TYPE)
|
||||
#define HASTIME(x) ((x).type == TIME_TYPE || (x).type == DATETIME_TYPE)
|
||||
#define HASDATE(x) ((x).type & DATE_TYPE)
|
||||
#define HASTIME(x) ((x).type & TIME_TYPE)
|
||||
|
||||
/* Macro for copying a value while destroying original copy */
|
||||
#define DCOPYVAL(x, y) ( (x) = (y), (y).type = ERR_TYPE )
|
||||
@@ -226,7 +227,7 @@ static int CacheHebYear, CacheHebMon, CacheHebDay;
|
||||
/* The array holding the built-in functions. */
|
||||
BuiltinFunc Func[] = {
|
||||
/* Name minargs maxargs is_constant func newfunc*/
|
||||
|
||||
{ "_", 1, 1, 0, F_, NULL },
|
||||
{ "abs", 1, 1, 1, FAbs, NULL },
|
||||
{ "access", 2, 2, 0, FAccess, NULL },
|
||||
{ "adawn", 0, 1, 0, FADawn, NULL},
|
||||
@@ -372,6 +373,28 @@ static int RetStrVal(char const *s, func_info *info)
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* F_ - look up a string in the translation table */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int F_(func_info *info)
|
||||
{
|
||||
DynamicBuffer translated;
|
||||
int r;
|
||||
|
||||
DBufInit(&translated);
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
r = GetTranslatedStringTryingVariants(ARGSTR(0), &translated);
|
||||
if (!r) {
|
||||
DCOPYVAL(RetVal, ARG(0));
|
||||
return OK;
|
||||
}
|
||||
r = RetStrVal(DBufValue(&translated), info);
|
||||
DBufFree(&translated);
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FStrlen - string length */
|
||||
@@ -1281,10 +1304,10 @@ static int FChoose(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
cur = cur->sibling;
|
||||
}
|
||||
PUT(") => ");
|
||||
PUT(ErrMsg[E_BAD_TYPE]);
|
||||
PUT(GetErr(E_BAD_TYPE));
|
||||
OUT();
|
||||
}
|
||||
Eprint("choose(): %s", ErrMsg[E_BAD_TYPE]);
|
||||
Eprint("choose(): %s", GetErr(E_BAD_TYPE));
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
n = v.v.val;
|
||||
@@ -1802,10 +1825,10 @@ static int FTrigger(func_info *info)
|
||||
|
||||
FromDSE(date, &y, &m, &d);
|
||||
if (tim != NO_TIME) {
|
||||
sprintf(buf, "%d %s %d AT %02d:%02d", d, EnglishMonthName[m], y,
|
||||
sprintf(buf, "%d %s %d AT %02d:%02d", d, MonthName[m], y,
|
||||
tim/60, tim%60);
|
||||
} else {
|
||||
sprintf(buf, "%d %s %d", d, EnglishMonthName[m], y);
|
||||
sprintf(buf, "%d %s %d", d, MonthName[m], y);
|
||||
}
|
||||
return RetStrVal(buf, info);
|
||||
}
|
||||
@@ -1995,7 +2018,7 @@ static int FIif(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
cur = cur->sibling;
|
||||
}
|
||||
PUT(") => ");
|
||||
PUT(ErrMsg[E_IIF_ODD]);
|
||||
PUT(GetErr(E_IIF_ODD));
|
||||
OUT();
|
||||
}
|
||||
return E_IIF_ODD;
|
||||
@@ -2153,7 +2176,7 @@ static int FTypeof(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FLanguage(func_info *info)
|
||||
{
|
||||
return RetStrVal(L_LANGNAME, info);
|
||||
return RetStrVal("English", info);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -2734,7 +2757,7 @@ static int SunStuff(int rise, double cosz, int dse)
|
||||
/* Get offset from UTC */
|
||||
if (CalculateUTC) {
|
||||
if (CalcMinsFromUTC(dse, 12*60, &mins, NULL)) {
|
||||
Eprint(ErrMsg[E_MKTIME_PROBLEM]);
|
||||
Eprint(GetErr(E_MKTIME_PROBLEM));
|
||||
return NO_TIME;
|
||||
}
|
||||
} else mins = MinsFromUTC;
|
||||
@@ -2756,7 +2779,7 @@ static int SunStuff(int rise, double cosz, int dse)
|
||||
/* Mean anomaly of sun starting from 1 Jan 1990 */
|
||||
/* NOTE: This assumes that BASE = 1990!!! */
|
||||
#if BASE != 1990
|
||||
#error Sun calculations assume a BASE of 1990!
|
||||
#warning Sun calculations assume a BASE of 1990!
|
||||
#endif
|
||||
t = 0.9856002585 * t;
|
||||
M = t + 357.828757; /* In degrees */
|
||||
@@ -2839,6 +2862,10 @@ static int FSun(int rise, func_info *info)
|
||||
double cosz = 0.0;
|
||||
int r;
|
||||
|
||||
/* Sun calculations assume BASE is 1990 */
|
||||
if (BASE != 1990) {
|
||||
return E_SWERR;
|
||||
}
|
||||
if (rise == 0 || rise == 1) {
|
||||
/* Sunrise and sunset : cos(90 degrees + 50 arcminutes) */
|
||||
cosz = -0.01454389765158243;
|
||||
@@ -3238,11 +3265,11 @@ static int setenv(char const *varname, char const *val, int overwrite)
|
||||
{
|
||||
static char tzbuf[256];
|
||||
if (strcmp(varname, "TZ")) {
|
||||
fprintf(stderr, "built-in setenv can only be used with TZ\n");
|
||||
fprintf(ErrFp, "built-in setenv can only be used with TZ\n");
|
||||
abort();
|
||||
}
|
||||
if (!overwrite) {
|
||||
fprintf(stderr, "built-in setenv must have overwrite=1\n");
|
||||
fprintf(ErrFp, "built-in setenv must have overwrite=1\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -3260,7 +3287,7 @@ static void unsetenv(char const *varname)
|
||||
{
|
||||
static char tzbuf[8];
|
||||
if (strcmp(varname, "TZ")) {
|
||||
fprintf(stderr, "built-in unsetenv can only be used with TZ\n");
|
||||
fprintf(ErrFp, "built-in unsetenv can only be used with TZ\n");
|
||||
abort();
|
||||
}
|
||||
sprintf(tzbuf, "%s", varname);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/* globals.h and err.h */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <stdio.h> /* For definition of FILE - sigh! */
|
||||
#include "types.h"
|
||||
#include "custom.h"
|
||||
#include "lang.h"
|
||||
#define MK_GLOBALS 1
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
124
src/globals.h
124
src/globals.h
@@ -7,7 +7,7 @@
|
||||
/* MK_GLOBALS. Also contains useful macro definitions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -30,7 +30,6 @@
|
||||
EXTERN FILE *ErrFp;
|
||||
|
||||
#include "dynbuf.h"
|
||||
#include "lang.h"
|
||||
|
||||
#define MAX_TRUSTED_USERS 20
|
||||
|
||||
@@ -69,6 +68,7 @@ EXTERN INIT( int PsCal, 0);
|
||||
EXTERN INIT( int CalWidth, 80);
|
||||
EXTERN INIT( int CalWeeks, 0);
|
||||
EXTERN INIT( int CalMonths, 0);
|
||||
EXTERN INIT( char const *CalType, "none");
|
||||
EXTERN INIT( int Hush, 0);
|
||||
EXTERN INIT( int NextMode, 0);
|
||||
EXTERN INIT( int InfiniteDelta, 0);
|
||||
@@ -179,62 +179,17 @@ EXTERN INIT( int SuppressImplicitRemWarnings, 0);
|
||||
extern int NumFullOmits, NumPartialOmits;
|
||||
|
||||
/* List of months */
|
||||
EXTERN char *EnglishMonthName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"}
|
||||
#endif
|
||||
;
|
||||
|
||||
#if LANG == ENGLISH
|
||||
#define MonthName EnglishMonthName
|
||||
#else
|
||||
EXTERN char *MonthName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {L_JAN, L_FEB, L_MAR, L_APR, L_MAY, L_JUN,
|
||||
L_JUL, L_AUG, L_SEP, L_OCT, L_NOV, L_DEC}
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
|
||||
EXTERN char *DynamicMonthName[]
|
||||
#ifdef MK_GLOBALS
|
||||
#if LANG == ENGLISH
|
||||
= {"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"}
|
||||
#else
|
||||
= {L_JAN, L_FEB, L_MAR, L_APR, L_MAY, L_JUN,
|
||||
L_JUL, L_AUG, L_SEP, L_OCT, L_NOV, L_DEC}
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
EXTERN char *EnglishDayName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
|
||||
"Saturday", "Sunday"}
|
||||
#endif
|
||||
;
|
||||
|
||||
#if LANG == ENGLISH
|
||||
#define DayName EnglishDayName
|
||||
#else
|
||||
EXTERN char *DayName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {L_MONDAY, L_TUESDAY, L_WEDNESDAY, L_THURSDAY, L_FRIDAY,
|
||||
L_SATURDAY, L_SUNDAY}
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
|
||||
EXTERN char *DynamicDayName []
|
||||
#ifdef MK_GLOBALS
|
||||
#if LANG == ENGLISH
|
||||
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
|
||||
"Saturday", "Sunday"}
|
||||
#else
|
||||
= {L_MONDAY, L_TUESDAY, L_WEDNESDAY, L_THURSDAY, L_FRIDAY,
|
||||
L_SATURDAY, L_SUNDAY}
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
|
||||
@@ -256,84 +211,15 @@ EXTERN int MonthIndex[2][12]
|
||||
#endif
|
||||
;
|
||||
|
||||
EXTERN char *DynamicAgo
|
||||
#ifdef MK_GLOBALS
|
||||
= L_AGO
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicAm
|
||||
#ifdef MK_GLOBALS
|
||||
= L_AM
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicAnd
|
||||
#ifdef MK_GLOBALS
|
||||
= L_AND
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicAt
|
||||
#ifdef MK_GLOBALS
|
||||
= L_AT
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicFromnow
|
||||
#ifdef MK_GLOBALS
|
||||
= L_FROMNOW
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicHour
|
||||
#ifdef MK_GLOBALS
|
||||
= L_HOUR
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicHplu
|
||||
#ifdef MK_GLOBALS
|
||||
= L_HPLU
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicIs
|
||||
#ifdef MK_GLOBALS
|
||||
= L_IS
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicMinute
|
||||
#ifdef MK_GLOBALS
|
||||
= L_MINUTE
|
||||
= "s"
|
||||
#endif
|
||||
;
|
||||
|
||||
EXTERN char *DynamicMplu
|
||||
#ifdef MK_GLOBALS
|
||||
= L_MPLU
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicNow
|
||||
#ifdef MK_GLOBALS
|
||||
= L_NOW
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicOn
|
||||
#ifdef MK_GLOBALS
|
||||
= L_ON
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicPm
|
||||
#ifdef MK_GLOBALS
|
||||
= L_PM
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicToday
|
||||
#ifdef MK_GLOBALS
|
||||
= L_TODAY
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicTomorrow
|
||||
#ifdef MK_GLOBALS
|
||||
= L_TOMORROW
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicWas
|
||||
#ifdef MK_GLOBALS
|
||||
= L_WAS
|
||||
= "s"
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
428
src/hashtab.c
Normal file
428
src/hashtab.c
Normal file
@@ -0,0 +1,428 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HASHTAB_STATS.C */
|
||||
/* */
|
||||
/* Implementation of hash table. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/**
|
||||
* \file hashtab.c
|
||||
*
|
||||
* \brief Implementation of hash table
|
||||
*
|
||||
* A hash table manages an array of buckets, each of which is the
|
||||
* head of a singly-linked list. A given hash table can store items
|
||||
* of a given type. The items in a hash table must be structs, and one
|
||||
* of their members must be a struct hash_link object. For example,
|
||||
* a hash table containing integers might have the hash objects
|
||||
* defined as:
|
||||
*
|
||||
* struct int_object {
|
||||
* int value;
|
||||
* struct hash_link link;
|
||||
* };
|
||||
*
|
||||
* When you initialize the hash table, you pass in the offset to the hash
|
||||
* link. For example, to initialize a hash table designed to hold
|
||||
* int_objects, you'd do something like:
|
||||
*
|
||||
* unsigned int hash_int_obj(void *x) {
|
||||
* return (unsigned int) ((int_object *) x)->value;
|
||||
* }
|
||||
* int compare_int_obj(void *a, void *b) {
|
||||
* return ((int_object *)a)->value - ((int_object *)b)->value;
|
||||
* }
|
||||
*
|
||||
* hash_table tab;
|
||||
* hash_table_init(&tab, offsetof(struct int_object, link), hash_int_obj, compare_int_obj);
|
||||
*
|
||||
* An item can be in multiple hash tables at once; just declare multiple
|
||||
* hash_link members and pass in the appropriate offset to each hash
|
||||
* table.
|
||||
*/
|
||||
|
||||
#include "hashtab.h"
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* The number of buckets should be a prime number.
|
||||
* Use these numbers of buckets to grow or shrink the hash table.
|
||||
* Yes, OK, the list below is probably excessive.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief A list of prime numbers from 17 to about 1.4 billion, approximately
|
||||
* doubling with each successive number.
|
||||
*
|
||||
* These are used as choices for the number of hash buckets in the table
|
||||
*/
|
||||
static size_t bucket_choices[] = {
|
||||
7, 17, 37, 79, 163, 331, 673, 1361, 2729, 5471, 10949, 21911, 43853, 87719,
|
||||
175447, 350899, 701819, 1403641, 2807303, 5614657, 11229331, 22458671,
|
||||
44917381, 89834777, 179669557, 359339171, 718678369, 1437356741 };
|
||||
|
||||
#define NUM_BUCKET_CHOICES (sizeof(bucket_choices) / sizeof(bucket_choices[0]))
|
||||
|
||||
#define NUM_BUCKETS(t) (bucket_choices[t->bucket_choice_index])
|
||||
|
||||
#define LINK(t, p) ( (struct hash_link *) (( ((char *) p) + t->hash_link_offset)) )
|
||||
|
||||
/**
|
||||
* \brief Initialize a hash table
|
||||
*
|
||||
* Initializes a hash table. A given hash table can contain a collection
|
||||
* of items, all of which must be the same. An item in a hash table is
|
||||
* a structure and one of the elements in the structure must be a
|
||||
* struct hash_link object. For example, if you are storing a collection
|
||||
* of integers in a hash table, your item might look like this:
|
||||
*
|
||||
* struct item {
|
||||
* int value;
|
||||
* struct hash_link link;
|
||||
* };
|
||||
*
|
||||
* \param t Pointer to a hash_table object
|
||||
* \param link_offset The offset to the struct hash_link object within the object being put in the hash table. In the example above, it would be
|
||||
* offsetof(struct item, link)
|
||||
* \param hashfunc A pointer to a function that computes a hash given a pointer to an object. This function must return an unsigned int.
|
||||
* \param compare A pointer to a function that compares two objects. It must
|
||||
* return 0 if they compare equal and non-zero if they do not.
|
||||
*
|
||||
* \return 0 on success, -1 on failure (and errno is set appropriately)
|
||||
*/
|
||||
int
|
||||
hash_table_init(hash_table *t,
|
||||
size_t link_offset,
|
||||
unsigned int (*hashfunc)(void *x),
|
||||
int (*compare)(void *a, void *b))
|
||||
{
|
||||
t->bucket_choice_index = 0;
|
||||
t->num_entries = 0;
|
||||
t->hash_link_offset = link_offset;
|
||||
t->hashfunc = hashfunc;
|
||||
t->compare = compare;
|
||||
t->buckets = malloc(sizeof(void *) * bucket_choices[0]);
|
||||
t->num_growths = 0;
|
||||
t->num_shrinks = 0;
|
||||
if (!t->buckets) {
|
||||
return -1;
|
||||
}
|
||||
for (size_t i=0; i<bucket_choices[0]; i++) {
|
||||
t->buckets[i] = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Free memory used by a hash table
|
||||
*
|
||||
* \param t Pointer to a hash_table object
|
||||
*/
|
||||
void
|
||||
hash_table_free(hash_table *t)
|
||||
{
|
||||
free(t->buckets);
|
||||
t->buckets = NULL;
|
||||
t->bucket_choice_index = -1;
|
||||
t->num_entries = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the number of items in a hash table
|
||||
*
|
||||
* \param t Pointer to a hash_table object
|
||||
*
|
||||
* \return The number of items in the hash table
|
||||
*/
|
||||
size_t
|
||||
hash_table_num_entries(hash_table *t)
|
||||
{
|
||||
return t->num_entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the number of buckets in a hash table
|
||||
*
|
||||
* \param t Pointer to a hash_table object
|
||||
*
|
||||
* \return The number of buckets in the hash table
|
||||
*/
|
||||
size_t
|
||||
hash_table_num_buckets(hash_table *t)
|
||||
{
|
||||
if (t->bucket_choice_index >= NUM_BUCKET_CHOICES) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return NUM_BUCKETS(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the length of the i'th bucket chain
|
||||
*
|
||||
* If i >= num_buckets, returns (size_t) -1
|
||||
*
|
||||
* \param t Pointer to a hash_table object
|
||||
* \param i The bucket whose length we want (0 to num_buckets-1)
|
||||
* \return The length of the i'th bucket chain
|
||||
*/
|
||||
size_t
|
||||
hash_table_chain_len(hash_table *t, size_t i)
|
||||
{
|
||||
if (i >= hash_table_num_buckets(t)) {
|
||||
return (size_t) -1;
|
||||
}
|
||||
size_t len = 0;
|
||||
void *ptr = t->buckets[i];
|
||||
while(ptr) {
|
||||
len++;
|
||||
ptr = LINK(t, ptr)->next;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Resize a hash table
|
||||
*
|
||||
* Resizes (either grows or shrinks) a hash table's bucket array
|
||||
*
|
||||
* \param t Pointer to a hash_table object
|
||||
* \param dir Must be either 1 (to increase the bucket array size) or
|
||||
* -1 (to decrease it).
|
||||
* \return 0 on success, non-zero if resizing fails. NOTE: Currently, resizing
|
||||
* cannot fail; if we fail to allocate memory for the new bucket array,
|
||||
* we just keep the existing array. This behaviour may change in future.
|
||||
*/
|
||||
static int
|
||||
hash_table_resize(hash_table *t, int dir)
|
||||
{
|
||||
if (dir != 1 && dir != -1) {
|
||||
return 0;
|
||||
}
|
||||
if ((dir == -1 && t->bucket_choice_index == 0) ||
|
||||
(dir == 1 && t->bucket_choice_index == NUM_BUCKET_CHOICES-1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t num_old_buckets = bucket_choices[t->bucket_choice_index];
|
||||
size_t num_new_buckets = bucket_choices[t->bucket_choice_index + dir];
|
||||
|
||||
void **new_buckets = malloc(sizeof(void *) * num_new_buckets);
|
||||
if (!new_buckets) {
|
||||
/* Out of memory... just don't resize? */
|
||||
return 0;
|
||||
}
|
||||
if (dir == 1) {
|
||||
t->num_growths++;
|
||||
} else {
|
||||
t->num_shrinks++;
|
||||
}
|
||||
for (size_t j=0; j<num_new_buckets; j++) {
|
||||
new_buckets[j] = NULL;
|
||||
}
|
||||
|
||||
/* Move everything from the old buckets into the new */
|
||||
for (size_t i=0; i<num_old_buckets; i++) {
|
||||
void *p = t->buckets[i];
|
||||
while(p) {
|
||||
struct hash_link *l = LINK(t, p);
|
||||
void *nxt = l->next;
|
||||
size_t j = l->hashval % num_new_buckets;
|
||||
l->next = new_buckets[j];
|
||||
new_buckets[j] = p;
|
||||
p = nxt;
|
||||
}
|
||||
}
|
||||
free(t->buckets);
|
||||
t->buckets = new_buckets;
|
||||
t->bucket_choice_index += dir;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Insert an item into a hash table
|
||||
*
|
||||
* Inserts an item into a hash table. The item MUST NOT be freed as
|
||||
* long as it is in a hash table
|
||||
*
|
||||
* \param t Pointer to a hash_table object
|
||||
* \param item Pointer to the item to insert
|
||||
*
|
||||
* \return 0 on success, -1 on failure (and errno is set appropriately)
|
||||
*/
|
||||
int
|
||||
hash_table_insert(hash_table *t, void *item)
|
||||
{
|
||||
if (!item) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int v = t->hashfunc(item);
|
||||
|
||||
struct hash_link *l = LINK(t, item);
|
||||
l->hashval = v;
|
||||
|
||||
v = v % NUM_BUCKETS(t);
|
||||
|
||||
l->next = t->buckets[v];
|
||||
t->buckets[v] = item;
|
||||
t->num_entries++;
|
||||
|
||||
/* Grow table for load factor > 2 */
|
||||
if (t->bucket_choice_index < NUM_BUCKET_CHOICES-1 &&
|
||||
t->num_entries > 2 * NUM_BUCKETS(t)) {
|
||||
return hash_table_resize(t, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Find an item in a hash table
|
||||
*
|
||||
* \param t Pointer to a hash_table object
|
||||
* \param candidate Pointer to an object to be sought in the table
|
||||
*
|
||||
* \return A pointer to the object if one that matches candidate is found. NULL if not found
|
||||
*/
|
||||
void *
|
||||
hash_table_find(hash_table *t, void *candidate)
|
||||
{
|
||||
if (!candidate) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int v = t->hashfunc(candidate);
|
||||
|
||||
void *ptr = t->buckets[v % NUM_BUCKETS(t)];
|
||||
|
||||
while(ptr) {
|
||||
if (!t->compare(candidate, ptr)) {
|
||||
return ptr;
|
||||
}
|
||||
ptr = LINK(t, ptr)->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Delete an item from a hash table
|
||||
*
|
||||
* \param t Pointer to a hash_table object
|
||||
* \param candidate Pointer to an object that is in the table and must be removed from it
|
||||
* \param resize_ok If non-zero, then it's OK to resize the hash table.
|
||||
*
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int
|
||||
hash_table_delete_helper(hash_table *t, void *item, int resize_ok)
|
||||
{
|
||||
if (!item) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct hash_link *l = LINK(t, item);
|
||||
unsigned int v = l->hashval;
|
||||
|
||||
v = v % NUM_BUCKETS(t);
|
||||
|
||||
if (t->buckets[v] == item) {
|
||||
t->buckets[v] = l->next;
|
||||
t->num_entries--;
|
||||
if (resize_ok) {
|
||||
/* Shrink table for load factor < 1 */
|
||||
if (t->bucket_choice_index > 0 &&
|
||||
t->num_entries < NUM_BUCKETS(t) / 2) {
|
||||
return hash_table_resize(t, -1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *ptr = t->buckets[v];
|
||||
while(ptr) {
|
||||
struct hash_link *l2 = LINK(t, ptr);
|
||||
if (l2->next == item) {
|
||||
l2->next = l->next;
|
||||
t->num_entries--;
|
||||
/* Shrink table for load factor < 1 */
|
||||
if (resize_ok) {
|
||||
if (t->bucket_choice_index > 0 &&
|
||||
t->num_entries < NUM_BUCKETS(t) / 2) {
|
||||
return hash_table_resize(t, -1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ptr = l2->next;
|
||||
}
|
||||
|
||||
/* Item not found in hash table */
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hash_table_delete(hash_table *t, void *item)
|
||||
{
|
||||
return hash_table_delete_helper(t, item, 1);
|
||||
}
|
||||
|
||||
int
|
||||
hash_table_delete_no_resize(hash_table *t, void *item)
|
||||
{
|
||||
return hash_table_delete_helper(t, item, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Iterate to the next item in a hash table
|
||||
*
|
||||
* Acts as an iterator. Given a pointer to an item in the hash
|
||||
* table, returns the next item, or NULL if no more items. If the
|
||||
* existing-item pointer is supplied as NULL, returns a pointer to the
|
||||
* first item in the hash table. You can therefore iterate across the
|
||||
* hash table like this*
|
||||
*
|
||||
* void *item = NULL;
|
||||
* while ( (item = hash_table_next(&table, item) ) != NULL) {
|
||||
* // Do something with item
|
||||
* }
|
||||
*
|
||||
* NOTE that you MUST NOT modify the hash table while iterating over it.
|
||||
*
|
||||
* \param t Pointer to a hash_table object
|
||||
* \param cur The current item. Supply as NULL to get the first item
|
||||
*
|
||||
* \return A pointer to the next item in the hash table, or NULL if there
|
||||
* are no more items
|
||||
*/
|
||||
void *
|
||||
hash_table_next(hash_table *t, void *cur)
|
||||
{
|
||||
size_t n_buckets = NUM_BUCKETS(t);
|
||||
|
||||
size_t start_bucket = 0;
|
||||
if (cur) {
|
||||
struct hash_link *l = LINK(t, cur);
|
||||
if (l->next) {
|
||||
return l->next;
|
||||
}
|
||||
/* End of this chain; start searching at the next bucket */
|
||||
start_bucket = (l->hashval % n_buckets) + 1;
|
||||
}
|
||||
|
||||
for (size_t i=start_bucket; i<n_buckets; i++) {
|
||||
if (t->buckets[i]) {
|
||||
return t->buckets[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
89
src/hashtab.h
Normal file
89
src/hashtab.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HASHTAB.H */
|
||||
/* */
|
||||
/* Header file for hash-table related functions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* For size_t */
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* \brief A structure for holding hash table chain links.
|
||||
*
|
||||
* This structure is embedded in a container structure to make up
|
||||
* a hash table entry
|
||||
*/
|
||||
struct hash_link {
|
||||
void *next; /**< Link to next item in the chain */
|
||||
unsigned int hashval; /**< Cached hash function value */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A hash table
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int bucket_choice_index; /**< Index into array of possible bucket counts */
|
||||
size_t num_growths; /**< How many times have we grown the hash table? */
|
||||
size_t num_shrinks; /**< How many times have we grown the hash table? */
|
||||
size_t num_entries; /**< Number of entries in the hash table */
|
||||
size_t hash_link_offset; /**< Offset of the struct hash_link in the container */
|
||||
void **buckets; /**< Array of buckets */
|
||||
unsigned int (*hashfunc)(void *x); /**< Pointer to the hashing function */
|
||||
int (*compare)(void *a, void *b); /**< Pointer to the comparison function */
|
||||
} hash_table;
|
||||
|
||||
/**
|
||||
* \brief Data type to hold statistics about a hash table
|
||||
*/
|
||||
struct hash_table_stats {
|
||||
size_t num_entries; /**< Number of items in the hash table */
|
||||
size_t num_buckets; /**< Number of buckets in the hash table */
|
||||
size_t num_nonempty_buckets; /**< Number of non-emptry buckets */
|
||||
size_t max_len; /**< Length of longest chain in the hash table */
|
||||
size_t min_len; /**< Length of the shortest chain in the hash table */
|
||||
size_t num_growths; /**< How many times have we grown the hash table? */
|
||||
size_t num_shrinks; /**< How many times have we grown the hash table? */
|
||||
double avg_len; /**< Average chain length */
|
||||
double avg_nonempty_len; /**< Average chain length of non-empty bucket */
|
||||
double stddev; /**< Standard deviation of chain lengths */
|
||||
};
|
||||
|
||||
int hash_table_init(hash_table *t,
|
||||
size_t link_offset,
|
||||
unsigned int (*hashfunc)(void *x),
|
||||
int (*compare)(void *a, void *b));
|
||||
void hash_table_free(hash_table *t);
|
||||
size_t hash_table_num_entries(hash_table *t);
|
||||
size_t hash_table_num_buckets(hash_table *t);
|
||||
size_t hash_table_chain_len(hash_table *t, size_t i);
|
||||
int hash_table_insert(hash_table *t, void *item);
|
||||
void *hash_table_find(hash_table *t, void *candidate);
|
||||
int hash_table_delete(hash_table *t, void *item);
|
||||
int hash_table_delete_no_resize(hash_table *t, void *item);
|
||||
void *hash_table_next(hash_table *t, void *cur);
|
||||
void hash_table_dump_stats(hash_table *t, FILE *fp);
|
||||
void hash_table_get_stats(hash_table *t, struct hash_table_stats *stat);
|
||||
|
||||
/**
|
||||
* \brief Iterate over all items in a hash table
|
||||
*
|
||||
* This macro iterates over all items in a hash table. Here is an
|
||||
* example of how to use it:
|
||||
*
|
||||
* hash_table tab;
|
||||
* void *item;
|
||||
* hash_table_for_each(item, &tab) {
|
||||
* // Do something with item
|
||||
* }
|
||||
*/
|
||||
#define hash_table_for_each(item, t) \
|
||||
for ((item) = hash_table_next((t), NULL); \
|
||||
(item); \
|
||||
(item) = hash_table_next((t), (item)))
|
||||
|
||||
99
src/hashtab_stats.c
Normal file
99
src/hashtab_stats.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HASHTAB_STATS.C */
|
||||
/* */
|
||||
/* Utility function to print hash table stats. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/**
|
||||
* \file hashtab_stats.c
|
||||
* \brief Obtain or print statistics about a hash table
|
||||
*
|
||||
* NOTE: Use of any of the functions in this file will require linking
|
||||
* with the math library to pull in the sqrt() function.
|
||||
*/
|
||||
|
||||
#include "hashtab.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* \brief Dump hash table statistics to a stdio FILE
|
||||
*
|
||||
* \param t A pointer to a hash_table object
|
||||
* \param fp A stdio file pointer that is writable
|
||||
*/
|
||||
void
|
||||
hash_table_dump_stats(hash_table *t, FILE *fp)
|
||||
{
|
||||
struct hash_table_stats stat;
|
||||
hash_table_get_stats(t, &stat);
|
||||
fprintf(fp, " Entries: %lu; Buckets: %lu; Non-empty Buckets: %lu\n",
|
||||
(unsigned long) stat.num_entries,
|
||||
(unsigned long) stat.num_buckets,
|
||||
(unsigned long) stat.num_nonempty_buckets);
|
||||
fprintf(fp, " Maxlen: %lu; Minlen: %lu; Avglen: %.3f; Stddev: %.3f; Avg nonempty len: %.3f\n",
|
||||
(unsigned long) stat.max_len,
|
||||
(unsigned long) stat.min_len,
|
||||
stat.avg_len, stat.stddev, stat.avg_nonempty_len);
|
||||
fprintf(fp, " Growths: %lu; Shrinks: %lu\n", (unsigned long) stat.num_growths, (unsigned long) stat.num_shrinks);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Obtain hash table statistics
|
||||
*
|
||||
* This function fills in the elements of a struct hash_table_stats object
|
||||
* with hash table statistics.
|
||||
*
|
||||
* \param t A pointer to a hash_table object
|
||||
* \param stat A pointer to a hash_table_stats object that will be filled in
|
||||
*/
|
||||
void
|
||||
hash_table_get_stats(hash_table *t, struct hash_table_stats *stat)
|
||||
{
|
||||
size_t n = hash_table_num_buckets(t);
|
||||
size_t max_len = 0;
|
||||
size_t min_len = 1000000000;
|
||||
|
||||
stat->num_buckets = n;
|
||||
stat->num_entries = hash_table_num_entries(t);
|
||||
stat->max_len = 0;
|
||||
stat->min_len = 0;
|
||||
stat->avg_len = 0.0;
|
||||
stat->stddev = 0.0;
|
||||
stat->num_nonempty_buckets = 0;
|
||||
stat->avg_nonempty_len = 0.0;
|
||||
stat->num_growths = t->num_growths;
|
||||
stat->num_shrinks = t->num_shrinks;
|
||||
double sum = 0.0;
|
||||
double sumsq = 0.0;
|
||||
|
||||
if (n == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i=0; i<n; i++) {
|
||||
size_t c = hash_table_chain_len(t, i);
|
||||
if (c != 0) {
|
||||
stat->num_nonempty_buckets++;
|
||||
}
|
||||
sum += (double) c;
|
||||
sumsq += (double) c * (double) c;
|
||||
if (c > max_len) max_len = c;
|
||||
if (c < min_len) min_len = c;
|
||||
}
|
||||
double avg_len = sum / (double) n;
|
||||
double stddev = sqrt( (sumsq / (double) n) - (avg_len * avg_len) );
|
||||
if (stat->num_nonempty_buckets > 0) {
|
||||
stat->avg_nonempty_len = sum / (double) stat->num_nonempty_buckets;
|
||||
}
|
||||
stat->max_len = max_len;
|
||||
stat->min_len = min_len;
|
||||
stat->avg_len = avg_len;
|
||||
stat->stddev = stddev;
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Support for the Hebrew calendar */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/* Derived from code written by Amos Shapir in 1978; revised */
|
||||
@@ -474,7 +474,7 @@ int ComputeJahr(int y, int m, int d, int *ans)
|
||||
}
|
||||
|
||||
if (d > monlen[m]) {
|
||||
Eprint("%d %s %d: %s", d, HebMonthNames[m], y, ErrMsg[E_BAD_HEBDATE]);
|
||||
Eprint("%d %s %d: %s", d, HebMonthNames[m], y, GetErr(E_BAD_HEBDATE));
|
||||
return E_BAD_HEBDATE;
|
||||
}
|
||||
|
||||
|
||||
103
src/init.c
103
src/init.c
@@ -7,7 +7,7 @@
|
||||
/* in normal mode. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -149,7 +149,7 @@ static char const *DefaultFilename(void)
|
||||
|
||||
s = getenv("HOME");
|
||||
if (!s) {
|
||||
fprintf(stderr, "HOME environment variable not set. Unable to determine reminder file.\n");
|
||||
fprintf(ErrFp, "HOME environment variable not set. Unable to determine reminder file.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
DBufPuts(&default_filename_buf, s);
|
||||
@@ -179,6 +179,14 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
dse = NO_DATE;
|
||||
|
||||
/* Initialize variable hash table */
|
||||
InitVars();
|
||||
|
||||
/* Initialize user-defined functions hash table */
|
||||
InitUserFunctions();
|
||||
|
||||
InitTranslationTable();
|
||||
|
||||
/* If stdout is a terminal, initialize $FormWidth to terminal width-8,
|
||||
but clamp to [20, 500] */
|
||||
InitCalWidthAndFormWidth(STDOUT_FILENO);
|
||||
@@ -188,7 +196,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
DBufInit(&LineBuffer);
|
||||
DBufInit(&ExprBuf);
|
||||
|
||||
DBufPuts(&Banner, L_BANNER);
|
||||
DBufPuts(&Banner, "Reminders for %w, %d%s %m, %y%o:");
|
||||
|
||||
PurgeFP = NULL;
|
||||
|
||||
@@ -208,7 +216,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
RealToday = SystemDate(&CurYear, &CurMon, &CurDay);
|
||||
if (RealToday < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_SYS_DATE], BASE);
|
||||
fprintf(ErrFp, GetErr(M_BAD_SYS_DATE), BASE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
DSEToday = RealToday;
|
||||
@@ -229,7 +237,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
InvokedAsRem = 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Invoked with a NULL argv[0]; bailing because that's just plain bizarre.\n");
|
||||
fprintf(ErrFp, "Invoked with a NULL argv[0]; bailing because that's just plain bizarre.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -493,9 +501,11 @@ void InitRemind(int argc, char const *argv[])
|
||||
break;
|
||||
}
|
||||
if (weeks) {
|
||||
CalType = "weekly";
|
||||
PARSENUM(CalWeeks, arg);
|
||||
if (!CalWeeks) CalWeeks = 1;
|
||||
} else {
|
||||
CalType = "monthly";
|
||||
PARSENUM(CalMonths, arg);
|
||||
if (!CalMonths) CalMonths = 1;
|
||||
}
|
||||
@@ -520,9 +530,11 @@ void InitRemind(int argc, char const *argv[])
|
||||
break;
|
||||
}
|
||||
if (weeks) {
|
||||
CalType = "weekly";
|
||||
PARSENUM(CalWeeks, arg);
|
||||
if (!CalWeeks) CalWeeks = 1;
|
||||
} else {
|
||||
CalType = "monthly";
|
||||
PARSENUM(CalMonths, arg);
|
||||
if (!CalMonths) CalMonths = 1;
|
||||
}
|
||||
@@ -533,10 +545,14 @@ void InitRemind(int argc, char const *argv[])
|
||||
DoSimpleCalendar = 1;
|
||||
IgnoreOnce = 1;
|
||||
PsCal = PSCAL_LEVEL1;
|
||||
weeks = 0;
|
||||
while (*arg == 'a' || *arg == 'A' ||
|
||||
*arg == 'q' || *arg == 'Q' ||
|
||||
*arg == '+' ||
|
||||
*arg == 'p' || *arg == 'P') {
|
||||
if (*arg == 'a' || *arg == 'A') {
|
||||
if (*arg == '+') {
|
||||
weeks = 1;
|
||||
} else if (*arg == 'a' || *arg == 'A') {
|
||||
DoSimpleCalDelta = 1;
|
||||
} else if (*arg == 'p' || *arg == 'P') {
|
||||
/* JSON interchange formats always include
|
||||
@@ -552,8 +568,16 @@ void InitRemind(int argc, char const *argv[])
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
PARSENUM(CalMonths, arg);
|
||||
if (!CalMonths) CalMonths = 1;
|
||||
if (weeks) {
|
||||
CalType = "weekly";
|
||||
PARSENUM(CalWeeks, arg);
|
||||
if (!CalWeeks) CalWeeks = 1;
|
||||
PsCal = PSCAL_LEVEL3;
|
||||
} else {
|
||||
CalType = "monthly";
|
||||
PARSENUM(CalMonths, arg);
|
||||
if (!CalMonths) CalMonths = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
@@ -569,7 +593,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
/* -wt means get width from /dev/tty */
|
||||
ttyfd = open("/dev/tty", O_RDONLY);
|
||||
if (ttyfd < 0) {
|
||||
fprintf(stderr, "%s: `-wt': Cannot open /dev/tty: %s\n",
|
||||
fprintf(ErrFp, "%s: `-wt': Cannot open /dev/tty: %s\n",
|
||||
argv[0], strerror(errno));
|
||||
} else {
|
||||
InitCalWidthAndFormWidth(ttyfd);
|
||||
@@ -610,6 +634,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
while (*arg) {
|
||||
switch(*arg++) {
|
||||
case 's': case 'S': DebugFlag |= DB_PARSE_EXPR; break;
|
||||
case 'h': case 'H': DebugFlag |= DB_HASHSTATS; break;
|
||||
case 'e': case 'E': DebugFlag |= DB_ECHO_LINE; break;
|
||||
case 'x': case 'X': DebugFlag |= DB_PRTEXPR; break;
|
||||
case 't': case 'T': DebugFlag |= DB_PRTTRIG; break;
|
||||
@@ -617,7 +642,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
case 'l': case 'L': DebugFlag |= DB_PRTLINE; break;
|
||||
case 'f': case 'F': DebugFlag |= DB_TRACE_FILES; break;
|
||||
default:
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_DB_FLAG], *(arg-1));
|
||||
fprintf(ErrFp, GetErr(M_BAD_DB_FLAG), *(arg-1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -652,7 +677,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_OPTION], *(arg-1));
|
||||
fprintf(ErrFp, GetErr(M_BAD_OPTION), *(arg-1));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -720,7 +745,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
fprintf(stderr, "%s: `%s'\n", ErrMsg[-tok.val], arg);
|
||||
fprintf(ErrFp, "%s: `%s'\n", GetErr(-tok.val), arg);
|
||||
Usage();
|
||||
}
|
||||
Usage();
|
||||
@@ -782,7 +807,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
#ifndef L_USAGE_OVERRIDE
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "\nREMIND %s Copyright (C) 1992-2025 Dianne Skoll\n", VERSION);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
@@ -844,7 +869,7 @@ static void ChgUser(char const *user)
|
||||
pwent = getpwnam(user);
|
||||
|
||||
if (!pwent) {
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_USER], user);
|
||||
fprintf(ErrFp, GetErr(M_BAD_USER), user);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -852,24 +877,24 @@ static void ChgUser(char const *user)
|
||||
/* Started as root, so drop privileges */
|
||||
#ifdef HAVE_INITGROUPS
|
||||
if (initgroups(pwent->pw_name, pwent->pw_gid) < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_GID], pwent->pw_gid);
|
||||
fprintf(ErrFp, GetErr(M_NO_CHG_GID), pwent->pw_gid);
|
||||
exit(EXIT_FAILURE);
|
||||
};
|
||||
#endif
|
||||
if (setgid(pwent->pw_gid) < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_GID], pwent->pw_gid);
|
||||
fprintf(ErrFp, GetErr(M_NO_CHG_GID), pwent->pw_gid);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (setuid(pwent->pw_uid) < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_UID], pwent->pw_uid);
|
||||
fprintf(ErrFp, GetErr(M_NO_CHG_UID), pwent->pw_uid);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
home = malloc(strlen(pwent->pw_dir) + 6);
|
||||
if (!home) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", GetErr(M_NOMEM_ENV));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(home, "HOME=%s", pwent->pw_dir);
|
||||
@@ -877,7 +902,7 @@ static void ChgUser(char const *user)
|
||||
|
||||
shell = malloc(strlen(pwent->pw_shell) + 7);
|
||||
if (!shell) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", GetErr(M_NOMEM_ENV));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(shell, "SHELL=%s", pwent->pw_shell);
|
||||
@@ -886,14 +911,14 @@ static void ChgUser(char const *user)
|
||||
if (pwent->pw_uid) {
|
||||
username = malloc(strlen(pwent->pw_name) + 6);
|
||||
if (!username) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", GetErr(M_NOMEM_ENV));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(username, "USER=%s", pwent->pw_name);
|
||||
putenv(username);
|
||||
logname= malloc(strlen(pwent->pw_name) + 9);
|
||||
if (!logname) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", GetErr(M_NOMEM_ENV));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(logname, "LOGNAME=%s", pwent->pw_name);
|
||||
@@ -911,7 +936,7 @@ DefineFunction(char const *str)
|
||||
r = DoFset(&p);
|
||||
DestroyParser(&p);
|
||||
if (r != OK) {
|
||||
fprintf(ErrFp, "-i option: %s: %s\n", str, ErrMsg[r]);
|
||||
fprintf(ErrFp, "-i option: %s: %s\n", str, GetErr(r));
|
||||
}
|
||||
}
|
||||
/***************************************************************/
|
||||
@@ -938,7 +963,7 @@ static void InitializeVar(char const *str)
|
||||
if (isalpha(*str) || *str == '_' || (r > 0 && *str == '(') || (r == 0 && *str == '$') || (r > 0 && isdigit(*str))) {
|
||||
varname[r++] = *str;
|
||||
} else {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_ILLEGAL_CHAR]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_ILLEGAL_CHAR));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -951,13 +976,13 @@ static void InitializeVar(char const *str)
|
||||
}
|
||||
varname[r] = 0;
|
||||
if (!*varname) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_VAR]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_VAR));
|
||||
return;
|
||||
}
|
||||
if (!*str) {
|
||||
/* Setting a system var does require =expr on the commandline */
|
||||
if (*varname == '$') {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_EQ]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_EQ));
|
||||
return;
|
||||
}
|
||||
val.type = INT_TYPE;
|
||||
@@ -967,41 +992,41 @@ static void InitializeVar(char const *str)
|
||||
r = PreserveVar(varname);
|
||||
}
|
||||
if (r) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*varname) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_VAR]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_VAR));
|
||||
return;
|
||||
}
|
||||
expr = str+1;
|
||||
if (!*expr) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_EXPR]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_EXPR));
|
||||
return;
|
||||
}
|
||||
|
||||
r=EvalExpr(&expr, &val, NULL);
|
||||
if (r) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*varname == '$') {
|
||||
r=SetSysVar(varname+1, &val);
|
||||
DestroyValue(val);
|
||||
if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
if (r) fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
return;
|
||||
}
|
||||
|
||||
r=SetVar(varname, &val);
|
||||
if (r) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
return;
|
||||
}
|
||||
r=PreserveVar(varname);
|
||||
if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
if (r) fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1010,14 +1035,14 @@ AddTrustedUser(char const *username)
|
||||
{
|
||||
struct passwd *pwent;
|
||||
if (NumTrustedUsers >= MAX_TRUSTED_USERS) {
|
||||
fprintf(stderr, "Too many trusted users (%d max)\n",
|
||||
fprintf(ErrFp, "Too many trusted users (%d max)\n",
|
||||
MAX_TRUSTED_USERS);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pwent = getpwnam(username);
|
||||
if (!pwent) {
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_USER], username);
|
||||
fprintf(ErrFp, GetErr(M_BAD_USER), username);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
TrustedUsers[NumTrustedUsers] = pwent->pw_uid;
|
||||
@@ -1077,6 +1102,16 @@ ProcessLongOption(char const *arg)
|
||||
printf("%s\n", CONFIG_CMD);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
if (!strcmp(arg, "print-errs")) {
|
||||
for (t=0; t<NumErrs; t++) {
|
||||
if (*ErrMsg[t]) {
|
||||
print_escaped_string(stdout, ErrMsg[t]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (!strcmp(arg, "print-tokens")) {
|
||||
print_remind_tokens();
|
||||
print_builtinfunc_tokens();
|
||||
|
||||
78
src/lang.h
78
src/lang.h
@@ -1,78 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* LANG.H */
|
||||
/* */
|
||||
/* Header file for language support for various languages. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* I'm chauvinistic and name each language with its English name... */
|
||||
|
||||
#define ENGLISH 0 /* original by Dianne Skoll */
|
||||
#define GERMAN 1 /* translated by Wolfgang Thronicke */
|
||||
#define DUTCH 2 /* translated by Willem Kasdorp and Erik-Jan Vens */
|
||||
#define FINNISH 3 /* translated by Mikko Silvonen */
|
||||
#define FRENCH 4 /* translated by Laurent Duperval */
|
||||
#define NORWEGIAN 5 /* translated by Trygve Randen */
|
||||
#define DANISH 6 /* translated by Mogens Lynnerup */
|
||||
#define POLISH 7 /* translated by Jerzy Sobczyk */
|
||||
#define BRAZPORT 8 /* Brazilian Portuguese by Marco Paganini */
|
||||
#define ITALIAN 9 /* translated by Valerio Aimale */
|
||||
#define ROMANIAN 10 /* translated by Liviu Daia */
|
||||
#define SPANISH 11 /* translated by Rafa Couto */
|
||||
#define ICELANDIC 12 /* translated by Björn Davíðsson */
|
||||
|
||||
/* Add more languages here - but please e-mail dianne@skoll.ca
|
||||
to have your favorite language assigned a number. If you add a
|
||||
language, please send me the header file, and permission to include
|
||||
it in future releases of Remind. Note that you'll get no remuneration
|
||||
for this service - just everlasting fame. :-)
|
||||
|
||||
Use the file tstlang.rem to test your new language file. */
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* Define the language you want to use here *
|
||||
* *
|
||||
************************************************************************/
|
||||
#ifndef LANG /* Allow for definition on compiler command line */
|
||||
#define LANG ENGLISH
|
||||
#endif
|
||||
|
||||
/* Pick up the appropriate header file */
|
||||
#if LANG == ENGLISH
|
||||
#include "langs/english.h"
|
||||
#elif LANG == GERMAN
|
||||
#include "langs/german.h"
|
||||
#elif LANG == DUTCH
|
||||
#include "langs/dutch.h"
|
||||
#elif LANG == FINNISH
|
||||
#include "langs/finnish.h"
|
||||
#elif LANG == FRENCH
|
||||
#include "langs/french.h"
|
||||
#elif LANG == NORWEGIAN
|
||||
#include "langs/norwgian.h"
|
||||
#elif LANG == DANISH
|
||||
#include "langs/danish.h"
|
||||
#elif LANG == POLISH
|
||||
#include "langs/polish.h"
|
||||
#elif LANG == BRAZPORT
|
||||
#include "langs/portbr.h"
|
||||
#elif LANG == ITALIAN
|
||||
#include "langs/italian.h"
|
||||
#elif LANG == ROMANIAN
|
||||
#include "langs/romanian.h"
|
||||
#elif LANG == SPANISH
|
||||
#include "langs/spanish.h"
|
||||
#elif LANG == ICELANDIC
|
||||
#include "langs/icelandic.h"
|
||||
|
||||
/* If no sensible language, choose English. I intended to use
|
||||
the #error directive here, but some C compilers barf. */
|
||||
#else
|
||||
#include "langs/english.h"
|
||||
#endif
|
||||
@@ -1,91 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DANISH.H */
|
||||
/* */
|
||||
/* Support for the Danish language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1993 by Mogens Lynnerup. */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Danish"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Søndag"
|
||||
#define L_MONDAY "Mandag"
|
||||
#define L_TUESDAY "Tirsdag"
|
||||
#define L_WEDNESDAY "Onsdag"
|
||||
#define L_THURSDAY "Torsdag"
|
||||
#define L_FRIDAY "Fredag"
|
||||
#define L_SATURDAY "Lørdag"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
#define L_FEB "Februar"
|
||||
#define L_MAR "Marts"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "Maj"
|
||||
#define L_JUN "Juni"
|
||||
#define L_JUL "Juli"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "Oktober"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "December"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "i dag"
|
||||
#define L_TOMORROW "i morgen"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Påmindelse for %w, %d. %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "siden"
|
||||
#define L_FROMNOW "fra nu"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "om %d dage"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "på"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "e"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nu"
|
||||
#define L_AT "kl."
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "time"
|
||||
#define L_IS "er"
|
||||
#define L_WAS "var"
|
||||
#define L_AND "og"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "r"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "ter"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#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[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[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
|
||||
#define L_V_OVER L_G_OVER
|
||||
@@ -1,102 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DUTCH.H */
|
||||
/* */
|
||||
/* Support for the DUTCH language. */
|
||||
/* */
|
||||
/* Author: Willem Kasdorp */
|
||||
/* */
|
||||
/* Modified slightly by Dianne Skoll */
|
||||
/* */
|
||||
/* Further corrections by Erik-Jan Vens */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Dutch"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "zondag"
|
||||
#define L_MONDAY "maandag"
|
||||
#define L_TUESDAY "dinsdag"
|
||||
#define L_WEDNESDAY "woensdag"
|
||||
#define L_THURSDAY "donderdag"
|
||||
#define L_FRIDAY "vrijdag"
|
||||
#define L_SATURDAY "zaterdag"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "januari"
|
||||
#define L_FEB "februari"
|
||||
#define L_MAR "maart"
|
||||
#define L_APR "april"
|
||||
#define L_MAY "mei"
|
||||
#define L_JUN "juni"
|
||||
#define L_JUL "juli"
|
||||
#define L_AUG "augustus"
|
||||
#define L_SEP "september"
|
||||
#define L_OCT "oktober"
|
||||
#define L_NOV "november"
|
||||
#define L_DEC "december"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "vandaag"
|
||||
#define L_TOMORROW "morgen"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Herinneringen voor %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "geleden"
|
||||
#define L_FROMNOW "vanaf nu"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "over %d dagen"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "op"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix. (Indeed..., wkasdo) */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nu"
|
||||
#define L_AT "op"
|
||||
#define L_MINUTE "minuut"
|
||||
#define L_HOUR "uur"
|
||||
#define L_IS "is"
|
||||
#define L_WAS "was"
|
||||
#define L_AND "en"
|
||||
/* What to add to make "hour" plural (should result in uren, not uuren (wkasdo) */
|
||||
#define L_HPLU "en"
|
||||
/* What to add to make "minute" plural (should be minuten, not minuuten) */
|
||||
#define L_MPLU "en"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
/* Willem - I fixed the uren/uuren problem here */
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "%d %s %s", mdiff, \
|
||||
((mdiff == 1) ? "minuut" : "minuten"), when); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "%d %s %s", hdiff, \
|
||||
((hdiff == 1) ? "uur" : "uren"), when); \
|
||||
else sprintf(s, "%d %s %s %d %s %s", hdiff, \
|
||||
(hdiff == 1 ? "uur" : "uren"), \
|
||||
L_AND, mdiff, \
|
||||
(mdiff == 1 ? "minuut" : "minuten"), \
|
||||
when);
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ENGLISH.H */
|
||||
/* */
|
||||
/* Support for the English language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "English"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Sunday"
|
||||
#define L_MONDAY "Monday"
|
||||
#define L_TUESDAY "Tuesday"
|
||||
#define L_WEDNESDAY "Wednesday"
|
||||
#define L_THURSDAY "Thursday"
|
||||
#define L_FRIDAY "Friday"
|
||||
#define L_SATURDAY "Saturday"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "January"
|
||||
#define L_FEB "February"
|
||||
#define L_MAR "March"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "May"
|
||||
#define L_JUN "June"
|
||||
#define L_JUL "July"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "October"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "December"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "today"
|
||||
#define L_TOMORROW "tomorrow"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Reminders for %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "ago"
|
||||
#define L_FROMNOW "from now"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "in %d days' time"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "on"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "now"
|
||||
#define L_AT "at"
|
||||
#define L_MINUTE "minute"
|
||||
#define L_HOUR "hour"
|
||||
#define L_IS "is"
|
||||
#define L_WAS "was"
|
||||
#define L_AND "and"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "s"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "s"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
@@ -1,292 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FINNISH.H */
|
||||
/* */
|
||||
/* Support for the Finnish language. */
|
||||
/* */
|
||||
/* Author: Mikko Silvonen <silvonen@iki.fi> */
|
||||
/* */
|
||||
/* See http://www.iki.fi/silvonen/remind/ for a list of */
|
||||
/* Finnish holidays. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* This file is Copyright (C) 1993-1998 by Mikko Silvonen. */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Finnish"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "sunnuntai"
|
||||
#define L_MONDAY "maanantai"
|
||||
#define L_TUESDAY "tiistai"
|
||||
#define L_WEDNESDAY "keskiviikko"
|
||||
#define L_THURSDAY "torstai"
|
||||
#define L_FRIDAY "perjantai"
|
||||
#define L_SATURDAY "lauantai"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "tammikuu"
|
||||
#define L_FEB "helmikuu"
|
||||
#define L_MAR "maaliskuu"
|
||||
#define L_APR "huhtikuu"
|
||||
#define L_MAY "toukokuu"
|
||||
#define L_JUN "kesäkuu"
|
||||
#define L_JUL "heinäkuu"
|
||||
#define L_AUG "elokuu"
|
||||
#define L_SEP "syyskuu"
|
||||
#define L_OCT "lokakuu"
|
||||
#define L_NOV "marraskuu"
|
||||
#define L_DEC "joulukuu"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "tänään"
|
||||
#define L_TOMORROW "huomenna"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Viestit %wna %d. %mta %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM " ap."
|
||||
#define L_PM " ip."
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "sitten"
|
||||
#define L_FROMNOW "kuluttua"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "%d päivän kuluttua"
|
||||
|
||||
/* "on" as in "on date...", but in Finnish it is a case ending;
|
||||
L_PARTIT is the partitive ending appended to -kuu and -tai */
|
||||
#define L_ON "na"
|
||||
#define L_PARTIT "ta"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
/* The partitive ending of "day" */
|
||||
#define L_PLURAL "ä"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nyt"
|
||||
#define L_AT "klo"
|
||||
#define L_MINUTE "minuutti"
|
||||
#define L_HOUR "tunti"
|
||||
#define L_IS "on"
|
||||
#define L_WAS "oli"
|
||||
#define L_AND "ja"
|
||||
|
||||
/* What to add to make "hour" plural (or actually partitive) */
|
||||
#define L_HPLU "a"
|
||||
/* What to add to make "minute" plural (or actually partitive) */
|
||||
#define L_MPLU "a"
|
||||
|
||||
/* Genitive form of "hour" */
|
||||
#define L_HGEN "tunnin"
|
||||
/* Genitive form of "minute" */
|
||||
#define L_MGEN "minuutin"
|
||||
|
||||
/* 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 switch(d) { \
|
||||
case 1: plu = ":senä"; break; \
|
||||
case 2: plu = ":sena"; break; \
|
||||
default: \
|
||||
switch(d%10) { \
|
||||
case 2: \
|
||||
case 3: \
|
||||
case 6: \
|
||||
case 8: plu = ":ntena"; break; \
|
||||
default: plu = ":ntenä"; break; \
|
||||
} \
|
||||
}
|
||||
#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[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[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[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); \
|
||||
else { \
|
||||
s[0] = '\0'; \
|
||||
if (hdiff != 0) { \
|
||||
if (tdiff < 0) \
|
||||
sprintf(s, "%d %s%s ", hdiff, L_HOUR, hplu); \
|
||||
else \
|
||||
sprintf(s, "%d %s ", hdiff, L_HGEN); \
|
||||
} \
|
||||
if (mdiff != 0) { \
|
||||
if (tdiff < 0) \
|
||||
sprintf(s + strlen(s), "%d %s%s ", mdiff, L_MINUTE, mplu); \
|
||||
else \
|
||||
sprintf(s + strlen(s), "%d %s ", mdiff, L_MGEN); \
|
||||
} \
|
||||
sprintf(s + strlen(s), when); \
|
||||
}
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
"Ok",
|
||||
"Puuttuva ']'",
|
||||
"Puuttuva lainausmerkki",
|
||||
"Liian monimutkainen lauseke",
|
||||
"Liian monimutkainen lauseke - liikaa operandeja",
|
||||
"Puuttuva ')'",
|
||||
"Määrittelemätön funktio",
|
||||
"Virheellinen merkki",
|
||||
"Kaksipaikkainen operaattori puuttuu",
|
||||
"Muisti loppui",
|
||||
"Virheellinen luku",
|
||||
"Operaattoripino tyhjä - sisäinen virhe",
|
||||
"Muuttujapino tyhjä - sisäinen virhe",
|
||||
"Tyyppimuunnos ei onnistu",
|
||||
"Virheellinen tyyppi",
|
||||
"Liian suuri päiväys",
|
||||
"Pinovirhe - sisäinen virhe",
|
||||
"Jako nollalla",
|
||||
"Määrittelemätön funktio",
|
||||
"Odottamaton rivin loppu",
|
||||
"Odottamaton tiedoston loppu",
|
||||
"Syöttö- tai tulostusvirhe",
|
||||
"Liian pitkä rivi",
|
||||
"Sisäinen virhe",
|
||||
"Virheellinen päiväys",
|
||||
"Liian vähän argumentteja",
|
||||
"Liian paljon argumentteja",
|
||||
"Virheellinen aika",
|
||||
"Liian suuri luku",
|
||||
"Liian pieni luku",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Liian monta sisäkkäistä INCLUDEa",
|
||||
"Jäsennysvirhe",
|
||||
"Laukaisuhetken laskenta ei onnistu",
|
||||
"Liian monta sisäkkäistä IF-lausetta",
|
||||
"ELSE ilman IF-lausetta",
|
||||
"ENDIF ilman IF-lausetta",
|
||||
"Kaikkia viikonpäiviä ei voi jättää pois",
|
||||
"Ylimääräisiä merkkejä rivillä",
|
||||
"POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia",
|
||||
"RUN-lauseen käyttö estetty",
|
||||
"Arvoaluevirhe",
|
||||
"Virheellinen tunniste",
|
||||
"Rekursiivinen funktiokutsu havaittu",
|
||||
"",
|
||||
"Järjestelmämuuttujan muuttaminen ei onnistu",
|
||||
"C-kirjastofunktio ei pysty esittämään päiväystä tai aikaa",
|
||||
"Sisäisen funktion määritelmää yritettiin muuttaa",
|
||||
"Lausekkeessa ei voi olla sisäkkäisiä funktiomääritelmiä",
|
||||
"Päiväyksen täytyy olla täydellinen toistokertoimessa",
|
||||
"Vuosi annettu kahdesti",
|
||||
"Kuukausi annettu kahdesti",
|
||||
"Päivä annettu kahdesti",
|
||||
"Tuntematon sana tai merkki",
|
||||
"OMIT-komennossa on annettava kuukausi",
|
||||
"Liian monta osittaista OMIT-komentoa",
|
||||
"Liian monta täydellistä OMIT-komentoa",
|
||||
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
|
||||
"Virhe tiedoston luvussa",
|
||||
"Pilkku puuttuu",
|
||||
"Virheellinen juutalainen päiväys",
|
||||
"IIF vaatii parittoman määrän argumentteja",
|
||||
"Varoitus: puuttuva ENDIF",
|
||||
"Pilkku puuttuu",
|
||||
"Viikonpäivä annettu kahdesti",
|
||||
"Käytä vain yhtä komennoista BEFORE, AFTER ja SKIP",
|
||||
"Sisäkkäisiä MSG-, MSF- ja RUN-lauseita ei voi käyttää lausekkeessa",
|
||||
"Toistokerroin annettu kahdesti",
|
||||
"Delta-arvo annettu kahdesti",
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa käytetty kahdesti. (Hah.)",
|
||||
"AT-sanan perästä puuttuu aika",
|
||||
"THROUGH/UNTIL-sanaa käytetty kahdesti",
|
||||
"Epätäydellinen päiväys",
|
||||
"FROM/SCANFROM-sanaa käytetty kahdesti",
|
||||
"Muuttuja",
|
||||
"Arvo",
|
||||
"*MÄÄRITTELEMÄTÖN*",
|
||||
"Siirrytään funktioon",
|
||||
"Poistutaan funktiosta",
|
||||
"Vanhentunut",
|
||||
"fork() epäonnistui - jonomuistutukset eivät toimi",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Virheellinen järjestelmäpäiväys: vuosi on vähemmän kuin %d\n",
|
||||
"Tuntematon virheenetsintätarkenne '%c'\n",
|
||||
"Tuntematon tarkenne '%c'\n",
|
||||
"Tuntematon käyttäjä '%s'\n",
|
||||
"Ryhmänumeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Käyttäjänumeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Muisti ei riitä ympäristölle\n",
|
||||
"Puuttuva '='-merkki",
|
||||
"Puuttuva muuttujanimi",
|
||||
"Puuttuva lauseke",
|
||||
"Päivän asetus %s:ksi ei onnitus\n",
|
||||
"Remind: tarkenne '-i': %s\n",
|
||||
"Ei viestejä.",
|
||||
"%d viesti(ä) tämän päivän jonossa.\n",
|
||||
"Numero puuttuu",
|
||||
"Virheellinen funktio WARN-lausekkeessa",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT",
|
||||
"Odotettu viikonpäivän nimi",
|
||||
"Päällekkäinen argumentin nimi",
|
||||
"Lausekkeiden arviointi on poistettu käytöstä",
|
||||
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETAVERSIO <<<<\n");
|
||||
#endif
|
||||
fprintf(ErrFp, "Käyttö: remind [tarkenteet] tiedosto [päiväys] [aika] [*toisto]\n");
|
||||
fprintf(ErrFp, "Tarkenteet:\n");
|
||||
fprintf(ErrFp, " -n Tulosta viestien seuraavat esiintymiskerrat yksink. muodossa\n");
|
||||
fprintf(ErrFp, " -r Estä RUN-lauseiden käyttö\n");
|
||||
fprintf(ErrFp, " -c[n] Tulosta n:n kuukauden kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -c+[n] Tulosta n:n viikon kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja välit\n");
|
||||
fprintf(ErrFp, " -s[+][n] Tulosta n:n kuukauden (viikon) 'yksink. kalenteri' (oletus 1)\n");
|
||||
fprintf(ErrFp, " -p[n] Kuten -s, mutta tulosta rem2ps:lle sopivassa muodossa\n");
|
||||
fprintf(ErrFp, " -v Laveat tulostukset\n");
|
||||
fprintf(ErrFp, " -o Älä noudata ONCE-lauseita\n");
|
||||
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta välittämättä\n");
|
||||
fprintf(ErrFp, " -h Suppeat tulostukset\n");
|
||||
fprintf(ErrFp, " -a Älä laukaise viestejä heti - lisää ne jonoon\n");
|
||||
fprintf(ErrFp, " -q Älä lisää viestejä jonoon\n");
|
||||
fprintf(ErrFp, " -f Laukaise viestit, pysy etualalla\n");
|
||||
fprintf(ErrFp, " -z[n] Käynnisty demonina, herätys n:n (5:n) minuutin välein\n");
|
||||
fprintf(ErrFp, " -d... Virheenetsintä: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Ohjaa virhetulostus stdout-vuohon\n");
|
||||
fprintf(ErrFp, " -b[n] Ajan ilmaisu: 0=ap/ip, 1=24 tuntia, 2=ei aikoja\n");
|
||||
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
|
||||
fprintf(ErrFp, " -g[ddd] Lajittele viestit päiväyksen, ajan ja tärkeyden mukaan\n");
|
||||
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja säilytä var\n");
|
||||
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eikä sunnuntaista\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
@@ -1,266 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FRENCH.H */
|
||||
/* */
|
||||
/* Support for the French language. */
|
||||
/* */
|
||||
/* Contributed by Laurent Duperval. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1993 by Laurent Duperval and */
|
||||
/* Dianne Skoll. */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "French"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "dimanche"
|
||||
#define L_MONDAY "lundi"
|
||||
#define L_TUESDAY "mardi"
|
||||
#define L_WEDNESDAY "mercredi"
|
||||
#define L_THURSDAY "jeudi"
|
||||
#define L_FRIDAY "vendredi"
|
||||
#define L_SATURDAY "samedi"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "janvier"
|
||||
#define L_FEB "février"
|
||||
#define L_MAR "mars"
|
||||
#define L_APR "avril"
|
||||
#define L_MAY "mai"
|
||||
#define L_JUN "juin"
|
||||
#define L_JUL "juillet"
|
||||
#define L_AUG "août"
|
||||
#define L_SEP "septembre"
|
||||
#define L_OCT "octobre"
|
||||
#define L_NOV "novembre"
|
||||
#define L_DEC "décembre"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "aujourd'hui"
|
||||
#define L_TOMORROW "demain"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Rappels pour %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "il y a"
|
||||
#define L_FROMNOW "dans"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "dans %d jours"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "le"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "maintenant"
|
||||
#define L_AT "à"
|
||||
#define L_MINUTE "minute"
|
||||
#define L_HOUR "heure"
|
||||
#define L_IS "est"
|
||||
#define L_WAS "était"
|
||||
#define L_AND "et"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "s"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "s"
|
||||
|
||||
/* 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 \
|
||||
switch(d) { \
|
||||
case 1: plu = "er"; break; \
|
||||
default: plu = ""; break; \
|
||||
}
|
||||
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (tdiff < 0) { \
|
||||
if (mdiff == 0) \
|
||||
sprintf(s, "il y a %d heure%s", hdiff, hplu); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "il y a %d minute%s", mdiff, mplu); \
|
||||
else \
|
||||
sprintf(s, "il y a %d heure%s et %d minute%s", hdiff, hplu, mdiff, mplu); \
|
||||
} else { \
|
||||
if (mdiff == 0) \
|
||||
sprintf(s, "dans %d heure%s", hdiff, hplu); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "dans %d minute%s", mdiff, mplu); \
|
||||
else \
|
||||
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[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[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
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
"Ok",
|
||||
"']' manquant",
|
||||
"Apostrophe manquant",
|
||||
"Expression trop complexe",
|
||||
"Expression trop complexe - trop d'opérandes",
|
||||
"')' manquante",
|
||||
"Fonction non-définie",
|
||||
"Caractère illégal",
|
||||
"Opérateur binaire attendu",
|
||||
"Manque de mémoire",
|
||||
"Nombre mal formé",
|
||||
"Erreur interne - 'underflow' de la pile d'opérateurs",
|
||||
"Erreur interne - 'underflow' de la pile de variables",
|
||||
"Impossible de convertir",
|
||||
"Types non-équivalents",
|
||||
"Débordement de date",
|
||||
"Erreur interne - erreur de pile",
|
||||
"Division par zéro",
|
||||
"Variable non définie",
|
||||
"Fin de ligne non attendue",
|
||||
"Fin de fichier non attendue",
|
||||
"Erreur I/O",
|
||||
"Ligne trop longue",
|
||||
"Erreur interne",
|
||||
"Mauvaise date spécifiée",
|
||||
"Pas assez d'arguments",
|
||||
"Trop d'arguments",
|
||||
"Heure mal formée",
|
||||
"Nombre trop élevé",
|
||||
"Nombre trop bas",
|
||||
"Impossible d'ouvrir le fichier",
|
||||
"Trop d'INCLUDE imbriqués",
|
||||
"Erreur d'analyse",
|
||||
"Impossible de calculer le déclenchement",
|
||||
"Trop de IF imbriqués",
|
||||
"ELSE sans IF correspondant",
|
||||
"ENDIF sans IF correspondant",
|
||||
"Impossible d'omettre (OMIT) tous les jours",
|
||||
"Elément(s) étranger(s) sur la ligne",
|
||||
"POP-OMIT-CONTEXT sans PUSH-OMIT-CONTEXT correspondant",
|
||||
"RUN déactivé",
|
||||
"Erreur de domaine",
|
||||
"Identificateur invalide",
|
||||
"Appel récursif détecté",
|
||||
"",
|
||||
"Impossible de modifier une variable système",
|
||||
"Fonction de la librairie C ne peut représenter la date/l'heure",
|
||||
"Tentative de redéfinition d'une fonction intrinsèque",
|
||||
"Impossible d'imbriquer une définition de fonction dans une expression",
|
||||
"Pour utiliser le facteur de répétition la date doit être spécifiée au complet",
|
||||
"Année spécifiée deux fois",
|
||||
"Mois spécifié deux fois",
|
||||
"Jour spécifié deux fois",
|
||||
"Elément inconnu",
|
||||
"Mois et jour doivent être spécifiés dans commande OMIT",
|
||||
"Trop de OMITs partiels",
|
||||
"Trop de OMITs complets",
|
||||
"Attention: PUSH-OMIT-CONTEXT sans POP-OMIT-CONTEXT correspondant",
|
||||
"Erreur à la lecture du fichier",
|
||||
"Fin de ligne attendue",
|
||||
"Date hébreuse invalide",
|
||||
"IIF demande nombre d'arguments impair",
|
||||
"Attention: ENDIF manquant",
|
||||
"Virgule attendue",
|
||||
"Jour de la semaine spécifié deux fois",
|
||||
"Utiliser un seul parmi BEFORE, AFTER ou SKIP",
|
||||
"Impossible d'imbriquer MSG, MSF, RUN, etc. dans une expression",
|
||||
"Valeur de répétition spécifiée deux fois",
|
||||
"Valeur delta spécifiée deux fois",
|
||||
"Valeur de retour spécifiée deux fois",
|
||||
"Mot-clé ONCE utilisé deux fois. (Hah.)",
|
||||
"Heure attendue après AT",
|
||||
"Mot-clé THROUGH/UNTIL utilisé deux fois",
|
||||
"Spécification de date incomplète",
|
||||
"Mot-clé FROM/SCANFROM utilisé deux fois",
|
||||
"Variable",
|
||||
"Valeur",
|
||||
"*NON-DEFINI*",
|
||||
"Entrée dans UserFN",
|
||||
"Sortie de UserFN",
|
||||
"Expiré",
|
||||
"fork() échoué - impossible de faire les appels en queue",
|
||||
"Impossible d'accéder au fichier",
|
||||
"Date système illégale: Année est inférieure à %d\n",
|
||||
"Option de déverminage inconnue '%c'\n",
|
||||
"Option inconnue '%c'\n",
|
||||
"Usager inconnu '%s'\n",
|
||||
"Impossible de changer gid pour %d\n",
|
||||
"Impossible de changer uid pour %d\n",
|
||||
"Manque de mémoire pour environnement\n",
|
||||
"Signe '=' manquant",
|
||||
"Nom de variable absent",
|
||||
"Expression absente",
|
||||
"Impossible de changer la date d'accès de %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Pas de rappels.",
|
||||
"%d rappel(s) en file pour aujourd'hui.\n",
|
||||
"Nombre attendu",
|
||||
"Fonction illégale après WARN",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT",
|
||||
"Nom du jour de la semaine attendu",
|
||||
"Nom de l'argument en double",
|
||||
"L'évaluation de l'expression est désactivée",
|
||||
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
fprintf(ErrFp, "\nUtilisation: remind [options] fichier [date] [heure] [*répétition]\n");
|
||||
fprintf(ErrFp, "Options:\n");
|
||||
fprintf(ErrFp, " -n Afficher la prochaine occurence des rappels en format simple\n");
|
||||
fprintf(ErrFp, " -r Désactiver les instructions RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Produire un calendrier pour n (défaut 1) mois\n");
|
||||
fprintf(ErrFp, " -c+[n] Produire un calendrier pour n (défaut 1) semaines\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Spécifier largeur, remplissage et espacement du calendrier\n");
|
||||
fprintf(ErrFp, " -s[+][n] Produire un 'calendrier simple' pour n (1) mois (semaines)\n");
|
||||
fprintf(ErrFp, " -p[n] Comme -s, mais avec entrée compatible avec rem2ps\n");
|
||||
fprintf(ErrFp, " -v Mode verbeux\n");
|
||||
fprintf(ErrFp, " -o Ignorer instructions ONCE\n");
|
||||
fprintf(ErrFp, " -t Déclencher tous les rappels peu importe le delta\n");
|
||||
fprintf(ErrFp, " -h Mode silencieux\n");
|
||||
fprintf(ErrFp, " -a Ne pas déclencher les rappels minutés immédiatement - les mettre en file\n");
|
||||
fprintf(ErrFp, " -q Ne pas mettre les rappels minutés en file\n");
|
||||
fprintf(ErrFp, " -f Déclencher les rappels minutés immédiatement en restant en avant-plan\n");
|
||||
fprintf(ErrFp, " -z[n] Entrer en mode 'daemon', réveil chaque n (5) minutes\n");
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Envoyer les messages de stderr à stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Formats de l'heure pour le calendrier: 0=am/pm, 1=24hr, 2=aucun\n");
|
||||
fprintf(ErrFp, " -x[n] Limite d'itérations pour la clause SATISFY (def=1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Exécuter 'cmd' pour les rappels de type MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorité avant d'émettre\n");
|
||||
fprintf(ErrFp, " -ivar=val Initialiser var à val et conserver var\n");
|
||||
fprintf(ErrFp, " -m Commencer le calendrier avec lundi plutôt que dimanche\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
@@ -1,88 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GERMAN.H */
|
||||
/* */
|
||||
/* Support for the German language. */
|
||||
/* */
|
||||
/* This file was derived from a patch submitted by Wolfgang */
|
||||
/* Thronicke. I don't guarantee that there are no mistakes - */
|
||||
/* I don't speak German. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "German"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Sonntag"
|
||||
#define L_MONDAY "Montag"
|
||||
#define L_TUESDAY "Dienstag"
|
||||
#define L_WEDNESDAY "Mittwoch"
|
||||
#define L_THURSDAY "Donnerstag"
|
||||
#define L_FRIDAY "Freitag"
|
||||
#define L_SATURDAY "Samstag"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
#define L_FEB "Februar"
|
||||
#define L_MAR "März"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "Mai"
|
||||
#define L_JUN "Juni"
|
||||
#define L_JUL "Juli"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "Oktober"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "Dezember"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "heute"
|
||||
#define L_TOMORROW "morgen"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Termine für %w, den %d. %m %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "vorher"
|
||||
#define L_FROMNOW "von heute"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "in %d Tagen"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "am"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "en"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "jetzt"
|
||||
#define L_AT "um"
|
||||
#define L_MINUTE "Minute"
|
||||
#define L_HOUR "Stunde"
|
||||
#define L_IS "ist"
|
||||
#define L_WAS "war"
|
||||
#define L_AND "und"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "n"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "n"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
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[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
|
||||
@@ -1,79 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ICELANDIC.H */
|
||||
/* */
|
||||
/* Support for the Icelandic language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Icelandic"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "sunnudagur"
|
||||
#define L_MONDAY "mánudagur"
|
||||
#define L_TUESDAY "þriðjudagur"
|
||||
#define L_WEDNESDAY "miðvikudagur"
|
||||
#define L_THURSDAY "fimmtudagur"
|
||||
#define L_FRIDAY "föstudagur"
|
||||
#define L_SATURDAY "laugardagur"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "janúar"
|
||||
#define L_FEB "febrúar"
|
||||
#define L_MAR "mars"
|
||||
#define L_APR "apríl"
|
||||
#define L_MAY "maí"
|
||||
#define L_JUN "júní"
|
||||
#define L_JUL "júlí"
|
||||
#define L_AUG "ágúst"
|
||||
#define L_SEP "september"
|
||||
#define L_OCT "október"
|
||||
#define L_NOV "nóvember"
|
||||
#define L_DEC "desember"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "í dag"
|
||||
#define L_TOMORROW "á morgun"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Minnisatriði: %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "fh"
|
||||
#define L_PM "eh"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "síðan"
|
||||
#define L_FROMNOW "frá því nú"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "eftir %d daga"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "þann"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "a"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "núna"
|
||||
#define L_AT "kl."
|
||||
#define L_MINUTE "mínútu"
|
||||
#define L_HOUR "klukkustund"
|
||||
#define L_IS "er"
|
||||
#define L_WAS "var"
|
||||
#define L_AND "og"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "ir"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "r"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
@@ -1,114 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ITALIAN.H */
|
||||
/* */
|
||||
/* Support for the Italian language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* It is Copyright (C) 1996 by Valerio Aimale */
|
||||
/* */
|
||||
/* Remind is copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Italian"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Domenica"
|
||||
#define L_MONDAY "Lunedì"
|
||||
#define L_TUESDAY "Martedì"
|
||||
#define L_WEDNESDAY "Mercoledì"
|
||||
#define L_THURSDAY "Giovedì"
|
||||
#define L_FRIDAY "Venerdì"
|
||||
#define L_SATURDAY "Sabato"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Gennaio"
|
||||
#define L_FEB "Febbraio"
|
||||
#define L_MAR "Marzo"
|
||||
#define L_APR "Aprile"
|
||||
#define L_MAY "Maggio"
|
||||
#define L_JUN "Giugno"
|
||||
#define L_JUL "Luglio"
|
||||
#define L_AUG "Agosto"
|
||||
#define L_SEP "Settembre"
|
||||
#define L_OCT "Ottobre"
|
||||
#define L_NOV "Novembre"
|
||||
#define L_DEC "Dicembre"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "oggi"
|
||||
|
||||
#define L_TOMORROW "domani"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Promemoria per %w, %d %m %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "fa"
|
||||
#define L_FROMNOW "da oggi"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "fra %d giorni"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON ""
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "ora"
|
||||
#define L_AT "alle"
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "or"
|
||||
#define L_IS "è"
|
||||
#define L_WAS "era"
|
||||
#define L_AND "e"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "s"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "s"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#define L_P_OVER sprintf(s, (diff == 1 ? "o" : "i"));
|
||||
#define L_Q_OVER sprintf(s, (diff == 1 ? "a" : "e"));
|
||||
|
||||
#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[dse%7], d,\
|
||||
MonthName[m], y);
|
||||
#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[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[dse%7], d, \
|
||||
MonthName[m], y);
|
||||
|
||||
#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[dse%7], d, \
|
||||
MonthName[m], y);
|
||||
|
||||
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, \
|
||||
MonthName[m]);
|
||||
@@ -1,84 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* NORWGIAN.H */
|
||||
/* */
|
||||
/* Support for the Norwegian language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* This file is Copyright (C) 1993 by Trygve Randen. */
|
||||
/* Remind is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Norwegian"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Søndag"
|
||||
#define L_MONDAY "Mandag"
|
||||
#define L_TUESDAY "Tirsdag"
|
||||
#define L_WEDNESDAY "Onsdag"
|
||||
#define L_THURSDAY "Torsdag"
|
||||
#define L_FRIDAY "Fredag"
|
||||
#define L_SATURDAY "Lørdag"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
#define L_FEB "Februar"
|
||||
#define L_MAR "Mars"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "Mai"
|
||||
#define L_JUN "Juni"
|
||||
#define L_JUL "Juli"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "Oktober"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "Desember"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "i dag"
|
||||
#define L_TOMORROW "i morgen"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Påminnelse for %w, %d. %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "siden"
|
||||
#define L_FROMNOW "fra nå"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "om %d dager"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "den"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "er"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nå"
|
||||
#define L_AT "kl."
|
||||
#define L_MINUTE "minutt"
|
||||
#define L_HOUR "time"
|
||||
#define L_IS "er"
|
||||
#define L_WAS "var"
|
||||
#define L_AND "og"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "r"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "er"
|
||||
|
||||
/* 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[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
|
||||
@@ -1,281 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* POLISH.H */
|
||||
/* */
|
||||
/* Support for the Polish language. */
|
||||
/* */
|
||||
/* This file was submitted by Jerzy Sobczyk. I don't */
|
||||
/* guarantee that there are no mistakes - I don't speak */
|
||||
/* Polish. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Polish"
|
||||
|
||||
/* Day names */
|
||||
# define L_SUNDAY "Niedziela"
|
||||
# define L_MONDAY "Poniedziałek"
|
||||
# define L_TUESDAY "Wtorek"
|
||||
# define L_WEDNESDAY "Środa"
|
||||
# define L_THURSDAY "Czwartek"
|
||||
# define L_FRIDAY "Piątek"
|
||||
# define L_SATURDAY "Sobota"
|
||||
|
||||
/* Month names */
|
||||
# define L_JAN "Styczeń"
|
||||
# define L_FEB "Luty"
|
||||
# define L_MAR "Marzec"
|
||||
# define L_APR "Kwiecień"
|
||||
# define L_MAY "Maj"
|
||||
# define L_JUN "Czerwiec"
|
||||
# define L_JUL "Lipiec"
|
||||
# define L_AUG "Sierpień"
|
||||
# define L_SEP "Wrzesień"
|
||||
# define L_OCT "Październik"
|
||||
# define L_NOV "Listopad"
|
||||
# define L_DEC "Grudzień"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "dzisiaj"
|
||||
#define L_TOMORROW "jutro"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Terminarz na %w, %d. %m %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "temu"
|
||||
#define L_FROMNOW "od teraz"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "za %d dni"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "-"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL ""
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "teraz"
|
||||
#define L_AT "o"
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "godzin"
|
||||
# define L_IS "będzie"
|
||||
# define L_WAS "było"
|
||||
#define L_AND "i"
|
||||
|
||||
#define L_HPLU ""
|
||||
#define L_MPLU ""
|
||||
|
||||
/* What to add to make "hour" or "minute" plural */
|
||||
#define L_NPLU( N ) ((N == 1) ? "ę" : ((N==12) || (N==13) || (N==14)) ? "" : \
|
||||
((N%10==2) || (N%10==3) || (N%10==4)) ? "y" : "" )
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU_OVER hplu = L_NPLU( hdiff );
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU_OVER mplu = L_NPLU( mdiff );
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) \
|
||||
ampm = (hour<12) ? \
|
||||
(hour<5) ? " w nocy" \
|
||||
: (hour<10) ? " rano" \
|
||||
: " przed południem" \
|
||||
: (hour<18) ? " po południu" \
|
||||
: (hour<22) ? " wieczorem" \
|
||||
: " w nocy";
|
||||
#define L_ORDINAL_OVERRIDE plu = "";
|
||||
#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
|
||||
|
||||
#define L_0_OVER sprintf(s, L_NPLU(hdiff));
|
||||
#define L_9_OVER sprintf(s, L_NPLU(mdiff));
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (tdiff > 0) \
|
||||
{ \
|
||||
if (hdiff == 0) \
|
||||
sprintf(s, "za %d %s%s", mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "za %d %s%s", hdiff, L_HOUR, L_NPLU(hdiff)); \
|
||||
else \
|
||||
sprintf(s, "za %d %s%s %s %d %s%s", hdiff, L_HOUR, L_NPLU(hdiff), \
|
||||
L_AND, mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (hdiff == 0) \
|
||||
sprintf(s, "%d %s%s temu", mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "%d %s%s temu", hdiff, L_HOUR, L_NPLU(hdiff)); \
|
||||
else \
|
||||
sprintf(s, "%d %s%s %s %d %s%s temu", hdiff, L_HOUR, L_NPLU(hdiff), \
|
||||
L_AND, mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
}
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
"OK",
|
||||
"Brakujący ']'",
|
||||
"Brakujący nawias",
|
||||
"Zbyt skomplikowane wyrażenie",
|
||||
"Zbyt skomplikowane wyrażenie - za dużo argumentów",
|
||||
"Brakujący ')'",
|
||||
"Nie zdefiniowana funkcja",
|
||||
"Nielegalny znak",
|
||||
"Spodziewany operator binarny",
|
||||
"Brak pamięci",
|
||||
"Niepoprawny numer",
|
||||
"Pusty stos operatorów - błąd wewnętrzny",
|
||||
"Pusty stos zmiennych - błąd wewnętrzny",
|
||||
"Niemożliwa konwersja",
|
||||
"Błąd typu",
|
||||
"Nadmiar daty",
|
||||
"Błąd stosu - błąd wewnętrzny",
|
||||
"Dzielenie przez zero",
|
||||
"Niezdefiniowana zmienna",
|
||||
"Niespodziewany koniec linii",
|
||||
"Niespodziewany koniec pliku",
|
||||
"Błąd wejscia/wyjscia",
|
||||
"Za długa linia",
|
||||
"Błąd wewnętrzny",
|
||||
"Zła specyfikacja daty",
|
||||
"Za mało argumentów",
|
||||
"Za dużo argumentów",
|
||||
"Nieprawidłowy czas",
|
||||
"Liczba za duża",
|
||||
"Liczba za mała",
|
||||
"Nie mogę otworzyć pliku",
|
||||
"Zbyt zagnieżdżone INCLUDE",
|
||||
"Błąd składniowy",
|
||||
"Nie mogę obliczyć przypomnienia",
|
||||
"Zbyt zagnieżdżone IF",
|
||||
"ELSE bez IF do pary",
|
||||
"ENDIF bez IF do pary",
|
||||
"Nie mogę ominąć (OMIT) wszystkich dni",
|
||||
"Niespodziewany wyraz w lini",
|
||||
"POP-OMIT-CONTEXT bez PUSH-OMIT-CONTEXT",
|
||||
"Komenda RUN zablokowana",
|
||||
"Błąd dziedziny",
|
||||
"Niepoprawny identyfikator",
|
||||
"Wykryto rekursywne wywołanie funkcji",
|
||||
"",
|
||||
"Nie mogę zmienić zmiennej systemowej",
|
||||
"Funkcja biblioteki C nie może reprezentowac daty/czasu",
|
||||
"Próba redefinicji funkcji wbudowanej",
|
||||
"Nie wolno zagnieżdżać definicji funkcji w wyrażeniu",
|
||||
"Aby użyc powtórzenia trzeba w pełni wyspecyfikować datę",
|
||||
"Rok podany dwókrotnie",
|
||||
"Miesiąc podany dwókrotnie",
|
||||
"Dzień podany dwókrotnie",
|
||||
"Nieznane słowo",
|
||||
"W komendzie OMIT trzeba podać miesiąc",
|
||||
"Za dużo częściowych komend OMIT",
|
||||
"Za dużo pełnych komend OMIT",
|
||||
"Ostrzeżenie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",
|
||||
"Błąd odczytu pliku",
|
||||
"Oczekiwany koniec linii",
|
||||
"Błędna data hebrajska",
|
||||
"IIF wymaga nieparzystej liczby argumentów",
|
||||
"Ostrzeżenie: Brakujacy ENDIF",
|
||||
"Oczekiwany przecinek",
|
||||
"Dzień tygodnia podany dwókrotnie",
|
||||
"Dozwolone tylko jedno z: BEFORE, AFTER i SKIP",
|
||||
"Nie można zagnieżdżać MSG, MSF, RUN, itp. w wyrażeniu",
|
||||
"Wartość powtorzenia podana dwókrotnie",
|
||||
"Wartość różnicy podana dwókrotnie",
|
||||
"Wartość cofnięcia podana dwókrotnie",
|
||||
"Słowo ONCE użyte dwókrotnie.",
|
||||
"Po AT oczekiwany jest czas",
|
||||
"Słowo THROUGH/UNTIL użyte dwókrotnie",
|
||||
"Niekompletna specyfikacja daty",
|
||||
"Słowo FROM/SCANFROM użyte dwókrotnie",
|
||||
"Zmienna",
|
||||
"Wartość",
|
||||
"*NIE ZDEFINIOWANE*",
|
||||
"Początek UserFN",
|
||||
"Koniec UserFN",
|
||||
"Przemineło",
|
||||
"Niepowodzenie w funkcji fork() - nie mogę kolejkować przypomnień",
|
||||
"Nie ma dostępu do pliku",
|
||||
"Błędna data systemowa: Rok mniejszy niż %d\n",
|
||||
"Nieznana flaga odpluskwiania '%c'\n",
|
||||
"Nieznana opcja '%c'\n",
|
||||
"Nieznany użytkownik '%s'\n",
|
||||
"Nie mogę zmienić gid na %d\n",
|
||||
"Nie mogę zmienić uid na %d\n",
|
||||
"Brak pamięci na zmienne środowiska\n",
|
||||
"Brak znaku '='",
|
||||
"Brak nazwy zmiennej",
|
||||
"Brak wyrażenia",
|
||||
"Nie mogę zmienić daty dostępu pliku %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Brak przypomnień.",
|
||||
"%d Przypomnienia zakolejkowane na później.\n",
|
||||
"Spodziewana liczba",
|
||||
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT",
|
||||
"Oczekiwana nazwa dnia tygodnia",
|
||||
"Zduplikowana nazwa argumentu",
|
||||
"Ocena wyrażeń jest wyłączona",
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
fprintf(ErrFp, "\nSposób użycia: remind [opcje] plik [data] [czas] [*powtórzenie]\n");
|
||||
fprintf(ErrFp, "Opcje:\n");
|
||||
fprintf(ErrFp, " -n Wypisz następne przypomnienia w prostym formacie\n");
|
||||
fprintf(ErrFp, " -r Zablokuj dyrektywy RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Wypisz kalendarz na n (domyślnie 1) miesięcy\n");
|
||||
fprintf(ErrFp, " -c+[n] Wypisz kalendarz na n (domyślnie 1) tygodni\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Ustaw szerokość, wypełnienie i odstępy w kalendarzu\n");
|
||||
fprintf(ErrFp, " -s[+][n] Wypisz uproszczony kalendarz na n (1) miesięcy (tygodni)\n");
|
||||
fprintf(ErrFp, " -p[n] To samo co -s, ale kompatybilne z rem2ps\n");
|
||||
fprintf(ErrFp, " -v Obszerniejsze komentarze\n");
|
||||
fprintf(ErrFp, " -o Ignoruj instrukcje ONCE\n");
|
||||
fprintf(ErrFp, " -t Odpal wszystkie przyszłe przypomnienia niezależnie od delty\n");
|
||||
fprintf(ErrFp, " -h Praca bezszmerowa\n");
|
||||
fprintf(ErrFp, " -a Nie odpalaj przyponień czasowych - kolejkuj je\n");
|
||||
fprintf(ErrFp, " -q Nie kolejkuj przyponień czasowych\n");
|
||||
fprintf(ErrFp, " -f Nie przechodź do pracy w tle\n");
|
||||
fprintf(ErrFp, " -z[n] Pracuj jako demon, budząc się co n (5) minut\n");
|
||||
fprintf(ErrFp, " -d... Odpluskwianie: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Komunikaty o błędach skieruj na stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=żaden\n");
|
||||
fprintf(ErrFp, " -x[n] Limit powtórzeń klauzuli SATISFY (domyślnie=1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Wywołaj 'cmd' dla przypomnień typu MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia według daty, czasu i priorytetu\n");
|
||||
fprintf(ErrFp, " -ivar=val Zainicjuj zmienną var wartościa val i zachowaj ja\n");
|
||||
fprintf(ErrFp, " -m Rozpocznij kalendarz od poniedziałku zamiast od niedzieli\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
@@ -1,290 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* PORTBR.H */
|
||||
/* */
|
||||
/* Support for the Brazilian Portuguese Language. */
|
||||
/* */
|
||||
/* Contributed by Marco Paganini (paganini@ism.com.br). */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1996 by Marco Paganini and */
|
||||
/* Dianne Skoll. */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Brazilian Portuguese"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "domingo"
|
||||
#define L_MONDAY "segunda"
|
||||
#define L_TUESDAY "terca"
|
||||
#define L_WEDNESDAY "quarta"
|
||||
#define L_THURSDAY "quinta"
|
||||
#define L_FRIDAY "sexta"
|
||||
#define L_SATURDAY "sabado"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "janeiro"
|
||||
#define L_FEB "fevereiro"
|
||||
#define L_MAR "marco"
|
||||
#define L_APR "abril"
|
||||
#define L_MAY "maio"
|
||||
#define L_JUN "junho"
|
||||
#define L_JUL "julho"
|
||||
#define L_AUG "agosto"
|
||||
#define L_SEP "setembro"
|
||||
#define L_OCT "outubro"
|
||||
#define L_NOV "novembro"
|
||||
#define L_DEC "dezembro"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "hoje"
|
||||
#define L_TOMORROW "amanha"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Avisos para %w, %d de %m de %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "atras"
|
||||
#define L_FROMNOW "adiante"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "em %d dias"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "em"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "agora"
|
||||
#define L_AT "as"
|
||||
#define L_MINUTE "minuto"
|
||||
#define L_HOUR "hora"
|
||||
#define L_IS "sao"
|
||||
#define L_WAS "eram"
|
||||
#define L_AND "e"
|
||||
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "s"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "s"
|
||||
|
||||
/* 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 = "";
|
||||
|
||||
/* Portuguese weekdays must be treated separately */
|
||||
#define _ON_WEEKDAY(x) ((x % 7) < 2) ? "no" : "na"
|
||||
|
||||
#define L_A_OVER \
|
||||
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(dse), DayName[dse%7]);
|
||||
|
||||
#define L_G_OVER \
|
||||
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(dse), DayName[dse%7], d, MonthName[m], y);
|
||||
|
||||
#define L_K_OVER \
|
||||
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(dse), DayName[dse%7], d, MonthName[m], y);
|
||||
|
||||
#define L_V_OVER \
|
||||
sprintf(s, "%s %s, %d de %s", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m]);
|
||||
|
||||
#define L_1_OVER \
|
||||
{ \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else \
|
||||
if (hdiff == 0) \
|
||||
{ \
|
||||
if (mdiff > 0) \
|
||||
sprintf(s, "em %d %s%s", mdiff, L_MINUTE, mplu); \
|
||||
else \
|
||||
sprintf(s, "%d %s%s atras", mdiff, L_MINUTE, mplu); \
|
||||
} \
|
||||
else if (mdiff == 0) \
|
||||
{ \
|
||||
if (hdiff > 0) \
|
||||
sprintf(s, "em %d %s%s", hdiff, L_HOUR, hplu); \
|
||||
else \
|
||||
sprintf(s, "%d %s%s atras", hdiff, L_HOUR, hplu); \
|
||||
} else { \
|
||||
if (tdiff > 0) \
|
||||
sprintf(s, "em %d %s%s %s %d %s%s", hdiff, L_HOUR, hplu, L_AND, mdiff, L_MINUTE, mplu); \
|
||||
else \
|
||||
sprintf(s, "%d %s%s %s %d %s%s atras", hdiff, L_HOUR, hplu, L_AND, mdiff, L_MINUTE, mplu); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
"Ok",
|
||||
"Falta um ']'",
|
||||
"Falta uma aspa",
|
||||
"Expressao muito complexa",
|
||||
"Expressao muito complexa - muitos operandos",
|
||||
"Falta um ')'",
|
||||
"Funcao nao definida",
|
||||
"Caracter ilegal",
|
||||
"Esperando operador binario",
|
||||
"Sem memoria",
|
||||
"Numero mal-formado",
|
||||
"Op stack underflow - erro interno",
|
||||
"Va stack underflow - erro interno",
|
||||
"Nao consigo fazer 'coerce'",
|
||||
"Type mismatch",
|
||||
"Overflow na data",
|
||||
"Erro de stack - erro interno",
|
||||
"Divisao por zero",
|
||||
"Variavel nao definida",
|
||||
"Fim da linha nao esperado",
|
||||
"Fim de arquivo nao esperado",
|
||||
"Erro de I/O",
|
||||
"Linha muito longa",
|
||||
"Erro interno",
|
||||
"Especificacao de data invalida",
|
||||
"Argumentos insuficientes",
|
||||
"Argumentos em excesso",
|
||||
"Hora mal-formada",
|
||||
"Numero muito grande",
|
||||
"Numero muito pequeno",
|
||||
"Nao consigo abrir o arquivo",
|
||||
"Ninho de INCLUDEs muito profundo",
|
||||
"Erro de parsing",
|
||||
"Nao consigo computar o 'trigger'",
|
||||
"Muitos IFs aninhados",
|
||||
"ELSE sem o IF correspondente",
|
||||
"ENDIF sem o IF correspondente",
|
||||
"Nao se pode usar OMIT para todos os dias da semana",
|
||||
"Token nao reconhecido na linha",
|
||||
"POP-OMIT-CONTEXT sem PUSH-OMIT-CONTEXT correspondente",
|
||||
"RUN desabilitado",
|
||||
"Erro de dominio",
|
||||
"Identificados invalido",
|
||||
"Chamada de funcao recursiva detectada",
|
||||
"",
|
||||
"Nao posso modificar variavel de sistema",
|
||||
"Funcao da biblioteca C nao pode representar data/hora",
|
||||
"Tentativa de redefinir funcao interna",
|
||||
"Nao e' possivel aninhar definicao de funcao em expressao",
|
||||
"Data deve ser completamente especificada para usar o fator de REPEAT",
|
||||
"Ano especificado duas vezes",
|
||||
"Mes especificado duas vezes",
|
||||
"Dia especificado duas vezes",
|
||||
"Token desconhecido",
|
||||
"O mes deve ser especificados no comando OMIT",
|
||||
"Muitos OMITs parciais",
|
||||
"Muitos OMITs full",
|
||||
"Aviso: PUSH-OMIT-CONTEXT sem POP-OMIT-CONTEXT correspondente",
|
||||
"Erro na leitura do arquivo",
|
||||
"Aguardando fim do arquivo",
|
||||
"Data hebraica invalida",
|
||||
"IIF necessita de numero impar de argumentos",
|
||||
"Warning: ENDIF faltando",
|
||||
"Esperando virgula",
|
||||
"Dia da semana especificado duas vezes",
|
||||
"Use apenas um de BEFORE, AFTER ou SKIP",
|
||||
"Nao e possivel aninhar MSG, MSF, RUN, etc. em expressoes",
|
||||
"Valor de Repeat especificado duas vezes",
|
||||
"Valor de Delta especificado duas vezes",
|
||||
"Valor de Back especificado duas vezes",
|
||||
"ONCE usado duas vezes (Eheheh)",
|
||||
"Esperando hora apos AT",
|
||||
"Keyword THROUGH/UNTIL usada duas vezes",
|
||||
"Especificacao de data incompleta",
|
||||
"Keyword FROM/SCANFROM usada duas vezes",
|
||||
"Variavel",
|
||||
"Valor",
|
||||
"*INDEFINIDO*",
|
||||
"Entrando UserFN",
|
||||
"Saindo UserFN",
|
||||
"Expirou",
|
||||
"fork() falhou - Nao posso processar compromissos na fila",
|
||||
"Nao consigo acessar o arquivo",
|
||||
"Data do sistema ilegal: Ano e menor que %d\n",
|
||||
"Flag de debug desconhecido '%c'\n",
|
||||
"Opcao desconhecida '%c'\n",
|
||||
"Usuario desconhecido '%s'\n",
|
||||
"Nao consigo mudar gid para %d\n",
|
||||
"Nao consigo mudar uid para %d\n",
|
||||
"Sem memoria para o environment\n",
|
||||
"Falta o sinal de '='",
|
||||
"Falta o nome da variavel",
|
||||
"Falta a expressao",
|
||||
"Nao consigo resetar a data de acesso de %s\n",
|
||||
"Remind: '-i' opcao: %s\n",
|
||||
"Sem compromissos.",
|
||||
"%d compromisso(s) colocados na fila para mais tarde.\n",
|
||||
"Esperando numero",
|
||||
"Funcao ilegal na clausula WARN",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT",
|
||||
"Esperando nome do dia da semana",
|
||||
"Nome de argumento duplicado",
|
||||
"A avaliação da expressão está desabilitada",
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> VERSAO BETA <<<<\n");
|
||||
#endif
|
||||
fprintf(ErrFp, "Uso: remind [opcoes] arquivo [data] [hora] [*rep]\n");
|
||||
fprintf(ErrFp, "Opcoes:\n");
|
||||
fprintf(ErrFp, " -n Imprime a proxima ocorrencia em formato simples\n");
|
||||
fprintf(ErrFp, " -r Desabilita a diretiva RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Produz calendario para n (default 1) meses\n");
|
||||
fprintf(ErrFp, " -c+[n] Produz calendario para n (default 1) semanas\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Especifica largura, preenchimento e espacejamento do calendario\n");
|
||||
fprintf(ErrFp, " -s[+][n] Produz um `calendario simples' para n (1) meses (semanas)\n");
|
||||
fprintf(ErrFp, " -p[n] Identico a -s, porem com saida compativel com rem2ps\n");
|
||||
fprintf(ErrFp, " -v Modo verbose\n");
|
||||
fprintf(ErrFp, " -o Ignora diretivas ONCE\n");
|
||||
fprintf(ErrFp, " -t Aciona todos os compromissos futuros, sem considerar o delta\n");
|
||||
fprintf(ErrFp, " -h Modo `Hush' - quieto\n");
|
||||
fprintf(ErrFp, " -a Nao aciona compromissos com hora imediatamente - apenas coloca na fila\n");
|
||||
fprintf(ErrFp, " -q Nao coloca compromissos com hora na fila\n");
|
||||
fprintf(ErrFp, " -f Aciona compromissos com hora em modo foreground\n");
|
||||
fprintf(ErrFp, " -z[n] Modo `daemon', acordando a cada n (5) minutos.\n");
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trigger v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Desvia mensagens normalmente enviadas a stderr para stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Formato da hora para o cal: 0=am/pm, 1=24hr, 2=nenhum\n");
|
||||
fprintf(ErrFp, " -x[n] Limite de iteracoes para a clausula SATISFY (default=1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Executa `cmd' para os compromissos com MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Classifica compromissos por data, hora e prioridade antes de exibir\n");
|
||||
fprintf(ErrFp, " -ivar=val Inicializa (e preserva) variavel var com val\n");
|
||||
fprintf(ErrFp, " -m Inicia o calendario na segunda, ao inves de domingo\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
@@ -1,105 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ROMANIAN.H */
|
||||
/* */
|
||||
/* Support for the Romanian language. */
|
||||
/* */
|
||||
/* Contributed by Liviu Daia <daia@stoilow.imar.ro> */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1996-1998 by Liviu Daia */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Romanian"
|
||||
|
||||
/* Day names */
|
||||
# define L_SUNDAY "Duminică"
|
||||
# define L_MONDAY "Luni"
|
||||
# define L_TUESDAY "Marți"
|
||||
# define L_WEDNESDAY "Miercuri"
|
||||
# define L_THURSDAY "Joi"
|
||||
# define L_FRIDAY "Vineri"
|
||||
# define L_SATURDAY "Sâmbătă"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Ianuarie"
|
||||
#define L_FEB "Februarie"
|
||||
#define L_MAR "Martie"
|
||||
#define L_APR "Aprilie"
|
||||
#define L_MAY "Mai"
|
||||
#define L_JUN "Iunie"
|
||||
#define L_JUL "Iulie"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "Septembrie"
|
||||
#define L_OCT "Octombrie"
|
||||
#define L_NOV "Noiembrie"
|
||||
#define L_DEC "Decembrie"
|
||||
|
||||
/* Today and tomorrow */
|
||||
# define L_TODAY "astăzi"
|
||||
# define L_TOMORROW "mâine"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Reamintiri pentru %w, %d %m %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "acum"
|
||||
#define L_FROMNOW "peste"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "peste %d zile"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "pe"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "le"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "acum"
|
||||
#define L_AT "la ora"
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "or"
|
||||
#define L_IS "este"
|
||||
#define L_WAS "a fost"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "e"
|
||||
#define L_HPLU "e"
|
||||
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU_OVER hplu = (hdiff == 1 ? "ă" : "e");
|
||||
#define L_AND "şi"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
#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[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[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); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "%s %d %s%s", when, mdiff, L_MINUTE, mplu); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "%s %d %s%s", when, hdiff, L_HOUR, hplu); \
|
||||
else \
|
||||
sprintf(s, "%s %d %s%s %s %d %s%s", when, hdiff, \
|
||||
L_HOUR, hplu, L_AND, mdiff, L_MINUTE, mplu);
|
||||
@@ -1,74 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SPANISH.H */
|
||||
/* */
|
||||
/* Support for the Spanish language. */
|
||||
/* */
|
||||
/* Author: Rafa Couto <rafacouto@biogate.com> */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#define L_LANGNAME "Spanish"
|
||||
|
||||
/* Nombres de los di'as de la semana */
|
||||
#define L_SUNDAY "Domingo"
|
||||
#define L_MONDAY "Lunes"
|
||||
#define L_TUESDAY "Martes"
|
||||
#define L_WEDNESDAY "Miércoles"
|
||||
#define L_THURSDAY "Jueves"
|
||||
#define L_FRIDAY "Viernes"
|
||||
#define L_SATURDAY "Sábado"
|
||||
|
||||
/* Nombres de los meses */
|
||||
#define L_JAN "Enero"
|
||||
#define L_FEB "Febrero"
|
||||
#define L_MAR "Marzo"
|
||||
#define L_APR "Abril"
|
||||
#define L_MAY "Mayo"
|
||||
#define L_JUN "Junio"
|
||||
#define L_JUL "Julio"
|
||||
#define L_AUG "Agosto"
|
||||
#define L_SEP "Septiembre"
|
||||
#define L_OCT "Octubre"
|
||||
#define L_NOV "Noviembre"
|
||||
#define L_DEC "Diciembre"
|
||||
|
||||
/* Hoy y man~ana */
|
||||
#define L_TODAY "hoy"
|
||||
#define L_TOMORROW "mañana"
|
||||
|
||||
/* El titular habitual */
|
||||
#define L_BANNER "Agenda para el %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Hace y desde hoy */
|
||||
#define L_AGO "hace"
|
||||
#define L_FROMNOW "desde hoy"
|
||||
|
||||
/* "dentro de %d di'as" */
|
||||
#define L_INXDAYS "dentro de %d días"
|
||||
#define L_ON "el día"
|
||||
|
||||
/* "el di'a..." */
|
||||
|
||||
/* plurales */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutos, horas, a las, etc */
|
||||
#define L_NOW "ahora"
|
||||
#define L_AT "a las"
|
||||
#define L_MINUTE "minuto"
|
||||
#define L_HOUR "hora"
|
||||
#define L_IS "es"
|
||||
#define L_WAS "fue"
|
||||
#define L_AND "y"
|
||||
#define L_HPLU "s"
|
||||
#define L_MPLU "s"
|
||||
|
||||
214
src/main.c
214
src/main.c
@@ -6,7 +6,7 @@
|
||||
/* routines, etc. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -60,17 +60,21 @@ exitfunc(void)
|
||||
/* Kill any execution-time-limiter process */
|
||||
unlimit_execution_time();
|
||||
|
||||
int maxlen, total;
|
||||
double avglen;
|
||||
if (DebugFlag & DB_PARSE_EXPR) {
|
||||
if (DebugFlag & DB_HASHSTATS) {
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
get_var_hash_stats(&total, &maxlen, &avglen);
|
||||
fprintf(stderr, " Var hash: total = %d; maxlen = %d; avglen = %.3f\n", total, maxlen, avglen);
|
||||
get_userfunc_hash_stats(&total, &maxlen, &avglen);
|
||||
fprintf(stderr, " Func hash: total = %d; maxlen = %d; avglen = %.3f\n", total, maxlen, avglen);
|
||||
get_dedupe_hash_stats(&total, &maxlen, &avglen);
|
||||
fprintf(stderr, "Dedup hash: total = %d; maxlen = %d; avglen = %.3f\n", total, maxlen, avglen);
|
||||
fflush(ErrFp);
|
||||
fprintf(ErrFp, "Variable hash table statistics:\n");
|
||||
dump_var_hash_stats();
|
||||
|
||||
fprintf(ErrFp, "Function hash table statistics:\n");
|
||||
dump_userfunc_hash_stats();
|
||||
|
||||
fprintf(ErrFp, "Dedupe hash table statistics:\n");
|
||||
dump_dedupe_hash_stats();
|
||||
|
||||
fprintf(ErrFp, "Translation hash table statistics:\n");
|
||||
dump_translation_hash_stats();
|
||||
|
||||
UnsetAllUserFuncs();
|
||||
print_expr_nodes_stats();
|
||||
}
|
||||
@@ -126,7 +130,7 @@ int main(int argc, char *argv[])
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = SA_RESTART;
|
||||
if (sigaction(SIGALRM, &act, NULL) < 0) {
|
||||
fprintf(stderr, "%s: sigaction() failed: %s\n",
|
||||
fprintf(ErrFp, "%s: sigaction() failed: %s\n",
|
||||
argv[0], strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
@@ -135,7 +139,7 @@ int main(int argc, char *argv[])
|
||||
act.sa_flags = SA_RESTART;
|
||||
sigemptyset(&act.sa_mask);
|
||||
if (sigaction(SIGXCPU, &act, NULL) < 0) {
|
||||
fprintf(stderr, "%s: sigaction() failed: %s\n",
|
||||
fprintf(ErrFp, "%s: sigaction() failed: %s\n",
|
||||
argv[0], strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
@@ -170,11 +174,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (!Hush) {
|
||||
if (DestroyOmitContexts(1))
|
||||
Eprint("%s", ErrMsg[E_PUSH_NOPOP]);
|
||||
Eprint("%s", GetErr(E_PUSH_NOPOP));
|
||||
if (!Daemon && !NextMode && !NumTriggered && !NumQueued) {
|
||||
printf("%s\n", ErrMsg[E_NOREMINDERS]);
|
||||
printf("%s\n", GetErr(E_NOREMINDERS));
|
||||
} else if (!Daemon && !NextMode && !NumTriggered) {
|
||||
printf(ErrMsg[M_QUEUED], NumQueued);
|
||||
printf(GetErr(M_QUEUED), NumQueued);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +198,7 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
if (pid == -1) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[E_CANTFORK]);
|
||||
fprintf(ErrFp, "%s", GetErr(E_CANTFORK));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -256,14 +260,14 @@ static void DoReminders(void)
|
||||
}
|
||||
|
||||
if (FileAccessDate < 0) {
|
||||
fprintf(ErrFp, "%s: `%s': %s.\n", ErrMsg[E_CANTACCESS], InitialFile, strerror(errno));
|
||||
fprintf(ErrFp, "%s: `%s': %s.\n", GetErr(E_CANTACCESS), InitialFile, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
r=IncludeFile(InitialFile);
|
||||
if (r) {
|
||||
fprintf(ErrFp, "%s %s: %s\n", ErrMsg[E_ERR_READING],
|
||||
InitialFile, ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s %s: %s\n", GetErr(E_ERR_READING),
|
||||
InitialFile, GetErr(r));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -271,7 +275,7 @@ static void DoReminders(void)
|
||||
r = ReadLine();
|
||||
if (r == E_EOF) return;
|
||||
if (r) {
|
||||
Eprint("%s: %s", ErrMsg[E_ERR_READING], ErrMsg[r]);
|
||||
Eprint("%s: %s", GetErr(E_ERR_READING), GetErr(r));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
s = FindInitialToken(&tok, CurLine);
|
||||
@@ -312,6 +316,7 @@ static void DoReminders(void)
|
||||
case T_EndIf: r=DoEndif(&p); break;
|
||||
case T_Include:
|
||||
case T_IncludeR:
|
||||
case T_IncludeSys:
|
||||
/* In purge mode, include closes file, so we
|
||||
need to echo it here! */
|
||||
if (PurgeMode) {
|
||||
@@ -352,6 +357,7 @@ static void DoReminders(void)
|
||||
case T_Preserve: r=DoPreserve(&p); break;
|
||||
case T_Push: r=PushOmitContext(&p); break;
|
||||
case T_Expr: r = DoExpr(&p); break;
|
||||
case T_Translate: r = DoTranslate(&p); break;
|
||||
case T_RemType: if (tok.val == RUN_TYPE) {
|
||||
r=DoRun(&p);
|
||||
} else {
|
||||
@@ -378,14 +384,14 @@ static void DoReminders(void)
|
||||
|
||||
}
|
||||
if (r && (!Hush || r != E_RUN_DISABLED)) {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
if (PurgeMode) {
|
||||
if (!purge_handled) {
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
} else {
|
||||
if (r) {
|
||||
PurgeEchoLine("#!P! Could not parse next line: %s\n", ErrMsg[r]);
|
||||
PurgeEchoLine("#!P! Could not parse next line: %s\n", GetErr(r));
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
}
|
||||
@@ -596,6 +602,100 @@ int ParseNonSpaceChar(ParsePtr p, int *err, int peek)
|
||||
return ch;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseTokenOrQuotedString */
|
||||
/* */
|
||||
/* Parse either a token or a double-quote-delimited string. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ParseTokenOrQuotedString(ParsePtr p, DynamicBuffer *dbuf)
|
||||
{
|
||||
int c, err;
|
||||
c = ParseNonSpaceChar(p, &err, 1);
|
||||
if (err) return err;
|
||||
if (c != '"') {
|
||||
return ParseToken(p, dbuf);
|
||||
}
|
||||
return ParseQuotedString(p, dbuf);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseQuotedString */
|
||||
/* */
|
||||
/* Parse a double-quote-delimited string. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ParseQuotedString(ParsePtr p, DynamicBuffer *dbuf)
|
||||
{
|
||||
int c, err;
|
||||
DBufFree(dbuf);
|
||||
c = ParseNonSpaceChar(p, &err, 0);
|
||||
if (err) return err;
|
||||
if (!c) {
|
||||
return E_EOLN;
|
||||
}
|
||||
if (c != '"') {
|
||||
return E_MISS_QUOTE;
|
||||
}
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
while (c != 0 && c != '"') {
|
||||
if (c == '\\') {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
switch(c) {
|
||||
case 'a':
|
||||
err = DBufPutc(dbuf, '\a');
|
||||
break;
|
||||
case 'b':
|
||||
err = DBufPutc(dbuf, '\b');
|
||||
break;
|
||||
case 'f':
|
||||
err = DBufPutc(dbuf, '\f');
|
||||
break;
|
||||
case 'n':
|
||||
err = DBufPutc(dbuf, '\n');
|
||||
break;
|
||||
case 'r':
|
||||
err = DBufPutc(dbuf, '\r');
|
||||
break;
|
||||
case 't':
|
||||
err = DBufPutc(dbuf, '\t');
|
||||
break;
|
||||
case 'v':
|
||||
err = DBufPutc(dbuf, '\v');
|
||||
break;
|
||||
default:
|
||||
err = DBufPutc(dbuf, c);
|
||||
}
|
||||
} else {
|
||||
err = DBufPutc(dbuf, c);
|
||||
}
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
if (c != '"') {
|
||||
DBufFree(dbuf);
|
||||
return E_MISS_QUOTE;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseToken */
|
||||
@@ -970,7 +1070,7 @@ int DoIf(ParsePtr p)
|
||||
else {
|
||||
if ( (r = EvaluateExpr(p, &v)) ) {
|
||||
syndrome = IF_TRUE | BEFORE_ELSE;
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
} else
|
||||
if ( (v.type != STR_TYPE && v.v.val) ||
|
||||
(v.type == STR_TYPE && strcmp(v.v.str, "")) ) {
|
||||
@@ -1055,7 +1155,7 @@ int DoIfTrig(ParsePtr p)
|
||||
if (r) {
|
||||
if (r != E_CANT_TRIG || !trig.maybe_uncomputable) {
|
||||
if (!Hush || r != E_RUN_DISABLED) {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
syndrome = IF_FALSE | BEFORE_ELSE;
|
||||
@@ -1119,7 +1219,7 @@ int VerifyEoln(ParsePtr p)
|
||||
if (*DBufValue(&buf) &&
|
||||
(*DBufValue(&buf) != '#') &&
|
||||
(*DBufValue(&buf) != ';')) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_EXPECTING_EOL], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(E_EXPECTING_EOL), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return E_EXTRANEOUS_TOKEN;
|
||||
}
|
||||
@@ -1173,6 +1273,12 @@ int DoDebug(ParsePtr p)
|
||||
else DebugFlag &= ~DB_PARSE_EXPR;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case 'H':
|
||||
if (val) DebugFlag |= DB_HASHSTATS;
|
||||
else DebugFlag &= ~DB_HASHSTATS;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
case 'X':
|
||||
if (val) DebugFlag |= DB_PRTEXPR;
|
||||
@@ -1900,8 +2006,7 @@ get_day_name(int wkday)
|
||||
if (wkday < 0 || wkday > 6) {
|
||||
return "INVALID_WKDAY";
|
||||
}
|
||||
if (DynamicDayName[wkday]) return DynamicDayName[wkday];
|
||||
return DayName[wkday];
|
||||
return tr(DayName[wkday]);
|
||||
}
|
||||
|
||||
char const *
|
||||
@@ -1910,8 +2015,7 @@ get_month_name(int mon)
|
||||
if (mon < 0 || mon > 11) {
|
||||
return "INVALID_MON";
|
||||
}
|
||||
if (DynamicMonthName[mon]) return DynamicMonthName[mon];
|
||||
return MonthName[mon];
|
||||
return tr(MonthName[mon]);
|
||||
}
|
||||
|
||||
static int GetOnceDateFromFile(void)
|
||||
@@ -1950,3 +2054,53 @@ int GetOnceDate(void)
|
||||
}
|
||||
return OnceDate;
|
||||
}
|
||||
|
||||
static void
|
||||
get_printf_escapes(char const *str, DynamicBuffer *out)
|
||||
{
|
||||
char const *s = str;
|
||||
while(*s) {
|
||||
if (*s == '%' && *(s+1) != 0) {
|
||||
s++;
|
||||
DBufPutc(out, *s);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
char const *GetErr(int r)
|
||||
{
|
||||
char const *msg;
|
||||
DynamicBuffer origEscapes;
|
||||
DynamicBuffer translatedEscapes;
|
||||
int dangerous;
|
||||
|
||||
if (r < 0 || r >= NumErrs) {
|
||||
r = E_SWERR;
|
||||
}
|
||||
|
||||
msg = GetTranslatedString(ErrMsg[r]);
|
||||
if (!msg) {
|
||||
return ErrMsg[r];
|
||||
}
|
||||
|
||||
/* We need to make sure both the original and translated version
|
||||
have the *SAME* printf-style escapes to avoid a malicious
|
||||
translation file doing a format-string attack */
|
||||
DBufInit(&origEscapes);
|
||||
DBufInit(&translatedEscapes);
|
||||
|
||||
get_printf_escapes(ErrMsg[r], &origEscapes);
|
||||
get_printf_escapes(msg, &translatedEscapes);
|
||||
|
||||
dangerous = strcmp(DBufValue(&origEscapes), DBufValue(&translatedEscapes));
|
||||
|
||||
DBufFree(&origEscapes);
|
||||
DBufFree(&translatedEscapes);
|
||||
|
||||
if (dangerous) {
|
||||
return ErrMsg[r];
|
||||
} else {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Calculations for figuring out moon phases. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
39
src/omit.c
39
src/omit.c
@@ -6,7 +6,7 @@
|
||||
/* the data structures for OMITted dates. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -116,10 +116,9 @@ int DestroyOmitContexts(int print_unmatched)
|
||||
/***************************************************************/
|
||||
int PushOmitContext(ParsePtr p)
|
||||
{
|
||||
register int i;
|
||||
OmitContext *context;
|
||||
|
||||
/* Create the saved context */
|
||||
/* Create the saved context */
|
||||
context = NEW(OmitContext);
|
||||
if (!context) return E_NO_MEM;
|
||||
|
||||
@@ -152,14 +151,11 @@ int PushOmitContext(ParsePtr p)
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
/* Copy the context over */
|
||||
for (i=0; i<NumFullOmits; i++)
|
||||
*(context->fullsave + i) = FullOmitArray[i];
|
||||
/* Copy the context over */
|
||||
memcpy(context->fullsave, FullOmitArray, NumFullOmits * sizeof(int));
|
||||
memcpy(context->partsave, PartialOmitArray, NumPartialOmits * sizeof(int));
|
||||
|
||||
for (i=0; i<NumPartialOmits; i++)
|
||||
*(context->partsave + i) = PartialOmitArray[i];
|
||||
|
||||
/* Add the context to the stack */
|
||||
/* Add the context to the stack */
|
||||
context->next = SavedOmitContexts;
|
||||
SavedOmitContexts = context;
|
||||
return VerifyEoln(p);
|
||||
@@ -175,7 +171,6 @@ int PushOmitContext(ParsePtr p)
|
||||
int PopOmitContext(ParsePtr p)
|
||||
{
|
||||
|
||||
register int i;
|
||||
OmitContext *c = SavedOmitContexts;
|
||||
|
||||
if (!c) return E_POP_NO_PUSH;
|
||||
@@ -183,17 +178,17 @@ int PopOmitContext(ParsePtr p)
|
||||
NumPartialOmits = c->numpart;
|
||||
WeekdayOmits = c->weekdaysave;
|
||||
|
||||
/* Copy the context over */
|
||||
for (i=0; i<NumFullOmits; i++)
|
||||
FullOmitArray[i] = *(c->fullsave + i);
|
||||
/* Copy the context over */
|
||||
memcpy(FullOmitArray, c->fullsave, NumFullOmits * sizeof(int));
|
||||
memcpy(PartialOmitArray, c->partsave, NumPartialOmits * sizeof(int));
|
||||
|
||||
for (i=0; i<NumPartialOmits; i++)
|
||||
PartialOmitArray[i] = *(c->partsave + i);
|
||||
|
||||
/* Remove the context from the stack */
|
||||
/* Remove the context from the stack */
|
||||
SavedOmitContexts = c->next;
|
||||
|
||||
/* Free memory used by the saved context */
|
||||
if (c->filename && FileName && strcmp(c->filename, FileName)) {
|
||||
Wprint("POP-OMIT-CONTEXT at %s:%d matches PUSH-OMIT-CONTEXT in different file: %s:%d", FileName, LineNo, c->filename, c->lineno);
|
||||
}
|
||||
/* Free memory used by the saved context */
|
||||
if (c->partsave) free(c->partsave);
|
||||
if (c->fullsave) free(c->fullsave);
|
||||
if (c->filename) free(c->filename);
|
||||
@@ -402,9 +397,9 @@ int DoOmit(ParsePtr p)
|
||||
if (tok.type == T_Until) {
|
||||
Eprint("OMIT: UNTIL not allowed; did you mean THROUGH?");
|
||||
} else if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", ErrMsg[-tok.val], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
} else {
|
||||
Eprint("%s: `%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN],
|
||||
Eprint("%s: `%s' (OMIT)", GetErr(E_UNKNOWN_TOKEN),
|
||||
DBufValue(&buf));
|
||||
}
|
||||
DBufFree(&buf);
|
||||
@@ -552,7 +547,7 @@ DumpOmits(void)
|
||||
} else {
|
||||
for (i=0; i<7; i++) {
|
||||
if (WeekdayOmits & (1<<i)) {
|
||||
printf("\t%s\n", EnglishDayName[i]);
|
||||
printf("\t%s\n", DayName[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
src/protos.h
27
src/protos.h
@@ -5,7 +5,7 @@
|
||||
/* Function Prototypes. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -87,6 +87,8 @@ void FromDSE (int dse, int *y, int *m, int *d);
|
||||
int JulianToGregorianOffset(int y, int m);
|
||||
int ParseChar (ParsePtr p, int *err, int peek);
|
||||
int ParseToken (ParsePtr p, DynamicBuffer *dbuf);
|
||||
int ParseQuotedString (ParsePtr p, DynamicBuffer *dbuf);
|
||||
int ParseTokenOrQuotedString (ParsePtr p, DynamicBuffer *dbuf);
|
||||
int ParseIdentifier (ParsePtr p, DynamicBuffer *dbuf);
|
||||
expr_node * ParseExpr(ParsePtr p, int *r);
|
||||
void print_expr_nodes_stats(void);
|
||||
@@ -111,6 +113,9 @@ int DoDebug (ParsePtr p);
|
||||
int DoBanner (ParsePtr p);
|
||||
int DoRun (ParsePtr p);
|
||||
int DoExpr (ParsePtr p);
|
||||
int DoTranslate (ParsePtr p);
|
||||
int InsertTranslation(char const *orig, char const *translated);
|
||||
void DumpTranslationTable(FILE *fp, int json);
|
||||
int DoErrMsg (ParsePtr p);
|
||||
int ClearGlobalOmits (void);
|
||||
int DoClear (ParsePtr p);
|
||||
@@ -158,7 +163,8 @@ int DoPreserve (Parser *p);
|
||||
int DoSatRemind (Trigger *trig, TimeTrig *tt, ParsePtr p);
|
||||
int DoMsgCommand (char const *cmd, char const *msg, int is_queued);
|
||||
int ParseNonSpaceChar (ParsePtr p, int *err, int peek);
|
||||
unsigned int HashVal (char const *str);
|
||||
unsigned int HashVal_ignorecase(char const *str);
|
||||
unsigned int HashVal_preservecase(char const *str);
|
||||
int DateOK (int y, int m, int d);
|
||||
BuiltinFunc *FindBuiltinFunc (char const *name);
|
||||
int InsertIntoSortBuffer (int dse, int tim, char const *body, int typ, int prio);
|
||||
@@ -223,7 +229,6 @@ void set_cloexec(FILE *fp);
|
||||
int push_call(char const *filename, char const *func, int lineno);
|
||||
void clear_callstack(void);
|
||||
int print_callstack(FILE *fp);
|
||||
int have_callstack(void);
|
||||
void pop_call(void);
|
||||
void FixSpecialType(Trigger *trig);
|
||||
void WriteJSONTrigger(Trigger const *t, int include_tags, int today);
|
||||
@@ -250,11 +255,21 @@ void print_builtinfunc_tokens(void);
|
||||
void print_remind_tokens(void);
|
||||
|
||||
/* Stats for -ds output */
|
||||
void get_var_hash_stats(int *total, int *maxlen, double *avglen);
|
||||
void get_userfunc_hash_stats(int *total, int *maxlen, double *avglen);
|
||||
void get_dedupe_hash_stats(int *total, int *maxlen, double *avglen);
|
||||
void dump_var_hash_stats(void);
|
||||
void dump_userfunc_hash_stats(void);
|
||||
void dump_dedupe_hash_stats(void);
|
||||
void dump_translation_hash_stats(void);
|
||||
|
||||
/* Dedupe code */
|
||||
int ShouldDedupe(int trigger_date, int trigger_time, char const *body);
|
||||
void ClearDedupeTable(void);
|
||||
void InitDedupeTable(void);
|
||||
|
||||
void InitVars(void);
|
||||
void InitUserFunctions(void);
|
||||
void InitTranslationTable(void);
|
||||
char const *GetTranslatedString(char const *orig);
|
||||
int GetTranslatedStringTryingVariants(char const *orig, DynamicBuffer *out);
|
||||
char const *GetErr(int r);
|
||||
char const *tr(char const *s);
|
||||
void print_escaped_string(FILE *fp, char const *s);
|
||||
|
||||
72
src/queue.c
72
src/queue.c
@@ -5,7 +5,7 @@
|
||||
/* Queue up reminders for subsequent execution. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -815,6 +815,11 @@ static void ServerWait(struct timeval *sleep_tv)
|
||||
int y, m, d;
|
||||
int max = 1;
|
||||
char cmdLine[256];
|
||||
char *s;
|
||||
int r;
|
||||
DynamicBuffer tx;
|
||||
|
||||
DBufInit(&tx);
|
||||
|
||||
FD_ZERO(&readSet);
|
||||
FD_SET(0, &readSet);
|
||||
@@ -868,9 +873,32 @@ static void ServerWait(struct timeval *sleep_tv)
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* Read a line from stdin and interpret it */
|
||||
if (!fgets(cmdLine, sizeof(cmdLine), stdin)) {
|
||||
exit(EXIT_SUCCESS);
|
||||
/* Read a line using read() one char at a time to avoid resetting
|
||||
* readability if we get two commands quickly */
|
||||
|
||||
s = cmdLine;
|
||||
*s = 0;
|
||||
while (1) {
|
||||
r = read(fileno(stdin), s, 1);
|
||||
if (r == 0) {
|
||||
/* EOF */
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
if (r != 1) {
|
||||
/* Error? */
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
*(s+1) = 0;
|
||||
if (*s == '\n') {
|
||||
break;
|
||||
}
|
||||
if ((size_t) (s - cmdLine) >= sizeof(cmdLine)-1) {
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
if (!strcmp(cmdLine, "EXIT\n")) {
|
||||
@@ -917,6 +945,42 @@ static void ServerWait(struct timeval *sleep_tv)
|
||||
printf("NOTE ENDJSONQUEUE\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
} else if (DaemonJSON && !strncmp(cmdLine, "TRANSLATE ", 10)) {
|
||||
/* Cut off the trailing "\n" */
|
||||
if (*(cmdLine + strlen(cmdLine)-1) == '\n') {
|
||||
*(cmdLine + strlen(cmdLine)-1) = 0;
|
||||
}
|
||||
|
||||
r = GetTranslatedStringTryingVariants(cmdLine+10, &tx);
|
||||
|
||||
/* Output NOTHING if there's no translation */
|
||||
if (r) {
|
||||
printf("{");
|
||||
PrintJSONKeyPairString("response", "translate");
|
||||
printf("\"translation\":{\"");
|
||||
PrintJSONString(cmdLine+10);
|
||||
printf("\":\"");
|
||||
PrintJSONString(DBufValue(&tx));
|
||||
DBufFree(&tx);
|
||||
printf("\"},");
|
||||
printf("\"command\":\"TRANSLATE\"}\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
} else if (!strcmp(cmdLine, "TRANSLATE_DUMP\n")) {
|
||||
if (!DaemonJSON) {
|
||||
printf("NOTE TRANSLATE_DUMP\n");
|
||||
} else {
|
||||
printf("{");
|
||||
PrintJSONKeyPairString("response", "translate_dump");
|
||||
printf("\"table\":");
|
||||
}
|
||||
DumpTranslationTable(stdout, 1);
|
||||
if (!DaemonJSON) {
|
||||
printf("\nNOTE ENDTRANSLATE_DUMP\n");
|
||||
} else {
|
||||
printf(",\"command\":\"TRANSLATE_DUMP\"}\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
} else if (!strcmp(cmdLine, "REREAD\n")) {
|
||||
if (DaemonJSON) {
|
||||
printf("{\"response\":\"reread\",\"command\":\"REREAD\"}\n");
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Print a PostScript calendar. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -350,13 +350,14 @@ int main(int argc, char *argv[])
|
||||
!strcmp(DBufValue(&buf), PSBEGIN2)) {
|
||||
if (!validfile) {
|
||||
if (Verbose) {
|
||||
fprintf(stderr, "Rem2PS: Version %s Copyright 1992-2024 by Dianne Skoll\n\n", VERSION);
|
||||
fprintf(stderr, "Rem2PS: Version %s Copyright (C) 1992-2025 by Dianne Skoll\n\n", VERSION);
|
||||
fprintf(stderr, "Generating PostScript calendar\n");
|
||||
}
|
||||
}
|
||||
validfile++;
|
||||
DoPsCal();
|
||||
}
|
||||
DBufFree(&buf);
|
||||
}
|
||||
if (!validfile) {
|
||||
fprintf(stderr, "Rem2PS: Couldn't find any calendar data - are you\n");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user