Compare commits

...

30 Commits

Author SHA1 Message Date
Dianne Skoll
4e7cfc20ce Make use of SYSINCLUDE.
All checks were successful
Remind unit tests / tests (push) Successful in 32s
2024-12-13 08:28:14 -05:00
Dianne Skoll
0c9a35a584 Add SYSINCLUDE to release notes. 2024-12-13 08:22:43 -05:00
Dianne Skoll
5e333f6162 Add the SYSINCLUDE directive. 2024-12-13 08:18:22 -05:00
Dianne Skoll
af8b4e6df1 Add const qualifier on Sysvar.value.
All checks were successful
Remind unit tests / tests (push) Successful in 44s
2024-12-12 20:27:54 -05:00
Dianne Skoll
3fa798523a Document the difference between %(foo) and [_("foo")] 2024-12-12 16:56:38 -05:00
Dianne Skoll
53001f9fbc Update WHATSNEW 2024-12-12 16:48:53 -05:00
Dianne Skoll
9cd76eae84 Fix typo 2024-12-12 16:47:34 -05:00
Dianne Skoll
c8295b6251 Convert files we ship to use %(foo) in place of [_("foo")] 2024-12-12 16:43:30 -05:00
Dianne Skoll
3c95245407 In the substitution filter, make %(foo) equivalent to [_("foo")] 2024-12-12 16:35:31 -05:00
Dianne Skoll
3362c7226c Add regression test for commit 356b562d75
All checks were successful
Remind unit tests / tests (push) Successful in 31s
2024-12-12 12:17:15 -05:00
Dianne Skoll
356b562d75 Fix logic error in resetting IF flags and Popfile interaction. 2024-12-12 12:14:29 -05:00
Dianne Skoll
6eebcdc39d Handle error return from GetSysVar. 2024-12-12 11:58:27 -05:00
Dianne Skoll
5a80d63060 Add localization tests. 2024-12-12 11:55:07 -05:00
Dianne Skoll
c7ca1b4baa Get rid of the DyamicFoo hacks and make most translatable variables live in the translation table. 2024-12-12 11:43:03 -05:00
Dianne Skoll
dc89a6fba9 Eliminate unnecessary test. 2024-12-12 10:12:50 -05:00
Dianne Skoll
f83fec5563 Add missing three Chinese New Year animals. 2024-12-12 09:55:30 -05:00
Dianne Skoll
9c38161430 Merge branch 'translation_de' into 'master'
Add German translations

See merge request dskoll/remind!8
2024-12-12 14:53:21 +00:00
Jochen Sprickerhof
68f5fe1d10 Add German translations
Based on nl.rem
2024-12-12 12:51:38 +01:00
Dianne Skoll
bc7c57e53b Add another translation-propagation test.
All checks were successful
Remind unit tests / tests (push) Successful in 27s
2024-12-11 20:10:11 -05:00
Dianne Skoll
88aacb3905 Get two-way propagation working properly. 2024-12-11 20:08:09 -05:00
Dianne Skoll
a894076bfc Verify two-way correspondence between translation table and system variables. 2024-12-11 19:48:19 -05:00
Dianne Skoll
82e068fcca Refactor SetSysVar. 2024-12-11 19:22:30 -05:00
Dianne Skoll
a119d97539 Make mapping between translatable system variables and TRANSLATE table table-driven. 2024-12-11 19:15:44 -05:00
Dianne Skoll
01afb63a3d Sent translations with only the first month, in a multi-month (-pN) output. 2024-12-11 18:07:48 -05:00
Dianne Skoll
54fccabdfe Escape the result of translation, in case a bad translation file includes HTML special characters. 2024-12-11 17:15:01 -05:00
Dianne Skoll
ba4d44664f Clarify docs.
All checks were successful
Remind unit tests / tests (push) Successful in 34s
2024-12-11 15:36:17 -05:00
Dianne Skoll
d76c5499b5 Document how translation table is passed to back-ends. 2024-12-11 15:35:31 -05:00
Dianne Skoll
84e8244e48 Use localized names for "Full Moon", etc. 2024-12-11 15:35:23 -05:00
Dianne Skoll
92a6115a5c Send the translation table to back-ends. 2024-12-11 15:24:37 -05:00
Dianne Skoll
b98e336e9e Tweak release notes. 2024-12-11 14:02:30 -05:00
33 changed files with 14301 additions and 303 deletions

View File

@@ -117,7 +117,8 @@
"NOQUEUE" "OMIT" "OMITFUNC" "ONCE" "POP" "POP-OMIT-CONTEXT" "PRESERVE" "NOQUEUE" "OMIT" "OMITFUNC" "ONCE" "POP" "POP-OMIT-CONTEXT" "PRESERVE"
"PRIORITY" "PS" "PSFILE" "PUSH" "PUSH-OMIT-CONTEXT" "REM" "RUN" "PRIORITY" "PS" "PSFILE" "PUSH" "PUSH-OMIT-CONTEXT" "REM" "RUN"
"SATISFY" "SCAN" "SCANFROM" "SCHED" "SECOND" "SET" "SKIP" "SPECIAL" "SATISFY" "SCAN" "SCANFROM" "SCHED" "SECOND" "SET" "SKIP" "SPECIAL"
"TAG" "THIRD" "THROUGH" "TRANSLATE" "TRANS" "UNSET" "UNTIL" "WARN") "SYSINCLUDE" "TAG" "THIRD" "THROUGH" "TRANSLATE" "TRANS" "UNSET"
"UNTIL" "WARN")
#'(lambda (a b) (> (length a) (length b))))) #'(lambda (a b) (> (length a) (length b)))))

View File

@@ -2,9 +2,9 @@ CHANGES TO REMIND
* VERSION 5.2 Patch 0 - ????-??=?? * VERSION 5.2 Patch 0 - ????-??=??
- MAJOR NEW FEATURE: remind: Add the TRANSLATE command and the _() - MAJOR NEW FEATURE: remind: Add the TRANSLATE command, the _()
built-in function. This allows you to localize your reminder files built-in function and the %(...) substitution sequence. These allow
more easily. you to localize your reminder files more easily.
- MAJOR CHANGE: remind: Remind used to support compile-time localization - MAJOR CHANGE: remind: Remind used to support compile-time localization
into different languages (French, English, etc.) That compile-time into different languages (French, English, etc.) That compile-time
@@ -19,6 +19,14 @@ CHANGES TO REMIND
- MINOR FEATURE: Add standard include/sun.rem file for sunrise/sunset. - 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
- IMPROVEMENT: remind: Refuse to open subdirectories named "*.rem" - IMPROVEMENT: remind: Refuse to open subdirectories named "*.rem"
under a top-level directory rather than trying and failing with a under a top-level directory rather than trying and failing with a
confusing error. confusing error.
@@ -27,7 +35,10 @@ CHANGES TO REMIND
that are easier on the eyes. that are easier on the eyes.
- IMPROVEMENT: remind: Remind used to have three completely separate - IMPROVEMENT: remind: Remind used to have three completely separate
hash table implementations. Replace them all with one piece of code. 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 - MINOR FIXES: remind: Fix typos in comments; use memcpy to copy OMIT
contexts internally. contexts internally.

View File

@@ -54,8 +54,8 @@ advance warning of holidays:
FSET msgsuffix(x) char(8) + dosubst(" is %b.%", $T) FSET msgsuffix(x) char(8) + dosubst(" is %b.%", $T)
# Include your holiday files here... # Include your holiday files here...
INCLUDE [$SysInclude]/holidays/us.rem SYSINCLUDE holidays/us.rem
INCLUDE [$SysInclude]/holidays/us/ny.rem SYSINCLUDE holidays/us/ny.rem
# Restore old version of msgsuffix and $DefaultDelta # Restore old version of msgsuffix and $DefaultDelta
FRENAME saved_msgsuffix msgsuffix FRENAME saved_msgsuffix msgsuffix

View File

