mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
369 Commits
03.04.00-R
...
04.02.01
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b5fe4f2a0 | ||
|
|
98fc4a917f | ||
|
|
e633530a36 | ||
|
|
bfea9915b9 | ||
|
|
d68ed6e75d | ||
|
|
a22631d768 | ||
|
|
552bf84e33 | ||
|
|
28d0251093 | ||
|
|
f3d969f658 | ||
|
|
2afe95d090 | ||
|
|
3692a6b265 | ||
|
|
8fc19358bb | ||
|
|
c8f9773d83 | ||
|
|
e1091db82f | ||
|
|
9f8ed13434 | ||
|
|
914f03d5eb | ||
|
|
a801f6d4ce | ||
|
|
fde5a7b4ca | ||
|
|
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 | ||
|
|
62b94ab065 | ||
|
|
49c7399599 | ||
|
|
5fa9297aba | ||
|
|
4ada31798b | ||
|
|
e78f953e90 | ||
|
|
af7a9ad8b5 | ||
|
|
35eae045a6 | ||
|
|
98a20ae058 | ||
|
|
df9ef6e13a | ||
|
|
10f5802069 | ||
|
|
780044219f | ||
|
|
d015c061e7 | ||
|
|
6f6326d433 | ||
|
|
9488e7ca13 | ||
|
|
71c11672c2 | ||
|
|
0acefa800e | ||
|
|
d45cee4712 | ||
|
|
c026aa05e2 | ||
|
|
50076c74fa | ||
|
|
1563d77c06 | ||
|
|
ed72ef8629 | ||
|
|
06c5996086 | ||
|
|
570ca857a0 | ||
|
|
f8f20b7afc | ||
|
|
f55ef7ff20 | ||
|
|
79220a74cf | ||
|
|
77111ef628 | ||
|
|
bf96063311 | ||
|
|
58a201fceb | ||
|
|
47cecb210b | ||
|
|
bfbf744b0a | ||
|
|
0cf56ac1de | ||
|
|
2880a718f4 | ||
|
|
da0dd0f7c6 | ||
|
|
c456d3e0ff | ||
|
|
59059736e6 | ||
|
|
f5cf2ab832 | ||
|
|
cc4ff2582d | ||
|
|
90f5fde3bb | ||
|
|
9fbe9f5132 | ||
|
|
f05661fa6c | ||
|
|
d6882c3378 | ||
|
|
e32cab937e | ||
|
|
14bb939977 | ||
|
|
13e830782d | ||
|
|
f39bb5e2d9 | ||
|
|
8b795e81b7 | ||
|
|
aef7eeda5a | ||
|
|
0641a6f8f1 | ||
|
|
4fdf7b706b | ||
|
|
0653b9420a | ||
|
|
27ede1ce37 | ||
|
|
a303fb9cba | ||
|
|
92af4e9c3e | ||
|
|
abc4f45fed | ||
|
|
e651f92bd9 | ||
|
|
b2d3d98d72 | ||
|
|
cb8b7f85af | ||
|
|
d30f347a0b | ||
|
|
5e9b1e7464 | ||
|
|
58085470c5 | ||
|
|
8f0de805d5 | ||
|
|
3f879a1b97 | ||
|
|
94270c3d98 | ||
|
|
bb8a689186 | ||
|
|
a7e73cdac8 | ||
|
|
d38c324340 | ||
|
|
fade38d522 | ||
|
|
858a7601aa | ||
|
|
37e3d3d1d1 | ||
|
|
ff67ab3c86 | ||
|
|
ad7faa8ad9 | ||
|
|
c927166a8a | ||
|
|
9d22fba842 | ||
|
|
3d5adf6c42 | ||
|
|
5ba862cbd7 | ||
|
|
6f20e056c9 | ||
|
|
878ab1a8bc | ||
|
|
4d17494371 | ||
|
|
65763b9522 | ||
|
|
52840d40de | ||
|
|
6892e7a805 | ||
|
|
24d0264f92 | ||
|
|
56c37e4e05 | ||
|
|
86c99102b5 | ||
|
|
de4a23ee1e | ||
|
|
6a9f7c186a | ||
|
|
eaed22a42b | ||
|
|
f47cf2320e | ||
|
|
eb100e57e2 | ||
|
|
948548c73f | ||
|
|
7495ae1e05 | ||
|
|
51ae17bd0a | ||
|
|
61d665ef7d | ||
|
|
5aaf19ffdb | ||
|
|
2eb672e380 | ||
|
|
4a59bf686b | ||
|
|
f98ab6f686 | ||
|
|
3600cd95cd | ||
|
|
f8bd79fbb2 | ||
|
|
4c403047eb | ||
|
|
25009de417 | ||
|
|
c4588654ec | ||
|
|
c1e5279272 | ||
|
|
cda8396690 | ||
|
|
c0f79d1e69 | ||
|
|
375a0fb7a2 | ||
|
|
2069114ef1 | ||
|
|
f6d9e8724d | ||
|
|
8e55438200 | ||
|
|
1ca6feb112 | ||
|
|
732ce8283f | ||
|
|
122bd3e07e | ||
|
|
0ac5cbb837 | ||
|
|
7f3d4812a8 | ||
|
|
e1fa11c94c | ||
|
|
c06c65acf1 | ||
|
|
a84fa0bc8f | ||
|
|
054648e02b | ||
|
|
9548041334 | ||
|
|
da306f2900 | ||
|
|
26587aea02 | ||
|
|
adc86e0f00 | ||
|
|
a9ed5f075e | ||
|
|
21e30c980e | ||
|
|
a657b2e55a | ||
|
|
ff8c55b8b6 | ||
|
|
eb36c5bca0 | ||
|
|
89173ce1ee | ||
|
|
5d115ba3e3 | ||
|
|
7e3adeb9c9 | ||
|
|
080cda86fa | ||
|
|
6274cbad52 | ||
|
|
85c4ad821d | ||
|
|
b758a2fea8 | ||
|
|
6619cc7ca4 | ||
|
|
961f7a8a62 | ||
|
|
905287901f | ||
|
|
669be7bf57 | ||
|
|
9b8eb2dc4c | ||
|
|
00ab7b196d | ||
|
|
f616be4bdd | ||
|
|
8ae9ce8523 | ||
|
|
6d2bbbd7e2 | ||
|
|
1453be83b2 | ||
|
|
8659131be2 | ||
|
|
0276ce322d | ||
|
|
b36c99a34b | ||
|
|
ad575f1485 | ||
|
|
a9162f1472 | ||
|
|
221e2554a9 | ||
|
|
04ec6c3695 | ||
|
|
b1594980fc | ||
|
|
024a8ef38d | ||
|
|
b281051421 | ||
|
|
aa1b275b51 | ||
|
|
c22ca68857 | ||
|
|
3804ce3fe3 | ||
|
|
0977f1db04 | ||
|
|
83c97934c9 | ||
|
|
44c9d74caa | ||
|
|
172f56754a | ||
|
|
dc184cc713 |
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -1,4 +1,5 @@
|
||||
.gitignore export-ignore
|
||||
.gitattributes export-ignore
|
||||
remind.php export-ignore
|
||||
sync-to-dianne-git export-ignore
|
||||
sync-to-dianne-git export-ignore
|
||||
php export-ignore
|
||||
|
||||
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 .
|
||||
27
.gitignore
vendored
27
.gitignore
vendored
@@ -1,27 +1,34 @@
|
||||
rem2pdf/Makefile.old
|
||||
*.bak
|
||||
*.o
|
||||
*~
|
||||
.gitignore
|
||||
MYMETA.json
|
||||
MYMETA.yml
|
||||
Makefile
|
||||
TAGS
|
||||
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
|
||||
rem2pdf/Makefile.PL
|
||||
rem2pdf/Makefile.old
|
||||
rem2pdf/Makefile.top
|
||||
rem2pdf/bin/rem2pdf
|
||||
set-irc-topic
|
||||
src/*.tar.gz*
|
||||
src/Makefile
|
||||
src/config.h
|
||||
src/rem2ps
|
||||
src/remind
|
||||
src/test-*.out
|
||||
src/version.h
|
||||
tests/test.out
|
||||
www/Makefile
|
||||
rem2pdf/Makefile.PL
|
||||
MYMETA.json
|
||||
MYMETA.yml
|
||||
Makefile
|
||||
blib/
|
||||
pm_to_blib
|
||||
rem2pdf/Makefile.top
|
||||
rem2pdf/bin/rem2pdf
|
||||
rem2html/rem2html.1
|
||||
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
|
||||
@@ -3,7 +3,7 @@ THE REMIND COPYRIGHT
|
||||
1. REMIND refers to the entire set of files and documentation in the
|
||||
REMIND package.
|
||||
|
||||
2. REMIND is Copyright 1992-2021 Dianne Skoll, except where noted in
|
||||
2. REMIND is Copyright 1992-2022 Dianne Skoll, except where noted in
|
||||
individual files.
|
||||
|
||||
3. DISTRIBUTION AND USE
|
||||
|
||||
27
Makefile
27
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
|
||||
@$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE)
|
||||
clean:
|
||||
find . -name '*~' -exec rm {} \;
|
||||
$(MAKE) -C src clean
|
||||
-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
|
||||
|
||||
|
||||
40
README
40
README
@@ -34,5 +34,45 @@ 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
|
||||
|
||||
If the little arrows for "Previous Month" and "Next Month" do not display
|
||||
correctly in TkRemind, you may need to install the Noto Fonts. Install
|
||||
all of your distribution's Nonto Font-related packages.
|
||||
|
||||
- On Debian-like systems, install with:
|
||||
|
||||
apt install fonts-noto-core fonts-noto-color-emoji \
|
||||
fonts-noto-extra fonts-noto-ui-core fonts-noto-ui-extra
|
||||
|
||||
==========================================================================
|
||||
Contact info: mailto:dianne@skoll.ca
|
||||
Home page: https://dianne.skoll.ca/projects/remind/
|
||||
|
||||
2
build.tk
2
build.tk
@@ -355,7 +355,7 @@ proc RunCommand { cmd } {
|
||||
# %RETURNS:
|
||||
# Nothing
|
||||
# %DESCRIPTION:
|
||||
# Reads characters from command pipelin and appends them to .msg.
|
||||
# Reads characters from command pipeline and appends them to .msg.
|
||||
#***********************************************************************
|
||||
proc CommandReadable { f } {
|
||||
global CmdDone
|
||||
|
||||
70
configure
vendored
70
configure
vendored
@@ -622,6 +622,8 @@ ac_includes_default="\
|
||||
ac_header_list=
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
LIBOBJS
|
||||
RELEASE_DATE
|
||||
PERLARTIFACTS
|
||||
VERSION
|
||||
EGREP
|
||||
GREP
|
||||
@@ -681,6 +683,7 @@ SHELL'
|
||||
ac_subst_files=''
|
||||
ac_user_opts='
|
||||
enable_option_checking
|
||||
enable_perl_build_artifacts
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
host_alias
|
||||
@@ -1305,6 +1308,13 @@ if test -n "$ac_init_help"; then
|
||||
|
||||
cat <<\_ACEOF
|
||||
|
||||
Optional Features:
|
||||
--disable-option-checking ignore unrecognized --enable/--with options
|
||||
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||
--disable-perl-build-artifacts
|
||||
Disable perllocal.pod and .packlist generation
|
||||
|
||||
Some influential environment variables:
|
||||
CC C compiler command
|
||||
CFLAGS C compiler flags
|
||||
@@ -2292,6 +2302,16 @@ EOF
|
||||
ac_config_headers="$ac_config_headers src/config.h"
|
||||
|
||||
|
||||
# Check whether --enable-perl-build-artifacts was given.
|
||||
if test "${enable_perl_build_artifacts+set}" = set; then :
|
||||
enableval=$enable_perl_build_artifacts; ac_cv_perlartifacts=$enableval
|
||||
else
|
||||
ac_cv_perlartifacts=yes
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
@@ -3287,7 +3307,6 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5
|
||||
$as_echo_n "checking for sqrt in -lm... " >&6; }
|
||||
if ${ac_cv_lib_m_sqrt+:} false; then :
|
||||
@@ -3798,7 +3817,7 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
for ac_header in sys/types.h sys/file.h glob.h wctype.h locale.h
|
||||
for ac_header in sys/types.h sys/file.h glob.h wctype.h locale.h langinfo.h
|
||||
do :
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
|
||||
@@ -3955,8 +3974,45 @@ fi
|
||||
|
||||
if test "$GCC" = yes; then
|
||||
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
|
||||
# Check for link-time optimization support
|
||||
f=-flto=auto
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $f" >&5
|
||||
$as_echo_n "checking whether $CC supports $f... " >&6; }
|
||||
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
CFLAGS="$CFLAGS $f"
|
||||
f=-ffat-lto-objects
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $f" >&5
|
||||
$as_echo_n "checking whether $CC supports $f... " >&6; }
|
||||
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
CFLAGS="$CFLAGS $f"
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$ac_cv_perlartifacts" = "yes" ; then
|
||||
PERLARTIFACTS=
|
||||
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`
|
||||
@@ -3969,10 +4025,12 @@ _ACEOF
|
||||
fi
|
||||
done
|
||||
|
||||
VERSION=03.04.00
|
||||
VERSION=04.02.01
|
||||
|
||||
|
||||
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
|
||||
@@ -4672,6 +4730,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
|
||||
|
||||
47
configure.in
47
configure.in
@@ -14,6 +14,12 @@ EOF
|
||||
|
||||
AC_CONFIG_HEADER(src/config.h)
|
||||
|
||||
AC_ARG_ENABLE(perl-build-artifacts,
|
||||
[ --disable-perl-build-artifacts
|
||||
Disable perllocal.pod and .packlist generation], ac_cv_perlartifacts=$enableval, ac_cv_perlartifacts=yes)
|
||||
|
||||
AH_BOTTOM([#include <custom.h>])
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
@@ -22,8 +28,6 @@ AC_PROG_MAKE_SET
|
||||
AC_PATH_PROG([PERL], [perl])
|
||||
|
||||
dnl Checks for libraries.
|
||||
dnl Replace `main' with a function in -lm:
|
||||
|
||||
AC_CHECK_LIB(m, sqrt)
|
||||
|
||||
dnl Integer sizes
|
||||
@@ -31,7 +35,7 @@ AC_CHECK_SIZEOF(unsigned int)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_CHECK_HEADERS(sys/types.h sys/file.h glob.h wctype.h locale.h)
|
||||
AC_CHECK_HEADERS(sys/types.h sys/file.h glob.h wctype.h locale.h langinfo.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_STRUCT_TM
|
||||
@@ -42,11 +46,44 @@ AC_HEADER_TIME
|
||||
|
||||
if test "$GCC" = yes; then
|
||||
CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes"
|
||||
# Check for link-time optimization support
|
||||
f=-flto=auto
|
||||
AC_MSG_CHECKING([whether $CC supports $f])
|
||||
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
|
||||
AC_MSG_RESULT([yes])
|
||||
CFLAGS="$CFLAGS $f"
|
||||
f=-ffat-lto-objects
|
||||
AC_MSG_CHECKING([whether $CC supports $f])
|
||||
if $CC -E $f /dev/null > /dev/null 2>&1 ; then
|
||||
AC_MSG_RESULT([yes])
|
||||
CFLAGS="$CFLAGS $f"
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$ac_cv_perlartifacts" = "yes" ; then
|
||||
PERLARTIFACTS=
|
||||
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=03.04.00
|
||||
VERSION=04.02.01
|
||||
AC_SUBST(VERSION)
|
||||
AC_SUBST(PERL)
|
||||
AC_OUTPUT(src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf)
|
||||
AC_SUBST(PERLARTIFACTS)
|
||||
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
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
# version 0.5 2007-03-21
|
||||
# - Add more help options
|
||||
# - --project-lead-time option
|
||||
# - Supress printing of heading if there are no todos to print
|
||||
# - Suppress printing of heading if there are no todos to print
|
||||
# version 0.4
|
||||
# - Version 0.4 changes all written or inspired by, and thanks to Mark Stosberg
|
||||
# - Change to GetOptions
|
||||
@@ -84,7 +84,7 @@ How may days in advance to start getting reminders about the events. Defaults to
|
||||
|
||||
ical2rem.pl --no-todos
|
||||
|
||||
If you don't care about the ToDos the calendar, this will surpress
|
||||
If you don't care about the ToDos the calendar, this will suppress
|
||||
printing of the ToDo heading, as well as skipping ToDo processing.
|
||||
|
||||
=head2 --heading
|
||||
|
||||
@@ -141,7 +141,7 @@ appear with exactly the text and exactly the same duration (including
|
||||
one VEVENT object, that will have a RFC2445 C<RDATE> property.
|
||||
|
||||
B<rem2ics> is not yet smart enough to derive an C<RRULE> based
|
||||
recurrance. If you really want that feature, either implement it and
|
||||
recurrence. If you really want that feature, either implement it and
|
||||
send in a patch, or contact the author and convince him to do it.
|
||||
|
||||
=head2 Other iCalendar Properties
|
||||
@@ -164,7 +164,7 @@ runs.
|
||||
|
||||
=head2 Other iCalendar Perl objects
|
||||
|
||||
Why does't B<rem2ics> use any of the iCalendar Perl stuff in CPAN?
|
||||
Why doesn't B<rem2ics> use any of the iCalendar Perl stuff in CPAN?
|
||||
Because I don't trust them, and they are too big for this app. One
|
||||
links to a binary library. Another hasn't been maintained since 1991,
|
||||
and is full of notes as to how buggy and incomplete it is. And so
|
||||
@@ -218,7 +218,7 @@ Bug fix, error message for non-recurring events
|
||||
Bug fix,
|
||||
rem2ics 0.91 chokes on timed reminders with
|
||||
duration using `remind -s` as it functions in remind-03.01.03.
|
||||
Remind 3.01 changed how the -s data is formated for events that have a duration
|
||||
Remind 3.01 changed how the -s data is formatted for events that have a duration
|
||||
Patch by Paul Hinze E<lt>paul dot t dot hinze at gmail dot comE<gt>
|
||||
and Michael Schultz E<lt>mjschultz at gmail dot comE<gt>
|
||||
|
||||
@@ -376,7 +376,7 @@ foreach $v (@events) {
|
||||
|
||||
my(%grovel);
|
||||
|
||||
# if the user doesnt want recurrance detection
|
||||
# if the user doesn't want recurrence detection
|
||||
unless ($options{norecurr}) {
|
||||
|
||||
# then dont put events in the grovel hash
|
||||
@@ -393,7 +393,7 @@ unless ($options{norecurr}) {
|
||||
$v = ${$grovel{$k}}[0];
|
||||
$v->{recurlist} = \@{$grovel{$k}};
|
||||
foreach my $v0 (@{$grovel{$k}}) {
|
||||
$v0->{is_recurrance} = $v;
|
||||
$v0->{is_recurrence} = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -409,12 +409,12 @@ unless ($options{norecurr}) {
|
||||
# might have a problem if a recurring event has two instances both on
|
||||
# the first day.
|
||||
|
||||
# Every event that is recurring has a "is_recurrance" property.
|
||||
# Every event that is recurring has a "is_recurrence" property.
|
||||
# Additionally, (hopefully) the first/earliest event in a set of
|
||||
# recurrances has a "recurlist" property. The "recurlist" is a
|
||||
# recurrences has a "recurlist" property. The "recurlist" is a
|
||||
# reference to a list of references to each of the events. The first
|
||||
# one on that list will be the same event that has the "recurlist"
|
||||
# property. The "is_recurrance" property is a reference back to the
|
||||
# property. The "is_recurrence" property is a reference back to the
|
||||
# event that has the "recurlist" property.
|
||||
|
||||
foreach my $k (keys %grovel) {
|
||||
@@ -466,8 +466,8 @@ foreach my $k (keys %grovel) {
|
||||
}
|
||||
|
||||
foreach $v (@events) {
|
||||
# for recurrant events, skip those that arnt the "head"
|
||||
next if ($v->{is_recurrance} and (not $v->{recurlist}));
|
||||
# for recurrent events, skip those that arnt the "head"
|
||||
next if ($v->{is_recurrence} and (not $v->{recurlist}));
|
||||
|
||||
if (${$v->{sf}}[4] eq "*") { # no time was given
|
||||
$v->{i_dtstart} = sprintf("DTSTART:%s", $v->{dts});
|
||||
@@ -485,7 +485,7 @@ foreach $v (@events) {
|
||||
}
|
||||
|
||||
if (${$v->{sf}}[3] ne "*") { # a duration was given
|
||||
# It's convienient that RFC2445 defines DURATION, thus we
|
||||
# It's convenient that RFC2445 defines DURATION, thus we
|
||||
# don't need to calculate DTEND, with awkward figuring out
|
||||
# crossing hours, days, months, year, etc. Instead we
|
||||
# will let the iCalendar consuming application worry about it.
|
||||
@@ -501,8 +501,8 @@ print "BEGIN:VCALENDAR\015\012"
|
||||
|
||||
# output each vevent
|
||||
foreach $v (@events) {
|
||||
# for recurrant events, only output the "head", skip the others
|
||||
next if ($v->{is_recurrance} and (not $v->{recurlist}));
|
||||
# for recurrent events, only output the "head", skip the others
|
||||
next if ($v->{is_recurrence} and (not $v->{recurlist}));
|
||||
|
||||
print "BEGIN:VEVENT\015\012";
|
||||
my $tag = ${$v->{sf}}[2];
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
;; Author: Shelagh Manton <shelagh.manton@gmail.com> with help from
|
||||
;; Dianne Skoll
|
||||
;; Keywords: remind configure convenience
|
||||
;; Version: 0.14
|
||||
;; Version: 0.15-dfs2
|
||||
|
||||
;; This program is free software; you can redistribute it and/or
|
||||
;; modify it under the terms of the GNU General Public License
|
||||
@@ -91,7 +91,6 @@
|
||||
(define-key remind-conf-mode-map "\C-c\C-x" 'rem-tomorrow)
|
||||
(define-key remind-conf-mode-map "\C-c\C-a" 'rem-days-away)
|
||||
(define-key remind-conf-mode-map "\M-j" 'remind-indent-line)
|
||||
(define-key remind-conf-mode-map (kbd "RET") 'remind-indent-line)
|
||||
(define-key remind-conf-mode-map "\C-c\C-c" 'rem-save-file)
|
||||
|
||||
;; syntax-table
|
||||
@@ -111,12 +110,18 @@
|
||||
|
||||
(defconst remind-keywords
|
||||
(sort
|
||||
(list "RUN" "REM" "ONCE" "SATISFY" "BEFORE" "UNSET" "OMIT" "FIRST" "SATISFY"
|
||||
"OMIT" "DATE" "SKIP" "ONCE" "AFTER" "WARN" "PRIORITY" "AT" "SCHED" "IF" "ELSE" "ENDIF"
|
||||
"WARN" "UNTIL" "THROUGH" "SCANFROM" "DURATION" "TAG" "MSG" "MSF" "CAL" "SPECIAL" "IFTRIG"
|
||||
"PS" "PSFILE" "BANNER" "INCLUDE" "PUSH-OMIT-CONTEXT" "DEBUG" "DUMPVARS" "PUSH" "CLEAR" "POP"
|
||||
"CLEAR-OMIT-CONTEXT" "POP-OMIT-CONTEXT" "SET" "ERRMSG" "FSET" "DUMP" "BAN" "INC" "SCAN"
|
||||
"EXIT" "FLUSH" "PRESERVE" "MOON" "COLOR" "UNSET")
|
||||
(list "ADDOMIT" "AFTER" "AT" "BANNER" "BEFORE"
|
||||
"CAL" "CLEAR-OMIT-CONTEXT" "DEBUG" "DO" "DUMPVARS"
|
||||
"DURATION" "ELSE" "ENDIF" "ERRMSG" "EXIT" "FIRST"
|
||||
"FLUSH" "FOURTH" "FROM" "FSET" "IF" "IFTRIG" "IN"
|
||||
"INCLUDE" "INCLUDECMD" "LAST" "LASTDAY"
|
||||
"LASTWORKDAY" "MAYBE-UNCOMPUTABLE" "MSF"
|
||||
"MSG" "OMIT" "OMITFUNC" "ONCE"
|
||||
"POP-OMIT-CONTEXT" "PRESERVE" "PRIORITY" "PS" "PSFILE"
|
||||
"PUSH-OMIT-CONTEXT" "REM" "RUN" "SATISFY" "SCANFROM"
|
||||
"SCHED" "SECOND" "SET" "SKIP" "SPECIAL"
|
||||
"TAG" "THIRD" "THROUGH" "UNSET" "UNTIL"
|
||||
"WARN")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
|
||||
@@ -127,12 +132,20 @@
|
||||
|
||||
(defconst remind-builtin-variables
|
||||
(sort
|
||||
(list "$CalcUTC" "$CalMode" "$Daemon" "$DateSep" "$DefaultPrio" "$DontFork" "$DontTrigAts" "$DontQueue"
|
||||
"$EndSent" "$EndSentIg" "$NumTrig" "$FirstIndent" "$FoldYear" "$FormWidth" "$HushMode"
|
||||
"$IgnoreOnce" "$InfDelta" "$NextMode" "$NumQueued" "$NumTrig" "$PrefixLineNo" "$PSCal" "$RunOff"
|
||||
"$SimpleCal" "$SortByDate" "$SortByPrio" "$MinsFromUTC" "$LatDeg" "$LatMin" "$LatSec" "$EndSent"
|
||||
"$EndSentIg" "$Location" "$LongDeg" "$LongMin" "$LongSec" "$MaxSatIter" "$SubsIndent" "$T" "$Td"
|
||||
"$Tm" "$Tw" "$Ty" "$TimeSep" "$UntimedFirst" "$U" "$Ud" "$Um" "$Uw" "$Uy")
|
||||
(list "$Ago" "$Am" "$And" "$April" "$At" "$August" "$CalcUTC" "$CalMode" "$Daemon" "$DateSep"
|
||||
"$DateTimeSep" "$December" "$DefaultColor" "$DefaultPrio"
|
||||
"$DefaultTDelta" "$DeltaOffset" "$DontFork" "$DontQueue"
|
||||
"$DontTrigAts" "$EndSent" "$EndSentIg" "$February" "$FirstIndent"
|
||||
"$FoldYear" "$FormWidth" "$Friday" "$Fromnow" "$Hour" "$Hplu" "$HushMode" "$IgnoreOnce"
|
||||
"$InfDelta" "$IntMax" "$IntMin" "$Is" "$January" "$July" "$June" "$LatDeg"
|
||||
"$Latitude" "$LatMin" "$LatSec" "$Location" "$LongDeg" "$Longitude"
|
||||
"$LongMin" "$LongSec" "$March" "$MaxSatIter" "$MaxStringLen" "$May"
|
||||
"$MinsFromUTC" "$Minute" "$Monday" "$Mplu" "$NextMode" "$November" "$Now" "$NumQueued"
|
||||
"$NumTrig" "$October" "$On" "$Pm" "$PrefixLineNo" "$PSCal" "$RunOff" "$Saturday"
|
||||
"$September" "$SimpleCal" "$SortByDate" "$SortByPrio" "$SortByTime"
|
||||
"$SubsIndent" "$Sunday" "$SysInclude" "$T" "$Td" "$Thursday" "$TimeSep" "$Tm"
|
||||
"$Today" "$Tomorrow" "$Tuesday" "$Tw" "$Ty" "$U" "$Ud" "$Um" "$UntimedFirst" "$Uw" "$Uy"
|
||||
"$Was" "$Wednesday")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
|
||||
@@ -147,15 +160,22 @@
|
||||
|
||||
(defconst remind-builtin-functions
|
||||
(sort
|
||||
(list "abs" "access" "args" "asc" "baseyr" "char" "choose" "coerce" "current" "date" "datetime" "datepart"
|
||||
"dawn" "day" "daysinmon" "defined" "dosubst" "dusk" "easter" "easterdate" "evaltrig" "filedate"
|
||||
"filedatetime" "filedir" "filename" "getenv" "hebdate" "hebday" "hebmon" "hebyear" "hour" "iif" "index" "isdst"
|
||||
"isleap" "isomitted" "language" "lower" "max" "min" "minute" "minsfromutc" "mon" "monnum" "moondate" "moondatetime"
|
||||
"moonphase" "moontime" "msgprefix" "msgsuffix" "nonomitted" "now" "ord" "ostype" "plural"
|
||||
"psmoon" "psshade" "realcurrent" "realnow" "realtoday" "sgn" "shell" "slide" "strlen" "substr" "sunrise" "sunset" "time" "timepart"
|
||||
"thisyear" "today" "trigdate" "trigdatetime" "trigger" "trigger" "trigtime" "trigvalid" "typeof" "tzconvert" "upper" "value"
|
||||
"version" "weekno" "wkday" "wkdaynum" "year"
|
||||
)
|
||||
(list "abs" "access" "adawn" "adusk" "ampm" "args" "asc" "baseyr" "char"
|
||||
"choose" "coerce" "current" "date" "datepart" "datetime" "dawn" "day"
|
||||
"daysinmon" "defined" "dosubst" "dusk" "easterdate" "evaltrig"
|
||||
"filedate" "filedatetime" "filedir" "filename" "getenv" "hebdate"
|
||||
"hebday" "hebmon" "hebyear" "hour" "iif" "index" "isany" "isdst"
|
||||
"isleap" "isomitted" "language" "lower" "max" "min" "minsfromutc"
|
||||
"minute" "mon" "monnum" "moondate" "moondatetime" "moonphase"
|
||||
"moontime" "ndawn" "ndusk" "nonomitted" "now" "ord" "ostype" "pad" "plural"
|
||||
"psmoon" "psshade" "realcurrent" "realnow" "realtoday" "sgn" "shell"
|
||||
"shellescape" "slide" "strlen" "substr" "sunrise" "sunset" "time"
|
||||
"timepart" "today" "trig" "trigback" "trigdate" "trigdatetime"
|
||||
"trigdelta" "trigduration" "trigeventduration" "trigeventstart"
|
||||
"trigfrom" "trigger" "trigpriority" "trigrep" "trigscanfrom"
|
||||
"trigtime" "trigtimedelta" "trigtimerep" "triguntil" "trigvalid"
|
||||
"typeof" "tzconvert" "upper" "value" "version" "weekno" "wkday"
|
||||
"wkdaynum" "year")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
;;; faces
|
||||
@@ -244,12 +264,35 @@
|
||||
:group 'remind-conf
|
||||
)
|
||||
|
||||
(defconst remind-keywords-regex (regexp-opt remind-keywords 'words))
|
||||
(defconst remind-type-keywords-regex (regexp-opt remind-type-keywords 'words))
|
||||
(defconst remind-builtin-variables-regex (regexp-opt remind-builtin-variables 'words))
|
||||
(defconst remind-builtin-functions-regex (regexp-opt remind-builtin-functions 'words))
|
||||
(defconst remind-time-words-regex (regexp-opt remind-time-words 'words))
|
||||
|
||||
;; Case-insensitive matching functions
|
||||
(defun remind-keywords-matcher (limit)
|
||||
(let ((case-fold-search t))
|
||||
(re-search-forward remind-keywords-regex limit 'no-error)))
|
||||
(defun remind-type-keywords-matcher (limit)
|
||||
(let ((case-fold-search t))
|
||||
(re-search-forward remind-type-keywords-regex limit 'no-error)))
|
||||
(defun remind-builtin-variables-matcher (limit)
|
||||
(let ((case-fold-search t))
|
||||
(re-search-forward remind-builtin-variables-regex limit 'no-error)))
|
||||
(defun remind-builtin-functions-matcher (limit)
|
||||
(let ((case-fold-search t))
|
||||
(re-search-forward remind-builtin-functions-regex limit 'no-error)))
|
||||
(defun remind-time-words-matcher (limit)
|
||||
(let ((case-fold-search t))
|
||||
(re-search-forward remind-time-words-regex limit 'no-error)))
|
||||
|
||||
;; keywords
|
||||
|
||||
(defconst remind-conf-font-lock-keywords-1
|
||||
(list
|
||||
'("^[\;\#]\\s-+.*$" . remind-comment-face)
|
||||
(cons (regexp-opt remind-keywords 'words) remind-conf-keyword-face)
|
||||
'(remind-keywords-matcher . remind-conf-keyword-face)
|
||||
'("%[\"_]" . font-lock-warning-face)
|
||||
'("\\(%[a-mops-w]\\)" . remind-conf-substitutes-face)
|
||||
'("\"[^\"]*\"" . remind-string-face))
|
||||
@@ -258,15 +301,15 @@
|
||||
(defconst remind-conf-font-lock-keywords-2
|
||||
(append remind-conf-font-lock-keywords-1
|
||||
(list
|
||||
(cons (regexp-opt remind-time-words 'words) remind-time-face)
|
||||
(cons (regexp-opt remind-builtin-functions 'words) remind-conf-command-face)
|
||||
'(remind-time-words-matcher . remind-time-face)
|
||||
'(remind-builtin-functions-matcher . remind-conf-command-face)
|
||||
'("%$" . remind-conf-endline-face)))
|
||||
"Additional commands to highlight in `remind-conf-mode'.")
|
||||
|
||||
(defconst remind-conf-font-lock-keywords-3
|
||||
(append remind-conf-font-lock-keywords-2
|
||||
(list
|
||||
(cons (regexp-opt remind-type-keywords 'words) remind-conf-type-face)
|
||||
'(remind-type-keywords-matcher . remind-conf-type-face)
|
||||
'("\[[a-zA-Z]\\{3,6\\}\]" . remind-conf-color-face)
|
||||
'("\\s-+\\([12][0-9]\\|3[01]\\|0?[0-9]\\)\\s-+" . remind-conf-substitutes-face);better date regexp
|
||||
'("\\s-+\\([12][09][0-9][0-9][-/]\\(0[1-9]\\|1[0-2]\\)[-/]\\([12][0-9]\\|0[1-9]\\|3[01]\\)\\)\\s-+" . remind-time-face) ;; pseudo ISO 8601 date format.
|
||||
@@ -274,7 +317,7 @@
|
||||
'("\\s-+\\(\\(?:20\\|19\\)[0-9][0-9]\\)\\s-+" . remind-conf-substitutes-face);years
|
||||
'("\\s-+\\(2[0-4]\\|[01]?[0-9][.:][0-5][0-9]\\)\\s-+" . remind-conf-substitutes-face);24hour clock, more precise
|
||||
'("\\s-+\\([+-][+-]?[1-9][0-9]*\\)\\s-+" 1 remind-conf-delta-face prepend)
|
||||
(cons (regexp-opt remind-builtin-variables 'words) remind-conf-variable-face)))
|
||||
'(remind-builtin-variables-matcher . remind-conf-variable-face)))
|
||||
"The ultimate in highlighting experiences for `remind-conf-mode'.")
|
||||
|
||||
;;YYYY-MM-DD@hh:mm, YYYY-MM-DD@hh.mm, YYYY/MM/DD@hh:mm and YYYY/MM/DD@hh.mm
|
||||
@@ -462,12 +505,11 @@ Acts on the region or places point where it needs to be."
|
||||
;; finally the derived mode.
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode remind-conf-mode text-mode "REM"
|
||||
(define-derived-mode remind-conf-mode text-mode "Remind Conf Mode"
|
||||
"Major mode for editing remind calendar configuration files.
|
||||
|
||||
\\{remind-conf-mode-map}"
|
||||
:syntax-table remind-conf-syntax-table
|
||||
(set (make-local-variable 'font-lock-keywords-case-fold-search) t) ;this is not working atm 2009-04-13
|
||||
(set (make-local-variable 'font-lock-defaults) '(remind-conf-font-lock-keywords))
|
||||
(set (make-local-variable 'comment-start) ";")
|
||||
(set (make-local-variable 'comment-start) "#")
|
||||
|
||||
348
docs/WHATSNEW
348
docs/WHATSNEW
@@ -1,6 +1,338 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* VERSION 3.4 Patch 0 - 2022-??-??
|
||||
* VERSION 4.2 Patch 1 - 2022-12-15
|
||||
|
||||
- MINOR IMPROVEMENT: TkRemind: If "Extra Remind Options" contains -m, make
|
||||
TkRemind start the calendar with Monday instead of Sunday.
|
||||
|
||||
- MINOR IMPROVEMENT: Sample files: Add French holidays courtesy of
|
||||
Clément Bœsch.
|
||||
|
||||
- MINOR IMPROVEMENT: A few performance fixes, likely not even noticeable in
|
||||
most cases.
|
||||
|
||||
- MINOR FIXES: Fix misleading comments in the source code.
|
||||
|
||||
- MINOR FIX: Remove a bunch of dead code in the moon-phase routines.
|
||||
|
||||
- MINOR FIX: Remove unnecessary %"...%" markers in holidays/us.rem
|
||||
|
||||
- MINOR FIX: Don't use the -ffat-lto-objects if we're compiling with Clang.
|
||||
|
||||
- MINOR FIX: Remind: Fix a broken printf-format string (need to double up on %
|
||||
to get a literal % in the output.)
|
||||
|
||||
- BUG FIX: Make test suite pass regardless of the date on which it is run.
|
||||
D'oh!!!
|
||||
|
||||
- BUG FIX: Make sure the banner gets printed each time through a "*N"
|
||||
command-line option loop.
|
||||
|
||||
* 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
|
||||
variables let you translate English words to another language, and a
|
||||
mechanism for altering the substitution filter at run-time lets you
|
||||
translate its output so the results are idiomatic. See the man page
|
||||
sections "RUN-TIME SUPPORT FOR OTHER LANGUAGES", "RUN-TIME
|
||||
MODIFICATION OF THE SUBSTITUTION FILTER" and "LANGUAGE PACKS".
|
||||
|
||||
- NEW FEATURE: remind: Add the pad() built-in function
|
||||
|
||||
- NEW FEATURE: tkremind: Day numbers can be displayed left-aligned,
|
||||
centered or right-aligned.
|
||||
|
||||
- IMPROVEMENT: contrib/remind-conf-mode: The Emacs syntax-highlighter
|
||||
has been updated with the latest system variables and functions
|
||||
and has been made case-insensitive.
|
||||
|
||||
- IMPROVEMENT: remind, rem2ps: Use link-time optimization with gcc if
|
||||
possible.
|
||||
|
||||
- IMPROVEMENT: remind: Print better diagnostics when errors occur inside
|
||||
a user-defined function. We now show the stack trace to make it easier
|
||||
to figure out where the error actually is.
|
||||
|
||||
- CHANGE: Add a "q" sub-option to the "-p", "-pp", and "-ppp" options.
|
||||
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.
|
||||
|
||||
- BUG FIX: Warn if the arguments to the "-@" option are out of range.
|
||||
Problem noted by Ian! D. Allen.
|
||||
|
||||
- BUG FIX: Always interpret $Latitude and $Longitude input values in the
|
||||
"C" locale. (We do accept localized input, but warn.)
|
||||
|
||||
- BUG FIX: Fix many spelling mistakes caught by Jens Schleusener
|
||||
|
||||
* VERSION 3.4 Patch 2 - 2022-03-14
|
||||
|
||||
- NEW FEATURE: remind: Add syntactic sugar to simplify some common
|
||||
types of reminders. See "SYNTACTIC SUGAR FOR REM" in the remind
|
||||
man page. Based on suggestions from Ian! D. Allen.
|
||||
|
||||
- CHANGE: examples/defs.rem: The examples file has been updated to use
|
||||
the newer syntactic sugar.
|
||||
|
||||
- CHANGE: remind: Always parse the body of REM statements to catch
|
||||
expression errors. In the past, something like:
|
||||
|
||||
REM 2025-01-02 MSG [1/0]
|
||||
|
||||
would not cause a division-by-zero error except on 2025-01-02. Now,
|
||||
the error is always caught. NOTE POTENTIAL INCOMPATIBILITY: There may
|
||||
be edge-cases when formerly-valid remind scripts now trigger errors.
|
||||
However, this is pretty unlikely.
|
||||
|
||||
- NEW FEATURE: remind: Add the "trig" function to allow more
|
||||
expressiveness when creating triggers. See man page for details.
|
||||
|
||||
- IMPROVEMENT: tkremind: Tweak the calendar display; improve ability to
|
||||
customize colors, including supplying two built-in themes. Based on
|
||||
patch and suggestion from Paulo (last name unknown).
|
||||
|
||||
- IMPROVEMENT: tkremind: TkRemind handles errors in reminders scripts
|
||||
much more unobtrusively. Instead of popping up a modal dialog box
|
||||
with almost-unreadable error output, it discreetly notifies you of
|
||||
errors with a button that lets you view the specific error messages
|
||||
in a more readable format.
|
||||
|
||||
- IMPROVEMENT: examples/remind.vim: Update list of keywords in vim syntax
|
||||
highlighting file.
|
||||
|
||||
- IMPROVEMENT: contrib/remind-conf-mode: Update the list of keywords,
|
||||
functions and variables in the Emacs syntax-highlighting file. Also make
|
||||
it match them case-insensitively.
|
||||
|
||||
- CHANGE: remind: Increase $MaxSatIter default to 1000 instead of 150.
|
||||
Computers are much faster than when I first wrote remind and they
|
||||
can handle this higher limit easily. The higher limit also enables
|
||||
certain reasonable reminders that failed in the past because of the
|
||||
low SATISFY iteration limit.
|
||||
|
||||
- CHANGE: remind: The "||" operator now returns the value of the first
|
||||
non-zero operand rather than just returning 1 or 0. Similarly, "&&"
|
||||
returns 0 if either operand is false or the value of the last
|
||||
operand if both operands are true.
|
||||
|
||||
NOTE POTENTIAL INCOMPATIBILITY: Remind scripts that depend on ||
|
||||
and && always returning exactly one of 1 or 0 may need
|
||||
adjustment.
|
||||
|
||||
- CHANGE: The || and && operators can accept any non-STRING type as long
|
||||
as both operands have the same type. The "false" values are defined
|
||||
as follows; true values are any other value:
|
||||
|
||||
INT: 0
|
||||
TIME: 00:00
|
||||
DATE: '1990-01-01' (the Remind epoch)
|
||||
DATETIME: '1990-01-01@00:00' (the Remind epoch)
|
||||
|
||||
- IMPROVEMENT: remind: Issue diagnostics if an UNTIL or THROUGH date
|
||||
is earlier than any possible trigger date, as well as an UNTIL date
|
||||
with a fully-specified date and no repeat ("*N"). Suggestion from
|
||||
Ian! D. Allen.
|
||||
|
||||
- BUG FIX: tkremind: If the same moon phase appeared twice in a month,
|
||||
TkRemind would not display the first occurrence correctly. This has
|
||||
been fixed.
|
||||
|
||||
- BUG FIX: rem2pdf: Fix typos in the man page.
|
||||
|
||||
- BUG FIX: remind: The IF command documentation didn't reflect how it
|
||||
actually worked; now it does.
|
||||
|
||||
- BUG FIX: remind: Use correct UNTIL/THROUGH keyword in error message.
|
||||
|
||||
- BUG FIX: rem2pdf: Correct the calculation that warns about an over-full
|
||||
calendar box. Problem noted by Jonathan Kamens.
|
||||
|
||||
- BUG FIX: remind: The "remind -c" output would sometimes be incorrect if
|
||||
scripts with double-wide characters were used. This has been fixed.
|
||||
|
||||
- BUG FIX: remind: The "remind -c" output would sometimes be incorrect
|
||||
if right-to-left scripts were used in reminders. This has been fixed.
|
||||
|
||||
* VERSION 3.4 Patch 1 - 2022-02-23
|
||||
|
||||
- MINOR IMPROVEMENT: Support the INSTALL_BASE environment variable for
|
||||
installing rem2pdf in a non-standard location like your home directory.
|
||||
This is passed in to rem2pdf's Makefile at build and install time.
|
||||
|
||||
- MINOR IMPROVEMENT: ./configure: Add --disable-perl-build-artifacts flag
|
||||
to avoid installation of perllocal.pod and .packlist files.
|
||||
|
||||
- BUG FIX: tkremind: If the system date rolls over, update the display
|
||||
to correctly highlight the current date. This worked in older versions
|
||||
of Remind, but was broken by 03.04.00.
|
||||
|
||||
- BUG FIX: rem2pdf: The small calendar font would sometimes be scaled
|
||||
incorrectly so the small calendar overflowed the box. This has been
|
||||
fixed.
|
||||
|
||||
* VERSION 3.4 Patch 0 - 2022-02-10
|
||||
|
||||
- MAJOR CHANGE: Remind and its helpers (except for rem2ps) fully support
|
||||
UTF-8. If your system locale is a UTF-8 locale and your terminal
|
||||
@@ -42,6 +374,9 @@ CHANGES TO REMIND
|
||||
|
||||
- CLEANUP: remind: C source code: Remove various unused or obsolete macros.
|
||||
|
||||
- BUG FIXES: Minor fixups to groff source and Makefiles courtesy of
|
||||
Jochen Sprickerhof.
|
||||
|
||||
- BUG FIX: Properly support formatting of double-wide characters in the
|
||||
terminal mode "remind -c" calendar.
|
||||
|
||||
@@ -880,7 +1215,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
|
||||
|
||||
@@ -1027,7 +1362,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.
|
||||
@@ -1618,7 +1953,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.
|
||||
@@ -1691,7 +2026,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()."
|
||||
|
||||
@@ -1833,6 +2168,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
|
||||
@@ -16,7 +16,7 @@
|
||||
# "#PSSTUFF" for nifty PostScript examples #
|
||||
# #
|
||||
# This file is part of REMIND. #
|
||||
# Copyright (C) 1992-2018 Dianne Skoll #
|
||||
# Copyright (C) 1992-2022 Dianne Skoll #
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
@@ -25,67 +25,18 @@ RUN OFF
|
||||
################################################
|
||||
# Ensure required version of remind is used... #
|
||||
################################################
|
||||
IF version() < "03.01.10"
|
||||
IF version() < "03.04.02"
|
||||
ERRMSG This file requires at least version 03.01.10 of Remind.%
|
||||
ERRMSG This version is version [version()].
|
||||
EXIT
|
||||
ENDIF
|
||||
|
||||
######################################
|
||||
# Symbolic constants for weekdays... #
|
||||
######################################
|
||||
SET Sunday 0
|
||||
SET Monday 1
|
||||
SET Tuesday 2
|
||||
SET Wednesday 3
|
||||
SET Thursday 4
|
||||
SET Friday 5
|
||||
SET Saturday 6
|
||||
|
||||
SET Sun 0
|
||||
SET Mon 1
|
||||
SET Tue 2
|
||||
SET Wed 3
|
||||
SET Thu 4
|
||||
SET Fri 5
|
||||
SET Sat 6
|
||||
|
||||
#########################################
|
||||
# Symbolic constants for month names... #
|
||||
#########################################
|
||||
|
||||
SET Jan 1
|
||||
SET Feb 2
|
||||
SET Mar 3
|
||||
SET Apr 4
|
||||
SET May 5
|
||||
SET Jun 6
|
||||
SET Jul 7
|
||||
SET Aug 8
|
||||
SET Sep 9
|
||||
SET Oct 10
|
||||
SET Nov 11
|
||||
SET Dec 12
|
||||
|
||||
SET January 1
|
||||
SET February 2
|
||||
SET March 3
|
||||
SET April 4
|
||||
SET May 5
|
||||
SET June 6
|
||||
SET July 7
|
||||
SET August 8
|
||||
SET September 9
|
||||
SET October 10
|
||||
SET November 11
|
||||
SET December 12
|
||||
|
||||
###########################################################
|
||||
# Other symbolic constants and functions for "pasting"... #
|
||||
# Symbolic constants and functions for "pasting"... #
|
||||
###########################################################
|
||||
SET Quote CHAR(34)
|
||||
|
||||
# Handy constants/function for specifing week of month...
|
||||
# Handy constants/function for specifying week of month...
|
||||
SET Week_1 1
|
||||
SET Week_2 8
|
||||
SET Week_3 15
|
||||
@@ -119,50 +70,23 @@ REM 1 MSG John's [_mo_num(11, 1984)] 'monthly' anniversary
|
||||
# Here's a tricky problem: The 4th of July is a holiday in the U.S.
|
||||
# However, if it falls on a Saturday, the previous Friday is a holiday.
|
||||
# If it falls on a Sunday, the next Monday is a holiday. Here's how
|
||||
# to do it. NOTE that the following procedure makes the OMIT context
|
||||
# dependent upon the current date. SInce it only depends on the current
|
||||
# year, which is not likely to change while producing a calendar, we
|
||||
# are fairly safe. However, reminders with huge DELTA or BACK components
|
||||
# may not operate as expected. In general, any time you make OMIT
|
||||
# dependent upon the current date, it's tricky and results may not be
|
||||
# what you expect. You should try to make sure that the OMIT context
|
||||
# "near" any current reminders will not change during a calendar run.
|
||||
# The SCANFROM clause will make these OMITs safe.
|
||||
# to do it.
|
||||
#
|
||||
# For those reminders that update the OMIT context with ADDOMIT, we use
|
||||
# SCANFROM -7 for safety; see the man page about moveable OMITs.
|
||||
############################################################################
|
||||
|
||||
# Calculate the weekday of the holiday.
|
||||
REM 4 July SCANFROM -7 SATISFY 1
|
||||
# If it falls on a Saturday, bump to previous Friday
|
||||
REM 3 JULY SCANFROM -7 ADDOMIT SATISFY [$Tw == 5] MSG Independence day (observed)
|
||||
|
||||
SET iday $T
|
||||
IF WKDAYNUM(iday) == Sat
|
||||
REM [iday] MSG Independence day (actual)
|
||||
OMIT [iday-1] MSG Independence day (observed)
|
||||
ELSE
|
||||
IF WKDAYNUM(iday) == Sun
|
||||
REM [iday] MSG Independence day (actual)
|
||||
OMIT [iday+1] MSG Independence day (observed)
|
||||
ELSE
|
||||
OMIT [iday] MSG Independence day
|
||||
ENDIF
|
||||
ENDIF
|
||||
# If it falls on a Sunday, bump to following Monday
|
||||
REM 5 July SCANFROM -7 ADDOMIT SATISFY [$Tw == 1] MSG Independence day (observed)
|
||||
|
||||
############################################################################
|
||||
# A meeting on the first Monday of every month which is moved to the #
|
||||
# second Monday in the event of a holiday. #
|
||||
############################################################################
|
||||
# If it falls on Sat or Sun, note the actual day
|
||||
REM 4 July SCANFROM -7 ADDOMIT SATISFY [$Tw == 0 || $Tw == 6] MSG Independence day (actual)
|
||||
|
||||
# First, the normal meeting. However, the SKIP keyword means this
|
||||
# one won't be triggered if the first Monday is a holiday
|
||||
REM Mon 1 SKIP MSG Meeting
|
||||
|
||||
# Now, calculate the "potential" delayed meeting
|
||||
REM Mon 8 SATISFY 1
|
||||
|
||||
# But only actually trigger the delayed meeting if the previous
|
||||
# Monday was a holiday
|
||||
IF ISOMITTED($T-7)
|
||||
REM [$T] MSG Delayed meeting
|
||||
ENDIF
|
||||
# Otherwise observed and actual is on the 4th
|
||||
REM 4 July SCANFROM -7 ADDOMIT SATISFY [$Tw >= 1 && $Tw <= 5] MSG Independence Day
|
||||
|
||||
##########################################################################
|
||||
# #
|
||||
@@ -216,38 +140,38 @@ REM [easter+49] MSG %"Pentecost%"
|
||||
# which ones are omitted - use the general forms shown below. You'll
|
||||
# need the Week_n variables defined way up in the file.
|
||||
|
||||
OMIT Jan 1 MSG %"New Year's%" Day
|
||||
REM Mon Jan [Week_3] MSG Martin Luther King - %"MLK Day%"
|
||||
OMIT Jan 1 MSG %"New Year's Day%"
|
||||
REM Third Monday in Jan MSG Martin Luther King - %"MLK Day%"
|
||||
REM Feb 2 MSG %"Ground Hog Day%"
|
||||
REM Feb 14 MSG %"Valentine's%" Day
|
||||
REM Mon Feb [Week_3] SCANFROM -7 ADDOMIT MSG %"President's Day%"
|
||||
REM Mar 17 MSG %"St. Patrick's%" Day
|
||||
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 Sun [_last(Oct)] ++2 UNTIL 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b
|
||||
REM Sun 1 Nov ++2 FROM 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %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
|
||||
|
||||
REM Apr 1 MSG %"April Fool's%" Day
|
||||
REM Mon Tue Wed Thu Fri Sat 15 Apr MSG %"Income tax%" due
|
||||
REM May 5 MSG %"Cinco de Mayo%"
|
||||
REM Sat May [Week_1] MSG %"Kentucky Derby%"
|
||||
REM Sun May [Week_2] MSG %"Mother's Day%"
|
||||
REM Sat May [Week_3] MSG %"Armed Forces Day%"
|
||||
REM Mon [_last(May)] SCANFROM -7 ADDOMIT MSG %"Memorial Day%"
|
||||
REM First Sat in May MSG %"Kentucky Derby%"
|
||||
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 Sun Jun [Week_3] MSG %"Father's Day%"
|
||||
REM Mon Sep [Week_1] SCANFROM -7 ADDOMIT MSG %"Labor Day%"
|
||||
REM Mon Oct [Week_2] MSG %"Columbus Day%"
|
||||
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 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 Thu Nov [Week_4] SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
|
||||
REM Last Thu in Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%"
|
||||
REM Fri Nov [Week_4+1] SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%"
|
||||
OMIT Dec 24 MSG %"Christmas Eve%"
|
||||
OMIT Dec 25 MSG %"Christmas%" Day
|
||||
@@ -262,6 +186,24 @@ if $NumTrig > SaveTrig
|
||||
REM SPECIAL SHADE 220
|
||||
endif
|
||||
|
||||
############################################################################
|
||||
# A meeting on the first Monday of every month which is moved to the #
|
||||
# second Monday in the event of a holiday. #
|
||||
############################################################################
|
||||
|
||||
# First, the normal meeting. However, the SKIP keyword means this
|
||||
# one won't be triggered if the first Monday is a holiday
|
||||
REM First Monday SKIP MSG Meeting
|
||||
|
||||
# Now, calculate the "potential" delayed meeting
|
||||
REM Second Monday SATISFY 1
|
||||
|
||||
# But only actually trigger the delayed meeting if the previous
|
||||
# Monday was a holiday
|
||||
IF ISOMITTED($T-7)
|
||||
REM [$T] MSG Delayed meeting
|
||||
ENDIF
|
||||
|
||||
#PSSTUFF2
|
||||
##########################################################################
|
||||
# #
|
||||
@@ -278,10 +220,10 @@ REM PS Border Border moveto \
|
||||
([hebday($U)] [hebmon($U)]) show
|
||||
|
||||
# Fill in the phases of the moon on the PostScript calendar
|
||||
[moondate(0)] SPECIAL MOON 0
|
||||
[moondate(1)] SPECIAL MOON 1
|
||||
[moondate(2)] SPECIAL MOON 2
|
||||
[moondate(3)] SPECIAL MOON 3
|
||||
REM [moondate(0)] SPECIAL MOON 0
|
||||
REM [moondate(1)] SPECIAL MOON 1
|
||||
REM [moondate(2)] SPECIAL MOON 2
|
||||
REM [moondate(3)] SPECIAL MOON 3
|
||||
|
||||
# The following example puts sunrise and sunset times in PostScript in the
|
||||
# calendar - the sizes are hard-coded, however, and work best in landscape.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
" Vim syntax file
|
||||
" Language: Remind
|
||||
" Maintainer: Davide Alberani <alberanid@libero.it>
|
||||
" Last Change: 18 Sep 2009
|
||||
" Version: 0.5
|
||||
" URL: http://erlug.linux.it/~da/vim/syntax/remind.vim
|
||||
" Maintainer: Davide Alberani <da@erlug.linux.it>
|
||||
" Last Change: 02 Nov 2015 + 13 Mar 2022 by Dianne Skoll <dianne@skoll.ca>
|
||||
" Version: 0.7+dianne1
|
||||
" URL: http://ismito.it/vim/syntax/remind.vim
|
||||
"
|
||||
" remind is a sophisticated reminder service
|
||||
" you can download remind from:
|
||||
@@ -23,7 +23,7 @@ syn keyword remindExpiry UNTIL FROM SCANFROM SCAN WARN SCHED THROUGH
|
||||
syn keyword remindTag PRIORITY TAG
|
||||
syn keyword remindTimed AT DURATION
|
||||
syn keyword remindMove ONCE SKIP BEFORE AFTER
|
||||
syn keyword remindSpecial INCLUDE INC BANNER PUSH-OMIT-CONTEXT PUSH CLEAR-OMIT-CONTEXT CLEAR POP-OMIT-CONTEXT POP COLOR COLOUR
|
||||
syn keyword remindSpecial INCLUDE INC BANNER PUSH-OMIT-CONTEXT PUSH CLEAR-OMIT-CONTEXT CLEAR POP-OMIT-CONTEXT POP COLOR COLOUR DO
|
||||
syn keyword remindRun MSG MSF RUN CAL SATISFY SPECIAL PS PSFILE SHADE MOON
|
||||
syn keyword remindConditional IF ELSE ENDIF IFTRIG
|
||||
syn keyword remindDebug DEBUG DUMPVARS DUMP ERRMSG FLUSH PRESERVE
|
||||
|
||||
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!
|
||||
29
include/holidays/ca.rem
Normal file
29
include/holidays/ca.rem
Normal file
@@ -0,0 +1,29 @@
|
||||
# Canadian holidays
|
||||
|
||||
OMIT 1 Jan MSG New Year's Day
|
||||
|
||||
# This varies by province
|
||||
REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG Family Day
|
||||
|
||||
# This varies by province
|
||||
OMIT [easterdate($Uy) - 2] MSG Good Friday
|
||||
|
||||
# This varies by province
|
||||
OMIT [easterdate($Uy) + 1] MSG Easter Monday
|
||||
|
||||
REM Mon 18 May SCANFROM -7 ADDOMIT MSG Victoria Day
|
||||
OMIT 1 July MSG Canada Day
|
||||
|
||||
# This varies by province
|
||||
REM First Monday in Aug SCANFROM -7 ADDOMIT MSG Civic Holiday
|
||||
|
||||
REM First Monday in Sep SCANFROM -7 ADDOMIT MSG Labour Day
|
||||
|
||||
REM Second Monday in Oct SCANFROM -7 ADDOMIT MSG Thanksgiving Day
|
||||
|
||||
REM 11 November MSG Remembrance Day
|
||||
|
||||
OMIT 25 Dec MSG Christmas
|
||||
|
||||
OMIT 26 Dec MSG Boxing Day
|
||||
|
||||
20
include/holidays/fr.rem
Normal file
20
include/holidays/fr.rem
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# France Holidays
|
||||
#
|
||||
# Source: Article L3133-1
|
||||
# https://www.legifrance.gouv.fr/codes/section_lc/LEGITEXT000006072050/LEGISCTA000006178007/2016-08-10/
|
||||
#
|
||||
|
||||
SET easter EASTERDATE($Uy)
|
||||
|
||||
REM Jan 1 MSG %"Jour de l'an%"
|
||||
REM [easter+1] MSG %"Lundi de Pâques%"
|
||||
REM May 1 MSG %"Fête du Travail%"
|
||||
REM May 8 MSG %"Victoire des alliés%"
|
||||
REM [easter+39] MSG %"Jeudi de l'Ascension%"
|
||||
REM [easter+50] MSG %"Lundi de Pentecôte%"
|
||||
REM Jul 14 MSG %"Fête nationale%"
|
||||
REM Aug 15 MSG %"Assomption%"
|
||||
REM Nov 1 MSG %"La Toussaint%"
|
||||
REM Nov 11 MSG %"Armistice%"
|
||||
REM Dec 25 MSG %"Noël%"
|
||||
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
|
||||
|
||||
54
include/holidays/us.rem
Normal file
54
include/holidays/us.rem
Normal file
@@ -0,0 +1,54 @@
|
||||
# US holidays
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2022 Dianne Skoll
|
||||
|
||||
REM [easterdate($Uy)-46] MSG Ash Wednesday
|
||||
REM [easterdate($Uy)-7] MSG Palm Sunday
|
||||
OMIT [easterdate($Uy)-2] MSG Good Friday
|
||||
OMIT [easterdate($Uy)] MSG %"Easter%" Sunday
|
||||
REM [easterdate($Uy)+39] MSG Ascension Day
|
||||
REM [easterdate($Uy)+49] MSG Pentecost
|
||||
|
||||
# Some holidays are omitted, some are not. You may want to change
|
||||
# which ones are omitted.
|
||||
|
||||
OMIT Jan 1 MSG New Year's Day
|
||||
REM Third Monday in Jan MSG Martin Luther King - %"MLK Day%"
|
||||
REM Feb 2 MSG Ground Hog Day
|
||||
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
|
||||
|
||||
# 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
|
||||
REM May 5 MSG Cinco de Mayo
|
||||
REM First Sat in May MSG Kentucky Derby
|
||||
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 / 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 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
|
||||
19
include/lang/auto.rem
Normal file
19
include/lang/auto.rem
Normal file
@@ -0,0 +1,19 @@
|
||||
SET autolang getenv("LC_ALL")
|
||||
IF autolang == ""
|
||||
SET autolang getenv("LANGUAGE")
|
||||
ENDIF
|
||||
IF autolang == ""
|
||||
SET autolang getenv("LANG")
|
||||
ENDIF
|
||||
|
||||
IF autolang != ""
|
||||
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 5)) + ".rem", "r") == 0
|
||||
INCLUDE [$SysInclude]/lang/[lower(substr(autolang, 1, 5))].rem
|
||||
ELSE
|
||||
IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 2)) + ".rem", "r") == 0
|
||||
INCLUDE [$SysInclude]/lang/[lower(substr(autolang, 1, 2))].rem
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
UNSET autolang
|
||||
69
include/lang/da.rem
Normal file
69
include/lang/da.rem
Normal file
@@ -0,0 +1,69 @@
|
||||
# Support for the Danish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Mogens Lynnerup.
|
||||
|
||||
SET $Sunday "Søndag"
|
||||
SET $Monday "Mandag"
|
||||
SET $Tuesday "Tirsdag"
|
||||
SET $Wednesday "Onsdag"
|
||||
SET $Thursday "Torsdag"
|
||||
SET $Friday "Fredag"
|
||||
SET $Saturday "Lørdag"
|
||||
|
||||
SET $January "Januar"
|
||||
SET $February "Februar"
|
||||
SET $March "Marts"
|
||||
SET $April "April"
|
||||
SET $May "Maj"
|
||||
SET $June "Juni"
|
||||
SET $July "Juli"
|
||||
SET $August "August"
|
||||
SET $September "September"
|
||||
SET $October "Oktober"
|
||||
SET $November "November"
|
||||
SET $December "December"
|
||||
|
||||
SET $Today "i dag"
|
||||
SET $Tomorrow "i morgen"
|
||||
|
||||
BANNER Påmindelse for %w, %d. %m, %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
SET $Pm "pm"
|
||||
|
||||
SET $Ago "siden"
|
||||
SET $Fromnow "fra nu"
|
||||
|
||||
SET $On "på"
|
||||
|
||||
SET $Now "nu"
|
||||
SET $At "kl."
|
||||
SET $Minute "minut"
|
||||
SET $Hour "time"
|
||||
SET $Is "er"
|
||||
SET $Was "var"
|
||||
SET $And "og"
|
||||
SET $Hplu "r"
|
||||
SET $Mplu "ter"
|
||||
|
||||
FSET subst_ampm(h) iif(h<5, " om natten", h < 12, " om formiddagen", h < 18, " om eftermiddagen", " om aftenen")
|
||||
FSET subst_ordinal(d) "."
|
||||
|
||||
FSET subst_p(alt, d, t) iif(d==today()+1, "", "e")
|
||||
FSET zeropad(s, len) pad(s, "0", len)
|
||||
FSET subst_a_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) + " " + year(d)
|
||||
FSET subst_ax(alt, d, t) iif(alt, subst_a_alt(d), $On + " " + subst_a_alt(d))
|
||||
|
||||
FSET subst_bx(a, d, t) "om " + (d-today()) + " dage"
|
||||
|
||||
FSET subst_ex(alt, d, t) "den " + zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2) + $DateSep + zeropad(year(d), 4)
|
||||
FSET subst_fx(alt, d, t) "den " + zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2) + $DateSep + zeropad(year(d), 4)
|
||||
|
||||
FSET subst_g_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d)
|
||||
FSET subst_gx(alt, d, t) iif(alt, subst_g_alt(d), $On + " " + subst_g_alt(d))
|
||||
|
||||
FSET subst_hx(alt, d, t) "den " + zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2)
|
||||
FSET subst_ix(alt, d, t) "den " + zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2)
|
||||
FSET subst_ux(alt, d, t) subst_ax(alt, d, t)
|
||||
FSET subst_vx(alt, d, t) subst_gx(alt, d, t)
|
||||
89
include/lang/de.rem
Normal file
89
include/lang/de.rem
Normal file
@@ -0,0 +1,89 @@
|
||||
# Support for the German language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Wolfgang Thronicke
|
||||
|
||||
# Day names
|
||||
SET $Sunday "Sonntag"
|
||||
SET $Monday "Montag"
|
||||
SET $Tuesday "Dienstag"
|
||||
SET $Wednesday "Mittwoch"
|
||||
SET $Thursday "Donnerstag"
|
||||
SET $Friday "Freitag"
|
||||
SET $Saturday "Samstag"
|
||||
|
||||
# Month names
|
||||
SET $January "Januar"
|
||||
SET $February "Februar"
|
||||
SET $March "März"
|
||||
SET $April "April"
|
||||
SET $May "Mai"
|
||||
SET $June "Juni"
|
||||
SET $July "Juli"
|
||||
SET $August "August"
|
||||
SET $September "September"
|
||||
SET $October "Oktober"
|
||||
SET $November "November"
|
||||
SET $December "Dezember"
|
||||
|
||||
SET $Today "heute"
|
||||
SET $Tomorrow "morgen"
|
||||
|
||||
# Banner
|
||||
BANNER Termine für %w, den %d. %m %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
SET $Pm "pm"
|
||||
SET $On "am"
|
||||
SET $Hplu "n"
|
||||
SET $Mplu "n"
|
||||
SET $Now "jetzt"
|
||||
SET $At "um"
|
||||
SET $Minute "Minute"
|
||||
SET $Hour "Stunde"
|
||||
SET $Is "ist"
|
||||
SET $Was "war"
|
||||
SET $And "und"
|
||||
SET $Ago "vorher"
|
||||
SET $Fromnow "von heute"
|
||||
|
||||
FSET subst_ampm(h) iif(h<5, " nachts", h<12, " vormittags", h<=17, " nachmittags", " abends")
|
||||
FSET subst_ordinal(d) "."
|
||||
|
||||
FSET subst_a_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) + " " + year(d)
|
||||
FSET subst_ax(alt, d, t) iif(alt, subst_a_alt(d), $On + " " + subst_a_alt(d))
|
||||
|
||||
FSET subst_bx(a, d, t) "in " + (d-today()) + " Tagen"
|
||||
|
||||
FSET subst_g_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d)
|
||||
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"
|
||||
4
include/lang/en.rem
Normal file
4
include/lang/en.rem
Normal file
@@ -0,0 +1,4 @@
|
||||
# Support for the English language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# Nothing to do for English since it is the default.
|
||||
48
include/lang/es.rem
Normal file
48
include/lang/es.rem
Normal file
@@ -0,0 +1,48 @@
|
||||
# Support for the Spanish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Rafa Couto <rafacouto@biogate.com>
|
||||
|
||||
SET $Sunday "Domingo"
|
||||
SET $Monday "Lunes"
|
||||
SET $Tuesday "Martes"
|
||||
SET $Wednesday "Miércoles"
|
||||
SET $Thursday "Jueves"
|
||||
SET $Friday "Viernes"
|
||||
SET $Saturday "Sábado"
|
||||
|
||||
SET $January "Enero"
|
||||
SET $February "Febrero"
|
||||
SET $March "Marzo"
|
||||
SET $April "Abril"
|
||||
SET $May "Mayo"
|
||||
SET $June "Junio"
|
||||
SET $July "Julio"
|
||||
SET $August "Agosto"
|
||||
SET $September "Septiembre"
|
||||
SET $October "Octubre"
|
||||
SET $November "Noviembre"
|
||||
SET $December "Diciembre"
|
||||
|
||||
SET $Today "hoy"
|
||||
SET $Tomorrow "mañana"
|
||||
|
||||
BANNER Agenda para el %w, %d%s %m, %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
SET $Pm "pm"
|
||||
|
||||
SET $Ago "hace"
|
||||
SET $Fromnow "desde hoy"
|
||||
SET $On "el día"
|
||||
SET $Now "ahora"
|
||||
SET $At "a las"
|
||||
SET $Minute "minuto"
|
||||
SET $Hour "hora"
|
||||
SET $Is "es"
|
||||
SET $Was "fue"
|
||||
SET $And "y"
|
||||
SET $Hplu "s"
|
||||
SET $Mplu "s"
|
||||
|
||||
FSET subst_bx(a, d, t) "dentro de " + (d-today()) + " días"
|
||||
94
include/lang/fi.rem
Normal file
94
include/lang/fi.rem
Normal file
@@ -0,0 +1,94 @@
|
||||
# Support for the Finnish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Mikko Silvonen
|
||||
|
||||
SET $Sunday "sunnuntai"
|
||||
SET $Monday "maanantai"
|
||||
SET $Tuesday "tiistai"
|
||||
SET $Wednesday "keskiviikko"
|
||||
SET $Thursday "torstai"
|
||||
SET $Friday "perjantai"
|
||||
SET $Saturday "lauantai"
|
||||
|
||||
SET $January "tammikuu"
|
||||
SET $February "helmikuu"
|
||||
SET $March "maaliskuu"
|
||||
SET $April "huhtikuu"
|
||||
SET $May "toukokuu"
|
||||
SET $June "kesäkuu"
|
||||
SET $July "heinäkuu"
|
||||
SET $August "elokuu"
|
||||
SET $September "syyskuu"
|
||||
SET $October "lokakuu"
|
||||
SET $November "marraskuu"
|
||||
SET $December "joulukuu"
|
||||
|
||||
SET $Today "tänään"
|
||||
SET $Tomorrow "huomenna"
|
||||
|
||||
BANNER Viestit %wna %d. %mta %y%o:
|
||||
|
||||
SET $Am " ap."
|
||||
SET $Pm " ip."
|
||||
|
||||
SET $ago "sitten"
|
||||
SET $Fromnow "kuluttua"
|
||||
|
||||
SET $On "na"
|
||||
|
||||
SET $Now "nyt"
|
||||
SET $At "klo"
|
||||
SET $Minute "minuutti"
|
||||
SET $Hour "tunti"
|
||||
SET $Is "on"
|
||||
SET $Was "oli"
|
||||
SET $And "ja"
|
||||
SET $Hplu "a"
|
||||
SET $Mplu "a"
|
||||
|
||||
FSET zeropad(s, len) pad(s, "0", len)
|
||||
|
||||
FSET subst_ordinal(d) iif(d==1, ":senä", d==2, ":sena", (d%10)==2||(d%10)==3||(d%10)==6||(d%10)==8, ":ntena", ":ntenä")
|
||||
|
||||
FSET subst_a_alt(d, o, p) wkday(d) + o + " " + day(d) + ". " + mon(d) + p + " " + year(d)
|
||||
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d, "", ""), subst_a_alt(d, $On, "ta"))
|
||||
|
||||
FSET subst_bx(a, d, t) (d-today()) + " päivän kuluttua"
|
||||
FSET subst_cx(a, d, t) iif(a, wkday(d), wkday(d) + $On)
|
||||
|
||||
FSET subst_ex(a, d, t) zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2) + $DateSep + zeropad(year(d), 4)
|
||||
FSET subst_fx(a, d, t) zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2) + $DateSep + zeropad(year(d), 4)
|
||||
|
||||
FSET subst_g_alt(d, o, p) wkday(d) + o + " " + day(d) + ". " + mon(d) + p
|
||||
FSET subst_gx(a, d, t) iif(a, subst_g_alt(d, "", ""), subst_g_alt(d, $On, "ta"))
|
||||
|
||||
FSET subst_hx(a, d, t) zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2)
|
||||
FSET subst_ix(a, d, t) zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2)
|
||||
|
||||
FSET subst_j_alt(d, o) wkday(d) + o + " " + mon(d) + "n " + day(d) + subst_ordinal(day(d)) + " " + year(d)
|
||||
FSET subst_jx(a, d, t) iif(a, subst_j_alt(d, ""), subst_j_alt(d, $On))
|
||||
|
||||
FSET subst_k_alt(d, o) wkday(d) + o + " " + mon(d) + "n " + day(d) + subst_ordinal(day(d))
|
||||
FSET subst_kx(a, d, t) iif(a, subst_k_alt(d, ""), subst_k_alt(d, $On))
|
||||
|
||||
FSET subst_lx(a, d, t) zeropad(year(d), 4) + $DateSep + zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2)
|
||||
FSET subst_p(a, d, t) iif(d==today()+1, "", "ä")
|
||||
FSET subst_qx(a, d, t) "n"
|
||||
|
||||
FSET subst_u_alt(d, o, p) wkday(d) + o + " " + day(d) + subst_ordinal(day(d)) + " " + mon(d) + p + " " + year(d)
|
||||
FSET subst_ux(a, d, t) iif(a, subst_u_alt(d, "", ""), subst_u_alt(d, $On, "ta"))
|
||||
|
||||
FSET subst_v_alt(d, o, p) wkday(d) + o + " " + day(d) + subst_ordinal(day(d)) + " " + mon(d) + p
|
||||
FSET subst_vx(a, d, t) iif(a, subst_v_alt(d, "", ""), subst_v_alt(d, $On, "ta"))
|
||||
|
||||
|
||||
FSET subst_1(a, d, t) iif(t==now(), $Now, t<now(), subst1_past(now()-t), subst1_future(t-now()))
|
||||
|
||||
FSET subst1_past(mins) subst_hour_past(mins/60) + subst_min_past(mins%60) + $Ago
|
||||
FSET subst1_future(mins) subst_hour_future(mins/60) + subst_min_future(mins%60) + $Fromnow
|
||||
|
||||
FSET subst_hour_past(h) iif(h==0, "", h + " " + $Hour + iif(h==1, " ", $Hplu + " "))
|
||||
FSET subst_min_past(m) iif(m==0, "", m + " " + $Minute + iif(m==1, " ", $Mplu + " "))
|
||||
FSET subst_hour_future(h) iif(h==0, "", h + " tunnin ")
|
||||
FSET subst_min_future(m) iif(m==0, "", m + " minuutin ")
|
||||
62
include/lang/fr.rem
Normal file
62
include/lang/fr.rem
Normal file
@@ -0,0 +1,62 @@
|
||||
# Support for the French language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Laurent Duperval
|
||||
|
||||
SET $Sunday "dimanche"
|
||||
SET $Monday "lundi"
|
||||
SET $Tuesday "mardi"
|
||||
SET $Wednesday "mercredi"
|
||||
SET $Thursday "jeudi"
|
||||
SET $Friday "vendredi"
|
||||
SET $Saturday "samedi"
|
||||
|
||||
SET $January "janvier"
|
||||
SET $February "février"
|
||||
SET $March "mars"
|
||||
SET $April "avril"
|
||||
SET $May "mai"
|
||||
SET $June "juin"
|
||||
SET $July "juillet"
|
||||
SET $August "août"
|
||||
SET $September "septembre"
|
||||
SET $October "octobre"
|
||||
SET $November "novembre"
|
||||
SET $December "décembre"
|
||||
|
||||
SET $Today "aujourd'hui"
|
||||
SET $Tomorrow "demain"
|
||||
SET $On "le"
|
||||
SET $At "à"
|
||||
SET $Now "maintenant"
|
||||
SET $Minute "minute"
|
||||
SET $Hour "heure"
|
||||
SET $Is "est"
|
||||
SET $Was "était"
|
||||
SET $And "et"
|
||||
SET $Hplu "s"
|
||||
SET $Mplu "s"
|
||||
SET $Ago "il y a"
|
||||
SET $Fromnow "dans"
|
||||
|
||||
# Banner
|
||||
BANNER Rappels pour %w, %d%s %m, %y%o:
|
||||
|
||||
# Ordinal for a day (English would be "st", "nd", "rd", "th")
|
||||
FSET subst_ordinal(d) iif(d == 1, "er", "")
|
||||
|
||||
# "%d hours", "%d minutes", or "%d hours and %d minutes"
|
||||
FSET subst_tdiff(hdiff, mdiff) iif(hdiff==0&&mdiff==0, $Now, \
|
||||
hdiff==0, mdiff + plural(mdiff, " minute"), \
|
||||
mdiff==0, hdiff + plural(hdiff, " heure"), \
|
||||
hdiff + plural(hdiff, " heure") + " et " + mdiff + plural(mdiff, " minute"))
|
||||
FSET subst_1(alt, date, time) iif(time == now(), "maintenant", \
|
||||
time > now(), "dans " + subst_tdiff((time-now())/60, (time-now())%60), \
|
||||
"il y a " + subst_tdiff ((now()-time)/60, (now()-time)%60))
|
||||
|
||||
FSET subst_bx(alt, date, time) "dans " + (date-today()) + " jours"
|
||||
FSET subst_j_alt(date) wkday(date) + ", " + day(date) + subst_ordinal(day(date)) + " " + mon(date) + ", " + year(date)
|
||||
FSET subst_jx(alt, date, time) iif(alt, subst_j_alt(date), $On + " " + subst_j_alt(date))
|
||||
|
||||
FSET subst_k_alt(date) wkday(date) + ", " + day(date) + subst_ordinal(day(date)) + " " + mon(date)
|
||||
FSET subst_kx(alt, date, time) iif(alt, subst_k_alt(date), $On + " " + subst_k_alt(date))
|
||||
51
include/lang/is.rem
Normal file
51
include/lang/is.rem
Normal file
@@ -0,0 +1,51 @@
|
||||
# Support for the Icelanding language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Björn Davíðsson (bjossi@snerpa.is)
|
||||
|
||||
SET $Sunday "sunnudagur"
|
||||
SET $Monday "mánudagur"
|
||||
SET $Tuesday "þriðjudagur"
|
||||
SET $Wednesday "miðvikudagur"
|
||||
SET $Thursday "fimmtudagur"
|
||||
SET $Friday "föstudagur"
|
||||
SET $Saturday "laugardagur"
|
||||
|
||||
SET $January "janúar"
|
||||
SET $February "febrúar"
|
||||
SET $March "mars"
|
||||
SET $April "apríl"
|
||||
SET $May "maí"
|
||||
SET $June "júní"
|
||||
SET $July "júlí"
|
||||
SET $August "ágúst"
|
||||
SET $September "september"
|
||||
SET $October "október"
|
||||
SET $November "nóvember"
|
||||
SET $December "desember"
|
||||
|
||||
SET $Today "í dag"
|
||||
SET $Tomorrow "á morgun"
|
||||
|
||||
BANNER Minnisatriði: %w, %d%s %m, %y%o:
|
||||
|
||||
SET $Am "fh"
|
||||
SET $Pm "eh"
|
||||
|
||||
SET $Ago "síðan"
|
||||
SET $Fromnow "frá því nú"
|
||||
|
||||
SET $On "þann"
|
||||
|
||||
SET $Now "núna"
|
||||
SET $At "kl."
|
||||
SET $Minute "mínútu"
|
||||
SET $Hour "klukkustund"
|
||||
SET $Is "er"
|
||||
SET $Was "var"
|
||||
SET $And "og"
|
||||
SET $Hplu "ir"
|
||||
SET $Mplu "r"
|
||||
|
||||
FSET subst_bx(a, d, t) "eftir " + (d - today()) + " daga"
|
||||
fset subst_p(a, d, t) iif(d == today()+1, "", "a")
|
||||
67
include/lang/it.rem
Normal file
67
include/lang/it.rem
Normal file
@@ -0,0 +1,67 @@
|
||||
# Support for the Italian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Valerio Aimale
|
||||
|
||||
SET $Sunday "Domenica"
|
||||
SET $Monday "Lunedí"
|
||||
SET $Tuesday "Martedí"
|
||||
SET $Wednesday "Mercoledí"
|
||||
SET $Thursday "Giovedí"
|
||||
SET $Friday "Venerdí"
|
||||
SET $Saturday "Sabato"
|
||||
|
||||
SET $January "Gennaio"
|
||||
SET $February "Febbraio"
|
||||
SET $March "Marzo"
|
||||
SET $April "Aprile"
|
||||
SET $May "Maggio"
|
||||
SET $June "Giugno"
|
||||
SET $July "Luglio"
|
||||
SET $August "Agosto"
|
||||
SET $September "Settembre"
|
||||
SET $October "Ottobre"
|
||||
SET $November "Novembre"
|
||||
SET $December "Dicembre"
|
||||
|
||||
SET $Today "oggi"
|
||||
SET $Tomorrow "domani"
|
||||
|
||||
BANNER Promemoria per %w, %d %m %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
SET $Pm "pm"
|
||||
|
||||
SET $Ago "fa"
|
||||
SET $Fromnow "da oggi"
|
||||
|
||||
SET $On ""
|
||||
SET $Now "ora"
|
||||
SET $At "alle"
|
||||
SET $Minute "minuto"
|
||||
SET $Hour "ora"
|
||||
SET $Is "é"
|
||||
SET $Was "era"
|
||||
SET $And "e"
|
||||
SET $Hplu "a"
|
||||
SET $Mplu "i"
|
||||
|
||||
FSET subst_bx(a, d, t) "fra " + (d-today()) + " giorni"
|
||||
FSET subst_p(a, d, t) iif(d==today()+1, "o", "i")
|
||||
FSET subst_q(a, d, t) iif(d==today()+1, "a", "e")
|
||||
|
||||
FSET subst_ax(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d) + " " + year(d)
|
||||
FSET subst_jx(a, d, t) subst_ax(a, d, t)
|
||||
FSET subst_kx(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d)
|
||||
FSET subst_ux(a, d, t) subst_ax(a, d, t)
|
||||
FSET subst_vx(a, d, t) subst_kx(a, d, t)
|
||||
|
||||
FSET subst_1(a, d, t) iif(t==now(), $Now, t<now(), subst_1a(now()-t, $Ago), subst_1a(t-now(), $Fromnow))
|
||||
FSET subst_1a(diff, when) subst_1b(diff/60, diff%60) + " " + when
|
||||
|
||||
FSET subst_1b(hdiff, mdiff) iif(hdiff==0, subst_minutes(mdiff), mdiff==0, subst_hours(hdiff), subst_hours(hdiff) + " " + $And + " " + subst_minutes(mdiff))
|
||||
FSET subst_minutes(m) iif(m==1, "1 minuto", m + " minuti")
|
||||
FSET subst_hours(h) iif(h==1, "1 ora", h + " ore")
|
||||
|
||||
FSET subst_0(a, d, t) iif(abs(now()-t)/60==1, "a", "e")
|
||||
FSET subst_9(a, d, t) iif(abs(now()-t)%60==1, "o", "i")
|
||||
56
include/lang/nl.rem
Normal file
56
include/lang/nl.rem
Normal file
@@ -0,0 +1,56 @@
|
||||
# Support for the Dutch language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Willem Kasdorp and Erik-Jan Vens
|
||||
|
||||
SET $Sunday "zondag"
|
||||
SET $Monday "maandag"
|
||||
SET $Tuesday "dinsdag"
|
||||
SET $Wednesday "woensdag"
|
||||
SET $Thursday "donderdag"
|
||||
SET $Friday "vrijdag"
|
||||
SET $Saturday "zaterdag"
|
||||
|
||||
SET $January "januari"
|
||||
SET $February "februari"
|
||||
SET $March "maart"
|
||||
SET $April "april"
|
||||
SET $May "mei"
|
||||
SET $June "juni"
|
||||
SET $July "juli"
|
||||
SET $August "augustus"
|
||||
SET $September "september"
|
||||
SET $October "oktober"
|
||||
SET $November "november"
|
||||
SET $December "december"
|
||||
|
||||
SET $Today "vandaag"
|
||||
SET $Tomorrow "morgen"
|
||||
|
||||
BANNER Herinneringen voor %w, %d%s %m, %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
SET $Pm "pm"
|
||||
|
||||
SET $Ago "geleden"
|
||||
SET $Fromnow "vanaf nu"
|
||||
SET $On "op"
|
||||
|
||||
SET $Now "nu"
|
||||
SET $At "op"
|
||||
SET $Minute "minuut"
|
||||
SET $Hour "uur"
|
||||
SET $Is "is"
|
||||
SET $Was "was"
|
||||
SET $And "en"
|
||||
SET $Hplu "en"
|
||||
SET $Mplu "en"
|
||||
|
||||
FSET subst_1(a, d, t) iif(t==now(), $Now, t<now(), subst_1a(now()-t, $Ago), subst_1a(t-now(), $Fromnow))
|
||||
FSET subst_1a(diff, when) subst_1b(diff/60, diff%60) + " " + when
|
||||
|
||||
FSET subst_1b(hdiff, mdiff) iif(hdiff==0, subst_minutes(mdiff), mdiff==0, subst_hours(hdiff), subst_hours(hdiff) + " " + $And + " " + subst_minutes(mdiff))
|
||||
FSET subst_minutes(m) iif(m==1, "1 minuut", m + " minuten")
|
||||
FSET subst_hours(h) iif(h==1, "1 uur", h + " uren")
|
||||
|
||||
FSET subst_bx(a, d, t) "over " + (d-today()) + " dagen"
|
||||
58
include/lang/no.rem
Normal file
58
include/lang/no.rem
Normal file
@@ -0,0 +1,58 @@
|
||||
# Support for the Norwegian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Trygve Randen
|
||||
|
||||
SET $Sunday "Søndag"
|
||||
SET $Monday "Mandag"
|
||||
SET $Tuesday "Tirsdag"
|
||||
SET $Wednesday "Onsdag"
|
||||
SET $Thursday "Torsdag"
|
||||
SET $Friday "Fredag"
|
||||
SET $Saturday "Lørdag"
|
||||
|
||||
SET $January "Januar"
|
||||
SET $February "Februar"
|
||||
SET $March "Mars"
|
||||
SET $April "April"
|
||||
SET $May "Mai"
|
||||
SET $June "Juni"
|
||||
SET $July "Juli"
|
||||
SET $August "August"
|
||||
SET $September "September"
|
||||
SET $October "Oktober"
|
||||
SET $November "November"
|
||||
SET $December "Desember"
|
||||
|
||||
SET $Today "i dag"
|
||||
SET $Tomorrow "i morgen"
|
||||
|
||||
BANNER Påminnelse for %w, %d. %m, %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
SET $Pm "pm"
|
||||
|
||||
SET $Ago "siden"
|
||||
SET $Fromnow "fra nå"
|
||||
|
||||
SET $On "den"
|
||||
SET $Now "nå"
|
||||
SET $At "kl."
|
||||
SET $Minute "minutt"
|
||||
SET $Hour "time"
|
||||
SET $Is "er"
|
||||
SET $Was "var"
|
||||
SET $And "og"
|
||||
SET $Hplu "r"
|
||||
SET $Mplu "er"
|
||||
|
||||
FSET subst_bx(a, d, t) "om " + (d-today()) + " dager"
|
||||
FSET subst_ordinal(d) "."
|
||||
|
||||
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d), $On + " " + subst_a_alt(d))
|
||||
FSET subst_a_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) + " " + year(d)
|
||||
FSET subst_gx(a, d, t) iif(a, subst_g_alt(d), $On + " " + subst_g_alt(d))
|
||||
FSET subst_g_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d)
|
||||
FSET subst_ux(a, d, t) subst_ax(a, d, t)
|
||||
FSET subst_vx(a, d, t) subst_gx(a, d, t)
|
||||
FSET subst_p(a, d, t) iif(d==today()+1, "", "er")
|
||||
69
include/lang/pl.rem
Normal file
69
include/lang/pl.rem
Normal file
@@ -0,0 +1,69 @@
|
||||
# Support for the Polish language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Jerzy Sobczyk
|
||||
|
||||
SET $Sunday "Niedziela"
|
||||
SET $Monday "Poniedziałek"
|
||||
SET $Tuesday "Wtorek"
|
||||
SET $Wednesday "Środa"
|
||||
SET $Thursday "Czwartek"
|
||||
SET $Friday "Piątek"
|
||||
SET $Saturday "Sobota"
|
||||
|
||||
SET $January "Styczeń"
|
||||
SET $February "Luty"
|
||||
SET $March "Marzec"
|
||||
SET $April "Kwiecień"
|
||||
SET $May "Maj"
|
||||
SET $June "Czerwiec"
|
||||
SET $July "Lipiec"
|
||||
SET $August "Sierpień"
|
||||
SET $September "Wrzesień"
|
||||
SET $October "Październik"
|
||||
SET $November "Listopad"
|
||||
SET $December "Grudzień"
|
||||
|
||||
SET $Today "dzisiaj"
|
||||
SET $Tomorrow "jutro"
|
||||
|
||||
BANNER Terminarz na %w, %d. %m %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
SET $Pm "pm"
|
||||
|
||||
SET $Ago "temu"
|
||||
SET $Fromnow "od teraz"
|
||||
SET $On "-"
|
||||
SET $Now "teraz"
|
||||
SET $At "o"
|
||||
SET $Minute "minut"
|
||||
SET $Hour "godzin"
|
||||
SET $Is "będzie"
|
||||
SET $Was "było"
|
||||
SET $And "i"
|
||||
SET $Hplu ""
|
||||
SET $Mplu ""
|
||||
|
||||
FSET subst_pl_plu(n) iif(n==1, "ę", (n==12||n==13||n==14), "", (n%10==2||n%10==3||n%10==4), "y", "")
|
||||
FSET subst_ampm(h) iif(h<5, " w nocy", h<10, " rano", h<12, " przed południem", h<18, " po południu", h<22, " wieczorem", " w nocy")
|
||||
FSET subst_ordinal(d) ""
|
||||
|
||||
FSET subst_a_alt(d) wkday(d) + ", " + day(d) + ". " + mon(d) + " " + year(d)
|
||||
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d), $On + " " + subst_a_alt(d))
|
||||
FSET subst_bx(a, d, t) "za " + (d-today()) + " dni"
|
||||
FSET subst_g_alt(d) wkday(d) + ", " + day(d) + ". " + mon(d)
|
||||
FSET subst_gx(a, d, t) iif(a, subst_g_alt(d), $On + " " + subst_g_alt(d))
|
||||
FSET subst_ux(a, d, t) subst_ax(a, d, t)
|
||||
FSET subst_vx(a, d, t) subst_gx(a, d, t)
|
||||
FSET subst_p(a, d, t) ""
|
||||
FSET subst_0(a, d, t) subst_pl_plu(abs(t-now())/60)
|
||||
FSET subst_9(a, d, t) subst_pl_plu(abs(t-now())%60)
|
||||
|
||||
FSET subst_1(a, d, t) iif(t==now(), $Now, t<now(), subst_1past(now()-t), subst_1future(t-now()))
|
||||
|
||||
FSET subst_1future(diff) "za " + iif(diff/60==0, subst_1min(diff%60), diff%60==0, subst_1h(diff/60), subst_1h(diff/60) + " " + $And + " " + subst_1min(diff%60))
|
||||
FSET subst_1past(diff) iif(diff/60==0, subst_1min(diff%60), diff%60==0, subst_1h(diff/60), subst_1h(diff/60) + " " + $And + " " + subst_1min(diff%60)) + " temu"
|
||||
|
||||
FSET subst_1min(m) m + " " + $Minute + subst_pl_plu(m)
|
||||
FSET subst_1h(h) h + " " + $Hour + subst_pl_plu(h)
|
||||
69
include/lang/pt.rem
Normal file
69
include/lang/pt.rem
Normal file
@@ -0,0 +1,69 @@
|
||||
# Support for the (Brazilian) Portuguese language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Marco Paganini
|
||||
|
||||
SET $Sunday "domingo"
|
||||
SET $Monday "segunda"
|
||||
SET $Tuesday "terça"
|
||||
SET $Wednesday "quarta"
|
||||
SET $Thursday "quinta"
|
||||
SET $Friday "sexta"
|
||||
SET $Saturday "sábado"
|
||||
|
||||
SET $January "janeiro"
|
||||
SET $February "fevereiro"
|
||||
SET $March "março"
|
||||
SET $April "abril"
|
||||
SET $May "maio"
|
||||
SET $June "junho"
|
||||
SET $July "julho"
|
||||
SET $August "agosto"
|
||||
SET $September "setembro"
|
||||
SET $October "outubro"
|
||||
SET $November "novembro"
|
||||
SET $December "dezembro"
|
||||
|
||||
SET $Today "hoje"
|
||||
SET $Tomorrow "amanhã"
|
||||
|
||||
BANNER Avisos para %w, %d de %m de %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
SET $Pm "pm"
|
||||
|
||||
SET $Ago "atrás"
|
||||
SET $Fromnow "adiante"
|
||||
|
||||
SET $On "em"
|
||||
SET $Now "agora"
|
||||
SET $At "as"
|
||||
SET $Minute "minuto"
|
||||
SET $Hour "hora"
|
||||
SET $Is "é"
|
||||
SET $Was "foi"
|
||||
SET $And "e"
|
||||
|
||||
SET $Hplu "s"
|
||||
SET $Mplu "s"
|
||||
|
||||
FSET subst_ordinal(d) ""
|
||||
FSET subst_on_wd(d) iif(wkdaynum(d) == 1 || wkdaynum(d) == 2, "no", "na")
|
||||
|
||||
FSET subst_a_alt(d) wkday(d) + ", " + day(d) + " de " + mon(d) + " de " + year(d)
|
||||
FSET subst_bx(a, d, t) "em " + (d-today()) + " dias"
|
||||
FSET subst_c_alt(d) wkday(d)
|
||||
FSET subst_g_alt(d) wkday(d) + ", " + day(d) + " " + mon(d)
|
||||
FSET subst_ax(a, d, t) iif(a, subst_a_alt(d), subst_on_wd(d) + " " + subst_a_alt(d))
|
||||
FSET subst_cx(a, d, t) iif(a, subst_c_alt(d), subst_on_wd(d) + " " + subst_c_alt(d))
|
||||
FSET subst_gx(a, d, t) iif(a, subst_g_alt(d), subst_on_wd(d) + " " + subst_g_alt(d))
|
||||
FSET subst_jx(a, d, t) subst_ax(a, d, t)
|
||||
FSET subst_k_alt(d) wkday(d) + ", " + day(d) + " de " + mon(d)
|
||||
FSET subst_kx(a, d, t) iif(a, subst_k_alt(d), subst_on_wd(d) + " " + subst_k_alt(d))
|
||||
FSET subst_ux(a, d, t) subst_ax(a, d, t)
|
||||
FSET subst_vx(a, d, t) subst_kx(a, d, t)
|
||||
|
||||
FSET subst_1(a, d, t) iif(t==now(), $Now, t>now(), "em " + subst_1help(t-now()), subst_1help(now()-t) + " " + $Ago)
|
||||
FSET subst_1help(diff) iif(diff/60==0, subst_mplu(diff%60), diff%60==0, subst_hplu(diff/60), subst_hplu(diff/60) + " " + $And + " " + subst_mplu(diff%60))
|
||||
FSET subst_mplu(m) iif(m==1, "1 " + $Minute, m + " " + $Minute + $Mplu)
|
||||
FSET subst_hplu(h) iif(h==1, "1 " + $Hour, h + " " + $Hour + $Hplu)
|
||||
68
include/lang/ro.rem
Normal file
68
include/lang/ro.rem
Normal file
@@ -0,0 +1,68 @@
|
||||
# Support for the Romanian language.
|
||||
# This file is part of REMIND.
|
||||
# REMIND is Copyright (C) 1992-2022 by Dianne Skoll
|
||||
# This file is derived from a translation by Liviu Daia
|
||||
|
||||
SET $Sunday "Duminică"
|
||||
SET $Monday "Luni"
|
||||
SET $Tuesday "Marți"
|
||||
SET $Wednesday "Miercuri"
|
||||
SET $Thursday "Joi"
|
||||
SET $Friday "Vineri"
|
||||
SET $Saturday "Sâmbătă"
|
||||
|
||||
SET $January "Ianuarie"
|
||||
SET $February "Februarie"
|
||||
SET $March "Martie"
|
||||
SET $April "Aprilie"
|
||||
SET $May "Mai"
|
||||
SET $June "Iunie"
|
||||
SET $July "Iulie"
|
||||
SET $August "August"
|
||||
SET $September "Septembrie"
|
||||
SET $October "Octombrie"
|
||||
SET $November "Noiembrie"
|
||||
SET $December "Decembrie"
|
||||
|
||||
SET $Today "astăzi"
|
||||
SET $Tomorrow "mâine"
|
||||
|
||||
BANNER Reamintiri pentru %w, %d %m %y%o:
|
||||
|
||||
SET $Am "am"
|
||||
SET $Pm "pm"
|
||||
|
||||
SET $Ago "acum"
|
||||
SET $Fromnow "peste"
|
||||
|
||||
SET $On "pe"
|
||||
|
||||
SET $Now "acum"
|
||||
SET $At "la ora"
|
||||
SET $Minute "minut"
|
||||
SET $Hour "or"
|
||||
SET $Is "este"
|
||||
SET $Was "a fost"
|
||||
SET $Mplu "e"
|
||||
SET $Hplu "e"
|
||||
SET $And "şi"
|
||||
|
||||
FSET subst_bx(a, d, t) "peste " + (d-today()) + " zile"
|
||||
|
||||
FSET subst_ampm(h) iif(h<4, " noaptea", h<12, " dimineaţa", h<18, " după-amiaza", " seara")
|
||||
FSET subst_ordinal(d) ""
|
||||
|
||||
FSET subst_ax(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d) + " " + year(d)
|
||||
FSET subst_cx(a, d, t) wkday(d)
|
||||
FSET subst_gx(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d)
|
||||
FSET subst_jx(a, d, t) wkday(d) + ", " + mon(d) + " " + day(d) + ", " + year(d)
|
||||
FSET subst_kx(a, d, t) wkday(d) + ", " + mon(d) + " " + day(d)
|
||||
FSET subst_ux(a, d, t) subst_ax(a, d, t)
|
||||
FSET subst_vx(a, d, t) subst_gx(a, d, t)
|
||||
FSET subst_p(a, d, t) iif(d==today()+1, "", "le")
|
||||
|
||||
FSET subst_1(a, d, t) iif(t==now(), $Now, t<now(), subst_1helper(now()-t, "acum "), subst_1helper(t-now(), "peste "))
|
||||
FSET subst_1helper(diff, when) when + iif(diff%60==0, subst_1h(diff/60), diff/60==0, subst_1m(diff%60), subst_1h(diff/60) + " " + $And + " " + subst_1m(diff%60))
|
||||
FSET subst_1h(h) iif(h==1, "1 oră", h + " ore")
|
||||
FSET subst_1m(m) iif(m==1, "1 minut", m + " minute")
|
||||
FSET subst_0(a, d, t) iif(abs(t-now())/60==1, "ă", "e")
|
||||
2
include/site/README
Normal file
2
include/site/README
Normal file
@@ -0,0 +1,2 @@
|
||||
This directory is for system administrators to install site-wide
|
||||
Remind scripts that are useful to their user-base.
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH REM 1 "1 January 2021"
|
||||
.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 "5 January 2021"
|
||||
.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.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
.TH TKREMIND 1 "15 January 2021"
|
||||
.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
|
||||
@@ -173,6 +179,13 @@ it will be underlined when you move the cursor over it, and
|
||||
you can edit it in a text editor by either left- or right-clicking
|
||||
on the reminder.
|
||||
|
||||
.SH ERRORS
|
||||
|
||||
If there are any errors in your reminder file, the "Queue..." button
|
||||
changes to "Errors...". Click on "Errors..." to see the Remind error
|
||||
output. Click "OK" to close the error window; this makes the button
|
||||
in the main TkRemind window to revert to "Queue..."
|
||||
|
||||
.SH BACKGROUND REMINDERS
|
||||
|
||||
If you create "timed" reminders, \fBTkRemind\fR will queue them in
|
||||
@@ -267,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
|
||||
@@ -286,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,
|
||||
@@ -316,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
|
||||
@@ -327,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
|
||||
@@ -393,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;
|
||||
|
||||
@@ -68,7 +68,7 @@ and newmoon.png, which are expected to live in C<--imgbase>.
|
||||
=item --stylesheet I<url.css>
|
||||
|
||||
Use I<url.css> as the stylesheet. If this option is used,
|
||||
I<url.css> is interpreted relative to B<imgbase> I<unless> it start
|
||||
I<url.css> is interpreted relative to B<imgbase> I<unless> it starts
|
||||
with a "/".
|
||||
|
||||
=item --nostyle
|
||||
@@ -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>},
|
||||
|
||||
@@ -29,12 +29,20 @@ install:
|
||||
if test $$? != 0 ; then echo "Not installing rem2pdf; missing $$m"; exit 0; fi; \
|
||||
done; \
|
||||
echo "Installing rem2pdf"; \
|
||||
if test "$(prefix)" = "/usr" ; then \
|
||||
if test "$(INSTALL_BASE)" != "" ; then \
|
||||
$(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 || 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
|
||||
|
||||
@@ -478,14 +479,14 @@ positioned absolutely with respect to the day's box (and is not
|
||||
counted when calculating the box's height.)
|
||||
|
||||
A positive I<x> value positions the left edge of the text I<x> points
|
||||
to the right of the left side of the calender box, while a negative
|
||||
to the right of the left side of the calendar box, while a negative
|
||||
I<x> value positions the right edge of the text I<x> points to the left
|
||||
of the right side of the calender box.
|
||||
of the right side of the calendar box.
|
||||
|
||||
A positive I<y> value positions the top edge of the text I<y> points
|
||||
below the top of the calender box, while a negative I<y> value
|
||||
below the top of the calendar box, while a negative I<y> value
|
||||
positions the bottom edge of the text I<y> points above the bottom of
|
||||
the calender box.
|
||||
the calendar box.
|
||||
|
||||
If you use absolutely-positioned text, it's up to you to make sure it
|
||||
doesn't overlap other text; B<rem2pdf> takes no special precautions to
|
||||
@@ -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
|
||||
@@ -637,7 +639,7 @@ sub draw_day
|
||||
$so_far += $h2;
|
||||
}
|
||||
if ($height) {
|
||||
if ($entry_height > $height) {
|
||||
if ($h + $entry_height + 2 * $settings->{border_size} > $height) {
|
||||
print STDERR "WARNING: overfull box at $day " . $self->{monthname} . ' ' . $self->{year} . "\n";
|
||||
$entry_height = $height;
|
||||
}
|
||||
@@ -753,24 +755,13 @@ sub draw_small_calendar
|
||||
$last_day_on_row += 7;
|
||||
$rows++;
|
||||
}
|
||||
my $layout = Pango::Cairo::create_layout($cr);
|
||||
my $desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . '10px');
|
||||
$layout->set_font_description($desc);
|
||||
$layout->set_text('88 88 88 88 88 88 88');
|
||||
my ($wid, $h) = $layout->get_pixel_size();
|
||||
$h += 1;
|
||||
$h *= ($rows + 2); # row for month name; row for day names
|
||||
my $font_size = $self->calculate_small_calendar_font_size($cr, $width, $height, $settings, $rows);
|
||||
|
||||
my $scale = $width / $wid;
|
||||
if (($height / $h) < $scale) {
|
||||
$scale = $height / $h;
|
||||
}
|
||||
my $font_size = int($scale * 10);
|
||||
$layout = Pango::Cairo::create_layout($cr);
|
||||
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
|
||||
my $layout = Pango::Cairo::create_layout($cr);
|
||||
my $desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
|
||||
$layout->set_font_description($desc);
|
||||
$layout->set_text('88 ');
|
||||
($wid, $h) = $layout->get_pixel_size();
|
||||
my ($wid, $h) = $layout->get_pixel_size();
|
||||
$h += 1;
|
||||
|
||||
# Month name
|
||||
@@ -824,6 +815,43 @@ sub draw_small_calendar
|
||||
}
|
||||
}
|
||||
|
||||
sub calculate_small_calendar_font_size
|
||||
{
|
||||
my ($self, $cr, $width, $height, $settings, $rows) = @_;
|
||||
|
||||
my $layout = Pango::Cairo::create_layout($cr);
|
||||
my $desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . '10px');
|
||||
$layout->set_font_description($desc);
|
||||
$layout->set_text('88 88 88 88 88 88 88');
|
||||
my ($wid, $h) = $layout->get_pixel_size();
|
||||
$h += 1;
|
||||
$h *= ($rows + 2); # row for month name; row for day names
|
||||
|
||||
my $scale = $width / $wid;
|
||||
if (($height / $h) < $scale) {
|
||||
$scale = $height / $h;
|
||||
}
|
||||
my $font_size = int($scale * 10);
|
||||
|
||||
# Check
|
||||
$desc = Pango::FontDescription->from_string($settings->{small_cal_font} . ' ' . $font_size . 'px');
|
||||
$layout->set_font_description($desc);
|
||||
$layout->set_text('88 88 88 88 88 88 88');
|
||||
($wid, $h) = $layout->get_pixel_size();
|
||||
$h += 1;
|
||||
$h *= ($rows + 2); # row for month name; row for day names
|
||||
|
||||
$scale = $width / $wid;
|
||||
if (($height / $h) < $scale) {
|
||||
$scale = $height / $h;
|
||||
}
|
||||
|
||||
if ($scale < 1) { # Font size is too big
|
||||
$font_size--;
|
||||
}
|
||||
return $font_size;
|
||||
}
|
||||
|
||||
package Remind::PDF::Multi;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
@@ -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;
|
||||
|
||||
434
scripts/tkremind
434
scripts/tkremind
@@ -7,7 +7,7 @@
|
||||
# A cheesy graphical front/back end for Remind using Tcl/Tk
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-2021 Dianne Skoll
|
||||
# Copyright (C) 1992-2022 Dianne Skoll
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -103,6 +103,9 @@ set OptDescr(RunCmd) "(String) If non-blank, run specified command when a pop-up
|
||||
set Option(FeedReminder) 0
|
||||
set OptDescr(FeedReminder) "(0/1) If 1, feed the reminder to RunCmd on standard input (see RunCmd option)"
|
||||
|
||||
set Option(DayAnchor) "center"
|
||||
set OptDescr(DayAnchor) "(w/center/e) Anchor the day number to the left (w), center or right (e) of its container"
|
||||
|
||||
set Option(Editor) "emacs +%d %s"
|
||||
set OptDescr(Editor) "(String) Specify command to edit a file. %d is replaced with line number and %s with filename"
|
||||
|
||||
@@ -127,6 +130,12 @@ set OptDescr(BackgroundColor) "Default background color of calendar boxes"
|
||||
set Option(TextColor) "#000000"
|
||||
set OptDescr(TextColor) "Default text color in calendar boxes"
|
||||
|
||||
set Option(TodayColor) "#00C0C0"
|
||||
set OptDescr(TodayColor) "Background color for today heading"
|
||||
|
||||
set Option(LineColor) "#000000"
|
||||
set OptDescr(LineColor) "Color of gridlines on calendar"
|
||||
|
||||
set Option(LabelColor) "#000000"
|
||||
set OptDescr(LabelColor) "Default label color for headings"
|
||||
|
||||
@@ -165,6 +174,9 @@ set EditorPid -1
|
||||
# Inotify file
|
||||
set InotifyFP ""
|
||||
|
||||
# Errors from last remind run
|
||||
set RemindErrors ""
|
||||
|
||||
# Reminder file to append to -- default
|
||||
set AppendFile {NOSUCHFILE}
|
||||
catch {set AppendFile $ReminderFile}
|
||||
@@ -282,7 +294,17 @@ proc is_warning_header { line } {
|
||||
proc Initialize {} {
|
||||
global DayNames argc argv CommandLine ReminderFile AppendFile Remind PSCmd
|
||||
global MondayFirst TwentyFourHourMode ReminderFileModTime
|
||||
global TodayDay TodayMonth TodayYear
|
||||
|
||||
global Option ConfigFile
|
||||
|
||||
# In case date has rolled over, recalculate Today* values
|
||||
set now [clock seconds]
|
||||
|
||||
set TodayMonth [expr [string trim [clock format $now -format %N]] - 1]
|
||||
set TodayYear [clock format $now -format %Y]
|
||||
set TodayDay [string trim [clock format $now -format %e]]
|
||||
|
||||
set CommandLine "|$Remind -itkremind=1 -pp -y -l EXTRA"
|
||||
set PSCmd "$Remind -itkremind=1 -itkprint=1 -pp -l EXTRA"
|
||||
set i 0
|
||||
@@ -435,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} {
|
||||
@@ -448,8 +471,7 @@ proc CreateCalFrame { w dayNames } {
|
||||
set h 5
|
||||
}
|
||||
|
||||
global MondayFirst
|
||||
frame $w -background $Option(WinBackground)
|
||||
frame $w -background $Option(LineColor)
|
||||
for {set i 0} {$i < 7} {incr i} {
|
||||
if {$MondayFirst} {
|
||||
set index [expr ($i+1)%7]
|
||||
@@ -457,28 +479,31 @@ proc CreateCalFrame { w dayNames } {
|
||||
set index $i
|
||||
}
|
||||
|
||||
label $w.day$i -border 1 -text [lindex $dayNames $index] -justify center -font HeadingFont -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
grid configure $w.day$i -row 0 -column $i -sticky ew
|
||||
label $w.day$i -bd 0 -text [lindex $dayNames $index] -justify center -font HeadingFont -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
|
||||
grid configure $w.day$i -row 0 -column $i -sticky ew -padx 1 -pady 1
|
||||
}
|
||||
for {set i 0} {$i < 6} {incr i} {
|
||||
set n [expr $i*7]
|
||||
for {set j 0} {$j < 7} {incr j} {
|
||||
set f [expr $n+$j]
|
||||
button $w.l$f -text "" -justify center -command "" \
|
||||
-state disabled -relief flat -border 0 -padx 0 -pady 0 -font HeadingFont
|
||||
text $w.t$f -width 12 -height $h -border 1 -spacing3 3 -wrap word -relief flat \
|
||||
-state disabled -takefocus 0 -cursor {} -font CalboxFont -foreground $Option(TextColor) -background $Option(BackgroundColor)
|
||||
button $w.l$f -text "" -justify center -command "" -anchor $Option(DayAnchor) \
|
||||
-state disabled -relief flat -bd 0 -padx 0 -pady 0 -font HeadingFont -highlightthickness 1
|
||||
text $w.t$f -width 12 -height $h -bd 0 -spacing3 3 -wrap word -relief flat \
|
||||
-state disabled -takefocus 0 -cursor {} -font CalboxFont -foreground $Option(TextColor) -background $Option(BackgroundColor) \
|
||||
-highlightthickness 0
|
||||
frame $w.f$f -padx 0 -pady 0 -highlightthickness 0 -relief flat -bd 0
|
||||
$w.t$f tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$f"
|
||||
$w.t$f tag bind REM <ButtonPress-3> "FireEditor $w.t$f"
|
||||
grid configure $w.l$f -row [expr $i*2+1] -column $j -sticky ew
|
||||
grid configure $w.t$f -row [expr $i*2+2] -column $j -sticky nsew
|
||||
pack $w.l$f -in $w.f$f -side top -expand 0 -fill x
|
||||
pack $w.t$f -in $w.f$f -side top -expand 1 -fill both
|
||||
grid configure $w.f$f -row [expr $i+1] -column $j -sticky nsew -padx 1 -pady 1
|
||||
}
|
||||
}
|
||||
|
||||
for {set i 0} {$i < 7} {incr i} {
|
||||
grid columnconfigure $w $i -weight 1
|
||||
}
|
||||
for {set i 2} {$i < 14} {incr i 2} {
|
||||
for {set i 1} {$i < 7} {incr i} {
|
||||
grid rowconfigure $w $i -weight 1
|
||||
}
|
||||
}
|
||||
@@ -504,8 +529,12 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
set last [expr $offset+$numDays]
|
||||
|
||||
for {set i 0} {$i < $first} {incr i} {
|
||||
grid $w.l$i $w.t$i
|
||||
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
grid $w.f$i
|
||||
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
|
||||
raise $w.t$i
|
||||
$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
|
||||
balloon_add_help $w.l$i ""
|
||||
$w.t$i configure -relief flat -takefocus 0 -state normal -background $Option(WinBackground)
|
||||
@@ -515,13 +544,19 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
}
|
||||
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
|
||||
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
|
||||
$w.t$i configure -state disabled
|
||||
$w.t$i configure -state disabled -takefocus 0
|
||||
}
|
||||
for {set i $first} {$i <= $last} {incr i} {
|
||||
grid $w.l$i $w.t$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
|
||||
raise $w.t$i
|
||||
set d [expr $i-$first+1]
|
||||
$w.l$i configure -text $d -state normal -relief flat \
|
||||
-command "ModifyDay $d $firstDay" -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
-command "ModifyDay $d $firstDay" -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
balloon_add_help $w.l$i "Add a reminder..."
|
||||
$w.t$i configure -relief sunken -takefocus 1 -state normal -foreground $Option(TextColor) -background $Option(BackgroundColor)
|
||||
$w.t$i delete 1.0 end
|
||||
@@ -530,23 +565,27 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
}
|
||||
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
|
||||
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
|
||||
$w.t$i configure -state disabled
|
||||
$w.t$i configure -state disabled -takefocus 0
|
||||
}
|
||||
set forgetIt 0
|
||||
for {set i [expr $last+1]} {$i < 42} {incr i} {
|
||||
if {$i%7 == 0} {
|
||||
set forgetIt 1
|
||||
}
|
||||
set row [expr ($i/7)*2+1]
|
||||
set row [expr ($i/7)+1]
|
||||
if {$forgetIt} {
|
||||
grid remove $w.l$i $w.t$i
|
||||
grid remove $w.f$i
|
||||
grid rowconfigure $w $row -weight 0
|
||||
grid rowconfigure $w [expr $row+1] -weight 0
|
||||
} else {
|
||||
grid $w.l$i $w.t$i
|
||||
grid rowconfigure $w [expr $row+1] -weight 1
|
||||
grid $w.f$i
|
||||
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
|
||||
raise $w.t$i
|
||||
grid rowconfigure $w $row -weight 1
|
||||
}
|
||||
$w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
$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
|
||||
balloon_add_help $w.l$i ""
|
||||
$w.t$i configure -relief flat -takefocus 0 -state normal -background $Option(WinBackground)
|
||||
@@ -556,11 +595,11 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
}
|
||||
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
|
||||
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
|
||||
$w.t$i configure -state disabled
|
||||
$w.t$i configure -state disabled -takefocus 0
|
||||
}
|
||||
if { $CurMonth == $TodayMonth && $CurYear == $TodayYear } {
|
||||
set n [expr $TodayDay + $offset]
|
||||
$w.l$n configure -background "#00c0c0"
|
||||
$w.l$n configure -background $Option(TodayColor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,36 +616,36 @@ proc DoQueue {} {
|
||||
#---------------------------------------------------------------------------
|
||||
proc CreateCalWindow { dayNames } {
|
||||
global Option
|
||||
frame .h -background $Option(WinBackground);
|
||||
label .h.title -text "" -justify center -pady 1 -border 1 -relief raised -font HeadingFont -background $Option(WinBackground) -foreground $Option(LabelColor)
|
||||
pack .h.title -side top -fill x
|
||||
frame .h -background $Option(LineColor)
|
||||
label .h.title -text "" -justify center -pady 2 -bd 0 -relief flat -font HeadingFont -background $Option(WinBackground) -foreground $Option(LabelColor)
|
||||
pack .h.title -side top -fill x -pady 1 -padx 1
|
||||
pack .h -side top -expand 0 -fill x
|
||||
|
||||
. configure -background $Option(LineColor)
|
||||
CreateCalFrame .cal $dayNames
|
||||
|
||||
frame .b -background $Option(WinBackground);
|
||||
button .b.prev -text "\u2b9c" -command {MoveMonth -1} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
frame .b -background $Option(LineColor)
|
||||
button .b.prev -text "\u2b9c" -command {MoveMonth -1} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
balloon_add_help .b.prev "Go to previous month"
|
||||
button .b.this -text {Today} -command {ThisMonth} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
button .b.this -text {Today} -command {ThisMonth} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
balloon_add_help .b.this "Go to this month"
|
||||
button .b.next -text "\u2b9e" -command {MoveMonth 1} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
button .b.next -text "\u2b9e" -command {MoveMonth 1} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
balloon_add_help .b.next "Go to next month"
|
||||
button .b.goto -text {Go To Date...} -command {GotoDialog} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
button .b.goto -text {Go To Date...} -command {GotoDialog} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
balloon_add_help .b.goto "Go to a specific date"
|
||||
button .b.print -text {Print...} -command {DoPrint} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
balloon_add_help .b.print "Print a PostScript calendar"
|
||||
button .b.queue -text {Queue...} -command {DoQueue} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
balloon_add_help .b.queue "See the queue of pending reminders (debugging purposes only)"
|
||||
button .b.quit -text {Quit} -command {Quit} -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
balloon_add_help .b.quit "Quit TkRemind"
|
||||
button .b.options -text {Options...} -command EditOptions -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
button .b.print -text {Print...} -command {DoPrint} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
balloon_add_help .b.print "Print a PostScript or PDF calendar"
|
||||
button .b.options -text {Options...} -command EditOptions -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
balloon_add_help .b.options "Set TkRemind options"
|
||||
label .b.status -text "" -width 25 -relief sunken -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
label .b.nqueued -text "" -width 20 -relief sunken -border 1 -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
pack .b.prev .b.this .b.next .b.goto .b.print .b.options .b.queue .b.quit -side left -fill both
|
||||
pack .b.status -side left -fill both -expand 1
|
||||
pack .b.nqueued -side left -fill both
|
||||
pack .b -side bottom -fill x -expand 0
|
||||
button .b.queue -text {Queue...} -command {DoQueue} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
balloon_add_help .b.queue "See the queue of pending reminders (debugging purposes only)"
|
||||
button .b.quit -text {Quit} -command {Quit} -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 1 -highlightcolor $Option(LineColor) -highlightbackground $Option(WinBackground)
|
||||
balloon_add_help .b.quit "Quit TkRemind"
|
||||
label .b.status -text "" -width 25 -relief flat -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
|
||||
label .b.nqueued -text "" -width 20 -relief flat -bd 0 -foreground $Option(LabelColor) -background $Option(WinBackground) -highlightthickness 0
|
||||
pack .b.prev .b.this .b.next .b.goto .b.print .b.options .b.queue .b.quit -side left -fill both -padx 1
|
||||
pack .b.status -side left -fill both -expand 1 -padx 1
|
||||
pack .b.nqueued -side left -fill both -padx 1
|
||||
pack .b -side bottom -fill x -expand 0 -pady 1
|
||||
pack .cal -side top -fill both -expand 1
|
||||
wm title . "TkRemind"
|
||||
wm iconname . ""
|
||||
@@ -689,7 +728,7 @@ proc EditOptions {} {
|
||||
pack $w.cmd -in $w.rf -side left -expand 1 -fill x
|
||||
$w.cmd insert 0 $tmpOpt(RunCmd)
|
||||
|
||||
frame $w.sep3 -border 1 -relief sunken
|
||||
frame $w.sep3 -bd 1 -relief sunken
|
||||
# E-mail reminder if popup not dismissed
|
||||
frame $w.eml
|
||||
label $w.lab_email_address -text "E-mail reminders here if popup not dismissed:" -anchor w -justify left
|
||||
@@ -734,6 +773,12 @@ proc EditOptions {} {
|
||||
label $w.bgcolor -text " Background color:"
|
||||
button $w.bbgcolor -background $Option(BackgroundColor) -command [list PickColor BackgroundColor $w.bbgcolor] -text ...
|
||||
|
||||
label $w.tbgcolor -text "Color for highlighting \"today\":"
|
||||
button $w.tbbgcolor -background $Option(TodayColor) -command [list PickColor TodayColor $w.tbbgcolor] -text ...
|
||||
|
||||
label $w.gridcolor -text " Gridline color:"
|
||||
button $w.gridbcolor -background $Option(LineColor) -command [list PickColor LineColor $w.gridbcolor] -text ...
|
||||
|
||||
grid $w.textcolor $w.btextcolor $w.bgcolor $w.bbgcolor -in $w.colors1
|
||||
grid $w.bgcolor $w.bbgcolor -in $w.colors1
|
||||
|
||||
@@ -742,22 +787,37 @@ proc EditOptions {} {
|
||||
label $w.wincolor -text " Window color:"
|
||||
button $w.bwincolor -background $Option(WinBackground) -command [list PickColor WinBackground $w.bwincolor] -text ...
|
||||
grid $w.headcolor $w.bheadcolor $w.wincolor $w.bwincolor -in $w.colors1
|
||||
|
||||
grid $w.tbgcolor $w.tbbgcolor $w.gridcolor $w.gridbcolor -in $w.colors1
|
||||
|
||||
grid columnconfigure $w.colors1 0 -weight 1
|
||||
grid columnconfigure $w.colors1 2 -weight 1
|
||||
frame $w.sep1 -border 1 -relief sunken
|
||||
frame $w.sep2 -border 1 -relief sunken
|
||||
frame $w.sep1 -bd 1 -relief sunken
|
||||
frame $w.sep2 -bd 1 -relief sunken
|
||||
|
||||
checkbutton $w.feed \
|
||||
-text "Feed popped-up reminder to command's standard input" \
|
||||
-variable tmpOpt(FeedReminder) -anchor w -justify left
|
||||
|
||||
frame $w.ancFrame
|
||||
label $w.ancLabel -text "Anchor day numbers to:"
|
||||
radiobutton $w.ancLeft \
|
||||
-text "Left" \
|
||||
-variable tmpOpt(DayAnchor) -value "w" -anchor w -justify left
|
||||
radiobutton $w.ancCenter \
|
||||
-text "Center" \
|
||||
-variable tmpOpt(DayAnchor) -value "center" -anchor w -justify left
|
||||
radiobutton $w.ancRight \
|
||||
-text "Right" \
|
||||
-variable tmpOpt(DayAnchor) -value "e" -anchor w -justify left
|
||||
pack $w.ancLabel $w.ancLeft $w.ancCenter $w.ancRight -in $w.ancFrame -side left
|
||||
|
||||
pack $w.startIconified -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.showTodays -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.confirmQuit -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.bringDown -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.ring -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.deic -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.ancFrame -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.sep1 -in $w.f -side top -expand 0 -fill x -ipady 1
|
||||
pack $w.rf -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.feed -in $w.f -side top -expand 0 -fill x
|
||||
@@ -770,10 +830,12 @@ proc EditOptions {} {
|
||||
pack $w.colors1 -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.sep2 -in $w.f -side top -expand 0 -fill x -ipady 1
|
||||
|
||||
button $w.default -text "Light Theme" -command [list set_default_colors $w]
|
||||
button $w.dark -text "Dark Theme" -command [list set_dark_colors $w]
|
||||
button $w.save -text "Save Options" -command "SaveOptions $w; destroy $w"
|
||||
button $w.cancel -text "Cancel" -command "CancelOptions; destroy $w"
|
||||
wm protocol $w WM_DELETE_WINDOW "CancelOptions; destroy $w"
|
||||
pack $w.save $w.cancel -in $w.b -side left -expand 0 -fill x
|
||||
pack $w.default $w.dark $w.save $w.cancel -in $w.b -side left -expand 0 -fill x
|
||||
CenterWindow $w .
|
||||
}
|
||||
|
||||
@@ -834,6 +896,13 @@ proc SaveOptions { w } {
|
||||
for {set i 0} {$i < 7} {incr i} {
|
||||
.cal.day$i configure -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
}
|
||||
for {set i 0} {$i < 6} {incr i} {
|
||||
set n [expr $i*7]
|
||||
for {set j 0} {$j < 7} {incr j} {
|
||||
set f [expr $n+$j]
|
||||
.cal.l$f configure -anchor $Option(DayAnchor);
|
||||
}
|
||||
}
|
||||
.b.status configure -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
.b.nqueued configure -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
.b configure -background $Option(WinBackground)
|
||||
@@ -845,6 +914,10 @@ proc SaveOptions { w } {
|
||||
.b.queue configure -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
.b.quit configure -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
.b.options configure -foreground $Option(LabelColor) -background $Option(WinBackground)
|
||||
. configure -background $Option(LineColor);
|
||||
.h configure -background $Option(LineColor);
|
||||
.cal configure -background $Option(LineColor)
|
||||
.b configure -background $Option(LineColor)
|
||||
}
|
||||
|
||||
proc WriteOptionsToFile {} {
|
||||
@@ -882,6 +955,7 @@ proc WriteOptionsToFile {} {
|
||||
#***********************************************************************
|
||||
proc LoadOptions {} {
|
||||
global Option ConfigFile
|
||||
global MondayFirst
|
||||
set problem [catch {set f [open "$ConfigFile" "r"]}]
|
||||
if {$problem} {
|
||||
return
|
||||
@@ -901,6 +975,9 @@ proc LoadOptions {} {
|
||||
set Option($key) $val
|
||||
}
|
||||
close $f
|
||||
if {[regexp -- {-m.*} $Option(ExtraRemindArgs)]} {
|
||||
set MondayFirst 1
|
||||
}
|
||||
font configure CalboxFont {*}$Option(CalboxFont)
|
||||
font configure HeadingFont {*}$Option(HeadingFont)
|
||||
}
|
||||
@@ -939,11 +1016,12 @@ proc ConfigureCalWindow { month year firstDay numDays } {
|
||||
proc FillCalWindow {} {
|
||||
set FileName ""
|
||||
set LineNo 0
|
||||
global DayNames CurYear CurMonth MonthNames CommandLine Option TagToObj
|
||||
global DayNames CurYear CurMonth MonthNames CommandLine Option TagToObj RemindErrors MondayFirst
|
||||
|
||||
array unset TagToObj
|
||||
|
||||
Status "Firing off Remind..."
|
||||
set_button_to_queue
|
||||
set month [lindex $MonthNames $CurMonth]
|
||||
|
||||
set cmd [regsub EXTRA $CommandLine $Option(ExtraRemindArgs)]
|
||||
@@ -977,7 +1055,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]
|
||||
|
||||
@@ -1012,8 +1095,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]
|
||||
@@ -1032,35 +1120,36 @@ proc FillCalWindow {} {
|
||||
continue
|
||||
}
|
||||
"MOON" {
|
||||
DoMoonSpecial $n $stuff $fntag
|
||||
DoMoonSpecial $n $stuff $fntag $day
|
||||
continue
|
||||
}
|
||||
"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
|
||||
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"} {
|
||||
@@ -1083,16 +1172,27 @@ proc FillCalWindow {} {
|
||||
}
|
||||
}
|
||||
.cal.t$n insert end "\n"
|
||||
.cal.t$n configure -state disabled
|
||||
.cal.t$n configure -state disabled -takefocus 0
|
||||
|
||||
}
|
||||
set problem [catch { close $file } errmsg]
|
||||
if {$problem} {
|
||||
tk_dialog .error Error "There was a problem running Remind: $errmsg" error 0 OK
|
||||
set RemindErrors [unique_lines $errmsg]
|
||||
set_button_to_errors
|
||||
}
|
||||
DisplayTime
|
||||
}
|
||||
|
||||
proc unique_lines { s } {
|
||||
set l [split $s "\n"]
|
||||
foreach line $l {
|
||||
if {"$line" != ""} {
|
||||
dict set d $line 1
|
||||
}
|
||||
}
|
||||
return [join [dict keys $d] "\n"]
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# MoveMonth -- move by +1 or -1 months
|
||||
# Arguments:
|
||||
@@ -1152,13 +1252,13 @@ proc DoPrint {} {
|
||||
toplevel .p
|
||||
wm title .p "TkRemind Print..."
|
||||
wm iconname .p "Print..."
|
||||
frame .p.f1 -relief sunken -border 2
|
||||
frame .p.f1 -relief sunken -bd 2
|
||||
frame .p.f11
|
||||
frame .p.f12
|
||||
frame .p.f2 -relief sunken -border 2
|
||||
frame .p.f2a -relief sunken -border 2
|
||||
frame .p.f3 -relief sunken -border 2
|
||||
frame .p.f3a -relief sunken -border 2
|
||||
frame .p.f2 -relief sunken -bd 2
|
||||
frame .p.f2a -relief sunken -bd 2
|
||||
frame .p.f3 -relief sunken -bd 2
|
||||
frame .p.f3a -relief sunken -bd 2
|
||||
frame .p.f4
|
||||
|
||||
radiobutton .p.tofile -text "To file: " -variable Option(PrintDest) -value file
|
||||
@@ -1169,7 +1269,7 @@ proc DoPrint {} {
|
||||
.p.command insert end "lpr"
|
||||
|
||||
if { $HaveRem2PDF } {
|
||||
frame .p.ff -relief sunken -border 2
|
||||
frame .p.ff -relief sunken -bd 2
|
||||
label .p.format -text "Output Format:"
|
||||
radiobutton .p.pdf -text "PDF" -variable Option(PrintFormat) -value pdf
|
||||
radiobutton .p.ps -text "PostScript" -variable Option(PrintFormat) -value ps
|
||||
@@ -1451,16 +1551,16 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
set month [lindex $MonthNames $CurMonth]
|
||||
set wkday [lindex $EnglishDayNames [expr ($day+$firstDay-1) % 7]]
|
||||
|
||||
frame $w.o -border 4 -relief ridge
|
||||
frame $w.o1 -border 4
|
||||
frame $w.o2 -border 4
|
||||
frame $w.o3 -border 4
|
||||
frame $w.exp -border 4
|
||||
frame $w.adv -border 4
|
||||
frame $w.weekend -border 4
|
||||
frame $w.durationbox -border 4
|
||||
frame $w.time -border 4
|
||||
frame $w.hol -border 4
|
||||
frame $w.o -bd 4 -relief ridge
|
||||
frame $w.o1 -bd 4
|
||||
frame $w.o2 -bd 4
|
||||
frame $w.o3 -bd 4
|
||||
frame $w.exp -bd 4
|
||||
frame $w.adv -bd 4
|
||||
frame $w.weekend -bd 4
|
||||
frame $w.durationbox -bd 4
|
||||
frame $w.time -bd 4
|
||||
frame $w.hol -bd 4
|
||||
frame $w.msg
|
||||
frame $w.buttons
|
||||
pack $w.o1 $w.o2 $w.o3 -side top -anchor w -in $w.o
|
||||
@@ -2016,7 +2116,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 %_%_%_%_"
|
||||
@@ -3530,7 +3630,7 @@ proc DoShadeSpecial { n r g b } {
|
||||
# %DESCRIPTION:
|
||||
# Handles the "MOON" special -- draws a moon symbol
|
||||
#***********************************************************************
|
||||
proc DoMoonSpecial { n stuff fntag } {
|
||||
proc DoMoonSpecial { n stuff fntag day } {
|
||||
set msg ""
|
||||
set num [scan $stuff "%d %d %d %s" phase junk1 junk2 msg]
|
||||
if {$num < 1} {
|
||||
@@ -3539,12 +3639,24 @@ proc DoMoonSpecial { n stuff fntag } {
|
||||
if {$phase < 0 || $phase > 3} {
|
||||
return
|
||||
}
|
||||
|
||||
switch -exact -- $phase {
|
||||
0 { set win .moon_new }
|
||||
1 { set win .moon_first }
|
||||
2 { set win .moon_full }
|
||||
3 { set win .moon_last }
|
||||
0 { set win .moon_new }
|
||||
1 { set win .moon_first }
|
||||
2 { set win .moon_full }
|
||||
3 { set win .moon_last }
|
||||
}
|
||||
|
||||
# We need two sets of moon phase windows. There can be
|
||||
# two of a given phase in the same month, but Tk does
|
||||
# not allow the same embedded window in two separate
|
||||
# text boxes. So we use this hack to make sure
|
||||
# we use a different window if the same moon phase
|
||||
# happens twice in a month.
|
||||
if {$day > 16} {
|
||||
append win "2"
|
||||
}
|
||||
|
||||
.cal.t$n configure -state normal
|
||||
.cal.t$n window create 1.0 -window $win
|
||||
|
||||
@@ -3569,7 +3681,7 @@ proc DoMoonSpecial { n stuff fntag } {
|
||||
.cal.t$n tag bind $fntag <ButtonPress-1> "FireEditor .cal.t$n $fntag"
|
||||
}
|
||||
}
|
||||
.cal.t$n configure -state disabled
|
||||
.cal.t$n configure -state disabled -takefocus 0
|
||||
}
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: DisplayTime
|
||||
@@ -3607,8 +3719,12 @@ proc CreateMoonWindows {} {
|
||||
catch { destroy .moon_full }
|
||||
catch { destroy .moon_last }
|
||||
|
||||
catch { destroy .moon_new2 }
|
||||
catch { destroy .moon_first2}
|
||||
catch { destroy .moon_full2 }
|
||||
catch { destroy .moon_last2 }
|
||||
|
||||
set extra 1
|
||||
#set wid [font measure CalboxFont 0]
|
||||
set wid [font metrics CalboxFont -ascent]
|
||||
set orig_wid $wid
|
||||
incr wid $extra
|
||||
@@ -3619,24 +3735,32 @@ proc CreateMoonWindows {} {
|
||||
incr orig_wid $extra
|
||||
|
||||
set w [expr $extra+$orig_wid]
|
||||
canvas .moon_new -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
.moon_new create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
|
||||
canvas .moon_first -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
.moon_first create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
.moon_first create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 90 -extent 180 -outline {}
|
||||
foreach win {.moon_new .moon_new2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
balloon_add_help $win "New Moon"
|
||||
}
|
||||
|
||||
canvas .moon_full -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
.moon_full create oval $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -width 1
|
||||
foreach win {.moon_first .moon_first2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
$win create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 90 -extent 180 -outline {}
|
||||
balloon_add_help $win "First Quarter"
|
||||
}
|
||||
|
||||
canvas .moon_last -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
.moon_last create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
.moon_last create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 270 -extent 180 -outline {}
|
||||
foreach win {.moon_full .moon_full2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -width 1
|
||||
balloon_add_help $win "Full Moon"
|
||||
}
|
||||
|
||||
balloon_add_help .moon_new "New Moon"
|
||||
balloon_add_help .moon_first "First Quarter"
|
||||
balloon_add_help .moon_full "Full Moon"
|
||||
balloon_add_help .moon_last "Last Quarter"
|
||||
foreach win {.moon_last .moon_last2 } {
|
||||
canvas $win -background $Option(BackgroundColor) -width $wid -height $wid -borderwidth 0 -highlightthickness 0
|
||||
$win create oval $extra $extra $w $w -outline $Option(TextColor) -width 1
|
||||
$win create arc $extra $extra $w $w -outline $Option(TextColor) -fill $Option(TextColor) -start 270 -extent 180 -outline {}
|
||||
balloon_add_help $win "Last Quarter"
|
||||
}
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
@@ -3996,4 +4120,72 @@ proc FindConfigFile {} {
|
||||
set ConfigFile "~/.tkremindrc"
|
||||
}
|
||||
|
||||
proc set_default_colors { w } {
|
||||
global tmpOpt
|
||||
set tmpOpt(BackgroundColor) "#d9d9d9"
|
||||
set tmpOpt(LabelColor) "#000000"
|
||||
set tmpOpt(LineColor) "#000000"
|
||||
set tmpOpt(TextColor) "#000000"
|
||||
set tmpOpt(TodayColor) "#00C0C0"
|
||||
set tmpOpt(WinBackground) "#d9d9d9"
|
||||
update_color_buttons $w
|
||||
}
|
||||
|
||||
proc set_dark_colors { w } {
|
||||
global tmpOpt
|
||||
set tmpOpt(BackgroundColor) "#000000"
|
||||
set tmpOpt(LabelColor) "#00ffff"
|
||||
set tmpOpt(LineColor) "#0080fc"
|
||||
set tmpOpt(TextColor) "#ffffff"
|
||||
set tmpOpt(TodayColor) "#b000b6"
|
||||
set tmpOpt(WinBackground) "#000000"
|
||||
update_color_buttons $w
|
||||
}
|
||||
|
||||
proc update_color_buttons { w } {
|
||||
global tmpOpt
|
||||
$w.bbgcolor configure -background $tmpOpt(BackgroundColor)
|
||||
$w.bheadcolor configure -background $tmpOpt(LabelColor)
|
||||
$w.gridbcolor configure -background $tmpOpt(LineColor)
|
||||
$w.btextcolor configure -background $tmpOpt(TextColor)
|
||||
$w.tbbgcolor configure -background $tmpOpt(TodayColor)
|
||||
$w.bwincolor configure -background $tmpOpt(WinBackground)
|
||||
}
|
||||
|
||||
proc set_button_to_queue {} {
|
||||
.b.queue configure -text {Queue...} -command {DoQueue}
|
||||
}
|
||||
proc set_button_to_errors {} {
|
||||
.b.queue configure -text {Errors...} -command {ShowErrors}
|
||||
}
|
||||
|
||||
proc ShowErrors {} {
|
||||
global RemindErrors
|
||||
set w ".errors"
|
||||
catch { destroy $w }
|
||||
toplevel $w
|
||||
text $w.t -width 80 -height 30 -wrap word -yscrollcommand "$w.sb set"
|
||||
scrollbar $w.sb -orient vertical -command "$w.t yview"
|
||||
button $w.ok -text OK -command DoneShowingErrors
|
||||
grid $w.t -row 0 -column 0 -sticky nsew
|
||||
grid $w.sb -row 0 -column 1 -sticky ns
|
||||
grid $w.ok -row 1 -column 0 -stick w
|
||||
grid columnconfigure $w 0 -weight 1
|
||||
grid columnconfigure $w 1 -weight 0
|
||||
grid rowconfigure $w 0 -weight 1
|
||||
grid rowconfigure $w 1 -weight 0
|
||||
$w.t insert end $RemindErrors
|
||||
$w.t configure -state disabled
|
||||
CenterWindow $w .
|
||||
}
|
||||
|
||||
proc DoneShowingErrors {} {
|
||||
global RemindErrors
|
||||
set RemindErrors {}
|
||||
set_button_to_queue
|
||||
destroy .errors
|
||||
}
|
||||
|
||||
# Rem2PS program to execute -- supply full path if you want
|
||||
|
||||
main
|
||||
|
||||
@@ -36,21 +36,21 @@ REMINDOBJS= $(REMINDSRCS:.c=.o)
|
||||
|
||||
all: remind rem2ps
|
||||
|
||||
test: remind
|
||||
test: all
|
||||
@sh ../tests/test-rem
|
||||
|
||||
.c.o:
|
||||
@CC@ -c @CPPFLAGS@ @CFLAGS@ @DEFS@ $(CEXTRA) $(LANGDEF) -I. -I$(srcdir) $<
|
||||
@CC@ -c @CPPFLAGS@ @CFLAGS@ @DEFS@ $(CEXTRA) $(LANGDEF) -DSYSDIR=$(datarootdir)/remind -I. -I$(srcdir) $<
|
||||
|
||||
$(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; \
|
||||
@@ -61,8 +61,10 @@ install-nostripped: all
|
||||
for man in $(MANS) ; do \
|
||||
$(INSTALL_DATA) $$man $(DESTDIR)$(mandir)/man1 || exit 1; \
|
||||
done
|
||||
-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
|
||||
|
||||
|
||||
530
src/calendar.c
530
src/calendar.c
@@ -5,16 +5,17 @@
|
||||
/* The code for generating a calendar. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#define _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include "config.h"
|
||||
#include "custom.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -26,6 +27,11 @@
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LANGINFO_H
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
|
||||
#include "lang.h"
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
@@ -75,6 +81,8 @@ static struct line_drawing VT100Drawing = {
|
||||
"\x6c", "\x74", "\x6a", "\x71"
|
||||
};
|
||||
|
||||
static int encoding_is_utf8 = 0;
|
||||
|
||||
static struct line_drawing UTF8Drawing = {
|
||||
"", "",
|
||||
"\xe2\x94\xb4",
|
||||
@@ -139,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)
|
||||
|
||||
@@ -221,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);
|
||||
@@ -236,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);
|
||||
@@ -248,6 +298,61 @@ 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
|
||||
*/
|
||||
if (UseUTF8Chars || encoding_is_utf8) {
|
||||
printf("\xE2\x80\x8E");
|
||||
}
|
||||
}
|
||||
|
||||
static char const *
|
||||
despace(char const *s)
|
||||
{
|
||||
@@ -270,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) {
|
||||
@@ -356,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;
|
||||
@@ -474,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;
|
||||
@@ -492,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)) +
|
||||
@@ -504,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;
|
||||
}
|
||||
@@ -539,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 */
|
||||
@@ -587,6 +784,14 @@ void ProduceCalendar(void)
|
||||
{
|
||||
int y, m, d;
|
||||
|
||||
/* Check if current locale is UTF-8, if we have langinfo.h */
|
||||
#ifdef HAVE_LANGINFO_H
|
||||
char const *encoding = nl_langinfo(CODESET);
|
||||
if (!strcasecmp(encoding, "utf-8")) {
|
||||
encoding_is_utf8 = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (UseUTF8Chars) {
|
||||
linestruct = &UTF8Drawing;
|
||||
} else if (UseVTChars) {
|
||||
@@ -596,8 +801,6 @@ void ProduceCalendar(void)
|
||||
}
|
||||
ShouldCache = 1;
|
||||
|
||||
CalWidth = ComputeCalWidth(CalWidth);
|
||||
|
||||
ColSpaces = (CalWidth - 9) / 7;
|
||||
CalWidth = 7*ColSpaces + 8;
|
||||
|
||||
@@ -650,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);
|
||||
}
|
||||
@@ -673,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();
|
||||
@@ -690,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();
|
||||
@@ -701,7 +931,7 @@ static void DoCalendarOneWeek(int nleft)
|
||||
/* Write the body lines */
|
||||
done = 0;
|
||||
while (!done) {
|
||||
done = WriteOneCalLine();
|
||||
done = WriteOneCalLine(OrigJul, wd);
|
||||
LinesWritten++;
|
||||
}
|
||||
|
||||
@@ -711,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();
|
||||
@@ -738,6 +971,8 @@ static void DoCalendarOneMonth(void)
|
||||
{
|
||||
int y, m, d, mm, yy, i, j;
|
||||
|
||||
InitMoonsAndShades();
|
||||
|
||||
if (!DoSimpleCalendar) WriteCalHeader();
|
||||
|
||||
DidADay = 0;
|
||||
@@ -838,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++;
|
||||
}
|
||||
|
||||
@@ -864,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, ' ');
|
||||
@@ -882,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();
|
||||
@@ -893,7 +1153,7 @@ static int WriteCalendarRow(void)
|
||||
/* Write the body lines */
|
||||
done = 0;
|
||||
while (!done) {
|
||||
done = WriteOneCalLine();
|
||||
done = WriteOneCalLine(OrigJul, wd);
|
||||
LinesWritten++;
|
||||
}
|
||||
|
||||
@@ -903,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();
|
||||
@@ -975,6 +1237,10 @@ static void PrintLeft(char const *s, int width, char pad)
|
||||
while (*ws && wcwidth(*ws) == 0) {
|
||||
PutWideChar(*ws++);
|
||||
}
|
||||
|
||||
/* Possibly send lrm control sequence */
|
||||
send_lrm();
|
||||
|
||||
for (i=display_len; i<width; i++) fputc(pad, stdout);
|
||||
if (buf != static_buf) free(buf);
|
||||
#endif
|
||||
@@ -1055,6 +1321,9 @@ static void PrintCentered(char const *s, int width, char *pad)
|
||||
while (*ws && wcwidth(*ws) == 0) {
|
||||
PutWideChar(*ws++);
|
||||
}
|
||||
/* Possibly send lrm control sequence */
|
||||
send_lrm();
|
||||
|
||||
for (i=d+display_len; i<width; i++) fputs(pad, stdout);
|
||||
if (buf != static_buf) free(buf);
|
||||
#endif
|
||||
@@ -1067,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();
|
||||
@@ -1089,7 +1364,6 @@ static int WriteOneCalLine(void)
|
||||
return done;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* WriteOneColLine */
|
||||
@@ -1109,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) {
|
||||
@@ -1140,27 +1417,35 @@ static int WriteOneColLine(int col)
|
||||
}
|
||||
if (iswspace(*ws)) {
|
||||
wspace = ws;
|
||||
}
|
||||
if (wcwidth(*ws)) {
|
||||
width++;
|
||||
} else {
|
||||
if (wcwidth(*ws)) {
|
||||
width += wcwidth(*ws);
|
||||
if (width > ColSpaces) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ws++;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
if (!wspace) {
|
||||
for (ws = e->wc_pos; ws - e->wc_pos < ColSpaces; ws++) {
|
||||
for (ws = e->wc_pos; numwritten < ColSpaces; ws++) {
|
||||
if (!*ws) break;
|
||||
if (iswspace(*ws)) {
|
||||
putchar(' ');
|
||||
numwritten++;
|
||||
} else {
|
||||
if (wcwidth(*ws) > 0) {
|
||||
if (numwritten + wcwidth(*ws) > ColSpaces) {
|
||||
break;
|
||||
}
|
||||
numwritten += wcwidth(*ws);
|
||||
}
|
||||
PutWideChar(*ws);
|
||||
@@ -1183,11 +1468,15 @@ 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 */
|
||||
send_lrm();
|
||||
|
||||
/* Flesh out the rest of the column */
|
||||
while(numwritten++ < ColSpaces) putchar(' ');
|
||||
|
||||
@@ -1235,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. */
|
||||
@@ -1263,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 */
|
||||
@@ -1359,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;
|
||||
@@ -1539,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);
|
||||
@@ -1602,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;
|
||||
@@ -1824,6 +2167,13 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
e->next = CurCol;
|
||||
CalColumn[col] = e;
|
||||
SortCol(&CalColumn[col]);
|
||||
} else {
|
||||
/* Parse the rest of the line to catch expression-pasting errors */
|
||||
while (ParseChar(p, &r, 0)) {
|
||||
if (r != 0) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
@@ -1857,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);
|
||||
@@ -1983,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("\"");
|
||||
@@ -2195,14 +2585,14 @@ CalendarTime(int tim, int duration)
|
||||
}
|
||||
|
||||
if (h >= 12) {
|
||||
ampm1 = L_PM;
|
||||
ampm1 = DynamicPm;
|
||||
} else {
|
||||
ampm1 = L_AM;
|
||||
ampm1 = DynamicAm;
|
||||
}
|
||||
if (h2 >= 12) {
|
||||
ampm2 = L_PM;
|
||||
ampm2 = DynamicPm;
|
||||
} else {
|
||||
ampm2 = L_AM;
|
||||
ampm2 = DynamicAm;
|
||||
}
|
||||
if (!days) {
|
||||
if (!strcmp(ampm1, ampm2)) {
|
||||
@@ -2249,7 +2639,7 @@ char const *SimpleTime(int tim)
|
||||
if (h == 0) hh=12;
|
||||
else if (h > 12) hh=h-12;
|
||||
else hh=h;
|
||||
sprintf(buf, "%d%c%02d%s ", hh, TimeSep, min, (h>=12) ? L_PM : L_AM);
|
||||
sprintf(buf, "%d%c%02d%s ", hh, TimeSep, min, (h>=12) ? DynamicPm : DynamicAm);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
54
src/compare-language-mods.pl
Executable file
54
src/compare-language-mods.pl
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $language_map = {
|
||||
en => 'ENGLISH',
|
||||
de => 'GERMAN',
|
||||
nl => 'DUTCH',
|
||||
fi => 'FINNISH',
|
||||
fr => 'FRENCH',
|
||||
'no' => 'NORWEGIAN',
|
||||
da => 'DANISH',
|
||||
pl => 'POLISH',
|
||||
is => 'ICELANDIC',
|
||||
pt => 'BRAZPORT',
|
||||
it => 'ITALIAN',
|
||||
ro => 'ROMANIAN',
|
||||
es => 'SPANISH',
|
||||
};
|
||||
|
||||
if (!$ARGV[0]) {
|
||||
print STDERR "Usage: $0 lang_code\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
my $lang = $ARGV[0];
|
||||
if (!exists($language_map->{$lang})) {
|
||||
print STDERR "$lang is not a valid language.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
my $flag = $language_map->{$lang};
|
||||
print STDERR "Testing for: $lang - $flag.\n";
|
||||
my_sys("make clean > /dev/null 2>&1") && die("make clean failed");
|
||||
my_sys("make -j6 all LANGDEF=-DLANG=$flag > /dev/null 2>&1") && die("make all failed");
|
||||
my_sys("./remind -q -r ../tests/tstlang.rem 2022-03-23 11:44 > test-$lang-compiled.out 2>&1");
|
||||
|
||||
my_sys("make clean > /dev/null 2>&1") && die("make clean failed");
|
||||
my_sys("make -j6 all > /dev/null 2>&1") && die("make all failed");
|
||||
my_sys("./remind -q -r -ii=\\\"../include/lang/$lang.rem\\\" ../tests/tstlang.rem 2022-03-23 11:44 > test-$lang-runtime.out 2>&1");
|
||||
|
||||
my $rc = my_sys("cmp test-$lang-compiled.out test-$lang-runtime.out > /dev/null 2>&1");
|
||||
if ($rc == 0) {
|
||||
print STDERR "Congrats! Compiled and runtime language output matches for $lang.\n";
|
||||
} else {
|
||||
print STDERR "Whoops. Compiled and runtime language output differs for $lang.\n"
|
||||
}
|
||||
exit(0);
|
||||
|
||||
sub my_sys
|
||||
{
|
||||
#print STDERR "Running: " . join(' ', @_) . "\n";
|
||||
return system(@_);
|
||||
}
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
#undef HAVE_LANGINFO_H
|
||||
|
||||
#undef HAVE_GLOB
|
||||
|
||||
#undef HAVE_SETENV
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* which you can customize. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
/* The default values are initially set to the city hall in Ottawa, */
|
||||
/* Ontario, Canada. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define DEFAULT_LATITUDE 45.42055555555555
|
||||
#define DEFAULT_LONGITUDE -75.68972222222223
|
||||
#define DEFAULT_LATITUDE 45.420556
|
||||
#define DEFAULT_LONGITUDE -75.689722
|
||||
#define LOCATION "Ottawa"
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
@@ -116,7 +116,7 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define VAL_STACK_SIZE 500
|
||||
#define VAL_STACK_SIZE 1000
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* which you can customize. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
/* The default values are initially set to the city hall in Ottawa, */
|
||||
/* Ontario, Canada. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define DEFAULT_LATITUDE 45.42055555555555
|
||||
#define DEFAULT_LONGITUDE -75.68972222222223
|
||||
#define DEFAULT_LATITUDE 45.420556
|
||||
#define DEFAULT_LONGITUDE -75.689722
|
||||
#define LOCATION "Ottawa"
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
@@ -116,7 +116,7 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define VAL_STACK_SIZE 500
|
||||
#define VAL_STACK_SIZE 1000
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */
|
||||
|
||||
172
src/dorem.c
172
src/dorem.c
@@ -7,7 +7,7 @@
|
||||
/* commands. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -28,7 +28,7 @@ static int ParseTimeTrig (ParsePtr s, TimeTrig *tim, int save_in_globals);
|
||||
static int ParseLocalOmit (ParsePtr s, Trigger *t);
|
||||
static int ParseScanFrom (ParsePtr s, Trigger *t, int type);
|
||||
static int ParsePriority (ParsePtr s, Trigger *t);
|
||||
static int ParseUntil (ParsePtr s, Trigger *t);
|
||||
static int ParseUntil (ParsePtr s, Trigger *t, int type);
|
||||
static int ShouldTriggerBasedOnWarn (Trigger *t, int jul, int *err);
|
||||
static int ComputeTrigDuration(TimeTrig *t);
|
||||
|
||||
@@ -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);
|
||||
@@ -168,27 +172,37 @@ int DoRem(ParsePtr p)
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
/* Queue the reminder, if necessary */
|
||||
|
||||
/* Queue the reminder, if necessary */
|
||||
if (jul == JulianToday &&
|
||||
!(!IgnoreOnce &&
|
||||
trig.once != NO_ONCE &&
|
||||
FileAccessDate == JulianToday))
|
||||
QueueReminder(p, &trig, &tim, trig.sched);
|
||||
/* If we're in daemon mode, do nothing over here */
|
||||
/* If we're in daemon mode, do nothing over here */
|
||||
if (Daemon) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
|
||||
r = OK;
|
||||
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, jul)) ) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
/* Parse the rest of the line to catch any potential
|
||||
expression-pasting errors */
|
||||
while (ParseChar(p, &r, 0)) {
|
||||
if (r != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
return r;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -237,11 +251,15 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
tim->delta = DefaultTDelta;
|
||||
tim->rep = NO_REP;
|
||||
tim->duration = NO_TIME;
|
||||
trig->need_wkday = 0;
|
||||
trig->adj_for_last = 0;
|
||||
|
||||
if (save_in_globals) {
|
||||
LastTriggerTime = NO_TIME;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
int parsing = 1;
|
||||
while(parsing) {
|
||||
/* Read space-delimited string */
|
||||
r = ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
@@ -249,6 +267,25 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
/* Figure out what we've got */
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
switch(tok.type) {
|
||||
case T_In:
|
||||
/* Completely ignored */
|
||||
DBufFree(&buf);
|
||||
break;
|
||||
|
||||
case T_Ordinal:
|
||||
DBufFree(&buf);
|
||||
if (trig->d != NO_DAY) return E_DAY_TWICE;
|
||||
if (tok.val < 0) {
|
||||
if (trig->back != NO_BACK) return E_BACK_TWICE;
|
||||
trig->back = -7;
|
||||
trig->d = 1;
|
||||
trig->adj_for_last = 1;
|
||||
} else {
|
||||
trig->d = 1 + 7 * tok.val;
|
||||
}
|
||||
trig->need_wkday = 1;
|
||||
break;
|
||||
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (trig->d != NO_DAY) return E_DAY_TWICE;
|
||||
@@ -322,7 +359,6 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
DBufFree(&buf);
|
||||
trig->typ = tok.val;
|
||||
if (s->isnested) return E_CANT_NEST_RTYPE;
|
||||
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
|
||||
if (trig->typ == PASSTHRU_TYPE) {
|
||||
r = ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
@@ -332,19 +368,20 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
}
|
||||
StrnCpy(trig->passthru, DBufValue(&buf), PASSTHRU_LEN);
|
||||
}
|
||||
return OK;
|
||||
parsing = 0;
|
||||
break;
|
||||
|
||||
case T_Through:
|
||||
DBufFree(&buf);
|
||||
if (trig->rep != NO_REP) return E_REP_TWICE;
|
||||
trig->rep = 1;
|
||||
r = ParseUntil(s, trig);
|
||||
r = ParseUntil(s, trig, tok.type);
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
case T_Until:
|
||||
DBufFree(&buf);
|
||||
r=ParseUntil(s, trig);
|
||||
r=ParseUntil(s, trig, tok.type);
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
@@ -378,6 +415,15 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
trig->back = tok.val;
|
||||
break;
|
||||
|
||||
case T_BackAdj:
|
||||
DBufFree(&buf);
|
||||
if (trig->back != NO_BACK) return E_BACK_TWICE;
|
||||
if (trig->d != NO_DAY) return E_DAY_TWICE;
|
||||
trig->back = tok.val;
|
||||
trig->d = 1;
|
||||
trig->adj_for_last = 1;
|
||||
break;
|
||||
|
||||
case T_Once:
|
||||
DBufFree(&buf);
|
||||
if (trig->once != NO_ONCE) return E_ONCE_TWICE;
|
||||
@@ -392,7 +438,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
case T_Omit:
|
||||
DBufFree(&buf);
|
||||
if (trig->omitfunc[0]) {
|
||||
Eprint("Warning: OMIT is ignored if you use OMITFUNC");
|
||||
Wprint("Warning: OMIT is ignored if you use OMITFUNC");
|
||||
}
|
||||
|
||||
r = ParseLocalOmit(s, trig);
|
||||
@@ -401,12 +447,12 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
|
||||
case T_Empty:
|
||||
DBufFree(&buf);
|
||||
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
|
||||
return OK;
|
||||
parsing = 0;
|
||||
break;
|
||||
|
||||
case T_OmitFunc:
|
||||
if (trig->localomit) {
|
||||
Eprint("Warning: OMIT is ignored if you use OMITFUNC");
|
||||
Wprint("Warning: OMIT is ignored if you use OMITFUNC");
|
||||
}
|
||||
r=ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
@@ -428,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:
|
||||
@@ -474,10 +525,58 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
DBufFree(&buf);
|
||||
trig->typ = MSG_TYPE;
|
||||
if (s->isnested) return E_CANT_NEST_RTYPE;
|
||||
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
|
||||
return OK;
|
||||
parsing = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (trig->need_wkday && trig->wd == NO_WD) {
|
||||
Eprint("Weekday name(s) required");
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
|
||||
/* Adjust month and possibly year */
|
||||
if (trig->adj_for_last) {
|
||||
if (trig->m != NO_MON) {
|
||||
trig->m++;
|
||||
if (trig->m >= 12) {
|
||||
trig->m = 0;
|
||||
if (trig->y != NO_YR) {
|
||||
trig->y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
trig->adj_for_last = 0;
|
||||
}
|
||||
|
||||
/* Check for some warning conditions */
|
||||
if (!s->nonconst_expr) {
|
||||
if (trig->y != NO_YR && trig->m != NO_MON && trig->d != NO_DAY && trig->until != NO_UNTIL) {
|
||||
if (Julian(trig->y, trig->m, trig->d) > trig->until) {
|
||||
Wprint("Warning: UNTIL/THROUGH date earlier than start date");
|
||||
}
|
||||
}
|
||||
if (trig->from != NO_DATE) {
|
||||
if (trig->until != NO_UNTIL && trig->until < trig->from) {
|
||||
Wprint("Warning: UNTIL/THROUGH date earlier than FROM date");
|
||||
}
|
||||
} else if (trig->scanfrom != NO_DATE) {
|
||||
if (trig->until != NO_UNTIL && trig->until < trig->scanfrom) {
|
||||
Wprint("Warning: UNTIL/THROUGH date earlier than SCANFROM date");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trig->y != NO_YR && trig->m != NO_MON && trig->d != NO_DAY && trig->until != NO_UNTIL && trig->rep == NO_REP) {
|
||||
Wprint("Warning: Useless use of UNTIL with fully-specified date and no *rep");
|
||||
}
|
||||
|
||||
/* Set scanfrom to default if not set explicitly */
|
||||
if (trig->scanfrom == NO_DATE) {
|
||||
trig->scanfrom = JulianToday;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -568,12 +667,18 @@ static int ParseLocalOmit(ParsePtr s, Trigger *t)
|
||||
/* ParseUntil - parse the UNTIL portion of a reminder */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int ParseUntil(ParsePtr s, Trigger *t)
|
||||
static int ParseUntil(ParsePtr s, Trigger *t, int type)
|
||||
{
|
||||
int y = NO_YR,
|
||||
m = NO_MON,
|
||||
d = NO_DAY;
|
||||
|
||||
char const *which;
|
||||
if (type == T_Until) {
|
||||
which = "UNTIL";
|
||||
} else {
|
||||
which = "THROUGH";
|
||||
}
|
||||
Token tok;
|
||||
int r;
|
||||
DynamicBuffer buf;
|
||||
@@ -589,7 +694,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
y = tok.val;
|
||||
@@ -598,7 +703,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
|
||||
case T_Month:
|
||||
DBufFree(&buf);
|
||||
if (m != NO_MON) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
m = tok.val;
|
||||
@@ -607,7 +712,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
|
||||
case T_Day:
|
||||
DBufFree(&buf);
|
||||
if (d != NO_DAY) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
d = tok.val;
|
||||
@@ -616,15 +721,15 @@ static int ParseUntil(ParsePtr s, Trigger *t)
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", which, ErrMsg[E_YR_TWICE]);
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
if (m != NO_MON) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", which, ErrMsg[E_MON_TWICE]);
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
if (d != NO_DAY) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", which, ErrMsg[E_DAY_TWICE]);
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
FromJulian(tok.val, &y, &m, &d);
|
||||
@@ -632,7 +737,7 @@ static int ParseUntil(ParsePtr s, Trigger *t)
|
||||
|
||||
default:
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_INCOMPLETE]);
|
||||
Eprint("%s: %s", which, ErrMsg[E_INCOMPLETE]);
|
||||
DBufFree(&buf);
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
@@ -772,6 +877,8 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* TriggerReminder */
|
||||
@@ -833,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);
|
||||
}
|
||||
|
||||
@@ -934,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);
|
||||
@@ -948,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) {
|
||||
@@ -959,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);
|
||||
@@ -973,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) {
|
||||
|
||||
346
src/dosubst.c
346
src/dosubst.c
@@ -6,11 +6,12 @@
|
||||
/* reminders are triggered. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "expr.h"
|
||||
#define L_IN_DOSUBST
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -29,9 +30,6 @@
|
||||
#define NL "\n"
|
||||
#endif
|
||||
|
||||
static char TODAY[] = L_TODAY;
|
||||
static char TOMORROW[] = L_TOMORROW;
|
||||
|
||||
#define SHIP_OUT(s) if(DBufPuts(dbuf, s) != OK) return E_NO_MEM
|
||||
|
||||
/***************************************************************/
|
||||
@@ -53,15 +51,23 @@ 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;
|
||||
int has_quote = 0;
|
||||
char *ss;
|
||||
char const *expr;
|
||||
char *os;
|
||||
char s[256];
|
||||
char uf[32];
|
||||
char mypm[64];
|
||||
char mycpm[64];
|
||||
char myplu[64];
|
||||
int origLen = DBufLen(dbuf);
|
||||
int altmode;
|
||||
int r;
|
||||
Value v;
|
||||
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
|
||||
@@ -74,16 +80,16 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_MPLU_OVER
|
||||
L_MPLU_OVER
|
||||
#else /* L_MPLU_OVER */
|
||||
mplu = (mdiff == 1 ? "" : L_MPLU);
|
||||
mplu = (mdiff == 1 ? "" : DynamicMplu);
|
||||
#endif /* L_MPLU_OVER */
|
||||
|
||||
#ifdef L_HPLU_OVER
|
||||
L_HPLU_OVER
|
||||
#else /* L_HPLU_OVER */
|
||||
hplu = (hdiff == 1 ? "" : L_HPLU);
|
||||
hplu = (hdiff == 1 ? "" : DynamicHplu);
|
||||
#endif /* L_HPLU_OVER */
|
||||
|
||||
when = (tdiff < 0 ? L_AGO : L_FROMNOW);
|
||||
when = (tdiff < 0) ? DynamicAgo : DynamicFromnow;
|
||||
|
||||
h = tim / 60;
|
||||
min = tim % 60;
|
||||
@@ -91,7 +97,26 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_AMPM_OVERRIDE
|
||||
L_AMPM_OVERRIDE (pm, h)
|
||||
#else
|
||||
pm = (h < 12) ? L_AM : L_PM;
|
||||
r = -1;
|
||||
if (UserFuncExists("subst_ampm") == 1) {
|
||||
snprintf(s, sizeof(s), "subst_ampm(%d)", h);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
snprintf(mypm, sizeof(mypm), "%s", v.v.str);
|
||||
pm = mypm;
|
||||
} else {
|
||||
r = -1;
|
||||
}
|
||||
DestroyValue(v);
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
pm = (h < 12) ? DynamicAm : DynamicPm;
|
||||
}
|
||||
#endif
|
||||
hh = (h == 12) ? 12 : h % 12;
|
||||
|
||||
@@ -101,25 +126,60 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_AMPM_OVERRIDE
|
||||
L_AMPM_OVERRIDE (cpm, ch)
|
||||
#else
|
||||
cpm = (ch < 12) ? L_AM : L_PM;
|
||||
r = -1;
|
||||
if (UserFuncExists("subst_ampm") == 1) {
|
||||
snprintf(s, sizeof(s), "subst_ampm(%d)", ch);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
snprintf(mycpm, sizeof(mycpm), "%s", v.v.str);
|
||||
cpm = mycpm;
|
||||
} else {
|
||||
r = -1;
|
||||
}
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
cpm = (h < 12) ? DynamicAm : DynamicPm;
|
||||
}
|
||||
#endif
|
||||
chh = (ch == 12) ? 12 : ch % 12;
|
||||
|
||||
#ifdef L_ORDINAL_OVERRIDE
|
||||
L_ORDINAL_OVERRIDE
|
||||
L_ORDINAL_OVERRIDE;
|
||||
#else
|
||||
switch(d) {
|
||||
case 1:
|
||||
case 21:
|
||||
case 31: plu = "st"; break;
|
||||
if (UserFuncExists("subst_ordinal") == 1) {
|
||||
snprintf(s, sizeof(s), "subst_ordinal(%d)", d);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
snprintf(myplu, sizeof(myplu), "%s", v.v.str);
|
||||
plu = myplu;
|
||||
} else {
|
||||
r = -1;
|
||||
}
|
||||
} else {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
}
|
||||
}
|
||||
if (r != OK) {
|
||||
switch(d) {
|
||||
case 1:
|
||||
case 21:
|
||||
case 31: plu = "st"; break;
|
||||
|
||||
case 2:
|
||||
case 22: plu = "nd"; break;
|
||||
case 2:
|
||||
case 22: plu = "nd"; break;
|
||||
|
||||
case 3:
|
||||
case 23: plu = "rd"; break;
|
||||
case 3:
|
||||
case 23: plu = "rd"; break;
|
||||
|
||||
default: plu = "th"; break;
|
||||
default: plu = "th"; break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -131,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;
|
||||
@@ -162,7 +225,69 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c == '{') {
|
||||
i = 0;
|
||||
ss = s + snprintf(s, sizeof(s), "subst_");
|
||||
while (1) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
if (c == '}' || !c) {
|
||||
break;
|
||||
}
|
||||
if (i < 64) {
|
||||
*ss++ = c;
|
||||
*ss = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (!c) {
|
||||
Wprint("Warning: Unterminated %%{...} substitution sequence");
|
||||
}
|
||||
if (UserFuncExists(s) != 3) {
|
||||
continue;
|
||||
}
|
||||
snprintf(ss, sizeof(s) - (ss-s), "(%d,'%04d-%02d-%02d',%02d:%02d)",
|
||||
altmode ? 1 : 0, y, m+1, d, h, min);
|
||||
expr = (char const *) s;
|
||||
r = EvalExpr(&expr, &v, NULL);
|
||||
if (r == OK) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
if (DBufPuts(dbuf, v.v.str) != OK) {
|
||||
DestroyValue(v);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
DestroyValue(v);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
done = 0;
|
||||
snprintf(uf, sizeof(uf), "subst_%c", c);
|
||||
if (UserFuncExists(uf) == 3) {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
if (diff <= 1) {
|
||||
switch(UPPER(c)) {
|
||||
#ifndef L_NOTOMORROW_A
|
||||
@@ -204,7 +329,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifndef L_NOTOMORROW_V
|
||||
case 'V':
|
||||
#endif
|
||||
sprintf(s, "%s", (diff ? TOMORROW : TODAY));
|
||||
snprintf(s, sizeof(s), "%s", (diff ? DynamicTomorrow: DynamicToday));
|
||||
SHIP_OUT(s);
|
||||
done = 1;
|
||||
break;
|
||||
@@ -213,16 +338,42 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!done) {
|
||||
snprintf(uf, sizeof(uf), "subst_%cx", c);
|
||||
if (UserFuncExists(uf) == 3) {
|
||||
snprintf(s, sizeof(s), "subst_%cx(%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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) switch(UPPER(c)) {
|
||||
case 'A':
|
||||
#ifdef L_A_OVER
|
||||
L_A_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s, %d %s, %d", get_day_name(jul%7), d,
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d %s, %d", get_day_name(jul%7), d,
|
||||
get_month_name(m), y);
|
||||
} else {
|
||||
sprintf(s, "%s %s, %d %s, %d", L_ON, get_day_name(jul%7), d,
|
||||
snprintf(s, sizeof(s), "%s %s, %d %s, %d", DynamicOn, get_day_name(jul%7), d,
|
||||
get_month_name(m), y);
|
||||
}
|
||||
#endif
|
||||
@@ -233,7 +384,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_B_OVER
|
||||
L_B_OVER
|
||||
#else
|
||||
sprintf(s, L_INXDAYS, diff);
|
||||
snprintf(s, sizeof(s), L_INXDAYS, diff);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -242,10 +393,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_C_OVER
|
||||
L_C_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s", get_day_name(jul%7));
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s", get_day_name(jul%7));
|
||||
} else {
|
||||
sprintf(s, "%s %s", L_ON, get_day_name(jul%7));
|
||||
snprintf(s, sizeof(s), "%s %s", DynamicOn, get_day_name(jul%7));
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
@@ -255,7 +406,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_D_OVER
|
||||
L_D_OVER
|
||||
#else
|
||||
sprintf(s, "%d", d);
|
||||
snprintf(s, sizeof(s), "%d", d);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -264,11 +415,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_E_OVER
|
||||
L_E_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%02d%c%02d%c%04d", d, DateSep,
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", d, DateSep,
|
||||
m+1, DateSep, y);
|
||||
} else {
|
||||
sprintf(s, "%s %02d%c%02d%c%04d", L_ON, d, DateSep,
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, d, DateSep,
|
||||
m+1, DateSep, y);
|
||||
}
|
||||
#endif
|
||||
@@ -279,10 +430,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_F_OVER
|
||||
L_F_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
} else {
|
||||
sprintf(s, "%s %02d%c%02d%c%04d", L_ON, m+1, DateSep, d, DateSep, y);
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d%c%04d", DynamicOn, m+1, DateSep, d, DateSep, y);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
@@ -292,10 +443,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_G_OVER
|
||||
L_G_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s, %d %s", get_day_name(jul%7), d, get_month_name(m));
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d %s", get_day_name(jul%7), d, get_month_name(m));
|
||||
} else {
|
||||
sprintf(s, "%s %s, %d %s", L_ON, get_day_name(jul%7), d, get_month_name(m));
|
||||
snprintf(s, sizeof(s), "%s %s, %d %s", DynamicOn, get_day_name(jul%7), d, get_month_name(m));
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
@@ -305,10 +456,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_H_OVER
|
||||
L_H_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%02d%c%02d", d, DateSep, m+1);
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", d, DateSep, m+1);
|
||||
} else {
|
||||
sprintf(s, "%s %02d%c%02d", L_ON, d, DateSep, m+1);
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, d, DateSep, m+1);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
@@ -318,10 +469,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_I_OVER
|
||||
L_I_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%02d%c%02d", m+1, DateSep, d);
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", m+1, DateSep, d);
|
||||
} else {
|
||||
sprintf(s, "%s %02d%c%02d", L_ON, m+1, DateSep, d);
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicOn, m+1, DateSep, d);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
@@ -331,11 +482,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_J_OVER
|
||||
L_J_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s, %s %d%s, %d", get_day_name(jul%7),
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %s %d%s, %d", get_day_name(jul%7),
|
||||
get_month_name(m), d, plu, y);
|
||||
} else {
|
||||
sprintf(s, "%s %s, %s %d%s, %d", L_ON, get_day_name(jul%7),
|
||||
snprintf(s, sizeof(s), "%s %s, %s %d%s, %d", DynamicOn, get_day_name(jul%7),
|
||||
get_month_name(m), d, plu, y);
|
||||
}
|
||||
#endif
|
||||
@@ -346,11 +497,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_K_OVER
|
||||
L_K_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s, %s %d%s", get_day_name(jul%7),
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %s %d%s", get_day_name(jul%7),
|
||||
get_month_name(m), d, plu);
|
||||
} else {
|
||||
sprintf(s, "%s %s, %s %d%s", L_ON, get_day_name(jul%7),
|
||||
snprintf(s, sizeof(s), "%s %s, %s %d%s", DynamicOn, get_day_name(jul%7),
|
||||
get_month_name(m), d, plu);
|
||||
}
|
||||
#endif
|
||||
@@ -361,10 +512,10 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_L_OVER
|
||||
L_L_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
} else {
|
||||
sprintf(s, "%s %04d%c%02d%c%02d", L_ON, y, DateSep, m+1, DateSep, d);
|
||||
snprintf(s, sizeof(s), "%s %04d%c%02d%c%02d", DynamicOn, y, DateSep, m+1, DateSep, d);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
@@ -374,7 +525,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_M_OVER
|
||||
L_M_OVER
|
||||
#else
|
||||
sprintf(s, "%s", get_month_name(m));
|
||||
snprintf(s, sizeof(s), "%s", get_month_name(m));
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -383,7 +534,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_N_OVER
|
||||
L_N_OVER
|
||||
#else
|
||||
sprintf(s, "%d", m+1);
|
||||
snprintf(s, sizeof(s), "%d", m+1);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -392,7 +543,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_O_OVER
|
||||
L_O_OVER
|
||||
#else
|
||||
if (RealToday == JulianToday) sprintf(s, " (%s)", L_TODAY);
|
||||
if (RealToday == JulianToday) snprintf(s, sizeof(s), " (%s)", DynamicToday);
|
||||
else *s = 0;
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
@@ -402,7 +553,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_P_OVER
|
||||
L_P_OVER
|
||||
#else
|
||||
sprintf(s, "%s", (diff == 1 ? "" : L_PLURAL));
|
||||
snprintf(s, sizeof(s), "%s", (diff == 1 ? "" : L_PLURAL));
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -411,7 +562,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_Q_OVER
|
||||
L_Q_OVER
|
||||
#else
|
||||
sprintf(s, "%s", (diff == 1 ? "'s" : "s'"));
|
||||
snprintf(s, sizeof(s), "%s", (diff == 1 ? "'s" : "s'"));
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -420,7 +571,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_R_OVER
|
||||
L_R_OVER
|
||||
#else
|
||||
sprintf(s, "%02d", d);
|
||||
snprintf(s, sizeof(s), "%02d", d);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -429,7 +580,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_S_OVER
|
||||
L_S_OVER
|
||||
#else
|
||||
sprintf(s, "%s", plu);
|
||||
snprintf(s, sizeof(s), "%s", plu);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -438,7 +589,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_T_OVER
|
||||
L_T_OVER
|
||||
#else
|
||||
sprintf(s, "%02d", m+1);
|
||||
snprintf(s, sizeof(s), "%02d", m+1);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -447,11 +598,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_U_OVER
|
||||
L_U_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s, %d%s %s, %d", get_day_name(jul%7), d,
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d%s %s, %d", get_day_name(jul%7), d,
|
||||
plu, get_month_name(m), y);
|
||||
} else {
|
||||
sprintf(s, "%s %s, %d%s %s, %d", L_ON, get_day_name(jul%7), d,
|
||||
snprintf(s, sizeof(s), "%s %s, %d%s %s, %d", DynamicOn, get_day_name(jul%7), d,
|
||||
plu, get_month_name(m), y);
|
||||
}
|
||||
#endif
|
||||
@@ -462,11 +613,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_V_OVER
|
||||
L_V_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s, %d%s %s", get_day_name(jul%7), d, plu,
|
||||
if (altmode == '*' || !strcmp(DynamicOn, "")) {
|
||||
snprintf(s, sizeof(s), "%s, %d%s %s", get_day_name(jul%7), d, plu,
|
||||
get_month_name(m));
|
||||
} else {
|
||||
sprintf(s, "%s %s, %d%s %s", L_ON, get_day_name(jul%7), d, plu,
|
||||
snprintf(s, sizeof(s), "%s %s, %d%s %s", DynamicOn, get_day_name(jul%7), d, plu,
|
||||
get_month_name(m));
|
||||
}
|
||||
#endif
|
||||
@@ -477,7 +628,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_W_OVER
|
||||
L_W_OVER
|
||||
#else
|
||||
sprintf(s, "%s", get_day_name(jul%7));
|
||||
snprintf(s, sizeof(s), "%s", get_day_name(jul%7));
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -486,7 +637,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_X_OVER
|
||||
L_X_OVER
|
||||
#else
|
||||
sprintf(s, "%d", diff);
|
||||
snprintf(s, sizeof(s), "%d", diff);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -495,7 +646,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_Y_OVER
|
||||
L_Y_OVER
|
||||
#else
|
||||
sprintf(s, "%d", y);
|
||||
snprintf(s, sizeof(s), "%d", y);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -504,7 +655,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_Z_OVER
|
||||
L_Z_OVER
|
||||
#else
|
||||
sprintf(s, "%d", y % 100);
|
||||
snprintf(s, sizeof(s), "%d", y % 100);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -514,14 +665,14 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
L_1_OVER
|
||||
#else
|
||||
if (tdiff == 0)
|
||||
sprintf(s, "%s", L_NOW);
|
||||
snprintf(s, sizeof(s), "%s", DynamicNow);
|
||||
else if (hdiff == 0)
|
||||
sprintf(s, "%d %s%s %s", mdiff, L_MINUTE, mplu, when);
|
||||
snprintf(s, sizeof(s), "%d %s%s %s", mdiff, DynamicMinute, mplu, when);
|
||||
else if (mdiff == 0)
|
||||
sprintf(s, "%d %s%s %s", hdiff, L_HOUR, hplu, when);
|
||||
snprintf(s, sizeof(s), "%d %s%s %s", hdiff, DynamicHour, hplu, when);
|
||||
else
|
||||
sprintf(s, "%d %s%s %s %d %s%s %s", hdiff, L_HOUR, hplu,
|
||||
L_AND, mdiff, L_MINUTE, mplu, when);
|
||||
snprintf(s, sizeof(s), "%d %s%s %s %d %s%s %s", hdiff, DynamicHour, hplu,
|
||||
DynamicAnd, mdiff, DynamicMinute, mplu, when);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -531,9 +682,9 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
L_2_OVER
|
||||
#else
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%d%c%02d%s", hh, TimeSep, min, pm);
|
||||
snprintf(s, sizeof(s), "%d%c%02d%s", hh, TimeSep, min, pm);
|
||||
} else {
|
||||
sprintf(s, "%s %d%c%02d%s", L_AT, hh, TimeSep, min, pm);
|
||||
snprintf(s, sizeof(s), "%s %d%c%02d%s", DynamicAt, hh, TimeSep, min, pm);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
@@ -545,9 +696,9 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#else
|
||||
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%02d%c%02d", h, TimeSep, min);
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", h, TimeSep, min);
|
||||
} else {
|
||||
sprintf(s, "%s %02d%c%02d", L_AT, h, TimeSep, min);
|
||||
snprintf(s, sizeof(s), "%s %02d%c%02d", DynamicAt, h, TimeSep, min);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
@@ -557,7 +708,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_4_OVER
|
||||
L_4_OVER
|
||||
#else
|
||||
sprintf(s, "%d", tdiff);
|
||||
snprintf(s, sizeof(s), "%d", tdiff);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -566,7 +717,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_5_OVER
|
||||
L_5_OVER
|
||||
#else
|
||||
sprintf(s, "%d", adiff);
|
||||
snprintf(s, sizeof(s), "%d", adiff);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -575,7 +726,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_6_OVER
|
||||
L_6_OVER
|
||||
#else
|
||||
sprintf(s, "%s", when);
|
||||
snprintf(s, sizeof(s), "%s", when);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -584,7 +735,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_7_OVER
|
||||
L_7_OVER
|
||||
#else
|
||||
sprintf(s, "%d", hdiff);
|
||||
snprintf(s, sizeof(s), "%d", hdiff);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -593,7 +744,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_8_OVER
|
||||
L_8_OVER
|
||||
#else
|
||||
sprintf(s, "%d", mdiff);
|
||||
snprintf(s, sizeof(s), "%d", mdiff);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -602,7 +753,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_9_OVER
|
||||
L_9_OVER
|
||||
#else
|
||||
sprintf(s, "%s", mplu);
|
||||
snprintf(s, sizeof(s), "%s", mplu);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -611,7 +762,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_0_OVER
|
||||
L_0_OVER
|
||||
#else
|
||||
sprintf(s, "%s", hplu);
|
||||
snprintf(s, sizeof(s), "%s", hplu);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -620,7 +771,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_BANG_OVER
|
||||
L_BANG_OVER
|
||||
#else
|
||||
sprintf(s, "%s", (tdiff >= 0 ? L_IS : L_WAS));
|
||||
snprintf(s, sizeof(s), "%s", (tdiff >= 0 ? DynamicIs : DynamicWas));
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -629,7 +780,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_AT_OVER
|
||||
L_AT_OVER
|
||||
#else
|
||||
sprintf(s, "%d%c%02d%s", chh, TimeSep, cmin, cpm);
|
||||
snprintf(s, sizeof(s), "%d%c%02d%s", chh, TimeSep, cmin, cpm);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -638,16 +789,16 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_HASH_OVER
|
||||
L_HASH_OVER
|
||||
#else
|
||||
sprintf(s, "%02d%c%02d", ch, TimeSep, cmin);
|
||||
snprintf(s, sizeof(s), "%02d%c%02d", ch, TimeSep, cmin);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '_':
|
||||
if (PsCal == PSCAL_LEVEL2 || PsCal == PSCAL_LEVEL3 || (mode != CAL_MODE && mode != ADVANCE_MODE && !MsgCommand)) {
|
||||
sprintf(s, "%s", NL);
|
||||
snprintf(s, sizeof(s), "%s", NL);
|
||||
} else {
|
||||
sprintf(s, " ");
|
||||
snprintf(s, sizeof(s), " ");
|
||||
}
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -657,8 +808,13 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
break;
|
||||
|
||||
case '"':
|
||||
if (DBufPutc(dbuf, QUOTE_MARKER) != OK) return E_NO_MEM;
|
||||
has_quote = 1;
|
||||
if (DontSuppressQuoteMarkers) {
|
||||
if (DBufPutc(dbuf, '%') != OK) return E_NO_MEM;
|
||||
if (DBufPutc(dbuf, c) != OK) return E_NO_MEM;
|
||||
} else {
|
||||
if (DBufPutc(dbuf, QUOTE_MARKER) != OK) return E_NO_MEM;
|
||||
has_quote = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* buffers. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Declaration of functions for manipulating dynamic buffers */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Error definitions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -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",
|
||||
|
||||
175
src/expr.c
175
src/expr.c
@@ -5,7 +5,7 @@
|
||||
/* This file contains routines to parse and evaluate */
|
||||
/* expressions. */
|
||||
/* */
|
||||
/* Copyright 1992-2021 by Dianne Skoll */
|
||||
/* Copyright 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -44,21 +44,32 @@ static int MakeValue (char const *s, Value *v, Var *locals, ParsePtr p);
|
||||
|
||||
/* Binary operators - all left-associative */
|
||||
|
||||
/* Operator precedence:
|
||||
* Highest: Unary - Unary !
|
||||
* / %
|
||||
* + -
|
||||
* < <= > >=
|
||||
* == !=
|
||||
* &&
|
||||
* Lowest: ||
|
||||
*
|
||||
*/
|
||||
|
||||
/* Make SURE they are sorted lexically... this may die on an EBCDIC
|
||||
system... */
|
||||
|
||||
Operator BinOp[] = {
|
||||
{ "!=", 15, BIN_OP, NotEqual },
|
||||
{ "%", 20, BIN_OP, Mod },
|
||||
{ "%", 20, BIN_OP, Mod },
|
||||
{ "&&", 14, BIN_OP, LogAND },
|
||||
{ "*", 20, BIN_OP, Multiply },
|
||||
{ "+", 18, BIN_OP, Add },
|
||||
{ "-", 18, BIN_OP, Subtract },
|
||||
{ "/", 20, BIN_OP, Divide },
|
||||
{ "<", 16, BIN_OP, LessThan },
|
||||
{ "*", 20, BIN_OP, Multiply },
|
||||
{ "+", 18, BIN_OP, Add },
|
||||
{ "-", 18, BIN_OP, Subtract },
|
||||
{ "/", 20, BIN_OP, Divide },
|
||||
{ "<", 16, BIN_OP, LessThan },
|
||||
{ "<=", 16, BIN_OP, LessOrEqual },
|
||||
{ "==", 15, BIN_OP, EqualTo },
|
||||
{ ">", 16, BIN_OP, GreaterThan },
|
||||
{ ">", 16, BIN_OP, GreaterThan },
|
||||
{ ">=", 16, BIN_OP, GreaterOrEqual },
|
||||
{ "||", 12, BIN_OP, LogOR },
|
||||
};
|
||||
@@ -66,16 +77,19 @@ Operator BinOp[] = {
|
||||
|
||||
/* These ones must be sorted too. */
|
||||
Operator UnOp[] = {
|
||||
{ "!", 22, UN_OP, LogNot },
|
||||
{ "-", 22, UN_OP, UnMinus },
|
||||
{ "!", 22, UN_OP, LogNot },
|
||||
{ "-", 22, UN_OP, UnMinus },
|
||||
};
|
||||
#define NUM_UN_OPS (sizeof(UnOp) / sizeof(Operator))
|
||||
|
||||
extern BuiltinFunc Func[];
|
||||
|
||||
Operator OpStack[OP_STACK_SIZE];
|
||||
Value ValStack[VAL_STACK_SIZE];
|
||||
int OpStackPtr, ValStackPtr;
|
||||
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;
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -115,12 +129,13 @@ static int DebugPerform(Operator *op)
|
||||
/* Clean the stack after an error occurs. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static void CleanStack(void)
|
||||
static void CleanStack(int old_op_stack_ptr, int old_val_stack_ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<ValStackPtr; i++) DestroyValue(ValStack[i]);
|
||||
ValStackPtr = 0;
|
||||
for (i=old_val_stack_ptr; i<ValStackPtr; i++) DestroyValue(ValStack[i]);
|
||||
ValStackPtr = old_val_stack_ptr;
|
||||
OpStackPtr = old_op_stack_ptr;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -238,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)++;
|
||||
@@ -306,8 +325,8 @@ int EvalExpr(char const **e, Value *v, ParsePtr p)
|
||||
{
|
||||
int r;
|
||||
|
||||
OpStackPtr = 0;
|
||||
ValStackPtr = 0;
|
||||
int old_op_stack_ptr = OpStackPtr;
|
||||
int old_val_stack_ptr = ValStackPtr;
|
||||
|
||||
r = Evaluate(e, NULL, p);
|
||||
|
||||
@@ -316,11 +335,15 @@ int EvalExpr(char const **e, Value *v, ParsePtr p)
|
||||
DBufFree(&ExprBuf);
|
||||
|
||||
if (r) {
|
||||
CleanStack();
|
||||
CleanStack(old_op_stack_ptr, old_val_stack_ptr);
|
||||
/* fprintf(stderr, "O=%d V=%d\n", OpStackPtr, ValStackPtr); */
|
||||
return r;
|
||||
}
|
||||
*v = *ValStack;
|
||||
ValStack[0].type = ERR_TYPE;
|
||||
OpStackPtr = old_op_stack_ptr;
|
||||
ValStackPtr = old_val_stack_ptr;
|
||||
*v = ValStack[old_val_stack_ptr];
|
||||
ValStack[old_val_stack_ptr].type = ERR_TYPE;
|
||||
/* fprintf(stderr, "O=%d V=%d\n", OpStackPtr, ValStackPtr); */
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -766,12 +789,11 @@ static int Add(void)
|
||||
|
||||
/* If both are ints, just add 'em */
|
||||
if (v2.type == INT_TYPE && v1.type == INT_TYPE) {
|
||||
int old = v1.v.val;
|
||||
v1.v.val += v2.v.val;
|
||||
/* Check for overflow */
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val, old)) {
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val)) {
|
||||
return E_2HIGH;
|
||||
}
|
||||
v1.v.val += v2.v.val;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
}
|
||||
@@ -779,9 +801,8 @@ static int Add(void)
|
||||
/* If it's a date plus an int, add 'em */
|
||||
if ((v1.type == DATE_TYPE && v2.type == INT_TYPE) ||
|
||||
(v1.type == INT_TYPE && v2.type == DATE_TYPE)) {
|
||||
int old = v1.v.val;
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val += v2.v.val;
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
|
||||
if (v1.v.val < 0) return E_DATE_OVER;
|
||||
v1.type = DATE_TYPE;
|
||||
PushValStack(v1);
|
||||
@@ -791,9 +812,8 @@ static int Add(void)
|
||||
/* If it's a datetime plus an int or a time, add 'em */
|
||||
if ((v1.type == DATETIME_TYPE && (v2.type == INT_TYPE || v2.type == TIME_TYPE)) ||
|
||||
((v1.type == INT_TYPE || v1.type == TIME_TYPE) && v2.type == DATETIME_TYPE)) {
|
||||
int old = v1.v.val;
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val += v2.v.val;
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
|
||||
if (v1.v.val < 0) return E_DATE_OVER;
|
||||
v1.type = DATETIME_TYPE;
|
||||
PushValStack(v1);
|
||||
@@ -805,9 +825,8 @@ static int Add(void)
|
||||
if ((v1.type == TIME_TYPE && v2.type == INT_TYPE) ||
|
||||
(v1.type == INT_TYPE && v2.type == TIME_TYPE) ||
|
||||
(v1.type == TIME_TYPE && v2.type == TIME_TYPE)) {
|
||||
int old = v1.v.val;
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val += v2.v.val;
|
||||
if (_private_add_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
|
||||
v1.v.val = v1.v.val % MINUTES_PER_DAY;
|
||||
if (v1.v.val < 0) v1.v.val += MINUTES_PER_DAY;
|
||||
v1.type = TIME_TYPE;
|
||||
@@ -868,18 +887,16 @@ static int Subtract(void)
|
||||
|
||||
/* If they're both INTs, do subtraction */
|
||||
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
|
||||
int old = v1.v.val;
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_2HIGH;
|
||||
v1.v.val -= v2.v.val;
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_2HIGH;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* If it's a date minus an int, do subtraction, checking for underflow */
|
||||
if (v1.type == DATE_TYPE && v2.type == INT_TYPE) {
|
||||
int old = v1.v.val;
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val -= v2.v.val;
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
|
||||
if (v1.v.val < 0) return E_DATE_OVER;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
@@ -888,9 +905,8 @@ static int Subtract(void)
|
||||
/* If it's a datetime minus an int or a time, do subtraction,
|
||||
* checking for underflow */
|
||||
if (v1.type == DATETIME_TYPE && (v2.type == INT_TYPE || v2.type == TIME_TYPE)) {
|
||||
int old = v1.v.val;
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val -= v2.v.val;
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
|
||||
if (v1.v.val < 0) return E_DATE_OVER;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
@@ -908,9 +924,8 @@ static int Subtract(void)
|
||||
if ((v1.type == TIME_TYPE && v2.type == TIME_TYPE) ||
|
||||
(v1.type == DATETIME_TYPE && v2.type == DATETIME_TYPE) ||
|
||||
(v1.type == DATE_TYPE && v2.type == DATE_TYPE)) {
|
||||
int old = v1.v.val;
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val)) return E_DATE_OVER;
|
||||
v1.v.val -= v2.v.val;
|
||||
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
|
||||
v1.type = INT_TYPE;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
@@ -945,11 +960,8 @@ static int Multiply(void)
|
||||
(v1.v.val == -1 && v2.v.val == INT_MIN)) {
|
||||
return E_2HIGH;
|
||||
}
|
||||
int old = v1.v.val;
|
||||
if (_private_mul_overflow(v1.v.val, v2.v.val)) return E_2HIGH;
|
||||
v1.v.val *= v2.v.val;
|
||||
if (v2.v.val != 0) {
|
||||
if (_private_div(v1.v.val, v2.v.val) != old) return E_2HIGH;
|
||||
}
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
}
|
||||
@@ -1108,13 +1120,16 @@ static int LogOR(void)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
|
||||
v1.v.val = (v1.v.val || v2.v.val) ? 1 : 0;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
if (v1.type != v2.type || v1.type == STR_TYPE || v2.type == STR_TYPE) {
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_BAD_TYPE;
|
||||
|
||||
if (v1.v.val == 0) {
|
||||
v1.v.val = v2.v.val;
|
||||
}
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1135,13 +1150,15 @@ static int LogAND(void)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
|
||||
v1.v.val = (v1.v.val && v2.v.val) ? 1 : 0;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
if (v1.type != v2.type || v1.type == STR_TYPE || v2.type == STR_TYPE) {
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_BAD_TYPE;
|
||||
if (v1.v.val != 0) {
|
||||
v1.v.val = v2.v.val;
|
||||
}
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -1155,9 +1172,8 @@ static int UnMinus(void)
|
||||
{
|
||||
Value *v = &ValStack[ValStackPtr-1];
|
||||
if (v->type != INT_TYPE) return E_BAD_TYPE;
|
||||
int old = v->v.val;
|
||||
if (v->v.val == INT_MIN) return E_2HIGH;
|
||||
v->v.val = -v->v.val;
|
||||
if (_private_unminus_overflow(old, v->v.val)) return E_2HIGH;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1178,9 +1194,9 @@ static int LogNot(void)
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindFunc */
|
||||
/* FindOperator */
|
||||
/* */
|
||||
/* Find a function. */
|
||||
/* Find an operator. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
Operator *FindOperator(char const *name, Operator where[], int num)
|
||||
@@ -1189,7 +1205,7 @@ Operator *FindOperator(char const *name, Operator where[], int num)
|
||||
int mid, r;
|
||||
while (top >= bot) {
|
||||
mid = (top + bot) / 2;
|
||||
r = StrCmpi(name, where[mid].name);
|
||||
r = strcmp(name, where[mid].name);
|
||||
if (!r) return &where[mid];
|
||||
else if (r > 0) bot = mid+1;
|
||||
else top = mid-1;
|
||||
@@ -1197,6 +1213,20 @@ Operator *FindOperator(char const *name, Operator where[], int num)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Compare two strings case-insensitively, where we KNOW
|
||||
that the second string is definitely lower-case */
|
||||
static int strcmp_lcfirst(char const *s1, char const *s2)
|
||||
{
|
||||
int r;
|
||||
while (*s1 && *s2) {
|
||||
r = tolower(*s1) - *s2;
|
||||
if (r) return r;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return tolower(*s1) - *s2;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindFunc */
|
||||
@@ -1210,7 +1240,7 @@ BuiltinFunc *FindFunc(char const *name, BuiltinFunc where[], int num)
|
||||
int mid, r;
|
||||
while (top >= bot) {
|
||||
mid = (top + bot) / 2;
|
||||
r = StrCmpi(name, where[mid].name);
|
||||
r = strcmp_lcfirst(name, where[mid].name);
|
||||
if (!r) return &where[mid];
|
||||
else if (r > 0) bot = mid+1;
|
||||
else top = mid-1;
|
||||
@@ -1228,12 +1258,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, "...");
|
||||
}
|
||||
|
||||
10
src/expr.h
10
src/expr.h
@@ -5,7 +5,7 @@
|
||||
/* Contains a few definitions used by expression evaluator. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -58,7 +58,7 @@ else \
|
||||
in various arithmetic operators. They have to be in separate
|
||||
functions with extern linkage to defeat compiler optimizations
|
||||
that would otherwise break the overflow checks. */
|
||||
extern int _private_div(int a, int b);
|
||||
extern int _private_add_overflow(int result, int b, int old);
|
||||
extern int _private_sub_overflow(int result, int b, int old);
|
||||
extern int _private_unminus_overflow(int a, int b);
|
||||
extern int _private_mul_overflow(int a, int b);
|
||||
extern int _private_add_overflow(int a, int b);
|
||||
extern int _private_sub_overflow(int a, int b);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/* files. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -163,6 +163,7 @@ int ReadLine(void)
|
||||
LineNo = CLine->LineNo;
|
||||
CLine = CLine->next;
|
||||
FreshLine = 1;
|
||||
clear_callstack();
|
||||
if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
|
||||
return OK;
|
||||
}
|
||||
@@ -263,6 +264,7 @@ static int ReadLineFromFile(int use_pclose)
|
||||
}
|
||||
|
||||
FreshLine = 1;
|
||||
clear_callstack();
|
||||
if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
|
||||
return OK;
|
||||
}
|
||||
@@ -818,6 +820,7 @@ static int IncludeCmd(char const *cmd)
|
||||
int old_flag;
|
||||
|
||||
FreshLine = 1;
|
||||
clear_callstack();
|
||||
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
@@ -935,6 +938,7 @@ int IncludeFile(char const *fname)
|
||||
struct stat statbuf;
|
||||
|
||||
FreshLine = 1;
|
||||
clear_callstack();
|
||||
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
|
||||
477
src/funcs.c
477
src/funcs.c
@@ -6,19 +6,26 @@
|
||||
/* expressions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#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,8 @@ 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 *);
|
||||
static int FAsc (func_info *);
|
||||
@@ -65,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 *);
|
||||
@@ -93,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 *);
|
||||
@@ -110,22 +121,27 @@ static int FNonomitted (func_info *);
|
||||
static int FNow (func_info *);
|
||||
static int FOrd (func_info *);
|
||||
static int FOstype (func_info *);
|
||||
static int FPad (func_info *);
|
||||
static int FPlural (func_info *);
|
||||
static int FPsmoon (func_info *);
|
||||
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 *);
|
||||
static int FTrigdate (func_info *);
|
||||
static int FTrigdatetime (func_info *);
|
||||
@@ -136,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 *);
|
||||
@@ -146,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 *);
|
||||
@@ -157,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
|
||||
@@ -210,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 },
|
||||
@@ -245,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 },
|
||||
@@ -262,23 +284,28 @@ BuiltinFunc Func[] = {
|
||||
{ "now", 0, 0, 0, FNow },
|
||||
{ "ord", 1, 1, 1, FOrd },
|
||||
{ "ostype", 0, 0, 1, FOstype },
|
||||
{ "pad", 3, 4, 1, FPad },
|
||||
{ "plural", 1, 3, 1, FPlural },
|
||||
{ "psmoon", 1, 4, 1, FPsmoon},
|
||||
{ "psshade", 1, 3, 1, FPsshade},
|
||||
{ "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 },
|
||||
{ "trigdate", 0, 0, 0, FTrigdate },
|
||||
{ "trigdatetime", 0, 0, 0, FTrigdatetime },
|
||||
@@ -291,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 },
|
||||
@@ -299,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 },
|
||||
@@ -897,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 */
|
||||
@@ -995,6 +1105,73 @@ static int FOrd(func_info *info)
|
||||
return RetStrVal(buf, info);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FPad - Pad a string to min length */
|
||||
/* */
|
||||
/* pad("1", "0", 4) --> "0004" */
|
||||
/* pad("1", "0", 4, 1) --> "4000" */
|
||||
/* pad("foo", "bar", 7) -> "barbfoo" */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int FPad(func_info *info)
|
||||
{
|
||||
int r;
|
||||
char *s;
|
||||
DynamicBuffer dbuf;
|
||||
size_t len;
|
||||
size_t wantlen;
|
||||
size_t i;
|
||||
|
||||
ASSERT_TYPE(1, STR_TYPE);
|
||||
ASSERT_TYPE(2, INT_TYPE);
|
||||
if (Nargs == 4) {
|
||||
ASSERT_TYPE(3, INT_TYPE);
|
||||
}
|
||||
|
||||
if (ARG(0).type != STR_TYPE) {
|
||||
r = DoCoerce(STR_TYPE, &ARG(0));
|
||||
if (r != OK) return r;
|
||||
}
|
||||
|
||||
wantlen = ARGV(2);
|
||||
len = strlen(ARGSTR(0));
|
||||
if (len >= wantlen) {
|
||||
DCOPYVAL(RetVal, ARG(0));
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (strlen(ARGSTR(1)) == 0) {
|
||||
return E_BAD_TYPE;
|
||||
}
|
||||
|
||||
if (MaxStringLen > 0 && wantlen > (size_t) MaxStringLen) {
|
||||
return E_STRING_TOO_LONG;
|
||||
}
|
||||
|
||||
DBufInit(&dbuf);
|
||||
s = ARGSTR(1);
|
||||
if (Nargs < 4 || !ARGV(3)) {
|
||||
/* Pad on the LEFT */
|
||||
for (i=0; i<wantlen-len; i++) {
|
||||
DBufPutc(&dbuf, *s++);
|
||||
if (!*s) s = ARGSTR(1);
|
||||
}
|
||||
DBufPuts(&dbuf, ARGSTR(0));
|
||||
} else {
|
||||
/* Pad on the RIGHT */
|
||||
DBufPuts(&dbuf, ARGSTR(0));
|
||||
for (i=0; i<wantlen-len; i++) {
|
||||
DBufPutc(&dbuf, *s++);
|
||||
if (!*s) s = ARGSTR(1);
|
||||
}
|
||||
}
|
||||
r = RetStrVal(DBufValue(&dbuf), info);
|
||||
DBufFree(&dbuf);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FPlural - pluralization function */
|
||||
@@ -1165,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" */
|
||||
@@ -1366,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;
|
||||
@@ -2122,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. */
|
||||
@@ -2234,10 +2554,10 @@ static int SunStuff(int rise, double cosz, int jul)
|
||||
/* Sometimes, we get roundoff error. Check for "reasonableness" of
|
||||
answer. */
|
||||
if (rise) {
|
||||
/* Sunrise so close to midnight it wrapped around -- permament light */
|
||||
/* Sunrise so close to midnight it wrapped around -- permanent light */
|
||||
if (hours >= 23) return NO_TIME;
|
||||
} else {
|
||||
/* Sunset so close to midnight it wrapped around -- permament light */
|
||||
/* Sunset so close to midnight it wrapped around -- permanent light */
|
||||
if (hours <= 1) return -NO_TIME;
|
||||
}
|
||||
return hours*60 + mins;
|
||||
@@ -2411,8 +2731,7 @@ static int FPsshade(func_info *info)
|
||||
|
||||
if (!psshade_warned) {
|
||||
psshade_warned = 1;
|
||||
Eprint("psshade() is deprecated; use SPECIAL SHADE instead.");
|
||||
FreshLine = 1;
|
||||
Wprint("psshade() is deprecated; use SPECIAL SHADE instead.");
|
||||
}
|
||||
|
||||
sprintf(s, "/_A LineWidth 2 div def ");
|
||||
@@ -2467,8 +2786,7 @@ static int FPsmoon(func_info *info)
|
||||
}
|
||||
if (!psmoon_warned) {
|
||||
psmoon_warned = 1;
|
||||
Eprint("psmoon() is deprecated; use SPECIAL MOON instead.");
|
||||
FreshLine = 1;
|
||||
Wprint("psmoon() is deprecated; use SPECIAL MOON instead.");
|
||||
}
|
||||
if (size > 0) {
|
||||
sprintf(sizebuf, "%d", size);
|
||||
@@ -2825,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--;
|
||||
}
|
||||
@@ -2837,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++;
|
||||
}
|
||||
@@ -2971,8 +3289,12 @@ FEvalTrig(func_info *info)
|
||||
CreateParser(ARGSTR(0), &p);
|
||||
p.allownested = 0;
|
||||
r = ParseRem(&p, &trig, &tim, 0);
|
||||
if (r) return r;
|
||||
if (r) {
|
||||
DestroyParser(&p);
|
||||
return r;
|
||||
}
|
||||
if (trig.typ != NO_TYPE) {
|
||||
DestroyParser(&p);
|
||||
FreeTrig(&trig);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
@@ -2981,7 +3303,7 @@ FEvalTrig(func_info *info)
|
||||
} else {
|
||||
/* Hokey... */
|
||||
if (trig.scanfrom != JulianToday) {
|
||||
Eprint("Warning: SCANFROM is ignored in two-argument form of evaltrig()");
|
||||
Wprint("Warning: SCANFROM is ignored in two-argument form of evaltrig()");
|
||||
}
|
||||
jul = ComputeTrigger(scanfrom, &trig, &tim, &r, 0);
|
||||
}
|
||||
@@ -2990,6 +3312,7 @@ FEvalTrig(func_info *info)
|
||||
jul = -1;
|
||||
}
|
||||
FreeTrig(&trig);
|
||||
DestroyParser(&p);
|
||||
if (r) return r;
|
||||
if (jul < 0) {
|
||||
RetVal.type = INT_TYPE;
|
||||
@@ -3003,3 +3326,133 @@ FEvalTrig(func_info *info)
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int LastTrig = 0;
|
||||
static int
|
||||
FTrig(func_info *info)
|
||||
{
|
||||
Parser p;
|
||||
Trigger trig;
|
||||
TimeTrig tim;
|
||||
int jul;
|
||||
int r;
|
||||
int i;
|
||||
|
||||
RetVal.type = DATE_TYPE;
|
||||
if (Nargs == 0) {
|
||||
RETVAL = LastTrig;
|
||||
return OK;
|
||||
}
|
||||
|
||||
for (i=0; i<Nargs; i++) {
|
||||
ASSERT_TYPE(i, STR_TYPE);
|
||||
}
|
||||
|
||||
RETVAL = 0;
|
||||
|
||||
for (i=0; i<Nargs; i++) {
|
||||
CreateParser(ARGSTR(i), &p);
|
||||
p.allownested = 0;
|
||||
r = ParseRem(&p, &trig, &tim, 0);
|
||||
if (r) {
|
||||
DestroyParser(&p);
|
||||
return r;
|
||||
}
|
||||
if (trig.typ != NO_TYPE) {
|
||||
DestroyParser(&p);
|
||||
FreeTrig(&trig);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
jul = ComputeTrigger(trig.scanfrom, &trig, &tim, &r, 0);
|
||||
|
||||
if (r == E_CANT_TRIG) {
|
||||
DestroyParser(&p);
|
||||
FreeTrig(&trig);
|
||||
continue;
|
||||
}
|
||||
if (ShouldTriggerReminder(&trig, &tim, jul, &r)) {
|
||||
LastTrig = jul;
|
||||
RETVAL = jul;
|
||||
DestroyParser(&p);
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
DestroyParser(&p);
|
||||
FreeTrig(&trig);
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
@@ -8,15 +8,16 @@
|
||||
/* globals.h and err.h */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h> /* For defintion of FILE - sigh! */
|
||||
#include <stdio.h> /* For definition of FILE - sigh! */
|
||||
#include "types.h"
|
||||
#include "custom.h"
|
||||
#include "lang.h"
|
||||
#define MK_GLOBALS 1
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
115
src/globals.h
115
src/globals.h
@@ -11,6 +11,7 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
#undef EXTERN
|
||||
#define EXTERN
|
||||
@@ -24,6 +25,10 @@
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
EXTERN FILE *ErrFp;
|
||||
|
||||
#include "dynbuf.h"
|
||||
#include "lang.h"
|
||||
|
||||
#define MAX_TRUSTED_USERS 20
|
||||
|
||||
@@ -53,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);
|
||||
@@ -75,6 +81,8 @@ 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);
|
||||
EXTERN INIT( int NumQueued, 0);
|
||||
@@ -88,13 +96,12 @@ EXTERN INIT( int DefaultColorB, -1);
|
||||
EXTERN INIT( int DefaultColorG, -1);
|
||||
EXTERN INIT( int SynthesizeTags, 0);
|
||||
EXTERN INIT( int ScFormat, SC_AMPM);
|
||||
EXTERN INIT( int MaxSatIter, 150);
|
||||
EXTERN INIT( int MaxSatIter, 1000);
|
||||
EXTERN INIT( int MaxStringLen, MAX_STR_LEN);
|
||||
EXTERN INIT( char *FileName, NULL);
|
||||
EXTERN INIT( int UseStdin, 0);
|
||||
EXTERN INIT( int PurgeMode, 0);
|
||||
EXTERN INIT( int PurgeIncludeDepth, 0);
|
||||
EXTERN FILE *ErrFp;
|
||||
EXTERN INIT( FILE *PurgeFP, NULL);
|
||||
EXTERN INIT( int NumIfs, 0);
|
||||
EXTERN INIT( unsigned int IfFlags, 0);
|
||||
@@ -106,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);
|
||||
@@ -141,11 +150,6 @@ EXTERN INIT( int SubsIndent, 0);
|
||||
EXTERN INIT( char *EndSent, ".?!");
|
||||
EXTERN INIT( char *EndSentIg, "\"')]}>");
|
||||
|
||||
/* We need the language stuff here... */
|
||||
|
||||
#include "lang.h"
|
||||
#include "dynbuf.h"
|
||||
|
||||
EXTERN DynamicBuffer Banner;
|
||||
EXTERN DynamicBuffer LineBuffer;
|
||||
EXTERN DynamicBuffer ExprBuf;
|
||||
@@ -227,3 +231,98 @@ EXTERN int MonthIndex[2][12]
|
||||
#endif
|
||||
;
|
||||
|
||||
EXTERN char *DynamicAgo
|
||||
#ifdef MK_GLOBALS
|
||||
= L_AGO
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicAm
|
||||
#ifdef MK_GLOBALS
|
||||
= L_AM
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicAnd
|
||||
#ifdef MK_GLOBALS
|
||||
= L_AND
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicAt
|
||||
#ifdef MK_GLOBALS
|
||||
= L_AT
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicFromnow
|
||||
#ifdef MK_GLOBALS
|
||||
= L_FROMNOW
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicHour
|
||||
#ifdef MK_GLOBALS
|
||||
= L_HOUR
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicHplu
|
||||
#ifdef MK_GLOBALS
|
||||
= L_HPLU
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicIs
|
||||
#ifdef MK_GLOBALS
|
||||
= L_IS
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicMinute
|
||||
#ifdef MK_GLOBALS
|
||||
= L_MINUTE
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicMplu
|
||||
#ifdef MK_GLOBALS
|
||||
= L_MPLU
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicNow
|
||||
#ifdef MK_GLOBALS
|
||||
= L_NOW
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicOn
|
||||
#ifdef MK_GLOBALS
|
||||
= L_ON
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicPm
|
||||
#ifdef MK_GLOBALS
|
||||
= L_PM
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicToday
|
||||
#ifdef MK_GLOBALS
|
||||
= L_TODAY
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicTomorrow
|
||||
#ifdef MK_GLOBALS
|
||||
= L_TOMORROW
|
||||
#endif
|
||||
;
|
||||
EXTERN char *DynamicWas
|
||||
#ifdef MK_GLOBALS
|
||||
= L_WAS
|
||||
#endif
|
||||
;
|
||||
|
||||
#define XSTR(x) #x
|
||||
#define STRSYSDIR(x) XSTR(x)
|
||||
|
||||
EXTERN char *SysDir
|
||||
#ifdef MK_GLOBALS
|
||||
= STRSYSDIR(SYSDIR)
|
||||
#endif
|
||||
;
|
||||
|
||||
EXTERN int SuppressLRM
|
||||
#ifdef MK_GLOBALS
|
||||
= 0
|
||||
#endif
|
||||
;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Support for the Hebrew calendar */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/* Derived from code written by Amos Shapir in 1978; revised */
|
||||
/* 1985. */
|
||||
|
||||
113
src/init.c
113
src/init.c
@@ -7,7 +7,7 @@
|
||||
/* in normal mode. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -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>
|
||||
@@ -30,10 +34,10 @@
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "globals.h"
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
#include "err.h"
|
||||
#include "globals.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,20 +165,14 @@ 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);
|
||||
DBufInit(&LineBuffer);
|
||||
@@ -232,17 +250,37 @@ void InitRemind(int argc, char const *argv[])
|
||||
Use256Colors = 1;
|
||||
} else if (x == 2) {
|
||||
UseTrueColors = 1;
|
||||
}
|
||||
} else if (x != 0) {
|
||||
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;
|
||||
}
|
||||
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':
|
||||
@@ -459,6 +497,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
DoSimpleCalendar = 1;
|
||||
PsCal = PSCAL_LEVEL1;
|
||||
while (*arg == 'a' || *arg == 'A' ||
|
||||
*arg == 'q' || *arg == 'Q' ||
|
||||
*arg == 'p' || *arg == 'P') {
|
||||
if (*arg == 'a' || *arg == 'A') {
|
||||
DoSimpleCalDelta = 1;
|
||||
@@ -471,7 +510,9 @@ void InitRemind(int argc, char const *argv[])
|
||||
} else {
|
||||
PsCal = PSCAL_LEVEL3;
|
||||
}
|
||||
}
|
||||
} else if (*arg == 'q' || *arg == 'Q') {
|
||||
DontSuppressQuoteMarkers = 1;
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
PARSENUM(CalMonths, arg);
|
||||
@@ -486,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++;
|
||||
@@ -672,7 +729,7 @@ void InitRemind(int argc, char const *argv[])
|
||||
#ifndef L_USAGE_OVERRIDE
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
@@ -680,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");
|
||||
@@ -698,7 +755,7 @@ void Usage(void)
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline f=tracefiles\n");
|
||||
fprintf(ErrFp, " -e Divert messages normally sent to stderr to stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Time format for cal: 0=am/pm, 1=24hr, 2=none\n");
|
||||
fprintf(ErrFp, " -x[n] Iteration limit for SATISFY clause (def=150)\n");
|
||||
fprintf(ErrFp, " -x[n] Iteration limit for SATISFY clause (def=1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Run `cmd' for MSG-type reminders\n");
|
||||
fprintf(ErrFp, " -g[dddd] Sort reminders by date, time, priority, and 'timedness'\n");
|
||||
fprintf(ErrFp, " -ivar=val Initialize var to val and preserve var\n");
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Header file for language support for various languages. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1993 by Mogens Lynnerup. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -48,9 +48,6 @@
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "siden"
|
||||
#define L_FROMNOW "fra nu"
|
||||
@@ -91,5 +88,3 @@
|
||||
#define L_I_OVER sprintf(s, "den %02d%c%02d", m+1, DateSep, d);
|
||||
#define L_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
/* Further corrections by Erik-Jan Vens */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -52,9 +52,6 @@
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "geleden"
|
||||
#define L_FROMNOW "vanaf nu"
|
||||
@@ -91,15 +88,14 @@ if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "%d %s %s", mdiff, \
|
||||
(mdiff == 1 ? "minuut" : "minuten"), when); \
|
||||
((mdiff == 1) ? "minuut" : "minuten"), when); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "%d %s %s", hdiff, \
|
||||
(mdiff == 1 ? "uur" : "uren"), when); \
|
||||
else sprintf(s, "%d %s %s %d %s %s", hdiff, \
|
||||
(hdiff == 1 ? "uur" : "uren"), \
|
||||
L_AND, mdiff, \
|
||||
(mdiff == 1 ? "minuut" : "minuten"), \
|
||||
when);
|
||||
((hdiff == 1) ? "uur" : "uren"), when); \
|
||||
else sprintf(s, "%d %s %s %d %s %s", hdiff, \
|
||||
(hdiff == 1 ? "uur" : "uren"), \
|
||||
L_AND, mdiff, \
|
||||
(mdiff == 1 ? "minuut" : "minuten"), \
|
||||
when);
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Support for the English language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -46,9 +46,6 @@
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "ago"
|
||||
#define L_FROMNOW "from now"
|
||||
@@ -72,11 +69,9 @@
|
||||
#define L_WAS "was"
|
||||
#define L_AND "and"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "s"
|
||||
#define L_HPLU "s"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "s"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* This file is Copyright (C) 1993-1998 by Mikko Silvonen. */
|
||||
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -52,9 +52,6 @@
|
||||
#define L_AM " ap."
|
||||
#define L_PM " ip."
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "sitten"
|
||||
#define L_FROMNOW "kuluttua"
|
||||
@@ -138,7 +135,6 @@ else { \
|
||||
} \
|
||||
sprintf(s + strlen(s), when); \
|
||||
}
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
@@ -199,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",
|
||||
@@ -257,7 +253,7 @@ EXTERN char *ErrMsg[] =
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETAVERSIO <<<<\n");
|
||||
#endif
|
||||
@@ -283,7 +279,7 @@ void Usage(void)
|
||||
fprintf(ErrFp, " -d... Virheenetsintä: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Ohjaa virhetulostus stdout-vuohon\n");
|
||||
fprintf(ErrFp, " -b[n] Ajan ilmaisu: 0=ap/ip, 1=24 tuntia, 2=ei aikoja\n");
|
||||
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 150)\n");
|
||||
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
|
||||
fprintf(ErrFp, " -g[ddd] Lajittele viestit päiväyksen, ajan ja tärkeyden mukaan\n");
|
||||
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja säilytä var\n");
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1993 by Laurent Duperval and */
|
||||
/* Dianne Skoll. */
|
||||
/* */
|
||||
@@ -51,9 +51,6 @@
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "il y a"
|
||||
#define L_FROMNOW "dans"
|
||||
@@ -113,8 +110,6 @@ else if (tdiff < 0) { \
|
||||
|
||||
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s", DayName[jul%7], d, plu, MonthName[m]); } else { sprintf(s, "%s %s, %d%s %s", L_ON, DayName[jul%7], d, plu, MonthName[m]); }
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
@@ -232,7 +227,7 @@ EXTERN char *ErrMsg[] =
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
@@ -258,7 +253,7 @@ void Usage(void)
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Envoyer les messages de stderr à stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Formats de l'heure pour le calendrier: 0=am/pm, 1=24hr, 2=aucun\n");
|
||||
fprintf(ErrFp, " -x[n] Limite d'itérations pour la clause SATISFY (def=150)\n");
|
||||
fprintf(ErrFp, " -x[n] Limite d'itérations pour la clause SATISFY (def=1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Exécuter 'cmd' pour les rappels de type MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorité avant d'émettre\n");
|
||||
fprintf(ErrFp, " -ivar=val Initialiser var à val et conserver var\n");
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/* I don't speak German. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -50,9 +50,6 @@
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "vorher"
|
||||
#define L_FROMNOW "von heute"
|
||||
@@ -88,5 +85,3 @@
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); }
|
||||
#define L_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
/* Support for the Icelandic language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -15,59 +15,56 @@
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "sunnudagur"
|
||||
#define L_MONDAY "mánudagur"
|
||||
#define L_TUESDAY "þriðjudagur"
|
||||
#define L_WEDNESDAY "miðvikudagur"
|
||||
#define L_MONDAY "mánudagur"
|
||||
#define L_TUESDAY "þriðjudagur"
|
||||
#define L_WEDNESDAY "miðvikudagur"
|
||||
#define L_THURSDAY "fimmtudagur"
|
||||
#define L_FRIDAY "föstudagur"
|
||||
#define L_FRIDAY "föstudagur"
|
||||
#define L_SATURDAY "laugardagur"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "janúar"
|
||||
#define L_FEB "febrúar"
|
||||
#define L_JAN "janúar"
|
||||
#define L_FEB "febrúar"
|
||||
#define L_MAR "mars"
|
||||
#define L_APR "apríl"
|
||||
#define L_MAY "maí"
|
||||
#define L_JUN "júní"
|
||||
#define L_JUL "júlí"
|
||||
#define L_AUG "ágúst"
|
||||
#define L_APR "apríl"
|
||||
#define L_MAY "maí"
|
||||
#define L_JUN "júní"
|
||||
#define L_JUL "júlí"
|
||||
#define L_AUG "ágúst"
|
||||
#define L_SEP "september"
|
||||
#define L_OCT "október"
|
||||
#define L_NOV "nóvember"
|
||||
#define L_OCT "október"
|
||||
#define L_NOV "nóvember"
|
||||
#define L_DEC "desember"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "í dag"
|
||||
#define L_TOMORROW "á morgun"
|
||||
#define L_TODAY "í dag"
|
||||
#define L_TOMORROW "á morgun"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Minnisatriði: %w, %d%s %m, %y%o:"
|
||||
#define L_BANNER "Minnisatriði: %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "fh"
|
||||
#define L_PM "eh"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "síðan"
|
||||
#define L_FROMNOW "frá því nú"
|
||||
#define L_AGO "síðan"
|
||||
#define L_FROMNOW "frá því nú"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "eftir %d daga"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "þann"
|
||||
#define L_ON "þann"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "a"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "núna"
|
||||
#define L_NOW "núna"
|
||||
#define L_AT "kl."
|
||||
#define L_MINUTE "mínútu"
|
||||
#define L_MINUTE "mínútu"
|
||||
#define L_HOUR "klukkustund"
|
||||
#define L_IS "er"
|
||||
#define L_WAS "var"
|
||||
@@ -79,5 +76,3 @@
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/* This file is part of REMIND. */
|
||||
/* It is Copyright (C) 1996 by Valerio Aimale */
|
||||
/* */
|
||||
/* Remind is copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Remind is copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -49,9 +49,6 @@
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "fa"
|
||||
#define L_FROMNOW "da oggi"
|
||||
@@ -114,6 +111,3 @@
|
||||
|
||||
#define L_V_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, \
|
||||
MonthName[m]);
|
||||
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* This file is Copyright (C) 1993 by Trygve Randen. */
|
||||
/* Remind is Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Remind is Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -47,9 +47,6 @@
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "siden"
|
||||
#define L_FROMNOW "fra nå"
|
||||
@@ -84,6 +81,3 @@
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); }
|
||||
#define L_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/* Polish. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -50,9 +50,6 @@
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "temu"
|
||||
#define L_FROMNOW "od teraz"
|
||||
@@ -75,13 +72,17 @@
|
||||
# define L_IS "będzie"
|
||||
# define L_WAS "było"
|
||||
#define L_AND "i"
|
||||
|
||||
#define L_HPLU ""
|
||||
#define L_MPLU ""
|
||||
|
||||
/* What to add to make "hour" or "minute" plural */
|
||||
#define L_NPLU( N ) ((N == 1) ? "ę" : ((N==12) || (N==13) || (N==14)) ? "" : \
|
||||
((N%10==2) || (N%10==3) || (N%10==4)) ? "y" : "" )
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU L_NPLU( hdiff )
|
||||
#define L_HPLU_OVER hplu = L_NPLU( hdiff );
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU L_NPLU( mdiff )
|
||||
#define L_MPLU_OVER mplu = L_NPLU( mdiff );
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
@@ -99,32 +100,30 @@ ampm = (hour<12) ? \
|
||||
#define L_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
#define L_0_OVER sprintf(s, L_HPLU);
|
||||
#define L_9_OVER sprintf(s, L_MPLU);
|
||||
#define L_0_OVER sprintf(s, L_NPLU(hdiff));
|
||||
#define L_9_OVER sprintf(s, L_NPLU(mdiff));
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (tdiff > 0) \
|
||||
{ \
|
||||
if (hdiff == 0) \
|
||||
sprintf(s, "za %d %s%s", mdiff, L_MINUTE, L_MPLU); \
|
||||
sprintf(s, "za %d %s%s", mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "za %d %s%s", hdiff, L_HOUR, L_HPLU); \
|
||||
sprintf(s, "za %d %s%s", hdiff, L_HOUR, L_NPLU(hdiff)); \
|
||||
else \
|
||||
sprintf(s, "za %d %s%s %s %d %s%s", hdiff, L_HOUR, L_HPLU, \
|
||||
L_AND, mdiff, L_MINUTE, L_MPLU); \
|
||||
sprintf(s, "za %d %s%s %s %d %s%s", hdiff, L_HOUR, L_NPLU(hdiff), \
|
||||
L_AND, mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (hdiff == 0) \
|
||||
sprintf(s, "%d %s%s temu", mdiff, L_MINUTE, L_MPLU); \
|
||||
sprintf(s, "%d %s%s temu", mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "%d %s%s temu", hdiff, L_HOUR, L_HPLU); \
|
||||
sprintf(s, "%d %s%s temu", hdiff, L_HOUR, L_NPLU(hdiff)); \
|
||||
else \
|
||||
sprintf(s, "%d %s%s %s %d %s%s temu", hdiff, L_HOUR, L_HPLU, \
|
||||
L_AND, mdiff, L_MINUTE, L_MPLU); \
|
||||
sprintf(s, "%d %s%s %s %d %s%s temu", hdiff, L_HOUR, L_NPLU(hdiff), \
|
||||
L_AND, mdiff, L_MINUTE, L_NPLU(mdiff)); \
|
||||
}
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
@@ -186,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",
|
||||
@@ -244,7 +243,7 @@ EXTERN char *ErrMsg[] =
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
@@ -270,7 +269,7 @@ void Usage(void)
|
||||
fprintf(ErrFp, " -d... Odpluskwianie: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Komunikaty o błędach skieruj na stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=żaden\n");
|
||||
fprintf(ErrFp, " -x[n] Limit powtórzeń klauzuli SATISFY (domyślnie=150)\n");
|
||||
fprintf(ErrFp, " -x[n] Limit powtórzeń klauzuli SATISFY (domyślnie=1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Wywołaj 'cmd' dla przypomnień typu MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia według daty, czasu i priorytetu\n");
|
||||
fprintf(ErrFp, " -ivar=val Zainicjuj zmienną var wartościa val i zachowaj ja\n");
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1996 by Marco Paganini and */
|
||||
/* Dianne Skoll. */
|
||||
/* */
|
||||
@@ -51,9 +51,6 @@
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "atras"
|
||||
#define L_FROMNOW "adiante"
|
||||
@@ -138,8 +135,6 @@
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
@@ -199,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",
|
||||
@@ -257,7 +252,7 @@ EXTERN char *ErrMsg[] =
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2022 Dianne Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> VERSAO BETA <<<<\n");
|
||||
#endif
|
||||
@@ -283,7 +278,7 @@ void Usage(void)
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trigger v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Desvia mensagens normalmente enviadas a stderr para stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Formato da hora para o cal: 0=am/pm, 1=24hr, 2=nenhum\n");
|
||||
fprintf(ErrFp, " -x[n] Limite de iteracoes para a clausula SATISFY (default=150)\n");
|
||||
fprintf(ErrFp, " -x[n] Limite de iteracoes para a clausula SATISFY (default=1000)\n");
|
||||
fprintf(ErrFp, " -kcmd Executa `cmd' para os compromissos com MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Classifica compromissos por data, hora e prioridade antes de exibir\n");
|
||||
fprintf(ErrFp, " -ivar=val Inicializa (e preserva) variavel var com val\n");
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* This file is Copyright (C) 1996-1998 by Liviu Daia */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
@@ -50,9 +50,6 @@
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
#ifdef L_IN_DOSUBST
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "acum"
|
||||
#define L_FROMNOW "peste"
|
||||
@@ -76,6 +73,7 @@
|
||||
#define L_WAS "a fost"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "e"
|
||||
#define L_HPLU "e"
|
||||
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU_OVER hplu = (hdiff == 1 ? "ă" : "e");
|
||||
@@ -104,5 +102,3 @@
|
||||
else \
|
||||
sprintf(s, "%s %d %s%s %s %d %s%s", when, hdiff, \
|
||||
L_HOUR, hplu, L_AND, mdiff, L_MINUTE, mplu);
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/* Author: Rafa Couto <rafacouto@biogate.com> */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -47,9 +47,6 @@
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Hace y desde hoy */
|
||||
#define L_AGO "hace"
|
||||
#define L_FROMNOW "desde hoy"
|
||||
@@ -74,5 +71,3 @@
|
||||
#define L_HPLU "s"
|
||||
#define L_MPLU "s"
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
|
||||
268
src/main.c
268
src/main.c
@@ -6,12 +6,14 @@
|
||||
/* routines, etc. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#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))) {
|
||||
@@ -169,6 +176,8 @@ static void DoReminders(void)
|
||||
Parser p;
|
||||
int purge_handled;
|
||||
|
||||
DidMsgReminder = 0;
|
||||
|
||||
if (!UseStdin) {
|
||||
FileAccessDate = GetAccessDate(InitialFile);
|
||||
} else {
|
||||
@@ -176,7 +185,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 +262,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 +339,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 +369,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;
|
||||
}
|
||||
|
||||
@@ -568,6 +585,29 @@ int EvaluateExpr(ParsePtr p, Value *v)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* Wprint - print a warning message. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void Wprint(char const *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
||||
|
||||
if (FileName) {
|
||||
if (strcmp(FileName, "-"))
|
||||
(void) fprintf(ErrFp, "%s(%d): ", FileName, LineNo);
|
||||
else
|
||||
(void) fprintf(ErrFp, "-stdin-(%d): ", LineNo);
|
||||
}
|
||||
|
||||
va_start(argptr, fmt);
|
||||
(void) vfprintf(ErrFp, fmt, argptr);
|
||||
(void) fputc('\n', ErrFp);
|
||||
va_end(argptr);
|
||||
return;
|
||||
}
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* Eprint - print an error message. */
|
||||
@@ -582,13 +622,23 @@ void Eprint(char const *fmt, ...)
|
||||
|
||||
if (FreshLine && FileName) {
|
||||
FreshLine = 0;
|
||||
if (strcmp(FileName, "-"))
|
||||
if (strcmp(FileName, "-")) {
|
||||
(void) fprintf(ErrFp, "%s(%d): ", FileName, LineNo);
|
||||
else
|
||||
if (print_callstack(ErrFp)) {
|
||||
(void) fprintf(ErrFp, ": ");
|
||||
}
|
||||
} else {
|
||||
(void) fprintf(ErrFp, "-stdin-(%d): ", LineNo);
|
||||
if (print_callstack(ErrFp)) {
|
||||
(void) fprintf(ErrFp, ": ");
|
||||
}
|
||||
}
|
||||
if (DebugFlag & DB_PRTLINE) OutputLine(ErrFp);
|
||||
} else if (FileName) {
|
||||
fprintf(ErrFp, " ");
|
||||
if (print_callstack(ErrFp)) {
|
||||
(void) fprintf(ErrFp, ": ");
|
||||
}
|
||||
}
|
||||
|
||||
va_start(argptr, fmt);
|
||||
@@ -824,19 +874,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++;
|
||||
@@ -1112,8 +1162,8 @@ int DoErrMsg(ParsePtr p)
|
||||
|
||||
/* The array FoldArray[2][7] contains sample years which begin
|
||||
on the specified weekday. For example, FoldArray[0][2] is a
|
||||
non-leapyear beginning on Wednesday, and FoldArray[1][5] is a
|
||||
leapyear beginning on Saturday. Used to fold back dates which
|
||||
non-leap year beginning on Wednesday, and FoldArray[1][5] is a
|
||||
leap year beginning on Saturday. Used to fold back dates which
|
||||
are too high for the standard Unix representation.
|
||||
NOTE: This implies that you cannot set BASE > 2001!!!!! */
|
||||
static int FoldArray[2][7] = {
|
||||
@@ -1143,6 +1193,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;
|
||||
@@ -1171,6 +1223,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 */
|
||||
@@ -1197,11 +1387,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) {
|
||||
@@ -1232,10 +1428,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) {
|
||||
@@ -1324,13 +1533,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
|
||||
@@ -1371,6 +1590,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;
|
||||
@@ -1391,8 +1611,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
|
||||
|
||||
22
src/moon.c
22
src/moon.c
@@ -5,7 +5,7 @@
|
||||
/* Calculations for figuring out moon phases. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -400,8 +400,8 @@ static double phase(double pdate,
|
||||
double *suangdia)
|
||||
{
|
||||
|
||||
double Day, N, M, Ec, Lambdasun, ml, MM, MN, Ev, Ae, A3, MmP,
|
||||
mEc, A4, lP, V, lPP, NP, y, x, Lambdamoon,
|
||||
double Day, N, M, Ec, Lambdasun, ml, MM, Ev, Ae, A3, MmP,
|
||||
mEc, A4, lP, V, lPP,
|
||||
MoonAge, MoonPhase,
|
||||
MoonDist, MoonDFrac, MoonAng,
|
||||
F, SunDist, SunAng;
|
||||
@@ -431,9 +431,6 @@ static double phase(double pdate,
|
||||
/* Moon's mean anomaly */
|
||||
MM = fixangle(ml - 0.1114041 * Day - mmlongp);
|
||||
|
||||
/* Moon's ascending node mean longitude */
|
||||
MN = fixangle(mlnode - 0.0529539 * Day);
|
||||
|
||||
/* Evection */
|
||||
Ev = 1.2739 * sin(torad(2 * (ml - Lambdasun) - MM));
|
||||
|
||||
@@ -461,19 +458,6 @@ static double phase(double pdate,
|
||||
/* 1 longitude */
|
||||
lPP = lP + V;
|
||||
|
||||
/* Corrected longitude of the node */
|
||||
NP = MN - 0.16 * sin(torad(M));
|
||||
|
||||
/* Y inclination coordinate */
|
||||
y = sin(torad(lPP - NP)) * cos(torad(minc));
|
||||
|
||||
/* X inclination coordinate */
|
||||
x = cos(torad(lPP - NP));
|
||||
|
||||
/* Ecliptic longitude */
|
||||
Lambdamoon = todeg(atan2(y, x));
|
||||
Lambdamoon += NP;
|
||||
|
||||
/* Calculation of the phase of the Moon */
|
||||
|
||||
/* Age of the Moon in degrees */
|
||||
|
||||
260
src/omit.c
260
src/omit.c
@@ -6,7 +6,7 @@
|
||||
/* the data structures for OMITted dates. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -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) {
|
||||
Eprint("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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
23
src/protos.h
23
src/protos.h
@@ -5,7 +5,7 @@
|
||||
/* Function Prototypes. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -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);
|
||||
@@ -62,6 +64,7 @@ int EvaluateExpr (ParsePtr p, Value *v);
|
||||
int Evaluate (char const **s, Var *locals, ParsePtr p);
|
||||
int FnPopValStack (Value *val);
|
||||
void Eprint (char const *fmt, ...);
|
||||
void Wprint (char const *fmt, ...);
|
||||
void OutputLine (FILE *fp);
|
||||
void CreateParser (char const *s, ParsePtr p);
|
||||
void DestroyParser (ParsePtr p);
|
||||
@@ -142,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);
|
||||
@@ -153,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);
|
||||
@@ -169,3 +172,15 @@ void set_components_from_lat_and_long(void);
|
||||
|
||||
char const *get_day_name(int wkday);
|
||||
char const *get_month_name(int mon);
|
||||
|
||||
int push_call(char const *filename, char const *func, int lineno);
|
||||
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
|
||||
|
||||
31
src/queue.c
31
src/queue.c
@@ -5,7 +5,7 @@
|
||||
/* Queue up reminders for subsequent execution. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -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) {
|
||||
@@ -230,7 +242,7 @@ void HandleQueuedReminders(void)
|
||||
/* Do NOT trigger the reminder if tt.nexttime is more than a
|
||||
minute in the past. This can happen if the clock is
|
||||
changed or a laptop awakes from hibernation.
|
||||
However, DO triger if tt.nexttime == tt.ttime so all
|
||||
However, DO trigger if tt.nexttime == tt.ttime so all
|
||||
queued reminders are triggered at least once. */
|
||||
if ((SystemTime(1) - (q->tt.nexttime * 60) <= 60) ||
|
||||
(q->tt.nexttime == q->tt.ttime)) {
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Print a PostScript calendar. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -349,7 +349,7 @@ int main(int argc, char *argv[])
|
||||
!strcmp(DBufValue(&buf), PSBEGIN2)) {
|
||||
if (!validfile) {
|
||||
if (Verbose) {
|
||||
fprintf(stderr, "Rem2PS: Version %s Copyright 1992-2021 by Dianne Skoll\n\n", VERSION);
|
||||
fprintf(stderr, "Rem2PS: Version %s Copyright 1992-2022 by Dianne Skoll\n\n", VERSION);
|
||||
fprintf(stderr, "Generating PostScript calendar\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Define the PostScript prologue */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -13,7 +13,7 @@ char *PSProlog1[] =
|
||||
{
|
||||
"% This file was produced by Remind and Rem2PS, written by",
|
||||
"% Dianne Skoll.",
|
||||
"% Remind and Rem2PS are Copyright 1992-2021 Dianne Skoll.",
|
||||
"% Remind and Rem2PS are Copyright 1992-2022 Dianne Skoll.",
|
||||
"/ISOLatin1Encoding where { pop save true }{ false } ifelse",
|
||||
" /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus",
|
||||
" StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Routines for sorting reminders by trigger date */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
@@ -4,9 +4,23 @@
|
||||
|
||||
ALL=`grep ^#define lang.h | grep -v '#define LANG' | awk '{print $2}'`
|
||||
|
||||
OUTPUT_COMPILED=lang-compiled.out
|
||||
OUTPUT_RUNTIME=lang-runtime.out
|
||||
cat /dev/null > $OUTPUT_COMPILED
|
||||
cat /dev/null > $OUTPUT_RUNTIME
|
||||
for i in $ALL ; do
|
||||
make clean
|
||||
make -j`nproc` all LANGDEF=-DLANG=$i || exit 1
|
||||
./remind -q -r ../tests/tstlang.rem
|
||||
./remind -q -r ../tests/tstlang.rem >> $OUTPUT_COMPILED 2>&1
|
||||
done
|
||||
|
||||
# Rebuild English version
|
||||
make clean
|
||||
make -j`nproc` all || exit 1
|
||||
|
||||
ALL=`ls ../include/lang/*.rem`
|
||||
for i in $ALL; do
|
||||
./remind -q -r "-ii=\"$i\"" ../tests/tstlang.rem >> $OUTPUT_RUNTIME 2>&1
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
||||
38
src/token.c
38
src/token.c
@@ -6,7 +6,7 @@
|
||||
/* classifying the tokens parsed. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -43,30 +43,37 @@ Token TokArray[] = {
|
||||
{ "at", 2, T_At, 0 },
|
||||
{ "august", 3, T_Month, 7 },
|
||||
{ "banner", 3, T_Banner, 0 },
|
||||
{ "before", 3, T_Skip, BEFORE_SKIP },
|
||||
{ "before", 3, T_Skip, BEFORE_SKIP },
|
||||
{ "cal", 3, T_RemType, CAL_TYPE },
|
||||
{ "clear-omit-context", 5, T_Clr, 0 },
|
||||
{ "debug", 5, T_Debug, 0 },
|
||||
{ "debug", 5, T_Debug, 0 },
|
||||
{ "december", 3, T_Month, 11 },
|
||||
{ "do", 2, T_IncludeR, 0 },
|
||||
{ "dumpvars", 4, T_Dumpvars, 0 },
|
||||
{ "dumpvars", 4, T_Dumpvars, 0 },
|
||||
{ "duration", 3, T_Duration, 0 },
|
||||
{ "else", 4, T_Else, 0 },
|
||||
{ "else", 4, T_Else, 0 },
|
||||
{ "endif", 5, T_EndIf, 0 },
|
||||
{ "errmsg", 6, T_ErrMsg, 0 },
|
||||
{ "errmsg", 6, T_ErrMsg, 0 },
|
||||
{ "exit", 4, T_Exit, 0 },
|
||||
{ "february", 3, T_Month, 1 },
|
||||
{ "first", 5, T_Ordinal, 0 },
|
||||
{ "flush", 5, T_Flush, 0 },
|
||||
{ "fourth", 6, T_Ordinal, 3 },
|
||||
{ "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 },
|
||||
{ "include", 3, T_Include, 0 },
|
||||
{ "includecmd", 10, T_IncludeCmd, 0 },
|
||||
{ "january", 3, T_Month, 0 },
|
||||
{ "july", 3, T_Month, 6 },
|
||||
{ "june", 3, T_Month, 5 },
|
||||
{ "last", 4, T_Ordinal, -1 },
|
||||
{ "lastday", 7, T_BackAdj, -1 },
|
||||
{ "lastworkday", 11, T_BackAdj, 1 },
|
||||
{ "march", 3, T_Month, 2 },
|
||||
{ "may", 3, T_Month, 4 },
|
||||
{ "maybe-uncomputable", 5, T_MaybeUncomputable, 0},
|
||||
@@ -90,12 +97,14 @@ Token TokArray[] = {
|
||||
{ "saturday", 3, T_WkDay, 5 },
|
||||
{ "scanfrom", 4, T_Scanfrom, SCANFROM_TYPE },
|
||||
{ "sched", 5, T_Sched, 0 },
|
||||
{ "second", 6, T_Ordinal, 1 },
|
||||
{ "september", 3, T_Month, 8 },
|
||||
{ "set", 3, T_Set, 0 },
|
||||
{ "skip", 3, T_Skip, SKIP_SKIP },
|
||||
{ "special", 7, T_RemType, PASSTHRU_TYPE },
|
||||
{ "sunday", 3, T_WkDay, 6 },
|
||||
{ "tag", 3, T_Tag, 0 },
|
||||
{ "third", 5, T_Ordinal, 2 },
|
||||
{ "through", 7, T_Through, 0 },
|
||||
{ "thursday", 3, T_WkDay, 3 },
|
||||
{ "tuesday", 3, T_WkDay, 1 },
|
||||
@@ -147,10 +156,6 @@ void FindToken(char const *s, Token *tok)
|
||||
int top, bot, mid, r, max;
|
||||
int l;
|
||||
|
||||
#if LANG != ENGLISH
|
||||
size_t i;
|
||||
#endif
|
||||
|
||||
tok->type = T_Illegal;
|
||||
if (! *s) {
|
||||
tok->type = T_Empty;
|
||||
@@ -325,6 +330,14 @@ void FindNumericToken(char const *s, Token *t)
|
||||
t->type = T_Back;
|
||||
t->val *= mult;
|
||||
return;
|
||||
} else if (*s == '~') {
|
||||
s++;
|
||||
if (*s == '~') { mult = -1; s++; }
|
||||
PARSENUM(t->val, s);
|
||||
if (*s) return; /* Illegal token if followed by non-numeric char */
|
||||
t->type = T_BackAdj;
|
||||
t->val *= mult;
|
||||
return;
|
||||
}
|
||||
return; /* Unknown token type */
|
||||
}
|
||||
@@ -342,7 +355,8 @@ static int TokStrCmp(Token const *t, char const *s)
|
||||
register int r;
|
||||
char const *tk = t->name;
|
||||
while(*tk && *s && !(*s == ',' && *(s+1) == 0)) {
|
||||
r = tolower(*tk) - tolower(*s);
|
||||
/* t->name is already lower-case */
|
||||
r = *tk - tolower(*s);
|
||||
tk++;
|
||||
s++;
|
||||
if (r) return r;
|
||||
@@ -350,5 +364,5 @@ static int TokStrCmp(Token const *t, char const *s)
|
||||
/* Ignore trailing commas on s */
|
||||
|
||||
if (!*s || (*s == ',' && !*(s+1))) return 0;
|
||||
return (tolower(*tk) - tolower(*s));
|
||||
return (*tk - tolower(*s));
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Routines for figuring out the trigger date of a reminder */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
20
src/types.h
20
src/types.h
@@ -5,7 +5,7 @@
|
||||
/* Type definitions all dumped here. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -69,6 +69,8 @@ typedef struct {
|
||||
int once;
|
||||
int scanfrom;
|
||||
int from;
|
||||
int adj_for_last; /* Adjust month/year for use of LAST */
|
||||
int need_wkday; /* Set if we *need* a weekday */
|
||||
int priority;
|
||||
int duration_days; /* Duration converted to days to search */
|
||||
int eventstart; /* Original event start (datetime) */
|
||||
@@ -153,11 +155,12 @@ 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,
|
||||
T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta, T_Back,
|
||||
T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta,
|
||||
T_Back, T_BackAdj,
|
||||
T_Once,
|
||||
T_Empty,
|
||||
T_Comment,
|
||||
@@ -175,7 +178,10 @@ enum TokTypes
|
||||
T_LongTime,
|
||||
T_OmitFunc,
|
||||
T_Through,
|
||||
T_MaybeUncomputable
|
||||
T_MaybeUncomputable,
|
||||
T_Ordinal,
|
||||
T_In,
|
||||
T_LastBack
|
||||
};
|
||||
|
||||
/* The structure of a token */
|
||||
@@ -232,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
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* functions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -32,6 +32,8 @@ typedef struct udf_struct {
|
||||
Var *locals;
|
||||
char IsActive;
|
||||
int nargs;
|
||||
char const *filename;
|
||||
int lineno;
|
||||
} UserFunc;
|
||||
|
||||
/* The hash table */
|
||||
@@ -51,6 +53,34 @@ static void FSet (UserFunc *f);
|
||||
static int SetUpLocalVars (UserFunc *f);
|
||||
static void DestroyLocalVals (UserFunc *f);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoFunset */
|
||||
/* */
|
||||
/* 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 */
|
||||
@@ -93,6 +123,11 @@ int DoFset(ParsePtr p)
|
||||
DBufFree(&buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
func->filename = StrDup(FileName);
|
||||
if (!func->filename) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
func->lineno = LineNo;
|
||||
StrnCpy(func->name, DBufValue(&buf), VAR_NAME_LEN);
|
||||
DBufFree(&buf);
|
||||
if (!Hush) {
|
||||
@@ -167,7 +202,7 @@ int DoFset(ParsePtr p)
|
||||
/* Add the function definition */
|
||||
FSet(func);
|
||||
if (orig_namelen > VAR_NAME_LEN) {
|
||||
Eprint("Warning: Function name `%s...' truncated to `%s'",
|
||||
Wprint("Warning: Function name `%s...' truncated to `%s'",
|
||||
func->name, func->name);
|
||||
}
|
||||
return OK;
|
||||
@@ -196,6 +231,9 @@ static void DestroyUserFunc(UserFunc *f)
|
||||
/* Free the function definition */
|
||||
if (f->text) free( (char *) f->text);
|
||||
|
||||
/* Free the filename */
|
||||
if (f->filename) free( (char *) f->filename);
|
||||
|
||||
/* Free the data structure itself */
|
||||
free(f);
|
||||
}
|
||||
@@ -306,7 +344,11 @@ int CallUserFunc(char const *name, int nargs, ParsePtr p)
|
||||
/* Skip the opening bracket, if there's one */
|
||||
while (isempty(*s)) s++;
|
||||
if (*s == BEG_OF_EXPR) s++;
|
||||
push_call(f->filename, f->name, f->lineno);
|
||||
h = Evaluate(&s, f->locals, p);
|
||||
if (h == OK) {
|
||||
pop_call();
|
||||
}
|
||||
f->IsActive = 0;
|
||||
DestroyLocalVals(f);
|
||||
if (DebugFlag &DB_PRTEXPR) {
|
||||
|
||||
134
src/utils.c
134
src/utils.c
@@ -5,7 +5,7 @@
|
||||
/* Useful utility functions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-2021 by Dianne Skoll */
|
||||
/* Copyright (C) 1992-2022 by Dianne Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -130,24 +128,33 @@ int DateOK(int y, int m, int d)
|
||||
|
||||
/* Functions designed to defeat gcc optimizer */
|
||||
|
||||
int _private_div(int a, int b) { return a/b; }
|
||||
int _private_add_overflow(int result, int b, int old)
|
||||
int _private_mul_overflow(int a, int b)
|
||||
{
|
||||
if (b > 0 && result < old) return 1;
|
||||
if (b < 0 && result > old) return 1;
|
||||
return 0;
|
||||
}
|
||||
int _private_sub_overflow(int result, int b, int old)
|
||||
{
|
||||
if (b < 0 && result < old) return 1;
|
||||
if (b > 0 && result > old) return 1;
|
||||
double aa = (double) a;
|
||||
double bb = (double) b;
|
||||
|
||||
if (aa*bb > (double) INT_MAX || aa*bb < (double) INT_MIN) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _private_unminus_overflow(int a, int b)
|
||||
int _private_add_overflow(int a, int b)
|
||||
{
|
||||
if (a > 0 && b > 0) return 1;
|
||||
if (a < 0 && b < 0) return 1;
|
||||
double aa = (double) a;
|
||||
double bb = (double) b;
|
||||
|
||||
if (aa+bb < (double) INT_MIN) return 1;
|
||||
if (aa+bb > (double) INT_MAX) return 1;
|
||||
return 0;
|
||||
}
|
||||
int _private_sub_overflow(int a, int b)
|
||||
{
|
||||
double aa = (double) a;
|
||||
double bb = (double) b;
|
||||
|
||||
if (aa-bb < (double) INT_MIN) return 1;
|
||||
if (aa-bb > (double) INT_MAX) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -162,3 +169,90 @@ ShellEscape(char const *in, DynamicBuffer *out)
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Call-stack for printing errors from user-defined functions */
|
||||
typedef struct cs_s {
|
||||
struct cs_s *next;
|
||||
char const *filename;
|
||||
char const *func;
|
||||
int lineno;
|
||||
} cs;
|
||||
|
||||
static cs *callstack = NULL;
|
||||
|
||||
static void
|
||||
destroy_cs(cs *entry)
|
||||
{
|
||||
if (entry->filename) free( (void *) entry->filename);
|
||||
if (entry->func) free( (void *) entry->func);
|
||||
free( (void *) entry);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
push_call(char const *filename, char const *func, int lineno)
|
||||
{
|
||||
cs *entry = NEW(cs);
|
||||
if (!entry) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
entry->next = NULL;
|
||||
entry->filename = StrDup(filename);
|
||||
entry->func = StrDup(func);
|
||||
entry->lineno = lineno;
|
||||
if (!entry->filename || !entry->func) {
|
||||
destroy_cs(entry);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
entry->next = callstack;
|
||||
callstack = entry;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void
|
||||
clear_callstack(void)
|
||||
{
|
||||
cs *entry = callstack;
|
||||
cs *next;
|
||||
while(entry) {
|
||||
next = entry->next;
|
||||
destroy_cs(entry);
|
||||
entry = next;
|
||||
}
|
||||
callstack = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
have_callstack(void)
|
||||
{
|
||||
if (callstack) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
print_callstack_aux(FILE *fp, cs *entry)
|
||||
{
|
||||
if (entry) {
|
||||
print_callstack_aux(fp, entry->next);
|
||||
fprintf(fp, "\n");
|
||||
(void) fprintf(fp, "%s(%d): In function `%s'", entry->filename, entry->lineno, entry->func);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
print_callstack(FILE *fp)
|
||||
{
|
||||
print_callstack_aux(fp, callstack);
|
||||
if (callstack) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pop_call(void)
|
||||
{
|
||||
cs *entry = callstack;
|
||||
if (entry) {
|
||||
callstack = entry->next;
|
||||
destroy_cs(entry);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user