mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-05-06 07:37:58 +02:00
Compare commits
176 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d09abc363 | |||
| 3dcd353fb5 | |||
| 124c5c4e7e | |||
| 77024562b3 | |||
| 35c33ae915 | |||
| 901831ff75 | |||
| e0c5e878a8 | |||
| ffba7fcb03 | |||
| b3f3cb9ce0 | |||
| 6f11e727f8 | |||
| 9f7ea96e87 | |||
| d650b8564c | |||
| 4f2e4030eb | |||
| 447bda5c91 | |||
| 4f351c089e | |||
| 6b31778973 | |||
| dcf8b46beb | |||
| 0f582ccb60 | |||
| 8d0743dd3e | |||
| 436526c27d | |||
| 5f3f3b410f | |||
| 4f79b0d42a | |||
| c96f9f21ed | |||
| dc192f2a69 | |||
| ac3dd1ec7c | |||
| b5717828f0 | |||
| c0d73fb9d1 | |||
| 3a2ac067b0 | |||
| 1d467ab9ed | |||
| c2ec4e9d29 | |||
| 96c11e89eb | |||
| a35920f28e | |||
| 17ccf5d2b4 | |||
| 788a09b2cd | |||
| 9f0e23a307 | |||
| 542620c188 | |||
| 50419bd83a | |||
| 2b7c582392 | |||
| 812a2af64b | |||
| 17d7abd4a4 | |||
| 098e98c59e | |||
| c5e0dbf2e5 | |||
| 18c8bc719f | |||
| 195ed15167 | |||
| 51677cd7b5 | |||
| 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 |
+1
-1
@@ -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
|
||||
@@ -35,3 +34,4 @@ tests/test.out
|
||||
www/Makefile
|
||||
gmon.out
|
||||
tests/once.timestamp
|
||||
src/xlat.c
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/
|
||||
@@ -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/)
|
||||
|
||||
@@ -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))]
|
||||
|
||||
@@ -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.03.
|
||||
#
|
||||
#
|
||||
# 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.03'
|
||||
PACKAGE_STRING='remind 05.02.03'
|
||||
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.03 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.03:";;
|
||||
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.03
|
||||
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.03, 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.03, 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.03
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+1
-1
@@ -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.03, , , 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
|
||||
|
||||
+4
-79
@@ -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/
|
||||
|
||||
+107
@@ -1,5 +1,112 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 5.2 Patch 3 - 2025-01-22
|
||||
|
||||
- NEW FEATURE: remind: Add "TRANSLATE GENERATE" command for generating
|
||||
a skeleton set of TRANSLATE commands to make it easier to localize
|
||||
Remind.
|
||||
|
||||
- NEW FEATURE: remind: Add "q" debug flag for tracing calls to _()
|
||||
or %(...) in the substitution filter; this will help with localizing
|
||||
reminder files.
|
||||
|
||||
- NEW FILES: remind: Add holidays/lgbtq.rem for LGBTQ holidays. Add
|
||||
country-specific files in holidays/lgbtq/*.rem
|
||||
|
||||
- IMPROVEMENT: TkRemind: use "info patchlevel" to display full Tcl/Tk
|
||||
version.
|
||||
|
||||
- IMPROVEMENT: remind: The DEBUG command issues a warning if given an
|
||||
unknown debug flag.
|
||||
|
||||
- BUG FIX: remind: "make test" will now succeed even if run between
|
||||
23:55 and 00:00 UTC. This is done with a new --test flag for remind.
|
||||
|
||||
- BUG FIX: remind: Avoid potential buffer overflow if someone supplies
|
||||
ridiculously-long translations for "am" or "pm".
|
||||
|
||||
* 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.
|
||||
|
||||
+1
-1
@@ -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,30 @@
|
||||
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)
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
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))
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# List of LGBTQ awareness days
|
||||
# Sourced from https://en.wikipedia.org/wiki/List_of_LGBTQ_awareness_periods
|
||||
# These are the internationally-recognized days.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
REM Sun 14 Feb MSG Start of Aromantic Spectrum Awareness Week
|
||||
REM 1 Mar MSG Zero Discrimination Day
|
||||
REM 31 Mar MSG Trans Day of Visibility
|
||||
REM 6 Apr MSG International Asexuality Day
|
||||
REM Wed 8 Apr MSG International Day of Pink
|
||||
REM 26 Apr MSG Lesbian Visibility Day
|
||||
REM 17 May MSG International Day Against Homophobia, Biphobia and Transphobia
|
||||
REM 19 May MSG Agender Pride Day
|
||||
REM 24 May MSG Pansexual & Panromantic Awareness Day
|
||||
REM 1 Jun MSG Start of LGBT Pride Month
|
||||
REM 5 Jun MSG Aromantic Visibility Day
|
||||
REM Mon 8 Jul MSG Start of Non-Binary Awareness Week
|
||||
REM 14 Jul MSG Non-Binary People's Day
|
||||
REM 16 Jul MSG Drag Day
|
||||
REM 9 Aug MSG Start of Dyke Week
|
||||
REM 16 Sep MSG Start of Bisexual Awareness Week
|
||||
REM 23 Sep MSG Celebrate Bisexuality Day
|
||||
REM 8 Oct MSG Lesbian Day
|
||||
REM 11 Oct MSG National Coming Out Day
|
||||
REM Wed 15 Oct MSG Pronouns Day
|
||||
REM 17 Oct MSG Start of Genderfluid Visibility Week
|
||||
REM Sun 19 Oct MSG Start of Ace Week
|
||||
REM 26 Oct MSG Intersex Awareness Day
|
||||
REM 8 Nov MSG Intersex Day of Remembrance
|
||||
REM 1 Nov MSG Start of Trans Awareness Month
|
||||
REM Sun 1 Nov MSG Trans Parent Day
|
||||
REM 13 Nov MSG Start of Trans Awareness Week
|
||||
REM 20 Nov MSG Transgender Day of Remembrance
|
||||
@@ -0,0 +1,8 @@
|
||||
# List of LGBTQ awareness days
|
||||
# Sourced from https://en.wikipedia.org/wiki/List_of_LGBTQ_awareness_periods
|
||||
# These are the holidays recognized in Australia
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
REM Sat 1 Mar MSG Mardi Gras Parade
|
||||
REM Fri 1 Sep --7 MSG Wear it Purple Day
|
||||
REM 1 Oct MSG Start of LGBT History Month
|
||||
@@ -0,0 +1,10 @@
|
||||
# List of LGBTQ awareness days
|
||||
# Sourced from https://en.wikipedia.org/wiki/List_of_LGBTQ_awareness_periods
|
||||
# These are the holidays recognized in Brazil
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
REM 29 Jan MSG National Day of Transgender Visibility
|
||||
REM 20 Feb MSG Trans Men and Transmasculine Day
|
||||
REM 25 Mar MSG National Gay Pride Day
|
||||
REM 29 Aug MSG National Day of Lesbian Visibility
|
||||
@@ -0,0 +1,7 @@
|
||||
# List of LGBTQ awareness days
|
||||
# Sourced from https://en.wikipedia.org/wiki/List_of_LGBTQ_awareness_periods
|
||||
# These are the holidays recognized in Canada
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
REM 1 Oct MSG Start of LGBT History Month
|
||||
@@ -0,0 +1,7 @@
|
||||
# List of LGBTQ awareness days
|
||||
# Sourced from https://en.wikipedia.org/wiki/List_of_LGBTQ_awareness_periods
|
||||
# These are the holidays recognized in Chile
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
REM 9 Jul MSG Lesbian Visibility Day
|
||||
@@ -0,0 +1,7 @@
|
||||
# List of LGBTQ awareness days
|
||||
# Sourced from https://en.wikipedia.org/wiki/List_of_LGBTQ_awareness_periods
|
||||
# These are the holidays recognized in Ireland
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
REM 22 May MSG Irish Marriage Referendum Day
|
||||
@@ -0,0 +1,7 @@
|
||||
# List of LGBTQ awareness days
|
||||
# Sourced from https://en.wikipedia.org/wiki/List_of_LGBTQ_awareness_periods
|
||||
# These are the holidays recognized in India
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
REM 2 Jul MSG Indian Coming Out Day
|
||||
@@ -0,0 +1,7 @@
|
||||
# List of LGBTQ awareness days
|
||||
# Sourced from https://en.wikipedia.org/wiki/List_of_LGBTQ_awareness_periods
|
||||
# These are the holidays recognized in the Netherlands
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
REM Fri 8 Dec MSG Purple Friday
|
||||
@@ -0,0 +1,7 @@
|
||||
# List of LGBTQ awareness days
|
||||
# Sourced from https://en.wikipedia.org/wiki/List_of_LGBTQ_awareness_periods
|
||||
# These are the holidays recognized in Ukraine
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
REM 12 Dec MSG Day of Remembrance of Homosexuals in Ukraine (victims of the totalitarian Soviet regime)
|
||||
@@ -0,0 +1,8 @@
|
||||
# List of LGBTQ awareness days
|
||||
# Sourced from https://en.wikipedia.org/wiki/List_of_LGBTQ_awareness_periods
|
||||
# These are the holidays recognized in the United Kingdom
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
REM 1 Feb MSG Start of LGBT History Month
|
||||
REM 6 May MSG Start of Trans+ History Week
|
||||
@@ -0,0 +1,16 @@
|
||||
# List of LGBTQ awareness days
|
||||
# Sourced from https://en.wikipedia.org/wiki/List_of_LGBTQ_awareness_periods
|
||||
# These are the holidays recognized in the United States of America
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
REM 1 Mar MSG Start of Bisexual Health Awareness Month
|
||||
REM Fri 8 Apr MSG Day of Silence
|
||||
REM 9 Apr MSG Sapphic Visibility Day
|
||||
REM 22 May MSG Harvey Milk Day
|
||||
REM 5 Jun MSG HIV Long-Term Survivors Awareness Day
|
||||
REM 12 Jun MSG Pulse Night of Remembrance
|
||||
REM 28 Jun MSG Stonewall Riots Anniversary
|
||||
REM 1 Aug MSG Start of Transgender History Month (CA)
|
||||
REM 1 Oct MSG Start of LGBT History Month
|
||||
REM Thu 15 Oct MSG Spirit Day
|
||||
@@ -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
|
||||
|
||||
+3
-1
@@ -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"
|
||||
|
||||
+3
-1
@@ -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"
|
||||
|
||||
+31
-22
@@ -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
-1
@@ -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.
|
||||
|
||||
+3
-1
@@ -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"
|
||||
|
||||
+103
-1
@@ -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" "Virheellinen järjestelmäpäiväys: vuosi on vähemmän kuin %d"
|
||||
TRANSLATE "Unknown debug flag '%c'" "Tuntematon virheenetsintätarkenne '%c'"
|
||||
TRANSLATE "Unknown option '%c'" "Tuntematon tarkenne '%c'"
|
||||
TRANSLATE "Unknown user '%s'" "Tuntematon käyttäjä '%s'"
|
||||
TRANSLATE "Could not change gid to %d" "Ryhmänumeron vaihto %d:ksi ei onnistunut"
|
||||
TRANSLATE "Could not change uid to %d" "Käyttäjänumeron vaihto %d:ksi ei onnistunut"
|
||||
TRANSLATE "Out of memory for environment" "Muisti ei riitä ympäristölle"
|
||||
TRANSLATE "Missing '=' sign" "Puuttuva '='-merkki"
|
||||
TRANSLATE "Missing variable name" "Puuttuva muuttujanimi"
|
||||
TRANSLATE "Missing expression" "Puuttuva lauseke"
|
||||
TRANSLATE "Remind: '-i' option: %s" "Remind: tarkenne '-i': %s"
|
||||
TRANSLATE "No reminders." "Ei viestejä."
|
||||
TRANSLATE "%d reminder(s) queued for later today." "%d viesti(ä) tämän päivän jonossa."
|
||||
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"
|
||||
|
||||
+103
-1
@@ -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,103 @@ 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" "Date système illégale: Année est inférieure à %d"
|
||||
TRANSLATE "Unknown debug flag '%c'" "Option de déverminage inconnue '%c'"
|
||||
TRANSLATE "Unknown option '%c'" "Option inconnue '%c'"
|
||||
TRANSLATE "Unknown user '%s'" "Usager inconnu '%s'"
|
||||
TRANSLATE "Could not change gid to %d" "Impossible de changer gid pour %d"
|
||||
TRANSLATE "Could not change uid to %d" "Impossible de changer uid pour %d"
|
||||
TRANSLATE "Out of memory for environment" "Manque de mémoire pour environnement"
|
||||
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." "%d rappel(s) en file pour aujourd'hui."
|
||||
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é"
|
||||
TRANSLATE "here" "ici"
|
||||
TRANSLATE "did you mean" "voulais-vous dire"
|
||||
|
||||
+11
-28
@@ -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" "Τέλος θέρους"
|
||||
|
||||
+3
-1
@@ -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"
|
||||
|
||||
+3
-1
@@ -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ì"
|
||||
|
||||
+34
-2
@@ -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."
|
||||
|
||||
+3
-1
@@ -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"
|
||||
|
||||
+104
-1
@@ -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" "Błędna data systemowa: Rok mniejszy niż %d"
|
||||
TRANSLATE "Unknown debug flag '%c'" "Nieznana flaga odpluskwiania '%c'"
|
||||
TRANSLATE "Unknown option '%c'" "Nieznana opcja '%c'"
|
||||
TRANSLATE "Unknown user '%s'" "Nieznany użytkownik '%s'"
|
||||
TRANSLATE "Could not change gid to %d" "Nie mogę zmienić gid na %d"
|
||||
TRANSLATE "Could not change uid to %d" "Nie mogę zmienić uid na %d"
|
||||
TRANSLATE "Out of memory for environment" "Brak pamięci na zmienne środowiska"
|
||||
TRANSLATE "Missing '=' sign" "Brak znaku '='"
|
||||
TRANSLATE "Missing variable name" "Brak nazwy zmiennej"
|
||||
TRANSLATE "Missing expression" "Brak wyrażenia"
|
||||
TRANSLATE "Remind: '-i' option: %s" "Remind: '-i' option: %s"
|
||||
TRANSLATE "No reminders." "Brak przypomnień."
|
||||
TRANSLATE "%d reminder(s) queued for later today." "%d Przypomnienia zakolejkowane na później."
|
||||
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"
|
||||
|
||||
+103
-1
@@ -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" "Data do sistema ilegal: Ano e menor que %d"
|
||||
TRANSLATE "Unknown debug flag '%c'" "Flag de debug desconhecido '%c'"
|
||||
TRANSLATE "Unknown option '%c'" "Opcao desconhecida '%c'"
|
||||
TRANSLATE "Unknown user '%s'" "Usuario desconhecido '%s'"
|
||||
TRANSLATE "Could not change gid to %d" "Nao consigo mudar gid para %d"
|
||||
TRANSLATE "Could not change uid to %d" "Nao consigo mudar uid para %d"
|
||||
TRANSLATE "Out of memory for environment" "Sem memoria para o environment"
|
||||
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" "Remind: '-i' opcao: %s"
|
||||
TRANSLATE "No reminders." "Sem compromissos."
|
||||
TRANSLATE "%d reminder(s) queued for later today." "%d compromisso(s) colocados na fila para mais tarde."
|
||||
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"
|
||||
|
||||
+3
-1
@@ -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
|
||||
|
||||
+8
-8
@@ -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
|
||||
|
||||
@@ -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
|
||||
+83
-27
@@ -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>
|
||||
|
||||
+252
-56
@@ -182,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
|
||||
@@ -200,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.
|
||||
@@ -310,6 +315,13 @@ 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.
|
||||
.TP
|
||||
.B q
|
||||
Output a TRANSLATE command each time the \fB_()\fR built-in function
|
||||
is called or the \fB%(...)\fR substitution sequence is encountered.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-g\fR[\fBa|d\fR[\fBa|d\fR[\fBa|d\fR[\fBa|d\fR]]]]
|
||||
@@ -469,6 +481,22 @@ 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. See also TRANSLATE GENERATE in the section
|
||||
"THE TRANSLATION TABLE".
|
||||
.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
|
||||
@@ -502,11 +530,16 @@ resources. Note that the limit \fIn\fR is approximate and
|
||||
\fBRemind\fR might execute for one or two more seconds before it is
|
||||
killed. If \fIn\fR is specified as zero, then no limit is applied, just
|
||||
as if the option had not been used at all.
|
||||
.RS
|
||||
.PP
|
||||
If a limit is applied, it applies only to the foreground run of \fBRemind\fR.
|
||||
If \fBRemind\fR finishes processing the script and then starts handling
|
||||
queued reminders, the time limit is reset to no limit.
|
||||
.PP
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-test
|
||||
The \fB\-\-test\fR long option is only for use by the acceptance tests
|
||||
run by "make test". Do not use this option in production.
|
||||
.SH REMINDER FILES
|
||||
.PP
|
||||
\fBRemind\fR uses scripts to control its operation. You can use any
|
||||
@@ -1196,7 +1229,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
|
||||
@@ -1598,6 +1631,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
|
||||
@@ -1906,22 +1943,21 @@ 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.
|
||||
@@ -1963,6 +1999,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
|
||||
@@ -2039,7 +2080,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).
|
||||
@@ -2491,7 +2532,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
|
||||
@@ -2512,12 +2553,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.
|
||||
@@ -2572,7 +2618,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
|
||||
@@ -2767,7 +2813,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
|
||||
@@ -2949,7 +2995,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.
|
||||
@@ -3018,6 +3064,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
|
||||
@@ -3474,12 +3555,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
|
||||
@@ -3969,7 +4051,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
|
||||
@@ -5523,22 +5608,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:
|
||||
@@ -5552,7 +5628,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)
|
||||
@@ -5656,6 +5732,127 @@ 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 four 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
|
||||
The fourth form, \fBTRANSLATE GENERATE\fR, dumps all of the
|
||||
strings that can be localized (as a series of TRANSLATE commands) to
|
||||
standard output. Strings that are already localized are output
|
||||
with their localization; strings that are not localized are
|
||||
output as:
|
||||
.PP
|
||||
.nf
|
||||
TRANSLATE "untranslated" ""
|
||||
.nf
|
||||
.PP
|
||||
If you want to add a new language, you can obtain a skeleton translation
|
||||
file by running:
|
||||
.PP
|
||||
.nf
|
||||
echo "TRANSLATE GENERATE" | remind -h - > /tmp/skeleton.rem
|
||||
.fi
|
||||
.PP
|
||||
If you have an existing language file that is missing some translations,
|
||||
you can update it by running:
|
||||
.PP
|
||||
.nf
|
||||
(echo INCLUDE mylang.rem; echo TRANSLATE GENERATE) | \\
|
||||
remind -h - > /tmp/mylang-update.rem
|
||||
.fi
|
||||
.PP
|
||||
and then editing \fBmylang-update.rem\fR to add in the missing translations.
|
||||
.PP
|
||||
If you have some reminder scripts that use the \fB_()\fR built-in function
|
||||
or \fB%(...)\fR substitution sequence, you can generate a list of needed
|
||||
TRANSLATE commands by running:
|
||||
.PP
|
||||
.nf
|
||||
remind -q -n -dq myscript.rem 2>&1 | grep ^TRANSLATE | sort | uniq
|
||||
.fi
|
||||
.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
|
||||
@@ -5670,14 +5867,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
|
||||
@@ -6189,16 +6386,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
|
||||
|
||||
+34
-1
@@ -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
|
||||
|
||||
|
||||
+303
-73
@@ -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();
|
||||
|
||||
+29
-13
@@ -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>
|
||||
|
||||
+260
-9
@@ -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;
|
||||
|
||||
|
||||
+62
-11
@@ -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
|
||||
@@ -780,7 +798,7 @@ proc EditOptions {} {
|
||||
pack $w.f -side top -expand 1 -fill both
|
||||
pack $w.b -side top -expand 0 -fill x
|
||||
|
||||
label $w.ver -text "TkRemind version @VERSION@ on Tcl/Tk version [info tclversion] with Remind version $ver"
|
||||
label $w.ver -text "TkRemind version @VERSION@ on Tcl/Tk version [info patchlevel] with Remind version $ver"
|
||||
pack $w.ver -in $w.f -side top -expand 0 -fill x
|
||||
# Start iconified
|
||||
checkbutton $w.startIconified -text "Start up Iconified" \
|
||||
@@ -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"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-7
@@ -27,13 +27,15 @@ 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 \
|
||||
XLATSRC= xlat.c
|
||||
|
||||
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)
|
||||
REMINDOBJS= $(REMINDSRCS:.c=.o) $(XLATSRC:.c=.o)
|
||||
|
||||
all: remind rem2ps
|
||||
|
||||
@@ -41,7 +43,14 @@ 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) $<
|
||||
|
||||
xlat.c: $(REMINDSRCS)
|
||||
@echo "#include <stddef.h>" > xlat.c
|
||||
@echo "char const *translatables[] = {" >> xlat.c
|
||||
@cat $(REMINDSRCS) | grep 'tr(".*")' | sed -e 's/.*tr."/"/' -e 's/").*/"/' | sort | uniq | grep -E -v '^"(am|at|from now|hour|minute|now|on|pm|today|tomorrow|was)"$$' | sed -e 's/^/ /' -e 's/$$/,/' >> xlat.c
|
||||
@echo " NULL" >> xlat.c
|
||||
@echo "};" >> xlat.c
|
||||
|
||||
$(REMINDOBJS): $(REMINDHDRS)
|
||||
|
||||
@@ -80,7 +89,7 @@ install-stripped: install
|
||||
strip $(DESTDIR)$(bindir)/rem2ps || true
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ core *.bak $(PROGS)
|
||||
rm -f *.o *~ core *.bak $(PROGS) $(XLATSRC)
|
||||
|
||||
clobber:
|
||||
rm -f *.o *~ remind rem2ps test.out core *.bak
|
||||
|
||||
+89
-30
@@ -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);
|
||||
@@ -499,7 +499,7 @@ get_month_abbrev(char const *mon)
|
||||
{
|
||||
static char buf[80];
|
||||
#ifndef REM_USE_WCHAR
|
||||
sprintf(buf, "%.3s", mon);
|
||||
snprintf(buf, sizeof(buf), "%.3s", mon);
|
||||
return buf;
|
||||
#else
|
||||
char *s;
|
||||
@@ -626,9 +626,9 @@ Colorize256(int r, int g, int b, int bg, int clamp)
|
||||
}
|
||||
}
|
||||
if (bg) {
|
||||
sprintf(buf, "\x1B[48;5;%dm", best);
|
||||
snprintf(buf, sizeof(buf), "\x1B[48;5;%dm", best);
|
||||
} else {
|
||||
sprintf(buf, "\x1B[38;5;%dm", best);
|
||||
snprintf(buf, sizeof(buf), "\x1B[38;5;%dm", best);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
@@ -641,9 +641,9 @@ ColorizeTrue(int r, int g, int b, int bg, int clamp)
|
||||
ClampColor(&r, &g, &b);
|
||||
}
|
||||
if (bg) {
|
||||
sprintf(buf, "\x1B[48;2;%d;%d;%dm", r, g, b);
|
||||
snprintf(buf, sizeof(buf), "\x1B[48;2;%d;%d;%dm", r, g, b);
|
||||
} else {
|
||||
sprintf(buf, "\x1B[38;2;%d;%d;%dm", r, g, b);
|
||||
snprintf(buf, sizeof(buf), "\x1B[38;2;%d;%d;%dm", r, g, b);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
@@ -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);
|
||||
@@ -1753,7 +1812,7 @@ static void WriteCalHeader(void)
|
||||
int y, m, d;
|
||||
|
||||
FromDSE(DSEToday, &y, &m, &d);
|
||||
sprintf(buf, "%s %d", get_month_name(m), y);
|
||||
snprintf(buf, sizeof(buf), "%s %d", get_month_name(m), y);
|
||||
|
||||
WriteTopCalLine();
|
||||
|
||||
@@ -1957,7 +2016,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
trig.typ == MSF_TYPE) {
|
||||
if (PsCal && is_color) {
|
||||
char cbuf[24];
|
||||
sprintf(cbuf, "%d %d %d ", col_r, col_g, col_b);
|
||||
snprintf(cbuf, sizeof(cbuf), "%d %d %d ", col_r, col_g, col_b);
|
||||
DBufPuts(&pre_buf, cbuf);
|
||||
strcpy(trig.passthru, "COLOR");
|
||||
/* Don't change trig.typ or next if() will trigger! */
|
||||
@@ -2090,7 +2149,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
if (trig.typ != PASSTHRU_TYPE &&
|
||||
UserFuncExists("calprefix")==1) {
|
||||
char evalBuf[64];
|
||||
sprintf(evalBuf, "calprefix(%d)", trig.priority);
|
||||
snprintf(evalBuf, sizeof(evalBuf), "calprefix(%d)", trig.priority);
|
||||
s2 = evalBuf;
|
||||
r = EvalExpr(&s2, &v, NULL);
|
||||
if (!r) {
|
||||
@@ -2133,7 +2192,7 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
if (trig.typ != PASSTHRU_TYPE &&
|
||||
UserFuncExists("calsuffix")==1) {
|
||||
char evalBuf[64];
|
||||
sprintf(evalBuf, "calsuffix(%d)", trig.priority);
|
||||
snprintf(evalBuf, sizeof(evalBuf), "calsuffix(%d)", trig.priority);
|
||||
s2 = evalBuf;
|
||||
r = EvalExpr(&s2, &v, NULL);
|
||||
if (!r) {
|
||||
@@ -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("],");
|
||||
@@ -2677,20 +2736,20 @@ CalendarTime(int tim, int duration)
|
||||
else hh2 = h2;
|
||||
|
||||
if (days) {
|
||||
sprintf(daybuf, "+%d", days);
|
||||
snprintf(daybuf, sizeof(daybuf), "+%d", days);
|
||||
} else {
|
||||
daybuf[0] = 0;
|
||||
}
|
||||
|
||||
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)) {
|
||||
@@ -2700,12 +2759,12 @@ CalendarTime(int tim, int duration)
|
||||
|
||||
switch(ScFormat) {
|
||||
case SC_AMPM:
|
||||
sprintf(buf, "%d%c%02d%s-%d%c%02d%s%s ",
|
||||
snprintf(buf, sizeof(buf), "%d%c%02d%s-%d%c%02d%s%s ",
|
||||
hh, TimeSep, min, ampm1, hh2, TimeSep, min2, ampm2, daybuf);
|
||||
break;
|
||||
|
||||
case SC_MIL:
|
||||
sprintf(buf, "%02d%c%02d-%02d%c%02d%s ",
|
||||
snprintf(buf, sizeof(buf), "%02d%c%02d-%02d%c%02d%s ",
|
||||
h, TimeSep, min, h2, TimeSep, min2, daybuf);
|
||||
break;
|
||||
}
|
||||
@@ -2723,7 +2782,7 @@ CalendarTime(int tim, int duration)
|
||||
/***************************************************************/
|
||||
char const *SimpleTime(int tim)
|
||||
{
|
||||
static char buf[32];
|
||||
static char buf[128];
|
||||
int h, min, hh;
|
||||
|
||||
buf[0] = 0;
|
||||
@@ -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);
|
||||
snprintf(buf, sizeof(buf), "%d%c%02d%.64s ", hh, TimeSep, min, (h>=12) ? tr("pm") : tr("am"));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2745,7 +2804,7 @@ char const *SimpleTime(int tim)
|
||||
if (tim != NO_TIME) {
|
||||
h = tim / 60;
|
||||
min = tim % 60;
|
||||
sprintf(buf, "%02d%c%02d ", h, TimeSep, min);
|
||||
snprintf(buf, sizeof(buf), "%02d%c%02d ", h, TimeSep, min);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2797,7 +2856,7 @@ char const *SynthesizeTag(void)
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, (unsigned char *) CurLine, strlen(CurLine));
|
||||
MD5Final(buf, &ctx);
|
||||
sprintf(out, "__syn__%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
snprintf(out, sizeof(out), "__syn__%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
(unsigned int) buf[0], (unsigned int) buf[1],
|
||||
(unsigned int) buf[2], (unsigned int) buf[3],
|
||||
(unsigned int) buf[4], (unsigned int) buf[5],
|
||||
|
||||
@@ -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(@_);
|
||||
}
|
||||
+3
-3
@@ -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"
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
+1
-1
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
+49
-69
@@ -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);
|
||||
}
|
||||
|
||||
+52
-52
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -67,18 +67,18 @@ check_trigger_function(char const *fname, char const *type)
|
||||
if (!f) {
|
||||
if (strcmp(type, "WARN")) {
|
||||
/* Undefined WARN functions are diagnosed elsewhere... */
|
||||
Wprint("Undefined %s function: `%s'", type, fname);
|
||||
Wprint(tr("Undefined %s function: `%s'"), type, fname);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (f->nargs != 1) {
|
||||
Wprint("%s function `%s' defined at %s:%d should take 1 argument but actually takes %d", type, fname, f->filename, f->lineno, f->nargs);
|
||||
Wprint(tr("%s function `%s' defined at %s:%d should take 1 argument but actually takes %d"), type, fname, f->filename, f->lineno, f->nargs);
|
||||
return;
|
||||
}
|
||||
if (ensure_expr_references_first_local_arg(f->node)) {
|
||||
return;
|
||||
}
|
||||
Wprint("%s function `%s' defined at %s:%d does not use its argument", type, fname, f->filename, f->lineno);
|
||||
Wprint(tr("%s function `%s' defined at %s:%d does not use its argument"), type, fname, f->filename, f->lineno);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -154,7 +154,7 @@ static void ensure_satnode_mentions_trigdate(expr_node *node)
|
||||
if (node->type == N_CONSTANT) {
|
||||
if (node->u.value.type == INT_TYPE) {
|
||||
if (node->u.value.v.val == 0) {
|
||||
Wprint("SATISFY: constant 0 will never be true");
|
||||
Wprint(tr("SATISFY: constant 0 will never be true"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -166,14 +166,14 @@ static void ensure_satnode_mentions_trigdate(expr_node *node)
|
||||
str = node->u.name;
|
||||
}
|
||||
if (!*str) {
|
||||
Wprint("SATISFY: constant \"\" will never be true");
|
||||
Wprint(tr("SATISFY: constant \"\" will never be true"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ensure_satnode_mentions_trigdate_aux(node, &mentioned);
|
||||
if (!mentioned) {
|
||||
Wprint("SATISFY: expression has no reference to trigdate() or $T...");
|
||||
Wprint(tr("SATISFY: expression has no reference to trigdate() or $T..."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
@@ -615,7 +615,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
case T_Omit:
|
||||
DBufFree(&buf);
|
||||
if (trig->omitfunc[0]) {
|
||||
Wprint("Warning: OMIT is ignored if you use OMITFUNC");
|
||||
Wprint(tr("Warning: OMIT is ignored if you use OMITFUNC"));
|
||||
}
|
||||
|
||||
r = ParseLocalOmit(s, trig);
|
||||
@@ -629,7 +629,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
|
||||
case T_OmitFunc:
|
||||
if (trig->localomit) {
|
||||
Wprint("Warning: OMIT is ignored if you use OMITFUNC");
|
||||
Wprint(tr("Warning: OMIT is ignored if you use OMITFUNC"));
|
||||
}
|
||||
r=ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -707,7 +707,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
trig->typ = MSG_TYPE;
|
||||
if (s->isnested) return E_CANT_NEST_RTYPE;
|
||||
if (!WarnedAboutImplicit && !SuppressImplicitRemWarnings) {
|
||||
Wprint("Missing REM type; assuming MSG");
|
||||
Wprint(tr("Missing REM type; assuming MSG"));
|
||||
WarnedAboutImplicit = 1;
|
||||
}
|
||||
parsing = 0;
|
||||
@@ -738,22 +738,22 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
if (!s->nonconst_expr) {
|
||||
if (trig->y != NO_YR && trig->m != NO_MON && trig->d != NO_DAY && trig->until != NO_UNTIL) {
|
||||
if (DSE(trig->y, trig->m, trig->d) > trig->until) {
|
||||
Wprint("Warning: UNTIL/THROUGH date earlier than start date");
|
||||
Wprint(tr("Warning: UNTIL/THROUGH date earlier than start date"));
|
||||
}
|
||||
}
|
||||
if (trig->from != NO_DATE) {
|
||||
if (trig->until != NO_UNTIL && trig->until < trig->from) {
|
||||
Wprint("Warning: UNTIL/THROUGH date earlier than FROM date");
|
||||
Wprint(tr("Warning: UNTIL/THROUGH date earlier than FROM date"));
|
||||
}
|
||||
} else if (trig->scanfrom != NO_DATE) {
|
||||
if (trig->until != NO_UNTIL && trig->until < trig->scanfrom) {
|
||||
Wprint("Warning: UNTIL/THROUGH date earlier than SCANFROM date");
|
||||
Wprint(tr("Warning: UNTIL/THROUGH date earlier than SCANFROM date"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trig->y != NO_YR && trig->m != NO_MON && trig->d != NO_DAY && trig->until != NO_UNTIL && trig->rep == NO_REP) {
|
||||
Wprint("Warning: Useless use of UNTIL with fully-specified date and no *rep");
|
||||
Wprint(tr("Warning: Useless use of UNTIL with fully-specified date and no *rep"));
|
||||
}
|
||||
|
||||
/* Set scanfrom to default if not set explicitly */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1180,7 +1180,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
||||
return OK;
|
||||
}
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
sprintf(tmpBuf, "%04d/%02d/%02d ", y, m+1, d);
|
||||
snprintf(tmpBuf, sizeof(tmpBuf), "%04d/%02d/%02d ", y, m+1, d);
|
||||
if (DBufPuts(&calRow, tmpBuf) != OK) {
|
||||
DBufFree(&calRow);
|
||||
DBufFree(&pre_buf);
|
||||
@@ -1201,9 +1201,9 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
||||
DBufPuts(&calRow, "* ");
|
||||
}
|
||||
if (tim->duration != NO_TIME) {
|
||||
sprintf(tmpBuf, "%d ", tim->duration);
|
||||
snprintf(tmpBuf, sizeof(tmpBuf), "%d ", tim->duration);
|
||||
} else {
|
||||
sprintf(tmpBuf, "* ");
|
||||
snprintf(tmpBuf, sizeof(tmpBuf), "* ");
|
||||
}
|
||||
if (DBufPuts(&calRow, tmpBuf) != OK) {
|
||||
DBufFree(&calRow);
|
||||
@@ -1211,9 +1211,9 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (tim->ttime != NO_TIME) {
|
||||
sprintf(tmpBuf, "%d ", tim->ttime);
|
||||
snprintf(tmpBuf, sizeof(tmpBuf), "%d ", tim->ttime);
|
||||
} else {
|
||||
sprintf(tmpBuf, "* ");
|
||||
snprintf(tmpBuf, sizeof(tmpBuf), "* ");
|
||||
}
|
||||
if (DBufPuts(&calRow, tmpBuf) != OK) {
|
||||
DBufFree(&calRow);
|
||||
@@ -1263,7 +1263,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
||||
/* Don't use msgprefix() on RUN-type reminders */
|
||||
if (t->typ != RUN_TYPE) {
|
||||
if (UserFuncExists("msgprefix") == 1) {
|
||||
sprintf(PrioExpr, "msgprefix(%d)", t->priority);
|
||||
snprintf(PrioExpr, sizeof(PrioExpr), "msgprefix(%d)", t->priority);
|
||||
s = PrioExpr;
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
if (!r) {
|
||||
@@ -1289,7 +1289,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int dse, int is_queue
|
||||
|
||||
if (t->typ != RUN_TYPE) {
|
||||
if (UserFuncExists("msgsuffix") == 1) {
|
||||
sprintf(PrioExpr, "msgsuffix(%d)", t->priority);
|
||||
snprintf(PrioExpr, sizeof(PrioExpr), "msgsuffix(%d)", t->priority);
|
||||
s = PrioExpr;
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
if (!r) {
|
||||
@@ -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,22 +1690,22 @@ 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++) {
|
||||
sprintf(buffer, "%s(%d)", t->warn, i);
|
||||
snprintf(buffer, sizeof(buffer), "%s(%d)", t->warn, i);
|
||||
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;
|
||||
|
||||
+164
-334
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -40,7 +40,7 @@ check_subst_args(UserFunc *f, int n)
|
||||
if (f->nargs == n) {
|
||||
return 1;
|
||||
}
|
||||
Wprint("Function `%s' defined at %s:%d should take %d argument%s, but actually takes %d",
|
||||
Wprint(tr("Function `%s' defined at %s:%d should take %d argument%s, but actually takes %d"),
|
||||
f->name, f->filename, f->lineno, n, (n == 1 ? "" : "s"), f->nargs);
|
||||
return 0;
|
||||
}
|
||||
@@ -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,39 @@ 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(tr("Warning: Unterminated %%(...) substitution sequence"));
|
||||
}
|
||||
err = OK;
|
||||
if (GetTranslatedStringTryingVariants(DBufValue(&orig), &translated)) {
|
||||
err = DBufPuts(dbuf, DBufValue(&translated));
|
||||
} else {
|
||||
err = DBufPuts(dbuf, DBufValue(&orig));
|
||||
}
|
||||
if (DebugFlag & DB_TRANSLATE) {
|
||||
TranslationTemplate(DBufValue(&orig));
|
||||
}
|
||||
DBufFree(&orig);
|
||||
DBufFree(&translated);
|
||||
if (err) return err;
|
||||
continue;
|
||||
}
|
||||
if (c == '*') {
|
||||
altmode = c;
|
||||
c = ParseChar(p, &err, 0);
|
||||
@@ -265,11 +278,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
}
|
||||
if (!c) {
|
||||
Wprint("Warning: Unterminated %%{...} substitution sequence");
|
||||
Wprint(tr("Warning: Unterminated %%{...} substitution sequence"));
|
||||
}
|
||||
func = FindUserFunc(s);
|
||||
if (!func) {
|
||||
Wprint("No substition function `%s' defined", s);
|
||||
Wprint(tr("No substition function `%s' defined"), s);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -312,52 +325,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 +375,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 +744,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;
|
||||
|
||||
+1
-1
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
+1
-1
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -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",
|
||||
@@ -226,20 +230,20 @@ EXTERN char *ErrMsg[]
|
||||
/* E_EXPIRED */ "Expired",
|
||||
/* E_CANTFORK */ "fork() failed - can't do queued reminders",
|
||||
/* E_CANTACCESS */ "Can't access file",
|
||||
/* M_BAD_SYS_DATE */ "Illegal system date: Year is less than %d\n",
|
||||
/* M_BAD_DB_FLAG */ "Unknown debug flag '%c'\n",
|
||||
/* M_BAD_OPTION */ "Unknown option '%c'\n",
|
||||
/* M_BAD_USER */ "Unknown user '%s'\n",
|
||||
/* M_NO_CHG_GID */ "Could not change gid to %d\n",
|
||||
/* M_NO_CHG_UID */ "Could not change uid to %d\n",
|
||||
/* M_NOMEM_ENV */ "Out of memory for environment\n",
|
||||
/* M_BAD_SYS_DATE */ "Illegal system date: Year is less than %d",
|
||||
/* M_BAD_DB_FLAG */ "Unknown debug flag '%c'",
|
||||
/* M_BAD_OPTION */ "Unknown option '%c'",
|
||||
/* M_BAD_USER */ "Unknown user '%s'",
|
||||
/* M_NO_CHG_GID */ "Could not change gid to %d",
|
||||
/* M_NO_CHG_UID */ "Could not change uid to %d",
|
||||
/* M_NOMEM_ENV */ "Out of memory for environment",
|
||||
/* 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_I_OPTION */ "Remind: '-i' option: %s\n",
|
||||
/* M_CANTSET_ACCESS */ "",
|
||||
/* M_I_OPTION */ "Remind: '-i' option: %s",
|
||||
/* E_NOREMINDERS */ "No reminders.",
|
||||
/* M_QUEUED */ "%d reminder(s) queued for later today.\n",
|
||||
/* M_QUEUED */ "%d reminder(s) queued for later today.",
|
||||
/* E_EXPECTING_NUMBER */ "Expecting number",
|
||||
/* M_BAD_WARN_FUNC */ "Undefined WARN function",
|
||||
/* E_CANT_CONVERT_TZ */ "Can't convert between time zones",
|
||||
@@ -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
|
||||
;
|
||||
|
||||
+102
-54
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -199,6 +199,46 @@ static UserFunc *CurrentUserFunc = NULL;
|
||||
/* How many expr_node objects to allocate at a time */
|
||||
#define ALLOC_CHUNK 64
|
||||
|
||||
static char const *
|
||||
find_end_of_expr(char const *s)
|
||||
{
|
||||
char const *e = s;
|
||||
int in_quoted_string = 0;
|
||||
int escaped = 0;
|
||||
|
||||
while(*e) {
|
||||
if (in_quoted_string) {
|
||||
if (escaped) {
|
||||
escaped = 0;
|
||||
e++;
|
||||
continue;
|
||||
}
|
||||
if (*e == '\\') {
|
||||
escaped = 1;
|
||||
e++;
|
||||
continue;
|
||||
}
|
||||
if (*e == '"') {
|
||||
in_quoted_string = 0;
|
||||
e++;
|
||||
continue;
|
||||
}
|
||||
e++;
|
||||
continue;
|
||||
}
|
||||
if (*e == '"') {
|
||||
in_quoted_string = 1;
|
||||
e++;
|
||||
continue;
|
||||
}
|
||||
if (*e == ']') {
|
||||
break;
|
||||
}
|
||||
e++;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* alloc_expr_node - allocate an expr_node object */
|
||||
@@ -282,7 +322,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 +361,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 +393,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 +466,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 +546,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 +586,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 +612,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 +621,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 +661,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 +683,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 +734,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 +890,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 +1581,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' (%s `%c%c'?)", GetErr(E_PARSE_ERR), c, tr("did you mean"), c, c);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
return OK;
|
||||
@@ -1633,10 +1673,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 +1871,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 +1899,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 +1921,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 +1945,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 +1984,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 +2003,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 +2027,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 +2035,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 +2059,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 +2077,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 +2157,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 +2166,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;
|
||||
}
|
||||
@@ -2137,6 +2177,7 @@ static expr_node *parse_atom(char const **e, int *r, Var *locals, int level)
|
||||
}
|
||||
|
||||
/* It's a constant or a variable reference */
|
||||
char const *olds = *e;
|
||||
*r = GET_TOKEN();
|
||||
if (*r != OK) return NULL;
|
||||
node = alloc_expr_node(r);
|
||||
@@ -2145,6 +2186,8 @@ static expr_node *parse_atom(char const **e, int *r, Var *locals, int level)
|
||||
}
|
||||
*r = make_atom(node, locals);
|
||||
if (*r != OK) {
|
||||
/* Preserve location for error position when we print ^-- here */
|
||||
*e = olds;
|
||||
return free_expr_tree(node);
|
||||
}
|
||||
return node;
|
||||
@@ -2498,6 +2541,7 @@ expr_node *parse_expression(char const **e, int *r, Var *locals)
|
||||
{
|
||||
char const *orig = *e;
|
||||
char const *o2 = *e;
|
||||
char const *end_of_expr;
|
||||
if (ExpressionEvaluationDisabled) {
|
||||
*r = E_EXPR_DISABLED;
|
||||
return NULL;
|
||||
@@ -2512,7 +2556,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);
|
||||
@@ -2529,25 +2573,29 @@ expr_node *parse_expression(char const **e, int *r, Var *locals)
|
||||
*r == E_2FEW_ARGS ||
|
||||
*r == E_PARSE_ERR ||
|
||||
*r == E_EOLN ||
|
||||
*r == E_BAD_NUMBER ||
|
||||
*r == E_BAD_DATE ||
|
||||
*r == E_BAD_TIME ||
|
||||
*r == E_ILLEGAL_CHAR) {
|
||||
orig = o2;
|
||||
while (*orig) {
|
||||
end_of_expr = find_end_of_expr(orig);
|
||||
while (**e && isempty(**e)) {
|
||||
(*e)++;
|
||||
}
|
||||
while (*orig && ((orig < end_of_expr) || (orig <= *e))) {
|
||||
if (*orig == '\n') {
|
||||
fprintf(ErrFp, " ");
|
||||
orig++;
|
||||
} else if (*orig == ']' && ! *(orig+1)) {
|
||||
break;
|
||||
} else {
|
||||
fprintf(ErrFp, "%c", *orig++);
|
||||
fprintf(ErrFp, "%c", *orig);
|
||||
}
|
||||
orig++;
|
||||
}
|
||||
fprintf(ErrFp, "\n");
|
||||
orig = o2;
|
||||
while ((orig < *e) && *orig) {
|
||||
while (*orig && (orig < *e || isspace(*orig))) {
|
||||
orig++;
|
||||
fprintf(ErrFp, " ");
|
||||
}
|
||||
fprintf(ErrFp, "^-- here\n");
|
||||
fprintf(ErrFp, "^-- %s\n", tr("here"));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -2966,12 +3014,12 @@ int DoCoerce(char type, Value *v)
|
||||
}
|
||||
case STR_TYPE:
|
||||
switch(v->type) {
|
||||
case INT_TYPE: sprintf(coerce_buf, "%d", v->v.val); break;
|
||||
case TIME_TYPE: sprintf(coerce_buf, "%02d%c%02d", v->v.val / 60,
|
||||
case INT_TYPE: snprintf(coerce_buf, sizeof(coerce_buf), "%d", v->v.val); break;
|
||||
case TIME_TYPE: snprintf(coerce_buf, sizeof(coerce_buf), "%02d%c%02d", v->v.val / 60,
|
||||
TimeSep, v->v.val % 60);
|
||||
break;
|
||||
case DATE_TYPE: FromDSE(v->v.val, &y, &m, &d);
|
||||
sprintf(coerce_buf, "%04d%c%02d%c%02d",
|
||||
snprintf(coerce_buf, sizeof(coerce_buf), "%04d%c%02d%c%02d",
|
||||
y, DateSep, m+1, DateSep, d);
|
||||
break;
|
||||
case DATETIME_TYPE:
|
||||
@@ -2980,7 +3028,7 @@ int DoCoerce(char type, Value *v)
|
||||
k = v->v.val % MINUTES_PER_DAY;
|
||||
h = k / 60;
|
||||
i = k % 60;
|
||||
sprintf(coerce_buf, "%04d%c%02d%c%02d%c%02d%c%02d",
|
||||
snprintf(coerce_buf, sizeof(coerce_buf), "%04d%c%02d%c%02d%c%02d%c%02d",
|
||||
y, DateSep, m+1, DateSep, d, DateTimeSep, h, TimeSep, i);
|
||||
break;
|
||||
default: return E_CANT_COERCE;
|
||||
@@ -3088,10 +3136,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" */
|
||||
|
||||
+50
-31
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -145,7 +145,8 @@ static void OpenPurgeFile(char const *fname, char const *mode)
|
||||
if (DBufPuts(&fname_buf, ".purged") != OK) return;
|
||||
PurgeFP = fopen(DBufValue(&fname_buf), mode);
|
||||
if (!PurgeFP) {
|
||||
fprintf(ErrFp, "Cannot open `%s' for writing: %s\n", DBufValue(&fname_buf), strerror(errno));
|
||||
fprintf(ErrFp, tr("Cannot open `%s' for writing: %s"), DBufValue(&fname_buf), strerror(errno));
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
set_cloexec(PurgeFP);
|
||||
DBufFree(&fname_buf);
|
||||
@@ -325,7 +326,8 @@ int OpenFile(char const *fname)
|
||||
while (h) {
|
||||
if (!strcmp(fname, h->filename)) {
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Reading `%s': Found in cache\n", fname);
|
||||
fprintf(ErrFp, tr("Reading `%s': Found in cache"), fname);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
CLine = h->cache;
|
||||
STRSET(FileName, fname);
|
||||
@@ -348,13 +350,14 @@ int OpenFile(char const *fname)
|
||||
PurgeFP = stdout;
|
||||
}
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Reading `-': Reading stdin\n");
|
||||
fprintf(ErrFp, "%s\n", tr("Reading `-': Reading stdin"));
|
||||
}
|
||||
} else {
|
||||
fp = fopen(fname, "r");
|
||||
set_cloexec(fp);
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Reading `%s': Opening file on disk\n", fname);
|
||||
fprintf(ErrFp, tr("Reading `%s': Opening file on disk"), fname);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
if (PurgeMode) {
|
||||
OpenPurgeFile(fname, "w");
|
||||
@@ -401,7 +404,8 @@ static int CacheFile(char const *fname, int use_pclose)
|
||||
char const *s;
|
||||
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Caching file `%s' in memory\n", fname);
|
||||
fprintf(ErrFp, tr("Caching file `%s' in memory"), fname);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
cl = NULL;
|
||||
/* Create a file header */
|
||||
@@ -519,7 +523,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,9 +541,10 @@ 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]);
|
||||
fprintf(ErrFp, tr("%s(%d): IF without ENDIF"), FileName, IfLinenos[j]);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
}
|
||||
if (!IStackPtr) return E_EOF;
|
||||
@@ -608,16 +613,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 +664,6 @@ int DoInclude(ParsePtr p, enum TokTypes tok)
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
|
||||
bailout:
|
||||
DBufFree(&buf);
|
||||
DBufFree(&path);
|
||||
@@ -713,8 +724,6 @@ int DoIncludeCmd(ParsePtr p)
|
||||
return r;
|
||||
}
|
||||
DBufFree(&buf);
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -756,8 +765,9 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
while(dc) {
|
||||
if (!strcmp(dc->dirname, dir)) {
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Found cached directory listing for `%s'\n",
|
||||
fprintf(ErrFp, tr("Found cached directory listing for `%s'"),
|
||||
dir);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
free(dir);
|
||||
i->chain = dc->chain;
|
||||
@@ -767,7 +777,8 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
}
|
||||
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Scanning directory `%s' for *.rem files\n", dir);
|
||||
fprintf(ErrFp, tr("Scanning directory `%s' for *.rem files"), dir);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
|
||||
if (ShouldCache) {
|
||||
@@ -781,7 +792,8 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
}
|
||||
if (dc) {
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Caching directory `%s' listing\n", dir);
|
||||
fprintf(ErrFp, tr("Caching directory `%s' listing"), dir);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
|
||||
dc->chain = NULL;
|
||||
@@ -905,13 +917,16 @@ static int IncludeCmd(char const *cmd)
|
||||
FCLOSE(fp);
|
||||
}
|
||||
IStackPtr++;
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
|
||||
/* If the file is cached, use it */
|
||||
h = CachedFiles;
|
||||
while(h) {
|
||||
if (!strcmp(fname, h->filename)) {
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Reading command `%s': Found in cache\n", fname);
|
||||
fprintf(ErrFp, tr("Reading command `%s': Found in cache"), fname);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
CLine = h->cache;
|
||||
STRSET(FileName, fname);
|
||||
@@ -928,8 +943,9 @@ static int IncludeCmd(char const *cmd)
|
||||
}
|
||||
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Executing `%s' for INCLUDECMD and caching as `%s'\n",
|
||||
fprintf(ErrFp, tr("Executing `%s' for INCLUDECMD and caching as `%s'"),
|
||||
cmd, fname);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
|
||||
/* Not found in cache */
|
||||
@@ -941,6 +957,7 @@ static int IncludeCmd(char const *cmd)
|
||||
fp2 = popen(cmd, "r");
|
||||
}
|
||||
if (!fp2) {
|
||||
PopFile();
|
||||
DBufFree(&buf);
|
||||
return E_CANT_OPEN;
|
||||
}
|
||||
@@ -1014,6 +1031,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. */
|
||||
@@ -1028,7 +1047,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;
|
||||
@@ -1042,14 +1061,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;
|
||||
@@ -1063,7 +1082,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;
|
||||
@@ -1192,7 +1211,7 @@ static int CheckSafetyAux(struct stat *statbuf)
|
||||
if (!geteuid()) {
|
||||
/* Reject files not owned by root or group/world writable */
|
||||
if (statbuf->st_uid != 0) {
|
||||
fprintf(ErrFp, "SECURITY: Won't read non-root-owned file or directory when running as root!\n");
|
||||
fprintf(ErrFp, "%s\n", tr("SECURITY: Won't read non-root-owned file or directory when running as root!"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1202,7 +1221,7 @@ static int CheckSafetyAux(struct stat *statbuf)
|
||||
return 1;
|
||||
}
|
||||
if ((statbuf->st_mode & S_IWOTH)) {
|
||||
fprintf(ErrFp, "SECURITY: Won't read world-writable file or directory!\n");
|
||||
fprintf(ErrFp, "%s\n", tr("SECURITY: Won't read world-writable file or directory!"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+82
-40
@@ -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 *);
|
||||
@@ -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,31 @@ 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);
|
||||
if (DebugFlag & DB_TRANSLATE) {
|
||||
TranslationTemplate(ARGSTR(0));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FStrlen - string length */
|
||||
@@ -1050,7 +1076,7 @@ static int FOrd(func_info *info)
|
||||
if (u == 1 && t != 11) s = "st";
|
||||
if (u == 2 && t != 12) s = "nd";
|
||||
if (u == 3 && t != 13) s = "rd";
|
||||
sprintf(buf, "%d%s", v, s);
|
||||
snprintf(buf, sizeof(buf), "%d%s", v, s);
|
||||
return RetStrVal(buf, info);
|
||||
}
|
||||
|
||||
@@ -1281,10 +1307,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 +1828,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,
|
||||
snprintf(buf, sizeof(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);
|
||||
snprintf(buf, sizeof(buf), "%d %s %d", d, MonthName[m], y);
|
||||
}
|
||||
return RetStrVal(buf, info);
|
||||
}
|
||||
@@ -1995,7 +2021,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 +2179,7 @@ static int FTypeof(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FLanguage(func_info *info)
|
||||
{
|
||||
return RetStrVal(L_LANGNAME, info);
|
||||
return RetStrVal("English", info);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -2734,7 +2760,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;
|
||||
@@ -2986,6 +3012,7 @@ static int FPsshade(func_info *info)
|
||||
char psbuff[256];
|
||||
char *s = psbuff;
|
||||
int i;
|
||||
size_t len = sizeof(psbuff);
|
||||
|
||||
/* 1 or 3 args */
|
||||
if (Nargs != 1 && Nargs != 3) return E_2MANY_ARGS;
|
||||
@@ -2998,19 +3025,22 @@ static int FPsshade(func_info *info)
|
||||
|
||||
if (!psshade_warned) {
|
||||
psshade_warned = 1;
|
||||
Wprint("psshade() is deprecated; use SPECIAL SHADE instead.");
|
||||
Wprint(tr("psshade() is deprecated; use SPECIAL SHADE instead."));
|
||||
}
|
||||
|
||||
sprintf(s, "/_A LineWidth 2 div def ");
|
||||
snprintf(s, len, "/_A LineWidth 2 div def ");
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
sprintf(s, "_A _A moveto ");
|
||||
snprintf(s, len, "_A _A moveto ");
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
sprintf(s, "BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto ");
|
||||
snprintf(s, len, "BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto ");
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
if (Nargs == 1) {
|
||||
sprintf(s, "_A BoxHeight _A sub lineto closepath %d 100 div setgray fill 0.0 setgray", ARGV(0));
|
||||
snprintf(s, len, "_A BoxHeight _A sub lineto closepath %d 100 div setgray fill 0.0 setgray", ARGV(0));
|
||||
} else {
|
||||
sprintf(s, "_A BoxHeight _A sub lineto closepath %d 100 div %d 100 div %d 100 div setrgbcolor fill 0.0 setgray", ARGV(0), ARGV(1), ARGV(2));
|
||||
snprintf(s, len, "_A BoxHeight _A sub lineto closepath %d 100 div %d 100 div %d 100 div setrgbcolor fill 0.0 setgray", ARGV(0), ARGV(1), ARGV(2));
|
||||
}
|
||||
return RetStrVal(psbuff, info);
|
||||
}
|
||||
@@ -3033,6 +3063,7 @@ static int FPsmoon(func_info *info)
|
||||
char const *extra = NULL;
|
||||
int size = -1;
|
||||
int fontsize = -1;
|
||||
size_t len = sizeof(psbuff);
|
||||
|
||||
ASSERT_TYPE(0, INT_TYPE);
|
||||
if (ARGV(0) < 0) return E_2LOW;
|
||||
@@ -3053,63 +3084,74 @@ static int FPsmoon(func_info *info)
|
||||
}
|
||||
if (!psmoon_warned) {
|
||||
psmoon_warned = 1;
|
||||
Wprint("psmoon() is deprecated; use SPECIAL MOON instead.");
|
||||
Wprint(tr("psmoon() is deprecated; use SPECIAL MOON instead."));
|
||||
}
|
||||
if (size > 0) {
|
||||
sprintf(sizebuf, "%d", size);
|
||||
snprintf(sizebuf, sizeof(sizebuf), "%d", size);
|
||||
} else {
|
||||
strcpy(sizebuf, "DaySize 2 div");
|
||||
}
|
||||
|
||||
if (fontsize > 0) {
|
||||
sprintf(fontsizebuf, "%d", fontsize);
|
||||
snprintf(fontsizebuf, sizeof(fontsizebuf), "%d", fontsize);
|
||||
} else {
|
||||
strcpy(fontsizebuf, "EntrySize");
|
||||
}
|
||||
|
||||
sprintf(s, "gsave 0 setgray newpath Border %s add BoxHeight Border sub %s sub",
|
||||
snprintf(s, len, "gsave 0 setgray newpath Border %s add BoxHeight Border sub %s sub",
|
||||
sizebuf, sizebuf);
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
sprintf(s, " %s 0 360 arc closepath", sizebuf);
|
||||
snprintf(s, len, " %s 0 360 arc closepath", sizebuf);
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
switch(ARGV(0)) {
|
||||
case 0:
|
||||
sprintf(s, " fill");
|
||||
snprintf(s, len, " fill");
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
sprintf(s, " stroke");
|
||||
snprintf(s, len, " stroke");
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
sprintf(s, " stroke");
|
||||
snprintf(s, len, " stroke");
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
sprintf(s, " newpath Border %s add BoxHeight Border sub %s sub",
|
||||
snprintf(s, len, " newpath Border %s add BoxHeight Border sub %s sub",
|
||||
sizebuf, sizebuf);
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
sprintf(s, " %s 90 270 arc closepath fill", sizebuf);
|
||||
snprintf(s, len, " %s 90 270 arc closepath fill", sizebuf);
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(s, " stroke");
|
||||
snprintf(s, len, " stroke");
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
sprintf(s, " newpath Border %s add BoxHeight Border sub %s sub",
|
||||
snprintf(s, len, " newpath Border %s add BoxHeight Border sub %s sub",
|
||||
sizebuf, sizebuf);
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
sprintf(s, " %s 270 90 arc closepath fill", sizebuf);
|
||||
snprintf(s, len, " %s 270 90 arc closepath fill", sizebuf);
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
break;
|
||||
}
|
||||
if (extra) {
|
||||
sprintf(s, " Border %s add %s add Border add BoxHeight border sub %s sub %s sub moveto /EntryFont findfont %s scalefont setfont (%s) show",
|
||||
snprintf(s, len, " Border %s add %s add Border add BoxHeight border sub %s sub %s sub moveto /EntryFont findfont %s scalefont setfont (%s) show",
|
||||
sizebuf, sizebuf, sizebuf, sizebuf, fontsizebuf, extra);
|
||||
len -= strlen(s);
|
||||
s += strlen(s);
|
||||
}
|
||||
|
||||
sprintf(s, " grestore");
|
||||
snprintf(s, len, " grestore");
|
||||
return RetStrVal(psbuff, info);
|
||||
}
|
||||
|
||||
@@ -3240,20 +3282,20 @@ static int FDatepart(func_info *info)
|
||||
* used for the timezone stuff! */
|
||||
static int setenv(char const *varname, char const *val, int overwrite)
|
||||
{
|
||||
static char tzbuf[256];
|
||||
static char tzbuf[128];
|
||||
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();
|
||||
}
|
||||
|
||||
if (strlen(val) > 250) {
|
||||
return -1;
|
||||
}
|
||||
sprintf(tzbuf, "%s=%s", varname, val);
|
||||
snprintf(tzbuf, sizeof(tzbuf), "%s=%s", varname, val);
|
||||
return(putenv(tzbuf));
|
||||
}
|
||||
#endif
|
||||
@@ -3262,12 +3304,12 @@ static int setenv(char const *varname, char const *val, int overwrite)
|
||||
* used for the timezone stuff! */
|
||||
static void unsetenv(char const *varname)
|
||||
{
|
||||
static char tzbuf[8];
|
||||
static char tzbuf[128];
|
||||
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);
|
||||
snprintf(tzbuf, sizeof(tzbuf), "%s", varname);
|
||||
putenv(tzbuf);
|
||||
}
|
||||
#endif
|
||||
@@ -3599,7 +3641,7 @@ FEvalTrig(func_info *info)
|
||||
} else {
|
||||
/* Hokey... */
|
||||
if (trig.scanfrom != DSEToday) {
|
||||
Wprint("Warning: SCANFROM is ignored in two-argument form of evaltrig()");
|
||||
Wprint(tr("Warning: SCANFROM is ignored in two-argument form of evaltrig()"));
|
||||
}
|
||||
dse = ComputeTrigger(scanfrom, &trig, &tim, &r, 0);
|
||||
}
|
||||
@@ -3654,7 +3696,7 @@ FMultiTrig(func_info *info)
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
if (tim.ttime != NO_TIME) {
|
||||
Eprint("Cannot use AT clause in multitrig() function");
|
||||
Eprint(tr("Cannot use AT clause in multitrig() function"));
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
|
||||
|
||||
+1
-2
@@ -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"
|
||||
|
||||
+11
-119
@@ -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);
|
||||
@@ -176,65 +176,23 @@ EXTERN INIT( unsigned int FuncRecursionLevel, 0);
|
||||
/* Suppress warnings about implicit REM and MSG */
|
||||
EXTERN INIT( int SuppressImplicitRemWarnings, 0);
|
||||
|
||||
/* Test mode - used by the acceptance tests */
|
||||
EXTERN INIT( int TestMode, 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 +214,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
|
||||
;
|
||||
|
||||
@@ -351,3 +240,6 @@ EXTERN int SuppressLRM
|
||||
= 0
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Translatable messages */
|
||||
extern char const *translatables[];
|
||||
|
||||
+428
@@ -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;
|
||||
}
|
||||
@@ -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)))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
+4
-4
@@ -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 */
|
||||
@@ -324,7 +324,7 @@ int GetValidHebDate(int yin, int min, int din, int adarbehave,
|
||||
case ADAR2ADARB: *mout = min = ADARB; break;
|
||||
|
||||
default:
|
||||
Eprint("GetValidHebDate: Bad adarbehave value %d", adarbehave);
|
||||
Eprint(tr("GetValidHebDate: Bad adarbehave value %d"), adarbehave);
|
||||
return E_SWERR;
|
||||
}
|
||||
}
|
||||
@@ -464,7 +464,7 @@ int ComputeJahr(int y, int m, int d, int *ans)
|
||||
|
||||
/* Check for Adar A */
|
||||
if (m == ADARA && monlen[m] == 0) {
|
||||
Eprint("No Adar A in %d", y);
|
||||
Eprint(tr("No Adar A in %d"), y);
|
||||
return E_BAD_HEBDATE;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+110
-36
@@ -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,8 @@ 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);
|
||||
fprintf(ErrFp, "\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
DSEToday = RealToday;
|
||||
@@ -229,7 +238,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 +502,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 +531,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 +546,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 +569,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 +594,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,14 +635,17 @@ 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;
|
||||
case 'v': case 'V': DebugFlag |= DB_DUMP_VARS; break;
|
||||
case 'l': case 'L': DebugFlag |= DB_PRTLINE; break;
|
||||
case 'f': case 'F': DebugFlag |= DB_TRACE_FILES; break;
|
||||
case 'q': case 'Q': DebugFlag |= DB_TRANSLATE; break;
|
||||
default:
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_DB_FLAG], *(arg-1));
|
||||
fprintf(ErrFp, GetErr(M_BAD_DB_FLAG), *(arg-1));
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -652,7 +680,8 @@ 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));
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -720,7 +749,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();
|
||||
@@ -766,10 +795,11 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
}
|
||||
|
||||
/* Figure out the offset from UTC */
|
||||
if (CalculateUTC)
|
||||
/* Figure out the offset from UTC */
|
||||
if (CalculateUTC) {
|
||||
(void) CalcMinsFromUTC(DSEToday, MinutesPastMidnight(0),
|
||||
&MinsFromUTC, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -782,7 +812,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 +874,8 @@ 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);
|
||||
fprintf(ErrFp, "\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -852,24 +883,28 @@ 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);
|
||||
fprintf(ErrFp, "\n");
|
||||
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);
|
||||
fprintf(ErrFp, "\n");
|
||||
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);
|
||||
fprintf(ErrFp, "\n");
|
||||
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));
|
||||
fprintf(ErrFp, "\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(home, "HOME=%s", pwent->pw_dir);
|
||||
@@ -877,7 +912,8 @@ 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));
|
||||
fprintf(ErrFp, "\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(shell, "SHELL=%s", pwent->pw_shell);
|
||||
@@ -886,14 +922,16 @@ 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));
|
||||
fprintf(ErrFp, "\n");
|
||||
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));
|
||||
fprintf(ErrFp, "\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(logname, "LOGNAME=%s", pwent->pw_name);
|
||||
@@ -911,7 +949,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 +976,8 @@ 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));
|
||||
fprintf(ErrFp, "\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -951,13 +990,15 @@ 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));
|
||||
fprintf(ErrFp, "\n");
|
||||
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));
|
||||
fprintf(ErrFp, "\n");
|
||||
return;
|
||||
}
|
||||
val.type = INT_TYPE;
|
||||
@@ -967,41 +1008,52 @@ 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));
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*varname) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_VAR]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_VAR));
|
||||
fprintf(ErrFp, "\n");
|
||||
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));
|
||||
fprintf(ErrFp, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
r=EvalExpr(&expr, &val, NULL);
|
||||
if (r) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
fprintf(ErrFp, "\n");
|
||||
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));
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
r=SetVar(varname, &val);
|
||||
if (r) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
fprintf(ErrFp, "\n");
|
||||
return;
|
||||
}
|
||||
r=PreserveVar(varname);
|
||||
if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
if (r) {
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1010,14 +1062,15 @@ 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);
|
||||
fprintf(ErrFp, "\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
TrustedUsers[NumTrustedUsers] = pwent->pw_uid;
|
||||
@@ -1069,6 +1122,17 @@ static void
|
||||
ProcessLongOption(char const *arg)
|
||||
{
|
||||
int t;
|
||||
if (!strcmp(arg, "test")) {
|
||||
fprintf(stderr, "Enabling test mode: This is meant for the acceptance test.\nDo not use --test in production.\nIn test mode, the system time is fixed at 2025-01-06@19:00\n");
|
||||
TestMode = 1;
|
||||
|
||||
/* Update RealToday because of TestMode */
|
||||
RealToday = SystemDate(&CurYear, &CurMon, &CurDay);
|
||||
DSEToday = RealToday;
|
||||
FromDSE(DSEToday, &CurYear, &CurMon, &CurDay);
|
||||
|
||||
return;
|
||||
}
|
||||
if (!strcmp(arg, "version")) {
|
||||
printf("%s\n", VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
@@ -1077,6 +1141,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();
|
||||
|
||||
+20
-20
@@ -299,7 +299,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
if (flags & flag_string)
|
||||
{
|
||||
if (!b)
|
||||
{ sprintf (error, "Unexpected EOF in string (at %u:%u)", line_and_col);
|
||||
{ snprintf (error, sizeof(error), "Unexpected EOF in string (at %u:%u)", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
|
||||
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
|
||||
{
|
||||
sprintf (error, "Invalid character value `%c` (at %u:%u)", b, line_and_col);
|
||||
snprintf (error, sizeof(error), "Invalid character value `%c` (at %u:%u)", b, line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
|
||||
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
|
||||
{
|
||||
sprintf (error, "Invalid character value `%c` (at %u:%u)", b, line_and_col);
|
||||
snprintf (error, sizeof(error), "Invalid character value `%c` (at %u:%u)", b, line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -472,7 +472,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
if (flags & flag_block_comment)
|
||||
{
|
||||
if (!b)
|
||||
{ sprintf (error, "%u:%u: Unexpected EOF in block comment", line_and_col);
|
||||
{ snprintf (error, sizeof(error), "%u:%u: Unexpected EOF in block comment", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -488,12 +488,12 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
else if (b == '/')
|
||||
{
|
||||
if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
|
||||
{ sprintf (error, "%u:%u: Comment not allowed here", line_and_col);
|
||||
{ snprintf (error, sizeof(error), "%u:%u: Comment not allowed here", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
if (++ state.ptr == end)
|
||||
{ sprintf (error, "%u:%u: EOF unexpected", line_and_col);
|
||||
{ snprintf (error, sizeof(error), "%u:%u: EOF unexpected", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -508,7 +508,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
continue;
|
||||
|
||||
default:
|
||||
sprintf (error, "%u:%u: Unexpected `%c` in comment opening sequence", line_and_col, b);
|
||||
snprintf (error, sizeof(error), "%u:%u: Unexpected `%c` in comment opening sequence", line_and_col, b);
|
||||
goto e_failed;
|
||||
};
|
||||
}
|
||||
@@ -526,7 +526,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
|
||||
default:
|
||||
|
||||
sprintf (error, "%u:%u: Trailing garbage: `%c`",
|
||||
snprintf (error, sizeof(error), "%u:%u: Trailing garbage: `%c`",
|
||||
state.cur_line, state.cur_col, b);
|
||||
|
||||
goto e_failed;
|
||||
@@ -545,7 +545,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
if (top && top->type == json_array)
|
||||
flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
|
||||
else
|
||||
{ sprintf (error, "%u:%u: Unexpected ]", line_and_col);
|
||||
{ snprintf (error, sizeof(error), "%u:%u: Unexpected ]", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -561,7 +561,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (error, "%u:%u: Expected , before %c",
|
||||
snprintf (error, sizeof(error), "%u:%u: Expected , before %c",
|
||||
state.cur_line, state.cur_col, b);
|
||||
|
||||
goto e_failed;
|
||||
@@ -576,7 +576,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (error, "%u:%u: Expected : before %c",
|
||||
snprintf (error, sizeof(error), "%u:%u: Expected : before %c",
|
||||
state.cur_line, state.cur_col, b);
|
||||
|
||||
goto e_failed;
|
||||
@@ -702,7 +702,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{ sprintf (error, "%u:%u: Unexpected %c when seeking value", line_and_col, b);
|
||||
{ snprintf (error, sizeof(error), "%u:%u: Unexpected %c when seeking value", line_and_col, b);
|
||||
goto e_failed;
|
||||
}
|
||||
};
|
||||
@@ -722,7 +722,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
case '"':
|
||||
|
||||
if (flags & flag_need_comma)
|
||||
{ sprintf (error, "%u:%u: Expected , before \"", line_and_col);
|
||||
{ snprintf (error, sizeof(error), "%u:%u: Expected , before \"", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -747,7 +747,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
sprintf (error, "%u:%u: Unexpected `%c` in object", line_and_col, b);
|
||||
snprintf (error, sizeof(error), "%u:%u: Unexpected `%c` in object", line_and_col, b);
|
||||
goto e_failed;
|
||||
};
|
||||
|
||||
@@ -765,7 +765,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
if (! (flags & flag_num_e))
|
||||
{
|
||||
if (flags & flag_num_zero)
|
||||
{ sprintf (error, "%u:%u: Unexpected `0` before `%c`", line_and_col, b);
|
||||
{ snprintf (error, sizeof(error), "%u:%u: Unexpected `0` before `%c`", line_and_col, b);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -814,7 +814,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
else if (b == '.' && top->type == json_integer)
|
||||
{
|
||||
if (!num_digits)
|
||||
{ sprintf (error, "%u:%u: Expected digit before `.`", line_and_col);
|
||||
{ snprintf (error, sizeof(error), "%u:%u: Expected digit before `.`", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -831,7 +831,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
if (top->type == json_double)
|
||||
{
|
||||
if (!num_digits)
|
||||
{ sprintf (error, "%u:%u: Expected digit after `.`", line_and_col);
|
||||
{ snprintf (error, sizeof(error), "%u:%u: Expected digit after `.`", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -857,7 +857,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
else
|
||||
{
|
||||
if (!num_digits)
|
||||
{ sprintf (error, "%u:%u: Expected digit after `e`", line_and_col);
|
||||
{ snprintf (error, sizeof(error), "%u:%u: Expected digit after `e`", line_and_col);
|
||||
goto e_failed;
|
||||
}
|
||||
|
||||
@@ -942,7 +942,7 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
|
||||
e_unknown_value:
|
||||
|
||||
sprintf (error, "%u:%u: Unknown value", line_and_col);
|
||||
snprintf (error, sizeof(error), "%u:%u: Unknown value", line_and_col);
|
||||
goto e_failed;
|
||||
|
||||
e_alloc_failure:
|
||||
@@ -952,7 +952,7 @@ e_alloc_failure:
|
||||
|
||||
e_overflow:
|
||||
|
||||
sprintf (error, "%u:%u: Too long (caught overflow)", line_and_col);
|
||||
snprintf (error, sizeof(error), "%u:%u: Too long (caught overflow)", line_and_col);
|
||||
goto e_failed;
|
||||
|
||||
e_failed:
|
||||
|
||||
-78
@@ -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"
|
||||
|
||||
+175
-32
@@ -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,12 @@ 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);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +199,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 +261,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 +276,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 +317,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 +358,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 {
|
||||
@@ -367,7 +374,7 @@ static void DoReminders(void)
|
||||
|
||||
default:
|
||||
if (!SuppressImplicitRemWarnings) {
|
||||
Wprint("Unrecognized command; interpreting as REM");
|
||||
Wprint(tr("Unrecognized command; interpreting as REM"));
|
||||
WarnedAboutImplicit = 1;
|
||||
}
|
||||
DestroyParser(&p);
|
||||
@@ -378,14 +385,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 +603,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 */
|
||||
@@ -909,6 +1010,11 @@ int SystemTime(int realtime)
|
||||
|
||||
if (!realtime && (SysTime != -1)) return SysTime;
|
||||
|
||||
if (TestMode) {
|
||||
/* Pretend it's 7:00PM in test mode */
|
||||
return 19 * 3600;
|
||||
}
|
||||
|
||||
now = time(NULL);
|
||||
t = localtime(&now);
|
||||
return t->tm_hour * 3600L + t->tm_min * 60L +
|
||||
@@ -942,6 +1048,14 @@ int SystemDate(int *y, int *m, int *d)
|
||||
time_t now;
|
||||
struct tm *t;
|
||||
|
||||
/* In test mode, always return 6 January 2025 */
|
||||
if (TestMode) {
|
||||
*y = 2025;
|
||||
*m = 0;
|
||||
*d = 6;
|
||||
return 12789; /* 2025-01-06 */
|
||||
}
|
||||
|
||||
now = time(NULL);
|
||||
t = localtime(&now);
|
||||
|
||||
@@ -970,7 +1084,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 +1169,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 +1233,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;
|
||||
}
|
||||
@@ -1167,12 +1281,24 @@ int DoDebug(ParsePtr p)
|
||||
else DebugFlag &= ~DB_ECHO_LINE;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
case 'Q':
|
||||
if (val) DebugFlag |= DB_TRANSLATE;
|
||||
else DebugFlag &= ~DB_TRANSLATE;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'S':
|
||||
if (val) DebugFlag |= DB_PARSE_EXPR;
|
||||
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;
|
||||
@@ -1202,6 +1328,9 @@ int DoDebug(ParsePtr p)
|
||||
if (val) DebugFlag |= DB_TRACE_FILES;
|
||||
else DebugFlag &= ~DB_TRACE_FILES;
|
||||
break;
|
||||
default:
|
||||
Wprint(GetErr(M_BAD_DB_FLAG), ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1900,8 +2029,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 +2038,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)
|
||||
@@ -1930,7 +2057,7 @@ static int GetOnceDateFromFile(void)
|
||||
/* Save today to file */
|
||||
fp = fopen(OnceFile, "w");
|
||||
if (!fp) {
|
||||
Wprint("Warning: Unable to save ONCE timestamp to %s: %s",
|
||||
Wprint(tr("Warning: Unable to save ONCE timestamp to %s: %s"),
|
||||
OnceFile, strerror(errno));
|
||||
return once_date;
|
||||
}
|
||||
@@ -1950,3 +2077,19 @@ int GetOnceDate(void)
|
||||
}
|
||||
return OnceDate;
|
||||
}
|
||||
|
||||
char const *GetErr(int r)
|
||||
{
|
||||
char const *msg;
|
||||
|
||||
if (r < 0 || r >= NumErrs) {
|
||||
r = E_SWERR;
|
||||
}
|
||||
|
||||
msg = GetTranslatedString(ErrMsg[r]);
|
||||
if (!msg) {
|
||||
return ErrMsg[r];
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
+12
-9
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -92,7 +92,7 @@ int DestroyOmitContexts(int print_unmatched)
|
||||
|
||||
while (c) {
|
||||
if (print_unmatched) {
|
||||
Wprint("Unmatched PUSH-OMIT-CONTEXT at %s(%d)",
|
||||
Wprint(tr("Unmatched PUSH-OMIT-CONTEXT at %s(%d)"),
|
||||
c->filename, c->lineno);
|
||||
}
|
||||
num++;
|
||||
@@ -185,6 +185,9 @@ int PopOmitContext(ParsePtr p)
|
||||
/* Remove the context from the stack */
|
||||
SavedOmitContexts = c->next;
|
||||
|
||||
if (c->filename && FileName && strcmp(c->filename, FileName)) {
|
||||
Wprint(tr("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);
|
||||
@@ -215,7 +218,7 @@ int IsOmitted(int dse, int localomit, char const *omitfunc, int *omit)
|
||||
Value v;
|
||||
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
sprintf(expr, "%s('%04d-%02d-%02d')",
|
||||
snprintf(expr, sizeof(expr), "%s('%04d-%02d-%02d')",
|
||||
omitfunc, y, m+1, d);
|
||||
s = expr;
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
@@ -392,11 +395,11 @@ int DoOmit(ParsePtr p)
|
||||
|
||||
default:
|
||||
if (tok.type == T_Until) {
|
||||
Eprint("OMIT: UNTIL not allowed; did you mean THROUGH?");
|
||||
Eprint(tr("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);
|
||||
@@ -462,7 +465,7 @@ int DoOmit(ParsePtr p)
|
||||
InsertIntoSortedArray(PartialOmitArray, NumPartialOmits, syndrome);
|
||||
NumPartialOmits++;
|
||||
if (NumPartialOmits == 366) {
|
||||
Wprint("You have OMITted everything! The space-time continuum is at risk.");
|
||||
Wprint(tr("You have OMITted everything! The space-time continuum is at risk."));
|
||||
}
|
||||
}
|
||||
if (mc == m[1] && dc == d[1]) {
|
||||
@@ -484,7 +487,7 @@ int DoOmit(ParsePtr p)
|
||||
start = DSE(y[0], m[0], d[0]);
|
||||
end = DSE(y[1], m[1], d[1]);
|
||||
if (end < start) {
|
||||
Eprint("Error: THROUGH date earlier than start date");
|
||||
Eprint(tr("Error: THROUGH date earlier than start date"));
|
||||
return E_BAD_DATE;
|
||||
}
|
||||
|
||||
@@ -544,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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
-6
@@ -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,24 @@ 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);
|
||||
void print_escaped_string_helper(FILE *fp, char const *s, int esc_for_remind);
|
||||
void GenerateSysvarTranslationTemplates(void);
|
||||
void TranslationTemplate(char const *msg);
|
||||
|
||||
+81
-8
@@ -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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -346,8 +346,9 @@ void HandleQueuedReminders(void)
|
||||
/* If we're a daemon, get the mod time of initial file */
|
||||
if (Daemon > 0) {
|
||||
if (stat(InitialFile, &StatBuf)) {
|
||||
fprintf(ErrFp, "Cannot stat %s - not running as daemon!\n",
|
||||
fprintf(ErrFp, tr("Cannot stat %s - not running as daemon!"),
|
||||
InitialFile);
|
||||
fprintf(ErrFp, "\n");
|
||||
Daemon = 0;
|
||||
} else FileModTime = StatBuf.st_mtime;
|
||||
}
|
||||
@@ -459,7 +460,11 @@ void HandleQueuedReminders(void)
|
||||
if (IsServerMode() && q->typ != RUN_TYPE) {
|
||||
if (DaemonJSON) {
|
||||
printf("{\"response\":\"reminder\",");
|
||||
snprintf(qid, sizeof(qid), "%lx", (unsigned long) q);
|
||||
if (TestMode) {
|
||||
snprintf(qid, sizeof(qid), "42424242");
|
||||
} else {
|
||||
snprintf(qid, sizeof(qid), "%lx", (unsigned long) q);
|
||||
}
|
||||
PrintJSONKeyPairString("qid", qid);
|
||||
PrintJSONKeyPairString("ttime", SimpleTimeNoSpace(q->tt.ttime));
|
||||
PrintJSONKeyPairString("now", SimpleTimeNoSpace(MinutesPastMidnight(1)));
|
||||
@@ -697,7 +702,7 @@ static int CalculateNextTimeUsingSched(QueuedRem *q)
|
||||
to be a security hole! */
|
||||
while(1) {
|
||||
char exprBuf[VAR_NAME_LEN+32];
|
||||
sprintf(exprBuf, "%s(%d)", q->sched, q->ntrig);
|
||||
snprintf(exprBuf, sizeof(exprBuf), "%s(%d)", q->sched, q->ntrig);
|
||||
s = exprBuf;
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
if (r) {
|
||||
@@ -759,7 +764,11 @@ json_queue(QueuedRem const *q)
|
||||
printf("{");
|
||||
WriteJSONTrigger(&(q->t), 1, DSEToday);
|
||||
WriteJSONTimeTrigger(&(q->tt));
|
||||
snprintf(idbuf, sizeof(idbuf), "%lx", (unsigned long) q);
|
||||
if (TestMode) {
|
||||
snprintf(idbuf, sizeof(idbuf), "42424242");
|
||||
} else {
|
||||
snprintf(idbuf, sizeof(idbuf), "%lx", (unsigned long) q);
|
||||
}
|
||||
PrintJSONKeyPairString("qid", idbuf);
|
||||
PrintJSONKeyPairInt("rundisabled", q->RunDisabled);
|
||||
PrintJSONKeyPairInt("ntrig", q->ntrig);
|
||||
@@ -815,6 +824,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 +882,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 +954,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");
|
||||
|
||||
+6
-5
@@ -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");
|
||||
@@ -1221,7 +1222,7 @@ int DoQueuedPs(void)
|
||||
if (moonsize < 0) {
|
||||
size = "DaySize 2 div";
|
||||
} else {
|
||||
sprintf(buffer, "%d", moonsize);
|
||||
snprintf(buffer, sizeof(buffer), "%d", moonsize);
|
||||
size = buffer;
|
||||
}
|
||||
|
||||
@@ -1234,7 +1235,7 @@ int DoQueuedPs(void)
|
||||
if (fontsize < 0) {
|
||||
fsize = "EntrySize";
|
||||
} else {
|
||||
sprintf(fbuffer, "%d", fontsize);
|
||||
snprintf(fbuffer, sizeof(fbuffer), "%d", fontsize);
|
||||
fsize = fbuffer;
|
||||
}
|
||||
printf("/EntryFont findfont %s scalefont setfont (",
|
||||
@@ -1272,7 +1273,7 @@ int DoQueuedPs(void)
|
||||
if (fontsize < 0) {
|
||||
fsize = "EntrySize";
|
||||
} else {
|
||||
sprintf(fbuffer, "%d", fontsize);
|
||||
snprintf(fbuffer, sizeof(fbuffer), "%d", fontsize);
|
||||
fsize = fbuffer;
|
||||
}
|
||||
printf("/EntryFont findfont %s scalefont setfont (",
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
/* Define the PostScript prologue */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -14,7 +14,7 @@ char *PSProlog1[] =
|
||||
{
|
||||
"% This file was produced by Remind and Rem2PS, written by",
|
||||
"% Dianne Skoll.",
|
||||
"% Remind and Rem2PS are Copyright 1992-2024 Dianne Skoll.",
|
||||
"% Remind and Rem2PS are Copyright (C) 1992-2025 Dianne Skoll.",
|
||||
"/ISOLatin1Encoding where { pop save true }{ false } ifelse",
|
||||
" /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus",
|
||||
" StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute",
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@
|
||||
/* Routines for sorting reminders by trigger date */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -77,7 +77,7 @@ int InsertIntoSortBuffer(int dse, int tim, char const *body, int typ, int prio)
|
||||
int ShouldGoAfter;
|
||||
|
||||
if (!new) {
|
||||
Eprint("%s", ErrMsg[E_NO_MEM]);
|
||||
Eprint("%s", GetErr(E_NO_MEM));
|
||||
IssueSortedReminders();
|
||||
SortByDate = 0;
|
||||
SortByTime = 0;
|
||||
@@ -183,7 +183,7 @@ static void IssueSortBanner(int dse)
|
||||
if (UserFuncExists("sortbanner") != 1) return;
|
||||
|
||||
FromDSE(dse, &y, &m, &d);
|
||||
sprintf(BanExpr, "sortbanner('%04d/%02d/%02d')", y, m+1, d);
|
||||
snprintf(BanExpr, sizeof(BanExpr), "sortbanner('%04d/%02d/%02d')", y, m+1, d);
|
||||
y = EvalExpr(&s, &v, NULL);
|
||||
if (y) return;
|
||||
if (DoCoerce(STR_TYPE, &v)) return;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Make sure Remind compiles with all supported languages; show
|
||||
# tstlang.rem output for each language.
|
||||
|
||||
ALL=`grep ^#define lang.h | grep -v '#define LANG' | awk '{print $2}'`
|
||||
|
||||
OUTPUT_COMPILED=lang-compiled.out
|
||||
OUTPUT_RUNTIME=lang-runtime.out
|
||||
cat /dev/null > $OUTPUT_COMPILED
|
||||
cat /dev/null > $OUTPUT_RUNTIME
|
||||
for i in $ALL ; do
|
||||
make clean
|
||||
make -j`nproc` all LANGDEF=-DLANG=$i || exit 1
|
||||
./remind -q -r ../tests/tstlang.rem >> $OUTPUT_COMPILED 2>&1
|
||||
done
|
||||
|
||||
# Rebuild English version
|
||||
make clean
|
||||
make -j`nproc` all || exit 1
|
||||
|
||||
ALL=`ls ../include/lang/*.rem`
|
||||
for i in $ALL; do
|
||||
./remind -q -r "-ii=\"$i\"" ../tests/tstlang.rem >> $OUTPUT_RUNTIME 2>&1
|
||||
done
|
||||
|
||||
exit 0
|
||||
+3
-1
@@ -6,7 +6,7 @@
|
||||
/* classifying the tokens parsed. */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -107,10 +107,12 @@ Token TokArray[] = {
|
||||
{ "skip", 4, T_Skip, SKIP_SKIP },
|
||||
{ "special", 7, T_RemType, PASSTHRU_TYPE },
|
||||
{ "sunday", 3, T_WkDay, 6 },
|
||||
{ "sysinclude", 10, T_IncludeSys, 0 },
|
||||
{ "tag", 3, T_Tag, 0 },
|
||||
{ "third", 5, T_Ordinal, 2 },
|
||||
{ "through", 7, T_Through, 0 },
|
||||
{ "thursday", 3, T_WkDay, 3 },
|
||||
{ "translate", 5, T_Translate, 0 },
|
||||
{ "tuesday", 3, T_WkDay, 1 },
|
||||
{ "unset", 5, T_UnSet, 0 },
|
||||
{ "until", 5, T_Until, 0 },
|
||||
|
||||
+521
@@ -0,0 +1,521 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* TRANS.C */
|
||||
/* */
|
||||
/* Functions to manage the translation table. Implements */
|
||||
/* the TRANSLATE keyword. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2025 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "types.h"
|
||||
#include "globals.h"
|
||||
#include "protos.h"
|
||||
#include "err.h"
|
||||
|
||||
/* The structure of a translation item */
|
||||
typedef struct xlat {
|
||||
struct hash_link link;
|
||||
char *orig;
|
||||
char *translated;
|
||||
} XlateItem;
|
||||
|
||||
hash_table TranslationTable;
|
||||
|
||||
static XlateItem *FindTranslation(char const *orig);
|
||||
static int printf_formatters_are_safe(char const *orig, char const *translated);
|
||||
|
||||
void
|
||||
TranslationTemplate(char const *in)
|
||||
{
|
||||
if (!*in) {
|
||||
return;
|
||||
}
|
||||
if (!strcmp(in, "LANGID")) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("TRANSLATE ");
|
||||
print_escaped_string_helper(stdout, in, 1);
|
||||
if (FindTranslation(in)) {
|
||||
printf(" ");
|
||||
print_escaped_string_helper(stdout, tr(in), 1);
|
||||
printf("\n");
|
||||
} else {
|
||||
printf(" \"\"\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GenerateTranslationTemplate(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("# Translation table template\n\n");
|
||||
|
||||
printf("TRANSLATE \"LANGID\" ");
|
||||
print_escaped_string_helper(stdout, tr("LANGID"), 1);
|
||||
printf("\n\n");
|
||||
|
||||
printf("BANNER %s\n", DBufValue(&Banner));
|
||||
|
||||
printf("\n# Weekday Names\n");
|
||||
for (i=0; i<7; i++) {
|
||||
printf("SET $%s ", DayName[i]);
|
||||
print_escaped_string_helper(stdout, tr(DayName[i]), 1);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("\n# Month Names\n");
|
||||
for (i=0; i<12; i++) {
|
||||
printf("SET $%s ", MonthName[i]);
|
||||
print_escaped_string_helper(stdout, tr(MonthName[i]), 1);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("\n# Other Translation-related System Variables\n");
|
||||
GenerateSysvarTranslationTemplates();
|
||||
|
||||
printf("\n# Error Messages\n");
|
||||
for (i=0; i<NumErrs; i++) {
|
||||
TranslationTemplate(ErrMsg[i]);
|
||||
}
|
||||
|
||||
printf("\n# Other Messages\n");
|
||||
for (i=0; translatables[i] != NULL; i++) {
|
||||
TranslationTemplate(translatables[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* AllocateXlateItem - Allocate a new translation item */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static XlateItem *
|
||||
AllocateXlateItem(char const *orig, char const *translated)
|
||||
{
|
||||
size_t s1 = sizeof(XlateItem);
|
||||
size_t s2 = strlen(orig)+1;
|
||||
size_t s3 = strlen(translated)+1;
|
||||
XlateItem *item;
|
||||
|
||||
/* Allocate the string space in ONE go! */
|
||||
char *blob = malloc(s1+s2+s3);
|
||||
if (!blob) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item = (XlateItem *) blob;
|
||||
|
||||
item->orig = blob + s1;
|
||||
item->translated = item->orig + s2;
|
||||
strcpy(item->orig, orig);
|
||||
strcpy(item->translated, translated);
|
||||
return item;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FreeXlateItem - Free a translation item */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static void
|
||||
FreeXlateItem(XlateItem *item)
|
||||
{
|
||||
if (!item) return;
|
||||
|
||||
free(item);
|
||||
}
|
||||
|
||||
static void
|
||||
RemoveTranslation(XlateItem *item)
|
||||
{
|
||||
hash_table_delete(&TranslationTable, item);
|
||||
FreeXlateItem(item);
|
||||
}
|
||||
|
||||
static void
|
||||
RemoveTranslationNoResize(XlateItem *item)
|
||||
{
|
||||
hash_table_delete_no_resize(&TranslationTable, item);
|
||||
FreeXlateItem(item);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ClearTranslationTable - free all translation items */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static void
|
||||
ClearTranslationTable(void)
|
||||
{
|
||||
XlateItem *item;
|
||||
XlateItem *next;
|
||||
|
||||
item = hash_table_next(&TranslationTable, NULL);
|
||||
while(item) {
|
||||
next = hash_table_next(&TranslationTable, item);
|
||||
RemoveTranslationNoResize(item);
|
||||
item = next;
|
||||
}
|
||||
hash_table_free(&TranslationTable);
|
||||
InitTranslationTable();
|
||||
}
|
||||
|
||||
void
|
||||
print_escaped_string(FILE *fp, char const *s)
|
||||
{
|
||||
print_escaped_string_helper(fp, s, 0);
|
||||
}
|
||||
|
||||
void
|
||||
print_escaped_string_helper(FILE *fp, char const *s, int esc_for_remind) {
|
||||
putc('"', fp);
|
||||
while(*s) {
|
||||
switch(*s) {
|
||||
case '\a': putc('\\', fp); putc('a', fp); break;
|
||||
case '\b': putc('\\', fp); putc('b', fp); break;
|
||||
case '\f': putc('\\', fp); putc('f', fp); break;
|
||||
case '\n': putc('\\', fp); putc('n', fp); break;
|
||||
case '\r': putc('\\', fp); putc('r', fp); break;
|
||||
case '\t': putc('\\', fp); putc('t', fp); break;
|
||||
case '\v': putc('\\', fp); putc('v', fp); break;
|
||||
case '"': putc('\\', fp); putc('"', fp); break;
|
||||
case '\\': putc('\\', fp); putc('\\', fp); break;
|
||||
default:
|
||||
if (esc_for_remind && *s == '[') {
|
||||
fprintf(fp, "[\"[\"]");
|
||||
} else {
|
||||
putc(*s, fp); break;
|
||||
}
|
||||
}
|
||||
s++;
|
||||
}
|
||||
putc('"', fp);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DumpTranslationTable - Dump the table to a file descriptor */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void
|
||||
DumpTranslationTable(FILE *fp, int json)
|
||||
{
|
||||
XlateItem *item;
|
||||
int done = 0;
|
||||
char const *t;
|
||||
if (!json) {
|
||||
fprintf(fp, "# Translation table\n");
|
||||
/* Always to LANGID first */
|
||||
t = GetTranslatedString("LANGID");
|
||||
if (t) {
|
||||
fprintf(fp, "TRANSLATE \"LANGID\" ");
|
||||
print_escaped_string(fp, t);
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
} else {
|
||||
fprintf(fp, "{");
|
||||
}
|
||||
item = hash_table_next(&TranslationTable, NULL);
|
||||
while(item) {
|
||||
if (!json) {
|
||||
if (strcmp(item->orig, "LANGID")) {
|
||||
fprintf(fp, "TRANSLATE ");
|
||||
print_escaped_string(fp, item->orig);
|
||||
fprintf(fp, " ");
|
||||
print_escaped_string(fp, item->translated);
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
} else {
|
||||
if (done) {
|
||||
fprintf(fp, ",");
|
||||
}
|
||||
done=1;
|
||||
print_escaped_string(fp, item->orig);
|
||||
fprintf(fp, ":");
|
||||
print_escaped_string(fp, item->translated);
|
||||
}
|
||||
item = hash_table_next(&TranslationTable, item);
|
||||
}
|
||||
if (json) {
|
||||
fprintf(fp, "}");
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
HashXlateItem(void *x)
|
||||
{
|
||||
XlateItem *item = (XlateItem *) x;
|
||||
return HashVal_preservecase(item->orig);
|
||||
}
|
||||
|
||||
static int
|
||||
CompareXlateItems(void *a, void *b)
|
||||
{
|
||||
XlateItem *i = (XlateItem *) a;
|
||||
XlateItem *j = (XlateItem *) b;
|
||||
return strcmp(i->orig, j->orig);
|
||||
}
|
||||
|
||||
void
|
||||
InitTranslationTable(void)
|
||||
{
|
||||
if (hash_table_init(&TranslationTable, offsetof(XlateItem, link),
|
||||
HashXlateItem, CompareXlateItems) < 0) {
|
||||
fprintf(ErrFp, "Unable to initialize translation hash table: Out of memory. Exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
InsertTranslation("LANGID", "en");
|
||||
}
|
||||
|
||||
static XlateItem *
|
||||
FindTranslation(char const *orig)
|
||||
{
|
||||
XlateItem *item;
|
||||
XlateItem candidate;
|
||||
candidate.orig = (char *) orig;
|
||||
item = hash_table_find(&TranslationTable, &candidate);
|
||||
return item;
|
||||
}
|
||||
|
||||
int
|
||||
InsertTranslation(char const *orig, char const *translated)
|
||||
{
|
||||
XlateItem *item;
|
||||
|
||||
if (!printf_formatters_are_safe(orig, translated)) {
|
||||
Eprint(tr("Invalid translation: Both original and translated must have the same printf-style formatting sequences in the same order."));
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
item = FindTranslation(orig);
|
||||
if (item) {
|
||||
if (!strcmp(item->translated, translated)) {
|
||||
/* Translation is the same; do nothing */
|
||||
return OK;
|
||||
}
|
||||
RemoveTranslation(item);
|
||||
}
|
||||
|
||||
if (strcmp(orig, "LANGID") && (!strcmp(orig, translated))) {
|
||||
return OK;
|
||||
}
|
||||
item = AllocateXlateItem(orig, translated);
|
||||
if (!item) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
hash_table_insert(&TranslationTable, item);
|
||||
return OK;
|
||||
}
|
||||
|
||||
char const *
|
||||
GetTranslatedString(char const *orig)
|
||||
{
|
||||
XlateItem *item = FindTranslation(orig);
|
||||
if (!item) return NULL;
|
||||
return item->translated;
|
||||
}
|
||||
|
||||
int
|
||||
GetTranslatedStringTryingVariants(char const *orig, DynamicBuffer *out)
|
||||
{
|
||||
DynamicBuffer in;
|
||||
char const *s;
|
||||
int first_lower = 0;
|
||||
int has_upper = 0;
|
||||
|
||||
DBufInit(&in);
|
||||
|
||||
/* Try exact match first */
|
||||
s = GetTranslatedString(orig);
|
||||
if (s) {
|
||||
DBufPuts(out, s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Classify orig */
|
||||
s = orig;
|
||||
while (*s) {
|
||||
if (isupper(*s)) {
|
||||
has_upper = 1;
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
if (islower(*orig)) {
|
||||
first_lower = 1;
|
||||
}
|
||||
|
||||
if (has_upper) {
|
||||
/* Try all lower-case version */
|
||||
DBufPuts(&in, orig);
|
||||
strtolower(DBufValue(&in));
|
||||
s = GetTranslatedString(DBufValue(&in));
|
||||
if (s) {
|
||||
DBufPuts(out, s);
|
||||
strtolower(DBufValue(out));
|
||||
*(DBufValue(out)) = toupper(*DBufValue(out));
|
||||
DBufFree(&in);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (first_lower) {
|
||||
/* Try ucfirst version */
|
||||
DBufFree(&in);
|
||||
DBufPuts(&in, orig);
|
||||
strtolower(DBufValue(&in));
|
||||
*(DBufValue(&in)) = toupper(*(DBufValue(&in)));
|
||||
s = GetTranslatedString(DBufValue(&in));
|
||||
if (s) {
|
||||
DBufPuts(out, s);
|
||||
strtolower(DBufValue(out));
|
||||
DBufFree(&in);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
DBufFree(&in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char const *tr(char const *orig)
|
||||
{
|
||||
char const *n = GetTranslatedString(orig);
|
||||
if (n) {
|
||||
return n;
|
||||
}
|
||||
return orig;
|
||||
}
|
||||
|
||||
int
|
||||
DoTranslate(ParsePtr p)
|
||||
{
|
||||
int r;
|
||||
DynamicBuffer orig, translated;
|
||||
DBufInit(&orig);
|
||||
DBufInit(&translated);
|
||||
int c;
|
||||
|
||||
c = ParseNonSpaceChar(p, &r, 1);
|
||||
if (r) return r;
|
||||
if (c == 0) {
|
||||
return E_EOLN;
|
||||
}
|
||||
|
||||
if (c != '"') {
|
||||
r = ParseToken(p, &orig);
|
||||
if (r) return r;
|
||||
r = VerifyEoln(p);
|
||||
if (!StrCmpi(DBufValue(&orig), "dump")) {
|
||||
DBufFree(&orig);
|
||||
if (r) return r;
|
||||
DumpTranslationTable(stdout, 0);
|
||||
return OK;
|
||||
}
|
||||
if (!StrCmpi(DBufValue(&orig), "clear")) {
|
||||
DBufFree(&orig);
|
||||
if (r) return r;
|
||||
ClearTranslationTable();
|
||||
return OK;
|
||||
}
|
||||
if (!StrCmpi(DBufValue(&orig), "generate")) {
|
||||
DBufFree(&orig);
|
||||
if (r) return r;
|
||||
GenerateTranslationTemplate();
|
||||
return OK;
|
||||
}
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
|
||||
if ( (r=ParseQuotedString(p, &orig)) ) {
|
||||
return r;
|
||||
}
|
||||
if ( (r=ParseQuotedString(p, &translated)) ) {
|
||||
if (r == E_EOLN) {
|
||||
XlateItem *item = FindTranslation(DBufValue(&orig));
|
||||
if (item) {
|
||||
RemoveTranslation(item);
|
||||
}
|
||||
if (!strcmp(DBufValue(&orig), "LANGID")) {
|
||||
InsertTranslation("LANGID", "en");
|
||||
}
|
||||
r = OK;
|
||||
}
|
||||
DBufFree(&orig);
|
||||
return r;
|
||||
}
|
||||
|
||||
if ( (r=VerifyEoln(p)) ) {
|
||||
DBufFree(&orig);
|
||||
DBufFree(&translated);
|
||||
return r;
|
||||
}
|
||||
r = InsertTranslation(DBufValue(&orig), DBufValue(&translated));
|
||||
DBufFree(&orig);
|
||||
DBufFree(&translated);
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
dump_translation_hash_stats(void)
|
||||
{
|
||||
hash_table_dump_stats(&TranslationTable, ErrFp);
|
||||
}
|
||||
|
||||
static void
|
||||
get_printf_escapes(char const *str, DynamicBuffer *out)
|
||||
{
|
||||
char const *s = str;
|
||||
while(*s) {
|
||||
if (*s == '%' && *(s+1) != 0) {
|
||||
|
||||
/* %% is safe and does not need to be replicated in translation */
|
||||
if (*(s+1) == '%') {
|
||||
s += 2;
|
||||
continue;
|
||||
}
|
||||
s++;
|
||||
DBufPutc(out, *s);
|
||||
while (*s && *(s+1) && strchr("#0- +'I%123456789.hlqLjzZt", *s)) {
|
||||
s++;
|
||||
DBufPutc(out, *s);
|
||||
}
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
printf_formatters_are_safe(char const *orig, char const *translated)
|
||||
{
|
||||
DynamicBuffer origEscapes;
|
||||
DynamicBuffer translatedEscapes;
|
||||
int dangerous;
|
||||
|
||||
DBufInit(&origEscapes);
|
||||
DBufInit(&translatedEscapes);
|
||||
|
||||
get_printf_escapes(orig, &origEscapes);
|
||||
get_printf_escapes(translated, &translatedEscapes);
|
||||
|
||||
dangerous = strcmp(DBufValue(&origEscapes), DBufValue(&translatedEscapes));
|
||||
|
||||
if (dangerous) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
+6
-6
@@ -5,7 +5,7 @@
|
||||
/* Routines for figuring out the trigger date of a reminder */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -265,7 +265,7 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
|
||||
return j;
|
||||
|
||||
default:
|
||||
Eprint("NextSimpleTrig %s %d", ErrMsg[E_SWERR], typ);
|
||||
Eprint("NextSimpleTrig %s %d", GetErr(E_SWERR), typ);
|
||||
*err = E_SWERR;
|
||||
return -1;
|
||||
}
|
||||
@@ -560,7 +560,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
(trig->d == NO_DAY ||
|
||||
trig->m == NO_MON ||
|
||||
trig->y == NO_YR)) {
|
||||
Eprint("%s", ErrMsg[E_REP_FULSPEC]);
|
||||
Eprint("%s", GetErr(E_REP_FULSPEC));
|
||||
*err = E_REP_FULSPEC;
|
||||
return -1;
|
||||
}
|
||||
@@ -580,7 +580,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%d): %s\n",
|
||||
FileName, LineNo, ErrMsg[E_EXPIRED]);
|
||||
FileName, LineNo, GetErr(E_EXPIRED));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -630,7 +630,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%d): %s\n",
|
||||
FileName, LineNo, ErrMsg[E_EXPIRED]);
|
||||
FileName, LineNo, GetErr(E_EXPIRED));
|
||||
}
|
||||
if (save_in_globals) {
|
||||
LastTriggerDate = result;
|
||||
@@ -655,7 +655,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%d): %s\n",
|
||||
FileName, LineNo, ErrMsg[E_EXPIRED]);
|
||||
FileName, LineNo, GetErr(E_EXPIRED));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
+27
-23
@@ -5,13 +5,14 @@
|
||||
/* Type definitions all dumped here. */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#include <limits.h>
|
||||
#include "dynbuf.h"
|
||||
#include "hashtab.h"
|
||||
|
||||
typedef struct udf_struct UserFunc;
|
||||
|
||||
@@ -27,6 +28,7 @@ typedef struct udf_struct UserFunc;
|
||||
#define STR_TYPE 0x8
|
||||
#define SPECIAL_TYPE 0x10 /* Only for system variables */
|
||||
#define CONST_INT_TYPE 0x20 /* Only for system variables */
|
||||
#define TRANS_TYPE 0x40 /* Only for system variables */
|
||||
|
||||
#define BEG_OF_EXPR '['
|
||||
#define END_OF_EXPR ']'
|
||||
@@ -56,7 +58,7 @@ enum expr_node_type
|
||||
N_SHORT_USER_FUNC,
|
||||
N_USER_FUNC,
|
||||
N_OPERATOR,
|
||||
N_ERROR = 32767,
|
||||
N_ERROR = 0x7FFF,
|
||||
};
|
||||
|
||||
/* Structure for passing in Nargs and out RetVal from functions */
|
||||
@@ -99,7 +101,7 @@ typedef struct expr_node_struct {
|
||||
|
||||
/* Define the structure of a variable */
|
||||
typedef struct var {
|
||||
struct var *next;
|
||||
struct hash_link link;
|
||||
char name[VAR_NAME_LEN+1];
|
||||
char preserve;
|
||||
Value v;
|
||||
@@ -198,13 +200,15 @@ typedef Parser *ParsePtr; /* Pointer to parser structure */
|
||||
#define NO_MAX 127
|
||||
|
||||
/* DEFINES for debugging flags */
|
||||
#define DB_PRTLINE 1
|
||||
#define DB_PRTEXPR 2
|
||||
#define DB_PRTTRIG 4
|
||||
#define DB_DUMP_VARS 8
|
||||
#define DB_ECHO_LINE 16
|
||||
#define DB_TRACE_FILES 32
|
||||
#define DB_PARSE_EXPR 64
|
||||
#define DB_PRTLINE 0x001
|
||||
#define DB_PRTEXPR 0x002
|
||||
#define DB_PRTTRIG 0x004
|
||||
#define DB_DUMP_VARS 0x008
|
||||
#define DB_ECHO_LINE 0x010
|
||||
#define DB_TRACE_FILES 0x020
|
||||
#define DB_PARSE_EXPR 0x040
|
||||
#define DB_HASHSTATS 0x080
|
||||
#define DB_TRANSLATE 0x100
|
||||
|
||||
/* Enumeration of the tokens */
|
||||
enum TokTypes
|
||||
@@ -213,11 +217,11 @@ enum TokTypes
|
||||
T_Date, T_DateTime, T_Day, T_Debug, T_Delta, T_Dumpvars, T_Duration,
|
||||
T_Else, T_Empty, T_EndIf, T_ErrMsg, T_Exit, T_Expr,
|
||||
T_Flush, T_Frename, T_Fset, T_Funset, T_If, T_IfTrig, T_In,
|
||||
T_Include, T_IncludeCmd, T_IncludeR, T_LastBack, T_LongTime,
|
||||
T_Include, T_IncludeCmd, T_IncludeR, T_IncludeSys, T_LastBack, T_LongTime,
|
||||
T_MaybeUncomputable, T_Month, T_NoQueue, T_Number, T_Omit, T_OmitFunc,
|
||||
T_Once, T_Ordinal, T_Pop, T_Preserve, T_Priority, T_Push,T_Rem,
|
||||
T_RemType, T_Rep, T_Scanfrom, T_Sched, T_Set, T_Skip, T_Tag, T_Through,
|
||||
T_Time, T_UnSet, T_Until, T_Warn, T_WkDay, T_Year
|
||||
T_Time, T_Translate, T_UnSet, T_Until, T_Warn, T_WkDay, T_Year
|
||||
};
|
||||
|
||||
/* The structure of a token */
|
||||
@@ -229,13 +233,13 @@ typedef struct {
|
||||
} Token;
|
||||
|
||||
/* Flags for the state of the "if" stack */
|
||||
#define IF_TRUE 0
|
||||
#define IF_FALSE 1
|
||||
#define BEFORE_ELSE 0
|
||||
#define AFTER_ELSE 2
|
||||
#define IF_MASK 3
|
||||
#define IF_TRUE_MASK 1
|
||||
#define IF_ELSE_MASK 2
|
||||
#define IF_TRUE 0x00
|
||||
#define IF_FALSE 0x01
|
||||
#define BEFORE_ELSE 0x00
|
||||
#define AFTER_ELSE 0x02
|
||||
#define IF_MASK 0x03
|
||||
#define IF_TRUE_MASK 0x01
|
||||
#define IF_ELSE_MASK 0x02
|
||||
|
||||
/* Flags for the DoSubst function */
|
||||
#define NORMAL_MODE 0
|
||||
@@ -245,9 +249,9 @@ typedef struct {
|
||||
#define QUOTE_MARKER 1 /* Unlikely character to appear in reminder */
|
||||
|
||||
/* Flags for disabling run */
|
||||
#define RUN_CMDLINE 1
|
||||
#define RUN_SCRIPT 2
|
||||
#define RUN_NOTOWNER 4
|
||||
#define RUN_CMDLINE 0x01
|
||||
#define RUN_SCRIPT 0x02
|
||||
#define RUN_NOTOWNER 0x04
|
||||
|
||||
/* Flags for the SimpleCalendar format */
|
||||
#define SC_AMPM 0 /* Time shown as 3:00am, etc. */
|
||||
@@ -291,7 +295,7 @@ typedef struct {
|
||||
|
||||
/* Define the data structure used to hold a user-defined function */
|
||||
typedef struct udf_struct {
|
||||
struct udf_struct *next;
|
||||
struct hash_link link;
|
||||
char name[VAR_NAME_LEN+1];
|
||||
expr_node *node;
|
||||
char **args;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user