@@ -1,29 +1,29 @@
REM 1 Feb 2022 MSG [_("Chinese New Year")] ([_("Tiger")]) REM 1 Feb 2022 MSG %(Chinese New Year) (%(Tiger))
REM 22 Jan 2023 MSG [_("Chinese New Year")] ([_("Rabbit")]) REM 22 Jan 2023 MSG %(Chinese New Year) (%(Rabbit))
REM 10 Feb 2024 MSG [_("Chinese New Year")] ([_("Dragon")]) REM 10 Feb 2024 MSG %(Chinese New Year) (%(Dragon))
REM 29 Jan 2025 MSG [_("Chinese New Year")] ([_("Snake")]) REM 29 Jan 2025 MSG %(Chinese New Year) (%(Snake))
REM 17 Feb 2026 MSG [_("Chinese New Year")] ([_("Horse")]) REM 17 Feb 2026 MSG %(Chinese New Year) (%(Horse))
REM 6 Feb 2027 MSG [_("Chinese New Year")] ([_("Goat")]) REM 6 Feb 2027 MSG %(Chinese New Year) (%(Goat))
REM 26 Jan 2028 MSG [_("Chinese New Year")] ([_("Monkey")]) REM 26 Jan 2028 MSG %(Chinese New Year) (%(Monkey))
REM 13 Feb 2029 MSG [_("Chinese New Year")] ([_("Rooster")]) REM 13 Feb 2029 MSG %(Chinese New Year) (%(Rooster))
REM 3 Feb 2030 MSG [_("Chinese New Year")] ([_("Dog")]) REM 3 Feb 2030 MSG %(Chinese New Year) (%(Dog))
REM 23 Jan 2031 MSG [_("Chinese New Year")] ([_("Pig")]) REM 23 Jan 2031 MSG %(Chinese New Year) (%(Pig))
REM 11 Feb 2032 MSG [_("Chinese New Year")] ([_("Rat")]) REM 11 Feb 2032 MSG %(Chinese New Year) (%(Rat))
REM 31 Jan 2033 MSG [_("Chinese New Year")] ([_("Ox")]) REM 31 Jan 2033 MSG %(Chinese New Year) (%(Ox))
REM 19 Feb 2034 MSG [_("Chinese New Year")] ([_("Tiger")]) REM 19 Feb 2034 MSG %(Chinese New Year) (%(Tiger))
REM 8 Feb 2035 MSG [_("Chinese New Year")] ([_("Rabbit")]) REM 8 Feb 2035 MSG %(Chinese New Year) (%(Rabbit))
REM 28 Jan 2036 MSG [_("Chinese New Year")] ([_("Dragon")]) REM 28 Jan 2036 MSG %(Chinese New Year) (%(Dragon))
REM 15 Feb 2037 MSG [_("Chinese New Year")] ([_("Snake")]) REM 15 Feb 2037 MSG %(Chinese New Year) (%(Snake))
REM 4 Feb 2038 MSG [_("Chinese New Year")] ([_("Horse")]) REM 4 Feb 2038 MSG %(Chinese New Year) (%(Horse))
REM 24 Jan 2039 MSG [_("Chinese New Year")] ([_("Goat")]) REM 24 Jan 2039 MSG %(Chinese New Year) (%(Goat))
REM 12 Feb 2040 MSG [_("Chinese New Year")] ([_("Monkey")]) REM 12 Feb 2040 MSG %(Chinese New Year) (%(Monkey))
REM 1 Feb 2041 MSG [_("Chinese New Year")] ([_("Rooster")]) REM 1 Feb 2041 MSG %(Chinese New Year) (%(Rooster))
REM 22 Jan 2042 MSG [_("Chinese New Year")] ([_("Dog")]) REM 22 Jan 2042 MSG %(Chinese New Year) (%(Dog))
REM 10 Feb 2043 MSG [_("Chinese New Year")] ([_("Pig")]) REM 10 Feb 2043 MSG %(Chinese New Year) (%(Pig))
REM 30 Jan 2044 MSG [_("Chinese New Year")] ([_("Rat")]) REM 30 Jan 2044 MSG %(Chinese New Year) (%(Rat))
REM 17 Feb 2045 MSG [_("Chinese New Year")] ([_("Ox")]) REM 17 Feb 2045 MSG %(Chinese New Year) (%(Ox))
REM 6 Feb 2046 MSG [_("Chinese New Year")] ([_("Tiger")]) REM 6 Feb 2046 MSG %(Chinese New Year) (%(Tiger))
REM 26 Jan 2047 MSG [_("Chinese New Year")] ([_("Rabbit")]) REM 26 Jan 2047 MSG %(Chinese New Year) (%(Rabbit))
REM 14 Feb 2048 MSG [_("Chinese New Year")] ([_("Dragon")]) REM 14 Feb 2048 MSG %(Chinese New Year) (%(Dragon))
REM 2 Feb 2049 MSG [_("Chinese New Year")] ([_("Snake")]) REM 2 Feb 2049 MSG %(Chinese New Year) (%(Snake))
REM 23 Jan 2050 MSG [_("Chinese New Year")] ([_("Horse")]) REM 23 Jan 2050 MSG %(Chinese New Year) (%(Horse))

View File

@@ -16,10 +16,10 @@ if !defined("__autolang__")
IF autolang != "" IF autolang != ""
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 5)) + ".rem", "r") == 0 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 ELSE
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 2)) + ".rem", "r") == 0 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 ENDIF
ENDIF ENDIF

View File

@@ -74,3 +74,27 @@ TRANSLATE "Autumnal Equinox" "Herbstanfang"
TRANSLATE "Winter Solstice" "Winteranfang" TRANSLATE "Winter Solstice" "Winteranfang"
TRANSLATE "Daylight Saving Time Starts" "Beginn Sommerzeit" TRANSLATE "Daylight Saving Time Starts" "Beginn Sommerzeit"
TRANSLATE "Daylight Saving Time Ends" "Ende Sommerzeit" TRANSLATE "Daylight Saving Time Ends" "Ende Sommerzeit"
TRANSLATE "New Moon" "Neumond"
TRANSLATE "First Quarter" "zunehmender Halbmond"
TRANSLATE "Full Moon" "Vollmond"
TRANSLATE "Last Quarter" "abnehmender Halbmond"
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"
TRANSLATE "Sunrise" "Sonnenaufgang"
TRANSLATE "Sunset" "Sonnenuntergang"
TRANSLATE "No reminders." "Keine Termine."

View File

@@ -63,7 +63,7 @@ TRANSLATE "First Quarter" "Eerste kwartier"
TRANSLATE "Full Moon" "Volle maan" TRANSLATE "Full Moon" "Volle maan"
TRANSLATE "Last Quarter" "Laatste kwartier" TRANSLATE "Last Quarter" "Laatste kwartier"
TRANSLATE "Vernal Equiniox" "Lente-equinox" TRANSLATE "Vernal Equinox" "Lente-equinox"
TRANSLATE "Summer Solstice" "Zomerzonnewende" TRANSLATE "Summer Solstice" "Zomerzonnewende"
TRANSLATE "Autumnal Equinox" "Herfst-equinox" TRANSLATE "Autumnal Equinox" "Herfst-equinox"
TRANSLATE "Winter Solstice" "Winterzonnewende" TRANSLATE "Winter Solstice" "Winterzonnewende"

View File

@@ -7,8 +7,8 @@ IF $CalMode || $PsCal
REM [moondate(2)] SPECIAL MOON 2 -1 -1 [moontime(2)] REM [moondate(2)] SPECIAL MOON 2 -1 -1 [moontime(2)]
REM [moondate(3)] SPECIAL MOON 3 -1 -1 [moontime(3)] REM [moondate(3)] SPECIAL MOON 3 -1 -1 [moontime(3)]
ELSE ELSE
REM NOQUEUE [moondatetime(0)] MSG [_("New Moon")] (%2) REM NOQUEUE [moondatetime(0)] MSG %(New Moon) (%2)
REM NOQUEUE [moondatetime(1)] MSG [_("First Quarter")] (%2) REM NOQUEUE [moondatetime(1)] MSG %(First Quarter) (%2)
REM NOQUEUE [moondatetime(2)] MSG [_("Full Moon")] (%2) REM NOQUEUE [moondatetime(2)] MSG %(Full Moon) (%2)
REM NOQUEUE [moondatetime(3)] MSG [_("Last Quarter")] (%2) REM NOQUEUE [moondatetime(3)] MSG %(Last Quarter) (%2)
ENDIF ENDIF

View File

@@ -3,14 +3,14 @@
IF $LatDeg >= 0 IF $LatDeg >= 0
# Northern Hemisphere # Northern Hemisphere
REM NOQUEUE [soleq(0)] MSG %"[_("Vernal Equinox")]%" [$Is] %3. REM NOQUEUE [soleq(0)] MSG %"%(Vernal Equinox)%" [$Is] %3.
REM NOQUEUE [soleq(1)] MSG %"[_("Summer Solstice")]%" [$Is] %3. REM NOQUEUE [soleq(1)] MSG %"%(Summer Solstice)%" [$Is] %3.
REM NOQUEUE [soleq(2)] MSG %"[_("Autumnal Equinox")]%" [$Is] %3. REM NOQUEUE [soleq(2)] MSG %"%(Autumnal Equinox)%" [$Is] %3.
REM NOQUEUE [soleq(3)] MSG %"[_("Winter Solstice")]%" [$Is] %3. REM NOQUEUE [soleq(3)] MSG %"%(Winter Solstice)%" [$Is] %3.
ELSE ELSE
# Southern Hemisphere # Southern Hemisphere
REM NOQUEUE [soleq(0)] MSG %"[_("Autumnal Equinox")]%" [$Is] %3. REM NOQUEUE [soleq(0)] MSG %"%(Autumnal Equinox)%" [$Is] %3.
REM NOQUEUE [soleq(1)] MSG %"[_("Winter Solstice")]%" [$Is] %3. REM NOQUEUE [soleq(1)] MSG %"%(Winter Solstice)%" [$Is] %3.
REM NOQUEUE [soleq(2)] MSG %"[_("Vernal Equinox")]%" [$Is] %3. REM NOQUEUE [soleq(2)] MSG %"%(Vernal Equinox)%" [$Is] %3.
REM NOQUEUE [soleq(3)] MSG %"[_("Summer Solstice")]%" [$Is] %3. REM NOQUEUE [soleq(3)] MSG %"%(Summer Solstice)%" [$Is] %3.
ENDIF ENDIF

View File

@@ -2,6 +2,6 @@
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
IF !$CalMode && !$PsCal IF !$CalMode && !$PsCal
REM NOQUEUE AT [sunrise()] MSG %"%"[_("Sunrise")] %! %2. REM NOQUEUE AT [sunrise()] MSG %"%"%(Sunrise) %! %2.
REM NOQUEUE AT [sunset()] MSG %"%"[_("Sunset")] %! %2. REM NOQUEUE AT [sunset()] MSG %"%"%(Sunset) %! %2.
ENDIF ENDIF

View File

@@ -336,6 +336,18 @@ older format contains enough information for them to work properly.
.PP .PP
\fBRemind \-p\fR sends the following lines to standard output. \fBRemind \-p\fR sends the following lines to standard output.
The information is designed to be easily parsed by back-end programs: 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 .TP
.B # rem2ps begin .B # rem2ps begin
This line signifies the start of calendar data. Back-ends can search This line signifies the start of calendar data. Back-ends can search
@@ -435,6 +447,16 @@ each reminder as a one-off event.
.PP .PP
The lines emitted by \fBremind \-pp\fR are as follows: The lines emitted by \fBremind \-pp\fR are as follows:
.TP .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 .B # rem2ps2 begin
This line signifies the start of calendar data. Back-ends can search This line signifies the start of calendar data. Back-ends can search
for it to verify they are being fed correct information. Note the 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 The year of the following month. (The same as \fByear\fR unless the
current month is December.) current month is December.)
.TP .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] .B entries \fR[\fIarray\fR]
The \fBentries\fR key consists of an array of calendar entries; each 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 entry is a JSON object that has the same format as described in the

