mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 06:18:47 +02:00
Compare commits
73 Commits
04.00.01
...
04.01.00-B
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fdc3e4d23d | ||
|
|
f179c837e1 | ||
|
|
740bb44956 | ||
|
|
5b953769fe | ||
|
|
1ae00ce778 | ||
|
|
a01e05c1db | ||
|
|
63fb3e99f3 | ||
|
|
6cf7f5d2d8 | ||
|
|
316eb43303 | ||
|
|
576112a39a | ||
|
|
6607223abb | ||
|
|
9e85b1932d | ||
|
|
4ba7f5b1f2 | ||
|
|
fc93ae890a | ||
|
|
8051d01945 | ||
|
|
63430c59f7 | ||
|
|
c646bfc63f | ||
|
|
58dea8f69b | ||
|
|
f1c82dcb37 | ||
|
|
b984b66819 | ||
|
|
44bdae302b | ||
|
|
8eb6b250fb | ||
|
|
d838c41bf2 | ||
|
|
f9dbf36496 | ||
|
|
fe1427db28 | ||
|
|
2621ad5604 | ||
|
|
efecf2e1ea | ||
|
|
8666e6357e | ||
|
|
ae7069c9cb | ||
|
|
0c6ab3e607 | ||
|
|
17d6a60c0a | ||
|
|
e3e0a541dc | ||
|
|
712aa08fbc | ||
|
|
98c5bf511e | ||
|
|
1f9281628f | ||
|
|
8fb15aed17 | ||
|
|
a24c3a8542 | ||
|
|
8f8059e3f3 | ||
|
|
24bb462199 | ||
|
|
38e914f171 | ||
|
|
4a02c54e8d | ||
|
|
5fe169438a | ||
|
|
a7ef6e851a | ||
|
|
4d57b9d0aa | ||
|
|
5a7452d9f6 | ||
|
|
3916887aff | ||
|
|
f84f59fa91 | ||
|
|
1032f8908e | ||
|
|
6c2e8fc608 | ||
|
|
012e527fb5 | ||
|
|
62198c9807 | ||
|
|
de95224d62 | ||
|
|
be374a0464 | ||
|
|
fe9b3186d7 | ||
|
|
8405ea6c53 | ||
|
|
4274d05e10 | ||
|
|
4e80ce1159 | ||
|
|
52f473f2af | ||
|
|
1d6ca51bf9 | ||
|
|
e662d0b3dd | ||
|
|
b910d557d1 | ||
|
|
a4ad0a9e97 | ||
|
|
07f67e7dd7 | ||
|
|
d6575773fb | ||
|
|
ac1303886e | ||
|
|
1569992184 | ||
|
|
55a1f1d746 | ||
|
|
ef7742a3cc | ||
|
|
ef48c2020b | ||
|
|
6dcb25073b | ||
|
|
4824b07ec8 | ||
|
|
a8f1228fb7 | ||
|
|
80e51d1d0f |
7
.github/README.md
vendored
Normal file
7
.github/README.md
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Remind has moved
|
||||
|
||||
For various reasons, I have decided to move Remind off GitHub. This repo
|
||||
will be archived. To create merge requests or issues, please visit
|
||||
Remind's new home at https://salsa.debian.org/dskoll/remind
|
||||
|
||||
-- Dianne Skoll
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -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
|
||||
|
||||
13
.gitlab-ci.yml
Normal file
13
.gitlab-ci.yml
Normal 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
|
||||
25
Makefile
25
Makefile
@@ -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
18
configure
vendored
@@ -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.01
|
||||
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
|
||||
|
||||
13
configure.in
13
configure.in
@@ -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.01
|
||||
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
|
||||
|
||||
@@ -1,5 +1,79 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 4.1 Patch 0 - ????-??-??
|
||||
|
||||
- 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.
|
||||
|
||||
- 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.
|
||||
|
||||
- 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.
|
||||
|
||||
- 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...
|
||||
output.
|
||||
|
||||
- BUG FIX: tkremind: Don't create empty files called '&1' when creating
|
||||
a new reminder.
|
||||
|
||||
- BUG FIX: remind: Don't call signal-unsafe functions from signal handler
|
||||
|
||||
* VERSION 4.0 Patch 2 - 2022-08-02
|
||||
|
||||
- IMPROVEMENT: remind: Allow more forms of OMIT as per Ian! D. Allen's request:
|
||||
|
||||
OMIT Month [THROUGH Month]
|
||||
OMIT Day Month [THROUGH Day Month]
|
||||
OMIT Day Month Year [THROUGH Day Month Year]
|
||||
|
||||
- BUG FIX: Make $T behave as documented, exactly like trigdate(). $T would
|
||||
return '1989-12-31' rather than 0 if the trigger date was not valid.
|
||||
|
||||
- BUG FIX: TkRemind: Fix resizing bug for a calendar with 6 rows.
|
||||
|
||||
- DOCUMENTATION IMPROVEMENT: Improve TkRemind documentation; document use
|
||||
of inotifywait if available.
|
||||
|
||||
* VERSION 4.0 Patch 1 - 2022-06-03
|
||||
|
||||
- IMPROVEMENT: Add $SuppressLRM system variable to suppress the UTF-8
|
||||
@@ -1188,7 +1262,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.
|
||||
@@ -1779,7 +1853,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.
|
||||
@@ -1852,7 +1926,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()."
|
||||
|
||||
@@ -1994,6 +2068,3 @@ CHANGES TO REMIND
|
||||
* Version 1.0
|
||||
|
||||
- never publicly released.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -586,6 +586,18 @@ For a SHADE or COLOR special, the blue color component.
|
||||
.B body \fIbody\fR
|
||||
The body of the reminder to issue. Always present.
|
||||
.TP
|
||||
.B calendar_body \fIbody\fR
|
||||
The text appropriate to include in a calendar. Only present if the
|
||||
original body contains %"...%" sequences and the "q" modifier was used
|
||||
with Remind's "-pp..." flag.
|
||||
.TP
|
||||
.B plain_body \fIbody\fR
|
||||
The "plain" body of the reminder with any %"...%" sequences removed.
|
||||
If your back-end is designed to draw a calendar, then it should
|
||||
use the \fBcalendar_body\fR if present. If not, then it
|
||||
should use the \fBplain_body\fR if present, and if not, then it
|
||||
should fall back on the \fBbody\fR.
|
||||
.TP
|
||||
.B rawbody \fIraw\fR
|
||||
The "raw" body of the reminder, before any expression-pasting or
|
||||
substitution-sequence processing. If the raw body would be the same
|
||||
@@ -674,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.
|
||||
|
||||
@@ -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,14 +99,27 @@ 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]]]
|
||||
@@ -1532,11 +1545,11 @@ 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 \fIday\fR \fImonth\fR [\fIyear\fR]
|
||||
\fBOMIT\fR [\fIday\fR] \fImonth\fR [\fIyear\fR]
|
||||
.PP
|
||||
or:
|
||||
.PP
|
||||
\fBOMIT\fR \fIday1\fR \fImonth1\fR \fIyear1\fR \fBTHROUGH\fR \fIday2\fR \fImonth2\fR \fIyear2\fR
|
||||
\fBOMIT\fR [\fIday1\fR] \fImonth1\fR [\fIyear1\fR] \fBTHROUGH\fR [\fIday2\fR] \fImonth2\fR [\fIyear2\fR]
|
||||
.RE
|
||||
.PP
|
||||
The \fBOMIT\fR command is used to "globally" omit certain days
|
||||
@@ -1545,8 +1558,13 @@ The \fBOMIT\fR command is used to "globally" omit certain days
|
||||
"\-\-" and "\+\+" forms. Some examples:
|
||||
.PP
|
||||
.nf
|
||||
OMIT 1 Jan
|
||||
OMIT 7 Sep 1992
|
||||
OMIT 1 Jan
|
||||
OMIT 7 Sep 1992
|
||||
OMIT 15 Jan THROUGH 14 Feb
|
||||
OMIT May # Equivalent to OMIT May 1 THROUGH May 31
|
||||
OMIT 25 Dec THROUGH 4 Jan
|
||||
OMIT 2023-05-03 THROUGH 2023-05-12
|
||||
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
|
||||
@@ -1578,9 +1596,7 @@ equivalent:
|
||||
.fi
|
||||
.PP
|
||||
The \fBTHROUGH\fR keyword lets you conveniently OMIT a range of days.
|
||||
The starting and ending points must be fully-specified (ie, they must
|
||||
include day, month and year.). For example, the following sequences
|
||||
are equivalent:
|
||||
For example, the following sequences are equivalent:
|
||||
.PP
|
||||
.nf
|
||||
OMIT 3 Jan 2011
|
||||
@@ -1592,12 +1608,28 @@ are equivalent:
|
||||
OMIT 3 Jan 2011 THROUGH 5 Jan 2011
|
||||
.fi
|
||||
.PP
|
||||
You can make a THROUGH \fBOMIT\fR do double-duty as a \fBREM\fR command:
|
||||
You can make a THROUGH \fBOMIT\fR do double-duty as a \fBREM\fR command as
|
||||
long as both dates are fully specified
|
||||
.PP
|
||||
.nf
|
||||
OMIT 6 Sep 2010 THROUGH 10 Sep 2010 MSG Vacation
|
||||
.fi
|
||||
|
||||
.PP
|
||||
If you use a THROUGH clause, then either the year must be supplied before
|
||||
and after the THROUGH, or it must be missing before and after the THROUGH.
|
||||
The following are legal:
|
||||
.PP
|
||||
.nf
|
||||
OMIT 25 Dec THROUGH 6 Jan
|
||||
OMIT 25 Dec 2024 THROUGH 6 Jan 2025
|
||||
.fi
|
||||
.PP
|
||||
But the following are not:
|
||||
.PP
|
||||
.nf
|
||||
OMIT 25 Dec THROUGH 6 Jan 2025
|
||||
OMIT 25 Dec 2024 THROUGH 6 Jan
|
||||
.nf
|
||||
.PP
|
||||
You can debug your global OMITs with the following command:
|
||||
.PP
|
||||
@@ -1706,6 +1738,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
|
||||
@@ -2342,8 +2380,8 @@ For example, the coordinates of the Statue of Liberty in New York City
|
||||
are approximately set by:
|
||||
.PP
|
||||
.nf
|
||||
SET $Latitude "40.68933"
|
||||
SET $Longitude "-74.04454"
|
||||
SET $Latitude "40.68933"
|
||||
SET $Longitude "-74.04454"
|
||||
.fi
|
||||
.RE
|
||||
.TP
|
||||
@@ -2812,6 +2850,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()
|
||||
@@ -3236,9 +3281,24 @@ 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 integers, emits a "Number too high" error.
|
||||
to represent as an integer, emits a "Number too high" error.
|
||||
.TP
|
||||
.B substr(s_str, i_start [,i_end])
|
||||
Returns a \fBSTRING\fR consisting of all characters in \fIstr\fR from
|
||||
@@ -4825,7 +4885,7 @@ Suppose you want to change the "%b" sequence to substitute "the day
|
||||
after tomorrow" for an event two days from now. You could do this:
|
||||
.PP
|
||||
.nf
|
||||
FSET subst_bx(a,d,t) iif(d==today()+2, "the day after tomorrow", \
|
||||
FSET subst_bx(a,d,t) iif(d==today()+2, "the day after tomorrow", \\
|
||||
"in " + (d-today()) + " days' time")
|
||||
REM [today()+3] ++3 MSG Event 1 is %b%
|
||||
REM [today()+2] ++3 MSG Event 2 is %b%
|
||||
@@ -5439,7 +5499,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)
|
||||
@@ -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
|
||||
@@ -18,13 +18,13 @@ as well as the tcllib extension. It also requires a \fBwish\fR
|
||||
binary. If you are using Tcl/Tk 8.5, you may also need either the Img
|
||||
or the tkpng extension to handle PNG images.
|
||||
|
||||
.SH OPTIONS
|
||||
\fBTkRemind\fR itself has no options. However, it passes certain options
|
||||
on to \fBRemind\fR. The options it passes are
|
||||
\fB\-b\fR, \fB\-g\fR, \fB\-x\fR, \fB\-i\fR and \fB\-m\fR.
|
||||
See the \fBRemind\fR man page for details about the options.
|
||||
Note that \fBTkRemind\fR will respect the \fB\-m\fR and
|
||||
\fB\-b1\fR options and adjust its appearance accordingly.
|
||||
.SH COMMAND-LINE OPTIONS
|
||||
\fBTkRemind\fR itself has no command-line options. However, it passes
|
||||
certain options on to \fBRemind\fR. The options it passes are
|
||||
\fB\-b\fR, \fB\-g\fR, \fB\-x\fR, \fB\-i\fR and \fB\-m\fR. See the
|
||||
\fBRemind\fR man page for details about the options. Note that
|
||||
\fBTkRemind\fR will respect the \fB\-m\fR and \fB\-b1\fR options and
|
||||
adjust its appearance accordingly.
|
||||
|
||||
\fIRead_file\fR is the file from which \fBTkRemind\fR reads reminders.
|
||||
It is in standard \fBRemind\fR format. \fIWrite_file\fR is the file
|
||||
@@ -44,8 +44,14 @@ include the line:
|
||||
.PP
|
||||
|
||||
\fIConfig_file\fR is the file in which \fBTkRemind\fR stores
|
||||
its options. If it is omitted, it defaults to \fI$HOME/.tkremindrt\fR.
|
||||
its options. If it is omitted, it defaults to \fI$HOME/.config/tkremindrc\fR.
|
||||
|
||||
.PP
|
||||
If \fB$HOME/.reminders\fR is a \fIdirectory\fR, then \fBTkRemind\fR defaults to
|
||||
reading \fB$HOME/.reminders\fR and writing new reminders to
|
||||
\fB$HOME/.reminders/100-tkremind.rem\fR. If you want to keep your
|
||||
reminders in a directory \fB$HOME/.reminders\fR, you should create that
|
||||
directory before starting \fBTkRemind\fR.
|
||||
.SH THE CALENDAR WINDOW
|
||||
When you start \fBTkRemind\fR, it displays a calendar for the current
|
||||
month, with today's date highlighted. Reminders are filled into each
|
||||
@@ -274,7 +280,7 @@ Similar to Change entry font, but applies to calendar heading
|
||||
.PP
|
||||
Once you've configured the options the way you like them,
|
||||
press \fBApply Options\fR to put them into effect, \fBSave Options\fR
|
||||
to put them into effect and save them in $HOME/.tkremindrc, or
|
||||
to put them into effect and save them in $HOME/.config/tkremindrc, or
|
||||
\fBCancel\fR to cancel any changes you made.
|
||||
|
||||
.SH KEYBOARD SHORTCUTS
|
||||
@@ -293,6 +299,19 @@ Next Month
|
||||
.B Home
|
||||
Today
|
||||
|
||||
.SH IMMEDIATE UPDATES
|
||||
|
||||
If you are running \fBTkRemind\fR on Linux and have the
|
||||
\fBinotifywait\fR program installed (part of the \fBinotify-tools\fR
|
||||
or similar package), then \fBTkRemind\fR redraws the calendar window
|
||||
\fIimmediately\fR if \fB$HOME/.reminders\fR changes (or, if it is a
|
||||
directory, any files in that directory change.)
|
||||
.PP
|
||||
This lets \fBTkRemind\fR react immediately to hand-edited reminders or
|
||||
to reminder files that are imported from another calendar system (for example,
|
||||
you may have a cron job that periodically imports your Google Calendar
|
||||
entries into Remind format.)
|
||||
|
||||
.SH ODDS AND ENDS
|
||||
\fBTkRemind\fR performs some basic consistency checks when you add or
|
||||
preview a reminder. However, if you edit a reminder in the previewer,
|
||||
@@ -323,8 +342,7 @@ You can use this to activate certain reminders in different ways
|
||||
for \fBTkRemind\fR (for example).
|
||||
.PP
|
||||
\fBTkRemind\fR uses tags to keep track of reminders in the
|
||||
script file. It also places special comments in the reminder
|
||||
file to store additional state. You can certainly mix
|
||||
script file. You can certainly mix
|
||||
"hand-crafted" reminders with reminders created by \fBTkRemind\fR
|
||||
if you are aware of the following rules and limitations:
|
||||
.TP
|
||||
@@ -334,15 +352,16 @@ where \fInnn\fR is a number. You should not use such \fBTAG\fRs
|
||||
in hand-crafted reminders.
|
||||
.TP
|
||||
o
|
||||
Do not edit lines starting with "# TKTAGnnn", "# TKEND", or any
|
||||
lines in between. You can move such lines, but be careful to move
|
||||
them as a single block.
|
||||
.TP
|
||||
o
|
||||
Hand-crafted reminders cannot be edited with \fBTkRemind\fR, and
|
||||
for hand-crafted timed reminders, you will not be presented with
|
||||
the "Don't remind me again" option when they pop up.
|
||||
|
||||
.PP
|
||||
However, rather than mixing hand-edited files with \fBTkRemind\fR-generated
|
||||
ones, it is better to make \fB$HOME/.reminders\fR a directory and keep
|
||||
your hand-edited files in a separate \fB*.rem\fR file than \fBTkRemind\fR's
|
||||
\fB100-tkremind.rem\fR file.
|
||||
|
||||
.SH SERVER MODE
|
||||
|
||||
\fBRemind\fR has a special mode for interacting with programs like
|
||||
@@ -400,14 +419,16 @@ This line is emitted in response to a \fBSTATUS\fR command. The number
|
||||
.SH AUTHOR
|
||||
TkRemind was written by Dianne Skoll <dianne@skoll.ca>
|
||||
|
||||
\fBTkRemind\fR is Copyright 1996-2020 by Dianne Skoll.
|
||||
\fBTkRemind\fR is Copyright 1996-2022 by Dianne Skoll.
|
||||
|
||||
.SH FILES
|
||||
|
||||
$HOME/.reminders -- default reminder file.
|
||||
$HOME/.reminders -- default reminder file or directory.
|
||||
|
||||
$HOME/.tkremindrc -- \fBTkRemind\fR saved options.
|
||||
$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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -227,14 +227,16 @@ sub parse_oldstyle_line
|
||||
|
||||
if ($hash->{passthru}) {
|
||||
if ($hash->{passthru} =~ /^(shade|color|colour)$/i) {
|
||||
if ($hash->{body} =~ /^\s*(\d+)\s+(\d+)\s+(\d+)/) {
|
||||
if ($hash->{body} =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s*(.*)/) {
|
||||
$hash->{r} = $1;
|
||||
$hash->{g} = $2;
|
||||
$hash->{b} = $3;
|
||||
} elsif ($hash->{body} =~ /^\s*(\d+)/) {
|
||||
$hash->{body} = $4;
|
||||
} elsif ($hash->{body} =~ /^\s*(\d+)\s*(.*)/) {
|
||||
$hash->{r} = $1;
|
||||
$hash->{g} = $1;
|
||||
$hash->{b} = $1;
|
||||
$hash->{body} = $2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,15 @@ sub render
|
||||
|
||||
$layout->set_width(1024 * ($x2 - $x1 - 2 * $settings->{border_size}));
|
||||
$layout->set_wrap('word-char');
|
||||
$layout->set_text(Encode::decode('UTF-8', $self->{body}));
|
||||
my $body;
|
||||
if (exists($self->{calendar_body})) {
|
||||
$body = $self->{calendar_body};
|
||||
} elsif (exists($self->{plain_body})) {
|
||||
$body = $self->{plain_body};
|
||||
} else {
|
||||
$body = $self->{body};
|
||||
}
|
||||
$layout->set_text(Encode::decode('UTF-8', $body));
|
||||
my $desc = Pango::FontDescription->from_string($settings->{entry_font} . ' ' . $settings->{entry_size} . 'px');
|
||||
$layout->set_font_description($desc);
|
||||
my ($wid, $h) = $layout->get_pixel_size();
|
||||
@@ -233,11 +241,9 @@ sub _adjust
|
||||
package Remind::PDF::Entry::color;
|
||||
use base 'Remind::PDF::Entry';
|
||||
|
||||
# Strip the RGB prefix from body
|
||||
# Nothing to do for COLOR-type reminder
|
||||
sub _adjust
|
||||
{
|
||||
my ($self) = @_;
|
||||
$self->{body} =~ s/^\d+\s+\d+\s+\d+\s+//;
|
||||
}
|
||||
|
||||
package Remind::PDF::Entry::postscript;
|
||||
|
||||
@@ -547,7 +547,9 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
$w.t$i configure -state disabled -takefocus 0
|
||||
}
|
||||
for {set i $first} {$i <= $last} {incr i} {
|
||||
set row [expr ($i/7)+1]
|
||||
grid $w.f$i
|
||||
grid rowconfigure $w $row -weight 1
|
||||
pack $w.l$i -in $w.f$i -side top -expand 0 -fill x
|
||||
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
|
||||
raise $w.l$i
|
||||
@@ -581,7 +583,7 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
pack $w.t$i -in $w.f$i -side top -expand 1 -fill both
|
||||
raise $w.l$i
|
||||
raise $w.t$i
|
||||
grid rowconfigure $w [expr $row+1] -weight 1
|
||||
grid rowconfigure $w $row -weight 1
|
||||
}
|
||||
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
$w.l$i configure -state disabled
|
||||
@@ -1089,8 +1091,13 @@ proc FillCalWindow {} {
|
||||
} else {
|
||||
set tag "*"
|
||||
}
|
||||
set stuff [dict get $obj body]
|
||||
|
||||
if {[dict exists $obj calendar_body]} {
|
||||
set stuff [dict get $obj calendar_body]
|
||||
} elseif {[dict exists $obj plain_body]} {
|
||||
set stuff [dict get $obj plain_body]
|
||||
} else {
|
||||
set stuff [dict get $obj body]
|
||||
}
|
||||
set day [string trimleft $day 0]
|
||||
set n [expr $day+$offset]
|
||||
set month [string trimleft $month 0]
|
||||
@@ -1114,30 +1121,31 @@ proc FillCalWindow {} {
|
||||
}
|
||||
"COLOUR" -
|
||||
"COLOR" {
|
||||
if {[regexp {^ *([0-9]+) +([0-9]+) +([0-9]+) +(.*)$} $stuff all r g b rest]} {
|
||||
if {$r > 255} {
|
||||
set r 255
|
||||
} elseif {$r < 0} {
|
||||
set r 0
|
||||
}
|
||||
if {$g > 255} {
|
||||
set g 255
|
||||
} elseif {$g < 0} {
|
||||
set g 0
|
||||
}
|
||||
if {$b > 255} {
|
||||
set b 255
|
||||
} elseif {$b < 0} {
|
||||
set b 0
|
||||
}
|
||||
set color [format "%02X%02X%02X" $r $g $b]
|
||||
set extratags "clr$color"
|
||||
.cal.t$n configure -state normal
|
||||
.cal.t$n tag configure $extratags -foreground "#$color"
|
||||
.cal.t$n configure -state disabled -takefocus 0
|
||||
set stuff $rest
|
||||
set type "COLOR"
|
||||
}
|
||||
set r [dict get $obj r]
|
||||
set g [dict get $obj g]
|
||||
set b [dict get $obj b]
|
||||
if {$r > 255} {
|
||||
set r 255
|
||||
} elseif {$r < 0} {
|
||||
set r 0
|
||||
}
|
||||
if {$g > 255} {
|
||||
set g 255
|
||||
} elseif {$g < 0} {
|
||||
set g 0
|
||||
}
|
||||
if {$b > 255} {
|
||||
set b 255
|
||||
} elseif {$b < 0} {
|
||||
set b 0
|
||||
}
|
||||
set color [format "%02X%02X%02X" $r $g $b]
|
||||
set extratags "clr$color"
|
||||
.cal.t$n configure -state normal
|
||||
.cal.t$n tag configure $extratags -foreground "#$color"
|
||||
.cal.t$n configure -state disabled -takefocus 0
|
||||
set stuff $stuff
|
||||
set type "COLOR"
|
||||
}
|
||||
}
|
||||
if { $type != "*" && $type != "COLOR" && $type != "COLOUR"} {
|
||||
@@ -2104,7 +2112,7 @@ proc CreateReminder {w} {
|
||||
|
||||
# Check it out!
|
||||
global Remind
|
||||
set f [open "|$Remind -arq -e - 2>&1" r+]
|
||||
set f [open "|$Remind -arq -e - 2>@1" r+]
|
||||
puts $f "BANNER %"
|
||||
puts $f "$rem MSG %"
|
||||
puts $f "MSG %_%_%_%_"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
439
src/calendar.c
439
src/calendar.c
@@ -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)
|
||||
{
|
||||
@@ -293,6 +375,19 @@ despace(char const *s)
|
||||
return buf;
|
||||
}
|
||||
|
||||
void PrintJSONChar(char c) {
|
||||
switch(c) {
|
||||
case '\b': printf("\\b"); break;
|
||||
case '\f': printf("\\f"); break;
|
||||
case '\n': printf("\\n"); break;
|
||||
case '\r': printf("\\r"); break;
|
||||
case '\t': printf("\\t"); break;
|
||||
case '"': printf("\\\""); break;
|
||||
case '\\': printf("\\\\"); break;
|
||||
default: printf("%c", c);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintJSONString(char const *s)
|
||||
{
|
||||
while (*s) {
|
||||
@@ -497,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;
|
||||
@@ -515,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)) +
|
||||
@@ -527,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;
|
||||
}
|
||||
@@ -562,20 +667,24 @@ 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
|
||||
@@ -599,6 +708,92 @@ ComputeCalWidth(int x)
|
||||
return w.ws_col;
|
||||
}
|
||||
|
||||
static void
|
||||
InitMoonsAndShades(void)
|
||||
{
|
||||
int i;
|
||||
/* Initialize the moon array */
|
||||
if (encoding_is_utf8) {
|
||||
for (i=0; i<=31; i++) {
|
||||
moons[i][0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear SHADEs */
|
||||
if (UseBGVTChars) {
|
||||
for (i=0; i<=31; i++) {
|
||||
bgcolor[i][0] = -1;
|
||||
bgcolor[i][1] = -1;
|
||||
bgcolor[i][2] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear weeks */
|
||||
for(i=0; i<=31; i++) {
|
||||
weeks[i][0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
@@ -681,18 +876,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);
|
||||
}
|
||||
@@ -704,13 +903,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();
|
||||
@@ -721,7 +940,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();
|
||||
@@ -732,7 +954,7 @@ static void DoCalendarOneWeek(int nleft)
|
||||
/* Write the body lines */
|
||||
done = 0;
|
||||
while (!done) {
|
||||
done = WriteOneCalLine();
|
||||
done = WriteOneCalLine(OrigJul, wd);
|
||||
LinesWritten++;
|
||||
}
|
||||
|
||||
@@ -742,7 +964,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();
|
||||
@@ -769,6 +994,8 @@ static void DoCalendarOneMonth(void)
|
||||
{
|
||||
int y, m, d, mm, yy, i, j;
|
||||
|
||||
InitMoonsAndShades();
|
||||
|
||||
if (!DoSimpleCalendar) WriteCalHeader();
|
||||
|
||||
DidADay = 0;
|
||||
@@ -869,10 +1096,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++;
|
||||
}
|
||||
|
||||
@@ -895,9 +1127,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, ' ');
|
||||
@@ -913,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();
|
||||
@@ -924,7 +1176,7 @@ static int WriteCalendarRow(void)
|
||||
/* Write the body lines */
|
||||
done = 0;
|
||||
while (!done) {
|
||||
done = WriteOneCalLine();
|
||||
done = WriteOneCalLine(OrigJul, wd);
|
||||
LinesWritten++;
|
||||
}
|
||||
|
||||
@@ -934,7 +1186,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();
|
||||
@@ -1105,19 +1359,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();
|
||||
@@ -1146,9 +1406,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) {
|
||||
@@ -1191,7 +1454,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. */
|
||||
@@ -1228,9 +1491,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 */
|
||||
@@ -1283,7 +1547,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. */
|
||||
@@ -1311,9 +1575,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 */
|
||||
@@ -1587,6 +1852,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);
|
||||
@@ -1650,10 +1928,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;
|
||||
@@ -1912,6 +2229,7 @@ static void WriteSimpleEntryProtocol1(CalEntry *e)
|
||||
static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
|
||||
{
|
||||
int done = 0;
|
||||
char const *s;
|
||||
if (DoPrefixLineNo) {
|
||||
PrintJSONKeyPairString("filename", e->filename);
|
||||
PrintJSONKeyPairInt("lineno", e->lineno);
|
||||
@@ -2038,6 +2356,45 @@ static void WriteSimpleEntryProtocol2(CalEntry *e, int today)
|
||||
if (strcmp(e->raw_text, e->text)) {
|
||||
PrintJSONKeyPairString("rawbody", e->raw_text);
|
||||
}
|
||||
|
||||
/* Figure out calendar_body and plain_body */
|
||||
if (DontSuppressQuoteMarkers) {
|
||||
s = strstr(e->text, "%\"");
|
||||
if (s) {
|
||||
s += 2;
|
||||
printf("\"calendar_body\":\"");
|
||||
while (*s) {
|
||||
if (*s == '%' && *(s+1) == '"') {
|
||||
break;
|
||||
}
|
||||
PrintJSONChar(*s);
|
||||
s++;
|
||||
}
|
||||
printf("\",");
|
||||
}
|
||||
}
|
||||
s = strstr(e->text, "%\"");
|
||||
if (s || e->is_color) {
|
||||
printf("\"plain_body\":\"");
|
||||
s = e->text;
|
||||
if (e->is_color) {
|
||||
while(*s && !isspace(*s)) s++;
|
||||
while(*s && isspace(*s)) s++;
|
||||
while(*s && !isspace(*s)) s++;
|
||||
while(*s && isspace(*s)) s++;
|
||||
while(*s && !isspace(*s)) s++;
|
||||
while(*s && isspace(*s)) s++;
|
||||
}
|
||||
while(*s) {
|
||||
if (*s == '%' && *(s+1) == '"') {
|
||||
s += 2;
|
||||
continue;
|
||||
}
|
||||
PrintJSONChar(*s);
|
||||
s++;
|
||||
}
|
||||
printf("\",");
|
||||
}
|
||||
printf("\"body\":\"");
|
||||
PrintJSONString(e->text);
|
||||
printf("\"");
|
||||
|
||||
13
src/dorem.c
13
src/dorem.c
@@ -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) {
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
#define E_MON_TWICE 51
|
||||
#define E_DAY_TWICE 52
|
||||
#define E_UNKNOWN_TOKEN 53
|
||||
#define E_SPEC_MON_DAY 54
|
||||
#define E_SPEC_MON 54
|
||||
#define E_2MANY_PART 55
|
||||
#define E_2MANY_FULL 56
|
||||
#define E_PUSH_NOPOP 57
|
||||
@@ -187,7 +187,7 @@ EXTERN char *ErrMsg[]
|
||||
"Month specified twice",
|
||||
"Day specified twice",
|
||||
"Unknown token",
|
||||
"Must specify month and day in OMIT command",
|
||||
"Must specify month in OMIT command",
|
||||
"Too many partial OMITs",
|
||||
"Too many full OMITs",
|
||||
"Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT",
|
||||
|
||||
31
src/funcs.c
31
src/funcs.c
@@ -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" */
|
||||
|
||||
@@ -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);
|
||||
|
||||
37
src/init.c
37
src/init.c
@@ -43,7 +43,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
|
||||
@@ -233,22 +234,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':
|
||||
@@ -689,7 +704,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");
|
||||
|
||||
@@ -195,7 +195,7 @@ EXTERN char *ErrMsg[] =
|
||||
"Kuukausi annettu kahdesti",
|
||||
"Päivä annettu kahdesti",
|
||||
"Tuntematon sana tai merkki",
|
||||
"OMIT-komennossa on annettava kuukausi ja päivä",
|
||||
"OMIT-komennossa on annettava kuukausi",
|
||||
"Liian monta osittaista OMIT-komentoa",
|
||||
"Liian monta täydellistä OMIT-komentoa",
|
||||
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
|
||||
|
||||
@@ -185,7 +185,7 @@ EXTERN char *ErrMsg[] =
|
||||
"Miesiąc podany dwókrotnie",
|
||||
"Dzień podany dwókrotnie",
|
||||
"Nieznane słowo",
|
||||
"W komendzie OMIT trzeba podać miesiąc i dzień",
|
||||
"W komendzie OMIT trzeba podać miesiąc",
|
||||
"Za dużo częściowych komend OMIT",
|
||||
"Za dużo pełnych komend OMIT",
|
||||
"Ostrzeżenie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",
|
||||
|
||||
@@ -194,7 +194,7 @@ EXTERN char *ErrMsg[] =
|
||||
"Mes especificado duas vezes",
|
||||
"Dia especificado duas vezes",
|
||||
"Token desconhecido",
|
||||
"Mes e dia devem ser especificados no comando OMIT",
|
||||
"O mes deve ser especificados no comando OMIT",
|
||||
"Muitos OMITs parciais",
|
||||
"Muitos OMITs full",
|
||||
"Aviso: PUSH-OMIT-CONTEXT sem POP-OMIT-CONTEXT correspondente",
|
||||
|
||||
43
src/main.c
43
src/main.c
@@ -329,7 +329,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 +359,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 +864,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++;
|
||||
@@ -1357,13 +1364,23 @@ void UTCToLocal(int utcdate, int utctime, int *locdate, int *loctime)
|
||||
/* command-line flag is supplied. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static sig_atomic_t got_sigint = 0;
|
||||
|
||||
void SigIntHandler(int d)
|
||||
void
|
||||
SigIntHandler(int d)
|
||||
{
|
||||
UNUSED(d);
|
||||
signal(SIGINT, SigIntHandler);
|
||||
GotSigInt();
|
||||
exit(0);
|
||||
got_sigint = 1;
|
||||
}
|
||||
|
||||
int
|
||||
GotSigInt(void)
|
||||
{
|
||||
if (got_sigint) {
|
||||
got_sigint = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
214
src/omit.c
214
src/omit.c
@@ -271,7 +271,6 @@ static void InsertIntoSortedArray(int *array, int num, int key)
|
||||
*cur = key;
|
||||
}
|
||||
|
||||
static int DoThroughOmit(ParsePtr p, int y, int m, int d);
|
||||
static void DumpOmits(void);
|
||||
|
||||
/***************************************************************/
|
||||
@@ -283,11 +282,15 @@ static void DumpOmits(void);
|
||||
/***************************************************************/
|
||||
int DoOmit(ParsePtr p)
|
||||
{
|
||||
int y = NO_YR, m = NO_MON, d = NO_DAY, r;
|
||||
int y[2] = {NO_YR, NO_YR}, m[2] = {NO_MON, NO_MON}, d[2] = {NO_DAY, NO_DAY}, r;
|
||||
Token tok;
|
||||
int parsing=1;
|
||||
int parsing = 1;
|
||||
int seen_through = 0;
|
||||
int syndrome;
|
||||
int not_first_token = -1;
|
||||
int start, end, tmp;
|
||||
|
||||
int mc, dc;
|
||||
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
@@ -308,28 +311,28 @@ int DoOmit(ParsePtr p)
|
||||
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) return E_YR_TWICE;
|
||||
if (m != NO_MON) return E_MON_TWICE;
|
||||
if (d != NO_DAY) return E_DAY_TWICE;
|
||||
FromJulian(tok.val, &y, &m, &d);
|
||||
if (y[seen_through] != NO_YR) return E_YR_TWICE;
|
||||
if (m[seen_through] != NO_MON) return E_MON_TWICE;
|
||||
if (d[seen_through] != NO_DAY) return E_DAY_TWICE;
|
||||
FromJulian(tok.val, &y[seen_through], &m[seen_through], &d[seen_through]);
|
||||
break;
|
||||
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) return E_YR_TWICE;
|
||||
y = tok.val;
|
||||
if (y[seen_through] != NO_YR) return E_YR_TWICE;
|
||||
y[seen_through] = tok.val;
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
DBufFree(&buf);
|
||||
if (m != NO_MON) return E_MON_TWICE;
|
||||
m = tok.val;
|
||||
if (m[seen_through] != NO_MON) return E_MON_TWICE;
|
||||
m[seen_through] = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
DBufFree(&buf);
|
||||
if (d != NO_DAY) return E_DAY_TWICE;
|
||||
d = tok.val;
|
||||
if (d[seen_through] != NO_DAY) return E_DAY_TWICE;
|
||||
d[seen_through] = tok.val;
|
||||
break;
|
||||
|
||||
case T_Delta:
|
||||
@@ -338,8 +341,9 @@ int DoOmit(ParsePtr p)
|
||||
|
||||
case T_Through:
|
||||
DBufFree(&buf);
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) return E_INCOMPLETE;
|
||||
return DoThroughOmit(p, y, m, d);
|
||||
if (seen_through) return E_UNTIL_TWICE;
|
||||
seen_through = 1;
|
||||
break;
|
||||
|
||||
case T_Empty:
|
||||
case T_Comment:
|
||||
@@ -358,26 +362,85 @@ int DoOmit(ParsePtr p)
|
||||
return E_UNKNOWN_TOKEN;
|
||||
}
|
||||
}
|
||||
if (m == NO_MON || d == NO_DAY) return E_SPEC_MON_DAY;
|
||||
|
||||
if (y == NO_YR) {
|
||||
if (NumPartialOmits == MAX_PARTIAL_OMITS) return E_2MANY_PART;
|
||||
|
||||
if (d > MonthDays[m]) return E_BAD_DATE;
|
||||
syndrome = (m<<5) + d;
|
||||
if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
|
||||
InsertIntoSortedArray(PartialOmitArray, NumPartialOmits, syndrome);
|
||||
NumPartialOmits++;
|
||||
}
|
||||
if (!seen_through) {
|
||||
/* We must have at least a month */
|
||||
if (m[0] == NO_MON) return E_SPEC_MON;
|
||||
m[1] = m[0];
|
||||
y[1] = y[0];
|
||||
if (d[0] == NO_DAY) {
|
||||
d[0] = 1;
|
||||
if (y[0] == NO_YR) {
|
||||
d[1] = MonthDays[m[0]];
|
||||
} else {
|
||||
d[1] = DaysInMonth(m[0], y[0]);
|
||||
}
|
||||
} else {
|
||||
d[1] = d[0];
|
||||
m[1] = m[0];
|
||||
y[1] = y[0];
|
||||
}
|
||||
} else {
|
||||
|
||||
if (d > DaysInMonth(m, y)) return E_BAD_DATE;
|
||||
syndrome = Julian(y, m, d);
|
||||
r = AddGlobalOmit(syndrome);
|
||||
if (r) {
|
||||
return r;
|
||||
if (m[0] == NO_MON) return E_SPEC_MON;
|
||||
if (m[1] == NO_MON) return E_SPEC_MON;
|
||||
if ((y[0] != NO_YR && y[1] == NO_YR) ||
|
||||
(y[0] == NO_YR && y[1] != NO_YR)) {
|
||||
return E_BAD_DATE;
|
||||
}
|
||||
if (d[0] == NO_DAY) d[0] = 1;
|
||||
if (d[1] == NO_DAY) {
|
||||
if (y[1] == NO_YR) {
|
||||
d[1] = MonthDays[m[1]];
|
||||
} else {
|
||||
d[1] = DaysInMonth(m[1], y[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (y[0] == NO_YR) {
|
||||
/* Partial OMITs */
|
||||
if (d[0] > MonthDays[m[0]]) return E_BAD_DATE;
|
||||
if (d[1] > MonthDays[m[1]]) return E_BAD_DATE;
|
||||
dc = d[0];
|
||||
mc = m[0];
|
||||
while(1) {
|
||||
syndrome = (mc<<5) + dc;
|
||||
if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
|
||||
InsertIntoSortedArray(PartialOmitArray, NumPartialOmits, syndrome);
|
||||
NumPartialOmits++;
|
||||
}
|
||||
if (mc == m[1] && dc == d[1]) {
|
||||
break;
|
||||
}
|
||||
dc++;
|
||||
if (dc > MonthDays[mc]) {
|
||||
dc = 1;
|
||||
mc++;
|
||||
if (mc > 11) {
|
||||
mc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Full OMITs */
|
||||
if (d[0] > DaysInMonth(m[0], y[0])) return E_BAD_DATE;
|
||||
if (d[1] > DaysInMonth(m[1], y[1])) return E_BAD_DATE;
|
||||
start = Julian(y[0], m[0], d[0]);
|
||||
end = Julian(y[1], m[1], d[1]);
|
||||
if (end < start) {
|
||||
Eprint("Error: THROUGH date earlier than start date");
|
||||
return E_BAD_DATE;
|
||||
}
|
||||
|
||||
for (tmp = start; tmp <= end; tmp++) {
|
||||
if (!BexistsIntArray(FullOmitArray, NumFullOmits, tmp)) {
|
||||
if (NumFullOmits >= MAX_FULL_OMITS) return E_2MANY_FULL;
|
||||
InsertIntoSortedArray(FullOmitArray, NumFullOmits, tmp);
|
||||
NumFullOmits++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
|
||||
return OK;
|
||||
|
||||
@@ -394,95 +457,6 @@ AddGlobalOmit(int jul)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int
|
||||
DoThroughOmit(ParsePtr p, int ystart, int mstart, int dstart)
|
||||
{
|
||||
int yend = NO_YR, mend = NO_MON, dend = NO_DAY, r;
|
||||
int start, end, tmp;
|
||||
int parsing = 1;
|
||||
|
||||
Token tok;
|
||||
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
|
||||
while(parsing) {
|
||||
if ( (r=ParseToken(p, &buf)) ) return r;
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
|
||||
switch(tok.type) {
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (yend != NO_YR) return E_YR_TWICE;
|
||||
if (mend != NO_MON) return E_MON_TWICE;
|
||||
if (dend != NO_DAY) return E_DAY_TWICE;
|
||||
FromJulian(tok.val, ¥d, &mend, &dend);
|
||||
break;
|
||||
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (yend != NO_YR) return E_YR_TWICE;
|
||||
yend = tok.val;
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
DBufFree(&buf);
|
||||
if (mend != NO_MON) return E_MON_TWICE;
|
||||
mend = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
DBufFree(&buf);
|
||||
if (dend != NO_DAY) return E_DAY_TWICE;
|
||||
dend = tok.val;
|
||||
break;
|
||||
|
||||
case T_Empty:
|
||||
case T_Comment:
|
||||
case T_RemType:
|
||||
case T_Priority:
|
||||
case T_Tag:
|
||||
case T_Duration:
|
||||
DBufFree(&buf);
|
||||
parsing = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
Eprint("%s: `%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN],
|
||||
DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
return E_UNKNOWN_TOKEN;
|
||||
|
||||
}
|
||||
}
|
||||
if (yend == NO_YR || mend == NO_MON || dend == NO_DAY) return E_INCOMPLETE;
|
||||
if (dend > DaysInMonth(mend, yend)) return E_BAD_DATE;
|
||||
if (dstart > DaysInMonth(mstart, ystart)) return E_BAD_DATE;
|
||||
|
||||
start = Julian(ystart, mstart, dstart);
|
||||
end = Julian(yend, mend, dend);
|
||||
|
||||
if (end < start) {
|
||||
Wprint("Warning: Swapping dates on OMIT ... THROUGH ... line");
|
||||
tmp = start;
|
||||
start = end;
|
||||
end = tmp;
|
||||
}
|
||||
|
||||
tmp = end - start + 1;
|
||||
|
||||
/* Don't create any OMITs if there would be too many. */
|
||||
if (NumFullOmits + tmp >= MAX_FULL_OMITS) return E_2MANY_FULL;
|
||||
for (tmp = start; tmp <= end; tmp++) {
|
||||
if (!BexistsIntArray(FullOmitArray, NumFullOmits, tmp)) {
|
||||
InsertIntoSortedArray(FullOmitArray, NumFullOmits, tmp);
|
||||
NumFullOmits++;
|
||||
}
|
||||
}
|
||||
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void
|
||||
DumpOmits(void)
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define isempty(c) (isspace(c) || ((c) == '\\'))
|
||||
|
||||
#include "dynbuf.h"
|
||||
#include <ctype.h>
|
||||
|
||||
int CallUserFunc (char const *name, int nargs, ParsePtr p);
|
||||
int DoFset (ParsePtr p);
|
||||
@@ -143,7 +144,7 @@ int MoonPhase (int date, int time);
|
||||
void HuntPhase (int startdate, int starttim, int phas, int *date, int *time);
|
||||
int CompareRems (int dat1, int tim1, int prio1, int dat2, int tim2, int prio2, int bydate, int bytime, int byprio, int untimed_first);
|
||||
void SigIntHandler (int d);
|
||||
void GotSigInt (void);
|
||||
int GotSigInt (void);
|
||||
void PurgeEchoLine(char const *fmt, ...);
|
||||
void FreeTrig(Trigger *t);
|
||||
void AppendTag(DynamicBuffer *buf, char const *s);
|
||||
@@ -154,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);
|
||||
|
||||
23
src/queue.c
23
src/queue.c
@@ -59,6 +59,7 @@ static QueuedRem *FindNextReminder (void);
|
||||
static int CalculateNextTimeUsingSched (QueuedRem *q);
|
||||
static void DaemonWait (struct timeval *sleep_tv);
|
||||
static void reread (void);
|
||||
static void PrintQueue(void);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -123,9 +124,10 @@ void HandleQueuedReminders(void)
|
||||
Trigger trig;
|
||||
struct timeval tv;
|
||||
struct timeval sleep_tv;
|
||||
struct sigaction sa;
|
||||
|
||||
/* Suppress the BANNER from being issued */
|
||||
NumTriggered = 1;
|
||||
DidMsgReminder = 1;
|
||||
|
||||
/* Turn off sorting -- otherwise, TriggerReminder has no effect! */
|
||||
SortByDate = 0;
|
||||
@@ -161,7 +163,11 @@ void HandleQueuedReminders(void)
|
||||
q = q->next;
|
||||
}
|
||||
|
||||
if (!DontFork || Daemon) signal(SIGINT, SigIntHandler);
|
||||
if (!DontFork || Daemon) {
|
||||
sa.sa_handler = SigIntHandler;
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGINT, &sa, NULL);
|
||||
}
|
||||
|
||||
/* Sit in a loop, issuing reminders when necessary */
|
||||
while(1) {
|
||||
@@ -205,6 +211,10 @@ void HandleQueuedReminders(void)
|
||||
sleep(SleepTime);
|
||||
}
|
||||
|
||||
if (GotSigInt()) {
|
||||
PrintQueue();
|
||||
}
|
||||
|
||||
/* If not in daemon mode and day has rolled around,
|
||||
exit -- not much we can do. */
|
||||
if (!Daemon) {
|
||||
@@ -337,13 +347,13 @@ static QueuedRem *FindNextReminder(void)
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GotSigInt */
|
||||
/* PrintQueue */
|
||||
/* */
|
||||
/* Split out what's done on a SIGINT from the SIGINT Handler. */
|
||||
/* This will be necessary for OS/2 multithreaded. */
|
||||
/* For debugging: Print queue contents to STDOUT */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void GotSigInt(void)
|
||||
static
|
||||
void PrintQueue(void)
|
||||
{
|
||||
QueuedRem *q = QueueHead;
|
||||
|
||||
@@ -368,6 +378,7 @@ void GotSigInt(void)
|
||||
q = q->next;
|
||||
}
|
||||
printf(NL);
|
||||
printf("To terminate program, send SIGQUIT (probably Ctrl-\\ on the keyboard.)%s", NL);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
@@ -170,10 +170,11 @@ static int latitude_func(int do_set, Value *val)
|
||||
static int trig_date_func(int do_set, Value *val)
|
||||
{
|
||||
UNUSED(do_set);
|
||||
val->type = DATE_TYPE;
|
||||
if (!LastTrigValid) {
|
||||
val->type = INT_TYPE;
|
||||
val->v.val = 0;
|
||||
} else {
|
||||
val->type = DATE_TYPE;
|
||||
val->v.val = LastTriggerDate;
|
||||
}
|
||||
return OK;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -123,23 +123,37 @@ REM Mon OMITFUNC foo MSG bar
|
||||
EOF
|
||||
|
||||
# Test default color
|
||||
../src/remind -ppp - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
../src/remind -pppq - 1 Jan 2012 9:00 <<'EOF' >> ../tests/test.out 2>&1
|
||||
REM 2 MSG Normal
|
||||
SET $DefaultColor "255 0 0"
|
||||
REM 3 MSG Red
|
||||
REM 3 MSG %"Red%" on the calendar!
|
||||
SET $DefaultColor "-1 -1 -1"
|
||||
REM 4 MSG Normal
|
||||
# Should give an error
|
||||
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"
|
||||
|
||||
1301
tests/test.cmp
1301
tests/test.cmp
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -798,6 +804,21 @@ set a pad(11:33, " ", 12)
|
||||
set a pad(11:33, " ", 12, 1)
|
||||
set a pad("foo", "0", $MaxStringLen+1)
|
||||
|
||||
# Test OMIT
|
||||
CLEAR-OMIT-CONTEXT
|
||||
|
||||
OMIT Apr
|
||||
OMIT Jun THROUGH July 15
|
||||
OMIT Sep 5 THROUGH Sep 10
|
||||
OMIT 2024-12-25 THROUGH 2025-01-04
|
||||
OMIT Apr 2022 through July
|
||||
|
||||
OMIT DUMP
|
||||
CLEAR-OMIT-CONTEXT
|
||||
OMIT 2000-01-01 THROUGH 2020-12-31
|
||||
|
||||
OMIT Dec 5 2029 through Dec 4 2029
|
||||
|
||||
# Don't want Remind to queue reminders
|
||||
EXIT
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user