mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 14:28:40 +02:00
Compare commits
400 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df6b4ac566 | ||
|
|
4ba21ab526 | ||
|
|
acac7a7b31 | ||
|
|
2290fd09f5 | ||
|
|
f02b6a1773 | ||
|
|
efffe05d42 | ||
|
|
950d67c522 | ||
|
|
a1aa61f54e | ||
|
|
3c2bd66460 | ||
|
|
245cebee56 | ||
|
|
c45364fdb3 | ||
|
|
e380308604 | ||
|
|
bd019524dd | ||
|
|
895536d7d3 | ||
|
|
3a0e41afd1 | ||
|
|
23dd28471e | ||
|
|
761217d403 | ||
|
|
77ed694111 | ||
|
|
61bcce3104 | ||
|
|
bf41b12ccd | ||
|
|
5eabd7d8d8 | ||
|
|
0c66f5f3af | ||
|
|
3190f784d9 | ||
|
|
394ff55879 | ||
|
|
9b846835bc | ||
|
|
01776af167 | ||
|
|
0db10424ad | ||
|
|
bafd7ea073 | ||
|
|
0ab27fcb4b | ||
|
|
95d016712e | ||
|
|
fcb55001bb | ||
|
|
7bc6961101 | ||
|
|
450e88fad8 | ||
|
|
3222b4c311 | ||
|
|
1e0cc3605d | ||
|
|
129b7bfeb7 | ||
|
|
388811b684 | ||
|
|
f83257407b | ||
|
|
e4ced77340 | ||
|
|
92e0bc316a | ||
|
|
a4a55f35b2 | ||
|
|
ed1150c189 | ||
|
|
08080f4e86 | ||
|
|
de4ebb8be6 | ||
|
|
11e2ce5093 | ||
|
|
2c560e6f2b | ||
|
|
643f394e6a | ||
|
|
6d047c2856 | ||
|
|
be86746685 | ||
|
|
da429b9629 | ||
|
|
b21a206c26 | ||
|
|
85bde8ba3a | ||
|
|
f84e658e6b | ||
|
|
8f0eba8bcd | ||
|
|
2faaaf78a8 | ||
|
|
7f659dace2 | ||
|
|
54cdd566c7 | ||
|
|
e212df87f9 | ||
|
|
4fb4db15e8 | ||
|
|
9a15a25a7b | ||
|
|
c02cfb9b17 | ||
|
|
3e726f21f7 | ||
|
|
21d4faa26f | ||
|
|
1d13d0ee07 | ||
|
|
329d13e480 | ||
|
|
2161c09b1d | ||
|
|
3f2e396c3c | ||
|
|
412e242109 | ||
|
|
e827516b72 | ||
|
|
7f953e98d7 | ||
|
|
821d3fe783 | ||
|
|
fdb4b302ac | ||
|
|
760d5d4a09 | ||
|
|
d561f98c42 | ||
|
|
ea74f276dc | ||
|
|
42cf82a5d5 | ||
|
|
825a6700da | ||
|
|
2f27645dac | ||
|
|
1e5b44d063 | ||
|
|
099ad9945d | ||
|
|
540ce3d946 | ||
|
|
ac2efcc993 | ||
|
|
b4bb1d9e37 | ||
|
|
9ec8b30934 | ||
|
|
fb38e5b35b | ||
|
|
5fa10e9d84 | ||
|
|
3bc1b5bd46 | ||
|
|
b266b399ba | ||
|
|
0e827a457d | ||
|
|
d05d85b243 | ||
|
|
a1faa8d804 | ||
|
|
70adbf90c2 | ||
|
|
501c04f4b6 | ||
|
|
d294e62be1 | ||
|
|
31f90b6c53 | ||
|
|
184d29c592 | ||
|
|
2d798bc4ec | ||
|
|
bd9a3761a6 | ||
|
|
b1063b0a9e | ||
|
|
cb2fffab92 | ||
|
|
55cca49428 | ||
|
|
5a0ab9ed8a | ||
|
|
1f2cfdfd84 | ||
|
|
dfd688caa6 | ||
|
|
830e3e339c | ||
|
|
bc9f560950 | ||
|
|
f91b748f50 | ||
|
|
3adbd7468c | ||
|
|
b66039ee24 | ||
|
|
27371f6475 | ||
|
|
19e7c34b47 | ||
|
|
3375aff3a7 | ||
|
|
41e9cb5ca3 | ||
|
|
6348860adf | ||
|
|
4e9d401002 | ||
|
|
3db2fc7d0f | ||
|
|
0101d76113 | ||
|
|
6fabab6d4b | ||
|
|
905f1b0aaf | ||
|
|
6a5ab8e70c | ||
|
|
943b037589 | ||
|
|
5624cd44de | ||
|
|
8529f8b843 | ||
|
|
08be7c43cf | ||
|
|
aae76207ec | ||
|
|
5434f8330e | ||
|
|
e18b4ed119 | ||
|
|
51f6ffc093 | ||
|
|
72de7c6b14 | ||
|
|
bd4785d631 | ||
|
|
cb08f12470 | ||
|
|
04146db69b | ||
|
|
d3fe045a39 | ||
|
|
2be1e16087 | ||
|
|
051e44ae3e | ||
|
|
6d5ae7a258 | ||
|
|
2e69e140eb | ||
|
|
516c4e2c39 | ||
|
|
b58ed62000 | ||
|
|
c685818783 | ||
|
|
3e20ce56c9 | ||
|
|
dd8d67f659 | ||
|
|
5ef4061819 | ||
|
|
a146a0c819 | ||
|
|
0f5a93cdf1 | ||
|
|
7db51e913e | ||
|
|
93ac1aebf7 | ||
|
|
56ebedb9de | ||
|
|
e87d33de50 | ||
|
|
a5774fd793 | ||
|
|
adb60f3400 | ||
|
|
47a0f63caa | ||
|
|
30a385a7bb | ||
|
|
9f2ae1773c | ||
|
|
f470297958 | ||
|
|
93dfc7995c | ||
|
|
c96869817f | ||
|
|
1bffa0e00b | ||
|
|
36035dda01 | ||
|
|
50a15cf089 | ||
|
|
b59d4ed4a4 | ||
|
|
4c53710279 | ||
|
|
2274e88485 | ||
|
|
984a4677f2 | ||
|
|
5e3dc54725 | ||
|
|
53a7bf9773 | ||
|
|
1dcc3897d6 | ||
|
|
fbc0375739 | ||
|
|
4a74c03fa4 | ||
|
|
d8833e6ce2 | ||
|
|
2b8b9a56aa | ||
|
|
85a8ebb357 | ||
|
|
a67d9e2524 | ||
|
|
6845e72fd5 | ||
|
|
0ab977fa05 | ||
|
|
ad64a12b2a | ||
|
|
cfde4b50bb | ||
|
|
f302c8eb95 | ||
|
|
7ecc355358 | ||
|
|
a52216d7e7 | ||
|
|
8d8d4b667d | ||
|
|
670369121e | ||
|
|
4365e580ee | ||
|
|
a8a09a905e | ||
|
|
dbb7381eb1 | ||
|
|
aa3531a6bf | ||
|
|
2848203d75 | ||
|
|
f0aef0703c | ||
|
|
7356a511e0 | ||
|
|
5be26a3cff | ||
|
|
36a80acb0c | ||
|
|
37ab03b49d | ||
|
|
75209cb40e | ||
|
|
4b2d274748 | ||
|
|
1423495b88 | ||
|
|
42e4ec8890 | ||
|
|
58fbd51ef4 | ||
|
|
7552dbb812 | ||
|
|
31e0ecb71d | ||
|
|
f6743a4f87 | ||
|
|
5f574949e6 | ||
|
|
724bce4fb9 | ||
|
|
8d59f025af | ||
|
|
aad44f4716 | ||
|
|
0a38d7d213 | ||
|
|
4fcd60fd95 | ||
|
|
38beeb8cb0 | ||
|
|
26f0acab35 | ||
|
|
3897973bc1 | ||
|
|
7b3da27461 | ||
|
|
a85ee5f31c | ||
|
|
b272863aa0 | ||
|
|
8249964380 | ||
|
|
af81bbb299 | ||
|
|
d818dd9c80 | ||
|
|
fe8e34dece | ||
|
|
ba928989f7 | ||
|
|
742f973028 | ||
|
|
043932fcbe | ||
|
|
ad5e096caa | ||
|
|
06c8fc8f78 | ||
|
|
487338d10c | ||
|
|
3d1c0e5667 | ||
|
|
ce3bb191c4 | ||
|
|
03e9dbf364 | ||
|
|
518aab3d02 | ||
|
|
f055664f77 | ||
|
|
ba3e01f2ce | ||
|
|
b6883c8a45 | ||
|
|
9e49ee3acb | ||
|
|
7481f68bb2 | ||
|
|
99792eec03 | ||
|
|
91458c7845 | ||
|
|
cad5849dc0 | ||
|
|
a38e120e99 | ||
|
|
0b31a78cf2 | ||
|
|
861858c1a6 | ||
|
|
d43a2277da | ||
|
|
f678dc96b8 | ||
|
|
c2e371904e | ||
|
|
2a1cbff22e | ||
|
|
a2d9f277c4 | ||
|
|
d939059417 | ||
|
|
740cd4cfed | ||
|
|
91a5306a67 | ||
|
|
b78ffcbffd | ||
|
|
4f72f557b7 | ||
|
|
e3b21d6d0d | ||
|
|
af28c49d8d | ||
|
|
67f4635573 | ||
|
|
5f8d10908d | ||
|
|
7307421812 | ||
|
|
5cd3b628c5 | ||
|
|
29e483ab64 | ||
|
|
66ddba45af | ||
|
|
9325b3f035 | ||
|
|
522c4c94e1 | ||
|
|
730505cff3 | ||
|
|
019783e1fa | ||
|
|
8612bb6480 | ||
|
|
7f1e6d21d9 | ||
|
|
e6c0371be1 | ||
|
|
58feaa7e0c | ||
|
|
a828378466 | ||
|
|
53316e8b06 | ||
|
|
6127e390a1 | ||
|
|
4caa77f6b1 | ||
|
|
70419e8757 | ||
|
|
21d8bd1406 | ||
|
|
25abee3259 | ||
|
|
2d490c2b7a | ||
|
|
902b7895b7 | ||
|
|
1c80bb649f | ||
|
|
4508215617 | ||
|
|
739b68347a | ||
|
|
d834760cda | ||
|
|
1bc78650bf | ||
|
|
ec4e203099 | ||
|
|
d23528da82 | ||
|
|
7401a0ba23 | ||
|
|
b14b4f08b1 | ||
|
|
70ece81340 | ||
|
|
19ac350527 | ||
|
|
a9b08d7db8 | ||
|
|
df8fa05632 | ||
|
|
6556137aad | ||
|
|
aa1ab2bbb4 | ||
|
|
be38d86521 | ||
|
|
3931afb6b1 | ||
|
|
7d2df86b75 | ||
|
|
5a3bd5839b | ||
|
|
b91ce9a3f7 | ||
|
|
ac889dd329 | ||
|
|
420df9b6ed | ||
|
|
f862b6811d | ||
|
|
c072698927 | ||
|
|
d22895831b | ||
|
|
3c41f4ade4 | ||
|
|
335d5fb984 | ||
|
|
66bd2b8fac | ||
|
|
fed3cad3b8 | ||
|
|
b20578f24f | ||
|
|
7a86e7f777 | ||
|
|
16c93fcad6 | ||
|
|
edd66d8d89 | ||
|
|
3ba39b6efe | ||
|
|
c656a1a169 | ||
|
|
19f03e419a | ||
|
|
5a281d5999 | ||
|
|
d80d14f585 | ||
|
|
520b8511bd | ||
|
|
91627d4f22 | ||
|
|
a21147c7a5 | ||
|
|
d22c1dee49 | ||
|
|
95b0fc7480 | ||
|
|
b40d5d7984 | ||
|
|
2df93c9df3 | ||
|
|
51cdea4b17 | ||
|
|
f229e64744 | ||
|
|
0f15955a41 | ||
|
|
390e6c2eed | ||
|
|
877eaccd6d | ||
|
|
6424e655a1 | ||
|
|
176037082b | ||
|
|
a361c7e426 | ||
|
|
caba0c1695 | ||
|
|
71b3f9fefc | ||
|
|
91f8507e51 | ||
|
|
b68e81a126 | ||
|
|
72658025f1 | ||
|
|
93aea240d6 | ||
|
|
7717b37c36 | ||
|
|
e1b2990fb0 | ||
|
|
e49194c6ee | ||
|
|
79ab150546 | ||
|
|
fc658d15d4 | ||
|
|
76d130ef82 | ||
|
|
3e9a55fbdb | ||
|
|
b071397d46 | ||
|
|
df0dd55635 | ||
|
|
960d08fd24 | ||
|
|
38603916a2 | ||
|
|
0ed1bb4017 | ||
|
|
b4ac0c9f6c | ||
|
|
b136af88ad | ||
|
|
508b5f9aae | ||
|
|
43dff67a60 | ||
|
|
41b850321f | ||
|
|
523237007b | ||
|
|
a3f6c5fd9c | ||
|
|
785cdc8726 | ||
|
|
cbf12b5601 | ||
|
|
1a6d59d9c0 | ||
|
|
23ae054abb | ||
|
|
b57852d3d8 | ||
|
|
c0e1be2f3a | ||
|
|
a442a15a8d | ||
|
|
f91bf634ad | ||
|
|
ce4311c3df | ||
|
|
08e69cb541 | ||
|
|
f8e2eaed73 | ||
|
|
e68a16e73d | ||
|
|
ca191fbd92 | ||
|
|
10276826c0 | ||
|
|
02c9129903 | ||
|
|
04e4c902bd | ||
|
|
0663ae77de | ||
|
|
0c0f5ea093 | ||
|
|
f450fd633e | ||
|
|
59cdd35f61 | ||
|
|
eab67cbda4 | ||
|
|
b3c4a48641 | ||
|
|
07ac8ed341 | ||
|
|
e32aa218fc | ||
|
|
09d11d36c3 | ||
|
|
629e287526 | ||
|
|
e2cd29c824 | ||
|
|
69e597dbe7 | ||
|
|
152e7ebac9 | ||
|
|
8d4451ed85 | ||
|
|
5b8836d4b8 | ||
|
|
be7086579e | ||
|
|
ab16c8f1fe | ||
|
|
6bb71ee5e3 | ||
|
|
ebb4ebea97 | ||
|
|
bf97e62d56 | ||
|
|
47645cddb6 | ||
|
|
cf2af56a05 | ||
|
|
50d1ae42c9 | ||
|
|
9501498a7e | ||
|
|
614ab08099 | ||
|
|
64ee338433 | ||
|
|
43556238d0 | ||
|
|
58d7ac0520 | ||
|
|
0754678ce7 | ||
|
|
2bea176816 | ||
|
|
fa90333219 | ||
|
|
e007b3bc0f | ||
|
|
978e83567b | ||
|
|
d01c1190cd |
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
*.bak
|
||||
autom4te.cache
|
||||
config.log
|
||||
config.status
|
||||
src/Makefile
|
||||
www/Makefile
|
||||
*.o
|
||||
src/config.h
|
||||
src/remind
|
||||
src/*.tar.gz*
|
||||
tests/test.out
|
||||
.gitignore
|
||||
*~
|
||||
src/rem2ps
|
||||
src/version.h
|
||||
@@ -1,54 +0,0 @@
|
||||
$Id: ACKNOWLEDGEMENTS,v 1.2 2000-02-18 03:45:11 dfs Exp $
|
||||
|
||||
I would like to thank the following people:
|
||||
|
||||
Bill Aten <netagw!bill@uunet.UU.NET> for providing remind-all.sh
|
||||
|
||||
Bradley D. Keister <keister@poincare.phys.cmu.edu>, Rhys Weatherly
|
||||
rhys@batserver.cs.uq.OZ.AU> and Anthony Cheng for initially providing
|
||||
the Turbo C compiler support.
|
||||
|
||||
Dennis Cottel <dennis@peanuts.nosc.mil> for providing the patch to
|
||||
produce calendars by weeks as well as by months.
|
||||
|
||||
Bill Silvert <bill%biomel@cs.dal.ca> and Dennis Cottel
|
||||
<dennis@peanuts.nosc.mil> for suggesting many of the new features in
|
||||
REMIND.
|
||||
|
||||
Dave Wolfe <dwolfe@pffft.sps.mot.com> and Raphael Manfredi
|
||||
<ram@eiffel.com> for noticing bugs and sending me fixes.
|
||||
|
||||
Dave Rickel and George M. Sipe for sample reminders and holidays.
|
||||
|
||||
Michael Salmon for ISO encoding of PostScript output.
|
||||
|
||||
Darrel Hankerson for helping me provide some OS/2 support. Sorry
|
||||
it's not complete, Darrel!
|
||||
|
||||
Phillipp Slusallek for suggesting the -k option.
|
||||
|
||||
Amos Shapir, David W. Tamkin and Frank Yellin for help with the Hebrew
|
||||
calendar.
|
||||
|
||||
All of the language translators whose names are listed in lang.h
|
||||
|
||||
Mark Harrison and Michael McLennan for the excellent book
|
||||
"Effective Tcl/Tk Programming". This is where I stole the source
|
||||
for Tcl/Tk tabbed notebooks, and is an excellent reference book.
|
||||
Thanks also to Lucent Technologies and Addison Wesley Longman for
|
||||
making it legal to steal the code.
|
||||
|
||||
All others who have corresponded with me to report bugs, express
|
||||
appreciation or suggest features - too many people to list here.
|
||||
|
||||
Finally, all those who donated money to support the production of
|
||||
REMIND. Your donations were gratefully appreciated.
|
||||
|
||||
--
|
||||
David F. Skoll <dfs@roaringpenguin.com> <aa775@freenet.carleton.ca>
|
||||
986 Eiffel Avenue
|
||||
Ottawa, Ontario K2C 0J2
|
||||
CANADA
|
||||
|
||||
Tel. (613) 225-8687
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
$Id: COPYRIGHT,v 1.16 2005-04-12 01:27:52 dfs Exp $
|
||||
THE REMIND COPYRIGHT
|
||||
|
||||
1. REMIND refers to the entire set of files and documentation in the
|
||||
REMIND package.
|
||||
|
||||
2. REMIND is Copyright 1999-2005 Roaring Penguin Software Inc.,
|
||||
2. REMIND is Copyright 1999-2010 Roaring Penguin Software Inc.,
|
||||
except where noted in individual files.
|
||||
|
||||
3. DISTRIBUTION AND USE
|
||||
|
||||
30
MICROSOFT-AND-APPLE
Normal file
30
MICROSOFT-AND-APPLE
Normal file
@@ -0,0 +1,30 @@
|
||||
MICROSOFT WINDOWS
|
||||
=================
|
||||
|
||||
I used to prohibit porting Remind to Microsoft Windows. However, this
|
||||
may cause problems with the GPL, so I have removed that restriction.
|
||||
|
||||
Although I cannot prevent you from porting Remind to Windows, I appeal
|
||||
to you not to do it. I am trying to encourage the growth of free
|
||||
software, not proprietary software.
|
||||
|
||||
If you port Remind to Windows, I will not provide support or answers to
|
||||
questions -- you're on your own. On the other hand, I will feel no guilt
|
||||
in taking enhancements and merging them into the UNIX stream.
|
||||
|
||||
APPLE
|
||||
=====
|
||||
|
||||
I can't prevent you from using Remind on Apple's products, but I hope
|
||||
you don't. Apple's corporate culture is the very antithesis of Free
|
||||
Software. Rather than using Mac OS X, I encourage you to switch to
|
||||
Linux or FreeBSD, two Free Software operating systems that are every
|
||||
bit as capable as Mac OS X and which are unencumbered by Apple's
|
||||
arbitrary restrictions.
|
||||
|
||||
And if you're looking to port Remind to other Apple products like the
|
||||
iPhone or iPad, please don't. Those products enforce Apple's rigorous
|
||||
controls much more stringently than Mac OS X on an Apple PC.
|
||||
|
||||
--
|
||||
David F. Skoll
|
||||
10
Makefile
10
Makefile
@@ -1,7 +1,5 @@
|
||||
# Top-level Makefile for Remind.
|
||||
|
||||
# $Id: Makefile,v 1.28 1998-05-06 01:51:12 dfs Exp $
|
||||
|
||||
all: src/Makefile
|
||||
@echo ""
|
||||
@echo "*******************"
|
||||
@@ -26,8 +24,14 @@ clean:
|
||||
find . -name '*~' -exec rm {} \;
|
||||
cd src; $(MAKE) clean
|
||||
|
||||
test:
|
||||
@cd src && $(MAKE) test
|
||||
|
||||
distclean: clean
|
||||
rm -f config.cache config.log config.status src/Makefile src/config.h
|
||||
rm -f config.cache config.log config.status src/Makefile src/config.h tests/test.out www/Makefile
|
||||
|
||||
src/Makefile: src/Makefile.in
|
||||
./configure
|
||||
|
||||
# DO NOT DELETE
|
||||
|
||||
|
||||
4
README
4
README
@@ -34,7 +34,5 @@ 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.
|
||||
|
||||
$Id: README,v 1.7 2000-06-26 14:43:25 dfs Exp $
|
||||
|
||||
Contact info: mailto:dfs@roaringpenguin.com
|
||||
Home page: http://www.roaringpenguin.com/remind.html
|
||||
Home page: http://www.roaringpenguin.com/remind
|
||||
|
||||
17
WINDOWS
17
WINDOWS
@@ -1,17 +0,0 @@
|
||||
$Id: WINDOWS,v 1.1 1999-04-05 17:34:28 dfs Exp $
|
||||
|
||||
MICROSOFT WINDOWS
|
||||
|
||||
I used to prohibit porting Remind to Microsoft Windows. However, this
|
||||
may cause problems with the GPL, so I have removed that restriction.
|
||||
|
||||
Although I cannot prevent you from porting Remind to Windows, I appeal
|
||||
to you not to do it. I am trying to encourage the growth of free
|
||||
software, not proprietary software.
|
||||
|
||||
If you port Remind to Windows, I will not provide support or answers to
|
||||
questions -- you're on your own. On the other hand, I will feel no guilt
|
||||
in taking enhancements and merging them into the UNIX stream.
|
||||
|
||||
--
|
||||
David F. Skoll.
|
||||
124
build.tk
124
build.tk
@@ -12,8 +12,6 @@
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
|
||||
# $Id: build.tk,v 1.13 2005-04-14 17:33:26 dfs Exp $
|
||||
|
||||
# the next line restarts using wish \
|
||||
exec wish "$0" "$@"
|
||||
|
||||
@@ -34,7 +32,7 @@ proc SetConfigDefaults {} {
|
||||
set Config(LON_MIN) 39
|
||||
set Config(LOCATION) "Ottawa"
|
||||
set Config(DEFAULT_PAGE) "Letter"
|
||||
set Config(DATESEP) "/"
|
||||
set Config(DATESEP) "-"
|
||||
set Config(TIMESEP) ":"
|
||||
set Config(ISOLATIN1) 0
|
||||
set Config(IBMEXTENDED) 0
|
||||
@@ -43,6 +41,8 @@ proc SetConfigDefaults {} {
|
||||
set Config(NORTHERN_HEMISPHERE) 1
|
||||
set Config(WESTERN_HEMISPHERE) 1
|
||||
set Config(LANGUAGE) "English"
|
||||
set Config(INST_DIR) "/usr/local/bin"
|
||||
set Config(MAN_DIR) "/usr/local/man"
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
@@ -99,7 +99,7 @@ proc CreateMainDialog {} {
|
||||
destroy .c
|
||||
update idletasks
|
||||
|
||||
SetConfigDefaults
|
||||
SetConfigFromRemind
|
||||
tabnotebook_create .tn
|
||||
|
||||
set Instdir [tabnotebook_page .tn "Installation Directories"]
|
||||
@@ -130,13 +130,14 @@ proc CreateMainDialog {} {
|
||||
# Creates the "installation directories" dialog.
|
||||
#***********************************************************************
|
||||
proc CreateInstallDirDialog { w } {
|
||||
global Config
|
||||
label $w.binlabel -text "Location for programs: "
|
||||
entry $w.bin -width 30
|
||||
$w.bin insert end "/usr/local/bin"
|
||||
$w.bin insert end $Config(INST_DIR)
|
||||
|
||||
label $w.manlabel -text "Location for man pages: "
|
||||
entry $w.man -width 30
|
||||
$w.man insert end "/usr/local/man"
|
||||
$w.man insert end $Config(MAN_DIR)
|
||||
|
||||
text $w.blurb -width 1 -height 5 -wrap word -relief flat -takefocus 0
|
||||
$w.blurb insert end "\n(Tabbed-notebook Tcl code taken from \"Effective Tcl/Tk Programming\" by Mark Harrison and Michael McLennan, Addison-Wesley Professional Computing Series.)"
|
||||
@@ -865,10 +866,121 @@ proc doLogo {} {
|
||||
|
||||
.c create text 4 28 -anchor nw -text "http://www.roaringpenguin.com" \
|
||||
-fill red -font {-family courier -size -14 -weight bold}
|
||||
|
||||
set rem [FindRemind]
|
||||
if {$rem != ""} {
|
||||
.c create text 4 52 -anchor nw -text "Found existing Remind... reusing settings" -fill red -font {-family courier -size -14 -weight bold}
|
||||
.c create text 4 66 -anchor nw -text "from $rem" -fill red -font {-family courier -size -14 -weight bold}
|
||||
}
|
||||
update idletasks
|
||||
after 2500
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: FindRemind
|
||||
# %ARGUMENTS:
|
||||
# None
|
||||
# %RETURNS:
|
||||
# Full path to an existing "remind" if one is found. Otherwise,
|
||||
# empty string.
|
||||
#***********************************************************************
|
||||
proc FindRemind {} {
|
||||
global env
|
||||
set path [concat [split $env(PATH) ":"] "/bin" "/usr/bin" "/usr/local/bin"]
|
||||
foreach thing $path {
|
||||
if [file executable [file join $thing "remind"]] {
|
||||
return [file join $thing "remind"]
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
#***********************************************************************
|
||||
# %PROCEDURE: SetConfigFromRemind
|
||||
# %ARGUMENTS:
|
||||
# None
|
||||
# %RETURNS:
|
||||
# Sets config settings based on existing remind (if one found) or else
|
||||
# sensible defaults.
|
||||
#***********************************************************************
|
||||
proc SetConfigFromRemind {} {
|
||||
global Config
|
||||
SetConfigDefaults
|
||||
set rem [FindRemind]
|
||||
if {"$rem" == ""} {
|
||||
return
|
||||
}
|
||||
set dir [file dirname $rem]
|
||||
set Config(INST_DIR) $dir
|
||||
if {"$dir" == "/usr/local/bin"} {
|
||||
set Config(MAN_DIR) "/usr/local/man"
|
||||
} elseif {$dir == "/usr/bin"} {
|
||||
set Config(MAN_DIR) "/usr/share/man"
|
||||
}
|
||||
|
||||
# Check for existing man page
|
||||
if {[file readable "/usr/share/man/man1/remind.1"]} {
|
||||
set Config(MAN_DIR) "/usr/share/man"
|
||||
} elseif {[file readable "/usr/man/man1/remind.1"]} {
|
||||
set Config(MAN_DIR) "/usr/man"
|
||||
} elseif {[file readable "/usr/local/man/man1/remind.1"]} {
|
||||
set Config(MAN_DIR) "/usr/local/man"
|
||||
}
|
||||
|
||||
# Query Remind for the rest
|
||||
QueryRemind $rem LAT_DEG {$LatDeg}
|
||||
QueryRemind $rem LAT_MIN {$LatMin}
|
||||
QueryRemind $rem LON_DEG {$LongDeg}
|
||||
QueryRemind $rem LON_MIN {$LongMin}
|
||||
QueryRemind $rem LOCATION {$Location}
|
||||
QueryRemind $rem DATESEP {$DateSep}
|
||||
QueryRemind $rem TIMESEP {$TimeSep}
|
||||
QueryRemind $rem LANGUAGE {language()}
|
||||
|
||||
set $Config(LAT_MIN) [expr abs($Config(LAT_MIN))]
|
||||
if {$Config(LAT_DEG) >= 0} {
|
||||
set Config(NORTHERN_HEMISPHERE) 1
|
||||
} else {
|
||||
set Config(NORTHERN_HEMISPHERE) 0
|
||||
set Config(LAT_DEG) [expr abs($Config(LAT_DEG))]
|
||||
}
|
||||
|
||||
set $Config(LON_MIN) [expr abs($Config(LON_MIN))]
|
||||
if {$Config(LON_DEG) >= 0} {
|
||||
set Config(WESTERN_HEMISPHERE) 1
|
||||
} else {
|
||||
set Config(WESTERN_HEMISPHERE) 0
|
||||
set Config(LON_DEG) [expr abs($Config(LON_DEG))]
|
||||
}
|
||||
|
||||
# Get default page from rem2ps
|
||||
set rem2ps [file join $dir "rem2ps"]
|
||||
|
||||
catch {
|
||||
exec $rem2ps -m help
|
||||
} err
|
||||
set errlist [split $err "\n"]
|
||||
set err [lindex $errlist end]
|
||||
if {[string match "Default media type is*" $err]} {
|
||||
set Config(DEFAULT_PAGE) [lindex $err end]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc QueryRemind { rem symbol rem_msg } {
|
||||
global Config
|
||||
catch {
|
||||
set fp [open "| $rem -" "r+"]
|
||||
puts $fp "banner %\nMSG \[$rem_msg\]%\nFLUSH\n"
|
||||
flush $fp
|
||||
gets $fp line
|
||||
catch { close $fp }
|
||||
}
|
||||
if {"$line" == ""} {
|
||||
return
|
||||
}
|
||||
set Config($symbol) $line
|
||||
}
|
||||
|
||||
CheckSanity
|
||||
CreateMainDialog
|
||||
|
||||
43
configure.in
43
configure.in
@@ -1,5 +1,4 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
dnl $Id: configure.in,v 1.9 2005-09-30 03:33:52 dfs Exp $
|
||||
|
||||
AC_INIT(src/queue.c)
|
||||
|
||||
@@ -15,6 +14,36 @@ EOF
|
||||
|
||||
AC_CONFIG_HEADER(src/config.h)
|
||||
|
||||
if test "`uname -s`" = "Darwin" ; then
|
||||
trap 'echo Be patient...' INT TERM
|
||||
cat <<'EOF'
|
||||
|
||||
Please don't use Apple products. This script will continue in 30 seconds
|
||||
if you insist on compiling Remind on Mac OS X.
|
||||
|
||||
EOF
|
||||
for i in 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ; do
|
||||
sleep 1
|
||||
done
|
||||
trap - INT
|
||||
trap - TERM
|
||||
fi
|
||||
|
||||
if uname -s | grep -i -q 'cygwin' ; then
|
||||
trap 'echo Be patient...' INT TERM
|
||||
cat <<'EOF'
|
||||
|
||||
Please don't use Microsoft products. This script will continue in 30
|
||||
seconds if you insist on compiling Remind on Cygwin.
|
||||
|
||||
EOF
|
||||
for i in 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ; do
|
||||
sleep 1
|
||||
done
|
||||
trap - INT
|
||||
trap - TERM
|
||||
fi
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
@@ -26,8 +55,13 @@ dnl Replace `main' with a function in -lm:
|
||||
|
||||
AC_CHECK_LIB(m, sqrt)
|
||||
|
||||
dnl Integer sizes
|
||||
AC_CHECK_SIZEOF(unsigned short)
|
||||
AC_CHECK_SIZEOF(unsigned int)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_CHECK_HEADERS(sys/file.h)
|
||||
AC_CHECK_HEADERS(sys/file.h glob.h wctype.h locale.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_STRUCT_TM
|
||||
@@ -40,4 +74,7 @@ if test "$GCC" = yes; then
|
||||
CFLAGS="$CFLAGS -Wall -Wstrict-prototypes"
|
||||
fi
|
||||
|
||||
AC_OUTPUT(src/Makefile)
|
||||
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale)
|
||||
VERSION=03.01.11
|
||||
AC_SUBST(VERSION)
|
||||
AC_OUTPUT(src/Makefile www/Makefile src/version.h)
|
||||
|
||||
10
contrib/README
Normal file
10
contrib/README
Normal file
@@ -0,0 +1,10 @@
|
||||
This directory contains contributed scripts. They are provided
|
||||
"as-is" with no warranty. Please do not contact David Skoll
|
||||
or Roaring Penguin Software Inc. for help with these scripts;
|
||||
instead, contact the script authors.
|
||||
|
||||
You should check the upstream sources; there may be newer versions
|
||||
of these scripts available.
|
||||
|
||||
--
|
||||
David F. Skoll
|
||||
279
contrib/ical2rem.pl
Executable file
279
contrib/ical2rem.pl
Executable file
@@ -0,0 +1,279 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# ical2rem.pl -
|
||||
# Reads iCal files and outputs remind-compatible files. Tested ONLY with
|
||||
# calendar files created by Mozilla Calendar/Sunbird. Use at your own risk.
|
||||
# Copyright (c) 2005, 2007, Justin B. Alcorn
|
||||
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
# version 0.5.2 2007-03-23
|
||||
# - BUG: leadtime for recurring events had a max of 4 instead of DEFAULT_LEAD_TIME
|
||||
# - remove project-lead-time, since Category was a non-standard attribute
|
||||
# - NOTE: There is a bug in iCal::Parser v1.14 that causes multiple calendars to
|
||||
# fail if a calendar with recurring events is followed by a calendar with no
|
||||
# recurring events. This has been reported to the iCal::Parser author.
|
||||
# version 0.5.1 2007-03-21
|
||||
# - BUG: Handle multiple calendars on STDIN
|
||||
# - add --heading option for priority on section headers
|
||||
# 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
|
||||
# version 0.4
|
||||
# - Version 0.4 changes all written or inspired by, and thanks to Mark Stosberg
|
||||
# - Change to GetOptions
|
||||
# - Change to pipe
|
||||
# - Add --label, --help options
|
||||
# - Add Help Text
|
||||
# - Change to subroutines
|
||||
# - Efficiency and Cleanup
|
||||
# version 0.3
|
||||
# - Convert to GPL (Thanks to Mark Stosberg)
|
||||
# - Add usage
|
||||
# version 0.2
|
||||
# - add command line switches
|
||||
# - add debug code
|
||||
# - add SCHED _sfun keyword
|
||||
# - fix typos
|
||||
# version 0.1 - ALPHA CODE.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
cat /path/to/file*.ics | ical2rem.pl > ~/.ical2rem
|
||||
|
||||
All options have reasonable defaults:
|
||||
--label Calendar name (Default: Calendar)
|
||||
--lead-time Advance days to start reminders (Default: 3)
|
||||
--todos, --no-todos Process Todos? (Default: Yes)
|
||||
--heading Define a priority for static entries
|
||||
--help Usage
|
||||
--man Complete man page
|
||||
|
||||
Expects an ICAL stream on STDIN. Converts it to the format
|
||||
used by the C<remind> script and prints it to STDOUT.
|
||||
|
||||
=head2 --label
|
||||
|
||||
ical2rem.pl --label "Bob's Calendar"
|
||||
|
||||
The syntax generated includes a label for the calendar parsed.
|
||||
By default this is "Calendar". You can customize this with
|
||||
the "--label" option.
|
||||
|
||||
=head2 --lead-time
|
||||
|
||||
ical2rem.pl --lead-time 3
|
||||
|
||||
How may days in advance to start getting reminders about the events. Defaults to 3.
|
||||
|
||||
=head2 --no-todos
|
||||
|
||||
ical2rem.pl --no-todos
|
||||
|
||||
If you don't care about the ToDos the calendar, this will surpress
|
||||
printing of the ToDo heading, as well as skipping ToDo processing.
|
||||
|
||||
=head2 --heading
|
||||
|
||||
ical2rem.pl --heading "PRIORITY 9999"
|
||||
|
||||
Set an option on static messages output. Using priorities can made the static messages look different from
|
||||
the calendar entries. See the file defs.rem from the remind distribution for more information.
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use iCal::Parser;
|
||||
use DateTime;
|
||||
use Getopt::Long 2.24 qw':config auto_help';
|
||||
use Pod::Usage;
|
||||
use Data::Dumper;
|
||||
use vars '$VERSION';
|
||||
$VERSION = "0.5.2";
|
||||
|
||||
# Declare how many days in advance to remind
|
||||
my $DEFAULT_LEAD_TIME = 3;
|
||||
my $PROCESS_TODOS = 1;
|
||||
my $HEADING = "";
|
||||
my $help;
|
||||
my $man;
|
||||
|
||||
my $label = 'Calendar';
|
||||
GetOptions (
|
||||
"label=s" => \$label,
|
||||
"lead-time=i" => \$DEFAULT_LEAD_TIME,
|
||||
"todos!" => \$PROCESS_TODOS,
|
||||
"heading=s" => \$HEADING,
|
||||
"help|?" => \$help,
|
||||
"man" => \$man
|
||||
);
|
||||
pod2usage(1) if $help;
|
||||
pod2usage(-verbose => 2) if $man;
|
||||
|
||||
my $month = ['None','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
|
||||
|
||||
my @calendars;
|
||||
my $in;
|
||||
|
||||
while (<>) {
|
||||
$in .= $_;
|
||||
if (/END:VCALENDAR/) {
|
||||
push(@calendars,$in);
|
||||
$in = "";
|
||||
}
|
||||
}
|
||||
my $parser = iCal::Parser->new();
|
||||
my $hash = $parser->parse_strings(@calendars);
|
||||
|
||||
##############################################################
|
||||
#
|
||||
# Subroutines
|
||||
#
|
||||
#############################################################
|
||||
#
|
||||
# _process_todos()
|
||||
# expects 'todos' hashref from iCal::Parser is input
|
||||
# returns String to output
|
||||
sub _process_todos {
|
||||
my $todos = shift;
|
||||
|
||||
my ($todo, @newtodos, $leadtime);
|
||||
my $output = "";
|
||||
|
||||
$output .= 'REM '.$HEADING.' MSG '.$label.' ToDos:%"%"%'."\n";
|
||||
|
||||
# For sorting, make sure everything's got something
|
||||
# To sort on.
|
||||
my $now = DateTime->now;
|
||||
for $todo (@{$todos}) {
|
||||
# remove completed items
|
||||
if ($todo->{'STATUS'} && $todo->{'STATUS'} eq 'COMPLETED') {
|
||||
next;
|
||||
} elsif ($todo->{'DUE'}) {
|
||||
# All we need is a due date, everything else is sugar
|
||||
$todo->{'SORT'} = $todo->{'DUE'}->clone;
|
||||
} elsif ($todo->{'DTSTART'}) {
|
||||
# for sorting, sort on start date if there's no due date
|
||||
$todo->{'SORT'} = $todo->{'DTSTART'}->clone;
|
||||
} else {
|
||||
# if there's no due or start date, just make it now.
|
||||
$todo->{'SORT'} = $now;
|
||||
}
|
||||
push(@newtodos,$todo);
|
||||
}
|
||||
if (! (scalar @newtodos)) {
|
||||
return "";
|
||||
}
|
||||
# Now sort on the new Due dates and print them out.
|
||||
for $todo (sort { DateTime->compare($a->{'SORT'}, $b->{'SORT'}) } @newtodos) {
|
||||
my $due = $todo->{'SORT'}->clone();
|
||||
my $priority = "";
|
||||
if (defined($todo->{'PRIORITY'})) {
|
||||
if ($todo->{'PRIORITY'} == 1) {
|
||||
$priority = "PRIORITY 1000";
|
||||
} elsif ($todo->{'PRIORITY'} == 3) {
|
||||
$priority = "PRIORITY 7500";
|
||||
}
|
||||
}
|
||||
if (defined($todo->{'DTSTART'}) && defined($todo->{'DUE'})) {
|
||||
# Lead time is duration of task + lead time
|
||||
my $diff = ($todo->{'DUE'}->delta_days($todo->{'DTSTART'})->days())+$DEFAULT_LEAD_TIME;
|
||||
$leadtime = "+".$diff;
|
||||
} else {
|
||||
$leadtime = "+".$DEFAULT_LEAD_TIME;
|
||||
}
|
||||
$output .= "REM ".$due->month_abbr." ".$due->day." ".$due->year." $leadtime $priority MSG \%a $todo->{'SUMMARY'}\%\"\%\"\%\n";
|
||||
}
|
||||
$output .= 'REM '.$HEADING.' MSG %"%"%'."\n";
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Main Program
|
||||
#
|
||||
######################################################################
|
||||
|
||||
print _process_todos($hash->{'todos'}) if $PROCESS_TODOS;
|
||||
|
||||
my ($leadtime, $yearkey, $monkey, $daykey,$uid,%eventsbyuid);
|
||||
print 'REM '.$HEADING.' MSG '.$label.' Events:%"%"%'."\n";
|
||||
my $events = $hash->{'events'};
|
||||
foreach $yearkey (sort keys %{$events} ) {
|
||||
my $yearevents = $events->{$yearkey};
|
||||
foreach $monkey (sort {$a <=> $b} keys %{$yearevents}){
|
||||
my $monevents = $yearevents->{$monkey};
|
||||
foreach $daykey (sort {$a <=> $b} keys %{$monevents} ) {
|
||||
my $dayevents = $monevents->{$daykey};
|
||||
foreach $uid (sort {
|
||||
DateTime->compare($dayevents->{$a}->{'DTSTART'}, $dayevents->{$b}->{'DTSTART'})
|
||||
} keys %{$dayevents}) {
|
||||
my $event = $dayevents->{$uid};
|
||||
if ($eventsbyuid{$uid}) {
|
||||
my $curreventday = $event->{'DTSTART'}->clone;
|
||||
$curreventday->truncate( to => 'day' );
|
||||
$eventsbyuid{$uid}{$curreventday->epoch()} =1;
|
||||
for (my $i = 0;$i < $DEFAULT_LEAD_TIME && !defined($event->{'LEADTIME'});$i++) {
|
||||
if ($eventsbyuid{$uid}{$curreventday->subtract( days => $i+1 )->epoch() }) {
|
||||
$event->{'LEADTIME'} = $i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$eventsbyuid{$uid} = $event;
|
||||
my $curreventday = $event->{'DTSTART'}->clone;
|
||||
$curreventday->truncate( to => 'day' );
|
||||
$eventsbyuid{$uid}{$curreventday->epoch()} =1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach $yearkey (sort keys %{$events} ) {
|
||||
my $yearevents = $events->{$yearkey};
|
||||
foreach $monkey (sort {$a <=> $b} keys %{$yearevents}){
|
||||
my $monevents = $yearevents->{$monkey};
|
||||
foreach $daykey (sort {$a <=> $b} keys %{$monevents} ) {
|
||||
my $dayevents = $monevents->{$daykey};
|
||||
foreach $uid (sort {
|
||||
DateTime->compare($dayevents->{$a}->{'DTSTART'}, $dayevents->{$b}->{'DTSTART'})
|
||||
} keys %{$dayevents}) {
|
||||
my $event = $dayevents->{$uid};
|
||||
if (exists($event->{'LEADTIME'})) {
|
||||
$leadtime = "+".$event->{'LEADTIME'};
|
||||
} else {
|
||||
$leadtime = "+".$DEFAULT_LEAD_TIME;
|
||||
}
|
||||
my $start = $event->{'DTSTART'};
|
||||
print "REM ".$start->month_abbr." ".$start->day." ".$start->year." $leadtime ";
|
||||
if ($start->hour > 0) {
|
||||
print " AT ";
|
||||
print $start->strftime("%H:%M");
|
||||
print " SCHED _sfun MSG %a %2 ";
|
||||
} else {
|
||||
print " MSG %a ";
|
||||
}
|
||||
print "%\"$event->{'SUMMARY'}";
|
||||
print " at $event->{'LOCATION'}" if $event->{'LOCATION'};
|
||||
print "\%\"%\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exit 0;
|
||||
#:vim set ft=perl ts=4 sts=4 expandtab :
|
||||
13
contrib/rem2ics-0.93/Makefile
Normal file
13
contrib/rem2ics-0.93/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
DESTDIR?=
|
||||
PREFIX?=/usr
|
||||
BINDIR?=$(PREFIX)/bin
|
||||
MANDIR?=$(PREFIX)/share/man
|
||||
|
||||
default: rem2ics.1
|
||||
|
||||
rem2ics.1:
|
||||
pod2man -c "" rem2ics > rem2ics.1
|
||||
|
||||
install: rem2ics.1
|
||||
install -p -D rem2ics $(DESTDIR)$(BINDIR)/rem2ics
|
||||
install -p -D -m 0644 rem2ics.1 $(DESTDIR)$(MANDIR)/man1/rem2ics.1
|
||||
847
contrib/rem2ics-0.93/rem2ics
Executable file
847
contrib/rem2ics-0.93/rem2ics
Executable file
@@ -0,0 +1,847 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# rem2ics -- convert the output of "remind -s" into RFC2445 iCalendar format.
|
||||
|
||||
# Copyright 2007,2008,2009
|
||||
# Mark Atwood <me@mark.atwood.name>
|
||||
# Paul Hinze <paul dot t dot hinze at gmail dot com>
|
||||
# Michael Schultz <mjschultz at gmail dot com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the
|
||||
# Free Software Foundation, Inc.
|
||||
# 51 Franklin Street, Fifth Floor
|
||||
# Boston MA 02110-1301 USA
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
rem2ics - convert the output of "remind -s" into RFC2445 iCalendar format.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
TZ=I<timezone> B<rem2ics> [B<-man>] [B<-do>] [B<-norecur>] [B<-usetag>] E<lt>input E<gt>output
|
||||
|
||||
=head1 OPTIONS AND ARGUMENTS
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<-man>
|
||||
|
||||
Print the manual page and exit.
|
||||
|
||||
=item B<-do>
|
||||
|
||||
Actually do the conversion. Otherwise just print a brief help message
|
||||
and usage example, and then exit.
|
||||
|
||||
=item B<-norecur>
|
||||
|
||||
Do not attempt to detect and fold together recurring events.
|
||||
|
||||
=item B<-usetag>
|
||||
|
||||
Generate UIDs using remind TAG clauses.
|
||||
|
||||
=back
|
||||
|
||||
Input is from standard input
|
||||
|
||||
Output is to standard output.
|
||||
|
||||
=head1 USAGE
|
||||
|
||||
remind -s360 -irem2ics=1 ~/.reminders 1 Jan 1991 | TZ=PST8PDT rem2ics -do >reminders.ics
|
||||
|
||||
This tells B<remind> to use ~/.reminders, and to process the entire
|
||||
range of dates it can handle (from Jan 1 1991 to Dec 31 2020), and to
|
||||
define a variable named C<rem2ics>, which can be used in
|
||||
C<IF !defined("rem2ics")> / C<ENDIF> pairs.
|
||||
B<rem2ics> will use a timezone of PST8PDT, and will fold events that
|
||||
have the same name and duration into a single iCalendar VEVENT object.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
=head2 Timezones and the TZ environment variable.
|
||||
|
||||
B<rem2ics> uses the TZ environment variable to determine the value of
|
||||
the RFC2445 TZID property. If you are running on a Linux or other GNU
|
||||
libc based system, you probably don't (and probably shouldn't)
|
||||
normally have TZ set. You can confirm this by running C<printenv TZ>
|
||||
at a shell prompt. If your remind data is in your "local time", and
|
||||
it probably is, you should probably set TZ to a good name for your
|
||||
local timezone just for the run of this script. You probably should
|
||||
NOT set TZ in your login scripts.
|
||||
|
||||
You can use TZ like this:
|
||||
|
||||
remind -s ~/.reminders | TZ=PST8PDT rem2ics -do >reminders.ics
|
||||
|
||||
or
|
||||
|
||||
remind -s ~/.reminders | TZ=US/Pacific rem2ics -do >reminders.ics
|
||||
|
||||
|
||||
If, for some reason, your remind files are all in GMT instead of
|
||||
localtime (you smart person you!), you can do this:
|
||||
|
||||
remind -s ~/.reminders | TZ=GMT rem2ics -do >reminders.ics
|
||||
|
||||
or
|
||||
|
||||
remind -s ~/.reminders | TZ=0 rem2ics -do >reminders.ics
|
||||
|
||||
and B<rem2ics> will use the ISO8601 "Z" notation for GMT time in the ics
|
||||
file. (Other synonyms for GMT are the empty string (not the same as
|
||||
the TZ not set), "I<0>", "I<Z>", "I<Zulu>", "I<Greenwitch>", "I<GMT>",
|
||||
"I<GMT+0>, and "I<GMT-0>".)
|
||||
|
||||
If you leave TZ undefined and unset, B<rem2ics> will use the ISO8601
|
||||
"T" notation date strings with no TZID property, which RFC2445 calls a
|
||||
"floating time". Who knows, it might work for you!
|
||||
|
||||
The TZ string value is literally incorporated into the iCalendar
|
||||
stream, so whatever your iCalendar-using application needs is what you
|
||||
should use. You may have to experiment a bit.
|
||||
|
||||
You can look around in C</usr/share/zoneinfo> to get the names of
|
||||
every timezone anywhere. This is the "Olson database" that RFC2445
|
||||
refers to. Read the man page for L<tzfile(5)> for more than you ever
|
||||
wanted to know about the format of these files, and about GNU libc's
|
||||
handling of timezones. As complex as it is, it's certainly better
|
||||
than what POSIX defines or what most legacy UNIX systems do, and most
|
||||
certainly better than Microsoft, who in their "cutting edge" "state of
|
||||
the art" "server" OS, still hasn't figured out that daylight time
|
||||
rules might be different in different years.
|
||||
|
||||
If you just ran B<rem2ics> without reading all this stuff, or if you
|
||||
don't want to worry about it at all, and somehow your iCalendar
|
||||
application manager is able to guess the proper timezone for you, just
|
||||
leave TZ undefined, and B<rem2ics> will use the ISO8601 "T" notation
|
||||
date strings with no TZID property, which RFC2445 calls a "floating
|
||||
time". Who knows, it might work for you!
|
||||
|
||||
=head2 Detecting recurring events
|
||||
|
||||
B<rem2ics> tries to detect recurring events. If any multiple events
|
||||
appear with exactly the text and exactly the same duration (including
|
||||
"no duration"), instead of multiple VEVENT objects, there will be just
|
||||
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
|
||||
send in a patch, or contact the author and convince him to do it.
|
||||
|
||||
=head2 Other iCalendar Properties
|
||||
|
||||
B<rem2ics> does not generate C<DESCRIPTION> or C<LOCATION>. One
|
||||
would have to heuristically parse them out of the text, and everyone
|
||||
uses a idiosyncratic way of putting things in B<remind>.
|
||||
|
||||
If the B<-usetag> option is not used or no C<TAG> is set for a
|
||||
reminder, B<rem2ics> will synthesize C<UID> properties for each
|
||||
VEVENT, but the UIDs will be different (and unique) for each run of
|
||||
B<rem2ics>. If you run rem2ics twice and import the two resulting ICS
|
||||
streams into your new scheduling program, your appointments will
|
||||
appear twice. If, however, you have set C<TAG> clauses in your
|
||||
reminders and activated B<-usetag>, these will be used. The same
|
||||
applies for tags synthesized by B<remind>'s B<-y> option. Hence, it
|
||||
is more useful to use the B<-y> option than to let B<rem2ics>
|
||||
synthesize UIDs, because the UIDs will stay the same across multiple
|
||||
runs.
|
||||
|
||||
=head2 Other iCalendar Perl objects
|
||||
|
||||
Why does'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
|
||||
forth. I am not at this moment interested in groveling around in
|
||||
L<Net::iCal>, L<DateTime::Format::iCal>, L<Tie::iCal>,
|
||||
L<iCal::Parser>, or C<libical>.
|
||||
|
||||
=head2 Previous implementation
|
||||
|
||||
There is a working quick & dirty rem2ics written in awk
|
||||
by Anthony J. Chivetta E<lt>achivetta@gmail.comE<gt>.
|
||||
|
||||
But it has the following problems: it doesn't escape the text, it
|
||||
doesn't handle events that cross over midnight, it doesn't do
|
||||
timezones, it doesn't enforce the correct EOL sequence, and it doesn't
|
||||
fold long lines. This is a replacement for that script.
|
||||
|
||||
=head1 TODO
|
||||
|
||||
If TZ not set, grab out of system config somewhere
|
||||
Detect recurring events.
|
||||
If I'm REALLY smart, derive RRULE
|
||||
Handle characters not in US-ASCII. Latin1? UTF8?
|
||||
|
||||
=head1 VERSION HISTORY
|
||||
|
||||
=over 8
|
||||
|
||||
=item version 0.1 2007-02-08
|
||||
|
||||
First cut.
|
||||
|
||||
=item version 0.2 2007-02-09
|
||||
|
||||
Reorg into multipass over a data structure.
|
||||
|
||||
=item version 0.3 2007-02-10
|
||||
|
||||
Collapse repeating events. Fold output lines.
|
||||
|
||||
=item version 0.9 2007-02-11
|
||||
|
||||
POD. Command line options. First public release.
|
||||
|
||||
=item version 0.91 2007-02-14
|
||||
|
||||
Bug fix, error message for non-recurring events
|
||||
|
||||
=item version 0.92 2008-01-28
|
||||
|
||||
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
|
||||
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>
|
||||
|
||||
=item version 0.93 2009-06-25
|
||||
|
||||
Add B<-usetag> option to allow for UIDs to stay the same across multiple runs
|
||||
by using the remind TAG clause.
|
||||
Patch by Tim Weber E<lt>scy at scytale dot nameE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<http://mark.atwood.name/code/rem2ics>
|
||||
|
||||
L<http://en.wikipedia.org/wiki/ICalendar>
|
||||
|
||||
L<http://tools.ietf.org/html/rfc2445>
|
||||
|
||||
L<http://www.roaringpenguin.com/en/penguin/openSourceProducts/remind>
|
||||
|
||||
L<remind(1)>
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright 2007,2008,2009 by Mark Atwood E<lt>me+rem2ics@mark.atwood.nameE<gt>. L<http://mark.atwood.name/>.
|
||||
|
||||
Please report bugs (with patches, if possible).
|
||||
|
||||
Inspired by Anthony J. Chivetta E<lt>achivetta@gmail.comE<gt>'s
|
||||
rem2ics in awk.
|
||||
|
||||
Thank you to David Skoll E<lt>dfs@roaringpengiun.com<gt> for Remind,
|
||||
and to the IETF calsch wg for the iCalendar specification.
|
||||
|
||||
=cut
|
||||
|
||||
use Getopt::Long;
|
||||
use Pod::Usage;
|
||||
|
||||
my $app_name = "rem2ics";
|
||||
my $app_version = "0.93";
|
||||
|
||||
# process the command line
|
||||
my %options;
|
||||
GetOptions(\%options, qw(man do norecurr usetag)) || pod2usage(2);
|
||||
pod2usage(-verbose => 2) if ($options{man});
|
||||
|
||||
unless ($options{do}) {
|
||||
print STDERR "Run \"$0 -man\" for information and usage examples.\n"
|
||||
. "Pay special attention to information about timezone.\n";
|
||||
exit(99);
|
||||
}
|
||||
|
||||
# grab the hostname
|
||||
# this is used as part of the UID property of each VEVENT
|
||||
my $ical_uid_hostname = $ENV{'HOSTNAME'};
|
||||
unless ($ical_uid_hostname) {
|
||||
print STDERR "Warning! "
|
||||
. "The environment variable HOSTNAME was not properly set.\n"
|
||||
. "Will use \"localhost\" in the RFC2445 UID property\n";
|
||||
$ical_uid_hostname = "localhost";
|
||||
}
|
||||
|
||||
# look for the TZ
|
||||
my $ical_tzid = undef;
|
||||
if (exists $ENV{'TZ'}) {
|
||||
$ical_tzid = $ENV{'TZ'};
|
||||
my %synonyms_for_gmt = (
|
||||
'' => 1, '0' => 1, 'z' => 1, 'zulu' => 1, 'greenwitch' => 1,
|
||||
'gmt' => 1, 'gmt+0' => 1, 'gmt-0' => 1, );
|
||||
if (exists $synonyms_for_gmt{lc($ical_tzid)}) {
|
||||
$ical_tzid = ''; # empty means GMT, below
|
||||
}
|
||||
} else {
|
||||
# leave it undefined, that has a meaning below
|
||||
}
|
||||
|
||||
# RFC2445 DTSTAMP property will be the time we started running ($^T)
|
||||
my ($ical_dtstamp);
|
||||
{
|
||||
my @gt = gmtime($^T);
|
||||
$ical_dtstamp = sprintf("%04d%02d%02dZ%02d%02d%02dZ",
|
||||
1900+$gt[5], $gt[4]+1, $gt[3],
|
||||
$gt[2], $gt[1], $gt[0]);
|
||||
}
|
||||
|
||||
my ($cnt, $v, @events);
|
||||
|
||||
$cnt = 0;
|
||||
foreach (<STDIN>) {
|
||||
$cnt++;
|
||||
|
||||
s/#.*//; # toss comments
|
||||
next if /^\s*$/; # skip blank lines
|
||||
chomp;
|
||||
|
||||
$v = undef;
|
||||
|
||||
# store the raw line
|
||||
$v->{src} = $_;
|
||||
$v->{cnt} = $cnt;
|
||||
|
||||
# split and parse the line
|
||||
# if we don't like it, skip it and go around again
|
||||
|
||||
# sf[0] = date, in yyyy/mm/dd format
|
||||
# sf[1] = special, usually "*"
|
||||
# sf[2] = tag, usually "*"
|
||||
# sf[3] = duration, in minutes
|
||||
# sf[4] = time, since midnight, in minutes
|
||||
# sf[5] = text
|
||||
|
||||
my @sf = split(' ', $_, 6);
|
||||
next unless ($sf[1] eq '*'); # ignore SPECIAL lines
|
||||
next unless (($sf[3] eq '*') or ($sf[3] =~ m/\d+/));
|
||||
next unless (($sf[4] eq '*') or ($sf[4] =~ m/\d+/));
|
||||
next unless (length($sf[5]) > 0);
|
||||
|
||||
my @dt = split('/', $sf[0], 3);
|
||||
next unless ($dt[0] =~ m/^\d{4}$/); # year
|
||||
next unless ($dt[1] =~ m/^\d{2}$/); # month
|
||||
next unless ($dt[2] =~ m/^\d{2}$/); # day
|
||||
|
||||
if ($sf[4] ne "*") { # a time was given
|
||||
# When an event has a time, remind -s "helpfully" also
|
||||
# puts it as text at the start of the text portion.
|
||||
# This takes the following form:
|
||||
# ##:##[a|p]m <rest of MSG>
|
||||
# or, if the event has a duration:
|
||||
# ##:##[a|p]m-##:##[a|p]m <rest of MSG>
|
||||
# Rather than a nasty regex, just splitting at the
|
||||
# first space does the trick.
|
||||
my($extra_time, $textmsg) = split(' ', $sf[5], 2);
|
||||
$sf[5] = $textmsg;
|
||||
}
|
||||
|
||||
$v->{sf} = \@sf;
|
||||
$v->{dt} = \@dt;
|
||||
|
||||
push @events, $v;
|
||||
}
|
||||
|
||||
# generate the "date time string" for each event
|
||||
foreach $v (@events) {
|
||||
if (${$v->{sf}}[4] eq "*") { # no time was given
|
||||
$v->{dts} = sprintf("%04d%02d%02d", @{$v->{dt}});
|
||||
} else { # a time was given
|
||||
my ($t_hr, $t_mn) = &idiv(${$v->{sf}}[4], 60);
|
||||
$v->{dts} = sprintf("%04d%02d%02dT%02d%02d00",
|
||||
@{$v->{dt}}, $t_hr, $t_mn);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
my(%grovel);
|
||||
|
||||
# if the user doesnt want recurrance detection
|
||||
unless ($options{norecurr}) {
|
||||
|
||||
# then dont put events in the grovel hash
|
||||
|
||||
foreach $v (@events) {
|
||||
# key is duration followed by text
|
||||
# \036 is "ASCII RS Record Separator"
|
||||
my $k = ${$v->{sf}}[3] . "\036" . ${$v->{sf}}[5];
|
||||
push @{$grovel{$k}}, $v;
|
||||
}
|
||||
|
||||
foreach my $k (keys %grovel) {
|
||||
if ((scalar @{$grovel{$k}}) > 1) {
|
||||
$v = ${$grovel{$k}}[0];
|
||||
$v->{recurlist} = \@{$grovel{$k}};
|
||||
foreach my $v0 (@{$grovel{$k}}) {
|
||||
$v0->{is_recurrance} = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# All of the individual events are in the @events array. All of the
|
||||
# unique combinations of duration/event name are the keys in the
|
||||
# %grovel hash, the elements of which are references to an arrays of
|
||||
# references to the events, in the same ordering as they we read by
|
||||
# us, which *ought* to be in datewise order. I don't know if "remind
|
||||
# -s" actually sorts into true chronological order. If it doesn't, we
|
||||
# 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.
|
||||
# Additionally, (hopefully) the first/earliest event in a set of
|
||||
# recurrances 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
|
||||
# event that has the "recurlist" property.
|
||||
|
||||
foreach my $k (keys %grovel) {
|
||||
next if ((scalar @{$grovel{$k}}) <= 1);
|
||||
|
||||
my $recur_str = "";
|
||||
foreach $v (@{$grovel{$k}}) {
|
||||
if (${$v->{sf}}[4] eq "*") { # no time was given
|
||||
$recur_str .= ($v->{dts} . ",");
|
||||
} else {
|
||||
if (defined($ical_tzid)) {
|
||||
if ($ical_tzid eq '') { # tz is defined but empty, so in GMT
|
||||
$recur_str .= $v->{dts} . "Z,";
|
||||
} else { # tz is non-zero, so output the tz as well
|
||||
$recur_str .= $v->{dts} . ",";
|
||||
}
|
||||
} else { # undefined tz, just floating time
|
||||
$recur_str .= $v->{dts} . ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# the recur_str now has an extra comma at the end. chop it off
|
||||
chop($recur_str);
|
||||
${$grovel{$k}}[0]->{recur_str} = $recur_str;
|
||||
}
|
||||
|
||||
foreach my $k (keys %grovel) {
|
||||
next if ((scalar @{$grovel{$k}}) <= 1);
|
||||
my $v = ${$grovel{$k}}[0]; # grab the head of each list
|
||||
if (${$v->{sf}}[4] eq "*") { # no time was given
|
||||
# the default value type for an RDATE is DATE-TIME,
|
||||
# we much change the type to DATE
|
||||
$v->{i_rdate} = sprintf("RDATE;VALUE=DATE:");
|
||||
} else {
|
||||
if (defined($ical_tzid)) {
|
||||
if ($ical_tzid eq '') { # tz is defined but empty, so in GMT
|
||||
$v->{i_rdate} = sprintf("RDATE:");
|
||||
} else { # tz is non-zero, so output the tz as well
|
||||
$v->{i_rdate} = sprintf("RDATE;TZID=%s:", $ical_tzid);
|
||||
}
|
||||
} else { # undefined tz, just floating time
|
||||
$v->{i_rdate} = sprintf("RDATE:");
|
||||
}
|
||||
}
|
||||
# now stick the recur_str onto the end
|
||||
$v->{i_rdate} .= $v->{recur_str};
|
||||
# if we ever get memory tight, we can probably undef($v->{recur_str})
|
||||
}
|
||||
|
||||
foreach $v (@events) {
|
||||
# for recurrant events, skip those that arnt the "head"
|
||||
next if ($v->{is_recurrance} and (not $v->{recurlist}));
|
||||
|
||||
if (${$v->{sf}}[4] eq "*") { # no time was given
|
||||
$v->{i_dtstart} = sprintf("DTSTART:%s", $v->{dts});
|
||||
} else {
|
||||
if (defined($ical_tzid)) {
|
||||
if ($ical_tzid eq '') { # tz is defined but empty, so in GMT
|
||||
$v->{i_dtstart} = sprintf("DTSTART:%sZ", $v->{dts});
|
||||
} else { # tz is non-zero, so output the tz as well
|
||||
$v->{i_dtstart} = sprintf("DTSTART;TZID=%s:%s",
|
||||
$ical_tzid, $v->{dts});
|
||||
}
|
||||
} else { # undefined tz, just floating time
|
||||
$v->{i_dtstart} = sprintf("DTSTART:%s", $v->{dts});
|
||||
}
|
||||
}
|
||||
|
||||
if (${$v->{sf}}[3] ne "*") { # a duration was given
|
||||
# It's convienient 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.
|
||||
$v->{i_duration} = sprintf("PT%dM", ${$v->{sf}}[3]);
|
||||
}
|
||||
}
|
||||
|
||||
# output header
|
||||
print "BEGIN:VCALENDAR\015\012"
|
||||
. "VERSION:2.0\015\012"
|
||||
. "PRODID:http://mark.atwood.name/code/rem2ics"
|
||||
. " $app_name $app_version\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}));
|
||||
|
||||
print "BEGIN:VEVENT\015\012";
|
||||
my $tag = ${$v->{sf}}[2];
|
||||
# if $tag is not set, fake up a UID from start time, process id & input line count
|
||||
if ($tag eq "*" || !$options{usetag}) {
|
||||
$tag = sprintf("%x.%x.%x", $^T, $$, $v->{cnt});
|
||||
}
|
||||
# add rem2ics and hostname to UID
|
||||
print &lineify(sprintf("UID:rem2ics.%s@%s",
|
||||
$tag, $ical_uid_hostname));
|
||||
print &lineify("SUMMARY:" . "ify(${$v->{sf}}[5]));
|
||||
print &lineify($v->{i_dtstart});
|
||||
print &lineify("DURATION:" . $v->{i_duration})
|
||||
if ($v->{i_duration});
|
||||
print &lineify($v->{i_rdate})
|
||||
if ($v->{i_rdate});
|
||||
print &lineify("DTSTAMP:" . $ical_dtstamp);
|
||||
print &lineify("COMMENT: generated by $app_name $app_version\\n"
|
||||
. " http://mark.atwood.name/code/rem2ics\\n"
|
||||
. " data[" . $v->{cnt} . "]=|" . "ify($v->{src}) . "|");
|
||||
print "END:VEVENT\015\012";
|
||||
}
|
||||
|
||||
# output trailer
|
||||
print "END:VCALENDAR\015\012";
|
||||
|
||||
|
||||
# integer division, return both quotient and remainder
|
||||
sub idiv {
|
||||
my $n = shift; my $d = shift;
|
||||
my $r = $n; my $q = 0;
|
||||
while ($r >= $d) {
|
||||
$r = $r - $d;
|
||||
$q = $q + 1;
|
||||
}
|
||||
return ($q, $r);
|
||||
}
|
||||
|
||||
# todo, perl5 version that defines ()*, need to specify a requires up top
|
||||
sub lineify {
|
||||
return join("\015\012 ", unpack('(A72)*', shift)) . "\015\012";
|
||||
}
|
||||
|
||||
sub quotify {
|
||||
my $s = shift;
|
||||
return $s if $s =~ m/^(\w| )*$/;
|
||||
|
||||
$s =~ s/\\/\\\\/gso;
|
||||
$s =~ s/\n/\\n/gso;
|
||||
$s =~ s/\s/ /gso;
|
||||
$s =~ s/\"/\\"/gso;
|
||||
$s =~ s/\,/\\,/gso;
|
||||
$s =~ s/\:/\\:/gso;
|
||||
$s =~ s/\;/\\;/gso;
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
EOF
|
||||
50
contrib/rem2ics-0.93/rem2ics.spec
Normal file
50
contrib/rem2ics-0.93/rem2ics.spec
Normal file
@@ -0,0 +1,50 @@
|
||||
Name: rem2ics
|
||||
Version: 0.93
|
||||
Release: 1%{?dist}
|
||||
Summary: Converts the output of "remind -s" into RFC2445 iCalendar format
|
||||
|
||||
Group: Applications/Productivity
|
||||
License: GPLv2+
|
||||
URL: http://mark.atwood.name/code/rem2ics/
|
||||
Source0: http://mark.atwood.name/code/rem2ics/rem2ics-%{version}.tar.gz
|
||||
Source1: rem2ics-Makefile
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
BuildArch: noarch
|
||||
BuildRequires: perl
|
||||
|
||||
|
||||
%description
|
||||
rem2ics converts the output of "remind -s" into RFC2445 iCalendar format.
|
||||
You may want to install remind if you install this package.
|
||||
|
||||
|
||||
%prep
|
||||
%setup -q -c
|
||||
cp -a %SOURCE1 Makefile
|
||||
|
||||
|
||||
%build
|
||||
make %{?_smp_mflags}
|
||||
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
mkdir $RPM_BUILD_ROOT
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%doc
|
||||
%{_bindir}/rem2ics
|
||||
%{_mandir}/man1/rem2ics.1*
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue Mar 25 2008 Till Maas <opensource till name> - 0.92-1
|
||||
- initial spec for Fedora
|
||||
56
contrib/remind-conf-mode.06/ac-remind.el
Normal file
56
contrib/remind-conf-mode.06/ac-remind.el
Normal file
@@ -0,0 +1,56 @@
|
||||
;;; setup for remind autocompletion (totally optional)
|
||||
|
||||
;; put something like
|
||||
;; (add-hook 'remind-conf-mode '(load-library "ac-remind")) in your .emacs file.
|
||||
(require 'auto-complete)
|
||||
|
||||
(define-key ac-complete-mode-map "\r" nil)
|
||||
|
||||
(defvar ac-remind-keywords
|
||||
'((candidates
|
||||
. (lambda ()
|
||||
(all-completions ac-target remind-keywords ))))
|
||||
"Source for remind-conf completion keywords.")
|
||||
|
||||
(defvar ac-remind-time-words
|
||||
'((candidates
|
||||
. (lambda ()
|
||||
(all-completions ac-target remind-time-words))))
|
||||
"Source for remind-conf time words completions.")
|
||||
|
||||
(defvar ac-remind-builtin-variables
|
||||
'((candidates
|
||||
. (lambda ()
|
||||
(all-completions ac-target remind-builtin-variables))))
|
||||
"Source for remind-conf builtin variables.")
|
||||
|
||||
(defvar ac-remind-type-keywords
|
||||
'((candidates
|
||||
. (lambda ()
|
||||
(all-completions ac-target remind-type-keywords))))
|
||||
"Source for remind-conf type keywords.")
|
||||
|
||||
(defvar ac-remind-builtin-functions
|
||||
'((candidates
|
||||
. (lambda ()
|
||||
(all-completions ac-target remind-builtin-functions))))
|
||||
"Source for remind-conf completion builtin functions.")
|
||||
|
||||
(add-hook 'remind-conf-mode-hook
|
||||
(lambda () "Makes auto-completion work in remind-conf-mode"
|
||||
(make-local-variable 'ac-sources)
|
||||
(setq ac-sources '(ac-remind-keywords
|
||||
ac-remind-builtin-variables
|
||||
ac-remind-builtin-functions
|
||||
ac-remind-type-keywords
|
||||
ac-remind-time-words
|
||||
ac-source-abbrev))
|
||||
(auto-complete-mode 1)))
|
||||
|
||||
(provide 'ac-remind)
|
||||
;; (define-skeleton ac-look
|
||||
;; ""
|
||||
;; (skeleton-read "well? ")
|
||||
;; "(when (looking-at (regexp-opt remind-" str " 'words))" \n
|
||||
;; >"(setq ac-sources '(ac-remind-" str ")))"
|
||||
;; )
|
||||
444
contrib/remind-conf-mode.06/remind-conf-mode.el
Normal file
444
contrib/remind-conf-mode.06/remind-conf-mode.el
Normal file
@@ -0,0 +1,444 @@
|
||||
;;; remind-conf-mode.el --- A mode to help configure remind.
|
||||
|
||||
;; Copyright (C) 2008 Shelagh Manton <shelagh.manton@gmail.com>
|
||||
|
||||
;; Author: Shelagh Manton <shelagh.manton@gmail.com> with help from
|
||||
;; David F. Skoll
|
||||
;; Keywords: remind configure mode
|
||||
;; Version: .04
|
||||
|
||||
;; This program is free software; you can redistribute it and/or
|
||||
;; modify it under the terms of the GNU General Public License
|
||||
;; as published by the Free Software Foundation; either version 2
|
||||
;; of the License, or (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program; if not, write to the Free Software
|
||||
;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
;; 02111-1307, USA.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Use this mode to help with the configuration of remind configuration files.
|
||||
;; Put (require 'remind-conf-mode) in your .emacs file
|
||||
;; or (autoload 'remind-conf-mode "remind-conf-mode" "Mode to help with remind files" t)
|
||||
;; also put (add-to-list 'auto-mode-alist '("\\.rem\\'" . remind-conf-mode)) and
|
||||
;; (setq auto-mode-alist
|
||||
;; (cons '(".reminders$" . remind-conf-mode) auto-mode-alist))
|
||||
;; if you want to have the mode work automatically when you open a remind configuration file.
|
||||
|
||||
;; If you want to use the auto-complete stuff, you will need to download and install the
|
||||
;; auto-complete library from http://www.cx4a.org/pub/auto-complete.el and put
|
||||
;; (require 'auto-complete) in your emacs with
|
||||
;; (add-hook 'remind-conf-mode-hook
|
||||
;; (lambda ()
|
||||
;; (make-local-variable 'ac-sources)
|
||||
;; (setq ac-sources '(ac-remind-conf ac-remind-builtin-variables ac-remind-builtin-functions))
|
||||
;; (auto-complete t)))
|
||||
;; in your .emacs file
|
||||
|
||||
;; PS. you could add ac-source-abbrev ac-source-words-in-buffer to have abbrevs and
|
||||
;; other words in buffer auto-complete too
|
||||
|
||||
;;; History:
|
||||
;; Thu, Feb 14, 2008
|
||||
;; Based mode on wpld-mode tutorial and sample-mode on emacs wiki.
|
||||
;; Ideas from mupad.el for font-lock styles.
|
||||
;; Mon, Jan 26, 2008
|
||||
;; Added rem-setup-colors to make it easy for colourised remind output.
|
||||
;; Added a demo skeleton for people to copy for easy entry of coloured remind entries.
|
||||
;; tried to hook in the auto-complete library so that all known functions and keywords can be easily entered.
|
||||
;; EXPERIMENTAL, but seems to work well here (emacs cvs).
|
||||
;; Seems to work without case folding which is nice. wonder why it didn't yesterday?
|
||||
|
||||
;;; Code:
|
||||
|
||||
|
||||
(require 'font-lock); this goes in the define-derived-mode part.
|
||||
(when (featurep 'xemacs)
|
||||
(require 'overlay)) ;I wonder if this will help with font-lock and xemacs?
|
||||
|
||||
|
||||
(defgroup remind-conf nil
|
||||
"Options for remind-conf-mode."
|
||||
:group 'remind-conf
|
||||
:prefix "remind-conf-")
|
||||
|
||||
|
||||
(defvar remind-conf-mode-hook nil
|
||||
"Hook to run in `remind-conf-mode'.")
|
||||
|
||||
;; keymap
|
||||
|
||||
(defvar remind-conf-mode-map
|
||||
(let ((remind-conf-mode-map (make-sparse-keymap)))
|
||||
remind-conf-mode-map)
|
||||
"Keymap for `remind-conf-mode'.")
|
||||
|
||||
(define-key remind-conf-mode-map "\C-cr" 'rem-skel)
|
||||
(define-key remind-conf-mode-map "\C-ct" 'rem-today)
|
||||
(define-key remind-conf-mode-map "\C-cd" 'rem-today-skel)
|
||||
(define-key remind-conf-mode-map "\C-cw" 'rem-week-away)
|
||||
(define-key remind-conf-mode-map "\C-cx" 'rem-tomorrow)
|
||||
(define-key remind-conf-mode-map "\C-ca" '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
|
||||
|
||||
(defvar remind-conf-syntax-table
|
||||
(let ((remind-conf-syntax-table (make-syntax-table text-mode-syntax-table)))
|
||||
(modify-syntax-entry ?\; ". 1b" remind-conf-syntax-table)
|
||||
(modify-syntax-entry ?\# ". 1b" remind-conf-syntax-table)
|
||||
(modify-syntax-entry ?\n "> b" remind-conf-syntax-table)
|
||||
;Names with _ are still one word.
|
||||
(modify-syntax-entry ?_ "w" remind-conf-syntax-table)
|
||||
(modify-syntax-entry ?. "w" remind-conf-syntax-table)
|
||||
remind-conf-syntax-table)
|
||||
"Syntax table for `remind-conf-mode'.")
|
||||
|
||||
;;; keyword sets
|
||||
|
||||
(defconst remind-keywords
|
||||
(sort
|
||||
(list "RUN" "REM" "ONCE" "SATISFY" "BEFORE" "UNSET" "OMIT"
|
||||
"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"
|
||||
"CLEAR-OMIT-CONTEXT" "POP-OMIT-CONTEXT" "SET" "ERRMSG" "FSET"
|
||||
"EXIT" "FLUSH" "PRESERVE" "MOON" "COLOR" "COLOUR")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
(defconst remind-type-keywords
|
||||
(sort
|
||||
(list "INT" "STRING" "TIME" "DATE" "SHADE")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
(defconst remind-builtin-variables
|
||||
(sort
|
||||
(list "$CalcUTC" "$CalMode" "$DefaultPrio" "$EndSent" "$EndSentIg" "$NumTrig"
|
||||
"$FirstIndent" "$FoldYear" "$FormWidth" "$MinsFromUTC" "$LatDeg" "$LatMin" "$LatSec"
|
||||
"$Location" "$LongDeg" "$LongMin" "$LongSec" "$MaxSatIter" "$SubsIndent")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
(defconst remind-time-words
|
||||
(sort
|
||||
(list "Jan" "January" "Feb" "Mar" "Apr" "Jun" "Jul" "Aug" "Sept" "Sep" "Oct" "Nov" "Dec" "February" "March" "April" "May" "June" "July" "August" "September" "October" "November" "December" "Mon" "Monday" "Tue" "Tues" "Tuesday" "Wed" "Wednesday" "Thu" "Thursday" "Fri" "Friday" "Saturday" "Sat" "Sun" "Sunday")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
(defconst remind-builtin-functions
|
||||
(sort
|
||||
(list "abs" "access" "shell" "args" "asc" "baseyr" "char" "choose" "coerce" "date"
|
||||
"dawn" "today" "day" "daysinmon" "defined" "dosubst" "dusk" "easterdate" "easter"
|
||||
"filedir" "filename" "getenv" "hour" "iif" "trigger" "index" "isdst" "isleap"
|
||||
"isomitted" "hebdate" "hebday" "hebmon" "hebyear" "language" "ord" "thisyear"
|
||||
"sunrise" "sunset" "lower" "max" "min" "minute" "mon" "moondate" "moontime"
|
||||
"moonphase" "now" "ostype" "plural" "realnow" "realtoday" "sgn" "strlen" "psshade"
|
||||
"substr" "trigdate" "trigger" "trigtime" "trigvalid" "typeof" "upper" "psmoon"
|
||||
"value" "version" "wkday" "wkdaynum" "msgprefix" "msgsuffix" "year")
|
||||
#'(lambda (a b) (> (length a) (length b)))))
|
||||
|
||||
;;; faces
|
||||
;;example of setting up special faces for a mode.
|
||||
|
||||
(defvar remind-conf-command-face 'remind-conf-command-face
|
||||
"Remind commands.")
|
||||
(defface remind-conf-command-face
|
||||
'((t :foreground "SeaGreen4" :bold t))
|
||||
"Font Lock mode face used to highlight commands."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-conf-keyword-face 'remind-conf-keyword-face
|
||||
"Remind keywords.")
|
||||
(defface remind-conf-keyword-face
|
||||
'((t :foreground "blue violet"))
|
||||
"Font Lock mode face used to highlight keywords."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-conf-substitutes-face 'remind-conf-substitutes-face
|
||||
"Remind substitutes.")
|
||||
(defface remind-conf-substitutes-face
|
||||
'((t :foreground "blue2"))
|
||||
"Font Lock mode face used to highlight substitutes."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-conf-endline-face 'remind-conf-endline-face
|
||||
"Remind endline.")
|
||||
(defface remind-conf-endline-face
|
||||
'((t :foreground "goldenrod2" :bold t))
|
||||
"Font Lock mode face used to highlight commands."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-conf-variable-face 'remind-conf-variable-face
|
||||
"Remind variable.")
|
||||
(defface remind-conf-variable-face
|
||||
'((t :foreground "DeepPink2" :bold t))
|
||||
"Font Lock mode face used to highlight commands."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-conf-color-face 'remind-conf-color-face
|
||||
"Remind color variables.")
|
||||
(defface remind-conf-color-face
|
||||
'((t :foreground "gold" :bold t))
|
||||
"Font Lock mode face used to highlight color changes."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-conf-delta-face 'remind-conf-delta-face
|
||||
"Remind deltas.")
|
||||
(defface remind-conf-delta-face
|
||||
'((t :foreground "sandy brown" :bold t))
|
||||
"Font Lock mode face used to highlight deltas."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-comment-face 'remind-comment-face
|
||||
"Remind comments.")
|
||||
(defface remind-comment-face
|
||||
'((t :foreground "brown"))
|
||||
"Font-lock face for highlighting comments."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-string-face 'remind-string-face
|
||||
"Remind strings.")
|
||||
(defface remind-string-face
|
||||
'((t :foreground "tomato"))
|
||||
"Font lock mode face used to highlight strings."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-time-face 'remind-time-face
|
||||
"Remind time words.")
|
||||
(defface remind-time-face
|
||||
'((t :foreground "LightSeaGreen" :bold t))
|
||||
"Font lock mode face to highlight time phrases."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defvar remind-conf-type-face 'remind-conf-type-face
|
||||
"Remind type keywords.")
|
||||
(defface remind-conf-type-face
|
||||
'((t :foreground "orange" :bold t))
|
||||
"Font lock mode face to highlight type keywords."
|
||||
:group 'remind-conf)
|
||||
|
||||
(defcustom rem-post-save-function ""
|
||||
"Name of shell function that can be run when you save and close a remind file.
|
||||
|
||||
If you put a & after the name of the function, it will run asyncronously. This might
|
||||
be useful if the process takes a long time."
|
||||
:type 'string
|
||||
:group 'remind-conf
|
||||
)
|
||||
|
||||
;; keywords
|
||||
|
||||
(defconst remind-conf-font-lock-keywords-1
|
||||
(list
|
||||
'("^[\;\#]\\s-+.*$" . remind-comment-face)
|
||||
(cons (regexp-opt remind-keywords 'words) remind-conf-keyword-face)
|
||||
'("%[\"_]" . font-lock-warning-face)
|
||||
'("\\(%[a-mops-w]\\)" . remind-conf-substitutes-face)
|
||||
'("\"[^\"]*\"" . remind-string-face))
|
||||
"Minimal font-locking for `remind-conf-mode'.")
|
||||
|
||||
(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-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)
|
||||
'("\[[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-+\\(\\(?: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)))
|
||||
"The ultimate in highlighting experiences for `remind-conf-mode'.")
|
||||
|
||||
(defcustom remind-conf-font-lock-keywords 'remind-conf-font-lock-keywords-3
|
||||
"Font-lock highlighting level for `remind-conf-mode'."
|
||||
:group 'remind-conf
|
||||
:type '(choice (const :tag "Barest minimum of highlighting." remind-conf-font-lock-keywords-1)
|
||||
(const :tag "Medium highlighting." remind-conf-font-lock-keywords-2)
|
||||
(const :tag "Highlighting deluxe." remind-conf-font-lock-keywords-3)))
|
||||
|
||||
;;; Indentation (I'm sure this could be made more simple. But at least it works.)
|
||||
|
||||
(defcustom remind-indent-level 4
|
||||
"User definable indentation."
|
||||
:group 'remind-conf
|
||||
:type '(integer)
|
||||
)
|
||||
|
||||
(defun remind-indent-line ()
|
||||
"Indent current line for remind configuration files."
|
||||
(interactive)
|
||||
(forward-line 0) ;remember this happens on every line as it is done per line basis
|
||||
(if (bobp)
|
||||
(indent-line-to 0)
|
||||
(let ((not-indented t) cur-indent)
|
||||
(if (looking-at "^[ \t]*\\<\\(ENDIF\\|POP\\(?:-OMIT-CONTEXT\\)?\\)\\>")
|
||||
(progn
|
||||
(save-excursion
|
||||
(forward-line -1)
|
||||
(setq cur-indent (- (current-indentation) remind-indent-level))) ;note that not-indented is still t
|
||||
(if (< cur-indent 0) (setq cur-indent 0)))
|
||||
(save-excursion
|
||||
(while not-indented
|
||||
(forward-line -1)
|
||||
(if (looking-at "^[ \t]*\\<\\(ENDIF\\|POP\\(?:-OMIT-CONTEXT\\)?\\)\\>")
|
||||
(progn
|
||||
(setq cur-indent 0)
|
||||
(delete-horizontal-space) ;don't know why I need this when other similar indent functions don't.
|
||||
(setq not-indented nil))
|
||||
(if (looking-at "\\<\\(IF\\(?:TRIG\\)?\\|PUSH\\(?:-OMIT-CONTEXT\\)?\\)\\>")
|
||||
(progn
|
||||
(setq cur-indent remind-indent-level)
|
||||
(setq not-indented nil))
|
||||
(if (bobp)
|
||||
(setq not-indented nil))))))
|
||||
(if cur-indent
|
||||
(indent-line-to cur-indent)
|
||||
(indent-line-to 0))))))
|
||||
|
||||
;;; Convenience functions
|
||||
|
||||
(define-skeleton rem-skel
|
||||
"Skeleton to insert a rem line in a remind configuration file."
|
||||
nil
|
||||
"REM "(skeleton-read "Date? " )
|
||||
("Optional: How many days ahead? " " +" str )
|
||||
resume:
|
||||
("Optional: At what time? Format eg 13:00. " " AT " str)
|
||||
resume:
|
||||
("Optional: How many minutes ahead? " " +" str )
|
||||
resume:
|
||||
("Optional: At what priority? eg 0-9999" " PRIORITY " str )
|
||||
resume:
|
||||
" MSG %\"" (skeleton-read "Your message? " )"%b%\"%" \n
|
||||
)
|
||||
|
||||
(define-skeleton rem-today-skel
|
||||
"Skeleton to insert a line for today's date."
|
||||
nil
|
||||
"REM " (format-time-string "%d %b %Y")
|
||||
("Optional: At what time? Format eg 13:20. " " AT " str)
|
||||
resume:
|
||||
("Optional: How many minutes ahead? " " +" str )
|
||||
resume:
|
||||
("Optional: At what priority? eg 0-9999" " PRIORITY " str )
|
||||
resume:
|
||||
" MSG " (skeleton-read "Your message? " )"%b.%" \n
|
||||
)
|
||||
|
||||
(defun rem-today ()
|
||||
"Insert the date for today in a remind friendly style."
|
||||
(interactive)
|
||||
(insert (format-time-string "%e %b %Y")))
|
||||
|
||||
(defun rem-tomorrow ()
|
||||
"Insert tomorrow's date in a remind friendly style."
|
||||
(interactive)
|
||||
(insert (format-time-string "%e %b %Y" (time-add (current-time) (days-to-time 1)))))
|
||||
|
||||
(defun rem-days-away (arg)
|
||||
"Insert a day N number of days in the future.
|
||||
|
||||
Takes a prefix argument, but defaults to 4."
|
||||
(interactive "nHow many Days?: ")
|
||||
(insert (format-time-string "%e %b %Y" (time-add (current-time) (days-to-time arg)))))
|
||||
|
||||
(defun rem-week-away ()
|
||||
"Insert a day 7 days in the future."
|
||||
(interactive)
|
||||
(insert (format-time-string "%e %b %Y" (time-add (current-time) (days-to-time 7)))))
|
||||
|
||||
(setq skeleton-end-hook nil) ; so the skeletons will not automatically go to a new line.
|
||||
|
||||
;;; private function
|
||||
;; could make it useful for others. Put somethin like the following in your .emacs
|
||||
;(setq rem-post-save-function "~/bin/dailypic &")
|
||||
|
||||
(defun rem-save-file ()
|
||||
"Save the file and start the shell function in one go.
|
||||
|
||||
This function will close the window after running. It needs the
|
||||
variable `rem-post-save-function' to be set. It will be most
|
||||
useful to people who have some sort of function they run to use
|
||||
remind data ie procucing calendars."
|
||||
(interactive)
|
||||
(if (boundp 'rem-post-save-function)
|
||||
(progn (save-buffer)
|
||||
(shell-command rem-post-save-function)
|
||||
(kill-buffer-and-window))
|
||||
(error "`rem-post-save-function' variable is not set")))
|
||||
|
||||
(defun rem-setup-colors ()
|
||||
"Insert set of variables for coloured output in remind messages."
|
||||
(interactive)
|
||||
(find-file (expand-file-name "~/.reminders"))
|
||||
(goto-char 0) ;we do want it somewhere near the top of the file.
|
||||
(save-excursion
|
||||
(re-search-forward "\n\n"); squeeze it in where you have a free line.
|
||||
(insert "\nSET Esc CHAR(27)
|
||||
SET Nrm Esc + \"[0m\"
|
||||
SET Blk Esc + \"[0;30m\"
|
||||
SET Red Esc + \"[0;31m\"
|
||||
SET Grn Esc + \"[0;32m\"
|
||||
SET Ylw Esc + \"[0;33m\"
|
||||
SET Blu Esc + \"[0;34m\"
|
||||
SET Mag Esc + \"[0;35m\"
|
||||
SET Cyn Esc + \"[0;36m\"
|
||||
SET Wht Esc + \"[0;37m\"
|
||||
SET Gry Esc + \"[30;1m\"
|
||||
SET BrRed Esc + \"[31;1m\"
|
||||
SET BrGrn Esc + \"[32;1m\"
|
||||
SET BrYlw Esc + \"[33;1m\"
|
||||
SET BrBlu Esc + \"[34;1m\"
|
||||
SET BrMag Esc + \"[35;1m\"
|
||||
SET BrCyn Esc + \"[36;1m\"
|
||||
SET BrWht Esc + \"[37;1m\" \n \n")))
|
||||
|
||||
;; So now you can do things like:
|
||||
|
||||
(define-skeleton birthcol
|
||||
"Make birthdays magenta.
|
||||
Acts on the region or places point where it needs to be."
|
||||
nil
|
||||
"[Mag]" _ " [Nrm]")
|
||||
|
||||
;; finally the derived mode.
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode remind-conf-mode text-mode "REM"
|
||||
"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) "#")
|
||||
(set (make-local-variable 'comment-end) "\n")
|
||||
(set (make-local-variable 'fill-column) '100);cause I was having problems with autofill.
|
||||
(set (make-local-variable 'indent-line-function) 'remind-indent-line)
|
||||
(use-local-map remind-conf-mode-map)
|
||||
)
|
||||
|
||||
|
||||
(provide 'remind-conf-mode)
|
||||
;;; remind-conf-mode.el ends here
|
||||
|
||||
;;; Indentation code
|
||||
;;; work out how to make the syntax highlighting work only before the (MSG|MSF)
|
||||
;;; keywords and not after.
|
||||
;;; for my own use. keymap to save file and do dailypic C-c C-c in time honoured tradition?
|
||||
@@ -1,3 +0,0 @@
|
||||
$Id: README.AMIGA,v 1.5 2005-09-30 03:36:19 dfs Exp $
|
||||
|
||||
Remind no longer works on AmigaDOS.
|
||||
@@ -1,3 +0,0 @@
|
||||
$Id: README.BCC,v 1.5 2005-09-30 03:36:19 dfs Exp $
|
||||
|
||||
Remind no longer works with Borland C Compiler.
|
||||
@@ -1,3 +0,0 @@
|
||||
$Id: README.DOS,v 1.5 2005-09-30 03:36:19 dfs Exp $
|
||||
|
||||
Remind no longer works on MS-DOS.
|
||||
@@ -1,3 +0,0 @@
|
||||
$Id: README.OS2,v 1.6 2005-09-30 03:36:20 dfs Exp $
|
||||
|
||||
Remind no longer works on OS/2.
|
||||
@@ -1,5 +1,4 @@
|
||||
$Id: README.UNIX,v 1.5 2000-02-18 03:45:33 dfs Exp $
|
||||
REMIND version 3.0 for UNIX
|
||||
REMIND version 3.1 for UNIX
|
||||
|
||||
REMIND is a sophisticated alarm/calendar program. Details are given
|
||||
in the man page, "remind.1".
|
||||
@@ -29,30 +28,6 @@ If you do NOT have Tcl/Tk or are NOT running X Windows:
|
||||
The subdirectory "www" contains scripts for making a nice calendar
|
||||
web server. See the files README and Makefile in that directory.
|
||||
|
||||
Two shell scripts, "scripts/remind-all.csh" and
|
||||
"scripts/remind-all.sh" are provided. These allow automatic mailing of
|
||||
reminders to all users who create a $HOME/.reminders file. These two
|
||||
scripts are equivalent; one is a "sh" script and the other is a "csh"
|
||||
script. Pick the one you want to use, and follow the instructions in
|
||||
the opening comments of the script.
|
||||
|
||||
A shell script called "scripts/rem" is provided for those who like to have
|
||||
'remind' assume a default reminders file. A man page for this script
|
||||
is provided. You should examine the script to ensure that the defaults
|
||||
are correct.
|
||||
|
||||
Many people have asked me why I supply the "rem" script instead of
|
||||
having Remind assume a default file. The answer is: That's how I like
|
||||
it! My personal preference is for a program which normally takes
|
||||
parameters to display usage information when invoked with no
|
||||
parameters. I like that behaviour so I can quickly get an idea of
|
||||
what a program does without poring through the man page. And I think
|
||||
I'll keep Remind that way. Sorry to all who dislike it. :-)
|
||||
|
||||
A shell script called "scripts/kall" is provided so you can kill your
|
||||
background remind processes when you log out. See the man page. Note
|
||||
that kall depends on the output of "ps", and may not be portable.
|
||||
|
||||
The file "examples/defs.rem" has some sample Remind definitions and
|
||||
commands, as well as U.S. and Jewish holidays.
|
||||
|
||||
@@ -126,9 +101,4 @@ exit
|
||||
|
||||
--
|
||||
David F. Skoll <dfs@roaringpenguin.com>
|
||||
986 Eiffel Avenue
|
||||
Ottawa, Ontario K2C 0J2
|
||||
CANADA
|
||||
|
||||
Tel. (613) 225-8687
|
||||
http://www.roaringpenguin.com/remind.html
|
||||
http://www.roaringpenguin.com/remind/
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
$Id: README_QDOS,v 1.6 2005-09-30 03:36:20 dfs Exp $
|
||||
|
||||
Remind no longer works on QDOS.
|
||||
@@ -1,6 +1,347 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* Version 3.0 Patch 24
|
||||
* Version 3.1 Patch 12 - 2012-01-23
|
||||
|
||||
- NEW FEATURE: Many substitution sequences "%x" have an alternate mode
|
||||
denoted by "%*x". This alternate mode leaves out prepositions. For
|
||||
example, in English "%i" might yield "on 01-25" while "%*i" yields only
|
||||
"01-25".
|
||||
|
||||
- BUG FIX: The "dusk" and "dawn" calculations were completely wrong. They
|
||||
have been fixed. Also, sunrise/sunset calculations have been tweaked,
|
||||
so the results may be off by a minute or two compared to previous versions
|
||||
of Remind.
|
||||
|
||||
* Version 3.1 Patch 11 - 2011-12-16
|
||||
|
||||
- BUG FIX: For some inexplicable reason, dawn was considered to happen when
|
||||
the sun was 14 degrees below the horizon instead of the standard 6
|
||||
degrees for Civil Dawn. This has been fixed.
|
||||
|
||||
- BUG FIXES: Clarified the man pages and fixed some typos.
|
||||
|
||||
- BUG FIX: Add THROUGH to the remind.vim syntax highlighting file.
|
||||
|
||||
- ENHANCEMENT (?): Allow SPECIAL COLOR to be spelled SPECIAL COLOUR.
|
||||
|
||||
- BUG FIX: Apply minor Debian cleanups reported by Kurt B. Kaiser.
|
||||
|
||||
* Version 3.1 Patch 10 - 2010-11-01
|
||||
|
||||
- NOTE: This is the 20th anniversary of Remind's first public release.
|
||||
|
||||
- ENHANCEMENT: Add the THROUGH keyword. You can omit blocks of dates with:
|
||||
|
||||
OMIT start THROUGH end
|
||||
|
||||
and the syntax REM start THROUGH end is equivalent to REM start *1 UNTIL end
|
||||
|
||||
- ENHANCEMENT: Add support for multibyte characters (eg, UTF-8) in calendar
|
||||
output. Note that UTF-8 strings are still not supported in PostScript
|
||||
output.
|
||||
|
||||
- ENHANCEMENT: Add support for UTF-8 line-drawing characters in calendar
|
||||
output.
|
||||
|
||||
- ENHANCEMENT: You can have multiple TAG clauses in a REM statement.
|
||||
|
||||
- BUG FIX: Avoid spawning long-running background processes in "make test".
|
||||
|
||||
- BUG FIX: Don't declare variables in the middle of statements (old C
|
||||
compilers choke.)
|
||||
|
||||
* Version 3.1 Patch 9 - 2010-06-20
|
||||
|
||||
- MAJOR ENHANCEMENT: New "purge mode" to delete expired reminders. See
|
||||
the PURGE MODE section of the remind man page.
|
||||
|
||||
- ENHANCEMENT: Support DURATION in TkRemind. Thanks to Marek Marczykowski.
|
||||
|
||||
- BUG FIX: Don't change the order of PS and PSFILE reminders. Bug found
|
||||
by John McGowan.
|
||||
|
||||
- BUG FIX: "REM 1990-01-01 SATISFY 1" would yield a spurious parse error
|
||||
in earlier versions of Remind.
|
||||
|
||||
- BUG FIX: Yom HaShoah is moved to Thursday if it would normally fall on
|
||||
a Friday. Thanks to Jonathan Kamens for pointing this out.
|
||||
|
||||
* Version 3.1 Patch 8 - 2010-03-09
|
||||
|
||||
- ENHANCEMENT: Include some useful scripts in contrib/
|
||||
|
||||
- ENHANCEMENT: Add the $T, $Td, $Tm, $Tw, $Ty, $U, $Ud, $Um, $Uw, $Uy
|
||||
special variables to make reminder files less wordy. See man page
|
||||
for details.
|
||||
|
||||
- MINOR ENHANCEMENT: Set an icon photo window manager resource on TkRemind.
|
||||
|
||||
- POLICY CHANGE: Discourage use of Remind on MS Windows or Apple Mac OS X.
|
||||
|
||||
- BUG FIX: Ignore msgprefix() and msgsuffix() on RUN-type reminders.
|
||||
|
||||
- BUG FIX: Adjust Remind and Rem2PS so that SHADE specials don't obliterate
|
||||
earlier MOON specials.
|
||||
|
||||
- BUG FIX: Fix bug in SCHED calculations if Remind is started in the middle
|
||||
of a SCHED interval.
|
||||
|
||||
* Version 3.1 Patch 7 - 2009-05-31
|
||||
|
||||
- ENHANCEMENT: Wherever you could write "day Mon year", the parser now
|
||||
accepts "YYYY-MM-DD". This applies on the command-line and to the
|
||||
REM and OMIT keywords. You can avoid wrapping date calculations in
|
||||
the trigger() function in many cases.
|
||||
|
||||
- ENHANCEMENT: New slide() built-in function eases some complicated reminders.
|
||||
|
||||
* Version 3.1 Patch 6 - 2008-11-16
|
||||
|
||||
- MAJOR ENHANCEMENT: A new OMITFUNC clause gives you additional
|
||||
control and flexibility over "omitted days" calculations. This is
|
||||
useful when holidays influence the timing of events several days
|
||||
later. See "COMPUTED LOCAL OMITS" in the man page.
|
||||
|
||||
- ENHANCEMENT: The new evaltrig() built-in function lets you evaluate triggers
|
||||
from within an expression.
|
||||
|
||||
- ENHANCEMENT: The new weekno() built-in function returns the ISO 8601
|
||||
week number of a date.
|
||||
|
||||
- ENHANCEMENT: The "WEEK" special lets you annotate calendar output with the
|
||||
week number. The TkRemind, rem2ps and rem2html back-ends support WEEK.
|
||||
|
||||
- MINOR ENHANCEMENT: You can control whether timed reminders come before or
|
||||
after non-timed reminders with the "-g" flag.
|
||||
|
||||
- BUG FIX: TkRemind did not work correctly if ~/.reminders was a directory.
|
||||
|
||||
- BUG FIX: TkRemind incorrectly invoked Remind with the "-a" flag when
|
||||
showing today's reminders.
|
||||
|
||||
- BUG FIX: In certain cases, a trigger containing a day, month and
|
||||
weekday would fail if it needed to cross a year boundary. This has
|
||||
been fixed.
|
||||
|
||||
* Version 3.1 Patch 5 - 2008-04-15
|
||||
|
||||
- MAJOR ENHANCEMENT: If you supply a directory name on the command line
|
||||
or for an INCLUDE command, then Remind reads all *.rem file in that
|
||||
directory (in the order returned by "glob")
|
||||
|
||||
- ENHANCEMENT: The plain-text calendar ("-c") can draw lines using VT-100
|
||||
line-drawing characters if invoked as "-cl"
|
||||
|
||||
- ENHANCEMENT: The plain-text calendar can approximate SPECIAL COLOR reminders
|
||||
using VT-100 color escape sequences if invoked as "-cc". (You can combine
|
||||
the colors and line-drawing characters with -clc or -ccl.)
|
||||
|
||||
- ENHANCEMENT: The "-t" option can take a numeric argument n. In this case,
|
||||
all reminders are assumed to have a delta of +n. (Without the argument,
|
||||
an infinite delta is assumed, as before.) If a numeric argument is given,
|
||||
the new system variable $DeltaOffset is set to the argument.
|
||||
|
||||
- MINOR ENHANCEMENT: The "-i" command-line option can be used to define
|
||||
a function as well as set a variable.
|
||||
|
||||
- MINOR ENHANCEMENT: String constants can have embedded quotes "Like \"this"
|
||||
|
||||
- MINOR ENHANCEMENT: tkremind works better on small screens like that of
|
||||
the Eee-PC.
|
||||
|
||||
- BUG FIX: Minor fix to HTML output courtesy of Ian! Allen.
|
||||
|
||||
- BUG FIX: Parse error in calendar mode was fixed.
|
||||
|
||||
* Version 3.1 Patch 4 - 2008-02-03
|
||||
|
||||
- ENHANCMENT: tkremind respects the "-b1" option and operates in 24-hour
|
||||
clock mode if the option is supplied.
|
||||
|
||||
- ENHANCEMENT: tkremind has been tweaked to look better with Tcl/Tk 8.5.
|
||||
|
||||
- CLEANUP: Version is kept only in configure.in instead of two different
|
||||
places.
|
||||
|
||||
- CLEANUP: Added "const" qualifier to many places in the code that previously
|
||||
lacked it.
|
||||
|
||||
- BUG FIX: A rare parsing error involving interaction between SATISFY and
|
||||
SKIP has been fixed.
|
||||
|
||||
- BUG FIX: rem2html would output a horribly-wrong calendar for a 28-day
|
||||
February starting on Sunday (such as February 2009.) This has been fixed.
|
||||
|
||||
- BUG FIX: The "-ivar=value" command-line option failed if Remind re-execed
|
||||
itself because we overwrote argv[]. This has been fixed.
|
||||
|
||||
* Version 3.1 Patch 3 - 2007-10-15
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- rem2html now uses CSS for a much better-looking calendar.
|
||||
NOTE: rem2html was completely rewritten and some of the command-line
|
||||
options have changed!
|
||||
|
||||
- If a reminder has a DURATION clause, then the starting and ending times
|
||||
are output in calendar mode.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- DST rules in "defs.rem" were updated to reflect new US/Canadian DST rules.
|
||||
|
||||
- If a REM command cannot compute a trigger date, the SATISFY expression
|
||||
is not evaluated. This helps avoid spurious error messages in some
|
||||
reminders.
|
||||
|
||||
* Version 3.1 Patch 2 - 2007-09-12
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- build.tk tries to set defaults for location, paper size, etc from an
|
||||
existing "remind" installation if it detects one.
|
||||
|
||||
- In queue mode, wake up once a minute and recalibrate sleep time.
|
||||
This should make Remind work better on laptops that suspend or
|
||||
hibernate. Note that "remind -q" does *not* handle date-rollover
|
||||
well; it simply exits if it notices date rollover. "remind -z0"
|
||||
(as used by tkremind) handles date rollover properly; it rereads the
|
||||
reminder file and rebuilds the queue if it notices date rollover.
|
||||
|
||||
- tkremind: Added some key bindings to make navigation easier.
|
||||
|
||||
- tkremind: Made calendar boxes use space more efficiently.
|
||||
|
||||
- remind: The functionality of "rem" is now built into remind. If you
|
||||
invoke remind as "rem", then it uses a default filename. The installer
|
||||
sets up "rem" as a symbolic link to "remind".
|
||||
|
||||
+ CHANGE
|
||||
|
||||
- "remind -p" no longer sorts SPECIAL reminders before non-SPECIAL.
|
||||
|
||||
*** THIS MAY AFFECT BACKENDS ***
|
||||
|
||||
Backends supplied by Roaring Penguin (rem2ps, rem2html and tkremind)
|
||||
are known to work properly.
|
||||
|
||||
- "remind -p" no longer suppresses any AT-time associated with SPECIAL
|
||||
reminders.
|
||||
|
||||
*** THIS MAY AFFECT BACKENDS ***
|
||||
|
||||
Backends supplied by Roaring Penguin (rem2ps, rem2html and tkremind)
|
||||
are known to work properly.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- examples/defs.rem: A few corrections to Jewish holidays courtesy of
|
||||
Art Werschulz.
|
||||
|
||||
- src/Makefile.in: Added install-nostripped target.
|
||||
|
||||
- SPECIAL COLOR now works more like MSG, including proper support for AT and
|
||||
for the %" %" escape sequence.
|
||||
|
||||
- SPECIAL COLOR is queued correctly if it has an AT clause.
|
||||
|
||||
- Using the psshade() or psmoon() functions emits a warning on stderr. You
|
||||
should use SPECIAL SHADE or SPECIAL MOON instead.
|
||||
|
||||
* Version 3.1 Patch 1 - 2007-08-23
|
||||
|
||||
+ MAJOR ENHANCEMENTS
|
||||
|
||||
- Added the "nonomitted" function that solves a number of
|
||||
moving-reminder-in-response-to-holiday problems. The real-world
|
||||
problems solved are the "moving-garbage-day" problem and the
|
||||
"six-day-school-cycle" problem.
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- A few minor performance improvements in response to profiling runs.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- Prevent compilation failure with gcc 2.95.
|
||||
|
||||
- Fix trailing "s" bug with -k option. This was fixed in Debian's release,
|
||||
but the Debian maintainer never bothered to let me know.
|
||||
|
||||
- Removed obsolete scripts: kall, rem, remind-all.sh, remind-all.csh
|
||||
|
||||
- Made "-n" output always use "/" as date separator for consistency with
|
||||
"-p" and "-s".
|
||||
|
||||
- Moon PNG images are transparent. Output of moon phases in rem2html
|
||||
improved slightly.
|
||||
|
||||
- Various man-page fixes.
|
||||
|
||||
* Version 3.1 Patch 0 - 2007-07-14
|
||||
|
||||
+ MAJOR ENHANCEMENTS
|
||||
|
||||
- Added the FROM clause. This lets you write reminders like:
|
||||
|
||||
REM Mon FROM 16 July 2007 UNTIL 13 Aug 2007 MSG Some Mondays...
|
||||
|
||||
- Remind now has a new datatype: A DATETIME object represents a date AND
|
||||
a time (to the nearest minute). DATETIME constants are written
|
||||
as '2007-09-01@14:33'. Various operators and functions have been
|
||||
modified to do sensible things with DATETIMEs and several new DATETIME
|
||||
functions have been added.
|
||||
|
||||
- The SPECIAL COLOR reminder type has been hacked to behave more like
|
||||
a MSG type. It sorts properly and is emitted as a normal reminder
|
||||
in non-calendar mode. Simlarly, SPECIAL HTML sorts with -g as well.
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- TkRemind can e-mail you reminders if you don't dismiss the popup window
|
||||
after one minute. This is useful if you need to leave your workstation
|
||||
but want reminders to "follow" you via e-mail.
|
||||
|
||||
- A new "-y" option to Remind generates tags for all reminders that lack
|
||||
a TAG clause. This may be useful for conversion tools that want each
|
||||
reminder to have a unique identifier.
|
||||
|
||||
- A new "tzconvert" function lets you convert datetimes between different
|
||||
time zones. It's only as good as your C library, so test thoroughly
|
||||
please! Based on a patch from Stefan Wehr.
|
||||
|
||||
- TkRemind sorts reminders by invoking Remind with the '-g' option.
|
||||
|
||||
- The time and date separator characters can be changed at runtime by
|
||||
setting $TimeSep and $DateSep respectively.
|
||||
|
||||
- The simple calendar ('-s') option can be immediately followed by an 'a'.
|
||||
This causes Remind to output reminders with deltas before the actual
|
||||
trigger date. Based loosely on an idea from Frank Terbeck.
|
||||
|
||||
+ MINOR CHANGES
|
||||
|
||||
- Default date separator is now '-' instead of '/'
|
||||
|
||||
- trigdate() and trigtime() behave differently - they return the integer 0
|
||||
if the last reminder could not be computed or did not have an AT clause
|
||||
(respectively).
|
||||
|
||||
- Maximum length of variable names has been increased from 12 to 16 characters.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- Fixed a potential memory leak in queue.c
|
||||
|
||||
- Fixed compile error on Mac OS X.
|
||||
|
||||
- Fixed behaviour of "-sa" option so deltas correctly obey omitted days
|
||||
and the scheduling function (if one is used).
|
||||
|
||||
- rem2ps would produce invalid PostScript in some rare cases
|
||||
(eg, for February 2007). This has been fixed.
|
||||
|
||||
* Version 3.0 Patch 24 - 2005-11-19
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
@@ -23,7 +364,7 @@ CHANGES TO REMIND
|
||||
- Fixed a bug in the tokenizer that could make Remind segfault. Fix courtesy
|
||||
of Stan Tobias.
|
||||
|
||||
* Version 3.0 Patch 23
|
||||
* Version 3.0 Patch 23 - 2005-04-14
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
@@ -47,7 +388,7 @@ CHANGES TO REMIND
|
||||
|
||||
- Fixed parser error for unterminated date constant: '2005/01/01
|
||||
|
||||
* Version 3.0 Patch 22
|
||||
* Version 3.0 Patch 22 - 2000-06-16
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
@@ -69,7 +410,7 @@ CHANGES TO REMIND
|
||||
- Fixed serious bug in which background queued reminders were ignored and
|
||||
Remind simply exited. Doh! Sorry about that.
|
||||
|
||||
* Version 3.0 Patch 21
|
||||
* Version 3.0 Patch 21 - 2000-03-15
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
@@ -100,7 +441,7 @@ CHANGES TO REMIND
|
||||
|
||||
- Fixed compilation problem on FreeBSD, IRIX, Tru64 and other UNIXes.
|
||||
|
||||
* Version 3.0 Patch 20
|
||||
* Version 3.0 Patch 20 - 1999-04-12
|
||||
|
||||
+ NEWS
|
||||
|
||||
@@ -129,7 +470,7 @@ CHANGES TO REMIND
|
||||
|
||||
- Fixed a typo in danish.h, courtesy of Niels Kristian Bech Jensen.
|
||||
|
||||
* Version 3.0 Patch 19
|
||||
* Version 3.0 Patch 19 - 1998-05-09
|
||||
|
||||
+ MAJOR ENHANCEMENTS
|
||||
|
||||
@@ -171,7 +512,7 @@ CHANGES TO REMIND
|
||||
- Lots more silly little bugs squashed -- too many to go into in
|
||||
detail.
|
||||
|
||||
* Version 3.0 Patch 18
|
||||
* Version 3.0 Patch 18 - 1998-02-15
|
||||
|
||||
+ MAJOR ENHANCEMENTS
|
||||
|
||||
@@ -235,7 +576,7 @@ CHANGES TO REMIND
|
||||
- Getting rid of fixed-sized buffers meant lots of changes to code.
|
||||
No doubt, I missed a few regression tests.
|
||||
|
||||
* Version 3.0 Patch 17
|
||||
* Version 3.0 Patch 17 - 1997-09-07
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
@@ -276,7 +617,7 @@ CHANGES TO REMIND
|
||||
library. All three of these fixes are courtesy of Christopher
|
||||
J. Madsen <madsen@iglobal.net>. Thanks, Christopher.
|
||||
|
||||
* Version 3.0 Patch 16
|
||||
* Version 3.0 Patch 16 - 1997-02-11
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
@@ -304,7 +645,7 @@ CHANGES TO REMIND
|
||||
- Fixed a problem under Solaris 2.5 whereby rem2ps was skipping some
|
||||
latin1 characters which it interpreted as white space.
|
||||
|
||||
* Version 3.0 Patch 15
|
||||
* Version 3.0 Patch 15 - 1996-10-27
|
||||
|
||||
+ IMPORTANT NOTES
|
||||
|
||||
@@ -334,7 +675,7 @@ CHANGES TO REMIND
|
||||
- Fixed bug in TkRemind which caused a crash if the "-m" option was used
|
||||
for a month beginning on Sunday. Doh!!!
|
||||
|
||||
* Version 3.0 Patch 14
|
||||
* Version 3.0 Patch 14 - 1996-05-25
|
||||
|
||||
+ CHANGE IN COPYING POLICY
|
||||
|
||||
@@ -393,7 +734,7 @@ CHANGES TO REMIND
|
||||
_not_ support MS Windows, and in fact do not allow Remind to run
|
||||
under Windows (see COPYRIGHT).
|
||||
|
||||
* Version 3.0 Patch 13
|
||||
* Version 3.0 Patch 13 - 1994-05-06
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
@@ -428,7 +769,7 @@ CHANGES TO REMIND
|
||||
|
||||
- Updated the copyright notices everywhere.
|
||||
|
||||
* Version 3.0 Patch 12
|
||||
* Version 3.0 Patch 12 - 1994-02-01
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
@@ -447,7 +788,7 @@ CHANGES TO REMIND
|
||||
- Fixed a problem with the '-k' option which resulted in a newline being
|
||||
placed after the message text. This was giving sh(1) heartburn...
|
||||
|
||||
* Version 3.0 Patch 11
|
||||
* Version 3.0 Patch 11 - 1993-11-26
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
@@ -527,7 +868,7 @@ CHANGES TO REMIND
|
||||
|
||||
- Fixed the Finnish language support which was missing a few newlines.
|
||||
|
||||
* Version 3.0 Patch 9
|
||||
* Version 3.0 Patch 9 - 1993-10-04
|
||||
|
||||
+ NOTES
|
||||
|
||||
@@ -584,7 +925,7 @@ CHANGES TO REMIND
|
||||
so that newlines in the body start new paragraphs, rather than being
|
||||
swallowed as white-space.
|
||||
|
||||
* Version 3.0 Patch 8
|
||||
* Version 3.0 Patch 8 - 1993-09-08
|
||||
|
||||
+ MAJOR ENHANCEMENTS
|
||||
|
||||
@@ -636,7 +977,7 @@ CHANGES TO REMIND
|
||||
range [-128, 255] (but not 0) so that char(asc(s)) works even
|
||||
on machines with signed char types.
|
||||
|
||||
* Version 3.0 Patch 7
|
||||
* Version 3.0 Patch 7 - 1993-07-22
|
||||
|
||||
+ MAJOR ENHANCEMENTS
|
||||
|
||||
@@ -679,7 +1020,7 @@ CHANGES TO REMIND
|
||||
- Changed kall so that "kall sh" doesn't commit suicide - patch courtesy
|
||||
of Michael Salmon.
|
||||
|
||||
* Version 3.0 Patch 6
|
||||
* Version 3.0 Patch 6 - 1993-05-05
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
@@ -702,7 +1043,7 @@ CHANGES TO REMIND
|
||||
- Fixed a bug in the -u option which sometimes caused a core dump
|
||||
(embarrassed grin!) The fix is due to Tina Hoeltig. Thanks, Tina!
|
||||
|
||||
* Version 3.0 Patch 5
|
||||
* Version 3.0 Patch 5 - 1993-04-27
|
||||
|
||||
+ MAJOR ENHANCEMENTS:
|
||||
|
||||
@@ -737,7 +1078,7 @@ CHANGES TO REMIND
|
||||
|
||||
- Fixed a bug in the man page - thanks to Ed Oskiewicz.
|
||||
|
||||
* Version 3.0 Patch 4
|
||||
* Version 3.0 Patch 4 - 1993-03-08
|
||||
|
||||
- Added the -g option - this sorts reminders by date/time before
|
||||
issuing them. (You can see I'm running out of letters to
|
||||
@@ -796,13 +1137,13 @@ CHANGES TO REMIND
|
||||
|
||||
- Put my new mailing address in the README files.
|
||||
|
||||
* Version 3.0 Patch 3
|
||||
* Version 3.0 Patch 3 - 1993-02-21
|
||||
|
||||
- Corrected bugs in Remind and Rem2PS. No new features added. You
|
||||
should NOT use patch level 2 - either stick to 3.0.1 or upgrade to
|
||||
3.0.3.
|
||||
|
||||
* Version 3.0 Patch 2
|
||||
* Version 3.0 Patch 2 - 1993-02-04
|
||||
|
||||
- Added the -u option to Remind so that root can run it as any user.
|
||||
This simplifies the remind-all scripts, and makes them more efficient.
|
||||
@@ -842,7 +1183,7 @@ CHANGES TO REMIND
|
||||
- Changed Remind so that supplying the -a option causes timed reminders
|
||||
not to be placed into the calendar in calendar mode.
|
||||
|
||||
* Version 3.0 Patch 1
|
||||
* Version 3.0 Patch 1 - 1992-12-18
|
||||
|
||||
- Wrote the Rem2ps program to produce PostScript calendars
|
||||
|
||||
@@ -882,7 +1223,7 @@ CHANGES TO REMIND
|
||||
|
||||
- Re-formatted the WHATSNEW.30 file.
|
||||
|
||||
* Version 3.0
|
||||
* Version 3.0 - 1992-11-09
|
||||
|
||||
- Total rewrite from previous versions
|
||||
|
||||
@@ -903,23 +1244,23 @@ CHANGES TO REMIND
|
||||
- Fixed a lurking bug in trigger date calculation which, amazingly, had not
|
||||
been caught in the couple of years that Remind has been out!
|
||||
|
||||
* Version 2.3 Patch 5
|
||||
* Version 2.3 Patch 5 - 1992-04-11
|
||||
|
||||
- Added the "c+n" option for printing a calendar by
|
||||
weeks instead of months, courtesy Dennis Cottel (dennis@peanuts.nosc.mil).
|
||||
|
||||
* Version 2.3 Patch 4
|
||||
* Version 2.3 Patch 4 - 1991-11-06
|
||||
|
||||
- Made the init.c file nicer. Made the Makefile
|
||||
prettier. Added "make test", "make tar" and "make shar" Makefile targets.
|
||||
|
||||
* Version 2.3 Patch 3
|
||||
* Version 2.3 Patch 3 - 1991-09-11
|
||||
|
||||
- Added a command-line option for Remind to process
|
||||
queued reminders in the foreground. This makes automatic termination
|
||||
of Remind processes from within X-Windows and Sunview easier.
|
||||
|
||||
* Version 2.3 Patch 2
|
||||
* Version 2.3 Patch 2 - 1991-07-19
|
||||
|
||||
- Fixed up a problem with timed reminders which resulted
|
||||
in cursor not starting from left side of screen on some systems.
|
||||
@@ -936,7 +1277,7 @@ CHANGES TO REMIND
|
||||
|
||||
- Made the Makefile more portable
|
||||
|
||||
* Version 2.3 Patch 1
|
||||
* Version 2.3 Patch 1 - 1991-03-08
|
||||
|
||||
- Added the "-t" command-line option to get Remind
|
||||
to trigger all non-expired reminders.
|
||||
@@ -950,7 +1291,7 @@ CHANGES TO REMIND
|
||||
|
||||
- Added manual pages for "kall" and "rem".
|
||||
|
||||
* Version 2.3
|
||||
* Version 2.3 - 1991-02-20
|
||||
|
||||
- Added the UNTIL keyword for forcing reminders to expire.
|
||||
|
||||
@@ -972,28 +1313,28 @@ CHANGES TO REMIND
|
||||
- Modified the calendar and SimpleCalendar formats so that the % escape
|
||||
substitutions ARE performed.
|
||||
|
||||
* Version 2.2 - Patch 5
|
||||
* Version 2.2 - Patch 5 - 1990-12-03
|
||||
|
||||
- Added the BEFORE, AFTER and SKIP tokens to make the
|
||||
handling of holidays more sensible. Also corrected a few more bugs.
|
||||
|
||||
* Version 2.2 - Patch 3
|
||||
* Version 2.2 - Patch 3 - 1990-11-28
|
||||
|
||||
- Added the MSG or RUN tokens in an OMIT command; also
|
||||
allowed RUN-type reminders to be explicitly included in the calendar by
|
||||
using the %" escape sequence.
|
||||
|
||||
* Version 2.2
|
||||
* Version 2.2 - 1990-11-16
|
||||
|
||||
- Added the AT keyword, the timed reminders daemon, and the
|
||||
calendar facility.
|
||||
|
||||
* Version 2.1
|
||||
* Version 2.1 - 1990-11-06
|
||||
|
||||
- Added the "repeat" token for repeating reminders with a period
|
||||
other than 7 days. Also fixed some bugs from version 2.0
|
||||
|
||||
* Version 2.0
|
||||
* Version 2.0 - 1990-11-01
|
||||
|
||||
- first public release. Included advanced date specifications,
|
||||
character substitution, and the RUN keyword.
|
||||
@@ -22,17 +22,13 @@
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
#
|
||||
# $Id: defs.rem,v 1.5 2001-05-07 14:06:17 dfs Exp $
|
||||
#
|
||||
|
||||
RUN OFF
|
||||
|
||||
################################################
|
||||
# Ensure required version of remind is used... #
|
||||
################################################
|
||||
IF version() < "03.00.19"
|
||||
ERRMSG This file requires at least version 03.00.19 of Remind.%
|
||||
IF version() < "03.01.08"
|
||||
ERRMSG This file requires at least version 03.01.08 of Remind.%
|
||||
ERRMSG This version is version [version()].
|
||||
EXIT
|
||||
ENDIF
|
||||
@@ -97,53 +93,10 @@ SET Week_1 1
|
||||
SET Week_2 8
|
||||
SET Week_3 15
|
||||
SET Week_4 22
|
||||
FSET _last(mo) "1 " + MON((mo%12)+1)+" --7"
|
||||
|
||||
# Shorthand for commonly used expression...
|
||||
FSET _trig() TRIGGER(TRIGDATE())
|
||||
FSET _last(mo) "1 " + MON((mo%12)+1) + " --7"
|
||||
|
||||
# Handy function to provide SCANFROM dates...
|
||||
FSET _back(days) TRIGGER(TODAY()-days)
|
||||
|
||||
###########################################################
|
||||
# On MS-DOS systems, the standard C library functions are #
|
||||
# not reliable for computing offsets from local time to #
|
||||
# UTC. The following provides a work-around for the #
|
||||
# sunrise() and sunset() functions. Note, however, that #
|
||||
# if Daylight Savings Time is in effect for today(), the #
|
||||
# sun functions return times in DST even for dates on #
|
||||
# which DST is not in effect; the converse can also occur.#
|
||||
# #
|
||||
# Change the timezone to your timezone - the default is #
|
||||
# for EST which is 5 hours (300 minutes) behind UTC. #
|
||||
# The code is correct for places in which Daylight Savings#
|
||||
# Time begins on the last Sunday in April and ends on the #
|
||||
# last Sunday in October. #
|
||||
###########################################################
|
||||
|
||||
IF OSTYPE() == "MSDOS"
|
||||
# Eastern Standard Time
|
||||
SET TimeZone -300
|
||||
|
||||
# Use --8 rather than --7 because we want the last day BEFORE
|
||||
# the time switch occurs.
|
||||
REM Sun 1 May --8 SATISFY 1
|
||||
SET BegDst TRIGDATE()
|
||||
|
||||
REM Sun 1 Nov --8 SATISFY 1
|
||||
SET EndDst TRIGDATE()
|
||||
|
||||
SET $CalcUTC 0
|
||||
|
||||
# Check out the following IF statement and figure out why it works!
|
||||
IF EndDst < BegDst
|
||||
# Daylight Savings Time
|
||||
SET $MinsFromUTC TimeZone+60
|
||||
ELSE
|
||||
# Standard Time
|
||||
SET $MinsFromUTC TimeZone
|
||||
ENDIF
|
||||
ENDIF
|
||||
FSET _back(days) TODAY()-days
|
||||
|
||||
###########################################################
|
||||
# Function which returns a string in "am/pm" format based #
|
||||
@@ -213,14 +166,14 @@ FSET _mail(from, subj) "fastmail -f " + \
|
||||
REM 4 July SCANFROM [_back(7)] SATISFY 1
|
||||
|
||||
IF WKDAYNUM(TRIGDATE()) == Sat
|
||||
REM [TRIGGER(TRIGDATE())] MSG Independence day (actual)
|
||||
OMIT [TRIGGER(TRIGDATE()-1)] MSG Independence day (observed)
|
||||
REM [TRIGDATE()] MSG Independence day (actual)
|
||||
OMIT [TRIGDATE()-1] MSG Independence day (observed)
|
||||
ELSE
|
||||
IF WKDAYNUM(TRIGDATE()) == Sun
|
||||
REM [TRIGGER(TRIGDATE())] MSG Independence day (actual)
|
||||
OMIT [TRIGGER(TRIGDATE()+1)] MSG Independence day (observed)
|
||||
REM [TRIGDATE()] MSG Independence day (actual)
|
||||
OMIT [TRIGDATE()+1] MSG Independence day (observed)
|
||||
ELSE
|
||||
OMIT [TRIGGER(TRIGDATE())] MSG Independence day
|
||||
OMIT [TRIGDATE()] MSG Independence day
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
@@ -241,7 +194,7 @@ REM Mon 8 SATISFY 1
|
||||
# But only actually trigger the delayed meeting if the previous
|
||||
# Monday was a holiday
|
||||
IF ISOMITTED(TRIGDATE()-7)
|
||||
REM [TRIGGER(TRIGDATE())] MSG Delayed meeting
|
||||
REM [TRIGDATE()] MSG Delayed meeting
|
||||
ENDIF
|
||||
|
||||
############################################################################
|
||||
@@ -332,12 +285,12 @@ REM Sat Sun SPECIAL SHADE 220
|
||||
|
||||
SET SaveTrig $NumTrig
|
||||
SET easter EASTERDATE(YEAR(TODAY()))
|
||||
REM [TRIGGER(easter-46)] MSG %"Ash Wednesday%"
|
||||
REM [TRIGGER(easter-7)] MSG %"Palm Sunday%"
|
||||
OMIT [TRIGGER(easter-2)] MSG %"Good Friday%"
|
||||
OMIT [TRIGGER(easter)] MSG %"Easter%" Sunday
|
||||
REM [TRIGGER(easter+39)] MSG %"Ascension Day%"
|
||||
REM [TRIGGER(easter+49)] MSG %"Pentecost%"
|
||||
REM [easter-46] MSG %"Ash Wednesday%"
|
||||
REM [easter-7] MSG %"Palm Sunday%"
|
||||
OMIT [easter-2] MSG %"Good Friday%"
|
||||
OMIT [easter] MSG %"Easter%" Sunday
|
||||
REM [easter+39] MSG %"Ascension Day%"
|
||||
REM [easter+49] MSG %"Pentecost%"
|
||||
|
||||
# Some holidays are omitted, some are not. You may want to change
|
||||
# which ones are omitted - use the general forms shown below.
|
||||
@@ -349,9 +302,14 @@ REM Mon Jan [Week_3] 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 [_back(7)] SATISFY 1
|
||||
OMIT [_trig()] MSG %"President's Day%"
|
||||
OMIT [trigdate()] MSG %"President's Day%"
|
||||
REM Mar 17 MSG %"St. Patrick's%" Day
|
||||
REM Sun Apr 1 ++2 MSG Daylight Savings Time - %"DST starts%" %b
|
||||
|
||||
# The DST rules are accurate for most locations in
|
||||
# North America
|
||||
REM Sun Apr 1 ++2 UNTIL 1 Jan 2007 MSG Daylight Savings Time - %"DST starts%" %b
|
||||
REM Sun Mar 8 ++2 FROM 1 Jan 2007 MSG Daylight Savings Time - %"DST starts%" %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%"
|
||||
@@ -359,23 +317,28 @@ 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 [_back(7)] SATISFY 1
|
||||
OMIT [_trig()] MSG %"Memorial Day%"
|
||||
OMIT [trigdate()] MSG %"Memorial Day%"
|
||||
REM Jun 14 MSG %"Flag Day%"
|
||||
REM Sun Jun [Week_3] MSG %"Father's Day%"
|
||||
REM Mon Sep [Week_1] SCANFROM [_back(7)] SATISFY 1
|
||||
OMIT [_trig()] MSG %"Labor Day%"
|
||||
OMIT [trigdate()] MSG %"Labor Day%"
|
||||
REM Mon Oct [Week_2] MSG %"Columbus Day%"
|
||||
REM Nov 11 MSG %"Veterans Day%"
|
||||
REM Sun [_last(Oct)] MSG Daylight Savings Time - %"DST over%"
|
||||
|
||||
# The DST rules are accurate for most locations in
|
||||
# North America
|
||||
REM Sun [_last(Oct)] UNTIL 1 Jan 2007 MSG Daylight Savings Time - %"DST over%"
|
||||
REM Sun 1 Nov FROM 1 Jan 2007 MSG Daylight Savings Time - %"DST over%"
|
||||
|
||||
REM Oct 30 MSG %"Mischief Night%"
|
||||
REM Oct 31 MSG %"Halloween%"
|
||||
REM Tue Nov 2 SCANFROM [_back(7)] \
|
||||
SATISFY [(YEAR(TRIGDATE()) % 4) == 0] \
|
||||
MSG %"Election%" Day
|
||||
REM Thu Nov [Week_4] SCANFROM [_back(7)] SATISFY 1
|
||||
OMIT [_trig()] MSG %"Thanksgiving%" Day
|
||||
OMIT [trigdate()] MSG %"Thanksgiving%" Day
|
||||
REM Fri Nov [Week_4+1] SCANFROM [_back(7)] SATISFY 1
|
||||
OMIT [_trig()] MSG %"Thanksgiving%" (cont.)
|
||||
OMIT [trigdate()] MSG %"Thanksgiving%" (cont.)
|
||||
OMIT Dec 24 MSG %"Christmas Eve%"
|
||||
OMIT Dec 25 MSG %"Christmas%" Day
|
||||
|
||||
@@ -413,10 +376,10 @@ REM PS Border Border moveto \
|
||||
([hebday(today())] [hebmon(today())]) show
|
||||
|
||||
# Fill in the phases of the moon on the PostScript calendar
|
||||
[trigger(moondate(0))] SPECIAL MOON 0
|
||||
[trigger(moondate(1))] SPECIAL MOON 1
|
||||
[trigger(moondate(2))] SPECIAL MOON 2
|
||||
[trigger(moondate(3))] SPECIAL MOON 3
|
||||
[moondate(0)] SPECIAL MOON 0
|
||||
[moondate(1)] SPECIAL MOON 1
|
||||
[moondate(2)] SPECIAL MOON 2
|
||||
[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.
|
||||
@@ -469,11 +432,12 @@ SET InIsrael 0
|
||||
SET Reform 0
|
||||
|
||||
# Convenient function definition to save typing
|
||||
FSET _h(x, y) TRIGGER(HEBDATE(x,y))
|
||||
FSET _h(x, y) HEBDATE(x,y)
|
||||
FSET _h2(x, y) HEBDATE(x, y, TODAY()-7)
|
||||
FSET _PastSat(x, y) TRIGGER(IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)+1))
|
||||
FSET _BackTwoFri(x, y) TRIGGER(IIF(WKDAYNUM(_h2(x,y))!=5, _h2(x,y), _h2(x,y)-2))
|
||||
FSET _BackTwoSat(x, y) TRIGGER(IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)-2))
|
||||
FSET _PastSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, _h2(x,y), _h2(x,y)+1)
|
||||
FSET _PastSun(x, y) IIF(WKDAYNUM(_h2(x,y))!=0, _h2(x,y), _h2(x,y)+1)
|
||||
FSET _PastMon(x, y) IIF(WKDAYNUM(_h2(x,y))!=1, _h2(x,y), _h2(x,y)+1)
|
||||
|
||||
# Default values in case InIsrael and Reform are not set
|
||||
SET InIsrael VALUE("InIsrael", 0)
|
||||
SET Reform VALUE("Reform", 0)
|
||||
@@ -493,7 +457,7 @@ IF !InIsrael
|
||||
[_h(16, "Tishrey")] MSG %"Sukkot 2%"
|
||||
ENDIF
|
||||
|
||||
[_h(21, "Tishrey")] ++4 MSG %"Hashana Rabba%" is %b.
|
||||
[_h(21, "Tishrey")] ++4 MSG %"Hoshana Rabba%" is %b.
|
||||
[_h(22, "Tishrey")] ++4 MSG %"Shemini Atzeret%" is %b.
|
||||
|
||||
IF InIsrael
|
||||
@@ -503,7 +467,7 @@ ELSE
|
||||
ENDIF
|
||||
|
||||
# Because Kislev can change length, we must be more careful about Chanukah
|
||||
FSET _chan(x) TRIGGER(HEBDATE(24, "Kislev", today()-9)+x)
|
||||
FSET _chan(x) HEBDATE(24, "Kislev", today()-9)+x
|
||||
[_chan(1)] ++4 MSG %"Chanukah 1%" is %b.
|
||||
[_chan(2)] MSG %"Chanukah 2%"
|
||||
[_chan(3)] MSG %"Chanukah 3%"
|
||||
@@ -521,15 +485,17 @@ IF !Reform
|
||||
ENDIF
|
||||
|
||||
[_h(15, "Shvat")] ++4 MSG %"Tu B'Shvat%" is %b.
|
||||
[_h(15, "Adar A")] ++4 MSG %"Purim Katan%" is %b.
|
||||
[_h(14, "Adar A")] ++4 MSG %"Purim Katan%" is %b.
|
||||
[_h(15, "Adar A")] ++4 MSG %"Shushan Purim Katan%" is %b.
|
||||
|
||||
# If Purim is on Sunday, then Fast of Esther is 11 Adar.
|
||||
IF WKDAYNUM(_h2(13, "Adar")) != 6
|
||||
REM [TRIGGER(_h2(13, "Adar"))] ++4 MSG %"Fast of Esther%" is %b.
|
||||
REM [_h2(13, "Adar")] ++4 MSG %"Fast of Esther%" is %b.
|
||||
ELSE
|
||||
REM [TRIGGER(_h2(11, "Adar"))] ++4 MSG %"Fast of Esther%" is %b.
|
||||
REM [_h2(11, "Adar")] ++4 MSG %"Fast of Esther%" is %b.
|
||||
ENDIF
|
||||
[_h(14, "Adar")] ++4 MSG %"Purim%" is %b.
|
||||
[_h(15, "Adar")] ++4 MSG %"Shushan Purim%" is %b.
|
||||
[_h(15, "Nisan")] ++4 MSG %"Pesach%" is %b.
|
||||
|
||||
IF !InIsrael
|
||||
@@ -542,9 +508,30 @@ 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.
|
||||
REM [_PastSun(27, "Nisan")] SATISFY 1
|
||||
|
||||
IF $Tw == 5
|
||||
REM [_PastSun(26, "Nisan")] ++4 MSG %"Yom HaShoah%" is %b.
|
||||
ELSE
|
||||
REM [_PastSun(27, "Nisan")] ++4 MSG %"Yom HaShoah%" is %b.
|
||||
ENDIF
|
||||
|
||||
# If 4 Iyar is a Friday, then Yom Hazikaron is
|
||||
# the Wednesday before and Yom Ha'atzmaut is on
|
||||
# Thursday. If 4 Iyar is a Sunday, then Yom Hazikaron
|
||||
# moves to 5 Iyar and Yom Ha'atzmaut to 6 Iyar.
|
||||
IF WKDAYNUM(_h2(4, "Iyar")) == 5
|
||||
[_h(2, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b.
|
||||
[_h(3, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
ELSE
|
||||
IF WKDAYNUM(_h2(4, "Iyar")) == 0
|
||||
[_h(5, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b.
|
||||
[_h(6, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
ELSE
|
||||
[_h(4, "Iyar")] ++4 MSG %"Yom Hazikaron%" is %b.
|
||||
[_h(5, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
# Not sure about Reform's position on Lag B'Omer
|
||||
IF !Reform
|
||||
|
||||
@@ -1,53 +1,79 @@
|
||||
" Vim syntax file
|
||||
" Language: Remind
|
||||
" Maintainer: Davide Alberani <alberanid@bigfoot.com>
|
||||
" Last change: 03 Dec 1999
|
||||
" Version: 0.1
|
||||
" URL: http://members.xoom.com/alberanid/vim/syntax/remind.vim
|
||||
" Maintainer: Davide Alberani <alberanid@libero.it>
|
||||
" Last Change: 18 Sep 2009
|
||||
" Version: 0.5
|
||||
" URL: http://erlug.linux.it/~da/vim/syntax/remind.vim
|
||||
"
|
||||
" remind is a sophisticated reminder service
|
||||
" you can download remind from ftp://ftp.doe.carleton.ca/pub/remind-3.0/
|
||||
" you can download remind from:
|
||||
" http://www.roaringpenguin.com/penguin/open_source_remind.php
|
||||
|
||||
" clear any unwanted syntax defs
|
||||
syn clear
|
||||
if version < 600
|
||||
syntax clear
|
||||
elseif exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
" shut case off
|
||||
" shut case off.
|
||||
syn case ignore
|
||||
|
||||
syn keyword remindCommands REM OMIT SET FSET UNSET
|
||||
syn keyword remindExpiry UNTIL SCANFROM SCAN WARN SCHED
|
||||
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
|
||||
syn keyword remindSpecial INCLUDE INC BANNER PUSH-OMIT-CONTEXT PUSH CLEAR-OMIT-CONTEXT CLEAR POP-OMIT-CONTEXT POP COLOR COLOUR
|
||||
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
|
||||
syn match remindComment "#.*$"
|
||||
syn region remindString start=+'+ end=+'+ skip=+\\\\\|\\'+ oneline
|
||||
syn region remindString start=+"+ end=+"+ skip=+\\\\\|\\"+ oneline
|
||||
syn keyword remindDebug DEBUG DUMPVARS DUMP ERRMSG FLUSH PRESERVE
|
||||
syn match remindVar "\$[_a-zA-Z][_a-zA-Z0-9]*"
|
||||
syn match remindSubst "%[^ ]"
|
||||
syn match remindAdvanceNumber "\(\*\|+\|-\|++\|--\)[0-9]\+"
|
||||
" XXX: use different separators for dates and times?
|
||||
syn match remindDateSeparators "[/:@\.-]" contained
|
||||
syn match remindTimes "[0-9]\{1,2}[:\.][0-9]\{1,2}" contains=remindDateSeparators
|
||||
" XXX: why not match only valid dates? Ok, checking for 'Feb the 30' would
|
||||
" be impossible, but at least check for valid months and times.
|
||||
syn match remindDates "'[0-9]\{4}[/-][0-9]\{1,2}[/-][0-9]\{1,2}\(@[0-9]\{1,2}[:\.][0-9]\{1,2}\)\?'" contains=remindDateSeparators
|
||||
" This will match trailing whitespaces that seem to break rem2ps.
|
||||
" Courtesy of Michael Dunn.
|
||||
syn match remindWarning display excludenl "\S\s\+$"ms=s+1
|
||||
|
||||
if !exists("did_remind_syntax_inits")
|
||||
let did_remind_syntax_inits = 1
|
||||
hi link remindCommands Function
|
||||
hi link remindExpiry Repeat
|
||||
hi link remindTag Label
|
||||
hi link remindTimed Statement
|
||||
hi link remindMove Statement
|
||||
hi link remindSpecial Include
|
||||
hi link remindRun Function
|
||||
hi link remindConditional Conditional
|
||||
hi link remindComment Comment
|
||||
hi link remindString String
|
||||
hi link remindDebug Debug
|
||||
hi link remindVar Identifier
|
||||
hi link remindSubst Constant
|
||||
hi link remindAdvanceNumber Number
|
||||
|
||||
if version >= 508 || !exists("did_remind_syn_inits")
|
||||
if version < 508
|
||||
let did_remind_syn_inits = 1
|
||||
command -nargs=+ HiLink hi link <args>
|
||||
else
|
||||
command -nargs=+ HiLink hi def link <args>
|
||||
endif
|
||||
|
||||
HiLink remindCommands Function
|
||||
HiLink remindExpiry Repeat
|
||||
HiLink remindTag Label
|
||||
HiLink remindTimed Statement
|
||||
HiLink remindMove Statement
|
||||
HiLink remindSpecial Include
|
||||
HiLink remindRun Function
|
||||
HiLink remindConditional Conditional
|
||||
HiLink remindComment Comment
|
||||
HiLink remindTimes String
|
||||
HiLink remindString String
|
||||
HiLink remindDebug Debug
|
||||
HiLink remindVar Identifier
|
||||
HiLink remindSubst Constant
|
||||
HiLink remindAdvanceNumber Number
|
||||
HiLink remindDateSeparators Comment
|
||||
HiLink remindDates String
|
||||
HiLink remindWarning Error
|
||||
|
||||
delcommand HiLink
|
||||
endif
|
||||
|
||||
let b:current_syntax = "remind"
|
||||
|
||||
"EOF vim: ts=8 noet tw=100 sw=8 sts=0
|
||||
" vim: ts=8 sw=2
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
.\" $Id: cm2rem.1,v 1.2 2000-03-15 15:51:36 dfs Exp $
|
||||
.TH CM2REM 1 "18 October 1999"
|
||||
.UC4
|
||||
.UC 4
|
||||
.SH NAME
|
||||
cm2rem.tcl \- Convert Sun's "cm" input file to Remind format
|
||||
.SH SYNOPSIS
|
||||
|
||||
28
man/kall.1
28
man/kall.1
@@ -1,28 +0,0 @@
|
||||
.\" $Id: kall.1,v 1.2 1998-02-16 02:35:09 dfs Exp $
|
||||
.TH KALL 1 "15 February 1998"
|
||||
.UC 4
|
||||
.SH NAME
|
||||
kall \- kill processes by command name
|
||||
.SH SYNOPSIS
|
||||
.B kall
|
||||
[\-\fIsignal\fR] prog1 [prog2...]
|
||||
.SH DESCRIPTION
|
||||
.B Kall
|
||||
sends the specified \fIsignal\fR (defaults to \fB-TERM\fR) to all processes
|
||||
whose command name is specified on the command line. For example:
|
||||
.PP
|
||||
.nf
|
||||
kall -HUP remind foobar
|
||||
.fi
|
||||
.PP
|
||||
sends a \fBHUP\fR signal to all \fIremind\fR and \fIfoobar\fR programs.
|
||||
Note that \fBkall\fR sends signals only to those processes owned by the
|
||||
user invoking \fBkall\fR.
|
||||
.SH AUTHOR
|
||||
David F. Skoll
|
||||
.SH BUGS
|
||||
.B Kall
|
||||
is a sh(1) script and depends on the behaviour of ps(1); thus, it is
|
||||
not especially portable.
|
||||
.SH SEE ALSO
|
||||
remind, rem
|
||||
39
man/rem.1
39
man/rem.1
@@ -1,35 +1,20 @@
|
||||
.\" $Id: rem.1,v 1.2 1998-02-16 02:35:09 dfs Exp $
|
||||
.TH REM 1 "15 February 1998"
|
||||
.TH REM 1 "30 August 2007"
|
||||
.UC 4
|
||||
.SH NAME
|
||||
rem \- run 'remind' with a default reminder file
|
||||
rem \- Invoke Remind with a default filename
|
||||
.SH SYNOPSIS
|
||||
.B rem
|
||||
[\-F \fIfilename\fR] [\fIremind_options\fR] [\fIremind_params\fR]
|
||||
.B rem [\fIoptions\fR] [\fIdate\fR] [\fI*rep\fR] [\fItime\fR]
|
||||
.SH DESCRIPTION
|
||||
.B Rem
|
||||
runs the \fBremind\fR program with a default reminder file of
|
||||
"$HOME/.reminders". You can supply remind options on the command line,
|
||||
as well as a date specification, just as with \fBremind\fR.
|
||||
|
||||
If you don't want to use the default filename, you can override it with
|
||||
the "-F" option, followed by a space and a filename. (This, however,
|
||||
defeats the purpose of \fBrem\fR)
|
||||
\fBrem\fR is a symbolic link to \fBremind\fR. When \fBremind\fR
|
||||
determines that it has been invoked as \fBrem\fR, it uses a default
|
||||
filename rather than expecting a filename to be supplied on the command
|
||||
line.
|
||||
.PP
|
||||
For example, typing:
|
||||
.PP
|
||||
.nf
|
||||
rem -c 1 jan 1992
|
||||
.fi
|
||||
.PP
|
||||
has the same effect as typing:
|
||||
.PP
|
||||
.nf
|
||||
remind -c $HOME/.reminders 1 jan 1992
|
||||
.fi
|
||||
If the environment variable DOTREMINDERS is set, \fBremind\fR uses the
|
||||
value of DOTREMINDERS as the filename. Otherwise, \fBremind\fR uses
|
||||
the filename $HOME/.reminders
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
David F. Skoll
|
||||
Remind was written by David F. Skoll <dfs@roaringpenguin.com>
|
||||
.SH SEE ALSO
|
||||
remind, kall
|
||||
|
||||
\fBremind\fR
|
||||
|
||||
32
man/rem2ps.1
32
man/rem2ps.1
@@ -1,6 +1,5 @@
|
||||
.\" $Id: rem2ps.1,v 1.6 2005-04-12 00:57:48 dfs Exp $
|
||||
.TH REM2PS 1 "11 April 2005"
|
||||
.UC4
|
||||
.UC 4
|
||||
.SH NAME
|
||||
rem2ps \- draw a PostScript calendar from Remind output
|
||||
.SH SYNOPSIS
|
||||
@@ -78,10 +77,10 @@ Letter
|
||||
8.5 x 11 in.
|
||||
.TP
|
||||
Legal
|
||||
11 x 17 in.
|
||||
8.5 x 14 in.
|
||||
.TP
|
||||
Ledger
|
||||
8.5 x 14 in.
|
||||
11 x 17 in.
|
||||
.TP
|
||||
Statement
|
||||
5.5 x 8.5 in.
|
||||
@@ -122,10 +121,10 @@ numbers.
|
||||
numbers.
|
||||
|
||||
.PP
|
||||
Type "rem2ps -m help" for a list of available media. Note that the media
|
||||
Type "rem2ps \-m help" for a list of available media. Note that the media
|
||||
type (and all \fBRem2ps\fR options) are case-sensitive. If you don't use
|
||||
the \fB\-m\fR option, the media defaults to a compiled-in default - this
|
||||
is usually Letter for North America and A4 for Europe. The "-m help"
|
||||
is usually Letter for North America and A4 for Europe. The "\-m help"
|
||||
option will display the compiled-in default.
|
||||
.RE
|
||||
.TP
|
||||
@@ -138,7 +137,7 @@ specifying:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
-ftshe Helvetica -fd Helvetica-BoldOblique
|
||||
\-ftshe Helvetica \-fd Helvetica-BoldOblique
|
||||
.fi
|
||||
.PP
|
||||
In other words, the heading, entry and small-calendar fonts are set
|
||||
@@ -154,7 +153,7 @@ are equivalent to specifying:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
-sthd 14 -se 8
|
||||
\-sthd 14 \-se 8
|
||||
.fi
|
||||
.PP
|
||||
In other words, the heading and day numbers are 14-point fonts, and the
|
||||
@@ -180,7 +179,7 @@ for good output:
|
||||
.PP
|
||||
.nf
|
||||
# This gives good results for putting into a binder
|
||||
rem2ps -ol 72 -sh 12
|
||||
rem2ps \-ol 72 \-sh 12
|
||||
.fi
|
||||
.SH USAGE
|
||||
To use \fBRem2ps\fR, you should pipe the output of \fBRemind\fR with the \fB\-p\fR
|
||||
@@ -188,14 +187,14 @@ option to \fBRem2ps\fR, and then send the result to a printer. This is most eas
|
||||
illustrated with examples:
|
||||
.PP
|
||||
.nf
|
||||
remind -p12 /dev/null 1 jan 1994 | rem2ps | lpr -Plaser
|
||||
remind \-p12 /dev/null 1 jan 1994 | rem2ps | lpr \-Plaser
|
||||
.fi
|
||||
.PP
|
||||
That example creates a blank calendar for the entire year of 1994, and
|
||||
sends it the the printer named "laser."
|
||||
.PP
|
||||
.nf
|
||||
remind -p ~/.reminders | rem2ps -l -sd 18 > cal.ps
|
||||
remind \-p ~/.reminders | rem2ps \-l \-sd 18 > cal.ps
|
||||
.fi
|
||||
.PP
|
||||
This reminder creates a calendar for the current month, filling in
|
||||
@@ -351,7 +350,9 @@ The remaining data consists of calendar entries, in the following format:
|
||||
\fIyyyy/mm/dd special tag dur time body\fR
|
||||
.PP
|
||||
Here, \fIyyyy\fR is the year, \fImm\fR is the month (01-12) and
|
||||
\fIdd\fR is the day of the month.
|
||||
\fIdd\fR is the day of the month. Note that the date components are
|
||||
always separated by "/" even if the date separator in \fBRemind\fR has
|
||||
been set to "-". The consistent use of "/" is designed to ease parsing.
|
||||
.PP
|
||||
\fIspecial\fR is a string used
|
||||
for "out-of-band" communication with back-ends. If the reminder
|
||||
@@ -361,7 +362,10 @@ Other back-ends may understand other specials. A back end should
|
||||
\fIsilently ignore\fR a reminder with a special it doesn't understand.
|
||||
.PP
|
||||
\fItag\fR is whatever tag the user provided with the \fBTAG\fR clause,
|
||||
or "*" if no tag was provided.
|
||||
or "*" if no tag was provided. If there is more than one \fBTAG\fR clause,
|
||||
the tags appear in a comma-separated list. For example, the command
|
||||
\fBREM TAG foo TAG bar TAG quux\fR would result in \fBfoo,bar,quux\fR
|
||||
in the \fItag\fR field.
|
||||
.PP
|
||||
\fIdur\fR is the \fBDURATION\fR value in minutes, or "*" if no duration
|
||||
was provided.
|
||||
@@ -406,4 +410,4 @@ 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 SEE ALSO
|
||||
\fBRemind\fR
|
||||
\fBremind\fR
|
||||
|
||||
1222
man/remind.1
1222
man/remind.1
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,3 @@
|
||||
.\" $Id: tkremind.1,v 1.11 2005-04-12 13:41:27 dfs Exp $ "
|
||||
.TH TKREMIND 1 "15 February 1998"
|
||||
.UC 4
|
||||
.SH NAME
|
||||
@@ -22,6 +21,8 @@ extra features as you become a more sophisticated \fBRemind\fR programmer.
|
||||
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
|
||||
@@ -73,7 +74,7 @@ The next control specifies an expiry date for the reminder. Select
|
||||
the check button to enable an expiry date, and fill in the values
|
||||
using pull-down menus.
|
||||
|
||||
The third control specifes how much advance notice you want (if any),
|
||||
The third control specifies how much advance notice you want (if any),
|
||||
and whether or not weekends and holidays are counted when computing advance
|
||||
notice.
|
||||
|
||||
@@ -178,7 +179,7 @@ it starts up in a normal window.
|
||||
.TP
|
||||
.B Show Today's Reminders on Startup
|
||||
If this is selected, \fBTkRemind\fR shows a text window containing reminders
|
||||
which would be issued by "remind -q -a -r" on startup, and when the date
|
||||
which would be issued by "remind \-q \-a \-r" on startup, and when the date
|
||||
changes at midnight.
|
||||
|
||||
.TP
|
||||
@@ -211,6 +212,18 @@ background reminder pops up.
|
||||
If selected, feeds the text of the reminder to the command described
|
||||
above.
|
||||
|
||||
.TP
|
||||
.B E-mail reminders here if popup not dismissed
|
||||
If you enter a non-blank e-mail address in this field, then \fBTkRemind\fR
|
||||
will e-mail you a reminder if you don't dismiss the popup box within
|
||||
one minute. This is useful if you need to leave your terminal but
|
||||
want your reminders to "follow" you via e-mail.
|
||||
|
||||
.TP
|
||||
.B Name or IP address of SMTP server
|
||||
\fBTkRemind\fR uses a direct SMTP connection to send mail. Enter the
|
||||
IP address of your SMTP server here.
|
||||
|
||||
.TP
|
||||
.B Text Editor
|
||||
This specifies a text editor to invoke when a reminder is right-clicked.
|
||||
@@ -224,6 +237,22 @@ press \fBApply Options\fR to put them into effect, \fBSave Options\fR
|
||||
to put them into effect and save them in $HOME/.tkremindrc, or
|
||||
\fBCancel\fR to cancel any changes you made.
|
||||
|
||||
.SH KEYBOARD SHORTCUTS
|
||||
\fBTkRemind\fR's main window includes the following keyboard shortcuts:
|
||||
|
||||
.TP
|
||||
.B Ctrl-Q
|
||||
Quit
|
||||
.TP
|
||||
.B Left Arrow
|
||||
Previous Month
|
||||
.TP
|
||||
.B Right Arrow
|
||||
Next Month
|
||||
.TP
|
||||
.B Home
|
||||
Today
|
||||
|
||||
.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,
|
||||
@@ -239,7 +268,7 @@ the body. Furthermore, if you use expression-pasting in the body,
|
||||
When \fBTkRemind\fR invokes \fBRemind\fR, it supplies the option:
|
||||
.PP
|
||||
.nf
|
||||
-itkremind=1
|
||||
\-itkremind=1
|
||||
.fi
|
||||
.PP
|
||||
on the command line. So, in your \fBRemind\fR file, you can include:
|
||||
@@ -257,10 +286,12 @@ for \fBTkRemind\fR (for example).
|
||||
script file. It also places special comments in the reminder
|
||||
file to store additional state. You can certainly mix
|
||||
"hand-crafted" reminders with reminders created by \fBTkRemind\fR
|
||||
if you are awared of the following rules and limitations:
|
||||
if you are aware of the following rules and limitations:
|
||||
.TP
|
||||
o
|
||||
Do not use the \fBTAG\fR keyword in hand-crafted reminders.
|
||||
\fBTkRemind\fR uses \fBTAG\fRs of the form \fBTKTAG\fR\fInnn\fR
|
||||
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
|
||||
|
||||
23
remind.lsm
23
remind.lsm
@@ -1,23 +0,0 @@
|
||||
Begin3
|
||||
Title: Remind
|
||||
Version: 03.00.22
|
||||
Entered-date: 12 Apr 1999
|
||||
Description: Full-featured calendar/reminder program featuring
|
||||
sophisticated date calculation, moon phases, sunrise/sunset,
|
||||
Hebrew calendar, alarms, PostScript output, X-Windows
|
||||
front-end, multilingual messages, and proper handling of
|
||||
holidays. Available for UNIX, MS-DOS, OS/2, and other
|
||||
platforms. Includes scripts for making a nice WWW
|
||||
calendar server.
|
||||
Keywords: calendar reminder alarm datebook PostScript www
|
||||
Author: dskoll@iname.com (David F. Skoll)
|
||||
Maintained-by: dskoll@iname.com (David F. Skoll)
|
||||
Primary-site: http://www.roaringpenguin.com/remind.html
|
||||
304kB remind-3.0.22.tgz
|
||||
Alternate-site:
|
||||
Original-site:
|
||||
Platform: Linux, Solaris, SunOS, HP-UX -- virtually any UN*X-like
|
||||
system. Wish 8.x required for TCL/Tk front-end, but
|
||||
this is not essential to use the software.
|
||||
Copying-policy: GPL
|
||||
End
|
||||
@@ -1,10 +1,4 @@
|
||||
Files in this directory:
|
||||
|
||||
kall -- Kills a program by command name, as in "kall remind"
|
||||
rem -- Starts Remind with a default file of $HOME/.reminders
|
||||
remind-all.csh -- Mails reminders to all users (C-Shell version)
|
||||
remind-all.sh -- Mails reminders to all users (Bourne Shell version)
|
||||
tkremind* -- Tcl/Tk graphical calendar using Remind as engine
|
||||
|
||||
$Id: README,v 1.1 1998-01-15 02:50:20 dfs Exp $
|
||||
|
||||
tkremind -- Tcl/Tk graphical calendar using Remind as engine
|
||||
cm2rem.tcl -- Convert Sun's "cm" calendar manager files to Remind.
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
|
||||
# $Id: cm2rem.tcl,v 1.3 2000-02-18 03:45:38 dfs Exp $
|
||||
|
||||
# the next line restarts using tclsh \
|
||||
exec tclsh "$0" "$@"
|
||||
|
||||
|
||||
42
scripts/kall
42
scripts/kall
@@ -1,42 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $Id: kall,v 1.1 1998-01-15 02:50:20 dfs Exp $
|
||||
#
|
||||
# kall - kill all processes belonging to this user that match
|
||||
# specified string.
|
||||
|
||||
signal=`echo $1 | grep '^\-.*'`
|
||||
me=`basename $0`
|
||||
|
||||
if [ "$signal" != "" ]; then
|
||||
shift
|
||||
else
|
||||
signal="-TERM"
|
||||
fi
|
||||
|
||||
if [ "$1" = "" ]; then
|
||||
echo "usage: $me [-signal] string [string...]"
|
||||
echo " kills all of your processes where command name matches"
|
||||
echo " any of the given strings."
|
||||
exit
|
||||
fi
|
||||
|
||||
msg="0"
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
|
||||
# NOTE: You may have to modify the next line, since PS is non-portable.
|
||||
# The 'awk' command picks out the process IDs to pass them on to kill.
|
||||
rprocs=`ps cx | awk '{if(prog == $NF && $1 != mypid) print $1}' prog=$1 mypid=$$ -`
|
||||
if [ "$rprocs" != "" ]; then
|
||||
msg="1"
|
||||
echo -n "${me}: Sending $signal signal to $1 process(es)"
|
||||
echo '...'
|
||||
kill $signal $rprocs
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if [ $msg = "1" ]; then
|
||||
echo "${me}: Done."
|
||||
fi
|
||||
45
scripts/rem
45
scripts/rem
@@ -1,45 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# rem - by David Skoll - 26 February 1991
|
||||
#
|
||||
# $Id: rem,v 1.1 1998-01-15 02:50:21 dfs Exp $
|
||||
#
|
||||
# This script runs 'remind' with a default reminder file assumed. You
|
||||
# can override the default by using "rem -F newfile ..." (But why would
|
||||
# you use rem unless you wanted to accept the default??)
|
||||
|
||||
# ------ You may wish to change the defaults below this line ------
|
||||
|
||||
# The default reminder file
|
||||
DEFAULT=$HOME/.reminders
|
||||
|
||||
# The executable file (you may wish to change this to /usr/local/bin/remind
|
||||
# or whatever.
|
||||
EXECUTABLE=remind
|
||||
|
||||
# No options yet
|
||||
OPTIONS=""
|
||||
|
||||
# No parameters yet
|
||||
PARAMETERS=""
|
||||
|
||||
# ------ You shouldn't change anything below this line -----
|
||||
|
||||
# Scan for options
|
||||
while test "$1" != ""
|
||||
do
|
||||
case $1 in
|
||||
|
||||
-F) DEFAULT=$2
|
||||
shift
|
||||
shift ;;
|
||||
|
||||
-*) OPTIONS="$OPTIONS $1"
|
||||
shift ;;
|
||||
|
||||
*) PARAMETERS=$*
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
$EXECUTABLE $OPTIONS $DEFAULT $PARAMETERS
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/bin/csh -f
|
||||
|
||||
# Shell script to mail all users reminders.
|
||||
|
||||
# $Id: remind-all.csh,v 1.1 1998-01-15 02:50:21 dfs Exp $
|
||||
|
||||
# Run it AFTER MIDNIGHT so that date is correct!
|
||||
# On our system, we have the following in our crontab:
|
||||
# 05 5 * * * /usr/share/lib/remind/remind-all > /dev/null 2>&1
|
||||
|
||||
# This script must be run by root. The -u option MUST be supplied
|
||||
# to Remind, or a severe security hole will exist. Note that Remind
|
||||
# must be compiled to support the -u option for this script to work.
|
||||
# Also, the -r and -q options must be used.
|
||||
|
||||
# The following line gets a list of users for systems using SUN's
|
||||
# NIS service:
|
||||
set USERS = `ypcat passwd | awk -F: '{print $1}'`
|
||||
|
||||
# The following line gets a list of users by examining /etc/passwd:
|
||||
# set USERS = `awk -F: '{print $1}' /etc/passwd`
|
||||
|
||||
# If neither of the above methods works, you must come up with some
|
||||
# way of getting a list of users on the system
|
||||
|
||||
# Set the following variables as appropriate for your system
|
||||
set REMIND = /usr/local/bin/remind
|
||||
set MAIL = /usr/ucb/mail
|
||||
set RM = "/usr/bin/rm -f"
|
||||
|
||||
set REMFILE = /tmp/RemFile.$$
|
||||
|
||||
# Scan each user's directory for a .reminders file
|
||||
foreach i ($USERS)
|
||||
if (-r ~$i/.reminders) then
|
||||
# echo "$i has a .reminders file." DEBUGGING PURPOSES ONLY
|
||||
|
||||
$REMIND -u$i -h -r -q -iremind_all=1 ~$i/.reminders < /dev/null > $REMFILE
|
||||
if (! -z $REMFILE) then
|
||||
# echo "Sending mail to $i" DEBUGGING PURPOSES ONLY
|
||||
|
||||
$MAIL -s "Reminders" $i < $REMFILE
|
||||
endif
|
||||
$RM $REMFILE
|
||||
endif
|
||||
end
|
||||
@@ -1,55 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Shell script to mail all users reminders.
|
||||
|
||||
# This file is part of REMIND
|
||||
#
|
||||
# $Id: remind-all.sh,v 1.4 2000-02-18 03:45:39 dfs Exp $
|
||||
#
|
||||
# REMIND is Copyright (C) 1992-1998 by David F. Skoll
|
||||
# Copyright (C) 1999-2000 Roaring Penguin Software Inc.
|
||||
# This file is Copyright (C) 1990 by Bill Aten
|
||||
|
||||
# Thanks to Bill Aten for this script.
|
||||
|
||||
# Run it AFTER MIDNIGHT so that date is correct!
|
||||
# On our system, we have the following in our crontab:
|
||||
# 02 00 * * * /usr/local/adm/remind-all >/dev/null 2>&1
|
||||
|
||||
# This script must be run by root. The -u option MUST be supplied
|
||||
# to Remind, or a severe security hole will exist. Note that Remind
|
||||
# must be compiled to support the -u option for this script to work.
|
||||
# Also, the -r and -q options must be used.
|
||||
|
||||
# The following line gets a list of users for systems using SUN's
|
||||
# NIS service:
|
||||
# USERS=`ypcat passwd | awk -F: '{print $1}'`
|
||||
|
||||
# The following line gets a list of users by examining /etc/passwd:
|
||||
USERS=`awk -F: '{print $1}' /etc/passwd`
|
||||
|
||||
# If neither of the above methods works, you must come up with some
|
||||
# way of getting a list of users on the system
|
||||
|
||||
# Set the following variables as appropriate for your system
|
||||
REMIND=/usr/local/bin/remind
|
||||
MAIL=/usr/bin/mail
|
||||
RM="/bin/rm -f"
|
||||
|
||||
REMFILE=/tmp/RemFile.$$
|
||||
|
||||
# Scan each user's directory for a .reminders file
|
||||
for i in $USERS
|
||||
do
|
||||
HOME=`grep \^$i: /etc/passwd | awk -F: '{print $6}'`
|
||||
if [ -r $HOME/.reminders ]; then
|
||||
|
||||
# echo "$i has a .reminders file." DEBUGGING PURPOSES ONLY
|
||||
|
||||
$REMIND -u$i -h -r -q -iremind_all=1 $HOME/.reminders < /dev/null > $REMFILE
|
||||
if [ -s $REMFILE ]; then
|
||||
# echo "Sending mail to $i" DEBUGGING PURPOSES ONLY
|
||||
$MAIL -s "Reminders" $i < $REMFILE
|
||||
fi
|
||||
$RM $REMFILE
|
||||
fi
|
||||
done
|
||||
398
scripts/tkremind
398
scripts/tkremind
@@ -8,17 +8,61 @@
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-1998 David F. Skoll
|
||||
# Copyright (C) 1999-2005 Roaring Penguin Software Inc.
|
||||
# Copyright (C) 1999-2010 Roaring Penguin Software Inc.
|
||||
#
|
||||
#--------------------------------------------------------------
|
||||
|
||||
# $Id: tkremind,v 1.40 2005-04-14 17:34:34 dfs Exp $
|
||||
|
||||
# the next line restarts using wish \
|
||||
exec wish "$0" "$@"
|
||||
|
||||
wm withdraw .
|
||||
|
||||
# Our icon photo
|
||||
catch {
|
||||
image create photo rpicon -data {
|
||||
R0lGODlhFwAgAOecABUTERYTERYUERcVEhgWExkXFBkXFRoXFRsZFhwZFxwa
|
||||
GB0bGR4cGR4cGh8dGiAeHCEfHCEfHSIgHSIgHiQiHyYkISknJCooJispJywq
|
||||
Jy4sKTIwLjUzMDUzMTo4Njs5Nzs5ODw7ODw7OT07OT48OkE/PUJAPkNBP0RC
|
||||
QEVDQUVEQkdFQ0lIRkpJR01LSU5MSlBPTVFQTlNSUFRSUFRSUVVTUlVUUllY
|
||||
VltZV1xaWF1cWmBfXmJgX2RiYGZlY2dmZGppZ2tqaG1ram9tbHFwb3Jwb3Rz
|
||||
cXV0c3Z0c3Z1c3Z1dHd1dHh2dXh3dnt5eHx7eXx7en18en59e4B/foGAf4KB
|
||||
f4SDgYWEgoWEg4eGhIiHhouKiI2Mio6Ni46NjJCQj5KRkJSTkZeWlpiXlpmY
|
||||
l5qZmJybmp6dnKCfnqGgoKKhoKOioaSjoqinp6qpqKurqq+urbCvrrCwr7Gw
|
||||
r7OysbW1tLi3tri3t7u6ur28vMTDw8TEw8XFxMbFxcfGxsfHxsrJycrKyczM
|
||||
y83My83MzM3NzdDQz9LR0dPS0tPT09fX19jY19ra2dvb29zc29zc3Ojn5+jo
|
||||
6Orq6uzs7O/v7/T09PX19fb29vf39/r6+vv7+/7+/v//////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
/////////////////////yH5BAEKAP8ALAAAAAAXACAAAAj+AP8JHEiwoMGD
|
||||
CAcusRAAQEKDBQIcEBAAwUODAQJAsBGAwsWCBzJuUBLgI0ENGVM2dACg5UWV
|
||||
KU+Y/JfRQBknPoq8ATQz4wxOQIFa6vMx5ZSgQetczJDSClKgcF6mFDEnE9I2
|
||||
D0fADOChUdA1D7dmTBEUTditDQRQAnomIQaxICpoAmomoUoAGS2YIBIUDEIu
|
||||
YndI8FAJaBaEMlIuSEkloxugUBBOSLkh44AvGfkAPYJQpYqMLIQEILB205DO
|
||||
KW9kJHMhQAmgkaKgzsgjggM5GbEAxaNmdoAPOoz8CCAgEVAtg3wPEPMnQQAU
|
||||
QWsg5AAzDZSMbIBeaoHwAUwSDAI2XMAENA8ThAPEBvAStEkc3yonrOW0aUMk
|
||||
+BkBVAlaKATC8Fsp8Igid5ABgxMHtaTgggy6ZFBAADs= }
|
||||
|
||||
wm iconphoto . -default rpicon
|
||||
}
|
||||
|
||||
proc missing_tcllib { pkg } {
|
||||
catch { puts stderr "Could not find the '$pkg' package -- you must install tcllib.\nPlease see http://tcllib.sourceforge.net/" }
|
||||
tk_dialog .err "Error: tcllib not installed" "Could not find the '$pkg' package -- you must install tcllib. Please see http://tcllib.sourceforge.net/" error 0 OK
|
||||
exit 1
|
||||
}
|
||||
if {[catch {package require mime}]} {
|
||||
missing_tcllib mime
|
||||
}
|
||||
|
||||
if {[catch {package require smtp}]} {
|
||||
missing_tcllib smtp
|
||||
}
|
||||
|
||||
|
||||
# Check that we have the right version of wish
|
||||
if {$tcl_version < 8.0} {
|
||||
tk_dialog .error Error "You need wish version 8.0 or higher to run TkRemind; you have $tcl_version" error 0 OK
|
||||
@@ -58,6 +102,12 @@ set OptDescr(FeedReminder) "(0/1) If 1, feed the reminder to RunCmd on standard
|
||||
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"
|
||||
|
||||
set Option(MailAddr) ""
|
||||
set OptDescr(MailAddr) "(String) Specify an e-mail address to which reminders should be sent if the popup window is not manually dismissed"
|
||||
|
||||
set Option(SMTPServer) "127.0.0.1"
|
||||
set OptDescr(SMTPServer) "(String) IP address or host name of SMTP server to use for sending e-mail"
|
||||
|
||||
# Remind program to execute -- supply full path if you want
|
||||
set Remind "remind"
|
||||
#set Remind "/home/dfs/Remind/src/remind"
|
||||
@@ -75,8 +125,12 @@ set EditorPid -1
|
||||
set AppendFile {NOSUCHFILE}
|
||||
catch {set AppendFile $ReminderFile}
|
||||
|
||||
set SetFontsWorked 0
|
||||
#---------------- DON'T CHANGE STUFF BELOW HERE ------------------
|
||||
|
||||
# 24-hour clock mode
|
||||
set TwentyFourHourMode 0
|
||||
|
||||
# Is Monday in first column?
|
||||
set MondayFirst 0
|
||||
|
||||
@@ -135,9 +189,9 @@ set HighestTagSoFar 0
|
||||
proc Initialize {} {
|
||||
|
||||
global DayNames argc argv CommandLine ReminderFile AppendFile Remind PSCmd
|
||||
global MondayFirst
|
||||
global MondayFirst TwentyFourHourMode
|
||||
|
||||
set CommandLine "|$Remind -itkremind=1 -p -l"
|
||||
set CommandLine "|$Remind -itkremind=1 -p -y -l"
|
||||
set PSCmd "$Remind -p -l"
|
||||
set i 0
|
||||
while {$i < $argc} {
|
||||
@@ -147,6 +201,9 @@ proc Initialize {} {
|
||||
if {[regexp -- {m} [lindex $argv $i]]} {
|
||||
set MondayFirst 1
|
||||
}
|
||||
if {"[lindex $argv $i]" == "-b1"} {
|
||||
set TwentyFourHourMode 1
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
@@ -162,6 +219,14 @@ proc Initialize {} {
|
||||
}
|
||||
}
|
||||
|
||||
# If reminder file is a directory and appendfile is the same as
|
||||
# reminder file, choose append file to be $ReminderFile/100-tkremind.rem
|
||||
if {[file isdirectory $ReminderFile]} {
|
||||
if {"$ReminderFile" == "$AppendFile"} {
|
||||
set AppendFile [file join $ReminderFile "100-tkremind.rem"]
|
||||
}
|
||||
}
|
||||
|
||||
# Check system sanity
|
||||
if {! [file readable $ReminderFile]} {
|
||||
set ans [tk_dialog .error "TkRemind: Warning" "Can't read reminder file `$ReminderFile'" warning 0 "Create it and continue" "Exit"]
|
||||
@@ -175,6 +240,12 @@ proc Initialize {} {
|
||||
exit 1
|
||||
}
|
||||
|
||||
if {[file isdirectory $ReminderFile] && ! [file exists $AppendFile]} {
|
||||
if {![catch {close [open "$AppendFile" "a"]}]} {
|
||||
tk_dialog .error "Created File" "Created blank file `$AppendFile'" info 0 "OK"
|
||||
}
|
||||
}
|
||||
|
||||
if {! [file writable $AppendFile]} {
|
||||
tk_dialog .error Error "Can't write reminder file `$AppendFile'" error 0 Ok
|
||||
exit 1
|
||||
@@ -253,9 +324,14 @@ proc CalEntryOffset { firstDay } {
|
||||
#***********************************************************************
|
||||
proc CreateCalFrame { w dayNames } {
|
||||
# Figure out reasonable height for text frames
|
||||
global SetFontsWorked
|
||||
set h [winfo screenheight .]
|
||||
if {$h <= 480} {
|
||||
set h 2
|
||||
if {$SetFontsWorked} {
|
||||
set h 3
|
||||
} else {
|
||||
set h 2
|
||||
}
|
||||
} elseif {$h <= 600} {
|
||||
set h 4
|
||||
} else {
|
||||
@@ -271,7 +347,7 @@ proc CreateCalFrame { w dayNames } {
|
||||
set index $i
|
||||
}
|
||||
|
||||
label $w.day$i -text [lindex $dayNames $index] -justify center
|
||||
label $w.day$i -border 1 -text [lindex $dayNames $index] -justify center
|
||||
grid configure $w.day$i -row 0 -column $i -sticky ew
|
||||
}
|
||||
for {set i 0} {$i < 6} {incr i} {
|
||||
@@ -279,11 +355,9 @@ proc CreateCalFrame { w dayNames } {
|
||||
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
|
||||
text $w.t$f -width 12 -height $h -wrap word -relief flat \
|
||||
-state disabled -takefocus 0 -cursor {}
|
||||
$w.t$f tag bind TAGGED <Enter> "TaggedEnter $w.t$f"
|
||||
$w.t$f tag bind TAGGED <Leave> "TaggedLeave $w.t$f"
|
||||
-state disabled -relief flat -border 0 -padx 0 -pady 0
|
||||
text $w.t$f -width 12 -height $h -border 1 -spacing3 3 -wrap word -relief flat \
|
||||
-state disabled -takefocus 0 -cursor {}
|
||||
$w.t$f tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$f"
|
||||
$w.t$f tag bind REM <ButtonPress-3> "FireEditor $w.t$f"
|
||||
|
||||
@@ -313,10 +387,13 @@ proc CreateCalFrame { w dayNames } {
|
||||
#***********************************************************************
|
||||
proc ConfigureCalFrame { w firstDay numDays } {
|
||||
global CurMonth CurYear TodayMonth TodayYear TodayDay
|
||||
global tk_version
|
||||
set offset [CalEntryOffset $firstDay]
|
||||
set first [expr $offset+1]
|
||||
set last [expr $offset+$numDays]
|
||||
|
||||
set bg [lindex [. configure -background] 3]
|
||||
|
||||
for {set i 0} {$i < $first} {incr i} {
|
||||
grid $w.l$i $w.t$i
|
||||
$w.l$i configure -text "" -command "" -state disabled -relief flat
|
||||
@@ -325,13 +402,11 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
foreach t [$w.t$i tag names] {
|
||||
$w.t$i tag delete $t
|
||||
}
|
||||
$w.t$i tag bind TAGGED <Enter> "TaggedEnter $w.t$i"
|
||||
$w.t$i tag bind TAGGED <Leave> "TaggedLeave $w.t$i"
|
||||
$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 -background [lindex [$w.t$i configure -background] 3]
|
||||
$w.l$i configure -background [lindex [$w.l$i configure -background] 3]
|
||||
$w.t$i configure -background $bg
|
||||
$w.l$i configure -background $bg
|
||||
}
|
||||
for {set i $first} {$i <= $last} {incr i} {
|
||||
grid $w.l$i $w.t$i
|
||||
@@ -343,13 +418,11 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
foreach t [$w.t$i tag names] {
|
||||
$w.t$i tag delete $t
|
||||
}
|
||||
$w.t$i tag bind TAGGED <Enter> "TaggedEnter $w.t$i"
|
||||
$w.t$i tag bind TAGGED <Leave> "TaggedLeave $w.t$i"
|
||||
$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 -background [lindex [$w.t$i configure -background] 3]
|
||||
$w.l$i configure -background [lindex [$w.l$i configure -background] 3]
|
||||
$w.t$i configure -background $bg
|
||||
$w.l$i configure -background $bg
|
||||
}
|
||||
set forgetIt 0
|
||||
for {set i [expr $last+1]} {$i < 42} {incr i} {
|
||||
@@ -370,13 +443,11 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
foreach t [$w.t$i tag names] {
|
||||
$w.t$i tag delete $t
|
||||
}
|
||||
$w.t$i tag bind TAGGED <Enter> "TaggedEnter $w.t$i"
|
||||
$w.t$i tag bind TAGGED <Leave> "TaggedLeave $w.t$i"
|
||||
$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 -background [lindex [$w.t$i configure -background] 3]
|
||||
$w.l$i configure -background [lindex [$w.l$i configure -background] 3]
|
||||
$w.t$i configure -background $bg
|
||||
$w.l$i configure -background $bg
|
||||
}
|
||||
if { $CurMonth == $TodayMonth && $CurYear == $TodayYear } {
|
||||
set n [expr $TodayDay + $offset]
|
||||
@@ -392,22 +463,22 @@ proc ConfigureCalFrame { w firstDay numDays } {
|
||||
proc CreateCalWindow { dayNames } {
|
||||
global Option
|
||||
frame .h
|
||||
label .h.title -text "" -justify center -pady 2 -relief raised
|
||||
label .h.title -text "" -justify center -pady 1 -border 1 -relief raised
|
||||
pack .h.title -side top -fill x
|
||||
pack .h -side top -expand 0 -fill x
|
||||
|
||||
CreateCalFrame .cal $dayNames
|
||||
|
||||
frame .b
|
||||
button .b.prev -text {<-} -command {MoveMonth -1}
|
||||
button .b.this -text {Today} -command {ThisMonth}
|
||||
button .b.next -text {->} -command {MoveMonth 1}
|
||||
button .b.goto -text {Go To Date...} -command {GotoDialog}
|
||||
button .b.print -text {Print...} -command {DoPrint}
|
||||
button .b.quit -text {Quit} -command {Quit}
|
||||
button .b.options -text {Options...} -command EditOptions
|
||||
label .b.status -text "" -width 25 -relief sunken
|
||||
label .b.nqueued -text "" -width 20 -relief sunken
|
||||
button .b.prev -text {<-} -command {MoveMonth -1} -border 1
|
||||
button .b.this -text {Today} -command {ThisMonth} -border 1
|
||||
button .b.next -text {->} -command {MoveMonth 1} -border 1
|
||||
button .b.goto -text {Go To Date...} -command {GotoDialog} -border 1
|
||||
button .b.print -text {Print...} -command {DoPrint} -border 1
|
||||
button .b.quit -text {Quit} -command {Quit} -border 1
|
||||
button .b.options -text {Options...} -command EditOptions -border 1
|
||||
label .b.status -text "" -width 25 -relief sunken -border 1
|
||||
label .b.nqueued -text "" -width 20 -relief sunken -border 1
|
||||
pack .b.prev .b.this .b.next .b.goto .b.print .b.options .b.quit -side left -fill x
|
||||
pack .b.status -side left -fill x -expand 1
|
||||
pack .b.nqueued -side left -fill x
|
||||
@@ -417,6 +488,13 @@ proc CreateCalWindow { dayNames } {
|
||||
wm iconname . ""
|
||||
wm protocol . WM_DELETE_WINDOW Quit
|
||||
wm deiconify .
|
||||
bind . <Control-KeyPress-q> Quit
|
||||
bind . <KeyPress-Left> ".b.prev flash; .b.prev invoke"
|
||||
bind . <KeyPress-Right> ".b.next flash; .b.next invoke"
|
||||
bind . <KeyPress-Prior> ".b.prev flash; .b.prev invoke"
|
||||
bind . <KeyPress-Next> ".b.next flash; .b.next invoke"
|
||||
bind . <KeyPress-Home> ".b.this flash; .b.this invoke"
|
||||
|
||||
if {$Option(StartIconified)} {
|
||||
wm iconify .
|
||||
}
|
||||
@@ -486,6 +564,22 @@ 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
|
||||
# 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
|
||||
entry $w.email_address -width 30
|
||||
pack $w.lab_email_address -in $w.eml -side left -expand 0 -fill none
|
||||
pack $w.email_address -in $w.eml -side left -expand 1 -fill x
|
||||
$w.email_address insert 0 $tmpOpt(MailAddr)
|
||||
|
||||
frame $w.fsmtp
|
||||
label $w.lab_smtp -text "Name or IP address of SMTP server:" -anchor w -justify left
|
||||
entry $w.smtp -width 30
|
||||
pack $w.lab_smtp -in $w.fsmtp -side left -expand 0 -fill none
|
||||
pack $w.smtp -in $w.fsmtp -side left -expand 1 -fill x
|
||||
$w.smtp insert 0 $tmpOpt(SMTPServer)
|
||||
|
||||
# Editor
|
||||
frame $w.ef
|
||||
label $w.el -text "Text Editor:" -anchor w -justify left
|
||||
@@ -510,6 +604,9 @@ proc EditOptions {} {
|
||||
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
|
||||
pack $w.sep3 -in $w.f -side top -expand 0 -fill x -ipady 1
|
||||
pack $w.eml -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.fsmtp -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.ef -in $w.f -side top -expand 0 -fill x
|
||||
pack $w.sep2 -in $w.f -side top -expand 0 -fill x -ipady 1
|
||||
|
||||
@@ -534,6 +631,9 @@ proc ApplyOptions { w } {
|
||||
global Option tmpOpt
|
||||
set tmpOpt(RunCmd) [$w.cmd get]
|
||||
set tmpOpt(Editor) [$w.editor get]
|
||||
set tmpOpt(MailAddr) [$w.email_address get]
|
||||
set tmpOpt(SMTPServer) [$w.smtp get]
|
||||
|
||||
# Copy working copy to real option set
|
||||
foreach name [array names tmpOpt] {
|
||||
set Option($name) $tmpOpt($name)
|
||||
@@ -623,7 +723,7 @@ proc LoadOptions {} {
|
||||
#***********************************************************************
|
||||
proc ConfigureCalWindow { month year firstDay numDays } {
|
||||
.h.title configure -text "$month $year"
|
||||
wm title . "TkRemind - $month $year"
|
||||
wm title . "$month $year - TkRemind"
|
||||
wm iconname . "$month $year"
|
||||
ConfigureCalFrame .cal $firstDay $numDays
|
||||
}
|
||||
@@ -661,10 +761,6 @@ proc FillCalWindow {} {
|
||||
ConfigureCalWindow $monthName $year $firstWkday $daysInMonth
|
||||
set offset [CalEntryOffset $firstWkday]
|
||||
|
||||
for {set i 1} {$i <= 31} {incr i} {
|
||||
set didSomething($i) 0
|
||||
}
|
||||
|
||||
set fntag "x"
|
||||
while { [gets $file line] >= 0 } {
|
||||
# File info
|
||||
@@ -685,6 +781,13 @@ proc FillCalWindow {} {
|
||||
set month [string trimleft $month 0]
|
||||
set extratags ""
|
||||
switch -exact -- $type {
|
||||
"WEEK" {
|
||||
set stuff [string trimleft $stuff]
|
||||
set stuff [string trimright $stuff]
|
||||
set label [expr $firstWkday + $day - 1]
|
||||
.cal.l$label configure -text "$day $stuff"
|
||||
continue
|
||||
}
|
||||
"SHADE" {
|
||||
DoShadeSpecial $n $stuff
|
||||
continue
|
||||
@@ -693,6 +796,7 @@ proc FillCalWindow {} {
|
||||
DoMoonSpecial $n $stuff
|
||||
continue
|
||||
}
|
||||
"COLOUR" -
|
||||
"COLOR" {
|
||||
if {[regexp {^ *([0-9]+) +([0-9]+) +([0-9]+) +(.*)$} $stuff all r g b rest]} {
|
||||
if {$r > 255} {
|
||||
@@ -719,16 +823,14 @@ proc FillCalWindow {} {
|
||||
}
|
||||
}
|
||||
}
|
||||
if { $type != "*" && $type != "COLOR"} {
|
||||
if { $type != "*" && $type != "COLOR" && $type != "COLOUR"} {
|
||||
continue
|
||||
}
|
||||
.cal.t$n configure -state normal
|
||||
if { $didSomething($day) } {
|
||||
.cal.t$n insert end " .....\n"
|
||||
}
|
||||
set didSomething($day) 1
|
||||
if {[regexp {TKTAG([0-9]+)} $tag all tagno]} {
|
||||
.cal.t$n insert end [string trim $stuff] [list REM TAGGED "TKTAG$tagno" $extratags $fntag]
|
||||
.cal.t$n tag bind "TKTAG$tagno" <Enter> "TaggedEnter .cal.t$n"
|
||||
.cal.t$n tag bind "TKTAG$tagno" <Leave> "TaggedLeave .cal.t$n"
|
||||
} else {
|
||||
.cal.t$n insert end [string trim $stuff] [list REM $extratags $fntag]
|
||||
}
|
||||
@@ -990,11 +1092,11 @@ proc DoGoto {} {
|
||||
global CurYear CurMonth MonthNames
|
||||
set year [.g.y.e get]
|
||||
if { ! [regexp {^[0-9]+$} $year] } {
|
||||
tk_dialog .error Error {Illegal year specified (1990-2078)} error 0 Ok
|
||||
tk_dialog .error Error {Illegal year specified (1990-5990)} error 0 Ok
|
||||
return
|
||||
}
|
||||
if { $year < 1990 || $year > 2078 } {
|
||||
tk_dialog .error Error {Illegal year specified (1990-2078)} error 0 Ok
|
||||
if { $year < 1990 || $year > 5990 } {
|
||||
tk_dialog .error Error {Illegal year specified (1990-5990)} error 0 Ok
|
||||
return
|
||||
}
|
||||
set month [lsearch -exact $MonthNames [.g.mon cget -text]]
|
||||
@@ -1034,7 +1136,7 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
|
||||
# Set up: Year, Month, Day, WeekdayName
|
||||
global CurYear CurMonth EnglishDayNames MonthNames OptionType SkipType
|
||||
global ModifyDialogResult
|
||||
global ModifyDialogResult TwentyFourHourMode
|
||||
|
||||
set OptionType 1
|
||||
set SkipType 1
|
||||
@@ -1050,12 +1152,13 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
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.msg
|
||||
frame $w.buttons
|
||||
pack $w.o1 $w.o2 $w.o3 -side top -anchor w -in $w.o
|
||||
pack $w.o $w.exp $w.adv $w.weekend $w.time $w.hol $w.msg -side top -anchor w -pady 4 -expand 1 -fill both
|
||||
pack $w.o $w.exp $w.adv $w.weekend $w.time $w.durationbox $w.hol $w.msg -side top -anchor w -pady 4 -expand 1 -fill both
|
||||
pack $w.buttons -side top -anchor w -pady 4 -expand 1 -fill x
|
||||
|
||||
# TYPE 1 REMINDER
|
||||
@@ -1154,7 +1257,11 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
checkbutton $w.timebut -text "Timed reminder at"
|
||||
$w.timebut deselect
|
||||
menubutton $w.timehour -text "12" -menu $w.timehour.menu -relief raised
|
||||
CreateDayMenu $w.timehour 1 12 0
|
||||
if {$TwentyFourHourMode} {
|
||||
CreateDayMenu $w.timehour 0 23 0
|
||||
} else {
|
||||
CreateDayMenu $w.timehour 1 12 0
|
||||
}
|
||||
menubutton $w.timemin -text "00" -menu $w.timemin.menu -relief raised
|
||||
menu $w.timemin.menu -tearoff 0
|
||||
foreach i {00 05 10 15 20 25 30 35 40 45 50 55} {
|
||||
@@ -1162,10 +1269,12 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
-command "$w.timemin configure -text $i"
|
||||
}
|
||||
|
||||
menubutton $w.ampm -text "PM" -menu $w.ampm.menu -relief raised
|
||||
menu $w.ampm.menu -tearoff 0
|
||||
$w.ampm.menu add command -label "AM" -command "$w.ampm configure -text {AM}"
|
||||
$w.ampm.menu add command -label "PM" -command "$w.ampm configure -text {PM}"
|
||||
if {!$TwentyFourHourMode} {
|
||||
menubutton $w.ampm -text "PM" -menu $w.ampm.menu -relief raised
|
||||
menu $w.ampm.menu -tearoff 0
|
||||
$w.ampm.menu add command -label "AM" -command "$w.ampm configure -text {AM}"
|
||||
$w.ampm.menu add command -label "PM" -command "$w.ampm configure -text {PM}"
|
||||
}
|
||||
|
||||
checkbutton $w.timeadvbut -text "with"
|
||||
$w.timeadvbut deselect
|
||||
@@ -1184,7 +1293,27 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
$w.timerep.menu add command -label $i -command "$w.timerep configure -text $i"
|
||||
}
|
||||
label $w.timelab2 -text "minutes"
|
||||
pack $w.timebut $w.timehour $w.timemin $w.ampm $w.timeadvbut $w.timeadv $w.timelab1 $w.timerepbut $w.timerep $w.timelab2 -side left -anchor w -in $w.time
|
||||
if {$TwentyFourHourMode} {
|
||||
pack $w.timebut $w.timehour $w.timemin $w.timeadvbut $w.timeadv $w.timelab1 $w.timerepbut $w.timerep $w.timelab2 -side left -anchor w -in $w.time
|
||||
} else {
|
||||
pack $w.timebut $w.timehour $w.timemin $w.ampm $w.timeadvbut $w.timeadv $w.timelab1 $w.timerepbut $w.timerep $w.timelab2 -side left -anchor w -in $w.time
|
||||
}
|
||||
|
||||
# DURATION
|
||||
checkbutton $w.durationbut -text "Duration"
|
||||
$w.durationbut deselect
|
||||
menubutton $w.durationh -text "1" -menu $w.durationh.menu -relief raised
|
||||
menu $w.durationh.menu -tearoff 0
|
||||
foreach i {0 1 2 3 4 5 6 7 8 9 10 11 12} {
|
||||
$w.durationh.menu add command -label $i -command "$w.durationh configure -text $i"
|
||||
}
|
||||
label $w.durationcolon -text ":"
|
||||
menubutton $w.durationm -text "00" -menu $w.durationm.menu -relief raised
|
||||
menu $w.durationm.menu -tearoff 0
|
||||
foreach i {00 15 30 45} {
|
||||
$w.durationm.menu add command -label $i -command "$w.durationm configure -text $i"
|
||||
}
|
||||
pack $w.durationbut $w.durationh $w.durationcolon $w.durationm -side left -anchor w -in $w.durationbox
|
||||
|
||||
# SKIP TYPE
|
||||
label $w.labhol -text "On holidays or weekends:"
|
||||
@@ -1208,7 +1337,10 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
pack $w.but$nbut -side left -anchor w -in $w.buttons -expand 1 -fill x
|
||||
}
|
||||
|
||||
bind $w <KeyPress-Escape> "$w.but1 invoke"
|
||||
bind $w <KeyPress-Escape> "$w.but1 flash; $w.but1 invoke"
|
||||
if {$nbut >= 2} {
|
||||
bind $w.entry <KeyPress-Return> "$w.but2 flash; $w.but2 invoke"
|
||||
}
|
||||
set ModifyDialogResult 0
|
||||
|
||||
# Center the window on the root
|
||||
@@ -1225,7 +1357,7 @@ proc CreateModifyDialog {w day firstDay args} {
|
||||
#***********************************************************************
|
||||
proc RemindDialogToOptions { w } {
|
||||
global OptionType SkipType repbut expbut advbut advcount
|
||||
global timebut timeadvbut timerepbut
|
||||
global timebut timeadvbut timerepbut durationbut
|
||||
global dSaturday dSunday dMonday dTuesday dWednesday dThursday dFriday
|
||||
set ans {}
|
||||
lappend ans "-global-OptionType" $OptionType
|
||||
@@ -1240,7 +1372,7 @@ proc RemindDialogToOptions { w } {
|
||||
lappend ans "-global-$winstem" [eval set $winstem]
|
||||
}
|
||||
"Entry" {
|
||||
lappend ans "-entry-$winstem" [$win get]
|
||||
lappend ans "-entry-$winstem" [string map -nocase {"\n" " "} [$win get]]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1259,13 +1391,20 @@ proc RemindDialogToOptions { w } {
|
||||
#***********************************************************************
|
||||
proc OptionsToRemindDialog { w opts } {
|
||||
global OptionType SkipType repbut expbut advbut advcount
|
||||
global timebut timeadvbut timerepbut
|
||||
global timebut timeadvbut timerepbut TwentyFourHourMode durationbut
|
||||
global dSaturday dSunday dMonday dTuesday dWednesday dThursday dFriday
|
||||
set hour ""
|
||||
set ampm ""
|
||||
foreach {flag value} $opts {
|
||||
switch -glob -- $flag {
|
||||
"-text-*" {
|
||||
set win [string range $flag 6 end]
|
||||
$w.$win configure -text $value
|
||||
catch { $w.$win configure -text $value }
|
||||
if {"$flag" == "-text-ampm"} {
|
||||
set ampm $value
|
||||
} elseif {"$flag" == "-text-timehour"} {
|
||||
set hour $value
|
||||
}
|
||||
}
|
||||
"-global-*" {
|
||||
set win [string range $flag 8 end]
|
||||
@@ -1278,6 +1417,26 @@ proc OptionsToRemindDialog { w opts } {
|
||||
}
|
||||
}
|
||||
}
|
||||
if {"$hour" != ""} {
|
||||
if {$TwentyFourHourMode} {
|
||||
if {"$ampm" != ""} {
|
||||
if {"$ampm" == "PM" && $hour < 12} {
|
||||
incr hour 12;
|
||||
$w.timehour configure -text $hour
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if {$hour > 12} {
|
||||
incr hour -12
|
||||
$w.timehour configure -text $hour
|
||||
$w.ampm configure -text "PM"
|
||||
} else {
|
||||
if {"$ampm" == ""} {
|
||||
$w.ampm configure -text "AM"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -1431,7 +1590,7 @@ proc CenterWindow {w} {
|
||||
# The reminder as a string.
|
||||
#---------------------------------------------------------------------------
|
||||
proc CreateReminder {w} {
|
||||
global DidOmit
|
||||
global DidOmit TwentyFourHourMode
|
||||
|
||||
set body [string trim [$w.entry get]]
|
||||
|
||||
@@ -1444,7 +1603,7 @@ proc CreateReminder {w} {
|
||||
# Delegate the first part to CreateReminder1, CreateReminder2, or
|
||||
# CreateReminder3
|
||||
global OptionType SkipType repbut expbut advbut advcount
|
||||
global timebut timeadvbut timerepbut
|
||||
global timebut timeadvbut timerepbut durationbut
|
||||
|
||||
set rem [CreateReminder$OptionType $w]
|
||||
|
||||
@@ -1468,13 +1627,15 @@ proc CreateReminder {w} {
|
||||
if {$timebut} {
|
||||
set hour [$w.timehour cget -text]
|
||||
set min [$w.timemin cget -text]
|
||||
if {[$w.ampm cget -text] == "PM"} {
|
||||
if {$hour < 12} {
|
||||
incr hour 12
|
||||
}
|
||||
} else {
|
||||
if {$hour == 12} {
|
||||
set hour 0
|
||||
if {!$TwentyFourHourMode} {
|
||||
if {[$w.ampm cget -text] == "PM"} {
|
||||
if {$hour < 12} {
|
||||
incr hour 12
|
||||
}
|
||||
} else {
|
||||
if {$hour == 12} {
|
||||
set hour 0
|
||||
}
|
||||
}
|
||||
}
|
||||
append rem " AT $hour:$min"
|
||||
@@ -1484,6 +1645,9 @@ proc CreateReminder {w} {
|
||||
if {$timerepbut} {
|
||||
append rem " *[$w.timerep cget -text]"
|
||||
}
|
||||
if {$durationbut} {
|
||||
append rem " DURATION [$w.durationh cget -text]:[$w.durationm cget -text]"
|
||||
}
|
||||
}
|
||||
|
||||
global SkipType
|
||||
@@ -1519,7 +1683,7 @@ proc CreateReminder {w} {
|
||||
regsub -- {^-stdin-\([0-9]*\): } $err {} err
|
||||
error "Error from Remind: $err"
|
||||
}
|
||||
append rem " MSG $body"
|
||||
append rem " MSG " [string map -nocase {"\n" " "} $body]
|
||||
return $rem
|
||||
}
|
||||
|
||||
@@ -1694,7 +1858,7 @@ proc EditReminder {rem args} {
|
||||
}
|
||||
pack .edit.t -side top -fill both -expand 1
|
||||
pack .edit.f -side top -fill x -expand 1
|
||||
bind .edit <KeyPress-Escape> ".edit.but1 invoke"
|
||||
bind .edit <KeyPress-Escape> ".edit.but1 flash; .edit.but1 invoke"
|
||||
set ModifyDialogResult 0
|
||||
CenterWindow .edit
|
||||
tkwait visibility .edit
|
||||
@@ -2070,12 +2234,15 @@ proc IssueBackgroundReminder { file time now tag } {
|
||||
label $w.l -text "Reminder for $time issued at $now"
|
||||
message $w.msg -width 6i -text $msg
|
||||
frame $w.b
|
||||
button $w.ok -text "OK" -command "destroy $w"
|
||||
|
||||
# Automatically shut down window after a minute if option says so
|
||||
set after_token [after 60000 [list ClosePopup $w "" $Option(MailAddr) $Option(AutoClose) "" $tag $msg $time]]
|
||||
|
||||
wm protocol $w WM_DELETE_WINDOW [list ClosePopup $w $after_token "" 1 "" $tag $msg $time]
|
||||
button $w.ok -text "OK" -command [list ClosePopup $w $after_token "" 1 "" $tag $msg $time]
|
||||
if {$tag != "*"} {
|
||||
button $w.nomore -text "Don't remind me again today" -command \
|
||||
"destroy $w; set Ignore($tag) 1"
|
||||
button $w.kill -text "Delete this reminder completely" -command \
|
||||
"destroy $w; InteractiveDeleteReminder $tag"
|
||||
button $w.nomore -text "Don't remind me again today" -command [list ClosePopup $w $after_token "" 1 "ignore" $tag $msg $time]
|
||||
button $w.kill -text "Delete this reminder completely" -command [list ClosePopup $w $after_token "" 1 "kill" $tag $msg $time]
|
||||
}
|
||||
pack $w.l -side top
|
||||
pack $w.msg -side top -expand 1 -fill both
|
||||
@@ -2087,11 +2254,6 @@ proc IssueBackgroundReminder { file time now tag } {
|
||||
|
||||
CenterWindow $w
|
||||
|
||||
# Automatically shut down window after a minute if option says so
|
||||
if {$Option(AutoClose)} {
|
||||
after 60000 "catch { destroy $w }"
|
||||
}
|
||||
|
||||
update
|
||||
if {$Option(RingBell)} {
|
||||
bell
|
||||
@@ -2156,8 +2318,11 @@ proc main {} {
|
||||
}
|
||||
|
||||
global AppendFile HighestTagSoFar DayNames
|
||||
puts "\nTkRemind Copyright (C) 1996-1998 David F. Skoll"
|
||||
puts "Copyright (C) 1999-2000 Roaring Penguin Software Inc."
|
||||
catch {
|
||||
puts "\nTkRemind Copyright (C) 1996-1998 David F. Skoll"
|
||||
puts "Copyright (C) 1999-2010 Roaring Penguin Software Inc."
|
||||
}
|
||||
catch { SetFonts }
|
||||
LoadOptions
|
||||
CreateMoonImages
|
||||
Initialize
|
||||
@@ -2249,6 +2414,8 @@ proc FireEditor { w } {
|
||||
return
|
||||
}
|
||||
}
|
||||
Status "Firing up editor..."
|
||||
after 1500 DisplayTime
|
||||
set EditorPid [exec sh -c $editor &]
|
||||
}
|
||||
|
||||
@@ -2590,12 +2757,13 @@ proc DoMoonSpecial { n stuff } {
|
||||
3 { set image last }
|
||||
}
|
||||
.cal.t$n configure -state normal
|
||||
.cal.t$n image create end -image $image
|
||||
.cal.t$n image create 1.0 -image $image
|
||||
|
||||
if {$msg != ""} {
|
||||
.cal.t$n insert end " $msg"
|
||||
.cal.t$n insert 1.1 " $msg\n"
|
||||
} else {
|
||||
.cal.t$n insert 1.1 "\n"
|
||||
}
|
||||
.cal.t$n insert end "\n"
|
||||
.cal.t$n configure -state disabled
|
||||
}
|
||||
#***********************************************************************
|
||||
@@ -2608,7 +2776,12 @@ proc DoMoonSpecial { n stuff } {
|
||||
# Displays current date and time in status window
|
||||
#***********************************************************************
|
||||
proc DisplayTime {} {
|
||||
set msg [clock format [clock seconds] -format "%e %b %Y %I:%M%p"]
|
||||
global TwentyFourHourMode
|
||||
if {$TwentyFourHourMode} {
|
||||
set msg [clock format [clock seconds] -format "%e %b %Y %H:%M"]
|
||||
} else {
|
||||
set msg [clock format [clock seconds] -format "%e %b %Y %I:%M%p"]
|
||||
}
|
||||
Status $msg
|
||||
}
|
||||
|
||||
@@ -2685,7 +2858,7 @@ proc ShowTodaysReminders {} {
|
||||
CenterWindow $w
|
||||
|
||||
# Grab the reminders
|
||||
set stuff [exec -keepnewline $Remind -q -a -r $ReminderFile 2>/dev/null]
|
||||
set stuff [exec -keepnewline $Remind -g -q -r $ReminderFile 2>/dev/null]
|
||||
$w.text insert end $stuff
|
||||
$w.text configure -state disabled
|
||||
}
|
||||
@@ -2708,4 +2881,53 @@ proc InteractiveDeleteReminder { tag } {
|
||||
}
|
||||
}
|
||||
|
||||
proc SendMail { recipient subject body } {
|
||||
global Option
|
||||
|
||||
if {"$Option(MailAddr)" == ""} {
|
||||
return
|
||||
}
|
||||
if {[catch {set token [mime::initialize -canonical text/plain -string $body]
|
||||
mime::setheader $token Subject $subject
|
||||
mime::setheader $token From "Reminder Service <>"
|
||||
mime::setheader $token To "<$recipient>"
|
||||
mime::setheader $token Auto-Submitted "auto-generated"
|
||||
smtp::sendmessage $token -originator "" -servers $Option(SMTPServer) -recipients $Option(MailAddr)} err]} {
|
||||
puts stderr "ERROR sending mail: $err"
|
||||
}
|
||||
}
|
||||
|
||||
proc ClosePopup { w after_token mail_addr close_win ignore_or_kill tag reminder rem_time } {
|
||||
global Ignore
|
||||
if {"$after_token" != ""} {
|
||||
catch { after cancel $after_token }
|
||||
}
|
||||
|
||||
if {$close_win} {
|
||||
catch { destroy $w }
|
||||
}
|
||||
|
||||
if {"$mail_addr" != ""} {
|
||||
SendMail $mail_addr "Reminder for $rem_time" "Hello,\n\nThe following reminder is scheduled for $rem_time:\n\n$reminder\nRegards,\n\nTkRemind\n"
|
||||
}
|
||||
if {"$ignore_or_kill" == "ignore"} {
|
||||
set Ignore($tag) 1
|
||||
}
|
||||
if {"$ignore_or_kill" == "kill"} {
|
||||
InteractiveDeleteReminder $tag
|
||||
}
|
||||
}
|
||||
|
||||
# Adjust font defaults for screen size
|
||||
proc SetFonts {} {
|
||||
global SetFontsWorked
|
||||
set h [winfo screenheight .]
|
||||
if {$h <= 480} {
|
||||
# Small screen (maybe eeepc?)
|
||||
font configure TkDefaultFont -size 6
|
||||
font configure TkFixedFont -size 6
|
||||
}
|
||||
set SetFontsWorked 1
|
||||
}
|
||||
|
||||
main
|
||||
|
||||
@@ -1,65 +1,70 @@
|
||||
# Makefile.in for REMIND
|
||||
#
|
||||
# $Id: Makefile.in,v 1.24 2005-09-30 03:29:32 dfs Exp $
|
||||
#
|
||||
|
||||
VERSION=03.00.24
|
||||
SHELL= /bin/sh
|
||||
|
||||
BETA = 1
|
||||
srcdir=@srcdir@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
mandir=@mandir@
|
||||
bindir=@bindir@
|
||||
datadir=@datadir@
|
||||
datarootdir=@datarootdir@
|
||||
VPATH=$(srcdir)
|
||||
VERSION=@VERSION@
|
||||
|
||||
INSTALL=@INSTALL@
|
||||
INSTALL_PROGRAM=@INSTALL_PROGRAM@
|
||||
INSTALL_DATA=@INSTALL_DATA@
|
||||
|
||||
PROGS= remind rem2ps
|
||||
SCRIPTS= $(srcdir)/../scripts/kall $(srcdir)/../scripts/rem \
|
||||
$(srcdir)/../scripts/tkremind $(srcdir)/../scripts/cm2rem.tcl
|
||||
SCRIPTS= $(srcdir)/../scripts/tkremind $(srcdir)/../scripts/cm2rem.tcl
|
||||
|
||||
MANS= $(srcdir)/../man/kall.1 $(srcdir)/../man/rem.1 \
|
||||
$(srcdir)/../man/rem2ps.1 $(srcdir)/../man/remind.1 \
|
||||
$(srcdir)/../man/tkremind.1 $(srcdir)/../man/cm2rem.1
|
||||
MANS= $(srcdir)/../man/rem2ps.1 $(srcdir)/../man/remind.1 \
|
||||
$(srcdir)/../man/tkremind.1 $(srcdir)/../man/cm2rem.1 \
|
||||
$(srcdir)/../man/rem.1
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
REMINDSRCS= calendar.c dynbuf.c dorem.c dosubst.c expr.c files.c funcs.c \
|
||||
globals.c hbcal.c init.c main.c moon.c omit.c queue.c sort.c \
|
||||
token.c trigger.c userfns.c utils.c var.c
|
||||
globals.c hbcal.c init.c main.c md5.c moon.c omit.c queue.c \
|
||||
sort.c token.c trigger.c userfns.c utils.c var.c
|
||||
|
||||
REMINDHDRS=config.h custom.h dynbuf.h err.h expr.h globals.h lang.h \
|
||||
md5.h protos.h rem2ps.h types.h version.h
|
||||
REMINDOBJS= $(REMINDSRCS:.c=.o)
|
||||
|
||||
all: remind rem2ps
|
||||
|
||||
test: remind
|
||||
sh ../tests/test-rem
|
||||
@sh ../tests/test-rem
|
||||
|
||||
.c.o:
|
||||
@CC@ -c @CFLAGS@ @DEFS@ $(CEXTRA) $(LANGDEF) -I. -I$(srcdir) $<
|
||||
|
||||
rem2ps: rem2ps.o dynbuf.o
|
||||
@CC@ @LDFLAGS@ -o rem2ps rem2ps.o dynbuf.o
|
||||
@CC@ @LDFLAGS@ $(LDEXTRA) -o rem2ps rem2ps.o dynbuf.o
|
||||
|
||||
remind: $(REMINDOBJS)
|
||||
@CC@ @LDFLAGS@ -o remind $(REMINDOBJS) @LIBS@
|
||||
@CC@ @LDFLAGS@ $(LDEXTRA) -o remind $(REMINDOBJS) @LIBS@
|
||||
|
||||
install: all
|
||||
install-nostripped: all
|
||||
-mkdir -p $(DESTDIR)$(bindir) || true
|
||||
for prog in $(PROGS) $(SCRIPTS) ; do \
|
||||
$(INSTALL_PROGRAM) $$prog $(DESTDIR)$(bindir) || exit 1; \
|
||||
done
|
||||
-strip $(DESTDIR)$(bindir)/remind || true
|
||||
-strip $(DESTDIR)$(bindir)/rem2ps || true
|
||||
rm -f $(DESTDIR)$(bindir)/rem > /dev/null 2>&1 || true
|
||||
ln -s remind $(DESTDIR)$(bindir)/rem
|
||||
-mkdir -p $(DESTDIR)$(mandir)/man1 || true
|
||||
for man in $(MANS) ; do \
|
||||
$(INSTALL_DATA) $$man $(DESTDIR)$(mandir)/man1 || exit 1; \
|
||||
done
|
||||
|
||||
install: install-nostripped
|
||||
strip $(DESTDIR)$(bindir)/remind || true
|
||||
strip $(DESTDIR)$(bindir)/rem2ps || true
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ core *.bak $(PROGS)
|
||||
|
||||
@@ -72,17 +77,19 @@ depend:
|
||||
# The next targets are not very useful to you. I use them to build
|
||||
# distributions, etc.
|
||||
|
||||
# Build a tar file based on all files checked into CVS.
|
||||
# Build a tar file based on all files checked into git.
|
||||
distro:
|
||||
ln -s .. remind-$(VERSION)
|
||||
peekentry `find remind-$(VERSION) -depth -follow -name 'Entries' -print` | xargs tar cvf remind-$(VERSION).tar
|
||||
ln -s . ../remind-$(VERSION)
|
||||
(cd ..; git ls-files | fgrep -v .gitignore | fgrep -v remind.php) | sed -e 's/^/remind-$(VERSION)\//' | xargs tar -C .. -cvf remind-$(VERSION).tar
|
||||
gzip -f -v -9 remind-$(VERSION).tar
|
||||
rm -f remind-$(VERSION)
|
||||
rm -f ../remind-$(VERSION)
|
||||
|
||||
beta-tgz:
|
||||
ln -s .. remind-$(VERSION)-BETA
|
||||
peekentry `find remind-$(VERSION)-BETA -depth -follow -name 'Entries' -print` | xargs tar cvf remind-$(VERSION)-BETA.tar
|
||||
gzip -f -v -9 remind-$(VERSION)-BETA.tar
|
||||
rm -f remind-$(VERSION)-BETA
|
||||
ln -s . ../remind-$(VERSION)-BETA-$(BETA)
|
||||
(cd ..; git ls-files | fgrep -v .gitignore | fgrep -v remind.php) | sed -e 's/^/remind-$(VERSION)-BETA-$(BETA)\//' | xargs tar -C .. -cvf remind-$(VERSION)-BETA-$(BETA).tar
|
||||
gzip -f -v -9 remind-$(VERSION)-BETA-$(BETA).tar
|
||||
rm -f ../remind-$(VERSION)-BETA-$(BETA)
|
||||
|
||||
#---------------- Stuff after this added by "make depend" -----------------
|
||||
|
||||
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
#$Id: Makefile_QDOS,v 1.1 2000-03-15 16:03:57 dfs Exp $
|
||||
# Makefile for REMIND for QDOS / SMSQ
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# THINGS FOR YOU TO EDIT START BELOW
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# Uncomment the next lines if you want to use gcc instead of default compiler
|
||||
# NOTE: Tempting as it may be, if you use 'cc' for the C compiler, do not
|
||||
# use 'ld' for the linker. It will probably work much better if you use
|
||||
# LD= cc rather than LD= ld.
|
||||
# QDOS remark: I made it work the following way, and I found it to be working.
|
||||
CC= cc
|
||||
LD= ld
|
||||
|
||||
# Put any additional flags for the C compiler or linker here - if you
|
||||
# are not using gcc, you probably want to remove '-ansi'.
|
||||
# QDOS remark: no -ansi option and no gcc on QDOS / SMSQ
|
||||
CFLAGS= -V -O -DQDOS
|
||||
CDEFS=
|
||||
LDFLAGS= -bufp200K
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# YOU SHOULDN'T EDIT ANYTHING BELOW HERE. You may want to change some things
|
||||
# in config_h; then, you should be able to type 'make'.
|
||||
#-----------------------------------------------------------------------------
|
||||
MATHLIB= -lm
|
||||
|
||||
HDRS= config_h err_h expr_h globals_h protos_h types_h version_h \
|
||||
lang_h english_h german_h dutch_h finnish_h french_h norwgian_h \
|
||||
danish_h polish_h
|
||||
|
||||
STDHDRS= config_h types_h protos_h globals_h err_h lang_h
|
||||
|
||||
LANGHDRS= english_h german_h dutch_h finnish_h french_h norwgian_h danish_h \
|
||||
polish_h
|
||||
|
||||
SRCS= calendar_c dorem_c dosubst_c expr_c files_c funcs_c globals_c hbcal_c \
|
||||
init_c main_c moon_c omit_c sort_c queue_c token_c trigger_c userfns_c \
|
||||
utils_c var_c
|
||||
|
||||
OBJS= calendar_o dorem_o dosubst_o expr_o files_o funcs_o globals_o hbcal_o \
|
||||
init_o main_o moon_o omit_o sort_o queue_o token_o trigger_o userfns_o \
|
||||
utils_o var_o
|
||||
|
||||
all: remind rem2ps
|
||||
|
||||
# _c_o:
|
||||
# $(CC) $(UNIX) $(SYSV) -c $(CFLAGS) $(CDEFS) $*_c
|
||||
|
||||
rem2ps: rem2ps_o
|
||||
# $(CC) $(CFLAGS) rem2ps_c
|
||||
$(LD) $(LDFLAGS) -orem2ps rem2ps_o
|
||||
|
||||
remind: $(OBJS)
|
||||
# $(CC) $(CFLAGS) $(SRCS)
|
||||
$(LD) $(LDFLAGS) -oremind $(OBJS) $(MATHLIB)
|
||||
|
||||
rem2ps_o: rem2ps_c rem2ps_h lang_h config_h
|
||||
calendar_o: calendar_c $(STDHDRS) expr_h
|
||||
dorem_o: dorem_c $(STDHDRS) expr_h
|
||||
dosubst_o: dosubst_c $(STDHDRS) $(LANGHDRS)
|
||||
expr_o: expr_c $(STDHDRS) expr_h
|
||||
files_o: files_c $(STDHDRS)
|
||||
funcs_o: funcs_c $(STDHDRS) expr_h version_h
|
||||
globals_o: globals_c config_h types_h globals_h err_h lang_h $(LANGHDRS)
|
||||
hbcal_o: hbcal_c $(STDHDRS)
|
||||
init_o: init_c $(STDHDRS) expr_h version_h lang_h $(LANGHDRS)
|
||||
main_o: main_c $(STDHDRS) expr_h
|
||||
moon_o: moon_c $(STDHDRS)
|
||||
omit_o: omit_c $(STDHDRS)
|
||||
sort_o: sort_c $(STDHDRS)
|
||||
queue_o: queue_c $(STDHDRS)
|
||||
token_o: token_c $(STDHDRS)
|
||||
trigger_o: trigger_c $(STDHDRS) expr_h
|
||||
userfns_o: userfns_c $(STDHDRS) expr_h
|
||||
utils_o: utils_c $(STDHDRS)
|
||||
var_o: var_c $(STDHDRS) expr_h
|
||||
|
||||
|
||||
clean:
|
||||
rm -f *_o *_bak
|
||||
|
||||
clobber:
|
||||
rm -f *_o remind rem2ps test_out *_bak
|
||||
@@ -1,7 +0,0 @@
|
||||
IGNORE=154
|
||||
IGNORE=161
|
||||
IGNORE=100
|
||||
IGNORE=85
|
||||
LINKOPT SC
|
||||
LINKOPT SD
|
||||
LINKOPT NOICONS
|
||||
@@ -1,65 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* AMIGA.C */
|
||||
/* */
|
||||
/* Support functions for AmigaDOS */
|
||||
/* */
|
||||
/* This file is Copyright (C) 1995 by Martin Hohl */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Remind is Copyright (C) 1992-1998 by David F. Skoll */
|
||||
/* Copyright (C) 1999-2000 by Roaring Penguin Software Inc. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: amiga.c,v 1.1 2000-03-15 16:03:57 dfs Exp $";
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <exec/types.h>
|
||||
#include <dos/dos.h>
|
||||
#include <dos/dosextens.h>
|
||||
|
||||
#include <proto/dos.h>
|
||||
|
||||
#include "version.h" /* Hopefully this will define VERSION as a string */
|
||||
|
||||
#ifdef __SASC_60
|
||||
/* AmigaDOS 2.04 compatible version string for "version" utility */
|
||||
const static char ver_string[] = "$VER: remind "VERSION" "__AMIGADATE__;
|
||||
#endif
|
||||
|
||||
void sleep(int dt)
|
||||
{
|
||||
register long Ticks;
|
||||
|
||||
if (dt != 0) {
|
||||
Ticks = 50L * dt;
|
||||
Delay(Ticks);
|
||||
}
|
||||
}
|
||||
|
||||
void execvp(char *name, char **argvec)
|
||||
{
|
||||
char *cmdline;
|
||||
int i,l;
|
||||
|
||||
l = strlen(name)+2;
|
||||
i=1;
|
||||
while (argvec[i] != 0L) {
|
||||
l += strlen(argvec[i])+1;
|
||||
i++;
|
||||
};
|
||||
cmdline = malloc(l+1);
|
||||
if (cmdline == 0L) return;
|
||||
strcpy(cmdline,name);
|
||||
i=1;
|
||||
while (argvec[i] != 0L) {
|
||||
strcat(cmdline," ");
|
||||
strcat(cmdline,argvec[i]);
|
||||
i++;
|
||||
};
|
||||
system(cmdline);
|
||||
free(cmdline);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
calendar.obj
|
||||
dorem.obj
|
||||
dosubst.obj
|
||||
expr.obj
|
||||
files.obj
|
||||
funcs.obj
|
||||
globals.obj
|
||||
hbcal.obj
|
||||
init.obj
|
||||
main.obj
|
||||
moon.obj
|
||||
omit.obj
|
||||
os2func.obj
|
||||
queue.obj
|
||||
sort.obj
|
||||
token.obj
|
||||
trigger.obj
|
||||
userfns.obj
|
||||
utils.obj
|
||||
var.obj
|
||||
@@ -1,23 +0,0 @@
|
||||
calendar.obj +
|
||||
dorem.obj +
|
||||
dosubst.obj +
|
||||
expr.obj +
|
||||
files.obj +
|
||||
funcs.obj +
|
||||
globals.obj +
|
||||
hbcal.obj +
|
||||
init.obj +
|
||||
main.obj +
|
||||
moon.obj +
|
||||
omit.obj +
|
||||
sort.obj +
|
||||
token.obj +
|
||||
trigger.obj +
|
||||
userfns.obj +
|
||||
utils.obj +
|
||||
var.obj
|
||||
remind.exe
|
||||
nul
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
-eremind.exe
|
||||
calendar.obj
|
||||
dorem.obj
|
||||
dosubst.obj
|
||||
expr.obj
|
||||
files.obj
|
||||
funcs.obj
|
||||
globals.obj
|
||||
hbcal.obj
|
||||
init.obj
|
||||
main.obj
|
||||
moon.obj
|
||||
omit.obj
|
||||
sort.obj
|
||||
token.obj
|
||||
trigger.obj
|
||||
userfns.obj
|
||||
utils.obj
|
||||
var.obj
|
||||
@@ -1,95 +0,0 @@
|
||||
# Makefile for REMIND for Borland C++
|
||||
# $Id: makefile.bcc,v 1.1 2000-03-15 16:03:57 dfs Exp $
|
||||
|
||||
MODEL=l
|
||||
|
||||
!if $d(__OS2__)
|
||||
CFLAGS= -DOS2_POPUP -w-pia -O2
|
||||
BINDIR= ..\OS2-EX
|
||||
DELFLAG= /f
|
||||
!else
|
||||
CFLAGS= -w-pia -O2 -m$(MODEL)
|
||||
BINDIR= ..\MSDOS-EX
|
||||
DELFLAG=
|
||||
!endif
|
||||
|
||||
HDRS= config.h err.h expr.h globals.h protos.h types.h version.h \
|
||||
lang.h english.h german.h dutch.h finnish.h french.h norwgian.h \
|
||||
danish.h polish.h
|
||||
|
||||
STDHDRS= config.h types.h protos.h globals.h err.h lang.h
|
||||
|
||||
LANGHDRS= english.h german.h dutch.h finnish.h french.h norwgian.h danish.h \
|
||||
polish.h
|
||||
|
||||
SRCS= calendar.c dorem.c dosubst.c expr.c files.c funcs.c globals.c init.c \
|
||||
main.c omit.c sort.c token.c trigger.c userfns.c utils.c var.c hbcal.c \
|
||||
queue.c moon.c os2func.c
|
||||
|
||||
OBJS=calendar.obj dorem.obj dosubst.obj expr.obj files.obj funcs.obj \
|
||||
globals.obj init.obj main.obj omit.obj sort.obj token.obj trigger.obj \
|
||||
utils.obj userfns.obj var.obj hbcal.obj queue.obj moon.obj os2func.obj
|
||||
|
||||
all: exes test-rem.cmd test-rem.bat
|
||||
test-rem
|
||||
|
||||
clean:
|
||||
-del $(DELFLAG) *.obj
|
||||
-del $(DELFLAG) $(BINDIR)\*.exe
|
||||
|
||||
exes: $(BINDIR)\remind.exe $(BINDIR)\rem2ps.exe
|
||||
|
||||
..\os2-ex\remind.exe: $(OBJS)
|
||||
bcc -e..\os2-ex\remind @lnk.bcc -lap;Toe
|
||||
|
||||
..\msdos-ex\remind.exe: $(OBJS)
|
||||
bcc -e..\msdos-ex\remind -m$(MODEL) @lnk.bcc
|
||||
|
||||
..\os2-ex\rem2ps.exe: rem2ps.obj
|
||||
bcc -e..\os2-ex\rem2ps rem2ps.obj -lap;Toe
|
||||
|
||||
..\msdos-ex\rem2ps.exe: rem2ps.obj
|
||||
bcc -e..\msdos-ex\rem2ps -m$(MODEL) rem2ps.obj
|
||||
|
||||
.c.obj:
|
||||
bcc $(CFLAGS) -c {$< }
|
||||
|
||||
rem2ps.obj: rem2ps.c rem2ps.h config.h lang.h
|
||||
|
||||
calendar.obj: calendar.c $(STDHDRS) expr.h
|
||||
|
||||
dorem.obj: dorem.c $(STDHDRS) expr.h
|
||||
|
||||
dosubst.obj: dosubst.c $(STDHDRS) $(LANGHDRS)
|
||||
|
||||
expr.obj: expr.c $(STDHDRS) expr.h
|
||||
|
||||
files.obj: files.c $(STDHDRS)
|
||||
|
||||
funcs.obj: funcs.c $(STDHDRS) expr.h version.h
|
||||
|
||||
globals.obj: globals.c config.h types.h globals.h err.h lang.h
|
||||
|
||||
init.obj: init.c $(STDHDRS) expr.h version.h
|
||||
|
||||
main.obj: main.c $(STDHDRS) expr.h
|
||||
|
||||
moon.obj: moon.c $(STDHDRS) expr.h
|
||||
|
||||
omit.obj: omit.c $(STDHDRS)
|
||||
|
||||
os2func.obj: os2func.c $(STDHDRS)
|
||||
|
||||
queue.obj: queue.c $(STDHDRS)
|
||||
|
||||
sort.obj: sort.c $(STDHDRS)
|
||||
|
||||
token.obj: token.c $(STDHDRS)
|
||||
|
||||
trigger.obj: trigger.c $(STDHDRS) expr.h
|
||||
|
||||
userfns.obj: userfns.c $(STDHDRS) expr.h
|
||||
|
||||
utils.obj: utils.c $(STDHDRS)
|
||||
|
||||
var.obj: var.c $(STDHDRS) expr.h
|
||||
@@ -1,74 +0,0 @@
|
||||
# Makefile for REMIND for Microsoft C for MSDOS
|
||||
# $Id: makefile.msc,v 1.1 2000-03-15 16:03:57 dfs Exp $
|
||||
|
||||
OBJS= calendar.obj dorem.obj dosubst.obj expr.obj files.obj funcs.obj \
|
||||
globals.obj init.obj main.obj omit.obj token.obj trigger.obj userfns.obj \
|
||||
utils.obj var.obj sort.obj hbcal.obj moon.obj
|
||||
|
||||
DEFINES= /D__MSDOS__ /D__MSC__
|
||||
|
||||
MODEL= /AM
|
||||
|
||||
calendar.obj: calendar.c
|
||||
cl /c $(DEFINES) $(MODEL) /Focalendar.obj calendar.c
|
||||
|
||||
dorem.obj: dorem.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fodorem.obj dorem.c
|
||||
|
||||
dosubst.obj: dosubst.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fodosubst.obj dosubst.c
|
||||
|
||||
expr.obj: expr.c
|
||||
cl /c $(DEFINES) $(MODEL) /Foexpr.obj expr.c
|
||||
|
||||
hbcal.obj: hbcal.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fohbcal.obj hbcal.c
|
||||
|
||||
sort.obj: sort.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fosort.obj sort.c
|
||||
|
||||
files.obj: files.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fofiles.obj files.c
|
||||
|
||||
funcs.obj: funcs.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fofuncs.obj funcs.c
|
||||
|
||||
globals.obj: globals.c
|
||||
cl /c $(DEFINES) $(MODEL) /Foglobals.obj globals.c
|
||||
|
||||
init.obj: init.c
|
||||
cl /c $(DEFINES) $(MODEL) /Foinit.obj init.c
|
||||
|
||||
main.obj: main.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fomain.obj main.c
|
||||
|
||||
moon.obj: moon.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fomoon.obj moon.c
|
||||
|
||||
omit.obj: omit.c
|
||||
cl /c $(DEFINES) $(MODEL) /Foomit.obj omit.c
|
||||
|
||||
token.obj: token.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fotoken.obj token.c
|
||||
|
||||
trigger.obj: trigger.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fotrigger.obj trigger.c
|
||||
|
||||
userfns.obj: userfns.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fouserfns.obj userfns.c
|
||||
|
||||
utils.obj: utils.c
|
||||
cl /c $(DEFINES) $(MODEL) /Foutils.obj utils.c
|
||||
|
||||
var.obj: var.c
|
||||
cl /c $(DEFINES) $(MODEL) /Fovar.obj var.c
|
||||
|
||||
remind.exe: $(OBJS)
|
||||
link /NOI @lnk.msc
|
||||
|
||||
rem2ps.obj: rem2ps.c
|
||||
cl /c $(DEFINES) $(MODEL) /Forem2ps.obj rem2ps.c
|
||||
|
||||
rem2ps.exe: rem2ps.obj
|
||||
link /NOI rem2ps,rem2ps.exe,,,
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
# Makefile for REMIND
|
||||
#
|
||||
# $Id: makefile.os2,v 1.1 2000-03-15 16:03:57 dfs Exp $
|
||||
#
|
||||
# THIS IS OUT OF DATE!
|
||||
#
|
||||
# - for GNU gcc (emx 0.8g kit) [executables for OS/2 2.x or DOS (32-bit)]
|
||||
# - for Microsoft C 6.00A [executables for OS/2 or MSDOS (16-bit)]
|
||||
|
||||
# To use, enter "make -f Makefile.os2" (this makefile depends on its
|
||||
# name being "Makefile.os2").
|
||||
#
|
||||
# Tested with dmake 3.8 and GNU make 3.68 under OS/2
|
||||
|
||||
default:
|
||||
@echo "Enter $(MAKE) -f Makefile.os2 target "
|
||||
@echo " where 'target' is chosen from "
|
||||
@echo " msc OS/2 exe [Microsoft C 6.00a] "
|
||||
@echo " mscbnd OS/2 and DOS exe [Microsoft C 6.00a] "
|
||||
@echo " emx OS/2 and DOS 32-bit exe [EMX/gcc] "
|
||||
@echo " emxomf OS/2 32-bit exe w/DLL C library [EMX/gcc] "
|
||||
|
||||
|
||||
msc:
|
||||
$(MAKE) -f Makefile.os2 all \
|
||||
CC="cl -nologo -AM" O=".obj" \
|
||||
CFLAGS="-D__STDC__ -D__OS2__" \
|
||||
LFLAGS="-Lp" \
|
||||
LFLAGS2="setargv.obj remind.def -link /NOE"
|
||||
|
||||
mscbnd:
|
||||
$(MAKE) -f Makefile.os2 all \
|
||||
CC="cl -nologo -AM" O=".obj" \
|
||||
CFLAGS="-D__STDC__ -D__OS2__ -D__MSDOS__" \
|
||||
LFLAGS="-Lp" LBIND="-Fb" \
|
||||
LFLAGS2="setargv.obj remind.def -link /NOE" \
|
||||
BIND="bind remind /n DOSMAKEPIPE DOSCWAIT VIOENDPOPUP VIOPOPUP"
|
||||
|
||||
emx:
|
||||
$(MAKE) -f Makefile.os2 all \
|
||||
CC="gcc -O -s" O=".o" \
|
||||
CFLAGS="-D__OS2__ -D__MSDOS__" \
|
||||
LFLAGS=""
|
||||
|
||||
emxomf:
|
||||
$(MAKE) -f Makefile.os2 all \
|
||||
CC="gcc -Zomf -O -s" O=".obj" \
|
||||
CFLAGS="-D__OS2__" \
|
||||
LFLAGS="-Zcrtdll -Zstack 32" \
|
||||
LFLAGS2="remind.def"
|
||||
|
||||
|
||||
# OS2_POPUP enables Russ Herman's popup reminders
|
||||
#OS2_POPUP =
|
||||
OS2_POPUP = -DOS2_POPUP
|
||||
|
||||
HDRS= config.h err.h expr.h globals.h protos.h types.h version.h \
|
||||
lang.h english.h german.h dutch.h finnish.h french.h norwgian.h \
|
||||
danish.h polish.h
|
||||
|
||||
STDHDRS= config.h types.h protos.h globals.h err.h lang.h
|
||||
|
||||
LANGHDRS= english.h german.h dutch.h finnish.h french.h norwgian.h danish.h \
|
||||
polish.h
|
||||
|
||||
SRCS= calendar.c dorem.c dosubst.c expr.c files.c funcs.c globals.c hbcal.c \
|
||||
init.c main.c moon.c omit.c sort.c queue.c token.c trigger.c userfns.c \
|
||||
utils.c var.c os2func.c
|
||||
|
||||
MANIFEST= README.UNIX README.DOS COPYRIGHT $(HDRS) $(SRCS) Makefile rem rem.1 \
|
||||
remind.1 remind-all.csh remind-all.sh test.rem test-rem test.cmp makefile.tc \
|
||||
makefile.msc lnk.msc lnk.tc MANIFEST.UNX MANIFEST.DOS WHATSNEW.30 kall kall.1 \
|
||||
defs.rem README.OS2 makefile.os2 rem2ps.c rem2ps.h remind.def rem2ps.1 \
|
||||
tstlang.rem README.BCC lnk.bcc makefile.bcc os2func.c \
|
||||
test-rem.bat test-rem.cmd test1.cmp test2.cmp
|
||||
|
||||
|
||||
OBJS= $(SRCS:.c=$O)
|
||||
|
||||
all: remind.exe rem2ps.exe
|
||||
|
||||
.SUFFIXES: $O
|
||||
|
||||
.c$O:
|
||||
$(CC) -c $(CFLAGS) $(OS2_POPUP) $*.c
|
||||
|
||||
rem2ps.exe: rem2ps$O
|
||||
$(CC) $(LFLAGS) $(LBIND) -o $@ rem2ps$O $(LFLAGS2)
|
||||
|
||||
remind.exe: $(OBJS)
|
||||
$(CC) $(LFLAGS) -o $@ $(OBJS) $(LFLAGS2)
|
||||
$(BIND)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.obj *~ core *.bak
|
||||
|
||||
clobber:
|
||||
rm -f *.o *.obj *~ remind.exe rem2ps.exe test.out core *.bak
|
||||
|
||||
test:
|
||||
test-rem.cmd
|
||||
|
||||
rem2ps$O: rem2ps.c rem2ps.h lang.h config.h
|
||||
calendar$O: calendar.c $(STDHDRS) expr.h
|
||||
dorem$O: dorem.c $(STDHDRS) expr.h
|
||||
dosubst$O: dosubst.c $(STDHDRS) $(LANGHDRS)
|
||||
expr$O: expr.c $(STDHDRS) expr.h
|
||||
files$O: files.c $(STDHDRS)
|
||||
funcs$O: funcs.c $(STDHDRS) expr.h version.h
|
||||
globals$O: globals.c config.h types.h globals.h err.h lang.h $(LANGHDRS)
|
||||
hbcal$O: hbcal.c $(STDHDRS)
|
||||
init$O: init.c $(STDHDRS) expr.h version.h $(LANGHDRS)
|
||||
main$O: main.c $(STDHDRS) expr.h
|
||||
moon$O: moon.c $(STDHDRS)
|
||||
omit$O: omit.c $(STDHDRS)
|
||||
sort$O: sort.c $(STDHDRS)
|
||||
queue$O: queue.c $(STDHDRS)
|
||||
token$O: token.c $(STDHDRS)
|
||||
trigger$O: trigger.c $(STDHDRS) expr.h
|
||||
userfns$O: userfns.c $(STDHDRS) expr.h
|
||||
utils$O: utils.c $(STDHDRS)
|
||||
var$O: var.c $(STDHDRS) expr.h
|
||||
@@ -1,67 +0,0 @@
|
||||
# Makefile for REMIND for Turbo C for MSDOS
|
||||
# $Id: makefile.tc,v 1.1 2000-03-15 16:03:57 dfs Exp $
|
||||
|
||||
CC= tcc
|
||||
|
||||
HDRS= config.h err.h expr.h globals.h protos.h types.h version.h \
|
||||
lang.h english.h german.h dutch.h finnish.h french.h norwgian.h \
|
||||
danish.h polish.h
|
||||
|
||||
STDHDRS= config.h types.h protos.h globals.h err.h lang.h
|
||||
|
||||
LANGHDRS= english.h german.h dutch.h finnish.h french.h norwgian.h danish.h \
|
||||
polish.h
|
||||
|
||||
SRCS= calendar.c dorem.c dosubst.c expr.c files.c funcs.c globals.c init.c \
|
||||
moon.c main.c omit.c sort.c token.c trigger.c userfns.c utils.c var.c hbcal.c
|
||||
|
||||
OBJS=calendar.obj dorem.obj dosubst.obj expr.obj files.obj funcs.obj \
|
||||
globals.obj init.obj main.obj omit.obj sort.obj token.obj trigger.obj \
|
||||
utils.obj userfns.obj var.obj hbcal.obj
|
||||
|
||||
all: remind.exe rem2ps.exe
|
||||
|
||||
remind.exe: $(OBJS)
|
||||
$(CC) @lnk.tc
|
||||
|
||||
rem2ps.exe: rem2ps.obj
|
||||
$(CC) -erem2ps.exe rem2ps.obj
|
||||
|
||||
.c.obj:
|
||||
$(CC) -w-pia -c -O -mm {$< }
|
||||
|
||||
rem2ps.obj: rem2ps.c rem2ps.h config.h lang.h
|
||||
|
||||
calendar.obj: calendar.c $(STDHDRS) expr.h
|
||||
|
||||
dorem.obj: dorem.c $(STDHDRS) expr.h
|
||||
|
||||
dosubst.obj: dosubst.c $(STDHDRS) $(LANGHDRS)
|
||||
|
||||
expr.obj: expr.c $(STDHDRS) expr.h
|
||||
|
||||
files.obj: files.c $(STDHDRS)
|
||||
|
||||
funcs.obj: funcs.c $(STDHDRS) expr.h version.h
|
||||
|
||||
globals.obj: globals.c config.h types.h globals.h err.h lang.h
|
||||
|
||||
init.obj: init.c $(STDHDRS) expr.h version.h
|
||||
|
||||
main.obj: main.c $(STDHDRS) expr.h
|
||||
|
||||
moon.obj: moon.c $(STDHDRS) expr.h
|
||||
|
||||
omit.obj: omit.c $(STDHDRS)
|
||||
|
||||
sort.obj: sort.c $(STDHDRS)
|
||||
|
||||
token.obj: token.c $(STDHDRS)
|
||||
|
||||
trigger.obj: trigger.c $(STDHDRS) expr.h
|
||||
|
||||
userfns.obj: userfns.c $(STDHDRS) expr.h
|
||||
|
||||
utils.obj: utils.c $(STDHDRS)
|
||||
|
||||
var.obj: var.c $(STDHDRS) expr.h
|
||||
@@ -1,159 +0,0 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* OS2FUNC.C */
|
||||
/* */
|
||||
/* Functions to support OS/2. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* This file is Copyright (C) 1993 by Russ Herman. */
|
||||
/* REMIND is Copyright (C) 1992-1998 by David F. Skoll */
|
||||
/* Copyright (C) 1999-2000 by Roaring Penguin Software Inc. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: os2func.c,v 1.1 2000-03-15 16:03:57 dfs Exp $";
|
||||
|
||||
#ifdef OS2_POPUP
|
||||
#define INCL_VIO
|
||||
#define INCL_KBD
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define INCL_DOSPROCESS
|
||||
#endif
|
||||
|
||||
#if defined(OS2_POPUP) || defined(_MSC_VER)
|
||||
#include <os2.h>
|
||||
#endif
|
||||
|
||||
#ifdef OS2_POPUP
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef OS2DBG
|
||||
#include <dos.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include "globals.h"
|
||||
|
||||
/* EMX defines PS_TYPE, so we undefine it here to avoid
|
||||
a redefinition warning when we include "types.h" */
|
||||
#ifdef PS_TYPE
|
||||
#undef PS_TYPE
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef USHORT APIRET;
|
||||
#endif
|
||||
|
||||
static APIRET apiret = 0;
|
||||
static KBDKEYINFO kbci;
|
||||
static char *pszPressAny = "\r\nPress any key to continue";
|
||||
static USHORT pflags = VP_WAIT; /* | VP_TRANSPARENT; */
|
||||
static HKBD hkbd = 0;
|
||||
static char VioSubstBuffer[SHELLSIZE + 1];
|
||||
|
||||
void StartPopUp()
|
||||
{
|
||||
if (OS2MODE)
|
||||
if (!(DebugFlag & DB_ECHO_LINE))
|
||||
VioPopUp(&pflags, 0);
|
||||
}
|
||||
|
||||
void EndPopUp()
|
||||
{
|
||||
if (DebugFlag & DB_ECHO_LINE)
|
||||
return;
|
||||
if (OS2MODE) {
|
||||
VioWrtTTY(pszPressAny, strlen(pszPressAny), 0);
|
||||
KbdCharIn(&kbci, IO_WAIT, hkbd);
|
||||
VioEndPopUp(0);
|
||||
}
|
||||
}
|
||||
|
||||
int PutsPopUp(char *s)
|
||||
{
|
||||
char c, *os = VioSubstBuffer;
|
||||
|
||||
if (DebugFlag & DB_ECHO_LINE)
|
||||
printf("%s", s);
|
||||
else {
|
||||
do {
|
||||
/* Convert \n to \r\n in auxiliary buffer for VIO */
|
||||
if ((c= *s++) == '\n')
|
||||
*os++ = '\r';
|
||||
*os++ = c;
|
||||
} while (c > 0);
|
||||
VioWrtTTY(VioSubstBuffer, strlen(VioSubstBuffer), 0);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int PutlPopUp(char *s)
|
||||
{
|
||||
StartPopUp();
|
||||
PutsPopUp(s);
|
||||
if (DebugFlag & DB_ECHO_LINE)
|
||||
fputc('\n', stdout);
|
||||
else
|
||||
VioWrtTTY("\r\n", 2, 0);
|
||||
EndPopUp();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int PutcPopUp(int c)
|
||||
{
|
||||
char *s = " ";
|
||||
|
||||
if (DebugFlag & DB_ECHO_LINE)
|
||||
fputc(c, stdout);
|
||||
else {
|
||||
switch (c) {
|
||||
case '\n':
|
||||
VioWrtTTY("\r\n", 2, 0);
|
||||
break;
|
||||
default:
|
||||
s[0] = c;
|
||||
VioWrtTTY(s, 1, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef OS2DBG
|
||||
#define DB_ECHO_LINE 16
|
||||
int DebugFlag = 0;
|
||||
void main(/* int argc, char **argv */)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = os2fputs("Test VIO PopUp Writing");
|
||||
if (ret)
|
||||
fprintf(stderr, "Test VIO PopUP Writing returned %d %ld",
|
||||
ret, apiret);
|
||||
exit(ret);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
unsigned sleep(unsigned sec)
|
||||
{
|
||||
return DosSleep(sec * 1000L);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __EMX__
|
||||
int fork()
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
NAME WINDOWCOMPAT NEWFILES
|
||||
@@ -1,94 +0,0 @@
|
||||
# $Id: smakefile,v 1.1 2000-03-15 16:03:57 dfs Exp $
|
||||
# Makefile for REMIND, suitable for SAS/C 6.50 under AmigaDOS
|
||||
# English version
|
||||
# THIS IS OUT OF DATE!
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# THINGS FOR YOU TO EDIT START BELOW
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# Uncomment the next line if you are running on a SYSV system
|
||||
# SYSV= -DSYSV
|
||||
|
||||
# Uncomment the next line if you are running under UNIX (including SYSV!)
|
||||
#UNIX= -DUNIX
|
||||
|
||||
# Uncomment the next lines if you want to use gcc instead of default compiler
|
||||
# NOTE: Tempting as it may be, if you use 'cc' for the C compiler, do not
|
||||
# use 'ld' for the linker. It will probably work much better if you use
|
||||
# LD= cc rather than LD= ld.
|
||||
CC= SC
|
||||
LD= SC
|
||||
|
||||
# Put any additional flags for the C compiler or linker here - if you
|
||||
# are not using gcc, you probably want to remove '-ansi'.
|
||||
CFLAGS= OPT NOSTKCHK NOSINT MATH=IEEE
|
||||
CDEFS=
|
||||
LDFLAGS= LINK
|
||||
|
||||
HDRS= config.h err.h expr.h globals.h protos.h types.h version.h \
|
||||
lang.h english.h german.h dutch.h finnish.h french.h norwgian.h
|
||||
|
||||
STDHDRS= config.h types.h protos.h globals.h err.h lang.h
|
||||
|
||||
LANGHDRS= english.h german.h dutch.h finnish.h french.h norwgian.h
|
||||
|
||||
SRCS= calendar.c dorem.c dosubst.c expr.c files.c funcs.c globals.c hbcal.c \
|
||||
init.c main.c moon.c omit.c sort.c queue.c token.c trigger.c userfns.c \
|
||||
utils.c var.c amiga.c
|
||||
|
||||
OBJS= calendar.o dorem.o dosubst.o expr.o files.o funcs.o globals.o hbcal.o \
|
||||
init.o main.o moon.o omit.o sort.o queue.o token.o trigger.o userfns.o \
|
||||
utils.o var.o amiga.o
|
||||
|
||||
MANIFEST= README.UNIX README.DOS COPYRIGHT $(HDRS) $(SRCS) Makefile rem rem.1 \
|
||||
remind.1 remind-all.csh remind-all.sh test.rem test-rem test.cmp makefile.tc \
|
||||
makefile.msc lnk.msc lnk.tc MANIFEST.UNX MANIFEST.DOS WHATSNEW.30 kall kall.1 \
|
||||
defs.rem README.OS2 makefile.os2 rem2ps.c rem2ps.h remind.def rem2ps.1 \
|
||||
tstlang.rem README.BCC lnk.bcc makefile.bcc os2func.c \
|
||||
test-rem.bat test-rem.cmd test1.cmp test2.cmp
|
||||
|
||||
|
||||
all: remind rem2ps
|
||||
|
||||
.c.o:
|
||||
$(CC) $(UNIX) $(SYSV) $(CFLAGS) $(CDEFS) $*.c
|
||||
|
||||
rem2ps: rem2ps.o
|
||||
$(LD) MATH=IEEE $(LDFLAGS) PNAME=rem2ps rem2ps.o
|
||||
|
||||
remind: $(OBJS)
|
||||
$(LD) MATH=IEEE $(LDFLAGS) PNAME=remind $(OBJS)
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ core *.bak
|
||||
|
||||
clobber:
|
||||
rm -f *.o *~ remind rem2ps test.out core *.bak
|
||||
|
||||
test: remind
|
||||
sh test-rem
|
||||
|
||||
rem2ps.o: rem2ps.c rem2ps.h lang.h config.h
|
||||
calendar.o: calendar.c $(STDHDRS) expr.h
|
||||
dorem.o: dorem.c $(STDHDRS) expr.h
|
||||
dosubst.o: dosubst.c $(STDHDRS) $(LANGHDRS)
|
||||
expr.o: expr.c $(STDHDRS) expr.h
|
||||
files.o: files.c $(STDHDRS)
|
||||
funcs.o: funcs.c $(STDHDRS) expr.h version.h
|
||||
globals.o: globals.c config.h types.h globals.h err.h lang.h $(LANGHDRS)
|
||||
hbcal.o: hbcal.c $(STDHDRS)
|
||||
init.o: init.c $(STDHDRS) expr.h version.h lang.h $(LANGHDRS)
|
||||
main.o: main.c $(STDHDRS) expr.h
|
||||
moon.o: moon.c $(STDHDRS)
|
||||
omit.o: omit.c $(STDHDRS)
|
||||
sort.o: sort.c $(STDHDRS)
|
||||
queue.o: queue.c $(STDHDRS)
|
||||
token.o: token.c $(STDHDRS)
|
||||
trigger.o: trigger.c $(STDHDRS) expr.h
|
||||
userfns.o: userfns.c $(STDHDRS) expr.h
|
||||
utils.o: utils.c $(STDHDRS)
|
||||
var.o: var.c $(STDHDRS) expr.h
|
||||
|
||||
amiga.o: amiga.c
|
||||
$(CC) OBJNAME=amiga.o $(CFLAGS) amiga.c
|
||||
984
src/calendar.c
984
src/calendar.c
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,6 @@
|
||||
/* src/config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* $Id: config.h.in,v 1.5 2005-09-30 03:29:32 dfs Exp $ */
|
||||
|
||||
/* Define if utime(file, NULL) sets file's timestamp to the present. */
|
||||
#undef HAVE_UTIME_NULL
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
||||
@@ -17,4 +10,30 @@
|
||||
/* Define if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
|
||||
/* Define if you have the <glob.h> header file */
|
||||
#undef HAVE_GLOB_H
|
||||
|
||||
#undef HAVE_WCTYPE_H
|
||||
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
#undef HAVE_GLOB
|
||||
|
||||
#undef HAVE_SETENV
|
||||
|
||||
#undef HAVE_UNSETENV
|
||||
|
||||
#undef HAVE_MBSTOWCS
|
||||
|
||||
#undef HAVE_SETLOCALE
|
||||
|
||||
/* The number of bytes in a unsigned int. */
|
||||
#undef SIZEOF_UNSIGNED_INT
|
||||
|
||||
/* The number of bytes in a unsigned long. */
|
||||
#undef SIZEOF_UNSIGNED_LONG
|
||||
|
||||
/* The number of bytes in a unsigned short. */
|
||||
#undef SIZEOF_UNSIGNED_SHORT
|
||||
|
||||
#include "custom.h"
|
||||
|
||||
48
src/custom.h
48
src/custom.h
@@ -11,8 +11,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: custom.h,v 1.34 2005-10-16 14:48:02 dfs Exp $ */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* LAT_DEG, LAT_MIN and LAT_SEC: Latitude of your location */
|
||||
/* LON_DEG, LON_MIN and LON_SEC: Longitude of your location */
|
||||
@@ -41,11 +39,11 @@
|
||||
/* #define DEFAULT_PAGE {"A4", 595, 842} */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* DATESEP: The default date separator. North American usage is '/'; */
|
||||
/* others may prefer '-'. */
|
||||
/* DATESEP: The default date separator. Standard usage is '-'; */
|
||||
/* others may prefer '/'. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define DATESEP '/'
|
||||
/* #define DATESEP '-' */
|
||||
#define DATESEP '-'
|
||||
/* #define DATESEP '/' */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* TIMESEP: The default time separator. North American usage is ':'; */
|
||||
@@ -89,8 +87,7 @@
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* WANT_U_OPTION: Comment out the next define to permanently disable */
|
||||
/* the -u option. If you do this, however, remind-all.[c]sh will not */
|
||||
/* work. */
|
||||
/* the -u option. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define WANT_U_OPTION 1
|
||||
|
||||
@@ -134,19 +131,16 @@
|
||||
#define BASE 1990
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* YR_RANGE: The range of years allowed. Computers with 16-bit */
|
||||
/* integers can handle about 89 years worth of reminders; if */
|
||||
/* you use 32-bit integers, you can handle over 5 867 000 */
|
||||
/* years. Note that YR_RANGE is set to 88 rather than 89 */
|
||||
/* because we can range up to the last day of the 88th year. */
|
||||
/* YR_RANGE: The range of years allowed. With 32-bit signed integers, */
|
||||
/* the DATETIME type can store 2^31 minutes or about 4074 years. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define YR_RANGE 88
|
||||
#define YR_RANGE 4000
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* VAR_NAME_LEN: The maximum length of variable names. Don't make it */
|
||||
/* any less than 12. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define VAR_NAME_LEN 12
|
||||
#define VAR_NAME_LEN 16
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* MAX_PRT_LEN: The maximum number of characters to print when */
|
||||
@@ -154,6 +148,12 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_PRT_LEN 40
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* MAX_STR_LEN: If non-zero, Remind will limit the maximum length */
|
||||
/* of string values to avoid eating up all of memory... */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_STR_LEN 65535
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* OP_STACK_SIZE: The size of the operator stack for expr. parsing */
|
||||
/*---------------------------------------------------------------------*/
|
||||
@@ -167,7 +167,7 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define INCLUDE_NEST 8
|
||||
#define INCLUDE_NEST 9
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* IF_NEST: How many nested IFs do we handle? Maximum is the number */
|
||||
@@ -178,17 +178,17 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many attempts to resolve a weird date spec? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define TRIG_ATTEMPTS 25
|
||||
#define TRIG_ATTEMPTS 50
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form YYYY MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_FULL_OMITS 75
|
||||
#define MAX_FULL_OMITS 500
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_PARTIAL_OMITS 75
|
||||
#define MAX_PARTIAL_OMITS 366
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* A newline - some systems need "\n\r" */
|
||||
@@ -207,9 +207,9 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* TAG_LEN: The maximum length of tags. Don't change it */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define TAG_LEN 32
|
||||
#define TAG_LEN 48
|
||||
|
||||
#define PASSTHRU_LEN 24
|
||||
#define PASSTHRU_LEN 32
|
||||
|
||||
#define PSBEGIN "# rem2ps begin"
|
||||
#define PSEND "# rem2ps end"
|
||||
@@ -221,3 +221,9 @@
|
||||
#define Putc putc
|
||||
#define PutChar putchar
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H)
|
||||
#define REM_USE_WCHAR 1
|
||||
#else
|
||||
#undef REM_USE_WCHAR
|
||||
#endif
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: custom.h.in,v 1.8 2005-09-30 03:29:32 dfs Exp $ */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* LAT_DEG, LAT_MIN and LAT_SEC: Latitude of your location */
|
||||
/* LON_DEG, LON_MIN and LON_SEC: Longitude of your location */
|
||||
@@ -41,11 +39,11 @@
|
||||
/* #define DEFAULT_PAGE {"A4", 595, 842} */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* DATESEP: The default date separator. North American usage is '/'; */
|
||||
/* others may prefer '-'. */
|
||||
/* DATESEP: The default date separator. Standard usage is '-'; */
|
||||
/* others may prefer '/'. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define DATESEP '/'
|
||||
/* #define DATESEP '-' */
|
||||
#define DATESEP '-'
|
||||
/* #define DATESEP '/' */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* TIMESEP: The default time separator. North American usage is ':'; */
|
||||
@@ -89,8 +87,7 @@
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* WANT_U_OPTION: Comment out the next define to permanently disable */
|
||||
/* the -u option. If you do this, however, remind-all.[c]sh will not */
|
||||
/* work. */
|
||||
/* the -u option. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define WANT_U_OPTION 1
|
||||
|
||||
@@ -134,19 +131,16 @@
|
||||
#define BASE 1990
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* YR_RANGE: The range of years allowed. Computers with 16-bit */
|
||||
/* integers can handle about 89 years worth of reminders; if */
|
||||
/* you use 32-bit integers, you can handle over 5 867 000 */
|
||||
/* years. Note that YR_RANGE is set to 88 rather than 89 */
|
||||
/* because we can range up to the last day of the 88th year. */
|
||||
/* YR_RANGE: The range of years allowed. With 32-bit signed integers, */
|
||||
/* the DATETIME type can store 2^31 minutes or about 4074 years. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define YR_RANGE 88
|
||||
#define YR_RANGE 4000
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* VAR_NAME_LEN: The maximum length of variable names. Don't make it */
|
||||
/* any less than 12. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define VAR_NAME_LEN 12
|
||||
#define VAR_NAME_LEN 16
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* MAX_PRT_LEN: The maximum number of characters to print when */
|
||||
@@ -154,6 +148,12 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_PRT_LEN 40
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* MAX_STR_LEN: If non-zero, Remind will limit the maximum length */
|
||||
/* of string values to avoid eating up all of memory... */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_STR_LEN 65535
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* OP_STACK_SIZE: The size of the operator stack for expr. parsing */
|
||||
/*---------------------------------------------------------------------*/
|
||||
@@ -167,7 +167,7 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define INCLUDE_NEST 8
|
||||
#define INCLUDE_NEST 9
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* IF_NEST: How many nested IFs do we handle? Maximum is the number */
|
||||
@@ -178,17 +178,17 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many attempts to resolve a weird date spec? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define TRIG_ATTEMPTS 25
|
||||
#define TRIG_ATTEMPTS 50
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form YYYY MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_FULL_OMITS 75
|
||||
#define MAX_FULL_OMITS 500
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_PARTIAL_OMITS 75
|
||||
#define MAX_PARTIAL_OMITS 366
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* A newline - some systems need "\n\r" */
|
||||
@@ -207,9 +207,9 @@
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* TAG_LEN: The maximum length of tags. Don't change it */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define TAG_LEN 32
|
||||
#define TAG_LEN 48
|
||||
|
||||
#define PASSTHRU_LEN 24
|
||||
#define PASSTHRU_LEN 32
|
||||
|
||||
#define PSBEGIN "# rem2ps begin"
|
||||
#define PSEND "# rem2ps end"
|
||||
@@ -221,3 +221,9 @@
|
||||
#define Putc putc
|
||||
#define PutChar putchar
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H)
|
||||
#define REM_USE_WCHAR 1
|
||||
#else
|
||||
#undef REM_USE_WCHAR
|
||||
#endif
|
||||
|
||||
440
src/dorem.c
440
src/dorem.c
@@ -13,8 +13,6 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: dorem.c,v 1.14 2005-11-20 01:26:59 dfs Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
@@ -31,12 +29,12 @@ static char const RCSID[] = "$Id: dorem.c,v 1.14 2005-11-20 01:26:59 dfs Exp $";
|
||||
static char const DontEscapeMe[] =
|
||||
"1234567890_-=+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@.,";
|
||||
|
||||
static int ParseTimeTrig (ParsePtr s, TimeTrig *tim);
|
||||
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);
|
||||
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 ShouldTriggerBasedOnWarn (Trigger *t, int jul);
|
||||
static int ShouldTriggerBasedOnWarn (Trigger *t, int jul, int *err);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -50,7 +48,7 @@ int DoRem(ParsePtr p)
|
||||
|
||||
Trigger trig;
|
||||
TimeTrig tim;
|
||||
int r;
|
||||
int r, err;
|
||||
int jul;
|
||||
DynamicBuffer buf;
|
||||
Token tok;
|
||||
@@ -58,28 +56,54 @@ int DoRem(ParsePtr p)
|
||||
DBufInit(&buf);
|
||||
|
||||
/* Parse the trigger date and time */
|
||||
if ( (r=ParseRem(p, &trig, &tim)) ) return r;
|
||||
if ( (r=ParseRem(p, &trig, &tim, 1)) ) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (trig.typ == NO_TYPE) return E_EOLN;
|
||||
if (trig.typ == NO_TYPE) {
|
||||
PurgeEchoLine("%s\n%s\n", "#!P! Cannot parse next line", CurLine);
|
||||
FreeTrig(&trig);
|
||||
return E_EOLN;
|
||||
}
|
||||
if (trig.typ == SAT_TYPE) {
|
||||
PurgeEchoLine("%s\n", "#!P: Cannot purge SATISFY-type reminders");
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
r=DoSatRemind(&trig, &tim, p);
|
||||
if (r) return r;
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
if (r == E_EXPIRED) return OK;
|
||||
return r;
|
||||
}
|
||||
if (!LastTrigValid) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
r=ParseToken(p, &buf);
|
||||
if (r) return r;
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
DBufFree(&buf);
|
||||
if (tok.type == T_Empty || tok.type == T_Comment) {
|
||||
DBufFree(&buf);
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
if (tok.type != T_RemType || tok.val == SAT_TYPE) {
|
||||
DBufFree(&buf);
|
||||
FreeTrig(&trig);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
if (tok.val == PASSTHRU_TYPE) {
|
||||
r=ParseToken(p, &buf);
|
||||
if (r) return r;
|
||||
if (r) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
if (!DBufLen(&buf)) {
|
||||
FreeTrig(&trig);
|
||||
DBufFree(&buf);
|
||||
return E_EOLN;
|
||||
}
|
||||
@@ -88,13 +112,42 @@ int DoRem(ParsePtr p)
|
||||
}
|
||||
trig.typ = tok.val;
|
||||
jul = LastTriggerDate;
|
||||
if (!LastTrigValid) return OK;
|
||||
if (!LastTrigValid || PurgeMode) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
} else {
|
||||
/* Calculate the trigger date */
|
||||
jul = ComputeTrigger(trig.scanfrom, &trig, &r);
|
||||
if (r) return r;
|
||||
jul = ComputeTrigger(trig.scanfrom, &trig, &r, 1);
|
||||
if (r) {
|
||||
if (PurgeMode) {
|
||||
PurgeEchoLine("%s: %s\n", "#!P! Problem calculating trigger date", ErrMsg[r]);
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (PurgeMode) {
|
||||
if (trig.expired || jul < JulianToday) {
|
||||
if (p->expr_happened) {
|
||||
if (p->nonconst_expr) {
|
||||
PurgeEchoLine("%s\n", "#!P: Next line may have expired, but contains non-constant expression");
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
} else {
|
||||
PurgeEchoLine("%s\n", "#!P: Next line has expired, but contains expression... please verify");
|
||||
PurgeEchoLine("#!P: Expired: %s\n", CurLine);
|
||||
}
|
||||
} else {
|
||||
PurgeEchoLine("#!P: Expired: %s\n", CurLine);
|
||||
}
|
||||
} else {
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
/* Queue the reminder, if necessary */
|
||||
if (jul == JulianToday &&
|
||||
!(!IgnoreOnce &&
|
||||
@@ -102,17 +155,21 @@ int DoRem(ParsePtr p)
|
||||
FileAccessDate == JulianToday))
|
||||
QueueReminder(p, &trig, &tim, trig.sched);
|
||||
/* If we're in daemon mode, do nothing over here */
|
||||
if (Daemon) return OK;
|
||||
|
||||
if (ShouldTriggerReminder(&trig, &tim, jul)) {
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, jul)) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
if (Daemon) {
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, jul)) ) {
|
||||
FreeTrig(&trig);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
FreeTrig(&trig);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -122,11 +179,12 @@ int DoRem(ParsePtr p)
|
||||
/* trigger structure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals)
|
||||
{
|
||||
register int r;
|
||||
DynamicBuffer buf;
|
||||
Token tok;
|
||||
int y, m, d;
|
||||
|
||||
DBufInit(&buf);
|
||||
|
||||
@@ -146,11 +204,16 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
trig->priority = DefaultPrio;
|
||||
trig->sched[0] = 0;
|
||||
trig->warn[0] = 0;
|
||||
trig->tag[0] = 0;
|
||||
trig->omitfunc[0] = 0;
|
||||
DBufInit(&(trig->tags));
|
||||
trig->passthru[0] = 0;
|
||||
tim->ttime = NO_TIME;
|
||||
tim->delta = NO_DELTA;
|
||||
tim->rep = NO_REP;
|
||||
tim->duration = NO_TIME;
|
||||
if (save_in_globals) {
|
||||
LastTriggerTime = NO_TIME;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
/* Read space-delimited string */
|
||||
@@ -160,6 +223,32 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
/* Figure out what we've got */
|
||||
FindToken(DBufValue(&buf), &tok);
|
||||
switch(tok.type) {
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (trig->d != NO_DAY) return E_DAY_TWICE;
|
||||
if (trig->m != NO_MON) return E_MON_TWICE;
|
||||
if (trig->y != NO_YR) return E_YR_TWICE;
|
||||
FromJulian(tok.val, &y, &m, &d);
|
||||
trig->y = y;
|
||||
trig->m = m;
|
||||
trig->d = d;
|
||||
break;
|
||||
|
||||
case T_DateTime:
|
||||
DBufFree(&buf);
|
||||
if (trig->d != NO_DAY) return E_DAY_TWICE;
|
||||
if (trig->m != NO_MON) return E_MON_TWICE;
|
||||
if (trig->y != NO_YR) return E_YR_TWICE;
|
||||
FromJulian(tok.val / MINUTES_PER_DAY, &y, &m, &d);
|
||||
trig->y = y;
|
||||
trig->m = m;
|
||||
trig->d = d;
|
||||
tim->ttime = (tok.val % MINUTES_PER_DAY);
|
||||
if (save_in_globals) {
|
||||
LastTriggerTime = tim->ttime;
|
||||
}
|
||||
break;
|
||||
|
||||
case T_WkDay:
|
||||
DBufFree(&buf);
|
||||
if (trig->wd & (1 << tok.val)) return E_WD_TWICE;
|
||||
@@ -186,13 +275,13 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
|
||||
case T_At:
|
||||
DBufFree(&buf);
|
||||
r=ParseTimeTrig(s, tim);
|
||||
r=ParseTimeTrig(s, tim, save_in_globals);
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
case T_Scanfrom:
|
||||
DBufFree(&buf);
|
||||
r=ParseScanFrom(s, trig);
|
||||
r=ParseScanFrom(s, trig, tok.val);
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
@@ -212,6 +301,14 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
}
|
||||
return OK;
|
||||
|
||||
case T_Through:
|
||||
DBufFree(&buf);
|
||||
if (trig->rep != NO_REP) return E_REP_TWICE;
|
||||
trig->rep = 1;
|
||||
r = ParseUntil(s, trig);
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
case T_Until:
|
||||
DBufFree(&buf);
|
||||
r=ParseUntil(s, trig);
|
||||
@@ -256,6 +353,10 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
|
||||
case T_Omit:
|
||||
DBufFree(&buf);
|
||||
if (trig->omitfunc[0]) {
|
||||
Eprint("Warning: OMIT is ignored if you use OMITFUNC");
|
||||
}
|
||||
|
||||
r = ParseLocalOmit(s, trig);
|
||||
if (r) return r;
|
||||
break;
|
||||
@@ -265,6 +366,16 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
|
||||
return OK;
|
||||
|
||||
case T_OmitFunc:
|
||||
if (trig->localomit) {
|
||||
Eprint("Warning: OMIT is ignored if you use OMITFUNC");
|
||||
}
|
||||
r=ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
StrnCpy(trig->omitfunc, DBufValue(&buf), VAR_NAME_LEN);
|
||||
DBufFree(&buf);
|
||||
break;
|
||||
|
||||
case T_Warn:
|
||||
r=ParseToken(s, &buf);
|
||||
if(r) return r;
|
||||
@@ -275,7 +386,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
case T_Tag:
|
||||
r = ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
StrnCpy(trig->tag, DBufValue(&buf), TAG_LEN);
|
||||
AppendTag(&(trig->tags), DBufValue(&buf));
|
||||
break;
|
||||
|
||||
case T_Duration:
|
||||
@@ -321,7 +432,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
/* ParseTimeTrig - parse the AT part of a timed reminder */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int ParseTimeTrig(ParsePtr s, TimeTrig *tim)
|
||||
static int ParseTimeTrig(ParsePtr s, TimeTrig *tim, int save_in_globals)
|
||||
{
|
||||
Token tok;
|
||||
int r;
|
||||
@@ -353,7 +464,9 @@ static int ParseTimeTrig(ParsePtr s, TimeTrig *tim)
|
||||
if (tim->ttime == NO_TIME) return E_EXPECT_TIME;
|
||||
|
||||
/* Save trigger time in global variable */
|
||||
LastTriggerTime = tim->ttime;
|
||||
if (save_in_globals) {
|
||||
LastTriggerTime = tim->ttime;
|
||||
}
|
||||
PushToken(DBufValue(&buf), s);
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
@@ -442,6 +555,23 @@ static int ParseUntil(ParsePtr s, Trigger *t)
|
||||
d = tok.val;
|
||||
break;
|
||||
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_YR_TWICE]);
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
if (m != NO_MON) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_MON_TWICE]);
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
if (d != NO_DAY) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_DAY_TWICE]);
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
FromJulian(tok.val, &y, &m, &d);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_INCOMPLETE]);
|
||||
@@ -462,10 +592,10 @@ static int ParseUntil(ParsePtr s, Trigger *t)
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseScanFrom - parse the SCANFROM portion of a reminder */
|
||||
/* ParseScanFrom - parse the FROM/SCANFROM portion */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
{
|
||||
int y = NO_YR,
|
||||
m = NO_MON,
|
||||
@@ -474,7 +604,14 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
Token tok;
|
||||
int r;
|
||||
DynamicBuffer buf;
|
||||
char const *word;
|
||||
|
||||
DBufInit(&buf);
|
||||
if (type == SCANFROM_TYPE) {
|
||||
word = "SCANFROM";
|
||||
} else {
|
||||
word = "FROM";
|
||||
}
|
||||
|
||||
if (t->scanfrom != NO_DATE) return E_SCAN_TWICE;
|
||||
|
||||
@@ -486,7 +623,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("SCANFROM: %s", ErrMsg[E_YR_TWICE]);
|
||||
Eprint("%s: %s", word, ErrMsg[E_YR_TWICE]);
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
y = tok.val;
|
||||
@@ -495,7 +632,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
case T_Month:
|
||||
DBufFree(&buf);
|
||||
if (m != NO_MON) {
|
||||
Eprint("SCANFROM: %s", ErrMsg[E_MON_TWICE]);
|
||||
Eprint("%s: %s", word, ErrMsg[E_MON_TWICE]);
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
m = tok.val;
|
||||
@@ -504,15 +641,32 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
case T_Day:
|
||||
DBufFree(&buf);
|
||||
if (d != NO_DAY) {
|
||||
Eprint("SCANFROM: %s", ErrMsg[E_DAY_TWICE]);
|
||||
Eprint("%s: %s", word, ErrMsg[E_DAY_TWICE]);
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
d = tok.val;
|
||||
break;
|
||||
|
||||
case T_Date:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_YR_TWICE]);
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
if (m != NO_MON) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_MON_TWICE]);
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
if (d != NO_DAY) {
|
||||
Eprint("%s: %s", word, ErrMsg[E_DAY_TWICE]);
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
FromJulian(tok.val, &y, &m, &d);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
|
||||
Eprint("SCANFROM: %s", ErrMsg[E_INCOMPLETE]);
|
||||
Eprint("%s: %s", word, ErrMsg[E_INCOMPLETE]);
|
||||
DBufFree(&buf);
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
@@ -521,6 +675,12 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
return E_BAD_DATE;
|
||||
}
|
||||
t->scanfrom = Julian(y, m, d);
|
||||
if (type == FROM_TYPE) {
|
||||
if (t->scanfrom < JulianToday) {
|
||||
t->scanfrom = JulianToday;
|
||||
}
|
||||
}
|
||||
|
||||
PushToken(DBufValue(&buf), s);
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
@@ -534,23 +694,52 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
/* Trigger the reminder if it's a RUN or MSG type. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
{
|
||||
int r, y, m, d;
|
||||
char PrioExpr[25];
|
||||
char PrioExpr[VAR_NAME_LEN+25];
|
||||
char tmpBuf[64];
|
||||
DynamicBuffer buf, calRow;
|
||||
char *s;
|
||||
DynamicBuffer pre_buf;
|
||||
char const *s;
|
||||
Value v;
|
||||
|
||||
DBufInit(&buf);
|
||||
DBufInit(&calRow);
|
||||
DBufInit(&pre_buf);
|
||||
if (t->typ == RUN_TYPE && RunDisabled) return E_RUN_DISABLED;
|
||||
if (t->typ == PASSTHRU_TYPE ||
|
||||
if ((t->typ == PASSTHRU_TYPE && strcmp(t->passthru, "COLOR") && strcmp(t->passthru, "COLOUR")) ||
|
||||
t->typ == CAL_TYPE ||
|
||||
t->typ == PS_TYPE ||
|
||||
t->typ == PSF_TYPE)
|
||||
return OK;
|
||||
|
||||
/* Handle COLOR types */
|
||||
if (t->typ == PASSTHRU_TYPE && (!strcmp(t->passthru, "COLOR") || !strcmp(t->passthru, "COLOUR"))) {
|
||||
/* Strip off three tokens */
|
||||
r = ParseToken(p, &buf);
|
||||
if (!NextMode) {
|
||||
DBufPuts(&pre_buf, DBufValue(&buf));
|
||||
DBufPutc(&pre_buf, ' ');
|
||||
}
|
||||
DBufFree(&buf);
|
||||
if (r) return r;
|
||||
r = ParseToken(p, &buf);
|
||||
if (!NextMode) {
|
||||
DBufPuts(&pre_buf, DBufValue(&buf));
|
||||
DBufPutc(&pre_buf, ' ');
|
||||
}
|
||||
DBufFree(&buf);
|
||||
if (r) return r;
|
||||
r = ParseToken(p, &buf);
|
||||
if (!NextMode) {
|
||||
DBufPuts(&pre_buf, DBufValue(&buf));
|
||||
DBufPutc(&pre_buf, ' ');
|
||||
}
|
||||
DBufFree(&buf);
|
||||
if (r) return r;
|
||||
t->typ = MSG_TYPE;
|
||||
}
|
||||
/* 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) {
|
||||
@@ -568,12 +757,14 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
if ( (r=DoSubst(p, &buf, t, tim, jul, CAL_MODE)) ) return r;
|
||||
if (!DBufLen(&buf)) {
|
||||
DBufFree(&buf);
|
||||
DBufFree(&pre_buf);
|
||||
return OK;
|
||||
}
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
sprintf(tmpBuf, "%04d%c%02d%c%02d ", y, DATESEP, m+1, DATESEP, d);
|
||||
sprintf(tmpBuf, "%04d/%02d/%02d ", y, m+1, d);
|
||||
if (DBufPuts(&calRow, tmpBuf) != OK) {
|
||||
DBufFree(&calRow);
|
||||
DBufFree(&pre_buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
/* If DoSimpleCalendar==1, output *all* simple calendar fields */
|
||||
@@ -581,17 +772,15 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
/* ignore passthru field when in NextMode */
|
||||
if (DBufPuts(&calRow, "* ") != OK) {
|
||||
DBufFree(&calRow);
|
||||
DBufFree(&pre_buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (t->tag[0]) {
|
||||
sprintf(tmpBuf, "%s ", t->tag);
|
||||
} else {
|
||||
sprintf(tmpBuf, "* ");
|
||||
}
|
||||
if (DBufPuts(&calRow, tmpBuf) != OK) {
|
||||
DBufFree(&calRow);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (*DBufValue(&(t->tags))) {
|
||||
DBufPuts(&calRow, DBufValue(&(t->tags)));
|
||||
DBufPutc(&calRow, ' ');
|
||||
} else {
|
||||
DBufPuts(&calRow, "* ");
|
||||
}
|
||||
if (tim->duration != NO_TIME) {
|
||||
sprintf(tmpBuf, "%d ", tim->duration);
|
||||
} else {
|
||||
@@ -599,6 +788,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
}
|
||||
if (DBufPuts(&calRow, tmpBuf) != OK) {
|
||||
DBufFree(&calRow);
|
||||
DBufFree(&pre_buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (tim->ttime != NO_TIME) {
|
||||
@@ -608,52 +798,63 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
}
|
||||
if (DBufPuts(&calRow, tmpBuf) != OK) {
|
||||
DBufFree(&calRow);
|
||||
DBufFree(&pre_buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
if (DBufPuts(&calRow, SimpleTime(tim->ttime)) != OK) {
|
||||
DBufFree(&calRow);
|
||||
DBufFree(&pre_buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
printf("%s%s\n", DBufValue(&calRow), DBufValue(&buf));
|
||||
printf("%s%s%s\n", DBufValue(&calRow), DBufValue(&pre_buf), DBufValue(&buf));
|
||||
DBufFree(&buf);
|
||||
DBufFree(&pre_buf);
|
||||
DBufFree(&calRow);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Put the substituted string into the substitution buffer */
|
||||
if (UserFuncExists("msgprefix") == 1) {
|
||||
sprintf(PrioExpr, "msgprefix(%d)", t->priority);
|
||||
s = PrioExpr;
|
||||
r = EvalExpr(&s, &v);
|
||||
if (!r) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
if (DBufPuts(&buf, v.v.str) != OK) {
|
||||
DBufFree(&buf);
|
||||
DestroyValue(v);
|
||||
return E_NO_MEM;
|
||||
/* Put the substituted string into the substitution buffer */
|
||||
|
||||
/* Don't use msgprefix() on RUN-type reminders */
|
||||
if (t->typ != RUN_TYPE) {
|
||||
if (UserFuncExists("msgprefix") == 1) {
|
||||
sprintf(PrioExpr, "msgprefix(%d)", t->priority);
|
||||
s = PrioExpr;
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
if (!r) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
if (DBufPuts(&buf, v.v.str) != OK) {
|
||||
DBufFree(&buf);
|
||||
DestroyValue(v);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
DestroyValue(v);
|
||||
}
|
||||
DestroyValue(v);
|
||||
}
|
||||
}
|
||||
|
||||
if ( (r=DoSubst(p, &buf, t, tim, jul, NORMAL_MODE)) ) return r;
|
||||
if (UserFuncExists("msgsuffix") == 1) {
|
||||
sprintf(PrioExpr, "msgsuffix(%d)", t->priority);
|
||||
s = PrioExpr;
|
||||
r = EvalExpr(&s, &v);
|
||||
if (!r) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
if (DBufPuts(&buf, v.v.str) != OK) {
|
||||
DBufFree(&buf);
|
||||
DestroyValue(v);
|
||||
return E_NO_MEM;
|
||||
if (t->typ != RUN_TYPE) {
|
||||
if (UserFuncExists("msgsuffix") == 1) {
|
||||
sprintf(PrioExpr, "msgsuffix(%d)", t->priority);
|
||||
s = PrioExpr;
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
if (!r) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
if (DBufPuts(&buf, v.v.str) != OK) {
|
||||
DBufFree(&buf);
|
||||
DestroyValue(v);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
DestroyValue(v);
|
||||
}
|
||||
DestroyValue(v);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!MsgCommand && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {
|
||||
if (DBufPutc(&buf, '\n') != OK) {
|
||||
DBufFree(&buf);
|
||||
@@ -675,6 +876,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
reminder now. */
|
||||
switch(t->typ) {
|
||||
case MSG_TYPE:
|
||||
case PASSTHRU_TYPE:
|
||||
if (MsgCommand) {
|
||||
DoMsgCommand(MsgCommand, DBufValue(&buf));
|
||||
} else {
|
||||
@@ -698,7 +900,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
DBufFree(&buf);
|
||||
NumTriggered++;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -706,12 +908,13 @@ static int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
/* */
|
||||
/* Return 1 if we should trigger a reminder, based on today's */
|
||||
/* date and the trigger. Return 0 if reminder should not be */
|
||||
/* triggered. */
|
||||
/* triggered. Sets *err non-zero in event of an error. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul)
|
||||
int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul, int *err)
|
||||
{
|
||||
int r;
|
||||
int r, omit;
|
||||
*err = 0;
|
||||
|
||||
/* Handle the ONCE modifier in the reminder. */
|
||||
if (!IgnoreOnce && t->once !=NO_ONCE && FileAccessDate == JulianToday)
|
||||
@@ -721,7 +924,17 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul)
|
||||
|
||||
/* Don't trigger timed reminders if DontIssueAts is true, and if the
|
||||
reminder is for today */
|
||||
if (jul == JulianToday && DontIssueAts && tim->ttime != NO_TIME) return 0;
|
||||
if (jul == JulianToday && DontIssueAts && tim->ttime != NO_TIME) {
|
||||
if (DontIssueAts > 1) {
|
||||
/* If two or more -a options, then *DO* issue ats that are in the
|
||||
future */
|
||||
if (tim->ttime < SystemTime(0) / 60) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't trigger "old" timed reminders */
|
||||
/*** REMOVED...
|
||||
@@ -735,7 +948,12 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul)
|
||||
|
||||
/* If there's a "warn" function, it overrides any deltas */
|
||||
if (t->warn[0] != 0) {
|
||||
return ShouldTriggerBasedOnWarn(t, jul);
|
||||
if (DeltaOffset) {
|
||||
if (jul <= JulianToday + DeltaOffset) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return ShouldTriggerBasedOnWarn(t, jul, err);
|
||||
}
|
||||
|
||||
/* Move back by delta days, if any */
|
||||
@@ -743,16 +961,29 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul)
|
||||
if (t->delta < 0)
|
||||
jul = jul + t->delta;
|
||||
else {
|
||||
int iter = 0;
|
||||
int max = MaxSatIter;
|
||||
r = t->delta;
|
||||
while(r && jul > JulianToday) {
|
||||
if (max < r*2) max = r*2;
|
||||
while(iter++ < max) {
|
||||
if (!r || (jul <= JulianToday)) {
|
||||
break;
|
||||
}
|
||||
jul--;
|
||||
if (!IsOmitted(jul, t->localomit)) r--;
|
||||
*err = IsOmitted(jul, t->localomit, t->omitfunc, &omit);
|
||||
if (*err) return 0;
|
||||
if (!omit) r--;
|
||||
}
|
||||
if (iter > max) {
|
||||
*err = E_CANT_TRIG;
|
||||
Eprint("Delta: Bad OMITFUNC? %s", ErrMsg[E_CANT_TRIG]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Should we trigger the reminder? */
|
||||
return (jul <= JulianToday);
|
||||
return (jul <= JulianToday + DeltaOffset);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -766,16 +997,20 @@ int DoSatRemind(Trigger *trig, TimeTrig *tim, ParsePtr p)
|
||||
{
|
||||
int iter, jul, r;
|
||||
Value v;
|
||||
char *s, *t;
|
||||
char const *s;
|
||||
char const *t;
|
||||
|
||||
t = p->pos;
|
||||
iter = 0;
|
||||
jul = trig->scanfrom;
|
||||
while (iter++ < MaxSatIter) {
|
||||
jul = ComputeTrigger(jul, trig, &r);
|
||||
jul = ComputeTrigger(jul, trig, &r, 1);
|
||||
if (r) {
|
||||
if (r == E_CANT_TRIG) return OK; else return r;
|
||||
}
|
||||
if (jul == -1) {
|
||||
return E_EXPIRED;
|
||||
}
|
||||
s = p->pos;
|
||||
r = EvaluateExpr(p, &v);
|
||||
t = p->pos;
|
||||
@@ -799,7 +1034,7 @@ int DoSatRemind(Trigger *trig, TimeTrig *tim, ParsePtr p)
|
||||
static int ParsePriority(ParsePtr s, Trigger *t)
|
||||
{
|
||||
int p, r;
|
||||
char *u;
|
||||
char const *u;
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
|
||||
@@ -837,14 +1072,14 @@ static int ParsePriority(ParsePtr s, Trigger *t)
|
||||
/* Execute the '-k' command, escaping shell chars in message. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoMsgCommand(char *cmd, char *msg)
|
||||
int DoMsgCommand(char const *cmd, char const *msg)
|
||||
{
|
||||
int r;
|
||||
int i, l;
|
||||
DynamicBuffer execBuffer;
|
||||
|
||||
DynamicBuffer buf;
|
||||
char *s;
|
||||
char const *s;
|
||||
|
||||
DBufInit(&buf);
|
||||
DBufInit(&execBuffer);
|
||||
@@ -865,7 +1100,7 @@ int DoMsgCommand(char *cmd, char *msg)
|
||||
msg = DBufValue(&buf);
|
||||
|
||||
/* Do "%s" substitution */
|
||||
l = strlen(cmd)-1;
|
||||
l = strlen(cmd);
|
||||
for (i=0; i<l; i++) {
|
||||
if (cmd[i] == '%' && cmd[i+1] == 's') {
|
||||
++i;
|
||||
@@ -880,11 +1115,6 @@ int DoMsgCommand(char *cmd, char *msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (l >= 0 && DBufPutc(&execBuffer, cmd[l]) != OK) {
|
||||
r = E_NO_MEM;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
r = OK;
|
||||
|
||||
system(DBufValue(&execBuffer));
|
||||
@@ -903,12 +1133,12 @@ finished:
|
||||
/* function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int ShouldTriggerBasedOnWarn(Trigger *t, int jul)
|
||||
static int ShouldTriggerBasedOnWarn(Trigger *t, int jul, int *err)
|
||||
{
|
||||
char buffer[VAR_NAME_LEN+32];
|
||||
int i;
|
||||
char *s;
|
||||
int r;
|
||||
char const *s;
|
||||
int r, omit;
|
||||
Value v;
|
||||
int lastReturnVal = 0; /* Silence compiler warning */
|
||||
|
||||
@@ -920,7 +1150,7 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int jul)
|
||||
for (i=1; ; i++) {
|
||||
sprintf(buffer, "%s(%d)", t->warn, i);
|
||||
s = buffer;
|
||||
r = EvalExpr(&s, &v);
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
if (r) {
|
||||
Eprint("%s: `%s': %s", ErrMsg[M_BAD_WARN_FUNC],
|
||||
t->warn, ErrMsg[r]);
|
||||
@@ -946,9 +1176,21 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int jul)
|
||||
if (JulianToday + v.v.val == jul) return 1;
|
||||
} else {
|
||||
int j = jul;
|
||||
while (v.v.val) {
|
||||
int iter = 0;
|
||||
int max = MaxSatIter;
|
||||
if (max < v.v.val * 2) max = v.v.val*2;
|
||||
while(iter++ <= max) {
|
||||
j--;
|
||||
if (!IsOmitted(j, t->localomit)) v.v.val++;
|
||||
*err = IsOmitted(j, t->localomit, t->omitfunc, &omit);
|
||||
if (*err) return 0;
|
||||
if (!omit) v.v.val++;
|
||||
if (!v.v.val) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (iter > max) {
|
||||
Eprint("Delta: Bad OMITFUNC? %s", ErrMsg[E_CANT_TRIG]);
|
||||
return 0;
|
||||
}
|
||||
if (j == JulianToday) return 1;
|
||||
}
|
||||
|
||||
147
src/dosubst.c
147
src/dosubst.c
@@ -12,8 +12,6 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: dosubst.c,v 1.11 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
#define L_IN_DOSUBST
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -44,6 +42,7 @@ static char TOMORROW[] = L_TOMORROW;
|
||||
/* Process the % escapes in the reminder. If */
|
||||
/* mode==NORMAL_MODE, ignore the %" sequence. If */
|
||||
/* mode==CAL_MODE, process the %" sequence. */
|
||||
/* If mode==ADVANCE_MODE, ignore %" but don't add newline */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul, int mode)
|
||||
@@ -55,13 +54,15 @@ 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;
|
||||
char *pm, *cpm;
|
||||
char const *pm, *cpm;
|
||||
int tdiff, adiff, mdiff, hdiff;
|
||||
char *mplu, *hplu, *when, *plu;
|
||||
char const *mplu, *hplu, *when, *plu;
|
||||
int has_quote = 0;
|
||||
char *ss, *os;
|
||||
char *ss;
|
||||
char *os;
|
||||
char s[256];
|
||||
int origLen = DBufLen(dbuf);
|
||||
int altmode;
|
||||
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
|
||||
@@ -131,7 +132,8 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
}
|
||||
if (c == '\n') continue;
|
||||
if (!c) {
|
||||
if (mode != CAL_MODE && t->typ != RUN_TYPE && !MsgCommand) {
|
||||
if (mode != CAL_MODE && mode != ADVANCE_MODE &&
|
||||
t->typ != RUN_TYPE && !MsgCommand) {
|
||||
if (DBufPutc(dbuf, '\n') != OK) return E_NO_MEM;
|
||||
}
|
||||
break;
|
||||
@@ -140,6 +142,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
if (DBufPutc(dbuf, c) != OK) return E_NO_MEM;
|
||||
continue;
|
||||
}
|
||||
altmode = 0;
|
||||
s[0] = 0;
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
@@ -149,6 +152,17 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
if (c == '*') {
|
||||
altmode = c;
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) {
|
||||
DBufFree(dbuf);
|
||||
return err;
|
||||
}
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
done = 0;
|
||||
if (diff <= 1) {
|
||||
switch(UPPER(c)) {
|
||||
@@ -205,8 +219,13 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_A_OVER
|
||||
L_A_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s, %d %s, %d", L_ON, DayName[jul%7], d,
|
||||
MonthName[m], y);
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s, %d %s, %d", DayName[jul%7], d,
|
||||
MonthName[m], y);
|
||||
} else {
|
||||
sprintf(s, "%s %s, %d %s, %d", L_ON, DayName[jul%7], d,
|
||||
MonthName[m], y);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -224,7 +243,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_C_OVER
|
||||
L_C_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s", L_ON, DayName[jul%7]);
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s", DayName[jul%7]);
|
||||
} else {
|
||||
sprintf(s, "%s %s", L_ON, DayName[jul%7]);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -242,8 +265,13 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_E_OVER
|
||||
L_E_OVER
|
||||
#else
|
||||
sprintf(s, "%s %02d%c%02d%c%04d", L_ON, d, DATESEP,
|
||||
m+1, DATESEP, y);
|
||||
if (altmode == '*') {
|
||||
sprintf(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,
|
||||
m+1, DateSep, y);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -252,7 +280,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_F_OVER
|
||||
L_F_OVER
|
||||
#else
|
||||
sprintf(s, "%s %02d%c%02d%c%04d", L_ON, m+1, DATESEP, d, DATESEP, y);
|
||||
if (altmode == '*') {
|
||||
sprintf(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);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -261,7 +293,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_G_OVER
|
||||
L_G_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s, %d %s", L_ON, DayName[jul%7], d, MonthName[m]);
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]);
|
||||
} else {
|
||||
sprintf(s, "%s %s, %d %s", L_ON, DayName[jul%7], d, MonthName[m]);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -270,7 +306,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_H_OVER
|
||||
L_H_OVER
|
||||
#else
|
||||
sprintf(s, "%s %02d%c%02d", L_ON, d, DATESEP, m+1);
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%02d%c%02d", d, DateSep, m+1);
|
||||
} else {
|
||||
sprintf(s, "%s %02d%c%02d", L_ON, d, DateSep, m+1);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -279,7 +319,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_I_OVER
|
||||
L_I_OVER
|
||||
#else
|
||||
sprintf(s, "%s %02d%c%02d", L_ON, m+1, DATESEP, d);
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%02d%c%02d", m+1, DateSep, d);
|
||||
} else {
|
||||
sprintf(s, "%s %02d%c%02d", L_ON, m+1, DateSep, d);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -288,8 +332,13 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_J_OVER
|
||||
L_J_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s, %s %d%s, %d", L_ON, DayName[jul%7],
|
||||
MonthName[m], d, plu, y);
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s, %s %d%s, %d", DayName[jul%7],
|
||||
MonthName[m], d, plu, y);
|
||||
} else {
|
||||
sprintf(s, "%s %s, %s %d%s, %d", L_ON, DayName[jul%7],
|
||||
MonthName[m], d, plu, y);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -298,8 +347,13 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_K_OVER
|
||||
L_K_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s, %s %d%s", L_ON, DayName[jul%7],
|
||||
MonthName[m], d, plu);
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s, %s %d%s", DayName[jul%7],
|
||||
MonthName[m], d, plu);
|
||||
} else {
|
||||
sprintf(s, "%s %s, %s %d%s", L_ON, DayName[jul%7],
|
||||
MonthName[m], d, plu);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -308,7 +362,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_L_OVER
|
||||
L_L_OVER
|
||||
#else
|
||||
sprintf(s, "%s %04d%c%02d%c%02d", L_ON, y, DATESEP, m+1, DATESEP, d);
|
||||
if (altmode == '*') {
|
||||
sprintf(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);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -390,8 +448,13 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_U_OVER
|
||||
L_U_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s, %d%s %s, %d", L_ON, DayName[jul%7], d,
|
||||
plu, MonthName[m], y);
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%s, %d%s %s, %d", DayName[jul%7], d,
|
||||
plu, MonthName[m], y);
|
||||
} else {
|
||||
sprintf(s, "%s %s, %d%s %s, %d", L_ON, DayName[jul%7], d,
|
||||
plu, MonthName[m], y);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -400,8 +463,13 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_V_OVER
|
||||
L_V_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s, %d%s %s", L_ON, DayName[jul%7], d, plu,
|
||||
MonthName[m]);
|
||||
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
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -463,7 +531,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
#ifdef L_2_OVER
|
||||
L_2_OVER
|
||||
#else
|
||||
sprintf(s, "%s %d%c%02d%s", L_AT, hh, TIMESEP, min, pm);
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%d%c%02d%s", hh, TimeSep, min, pm);
|
||||
} else {
|
||||
sprintf(s, "%s %d%c%02d%s", L_AT, hh, TimeSep, min, pm);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -473,7 +545,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
L_3_OVER
|
||||
#else
|
||||
|
||||
sprintf(s, "%s %02d%c%02d", L_AT, h, TIMESEP, min);
|
||||
if (altmode == '*') {
|
||||
sprintf(s, "%02d%c%02d", h, TimeSep, min);
|
||||
} else {
|
||||
sprintf(s, "%s %02d%c%02d", L_AT, h, TimeSep, min);
|
||||
}
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -554,7 +630,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);
|
||||
sprintf(s, "%d%c%02d%s", chh, TimeSep, cmin, cpm);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
@@ -563,13 +639,13 @@ 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);
|
||||
sprintf(s, "%02d%c%02d", ch, TimeSep, cmin);
|
||||
#endif
|
||||
SHIP_OUT(s);
|
||||
break;
|
||||
|
||||
case '_':
|
||||
if (mode != CAL_MODE && !MsgCommand)
|
||||
if (mode != CAL_MODE && mode != ADVANCE_MODE && !MsgCommand)
|
||||
sprintf(s, "%s", NL);
|
||||
else
|
||||
sprintf(s, " ");
|
||||
@@ -589,8 +665,11 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
if (DBufPutc(dbuf, c) != OK) return E_NO_MEM;
|
||||
}
|
||||
if (isupper(c)) {
|
||||
os = DBufValue(dbuf) - strlen(s);
|
||||
*os = UPPER(*os);
|
||||
os = DBufValue(dbuf);
|
||||
os += strlen(os) - strlen(s);
|
||||
if (os >= DBufValue(dbuf)) {
|
||||
*os = UPPER(*os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,7 +681,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
/* If there are NO quotes, then: If CAL_MODE && RUN_TYPE, we don't want the
|
||||
reminder in the calendar. Zero the output buffer and quit. */
|
||||
if (!has_quote) {
|
||||
if (mode == CAL_MODE && t->typ == RUN_TYPE) {
|
||||
if ((mode == ADVANCE_MODE || mode == CAL_MODE) && t->typ == RUN_TYPE) {
|
||||
*DBufValue(dbuf) = 0;
|
||||
dbuf->len = 0;
|
||||
}
|
||||
@@ -614,7 +693,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
|
||||
ss = DBufValue(dbuf) + origLen;
|
||||
os = ss;
|
||||
if (mode == NORMAL_MODE) {
|
||||
if (mode == NORMAL_MODE || mode == ADVANCE_MODE) {
|
||||
while (*ss) {
|
||||
if (*ss != QUOTE_MARKER) *os++ = *ss;
|
||||
ss++;
|
||||
@@ -649,7 +728,7 @@ int DoSubst(ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul,
|
||||
/* default triggers and a mode of NORMAL_MODE. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoSubstFromString(char *source, DynamicBuffer *dbuf,
|
||||
int DoSubstFromString(char const *source, DynamicBuffer *dbuf,
|
||||
int jul, int tim)
|
||||
{
|
||||
Trigger tempTrig;
|
||||
|
||||
11
src/dynbuf.c
11
src/dynbuf.c
@@ -11,9 +11,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] =
|
||||
"$Id: dynbuf.c,v 1.6 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include "dynbuf.h"
|
||||
#include "err.h"
|
||||
@@ -45,7 +42,7 @@ static int DBufMakeRoom(DynamicBuffer *dbuf, int n)
|
||||
}
|
||||
|
||||
/* Allocate memory */
|
||||
buf = (char *) malloc(size);
|
||||
buf = malloc(size);
|
||||
if (!buf) return E_NO_MEM;
|
||||
|
||||
/* Copy contents */
|
||||
@@ -76,7 +73,7 @@ void DBufInit(DynamicBuffer *dbuf)
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
%FUNCTION: DBufPutc
|
||||
%FUNCTION: DBufPutcFN
|
||||
%ARGUMENTS:
|
||||
dbuf -- pointer to a dynamic buffer
|
||||
c -- character to append to buffer
|
||||
@@ -85,7 +82,7 @@ void DBufInit(DynamicBuffer *dbuf)
|
||||
%DESCRIPTION:
|
||||
Appends a character to the buffer.
|
||||
**********************************************************************/
|
||||
int DBufPutc(DynamicBuffer *dbuf, char c)
|
||||
int DBufPutcFN(DynamicBuffer *dbuf, char c)
|
||||
{
|
||||
if (dbuf->allocatedLen == dbuf->len+1) {
|
||||
if (DBufMakeRoom(dbuf, dbuf->len+1) != OK) return E_NO_MEM;
|
||||
@@ -105,7 +102,7 @@ int DBufPutc(DynamicBuffer *dbuf, char c)
|
||||
%DESCRIPTION:
|
||||
Appends a string to the buffer.
|
||||
**********************************************************************/
|
||||
int DBufPuts(DynamicBuffer *dbuf, char *str)
|
||||
int DBufPuts(DynamicBuffer *dbuf, char const *str)
|
||||
{
|
||||
int l = strlen(str);
|
||||
if (!l) return OK;
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: dynbuf.h,v 1.4 2005-09-30 03:29:32 dfs Exp $ */
|
||||
|
||||
#ifndef DYNBUF_H
|
||||
#define DYNBUF_H
|
||||
|
||||
@@ -26,12 +24,14 @@ typedef struct {
|
||||
} DynamicBuffer;
|
||||
|
||||
void DBufInit(DynamicBuffer *dbuf);
|
||||
int DBufPutc(DynamicBuffer *dbuf, char c);
|
||||
int DBufPuts(DynamicBuffer *dbuf, char *str);
|
||||
int DBufPutcFN(DynamicBuffer *dbuf, char c);
|
||||
int DBufPuts(DynamicBuffer *dbuf, char const *str);
|
||||
void DBufFree(DynamicBuffer *dbuf);
|
||||
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)
|
||||
|
||||
#endif /* DYNBUF_H */
|
||||
|
||||
16
src/err.h
16
src/err.h
@@ -10,8 +10,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: err.h,v 1.4 2000-02-18 03:45:51 dfs Exp $ */
|
||||
|
||||
/* Note that not all of the "errors" are really errors - some are just
|
||||
messages for information purposes. Constants beginning with M_ should
|
||||
never be returned as error indicators - they should only be used to
|
||||
@@ -118,6 +116,9 @@
|
||||
#define M_QUEUED 96
|
||||
#define E_EXPECTING_NUMBER 97
|
||||
#define M_BAD_WARN_FUNC 98
|
||||
#define E_CANT_CONVERT_TZ 99
|
||||
#define E_NO_MATCHING_REMS 100
|
||||
#define E_STRING_TOO_LONG 101
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
#undef EXTERN
|
||||
@@ -190,7 +191,7 @@ EXTERN char *ErrMsg[]
|
||||
"Too many partial OMITs",
|
||||
"Too many full OMITs",
|
||||
"Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT",
|
||||
"Error reading file",
|
||||
"Error reading",
|
||||
"Expecting end-of-line",
|
||||
"Invalid Hebrew date",
|
||||
"IIF needs odd number of arguments",
|
||||
@@ -204,9 +205,9 @@ EXTERN char *ErrMsg[]
|
||||
"Back value specified twice",
|
||||
"ONCE keyword used twice. (Hah.)",
|
||||
"Expecting time after AT",
|
||||
"UNTIL keyword used twice",
|
||||
"THROUGH/UNTIL keyword used twice",
|
||||
"Incomplete date specification",
|
||||
"SCANFROM keyword used twice",
|
||||
"FROM/SCANFROM keyword used twice",
|
||||
"Variable",
|
||||
"Value",
|
||||
"*UNDEFINED*",
|
||||
@@ -230,7 +231,10 @@ EXTERN char *ErrMsg[]
|
||||
"No reminders.",
|
||||
"%d reminder(s) queued for later today.\n",
|
||||
"Expecting number",
|
||||
"Bad function in WARN clause"
|
||||
"Bad function in WARN clause",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long"
|
||||
}
|
||||
#endif /* MK_GLOBALS */
|
||||
;
|
||||
|
||||
324
src/expr.c
324
src/expr.c
@@ -11,8 +11,6 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: expr.c,v 1.10 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
@@ -43,8 +41,7 @@ static int Multiply(void), Divide(void), Mod(void), Add(void),
|
||||
UnMinus(void), LogNot(void),
|
||||
Compare(int);
|
||||
|
||||
static int MakeValue (char *s, Value *v, Var *locals);
|
||||
static int ParseLiteralDate (char **s, int *jul);
|
||||
static int MakeValue (char const *s, Value *v, Var *locals, ParsePtr p);
|
||||
|
||||
/* Binary operators - all left-associative */
|
||||
|
||||
@@ -75,9 +72,7 @@ Operator UnOp[] = {
|
||||
};
|
||||
#define NUM_UN_OPS (sizeof(UnOp) / sizeof(Operator))
|
||||
|
||||
/* Functions have the same definitions as operators, except the prec field
|
||||
is used to indicate how many arguments are needed. */
|
||||
extern Operator Func[];
|
||||
extern BuiltinFunc Func[];
|
||||
|
||||
Operator OpStack[OP_STACK_SIZE];
|
||||
Value ValStack[VAL_STACK_SIZE];
|
||||
@@ -134,10 +129,10 @@ static void CleanStack(void)
|
||||
/* PeekChar - peek ahead to next char. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static char PeekChar(char **s)
|
||||
static char PeekChar(char const **s)
|
||||
{
|
||||
char *t = *s;
|
||||
while (*t && isspace(*t)) t++;
|
||||
char const *t = *s;
|
||||
while (*t && isempty(*t)) t++;
|
||||
return *t;
|
||||
}
|
||||
|
||||
@@ -148,14 +143,14 @@ static char PeekChar(char **s)
|
||||
/* Read a token. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int ParseExprToken(DynamicBuffer *buf, char **in)
|
||||
static int ParseExprToken(DynamicBuffer *buf, char const **in)
|
||||
{
|
||||
|
||||
char c;
|
||||
|
||||
DBufFree(buf);
|
||||
/* Skip white space */
|
||||
while (**in && isspace(**in)) (*in)++;
|
||||
while (**in && isempty(**in)) (*in)++;
|
||||
|
||||
if (!**in) return OK;
|
||||
|
||||
@@ -206,6 +201,46 @@ static int ParseExprToken(DynamicBuffer *buf, char **in)
|
||||
if (c == '\"') {
|
||||
if (!**in) return E_MISS_QUOTE;
|
||||
while (**in) {
|
||||
/* Allow backslash-escapes */
|
||||
if (**in == '\\') {
|
||||
int r;
|
||||
(*in)++;
|
||||
if (!**in) {
|
||||
DBufFree(buf);
|
||||
return E_MISS_QUOTE;
|
||||
}
|
||||
switch(**in) {
|
||||
case 'a':
|
||||
r = DBufPutc(buf, '\a');
|
||||
break;
|
||||
case 'b':
|
||||
r = DBufPutc(buf, '\b');
|
||||
break;
|
||||
case 'f':
|
||||
r = DBufPutc(buf, '\f');
|
||||
break;
|
||||
case 'n':
|
||||
r = DBufPutc(buf, '\n');
|
||||
break;
|
||||
case 'r':
|
||||
r = DBufPutc(buf, '\r');
|
||||
break;
|
||||
case 't':
|
||||
r = DBufPutc(buf, '\t');
|
||||
break;
|
||||
case 'v':
|
||||
r = DBufPutc(buf, '\v');
|
||||
break;
|
||||
default:
|
||||
r = DBufPutc(buf, **in);
|
||||
}
|
||||
(*in)++;
|
||||
if (r != OK) {
|
||||
DBufFree(buf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
c = *(*in)++;
|
||||
if (DBufPutc(buf, c) != OK) {
|
||||
DBufFree(buf);
|
||||
@@ -240,7 +275,7 @@ static int ParseExprToken(DynamicBuffer *buf, char **in)
|
||||
}
|
||||
|
||||
/* Parse a constant, variable name or function */
|
||||
while (ISID(**in) || **in == ':' || **in == '.' || **in == TIMESEP) {
|
||||
while (ISID(**in) || **in == ':' || **in == '.' || **in == TimeSep) {
|
||||
if (DBufPutc(buf, **in) != OK) {
|
||||
DBufFree(buf);
|
||||
return E_NO_MEM;
|
||||
@@ -248,7 +283,7 @@ static int ParseExprToken(DynamicBuffer *buf, char **in)
|
||||
(*in)++;
|
||||
}
|
||||
/* Chew up any remaining white space */
|
||||
while (**in && isspace(**in)) (*in)++;
|
||||
while (**in && isempty(**in)) (*in)++;
|
||||
|
||||
/* Peek ahead - is it '('? Then we have a function call */
|
||||
if (**in == '(') {
|
||||
@@ -268,14 +303,14 @@ static int ParseExprToken(DynamicBuffer *buf, char **in)
|
||||
/* Put the result into value pointed to by v. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int EvalExpr(char **e, Value *v)
|
||||
int EvalExpr(char const **e, Value *v, ParsePtr p)
|
||||
{
|
||||
int r;
|
||||
|
||||
OpStackPtr = 0;
|
||||
ValStackPtr = 0;
|
||||
|
||||
r = Evaluate(e, NULL);
|
||||
r = Evaluate(e, NULL, p);
|
||||
|
||||
/* Put last character parsed back onto input stream */
|
||||
if (DBufLen(&ExprBuf)) (*e)--;
|
||||
@@ -291,15 +326,16 @@ int EvalExpr(char **e, Value *v)
|
||||
}
|
||||
|
||||
/* Evaluate - do the actual work of evaluation. */
|
||||
int Evaluate(char **s, Var *locals)
|
||||
int Evaluate(char const **s, Var *locals, ParsePtr p)
|
||||
{
|
||||
int OpBase, ValBase;
|
||||
int r;
|
||||
Operator *f;
|
||||
Operator *o;
|
||||
BuiltinFunc *f;
|
||||
int args; /* Number of function arguments */
|
||||
Operator op, op2;
|
||||
Value va;
|
||||
char *ufname = NULL; /* Stop GCC from complaining about use of uninit var */
|
||||
char const *ufname = NULL; /* Stop GCC from complaining about use of uninit var */
|
||||
|
||||
OpBase = OpStackPtr;
|
||||
ValBase = ValStackPtr;
|
||||
@@ -315,7 +351,7 @@ int Evaluate(char **s, Var *locals)
|
||||
|
||||
if (*DBufValue(&ExprBuf) == '(') { /* Parenthesized expression */
|
||||
DBufFree(&ExprBuf);
|
||||
r = Evaluate(s, locals); /* Leaves the last parsed token in ExprBuf */
|
||||
r = Evaluate(s, locals, p); /* Leaves the last parsed token in ExprBuf */
|
||||
if (r) return r;
|
||||
r = OK;
|
||||
if (*DBufValue(&ExprBuf) != ')') {
|
||||
@@ -338,10 +374,12 @@ int Evaluate(char **s, Var *locals)
|
||||
}
|
||||
args = 0;
|
||||
if (PeekChar(s) == ')') { /* Function has no arguments */
|
||||
if (f) r = CallFunc(f, 0);
|
||||
else {
|
||||
r = CallUserFunc(ufname, 0);
|
||||
free(ufname);
|
||||
if (f) {
|
||||
if (!f->is_constant && (p != NULL)) p->nonconst_expr = 1;
|
||||
r = CallFunc(f, 0);
|
||||
} else {
|
||||
r = CallUserFunc(ufname, 0, p);
|
||||
free((char *) ufname);
|
||||
}
|
||||
if (r) return r;
|
||||
r = ParseExprToken(&ExprBuf, s); /* Guaranteed to be right paren. */
|
||||
@@ -349,33 +387,35 @@ int Evaluate(char **s, Var *locals)
|
||||
} else { /* Function has some arguments */
|
||||
while(1) {
|
||||
args++;
|
||||
r = Evaluate(s, locals);
|
||||
r = Evaluate(s, locals, p);
|
||||
if (r) {
|
||||
if (!f) free(ufname);
|
||||
if (!f) free((char *) ufname);
|
||||
return r;
|
||||
}
|
||||
if (*DBufValue(&ExprBuf) == ')') break;
|
||||
else if (*DBufValue(&ExprBuf) != ',') {
|
||||
if (!f) free(ufname);
|
||||
if (!f) free((char *) ufname);
|
||||
Eprint("%s: `%c'", ErrMsg[E_EXPECT_COMMA],
|
||||
*DBufValue(&ExprBuf));
|
||||
DBufFree(&ExprBuf);
|
||||
return E_EXPECT_COMMA;
|
||||
}
|
||||
}
|
||||
if (f) r = CallFunc(f, args);
|
||||
else {
|
||||
r = CallUserFunc(ufname, args);
|
||||
free(ufname);
|
||||
if (f) {
|
||||
if (!f->is_constant && (p != NULL)) p->nonconst_expr = 1;
|
||||
r = CallFunc(f, args);
|
||||
} else {
|
||||
r = CallUserFunc(ufname, args, p);
|
||||
free((char *) ufname);
|
||||
}
|
||||
if (r) return r;
|
||||
DBufFree(&ExprBuf);
|
||||
if (r) return r;
|
||||
}
|
||||
} else { /* Unary operator */
|
||||
f = FindFunc(DBufValue(&ExprBuf), UnOp, NUM_UN_OPS);
|
||||
if (f) {
|
||||
o = FindOperator(DBufValue(&ExprBuf), UnOp, NUM_UN_OPS);
|
||||
if (o) {
|
||||
DBufFree(&ExprBuf);
|
||||
PushOpStack(*f);
|
||||
PushOpStack(*o);
|
||||
continue; /* Still looking for an atomic vlue */
|
||||
} else if (!ISID(*DBufValue(&ExprBuf)) &&
|
||||
*DBufValue(&ExprBuf) != '$' &&
|
||||
@@ -386,7 +426,7 @@ int Evaluate(char **s, Var *locals)
|
||||
DBufFree(&ExprBuf);
|
||||
return E_ILLEGAL_CHAR;
|
||||
} else { /* Must be a literal value */
|
||||
r = MakeValue(DBufValue(&ExprBuf), &va, locals);
|
||||
r = MakeValue(DBufValue(&ExprBuf), &va, locals, p);
|
||||
DBufFree(&ExprBuf);
|
||||
if (r) return r;
|
||||
PushValStack(va);
|
||||
@@ -421,13 +461,13 @@ int Evaluate(char **s, Var *locals)
|
||||
return OK;
|
||||
}
|
||||
/* Must be a binary operator */
|
||||
f = FindFunc(DBufValue(&ExprBuf), BinOp, NUM_BIN_OPS);
|
||||
o = FindOperator(DBufValue(&ExprBuf), BinOp, NUM_BIN_OPS);
|
||||
DBufFree(&ExprBuf);
|
||||
if (!f) return E_EXPECTING_BINOP;
|
||||
if (!o) return E_EXPECTING_BINOP;
|
||||
|
||||
/* While operators of higher or equal precedence are on the stack,
|
||||
pop them off and evaluate */
|
||||
while (OpStackPtr > OpBase && OpStack[OpStackPtr-1].prec >= f->prec) {
|
||||
while (OpStackPtr > OpBase && OpStack[OpStackPtr-1].prec >= o->prec) {
|
||||
PopOpStack(op2);
|
||||
if (r) return r;
|
||||
if (DebugFlag & DB_PRTEXPR)
|
||||
@@ -439,7 +479,7 @@ int Evaluate(char **s, Var *locals)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
PushOpStack(*f);
|
||||
PushOpStack(*o);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,7 +490,7 @@ int Evaluate(char **s, Var *locals)
|
||||
/* a date or the value of a symbol. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int MakeValue(char *s, Value *v, Var *locals)
|
||||
static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
|
||||
{
|
||||
int len;
|
||||
int h, m, r;
|
||||
@@ -458,7 +498,7 @@ static int MakeValue(char *s, Value *v, Var *locals)
|
||||
if (*s == '\"') { /* It's a literal string "*/
|
||||
len = strlen(s)-1;
|
||||
v->type = STR_TYPE;
|
||||
v->v.str = (char *) malloc(len);
|
||||
v->v.str = malloc(len);
|
||||
if (! v->v.str) {
|
||||
v->type = ERR_TYPE;
|
||||
return E_NO_MEM;
|
||||
@@ -468,10 +508,15 @@ static int MakeValue(char *s, Value *v, Var *locals)
|
||||
return OK;
|
||||
} else if (*s == '\'') { /* It's a literal date */
|
||||
s++;
|
||||
if ((r=ParseLiteralDate(&s, &h))) return r;
|
||||
if ((r=ParseLiteralDate(&s, &h, &m))) return r;
|
||||
if (*s != '\'') return E_BAD_DATE;
|
||||
v->type = DATE_TYPE;
|
||||
v->v.val = h;
|
||||
if (m == NO_TIME) {
|
||||
v->type = DATE_TYPE;
|
||||
v->v.val = h;
|
||||
} else {
|
||||
v->type = DATETIME_TYPE;
|
||||
v->v.val = (h * MINUTES_PER_DAY) + m;
|
||||
}
|
||||
return OK;
|
||||
} else if (isdigit(*s)) { /* It's a number - use len to hold it.*/
|
||||
len = 0;
|
||||
@@ -479,7 +524,7 @@ static int MakeValue(char *s, Value *v, Var *locals)
|
||||
len *= 10;
|
||||
len += (*s++ - '0');
|
||||
}
|
||||
if (*s == ':' || *s == '.' || *s == TIMESEP) { /* Must be a literal time */
|
||||
if (*s == ':' || *s == '.' || *s == TimeSep) { /* Must be a literal time */
|
||||
s++;
|
||||
if (!isdigit(*s)) return E_BAD_TIME;
|
||||
h = len;
|
||||
@@ -490,7 +535,7 @@ static int MakeValue(char *s, Value *v, Var *locals)
|
||||
s++;
|
||||
}
|
||||
if (*s || h>23 || m>59) return E_BAD_TIME;
|
||||
v->type = TIM_TYPE;
|
||||
v->type = TIME_TYPE;
|
||||
v->v.val = h*60 + m;
|
||||
return OK;
|
||||
}
|
||||
@@ -500,6 +545,7 @@ static int MakeValue(char *s, Value *v, Var *locals)
|
||||
v->v.val = len;
|
||||
return OK;
|
||||
} else if (*s == '$') { /* A system variable */
|
||||
if (p) p->nonconst_expr = 1;
|
||||
if (DebugFlag & DB_PRTEXPR)
|
||||
fprintf(ErrFp, "%s => ", s);
|
||||
r = GetSysVar(s+1, v);
|
||||
@@ -510,10 +556,11 @@ static int MakeValue(char *s, Value *v, Var *locals)
|
||||
Putc('\n', ErrFp);
|
||||
}
|
||||
return r;
|
||||
} else /* Must be a symbol */
|
||||
} else { /* Must be a symbol */
|
||||
if (DebugFlag & DB_PRTEXPR)
|
||||
fprintf(ErrFp, "%s => ", s);
|
||||
r = GetVarValue(s, v, locals);
|
||||
}
|
||||
r = GetVarValue(s, v, locals, p);
|
||||
if (! (DebugFlag & DB_PRTEXPR)) return r;
|
||||
if (r == OK) {
|
||||
PrintValue(v, ErrFp);
|
||||
@@ -529,22 +576,52 @@ static int MakeValue(char *s, Value *v, Var *locals)
|
||||
/***************************************************************/
|
||||
int DoCoerce(char type, Value *v)
|
||||
{
|
||||
int h, d, m, y, i;
|
||||
char *s;
|
||||
int h, d, m, y, i, k;
|
||||
char const *s;
|
||||
|
||||
/* Do nothing if value is already the right type */
|
||||
if (type == v->type) return OK;
|
||||
|
||||
switch(type) {
|
||||
case DATETIME_TYPE:
|
||||
switch(v->type) {
|
||||
case INT_TYPE:
|
||||
v->type = DATETIME_TYPE;
|
||||
return OK;
|
||||
case DATE_TYPE:
|
||||
v->type = DATETIME_TYPE;
|
||||
v->v.val *= MINUTES_PER_DAY;
|
||||
return OK;
|
||||
case STR_TYPE:
|
||||
s = v->v.str;
|
||||
if (ParseLiteralDate(&s, &i, &m)) return E_CANT_COERCE;
|
||||
if (*s) return E_CANT_COERCE;
|
||||
v->type = DATETIME_TYPE;
|
||||
free(v->v.str);
|
||||
if (m == NO_TIME) m = 0;
|
||||
v->v.val = i * MINUTES_PER_DAY + m;
|
||||
return OK;
|
||||
default:
|
||||
return E_CANT_COERCE;
|
||||
}
|
||||
case STR_TYPE:
|
||||
switch(v->type) {
|
||||
case INT_TYPE: sprintf(CoerceBuf, "%d", v->v.val); break;
|
||||
case TIM_TYPE: sprintf(CoerceBuf, "%02d%c%02d", v->v.val / 60,
|
||||
TIMESEP, v->v.val % 60);
|
||||
case TIME_TYPE: sprintf(CoerceBuf, "%02d%c%02d", v->v.val / 60,
|
||||
TimeSep, v->v.val % 60);
|
||||
break;
|
||||
case DATE_TYPE: FromJulian(v->v.val, &y, &m, &d);
|
||||
sprintf(CoerceBuf, "%04d%c%02d%c%02d",
|
||||
y, DATESEP, m+1, DATESEP, d);
|
||||
y, DateSep, m+1, DateSep, d);
|
||||
break;
|
||||
case DATETIME_TYPE:
|
||||
i = v->v.val / MINUTES_PER_DAY;
|
||||
FromJulian(i, &y, &m, &d);
|
||||
k = v->v.val % MINUTES_PER_DAY;
|
||||
h = k / 60;
|
||||
i = k % 60;
|
||||
sprintf(CoerceBuf, "%04d%c%02d%c%02d@%02d%c%02d",
|
||||
y, DateSep, m+1, DateSep, d, h, TimeSep, i);
|
||||
break;
|
||||
default: return E_CANT_COERCE;
|
||||
}
|
||||
@@ -581,7 +658,8 @@ int DoCoerce(char type, Value *v)
|
||||
return OK;
|
||||
|
||||
case DATE_TYPE:
|
||||
case TIM_TYPE:
|
||||
case TIME_TYPE:
|
||||
case DATETIME_TYPE:
|
||||
v->type = INT_TYPE;
|
||||
return OK;
|
||||
|
||||
@@ -598,22 +676,28 @@ int DoCoerce(char type, Value *v)
|
||||
|
||||
case STR_TYPE:
|
||||
s = v->v.str;
|
||||
if (ParseLiteralDate(&s, &i)) return E_CANT_COERCE;
|
||||
if (ParseLiteralDate(&s, &i, &m)) return E_CANT_COERCE;
|
||||
if (*s) return E_CANT_COERCE;
|
||||
v->type = DATE_TYPE;
|
||||
free(v->v.str);
|
||||
v->v.val = i;
|
||||
return OK;
|
||||
|
||||
case DATETIME_TYPE:
|
||||
v->type = DATE_TYPE;
|
||||
v->v.val /= MINUTES_PER_DAY;
|
||||
return OK;
|
||||
|
||||
default: return E_CANT_COERCE;
|
||||
}
|
||||
|
||||
case TIM_TYPE:
|
||||
case TIME_TYPE:
|
||||
switch(v->type) {
|
||||
case INT_TYPE:
|
||||
v->type = TIM_TYPE;
|
||||
v->v.val %= 1440;
|
||||
if (v->v.val < 0) v->v.val += 1440;
|
||||
case DATETIME_TYPE:
|
||||
v->type = TIME_TYPE;
|
||||
v->v.val %= MINUTES_PER_DAY;
|
||||
if (v->v.val < 0) v->v.val += MINUTES_PER_DAY;
|
||||
return OK;
|
||||
|
||||
case STR_TYPE:
|
||||
@@ -625,7 +709,7 @@ int DoCoerce(char type, Value *v)
|
||||
h *= 10;
|
||||
h += *s++ - '0';
|
||||
}
|
||||
if (*s != ':' && *s != '.' && *s != TIMESEP)
|
||||
if (*s != ':' && *s != '.' && *s != TimeSep)
|
||||
return E_CANT_COERCE;
|
||||
s++;
|
||||
if (!isdigit(*s)) return E_CANT_COERCE;
|
||||
@@ -634,7 +718,7 @@ int DoCoerce(char type, Value *v)
|
||||
m += *s++ - '0';
|
||||
}
|
||||
if (*s || h>23 || m>59) return E_CANT_COERCE;
|
||||
v->type = TIM_TYPE;
|
||||
v->type = TIME_TYPE;
|
||||
free(v->v.str);
|
||||
v->v.val = h*60+m;
|
||||
return OK;
|
||||
@@ -657,6 +741,8 @@ static int Add(void)
|
||||
Value v1, v2, v3;
|
||||
int r;
|
||||
|
||||
size_t l1, l2;
|
||||
|
||||
PopValStack(v2);
|
||||
if ( (r = FnPopValStack(&v1)) ) {
|
||||
DestroyValue(v2);
|
||||
@@ -680,12 +766,22 @@ static int Add(void)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* If it's a time plus an int, add 'em mod 1440 */
|
||||
if ((v1.type == TIM_TYPE && v2.type == INT_TYPE) ||
|
||||
(v1.type == INT_TYPE && v2.type == TIM_TYPE)) {
|
||||
v1.v.val = (v1.v.val + v2.v.val) % 1440;
|
||||
if (v1.v.val < 0) v1.v.val += 1440;
|
||||
v1.type = TIM_TYPE;
|
||||
/* If it's a datetime plus an int, add 'em */
|
||||
if ((v1.type == DATETIME_TYPE && v2.type == INT_TYPE) ||
|
||||
(v1.type == INT_TYPE && v2.type == DATETIME_TYPE)) {
|
||||
v1.v.val += v2.v.val;
|
||||
if (v1.v.val < 0) return E_DATE_OVER;
|
||||
v1.type = DATETIME_TYPE;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* If it's a time plus an int, add 'em mod MINUTES_PER_DAY */
|
||||
if ((v1.type == TIME_TYPE && v2.type == INT_TYPE) ||
|
||||
(v1.type == INT_TYPE && v2.type == TIME_TYPE)) {
|
||||
v1.v.val = (v1.v.val + v2.v.val) % MINUTES_PER_DAY;
|
||||
if (v1.v.val < 0) v1.v.val += MINUTES_PER_DAY;
|
||||
v1.type = TIME_TYPE;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
}
|
||||
@@ -701,7 +797,13 @@ static int Add(void)
|
||||
return r;
|
||||
}
|
||||
v3.type = STR_TYPE;
|
||||
v3.v.str = (char *) malloc(strlen(v1.v.str) + strlen(v2.v.str) + 1);
|
||||
l1 = strlen(v1.v.str);
|
||||
l2 = strlen(v2.v.str);
|
||||
if (MaxStringLen && (l1 + l2 > MaxStringLen)) {
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_STRING_TOO_LONG;
|
||||
}
|
||||
v3.v.str = malloc(l1 + l2 + 1);
|
||||
if (!v3.v.str) {
|
||||
DestroyValue(v1); DestroyValue(v2);
|
||||
return E_NO_MEM;
|
||||
@@ -750,16 +852,25 @@ static int Subtract(void)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* If it's a time minus an int, do subtraction mod 1440 */
|
||||
if (v1.type == TIM_TYPE && v2.type == INT_TYPE) {
|
||||
v1.v.val = (v1.v.val - v2.v.val) % 1440;
|
||||
if (v1.v.val < 0) v1.v.val += 1440;
|
||||
/* If it's a datetime minus an int, do subtraction, checking for underflow */
|
||||
if (v1.type == DATETIME_TYPE && v2.type == INT_TYPE) {
|
||||
v1.v.val -= v2.v.val;
|
||||
if (v1.v.val < 0) return E_DATE_OVER;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* If it's a time minus an int, do subtraction mod MINUTES_PER_DAY */
|
||||
if (v1.type == TIME_TYPE && v2.type == INT_TYPE) {
|
||||
v1.v.val = (v1.v.val - v2.v.val) % MINUTES_PER_DAY;
|
||||
if (v1.v.val < 0) v1.v.val += MINUTES_PER_DAY;
|
||||
PushValStack(v1);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* If it's a time minus a time or a date minus a date, do it */
|
||||
if ((v1.type == TIM_TYPE && v2.type == TIM_TYPE) ||
|
||||
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)) {
|
||||
v1.v.val -= v2.v.val;
|
||||
v1.type = INT_TYPE;
|
||||
@@ -1019,7 +1130,28 @@ static int LogNot(void)
|
||||
/* Find a function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
Operator *FindFunc(char *name, Operator where[], int num)
|
||||
Operator *FindOperator(char const *name, Operator where[], int num)
|
||||
{
|
||||
int top=num-1, bot=0;
|
||||
int mid, r;
|
||||
while (top >= bot) {
|
||||
mid = (top + bot) / 2;
|
||||
r = StrCmpi(name, where[mid].name);
|
||||
if (!r) return &where[mid];
|
||||
else if (r > 0) bot = mid+1;
|
||||
else top = mid-1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindFunc */
|
||||
/* */
|
||||
/* Find a function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
BuiltinFunc *FindFunc(char const *name, BuiltinFunc where[], int num)
|
||||
{
|
||||
int top=num-1, bot=0;
|
||||
int mid, r;
|
||||
@@ -1043,7 +1175,7 @@ Operator *FindFunc(char *name, Operator where[], int num)
|
||||
void PrintValue (Value *v, FILE *fp)
|
||||
{
|
||||
int y, m, d;
|
||||
char *s;
|
||||
char const *s;
|
||||
|
||||
if (v->type == STR_TYPE) {
|
||||
s=v->v.str;
|
||||
@@ -1053,11 +1185,16 @@ void PrintValue (Value *v, FILE *fp)
|
||||
if (*s) fprintf(fp, "...");
|
||||
}
|
||||
else if (v->type == INT_TYPE) fprintf(fp, "%d", v->v.val);
|
||||
else if (v->type == TIM_TYPE) fprintf(fp, "%02d%c%02d", v->v.val / 60,
|
||||
TIMESEP, v->v.val % 60);
|
||||
else if (v->type == TIME_TYPE) fprintf(fp, "%02d%c%02d", v->v.val / 60,
|
||||
TimeSep, v->v.val % 60);
|
||||
else if (v->type == DATE_TYPE) {
|
||||
FromJulian(v->v.val, &y, &m, &d);
|
||||
fprintf(fp, "%04d%c%02d%c%02d", y, DATESEP, m+1, DATESEP, d);
|
||||
fprintf(fp, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
}
|
||||
else if (v->type == DATETIME_TYPE) {
|
||||
FromJulian(v->v.val / MINUTES_PER_DAY, &y, &m, &d);
|
||||
fprintf(fp, "%04d%c%02d%c%02d@%02d%c%02d", y, DateSep, m+1, DateSep, d,
|
||||
(v->v.val % MINUTES_PER_DAY) / 60, TimeSep, (v->v.val % MINUTES_PER_DAY) % 60);
|
||||
}
|
||||
else fprintf(fp, "ERR");
|
||||
}
|
||||
@@ -1086,21 +1223,25 @@ int CopyValue(Value *dest, const Value *src)
|
||||
/* */
|
||||
/* ParseLiteralDate */
|
||||
/* */
|
||||
/* Parse a literal date. Return result in jul, update s. */
|
||||
/* Parse a literal date or datetime. Return result in jul */
|
||||
/* and tim; update s. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int ParseLiteralDate(char **s, int *jul)
|
||||
int ParseLiteralDate(char const **s, int *jul, int *tim)
|
||||
{
|
||||
int y, m, d;
|
||||
int hour, min;
|
||||
|
||||
y=0; m=0; d=0;
|
||||
hour=0; min=0;
|
||||
|
||||
*tim = NO_TIME;
|
||||
if (!isdigit(**s)) return E_BAD_DATE;
|
||||
while (isdigit(**s)) {
|
||||
y *= 10;
|
||||
y += *(*s)++ - '0';
|
||||
}
|
||||
if (**s != '/' && **s != '-' && **s != DATESEP) return E_BAD_DATE;
|
||||
if (**s != '/' && **s != '-' && **s != DateSep) return E_BAD_DATE;
|
||||
(*s)++;
|
||||
if (!isdigit(**s)) return E_BAD_DATE;
|
||||
while (isdigit(**s)) {
|
||||
@@ -1108,7 +1249,7 @@ static int ParseLiteralDate(char **s, int *jul)
|
||||
m += *(*s)++ - '0';
|
||||
}
|
||||
m--;
|
||||
if (**s != '/' && **s != '-' && **s != DATESEP) return E_BAD_DATE;
|
||||
if (**s != '/' && **s != '-' && **s != DateSep) return E_BAD_DATE;
|
||||
(*s)++;
|
||||
if (!isdigit(**s)) return E_BAD_DATE;
|
||||
while (isdigit(**s)) {
|
||||
@@ -1119,6 +1260,23 @@ static int ParseLiteralDate(char **s, int *jul)
|
||||
|
||||
*jul = Julian(y, m, d);
|
||||
|
||||
/* Do we have a time part as well? */
|
||||
if (**s == ' ' || **s == '@') {
|
||||
(*s)++;
|
||||
while(isdigit(**s)) {
|
||||
hour *= 10;
|
||||
hour += *(*s)++ - '0';
|
||||
}
|
||||
if (**s != ':' && **s != '.' && **s != TimeSep) return E_BAD_TIME;
|
||||
(*s)++;
|
||||
while(isdigit(**s)) {
|
||||
min *= 10;
|
||||
min += *(*s)++ - '0';
|
||||
}
|
||||
if (hour > 23 || min > 59) return E_BAD_TIME;
|
||||
*tim = hour * 60 + min;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
14
src/expr.h
14
src/expr.h
@@ -10,14 +10,14 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: expr.h,v 1.4 2000-02-18 03:45:53 dfs Exp $ */
|
||||
|
||||
/* Define the types of values */
|
||||
#define ERR_TYPE 0
|
||||
#define INT_TYPE 1
|
||||
#define TIM_TYPE 2
|
||||
#define DATE_TYPE 3
|
||||
#define STR_TYPE 4
|
||||
#define ERR_TYPE 0
|
||||
#define INT_TYPE 1
|
||||
#define TIME_TYPE 2
|
||||
#define DATE_TYPE 3
|
||||
#define STR_TYPE 4
|
||||
#define DATETIME_TYPE 5
|
||||
#define SPECIAL_TYPE 6 /* Only for system variables */
|
||||
|
||||
/* Define stuff for parsing expressions */
|
||||
#define BEG_OF_EXPR '['
|
||||
|
||||
369
src/files.c
369
src/files.c
@@ -13,11 +13,11 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: files.c,v 1.11 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -31,6 +31,10 @@ static char const RCSID[] = "$Id: files.c,v 1.11 2005-09-30 03:29:32 dfs Exp $";
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_GLOB_H
|
||||
#include <glob.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "globals.h"
|
||||
@@ -43,20 +47,34 @@ static char const RCSID[] = "$Id: files.c,v 1.11 2005-09-30 03:29:32 dfs Exp $";
|
||||
/* Define the structures needed by the file caching system */
|
||||
typedef struct cache {
|
||||
struct cache *next;
|
||||
char *text;
|
||||
char const *text;
|
||||
int LineNo;
|
||||
} CachedLine;
|
||||
|
||||
typedef struct cheader {
|
||||
struct cheader *next;
|
||||
char *filename;
|
||||
char const *filename;
|
||||
CachedLine *cache;
|
||||
int ownedByMe;
|
||||
} CachedFile;
|
||||
|
||||
/* A linked list of filenames if we INCLUDE /some/directory/ */
|
||||
typedef struct fname_chain {
|
||||
struct fname_chain *next;
|
||||
char const *filename;
|
||||
} FilenameChain;
|
||||
|
||||
/* Cache filename chains for directories */
|
||||
typedef struct directory_fname_chain {
|
||||
struct directory_fname_chain *next;
|
||||
FilenameChain *chain;
|
||||
char const *dirname;
|
||||
} DirectoryFilenameChain;
|
||||
|
||||
/* Define the structures needed by the INCLUDE file system */
|
||||
typedef struct {
|
||||
char *filename;
|
||||
char const *filename;
|
||||
FilenameChain *chain;
|
||||
int LineNo;
|
||||
unsigned int IfFlags;
|
||||
int NumIfs;
|
||||
@@ -67,6 +85,7 @@ typedef struct {
|
||||
|
||||
static CachedFile *CachedFiles = (CachedFile *) NULL;
|
||||
static CachedLine *CLine = (CachedLine *) NULL;
|
||||
static DirectoryFilenameChain *CachedDirectoryChains = NULL;
|
||||
|
||||
static FILE *fp;
|
||||
|
||||
@@ -74,9 +93,52 @@ static IncludeStruct IStack[INCLUDE_NEST];
|
||||
static int IStackPtr = 0;
|
||||
|
||||
static int ReadLineFromFile (void);
|
||||
static int CacheFile (const char *fname);
|
||||
static int CacheFile (char const *fname);
|
||||
static void DestroyCache (CachedFile *cf);
|
||||
static int CheckSafety (void);
|
||||
static int PopFile (void);
|
||||
|
||||
static void OpenPurgeFile(char const *fname, char const *mode)
|
||||
{
|
||||
DynamicBuffer fname_buf;
|
||||
|
||||
if (PurgeFP != NULL && PurgeFP != stdout) {
|
||||
fclose(PurgeFP);
|
||||
}
|
||||
PurgeFP = NULL;
|
||||
|
||||
/* Do not open a purge file if we're below purge
|
||||
include depth */
|
||||
if (IStackPtr-2 >= PurgeIncludeDepth) {
|
||||
PurgeFP = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
DBufInit(&fname_buf);
|
||||
if (DBufPuts(&fname_buf, fname) != OK) return;
|
||||
if (DBufPuts(&fname_buf, ".purged") != OK) return;
|
||||
PurgeFP = fopen(DBufValue(&fname_buf), mode);
|
||||
if (!PurgeFP) {
|
||||
fprintf(ErrFp, "Cannot open `%s' for writing: %s\n", DBufValue(&fname_buf), strerror(errno));
|
||||
}
|
||||
DBufFree(&fname_buf);
|
||||
}
|
||||
|
||||
static void FreeChainItem(FilenameChain *chain)
|
||||
{
|
||||
if (chain->filename) free((void *) chain->filename);
|
||||
free(chain);
|
||||
}
|
||||
|
||||
static void FreeChain(FilenameChain *chain)
|
||||
{
|
||||
FilenameChain *next;
|
||||
while(chain) {
|
||||
next = chain->next;
|
||||
FreeChainItem(chain);
|
||||
chain = next;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -138,14 +200,32 @@ static int ReadLineFromFile(void)
|
||||
}
|
||||
if (feof(fp)) {
|
||||
FCLOSE(fp);
|
||||
if ((DBufLen(&buf) == 0) &&
|
||||
(DBufLen(&LineBuffer) == 0) && PurgeMode) {
|
||||
if (PurgeFP != NULL && PurgeFP != stdout) fclose(PurgeFP);
|
||||
PurgeFP = NULL;
|
||||
}
|
||||
}
|
||||
l = DBufLen(&buf);
|
||||
if (l && (DBufValue(&buf)[l-1] == '\\')) {
|
||||
DBufValue(&buf)[l-1] = 0;
|
||||
if (DBufPuts(&LineBuffer, DBufValue(&buf)) != OK) {
|
||||
DBufFree(&buf);
|
||||
DBufFree(&LineBuffer);
|
||||
return E_NO_MEM;
|
||||
if (PurgeMode) {
|
||||
if (DBufPuts(&LineBuffer, DBufValue(&buf)) != OK) {
|
||||
DBufFree(&buf);
|
||||
DBufFree(&LineBuffer);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
if (DBufPutc(&LineBuffer, '\n') != OK) {
|
||||
DBufFree(&buf);
|
||||
DBufFree(&LineBuffer);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
} else {
|
||||
DBufValue(&buf)[l-1] = '\n';
|
||||
if (DBufPuts(&LineBuffer, DBufValue(&buf)) != OK) {
|
||||
DBufFree(&buf);
|
||||
DBufFree(&LineBuffer);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -172,11 +252,18 @@ static int ReadLineFromFile(void)
|
||||
/* ShouldCache is 1, cache the file */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int OpenFile(const char *fname)
|
||||
int OpenFile(char const *fname)
|
||||
{
|
||||
CachedFile *h = CachedFiles;
|
||||
int r;
|
||||
|
||||
if (PurgeMode) {
|
||||
if (PurgeFP != NULL && PurgeFP != stdout) {
|
||||
fclose(PurgeFP);
|
||||
}
|
||||
PurgeFP = NULL;
|
||||
}
|
||||
|
||||
/* Assume we own the file for now */
|
||||
RunDisabled &= ~RUN_NOTOWNER;
|
||||
|
||||
@@ -184,6 +271,9 @@ int OpenFile(const char *fname)
|
||||
|
||||
while (h) {
|
||||
if (!strcmp(fname, h->filename)) {
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Reading `%s': Found in cache\n", fname);
|
||||
}
|
||||
CLine = h->cache;
|
||||
STRSET(FileName, fname);
|
||||
LineNo = 0;
|
||||
@@ -198,8 +288,20 @@ int OpenFile(const char *fname)
|
||||
/* If it's a dash, then it's stdin */
|
||||
if (!strcmp(fname, "-")) {
|
||||
fp = stdin;
|
||||
if (PurgeMode) {
|
||||
PurgeFP = stdout;
|
||||
}
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Reading `-': Reading stdin\n");
|
||||
}
|
||||
} else {
|
||||
fp = fopen(fname, "r");
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Reading `%s': Opening file on disk\n", fname);
|
||||
}
|
||||
if (PurgeMode) {
|
||||
OpenPurgeFile(fname, "w");
|
||||
}
|
||||
}
|
||||
if (!fp || !CheckSafety()) return E_CANT_OPEN;
|
||||
CLine = NULL;
|
||||
@@ -213,8 +315,10 @@ int OpenFile(const char *fname)
|
||||
if (strcmp(fname, "-")) {
|
||||
fp = fopen(fname, "r");
|
||||
if (!fp || !CheckSafety()) return E_CANT_OPEN;
|
||||
if (PurgeMode) OpenPurgeFile(fname, "w");
|
||||
} else {
|
||||
fp = stdin;
|
||||
if (PurgeMode) PurgeFP = stdout;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -231,18 +335,25 @@ int OpenFile(const char *fname)
|
||||
/* Returns an indication of success or failure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int CacheFile(const char *fname)
|
||||
static int CacheFile(char const *fname)
|
||||
{
|
||||
int r;
|
||||
CachedFile *cf;
|
||||
CachedLine *cl;
|
||||
char *s;
|
||||
char const *s;
|
||||
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Caching file `%s' in memory\n", fname);
|
||||
}
|
||||
cl = NULL;
|
||||
/* Create a file header */
|
||||
cf = NEW(CachedFile);
|
||||
cf->cache = NULL;
|
||||
if (!cf) { ShouldCache = 0; FCLOSE(fp); return E_NO_MEM; }
|
||||
if (!cf) {
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
cf->filename = StrDup(fname);
|
||||
if (!cf->filename) {
|
||||
ShouldCache = 0;
|
||||
@@ -268,7 +379,7 @@ static int CacheFile(const char *fname)
|
||||
}
|
||||
/* Skip blank chars */
|
||||
s = DBufValue(&LineBuffer);
|
||||
while (isspace(*s)) s++;
|
||||
while (isempty(*s)) s++;
|
||||
if (*s && *s!=';' && *s!='#') {
|
||||
/* Add the line to the cache */
|
||||
if (!cl) {
|
||||
@@ -312,13 +423,33 @@ static int CacheFile(const char *fname)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* NextChainedFile - move to the next chained file in a glob */
|
||||
/* list. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int NextChainedFile(IncludeStruct *i)
|
||||
{
|
||||
while(i->chain) {
|
||||
FilenameChain *cur = i->chain;
|
||||
i->chain = i->chain->next;
|
||||
if (OpenFile(cur->filename) == OK) {
|
||||
return OK;
|
||||
} else {
|
||||
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], cur->filename);
|
||||
}
|
||||
}
|
||||
return E_EOF;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* PopFile - we've reached the end. Pop up to the previous */
|
||||
/* file, or return E_EOF */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int PopFile(void)
|
||||
static int PopFile(void)
|
||||
{
|
||||
IncludeStruct *i;
|
||||
|
||||
@@ -327,8 +458,21 @@ int PopFile(void)
|
||||
|
||||
if (!Hush && NumIfs) Eprint("%s", ErrMsg[E_MISS_ENDIF]);
|
||||
if (!IStackPtr) return E_EOF;
|
||||
i = &IStack[IStackPtr-1];
|
||||
|
||||
if (i->chain) {
|
||||
int oldRunDisabled = RunDisabled;
|
||||
if (NextChainedFile(i) == OK) {
|
||||
return OK;
|
||||
}
|
||||
RunDisabled = oldRunDisabled;
|
||||
}
|
||||
|
||||
if (IStackPtr <= 1) {
|
||||
return E_EOF;
|
||||
}
|
||||
|
||||
IStackPtr--;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
LineNo = i->LineNo;
|
||||
IfFlags = i->IfFlags;
|
||||
@@ -344,13 +488,15 @@ int PopFile(void)
|
||||
if (strcmp(i->filename, "-")) {
|
||||
fp = fopen(i->filename, "r");
|
||||
if (!fp || !CheckSafety()) return E_CANT_OPEN;
|
||||
if (PurgeMode) OpenPurgeFile(i->filename, "a");
|
||||
} else {
|
||||
fp = stdin;
|
||||
if (PurgeMode) PurgeFP = stdout;
|
||||
}
|
||||
if (fp != stdin)
|
||||
(void) fseek(fp, i->offset, 0); /* Trust that it works... */
|
||||
}
|
||||
free(i->filename);
|
||||
free((char *) i->filename);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -362,13 +508,13 @@ int PopFile(void)
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int DoInclude(ParsePtr p)
|
||||
{
|
||||
{
|
||||
DynamicBuffer buf;
|
||||
int r, e;
|
||||
|
||||
DBufInit(&buf);
|
||||
if ( (r=ParseToken(p, &buf)) ) return r;
|
||||
e = VerifyEoln(p);
|
||||
e = VerifyEoln(p);
|
||||
if (e) Eprint("%s", ErrMsg[e]);
|
||||
if ( (r=IncludeFile(DBufValue(&buf))) ) {
|
||||
DBufFree(&buf);
|
||||
@@ -380,6 +526,126 @@ int DoInclude(ParsePtr p)
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GLOB
|
||||
static int SetupGlobChain(char const *dirname, IncludeStruct *i)
|
||||
{
|
||||
DynamicBuffer pattern;
|
||||
char *dir;
|
||||
size_t l;
|
||||
int r;
|
||||
glob_t glob_buf;
|
||||
DirectoryFilenameChain *dc = CachedDirectoryChains;
|
||||
|
||||
i->chain = NULL;
|
||||
if (!*dirname) return E_CANT_OPEN;
|
||||
|
||||
dir = StrDup(dirname);
|
||||
if (!dir) return E_NO_MEM;
|
||||
|
||||
/* Strip trailing slashes off directory */
|
||||
l = strlen(dir);
|
||||
while(l) {
|
||||
if (*(dir+l-1) == '/') {
|
||||
l--;
|
||||
*(dir+l) = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Repair root directory :-) */
|
||||
if (!l) {
|
||||
*dir = '/';
|
||||
}
|
||||
|
||||
/* Check the cache */
|
||||
while(dc) {
|
||||
if (!strcmp(dc->dirname, dir)) {
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Found cached directory listing for `%s'\n",
|
||||
dir);
|
||||
}
|
||||
free(dir);
|
||||
i->chain = dc->chain;
|
||||
return OK;
|
||||
}
|
||||
dc = dc->next;
|
||||
}
|
||||
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Scanning directory `%s' for *.rem files\n", dir);
|
||||
}
|
||||
|
||||
if (ShouldCache) {
|
||||
dc = malloc(sizeof(DirectoryFilenameChain));
|
||||
if (dc) {
|
||||
dc->dirname = StrDup(dir);
|
||||
if (!dc->dirname) {
|
||||
free(dc);
|
||||
dc = NULL;
|
||||
}
|
||||
}
|
||||
if (dc) {
|
||||
if (DebugFlag & DB_TRACE_FILES) {
|
||||
fprintf(ErrFp, "Caching directory `%s' listing\n", dir);
|
||||
}
|
||||
|
||||
dc->chain = NULL;
|
||||
dc->next = CachedDirectoryChains;
|
||||
CachedDirectoryChains = dc;
|
||||
}
|
||||
}
|
||||
|
||||
DBufInit(&pattern);
|
||||
DBufPuts(&pattern, dir);
|
||||
DBufPuts(&pattern, "/*.rem");
|
||||
free(dir);
|
||||
|
||||
r = glob(DBufValue(&pattern), 0, NULL, &glob_buf);
|
||||
DBufFree(&pattern);
|
||||
|
||||
if (r == GLOB_NOMATCH) {
|
||||
globfree(&glob_buf);
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (r != 0) {
|
||||
globfree(&glob_buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Add the files to the chain backwards to preserve sort order */
|
||||
for (r=glob_buf.gl_pathc-1; r>=0; r--) {
|
||||
FilenameChain *ch = malloc(sizeof(FilenameChain));
|
||||
if (!ch) {
|
||||
globfree(&glob_buf);
|
||||
FreeChain(i->chain);
|
||||
i->chain = NULL;
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
/* TODO: stat the file and only add if it's a plain file and
|
||||
readable by us */
|
||||
ch->filename = StrDup(glob_buf.gl_pathv[r]);
|
||||
if (!ch->filename) {
|
||||
globfree(&glob_buf);
|
||||
FreeChain(i->chain);
|
||||
i->chain = NULL;
|
||||
free(ch);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
ch->next = i->chain;
|
||||
i->chain = ch;
|
||||
}
|
||||
if (dc) {
|
||||
dc->chain = i->chain;
|
||||
}
|
||||
|
||||
globfree(&glob_buf);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* IncludeFile */
|
||||
@@ -388,22 +654,28 @@ int DoInclude(ParsePtr p)
|
||||
/* inclusion. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int IncludeFile(const char *fname)
|
||||
int IncludeFile(char const *fname)
|
||||
{
|
||||
IncludeStruct *i;
|
||||
int r;
|
||||
int oldRunDisabled;
|
||||
struct stat statbuf;
|
||||
|
||||
FreshLine = 1;
|
||||
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
i->filename = StrDup(FileName);
|
||||
if (!i->filename) return E_NO_MEM;
|
||||
if (FileName) {
|
||||
i->filename = StrDup(FileName);
|
||||
if (!i->filename) return E_NO_MEM;
|
||||
} else {
|
||||
i->filename = NULL;
|
||||
}
|
||||
i->LineNo = LineNo;
|
||||
i->NumIfs = NumIfs;
|
||||
i->IfFlags = IfFlags;
|
||||
i->CLine = CLine;
|
||||
i->offset = -1L;
|
||||
i->chain = NULL;
|
||||
if (RunDisabled & RUN_NOTOWNER) {
|
||||
i->ownedByMe = 0;
|
||||
} else {
|
||||
@@ -416,15 +688,52 @@ int IncludeFile(const char *fname)
|
||||
|
||||
IStackPtr++;
|
||||
|
||||
#ifdef HAVE_GLOB
|
||||
/* If it's a directory, set up the glob chain here. */
|
||||
if (stat(fname, &statbuf) == 0) {
|
||||
FilenameChain *fc;
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
if (SetupGlobChain(fname, i) == OK) { /* Glob succeeded */
|
||||
if (!i->chain) { /* Oops... no matching files */
|
||||
if (!Hush) {
|
||||
Eprint("%s: %s", fname, ErrMsg[E_NO_MATCHING_REMS]);
|
||||
}
|
||||
PopFile();
|
||||
return E_NO_MATCHING_REMS;
|
||||
}
|
||||
while(i->chain) {
|
||||
fc = i->chain;
|
||||
i->chain = i->chain->next;
|
||||
|
||||
/* Munch first file */
|
||||
oldRunDisabled = RunDisabled;
|
||||
if (!OpenFile(fc->filename)) {
|
||||
return OK;
|
||||
}
|
||||
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], fc->filename);
|
||||
RunDisabled = oldRunDisabled;
|
||||
}
|
||||
/* Couldn't open anything... bail */
|
||||
return PopFile();
|
||||
} else {
|
||||
if (!Hush) {
|
||||
Eprint("%s: %s", fname, ErrMsg[E_NO_MATCHING_REMS]);
|
||||
}
|
||||
}
|
||||
return E_NO_MATCHING_REMS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
oldRunDisabled = RunDisabled;
|
||||
/* Try to open the new file */
|
||||
if (!OpenFile(fname)) {
|
||||
return OK;
|
||||
}
|
||||
RunDisabled = oldRunDisabled;
|
||||
/* Ugh! We failed! */
|
||||
if ( (r=PopFile()) ) return r;
|
||||
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], fname);
|
||||
/* Ugh! We failed! */
|
||||
PopFile();
|
||||
return E_CANT_OPEN;
|
||||
}
|
||||
|
||||
@@ -433,7 +742,7 @@ int IncludeFile(const char *fname)
|
||||
/* GetAccessDate - get the access date of a file. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int GetAccessDate(char *file)
|
||||
int GetAccessDate(char const *file)
|
||||
{
|
||||
struct stat statbuf;
|
||||
struct tm *t1;
|
||||
@@ -458,10 +767,10 @@ static void DestroyCache(CachedFile *cf)
|
||||
{
|
||||
CachedLine *cl, *cnext;
|
||||
CachedFile *temp;
|
||||
if (cf->filename) free(cf->filename);
|
||||
if (cf->filename) free((char *) cf->filename);
|
||||
cl = cf->cache;
|
||||
while (cl) {
|
||||
if (cl->text) free (cl->text);
|
||||
if (cl->text) free ((char *) cl->text);
|
||||
cnext = cl->next;
|
||||
free(cl);
|
||||
cl = cnext;
|
||||
@@ -489,7 +798,7 @@ static void DestroyCache(CachedFile *cf)
|
||||
/***************************************************************/
|
||||
int TopLevel(void)
|
||||
{
|
||||
return !IStackPtr;
|
||||
return IStackPtr <= 1;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
1743
src/funcs.c
1743
src/funcs.c
File diff suppressed because it is too large
Load Diff
@@ -14,10 +14,10 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: globals.c,v 1.4 2000-02-18 03:45:56 dfs Exp $";
|
||||
|
||||
#include <stdio.h> /* For defintion of FILE - sigh! */
|
||||
#include "types.h"
|
||||
#include "custom.h"
|
||||
#define MK_GLOBALS
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: globals.h,v 1.9 2005-09-30 03:29:32 dfs Exp $ */
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
#undef EXTERN
|
||||
#define EXTERN
|
||||
@@ -24,6 +22,8 @@
|
||||
#define INIT(var, val) var
|
||||
#endif
|
||||
|
||||
#define MINUTES_PER_DAY 1440
|
||||
|
||||
#define DaysInYear(y) (((y) % 4) ? 365 : ((!((y) % 100) && ((y) % 400)) ? 365 : 366 ))
|
||||
#define IsLeapYear(y) (((y) % 4) ? 0 : ((!((y) % 100) && ((y) % 400)) ? 0 : 1 ))
|
||||
#define DaysInMonth(m, y) ((m) != 1 ? MonthDays[m] : 28 + IsLeapYear(y))
|
||||
@@ -37,11 +37,12 @@ EXTERN int CurMon;
|
||||
EXTERN int CurYear;
|
||||
EXTERN int LineNo;
|
||||
EXTERN int FreshLine;
|
||||
EXTERN INIT( char *MsgCommand, NULL);
|
||||
EXTERN INIT( char const *MsgCommand, NULL);
|
||||
EXTERN INIT( int ShowAllErrors, 0);
|
||||
EXTERN INIT( int DebugFlag, 0);
|
||||
EXTERN INIT( int DoCalendar, 0);
|
||||
EXTERN INIT( int DoSimpleCalendar, 0);
|
||||
EXTERN INIT( int DoSimpleCalDelta, 0);
|
||||
EXTERN INIT( int DoPrefixLineNo, 0);
|
||||
EXTERN INIT( int MondayFirst, 0);
|
||||
EXTERN INIT( int Iterations, 1);
|
||||
@@ -52,15 +53,17 @@ EXTERN INIT( int CalMonths, 0);
|
||||
EXTERN INIT( int Hush, 0);
|
||||
EXTERN INIT( int NextMode, 0);
|
||||
EXTERN INIT( int InfiniteDelta, 0);
|
||||
EXTERN INIT( int DeltaOffset, 0);
|
||||
EXTERN INIT( int RunDisabled, 0);
|
||||
EXTERN INIT( int IgnoreOnce, 0);
|
||||
EXTERN INIT( int SortByTime, 0);
|
||||
EXTERN INIT( int SortByDate, 0);
|
||||
EXTERN INIT( int SortByPrio, 0);
|
||||
EXTERN INIT( int UntimedBeforeTimed, 0);
|
||||
EXTERN INIT( int DefaultPrio, NO_PRIORITY);
|
||||
EXTERN INIT( long SysTime, -1L);
|
||||
|
||||
EXTERN char *InitialFile;
|
||||
EXTERN char const *InitialFile;
|
||||
EXTERN int FileAccessDate;
|
||||
|
||||
EXTERN INIT( int DontFork, 0);
|
||||
@@ -68,25 +71,33 @@ EXTERN INIT( int DontQueue, 0);
|
||||
EXTERN INIT( int NumQueued, 0);
|
||||
EXTERN INIT( int DontIssueAts, 0);
|
||||
EXTERN INIT( int Daemon, 0);
|
||||
|
||||
|
||||
EXTERN INIT( char DateSep, DATESEP);
|
||||
EXTERN INIT( char TimeSep, TIMESEP);
|
||||
EXTERN INIT( int SynthesizeTags, 0);
|
||||
EXTERN INIT( int ScFormat, SC_AMPM);
|
||||
EXTERN INIT( int MaxSatIter, 150);
|
||||
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);
|
||||
EXTERN INIT( int LastTriggerDate, 0);
|
||||
EXTERN INIT( int LastTrigValid, 0);
|
||||
EXTERN INIT( int LastTriggerTime, 0);
|
||||
EXTERN INIT( int ShouldCache, 0);
|
||||
EXTERN char *CurLine;
|
||||
EXTERN char const *CurLine;
|
||||
EXTERN INIT( int NumTriggered, 0);
|
||||
EXTERN int ArgC;
|
||||
EXTERN char **ArgV;
|
||||
EXTERN char const **ArgV;
|
||||
EXTERN INIT( int CalLines, CAL_LINES);
|
||||
EXTERN INIT( int CalPad, 1);
|
||||
EXTERN INIT( int UseVTChars, 0);
|
||||
EXTERN INIT( int UseUTF8Chars, 0);
|
||||
EXTERN INIT( int UseVTColors, 0);
|
||||
|
||||
/* Latitude and longitude */
|
||||
EXTERN INIT( int LatDeg, LAT_DEG);
|
||||
|
||||
17
src/hbcal.c
17
src/hbcal.c
@@ -14,7 +14,6 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: hbcal.c,v 1.5 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
#include <stdio.h> /* For FILE used by protos.h - sigh. */
|
||||
#include "types.h"
|
||||
@@ -56,7 +55,7 @@ static char const RCSID[] = "$Id: hbcal.c,v 1.5 2005-09-30 03:29:32 dfs Exp $";
|
||||
#define ADAR2ADARA 1
|
||||
#define ADAR2BOTH 2
|
||||
|
||||
static char *HebMonthNames[] = {
|
||||
static char const *HebMonthNames[] = {
|
||||
"Tishrey", "Heshvan", "Kislev", "Tevet", "Shvat", "Adar A", "Adar B",
|
||||
"Nisan", "Iyar", "Sivan", "Tamuz", "Av", "Elul", "Adar"};
|
||||
|
||||
@@ -138,7 +137,7 @@ int DaysInHebYear(int y)
|
||||
/* given the LENGTH of the Hebrew year. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char *DaysInHebMonths(int ylen)
|
||||
char const *DaysInHebMonths(int ylen)
|
||||
{
|
||||
static char monlen[13] =
|
||||
{30, 29, 30, 29, 30, 0, 29, 30, 29, 30, 29, 30, 29};
|
||||
@@ -167,7 +166,7 @@ char *DaysInHebMonths(int ylen)
|
||||
int HebToJul(int hy, int hm, int hd)
|
||||
{
|
||||
int ylen;
|
||||
char *monlens;
|
||||
char const *monlens;
|
||||
int rh;
|
||||
int m;
|
||||
|
||||
@@ -202,7 +201,7 @@ void JulToHeb(int jul, int *hy, int *hm, int *hd)
|
||||
int y, m, d;
|
||||
int rh;
|
||||
int ylen;
|
||||
char *monlen;
|
||||
char const *monlen;
|
||||
/* Get the common year */
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
y += 3763; /* Over-estimate a bit to be on the safe side below... */
|
||||
@@ -233,7 +232,7 @@ void JulToHeb(int jul, int *hy, int *hm, int *hd)
|
||||
/* year. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int HebNameToNum(const char *mname)
|
||||
int HebNameToNum(char const *mname)
|
||||
{
|
||||
int i;
|
||||
int m=-1;
|
||||
@@ -255,7 +254,7 @@ int HebNameToNum(const char *mname)
|
||||
/* year. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char *HebMonthName(int m, int y)
|
||||
char const *HebMonthName(int m, int y)
|
||||
{
|
||||
if (m != ADARA && m != ADARB) return HebMonthNames[m];
|
||||
|
||||
@@ -294,7 +293,7 @@ char *HebMonthName(int m, int y)
|
||||
int GetValidHebDate(int yin, int min, int din, int adarbehave,
|
||||
int *mout, int *dout, int jahr)
|
||||
{
|
||||
char *monlen;
|
||||
char const *monlen;
|
||||
int ylen;
|
||||
|
||||
*mout = min;
|
||||
@@ -449,7 +448,7 @@ int GetNextHebrewDate(int julstart, int hm, int hd,
|
||||
/***************************************************************/
|
||||
int ComputeJahr(int y, int m, int d, int *ans)
|
||||
{
|
||||
char *monlen;
|
||||
char const *monlen;
|
||||
int len;
|
||||
|
||||
*ans = JAHR_NONE;
|
||||
|
||||
337
src/init.c
337
src/init.c
@@ -8,12 +8,12 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1998 by David F. Skoll */
|
||||
/* Copyright (C) 1999-2005 by Roaring Penguin Software Inc. */
|
||||
/* Copyright (C) 1999-2011 by Roaring Penguin Software Inc. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#include "version.h"
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: init.c,v 1.16 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
#define L_IN_INIT 1
|
||||
#include <stdio.h>
|
||||
@@ -29,7 +29,6 @@ static char const RCSID[] = "$Id: init.c,v 1.16 2005-09-30 03:29:32 dfs Exp $";
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
#include "err.h"
|
||||
#include "version.h"
|
||||
#include "globals.h"
|
||||
|
||||
/***************************************************************
|
||||
@@ -53,6 +52,7 @@ static char const RCSID[] = "$Id: init.c,v 1.16 2005-09-30 03:29:32 dfs Exp $";
|
||||
* -h = Hush mode
|
||||
* -f = Do not fork
|
||||
* -dchars = Debugging mode: Chars are:
|
||||
* f = Trace file openings
|
||||
* e = Echo input lines
|
||||
* x = Display expression evaluation
|
||||
* t = Display trigger dates
|
||||
@@ -67,9 +67,13 @@ static char const RCSID[] = "$Id: init.c,v 1.16 2005-09-30 03:29:32 dfs Exp $";
|
||||
* -kcmd = Run 'cmd' for MSG-type reminders instead of printing to stdout
|
||||
* -iVAR=EXPR = Initialize and preserve VAR.
|
||||
* -m = Start calendar with Monday instead of Sunday.
|
||||
* -j[n] = Purge all junk from reminder files (n = INCLUDE depth)
|
||||
* A minus sign alone indicates to take input from stdin
|
||||
*
|
||||
**************************************************************/
|
||||
#if defined(__APPLE__) || defined(__CYGWIN__)
|
||||
static void rkrphgvba(int x);
|
||||
#endif
|
||||
|
||||
/* For parsing an integer */
|
||||
#define PARSENUM(var, s) \
|
||||
@@ -80,10 +84,41 @@ while (isdigit(*(s))) { \
|
||||
s++; \
|
||||
}
|
||||
|
||||
static void ChgUser(char *u);
|
||||
static void InitializeVar(char *str);
|
||||
static void ChgUser(char const *u);
|
||||
static void InitializeVar(char const *str);
|
||||
|
||||
static char *BadDate = "Illegal date on command line\n";
|
||||
static char const *BadDate = "Illegal date on command line\n";
|
||||
|
||||
static DynamicBuffer default_filename_buf;
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DefaultFilename */
|
||||
/* */
|
||||
/* If we're invoked as "rem" rather than "remind", use a */
|
||||
/* default filename. Use $DOTREMINDERS or $HOME/.reminders */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static char const *DefaultFilename(void)
|
||||
{
|
||||
char const *s;
|
||||
|
||||
DBufInit(&default_filename_buf);
|
||||
|
||||
s = getenv("DOTREMINDERS");
|
||||
if (s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
s = getenv("HOME");
|
||||
if (!s) {
|
||||
fprintf(stderr, "HOME environment variable not set. Unable to determine reminder file.\n");
|
||||
exit(1);
|
||||
}
|
||||
DBufPuts(&default_filename_buf, s);
|
||||
DBufPuts(&default_filename_buf, "/.reminders");
|
||||
return DBufValue(&default_filename_buf);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -92,12 +127,25 @@ static char *BadDate = "Illegal date on command line\n";
|
||||
/* Initialize the system - called only once at beginning! */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void InitRemind(int argc, char *argv[])
|
||||
void InitRemind(int argc, char const *argv[])
|
||||
{
|
||||
char *arg;
|
||||
char const *arg;
|
||||
int i;
|
||||
int y, m, d, rep;
|
||||
Token tok;
|
||||
int InvokedAsRem = 0;
|
||||
char const *s;
|
||||
int weeks;
|
||||
|
||||
int jul;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
rkrphgvba(0);
|
||||
#elif defined(__CYGWIN__)
|
||||
rkrphgvba(1);
|
||||
#endif
|
||||
|
||||
jul = NO_DATE;
|
||||
|
||||
/* Initialize global dynamic buffers */
|
||||
DBufInit(&Banner);
|
||||
@@ -106,6 +154,8 @@ void InitRemind(int argc, char *argv[])
|
||||
|
||||
DBufPuts(&Banner, L_BANNER);
|
||||
|
||||
PurgeFP = NULL;
|
||||
|
||||
/* Make sure remind is not installed set-uid or set-gid */
|
||||
if (getgid() != getegid() ||
|
||||
getuid() != geteuid()) {
|
||||
@@ -126,6 +176,19 @@ void InitRemind(int argc, char *argv[])
|
||||
JulianToday = RealToday;
|
||||
FromJulian(JulianToday, &CurYear, &CurMon, &CurDay);
|
||||
|
||||
/* See if we were invoked as "rem" rather than "remind" */
|
||||
if (argv[0]) {
|
||||
s = strrchr(argv[0], '/');
|
||||
if (!s) {
|
||||
s = argv[0];
|
||||
} else {
|
||||
s++;
|
||||
}
|
||||
if (!strcmp(s, "rem")) {
|
||||
InvokedAsRem = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the command-line options */
|
||||
i = 1;
|
||||
while (i < argc) {
|
||||
@@ -142,6 +205,13 @@ void InitRemind(int argc, char *argv[])
|
||||
while (*arg) {
|
||||
switch(*arg++) {
|
||||
|
||||
case 'j':
|
||||
case 'J':
|
||||
PurgeMode = 1;
|
||||
if (*arg) {
|
||||
PARSENUM(PurgeIncludeDepth, arg);
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
case 'I':
|
||||
InitializeVar(arg);
|
||||
@@ -170,11 +240,22 @@ void InitRemind(int argc, char *argv[])
|
||||
IgnoreOnce = 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
InfiniteDelta = 1;
|
||||
case 'y':
|
||||
case 'Y':
|
||||
SynthesizeTags = 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
if (!*arg) {
|
||||
InfiniteDelta = 1;
|
||||
} else {
|
||||
PARSENUM(DeltaOffset, arg);
|
||||
if (DeltaOffset < 0) {
|
||||
DeltaOffset = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
ErrFp = stdout;
|
||||
@@ -190,6 +271,7 @@ void InitRemind(int argc, char *argv[])
|
||||
SortByDate = SORT_ASCEND;
|
||||
SortByTime = SORT_ASCEND;
|
||||
SortByPrio = SORT_ASCEND;
|
||||
UntimedBeforeTimed = 0;
|
||||
if (*arg) {
|
||||
if (*arg == 'D' || *arg == 'd')
|
||||
SortByDate = SORT_DESCEND;
|
||||
@@ -205,6 +287,11 @@ void InitRemind(int argc, char *argv[])
|
||||
SortByPrio = SORT_DESCEND;
|
||||
arg++;
|
||||
}
|
||||
if (*arg) {
|
||||
if (*arg == 'D' || *arg == 'd')
|
||||
UntimedBeforeTimed = 1;
|
||||
arg++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
@@ -219,18 +306,18 @@ void InitRemind(int argc, char *argv[])
|
||||
if (*arg == '0') {
|
||||
PARSENUM(Daemon, arg);
|
||||
if (Daemon == 0) Daemon = -1;
|
||||
else if (Daemon < 5) Daemon = 5;
|
||||
else if (Daemon < 1) Daemon = 1;
|
||||
else if (Daemon > 60) Daemon = 60;
|
||||
} else {
|
||||
PARSENUM(Daemon, arg);
|
||||
if (Daemon<5) Daemon=5;
|
||||
if (Daemon<1) Daemon=1;
|
||||
else if (Daemon>60) Daemon=60;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
DontIssueAts = 1;
|
||||
DontIssueAts++;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
@@ -245,8 +332,38 @@ void InitRemind(int argc, char *argv[])
|
||||
case 'c':
|
||||
case 'C':
|
||||
DoCalendar = 1;
|
||||
if (*arg == '+') {
|
||||
arg++;
|
||||
weeks = 0;
|
||||
/* Parse the flags */
|
||||
while(*arg) {
|
||||
if (*arg == 'a' ||
|
||||
*arg == 'A') {
|
||||
DoSimpleCalDelta = 1;
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
if (*arg == '+') {
|
||||
weeks = 1;
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
if (*arg == 'l' || *arg == 'L') {
|
||||
UseVTChars = 1;
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
if (*arg == 'u' || *arg == 'U') {
|
||||
UseUTF8Chars = 1;
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
if (*arg == 'c' || *arg == 'C') {
|
||||
UseVTColors = 1;
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (weeks) {
|
||||
PARSENUM(CalWeeks, arg);
|
||||
if (!CalWeeks) CalWeeks = 1;
|
||||
} else {
|
||||
@@ -258,8 +375,21 @@ void InitRemind(int argc, char *argv[])
|
||||
case 's':
|
||||
case 'S':
|
||||
DoSimpleCalendar = 1;
|
||||
if (*arg == '+') {
|
||||
arg++;
|
||||
weeks = 0;
|
||||
while(*arg) {
|
||||
if (*arg == 'a' || *arg == 'A') {
|
||||
DoSimpleCalDelta = 1;
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
if (*arg == '+') {
|
||||
arg++;
|
||||
weeks = 1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (weeks) {
|
||||
PARSENUM(CalWeeks, arg);
|
||||
if (!CalWeeks) CalWeeks = 1;
|
||||
} else {
|
||||
@@ -272,6 +402,10 @@ void InitRemind(int argc, char *argv[])
|
||||
case 'P':
|
||||
DoSimpleCalendar = 1;
|
||||
PsCal = 1;
|
||||
if (*arg == 'a' || *arg == 'A') {
|
||||
DoSimpleCalDelta = 1;
|
||||
arg++;
|
||||
}
|
||||
PARSENUM(CalMonths, arg);
|
||||
if (!CalMonths) CalMonths = 1;
|
||||
break;
|
||||
@@ -305,11 +439,12 @@ void InitRemind(int argc, char *argv[])
|
||||
case 'D':
|
||||
while (*arg) {
|
||||
switch(*arg++) {
|
||||
case 'e': case 'E': DebugFlag |= DB_ECHO_LINE; break;
|
||||
case 'x': case 'X': DebugFlag |= DB_PRTEXPR; break;
|
||||
case 't': case 'T': DebugFlag |= DB_PRTTRIG; break;
|
||||
case 'v': case 'V': DebugFlag |= DB_DUMP_VARS; break;
|
||||
case 'l': case 'L': DebugFlag |= DB_PRTLINE; break;
|
||||
case 'e': case 'E': DebugFlag |= DB_ECHO_LINE; break;
|
||||
case 'x': case 'X': DebugFlag |= DB_PRTEXPR; break;
|
||||
case 't': case 'T': DebugFlag |= DB_PRTTRIG; break;
|
||||
case 'v': case 'V': DebugFlag |= DB_DUMP_VARS; break;
|
||||
case 'l': case 'L': DebugFlag |= DB_PRTLINE; break;
|
||||
case 'f': case 'F': DebugFlag |= DB_TRACE_FILES; break;
|
||||
default:
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_DB_FLAG], *(arg-1));
|
||||
}
|
||||
@@ -348,11 +483,15 @@ void InitRemind(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Get the filename. */
|
||||
if (i >= argc) {
|
||||
Usage();
|
||||
exit(1);
|
||||
if (!InvokedAsRem) {
|
||||
if (i >= argc) {
|
||||
Usage();
|
||||
exit(1);
|
||||
}
|
||||
InitialFile = argv[i++];
|
||||
} else {
|
||||
InitialFile = DefaultFilename();
|
||||
}
|
||||
InitialFile = argv[i++];
|
||||
|
||||
/* Get the date, if any */
|
||||
if (i < argc) {
|
||||
@@ -369,18 +508,32 @@ void InitRemind(int argc, char *argv[])
|
||||
}
|
||||
break;
|
||||
|
||||
case T_DateTime:
|
||||
if (SysTime != -1L) Usage();
|
||||
if (m != NO_MON || d != NO_DAY || y != NO_YR || jul != NO_DATE) Usage();
|
||||
SysTime = (tok.val % MINUTES_PER_DAY) * 60;
|
||||
DontQueue = 1;
|
||||
Daemon = 0;
|
||||
jul = tok.val / MINUTES_PER_DAY;
|
||||
break;
|
||||
|
||||
case T_Date:
|
||||
if (m != NO_MON || d != NO_DAY || y != NO_YR || jul != NO_DATE) Usage();
|
||||
jul = tok.val;
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
if (m != NO_MON) Usage();
|
||||
if (m != NO_MON || jul != NO_DATE) Usage();
|
||||
else m = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
if (d != NO_DAY) Usage();
|
||||
if (d != NO_DAY || jul != NO_DATE) Usage();
|
||||
else d = tok.val;
|
||||
break;
|
||||
|
||||
case T_Year:
|
||||
if (y != NO_YR) Usage();
|
||||
if (y != NO_YR || jul != NO_DATE) Usage();
|
||||
else y = tok.val;
|
||||
break;
|
||||
|
||||
@@ -389,7 +542,8 @@ void InitRemind(int argc, char *argv[])
|
||||
else rep = tok.val;
|
||||
break;
|
||||
|
||||
default: Usage();
|
||||
default:
|
||||
Usage();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,6 +553,9 @@ void InitRemind(int argc, char *argv[])
|
||||
Daemon = 0;
|
||||
}
|
||||
|
||||
if (jul != NO_DATE) {
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
}
|
||||
/* Must supply date in the form: day, mon, yr OR mon, yr */
|
||||
if (m != NO_MON || y != NO_YR || d != NO_DAY) {
|
||||
if (m == NO_MON || y == NO_YR) {
|
||||
@@ -412,12 +569,12 @@ void InitRemind(int argc, char *argv[])
|
||||
}
|
||||
if (d == NO_DAY) d=1;
|
||||
if (d > DaysInMonth(m, y)) {
|
||||
fprintf(ErrFp, BadDate);
|
||||
fprintf(ErrFp, "%s", BadDate);
|
||||
Usage();
|
||||
}
|
||||
JulianToday = Julian(y, m, d);
|
||||
if (JulianToday == -1) {
|
||||
fprintf(ErrFp, BadDate);
|
||||
fprintf(ErrFp, "%s", BadDate);
|
||||
Usage();
|
||||
}
|
||||
CurYear = y;
|
||||
@@ -444,7 +601,7 @@ void InitRemind(int argc, char *argv[])
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1998 David F. Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "Copyright 1999-2005 Roaring Penguin Software Inc.\n");
|
||||
fprintf(ErrFp, "Copyright 1999-2011 Roaring Penguin Software Inc.\n");
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
@@ -452,28 +609,30 @@ 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, " -c[n] Produce a calendar for n (default 1) months\n");
|
||||
fprintf(ErrFp, " -c+[n] Produce a calendar for n (default 1) weeks\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");
|
||||
fprintf(ErrFp, " -s[+][n] Produce `simple calendar' for n (1) months (weeks)\n");
|
||||
fprintf(ErrFp, " -p[n] Same as -s, but input compatible with rem2ps\n");
|
||||
fprintf(ErrFp, " -s[a][+][n] Produce `simple calendar' for n (1) months (weeks)\n");
|
||||
fprintf(ErrFp, " -p[a][n] Same as -s, but input compatible with rem2ps\n");
|
||||
fprintf(ErrFp, " -l Prefix each simple calendar line with line number and filename comment\n");
|
||||
fprintf(ErrFp, " -v Verbose mode\n");
|
||||
fprintf(ErrFp, " -o Ignore ONCE directives\n");
|
||||
fprintf(ErrFp, " -t Trigger all future reminders regardless of delta\n");
|
||||
fprintf(ErrFp, " -t[n] Trigger all future (or those within `n' days)\n");
|
||||
fprintf(ErrFp, " -h `Hush' mode - be very quiet\n");
|
||||
fprintf(ErrFp, " -a Don't trigger timed reminders immediately - just queue them\n");
|
||||
fprintf(ErrFp, " -q Don't queue timed reminders\n");
|
||||
fprintf(ErrFp, " -f Trigger timed reminders by staying in foreground\n");
|
||||
fprintf(ErrFp, " -z[n] Enter daemon mode, waking every n (5) minutes.\n");
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
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, " -kcmd Run `cmd' for MSG-type reminders\n");
|
||||
fprintf(ErrFp, " -g[ddd] Sort reminders by date, time and priority before issuing\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");
|
||||
fprintf(ErrFp, " -m Start calendar with Monday rather than Sunday\n");
|
||||
fprintf(ErrFp, " -y Synthesize tags for tagless reminders\n");
|
||||
fprintf(ErrFp, " -j[n] Run in 'purge' mode. [n = INCLUDE depth]\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_USAGE_OVERRIDE */
|
||||
@@ -487,12 +646,15 @@ void Usage(void)
|
||||
/* USER environment variables. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static void ChgUser(char *user)
|
||||
static void ChgUser(char const *user)
|
||||
{
|
||||
uid_t myuid;
|
||||
|
||||
struct passwd *pwent;
|
||||
static char *home, *shell, *username, *logname;
|
||||
static char *home;
|
||||
static char *shell;
|
||||
static char *username;
|
||||
static char *logname;
|
||||
|
||||
myuid = getuid();
|
||||
|
||||
@@ -515,7 +677,7 @@ static void ChgUser(char *user)
|
||||
|
||||
home = malloc(strlen(pwent->pw_dir) + 6);
|
||||
if (!home) {
|
||||
fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(home, "HOME=%s", pwent->pw_dir);
|
||||
@@ -523,7 +685,7 @@ static void ChgUser(char *user)
|
||||
|
||||
shell = malloc(strlen(pwent->pw_shell) + 7);
|
||||
if (!shell) {
|
||||
fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(shell, "SHELL=%s", pwent->pw_shell);
|
||||
@@ -532,20 +694,34 @@ static void ChgUser(char *user)
|
||||
if (pwent->pw_uid) {
|
||||
username = malloc(strlen(pwent->pw_name) + 6);
|
||||
if (!username) {
|
||||
fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(username, "USER=%s", pwent->pw_name);
|
||||
putenv(username);
|
||||
logname= malloc(strlen(pwent->pw_name) + 9);
|
||||
if (!logname) {
|
||||
fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
|
||||
fprintf(ErrFp, "%s", ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(logname, "LOGNAME=%s", pwent->pw_name);
|
||||
putenv(logname);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DefineFunction(char const *str)
|
||||
{
|
||||
Parser p;
|
||||
int r;
|
||||
|
||||
CreateParser(str, &p);
|
||||
r = DoFset(&p);
|
||||
DestroyParser(&p);
|
||||
if (r != OK) {
|
||||
fprintf(ErrFp, "-i option: %s: %s\n", str, ErrMsg[r]);
|
||||
}
|
||||
}
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* InitializeVar */
|
||||
@@ -553,22 +729,34 @@ static void ChgUser(char *user)
|
||||
/* Initialize and preserve a variable */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static void InitializeVar(char *str)
|
||||
static void InitializeVar(char const *str)
|
||||
{
|
||||
char *varname, *expr;
|
||||
char const *expr;
|
||||
char const *ostr = str;
|
||||
char varname[VAR_NAME_LEN+1];
|
||||
|
||||
Value val;
|
||||
|
||||
int r;
|
||||
|
||||
/* Scan for an '=' sign */
|
||||
varname = str;
|
||||
while (*str && *str != '=') str++;
|
||||
r = 0;
|
||||
while (*str && *str != '=') {
|
||||
if (r < VAR_NAME_LEN) {
|
||||
varname[r++] = *str;
|
||||
}
|
||||
if (*str == '(') {
|
||||
/* Do a function definition if we see a paren */
|
||||
DefineFunction(ostr);
|
||||
return;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
varname[r] = 0;
|
||||
if (!*str) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_EQ]);
|
||||
return;
|
||||
}
|
||||
*str = 0;
|
||||
if (!*varname) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_VAR]);
|
||||
return;
|
||||
@@ -579,7 +767,7 @@ static void InitializeVar(char *str)
|
||||
return;
|
||||
}
|
||||
|
||||
r=EvalExpr(&expr, &val);
|
||||
r=EvalExpr(&expr, &val, NULL);
|
||||
if (r) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
return;
|
||||
@@ -601,3 +789,46 @@ static void InitializeVar(char *str)
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__) || defined(__CYGWIN__)
|
||||
static char const pmsg1[] = {
|
||||
0x4c, 0x62, 0x68, 0x20, 0x6e, 0x63, 0x63, 0x72, 0x6e, 0x65, 0x20,
|
||||
0x67, 0x62, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x68, 0x61, 0x61, 0x76,
|
||||
0x61, 0x74, 0x20, 0x45, 0x72, 0x7a, 0x76, 0x61, 0x71, 0x20, 0x62,
|
||||
0x61, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x63, 0x63, 0x79, 0x72, 0x20,
|
||||
0x63, 0x65, 0x62, 0x71, 0x68, 0x70, 0x67, 0x2e, 0x20, 0x20, 0x56,
|
||||
0x27, 0x71, 0x20, 0x65, 0x6e, 0x67, 0x75, 0x72, 0x65, 0x20, 0x67,
|
||||
0x75, 0x6e, 0x67, 0x0a, 0x6c, 0x62, 0x68, 0x20, 0x71, 0x76, 0x71,
|
||||
0x61, 0x27, 0x67, 0x2e, 0x20, 0x20, 0x45, 0x72, 0x7a, 0x76, 0x61,
|
||||
0x71, 0x20, 0x72, 0x6b, 0x72, 0x70, 0x68, 0x67, 0x76, 0x62, 0x61,
|
||||
0x20, 0x6a, 0x76, 0x79, 0x79, 0x20, 0x70, 0x62, 0x61, 0x67, 0x76,
|
||||
0x61, 0x68, 0x72, 0x20, 0x7a, 0x62, 0x7a, 0x72, 0x61, 0x67, 0x6e,
|
||||
0x65, 0x76, 0x79, 0x6c, 0x2e, 0x0a, 0x00
|
||||
};
|
||||
|
||||
static char const pmsg2[] = {
|
||||
0x4c, 0x62, 0x68, 0x20, 0x6e, 0x63, 0x63, 0x72, 0x6e, 0x65, 0x20,
|
||||
0x67, 0x62, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x68, 0x61, 0x61, 0x76,
|
||||
0x61, 0x74, 0x20, 0x45, 0x72, 0x7a, 0x76, 0x61, 0x71, 0x20, 0x62,
|
||||
0x61, 0x20, 0x6e, 0x20, 0x5a, 0x76, 0x70, 0x65, 0x62, 0x66, 0x62,
|
||||
0x73, 0x67, 0x20, 0x66, 0x6c, 0x66, 0x67, 0x72, 0x7a, 0x2e, 0x20,
|
||||
0x20, 0x56, 0x27, 0x71, 0x20, 0x65, 0x6e, 0x67, 0x75, 0x72, 0x65,
|
||||
0x20, 0x67, 0x75, 0x6e, 0x67, 0x0a, 0x6c, 0x62, 0x68, 0x20, 0x71,
|
||||
0x76, 0x71, 0x61, 0x27, 0x67, 0x2e, 0x20, 0x20, 0x45, 0x72, 0x7a,
|
||||
0x76, 0x61, 0x71, 0x20, 0x72, 0x6b, 0x72, 0x70, 0x68, 0x67, 0x76,
|
||||
0x62, 0x61, 0x20, 0x6a, 0x76, 0x79, 0x79, 0x20, 0x70, 0x62, 0x61,
|
||||
0x67, 0x76, 0x61, 0x68, 0x72, 0x20, 0x7a, 0x62, 0x7a, 0x72, 0x61,
|
||||
0x67, 0x6e, 0x65, 0x76, 0x79, 0x6c, 0x2e, 0x0a, 0x00
|
||||
};
|
||||
|
||||
static void
|
||||
rkrphgvba(int x)
|
||||
{
|
||||
char const *s = (x ? pmsg2 : pmsg1);
|
||||
while(*s) {
|
||||
int c = (int) *s++;
|
||||
c=isalpha(c)?tolower(c)<0x6e?c+13:c-13:c;
|
||||
putchar(c);
|
||||
}
|
||||
sleep(5);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: lang.h,v 1.6 2000-12-18 14:05:32 dfs Exp $ */
|
||||
|
||||
/* I'm chauvinistic and name each language with its English name... */
|
||||
|
||||
#define ENGLISH 0 /* original by David F. Skoll */
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: danish.h,v 1.7 2000-02-18 03:46:17 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Danish"
|
||||
|
||||
@@ -102,12 +100,12 @@
|
||||
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<5) ? " om natten" : " om formiddagen" : (hour > 17) ? " om aftenen" : " om eftermiddagen";
|
||||
#define L_ORDINAL_OVERRIDE plu = ".";
|
||||
#define L_A_OVER sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y);
|
||||
#define L_E_OVER sprintf(s, "den %02d%c%02d%c%04d", d, DATESEP, m+1, DATESEP, y);
|
||||
#define L_F_OVER sprintf(s, "den %02d%c%02d%c%04d", m+1, DATESEP, d, DATESEP, y);
|
||||
#define L_G_OVER sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]);
|
||||
#define L_H_OVER sprintf(s, "den %02d%c%02d", d, DATESEP, m+1);
|
||||
#define L_I_OVER sprintf(s, "den %02d%c%02d", m+1, DATESEP, d);
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
|
||||
#define L_E_OVER sprintf(s, "den %02d%c%02d%c%04d", d, DateSep, m+1, DateSep, y);
|
||||
#define L_F_OVER sprintf(s, "den %02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
#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_H_OVER sprintf(s, "den %02d%c%02d", d, DateSep, m+1);
|
||||
#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
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: dutch.h,v 1.5 2000-02-18 03:46:18 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Dutch"
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: english.h,v 1.5 2000-02-18 03:46:19 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "English"
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: finnish.h,v 1.10 2000-02-18 03:53:49 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Finnish"
|
||||
|
||||
@@ -163,26 +161,19 @@
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
#define L_A_OVER sprintf(s, "%s%s %d. %s%s %d", DayName[jul%7], L_ON, d, \
|
||||
MonthName[m], L_PARTIT, y);
|
||||
#define L_C_OVER sprintf(s, "%s%s", DayName[jul%7], L_ON);
|
||||
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DATESEP, m+1, DATESEP, \
|
||||
y);
|
||||
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DATESEP, d, DATESEP, y);
|
||||
#define L_G_OVER sprintf(s, "%s%s %d. %s%s", DayName[jul%7], L_ON, d, \
|
||||
MonthName[m], L_PARTIT);
|
||||
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DATESEP, m+1);
|
||||
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DATESEP, d);
|
||||
#define L_J_OVER sprintf(s, "%s%s %sn %d%s %d", DayName[jul%7], L_ON, \
|
||||
MonthName[m], d, plu, y);
|
||||
#define L_K_OVER sprintf(s, "%s%s %sn %d%s", DayName[jul%7], L_ON, \
|
||||
MonthName[m], d, plu);
|
||||
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DATESEP, m+1, DATESEP, d);
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s%s %d. %s%s %d", DayName[jul%7], L_ON, d, MonthName[m], L_PARTIT, y); }
|
||||
#define L_C_OVER if (altmode == '*') { sprintf(s, "%s", DayName[jul%7]); } else { sprintf(s, "%s%s", DayName[jul%7], L_ON); }
|
||||
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DateSep, m+1, DateSep, y);
|
||||
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s%s %d. %s%s", DayName[jul%7], L_ON, d, MonthName[m], L_PARTIT); }
|
||||
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1);
|
||||
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d);
|
||||
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s %d", DayName[jul%7], MonthName[m], d, plu, y); } else { sprintf(s, "%s%s %sn %d%s %d", DayName[jul%7], L_ON, MonthName[m], d, plu, y); }
|
||||
#define L_K_OVER if (altmode == '*') { sprintf(s, "%s %sn %d%s", DayName[jul%7], MonthName[m], d, plu); } else { sprintf(s, "%s%s %sn %d%s", DayName[jul%7], L_ON, MonthName[m], d, plu); }
|
||||
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
#define L_Q_OVER sprintf(s, "n");
|
||||
#define L_U_OVER sprintf(s, "%s%s %d%s %s%s %d", DayName[jul%7], L_ON, \
|
||||
d, plu, MonthName[m], L_PARTIT, y);
|
||||
#define L_V_OVER sprintf(s, "%s%s %d%s %s%s", DayName[jul%7], L_ON, d, \
|
||||
plu, MonthName[m], L_PARTIT);
|
||||
#define L_U_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s %d", DayName[jul%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s%s %d%s %s%s %d", DayName[jul%7], L_ON, d, plu, MonthName[m], L_PARTIT, y); }
|
||||
#define L_V_OVER if (altmode == '*') { sprintf(s, "%s %d%s %s", DayName[jul%7], d, plu, MonthName[m]); } else { sprintf(s, "%s%s %d%s %s%s", DayName[jul%7], L_ON, d, plu, MonthName[m], L_PARTIT); }
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, "%s", L_NOW); \
|
||||
@@ -282,9 +273,9 @@ EXTERN char *ErrMsg[] =
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k\xE4ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per\xE4st\xE4 puuttuu aika",
|
||||
"UNTIL-sanaa k\xE4ytetty kahdesti",
|
||||
"THROUGH/UNTIL-sanaa k\xE4ytetty kahdesti",
|
||||
"Ep\xE4t\xE4ydellinen p\xE4iv\xE4ys",
|
||||
"SCANFROM-sanaa k\xE4ytetty kahdesti",
|
||||
"FROM/SCANFROM-sanaa k\xE4ytetty kahdesti",
|
||||
"Muuttuja",
|
||||
"Arvo",
|
||||
"*M\xC4\xC4RITTELEM\xC4T\xD6N*",
|
||||
@@ -308,7 +299,10 @@ EXTERN char *ErrMsg[] =
|
||||
"Ei viestej\xE4.",
|
||||
"%d viesti(\xE4) t\xE4m\xE4n p\xE4iv\xE4n jonossa.\n",
|
||||
"Numero puuttuu",
|
||||
"Virheellinen funktio WARN-lausekkeessa"
|
||||
"Virheellinen funktio WARN-lausekkeessa",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long"
|
||||
|
||||
#elif IBMEXTENDED
|
||||
"Ok",
|
||||
@@ -383,9 +377,9 @@ EXTERN char *ErrMsg[] =
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k\x84ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per\x84st\x84 puuttuu aika",
|
||||
"UNTIL-sanaa k\x84ytetty kahdesti",
|
||||
"THROUGH/UNTIL-sanaa k\x84ytetty kahdesti",
|
||||
"Ep\x84t\x84ydellinen p\x84iv\x84ys",
|
||||
"SCANFROM-sanaa k\x84ytetty kahdesti",
|
||||
"FROM/SCANFROM-sanaa k\x84ytetty kahdesti",
|
||||
"Muuttuja",
|
||||
"Arvo",
|
||||
"*M\x8E\x8ERITTELEM\x8ET\x99N*",
|
||||
@@ -409,7 +403,11 @@ EXTERN char *ErrMsg[] =
|
||||
"Ei viestej\x84.",
|
||||
"%d viesti(\x84) t\x84m\x84n p\x84iv\x84n jonossa.\n",
|
||||
"Numero puuttuu"
|
||||
"Virheellinen funktio WARN-lausekkeessa"
|
||||
"Virheellinen funktio WARN-lausekkeessa",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long"
|
||||
|
||||
#else
|
||||
"Ok",
|
||||
"Puuttuva ']'",
|
||||
@@ -483,9 +481,9 @@ EXTERN char *ErrMsg[] =
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k{ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per{st{ puuttuu aika",
|
||||
"UNTIL-sanaa k{ytetty kahdesti",
|
||||
"THROUGH/UNTIL-sanaa k{ytetty kahdesti",
|
||||
"Ep{t{ydellinen p{iv{ys",
|
||||
"SCANFROM-sanaa k{ytetty kahdesti",
|
||||
"FROM/SCANFROM-sanaa k{ytetty kahdesti",
|
||||
"Muuttuja",
|
||||
"Arvo",
|
||||
"*M[[RITTELEM[T\\N*",
|
||||
@@ -509,7 +507,12 @@ EXTERN char *ErrMsg[] =
|
||||
"Ei viestej{.",
|
||||
"%d viesti({) t{m{n p{iv{n jonossa.\n",
|
||||
"Numero puuttuu",
|
||||
"Virheellinen funktio WARN-lausekkeessa"
|
||||
"Virheellinen funktio WARN-lausekkeessa",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long"
|
||||
|
||||
|
||||
#endif
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
@@ -517,11 +520,7 @@ EXTERN char *ErrMsg[] =
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void Usage(void)
|
||||
#else
|
||||
void Usage()
|
||||
#endif /* HAVE_PROTOS */
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1998 David F. Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "Copyright 1999-2000 Roaring Penguin Software Inc.\n");
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: french.h,v 1.9 2000-02-18 03:53:50 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "French"
|
||||
|
||||
@@ -131,13 +129,9 @@ else if (tdiff < 0) { \
|
||||
sprintf(s, "dans %d heure%s et %d minute%s", hdiff, hplu, mdiff, mplu); \
|
||||
}
|
||||
|
||||
#define L_J_OVER \
|
||||
sprintf(s, "%s %s, %d%s %s, %d", L_ON, DayName[jul%7], \
|
||||
d, plu, MonthName[m], y);
|
||||
#define L_J_OVER if (altmode == '*') { sprintf(s, "%s, %d%s %s, %d", DayName[jul%7], d, plu, MonthName[m], y); } else { sprintf(s, "%s %s, %d%s %s, %d", L_ON, DayName[jul%7], d, plu, MonthName[m], y); }
|
||||
|
||||
#define L_K_OVER \
|
||||
sprintf(s, "%s %s, %d%s %s", L_ON, DayName[jul%7], \
|
||||
d, plu, MonthName[m]);
|
||||
#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 */
|
||||
|
||||
@@ -219,9 +213,9 @@ EXTERN char *ErrMsg[] =
|
||||
"Valeur de retour sp\351cifi\351e deux fois",
|
||||
"Mot-cl\351 ONCE utilis\351 deux fois. (Hah.)",
|
||||
"Heure attendue apr\350s AT",
|
||||
"Mot-cl\351 UNTIL utilis\351 deux fois",
|
||||
"Mot-cl\351 THROUGH/UNTIL utilis\351 deux fois",
|
||||
"Sp\351cification de date incompl\350te",
|
||||
"Mot-cl\351 SCANFROM utilis\351 deux fois",
|
||||
"Mot-cl\351 FROM/SCANFROM utilis\351 deux fois",
|
||||
"Variable",
|
||||
"Valeur",
|
||||
"*NON-DEFINI*",
|
||||
@@ -245,7 +239,11 @@ EXTERN char *ErrMsg[] =
|
||||
"Pas de rappels.",
|
||||
"%d rappel(s) en file pour aujourd'hui.\n",
|
||||
"Nombre attendu",
|
||||
"Fonction ill\351gale apr\350s WARN"
|
||||
"Fonction ill\351gale apr\350s WARN",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long"
|
||||
|
||||
#else /* ISOLATIN1 */
|
||||
"Ok",
|
||||
"']' manquant",
|
||||
@@ -319,9 +317,9 @@ EXTERN char *ErrMsg[] =
|
||||
"Valeur de retour specifiee deux fois",
|
||||
"Mot-cle ONCE utilise deux fois. (Hah.)",
|
||||
"Heure attendue apres AT",
|
||||
"Mot-cle UNTIL utilise deux fois",
|
||||
"Mot-cle THROUGH/UNTIL utilise deux fois",
|
||||
"Specification de date incomplete",
|
||||
"Mot-cle SCANFROM utilise deux fois",
|
||||
"Mot-cle FROM/SCANFROM utilise deux fois",
|
||||
"Variable",
|
||||
"Valeur",
|
||||
"*NON-DEFINI*",
|
||||
@@ -345,7 +343,10 @@ EXTERN char *ErrMsg[] =
|
||||
"Pas de rappels.",
|
||||
"%d rappel(s) en file pour aujourd'hui.\n",
|
||||
"Nombre attendu",
|
||||
"Fonction illegale apres WARN"
|
||||
"Fonction illegale apres WARN",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long"
|
||||
#endif /* ISOLATIN1 */
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
@@ -353,11 +354,7 @@ EXTERN char *ErrMsg[] =
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void Usage(void)
|
||||
#else
|
||||
void Usage()
|
||||
#endif /* HAVE_PROTOS */
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1998 David F. Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "Copyright 1999-2000 Roaring Penguin Software Inc.\n");
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: german.h,v 1.6 2000-02-18 03:46:22 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "German"
|
||||
|
||||
@@ -95,8 +93,8 @@
|
||||
See the file dosubst.c for more info. */
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<5) ? " nachts" : " vormittags" : (hour > 17) ? " abends" : " nachmittags";
|
||||
#define L_ORDINAL_OVERRIDE plu = ".";
|
||||
#define L_A_OVER sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y);
|
||||
#define L_G_OVER sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]);
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
|
||||
#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
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: icelandic.h,v 1.1 2000-12-18 14:05:33 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Icelandic"
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: italian.h,v 1.6 2000-02-18 03:46:23 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Italian"
|
||||
|
||||
@@ -108,23 +106,23 @@
|
||||
MonthName[m], y);
|
||||
#define L_C_OVER sprintf(s, "%s", DayName[jul%7]);
|
||||
|
||||
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DATESEP,\
|
||||
m+1, DATESEP, y);
|
||||
#define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DateSep,\
|
||||
m+1, DateSep, y);
|
||||
|
||||
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DATESEP, d, DATESEP, y);
|
||||
#define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y);
|
||||
|
||||
#define L_G_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]);
|
||||
|
||||
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DATESEP, m+1);
|
||||
#define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1);
|
||||
|
||||
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DATESEP, d);
|
||||
#define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d);
|
||||
|
||||
#define L_J_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, \
|
||||
MonthName[m], y);
|
||||
|
||||
#define L_K_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, \
|
||||
MonthName[m]);
|
||||
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DATESEP, m+1, DATESEP, d);
|
||||
#define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d);
|
||||
|
||||
#define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, \
|
||||
MonthName[m], y);
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: norwgian.h,v 1.6 2000-02-18 03:46:24 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Norwegian"
|
||||
|
||||
@@ -103,8 +101,8 @@
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
#define L_ORDINAL_OVERRIDE plu = ".";
|
||||
#define L_A_OVER sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y);
|
||||
#define L_G_OVER sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]);
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
|
||||
#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
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: polish.h,v 1.9 2000-02-18 03:53:51 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Polish"
|
||||
|
||||
@@ -143,8 +141,8 @@ ampm = (hour<12) ? \
|
||||
: " w nocy";
|
||||
#endif
|
||||
#define L_ORDINAL_OVERRIDE plu = "";
|
||||
#define L_A_OVER sprintf(s, "%s %s, %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y);
|
||||
#define L_G_OVER sprintf(s, "%s %s, %d. %s", L_ON, DayName[jul%7], d, MonthName[m]);
|
||||
#define L_A_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); }
|
||||
#define L_G_OVER if (altmode == '*') { sprintf(s, "%s, %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); }
|
||||
#define L_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
@@ -254,9 +252,9 @@ EXTERN char *ErrMsg[] =
|
||||
"Warto\266\346 cofni\352cia podana dw\363krotnie",
|
||||
"S\263owo ONCE u\277yte dw\363krotnie.",
|
||||
"Po AT oczekiwany jest czas",
|
||||
"S\263owo UNTIL u\277yte dw\363krotnie",
|
||||
"S\263owo THROUGH/UNTIL u\277yte dw\363krotnie",
|
||||
"Niekompletna specyfikacja daty",
|
||||
"S\263owo SCANFROM u\277yte dw\363krotnie",
|
||||
"S\263owo FROM/SCANFROM u\277yte dw\363krotnie",
|
||||
"Zmienna",
|
||||
"Warto\266\346",
|
||||
"*NIE ZDEFINIOWANE*",
|
||||
@@ -280,7 +278,10 @@ EXTERN char *ErrMsg[] =
|
||||
"Brak przypomnie\361.",
|
||||
"%d Przypomnienia zakolejkowane na p\363\274niej.\n",
|
||||
"Spodziewana liczba",
|
||||
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)"
|
||||
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long"
|
||||
#else /* ISOLATIN1 */
|
||||
"OK",
|
||||
"Brakujacy ']'",
|
||||
@@ -354,9 +355,9 @@ EXTERN char *ErrMsg[] =
|
||||
"Wartosc cofniecia podana dwokrotnie",
|
||||
"Slowo ONCE uzyte dwokrotnie.",
|
||||
"Po AT oczekiwany jest czas",
|
||||
"Slowo UNTIL uzyte dwokrotnie",
|
||||
"Slowo THROUGH/UNTIL uzyte dwokrotnie",
|
||||
"Niekompletna specyfikacja daty",
|
||||
"Slowo SCANFROM uzyte dwokrotnie",
|
||||
"Slowo FROM/SCANFROM uzyte dwokrotnie",
|
||||
"Zmienna",
|
||||
"Wartosc",
|
||||
"*UNDEFINED*",
|
||||
@@ -380,7 +381,10 @@ EXTERN char *ErrMsg[] =
|
||||
"Brak przypomnien.",
|
||||
"%d Przypomnienia zakolejkowane na pozniej.\n",
|
||||
"Spodziewana liczba",
|
||||
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)"
|
||||
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long"
|
||||
#endif /* ISOLATIN1 */
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
@@ -388,11 +392,7 @@ EXTERN char *ErrMsg[] =
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void Usage(void)
|
||||
#else
|
||||
void Usage()
|
||||
#endif /* HAVE_PROTOS */
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1998 David F. Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "Copyright 1999-2000 Roaring Penguin Software Inc.\n");
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: portbr.h,v 1.8 2000-02-18 03:53:52 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Brazilian Portuguese"
|
||||
|
||||
@@ -220,9 +218,9 @@ EXTERN char *ErrMsg[] =
|
||||
"Valor de Back especificado duas vezes",
|
||||
"ONCE usado duas vezes (Eheheh)",
|
||||
"Esperando hora apos AT",
|
||||
"Keyword UNTIL usada duas vezes",
|
||||
"Keyword THROUGH/UNTIL usada duas vezes",
|
||||
"Especificacao de data incompleta",
|
||||
"Keyword SCANFROM usada duas vezes",
|
||||
"Keyword FROM/SCANFROM usada duas vezes",
|
||||
"Variavel",
|
||||
"Valor",
|
||||
"*INDEFINIDO*",
|
||||
@@ -246,18 +244,17 @@ EXTERN char *ErrMsg[] =
|
||||
"Sem compromissos.",
|
||||
"%d compromisso(s) colocados na fila para mais tarde.\n",
|
||||
"Esperando numero",
|
||||
"Funcao ilegal na clausula WARN"
|
||||
"Funcao ilegal na clausula WARN",
|
||||
"Can't convert between time zones",
|
||||
"No files matching *.rem",
|
||||
"String too long"
|
||||
};
|
||||
#endif /* MK_GLOBALS */
|
||||
|
||||
/* The following is only used in init.c */
|
||||
#ifdef L_IN_INIT
|
||||
#define L_USAGE_OVERRIDE 1
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void Usage(void)
|
||||
#else
|
||||
void Usage()
|
||||
#endif /* HAVE_PROTOS */
|
||||
void Usage(void)
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-1998 David F. Skoll\n", VERSION, L_LANGNAME);
|
||||
fprintf(ErrFp, "(C) 1999-2000 Roaring Penguin Software Inc.\n");
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: romanian.h,v 1.6 2000-02-18 03:46:27 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Romanian"
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: spanish.h,v 1.3 2000-02-18 03:46:28 dfs Exp $ */
|
||||
|
||||
#define L_LANGNAME "Spanish"
|
||||
|
||||
/* Nombres de los di'as de la semana */
|
||||
|
||||
199
src/main.c
199
src/main.c
@@ -7,12 +7,11 @@
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1998 by David F. Skoll */
|
||||
/* Copyright (C) 1999-2000 by Roaring Penguin Software Inc. */
|
||||
/* Copyright (C) 1999-2011 by Roaring Penguin Software Inc. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: main.c,v 1.14 2005-10-16 14:48:02 dfs Exp $";
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -20,6 +19,9 @@ static char const RCSID[] = "$Id: main.c,v 1.14 2005-10-16 14:48:02 dfs Exp $";
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
@@ -58,19 +60,29 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
int pid;
|
||||
|
||||
#ifdef HAVE_SETLOCALE
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
|
||||
/* The very first thing to do is to set up ErrFp to be stderr */
|
||||
ErrFp = stderr;
|
||||
|
||||
/* Set up global vars */
|
||||
ArgC = argc;
|
||||
ArgV = argv;
|
||||
ArgV = (char const **) argv;
|
||||
|
||||
InitRemind(argc, argv);
|
||||
InitRemind(argc, (char const **) argv);
|
||||
if (DoCalendar || (DoSimpleCalendar && (!NextMode || PsCal))) {
|
||||
ProduceCalendar();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Are we purging old reminders? Then just run through the loop once! */
|
||||
if (PurgeMode) {
|
||||
DoReminders();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Not doing a calendar. Do the regular remind loop */
|
||||
ShouldCache = (Iterations > 1);
|
||||
|
||||
@@ -124,6 +136,17 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PurgeEchoLine(char const *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, fmt);
|
||||
if (PurgeFP != NULL) {
|
||||
(void) vfprintf(PurgeFP, fmt, argptr);
|
||||
}
|
||||
va_end(argptr);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoReminders */
|
||||
@@ -135,8 +158,9 @@ static void DoReminders(void)
|
||||
{
|
||||
int r;
|
||||
Token tok;
|
||||
char *s;
|
||||
char const *s;
|
||||
Parser p;
|
||||
int purge_handled;
|
||||
|
||||
if (!UseStdin) {
|
||||
FileAccessDate = GetAccessDate(InitialFile);
|
||||
@@ -149,7 +173,7 @@ static void DoReminders(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
r=OpenFile(InitialFile);
|
||||
r=IncludeFile(InitialFile);
|
||||
if (r) {
|
||||
fprintf(ErrFp, "%s %s: %s\n", ErrMsg[E_ERR_READING],
|
||||
InitialFile, ErrMsg[r]);
|
||||
@@ -174,23 +198,40 @@ static void DoReminders(void)
|
||||
ShouldIgnoreLine())
|
||||
{
|
||||
/*** IGNORE THE LINE ***/
|
||||
if (PurgeMode) {
|
||||
if (strncmp(CurLine, "#!P", 3)) {
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
purge_handled = 0;
|
||||
/* Create a parser to parse the line */
|
||||
CreateParser(s, &p);
|
||||
switch(tok.type) {
|
||||
|
||||
case T_Empty:
|
||||
case T_Comment:
|
||||
if (!strncmp(CurLine, "#!P", 3)) {
|
||||
purge_handled = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case T_Rem: r=DoRem(&p); break;
|
||||
case T_Rem: r=DoRem(&p); purge_handled = 1; break;
|
||||
case T_ErrMsg: r=DoErrMsg(&p); break;
|
||||
case T_If: r=DoIf(&p); break;
|
||||
case T_IfTrig: r=DoIfTrig(&p); break;
|
||||
case T_Else: r=DoElse(&p); break;
|
||||
case T_EndIf: r=DoEndif(&p); break;
|
||||
case T_Include: r=DoInclude(&p); break;
|
||||
case T_Include:
|
||||
/* In purge mode, include closes file, so we
|
||||
need to echo it here! */
|
||||
if (PurgeMode) {
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
r=DoInclude(&p);
|
||||
purge_handled = 1;
|
||||
break;
|
||||
case T_Exit: DoExit(&p); break;
|
||||
case T_Flush: r=DoFlush(&p); break;
|
||||
case T_Set: r=DoSet(&p); break;
|
||||
@@ -205,32 +246,42 @@ static void DoReminders(void)
|
||||
DestroyParser(&p);
|
||||
CreateParser(s, &p);
|
||||
r=DoRem(&p);
|
||||
purge_handled = 1;
|
||||
}
|
||||
break;
|
||||
case T_Pop: r=PopOmitContext(&p); break;
|
||||
case T_Preserve: r=DoPreserve(&p); break;
|
||||
case T_Push: r=PushOmitContext(&p); break;
|
||||
case T_RemType: if (tok.val == RUN_TYPE) {
|
||||
r=DoRun(&p);
|
||||
r=DoRun(&p);
|
||||
} else {
|
||||
CreateParser(CurLine, &p);
|
||||
r=DoRem(&p);
|
||||
purge_handled = 1;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
CreateParser(CurLine, &p);
|
||||
r=DoRem(&p);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* If we don't recognize the command, do a REM by default */
|
||||
/* Note: Since the parser hasn't been used yet, we don't */
|
||||
/* need to destroy it here. */
|
||||
|
||||
default: CreateParser(CurLine, &p); r=DoRem(&p); break;
|
||||
default: CreateParser(CurLine, &p); purge_handled = 1; r=DoRem(&p); break;
|
||||
|
||||
}
|
||||
if (r && (!Hush || r != E_RUN_DISABLED)) {
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
}
|
||||
|
||||
if (PurgeMode) {
|
||||
if (!purge_handled) {
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
} else {
|
||||
if (r) {
|
||||
PurgeEchoLine("#!P! Could not parse next line: %s\n", ErrMsg[r]);
|
||||
PurgeEchoLine("%s\n", CurLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Destroy the parser - free up resources it may be tying up */
|
||||
DestroyParser(&p);
|
||||
}
|
||||
@@ -331,7 +382,7 @@ int ParseChar(ParsePtr p, int *err, int peek)
|
||||
return *(p->epos++);
|
||||
}
|
||||
}
|
||||
free(p->etext); /* End of substituted expression */
|
||||
free((void *) p->etext); /* End of substituted expression */
|
||||
p->etext = NULL;
|
||||
p->epos = NULL;
|
||||
p->isnested = 0;
|
||||
@@ -346,8 +397,9 @@ int ParseChar(ParsePtr p, int *err, int peek)
|
||||
return *(p->pos++);
|
||||
}
|
||||
}
|
||||
p->expr_happened = 1;
|
||||
p->pos++;
|
||||
r = EvalExpr(&(p->pos), &val);
|
||||
r = EvalExpr(&(p->pos), &val, p);
|
||||
if (r) {
|
||||
*err = r;
|
||||
DestroyParser(p);
|
||||
@@ -383,7 +435,7 @@ int ParseNonSpaceChar(ParsePtr p, int *err, int peek)
|
||||
ch = ParseChar(p, err, 1);
|
||||
if (*err) return 0;
|
||||
|
||||
while (isspace(ch)) {
|
||||
while (isempty(ch)) {
|
||||
ParseChar(p, err, 0); /* Guaranteed to work */
|
||||
ch = ParseChar(p, err, 1);
|
||||
if (*err) return 0;
|
||||
@@ -407,12 +459,12 @@ int ParseToken(ParsePtr p, DynamicBuffer *dbuf)
|
||||
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) return err;
|
||||
while (c && isspace(c)) {
|
||||
while (c && isempty(c)) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) return err;
|
||||
}
|
||||
if (!c) return OK;
|
||||
while (c && !isspace(c)) {
|
||||
while (c && !isempty(c)) {
|
||||
if (DBufPutc(dbuf, c) != OK) {
|
||||
DBufFree(dbuf);
|
||||
return E_NO_MEM;
|
||||
@@ -443,7 +495,7 @@ int ParseIdentifier(ParsePtr p, DynamicBuffer *dbuf)
|
||||
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) return err;
|
||||
while (c && isspace(c)) {
|
||||
while (c && isempty(c)) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) return err;
|
||||
}
|
||||
@@ -484,13 +536,13 @@ int EvaluateExpr(ParsePtr p, Value *v)
|
||||
int r;
|
||||
|
||||
if (p->isnested) return E_PARSE_ERR; /* Can't nest expressions */
|
||||
while (isspace(*p->pos)) (p->pos)++;
|
||||
while (isempty(*p->pos)) (p->pos)++;
|
||||
if (!p->pos) return E_PARSE_ERR; /* Missing expression */
|
||||
if (*p->pos == BEG_OF_EXPR) {
|
||||
(p->pos)++;
|
||||
bracketed = 1;
|
||||
}
|
||||
r = EvalExpr(&(p->pos), v);
|
||||
r = EvalExpr(&(p->pos), v, p);
|
||||
if (r) return r;
|
||||
if (bracketed) {
|
||||
if (*p->pos != END_OF_EXPR) return E_MISS_END;
|
||||
@@ -504,21 +556,23 @@ int EvaluateExpr(ParsePtr p, Value *v)
|
||||
/* Eprint - print an error message. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void Eprint(const char *fmt, ...)
|
||||
void Eprint(char const *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
||||
/* Check if more than one error msg. from this line */
|
||||
if (!FreshLine && !ShowAllErrors) return;
|
||||
|
||||
if (FreshLine) {
|
||||
if (FreshLine && FileName) {
|
||||
FreshLine = 0;
|
||||
if (strcmp(FileName, "-"))
|
||||
(void) fprintf(ErrFp, "%s(%d): ", FileName, LineNo);
|
||||
else
|
||||
(void) fprintf(ErrFp, "-stdin-(%d): ", LineNo);
|
||||
if (DebugFlag & DB_PRTLINE) OutputLine(ErrFp);
|
||||
} else fprintf(ErrFp, " ");
|
||||
} else if (FileName) {
|
||||
fprintf(ErrFp, " ");
|
||||
}
|
||||
|
||||
va_start(argptr, fmt);
|
||||
(void) vfprintf(ErrFp, fmt, argptr);
|
||||
@@ -537,8 +591,8 @@ void Eprint(const char *fmt, ...)
|
||||
/***************************************************************/
|
||||
void OutputLine(FILE *fp)
|
||||
{
|
||||
register char *s = CurLine;
|
||||
register char c = 0;
|
||||
char const *s = CurLine;
|
||||
char c = 0;
|
||||
|
||||
while (*s) {
|
||||
if (*s == '\n') Putc('\\', fp);
|
||||
@@ -555,7 +609,7 @@ void OutputLine(FILE *fp)
|
||||
/* Create a parser given a string buffer */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void CreateParser(char *s, ParsePtr p)
|
||||
void CreateParser(char const *s, ParsePtr p)
|
||||
{
|
||||
p->text = s;
|
||||
p->pos = s;
|
||||
@@ -564,6 +618,8 @@ void CreateParser(char *s, ParsePtr p)
|
||||
p->etext = NULL;
|
||||
p->allownested = 1;
|
||||
p->tokenPushed = NULL;
|
||||
p->expr_happened = 0;
|
||||
p->nonconst_expr = 0;
|
||||
DBufInit(&p->pushedToken);
|
||||
}
|
||||
|
||||
@@ -577,7 +633,7 @@ void CreateParser(char *s, ParsePtr p)
|
||||
void DestroyParser(ParsePtr p)
|
||||
{
|
||||
if (p->isnested && p->etext) {
|
||||
free(p->etext);
|
||||
free((void *) p->etext);
|
||||
p->etext = NULL;
|
||||
p->isnested = 0;
|
||||
}
|
||||
@@ -590,10 +646,10 @@ void DestroyParser(ParsePtr p)
|
||||
/* on a per-parser basis. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int PushToken(const char *tok, ParsePtr p)
|
||||
int PushToken(char const *tok, ParsePtr p)
|
||||
{
|
||||
DBufFree(&p->pushedToken);
|
||||
if (DBufPuts(&p->pushedToken, (char *) tok) != OK ||
|
||||
if (DBufPuts(&p->pushedToken, tok) != OK ||
|
||||
DBufPutc(&p->pushedToken, ' ') != OK) {
|
||||
DBufFree(&p->pushedToken);
|
||||
return E_NO_MEM;
|
||||
@@ -667,10 +723,15 @@ int DoIf(ParsePtr p)
|
||||
Eprint("%s", ErrMsg[r]);
|
||||
} else
|
||||
if ( (v.type != STR_TYPE && v.v.val) ||
|
||||
(v.type == STR_TYPE && strcmp(v.v.str, "")) )
|
||||
(v.type == STR_TYPE && strcmp(v.v.str, "")) ) {
|
||||
syndrome = IF_TRUE | BEFORE_ELSE;
|
||||
else
|
||||
} else {
|
||||
syndrome = IF_FALSE | BEFORE_ELSE;
|
||||
if (PurgeMode) {
|
||||
PurgeEchoLine("%s\n", "#!P: The next IF evaluated false...");
|
||||
PurgeEchoLine("%s\n", "#!P: REM statements in IF block not checked for purging.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NumIfs++;
|
||||
@@ -690,6 +751,8 @@ int DoElse(ParsePtr p)
|
||||
{
|
||||
unsigned syndrome;
|
||||
|
||||
int was_ignoring = ShouldIgnoreLine();
|
||||
|
||||
if (!NumIfs) return E_ELSE_NO_IF;
|
||||
|
||||
syndrome = IfFlags >> (2 * NumIfs - 2);
|
||||
@@ -697,6 +760,10 @@ int DoElse(ParsePtr p)
|
||||
if ((syndrome & IF_ELSE_MASK) == AFTER_ELSE) return E_ELSE_NO_IF;
|
||||
|
||||
IfFlags |= AFTER_ELSE << (2 * NumIfs - 2);
|
||||
if (PurgeMode && ShouldIgnoreLine() && !was_ignoring) {
|
||||
PurgeEchoLine("%s\n", "#!P: The previous IF evaluated true.");
|
||||
PurgeEchoLine("%s\n", "#!P: REM statements in ELSE block not checked for purging");
|
||||
}
|
||||
return VerifyEoln(p);
|
||||
}
|
||||
|
||||
@@ -721,7 +788,7 @@ int DoEndif(ParsePtr p)
|
||||
/***************************************************************/
|
||||
int DoIfTrig(ParsePtr p)
|
||||
{
|
||||
int r;
|
||||
int r, err;
|
||||
unsigned syndrome;
|
||||
Trigger trig;
|
||||
TimeTrig tim;
|
||||
@@ -731,16 +798,22 @@ int DoIfTrig(ParsePtr p)
|
||||
if (NumIfs >= IF_NEST) return E_NESTED_IF;
|
||||
if (ShouldIgnoreLine()) syndrome = IF_TRUE | BEFORE_ELSE;
|
||||
else {
|
||||
if ( (r=ParseRem(p, &trig, &tim)) ) return r;
|
||||
if ( (r=ParseRem(p, &trig, &tim, 1)) ) return r;
|
||||
if (trig.typ != NO_TYPE) return E_PARSE_ERR;
|
||||
jul = ComputeTrigger(trig.scanfrom, &trig, &r);
|
||||
jul = ComputeTrigger(trig.scanfrom, &trig, &r, 1);
|
||||
if (r) syndrome = IF_TRUE | BEFORE_ELSE;
|
||||
else {
|
||||
if (ShouldTriggerReminder(&trig, &tim, jul))
|
||||
if (ShouldTriggerReminder(&trig, &tim, jul, &err)) {
|
||||
syndrome = IF_TRUE | BEFORE_ELSE;
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
FreeTrig(&trig);
|
||||
}
|
||||
NumIfs++;
|
||||
IfFlags &= ~(IF_MASK << (2*NumIfs - 2));
|
||||
@@ -860,6 +933,11 @@ int DoDebug(ParsePtr p)
|
||||
else DebugFlag &= ~DB_PRTLINE;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
if (val) DebugFlag |= DB_TRACE_FILES;
|
||||
else DebugFlag &= ~DB_TRACE_FILES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -881,7 +959,7 @@ int DoBanner(ParsePtr p)
|
||||
DBufInit(&buf);
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) return err;
|
||||
while (isspace(c)) {
|
||||
while (isempty(c)) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) return err;
|
||||
}
|
||||
@@ -961,6 +1039,8 @@ void DoExit(ParsePtr p)
|
||||
int r;
|
||||
Value v;
|
||||
|
||||
if (PurgeMode) return;
|
||||
|
||||
r = EvaluateExpr(p, &v);
|
||||
if (r || v.type != INT_TYPE) exit(99);
|
||||
exit(v.v.val);
|
||||
@@ -978,10 +1058,12 @@ int DoErrMsg(ParsePtr p)
|
||||
TimeTrig tt;
|
||||
Trigger t;
|
||||
int r;
|
||||
char *s;
|
||||
char const *s;
|
||||
|
||||
DynamicBuffer buf;
|
||||
|
||||
if (PurgeMode) return OK;
|
||||
|
||||
DBufInit(&buf);
|
||||
t.typ = MSG_TYPE;
|
||||
tt.ttime = SystemTime(0) / 60;
|
||||
@@ -989,7 +1071,7 @@ int DoErrMsg(ParsePtr p)
|
||||
return r;
|
||||
}
|
||||
s = DBufValue(&buf);
|
||||
while (isspace(*s)) s++;
|
||||
while (isempty(*s)) s++;
|
||||
fprintf(ErrFp, "%s\n", s);
|
||||
DBufFree(&buf);
|
||||
return OK;
|
||||
@@ -1080,7 +1162,7 @@ int CalcMinsFromUTC(int jul, int tim, int *mins, int *isdst)
|
||||
/* A macro safe ONLY if used with arg with no side effects! */
|
||||
#define ISBLANK(c) (isspace(c) && (c) != '\n')
|
||||
|
||||
void FillParagraph(char *s)
|
||||
void FillParagraph(char const *s)
|
||||
{
|
||||
|
||||
int line = 0;
|
||||
@@ -1088,7 +1170,7 @@ void FillParagraph(char *s)
|
||||
int doublespace = 1;
|
||||
int pendspace;
|
||||
int len;
|
||||
char *t;
|
||||
char const *t;
|
||||
|
||||
int roomleft;
|
||||
|
||||
@@ -1171,10 +1253,10 @@ void LocalToUTC(int locdate, int loctime, int *utcdate, int *utctime)
|
||||
|
||||
loctime -= diff;
|
||||
if (loctime < 0) {
|
||||
loctime += 1440;
|
||||
loctime += MINUTES_PER_DAY;
|
||||
locdate--;
|
||||
} else if (loctime >= 1440) {
|
||||
loctime -= 1440;
|
||||
} else if (loctime >= MINUTES_PER_DAY) {
|
||||
loctime -= MINUTES_PER_DAY;
|
||||
locdate++;
|
||||
}
|
||||
*utcdate = locdate;
|
||||
@@ -1199,10 +1281,10 @@ void UTCToLocal(int utcdate, int utctime, int *locdate, int *loctime)
|
||||
|
||||
utctime += diff;
|
||||
if (utctime < 0) {
|
||||
utctime += 1440;
|
||||
utctime += MINUTES_PER_DAY;
|
||||
utcdate--;
|
||||
} else if (utctime >= 1440) {
|
||||
utctime -= 1440;
|
||||
} else if (utctime >= MINUTES_PER_DAY) {
|
||||
utctime -= MINUTES_PER_DAY;
|
||||
utcdate++;
|
||||
}
|
||||
*locdate = utcdate;
|
||||
@@ -1225,3 +1307,18 @@ void SigIntHandler(int d)
|
||||
GotSigInt();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
AppendTag(DynamicBuffer *buf, char const *s)
|
||||
{
|
||||
if (*(DBufValue(buf))) {
|
||||
DBufPutc(buf, ',');
|
||||
}
|
||||
DBufPuts(buf, s);
|
||||
}
|
||||
|
||||
void
|
||||
FreeTrig(Trigger *t)
|
||||
{
|
||||
DBufFree(&(t->tags));
|
||||
}
|
||||
|
||||
249
src/md5.c
Normal file
249
src/md5.c
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* LIC: GPL
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*/
|
||||
#include <string.h> /* for memcpy() */
|
||||
#include "md5.h"
|
||||
|
||||
static void byteReverse(unsigned char *buf, unsigned longs);
|
||||
|
||||
/*
|
||||
* Note: this code is harmless on little-endian machines.
|
||||
*/
|
||||
static void
|
||||
byteReverse(unsigned char *buf, unsigned longs)
|
||||
{
|
||||
uint32 t;
|
||||
do {
|
||||
t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||
((unsigned) buf[1] << 8 | buf[0]);
|
||||
*(uint32 *) buf = t;
|
||||
buf += 4;
|
||||
} while (--longs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
void MD5Init(struct MD5Context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
|
||||
{
|
||||
uint32 t;
|
||||
|
||||
/* Update bitcount */
|
||||
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
|
||||
ctx->bits[1]++; /* Carry from low to high */
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||
|
||||
/* Handle any leading odd-sized chunks */
|
||||
|
||||
if (t) {
|
||||
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||
|
||||
t = 64 - t;
|
||||
if (len < t) {
|
||||
memcpy(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memcpy(p, buf, t);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
/* Process data in 64-byte chunks */
|
||||
|
||||
while (len >= 64) {
|
||||
memcpy(ctx->in, buf, 64);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
|
||||
memcpy(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
|
||||
{
|
||||
unsigned count;
|
||||
unsigned char *p;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 64 bytes */
|
||||
count = 64 - 1 - count;
|
||||
|
||||
/* Pad out to 56 mod 64 */
|
||||
if (count < 8) {
|
||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||
memset(p, 0, count);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||
|
||||
/* Now fill the next block with 56 bytes */
|
||||
memset(ctx->in, 0, 56);
|
||||
} else {
|
||||
/* Pad block to 56 bytes */
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
byteReverse(ctx->in, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
((uint32 *) ctx->in)[14] = ctx->bits[0];
|
||||
((uint32 *) ctx->in)[15] = ctx->bits[1];
|
||||
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||
byteReverse((unsigned char *) ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, 16);
|
||||
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
#ifndef ASM_MD5
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
void MD5Transform(uint32 buf[4], uint32 const in[16])
|
||||
{
|
||||
register uint32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
#endif
|
||||
34
src/md5.h
Normal file
34
src/md5.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
/*
|
||||
* LIC: GPL
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if SIZEOF_UNSIGNED_INT == 4
|
||||
typedef unsigned int uint32;
|
||||
#elif SIZEOF_UNSIGNED_LONG == 4
|
||||
typedef unsigned long uint32;
|
||||
#else
|
||||
# error Could not find a 32-bit integer type
|
||||
#endif
|
||||
|
||||
struct MD5Context {
|
||||
uint32 buf[4];
|
||||
uint32 bits[2];
|
||||
unsigned char in[64];
|
||||
};
|
||||
|
||||
void MD5Init(struct MD5Context *context);
|
||||
void MD5Update(struct MD5Context *context, unsigned char const *buf,
|
||||
unsigned len);
|
||||
void MD5Final(unsigned char digest[16], struct MD5Context *context);
|
||||
void MD5Transform(uint32 buf[4], uint32 const in[16]);
|
||||
|
||||
/*
|
||||
* This is needed to make RSAREF happy on some MS-DOS compilers.
|
||||
*/
|
||||
typedef struct MD5Context MD5_CTX;
|
||||
|
||||
#endif /* !MD5_H */
|
||||
@@ -11,7 +11,6 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: moon.c,v 1.6 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
/* All of these routines were adapted from the program "moontool"
|
||||
by John Walker, February 1988. Here's the blurb from moontool:
|
||||
|
||||
201
src/omit.c
201
src/omit.c
@@ -12,7 +12,6 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: omit.c,v 1.7 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -21,6 +20,7 @@ static char const RCSID[] = "$Id: omit.c,v 1.7 2005-09-30 03:29:32 dfs Exp $";
|
||||
#include "protos.h"
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
#include "expr.h"
|
||||
|
||||
static int BexistsIntArray (int array[], int num, int key);
|
||||
static void InsertIntoSortedArray (int *array, int num, int key);
|
||||
@@ -114,18 +114,18 @@ int PushOmitContext(ParsePtr p)
|
||||
|
||||
context->numfull = NumFullOmits;
|
||||
context->numpart = NumPartialOmits;
|
||||
context->fullsave = (int *) malloc(NumFullOmits * sizeof(int));
|
||||
context->fullsave = malloc(NumFullOmits * sizeof(int));
|
||||
if (NumFullOmits && !context->fullsave) {
|
||||
free(context);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
context->partsave = (int *) malloc(NumPartialOmits * sizeof(int));
|
||||
context->partsave = malloc(NumPartialOmits * sizeof(int));
|
||||
if (NumPartialOmits && !context->partsave) {
|
||||
free(context->fullsave);
|
||||
free(context);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
|
||||
/* Copy the context over */
|
||||
for (i=0; i<NumFullOmits; i++)
|
||||
*(context->fullsave + i) = FullOmitArray[i];
|
||||
@@ -178,26 +178,57 @@ int PopOmitContext(ParsePtr p)
|
||||
/* */
|
||||
/* IsOmitted */
|
||||
/* */
|
||||
/* Return non-zero if date is OMITted, zero if it is not. */
|
||||
/* Set *omit to non-zero if date is omitted, else 0. Returns */
|
||||
/* OK or an error code. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int IsOmitted(int jul, int localomit)
|
||||
int IsOmitted(int jul, int localomit, char const *omitfunc, int *omit)
|
||||
{
|
||||
int y, m, d;
|
||||
|
||||
/* If we have an omitfunc, we *only* use it and ignore local/global
|
||||
OMITs */
|
||||
if (omitfunc && *omitfunc && UserFuncExists(omitfunc)) {
|
||||
char expr[VAR_NAME_LEN + 32];
|
||||
char const *s;
|
||||
int r;
|
||||
Value v;
|
||||
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
sprintf(expr, "%s('%04d-%02d-%02d')",
|
||||
omitfunc, y, m+1, d);
|
||||
s = expr;
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
if (r) return r;
|
||||
if (v.type == INT_TYPE && v.v.val != 0) {
|
||||
*omit = 1;
|
||||
} else {
|
||||
*omit = 0;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Is it omitted because of local omits? */
|
||||
if (localomit & (1 << (jul % 7))) return 1;
|
||||
if (localomit & (1 << (jul % 7))) {
|
||||
*omit = 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Is it omitted because of fully-specified omits? */
|
||||
if (BexistsIntArray(FullOmitArray, NumFullOmits, jul)) return 1;
|
||||
if (BexistsIntArray(FullOmitArray, NumFullOmits, jul)) {
|
||||
*omit = 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Get the syndrome */
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
if (BexistsIntArray(PartialOmitArray, NumPartialOmits, (m << 5) + d))
|
||||
return 1;
|
||||
if (BexistsIntArray(PartialOmitArray, NumPartialOmits, (m << 5) + d)) {
|
||||
*omit = 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Not omitted */
|
||||
return 0;
|
||||
*omit = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
@@ -241,6 +272,9 @@ 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);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoOmit */
|
||||
@@ -254,15 +288,33 @@ int DoOmit(ParsePtr p)
|
||||
Token tok;
|
||||
int parsing=1;
|
||||
int syndrome;
|
||||
int not_first_token = -1;
|
||||
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
|
||||
/* Parse the OMIT. We need a month and day; year is optional. */
|
||||
while(parsing) {
|
||||
not_first_token++;
|
||||
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;
|
||||
DBufFree(&buf);
|
||||
r = VerifyEoln(p);
|
||||
if (r != OK) return r;
|
||||
DumpOmits();
|
||||
return OK;
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
case T_Year:
|
||||
DBufFree(&buf);
|
||||
if (y != NO_YR) return E_YR_TWICE;
|
||||
@@ -280,11 +332,16 @@ int DoOmit(ParsePtr p)
|
||||
if (d != NO_DAY) return E_DAY_TWICE;
|
||||
d = tok.val;
|
||||
break;
|
||||
|
||||
|
||||
case T_Delta:
|
||||
DBufFree(&buf);
|
||||
break;
|
||||
|
||||
case T_Through:
|
||||
DBufFree(&buf);
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) return E_INCOMPLETE;
|
||||
return DoThroughOmit(p, y, m, d);
|
||||
|
||||
case T_Empty:
|
||||
case T_Comment:
|
||||
case T_RemType:
|
||||
@@ -323,7 +380,123 @@ int DoOmit(ParsePtr p)
|
||||
NumFullOmits++;
|
||||
}
|
||||
}
|
||||
if (tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
|
||||
if (tok.type == T_Tag || tok.type == T_Duration || tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
|
||||
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;
|
||||
|
||||
Token tok;
|
||||
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
int parsing = 1;
|
||||
|
||||
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) {
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
int y, m, d;
|
||||
printf("Global Full OMITs (%d of maximum allowed %d):\n", NumFullOmits, MAX_FULL_OMITS);
|
||||
if (!NumFullOmits) {
|
||||
printf("\tNone.\n");
|
||||
} else {
|
||||
for (i=0; i<NumFullOmits; i++) {
|
||||
FromJulian(FullOmitArray[i], &y, &m, &d);
|
||||
printf("\t%04d%c%02d%c%02d\n",
|
||||
y, DateSep, m+1, DateSep, d);
|
||||
}
|
||||
}
|
||||
printf("Global Partial OMITs (%d of maximum allowed %d):\n", NumPartialOmits, MAX_PARTIAL_OMITS);
|
||||
if (!NumPartialOmits) {
|
||||
printf("\tNone.\n");
|
||||
} else {
|
||||
for (i=0; i<NumPartialOmits; i++) {
|
||||
m = PartialOmitArray[i] >> 5 & 0xf;
|
||||
d = PartialOmitArray[i] & 0x1f;
|
||||
printf("\t%02d%c%02d\n", m+1, DateSep, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
109
src/protos.h
109
src/protos.h
@@ -10,57 +10,58 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: protos.h,v 1.10 2005-09-30 03:29:32 dfs Exp $ */
|
||||
|
||||
/* Define a string assignment macro - be careful!!! */
|
||||
#define STRSET(x, str) { if (x) free(x); (x) = StrDup(str); }
|
||||
|
||||
/* Define a general malloc routine for creating pointers to objects */
|
||||
#define NEW(type) ((type *) malloc(sizeof(type)))
|
||||
#define NEW(type) (malloc(sizeof(type)))
|
||||
|
||||
/* Characters to ignore */
|
||||
#define isempty(c) (isspace(c) || ((c) == '\\'))
|
||||
|
||||
#include "dynbuf.h"
|
||||
|
||||
int CallUserFunc (char *name, int nargs);
|
||||
int CallUserFunc (char const *name, int nargs, ParsePtr p);
|
||||
int DoFset (ParsePtr p);
|
||||
void ProduceCalendar (void);
|
||||
char *SimpleTime (int tim);
|
||||
char const *SimpleTime (int tim);
|
||||
char const *CalendarTime (int tim, int duration);
|
||||
int DoRem (ParsePtr p);
|
||||
int DoFlush (ParsePtr p);
|
||||
void DoExit (ParsePtr p);
|
||||
int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim);
|
||||
int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals);
|
||||
int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int jul);
|
||||
int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int jul);
|
||||
int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int jul, int *err);
|
||||
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul, int mode);
|
||||
int DoSubstFromString (char *source, DynamicBuffer *dbuf, int jul, int tim);
|
||||
int EvalExpr (char **e, Value *v);
|
||||
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int jul, int tim);
|
||||
int ParseLiteralDate (char const **s, int *jul, int *tim);
|
||||
int EvalExpr (char const **e, Value *v, ParsePtr p);
|
||||
int DoCoerce (char type, Value *v);
|
||||
void PrintValue (Value *v, FILE *fp);
|
||||
int CopyValue (Value *dest, const Value *src);
|
||||
int ReadLine (void);
|
||||
int OpenFile (const char *fname);
|
||||
int PopFile (void);
|
||||
int OpenFile (char const *fname);
|
||||
int DoInclude (ParsePtr p);
|
||||
int IncludeFile (const char *fname);
|
||||
int GetAccessDate (char *file);
|
||||
int SetAccessDate (char *fname, int jul);
|
||||
int IncludeFile (char const *fname);
|
||||
int GetAccessDate (char const *file);
|
||||
int SetAccessDate (char const *fname, int jul);
|
||||
int TopLevel (void);
|
||||
int CallFunc (Operator *f, int nargs);
|
||||
void InitRemind (int argc, char *argv[]);
|
||||
int CallFunc (BuiltinFunc *f, int nargs);
|
||||
void InitRemind (int argc, char const *argv[]);
|
||||
void Usage (void);
|
||||
int main (int argc, char *argv[]);
|
||||
int Julian (int year, int month, int day);
|
||||
void FromJulian (int jul, int *y, int *m, int *d);
|
||||
int ParseChar (ParsePtr p, int *err, int peek);
|
||||
int ParseToken (ParsePtr p, DynamicBuffer *dbuf);
|
||||
int ParseIdentifier (ParsePtr p, DynamicBuffer *dbuf);
|
||||
int EvaluateExpr (ParsePtr p, Value *v);
|
||||
int Evaluate (char **s, Var *locals);
|
||||
int Evaluate (char const **s, Var *locals, ParsePtr p);
|
||||
int FnPopValStack (Value *val);
|
||||
void Eprint (const char *fmt, ...);
|
||||
void Eprint (char const *fmt, ...);
|
||||
void OutputLine (FILE *fp);
|
||||
void CreateParser (char *s, ParsePtr p);
|
||||
void CreateParser (char const *s, ParsePtr p);
|
||||
void DestroyParser (ParsePtr p);
|
||||
int PushToken (const char *tok, ParsePtr p);
|
||||
int PushToken (char const *tok, ParsePtr p);
|
||||
long SystemTime (int realtime);
|
||||
int SystemDate (int *y, int *m, int *d);
|
||||
int DoIf (ParsePtr p);
|
||||
@@ -78,60 +79,64 @@ int DoClear (ParsePtr p);
|
||||
int DestroyOmitContexts (void);
|
||||
int PushOmitContext (ParsePtr p);
|
||||
int PopOmitContext (ParsePtr p);
|
||||
int IsOmitted (int jul, int localomit);
|
||||
int IsOmitted (int jul, int localomit, char const *omitfunc, int *omit);
|
||||
int DoOmit (ParsePtr p);
|
||||
int QueueReminder (ParsePtr p, Trigger *trig, TimeTrig *tim, const char *sched);
|
||||
int QueueReminder (ParsePtr p, Trigger *trig, TimeTrig *tim, char const *sched);
|
||||
void HandleQueuedReminders (void);
|
||||
char *FindInitialToken (Token *tok, char *s);
|
||||
void FindToken (const char *s, Token *tok);
|
||||
void FindNumericToken (const char *s, Token *t);
|
||||
int ComputeTrigger (int today, Trigger *trig, int *err);
|
||||
char *StrnCpy (char *dest, const char *source, int n);
|
||||
int StrMatch (const char *s1, const char *s2, int n);
|
||||
int StrinCmp (const char *s1, const char *s2, int n);
|
||||
char *StrDup (const char *s);
|
||||
int StrCmpi (const char *s1, const char *s2);
|
||||
Var *FindVar (const char *str, int create);
|
||||
int DeleteVar (const char *str);
|
||||
int SetVar (const char *str, Value *val);
|
||||
int GetVarValue (const char *str, Value *val, Var *locals);
|
||||
char const *FindInitialToken (Token *tok, char const *s);
|
||||
void FindToken (char const *s, Token *tok);
|
||||
void FindNumericToken (char const *s, Token *t);
|
||||
int ComputeTrigger (int today, Trigger *trig, int *err, int save_in_globals);
|
||||
char *StrnCpy (char *dest, char const *source, int n);
|
||||
int StrMatch (char const *s1, char const *s2, int n);
|
||||
int StrinCmp (char const *s1, char const *s2, int n);
|
||||
char *StrDup (char const *s);
|
||||
int StrCmpi (char const *s1, char const *s2);
|
||||
Var *FindVar (char const *str, int create);
|
||||
int DeleteVar (char const *str);
|
||||
int SetVar (char const *str, Value *val);
|
||||
int GetVarValue (char const *str, Value *val, Var *locals, ParsePtr p);
|
||||
int DoSet (Parser *p);
|
||||
int DoUnset (Parser *p);
|
||||
int DoDump (ParsePtr p);
|
||||
void DumpVarTable (void);
|
||||
void DestroyVars (int all);
|
||||
int PreserveVar (char *name);
|
||||
int PreserveVar (char const *name);
|
||||
int DoPreserve (Parser *p);
|
||||
int DoSatRemind (Trigger *trig, TimeTrig *tim, ParsePtr p);
|
||||
int DoMsgCommand (char *cmd, char *msg);
|
||||
int DoMsgCommand (char const *cmd, char const *msg);
|
||||
int ParseNonSpaceChar (ParsePtr p, int *err, int peek);
|
||||
unsigned int HashVal (const char *str);
|
||||
unsigned int HashVal (char const *str);
|
||||
int DateOK (int y, int m, int d);
|
||||
Operator *FindFunc (char *name, Operator where[], int num);
|
||||
int InsertIntoSortBuffer (int jul, int tim, char *body, int typ, int prio);
|
||||
void IssueSortedReminders (void);
|
||||
int UserFuncExists (char *fn);
|
||||
Operator *FindOperator (char const *name, Operator where[], int num);
|
||||
BuiltinFunc *FindFunc (char const *name, BuiltinFunc where[], int num);
|
||||
int InsertIntoSortBuffer (int jul, int tim, char const *body, int typ, int prio);
|
||||
void IssueSortedReminders (void);
|
||||
int UserFuncExists (char const *fn);
|
||||
void JulToHeb (int jul, int *hy, int *hm, int *hd);
|
||||
int HebNameToNum (const char *mname);
|
||||
char *HebMonthName (int m, int y);
|
||||
int HebNameToNum (char const *mname);
|
||||
char const *HebMonthName (int m, int y);
|
||||
int RoshHashana (int i);
|
||||
long DaysToHebYear (int y);
|
||||
int DaysInHebYear (int y);
|
||||
char *DaysInHebMonths (int ylen);
|
||||
char const *DaysInHebMonths (int ylen);
|
||||
int HebToJul (int hy, int hm, int hd);
|
||||
int GetValidHebDate (int yin, int min, int din, int adarbehave, int *mout, int *dout, int yahr);
|
||||
int GetNextHebrewDate (int julstart, int hm, int hd, int yahr, int adarbehave, int *ans);
|
||||
int ComputeJahr (int y, int m, int d, int *ans);
|
||||
int GetSysVar (const char *name, Value *val);
|
||||
int SetSysVar (const char *name, Value *val);
|
||||
void DumpSysVarByName (const char *name);
|
||||
int GetSysVar (char const *name, Value *val);
|
||||
int SetSysVar (char const *name, Value *val);
|
||||
void DumpSysVarByName (char const *name);
|
||||
int CalcMinsFromUTC (int jul, int tim, int *mins, int *isdst);
|
||||
void FillParagraph (char *s);
|
||||
void FillParagraph (char const *s);
|
||||
void LocalToUTC (int locdate, int loctime, int *utcdate, int *utctime);
|
||||
void UTCToLocal (int utcdate, int utctime, int *locdate, int *loctime);
|
||||
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 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);
|
||||
|
||||
void PurgeEchoLine(char const *fmt, ...);
|
||||
void FreeTrig(Trigger *t);
|
||||
void AppendTag(DynamicBuffer *buf, char const *s);
|
||||
char const *SynthesizeTag(void);
|
||||
|
||||
136
src/queue.c
136
src/queue.c
@@ -11,7 +11,6 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: queue.c,v 1.18 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
/* Solaris needs this to get select() prototype */
|
||||
#ifdef __sun__
|
||||
@@ -41,9 +40,10 @@ typedef struct queuedrem {
|
||||
int typ;
|
||||
int RunDisabled;
|
||||
int ntrig;
|
||||
char *text;
|
||||
char const *text;
|
||||
char passthru[PASSTHRU_LEN+1];
|
||||
char sched[VAR_NAME_LEN+1];
|
||||
char tag[TAG_LEN+1];
|
||||
DynamicBuffer tags;
|
||||
TimeTrig tt;
|
||||
} QueuedRem;
|
||||
|
||||
@@ -69,7 +69,7 @@ static void reread (void);
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int QueueReminder(ParsePtr p, Trigger *trig,
|
||||
TimeTrig *tim, const char *sched)
|
||||
TimeTrig *tim, char const *sched)
|
||||
{
|
||||
QueuedRem *qelem;
|
||||
|
||||
@@ -90,12 +90,17 @@ int QueueReminder(ParsePtr p, Trigger *trig,
|
||||
}
|
||||
NumQueued++;
|
||||
qelem->typ = trig->typ;
|
||||
strcpy(qelem->passthru, trig->passthru);
|
||||
qelem->tt = *tim;
|
||||
qelem->next = QueueHead;
|
||||
qelem->RunDisabled = RunDisabled;
|
||||
qelem->ntrig = 0;
|
||||
strcpy(qelem->sched, sched);
|
||||
strcpy(qelem->tag, trig->tag);
|
||||
DBufInit(&(qelem->tags));
|
||||
DBufPuts(&(qelem->tags), DBufValue(&(trig->tags)));
|
||||
if (SynthesizeTags) {
|
||||
AppendTag(&(qelem->tags), SynthesizeTag());
|
||||
}
|
||||
QueueHead = qelem;
|
||||
return OK;
|
||||
}
|
||||
@@ -110,7 +115,7 @@ int QueueReminder(ParsePtr p, Trigger *trig,
|
||||
void HandleQueuedReminders(void)
|
||||
{
|
||||
QueuedRem *q = QueueHead;
|
||||
long TimeToSleep;
|
||||
int TimeToSleep;
|
||||
unsigned SleepTime;
|
||||
Parser p;
|
||||
Trigger trig;
|
||||
@@ -164,66 +169,92 @@ void HandleQueuedReminders(void)
|
||||
if (Daemon && !q) {
|
||||
if (Daemon < 0) {
|
||||
/* Sleep until midnight */
|
||||
TimeToSleep = (long) 1440*60L - SystemTime(0);
|
||||
TimeToSleep = MINUTES_PER_DAY*60 - SystemTime(0);
|
||||
} else {
|
||||
TimeToSleep = (long) 60*Daemon;
|
||||
TimeToSleep = 60*Daemon;
|
||||
}
|
||||
} else {
|
||||
TimeToSleep = (long) q->tt.nexttime * 60L - SystemTime(0);
|
||||
TimeToSleep = q->tt.nexttime * 60L - SystemTime(0);
|
||||
}
|
||||
|
||||
while (TimeToSleep > 0L) {
|
||||
SleepTime = (unsigned) ((TimeToSleep > 30000L) ? 30000 : TimeToSleep);
|
||||
SleepTime = TimeToSleep;
|
||||
|
||||
if (Daemon > 0 && SleepTime > 60*Daemon) SleepTime = 60*Daemon;
|
||||
|
||||
/* Wake up once a minute to recalibrate sleep time in
|
||||
case of laptop hibernation */
|
||||
if (Daemon <= 0) {
|
||||
if (SleepTime > 60) {
|
||||
SleepTime = 60;
|
||||
}
|
||||
}
|
||||
|
||||
if (Daemon >= 0) {
|
||||
sleep(SleepTime);
|
||||
} else {
|
||||
DaemonWait(SleepTime);
|
||||
}
|
||||
|
||||
if (Daemon> 0 && SleepTime) CheckInitialFile();
|
||||
/* If not in daemon mode and day has rolled around,
|
||||
exit -- not much we can do. */
|
||||
if (!Daemon) {
|
||||
int y, m, d;
|
||||
if (RealToday != SystemDate(&y, &m, &d)) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (Daemon > 0 && SleepTime) CheckInitialFile();
|
||||
|
||||
if (Daemon && !q) {
|
||||
if (Daemon < 0) {
|
||||
/* Sleep until midnight */
|
||||
TimeToSleep = (long) 1440*60L - SystemTime(0);
|
||||
TimeToSleep = MINUTES_PER_DAY*60 - SystemTime(0);
|
||||
} else {
|
||||
TimeToSleep = (long) 60*Daemon;
|
||||
TimeToSleep = 60*Daemon;
|
||||
}
|
||||
} else {
|
||||
TimeToSleep = (long) q->tt.nexttime * 60L - SystemTime(0);
|
||||
TimeToSleep = q->tt.nexttime * 60L - SystemTime(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Trigger the reminder */
|
||||
CreateParser(q->text, &p);
|
||||
trig.typ = q->typ;
|
||||
RunDisabled = q->RunDisabled;
|
||||
if (Daemon < 0) {
|
||||
printf("NOTE reminder %s ",
|
||||
SimpleTime(q->tt.ttime));
|
||||
printf("%s ", SimpleTime(SystemTime(0)/60));
|
||||
if (!*q->tag) {
|
||||
printf("*");
|
||||
} else {
|
||||
printf("%s", q->tag);
|
||||
/* 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
|
||||
queued reminders are triggered at least once. */
|
||||
if ((SystemTime(0) - (q->tt.nexttime * 60) <= 60) ||
|
||||
(q->tt.nexttime == q->tt.ttime)) {
|
||||
/* Trigger the reminder */
|
||||
CreateParser(q->text, &p);
|
||||
trig.typ = q->typ;
|
||||
strcpy(trig.passthru, q->passthru);
|
||||
RunDisabled = q->RunDisabled;
|
||||
if (Daemon < 0) {
|
||||
printf("NOTE reminder %s",
|
||||
SimpleTime(q->tt.ttime));
|
||||
printf("%s", SimpleTime(SystemTime(0)/60));
|
||||
if (!*DBufValue(&q->tags)) {
|
||||
printf("*\n");
|
||||
} else {
|
||||
printf("%s\n", DBufValue(&(q->tags)));
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* Set up global variables so some functions like trigdate()
|
||||
and trigtime() work correctly */
|
||||
LastTriggerDate = JulianToday;
|
||||
LastTriggerTime = q->tt.ttime;
|
||||
LastTrigValid = 1;
|
||||
(void) TriggerReminder(&p, &trig, &q->tt, JulianToday);
|
||||
if (Daemon < 0) {
|
||||
printf("NOTE endreminder\n");
|
||||
/* Set up global variables so some functions like trigdate()
|
||||
and trigtime() work correctly */
|
||||
LastTriggerDate = JulianToday;
|
||||
LastTriggerTime = q->tt.ttime;
|
||||
LastTrigValid = 1;
|
||||
(void) TriggerReminder(&p, &trig, &q->tt, JulianToday);
|
||||
if (Daemon < 0) {
|
||||
printf("NOTE endreminder\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
DestroyParser(&p);
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
/* Calculate the next trigger time */
|
||||
q->tt.nexttime = CalculateNextTime(q);
|
||||
@@ -314,13 +345,16 @@ void GotSigInt(void)
|
||||
while (q) {
|
||||
if (q->tt.nexttime != NO_TIME) {
|
||||
printf("Trigger: %02d%c%02d Activate: %02d%c%02d Rep: %d Delta: %d Sched: %s",
|
||||
q->tt.ttime / 60, TIMESEP, q->tt.ttime % 60,
|
||||
q->tt.nexttime / 60, TIMESEP, q->tt.nexttime % 60,
|
||||
q->tt.ttime / 60, TimeSep, q->tt.ttime % 60,
|
||||
q->tt.nexttime / 60, TimeSep, q->tt.nexttime % 60,
|
||||
q->tt.rep, q->tt.delta, q->sched);
|
||||
if (*q->sched) printf("(%d)", q->ntrig+1);
|
||||
printf("%s", NL);
|
||||
printf("Text: %s %s%s%s", ((q->typ == MSG_TYPE) ? "MSG" :
|
||||
((q->typ == MSF_TYPE) ? "MSF" :"RUN")),
|
||||
printf("Text: %s %s%s%s%s%s", ((q->typ == MSG_TYPE) ? "MSG" :
|
||||
((q->typ == MSF_TYPE) ? "MSF" :
|
||||
((q->typ == RUN_TYPE) ? "RUN" : "SPECIAL"))),
|
||||
q->passthru,
|
||||
(*(q->passthru)) ? " " : "",
|
||||
q->text,
|
||||
NL, NL);
|
||||
}
|
||||
@@ -362,7 +396,7 @@ static int CalculateNextTimeUsingSched(QueuedRem *q)
|
||||
/* Use LineBuffer for temp. string storage. */
|
||||
int r;
|
||||
Value v;
|
||||
char *s;
|
||||
char const *s;
|
||||
int LastTime = -1;
|
||||
int ThisTime;
|
||||
|
||||
@@ -377,16 +411,20 @@ static int CalculateNextTimeUsingSched(QueuedRem *q)
|
||||
char exprBuf[VAR_NAME_LEN+32];
|
||||
sprintf(exprBuf, "%s(%d)", q->sched, q->ntrig);
|
||||
s = exprBuf;
|
||||
r = EvalExpr(&s, &v);
|
||||
r = EvalExpr(&s, &v, NULL);
|
||||
if (r) {
|
||||
q->sched[0] = 0;
|
||||
return NO_TIME;
|
||||
}
|
||||
if (v.type == TIM_TYPE) {
|
||||
if (v.type == TIME_TYPE) {
|
||||
ThisTime = v.v.val;
|
||||
} else if (v.type == INT_TYPE) {
|
||||
if (v.v.val > 0)
|
||||
ThisTime = q->tt.nexttime + v.v.val;
|
||||
if (LastTime >= 0) {
|
||||
ThisTime = LastTime + v.v.val;
|
||||
} else {
|
||||
ThisTime = q->tt.nexttime + v.v.val;
|
||||
}
|
||||
else
|
||||
ThisTime = q->tt.ttime + v.v.val;
|
||||
|
||||
@@ -396,7 +434,11 @@ static int CalculateNextTimeUsingSched(QueuedRem *q)
|
||||
return NO_TIME;
|
||||
}
|
||||
if (ThisTime < 0) ThisTime = 0; /* Can't be less than 00:00 */
|
||||
if (ThisTime > 1439) ThisTime = 1439; /* or greater than 11:59 */
|
||||
if (ThisTime > (MINUTES_PER_DAY-1)) ThisTime = (MINUTES_PER_DAY-1); /* or greater than 11:59 */
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
fprintf(ErrFp, "SCHED: Considering %02d%c%02d\n",
|
||||
ThisTime / 60, TimeSep, ThisTime % 60);
|
||||
}
|
||||
if (ThisTime > q->tt.nexttime) return ThisTime;
|
||||
if (ThisTime <= LastTime) {
|
||||
q->sched[0] = 0;
|
||||
@@ -483,6 +525,6 @@ static void DaemonWait(unsigned int sleeptime)
|
||||
/***************************************************************/
|
||||
static void reread(void)
|
||||
{
|
||||
execvp(ArgV[0], ArgV);
|
||||
execvp(ArgV[0], (char **) ArgV);
|
||||
}
|
||||
|
||||
|
||||
122
src/rem2ps.c
122
src/rem2ps.c
@@ -10,9 +10,9 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
#include "version.h"
|
||||
#include "config.h"
|
||||
#include "dynbuf.h"
|
||||
static char const RCSID[] = "$Id: rem2ps.c,v 1.14 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -21,16 +21,27 @@ static char const RCSID[] = "$Id: rem2ps.c,v 1.14 2005-09-30 03:29:32 dfs Exp $"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "rem2ps.h"
|
||||
#include "version.h"
|
||||
|
||||
#define NEW(type) ((type *) malloc(sizeof(type)))
|
||||
#define NEW(type) (malloc(sizeof(type)))
|
||||
|
||||
#define SPECIAL_NORMAL 0
|
||||
#define SPECIAL_POSTSCRIPT 1
|
||||
#define SPECIAL_PSFILE 2
|
||||
#define SPECIAL_MOON 3
|
||||
#define SPECIAL_SHADE 4
|
||||
#define SPECIAL_COLOR 5
|
||||
#define SPECIAL_COLOR 4
|
||||
#define SPECIAL_WEEK 5
|
||||
#define SPECIAL_SHADE 6
|
||||
|
||||
/* Array holding how specials sort */
|
||||
static int SpecialSortOrder[] = {
|
||||
0, /* NORMAL */
|
||||
1, /* POSTSCRIPT */
|
||||
1, /* PSFILE */
|
||||
2, /* MOON */
|
||||
0, /* COLOR */
|
||||
4, /* WEEK */
|
||||
5 /* SHADE */
|
||||
};
|
||||
|
||||
typedef struct calentry {
|
||||
struct calentry *next;
|
||||
@@ -39,13 +50,13 @@ typedef struct calentry {
|
||||
} CalEntry;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char const *name;
|
||||
int xsize, ysize;
|
||||
} PageType;
|
||||
|
||||
char DayName[7][33];
|
||||
|
||||
char *SmallCalLoc[] = {
|
||||
char const *SmallCalLoc[] = {
|
||||
"",
|
||||
"bt",
|
||||
"tb",
|
||||
@@ -53,7 +64,7 @@ char *SmallCalLoc[] = {
|
||||
};
|
||||
|
||||
#define NUMSMALL (sizeof(SmallCalLoc)/sizeof(SmallCalLoc[0]))
|
||||
char *SmallLocation;
|
||||
char const *SmallLocation;
|
||||
int SmallCol1, SmallCol2;
|
||||
|
||||
PageType Pages[] =
|
||||
@@ -89,20 +100,20 @@ char PortraitMode;
|
||||
char NoSmallCal;
|
||||
char UseISO;
|
||||
|
||||
char *HeadFont="Helvetica";
|
||||
char *TitleFont="Helvetica";
|
||||
char *DayFont="Helvetica-BoldOblique";
|
||||
char *EntryFont="Helvetica";
|
||||
char *SmallFont="Helvetica";
|
||||
char *LineWidth = "1";
|
||||
char const *HeadFont="Helvetica";
|
||||
char const *TitleFont="Helvetica";
|
||||
char const *DayFont="Helvetica-BoldOblique";
|
||||
char const *EntryFont="Helvetica";
|
||||
char const *SmallFont="Helvetica";
|
||||
char const *LineWidth = "1";
|
||||
|
||||
char *HeadSize="14";
|
||||
char *TitleSize="14";
|
||||
char *DaySize="14";
|
||||
char *EntrySize="8";
|
||||
char *BorderSize = "6";
|
||||
char const *HeadSize="14";
|
||||
char const *TitleSize="14";
|
||||
char const *DaySize="14";
|
||||
char const *EntrySize="8";
|
||||
char const *BorderSize = "6";
|
||||
|
||||
char *UserProlog = NULL;
|
||||
char const *UserProlog = NULL;
|
||||
|
||||
int validfile = 0;
|
||||
|
||||
@@ -117,15 +128,15 @@ int FillPage;
|
||||
int Verbose = 0;
|
||||
|
||||
void Init (int argc, char *argv[]);
|
||||
void Usage (char *s);
|
||||
void Usage (char const *s);
|
||||
void DoPsCal (void);
|
||||
int DoQueuedPs (void);
|
||||
void DoSmallCal (char *m, int days, int first, int col, int which);
|
||||
void DoSmallCal (char const *m, int days, int first, int col, int which);
|
||||
void WriteProlog (void);
|
||||
void WriteCalEntry (void);
|
||||
void WriteOneEntry (CalEntry *c);
|
||||
void GetSmallLocations (void);
|
||||
char *EatToken(char *in, char *out, int maxlen);
|
||||
char const *EatToken(char const *in, char *out, int maxlen);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -183,10 +194,10 @@ void DoPsCal(void)
|
||||
int i;
|
||||
int is_ps;
|
||||
int firstcol;
|
||||
char *startOfBody;
|
||||
char const *startOfBody;
|
||||
char passthru[PASSTHRU_LEN+1];
|
||||
DynamicBuffer buf;
|
||||
CalEntry *c, *d;
|
||||
CalEntry *c, *d, *p;
|
||||
|
||||
/* Read the month and year name, followed by # days in month and 1st day of
|
||||
month */
|
||||
@@ -307,6 +318,7 @@ void DoPsCal(void)
|
||||
if (!strcmp(passthru, "PostScript") ||
|
||||
!strcmp(passthru, "PSFile") ||
|
||||
!strcmp(passthru, "MOON") ||
|
||||
!strcmp(passthru, "WEEK") ||
|
||||
!strcmp(passthru, "SHADE")) {
|
||||
is_ps = 1;
|
||||
}
|
||||
@@ -325,6 +337,8 @@ void DoPsCal(void)
|
||||
c->special = SPECIAL_SHADE;
|
||||
} else if (!strcmp(passthru, "MOON")) {
|
||||
c->special = SPECIAL_MOON;
|
||||
} else if (!strcmp(passthru, "WEEK")) {
|
||||
c->special = SPECIAL_WEEK;
|
||||
} else {
|
||||
c->special = SPECIAL_PSFILE;
|
||||
}
|
||||
@@ -333,10 +347,26 @@ void DoPsCal(void)
|
||||
PsEntries[DayNum] = c;
|
||||
} else {
|
||||
d = PsEntries[DayNum];
|
||||
while(d->next) d = d->next;
|
||||
d->next = c;
|
||||
p = NULL;
|
||||
/* Slot it into the right place */
|
||||
while (d->next && (SpecialSortOrder[c->special] <= SpecialSortOrder[d->special])) {
|
||||
p = d;
|
||||
d = d->next;
|
||||
}
|
||||
if (SpecialSortOrder[c->special] <= SpecialSortOrder[d->special]) {
|
||||
c->next = d->next;
|
||||
d->next = c;
|
||||
} else {
|
||||
if (p) {
|
||||
p->next = c;
|
||||
} else {
|
||||
PsEntries[DayNum] = c;
|
||||
}
|
||||
c->next = d;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(passthru, "*") ||
|
||||
!strcmp(passthru, "COLOUR") ||
|
||||
!strcmp(passthru, "COLOR")) {
|
||||
/* Put on linked list */
|
||||
if (!CurEntries) {
|
||||
@@ -346,7 +376,8 @@ void DoPsCal(void)
|
||||
while(d->next) d = d->next;
|
||||
d->next = c;
|
||||
}
|
||||
if (!strcmp(passthru, "COLOR")) {
|
||||
if (!strcmp(passthru, "COLOR") ||
|
||||
!strcmp(passthru, "COLOUR")) {
|
||||
c->special = SPECIAL_COLOR;
|
||||
}
|
||||
}
|
||||
@@ -389,7 +420,7 @@ void WriteProlog(void)
|
||||
int i;
|
||||
int x = CurPage->xsize;
|
||||
int y = CurPage->ysize;
|
||||
char *isostuff;
|
||||
char const *isostuff;
|
||||
FILE *fp;
|
||||
int nread;
|
||||
char buffer[512];
|
||||
@@ -575,7 +606,7 @@ void WriteCalEntry(void)
|
||||
void WriteOneEntry(CalEntry *c)
|
||||
{
|
||||
int ch, i;
|
||||
char *s = c->entry;
|
||||
char const *s = c->entry;
|
||||
|
||||
printf(" [");
|
||||
|
||||
@@ -601,7 +632,6 @@ void WriteOneEntry(CalEntry *c)
|
||||
PutChar(')');
|
||||
while(isspace((unsigned char)*s)) s++;
|
||||
if (!*s) {
|
||||
printf("]\n");
|
||||
goto finish;
|
||||
}
|
||||
PutChar('(');
|
||||
@@ -637,7 +667,8 @@ void WriteOneEntry(CalEntry *c)
|
||||
/***************************************************************/
|
||||
void Init(int argc, char *argv[])
|
||||
{
|
||||
char *s, *t;
|
||||
char const *s;
|
||||
char const *t;
|
||||
int i=1;
|
||||
int j;
|
||||
int offset;
|
||||
@@ -793,7 +824,7 @@ void Init(int argc, char *argv[])
|
||||
/* Usage - print usage information */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void Usage(char *s)
|
||||
void Usage(char const *s)
|
||||
{
|
||||
if (s) fprintf(stderr, "Rem2PS: %s\n\n", s);
|
||||
|
||||
@@ -822,7 +853,7 @@ void Usage(char *s)
|
||||
/* month. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void DoSmallCal(char *m, int days, int first, int col, int which)
|
||||
void DoSmallCal(char const *m, int days, int first, int col, int which)
|
||||
{
|
||||
/* Do the small calendar */
|
||||
int i, j;
|
||||
@@ -887,7 +918,8 @@ int DoQueuedPs(void)
|
||||
FILE *fp;
|
||||
int fnoff;
|
||||
char buffer[512];
|
||||
char *size, *extra;
|
||||
char const *size, *extra;
|
||||
char const *s;
|
||||
int num, r, g, b, phase, fontsize, moonsize;
|
||||
unsigned char c;
|
||||
|
||||
@@ -955,6 +987,22 @@ int DoQueuedPs(void)
|
||||
r/255.0, g/255.0, b/255.0);
|
||||
break;
|
||||
|
||||
case SPECIAL_WEEK: /* Week number */
|
||||
printf("gsave Border Border 2 div moveto /EntryFont findfont EntrySize 1.2 div scalefont setfont (");
|
||||
s = e->entry+fnoff;
|
||||
while(*s && isspace(*s)) {
|
||||
s++;
|
||||
}
|
||||
while(*s) {
|
||||
if (*s == '\\' || *s == '(' || *s == ')') {
|
||||
PutChar('\\');
|
||||
}
|
||||
PutChar(*s);
|
||||
s++;
|
||||
}
|
||||
printf(") show grestore\n");
|
||||
break;
|
||||
|
||||
case SPECIAL_MOON: /* Moon phase */
|
||||
num = sscanf(e->entry+fnoff, "%d %d %d", &phase, &moonsize,
|
||||
&fontsize);
|
||||
@@ -1062,7 +1110,7 @@ int DoQueuedPs(void)
|
||||
void GetSmallLocations(void)
|
||||
{
|
||||
char c;
|
||||
char *s = SmallLocation;
|
||||
char const *s = SmallLocation;
|
||||
int colfirst, collast;
|
||||
|
||||
/* Figure out the first and last columns */
|
||||
@@ -1124,7 +1172,7 @@ void GetSmallLocations(void)
|
||||
/* Read a space-delimited token into an output buffer. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char *EatToken(char *in, char *out, int maxlen)
|
||||
char const *EatToken(char const *in, char *out, int maxlen)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: rem2ps.h,v 1.5 2004-08-11 01:55:32 dfs Exp $ */
|
||||
|
||||
char *PSProlog1[] =
|
||||
{
|
||||
"% This file was produced by Remind and Rem2PS, written by",
|
||||
|
||||
36
src/sort.c
36
src/sort.c
@@ -11,7 +11,6 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: sort.c,v 1.8 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -26,7 +25,7 @@ static char const RCSID[] = "$Id: sort.c,v 1.8 2005-09-30 03:29:32 dfs Exp $";
|
||||
/* The structure of a sorted entry */
|
||||
typedef struct sortrem {
|
||||
struct sortrem *next;
|
||||
char *text;
|
||||
char const *text;
|
||||
int trigdate;
|
||||
int trigtime;
|
||||
int typ;
|
||||
@@ -36,7 +35,7 @@ typedef struct sortrem {
|
||||
/* The sorted reminder queue */
|
||||
static Sortrem *SortedQueue = (Sortrem *) NULL;
|
||||
|
||||
static Sortrem *MakeSortRem (int jul, int tim, char *body, int typ, int prio);
|
||||
static Sortrem *MakeSortRem (int jul, int tim, char const *body, int typ, int prio);
|
||||
static void IssueSortBanner (int jul);
|
||||
|
||||
/***************************************************************/
|
||||
@@ -46,7 +45,7 @@ static void IssueSortBanner (int jul);
|
||||
/* Create a new Sortrem entry - return NULL on failure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static Sortrem *MakeSortRem(int jul, int tim, char *body, int typ, int prio)
|
||||
static Sortrem *MakeSortRem(int jul, int tim, char const *body, int typ, int prio)
|
||||
{
|
||||
Sortrem *new = NEW(Sortrem);
|
||||
if (!new) return NULL;
|
||||
@@ -72,7 +71,7 @@ static Sortrem *MakeSortRem(int jul, int tim, char *body, int typ, int prio)
|
||||
/* Insert a reminder into the sort buffer */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int InsertIntoSortBuffer(int jul, int tim, char *body, int typ, int prio)
|
||||
int InsertIntoSortBuffer(int jul, int tim, char const *body, int typ, int prio)
|
||||
{
|
||||
Sortrem *new = MakeSortRem(jul, tim, body, typ, prio);
|
||||
Sortrem *cur = SortedQueue, *prev = NULL;
|
||||
@@ -84,6 +83,7 @@ int InsertIntoSortBuffer(int jul, int tim, char *body, int typ, int prio)
|
||||
SortByDate = 0;
|
||||
SortByTime = 0;
|
||||
SortByPrio = 0;
|
||||
UntimedBeforeTimed = 0;
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
@@ -95,8 +95,8 @@ int InsertIntoSortBuffer(int jul, int tim, char *body, int typ, int prio)
|
||||
while (cur) {
|
||||
ShouldGoAfter = CompareRems(new->trigdate, new->trigtime, new->priority,
|
||||
cur->trigdate, cur->trigtime, cur->priority,
|
||||
SortByDate, SortByTime, SortByPrio);
|
||||
|
||||
SortByDate, SortByTime, SortByPrio, UntimedBeforeTimed);
|
||||
|
||||
if (ShouldGoAfter <= 0) {
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
@@ -155,7 +155,7 @@ void IssueSortedReminders(void)
|
||||
break;
|
||||
}
|
||||
|
||||
free(cur->text);
|
||||
free((char *) cur->text);
|
||||
free(cur);
|
||||
cur = next;
|
||||
}
|
||||
@@ -174,14 +174,14 @@ static void IssueSortBanner(int jul)
|
||||
char BanExpr[64];
|
||||
int y, m, d;
|
||||
Value v;
|
||||
char *s = BanExpr;
|
||||
char const *s = BanExpr;
|
||||
DynamicBuffer buf;
|
||||
|
||||
if (UserFuncExists("sortbanner") != 1) return;
|
||||
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
sprintf(BanExpr, "sortbanner('%04d/%02d/%02d')", y, m+1, d);
|
||||
y = EvalExpr(&s, &v);
|
||||
y = EvalExpr(&s, &v, NULL);
|
||||
if (y) return;
|
||||
if (DoCoerce(STR_TYPE, &v)) return;
|
||||
DBufInit(&buf);
|
||||
@@ -204,19 +204,27 @@ static void IssueSortBanner(int jul)
|
||||
/***************************************************************/
|
||||
int CompareRems(int dat1, int tim1, int prio1,
|
||||
int dat2, int tim2, int prio2,
|
||||
int bydate, int bytime, int byprio)
|
||||
int bydate, int bytime, int byprio,
|
||||
int untimed_first)
|
||||
{
|
||||
int dafter, tafter, pafter;
|
||||
int dafter, tafter, pafter, uafter;
|
||||
|
||||
dafter = (bydate != SORT_DESCEND) ? 1 : -1;
|
||||
tafter = (bytime != SORT_DESCEND) ? 1 : -1;
|
||||
pafter = (byprio != SORT_DESCEND) ? 1 : -1;
|
||||
uafter = (untimed_first) ? -1 : 1;
|
||||
|
||||
if (dat1 < dat2) return dafter;
|
||||
if (dat1 > dat2) return -dafter;
|
||||
|
||||
if (tim1 == NO_TIME && tim2 != NO_TIME) return -1;
|
||||
if (tim1 != NO_TIME && tim2 == NO_TIME) return 1;
|
||||
if (tim1 == NO_TIME && tim2 != NO_TIME) {
|
||||
return -uafter;
|
||||
}
|
||||
|
||||
if (tim1 != NO_TIME && tim2 == NO_TIME) {
|
||||
return uafter;
|
||||
}
|
||||
|
||||
if (tim1 < tim2) return tafter;
|
||||
if (tim1 > tim2) return -tafter;
|
||||
|
||||
|
||||
11
src/test-all-languages.sh
Executable file
11
src/test-all-languages.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
# Make sure Remind compiles with all supported languages; show
|
||||
# tstlang.rem output for each language.
|
||||
|
||||
ALL=`grep ^#define lang.h | grep -v '#define LANG' | awk '{print $2}'`
|
||||
|
||||
for i in $ALL ; do
|
||||
make clean all LANGDEF=-DLANG=$i || exit 1
|
||||
./remind -q -r ../tests/tstlang.rem
|
||||
done
|
||||
exit 0
|
||||
48
src/token.c
48
src/token.c
@@ -12,7 +12,6 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: token.c,v 1.13 2005-11-20 01:26:59 dfs Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -35,8 +34,6 @@ while (isdigit(*(string))) { \
|
||||
string++; \
|
||||
}
|
||||
|
||||
#define UPPER(c) (islower(c) ? toupper(c) : c)
|
||||
|
||||
/* The big array holding all recognized (literal) tokens in reminder file.
|
||||
Keep this array sorted, or software will not work. */
|
||||
Token TokArray[] = {
|
||||
@@ -61,6 +58,7 @@ Token TokArray[] = {
|
||||
{ "february", 3, T_Month, 1 },
|
||||
{ "flush", 5, T_Flush, 0 },
|
||||
{ "friday", 3, T_WkDay, 4 },
|
||||
{ "from", 4, T_Scanfrom, FROM_TYPE },
|
||||
{ "fset", 4, T_Fset, 0 },
|
||||
{ "if", 2, T_If, 0 },
|
||||
{ "iftrig", 6, T_IfTrig, 0 },
|
||||
@@ -76,6 +74,7 @@ Token TokArray[] = {
|
||||
{ "november", 3, T_Month, 10 },
|
||||
{ "october", 3, T_Month, 9 },
|
||||
{ "omit", 3, T_Omit, 0 },
|
||||
{ "omitfunc", 8, T_OmitFunc, 0 },
|
||||
{ "once", 3, T_Once, 0 },
|
||||
{ "pop-omit-context", 3, T_Pop, 0 },
|
||||
{ "preserve", 8, T_Preserve, 0 },
|
||||
@@ -87,7 +86,7 @@ Token TokArray[] = {
|
||||
{ "run", 3, T_RemType, RUN_TYPE },
|
||||
{ "satisfy", 7, T_RemType, SAT_TYPE },
|
||||
{ "saturday", 3, T_WkDay, 5 },
|
||||
{ "scanfrom", 4, T_Scanfrom, 0 },
|
||||
{ "scanfrom", 4, T_Scanfrom, SCANFROM_TYPE },
|
||||
{ "sched", 5, T_Sched, 0 },
|
||||
{ "september", 3, T_Month, 8 },
|
||||
{ "set", 3, T_Set, 0 },
|
||||
@@ -95,6 +94,7 @@ Token TokArray[] = {
|
||||
{ "special", 7, T_RemType, PASSTHRU_TYPE },
|
||||
{ "sunday", 3, T_WkDay, 6 },
|
||||
{ "tag", 3, T_Tag, 0 },
|
||||
{ "through", 7, T_Through, 0 },
|
||||
{ "thursday", 3, T_WkDay, 3 },
|
||||
{ "tuesday", 3, T_WkDay, 1 },
|
||||
{ "unset", 5, T_UnSet, 0 },
|
||||
@@ -130,7 +130,7 @@ Token NonEnglishToks[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
static int TokStrCmp (const Token *t, const char *s);
|
||||
static int TokStrCmp (Token const *t, char const *s);
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
@@ -140,16 +140,16 @@ static int TokStrCmp (const Token *t, const char *s);
|
||||
/* left square bracket, return a T_Illegal type. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
char *FindInitialToken(Token *tok, char *s)
|
||||
char const *FindInitialToken(Token *tok, char const *s)
|
||||
{
|
||||
DynamicBuffer buf;
|
||||
DBufInit(&buf);
|
||||
|
||||
tok->type = T_Illegal;
|
||||
|
||||
while (isspace(*s)) s++;
|
||||
while (isempty(*s)) s++;
|
||||
|
||||
while (*s && !isspace(*s)) {
|
||||
while (*s && !isempty(*s)) {
|
||||
if (DBufPutc(&buf, *s++) != OK) return s;
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ char *FindInitialToken(Token *tok, char *s)
|
||||
/* Given a string, which token is it? */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void FindToken(const char *s, Token *tok)
|
||||
void FindToken(char const *s, Token *tok)
|
||||
{
|
||||
int top, bot, mid, r, max;
|
||||
int l;
|
||||
@@ -254,15 +254,33 @@ void FindToken(const char *s, Token *tok)
|
||||
/* Rep - *n */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
void FindNumericToken(const char *s, Token *t)
|
||||
void FindNumericToken(char const *s, Token *t)
|
||||
{
|
||||
int mult = 1, hour, min;
|
||||
char const *s_orig = s;
|
||||
|
||||
t->type = T_Illegal;
|
||||
t->val = 0;
|
||||
if (isdigit(*s)) {
|
||||
PARSENUM(t->val, s);
|
||||
|
||||
/* If we hit a '-' or a '/', we may have a date or a datetime */
|
||||
if (*s == '-' || *s == '/') {
|
||||
char const *p = s_orig;
|
||||
int jul, tim;
|
||||
if (ParseLiteralDate(&p, &jul, &tim) == OK) {
|
||||
if (*p) return;
|
||||
if (tim == NO_TIME) {
|
||||
t->type = T_Date;
|
||||
t->val = jul;
|
||||
return;
|
||||
}
|
||||
t->type = T_DateTime;
|
||||
t->val = MINUTES_PER_DAY * jul + tim;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we hit a comma, swallow it. This allows stuff
|
||||
like Jan 6, 1998 */
|
||||
if (*s == ',') {
|
||||
@@ -278,7 +296,7 @@ void FindNumericToken(const char *s, Token *t)
|
||||
return;
|
||||
}
|
||||
/* If we hit a colon or a period, we've probably got a time hr:min */
|
||||
if (*s == ':' || *s == '.' || *s == TIMESEP) {
|
||||
if (*s == ':' || *s == '.' || *s == TimeSep) {
|
||||
s++;
|
||||
hour = t->val;
|
||||
PARSENUM(min, s);
|
||||
@@ -337,12 +355,12 @@ void FindNumericToken(const char *s, Token *t)
|
||||
/* Compare a token to a string. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static int TokStrCmp(const Token *t, const char *s)
|
||||
static int TokStrCmp(Token const *t, char const *s)
|
||||
{
|
||||
register int r;
|
||||
char *tk = t->name;
|
||||
char const *tk = t->name;
|
||||
while(*tk && *s && !(*s == ',' && *(s+1) == 0)) {
|
||||
r = UPPER(*tk) - UPPER(*s);
|
||||
r = tolower(*tk) - tolower(*s);
|
||||
tk++;
|
||||
s++;
|
||||
if (r) return r;
|
||||
@@ -350,5 +368,5 @@ static int TokStrCmp(const Token *t, const char *s)
|
||||
/* Ignore trailing commas on s */
|
||||
|
||||
if (!*s || (*s == ',' && !*(s+1))) return 0;
|
||||
return (*tk - *s);
|
||||
return (tolower(*tk) - tolower(*s));
|
||||
}
|
||||
|
||||
152
src/trigger.c
152
src/trigger.c
@@ -11,8 +11,6 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: trigger.c,v 1.6 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -208,16 +206,27 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
|
||||
*err = E_BAD_DATE;
|
||||
return -1;
|
||||
}
|
||||
/* Back up a year in case we'll cross a year boundary*/
|
||||
if (y > BASE) {
|
||||
y--;
|
||||
}
|
||||
|
||||
/* Move up to the first valid year */
|
||||
while (trig->d > DaysInMonth(trig->m, y)) y++;
|
||||
|
||||
/* Try last year */
|
||||
j = Julian(y, trig->m, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
if (j >= startdate) return j;
|
||||
|
||||
/* Try this year */
|
||||
y++;
|
||||
j = Julian(y, trig->m, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
if (j >= startdate) return j;
|
||||
|
||||
/* Must be next year */
|
||||
y = y + 1;
|
||||
y++;
|
||||
while (trig->d > DaysInMonth(trig->m, y)) y++;
|
||||
j = Julian(y, trig->m, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
@@ -288,16 +297,33 @@ static int JYear(int jul)
|
||||
/***************************************************************/
|
||||
static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart)
|
||||
{
|
||||
int simple, mod;
|
||||
int simple, mod, omit;
|
||||
|
||||
/* First: Have we passed the UNTIL date? */
|
||||
if (trig->until != NO_UNTIL &&
|
||||
trig->until < start) return -1; /* expired */
|
||||
trig->until < start) {
|
||||
trig->expired = 1;
|
||||
return -1; /* expired */
|
||||
}
|
||||
|
||||
/* Next: If it's an "AFTER"-type skip, back up
|
||||
until we're at the start of a block of holidays */
|
||||
if (trig->skip == AFTER_SKIP)
|
||||
while (IsOmitted(start-1, trig->localomit)) start--;
|
||||
if (trig->skip == AFTER_SKIP) {
|
||||
int iter = 0;
|
||||
while (iter++ <= MaxSatIter) {
|
||||
*err = IsOmitted(start-1, trig->localomit, trig->omitfunc, &omit);
|
||||
if (*err) return -2;
|
||||
if (!omit) {
|
||||
break;
|
||||
}
|
||||
start--;
|
||||
}
|
||||
if (iter > MaxSatIter) {
|
||||
/* omitfunc must have returned "true" too often */
|
||||
*err = E_CANT_TRIG;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the next simple trigger */
|
||||
simple = NextSimpleTrig(start, trig, err);
|
||||
@@ -311,12 +337,29 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
/* If there's a BACK, back up... */
|
||||
if (trig->back != NO_BACK) {
|
||||
mod = trig->back;
|
||||
if (mod < 0) simple += mod;
|
||||
else
|
||||
while(mod) {
|
||||
simple--;
|
||||
if (!IsOmitted(simple, trig->localomit)) mod--;
|
||||
if (mod < 0) {
|
||||
simple += mod;
|
||||
}
|
||||
else {
|
||||
int iter = 0;
|
||||
int max = MaxSatIter;
|
||||
if (max < mod*2) {
|
||||
max = mod*2;
|
||||
}
|
||||
while(iter++ <= max) {
|
||||
if (!mod) {
|
||||
break;
|
||||
}
|
||||
simple--;
|
||||
*err = IsOmitted(simple, trig->localomit, trig->omitfunc, &omit);
|
||||
if (*err) return -2;
|
||||
if (!omit) mod--;
|
||||
}
|
||||
if (iter > max) {
|
||||
*err = E_CANT_TRIG;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's a REP, calculate the next occurrence */
|
||||
@@ -329,12 +372,38 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
|
||||
/* If it's a "BEFORE"-type skip, back up */
|
||||
if (trig->skip == BEFORE_SKIP)
|
||||
while(IsOmitted(simple, trig->localomit)) simple--;
|
||||
if (trig->skip == BEFORE_SKIP) {
|
||||
int iter = 0;
|
||||
while(iter++ <= MaxSatIter) {
|
||||
*err = IsOmitted(simple, trig->localomit, trig->omitfunc, &omit);
|
||||
if (*err) return -2;
|
||||
if (!omit) {
|
||||
break;
|
||||
}
|
||||
simple--;
|
||||
}
|
||||
if (iter > MaxSatIter) {
|
||||
*err = E_CANT_TRIG;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
/* If it's an "AFTER"-type skip, jump ahead */
|
||||
if (trig->skip == AFTER_SKIP)
|
||||
while (IsOmitted(simple, trig->localomit)) simple++;
|
||||
if (trig->skip == AFTER_SKIP) {
|
||||
int iter = 0;
|
||||
while (iter++ <= MaxSatIter) {
|
||||
*err = IsOmitted(simple, trig->localomit, trig->omitfunc, &omit);
|
||||
if (*err) return -2;
|
||||
if (!omit) {
|
||||
break;
|
||||
}
|
||||
simple++;
|
||||
}
|
||||
if (iter > MaxSatIter) {
|
||||
*err = E_CANT_TRIG;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the date */
|
||||
return simple;
|
||||
@@ -348,15 +417,17 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
/* today's date. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int ComputeTrigger(int today, Trigger *trig, int *err)
|
||||
int ComputeTrigger(int today, Trigger *trig, int *err, int save_in_globals)
|
||||
{
|
||||
int nattempts = 0,
|
||||
start = today,
|
||||
nextstart,
|
||||
y, m, d,
|
||||
nextstart = 0,
|
||||
y, m, d, omit,
|
||||
result;
|
||||
|
||||
LastTrigValid = 0;
|
||||
trig->expired = 0;
|
||||
if (save_in_globals) LastTrigValid = 0;
|
||||
|
||||
/* Assume everything works */
|
||||
*err = OK;
|
||||
|
||||
@@ -374,14 +445,15 @@ int ComputeTrigger(int today, Trigger *trig, int *err)
|
||||
*err = E_REP_FULSPEC;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
while (nattempts++ < TRIG_ATTEMPTS) {
|
||||
result = GetNextTriggerDate(trig, start, err, &nextstart);
|
||||
|
||||
/* If there's an error, die immediately */
|
||||
if (*err) return -1;
|
||||
if (result == -1) {
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%d): %s\n",
|
||||
FileName, LineNo, ErrMsg[E_EXPIRED]);
|
||||
@@ -390,10 +462,18 @@ int ComputeTrigger(int today, Trigger *trig, int *err)
|
||||
}
|
||||
|
||||
/* If result is >= today, great! */
|
||||
if (trig->skip == SKIP_SKIP) {
|
||||
*err = IsOmitted(result, trig->localomit, trig->omitfunc, &omit);
|
||||
if (*err) return -1;
|
||||
} else {
|
||||
omit = 0;
|
||||
}
|
||||
if (result >= today &&
|
||||
(trig->skip != SKIP_SKIP || !IsOmitted(result, trig->localomit))) {
|
||||
LastTriggerDate = result; /* Save in global var */
|
||||
LastTrigValid = 1;
|
||||
(trig->skip != SKIP_SKIP || !omit)) {
|
||||
if (save_in_globals) {
|
||||
LastTriggerDate = result; /* Save in global var */
|
||||
LastTrigValid = 1;
|
||||
}
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
FromJulian(result, &y, &m, &d);
|
||||
fprintf(ErrFp, "%s(%d): Trig = %s, %d %s, %d\n",
|
||||
@@ -410,22 +490,36 @@ int ComputeTrigger(int today, Trigger *trig, int *err)
|
||||
if (trig->back == NO_BACK &&
|
||||
trig->skip == NO_SKIP &&
|
||||
trig->rep == NO_REP) {
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%d): %s\n",
|
||||
FileName, LineNo, ErrMsg[E_EXPIRED]);
|
||||
}
|
||||
if (result != -1) {
|
||||
LastTriggerDate = result;
|
||||
LastTrigValid = 1;
|
||||
if (save_in_globals) {
|
||||
LastTriggerDate = result;
|
||||
LastTrigValid = 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (trig->skip == SKIP_SKIP &&
|
||||
omit &&
|
||||
nextstart <= start &&
|
||||
result >= start) {
|
||||
nextstart = result + 1;
|
||||
}
|
||||
|
||||
/* Keep scanning... unless there's no point in doing it.*/
|
||||
if (nextstart <= start) {
|
||||
if (result != -1) {
|
||||
LastTriggerDate = result;
|
||||
LastTrigValid = 1;
|
||||
if (save_in_globals) {
|
||||
LastTriggerDate = result;
|
||||
LastTrigValid = 1;
|
||||
}
|
||||
}
|
||||
trig->expired = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%d): %s\n",
|
||||
FileName, LineNo, ErrMsg[E_EXPIRED]);
|
||||
|
||||
64
src/types.h
64
src/types.h
@@ -10,8 +10,6 @@
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: types.h,v 1.7 2005-11-20 01:26:59 dfs Exp $ */
|
||||
|
||||
#include <limits.h>
|
||||
#include "dynbuf.h"
|
||||
|
||||
@@ -26,12 +24,27 @@ typedef struct {
|
||||
|
||||
/* Define the type of operators */
|
||||
typedef struct {
|
||||
char *name;
|
||||
char const *name;
|
||||
char prec;
|
||||
char type;
|
||||
int (*func)(void);
|
||||
} Operator;
|
||||
|
||||
/* Structure for passing in Nargs and out RetVal from functions */
|
||||
typedef struct {
|
||||
int nargs;
|
||||
Value retval;
|
||||
} func_info;
|
||||
|
||||
/* Define the type of user-functions */
|
||||
typedef struct {
|
||||
char const *name;
|
||||
char minargs;
|
||||
char maxargs;
|
||||
char is_constant;
|
||||
int (*func)(func_info *);
|
||||
} BuiltinFunc;
|
||||
|
||||
/* Define the structure of a variable */
|
||||
typedef struct var {
|
||||
struct var *next;
|
||||
@@ -42,6 +55,7 @@ typedef struct var {
|
||||
|
||||
/* A trigger */
|
||||
typedef struct {
|
||||
int expired;
|
||||
int wd;
|
||||
int d;
|
||||
int m;
|
||||
@@ -58,7 +72,8 @@ typedef struct {
|
||||
int priority;
|
||||
char sched[VAR_NAME_LEN+1]; /* Scheduling function */
|
||||
char warn[VAR_NAME_LEN+1]; /* Warning function */
|
||||
char tag[TAG_LEN+1];
|
||||
char omitfunc[VAR_NAME_LEN+1]; /* OMITFUNC function */
|
||||
DynamicBuffer tags;
|
||||
char passthru[PASSTHRU_LEN+1];
|
||||
} Trigger;
|
||||
|
||||
@@ -73,14 +88,16 @@ typedef struct {
|
||||
|
||||
/* The parse pointer */
|
||||
typedef struct {
|
||||
char isnested; /* Is it a nested expression? */
|
||||
char isnested; /* Is it a nested expression? */
|
||||
char allownested;
|
||||
char *text; /* Start of text */
|
||||
char *pos; /* Current position */
|
||||
char *etext; /* Substituted text */
|
||||
char *epos; /* Position in substituted text */
|
||||
char const *text; /* Start of text */
|
||||
char const *pos; /* Current position */
|
||||
char const *etext; /* Substituted text */
|
||||
char const *epos; /* Position in substituted text */
|
||||
DynamicBuffer pushedToken; /* Pushed-back token */
|
||||
char *tokenPushed; /* NULL if no pushed-back token */
|
||||
char const *tokenPushed; /* NULL if no pushed-back token */
|
||||
char expr_happened; /* Did we encounter an [expression] ? */
|
||||
char nonconst_expr; /* Did we encounter a non-constant [expression] ? */
|
||||
} Parser;
|
||||
|
||||
typedef Parser *ParsePtr; /* Pointer to parser structure */
|
||||
@@ -118,11 +135,12 @@ typedef Parser *ParsePtr; /* Pointer to parser structure */
|
||||
|
||||
|
||||
/* DEFINES for debugging flags */
|
||||
#define DB_PRTLINE 1
|
||||
#define DB_PRTEXPR 2
|
||||
#define DB_PRTTRIG 4
|
||||
#define DB_DUMP_VARS 8
|
||||
#define DB_ECHO_LINE 16
|
||||
#define DB_PRTLINE 1
|
||||
#define DB_PRTEXPR 2
|
||||
#define DB_PRTTRIG 4
|
||||
#define DB_DUMP_VARS 8
|
||||
#define DB_ECHO_LINE 16
|
||||
#define DB_TRACE_FILES 32
|
||||
|
||||
/* Enumeration of the tokens */
|
||||
enum TokTypes
|
||||
@@ -132,7 +150,7 @@ enum TokTypes
|
||||
T_IfTrig, T_ErrMsg,
|
||||
T_Set, T_UnSet, T_Fset, T_Omit, T_Banner, T_Exit,
|
||||
T_WkDay,
|
||||
T_Month, T_Time,
|
||||
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_Once,
|
||||
T_Empty,
|
||||
@@ -148,7 +166,9 @@ enum TokTypes
|
||||
T_Warn,
|
||||
T_Tag,
|
||||
T_Duration,
|
||||
T_LongTime
|
||||
T_LongTime,
|
||||
T_OmitFunc,
|
||||
T_Through
|
||||
};
|
||||
|
||||
/* The structure of a token */
|
||||
@@ -169,8 +189,10 @@ typedef struct {
|
||||
#define IF_ELSE_MASK 2
|
||||
|
||||
/* Flags for the DoSubst function */
|
||||
#define NORMAL_MODE 0
|
||||
#define CAL_MODE 1
|
||||
#define NORMAL_MODE 0
|
||||
#define CAL_MODE 1
|
||||
#define ADVANCE_MODE 2
|
||||
|
||||
#define QUOTE_MARKER 1 /* Unlikely character to appear in reminder */
|
||||
|
||||
/* Flags for disabling run */
|
||||
@@ -187,3 +209,7 @@ typedef struct {
|
||||
#define SORT_NONE 0
|
||||
#define SORT_ASCEND 1
|
||||
#define SORT_DESCEND 2
|
||||
|
||||
/* Flags for FROM / SCANFROM */
|
||||
#define SCANFROM_TYPE 0
|
||||
#define FROM_TYPE 1
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
/***************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
static char const RCSID[] = "$Id: userfns.c,v 1.7 2005-09-30 03:29:32 dfs Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
@@ -30,7 +29,7 @@ static char const RCSID[] = "$Id: userfns.c,v 1.7 2005-09-30 03:29:32 dfs Exp $"
|
||||
typedef struct udf_struct {
|
||||
struct udf_struct *next;
|
||||
char name[VAR_NAME_LEN+1];
|
||||
char *text;
|
||||
char const *text;
|
||||
Var *locals;
|
||||
char IsActive;
|
||||
int nargs;
|
||||
@@ -41,14 +40,14 @@ static UserFunc *FuncHash[FUNC_HASH_SIZE];
|
||||
|
||||
/* Access to built-in functions */
|
||||
extern int NumFuncs;
|
||||
extern Operator Func[];
|
||||
extern BuiltinFunc Func[];
|
||||
|
||||
/* We need access to the expression evaluation stack */
|
||||
extern Value ValStack[];
|
||||
extern int ValStackPtr;
|
||||
|
||||
static void DestroyUserFunc (UserFunc *f);
|
||||
static void FUnset (char *name);
|
||||
static void FUnset (char const *name);
|
||||
static void FSet (UserFunc *f);
|
||||
static int SetUpLocalVars (UserFunc *f);
|
||||
static void DestroyLocalVals (UserFunc *f);
|
||||
@@ -143,6 +142,11 @@ int DoFset(ParsePtr p)
|
||||
}
|
||||
}
|
||||
|
||||
/* Allow an optional = sign: FSET f(x) = x*x */
|
||||
c = ParseNonSpaceChar(p, &r, 1);
|
||||
if (c == '=') {
|
||||
c = ParseNonSpaceChar(p, &r, 0);
|
||||
}
|
||||
/* Copy the text over */
|
||||
if (p->isnested) {
|
||||
Eprint("%s", ErrMsg[E_CANTNEST_FDEF]);
|
||||
@@ -185,7 +189,7 @@ static void DestroyUserFunc(UserFunc *f)
|
||||
}
|
||||
|
||||
/* Free the function definition */
|
||||
if (f->text) free(f->text);
|
||||
if (f->text) free( (char *) f->text);
|
||||
|
||||
/* Free the data structure itself */
|
||||
free(f);
|
||||
@@ -199,7 +203,7 @@ static void DestroyUserFunc(UserFunc *f)
|
||||
/* it exists. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
static void FUnset(char *name)
|
||||
static void FUnset(char const *name)
|
||||
{
|
||||
UserFunc *cur, *prev;
|
||||
int h;
|
||||
@@ -239,12 +243,12 @@ static void FSet(UserFunc *f)
|
||||
/* Call a user-defined function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int CallUserFunc(char *name, int nargs)
|
||||
int CallUserFunc(char const *name, int nargs, ParsePtr p)
|
||||
{
|
||||
UserFunc *f;
|
||||
int h = HashVal(name) % FUNC_HASH_SIZE;
|
||||
int i;
|
||||
char *s;
|
||||
char const *s;
|
||||
|
||||
/* Search for the function */
|
||||
f = FuncHash[h];
|
||||
@@ -295,9 +299,9 @@ int CallUserFunc(char *name, int nargs)
|
||||
s = f->text;
|
||||
|
||||
/* Skip the opening bracket, if there's one */
|
||||
while (isspace(*s)) s++;
|
||||
while (isempty(*s)) s++;
|
||||
if (*s == BEG_OF_EXPR) s++;
|
||||
h = Evaluate(&s, f->locals);
|
||||
h = Evaluate(&s, f->locals, p);
|
||||
f->IsActive = 0;
|
||||
DestroyLocalVals(f);
|
||||
if (DebugFlag &DB_PRTEXPR) {
|
||||
@@ -357,7 +361,7 @@ static void DestroyLocalVals(UserFunc *f)
|
||||
/* it is defined, or -1 if it is not defined. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int UserFuncExists(char *fn)
|
||||
int UserFuncExists(char const *fn)
|
||||
{
|
||||
UserFunc *f;
|
||||
int h = HashVal(fn) % FUNC_HASH_SIZE;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user