View File

@@ -1612,6 +1612,10 @@ is replaced with "\fIyear\fR", the year of the trigger date.
.B %z .B %z
is replaced with "\fIyy\fR", the last two digits of the year. is replaced with "\fIyy\fR", the last two digits of the year.
.TP .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 %_ .B %_
(percent-underscore) is replaced with a newline. You can use this to (percent-underscore) is replaced with a newline. You can use this to
achieve multi-line reminders. Note that calendar back-ends vary in achieve multi-line reminders. Note that calendar back-ends vary in
@@ -1920,7 +1924,7 @@ the first day of the month. The local \fBOMIT\fR keyword causes the
Finally, the \fBAFTER\fR keyword will keep moving the reminder forward Finally, the \fBAFTER\fR keyword will keep moving the reminder forward
until it has passed any holidays specified with global \fBOMIT\fR until it has passed any holidays specified with global \fBOMIT\fR
commands. commands.
.SH THE DO AND INCLUDE COMMANDS .SH THE DO, INCLUDE AND SYSINCLUDE COMMANDS
.PP .PP
\fBRemind\fR allows you to include other files in your reminder script, \fBRemind\fR allows you to include other files in your reminder script,
similar to the C preprocessor #include directive. For example, your similar to the C preprocessor #include directive. For example, your
@@ -1977,6 +1981,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 resolve the real path of symbolic links, so you should avoid using
symbolic links to files. symbolic links to files.
.PP .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 thie version of \fBRemind\fR, the system directory is
"@prefix@/share/remind".
.PP
.SH THE RUN COMMAND .SH THE RUN COMMAND
.PP .PP
If you include other files in your reminder script, you may not always If you include other files in your reminder script, you may not always
@@ -3046,6 +3055,25 @@ For example, consider this sequence:
After those two lines have been executed, the variable \fBa\fR will be 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 set to "Tot ziens". See the section THE TRANSLATION TABLE for more
information. 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 .RE
.TP .TP
.B abs(i_num) .B abs(i_num)
@@ -5727,8 +5755,10 @@ then \fBRemind\fR \fIalso\fR makes a corresponding translation
table entry automatically. This is done for all of the translation-related table entry automatically. This is done for all of the translation-related
system variables \fIexcept for\fR \fB$Hplu\fR and \fB$Mplu\fR. system variables \fIexcept for\fR \fB$Hplu\fR and \fB$Mplu\fR.
.PP .PP
The converse does not apply; creating a translation table entry for The converse applies too; creating a translation table for
"December" does not automatically set \fB$December\fR. "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 .PP
The translation table always contains a special entry \fBLANGID\fR whose The translation table always contains a special entry \fBLANGID\fR whose
default value is \fBen\fR. Translators are encouraged to add a \fBLANGID\fR default value is \fBen\fR. Translators are encouraged to add a \fBLANGID\fR
@@ -5779,14 +5809,14 @@ To use a language pack (in this example, de.rem), simply place this at
the top of your reminders file: the top of your reminders file:
.PP .PP
.nf .nf
INCLUDE [$SysInclude]/lang/de.rem SYSINCLUDE lang/de.rem
.fi .fi
.PP .PP
If you want \fBRemind\fR to try to find the language pack appropriate If you want \fBRemind\fR to try to find the language pack appropriate
for your locale settings, use: for your locale settings, use:
.PP .PP
.nf .nf
INCLUDE [$SysInclude]/lang/auto.rem SYSINCLUDE lang/auto.rem
.fi .fi
.PP .PP
You are encouraged to study the language packs to see how to translate You are encouraged to study the language packs to see how to translate

View File

