Compare commits

..

64 Commits

Author SHA1 Message Date
Dianne Skoll
f547c1e714 Update release notes. 2022-09-26 12:08:49 -04:00
Dianne Skoll
f8ea124b1f Add OS error message if we can't open file. 2022-09-24 10:57:32 -04:00
Dianne Skoll
820e2aec4d Document that "-wcol" also sets $FormWidth 2022-09-24 10:48:43 -04:00
Dianne Skoll
01ce6b2d8f Clamp min CalWidth at 71. 2022-09-24 10:40:04 -04:00
Dianne Skoll
b39e0eab7e Get rid of ComputeCalWidth - it's obsolete 2022-09-24 10:39:05 -04:00
Dianne Skoll
d6fc451d74 Refactor code. 2022-09-24 10:34:05 -04:00
Dianne Skoll
ac91556fc2 Make '-wn' initialize FormWidth as well. 2022-09-24 10:29:23 -04:00
Dianne Skoll
ccf639efe6 Make '-wt' accept FormWidth as well as CalWidth 2022-09-24 10:27:19 -04:00
Dianne Skoll
a8aa3b328b Add "-wt" option to size calendar according to terminal window. 2022-09-24 10:26:06 -04:00
Dianne Skoll
74a3b3e73d Yet more doc fixes. 2022-09-24 09:56:16 -04:00
Dianne Skoll
c0e68b57ea Fix pod 2022-09-24 09:53:11 -04:00
Dianne Skoll
0ad4ea26eb Properly set version and release date in man pages for rem2html and rem2pdf 2022-09-24 09:50:15 -04:00
Dianne Skoll
ea7aafaf5e Refactor code to reduce copy-paste coding. 2022-09-24 09:16:50 -04:00
Dianne Skoll
18043080ba Properly detect missing quote after escape sequence. 2022-09-23 20:42:57 -04:00
Dianne Skoll
7cd8cf3a77 Dump strings more sensibly in PrintValue. 2022-09-23 19:10:36 -04:00
Dianne Skoll
21da52ec36 Update unit tests. 2022-09-23 19:05:51 -04:00
Dianne Skoll
7a0c164843 Dump strings more sensibly. 2022-09-23 19:05:26 -04:00
Dianne Skoll
5cf4961f19 More clarification. 2022-09-23 08:38:00 -04:00
Dianne Skoll
68926d145b Fix innacuracy in how string constants are described. 2022-09-23 08:32:12 -04:00
Dianne Skoll
fdc3e4d23d Update WHATSNEW 2022-09-22 15:00:30 -04:00
Dianne Skoll
f179c837e1 Update regression tests. 2022-09-22 08:56:58 -04:00
Dianne Skoll
740bb44956 Don't consider IFTRIG true if we could not compute a trigger date.
Bug noted by Gunther Reißig
2022-09-22 08:48:19 -04:00
Dianne Skoll
5b953769fe Obey $DefaultColor in a SATISFY-type reminder.
Bug found by Gunther Reißig.
2022-09-22 08:37:37 -04:00
Dianne Skoll
1ae00ce778 No need to reset NumTriggered. 2022-09-21 19:11:30 -04:00
Dianne Skoll
a01e05c1db Fix bug introduced in commit 98c5bf511e:
Don't print a banner when issuing a queued reminder.
2022-09-21 18:17:25 -04:00
Dianne Skoll
63fb3e99f3 Make "test" depend on "all" rather than just "remind" 2022-09-19 13:56:11 -04:00
Dianne Skoll
6cf7f5d2d8 Merge branch 'add_ci' into 'master'
Add ci

See merge request dskoll/remind!2
2022-09-19 17:54:45 +00:00
Jochen Sprickerhof
316eb43303 Add Gitlab CI 2022-09-19 19:51:15 +02:00
Dianne Skoll
576112a39a Merge branch 'drop_fgrep' into 'master'
Replace deprecated fgrep by grep

