mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 22:38:37 +02:00
Compare commits
115 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e394f402f8 | ||
|
|
5a2914f6c7 | ||
|
|
a19b009f7c | ||
|
|
6373ae8ca5 | ||
|
|
b8c4786b33 | ||
|
|
4e7cfc20ce | ||
|
|
0c9a35a584 | ||
|
|
5e333f6162 | ||
|
|
af8b4e6df1 | ||
|
|
3fa798523a | ||
|
|
53001f9fbc | ||
|
|
9cd76eae84 | ||
|
|
c8295b6251 | ||
|
|
3c95245407 | ||
|
|
3362c7226c | ||
|
|
356b562d75 | ||
|
|
6eebcdc39d | ||
|
|
5a80d63060 | ||
|
|
c7ca1b4baa | ||
|
|
dc89a6fba9 | ||
|
|
f83fec5563 | ||
|
|
9c38161430 | ||
|
|
68f5fe1d10 | ||
|
|
bc7c57e53b | ||
|
|
88aacb3905 | ||
|
|
a894076bfc | ||
|
|
82e068fcca | ||
|
|
a119d97539 | ||
|
|
01afb63a3d | ||
|
|
54fccabdfe | ||
|
|
ba4d44664f | ||
|
|
d76c5499b5 | ||
|
|
84e8244e48 | ||
|
|
92a6115a5c | ||
|
|
b98e336e9e | ||
|
|
ffcd21446e | ||
|
|
af9ca68d99 | ||
|
|
71db7168a1 | ||
|
|
54f284c43f | ||
|
|
0ab93f2dea | ||
|
|
3d97f87bcd | ||
|
|
dcfa6d8ef8 | ||
|
|
52dd5332f4 | ||
|
|
7b5fafe1ab | ||
|
|
929af71a10 | ||
|
|
abf7c74ff2 | ||
|
|
5b9d9a67b2 | ||
|
|
16ca2ade23 | ||
|
|
d3e6c81a3a | ||
|
|
13ae49d3cd | ||
|
|
78adc9f61d | ||
|
|
a622d4fad4 | ||
|
|
6c0e7b4ff5 | ||
|
|
28e0599380 | ||
|
|
87445f639c | ||
|
|
af6e159eaa | ||
|
|
bffa28e258 | ||
|
|
1781f84d84 | ||
|
|
ed6e65182e | ||
|
|
f5cc0ec686 | ||
|
|
a2c818f96c | ||
|
|
0bbbaaf3d9 | ||
|
|
1c81d4cae3 | ||
|
|
56c684087b | ||
|
|
9500a929ea | ||
|
|
585d45e4a1 | ||
|
|
67d1d1366d | ||
|
|
f4018892e8 | ||
|
|
ffd309f89d | ||
|
|
286babc1bf | ||
|
|
cc3c0040e9 | ||
|
|
b33a1ee98b | ||
|
|
99706741bb | ||
|
|
df73a74503 | ||
|
|
c747ebebb4 | ||
|
|
6b412062c2 | ||
|
|
27b688f82c | ||
|
|
4c314ff81c | ||
|
|
d2955ec733 | ||
|
|
480216db9e | ||
|
|
9dbb0de7e6 | ||
|
|
9f9ae77895 | ||
|
|
d9796e72e5 | ||
|
|
e0b0d043c6 | ||
|
|
fe4499ab72 | ||
|
|
e50d583659 | ||
|
|
6b05d772f0 | ||
|
|
84dd73f023 | ||
|
|
00dca8b70f | ||
|
|
c4bc145cd9 | ||
|
|
bd614c1cde | ||
|
|
1446ac0552 | ||
|
|
26ded447ab | ||
|
|
a4ccb0738e | ||
|
|
27a1b449bd | ||
|
|
1443282859 | ||
|
|
4a2d707654 | ||
|
|
fd2a61928c | ||
|
|
a05d9eefc9 | ||
|
|
6f230e81bd | ||
|
|
973019c4c7 | ||
|
|
cb712ad7e7 | ||
|
|
be7c67b6fd | ||
|
|
a933c8bc69 | ||
|
|
087fbfd8e6 | ||
|
|
ff641d7990 | ||
|
|
54e788b765 | ||
|
|
4283feff31 | ||
|
|
062a84b758 | ||
|
|
d161a8ff1a | ||
|
|
0df4a79531 | ||
|
|
1b26e39e2f | ||
|
|
c63c4cf07e | ||
|
|
586b3565f0 | ||
|
|
877aaed1a1 |
50
build.tk
50
build.tk
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -786,7 +743,6 @@ proc SetConfigFromRemind {} {
|
||||
QueryRemind $rem LOCATION {$Location}
|
||||
QueryRemind $rem DATESEP {$DateSep}
|
||||
QueryRemind $rem TIMESEP {$TimeSep}
|
||||
QueryRemind $rem LANGUAGE {language()}
|
||||
|
||||
set $Config(LAT_MIN) [expr abs($Config(LAT_MIN))]
|
||||
set $Config(LAT_SEC) [expr abs($Config(LAT_SEC))]
|
||||
|
||||
18
configure
vendored
18
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.71 for remind 05.01.01.
|
||||
# Generated by GNU Autoconf 2.71 for remind 05.02.00.
|
||||
#
|
||||
#
|
||||
# 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.00'
|
||||
PACKAGE_STRING='remind 05.02.00'
|
||||
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.00 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.00:";;
|
||||
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.00
|
||||
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.00, 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.00, 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.00
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(remind, 05.01.01, , , https://dianne.skoll.ca/projects/remind/)
|
||||
AC_INIT(remind, 05.02.00, , , 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)))))
|
||||
|
||||
|
||||
@@ -162,7 +163,7 @@
|
||||
|
||||
(defconst remind-builtin-functions
|
||||
(sort
|
||||
(list "abs" "access" "adawn" "adusk" "ampm" "ansicolor" "args" "asc"
|
||||
(list "_" "abs" "access" "adawn" "adusk" "ampm" "ansicolor" "args" "asc"
|
||||
"baseyr" "char" "choose" "coerce" "columns" "current" "date"
|
||||
"datepart" "datetime" "dawn" "day" "daysinmon" "defined" "dosubst"
|
||||
"dusk" "easterdate" "evaltrig" "filedate" "filedatetime" "filedir"
|
||||
@@ -188,21 +189,21 @@
|
||||
(defvar remind-conf-command-face 'remind-conf-command-face
|
||||
"Remind commands.")
|
||||
(defface remind-conf-command-face
|
||||
'((t :foreground "SeaGreen4" :bold t))
|
||||
'((t :foreground "#FF8080"))
|
||||
"Font Lock mode face used to highlight commands."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-conf-keyword-face 'remind-conf-keyword-face
|
||||
"Remind keywords.")
|
||||
(defface remind-conf-keyword-face
|
||||
'((t :foreground "blue violet"))
|
||||
'((t :foreground "#FFFF80"))
|
||||
"Font Lock mode face used to highlight keywords."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-conf-substitutes-face 'remind-conf-substitutes-face
|
||||
"Remind substitutes.")
|
||||
(defface remind-conf-substitutes-face
|
||||
'((t :foreground "blue2"))
|
||||
'((t :foreground "#8080FF"))
|
||||
"Font Lock mode face used to highlight substitutes."
|
||||
:group 'remind-conf)
|
||||
|
||||
@@ -216,7 +217,7 @@
|
||||
(defvar remind-conf-variable-face 'remind-conf-variable-face
|
||||
"Remind variable.")
|
||||
(defface remind-conf-variable-face
|
||||
'((t :foreground "DeepPink2" :bold t))
|
||||
'((t :foreground "#FF8080" :bold t))
|
||||
"Font Lock mode face used to highlight commands."
|
||||
:group 'remind-conf)
|
||||
|
||||
@@ -237,14 +238,14 @@
|
||||
(defvar remind-comment-face 'remind-comment-face
|
||||
"Remind comments.")
|
||||
(defface remind-comment-face
|
||||
'((t :foreground "brown"))
|
||||
'((t :foreground "#FF7F24"))
|
||||
"Font-lock face for highlighting comments."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-string-face 'remind-string-face
|
||||
"Remind strings.")
|
||||
(defface remind-string-face
|
||||
'((t :foreground "tomato"))
|
||||
'((t :foreground "#FF7FE0"))
|
||||
"Font lock mode face used to highlight strings."
|
||||
:group 'remind-conf)
|
||||
|
||||
@@ -296,11 +297,11 @@
|
||||
(defconst remind-conf-font-lock-keywords-1
|
||||
(list
|
||||
'("^\s*[\;\#].*$" . remind-comment-face)
|
||||
'("\"[^\"]*\"" . remind-string-face)
|
||||
'(remind-keywords-matcher . remind-conf-keyword-face)
|
||||
'("%[\"_]" . font-lock-warning-face)
|
||||
'("\\(%[a-mops-w]\\)" . remind-conf-substitutes-face)
|
||||
'("\"[^\"]*\"" . remind-string-face))
|
||||
"Minimal font-locking for `remind-conf-mode'.")
|
||||
'("\\(%[a-z]\\)" . remind-conf-substitutes-face)
|
||||
"Minimal font-locking for `remind-conf-mode'."))
|
||||
|
||||
(defconst remind-conf-font-lock-keywords-2
|
||||
(append remind-conf-font-lock-keywords-1
|
||||
|
||||
@@ -1,5 +1,64 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* 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.
|
||||
|
||||
@@ -54,8 +54,8 @@ advance warning of holidays:
|
||||
FSET msgsuffix(x) char(8) + dosubst(" is %b.%", $T)
|
||||
|
||||
# Include your holiday files here...
|
||||
INCLUDE [$SysInclude]/holidays/us.rem
|
||||
INCLUDE [$SysInclude]/holidays/us/ny.rem
|
||||
SYSINCLUDE holidays/us.rem
|
||||
SYSINCLUDE holidays/us/ny.rem
|
||||
|
||||
# Restore old version of msgsuffix and $DefaultDelta
|
||||
FRENAME saved_msgsuffix msgsuffix
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
REM 1 Feb 2022 MSG Chinese New Year (Tiger)
|
||||
REM 22 Jan 2023 MSG Chinese New Year (Rabbit)
|
||||
REM 10 Feb 2024 MSG Chinese New Year (Dragon)
|
||||
REM 29 Jan 2025 MSG Chinese New Year (Snake)
|
||||
REM 17 Feb 2026 MSG Chinese New Year (Horse)
|
||||
REM 6 Feb 2027 MSG Chinese New Year (Goat)
|
||||
REM 26 Jan 2028 MSG Chinese New Year (Monkey)
|
||||
REM 13 Feb 2029 MSG Chinese New Year (Rooster)
|
||||
REM 3 Feb 2030 MSG Chinese New Year (Dog)
|
||||
REM 23 Jan 2031 MSG Chinese New Year (Pig)
|
||||
REM 11 Feb 2032 MSG Chinese New Year (Rat)
|
||||
REM 31 Jan 2033 MSG Chinese New Year (Ox)
|
||||
REM 19 Feb 2034 MSG Chinese New Year (Tiger)
|
||||
REM 8 Feb 2035 MSG Chinese New Year (Rabbit)
|
||||
REM 28 Jan 2036 MSG Chinese New Year (Dragon)
|
||||
REM 15 Feb 2037 MSG Chinese New Year (Snake)
|
||||
REM 4 Feb 2038 MSG Chinese New Year (Horse)
|
||||
REM 24 Jan 2039 MSG Chinese New Year (Goat)
|
||||
REM 12 Feb 2040 MSG Chinese New Year (Monkey)
|
||||
REM 1 Feb 2041 MSG Chinese New Year (Rooster)
|
||||
REM 22 Jan 2042 MSG Chinese New Year (Dog)
|
||||
REM 10 Feb 2043 MSG Chinese New Year (Pig)
|
||||
REM 30 Jan 2044 MSG Chinese New Year (Rat)
|
||||
REM 17 Feb 2045 MSG Chinese New Year (Ox)
|
||||
REM 6 Feb 2046 MSG Chinese New Year (Tiger)
|
||||
REM 26 Jan 2047 MSG Chinese New Year (Rabbit)
|
||||
REM 14 Feb 2048 MSG Chinese New Year (Dragon)
|
||||
REM 2 Feb 2049 MSG Chinese New Year (Snake)
|
||||
REM 23 Jan 2050 MSG Chinese New Year (Horse)
|
||||
REM 1 Feb 2022 MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 22 Jan 2023 MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 10 Feb 2024 MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 29 Jan 2025 MSG %(Chinese New Year) (%(Snake))
|
||||
REM 17 Feb 2026 MSG %(Chinese New Year) (%(Horse))
|
||||
REM 6 Feb 2027 MSG %(Chinese New Year) (%(Goat))
|
||||
REM 26 Jan 2028 MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 13 Feb 2029 MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 3 Feb 2030 MSG %(Chinese New Year) (%(Dog))
|
||||
REM 23 Jan 2031 MSG %(Chinese New Year) (%(Pig))
|
||||
REM 11 Feb 2032 MSG %(Chinese New Year) (%(Rat))
|
||||
REM 31 Jan 2033 MSG %(Chinese New Year) (%(Ox))
|
||||
REM 19 Feb 2034 MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 8 Feb 2035 MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 28 Jan 2036 MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 15 Feb 2037 MSG %(Chinese New Year) (%(Snake))
|
||||
REM 4 Feb 2038 MSG %(Chinese New Year) (%(Horse))
|
||||
REM 24 Jan 2039 MSG %(Chinese New Year) (%(Goat))
|
||||
REM 12 Feb 2040 MSG %(Chinese New Year) (%(Monkey))
|
||||
REM 1 Feb 2041 MSG %(Chinese New Year) (%(Rooster))
|
||||
REM 22 Jan 2042 MSG %(Chinese New Year) (%(Dog))
|
||||
REM 10 Feb 2043 MSG %(Chinese New Year) (%(Pig))
|
||||
REM 30 Jan 2044 MSG %(Chinese New Year) (%(Rat))
|
||||
REM 17 Feb 2045 MSG %(Chinese New Year) (%(Ox))
|
||||
REM 6 Feb 2046 MSG %(Chinese New Year) (%(Tiger))
|
||||
REM 26 Jan 2047 MSG %(Chinese New Year) (%(Rabbit))
|
||||
REM 14 Feb 2048 MSG %(Chinese New Year) (%(Dragon))
|
||||
REM 2 Feb 2049 MSG %(Chinese New Year) (%(Snake))
|
||||
REM 23 Jan 2050 MSG %(Chinese New Year) (%(Horse))
|
||||
|
||||
@@ -19,3 +19,4 @@ OMIT 24 September MSG ទិវាប្រកាសរដ្ឋធម្មន
|
||||
OMIT 15 October MSG ទិវាប្រារព្ឋពិធីគោរពព្រះវិញ្ញាណក្ខន្ឋ ព្រះករុណា ព្រះបាទសម្តេចព្រះ នរោត្តម សីហនុ ព្រះមហាវីរក្សត្រ ព្រះវររាជបិតាឯករាជ្យ បូរណភាពទឹកដី និងឯកភាពជាតិខ្មែរ ព្រះបរមរតនកោដ្ឋ
|
||||
OMIT 29 October MSG ព្រះរាជពិធីគ្រងព្រះបរមរាជសម្បត្តិ របស់ ព្រះករុណា ព្រះបាទសម្តេចព្រះបរមនាថ នរោត្តម សីហមុនី ព្រះមហាក្សត្រនៃព្រះរាជាណាចក្រកម្ពុជា
|
||||
OMIT 9 November MSG ពិធីបុណ្យឯករាជ្យជាតិ
|
||||
OMIT 29 December MSG ទិវាសន្តិភាពនៅកម្ពុជា
|
||||
|
||||
@@ -24,7 +24,6 @@ REM 3 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 4)) == 6] MSG Ind
|
||||
OMIT 4 July MSG Independence Day
|
||||
REM 5 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 4)) == 0] MSG Independence Day (observed)
|
||||
REM First Monday in September ADDOMIT SCANFROM -28 MSG Labor Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM 10 November ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 11)) == 6] MSG Veterans Day (observed)
|
||||
OMIT 11 November MSG Veterans Day
|
||||
REM 12 November ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 11, 11)) == 0] MSG Veterans Day (observed)
|
||||
|
||||
@@ -16,4 +16,5 @@ REM 18 April ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 4, 17)) == 0] MSG
|
||||
REM 15 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 16)) == 6] MSG Manu'a Islands Cession Day (observed)
|
||||
OMIT 16 July MSG Manu'a Islands Cession Day
|
||||
REM 17 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 16)) == 0] MSG Manu'a Islands Cession Day (observed)
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Second Sunday in October ADDOMIT SCANFROM -28 MSG White Sunday
|
||||
|
||||
@@ -11,3 +11,4 @@
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Third Monday in January ADDOMIT SCANFROM -28 MSG Dr. Martin Luther King Jr. / Civil Rights Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -14,3 +14,4 @@ REM 11 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 6] M
|
||||
OMIT 12 February MSG Lincoln's Birthday
|
||||
REM 13 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 0] MSG Lincoln's Birthday (observed)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Fourth Monday in April ADDOMIT SCANFROM -28 MSG State Holiday
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG State Holiday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [$TW == 4 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 2 || $Tw == 4] MSG Washington's Birthday
|
||||
|
||||
@@ -11,3 +11,4 @@
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Third Monday in January ADDOMIT SCANFROM -28 MSG Martin Luther King Jr. / Idaho Human Rights Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -14,3 +14,4 @@ REM 11 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 6] M
|
||||
OMIT 12 February MSG Lincoln's Birthday
|
||||
REM 13 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 0] MSG Lincoln's Birthday (observed)
|
||||
REM First Monday in March ADDOMIT SCANFROM -28 MSG Casimir Pulaski Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
REM Tuesday 2 May ADDOMIT SCANFROM -28 MSG Primary Election Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG Lincoln's Birthday
|
||||
REM 23 December ADDOMIT SCANFROM -28 SATISFY [$TW == 4 || $Tw == 5] MSG Washington's Birthday
|
||||
REM 24 December ADDOMIT SCANFROM -28 SATISFY [$Tw == 1 || $Tw == 2 || $Tw == 4] MSG Washington's Birthday
|
||||
|
||||
@@ -14,3 +14,4 @@ OMIT 17 March MSG Evacuation Day
|
||||
REM 18 March ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 17)) == 0] MSG Evacuation Day (observed)
|
||||
REM 19 March ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 3, 17)) == 6] MSG Evacuation Day (observed)
|
||||
REM Third Monday in April ADDOMIT SCANFROM -28 MSG Patriots' Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -10,4 +10,5 @@
|
||||
# If you want the national holidays as well, you must
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG American Indian Heritage Day
|
||||
|
||||
@@ -13,3 +13,4 @@
|
||||
REM 7 May ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 8)) == 6] MSG Truman Day (observed)
|
||||
OMIT 8 May MSG Truman Day
|
||||
REM 9 May ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 5, 8)) == 0] MSG Truman Day (observed)
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
13
include/holidays/us/mt.rem
Normal file
13
include/holidays/us/mt.rem
Normal file
@@ -0,0 +1,13 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Holiday file for subdivision MT in United States
|
||||
# Derived from the Python holidays project at
|
||||
# https://github.com/vacanza/holidays
|
||||
#
|
||||
# Note that this file includes only the holidays for
|
||||
# the specific subdivision MT.
|
||||
# See important caveats in the file ../README
|
||||
#
|
||||
# If you want the national holidays as well, you must
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
@@ -14,3 +14,4 @@ REM 11 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 6] M
|
||||
OMIT 12 February MSG Lincoln's Birthday
|
||||
REM 13 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 0] MSG Lincoln's Birthday (observed)
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -14,3 +14,4 @@ REM 11 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 6] M
|
||||
OMIT 12 February MSG Lincoln's Birthday
|
||||
REM 13 February ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 2, 12)) == 0] MSG Lincoln's Birthday (observed)
|
||||
OMIT 15 February MSG Susan B. Anthony Day
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
13
include/holidays/us/oh.rem
Normal file
13
include/holidays/us/oh.rem
Normal file
@@ -0,0 +1,13 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Holiday file for subdivision OH in United States
|
||||
# Derived from the Python holidays project at
|
||||
# https://github.com/vacanza/holidays
|
||||
#
|
||||
# Note that this file includes only the holidays for
|
||||
# the specific subdivision OH.
|
||||
# See important caveats in the file ../README
|
||||
#
|
||||
# If you want the national holidays as well, you must
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
@@ -10,4 +10,5 @@
|
||||
# If you want the national holidays as well, you must
|
||||
# also include [$SysInclude]/holidays/us.rem
|
||||
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG Day After Thanksgiving
|
||||
|
||||
@@ -13,3 +13,4 @@
|
||||
REM 23 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 24)) == 6] MSG Pioneer Day (observed)
|
||||
OMIT 24 July MSG Pioneer Day
|
||||
REM 25 July ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 7, 24)) == 0] MSG Pioneer Day (observed)
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
|
||||
@@ -13,4 +13,5 @@
|
||||
REM 19 June ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 20)) == 6] MSG West Virginia Day (observed)
|
||||
OMIT 20 June MSG West Virginia Day
|
||||
REM 21 June ADDOMIT SCANFROM -28 SATISFY [wkdaynum(date($Ty, 6, 20)) == 0] MSG West Virginia Day (observed)
|
||||
REM Second Monday in October ADDOMIT SCANFROM -28 MSG Columbus Day
|
||||
REM Friday 23 November ADDOMIT SCANFROM -28 MSG Day After Thanksgiving
|
||||
|
||||
@@ -16,10 +16,10 @@ if !defined("__autolang__")
|
||||
|
||||
IF autolang != ""
|
||||
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 5)) + ".rem", "r") == 0
|
||||
INCLUDE [$SysInclude]/lang/[lower(substr(autolang, 1, 5))].rem
|
||||
SYSINCLUDE lang/[lower(substr(autolang, 1, 5))].rem
|
||||
ELSE
|
||||
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 2)) + ".rem", "r") == 0
|
||||
INCLUDE [$SysInclude]/lang/[lower(substr(autolang, 1, 2))].rem
|
||||
SYSINCLUDE lang/[lower(substr(autolang, 1, 2))].rem
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 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,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 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"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 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."
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 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"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# This file is derived from a translation by Mikko Silvonen
|
||||
|
||||
TRANSLATE "LANGID" "fi"
|
||||
|
||||
SET $Sunday "sunnuntai"
|
||||
SET $Monday "maanantai"
|
||||
SET $Tuesday "tiistai"
|
||||
@@ -92,3 +94,103 @@ FSET subst_hour_past(h) iif(h==0, "", h + " " + $Hour + iif(h==1, " ", $Hplu + "
|
||||
FSET subst_min_past(m) iif(m==0, "", m + " " + $Minute + iif(m==1, " ", $Mplu + " "))
|
||||
FSET subst_hour_future(h) iif(h==0, "", h + " tunnin ")
|
||||
FSET subst_min_future(m) iif(m==0, "", m + " minuutin ")
|
||||
|
||||
TRANSLATE "Missing ']'" "Puuttuva ']'"
|
||||
TRANSLATE "Missing quote" "Puuttuva lainausmerkki"
|
||||
TRANSLATE "Expression too complex" "Liian monimutkainen lauseke"
|
||||
TRANSLATE "Missing ')'" "Puuttuva ')'"
|
||||
TRANSLATE "Undefined function" "Määrittelemätön funktio"
|
||||
TRANSLATE "Illegal character" "Virheellinen merkki"
|
||||
TRANSLATE "Expecting binary operator" "Kaksipaikkainen operaattori puuttuu"
|
||||
TRANSLATE "Out of memory" "Muisti loppui"
|
||||
TRANSLATE "Ill-formed number" "Virheellinen luku"
|
||||
TRANSLATE "Can't coerce" "Tyyppimuunnos ei onnistu"
|
||||
TRANSLATE "Type mismatch" "Virheellinen tyyppi"
|
||||
TRANSLATE "Date overflow" "Liian suuri päiväys"
|
||||
TRANSLATE "Division by zero" "Jako nollalla"
|
||||
TRANSLATE "Undefined variable" "Määrittelemätön funktio"
|
||||
TRANSLATE "Unexpected end of line" "Odottamaton rivin loppu"
|
||||
TRANSLATE "Unexpected end of file" "Odottamaton tiedoston loppu"
|
||||
TRANSLATE "I/O error" "Syöttö- tai tulostusvirhe"
|
||||
TRANSLATE "Internal error" "Sisäinen virhe"
|
||||
TRANSLATE "Bad date specification" "Virheellinen päiväys"
|
||||
TRANSLATE "Not enough arguments" "Liian vähän argumentteja"
|
||||
TRANSLATE "Too many arguments" "Liian paljon argumentteja"
|
||||
TRANSLATE "Ill-formed time" "Virheellinen aika"
|
||||
TRANSLATE "Number too high" "Liian suuri luku"
|
||||
TRANSLATE "Number too low" "Liian pieni luku"
|
||||
TRANSLATE "Can't open file" "Tiedoston avaus ei onnistu"
|
||||
TRANSLATE "INCLUDE nested too deeply (max. 9)" "Liian monta sisäkkäistä INCLUDEa"
|
||||
TRANSLATE "Parse error" "Jäsennysvirhe"
|
||||
TRANSLATE "Can't compute trigger" "Laukaisuhetken laskenta ei onnistu"
|
||||
TRANSLATE "Too many nested IFs" "Liian monta sisäkkäistä IF-lausetta"
|
||||
TRANSLATE "ELSE with no matching IF" "ELSE ilman IF-lausetta"
|
||||
TRANSLATE "ENDIF with no matching IF" "ENDIF ilman IF-lausetta"
|
||||
TRANSLATE "Can't OMIT every weekday" "Kaikkia viikonpäiviä ei voi jättää pois"
|
||||
TRANSLATE "Extraneous token(s) on line" "Ylimääräisiä merkkejä rivillä"
|
||||
TRANSLATE "POP-OMIT-CONTEXT without matching PUSH-OMIT-CONTEXT" "POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia"
|
||||
TRANSLATE "RUN disabled" "RUN-lauseen käyttö estetty"
|
||||
TRANSLATE "Domain error" "Arvoaluevirhe"
|
||||
TRANSLATE "Invalid identifier" "Virheellinen tunniste"
|
||||
TRANSLATE "Too many recursive function calls" "Liian monta rekursiivista toimintopuhelua"
|
||||
TRANSLATE "Cannot modify system variable" "Järjestelmämuuttujan muuttaminen ei onnistu"
|
||||
TRANSLATE "C library function can't represent date/time" "C-kirjastofunktio ei pysty esittämään päiväystä tai aikaa"
|
||||
TRANSLATE "Attempt to redefine built-in function" "Sisäisen funktion määritelmää yritettiin muuttaa"
|
||||
TRANSLATE "Can't nest function definition in expression" "Lausekkeessa ei voi olla sisäkkäisiä funktiomääritelmiä"
|
||||
TRANSLATE "Must fully specify date to use repeat factor" "Päiväyksen täytyy olla täydellinen toistokertoimessa"
|
||||
TRANSLATE "Year specified twice" "Vuosi annettu kahdesti"
|
||||
TRANSLATE "Month specified twice" "Kuukausi annettu kahdesti"
|
||||
TRANSLATE "Day specified twice" "Päivä annettu kahdesti"
|
||||
TRANSLATE "Unknown token" "Tuntematon sana tai merkki"
|
||||
TRANSLATE "Must specify month in OMIT command" "OMIT-komennossa on annettava kuukausi"
|
||||
TRANSLATE "Too many full OMITs (max. 1000)" "Liian monta täydellistä OMIT-komentoa"
|
||||
TRANSLATE "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT" "Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia"
|
||||
TRANSLATE "Error reading" "Virhe tiedoston luvussa"
|
||||
TRANSLATE "Expecting end-of-line" "Pilkku puuttuu"
|
||||
TRANSLATE "Invalid Hebrew date" "Virheellinen juutalainen päiväys"
|
||||
TRANSLATE "iif(): odd number of arguments required" "IIF vaatii parittoman määrän argumentteja"
|
||||
TRANSLATE "Warning: Missing ENDIF" "Varoitus: puuttuva ENDIF"
|
||||
TRANSLATE "Expecting comma" "Pilkku puuttuu"
|
||||
TRANSLATE "Weekday specified twice" "Viikonpäivä annettu kahdesti"
|
||||
TRANSLATE "Only use one of BEFORE, AFTER or SKIP" "Käytä vain yhtä komennoista BEFORE, AFTER ja SKIP"
|
||||
TRANSLATE "Can't nest MSG, MSF, RUN, etc. in expression" "Sisäkkäisiä MSG-, MSF- ja RUN-lauseita ei voi käyttää lausekkeessa"
|
||||
TRANSLATE "Repeat value specified twice" "Toistokerroin annettu kahdesti"
|
||||
TRANSLATE "Delta value specified twice" "Delta-arvo annettu kahdesti"
|
||||
TRANSLATE "Back value specified twice" "Peruutusarvo annettu kahdesti"
|
||||
TRANSLATE "ONCE keyword used twice. (Hah.)" "ONCE-avainsanaa käytetty kahdesti. (Hah.)"
|
||||
TRANSLATE "Expecting time after AT" "AT-sanan perästä puuttuu aika"
|
||||
TRANSLATE "THROUGH/UNTIL keyword used twice" "THROUGH/UNTIL-sanaa käytetty kahdesti"
|
||||
TRANSLATE "Incomplete date specification" "Epätäydellinen päiväys"
|
||||
TRANSLATE "FROM/SCANFROM keyword used twice" "FROM/SCANFROM-sanaa käytetty kahdesti"
|
||||
TRANSLATE "Variable" "Muuttuja"
|
||||
TRANSLATE "Value" "Arvo"
|
||||
TRANSLATE "*UNDEFINED*" "*MÄÄRITTELEMÄTÖN*"
|
||||
TRANSLATE "Entering UserFN" "Siirrytään funktioon"
|
||||
TRANSLATE "Leaving UserFN" "Poistutaan funktiosta"
|
||||
TRANSLATE "Expired" "Vanhentunut"
|
||||
TRANSLATE "fork() failed - can't do queued reminders" "fork() epäonnistui - jonomuistutukset eivät toimi"
|
||||
TRANSLATE "Can't access file" "Tiedoston avaus ei onnistu"
|
||||
TRANSLATE "Illegal system date: Year is less than %d\n" "Virheellinen järjestelmäpäiväys: vuosi on vähemmän kuin %d\n"
|
||||
TRANSLATE "Unknown debug flag '%c'\n" "Tuntematon virheenetsintätarkenne '%c'\n"
|
||||
TRANSLATE "Unknown option '%c'\n" "Tuntematon tarkenne '%c'\n"
|
||||
TRANSLATE "Unknown user '%s'\n" "Tuntematon käyttäjä '%s'\n"
|
||||
TRANSLATE "Could not change gid to %d\n" "Ryhmänumeron vaihto %d:ksi ei onnistunut\n"
|
||||
TRANSLATE "Could not change uid to %d\n" "Käyttäjänumeron vaihto %d:ksi ei onnistunut\n"
|
||||
TRANSLATE "Out of memory for environment\n" "Muisti ei riitä ympäristölle\n"
|
||||
TRANSLATE "Missing '=' sign" "Puuttuva '='-merkki"
|
||||
TRANSLATE "Missing variable name" "Puuttuva muuttujanimi"
|
||||
TRANSLATE "Missing expression" "Puuttuva lauseke"
|
||||
TRANSLATE "Remind: '-i' option: %s\n" "Remind: tarkenne '-i': %s\n"
|
||||
TRANSLATE "No reminders." "Ei viestejä."
|
||||
TRANSLATE "%d reminder(s) queued for later today.\n" "%d viesti(ä) tämän päivän jonossa.\n"
|
||||
TRANSLATE "Expecting number" "Numero puuttuu"
|
||||
TRANSLATE "Undefined WARN function" "Virheellinen funktio WARN-lausekkeessa"
|
||||
TRANSLATE "Can't convert between time zones" "Aikavyöhykkeiden välillä ei voi muuntaa"
|
||||
TRANSLATE "No files matching *.rem" "Ei tiedostoja, jotka vastaavat *.rem"
|
||||
TRANSLATE "String too long" "Merkkijono liian kauan"
|
||||
TRANSLATE "Time specified twice" "Aika määritetty kahdesti"
|
||||
TRANSLATE "Cannot specify DURATION without specifying AT" "Ei voi määrittää DURATION määrittelemättä AT"
|
||||
TRANSLATE "Expecting weekday name" "Odotettu viikonpäivän nimi"
|
||||
TRANSLATE "Duplicate argument name" "Päällekkäinen argumentin nimi"
|
||||
TRANSLATE "Expression evaluation is disabled" "Lausekkeiden arviointi on poistettu käytöstä"
|
||||
TRANSLATE "Time limit for expression evaluation exceeded" "Ilmaisun arvioinnin aikaraja ylitti"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# This file is derived from a translation by Laurent Duperval
|
||||
|
||||
TRANSLATE "LANGID" "fr"
|
||||
|
||||
SET $Sunday "dimanche"
|
||||
SET $Monday "lundi"
|
||||
SET $Tuesday "mardi"
|
||||
@@ -60,3 +62,101 @@ FSET subst_jx(alt, date, time) iif(alt, subst_j_alt(date), $On + " " + subst_j_a
|
||||
|
||||
FSET subst_k_alt(date) wkday(date) + ", " + day(date) + subst_ordinal(day(date)) + " " + mon(date)
|
||||
FSET subst_kx(alt, date, time) iif(alt, subst_k_alt(date), $On + " " + subst_k_alt(date))
|
||||
|
||||
TRANSLATE "Missing ']'" "']' manquant"
|
||||
TRANSLATE "Missing quote" "Apostrophe manquant"
|
||||
TRANSLATE "Expression too complex" "Expression trop complexe"
|
||||
TRANSLATE "Missing ')'" "')' manquante"
|
||||
TRANSLATE "Undefined function" "Fonction non-définie"
|
||||
TRANSLATE "Illegal character" "Caractère illégal"
|
||||
TRANSLATE "Expecting binary operator" "Opérateur binaire attendu"
|
||||
TRANSLATE "Out of memory" "Manque de mémoire"
|
||||
TRANSLATE "Ill-formed number" "Nombre mal formé"
|
||||
TRANSLATE "Can't coerce" "Impossible de convertir"
|
||||
TRANSLATE "Type mismatch" "Types non-équivalents"
|
||||
TRANSLATE "Date overflow" "Débordement de date"
|
||||
TRANSLATE "Division by zero" "Division par zéro"
|
||||
TRANSLATE "Undefined variable" "Variable non définie"
|
||||
TRANSLATE "Unexpected end of line" "Fin de ligne non attendue"
|
||||
TRANSLATE "Unexpected end of file" "Fin de fichier non attendue"
|
||||
TRANSLATE "I/O error" "Erreur I/O"
|
||||
TRANSLATE "Internal error" "Erreur interne"
|
||||
TRANSLATE "Bad date specification" "Mauvaise date spécifiée"
|
||||
TRANSLATE "Not enough arguments" "Pas assez d'arguments"
|
||||
TRANSLATE "Too many arguments" "Trop d'arguments"
|
||||
TRANSLATE "Ill-formed time" "Heure mal formée"
|
||||
TRANSLATE "Number too high" "Nombre trop élevé"
|
||||
TRANSLATE "Number too low" "Nombre trop bas"
|
||||
TRANSLATE "Can't open file" "Impossible d'ouvrir le fichier"
|
||||
TRANSLATE "INCLUDE nested too deeply (max. 9)" "Trop d'INCLUDE imbriqués"
|
||||
TRANSLATE "Parse error" "Erreur d'analyse"
|
||||
TRANSLATE "Can't compute trigger" "Impossible de calculer le déclenchement"
|
||||
TRANSLATE "Too many nested IFs" "Trop de IF imbriqués"
|
||||
TRANSLATE "ELSE with no matching IF" "ELSE sans IF correspondant"
|
||||
TRANSLATE "ENDIF with no matching IF" "ENDIF sans IF correspondant"
|
||||
TRANSLATE "Can't OMIT every weekday" "Impossible d'omettre (OMIT) tous les jours"
|
||||
TRANSLATE "Extraneous token(s) on line" "Elément(s) étranger(s) sur la ligne"
|
||||
TRANSLATE "POP-OMIT-CONTEXT without matching PUSH-OMIT-CONTEXT" "POP-OMIT-CONTEXT sans PUSH-OMIT-CONTEXT correspondant"
|
||||
TRANSLATE "RUN disabled" "RUN déactivé"
|
||||
TRANSLATE "Domain error" "Erreur de domaine"
|
||||
TRANSLATE "Invalid identifier" "Identificateur invalide"
|
||||
TRANSLATE "Too many recursive function calls" "Trop d'appels de fonctions récursives"
|
||||
TRANSLATE "Cannot modify system variable" "Impossible de modifier une variable système"
|
||||
TRANSLATE "C library function can't represent date/time" "Fonction de la librairie C ne peut représenter la date/l'heure"
|
||||
TRANSLATE "Attempt to redefine built-in function" "Tentative de redéfinition d'une fonction intrinsèque"
|
||||
TRANSLATE "Can't nest function definition in expression" "Impossible d'imbriquer une définition de fonction dans une expression"
|
||||
TRANSLATE "Must fully specify date to use repeat factor" "Pour utiliser le facteur de répétition la date doit être spécifiée au complet"
|
||||
TRANSLATE "Year specified twice" "Année spécifiée deux fois"
|
||||
TRANSLATE "Month specified twice" "Mois spécifié deux fois"
|
||||
TRANSLATE "Day specified twice" "Jour spécifié deux fois"
|
||||
TRANSLATE "Unknown token" "Elément inconnu"
|
||||
TRANSLATE "Must specify month in OMIT command" "Mois doit être spécifiés dans commande OMIT"
|
||||
TRANSLATE "Too many full OMITs (max. 1000)" "Trop de OMITs complets"
|
||||
TRANSLATE "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT" "Attention: PUSH-OMIT-CONTEXT sans POP-OMIT-CONTEXT correspondant"
|
||||
TRANSLATE "Error reading" "Erreur à la lecture du fichier"
|
||||
TRANSLATE "Expecting end-of-line" "Fin de ligne attendue"
|
||||
TRANSLATE "Invalid Hebrew date" "Date hébreuse invalide"
|
||||
TRANSLATE "iif(): odd number of arguments required" "IIF demande nombre d'arguments impair"
|
||||
TRANSLATE "Warning: Missing ENDIF" "Attention: ENDIF manquant"
|
||||
TRANSLATE "Expecting comma" "Virgule attendue"
|
||||
TRANSLATE "Weekday specified twice" "Jour de la semaine spécifié deux fois"
|
||||
TRANSLATE "Only use one of BEFORE, AFTER or SKIP" "Utiliser un seul parmi BEFORE, AFTER ou SKIP"
|
||||
TRANSLATE "Can't nest MSG, MSF, RUN, etc. in expression" "Impossible d'imbriquer MSG, MSF, RUN, etc. dans une expression"
|
||||
TRANSLATE "Repeat value specified twice" "Valeur de répétition spécifiée deux fois"
|
||||
TRANSLATE "Delta value specified twice" "Valeur delta spécifiée deux fois"
|
||||
TRANSLATE "Back value specified twice" "Valeur de retour spécifiée deux fois"
|
||||
TRANSLATE "ONCE keyword used twice. (Hah.)" "Mot-clé ONCE utilisé deux fois. (Hah.)"
|
||||
TRANSLATE "Expecting time after AT" "Heure attendue après AT"
|
||||
TRANSLATE "THROUGH/UNTIL keyword used twice" "Mot-clé THROUGH/UNTIL utilisé deux fois"
|
||||
TRANSLATE "Incomplete date specification" "Spécification de date incomplète"
|
||||
TRANSLATE "FROM/SCANFROM keyword used twice" "Mot-clé FROM/SCANFROM utilisé deux fois"
|
||||
TRANSLATE "Variable" "Variable"
|
||||
TRANSLATE "Value" "Valeur"
|
||||
TRANSLATE "*UNDEFINED*" "*NON-DEFINI*"
|
||||
TRANSLATE "Entering UserFN" "Entrée dans UserFN"
|
||||
TRANSLATE "Leaving UserFN" "Sortie de UserFN"
|
||||
TRANSLATE "Expired" "Expiré"
|
||||
TRANSLATE "fork() failed - can't do queued reminders" "fork() échoué - impossible de faire les appels en queue"
|
||||
TRANSLATE "Can't access file" "Impossible d'accéder au fichier"
|
||||
TRANSLATE "Illegal system date: Year is less than %d\n" "Date système illégale: Année est inférieure à %d\n"
|
||||
TRANSLATE "Unknown debug flag '%c'\n" "Option de déverminage inconnue '%c'\n"
|
||||
TRANSLATE "Unknown option '%c'\n" "Option inconnue '%c'\n"
|
||||
TRANSLATE "Unknown user '%s'\n" "Usager inconnu '%s'\n"
|
||||
TRANSLATE "Could not change gid to %d\n" "Impossible de changer gid pour %d\n"
|
||||
TRANSLATE "Could not change uid to %d\n" "Impossible de changer uid pour %d\n"
|
||||
TRANSLATE "Out of memory for environment\n" "Manque de mémoire pour environnement\n"
|
||||
TRANSLATE "Missing '=' sign" "Signe '=' manquant"
|
||||
TRANSLATE "Missing variable name" "Nom de variable absent"
|
||||
TRANSLATE "Missing expression" "Expression absente"
|
||||
TRANSLATE "%d reminder(s) queued for later today.\n" "%d rappel(s) en file pour aujourd'hui.\n"
|
||||
TRANSLATE "Expecting number" "Nombre attendu"
|
||||
TRANSLATE "Undefined WARN function" "Fonction illégale après WARN"
|
||||
TRANSLATE "Can't convert between time zones" "Impossible de convertir entre les fuseaux horaires"
|
||||
TRANSLATE "No files matching *.rem" "Aucun fichier correspondant à *.rem"
|
||||
TRANSLATE "String too long" "Chaîne trop longue"
|
||||
TRANSLATE "Time specified twice" "Heure spécifiée deux fois"
|
||||
TRANSLATE "Cannot specify DURATION without specifying AT" "Impossible de spécifier DURATION sans spécifier AT"
|
||||
TRANSLATE "Expecting weekday name" "Nom du jour de la semaine attendu"
|
||||
TRANSLATE "Duplicate argument name" "Nom de l'argument en double"
|
||||
TRANSLATE "Expression evaluation is disabled" "L'évaluation de l'expression est désactivée"
|
||||
TRANSLATE "Time limit for expression evaluation exceeded" "Délai d'évaluation de l'expression dépassé"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 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,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 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,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 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ì"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 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,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 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"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# This file is derived from a translation by Jerzy Sobczyk
|
||||
|
||||
TRANSLATE "LANGID" "pl"
|
||||
|
||||
SET $Sunday "Niedziela"
|
||||
SET $Monday "Poniedziałek"
|
||||
SET $Tuesday "Wtorek"
|
||||
@@ -67,3 +69,104 @@ FSET subst_1past(diff) iif(diff/60==0, subst_1min(diff%60), diff%60==0, subst_1h
|
||||
|
||||
FSET subst_1min(m) m + " " + $Minute + subst_pl_plu(m)
|
||||
FSET subst_1h(h) h + " " + $Hour + subst_pl_plu(h)
|
||||
|
||||
TRANSLATE "Ok" "OK"
|
||||
TRANSLATE "Missing ']'" "Brakujący ']'"
|
||||
TRANSLATE "Missing quote" "Brakujący nawias"
|
||||
TRANSLATE "Expression too complex" "Zbyt skomplikowane wyrażenie"
|
||||
TRANSLATE "Missing ')'" "Brakujący ')'"
|
||||
TRANSLATE "Undefined function" "Nie zdefiniowana funkcja"
|
||||
TRANSLATE "Illegal character" "Nielegalny znak"
|
||||
TRANSLATE "Expecting binary operator" "Spodziewany operator binarny"
|
||||
TRANSLATE "Out of memory" "Brak pamięci"
|
||||
TRANSLATE "Ill-formed number" "Niepoprawny numer"
|
||||
TRANSLATE "Can't coerce" "Niemożliwa konwersja"
|
||||
TRANSLATE "Type mismatch" "Błąd typu"
|
||||
TRANSLATE "Date overflow" "Nadmiar daty"
|
||||
TRANSLATE "Division by zero" "Dzielenie przez zero"
|
||||
TRANSLATE "Undefined variable" "Niezdefiniowana zmienna"
|
||||
TRANSLATE "Unexpected end of line" "Niespodziewany koniec linii"
|
||||
TRANSLATE "Unexpected end of file" "Niespodziewany koniec pliku"
|
||||
TRANSLATE "I/O error" "Błąd wejscia/wyjscia"
|
||||
TRANSLATE "Internal error" "Błąd wewnętrzny"
|
||||
TRANSLATE "Bad date specification" "Zła specyfikacja daty"
|
||||
TRANSLATE "Not enough arguments" "Za mało argumentów"
|
||||
TRANSLATE "Too many arguments" "Za dużo argumentów"
|
||||
TRANSLATE "Ill-formed time" "Nieprawidłowy czas"
|
||||
TRANSLATE "Number too high" "Liczba za duża"
|
||||
TRANSLATE "Number too low" "Liczba za mała"
|
||||
TRANSLATE "Can't open file" "Nie mogę otworzyć pliku"
|
||||
TRANSLATE "INCLUDE nested too deeply (max. 9)" "Zbyt zagnieżdżone INCLUDE"
|
||||
TRANSLATE "Parse error" "Błąd składniowy"
|
||||
TRANSLATE "Can't compute trigger" "Nie mogę obliczyć przypomnienia"
|
||||
TRANSLATE "Too many nested IFs" "Zbyt zagnieżdżone IF"
|
||||
TRANSLATE "ELSE with no matching IF" "ELSE bez IF do pary"
|
||||
TRANSLATE "ENDIF with no matching IF" "ENDIF bez IF do pary"
|
||||
TRANSLATE "Can't OMIT every weekday" "Nie mogę ominąć (OMIT) wszystkich dni"
|
||||
TRANSLATE "Extraneous token(s) on line" "Niespodziewany wyraz w lini"
|
||||
TRANSLATE "POP-OMIT-CONTEXT without matching PUSH-OMIT-CONTEXT" "POP-OMIT-CONTEXT bez PUSH-OMIT-CONTEXT"
|
||||
TRANSLATE "RUN disabled" "Komenda RUN zablokowana"
|
||||
TRANSLATE "Domain error" "Błąd dziedziny"
|
||||
TRANSLATE "Invalid identifier" "Niepoprawny identyfikator"
|
||||
TRANSLATE "Too many recursive function calls" "Wykryto rekursywne wywołanie funkcji"
|
||||
TRANSLATE "Cannot modify system variable" "Nie mogę zmienić zmiennej systemowej"
|
||||
TRANSLATE "C library function can't represent date/time" "Funkcja biblioteki C nie może reprezentowac daty/czasu"
|
||||
TRANSLATE "Attempt to redefine built-in function" "Próba redefinicji funkcji wbudowanej"
|
||||
TRANSLATE "Can't nest function definition in expression" "Nie wolno zagnieżdżać definicji funkcji w wyrażeniu"
|
||||
TRANSLATE "Must fully specify date to use repeat factor" "Aby użyc powtórzenia trzeba w pełni wyspecyfikować datę"
|
||||
TRANSLATE "Year specified twice" "Rok podany dwókrotnie"
|
||||
TRANSLATE "Month specified twice" "Miesiąc podany dwókrotnie"
|
||||
TRANSLATE "Day specified twice" "Dzień podany dwókrotnie"
|
||||
TRANSLATE "Unknown token" "Nieznane słowo"
|
||||
TRANSLATE "Must specify month in OMIT command" "W komendzie OMIT trzeba podać miesiąc"
|
||||
TRANSLATE "Too many full OMITs (max. 1000)" "Za dużo pełnych komend OMIT"
|
||||
TRANSLATE "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT" "Ostrzeżenie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT"
|
||||
TRANSLATE "Error reading" "Błąd odczytu pliku"
|
||||
TRANSLATE "Expecting end-of-line" "Oczekiwany koniec linii"
|
||||
TRANSLATE "Invalid Hebrew date" "Błędna data hebrajska"
|
||||
TRANSLATE "iif(): odd number of arguments required" "IIF wymaga nieparzystej liczby argumentów"
|
||||
TRANSLATE "Warning: Missing ENDIF" "Ostrzeżenie: Brakujacy ENDIF"
|
||||
TRANSLATE "Expecting comma" "Oczekiwany przecinek"
|
||||
TRANSLATE "Weekday specified twice" "Dzień tygodnia podany dwókrotnie"
|
||||
TRANSLATE "Only use one of BEFORE, AFTER or SKIP" "Dozwolone tylko jedno z: BEFORE, AFTER i SKIP"
|
||||
TRANSLATE "Can't nest MSG, MSF, RUN, etc. in expression" "Nie można zagnieżdżać MSG, MSF, RUN, itp. w wyrażeniu"
|
||||
TRANSLATE "Repeat value specified twice" "Wartość powtorzenia podana dwókrotnie"
|
||||
TRANSLATE "Delta value specified twice" "Wartość różnicy podana dwókrotnie"
|
||||
TRANSLATE "Back value specified twice" "Wartość cofnięcia podana dwókrotnie"
|
||||
TRANSLATE "ONCE keyword used twice. (Hah.)" "Słowo ONCE użyte dwókrotnie."
|
||||
TRANSLATE "Expecting time after AT" "Po AT oczekiwany jest czas"
|
||||
TRANSLATE "THROUGH/UNTIL keyword used twice" "Słowo THROUGH/UNTIL użyte dwókrotnie"
|
||||
TRANSLATE "Incomplete date specification" "Niekompletna specyfikacja daty"
|
||||
TRANSLATE "FROM/SCANFROM keyword used twice" "Słowo FROM/SCANFROM użyte dwókrotnie"
|
||||
TRANSLATE "Variable" "Zmienna"
|
||||
TRANSLATE "Value" "Wartość"
|
||||
TRANSLATE "*UNDEFINED*" "*NIE ZDEFINIOWANE*"
|
||||
TRANSLATE "Entering UserFN" "Początek UserFN"
|
||||
TRANSLATE "Leaving UserFN" "Koniec UserFN"
|
||||
TRANSLATE "Expired" "Przemineło"
|
||||
TRANSLATE "fork() failed - can't do queued reminders" "Niepowodzenie w funkcji fork() - nie mogę kolejkować przypomnień"
|
||||
TRANSLATE "Can't access file" "Nie ma dostępu do pliku"
|
||||
TRANSLATE "Illegal system date: Year is less than %d\n" "Błędna data systemowa: Rok mniejszy niż %d\n"
|
||||
TRANSLATE "Unknown debug flag '%c'\n" "Nieznana flaga odpluskwiania '%c'\n"
|
||||
TRANSLATE "Unknown option '%c'\n" "Nieznana opcja '%c'\n"
|
||||
TRANSLATE "Unknown user '%s'\n" "Nieznany użytkownik '%s'\n"
|
||||
TRANSLATE "Could not change gid to %d\n" "Nie mogę zmienić gid na %d\n"
|
||||
TRANSLATE "Could not change uid to %d\n" "Nie mogę zmienić uid na %d\n"
|
||||
TRANSLATE "Out of memory for environment\n" "Brak pamięci na zmienne środowiska\n"
|
||||
TRANSLATE "Missing '=' sign" "Brak znaku '='"
|
||||
TRANSLATE "Missing variable name" "Brak nazwy zmiennej"
|
||||
TRANSLATE "Missing expression" "Brak wyrażenia"
|
||||
TRANSLATE "Remind: '-i' option: %s\n" "Remind: '-i' option: %s\n"
|
||||
TRANSLATE "No reminders." "Brak przypomnień."
|
||||
TRANSLATE "%d reminder(s) queued for later today.\n" "%d Przypomnienia zakolejkowane na później.\n"
|
||||
TRANSLATE "Expecting number" "Spodziewana liczba"
|
||||
TRANSLATE "Undefined WARN function" "Nielegalna funkcja w klauzuli WARN:"
|
||||
TRANSLATE "Can't convert between time zones" "Nie można konwertować między strefami czasowymi"
|
||||
TRANSLATE "No files matching *.rem" "Brak dopasowania plików *.rem"
|
||||
TRANSLATE "String too long" "Ciąg za długo:"
|
||||
TRANSLATE "Time specified twice" "Czas określony dwukrotnie:"
|
||||
TRANSLATE "Cannot specify DURATION without specifying AT" "Nie można określić DURATION bez AT"
|
||||
TRANSLATE "Expecting weekday name" "Oczekiwana nazwa dnia tygodnia"
|
||||
TRANSLATE "Duplicate argument name" "Zduplikowana nazwa argumentu"
|
||||
TRANSLATE "Expression evaluation is disabled" "Ocena wyrażeń jest wyłączona"
|
||||
TRANSLATE "Time limit for expression evaluation exceeded" "Przekroczono limit czasu na ocenę wyrażenia"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# This file is derived from a translation by Marco Paganini
|
||||
|
||||
TRANSLATE "LANGID" "pt"
|
||||
|
||||
SET $Sunday "domingo"
|
||||
SET $Monday "segunda"
|
||||
SET $Tuesday "terça"
|
||||
@@ -67,3 +69,103 @@ FSET subst_1(a, d, t) iif(t==now(), $Now, t>now(), "em " + subst_1help(t-now()),
|
||||
FSET subst_1help(diff) iif(diff/60==0, subst_mplu(diff%60), diff%60==0, subst_hplu(diff/60), subst_hplu(diff/60) + " " + $And + " " + subst_mplu(diff%60))
|
||||
FSET subst_mplu(m) iif(m==1, "1 " + $Minute, m + " " + $Minute + $Mplu)
|
||||
FSET subst_hplu(h) iif(h==1, "1 " + $Hour, h + " " + $Hour + $Hplu)
|
||||
|
||||
TRANSLATE "Missing ']'" "Falta um ']'"
|
||||
TRANSLATE "Missing quote" "Falta uma aspa"
|
||||
TRANSLATE "Expression too complex" "Expressao muito complexa"
|
||||
TRANSLATE "Missing ')'" "Falta um ')'"
|
||||
TRANSLATE "Undefined function" "Funcao nao definida"
|
||||
TRANSLATE "Illegal character" "Caracter ilegal"
|
||||
TRANSLATE "Expecting binary operator" "Esperando operador binario"
|
||||
TRANSLATE "Out of memory" "Sem memoria"
|
||||
TRANSLATE "Ill-formed number" "Numero mal-formado"
|
||||
TRANSLATE "Can't coerce" "Nao consigo fazer 'coerce'"
|
||||
TRANSLATE "Type mismatch" "Type mismatch"
|
||||
TRANSLATE "Date overflow" "Overflow na data"
|
||||
TRANSLATE "Division by zero" "Divisao por zero"
|
||||
TRANSLATE "Undefined variable" "Variavel nao definida"
|
||||
TRANSLATE "Unexpected end of line" "Fim da linha nao esperado"
|
||||
TRANSLATE "Unexpected end of file" "Fim de arquivo nao esperado"
|
||||
TRANSLATE "I/O error" "Erro de I/O"
|
||||
TRANSLATE "Internal error" "Erro interno"
|
||||
TRANSLATE "Bad date specification" "Especificacao de data invalida"
|
||||
TRANSLATE "Not enough arguments" "Argumentos insuficientes"
|
||||
TRANSLATE "Too many arguments" "Argumentos em excesso"
|
||||
TRANSLATE "Ill-formed time" "Hora mal-formada"
|
||||
TRANSLATE "Number too high" "Numero muito grande"
|
||||
TRANSLATE "Number too low" "Numero muito pequeno"
|
||||
TRANSLATE "Can't open file" "Nao consigo abrir o arquivo"
|
||||
TRANSLATE "INCLUDE nested too deeply (max. 9)" "Ninho de INCLUDEs muito profundo"
|
||||
TRANSLATE "Parse error" "Erro de parsing"
|
||||
TRANSLATE "Can't compute trigger" "Nao consigo computar o 'trigger'"
|
||||
TRANSLATE "Too many nested IFs" "Muitos IFs aninhados"
|
||||
TRANSLATE "ELSE with no matching IF" "ELSE sem o IF correspondente"
|
||||
TRANSLATE "ENDIF with no matching IF" "ENDIF sem o IF correspondente"
|
||||
TRANSLATE "Can't OMIT every weekday" "Nao se pode usar OMIT para todos os dias da semana"
|
||||
TRANSLATE "Extraneous token(s) on line" "Token nao reconhecido na linha"
|
||||
TRANSLATE "POP-OMIT-CONTEXT without matching PUSH-OMIT-CONTEXT" "POP-OMIT-CONTEXT sem PUSH-OMIT-CONTEXT correspondente"
|
||||
TRANSLATE "RUN disabled" "RUN desabilitado"
|
||||
TRANSLATE "Domain error" "Erro de dominio"
|
||||
TRANSLATE "Invalid identifier" "Identificados invalido"
|
||||
TRANSLATE "Too many recursive function calls" "Muitas chamadas de função recursiva"
|
||||
TRANSLATE "Cannot modify system variable" "Nao posso modificar variavel de sistema"
|
||||
TRANSLATE "C library function can't represent date/time" "Funcao da biblioteca C nao pode representar data/hora"
|
||||
TRANSLATE "Attempt to redefine built-in function" "Tentativa de redefinir funcao interna"
|
||||
TRANSLATE "Can't nest function definition in expression" "Nao e' possivel aninhar definicao de funcao em expressao"
|
||||
TRANSLATE "Must fully specify date to use repeat factor" "Data deve ser completamente especificada para usar o fator de REPEAT"
|
||||
TRANSLATE "Year specified twice" "Ano especificado duas vezes"
|
||||
TRANSLATE "Month specified twice" "Mes especificado duas vezes"
|
||||
TRANSLATE "Day specified twice" "Dia especificado duas vezes"
|
||||
TRANSLATE "Unknown token" "Token desconhecido"
|
||||
TRANSLATE "Must specify month in OMIT command" "O mes deve ser especificados no comando OMIT"
|
||||
TRANSLATE "Too many full OMITs (max. 1000)" "Muitos OMITs full"
|
||||
TRANSLATE "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT" "Aviso: PUSH-OMIT-CONTEXT sem POP-OMIT-CONTEXT correspondente"
|
||||
TRANSLATE "Error reading" "Erro na leitura do arquivo"
|
||||
TRANSLATE "Expecting end-of-line" "Aguardando fim do arquivo"
|
||||
TRANSLATE "Invalid Hebrew date" "Data hebraica invalida"
|
||||
TRANSLATE "iif(): odd number of arguments required" "IIF necessita de numero impar de argumentos"
|
||||
TRANSLATE "Warning: Missing ENDIF" "Warning: ENDIF faltando"
|
||||
TRANSLATE "Expecting comma" "Esperando virgula"
|
||||
TRANSLATE "Weekday specified twice" "Dia da semana especificado duas vezes"
|
||||
TRANSLATE "Only use one of BEFORE, AFTER or SKIP" "Use apenas um de BEFORE, AFTER ou SKIP"
|
||||
TRANSLATE "Can't nest MSG, MSF, RUN, etc. in expression" "Nao e possivel aninhar MSG, MSF, RUN, etc. em expressoes"
|
||||
TRANSLATE "Repeat value specified twice" "Valor de Repeat especificado duas vezes"
|
||||
TRANSLATE "Delta value specified twice" "Valor de Delta especificado duas vezes"
|
||||
TRANSLATE "Back value specified twice" "Valor de Back especificado duas vezes"
|
||||
TRANSLATE "ONCE keyword used twice. (Hah.)" "ONCE usado duas vezes (Eheheh)"
|
||||
TRANSLATE "Expecting time after AT" "Esperando hora apos AT"
|
||||
TRANSLATE "THROUGH/UNTIL keyword used twice" "Keyword THROUGH/UNTIL usada duas vezes"
|
||||
TRANSLATE "Incomplete date specification" "Especificacao de data incompleta"
|
||||
TRANSLATE "FROM/SCANFROM keyword used twice" "Keyword FROM/SCANFROM usada duas vezes"
|
||||
TRANSLATE "Variable" "Variavel"
|
||||
TRANSLATE "Value" "Valor"
|
||||
TRANSLATE "*UNDEFINED*" "*INDEFINIDO*"
|
||||
TRANSLATE "Entering UserFN" "Entrando UserFN"
|
||||
TRANSLATE "Leaving UserFN" "Saindo UserFN"
|
||||
TRANSLATE "Expired" "Expirou"
|
||||
TRANSLATE "fork() failed - can't do queued reminders" "fork() falhou - Nao posso processar compromissos na fila"
|
||||
TRANSLATE "Can't access file" "Nao consigo acessar o arquivo"
|
||||
TRANSLATE "Illegal system date: Year is less than %d\n" "Data do sistema ilegal: Ano e menor que %d\n"
|
||||
TRANSLATE "Unknown debug flag '%c'\n" "Flag de debug desconhecido '%c'\n"
|
||||
TRANSLATE "Unknown option '%c'\n" "Opcao desconhecida '%c'\n"
|
||||
TRANSLATE "Unknown user '%s'\n" "Usuario desconhecido '%s'\n"
|
||||
TRANSLATE "Could not change gid to %d\n" "Nao consigo mudar gid para %d\n"
|
||||
TRANSLATE "Could not change uid to %d\n" "Nao consigo mudar uid para %d\n"
|
||||
TRANSLATE "Out of memory for environment\n" "Sem memoria para o environment\n"
|
||||
TRANSLATE "Missing '=' sign" "Falta o sinal de '='"
|
||||
TRANSLATE "Missing variable name" "Falta o nome da variavel"
|
||||
TRANSLATE "Missing expression" "Falta a expressao"
|
||||
TRANSLATE "Remind: '-i' option: %s\n" "Remind: '-i' opcao: %s\n"
|
||||
TRANSLATE "No reminders." "Sem compromissos."
|
||||
TRANSLATE "%d reminder(s) queued for later today.\n" "%d compromisso(s) colocados na fila para mais tarde.\n"
|
||||
TRANSLATE "Expecting number" "Esperando numero"
|
||||
TRANSLATE "Undefined WARN function" "Funcao ilegal na clausula WARN"
|
||||
TRANSLATE "Can't convert between time zones" "Não consigo converter entre fusos horários"
|
||||
TRANSLATE "No files matching *.rem" "Nenhum arquivo correspondente *.rem"
|
||||
TRANSLATE "String too long" "String muito longa"
|
||||
TRANSLATE "Time specified twice" "Tempo especificado duas vezes"
|
||||
TRANSLATE "Cannot specify DURATION without specifying AT" "Não é possível especificar DURATION sem especificar AT"
|
||||
TRANSLATE "Expecting weekday name" "Esperando nome do dia da semana"
|
||||
TRANSLATE "Duplicate argument name" "Nome de argumento duplicado"
|
||||
TRANSLATE "Expression evaluation is disabled" "A avaliação da expressão está desabilitada"
|
||||
TRANSLATE "Time limit for expression evaluation exceeded" "Limite de tempo para avaliação de expressão excedido"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# REMIND is Copyright (C) 1992-2024 by Dianne Skoll
|
||||
# This file is derived from a translation by Liviu Daia
|
||||
|
||||
TRANSLATE "LANGID" "ro"
|
||||
|
||||
SET $Sunday "Duminică"
|
||||
SET $Monday "Luni"
|
||||
SET $Tuesday "Marți"
|
||||
|
||||
@@ -7,8 +7,8 @@ IF $CalMode || $PsCal
|
||||
REM [moondate(2)] SPECIAL MOON 2 -1 -1 [moontime(2)]
|
||||
REM [moondate(3)] SPECIAL MOON 3 -1 -1 [moontime(3)]
|
||||
ELSE
|
||||
REM NOQUEUE [moondatetime(0)] MSG New Moon (%2)
|
||||
REM NOQUEUE [moondatetime(1)] MSG First Quarter (%2)
|
||||
REM NOQUEUE [moondatetime(2)] MSG Full Moon (%2)
|
||||
REM NOQUEUE [moondatetime(3)] MSG Last Quarter (%2)
|
||||
REM NOQUEUE [moondatetime(0)] MSG %(New Moon) (%2)
|
||||
REM NOQUEUE [moondatetime(1)] MSG %(First Quarter) (%2)
|
||||
REM NOQUEUE [moondatetime(2)] MSG %(Full Moon) (%2)
|
||||
REM NOQUEUE [moondatetime(3)] MSG %(Last Quarter) (%2)
|
||||
ENDIF
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
|
||||
IF $LatDeg >= 0
|
||||
# Northern Hemisphere
|
||||
REM NOQUEUE [soleq(0)] MSG %"Vernal Equinox%" is %3.
|
||||
REM NOQUEUE [soleq(1)] MSG %"Summer Solstice%" is %3.
|
||||
REM NOQUEUE [soleq(2)] MSG %"Autumnal Equinox%" is %3.
|
||||
REM NOQUEUE [soleq(3)] MSG %"Winter Solstice%" is %3.
|
||||
REM NOQUEUE [soleq(0)] MSG %"%(Vernal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(1)] MSG %"%(Summer Solstice)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(2)] MSG %"%(Autumnal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(3)] MSG %"%(Winter Solstice)%" [$Is] %3.
|
||||
ELSE
|
||||
# Southern Hemisphere
|
||||
REM NOQUEUE [soleq(0)] MSG %"Autumnal Equinox%" is %3.
|
||||
REM NOQUEUE [soleq(1)] MSG %"Winter Solstice%" is %3.
|
||||
REM NOQUEUE [soleq(2)] MSG %"Vernal Equinox%" is %3.
|
||||
REM NOQUEUE [soleq(3)] MSG %"Summer Solstice%" is %3.
|
||||
REM NOQUEUE [soleq(0)] MSG %"%(Autumnal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(1)] MSG %"%(Winter Solstice)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(2)] MSG %"%(Vernal Equinox)%" [$Is] %3.
|
||||
REM NOQUEUE [soleq(3)] MSG %"%(Summer Solstice)%" [$Is] %3.
|
||||
ENDIF
|
||||
|
||||
7
include/sun.rem
Normal file
7
include/sun.rem
Normal file
@@ -0,0 +1,7 @@
|
||||
# Sunrise and sunset
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
IF !$CalMode && !$PsCal
|
||||
REM NOQUEUE AT [sunrise()] MSG %"%"%(Sunrise) %! %2.
|
||||
REM NOQUEUE AT [sunset()] MSG %"%"%(Sunset) %! %2.
|
||||
ENDIF
|
||||
@@ -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
|
||||
@@ -664,6 +686,10 @@ The number of days in the following month.
|
||||
The year of the following month. (The same as \fByear\fR unless the
|
||||
current month is December.)
|
||||
.TP
|
||||
.B translations \fR{\fIobject\fR}
|
||||
A complete dump of the Remind translation table. In output for multiple
|
||||
months, the translation table is included only with the first month.
|
||||
.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
|
||||
|
||||
249
man/remind.1.in
249
man/remind.1.in
@@ -14,11 +14,12 @@ If \fIfilename\fR is specified as a single dash '-', then \fBRemind\fR
|
||||
takes its input from standard input.
|
||||
|
||||
.PP
|
||||
If \fIfilename\fR happens to
|
||||
be a directory rather than a plain file, then \fBRemind\fR reads all of
|
||||
the files in that directory that match the pattern "*.rem". The files
|
||||
are read in sorted order; the sort order may depend on your locale, but
|
||||
should match the sort order used by the shell to expand "*.rem".
|
||||
If \fIfilename\fR happens to be a directory rather than a plain file,
|
||||
then \fBRemind\fR reads all of the files (but not any subdirectories!)
|
||||
in that directory that match the pattern "*.rem". The files are read
|
||||
in sorted order; the sort order may depend on your locale, but should
|
||||
match the sort order used by the shell to expand "*.rem".
|
||||
|
||||
.PP
|
||||
\fBRemind\fR reads its files starting from the beginning to the end, or
|
||||
until it encounters a line whose sole content is "__EOF__" (without the quotes.)
|
||||
@@ -468,6 +469,20 @@ case-sensitive:
|
||||
The \fB\-\-version\fR option causes \fBRemind\fR to print its version number
|
||||
to standard output and then exit.
|
||||
.TP
|
||||
.B \-\-print-errs
|
||||
The \fB\-\-print-errs\fR option causes \fBRemind\fR to print all possible
|
||||
error messages to standard output and then exit. The messages are printed
|
||||
in a format suitable for the first argument of a TRANSLATE command. If
|
||||
you TRANSLATE the error messages, then \fBRemind\fR will use the translated
|
||||
versions when outputting error and warning messages.
|
||||
.RS
|
||||
.PP
|
||||
Note that if an untranslated message contains printf-style formatting
|
||||
sequences like "%s" or "%d", then the translated message \fImust\fR
|
||||
contain the same sequences in the same order, or \fBRemind\fR will
|
||||
ignore it and use the original untranslated message.
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-print-config-cmd
|
||||
This option causes \fBRemind\fR to print the exact \fB./configure\fR
|
||||
command that was used when \fBRemind\fR was built. You can use this
|
||||
@@ -1195,7 +1210,7 @@ The command:
|
||||
REM ... whatever ... ADDOMIT MSG Foo
|
||||
.fi
|
||||
.PP
|
||||
is identical in behaviour to the sequence:
|
||||
is identical in behavior to the sequence:
|
||||
.PP
|
||||
.nf
|
||||
REM ... whatever ... SATISFY 1
|
||||
@@ -1597,6 +1612,10 @@ is replaced with "\fIyear\fR", the year of the trigger date.
|
||||
.B %z
|
||||
is replaced with "\fIyy\fR", the last two digits of the year.
|
||||
.TP
|
||||
.B %(\fIany_text\fR\fB)
|
||||
is replaced with the lookup of \fIany_text\fR in the translation table.
|
||||
It is the equivalent of [_("any_text")] but is more convenient to type.
|
||||
.TP
|
||||
.B %_
|
||||
(percent-underscore) is replaced with a newline. You can use this to
|
||||
achieve multi-line reminders. Note that calendar back-ends vary in
|
||||
@@ -1905,30 +1924,30 @@ the first day of the month. The local \fBOMIT\fR keyword causes the
|
||||
Finally, the \fBAFTER\fR keyword will keep moving the reminder forward
|
||||
until it has passed any holidays specified with global \fBOMIT\fR
|
||||
commands.
|
||||
.SH THE DO AND INCLUDE COMMANDS
|
||||
.SH THE DO, INCLUDE AND SYSINCLUDE COMMANDS
|
||||
.PP
|
||||
\fBRemind\fR allows you to include other files in your reminder script,
|
||||
similar to the C preprocessor #include directive. For example, your
|
||||
system administrator may maintain a file of holidays or system-wide
|
||||
reminders. You can include these in your reminder script as follows:
|
||||
similar to the C preprocessor #include directive. For example, you
|
||||
might organize different reminders into different files like this:
|
||||
.PP
|
||||
.nf
|
||||
INCLUDE /usr/share/remind/holidays
|
||||
INCLUDE /usr/share/remind/reminders
|
||||
INCLUDE holidays.rem
|
||||
INCLUDE birthdays.rem
|
||||
INCLUDE "quote files with spaces.rem"
|
||||
.fi
|
||||
.PP
|
||||
(The actual pathnames vary from system to system - ask your system
|
||||
administrator.)
|
||||
.PP
|
||||
\fBINCLUDE\fR files can be nested up to a depth of 8.
|
||||
\fBINCLUDE\fR files can be nested up to a depth of 8. As shown above, if a
|
||||
filename has spaces in it (not recommended!) you can use double-quotes
|
||||
around the filename.
|
||||
.PP
|
||||
If you specify a filename of "-" in the \fBINCLUDE\fR command, \fBRemind\fR
|
||||
will begin reading from standard input.
|
||||
.PP
|
||||
If you specify a \fIdirectory\fR as the argument to \fBINCLUDE\fR, then
|
||||
\fBRemind\fR will process all files in that directory that match the shell
|
||||
pattern "*.rem". The files are processed in sorted order; the sort order
|
||||
matches that used by the shell when it expands "*.rem".
|
||||
If you specify a \fIdirectory\fR as the argument to \fBINCLUDE\fR,
|
||||
then \fBRemind\fR will process all files (but not subdirectories!) in
|
||||
that directory that match the shell pattern "*.rem". The files are
|
||||
processed in sorted order; the sort order matches that used by the
|
||||
shell when it expands "*.rem".
|
||||
.PP
|
||||
Note that the file specified by an \fBINCLUDE\fR command is interpreted
|
||||
relative to the \fIcurrent working directory of the Remind process\fR.
|
||||
@@ -1961,6 +1980,11 @@ symbolic link itself, \fBDO\fR will fail. \fBRemind\fR does \fInot\fR
|
||||
resolve the real path of symbolic links, so you should avoid using
|
||||
symbolic links to files.
|
||||
.PP
|
||||
The \fBSYSINCLUDE\fR command is similar to \fBDO\fR, but it looks for
|
||||
relative pathnames under the system directory containing standard reminder
|
||||
scripts. For this version of \fBRemind\fR, the system directory is
|
||||
"@prefix@/share/remind".
|
||||
.PP
|
||||
.SH THE RUN COMMAND
|
||||
.PP
|
||||
If you include other files in your reminder script, you may not always
|
||||
@@ -2037,7 +2061,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).
|
||||
@@ -2765,7 +2789,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
|
||||
@@ -3016,6 +3040,41 @@ an underscore and an identifier naming the argument.
|
||||
.PP
|
||||
The built-in functions are:
|
||||
.TP
|
||||
.B _(s_message)
|
||||
Returns the translation table entry for \fImessage\fR. If there is no
|
||||
such translation table entry, then returns \fImessage\fR unmodified.
|
||||
For example, consider this sequence:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
TRANSLATE "Goodbye" "Tot ziens"
|
||||
SET a _("Goodbye")
|
||||
.fi
|
||||
.PP
|
||||
After those two lines have been executed, the variable \fBa\fR will be
|
||||
set to "Tot ziens". See the section THE TRANSLATION TABLE for more
|
||||
information.
|
||||
.PP
|
||||
In the body of a reminder, the substitution sequence
|
||||
\fB%(\fItext\fR\fB)\fR is (almost) the equivalent of
|
||||
\fB[_("\fItext\fR\fB")]\fR. Therefore, the following reminders are
|
||||
almost equivalent:
|
||||
.PP
|
||||
.nf
|
||||
|
||||
REM MSG %(Goodbye)
|
||||
REM MSG [_("Goodbye")]
|
||||
.fi
|
||||
.PP
|
||||
The only difference is that if _("Goodbye") contains a \fB%\fR sign,
|
||||
then that result will be run through the substitution filter, whereas
|
||||
in the first reminder, it will not. That is because the second
|
||||
\fBREM\fR command performs expression pasting followed by a
|
||||
substitution filter pass, while the first one performs the translation
|
||||
as part of the substitution filter (and does not make a second
|
||||
substitution filter pass.)
|
||||
.RE
|
||||
.TP
|
||||
.B abs(i_num)
|
||||
Returns the absolute value of \fInum\fR.
|
||||
.TP
|
||||
@@ -3472,12 +3531,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 returnes "English". However, the expression
|
||||
\fB_("LANGID")\fR returns the two-character ISO 639 language code
|
||||
of any language pack in effect, assuming the language pack author has
|
||||
written the localization correctly!
|
||||
.TP
|
||||
.B localtoutc(q_datetime)
|
||||
Given a \fBDATETIME\fR object interpreted in the local time zone, return
|
||||
@@ -3967,7 +4027,10 @@ output is not going to a TTY.
|
||||
.TP
|
||||
.B strlen(s_str)
|
||||
Returns the length of \fIstr\fR. If the length of \fIstr\fR is too large
|
||||
to represent as an integer, emits a "Number too high" error.
|
||||
to represent as an integer, emits a "Number too high" error. Note that
|
||||
\fBstrlen\fR returns the number of \fIbytes\fR in the string, not the
|
||||
number of \fIcharacters\fR. These numbers are the same for ASCII strings,
|
||||
but may be different for UTF-8 strings.
|
||||
.TP
|
||||
.B substr(s_str, i_start [,i_end])
|
||||
Returns a \fBSTRING\fR consisting of all characters in \fIstr\fR from
|
||||
@@ -5521,22 +5584,13 @@ error messages. For an example of this, define the following:
|
||||
.PP
|
||||
.SH COMPILE-TIME SUPPORT FOR OTHER LANGUAGES
|
||||
.PP
|
||||
Your version of \fBRemind\fR may have been compiled to support a
|
||||
language other than English. This support may or may not be complete -
|
||||
for example, all error and usage messages may still be in English.
|
||||
However, at a minimum, non-English versions of \fBRemind\fR will
|
||||
output names of months and weekdays in the selected language. Also,
|
||||
the substitution mechanism will substitute constructs suitable for the
|
||||
selected language rather than for English.
|
||||
.PP
|
||||
Note that a non-English version of \fBRemind\fR will accept \fIonly\fR
|
||||
English names of weekdays and months in a reminder script.
|
||||
Remind used to support compile-time localization to other languages,
|
||||
but no longer does. All localization is now done at run-time.
|
||||
.PP
|
||||
.SH RUN-TIME SUPPORT FOR OTHER LANGUAGES
|
||||
.PP
|
||||
\fBRemind\fR has run-time support for other languages, and it is
|
||||
expected that compile-time support will be deprecated in favour of
|
||||
run-time support.
|
||||
\fBRemind\fR has run-time support for other languages, and
|
||||
compile-time support has been removed in favour of run-time support.
|
||||
.PP
|
||||
A number of system variables let you translate various phrases
|
||||
to other languages. These system variables are:
|
||||
@@ -5550,7 +5604,7 @@ day's name in your language. Strings must be valid UTF-8 strings.
|
||||
Set each of these system variables to a string representing the corresponding
|
||||
month's name in your language. Strings must be valid UTF-8 strings.
|
||||
.TP
|
||||
.B $Ago, $Am, $And, $At, $Hour, $Is, $Minute, $Now, $On, $Pm, $Was
|
||||
.B $Ago, $Am, $And, $At, $Hour, $Is, $Minute, $Now, $On, $Pm, $Today, $Tomorrow, $Was
|
||||
Set each of these system variables to the translation of the corresponding
|
||||
English word into your language. Note that \fB$Am\fR and \fB$Pm\fR should
|
||||
be the translations of "AM" and "PM" (morning and afternoon time indicators)
|
||||
@@ -5654,6 +5708,92 @@ If you use a \fB%{name}\fR sequence and the function \fBsubst_\fIname\fR is
|
||||
not defined or returns an error, then \fB%{name}\fR is replaced with the
|
||||
empty string.
|
||||
.PP
|
||||
.SH THE TRANSLATION TABLE
|
||||
.PP
|
||||
To assist with localizing reminder files, \fBRemind\fR maintains a
|
||||
table of translations. This is simple a lookup table that maps one
|
||||
string (the original string) to a new string (the translated string.)
|
||||
When \fBRemind\fR starts executing, the translation table is empty.
|
||||
.PP
|
||||
To add a message to the translation table, use the \fBTRANSLATE\fR
|
||||
command (which may be abbreviated to \fBTRANS\fR.) The \fBTRANSLATE\fR
|
||||
command must be followed by two quoted strings, separated from each
|
||||
other and from the command by whitespace. For example, a Dutch
|
||||
language file might contain something like this:
|
||||
.PP
|
||||
.nf
|
||||
TRANSLATE "New Moon" "Nieuwe maan"
|
||||
TRANSLATE "First Quarter" "Eerste kwartier"
|
||||
TRANSLATE "Full Moon" "Volle maan"
|
||||
TRANSLATE "Last Quarter" "Laatste kwartier"
|
||||
.fi
|
||||
.PP
|
||||
To actually use the translation table, make use of the \fB_\fR built-in
|
||||
function, as follows:
|
||||
.PP
|
||||
.nf
|
||||
REM NOQUEUE [moondatetime(0)] MSG [_("New Moon")] (%2)
|
||||
REM NOQUEUE [moondatetime(1)] MSG [_("First Quarter")] (%2)
|
||||
REM NOQUEUE [moondatetime(2)] MSG [_("Full Moon")] (%2)
|
||||
REM NOQUEUE [moondatetime(3)] MSG [_("Last Quarter")] (%2)
|
||||
.fi
|
||||
.PP
|
||||
By using \fBTRANSLATE\fR and \fB_\fR judiciously, you can make your
|
||||
reminder files easy to translate.
|
||||
.PP
|
||||
\fBTRANSLATE\fR has three additional forms: If it is followed
|
||||
by \fIone\fR quoted string instead of two, then \fBRemind\fR deletes the
|
||||
translation table entry for that string. If it is followed by
|
||||
the keyword \fBDUMP\fR, then \fBRemind\fR dumps all translation table entries
|
||||
to standard output. And if it is followed by \fBCLEAR\fR, then
|
||||
\fBRemind\fR deletes all of the translation table entries.
|
||||
.PP
|
||||
Note that if you \fBSET\fR various translation-related system
|
||||
variables such as \fB$Monday\fR, \fB$December\fR, \fB$Ago\fR, etc,
|
||||
then \fBRemind\fR \fIalso\fR makes a corresponding translation
|
||||
table entry automatically. This is done for all of the translation-related
|
||||
system variables \fIexcept for\fR \fB$Hplu\fR and \fB$Mplu\fR.
|
||||
.PP
|
||||
The converse applies too; creating a translation table for
|
||||
"December" automatically sets \fB$December\fR. And if you invoke
|
||||
\fBTRANSLATE CLEAR\fR, then all translation-related system variables
|
||||
are set to their default values as well.
|
||||
.PP
|
||||
The translation table always contains a special entry \fBLANGID\fR whose
|
||||
default value is \fBen\fR. Translators are encouraged to add a \fBLANGID\fR
|
||||
entry in their language files; the value should be the two-characters
|
||||
ISO 639 language code.
|
||||
.PP
|
||||
For example, if you write a translation file for the Dutch language,
|
||||
add this line:
|
||||
.PP
|
||||
.nf
|
||||
TRANSLATE "LANGID" "nl"
|
||||
.fi
|
||||
.PP
|
||||
Scripts can use \fB_("LANGID")\fR to query the translation language that is
|
||||
in effect.
|
||||
.PP
|
||||
The \fB_()\fR function uses the following procedure to obtain the translation
|
||||
for a string:
|
||||
.RS
|
||||
.TP
|
||||
1
|
||||
Look for an exact match. If found, return.
|
||||
.TP
|
||||
2
|
||||
If the original string had an upper-case letter, search for the
|
||||
all-lower-case equivalent. If found, make the first letter of the
|
||||
result upper-case and return.
|
||||
.TP
|
||||
3
|
||||
If the original string started with a lower-case letter, search
|
||||
for an equivalent whose first letter is upper-case and the rest lower-case.
|
||||
If found, make the first letter of the result lower-case and return.
|
||||
.TP
|
||||
4
|
||||
No translation was found. Return the original string.
|
||||
.RE
|
||||
.SH LANGUAGE PACKS
|
||||
.PP
|
||||
\fBRemind\fR ships with a number of language packs, which are simply reminder
|
||||
@@ -5668,14 +5808,14 @@ To use a language pack (in this example, de.rem), simply place this at
|
||||
the top of your reminders file:
|
||||
.PP
|
||||
.nf
|
||||
INCLUDE [$SysInclude]/lang/de.rem
|
||||
SYSINCLUDE lang/de.rem
|
||||
.fi
|
||||
.PP
|
||||
If you want \fBRemind\fR to try to find the language pack appropriate
|
||||
for your locale settings, use:
|
||||
.PP
|
||||
.nf
|
||||
INCLUDE [$SysInclude]/lang/auto.rem
|
||||
SYSINCLUDE lang/auto.rem
|
||||
.fi
|
||||
.PP
|
||||
You are encouraged to study the language packs to see how to translate
|
||||
@@ -6187,16 +6327,15 @@ Do not hard-code the above directory in your reminder files. Instead,
|
||||
use the value of the $SysInclude system variable.
|
||||
.SH AUTHOR
|
||||
.PP
|
||||
Dianne Skoll <dianne@skoll.ca> wrote \fBRemind\fR. The moon code
|
||||
was copied largely unmodified from "moontool" by John Walker. The
|
||||
sunrise and sunset functions use ideas from programs by Michael
|
||||
Schwartz and Marc T. Kaufman. The Hebrew calendar support was taken
|
||||
from "hdate" by Amos Shapir. OS/2 support was done by Darrel
|
||||
Hankerson, Russ Herman, and Norman Walsh. The supported
|
||||
languages and their translators are listed below. Languages marked
|
||||
"complete" support error messages and usage instructions in that
|
||||
language; all others only support the substitution filter mechanism
|
||||
and month/day names.
|
||||
Dianne Skoll <dianne@skoll.ca> wrote \fBRemind\fR. The moon code was
|
||||
copied largely unmodified from "moontool" by John Walker. The sunrise
|
||||
and sunset functions use ideas from programs by Michael Schwartz and
|
||||
Marc T. Kaufman. The Hebrew calendar support was taken from "hdate"
|
||||
by Amos Shapir. OS/2 support was done by Darrel Hankerson, Russ
|
||||
Herman, and Norman Walsh. The supported languages and their
|
||||
translators are listed below. Languages marked "complete" support
|
||||
error messages in that language; all others only support the
|
||||
substitution filter mechanism and month/day names.
|
||||
.PP
|
||||
\fBGerman\fR --
|
||||
Wolfgang Thronicke
|
||||
|
||||
@@ -413,6 +413,39 @@ like this:
|
||||
The value of the \fBqueue\fR key is an array of JSON objects, each
|
||||
representing a queued reminder.
|
||||
|
||||
.TP
|
||||
TRANSLATE Any string goes here
|
||||
Returns the translation of "Any string goes here" according to \fBRemind\fR's
|
||||
translation table. Note that there must be exactly one space after
|
||||
TRANSLATE and before the string you wish to translate. The JSON object
|
||||
that results from "TRANSLATE New Moon" might look like this:
|
||||
.nf
|
||||
|
||||
{"response":"translate","translation":{"New Moon":"Nieuwe maan"},"command":"TRANSLATE"}
|
||||
|
||||
.fi
|
||||
As you see, the value of the \fBtranslation\fR key is an object whose
|
||||
key is the original text and value is the translated text. A
|
||||
front-end can use TRANSLATE do its own localization; for example,
|
||||
TkRemind uses it to localize the moon phase popup window for the
|
||||
SPECIAL MOON display.
|
||||
.RS
|
||||
.PP
|
||||
If the argument to TRANSLATE is not in the translation table, then
|
||||
\fBRemind\fR \fIwill not issue any response at all\fR to the TRANSLATE command.
|
||||
.RE
|
||||
.TP
|
||||
TRANSLATE_DUMP
|
||||
Returns the contents of the translation table. The JSON object looks
|
||||
like this:
|
||||
.nf
|
||||
|
||||
{"response":"translate_dump","table":{...},"command":"TRANSLATE_DUMP"}
|
||||
|
||||
.fi
|
||||
The value of the \fBtable\fR key is a dictionary of original-to-translated
|
||||
strings.
|
||||
|
||||
.TP
|
||||
DEL \fIqid\fR
|
||||
Delete the reminder with queue-id \fIqid\fR from the queue.
|
||||
|
||||
@@ -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,
|
||||
@@ -265,6 +267,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 +302,12 @@ sub parse_input
|
||||
|
||||
my $found_data = 0;
|
||||
while(<STDIN>) {
|
||||
chomp;
|
||||
last if /^\# rem2ps2? begin$/;
|
||||
chomp;
|
||||
if (/# translations/) {
|
||||
slurp_translations();
|
||||
next;
|
||||
}
|
||||
last if /^\# rem2ps2? begin$/;
|
||||
}
|
||||
|
||||
my $line;
|
||||
@@ -659,7 +690,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 +698,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 +707,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 +715,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>");
|
||||
|
||||
@@ -30,6 +30,8 @@ catch {
|
||||
set Hostname [exec hostname]
|
||||
}
|
||||
|
||||
set Translations [dict create]
|
||||
|
||||
global env
|
||||
set HOME $env(HOME)
|
||||
|
||||
@@ -696,6 +698,21 @@ proc DoQueue {} {
|
||||
flush $DaemonFile
|
||||
}
|
||||
|
||||
proc DoTranslate {} {
|
||||
global DaemonFile
|
||||
global Translations
|
||||
|
||||
# Clear out any existing translations
|
||||
set Translations [dict create]
|
||||
|
||||
# Get just the translations we can use
|
||||
puts $DaemonFile "TRANSLATE New Moon"
|
||||
puts $DaemonFile "TRANSLATE Full Moon"
|
||||
puts $DaemonFile "TRANSLATE First Quarter"
|
||||
puts $DaemonFile "TRANSLATE Last Quarter"
|
||||
flush $DaemonFile
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# CreateCalWindow -- create the calendar window.
|
||||
# Arguments:
|
||||
@@ -703,6 +720,7 @@ proc DoQueue {} {
|
||||
#---------------------------------------------------------------------------
|
||||
proc CreateCalWindow { dayNames } {
|
||||
global Option
|
||||
|
||||
frame .h -background $Option(LineColor)
|
||||
label .h.title -text "" -justify center -pady 2 -bd 0 -relief flat -font HeadingFont -background $Option(WinBackground) -foreground $Option(LabelColor)
|
||||
pack .h.title -side top -fill x -pady 1 -padx 1
|
||||
@@ -2702,7 +2720,8 @@ proc StartBackgroundRemindDaemon {} {
|
||||
} else {
|
||||
fileevent $DaemonFile readable "DaemonReadable $DaemonFile"
|
||||
puts $DaemonFile "STATUS"
|
||||
flush $DaemonFile
|
||||
DoTranslate
|
||||
ScheduleUpdateForChanges
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2826,6 +2845,33 @@ proc sort_q { a b } {
|
||||
return 0
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# AddTranslation
|
||||
# Arguments:
|
||||
# obj - a dictionary of the form old:new
|
||||
# Returns:
|
||||
# nothing
|
||||
# Description:
|
||||
# Updates the Translations dict object
|
||||
#---------------------------------------------------------------------------
|
||||
proc AddTranslation { obj } {
|
||||
global Translations
|
||||
set Translations [dict merge $Translations $obj]
|
||||
ScheduleUpdateForChanges
|
||||
}
|
||||
|
||||
proc t { str } {
|
||||
global Translations
|
||||
set trans ""
|
||||
catch {
|
||||
set trans [dict get $Translations $str]
|
||||
}
|
||||
if {"$trans" == ""} {
|
||||
return $str
|
||||
}
|
||||
return $trans
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# DaemonReadable
|
||||
# Arguments:
|
||||
@@ -2851,6 +2897,9 @@ proc DaemonReadable { file } {
|
||||
}
|
||||
set response [dict get $obj response]
|
||||
switch -- $response {
|
||||
"translate" {
|
||||
AddTranslation [dict get $obj translation]
|
||||
}
|
||||
"queued" {
|
||||
set n [dict get $obj nqueued]
|
||||
if {$n == 1} {
|
||||
@@ -2888,7 +2937,9 @@ proc DaemonReadable { file } {
|
||||
if {[dict exists $obj command]} {
|
||||
set cmd [dict get $obj command]
|
||||
if {"$cmd" == "inotify"} {
|
||||
FillCalWindow
|
||||
# Update our translations if file has changed
|
||||
DoTranslate
|
||||
ScheduleUpdateForChanges
|
||||
}
|
||||
}
|
||||
puts $file "STATUS"
|
||||
@@ -3617,14 +3668,14 @@ proc UpdateForChanges {} {
|
||||
RestartBackgroundRemindDaemon
|
||||
}
|
||||
|
||||
# Schedule an update for 100ms in the future.
|
||||
# Schedule an update for 250ms in the future.
|
||||
# That way, if we get a rapid succession of
|
||||
# change notifications, we (probably) only
|
||||
# end up doing one call to UpdateForChanges
|
||||
proc ScheduleUpdateForChanges {} {
|
||||
global TimerUpdateForChanges
|
||||
catch { after cancel $TimerUpdateForChanges }
|
||||
set TimerUpdateForChanges [after 100 UpdateForChanges]
|
||||
set TimerUpdateForChanges [after 250 UpdateForChanges]
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
@@ -3929,27 +3980,27 @@ proc CreateMoonWindows {} {
|
||||
foreach win {.moon_new .moon_new2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
balloon_add_help $win "New Moon"
|
||||
balloon_add_help $win [t "New Moon"]
|
||||
}
|
||||
|
||||
foreach win {.moon_first .moon_first2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
$win create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 90 -extent 180 -outline {}
|
||||
balloon_add_help $win "First Quarter"
|
||||
balloon_add_help $win [t "First Quarter"]
|
||||
}
|
||||
|
||||
foreach win {.moon_full .moon_full2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -width 1
|
||||
balloon_add_help $win "Full Moon"
|
||||
balloon_add_help $win [t "Full Moon"]
|
||||
}
|
||||
|
||||
foreach win {.moon_last .moon_last2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
$win create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 270 -extent 180 -outline {}
|
||||
balloon_add_help $win "Last Quarter"
|
||||
balloon_add_help $win [t "Last Quarter"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@ MANS= $(srcdir)/../man/rem2ps.1 $(srcdir)/../man/remind.1 \
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
REMINDSRCS= calendar.c dedupe.c dynbuf.c dorem.c dosubst.c expr.c \
|
||||
files.c funcs.c globals.c hbcal.c init.c main.c md5.c \
|
||||
moon.c omit.c queue.c sort.c token.c trigger.c \
|
||||
userfns.c utils.c var.c
|
||||
files.c funcs.c globals.c hashtab.c hashtab_stats.c \
|
||||
hbcal.c init.c main.c md5.c moon.c omit.c queue.c \
|
||||
sort.c token.c trans.c trigger.c userfns.c utils.c var.c
|
||||
|
||||
REMINDHDRS=config.h custom.h dynbuf.h err.h globals.h lang.h \
|
||||
REMINDHDRS=config.h custom.h dynbuf.h err.h globals.h hashtab.h \
|
||||
md5.h protos.h rem2ps.h types.h version.h
|
||||
REMINDOBJS= $(REMINDSRCS:.c=.o)
|
||||
|
||||
@@ -41,7 +41,7 @@ test: all
|
||||
@sh ../tests/test-rem
|
||||
|
||||
.c.o:
|
||||
@CC@ -c @CPPFLAGS@ @CFLAGS@ @DEFS@ $(CEXTRA) $(LANGDEF) -DSYSDIR=$(datarootdir)/remind -I. -I$(srcdir) $<
|
||||
@CC@ -c @CPPFLAGS@ @CFLAGS@ @DEFS@ $(CEXTRA) -DSYSDIR=$(datarootdir)/remind -I. -I$(srcdir) $<
|
||||
|
||||
$(REMINDOBJS): $(REMINDHDRS)
|
||||
|
||||
@@ -92,7 +92,7 @@ depend:
|
||||
# distributions, etc.
|
||||
|
||||
cppcheck:
|
||||
cppcheck -j`nproc` --force --enable=all --suppress=ConfigurationNotChecked --suppress=unmatchedSuppression --suppress=variableScope --inline-suppr .
|
||||
cppcheck -j`nproc` -v --force --enable=all --suppress=ConfigurationNotChecked --suppress=unmatchedSuppression --suppress=variableScope --inline-suppr .
|
||||
|
||||
# Build a tar file based on all files checked into git.
|
||||
distro:
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
|
||||
#include "lang.h"
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "globals.h"
|
||||
@@ -966,6 +965,18 @@ static void DoCalendarOneWeek(int nleft)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SendTranslationTable(int pslevel)
|
||||
{
|
||||
if (pslevel < PSCAL_LEVEL3) {
|
||||
printf("# translations\n");
|
||||
}
|
||||
DumpTranslationTable(stdout, 1);
|
||||
if (pslevel < PSCAL_LEVEL3) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoSimpleCalendarOneMonth */
|
||||
@@ -985,14 +996,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",
|
||||
@@ -1250,7 +1272,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 +1357,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 +1667,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 +1675,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 +1708,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 +1734,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 +1757,7 @@ static void GenerateCalEntries(int col)
|
||||
r=DoCalRem(&p, col);
|
||||
break;
|
||||
}
|
||||
if (r && (!Hush || r != E_RUN_DISABLED)) Eprint("%s", ErrMsg[r]);
|
||||
if (r && (!Hush || r != E_RUN_DISABLED)) Eprint("%s", GetErr(r));
|
||||
|
||||
/* Destroy the parser - free up resources it may be tying up */
|
||||
DestroyParser(&p);
|
||||
@@ -2297,7 +2321,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 +2356,7 @@ void WriteJSONTrigger(Trigger const *t, int include_tags, int today)
|
||||
printf(",");
|
||||
}
|
||||
done = 1;
|
||||
printf("\"%s\"", EnglishDayName[i]);
|
||||
printf("\"%s\"", DayName[i]);
|
||||
}
|
||||
}
|
||||
printf("],");
|
||||
@@ -2683,14 +2707,14 @@ CalendarTime(int tim, int duration)
|
||||
}
|
||||
|
||||
if (h >= 12) {
|
||||
ampm1 = DynamicPm;
|
||||
ampm1 = tr("pm");
|
||||
} else {
|
||||
ampm1 = DynamicAm;
|
||||
ampm1 = tr("am");
|
||||
}
|
||||
if (h2 >= 12) {
|
||||
ampm2 = DynamicPm;
|
||||
ampm2 = tr("pm");
|
||||
} else {
|
||||
ampm2 = DynamicAm;
|
||||
ampm2 = tr("am");
|
||||
}
|
||||
if (!days) {
|
||||
if (!strcmp(ampm1, ampm2)) {
|
||||
@@ -2737,7 +2761,7 @@ char const *SimpleTime(int tim)
|
||||
if (h == 0) hh=12;
|
||||
else if (h > 12) hh=h-12;
|
||||
else hh=h;
|
||||
sprintf(buf, "%d%c%02d%s ", hh, TimeSep, min, (h>=12) ? DynamicPm : DynamicAm);
|
||||
sprintf(buf, "%d%c%02d%s ", hh, TimeSep, min, (h>=12) ? tr("pm") : tr("am"));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $language_map = {
|
||||
en => 'ENGLISH',
|
||||
de => 'GERMAN',
|
||||
nl => 'DUTCH',
|
||||
fi => 'FINNISH',
|
||||
fr => 'FRENCH',
|
||||
'no' => 'NORWEGIAN',
|
||||
da => 'DANISH',
|
||||
pl => 'POLISH',
|
||||
is => 'ICELANDIC',
|
||||
pt => 'BRAZPORT',
|
||||
it => 'ITALIAN',
|
||||
ro => 'ROMANIAN',
|
||||
es => 'SPANISH',
|
||||
};
|
||||
|
||||
if (!$ARGV[0]) {
|
||||
print STDERR "Usage: $0 lang_code\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
my $lang = $ARGV[0];
|
||||
my $rc = 0;
|
||||
if ($lang eq 'all') {
|
||||
foreach my $l (sort(keys(%$language_map))) {
|
||||
if (check($l)) {
|
||||
$rc = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$rc = check($lang);
|
||||
}
|
||||
|
||||
exit($rc);
|
||||
|
||||
sub check
|
||||
{
|
||||
my ($lang) = @_;
|
||||
if (!exists($language_map->{$lang})) {
|
||||
print STDERR "$lang is not a valid language.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
my $flag = $language_map->{$lang};
|
||||
print STDERR "Testing for: $lang - $flag.\n";
|
||||
my_sys("make clean > /dev/null 2>&1") && die("make clean failed");
|
||||
my_sys("make -j18 all LANGDEF=-DLANG=$flag > /dev/null 2>&1") && die("make all failed");
|
||||
my_sys("./remind -q -r ../tests/tstlang.rem 2022-03-23 11:44 > test-$lang-compiled.out 2>&1");
|
||||
|
||||
my_sys("make clean > /dev/null 2>&1") && die("make clean failed");
|
||||
my_sys("make -j18 all > /dev/null 2>&1") && die("make all failed");
|
||||
my_sys("./remind -q -r -ii=\\\"../include/lang/$lang.rem\\\" ../tests/tstlang.rem 2022-03-23 11:44 > test-$lang-runtime.out 2>&1");
|
||||
|
||||
my $rc = my_sys("cmp test-$lang-compiled.out test-$lang-runtime.out > /dev/null 2>&1");
|
||||
if ($rc == 0) {
|
||||
print STDERR "Congrats! Compiled and runtime language output matches for $lang.\n";
|
||||
} else {
|
||||
print STDERR "Whoops. Compiled and runtime language output differs for $lang.\n"
|
||||
}
|
||||
return $rc;
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
||||
sub my_sys
|
||||
{
|
||||
#print STDERR "Running: " . join(' ', @_) . "\n";
|
||||
return system(@_);
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
116
src/dedupe.c
116
src/dedupe.c
@@ -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);
|
||||
}
|
||||
|
||||
60
src/dorem.c
60
src/dorem.c
@@ -284,7 +284,7 @@ int DoRem(ParsePtr p)
|
||||
dse = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 1);
|
||||
if (r) {
|
||||
if (PurgeMode) {
|
||||
PurgeEchoLine("%s: %s\n", "#!P! Problem calculating trigger date", ErrMsg[r]);
|
||||
PurgeEchoLine("%s: %s\n", "#!P! Problem calculating trigger date", GetErr(r));
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
if (r == E_CANT_TRIG && trig.maybe_uncomputable) {
|
||||
@@ -698,7 +698,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", ErrMsg[-tok.val], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return -tok.val;
|
||||
}
|
||||
@@ -808,7 +808,7 @@ static int ParseTimeTrig(ParsePtr s, TimeTrig *tim)
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", ErrMsg[-tok.val], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return -tok.val;
|
||||
}
|
||||
@@ -887,7 +887,7 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
y = tok.val;
|
||||
@@ -896,7 +896,7 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
case T_Month:
|
||||
DBufFree(&buf);
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
m = tok.val;
|
||||
@@ -905,7 +905,7 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
case T_Day:
|
||||
DBufFree(&buf);
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
d = tok.val;
|
||||
@@ -914,15 +914,15 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", which, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
FromDSE(tok.val, &y, &m, &d);
|
||||
@@ -930,12 +930,12 @@ static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", ErrMsg[-tok.val], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return -tok.val;
|
||||
}
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
|
||||
Eprint("%s: %s", which, ErrMsg[E_INCOMPLETE]);
|
||||
Eprint("%s: %s", which, GetErr(E_INCOMPLETE));
|
||||
DBufFree(&buf);
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
@@ -984,7 +984,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
y = tok.val;
|
||||
@@ -993,7 +993,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
case T_Month:
|
||||
DBufFree(&buf);
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
m = tok.val;
|
||||
@@ -1002,7 +1002,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
case T_Day:
|
||||
DBufFree(&buf);
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
d = tok.val;
|
||||
@@ -1011,15 +1011,15 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
FromDSE(tok.val, &y, &m, &d);
|
||||
@@ -1028,19 +1028,19 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
case T_Back:
|
||||
DBufFree(&buf);
|
||||
if (type != SCANFROM_TYPE) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_INCOMPLETE]);
|
||||
Eprint("%s: %s", word, GetErr(E_INCOMPLETE));
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_YR_TWICE));
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_MON_TWICE));
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", word, GetErr(E_DAY_TWICE));
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
if (tok.val < 0) {
|
||||
@@ -1054,12 +1054,12 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", ErrMsg[-tok.val], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return -tok.val;
|
||||
}
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_INCOMPLETE]);
|
||||
Eprint("%s: %s", word, GetErr(E_INCOMPLETE));
|
||||
DBufFree(&buf);
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
@@ -1471,7 +1471,7 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int dse, int *err)
|
||||
}
|
||||
if (iter > max) {
|
||||
*err = E_CANT_TRIG;
|
||||
Eprint("Delta: Bad OMITFUNC? %s", ErrMsg[E_CANT_TRIG]);
|
||||
Eprint("Delta: Bad OMITFUNC? %s", GetErr(E_CANT_TRIG));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1690,7 +1690,7 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
||||
|
||||
/* If no proper function exists, barf... */
|
||||
if (UserFuncExists(t->warn) != 1) {
|
||||
Eprint("%s: `%s'", ErrMsg[M_BAD_WARN_FUNC], t->warn);
|
||||
Eprint("%s: `%s'", GetErr(M_BAD_WARN_FUNC), t->warn);
|
||||
return (dse == DSEToday);
|
||||
}
|
||||
for (i=1; ; i++) {
|
||||
@@ -1698,14 +1698,14 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
||||
s = buffer;
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
if (r) {
|
||||
Eprint("%s: `%s': %s", ErrMsg[M_BAD_WARN_FUNC],
|
||||
t->warn, ErrMsg[r]);
|
||||
Eprint("%s: `%s': %s", GetErr(M_BAD_WARN_FUNC),
|
||||
t->warn, GetErr(r));
|
||||
return (dse == DSEToday);
|
||||
}
|
||||
if (v.type != INT_TYPE) {
|
||||
DestroyValue(v);
|
||||
Eprint("%s: `%s': %s", ErrMsg[M_BAD_WARN_FUNC],
|
||||
t->warn, ErrMsg[E_BAD_TYPE]);
|
||||
Eprint("%s: `%s': %s", GetErr(M_BAD_WARN_FUNC),
|
||||
t->warn, GetErr(E_BAD_TYPE));
|
||||
return (dse == DSEToday);
|
||||
}
|
||||
|
||||
@@ -1735,7 +1735,7 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int dse, int *err)
|
||||
}
|
||||
}
|
||||
if (iter > max) {
|
||||
Eprint("Delta: Bad OMITFUNC? %s", ErrMsg[E_CANT_TRIG]);
|
||||
Eprint("Delta: Bad OMITFUNC? %s", GetErr(E_CANT_TRIG));
|
||||
return 0;
|
||||
}
|
||||
if (j == DSEToday) return 1;
|
||||
|
||||
487
src/dosubst.c
487
src/dosubst.c
@@ -93,26 +93,14 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
mdiff = adiff % 60;
|
||||
hdiff = adiff / 60;
|
||||
|
||||
#ifdef L_MPLU_OVER
|
||||
L_MPLU_OVER
|
||||
#else /* L_MPLU_OVER */
|
||||
mplu = (mdiff == 1 ? "" : DynamicMplu);
|
||||
#endif /* L_MPLU_OVER */
|
||||
|
||||
#ifdef L_HPLU_OVER
|
||||
L_HPLU_OVER
|
||||
#else /* L_HPLU_OVER */
|
||||
hplu = (hdiff == 1 ? "" : DynamicHplu);
|
||||
#endif /* L_HPLU_OVER */
|
||||
|
||||
when = (tdiff < 0) ? DynamicAgo : DynamicFromnow;
|
||||
when = (tdiff < 0) ? tr("ago") : tr("from now");
|
||||
|
||||
h = tim / 60;
|
||||
min = tim % 60;
|
||||
|
||||
#ifdef L_AMPM_OVERRIDE
|
||||
L_AMPM_OVERRIDE (pm, h)
|
||||
#else
|
||||
r = -1;
|
||||
func = FindUserFunc("subst_ampm");
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
@@ -128,21 +116,18 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
pm = (h < 12) ? DynamicAm : DynamicPm;
|
||||
pm = (h < 12) ? tr("am") : tr("pm");
|
||||
}
|
||||
#endif
|
||||
|
||||
hh = (h == 12) ? 12 : h % 12;
|
||||
|
||||
ch = curtime / 60;
|
||||
cmin = curtime % 60;
|
||||
|
||||
#ifdef L_AMPM_OVERRIDE
|
||||
L_AMPM_OVERRIDE (cpm, ch)
|
||||
#else
|
||||
r = -1;
|
||||
func = FindUserFunc("subst_ampm");
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
@@ -158,18 +143,14 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
cpm = (h < 12) ? DynamicAm : DynamicPm;
|
||||
cpm = (h < 12) ? tr("am") : tr("pm");
|
||||
}
|
||||
#endif
|
||||
chh = (ch == 12) ? 12 : ch % 12;
|
||||
|
||||
#ifdef L_ORDINAL_OVERRIDE
|
||||
L_ORDINAL_OVERRIDE;
|
||||
#else
|
||||
func = FindUserFunc("subst_ordinal");
|
||||
if (func && check_subst_args(func, 1)) {
|
||||
snprintf(s, sizeof(s), "subst_ordinal(%d)", d);
|
||||
@@ -184,7 +165,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
@@ -202,7 +183,6 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
default: plu = "th"; break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
@@ -235,6 +215,36 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
if (c == '(') {
|
||||
DynamicBuffer orig;
|
||||
DynamicBuffer translated;
|
||||
DBufInit(&orig);
|
||||
DBufInit(&translated);
|
||||
while(1) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(&orig);
|
||||
return err;
|
||||
}
|
||||
if (!c || c == ')') {
|
||||
break;
|
||||
}
|
||||
DBufPutc(&orig, c);
|
||||
}
|
||||
if (!c) {
|
||||
Wprint("Warning: Unterminated %%(...) substitution sequence");
|
||||
}
|
||||
err = OK;
|
||||
if (GetTranslatedStringTryingVariants(DBufValue(&orig), &translated)) {
|
||||
err = DBufPuts(dbuf, DBufValue(&translated));
|
||||
} else {
|
||||
err = DBufPuts(dbuf, DBufValue(&orig));
|
||||
}
|
||||
DBufFree(&orig);
|
||||
DBufFree(&translated);
|
||||
if (err) return err;
|
||||
continue;
|
||||
}
|
||||
if (c == '*') {
|
||||
altmode = c;
|
||||
c = ParseChar(p, &err, 0);
|
||||
@@ -312,52 +322,26 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
|
||||
if (diff <= 1) {
|
||||
switch(UPPER(c)) {
|
||||
#ifndef L_NOTOMORROW_A
|
||||
case 'A':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_B
|
||||
case 'B':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_C
|
||||
case 'C':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_E
|
||||
case 'E':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_F
|
||||
case 'F':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_G
|
||||
case 'G':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_H
|
||||
case 'H':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_I
|
||||
case 'I':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_J
|
||||
case 'J':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_K
|
||||
case 'K':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_L
|
||||
case 'L':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_U
|
||||
case 'U':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_V
|
||||
case 'V':
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", (diff ? DynamicTomorrow: DynamicToday));
|
||||
snprintf(s, sizeof(s), "%s", (diff ? tr("tomorrow") : tr("today")));
|
||||
SHIP_OUT(s);
|
||||
done = 1;
|
||||
break;
|
||||
@@ -388,436 +372,279 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
switch(UPPER(c)) {
|
||||
case 'A':
|
||||
#ifdef L_A_OVER
|
||||
L_A_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d %s, %d", get_day_name(dse%7), d,
|
||||
get_month_name(m), y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d %s, %d", DynamicOn, get_day_name(dse%7), d,
|
||||
get_month_name(m), y);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d %s, %d", get_day_name(dse%7), d,
|
||||
get_month_name(m), y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d %s, %d", tr("on"), get_day_name(dse%7), d,
|
||||
get_month_name(m), y);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
#ifdef L_B_OVER
|
||||
L_B_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), L_INXDAYS, diff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "in %d days' time", diff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
#ifdef L_C_OVER
|
||||
L_C_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s", DynamicOn, get_day_name(dse%7));
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s", tr("on"), get_day_name(dse%7));
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
#ifdef L_D_OVER
|
||||
L_D_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", d);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", d);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
#ifdef L_E_OVER
|
||||
L_E_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", d, DateSep,
|
||||
m+1, DateSep, y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, d, DateSep,
|
||||
m+1, DateSep, y);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", d, DateSep,
|
||||
m+1, DateSep, y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", tr("on"), d, DateSep,
|
||||
m+1, DateSep, y);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
#ifdef L_F_OVER
|
||||
L_F_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, m+1, DateSep, d, DateSep, y);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", tr("on"), m+1, DateSep, d, DateSep, y);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
#ifdef L_G_OVER
|
||||
L_G_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d %s", get_day_name(dse%7), d, get_month_name(m));
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d %s", DynamicOn, get_day_name(dse%7), d, get_month_name(m));
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d %s", get_day_name(dse%7), d, get_month_name(m));
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d %s", tr("on"), get_day_name(dse%7), d, get_month_name(m));
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
#ifdef L_H_OVER
|
||||
L_H_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", d, DateSep, m+1);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, d, DateSep, m+1);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", d, DateSep, m+1);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", tr("on"), d, DateSep, m+1);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
#ifdef L_I_OVER
|
||||
L_I_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", m+1, DateSep, d);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, m+1, DateSep, d);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", m+1, DateSep, d);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", tr("on"), m+1, DateSep, d);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
#ifdef L_J_OVER
|
||||
L_J_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %s %d%s, %d", get_day_name(dse%7),
|
||||
get_month_name(m), d, plu, y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %s %d%s, %d", DynamicOn, get_day_name(dse%7),
|
||||
get_month_name(m), d, plu, y);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%s, %s %d%s, %d", get_day_name(dse%7),
|
||||
get_month_name(m), d, plu, y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %s %d%s, %d", tr("on"), get_day_name(dse%7),
|
||||
get_month_name(m), d, plu, y);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
#ifdef L_K_OVER
|
||||
L_K_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %s %d%s", get_day_name(dse%7),
|
||||
get_month_name(m), d, plu);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %s %d%s", DynamicOn, get_day_name(dse%7),
|
||||
get_month_name(m), d, plu);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%s, %s %d%s", get_day_name(dse%7),
|
||||
get_month_name(m), d, plu);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %s %d%s", tr("on"), get_day_name(dse%7),
|
||||
get_month_name(m), d, plu);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
#ifdef L_L_OVER
|
||||
L_L_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %04d%c%02d%c%02d", DynamicOn, y, DateSep, m+1, DateSep, d);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %04d%c%02d%c%02d", tr("on"), y, DateSep, m+1, DateSep, d);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
#ifdef L_M_OVER
|
||||
L_M_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", get_month_name(m));
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", get_month_name(m));
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
#ifdef L_N_OVER
|
||||
L_N_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", m+1);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", m+1);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
#ifdef L_O_OVER
|
||||
L_O_OVER
|
||||
#else
|
||||
if (RealToday == DSEToday) snprintf(s, sizeof(s), " (%s)", DynamicToday);
|
||||
else *s = 0;
|
||||
#endif
|
||||
if (RealToday == DSEToday) snprintf(s, sizeof(s), " (%s)", tr("today"));
|
||||
else *s = 0;
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
#ifdef L_P_OVER
|
||||
L_P_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", (diff == 1 ? "" : L_PLURAL));
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", (diff == 1 ? "" : "s"));
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
#ifdef L_Q_OVER
|
||||
L_Q_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", (diff == 1 ? "'s" : "s'"));
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", (diff == 1 ? "'s" : "s'"));
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
#ifdef L_R_OVER
|
||||
L_R_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%02d", d);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%02d", d);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
#ifdef L_S_OVER
|
||||
L_S_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", plu);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", plu);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
#ifdef L_T_OVER
|
||||
L_T_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%02d", m+1);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%02d", m+1);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
#ifdef L_U_OVER
|
||||
L_U_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d%s %s, %d", get_day_name(dse%7), d,
|
||||
plu, get_month_name(m), y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d%s %s, %d", DynamicOn, get_day_name(dse%7), d,
|
||||
plu, get_month_name(m), y);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d%s %s, %d", get_day_name(dse%7), d,
|
||||
plu, get_month_name(m), y);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d%s %s, %d", tr("on"), get_day_name(dse%7), d,
|
||||
plu, get_month_name(m), y);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
#ifdef L_V_OVER
|
||||
L_V_OVER
|
||||
#else
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d%s %s", get_day_name(dse%7), d, plu,
|
||||
get_month_name(m));
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d%s %s", DynamicOn, get_day_name(dse%7), d, plu,
|
||||
get_month_name(m));
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*' || !strcmp(tr("on"), "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d%s %s", get_day_name(dse%7), d, plu,
|
||||
get_month_name(m));
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %s, %d%s %s", tr("on"), get_day_name(dse%7), d, plu,
|
||||
get_month_name(m));
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
#ifdef L_W_OVER
|
||||
L_W_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
#ifdef L_X_OVER
|
||||
L_X_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", diff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", diff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
#ifdef L_Y_OVER
|
||||
L_Y_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", y);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", y);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
#ifdef L_Z_OVER
|
||||
L_Z_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", y % 100);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", y % 100);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '1':
|
||||
#ifdef L_1_OVER
|
||||
L_1_OVER
|
||||
#else
|
||||
if (tdiff == 0)
|
||||
snprintf(s, sizeof(s), "%s", DynamicNow);
|
||||
else if (hdiff == 0)
|
||||
snprintf(s, sizeof(s), "%d %s%s %s", mdiff, DynamicMinute, mplu, when);
|
||||
else if (mdiff == 0)
|
||||
snprintf(s, sizeof(s), "%d %s%s %s", hdiff, DynamicHour, hplu, when);
|
||||
else
|
||||
snprintf(s, sizeof(s), "%d %s%s %s %d %s%s %s", hdiff, DynamicHour, hplu,
|
||||
DynamicAnd, mdiff, DynamicMinute, mplu, when);
|
||||
#endif
|
||||
if (tdiff == 0)
|
||||
snprintf(s, sizeof(s), "%s", tr("now"));
|
||||
else if (hdiff == 0)
|
||||
snprintf(s, sizeof(s), "%d %s%s %s", mdiff, tr("minute"), mplu, when);
|
||||
else if (mdiff == 0)
|
||||
snprintf(s, sizeof(s), "%d %s%s %s", hdiff, tr("hour"), hplu, when);
|
||||
else
|
||||
snprintf(s, sizeof(s), "%d %s%s %s %d %s%s %s", hdiff, tr("hour"), hplu,
|
||||
tr("and"), mdiff, tr("minute"), mplu, when);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '2':
|
||||
#ifdef L_2_OVER
|
||||
L_2_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
snprintf(s, sizeof(s), "%d%c%02d%s", hh, TimeSep, min, pm);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %d%c%02d%s", DynamicAt, hh, TimeSep, min, pm);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*') {
|
||||
snprintf(s, sizeof(s), "%d%c%02d%s", hh, TimeSep, min, pm);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %d%c%02d%s", tr("at"), hh, TimeSep, min, pm);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '3':
|
||||
#ifdef L_3_OVER
|
||||
L_3_OVER
|
||||
#else
|
||||
|
||||
if (altmode == '*') {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", h, TimeSep, min);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicAt, h, TimeSep, min);
|
||||
}
|
||||
#endif
|
||||
if (altmode == '*') {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", h, TimeSep, min);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", tr("at"), h, TimeSep, min);
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '4':
|
||||
#ifdef L_4_OVER
|
||||
L_4_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", tdiff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", tdiff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '5':
|
||||
#ifdef L_5_OVER
|
||||
L_5_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", adiff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", adiff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '6':
|
||||
#ifdef L_6_OVER
|
||||
L_6_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", when);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", when);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '7':
|
||||
#ifdef L_7_OVER
|
||||
L_7_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", hdiff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", hdiff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '8':
|
||||
#ifdef L_8_OVER
|
||||
L_8_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d", mdiff);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d", mdiff);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '9':
|
||||
#ifdef L_9_OVER
|
||||
L_9_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", mplu);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", mplu);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '0':
|
||||
#ifdef L_0_OVER
|
||||
L_0_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", hplu);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", hplu);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '!':
|
||||
#ifdef L_BANG_OVER
|
||||
L_BANG_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? DynamicIs : DynamicWas));
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? tr("is") : tr("was")));
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '@':
|
||||
#ifdef L_AT_OVER
|
||||
L_AT_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%d%c%02d%s", chh, TimeSep, cmin, cpm);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%d%c%02d%s", chh, TimeSep, cmin, cpm);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '#':
|
||||
#ifdef L_HASH_OVER
|
||||
L_HASH_OVER
|
||||
#else
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", ch, TimeSep, cmin);
|
||||
#endif
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", ch, TimeSep, cmin);
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
@@ -914,7 +741,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoSubstFromString(char const *source, DynamicBuffer *dbuf,
|
||||
int dse, int tim)
|
||||
int dse, int tim)
|
||||
{
|
||||
Trigger tempTrig;
|
||||
TimeTrig tempTime;
|
||||
|
||||
42
src/err.h
42
src/err.h
@@ -13,31 +13,35 @@
|
||||
/* Note that not all of the "errors" are really errors - some are just
|
||||
messages for information purposes. Constants beginning with M_ should
|
||||
never be returned as error indicators - they should only be used to
|
||||
index the ErrMsg array. */
|
||||
index the ErrMsg array.
|
||||
|
||||
Some #defines are commented out; these are former error codes that are
|
||||
no longer used. They are left as placeholders because renumbering
|
||||
everything wouild be too tedious */
|
||||
|
||||
#define OK 0
|
||||
#define E_MISS_END 1
|
||||
#define E_MISS_QUOTE 2
|
||||
#define E_OP_STK_OVER 3
|
||||
#define E_VA_STK_OVER 4
|
||||
/* #define E_VA_STK_OVER 4 */
|
||||
#define E_MISS_RIGHT_PAREN 5
|
||||
#define E_UNDEF_FUNC 6
|
||||
#define E_ILLEGAL_CHAR 7
|
||||
#define E_EXPECTING_BINOP 8
|
||||
/* #define E_EXPECTING_BINOP 8 */
|
||||
#define E_NO_MEM 9
|
||||
#define E_BAD_NUMBER 10
|
||||
#define E_OP_STK_UNDER 11
|
||||
#define E_VA_STK_UNDER 12
|
||||
/* #define E_OP_STK_UNDER 11 */
|
||||
/* #define E_VA_STK_UNDER 12 */
|
||||
#define E_CANT_COERCE 13
|
||||
#define E_BAD_TYPE 14
|
||||
#define E_DATE_OVER 15
|
||||
#define E_STACK_ERR 16
|
||||
/* #define E_STACK_ERR 16 */
|
||||
#define E_DIV_ZERO 17
|
||||
#define E_NOSUCH_VAR 18
|
||||
#define E_EOLN 19
|
||||
#define E_EOF 20
|
||||
#define E_IO_ERR 21
|
||||
#define E_LINE_2_LONG 22
|
||||
/* #define E_LINE_2_LONG 22 */
|
||||
#define E_SWERR 23
|
||||
#define E_BAD_DATE 24
|
||||
#define E_2FEW_ARGS 25
|
||||
@@ -72,7 +76,7 @@
|
||||
#define E_DAY_TWICE 52
|
||||
#define E_UNKNOWN_TOKEN 53
|
||||
#define E_SPEC_MON 54
|
||||
#define E_2MANY_PART 55
|
||||
/* #define E_2MANY_PART 55 */
|
||||
#define E_2MANY_FULL 56
|
||||
#define E_PUSH_NOPOP 57
|
||||
#define E_ERR_READING 58
|
||||
@@ -110,7 +114,7 @@
|
||||
#define E_MISS_EQ 90
|
||||
#define E_MISS_VAR 91
|
||||
#define E_MISS_EXPR 92
|
||||
#define M_CANTSET_ACCESS 93
|
||||
/* #define M_CANTSET_ACCESS 93 */
|
||||
#define M_I_OPTION 94
|
||||
#define E_NOREMINDERS 95
|
||||
#define M_QUEUED 96
|
||||
@@ -147,25 +151,25 @@ EXTERN char *ErrMsg[]
|
||||
/* E_MISS_END */ "Missing ']'",
|
||||
/* E_MISS_QUOTE */ "Missing quote",
|
||||
/* E_OP_STK_OVER */ "Expression too complex",
|
||||
/* E_VA_STK_OVER */ "Expression too complex - too many operands",
|
||||
/* E_VA_STK_OVER */ "",
|
||||
/* E_MISS_RIGHT_PAREN */ "Missing ')'",
|
||||
/* E_UNDEF_FUNC */ "Undefined function",
|
||||
/* E_ILLEGAL_CHAR */ "Illegal character",
|
||||
/* E_EXPECTING_BINOP */ "Expecting binary operator",
|
||||
/* E_NO_MEM */ "Out of memory",
|
||||
/* E_BAD_NUMBER */ "Ill-formed number",
|
||||
/* E_OP_STK_UNDER */ "Op stack underflow - internal error",
|
||||
/* E_VA_STK_UNDER */ "Va stack underflow - internal error",
|
||||
/* E_OP_STK_UNDER */ "",
|
||||
/* E_VA_STK_UNDER */ "",
|
||||
/* E_CANT_COERCE */ "Can't coerce",
|
||||
/* E_BAD_TYPE */ "Type mismatch",
|
||||
/* E_DATE_OVER */ "Date overflow",
|
||||
/* E_STACK_ERR */ "Stack error - internal error",
|
||||
/* E_STACK_ERR */ "",
|
||||
/* E_DIV_ZERO */ "Division by zero",
|
||||
/* E_NOSUCH_VAR */ "Undefined variable",
|
||||
/* E_EOLN */ "Unexpected end of line",
|
||||
/* E_EOF */ "Unexpected end of file",
|
||||
/* E_IO_ERR */ "I/O error",
|
||||
/* E_LINE_2_LONG */ "Line too long",
|
||||
/* E_LINE_2_LONG */ "",
|
||||
/* E_SWERR */ "Internal error",
|
||||
/* E_BAD_DATE */ "Bad date specification",
|
||||
/* E_2FEW_ARGS */ "Not enough arguments",
|
||||
@@ -198,7 +202,7 @@ EXTERN char *ErrMsg[]
|
||||
/* E_DAY_TWICE */ "Day specified twice",
|
||||
/* E_UNKNOWN_TOKEN */ "Unknown token",
|
||||
/* E_SPEC_MON */ "Must specify month in OMIT command",
|
||||
/* E_2MANY_PART */ "Too many partial OMITs (max. " STR(MAX_PARTIAL_OMITS) ")",
|
||||
/* E_2MANY_PART */ "",
|
||||
/* E_2MANY_FULL */ "Too many full OMITs (max. " STR(MAX_FULL_OMITS) ")",
|
||||
/* E_PUSH_NOPOP */ "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT",
|
||||
/* E_ERR_READING */ "Error reading",
|
||||
@@ -236,7 +240,7 @@ EXTERN char *ErrMsg[]
|
||||
/* E_MISS_EQ */ "Missing '=' sign",
|
||||
/* E_MISS_VAR */ "Missing variable name",
|
||||
/* E_MISS_EXPR */ "Missing expression",
|
||||
/* M_CANTSET_ACCESS */ "Can't reset access date of %s\n",
|
||||
/* M_CANTSET_ACCESS */ "",
|
||||
/* M_I_OPTION */ "Remind: '-i' option: %s\n",
|
||||
/* E_NOREMINDERS */ "No reminders.",
|
||||
/* M_QUEUED */ "%d reminder(s) queued for later today.\n",
|
||||
@@ -255,3 +259,9 @@ EXTERN char *ErrMsg[]
|
||||
#endif /* MK_GLOBALS */
|
||||
;
|
||||
#endif /* L_ERR_OVERRIDE */
|
||||
|
||||
EXTERN int NumErrs
|
||||
#ifdef MK_GLOBALS
|
||||
= sizeof(ErrMsg) / sizeof(ErrMsg[0])
|
||||
#endif
|
||||
;
|
||||
|
||||
82
src/expr.c
82
src/expr.c
@@ -282,7 +282,7 @@ debug_evaluation(Value *ans, int r, char const *fmt, ...)
|
||||
vfprintf(ErrFp, fmt, argptr);
|
||||
fprintf(ErrFp, " => ");
|
||||
if (r != OK) {
|
||||
fprintf(ErrFp, "%s\n", ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s\n", GetErr(r));
|
||||
} else {
|
||||
PrintValue(ans, ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
@@ -321,7 +321,7 @@ debug_evaluation_binop(Value *ans, int r, Value *v1, Value *v2, char const *fmt,
|
||||
}
|
||||
fprintf(ErrFp, " => ");
|
||||
if (r != OK) {
|
||||
fprintf(ErrFp, "%s\n", ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s\n", GetErr(r));
|
||||
} else {
|
||||
PrintValue(ans, ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
@@ -353,7 +353,7 @@ debug_evaluation_unop(Value *ans, int r, Value *v1, char const *fmt, ...)
|
||||
}
|
||||
fprintf(ErrFp, " => ");
|
||||
if (r != OK) {
|
||||
fprintf(ErrFp, "%s\n", ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s\n", GetErr(r));
|
||||
} else {
|
||||
PrintValue(ans, ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
@@ -426,11 +426,11 @@ eval_builtin(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
/* Check that we have the right number of argumens */
|
||||
if (node->num_kids < f->minargs) {
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2FEW_ARGS]);
|
||||
Eprint("%s(): %s", f->name, GetErr(E_2FEW_ARGS));
|
||||
return E_2FEW_ARGS;
|
||||
}
|
||||
if (node->num_kids > f->maxargs && f->maxargs != NO_MAX) {
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2MANY_ARGS]);
|
||||
Eprint("%s(): %s", f->name, GetErr(E_2MANY_ARGS));
|
||||
return E_2MANY_ARGS;
|
||||
}
|
||||
|
||||
@@ -506,14 +506,14 @@ eval_builtin(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
/* Debug */
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
if (r) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s", GetErr(r));
|
||||
} else {
|
||||
PrintValue(ans, ErrFp);
|
||||
}
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
if (r != OK) {
|
||||
Eprint("%s(): %s", f->name, ErrMsg[r]);
|
||||
Eprint("%s(): %s", f->name, GetErr(r));
|
||||
}
|
||||
/* Clean up */
|
||||
if (info.args) {
|
||||
@@ -546,7 +546,7 @@ debug_enter_userfunc(expr_node *node, Value *locals, int nargs)
|
||||
} else {
|
||||
fname = node->u.value.v.str;
|
||||
}
|
||||
fprintf(ErrFp, "%s %s(", ErrMsg[E_ENTER_FUN], fname);
|
||||
fprintf(ErrFp, "%s %s(", GetErr(E_ENTER_FUN), fname);
|
||||
for (i=0; i<nargs; i++) {
|
||||
if (i) fprintf(ErrFp, ", ");
|
||||
PrintValue(&(locals[i]), ErrFp);
|
||||
@@ -572,7 +572,7 @@ debug_exit_userfunc(expr_node *node, Value *ans, int r, Value *locals, int nargs
|
||||
} else {
|
||||
fname = node->u.value.v.str;
|
||||
}
|
||||
fprintf(ErrFp, "%s %s(", ErrMsg[E_LEAVE_FUN], fname);
|
||||
fprintf(ErrFp, "%s %s(", GetErr(E_LEAVE_FUN), fname);
|
||||
for (i=0; i<nargs; i++) {
|
||||
if (i) fprintf(ErrFp, ", ");
|
||||
PrintValue(&(locals[i]), ErrFp);
|
||||
@@ -581,7 +581,7 @@ debug_exit_userfunc(expr_node *node, Value *ans, int r, Value *locals, int nargs
|
||||
if (r == OK) {
|
||||
PrintValue(ans, ErrFp);
|
||||
} else {
|
||||
fprintf(ErrFp, "%s", ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s", GetErr(r));
|
||||
}
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
@@ -621,19 +621,19 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
/* Bail if function does not exist */
|
||||
if (!f) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_UNDEF_FUNC], fname);
|
||||
Eprint("%s: `%s'", GetErr(E_UNDEF_FUNC), fname);
|
||||
return E_UNDEF_FUNC;
|
||||
}
|
||||
|
||||
/* Make sure we have the right number of arguments */
|
||||
if (node->num_kids < f->nargs) {
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, ErrMsg[E_2FEW_ARGS]));
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2FEW_ARGS]);
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, GetErr(E_2FEW_ARGS)));
|
||||
Eprint("%s(): %s", f->name, GetErr(E_2FEW_ARGS));
|
||||
return E_2FEW_ARGS;
|
||||
}
|
||||
if (node->num_kids > f->nargs) {
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, ErrMsg[E_2MANY_ARGS]));
|
||||
Eprint("%s(): %s", f->name, ErrMsg[E_2MANY_ARGS]);
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, GetErr(E_2MANY_ARGS)));
|
||||
Eprint("%s(): %s", f->name, GetErr(E_2MANY_ARGS));
|
||||
return E_2MANY_ARGS;
|
||||
}
|
||||
|
||||
@@ -643,7 +643,7 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
/* Too many args to fit on stack; put on heap */
|
||||
new_locals = malloc(node->num_kids * sizeof(Value));
|
||||
if (!new_locals) {
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, ErrMsg[E_NO_MEM]));
|
||||
DBG(fprintf(ErrFp, "%s(...) => %s\n", fname, GetErr(E_NO_MEM)));
|
||||
return E_NO_MEM;
|
||||
}
|
||||
} else {
|
||||
@@ -694,7 +694,7 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
if (r != OK) {
|
||||
/* We print the error here in order to get the call stack trace */
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
|
||||
if (pushed == OK) pop_call();
|
||||
@@ -850,7 +850,7 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
/* Operator? Evaluate it */
|
||||
r = node->u.operator_func(node, locals, ans, nonconst);
|
||||
if (r != OK) {
|
||||
Eprint("`%s': %s", get_operator_name(node), ErrMsg[r]);
|
||||
Eprint("`%s': %s", get_operator_name(node), GetErr(r));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -1541,7 +1541,7 @@ static int parse_expr_token(DynamicBuffer *buf, char const **in)
|
||||
}
|
||||
(*in)++;
|
||||
} else {
|
||||
Eprint("%s `%c' (did you mean `%c%c'?)", ErrMsg[E_PARSE_ERR], c, c, c);
|
||||
Eprint("%s `%c' (did you mean `%c%c'?)", GetErr(E_PARSE_ERR), c, c, c);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
return OK;
|
||||
@@ -1633,10 +1633,10 @@ static int parse_expr_token(DynamicBuffer *buf, char const **in)
|
||||
|
||||
if (!ISID(c) && c != '$') {
|
||||
if (!c) {
|
||||
Eprint("%s", ErrMsg[E_EOLN]);
|
||||
Eprint("%s", GetErr(E_EOLN));
|
||||
return E_EOLN;
|
||||
}
|
||||
Eprint("%s `%c'", ErrMsg[E_ILLEGAL_CHAR], c);
|
||||
Eprint("%s `%c'", GetErr(E_ILLEGAL_CHAR), c);
|
||||
return E_ILLEGAL_CHAR;
|
||||
}
|
||||
|
||||
@@ -1831,7 +1831,7 @@ static expr_node * parse_function_call(char const **e, int *r, Var *locals, int
|
||||
return free_expr_tree(node);
|
||||
}
|
||||
if (TOKEN_IS(")")) {
|
||||
Eprint("%s `)'", ErrMsg[E_PARSE_ERR]);
|
||||
Eprint("%s `)'", GetErr(E_PARSE_ERR));
|
||||
*r = E_PARSE_ERR;
|
||||
return free_expr_tree(node);
|
||||
}
|
||||
@@ -1859,7 +1859,7 @@ static expr_node * parse_function_call(char const **e, int *r, Var *locals, int
|
||||
if (*r != OK) {
|
||||
if (node->type == N_BUILTIN_FUNC) {
|
||||
f = node->u.builtin_func;
|
||||
Eprint("%s: %s", f->name, ErrMsg[*r]);
|
||||
Eprint("%s: %s", f->name, GetErr(*r));
|
||||
}
|
||||
return free_expr_tree(node);
|
||||
}
|
||||
@@ -1881,7 +1881,7 @@ static int set_constant_value(expr_node *atom)
|
||||
atom->type = N_CONSTANT;
|
||||
|
||||
if (!*s) {
|
||||
Eprint("%s", ErrMsg[E_EOLN]);
|
||||
Eprint("%s", GetErr(E_EOLN));
|
||||
return E_EOLN;
|
||||
}
|
||||
ampm = 0;
|
||||
@@ -1905,15 +1905,15 @@ static int set_constant_value(expr_node *atom)
|
||||
} else if (*s == '\'') { /* It's a literal date */
|
||||
s++;
|
||||
if ((r=ParseLiteralDateOrTime(&s, &dse, &tim)) != 0) {
|
||||
Eprint("%s: %s", ErrMsg[r], DBufValue(&ExprBuf));
|
||||
Eprint("%s: %s", GetErr(r), DBufValue(&ExprBuf));
|
||||
return r;
|
||||
}
|
||||
if (*s != '\'') {
|
||||
if (dse != NO_DATE) {
|
||||
Eprint("%s: %s", ErrMsg[E_BAD_DATE], DBufValue(&ExprBuf));
|
||||
Eprint("%s: %s", GetErr(E_BAD_DATE), DBufValue(&ExprBuf));
|
||||
return E_BAD_DATE;
|
||||
} else {
|
||||
Eprint("%s: %s", ErrMsg[E_BAD_TIME], DBufValue(&ExprBuf));
|
||||
Eprint("%s: %s", GetErr(E_BAD_TIME), DBufValue(&ExprBuf));
|
||||
return E_BAD_TIME;
|
||||
}
|
||||
}
|
||||
@@ -1944,7 +1944,7 @@ static int set_constant_value(expr_node *atom)
|
||||
if (*s == ':' || *s == '.' || *s == TimeSep) { /* Must be a literal time */
|
||||
s++;
|
||||
if (!isdigit(*s)) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_BAD_TIME], DBufValue(&ExprBuf));
|
||||
Eprint("%s: `%s'", GetErr(E_BAD_TIME), DBufValue(&ExprBuf));
|
||||
return E_BAD_TIME;
|
||||
}
|
||||
h = val;
|
||||
@@ -1963,12 +1963,12 @@ static int set_constant_value(expr_node *atom)
|
||||
}
|
||||
}
|
||||
if (*s || h>23 || m>59) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_BAD_TIME], DBufValue(&ExprBuf));
|
||||
Eprint("%s: `%s'", GetErr(E_BAD_TIME), DBufValue(&ExprBuf));
|
||||
return E_BAD_TIME;
|
||||
}
|
||||
if (ampm) {
|
||||
if (h < 1 || h > 12) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_BAD_TIME], DBufValue(&ExprBuf));
|
||||
Eprint("%s: `%s'", GetErr(E_BAD_TIME), DBufValue(&ExprBuf));
|
||||
return E_BAD_TIME;
|
||||
}
|
||||
if (ampm == 'a') {
|
||||
@@ -1987,7 +1987,7 @@ static int set_constant_value(expr_node *atom)
|
||||
}
|
||||
/* Not a time - must be a number */
|
||||
if (*s) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_BAD_NUMBER], DBufValue(&ExprBuf));
|
||||
Eprint("%s: `%s'", GetErr(E_BAD_NUMBER), DBufValue(&ExprBuf));
|
||||
return E_BAD_NUMBER;
|
||||
}
|
||||
atom->u.value.type = INT_TYPE;
|
||||
@@ -1995,7 +1995,7 @@ static int set_constant_value(expr_node *atom)
|
||||
return OK;
|
||||
}
|
||||
atom->u.value.type = ERR_TYPE;
|
||||
Eprint("`%s': %s", DBufValue(&ExprBuf), ErrMsg[E_ILLEGAL_CHAR]);
|
||||
Eprint("`%s': %s", DBufValue(&ExprBuf), GetErr(E_ILLEGAL_CHAR));
|
||||
return E_ILLEGAL_CHAR;
|
||||
}
|
||||
|
||||
@@ -2019,7 +2019,7 @@ static int make_atom(expr_node *atom, Var *locals)
|
||||
atom->u.arg = i;
|
||||
return OK;
|
||||
}
|
||||
v = v->next;
|
||||
v = v->link.next;
|
||||
i++;
|
||||
}
|
||||
if (strlen(s) < SHORT_NAME_BUF) {
|
||||
@@ -2037,7 +2037,7 @@ static int make_atom(expr_node *atom, Var *locals)
|
||||
/* System Variable */
|
||||
if (*(s) == '$' && isalpha(*(s+1))) {
|
||||
if (!FindSysVar(s+1)) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_NOSUCH_VAR], s);
|
||||
Eprint("%s: `%s'", GetErr(E_NOSUCH_VAR), s);
|
||||
return E_NOSUCH_VAR;
|
||||
}
|
||||
if (strlen(s+1) < SHORT_NAME_BUF) {
|
||||
@@ -2117,7 +2117,7 @@ static expr_node *parse_atom(char const **e, int *r, Var *locals, int level)
|
||||
/* Check that it's a valid ID or constant */
|
||||
s = DBufValue(&ExprBuf);
|
||||
if (!*s) {
|
||||
Eprint("%s", ErrMsg[E_EOLN]);
|
||||
Eprint("%s", GetErr(E_EOLN));
|
||||
*r = E_EOLN;
|
||||
return NULL;
|
||||
}
|
||||
@@ -2126,7 +2126,7 @@ static expr_node *parse_atom(char const **e, int *r, Var *locals, int level)
|
||||
*s != '$' &&
|
||||
*s != '"' &&
|
||||
*s != '\'') {
|
||||
Eprint("%s `%c'", ErrMsg[E_ILLEGAL_CHAR], *s);
|
||||
Eprint("%s `%c'", GetErr(E_ILLEGAL_CHAR), *s);
|
||||
*r = E_ILLEGAL_CHAR;
|
||||
return NULL;
|
||||
}
|
||||
@@ -2512,7 +2512,7 @@ expr_node *parse_expression(char const **e, int *r, Var *locals)
|
||||
}
|
||||
putc('\n', ErrFp);
|
||||
if (*r != OK) {
|
||||
fprintf(ErrFp, " => Error: %s\n", ErrMsg[*r]);
|
||||
fprintf(ErrFp, " => Error: %s\n", GetErr(*r));
|
||||
} else {
|
||||
fprintf(ErrFp, " => ");
|
||||
print_expr_tree(node, ErrFp);
|
||||
@@ -3088,10 +3088,10 @@ int DoCoerce(char type, Value *v)
|
||||
/***************************************************************/
|
||||
void print_expr_nodes_stats(void)
|
||||
{
|
||||
fprintf(stderr, " Expression nodes allocated: %d\n", ExprNodesAllocated);
|
||||
fprintf(stderr, "Expression nodes high-water: %d\n", ExprNodesHighWater);
|
||||
fprintf(stderr, " Expression nodes leaked: %d\n", ExprNodesUsed);
|
||||
fprintf(stderr, " Parse level high-water: %d\n", parse_level_high_water);
|
||||
fprintf(ErrFp, " Expression nodes allocated: %d\n", ExprNodesAllocated);
|
||||
fprintf(ErrFp, "Expression nodes high-water: %d\n", ExprNodesHighWater);
|
||||
fprintf(ErrFp, " Expression nodes leaked: %d\n", ExprNodesUsed);
|
||||
fprintf(ErrFp, " Parse level high-water: %d\n", parse_level_high_water);
|
||||
}
|
||||
|
||||
/* Return 1 if a value is "true" for its type, 0 if "false" */
|
||||
|
||||
67
src/files.c
67
src/files.c
@@ -519,7 +519,7 @@ static int NextChainedFile(IncludeStruct *i)
|
||||
if (OpenFile(cur->filename) == OK) {
|
||||
return OK;
|
||||
} else {
|
||||
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], cur->filename);
|
||||
Eprint("%s: %s", GetErr(E_CANT_OPEN), cur->filename);
|
||||
}
|
||||
}
|
||||
return E_EOF;
|
||||
@@ -537,7 +537,7 @@ static int PopFile(void)
|
||||
int j;
|
||||
|
||||
if (!Hush && NumIfs) {
|
||||
Eprint("%s", ErrMsg[E_MISS_ENDIF]);
|
||||
Eprint("%s", GetErr(E_MISS_ENDIF));
|
||||
for (j=NumIfs-1; j >=0; j--) {
|
||||
fprintf(ErrFp, "%s(%d): IF without ENDIF\n", FileName, IfLinenos[j]);
|
||||
}
|
||||
@@ -608,16 +608,25 @@ int DoInclude(ParsePtr p, enum TokTypes tok)
|
||||
DBufInit(&buf);
|
||||
DBufInit(&fullname);
|
||||
DBufInit(&path);
|
||||
if ( (r=ParseToken(p, &buf)) ) return r;
|
||||
if ( (r=ParseTokenOrQuotedString(p, &buf)) ) return r;
|
||||
e = VerifyEoln(p);
|
||||
if (e) Eprint("%s", ErrMsg[e]);
|
||||
if (e) Eprint("%s", GetErr(e));
|
||||
|
||||
if (tok == T_IncludeR && *(DBufValue(&buf)) != '/') {
|
||||
if ((tok == T_IncludeR || tok == T_IncludeSys) &&
|
||||
*(DBufValue(&buf)) != '/') {
|
||||
/* Relative include: Include relative to dir
|
||||
containing current file */
|
||||
if (DBufPuts(&path, FileName) != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto bailout;
|
||||
if (tok == T_IncludeR) {
|
||||
if (DBufPuts(&path, FileName) != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto bailout;
|
||||
}
|
||||
} else {
|
||||
if (DBufPuts(&path, SysDir) != OK ||
|
||||
DBufPutc(&path, '/') != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto bailout;
|
||||
}
|
||||
}
|
||||
if (DBufLen(&path) == 0) {
|
||||
s = DBufValue(&buf);
|
||||
@@ -650,9 +659,6 @@ int DoInclude(ParsePtr p, enum TokTypes tok)
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
|
||||
bailout:
|
||||
DBufFree(&buf);
|
||||
DBufFree(&path);
|
||||
@@ -713,8 +719,6 @@ int DoIncludeCmd(ParsePtr p)
|
||||
return r;
|
||||
}
|
||||
DBufFree(&buf);
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -726,6 +730,8 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
size_t l;
|
||||
int r;
|
||||
glob_t glob_buf;
|
||||
struct stat sb;
|
||||
|
||||
DirectoryFilenameChain *dc = CachedDirectoryChains;
|
||||
|
||||
i->chain = NULL;
|
||||
@@ -808,6 +814,16 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
|
||||
/* Add the files to the chain backwards to preserve sort order */
|
||||
for (r=glob_buf.gl_pathc-1; r>=0; r--) {
|
||||
if (stat(glob_buf.gl_pathv[r], &sb) < 0) {
|
||||
/* Couldn't stat the file... fuggedaboutit */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Don't add directories */
|
||||
if (S_ISDIR(sb.st_mode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FilenameChain *ch = malloc(sizeof(FilenameChain));
|
||||
if (!ch) {
|
||||
globfree(&glob_buf);
|
||||
@@ -816,8 +832,6 @@ static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
/* TODO: stat the file and only add if it's a plain file and
|
||||
readable by us */
|
||||
ch->filename = StrDup(glob_buf.gl_pathv[r]);
|
||||
if (!ch->filename) {
|
||||
globfree(&glob_buf);
|
||||
@@ -858,7 +872,7 @@ static int IncludeCmd(char const *cmd)
|
||||
|
||||
got_a_fresh_line();
|
||||
clear_callstack();
|
||||
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
if (IStackPtr >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
/* Use "cmd|" as the filename */
|
||||
@@ -895,6 +909,8 @@ static int IncludeCmd(char const *cmd)
|
||||
FCLOSE(fp);
|
||||
}
|
||||
IStackPtr++;
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
|
||||
/* If the file is cached, use it */
|
||||
h = CachedFiles;
|
||||
@@ -931,6 +947,7 @@ static int IncludeCmd(char const *cmd)
|
||||
fp2 = popen(cmd, "r");
|
||||
}
|
||||
if (!fp2) {
|
||||
PopFile();
|
||||
DBufFree(&buf);
|
||||
return E_CANT_OPEN;
|
||||
}
|
||||
@@ -977,7 +994,7 @@ int IncludeFile(char const *fname)
|
||||
|
||||
got_a_fresh_line();
|
||||
clear_callstack();
|
||||
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
if (IStackPtr >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
if (FileName) {
|
||||
@@ -1004,6 +1021,8 @@ int IncludeFile(char const *fname)
|
||||
}
|
||||
|
||||
IStackPtr++;
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
|
||||
#ifdef HAVE_GLOB
|
||||
/* If it's a directory, set up the glob chain here. */
|
||||
@@ -1018,7 +1037,7 @@ int IncludeFile(char const *fname)
|
||||
if (SetupGlobChain(fname, i) == OK) { /* Glob succeeded */
|
||||
if (!i->chain) { /* Oops... no matching files */
|
||||
if (!Hush) {
|
||||
Eprint("%s: %s", fname, ErrMsg[E_NO_MATCHING_REMS]);
|
||||
Eprint("%s: %s", fname, GetErr(E_NO_MATCHING_REMS));
|
||||
}
|
||||
PopFile();
|
||||
return E_NO_MATCHING_REMS;
|
||||
@@ -1032,14 +1051,14 @@ int IncludeFile(char const *fname)
|
||||
if (!OpenFile(fc->filename)) {
|
||||
return OK;
|
||||
}
|
||||
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], fc->filename);
|
||||
Eprint("%s: %s", GetErr(E_CANT_OPEN), fc->filename);
|
||||
RunDisabled = oldRunDisabled;
|
||||
}
|
||||
/* Couldn't open anything... bail */
|
||||
return PopFile();
|
||||
} else {
|
||||
if (!Hush) {
|
||||
Eprint("%s: %s", fname, ErrMsg[E_NO_MATCHING_REMS]);
|
||||
Eprint("%s: %s", fname, GetErr(E_NO_MATCHING_REMS));
|
||||
}
|
||||
}
|
||||
return E_NO_MATCHING_REMS;
|
||||
@@ -1053,7 +1072,7 @@ int IncludeFile(char const *fname)
|
||||
return OK;
|
||||
}
|
||||
RunDisabled = oldRunDisabled;
|
||||
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], fname);
|
||||
Eprint("%s: %s", GetErr(E_CANT_OPEN), fname);
|
||||
/* Ugh! We failed! */
|
||||
PopFile();
|
||||
return E_CANT_OPEN;
|
||||
@@ -1149,6 +1168,12 @@ static int CheckSafety(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CheckSafetyAux(&statbuf)) {
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
|
||||
55
src/funcs.c
55
src/funcs.c
@@ -68,6 +68,7 @@ static int
|
||||
solstice_equinox_for_year(int y, int which);
|
||||
|
||||
/* Function prototypes */
|
||||
static int F_ (func_info *);
|
||||
static int FADawn (func_info *);
|
||||
static int FADusk (func_info *);
|
||||
static int FAbs (func_info *);
|
||||
@@ -210,8 +211,8 @@ static int CacheHebYear, CacheHebMon, CacheHebDay;
|
||||
/* Macro for getting time part of a time or datetime value */
|
||||
#define TIMEPART(x) ((x).type == TIME_TYPE ? (x).v.val : ((x).v.val % MINUTES_PER_DAY))
|
||||
|
||||
#define HASDATE(x) ((x).type == DATE_TYPE || (x).type == DATETIME_TYPE)
|
||||
#define HASTIME(x) ((x).type == TIME_TYPE || (x).type == DATETIME_TYPE)
|
||||
#define HASDATE(x) ((x).type & DATE_TYPE)
|
||||
#define HASTIME(x) ((x).type & TIME_TYPE)
|
||||
|
||||
/* Macro for copying a value while destroying original copy */
|
||||
#define DCOPYVAL(x, y) ( (x) = (y), (y).type = ERR_TYPE )
|
||||
@@ -226,7 +227,7 @@ static int CacheHebYear, CacheHebMon, CacheHebDay;
|
||||
/* The array holding the built-in functions. */
|
||||
BuiltinFunc Func[] = {
|
||||
/* Name minargs maxargs is_constant func newfunc*/
|
||||
|
||||
{ "_", 1, 1, 0, F_, NULL },
|
||||
{ "abs", 1, 1, 1, FAbs, NULL },
|
||||
{ "access", 2, 2, 0, FAccess, NULL },
|
||||
{ "adawn", 0, 1, 0, FADawn, NULL},
|
||||
@@ -372,6 +373,28 @@ static int RetStrVal(char const *s, func_info *info)
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* F_ - look up a string in the translation table */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int F_(func_info *info)
|
||||
{
|
||||
DynamicBuffer translated;
|
||||
int r;
|
||||
|
||||
DBufInit(&translated);
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
r = GetTranslatedStringTryingVariants(ARGSTR(0), &translated);
|
||||
if (!r) {
|
||||
DCOPYVAL(RetVal, ARG(0));
|
||||
return OK;
|
||||
}
|
||||
r = RetStrVal(DBufValue(&translated), info);
|
||||
DBufFree(&translated);
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FStrlen - string length */
|
||||
@@ -1281,10 +1304,10 @@ static int FChoose(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
cur = cur->sibling;
|
||||
}
|
||||
PUT(") => ");
|
||||
PUT(ErrMsg[E_BAD_TYPE]);
|
||||
PUT(GetErr(E_BAD_TYPE));
|
||||
OUT();
|
||||
}
|
||||
Eprint("choose(): %s", ErrMsg[E_BAD_TYPE]);
|
||||
Eprint("choose(): %s", GetErr(E_BAD_TYPE));
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
n = v.v.val;
|
||||
@@ -1802,10 +1825,10 @@ static int FTrigger(func_info *info)
|
||||
|
||||
FromDSE(date, &y, &m, &d);
|
||||
if (tim != NO_TIME) {
|
||||
sprintf(buf, "%d %s %d AT %02d:%02d", d, EnglishMonthName[m], y,
|
||||
sprintf(buf, "%d %s %d AT %02d:%02d", d, MonthName[m], y,
|
||||
tim/60, tim%60);
|
||||
} else {
|
||||
sprintf(buf, "%d %s %d", d, EnglishMonthName[m], y);
|
||||
sprintf(buf, "%d %s %d", d, MonthName[m], y);
|
||||
}
|
||||
return RetStrVal(buf, info);
|
||||
}
|
||||
@@ -1995,7 +2018,7 @@ static int FIif(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
cur = cur->sibling;
|
||||
}
|
||||
PUT(") => ");
|
||||
PUT(ErrMsg[E_IIF_ODD]);
|
||||
PUT(GetErr(E_IIF_ODD));
|
||||
OUT();
|
||||
}
|
||||
return E_IIF_ODD;
|
||||
@@ -2153,7 +2176,7 @@ static int FTypeof(func_info *info)
|
||||
/***************************************************************/
|
||||
static int FLanguage(func_info *info)
|
||||
{
|
||||
return RetStrVal(L_LANGNAME, info);
|
||||
return RetStrVal("English", info);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -2734,7 +2757,7 @@ static int SunStuff(int rise, double cosz, int dse)
|
||||
/* Get offset from UTC */
|
||||
if (CalculateUTC) {
|
||||
if (CalcMinsFromUTC(dse, 12*60, &mins, NULL)) {
|
||||
Eprint(ErrMsg[E_MKTIME_PROBLEM]);
|
||||
Eprint(GetErr(E_MKTIME_PROBLEM));
|
||||
return NO_TIME;
|
||||
}
|
||||
} else mins = MinsFromUTC;
|
||||
@@ -2756,7 +2779,7 @@ static int SunStuff(int rise, double cosz, int dse)
|
||||
/* Mean anomaly of sun starting from 1 Jan 1990 */
|
||||
/* NOTE: This assumes that BASE = 1990!!! */
|
||||
#if BASE != 1990
|
||||
#error Sun calculations assume a BASE of 1990!
|
||||
#warning Sun calculations assume a BASE of 1990!
|
||||
#endif
|
||||
t = 0.9856002585 * t;
|
||||
M = t + 357.828757; /* In degrees */
|
||||
@@ -2839,6 +2862,10 @@ static int FSun(int rise, func_info *info)
|
||||
double cosz = 0.0;
|
||||
int r;
|
||||
|
||||
/* Sun calculations assume BASE is 1990 */
|
||||
if (BASE != 1990) {
|
||||
return E_SWERR;
|
||||
}
|
||||
if (rise == 0 || rise == 1) {
|
||||
/* Sunrise and sunset : cos(90 degrees + 50 arcminutes) */
|
||||
cosz = -0.01454389765158243;
|
||||
@@ -3238,11 +3265,11 @@ static int setenv(char const *varname, char const *val, int overwrite)
|
||||
{
|
||||
static char tzbuf[256];
|
||||
if (strcmp(varname, "TZ")) {
|
||||
fprintf(stderr, "built-in setenv can only be used with TZ\n");
|
||||
fprintf(ErrFp, "built-in setenv can only be used with TZ\n");
|
||||
abort();
|
||||
}
|
||||
if (!overwrite) {
|
||||
fprintf(stderr, "built-in setenv must have overwrite=1\n");
|
||||
fprintf(ErrFp, "built-in setenv must have overwrite=1\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -3260,7 +3287,7 @@ static void unsetenv(char const *varname)
|
||||
{
|
||||
static char tzbuf[8];
|
||||
if (strcmp(varname, "TZ")) {
|
||||
fprintf(stderr, "built-in unsetenv can only be used with TZ\n");
|
||||
fprintf(ErrFp, "built-in unsetenv can only be used with TZ\n");
|
||||
abort();
|
||||
}
|
||||
sprintf(tzbuf, "%s", varname);
|
||||
|
||||
@@ -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"
|
||||
|
||||
121
src/globals.h
121
src/globals.h
@@ -30,7 +30,6 @@
|
||||
EXTERN FILE *ErrFp;
|
||||
|
||||
#include "dynbuf.h"
|
||||
#include "lang.h"
|
||||
|
||||
#define MAX_TRUSTED_USERS 20
|
||||
|
||||
@@ -179,62 +178,17 @@ EXTERN INIT( int SuppressImplicitRemWarnings, 0);
|
||||
extern int NumFullOmits, NumPartialOmits;
|
||||
|
||||
/* List of months */
|
||||
EXTERN char *EnglishMonthName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"}
|
||||
#endif
|
||||
;
|
||||
|
||||
#if LANG == ENGLISH
|
||||
#define MonthName EnglishMonthName
|
||||
#else
|
||||
EXTERN char *MonthName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {L_JAN, L_FEB, L_MAR, L_APR, L_MAY, L_JUN,
|
||||
L_JUL, L_AUG, L_SEP, L_OCT, L_NOV, L_DEC}
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
|
||||
EXTERN char *DynamicMonthName[]
|
||||
#ifdef MK_GLOBALS
|
||||
#if LANG == ENGLISH
|
||||
= {"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"}
|
||||
#else
|
||||
= {L_JAN, L_FEB, L_MAR, L_APR, L_MAY, L_JUN,
|
||||
L_JUL, L_AUG, L_SEP, L_OCT, L_NOV, L_DEC}
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
EXTERN char *EnglishDayName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
|
||||
"Saturday", "Sunday"}
|
||||
#endif
|
||||
;
|
||||
|
||||
#if LANG == ENGLISH
|
||||
#define DayName EnglishDayName
|
||||
#else
|
||||
EXTERN char *DayName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {L_MONDAY, L_TUESDAY, L_WEDNESDAY, L_THURSDAY, L_FRIDAY,
|
||||
L_SATURDAY, L_SUNDAY}
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
|
||||
EXTERN char *DynamicDayName []
|
||||
#ifdef MK_GLOBALS
|
||||
#if LANG == ENGLISH
|
||||
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
|
||||
"Saturday", "Sunday"}
|
||||
#else
|
||||
= {L_MONDAY, L_TUESDAY, L_WEDNESDAY, L_THURSDAY, L_FRIDAY,
|
||||
L_SATURDAY, L_SUNDAY}
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
|
||||
@@ -256,84 +210,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
|
||||
;
|
||||
|
||||
|
||||
454
src/hashtab.c
Normal file
454
src/hashtab.c
Normal file
@@ -0,0 +1,454 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HASHTAB_STATS.C */
|
||||
/* */
|
||||
/* Implementation of hash table. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 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 Find the next item in a hash table
|
||||
*
|
||||
* \param t Pointer to a hash table object
|
||||
* \param obj Pointer to an object that was perviously returned by
|
||||
* hash_table_find() or hash_table_find_next().
|
||||
*
|
||||
* \return A pointer to the next object matching obj, or NULL if
|
||||
* no more exist
|
||||
*/
|
||||
void *
|
||||
hash_table_find_next(hash_table *t, void *obj)
|
||||
{
|
||||
if (!obj) {
|
||||
return NULL;
|
||||
}
|
||||
void *ptr = LINK(t, obj)->next;
|
||||
while(ptr) {
|
||||
if (!t->compare(obj, 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;
|
||||
}
|
||||
116
src/hashtab.h
Normal file
116
src/hashtab.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HASHTAB.H */
|
||||
/* */
|
||||
/* Header file for hash-table related functions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 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);
|
||||
void *hash_table_find_next(hash_table *t, void *obj);
|
||||
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)))
|
||||
|
||||
/**
|
||||
* \brief Iterate over all items in a hash table that match a candidate
|
||||
*
|
||||
* This macro iterates over all items in a hash table that match a
|
||||
* candidate object. (In general, a hash table may contain multiple
|
||||
* objects with the same key.) Here is an example assuming that the hash
|
||||
* table holds objects of type struct int_object:
|
||||
*
|
||||
* struct int_object {
|
||||
* int value;
|
||||
* struct hash_link link;
|
||||
* }
|
||||
*
|
||||
* hash_table tab;
|
||||
* int_object candidate;
|
||||
*
|
||||
* candidate.value = 7;
|
||||
* int_object *item;
|
||||
* hash_table_for_each_matching(item, &candidate, &tab) {
|
||||
* // Do something with item, which will match "7"
|
||||
* }
|
||||
*/
|
||||
#define hash_table_for_each_matching(item, candidate, t) \
|
||||
for ((item) = hash_table_find((t), (candidate)); \
|
||||
(item); \
|
||||
(item) = hash_table_find_next((t), (item)))
|
||||
99
src/hashtab_stats.c
Normal file
99
src/hashtab_stats.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HASHTAB_STATS.C */
|
||||
/* */
|
||||
/* Utility function to print hash table stats. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
78
src/init.c
78
src/init.c
@@ -149,7 +149,7 @@ static char const *DefaultFilename(void)
|
||||
|
||||
s = getenv("HOME");
|
||||
if (!s) {
|
||||
fprintf(stderr, "HOME environment variable not set. Unable to determine reminder file.\n");
|
||||
fprintf(ErrFp, "HOME environment variable not set. Unable to determine reminder file.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
DBufPuts(&default_filename_buf, s);
|
||||
@@ -179,6 +179,14 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
dse = NO_DATE;
|
||||
|
||||
/* Initialize variable hash table */
|
||||
InitVars();
|
||||
|
||||
/* Initialize user-defined functions hash table */
|
||||
InitUserFunctions();
|
||||
|
||||
InitTranslationTable();
|
||||
|
||||
/* If stdout is a terminal, initialize $FormWidth to terminal width-8,
|
||||
but clamp to [20, 500] */
|
||||
InitCalWidthAndFormWidth(STDOUT_FILENO);
|
||||
@@ -188,7 +196,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
DBufInit(&LineBuffer);
|
||||
DBufInit(&ExprBuf);
|
||||
|
||||
DBufPuts(&Banner, L_BANNER);
|
||||
DBufPuts(&Banner, "Reminders for %w, %d%s %m, %y%o:");
|
||||
|
||||
PurgeFP = NULL;
|
||||
|
||||
@@ -208,7 +216,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
RealToday = SystemDate(&CurYear, &CurMon, &CurDay);
|
||||
if (RealToday < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_SYS_DATE], BASE);
|
||||
fprintf(ErrFp, GetErr(M_BAD_SYS_DATE), BASE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
DSEToday = RealToday;
|
||||
@@ -229,7 +237,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
InvokedAsRem = 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Invoked with a NULL argv[0]; bailing because that's just plain bizarre.\n");
|
||||
fprintf(ErrFp, "Invoked with a NULL argv[0]; bailing because that's just plain bizarre.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -569,7 +577,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);
|
||||
@@ -617,7 +625,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
case 'l': case 'L': DebugFlag |= DB_PRTLINE; break;
|
||||
case 'f': case 'F': DebugFlag |= DB_TRACE_FILES; break;
|
||||
default:
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_DB_FLAG], *(arg-1));
|
||||
fprintf(ErrFp, GetErr(M_BAD_DB_FLAG), *(arg-1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -652,7 +660,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_OPTION], *(arg-1));
|
||||
fprintf(ErrFp, GetErr(M_BAD_OPTION), *(arg-1));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -720,7 +728,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
|
||||
default:
|
||||
if (tok.type == T_Illegal && tok.val < 0) {
|
||||
fprintf(stderr, "%s: `%s'\n", ErrMsg[-tok.val], arg);
|
||||
fprintf(ErrFp, "%s: `%s'\n", GetErr(-tok.val), arg);
|
||||
Usage();
|
||||
}
|
||||
Usage();
|
||||
@@ -782,7 +790,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 1992-2024 Dianne Skoll\n", VERSION);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
@@ -844,7 +852,7 @@ static void ChgUser(char const *user)
|
||||
pwent = getpwnam(user);
|
||||
|
||||
if (!pwent) {
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_USER], user);
|
||||
fprintf(ErrFp, GetErr(M_BAD_USER), user);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -852,24 +860,24 @@ static void ChgUser(char const *user)
|
||||
/* Started as root, so drop privileges */
|
||||
#ifdef HAVE_INITGROUPS
|
||||
if (initgroups(pwent->pw_name, pwent->pw_gid) < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_GID], pwent->pw_gid);
|
||||
fprintf(ErrFp, GetErr(M_NO_CHG_GID), pwent->pw_gid);
|
||||
exit(EXIT_FAILURE);
|
||||
};
|
||||
#endif
|
||||
if (setgid(pwent->pw_gid) < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_GID], pwent->pw_gid);
|
||||
fprintf(ErrFp, GetErr(M_NO_CHG_GID), pwent->pw_gid);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (setuid(pwent->pw_uid) < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_UID], pwent->pw_uid);
|
||||
fprintf(ErrFp, GetErr(M_NO_CHG_UID), pwent->pw_uid);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
home = malloc(strlen(pwent->pw_dir) + 6);
|
||||
if (!home) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", GetErr(M_NOMEM_ENV));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(home, "HOME=%s", pwent->pw_dir);
|
||||
@@ -877,7 +885,7 @@ static void ChgUser(char const *user)
|
||||
|
||||
shell = malloc(strlen(pwent->pw_shell) + 7);
|
||||
if (!shell) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", GetErr(M_NOMEM_ENV));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(shell, "SHELL=%s", pwent->pw_shell);
|
||||
@@ -886,14 +894,14 @@ static void ChgUser(char const *user)
|
||||
if (pwent->pw_uid) {
|
||||
username = malloc(strlen(pwent->pw_name) + 6);
|
||||
if (!username) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", GetErr(M_NOMEM_ENV));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(username, "USER=%s", pwent->pw_name);
|
||||
putenv(username);
|
||||
logname= malloc(strlen(pwent->pw_name) + 9);
|
||||
if (!logname) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", GetErr(M_NOMEM_ENV));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sprintf(logname, "LOGNAME=%s", pwent->pw_name);
|
||||
@@ -911,7 +919,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 +946,7 @@ static void InitializeVar(char const *str)
|
||||
if (isalpha(*str) || *str == '_' || (r > 0 && *str == '(') || (r == 0 && *str == '$') || (r > 0 && isdigit(*str))) {
|
||||
varname[r++] = *str;
|
||||
} else {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_ILLEGAL_CHAR]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_ILLEGAL_CHAR));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -951,13 +959,13 @@ static void InitializeVar(char const *str)
|
||||
}
|
||||
varname[r] = 0;
|
||||
if (!*varname) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_VAR]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_VAR));
|
||||
return;
|
||||
}
|
||||
if (!*str) {
|
||||
/* Setting a system var does require =expr on the commandline */
|
||||
if (*varname == '$') {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_EQ]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_EQ));
|
||||
return;
|
||||
}
|
||||
val.type = INT_TYPE;
|
||||
@@ -967,41 +975,41 @@ static void InitializeVar(char const *str)
|
||||
r = PreserveVar(varname);
|
||||
}
|
||||
if (r) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*varname) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_VAR]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_VAR));
|
||||
return;
|
||||
}
|
||||
expr = str+1;
|
||||
if (!*expr) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_EXPR]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(E_MISS_EXPR));
|
||||
return;
|
||||
}
|
||||
|
||||
r=EvalExpr(&expr, &val, NULL);
|
||||
if (r) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*varname == '$') {
|
||||
r=SetSysVar(varname+1, &val);
|
||||
DestroyValue(val);
|
||||
if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
if (r) fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
return;
|
||||
}
|
||||
|
||||
r=SetVar(varname, &val);
|
||||
if (r) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
return;
|
||||
}
|
||||
r=PreserveVar(varname);
|
||||
if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
if (r) fprintf(ErrFp, GetErr(M_I_OPTION), GetErr(r));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1010,14 +1018,14 @@ AddTrustedUser(char const *username)
|
||||
{
|
||||
struct passwd *pwent;
|
||||
if (NumTrustedUsers >= MAX_TRUSTED_USERS) {
|
||||
fprintf(stderr, "Too many trusted users (%d max)\n",
|
||||
fprintf(ErrFp, "Too many trusted users (%d max)\n",
|
||||
MAX_TRUSTED_USERS);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pwent = getpwnam(username);
|
||||
if (!pwent) {
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_USER], username);
|
||||
fprintf(ErrFp, GetErr(M_BAD_USER), username);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
TrustedUsers[NumTrustedUsers] = pwent->pw_uid;
|
||||
@@ -1077,6 +1085,16 @@ ProcessLongOption(char const *arg)
|
||||
printf("%s\n", CONFIG_CMD);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
if (!strcmp(arg, "print-errs")) {
|
||||
for (t=0; t<NumErrs; t++) {
|
||||
if (*ErrMsg[t]) {
|
||||
print_escaped_string(stdout, ErrMsg[t]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (!strcmp(arg, "print-tokens")) {
|
||||
print_remind_tokens();
|
||||
print_builtinfunc_tokens();
|
||||
|
||||
78
src/lang.h
78
src/lang.h
@@ -1,78 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* LANG.H */
|
||||
/* */
|
||||
/* Header file for language support for various languages. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* I'm chauvinistic and name each language with its English name... */
|
||||
|
||||
#define ENGLISH 0 /* original by Dianne Skoll */
|
||||
#define GERMAN 1 /* translated by Wolfgang Thronicke */
|
||||
#define DUTCH 2 /* translated by Willem Kasdorp and Erik-Jan Vens */
|
||||
#define FINNISH 3 /* translated by Mikko Silvonen */
|
||||
#define FRENCH 4 /* translated by Laurent Duperval */
|
||||
#define NORWEGIAN 5 /* translated by Trygve Randen */
|
||||
#define DANISH 6 /* translated by Mogens Lynnerup */
|
||||
#define POLISH 7 /* translated by Jerzy Sobczyk */
|
||||
#define BRAZPORT 8 /* Brazilian Portuguese by Marco Paganini */
|
||||
#define ITALIAN 9 /* translated by Valerio Aimale */
|
||||
#define ROMANIAN 10 /* translated by Liviu Daia */
|
||||
#define SPANISH 11 /* translated by Rafa Couto */
|
||||
#define ICELANDIC 12 /* translated by Björn Davíðsson */
|
||||
|
||||
/* Add more languages here - but please e-mail dianne@skoll.ca
|
||||
to have your favorite language assigned a number. If you add a
|
||||
language, please send me the header file, and permission to include
|
||||
it in future releases of Remind. Note that you'll get no remuneration
|
||||
for this service - just everlasting fame. :-)
|
||||
|
||||
Use the file tstlang.rem to test your new language file. */
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* Define the language you want to use here *
|
||||
* *
|
||||
************************************************************************/
|
||||
#ifndef LANG /* Allow for definition on compiler command line */
|
||||
#define LANG ENGLISH
|
||||
#endif
|
||||
|
||||
/* Pick up the appropriate header file */
|
||||
#if LANG == ENGLISH
|
||||
#include "langs/english.h"
|
||||
#elif LANG == GERMAN
|
||||
#include "langs/german.h"
|
||||
#elif LANG == DUTCH
|
||||
#include "langs/dutch.h"
|
||||
#elif LANG == FINNISH
|
||||
#include "langs/finnish.h"
|
||||
#elif LANG == FRENCH
|
||||
#include "langs/french.h"
|
||||
#elif LANG == NORWEGIAN
|
||||
#include "langs/norwgian.h"
|
||||
#elif LANG == DANISH
|
||||
#include "langs/danish.h"
|
||||
#elif LANG == POLISH
|
||||
#include "langs/polish.h"
|
||||
#elif LANG == BRAZPORT
|
||||
#include "langs/portbr.h"
|
||||
#elif LANG == ITALIAN
|
||||
#include "langs/italian.h"
|
||||
#elif LANG == ROMANIAN
|
||||
#include "langs/romanian.h"
|
||||
#elif LANG == SPANISH
|
||||
#include "langs/spanish.h"
|
||||
#elif LANG == ICELANDIC
|
||||
#include "langs/icelandic.h"
|
||||
|
||||
/* If no sensible language, choose English. I intended to use
|
||||
the #error directive here, but some C compilers barf. */
|
||||
#else
|
||||
#include "langs/english.h"
|
||||
#endif
|
||||
@@ -1,91 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DANISH.H */
|
||||
/* */
|
||||
/* Support for the Danish language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1993 by Mogens Lynnerup. */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Danish"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Søndag"
|
||||
#define L_MONDAY "Mandag"
|
||||
#define L_TUESDAY "Tirsdag"
|
||||
#define L_WEDNESDAY "Onsdag"
|
||||
#define L_THURSDAY "Torsdag"
|
||||
#define L_FRIDAY "Fredag"
|
||||
#define L_SATURDAY "Lørdag"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
#define L_FEB "Februar"
|
||||
#define L_MAR "Marts"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "Maj"
|
||||
#define L_JUN "Juni"
|
||||
#define L_JUL "Juli"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "Oktober"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "December"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "i dag"
|
||||
#define L_TOMORROW "i morgen"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Påmindelse for %w, %d. %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "siden"
|
||||
#define L_FROMNOW "fra nu"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "om %d dage"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "på"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "e"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nu"
|
||||
#define L_AT "kl."
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "time"
|
||||
#define L_IS "er"
|
||||
#define L_WAS "var"
|
||||
#define L_AND "og"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "r"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "ter"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<5) ? " om natten" : " om formiddagen" : (hour > 17) ? " om aftenen" : " om eftermiddagen";
|
||||
#define L_ORDINAL_OVERRIDE plu = ".";
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
|
||||
#define L_E_OVER sprintf(s, "den %02d%c%02d%c%04d", d, DateSep, m+1, DateSep, y);
|
||||
#define L_F_OVER sprintf(s, "den %02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
|
||||
#define L_H_OVER sprintf(s, "den %02d%c%02d", d, DateSep, m+1);
|
||||
#define L_I_OVER sprintf(s, "den %02d%c%02d", m+1, DateSep, d);
|
||||
#define L_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
@@ -1,102 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DUTCH.H */
|
||||
/* */
|
||||
/* Support for the DUTCH language. */
|
||||
/* */
|
||||
/* Author: Willem Kasdorp */
|
||||
/* */
|
||||
/* Modified slightly by Dianne Skoll */
|
||||
/* */
|
||||
/* Further corrections by Erik-Jan Vens */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Dutch"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "zondag"
|
||||
#define L_MONDAY "maandag"
|
||||
#define L_TUESDAY "dinsdag"
|
||||
#define L_WEDNESDAY "woensdag"
|
||||
#define L_THURSDAY "donderdag"
|
||||
#define L_FRIDAY "vrijdag"
|
||||
#define L_SATURDAY "zaterdag"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "januari"
|
||||
#define L_FEB "februari"
|
||||
#define L_MAR "maart"
|
||||
#define L_APR "april"
|
||||
#define L_MAY "mei"
|
||||
#define L_JUN "juni"
|
||||
#define L_JUL "juli"
|
||||
#define L_AUG "augustus"
|
||||
#define L_SEP "september"
|
||||
#define L_OCT "oktober"
|
||||
#define L_NOV "november"
|
||||
#define L_DEC "december"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "vandaag"
|
||||
#define L_TOMORROW "morgen"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Herinneringen voor %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "geleden"
|
||||
#define L_FROMNOW "vanaf nu"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "over %d dagen"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "op"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix. (Indeed..., wkasdo) */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nu"
|
||||
#define L_AT "op"
|
||||
#define L_MINUTE "minuut"
|
||||
#define L_HOUR "uur"
|
||||
#define L_IS "is"
|
||||
#define L_WAS "was"
|
||||
#define L_AND "en"
|
||||
/* What to add to make "hour" plural (should result in uren, not uuren (wkasdo) */
|
||||
#define L_HPLU "en"
|
||||
/* What to add to make "minute" plural (should be minuten, not minuuten) */
|
||||
#define L_MPLU "en"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
/* Willem - I fixed the uren/uuren problem here */
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "%d %s %s", mdiff, \
|
||||
((mdiff == 1) ? "minuut" : "minuten"), when); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "%d %s %s", hdiff, \
|
||||
((hdiff == 1) ? "uur" : "uren"), when); \
|
||||
else sprintf(s, "%d %s %s %d %s %s", hdiff, \
|
||||
(hdiff == 1 ? "uur" : "uren"), \
|
||||
L_AND, mdiff, \
|
||||
(mdiff == 1 ? "minuut" : "minuten"), \
|
||||
when);
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ENGLISH.H */
|
||||
/* */
|
||||
/* Support for the English language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "English"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Sunday"
|
||||
#define L_MONDAY "Monday"
|
||||
#define L_TUESDAY "Tuesday"
|
||||
#define L_WEDNESDAY "Wednesday"
|
||||
#define L_THURSDAY "Thursday"
|
||||
#define L_FRIDAY "Friday"
|
||||
#define L_SATURDAY "Saturday"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "January"
|
||||
#define L_FEB "February"
|
||||
#define L_MAR "March"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "May"
|
||||
#define L_JUN "June"
|
||||
#define L_JUL "July"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "October"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "December"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "today"
|
||||
#define L_TOMORROW "tomorrow"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Reminders for %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "ago"
|
||||
#define L_FROMNOW "from now"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "in %d days' time"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "on"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "now"
|
||||
#define L_AT "at"
|
||||
#define L_MINUTE "minute"
|
||||
#define L_HOUR "hour"
|
||||
#define L_IS "is"
|
||||
#define L_WAS "was"
|
||||
#define L_AND "and"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "s"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "s"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
@@ -1,292 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FINNISH.H */
|
||||
/* */
|
||||
/* Support for the Finnish language. */
|
||||
/* */
|
||||
/* Author: Mikko Silvonen <silvonen@iki.fi> */
|
||||
/* */
|
||||
/* See http://www.iki.fi/silvonen/remind/ for a list of */
|
||||
/* Finnish holidays. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* This file is Copyright (C) 1993-1998 by Mikko Silvonen. */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Finnish"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "sunnuntai"
|
||||
#define L_MONDAY "maanantai"
|
||||
#define L_TUESDAY "tiistai"
|
||||
#define L_WEDNESDAY "keskiviikko"
|
||||
#define L_THURSDAY "torstai"
|
||||
#define L_FRIDAY "perjantai"
|
||||
#define L_SATURDAY "lauantai"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "tammikuu"
|
||||
#define L_FEB "helmikuu"
|
||||
#define L_MAR "maaliskuu"
|
||||
#define L_APR "huhtikuu"
|
||||
#define L_MAY "toukokuu"
|
||||
#define L_JUN "kesäkuu"
|
||||
#define L_JUL "heinäkuu"
|
||||
#define L_AUG "elokuu"
|
||||
#define L_SEP "syyskuu"
|
||||
#define L_OCT "lokakuu"
|
||||
#define L_NOV "marraskuu"
|
||||
#define L_DEC "joulukuu"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "tänään"
|
||||
#define L_TOMORROW "huomenna"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Viestit %wna %d. %mta %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM " ap."
|
||||
#define L_PM " ip."
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "sitten"
|
||||
#define L_FROMNOW "kuluttua"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "%d päivän kuluttua"
|
||||
|
||||
/* "on" as in "on date...", but in Finnish it is a case ending;
|
||||
L_PARTIT is the partitive ending appended to -kuu and -tai */
|
||||
#define L_ON "na"
|
||||
#define L_PARTIT "ta"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
/* The partitive ending of "day" */
|
||||
#define L_PLURAL "ä"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nyt"
|
||||
#define L_AT "klo"
|
||||
#define L_MINUTE "minuutti"
|
||||
#define L_HOUR "tunti"
|
||||
#define L_IS "on"
|
||||
#define L_WAS "oli"
|
||||
#define L_AND "ja"
|
||||
|
||||
/* What to add to make "hour" plural (or actually partitive) */
|
||||
#define L_HPLU "a"
|
||||
/* What to add to make "minute" plural (or actually partitive) */
|
||||
#define L_MPLU "a"
|
||||
|
||||
/* Genitive form of "hour" */
|
||||
#define L_HGEN "tunnin"
|
||||
/* Genitive form of "minute" */
|
||||
#define L_MGEN "minuutin"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#define L_ORDINAL_OVERRIDE switch(d) { \
|
||||
case 1: plu = ":senä"; break; \
|
||||
case 2: plu = ":sena"; break; \
|
||||
default: \
|
||||
switch(d%10) { \
|
||||
case 2: \
|
||||
case 3: \
|
||||
case 6: \
|
||||
case 8: plu = ":ntena"; break; \
|
||||
default: plu = ":ntenä"; break; \
|
||||
} \
|
||||
}
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s%s %d. %s%s %d", DayName[dse%7], L_ON, d, MonthName[m], L_PARTIT, y); }
|
||||
#define L_C_OVER if (altmode == '*') { sprintf(s, "%s", DayName[dse%7]); } else { sprintf(s, "%s%s", DayName[dse%7], L_ON); }
|
||||
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DateSep, m+1, DateSep, y);
|
||||
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s%s %d. %s%s", DayName[dse%7], L_ON, d, MonthName[m], L_PARTIT); }
|
||||
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1);
|
||||
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d);
|
||||
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s %d", DayName[dse%7], MonthName[m], d, plu, y); } else { sprintf(s, "%s%s %sn %d%s %d", DayName[dse%7], L_ON, MonthName[m], d, plu, y); }
|
||||
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s", DayName[dse%7], MonthName[m], d, plu); } else { sprintf(s, "%s%s %sn %d%s", DayName[dse%7], L_ON, MonthName[m], d, plu); }
|
||||
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
#define L_Q_OVER sprintf(s, "n");
|
||||
#define L_U_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s %d", DayName[dse%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s%s %d%s %s%s %d", DayName[dse%7], L_ON, d, plu, MonthName[m], L_PARTIT, y); }
|
||||
#define L_V_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s", DayName[dse%7], d, plu, MonthName[m]); } else { sprintf(s, "%s%s %d%s %s%s", DayName[dse%7], L_ON, d, plu, MonthName[m], L_PARTIT); }
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, "%s", L_NOW); \
|
||||
else { \
|
||||
s[0] = '\0'; \
|
||||
if (hdiff != 0) { \
|
||||
if (tdiff < 0) \
|
||||
sprintf(s, "%d %s%s ", hdiff, L_HOUR, hplu); \
|
||||
else \
|
||||
sprintf(s, "%d %s ", hdiff, L_HGEN); \
|
||||
} \
|
||||
if (mdiff != 0) { \
|
||||
if (tdiff < 0) \
|
||||
sprintf(s + strlen(s), "%d %s%s ", mdiff, L_MINUTE, mplu); \
|
||||
else \
|
||||
sprintf(s + strlen(s), "%d %s ", mdiff, L_MGEN); \
|
||||
} \
|
||||
sprintf(s + strlen(s), when); \
|
||||
}
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
"Ok",
|
||||
"Puuttuva ']'",
|
||||
"Puuttuva lainausmerkki",
|
||||
"Liian monimutkainen lauseke",
|
||||
"Liian monimutkainen lauseke - liikaa operandeja",
|
||||
"Puuttuva ')'",
|
||||
"Määrittelemätön funktio",
|
||||
"Virheellinen merkki",
|
||||
"Kaksipaikkainen operaattori puuttuu",
|
||||
"Muisti loppui",
|
||||
"Virheellinen luku",
|
||||
"Operaattoripino tyhjä - sisäinen virhe",
|
||||
"Muuttujapino tyhjä - sisäinen virhe",
|
||||
"Tyyppimuunnos ei onnistu",
|
||||
"Virheellinen tyyppi",
|
||||
"Liian suuri päiväys",
|
||||
"Pinovirhe - sisäinen virhe",
|
||||
"Jako nollalla",
|
||||
"Määrittelemätön funktio",
|
||||
"Odottamaton rivin loppu",
|
||||
"Odottamaton tiedoston loppu",
|
||||
"Syöttö- tai tulostusvirhe",
|
||||
"Liian pitkä rivi",
|
||||
"Sisäinen virhe",
|
||||
"Virheellinen päiväys",
|
||||
"Liian vähän argumentteja",
|
||||
"Liian paljon argumentteja",
|
||||
"Virheellinen aika",
|
||||
"Liian suuri luku",
|
||||
"Liian pieni luku",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Liian monta sisäkkäistä INCLUDEa",
|
||||
"Jäsennysvirhe",
|
||||
"Laukaisuhetken laskenta ei onnistu",
|
||||
"Liian monta sisäkkäistä IF-lausetta",
|
||||
"ELSE ilman IF-lausetta",
|
||||
"ENDIF ilman IF-lausetta",
|
||||
"Kaikkia viikonpäiviä ei voi jättää pois",
|
||||
"Ylimääräisiä merkkejä rivillä",
|
||||
"POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia",
|
||||
"RUN-lauseen käyttö estetty",
|
||||
"Arvoaluevirhe",
|
||||
"Virheellinen tunniste",
|
||||
"Rekursiivinen funktiokutsu havaittu",
|
||||
"",
|
||||
"Järjestelmämuuttujan muuttaminen ei onnistu",
|
||||
"C-kirjastofunktio ei pysty esittämään päiväystä tai aikaa",
|
||||
"Sisäisen funktion määritelmää yritettiin muuttaa",
|
||||
"Lausekkeessa ei voi olla sisäkkäisiä funktiomääritelmiä",
|
||||
"Päiväyksen täytyy olla täydellinen toistokertoimessa",
|
||||
"Vuosi annettu kahdesti",
|
||||
"Kuukausi annettu kahdesti",
|
||||
"Päivä annettu kahdesti",
|
||||
"Tuntematon sana tai merkki",
|
||||
"OMIT-komennossa on annettava kuukausi",
|
||||
"Liian monta osittaista OMIT-komentoa",
|
||||
"Liian monta täydellistä OMIT-komentoa",
|
||||
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
|
||||
"Virhe tiedoston luvussa",
|
||||
"Pilkku puuttuu",
|
||||
"Virheellinen juutalainen päiväys",
|
||||
"IIF vaatii parittoman määrän argumentteja",
|
||||
"Varoitus: puuttuva ENDIF",
|
||||
"Pilkku puuttuu",
|
||||
"Viikonpäivä annettu kahdesti",
|
||||
"Käytä vain yhtä komennoista BEFORE, AFTER ja SKIP",
|
||||
"Sisäkkäisiä MSG-, MSF- ja RUN-lauseita ei voi käyttää lausekkeessa",
|
||||
"Toistokerroin annettu kahdesti",
|
||||
"Delta-arvo annettu kahdesti",
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa käytetty kahdesti. (Hah.)",
|
||||
"AT-sanan perästä puuttuu aika",
|
||||
"THROUGH/UNTIL-sanaa käytetty kahdesti",
|
||||
"Epätäydellinen päiväys",
|
||||
"FROM/SCANFROM-sanaa käytetty kahdesti",
|
||||
"Muuttuja",
|
||||
"Arvo",
|
||||
"*MÄÄRITTELEMÄTÖN*",
|
||||
"Siirrytään funktioon",
|
||||
"Poistutaan funktiosta",
|
||||
"Vanhentunut",
|
||||
"fork() epäonnistui - jonomuistutukset eivät toimi",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Virheellinen järjestelmäpäiväys: vuosi on vähemmän kuin %d\n",
|
||||
"Tuntematon virheenetsintätarkenne '%c'\n",
|
||||
"Tuntematon tarkenne '%c'\n",
|
||||
"Tuntematon käyttäjä '%s'\n",
|
||||
"Ryhmänumeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Käyttäjänumeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Muisti ei riitä ympäristölle\n",
|
||||
"Puuttuva '='-merkki",
|
||||
"Puuttuva muuttujanimi",
|
||||
"Puuttuva lauseke",
|
||||
"Päivän asetus %s:ksi ei onnitus\n",
|
||||
"Remind: tarkenne '-i': %s\n",
|
||||
"Ei viestejä.",
|
||||
"%d viesti(ä) tämän päivän jonossa.\n",
|
||||
"Numero puuttuu",
|
||||
"Virheellinen funktio WARN-lausekkeessa",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT",
|
||||
"Odotettu viikonpäivän nimi",
|
||||
"Päällekkäinen argumentin nimi",
|
||||
"Lausekkeiden arviointi on poistettu käytöstä",
|
||||
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETAVERSIO <<<<\n");
|
||||
#endif
|
||||
fprintf(ErrFp, "Käyttö: remind [tarkenteet] tiedosto [päiväys] [aika] [*toisto]\n");
|
||||
fprintf(ErrFp, "Tarkenteet:\n");
|
||||
fprintf(ErrFp, " -n Tulosta viestien seuraavat esiintymiskerrat yksink. muodossa\n");
|
||||
fprintf(ErrFp, " -r Estä RUN-lauseiden käyttö\n");
|
||||
fprintf(ErrFp, " -c[n] Tulosta n:n kuukauden kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -c+[n] Tulosta n:n viikon kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja välit\n");
|
||||
fprintf(ErrFp, " -s[+][n] Tulosta n:n kuukauden (viikon) 'yksink. kalenteri' (oletus 1)\n");
|
||||
fprintf(ErrFp, " -p[n] Kuten -s, mutta tulosta rem2ps:lle sopivassa muodossa\n");
|
||||
fprintf(ErrFp, " -v Laveat tulostukset\n");
|
||||
fprintf(ErrFp, " -o Älä noudata ONCE-lauseita\n");
|
||||
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta välittämättä\n");
|
||||
fprintf(ErrFp, " -h Suppeat tulostukset\n");
|
||||
fprintf(ErrFp, " -a Älä laukaise viestejä heti - lisää ne jonoon\n");
|
||||
fprintf(ErrFp, " -q Älä lisää viestejä jonoon\n");
|
||||
fprintf(ErrFp, " -f Laukaise viestit, pysy etualalla\n");
|
||||
fprintf(ErrFp, " -z[n] Käynnisty demonina, herätys n:n (5:n) minuutin välein\n");
|
||||
fprintf(ErrFp, " -d... Virheenetsintä: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Ohjaa virhetulostus stdout-vuohon\n");
|
||||
fprintf(ErrFp, " -b[n] Ajan ilmaisu: 0=ap/ip, 1=24 tuntia, 2=ei aikoja\n");
|
||||
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
|
||||
fprintf(ErrFp, " -g[ddd] Lajittele viestit päiväyksen, ajan ja tärkeyden mukaan\n");
|
||||
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja säilytä var\n");
|
||||
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eikä sunnuntaista\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
@@ -1,266 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FRENCH.H */
|
||||
/* */
|
||||
/* Support for the French language. */
|
||||
/* */
|
||||
/* Contributed by Laurent Duperval. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1993 by Laurent Duperval and */
|
||||
/* Dianne Skoll. */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "French"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "dimanche"
|
||||
#define L_MONDAY "lundi"
|
||||
#define L_TUESDAY "mardi"
|
||||
#define L_WEDNESDAY "mercredi"
|
||||
#define L_THURSDAY "jeudi"
|
||||
#define L_FRIDAY "vendredi"
|
||||
#define L_SATURDAY "samedi"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "janvier"
|
||||
#define L_FEB "février"
|
||||
#define L_MAR "mars"
|
||||
#define L_APR "avril"
|
||||
#define L_MAY "mai"
|
||||
#define L_JUN "juin"
|
||||
#define L_JUL "juillet"
|
||||
#define L_AUG "août"
|
||||
#define L_SEP "septembre"
|
||||
#define L_OCT "octobre"
|
||||
#define L_NOV "novembre"
|
||||
#define L_DEC "décembre"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "aujourd'hui"
|
||||
#define L_TOMORROW "demain"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Rappels pour %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "il y a"
|
||||
#define L_FROMNOW "dans"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "dans %d jours"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "le"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "maintenant"
|
||||
#define L_AT "à"
|
||||
#define L_MINUTE "minute"
|
||||
#define L_HOUR "heure"
|
||||
#define L_IS "est"
|
||||
#define L_WAS "était"
|
||||
#define L_AND "et"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "s"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "s"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#define L_ORDINAL_OVERRIDE \
|
||||
switch(d) { \
|
||||
case 1: plu = "er"; break; \
|
||||
default: plu = ""; break; \
|
||||
}
|
||||
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (tdiff < 0) { \
|
||||
if (mdiff == 0) \
|
||||
sprintf(s, "il y a %d heure%s", hdiff, hplu); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "il y a %d minute%s", mdiff, mplu); \
|
||||
else \
|
||||
sprintf(s, "il y a %d heure%s et %d minute%s", hdiff, hplu, mdiff, mplu); \
|
||||
} else { \
|
||||
if (mdiff == 0) \
|
||||
sprintf(s, "dans %d heure%s", hdiff, hplu); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "dans %d minute%s", mdiff, mplu); \
|
||||
else \
|
||||
sprintf(s, "dans %d heure%s et %d minute%s", hdiff, hplu, mdiff, mplu); \
|
||||
}
|
||||
|
||||
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s, %d", DayName[dse%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s %s, %d%s %s, %d", L_ON, DayName[dse%7], d, plu, MonthName[m], y); }
|
||||
|
||||
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s", DayName[dse%7], d, plu, MonthName[m]); } else { sprintf(s, "%s %s, %d%s %s", L_ON, DayName[dse%7], d, plu, MonthName[m]); }
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
"Ok",
|
||||
"']' manquant",
|
||||
"Apostrophe manquant",
|
||||
"Expression trop complexe",
|
||||
"Expression trop complexe - trop d'opérandes",
|
||||
"')' manquante",
|
||||
"Fonction non-définie",
|
||||
"Caractère illégal",
|
||||
"Opérateur binaire attendu",
|
||||
"Manque de mémoire",
|
||||
"Nombre mal formé",
|
||||
"Erreur interne - 'underflow' de la pile d'opérateurs",
|
||||
"Erreur interne - 'underflow' de la pile de variables",
|
||||
"Impossible de convertir",
|
||||
"Types non-équivalents",
|
||||
"Débordement de date",
|
||||
"Erreur interne - erreur de pile",
|
||||
"Division par zéro",
|
||||
"Variable non définie",
|
||||
"Fin de ligne non attendue",
|
||||
"Fin de fichier non attendue",
|
||||
"Erreur I/O",
|
||||
"Ligne trop longue",
|
||||
"Erreur interne",
|
||||
"Mauvaise date spécifiée",
|
||||
"Pas assez d'arguments",
|
||||
"Trop d'arguments",
|
||||
"Heure mal formée",
|
||||
"Nombre trop élevé",
|
||||
"Nombre trop bas",
|
||||
"Impossible d'ouvrir le fichier",
|
||||
"Trop d'INCLUDE imbriqués",
|
||||
"Erreur d'analyse",
|
||||
"Impossible de calculer le déclenchement",
|
||||
"Trop de IF imbriqués",
|
||||
"ELSE sans IF correspondant",
|
||||
"ENDIF sans IF correspondant",
|
||||
"Impossible d'omettre (OMIT) tous les jours",
|
||||
"Elément(s) étranger(s) sur la ligne",
|
||||
"POP-OMIT-CONTEXT sans PUSH-OMIT-CONTEXT correspondant",
|
||||
"RUN déactivé",
|
||||
"Erreur de domaine",
|
||||
"Identificateur invalide",
|
||||
"Appel récursif détecté",
|
||||
"",
|
||||
"Impossible de modifier une variable système",
|
||||
"Fonction de la librairie C ne peut représenter la date/l'heure",
|
||||
"Tentative de redéfinition d'une fonction intrinsèque",
|
||||
"Impossible d'imbriquer une définition de fonction dans une expression",
|
||||
"Pour utiliser le facteur de répétition la date doit être spécifiée au complet",
|
||||
"Année spécifiée deux fois",
|
||||
"Mois spécifié deux fois",
|
||||
"Jour spécifié deux fois",
|
||||
"Elément inconnu",
|
||||
"Mois et jour doivent être spécifiés dans commande OMIT",
|
||||
"Trop de OMITs partiels",
|
||||
"Trop de OMITs complets",
|
||||
"Attention: PUSH-OMIT-CONTEXT sans POP-OMIT-CONTEXT correspondant",
|
||||
"Erreur à la lecture du fichier",
|
||||
"Fin de ligne attendue",
|
||||
"Date hébreuse invalide",
|
||||
"IIF demande nombre d'arguments impair",
|
||||
"Attention: ENDIF manquant",
|
||||
"Virgule attendue",
|
||||
"Jour de la semaine spécifié deux fois",
|
||||
"Utiliser un seul parmi BEFORE, AFTER ou SKIP",
|
||||
"Impossible d'imbriquer MSG, MSF, RUN, etc. dans une expression",
|
||||
"Valeur de répétition spécifiée deux fois",
|
||||
"Valeur delta spécifiée deux fois",
|
||||
"Valeur de retour spécifiée deux fois",
|
||||
"Mot-clé ONCE utilisé deux fois. (Hah.)",
|
||||
"Heure attendue après AT",
|
||||
"Mot-clé THROUGH/UNTIL utilisé deux fois",
|
||||
"Spécification de date incomplète",
|
||||
"Mot-clé FROM/SCANFROM utilisé deux fois",
|
||||
"Variable",
|
||||
"Valeur",
|
||||
"*NON-DEFINI*",
|
||||
"Entrée dans UserFN",
|
||||
"Sortie de UserFN",
|
||||
"Expiré",
|
||||
"fork() échoué - impossible de faire les appels en queue",
|
||||
"Impossible d'accéder au fichier",
|
||||
"Date système illégale: Année est inférieure à %d\n",
|
||||
"Option de déverminage inconnue '%c'\n",
|
||||
"Option inconnue '%c'\n",
|
||||
"Usager inconnu '%s'\n",
|
||||
"Impossible de changer gid pour %d\n",
|
||||
"Impossible de changer uid pour %d\n",
|
||||
"Manque de mémoire pour environnement\n",
|
||||
"Signe '=' manquant",
|
||||
"Nom de variable absent",
|
||||
"Expression absente",
|
||||
"Impossible de changer la date d'accès de %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Pas de rappels.",
|
||||
"%d rappel(s) en file pour aujourd'hui.\n",
|
||||
"Nombre attendu",
|
||||
"Fonction illégale après WARN",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT",
|
||||
"Nom du jour de la semaine attendu",
|
||||
"Nom de l'argument en double",
|
||||
"L'évaluation de l'expression est désactivée",
|
||||
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
fprintf(ErrFp, "\nUtilisation: remind [options] fichier [date] [heure] [*répétition]\n");
|
||||
fprintf(ErrFp, "Options:\n");
|
||||
fprintf(ErrFp, " -n Afficher la prochaine occurence des rappels en format simple\n");
|
||||
fprintf(ErrFp, " -r Désactiver les instructions RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Produire un calendrier pour n (défaut 1) mois\n");
|
||||
fprintf(ErrFp, " -c+[n] Produire un calendrier pour n (défaut 1) semaines\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Spécifier largeur, remplissage et espacement du calendrier\n");
|
||||
fprintf(ErrFp, " -s[+][n] Produire un 'calendrier simple' pour n (1) mois (semaines)\n");
|
||||
fprintf(ErrFp, " -p[n] Comme -s, mais avec entrée compatible avec rem2ps\n");
|
||||
fprintf(ErrFp, " -v Mode verbeux\n");
|
||||
fprintf(ErrFp, " -o Ignorer instructions ONCE\n");
|
||||
fprintf(ErrFp, " -t Déclencher tous les rappels peu importe le delta\n");
|
||||
fprintf(ErrFp, " -h Mode silencieux\n");
|
||||
fprintf(ErrFp, " -a Ne pas déclencher les rappels minutés immédiatement - les mettre en file\n");
|
||||
fprintf(ErrFp, " -q Ne pas mettre les rappels minutés en file\n");
|
||||
fprintf(ErrFp, " -f Déclencher les rappels minutés immédiatement en restant en avant-plan\n");
|
||||
fprintf(ErrFp, " -z[n] Entrer en mode 'daemon', réveil chaque n (5) minutes\n");
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Envoyer les messages de stderr à stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Formats de l'heure pour le calendrier: 0=am/pm, 1=24hr, 2=aucun\n");
|
||||
fprintf(ErrFp, " -x[n] Limite d'itérations pour la clause SATISFY (def=1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Exécuter 'cmd' pour les rappels de type MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorité avant d'émettre\n");
|
||||
fprintf(ErrFp, " -ivar=val Initialiser var à val et conserver var\n");
|
||||
fprintf(ErrFp, " -m Commencer le calendrier avec lundi plutôt que dimanche\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
@@ -1,88 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GERMAN.H */
|
||||
/* */
|
||||
/* Support for the German language. */
|
||||
/* */
|
||||
/* This file was derived from a patch submitted by Wolfgang */
|
||||
/* Thronicke. I don't guarantee that there are no mistakes - */
|
||||
/* I don't speak German. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "German"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Sonntag"
|
||||
#define L_MONDAY "Montag"
|
||||
#define L_TUESDAY "Dienstag"
|
||||
#define L_WEDNESDAY "Mittwoch"
|
||||
#define L_THURSDAY "Donnerstag"
|
||||
#define L_FRIDAY "Freitag"
|
||||
#define L_SATURDAY "Samstag"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
#define L_FEB "Februar"
|
||||
#define L_MAR "März"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "Mai"
|
||||
#define L_JUN "Juni"
|
||||
#define L_JUL "Juli"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "Oktober"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "Dezember"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "heute"
|
||||
#define L_TOMORROW "morgen"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Termine für %w, den %d. %m %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "vorher"
|
||||
#define L_FROMNOW "von heute"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "in %d Tagen"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "am"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "en"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "jetzt"
|
||||
#define L_AT "um"
|
||||
#define L_MINUTE "Minute"
|
||||
#define L_HOUR "Stunde"
|
||||
#define L_IS "ist"
|
||||
#define L_WAS "war"
|
||||
#define L_AND "und"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "n"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "n"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<5) ? " nachts" : " vormittags" : (hour > 17) ? " abends" : " nachmittags";
|
||||
#define L_ORDINAL_OVERRIDE plu = ".";
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
|
||||
#define L_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
@@ -1,79 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ICELANDIC.H */
|
||||
/* */
|
||||
/* Support for the Icelandic language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Icelandic"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "sunnudagur"
|
||||
#define L_MONDAY "mánudagur"
|
||||
#define L_TUESDAY "þriðjudagur"
|
||||
#define L_WEDNESDAY "miðvikudagur"
|
||||
#define L_THURSDAY "fimmtudagur"
|
||||
#define L_FRIDAY "föstudagur"
|
||||
#define L_SATURDAY "laugardagur"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "janúar"
|
||||
#define L_FEB "febrúar"
|
||||
#define L_MAR "mars"
|
||||
#define L_APR "apríl"
|
||||
#define L_MAY "maí"
|
||||
#define L_JUN "júní"
|
||||
#define L_JUL "júlí"
|
||||
#define L_AUG "ágúst"
|
||||
#define L_SEP "september"
|
||||
#define L_OCT "október"
|
||||
#define L_NOV "nóvember"
|
||||
#define L_DEC "desember"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "í dag"
|
||||
#define L_TOMORROW "á morgun"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Minnisatriði: %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "fh"
|
||||
#define L_PM "eh"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "síðan"
|
||||
#define L_FROMNOW "frá því nú"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "eftir %d daga"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "þann"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "a"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "núna"
|
||||
#define L_AT "kl."
|
||||
#define L_MINUTE "mínútu"
|
||||
#define L_HOUR "klukkustund"
|
||||
#define L_IS "er"
|
||||
#define L_WAS "var"
|
||||
#define L_AND "og"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "ir"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "r"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
@@ -1,114 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ITALIAN.H */
|
||||
/* */
|
||||
/* Support for the Italian language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* It is Copyright (C) 1996 by Valerio Aimale */
|
||||
/* */
|
||||
/* Remind is copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Italian"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Domenica"
|
||||
#define L_MONDAY "Lunedì"
|
||||
#define L_TUESDAY "Martedì"
|
||||
#define L_WEDNESDAY "Mercoledì"
|
||||
#define L_THURSDAY "Giovedì"
|
||||
#define L_FRIDAY "Venerdì"
|
||||
#define L_SATURDAY "Sabato"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Gennaio"
|
||||
#define L_FEB "Febbraio"
|
||||
#define L_MAR "Marzo"
|
||||
#define L_APR "Aprile"
|
||||
#define L_MAY "Maggio"
|
||||
#define L_JUN "Giugno"
|
||||
#define L_JUL "Luglio"
|
||||
#define L_AUG "Agosto"
|
||||
#define L_SEP "Settembre"
|
||||
#define L_OCT "Ottobre"
|
||||
#define L_NOV "Novembre"
|
||||
#define L_DEC "Dicembre"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "oggi"
|
||||
|
||||
#define L_TOMORROW "domani"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Promemoria per %w, %d %m %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "fa"
|
||||
#define L_FROMNOW "da oggi"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "fra %d giorni"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON ""
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "ora"
|
||||
#define L_AT "alle"
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "or"
|
||||
#define L_IS "è"
|
||||
#define L_WAS "era"
|
||||
#define L_AND "e"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "s"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "s"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#define L_P_OVER sprintf(s, (diff == 1 ? "o" : "i"));
|
||||
#define L_Q_OVER sprintf(s, (diff == 1 ? "a" : "e"));
|
||||
|
||||
#define L_HPLU_OVER hplu = (hdiff == 1 ? "a" : "e");
|
||||
#define L_MPLU_OVER mplu = (mdiff == 1 ? "o" : "i");
|
||||
|
||||
#define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d,\
|
||||
MonthName[m], y);
|
||||
#define L_C_OVER sprintf(s, "%s", DayName[dse%7]);
|
||||
|
||||
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DateSep,\
|
||||
m+1, DateSep, y);
|
||||
|
||||
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
|
||||
#define L_G_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, MonthName[m]);
|
||||
|
||||
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1);
|
||||
|
||||
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d);
|
||||
|
||||
#define L_J_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d, \
|
||||
MonthName[m], y);
|
||||
|
||||
#define L_K_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, \
|
||||
MonthName[m]);
|
||||
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
|
||||
#define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d, \
|
||||
MonthName[m], y);
|
||||
|
||||
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, \
|
||||
MonthName[m]);
|
||||
@@ -1,84 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* NORWGIAN.H */
|
||||
/* */
|
||||
/* Support for the Norwegian language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* This file is Copyright (C) 1993 by Trygve Randen. */
|
||||
/* Remind is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Norwegian"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Søndag"
|
||||
#define L_MONDAY "Mandag"
|
||||
#define L_TUESDAY "Tirsdag"
|
||||
#define L_WEDNESDAY "Onsdag"
|
||||
#define L_THURSDAY "Torsdag"
|
||||
#define L_FRIDAY "Fredag"
|
||||
#define L_SATURDAY "Lørdag"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
#define L_FEB "Februar"
|
||||
#define L_MAR "Mars"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "Mai"
|
||||
#define L_JUN "Juni"
|
||||
#define L_JUL "Juli"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "Oktober"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "Desember"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "i dag"
|
||||
#define L_TOMORROW "i morgen"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Påminnelse for %w, %d. %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "siden"
|
||||
#define L_FROMNOW "fra nå"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "om %d dager"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "den"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "er"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nå"
|
||||
#define L_AT "kl."
|
||||
#define L_MINUTE "minutt"
|
||||
#define L_HOUR "time"
|
||||
#define L_IS "er"
|
||||
#define L_WAS "var"
|
||||
#define L_AND "og"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "r"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "er"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
#define L_ORDINAL_OVERRIDE plu = ".";
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
|
||||
#define L_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
@@ -1,281 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* POLISH.H */
|
||||
/* */
|
||||
/* Support for the Polish language. */
|
||||
/* */
|
||||
/* This file was submitted by Jerzy Sobczyk. I don't */
|
||||
/* guarantee that there are no mistakes - I don't speak */
|
||||
/* Polish. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Polish"
|
||||
|
||||
/* Day names */
|
||||
# define L_SUNDAY "Niedziela"
|
||||
# define L_MONDAY "Poniedziałek"
|
||||
# define L_TUESDAY "Wtorek"
|
||||
# define L_WEDNESDAY "Środa"
|
||||
# define L_THURSDAY "Czwartek"
|
||||
# define L_FRIDAY "Piątek"
|
||||
# define L_SATURDAY "Sobota"
|
||||
|
||||
/* Month names */
|
||||
# define L_JAN "Styczeń"
|
||||
# define L_FEB "Luty"
|
||||
# define L_MAR "Marzec"
|
||||
# define L_APR "Kwiecień"
|
||||
# define L_MAY "Maj"
|
||||
# define L_JUN "Czerwiec"
|
||||
# define L_JUL "Lipiec"
|
||||
# define L_AUG "Sierpień"
|
||||
# define L_SEP "Wrzesień"
|
||||
# define L_OCT "Październik"
|
||||
# define L_NOV "Listopad"
|
||||
# define L_DEC "Grudzień"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "dzisiaj"
|
||||
#define L_TOMORROW "jutro"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Terminarz na %w, %d. %m %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "temu"
|
||||
#define L_FROMNOW "od teraz"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "za %d dni"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "-"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL ""
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "teraz"
|
||||
#define L_AT "o"
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "godzin"
|
||||
# define L_IS "będzie"
|
||||
# define L_WAS "było"
|
||||
#define L_AND "i"
|
||||
|
||||
#define L_HPLU ""
|
||||
#define L_MPLU ""
|
||||
|
||||
/* What to add to make "hour" or "minute" plural */
|
||||
#define L_NPLU( N ) ((N == 1) ? "ę" : ((N==12) || (N==13) || (N==14)) ? "" : \
|
||||
((N%10==2) || (N%10==3) || (N%10==4)) ? "y" : "" )
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU_OVER hplu = L_NPLU( hdiff );
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU_OVER mplu = L_NPLU( mdiff );
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) \
|
||||
ampm = (hour<12) ? \
|
||||
(hour<5) ? " w nocy" \
|
||||
: (hour<10) ? " rano" \
|
||||
: " przed południem" \
|
||||
: (hour<18) ? " po południu" \
|
||||
: (hour<22) ? " wieczorem" \
|
||||
: " w nocy";
|
||||
#define L_ORDINAL_OVERRIDE plu = "";
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s %d", DayName[dse%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, %d. %s %d", L_ON, DayName[dse%7], d, MonthName[m], y); }
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s", DayName[dse%7], d, MonthName[m]); } else { sprintf(s, "%s %s, %d. %s", L_ON, DayName[dse%7], d, MonthName[m]); }
|
||||
#define L_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
#define L_0_OVER sprintf(s, L_NPLU(hdiff));
|
||||
#define L_9_OVER sprintf(s, L_NPLU(mdiff));
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (tdiff > 0) \
|
||||
{ \
|
||||
if (hdiff == 0) \
|
||||
sprintf(s, "za %d %s%s", mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "za %d %s%s", hdiff, L_HOUR, L_NPLU(hdiff)); \
|
||||
else \
|
||||
sprintf(s, "za %d %s%s %s %d %s%s", hdiff, L_HOUR, L_NPLU(hdiff), \
|
||||
L_AND, mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (hdiff == 0) \
|
||||
sprintf(s, "%d %s%s temu", mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "%d %s%s temu", hdiff, L_HOUR, L_NPLU(hdiff)); \
|
||||
else \
|
||||
sprintf(s, "%d %s%s %s %d %s%s temu", hdiff, L_HOUR, L_NPLU(hdiff), \
|
||||
L_AND, mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
}
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
"OK",
|
||||
"Brakujący ']'",
|
||||
"Brakujący nawias",
|
||||
"Zbyt skomplikowane wyrażenie",
|
||||
"Zbyt skomplikowane wyrażenie - za dużo argumentów",
|
||||
"Brakujący ')'",
|
||||
"Nie zdefiniowana funkcja",
|
||||
"Nielegalny znak",
|
||||
"Spodziewany operator binarny",
|
||||
"Brak pamięci",
|
||||
"Niepoprawny numer",
|
||||
"Pusty stos operatorów - błąd wewnętrzny",
|
||||
"Pusty stos zmiennych - błąd wewnętrzny",
|
||||
"Niemożliwa konwersja",
|
||||
"Błąd typu",
|
||||
"Nadmiar daty",
|
||||
"Błąd stosu - błąd wewnętrzny",
|
||||
"Dzielenie przez zero",
|
||||
"Niezdefiniowana zmienna",
|
||||
"Niespodziewany koniec linii",
|
||||
"Niespodziewany koniec pliku",
|
||||
"Błąd wejscia/wyjscia",
|
||||
"Za długa linia",
|
||||
"Błąd wewnętrzny",
|
||||
"Zła specyfikacja daty",
|
||||
"Za mało argumentów",
|
||||
"Za dużo argumentów",
|
||||
"Nieprawidłowy czas",
|
||||
"Liczba za duża",
|
||||
"Liczba za mała",
|
||||
"Nie mogę otworzyć pliku",
|
||||
"Zbyt zagnieżdżone INCLUDE",
|
||||
"Błąd składniowy",
|
||||
"Nie mogę obliczyć przypomnienia",
|
||||
"Zbyt zagnieżdżone IF",
|
||||
"ELSE bez IF do pary",
|
||||
"ENDIF bez IF do pary",
|
||||
"Nie mogę ominąć (OMIT) wszystkich dni",
|
||||
"Niespodziewany wyraz w lini",
|
||||
"POP-OMIT-CONTEXT bez PUSH-OMIT-CONTEXT",
|
||||
"Komenda RUN zablokowana",
|
||||
"Błąd dziedziny",
|
||||
"Niepoprawny identyfikator",
|
||||
"Wykryto rekursywne wywołanie funkcji",
|
||||
"",
|
||||
"Nie mogę zmienić zmiennej systemowej",
|
||||
"Funkcja biblioteki C nie może reprezentowac daty/czasu",
|
||||
"Próba redefinicji funkcji wbudowanej",
|
||||
"Nie wolno zagnieżdżać definicji funkcji w wyrażeniu",
|
||||
"Aby użyc powtórzenia trzeba w pełni wyspecyfikować datę",
|
||||
"Rok podany dwókrotnie",
|
||||
"Miesiąc podany dwókrotnie",
|
||||
"Dzień podany dwókrotnie",
|
||||
"Nieznane słowo",
|
||||
"W komendzie OMIT trzeba podać miesiąc",
|
||||
"Za dużo częściowych komend OMIT",
|
||||
"Za dużo pełnych komend OMIT",
|
||||
"Ostrzeżenie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",
|
||||
"Błąd odczytu pliku",
|
||||
"Oczekiwany koniec linii",
|
||||
"Błędna data hebrajska",
|
||||
"IIF wymaga nieparzystej liczby argumentów",
|
||||
"Ostrzeżenie: Brakujacy ENDIF",
|
||||
"Oczekiwany przecinek",
|
||||
"Dzień tygodnia podany dwókrotnie",
|
||||
"Dozwolone tylko jedno z: BEFORE, AFTER i SKIP",
|
||||
"Nie można zagnieżdżać MSG, MSF, RUN, itp. w wyrażeniu",
|
||||
"Wartość powtorzenia podana dwókrotnie",
|
||||
"Wartość różnicy podana dwókrotnie",
|
||||
"Wartość cofnięcia podana dwókrotnie",
|
||||
"Słowo ONCE użyte dwókrotnie.",
|
||||
"Po AT oczekiwany jest czas",
|
||||
"Słowo THROUGH/UNTIL użyte dwókrotnie",
|
||||
"Niekompletna specyfikacja daty",
|
||||
"Słowo FROM/SCANFROM użyte dwókrotnie",
|
||||
"Zmienna",
|
||||
"Wartość",
|
||||
"*NIE ZDEFINIOWANE*",
|
||||
"Początek UserFN",
|
||||
"Koniec UserFN",
|
||||
"Przemineło",
|
||||
"Niepowodzenie w funkcji fork() - nie mogę kolejkować przypomnień",
|
||||
"Nie ma dostępu do pliku",
|
||||
"Błędna data systemowa: Rok mniejszy niż %d\n",
|
||||
"Nieznana flaga odpluskwiania '%c'\n",
|
||||
"Nieznana opcja '%c'\n",
|
||||
"Nieznany użytkownik '%s'\n",
|
||||
"Nie mogę zmienić gid na %d\n",
|
||||
"Nie mogę zmienić uid na %d\n",
|
||||
"Brak pamięci na zmienne środowiska\n",
|
||||
"Brak znaku '='",
|
||||
"Brak nazwy zmiennej",
|
||||
"Brak wyrażenia",
|
||||
"Nie mogę zmienić daty dostępu pliku %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Brak przypomnień.",
|
||||
"%d Przypomnienia zakolejkowane na później.\n",
|
||||
"Spodziewana liczba",
|
||||
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT",
|
||||
"Oczekiwana nazwa dnia tygodnia",
|
||||
"Zduplikowana nazwa argumentu",
|
||||
"Ocena wyrażeń jest wyłączona",
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
fprintf(ErrFp, "\nSposób użycia: remind [opcje] plik [data] [czas] [*powtórzenie]\n");
|
||||
fprintf(ErrFp, "Opcje:\n");
|
||||
fprintf(ErrFp, " -n Wypisz następne przypomnienia w prostym formacie\n");
|
||||
fprintf(ErrFp, " -r Zablokuj dyrektywy RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Wypisz kalendarz na n (domyślnie 1) miesięcy\n");
|
||||
fprintf(ErrFp, " -c+[n] Wypisz kalendarz na n (domyślnie 1) tygodni\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Ustaw szerokość, wypełnienie i odstępy w kalendarzu\n");
|
||||
fprintf(ErrFp, " -s[+][n] Wypisz uproszczony kalendarz na n (1) miesięcy (tygodni)\n");
|
||||
fprintf(ErrFp, " -p[n] To samo co -s, ale kompatybilne z rem2ps\n");
|
||||
fprintf(ErrFp, " -v Obszerniejsze komentarze\n");
|
||||
fprintf(ErrFp, " -o Ignoruj instrukcje ONCE\n");
|
||||
fprintf(ErrFp, " -t Odpal wszystkie przyszłe przypomnienia niezależnie od delty\n");
|
||||
fprintf(ErrFp, " -h Praca bezszmerowa\n");
|
||||
fprintf(ErrFp, " -a Nie odpalaj przyponień czasowych - kolejkuj je\n");
|
||||
fprintf(ErrFp, " -q Nie kolejkuj przyponień czasowych\n");
|
||||
fprintf(ErrFp, " -f Nie przechodź do pracy w tle\n");
|
||||
fprintf(ErrFp, " -z[n] Pracuj jako demon, budząc się co n (5) minut\n");
|
||||
fprintf(ErrFp, " -d... Odpluskwianie: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Komunikaty o błędach skieruj na stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=żaden\n");
|
||||
fprintf(ErrFp, " -x[n] Limit powtórzeń klauzuli SATISFY (domyślnie=1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Wywołaj 'cmd' dla przypomnień typu MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia według daty, czasu i priorytetu\n");
|
||||
fprintf(ErrFp, " -ivar=val Zainicjuj zmienną var wartościa val i zachowaj ja\n");
|
||||
fprintf(ErrFp, " -m Rozpocznij kalendarz od poniedziałku zamiast od niedzieli\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
@@ -1,290 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* PORTBR.H */
|
||||
/* */
|
||||
/* Support for the Brazilian Portuguese Language. */
|
||||
/* */
|
||||
/* Contributed by Marco Paganini (paganini@ism.com.br). */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1996 by Marco Paganini and */
|
||||
/* Dianne Skoll. */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Brazilian Portuguese"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "domingo"
|
||||
#define L_MONDAY "segunda"
|
||||
#define L_TUESDAY "terca"
|
||||
#define L_WEDNESDAY "quarta"
|
||||
#define L_THURSDAY "quinta"
|
||||
#define L_FRIDAY "sexta"
|
||||
#define L_SATURDAY "sabado"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "janeiro"
|
||||
#define L_FEB "fevereiro"
|
||||
#define L_MAR "marco"
|
||||
#define L_APR "abril"
|
||||
#define L_MAY "maio"
|
||||
#define L_JUN "junho"
|
||||
#define L_JUL "julho"
|
||||
#define L_AUG "agosto"
|
||||
#define L_SEP "setembro"
|
||||
#define L_OCT "outubro"
|
||||
#define L_NOV "novembro"
|
||||
#define L_DEC "dezembro"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "hoje"
|
||||
#define L_TOMORROW "amanha"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Avisos para %w, %d de %m de %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "atras"
|
||||
#define L_FROMNOW "adiante"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "em %d dias"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "em"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "agora"
|
||||
#define L_AT "as"
|
||||
#define L_MINUTE "minuto"
|
||||
#define L_HOUR "hora"
|
||||
#define L_IS "sao"
|
||||
#define L_WAS "eram"
|
||||
#define L_AND "e"
|
||||
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "s"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "s"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#define L_ORDINAL_OVERRIDE plu = "";
|
||||
|
||||
/* Portuguese weekdays must be treated separately */
|
||||
#define _ON_WEEKDAY(x) ((x % 7) < 2) ? "no" : "na"
|
||||
|
||||
#define L_A_OVER \
|
||||
sprintf(s, "%s %s, %d de %s de %d", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m], y);
|
||||
|
||||
#define L_C_OVER \
|
||||
sprintf(s, "%s %s", _ON_WEEKDAY(dse), DayName[dse%7]);
|
||||
|
||||
#define L_G_OVER \
|
||||
sprintf(s, "%s %s, %d %s", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m]);
|
||||
|
||||
#define L_J_OVER \
|
||||
sprintf(s, "%s %s, %d de %s de %d", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m], y);
|
||||
|
||||
#define L_K_OVER \
|
||||
sprintf(s, "%s %s, %d de %s", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m]);
|
||||
|
||||
/* Portuguese does not use some suffixes, some some %u and %j are the same */
|
||||
#define L_U_OVER \
|
||||
sprintf(s, "%s %s, %d de %s de %d", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m], y);
|
||||
|
||||
#define L_V_OVER \
|
||||
sprintf(s, "%s %s, %d de %s", _ON_WEEKDAY(dse), DayName[dse%7], d, MonthName[m]);
|
||||
|
||||
#define L_1_OVER \
|
||||
{ \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else \
|
||||
if (hdiff == 0) \
|
||||
{ \
|
||||
if (mdiff > 0) \
|
||||
sprintf(s, "em %d %s%s", mdiff, L_MINUTE, mplu); \
|
||||
else \
|
||||
sprintf(s, "%d %s%s atras", mdiff, L_MINUTE, mplu); \
|
||||
} \
|
||||
else if (mdiff == 0) \
|
||||
{ \
|
||||
if (hdiff > 0) \
|
||||
sprintf(s, "em %d %s%s", hdiff, L_HOUR, hplu); \
|
||||
else \
|
||||
sprintf(s, "%d %s%s atras", hdiff, L_HOUR, hplu); \
|
||||
} else { \
|
||||
if (tdiff > 0) \
|
||||
sprintf(s, "em %d %s%s %s %d %s%s", hdiff, L_HOUR, hplu, L_AND, mdiff, L_MINUTE, mplu); \
|
||||
else \
|
||||
sprintf(s, "%d %s%s %s %d %s%s atras", hdiff, L_HOUR, hplu, L_AND, mdiff, L_MINUTE, mplu); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
"Ok",
|
||||
"Falta um ']'",
|
||||
"Falta uma aspa",
|
||||
"Expressao muito complexa",
|
||||
"Expressao muito complexa - muitos operandos",
|
||||
"Falta um ')'",
|
||||
"Funcao nao definida",
|
||||
"Caracter ilegal",
|
||||
"Esperando operador binario",
|
||||
"Sem memoria",
|
||||
"Numero mal-formado",
|
||||
"Op stack underflow - erro interno",
|
||||
"Va stack underflow - erro interno",
|
||||
"Nao consigo fazer 'coerce'",
|
||||
"Type mismatch",
|
||||
"Overflow na data",
|
||||
"Erro de stack - erro interno",
|
||||
"Divisao por zero",
|
||||
"Variavel nao definida",
|
||||
"Fim da linha nao esperado",
|
||||
"Fim de arquivo nao esperado",
|
||||
"Erro de I/O",
|
||||
"Linha muito longa",
|
||||
"Erro interno",
|
||||
"Especificacao de data invalida",
|
||||
"Argumentos insuficientes",
|
||||
"Argumentos em excesso",
|
||||
"Hora mal-formada",
|
||||
"Numero muito grande",
|
||||
"Numero muito pequeno",
|
||||
"Nao consigo abrir o arquivo",
|
||||
"Ninho de INCLUDEs muito profundo",
|
||||
"Erro de parsing",
|
||||
"Nao consigo computar o 'trigger'",
|
||||
"Muitos IFs aninhados",
|
||||
"ELSE sem o IF correspondente",
|
||||
"ENDIF sem o IF correspondente",
|
||||
"Nao se pode usar OMIT para todos os dias da semana",
|
||||
"Token nao reconhecido na linha",
|
||||
"POP-OMIT-CONTEXT sem PUSH-OMIT-CONTEXT correspondente",
|
||||
"RUN desabilitado",
|
||||
"Erro de dominio",
|
||||
"Identificados invalido",
|
||||
"Chamada de funcao recursiva detectada",
|
||||
"",
|
||||
"Nao posso modificar variavel de sistema",
|
||||
"Funcao da biblioteca C nao pode representar data/hora",
|
||||
"Tentativa de redefinir funcao interna",
|
||||
"Nao e' possivel aninhar definicao de funcao em expressao",
|
||||
"Data deve ser completamente especificada para usar o fator de REPEAT",
|
||||
"Ano especificado duas vezes",
|
||||
"Mes especificado duas vezes",
|
||||
"Dia especificado duas vezes",
|
||||
"Token desconhecido",
|
||||
"O mes deve ser especificados no comando OMIT",
|
||||
"Muitos OMITs parciais",
|
||||
"Muitos OMITs full",
|
||||
"Aviso: PUSH-OMIT-CONTEXT sem POP-OMIT-CONTEXT correspondente",
|
||||
"Erro na leitura do arquivo",
|
||||
"Aguardando fim do arquivo",
|
||||
"Data hebraica invalida",
|
||||
"IIF necessita de numero impar de argumentos",
|
||||
"Warning: ENDIF faltando",
|
||||
"Esperando virgula",
|
||||
"Dia da semana especificado duas vezes",
|
||||
"Use apenas um de BEFORE, AFTER ou SKIP",
|
||||
"Nao e possivel aninhar MSG, MSF, RUN, etc. em expressoes",
|
||||
"Valor de Repeat especificado duas vezes",
|
||||
"Valor de Delta especificado duas vezes",
|
||||
"Valor de Back especificado duas vezes",
|
||||
"ONCE usado duas vezes (Eheheh)",
|
||||
"Esperando hora apos AT",
|
||||
"Keyword THROUGH/UNTIL usada duas vezes",
|
||||
"Especificacao de data incompleta",
|
||||
"Keyword FROM/SCANFROM usada duas vezes",
|
||||
"Variavel",
|
||||
"Valor",
|
||||
"*INDEFINIDO*",
|
||||
"Entrando UserFN",
|
||||
"Saindo UserFN",
|
||||
"Expirou",
|
||||
"fork() falhou - Nao posso processar compromissos na fila",
|
||||
"Nao consigo acessar o arquivo",
|
||||
"Data do sistema ilegal: Ano e menor que %d\n",
|
||||
"Flag de debug desconhecido '%c'\n",
|
||||
"Opcao desconhecida '%c'\n",
|
||||
"Usuario desconhecido '%s'\n",
|
||||
"Nao consigo mudar gid para %d\n",
|
||||
"Nao consigo mudar uid para %d\n",
|
||||
"Sem memoria para o environment\n",
|
||||
"Falta o sinal de '='",
|
||||
"Falta o nome da variavel",
|
||||
"Falta a expressao",
|
||||
"Nao consigo resetar a data de acesso de %s\n",
|
||||
"Remind: '-i' opcao: %s\n",
|
||||
"Sem compromissos.",
|
||||
"%d compromisso(s) colocados na fila para mais tarde.\n",
|
||||
"Esperando numero",
|
||||
"Funcao ilegal na clausula WARN",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long",
|
||||
"Time specified twice",
|
||||
"Cannot specify DURATION without specifying AT",
|
||||
"Esperando nome do dia da semana",
|
||||
"Nome de argumento duplicado",
|
||||
"A avaliação da expressão está desabilitada",
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2024 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> VERSAO BETA <<<<\n");
|
||||
#endif
|
||||
fprintf(ErrFp, "Uso: remind [opcoes] arquivo [data] [hora] [*rep]\n");
|
||||
fprintf(ErrFp, "Opcoes:\n");
|
||||
fprintf(ErrFp, " -n Imprime a proxima ocorrencia em formato simples\n");
|
||||
fprintf(ErrFp, " -r Desabilita a diretiva RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Produz calendario para n (default 1) meses\n");
|
||||
fprintf(ErrFp, " -c+[n] Produz calendario para n (default 1) semanas\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Especifica largura, preenchimento e espacejamento do calendario\n");
|
||||
fprintf(ErrFp, " -s[+][n] Produz um `calendario simples' para n (1) meses (semanas)\n");
|
||||
fprintf(ErrFp, " -p[n] Identico a -s, porem com saida compativel com rem2ps\n");
|
||||
fprintf(ErrFp, " -v Modo verbose\n");
|
||||
fprintf(ErrFp, " -o Ignora diretivas ONCE\n");
|
||||
fprintf(ErrFp, " -t Aciona todos os compromissos futuros, sem considerar o delta\n");
|
||||
fprintf(ErrFp, " -h Modo `Hush' - quieto\n");
|
||||
fprintf(ErrFp, " -a Nao aciona compromissos com hora imediatamente - apenas coloca na fila\n");
|
||||
fprintf(ErrFp, " -q Nao coloca compromissos com hora na fila\n");
|
||||
fprintf(ErrFp, " -f Aciona compromissos com hora em modo foreground\n");
|
||||
fprintf(ErrFp, " -z[n] Modo `daemon', acordando a cada n (5) minutos.\n");
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trigger v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Desvia mensagens normalmente enviadas a stderr para stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Formato da hora para o cal: 0=am/pm, 1=24hr, 2=nenhum\n");
|
||||
fprintf(ErrFp, " -x[n] Limite de iteracoes para a clausula SATISFY (default=1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Executa `cmd' para os compromissos com MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Classifica compromissos por data, hora e prioridade antes de exibir\n");
|
||||
fprintf(ErrFp, " -ivar=val Inicializa (e preserva) variavel var com val\n");
|
||||
fprintf(ErrFp, " -m Inicia o calendario na segunda, ao inves de domingo\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
@@ -1,105 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ROMANIAN.H */
|
||||
/* */
|
||||
/* Support for the Romanian language. */
|
||||
/* */
|
||||
/* Contributed by Liviu Daia <daia@stoilow.imar.ro> */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1996-1998 by Liviu Daia */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Romanian"
|
||||
|
||||
/* Day names */
|
||||
# define L_SUNDAY "Duminică"
|
||||
# define L_MONDAY "Luni"
|
||||
# define L_TUESDAY "Marți"
|
||||
# define L_WEDNESDAY "Miercuri"
|
||||
# define L_THURSDAY "Joi"
|
||||
# define L_FRIDAY "Vineri"
|
||||
# define L_SATURDAY "Sâmbătă"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Ianuarie"
|
||||
#define L_FEB "Februarie"
|
||||
#define L_MAR "Martie"
|
||||
#define L_APR "Aprilie"
|
||||
#define L_MAY "Mai"
|
||||
#define L_JUN "Iunie"
|
||||
#define L_JUL "Iulie"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "Septembrie"
|
||||
#define L_OCT "Octombrie"
|
||||
#define L_NOV "Noiembrie"
|
||||
#define L_DEC "Decembrie"
|
||||
|
||||
/* Today and tomorrow */
|
||||
# define L_TODAY "astăzi"
|
||||
# define L_TOMORROW "mâine"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Reamintiri pentru %w, %d %m %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "acum"
|
||||
#define L_FROMNOW "peste"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "peste %d zile"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "pe"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "le"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "acum"
|
||||
#define L_AT "la ora"
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "or"
|
||||
#define L_IS "este"
|
||||
#define L_WAS "a fost"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "e"
|
||||
#define L_HPLU "e"
|
||||
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU_OVER hplu = (hdiff == 1 ? "ă" : "e");
|
||||
#define L_AND "şi"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<4) ? " noaptea" : " dimineaţa" : (hour > 17) ? " seara" : " după-amiaza";
|
||||
#define L_ORDINAL_OVERRIDE plu = "";
|
||||
|
||||
#define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d, MonthName[m], y);
|
||||
#define L_C_OVER sprintf(s, "%s", DayName[dse%7]);
|
||||
#define L_G_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, MonthName[m]);
|
||||
#define L_J_OVER sprintf(s, "%s, %s %d, %d", DayName[dse%7], MonthName[m], d, y);
|
||||
#define L_K_OVER sprintf(s, "%s, %s %d", DayName[dse%7], MonthName[m], d);
|
||||
#define L_S_OVER
|
||||
#define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[dse%7], d, MonthName[m], y);
|
||||
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[dse%7], d, MonthName[m]);
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "%s %d %s%s", when, mdiff, L_MINUTE, mplu); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "%s %d %s%s", when, hdiff, L_HOUR, hplu); \
|
||||
else \
|
||||
sprintf(s, "%s %d %s%s %s %d %s%s", when, hdiff, \
|
||||
L_HOUR, hplu, L_AND, mdiff, L_MINUTE, mplu);
|
||||
@@ -1,74 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SPANISH.H */
|
||||
/* */
|
||||
/* Support for the Spanish language. */
|
||||
/* */
|
||||
/* Author: Rafa Couto <rafacouto@biogate.com> */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 by Dianne Skoll */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#define L_LANGNAME "Spanish"
|
||||
|
||||
/* Nombres de los di'as de la semana */
|
||||
#define L_SUNDAY "Domingo"
|
||||
#define L_MONDAY "Lunes"
|
||||
#define L_TUESDAY "Martes"
|
||||
#define L_WEDNESDAY "Miércoles"
|
||||
#define L_THURSDAY "Jueves"
|
||||
#define L_FRIDAY "Viernes"
|
||||
#define L_SATURDAY "Sábado"
|
||||
|
||||
/* Nombres de los meses */
|
||||
#define L_JAN "Enero"
|
||||
#define L_FEB "Febrero"
|
||||
#define L_MAR "Marzo"
|
||||
#define L_APR "Abril"
|
||||
#define L_MAY "Mayo"
|
||||
#define L_JUN "Junio"
|
||||
#define L_JUL "Julio"
|
||||
#define L_AUG "Agosto"
|
||||
#define L_SEP "Septiembre"
|
||||
#define L_OCT "Octubre"
|
||||
#define L_NOV "Noviembre"
|
||||
#define L_DEC "Diciembre"
|
||||
|
||||
/* Hoy y man~ana */
|
||||
#define L_TODAY "hoy"
|
||||
#define L_TOMORROW "mañana"
|
||||
|
||||
/* El titular habitual */
|
||||
#define L_BANNER "Agenda para el %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/* Hace y desde hoy */
|
||||
#define L_AGO "hace"
|
||||
#define L_FROMNOW "desde hoy"
|
||||
|
||||
/* "dentro de %d di'as" */
|
||||
#define L_INXDAYS "dentro de %d días"
|
||||
#define L_ON "el día"
|
||||
|
||||
/* "el di'a..." */
|
||||
|
||||
/* plurales */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutos, horas, a las, etc */
|
||||
#define L_NOW "ahora"
|
||||
#define L_AT "a las"
|
||||
#define L_MINUTE "minuto"
|
||||
#define L_HOUR "hora"
|
||||
#define L_IS "es"
|
||||
#define L_WAS "fue"
|
||||
#define L_AND "y"
|
||||
#define L_HPLU "s"
|
||||
#define L_MPLU "s"
|
||||
|
||||
204
src/main.c
204
src/main.c
@@ -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) {
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
get_var_hash_stats(&total, &maxlen, &avglen);
|
||||
fprintf(stderr, " Var hash: total = %d; maxlen = %d; avglen = %.3f\n", total, maxlen, avglen);
|
||||
get_userfunc_hash_stats(&total, &maxlen, &avglen);
|
||||
fprintf(stderr, " Func hash: total = %d; maxlen = %d; avglen = %.3f\n", total, maxlen, avglen);
|
||||
get_dedupe_hash_stats(&total, &maxlen, &avglen);
|
||||
fprintf(stderr, "Dedup hash: total = %d; maxlen = %d; avglen = %.3f\n", total, maxlen, avglen);
|
||||
fflush(ErrFp);
|
||||
fprintf(ErrFp, "Variable hash table statistics:\n");
|
||||
dump_var_hash_stats();
|
||||
|
||||
fprintf(ErrFp, "Function hash table statistics:\n");
|
||||
dump_userfunc_hash_stats();
|
||||
|
||||
fprintf(ErrFp, "Dedupe hash table statistics:\n");
|
||||
dump_dedupe_hash_stats();
|
||||
|
||||
fprintf(ErrFp, "Translation hash table statistics:\n");
|
||||
dump_translation_hash_stats();
|
||||
|
||||
UnsetAllUserFuncs();
|
||||
print_expr_nodes_stats();
|
||||
}
|
||||
@@ -126,7 +130,7 @@ int main(int argc, char *argv[])
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = SA_RESTART;
|
||||
if (sigaction(SIGALRM, &act, NULL) < 0) {
|
||||
fprintf(stderr, "%s: sigaction() failed: %s\n",
|
||||
fprintf(ErrFp, "%s: sigaction() failed: %s\n",
|
||||
argv[0], strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
@@ -135,7 +139,7 @@ int main(int argc, char *argv[])
|
||||
act.sa_flags = SA_RESTART;
|
||||
sigemptyset(&act.sa_mask);
|
||||
if (sigaction(SIGXCPU, &act, NULL) < 0) {
|
||||
fprintf(stderr, "%s: sigaction() failed: %s\n",
|
||||
fprintf(ErrFp, "%s: sigaction() failed: %s\n",
|
||||
argv[0], strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
@@ -170,11 +174,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (!Hush) {
|
||||
if (DestroyOmitContexts(1))
|
||||
Eprint("%s", ErrMsg[E_PUSH_NOPOP]);
|
||||
Eprint("%s", GetErr(E_PUSH_NOPOP));
|
||||
if (!Daemon && !NextMode && !NumTriggered && !NumQueued) {
|
||||
printf("%s\n", ErrMsg[E_NOREMINDERS]);
|
||||
printf("%s\n", GetErr(E_NOREMINDERS));
|
||||
} else if (!Daemon && !NextMode && !NumTriggered) {
|
||||
printf(ErrMsg[M_QUEUED], NumQueued);
|
||||
printf(GetErr(M_QUEUED), NumQueued);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +198,7 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
if (pid == -1) {
|
||||
fprintf(ErrFp, "%s", ErrMsg[E_CANTFORK]);
|
||||
fprintf(ErrFp, "%s", GetErr(E_CANTFORK));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -256,14 +260,14 @@ static void DoReminders(void)
|
||||
}
|
||||
|
||||
if (FileAccessDate < 0) {
|
||||
fprintf(ErrFp, "%s: `%s': %s.\n", ErrMsg[E_CANTACCESS], InitialFile, strerror(errno));
|
||||
fprintf(ErrFp, "%s: `%s': %s.\n", GetErr(E_CANTACCESS), InitialFile, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
r=IncludeFile(InitialFile);
|
||||
if (r) {
|
||||
fprintf(ErrFp, "%s %s: %s\n", ErrMsg[E_ERR_READING],
|
||||
InitialFile, ErrMsg[r]);
|
||||
fprintf(ErrFp, "%s %s: %s\n", GetErr(E_ERR_READING),
|
||||
InitialFile, GetErr(r));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -271,7 +275,7 @@ static void DoReminders(void)
|
||||
r = ReadLine();
|
||||
if (r == E_EOF) return;
|
||||
if (r) {
|
||||
Eprint("%s: %s", ErrMsg[E_ERR_READING], ErrMsg[r]);
|
||||
Eprint("%s: %s", GetErr(E_ERR_READING), GetErr(r));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
s = FindInitialToken(&tok, CurLine);
|
||||
@@ -312,6 +316,7 @@ static void DoReminders(void)
|
||||
case T_EndIf: r=DoEndif(&p); break;
|
||||
case T_Include:
|
||||
case T_IncludeR:
|
||||
case T_IncludeSys:
|
||||
/* In purge mode, include closes file, so we
|
||||
need to echo it here! */
|
||||
if (PurgeMode) {
|
||||
@@ -352,6 +357,7 @@ static void DoReminders(void)
|
||||
case T_Preserve: r=DoPreserve(&p); break;
|
||||
case T_Push: r=PushOmitContext(&p); break;
|
||||
case T_Expr: r = DoExpr(&p); break;
|
||||
case T_Translate: r = DoTranslate(&p); break;
|
||||
case T_RemType: if (tok.val == RUN_TYPE) {
|
||||
r=DoRun(&p);
|
||||
} else {
|
||||
@@ -378,14 +384,14 @@ static void DoReminders(void)
|
||||
|
||||
}
|
||||
if (r && (!Hush || r != E_RUN_DISABLED)) {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
if (PurgeMode) {
|
||||
if (!purge_handled) {
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
} else {
|
||||
if (r) {
|
||||
PurgeEchoLine("#!P! Could not parse next line: %s\n", ErrMsg[r]);
|
||||
PurgeEchoLine("#!P! Could not parse next line: %s\n", GetErr(r));
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
}
|
||||
@@ -596,6 +602,100 @@ int ParseNonSpaceChar(ParsePtr p, int *err, int peek)
|
||||
return ch;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseTokenOrQuotedString */
|
||||
/* */
|
||||
/* Parse either a token or a double-quote-delimited string. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ParseTokenOrQuotedString(ParsePtr p, DynamicBuffer *dbuf)
|
||||
{
|
||||
int c, err;
|
||||
c = ParseNonSpaceChar(p, &err, 1);
|
||||
if (err) return err;
|
||||
if (c != '"') {
|
||||
return ParseToken(p, dbuf);
|
||||
}
|
||||
return ParseQuotedString(p, dbuf);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseQuotedString */
|
||||
/* */
|
||||
/* Parse a double-quote-delimited string. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ParseQuotedString(ParsePtr p, DynamicBuffer *dbuf)
|
||||
{
|
||||
int c, err;
|
||||
DBufFree(dbuf);
|
||||
c = ParseNonSpaceChar(p, &err, 0);
|
||||
if (err) return err;
|
||||
if (!c) {
|
||||
return E_EOLN;
|
||||
}
|
||||
if (c != '"') {
|
||||
return E_MISS_QUOTE;
|
||||
}
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
while (c != 0 && c != '"') {
|
||||
if (c == '\\') {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
switch(c) {
|
||||
case 'a':
|
||||
err = DBufPutc(dbuf, '\a');
|
||||
break;
|
||||
case 'b':
|
||||
err = DBufPutc(dbuf, '\b');
|
||||
break;
|
||||
case 'f':
|
||||
err = DBufPutc(dbuf, '\f');
|
||||
break;
|
||||
case 'n':
|
||||
err = DBufPutc(dbuf, '\n');
|
||||
break;
|
||||
case 'r':
|
||||
err = DBufPutc(dbuf, '\r');
|
||||
break;
|
||||
case 't':
|
||||
err = DBufPutc(dbuf, '\t');
|
||||
break;
|
||||
case 'v':
|
||||
err = DBufPutc(dbuf, '\v');
|
||||
break;
|
||||
default:
|
||||
err = DBufPutc(dbuf, c);
|
||||
}
|
||||
} else {
|
||||
err = DBufPutc(dbuf, c);
|
||||
}
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
if (c != '"') {
|
||||
DBufFree(dbuf);
|
||||
return E_MISS_QUOTE;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseToken */
|
||||
@@ -970,7 +1070,7 @@ int DoIf(ParsePtr p)
|
||||
else {
|
||||
if ( (r = EvaluateExpr(p, &v)) ) {
|
||||
syndrome = IF_TRUE | BEFORE_ELSE;
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
} else
|
||||
if ( (v.type != STR_TYPE && v.v.val) ||
|
||||
(v.type == STR_TYPE && strcmp(v.v.str, "")) ) {
|
||||
@@ -1055,7 +1155,7 @@ int DoIfTrig(ParsePtr p)
|
||||
if (r) {
|
||||
if (r != E_CANT_TRIG || !trig.maybe_uncomputable) {
|
||||
if (!Hush || r != E_RUN_DISABLED) {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
Eprint("%s", GetErr(r));
|
||||
}
|
||||
}
|
||||
syndrome = IF_FALSE | BEFORE_ELSE;
|
||||
@@ -1119,7 +1219,7 @@ int VerifyEoln(ParsePtr p)
|
||||
if (*DBufValue(&buf) &&
|
||||
(*DBufValue(&buf) != '#') &&
|
||||
(*DBufValue(&buf) != ';')) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_EXPECTING_EOL], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(E_EXPECTING_EOL), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return E_EXTRANEOUS_TOKEN;
|
||||
}
|
||||
@@ -1900,8 +2000,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 +2009,7 @@ get_month_name(int mon)
|
||||
if (mon < 0 || mon > 11) {
|
||||
return "INVALID_MON";
|
||||
}
|
||||
if (DynamicMonthName[mon]) return DynamicMonthName[mon];
|
||||
return MonthName[mon];
|
||||
return tr(MonthName[mon]);
|
||||
}
|
||||
|
||||
static int GetOnceDateFromFile(void)
|
||||
@@ -1950,3 +2048,53 @@ int GetOnceDate(void)
|
||||
}
|
||||
return OnceDate;
|
||||
}
|
||||
|
||||
static void
|
||||
get_printf_escapes(char const *str, DynamicBuffer *out)
|
||||
{
|
||||
char const *s = str;
|
||||
while(*s) {
|
||||
if (*s == '%' && *(s+1) != 0) {
|
||||
s++;
|
||||
DBufPutc(out, *s);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
char const *GetErr(int r)
|
||||
{
|
||||
char const *msg;
|
||||
DynamicBuffer origEscapes;
|
||||
DynamicBuffer translatedEscapes;
|
||||
int dangerous;
|
||||
|
||||
if (r < 0 || r >= NumErrs) {
|
||||
r = E_SWERR;
|
||||
}
|
||||
|
||||
msg = GetTranslatedString(ErrMsg[r]);
|
||||
if (!msg) {
|
||||
return ErrMsg[r];
|
||||
}
|
||||
|
||||
/* We need to make sure both the original and translated version
|
||||
have the *SAME* printf-style escapes to avoid a malicious
|
||||
translation file doing a format-string attack */
|
||||
DBufInit(&origEscapes);
|
||||
DBufInit(&translatedEscapes);
|
||||
|
||||
get_printf_escapes(ErrMsg[r], &origEscapes);
|
||||
get_printf_escapes(msg, &translatedEscapes);
|
||||
|
||||
dangerous = strcmp(DBufValue(&origEscapes), DBufValue(&translatedEscapes));
|
||||
|
||||
DBufFree(&origEscapes);
|
||||
DBufFree(&translatedEscapes);
|
||||
|
||||
if (dangerous) {
|
||||
return ErrMsg[r];
|
||||
} else {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
34
src/omit.c
34
src/omit.c
@@ -116,10 +116,9 @@ int DestroyOmitContexts(int print_unmatched)
|
||||
/***************************************************************/
|
||||
int PushOmitContext(ParsePtr p)
|
||||
{
|
||||
register int i;
|
||||
OmitContext *context;
|
||||
|
||||
/* Create the saved context */
|
||||
/* Create the saved context */
|
||||
context = NEW(OmitContext);
|
||||
if (!context) return E_NO_MEM;
|
||||
|
||||
@@ -152,14 +151,11 @@ int PushOmitContext(ParsePtr p)
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
/* Copy the context over */
|
||||
for (i=0; i<NumFullOmits; i++)
|
||||
*(context->fullsave + i) = FullOmitArray[i];
|
||||
/* Copy the context over */
|
||||
memcpy(context->fullsave, FullOmitArray, NumFullOmits * sizeof(int));
|
||||
memcpy(context->partsave, PartialOmitArray, NumPartialOmits * sizeof(int));
|
||||
|
||||
for (i=0; i<NumPartialOmits; i++)
|
||||
*(context->partsave + i) = PartialOmitArray[i];
|
||||
|
||||
/* Add the context to the stack */
|
||||
/* Add the context to the stack */
|
||||
context->next = SavedOmitContexts;
|
||||
SavedOmitContexts = context;
|
||||
return VerifyEoln(p);
|
||||
@@ -175,7 +171,6 @@ int PushOmitContext(ParsePtr p)
|
||||
int PopOmitContext(ParsePtr p)
|
||||
{
|
||||
|
||||
register int i;
|
||||
OmitContext *c = SavedOmitContexts;
|
||||
|
||||
if (!c) return E_POP_NO_PUSH;
|
||||
@@ -183,17 +178,14 @@ int PopOmitContext(ParsePtr p)
|
||||
NumPartialOmits = c->numpart;
|
||||
WeekdayOmits = c->weekdaysave;
|
||||
|
||||
/* Copy the context over */
|
||||
for (i=0; i<NumFullOmits; i++)
|
||||
FullOmitArray[i] = *(c->fullsave + i);
|
||||
/* Copy the context over */
|
||||
memcpy(FullOmitArray, c->fullsave, NumFullOmits * sizeof(int));
|
||||
memcpy(PartialOmitArray, c->partsave, NumPartialOmits * sizeof(int));
|
||||
|
||||
for (i=0; i<NumPartialOmits; i++)
|
||||
PartialOmitArray[i] = *(c->partsave + i);
|
||||
|
||||
/* Remove the context from the stack */
|
||||
/* Remove the context from the stack */
|
||||
SavedOmitContexts = c->next;
|
||||
|
||||
/* Free memory used by the saved context */
|
||||
/* Free memory used by the saved context */
|
||||
if (c->partsave) free(c->partsave);
|
||||
if (c->fullsave) free(c->fullsave);
|
||||
if (c->filename) free(c->filename);
|
||||
@@ -402,9 +394,9 @@ int DoOmit(ParsePtr p)
|
||||
if (tok.type == T_Until) {
|
||||
Eprint("OMIT: UNTIL not allowed; did you mean THROUGH?");
|
||||
} else if (tok.type == T_Illegal && tok.val < 0) {
|
||||
Eprint("%s: `%s'", ErrMsg[-tok.val], DBufValue(&buf));
|
||||
Eprint("%s: `%s'", GetErr(-tok.val), DBufValue(&buf));
|
||||
} else {
|
||||
Eprint("%s: `%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN],
|
||||
Eprint("%s: `%s' (OMIT)", GetErr(E_UNKNOWN_TOKEN),
|
||||
DBufValue(&buf));
|
||||
}
|
||||
DBufFree(&buf);
|
||||
@@ -552,7 +544,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
src/protos.h
24
src/protos.h
@@ -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);
|
||||
@@ -250,11 +256,21 @@ void print_builtinfunc_tokens(void);
|
||||
void print_remind_tokens(void);
|
||||
|
||||
/* Stats for -ds output */
|
||||
void get_var_hash_stats(int *total, int *maxlen, double *avglen);
|
||||
void get_userfunc_hash_stats(int *total, int *maxlen, double *avglen);
|
||||
void get_dedupe_hash_stats(int *total, int *maxlen, double *avglen);
|
||||
void dump_var_hash_stats(void);
|
||||
void dump_userfunc_hash_stats(void);
|
||||
void dump_dedupe_hash_stats(void);
|
||||
void dump_translation_hash_stats(void);
|
||||
|
||||
/* Dedupe code */
|
||||
int ShouldDedupe(int trigger_date, int trigger_time, char const *body);
|
||||
void ClearDedupeTable(void);
|
||||
void InitDedupeTable(void);
|
||||
|
||||
void InitVars(void);
|
||||
void InitUserFunctions(void);
|
||||
void InitTranslationTable(void);
|
||||
char const *GetTranslatedString(char const *orig);
|
||||
int GetTranslatedStringTryingVariants(char const *orig, DynamicBuffer *out);
|
||||
char const *GetErr(int r);
|
||||
char const *tr(char const *s);
|
||||
void print_escaped_string(FILE *fp, char const *s);
|
||||
|
||||
70
src/queue.c
70
src/queue.c
@@ -815,6 +815,11 @@ static void ServerWait(struct timeval *sleep_tv)
|
||||
int y, m, d;
|
||||
int max = 1;
|
||||
char cmdLine[256];
|
||||
char *s;
|
||||
int r;
|
||||
DynamicBuffer tx;
|
||||
|
||||
DBufInit(&tx);
|
||||
|
||||
FD_ZERO(&readSet);
|
||||
FD_SET(0, &readSet);
|
||||
@@ -868,9 +873,32 @@ static void ServerWait(struct timeval *sleep_tv)
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* Read a line from stdin and interpret it */
|
||||
if (!fgets(cmdLine, sizeof(cmdLine), stdin)) {
|
||||
exit(EXIT_SUCCESS);
|
||||
/* Read a line using read() one char at a time to avoid resetting
|
||||
* readability if we get two commands quickly */
|
||||
|
||||
s = cmdLine;
|
||||
*s = 0;
|
||||
while (1) {
|
||||
r = read(fileno(stdin), s, 1);
|
||||
if (r == 0) {
|
||||
/* EOF */
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
if (r != 1) {
|
||||
/* Error? */
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
*(s+1) = 0;
|
||||
if (*s == '\n') {
|
||||
break;
|
||||
}
|
||||
if ((size_t) (s - cmdLine) >= sizeof(cmdLine)-1) {
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
if (!strcmp(cmdLine, "EXIT\n")) {
|
||||
@@ -917,6 +945,42 @@ static void ServerWait(struct timeval *sleep_tv)
|
||||
printf("NOTE ENDJSONQUEUE\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
} else if (DaemonJSON && !strncmp(cmdLine, "TRANSLATE ", 10)) {
|
||||
/* Cut off the trailing "\n" */
|
||||
if (*(cmdLine + strlen(cmdLine)-1) == '\n') {
|
||||
*(cmdLine + strlen(cmdLine)-1) = 0;
|
||||
}
|
||||
|
||||
r = GetTranslatedStringTryingVariants(cmdLine+10, &tx);
|
||||
|
||||
/* Output NOTHING if there's no translation */
|
||||
if (r) {
|
||||
printf("{");
|
||||
PrintJSONKeyPairString("response", "translate");
|
||||
printf("\"translation\":{\"");
|
||||
PrintJSONString(cmdLine+10);
|
||||
printf("\":\"");
|
||||
PrintJSONString(DBufValue(&tx));
|
||||
DBufFree(&tx);
|
||||
printf("\"},");
|
||||
printf("\"command\":\"TRANSLATE\"}\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
} else if (!strcmp(cmdLine, "TRANSLATE_DUMP\n")) {
|
||||
if (!DaemonJSON) {
|
||||
printf("NOTE TRANSLATE_DUMP\n");
|
||||
} else {
|
||||
printf("{");
|
||||
PrintJSONKeyPairString("response", "translate_dump");
|
||||
printf("\"table\":");
|
||||
}
|
||||
DumpTranslationTable(stdout, 1);
|
||||
if (!DaemonJSON) {
|
||||
printf("\nNOTE ENDTRANSLATE_DUMP\n");
|
||||
} else {
|
||||
printf(",\"command\":\"TRANSLATE_DUMP\"}\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
} else if (!strcmp(cmdLine, "REREAD\n")) {
|
||||
if (DaemonJSON) {
|
||||
printf("{\"response\":\"reread\",\"command\":\"REREAD\"}\n");
|
||||
|
||||
@@ -357,6 +357,7 @@ int main(int argc, char *argv[])
|
||||
validfile++;
|
||||
DoPsCal();
|
||||
}
|
||||
DBufFree(&buf);
|
||||
}
|
||||
if (!validfile) {
|
||||
fprintf(stderr, "Rem2PS: Couldn't find any calendar data - are you\n");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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 },
|
||||
|
||||
393
src/trans.c
Normal file
393
src/trans.c
Normal file
@@ -0,0 +1,393 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* TRANS.C */
|
||||
/* */
|
||||
/* Functions to manage the translation table. Implements */
|
||||
/* the TRANSLATE keyword. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2024 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;
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* 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)
|
||||
{
|
||||
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:
|
||||
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 = FindTranslation(orig);
|
||||
if (item) {
|
||||
if (!strcmp(item->translated, translated)) {
|
||||
/* Translation is the same; do nothing */
|
||||
return OK;
|
||||
}
|
||||
RemoveTranslation(item);
|
||||
}
|
||||
|
||||
/* TRANSLATE "foo" "foo" means to remove the translation */
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
71
src/types.h
71
src/types.h
@@ -12,18 +12,23 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include "dynbuf.h"
|
||||
#include "hashtab.h"
|
||||
|
||||
typedef struct udf_struct UserFunc;
|
||||
|
||||
/* Define the types of values */
|
||||
#define ERR_TYPE 0
|
||||
#define INT_TYPE 1
|
||||
#define TIME_TYPE 2
|
||||
#define DATE_TYPE 3
|
||||
#define STR_TYPE 4
|
||||
#define DATETIME_TYPE 5
|
||||
#define SPECIAL_TYPE 6 /* Only for system variables */
|
||||
#define CONST_INT_TYPE 7 /* Only for system variables */
|
||||
/* Define the types of values. We use bitmasks so we can define
|
||||
DATETIME_TYPE as a combo of DATE_TYPE and TIME_TYPE */
|
||||
|
||||
#define ERR_TYPE 0x0
|
||||
#define INT_TYPE 0x1
|
||||
#define TIME_TYPE 0x2
|
||||
#define DATE_TYPE 0x4
|
||||
/* DATETIME_TYPE has both DATE and TIME bits turned on */
|
||||
#define DATETIME_TYPE (TIME_TYPE | DATE_TYPE)
|
||||
#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 ']'
|
||||
@@ -96,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;
|
||||
@@ -206,42 +211,20 @@ typedef Parser *ParsePtr; /* Pointer to parser structure */
|
||||
/* Enumeration of the tokens */
|
||||
enum TokTypes
|
||||
{ T_Illegal,
|
||||
/* Commands first */
|
||||
T_Rem, T_Push, T_Pop, T_Preserve, T_Include, T_IncludeR, T_IncludeCmd, T_If, T_Else, T_EndIf,
|
||||
T_IfTrig, T_ErrMsg,
|
||||
T_Set, T_UnSet, T_Fset, T_Funset, T_Frename, T_Omit, T_Banner, T_Exit,
|
||||
T_AddOmit, T_NoQueue,
|
||||
T_WkDay,
|
||||
T_Month, T_Time, T_Date, T_DateTime,
|
||||
T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta,
|
||||
T_Back, T_BackAdj,
|
||||
T_Once,
|
||||
T_Empty,
|
||||
T_Comment,
|
||||
T_Number,
|
||||
T_Clr,
|
||||
T_Debug,
|
||||
T_Dumpvars,
|
||||
T_Scanfrom,
|
||||
T_Flush,
|
||||
T_Priority,
|
||||
T_Sched,
|
||||
T_Warn,
|
||||
T_Tag,
|
||||
T_Duration,
|
||||
T_LongTime,
|
||||
T_OmitFunc,
|
||||
T_Through,
|
||||
T_MaybeUncomputable,
|
||||
T_Ordinal,
|
||||
T_In,
|
||||
T_LastBack,
|
||||
T_Expr
|
||||
T_AddOmit, T_At, T_Back, T_BackAdj, T_Banner, T_Clr, T_Comment,
|
||||
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_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_Translate, T_UnSet, T_Until, T_Warn, T_WkDay, T_Year
|
||||
};
|
||||
|
||||
/* The structure of a token */
|
||||
typedef struct {
|
||||
char *name;
|
||||
char const *name;
|
||||
char MinLen;
|
||||
enum TokTypes type;
|
||||
int val;
|
||||
@@ -303,14 +286,14 @@ typedef struct {
|
||||
char const *name;
|
||||
char modifiable;
|
||||
int type;
|
||||
void *value;
|
||||
void const *value;
|
||||
int min; /* Or const-value */
|
||||
int max;
|
||||
} SysVar;
|
||||
|
||||
/* 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;
|
||||
|
||||
139
src/userfns.c
139
src/userfns.c
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
@@ -27,23 +28,46 @@
|
||||
#include "protos.h"
|
||||
#include "err.h"
|
||||
|
||||
#define FUNC_HASH_SIZE 31 /* Size of User-defined function hash table */
|
||||
|
||||
/* The hash table */
|
||||
static UserFunc *FuncHash[FUNC_HASH_SIZE];
|
||||
hash_table FuncHash;
|
||||
|
||||
static void DestroyUserFunc (UserFunc *f);
|
||||
static void FUnset (char const *name);
|
||||
static void FSet (UserFunc *f);
|
||||
static void RenameUserFunc(char const *oldname, char const *newname);
|
||||
|
||||
static unsigned int HashUserFunc(void *x)
|
||||
{
|
||||
UserFunc *f = (UserFunc *) x;
|
||||
return HashVal_preservecase(f->name);
|
||||
}
|
||||
|
||||
static int CompareUserFuncs(void *a, void *b)
|
||||
{
|
||||
UserFunc *f = (UserFunc *) a;
|
||||
UserFunc *g = (UserFunc *) b;
|
||||
return strcmp(f->name, g->name);
|
||||
}
|
||||
|
||||
void
|
||||
InitUserFunctions(void)
|
||||
{
|
||||
if (hash_table_init(&FuncHash,
|
||||
offsetof(UserFunc, link),
|
||||
HashUserFunc,
|
||||
CompareUserFuncs) < 0) {
|
||||
fprintf(ErrFp, "Unable to initialize function hash table: Out of memory. Exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HashVal */
|
||||
/* HashVal_preservecase */
|
||||
/* Given a string, compute the hash value. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
unsigned int HashVal_nocase(char const *str)
|
||||
unsigned int HashVal_preservecase(char const *str)
|
||||
{
|
||||
unsigned int h = 0, high;
|
||||
while(*str) {
|
||||
@@ -93,13 +117,13 @@ int DoFrename(ParsePtr p)
|
||||
return r;
|
||||
}
|
||||
if (FindBuiltinFunc(DBufValue(&newbuf))) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_REDEF_FUNC], DBufValue(&newbuf));
|
||||
Eprint("%s: `%s'", GetErr(E_REDEF_FUNC), DBufValue(&newbuf));
|
||||
DBufFree(&oldbuf);
|
||||
DBufFree(&newbuf);
|
||||
return E_REDEF_FUNC;
|
||||
}
|
||||
if (FindBuiltinFunc(DBufValue(&oldbuf))) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_REDEF_FUNC], DBufValue(&oldbuf));
|
||||
Eprint("%s: `%s'", GetErr(E_REDEF_FUNC), DBufValue(&oldbuf));
|
||||
DBufFree(&oldbuf);
|
||||
DBufFree(&newbuf);
|
||||
return E_REDEF_FUNC;
|
||||
@@ -219,7 +243,7 @@ int DoFset(ParsePtr p)
|
||||
DBufFree(&buf);
|
||||
if (!Hush) {
|
||||
if (FindBuiltinFunc(func->name)) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_REDEF_FUNC], func->name);
|
||||
Eprint("%s: `%s'", GetErr(E_REDEF_FUNC), func->name);
|
||||
}
|
||||
}
|
||||
func->node = NULL;
|
||||
@@ -257,8 +281,8 @@ int DoFset(ParsePtr p)
|
||||
}
|
||||
local_array[i].v.type = ERR_TYPE;
|
||||
StrnCpy(local_array[i].name, DBufValue(&buf), VAR_NAME_LEN);
|
||||
local_array[i].next = &(local_array[i+1]);
|
||||
local_array[i+1].next = NULL;
|
||||
local_array[i].link.next = &(local_array[i+1]);
|
||||
local_array[i+1].link.next = NULL;
|
||||
func->nargs++;
|
||||
c = ParseNonSpaceChar(p, &r, 0);
|
||||
if (r) {
|
||||
@@ -284,7 +308,7 @@ int DoFset(ParsePtr p)
|
||||
(void) ParseNonSpaceChar(p, &r, 0);
|
||||
}
|
||||
if (p->isnested) {
|
||||
Eprint("%s", ErrMsg[E_CANTNEST_FDEF]);
|
||||
Eprint("%s", GetErr(E_CANTNEST_FDEF));
|
||||
DestroyUserFunc(func);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
@@ -373,21 +397,11 @@ static void DestroyUserFunc(UserFunc *f)
|
||||
/***************************************************************/
|
||||
static void FUnset(char const *name)
|
||||
{
|
||||
UserFunc *cur, *prev;
|
||||
int h;
|
||||
|
||||
h = HashVal_nocase(name) % FUNC_HASH_SIZE;
|
||||
|
||||
cur = FuncHash[h];
|
||||
prev = NULL;
|
||||
while(cur) {
|
||||
if (! strncmp(name, cur->name, VAR_NAME_LEN)) break;
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
UserFunc *f = FindUserFunc(name);
|
||||
if (f) {
|
||||
hash_table_delete(&FuncHash, f);
|
||||
DestroyUserFunc(f);
|
||||
}
|
||||
if (!cur) return;
|
||||
if (prev) prev->next = cur->next; else FuncHash[h] = cur->next;
|
||||
DestroyUserFunc(cur);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -399,19 +413,17 @@ static void FUnset(char const *name)
|
||||
/***************************************************************/
|
||||
static void FSet(UserFunc *f)
|
||||
{
|
||||
int h = HashVal_nocase(f->name) % FUNC_HASH_SIZE;
|
||||
f->next = FuncHash[h];
|
||||
FuncHash[h] = f;
|
||||
hash_table_insert(&FuncHash, f);
|
||||
}
|
||||
|
||||
UserFunc *FindUserFunc(char const *name)
|
||||
{
|
||||
UserFunc *f;
|
||||
int h = HashVal_nocase(name) % FUNC_HASH_SIZE;
|
||||
UserFunc candidate;
|
||||
|
||||
/* Search for the function */
|
||||
f = FuncHash[h];
|
||||
while (f && strncmp(name, f->name, VAR_NAME_LEN)) f = f->next;
|
||||
StrnCpy(candidate.name, name, VAR_NAME_LEN);
|
||||
|
||||
f = hash_table_find(&FuncHash, &candidate);
|
||||
return f;
|
||||
}
|
||||
|
||||
@@ -444,16 +456,16 @@ UnsetAllUserFuncs(void)
|
||||
{
|
||||
UserFunc *f;
|
||||
UserFunc *next;
|
||||
int i;
|
||||
for (i=0; i<FUNC_HASH_SIZE; i++) {
|
||||
f = FuncHash[i];
|
||||
while(f) {
|
||||
next = f->next;
|
||||
DestroyUserFunc(f);
|
||||
f = next;
|
||||
}
|
||||
FuncHash[i] = NULL;
|
||||
|
||||
f = hash_table_next(&FuncHash, NULL);
|
||||
while(f) {
|
||||
next = hash_table_next(&FuncHash, f);
|
||||
hash_table_delete_no_resize(&FuncHash, f);
|
||||
DestroyUserFunc(f);
|
||||
f = next;
|
||||
}
|
||||
hash_table_free(&FuncHash);
|
||||
InitUserFunctions();
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -469,7 +481,6 @@ static void
|
||||
RenameUserFunc(char const *oldname, char const *newname)
|
||||
{
|
||||
UserFunc *f = FindUserFunc(oldname);
|
||||
UserFunc *cur, *prev;
|
||||
|
||||
if (!strcmp(oldname, newname)) {
|
||||
/* Same name; do nothing */
|
||||
@@ -485,52 +496,18 @@ RenameUserFunc(char const *oldname, char const *newname)
|
||||
}
|
||||
|
||||
/* Remove from hash table */
|
||||
int h = HashVal_nocase(f->name) % FUNC_HASH_SIZE;
|
||||
cur = FuncHash[h];
|
||||
prev = NULL;
|
||||
while(cur) {
|
||||
if (cur == f) {
|
||||
if (prev) {
|
||||
prev->next = cur->next;
|
||||
} else {
|
||||
FuncHash[h] = cur->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
hash_table_delete(&FuncHash, f);
|
||||
|
||||
/* Rename */
|
||||
StrnCpy(f->name, newname, VAR_NAME_LEN);
|
||||
|
||||
/* Insert into hash table */
|
||||
h = HashVal_nocase(f->name) % FUNC_HASH_SIZE;
|
||||
f->next = FuncHash[h];
|
||||
FuncHash[h] = f;
|
||||
hash_table_insert(&FuncHash, f);
|
||||
}
|
||||
|
||||
void
|
||||
get_userfunc_hash_stats(int *total, int *maxlen, double *avglen)
|
||||
dump_userfunc_hash_stats(void)
|
||||
{
|
||||
int len;
|
||||
int i;
|
||||
UserFunc *f;
|
||||
|
||||
*maxlen = 0;
|
||||
*total = 0;
|
||||
|
||||
for (i=0; i<FUNC_HASH_SIZE; i++) {
|
||||
len = 0;
|
||||
f = FuncHash[i];
|
||||
while(f) {
|
||||
len++;
|
||||
(*total)++;
|
||||
f = f->next;
|
||||
}
|
||||
if (len > *maxlen) {
|
||||
*maxlen = len;
|
||||
}
|
||||
}
|
||||
*avglen = (double) *total / (double) FUNC_HASH_SIZE;
|
||||
hash_table_dump_stats(&FuncHash, ErrFp);
|
||||
}
|
||||
|
||||
|
||||
292
src/var.c
292
src/var.c
@@ -17,6 +17,7 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
@@ -27,16 +28,38 @@
|
||||
#include "err.h"
|
||||
#define UPPER(c) (islower(c) ? toupper(c) : c)
|
||||
|
||||
/* The variable hash table */
|
||||
#define VAR_HASH_SIZE 67
|
||||
#define VARIABLE ErrMsg[E_VAR]
|
||||
#define VALUE ErrMsg[E_VAL]
|
||||
#define UNDEF ErrMsg[E_UNDEF]
|
||||
#define VARIABLE GetErr(E_VAR)
|
||||
#define VALUE GetErr(E_VAL)
|
||||
#define UNDEF GetErr(E_UNDEF)
|
||||
|
||||
static int IntMin = INT_MIN;
|
||||
static int IntMax = INT_MAX;
|
||||
|
||||
static Var *VHashTbl[VAR_HASH_SIZE];
|
||||
static hash_table VHashTbl;
|
||||
static int SetSysVarHelper(SysVar *v, Value *value);
|
||||
|
||||
static unsigned int VarHashFunc(void *x)
|
||||
{
|
||||
Var *v = (Var *) x;
|
||||
return HashVal_ignorecase(v->name);
|
||||
}
|
||||
|
||||
static int VarCompareFunc(void *a, void *b)
|
||||
{
|
||||
Var *x = (Var *) a;
|
||||
Var *y = (Var *) b;
|
||||
return StrCmpi(x->name, y->name);
|
||||
}
|
||||
|
||||
void
|
||||
InitVars(void)
|
||||
{
|
||||
if (hash_table_init(&VHashTbl, offsetof(Var, link),
|
||||
VarHashFunc, VarCompareFunc) < 0) {
|
||||
fprintf(ErrFp, "Unable to initialize variable hash table: Out of memory. Exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static double
|
||||
strtod_in_c_locale(char const *str, char **endptr)
|
||||
@@ -455,11 +478,11 @@ static int time_sep_func(int do_set, Value *val)
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HashVal */
|
||||
/* Given a string, compute the hash value. */
|
||||
/* HashVal_ignorecase */
|
||||
/* Given a string, compute the hash value case-insensitively */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
unsigned int HashVal(char const *str)
|
||||
unsigned int HashVal_ignorecase(char const *str)
|
||||
{
|
||||
unsigned int h = 0, high;
|
||||
while(*str) {
|
||||
@@ -483,31 +506,22 @@ unsigned int HashVal(char const *str)
|
||||
/***************************************************************/
|
||||
Var *FindVar(char const *str, int create)
|
||||
{
|
||||
register int h;
|
||||
register Var *v;
|
||||
register Var *prev;
|
||||
Var *v;
|
||||
Var candidate;
|
||||
StrnCpy(candidate.name, str, VAR_NAME_LEN);
|
||||
|
||||
h = HashVal(str) % VAR_HASH_SIZE;
|
||||
v = VHashTbl[h];
|
||||
prev = NULL;
|
||||
v = (Var *) hash_table_find(&VHashTbl, &candidate);
|
||||
if (v != NULL || !create) return v;
|
||||
|
||||
while(v) {
|
||||
if (! StrinCmp(str, v->name, VAR_NAME_LEN)) return v;
|
||||
prev = v;
|
||||
v = v-> next;
|
||||
}
|
||||
if (!create) return v;
|
||||
|
||||
/* Create the variable */
|
||||
/* Create the variable */
|
||||
v = NEW(Var);
|
||||
if (!v) return v;
|
||||
v->next = NULL;
|
||||
v->v.type = INT_TYPE;
|
||||
v->v.v.val = 0;
|
||||
v->preserve = 0;
|
||||
StrnCpy(v->name, str, VAR_NAME_LEN);
|
||||
|
||||
if (prev) prev->next = v; else VHashTbl[h] = v;
|
||||
hash_table_insert(&VHashTbl, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -520,23 +534,12 @@ Var *FindVar(char const *str, int create)
|
||||
/***************************************************************/
|
||||
int DeleteVar(char const *str)
|
||||
{
|
||||
register int h;
|
||||
register Var *v;
|
||||
register Var *prev;
|
||||
Var *v;
|
||||
|
||||
h = HashVal(str) % VAR_HASH_SIZE;
|
||||
v = VHashTbl[h];
|
||||
prev = NULL;
|
||||
|
||||
while(v) {
|
||||
if (! StrinCmp(str, v->name, VAR_NAME_LEN)) break;
|
||||
prev = v;
|
||||
v = v-> next;
|
||||
}
|
||||
v = FindVar(str, 0);
|
||||
if (!v) return E_NOSUCH_VAR;
|
||||
DestroyValue(v->v);
|
||||
if (prev) prev->next = v->next; else VHashTbl[h] = v->next;
|
||||
free(v);
|
||||
hash_table_delete(&VHashTbl, v);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -572,7 +575,7 @@ int GetVarValue(char const *str, Value *val)
|
||||
v=FindVar(str, 0);
|
||||
|
||||
if (!v) {
|
||||
Eprint("%s: `%s'", ErrMsg[E_NOSUCH_VAR], str);
|
||||
Eprint("%s: `%s'", GetErr(E_NOSUCH_VAR), str);
|
||||
return E_NOSUCH_VAR;
|
||||
}
|
||||
return CopyValue(val, &v->v);
|
||||
@@ -720,24 +723,19 @@ int DoDump(ParsePtr p)
|
||||
/* */
|
||||
/* DumpVarTable */
|
||||
/* */
|
||||
/* Dump the variable table to stderr. */
|
||||
/* Dump the variable table to ErrFp. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void DumpVarTable(void)
|
||||
{
|
||||
register Var *v;
|
||||
register int i;
|
||||
Var *v;
|
||||
|
||||
fprintf(ErrFp, "%s %s\n\n", VARIABLE, VALUE);
|
||||
|
||||
for (i=0; i<VAR_HASH_SIZE; i++) {
|
||||
v = VHashTbl[i];
|
||||
while(v) {
|
||||
fprintf(ErrFp, "%s ", v->name);
|
||||
PrintValue(&(v->v), ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
v = v->next;
|
||||
}
|
||||
hash_table_for_each(v, &VHashTbl) {
|
||||
fprintf(ErrFp, "%s ", v->name);
|
||||
PrintValue(&(v->v), ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -751,27 +749,22 @@ void DumpVarTable(void)
|
||||
/***************************************************************/
|
||||
void DestroyVars(int all)
|
||||
{
|
||||
int i;
|
||||
Var *v, *next, *prev;
|
||||
Var *v;
|
||||
Var *next;
|
||||
|
||||
for (i=0; i<VAR_HASH_SIZE; i++) {
|
||||
v = VHashTbl[i];
|
||||
VHashTbl[i] = NULL;
|
||||
prev = NULL;
|
||||
while(v) {
|
||||
if (all || !v->preserve) {
|
||||
DestroyValue(v->v);
|
||||
next = v->next;
|
||||
free(v);
|
||||
} else {
|
||||
if (prev) prev->next = v;
|
||||
else VHashTbl[i] = v;
|
||||
prev = v;
|
||||
next = v->next;
|
||||
v->next = NULL;
|
||||
}
|
||||
v = next;
|
||||
v = hash_table_next(&VHashTbl, NULL);
|
||||
while(v) {
|
||||
next = hash_table_next(&VHashTbl, v);
|
||||
if (all || !v->preserve) {
|
||||
DestroyValue(v->v);
|
||||
hash_table_delete_no_resize(&VHashTbl, v);
|
||||
free(v);
|
||||
}
|
||||
v = next;
|
||||
}
|
||||
if (all) {
|
||||
hash_table_free(&VHashTbl);
|
||||
InitVars();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -852,47 +845,47 @@ int DoPreserve (Parser *p)
|
||||
static SysVar SysVarArr[] = {
|
||||
/* name mod type value min/mal max */
|
||||
{"AddBlankLines", 1, INT_TYPE, &AddBlankLines, 0, 1 },
|
||||
{"Ago", 1, STR_TYPE, &DynamicAgo, 0, 0 },
|
||||
{"Am", 1, STR_TYPE, &DynamicAm, 0, 0 },
|
||||
{"And", 1, STR_TYPE, &DynamicAnd, 0, 0 },
|
||||
{"April", 1, STR_TYPE, &DynamicMonthName[3], 0, 0 },
|
||||
{"At", 1, STR_TYPE, &DynamicAt, 0, 0 },
|
||||
{"August", 1, STR_TYPE, &DynamicMonthName[7], 0, 0 },
|
||||
{"Ago", 1, TRANS_TYPE, "ago", 0, 0 },
|
||||
{"Am", 1, TRANS_TYPE, "am", 0, 0 },
|
||||
{"And", 1, TRANS_TYPE, "and", 0, 0 },
|
||||
{"April", 1, TRANS_TYPE, "April", 0, 0 },
|
||||
{"At", 1, TRANS_TYPE, "at", 0, 0 },
|
||||
{"August", 1, TRANS_TYPE, "August", 0, 0 },
|
||||
{"CalcUTC", 1, INT_TYPE, &CalculateUTC, 0, 1 },
|
||||
{"CalMode", 0, INT_TYPE, &DoCalendar, 0, 0 },
|
||||
{"Daemon", 0, INT_TYPE, &Daemon, 0, 0 },
|
||||
{"DateSep", 1, SPECIAL_TYPE, date_sep_func, 0, 0 },
|
||||
{"DateTimeSep", 1, SPECIAL_TYPE, datetime_sep_func, 0, 0 },
|
||||
{"December", 1, STR_TYPE, &DynamicMonthName[11],0, 0 },
|
||||
{"December", 1, TRANS_TYPE, "December", 0, 0 },
|
||||
{"DedupeReminders",1, INT_TYPE, &DedupeReminders, 0, 1 },
|
||||
{"DefaultColor", 1, SPECIAL_TYPE, default_color_func, 0, 0 },
|
||||
{"DefaultDelta", 1, INT_TYPE, &DefaultDelta, 0, 10000 },
|
||||
{"DefaultPrio", 1, INT_TYPE, &DefaultPrio, 0, 9999 },
|
||||
{"DefaultTDelta", 1, INT_TYPE, &DefaultTDelta, 0, 1440 },
|
||||
{"DeltaOverride", 0, INT_TYPE, &DeltaOverride, 0, 0 },
|
||||
{"DeltaOverride", 0, INT_TYPE, &DeltaOverride, 0, 0 },
|
||||
{"DontFork", 0, INT_TYPE, &DontFork, 0, 0 },
|
||||
{"DontQueue", 0, INT_TYPE, &DontQueue, 0, 0 },
|
||||
{"DontTrigAts", 0, INT_TYPE, &DontIssueAts, 0, 0 },
|
||||
{"EndSent", 1, STR_TYPE, &EndSent, 0, 0 },
|
||||
{"EndSentIg", 1, STR_TYPE, &EndSentIg, 0, 0 },
|
||||
{"ExpressionTimeLimit", 1, SPECIAL_TYPE, expr_time_limit_func, 0, 0 },
|
||||
{"February", 1, STR_TYPE, &DynamicMonthName[1], 0, 0 },
|
||||
{"February", 1, TRANS_TYPE, "February", 0, 0 },
|
||||
{"FirstIndent", 1, INT_TYPE, &FirstIndent, 0, 132 },
|
||||
{"FoldYear", 1, INT_TYPE, &FoldYear, 0, 1 },
|
||||
{"FormWidth", 1, INT_TYPE, &FormWidth, 20, 500 },
|
||||
{"Friday", 1, STR_TYPE, &DynamicDayName[4], 0, 0 },
|
||||
{"Fromnow", 1, STR_TYPE, &DynamicFromnow, 0, 0 },
|
||||
{"Hour", 1, STR_TYPE, &DynamicHour, 0, 0 },
|
||||
{"Friday", 1, TRANS_TYPE, "Friday", 0, 0 },
|
||||
{"Fromnow", 1, TRANS_TYPE, "from now", 0, 0 },
|
||||
{"Hour", 1, TRANS_TYPE, "hour", 0, 0 },
|
||||
{"Hplu", 1, STR_TYPE, &DynamicHplu, 0, 0 },
|
||||
{"HushMode", 0, INT_TYPE, &Hush, 0, 0 },
|
||||
{"IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 0, 0 },
|
||||
{"InfDelta", 0, INT_TYPE, &InfiniteDelta, 0, 0 },
|
||||
{"IntMax", 0, INT_TYPE, &IntMax, 0, 0 },
|
||||
{"IntMin", 0, INT_TYPE, &IntMin, 0, 0 },
|
||||
{"Is", 1, STR_TYPE, &DynamicIs, 0, 0 },
|
||||
{"January", 1, STR_TYPE, &DynamicMonthName[0], 0, 0 },
|
||||
{"July", 1, STR_TYPE, &DynamicMonthName[6], 0, 0 },
|
||||
{"June", 1, STR_TYPE, &DynamicMonthName[5], 0, 0 },
|
||||
{"Is", 1, TRANS_TYPE, "is", 0, 0 },
|
||||
{"January", 1, TRANS_TYPE, "January", 0, 0 },
|
||||
{"July", 1, TRANS_TYPE, "July", 0, 0 },
|
||||
{"June", 1, TRANS_TYPE, "June", 0, 0 },
|
||||
{"LatDeg", 1, SPECIAL_TYPE, latdeg_func, 0, 0 },
|
||||
{"Latitude", 1, SPECIAL_TYPE, latitude_func, 0, 0 },
|
||||
{"LatMin", 1, SPECIAL_TYPE, latmin_func, 0, 0 },
|
||||
@@ -902,53 +895,53 @@ static SysVar SysVarArr[] = {
|
||||
{"Longitude", 1, SPECIAL_TYPE, longitude_func, 0, 0 },
|
||||
{"LongMin", 1, SPECIAL_TYPE, longmin_func, 0, 0 },
|
||||
{"LongSec", 1, SPECIAL_TYPE, longsec_func, 0, 0 },
|
||||
{"March", 1, STR_TYPE, &DynamicMonthName[2], 0, 0 },
|
||||
{"March", 1, TRANS_TYPE, "March", 0, 0 },
|
||||
{"MaxFullOmits", 0, CONST_INT_TYPE, NULL, MAX_FULL_OMITS, 0},
|
||||
{"MaxLateMinutes", 1, INT_TYPE, &MaxLateMinutes, 0, 1440 },
|
||||
{"MaxPartialOmits",0, CONST_INT_TYPE, NULL, MAX_PARTIAL_OMITS, 0},
|
||||
{"MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY },
|
||||
{"MaxStringLen", 1, INT_TYPE, &MaxStringLen, -1, ANY },
|
||||
{"May", 1, STR_TYPE, &DynamicMonthName[4], 0, 0 },
|
||||
{"May", 1, TRANS_TYPE, "May", 0, 0 },
|
||||
{"MinsFromUTC", 1, INT_TYPE, &MinsFromUTC, -780, 780 },
|
||||
{"Minute", 1, STR_TYPE, &DynamicMinute, 0, 0 },
|
||||
{"Monday", 1, STR_TYPE, &DynamicDayName[0], 0, 0 },
|
||||
{"Minute", 1, TRANS_TYPE, "minute", 0, 0 },
|
||||
{"Monday", 1, TRANS_TYPE, "Monday", 0, 0 },
|
||||
{"Mplu", 1, STR_TYPE, &DynamicMplu, 0, 0 },
|
||||
{"NextMode", 0, INT_TYPE, &NextMode, 0, 0 },
|
||||
{"November", 1, STR_TYPE, &DynamicMonthName[10],0, 0 },
|
||||
{"Now", 1, STR_TYPE, &DynamicNow, 0, 0 },
|
||||
{"November", 1, TRANS_TYPE, "November", 0, 0 },
|
||||
{"Now", 1, TRANS_TYPE, "now", 0, 0 },
|
||||
{"NumFullOmits", 0, INT_TYPE, &NumFullOmits, 0, 0 },
|
||||
{"NumPartialOmits",0, INT_TYPE, &NumPartialOmits, 0, 0 },
|
||||
{"NumQueued", 0, INT_TYPE, &NumQueued, 0, 0 },
|
||||
{"NumTrig", 0, INT_TYPE, &NumTriggered, 0, 0 },
|
||||
{"October", 1, STR_TYPE, &DynamicMonthName[9], 0, 0 },
|
||||
{"On", 1, STR_TYPE, &DynamicOn, 0, 0 },
|
||||
{"October", 1, TRANS_TYPE, "October", 0, 0 },
|
||||
{"On", 1, TRANS_TYPE, "on", 0, 0 },
|
||||
{"OnceFile", 1, SPECIAL_TYPE, oncefile_func, 0, 0 },
|
||||
{"ParseUntriggered", 1, INT_TYPE, &ParseUntriggered, 0, 1 },
|
||||
{"Pm", 1, STR_TYPE, &DynamicPm, 0, 0 },
|
||||
{"Pm", 1, TRANS_TYPE, "pm", 0, 0 },
|
||||
{"PrefixLineNo", 0, INT_TYPE, &DoPrefixLineNo, 0, 0 },
|
||||
{"PSCal", 0, INT_TYPE, &PsCal, 0, 0 },
|
||||
{"RunOff", 0, INT_TYPE, &RunDisabled, 0, 0 },
|
||||
{"Saturday", 1, STR_TYPE, &DynamicDayName[5], 0, 0 },
|
||||
{"September", 1, STR_TYPE, &DynamicMonthName[8], 0, 0 },
|
||||
{"Saturday", 1, TRANS_TYPE, "Saturday", 0, 0 },
|
||||
{"September", 1, TRANS_TYPE, "September", 0, 0 },
|
||||
{"SimpleCal", 0, INT_TYPE, &DoSimpleCalendar, 0, 0 },
|
||||
{"SortByDate", 0, INT_TYPE, &SortByDate, 0, 0 },
|
||||
{"SortByPrio", 0, INT_TYPE, &SortByPrio, 0, 0 },
|
||||
{"SortByTime", 0, INT_TYPE, &SortByTime, 0, 0 },
|
||||
{"SubsIndent", 1, INT_TYPE, &SubsIndent, 0, 132 },
|
||||
{"Sunday", 1, STR_TYPE, &DynamicDayName[6], 0, 0 },
|
||||
{"Sunday", 1, TRANS_TYPE, "Sunday", 0, 0 },
|
||||
{"SuppressImplicitWarnings", 1, INT_TYPE, &SuppressImplicitRemWarnings, 0, 1},
|
||||
{"SuppressLRM", 1, INT_TYPE, &SuppressLRM, 0, 1 },
|
||||
{"SysInclude", 0, STR_TYPE, &SysDir, 0, 0 },
|
||||
{"T", 0, SPECIAL_TYPE, trig_date_func, 0, 0 },
|
||||
{"Td", 0, SPECIAL_TYPE, trig_day_func, 0, 0 },
|
||||
{"TerminalBackground", 0, SPECIAL_TYPE, terminal_bg_func, 0, 0 },
|
||||
{"Thursday", 1, STR_TYPE, &DynamicDayName[3], 0, 0 },
|
||||
{"Thursday", 1, TRANS_TYPE, "Thursday", 0, 0 },
|
||||
{"TimeSep", 1, SPECIAL_TYPE, time_sep_func, 0, 0 },
|
||||
{"Tm", 0, SPECIAL_TYPE, trig_mon_func, 0, 0 },
|
||||
{"Today", 1, STR_TYPE, &DynamicToday, 0, 0 },
|
||||
{"Tomorrow", 1, STR_TYPE, &DynamicTomorrow, 0, 0 },
|
||||
{"Today", 1, TRANS_TYPE, "today", 0, 0 },
|
||||
{"Tomorrow", 1, TRANS_TYPE, "tomorrow", 0, 0 },
|
||||
{"Tt", 0, SPECIAL_TYPE, trig_time_func, 0, 0 },
|
||||
{"Tuesday", 1, STR_TYPE, &DynamicDayName[1], 0, 0 },
|
||||
{"Tuesday", 1, TRANS_TYPE, "Tuesday", 0, 0 },
|
||||
{"Tw", 0, SPECIAL_TYPE, trig_wday_func, 0, 0 },
|
||||
{"Ty", 0, SPECIAL_TYPE, trig_year_func, 0, 0 },
|
||||
{"U", 0, SPECIAL_TYPE, today_date_func, 0, 0 },
|
||||
@@ -956,34 +949,51 @@ static SysVar SysVarArr[] = {
|
||||
{"Um", 0, SPECIAL_TYPE, today_mon_func, 0, 0 },
|
||||
{"UntimedFirst", 0, INT_TYPE, &UntimedBeforeTimed, 0, 0 },
|
||||
{"Use256Colors", 0, INT_TYPE, &Use256Colors, 0, 0 },
|
||||
{"UseBGVTColors", 0, INT_TYPE, &UseBGVTColors, 0, 0 },
|
||||
{"UseBGVTColors", 0, INT_TYPE, &UseBGVTColors, 0, 0 },
|
||||
{"UseTrueColors", 0, INT_TYPE, &UseTrueColors, 0, 0 },
|
||||
{"UseVTColors", 0, INT_TYPE, &UseVTColors, 0, 0 },
|
||||
{"Uw", 0, SPECIAL_TYPE, today_wday_func, 0, 0 },
|
||||
{"Uy", 0, SPECIAL_TYPE, today_year_func, 0, 0 },
|
||||
{"Was", 1, STR_TYPE, &DynamicWas, 0, 0 },
|
||||
{"Wednesday", 1, STR_TYPE, &DynamicDayName[2], 0, 0 }
|
||||
{"Was", 1, TRANS_TYPE, "was", 0, 0 },
|
||||
{"Wednesday", 1, TRANS_TYPE, "Wednesday", 0, 0 }
|
||||
};
|
||||
|
||||
#define NUMSYSVARS ( sizeof(SysVarArr) / sizeof(SysVar) )
|
||||
static void DumpSysVar (char const *name, const SysVar *v);
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SetSysVar */
|
||||
/* */
|
||||
/* Set a system variable to the indicated value. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int SetSysVar(char const *name, Value *value)
|
||||
|
||||
static int SetTranslatableVariable(SysVar *v, Value *value)
|
||||
{
|
||||
return InsertTranslation((char const *) v->value, value->v.str);
|
||||
}
|
||||
|
||||
static int GetTranslatableVariable(SysVar *v, Value *value)
|
||||
{
|
||||
char const *translated = tr((char const *) v->value);
|
||||
if (translated) {
|
||||
value->v.str = StrDup(translated);
|
||||
} else {
|
||||
value->v.str = StrDup("");
|
||||
}
|
||||
if (!value->v.str) return E_NO_MEM;
|
||||
value->type = STR_TYPE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int SetSysVarHelper(SysVar *v, Value *value)
|
||||
{
|
||||
int r;
|
||||
SysVar *v = FindSysVar(name);
|
||||
if (!v) return E_NOSUCH_VAR;
|
||||
if (!v->modifiable) {
|
||||
Eprint("%s: `$%s'", ErrMsg[E_CANT_MODIFY], name);
|
||||
Eprint("%s: `$%s'", GetErr(E_CANT_MODIFY), v->name);
|
||||
return E_CANT_MODIFY;
|
||||
}
|
||||
|
||||
if (v->type == TRANS_TYPE) {
|
||||
if (value->type != STR_TYPE) return E_BAD_TYPE;
|
||||
r = SetTranslatableVariable(v, value);
|
||||
DestroyValue(*value);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (v->type != SPECIAL_TYPE &&
|
||||
v->type != value->type) return E_BAD_TYPE;
|
||||
if (v->type == SPECIAL_TYPE) {
|
||||
@@ -1013,6 +1023,20 @@ int SetSysVar(char const *name, Value *value)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SetSysVar */
|
||||
/* */
|
||||
/* Set a system variable to the indicated value. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int SetSysVar(char const *name, Value *value)
|
||||
{
|
||||
SysVar *v = FindSysVar(name);
|
||||
if (!v) return E_NOSUCH_VAR;
|
||||
return SetSysVarHelper(v, value);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetSysVar */
|
||||
@@ -1026,6 +1050,10 @@ int GetSysVar(char const *name, Value *val)
|
||||
|
||||
val->type = ERR_TYPE;
|
||||
if (!v) return E_NOSUCH_VAR;
|
||||
if (v->type == TRANS_TYPE) {
|
||||
return GetTranslatableVariable(v, val);
|
||||
}
|
||||
|
||||
if (v->type == CONST_INT_TYPE) {
|
||||
val->v.val = v->constval;
|
||||
val->type = INT_TYPE;
|
||||
@@ -1132,6 +1160,15 @@ static void DumpSysVar(char const *name, const SysVar *v)
|
||||
PrintValue(&vtmp, ErrFp);
|
||||
putc('\n', ErrFp);
|
||||
DestroyValue(vtmp);
|
||||
} else if (v->type == TRANS_TYPE) {
|
||||
int r = GetSysVar(v->name, &vtmp);
|
||||
if (r == OK) {
|
||||
PrintValue(&vtmp, ErrFp);
|
||||
putc('\n', ErrFp);
|
||||
DestroyValue(vtmp);
|
||||
} else {
|
||||
fprintf(ErrFp, "Error: %s\n", GetErr(r));
|
||||
}
|
||||
} else if (v->type == STR_TYPE) {
|
||||
vtmp.type = STR_TYPE;
|
||||
vtmp.v.str = * ((char **)v->value);
|
||||
@@ -1212,26 +1249,7 @@ print_sysvar_tokens(void)
|
||||
}
|
||||
|
||||
void
|
||||
get_var_hash_stats(int *total, int *maxlen, double *avglen)
|
||||
dump_var_hash_stats(void)
|
||||
{
|
||||
int len;
|
||||
int i;
|
||||
Var *v;
|
||||
|
||||
*maxlen = 0;
|
||||
*total = 0;
|
||||
|
||||
for (i=0; i<VAR_HASH_SIZE; i++) {
|
||||
len = 0;
|
||||
v = VHashTbl[i];
|
||||
while(v) {
|
||||
len++;
|
||||
(*total)++;
|
||||
v = v->next;
|
||||
}
|
||||
if (len > *maxlen) {
|
||||
*maxlen = len;
|
||||
}
|
||||
}
|
||||
*avglen = (double) *total / (double) VAR_HASH_SIZE;
|
||||
hash_table_dump_stats(&VHashTbl, ErrFp);
|
||||
}
|
||||
|
||||
6
tests/test-all-langs.sh
Executable file
6
tests/test-all-langs.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
for i in ../include/lang/??.rem ; do
|
||||
echo "Testing lang file: $i"
|
||||
../src/remind -r -q "-ii=\"$i\"" ../tests/tstlang.rem
|
||||
done
|
||||
@@ -27,7 +27,7 @@ if test `id -u` = 0 ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# We alias "remind" here so that we don't inadvertantly add code that
|
||||
# We alias "remind" here so that we don't inadvertently add code that
|
||||
# runs the system-installed verion of Remind rather than
|
||||
# ../src/remind. This trick was suggested by Jochen Sprickerhof
|
||||
alias remind="echo You should be using ../src/remind explicitly in test-rem >&2; exit 1"
|
||||
@@ -619,6 +619,14 @@ fi
|
||||
# Test --print-tokens long option
|
||||
../src/remind --print-tokens < /dev/null >> ../tests/test.out 2>&1
|
||||
|
||||
# Torture test #2
|
||||
../src/remind ../tests/torture2.rem >> ../tests/test.out 2>&1
|
||||
|
||||
# Languages
|
||||
for i in ../include/lang/??.rem ; do
|
||||
../src/remind -r -q "-ii=\"$i\"" ../tests/tstlang.rem 1 Feb 2024 13:34 >> ../tests/test.out 2>&1
|
||||
done
|
||||
|
||||
# Make sure all the include files are ok
|
||||
find ../include -type f -name '*.rem' | while read x; do ../src/remind -n $x 1 Jan 2024 2>>../tests/test.out 1>/dev/null; done
|
||||
cmp -s ../tests/test.out ../tests/test.cmp
|
||||
|
||||
27133
tests/test.cmp
27133
tests/test.cmp
File diff suppressed because one or more lines are too long
262
tests/test.rem
262
tests/test.rem
@@ -26,8 +26,12 @@ continued so there
|
||||
# This should work
|
||||
INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo MSG Yippee
|
||||
|
||||
# This should fail
|
||||
# This should work
|
||||
INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo MSG Yippee
|
||||
|
||||
# This should fail
|
||||
INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo INCLUDECMD echo MSG Yippee
|
||||
|
||||
REM MSG Today is [hebday(today())] [hebmon(today())] [hebyear(today())]
|
||||
fset _h(x, y) trigger(hebdate(x,y))
|
||||
|
||||
@@ -1180,8 +1184,264 @@ REM MSG Hello
|
||||
FSET msgsuffix(x) char(8) + " on the same line"
|
||||
REM MSG Hello
|
||||
|
||||
# Test TRANSLATE
|
||||
set a _("Hello")
|
||||
|
||||
TRANSLATE "Hello" "Goodbye"
|
||||
set a _("Hello")
|
||||
|
||||
TRANSLATE "Hello" "Hallo!!!!!"
|
||||
set a _("Hello")
|
||||
|
||||
TRANSLATE DUMP
|
||||
TRANSLATE CLEAR
|
||||
TRANSLATE DUMP
|
||||
set a _("Hello")
|
||||
|
||||
TRANSLATE "Wookie" "Bar"
|
||||
TRANSLATE "Bar" "Quux"
|
||||
TRANSLATE "Quux" "OOOGHY"
|
||||
|
||||
# Delete Bar translation
|
||||
TRANSLATE "Bar"
|
||||
|
||||
# LANGID is a special case
|
||||
set a _("LANGID")
|
||||
|
||||
TRANSLATE "LANGID" "nl"
|
||||
set a _("LANGID")
|
||||
|
||||
TRANSLATE "LANGID"
|
||||
set a _("LANGID")
|
||||
|
||||
set a _("Wookie")
|
||||
set a _("Bar")
|
||||
set a _("Quux")
|
||||
|
||||
SET $ago "Txago"
|
||||
SET $am "Txam"
|
||||
SET $and "Txand"
|
||||
SET $at "Txat"
|
||||
SET $fromnow "Txfromnow"
|
||||
SET $hour "Txhour"
|
||||
SET $is "Txis"
|
||||
SET $minute "Txminute"
|
||||
SET $now "Txnow"
|
||||
SET $on "Txon"
|
||||
SET $pm "Txpm"
|
||||
SET $today "Txtoday"
|
||||
SET $tomorrow "Txtomorrow"
|
||||
SET $was "Txwas"
|
||||
SET $January "TxJanuary"
|
||||
SET $February "TxFebruary"
|
||||
SET $March "TxMarch"
|
||||
SET $April "TxApril"
|
||||
SET $May "TxMay"
|
||||
SET $June "TxJune"
|
||||
SET $July "TxJuly"
|
||||
SET $August "TxAugust"
|
||||
SET $September "TxSeptember"
|
||||
SET $October "TxOctober"
|
||||
SET $November "TxNovember"
|
||||
SET $December "TxDecember"
|
||||
SET $Monday "TxMonday"
|
||||
SET $Tuesday "TxTuesday"
|
||||
SET $Wednesday "TxWednesday"
|
||||
SET $Thursday "TxThursday"
|
||||
SET $Friday "TxFriday"
|
||||
SET $Saturday "TxSaturday"
|
||||
SET $Sunday "TxSunday"
|
||||
TRANSLATE DUMP
|
||||
|
||||
TRANSLATE "missing quote" "missing a quote
|
||||
TRANSLATE "missing quote
|
||||
|
||||
DO torture-test.rem
|
||||
|
||||
TRANSLATE "Division by zero" "Ya tried to divide by zero, ya FOOOL!!!!!"
|
||||
set a 1/0
|
||||
TRANSLATE "Division by zero"
|
||||
set a 1/0
|
||||
|
||||
TRANSLATE "Moo" "Bark"
|
||||
TRANSLATE "meow" "chirp"
|
||||
|
||||
DEBUG +x
|
||||
set a _("moo")
|
||||
set a _("Moo")
|
||||
set a _("MOO")
|
||||
set a _("meow")
|
||||
set a _("Meow")
|
||||
set a _("MEOW")
|
||||
|
||||
# Check bidirectional connection between system variables and translation
|
||||
# tables
|
||||
DEBUG -x
|
||||
TRANSLATE CLEAR
|
||||
|
||||
SET $Ago "translated-Ago"
|
||||
SET $Am "translated-Am"
|
||||
SET $And "translated-And"
|
||||
SET $At "translated-At"
|
||||
SET $Fromnow "translated-Fromnow"
|
||||
SET $Hour "translated-Hour"
|
||||
SET $Is "translated-Is"
|
||||
SET $Minute "translated-Minute"
|
||||
SET $Now "translated-Now"
|
||||
SET $On "translated-On"
|
||||
SET $Pm "translated-Pm"
|
||||
SET $Today "translated-Today"
|
||||
SET $Tomorrow "translated-Tomorrow"
|
||||
SET $Was "translated-Was"
|
||||
SET $January "translated-January"
|
||||
SET $February "translated-February"
|
||||
SET $March "translated-March"
|
||||
SET $April "translated-April"
|
||||
SET $May "translated-May"
|
||||
SET $June "translated-June"
|
||||
SET $July "translated-July"
|
||||
SET $August "translated-August"
|
||||
SET $September "translated-September"
|
||||
SET $October "translated-October"
|
||||
SET $November "translated-November"
|
||||
SET $December "translated-December"
|
||||
SET $Monday "translated-Monday"
|
||||
SET $Tuesday "translated-Tuesday"
|
||||
SET $Wednesday "translated-Wednesday"
|
||||
SET $Thursday "translated-Thursday"
|
||||
SET $Friday "translated-Friday"
|
||||
SET $Saturday "translated-Saturday"
|
||||
SET $Sunday "translated-Sunday"
|
||||
|
||||
TRANSLATE DUMP
|
||||
|
||||
TRANSLATE CLEAR
|
||||
TRANSLATE "ago" "otherway-Ago"
|
||||
TRANSLATE "am" "otherway-Am"
|
||||
TRANSLATE "and" "otherway-And"
|
||||
TRANSLATE "at" "otherway-At"
|
||||
TRANSLATE "from now" "otherway-Fromnow"
|
||||
TRANSLATE "hour" "otherway-Hour"
|
||||
TRANSLATE "is" "otherway-Is"
|
||||
TRANSLATE "minute" "otherway-Minute"
|
||||
TRANSLATE "now" "otherway-Now"
|
||||
TRANSLATE "on" "otherway-On"
|
||||
TRANSLATE "pm" "otherway-Pm"
|
||||
TRANSLATE "today" "otherway-Today"
|
||||
TRANSLATE "tomorrow" "otherway-Tomorrow"
|
||||
TRANSLATE "was" "otherway-Was"
|
||||
TRANSLATE "January" "otherway-January"
|
||||
TRANSLATE "February" "otherway-February"
|
||||
TRANSLATE "March" "otherway-March"
|
||||
TRANSLATE "April" "otherway-April"
|
||||
TRANSLATE "May" "otherway-May"
|
||||
TRANSLATE "June" "otherway-June"
|
||||
TRANSLATE "July" "otherway-July"
|
||||
TRANSLATE "August" "otherway-August"
|
||||
TRANSLATE "September" "otherway-September"
|
||||
TRANSLATE "October" "otherway-October"
|
||||
TRANSLATE "November" "otherway-November"
|
||||
TRANSLATE "December" "otherway-December"
|
||||
TRANSLATE "Monday" "otherway-Monday"
|
||||
TRANSLATE "Tuesday" "otherway-Tuesday"
|
||||
TRANSLATE "Wednesday" "otherway-Wednesday"
|
||||
TRANSLATE "Thursday" "otherway-Thursday"
|
||||
TRANSLATE "Friday" "otherway-Friday"
|
||||
TRANSLATE "Saturday" "otherway-Saturday"
|
||||
TRANSLATE "Sunday" "otherway-Sunday"
|
||||
|
||||
MSG $Ago is [$Ago]%
|
||||
MSG $Am is [$Am]%
|
||||
MSG $And is [$And]%
|
||||
MSG $At is [$At]%
|
||||
MSG $Fromnow is [$Fromnow]%
|
||||
MSG $Hour is [$Hour]%
|
||||
MSG $Is is [$Is]%
|
||||
MSG $Minute is [$Minute]%
|
||||
MSG $Now is [$Now]%
|
||||
MSG $On is [$On]%
|
||||
MSG $Pm is [$Pm]%
|
||||
MSG $Today is [$Today]%
|
||||
MSG $Tomorrow is [$Tomorrow]%
|
||||
MSG $Was is [$Was]%
|
||||
MSG $January is [$January]%
|
||||
MSG $February is [$February]%
|
||||
MSG $March is [$March]%
|
||||
MSG $April is [$April]%
|
||||
MSG $May is [$May]%
|
||||
MSG $June is [$June]%
|
||||
MSG $July is [$July]%
|
||||
MSG $August is [$August]%
|
||||
MSG $September is [$September]%
|
||||
MSG $October is [$October]%
|
||||
MSG $November is [$November]%
|
||||
MSG $December is [$December]%
|
||||
MSG $Monday is [$Monday]%
|
||||
MSG $Tuesday is [$Tuesday]%
|
||||
MSG $Wednesday is [$Wednesday]%
|
||||
MSG $Thursday is [$Thursday]%
|
||||
MSG $Friday is [$Friday]%
|
||||
MSG $Saturday is [$Saturday]%
|
||||
MSG $Sunday is [$Sunday]%
|
||||
|
||||
TRANSLATE CLEAR
|
||||
TRANSLATE DUMP
|
||||
MSG $Ago is [$Ago]%
|
||||
MSG $Am is [$Am]%
|
||||
MSG $And is [$And]%
|
||||
MSG $At is [$At]%
|
||||
MSG $Fromnow is [$Fromnow]%
|
||||
MSG $Hour is [$Hour]%
|
||||
MSG $Is is [$Is]%
|
||||
MSG $Minute is [$Minute]%
|
||||
MSG $Now is [$Now]%
|
||||
MSG $On is [$On]%
|
||||
MSG $Pm is [$Pm]%
|
||||
MSG $Today is [$Today]%
|
||||
MSG $Tomorrow is [$Tomorrow]%
|
||||
MSG $Was is [$Was]%
|
||||
MSG $January is [$January]%
|
||||
MSG $February is [$February]%
|
||||
MSG $March is [$March]%
|
||||
MSG $April is [$April]%
|
||||
MSG $May is [$May]%
|
||||
MSG $June is [$June]%
|
||||
MSG $July is [$July]%
|
||||
MSG $August is [$August]%
|
||||
MSG $September is [$September]%
|
||||
MSG $October is [$October]%
|
||||
MSG $November is [$November]%
|
||||
MSG $December is [$December]%
|
||||
MSG $Monday is [$Monday]%
|
||||
MSG $Tuesday is [$Tuesday]%
|
||||
MSG $Wednesday is [$Wednesday]%
|
||||
MSG $Thursday is [$Thursday]%
|
||||
MSG $Friday is [$Friday]%
|
||||
MSG $Saturday is [$Saturday]%
|
||||
MSG $Sunday is [$Sunday]%
|
||||
|
||||
DEBUG +e
|
||||
set $Is "foo"
|
||||
set $Was "bar"
|
||||
TRANSLATE DUMP
|
||||
TRANSLATE "is" "is"
|
||||
TRANSLATE "was"
|
||||
TRANSLATE DUMP
|
||||
MSG $Is is [$Is]%
|
||||
MSG $Was is [$Was]%
|
||||
|
||||
# Catch an error fixed in commit 356b562d75852dafb2ffc6b1122500a98fa7d9d0
|
||||
IF 1
|
||||
INCLUDE /non/existent/file/should/not/work/wookie
|
||||
ENDIF
|
||||
|
||||
do "with space.rem"
|
||||
|
||||
DEBUG -e
|
||||
|
||||
# Output expression-node stats
|
||||
DEBUG +s
|
||||
|
||||
# Don't want Remind to queue reminders
|
||||
EXIT
|
||||
|
||||
|
||||
310012
tests/torture-test.rem
Normal file
310012
tests/torture-test.rem
Normal file
File diff suppressed because it is too large
Load Diff
600004
tests/torture2.rem
Normal file
600004
tests/torture2.rem
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user