@@ -10,6 +10,8 @@ use Encode;
my %Options; my %Options;
my $Translations = {};
my $rem2html_version = '@VERSION@'; my $rem2html_version = '@VERSION@';
my($days, $shades, $moons, $classes, $Month, $Year, $Numdays, $Firstwkday, $Mondayfirst, $weeks, my($days, $shades, $moons, $classes, $Month, $Year, $Numdays, $Firstwkday, $Mondayfirst, $weeks,
@@ -265,6 +267,31 @@ sub end_output
print("</body>\n</html>\n"); 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 sub parse_input
{ {
undef $days; undef $days;
@@ -275,8 +302,12 @@ sub parse_input
my $found_data = 0; my $found_data = 0;
while(<STDIN>) { while(<STDIN>) {
chomp; chomp;
last if /^\# rem2ps2? begin$/; if (/# translations/) {
slurp_translations();
next;
}
last if /^\# rem2ps2? begin$/;
} }
my $line; my $line;
@@ -659,7 +690,7 @@ sub draw_day_cell
} else { } else {
$img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAC6SURBVDiNpdNNbsIwFATgL0HKolchHKBX6yFaBOEyoPYUabvOIVKJRaCL2JX5TRNGGvnJ8ozGz89cYoElPvET+BX2yivn/1Bggw5HHMKa1h2qcPZC/JEIhvh+brIZIY6sorhMYo9hh3KGFzzfa84NZNjDt9OG/ZcH1BlaPE1IAG0+URhxzNGESKPFaHJs9Q0Ziww7HnvGeXSrJhis0jiFfjwnj3I0WRv+TKtr4hQl3lDrZ6QN9Wt654hfWfGDmBpUwDkAAAAASUVORK5CYII='; $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'; $alt = 'new';
} elsif ($phase == 1) { } elsif ($phase == 1) {
if ($Options{pngs}) { if ($Options{pngs}) {
@@ -667,7 +698,7 @@ sub draw_day_cell
} else { } else {
$img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADfSURBVDiNndM9TsNAFATgzy5yjZSAE85JBygETgENUPF3iBCitHAFQkcIhZ/Ryn9gRlrZmp2Z3ef3TBOHOMULPrDBMrhpi/4HI5xjix2+4nmJRbx/Yh7ahvkpRPVV4QDXwT3UQy46zGkAZDgK/iytefvHgCrkJsqZUH6cLnNbABSxd5Jhhf1IbkMXv8Qux7hH1Ic1xvk/jBWy6gavumvtwx7ectwZXkKh7MA95XgObeOtpI2U4zl0kGbpxgiPvwQUcXLrKFchc82f6Ur0PK49azOnmOI4TBu84zm4SV38DeIVYkrYJyNbAAAAAElFTkSuQmCC'; $img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADfSURBVDiNndM9TsNAFATgzy5yjZSAE85JBygETgENUPF3iBCitHAFQkcIhZ/Ryn9gRlrZmp2Z3ef3TBOHOMULPrDBMrhpi/4HI5xjix2+4nmJRbx/Yh7ahvkpRPVV4QDXwT3UQy46zGkAZDgK/iytefvHgCrkJsqZUH6cLnNbABSxd5Jhhf1IbkMXv8Qux7hH1Ic1xvk/jBWy6gavumvtwx7ectwZXkKh7MA95XgObeOtpI2U4zl0kGbpxgiPvwQUcXLrKFchc82f6Ur0PK49azOnmOI4TBu84zm4SV38DeIVYkrYJyNbAAAAAElFTkSuQmCC';
} }
$title = 'First Quarter'; $title = escape_html(t('First Quarter'));
$alt = '1st'; $alt = '1st';
} elsif ($phase == 2) { } elsif ($phase == 2) {
if ($Options{pngs}) { 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'; $img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADlSURBVDiNrdNBUsJAEAXQlyw4hq4hwWPqTixET6ELkZ16CcAq7oFLqXExjaYgQVNlV/Viev7/6XT/4TjGuME7PiLXUatb8N8xwB12SFjiIXIZtU/MAntEfgvQE4YtHxhiHpjXQ5H7uLhEcaLLAleBvd0Xx9Ha/BdyU+Q5OBV5OKmj7a4YBWdSyNPe4aKHAHkzqcQZNj3JgnNexqE8heyIAulffuFF3kTfIVbBVeu/xoXGGsn2TLJJ/mqkafNiINszySYZdbS90GHlvcgsWktY4TFy7ecxTdvIzahxHQLbyFXUqkPwF2ASRNYgB/PXAAAAAElFTkSuQmCC';
} }
$alt = 'full'; $alt = 'full';
$title = 'Full Moon'; $title = escape_html(t('Full Moon'));
} else { } else {
if ($Options{pngs}) { if ($Options{pngs}) {
$img = smoosh($Options{imgbase}, 'lastquarter.png'); $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=='; $img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGQAAABkABchkaRQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADmSURBVDiNndMxTsNAEIXhzy5yCyQ6FAgcE7oQheQWUAAl5BIkREoZrgB0GFNkHBl7bURGsryaee/3jHeXdpxjghU+8InXyI0S+n0MMEeBEi+4jfV3vAvMQtsyL0J0j2GtViaeRRMyj8IlsgY8BSijE2Kur/hy09wHKMJrEolhwtwHKDHOsI4OLnoAXfl1jiNsOkR9keE4P8D4q4scbzg5xIxtjie709f1E7siC+9+Gx/8fxvPKtEsklcJSBdgWhcN8ByFR5z+AWgd5QpyE+OUWOJO+zJNU+Z6jHAdgHe7K73CuD5zFT9nCmRDIssCaAAAAABJRU5ErkJggg==';
} }
$alt = 'last'; $alt = 'last';
$title = 'Last Quarter'; $title = escape_html(t('Last Quarter'));
} }
if ($Options{nostyle}) { if ($Options{nostyle}) {
print("<div style=\"float: left\"><img border=\"0\" width=\"16\" height=\"16\" alt=\"$alt\" title=\"$title\" src=\"$img\">$msg</div>"); print("<div style=\"float: left\"><img border=\"0\" width=\"16\" height=\"16\" alt=\"$alt\" title=\"$title\" src=\"$img\">$msg</div>");

View File

@@ -965,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 */ /* DoSimpleCalendarOneMonth */
@@ -984,14 +996,25 @@ static void DoSimpleCalendarOneMonth(void)
if (PsCal) { if (PsCal) {
FromDSE(DSEToday, &y, &m, &d); FromDSE(DSEToday, &y, &m, &d);
if (PsCal == PSCAL_LEVEL1) { if (PsCal == PSCAL_LEVEL1) {
if (!DidAMonth) {
SendTranslationTable(PsCal);
}
printf("%s\n", PSBEGIN); printf("%s\n", PSBEGIN);
} else if (PsCal == PSCAL_LEVEL2) { } else if (PsCal == PSCAL_LEVEL2) {
if (!DidAMonth) {
SendTranslationTable(PsCal);
}
printf("%s\n", PSBEGIN2); printf("%s\n", PSBEGIN2);
} else { } else {
if (DidAMonth) { if (DidAMonth) {
printf(",\n"); printf(",\n");
} }
printf("{\n"); printf("{\n");
if (!DidAMonth) {
printf("\"translations\":");
SendTranslationTable(PsCal);
printf(",");
}
} }
if (PsCal < PSCAL_LEVEL3) { if (PsCal < PSCAL_LEVEL3) {
printf("%s %d %d %d %d\n", printf("%s %d %d %d %d\n",
@@ -1685,6 +1708,7 @@ static void GenerateCalEntries(int col)
case T_EndIf: r=DoEndif(&p); break; case T_EndIf: r=DoEndif(&p); break;
case T_Include: case T_Include:
case T_IncludeSys:
case T_IncludeR: r=DoInclude(&p, tok.type); break; case T_IncludeR: r=DoInclude(&p, tok.type); break;
case T_IncludeCmd: r=DoIncludeCmd(&p); break; case T_IncludeCmd: r=DoIncludeCmd(&p); break;
@@ -2297,7 +2321,7 @@ void WriteJSONTrigger(Trigger const *t, int include_tags, int today)
printf(","); printf(",");
} }
done = 1; done = 1;
printf("\"%s\"", EnglishDayName[i]); printf("\"%s\"", DayName[i]);
} }
} }
printf("],"); printf("],");
@@ -2332,7 +2356,7 @@ void WriteJSONTrigger(Trigger const *t, int include_tags, int today)
printf(","); printf(",");
} }
done = 1; done = 1;
printf("\"%s\"", EnglishDayName[i]); printf("\"%s\"", DayName[i]);
} }
} }
printf("],"); printf("],");
@@ -2683,14 +2707,14 @@ CalendarTime(int tim, int duration)
} }
if (h >= 12) { if (h >= 12) {
ampm1 = DynamicPm; ampm1 = tr("pm");
} else { } else {
ampm1 = DynamicAm; ampm1 = tr("am");
} }
if (h2 >= 12) { if (h2 >= 12) {
ampm2 = DynamicPm; ampm2 = tr("pm");
} else { } else {
ampm2 = DynamicAm; ampm2 = tr("am");
} }
if (!days) { if (!days) {
if (!strcmp(ampm1, ampm2)) { if (!strcmp(ampm1, ampm2)) {
@@ -2737,7 +2761,7 @@ char const *SimpleTime(int tim)
if (h == 0) hh=12; if (h == 0) hh=12;
else if (h > 12) hh=h-12; else if (h > 12) hh=h-12;
else hh=h; 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; break;

View File

@@ -96,7 +96,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
mplu = (mdiff == 1 ? "" : DynamicMplu); mplu = (mdiff == 1 ? "" : DynamicMplu);
hplu = (hdiff == 1 ? "" : DynamicHplu); hplu = (hdiff == 1 ? "" : DynamicHplu);
when = (tdiff < 0) ? DynamicAgo : DynamicFromnow; when = (tdiff < 0) ? tr("ago") : tr("from now");
h = tim / 60; h = tim / 60;
min = tim % 60; min = tim % 60;
@@ -120,7 +120,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
} }
} }
if (r != OK) { if (r != OK) {
pm = (h < 12) ? DynamicAm : DynamicPm; pm = (h < 12) ? tr("am") : tr("pm");
} }
hh = (h == 12) ? 12 : h % 12; hh = (h == 12) ? 12 : h % 12;
@@ -147,7 +147,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
} }
} }
if (r != OK) { if (r != OK) {
cpm = (h < 12) ? DynamicAm : DynamicPm; cpm = (h < 12) ? tr("am") : tr("pm");
} }
chh = (ch == 12) ? 12 : ch % 12; chh = (ch == 12) ? 12 : ch % 12;
@@ -215,6 +215,36 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
if (!c) { if (!c) {
break; 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 == '*') { if (c == '*') {
altmode = c; altmode = c;
c = ParseChar(p, &err, 0); c = ParseChar(p, &err, 0);
@@ -311,7 +341,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
case 'L': case 'L':
case 'U': case 'U':
case 'V': case 'V':
snprintf(s, sizeof(s), "%s", (diff ? DynamicTomorrow: DynamicToday)); snprintf(s, sizeof(s), "%s", (diff ? tr("tomorrow") : tr("today")));
SHIP_OUT(s); SHIP_OUT(s);
done = 1; done = 1;
break; break;
@@ -347,11 +377,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
} }
switch(UPPER(c)) { switch(UPPER(c)) {
case 'A': case 'A':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%s, %d %s, %d", get_day_name(dse%7), d, snprintf(s, sizeof(s), "%s, %d %s, %d", get_day_name(dse%7), d,
get_month_name(m), y); get_month_name(m), y);
} else { } else {
snprintf(s, sizeof(s), "%s %s, %d %s, %d", DynamicOn, get_day_name(dse%7), d, snprintf(s, sizeof(s), "%s %s, %d %s, %d", tr("on"), get_day_name(dse%7), d,
get_month_name(m), y); get_month_name(m), y);
} }
SHIP_OUT(s); SHIP_OUT(s);
@@ -363,10 +393,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
break; break;
case 'C': case 'C':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%s", get_day_name(dse%7)); snprintf(s, sizeof(s), "%s", get_day_name(dse%7));
} else { } else {
snprintf(s, sizeof(s), "%s %s", DynamicOn, get_day_name(dse%7)); snprintf(s, sizeof(s), "%s %s", tr("on"), get_day_name(dse%7));
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
@@ -377,79 +407,79 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
break; break;
case 'E': case 'E':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", d, DateSep, snprintf(s, sizeof(s), "%02d%c%02d%c%04d", d, DateSep,
m+1, DateSep, y); m+1, DateSep, y);
} else { } else {
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, d, DateSep, snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", tr("on"), d, DateSep,
m+1, DateSep, y); m+1, DateSep, y);
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
case 'F': case 'F':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y); snprintf(s, sizeof(s), "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
} else { } else {
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, m+1, DateSep, d, DateSep, y); snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", tr("on"), m+1, DateSep, d, DateSep, y);
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
case 'G': case 'G':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%s, %d %s", get_day_name(dse%7), d, get_month_name(m)); snprintf(s, sizeof(s), "%s, %d %s", get_day_name(dse%7), d, get_month_name(m));
} else { } else {
snprintf(s, sizeof(s), "%s %s, %d %s", DynamicOn, get_day_name(dse%7), d, get_month_name(m)); snprintf(s, sizeof(s), "%s %s, %d %s", tr("on"), get_day_name(dse%7), d, get_month_name(m));
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
case 'H': case 'H':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%02d%c%02d", d, DateSep, m+1); snprintf(s, sizeof(s), "%02d%c%02d", d, DateSep, m+1);
} else { } else {
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, d, DateSep, m+1); snprintf(s, sizeof(s), "%s %02d%c%02d", tr("on"), d, DateSep, m+1);
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
case 'I': case 'I':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%02d%c%02d", m+1, DateSep, d); snprintf(s, sizeof(s), "%02d%c%02d", m+1, DateSep, d);
} else { } else {
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, m+1, DateSep, d); snprintf(s, sizeof(s), "%s %02d%c%02d", tr("on"), m+1, DateSep, d);
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
case 'J': case 'J':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%s, %s %d%s, %d", get_day_name(dse%7), snprintf(s, sizeof(s), "%s, %s %d%s, %d", get_day_name(dse%7),
get_month_name(m), d, plu, y); get_month_name(m), d, plu, y);
} else { } else {
snprintf(s, sizeof(s), "%s %s, %s %d%s, %d", DynamicOn, get_day_name(dse%7), snprintf(s, sizeof(s), "%s %s, %s %d%s, %d", tr("on"), get_day_name(dse%7),
get_month_name(m), d, plu, y); get_month_name(m), d, plu, y);
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
case 'K': case 'K':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%s, %s %d%s", get_day_name(dse%7), snprintf(s, sizeof(s), "%s, %s %d%s", get_day_name(dse%7),
get_month_name(m), d, plu); get_month_name(m), d, plu);
} else { } else {
snprintf(s, sizeof(s), "%s %s, %s %d%s", DynamicOn, get_day_name(dse%7), snprintf(s, sizeof(s), "%s %s, %s %d%s", tr("on"), get_day_name(dse%7),
get_month_name(m), d, plu); get_month_name(m), d, plu);
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
case 'L': case 'L':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d); snprintf(s, sizeof(s), "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
} else { } else {
snprintf(s, sizeof(s), "%s %04d%c%02d%c%02d", DynamicOn, y, DateSep, m+1, DateSep, d); snprintf(s, sizeof(s), "%s %04d%c%02d%c%02d", tr("on"), y, DateSep, m+1, DateSep, d);
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
@@ -465,7 +495,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
break; break;
case 'O': case 'O':
if (RealToday == DSEToday) snprintf(s, sizeof(s), " (%s)", DynamicToday); if (RealToday == DSEToday) snprintf(s, sizeof(s), " (%s)", tr("today"));
else *s = 0; else *s = 0;
SHIP_OUT(s); SHIP_OUT(s);
break; break;
@@ -496,22 +526,22 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
break; break;
case 'U': case 'U':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%s, %d%s %s, %d", get_day_name(dse%7), d, snprintf(s, sizeof(s), "%s, %d%s %s, %d", get_day_name(dse%7), d,
plu, get_month_name(m), y); plu, get_month_name(m), y);
} else { } else {
snprintf(s, sizeof(s), "%s %s, %d%s %s, %d", DynamicOn, get_day_name(dse%7), d, snprintf(s, sizeof(s), "%s %s, %d%s %s, %d", tr("on"), get_day_name(dse%7), d,
plu, get_month_name(m), y); plu, get_month_name(m), y);
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
case 'V': case 'V':
if (altmode == '*' || !strcmp(DynamicOn, "")) { if (altmode == '*' || !strcmp(tr("on"), "")) {
snprintf(s, sizeof(s), "%s, %d%s %s", get_day_name(dse%7), d, plu, snprintf(s, sizeof(s), "%s, %d%s %s", get_day_name(dse%7), d, plu,
get_month_name(m)); get_month_name(m));
} else { } else {
snprintf(s, sizeof(s), "%s %s, %d%s %s", DynamicOn, get_day_name(dse%7), d, plu, snprintf(s, sizeof(s), "%s %s, %d%s %s", tr("on"), get_day_name(dse%7), d, plu,
get_month_name(m)); get_month_name(m));
} }
SHIP_OUT(s); SHIP_OUT(s);
@@ -539,14 +569,14 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
case '1': case '1':
if (tdiff == 0) if (tdiff == 0)
snprintf(s, sizeof(s), "%s", DynamicNow); snprintf(s, sizeof(s), "%s", tr("now"));
else if (hdiff == 0) else if (hdiff == 0)
snprintf(s, sizeof(s), "%d %s%s %s", mdiff, DynamicMinute, mplu, when); snprintf(s, sizeof(s), "%d %s%s %s", mdiff, tr("minute"), mplu, when);
else if (mdiff == 0) else if (mdiff == 0)
snprintf(s, sizeof(s), "%d %s%s %s", hdiff, DynamicHour, hplu, when); snprintf(s, sizeof(s), "%d %s%s %s", hdiff, tr("hour"), hplu, when);
else else
snprintf(s, sizeof(s), "%d %s%s %s %d %s%s %s", hdiff, DynamicHour, hplu, snprintf(s, sizeof(s), "%d %s%s %s %d %s%s %s", hdiff, tr("hour"), hplu,
DynamicAnd, mdiff, DynamicMinute, mplu, when); tr("and"), mdiff, tr("minute"), mplu, when);
SHIP_OUT(s); SHIP_OUT(s);
break; break;
@@ -554,7 +584,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
if (altmode == '*') { if (altmode == '*') {
snprintf(s, sizeof(s), "%d%c%02d%s", hh, TimeSep, min, pm); snprintf(s, sizeof(s), "%d%c%02d%s", hh, TimeSep, min, pm);
} else { } else {
snprintf(s, sizeof(s), "%s %d%c%02d%s", DynamicAt, hh, TimeSep, min, pm); snprintf(s, sizeof(s), "%s %d%c%02d%s", tr("at"), hh, TimeSep, min, pm);
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
@@ -563,7 +593,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
if (altmode == '*') { if (altmode == '*') {
snprintf(s, sizeof(s), "%02d%c%02d", h, TimeSep, min); snprintf(s, sizeof(s), "%02d%c%02d", h, TimeSep, min);
} else { } else {
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicAt, h, TimeSep, min); snprintf(s, sizeof(s), "%s %02d%c%02d", tr("at"), h, TimeSep, min);
} }
SHIP_OUT(s); SHIP_OUT(s);
break; break;
@@ -604,7 +634,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int dse,
break; break;
case '!': case '!':
snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? DynamicIs : DynamicWas)); snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? tr("is") : tr("was")));
SHIP_OUT(s); SHIP_OUT(s);
break; break;