See merge request dskoll/remind!1
2022-09-19 17:50:03 +00:00
Jochen Sprickerhof
6607223abb Replace deprecated fgrep by grep -F 2022-09-19 19:49:20 +02:00
Dianne Skoll
9e85b1932d Mark today in bold iff "remind -c" color output is enabled. 2022-09-19 11:32:10 -04:00
Dianne Skoll
4ba7f5b1f2 Only embolden today if stdout is a tty 2022-09-19 10:44:21 -04:00
Dianne Skoll
fc93ae890a Allow NULL pointers to be supplied to FromJulian if we are not interested in specific values 2022-09-17 23:04:34 -04:00
Dianne Skoll
8051d01945 Document change in Makefile install/install-stripped targets. 2022-09-17 09:07:27 -04:00
Dianne Skoll
63430c59f7 Make "make install" *not* strip debugging symbols; add "make install-stripped" target to strip them. 2022-09-17 09:04:45 -04:00
Dianne Skoll
c646bfc63f Make today's date bold in -c mode. 2022-09-16 21:01:10 -04:00
Dianne Skoll
58dea8f69b Support greyscale version of SHADE. 2022-09-16 20:44:59 -04:00
Dianne Skoll
f1c82dcb37 Update docs; bump version to 04.01.00. 2022-09-16 19:54:04 -04:00
Dianne Skoll
b984b66819 Put a space before the "***" representing today in -c mode. 2022-09-16 16:15:01 -04:00
Dianne Skoll
44bdae302b Allow 2 (=TERMINAL_BACKGROUND_UNKNOWN) for m in -@n,m,b 2022-09-16 15:58:51 -04:00
Dianne Skoll
8eb6b250fb Add support for the WEEK speical. 2022-09-16 15:08:53 -04:00
Dianne Skoll
d838c41bf2 Add tests for stdout() function. 2022-09-16 14:14:06 -04:00
Dianne Skoll
f9dbf36496 Don't backgroundize the row with day numbers. 2022-09-16 13:53:33 -04:00
Dianne Skoll
fe1427db28 Finalize support for SPECIAL SHADE in "remind -c" 2022-09-16 13:50:23 -04:00
Dianne Skoll
2621ad5604 Tweak calendar column-to-day handling. 2022-09-16 13:43:20 -04:00
Dianne Skoll
efecf2e1ea Make "remind -c" optionally support the SPECIAL SHADE 2022-09-16 11:41:18 -04:00
Dianne Skoll
8666e6357e Start working on support for SHADE in remind -c output. 2022-09-16 08:42:20 -04:00
Dianne Skoll
ae7069c9cb Gotta use the right sscanf format. :( 2022-09-15 18:43:58 -04:00
Dianne Skoll
0c6ab3e607 Properly parse args to MOON special 2022-09-15 18:37:46 -04:00
Dianne Skoll
17d6a60c0a Fix moon-phase-in-terminal printing and add tests. 2022-09-15 18:23:03 -04:00
Dianne Skoll
e3e0a541dc Print moon phases in terminal if terminal supports UTF-8 2022-09-15 18:18:05 -04:00
Jochen Sprickerhof
712aa08fbc make test depend on all 2022-09-08 16:32:04 +02:00
Dianne Skoll
98c5bf511e Print banner prior to first MSG-type reminder. 2022-09-06 09:14:55 -04:00
Dianne Skoll
1f9281628f Add home page to rem2pdf.1 and rem2html.1 2022-08-27 11:21:24 -04:00
Dianne Skoll
8fb15aed17 Do a sanity-check to make sure we pick up a release date. 2022-08-27 10:26:51 -04:00
Dianne Skoll
a24c3a8542 Remove generated man pages when running "make clean" 2022-08-27 10:24:29 -04:00
Dianne Skoll
8f8059e3f3 Generate man files from *.in versions to include release date and version number. 2022-08-27 10:22:31 -04:00
Dianne Skoll
24bb462199 Rename *.1 to *.1.in 2022-08-27 10:14:16 -04:00
Dianne Skoll
38e914f171 Get release date. 2022-08-27 10:06:02 -04:00
Dianne Skoll
4a02c54e8d Add home page to man pages. 2022-08-26 16:33:39 -04:00
Dianne Skoll
5fe169438a Document behavior of DO and filedir() with respect to symbolic links. 2022-08-22 09:19:30 -04:00
Dianne Skoll
a7ef6e851a Fix error in Makefile - remove duplicate clean: definition 2022-08-21 10:24:30 -04:00
Dianne Skoll
4d57b9d0aa Pass CFLAGS at link-time
Thanks to Zoltan Puskas for suggestion.
2022-08-21 10:23:16 -04:00
Dianne Skoll
5a7452d9f6 Add install-nostripped top-level target.
Thanks to Zoltan Puskas for suggestion.
2022-08-21 10:22:58 -04:00
30 changed files with 1433 additions and 794 deletions

6
.gitignore vendored
View File

@@ -10,6 +10,10 @@ autom4te.cache
blib/
config.log
config.status
man/rem.1
man/rem2ps.1
man/remind.1
man/tkremind.1
pm_to_blib
rem2html/Makefile
rem2html/rem2html.1
@@ -17,6 +21,7 @@ rem2pdf/Makefile.PL
rem2pdf/Makefile.old
rem2pdf/Makefile.top
rem2pdf/bin/rem2pdf
set-irc-topic
src/*.tar.gz*
src/Makefile
src/config.h
@@ -26,4 +31,3 @@ src/test-*.out
src/version.h
tests/test.out
www/Makefile
set-irc-topic

13
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,13 @@
tests:
image: 'debian:stable-slim'
before_script:
- apt update && apt-get -y install gcc make
- useradd --create-home testuser
- chown -R testuser .
- chmod -R go-w .
script:
- LANG=C.UTF-8 su testuser -c 'make test'
artifacts:
when: always
paths:
- tests/test.out

View File

@@ -12,21 +12,34 @@ all: src/Makefile
@$(MAKE) -C rem2pdf -f Makefile.top
install:
@echo ""
@echo "*********************"
@echo "* *"
@echo "* Installing REMIND *"
@echo "* *"
@echo "*********************"
@echo "**********************************"
@echo "* *"
@echo "* Installing REMIND (unstripped) *"
@echo "* *"
@echo "**********************************"
@echo ""
@$(MAKE) -C src install
@$(MAKE) -C rem2html install
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
clean:
find . -name '*~' -exec rm {} \;
-rm man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1
-$(MAKE) -C src clean
-$(MAKE) -C rem2pdf clean
test:
install-stripped:
@echo ""
@echo "********************************"
@echo "* *"
@echo "* Installing REMIND (stripped) *"
@echo "* *"
@echo "**********************************"
@echo ""
@$(MAKE) -C src install-stripped
@$(MAKE) -C rem2html install
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
test: all
@$(MAKE) -C src -s test
distclean: clean

18
configure vendored
View File

@@ -622,6 +622,7 @@ ac_includes_default="\
ac_header_list=
ac_subst_vars='LTLIBOBJS
LIBOBJS
RELEASE_DATE
PERLARTIFACTS
VERSION
EGREP
@@ -3994,6 +3995,14 @@ else
PERLARTIFACTS='NO_PACKLIST=1 NO_PERLLOCAL=1'
fi
RELEASE_DATE=`grep '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]' docs/WHATSNEW | head -n 1 | awk '{print $NF}'`
# Sanity-check release date
echo "$RELEASE_DATE" | grep '^....-..-..$' > /dev/null 2>&1
if test "$?" != 0 ; then
echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!"
exit 1
fi
for ac_func in setenv unsetenv glob mbstowcs setlocale initgroups
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
@@ -4006,11 +4015,12 @@ _ACEOF
fi
done
VERSION=04.00.03
VERSION=04.01.00
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf"
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -4710,6 +4720,10 @@ do
"rem2pdf/Makefile.PL") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.PL" ;;
"rem2pdf/Makefile.top") CONFIG_FILES="$CONFIG_FILES rem2pdf/Makefile.top" ;;
"rem2pdf/bin/rem2pdf") CONFIG_FILES="$CONFIG_FILES rem2pdf/bin/rem2pdf" ;;
"man/rem.1") CONFIG_FILES="$CONFIG_FILES man/rem.1" ;;
"man/rem2ps.1") CONFIG_FILES="$CONFIG_FILES man/rem2ps.1" ;;
"man/remind.1") CONFIG_FILES="$CONFIG_FILES man/remind.1" ;;
"man/tkremind.1") CONFIG_FILES="$CONFIG_FILES man/tkremind.1" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac

View File

@@ -64,10 +64,19 @@ else
PERLARTIFACTS='NO_PACKLIST=1 NO_PERLLOCAL=1'
fi
RELEASE_DATE=`grep '[[0-9]][[0-9]][[0-9]][[0-9]]-[[0-9]][[0-9]]-[[0-9]][[0-9]]' docs/WHATSNEW | head -n 1 | awk '{print $NF}'`
# Sanity-check release date
echo "$RELEASE_DATE" | grep '^....-..-..$' > /dev/null 2>&1
if test "$?" != 0 ; then
echo "*** COULD NOT DETERMINE RELEASE DATE: docs/WHATSNEW is incorrect!"
exit 1
fi
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups)
VERSION=04.00.03
VERSION=04.01.00
AC_SUBST(VERSION)
AC_SUBST(PERL)
AC_SUBST(PERLARTIFACTS)
AC_OUTPUT(src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf)
AC_SUBST(RELEASE_DATE)
AC_OUTPUT(src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf man/rem.1 man/rem2ps.1 man/remind.1 man/tkremind.1)
chmod a+x rem2pdf/bin/rem2pdf

View File

@@ -1,5 +1,62 @@
CHANGES TO REMIND
* VERSION 4.1 Patch 0 - 2022-09-25
- NEW FEATURE: remind: "remind -c" now supports the MOON special, printing
the moon phases in the calendar if the locale supports UTF-8 encoding.
- NEW FEATURE: remind: "remind -c" now supports the SHADE special. Works
best with the 256-color extended XTerm palette or 24-bit true-color
terminal escape sequences.
- NEW FEATURE: remind: "remind -c" now supports the WEEK special.
- NEW FEATURE: remind: The new "stdout()" function returns a string describing
where stdout is going. Examples of return values are "TTY" if remind's
output is going to terminal, "FILE" if it's redirected to a plain file,
or "PIPE" if it's going to a pipe. See the man page for all the details.
- NEW FEATURE: Add the "-wt" option to set the calendar width to the terminal
width even if standard output is a pipe. Useful for situations like this:
remind -wt -c .reminders | less -R
- CHANGE: "make install" now no longer strips debugging symbols from the
remind and rem2ps executables. Use "make install-stripped" if you want
them stripped.
- CHANGE: remind: "remind -c" highlights today's date in bold, if
colors are enabled.
- CHANGE: Dump string values with control characters escaped.
- DOCUMENTATION FIX: Document behavior of DO and filedir() with respect
to symbolic links.
- DOCUMENTATION FIX: Add home page link to man pages. Suggested by Ian! D.
Allen.
- DOCUMENTATION FIX: Make date in man pages actually be the release date.
Include Remind version in man pages. Also suggested by Ian! D. Allen.
- 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.
- BUG FIX: If the first REM command to trigger was a RUN command, the banner
would not print. This has been fixed.
- BUG FIX: replace deprecated 'fgrep' with 'grep -F' (Jochen Sprickerhof)
- 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.
- BUG FIX: Don't consider IFTRIG true if we could not compute a trigger date.
Bug noted by Gunther Reißig
* VERSION 4.0 Patch 3 - 2022-08-16
- IMPROVEMENT: remind: add plain_body and calendar_body JSON keys in -pp...
@@ -12,7 +69,7 @@ CHANGES TO REMIND
* VERSION 4.0 Patch 2 - 2022-08-02
- IMPROVEMENT: remind: Allow more forms of OMIT as per Ian D. Allen!'s request:
- IMPROVEMENT: remind: Allow more forms of OMIT as per Ian! D. Allen's request:
OMIT Month [THROUGH Month]
OMIT Day Month [THROUGH Day Month]
@@ -1214,7 +1271,7 @@ CHANGES TO REMIND
- Made parser _very_ forgiving -- the type of reminder now defaults
to MSG. This lets you have lines in the reminder file like this:
Feb 9, 1998 Meeting with Joe.
Feb 9, 1998 Meeting with Joe.
But I don't recommend abusing it. It's mostly to ease migration from
UNIX calendar(1) files.
@@ -1805,7 +1862,7 @@ CHANGES TO REMIND
- Removed identifiers in the C source beginning with "_" to conform
to ANSI practice.
- Fixed a bug in the -u option which resulted in environment variables
SHELL and USER not being set correctly. Also made -u set the LOGNAME
environment variable.
@@ -1878,7 +1935,7 @@ CHANGES TO REMIND
- Fixed all the source files to include "config.h" first.
- Changed the way triggers are calculated so that trigger dates are
- Changed the way triggers are calculated so that trigger dates are
always valid if year, month and day are specified, and there is no
UNTIL clause. See MAN page section "DETAILS ABOUT TRIGVALID()."
@@ -2020,6 +2077,3 @@ CHANGES TO REMIND
* Version 1.0
- never publicly released.

View File

@@ -1,4 +1,4 @@
.TH REM 1 "14 March 2022"
.TH REM 1 "@RELEASE_DATE@" "User Commands" "VERSION @VERSION@"
.UC 4
.SH NAME
rem \- Invoke Remind with a default filename
@@ -16,5 +16,7 @@ the filename $HOME/.reminders
.PP
.SH AUTHOR
Remind was written by Dianne Skoll <dianne@skoll.ca>
.SH HOME PAGE
https://dianne.skoll.ca/projects/remind/
.SH SEE ALSO
\fBremind\fR

View File

@@ -1,4 +1,4 @@
.TH REM2PS 1 "14 March 2022"
.TH REM2PS 1 "@RELEASE_DATE@" "User Commands" "VERSION @VERSION@"
.UC 4
.SH NAME
rem2ps \- draw a PostScript calendar from Remind output
@@ -686,6 +686,8 @@ resulting PostScript output will probably not work.
You should ensure that the values you supply for margin widths are sensible.
If they are too big for the media size, \fBRem2ps\fR will not complain,
but again, the PostScript output will probably not work.
.SH HOME PAGE
https://dianne.skoll.ca/projects/remind/
.SH SEE ALSO
\fBremind\fR, \fBrem2pdf\fR, \fBrem2html\fR, \fBtkremind\fR.

View File

@@ -1,4 +1,4 @@
.TH REMIND 1 "14 March 2022"
.TH REMIND 1 "@RELEASE_DATE@" "User Commands" "VERSION @VERSION@"
.UC 4
.SH NAME
remind \- a sophisticated reminder service
@@ -78,18 +78,18 @@ display.
.B 'c'
causes \fBRemind\fR to use VT100 escape sequences to approximate
SPECIAL COLOR reminders. Note that this flag is kept for
backwards-compatibility; you should use the \fB\-@\fI[n][,m]\fR
backwards-compatibility; you should use the \fB\-@\fI[n][,m][,b]\fR
command-line option instead.
.RE
.TP
.B \-@\fR[\fIn\fR][,\fIm\fR]
Tells \fBRemind\fR to approximate SPECIAL COLOR reminders using VT100
escape sequences. The approximation is (of necessity) very
coarse, because the VT100 only has eight different color sequences,
each with one of two brightnesses. A color component greater than
64 is considered "on", and if any of the three color components is
greater than 128, the color is considered "bright".
.B \-@\fR[\fIn\fR][,\fIm\fR][,\fIb\fR]
Tells \fBRemind\fR to approximate SPECIAL COLOR and SHADE reminders
using VT100 escape sequences. The approximation is (of necessity)
very coarse, because the VT100 only has eight different color
sequences, each with one of two brightnesses. A color component
greater than 64 is considered "on", and if any of the three color
components is greater than 128, the color is considered "bright".
.RS
.PP
If you supply the optional numeric parameters, the have the following
@@ -99,23 +99,53 @@ by many terminal emulators such as xterm. And \fIn\fR=2 tells it to
use escape sequences that support true 24-bit colors, again supported
by many terminal emulators such as xterm.
.PP
If the optional \fIm\fR parameter is supplied following a comma,
then \fIm\fR=0 tells \fBRemind\fR that the terminal background is dark,
and \fBRemind\fR will brighten up dark colors to make them visible. If
If the optional \fIm\fR parameter is supplied following a comma, then
\fIm\fR=0 tells \fBRemind\fR that the terminal background is dark, and
\fBRemind\fR will brighten up dark colors to make them visible. If
\fIm\fR=1, then \fBRemind\fR assumes the terminal background is light
and it will darken bright colors to make them visible. If no \fIm\fR
is supplied, then \fBRemind\fR does not perform any adjustments, and
some reminders may be hard or impossible to see if the color is too close
to the terminal background color.
is supplied, or it is supplied as \fIm\fR=2, then \fBRemind\fR does
not perform any adjustments, and some reminders may be hard or
impossible to see if the color is too close to the terminal background
color.
.PP
If the optional \fIb\fR parameter is supplied following a comma, then
\fIb=0\fR tells \fBRemind\fR to ignore SPECIAL SHADE reminders (the
default) and \fIb=1\fR tells \fBRemind\fR to respect SPECIAL SHADE
reminders by emitting VT100 escape codes to color the background of the
calendar cell. Note that SHADE does not work well unless you are
using the extended 256-color palette (\fIn\fR=1) or the true
24-bit colors (\fIn\fR=2). Note that for calendar cells that are
shaded, the clamping mechanism described earlier for \fIm=0\fR or
\fIm=1\fR is skipped; it is assumed that if you set \fIboth\fR the
foreground color of a reminder and the background color of a cell,
then you know what you are doing.
.RE
.TP
.B \-w\fR\fIcol\fR[,\fIpad\fR[,\fIspc\fR]]]
The \fB\-w\fR option specifies the output width, padding and spacing
of the formatted calendar output. \fICol\fR specifies the number of
columns in the output device. If not specified, or specified as 0,
it defaults to the larger of 71 or the actual width of your terminal,
or to 80 if standard output is not a terminal.
columns in the output device. If \fIcol\fR is not specified, or is
specified as 0, it defaults to the larger of 71 or the actual width of
your terminal, or to 80 if standard output is not a terminal. If
\fIcol\fR is specified as the letter \fBt\fR, then \fBRemind\fR
attempts to get the width of the \fB/dev/tty\fR terminal device. This
is useful, for example, if you pipe calendar output into \fBless\fR;
even though standard output is a pipe, you want the calendar to be
sized correctly for your terminal window:
.RS
.PP
.nf
remind -c -wt .reminders | less
.fi
.RE
.RS
.PP
Note that the value of \fIcol\fR is also used to set the system variable
$FormWidth, which is initialized to \fIcol\fR - 8. See "SYSTEM VARIABLES"
for details.
.PP
\fIPad\fR specifies how many lines
to use to "pad" empty calendar boxes. This defaults to 5. If you
@@ -1725,6 +1755,12 @@ Arguably, the \fBINCLUDE\fR command should have worked the way \fBDO\fR
does right from the start, but changing it would have broken
backward-compatibility, hence the introduction of \fBDO\fR.
.PP
Note that if the currently-processing reminders file was specified as
a symbolic link to a file that is not in the same directory as the
symbolic link itself, \fBDO\fR will fail. \fBRemind\fR does \fInot\fR
resolve the real path of symbolic links, so you should avoid using
symbolic links to files.
.PP
.SH THE RUN COMMAND
.PP
If you include other files in your reminder script, you may not always
@@ -1919,12 +1955,16 @@ The following examples illustrate constants in \fBRemind\fR expressions:
12, 36, \-10, 0, 1209
.TP
.B STRING constants
"Hello there", "This is a test", "\\n\\gosd\\w", ""
"Hello there", "This is a test", "\\nHello\\tThere", ""
.PP
.RS
Note that the empty string is represented by "", and that
backslashes in a string are \fInot\fR interpreted specially, as in they are
in C.
Note that the empty string is represented by "". Remind supports
the escape sequences "\\a", "\\b", "\\f", "\\n", "\\r", "\\t"
and "\\v" which have the same meanings as their counterparts in C.
To include a quote in a string, use "\\"". Any other character
preceded by a backslash is inserted into the string as-is, but the
backslash itself is removed. To include a backslash in a string,
use "\\\\".
.RE
.TP
.B TIME constants
@@ -2831,6 +2871,13 @@ This includes the file "stuff" in the same directory as the
current file being processed. Note that this workaround is
no longer necessary because \fBDO stuff\fR will achieve the
same goal.
.PP
Note that if the currently-processing reminders file was specified as
a symbolic link, then \fBfiledir()\fR returns the directory containing
the symbolic link and \fInot\fR the directory containing the target
of the symbolic link. You should avoid using
symbolic links to files unless both the symbolic link and its target
happen to be in the same directory.
.RE
.TP
.B filename()
@@ -3255,6 +3302,21 @@ May 16 and 17. You can go backwards, too, so:
takes \fIa\fR back to 2009-05-13.
.RE
.TP
.B stdout()
Returns a string representing where Remind's standard output is going.
The return values are one of the following: "TTY" if standard-output
is a terminal, "BLOCKDEV" if it is a block device (very unlikely),
"CHARDEV" if it is a character device (eg, /dev/null), "DIR" if it
is a directory (very unlikely), "PIPE" if it is a pipe or FIFO,
"SYMLINK" if it is a symlink (very unlikely), "SOCKET" if it is a
socket, or "UNKNOWN" if it could not be determined.
.RS
.PP
The purpose of \fBstdout()\fR is mostly to distinguish between TTY
and non-TTY output; you may wish to change or disable colors if the
output is not going to a TTY.
.RE
.TP
.B strlen(s_str)
Returns the length of \fIstr\fR. If the length of \fIstr\fR is too large
to represent as an integer, emits a "Number too high" error.
@@ -5458,7 +5520,8 @@ Almanac Office, USNO.
.PP
Richard Siegel and Michael and Sharon Strassfeld, \fIThe First Jewish
Catalog\fR, Jewish Publication Society of America.
.PP
.SH HOME PAGE
https://dianne.skoll.ca/projects/remind/
.SH SEE ALSO
.PP
\fBrem\fR(1), \fBrem2ps\fR(1), \fBrem2pdf\fR(1), \fBtkremind\fR(1), \fBrem2html\fR(1)

View File

@@ -1,4 +1,4 @@
.TH TKREMIND 1 "14 March 2022"
.TH TKREMIND 1 "@RELEASE_DATE@" "User Commands" "VERSION @VERSION@"
.UC 4
.SH NAME
tkremind \- graphical front-end to Remind calendar program
@@ -427,6 +427,8 @@ $HOME/.reminders -- default reminder file or directory.
$HOME/.config/tkremindrc -- \fBTkRemind\fR saved options.
.SH HOME PAGE
https://dianne.skoll.ca/projects/remind/
.SH SEE ALSO
\fBremind\fR, \fBrem2ps\fR, \fBrem2pdf\fR, \fBrem2html\fR

View File

@@ -19,7 +19,7 @@ install:
$(PERL) -M$$m -e 1 > /dev/null 2>&1; \
if test $$? != 0 ; then echo "Not installing rem2html; missing $$m"; exit 0; fi; \
done; \
pod2man rem2html > rem2html.1 && mkdir -p $(DESTDIR)$(mandir)/man1 && cp rem2html.1 $(DESTDIR)$(mandir)/man1/rem2html.1 || true; \
pod2man --center "VERSION @VERSION@" --date "@RELEASE_DATE@" rem2html > rem2html.1 && mkdir -p $(DESTDIR)$(mandir)/man1 && cp rem2html.1 $(DESTDIR)$(mandir)/man1/rem2html.1 || true; \
echo "Installing rem2html in $(DESTDIR)$(bindir)"; \
mkdir -p $(DESTDIR)$(bindir) && sed -e 's|^#!perl|#!$(PERL)|' < rem2html > $(DESTDIR)$(bindir)/rem2html && chmod 755 $(DESTDIR)$(bindir)/rem2html && exit 0; \
exit 1;

View File

@@ -130,6 +130,10 @@ today's date, add the following reminder to your reminders file:
rem2html was written by Dianne Skoll with much inspiration from an
earlier version by Don Schwarz.
=head1 HOME PAGE
L<https://dianne.skoll.ca/projects/remind/>
=head1 SEE ALSO
B<remind>, B<rem2ps>, B<rem2pdf>, B<tkremind>

View File

@@ -1,4 +1,15 @@
use ExtUtils::MakeMaker;
{
# Override pod2man options
package MY;
sub manifypods {
my ($self,%attribs) = @_;
my $result = $self->SUPER::manifypods(%attribs);
$result =~ s/^(POD2MAN_EXE\s*=\s*)(.+)$/$1$2 --center 'VERSION @VERSION@' --date '@RELEASE_DATE@'/m;
return $result;
}
}
WriteMakefile(
NAME => 'Remind::PDF',
AUTHOR => q{Dianne Skoll <dianne@skoll.ca>},

View File

@@ -443,14 +443,14 @@ B<-p>, B<-pp> or B<-ppp> options into B<rem2pdf>. The PDF output
will be sent to standard output. So for example, to print a 12-month
calendar for the year 2030, use:
remind -pp12 /dev/null Jan 2030 | rem2pdf -e -l -c=3 | lpr
remind -pp12 /dev/null Jan 2030 | rem2pdf -e -l -c3 | lpr
You can concatenate multiple B<remind> runs. For example, the following
will produce a PDF calendar for January through March of 2023, and
June of 2023 (for a total of four pages);
(remind -pp3 Jan 2023 /dev/null ; \
remind -p June 2023 /dev/null) | rem2pdf -e -l -c=3 > cal.pdf
(remind -pp3 /dev/null Jan 2023 ; \
remind -pp /dev/null June 2023) | rem2pdf -e -l -c3 > cal.pdf
=head1 FORMATTED TEXT
@@ -504,6 +504,10 @@ of each calendar box:
B<Rem2PDF> was written by Dianne Skoll <dianne@skoll.ca>
=head1 HOME PAGE
L<https://dianne.skoll.ca/projects/remind/>
=head1 SEE ALSO
B<remind>, B<rem2ps>, B<rem2html>, B<tkremind>

View File

@@ -36,7 +36,7 @@ REMINDOBJS= $(REMINDSRCS:.c=.o)
all: remind rem2ps
test: remind
test: all
@sh ../tests/test-rem
.c.o:
@@ -45,12 +45,12 @@ test: remind
$(REMINDOBJS): $(REMINDHDRS)
rem2ps: rem2ps.o dynbuf.o json.o
@CC@ @LDFLAGS@ $(LDEXTRA) -o rem2ps rem2ps.o dynbuf.o json.o -lm
@CC@ @CFLAGS@ @LDFLAGS@ $(LDEXTRA) -o rem2ps rem2ps.o dynbuf.o json.o -lm
remind: $(REMINDOBJS)
@CC@ @LDFLAGS@ $(LDEXTRA) -o remind $(REMINDOBJS) @LIBS@
@CC@ @CFLAGS@ @LDFLAGS@ $(LDEXTRA) -o remind $(REMINDOBJS) @LIBS@
install-nostripped: all
install: all
-mkdir -p $(DESTDIR)$(bindir) || true
for prog in $(PROGS) $(SCRIPTS) ; do \
$(INSTALL_PROGRAM) $$prog $(DESTDIR)$(bindir) || exit 1; \
@@ -64,7 +64,7 @@ install-nostripped: all
-mkdir -p $(DESTDIR)$(datarootdir)/remind || true
cp -R ../include/* $(DESTDIR)$(datarootdir)/remind
install: install-nostripped
install-stripped: install
strip $(DESTDIR)$(bindir)/remind || true
strip $(DESTDIR)$(bindir)/rem2ps || true

View File

@@ -147,6 +147,47 @@ static char *VT100Colors[2][2][2][2] /* [Br][R][G][B] */ = {
}
};
static char *VT100BGColors[2][2][2] /* [R][G][B] */ = {
{
{
/* 0, 0, 0 = Black */ "\x1B[0;40m",
/* 0, 0, 1 = Blue */ "\x1B[0;44m"
},
{
/* 0, 1, 0 = Green */ "\x1B[0;42m",
/* 0, 1, 1 = Cyan */ "\x1B[0;46m"
}
},
{
{
/* 1, 0, 0 = Red */ "\x1B[0;41m",
/* 1, 0, 1 = Magenta */ "\x1B[0;45m"
},
{
/* 1, 1, 0 = Yellow */ "\x1B[0;43m",
/* 1, 1, 1 = White */ "\x1B[0;47m"
}
}
};
/* Moon phase icons in UTF-8 */
static char const *moonphase_emojis[] = {
"\xF0\x9F\x8C\x91",
"\xF0\x9F\x8C\x93",
"\xF0\x9F\x8C\x95",
"\xF0\x9F\x8C\x97"
};
/* Moon phases for each day 1-31, up to 32 chars per moon-phase string
including termination \0 */
static char moons[32][32];
/* Week indicators */
static char weeks[32][32];
/* Background colors of each day 1-31, rgb */
static int bgcolor[32][3];
static struct line_drawing *linestruct;
#define DRAW(x) fputs(linestruct->x, stdout)
@@ -229,13 +270,14 @@ static struct xterm256_colors XTerm256Colors[] =
/* Global variables */
static CalEntry *CalColumn[7];
static int ColToDay[7];
static int ColSpaces;
static int DidAMonth;
static int DidADay;
static void ColorizeEntry(CalEntry const *e);
static void ColorizeEntry(CalEntry const *e, int clamp);
static void SortCol (CalEntry **col);
static void DoCalendarOneWeek (int nleft);
static void DoCalendarOneMonth (void);
@@ -244,7 +286,7 @@ static void WriteWeekHeaderLine (void);
static void WritePostHeaderLine (void);
static void PrintLeft (char const *s, int width, char pad);
static void PrintCentered (char const *s, int width, char *pad);
static int WriteOneCalLine (void);
static int WriteOneCalLine (int jul, int wd);
static int WriteOneColLine (int col);
static void GenerateCalEntries (int col);
static void WriteCalHeader (void);
@@ -256,6 +298,46 @@ static void WriteBottomCalLine (void);
static void WriteIntermediateCalLine (void);
static void WriteCalDays (void);
static int
DayOf(int jul)
{
int d;
FromJulian(jul, NULL, NULL, &d);
return d;
}
static void
Backgroundize(int d)
{
if (d < 1 || d > 31) {
return;
}
if (!UseBGVTChars) {
return;
}
if (bgcolor[d][0] < 0) {
return;
}
printf("%s", Colorize(bgcolor[d][0], bgcolor[d][1], bgcolor[d][2], 1, 0));
}
static void
UnBackgroundize(int d)
{
if (d < 1 || d > 31) {
return;
}
if (!UseBGVTChars) {
return;
}
if (bgcolor[d][0] < 0) {
return;
}
printf("%s", Decolorize());
}
static void
send_lrm(void)
{
@@ -510,16 +592,13 @@ ClampColor(int *r, int *g, int *b)
}
char const *
Decolorize(int r, int g, int b)
Decolorize(void)
{
if (!strcmp(Colorize(r, g, b), "")) {
return "";
}
return "\x1B[0m";
}
static char const *
Colorize256(int r, int g, int b)
Colorize256(int r, int g, int b, int bg, int clamp)
{
static char buf[40];
int best = -1;
@@ -528,7 +607,9 @@ Colorize256(int r, int g, int b)
struct xterm256_colors *cur;
size_t i;
ClampColor(&r, &g, &b);
if (clamp) {
ClampColor(&r, &g, &b);
}
for (i=0; i<(sizeof(XTerm256Colors) / sizeof(XTerm256Colors[0])); i++) {
cur = &XTerm256Colors[i];
dist = ((r - cur->r) * (r - cur->r)) +
@@ -540,31 +621,42 @@ Colorize256(int r, int g, int b)
}
}
cur = &XTerm256Colors[best];
sprintf(buf, "\x1B[38;5;%dm", best);
if (bg) {
sprintf(buf, "\x1B[48;5;%dm", best);
} else {
sprintf(buf, "\x1B[38;5;%dm", best);
}
return buf;
}
static char const *
ColorizeTrue(int r, int g, int b)
ColorizeTrue(int r, int g, int b, int bg, int clamp)
{
static char buf[40];
ClampColor(&r, &g, &b);
sprintf(buf, "\x1B[38;2;%d;%d;%dm", r, g, b);
if (clamp) {
ClampColor(&r, &g, &b);
}
if (bg) {
sprintf(buf, "\x1B[48;2;%d;%d;%dm", r, g, b);
} else {
sprintf(buf, "\x1B[38;2;%d;%d;%dm", r, g, b);
}
return buf;
}
char const *
Colorize(int r, int g, int b)
Colorize(int r, int g, int b, int bg, int clamp)
{
int bright = 0;
if (UseTrueColors) {
return ColorizeTrue(r, g, b);
return ColorizeTrue(r, g, b, bg, clamp);
}
if (Use256Colors) {
return Colorize256(r, g, b);
return Colorize256(r, g, b, bg, clamp);
}
if (r > 128 || g > 128 || b > 128) {
bright = 1;
}
@@ -575,43 +667,112 @@ Colorize(int r, int g, int b)
if (b > 64) b = 1;
else b = 0;
if (TerminalBackground == TERMINAL_BACKGROUND_DARK) {
if (clamp && TerminalBackground == TERMINAL_BACKGROUND_DARK && !bg) {
/* Convert black-on-black to grey */
if (!r && !g && !b) return VT100Colors[1][0][0][0];
}
if (TerminalBackground == TERMINAL_BACKGROUND_LIGHT) {
if (clamp && TerminalBackground == TERMINAL_BACKGROUND_LIGHT && !bg) {
/* Convert white-on-white to grey */
if (r && g && b) return VT100Colors[1][0][0][0];
}
return VT100Colors[bright][r][g][b];
if (bg) {
return VT100BGColors[r][g][b];
} else {
return VT100Colors[bright][r][g][b];
}
}
static void ColorizeEntry(CalEntry const *e)
static void ColorizeEntry(CalEntry const *e, int clamp)
{
printf("%s", Colorize(e->r, e->g, e->b));
printf("%s", Colorize(e->r, e->g, e->b, 0, clamp));
}
static int
ComputeCalWidth(int x)
static void
InitMoonsAndShades(void)
{
struct winsize w;
if (x >= 71) {
/* Has been set with -w option */
return x;
int i;
/* Initialize the moon array */
if (encoding_is_utf8) {
for (i=0; i<=31; i++) {
moons[i][0] = 0;
}
}
if (!isatty(STDOUT_FILENO)) {
/* Output is not a TTY... assume 80 */
return 80;
/* Clear SHADEs */
if (UseBGVTChars) {
for (i=0; i<=31; i++) {
bgcolor[i][0] = -1;
bgcolor[i][1] = -1;
bgcolor[i][2] = -1;
}
}
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) < 0) {
return 80;
/* Clear weeks */
for(i=0; i<=31; i++) {
weeks[i][0] = 0;
}
if (w.ws_col < 71) {
return 71;
}
return w.ws_col;
}
static void
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) {
return;
}
if (sscanf(shade, "%d %d %d", &r, &g, &b) != 3) {
if (sscanf(shade, "%d", &r) != 1) {
return;
}
g = r;
b = r;
}
if (r < 0 || g < 0 || b < 0 || r > 255 || g > 255 || b > 255) {
return;
}
FromJulian(jul, &y, &m, &d);
bgcolor[d][0] = r;
bgcolor[d][1] = g;
bgcolor[d][2] = b;
}
static void
SetMoonEntry(int jul, char const *moon)
{
int phase;
int y, m, d;
char msg[32];
/* Don't bother unless it's utf-8 */
if (!encoding_is_utf8) {
return;
}
msg[0] = 0;
if (sscanf(moon, "%d %*d %*d %31[^\x01]", &phase, msg) < 4) {
if (sscanf(moon, "%d", &phase) != 1) {
/* Malformed MOON special; ignore */
fprintf(stderr, "Oops 1\n");
return;
}
}
if (phase < 0 || phase > 3) {
/* Bad phase */
fprintf(stderr, "Oops 2\n");
return;
}
FromJulian(jul, &y, &m, &d);
if (msg[0]) {
snprintf(moons[d], sizeof(moons[d]), "%s %s", moonphase_emojis[phase], msg);
} else {
snprintf(moons[d], sizeof(moons[d]), "%s", moonphase_emojis[phase]);
}
}
/***************************************************************/
/* */
/* ProduceCalendar */
@@ -640,8 +801,6 @@ void ProduceCalendar(void)
}
ShouldCache = 1;
CalWidth = ComputeCalWidth(CalWidth);
ColSpaces = (CalWidth - 9) / 7;
CalWidth = 7*ColSpaces + 8;
@@ -694,18 +853,22 @@ static void DoCalendarOneWeek(int nleft)
int LinesWritten = 0;
int OrigJul = JulianToday;
InitMoonsAndShades();
/* Fill in the column entries */
for (i=0; i<7; i++) {
ColToDay[i] = DayOf(JulianToday);
GenerateCalEntries(i);
JulianToday++;
}
/* Output the entries */
/* Figure out weekday of first column */
if (MondayFirst) wd = JulianToday % 7;
else wd = (JulianToday + 1) % 7;
/* Output the entries */
/* If it's "Simple Calendar" format, do it simply... */
if (DoSimpleCalendar) {
if (MondayFirst) wd = JulianToday % 7;
else wd = (JulianToday + 1) % 7;
for (i=0; i<7; i++) {
WriteSimpleEntries(i, OrigJul+i-wd);
}
@@ -717,13 +880,33 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
FromJulian(OrigJul+i, &y, &m, &d);
FromJulian(OrigJul+i, &y, &m, &d);
char const *mon = get_month_name(m);
snprintf(buf, sizeof(buf), "%d %s ", d, get_month_abbrev(mon));
if (OrigJul+i == RealToday)
PrintLeft(buf, ColSpaces, '*');
else
if (moons[d][0]) {
if (weeks[d][0]) {
snprintf(buf, sizeof(buf), "%d %s %s %s ", d, get_month_abbrev(mon), weeks[d], moons[d]);
} else {
snprintf(buf, sizeof(buf), "%d %s %s ", d, get_month_abbrev(mon), moons[d]);
}
} else {
if (weeks[d][0]) {
snprintf(buf, sizeof(buf), "%d %s %s ", d, get_month_abbrev(mon), weeks[d]);
} else {
snprintf(buf, sizeof(buf), "%d %s ", d, get_month_abbrev(mon));
}
}
if (OrigJul+i == RealToday) {
if (UseVTColors) {
printf("\x1B[1m"); /* Bold */
}
PrintLeft(buf, ColSpaces-1, '*');
if (UseVTColors) {
printf("\x1B[0m"); /* Normal */
}
putchar(' ');
} else {
PrintLeft(buf, ColSpaces, ' ');
}
gon();
DRAW(tb);
goff();
@@ -734,7 +917,10 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
d = ColToDay[i];
Backgroundize(d);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(d);
gon();
DRAW(tb);
goff();
@@ -745,7 +931,7 @@ static void DoCalendarOneWeek(int nleft)
/* Write the body lines */
done = 0;
while (!done) {
done = WriteOneCalLine();
done = WriteOneCalLine(OrigJul, wd);
LinesWritten++;
}
@@ -755,7 +941,10 @@ static void DoCalendarOneWeek(int nleft)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
d = ColToDay[i];
Backgroundize(d);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(d);
gon();
DRAW(tb);
goff();
@@ -782,6 +971,8 @@ static void DoCalendarOneMonth(void)
{
int y, m, d, mm, yy, i, j;
InitMoonsAndShades();
if (!DoSimpleCalendar) WriteCalHeader();
DidADay = 0;
@@ -882,10 +1073,15 @@ static int WriteCalendarRow(void)
if (!MondayFirst) wd = (JulianToday + 1) % 7;
else wd = JulianToday % 7;
for (i=0; i<7; i++) {
ColToDay[i] = 0;
}
/* Fill in the column entries */
for (i=wd; i<7; i++) {
if (d+i-wd > DaysInMonth(m, y)) break;
GenerateCalEntries(i);
ColToDay[i] = DayOf(JulianToday);
JulianToday++;
}
@@ -908,9 +1104,27 @@ static int WriteCalendarRow(void)
if (i < wd || d+i-wd>DaysInMonth(m, y))
PrintLeft("", ColSpaces, ' ');
else {
sprintf(buf, "%d ", d+i-wd);
if (moons[d+i-wd][0]) {
if (weeks[d+i-wd][0]) {
snprintf(buf, sizeof(buf), "%d %s %s ", d+i-wd, weeks[d+i-wd], moons[d+i-wd]);
} else {
snprintf(buf, sizeof(buf), "%d %s ", d+i-wd, moons[d+i-wd]);
}
} else {
if (weeks[d+i-wd][0]) {
snprintf(buf, sizeof(buf), "%d %s ", d+i-wd, weeks[d+i-wd]);
} else {
snprintf(buf, sizeof(buf), "%d ", d+i-wd);
}
}
if (Julian(y, m, d+i-wd) == RealToday) {
if (UseVTColors) {
printf("\x1B[1m"); /* Bold */
}
PrintLeft(buf, ColSpaces-1, '*');
if (UseVTColors) {
printf("\x1B[0m"); /* Normal */
}
putchar(' ');
} else {
PrintLeft(buf, ColSpaces, ' ');
@@ -926,7 +1140,9 @@ static int WriteCalendarRow(void)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
Backgroundize(ColToDay[i]);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(ColToDay[i]);
gon();
DRAW(tb);
goff();
@@ -937,7 +1153,7 @@ static int WriteCalendarRow(void)
/* Write the body lines */
done = 0;
while (!done) {
done = WriteOneCalLine();
done = WriteOneCalLine(OrigJul, wd);
LinesWritten++;
}
@@ -947,7 +1163,9 @@ static int WriteCalendarRow(void)
DRAW(tb);
goff();
for (i=0; i<7; i++) {
Backgroundize(ColToDay[i]);
PrintLeft("", ColSpaces, ' ');
UnBackgroundize(ColToDay[i]);
gon();
DRAW(tb);
goff();
@@ -1118,19 +1336,25 @@ static void PrintCentered(char const *s, int width, char *pad)
/* Write a single line. */
/* */
/***************************************************************/
static int WriteOneCalLine(void)
static int WriteOneCalLine(int start_jul, int wd)
{
int done = 1, i;
int y, m, d;
gon();
DRAW(tb);
goff();
for (i=0; i<7; i++) {
FromJulian(start_jul+i, &y, &m, &d);
d -= wd;
if (CalColumn[i]) {
Backgroundize(ColToDay[i]);
if (WriteOneColLine(i)) done = 0;
} else {
Backgroundize(ColToDay[i]);
PrintCentered("", ColSpaces, " ");
}
UnBackgroundize(ColToDay[i]);
gon();
DRAW(tb);
goff();
@@ -1159,9 +1383,12 @@ static int WriteOneColLine(int col)
wchar_t const *wspace;
int width;
#endif
int clamp = 1;
int numwritten = 0;
int d = ColToDay[col];
if (d && UseBGVTChars && bgcolor[d][0] != -1) {
clamp = 0;
}
/* Print as many characters as possible within the column */
#ifdef REM_USE_WCHAR
if (e->wc_text) {
@@ -1204,7 +1431,7 @@ static int WriteOneColLine(int col)
/* Colorize reminder if necessary */
if (UseVTColors && e->is_color) {
ColorizeEntry(e);
ColorizeEntry(e, clamp);
}
/* If we couldn't find a space char, print what we have. */
@@ -1241,9 +1468,10 @@ static int WriteOneColLine(int col)
}
}
/* Decolorize reminder if necessary */
/* Decolorize reminder if necessary, but keep any SHADE */
if (UseVTColors && e->is_color) {
printf("%s", Decolorize(e->r, e->g, e->b));
printf("%s", Decolorize());
Backgroundize(d);
}
/* Possibly send lrm control sequence */
@@ -1296,7 +1524,7 @@ static int WriteOneColLine(int col)
/* Colorize reminder if necessary */
if (UseVTColors && e->is_color) {
ColorizeEntry(e);
ColorizeEntry(e, clamp);
}
/* If we couldn't find a space char, print what we have. */
@@ -1324,9 +1552,10 @@ static int WriteOneColLine(int col)
}
}
/* Decolorize reminder if necessary */
/* Decolorize reminder if necessary, but keep SHADE */
if (UseVTColors && e->is_color) {
printf("%s", Decolorize(e->r, e->g, e->b));
printf("%s", Decolorize());
Backgroundize(d);
}
/* Flesh out the rest of the column */
@@ -1600,6 +1829,19 @@ static int DoCalRem(ParsePtr p, int col)
DBufFree(&buf);
}
trig.typ = tok.val;
if (trig.typ == MSG_TYPE ||
trig.typ == CAL_TYPE ||
trig.typ == MSF_TYPE) {
is_color = (
DefaultColorR != -1
&& DefaultColorG != -1
&& DefaultColorB != -1);
if (is_color) {
col_r = DefaultColorR;
col_g = DefaultColorG;
col_b = DefaultColorB;
}
}
jul = LastTriggerDate;
if (!LastTrigValid) {
FreeTrig(&trig);
@@ -1663,10 +1905,49 @@ static int DoCalRem(ParsePtr p, int col)
}
}
if (trig.typ == PASSTHRU_TYPE) {
if (!PsCal && StrCmpi(trig.passthru, "COLOR") && StrCmpi(trig.passthru, "COLOUR")) {
if (!PsCal && !StrCmpi(trig.passthru, "SHADE")) {
if (jul == JulianToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
SetShadeEntry(jul, DBufValue(&obuf));
DBufFree(&obuf);
}
}
if (!PsCal && !StrCmpi(trig.passthru, "WEEK")) {
if (jul == JulianToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
sscanf(DBufValue(&obuf), "%31[^\x01]", weeks[DayOf(jul)]);
DBufFree(&obuf);
}
}
if (!PsCal && StrCmpi(trig.passthru, "COLOR") && StrCmpi(trig.passthru, "COLOUR") && StrCmpi(trig.passthru, "MOON")) {
FreeTrig(&trig);
return OK;
}
if (!PsCal && !StrCmpi(trig.passthru, "MOON")) {
if (jul == JulianToday) {
DBufInit(&obuf);
r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
if (r) {
DBufFree(&obuf);
FreeTrig(&trig);
return r;
}
SetMoonEntry(jul, DBufValue(&obuf));
DBufFree(&obuf);
}
}
if (!StrCmpi(trig.passthru, "COLOR") ||
!StrCmpi(trig.passthru, "COLOUR")) {
is_color = 1;

View File

@@ -868,6 +868,8 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
}
}
}
/***************************************************************/
/* */
/* TriggerReminder */
@@ -929,7 +931,8 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
}
/* If it's a MSG-type reminder, and no -k option was used, issue the banner. */
if ((t->typ == MSG_TYPE || t->typ == MSF_TYPE)
&& !NumTriggered && !NextMode && !MsgCommand) {
&& !DidMsgReminder && !NextMode && !MsgCommand) {
DidMsgReminder = 1;
if (!DoSubstFromString(DBufValue(&Banner), &buf,
JulianToday, NO_TIME) &&
DBufLen(&buf)) {
@@ -1030,7 +1033,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
if (!r) {
if (!DoCoerce(STR_TYPE, &v)) {
if (is_color) {
DBufPuts(&buf, Colorize(red, green, blue));
DBufPuts(&buf, Colorize(red, green, blue, 0, 1));
}
if (DBufPuts(&buf, v.v.str) != OK) {
DBufFree(&buf);
@@ -1044,7 +1047,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
}
if (is_color) {
DBufPuts(&buf, Colorize(red, green, blue));
DBufPuts(&buf, Colorize(red, green, blue, 0, 1));
}
if ( (r=DoSubst(p, &buf, t, tim, jul, NORMAL_MODE)) ) return r;
if (t->typ != RUN_TYPE) {
@@ -1055,7 +1058,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
if (!r) {
if (!DoCoerce(STR_TYPE, &v)) {
if (is_color) {
DBufPuts(&buf, Colorize(red, green, blue));
DBufPuts(&buf, Colorize(red, green, blue, 0, 1));
}
if (DBufPuts(&buf, v.v.str) != OK) {
DBufFree(&buf);
@@ -1069,7 +1072,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
}
if (is_color) {
DBufPuts(&buf, Decolorize(red, green, blue));
DBufPuts(&buf, Decolorize());
}
if ((!MsgCommand && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {

View File

@@ -253,6 +253,10 @@ static int ParseExprToken(DynamicBuffer *buf, char const **in)
DBufFree(buf);
return E_NO_MEM;
}
if (!**in) {
DBufFree(buf);
return E_MISS_QUOTE;
}
continue;
}
c = *(*in)++;
@@ -1245,7 +1249,21 @@ void PrintValue (Value *v, FILE *fp)
if (v->type == STR_TYPE) {
s=v->v.str;
putc('"', fp);
for (y=0; y<MAX_PRT_LEN && *s; y++) putc(*s++, fp);
for (y=0; y<MAX_PRT_LEN && *s; y++) {
switch(*s) {
case '\a': fprintf(ErrFp, "\\a"); break;
case '\b': fprintf(ErrFp, "\\b"); break;
case '\f': fprintf(ErrFp, "\\f"); break;
case '\n': fprintf(ErrFp, "\\n"); break;
case '\r': fprintf(ErrFp, "\\r"); break;
case '\t': fprintf(ErrFp, "\\t"); break;
case '\v': fprintf(ErrFp, "\\v"); break;
case '"': fprintf(ErrFp, "\\\""); break;
case '\\': fprintf(ErrFp, "\\\\"); break;
default: putc(*s, ErrFp); break;
}
s++;
}
putc('"',fp);
if (*s) fprintf(fp, "...");
}

View File

@@ -121,6 +121,7 @@ static int FRealtoday (func_info *);
static int FSgn (func_info *);
static int FShell (func_info *);
static int FSlide (func_info *);
static int FStdout (func_info *);
static int FStrlen (func_info *);
static int FSubstr (func_info *);
static int FSunrise (func_info *);
@@ -276,6 +277,7 @@ BuiltinFunc Func[] = {
{ "shell", 1, 2, 0, FShell },
{ "shellescape", 1, 1, 1, FShellescape },
{ "slide", 2, NO_MAX, 0, FSlide },
{ "stdout", 0, 0, 1, FStdout },
{ "strlen", 1, 1, 1, FStrlen },
{ "substr", 2, 3, 1, FSubstr },
{ "sunrise", 0, 1, 0, FSunrise},
@@ -1237,6 +1239,35 @@ static int FLower(func_info *info)
return OK;
}
/***************************************************************/
/* */
/* FStdout - return the type of file descriptor for stdout */
/* */
/***************************************************************/
static int FStdout(func_info *info)
{
struct stat statbuf;
int r;
if (isatty(STDOUT_FILENO)) {
return RetStrVal("TTY", info);
}
if (fstat(STDOUT_FILENO, &statbuf) < 0) {
return RetStrVal("UNKNOWN", info);
}
switch(statbuf.st_mode & S_IFMT) {
case S_IFBLK: r = RetStrVal("BLOCKDEV", info); break;
case S_IFCHR: r = RetStrVal("CHARDEV", info); break;
case S_IFDIR: r = RetStrVal("DIR",info); break;
case S_IFIFO: r = RetStrVal("PIPE",info); break;
case S_IFLNK: r = RetStrVal("SYMLINK", info); break;
case S_IFREG: r = RetStrVal("FILE",info); break;
case S_IFSOCK: r = RetStrVal("SOCKET", info); break;
default: r = RetStrVal("UNKNOWN", info); break;
}
return r;
}
/***************************************************************/
/* */
/* FToday - return the system's notion of "today" */

View File

@@ -60,7 +60,7 @@ EXTERN INIT( int DoPrefixLineNo, 0);
EXTERN INIT( int MondayFirst, 0);
EXTERN INIT( int Iterations, 1);
EXTERN INIT( int PsCal, 0);
EXTERN INIT( int CalWidth, -1);
EXTERN INIT( int CalWidth, 80);
EXTERN INIT( int CalWeeks, 0);
EXTERN INIT( int CalMonths, 0);
EXTERN INIT( int Hush, 0);
@@ -111,11 +111,13 @@ EXTERN INIT( int LastTriggerTime, 0);
EXTERN INIT( int ShouldCache, 0);
EXTERN char const *CurLine;
EXTERN INIT( int NumTriggered, 0);
EXTERN INIT( int DidMsgReminder, 0);
EXTERN int ArgC;
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 UseUTF8Chars, 0);
EXTERN INIT( int UseVTColors, 0);
EXTERN INIT( int Use256Colors, 0);

View File

@@ -21,6 +21,10 @@
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <pwd.h>
#include <unistd.h>
#include <sys/ioctl.h>
@@ -43,7 +47,8 @@
* simple calendar format.
* -r = Disallow RUN mode
* -c[n] = Produce a calendar for n months (default = 1)
* -@[n,m] = Colorize n=0 VT100 n=1 85 n=2 True m=0 dark terminal m=1 light
* -@[n,m,b]= Colorize n=0 VT100 n=1 85 n=2 True m=0 dark terminal m=1 light
* b=0 ignore SHADE b=1 respect SHADE
* -w[n,n,n] = Specify output device width, padding and spacing
* -s[n] = Produce calendar in "simple calendar" format
* -p[n] = Produce calendar in format compatible with rem2ps
@@ -94,6 +99,25 @@ static void AddTrustedUser(char const *username);
static DynamicBuffer default_filename_buf;
static void
InitCalWidthAndFormWidth(int fd)
{
struct winsize w;
if (!isatty(fd)) {
return;
}
if (ioctl(fd, TIOCGWINSZ, &w) == 0) {
CalWidth = w.ws_col;
if (CalWidth < 71) {
CalWidth = 71;
}
FormWidth = w.ws_col - 8;
if (FormWidth < 20) FormWidth = 20;
if (FormWidth > 500) FormWidth = 500;
}
}
/***************************************************************/
/* */
/* DefaultFilename */
@@ -141,19 +165,13 @@ void InitRemind(int argc, char const *argv[])
int weeks;
int x;
int jul;
int ttyfd;
jul = NO_DATE;
/* If stdout is a terminal, initialize $FormWidth to terminal width-8,
but clamp to [20, 500] */
if (isatty(STDOUT_FILENO)) {
struct winsize w;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0) {
FormWidth = w.ws_col - 8;
if (FormWidth < 20) FormWidth = 20;
if (FormWidth > 500) FormWidth = 500;
}
}
InitCalWidthAndFormWidth(STDOUT_FILENO);
/* Initialize global dynamic buffers */
DBufInit(&Banner);
@@ -233,22 +251,36 @@ void InitRemind(int argc, char const *argv[])
} else if (x == 2) {
UseTrueColors = 1;
} else if (x != 0) {
fprintf(ErrFp, "%s: -@n,m: n must be 0, 1 or 2 (assuming 0)\n",
fprintf(ErrFp, "%s: -@n,m,b: n must be 0, 1 or 2 (assuming 0)\n",
argv[0]);
}
}
if (*arg == ',') {
arg++;
PARSENUM(x, arg);
if (x == 0) {
TerminalBackground = TERMINAL_BACKGROUND_DARK;
} else if (x == 1) {
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
} else {
fprintf(ErrFp, "%s: -@n,m: m must be 0 or 1\n",
argv[0]);
if (*arg != ',') {
PARSENUM(x, arg);
if (x == 0) {
TerminalBackground = TERMINAL_BACKGROUND_DARK;
} else if (x == 1) {
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
} else if (x == 2) {
TerminalBackground = TERMINAL_BACKGROUND_UNKNOWN;
} else {
fprintf(ErrFp, "%s: -@n,m,b: m must be 0, 1 or 2 (assuming 2)\n",
argv[0]);
}
}
}
if (*arg == ',') {
arg++;
PARSENUM(x, arg);
if (x != 0 && x != 1) {
fprintf(ErrFp, "%s: -@n,m,b: b must be 0 or 1 (assuming 0)\n",
argv[0]);
x = 0;
}
UseBGVTChars = x;
}
break;
case 'j':
@@ -495,11 +527,27 @@ void InitRemind(int argc, char const *argv[])
case 'w':
case 'W':
if (*arg != ',') {
PARSENUM(CalWidth, arg);
if (CalWidth != 0 && CalWidth < 71) CalWidth = 71;
if (CalWidth == 0) {
CalWidth = -1;
}
if (*arg == 't') {
arg++;
/* -wt means get width from /dev/tty */
ttyfd = open("/dev/tty", O_RDONLY);
if (!ttyfd) {
fprintf(stderr, "%s: `-wt': Cannot open /dev/tty: %s\n",
argv[0], strerror(errno));
} else {
InitCalWidthAndFormWidth(ttyfd);
close(ttyfd);
}
} else {
PARSENUM(CalWidth, arg);
if (CalWidth != 0 && CalWidth < 71) CalWidth = 71;
if (CalWidth == 0) {
CalWidth = -1;
}
FormWidth = CalWidth - 8;
if (FormWidth < 20) FormWidth = 20;
if (FormWidth > 500) FormWidth = 500;
}
}
if (*arg == ',') {
arg++;
@@ -689,7 +737,7 @@ void Usage(void)
fprintf(ErrFp, "Options:\n");
fprintf(ErrFp, " -n Output next occurrence of reminders in simple format\n");
fprintf(ErrFp, " -r Disable RUN directives\n");
fprintf(ErrFp, " -@[n,m] Colorize COLOR reminders\n");
fprintf(ErrFp, " -@[n,m,b] Colorize COLOR/SHADE reminders\n");
fprintf(ErrFp, " -c[a][n] Produce a calendar for n (default 1) months\n");
fprintf(ErrFp, " -c[a]+[n] Produce a calendar for n (default 1) weeks\n");
fprintf(ErrFp, " -w[n[,p[,s]]] Specify width, padding and spacing of calendar\n");

View File

@@ -12,6 +12,7 @@
#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
@@ -176,7 +177,7 @@ static void DoReminders(void)
}
if (FileAccessDate < 0) {
fprintf(ErrFp, "%s: `%s'.\n", ErrMsg[E_CANTACCESS], InitialFile);
fprintf(ErrFp, "%s: `%s': %s.\n", ErrMsg[E_CANTACCESS], InitialFile, strerror(errno));
exit(1);
}
@@ -329,7 +330,8 @@ int Julian(int year, int month, int day)
/* */
/* FromJulian */
/* */
/* Convert a Julian date to year, month, day. */
/* Convert a Julian date to year, month, day. You may supply */
/* NULL for y, m or d if you're not interested in that value */
/* */
/***************************************************************/
void FromJulian(int jul, int *y, int *m, int *d)
@@ -358,9 +360,15 @@ void FromJulian(int jul, int *y, int *m, int *d)
try_mon++;
t = DaysInMonth(try_mon, try_yr);
}
*y = try_yr;
*m = try_mon;
*d = jul + 1;
if (y) {
*y = try_yr;
}
if (m) {
*m = try_mon;
}
if (d) {
*d = jul + 1;
}
return;
}
@@ -857,19 +865,19 @@ int DoIfTrig(ParsePtr p)
Eprint("%s", ErrMsg[r]);
}
}
syndrome = IF_TRUE | BEFORE_ELSE;
syndrome = IF_FALSE | BEFORE_ELSE;
}
else {
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
syndrome = IF_TRUE | BEFORE_ELSE;
} else {
syndrome = IF_FALSE | BEFORE_ELSE;
if (PurgeMode) {
PurgeEchoLine("%s\n", "#!P: The next IFTRIG did not trigger.");
PurgeEchoLine("%s\n", "#!P: REM statements in IFTRIG block not checked for purging.");
}
}
}
if (syndrome == (IF_FALSE | BEFORE_ELSE) && PurgeMode) {
PurgeEchoLine("%s\n", "#!P: The next IFTRIG did not trigger.");
PurgeEchoLine("%s\n", "#!P: REM statements in IFTRIG block not checked for purging.");
}
FreeTrig(&trig);
}
NumIfs++;

