mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
188 Commits
04.00.00-B
...
04.02.00
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e1fff6339 | ||
|
|
60fdeac2e9 | ||
|
|
3b3f10d448 | ||
|
|
48a4314dd2 | ||
|
|
9beff3a24a | ||
|
|
1ef90c7a61 | ||
|
|
5c886d181e | ||
|
|
da4d830163 | ||
|
|
c7abb7986c | ||
|
|
5a3b3d8a06 | ||
|
|
127cee03df | ||
|
|
7455748d54 | ||
|
|
e278d0e768 | ||
|
|
a5acc12239 | ||
|
|
a25afb9771 | ||
|
|
6252a472b5 | ||
|
|
dbe4c662c1 | ||
|
|
b77a261c87 | ||
|
|
351c54cc50 | ||
|
|
72d0b13ad5 | ||
|
|
bea2a6541c | ||
|
|
5258e98f54 | ||
|
|
af9d42721c | ||
|
|
8ed43f5c3e | ||
|
|
ec02a87c2b | ||
|
|
6c2ec04d40 | ||
|
|
9f91cdf0b9 | ||
|
|
8ada68ce54 | ||
|
|
d7975634af | ||
|
|
87be68fecf | ||
|
|
b42d5fd412 | ||
|
|
603228b944 | ||
|
|
c62f676813 | ||
|
|
c7654c27a6 | ||
|
|
b00bf05fea | ||
|
|
29bd07d4ef | ||
|
|
b7047da89e | ||
|
|
f26334e25f | ||
|
|
b80bc5f788 | ||
|
|
91549e18ce | ||
|
|
07fd975935 | ||
|
|
f9d968cf68 | ||
|
|
6a7e696a60 | ||
|
|
6734fae1db | ||
|
|
481fbc20a1 | ||
|
|
3c120bf561 | ||
|
|
ee65e04974 | ||
|
|
4ee6bb0eca | ||
|
|
b9839421f2 | ||
|
|
67601507fa | ||
|
|
c2e5534462 | ||
|
|
f4ea3af6fc | ||
|
|
e0998a3991 | ||
|
|
d67e580d0a | ||
|
|
d6ce54eea4 | ||
|
|
8b9ec43029 | ||
|
|
9d68134f0f | ||
|
|
3d91371870 | ||
|
|
d1c0ef63b0 | ||
|
|
2a59da61e1 | ||
|
|
2bc5e21627 | ||
|
|
7d77bfd12a | ||
|
|
0ff589c288 | ||
|
|
f3cca092be | ||
|
|
7218d55f08 | ||
|
|
ec72c74016 | ||
|
|
c946f08235 | ||
|
|
a8543ac349 | ||
|
|
dd3c0e14ed | ||
|
|
a2bc0acd3c | ||
|
|
a34266741a | ||
|
|
dedb9766c9 | ||
|
|
aedd759f50 | ||
|
|
a24c2f6905 | ||
|
|
fac31a10b8 | ||
|
|
fba9f139ed | ||
|
|
588d9debe8 | ||
|
|
805c2e0c69 | ||
|
|
2c2b1440b3 | ||
|
|
6973f62d74 | ||
|
|
f547c1e714 | ||
|
|
f8ea124b1f | ||
|
|
820e2aec4d | ||
|
|
01ce6b2d8f | ||
|
|
b39e0eab7e | ||
|
|
d6fc451d74 | ||
|
|
ac91556fc2 | ||
|
|
ccf639efe6 | ||
|
|
a8aa3b328b | ||
|
|
74a3b3e73d | ||
|
|
c0e68b57ea | ||
|
|
0ad4ea26eb | ||
|
|
ea7aafaf5e | ||
|
|
18043080ba | ||
|
|
7cd8cf3a77 | ||
|
|
21da52ec36 | ||
|
|
7a0c164843 | ||
|
|
5cf4961f19 | ||
|
|
68926d145b | ||
|
|
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 | ||
|
|
80e30638a5 | ||
|
|
dd2fc30364 | ||
|
|
a5865fb5fe | ||
|
|
aca2f28341 | ||
|
|
7a3f5f7ac9 | ||
|
|
1731710ef2 | ||
|
|
dc2a8f48bf | ||
|
|
5e16179bfa | ||
|
|
a7c1bc81b2 | ||
|
|
5f5ec8ef19 | ||
|
|
712ff56792 | ||
|
|
99af1f964c | ||
|
|
de5d1347e5 | ||
|
|
5e07fbde6d | ||
|
|
c523c7f3b3 | ||
|
|
6b3c6b0ec7 |
2
.github/FUNDING.yml
vendored
Normal file
2
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
liberapay: dskoll
|
||||
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
|
||||
29
.github/workflows/github-action.yml
vendored
Normal file
29
.github/workflows/github-action.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# language: bash
|
||||
---
|
||||
|
||||
name: Remind unit tests
|
||||
|
||||
on:
|
||||
push
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Remind
|
||||
uses: actions/checkout@v2
|
||||
- name: Add test user
|
||||
run: |
|
||||
sudo adduser --home /home/testuser --gecos 'Test User' --disabled-password testuser
|
||||
- name: Fix ownership
|
||||
run: |
|
||||
sudo chown -R testuser .
|
||||
- name: Build
|
||||
run: |
|
||||
sudo su -c './configure && make' testuser
|
||||
- name: Run Tests
|
||||
run: |
|
||||
sudo su -c 'make test' testuser
|
||||
- name: Fix up permissions so GitHub does not complain
|
||||
run: |
|
||||
sudo chmod -R a+rwX .
|
||||
6
.gitignore
vendored
6
.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
|
||||
@@ -26,3 +31,4 @@ src/test-*.out
|
||||
src/version.h
|
||||
tests/test.out
|
||||
www/Makefile
|
||||
gmon.out
|
||||
|
||||
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 './configure && make all && make test'
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- tests/test.out
|
||||
23
Makefile
23
Makefile
@@ -12,20 +12,33 @@ 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
|
||||
|
||||
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:
|
||||
@$(MAKE) -C src -s test
|
||||
|
||||
|
||||
31
README
31
README
@@ -34,5 +34,36 @@ If you do NOT have Tcl/Tk or are NOT running X Windows:
|
||||
|
||||
5) Type: "make install" -- you may need to be root to do this.
|
||||
|
||||
PREREQUISITES:
|
||||
--------------
|
||||
|
||||
Remind and rem2ps have no prerequisites beyond the standard C library and
|
||||
the standard math library.
|
||||
|
||||
Rem2HTML requires the JSON::MaybeXS Perl module.
|
||||
Rem2PDF requires the JSON::MaybeXS, Pango and Cairo Perl modules.
|
||||
|
||||
- On Debian-like systems, these prerequisites may be installed with:
|
||||
|
||||
apt install libjson-maybexs-perl libpango-perl libcairo-perl
|
||||
|
||||
- On RPM-based systems, you need perl-Pango, perl-Cairo and perl-JSON-MaybeXS
|
||||
|
||||
- On Gentoo, you need dev-perl/Pango, dev-perl/Cairo and dev-perl/JSON-MaybeXS.
|
||||
|
||||
- On Arch linux, you need pango-perl, cairo-perl and perl-json-maybexs
|
||||
|
||||
TkRemind requires Tcl/Tk and the tcllib library.
|
||||
|
||||
- On Debian-like systems, install with:
|
||||
|
||||
apt install tcl tk tcllib
|
||||
|
||||
- On RPM-based systems, you need tcl, tk and tcllib
|
||||
|
||||
- On Arch Linux, you need tk and tcllib. The latter is available at
|
||||
https://aur.archlinux.org/packages/tcllib
|
||||
|
||||
==========================================================================
|
||||
Contact info: mailto:dianne@skoll.ca
|
||||
Home page: https://dianne.skoll.ca/projects/remind/
|
||||
|
||||
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.00
|
||||
VERSION=04.02.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.00
|
||||
VERSION=04.02.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
|
||||
|
||||
171
docs/WHATSNEW
171
docs/WHATSNEW
@@ -1,6 +1,159 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 4.0 Patch 0 - 2022-??-??
|
||||
* VERSION 4.2 Patch 0 - 2022-10-14
|
||||
|
||||
- NEW FEATURE: remind: Allow weekdays to be globally-omitted. For example:
|
||||
|
||||
OMIT Saturday Sunday
|
||||
|
||||
globally-omits all Saturdays and Sundays.
|
||||
|
||||
- NEW FEATURE: remind: Add ansicolor() built-in function to make it easier
|
||||
to colorize reminders on the terminal. Suggested by Tim Chase.
|
||||
|
||||
- NEW FEATURE: remind: Add several special variables related to the color
|
||||
mode: $UseVTColors, $UseBGVTColors, $Use256Colors, $UseTrueColors and
|
||||
$TerminalBackground. Based on a suggestion by Tim Chase.
|
||||
|
||||
- NEW FEATURE: remind: Add utctolocal() and localtoutc() built-in functions.
|
||||
|
||||
- NEW FEATURE: remind: Add timezone() built-in function.
|
||||
|
||||
- NEW FEATURE: remind: Add trigtags() function per suggestion from Tim Chase.
|
||||
|
||||
- NEW FEATURE: remind: The $AddBlankLines system variable controls whether or
|
||||
not a blank line is added after each reminder.
|
||||
|
||||
- NEW FEATURE: remind: The built-in functions columns() and rows() return the
|
||||
width and height of the terminal (in character positions) respectively.
|
||||
|
||||
- NEW FEATURE: remind: The built-in function columns("string") returns the
|
||||
number of columns occupied by "string" on the terminal, taking into account
|
||||
double-width Unicode characters and zero-width ANSI escape sequences.
|
||||
|
||||
- NEW FEATURE: remind: You can add custom substitution sequences of the form
|
||||
%{name} or %*{name} that end up calling the function subst_name and using
|
||||
its return value as the replacement for the substitution sequence.
|
||||
|
||||
- NEW FEATURE: remind: Add the FUNSET command to undefine a user-defined
|
||||
function.
|
||||
|
||||
- NEW FILES: Add standard include files holidays/jewish.rem and
|
||||
ansitext.rem (the latter defines standard ANSI escape codes for
|
||||
changing text attributes such as bold, underline, etc.)
|
||||
|
||||
- NEW EXAMPLES: add examples/alignmemt.rem, examples/ansitext and
|
||||
examples/astro
|
||||
|
||||
- BUG FIX: remind: Make MSF correctly format UTF-8 text and text with
|
||||
embedded ANSI color-changing codes.
|
||||
|
||||
- BUG FIX: remind: Make ADDOMIT actually work correctly in a SATISFY-type
|
||||
REM command. Bug found by Gunther Reißig
|
||||
|
||||
- BUG FIX: Convert documentation files and src/lang.h to UTF-8. Patch
|
||||
from Jochen Sprickerhof.
|
||||
|
||||
- BUG FIX: Fix tests in non-UTF-8 locales.
|
||||
|
||||
- BUG FIX: Fix a few problems with the include/holidays/us.rem file.
|
||||
|
||||
- BUG FIX: remind: Fix an ancient logic error in DBufPutc that hurt
|
||||
performance.
|
||||
|
||||
- MINOR IMPROVEMENT: Clean up code and remove some dead code.
|
||||
|
||||
* VERSION 4.1 Patch 0 - 2022-09-25
|
||||
|
||||
- NEW FEATURE: remind: "remind -c" now supports the MOON special, printing
|
||||
the moon phases in the calendar if the locale supports UTF-8 encoding.
|
||||
|
||||
- NEW FEATURE: remind: "remind -c" now supports the SHADE special. Works
|
||||
best with the 256-color extended XTerm palette or 24-bit true-color
|
||||
terminal escape sequences.
|
||||
|
||||
- NEW FEATURE: remind: "remind -c" now supports the WEEK special.
|
||||
|
||||
- NEW FEATURE: remind: The new "stdout()" function returns a string describing
|
||||
where stdout is going. Examples of return values are "TTY" if remind's
|
||||
output is going to terminal, "FILE" if it's redirected to a plain file,
|
||||
or "PIPE" if it's going to a pipe. See the man page for all the details.
|
||||
|
||||
- NEW FEATURE: Add the "-wt" option to set the calendar width to the terminal
|
||||
width even if standard output is a pipe. Useful for situations like this:
|
||||
|
||||
remind -wt -c .reminders | less -R
|
||||
|
||||
- CHANGE: "make install" now no longer strips debugging symbols from the
|
||||
remind and rem2ps executables. Use "make install-stripped" if you want
|
||||
them stripped.
|
||||
|
||||
- CHANGE: remind: "remind -c" highlights today's date in bold, if
|
||||
colors are enabled.
|
||||
|
||||
- CHANGE: Dump string values with control characters escaped.
|
||||
|
||||
- DOCUMENTATION FIX: Document behavior of DO and filedir() with respect
|
||||
to symbolic links.
|
||||
|
||||
- DOCUMENTATION FIX: Add home page link to man pages. Suggested by Ian! D.
|
||||
Allen.
|
||||
|
||||
- DOCUMENTATION FIX: Make date in man pages actually be the release date.
|
||||
Include Remind version in man pages. Also suggested by Ian! D. Allen.
|
||||
|
||||
- DOCUMENTATION FIX: Fix inaccuracy in how string constants were documented.
|
||||
|
||||
- BUG FIX: Makefiles: Pass CFLAGS at link-time so link-time optimization
|
||||
actually happens. Pointed out by Zoltan 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
|
||||
Left-to-Right mark in "remind -c" output.
|
||||
|
||||
- DOCUMENTATION FIX: Document the "q" sub-option to the "-p" option.
|
||||
|
||||
* VERSION 4.0 Patch 0 - 2022-04-04
|
||||
|
||||
- MAJOR NEW FEATURE: remind: Remind output can effectively be
|
||||
translated into other languages at run-time. A number of system
|
||||
@@ -30,6 +183,11 @@ CHANGES TO REMIND
|
||||
This causes Remind *not* to remove the %"...%" marker sequence from
|
||||
remind bodies.
|
||||
|
||||
- BUG FIX: rem2pdf: Make rem2pdf respect the --prefix ./configure flag.
|
||||
Loosely based on patch by Jonathan Kamens.
|
||||
|
||||
- BUG FIX: tkremind: Fix the "-m" flag, which was broken in 03.04.00.
|
||||
|
||||
- BUG FIX: Fix the overflow-detection functions so they work with link-time
|
||||
optimization. The previous versions would be optimized away.
|
||||
|
||||
@@ -1029,7 +1187,7 @@ CHANGES TO REMIND
|
||||
- Fixed dates for Yom Hazikaron and Yom Ha'atzmaut if 5 Iyar falls on a
|
||||
Saturday. (Hebrew calendar fix.)
|
||||
|
||||
- Added support for the Icelandic language, courtesy of Björn Davíðsson.
|
||||
- Added support for the Icelandic language, courtesy of Björn Davíðsson.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
@@ -1176,7 +1334,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.
|
||||
@@ -1767,7 +1925,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.
|
||||
@@ -1840,7 +1998,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()."
|
||||
|
||||
@@ -1982,6 +2140,3 @@ CHANGES TO REMIND
|
||||
* Version 1.0
|
||||
|
||||
- never publicly released.
|
||||
|
||||
|
||||
|
||||
|
||||
18
examples/alignment.rem
Normal file
18
examples/alignment.rem
Normal file
@@ -0,0 +1,18 @@
|
||||
# Demo the columns() function
|
||||
#
|
||||
# Run as: remind -@2 alignment.rem
|
||||
|
||||
SET $AddBlankLines 0
|
||||
BANNER %
|
||||
|
||||
FSET center(x) pad("", " ", (columns() - columns(x))/2) + x
|
||||
FSET right(x) pad("", " ", columns() - columns(x)) + x
|
||||
|
||||
MSG This is left-aligned.
|
||||
MSG [ansicolor(0,255,0)]This is also left-aligned.[ansicolor("")]
|
||||
|
||||
MSG [center("This is centered.")]
|
||||
MSG [ansicolor(255,255,0) + center("🌕 🌕 🌕 🌕 This is also centered. ") + ansicolor("")]
|
||||
|
||||
msg [right("This is right-aligned.")]
|
||||
msg [ansicolor(255,0,0) + right("This is also right-aligned. 🌕 🌕 🌕") + ansicolor("")]
|
||||
35
examples/ansitext
Executable file
35
examples/ansitext
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# A little demo script that displays ANSI text attributes
|
||||
# Not all attributes work on all terminals... your mileage may vary.
|
||||
|
||||
remind -@2 - <<'EOF'
|
||||
|
||||
SET $AddBlankLines 0
|
||||
BANNER %
|
||||
INCLUDE [$SysInclude]/ansitext.rem
|
||||
MSG This file shows off some ANSI text attributes and colors.
|
||||
MSG Not all attributes work on all terminals.%_
|
||||
|
||||
MSG This is [ansi_bold]bold.[ansi_normal]
|
||||
MSG This is [ansi_faint]faint.[ansi_normal]
|
||||
MSG This is [ansi_italic]italic.[ansi_normal]
|
||||
MSG This is [ansi_underline]underline.[ansi_normal]
|
||||
MSG This is [ansi_underline2]underline2.[ansi_normal]%_
|
||||
MSG This is [ansi_reverse]reverse.[ansi_normal]%_
|
||||
MSG This is [ansi_strikeout]strikeout.[ansi_normal]%_
|
||||
MSG This is [ansi_overline]overline.[ansi_normal]%_
|
||||
|
||||
MSG This is [ansicolor(255,0,0)]red.[ansicolor("")]
|
||||
MSG This is [ansicolor(0,255,0)]green.[ansicolor("")]
|
||||
MSG This is [ansicolor(0,0,255)]blue.[ansicolor("")]
|
||||
MSG This is [ansicolor(255,255,0)]yellow.[ansicolor("")]
|
||||
MSG This is [ansicolor(255,0,255)]magenta.[ansicolor("")]
|
||||
MSG This is [ansicolor(0,255,255)]cyan.[ansicolor("")]%_
|
||||
|
||||
# You can combine attributes
|
||||
MSG This is [ansicolor(0,255,0)][ansicolor(0,0,96,1)][ansi_italic][ansi_bold]Green-Bold-Italic-on-Blue[ansi_normal][ansicolor("")]
|
||||
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
36
examples/astro
Executable file
36
examples/astro
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# A little demo script that displays astronomical events
|
||||
#
|
||||
# Best used in a UTF-8 environment.
|
||||
|
||||
remind -g -@2 - <<'EOF'
|
||||
# Set this variable to 1 if your terminal has a dark background or 0 if
|
||||
# it is light.
|
||||
|
||||
SET bg_dark 1
|
||||
|
||||
SET $AddBlankLines 0
|
||||
BANNER %
|
||||
|
||||
MSG Today is [today()].%_
|
||||
|
||||
IF bg_dark
|
||||
SPECIAL COLOR 255 255 0 Sunrise: 🌅 [sunrise()] today and [sunrise(today()+1)] tomorrow
|
||||
SPECIAL COLOR 255 128 0 Sunset: 🌇 [sunset()] today and [sunset(today()+1)] tomorrow%_
|
||||
|
||||
REM [moondate(0)] +60 SPECIAL COLOR 255 255 0 New moon: 🌑 [moondate(0)] (%b)
|
||||
REM [moondate(1)] +60 SPECIAL COLOR 255 255 128 First Quarter: 🌓 [moondate(1)] (%b)
|
||||
REM [moondate(2)] +60 SPECIAL COLOR 255 255 255 Full moon: 🌕 [moondate(2)] (%b)
|
||||
REM [moondate(3)] +60 SPECIAL COLOR 255 255 128 Last Quarter: 🌗 [moondate(3)] (%b)
|
||||
ELSE
|
||||
SPECIAL COLOR 128 128 0 Sunrise: 🌅 [sunrise()] today and [sunrise(today()+1)] tomorrow
|
||||
SPECIAL COLOR 128 32 0 Sunset: 🌇 [sunset()] today and [sunset(today()+1)] tomorrow%_
|
||||
|
||||
REM [moondate(0)] +60 SPECIAL COLOR 128 128 0 New moon: 🌑 [moondate(0)] (%b)
|
||||
REM [moondate(1)] +60 SPECIAL COLOR 128 128 64 First Quarter: 🌓 [moondate(1)] (%b)
|
||||
REM [moondate(2)] +60 SPECIAL COLOR 0 0 0 Full moon: 🌕 [moondate(2)] (%b)
|
||||
REM [moondate(3)] +60 SPECIAL COLOR 128 128 64 Last Quarter: 🌗 [moondate(3)] (%b)
|
||||
ENDIF
|
||||
|
||||
EOF
|
||||
@@ -77,16 +77,16 @@ REM 1 MSG John's [_mo_num(11, 1984)] 'monthly' anniversary
|
||||
############################################################################
|
||||
|
||||
# If it falls on a Saturday, bump to previous Friday
|
||||
REM 4 July OMIT SAT SCANFROM -1 BEFORE ADDOMIT SATISFY [$Td != 4] MSG Independence day (observed)
|
||||
REM 3 JULY SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Independence day (observed)
|
||||
|
||||
# If it falls on a Sunday, bump to following Monday
|
||||
REM 4 July OMIT SUN SCANFROM -7 AFTER ADDOMIT SATISFY [$Td != 4] MSG Independence day (observed)
|
||||
REM 5 July SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Independence day (observed)
|
||||
|
||||
# If it falls on Sat or Sun, note the actual day
|
||||
REM 4 July SATISFY [$Tw == 0 || $Tw == 6] MSG Independence day (actual)
|
||||
REM 4 July SCANFROM -7 ADDOMIT SATISFY [$Tw == 0 || $Tw == 6] MSG Independence day (actual)
|
||||
|
||||
# Otherwise observed and actual is on the 4th
|
||||
REM 4 July OMIT SAT SUN SKIP SCANFROM -7 ADDOMIT MSG Independence Day
|
||||
REM 4 July SCANFROM -7 ADDOMIT SATISFY [$Tw >= 1 && $Tw <= 5] MSG Independence Day
|
||||
|
||||
##########################################################################
|
||||
# #
|
||||
|
||||
34
include/ansitext.rem
Normal file
34
include/ansitext.rem
Normal file
@@ -0,0 +1,34 @@
|
||||
# Global variables for various ANSI escape-code sequences
|
||||
# Not all sequences are supported by all terminals.
|
||||
|
||||
# This file is part of REMIND
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
|
||||
if !defined("ansi_bold")
|
||||
# Disable ANSI attributes in calandar mode
|
||||
if $CalMode
|
||||
set ansi_normal ""
|
||||
set ansi_bold ""
|
||||
set ansi_faint ""
|
||||
set ansi_italic ""
|
||||
set ansi_underline ""
|
||||
set ansi_reverse ""
|
||||
set ansi_strikeout ""
|
||||
set ansi_underline2 ""
|
||||
set ansi_overline ""
|
||||
else
|
||||
set ansi_normal char(27) + "[0m"
|
||||
set ansi_bold char(27) + "[1m"
|
||||
set ansi_faint char(27) + "[2m"
|
||||
set ansi_italic char(27) + "[3m"
|
||||
set ansi_underline char(27) + "[4m"
|
||||
set ansi_reverse char(27) + "[7m"
|
||||
set ansi_strikeout char(27) + "[9m"
|
||||
set ansi_underline2 char(27) + "[21m"
|
||||
set ansi_overline char(27) + "[53m"
|
||||
endif
|
||||
preserve ansi_normal ansi_bold ansi_faint ansi_italic ansi_underline2 ansi_reverse ansi_strikeout ansi_underline2 ansi_overline
|
||||
endif
|
||||
|
||||
# Example: REM MSG I must [ansi_bold]emphasize[ansi_normal] \
|
||||
# the [ansi_italic]severity[ansi_normal] of the situation!
|
||||
111
include/holidays/jewish.rem
Normal file
111
include/holidays/jewish.rem
Normal file
@@ -0,0 +1,111 @@
|
||||
# Major Jewish Holidays
|
||||
|
||||
# Set the variable InIsrael to 1 if you live in Israel. Otherwise,
|
||||
# you get the Diaspora versions of Jewish holidays
|
||||
SET InIsrael value("InIsrael", 0)
|
||||
|
||||
# Set the variable Reform to 1 if you want the Reform version of the
|
||||
# Jewish calendar. Otherwise, you get the traditional version
|
||||
SET Reform value("Reform", 0)
|
||||
|
||||
# Convenient function definition to save typing
|
||||
FSET _h(x, y) HEBDATE(x,y)
|
||||
FSET _h2(x, y) HEBDATE(x, y, $U-7)
|
||||
FSET _PastSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)+1)
|
||||
FSET _BackTwoFri(x, y) IIF(WKDAYNUM(_h2(x,y))!=5, _h2(x,y), _h2(x,y)-2)
|
||||
FSET _BackTwoSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)-2)
|
||||
# Default values in case InIsrael and Reform are not set
|
||||
SET InIsrael VALUE("InIsrael", 0)
|
||||
SET Reform VALUE("Reform", 0)
|
||||
|
||||
[_h(1, "Tishrey")] ++4 MSG %"Rosh Hashana 1%" is %b.
|
||||
|
||||
# No RH-2 or Tzom Gedalia in Reform
|
||||
IF !Reform
|
||||
[_h(2, "Tishrey")] ++4 MSG %"Rosh Hashana 2%" is %b.
|
||||
[_PastSat(3, "Tishrey")] ++4 MSG %"Tzom Gedalia%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(10, "Tishrey")] ++4 MSG %"Yom Kippur%" is %b.
|
||||
[_h(15, "Tishrey")] ++4 MSG %"Sukkot 1%" is %b.
|
||||
|
||||
IF !InIsrael
|
||||
[_h(16, "Tishrey")] MSG %"Sukkot 2%"
|
||||
ENDIF
|
||||
|
||||
[_h(21, "Tishrey")] ++4 MSG %"Hoshana Rabba%" is %b.
|
||||
[_h(22, "Tishrey")] ++4 MSG %"Shemini Atzeret%" is %b.
|
||||
|
||||
IF InIsrael
|
||||
[_h(22, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
ELSE
|
||||
[_h(23, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
ENDIF
|
||||
|
||||
# Because Kislev can change length, we must be more careful about Chanukah
|
||||
FSET _chan(x) HEBDATE(24, "Kislev", $U-9)+x
|
||||
[_chan(1)] ++4 MSG %"Chanukah 1%" is %b.
|
||||
[_chan(2)] MSG %"Chanukah 2%"
|
||||
[_chan(3)] MSG %"Chanukah 3%"
|
||||
[_chan(4)] MSG %"Chanukah 4%"
|
||||
[_chan(5)] MSG %"Chanukah 5%"
|
||||
[_chan(6)] MSG %"Chanukah 6%"
|
||||
[_chan(7)] MSG %"Chanukah 7%"
|
||||
[_chan(8)] MSG %"Chanukah 8%"
|
||||
|
||||
# Not sure about Reform's position on the next one.
|
||||
IF !Reform
|
||||
# 10 Tevet will never be a Saturday, so whether or not to
|
||||
# move it is moot. (Thanks to Art Werschulz.)
|
||||
[_h(10, "Tevet")] MSG %"Tzom Tevet%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(15, "Shvat")] ++4 MSG %"Tu B'Shvat%" is %b.
|
||||
[_h(14, "Adar A")] ++4 MSG %"Purim Katan%" is %b.
|
||||
|
||||
# If Purim is on Sunday, then Fast of Esther is 11 Adar.
|
||||
IF WKDAYNUM(_h2(13, "Adar")) != 6
|
||||
REM [_h2(13, "Adar")] ++4 MSG %"Fast of Esther%" is %b.
|
||||
ELSE
|
||||
REM [_h2(11, "Adar")] ++4 MSG %"Fast of Esther%" is %b.
|
||||
ENDIF
|
||||
[_h(14, "Adar")] ++4 MSG %"Purim%" is %b.
|
||||
[_h(15, "Nisan")] ++4 MSG %"Pesach%" is %b.
|
||||
|
||||
IF !InIsrael
|
||||
[_h(16, "Nisan")] MSG %"Pesach 2%"
|
||||
ENDIF
|
||||
|
||||
[_h(21, "Nisan")] MSG %"Pesach 7%"
|
||||
|
||||
IF !InIsrael && !Reform
|
||||
[_h(22, "Nisan")] MSG %"Pesach 8%"
|
||||
ENDIF
|
||||
|
||||
[_h(27, "Nisan")] ++4 MSG %"Yom HaShoah%" is %b.
|
||||
[_BackTwoFri(4, "Iyar")] ++4 MSG %"Yom HaZikaron%" is %b.
|
||||
[_BackTwoSat(5, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
|
||||
# Not sure about Reform's position on Lag B'Omer
|
||||
IF !Reform
|
||||
[_h(18, "Iyar")] ++4 MSG %"Lag B'Omer%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(28, "Iyar")] ++4 MSG %"Yom Yerushalayim%" is %b.
|
||||
[_h(6, "Sivan")] ++4 MSG %"Shavuot%" is %b.
|
||||
|
||||
IF !InIsrael && !Reform
|
||||
[_h(7, "Sivan")] MSG %"Shavuot 2%"
|
||||
ENDIF
|
||||
|
||||
# Fairly sure Reform Jews don't observe the next two
|
||||
IF !Reform
|
||||
# Tzom Tamuz and Tish'a B'Av are moved to Sunday if they normally
|
||||
# fall on a Saturday
|
||||
[_PastSat(17, "Tamuz")] ++4 MSG %"Tzom Tammuz%" is %b.
|
||||
[_PastSat(9, "Av")] ++4 MSG %"Tish'a B'Av%" is %b.
|
||||
ENDIF
|
||||
|
||||
# Clean up
|
||||
FUNSET _h _h2 _PastSat _BackTwoFri _BackTwoSat _chan
|
||||
|
||||
@@ -19,13 +19,9 @@ REM Feb 14 MSG %"Valentine's Day%"
|
||||
REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG %"President's Day%"
|
||||
REM Mar 17 MSG %"St. Patrick's Day%"
|
||||
|
||||
# The DST rules are accurate for most locations in
|
||||
# North America
|
||||
REM Sun Apr 1 ++2 UNTIL 1 Jan 2007 MSG Daylight Saving Time - %"DST starts%" %b
|
||||
REM Sun Mar 8 ++2 FROM 1 Jan 2007 MSG Daylight Saving Time - %"DST starts%" %b
|
||||
|
||||
REM Last Sunday in October ++2 UNTIL 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b
|
||||
REM First Sunday in November ++2 FROM 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b
|
||||
# These are accurate for most places in North America
|
||||
REM MAYBE-UNCOMPUTABLE Sun November SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Ends
|
||||
REM MAYBE-UNCOMPUTABLE Sun March SATISFY [isdst($T) != isdst($T+1)] MSG Daylight Saving Time Starts
|
||||
|
||||
REM Apr 1 MSG %"April Fool's%" Day
|
||||
REM Mon Tue Wed Thu Fri Sat 15 Apr MSG %"Income tax%" due
|
||||
@@ -35,15 +31,24 @@ REM Second Sun in May MSG %"Mother's Day%"
|
||||
REM Third Sat in May MSG %"Armed Forces Day%"
|
||||
REM Last Monday in May SCANFROM -7 ADDOMIT MSG %"Memorial Day%"
|
||||
REM Jun 14 MSG %"Flag Day%"
|
||||
|
||||
REM July 4 SCANFROM -7 ADDOMIT MSG Independence Day
|
||||
REM July 3 SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Independence Day (observed)
|
||||
REM July 5 SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Independence Day (observed)
|
||||
|
||||
REM Third Sun in June MSG %"Father's Day%"
|
||||
REM First Mon in Sep SCANFROM -7 ADDOMIT MSG %"Labor Day%"
|
||||
REM Second Mon in Oct MSG %"Columbus Day%"
|
||||
REM Second Mon in Oct MSG %"Columbus Day / Indigenous Peoples' Day%"
|
||||
REM Nov 11 MSG %"Veterans Day%"
|
||||
|
||||
REM Oct 30 MSG %"Mischief Night%"
|
||||
REM Oct 31 MSG %"Halloween%"
|
||||
|
||||
REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG %"Election Day%"
|
||||
REM Last Thu in Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
|
||||
REM Fri Nov [Week_4+1] SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
|
||||
|
||||
REM Thu 22 Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
|
||||
|
||||
REM Fri 23 Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
|
||||
|
||||
REM Dec 24 MSG %"Christmas Eve%"
|
||||
OMIT Dec 25 MSG %"Christmas%" Day
|
||||
|
||||
@@ -61,3 +61,29 @@ FSET subst_gx(alt, d, t) iif(alt, subst_g_alt(d), $On + " " + subst_g_alt(d))
|
||||
FSET subst_ux(alt, d, t) subst_ax(alt, d, t)
|
||||
FSET subst_vx(alt, d, t) subst_gx(alt, d, t)
|
||||
FSET subst_p(alt, d, t) iif(d == today()+1, "", "en")
|
||||
|
||||
# Localization of various astronomical events
|
||||
|
||||
# Perihelion
|
||||
SET earthseasons_Perihelion_str "Perihel"
|
||||
|
||||
# Vernal equinox
|
||||
SET earthseasons_EquinoxMar_str "Frühlingsanfang"
|
||||
|
||||
# Summer solstice
|
||||
SET earthseasons_SolsticeJun_str "Sommeranfang"
|
||||
|
||||
# Aphelion
|
||||
SET earthseasons_Aphelion_str "Aphel"
|
||||
|
||||
# Autumnal Equinox
|
||||
SET earthseasons_EquinoxSep_str "Herbstanfang"
|
||||
|
||||
# Winter Solstice
|
||||
SET earthseasons_SolsticeDec_str "Winteranfang"
|
||||
|
||||
# Daylight saving time starts
|
||||
SET daylightST_starts_str "Beginn Sommerzeit"
|
||||
|
||||
# Daylight saving time ends
|
||||
SET daylightST_ends_str "Ende Sommerzeit"
|
||||
|
||||
@@ -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,23 +99,53 @@ by many terminal emulators such as xterm. And \fIn\fR=2 tells it to
|
||||
use escape sequences that support true 24-bit colors, again supported
|
||||
by many terminal emulators such as xterm.
|
||||
.PP
|
||||
If the optional \fIm\fR parameter is supplied following a comma,
|
||||
then \fIm\fR=0 tells \fBRemind\fR that the terminal background is dark,
|
||||
and \fBRemind\fR will brighten up dark colors to make them visible. If
|
||||
If the optional \fIm\fR parameter is supplied following a comma, then
|
||||
\fIm\fR=0 tells \fBRemind\fR that the terminal background is dark, and
|
||||
\fBRemind\fR will brighten up dark colors to make them visible. If
|
||||
\fIm\fR=1, then \fBRemind\fR assumes the terminal background is light
|
||||
and it will darken bright colors to make them visible. If no \fIm\fR
|
||||
is supplied, then \fBRemind\fR does not perform any adjustments, and
|
||||
some reminders may be hard or impossible to see if the color is too close
|
||||
to the terminal background color.
|
||||
is supplied, or it is supplied as \fIm\fR=2, then \fBRemind\fR does
|
||||
not perform any adjustments, and some reminders may be hard or
|
||||
impossible to see if the color is too close to the terminal background
|
||||
color.
|
||||
.PP
|
||||
If the optional \fIb\fR parameter is supplied following a comma, then
|
||||
\fIb=0\fR tells \fBRemind\fR to ignore SPECIAL SHADE reminders (the
|
||||
default) and \fIb=1\fR tells \fBRemind\fR to respect SPECIAL SHADE
|
||||
reminders by emitting VT100 escape codes to color the background of the
|
||||
calendar cell. Note that SHADE does not work well unless you are
|
||||
using the extended 256-color palette (\fIn\fR=1) or the true
|
||||
24-bit colors (\fIn\fR=2). Note that for calendar cells that are
|
||||
shaded, the clamping mechanism described earlier for \fIm=0\fR or
|
||||
\fIm=1\fR is skipped; it is assumed that if you set \fIboth\fR the
|
||||
foreground color of a reminder and the background color of a cell,
|
||||
then you know what you are doing.
|
||||
.RE
|
||||
.TP
|
||||
.B \-w\fR\fIcol\fR[,\fIpad\fR[,\fIspc\fR]]]
|
||||
The \fB\-w\fR option specifies the output width, padding and spacing
|
||||
of the formatted calendar output. \fICol\fR specifies the number of
|
||||
columns in the output device. If not specified, or specified as 0,
|
||||
it defaults to the larger of 71 or the actual width of your terminal,
|
||||
or to 80 if standard output is not a terminal.
|
||||
columns in the output device. If \fIcol\fR is not specified, or is
|
||||
specified as 0, it defaults to the larger of 71 or the actual width of
|
||||
your terminal, or to 80 if standard output is not a terminal. If
|
||||
\fIcol\fR is specified as the letter \fBt\fR, then \fBRemind\fR
|
||||
attempts to get the width of the \fB/dev/tty\fR terminal device. This
|
||||
is useful, for example, if you pipe calendar output into \fBless\fR;
|
||||
even though standard output is a pipe, you want the calendar to be
|
||||
sized correctly for your terminal window:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
remind -c -wt .reminders | less
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.RS
|
||||
.PP
|
||||
Note that the value of \fIcol\fR is also used to set the system variable
|
||||
$FormWidth, which is initialized to \fIcol\fR - 8. See "SYSTEM VARIABLES"
|
||||
for details.
|
||||
|
||||
.PP
|
||||
\fIPad\fR specifies how many lines
|
||||
to use to "pad" empty calendar boxes. This defaults to 5. If you
|
||||
@@ -141,7 +171,7 @@ If you immediately follow the \fBs\fR with the letter
|
||||
day they actually occur \fIas well as\fR on any preceding days specified
|
||||
by the reminder's \fIdelta\fR.
|
||||
.TP
|
||||
.B \-p\fR[\fBa\fR][\fBp\fR][\fBp\fR]\fIn\fR
|
||||
.B \-p\fR[\fBa\fR][\fBp\fR][\fBp\fR][\fBq\fR]\fIn\fR
|
||||
The \fB\-p\fR option is very similar to the \fB\-s\fR option, except
|
||||
that the output contains additional information for use by the
|
||||
\fBRem2PS\fR program, which creates a PostScript calendar, and various
|
||||
@@ -156,7 +186,9 @@ by the reminder's \fIdelta\fR. If you follow the \fBp\fR with another
|
||||
format rather than the "simple calendar" format. This format is
|
||||
also documented in the \fBrem2ps(1)\fR man page. Finally, if you use
|
||||
three p's, as in \fB\-ppp\fR, then \fBRemind\fR uses a pure JSON
|
||||
format, again documented in \fBrem2ps(1)\fR.
|
||||
format, again documented in \fBrem2ps(1)\fR. If you include a \fBq\fR
|
||||
letter with this option, then the normal calendar-mode substitution filter
|
||||
is disabled and the %"...%" sequences are preserved in the output.
|
||||
.RS
|
||||
.PP
|
||||
Note that the \fB\-pp\fR or \fB\-ppp\fR options also enable the \fB\-l\fR
|
||||
@@ -378,7 +410,7 @@ information.
|
||||
.SH REMINDER FILES
|
||||
.PP
|
||||
\fBRemind\fR uses scripts to control its operation. You can use any
|
||||
text editor capable of creating plain ASCII files to create a
|
||||
text editor capable of creating plain-text files to create a
|
||||
\fBRemind\fR script. The commands inside a script can range from the
|
||||
very simple and almost immediately understandable:
|
||||
.PP
|
||||
@@ -563,6 +595,7 @@ The trigger date for a specific run is simply the current system date.
|
||||
present. The reminder is triggered on the specified day of each month.
|
||||
The trigger date for a particular run is the closest such day to the
|
||||
current system date. For example:
|
||||
.PP
|
||||
.nf
|
||||
REM 1 MSG First of every month.
|
||||
REM 31 MSG 31st of every month that has 31 days.
|
||||
@@ -572,6 +605,7 @@ current system date. For example:
|
||||
.I month
|
||||
present. The reminder is triggered every day of the specified month.
|
||||
Example:
|
||||
.PP
|
||||
.nf
|
||||
REM Feb MSG Every day in February
|
||||
.fi
|
||||
@@ -581,6 +615,7 @@ Example:
|
||||
and
|
||||
.I month
|
||||
present. Examples:
|
||||
.PP
|
||||
.nf
|
||||
REM 6 Jan MSG Every 6th of January
|
||||
REM Feb 29 MSG Every 29th of February
|
||||
@@ -589,6 +624,7 @@ present. Examples:
|
||||
5. Only
|
||||
.I year
|
||||
present. Example:
|
||||
.PP
|
||||
.nf
|
||||
REM 1991 MSG Every day in 1991
|
||||
.fi
|
||||
@@ -598,6 +634,7 @@ present. Example:
|
||||
and
|
||||
.I day
|
||||
present. Examples:
|
||||
.PP
|
||||
.nf
|
||||
REM 1 1990 MSG 1st of every month in 1990
|
||||
REM 1992 23 MSG 23rd of every month in 1992
|
||||
@@ -608,6 +645,7 @@ present. Examples:
|
||||
and
|
||||
.I month
|
||||
present. Examples:
|
||||
.PP
|
||||
.nf
|
||||
REM Feb 1991 MSG Every day in Feb 1991
|
||||
REM 1992 September MSG Every day in Sept 1992
|
||||
@@ -618,6 +656,7 @@ present. Examples:
|
||||
and
|
||||
.I day
|
||||
present. Examples:
|
||||
.PP
|
||||
.nf
|
||||
REM 8 Jan 1991 MSG 8th January 1991.
|
||||
REM 1992 March 9 MSG 9th March 1992.
|
||||
@@ -626,6 +665,7 @@ present. Examples:
|
||||
9.
|
||||
.I weekday
|
||||
only. Examples:
|
||||
.PP
|
||||
.nf
|
||||
REM Sat MSG Every Saturday
|
||||
REM Mon Tue Wed Thu Fri MSG Every working day
|
||||
@@ -637,6 +677,7 @@ only. Examples:
|
||||
and
|
||||
.I day
|
||||
present. Examples:
|
||||
.PP
|
||||
.nf
|
||||
REM Sat 1 MSG First Saturday of every month
|
||||
REM Mon Tue Wed Thu Fri 15 \\
|
||||
@@ -648,6 +689,7 @@ present. Examples:
|
||||
and
|
||||
.I month
|
||||
present. Examples:
|
||||
.PP
|
||||
.nf
|
||||
REM Mon March MSG Every Monday in March
|
||||
REM Mon Tue Wed Thu Fri Feb MSG Every working day in February
|
||||
@@ -658,6 +700,7 @@ present. Examples:
|
||||
and
|
||||
.I day
|
||||
present. Examples:
|
||||
.PP
|
||||
.nf
|
||||
REM Mon 1 March MSG First Monday in March
|
||||
REM Sat Sun 15 July MSG First Sat or Sun on or after 15 July
|
||||
@@ -668,6 +711,7 @@ present. Examples:
|
||||
and
|
||||
.I year
|
||||
present. Example:
|
||||
.PP
|
||||
.nf
|
||||
REM Sat Sun 1991 MSG Every Saturday and Sunday in 1991
|
||||
.fi
|
||||
@@ -677,6 +721,7 @@ present. Example:
|
||||
and
|
||||
.I year
|
||||
present. Examples:
|
||||
.PP
|
||||
.nf
|
||||
REM Mon 15 1990 MSG 1st Mon after 15th of every month in 1990
|
||||
REM Mon Tue Wed Thu Fri 1 1990 \\
|
||||
@@ -688,6 +733,7 @@ present. Examples:
|
||||
and
|
||||
.I year
|
||||
present. Example:
|
||||
.PP
|
||||
.nf
|
||||
REM Mon Wed 1991 Feb MSG Every Mon and Wed in Feb 1991.
|
||||
.fi
|
||||
@@ -697,6 +743,7 @@ present. Example:
|
||||
and
|
||||
.I year
|
||||
present. Example:
|
||||
.PP
|
||||
.nf
|
||||
REM Mon Tue Wed Thu Fri 28 Oct 1990 \\
|
||||
MSG 1st working day on or after 28 October 1990.
|
||||
@@ -957,6 +1004,18 @@ also. See "The OMIT command" for more details.)
|
||||
By comparison, if we had used "\-\-1", the reminder would be triggered on
|
||||
the last day of the month, regardless of the \fBOMIT\fR.
|
||||
.PP
|
||||
If you locally omit weekdays but also have globally-omitted weekdays, then
|
||||
the list of ommitted weekdays is the union of the two. Consider this
|
||||
example:
|
||||
.PP
|
||||
.nf
|
||||
OMIT Sat Sun
|
||||
REM 15 OMIT Fri Sat MSG Whatever
|
||||
.fi
|
||||
.PP
|
||||
In the REM command, the effective list of omitted weekdays will
|
||||
be Friday, Saturday and Sunday.
|
||||
.PP
|
||||
.B COMPUTED LOCAL OMITS
|
||||
.PP
|
||||
The \fBOMITFUNC\fR phrase of the \fBREM\fR command allows you to
|
||||
@@ -1130,7 +1189,8 @@ tags; see their documentation for details.
|
||||
.PP
|
||||
The \fBTAG\fR keyword is followed by a tag consisting of up to
|
||||
48 characters. You can have as many TAG clauses as you like in
|
||||
a given REM statement.
|
||||
a given REM statement. A tag can contain any character except for
|
||||
whitespace and a comma.
|
||||
.PP
|
||||
If you supply the \fB\-y\fR option to \fBRemind\fR, then any
|
||||
reminder that lacks a \fBTAG\fR will have one synthesized. The
|
||||
@@ -1466,7 +1526,8 @@ Notes:
|
||||
o
|
||||
.B Remind
|
||||
normally prints a blank line after each reminder; if the last character
|
||||
of the body is "%", the blank line will not be printed.
|
||||
of the body is "%", the blank line will not be printed. You can globally
|
||||
suppress the extra blank lines by setting \fB$AddBlankLines\fR to 0.
|
||||
.TP
|
||||
o
|
||||
Substitutions a, b, c, e, f, g, h, i, j, k, l, u and v all are replaced
|
||||
@@ -1515,11 +1576,15 @@ 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 \fIweekday\fR [\fIweekday\fR...]
|
||||
.PP
|
||||
or:
|
||||
.PP
|
||||
\fBOMIT\fR \fIday1\fR \fImonth1\fR \fIyear1\fR \fBTHROUGH\fR \fIday2\fR \fImonth2\fR \fIyear2\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]
|
||||
.RE
|
||||
.PP
|
||||
The \fBOMIT\fR command is used to "globally" omit certain days
|
||||
@@ -1528,12 +1593,23 @@ 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 Saturday Sunday
|
||||
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
|
||||
year - New Year's Day. The second example specifies a holiday that
|
||||
The first example omits every Saturday and Sunday. This is useful for
|
||||
reminders that shouldn't trigger on weekends.
|
||||
.PP
|
||||
The second example specifies a holiday that occurs on the same date each
|
||||
year - New Year's Day.
|
||||
.PP
|
||||
The third example specifies a holiday that
|
||||
changes each year - Labour Day. For these types of holidays, you
|
||||
must create an \fBOMIT\fR command for each year. (Later, in the
|
||||
description of expressions and some of the more advanced features of
|
||||
@@ -1561,9 +1637,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
|
||||
@@ -1575,12 +1649,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
|
||||
@@ -1689,6 +1779,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
|
||||
@@ -1883,12 +1979,16 @@ The following examples illustrate constants in \fBRemind\fR expressions:
|
||||
12, 36, \-10, 0, 1209
|
||||
.TP
|
||||
.B STRING constants
|
||||
"Hello there", "This is a test", "\\n\\gosd\\w", ""
|
||||
"Hello there", "This is a test", "\\nHello\\tThere", ""
|
||||
.PP
|
||||
.RS
|
||||
Note that the empty string is represented by "", and that
|
||||
backslashes in a string are \fInot\fR interpreted specially, as in they are
|
||||
in C.
|
||||
Note that the empty string is represented by "". Remind supports
|
||||
the escape sequences "\\a", "\\b", "\\f", "\\n", "\\r", "\\t"
|
||||
and "\\v" which have the same meanings as their counterparts in C.
|
||||
To include a quote in a string, use "\\"". Any other character
|
||||
preceded by a backslash is inserted into the string as-is, but the
|
||||
backslash itself is removed. To include a backslash in a string,
|
||||
use "\\\\".
|
||||
.RE
|
||||
.TP
|
||||
.B TIME constants
|
||||
@@ -2175,6 +2275,16 @@ The following system variables are defined. Those marked
|
||||
"read-only" cannot be changed with the \fBSET\fR command.
|
||||
All system variables hold values of type \fBINT\fR, unless otherwise
|
||||
specified.
|
||||
.TP
|
||||
.B $AddBlankLines
|
||||
If set to 1 (the default), then \fBRemind\fR normally prints a blank
|
||||
line after the banner and each reminder. (This can be suppressed by
|
||||
ending the reminder or banner with a single percent sign.) If
|
||||
$AddBlankLines is set to 0, then Remind does not print the blank line.
|
||||
In this case, ending a reminder with % has no effect. If you \fIdo\fR
|
||||
want a blank line after a reminder, end it with \fB%_\fR to insert a
|
||||
newline.
|
||||
|
||||
.TP
|
||||
.B $CalcUTC
|
||||
If 1 (the default), then \fBRemind\fR uses C library functions
|
||||
@@ -2323,9 +2433,10 @@ the decimal point must be a period (".").
|
||||
.PP
|
||||
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
|
||||
@@ -2441,6 +2552,20 @@ order, or 2 if sorting by time in descending order.
|
||||
The number of spaces by which all lines (except the first) of an
|
||||
\fBMSF\fR-type reminder should be indented. The default is 0.
|
||||
.TP
|
||||
.B $SuppressLRM
|
||||
Normally, when Remind is run with the \fB\-c\fR option in a UTF-8 locale,
|
||||
it emits a left-to-right mark sequence after printing day names or
|
||||
reminders. Some terminals render this incorrectly, so you can use:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
SET $SuppressLRM 1
|
||||
.fi
|
||||
.PP
|
||||
at the top of your reminder file to suppress the LRM sequences, or you
|
||||
can invoke Remind with the option \fB'\-i$SuppressLRM=1'\fR.
|
||||
.RE
|
||||
.TP
|
||||
.B $SysInclude (read-only, STRING type)
|
||||
A directory path containing standard reminder scripts. Currently,
|
||||
Remind ships with some standard holiday files and language packs.
|
||||
@@ -2485,6 +2610,23 @@ Equivalent to \fBwkdaynum(today())\fR.
|
||||
.TP
|
||||
.B $Uy (read-only)
|
||||
Equivalent to \fByear(today())\fR.
|
||||
.TP
|
||||
.B $UseVTColors (read-only)
|
||||
Set to 1 if the \fB\-@\fR or \fB\-cc\fR options were used; 0 otherwise.
|
||||
.TP
|
||||
.B $UseBGVTColors (read-only)
|
||||
Set to 1 if the \fB\-@,,1\fR option was used; 0 otherwise.
|
||||
.TP
|
||||
.B $Use256Colors (read-only)
|
||||
Set to 1 if the \fB\-@1\fR option was used; 0 otherwise.
|
||||
.TP
|
||||
.B $UseTrueColors (read-only)
|
||||
Set to 1 if the \fB\-@2\fR option was used; 0 otherwise.
|
||||
.TP
|
||||
.B $TerminalBackground (read-only)
|
||||
Returns -1 if the terminal background color was not specified,
|
||||
0 if it was specified as dark with the \fB\-@,0\fR option or
|
||||
1 if it was specified as light with the \fB\-@,1\fR option.
|
||||
.PP
|
||||
Note: If any of the calendar modes are in effect, then the
|
||||
values of $Daemon, $DontFork, $DontTrigAts, $DontQueue, $HushMode,
|
||||
@@ -2547,6 +2689,60 @@ $TimeSep and $DateTimeSep when formatting its output. For example:
|
||||
.PP
|
||||
.RE
|
||||
.TP
|
||||
.B ansicolor(i_red, i_green, i_blue [,i_bg [,i_clamp]])
|
||||
Returns a \fBSTRING\fR that contains an ANSI escape sequence for changing
|
||||
the terminal text color. The parameters \fIred\fR, \fIgreen\fR and \fIblue\fR
|
||||
are integers from 0 to 255 specifying the value of the respective color
|
||||
component. As a special case, all three values can be -1, in which case
|
||||
the ANSI sequence "ESC[0m" is returned, which resets all text attributes
|
||||
to normal.
|
||||
.RS
|
||||
.PP
|
||||
The string returned by \fBansicolor\fR depends on the color mode that
|
||||
\fBRemind\fR is running in, as specified by the \fB\-@\fR option. If color
|
||||
mode is not enabled, then \fBansicolor\fR always returns the empty string.
|
||||
Otherwise, it returns the escape sequence that best approximates the color
|
||||
according to the \fB\-@\fR color mode.
|
||||
.PP
|
||||
The optional \fIbg\fR argument is either 0 or 1. If 0 (the default), then
|
||||
the foreground color is set. If 1, then the background color is set. Note
|
||||
that setting the background color only works in 256-color or true-color
|
||||
mode.
|
||||
.PP
|
||||
The optional \fIclamp\fR argument is either 0 or 1. If 0 (the default),
|
||||
then colors are not adjusted based on the terminal background color. If
|
||||
1, then \fBRemind\fR attempts to adjust dark or bright colors so they have
|
||||
enough contrast to be visible in the terminal.
|
||||
.PP
|
||||
The first three arguments may alternatively be specified as a string
|
||||
consisting of three space-separated numbers, as in this example: "128 128 0"
|
||||
.PP
|
||||
As a special case, \fBansicolor("")\fR is equivalent to
|
||||
\fBansicolor(-1,-1,-1)\fR and returns the ANSI sequence to reset all text
|
||||
attributes to normal.
|
||||
.PP
|
||||
Note that inserting ANSI color sequences in calendar mode \fIwill
|
||||
produce garbled results\fR. Therefore, we recommend defining
|
||||
functions such as the ones below that return the empty string in
|
||||
calendar mode:
|
||||
.PP
|
||||
.nf
|
||||
IF $CalMode
|
||||
FSET fg(r,g,b) ""
|
||||
FSET bg(r,g,b) ""
|
||||
ELSE
|
||||
FSET fg(r,g,b) ansicolor(r,g,b)
|
||||
FSET bg(r,g,b) ansicolor(r,g,b,1)
|
||||
ENDIF
|
||||
REM [fg(255,0,0)][bg(64,64,64)]Red on Gray[fg(-1,-1,-1)] in normal mode
|
||||
REM SPECIAL COLOR 0 255 0 Green in normal and calendar mode
|
||||
.fi
|
||||
.PP
|
||||
If you use the \fBansicolor\fR function, don't forget to reset the color
|
||||
back to normal with \fBansicolor(-1,-1,-1)\fR or subsequent reminders
|
||||
will continue to be colored.
|
||||
.RE
|
||||
.TP
|
||||
.B args(s_fname)
|
||||
Returns the number of arguments expected by the user-defined function
|
||||
\fIfname\fR, or \-1 if no such user-defined function exists. Note that
|
||||
@@ -2557,7 +2753,10 @@ available only in versions of \fBRemind\fR from 03.00.04 and up.
|
||||
.TP
|
||||
.B asc(s_string)
|
||||
Returns an \fBINT\fR that is the ASCII code of the first character
|
||||
in \fIstring\fR. As a special case, \fBasc("")\fR returns 0.
|
||||
in \fIstring\fR. As a special case, \fBasc("")\fR returns 0. For UTF-8
|
||||
strings, this will return the UTF-8 byte with which the string
|
||||
begins, which is not likely to be very useful (and may indeed be negative
|
||||
on machines where \fBchar\fR is a signed type.)
|
||||
.TP
|
||||
.B baseyr()
|
||||
Returns the "base year" that was compiled into \fBRemind\fR (normally
|
||||
@@ -2566,14 +2765,10 @@ Returns the "base year" that was compiled into \fBRemind\fR (normally
|
||||
.TP
|
||||
.B char(i_i1 [,i_i2...])
|
||||
This function can take any number of \fBINT\fR arguments. It returns
|
||||
a \fBSTRING\fR consisting of the characters specified by the arguments.
|
||||
Note that none of the arguments can be 0, unless there is only one
|
||||
a \fBSTRING\fR consisting of the bytes specified by the arguments.
|
||||
It is easy to create invalid UTF-8 sequences; \fBchar\fR does not check
|
||||
for this. Note that none of the arguments can be 0, unless there is only one
|
||||
argument. As a special case, \fBchar(0)\fR returns "".
|
||||
.PP
|
||||
.RS
|
||||
Note that because \fBRemind\fR does not support escaping of characters
|
||||
in strings, the only way to get a double-quote in a string is to use
|
||||
\fBchar(34)\fR.
|
||||
.RE
|
||||
.TP
|
||||
.B choose(i_index, x_arg1 [,x_arg2...])
|
||||
@@ -2632,6 +2827,22 @@ arguments are converted using the reverse of procedures described
|
||||
above. A \fBSTRING\fR \fIarg\fR is converted by parsing it as an
|
||||
integer.
|
||||
.RE
|
||||
.TP
|
||||
.B columns([s_arg])
|
||||
If called with no arguments, \fBcolumns()\fR behaves as follows:
|
||||
If standard output is a TTY, returns the width of the terminal in columns.
|
||||
If standard output is not a TTY, attempts to open "/dev/tty" to obtain
|
||||
the terminal size. If this fails, returns -1.
|
||||
.RS
|
||||
.PP
|
||||
If called with a single string argument, \fBcolumns(str)\fR returns
|
||||
the number of columns \fBstr\fR will occupy if printed to a terminal.
|
||||
ANSI color-changing sequences occupy zero columns whereas some Unicode
|
||||
characters occupy two columns. \fBcolumns(str)\fR takes all of that
|
||||
into account. Note that if Remind was compiled without Unicode support,
|
||||
\fBcolumns(str)\fR returns a type mismatch error.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B current()
|
||||
Returns the current date and time as a DATETIME object. This may be the
|
||||
@@ -2780,6 +2991,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()
|
||||
@@ -2872,6 +3090,10 @@ other languages, this function will return the English name of the
|
||||
language (e.g. "German") Note that \fBlanguage()\fR is not available
|
||||
in versions of \fBRemind\fR prior to 03.00.02.
|
||||
.TP
|
||||
.B localtoutc(q_datetime)
|
||||
Given a \fBDATETIME\fR object interpreted in the local time zone, return
|
||||
a \fBDATETIME\fR object that expresses the same time in UTC.
|
||||
.TP
|
||||
.B lower(s_string)
|
||||
Returns a \fBSTRING\fR with all upper-case characters in \fIstring\fR
|
||||
converted to lower-case.
|
||||
@@ -3048,6 +3270,7 @@ be right-padded.
|
||||
.RS
|
||||
.PP
|
||||
Here are some examples:
|
||||
.PP
|
||||
.nf
|
||||
pad(3, "0", 2) --> "03"
|
||||
pad(465, "0", 2) --> "465"
|
||||
@@ -3142,6 +3365,11 @@ Returns the date as provided by the operating system. This is in contrast to
|
||||
\fBRemind\fR's concept of "today", which may be changed if it is running
|
||||
in calendar mode, or if a date has been supplied on the command line.
|
||||
.TP
|
||||
.B rows()
|
||||
If standard output is a TTY, returns the height of the terminal in rows.
|
||||
If standard output is not a TTY, attempts to open "/dev/tty" to obtain
|
||||
the terminal size. If this fails, returns -1.
|
||||
.TP
|
||||
.B sgn(i_num)
|
||||
Returns \-1 if \fInum\fR is negative, 1 if \fInum\fR is positive,
|
||||
and 0 if \fInum\fR is zero.
|
||||
@@ -3203,9 +3431,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
|
||||
@@ -3245,6 +3488,12 @@ Creates a \fBTIME\fR with the hour and minute components specified by
|
||||
Returns a \fBTIME\fR object representing the time portion of
|
||||
\fIdatetime\fR.
|
||||
.TP
|
||||
.B timezone([dq_datetime])
|
||||
Returns a string representing the local time zone name of the given
|
||||
\fBDATETIME\fR. If no argument is supplied, \fBRemind\fR uses the
|
||||
value of \fBcurrent()\fR. If a \fBDATE\fR rather than \fBDATETIME\fR
|
||||
is supplied, \fBRemind\fR uses a time part of 00:00.
|
||||
.TP
|
||||
.B today()
|
||||
Returns \fBRemind\fR's notion of "today." This may be the actual system
|
||||
date, or a date supplied on the command line, or the date of the
|
||||
@@ -3266,6 +3515,7 @@ non-zero trigger date.
|
||||
\fBIFTRIG\fR. For example, if you have meetings every Monday in
|
||||
June and July, and you want warnings 3 days in advance, you
|
||||
could use:
|
||||
.PP
|
||||
.nf
|
||||
REM [trig("Mon Jun +3", "Mon July +3")] +3 MSG Meeting %b
|
||||
.fi
|
||||
@@ -3470,6 +3720,12 @@ returns "30 November 1994 AT 22:00" for EST, which is 5 hours behind UTC.
|
||||
The value for your time zone may differ.
|
||||
.RE
|
||||
.TP
|
||||
.B trigtags()
|
||||
Returns a comma-separated list of the TAGs associated with the most recent
|
||||
\fBREM\fR command that was triggered. Returns the empty string if there
|
||||
were no TAGs. If there are multiple tags, they are each separated by
|
||||
a single comma, not a comma and a space.
|
||||
.TP
|
||||
.B trigtime()
|
||||
Returns the time of the last \fBREM\fR command with an \fBAT\fR
|
||||
clause. If the last \fBREM\fR did not have an \fBAT\fR clause,
|
||||
@@ -3511,6 +3767,11 @@ values. Here is an example:
|
||||
Returns a \fBSTRING\fR with all lower-case characters in \fIstring\fR
|
||||
converted to upper-case.
|
||||
.TP
|
||||
.B utctolocal(q_datetime)
|
||||
Given a \fBDATETIME\fR object interpreted in UTC, return a
|
||||
\fBDATETIME\fR object that expresses the same time in the local time
|
||||
zone.
|
||||
.TP
|
||||
.B value(s_varname [,x_default])
|
||||
Returns the value of the specified variable. For example, value("X"+"Y")
|
||||
returns the value of variable XY, if it is defined. If XY is not defined,
|
||||
@@ -3524,7 +3785,7 @@ defined, and the value of XY if it is defined.
|
||||
.TP
|
||||
.B version()
|
||||
Returns a string specifying the version of \fBRemind\fR. For version
|
||||
03.00.04, returns "03.00.04". It is guaranteed that as new versions of
|
||||
@VERSION@, returns "@VERSION@". It is guaranteed that as new versions of
|
||||
\fBRemind\fR are released, the value returned by \fBversion()\fR will
|
||||
strictly increase, according to the rules for string ordering.
|
||||
.TP
|
||||
@@ -3857,13 +4118,13 @@ Notes:
|
||||
.TP
|
||||
o
|
||||
If you access a variable in \fIexpr\fR that is not in the list of arguments,
|
||||
the "global" value (if any) is used.
|
||||
the global value (if any) is used.
|
||||
.TP
|
||||
o
|
||||
Function and parameter names are significant only to 12 characters.
|
||||
Function and parameter names are significant to 64 characters.
|
||||
.TP
|
||||
o
|
||||
The \fBvalue()\fR function \fIalways\fR accesses the "global" value of a
|
||||
The \fBvalue()\fR function \fIalways\fR accesses the global value of a
|
||||
variable, even if it has the same name as an argument. For example:
|
||||
.RS
|
||||
.PP
|
||||
@@ -3891,6 +4152,19 @@ with future versions of \fBRemind\fR (which may define more built-in
|
||||
functions), you may wish to name all user-defined functions beginning
|
||||
with an underscore.
|
||||
.PP
|
||||
To delete a user-defined function, use \fBFUNSET\fR. This takes a
|
||||
space-separated list of user-defined functions to delete. For
|
||||
example, after the command:
|
||||
.PP
|
||||
.nf
|
||||
FUNSET myfunc1 otherfunc thirdfunc
|
||||
.fi
|
||||
.PP
|
||||
it is guaranteed that no user-defined functions named myfunc1, otherfunc
|
||||
or thirdfunc will exist. \fBRemind\fR does not issue an error if you
|
||||
try to \fBFUNSET\fR a nonexistent user-defined function; it simply
|
||||
does nothing in that case.
|
||||
.PP
|
||||
.SH PRECISE SCHEDULING
|
||||
.PP
|
||||
The \fBWARN\fR keyword allows precise control over advance warning in
|
||||
@@ -4772,25 +5046,26 @@ This function is passed a single integer, namely a day of the month from
|
||||
turn it into an ordinal number. In English, for example, the function
|
||||
might return "st", "nd", "rd" or "th", depending on \fId\fR.
|
||||
.TP
|
||||
.B subst_N(alt, date, time)
|
||||
.B subst_\fIN\fR\fB(alt, date, time)\fR
|
||||
This is actually a \fIfamily\fR of functions, where \fIN\fR is a letter
|
||||
or number. This function \fIcompletely overrides\fR the substitution
|
||||
sequence "%X". The three arguments are an integer \fIalt\fR which,
|
||||
sequence "%N". The three arguments are an integer \fIalt\fR which,
|
||||
if non-zero, indicates that the alternate-mode substitution sequence
|
||||
"%*X" was encountered; \fIdate\fR which is the trigger date of the
|
||||
"%*N" was encountered; \fIdate\fR which is the trigger date of the
|
||||
reminder and \fItime\fR which is the trigger time.
|
||||
.TP
|
||||
.B subst_Nx(alt, date, time)
|
||||
.B subst_\fIN\fR\fBx(alt, date, time)\fR
|
||||
Again, this is a \fIfamily\fR of functions. It is similar to the
|
||||
\fBsubst_x\fR family except it is only called if \fIdate\fR is two or
|
||||
\fBsubst_\fIN\fR family except it is only called if \fIdate\fR is two or
|
||||
more days away from \fItoday()\fR. This is useful if you don't want to
|
||||
override the "today" or "tomorrow" output for most substitution sequences.
|
||||
.PP
|
||||
Here's an example of how you might customize your substitution filter.
|
||||
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%
|
||||
@@ -4799,6 +5074,7 @@ after tomorrow" for an event two days from now. You could do this:
|
||||
.fi
|
||||
.PP
|
||||
The output of this script is:
|
||||
.PP
|
||||
.nf
|
||||
Event 1 is in 3 days' time
|
||||
Event 2 is the day after tomorrow
|
||||
@@ -4811,6 +5087,26 @@ time", and note also that the "tomorrow" and "today" events used the
|
||||
normal substitution---\fBsubst_bx\fR is not called for trigger days of
|
||||
today or tomorrow.
|
||||
.PP
|
||||
As a special case, if a \fBsubst_Nx\fB or \fBsubst_N\fR function
|
||||
returns the integer zero, then the normal substitution mechanism is
|
||||
used. Therefore, the previous example could have been written more simply
|
||||
as:
|
||||
.PP
|
||||
.nf
|
||||
FSET subst_bx(a,d,t) iif(d==today()+2, "the day after tomorrow", 0)
|
||||
.fi
|
||||
.PP
|
||||
You can define your own substitution sequences in addition to the built-in
|
||||
ones as follows: If you define a function named \fBsubst_\fIname\fB(alt, date, time)\fR, then the sequence \fB%{name}\fR calls the function with \fBalt\fR
|
||||
set to 0 and \fBdate\fR and \fRtime\fR to the trigger date and time,
|
||||
respectively. The \fB%{name}\fR sequence is replaced with whatever the
|
||||
function returns. The sequence \fB%*{name}\fR is similar, but calls
|
||||
the function with \fBalt\fR set to 1.
|
||||
.PP
|
||||
If you use a \fB%{name}\fR sequence and the function \fBsubst_\fIname\fR is
|
||||
not defined or returns an error, then \fB%{name}\fR is replaced with the
|
||||
empty string.
|
||||
.PP
|
||||
.SH LANGUAGE PACKS
|
||||
.PP
|
||||
\fBRemind\fR ships with a number of language packs, which are simply reminder
|
||||
@@ -4823,12 +5119,14 @@ pl.rem (Polish), pt.rem (Portuguese) and ro.rem (Romanian).
|
||||
.PP
|
||||
To use a language pack (in this example, de.rem), simply place this at
|
||||
the top of your reminders file:
|
||||
.PP
|
||||
.nf
|
||||
INCLUDE [$SysInclude]/lang/de.rem
|
||||
.fi
|
||||
.PP
|
||||
If you want \fBRemind\fR to try to find the language pack appropriate
|
||||
for your locale settings, use:
|
||||
.PP
|
||||
.nf
|
||||
INCLUDE [$SysInclude]/lang/auto.rem
|
||||
.fi
|
||||
@@ -5043,10 +5341,12 @@ should attempt to support. They are currently supported by
|
||||
.PP
|
||||
The \fBSHADE\fR special replaces the \fBpsshade()\fR function.
|
||||
Use it like this:
|
||||
.PP
|
||||
.nf
|
||||
REM Sat Sun SPECIAL SHADE 128
|
||||
REM Mon SPECIAL SHADE 255 0 0
|
||||
.fi
|
||||
.PP
|
||||
The \fBSHADE\fR keyword is followed by either one or three numbers,
|
||||
from 0 to 255. If one number is supplied, it is interpreted as
|
||||
a grey-scale value from black (0) to white (255). If three numbers
|
||||
@@ -5057,14 +5357,17 @@ in calendars produced by \fBRem2PS\fR, \fBtkremind\fR and \fBrem2html\fR.)
|
||||
.PP
|
||||
The \fBMOON\fR special replaces the \fBpsmoon()\fR function. Use it
|
||||
like this:
|
||||
.PP
|
||||
.nf
|
||||
REM [moondate(0)] SPECIAL MOON 0
|
||||
REM [moondate(1)] SPECIAL MOON 1
|
||||
REM [moondate(2)] SPECIAL MOON 2
|
||||
REM [moondate(3)] SPECIAL MOON 3
|
||||
.fi
|
||||
.PP
|
||||
These draw little moons on the various calendars. The complete syntax
|
||||
of the \fBMOON\fR special is as follows:
|
||||
.PP
|
||||
.nf
|
||||
... SPECIAL MOON phase moonsize fontsize msg
|
||||
.fi
|
||||
@@ -5085,12 +5388,12 @@ and \fIfontsize\fR; the other backends use fixed sizes.
|
||||
.PP
|
||||
The \fBCOLOR\fR special lets you place colored reminders in the
|
||||
calendar. Use it like this:
|
||||
|
||||
.PP
|
||||
.nf
|
||||
REM ... SPECIAL COLOR 255 0 0 This is a bright red reminder
|
||||
REM ... SPECIAL COLOR 0 128 0 This is a dark green reminder
|
||||
.fi
|
||||
|
||||
.PP
|
||||
You can spell COLOR either the American way ("COLOR") or the British
|
||||
way ("COLOUR"). This manual will use the American way.
|
||||
|
||||
@@ -5111,11 +5414,11 @@ number in the calendar. For example, this would number each Monday
|
||||
with the ISO 8601 week number. The week number is shown like this:
|
||||
"(W\fIn\fR)" in this example, but you can put whatever text you like
|
||||
after the WEEK keyword.
|
||||
|
||||
.PP
|
||||
.nf
|
||||
REM Monday SPECIAL WEEK (W[weekno()])
|
||||
.fi
|
||||
|
||||
.PP
|
||||
.SH MISCELLANEOUS
|
||||
.PP
|
||||
.B COMMAND ABBREVIATIONS
|
||||
@@ -5373,9 +5676,6 @@ are not implemented as read-only system variables.
|
||||
.PP
|
||||
Hebrew dates in \fBRemind\fR change at midnight instead of sunset.
|
||||
.PP
|
||||
Language should be selectable at run-time, not compile-time. Don't
|
||||
expect this to happen soon!
|
||||
.PP
|
||||
\fBRemind\fR has some built-in limits (for example, number of global
|
||||
\fBOMIT\fRs.)
|
||||
.PP
|
||||
@@ -5390,7 +5690,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
|
||||
|
||||
@@ -19,7 +19,7 @@ install:
|
||||
$(PERL) -M$$m -e 1 > /dev/null 2>&1; \
|
||||
if test $$? != 0 ; then echo "Not installing rem2html; missing $$m"; exit 0; fi; \
|
||||
done; \
|
||||
pod2man rem2html > rem2html.1 && mkdir -p $(DESTDIR)$(mandir)/man1 && cp rem2html.1 $(DESTDIR)$(mandir)/man1/rem2html.1 || true; \
|
||||
pod2man --center "VERSION @VERSION@" --date "@RELEASE_DATE@" rem2html > rem2html.1 && mkdir -p $(DESTDIR)$(mandir)/man1 && cp rem2html.1 $(DESTDIR)$(mandir)/man1/rem2html.1 || true; \
|
||||
echo "Installing rem2html in $(DESTDIR)$(bindir)"; \
|
||||
mkdir -p $(DESTDIR)$(bindir) && sed -e 's|^#!perl|#!$(PERL)|' < rem2html > $(DESTDIR)$(bindir)/rem2html && chmod 755 $(DESTDIR)$(bindir)/rem2html && exit 0; \
|
||||
exit 1;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
use ExtUtils::MakeMaker;
|
||||
{
|
||||
# Override pod2man options
|
||||
package MY;
|
||||
sub manifypods {
|
||||
my ($self,%attribs) = @_;
|
||||
my $result = $self->SUPER::manifypods(%attribs);
|
||||
$result =~ s/^(POD2MAN_EXE\s*=\s*)(.+)$/$1$2 --center 'VERSION @VERSION@' --date '@RELEASE_DATE@'/m;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
WriteMakefile(
|
||||
NAME => 'Remind::PDF',
|
||||
AUTHOR => q{Dianne Skoll <dianne@skoll.ca>},
|
||||
|
||||
@@ -33,10 +33,16 @@ install:
|
||||
$(MAKE) install DESTDIR=$(DESTDIR) "INSTALL_BASE=$(INSTALL_BASE)" && exit 0; \
|
||||
elif test "$(prefix)" = "/usr" ; then \
|
||||
$(MAKE) install DESTDIR=$(DESTDIR) INSTALLDIRS=vendor && exit 0; \
|
||||
else \
|
||||
elif test "$(prefix)" = "/usr/local" ; then \
|
||||
$(MAKE) install DESTDIR=$(DESTDIR) && exit 0; \
|
||||
else \
|
||||
$(MAKE) install DESTDIR=$(DESTDIR) "INSTALL_BASE=$(prefix)" && exit 0; \
|
||||
fi; \
|
||||
exit 1;
|
||||
|
||||
Makefile: Makefile.PL
|
||||
$(PERL) Makefile.PL @PERLARTIFACTS@ INSTALL_BASE=$(INSTALL_BASE) || true
|
||||
if test "$(prefix)" != "/usr" -a "$(prefix)" != "/usr/local" -a "$(INSTALL_BASE)" = "" ; then \
|
||||
$(PERL) Makefile.PL @PERLARTIFACTS@ INSTALL_BASE=$(prefix) || true;\
|
||||
else \
|
||||
$(PERL) Makefile.PL @PERLARTIFACTS@ INSTALL_BASE=$(INSTALL_BASE) || true;\
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!@PERL@
|
||||
use strict;
|
||||
use warnings;
|
||||
use lib '@prefix@/lib/perl5';
|
||||
|
||||
use Encode;
|
||||
use Cairo;
|
||||
@@ -442,14 +443,14 @@ B<-p>, B<-pp> or B<-ppp> options into B<rem2pdf>. The PDF output
|
||||
will be sent to standard output. So for example, to print a 12-month
|
||||
calendar for the year 2030, use:
|
||||
|
||||
remind -pp12 /dev/null Jan 2030 | rem2pdf -e -l -c=3 | lpr
|
||||
remind -pp12 /dev/null Jan 2030 | rem2pdf -e -l -c3 | lpr
|
||||
|
||||
You can concatenate multiple B<remind> runs. For example, the following
|
||||
will produce a PDF calendar for January through March of 2023, and
|
||||
June of 2023 (for a total of four pages);
|
||||
|
||||
(remind -pp3 Jan 2023 /dev/null ; \
|
||||
remind -p June 2023 /dev/null) | rem2pdf -e -l -c=3 > cal.pdf
|
||||
(remind -pp3 /dev/null Jan 2023 ; \
|
||||
remind -pp /dev/null June 2023) | rem2pdf -e -l -c3 > cal.pdf
|
||||
|
||||
=head1 FORMATTED TEXT
|
||||
|
||||
@@ -503,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -285,7 +287,7 @@ sub read_one_month_pp
|
||||
Given a hashref C<$hash> consisting of one entry parsed
|
||||
from the "remind -p" stream and a C<$specials_accepted> hash,
|
||||
return 1 if we should include this entry in the calendar or
|
||||
0 if mot.
|
||||
0 if not.
|
||||
|
||||
=cut
|
||||
sub accept_special
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -457,6 +457,7 @@ proc CreateCalFrame { w dayNames } {
|
||||
# Figure out reasonable height for text frames
|
||||
global SetFontsWorked
|
||||
global Option
|
||||
global MondayFirst
|
||||
set h [winfo screenheight .]
|
||||
if {$h <= 480} {
|
||||
if {$SetFontsWorked} {
|
||||
@@ -470,7 +471,6 @@ proc CreateCalFrame { w dayNames } {
|
||||
set h 5
|
||||
}
|
||||
|
||||
global MondayFirst
|
||||
frame $w -background $Option(LineColor)
|
||||
for {set i 0} {$i < 7} {incr i} {
|
||||
if {$MondayFirst} {
|
||||
@@ -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
|
||||
@@ -1010,7 +1012,7 @@ proc ConfigureCalWindow { month year firstDay numDays } {
|
||||
proc FillCalWindow {} {
|
||||
set FileName ""
|
||||
set LineNo 0
|
||||
global DayNames CurYear CurMonth MonthNames CommandLine Option TagToObj RemindErrors
|
||||
global DayNames CurYear CurMonth MonthNames CommandLine Option TagToObj RemindErrors MondayFirst
|
||||
|
||||
array unset TagToObj
|
||||
|
||||
@@ -1049,7 +1051,12 @@ proc FillCalWindow {} {
|
||||
|
||||
# Update the day names in the calendar window
|
||||
for {set i 0} {$i < 7} {incr i} {
|
||||
.cal.day$i configure -text [lindex $DayNames $i]
|
||||
if {$MondayFirst} {
|
||||
set index [expr ($i+1)%7]
|
||||
} else {
|
||||
set index $i
|
||||
}
|
||||
.cal.day$i configure -text [lindex $DayNames $index]
|
||||
}
|
||||
set offset [CalEntryOffset $firstWkday]
|
||||
|
||||
@@ -1084,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]
|
||||
@@ -1109,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"} {
|
||||
@@ -2099,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
|
||||
|
||||
|
||||
459
src/calendar.c
459
src/calendar.c
@@ -9,7 +9,7 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#define _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include "config.h"
|
||||
#include "custom.h"
|
||||
|
||||
@@ -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,9 +298,53 @@ 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 (!UseBGVTColors) {
|
||||
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 (!UseBGVTColors) {
|
||||
return;
|
||||
}
|
||||
if (bgcolor[d][0] < 0) {
|
||||
return;
|
||||
}
|
||||
printf("%s", Decolorize());
|
||||
}
|
||||
|
||||
static void
|
||||
send_lrm(void)
|
||||
{
|
||||
/* Don't send LRM if SuppressLRM is set */
|
||||
if (SuppressLRM) {
|
||||
return;
|
||||
}
|
||||
/* Send a lrm control sequence if UseUTF8Chars is enabled
|
||||
or char encoding is UTF-8
|
||||
*/
|
||||
@@ -289,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) {
|
||||
@@ -375,7 +474,7 @@ void PrintJSONKeyPairTime(char const *name, int t)
|
||||
}
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
static void PutWideChar(wchar_t const wc)
|
||||
void PutWideChar(wchar_t const wc)
|
||||
{
|
||||
char buf[MB_CUR_MAX+1];
|
||||
int len;
|
||||
@@ -493,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;
|
||||
@@ -511,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)) +
|
||||
@@ -523,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;
|
||||
}
|
||||
@@ -558,43 +667,112 @@ Colorize(int r, int g, int b)
|
||||
if (b > 64) b = 1;
|
||||
else b = 0;
|
||||
|
||||
if (TerminalBackground == TERMINAL_BACKGROUND_DARK) {
|
||||
if (clamp && TerminalBackground == TERMINAL_BACKGROUND_DARK && !bg) {
|
||||
/* Convert black-on-black to grey */
|
||||
if (!r && !g && !b) return VT100Colors[1][0][0][0];
|
||||
}
|
||||
if (TerminalBackground == TERMINAL_BACKGROUND_LIGHT) {
|
||||
if (clamp && TerminalBackground == TERMINAL_BACKGROUND_LIGHT && !bg) {
|
||||
/* Convert white-on-white to grey */
|
||||
if (r && g && b) return VT100Colors[1][0][0][0];
|
||||
}
|
||||
return VT100Colors[bright][r][g][b];
|
||||
if (bg) {
|
||||
return VT100BGColors[r][g][b];
|
||||
} else {
|
||||
return VT100Colors[bright][r][g][b];
|
||||
}
|
||||
}
|
||||
|
||||
static void ColorizeEntry(CalEntry const *e)
|
||||
static void ColorizeEntry(CalEntry const *e, int clamp)
|
||||
{
|
||||
printf("%s", Colorize(e->r, e->g, e->b));
|
||||
printf("%s", Colorize(e->r, e->g, e->b, 0, clamp));
|
||||
}
|
||||
|
||||
static int
|
||||
ComputeCalWidth(int x)
|
||||
static void
|
||||
InitMoonsAndShades(void)
|
||||
{
|
||||
struct winsize w;
|
||||
if (x >= 71) {
|
||||
/* Has been set with -w option */
|
||||
return x;
|
||||
int i;
|
||||
/* Initialize the moon array */
|
||||
if (encoding_is_utf8) {
|
||||
for (i=0; i<=31; i++) {
|
||||
moons[i][0] = 0;
|
||||
}
|
||||
}
|
||||
if (!isatty(STDOUT_FILENO)) {
|
||||
/* Output is not a TTY... assume 80 */
|
||||
return 80;
|
||||
|
||||
/* Clear SHADEs */
|
||||
if (UseBGVTColors) {
|
||||
for (i=0; i<=31; i++) {
|
||||
bgcolor[i][0] = -1;
|
||||
bgcolor[i][1] = -1;
|
||||
bgcolor[i][2] = -1;
|
||||
}
|
||||
}
|
||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) < 0) {
|
||||
return 80;
|
||||
|
||||
/* Clear weeks */
|
||||
for(i=0; i<=31; i++) {
|
||||
weeks[i][0] = 0;
|
||||
}
|
||||
if (w.ws_col < 71) {
|
||||
return 71;
|
||||
}
|
||||
return w.ws_col;
|
||||
}
|
||||
|
||||
static void
|
||||
SetShadeEntry(int jul, char const *shade)
|
||||
{
|
||||
int y, m, d;
|
||||
int r, g, b;
|
||||
/* Don't bother if we're not doing SHADE specials */
|
||||
if (!UseBGVTColors) {
|
||||
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[28];
|
||||
|
||||
/* Don't bother unless it's utf-8 */
|
||||
if (!encoding_is_utf8) {
|
||||
return;
|
||||
}
|
||||
|
||||
msg[0] = 0;
|
||||
if (sscanf(moon, "%d %*d %*d %27[^\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 */
|
||||
@@ -623,8 +801,6 @@ void ProduceCalendar(void)
|
||||
}
|
||||
ShouldCache = 1;
|
||||
|
||||
CalWidth = ComputeCalWidth(CalWidth);
|
||||
|
||||
ColSpaces = (CalWidth - 9) / 7;
|
||||
CalWidth = 7*ColSpaces + 8;
|
||||
|
||||
@@ -677,18 +853,22 @@ static void DoCalendarOneWeek(int nleft)
|
||||
int LinesWritten = 0;
|
||||
int OrigJul = JulianToday;
|
||||
|
||||
InitMoonsAndShades();
|
||||
/* Fill in the column entries */
|
||||
for (i=0; i<7; i++) {
|
||||
ColToDay[i] = DayOf(JulianToday);
|
||||
GenerateCalEntries(i);
|
||||
JulianToday++;
|
||||
}
|
||||
|
||||
/* Output the entries */
|
||||
/* Figure out weekday of first column */
|
||||
|
||||
if (MondayFirst) wd = JulianToday % 7;
|
||||
else wd = (JulianToday + 1) % 7;
|
||||
|
||||
/* Output the entries */
|
||||
/* If it's "Simple Calendar" format, do it simply... */
|
||||
if (DoSimpleCalendar) {
|
||||
if (MondayFirst) wd = JulianToday % 7;
|
||||
else wd = (JulianToday + 1) % 7;
|
||||
for (i=0; i<7; i++) {
|
||||
WriteSimpleEntries(i, OrigJul+i-wd);
|
||||
}
|
||||
@@ -700,13 +880,33 @@ static void DoCalendarOneWeek(int nleft)
|
||||
DRAW(tb);
|
||||
goff();
|
||||
for (i=0; i<7; i++) {
|
||||
FromJulian(OrigJul+i, &y, &m, &d);
|
||||
FromJulian(OrigJul+i, &y, &m, &d);
|
||||
char const *mon = get_month_name(m);
|
||||
snprintf(buf, sizeof(buf), "%d %s ", d, get_month_abbrev(mon));
|
||||
if (OrigJul+i == RealToday)
|
||||
PrintLeft(buf, ColSpaces, '*');
|
||||
else
|
||||
if (moons[d][0]) {
|
||||
if (weeks[d][0]) {
|
||||
snprintf(buf, sizeof(buf), "%d %s %s %s ", d, get_month_abbrev(mon), weeks[d], moons[d]);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%d %s %s ", d, get_month_abbrev(mon), moons[d]);
|
||||
}
|
||||
} else {
|
||||
if (weeks[d][0]) {
|
||||
snprintf(buf, sizeof(buf), "%d %s %s ", d, get_month_abbrev(mon), weeks[d]);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%d %s ", d, get_month_abbrev(mon));
|
||||
}
|
||||
}
|
||||
if (OrigJul+i == RealToday) {
|
||||
if (UseVTColors) {
|
||||
printf("\x1B[1m"); /* Bold */
|
||||
}
|
||||
PrintLeft(buf, ColSpaces-1, '*');
|
||||
if (UseVTColors) {
|
||||
printf("\x1B[0m"); /* Normal */
|
||||
}
|
||||
putchar(' ');
|
||||
} else {
|
||||
PrintLeft(buf, ColSpaces, ' ');
|
||||
}
|
||||
gon();
|
||||
DRAW(tb);
|
||||
goff();
|
||||
@@ -717,7 +917,10 @@ static void DoCalendarOneWeek(int nleft)
|
||||
DRAW(tb);
|
||||
goff();
|
||||
for (i=0; i<7; i++) {
|
||||
d = ColToDay[i];
|
||||
Backgroundize(d);
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
UnBackgroundize(d);
|
||||
gon();
|
||||
DRAW(tb);
|
||||
goff();
|
||||
@@ -728,7 +931,7 @@ static void DoCalendarOneWeek(int nleft)
|
||||
/* Write the body lines */
|
||||
done = 0;
|
||||
while (!done) {
|
||||
done = WriteOneCalLine();
|
||||
done = WriteOneCalLine(OrigJul, wd);
|
||||
LinesWritten++;
|
||||
}
|
||||
|
||||
@@ -738,7 +941,10 @@ static void DoCalendarOneWeek(int nleft)
|
||||
DRAW(tb);
|
||||
goff();
|
||||
for (i=0; i<7; i++) {
|
||||
d = ColToDay[i];
|
||||
Backgroundize(d);
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
UnBackgroundize(d);
|
||||
gon();
|
||||
DRAW(tb);
|
||||
goff();
|
||||
@@ -765,6 +971,8 @@ static void DoCalendarOneMonth(void)
|
||||
{
|
||||
int y, m, d, mm, yy, i, j;
|
||||
|
||||
InitMoonsAndShades();
|
||||
|
||||
if (!DoSimpleCalendar) WriteCalHeader();
|
||||
|
||||
DidADay = 0;
|
||||
@@ -865,10 +1073,15 @@ static int WriteCalendarRow(void)
|
||||
if (!MondayFirst) wd = (JulianToday + 1) % 7;
|
||||
else wd = JulianToday % 7;
|
||||
|
||||
for (i=0; i<7; i++) {
|
||||
ColToDay[i] = 0;
|
||||
}
|
||||
|
||||
/* Fill in the column entries */
|
||||
for (i=wd; i<7; i++) {
|
||||
if (d+i-wd > DaysInMonth(m, y)) break;
|
||||
GenerateCalEntries(i);
|
||||
ColToDay[i] = DayOf(JulianToday);
|
||||
JulianToday++;
|
||||
}
|
||||
|
||||
@@ -891,9 +1104,27 @@ static int WriteCalendarRow(void)
|
||||
if (i < wd || d+i-wd>DaysInMonth(m, y))
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
else {
|
||||
sprintf(buf, "%d ", d+i-wd);
|
||||
if (moons[d+i-wd][0]) {
|
||||
if (weeks[d+i-wd][0]) {
|
||||
snprintf(buf, sizeof(buf), "%d %s %s ", d+i-wd, weeks[d+i-wd], moons[d+i-wd]);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%d %s ", d+i-wd, moons[d+i-wd]);
|
||||
}
|
||||
} else {
|
||||
if (weeks[d+i-wd][0]) {
|
||||
snprintf(buf, sizeof(buf), "%d %s ", d+i-wd, weeks[d+i-wd]);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%d ", d+i-wd);
|
||||
}
|
||||
}
|
||||
if (Julian(y, m, d+i-wd) == RealToday) {
|
||||
if (UseVTColors) {
|
||||
printf("\x1B[1m"); /* Bold */
|
||||
}
|
||||
PrintLeft(buf, ColSpaces-1, '*');
|
||||
if (UseVTColors) {
|
||||
printf("\x1B[0m"); /* Normal */
|
||||
}
|
||||
putchar(' ');
|
||||
} else {
|
||||
PrintLeft(buf, ColSpaces, ' ');
|
||||
@@ -909,7 +1140,9 @@ static int WriteCalendarRow(void)
|
||||
DRAW(tb);
|
||||
goff();
|
||||
for (i=0; i<7; i++) {
|
||||
Backgroundize(ColToDay[i]);
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
UnBackgroundize(ColToDay[i]);
|
||||
gon();
|
||||
DRAW(tb);
|
||||
goff();
|
||||
@@ -920,7 +1153,7 @@ static int WriteCalendarRow(void)
|
||||
/* Write the body lines */
|
||||
done = 0;
|
||||
while (!done) {
|
||||
done = WriteOneCalLine();
|
||||
done = WriteOneCalLine(OrigJul, wd);
|
||||
LinesWritten++;
|
||||
}
|
||||
|
||||
@@ -930,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();
|
||||
@@ -1101,19 +1336,25 @@ static void PrintCentered(char const *s, int width, char *pad)
|
||||
/* Write a single line. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int WriteOneCalLine(void)
|
||||
static int WriteOneCalLine(int start_jul, int wd)
|
||||
{
|
||||
int done = 1, i;
|
||||
int y, m, d;
|
||||
|
||||
gon();
|
||||
DRAW(tb);
|
||||
goff();
|
||||
for (i=0; i<7; i++) {
|
||||
FromJulian(start_jul+i, &y, &m, &d);
|
||||
d -= wd;
|
||||
if (CalColumn[i]) {
|
||||
Backgroundize(ColToDay[i]);
|
||||
if (WriteOneColLine(i)) done = 0;
|
||||
} else {
|
||||
Backgroundize(ColToDay[i]);
|
||||
PrintCentered("", ColSpaces, " ");
|
||||
}
|
||||
UnBackgroundize(ColToDay[i]);
|
||||
gon();
|
||||
DRAW(tb);
|
||||
goff();
|
||||
@@ -1142,9 +1383,12 @@ static int WriteOneColLine(int col)
|
||||
wchar_t const *wspace;
|
||||
int width;
|
||||
#endif
|
||||
|
||||
int clamp = 1;
|
||||
int numwritten = 0;
|
||||
|
||||
int d = ColToDay[col];
|
||||
if (d && UseBGVTColors && bgcolor[d][0] != -1) {
|
||||
clamp = 0;
|
||||
}
|
||||
/* Print as many characters as possible within the column */
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (e->wc_text) {
|
||||
@@ -1187,7 +1431,7 @@ static int WriteOneColLine(int col)
|
||||
|
||||
/* Colorize reminder if necessary */
|
||||
if (UseVTColors && e->is_color) {
|
||||
ColorizeEntry(e);
|
||||
ColorizeEntry(e, clamp);
|
||||
}
|
||||
|
||||
/* If we couldn't find a space char, print what we have. */
|
||||
@@ -1224,9 +1468,10 @@ static int WriteOneColLine(int col)
|
||||
}
|
||||
}
|
||||
|
||||
/* Decolorize reminder if necessary */
|
||||
/* Decolorize reminder if necessary, but keep any SHADE */
|
||||
if (UseVTColors && e->is_color) {
|
||||
printf("%s", Decolorize(e->r, e->g, e->b));
|
||||
printf("%s", Decolorize());
|
||||
Backgroundize(d);
|
||||
}
|
||||
|
||||
/* Possibly send lrm control sequence */
|
||||
@@ -1279,7 +1524,7 @@ static int WriteOneColLine(int col)
|
||||
|
||||
/* Colorize reminder if necessary */
|
||||
if (UseVTColors && e->is_color) {
|
||||
ColorizeEntry(e);
|
||||
ColorizeEntry(e, clamp);
|
||||
}
|
||||
|
||||
/* If we couldn't find a space char, print what we have. */
|
||||
@@ -1307,9 +1552,10 @@ static int WriteOneColLine(int col)
|
||||
}
|
||||
}
|
||||
|
||||
/* Decolorize reminder if necessary */
|
||||
/* Decolorize reminder if necessary, but keep SHADE */
|
||||
if (UseVTColors && e->is_color) {
|
||||
printf("%s", Decolorize(e->r, e->g, e->b));
|
||||
printf("%s", Decolorize());
|
||||
Backgroundize(d);
|
||||
}
|
||||
|
||||
/* Flesh out the rest of the column */
|
||||
@@ -1403,6 +1649,7 @@ static void GenerateCalEntries(int col)
|
||||
case T_Exit: DoExit(&p); break;
|
||||
case T_Set: r=DoSet(&p); break;
|
||||
case T_Fset: r=DoFset(&p); break;
|
||||
case T_Funset: r=DoFunset(&p); break;
|
||||
case T_UnSet: r=DoUnset(&p); break;
|
||||
case T_Clr: r=DoClear(&p); break;
|
||||
case T_Flush: r=DoFlush(&p); break;
|
||||
@@ -1583,6 +1830,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);
|
||||
@@ -1646,10 +1906,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;
|
||||
@@ -1908,6 +2207,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);
|
||||
@@ -2034,6 +2334,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("\"");
|
||||
|
||||
28
src/dorem.c
28
src/dorem.c
@@ -96,9 +96,13 @@ int DoRem(ParsePtr p)
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
DBufFree(&buf);
|
||||
if (tok.type == T_Empty || tok.type == T_Comment) {
|
||||
r = OK;
|
||||
if (trig.addomit) {
|
||||
r = AddGlobalOmit(LastTriggerDate);
|
||||
}
|
||||
DBufFree(&buf);
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
return r;
|
||||
}
|
||||
if (tok.type != T_RemType || tok.val == SAT_TYPE) {
|
||||
DBufFree(&buf);
|
||||
@@ -470,7 +474,12 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
case T_Tag:
|
||||
r = ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
if (strchr(DBufValue(&buf), ',')) {
|
||||
DBufFree(&buf);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
AppendTag(&(trig->tags), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
break;
|
||||
|
||||
case T_Duration:
|
||||
@@ -868,6 +877,8 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* TriggerReminder */
|
||||
@@ -929,12 +940,13 @@ 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)) {
|
||||
printf("%s\n", DBufValue(&buf));
|
||||
}
|
||||
printf("%s\n", DBufValue(&buf));
|
||||
}
|
||||
DBufFree(&buf);
|
||||
}
|
||||
|
||||
@@ -1030,7 +1042,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 +1056,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 +1067,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 +1081,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) {
|
||||
|
||||
@@ -51,6 +51,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
int d, m, y;
|
||||
int tim = tt->ttime;
|
||||
int h, min, hh, ch, cmin, chh;
|
||||
int i;
|
||||
char const *pm, *cpm;
|
||||
int tdiff, adiff, mdiff, hdiff;
|
||||
char const *mplu, *hplu, *when, *plu;
|
||||
@@ -190,8 +191,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
}
|
||||
if (c == '\n') continue;
|
||||
if (!c) {
|
||||
if (mode != CAL_MODE && mode != ADVANCE_MODE &&
|
||||
t->typ != RUN_TYPE && !MsgCommand) {
|
||||
if (AddBlankLines &&
|
||||
mode != CAL_MODE &&
|
||||
mode != ADVANCE_MODE &&
|
||||
t->typ != RUN_TYPE &&
|
||||
!MsgCommand) {
|
||||
if (DBufPutc(dbuf, '\n') != OK) return E_NO_MEM;
|
||||
}
|
||||
break;
|
||||
@@ -221,11 +225,32 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
break;
|
||||
}
|
||||
}
|
||||
done = 0;
|
||||
snprintf(uf, sizeof(uf), "subst_%c", c);
|
||||
if (UserFuncExists(uf) == 3) {
|
||||
snprintf(s, sizeof(s), "subst_%c(%d,'%04d-%02d-%02d',%02d:%02d)",
|
||||
c, altmode ? 1 : 0, y, m+1, d, h, min);
|
||||
if (c == '{') {
|
||||
i = 0;
|
||||
ss = s + snprintf(s, sizeof(s), "subst_");
|
||||
while (1) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
if (c == '}' || !c) {
|
||||
break;
|
||||
}
|
||||
if (i < 64) {
|
||||
*ss++ = c;
|
||||
*ss = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (!c) {
|
||||
Wprint("Warning: Unterminated %{...} substitution sequence");
|
||||
}
|
||||
if (UserFuncExists(s) != 3) {
|
||||
continue;
|
||||
}
|
||||
snprintf(ss, sizeof(s) - (ss-s), "(%d,'%04d-%02d-%02d',%02d:%02d)",
|
||||
altmode ? 1 : 0, y, m+1, d, h, min);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
@@ -236,7 +261,28 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
}
|
||||
}
|
||||
DestroyValue(v);
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
done = 0;
|
||||
snprintf(uf, sizeof(uf), "subst_%c", c);
|
||||
if (UserFuncExists(uf) == 3) {
|
||||
snprintf(s, sizeof(s), "subst_%c(%d,'%04d-%02d-%02d',%02d:%02d)",
|
||||
c, altmode ? 1 : 0, y, m+1, d, h, min);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (v.type != INT_TYPE || v.v.val != 0) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
if (DBufPuts(dbuf, v.v.str) != OK) {
|
||||
DestroyValue(v);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
DestroyValue(v);
|
||||
continue;
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
}
|
||||
@@ -301,14 +347,17 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
if (DBufPuts(dbuf, v.v.str) != OK) {
|
||||
DestroyValue(v);
|
||||
return E_NO_MEM;
|
||||
if (v.type != INT_TYPE || v.v.val != 0) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
if (DBufPuts(dbuf, v.v.str) != OK) {
|
||||
DestroyValue(v);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
DestroyValue(v);
|
||||
continue;
|
||||
}
|
||||
DestroyValue(v);
|
||||
continue;
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ int DBufGets(DynamicBuffer *dbuf, FILE *fp);
|
||||
#define DBufValue(bufPtr) ((bufPtr)->buffer)
|
||||
#define DBufLen(bufPtr) ((bufPtr)->len)
|
||||
|
||||
#define DBufPutc(dbuf, c) ( (dbuf)->allocatedLen < (dbuf)->len+1 ) ? (dbuf)->buffer[(dbuf)->len++] = c, (dbuf)->buffer[(dbuf)->len] = 0, OK : DBufPutcFN((dbuf), c)
|
||||
#define DBufPutc(dbuf, c) ( ( (dbuf)->allocatedLen <= (dbuf)->len+1 ) ? \
|
||||
DBufPutcFN( (dbuf), c) : \
|
||||
( (dbuf)->buffer[(dbuf)->len++] = c, (dbuf)->buffer[(dbuf)->len] = 0, OK) )
|
||||
|
||||
#endif /* DYNBUF_H */
|
||||
|
||||
@@ -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",
|
||||
|
||||
39
src/expr.c
39
src/expr.c
@@ -84,10 +84,12 @@ Operator UnOp[] = {
|
||||
|
||||
extern BuiltinFunc Func[];
|
||||
|
||||
Operator OpStack[OP_STACK_SIZE];
|
||||
Value ValStack[VAL_STACK_SIZE];
|
||||
int OpStackPtr = 0;
|
||||
int ValStackPtr = 0;
|
||||
static Operator OpStack[OP_STACK_SIZE];
|
||||
static int OpStackPtr = 0;
|
||||
|
||||
/* ValStack can't be static - needed by funcs.c */
|
||||
Value ValStack[VAL_STACK_SIZE];
|
||||
int ValStackPtr = 0;
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -251,6 +253,10 @@ static int ParseExprToken(DynamicBuffer *buf, char const **in)
|
||||
DBufFree(buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (!**in) {
|
||||
DBufFree(buf);
|
||||
return E_MISS_QUOTE;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
c = *(*in)++;
|
||||
@@ -1238,12 +1244,31 @@ BuiltinFunc *FindFunc(char const *name, BuiltinFunc where[], int num)
|
||||
void PrintValue (Value *v, FILE *fp)
|
||||
{
|
||||
int y, m, d;
|
||||
char const *s;
|
||||
unsigned char const *s;
|
||||
|
||||
if (v->type == STR_TYPE) {
|
||||
s=v->v.str;
|
||||
s = (unsigned char const *) v->v.str;
|
||||
putc('"', fp);
|
||||
for (y=0; y<MAX_PRT_LEN && *s; y++) putc(*s++, fp);
|
||||
for (y=0; y<MAX_PRT_LEN && *s; y++) {
|
||||
switch(*s) {
|
||||
case '\a': fprintf(ErrFp, "\\a"); break;
|
||||
case '\b': fprintf(ErrFp, "\\b"); break;
|
||||
case '\f': fprintf(ErrFp, "\\f"); break;
|
||||
case '\n': fprintf(ErrFp, "\\n"); break;
|
||||
case '\r': fprintf(ErrFp, "\\r"); break;
|
||||
case '\t': fprintf(ErrFp, "\\t"); break;
|
||||
case '\v': fprintf(ErrFp, "\\v"); break;
|
||||
case '"': fprintf(ErrFp, "\\\""); break;
|
||||
case '\\': fprintf(ErrFp, "\\\\"); break;
|
||||
default:
|
||||
if (*s < 32) {
|
||||
fprintf(ErrFp, "\\x%02x", (unsigned int) *s);
|
||||
} else {
|
||||
putc(*s, ErrFp); break;
|
||||
}
|
||||
}
|
||||
s++;
|
||||
}
|
||||
putc('"',fp);
|
||||
if (*s) fprintf(fp, "...");
|
||||
}
|
||||
|
||||
328
src/funcs.c
328
src/funcs.c
@@ -13,12 +13,19 @@
|
||||
#include "version.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -58,6 +65,7 @@ static int FADusk (func_info *);
|
||||
static int FAbs (func_info *);
|
||||
static int FAccess (func_info *);
|
||||
static int FAmpm (func_info *);
|
||||
static int FAnsicolor (func_info *);
|
||||
static int FTrig (func_info *);
|
||||
static int FIsAny (func_info *);
|
||||
static int FArgs (func_info *);
|
||||
@@ -66,6 +74,7 @@ static int FBaseyr (func_info *);
|
||||
static int FChar (func_info *);
|
||||
static int FChoose (func_info *);
|
||||
static int FCoerce (func_info *);
|
||||
static int FColumns (func_info *);
|
||||
static int FCurrent (func_info *);
|
||||
static int FDate (func_info *);
|
||||
static int FDateTime (func_info *);
|
||||
@@ -94,6 +103,7 @@ static int FIsdst (func_info *);
|
||||
static int FIsleap (func_info *);
|
||||
static int FIsomitted (func_info *);
|
||||
static int FLanguage (func_info *);
|
||||
static int FLocalToUTC (func_info *);
|
||||
static int FLower (func_info *);
|
||||
static int FMax (func_info *);
|
||||
static int FMin (func_info *);
|
||||
@@ -118,15 +128,18 @@ static int FPsshade (func_info *);
|
||||
static int FRealCurrent (func_info *);
|
||||
static int FRealnow (func_info *);
|
||||
static int FRealtoday (func_info *);
|
||||
static int FRows (func_info *);
|
||||
static int FSgn (func_info *);
|
||||
static int FShell (func_info *);
|
||||
static int FSlide (func_info *);
|
||||
static int FStdout (func_info *);
|
||||
static int FStrlen (func_info *);
|
||||
static int FSubstr (func_info *);
|
||||
static int FSunrise (func_info *);
|
||||
static int FSunset (func_info *);
|
||||
static int FTime (func_info *);
|
||||
static int FTimepart (func_info *);
|
||||
static int FTimezone (func_info *);
|
||||
static int FToday (func_info *);
|
||||
static int FTrig (func_info *);
|
||||
static int FTrigback (func_info *);
|
||||
@@ -139,6 +152,7 @@ static int FTrigeventstart (func_info *);
|
||||
static int FTrigfrom (func_info *);
|
||||
static int FTrigger (func_info *);
|
||||
static int FTrigpriority (func_info *);
|
||||
static int FTrigtags (func_info *);
|
||||
static int FTrigrep (func_info *);
|
||||
static int FTrigscanfrom (func_info *);
|
||||
static int FTrigtime (func_info *);
|
||||
@@ -149,6 +163,7 @@ static int FTrigvalid (func_info *);
|
||||
static int FTypeof (func_info *);
|
||||
static int FTzconvert (func_info *);
|
||||
static int FUpper (func_info *);
|
||||
static int FUTCToLocal (func_info *);
|
||||
static int FValue (func_info *);
|
||||
static int FVersion (func_info *);
|
||||
static int FWeekno (func_info *);
|
||||
@@ -160,6 +175,7 @@ static int FShellescape (func_info *);
|
||||
static int CleanUpAfterFunc (func_info *);
|
||||
static int CheckArgs (BuiltinFunc *f, int nargs);
|
||||
static int SunStuff (int rise, double cosz, int jul);
|
||||
static int tz_set_tz (char const *tz);
|
||||
|
||||
/* "Overload" the struct Operator definition */
|
||||
#define NO_MAX 127
|
||||
@@ -213,12 +229,14 @@ BuiltinFunc Func[] = {
|
||||
{ "adawn", 0, 1, 0, FADawn},
|
||||
{ "adusk", 0, 1, 0, FADusk},
|
||||
{ "ampm", 1, 3, 1, FAmpm },
|
||||
{ "ansicolor", 1, 5, 1, FAnsicolor },
|
||||
{ "args", 1, 1, 0, FArgs },
|
||||
{ "asc", 1, 1, 1, FAsc },
|
||||
{ "baseyr", 0, 0, 1, FBaseyr },
|
||||
{ "char", 1, NO_MAX, 1, FChar },
|
||||
{ "choose", 2, NO_MAX, 1, FChoose },
|
||||
{ "coerce", 2, 2, 1, FCoerce },
|
||||
{ "columns", 0, 1, 0, FColumns },
|
||||
{ "current", 0, 0, 0, FCurrent },
|
||||
{ "date", 3, 3, 1, FDate },
|
||||
{ "datepart", 1, 1, 1, FDatepart },
|
||||
@@ -248,6 +266,7 @@ BuiltinFunc Func[] = {
|
||||
{ "isleap", 1, 1, 1, FIsleap },
|
||||
{ "isomitted", 1, 1, 0, FIsomitted },
|
||||
{ "language", 0, 0, 1, FLanguage },
|
||||
{ "localtoutc", 1, 1, 1, FLocalToUTC },
|
||||
{ "lower", 1, 1, 1, FLower },
|
||||
{ "max", 1, NO_MAX, 1, FMax },
|
||||
{ "min", 1, NO_MAX, 1, FMin },
|
||||
@@ -272,16 +291,19 @@ BuiltinFunc Func[] = {
|
||||
{ "realcurrent", 0, 0, 0, FRealCurrent},
|
||||
{ "realnow", 0, 0, 0, FRealnow},
|
||||
{ "realtoday", 0, 0, 0, FRealtoday },
|
||||
{ "rows", 0, 0, 0, FRows },
|
||||
{ "sgn", 1, 1, 1, FSgn },
|
||||
{ "shell", 1, 2, 0, FShell },
|
||||
{ "shellescape", 1, 1, 1, FShellescape },
|
||||
{ "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},
|
||||
{ "sunset", 0, 1, 0, FSunset },
|
||||
{ "time", 2, 2, 1, FTime },
|
||||
{ "timepart", 1, 1, 1, FTimepart },
|
||||
{ "timezone", 0, 1, 1, FTimezone },
|
||||
{ "today", 0, 0, 0, FToday },
|
||||
{ "trig", 0, NO_MAX, 0, FTrig },
|
||||
{ "trigback", 0, 0, 0, FTrigback },
|
||||
@@ -296,6 +318,7 @@ BuiltinFunc Func[] = {
|
||||
{ "trigpriority", 0, 0, 0, FTrigpriority },
|
||||
{ "trigrep", 0, 0, 0, FTrigrep },
|
||||
{ "trigscanfrom", 0, 0, 0, FTrigscanfrom },
|
||||
{ "trigtags", 0, 0, 0, FTrigtags },
|
||||
{ "trigtime", 0, 0, 0, FTrigtime },
|
||||
{ "trigtimedelta",0, 0, 0, FTrigtimedelta },
|
||||
{ "trigtimerep", 0, 0, 0, FTrigtimerep },
|
||||
@@ -304,6 +327,7 @@ BuiltinFunc Func[] = {
|
||||
{ "typeof", 1, 1, 1, FTypeof },
|
||||
{ "tzconvert", 2, 3, 0, FTzconvert },
|
||||
{ "upper", 1, 1, 1, FUpper },
|
||||
{ "utctolocal", 1, 1, 1, FUTCToLocal },
|
||||
{ "value", 1, 2, 0, FValue },
|
||||
{ "version", 0, 0, 1, FVersion },
|
||||
{ "weekno", 0, 3, 1, FWeekno },
|
||||
@@ -902,6 +926,87 @@ static int FSgn(func_info *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int parse_color_helper(char const *str, int *r, int *g, int *b)
|
||||
{
|
||||
if (!*str) {
|
||||
/* Empty string means "reset to normal" */
|
||||
*r = -1;
|
||||
*g = -1;
|
||||
*b = -1;
|
||||
return OK;
|
||||
}
|
||||
if (sscanf(str, "%d %d %d", r, g, b) != 3) {
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FAnsicolor - return an ANSI terminal color sequence */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int FAnsicolor(func_info *info)
|
||||
{
|
||||
int r=0, g=0, b=0, bg=0, clamp=1;
|
||||
int status = 0;
|
||||
int index = 0;
|
||||
bg = 0;
|
||||
clamp = 1;
|
||||
|
||||
/* If first arg is a string: Parse out the colors */
|
||||
if (ARG(0).type == STR_TYPE) {
|
||||
/* If first arg is a string: Parse out the colors */
|
||||
status = parse_color_helper(ARGSTR(0), &r, &g, &b);
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
index = 1;
|
||||
} else if (ARG(0).type == INT_TYPE) {
|
||||
/* Must be at least three arguments */
|
||||
if (Nargs < 3) return E_2FEW_ARGS;
|
||||
ASSERT_TYPE(1, INT_TYPE);
|
||||
ASSERT_TYPE(2, INT_TYPE);
|
||||
r = ARGV(0);
|
||||
g = ARGV(1);
|
||||
b = ARGV(2);
|
||||
index = 3;
|
||||
}
|
||||
if (r < -1 || g < -1 || b < -1) return E_2LOW;
|
||||
if (r > 255 || g > 255 || b > 255) return E_2HIGH;
|
||||
/* If any is -1, then all must be -1 */
|
||||
if (r == -1 || g == -1 || b == -1) {
|
||||
if (r != -1 || g != -1 || b != -1) {
|
||||
return E_2LOW;
|
||||
}
|
||||
}
|
||||
if (Nargs > index) {
|
||||
ASSERT_TYPE(index, INT_TYPE);
|
||||
if (ARGV(index) < 0) return E_2LOW;
|
||||
if (ARGV(index) > 1) return E_2HIGH;
|
||||
bg = ARGV(index);
|
||||
index++;
|
||||
if (Nargs > index) {
|
||||
ASSERT_TYPE(index, INT_TYPE);
|
||||
if (ARGV(index) < 0) return E_2LOW;
|
||||
if (ARGV(index) > 1) return E_2HIGH;
|
||||
clamp = ARGV(index);
|
||||
}
|
||||
}
|
||||
|
||||
/* All righ! We have our parameters; now return the string */
|
||||
if (!UseVTColors) {
|
||||
/* Not using any colors: Empty strin */
|
||||
return RetStrVal("", info);
|
||||
}
|
||||
|
||||
if (r < 0) {
|
||||
/* Return ANSI "reset to normal" string */
|
||||
return RetStrVal(Decolorize(), info);
|
||||
}
|
||||
return RetStrVal(Colorize(r, g, b, bg, clamp), info);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FAmpm - return a time as a string with "AM" or "PM" suffix */
|
||||
@@ -1237,6 +1342,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" */
|
||||
@@ -1438,6 +1572,11 @@ static int FTrigrep(func_info *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FTrigtags(func_info *info)
|
||||
{
|
||||
return RetStrVal(DBufValue(&(LastTrigger.tags)), info);
|
||||
}
|
||||
|
||||
static int FTrigpriority(func_info *info)
|
||||
{
|
||||
RetVal.type = INT_TYPE;
|
||||
@@ -2194,6 +2333,115 @@ static int FTimeStuff(int wantmins, func_info *info)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FTimezone(func_info *info)
|
||||
{
|
||||
int yr, mon, day, hr, min, jul, now;
|
||||
struct tm local, *withzone;
|
||||
time_t t;
|
||||
char buf[64];
|
||||
|
||||
if (Nargs == 0) {
|
||||
jul = JulianToday;
|
||||
now = (SystemTime(0) / 60);
|
||||
} else {
|
||||
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
|
||||
jul = DATEPART(ARG(0));
|
||||
if (HASTIME(ARG(0))) {
|
||||
now = TIMEPART(ARG(0));
|
||||
} else {
|
||||
now = 0;
|
||||
}
|
||||
}
|
||||
FromJulian(jul, &yr, &mon, &day);
|
||||
hr = now / 60;
|
||||
min = now % 60;
|
||||
|
||||
memset(&local, 0, sizeof(local));
|
||||
local.tm_sec = 0;
|
||||
local.tm_min = min;
|
||||
local.tm_hour = hr;
|
||||
local.tm_mday = day;
|
||||
local.tm_mon = mon;
|
||||
local.tm_year = yr-1900;
|
||||
local.tm_isdst = -1;
|
||||
|
||||
t = mktime(&local);
|
||||
withzone = localtime(&t);
|
||||
buf[0] = 0;
|
||||
strftime(buf, sizeof(buf), "%Z", withzone);
|
||||
return RetStrVal(buf, info);
|
||||
}
|
||||
|
||||
static int FLocalToUTC(func_info *info)
|
||||
{
|
||||
int yr, mon, day, hr, min, jul;
|
||||
time_t loc_t;
|
||||
struct tm local, *utc;
|
||||
|
||||
ASSERT_TYPE(0, DATETIME_TYPE);
|
||||
|
||||
FromJulian(DATEPART(ARG(0)), &yr, &mon, &day);
|
||||
hr = TIMEPART(ARG(0))/60;
|
||||
min = TIMEPART(ARG(0))%60;
|
||||
|
||||
memset(&local, 0, sizeof(local));
|
||||
local.tm_sec = 0;
|
||||
local.tm_min = min;
|
||||
local.tm_hour = hr;
|
||||
local.tm_mday = day;
|
||||
local.tm_mon = mon;
|
||||
local.tm_year = yr-1900;
|
||||
local.tm_isdst = -1;
|
||||
loc_t = mktime(&local);
|
||||
if (loc_t == -1) {
|
||||
return E_MKTIME_PROBLEM;
|
||||
}
|
||||
|
||||
utc = gmtime(&loc_t);
|
||||
jul = Julian(utc->tm_year+1900, utc->tm_mon, utc->tm_mday);
|
||||
RetVal.type = DATETIME_TYPE;
|
||||
RETVAL = MINUTES_PER_DAY * jul + utc->tm_hour*60 + utc->tm_min;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FUTCToLocal(func_info *info)
|
||||
{
|
||||
int yr, mon, day, hr, min, jul;
|
||||
time_t utc_t;
|
||||
struct tm *local, utc;
|
||||
char const *old_tz;
|
||||
|
||||
ASSERT_TYPE(0, DATETIME_TYPE);
|
||||
FromJulian(DATEPART(ARG(0)), &yr, &mon, &day);
|
||||
hr = TIMEPART(ARG(0))/60;
|
||||
min = TIMEPART(ARG(0))%60;
|
||||
|
||||
old_tz = getenv("TZ");
|
||||
|
||||
tz_set_tz("UTC");
|
||||
|
||||
memset(&utc, 0, sizeof(utc));
|
||||
utc.tm_sec = 0;
|
||||
utc.tm_min = min;
|
||||
utc.tm_hour = hr;
|
||||
utc.tm_mday = day;
|
||||
utc.tm_mon = mon;
|
||||
utc.tm_year = yr-1900;
|
||||
utc.tm_isdst = 0;
|
||||
utc_t = mktime(&utc);
|
||||
tz_set_tz(old_tz);
|
||||
|
||||
if (utc_t == -1) {
|
||||
return E_MKTIME_PROBLEM;
|
||||
}
|
||||
|
||||
local = localtime(&utc_t);
|
||||
jul = Julian(local->tm_year+1900, local->tm_mon, local->tm_mday);
|
||||
RetVal.type = DATETIME_TYPE;
|
||||
RETVAL = MINUTES_PER_DAY * jul + local->tm_hour*60 + local->tm_min;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* Sunrise and sunset functions. */
|
||||
@@ -2895,11 +3143,11 @@ FSlide(func_info *info)
|
||||
}
|
||||
|
||||
/* If ALL weekdays are omitted... barf! */
|
||||
if (localomit == 127 && amt != 0) return E_2MANY_LOCALOMIT;
|
||||
if ((WeekdayOmits | localomit) == 0x7F && amt != 0) return E_2MANY_LOCALOMIT;
|
||||
if (amt > 0) {
|
||||
while(amt) {
|
||||
d++;
|
||||
r = IsOmitted(d, localomit, NULL,&omit);
|
||||
r = IsOmitted(d, localomit, NULL, &omit);
|
||||
if (r) return r;
|
||||
if (!omit) amt--;
|
||||
}
|
||||
@@ -2907,7 +3155,7 @@ FSlide(func_info *info)
|
||||
while(amt) {
|
||||
d--;
|
||||
if (d < 0) return E_DATE_OVER;
|
||||
r = IsOmitted(d, localomit, NULL,&omit);
|
||||
r = IsOmitted(d, localomit, NULL, &omit);
|
||||
if (r) return r;
|
||||
if (!omit) amt++;
|
||||
}
|
||||
@@ -3134,3 +3382,77 @@ FTrig(func_info *info)
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int
|
||||
rows_or_cols(func_info *info, int want_rows)
|
||||
{
|
||||
struct winsize w;
|
||||
int fd = STDOUT_FILENO;
|
||||
|
||||
RetVal.type = INT_TYPE;
|
||||
if (!isatty(fd)) {
|
||||
fd = open("/dev/tty", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
RETVAL = -1;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
if (ioctl(fd, TIOCGWINSZ, &w) == 0) {
|
||||
if (want_rows) RETVAL = w.ws_row;
|
||||
else RETVAL = w.ws_col;
|
||||
} else {
|
||||
RETVAL = -1;
|
||||
}
|
||||
if (fd != STDOUT_FILENO) {
|
||||
close(fd);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int FRows(func_info *info)
|
||||
{
|
||||
return rows_or_cols(info, 1);
|
||||
}
|
||||
static int FColumns(func_info *info)
|
||||
{
|
||||
#ifdef REM_USE_WCHAR
|
||||
size_t len;
|
||||
wchar_t *buf, *s;
|
||||
int width;
|
||||
#endif
|
||||
if (Nargs == 0) {
|
||||
return rows_or_cols(info, 0);
|
||||
}
|
||||
ASSERT_TYPE(0, STR_TYPE);
|
||||
#ifdef REM_USE_WCHAR
|
||||
len = mbstowcs(NULL, ARGSTR(0), 0);
|
||||
if (len == (size_t) -1) return E_NO_MEM;
|
||||
buf = calloc(len+1, sizeof(wchar_t));
|
||||
if (!buf) return E_NO_MEM;
|
||||
(void) mbstowcs(buf, ARGSTR(0), len+1);
|
||||
|
||||
s = buf;
|
||||
width = 0;
|
||||
while (*s) {
|
||||
if (*s == 0x1B && *(s+1) == '[') {
|
||||
/* Skip escape sequences */
|
||||
s += 2;
|
||||
while (*s && (*s < 0x40 || *s > 0x7E)) {
|
||||
s++;
|
||||
}
|
||||
if (*s) {
|
||||
s++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
width += wcwidth(*s);
|
||||
s++;
|
||||
}
|
||||
free(buf);
|
||||
RetVal.type = INT_TYPE;
|
||||
RETVAL = width;
|
||||
return OK;
|
||||
#else
|
||||
return E_BAD_TYPE;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -58,9 +58,10 @@ EXTERN INIT( int DoSimpleCalendar, 0);
|
||||
EXTERN INIT( int DoSimpleCalDelta, 0);
|
||||
EXTERN INIT( int DoPrefixLineNo, 0);
|
||||
EXTERN INIT( int MondayFirst, 0);
|
||||
EXTERN INIT( int AddBlankLines, 1);
|
||||
EXTERN INIT( int Iterations, 1);
|
||||
EXTERN INIT( int PsCal, 0);
|
||||
EXTERN INIT( int CalWidth, -1);
|
||||
EXTERN INIT( int CalWidth, 80);
|
||||
EXTERN INIT( int CalWeeks, 0);
|
||||
EXTERN INIT( int CalMonths, 0);
|
||||
EXTERN INIT( int Hush, 0);
|
||||
@@ -80,6 +81,7 @@ EXTERN INIT( long SysTime, -1L);
|
||||
EXTERN char const *InitialFile;
|
||||
EXTERN int FileAccessDate;
|
||||
|
||||
EXTERN INIT( int WeekdayOmits, 0);
|
||||
EXTERN INIT( int DontSuppressQuoteMarkers, 0);
|
||||
EXTERN INIT( int DontFork, 0);
|
||||
EXTERN INIT( int DontQueue, 0);
|
||||
@@ -111,11 +113,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 UseBGVTColors, 0);
|
||||
EXTERN INIT( int UseUTF8Chars, 0);
|
||||
EXTERN INIT( int UseVTColors, 0);
|
||||
EXTERN INIT( int Use256Colors, 0);
|
||||
@@ -313,6 +317,12 @@ EXTERN char *DynamicWas
|
||||
|
||||
EXTERN char *SysDir
|
||||
#ifdef MK_GLOBALS
|
||||
= STRSYSDIR(SYSDIR);
|
||||
= STRSYSDIR(SYSDIR)
|
||||
#endif
|
||||
;
|
||||
|
||||
EXTERN int SuppressLRM
|
||||
#ifdef MK_GLOBALS
|
||||
= 0
|
||||
#endif
|
||||
;
|
||||
|
||||
96
src/init.c
96
src/init.c
@@ -21,6 +21,10 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -43,7 +47,8 @@
|
||||
* simple calendar format.
|
||||
* -r = Disallow RUN mode
|
||||
* -c[n] = Produce a calendar for n months (default = 1)
|
||||
* -@[n,m] = Colorize n=0 VT100 n=1 85 n=2 True m=0 dark terminal m=1 light
|
||||
* -@[n,m,b]= Colorize n=0 VT100 n=1 85 n=2 True m=0 dark terminal m=1 light
|
||||
* b=0 ignore SHADE b=1 respect SHADE
|
||||
* -w[n,n,n] = Specify output device width, padding and spacing
|
||||
* -s[n] = Produce calendar in "simple calendar" format
|
||||
* -p[n] = Produce calendar in format compatible with rem2ps
|
||||
@@ -94,6 +99,25 @@ static void AddTrustedUser(char const *username);
|
||||
|
||||
static DynamicBuffer default_filename_buf;
|
||||
|
||||
static void
|
||||
InitCalWidthAndFormWidth(int fd)
|
||||
{
|
||||
struct winsize w;
|
||||
|
||||
if (!isatty(fd)) {
|
||||
return;
|
||||
}
|
||||
if (ioctl(fd, TIOCGWINSZ, &w) == 0) {
|
||||
CalWidth = w.ws_col;
|
||||
if (CalWidth < 71) {
|
||||
CalWidth = 71;
|
||||
}
|
||||
FormWidth = w.ws_col - 8;
|
||||
if (FormWidth < 20) FormWidth = 20;
|
||||
if (FormWidth > 500) FormWidth = 500;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DefaultFilename */
|
||||
@@ -141,19 +165,13 @@ void InitRemind(int argc, char const *argv[])
|
||||
int weeks;
|
||||
int x;
|
||||
int jul;
|
||||
int ttyfd;
|
||||
|
||||
jul = NO_DATE;
|
||||
|
||||
/* If stdout is a terminal, initialize $FormWidth to terminal width-8,
|
||||
but clamp to [20, 500] */
|
||||
if (isatty(STDOUT_FILENO)) {
|
||||
struct winsize w;
|
||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0) {
|
||||
FormWidth = w.ws_col - 8;
|
||||
if (FormWidth < 20) FormWidth = 20;
|
||||
if (FormWidth > 500) FormWidth = 500;
|
||||
}
|
||||
}
|
||||
InitCalWidthAndFormWidth(STDOUT_FILENO);
|
||||
|
||||
/* Initialize global dynamic buffers */
|
||||
DBufInit(&Banner);
|
||||
@@ -233,22 +251,36 @@ void InitRemind(int argc, char const *argv[])
|
||||
} else if (x == 2) {
|
||||
UseTrueColors = 1;
|
||||
} else if (x != 0) {
|
||||
fprintf(ErrFp, "%s: -@n,m: n must be 0, 1 or 2 (assuming 0)\n",
|
||||
fprintf(ErrFp, "%s: -@n,m,b: n must be 0, 1 or 2 (assuming 0)\n",
|
||||
argv[0]);
|
||||
}
|
||||
}
|
||||
if (*arg == ',') {
|
||||
arg++;
|
||||
PARSENUM(x, arg);
|
||||
if (x == 0) {
|
||||
TerminalBackground = TERMINAL_BACKGROUND_DARK;
|
||||
} else if (x == 1) {
|
||||
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
|
||||
} else {
|
||||
fprintf(ErrFp, "%s: -@n,m: m must be 0 or 1\n",
|
||||
argv[0]);
|
||||
if (*arg != ',') {
|
||||
PARSENUM(x, arg);
|
||||
if (x == 0) {
|
||||
TerminalBackground = TERMINAL_BACKGROUND_DARK;
|
||||
} else if (x == 1) {
|
||||
TerminalBackground = TERMINAL_BACKGROUND_LIGHT;
|
||||
} else if (x == 2) {
|
||||
TerminalBackground = TERMINAL_BACKGROUND_UNKNOWN;
|
||||
} else {
|
||||
fprintf(ErrFp, "%s: -@n,m,b: m must be 0, 1 or 2 (assuming 2)\n",
|
||||
argv[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*arg == ',') {
|
||||
arg++;
|
||||
PARSENUM(x, arg);
|
||||
if (x != 0 && x != 1) {
|
||||
fprintf(ErrFp, "%s: -@n,m,b: b must be 0 or 1 (assuming 0)\n",
|
||||
argv[0]);
|
||||
x = 0;
|
||||
}
|
||||
UseBGVTColors = x;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'j':
|
||||
@@ -495,11 +527,27 @@ void InitRemind(int argc, char const *argv[])
|
||||
case 'w':
|
||||
case 'W':
|
||||
if (*arg != ',') {
|
||||
PARSENUM(CalWidth, arg);
|
||||
if (CalWidth != 0 && CalWidth < 71) CalWidth = 71;
|
||||
if (CalWidth == 0) {
|
||||
CalWidth = -1;
|
||||
}
|
||||
if (*arg == 't') {
|
||||
arg++;
|
||||
/* -wt means get width from /dev/tty */
|
||||
ttyfd = open("/dev/tty", O_RDONLY);
|
||||
if (!ttyfd) {
|
||||
fprintf(stderr, "%s: `-wt': Cannot open /dev/tty: %s\n",
|
||||
argv[0], strerror(errno));
|
||||
} else {
|
||||
InitCalWidthAndFormWidth(ttyfd);
|
||||
close(ttyfd);
|
||||
}
|
||||
} else {
|
||||
PARSENUM(CalWidth, arg);
|
||||
if (CalWidth != 0 && CalWidth < 71) CalWidth = 71;
|
||||
if (CalWidth == 0) {
|
||||
CalWidth = -1;
|
||||
}
|
||||
FormWidth = CalWidth - 8;
|
||||
if (FormWidth < 20) FormWidth = 20;
|
||||
if (FormWidth > 500) FormWidth = 500;
|
||||
}
|
||||
}
|
||||
if (*arg == ',') {
|
||||
arg++;
|
||||
@@ -689,7 +737,7 @@ void Usage(void)
|
||||
fprintf(ErrFp, "Options:\n");
|
||||
fprintf(ErrFp, " -n Output next occurrence of reminders in simple format\n");
|
||||
fprintf(ErrFp, " -r Disable RUN directives\n");
|
||||
fprintf(ErrFp, " -@[n,m] Colorize COLOR reminders\n");
|
||||
fprintf(ErrFp, " -@[n,m,b] Colorize COLOR/SHADE reminders\n");
|
||||
fprintf(ErrFp, " -c[a][n] Produce a calendar for n (default 1) months\n");
|
||||
fprintf(ErrFp, " -c[a]+[n] Produce a calendar for n (default 1) weeks\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Specify width, padding and spacing of calendar\n");
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define ITALIAN 9 /* translated by Valerio Aimale */
|
||||
#define ROMANIAN 10 /* translated by Liviu Daia */
|
||||
#define SPANISH 11 /* translated by Rafa Couto */
|
||||
#define ICELANDIC 12 /* translated by Björn Davíðsson */
|
||||
#define ICELANDIC 12 /* translated by Björn Davíðsson */
|
||||
|
||||
/* Add more languages here - but please e-mail dianne@skoll.ca
|
||||
to have your favorite language assigned a number. If you add a
|
||||
|
||||
@@ -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",
|
||||
|
||||
223
src/main.c
223
src/main.c
@@ -10,8 +10,10 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
@@ -35,6 +37,10 @@
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef REM_USE_WCHAR
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
@@ -67,6 +73,7 @@ int main(int argc, char *argv[])
|
||||
ArgV = (char const **) argv;
|
||||
|
||||
InitRemind(argc, (char const **) argv);
|
||||
DBufInit(&(LastTrigger.tags));
|
||||
ClearLastTriggers();
|
||||
|
||||
if (DoCalendar || (DoSimpleCalendar && (!NextMode || PsCal))) {
|
||||
@@ -176,7 +183,7 @@ static void DoReminders(void)
|
||||
}
|
||||
|
||||
if (FileAccessDate < 0) {
|
||||
fprintf(ErrFp, "%s: `%s'.\n", ErrMsg[E_CANTACCESS], InitialFile);
|
||||
fprintf(ErrFp, "%s: `%s': %s.\n", ErrMsg[E_CANTACCESS], InitialFile, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -253,6 +260,7 @@ static void DoReminders(void)
|
||||
case T_Flush: r=DoFlush(&p); break;
|
||||
case T_Set: r=DoSet(&p); break;
|
||||
case T_Fset: r=DoFset(&p); break;
|
||||
case T_Funset: r=DoFunset(&p); break;
|
||||
case T_UnSet: r=DoUnset(&p); break;
|
||||
case T_Clr: r=DoClear(&p); break;
|
||||
case T_Debug: r=DoDebug(&p); break;
|
||||
@@ -329,7 +337,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 +367,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 +872,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++;
|
||||
@@ -1176,6 +1191,8 @@ int CalcMinsFromUTC(int jul, int tim, int *mins, int *isdst)
|
||||
local.tm_sec = 0;
|
||||
local.tm_min = tim % 60;
|
||||
local.tm_hour = tim / 60;
|
||||
|
||||
|
||||
local.tm_mday = day;
|
||||
local.tm_mon = mon;
|
||||
local.tm_year = yr-1900;
|
||||
@@ -1204,6 +1221,144 @@ int CalcMinsFromUTC(int jul, int tim, int *mins, int *isdst)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char const *OutputEscapeSequences(char const *s, int print)
|
||||
{
|
||||
while (*s == 0x1B && *(s+1) == '[') {
|
||||
if (print) putchar(*s);
|
||||
s++;
|
||||
if (print) putchar(*s);
|
||||
s++;
|
||||
while (*s && (*s < 0x40 || *s > 0x7E)) {
|
||||
if (print) putchar(*s);
|
||||
s++;
|
||||
}
|
||||
if (*s) {
|
||||
if (print) putchar(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
#define ISWBLANK(c) (iswspace(c) && (c) != '\n')
|
||||
static wchar_t const *OutputEscapeSequencesWS(wchar_t const *s, int print)
|
||||
{
|
||||
while (*s == 0x1B && *(s+1) == '[') {
|
||||
if (print) PutWideChar(*s);
|
||||
s++;
|
||||
if (print) PutWideChar(*s);
|
||||
s++;
|
||||
while (*s && (*s < 0x40 || *s > 0x7E)) {
|
||||
if (print) PutWideChar(*s);
|
||||
s++;
|
||||
}
|
||||
if (*s) {
|
||||
if (print) PutWideChar(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
FillParagraphWCAux(wchar_t const *s)
|
||||
{
|
||||
int line = 0;
|
||||
int i, j;
|
||||
int doublespace = 1;
|
||||
int pendspace;
|
||||
int len;
|
||||
wchar_t const *t;
|
||||
|
||||
int roomleft;
|
||||
/* Start formatting */
|
||||
while(1) {
|
||||
|
||||
/* If it's a carriage return, output it and start new paragraph */
|
||||
if (*s == '\n') {
|
||||
putchar('\n');
|
||||
s++;
|
||||
line = 0;
|
||||
while(ISWBLANK(*s)) s++;
|
||||
continue;
|
||||
}
|
||||
if (!*s) {
|
||||
return;
|
||||
}
|
||||
/* Over here, we're at the beginning of a line. Emit the correct
|
||||
number of spaces */
|
||||
j = line ? SubsIndent : FirstIndent;
|
||||
for (i=0; i<j; i++) {
|
||||
putchar(' ');
|
||||
}
|
||||
|
||||
/* Calculate the amount of room left on this line */
|
||||
roomleft = FormWidth - j;
|
||||
pendspace = 0;
|
||||
|
||||
/* Emit words until the next one won't fit */
|
||||
while(1) {
|
||||
while(ISWBLANK(*s)) s++;
|
||||
if (*s == '\n') break;
|
||||
while(1) {
|
||||
t = s;
|
||||
s = OutputEscapeSequencesWS(s, 1);
|
||||
if (s == t) break;
|
||||
while(ISWBLANK(*s)) s++;
|
||||
}
|
||||
t = s;
|
||||
len = 0;
|
||||
while(*s && !iswspace(*s)) {
|
||||
if (*s == 0x1B && *(s+1) == '[') {
|
||||
s = OutputEscapeSequencesWS(s, 0);
|
||||
continue;
|
||||
}
|
||||
len += wcwidth(*s);
|
||||
s++;
|
||||
}
|
||||
if (s == t) {
|
||||
return;
|
||||
}
|
||||
if (!pendspace || len+pendspace <= roomleft) {
|
||||
for (i=0; i<pendspace; i++) {
|
||||
putchar(' ');
|
||||
}
|
||||
while(t < s) {
|
||||
PutWideChar(*t);
|
||||
if (strchr(EndSent, *t)) doublespace = 2;
|
||||
else if (!strchr(EndSentIg, *t)) doublespace = 1;
|
||||
t++;
|
||||
}
|
||||
} else {
|
||||
s = t;
|
||||
putchar('\n');
|
||||
line++;
|
||||
break;
|
||||
}
|
||||
roomleft -= len+doublespace;
|
||||
pendspace = doublespace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
FillParagraphWC(char const *s)
|
||||
{
|
||||
size_t len;
|
||||
wchar_t *buf;
|
||||
|
||||
len = mbstowcs(NULL, s, 0);
|
||||
if (len == (size_t) -1) return E_NO_MEM;
|
||||
buf = calloc(len+1, sizeof(wchar_t));
|
||||
if (!buf) return E_NO_MEM;
|
||||
(void) mbstowcs(buf, s, len+1);
|
||||
FillParagraphWCAux(buf);
|
||||
free(buf);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FillParagraph */
|
||||
@@ -1230,11 +1385,17 @@ void FillParagraph(char const *s)
|
||||
char const *t;
|
||||
|
||||
int roomleft;
|
||||
|
||||
if (!s || !*s) return;
|
||||
|
||||
/* Skip leading spaces */
|
||||
while(ISBLANK(*s)) s++;
|
||||
if (!*s) return;
|
||||
|
||||
#ifdef REM_USE_WCHAR
|
||||
if (FillParagraphWC(s) == OK) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Start formatting */
|
||||
while(1) {
|
||||
@@ -1265,10 +1426,23 @@ void FillParagraph(char const *s)
|
||||
while(1) {
|
||||
while(ISBLANK(*s)) s++;
|
||||
if (*s == '\n') break;
|
||||
while(1) {
|
||||
t = s;
|
||||
s = OutputEscapeSequences(s, 1);
|
||||
if (s == t) break;
|
||||
while(ISBLANK(*s)) s++;
|
||||
}
|
||||
t = s;
|
||||
while(*s && !isspace(*s)) s++;
|
||||
len = s - t;
|
||||
if (!len) {
|
||||
len = 0;
|
||||
while(*s && !isspace(*s)) {
|
||||
if (*s == 0x1B && *(s+1) == '[') {
|
||||
s = OutputEscapeSequences(s, 0);
|
||||
continue;
|
||||
}
|
||||
s++;
|
||||
len++;
|
||||
}
|
||||
if (s == t) {
|
||||
return;
|
||||
}
|
||||
if (!pendspace || len+pendspace <= roomleft) {
|
||||
@@ -1357,13 +1531,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
|
||||
@@ -1404,6 +1588,7 @@ ClearLastTriggers(void)
|
||||
LastTrigger.warn[0] = 0;
|
||||
LastTrigger.omitfunc[0] = 0;
|
||||
LastTrigger.passthru[0] = 0;
|
||||
DBufFree(&(LastTrigger.tags));
|
||||
|
||||
LastTimeTrig.ttime = NO_TIME;
|
||||
LastTimeTrig.delta = NO_DELTA;
|
||||
@@ -1424,8 +1609,10 @@ SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigt
|
||||
void
|
||||
SaveLastTrigger(Trigger const *t)
|
||||
{
|
||||
DBufFree(&(LastTrigger.tags));
|
||||
memcpy(&LastTrigger, t, sizeof(LastTrigger));
|
||||
DBufInit(&(LastTrigger.tags));
|
||||
DBufPuts(&(LastTrigger.tags), DBufValue(&(t->tags)));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
258
src/omit.c
258
src/omit.c
@@ -28,6 +28,8 @@ static void InsertIntoSortedArray (int *array, int num, int key);
|
||||
static int FullOmitArray[MAX_FULL_OMITS];
|
||||
static int PartialOmitArray[MAX_PARTIAL_OMITS];
|
||||
|
||||
/* WeekdayOmits is declared in global.h */
|
||||
|
||||
/* How many of each omit types do we have? */
|
||||
static int NumFullOmits, NumPartialOmits;
|
||||
|
||||
@@ -37,6 +39,7 @@ typedef struct omitcontext {
|
||||
int numfull, numpart;
|
||||
int *fullsave;
|
||||
int *partsave;
|
||||
int weekdaysave;
|
||||
} OmitContext;
|
||||
|
||||
/* The stack of saved omit contexts */
|
||||
@@ -52,6 +55,7 @@ static OmitContext *SavedOmitContexts = NULL;
|
||||
int ClearGlobalOmits(void)
|
||||
{
|
||||
NumFullOmits = NumPartialOmits = 0;
|
||||
WeekdayOmits = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -113,6 +117,7 @@ int PushOmitContext(ParsePtr p)
|
||||
|
||||
context->numfull = NumFullOmits;
|
||||
context->numpart = NumPartialOmits;
|
||||
context->weekdaysave = WeekdayOmits;
|
||||
context->fullsave = malloc(NumFullOmits * sizeof(int));
|
||||
if (NumFullOmits && !context->fullsave) {
|
||||
free(context);
|
||||
@@ -154,6 +159,7 @@ int PopOmitContext(ParsePtr p)
|
||||
if (!c) return E_POP_NO_PUSH;
|
||||
NumFullOmits = c->numfull;
|
||||
NumPartialOmits = c->numpart;
|
||||
WeekdayOmits = c->weekdaysave;
|
||||
|
||||
/* Copy the context over */
|
||||
for (i=0; i<NumFullOmits; i++)
|
||||
@@ -213,6 +219,12 @@ int IsOmitted(int jul, int localomit, char const *omitfunc, int *omit)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Is it omitted because of global weekday omits? */
|
||||
if (WeekdayOmits & (1 << (jul % 7))) {
|
||||
*omit = 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Is it omitted because of fully-specified omits? */
|
||||
if (BexistsIntArray(FullOmitArray, NumFullOmits, jul)) {
|
||||
*omit = 1;
|
||||
@@ -271,7 +283,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 +294,16 @@ 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 wd = 0;
|
||||
|
||||
int mc, dc;
|
||||
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
@@ -298,9 +314,15 @@ int DoOmit(ParsePtr p)
|
||||
if ( (r=ParseToken(p, &buf)) ) return r;
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
switch (tok.type) {
|
||||
case T_Dumpvars:
|
||||
if (not_first_token) return E_PARSE_ERR;
|
||||
case T_WkDay:
|
||||
DBufFree(&buf);
|
||||
if (wd & (1 << tok.val)) return E_WD_TWICE;
|
||||
wd |= (1 << tok.val);
|
||||
break;
|
||||
|
||||
case T_Dumpvars:
|
||||
DBufFree(&buf);
|
||||
if (not_first_token) return E_PARSE_ERR;
|
||||
r = VerifyEoln(p);
|
||||
if (r != OK) return r;
|
||||
DumpOmits();
|
||||
@@ -308,28 +330,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 +360,10 @@ 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 (wd) return E_PARSE_ERR;
|
||||
if (seen_through) return E_UNTIL_TWICE;
|
||||
seen_through = 1;
|
||||
break;
|
||||
|
||||
case T_Empty:
|
||||
case T_Comment:
|
||||
@@ -358,26 +382,97 @@ 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 (wd) {
|
||||
if (y[0] != NO_YR || m[0] != NO_MON || d[0] != NO_DAY) {
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
if ((WeekdayOmits | wd) == 0x7F) {
|
||||
return E_2MANY_LOCALOMIT;
|
||||
}
|
||||
WeekdayOmits |= wd;
|
||||
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (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 +489,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)
|
||||
{
|
||||
@@ -508,5 +514,15 @@ DumpOmits(void)
|
||||
printf("\t%02d%c%02d\n", m+1, DateSep, d);
|
||||
}
|
||||
}
|
||||
printf("Global Weekday OMITs:\n");
|
||||
if (WeekdayOmits == 0) {
|
||||
printf("\tNone.\n");
|
||||
} else {
|
||||
for (i=0; i<7; i++) {
|
||||
if (WeekdayOmits & (1<<i)) {
|
||||
printf("\t%s\n", EnglishDayName[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
src/protos.h
14
src/protos.h
@@ -22,9 +22,11 @@
|
||||
#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);
|
||||
int DoFunset (ParsePtr p);
|
||||
void ProduceCalendar (void);
|
||||
char const *SimpleTime (int tim);
|
||||
char const *CalendarTime (int tim, int duration);
|
||||
@@ -143,7 +145,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 +156,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);
|
||||
@@ -176,3 +178,9 @@ void clear_callstack(void);
|
||||
int have_callstack(void);
|
||||
int print_callstack(FILE *fp);
|
||||
void pop_call(void);
|
||||
#ifdef REM_USE_WCHAR
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
void PutWideChar(wchar_t const wc);
|
||||
#endif
|
||||
|
||||
27
src/queue.c
27
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) {
|
||||
@@ -184,7 +190,9 @@ void HandleQueuedReminders(void)
|
||||
while (TimeToSleep > 0L) {
|
||||
SleepTime = TimeToSleep;
|
||||
|
||||
if (Daemon > 0 && SleepTime > (unsigned int) 60*Daemon) SleepTime = 60*Daemon;
|
||||
if (Daemon > 0 && SleepTime > (unsigned int) 60*Daemon) {
|
||||
SleepTime = 60*Daemon;
|
||||
}
|
||||
|
||||
/* Wake up once a minute to recalibrate sleep time in
|
||||
case of laptop hibernation */
|
||||
@@ -203,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) {
|
||||
@@ -335,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;
|
||||
|
||||
@@ -366,6 +378,7 @@ void GotSigInt(void)
|
||||
q = q->next;
|
||||
}
|
||||
printf(NL);
|
||||
printf("To terminate program, send SIGQUIT (probably Ctrl-\\ on the keyboard.)%s", NL);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
@@ -62,6 +62,7 @@ Token TokArray[] = {
|
||||
{ "friday", 3, T_WkDay, 4 },
|
||||
{ "from", 4, T_Scanfrom, FROM_TYPE },
|
||||
{ "fset", 4, T_Fset, 0 },
|
||||
{ "funset", 6, T_Funset, 0 },
|
||||
{ "if", 2, T_If, 0 },
|
||||
{ "iftrig", 6, T_IfTrig, 0 },
|
||||
{ "in", 2, T_In, 0 },
|
||||
|
||||
@@ -530,7 +530,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
|
||||
*err = OK;
|
||||
|
||||
/* But check for obvious problems... */
|
||||
if (trig->localomit == 1 + 2 + 4 + 8 + 16 + 32 + 64) {
|
||||
if ((WeekdayOmits | trig->localomit) == 0x7F) {
|
||||
*err = E_2MANY_LOCALOMIT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ enum TokTypes
|
||||
/* Commands first */
|
||||
T_Rem, T_Push, T_Pop, T_Preserve, T_Include, T_IncludeR, T_IncludeCmd, T_If, T_Else, T_EndIf,
|
||||
T_IfTrig, T_ErrMsg,
|
||||
T_Set, T_UnSet, T_Fset, T_Omit, T_Banner, T_Exit,
|
||||
T_Set, T_UnSet, T_Fset, T_Funset, T_Omit, T_Banner, T_Exit,
|
||||
T_AddOmit,
|
||||
T_WkDay,
|
||||
T_Month, T_Time, T_Date, T_DateTime,
|
||||
@@ -238,6 +238,6 @@ typedef struct {
|
||||
/* Pure JSON */
|
||||
#define PSCAL_LEVEL3 3
|
||||
|
||||
#define TERMINAL_BACKGROUND_UNKNOWN 0
|
||||
#define TERMINAL_BACKGROUND_DARK 1
|
||||
#define TERMINAL_BACKGROUND_LIGHT 2
|
||||
#define TERMINAL_BACKGROUND_UNKNOWN -1
|
||||
#define TERMINAL_BACKGROUND_DARK 0
|
||||
#define TERMINAL_BACKGROUND_LIGHT 1
|
||||
|
||||
@@ -53,6 +53,34 @@ static void FSet (UserFunc *f);
|
||||
static int SetUpLocalVars (UserFunc *f);
|
||||
static void DestroyLocalVals (UserFunc *f);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoFset */
|
||||
/* */
|
||||
/* Undefine a user-defined function - the FUNSET command. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoFunset(ParsePtr p)
|
||||
{
|
||||
int r;
|
||||
int seen_one = 0;
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
|
||||
while(1) {
|
||||
r = ParseIdentifier(p, &buf);
|
||||
if (r == E_EOLN) {
|
||||
DBufFree(&buf);
|
||||
break;
|
||||
}
|
||||
seen_one = 1;
|
||||
FUnset(DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
}
|
||||
if (seen_one) return OK;
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoFset */
|
||||
|
||||
10
src/utils.c
10
src/utils.c
@@ -24,8 +24,6 @@ static char const DontEscapeMe[] =
|
||||
#include "globals.h"
|
||||
#include "protos.h"
|
||||
|
||||
#define UPPER(c) toupper(c)
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* StrnCpy */
|
||||
@@ -68,12 +66,12 @@ int StrinCmp(char const *s1, char const *s2, int n)
|
||||
register int r;
|
||||
while (n && *s1 && *s2) {
|
||||
n--;
|
||||
r = UPPER(*s1) - UPPER(*s2);
|
||||
r = toupper(*s1) - toupper(*s2);
|
||||
if (r) return r;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
if (n) return (UPPER(*s1) - UPPER(*s2)); else return 0;
|
||||
if (n) return (toupper(*s1) - toupper(*s2)); else return 0;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -102,12 +100,12 @@ int StrCmpi(char const *s1, char const *s2)
|
||||
{
|
||||
int r;
|
||||
while (*s1 && *s2) {
|
||||
r = UPPER(*s1) - UPPER(*s2);
|
||||
r = toupper(*s1) - toupper(*s2);
|
||||
if (r) return r;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return UPPER(*s1) - UPPER(*s2);
|
||||
return toupper(*s1) - toupper(*s2);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
241
src/var.c
241
src/var.c
@@ -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;
|
||||
@@ -762,7 +763,6 @@ typedef struct {
|
||||
void *value;
|
||||
int min;
|
||||
int max;
|
||||
int (*validate)(void const *newvalue);
|
||||
} SysVar;
|
||||
|
||||
/* If the type of a sys variable is STR_TYPE, then min is redefined
|
||||
@@ -774,100 +774,107 @@ typedef struct {
|
||||
|
||||
/* All of the system variables sorted alphabetically */
|
||||
static SysVar SysVarArr[] = {
|
||||
/* name mod type value min/mal max validate*/
|
||||
{"Ago", 1, STR_TYPE, &DynamicAgo, 0, 0, NULL },
|
||||
{"Am", 1, STR_TYPE, &DynamicAm, 0, 0, NULL },
|
||||
{"And", 1, STR_TYPE, &DynamicAnd, 0, 0, NULL },
|
||||
{"April", 1, STR_TYPE, &DynamicMonthName[3], 0, 0, NULL },
|
||||
{"At", 1, STR_TYPE, &DynamicAt, 0, 0, NULL },
|
||||
{"August", 1, STR_TYPE, &DynamicMonthName[7], 0, 0, NULL },
|
||||
{"CalcUTC", 1, INT_TYPE, &CalculateUTC, 0, 1, NULL },
|
||||
{"CalMode", 0, INT_TYPE, &DoCalendar, 0, 0, NULL },
|
||||
{"Daemon", 0, INT_TYPE, &Daemon, 0, 0, NULL },
|
||||
{"DateSep", 1, SPECIAL_TYPE, date_sep_func, 0, 0, NULL },
|
||||
{"DateTimeSep", 1, SPECIAL_TYPE, datetime_sep_func, 0, 0, NULL },
|
||||
{"December", 1, STR_TYPE, &DynamicMonthName[11],0, 0, NULL },
|
||||
{"DefaultColor", 1, SPECIAL_TYPE, default_color_func, 0, 0, NULL },
|
||||
{"DefaultPrio", 1, INT_TYPE, &DefaultPrio, 0, 9999, NULL },
|
||||
{"DefaultTDelta", 1, INT_TYPE, &DefaultTDelta, 0, 1440, NULL },
|
||||
{"DeltaOffset", 0, INT_TYPE, &DeltaOffset, 0, 0, NULL },
|
||||
{"DontFork", 0, INT_TYPE, &DontFork, 0, 0, NULL },
|
||||
{"DontQueue", 0, INT_TYPE, &DontQueue, 0, 0, NULL },
|
||||
{"DontTrigAts", 0, INT_TYPE, &DontIssueAts, 0, 0, NULL },
|
||||
{"EndSent", 1, STR_TYPE, &EndSent, 0, 0, NULL },
|
||||
{"EndSentIg", 1, STR_TYPE, &EndSentIg, 0, 0, NULL },
|
||||
{"February", 1, STR_TYPE, &DynamicMonthName[1], 0, 0, NULL },
|
||||
{"FirstIndent", 1, INT_TYPE, &FirstIndent, 0, 132, NULL },
|
||||
{"FoldYear", 1, INT_TYPE, &FoldYear, 0, 1, NULL },
|
||||
{"FormWidth", 1, INT_TYPE, &FormWidth, 20, 500, NULL },
|
||||
{"Friday", 1, STR_TYPE, &DynamicDayName[4], 0, 0, NULL },
|
||||
{"Fromnow", 1, STR_TYPE, &DynamicFromnow, 0, 0, NULL },
|
||||
{"Hour", 1, STR_TYPE, &DynamicHour, 0, 0, NULL },
|
||||
{"Hplu", 1, STR_TYPE, &DynamicHplu, 0, 0, NULL },
|
||||
{"HushMode", 0, INT_TYPE, &Hush, 0, 0, NULL },
|
||||
{"IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 0, 0, NULL },
|
||||
{"InfDelta", 0, INT_TYPE, &InfiniteDelta, 0, 0, NULL },
|
||||
{"IntMax", 0, INT_TYPE, &IntMax, 0, 0, NULL },
|
||||
{"IntMin", 0, INT_TYPE, &IntMin, 0, 0, NULL },
|
||||
{"Is", 1, STR_TYPE, &DynamicIs, 0, 0, NULL },
|
||||
{"January", 1, STR_TYPE, &DynamicMonthName[0], 0, 0, NULL },
|
||||
{"July", 1, STR_TYPE, &DynamicMonthName[6], 0, 0, NULL },
|
||||
{"June", 1, STR_TYPE, &DynamicMonthName[5], 0, 0, NULL },
|
||||
{"LatDeg", 1, SPECIAL_TYPE, latdeg_func, 0, 0, NULL },
|
||||
{"Latitude", 1, SPECIAL_TYPE, latitude_func, 0, 0, NULL },
|
||||
{"LatMin", 1, SPECIAL_TYPE, latmin_func, 0, 0, NULL },
|
||||
{"LatSec", 1, SPECIAL_TYPE, latsec_func, 0, 0, NULL },
|
||||
{"Location", 1, STR_TYPE, &Location, 0, 0, NULL },
|
||||
{"LongDeg", 1, SPECIAL_TYPE, longdeg_func, 0, 0, NULL },
|
||||
{"Longitude", 1, SPECIAL_TYPE, longitude_func, 0, 0, NULL },
|
||||
{"LongMin", 1, SPECIAL_TYPE, longmin_func, 0, 0, NULL },
|
||||
{"LongSec", 1, SPECIAL_TYPE, longsec_func, 0, 0, NULL },
|
||||
{"March", 1, STR_TYPE, &DynamicMonthName[2], 0, 0, NULL },
|
||||
{"MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY, NULL },
|
||||
{"MaxStringLen", 1, INT_TYPE, &MaxStringLen, -1, ANY, NULL },
|
||||
{"May", 1, STR_TYPE, &DynamicMonthName[4], 0, 0, NULL },
|
||||
{"MinsFromUTC", 1, INT_TYPE, &MinsFromUTC, -780, 780, NULL },
|
||||
{"Minute", 1, STR_TYPE, &DynamicMinute, 0, 0, NULL },
|
||||
{"Monday", 1, STR_TYPE, &DynamicDayName[0], 0, 0, NULL },
|
||||
{"Mplu", 1, STR_TYPE, &DynamicMplu, 0, 0, NULL },
|
||||
{"NextMode", 0, INT_TYPE, &NextMode, 0, 0, NULL },
|
||||
{"November", 1, STR_TYPE, &DynamicMonthName[10],0, 0, NULL },
|
||||
{"Now", 1, STR_TYPE, &DynamicNow, 0, 0, NULL },
|
||||
{"NumQueued", 0, INT_TYPE, &NumQueued, 0, 0, NULL },
|
||||
{"NumTrig", 0, INT_TYPE, &NumTriggered, 0, 0, NULL },
|
||||
{"October", 1, STR_TYPE, &DynamicMonthName[9], 0, 0, NULL },
|
||||
{"On", 1, STR_TYPE, &DynamicOn, 0, 0, NULL },
|
||||
{"Pm", 1, STR_TYPE, &DynamicPm, 0, 0, NULL },
|
||||
{"PrefixLineNo", 0, INT_TYPE, &DoPrefixLineNo, 0, 0, NULL },
|
||||
{"PSCal", 0, INT_TYPE, &PsCal, 0, 0, NULL },
|
||||
{"RunOff", 0, INT_TYPE, &RunDisabled, 0, 0, NULL },
|
||||
{"Saturday", 1, STR_TYPE, &DynamicDayName[5], 0, 0, NULL },
|
||||
{"September", 1, STR_TYPE, &DynamicMonthName[8], 0, 0, NULL },
|
||||
{"SimpleCal", 0, INT_TYPE, &DoSimpleCalendar, 0, 0, NULL },
|
||||
{"SortByDate", 0, INT_TYPE, &SortByDate, 0, 0, NULL },
|
||||
{"SortByPrio", 0, INT_TYPE, &SortByPrio, 0, 0, NULL },
|
||||
{"SortByTime", 0, INT_TYPE, &SortByTime, 0, 0, NULL },
|
||||
{"SubsIndent", 1, INT_TYPE, &SubsIndent, 0, 132, NULL },
|
||||
{"Sunday", 1, STR_TYPE, &DynamicDayName[6], 0, 0, NULL },
|
||||
{"SysInclude", 0, STR_TYPE, &SysDir, 0, 0, NULL },
|
||||
{"T", 0, SPECIAL_TYPE, trig_date_func, 0, 0, NULL },
|
||||
{"Td", 0, SPECIAL_TYPE, trig_day_func, 0, 0, NULL },
|
||||
{"Thursday", 1, STR_TYPE, &DynamicDayName[3], 0, 0, NULL },
|
||||
{"TimeSep", 1, SPECIAL_TYPE, time_sep_func, 0, 0, NULL },
|
||||
{"Tm", 0, SPECIAL_TYPE, trig_mon_func, 0, 0, NULL },
|
||||
{"Today", 1, STR_TYPE, &DynamicToday, 0, 0, NULL },
|
||||
{"Tomorrow", 1, STR_TYPE, &DynamicTomorrow, 0, 0, NULL },
|
||||
{"Tuesday", 1, STR_TYPE, &DynamicDayName[1], 0, 0, NULL },
|
||||
{"Tw", 0, SPECIAL_TYPE, trig_wday_func, 0, 0, NULL },
|
||||
{"Ty", 0, SPECIAL_TYPE, trig_year_func, 0, 0, NULL },
|
||||
{"U", 0, SPECIAL_TYPE, today_date_func, 0, 0, NULL },
|
||||
{"Ud", 0, SPECIAL_TYPE, today_day_func, 0, 0, NULL },
|
||||
{"Um", 0, SPECIAL_TYPE, today_mon_func, 0, 0, NULL },
|
||||
{"UntimedFirst", 0, INT_TYPE, &UntimedBeforeTimed, 0, 0, NULL },
|
||||
{"Uw", 0, SPECIAL_TYPE, today_wday_func, 0, 0, NULL },
|
||||
{"Uy", 0, SPECIAL_TYPE, today_year_func, 0, 0, NULL },
|
||||
{"Was", 1, STR_TYPE, &DynamicWas, 0, 0, NULL },
|
||||
{"Wednesday", 1, STR_TYPE, &DynamicDayName[2], 0, 0, NULL }
|
||||
/* name mod type value min/mal max */
|
||||
{"AddBlankLines", 1, INT_TYPE, &AddBlankLines, 0, 1 },
|
||||
{"Ago", 1, STR_TYPE, &DynamicAgo, 0, 0 },
|
||||
{"Am", 1, STR_TYPE, &DynamicAm, 0, 0 },
|
||||
{"And", 1, STR_TYPE, &DynamicAnd, 0, 0 },
|
||||
{"April", 1, STR_TYPE, &DynamicMonthName[3], 0, 0 },
|
||||
{"At", 1, STR_TYPE, &DynamicAt, 0, 0 },
|
||||
{"August", 1, STR_TYPE, &DynamicMonthName[7], 0, 0 },
|
||||
{"CalcUTC", 1, INT_TYPE, &CalculateUTC, 0, 1 },
|
||||
{"CalMode", 0, INT_TYPE, &DoCalendar, 0, 0 },
|
||||
{"Daemon", 0, INT_TYPE, &Daemon, 0, 0 },
|
||||
{"DateSep", 1, SPECIAL_TYPE, date_sep_func, 0, 0 },
|
||||
{"DateTimeSep", 1, SPECIAL_TYPE, datetime_sep_func, 0, 0 },
|
||||
{"December", 1, STR_TYPE, &DynamicMonthName[11],0, 0 },
|
||||
{"DefaultColor", 1, SPECIAL_TYPE, default_color_func, 0, 0 },
|
||||
{"DefaultPrio", 1, INT_TYPE, &DefaultPrio, 0, 9999 },
|
||||
{"DefaultTDelta", 1, INT_TYPE, &DefaultTDelta, 0, 1440 },
|
||||
{"DeltaOffset", 0, INT_TYPE, &DeltaOffset, 0, 0 },
|
||||
{"DontFork", 0, INT_TYPE, &DontFork, 0, 0 },
|
||||
{"DontQueue", 0, INT_TYPE, &DontQueue, 0, 0 },
|
||||
{"DontTrigAts", 0, INT_TYPE, &DontIssueAts, 0, 0 },
|
||||
{"EndSent", 1, STR_TYPE, &EndSent, 0, 0 },
|
||||
{"EndSentIg", 1, STR_TYPE, &EndSentIg, 0, 0 },
|
||||
{"February", 1, STR_TYPE, &DynamicMonthName[1], 0, 0 },
|
||||
{"FirstIndent", 1, INT_TYPE, &FirstIndent, 0, 132 },
|
||||
{"FoldYear", 1, INT_TYPE, &FoldYear, 0, 1 },
|
||||
{"FormWidth", 1, INT_TYPE, &FormWidth, 20, 500 },
|
||||
{"Friday", 1, STR_TYPE, &DynamicDayName[4], 0, 0 },
|
||||
{"Fromnow", 1, STR_TYPE, &DynamicFromnow, 0, 0 },
|
||||
{"Hour", 1, STR_TYPE, &DynamicHour, 0, 0 },
|
||||
{"Hplu", 1, STR_TYPE, &DynamicHplu, 0, 0 },
|
||||
{"HushMode", 0, INT_TYPE, &Hush, 0, 0 },
|
||||
{"IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 0, 0 },
|
||||
{"InfDelta", 0, INT_TYPE, &InfiniteDelta, 0, 0 },
|
||||
{"IntMax", 0, INT_TYPE, &IntMax, 0, 0 },
|
||||
{"IntMin", 0, INT_TYPE, &IntMin, 0, 0 },
|
||||
{"Is", 1, STR_TYPE, &DynamicIs, 0, 0 },
|
||||
{"January", 1, STR_TYPE, &DynamicMonthName[0], 0, 0 },
|
||||
{"July", 1, STR_TYPE, &DynamicMonthName[6], 0, 0 },
|
||||
{"June", 1, STR_TYPE, &DynamicMonthName[5], 0, 0 },
|
||||
{"LatDeg", 1, SPECIAL_TYPE, latdeg_func, 0, 0 },
|
||||
{"Latitude", 1, SPECIAL_TYPE, latitude_func, 0, 0 },
|
||||
{"LatMin", 1, SPECIAL_TYPE, latmin_func, 0, 0 },
|
||||
{"LatSec", 1, SPECIAL_TYPE, latsec_func, 0, 0 },
|
||||
{"Location", 1, STR_TYPE, &Location, 0, 0 },
|
||||
{"LongDeg", 1, SPECIAL_TYPE, longdeg_func, 0, 0 },
|
||||
{"Longitude", 1, SPECIAL_TYPE, longitude_func, 0, 0 },
|
||||
{"LongMin", 1, SPECIAL_TYPE, longmin_func, 0, 0 },
|
||||
{"LongSec", 1, SPECIAL_TYPE, longsec_func, 0, 0 },
|
||||
{"March", 1, STR_TYPE, &DynamicMonthName[2], 0, 0 },
|
||||
{"MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY },
|
||||
{"MaxStringLen", 1, INT_TYPE, &MaxStringLen, -1, ANY },
|
||||
{"May", 1, STR_TYPE, &DynamicMonthName[4], 0, 0 },
|
||||
{"MinsFromUTC", 1, INT_TYPE, &MinsFromUTC, -780, 780 },
|
||||
{"Minute", 1, STR_TYPE, &DynamicMinute, 0, 0 },
|
||||
{"Monday", 1, STR_TYPE, &DynamicDayName[0], 0, 0 },
|
||||
{"Mplu", 1, STR_TYPE, &DynamicMplu, 0, 0 },
|
||||
{"NextMode", 0, INT_TYPE, &NextMode, 0, 0 },
|
||||
{"November", 1, STR_TYPE, &DynamicMonthName[10],0, 0 },
|
||||
{"Now", 1, STR_TYPE, &DynamicNow, 0, 0 },
|
||||
{"NumQueued", 0, INT_TYPE, &NumQueued, 0, 0 },
|
||||
{"NumTrig", 0, INT_TYPE, &NumTriggered, 0, 0 },
|
||||
{"October", 1, STR_TYPE, &DynamicMonthName[9], 0, 0 },
|
||||
{"On", 1, STR_TYPE, &DynamicOn, 0, 0 },
|
||||
{"Pm", 1, STR_TYPE, &DynamicPm, 0, 0 },
|
||||
{"PrefixLineNo", 0, INT_TYPE, &DoPrefixLineNo, 0, 0 },
|
||||
{"PSCal", 0, INT_TYPE, &PsCal, 0, 0 },
|
||||
{"RunOff", 0, INT_TYPE, &RunDisabled, 0, 0 },
|
||||
{"Saturday", 1, STR_TYPE, &DynamicDayName[5], 0, 0 },
|
||||
{"September", 1, STR_TYPE, &DynamicMonthName[8], 0, 0 },
|
||||
{"SimpleCal", 0, INT_TYPE, &DoSimpleCalendar, 0, 0 },
|
||||
{"SortByDate", 0, INT_TYPE, &SortByDate, 0, 0 },
|
||||
{"SortByPrio", 0, INT_TYPE, &SortByPrio, 0, 0 },
|
||||
{"SortByTime", 0, INT_TYPE, &SortByTime, 0, 0 },
|
||||
{"SubsIndent", 1, INT_TYPE, &SubsIndent, 0, 132 },
|
||||
{"Sunday", 1, STR_TYPE, &DynamicDayName[6], 0, 0 },
|
||||
{"SuppressLRM", 1, INT_TYPE, &SuppressLRM, 0, 1 },
|
||||
{"SysInclude", 0, STR_TYPE, &SysDir, 0, 0 },
|
||||
{"T", 0, SPECIAL_TYPE, trig_date_func, 0, 0 },
|
||||
{"Td", 0, SPECIAL_TYPE, trig_day_func, 0, 0 },
|
||||
{"TerminalBackground", 0, INT_TYPE, &TerminalBackground, 0, 0 },
|
||||
{"Thursday", 1, STR_TYPE, &DynamicDayName[3], 0, 0 },
|
||||
{"TimeSep", 1, SPECIAL_TYPE, time_sep_func, 0, 0 },
|
||||
{"Tm", 0, SPECIAL_TYPE, trig_mon_func, 0, 0 },
|
||||
{"Today", 1, STR_TYPE, &DynamicToday, 0, 0 },
|
||||
{"Tomorrow", 1, STR_TYPE, &DynamicTomorrow, 0, 0 },
|
||||
{"Tuesday", 1, STR_TYPE, &DynamicDayName[1], 0, 0 },
|
||||
{"Tw", 0, SPECIAL_TYPE, trig_wday_func, 0, 0 },
|
||||
{"Ty", 0, SPECIAL_TYPE, trig_year_func, 0, 0 },
|
||||
{"U", 0, SPECIAL_TYPE, today_date_func, 0, 0 },
|
||||
{"Ud", 0, SPECIAL_TYPE, today_day_func, 0, 0 },
|
||||
{"Um", 0, SPECIAL_TYPE, today_mon_func, 0, 0 },
|
||||
{"UntimedFirst", 0, INT_TYPE, &UntimedBeforeTimed, 0, 0 },
|
||||
{"Use256Colors", 0, INT_TYPE, &Use256Colors, 0, 0 },
|
||||
{"UseBGVTColors", 0, INT_TYPE, &UseBGVTColors, 0, 0 },
|
||||
{"UseTrueColors", 0, INT_TYPE, &UseTrueColors, 0, 0 },
|
||||
{"UseVTColors", 0, INT_TYPE, &UseVTColors, 0, 0 },
|
||||
{"Uw", 0, SPECIAL_TYPE, today_wday_func, 0, 0 },
|
||||
{"Uy", 0, SPECIAL_TYPE, today_year_func, 0, 0 },
|
||||
{"Was", 1, STR_TYPE, &DynamicWas, 0, 0 },
|
||||
{"Wednesday", 1, STR_TYPE, &DynamicDayName[2], 0, 0 }
|
||||
};
|
||||
|
||||
#define NUMSYSVARS ( sizeof(SysVarArr) / sizeof(SysVar) )
|
||||
@@ -898,16 +905,7 @@ int SetSysVar(char const *name, Value *value)
|
||||
DestroyValue(*value);
|
||||
return r;
|
||||
}
|
||||
if (v->validate) {
|
||||
if (v->type == STR_TYPE) {
|
||||
r = (v->validate)((void *) value->v.str);
|
||||
} else {
|
||||
r = (v->validate)((void *) &(value->v.val));
|
||||
}
|
||||
if (r != OK) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (v->type == STR_TYPE) {
|
||||
/* If it's already the same, don't bother doing anything */
|
||||
if (!strcmp(value->v.str, (char const *) v->value)) {
|
||||
@@ -1021,6 +1019,7 @@ void DumpSysVarByName(char const *name)
|
||||
static void DumpSysVar(char const *name, const SysVar *v)
|
||||
{
|
||||
char buffer[VAR_NAME_LEN+10];
|
||||
Value vtmp;
|
||||
|
||||
if (name && !*name) name=NULL;
|
||||
if (!v && !name) return; /* Shouldn't happen... */
|
||||
@@ -1034,32 +1033,20 @@ static void DumpSysVar(char const *name, const SysVar *v)
|
||||
fprintf(ErrFp, "%16s ", buffer);
|
||||
if (v) {
|
||||
if (v->type == SPECIAL_TYPE) {
|
||||
Value val;
|
||||
SysVarFunc f = (SysVarFunc) v->value;
|
||||
f(0, &val);
|
||||
PrintValue(&val, ErrFp);
|
||||
f(0, &vtmp);
|
||||
PrintValue(&vtmp, ErrFp);
|
||||
putc('\n', ErrFp);
|
||||
DestroyValue(val);
|
||||
DestroyValue(vtmp);
|
||||
} else if (v->type == STR_TYPE) {
|
||||
char const *s = *((char **)v->value);
|
||||
int y;
|
||||
putc('"', ErrFp);
|
||||
for (y=0; y<MAX_PRT_LEN && *s; y++) {
|
||||
if (*s == '"') {
|
||||
fprintf(ErrFp, "\" + char(34) + \"");
|
||||
s++;
|
||||
} else {
|
||||
putc(*s++, ErrFp);
|
||||
}
|
||||
}
|
||||
putc('"', ErrFp);
|
||||
if (*s) fprintf(ErrFp, "...");
|
||||
vtmp.type = STR_TYPE;
|
||||
vtmp.v.str = * ((char **)v->value);
|
||||
PrintValue(&vtmp, ErrFp);
|
||||
putc('\n', ErrFp);
|
||||
} else if (v->type == DATE_TYPE) {
|
||||
Value val;
|
||||
val.type = DATE_TYPE;
|
||||
val.v.val = * (int *) v->value;
|
||||
PrintValue(&val, ErrFp);
|
||||
vtmp.type = DATE_TYPE;
|
||||
vtmp.v.val = * (int *) v->value;
|
||||
PrintValue(&vtmp, ErrFp);
|
||||
putc('\n', ErrFp);
|
||||
} else {
|
||||
if (!v->modifiable) fprintf(ErrFp, "%d\n", *((int *)v->value));
|
||||
|
||||
49
tests/ansicolors.rem
Normal file
49
tests/ansicolors.rem
Normal file
@@ -0,0 +1,49 @@
|
||||
BANNER %
|
||||
MSG TerminalBackground is: [$TerminalBackground]%
|
||||
MSG UseVTColors is: [$UseVTColors]%
|
||||
MSG Use256Colors is: [$Use256Colors]%
|
||||
MSG UseTrueColors is: [$UseTrueColors]%
|
||||
MSG UseBGVTColors is: [$UseBGVTColors]%
|
||||
set n ansicolor("")]
|
||||
MSG This is [ansicolor(0,255,0)]green[n], [ansicolor("255 0 0")]red[n] and [ansicolor("0 0 255")]blue[n] text.%
|
||||
MSG This is [ansicolor(0,0,0)][ansicolor(0,255,0,1)]black text on a green background[n]%
|
||||
MSG This is [ansicolor(0,0,0,0,1)]clamped black text[n]%
|
||||
MSG This is [ansicolor(255,255,255,0,1)]clamped white text[n]
|
||||
|
||||
FLUSH
|
||||
|
||||
# Test that MSF ignores ansi color sequences
|
||||
set r ansicolor(255, 0, 0)
|
||||
set g ansicolor(0, 255, 0)
|
||||
set b ansicolor(0, 0, 255)
|
||||
set n ansicolor("")
|
||||
|
||||
|
||||
REM MSF Here we have a formatted reminder. It should be word-wrapped nicely and neatly by Remind. Although it is very long and unwieldy, the MSF keyword will wrap it so it's pleasantly readable.%_Here we have a formatted reminder. It should be word-wrapped nicely and neatly by Remind. Although it is very long and unwieldy, the MSF keyword will wrap it so it's pleasantly readable.
|
||||
|
||||
# Should have exactly the same word breaks
|
||||
REM MSF [r]Here [g]we [b]have [r]a [g]formatted [b]reminder. [r]It [g]should[b] be [r]word-wrapped[g] nicely [b]and [r]neatly [g]by Remind. [b]Although [r]it [g]is [b]very [r]long [g]and [b]u[r]n[g]w[b]i[r]e[g]l[b]d[r]y[g], [r]the [g]MSF [b]keyword [r]will [r] [g] [b] [g]wrap [b]it [r]so [g]it's [b]pleasantly [r]readable.[n]%_[r]Here [g]we [b]have [r]a [g]formatted [b]reminder. [r]It [g]should[b] be [r]word-wrapped[g] nicely [b]and [r]neatly [g]by Remind. [b]Although [r]it [g]is [b]very [r]long [g]and [b]u[r]n[g]w[b]i[r]e[g]l[b]d[r]y[g], [r]the [g]MSF [b]keyword [r]will [r] [g] [b] [g]wrap [b]it [r]so [g]it's [b]pleasantly [r]readable.[n]
|
||||
|
||||
REM MSF Εδώ έχουμε μια μορφοποιημένη υπενθύμιση. Θα πρέπει να είναι τυλιγμένο με λέξεις όμορφα και τακτοποιημένα από το Remind. Αν και είναι πολύ μακρύ και δυσκίνητο, η λέξη-κλειδί των ΓΧΣ θα το τυλίξει έτσι ώστε να είναι ευχάριστα ευανάγνωστο. 🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅%_Εδώ έχουμε μια μορφοποιημένη υπενθύμιση. Θα πρέπει να είναι τυλιγμένο με λέξεις όμορφα και τακτοποιημένα από το Remind. Αν και είναι πολύ μακρύ και δυσκίνητο, η λέξη-κλειδί των ΓΧΣ θα το τυλίξει έτσι ώστε να είναι ευχάριστα ευανάγνωστο. 🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅
|
||||
|
||||
REM MSF [r]Εδώ [g]έχουμε [b]μια [r]μ[g]ο[b]ρ[r]φοποιημένη[n] υπενθύμιση. Θα πρέπει να είναι τυλιγμένο με λέξεις όμορφα και τακτοποιημένα από το Remind. Αν και είναι πολύ μακρύ και δυσκίνητο, η λέξη-κλειδί των ΓΧΣ θα το τυλίξει έτσι ώστε να είναι ευχάριστα ευανάγνωστο. 🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅%_[r]Εδώ [g]έχουμε [b]μια [r]μ[g]ο[b]ρ[r]φοποιημένη[n] υπενθύμιση. Θα πρέπει να είναι τυλιγμένο με λέξεις όμορφα και τακτοποιημένα από το Remind. Αν και είναι πολύ μακρύ και δυσκίνητο, η λέξη-κλειδί των ΓΧΣ θα το τυλίξει έτσι ώστε να είναι ευχάριστα ευανάγνωστο. 🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅🌅 🌅 🌅 🌅 🌅
|
||||
FLUSH
|
||||
|
||||
# Some invalid combos
|
||||
set a ansicolor(1)
|
||||
set a ansicolor(-1, 0, 0)
|
||||
set a ansicolor(42, 42, 256)
|
||||
set a ansicolor("foo")
|
||||
set a ansicolor("1 1")
|
||||
set a ansicolor("-1 -1 0");
|
||||
set a ansicolor("256 1 1");
|
||||
set a ansicolor(128, 128, 128, 2)
|
||||
set a ansicolor(128, 128, 128, -1)
|
||||
set a ansicolor(128, 128, 128, 0, 2)
|
||||
set a ansicolor(128, 128, 128, 0, -1)
|
||||
|
||||
set a ansicolor(128,0,0)
|
||||
|
||||
set str a + "foo: 🌅"
|
||||
set w columns(str)
|
||||
MSG Width of [str] is: [w]
|
||||
5
tests/blanks.rem
Normal file
5
tests/blanks.rem
Normal file
@@ -0,0 +1,5 @@
|
||||
MSG $AddBlankLines=[$AddBlankLines]%_
|
||||
MSG Hello
|
||||
MSG Hi
|
||||
MSF How are you?
|
||||
MSG OK
|
||||
@@ -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
|
||||
|
||||
|
||||
134
tests/test-rem
134
tests/test-rem
@@ -26,11 +26,30 @@ if test `id -u` = 0 ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If we're already in a utf-8 locale, do
|
||||
# nothing; otherwise, set LC_ALL
|
||||
OK=0
|
||||
if echo $LC_ALL | grep -i utf-8 > /dev/null 2>&1 ; then
|
||||
OK=1
|
||||
fi
|
||||
|
||||
if test -z "$LC_ALL" ; then
|
||||
if echo $LANG | grep -i utf-8 > /dev/null 2>&1 ; then
|
||||
export LC_ALL="$LANG"
|
||||
OK=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$OK" = 0 ; then
|
||||
export LC_ALL=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
fi
|
||||
|
||||
chmod 000 include_dir/04cantread.rem
|
||||
TEST_GETENV="foo bar baz" ; export TEST_GETENV
|
||||
echo "Test 1" > ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
../src/remind -e -dxte ../tests/test.rem 16 feb 1991 >> ../tests/test.out 2>&1
|
||||
../src/remind -e -dxte ../tests/test.rem 16 feb 1991 12:13 >> ../tests/test.out 2>&1
|
||||
echo "" >> ../tests/test.out
|
||||
echo "Test 2" >> ../tests/test.out
|
||||
echo "" >> ../tests/test.out
|
||||
@@ -76,6 +95,32 @@ echo 'REM Mon 31 2021 MSG [$T]' | ../src/remind -dt - 31 dec 2021 >> ../tests/te
|
||||
echo "Color Test" >> ../tests/test.out
|
||||
../src/remind -ccl ../tests/colors.rem 1 aug 2007 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "ANSI Color Test" >> ../tests/test.out
|
||||
../src/remind ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,0 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,0,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@0,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@1,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind -@2,1,1 ../tests/ansicolors.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
|
||||
echo '$AddBlankLines test' >> ../tests/test.out
|
||||
../src/remind ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind '-i$AddBlankLines=1' ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
../src/remind '-i$AddBlankLines=0' ../tests/blanks.rem 1 Jan 2022 >> ../tests/test.out 2>&1
|
||||
|
||||
echo "MON WKDAY DAY across year test" >> ../tests/test.out
|
||||
echo 'REM Mon 29 Dec MSG x' | ../src/remind -dt - 1 Jan 2000 >> ../tests/test.out 2>&1
|
||||
|
||||
@@ -123,23 +168,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 +212,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 +234,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 +256,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 +278,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 +300,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 +322,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 +344,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 +366,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
|
||||
@@ -306,30 +389,17 @@ rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
|
||||
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
|
||||
EOF
|
||||
|
||||
# If we're already in a utf-8 locale, do
|
||||
# nothing; otherwise, set LC_ALL
|
||||
OK=0
|
||||
if echo $LC_ALL | grep -i utf-8 > /dev/null 2>&1 ; then
|
||||
OK=1
|
||||
fi
|
||||
|
||||
if test -z "$LC_ALL" ; then
|
||||
if echo $LANG | grep -i utf-8 > /dev/null 2>&1 ; then
|
||||
export LC_ALL="$LANG"
|
||||
OK=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$OK" = 0 ; then
|
||||
export LC_ALL=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
fi
|
||||
|
||||
../src/remind -w128 -c ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
../src/remind -c ../tests/test-addomit.rem 1 Sep 2021 >> ../tests/test.out
|
||||
|
||||
../src/remind -cu ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
../src/remind -cu '-i$SuppressLRM=1' ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
|
||||
|
||||
TZ=America/Toronto ../src/remind -dxe ../tests/tz.rem >> ../tests/test.out 2>&1
|
||||
TZ=Europe/Berlin ../src/remind -dxe ../tests/tz.rem >> ../tests/test.out 2>&1
|
||||
|
||||
# Remove references to SysInclude, which is build-specific
|
||||
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"
|
||||
|
||||
3780
tests/test.cmp
3780
tests/test.cmp
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
30
tests/tz.rem
Normal file
30
tests/tz.rem
Normal file
@@ -0,0 +1,30 @@
|
||||
# Test conversion between local time and UTC
|
||||
|
||||
set a localtoutc('2022-01-01@12:00')
|
||||
set a localtoutc('2022-03-13@02:59')
|
||||
set a localtoutc('2022-03-13@03:00')
|
||||
set a localtoutc('2022-03-13@03:01')
|
||||
set a localtoutc('2022-06-01@12:00')
|
||||
set a localtoutc('2022-11-06@01:59')
|
||||
set a localtoutc('2022-11-06@02:00')
|
||||
set a localtoutc('2022-11-06@02:01')
|
||||
set a localtoutc('2022-12-01@12:00')
|
||||
|
||||
set b utctolocal('2022-01-01@17:00')
|
||||
set b utctolocal('2022-03-13@06:00')
|
||||
set b utctolocal('2022-03-13@06:01')
|
||||
set b utctolocal('2022-03-13@06:59')
|
||||
set b utctolocal('2022-03-13@07:00')
|
||||
set b utctolocal('2022-03-13@07:01')
|
||||
set b utctolocal('2022-03-13@07:59')
|
||||
set b utctolocal('2022-06-01@16:00')
|
||||
set b utctolocal('2022-11-06@05:59')
|
||||
set b utctolocal('2022-11-06@06:00')
|
||||
set b utctolocal('2022-11-06@06:01')
|
||||
set b utctolocal('2022-11-06@06:59')
|
||||
set b utctolocal('2022-11-06@07:00')
|
||||
set b utctolocal('2022-11-06@07:01')
|
||||
set b utctolocal('2022-12-01@17:00')
|
||||
|
||||
set c timezone('2022-07-01')
|
||||
set c timezone('2022-12-01')
|
||||
@@ -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
|
||||
|
||||
@@ -17,7 +17,7 @@ HTMLDIR = /var/www/remind
|
||||
# Where you stick images and CSS files, as seen by UNIX
|
||||
IMAGEDIR = /var/www/remind/resources
|
||||
|
||||
# Where images and CSS fiels are, as seen by web browers
|
||||
# Where images and CSS files are, as seen by web browsers
|
||||
IMAGEBASE = /remind/resources
|
||||
|
||||
# Set by configure - don't touch.
|
||||
|
||||
Reference in New Issue
Block a user