View File

@@ -612,12 +612,21 @@ int DoInclude(ParsePtr p, enum TokTypes tok)
e = VerifyEoln(p); e = VerifyEoln(p);
if (e) Eprint("%s", GetErr(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 /* Relative include: Include relative to dir
containing current file */ containing current file */
if (DBufPuts(&path, FileName) != OK) { if (tok == T_IncludeR) {
r = E_NO_MEM; if (DBufPuts(&path, FileName) != OK) {
goto bailout; 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) { if (DBufLen(&path) == 0) {
s = DBufValue(&buf); s = DBufValue(&buf);
@@ -650,9 +659,6 @@ int DoInclude(ParsePtr p, enum TokTypes tok)
goto bailout; goto bailout;
} }
NumIfs = 0;
IfFlags = 0;
bailout: bailout:
DBufFree(&buf); DBufFree(&buf);
DBufFree(&path); DBufFree(&path);
@@ -713,8 +719,6 @@ int DoIncludeCmd(ParsePtr p)
return r; return r;
} }
DBufFree(&buf); DBufFree(&buf);
NumIfs = 0;
IfFlags = 0;
return OK; return OK;
} }
@@ -905,6 +909,8 @@ static int IncludeCmd(char const *cmd)
FCLOSE(fp); FCLOSE(fp);
} }
IStackPtr++; IStackPtr++;
NumIfs = 0;
IfFlags = 0;
/* If the file is cached, use it */ /* If the file is cached, use it */
h = CachedFiles; h = CachedFiles;
@@ -941,6 +947,7 @@ static int IncludeCmd(char const *cmd)
fp2 = popen(cmd, "r"); fp2 = popen(cmd, "r");
} }
if (!fp2) { if (!fp2) {
PopFile();
DBufFree(&buf); DBufFree(&buf);
return E_CANT_OPEN; return E_CANT_OPEN;
} }
@@ -1014,6 +1021,8 @@ int IncludeFile(char const *fname)
} }
IStackPtr++; IStackPtr++;
NumIfs = 0;
IfFlags = 0;
#ifdef HAVE_GLOB #ifdef HAVE_GLOB
/* If it's a directory, set up the glob chain here. */ /* If it's a directory, set up the glob chain here. */

View File

@@ -1825,10 +1825,10 @@ static int FTrigger(func_info *info)
FromDSE(date, &y, &m, &d); FromDSE(date, &y, &m, &d);
if (tim != NO_TIME) { 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); tim/60, tim%60);
} else { } else {
sprintf(buf, "%d %s %d", d, EnglishMonthName[m], y); sprintf(buf, "%d %s %d", d, MonthName[m], y);
} }
return RetStrVal(buf, info); return RetStrVal(buf, info);
} }

View File

@@ -178,31 +178,14 @@ EXTERN INIT( int SuppressImplicitRemWarnings, 0);
extern int NumFullOmits, NumPartialOmits; extern int NumFullOmits, NumPartialOmits;
/* List of months */ /* List of months */
EXTERN char *EnglishMonthName[] EXTERN char *MonthName[]
#ifdef MK_GLOBALS #ifdef MK_GLOBALS
= {"January", "February", "March", "April", "May", "June", = {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"} "July", "August", "September", "October", "November", "December"}
#endif #endif
; ;
#define MonthName EnglishMonthName EXTERN char *DayName[]
EXTERN char *DynamicMonthName[]
#ifdef MK_GLOBALS
= {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"}
#endif
;
EXTERN char *EnglishDayName[]
#ifdef MK_GLOBALS
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
"Saturday", "Sunday"}
#endif
;
#define DayName EnglishDayName
EXTERN char *DynamicDayName []
#ifdef MK_GLOBALS #ifdef MK_GLOBALS
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
"Saturday", "Sunday"} "Saturday", "Sunday"}
@@ -227,86 +210,17 @@ EXTERN int MonthIndex[2][12]
#endif #endif
; ;
EXTERN char *DynamicAgo
#ifdef MK_GLOBALS
= "ago"
#endif
;
EXTERN char *DynamicAm
#ifdef MK_GLOBALS
= "am"
#endif
;
EXTERN char *DynamicAnd
#ifdef MK_GLOBALS
= "and"
#endif
;
EXTERN char *DynamicAt
#ifdef MK_GLOBALS
= "at"
#endif
;
EXTERN char *DynamicFromnow
#ifdef MK_GLOBALS
= "from now"
#endif
;
EXTERN char *DynamicHour
#ifdef MK_GLOBALS
= "hour"
#endif
;
EXTERN char *DynamicHplu EXTERN char *DynamicHplu
#ifdef MK_GLOBALS #ifdef MK_GLOBALS
= "s" = "s"
#endif #endif
; ;
EXTERN char *DynamicIs
#ifdef MK_GLOBALS
= "is"
#endif
;
EXTERN char *DynamicMinute
#ifdef MK_GLOBALS
= "minute"
#endif
;
EXTERN char *DynamicMplu EXTERN char *DynamicMplu
#ifdef MK_GLOBALS #ifdef MK_GLOBALS
= "s" = "s"
#endif #endif
; ;
EXTERN char *DynamicNow
#ifdef MK_GLOBALS
= "now"
#endif
;
EXTERN char *DynamicOn
#ifdef MK_GLOBALS
= "on"
#endif
;
EXTERN char *DynamicPm
#ifdef MK_GLOBALS
= "pm"
#endif
;
EXTERN char *DynamicToday
#ifdef MK_GLOBALS
= "today"
#endif
;
EXTERN char *DynamicTomorrow
#ifdef MK_GLOBALS
= "tomorrow"
#endif
;
EXTERN char *DynamicWas
#ifdef MK_GLOBALS
= "was"
#endif
;
#define XSTR(x) #x #define XSTR(x) #x
#define STRSYSDIR(x) XSTR(x) #define STRSYSDIR(x) XSTR(x)

View File