View File

@@ -155,8 +155,8 @@ void SaveLastTimeTrig(TimeTrig const *t);
void SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigtime, int valid);
void PerIterationInit(void);
char const *Decolorize(int r, int g, int b);
char const *Colorize(int r, int g, int b);
char const *Decolorize(void);
char const *Colorize(int r, int g, int b, int bg, int clamp);
void PrintJSONString(char const *s);
void PrintJSONKeyPairInt(char const *name, int val);
void PrintJSONKeyPairString(char const *name, char const *val);

View File

@@ -127,7 +127,7 @@ void HandleQueuedReminders(void)
struct sigaction sa;
/* Suppress the BANNER from being issued */
NumTriggered = 1;
DidMsgReminder = 1;
/* Turn off sorting -- otherwise, TriggerReminder has no effect! */
SortByDate = 0;

View File

@@ -1023,6 +1023,7 @@ void DumpSysVarByName(char const *name)
static void DumpSysVar(char const *name, const SysVar *v)
{
char buffer[VAR_NAME_LEN+10];
Value vtmp;
if (name && !*name) name=NULL;
if (!v && !name) return; /* Shouldn't happen... */
@@ -1036,32 +1037,20 @@ static void DumpSysVar(char const *name, const SysVar *v)
fprintf(ErrFp, "%16s ", buffer);
if (v) {
if (v->type == SPECIAL_TYPE) {
Value val;
SysVarFunc f = (SysVarFunc) v->value;
f(0, &val);
PrintValue(&val, ErrFp);
f(0, &vtmp);
PrintValue(&vtmp, ErrFp);
putc('\n', ErrFp);
DestroyValue(val);
DestroyValue(vtmp);
} else if (v->type == STR_TYPE) {
char const *s = *((char **)v->value);
int y;
putc('"', ErrFp);
for (y=0; y<MAX_PRT_LEN && *s; y++) {
if (*s == '"') {
fprintf(ErrFp, "\" + char(34) + \"");
s++;
} else {
putc(*s++, ErrFp);
}
}
putc('"', ErrFp);
if (*s) fprintf(ErrFp, "...");
vtmp.type = STR_TYPE;
vtmp.v.str = * ((char **)v->value);
PrintValue(&vtmp, ErrFp);
putc('\n', ErrFp);
} else if (v->type == DATE_TYPE) {
Value val;
val.type = DATE_TYPE;
val.v.val = * (int *) v->value;
PrintValue(&val, ErrFp);
vtmp.type = DATE_TYPE;
vtmp.v.val = * (int *) v->value;
PrintValue(&vtmp, ErrFp);
putc('\n', ErrFp);
} else {
if (!v->modifiable) fprintf(ErrFp, "%d\n", *((int *)v->value));

View File

@@ -15,3 +15,6 @@ REM 28 SPECIAL COLOUR 129 0 129 Bright Magenta
REM 28 SPECIAL COLOUR 129 129 0 Bright Yellow
REM 28 SPECIAL COLOUR 129 129 129 Bright White
SET $DefaultColor "255 255 0"
REM 23 SATISFY [1] MSG DefaultColor_Yellow

View File

@@ -133,13 +133,27 @@ REM 4 MSG Normal
SET $DefaultColor "256 0 0"
EOF
# Test stdout
../src/remind - 1 jan 2012 <<'EOF' >> ../tests/test.out 2>&1
BANNER %
MSG STDOUT is a: [stdout()]%
EOF
../src/remind - 1 jan 2012 <<'EOF' 2>&1 | cat >> ../tests/test.out
BANNER %
MSG STDOUT is a: [stdout()]%
EOF
# Test -@ option
../src/remind -w,0,0 -@0 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@0,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@0
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -153,12 +167,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@0,0 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@0,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@0,0
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -172,12 +189,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@0,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@0,1
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -191,12 +211,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@1,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@1
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -210,12 +233,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@1,0 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@1,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@1,0
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -229,12 +255,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@1,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@1,1
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -248,12 +277,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@2 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@2,,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@2
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -267,12 +299,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@2,0 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@2,0,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@2,0
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -286,12 +321,15 @@ rem 23 SPECIAL COLOR 200 0 200 BRIGHT MAGENTA
rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
../src/remind -w,0,0 -@2,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
../src/remind -w,0,0 -@2,1,1 -c - 1 Jan 2020 <<'EOF' >> ../tests/test.out 2>&1
rem 1 SPECIAL COLOR 0 0 0 BLACK
rem 2 SPECIAL COLOR 0 0 65 BLUE
rem 3 SPECIAL COLOR 0 65 0 GREEN
rem 4 SPECIAL COLOR 0 65 65 CYAN
rem 5 msg -@2,1
rem 6 SPECIAL SHADE 255 255 0
rem 7 SPECIAL SHADE 255 0 255
rem 8 SPECIAL SHADE 0 255 255
rem 15 SPECIAL COLOR 65 0 0 RED
rem 16 SPECIAL COLOR 65 0 65 MAGENTA
rem 17 SPECIAL COLOR 65 65 0 YELLOW
@@ -332,7 +370,7 @@ fi
../src/remind -cu '-i$SuppressLRM=1' ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
# Remove references to SysInclude, which is build-specific
fgrep -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out
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
if [ "$?" = "0" ]; then
echo "Remind: Acceptance test PASSED"

File diff suppressed because it is too large Load Diff

View File

@@ -436,6 +436,7 @@ set a132 trigdatetime()
set a133 trigduration()
set a134 trigeventstart()
set a135 trigeventduration()
set a136 stdout()
# These will issue errors
REM Mon OMIT Mon SKIP MSG Never ever ever...
@@ -730,6 +731,11 @@ msg [a]
set x psshade(50)
set x psmoon(0)
# Recursive expression evaluation
FSET _f(x) 0
SET tmp evaltrig("Wed SKIP OMITFUNC _f",date(1992,1,8))
REM MSG [tmp]
# Trig
IF trig("sun +1") || trig("thu +1")
REM [trig()] +1 MSG Foo %b

View File

@@ -1,4 +1,9 @@
MSG ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский
MSG עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית
Wed MSG With tabs and spaces
Wed MSG With tabs and spaces
REM [moondate(0)] MSG 🌑
REM [moondate(1)] MSG 🌓 woo
REM [moondate(2)] MSG 🌕 blech bo
REM [moondate(3)] MSG 🌗 zo zo oz