mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
59 Commits
04.01.00
...
04.02.00-B
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5258e98f54 | ||
|
|
af9d42721c | ||
|
|
8ed43f5c3e | ||
|
|
ec02a87c2b | ||
|
|
6c2ec04d40 | ||
|
|
9f91cdf0b9 | ||
|
|
8ada68ce54 | ||
|
|
d7975634af | ||
|
|
87be68fecf | ||
|
|
b42d5fd412 | ||
|
|
603228b944 | ||
|
|
c62f676813 | ||
|
|
c7654c27a6 | ||
|
|
b00bf05fea | ||
|
|
29bd07d4ef | ||
|
|
b7047da89e | ||
|
|
f26334e25f | ||
|
|
b80bc5f788 | ||
|
|
91549e18ce | ||
|
|
07fd975935 | ||
|
|
f9d968cf68 | ||
|
|
6a7e696a60 | ||
|
|
6734fae1db | ||
|
|
481fbc20a1 | ||
|
|
3c120bf561 | ||
|
|
ee65e04974 | ||
|
|
4ee6bb0eca | ||
|
|
b9839421f2 | ||
|
|
67601507fa | ||
|
|
c2e5534462 | ||
|
|
f4ea3af6fc | ||
|
|
e0998a3991 | ||
|
|
d67e580d0a | ||
|
|
d6ce54eea4 | ||
|
|
8b9ec43029 | ||
|
|
9d68134f0f | ||
|
|
3d91371870 | ||
|
|
d1c0ef63b0 | ||
|
|
2a59da61e1 | ||
|
|
2bc5e21627 | ||
|
|
7d77bfd12a | ||
|
|
0ff589c288 | ||
|
|
f3cca092be | ||
|
|
7218d55f08 | ||
|
|
ec72c74016 | ||
|
|
c946f08235 | ||
|
|
a8543ac349 | ||
|
|
dd3c0e14ed | ||
|
|
a2bc0acd3c | ||
|
|
a34266741a | ||
|
|
dedb9766c9 | ||
|
|
aedd759f50 | ||
|
|
a24c2f6905 | ||
|
|
fac31a10b8 | ||
|
|
fba9f139ed | ||
|
|
588d9debe8 | ||
|
|
805c2e0c69 | ||
|
|
2c2b1440b3 | ||
|
|
6973f62d74 |
@@ -6,7 +6,7 @@ tests:
|
||||
- chown -R testuser .
|
||||
- chmod -R go-w .
|
||||
script:
|
||||
- LANG=C.UTF-8 su testuser -c 'make test'
|
||||
- LANG=C.UTF-8 su testuser -c './configure && make test'
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
|
||||
2
Makefile
2
Makefile
@@ -39,7 +39,7 @@ install-stripped:
|
||||
@$(MAKE) -C rem2html install
|
||||
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
|
||||
|
||||
test: all
|
||||
test:
|
||||
@$(MAKE) -C src -s test
|
||||
|
||||
distclean: clean
|
||||
|
||||
21
README
21
README
@@ -34,5 +34,26 @@ If you do NOT have Tcl/Tk or are NOT running X Windows:
|
||||
|
||||
5) Type: "make install" -- you may need to be root to do this.
|
||||
|
||||
PREREQUISITES:
|
||||
--------------
|
||||
|
||||
Remind and rem2ps have no prerequisites beyond the standard C library and
|
||||
the standard math library.
|
||||
|
||||
Rem2HTML requires the JSON::MaybeXS Perl module; on Debian-like
|
||||
systems, you can install that with:
|
||||
|
||||
apt install libjson-maybexs-perl
|
||||
|
||||
Rem2PDF requires the JSON::MaybeXS, Pango and Cairo Perl modules. On
|
||||
Debian-like systems, install with:
|
||||
|
||||
apt install libjson-maybexs-perl libpango-perl libcairo-perl
|
||||
|
||||
TkRemind requires Tcl/Tk and the tcllib library. On Debian-like systems
|
||||
install with:
|
||||
|
||||
apt install tcl tk tcllib
|
||||
|
||||
Contact info: mailto:dianne@skoll.ca
|
||||
Home page: https://dianne.skoll.ca/projects/remind/
|
||||
|
||||
2
configure
vendored
2
configure
vendored
@@ -4015,7 +4015,7 @@ _ACEOF
|
||||
fi
|
||||
done
|
||||
|
||||
VERSION=04.01.00
|
||||
VERSION=04.02.00
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ if test "$?" != 0 ; then
|
||||
exit 1
|
||||
fi
|
||||
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
|
||||
VERSION=04.01.00
|
||||
VERSION=04.02.00
|
||||
AC_SUBST(VERSION)
|
||||
AC_SUBST(PERL)
|
||||
AC_SUBST(PERLARTIFACTS)
|
||||
|
||||
@@ -1,5 +1,54 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 4.2 Patch 0 - 2022-??-??
|
||||
|
||||
- NEW FEATURE: remind: Allow weekdays to be globally-omitted. For example:
|
||||
|
||||
OMIT Saturday Sunday
|
||||
|
||||
globally-omits all Saturdays and Sundays.
|
||||
|
||||
- NEW FEATURE: remind: Add ansicolor() built-in function to make it easier
|
||||
to colorize reminders on the terminal. Suggested by Tim Chase.
|
||||
|
||||
- NEW FEATURE: remind: Add several special variables related to the color
|
||||
mode: $UseVTColors, $UseBGVTColors, $Use256Colors, $UseTrueColors and
|
||||
$TerminalBackground. Based on a suggestion by Tim Chase.
|
||||
|
||||
- NEW FEATURE: remind: Add utctolocal() and localtoutc() built-in functions.
|
||||
|
||||
- NEW FEATURE: remind: Add timezone() built-in function.
|
||||
|
||||
- NEW FEATURE: remind: Add trigtags() function per suggestion from Tim Chase.
|
||||
|
||||
- NEW FEATURE: remind: The $AddBlankLines system variable controls whether or
|
||||
not a blank line is added after each reminder.
|
||||
|
||||
- NEW FEATURE: remind: The built-in functions columns() and rows() return the
|
||||
width and height of the terminal (in character positions) respectively.
|
||||
|
||||
- NEW FEATURE: remind: The built-in function columns("string") returns the
|
||||
number of columns occupied by "string" on the terminal, taking into account
|
||||
double-width Unicode characters and zero-width ANSI escape sequences.
|
||||
|
||||
- NEW FEATURE: remind: You can add custom substitution sequences of the form
|
||||
%{name} or %*{name} that end up calling the function subst_name and using
|
||||
its return value as the replacement for the substitution sequence.
|
||||
|
||||
- BUG FIX: remind: Make MSF correctly format UTF-8 text and text with
|
||||
embedded ANSI color-changing codes.
|
||||
|
||||
- BUG FIX: remind: Make ADDOMIT actually work correctly in a SATISFY-type
|
||||
REM command. Bug found by Gunther Reißig
|
||||
|
||||
- BUG FIX: Convert documentation files and src/lang.h to UTF-8. Patch
|
||||
from Jochen Sprickerhof.
|
||||
|
||||
- BUG FIX: Fix tests in non-UTF-8 locales.
|
||||
|
||||
- BUG FIX: Fix a few problems with the include include/holidays/us.rem
|
||||
file.
|
||||
|
||||
* VERSION 4.1 Patch 0 - 2022-09-25
|
||||
|
||||
- NEW FEATURE: remind: "remind -c" now supports the MOON special, printing
|
||||
@@ -42,7 +91,7 @@ CHANGES TO REMIND
|
||||
- DOCUMENTATION FIX: Fix inaccuracy in how string constants were documented.
|
||||
|
||||
- BUG FIX: Makefiles: Pass CFLAGS at link-time so link-time optimization
|
||||
actually happens. Pointed out by Zolan Puskas.
|
||||
actually happens. Pointed out by Zoltan Puskas.
|
||||
|
||||
- BUG FIX: If the first REM command to trigger was a RUN command, the banner
|
||||
would not print. This has been fixed.
|
||||
@@ -52,10 +101,10 @@ CHANGES TO REMIND
|
||||
- BUG FIX: make "make test" depend on "make all" (Jochen Sprickerhof)
|
||||
|
||||
- BUG FIX: make "REM ... SATISFY ... MSG foo" respect $DefaultColor. Bug
|
||||
reported by Gunther Reißig.
|
||||
reported by Gunther Reißig.
|
||||
|
||||
- BUG FIX: Don't consider IFTRIG true if we could not compute a trigger date.
|
||||
Bug noted by Gunther Reißig
|
||||
Bug noted by Gunther Reißig.
|
||||
|
||||
* VERSION 4.0 Patch 3 - 2022-08-16
|
||||
|
||||
@@ -1124,7 +1173,7 @@ CHANGES TO REMIND
|
||||
- Fixed dates for Yom Hazikaron and Yom Ha'atzmaut if 5 Iyar falls on a
|
||||
Saturday. (Hebrew calendar fix.)
|
||||
|
||||
- Added support for the Icelandic language, courtesy of Björn Davíðsson.
|
||||
- Added support for the Icelandic language, courtesy of Björn Davíðsson.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
|
||||
18
examples/alignment.rem
Normal file
18
examples/alignment.rem
Normal file
@@ -0,0 +1,18 @@
|
||||
# Demo the columns() function
|
||||
#
|
||||
# Run as: remind -@2 alignment.rem
|
||||
|
||||
SET $AddBlankLines 0
|
||||
BANNER %
|
||||
|
||||
FSET center(x) pad("", " ", (columns() - columns(x))/2) + x
|
||||
FSET right(x) pad("", " ", columns() - columns(x)) + x
|
||||
|
||||
MSG This is left-aligned.
|
||||
MSG [ansicolor(0,255,0)]This is also left-aligned.[ansicolor("")]
|
||||
|
||||
MSG [center("This is centered.")]
|
||||
MSG [ansicolor(255,255,0) + center("🌕 🌕 🌕 🌕 This is also centered. ") + ansicolor("")]
|
||||
|
||||
msg [right("This is right-aligned.")]
|
||||
msg [ansicolor(255,0,0) + right("This is also right-aligned. 🌕 🌕 🌕") + ansicolor("")]
|
||||
34
examples/astro
Executable file
34
examples/astro
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# A little demo script that displays astronomical events
|
||||
#
|
||||
# Best used in a UTF-8 environment.
|
||||
|
||||
remind -g -@2 - <<'EOF'
|
||||
# Set this variable to 1 if your terminal has a dark background or 0 if
|
||||
# it is light.
|
||||
|
||||
SET bg_dark 1
|
||||
|
||||
SET $AddBlankLines 0
|
||||
BANNER %
|
||||
|
||||
IF bg_dark
|
||||
SPECIAL COLOR 255 255 0 Sunrise: 🌅 [sunrise()] today and [sunrise(today()+1)] tomorrow
|
||||
SPECIAL COLOR 255 128 0 Sunset: 🌇 [sunset()] today and [sunset(today()+1)] tomorrow%_
|
||||
|
||||
REM [moondate(0)] +60 SPECIAL COLOR 255 255 0 New moon: 🌑 [moondate(0)] (%b)
|
||||
REM [moondate(1)] +60 SPECIAL COLOR 255 255 128 First Quarter: 🌓 [moondate(1)] (%b)
|
||||
REM [moondate(2)] +60 SPECIAL COLOR 255 255 255 Full moon: 🌕 [moondate(2)] (%b)
|
||||
REM [moondate(3)] +60 SPECIAL COLOR 255 255 128 Last Quarter: 🌗 [moondate(3)] (%b)
|
||||
ELSE
|
||||
SPECIAL COLOR 128 128 0 Sunrise: 🌅 [sunrise()] today and [sunrise(today()+1)] tomorrow
|
||||
SPECIAL COLOR 128 32 0 Sunset: 🌇 [sunset()] today and [sunset(today()+1)] tomorrow%_
|
||||
|
||||
REM [moondate(0)] +60 SPECIAL COLOR 128 128 0 New moon: 🌑 [moondate(0)] (%b)
|
||||
REM [moondate(1)] +60 SPECIAL COLOR 128 128 64 First Quarter: 🌓 [moondate(1)] (%b)
|
||||
REM [moondate(2)] +60 SPECIAL COLOR 0 0 0 Full moon: 🌕 [moondate(2)] (%b)
|
||||
REM [moondate(3)] +60 SPECIAL COLOR 128 128 64 Last Quarter: 🌗 [moondate(3)] (%b)
|
||||
ENDIF
|
||||
|
||||
EOF
|
||||
@@ -77,16 +77,16 @@ REM 1 MSG John's [_mo_num(11, 1984)] 'monthly' anniversary
|
||||
############################################################################
|
||||
|
||||
# If it falls on a Saturday, bump to previous Friday
|
||||
REM 4 July OMIT SAT SCANFROM -1 BEFORE ADDOMIT SATISFY [$Td != 4] MSG Independence day (observed)
|
||||
REM 3 JULY SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Independence day (observed)
|
||||
|
||||
# If it falls on a Sunday, bump to following Monday
|
||||
REM 4 July OMIT SUN SCANFROM -7 AFTER ADDOMIT SATISFY [$Td != 4] MSG Independence day (observed)
|
||||
REM 5 July SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Independence day (observed)
|
||||
|
||||
# If it falls on Sat or Sun, note the actual day
|
||||
REM 4 July SATISFY [$Tw == 0 || $Tw == 6] MSG Independence day (actual)
|
||||
REM 4 July SCANFROM -7 ADDOMIT SATISFY [$Tw == 0 || $Tw == 6] MSG Independence day (actual)
|
||||
|
||||
# Otherwise observed and actual is on the 4th
|
||||
REM 4 July OMIT SAT SUN SKIP SCANFROM -7 ADDOMIT MSG Independence Day
|
||||
REM 4 July SCANFROM -7 ADDOMIT SATISFY [$Tw >= 1 && $Tw <= 5] MSG Independence Day
|
||||
|
||||
##########################################################################
|
||||
# #
|
||||
|
||||
@@ -19,13 +19,9 @@ REM Feb 14 MSG %"Valentine's Day%"
|
||||
REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG %"President's Day%"
|
||||
REM Mar 17 MSG %"St. Patrick's Day%"
|
||||
|
||||
# The DST rules are accurate for most locations in
|
||||
# North America
|
||||
REM Sun Apr 1 ++2 UNTIL 1 Jan 2007 MSG Daylight Saving Time - %"DST starts%" %b
|
||||
REM Sun Mar 8 ++2 FROM 1 Jan 2007 MSG Daylight Saving Time - %"DST starts%" %b
|
||||
|
||||
REM Last Sunday in October ++2 UNTIL 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b
|
||||
REM First Sunday in November ++2 FROM 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b
|
||||
# These are accurate for most places in North America
|
||||
REM MAYBE-UNCOMPUTABLE Sun November SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Ends
|
||||
REM MAYBE-UNCOMPUTABLE Sun March SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Starts
|
||||
|
||||
REM Apr 1 MSG %"April Fool's%" Day
|
||||
REM Mon Tue Wed Thu Fri Sat 15 Apr MSG %"Income tax%" due
|
||||
@@ -35,15 +31,24 @@ REM Second Sun in May MSG %"Mother's Day%"
|
||||
REM Third Sat in May MSG %"Armed Forces Day%"
|
||||
REM Last Monday in May SCANFROM -7 ADDOMIT MSG %"Memorial Day%"
|
||||
REM Jun 14 MSG %"Flag Day%"
|
||||
|
||||
REM July 4 SCANFROM -7 ADDOMIT MSG Independence Day
|
||||
REM July 3 SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Independence Day (observed)
|
||||
REM July 5 SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Independence Day (observed)
|
||||
|
||||
REM Third Sun in June MSG %"Father's Day%"
|
||||
REM First Mon in Sep SCANFROM -7 ADDOMIT MSG %"Labor Day%"
|
||||
REM Second Mon in Oct MSG %"Columbus Day%"
|
||||
REM Second Mon in Oct MSG %"Columbus Day / Indigenous Peoples' Day%"
|
||||
REM Nov 11 MSG %"Veterans Day%"
|
||||
|
||||
REM Oct 30 MSG %"Mischief Night%"
|
||||
REM Oct 31 MSG %"Halloween%"
|
||||
|
||||
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG %"Election Day%"
|
||||
REM Last Thu in Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
|
||||
REM Fri Nov [Week_4+1] SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
|
||||
|
||||
REM Thu 22 Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
|
||||
|
||||
REM Fri 23 Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
|
||||
|
||||
REM Dec 24 MSG %"Christmas Eve%"
|
||||
OMIT Dec 25 MSG %"Christmas%" Day
|
||||
|
||||
@@ -61,3 +61,29 @@ 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)
|
||||
FSET subst_p(alt, d, t) iif(d == today()+1, "", "en")
|
||||
|
||||
# Localization of various astronomical events
|
||||
|
||||
# Perihelion
|
||||
SET earthseasons_Perihelion_str "Perihel"
|
||||
|
||||
# Vernal equinox
|
||||
SET earthseasons_EquinoxMar_str "Frühlingsanfang"
|
||||
|
||||
# Summer solstice
|
||||
SET earthseasons_SolsticeJun_str "Sommeranfang"
|
||||
|
||||
# Aphelion
|
||||
SET earthseasons_Aphelion_str "Aphel"
|
||||
|
||||
# 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"
|
||||
|
||||
201
man/remind.1.in
201
man/remind.1.in
@@ -410,7 +410,7 @@ information.
|
||||
.SH REMINDER FILES
|
||||
.PP
|
||||
\fBRemind\fR uses scripts to control its operation. You can use any
|
||||
text editor capable of creating plain ASCII files to create a
|
||||
text editor capable of creating plain-text files to create a
|
||||
\fBRemind\fR script. The commands inside a script can range from the
|
||||
very simple and almost immediately understandable:
|
||||
.PP
|
||||
@@ -1004,6 +1004,18 @@ also. See "The OMIT command" for more details.)
|
||||
By comparison, if we had used "\-\-1", the reminder would be triggered on
|
||||
the last day of the month, regardless of the \fBOMIT\fR.
|
||||
.PP
|
||||
If you locally omit weekdays but also have globally-omitted weekdays, then
|
||||
the list of ommitted weekdays is the union of the two. Consider this
|
||||
example:
|
||||
.PP
|
||||
.nf
|
||||
OMIT Sat Sun
|
||||
REM 15 OMIT Fri Sat MSG Whatever
|
||||
.fi
|
||||
.PP
|
||||
In the REM command, the effective list of omitted weekdays will
|
||||
be Friday, Saturday and Sunday.
|
||||
.PP
|
||||
.B COMPUTED LOCAL OMITS
|
||||
.PP
|
||||
The \fBOMITFUNC\fR phrase of the \fBREM\fR command allows you to
|
||||
@@ -1177,7 +1189,8 @@ tags; see their documentation for details.
|
||||
.PP
|
||||
The \fBTAG\fR keyword is followed by a tag consisting of up to
|
||||
48 characters. You can have as many TAG clauses as you like in
|
||||
a given REM statement.
|
||||
a given REM statement. A tag can contain any character except for
|
||||
whitespace and a comma.
|
||||
.PP
|
||||
If you supply the \fB\-y\fR option to \fBRemind\fR, then any
|
||||
reminder that lacks a \fBTAG\fR will have one synthesized. The
|
||||
@@ -1513,7 +1526,8 @@ Notes:
|
||||
o
|
||||
.B Remind
|
||||
normally prints a blank line after each reminder; if the last character
|
||||
of the body is "%", the blank line will not be printed.
|
||||
of the body is "%", the blank line will not be printed. You can globally
|
||||
suppress the extra blank lines by setting \fB$AddBlankLines\fR to 0.
|
||||
.TP
|
||||
o
|
||||
Substitutions a, b, c, e, f, g, h, i, j, k, l, u and v all are replaced
|
||||
@@ -1562,6 +1576,10 @@ In addition to being a keyword in the \fBREM\fR command,
|
||||
\fBOMIT\fR is a command in its own right. Its syntax is:
|
||||
.PP
|
||||
.RS
|
||||
\fBOMIT\fR \fIweekday\fR [\fIweekday\fR...]
|
||||
.PP
|
||||
or:
|
||||
.PP
|
||||
\fBOMIT\fR [\fIday\fR] \fImonth\fR [\fIyear\fR]
|
||||
.PP
|
||||
or:
|
||||
@@ -1575,6 +1593,7 @@ The \fBOMIT\fR command is used to "globally" omit certain days
|
||||
"\-\-" and "\+\+" forms. Some examples:
|
||||
.PP
|
||||
.nf
|
||||
OMIT Saturday Sunday
|
||||
OMIT 1 Jan
|
||||
OMIT 7 Sep 1992
|
||||
OMIT 15 Jan THROUGH 14 Feb
|
||||
@@ -1584,8 +1603,13 @@ The \fBOMIT\fR command is used to "globally" omit certain days
|
||||
OMIT Jun THROUGH July # Equivalent to OMIT Jun 1 THROUGH July 31
|
||||
.fi
|
||||
.PP
|
||||
The first example specifies a holiday that occurs on the same date each
|
||||
year - New Year's Day. The second example specifies a holiday that
|
||||
The first example omits every Saturday and Sunday. This is useful for
|
||||
reminders that shouldn't trigger on weekends.
|
||||
.PP
|
||||
The second example specifies a holiday that occurs on the same date each
|
||||
year - New Year's Day.
|
||||
.PP
|
||||
The third example specifies a holiday that
|
||||
changes each year - Labour Day. For these types of holidays, you
|
||||
must create an \fBOMIT\fR command for each year. (Later, in the
|
||||
description of expressions and some of the more advanced features of
|
||||
@@ -2251,6 +2275,16 @@ The following system variables are defined. Those marked
|
||||
"read-only" cannot be changed with the \fBSET\fR command.
|
||||
All system variables hold values of type \fBINT\fR, unless otherwise
|
||||
specified.
|
||||
.TP
|
||||
.B $AddBlankLines
|
||||
If set to 1 (the default), then \fBRemind\fR normally prints a blank
|
||||
line after the banner and each reminder. (This can be suppressed by
|
||||
ending the reminder or banner with a single percent sign.) If
|
||||
$AddBlankLines is set to 0, then Remind does not print the blank line.
|
||||
In this case, ending a reminder with % has no effect. If you \fIdo\fR
|
||||
want a blank line after a reminder, end it with \fB%_\fR to insert a
|
||||
newline.
|
||||
|
||||
.TP
|
||||
.B $CalcUTC
|
||||
If 1 (the default), then \fBRemind\fR uses C library functions
|
||||
@@ -2576,6 +2610,23 @@ Equivalent to \fBwkdaynum(today())\fR.
|
||||
.TP
|
||||
.B $Uy (read-only)
|
||||
Equivalent to \fByear(today())\fR.
|
||||
.TP
|
||||
.B $UseVTColors (read-only)
|
||||
Set to 1 if the \fB\-@\fR or \fB\-cc\fR options were used; 0 otherwise.
|
||||
.TP
|
||||
.B $UseBGVTColors (read-only)
|
||||
Set to 1 if the \fB\-@,,1\fR option was used; 0 otherwise.
|
||||
.TP
|
||||
.B $Use256Colors (read-only)
|
||||
Set to 1 if the \fB\-@1\fR option was used; 0 otherwise.
|
||||
.TP
|
||||
.B $UseTrueColors (read-only)
|
||||
Set to 1 if the \fB\-@2\fR option was used; 0 otherwise.
|
||||
.TP
|
||||
.B $TerminalBackground (read-only)
|
||||
Returns -1 if the terminal background color was not specified,
|
||||
0 if it was specified as dark with the \fB\-@,0\fR option or
|
||||
1 if it was specified as light with the \fB\-@,1\fR option.
|
||||
.PP
|
||||
Note: If any of the calendar modes are in effect, then the
|
||||
values of $Daemon, $DontFork, $DontTrigAts, $DontQueue, $HushMode,
|
||||
@@ -2638,6 +2689,60 @@ $TimeSep and $DateTimeSep when formatting its output. For example:
|
||||
.PP
|
||||
.RE
|
||||
.TP
|
||||
.B ansicolor(i_red, i_green, i_blue [,i_bg [,i_clamp]])
|
||||
Returns a \fBSTRING\fR that contains an ANSI escape sequence for changing
|
||||
the terminal text color. The parameters \fIred\fR, \fIgreen\fR and \fIblue\fR
|
||||
are integers from 0 to 255 specifying the value of the respective color
|
||||
component. As a special case, all three values can be -1, in which case
|
||||
the ANSI sequence "ESC[0m" is returned, which resets all text attributes
|
||||
to normal.
|
||||
.RS
|
||||
.PP
|
||||
The string returned by \fBansicolor\fR depends on the color mode that
|
||||
\fBRemind\fR is running in, as specified by the \fB\-@\fR option. If color
|
||||
mode is not enabled, then \fBansicolor\fR always returns the empty string.
|
||||
Otherwise, it returns the escape sequence that best approximates the color
|
||||
according to the \fB\-@\fR color mode.
|
||||
.PP
|
||||
The optional \fIbg\fR argument is either 0 or 1. If 0 (the default), then
|
||||
the foreground color is set. If 1, then the background color is set. Note
|
||||
that setting the background color only works in 256-color or true-color
|
||||
mode.
|
||||
.PP
|
||||
The optional \fIclamp\fR argument is either 0 or 1. If 0 (the default),
|
||||
then colors are not adjusted based on the terminal background color. If
|
||||
1, then \fBRemind\fR attempts to adjust dark or bright colors so they have
|
||||
enough contrast to be visible in the terminal.
|
||||
.PP
|
||||
The first three arguments may alternatively be specified as a string
|
||||
consisting of three space-separated numbers, as in this example: "128 128 0"
|
||||
.PP
|
||||
As a special case, \fBansicolor("")\fR is equivalent to
|
||||
\fBansicolor(-1,-1,-1)\fR and returns the ANSI sequence to reset all text
|
||||
attributes to normal.
|
||||
.PP
|
||||
Note that inserting ANSI color sequences in calendar mode \fIwill
|
||||
produce garbled results\fR. Therefore, we recommend defining
|
||||
functions such as the ones below that return the empty string in
|
||||
calendar mode:
|
||||
.PP
|
||||
.nf
|
||||
IF $CalMode
|
||||
FSET fg(r,g,b) ""
|
||||
FSET bg(r,g,b) ""
|
||||
ELSE
|
||||
FSET fg(r,g,b) ansicolor(r,g,b)
|
||||
FSET bg(r,g,b) ansicolor(r,g,b,1)
|
||||
ENDIF
|
||||
REM [fg(255,0,0)][bg(64,64,64)]Red on Gray[fg(-1,-1,-1)] in normal mode
|
||||
REM SPECIAL COLOR 0 255 0 Green in normal and calendar mode
|
||||
.fi
|
||||
.PP
|
||||
If you use the \fBansicolor\fR function, don't forget to reset the color
|
||||
back to normal with \fBansicolor(-1,-1,-1)\fR or subsequent reminders
|
||||
will continue to be colored.
|
||||
.RE
|
||||
.TP
|
||||
.B args(s_fname)
|
||||
Returns the number of arguments expected by the user-defined function
|
||||
\fIfname\fR, or \-1 if no such user-defined function exists. Note that
|
||||
@@ -2648,7 +2753,10 @@ available only in versions of \fBRemind\fR from 03.00.04 and up.
|
||||
.TP
|
||||
.B asc(s_string)
|
||||
Returns an \fBINT\fR that is the ASCII code of the first character
|
||||
in \fIstring\fR. As a special case, \fBasc("")\fR returns 0.
|
||||
in \fIstring\fR. As a special case, \fBasc("")\fR returns 0. For UTF-8
|
||||
strings, this will return the UTF-8 byte with which the string
|
||||
begins, which is not likely to be very useful (and may indeed be negative
|
||||
on machines where \fBchar\fR is a signed type.)
|
||||
.TP
|
||||
.B baseyr()
|
||||
Returns the "base year" that was compiled into \fBRemind\fR (normally
|
||||
@@ -2657,14 +2765,10 @@ Returns the "base year" that was compiled into \fBRemind\fR (normally
|
||||
.TP
|
||||
.B char(i_i1 [,i_i2...])
|
||||
This function can take any number of \fBINT\fR arguments. It returns
|
||||
a \fBSTRING\fR consisting of the characters specified by the arguments.
|
||||
Note that none of the arguments can be 0, unless there is only one
|
||||
a \fBSTRING\fR consisting of the bytes specified by the arguments.
|
||||
It is easy to create invalid UTF-8 sequences; \fBchar\fR does not check
|
||||
for this. Note that none of the arguments can be 0, unless there is only one
|
||||
argument. As a special case, \fBchar(0)\fR returns "".
|
||||
.PP
|
||||
.RS
|
||||
Note that because \fBRemind\fR does not support escaping of characters
|
||||
in strings, the only way to get a double-quote in a string is to use
|
||||
\fBchar(34)\fR.
|
||||
.RE
|
||||
.TP
|
||||
.B choose(i_index, x_arg1 [,x_arg2...])
|
||||
@@ -2723,6 +2827,22 @@ arguments are converted using the reverse of procedures described
|
||||
above. A \fBSTRING\fR \fIarg\fR is converted by parsing it as an
|
||||
integer.
|
||||
.RE
|
||||
.TP
|
||||
.B columns([s_arg])
|
||||
If called with no arguments, \fBcolumns()\fR behaves as follows:
|
||||
If standard output is a TTY, returns the width of the terminal in columns.
|
||||
If standard output is not a TTY, attempts to open "/dev/tty" to obtain
|
||||
the terminal size. If this fails, returns -1.
|
||||
.RS
|
||||
.PP
|
||||
If called with a single string argument, \fBcolumns(str)\fR returns
|
||||
the number of columns \fBstr\fR will occupy if printed to a terminal.
|
||||
ANSI color-changing sequences occupy zero columns whereas some Unicode
|
||||
characters occupy two columns. \fBcolumns(str)\fR takes all of that
|
||||
into account. Note that if Remind was compiled without Unicode support,
|
||||
\fBcolumns(str)\fR returns a type mismatch error.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B current()
|
||||
Returns the current date and time as a DATETIME object. This may be the
|
||||
@@ -2970,6 +3090,10 @@ 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.
|
||||
.TP
|
||||
.B localtoutc(q_datetime)
|
||||
Given a \fBDATETIME\fR object interpreted in the local time zone, return
|
||||
a \fBDATETIME\fR object that expresses the same time in UTC.
|
||||
.TP
|
||||
.B lower(s_string)
|
||||
Returns a \fBSTRING\fR with all upper-case characters in \fIstring\fR
|
||||
converted to lower-case.
|
||||
@@ -3241,6 +3365,11 @@ Returns the date as provided by the operating system. This is in contrast to
|
||||
\fBRemind\fR's concept of "today", which may be changed if it is running
|
||||
in calendar mode, or if a date has been supplied on the command line.
|
||||
.TP
|
||||
.B rows()
|
||||
If standard output is a TTY, returns the height of the terminal in rows.
|
||||
If standard output is not a TTY, attempts to open "/dev/tty" to obtain
|
||||
the terminal size. If this fails, returns -1.
|
||||
.TP
|
||||
.B sgn(i_num)
|
||||
Returns \-1 if \fInum\fR is negative, 1 if \fInum\fR is positive,
|
||||
and 0 if \fInum\fR is zero.
|
||||
@@ -3359,6 +3488,12 @@ Creates a \fBTIME\fR with the hour and minute components specified by
|
||||
Returns a \fBTIME\fR object representing the time portion of
|
||||
\fIdatetime\fR.
|
||||
.TP
|
||||
.B timezone([dq_datetime])
|
||||
Returns a string representing the local time zone name of the given
|
||||
\fBDATETIME\fR. If no argument is supplied, \fBRemind\fR uses the
|
||||
value of \fBcurrent()\fR. If a \fBDATE\fR rather than \fBDATETIME\fR
|
||||
is supplied, \fBRemind\fR uses a time part of 00:00.
|
||||
.TP
|
||||
.B today()
|
||||
Returns \fBRemind\fR's notion of "today." This may be the actual system
|
||||
date, or a date supplied on the command line, or the date of the
|
||||
@@ -3585,6 +3720,12 @@ returns "30 November 1994 AT 22:00" for EST, which is 5 hours behind UTC.
|
||||
The value for your time zone may differ.
|
||||
.RE
|
||||
.TP
|
||||
.B trigtags()
|
||||
Returns a comma-separated list of the TAGs associated with the most recent
|
||||
\fBREM\fR command that was triggered. Returns the empty string if there
|
||||
were no TAGs. If there are multiple tags, they are each separated by
|
||||
a single comma, not a comma and a space.
|
||||
.TP
|
||||
.B trigtime()
|
||||
Returns the time of the last \fBREM\fR command with an \fBAT\fR
|
||||
clause. If the last \fBREM\fR did not have an \fBAT\fR clause,
|
||||
@@ -3626,6 +3767,11 @@ values. Here is an example:
|
||||
Returns a \fBSTRING\fR with all lower-case characters in \fIstring\fR
|
||||
converted to upper-case.
|
||||
.TP
|
||||
.B utctolocal(q_datetime)
|
||||
Given a \fBDATETIME\fR object interpreted in UTC, return a
|
||||
\fBDATETIME\fR object that expresses the same time in the local time
|
||||
zone.
|
||||
.TP
|
||||
.B value(s_varname [,x_default])
|
||||
Returns the value of the specified variable. For example, value("X"+"Y")
|
||||
returns the value of variable XY, if it is defined. If XY is not defined,
|
||||
@@ -3639,7 +3785,7 @@ defined, and the value of XY if it is defined.
|
||||
.TP
|
||||
.B version()
|
||||
Returns a string specifying the version of \fBRemind\fR. For version
|
||||
03.00.04, returns "03.00.04". It is guaranteed that as new versions of
|
||||
@VERSION@, returns "@VERSION@". It is guaranteed that as new versions of
|
||||
\fBRemind\fR are released, the value returned by \fBversion()\fR will
|
||||
strictly increase, according to the rules for string ordering.
|
||||
.TP
|
||||
@@ -3972,13 +4118,13 @@ Notes:
|
||||
.TP
|
||||
o
|
||||
If you access a variable in \fIexpr\fR that is not in the list of arguments,
|
||||
the "global" value (if any) is used.
|
||||
the global value (if any) is used.
|
||||
.TP
|
||||
o
|
||||
Function and parameter names are significant only to 12 characters.
|
||||
Function and parameter names are significant to 64 characters.
|
||||
.TP
|
||||
o
|
||||
The \fBvalue()\fR function \fIalways\fR accesses the "global" value of a
|
||||
The \fBvalue()\fR function \fIalways\fR accesses the global value of a
|
||||
variable, even if it has the same name as an argument. For example:
|
||||
.RS
|
||||
.PP
|
||||
@@ -4887,17 +5033,17 @@ This function is passed a single integer, namely a day of the month from
|
||||
turn it into an ordinal number. In English, for example, the function
|
||||
might return "st", "nd", "rd" or "th", depending on \fId\fR.
|
||||
.TP
|
||||
.B subst_N(alt, date, time)
|
||||
.B subst_\fIN\fR\fB(alt, date, time)\fR
|
||||
This is actually a \fIfamily\fR of functions, where \fIN\fR is a letter
|
||||
or number. This function \fIcompletely overrides\fR the substitution
|
||||
sequence "%X". The three arguments are an integer \fIalt\fR which,
|
||||
sequence "%N". The three arguments are an integer \fIalt\fR which,
|
||||
if non-zero, indicates that the alternate-mode substitution sequence
|
||||
"%*X" was encountered; \fIdate\fR which is the trigger date of the
|
||||
"%*N" was encountered; \fIdate\fR which is the trigger date of the
|
||||
reminder and \fItime\fR which is the trigger time.
|
||||
.TP
|
||||
.B subst_Nx(alt, date, time)
|
||||
.B subst_\fIN\fR\fBx(alt, date, time)\fR
|
||||
Again, this is a \fIfamily\fR of functions. It is similar to the
|
||||
\fBsubst_N\fR family except it is only called if \fIdate\fR is two or
|
||||
\fBsubst_\fIN\fR family except it is only called if \fIdate\fR is two or
|
||||
more days away from \fItoday()\fR. This is useful if you don't want to
|
||||
override the "today" or "tomorrow" output for most substitution sequences.
|
||||
.PP
|
||||
@@ -4937,6 +5083,17 @@ as:
|
||||
FSET subst_bx(a,d,t) iif(d==today()+2, "the day after tomorrow", 0)
|
||||
.fi
|
||||
.PP
|
||||
You can define your own substitution sequences in addition to the built-in
|
||||
ones as follows: If you define a function named \fBsubst_\fIname\fB(alt, date, time)\fR, then the sequence \fB%{name}\fR calls the function with \fBalt\fR
|
||||
set to 0 and \fBdate\fR and \fRtime\fR to the trigger date and time,
|
||||
respectively. The \fB%{name}\fR sequence is replaced with whatever the
|
||||
function returns. The sequence \fB%*{name}\fR is similar, but calls
|
||||
the function with \fBalt\fR set to 1.
|
||||
.PP
|
||||
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 LANGUAGE PACKS
|
||||
.PP
|
||||
\fBRemind\fR ships with a number of language packs, which are simply reminder
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#define _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include "config.h"
|
||||
#include "custom.h"
|
||||
|
||||
@@ -313,7 +313,7 @@ Backgroundize(int d)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UseBGVTChars) {
|
||||
if (!UseBGVTColors) {
|
||||
return;
|
||||
}
|
||||
if (bgcolor[d][0] < 0) {
|
||||
@@ -329,7 +329,7 @@ UnBackgroundize(int d)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UseBGVTChars) {
|
||||
if (!UseBGVTColors) {
|
||||
return;
|
||||
}
|
||||
if (bgcolor[d][0] < 0) {
|
||||
@@ -474,7 +474,7 @@ void PrintJSONKeyPairTime(char const *name, int t)
|
||||
}
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
static void PutWideChar(wchar_t const wc)
|
||||
void PutWideChar(wchar_t const wc)
|
||||
{
|
||||
char buf[MB_CUR_MAX+1];
|
||||
int len;
|
||||
@@ -699,7 +699,7 @@ InitMoonsAndShades(void)
|
||||
}
|
||||
|
||||
/* Clear SHADEs */
|
||||
if (UseBGVTChars) {
|
||||
if (UseBGVTColors) {
|
||||
for (i=0; i<=31; i++) {
|
||||
bgcolor[i][0] = -1;
|
||||
bgcolor[i][1] = -1;
|
||||
@@ -719,7 +719,7 @@ SetShadeEntry(int jul, char const *shade)
|
||||
int y, m, d;
|
||||
int r, g, b;
|
||||
/* Don't bother if we're not doing SHADE specials */
|
||||
if (!UseBGVTChars) {
|
||||
if (!UseBGVTColors) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1386,7 +1386,7 @@ static int WriteOneColLine(int col)
|
||||
int clamp = 1;
|
||||
int numwritten = 0;
|
||||
int d = ColToDay[col];
|
||||
if (d && UseBGVTChars && bgcolor[d][0] != -1) {
|
||||
if (d && UseBGVTColors && bgcolor[d][0] != -1) {
|
||||
clamp = 0;
|
||||
}
|
||||
/* Print as many characters as possible within the column */
|
||||
|
||||
15
src/dorem.c
15
src/dorem.c
@@ -96,9 +96,13 @@ int DoRem(ParsePtr p)
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
DBufFree(&buf);
|
||||
if (tok.type == T_Empty || tok.type == T_Comment) {
|
||||
r = OK;
|
||||
if (trig.addomit) {
|
||||
r = AddGlobalOmit(LastTriggerDate);
|
||||
}
|
||||
DBufFree(&buf);
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
return r;
|
||||
}
|
||||
if (tok.type != T_RemType || tok.val == SAT_TYPE) {
|
||||
DBufFree(&buf);
|
||||
@@ -470,7 +474,12 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
case T_Tag:
|
||||
r = ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
if (strchr(DBufValue(&buf), ',')) {
|
||||
DBufFree(&buf);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
AppendTag(&(trig->tags), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
break;
|
||||
|
||||
case T_Duration:
|
||||
@@ -936,8 +945,8 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
if (!DoSubstFromString(DBufValue(&Banner), &buf,
|
||||
JulianToday, NO_TIME) &&
|
||||
DBufLen(&buf)) {
|
||||
printf("%s\n", DBufValue(&buf));
|
||||
}
|
||||
printf("%s\n", DBufValue(&buf));
|
||||
}
|
||||
DBufFree(&buf);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
int d, m, y;
|
||||
int tim = tt->ttime;
|
||||
int h, min, hh, ch, cmin, chh;
|
||||
int i;
|
||||
char const *pm, *cpm;
|
||||
int tdiff, adiff, mdiff, hdiff;
|
||||
char const *mplu, *hplu, *when, *plu;
|
||||
@@ -190,8 +191,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
}
|
||||
if (c == '\n') continue;
|
||||
if (!c) {
|
||||
if (mode != CAL_MODE && mode != ADVANCE_MODE &&
|
||||
t->typ != RUN_TYPE && !MsgCommand) {
|
||||
if (AddBlankLines &&
|
||||
mode != CAL_MODE &&
|
||||
mode != ADVANCE_MODE &&
|
||||
t->typ != RUN_TYPE &&
|
||||
!MsgCommand) {
|
||||
if (DBufPutc(dbuf, '\n') != OK) return E_NO_MEM;
|
||||
}
|
||||
break;
|
||||
@@ -221,6 +225,45 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c == '{') {
|
||||
i = 0;
|
||||
ss = s + snprintf(s, sizeof(s), "subst_");
|
||||
while (1) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
if (c == '}' || !c) {
|
||||
break;
|
||||
}
|
||||
if (i < 64) {
|
||||
*ss++ = c;
|
||||
*ss = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (!c) {
|
||||
Wprint("Warning: Unterminated %{...} substitution sequence");
|
||||
}
|
||||
if (UserFuncExists(s) != 3) {
|
||||
continue;
|
||||
}
|
||||
snprintf(ss, sizeof(s) - (ss-s), "(%d,'%04d-%02d-%02d',%02d:%02d)",
|
||||
altmode ? 1 : 0, y, m+1, d, h, min);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
if (DBufPuts(dbuf, v.v.str) != OK) {
|
||||
DestroyValue(v);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
DestroyValue(v);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
done = 0;
|
||||
snprintf(uf, sizeof(uf), "subst_%c", c);
|
||||
if (UserFuncExists(uf) == 3) {
|
||||
|
||||
11
src/expr.c
11
src/expr.c
@@ -1244,10 +1244,10 @@ BuiltinFunc *FindFunc(char const *name, BuiltinFunc where[], int num)
|
||||
void PrintValue (Value *v, FILE *fp)
|
||||
{
|
||||
int y, m, d;
|
||||
char const *s;
|
||||
unsigned char const *s;
|
||||
|
||||
if (v->type == STR_TYPE) {
|
||||
s=v->v.str;
|
||||
s = (unsigned char const *) v->v.str;
|
||||
putc('"', fp);
|
||||
for (y=0; y<MAX_PRT_LEN && *s; y++) {
|
||||
switch(*s) {
|
||||
@@ -1260,7 +1260,12 @@ void PrintValue (Value *v, FILE *fp)
|
||||
case '\v': fprintf(ErrFp, "\\v"); break;
|
||||
case '"': fprintf(ErrFp, "\\\""); break;
|
||||
case '\\': fprintf(ErrFp, "\\\\"); break;
|
||||
default: putc(*s, ErrFp); break;
|
||||
default:
|
||||
if (*s < 32) {
|
||||
fprintf(ErrFp, "\\x%02x", (unsigned int) *s);
|
||||
} else {
|
||||
putc(*s, ErrFp); break;
|
||||
}
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
297
src/funcs.c
297
src/funcs.c
@@ -13,12 +13,19 @@
|
||||
#include "version.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -58,6 +65,7 @@ static int FADusk (func_info *);
|
||||
static int FAbs (func_info *);
|
||||
static int FAccess (func_info *);
|
||||
static int FAmpm (func_info *);
|
||||
static int FAnsicolor (func_info *);
|
||||
static int FTrig (func_info *);
|
||||
static int FIsAny (func_info *);
|
||||
static int FArgs (func_info *);
|
||||
@@ -66,6 +74,7 @@ static int FBaseyr (func_info *);
|
||||
static int FChar (func_info *);
|
||||
static int FChoose (func_info *);
|
||||
static int FCoerce (func_info *);
|
||||
static int FColumns (func_info *);
|
||||
static int FCurrent (func_info *);
|
||||
static int FDate (func_info *);
|
||||
static int FDateTime (func_info *);
|
||||
@@ -94,6 +103,7 @@ static int FIsdst (func_info *);
|
||||
static int FIsleap (func_info *);
|
||||
static int FIsomitted (func_info *);
|
||||
static int FLanguage (func_info *);
|
||||
static int FLocalToUTC (func_info *);
|
||||
static int FLower (func_info *);
|
||||
static int FMax (func_info *);
|
||||
static int FMin (func_info *);
|
||||
@@ -118,6 +128,7 @@ static int FPsshade (func_info *);
|
||||
static int FRealCurrent (func_info *);
|
||||
static int FRealnow (func_info *);
|
||||
static int FRealtoday (func_info *);
|
||||
static int FRows (func_info *);
|
||||
static int FSgn (func_info *);
|
||||
static int FShell (func_info *);
|
||||
static int FSlide (func_info *);
|
||||
@@ -128,6 +139,7 @@ static int FSunrise (func_info *);
|
||||
static int FSunset (func_info *);
|
||||
static int FTime (func_info *);
|
||||
static int FTimepart (func_info *);
|
||||
static int FTimezone (func_info *);
|
||||
static int FToday (func_info *);
|
||||
static int FTrig (func_info *);
|
||||
static int FTrigback (func_info *);
|
||||
@@ -140,6 +152,7 @@ static int FTrigeventstart (func_info *);
|
||||
static int FTrigfrom (func_info *);
|
||||
static int FTrigger (func_info *);
|
||||
static int FTrigpriority (func_info *);
|
||||
static int FTrigtags (func_info *);
|
||||
static int FTrigrep (func_info *);
|
||||
static int FTrigscanfrom (func_info *);
|
||||
static int FTrigtime (func_info *);
|
||||
@@ -150,6 +163,7 @@ static int FTrigvalid (func_info *);
|
||||
static int FTypeof (func_info *);
|
||||
static int FTzconvert (func_info *);
|
||||
static int FUpper (func_info *);
|
||||
static int FUTCToLocal (func_info *);
|
||||
static int FValue (func_info *);
|
||||
static int FVersion (func_info *);
|
||||
static int FWeekno (func_info *);
|
||||
@@ -161,6 +175,7 @@ static int FShellescape (func_info *);
|
||||
static int CleanUpAfterFunc (func_info *);
|
||||
static int CheckArgs (BuiltinFunc *f, int nargs);
|
||||
static int SunStuff (int rise, double cosz, int jul);
|
||||
static int tz_set_tz (char const *tz);
|
||||
|
||||
/* "Overload" the struct Operator definition */
|
||||
#define NO_MAX 127
|
||||
@@ -214,12 +229,14 @@ BuiltinFunc Func[] = {
|
||||
{ "adawn", 0, 1, 0, FADawn},
|
||||
{ "adusk", 0, 1, 0, FADusk},
|
||||
{ "ampm", 1, 3, 1, FAmpm },
|
||||
{ "ansicolor", 1, 5, 1, FAnsicolor },
|
||||
{ "args", 1, 1, 0, FArgs },
|
||||
{ "asc", 1, 1, 1, FAsc },
|
||||
{ "baseyr", 0, 0, 1, FBaseyr },
|
||||
{ "char", 1, NO_MAX, 1, FChar },
|
||||
{ "choose", 2, NO_MAX, 1, FChoose },
|
||||
{ "coerce", 2, 2, 1, FCoerce },
|
||||
{ "columns", 0, 1, 0, FColumns },
|
||||
{ "current", 0, 0, 0, FCurrent },
|
||||
{ "date", 3, 3, 1, FDate },
|
||||
{ "datepart", 1, 1, 1, FDatepart },
|
||||
@@ -249,6 +266,7 @@ BuiltinFunc Func[] = {
|
||||
{ "isleap", 1, 1, 1, FIsleap },
|
||||
{ "isomitted", 1, 1, 0, FIsomitted },
|
||||
{ "language", 0, 0, 1, FLanguage },
|
||||
{ "localtoutc", 1, 1, 1, FLocalToUTC },
|
||||
{ "lower", 1, 1, 1, FLower },
|
||||
{ "max", 1, NO_MAX, 1, FMax },
|
||||
{ "min", 1, NO_MAX, 1, FMin },
|
||||
@@ -273,6 +291,7 @@ BuiltinFunc Func[] = {
|
||||
{ "realcurrent", 0, 0, 0, FRealCurrent},
|
||||
{ "realnow", 0, 0, 0, FRealnow},
|
||||
{ "realtoday", 0, 0, 0, FRealtoday },
|
||||
{ "rows", 0, 0, 0, FRows },
|
||||
{ "sgn", 1, 1, 1, FSgn },
|
||||
{ "shell", 1, 2, 0, FShell },
|
||||
{ "shellescape", 1, 1, 1, FShellescape },
|
||||
@@ -284,6 +303,7 @@ BuiltinFunc Func[] = {
|
||||
{ "sunset", 0, 1, 0, FSunset },
|
||||
{ "time", 2, 2, 1, FTime },
|
||||
{ "timepart", 1, 1, 1, FTimepart },
|
||||
{ "timezone", 0, 1, 1, FTimezone },
|
||||
{ "today", 0, 0, 0, FToday },
|
||||
{ "trig", 0, NO_MAX, 0, FTrig },
|
||||
{ "trigback", 0, 0, 0, FTrigback },
|
||||
@@ -298,6 +318,7 @@ BuiltinFunc Func[] = {
|
||||
{ "trigpriority", 0, 0, 0, FTrigpriority },
|
||||
{ "trigrep", 0, 0, 0, FTrigrep },
|
||||
{ "trigscanfrom", 0, 0, 0, FTrigscanfrom },
|
||||
{ "trigtags", 0, 0, 0, FTrigtags },
|
||||
{ "trigtime", 0, 0, 0, FTrigtime },
|
||||
{ "trigtimedelta",0, 0, 0, FTrigtimedelta },
|
||||
{ "trigtimerep", 0, 0, 0, FTrigtimerep },
|
||||
@@ -306,6 +327,7 @@ BuiltinFunc Func[] = {
|
||||
{ "typeof", 1, 1, 1, FTypeof },
|
||||
{ "tzconvert", 2, 3, 0, FTzconvert },
|
||||
{ "upper", 1, 1, 1, FUpper },
|
||||
{ "utctolocal", 1, 1, 1, FUTCToLocal },
|
||||
{ "value", 1, 2, 0, FValue },
|
||||
{ "version", 0, 0, 1, FVersion },
|
||||
{ "weekno", 0, 3, 1, FWeekno },
|
||||
@@ -904,6 +926,87 @@ static int FSgn(func_info *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int parse_color_helper(char const *str, int *r, int *g, int *b)
|
||||
{
|
||||
if (!*str) {
|
||||
/* Empty string means "reset to normal" */
|
||||
*r = -1;
|
||||
*g = -1;
|
||||
*b = -1;
|
||||
return OK;
|
||||
}
|
||||
if (sscanf(str, "%d %d %d", r, g, b) != 3) {
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FAnsicolor - return an ANSI terminal color sequence */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int FAnsicolor(func_info *info)
|
||||
{
|
||||
int r=0, g=0, b=0, bg=0, clamp=1;
|
||||
int status = 0;
|
||||
int index = 0;
|
||||
bg = 0;
|
||||
clamp = 1;
|
||||
|
||||
/* If first arg is a string: Parse out the colors */
|
||||
if (ARG(0).type == STR_TYPE) {
|
||||
/* If first arg is a string: Parse out the colors */
|
||||
status = parse_color_helper(ARGSTR(0), &r, &g, &b);
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
index = 1;
|
||||
} else if (ARG(0).type == INT_TYPE) {
|
||||
/* Must be at least three arguments */
|
||||
if (Nargs < 3) return E_2FEW_ARGS;
|
||||
ASSERT_TYPE(1, INT_TYPE);
|
||||
ASSERT_TYPE(2, INT_TYPE);
|
||||
r = ARGV(0);
|
||||
g = ARGV(1);
|
||||
b = ARGV(2);
|
||||
index = 3;
|
||||
}
|
||||
if (r < -1 || g < -1 || b < -1) return E_2LOW;
|
||||
if (r > 255 || g > 255 || b > 255) return E_2HIGH;
|
||||
/* If any is -1, then all must be -1 */
|
||||
if (r == -1 || g == -1 || b == -1) {
|
||||
if (r != -1 || g != -1 || b != -1) {
|
||||
return E_2LOW;
|
||||
}
|
||||
}
|
||||
if (Nargs > index) {
|
||||
ASSERT_TYPE(index, INT_TYPE);
|
||||
if (ARGV(index) < 0) return E_2LOW;
|
||||
if (ARGV(index) > 1) return E_2HIGH;
|
||||
bg = ARGV(index);
|
||||
index++;
|
||||
if (Nargs > index) {
|
||||
ASSERT_TYPE(index, INT_TYPE);
|
||||
if (ARGV(index) < 0) return E_2LOW;
|
||||
if (ARGV(index) > 1) return E_2HIGH;
|
||||
clamp = ARGV(index);
|
||||
}
|
||||
}
|
||||
|
||||
/* All righ! We have our parameters; now return the string */
|
||||
if (!UseVTColors) {
|
||||
/* Not using any colors: Empty strin */
|
||||
return RetStrVal("", info);
|
||||
}
|
||||
|
||||
if (r < 0) {
|
||||
/* Return ANSI "reset to normal" string */
|
||||
return RetStrVal(Decolorize(), info);
|
||||
}
|
||||
return RetStrVal(Colorize(r, g, b, bg, clamp), info);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FAmpm - return a time as a string with "AM" or "PM" suffix */
|
||||
@@ -1469,6 +1572,11 @@ static int FTrigrep(func_info *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FTrigtags(func_info *info)
|
||||
{
|
||||
return RetStrVal(DBufValue(&(LastTrigger.tags)), info);
|
||||
}
|
||||
|
||||
static int FTrigpriority(func_info *info)
|
||||
{
|
||||
RetVal.type = INT_TYPE;
|
||||
@@ -2225,6 +2333,115 @@ static int FTimeStuff(int wantmins, func_info *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FTimezone(func_info *info)
|
||||
{
|
||||
int yr, mon, day, hr, min, jul, now;
|
||||
struct tm local, *withzone;
|
||||
time_t t;
|
||||
char buf[64];
|
||||
|
||||
if (Nargs == 0) {
|
||||
jul = JulianToday;
|
||||
now = (SystemTime(0) / 60);
|
||||
} else {
|
||||
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
|
||||
jul = DATEPART(ARG(0));
|
||||
if (HASTIME(ARG(0))) {
|
||||
now = TIMEPART(ARG(0));
|
||||
} else {
|
||||
now = 0;
|
||||
}
|
||||
}
|
||||
FromJulian(jul, &yr, &mon, &day);
|
||||
hr = now / 60;
|
||||
min = now % 60;
|
||||
|
||||
memset(&local, 0, sizeof(local));
|
||||
local.tm_sec = 0;
|
||||
local.tm_min = min;
|
||||
local.tm_hour = hr;
|
||||
local.tm_mday = day;
|
||||
local.tm_mon = mon;
|
||||
local.tm_year = yr-1900;
|
||||
local.tm_isdst = -1;
|
||||
|
||||
t = mktime(&local);
|
||||
withzone = localtime(&t);
|
||||
buf[0] = 0;
|
||||
strftime(buf, sizeof(buf), "%Z", withzone);
|
||||
return RetStrVal(buf, info);
|
||||
}
|
||||
|
||||
static int FLocalToUTC(func_info *info)
|
||||
{
|
||||
int yr, mon, day, hr, min, jul;
|
||||
time_t loc_t;
|
||||
struct tm local, *utc;
|
||||
|
||||
ASSERT_TYPE(0, DATETIME_TYPE);
|
||||
|
||||
FromJulian(DATEPART(ARG(0)), &yr, &mon, &day);
|
||||
hr = TIMEPART(ARG(0))/60;
|
||||
min = TIMEPART(ARG(0))%60;
|
||||
|
||||
memset(&local, 0, sizeof(local));
|
||||
local.tm_sec = 0;
|
||||
local.tm_min = min;
|
||||
local.tm_hour = hr;
|
||||
local.tm_mday = day;
|
||||
local.tm_mon = mon;
|
||||
local.tm_year = yr-1900;
|
||||
local.tm_isdst = -1;
|
||||
loc_t = mktime(&local);
|
||||
if (loc_t == -1) {
|
||||
return E_MKTIME_PROBLEM;
|
||||
}
|
||||
|
||||
utc = gmtime(&loc_t);
|
||||
jul = Julian(utc->tm_year+1900, utc->tm_mon, utc->tm_mday);
|
||||
RetVal.type = DATETIME_TYPE;
|
||||
RETVAL = MINUTES_PER_DAY * jul + utc->tm_hour*60 + utc->tm_min;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FUTCToLocal(func_info *info)
|
||||
{
|
||||
int yr, mon, day, hr, min, jul;
|
||||
time_t utc_t;
|
||||
struct tm *local, utc;
|
||||
char const *old_tz;
|
||||
|
||||
ASSERT_TYPE(0, DATETIME_TYPE);
|
||||
FromJulian(DATEPART(ARG(0)), &yr, &mon, &day);
|
||||
hr = TIMEPART(ARG(0))/60;
|
||||
min = TIMEPART(ARG(0))%60;
|
||||
|
||||
old_tz = getenv("TZ");
|
||||
|
||||
tz_set_tz("UTC");
|
||||
|
||||
memset(&utc, 0, sizeof(utc));
|
||||
utc.tm_sec = 0;
|
||||
utc.tm_min = min;
|
||||
utc.tm_hour = hr;
|
||||
utc.tm_mday = day;
|
||||
utc.tm_mon = mon;
|
||||
utc.tm_year = yr-1900;
|
||||
utc.tm_isdst = 0;
|
||||
utc_t = mktime(&utc);
|
||||
tz_set_tz(old_tz);
|
||||
|
||||
if (utc_t == -1) {
|
||||
return E_MKTIME_PROBLEM;
|
||||
}
|
||||
|
||||
local = localtime(&utc_t);
|
||||
jul = Julian(local->tm_year+1900, local->tm_mon, local->tm_mday);
|
||||
RetVal.type = DATETIME_TYPE;
|
||||
RETVAL = MINUTES_PER_DAY * jul + local->tm_hour*60 + local->tm_min;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* Sunrise and sunset functions. */
|
||||
@@ -2926,11 +3143,11 @@ FSlide(func_info *info)
|
||||
}
|
||||
|
||||
/* If ALL weekdays are omitted... barf! */
|
||||
if (localomit == 127 && amt != 0) return E_2MANY_LOCALOMIT;
|
||||
if ((WeekdayOmits | localomit) == 0x7F && amt != 0) return E_2MANY_LOCALOMIT;
|
||||
if (amt > 0) {
|
||||
while(amt) {
|
||||
d++;
|
||||
r = IsOmitted(d, localomit, NULL,&omit);
|
||||
r = IsOmitted(d, localomit, NULL, &omit);
|
||||
if (r) return r;
|
||||
if (!omit) amt--;
|
||||
}
|
||||
@@ -2938,7 +3155,7 @@ FSlide(func_info *info)
|
||||
while(amt) {
|
||||
d--;
|
||||
if (d < 0) return E_DATE_OVER;
|
||||
r = IsOmitted(d, localomit, NULL,&omit);
|
||||
r = IsOmitted(d, localomit, NULL, &omit);
|
||||
if (r) return r;
|
||||
if (!omit) amt++;
|
||||
}
|
||||
@@ -3165,3 +3382,77 @@ FTrig(func_info *info)
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int
|
||||
rows_or_cols(func_info *info, int want_rows)
|
||||
{
|
||||
struct winsize w;
|
||||
int fd = STDOUT_FILENO;
|
||||
|
||||
RetVal.type = INT_TYPE;
|
||||
if (!isatty(fd)) {
|
||||
fd = open("/dev/tty", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
RETVAL = -1;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
if (ioctl(fd, TIOCGWINSZ, &w) == 0) {
|
||||
if (want_rows) RETVAL = w.ws_row;
|
||||
else RETVAL = w.ws_col;
|
||||
} else {
|
||||
RETVAL = -1;
|
||||
}
|
||||
if (fd != STDOUT_FILENO) {
|
||||
close(fd);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FRows(func_info *info)
|
||||
{
|
||||
return rows_or_cols(info, 1);
|
||||
}
|
||||
static int FColumns(func_info *info)
|
||||
{
|
||||
#ifdef REM_USE_WCHAR
|
||||
size_t len;
|
||||
wchar_t *buf, *s;
|
||||
int width;
|
||||
#endif
|
||||
if (Nargs == 0) {
|
||||
return rows_or_cols(info, 0);
|
||||
}
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
#ifdef REM_USE_WCHAR
|
||||
len = mbstowcs(NULL, ARGSTR(0), 0);
|
||||
if (len == (size_t) -1) return E_NO_MEM;
|
||||
buf = calloc(len+1, sizeof(wchar_t));
|
||||
if (!buf) return E_NO_MEM;
|
||||
(void) mbstowcs(buf, ARGSTR(0), len+1);
|
||||
|
||||
s = buf;
|
||||
width = 0;
|
||||
while (*s) {
|
||||
if (*s == 0x1B && *(s+1) == '[') {
|
||||
/* Skip escape sequences */
|
||||
s += 2;
|
||||
while (*s && (*s < 0x40 || *s > 0x7E)) {
|
||||
s++;
|
||||
}
|
||||
if (*s) {
|
||||
s++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
width += wcwidth(*s);
|
||||
s++;
|
||||
}
|
||||
free(buf);
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = width;
|
||||
return OK;
|
||||
#else
|
||||
return E_BAD_TYPE;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ EXTERN INIT( int DoSimpleCalendar, 0);
|
||||
EXTERN INIT( int DoSimpleCalDelta, 0);
|
||||
EXTERN INIT( int DoPrefixLineNo, 0);
|
||||
EXTERN INIT( int MondayFirst, 0);
|
||||
EXTERN INIT( int AddBlankLines, 1);
|
||||
EXTERN INIT( int Iterations, 1);
|
||||
EXTERN INIT( int PsCal, 0);
|
||||
EXTERN INIT( int CalWidth, 80);
|
||||
@@ -80,6 +81,7 @@ EXTERN INIT( long SysTime, -1L);
|
||||
EXTERN char const *InitialFile;
|
||||
EXTERN int FileAccessDate;
|
||||
|
||||
EXTERN INIT( int WeekdayOmits, 0);
|
||||
EXTERN INIT( int DontSuppressQuoteMarkers, 0);
|
||||
EXTERN INIT( int DontFork, 0);
|
||||
EXTERN INIT( int DontQueue, 0);
|
||||
@@ -117,7 +119,7 @@ EXTERN char const **ArgV;
|
||||
EXTERN INIT( int CalLines, CAL_LINES);
|
||||
EXTERN INIT( int CalPad, 1);
|
||||
EXTERN INIT( int UseVTChars, 0);
|
||||
EXTERN INIT( int UseBGVTChars, 0);
|
||||
EXTERN INIT( int UseBGVTColors, 0);
|
||||
EXTERN INIT( int UseUTF8Chars, 0);
|
||||
EXTERN INIT( int UseVTColors, 0);
|
||||
EXTERN INIT( int Use256Colors, 0);
|
||||
|
||||
@@ -279,7 +279,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
argv[0]);
|
||||
x = 0;
|
||||
}
|
||||
UseBGVTChars = x;
|
||||
UseBGVTColors = x;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#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 */
|
||||
#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
|
||||
|
||||
176
src/main.c
176
src/main.c
@@ -10,6 +10,7 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
@@ -36,6 +37,10 @@
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef REM_USE_WCHAR
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
@@ -68,6 +73,7 @@ int main(int argc, char *argv[])
|
||||
ArgV = (char const **) argv;
|
||||
|
||||
InitRemind(argc, (char const **) argv);
|
||||
DBufInit(&(LastTrigger.tags));
|
||||
ClearLastTriggers();
|
||||
|
||||
if (DoCalendar || (DoSimpleCalendar && (!NextMode || PsCal))) {
|
||||
@@ -1184,6 +1190,8 @@ int CalcMinsFromUTC(int jul, int tim, int *mins, int *isdst)
|
||||
local.tm_sec = 0;
|
||||
local.tm_min = tim % 60;
|
||||
local.tm_hour = tim / 60;
|
||||
|
||||
|
||||
local.tm_mday = day;
|
||||
local.tm_mon = mon;
|
||||
local.tm_year = yr-1900;
|
||||
@@ -1212,6 +1220,144 @@ int CalcMinsFromUTC(int jul, int tim, int *mins, int *isdst)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char const *OutputEscapeSequences(char const *s, int print)
|
||||
{
|
||||
while (*s == 0x1B && *(s+1) == '[') {
|
||||
if (print) putchar(*s);
|
||||
s++;
|
||||
if (print) putchar(*s);
|
||||
s++;
|
||||
while (*s && (*s < 0x40 || *s > 0x7E)) {
|
||||
if (print) putchar(*s);
|
||||
s++;
|
||||
}
|
||||
if (*s) {
|
||||
if (print) putchar(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
#define ISWBLANK(c) (iswspace(c) && (c) != '\n')
|
||||
static wchar_t const *OutputEscapeSequencesWS(wchar_t const *s, int print)
|
||||
{
|
||||
while (*s == 0x1B && *(s+1) == '[') {
|
||||
if (print) PutWideChar(*s);
|
||||
s++;
|
||||
if (print) PutWideChar(*s);
|
||||
s++;
|
||||
while (*s && (*s < 0x40 || *s > 0x7E)) {
|
||||
if (print) PutWideChar(*s);
|
||||
s++;
|
||||
}
|
||||
if (*s) {
|
||||
if (print) PutWideChar(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
FillParagraphWCAux(wchar_t const *s)
|
||||
{
|
||||
int line = 0;
|
||||
int i, j;
|
||||
int doublespace = 1;
|
||||
int pendspace;
|
||||
int len;
|
||||
wchar_t const *t;
|
||||
|
||||
int roomleft;
|
||||
/* Start formatting */
|
||||
while(1) {
|
||||
|
||||
/* If it's a carriage return, output it and start new paragraph */
|
||||
if (*s == '\n') {
|
||||
putchar('\n');
|
||||
s++;
|
||||
line = 0;
|
||||
while(ISWBLANK(*s)) s++;
|
||||
continue;
|
||||
}
|
||||
if (!*s) {
|
||||
return;
|
||||
}
|
||||
/* Over here, we're at the beginning of a line. Emit the correct
|
||||
number of spaces */
|
||||
j = line ? SubsIndent : FirstIndent;
|
||||
for (i=0; i<j; i++) {
|
||||
putchar(' ');
|
||||
}
|
||||
|
||||
/* Calculate the amount of room left on this line */
|
||||
roomleft = FormWidth - j;
|
||||
pendspace = 0;
|
||||
|
||||
/* Emit words until the next one won't fit */
|
||||
while(1) {
|
||||
while(ISWBLANK(*s)) s++;
|
||||
if (*s == '\n') break;
|
||||
while(1) {
|
||||
t = s;
|
||||
s = OutputEscapeSequencesWS(s, 1);
|
||||
if (s == t) break;
|
||||
while(ISWBLANK(*s)) s++;
|
||||
}
|
||||
t = s;
|
||||
len = 0;
|
||||
while(*s && !iswspace(*s)) {
|
||||
if (*s == 0x1B && *(s+1) == '[') {
|
||||
s = OutputEscapeSequencesWS(s, 0);
|
||||
continue;
|
||||
}
|
||||
len += wcwidth(*s);
|
||||
s++;
|
||||
}
|
||||
if (s == t) {
|
||||
return;
|
||||
}
|
||||
if (!pendspace || len+pendspace <= roomleft) {
|
||||
for (i=0; i<pendspace; i++) {
|
||||
putchar(' ');
|
||||
}
|
||||
while(t < s) {
|
||||
PutWideChar(*t);
|
||||
if (strchr(EndSent, *t)) doublespace = 2;
|
||||
else if (!strchr(EndSentIg, *t)) doublespace = 1;
|
||||
t++;
|
||||
}
|
||||
} else {
|
||||
s = t;
|
||||
putchar('\n');
|
||||
line++;
|
||||
break;
|
||||
}
|
||||
roomleft -= len+doublespace;
|
||||
pendspace = doublespace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
FillParagraphWC(char const *s)
|
||||
{
|
||||
size_t len;
|
||||
wchar_t *buf;
|
||||
|
||||
len = mbstowcs(NULL, s, 0);
|
||||
if (len == (size_t) -1) return E_NO_MEM;
|
||||
buf = calloc(len+1, sizeof(wchar_t));
|
||||
if (!buf) return E_NO_MEM;
|
||||
(void) mbstowcs(buf, s, len+1);
|
||||
FillParagraphWCAux(buf);
|
||||
free(buf);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FillParagraph */
|
||||
@@ -1238,11 +1384,17 @@ void FillParagraph(char const *s)
|
||||
char const *t;
|
||||
|
||||
int roomleft;
|
||||
|
||||
if (!s || !*s) return;
|
||||
|
||||
/* Skip leading spaces */
|
||||
while(ISBLANK(*s)) s++;
|
||||
if (!*s) return;
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (FillParagraphWC(s) == OK) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Start formatting */
|
||||
while(1) {
|
||||
@@ -1273,10 +1425,23 @@ void FillParagraph(char const *s)
|
||||
while(1) {
|
||||
while(ISBLANK(*s)) s++;
|
||||
if (*s == '\n') break;
|
||||
while(1) {
|
||||
t = s;
|
||||
s = OutputEscapeSequences(s, 1);
|
||||
if (s == t) break;
|
||||
while(ISBLANK(*s)) s++;
|
||||
}
|
||||
t = s;
|
||||
while(*s && !isspace(*s)) s++;
|
||||
len = s - t;
|
||||
if (!len) {
|
||||
len = 0;
|
||||
while(*s && !isspace(*s)) {
|
||||
if (*s == 0x1B && *(s+1) == '[') {
|
||||
s = OutputEscapeSequences(s, 0);
|
||||
continue;
|
||||
}
|
||||
s++;
|
||||
len++;
|
||||
}
|
||||
if (s == t) {
|
||||
return;
|
||||
}
|
||||
if (!pendspace || len+pendspace <= roomleft) {
|
||||
@@ -1422,6 +1587,7 @@ ClearLastTriggers(void)
|
||||
LastTrigger.warn[0] = 0;
|
||||
LastTrigger.omitfunc[0] = 0;
|
||||
LastTrigger.passthru[0] = 0;
|
||||
DBufFree(&(LastTrigger.tags));
|
||||
|
||||
LastTimeTrig.ttime = NO_TIME;
|
||||
LastTimeTrig.delta = NO_DELTA;
|
||||
@@ -1442,8 +1608,10 @@ SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigt
|
||||
void
|
||||
SaveLastTrigger(Trigger const *t)
|
||||
{
|
||||
DBufFree(&(LastTrigger.tags));
|
||||
memcpy(&LastTrigger, t, sizeof(LastTrigger));
|
||||
DBufInit(&(LastTrigger.tags));
|
||||
DBufPuts(&(LastTrigger.tags), DBufValue(&(t->tags)));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
46
src/omit.c
46
src/omit.c
@@ -28,6 +28,8 @@ static void InsertIntoSortedArray (int *array, int num, int key);
|
||||
static int FullOmitArray[MAX_FULL_OMITS];
|
||||
static int PartialOmitArray[MAX_PARTIAL_OMITS];
|
||||
|
||||
/* WeekdayOmits is declared in global.h */
|
||||
|
||||
/* How many of each omit types do we have? */
|
||||
static int NumFullOmits, NumPartialOmits;
|
||||
|
||||
@@ -37,6 +39,7 @@ typedef struct omitcontext {
|
||||
int numfull, numpart;
|
||||
int *fullsave;
|
||||
int *partsave;
|
||||
int weekdaysave;
|
||||
} OmitContext;
|
||||
|
||||
/* The stack of saved omit contexts */
|
||||
@@ -52,6 +55,7 @@ static OmitContext *SavedOmitContexts = NULL;
|
||||
int ClearGlobalOmits(void)
|
||||
{
|
||||
NumFullOmits = NumPartialOmits = 0;
|
||||
WeekdayOmits = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -113,6 +117,7 @@ int PushOmitContext(ParsePtr p)
|
||||
|
||||
context->numfull = NumFullOmits;
|
||||
context->numpart = NumPartialOmits;
|
||||
context->weekdaysave = WeekdayOmits;
|
||||
context->fullsave = malloc(NumFullOmits * sizeof(int));
|
||||
if (NumFullOmits && !context->fullsave) {
|
||||
free(context);
|
||||
@@ -154,6 +159,7 @@ int PopOmitContext(ParsePtr p)
|
||||
if (!c) return E_POP_NO_PUSH;
|
||||
NumFullOmits = c->numfull;
|
||||
NumPartialOmits = c->numpart;
|
||||
WeekdayOmits = c->weekdaysave;
|
||||
|
||||
/* Copy the context over */
|
||||
for (i=0; i<NumFullOmits; i++)
|
||||
@@ -213,6 +219,12 @@ int IsOmitted(int jul, int localomit, char const *omitfunc, int *omit)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Is it omitted because of global weekday omits? */
|
||||
if (WeekdayOmits & (1 << (jul % 7))) {
|
||||
*omit = 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Is it omitted because of fully-specified omits? */
|
||||
if (BexistsIntArray(FullOmitArray, NumFullOmits, jul)) {
|
||||
*omit = 1;
|
||||
@@ -289,6 +301,7 @@ int DoOmit(ParsePtr p)
|
||||
int syndrome;
|
||||
int not_first_token = -1;
|
||||
int start, end, tmp;
|
||||
int wd = 0;
|
||||
|
||||
int mc, dc;
|
||||
|
||||
@@ -301,9 +314,15 @@ int DoOmit(ParsePtr p)
|
||||
if ( (r=ParseToken(p, &buf)) ) return r;
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
switch (tok.type) {
|
||||
case T_Dumpvars:
|
||||
if (not_first_token) return E_PARSE_ERR;
|
||||
case T_WkDay:
|
||||
DBufFree(&buf);
|
||||
if (wd & (1 << tok.val)) return E_WD_TWICE;
|
||||
wd |= (1 << tok.val);
|
||||
break;
|
||||
|
||||
case T_Dumpvars:
|
||||
DBufFree(&buf);
|
||||
if (not_first_token) return E_PARSE_ERR;
|
||||
r = VerifyEoln(p);
|
||||
if (r != OK) return r;
|
||||
DumpOmits();
|
||||
@@ -341,6 +360,7 @@ int DoOmit(ParsePtr p)
|
||||
|
||||
case T_Through:
|
||||
DBufFree(&buf);
|
||||
if (wd) return E_PARSE_ERR;
|
||||
if (seen_through) return E_UNTIL_TWICE;
|
||||
seen_through = 1;
|
||||
break;
|
||||
@@ -363,6 +383,18 @@ int DoOmit(ParsePtr p)
|
||||
}
|
||||
}
|
||||
|
||||
if (wd) {
|
||||
if (y[0] != NO_YR || m[0] != NO_MON || d[0] != NO_DAY) {
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
if ((WeekdayOmits | wd) == 0x7F) {
|
||||
return E_2MANY_LOCALOMIT;
|
||||
}
|
||||
WeekdayOmits |= wd;
|
||||
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (!seen_through) {
|
||||
/* We must have at least a month */
|
||||
if (m[0] == NO_MON) return E_SPEC_MON;
|
||||
@@ -482,5 +514,15 @@ DumpOmits(void)
|
||||
printf("\t%02d%c%02d\n", m+1, DateSep, d);
|
||||
}
|
||||
}
|
||||
printf("Global Weekday OMITs:\n");
|
||||
if (WeekdayOmits == 0) {
|
||||
printf("\tNone.\n");
|
||||
} else {
|
||||
for (i=0; i<7; i++) {
|
||||
if (WeekdayOmits & (1<<i)) {
|
||||
printf("\t%s\n", EnglishDayName[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,3 +177,9 @@ void clear_callstack(void);
|
||||
int have_callstack(void);
|
||||
int print_callstack(FILE *fp);
|
||||
void pop_call(void);
|
||||
#ifdef REM_USE_WCHAR
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
void PutWideChar(wchar_t const wc);
|
||||
#endif
|
||||
|
||||
@@ -530,7 +530,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
*err = OK;
|
||||
|
||||
/* But check for obvious problems... */
|
||||
if (trig->localomit == 1 + 2 + 4 + 8 + 16 + 32 + 64) {
|
||||
if ((WeekdayOmits | trig->localomit) == 0x7F) {
|
||||
*err = E_2MANY_LOCALOMIT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -238,6 +238,6 @@ typedef struct {
|
||||
/* Pure JSON */
|
||||
#define PSCAL_LEVEL3 3
|
||||
|
||||
#define TERMINAL_BACKGROUND_UNKNOWN 0
|
||||
#define TERMINAL_BACKGROUND_DARK 1
|
||||
#define TERMINAL_BACKGROUND_LIGHT 2
|
||||
#define TERMINAL_BACKGROUND_UNKNOWN -1
|
||||
#define TERMINAL_BACKGROUND_DARK 0
|
||||
#define TERMINAL_BACKGROUND_LIGHT 1
|
||||
|
||||
@@ -776,6 +776,7 @@ typedef struct {
|
||||
/* All of the system variables sorted alphabetically */
|
||||
static SysVar SysVarArr[] = {
|
||||
/* name mod type value min/mal max validate*/
|
||||
{"AddBlankLines", 1, INT_TYPE, &AddBlankLines, 0, 1, NULL },
|
||||
{"Ago", 1, STR_TYPE, &DynamicAgo, 0, 0, NULL },
|
||||
{"Am", 1, STR_TYPE, &DynamicAm, 0, 0, NULL },
|
||||
{"And", 1, STR_TYPE, &DynamicAnd, 0, 0, NULL },
|
||||
@@ -854,6 +855,7 @@ static SysVar SysVarArr[] = {
|
||||
{"SysInclude", 0, STR_TYPE, &SysDir, 0, 0, NULL },
|
||||
{"T", 0, SPECIAL_TYPE, trig_date_func, 0, 0, NULL },
|
||||
{"Td", 0, SPECIAL_TYPE, trig_day_func, 0, 0, NULL },
|
||||
{"TerminalBackground", 0, INT_TYPE, &TerminalBackground, 0, 0, NULL },
|
||||
{"Thursday", 1, STR_TYPE, &DynamicDayName[3], 0, 0, NULL },
|
||||
{"TimeSep", 1, SPECIAL_TYPE, time_sep_func, 0, 0, NULL },
|
||||
{"Tm", 0, SPECIAL_TYPE, trig_mon_func, 0, 0, NULL },
|
||||
@@ -866,6 +868,10 @@ static SysVar SysVarArr[] = {
|
||||
{"Ud", 0, SPECIAL_TYPE, today_day_func, 0, 0, NULL },
|
||||
{"Um", 0, SPECIAL_TYPE, today_mon_func, 0, 0, NULL },
|
||||
{"UntimedFirst", 0, INT_TYPE, &UntimedBeforeTimed, 0, 0, NULL },
|
||||
{"Use256Colors", 0, INT_TYPE, &Use256Colors, 0, 0, NULL },
|
||||
{"UseBGVTColors", 0, INT_TYPE, &UseBGVTColors, 0, 0, NULL },
|
||||
{"UseTrueColors", 0, INT_TYPE, &UseTrueColors, 0, 0, NULL },
|
||||
{"UseVTColors", 0, INT_TYPE, &UseVTColors, 0, 0, NULL },
|
||||
{"Uw", 0, SPECIAL_TYPE, today_wday_func, 0, 0, NULL },
|
||||
{"Uy", 0, SPECIAL_TYPE, today_year_func, 0, 0, NULL },
|
||||
{"Was", 1, STR_TYPE, &DynamicWas, 0, 0, NULL },
|
||||
|
||||
49
tests/ansicolors.rem
Normal file
49
tests/ansicolors.rem
Normal file
@@ -0,0 +1,49 @@
|
||||
BANNER %
|
||||
MSG TerminalBackground is: [$TerminalBackground]%
|
||||
MSG UseVTColors is: [$UseVTColors]%
|
||||
MSG Use256Colors is: [$Use256Colors]%
|
||||
MSG UseTrueColors is: [$UseTrueColors]%
|
||||
MSG UseBGVTColors is: [$UseBGVTColors]%
|
||||
set n ansicolor("")]
|
||||
MSG This is [ansicolor(0,255,0)]green[n], [ansicolor("255 0 0")]red[n] and [ansicolor("0 0 255")]blue[n] text.%
|
||||
MSG This is [ansicolor(0,0,0)][ansicolor(0,255,0,1)]black text on a green background[n]%
|
||||
MSG This is [ansicolor(0,0,0,0,1)]clamped black text[n]%
|
||||
MSG This is [ansicolor(255,255,255,0,1)]clamped white text[n]
|
||||
|
||||
FLUSH
|
||||
|
||||
# Test that MSF ignores ansi color sequences
|
||||
set r ansicolor(255, 0, 0)
|
||||
set g ansicolor(0, 255, 0)
|
||||
set b ansicolor(0, 0, 255)
|
||||
set n ansicolor("")
|
||||
|
||||
|
||||
REM MSF Here we have a formatted reminder. It should be word-wrapped nicely and neatly by Remind. Although it is very long and unwieldy, the MSF keyword will wrap it so it's pleasantly readable.%_Here we have a formatted reminder. It should be word-wrapped nicely and neatly by Remind. Although it is very long and unwieldy, the MSF keyword will wrap it so it's pleasantly readable.
|
||||
|
||||
# Should have exactly the same word breaks
|
||||
REM MSF [r]Here [g]we [b]have [r]a [g]formatted [b]reminder. [r]It [g]should[b] be [r]word-wrapped[g] nicely [b]and [r]neatly [g]by Remind. [b]Although [r]it [g]is [b]very [r]long [g]and [b]u[r]n[g]w[b]i[r]e[g]l[b]d[r]y[g], [r]the [g]MSF [b]keyword [r]will [r] [g] [b] [g]wrap [b]it [r]so [g]it's [b]pleasantly [r]readable.[n]%_[r]Here [g]we [b]have [r]a [g]formatted [b]reminder. [r]It [g]should[b] be [r]word-wrapped[g] nicely [b]and [r]neatly [g]by Remind. [b]Although [r]it [g]is [b]very [r]long [g]and [b]u[r]n[g]w[b]i[r]e[g]l[b]d[r]y[g], [r]the [g]MSF [b]keyword [r]will [r] [g] [b] [g]wrap [b]it [r]so [g]it's [b]pleasantly [r]readable.[n]
|
||||
|
||||
REM MSF Εδώ έχουμε μια μορφοποιημένη υπενθύμιση. Θα πρέπει να είναι τυλιγμένο με λέξεις όμορφα και τακτοποιημένα από το Remind. Αν και είναι πολύ μακρύ και δυσκίνητο, η λέξη-κλειδί των ΓΧΣ θα το τυλίξει έτσι ώστε να είναι ευχάριστα ευανάγνωστο. 🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅%_Εδώ έχουμε μια μορφοποιημένη υπενθύμιση. Θα πρέπει να είναι τυλιγμένο με λέξεις όμορφα και τακτοποιημένα από το Remind. Αν και είναι πολύ μακρύ και δυσκίνητο, η λέξη-κλειδί των ΓΧΣ θα το τυλίξει έτσι ώστε να είναι ευχάριστα ευανάγνωστο. 🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅
|
||||
|
||||
REM MSF [r]Εδώ [g]έχουμε [b]μια [r]μ[g]ο[b]ρ[r]φοποιημένη[n] υπενθύμιση. Θα πρέπει να είναι τυλιγμένο με λέξεις όμορφα και τακτοποιημένα από το Remind. Αν και είναι πολύ μακρύ και δυσκίνητο, η λέξη-κλειδί των ΓΧΣ θα το τυλίξει έτσι ώστε να είναι ευχάριστα ευανάγνωστο. 🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅%_[r]Εδώ [g]έχουμε [b]μια [r]μ[g]ο[b]ρ[r]φοποιημένη[n] υπενθύμιση. Θα πρέπει να είναι τυλιγμένο με λέξεις όμορφα και τακτοποιημένα από το Remind. Αν και είναι πολύ μακρύ και δυσκίνητο, η λέξη-κλειδί των ΓΧΣ θα το τυλίξει έτσι ώστε να είναι ευχάριστα ευανάγνωστο. 🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅
|
||||
FLUSH
|
||||
|
||||
# Some invalid combos
|
||||
set a ansicolor(1)
|
||||
set a ansicolor(-1, 0, 0)
|
||||
set a ansicolor(42, 42, 256)
|
||||
set a ansicolor("foo")
|
||||
set a ansicolor("1 1")
|
||||
set a ansicolor("-1 -1 0");
|
||||
set a ansicolor("256 1 1");
|
||||
set a ansicolor(128, 128, 128, 2)
|
||||
set a ansicolor(128, 128, 128, -1)
|
||||
set a ansicolor(128, 128, 128, 0, 2)
|
||||
set a ansicolor(128, 128, 128, 0, -1)
|
||||
|
||||
set a ansicolor(128,0,0)
|
||||
|
||||
set str a + "foo: 🌅"
|
||||
set w columns(str)
|
||||
MSG Width of [str] is: [w]
|
||||
5
tests/blanks.rem
Normal file
5
tests/blanks.rem
Normal file
@@ -0,0 +1,5 @@
|
||||
MSG $AddBlankLines=[$AddBlankLines]%_
|
||||
MSG Hello
|
||||
MSG Hi
|
||||
MSF How are you?
|
||||
MSG OK
|
||||
@@ -26,11 +26,30 @@ if test `id -u` = 0 ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If we're already in a utf-8 locale, do
|
||||
# nothing; otherwise, set LC_ALL
|
||||
OK=0
|
||||
if echo $LC_ALL | grep -i utf-8 > /dev/null 2>&1 ; then
|
||||
OK=1
|
||||
fi
|
||||
|
||||
if test -z "$LC_ALL" ; then
|
||||
if echo $LANG | grep -i utf-8 > /dev/null 2>&1 ; then
|
||||
export LC_ALL="$LANG"
|
||||
OK=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$OK" = 0 ; then
|
||||
export LC_ALL=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
fi
|
||||
|
||||
chmod 000 include_dir/04cantread.rem
|
||||
TEST_GETENV="foo bar baz" ; export TEST_GETENV
|
||||
echo "Test 1" > ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -e -dxte ../tests/test.rem 16 feb 1991 >> ../tests/test.out 2>&1
|
||||
../src/remind -e -dxte ../tests/test.rem 16 feb 1991 12:13 >> ../tests/test.out 2>&1
|
||||
echo "" >> ../tests/test.out
|
||||
echo "Test 2" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
@@ -76,6 +95,32 @@ echo 'REM Mon 31 2021 MSG [$T]' | ../src/remind -dt - 31 dec 2021 >> ../tests/te
|
||||
echo "Color Test" >> ../tests/test.out
|
||||
../src/remind -ccl ../tests/colors.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "ANSI Color Test" >> ../tests/test.out
|
||||
../src/remind ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
|
||||
echo '$AddBlankLines test' >> ../tests/test.out
|
||||
../src/remind ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind '-i$AddBlankLines=1' ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind '-i$AddBlankLines=0' ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "MON WKDAY DAY across year test" >> ../tests/test.out
|
||||
echo 'REM Mon 29 Dec MSG x' | ../src/remind -dt - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
|
||||
@@ -344,31 +389,15 @@ rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
|
||||
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
|
||||
EOF
|
||||
|
||||
# If we're already in a utf-8 locale, do
|
||||
# nothing; otherwise, set LC_ALL
|
||||
OK=0
|
||||
if echo $LC_ALL | grep -i utf-8 > /dev/null 2>&1 ; then
|
||||
OK=1
|
||||
fi
|
||||
|
||||
if test -z "$LC_ALL" ; then
|
||||
if echo $LANG | grep -i utf-8 > /dev/null 2>&1 ; then
|
||||
export LC_ALL="$LANG"
|
||||
OK=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$OK" = 0 ; then
|
||||
export LC_ALL=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
fi
|
||||
|
||||
../src/remind -w128 -c ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
../src/remind -c ../tests/test-addomit.rem 1 Sep 2021 >> ../tests/test.out
|
||||
|
||||
../src/remind -cu ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
../src/remind -cu '-i$SuppressLRM=1' ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
|
||||
TZ=America/Toronto ../src/remind -dxe ../tests/tz.rem >> ../tests/test.out 2>&1
|
||||
TZ=Europe/Berlin ../src/remind -dxe ../tests/tz.rem >> ../tests/test.out 2>&1
|
||||
|
||||
# Remove references to SysInclude, which is build-specific
|
||||
grep -F -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out
|
||||
cmp -s ../tests/test.out ../tests/test.cmp
|
||||
|
||||
2716
tests/test.cmp
2716
tests/test.cmp
File diff suppressed because it is too large
Load Diff
@@ -146,8 +146,14 @@ REM Tue 28 Jan 1992 MSG Tue 28 Jan 1992
|
||||
|
||||
# Try some Backs
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun
|
||||
REM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun
|
||||
REM 1 -1 OMIT thu MSG 1 -1 OMIT Thu
|
||||
REM 1 --1 OMIT thu MSG 1 --1 OMIT Thu
|
||||
|
||||
PUSH-OMIT-CONTEXT
|
||||
OMIT Thu
|
||||
REM 1 -1 MSG 1 -1 OMIT Thu globally
|
||||
REM 1 --1 MSG 1 --1 OMIT Thu globally
|
||||
POP-OMIT-CONTEXT
|
||||
|
||||
OMIT 28 Feb
|
||||
REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun (28 Feb omitted)
|
||||
@@ -227,6 +233,15 @@ REM Wed UNTIL 1991-01-01 MSG Expired
|
||||
REM Wed SCANFROM 1991-02-26 MSG SCANFROM
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
|
||||
# Test trigtags and tag parsing
|
||||
|
||||
REM tag ill,egal MSG bad tag
|
||||
REM MSG The tags are: [trigtags()]
|
||||
REM TAG foo The tags are: [trigtags()]
|
||||
REM TAG foo TAG bar TAG quux TAG znort TAG cabbage The tags are: [trigtags()]
|
||||
REM MSG The tags are: [trigtags()]
|
||||
|
||||
# Test ADDOMIT
|
||||
|
||||
REM Mon 15 Feb ADDOMIT MSG Family Day
|
||||
@@ -819,6 +834,17 @@ OMIT 2000-01-01 THROUGH 2020-12-31
|
||||
|
||||
OMIT Dec 5 2029 through Dec 4 2029
|
||||
|
||||
# Test MSF
|
||||
|
||||
REM MSF This is a very long reminder. It should be wrapped. Will it be wrapped? I'm interested to see it it's wrapped. Please wrap this, ok?
|
||||
|
||||
# Custom substitution sequences
|
||||
FSET subst_custom(a, d, t) "Custom: a=" + a + "; d=" + d + "; t=" + t
|
||||
|
||||
REM MSG Here: %{custom}
|
||||
REM MSG There: %*{custom}
|
||||
REM MSG Bad: %{custom
|
||||
|
||||
# Don't want Remind to queue reminders
|
||||
EXIT
|
||||
|
||||
|
||||
30
tests/tz.rem
Normal file
30
tests/tz.rem
Normal file
@@ -0,0 +1,30 @@
|
||||
# Test conversion between local time and UTC
|
||||
|
||||
set a localtoutc('2022-01-01@12:00')
|
||||
set a localtoutc('2022-03-13@02:59')
|
||||
set a localtoutc('2022-03-13@03:00')
|
||||
set a localtoutc('2022-03-13@03:01')
|
||||
set a localtoutc('2022-06-01@12:00')
|
||||
set a localtoutc('2022-11-06@01:59')
|
||||
set a localtoutc('2022-11-06@02:00')
|
||||
set a localtoutc('2022-11-06@02:01')
|
||||
set a localtoutc('2022-12-01@12:00')
|
||||
|
||||
set b utctolocal('2022-01-01@17:00')
|
||||
set b utctolocal('2022-03-13@06:00')
|
||||
set b utctolocal('2022-03-13@06:01')
|
||||
set b utctolocal('2022-03-13@06:59')
|
||||
set b utctolocal('2022-03-13@07:00')
|
||||
set b utctolocal('2022-03-13@07:01')
|
||||
set b utctolocal('2022-03-13@07:59')
|
||||
set b utctolocal('2022-06-01@16:00')
|
||||
set b utctolocal('2022-11-06@05:59')
|
||||
set b utctolocal('2022-11-06@06:00')
|
||||
set b utctolocal('2022-11-06@06:01')
|
||||
set b utctolocal('2022-11-06@06:59')
|
||||
set b utctolocal('2022-11-06@07:00')
|
||||
set b utctolocal('2022-11-06@07:01')
|
||||
set b utctolocal('2022-12-01@17:00')
|
||||
|
||||
set c timezone('2022-07-01')
|
||||
set c timezone('2022-12-01')
|
||||
Reference in New Issue
Block a user