@@ -222,9 +222,6 @@ hash_table_resize(hash_table *t, int dir)
/* Move everything from the old buckets into the new */ /* Move everything from the old buckets into the new */
for (size_t i=0; i<num_old_buckets; i++) { for (size_t i=0; i<num_old_buckets; i++) {
if (!t->buckets[i]) {
continue;
}
void *p = t->buckets[i]; void *p = t->buckets[i];
while(p) { while(p) {
struct hash_link *l = LINK(t, p); struct hash_link *l = LINK(t, p);

View File

@@ -314,6 +314,7 @@ static void DoReminders(void)
case T_EndIf: r=DoEndif(&p); break; case T_EndIf: r=DoEndif(&p); break;
case T_Include: case T_Include:
case T_IncludeR: case T_IncludeR:
case T_IncludeSys:
/* In purge mode, include closes file, so we /* In purge mode, include closes file, so we
need to echo it here! */ need to echo it here! */
if (PurgeMode) { if (PurgeMode) {
@@ -1979,8 +1980,7 @@ get_day_name(int wkday)
if (wkday < 0 || wkday > 6) { if (wkday < 0 || wkday > 6) {
return "INVALID_WKDAY"; return "INVALID_WKDAY";
} }
if (DynamicDayName[wkday]) return DynamicDayName[wkday]; return t(DayName[wkday]);
return DayName[wkday];
} }
char const * char const *
@@ -1989,8 +1989,7 @@ get_month_name(int mon)
if (mon < 0 || mon > 11) { if (mon < 0 || mon > 11) {
return "INVALID_MON"; return "INVALID_MON";
} }
if (DynamicMonthName[mon]) return DynamicMonthName[mon]; return t(MonthName[mon]);
return MonthName[mon];
} }
static int GetOnceDateFromFile(void) static int GetOnceDateFromFile(void)

View File

@@ -544,7 +544,7 @@ DumpOmits(void)
} else { } else {
for (i=0; i<7; i++) { for (i=0; i<7; i++) {
if (WeekdayOmits & (1<<i)) { if (WeekdayOmits & (1<<i)) {
printf("\t%s\n", EnglishDayName[i]); printf("\t%s\n", DayName[i]);
} }
} }
} }

View File

@@ -272,4 +272,5 @@ char const *GetTranslatedString(char const *orig);
int GetTranslatedStringTryingVariants(char const *orig, DynamicBuffer *out); int GetTranslatedStringTryingVariants(char const *orig, DynamicBuffer *out);
char const *GetErr(int r); char const *GetErr(int r);
char const *t(char const *s); char const *t(char const *s);
char const *tr(char const *s);
void print_escaped_string(FILE *fp, char const *s); void print_escaped_string(FILE *fp, char const *s);

View File

@@ -357,6 +357,7 @@ int main(int argc, char *argv[])
validfile++; validfile++;
DoPsCal(); DoPsCal();
} }
DBufFree(&buf);
} }
if (!validfile) { if (!validfile) {
fprintf(stderr, "Rem2PS: Couldn't find any calendar data - are you\n"); fprintf(stderr, "Rem2PS: Couldn't find any calendar data - are you\n");

View File

@@ -107,6 +107,7 @@ Token TokArray[] = {
{ "skip", 4, T_Skip, SKIP_SKIP }, { "skip", 4, T_Skip, SKIP_SKIP },
{ "special", 7, T_RemType, PASSTHRU_TYPE }, { "special", 7, T_RemType, PASSTHRU_TYPE },
{ "sunday", 3, T_WkDay, 6 }, { "sunday", 3, T_WkDay, 6 },
{ "sysinclude", 10, T_IncludeSys, 0 },
{ "tag", 3, T_Tag, 0 }, { "tag", 3, T_Tag, 0 },
{ "third", 5, T_Ordinal, 2 }, { "third", 5, T_Ordinal, 2 },
{ "through", 7, T_Through, 0 }, { "through", 7, T_Through, 0 },

View File

@@ -229,6 +229,11 @@ InsertTranslation(char const *orig, char const *translated)
} }
RemoveTranslation(item); RemoveTranslation(item);
} }
/* TRANSLATE "foo" "foo" means to remove the translation */
if (strcmp(orig, "LANGID") && (!strcmp(orig, translated))) {
return OK;
}
item = AllocateXlateItem(orig, translated); item = AllocateXlateItem(orig, translated);
if (!item) { if (!item) {
return E_NO_MEM; return E_NO_MEM;
@@ -317,6 +322,12 @@ char const *t(char const *orig)
return orig; return orig;
} }
/* If another "t" is in scope... */
char const *tr(char const *orig)
{
return t(orig);
}
int int
DoTranslate(ParsePtr p) DoTranslate(ParsePtr p)
{ {

View File

@@ -28,6 +28,7 @@ typedef struct udf_struct UserFunc;
#define STR_TYPE 0x8 #define STR_TYPE 0x8
#define SPECIAL_TYPE 0x10 /* Only for system variables */ #define SPECIAL_TYPE 0x10 /* Only for system variables */
#define CONST_INT_TYPE 0x20 /* 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 BEG_OF_EXPR '['
#define END_OF_EXPR ']' #define END_OF_EXPR ']'
@@ -214,7 +215,7 @@ enum TokTypes
T_Date, T_DateTime, T_Day, T_Debug, T_Delta, T_Dumpvars, T_Duration, 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_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_Flush, T_Frename, T_Fset, T_Funset, T_If, T_IfTrig, T_In,
T_Include, T_IncludeCmd, T_IncludeR, T_LastBack, T_LongTime, T_Include, T_IncludeCmd, T_IncludeR, T_IncludeSys, T_LastBack, T_LongTime,
T_MaybeUncomputable, T_Month, T_NoQueue, T_Number, T_Omit, T_OmitFunc, T_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_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_RemType, T_Rep, T_Scanfrom, T_Sched, T_Set, T_Skip, T_Tag, T_Through,
@@ -285,7 +286,7 @@ typedef struct {
char const *name; char const *name;
char modifiable; char modifiable;
int type; int type;
void *value; void const *value;
int min; /* Or const-value */ int min; /* Or const-value */
int max; int max;
} SysVar; } SysVar;

170
src/var.c
View File

@@ -36,6 +36,7 @@ static int IntMin = INT_MIN;
static int IntMax = INT_MAX; static int IntMax = INT_MAX;
static hash_table VHashTbl; static hash_table VHashTbl;
static int SetSysVarHelper(SysVar *v, Value *value);
static unsigned int VarHashFunc(void *x) static unsigned int VarHashFunc(void *x)
{ {
@@ -844,47 +845,47 @@ int DoPreserve (Parser *p)
static SysVar SysVarArr[] = { static SysVar SysVarArr[] = {
/* name mod type value min/mal max */ /* name mod type value min/mal max */
{"AddBlankLines", 1, INT_TYPE, &AddBlankLines, 0, 1 }, {"AddBlankLines", 1, INT_TYPE, &AddBlankLines, 0, 1 },
{"Ago", 1, STR_TYPE, &DynamicAgo, 0, 0 }, {"Ago", 1, TRANS_TYPE, "ago", 0, 0 },
{"Am", 1, STR_TYPE, &DynamicAm, 0, 0 }, {"Am", 1, TRANS_TYPE, "am", 0, 0 },
{"And", 1, STR_TYPE, &DynamicAnd, 0, 0 }, {"And", 1, TRANS_TYPE, "and", 0, 0 },
{"April", 1, STR_TYPE, &DynamicMonthName[3], 0, 0 }, {"April", 1, TRANS_TYPE, "April", 0, 0 },
{"At", 1, STR_TYPE, &DynamicAt, 0, 0 }, {"At", 1, TRANS_TYPE, "at", 0, 0 },
{"August", 1, STR_TYPE, &DynamicMonthName[7], 0, 0 }, {"August", 1, TRANS_TYPE, "August", 0, 0 },
{"CalcUTC", 1, INT_TYPE, &CalculateUTC, 0, 1 }, {"CalcUTC", 1, INT_TYPE, &CalculateUTC, 0, 1 },
{"CalMode", 0, INT_TYPE, &DoCalendar, 0, 0 }, {"CalMode", 0, INT_TYPE, &DoCalendar, 0, 0 },
{"Daemon", 0, INT_TYPE, &Daemon, 0, 0 }, {"Daemon", 0, INT_TYPE, &Daemon, 0, 0 },
{"DateSep", 1, SPECIAL_TYPE, date_sep_func, 0, 0 }, {"DateSep", 1, SPECIAL_TYPE, date_sep_func, 0, 0 },
{"DateTimeSep", 1, SPECIAL_TYPE, datetime_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 }, {"DedupeReminders",1, INT_TYPE, &DedupeReminders, 0, 1 },
{"DefaultColor", 1, SPECIAL_TYPE, default_color_func, 0, 0 }, {"DefaultColor", 1, SPECIAL_TYPE, default_color_func, 0, 0 },
{"DefaultDelta", 1, INT_TYPE, &DefaultDelta, 0, 10000 }, {"DefaultDelta", 1, INT_TYPE, &DefaultDelta, 0, 10000 },
{"DefaultPrio", 1, INT_TYPE, &DefaultPrio, 0, 9999 }, {"DefaultPrio", 1, INT_TYPE, &DefaultPrio, 0, 9999 },
{"DefaultTDelta", 1, INT_TYPE, &DefaultTDelta, 0, 1440 }, {"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 }, {"DontFork", 0, INT_TYPE, &DontFork, 0, 0 },
{"DontQueue", 0, INT_TYPE, &DontQueue, 0, 0 }, {"DontQueue", 0, INT_TYPE, &DontQueue, 0, 0 },
{"DontTrigAts", 0, INT_TYPE, &DontIssueAts, 0, 0 }, {"DontTrigAts", 0, INT_TYPE, &DontIssueAts, 0, 0 },
{"EndSent", 1, STR_TYPE, &EndSent, 0, 0 }, {"EndSent", 1, STR_TYPE, &EndSent, 0, 0 },
{"EndSentIg", 1, STR_TYPE, &EndSentIg, 0, 0 }, {"EndSentIg", 1, STR_TYPE, &EndSentIg, 0, 0 },
{"ExpressionTimeLimit", 1, SPECIAL_TYPE, expr_time_limit_func, 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 }, {"FirstIndent", 1, INT_TYPE, &FirstIndent, 0, 132 },
{"FoldYear", 1, INT_TYPE, &FoldYear, 0, 1 }, {"FoldYear", 1, INT_TYPE, &FoldYear, 0, 1 },
{"FormWidth", 1, INT_TYPE, &FormWidth, 20, 500 }, {"FormWidth", 1, INT_TYPE, &FormWidth, 20, 500 },
{"Friday", 1, STR_TYPE, &DynamicDayName[4], 0, 0 }, {"Friday", 1, TRANS_TYPE, "Friday", 0, 0 },
{"Fromnow", 1, STR_TYPE, &DynamicFromnow, 0, 0 }, {"Fromnow", 1, TRANS_TYPE, "from now", 0, 0 },
{"Hour", 1, STR_TYPE, &DynamicHour, 0, 0 }, {"Hour", 1, TRANS_TYPE, "hour", 0, 0 },
{"Hplu", 1, STR_TYPE, &DynamicHplu, 0, 0 }, {"Hplu", 1, STR_TYPE, &DynamicHplu, 0, 0 },
{"HushMode", 0, INT_TYPE, &Hush, 0, 0 }, {"HushMode", 0, INT_TYPE, &Hush, 0, 0 },
{"IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 0, 0 }, {"IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 0, 0 },
{"InfDelta", 0, INT_TYPE, &InfiniteDelta, 0, 0 }, {"InfDelta", 0, INT_TYPE, &InfiniteDelta, 0, 0 },
{"IntMax", 0, INT_TYPE, &IntMax, 0, 0 }, {"IntMax", 0, INT_TYPE, &IntMax, 0, 0 },
{"IntMin", 0, INT_TYPE, &IntMin, 0, 0 }, {"IntMin", 0, INT_TYPE, &IntMin, 0, 0 },
{"Is", 1, STR_TYPE, &DynamicIs, 0, 0 }, {"Is", 1, TRANS_TYPE, "is", 0, 0 },
{"January", 1, STR_TYPE, &DynamicMonthName[0], 0, 0 }, {"January", 1, TRANS_TYPE, "January", 0, 0 },
{"July", 1, STR_TYPE, &DynamicMonthName[6], 0, 0 }, {"July", 1, TRANS_TYPE, "July", 0, 0 },
{"June", 1, STR_TYPE, &DynamicMonthName[5], 0, 0 }, {"June", 1, TRANS_TYPE, "June", 0, 0 },
{"LatDeg", 1, SPECIAL_TYPE, latdeg_func, 0, 0 }, {"LatDeg", 1, SPECIAL_TYPE, latdeg_func, 0, 0 },
{"Latitude", 1, SPECIAL_TYPE, latitude_func, 0, 0 }, {"Latitude", 1, SPECIAL_TYPE, latitude_func, 0, 0 },
{"LatMin", 1, SPECIAL_TYPE, latmin_func, 0, 0 }, {"LatMin", 1, SPECIAL_TYPE, latmin_func, 0, 0 },
@@ -894,53 +895,53 @@ static SysVar SysVarArr[] = {
{"Longitude", 1, SPECIAL_TYPE, longitude_func, 0, 0 }, {"Longitude", 1, SPECIAL_TYPE, longitude_func, 0, 0 },
{"LongMin", 1, SPECIAL_TYPE, longmin_func, 0, 0 }, {"LongMin", 1, SPECIAL_TYPE, longmin_func, 0, 0 },
{"LongSec", 1, SPECIAL_TYPE, longsec_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}, {"MaxFullOmits", 0, CONST_INT_TYPE, NULL, MAX_FULL_OMITS, 0},
{"MaxLateMinutes", 1, INT_TYPE, &MaxLateMinutes, 0, 1440 }, {"MaxLateMinutes", 1, INT_TYPE, &MaxLateMinutes, 0, 1440 },
{"MaxPartialOmits",0, CONST_INT_TYPE, NULL, MAX_PARTIAL_OMITS, 0}, {"MaxPartialOmits",0, CONST_INT_TYPE, NULL, MAX_PARTIAL_OMITS, 0},
{"MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY }, {"MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY },
{"MaxStringLen", 1, INT_TYPE, &MaxStringLen, -1, 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 }, {"MinsFromUTC", 1, INT_TYPE, &MinsFromUTC, -780, 780 },
{"Minute", 1, STR_TYPE, &DynamicMinute, 0, 0 }, {"Minute", 1, TRANS_TYPE, "minute", 0, 0 },
{"Monday", 1, STR_TYPE, &DynamicDayName[0], 0, 0 }, {"Monday", 1, TRANS_TYPE, "Monday", 0, 0 },
{"Mplu", 1, STR_TYPE, &DynamicMplu, 0, 0 }, {"Mplu", 1, STR_TYPE, &DynamicMplu, 0, 0 },
{"NextMode", 0, INT_TYPE, &NextMode, 0, 0 }, {"NextMode", 0, INT_TYPE, &NextMode, 0, 0 },
{"November", 1, STR_TYPE, &DynamicMonthName[10],0, 0 }, {"November", 1, TRANS_TYPE, "November", 0, 0 },
{"Now", 1, STR_TYPE, &DynamicNow, 0, 0 }, {"Now", 1, TRANS_TYPE, "now", 0, 0 },
{"NumFullOmits", 0, INT_TYPE, &NumFullOmits, 0, 0 }, {"NumFullOmits", 0, INT_TYPE, &NumFullOmits, 0, 0 },
{"NumPartialOmits",0, INT_TYPE, &NumPartialOmits, 0, 0 }, {"NumPartialOmits",0, INT_TYPE, &NumPartialOmits, 0, 0 },
{"NumQueued", 0, INT_TYPE, &NumQueued, 0, 0 }, {"NumQueued", 0, INT_TYPE, &NumQueued, 0, 0 },
{"NumTrig", 0, INT_TYPE, &NumTriggered, 0, 0 }, {"NumTrig", 0, INT_TYPE, &NumTriggered, 0, 0 },
{"October", 1, STR_TYPE, &DynamicMonthName[9], 0, 0 }, {"October", 1, TRANS_TYPE, "October", 0, 0 },
{"On", 1, STR_TYPE, &DynamicOn, 0, 0 }, {"On", 1, TRANS_TYPE, "on", 0, 0 },
{"OnceFile", 1, SPECIAL_TYPE, oncefile_func, 0, 0 }, {"OnceFile", 1, SPECIAL_TYPE, oncefile_func, 0, 0 },
{"ParseUntriggered", 1, INT_TYPE, &ParseUntriggered, 0, 1 }, {"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 }, {"PrefixLineNo", 0, INT_TYPE, &DoPrefixLineNo, 0, 0 },
{"PSCal", 0, INT_TYPE, &PsCal, 0, 0 }, {"PSCal", 0, INT_TYPE, &PsCal, 0, 0 },
{"RunOff", 0, INT_TYPE, &RunDisabled, 0, 0 }, {"RunOff", 0, INT_TYPE, &RunDisabled, 0, 0 },
{"Saturday", 1, STR_TYPE, &DynamicDayName[5], 0, 0 }, {"Saturday", 1, TRANS_TYPE, "Saturday", 0, 0 },
{"September", 1, STR_TYPE, &DynamicMonthName[8], 0, 0 }, {"September", 1, TRANS_TYPE, "September", 0, 0 },
{"SimpleCal", 0, INT_TYPE, &DoSimpleCalendar, 0, 0 }, {"SimpleCal", 0, INT_TYPE, &DoSimpleCalendar, 0, 0 },
{"SortByDate", 0, INT_TYPE, &SortByDate, 0, 0 }, {"SortByDate", 0, INT_TYPE, &SortByDate, 0, 0 },
{"SortByPrio", 0, INT_TYPE, &SortByPrio, 0, 0 }, {"SortByPrio", 0, INT_TYPE, &SortByPrio, 0, 0 },
{"SortByTime", 0, INT_TYPE, &SortByTime, 0, 0 }, {"SortByTime", 0, INT_TYPE, &SortByTime, 0, 0 },
{"SubsIndent", 1, INT_TYPE, &SubsIndent, 0, 132 }, {"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}, {"SuppressImplicitWarnings", 1, INT_TYPE, &SuppressImplicitRemWarnings, 0, 1},
{"SuppressLRM", 1, INT_TYPE, &SuppressLRM, 0, 1 }, {"SuppressLRM", 1, INT_TYPE, &SuppressLRM, 0, 1 },
{"SysInclude", 0, STR_TYPE, &SysDir, 0, 0 }, {"SysInclude", 0, STR_TYPE, &SysDir, 0, 0 },
{"T", 0, SPECIAL_TYPE, trig_date_func, 0, 0 }, {"T", 0, SPECIAL_TYPE, trig_date_func, 0, 0 },
{"Td", 0, SPECIAL_TYPE, trig_day_func, 0, 0 }, {"Td", 0, SPECIAL_TYPE, trig_day_func, 0, 0 },
{"TerminalBackground", 0, SPECIAL_TYPE, terminal_bg_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 }, {"TimeSep", 1, SPECIAL_TYPE, time_sep_func, 0, 0 },
{"Tm", 0, SPECIAL_TYPE, trig_mon_func, 0, 0 }, {"Tm", 0, SPECIAL_TYPE, trig_mon_func, 0, 0 },
{"Today", 1, STR_TYPE, &DynamicToday, 0, 0 }, {"Today", 1, TRANS_TYPE, "today", 0, 0 },
{"Tomorrow", 1, STR_TYPE, &DynamicTomorrow, 0, 0 }, {"Tomorrow", 1, TRANS_TYPE, "tomorrow", 0, 0 },
{"Tt", 0, SPECIAL_TYPE, trig_time_func, 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 }, {"Tw", 0, SPECIAL_TYPE, trig_wday_func, 0, 0 },
{"Ty", 0, SPECIAL_TYPE, trig_year_func, 0, 0 }, {"Ty", 0, SPECIAL_TYPE, trig_year_func, 0, 0 },
{"U", 0, SPECIAL_TYPE, today_date_func, 0, 0 }, {"U", 0, SPECIAL_TYPE, today_date_func, 0, 0 },
@@ -948,72 +949,51 @@ static SysVar SysVarArr[] = {
{"Um", 0, SPECIAL_TYPE, today_mon_func, 0, 0 }, {"Um", 0, SPECIAL_TYPE, today_mon_func, 0, 0 },
{"UntimedFirst", 0, INT_TYPE, &UntimedBeforeTimed, 0, 0 }, {"UntimedFirst", 0, INT_TYPE, &UntimedBeforeTimed, 0, 0 },
{"Use256Colors", 0, INT_TYPE, &Use256Colors, 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 }, {"UseTrueColors", 0, INT_TYPE, &UseTrueColors, 0, 0 },
{"UseVTColors", 0, INT_TYPE, &UseVTColors, 0, 0 }, {"UseVTColors", 0, INT_TYPE, &UseVTColors, 0, 0 },
{"Uw", 0, SPECIAL_TYPE, today_wday_func, 0, 0 }, {"Uw", 0, SPECIAL_TYPE, today_wday_func, 0, 0 },
{"Uy", 0, SPECIAL_TYPE, today_year_func, 0, 0 }, {"Uy", 0, SPECIAL_TYPE, today_year_func, 0, 0 },
{"Was", 1, STR_TYPE, &DynamicWas, 0, 0 }, {"Was", 1, TRANS_TYPE, "was", 0, 0 },
{"Wednesday", 1, STR_TYPE, &DynamicDayName[2], 0, 0 } {"Wednesday", 1, TRANS_TYPE, "Wednesday", 0, 0 }
}; };
#define NUMSYSVARS ( sizeof(SysVarArr) / sizeof(SysVar) ) #define NUMSYSVARS ( sizeof(SysVarArr) / sizeof(SysVar) )
static void DumpSysVar (char const *name, const SysVar *v); static void DumpSysVar (char const *name, const SysVar *v);
static void HandleTranslatableVariable(char **var) static int SetTranslatableVariable(SysVar *v, Value *value)
{ {
if (var == (char **) &DynamicAgo) InsertTranslation("ago", *var); return InsertTranslation((char const *) v->value, value->v.str);
else if (var == (char **) &DynamicAm) InsertTranslation("am", *var);
else if (var == (char **) &DynamicAnd) InsertTranslation("and", *var);
else if (var == (char **) &DynamicAt) InsertTranslation("at", *var);
else if (var == (char **) &DynamicFromnow) InsertTranslation("from now", *var);
else if (var == (char **) &DynamicHour) InsertTranslation("hour", *var);
else if (var == (char **) &DynamicIs) InsertTranslation("is", *var);
else if (var == (char **) &DynamicMinute) InsertTranslation("minute", *var);
else if (var == (char **) &DynamicNow) InsertTranslation("now", *var);
else if (var == (char **) &DynamicOn) InsertTranslation("on", *var);
else if (var == (char **) &DynamicPm) InsertTranslation("pm", *var);
else if (var == (char **) &DynamicToday) InsertTranslation("today", *var);
else if (var == (char **) &DynamicTomorrow) InsertTranslation("tomorrow", *var);
else if (var == (char **) &DynamicWas) InsertTranslation("was", *var);
else if (var == (char **) &DynamicMonthName[0]) InsertTranslation("January", *var);
else if (var == (char **) &DynamicMonthName[1]) InsertTranslation("February", *var);
else if (var == (char **) &DynamicMonthName[2]) InsertTranslation("March", *var);
else if (var == (char **) &DynamicMonthName[3]) InsertTranslation("April", *var);
else if (var == (char **) &DynamicMonthName[4]) InsertTranslation("May", *var);
else if (var == (char **) &DynamicMonthName[5]) InsertTranslation("June", *var);
else if (var == (char **) &DynamicMonthName[6]) InsertTranslation("July", *var);
else if (var == (char **) &DynamicMonthName[7]) InsertTranslation("August", *var);
else if (var == (char **) &DynamicMonthName[8]) InsertTranslation("September", *var);
else if (var == (char **) &DynamicMonthName[9]) InsertTranslation("October", *var);
else if (var == (char **) &DynamicMonthName[10]) InsertTranslation("November", *var);
else if (var == (char **) &DynamicMonthName[11]) InsertTranslation("December", *var);
else if (var == (char **) &DynamicDayName[0]) InsertTranslation("Monday", *var);
else if (var == (char **) &DynamicDayName[1]) InsertTranslation("Tuesday", *var);
else if (var == (char **) &DynamicDayName[2]) InsertTranslation("Wednesday", *var);
else if (var == (char **) &DynamicDayName[3]) InsertTranslation("Thursday", *var);
else if (var == (char **) &DynamicDayName[4]) InsertTranslation("Friday", *var);
else if (var == (char **) &DynamicDayName[5]) InsertTranslation("Saturday", *var);
else if (var == (char **) &DynamicDayName[6]) InsertTranslation("Sunday", *var);
} }
/***************************************************************/
/* */ static int GetTranslatableVariable(SysVar *v, Value *value)
/* SetSysVar */ {
/* */ char const *translated = t((char const *) v->value);
/* Set a system variable to the indicated value. */ if (translated) {
/* */ value->v.str = StrDup(translated);
/***************************************************************/ } else {
int SetSysVar(char const *name, Value *value) 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; int r;
SysVar *v = FindSysVar(name);
if (!v) return E_NOSUCH_VAR;
if (!v->modifiable) { if (!v->modifiable) {
Eprint("%s: `$%s'", GetErr(E_CANT_MODIFY), name); Eprint("%s: `$%s'", GetErr(E_CANT_MODIFY), v->name);
return E_CANT_MODIFY; 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 && if (v->type != SPECIAL_TYPE &&
v->type != value->type) return E_BAD_TYPE; v->type != value->type) return E_BAD_TYPE;
if (v->type == SPECIAL_TYPE) { if (v->type == SPECIAL_TYPE) {
@@ -1035,7 +1015,6 @@ int SetSysVar(char const *name, Value *value)
v->been_malloced = 1; v->been_malloced = 1;
*((char **) v->value) = value->v.str; *((char **) v->value) = value->v.str;
value->type = ERR_TYPE; /* So that it's not accidentally freed */ value->type = ERR_TYPE; /* So that it's not accidentally freed */
HandleTranslatableVariable((char **) v->value);
} else { } else {
if (v->max != ANY && value->v.val > v->max) return E_2HIGH; if (v->max != ANY && value->v.val > v->max) return E_2HIGH;
if (v->min != ANY && value->v.val < v->min) return E_2LOW; if (v->min != ANY && value->v.val < v->min) return E_2LOW;
@@ -1044,6 +1023,20 @@ int SetSysVar(char const *name, Value *value)
return OK; 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 */ /* GetSysVar */
@@ -1057,6 +1050,10 @@ int GetSysVar(char const *name, Value *val)
val->type = ERR_TYPE; val->type = ERR_TYPE;
if (!v) return E_NOSUCH_VAR; if (!v) return E_NOSUCH_VAR;
if (v->type == TRANS_TYPE) {
return GetTranslatableVariable(v, val);
}
if (v->type == CONST_INT_TYPE) { if (v->type == CONST_INT_TYPE) {
val->v.val = v->constval; val->v.val = v->constval;
val->type = INT_TYPE; val->type = INT_TYPE;
@@ -1163,6 +1160,15 @@ static void DumpSysVar(char const *name, const SysVar *v)
PrintValue(&vtmp, ErrFp); PrintValue(&vtmp, ErrFp);
putc('\n', ErrFp); putc('\n', ErrFp);
DestroyValue(vtmp); 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) { } else if (v->type == STR_TYPE) {
vtmp.type = STR_TYPE; vtmp.type = STR_TYPE;
vtmp.v.str = * ((char **)v->value); vtmp.v.str = * ((char **)v->value);

6
tests/test-all-langs.sh Executable file
View 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

View File

@@ -622,6 +622,11 @@ fi
# Torture test #2 # Torture test #2
../src/remind ../tests/torture2.rem >> ../tests/test.out 2>&1 ../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 # 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 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 cmp -s ../tests/test.out ../tests/test.cmp

File diff suppressed because it is too large Load Diff

View File

@@ -1274,6 +1274,169 @@ set a _("meow")
set a _("Meow") 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
DEBUG -e
# Output expression-node stats # Output expression-node stats
DEBUG +s DEBUG +s

View File

@@ -310009,3 +310009,4 @@ REM MSG Dedup-9996
REM MSG Dedup-9997 REM MSG Dedup-9997
REM MSG Dedup-9998 REM MSG Dedup-9998
REM MSG Dedup-9999 REM MSG Dedup-9999
set $DedupeReminders 0

View File

@@ -33,9 +33,9 @@ endif
if defined("i") if defined("i")
do [i] do [i]
# msg INCLUDING [i]
endif endif
REM MSG Language: %(LANGID)
# Set up a few useful definitions # Set up a few useful definitions
fset show(x) "%%" + x + " yields: " + char(34) + "%" + x + char(34) + "% and %%*" + x + " yields: " + char(34) + "%*" + x + char(34) + "%" fset show(x) "%%" + x + " yields: " + char(34) + "%" + x + char(34) + "% and %%*" + x + " yields: " + char(34) + "%*" + x + char(34) + "%"
set a trigger(today()+2) + " ++2" set a trigger(today()+2) + " ++2"
@@ -856,3 +856,37 @@ msg [showmon(9)]
msg [showmon(10)] msg [showmon(10)]
msg [showmon(11)] msg [showmon(11)]
msg [showmon(12)] msg [showmon(12)]
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]%