mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 06:48:47 +02:00
Initial checkin
This commit is contained in:
103
COPYRIGHT
Normal file
103
COPYRIGHT
Normal file
@@ -0,0 +1,103 @@
|
||||
$Id: COPYRIGHT,v 1.1 1996-03-27 03:25:46 dfs Exp $
|
||||
THE REMIND COPYRIGHT
|
||||
|
||||
1. REMIND refers to the entire set of files and documentation in the
|
||||
REMIND package.
|
||||
|
||||
2. REMIND is Copyright 1992-1996 by David Skoll,
|
||||
except where noted in individual files.
|
||||
|
||||
3. You may use REMIND for free, and may freely distribute it, providing
|
||||
you do not charge the recipients to whom you distribute REMIND.
|
||||
|
||||
4. This means that if you distribute REMIND:
|
||||
|
||||
- You may not charge more than cost for distribution media.
|
||||
- If you run a BBS or network service, you cannot charge more than
|
||||
the regular access fee for REMIND. That is, REMIND must be accessible
|
||||
at the basic BBS access rate, with no surcharge.
|
||||
- You may not charge users support fees for REMIND.
|
||||
- No other fees may be levied for REMIND.
|
||||
- You cannot use REMIND to solicit donations.
|
||||
|
||||
5. You may modify REMIND. However, you must clearly indicate such
|
||||
modifications when you distribute REMIND, and must tell the recipients
|
||||
of the modified version that it is modified. Place that notice in the
|
||||
WHATSNEW.xx file.
|
||||
|
||||
6. You may incorporate parts of REMIND into your own programs,
|
||||
providing you do not sell these programs. You must clearly indicate
|
||||
that the parts of REMIND you have incorporated are Copyright 1992-1996
|
||||
by David Skoll. These programs can be distributed according to the terms
|
||||
of paragraphs 3 and 4.
|
||||
|
||||
7. I will attempt to support REMIND as much as possible. However,
|
||||
REMIND is supplied on an "as-is" basis with no warranty. You use it
|
||||
at your own risk. I am not responsible for any damages caused by the
|
||||
use or misuse of REMIND.
|
||||
|
||||
8. If you wish to contribute ideas or money to help the production of
|
||||
software like REMIND, you can reply to the address shown at the end of
|
||||
this file. Note that you are under no obligation to send me money.
|
||||
If you don't donate, you have full rights to use REMIND just as if you
|
||||
had donated. If you do donate, you get a big thank-you, but no
|
||||
special rights. However, you will have helped support the production
|
||||
of software like REMIND. Should you wish to donate, the suggested
|
||||
amount is $18.00 (Canadian)
|
||||
|
||||
If you wish to incorporate Remind into a commercial product, or to
|
||||
charge support fees for products incorporating Remind, contact
|
||||
me for licensing arrangements.
|
||||
|
||||
ACKNOWLEDGEMENTS:
|
||||
|
||||
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
|
||||
|
||||
Timo Salmi, Keith Petersen, Bill Davidsen and Kent Landfield for
|
||||
maintaining the uwasa and SIMTEL archives, and comp.binaries.ibm.pc
|
||||
and comp.sources.misc in the face of a flurry of updates to REMIND.
|
||||
|
||||
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@doe.carleton.ca>
|
||||
986 Eiffel Avenue
|
||||
Ottawa, Ontario K2C 0J2
|
||||
CANADA
|
||||
|
||||
Tel. (613) 225-8687
|
||||
|
||||
72
MANIFEST.DOS
Normal file
72
MANIFEST.DOS
Normal file
@@ -0,0 +1,72 @@
|
||||
calendar.c
|
||||
config.h
|
||||
copyrigh
|
||||
danish.h
|
||||
defs.rem
|
||||
dorem.c
|
||||
dosubst.c
|
||||
dutch.h
|
||||
english.h
|
||||
err.h
|
||||
expr.c
|
||||
expr.h
|
||||
files.c
|
||||
finnish.h
|
||||
french.h
|
||||
funcs.c
|
||||
german.h
|
||||
globals.c
|
||||
globals.h
|
||||
hbcal.c
|
||||
init.c
|
||||
kall
|
||||
kall.1
|
||||
lang.h
|
||||
lnk.bcc
|
||||
lnk.msc
|
||||
lnk.tc
|
||||
main.c
|
||||
makefile
|
||||
makefile.bcc
|
||||
makefile.msc
|
||||
makefile.os2
|
||||
makefile.tc
|
||||
manifest.dos
|
||||
manifest.unx
|
||||
moon.c
|
||||
norwgian.h
|
||||
omit.c
|
||||
os2func.c
|
||||
polish.h
|
||||
protos.h
|
||||
queue.c
|
||||
readme.bcc
|
||||
readme.dos
|
||||
readme.os2
|
||||
readme.uni
|
||||
rem
|
||||
rem.1
|
||||
rem2ps.1
|
||||
rem2ps.c
|
||||
rem2ps.h
|
||||
remind-a.csh
|
||||
remind-a.sh
|
||||
remind.1
|
||||
remind.def
|
||||
sort.c
|
||||
test-rem
|
||||
test-rem.bat
|
||||
test-rem.cmd
|
||||
test.cmp
|
||||
test.rem
|
||||
test1.cmp
|
||||
test2.cmp
|
||||
token.c
|
||||
trigger.c
|
||||
tstlang.rem
|
||||
types.h
|
||||
userfns.c
|
||||
utils.c
|
||||
var.c
|
||||
version.h
|
||||
whatsnew.30
|
||||
72
MANIFEST.UNX
Normal file
72
MANIFEST.UNX
Normal file
@@ -0,0 +1,72 @@
|
||||
COPYRIGHT
|
||||
MANIFEST.DOS
|
||||
MANIFEST.UNX
|
||||
Makefile
|
||||
README.BCC
|
||||
README.DOS
|
||||
README.OS2
|
||||
README.UNIX
|
||||
WHATSNEW.30
|
||||
calendar.c
|
||||
config.h
|
||||
danish.h
|
||||
defs.rem
|
||||
dorem.c
|
||||
dosubst.c
|
||||
dutch.h
|
||||
english.h
|
||||
err.h
|
||||
expr.c
|
||||
expr.h
|
||||
files.c
|
||||
finnish.h
|
||||
french.h
|
||||
funcs.c
|
||||
german.h
|
||||
globals.c
|
||||
globals.h
|
||||
hbcal.c
|
||||
init.c
|
||||
kall
|
||||
kall.1
|
||||
lang.h
|
||||
lnk.bcc
|
||||
lnk.msc
|
||||
lnk.tc
|
||||
main.c
|
||||
makefile.bcc
|
||||
makefile.msc
|
||||
makefile.os2
|
||||
makefile.tc
|
||||
moon.c
|
||||
norwgian.h
|
||||
omit.c
|
||||
os2func.c
|
||||
polish.h
|
||||
protos.h
|
||||
queue.c
|
||||
rem
|
||||
rem.1
|
||||
rem2ps.1
|
||||
rem2ps.c
|
||||
rem2ps.h
|
||||
remind-all.csh
|
||||
remind-all.sh
|
||||
remind.1
|
||||
remind.def
|
||||
sort.c
|
||||
test-rem
|
||||
test-rem.bat
|
||||
test-rem.cmd
|
||||
test.cmp
|
||||
test.rem
|
||||
test1.cmp
|
||||
test2.cmp
|
||||
token.c
|
||||
trigger.c
|
||||
tstlang.rem
|
||||
types.h
|
||||
userfns.c
|
||||
utils.c
|
||||
var.c
|
||||
version.h
|
||||
210
Makefile
Normal file
210
Makefile
Normal file
@@ -0,0 +1,210 @@
|
||||
# Makefile for REMIND
|
||||
# $Id: Makefile,v 1.1 1996-03-27 03:25:48 dfs Exp $
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# 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= gcc
|
||||
LD= gcc
|
||||
|
||||
# Put any additional flags for the C compiler or linker here - if you
|
||||
# are not using gcc, you probably want to remove '-ansi'.
|
||||
CFLAGS= -O -ansi
|
||||
CDEFS=
|
||||
LDFLAGS=
|
||||
|
||||
#### INSTALLATION LOCATIONS ####
|
||||
# Note that I use 'cp' rather than 'install' for improved portability.
|
||||
#
|
||||
# BINDIR: Where should the Remind executable be installed?
|
||||
BINDIR= /usr/local/bin
|
||||
|
||||
# SCRIPTDIR: Where should the kall and rem shell scripts be installed?
|
||||
SCRIPTDIR= /usr/local/bin
|
||||
|
||||
# MANDIR: Where should the man pages be installed?
|
||||
MANDIR= /usr/local/man
|
||||
|
||||
# MANSECT: Which man section should the man pages go into?
|
||||
MANSECT= 1
|
||||
|
||||
# EXEMODE: What file protection mode should be used for the executables?
|
||||
EXEMODE= 755
|
||||
|
||||
# MANMODE: What file protection mode should be used for the man pages?
|
||||
MANMODE= 644
|
||||
|
||||
# OWNER, GROUP: What owner and group to use for executables,
|
||||
# scripts and man pages?
|
||||
OWNER=bin
|
||||
GROUP=bin
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# 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'.
|
||||
#-----------------------------------------------------------------------------
|
||||
VERSION= 03.00.13
|
||||
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
|
||||
|
||||
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 rem2ps
|
||||
|
||||
.c.o:
|
||||
$(CC) $(UNIX) $(SYSV) -c $(CFLAGS) $(CDEFS) $*.c
|
||||
|
||||
rem2ps: rem2ps.o
|
||||
$(LD) $(LDFLAGS) -o rem2ps rem2ps.o
|
||||
|
||||
remind: $(OBJS)
|
||||
$(LD) $(LDFLAGS) -o remind $(OBJS) $(MATHLIB)
|
||||
|
||||
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
|
||||
|
||||
tarZ:
|
||||
tar cvf remind-3.0.13.tar $(MANIFEST)
|
||||
compress -v remind-3.0.13.tar
|
||||
|
||||
shar:
|
||||
shar -x -n"Remind $(VERSION)" -l45 -o./Shar $(MANIFEST)
|
||||
|
||||
todos:
|
||||
mcopy -tn $(MANIFEST) a:
|
||||
|
||||
fromdos:
|
||||
mcopy -tn 'a:*' .
|
||||
-mv -f copyrigh COPYRIGHT
|
||||
-mv -f makefile Makefile
|
||||
-mv -f readme.os2 README.OS2
|
||||
-mv -f readme.dos README.DOS
|
||||
-mv -f readme.bcc README.BCC
|
||||
-mv -f readme.uni README.UNIX
|
||||
-mv -f remind-a.csh remind-all.csh
|
||||
-mv -f remind-a.sh remind-all.sh
|
||||
-mv -f manifest.dos MANIFEST.DOS
|
||||
-mv -f manifest.unx MANIFEST.UNX
|
||||
-mv -f whatsnew.30 WHATSNEW.30
|
||||
-chmod u+x test-rem
|
||||
|
||||
backup:
|
||||
cp $(MANIFEST) ../backup
|
||||
|
||||
transmit:
|
||||
sz -a -e $(MANIFEST)
|
||||
|
||||
install: install-bin install-scripts install-man
|
||||
|
||||
install-bin: remind rem2ps
|
||||
cp remind $(BINDIR)/remind
|
||||
-chmod $(EXEMODE) $(BINDIR)/remind
|
||||
-chown $(OWNER) $(BINDIR)/remind
|
||||
-chgrp $(GROUP) $(BINDIR)/remind
|
||||
cp rem2ps $(BINDIR)/rem2ps
|
||||
-chmod $(EXEMODE) $(BINDIR)/rem2ps
|
||||
-chown $(OWNER) $(BINDIR)/rem2ps
|
||||
-chgrp $(GROUP) $(BINDIR)/rem2ps
|
||||
|
||||
install-scripts:
|
||||
cp kall $(SCRIPTDIR)/kall
|
||||
-chmod $(EXEMODE) $(SCRIPTDIR)/kall
|
||||
-chown $(OWNER) $(SCRIPTDIR)/kall
|
||||
-chgrp $(GROUP) $(SCRIPTDIR)/kall
|
||||
cp rem $(SCRIPTDIR)/rem
|
||||
-chmod $(EXEMODE) $(SCRIPTDIR)/rem
|
||||
-chown $(OWNER) $(SCRIPTDIR)/rem
|
||||
-chgrp $(GROUP) $(SCRIPTDIR)/rem
|
||||
|
||||
install-man:
|
||||
cp remind.1 $(MANDIR)/man$(MANSECT)/remind.$(MANSECT)
|
||||
-chmod $(MANMODE) $(MANDIR)/man$(MANSECT)/remind.$(MANSECT)
|
||||
-chown $(OWNER) $(MANDIR)/man$(MANSECT)/remind.$(MANSECT)
|
||||
-chgrp $(GROUP) $(MANDIR)/man$(MANSECT)/remind.$(MANSECT)
|
||||
cp rem.1 $(MANDIR)/man$(MANSECT)/rem.$(MANSECT)
|
||||
-chmod $(MANMODE) $(MANDIR)/man$(MANSECT)/rem.$(MANSECT)
|
||||
-chown $(OWNER) $(MANDIR)/man$(MANSECT)/rem.$(MANSECT)
|
||||
-chgrp $(GROUP) $(MANDIR)/man$(MANSECT)/rem.$(MANSECT)
|
||||
cp kall.1 $(MANDIR)/man$(MANSECT)/kall.$(MANSECT)
|
||||
-chmod $(MANMODE) $(MANDIR)/man$(MANSECT)/kall.$(MANSECT)
|
||||
-chown $(OWNER) $(MANDIR)/man$(MANSECT)/kall.$(MANSECT)
|
||||
-chgrp $(GROUP) $(MANDIR)/man$(MANSECT)/kall.$(MANSECT)
|
||||
cp rem2ps.1 $(MANDIR)/man$(MANSECT)/rem2ps.$(MANSECT)
|
||||
-chmod $(MANMODE) $(MANDIR)/man$(MANSECT)/rem2ps.$(MANSECT)
|
||||
-chown $(OWNER) $(MANDIR)/man$(MANSECT)/rem2ps.$(MANSECT)
|
||||
-chgrp $(GROUP) $(MANDIR)/man$(MANSECT)/rem2ps.$(MANSECT)
|
||||
|
||||
release:
|
||||
-mkdir RELEASE
|
||||
-rm -f RELEASE/*
|
||||
mkpatch ../prev . patch.13 Shar "Remind-3.0/Patch-13/part"
|
||||
mv Shar* RELEASE
|
||||
rm -f patch.13*
|
||||
for i in *.1; do nroff -man $$i | sed -e 's/_//g' > `basename $$i .1`.man; done
|
||||
mv *.man RELEASE
|
||||
for i in *.1; do groff -man -Tps $$i > `basename $$i .1`.ps; done
|
||||
mv *.ps RELEASE
|
||||
|
||||
# Meant for debugging - don't invoke this target unless you know what
|
||||
# you're doing!
|
||||
majortest:
|
||||
for comp in "cc" "gcc -Wall -pedantic -ansi" ; do for lang in 1 2 3 4 5 0 ; do for def in ISOLATIN1 IBMEXTENDED FOOBARBAZ ; do echo $$def $$lang ; $(MAKE) clobber ; $(MAKE) "CDEFS=-DLANG=$$lang -D$$def=1" CFLAGS=-O "CC=$$comp" "LD=$$comp" ; done ; done ; done
|
||||
|
||||
65
README.BCC
Normal file
65
README.BCC
Normal file
@@ -0,0 +1,65 @@
|
||||
$Id: README.BCC,v 1.1 1996-03-27 03:25:48 dfs Exp $
|
||||
REMIND version 3.0 for Borland C++
|
||||
|
||||
1 - Read the file COPYRIGHT. (This may be called COPYRIGH on your
|
||||
MS-DOS system.)
|
||||
|
||||
2 - You must use the Borland C++ OS/2 or MSDOS/Windows compiler.
|
||||
|
||||
3 - Examine the file config.h and adjust parameters as needed
|
||||
|
||||
4 - Examine the file makefile.bcc and adjust parameters as needed.
|
||||
|
||||
5 - Type:
|
||||
|
||||
make -f makefile.bcc
|
||||
|
||||
This will make 'remind.exe' and 'rem2ps.exe' in the ..\os2-ex or ..\msdos-ex
|
||||
directories.
|
||||
|
||||
The file "defs.rem" has some sample Remind definitions and commands,
|
||||
as well as U.S. and Jewish holidays.
|
||||
|
||||
NOTE that I do not have access to an OS/2 system, so support for this
|
||||
system may not be as good as I'd like.
|
||||
|
||||
OS/2 support is courtesy of Russ Herman <rwh@gov.on.ca>, Norman Walsh
|
||||
<norm@ora.com>, and Darrel Hankerson <hankedr@mail.auburn.edu>.
|
||||
However, if you have problems, please contact me.
|
||||
|
||||
OTHER LANGUAGE SUPPORT
|
||||
|
||||
Remind has support for languages other than English. See the file
|
||||
"lang.h" for details. The language support may vary - you can change
|
||||
only the substitution filter, or you can translate all of the usage
|
||||
instructions and error messages as well. See "french.h" for an
|
||||
example of the latter.
|
||||
|
||||
If you add support for a non-English language, Remind will accept both the
|
||||
English and non-English names of months and weekdays in an input script.
|
||||
However, you should not rely on this feature if you want to write portable
|
||||
Remind scripts.
|
||||
|
||||
At a minimum, you should support month and day names in the foreign
|
||||
language, and should modify the substitution filter appropriately.
|
||||
If you are truly diligent, you can translate usage and error messages
|
||||
too.
|
||||
|
||||
Take a look at the files "english.h" and "german.h" if you want to add
|
||||
support for your favourite language. If you do add another language
|
||||
to Remind, please let me know! Here are the basic guidelines:
|
||||
|
||||
- Your language file should be called "lxxx.h", where lxxx is the first 8
|
||||
characters of the ENGLISH name of your language.
|
||||
|
||||
- You should define L_LANGNAME to be the full English name of your language,
|
||||
with the first letter capitalized and the rest lower-case.
|
||||
|
||||
--
|
||||
David F. Skoll <dfs@doe.carleton.ca>
|
||||
986 Eiffel Avenue
|
||||
Ottawa, Ontario K2C 0J2
|
||||
CANADA
|
||||
|
||||
Tel. (613) 225-8687
|
||||
|
||||
59
README.DOS
Normal file
59
README.DOS
Normal file
@@ -0,0 +1,59 @@
|
||||
$Id: README.DOS,v 1.1 1996-03-27 03:25:49 dfs Exp $
|
||||
REMIND version 3.0 for MS-DOS
|
||||
|
||||
REMIND is a sophisticated alarm/calendar program. Details are given
|
||||
in the man page, "remind.1".
|
||||
|
||||
1 - Read the file COPYRIGHT. (This may be called COPYRIGH on your
|
||||
MS-DOS system.)
|
||||
|
||||
2 - Examine the file config.h and adjust parameters as needed
|
||||
|
||||
3 - If you are using Turbo C to compile Remind, type:
|
||||
|
||||
make -fmakefile.tc
|
||||
|
||||
If you are using Microsoft C to compile Remind, type:
|
||||
|
||||
make makefile.msc
|
||||
|
||||
This will create REMIND.EXE, which is ready to be executed.
|
||||
|
||||
The file "defs.rem" has some sample Remind definitions and commands,
|
||||
as well as U.S. and Jewish holidays.
|
||||
|
||||
OTHER LANGUAGE SUPPORT
|
||||
|
||||
Remind has support for languages other than English. See the file
|
||||
"lang.h" for details. The language support may vary - you can change
|
||||
only the substitution filter, or you can translate all of the usage
|
||||
instructions and error messages as well. See "french.h" for an example.
|
||||
|
||||
If you add support for a non-English language, Remind will accept both the
|
||||
English and non-English names of months and weekdays in an input script.
|
||||
However, you should not rely on this feature if you want to write portable
|
||||
Remind scripts.
|
||||
|
||||
At a minimum, you should support month and day names in the foreign
|
||||
language, and should modify the substitution filter appropriately.
|
||||
If you are truly diligent, you can translate usage and error messages
|
||||
too.
|
||||
|
||||
Take a look at the files "english.h" and "german.h" if you want to add
|
||||
support for your favourite language. If you do add another language
|
||||
to Remind, please let me know! Here are the basic guidelines:
|
||||
|
||||
- Your language file should be called "lxxx.h", where lxxx is the first 8
|
||||
characters of the ENGLISH name of your language.
|
||||
|
||||
- You should define L_LANGNAME to be the full English name of your language,
|
||||
with the first letter capitalized and the rest lower-case.
|
||||
|
||||
--
|
||||
David F. Skoll <dfs@doe.carleton.ca>
|
||||
986 Eiffel Avenue
|
||||
Ottawa, Ontario K2C 0J2
|
||||
CANADA
|
||||
|
||||
Tel. (613) 225-8687
|
||||
|
||||
137
README.OS2
Normal file
137
README.OS2
Normal file
@@ -0,0 +1,137 @@
|
||||
$Id: README.OS2,v 1.1 1996-03-27 03:25:49 dfs Exp $
|
||||
REMIND version 3.0 for OS/2
|
||||
|
||||
This file contains instructions for compiling Remind under OS/2 with
|
||||
Eberhard Mattes' emx/gcc compiler and with the Microsoft C compiler.
|
||||
There are a number of targets in Makefile.os2, including OS/2-only
|
||||
versions and bound versions (programs which run under OS/2 and DOS).
|
||||
|
||||
Note that there is also support for OS/2 using the Borland C
|
||||
compiler--see the file README.BCC for details.
|
||||
|
||||
REMIND is a sophisticated alarm/calendar program. Details are given
|
||||
in the man page, "remind.1".
|
||||
|
||||
1 - Read the file COPYRIGHT. (This may be called COPYRIGH on your
|
||||
MS-DOS system.)
|
||||
|
||||
2 - To compile Remind for OS/2, you must use the Microsoft C compiler
|
||||
or emx/gcc. You must also have a decent version of 'make', such
|
||||
as dmake or GNU make.
|
||||
|
||||
3 - Examine the file config.h and adjust parameters as needed
|
||||
|
||||
4 - Examine the file Makefile.os2 and adjust parameters as needed.
|
||||
|
||||
5 - Type:
|
||||
|
||||
make -f Makefile.os2
|
||||
|
||||
to see a list of targets. For example,
|
||||
|
||||
make -f Makefile.os2 emx
|
||||
|
||||
will build a 32-bit emx version which runs under OS/2 2.x and DOS.
|
||||
|
||||
The file "defs.rem" has some sample Remind definitions and commands,
|
||||
as well as U.S. and Jewish holidays.
|
||||
|
||||
NOTE that I do not have access to an OS/2 system, so support for this
|
||||
system may not be as good as I'd like.
|
||||
|
||||
OS/2 support is courtesy of Russ Herman <rwh@gov.on.ca>, Norman Walsh
|
||||
<norm@ora.com>, and Darrel Hankerson <hankedr@mail.auburn.edu>.
|
||||
However, if you have problems, please contact me.
|
||||
|
||||
OTHER LANGUAGE SUPPORT
|
||||
|
||||
Remind has support for languages other than English. See the file
|
||||
"lang.h" for details. The language support may vary - you can change
|
||||
only the substitution filter, or you can translate all of the usage
|
||||
instructions and error messages as well. See "french.h" for an
|
||||
example of the latter.
|
||||
|
||||
If you add support for a non-English language, Remind will accept both the
|
||||
English and non-English names of months and weekdays in an input script.
|
||||
However, you should not rely on this feature if you want to write portable
|
||||
Remind scripts.
|
||||
|
||||
At a minimum, you should support month and day names in the foreign
|
||||
language, and should modify the substitution filter appropriately.
|
||||
If you are truly diligent, you can translate usage and error messages
|
||||
too.
|
||||
|
||||
Take a look at the files "english.h" and "german.h" if you want to add
|
||||
support for your favourite language. If you do add another language
|
||||
to Remind, please let me know! Here are the basic guidelines:
|
||||
|
||||
- Your language file should be called "lxxx.h", where lxxx is the first 8
|
||||
characters of the ENGLISH name of your language.
|
||||
|
||||
- You should define L_LANGNAME to be the full English name of your language,
|
||||
with the first letter capitalized and the rest lower-case.
|
||||
|
||||
RELEASE NOTES -- miscellaneous info that couldn't go anywhere else!
|
||||
|
||||
1. POPUP REMINDERS
|
||||
|
||||
If you define the symbol OS2_POPUP in the OS/2 Makefile, you get
|
||||
"full-screen popups" (as implemented by Russ Herman) for all MSG-
|
||||
and MSF-type reminders. You may or may not like this feature.
|
||||
|
||||
One way of implementing popup reminders is to get the program
|
||||
"pmpopup.exe" from ftp-os2.cdrom.com, and using Remind with the
|
||||
'-k' option as follows from C:\STARTUP.CMD:
|
||||
|
||||
start /pm /inv /n remind "-kstart pmpopup %%s" remfile
|
||||
|
||||
Alternatively, if you have the Vrexx package, you can use this
|
||||
procedure suggested by Norman Walsh:
|
||||
|
||||
Start remind like this in C:\STARTUP.CMD:
|
||||
|
||||
start /pm /inv /n \bin\remind -faz "-kstart popupmsg %%s" .reminders
|
||||
|
||||
The popups are done by POPUPMSG.CMD which looks like this:
|
||||
|
||||
-------------- Cut Here ---------- Cut Here ---------- Cut Here --------
|
||||
/* PopUpMsg */
|
||||
|
||||
'@echo off'
|
||||
|
||||
parse arg theargs
|
||||
if theargs = "" then
|
||||
theargs = "Empty message"
|
||||
|
||||
call RxFuncAdd 'VInit', 'VREXX', 'VINIT'
|
||||
initcode = VInit()
|
||||
if initcode = 'ERROR' then signal CLEANUP
|
||||
|
||||
signal on failure name CLEANUP
|
||||
signal on halt name CLEANUP
|
||||
signal on syntax name CLEANUP
|
||||
|
||||
/* example VMsgBox call */
|
||||
|
||||
msg.0 = 1
|
||||
msg.1 = theargs
|
||||
|
||||
call VDialogPos 50, 50
|
||||
call VMsgBox 'Popup Message', msg, 1
|
||||
|
||||
/* end of CMD file */
|
||||
|
||||
CLEANUP:
|
||||
call VExit
|
||||
|
||||
exit
|
||||
-------------- Cut Here ---------- Cut Here ---------- Cut Here --------
|
||||
|
||||
--
|
||||
David F. Skoll <dfs@doe.carleton.ca>
|
||||
986 Eiffel Avenue
|
||||
Ottawa, Ontario K2C 0J2
|
||||
CANADA
|
||||
|
||||
Tel. (613) 225-8687
|
||||
|
||||
139
README.UNIX
Normal file
139
README.UNIX
Normal file
@@ -0,0 +1,139 @@
|
||||
$Id: README.UNIX,v 1.1 1996-03-27 03:25:49 dfs Exp $
|
||||
REMIND version 3.0 for UNIX
|
||||
|
||||
REMIND is a sophisticated alarm/calendar program. Details are given
|
||||
in the man page, "remind.1".
|
||||
|
||||
1 - Read the file COPYRIGHT.
|
||||
|
||||
2- Before compiling the software, check to see if it includes patches.
|
||||
These are files called patch.xx. If there are patches, apply them all
|
||||
by typing:
|
||||
|
||||
cat patch.* | patch
|
||||
|
||||
3 - Examine the Makefile and change any parameters which need to be
|
||||
changed for your system. As it stands, the Makefile is set up for a
|
||||
BSD system.
|
||||
|
||||
4 - Examine the file config.h and adjust parameters as needed
|
||||
|
||||
5 - Examine lang.h and choose the language you want Remind to use.
|
||||
|
||||
6 - Type 'make'
|
||||
|
||||
7 - Type 'sh test-rem' or 'make test' to run the acceptance test. Note
|
||||
that the test script works only for the English version of Remind.
|
||||
|
||||
8 - Type 'make install' to install Remind, kall, rem and the man
|
||||
pages.
|
||||
|
||||
Two shell scripts, "remind-all.csh" and "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.
|
||||
|
||||
*** NOTE *** Please be aware that "remind-all.csh" and "remind-all.sh"
|
||||
have been changed since version 03.00.05 of Remind. If you install
|
||||
the new remind executable, make sure you switch over to the new
|
||||
"remind-all" scripts.
|
||||
|
||||
A shell script called "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 "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 "defs.rem" has some sample Remind definitions and commands,
|
||||
as well as U.S. and Jewish holidays.
|
||||
|
||||
OTHER LANGUAGE SUPPORT
|
||||
|
||||
Remind has support for languages other than English. See the file
|
||||
"lang.h" for details. The language support may vary - you can change
|
||||
only the substitution filter, or you can translate all of the usage
|
||||
instructions and error messages as well. See "french.h" for an
|
||||
example of the latter.
|
||||
|
||||
If you add support for a non-English language, Remind will accept both the
|
||||
English and non-English names of months and weekdays in an input script.
|
||||
However, you should not rely on this feature if you want to write portable
|
||||
Remind scripts.
|
||||
|
||||
At a minimum, you should support month and day names in the foreign
|
||||
language, and should modify the substitution filter appropriately.
|
||||
If you are truly diligent, you can translate usage and error messages
|
||||
too.
|
||||
|
||||
Take a look at the files "english.h" and "german.h" if you want to add
|
||||
support for your favourite language. If you do add another language
|
||||
to Remind, please let me know! Here are the basic guidelines:
|
||||
|
||||
- Your language file should be called "lxxx.h", where lxxx is the first 8
|
||||
characters of the ENGLISH name of your language.
|
||||
|
||||
- Your language file should define L_LANGNAME to be the full English
|
||||
name of your language, with the first letter capitalized and the rest
|
||||
lower-case.
|
||||
|
||||
RELEASE NOTES -- miscellaneous info that couldn't go anywhere else!
|
||||
|
||||
1. POPUP REMINDERS
|
||||
|
||||
If you're running under X-Windows and you have the TCL tools,
|
||||
you can create simple pop-up reminders by creating the following
|
||||
TCL script called 'popup'. It pops a message on to the screen and
|
||||
waits for you to press the 'OK' button. If you don't press the OK button
|
||||
within 15 seconds, it exits anyway. To use it, you can use the '-k' option
|
||||
for Remind as follows:
|
||||
|
||||
remind "-kpopup '%s'&" .reminders
|
||||
|
||||
Or use the following in your Remind script:
|
||||
|
||||
REM AT 17:00 RUN popup 'Time to go home.' &
|
||||
|
||||
This TCL script is a slightly modified version of one submitted by
|
||||
Norman Walsh. TCL is available via FTP at ftp.uu.net in /languages/tcl.
|
||||
|
||||
-------------- Cut Here ---------- Cut Here ---------- Cut Here -------------
|
||||
#!/usr/local/bin/wish -f
|
||||
|
||||
wm withdraw .
|
||||
|
||||
if { [ llength $argv ] == 1 } {
|
||||
eval set msg $argv
|
||||
} else {
|
||||
eval set msg [ list $argv ]
|
||||
}
|
||||
|
||||
after 15000 { destroy . ; exit }
|
||||
|
||||
tk_dialog .d { Message } $msg warning 0 { OK }
|
||||
|
||||
destroy .
|
||||
|
||||
exit
|
||||
-------------- Cut Here ---------- Cut Here ---------- Cut Here -------------
|
||||
|
||||
|
||||
--
|
||||
David F. Skoll <dfs@doe.carleton.ca>
|
||||
986 Eiffel Avenue
|
||||
Ottawa, Ontario K2C 0J2
|
||||
CANADA
|
||||
|
||||
Tel. (613) 225-8687
|
||||
613
WHATSNEW.30
Normal file
613
WHATSNEW.30
Normal file
@@ -0,0 +1,613 @@
|
||||
CHANGES TO REMIND
|
||||
|
||||
* Version 3.0 Patch 13
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- Added extra parameters to the "psmoon" built-in function so you
|
||||
can annotate the PostScript moon icons.
|
||||
|
||||
- Added a command-line "time" argument to Remind for testing Remind
|
||||
scripts with specific system times. Also added the realnow() function
|
||||
which has the same relationship to now() as realtoday() has to today().
|
||||
(See the man page!)
|
||||
|
||||
- Modified Rem2PS so it prints progress messages to stderr if
|
||||
'-v' command-line argument is used.
|
||||
|
||||
- In the top of the 'finnish.h' file, added a note about
|
||||
Mikko Silvonen's file of Finnish holidays.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- Fixed a bug in rem2ps which sometimes caused incorrect PostScript if
|
||||
the -e and -m options were used. Thanks to Michael Neuhauser for
|
||||
reporting the bug and providing a fix.
|
||||
|
||||
- Made the '-k' option escape shell characters in the message to make it
|
||||
safer.
|
||||
|
||||
- Fixed a segmentation violation which resulted if not all
|
||||
PUSH-OMIT-CONTEXTs were balanced by POP-OMIT-CONTEXTs.
|
||||
|
||||
- Removed the prototype for DestroyValue, which is now a macro. I'm
|
||||
amazed that very few compilers complained about this one!
|
||||
|
||||
- Updated the copyright notices everywhere.
|
||||
|
||||
* Version 3.0 Patch 12
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- Added support for the Danish language, courtesy of Mogens Lynnerup.
|
||||
|
||||
- Added support for the Polish language, courtesy of Jerzy Sobczyk.
|
||||
|
||||
- Made the Makefile more portable, thanks to Jim Budler.
|
||||
|
||||
- Removed some compiler warnings under Linux, thanks to Francois Pinard.
|
||||
|
||||
- Tidied the man page a bit; added a small bibliography.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- 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
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- Added release notes to README.UNIX and README.OS2 describing one
|
||||
way to make pop-up alarms under X-Windows and Presentation Manager.
|
||||
|
||||
- Added the $DefaultPrio system variable
|
||||
|
||||
- Improved OS/2 support, thanks to Darrel Hankerson, Russ Herman
|
||||
and Norman Walsh.
|
||||
|
||||
- Made the pushing and popping of operators and operands during
|
||||
expression evaluation in-line code instead of function calls. Did the
|
||||
same for DestroyValue. I'm not sure if this was a good idea -- on the
|
||||
Sparc using gcc, this slowed things down... go figure.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- Fixed a potential memory leak in the char() function.
|
||||
|
||||
- Made the TRIGGER() built-in function return its answer in English even
|
||||
for the foreign-language versions -- this was required for compilers which
|
||||
are not 8-bit clean, and for languages with accented letters.
|
||||
|
||||
- Made expression evaluation slightly faster by eliminating some unnecessary
|
||||
copying of string values.
|
||||
|
||||
- Corrected some non-portable definitions of the macro UPPER(c)
|
||||
|
||||
- Fixed typos in french.h
|
||||
|
||||
* Version 3.0 Patch 10
|
||||
|
||||
+ MAJOR ENHANCEMENT
|
||||
|
||||
- OS/2 support is now much better, thanks to Russ Herman. The Borland
|
||||
C compiler under OS/2 and MS-DOS is supported.
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- Added the SCHED keyword for precise control of scheduling of timed
|
||||
reminders -- it's really quite nifty!
|
||||
|
||||
- Modified the trigger() function to take up to three arguments -- in
|
||||
addition to a date, you can specify a time and a flag specifying that
|
||||
the trigger should be converted from UTC to local time.
|
||||
|
||||
- Added $SortByDate, $SortByTime and $SortByPrio system variables.
|
||||
|
||||
- Added test suites for MS-DOS and OS/2, courtesy of Russ Herman.
|
||||
|
||||
- In PostScript output, the month and year are output in the %%Page: comments.
|
||||
Makes it nicer to view multi-month calendars with previewers (eg,
|
||||
GhostView.)
|
||||
|
||||
- Added the PRIORITY keyword for more control of sort order of reminders.
|
||||
Based on a suggestion by George M. Sipe.
|
||||
|
||||
- Added the msgprefix() and msgsuffix() evaluations around MSG-type
|
||||
reminders for doing fancy things with reminders of different priorities.
|
||||
Also added calprefix() and calsuffix() for doing the same thing in
|
||||
calendar mode.
|
||||
|
||||
- Enabled the -g option during calendar mode as well as regular mode.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- Fixed minor bugs in the LocalToUTC and UTCToLocal functions.
|
||||
|
||||
- "remind -c -de file" used to cause a segmentation violation. Whoops...
|
||||
|
||||
- Some files which should have included <string.h> didn't include it - these
|
||||
are now fixed.
|
||||
|
||||
- Fixed the moondate() and moontime() functions, which used to be incorrect
|
||||
after November 1994.
|
||||
|
||||
- Fixed the Finnish language support which was missing a few newlines.
|
||||
|
||||
* Version 3.0 Patch 9
|
||||
|
||||
+ NOTES
|
||||
|
||||
- Remind is now too big to compile under the "small" model in
|
||||
MS-DOS. You must recompile everything under the "medium" model.
|
||||
|
||||
+ MAJOR ENHANCEMENTS
|
||||
|
||||
- Functions moonphase(), moondate() and moontime() were added for dealing
|
||||
with phases of the moon. The code was snarfed from "moontool" by
|
||||
John Walker - see the file "moon.c" for detailed acknowledgement. Also
|
||||
added psmoon() for putting little moon symbols on the PostScript calendar.
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- Added some more examples to defs.rem - notably, support for ANSI
|
||||
terminal color-changing escape sequences, thanks to Gail Gurman.
|
||||
|
||||
- Modified both Remind and Rem2PS so that calendars can start on Sunday or
|
||||
Monday, depending on your preference. Unfortunately, the command-line
|
||||
options are different -- for Remind, it's '-m' and for Rem2PS it's '-n'
|
||||
because '-m' was already in use. Based on a suggestion by John Plate
|
||||
and a patch sent by Mikko Silvonen.
|
||||
|
||||
- The Finnish language support is better - now, all usage and error
|
||||
messages are in Finnish. In addition, the Finnish language module
|
||||
supports the IBM extended character set as well as ISOLATIN1.
|
||||
Thanks to Mikko Silvonen.
|
||||
|
||||
- Modified Rem2PS to allow more control over the placement of the small
|
||||
calendars, thanks to a suggestion by Frank Vance. Also added option
|
||||
to control the calendar title (e.g., "September 1993") independently
|
||||
of day-of-week headings.
|
||||
|
||||
- Added the psshade() function to make it easier to shade PostScript
|
||||
calendars.
|
||||
|
||||
- Allowed a repeat parameter '*num' to be supplied on command line so
|
||||
a 'preview' of many days' worth of reminders can be obtained easily.
|
||||
|
||||
- Added the $Location system variable.
|
||||
|
||||
- Allowed an expression to be supplied to EXIT to return an exit
|
||||
status.
|
||||
|
||||
- Added the FLUSH command.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- Fixed the MSF-type reminder to fill paragraphs more intelligently.
|
||||
It puts double spaces after '!', '.' and '?', and can handle quotes,
|
||||
brackets, etc. after periods, etc. These characters can be specified
|
||||
with the $EndSent and $EndSentIg system variables. Also modified it
|
||||
so that newlines in the body start new paragraphs, rather than being
|
||||
swallowed as white-space.
|
||||
|
||||
* Version 3.0 Patch 8
|
||||
|
||||
+ MAJOR ENHANCEMENTS
|
||||
|
||||
- Changed the code to more fully support foreign languages - error
|
||||
messages and usage instructions can now be changed. All changes can
|
||||
be localized in the appropriate language.h files.
|
||||
|
||||
- Added support for the French language, courtesy of Laurent Duperval.
|
||||
Note that the French support is more complete than for other languages -
|
||||
French usage instructions and error messages are supported.
|
||||
|
||||
- Added support for the Norwegian language, courtesy of Trygve Randen.
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- Added code for the functions timelocal() and timegm(), courtesy of
|
||||
Lucio de Re. This is for those very few machines whose libraries
|
||||
include neither those functions nor mktime().
|
||||
|
||||
- Added the filedate() function.
|
||||
|
||||
- Allowed the filename to be specified as "-" to cause Remind to take
|
||||
its input from the standard input stream.
|
||||
|
||||
- Added the "MSF" keyword to cause reminders to be formatted automatically.
|
||||
This keyword paragraph-fills reminder text following user specifications.
|
||||
Based on a suggestion by Ken McGlothlen.
|
||||
|
||||
- Added the "-e" option to Rem2PS, allowing the PostScript calendar
|
||||
to fill the entire page. Thanks to Arthur G. Yaffe.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- Corrected the Hebrew holidays Tzom Gedalia, Tzom Tevet, Ta'anit
|
||||
Esther, Tzom Tamuz and Tisha B'Av so they won't occur on Saturday.
|
||||
Corrections made following the algorithm in "Calendrical Calculations"
|
||||
by Nachum Dershowitz and Edward M. Reingold.
|
||||
|
||||
- Changed the dutch.h language file as suggested by Erik-Jan Vens. Made
|
||||
month and day names lower-case; corrected the spelling of oktober.
|
||||
|
||||
- Changed HashVal in var.c to use unsigned arithmetic - it's conceivable
|
||||
that a machine with signed chars could cause problems otherwise.
|
||||
|
||||
- Changed the LONG_* macros in config.h to LON_* to avoid conflicts
|
||||
with names defined by ANSI C. Thanks to David W. Sanderson.
|
||||
|
||||
- Allowed the built-in function char() to accept numbers in the
|
||||
range [-128, 255] (but not 0) so that char(asc(s)) works even
|
||||
on machines with signed char types.
|
||||
|
||||
* Version 3.0 Patch 7
|
||||
|
||||
+ MAJOR ENHANCEMENTS
|
||||
|
||||
- Added "system variables" to allow the user more control over
|
||||
Remind operation, and to allow queries about the command-line
|
||||
options from within a reminder script. They allow for specification
|
||||
of longitude and latitude for use by sunrise/sunset calculations.
|
||||
|
||||
- Added sunrise(), sunset(), isdst() and minsfromutc() functions -
|
||||
these are needed to support sunrise and sunset calculations.
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- Allowed the MSG, RUN, CAL, PS and PSF keywords to be used in the
|
||||
same reminder as the SATISFY keyword. This makes many complex
|
||||
reminders more compact.
|
||||
|
||||
- Added the filedir() function to enable Remind's include to emulate
|
||||
CPP's #include more closely.
|
||||
|
||||
- Allowed non-root users to use the "-u" option. It only affects
|
||||
the "SHELL", "HOME", "USER" and "LOGNAME" environment variables -
|
||||
it doesn't change the effective uid and gid when run by non-root.
|
||||
|
||||
- Added built-in function "easterdate" to calculate date of Easter
|
||||
Sunday - function courtesy of Michael Salmon.
|
||||
|
||||
- Improved the Jewish holiday reminders in "defs.rem" to give advance
|
||||
notice of holidays.
|
||||
|
||||
- Allowed the "simple calendar" option (-s) to specify a number of
|
||||
weeks as well as a number of months, in the same fashion as the
|
||||
-c option. Thanks to Dave Rickel.
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- Corrected the behaviour of "hebdate" for jahrzeits; added an additional
|
||||
parameter to specify the behaviour of dates in Adar during leap years.
|
||||
|
||||
- Changed kall so that "kall sh" doesn't commit suicide - patch courtesy
|
||||
of Michael Salmon.
|
||||
|
||||
* Version 3.0 Patch 6
|
||||
|
||||
+ MINOR ENHANCEMENTS
|
||||
|
||||
- Added the PS- and PSFILE-type reminders - these allow you to include
|
||||
arbitrary PostScript code in your PostScript calendars. Useful for
|
||||
shading, drawing graphics on calendars, etc. Use with care, though!
|
||||
|
||||
- Added the "-ivar=val" option to initialize variables from the command
|
||||
line. Changed the remind-all.* shell scripts to predefine the variable
|
||||
"remind_all".
|
||||
|
||||
+ BUG FIXES
|
||||
|
||||
- Fixed a bug in the hebmon(), hebday() and hebyear() functions - there
|
||||
was an off-by-one error. Sorry!
|
||||
|
||||
- Fixed a bug in the hebdate() function which resulted in infinite loops
|
||||
for dates after about 2075
|
||||
|
||||
- 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
|
||||
|
||||
+ MAJOR ENHANCEMENTS:
|
||||
|
||||
- Added support for the Hebrew calendar - can now specify Jewish holidays
|
||||
easily. Thanks to Amos Shapir for explaining the Hebrew calendar, and
|
||||
to Danny Sadinoff, from whose HEBCAL program I got some inspiration.
|
||||
Also thanks to David W. Tamkin and Frank Yellin for explaining the rules
|
||||
for jahrzeits.
|
||||
|
||||
+ MINOR ENHANCEMENTS:
|
||||
|
||||
- Allowed the default page size used by Rem2PS to be selected in config.h
|
||||
|
||||
- Edited the defs.rem file to contain Jewish holidays. Cleaned up some
|
||||
of the examples and improved the layout - thanks to George M. Sipe.
|
||||
|
||||
- Modified the IIF function to be more general
|
||||
|
||||
- Updated finnish.h to support the ISO 8859-1 character set, courtesy
|
||||
of Mikko Silvonen.
|
||||
|
||||
- Changed the date conversion routines to greatly speed up conversion from
|
||||
Julian to yyyy/mm/dd form.
|
||||
|
||||
+ BUG FIXES:
|
||||
|
||||
- Fixed a bug in which Remind complained incorrectly about a missing quote
|
||||
in the command SET foo ""
|
||||
|
||||
- Fixed bugs in dosubst.c which caused the %o, %1 and %@ substitutions
|
||||
to be incorrect
|
||||
|
||||
- Fixed a bug in the man page - thanks to Ed Oskiewicz.
|
||||
|
||||
* Version 3.0 Patch 4
|
||||
|
||||
- Added the -g option - this sorts reminders by date/time before
|
||||
issuing them. (You can see I'm running out of letters to
|
||||
name options!) This feature was suggested by George M. Sipe,
|
||||
Paul D. Smith, and Francois Pinard.
|
||||
|
||||
- Added the "args()" and "dosubst()" built-in functions - see the
|
||||
man page for details.
|
||||
|
||||
- Added more support for the ISO 8859-1 character set, and
|
||||
modified the german.h file to take advantage of this, thanks
|
||||
to Robert Joop.
|
||||
|
||||
- Allowed any character to be used as date and time separator
|
||||
characters (not just "/-:.")
|
||||
|
||||
- Added support for the Dutch and Finnish languages, thanks to
|
||||
Willem Kasdorp and Mikko Silvonen. (Anyone care to contribute
|
||||
French? Italian? Spanish?)
|
||||
|
||||
- Made Remind issue a warning if you try to redefine a built-in
|
||||
function. This warning is disabled in 'Hush' mode.
|
||||
|
||||
- Added the SCANFROM clause to the REM command. This allows reasonably
|
||||
safe moveable OMITs such as the Labour Day example in the manual.
|
||||
|
||||
- Added more examples to the defs.rem file, and cleaned up some old
|
||||
examples. Note that there are now safe moveable holidays for most
|
||||
U.S. holidays provided in the defs.rem file.
|
||||
|
||||
- Added the '-k' option, which allows MSG-type reminders to be passed
|
||||
to any system command. (Idea and patch courtesy of Philipp Slusallek.)
|
||||
|
||||
- Allowed selection of ':' or '.' as time separator characters at
|
||||
compile-time.
|
||||
|
||||
- Edited the COPYRIGHT file to clarify the rules. Please read them.
|
||||
|
||||
- Removed hard-coding of "am" and "pm" and placed them in language-specific
|
||||
header files as #defines L_AM and L_PM
|
||||
|
||||
- Fixed a bug in the FindToken() routine which had, through sheer luck,
|
||||
never been activated until the SCANFROM clause was added!
|
||||
|
||||
- Fixed the UNTIL clause to check for a valid expiry date.
|
||||
|
||||
- Removed identifiers in the C source beginning with "_" to conform
|
||||
to ANSI practice.
|
||||
|
||||
- Fixed a bug in the -u option which resulted in environment variables
|
||||
SHELL and USER not being set correctly. Also made -u set the LOGNAME
|
||||
environment variable.
|
||||
|
||||
- Fixed a couple of typos in the man page; added LDFLAGS to the
|
||||
Makefile. (Thanks to Dave Wolfe.)
|
||||
|
||||
- Put my new mailing address in the README files.
|
||||
|
||||
* Version 3.0 Patch 3
|
||||
|
||||
- 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
|
||||
|
||||
- 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.
|
||||
If you are worried that this option is a security hole, you can
|
||||
disable it in config.h
|
||||
|
||||
- Changed the RUN command so that RUN OFF can be used anywhere, even
|
||||
though RUN ON only works in the top-level file. This eases the
|
||||
management of global files which may want to switch RUN OFF.
|
||||
|
||||
- Added ISO encoding (ISO 8859-1) to the PostScript output, courtesy of
|
||||
Michael Salmon. This can be selected with the '-i' option in rem2ps.
|
||||
|
||||
- Added support for the '-' date separator as well as the '/' separator.
|
||||
|
||||
- Added support for languages other than English. Note that this support
|
||||
is not complete - error messages are still in English. The idea and
|
||||
German translation came from Wolfgang Thronicke.
|
||||
|
||||
- Changed the -w option to include the "padding" and "spacing" options.
|
||||
NOTE INCOMPATIBILITY: In the previous patch level, creating a weekly
|
||||
calendar using the -c+n option left no blank lines between the day
|
||||
number and the first reminder entry. This has been changed so that one
|
||||
blank line is left. To revert to the old behaviour, use the "-w,,0"
|
||||
option.
|
||||
|
||||
- Added the -o option to Rem2ps. This allows you to specify the margins
|
||||
when producing a PostScript calendar.
|
||||
|
||||
- Updated the copyright notices in all the files. :-)
|
||||
|
||||
- Added 'make clobber' and 'make test' targets to the Unix makefile.
|
||||
|
||||
- Corrected typos in WHATSNEW.30 and remind.1 man page. Thanks to
|
||||
Dave Wolfe <dwolfe@pffft.sps.mot.com>
|
||||
|
||||
- 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
|
||||
|
||||
- Wrote the Rem2ps program to produce PostScript calendars
|
||||
|
||||
- Added an 'install' target to the Makefile
|
||||
|
||||
- Fixed a bug which allowed the shell() function to execute in timed
|
||||
reminders which were queued with RUN disabled.
|
||||
|
||||
- Added support for OS/2, courtesy of DARREL HANKERSON
|
||||
<HANK@DUCVAX.AUBURN.EDU>
|
||||
|
||||
- In expressions, can now specify literal dates as 'yyyy/mm/dd' rather than
|
||||
using the date() function.
|
||||
|
||||
- Fixed all the source files to include "config.h" first.
|
||||
|
||||
- Changed the way triggers are calculated so that trigger dates are
|
||||
always valid if year, month and day are specified, and there is no
|
||||
UNTIL clause. See MAN page section "DETAILS ABOUT TRIGVALID()."
|
||||
|
||||
- Defined _POSIX_SOURCE so Remind will compile on SGI workstations (and
|
||||
be more portable... I hope.)
|
||||
|
||||
- Fixed some rather brain-dead definitions of UPPER and LOWER, as pointed
|
||||
out by <rsalz@osf.org>
|
||||
|
||||
- Added more details to the Man page concerning how triggers are computed,
|
||||
and added warnings about computing OMIT dates.
|
||||
|
||||
- Added the file defs.rem which contains examples of useful definitions and
|
||||
triggers.
|
||||
|
||||
- Changed the script test-rem to be a sh script instead of csh for improved
|
||||
portability.
|
||||
|
||||
- Fixed up the README.* files to reflect the changes.
|
||||
|
||||
- Re-formatted the WHATSNEW.30 file.
|
||||
|
||||
* Version 3.0
|
||||
|
||||
- Total rewrite from previous versions
|
||||
|
||||
- Added variables, expressions, flow-control statements, daemon mode
|
||||
|
||||
- Added "expression pasting"
|
||||
|
||||
- Added CAL-type reminders
|
||||
|
||||
- Added the SATISFY clause
|
||||
|
||||
- Improved debugging of reminder scripts
|
||||
|
||||
- Took out the "purge" option - it is in general too dificult to tell when
|
||||
a reminder has expired for good, so now it's up to you to do this
|
||||
by hand.
|
||||
|
||||
- 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
|
||||
|
||||
- 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
|
||||
|
||||
- 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
|
||||
|
||||
- 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
|
||||
|
||||
- Fixed up a problem with timed reminders which resulted
|
||||
in cursor not starting from left side of screen on some systems.
|
||||
|
||||
- Fixed the SIGINT handler for SYSV systems - this was interrupting the
|
||||
sleep(2) system call.
|
||||
|
||||
- Closed stdin and stdout if remind was part of a pipe - this prevents other
|
||||
sections of the pipe from hanging as remind puts itself in the background.
|
||||
|
||||
- Added the "-h" (Hush mode) option
|
||||
|
||||
- Added the "%#" and "%@" modifiers for the current time.
|
||||
|
||||
- Made the Makefile more portable
|
||||
|
||||
* Version 2.3 Patch 1
|
||||
|
||||
- Added the "-t" command-line option to get Remind
|
||||
to trigger all non-expired reminders.
|
||||
|
||||
- Added Turbo C support courtesy of Rhys Weatherly
|
||||
|
||||
- Added the "RUN ON" and "RUN OFF" commands for a secure interface with
|
||||
the Elm mail system.
|
||||
|
||||
- Added the "rem" shell script for running Remind with a default script.
|
||||
|
||||
- Added manual pages for "kall" and "rem".
|
||||
|
||||
* Version 2.3
|
||||
|
||||
- Added the UNTIL keyword for forcing reminders to expire.
|
||||
|
||||
- Added the "++" form of 'back' and the "--" form of 'delta' for
|
||||
ignoring OMIT information.
|
||||
|
||||
- Added the CLEAR-OMIT-CONTEXT, PUSH-OMIT-CONTEXT and POP-OMIT-CONTEXT
|
||||
keywords for isolating personal or peculiar reminders from the global
|
||||
OMIT context.
|
||||
|
||||
- Speeded up the parsing of tokens.
|
||||
|
||||
- Changed the source to recognize and exploit ANSI-C compilers which
|
||||
accept function prototypes.
|
||||
|
||||
- Added the "-n" option to output the next occurrence of each reminder
|
||||
in SimpleCalendar format
|
||||
|
||||
- Modified the calendar and SimpleCalendar formats so that the % escape
|
||||
substitutions ARE performed.
|
||||
|
||||
* Version 2.2 - Patch 5
|
||||
|
||||
- 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
|
||||
|
||||
- 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
|
||||
|
||||
- Added the AT keyword, the timed reminders daemon, and the
|
||||
calendar facility.
|
||||
|
||||
* Version 2.1
|
||||
|
||||
- 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
|
||||
|
||||
- first public release. Included advanced date specifications,
|
||||
character substitution, and the RUN keyword.
|
||||
|
||||
* Version 1.0
|
||||
|
||||
- never publicly released.
|
||||
|
||||
|
||||
|
||||
924
calendar.c
Normal file
924
calendar.c
Normal file
@@ -0,0 +1,924 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* CALENDAR.C */
|
||||
/* */
|
||||
/* The code for generating a calendar. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: calendar.c,v 1.1 1996-03-27 03:25:50 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
/* Data structures used by the calendar */
|
||||
typedef struct cal_entry {
|
||||
struct cal_entry *next;
|
||||
char *text;
|
||||
char *pos;
|
||||
int time;
|
||||
int priority;
|
||||
} CalEntry;
|
||||
|
||||
/* Global variables */
|
||||
static CalEntry *CalColumn[7];
|
||||
static CalEntry *CalPs[7];
|
||||
|
||||
static int ColSpaces;
|
||||
|
||||
PRIVATE void SortCol ARGS((CalEntry **col));
|
||||
PRIVATE void DoCalendarOneWeek ARGS ((void));
|
||||
PRIVATE void DoCalendarOneMonth ARGS ((void));
|
||||
PRIVATE int WriteCalendarRow ARGS ((void));
|
||||
PRIVATE void PrintLeft ARGS ((char *s, int width, char pad));
|
||||
PRIVATE void PrintCentered ARGS ((char *s, int width, char pad));
|
||||
PRIVATE int WriteOneCalLine ARGS ((void));
|
||||
PRIVATE int WriteOneColLine ARGS ((int col));
|
||||
PRIVATE void GenerateCalEntries ARGS ((int col));
|
||||
PRIVATE void WriteCalHeader ARGS ((void));
|
||||
PRIVATE void WriteCalTrailer ARGS ((void));
|
||||
PRIVATE int DoCalRem ARGS ((ParsePtr p, int col));
|
||||
PRIVATE void WriteSimpleEntries ARGS ((int col, int jul));
|
||||
PRIVATE void WriteSolidCalLine ARGS ((void));
|
||||
PRIVATE void WriteIntermediateCalLine ARGS ((void));
|
||||
PRIVATE void WriteCalDays ARGS ((void));
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ProduceCalendar */
|
||||
/* */
|
||||
/* Main loop for generating a calendar. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void ProduceCalendar(void)
|
||||
#else
|
||||
void ProduceCalendar()
|
||||
#endif
|
||||
{
|
||||
int y, m, d;
|
||||
|
||||
ShouldCache = 1;
|
||||
|
||||
ColSpaces = (CalWidth - 9) / 7;
|
||||
CalWidth = 7*ColSpaces + 8;
|
||||
|
||||
if (CalMonths) {
|
||||
FromJulian(JulianToday, &y, &m, &d);
|
||||
JulianToday = Julian(y, m, 1);
|
||||
while (CalMonths--)
|
||||
DoCalendarOneMonth();
|
||||
return;
|
||||
} else {
|
||||
if (MondayFirst) JulianToday -= (JulianToday%7);
|
||||
else JulianToday -= ((JulianToday+1)%7);
|
||||
|
||||
if (!DoSimpleCalendar) {
|
||||
WriteIntermediateCalLine();
|
||||
WriteCalDays();
|
||||
WriteIntermediateCalLine();
|
||||
}
|
||||
|
||||
while (CalWeeks--)
|
||||
DoCalendarOneWeek();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoCalendarOneWeek */
|
||||
/* */
|
||||
/* Write a calendar for a single week */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void DoCalendarOneWeek(void)
|
||||
#else
|
||||
static void DoCalendarOneWeek()
|
||||
#endif
|
||||
{
|
||||
int y, m, d, done, i, l, wd;
|
||||
char buf[81];
|
||||
int LinesWritten = 0;
|
||||
int OrigJul = JulianToday;
|
||||
|
||||
/* Fill in the column entries */
|
||||
for (i=0; i<7; i++) {
|
||||
GenerateCalEntries(i);
|
||||
JulianToday++;
|
||||
}
|
||||
|
||||
/* Output the entries */
|
||||
|
||||
/* If it's "Simple Calendar" format, do it simply... */
|
||||
if (DoSimpleCalendar) {
|
||||
if (MondayFirst) wd = JulianToday % 7;
|
||||
else wd = (JulianToday + 1) % 7;
|
||||
for (i=0; i<7; i++) {
|
||||
WriteSimpleEntries(i, OrigJul+i-wd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Here come the first few lines... */
|
||||
putchar('|');
|
||||
for (i=0; i<7; i++) {
|
||||
FromJulian(OrigJul+i, &y, &m, &d);
|
||||
sprintf(buf, "%d %c%c%c ", d, MonthName[m][0], MonthName[m][1],
|
||||
MonthName[m][2]);
|
||||
if (OrigJul+i == RealToday)
|
||||
PrintLeft(buf, ColSpaces, '*');
|
||||
else
|
||||
PrintLeft(buf, ColSpaces, ' ');
|
||||
putchar('|');
|
||||
}
|
||||
putchar('\n');
|
||||
for (l=0; l<CalPad; l++) {
|
||||
putchar('|');
|
||||
for (i=0; i<7; i++) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
putchar('|');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
/* Write the body lines */
|
||||
done = 0;
|
||||
while (!done) {
|
||||
done = WriteOneCalLine();
|
||||
LinesWritten++;
|
||||
}
|
||||
|
||||
/* Write any blank lines required */
|
||||
while (LinesWritten++ < CalLines) {
|
||||
putchar('|');
|
||||
for (i=0; i<7; i++) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
putchar('|');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
/* Write the final line */
|
||||
WriteIntermediateCalLine();
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoCalendarOneMonth */
|
||||
/* */
|
||||
/* Produce a calendar for the current month. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void DoCalendarOneMonth(void)
|
||||
#else
|
||||
static void DoCalendarOneMonth()
|
||||
#endif
|
||||
{
|
||||
int y, m, d, mm, yy;
|
||||
|
||||
if (!DoSimpleCalendar) WriteCalHeader();
|
||||
|
||||
if (PsCal) {
|
||||
FromJulian(JulianToday, &y, &m, &d);
|
||||
printf("%s\n", PSBEGIN);
|
||||
printf("%s %d %d %d\n",
|
||||
MonthName[m], y, DaysInMonth(m, y), (JulianToday+1) % 7);
|
||||
mm = m-1;
|
||||
if (mm<0) {
|
||||
mm = 11; yy = y-1;
|
||||
} else yy=y;
|
||||
|
||||
printf("%s %d\n", MonthName[mm], DaysInMonth(mm,yy));
|
||||
mm = m+1;
|
||||
if (mm>11) {
|
||||
mm = 0; yy = y+1;
|
||||
} else yy=y;
|
||||
printf("%s %d\n", MonthName[mm], DaysInMonth(mm,yy));
|
||||
}
|
||||
while (WriteCalendarRow()) continue;
|
||||
|
||||
if (PsCal) printf("%s\n", PSEND);
|
||||
if (!DoSimpleCalendar) WriteCalTrailer();
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* WriteCalendarRow */
|
||||
/* */
|
||||
/* Write one row of the calendar */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int WriteCalendarRow(void)
|
||||
#else
|
||||
static int WriteCalendarRow()
|
||||
#endif
|
||||
{
|
||||
int y, m, d, wd, i, l;
|
||||
int done;
|
||||
char buf[81];
|
||||
int OrigJul = JulianToday;
|
||||
int LinesWritten = 0;
|
||||
|
||||
/* Get the date of the first day */
|
||||
FromJulian(JulianToday, &y, &m, &d);
|
||||
if (!MondayFirst) wd = (JulianToday + 1) % 7;
|
||||
else wd = JulianToday % 7;
|
||||
|
||||
/* Fill in the column entries */
|
||||
for (i=wd; i<7; i++) {
|
||||
if (d+i-wd > DaysInMonth(m, y)) break;
|
||||
GenerateCalEntries(i);
|
||||
JulianToday++;
|
||||
}
|
||||
|
||||
/* Output the entries */
|
||||
|
||||
/* If it's "Simple Calendar" format, do it simply... */
|
||||
if (DoSimpleCalendar) {
|
||||
for (i=wd; i<7 && d+i-wd<=DaysInMonth(m, y); i++) {
|
||||
WriteSimpleEntries(i, OrigJul+i-wd);
|
||||
}
|
||||
return (d+7-wd <= DaysInMonth(m, y));
|
||||
}
|
||||
|
||||
|
||||
/* Here come the first few lines... */
|
||||
putchar('|');
|
||||
for (i=0; i<7; i++) {
|
||||
if (i < wd || d+i-wd>DaysInMonth(m, y))
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
else {
|
||||
sprintf(buf, "%d", d+i-wd);
|
||||
PrintLeft(buf, ColSpaces, ' ');
|
||||
}
|
||||
putchar('|');
|
||||
}
|
||||
putchar('\n');
|
||||
for (l=0; l<CalPad; l++) {
|
||||
putchar('|');
|
||||
for (i=0; i<7; i++) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
putchar('|');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
/* Write the body lines */
|
||||
done = 0;
|
||||
while (!done) {
|
||||
done = WriteOneCalLine();
|
||||
LinesWritten++;
|
||||
}
|
||||
|
||||
/* Write any blank lines required */
|
||||
while (LinesWritten++ < CalLines) {
|
||||
putchar('|');
|
||||
for (i=0; i<7; i++) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
putchar('|');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
WriteIntermediateCalLine();
|
||||
|
||||
/* Return non-zero if we have not yet finished */
|
||||
return (d+7-wd <= DaysInMonth(m, y));
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* PrintLeft */
|
||||
/* */
|
||||
/* Left-justify a piece of text. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void PrintLeft(char *s, int width, char pad)
|
||||
#else
|
||||
static void PrintLeft(s, width, pad)
|
||||
char *s;
|
||||
int width;
|
||||
char pad;
|
||||
#endif
|
||||
{
|
||||
int len = strlen(s);
|
||||
printf("%s", s);
|
||||
while (len++ < width) putchar(pad);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* PrintCentered */
|
||||
/* */
|
||||
/* Center a piec of text */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void PrintCentered(char *s, int width, char pad)
|
||||
#else
|
||||
static void PrintCentered(s, width, pad)
|
||||
char *s;
|
||||
int width;
|
||||
char pad;
|
||||
#endif
|
||||
{
|
||||
int len = strlen(s);
|
||||
int d = (width - len) / 2;
|
||||
int i;
|
||||
|
||||
for (i=0; i<d; i++) putchar(pad);
|
||||
for (i=0; i<width; i++) {
|
||||
if (*s) putchar(*s++); else break;
|
||||
}
|
||||
for (i=d+len; i<width; i++) putchar(pad);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* WriteOneCalLine */
|
||||
/* */
|
||||
/* Write a single line. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int WriteOneCalLine(void)
|
||||
#else
|
||||
static int WriteOneCalLine()
|
||||
#endif
|
||||
{
|
||||
int done = 1, i;
|
||||
|
||||
putchar('|');
|
||||
for (i=0; i<7; i++) {
|
||||
if (CalColumn[i]) {
|
||||
if (WriteOneColLine(i)) done = 0;
|
||||
} else {
|
||||
PrintCentered("", ColSpaces, ' ');
|
||||
}
|
||||
putchar('|');
|
||||
}
|
||||
putchar('\n');
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* WriteOneColLine */
|
||||
/* */
|
||||
/* Write a single line for a specified column. Return 1 if */
|
||||
/* the column still has entries; 0 otherwise. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int WriteOneColLine(int col)
|
||||
#else
|
||||
static int WriteOneColLine(col)
|
||||
int col;
|
||||
#endif
|
||||
{
|
||||
CalEntry *e = CalColumn[col];
|
||||
char *s;
|
||||
char *space;
|
||||
int numwritten = 0;
|
||||
|
||||
/* Print as many characters as possible within the column */
|
||||
space = NULL;
|
||||
s = e->pos;
|
||||
|
||||
/* If we're at the end, and there's another entry, do a blank line and move
|
||||
to next entry. */
|
||||
if (!*s && e->next) {
|
||||
PrintLeft("", ColSpaces, ' ');
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Find the last space char within the column. */
|
||||
while (s - e->pos <= ColSpaces) {
|
||||
if (!*s) {space = s; break;}
|
||||
if (*s == ' ') space = s;
|
||||
s++;
|
||||
}
|
||||
|
||||
/* If we couldn't find a space char, print what we have. */
|
||||
if (!space) {
|
||||
for (s = e->pos; s - e->pos < ColSpaces; s++) {
|
||||
if (!*s) break;
|
||||
numwritten++;
|
||||
putchar(*s);
|
||||
}
|
||||
e->pos = s;
|
||||
} else {
|
||||
|
||||
/* We found a space - print everything before it. */
|
||||
for (s = e->pos; s<space; s++) {
|
||||
if (!*s) break;
|
||||
numwritten++;
|
||||
putchar(*s);
|
||||
}
|
||||
}
|
||||
|
||||
/* Flesh out the rest of the column */
|
||||
while(numwritten++ < ColSpaces) putchar(' ');
|
||||
|
||||
/* Skip any spaces before next word */
|
||||
while (*s == ' ') s++;
|
||||
|
||||
/* If done, free memory if no next entry. */
|
||||
if (!*s && !e->next) {
|
||||
CalColumn[col] = e->next;
|
||||
free(e->text);
|
||||
free(e);
|
||||
} else {
|
||||
e->pos = s;
|
||||
}
|
||||
if (CalColumn[col]) return 1; else return 0;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GenerateCalEntries */
|
||||
/* */
|
||||
/* Generate the calendar entries for the ith column */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void GenerateCalEntries(int col)
|
||||
#else
|
||||
static void GenerateCalEntries(col)
|
||||
int col;
|
||||
#endif
|
||||
{
|
||||
int r;
|
||||
Token tok;
|
||||
char *s;
|
||||
Parser p;
|
||||
|
||||
/* Do some initialization first... */
|
||||
ClearGlobalOmits();
|
||||
DestroyOmitContexts();
|
||||
DestroyVars(0);
|
||||
NumTriggered = 0;
|
||||
|
||||
r=OpenFile(InitialFile);
|
||||
if (r) {
|
||||
fprintf(ErrFp, "%s %s: %s\n", ErrMsg[E_ERR_READING], InitialFile, ErrMsg[r]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
r = ReadLine();
|
||||
if (r == E_EOF) return;
|
||||
if (r) {
|
||||
Eprint("%s: %s", ErrMsg[E_ERR_READING], ErrMsg[r]);
|
||||
exit(1);
|
||||
}
|
||||
s = FindInitialToken(&tok, CurLine);
|
||||
|
||||
/* Should we ignore it? */
|
||||
if (NumIfs &&
|
||||
tok.type != T_If &&
|
||||
tok.type != T_Else &&
|
||||
tok.type != T_EndIf &&
|
||||
tok.type != T_IfTrig &&
|
||||
ShouldIgnoreLine())
|
||||
{
|
||||
/* DO NOTHING */
|
||||
}
|
||||
else {
|
||||
/* Create a parser to parse the line */
|
||||
CreateParser(s, &p);
|
||||
|
||||
switch(tok.type) {
|
||||
|
||||
case T_Empty:
|
||||
case T_Comment:
|
||||
break;
|
||||
|
||||
case T_ErrMsg: r=DoErrMsg(&p); break;
|
||||
case T_Rem: r=DoCalRem(&p, col); 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_Exit: DoExit(&p); break;
|
||||
case T_Set: r=DoSet(&p); break;
|
||||
case T_Fset: r=DoFset(&p); break;
|
||||
case T_UnSet: r=DoUnset(&p); break;
|
||||
case T_Clr: r=DoClear(&p); break;
|
||||
case T_Flush: r=DoFlush(&p); break;
|
||||
case T_Debug: break; /* IGNORE DEBUG CMD */
|
||||
case T_Dumpvars: break; /* IGNORE DUMPVARS CMD */
|
||||
case T_Banner: break; /* IGNORE BANNER CMD */
|
||||
case T_Omit: r=DoOmit(&p);
|
||||
if (r == E_PARSE_AS_REM) {
|
||||
DestroyParser(&p);
|
||||
CreateParser(s, &p);
|
||||
r=DoCalRem(&p, col);
|
||||
}
|
||||
break;
|
||||
case T_Pop: r=PopOmitContext(&p); break;
|
||||
case T_Push: r=PushOmitContext(&p); break;
|
||||
case T_Preserve: r=DoPreserve(&p); break;
|
||||
case T_RemType: if (tok.val == RUN_TYPE) {
|
||||
r=DoRun(&p);
|
||||
break;
|
||||
} else {
|
||||
CreateParser(CurLine, &p);
|
||||
r=DoCalRem(&p, col);
|
||||
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=DoCalRem(&p, col);
|
||||
break;
|
||||
}
|
||||
if (r && (!Hush || r != E_RUN_DISABLED)) Eprint("%s", ErrMsg[r]);
|
||||
|
||||
/* Destroy the parser - free up resources it may be tying up */
|
||||
DestroyParser(&p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* WriteCalHeader */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void WriteCalHeader(void)
|
||||
#else
|
||||
static void WriteCalHeader()
|
||||
#endif
|
||||
{
|
||||
char buf[80];
|
||||
int y, m, d;
|
||||
|
||||
FromJulian(JulianToday, &y, &m, &d);
|
||||
sprintf(buf, "%s %d", MonthName[m], y);
|
||||
|
||||
WriteSolidCalLine();
|
||||
|
||||
putchar('|');
|
||||
PrintCentered(buf, CalWidth-2, ' ');
|
||||
putchar('|');
|
||||
putchar('\n');
|
||||
|
||||
WriteIntermediateCalLine();
|
||||
WriteCalDays();
|
||||
WriteIntermediateCalLine();
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* WriteCalTrailer */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void WriteCalTrailer(void)
|
||||
#else
|
||||
static void WriteCalTrailer()
|
||||
#endif
|
||||
{
|
||||
putchar('\f');
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoCalRem */
|
||||
/* */
|
||||
/* Do the REM command in the context of a calendar. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int DoCalRem(ParsePtr p, int col)
|
||||
#else
|
||||
static int DoCalRem(p, col)
|
||||
ParsePtr p;
|
||||
int col;
|
||||
#endif
|
||||
{
|
||||
|
||||
Trigger trig;
|
||||
TimeTrig tim;
|
||||
Value v;
|
||||
int r;
|
||||
int jul;
|
||||
CalEntry *CurCol = CalColumn[col];
|
||||
CalEntry *CurPs = CalPs[col];
|
||||
CalEntry *e;
|
||||
char *s, *s2;
|
||||
static char buf[TOKSIZE];
|
||||
static char obuf[LINELEN];
|
||||
Token tok;
|
||||
|
||||
/* Parse the trigger date and time */
|
||||
if ( (r=ParseRem(p, &trig, &tim)) ) return r;
|
||||
|
||||
/* Don't include timed reminders in calendar if -a option supplied. */
|
||||
#ifdef HAVE_QUEUED
|
||||
if (DontIssueAts && tim.ttime != NO_TIME) return OK;
|
||||
#endif
|
||||
if (trig.typ == NO_TYPE) return E_EOLN;
|
||||
if (trig.typ == SAT_TYPE) {
|
||||
r=DoSatRemind(&trig, &tim, p);
|
||||
if (r) return r;
|
||||
r=ParseToken(p, buf);
|
||||
if (r) return r;
|
||||
FindToken(buf, &tok);
|
||||
if (tok.type == T_Empty || tok.type == T_Comment) return OK;
|
||||
if (tok.type != T_RemType || tok.val == SAT_TYPE) return E_PARSE_ERR;
|
||||
trig.typ = tok.val;
|
||||
jul = LastTriggerDate;
|
||||
if (!LastTrigValid) return OK;
|
||||
} else {
|
||||
/* Calculate the trigger date */
|
||||
jul = ComputeTrigger(trig.scanfrom, &trig, &r);
|
||||
if (r) return r;
|
||||
}
|
||||
|
||||
if (!PsCal && (trig.typ == PS_TYPE || trig.typ == PSF_TYPE)) return OK;
|
||||
|
||||
/* Remove any "at" times from PS or PSFILE reminders */
|
||||
if (trig.typ == PS_TYPE || trig.typ == PSF_TYPE) tim.ttime = NO_TIME;
|
||||
|
||||
/* If trigger date == today, add it to the current entry */
|
||||
if (jul == JulianToday) {
|
||||
NumTriggered++;
|
||||
s = obuf;
|
||||
*s = 0;
|
||||
if (DoSimpleCalendar || tim.ttime != NO_TIME)
|
||||
s += strlen(SimpleTime(tim.ttime, s));
|
||||
if (trig.typ != PS_TYPE && trig.typ != PSF_TYPE &&
|
||||
UserFuncExists("calprefix")==1) {
|
||||
sprintf(buf, "calprefix(%d)", trig.priority);
|
||||
s2 = buf;
|
||||
r = EvalExpr(&s2, &v);
|
||||
if (!r) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
strcat(s, v.v.str);
|
||||
s += strlen(s);
|
||||
}
|
||||
DestroyValue(v);
|
||||
}
|
||||
}
|
||||
if ( (r=DoSubst(p, s, &trig, &tim, jul, CAL_MODE)) ) return r;
|
||||
if (!*s) return OK;
|
||||
if (trig.typ != PS_TYPE && trig.typ != PSF_TYPE &&
|
||||
UserFuncExists("calsuffix")==1) {
|
||||
sprintf(buf, "calsuffix(%d)", trig.priority);
|
||||
s2 = buf;
|
||||
r = EvalExpr(&s2, &v);
|
||||
if (!r) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
strcat(s, v.v.str);
|
||||
s += strlen(s);
|
||||
}
|
||||
DestroyValue(v);
|
||||
}
|
||||
}
|
||||
s = obuf;
|
||||
if (!DoSimpleCalendar) while (isspace(*s)) s++;
|
||||
e = NEW(CalEntry);
|
||||
if (!e) return E_NO_MEM;
|
||||
e->text = StrDup(s);
|
||||
if (!e->text) {
|
||||
free(e);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
e->priority = trig.priority;
|
||||
if (trig.typ == PS_TYPE || trig.typ == PSF_TYPE) {
|
||||
e->pos = (trig.typ == PS_TYPE) ? "P" : "F";
|
||||
e->time = NO_TIME;
|
||||
e->next = CurPs;
|
||||
CalPs[col] = e;
|
||||
SortCol(&CalPs[col]);
|
||||
} else {
|
||||
e->pos = e->text;
|
||||
e->time = tim.ttime;
|
||||
e->next = CurCol;
|
||||
CalColumn[col] = e;
|
||||
SortCol(&CalColumn[col]);
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* WriteSimpleEntries */
|
||||
/* */
|
||||
/* Write entries in 'simple calendar' format. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void WriteSimpleEntries(int col, int jul)
|
||||
#else
|
||||
static void WriteSimpleEntries(col, jul)
|
||||
int col, jul;
|
||||
#endif
|
||||
{
|
||||
CalEntry *e = CalPs[col];
|
||||
CalEntry *n;
|
||||
int y, m, d;
|
||||
|
||||
/* Do all the PostScript entries first, if any */
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
while(e) {
|
||||
printf("%c%c%c%c%c%02d%c%02d ", *(e->pos), *(e->pos),
|
||||
*(e->pos), *(e->pos), DATESEP,
|
||||
m+1, DATESEP, d);
|
||||
printf("%s\n", e->text);
|
||||
free(e->text);
|
||||
n = e->next;
|
||||
free(e);
|
||||
e = n;
|
||||
}
|
||||
CalPs[col] = NULL;
|
||||
|
||||
e = CalColumn[col];
|
||||
while(e) {
|
||||
printf("%04d%c%02d%c%02d ", y, DATESEP, m+1, DATESEP, d);
|
||||
printf("%s\n", e->text);
|
||||
free(e->text);
|
||||
n = e->next;
|
||||
free(e);
|
||||
e = n;
|
||||
}
|
||||
CalColumn[col] = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* Various functions for writing different types of lines. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void WriteSolidCalLine(void)
|
||||
#else
|
||||
static void WriteSolidCalLine()
|
||||
#endif
|
||||
{
|
||||
putchar('+');
|
||||
PrintCentered("", CalWidth-2, '-');
|
||||
putchar('+');
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void WriteIntermediateCalLine(void)
|
||||
#else
|
||||
static void WriteIntermediateCalLine()
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
|
||||
putchar('+');
|
||||
for (i=0; i<7; i++) {
|
||||
PrintCentered("", ColSpaces, '-');
|
||||
putchar('+');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void WriteCalDays(void)
|
||||
#else
|
||||
static void WriteCalDays()
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
putchar('|');
|
||||
for (i=0; i<7; i++) {
|
||||
if (!MondayFirst)
|
||||
PrintCentered(DayName[(i+6)%7], ColSpaces, ' ');
|
||||
else
|
||||
PrintCentered(DayName[i%7], ColSpaces, ' ');
|
||||
putchar('|');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SimpleTime */
|
||||
/* */
|
||||
/* Format the time according to simple time format. */
|
||||
/* If out is NULL, result placed in internal static buffer. */
|
||||
/* A trailing space is always added. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC char *SimpleTime(int tim, char *out)
|
||||
#else
|
||||
char *SimpleTime(tim, out)
|
||||
int tim;
|
||||
char *out;
|
||||
#endif
|
||||
{
|
||||
static buf[9];
|
||||
int h, min, hh;
|
||||
|
||||
if (!out) out = (char *) buf;
|
||||
|
||||
*out = 0;
|
||||
|
||||
switch(ScFormat) {
|
||||
|
||||
case SC_AMPM:
|
||||
if (tim == NO_TIME) sprintf(out, " ");
|
||||
else {
|
||||
h = tim / 60;
|
||||
min = tim % 60;
|
||||
if (h == 0) hh=12;
|
||||
else if (h > 12) hh=h-12;
|
||||
else hh=h;
|
||||
sprintf(out, "%2d%c%02d%s ", hh, TIMESEP, min, (h>=12) ? L_PM : L_AM);
|
||||
}
|
||||
break;
|
||||
|
||||
case SC_MIL:
|
||||
if (tim == NO_TIME) sprintf(out, " ");
|
||||
else {
|
||||
h = tim / 60;
|
||||
min = tim % 60;
|
||||
sprintf(out, "%02d%c%02d ", h, TIMESEP, min);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SortCol */
|
||||
/* */
|
||||
/* Sort the calendar entries in a column by time and priority */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void SortCol(CalEntry **col)
|
||||
#else
|
||||
static void SortCol(col)
|
||||
CalEntry **col;
|
||||
#endif
|
||||
{
|
||||
CalEntry *cur, *prev, *next;
|
||||
|
||||
cur = *col;
|
||||
prev = NULL;
|
||||
|
||||
/* Note that we use <= comparison rather than > comparison to preserve the
|
||||
file order of reminders which have the same time and priority */
|
||||
|
||||
while (cur->next &&
|
||||
CompareRems(0, cur->time, cur->priority,
|
||||
0, cur->next->time, cur->next->priority,
|
||||
SortByDate, SortByTime, SortByPrio) <= 0) {
|
||||
next = cur->next;
|
||||
/* Swap cur and next */
|
||||
if (!prev) {
|
||||
*col = next;
|
||||
cur->next = next->next;
|
||||
next->next = cur;
|
||||
prev = next;
|
||||
} else {
|
||||
prev->next = next;
|
||||
cur->next = next->next;
|
||||
next->next = cur;
|
||||
prev = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
263
config.h
Normal file
263
config.h
Normal file
@@ -0,0 +1,263 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* CONFIG.H */
|
||||
/* */
|
||||
/* Contains various configuration parameters for Remind. */
|
||||
/* You may have to edit this file to tweak parameters or take */
|
||||
/* care of certain system dependencies. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: config.h,v 1.1 1996-03-27 03:25:50 dfs Exp $ */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* LAT_DEG, LAT_MIN and LAT_SEC: Latitude of your location */
|
||||
/* LON_DEG, LON_MIN and LON_SEC: Longitude of your location */
|
||||
/* LOCATION: A string identifying your location. */
|
||||
/* For latitude, north is positive, south is negative. */
|
||||
/* For longitude, west is positive, east is negative. */
|
||||
/* NOTE: For negative numbers, all three of DEG, MIN, SEC should be */
|
||||
/* negative. To indicate -20deg22'33" use */
|
||||
/* DEG=-20, MIN=-22 and SEC=-33. */
|
||||
/* The default values are initially set to Ottawa, Ontario, Canada. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define LAT_DEG 45
|
||||
#define LAT_MIN 24
|
||||
#define LAT_SEC 0
|
||||
#define LON_DEG 75
|
||||
#define LON_MIN 39
|
||||
#define LON_SEC 0
|
||||
#define LOCATION "Ottawa"
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* HAVE_MKTIME: Define this if your C library includes the mktime() */
|
||||
/* function. Otherwise, will attempt to use the Unix */
|
||||
/* style time manipulations. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define HAVE_MKTIME 1
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* NEED_TIMEGM: If your C library does not have mktime() and it ALSO */
|
||||
/* does not have timelocal() or timegm(), uncomment the */
|
||||
/* next line. If HAVE_MKTIME is defined, NEED_TIMEGM is */
|
||||
/* ignored. Very few systems should require NEED_TIMEGM. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* #define NEED_TIMEGM 1 */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* DEFAULT_PAGE: The default page size to use for Rem2PS. */
|
||||
/* The Letter version is appropriate for North America; the A4 version */
|
||||
/* is appropriate for Europe. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define DEFAULT_PAGE {"Letter", 612, 792}
|
||||
/* #define DEFAULT_PAGE {"A4", 595, 842} */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* DATESEP: The default date separator. North American usage is '/'; */
|
||||
/* others may prefer '-'. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define DATESEP '/'
|
||||
/* #define DATESEP '-' */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* TIMESEP: The default time separator. North American usage is ':'; */
|
||||
/* others may prefer '.'. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define TIMESEP ':'
|
||||
/* #define TIMESEP '.' */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* ISOLATIN1: uncomment the following line if your system uses the */
|
||||
/* ISO 8859-1 character set instead of ASCII. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* #define ISOLATIN1 1 */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* IBMEXTENDED: uncomment the following line if you want to use the */
|
||||
/* IBM extended character set. NOT ALL LANGUAGE MODULES SUPPORT THIS. */
|
||||
/* Note that at most one of ISOLATIN1 or IBMEXTENDED should be */
|
||||
/* defined; if both are defined, the results are unspecified. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* #define IBMEXTENDED 1 */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* 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. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define WANT_U_OPTION 1
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* WANT_SHELL_ESCAPING: Define this if you want special shell */
|
||||
/* characters to be escaped with a backslash for the -k option. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#if defined(UNIX)
|
||||
#define WANT_SHELL_ESCAPING 1
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRSTR: If your system does not have the "strstr" function, */
|
||||
/* uncomment the following line. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* #define NO_STRSTR 1 */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STDLIB: If you don't have the <stdlib.h> header file, comment the */
|
||||
/* following line. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* MALLOC: If you do not have the <malloc.h> header file, */
|
||||
/* comment out the next 3 lines. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#ifdef UNIX
|
||||
#define HAVE_MALLOC_H 1
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* BASE: The base year for date calculation. NOTE! January 1 of the */
|
||||
/* base year MUST be a Monday, else Remind will not work! */
|
||||
/* IMPORTANT NOTE: The Hebrew date routines depend on BASE */
|
||||
/* being set to 1990. If you change it, you'll have to add the */
|
||||
/* number of days between 1 Jan <NEWBASE> and 1 Jan 1990 to the */
|
||||
/* manifest constant CORRECTION in hbcal.c. Also, the year */
|
||||
/* folding mechanism in main.c depends on BASE<2001. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#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. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define YR_RANGE 88
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* VAR_NAME_LEN: The maximum length of variable names. Don't make it */
|
||||
/* any less than 12. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define VAR_NAME_LEN 12
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* MAX_PRT_LEN: The maximum number of characters to print when */
|
||||
/* displaying a string value for debugging purposes. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_PRT_LEN 40
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* LINELEN: The maximum length of an input line */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define LINELEN 512
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* OP_STACK_SIZE: The size of the operator stack for expr. parsing */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define OP_STACK_SIZE 30
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* VAL_STACK_SIZE: The size of the operand stack for expr. parsing */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define VAL_STACK_SIZE 30
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* INCLUDE_NEST: How many nested INCLUDES do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define INCLUDE_NEST 8
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* IF_NEST: How many nested IFs do we handle? Maximum is the number */
|
||||
/* of bits in an int, divided by two. Beware! */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define IF_NEST (4*sizeof(unsigned int))
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* Do we handle queued reminders? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#if defined(UNIX) || defined(__OS2__)
|
||||
#define HAVE_QUEUED 1
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* Does our C compiler have prototypes? Override this test if you */
|
||||
/* are using a non-ANSI compiler that nevertheless has prototypes. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#if defined(__STDC__) || defined(__TURBOC__) || defined(__BORLANDC__)
|
||||
#define HAVE_PROTOS 1
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* Do we use the <stdarg.h> scheme for functions with variable number */
|
||||
/* of parameters? If not, the <varargs.h> scheme is assumed. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#if defined(__STDC__) || defined(__TURBOC__) || defined(__BORLANDC__)
|
||||
#define HAVE_STDARG 1
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* Does the function argument to the signal() function take an INT */
|
||||
/* argument? If yes, uncomment the next line. If you get it wrong, */
|
||||
/* the only bad side effect is a compiler warning, so don't worry too */
|
||||
/* much about it. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* #define SIGHANDLER_INT_ARG 1 */
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* Do we have the <unistd.h> header? If not, use sys/files.h */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#ifdef UNIX
|
||||
#define HAVE_UNISTD 1
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many attempts to resolve a weird date spec? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define TRIG_ATTEMPTS 25
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form YYYY MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_FULL_OMITS 75
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* How many global omits of the form MM DD do we handle? */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define MAX_PARTIAL_OMITS 75
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* The size of statically-allocated buffers for tokens. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define TOKSIZE 128
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* The size of the buffer for the shell() function. */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define SHELLSIZE 512
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* A newline - some systems need "\n\r" */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define NL "\n"
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* Minimum number of linefeeds in each calendar "box" */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define CAL_LINES 5
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* Don't change the next definitions */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define PUBLIC
|
||||
#define PRIVATE static
|
||||
|
||||
#ifdef UNIX
|
||||
#define _POSIX_SOURCE
|
||||
#endif
|
||||
|
||||
#define PSBEGIN "# rem2ps begin"
|
||||
#define PSEND "# rem2ps end"
|
||||
116
danish.h
Normal file
116
danish.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DANISH.H */
|
||||
/* */
|
||||
/* Support for the Danish language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* This file is Copyright (C) 1993 by Mogens Lynnerup. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: danish.h,v 1.1 1996-03-27 03:25:51 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Danish"
|
||||
|
||||
/* Day names */
|
||||
#ifdef ISOLATIN1
|
||||
# define L_SUNDAY "S\370ndag"
|
||||
#else
|
||||
# define L_SUNDAY "Soendag"
|
||||
#endif
|
||||
#define L_MONDAY "Mandag"
|
||||
#define L_TUESDAY "Tirsdag"
|
||||
#define L_WEDNESDAY "Onsdag"
|
||||
#define L_THURSDAY "Torsdag"
|
||||
#define L_FRIDAY "Fredag"
|
||||
#ifdef ISOLATIN1
|
||||
# define L_SATURDAY "L\370rdag"
|
||||
#else
|
||||
# define L_SATURDAY "Loerdag"
|
||||
#endif
|
||||
|
||||
/* Day initials - first letter only */
|
||||
#define L_DAYINIT "SMTOTFL"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
#define L_FEB "Februar"
|
||||
#define L_MAR "Mars"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "Maj"
|
||||
#define L_JUN "Juni"
|
||||
#define L_JUL "Juli"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "Oktober"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "December"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "i dag"
|
||||
#define L_TOMORROW "i morgen"
|
||||
|
||||
/* The default banner */
|
||||
#ifdef ISOLATIN1
|
||||
# define L_BANNER "P\345mindelse for %w, %d. %m, %y%o:"
|
||||
#else
|
||||
# define L_BANNER "Paamindelse for %w, %d. %m, %y%o:"
|
||||
#endif
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "siden"
|
||||
#define L_FROMNOW "fra nu"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "om %d dage"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#ifdef ISOLATIN1
|
||||
# define L_ON "p\345"
|
||||
#else
|
||||
# define L_ON "paa"
|
||||
#endif
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "e"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nu"
|
||||
#define L_AT "kl."
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "time"
|
||||
#define L_IS "er"
|
||||
#define L_WAS "var"
|
||||
#define L_AND "og"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "r"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "ter"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#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_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
629
defs.rem
Normal file
629
defs.rem
Normal file
@@ -0,0 +1,629 @@
|
||||
#############################################################################
|
||||
# #
|
||||
# DEFS.REM #
|
||||
# #
|
||||
# This file is a reminder script, which contains a few handy definitions. #
|
||||
# Cut and paste as desired! Also, near the end, there are a bunch of #
|
||||
# holiday definitions for the U.S. #
|
||||
# #
|
||||
# Some examples provided by George M. Sipe <gsipe@pyratl.ga.pyramid.com> #
|
||||
# #
|
||||
# U.S. holidays provided by Dave Rickel <drickel@sjc.mentorg.com> #
|
||||
# #
|
||||
# Use your text editor to search for: #
|
||||
# "#USHOLS" for U.S. holidays #
|
||||
# "#JHOLS" for Jewish holidays #
|
||||
# "#PSSTUFF" for nifty PostScript examples #
|
||||
# "#COLORS" for examples of ANSI color escape sequences. #
|
||||
# #
|
||||
# This file is part of REMIND. #
|
||||
# Copyright (C) 1992-1996 by David F. Skoll #
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
#
|
||||
# $Id: defs.rem,v 1.1 1996-03-27 03:25:51 dfs Exp $
|
||||
#
|
||||
|
||||
RUN OFF
|
||||
|
||||
################################################
|
||||
# Ensure required version of remind is used... #
|
||||
################################################
|
||||
IF version() < "03.00.10"
|
||||
ERRMSG This file requires at least version 03.00.10 of Remind.%
|
||||
ERRMSG This version is version [version()].
|
||||
EXIT
|
||||
ENDIF
|
||||
|
||||
######################################
|
||||
# Symbolic constants for weekdays... #
|
||||
######################################
|
||||
SET Sunday 0
|
||||
SET Monday 1
|
||||
SET Tuesday 2
|
||||
SET Wednesday 3
|
||||
SET Thursday 4
|
||||
SET Friday 5
|
||||
SET Saturday 6
|
||||
|
||||
SET Sun 0
|
||||
SET Mon 1
|
||||
SET Tue 2
|
||||
SET Wed 3
|
||||
SET Thu 4
|
||||
SET Fri 5
|
||||
SET Sat 6
|
||||
|
||||
#########################################
|
||||
# Symbolic constants for month names... #
|
||||
#########################################
|
||||
|
||||
SET Jan 1
|
||||
SET Feb 2
|
||||
SET Mar 3
|
||||
SET Apr 4
|
||||
SET May 5
|
||||
SET Jun 6
|
||||
SET Jul 7
|
||||
SET Aug 8
|
||||
SET Sep 9
|
||||
SET Oct 10
|
||||
SET Nov 11
|
||||
SET Dec 12
|
||||
|
||||
SET January 1
|
||||
SET February 2
|
||||
SET March 3
|
||||
SET April 4
|
||||
SET May 5
|
||||
SET June 6
|
||||
SET July 7
|
||||
SET August 8
|
||||
SET September 9
|
||||
SET October 10
|
||||
SET November 11
|
||||
SET December 12
|
||||
|
||||
###########################################################
|
||||
# Other symbolic constants and functions for "pasting"... #
|
||||
###########################################################
|
||||
|
||||
SET Quote CHAR(34)
|
||||
|
||||
# Handy constants/function for specifing week of month...
|
||||
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())
|
||||
|
||||
# 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
|
||||
|
||||
###########################################################
|
||||
# Function which returns a string in "am/pm" format based #
|
||||
# on the time. For example, set a am_pm(NOW())... #
|
||||
###########################################################
|
||||
|
||||
FSET _am_pm(tm) IIF(tm<01:00, tm+12*60+"am", \
|
||||
tm<12:00, tm+"am", \
|
||||
tm<13:00, tm+"pm", \
|
||||
tm-12*60+"pm")
|
||||
|
||||
#################################################################
|
||||
# Function which removes a single leading zero from a string... #
|
||||
#################################################################
|
||||
|
||||
FSET _no_lz(s) IIF(SUBSTR(s, 1, 1)=="0", SUBSTR(s, 2), s)
|
||||
|
||||
############################################################
|
||||
# Function to calculate number of years since a given year #
|
||||
# or number of months since a given month and year... #
|
||||
############################################################
|
||||
|
||||
FSET _yr_num(yr) ORD(YEAR(TRIGDATE()) - yr)
|
||||
FSET _mo_num(mo, yr) ORD(12 * (YEAR(TRIGDATE()) - yr) + \
|
||||
MONNUM(TRIGDATE()) - mo)
|
||||
|
||||
# Here's an example of how to use them:
|
||||
REM 1 Nov ++12 MSG %"Dean's [_yr_num(1984)] birthday%" is %b.
|
||||
REM 1 MSG Dean's [_mo_num(11, 1984)] 'monthly' anniversary
|
||||
|
||||
###########################################################
|
||||
# Function to send mail via elm's "fastmail" (by GMS!)... #
|
||||
###########################################################
|
||||
|
||||
#FSET _mail(from, subj) "mailx -s " + \
|
||||
# Quote + from + " : " + subj + Quote \
|
||||
# GETENV("LOGNAME") + " < /dev/null 1>&0"
|
||||
FSET _mail(from, subj) "fastmail -f " + \
|
||||
Quote + from + Quote + \
|
||||
" -s " + Quote + subj + Quote + \
|
||||
" /dev/null " + GETENV("LOGNAME")
|
||||
|
||||
#############################################################################
|
||||
# Here's a tricky problem: The 4th of July is a holiday in the U.S.
|
||||
# However, if it falls on a Saturday, the previous Friday is a holiday.
|
||||
# If it falls on a Sunday, the next Monday is a holiday. Here's how
|
||||
# to do it. NOTE that the following procedure makes the OMIT context
|
||||
# dependent upon the current date. SInce it only depends on the current
|
||||
# year, which is not likely to change while producing a calendar, we
|
||||
# are fairly safe. However, reminders with huge DELTA or BACK components
|
||||
# may not operate as expected. In general, any time you make OMIT
|
||||
# dependent upon the current date, it's tricky and results may not be
|
||||
# what you expect. You should try to make sure that the OMIT context
|
||||
# "near" any current reminders will not change during a calendar run.
|
||||
# The SCANFROM clause should help make these OMITs very safe.
|
||||
############################################################################
|
||||
|
||||
# Calculate the weekday of the holiday.
|
||||
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)
|
||||
ELSE
|
||||
IF WKDAYNUM(TRIGDATE()) == Sun
|
||||
REM [TRIGGER(TRIGDATE())] MSG Independence day (actual)
|
||||
OMIT [TRIGGER(TRIGDATE()+1)] MSG Independence day (observed)
|
||||
ELSE
|
||||
OMIT [TRIGGER(TRIGDATE())] MSG Independence day
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
############################################################################
|
||||
# #
|
||||
# A meeting on the first Monday of every month which is moved to the #
|
||||
# second Monday in the event of a holiday. #
|
||||
# #
|
||||
############################################################################
|
||||
|
||||
# First, the normal meeting. However, the SKIP keyword means this
|
||||
# one won't be triggered if the first Monday is a holiday
|
||||
REM Mon 1 SKIP MSG Meeting
|
||||
|
||||
# Now, calculate the "potential" delayed meeting
|
||||
REM Mon 8 SATISFY 1
|
||||
|
||||
# But only actually trigger the delayed meeting if the previous
|
||||
# Monday was a holiday
|
||||
IF ISOMITTED(TRIGDATE()-7)
|
||||
REM [TRIGGER(TRIGDATE())] MSG Delayed meeting
|
||||
ENDIF
|
||||
|
||||
############################################################################
|
||||
# #
|
||||
# A very complicated reminder sent in by a Remind user. #
|
||||
# This person gets paid every two weeks, starting from 8 January 1993. #
|
||||
# If a pay date occurs before the twelfth of a month, then that #
|
||||
# he pays his mortgage on that pay date. Otherwise, he pays the mortgage #
|
||||
# on the previous pay date. Furthermore, he has to schedule his #
|
||||
# mortgage payment six days before it is due. He wants to be reminded #
|
||||
# a further four days before the scheduling deadline. He also #
|
||||
# wants to be mailed a notice two weeks before the scheduling deadline. #
|
||||
# #
|
||||
# Here's the solution - if you can follow this, consider yourself a #
|
||||
# Remind programmer extraordinaire! #
|
||||
# #
|
||||
############################################################################
|
||||
|
||||
# A function to determine whether or not a pay-date is a mortgage-date.
|
||||
|
||||
FSET _IsMortDate(x) DAY(x) < 12 || (DAY(x+14) >= 12 && DAY(x+14) <= 14)
|
||||
|
||||
# Paydays - for reference
|
||||
|
||||
REM 8 Jan 1993 *14 MSG Payday
|
||||
|
||||
# Calculate the mortgage payment six days ahead of time. Note that this
|
||||
# is done "implicitly" by subtracting 6 from the starting date - we start
|
||||
# on 2 Jan rather than 8 Jan. We add 6 to TRIGDATE() in _IsMortDate to
|
||||
# compensate.
|
||||
|
||||
REM 2 Jan 1993 *14 ++4 SATISFY [_IsMortDate(TRIGDATE()+6)] \
|
||||
MSG %"Schedule mortgage payment%" for %a.
|
||||
|
||||
# Now the mail reminder two weeks before the payment date - because two
|
||||
# weeks before a payment date is also a payment date, no pre-compensation
|
||||
# in the starting date of 8 Jan is necessary - convince yourself of this!
|
||||
# This uses the _mail() function defined earlier.
|
||||
|
||||
REM ONCE 8 Jan 1993 *14 SATISFY [_IsMortDate(TRIGDATE()+14)] \
|
||||
RUN [_mail("Decatur Federal", \
|
||||
"Pay mortgage by the " + ORD(DAY(TRIGDATE()+14)))]
|
||||
|
||||
# Make an entry on the calendar when the mortgage should be paid
|
||||
|
||||
REM 8 Jan 1993 *14 SATISFY [_IsMortDate(TRIGDATE())] \
|
||||
CAL Mortgage payment
|
||||
|
||||
##########################################################################
|
||||
# #
|
||||
# On our UNIX system, I run a program which queries the university #
|
||||
# library and creates a file called ".booksdue". This file is #
|
||||
# a REMIND script to tell me when my library books are due. Here's #
|
||||
# an example from my reminder file - it shows the use of filedate(). #
|
||||
# When the .booksdue file is at least 7 days old, I create a new version #
|
||||
# by querying the library computer. Note the use of realtoday() rather #
|
||||
# than today. #
|
||||
# #
|
||||
##########################################################################
|
||||
|
||||
IF !$RunOff && !$CalMode && !$SimpleCal
|
||||
IF REALTODAY()-FILEDATE("/home/dfs/.booksdue") >= 7
|
||||
REM RUN /home/dfs/bilge/library/getbooks
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
#PSSTUFF
|
||||
##########################################################################
|
||||
# #
|
||||
# This portion of the file contains some cute examples of the new #
|
||||
# PS-type reminders. You need a PostScript printer or viewer to #
|
||||
# appreciate these. To use them, pipe the output of remind -p into the #
|
||||
# rem2ps program. #
|
||||
# #
|
||||
##########################################################################
|
||||
|
||||
# Convenient to stick all the PostScript code in a string var - makes
|
||||
# reminders easier to understand and faster. The variable "shade" will
|
||||
# contain PostScript code to shade in a particular box on the calendar.
|
||||
SET shade psshade(95)
|
||||
|
||||
# The following reminder will shade the Saturday and Sunday calendar
|
||||
# entries.
|
||||
REM Sat Sun PS [shade]
|
||||
|
||||
# The following will fill in the Hebrew dates on the calendar. For this
|
||||
# example, I recommend that you use the -sd 10 option for Rem2PS.
|
||||
REM PS Border Border moveto \
|
||||
/DayFont findfont DaySize scalefont setfont \
|
||||
([hebday(today())] [hebmon(today())]) show
|
||||
|
||||
# Fill in the phases of the moon on the PostScript calendar
|
||||
[trigger(moondate(0))] PS [psmoon(0)]
|
||||
[trigger(moondate(1))] PS [psmoon(1)]
|
||||
[trigger(moondate(2))] PS [psmoon(2)]
|
||||
[trigger(moondate(3))] PS [psmoon(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.
|
||||
REM PS Border Border 5 sub moveto \
|
||||
/SmallFont findfont 4 scalefont setfont \
|
||||
(Sunrise: [sunrise(trigdate())] Sunset: [sunset(trigdate())]) show
|
||||
|
||||
# The next one puts the day number (1-366) and days left in the year at the
|
||||
# bottom of the post-script calendar. Again, the hard-coded sizes work best
|
||||
# in landscape.
|
||||
FSET _DayOfYear(x) x-(date(year(x),1,1) - 1)
|
||||
REM PS BoxWidth 3 mul 4 div Border 5 sub moveto \
|
||||
/SmallFont findfont 4 scalefont setfont \
|
||||
([_DayOfYear(today())]([365+isleap(today())-_DayOfYear(today())])) show
|
||||
|
||||
#USHOLS
|
||||
#############################################################################
|
||||
# #
|
||||
# The following holidays were provided by Dave Rickel #
|
||||
# Modified by D. Skoll to give safe OMITs for moveable holidays #
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
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%"
|
||||
|
||||
# Some holidays are omitted, some are not. You may want to change
|
||||
# which ones are omitted - use the general forms shown below.
|
||||
# You'll need the _back() function and the Week_n variables defined
|
||||
# way up in the file.
|
||||
|
||||
OMIT Jan 1 MSG %"New Year's%" Day
|
||||
REM Mon Jan [Week_3] MSG Martin Luther King - %"MLK Day%"
|
||||
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%"
|
||||
REM Mar 17 MSG %"St. Patrick's%" Day
|
||||
REM Sun Apr 1 ++2 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%"
|
||||
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%"
|
||||
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%"
|
||||
REM Mon Oct [Week_2] MSG %"Columbus Day%"
|
||||
REM Nov 11 MSG %"Veterans Day%"
|
||||
REM Sun [_last(Oct)] 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
|
||||
REM Fri Nov [Week_4+1] SCANFROM [_back(7)] SATISFY 1
|
||||
OMIT [_trig()] MSG %"Thanksgiving%" (cont.)
|
||||
OMIT Dec 24 MSG %"Christmas Eve%"
|
||||
OMIT Dec 25 MSG %"Christmas%" Day
|
||||
|
||||
##########################################################################
|
||||
# #
|
||||
# The next block uses the shade variable defined in PSSTUFF above. #
|
||||
# If any US holidays were triggered above, shade in the calendar #
|
||||
# entry in PostScript. This is not quite correct, as it blots out the #
|
||||
# other PostScript stuff above. I was too lazy to do it properly :-) #
|
||||
# #
|
||||
##########################################################################
|
||||
if $NumTrig > SaveTrig
|
||||
REM PS [shade]
|
||||
endif
|
||||
|
||||
# Seasons (valid from 1992 to 2000)...
|
||||
REM Mar 20 MSG %"Spring%" begins
|
||||
REM Jun [IIF(YEAR(TODAY())%4, 21, 20)] MSG %"Summer%" begins
|
||||
REM Sep [CHOOSE(YEAR(TODAY())-1991, 22,22,23,23,22,22,22,23,22)] \
|
||||
MSG %"Fall%" begins
|
||||
REM Dec [IIF((YEAR(TODAY())+1)%4, 21, 22)] MSG %"Winter%" begins
|
||||
|
||||
#JHOLS
|
||||
##########################################################################
|
||||
# #
|
||||
# This portion of the file contains reminders for Jewish holidays. The #
|
||||
# dates were obtained from "The First Jewish Catalog" by Richard Siegel #
|
||||
# and Michael and Sharon Strassfeld, published by the Jewish Publication #
|
||||
# Society of America. The Reform version of the calendar was guessed #
|
||||
# at by David Skoll based on experience. There is probably no standard #
|
||||
# Reform position on many of the holidays, so you may have to adjust #
|
||||
# the file as required. #
|
||||
# #
|
||||
# Additional corrections were made from the paper "Calendrical #
|
||||
# Calculations" by Nachum Dershowitz and Edward M. Reingold. Any #
|
||||
# further corrections are welcome. #
|
||||
# #
|
||||
##########################################################################
|
||||
|
||||
# Here are some general functions that you might find nice to use
|
||||
|
||||
# _hstr: Returns a string which is the full Hebrew date of its argument.
|
||||
# Example: hstr('1994/02/02') returns "21 Shvat 5754"
|
||||
FSET _hstr(x) HEBDAY(x) + " " + HEBMON(x) + " " + HEBYEAR(x)
|
||||
|
||||
# _hyrlen: Return the length of the specified Hebrew year
|
||||
# Example: _hyrlen(5754) returns 355
|
||||
FSET _hyrlen(x) HEBDATE(1, "Tishrey", x+1) - HEBDATE(1, "Tishrey", x)
|
||||
|
||||
# --- HERE ARE THE JEWISH HOLIDAYS ---
|
||||
# Set the variable InIsrael to 1 if you live in Israel. Otherwise,
|
||||
# you get the Diaspora versions of Jewish holidays
|
||||
SET InIsrael 0
|
||||
|
||||
# Set the variable Reform to 1 if you want the Reform version of the
|
||||
# Jewish calendar. Otherwise, you get the traditional version
|
||||
SET Reform 0
|
||||
|
||||
# Convenient function definition to save typing
|
||||
FSET _h(x, y) TRIGGER(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))
|
||||
|
||||
# Default values in case InIsrael and Reform are not set
|
||||
SET InIsrael VALUE("InIsrael", 0)
|
||||
SET Reform VALUE("Reform", 0)
|
||||
|
||||
[_h(1, "Tishrey")] ++4 MSG %"Rosh Hashana 1%" is %b.
|
||||
|
||||
# No RH-2 or Tzom Gedalia in Reform
|
||||
IF !Reform
|
||||
[_h(2, "Tishrey")] ++4 MSG %"Rosh Hashana 2%" is %b.
|
||||
[_PastSat(3, "Tishrey")] ++4 MSG %"Tzom Gedalia%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(10, "Tishrey")] ++4 MSG %"Yom Kippur%" is %b.
|
||||
[_h(15, "Tishrey")] ++4 MSG %"Sukkot 1%" is %b.
|
||||
|
||||
IF !InIsrael
|
||||
[_h(16, "Tishrey")] MSG %"Sukkot 2%"
|
||||
ENDIF
|
||||
|
||||
[_h(21, "Tishrey")] ++4 MSG %"Hashana Rabba%" is %b.
|
||||
[_h(22, "Tishrey")] ++4 MSG %"Shemini Atzeret%" is %b.
|
||||
|
||||
IF InIsrael
|
||||
[_h(22, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
ELSE
|
||||
[_h(23, "Tishrey")] ++4 MSG %"Simchat Torah%" is %b.
|
||||
ENDIF
|
||||
|
||||
# Because Kislev can change length, we must be more careful about Chanukah
|
||||
FSET _chan(x) TRIGGER(HEBDATE(24, "Kislev", today()-9)+x)
|
||||
[_chan(1)] ++4 MSG %"Chanukah 1%" is %b.
|
||||
[_chan(2)] MSG %"Chanukah 2%"
|
||||
[_chan(3)] MSG %"Chanukah 3%"
|
||||
[_chan(4)] MSG %"Chanukah 4%"
|
||||
[_chan(5)] MSG %"Chanukah 5%"
|
||||
[_chan(6)] MSG %"Chanukah 6%"
|
||||
[_chan(7)] MSG %"Chanukah 7%"
|
||||
[_chan(8)] MSG %"Chanukah 8%"
|
||||
|
||||
# Not sure about Reform's position on the next one.
|
||||
IF !Reform
|
||||
# 10 Tevet will never be a Saturday, so whether or not to
|
||||
# move it is moot. (Thanks to Art Werschulz.)
|
||||
[_h(10, "Tevet")] MSG %"Tzom Tevet%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(15, "Shvat")] ++4 MSG %"Tu B'Shvat%" is %b.
|
||||
[_h(15, "Adar A")] ++4 MSG %"Purim Katan%" is %b.
|
||||
|
||||
# If Purim is on Sunday, then Fast of Esther is 11 Adar.
|
||||
IF WKDAYNUM(_h2(13, "Adar")) != 6
|
||||
REM [TRIGGER(_h2(13, "Adar"))] ++4 MSG %"Fast of Esther%" is %b.
|
||||
ELSE
|
||||
REM [TRIGGER(_h2(11, "Adar"))] ++4 MSG %"Fast of Esther%" is %b.
|
||||
ENDIF
|
||||
[_h(14, "Adar")] ++4 MSG %"Purim%" is %b.
|
||||
[_h(15, "Nisan")] ++4 MSG %"Pesach%" is %b.
|
||||
|
||||
IF !InIsrael
|
||||
[_h(16, "Nisan")] MSG %"Pesach 2%"
|
||||
ENDIF
|
||||
|
||||
[_h(21, "Nisan")] MSG %"Pesach 7%"
|
||||
|
||||
IF !InIsrael && !Reform
|
||||
[_h(22, "Nisan")] MSG %"Pesach 8%"
|
||||
ENDIF
|
||||
|
||||
[_h(27, "Nisan")] ++4 MSG %"Yom HaShoah%" is %b.
|
||||
[_h(4, "Iyar")] ++4 MSG %"Yom HaZikaron%" is %b.
|
||||
[_h(5, "Iyar")] ++4 MSG %"Yom Ha'atzmaut%" is %b.
|
||||
|
||||
# Not sure about Reform's position on Lag B'Omer
|
||||
IF !Reform
|
||||
[_h(18, "Iyar")] ++4 MSG %"Lag B'Omer%" is %b.
|
||||
ENDIF
|
||||
|
||||
[_h(28, "Iyar")] ++4 MSG %"Yom Yerushalayim%" is %b.
|
||||
[_h(6, "Sivan")] ++4 MSG %"Shavuot%" is %b.
|
||||
|
||||
IF !InIsrael && !Reform
|
||||
[_h(7, "Sivan")] MSG %"Shavuot 2%"
|
||||
ENDIF
|
||||
|
||||
# Fairly sure Reform Jews don't observe the next two
|
||||
IF !Reform
|
||||
# Tzom Tamuz and Tish'a B'Av are moved to Sunday if they normally
|
||||
# fall on a Saturday
|
||||
[_PastSat(17, "Tamuz")] ++4 MSG %"Tzom Tammuz%" is %b.
|
||||
[_PastSat(9, "Av")] ++4 MSG %"Tish'a B'Av%" is %b.
|
||||
ENDIF
|
||||
|
||||
# Counting the omer - do the whole spiel, i.e:
|
||||
# "This is the xth day of the omer, being y weeks and z days of the omer."
|
||||
# Nice Remind programming example here!
|
||||
SET ostart HEBDATE(16, "Nisan", TODAY()-50)
|
||||
IF ostart <= TODAY() && (TODAY() - ostart < 49)
|
||||
SET odays TODAY()-ostart+1
|
||||
IF odays < 7
|
||||
MSG %"%"Today is the [ORD(odays)] day of the Omer.
|
||||
ELSE
|
||||
IF !(odays % 7)
|
||||
MSG %"%"Today is the [ORD(odays)] day of the Omer, being [odays / 7] [PLURAL(odays/7, "week")] of the Omer.
|
||||
ELSE
|
||||
MSG %"%"Today is the [ORD(odays)] day of the Omer, being [odays/7] [PLURAL(odays/7, "week")] and [odays%7] [PLURAL(odays%7, "day")] of the Omer.
|
||||
ENDIF
|
||||
ENDIF
|
||||
CAL [ORD(odays)] of Omer
|
||||
ENDIF
|
||||
|
||||
### Candle lighting and Havdalah. You should probably add candle lighting
|
||||
### for other holidays besides Shabbat. These just create calendar entries
|
||||
### for Friday and Saturday. Note: You must set your latitude, longitude
|
||||
### and possibly time zone for these to work properly!
|
||||
|
||||
REM Friday CAL Candle lighting at [sunset(trigdate())-18]
|
||||
REM Saturday CAL Havdalah at [sunset(trigdate())+42]
|
||||
|
||||
#COLORS
|
||||
##########################################################################
|
||||
# #
|
||||
# This contains sample ANSI escape sequences for coloring messages. #
|
||||
# It should work on an IBM PC with the ANSI.SYS driver, and on #
|
||||
# other terminals which use the ANSI sequences. #
|
||||
# #
|
||||
# This information was provided by Gail Gurman.
|
||||
# #
|
||||
##########################################################################
|
||||
# Colors - use Nrm to reset to normal text.
|
||||
SET 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"
|
||||
|
||||
# Examples
|
||||
REM MSG A [Blu]blue[Nrm] reminder.
|
||||
REM MSG [Red]%"A red reminder%" safe to use in the calendar mode.[Nrm]
|
||||
|
||||
# Here is an example of how to use msgprefix() and msgsuffix(). These
|
||||
# will highlight priority-0 reminders in bright red,
|
||||
# priority-2500 in red, and priority-7500 in blue. All others
|
||||
# will be in the normal colors
|
||||
FSET msgprefix(x) iif(x==0, BrRed, x==2500, Red, x==7500, Blu, Nrm)
|
||||
|
||||
# Don't forget to return to normal color set at the end of reminder!
|
||||
FSET msgsuffix(x) Nrm
|
||||
|
||||
# The next examples are great for putting right at the end of the reminder
|
||||
# file. They make queued reminders more eye-catching when they pop up.
|
||||
FSET msgprefix(x) char(13,10,13,10)+"******************"+char(13,10,13,10)
|
||||
FSET msgsuffix(x) char(13,10)+"******************"+char(13,10,13,10)
|
||||
797
dorem.c
Normal file
797
dorem.c
Normal file
@@ -0,0 +1,797 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DOREM.C */
|
||||
/* */
|
||||
/* Contains routines for parsing reminders and evaluating */
|
||||
/* triggers. Also contains routines for parsing OMIT */
|
||||
/* commands. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: dorem.c,v 1.1 1996-03-27 03:25:52 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
|
||||
PRIVATE int ParseTimeTrig ARGS ((ParsePtr s, TimeTrig *tim));
|
||||
PRIVATE int ParseLocalOmit ARGS ((ParsePtr s, Trigger *t));
|
||||
PRIVATE int ParseScanFrom ARGS ((ParsePtr s, Trigger *t));
|
||||
PRIVATE int ParsePriority ARGS ((ParsePtr s, Trigger *t));
|
||||
PRIVATE int ParseUntil ARGS ((ParsePtr s, Trigger *t));
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoRem */
|
||||
/* */
|
||||
/* Do the REM command. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoRem(ParsePtr p)
|
||||
#else
|
||||
int DoRem(p)
|
||||
ParsePtr p;
|
||||
#endif
|
||||
{
|
||||
|
||||
Trigger trig;
|
||||
TimeTrig tim;
|
||||
int r;
|
||||
int jul;
|
||||
char buf[TOKSIZE];
|
||||
Token tok;
|
||||
|
||||
/* Parse the trigger date and time */
|
||||
if ( (r=ParseRem(p, &trig, &tim)) ) return r;
|
||||
|
||||
if (trig.typ == NO_TYPE) return E_EOLN;
|
||||
if (trig.typ == SAT_TYPE) {
|
||||
r=DoSatRemind(&trig, &tim, p);
|
||||
if (r) return r;
|
||||
r=ParseToken(p, buf);
|
||||
if (r) return r;
|
||||
FindToken(buf, &tok);
|
||||
if (tok.type == T_Empty || tok.type == T_Comment) return OK;
|
||||
if (tok.type != T_RemType || tok.val == SAT_TYPE) return E_PARSE_ERR;
|
||||
trig.typ = tok.val;
|
||||
jul = LastTriggerDate;
|
||||
if (!LastTrigValid) return OK;
|
||||
} else {
|
||||
/* Calculate the trigger date */
|
||||
jul = ComputeTrigger(trig.scanfrom, &trig, &r);
|
||||
if (r) return r;
|
||||
}
|
||||
|
||||
/* Queue the reminder, if necessary */
|
||||
#ifdef HAVE_QUEUED
|
||||
if (jul == JulianToday &&
|
||||
!(!IgnoreOnce &&
|
||||
trig.once != NO_ONCE &&
|
||||
FileAccessDate == JulianToday))
|
||||
QueueReminder(p, trig.typ, &tim, trig.sched);
|
||||
/* If we're in daemon mode, do nothing over here */
|
||||
if (Daemon) return OK;
|
||||
#endif
|
||||
|
||||
|
||||
if (ShouldTriggerReminder(&trig, &tim, jul)) {
|
||||
#ifdef OS2_POPUP
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, jul, 0)) ) {
|
||||
#else
|
||||
if ( (r=TriggerReminder(p, &trig, &tim, jul)) ) {
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseRem */
|
||||
/* */
|
||||
/* Given a parse pointer, parse line and fill in a */
|
||||
/* trigger structure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
#else
|
||||
int ParseRem(s, trig, tim)
|
||||
ParsePtr s;
|
||||
Trigger *trig;
|
||||
TimeTrig *tim;
|
||||
#endif
|
||||
{
|
||||
register int r;
|
||||
Token tok;
|
||||
|
||||
trig->y = NO_YR;
|
||||
trig->m = NO_MON;
|
||||
trig->d = NO_DAY;
|
||||
trig->wd = NO_WD;
|
||||
trig->back = NO_BACK;
|
||||
trig->delta = NO_DELTA;
|
||||
trig->until = NO_UNTIL;
|
||||
trig->rep = NO_REP;
|
||||
trig->localomit = NO_WD;
|
||||
trig->skip = NO_SKIP;
|
||||
trig->once = NO_ONCE;
|
||||
trig->typ = NO_TYPE;
|
||||
trig->scanfrom = NO_DATE;
|
||||
trig->priority = DefaultPrio;
|
||||
trig->sched[0] = 0;
|
||||
tim->ttime = NO_TIME;
|
||||
tim->delta = NO_DELTA;
|
||||
tim->rep = NO_REP;
|
||||
|
||||
while(1) {
|
||||
/* Read space-delimited string */
|
||||
r = ParseToken(s, TokBuffer);
|
||||
if (r) return r;
|
||||
|
||||
/* Figure out what we've got */
|
||||
FindToken(TokBuffer, &tok);
|
||||
switch(tok.type) {
|
||||
case T_WkDay:
|
||||
if (trig->wd & (1 << tok.val)) return E_WD_TWICE;
|
||||
trig->wd |= (1 << tok.val);
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
if (trig->m != NO_MON) return E_MON_TWICE;
|
||||
trig->m = tok.val;
|
||||
break;
|
||||
|
||||
case T_Skip:
|
||||
if (trig->skip != NO_SKIP) return E_SKIP_ERR;
|
||||
trig->skip = tok.val;
|
||||
break;
|
||||
|
||||
case T_Priority:
|
||||
r=ParsePriority(s, trig);
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
case T_At:
|
||||
r=ParseTimeTrig(s, tim);
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
case T_Scanfrom:
|
||||
r=ParseScanFrom(s, trig);
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
case T_RemType:
|
||||
trig->typ = tok.val;
|
||||
if (s->isnested) return E_CANT_NEST_RTYPE;
|
||||
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
|
||||
return OK;
|
||||
|
||||
case T_Until:
|
||||
r=ParseUntil(s, trig);
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
case T_Year:
|
||||
if (trig->y != NO_YR) return E_YR_TWICE;
|
||||
trig->y = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
if (trig->d != NO_DAY) return E_DAY_TWICE;
|
||||
trig->d = tok.val;
|
||||
break;
|
||||
|
||||
case T_Rep:
|
||||
if (trig->rep != NO_REP) return E_REP_TWICE;
|
||||
trig->rep = tok.val;
|
||||
break;
|
||||
|
||||
case T_Delta:
|
||||
if (trig->delta != NO_DELTA) return E_DELTA_TWICE;
|
||||
trig->delta = tok.val;
|
||||
break;
|
||||
|
||||
case T_Back:
|
||||
if (trig->back != NO_BACK) return E_BACK_TWICE;
|
||||
trig->back = tok.val;
|
||||
break;
|
||||
|
||||
case T_Once:
|
||||
if (trig->once != NO_ONCE) return E_ONCE_TWICE;
|
||||
trig->once = ONCE_ONCE;
|
||||
break;
|
||||
|
||||
case T_Omit:
|
||||
r = ParseLocalOmit(s, trig);
|
||||
if (r) return r;
|
||||
break;
|
||||
|
||||
case T_Empty:
|
||||
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
|
||||
return OK;
|
||||
|
||||
case T_Sched:
|
||||
r=ParseToken(s, TokBuffer);
|
||||
if(r) return r;
|
||||
StrnCpy(trig->sched, TokBuffer, VAR_NAME_LEN);
|
||||
break;
|
||||
|
||||
default:
|
||||
Eprint("%s: %s", ErrMsg[E_UNKNOWN_TOKEN], TokBuffer);
|
||||
return E_UNKNOWN_TOKEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseTimeTrig - parse the AT part of a timed reminder */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int ParseTimeTrig(ParsePtr s, TimeTrig *tim)
|
||||
#else
|
||||
static int ParseTimeTrig(s, tim)
|
||||
ParsePtr s;
|
||||
TimeTrig *tim;
|
||||
#endif
|
||||
{
|
||||
Token tok;
|
||||
int r;
|
||||
|
||||
while(1) {
|
||||
r = ParseToken(s, TokBuffer);
|
||||
if (r) return r;
|
||||
FindToken(TokBuffer, &tok);
|
||||
switch(tok.type) {
|
||||
case T_Time:
|
||||
tim->ttime = tok.val;
|
||||
break;
|
||||
|
||||
case T_Delta:
|
||||
tim->delta = (tok.val > 0) ? tok.val : -tok.val;
|
||||
break;
|
||||
|
||||
case T_Rep:
|
||||
tim->rep = tok.val;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (tim->ttime == NO_TIME) return E_EXPECT_TIME;
|
||||
/* Save in global variable */
|
||||
LastTriggerTime = tim->ttime;
|
||||
PushToken(TokBuffer);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseLocalOmit - parse the local OMIT portion of a */
|
||||
/* reminder. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int ParseLocalOmit(ParsePtr s, Trigger *t)
|
||||
#else
|
||||
static int ParseLocalOmit(s, t)
|
||||
ParsePtr s;
|
||||
Trigger *t;
|
||||
#endif
|
||||
{
|
||||
Token tok;
|
||||
int r;
|
||||
|
||||
while(1) {
|
||||
r = ParseToken(s, TokBuffer);
|
||||
if (r) return r;
|
||||
FindToken(TokBuffer, &tok);
|
||||
switch(tok.type) {
|
||||
case T_WkDay:
|
||||
t->localomit |= (1 << tok.val);
|
||||
break;
|
||||
|
||||
default:
|
||||
PushToken(TokBuffer);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseUntil - parse the UNTIL portion of a reminder */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int ParseUntil(ParsePtr s, Trigger *t)
|
||||
#else
|
||||
static int ParseUntil(s, t)
|
||||
ParsePtr s;
|
||||
Trigger *t;
|
||||
#endif
|
||||
{
|
||||
int y = NO_YR,
|
||||
m = NO_MON,
|
||||
d = NO_DAY;
|
||||
|
||||
Token tok;
|
||||
int r;
|
||||
|
||||
if (t->until != NO_UNTIL) return E_UNTIL_TWICE;
|
||||
|
||||
while(1) {
|
||||
r = ParseToken(s, TokBuffer);
|
||||
if (r) return r;
|
||||
FindToken(TokBuffer, &tok);
|
||||
switch(tok.type) {
|
||||
case T_Year:
|
||||
if (y != NO_YR) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_YR_TWICE]);
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
y = tok.val;
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
if (m != NO_MON) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_MON_TWICE]);
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
m = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
if (d != NO_DAY) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_DAY_TWICE]);
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
d = tok.val;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
|
||||
Eprint("UNTIL: %s", ErrMsg[E_INCOMPLETE]);
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
if (!DateOK(y, m, d)) return E_BAD_DATE;
|
||||
t->until = Julian(y, m, d);
|
||||
PushToken(TokBuffer);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParseScanFrom - parse the SCANFROM portion of a reminder */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int ParseScanFrom(ParsePtr s, Trigger *t)
|
||||
#else
|
||||
static int ParseScanFrom(s, t)
|
||||
ParsePtr s;
|
||||
Trigger *t;
|
||||
#endif
|
||||
{
|
||||
int y = NO_YR,
|
||||
m = NO_MON,
|
||||
d = NO_DAY;
|
||||
|
||||
Token tok;
|
||||
int r;
|
||||
|
||||
if (t->scanfrom != NO_DATE) return E_SCAN_TWICE;
|
||||
|
||||
while(1) {
|
||||
r = ParseToken(s, TokBuffer);
|
||||
if (r) return r;
|
||||
FindToken(TokBuffer, &tok);
|
||||
switch(tok.type) {
|
||||
case T_Year:
|
||||
if (y != NO_YR) {
|
||||
Eprint("SCANFROM: %s", ErrMsg[E_YR_TWICE]);
|
||||
return E_YR_TWICE;
|
||||
}
|
||||
y = tok.val;
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
if (m != NO_MON) {
|
||||
Eprint("SCANFROM: %s", ErrMsg[E_MON_TWICE]);
|
||||
return E_MON_TWICE;
|
||||
}
|
||||
m = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
if (d != NO_DAY) {
|
||||
Eprint("SCANFROM: %s", ErrMsg[E_DAY_TWICE]);
|
||||
return E_DAY_TWICE;
|
||||
}
|
||||
d = tok.val;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (y == NO_YR || m == NO_MON || d == NO_DAY) {
|
||||
Eprint("SCANFROM: %s", ErrMsg[E_INCOMPLETE]);
|
||||
return E_INCOMPLETE;
|
||||
}
|
||||
if (!DateOK(y, m, d)) return E_BAD_DATE;
|
||||
t->scanfrom = Julian(y, m, d);
|
||||
PushToken(TokBuffer);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* TriggerReminder */
|
||||
/* */
|
||||
/* Trigger the reminder if it's a RUN or MSG type. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
#ifdef OS2_POPUP
|
||||
PUBLIC int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul,
|
||||
int AsPopUp)
|
||||
#else /* ! OS2_POPUP */
|
||||
PUBLIC int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
#endif /* OS2_POPUP */
|
||||
#else /* ! HAVE_PROTOS */
|
||||
#ifdef OS2_POPUP
|
||||
int TriggerReminder(p, t, tim, jul, AsPopUp)
|
||||
ParsePtr p;
|
||||
Trigger *t;
|
||||
TimeTrig *tim;
|
||||
int jul;
|
||||
int AsPopUp;
|
||||
#else /* ! OS2_POPUP */
|
||||
int TriggerReminder(p, t, tim, jul)
|
||||
ParsePtr p;
|
||||
Trigger *t;
|
||||
TimeTrig *tim;
|
||||
int jul;
|
||||
#endif /* OS2_POPUP */
|
||||
#endif /* HAVE_PROTOS */
|
||||
{
|
||||
int r, y, m, d;
|
||||
char PrioExpr[25];
|
||||
static char buf[LINELEN+TOKSIZE];
|
||||
char *s, *s2;
|
||||
Value v;
|
||||
|
||||
if (t->typ == RUN_TYPE && RunDisabled) return E_RUN_DISABLED;
|
||||
if (t->typ == CAL_TYPE || t->typ == PS_TYPE || t->typ == PSF_TYPE)
|
||||
return OK;
|
||||
|
||||
/* 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) {
|
||||
if (!DoSubstFromString(Banner, SubstBuffer, JulianToday, NO_TIME) && *SubstBuffer)
|
||||
#ifdef OS2_POPUP
|
||||
if (AsPopUp)
|
||||
PutlPopUp(SubstBuffer);
|
||||
else
|
||||
printf("%s\n", SubstBuffer);
|
||||
#else
|
||||
printf("%s\n", SubstBuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If it's NextMode, process as a CAL-type entry, and issue simple-calendar
|
||||
format. */
|
||||
if (NextMode) {
|
||||
if ( (r=DoSubst(p, SubstBuffer, t, tim, jul, CAL_MODE)) ) return r;
|
||||
if (!*SubstBuffer) return OK;
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
#ifdef OS2_POPUP
|
||||
if (AsPopUp) {
|
||||
sprintf(buf, "%04d%c%02d%c%02d %s", y, DATESEP, m+1, DATESEP, d,
|
||||
SimpleTime(tim->ttime, NULL));
|
||||
StartPopUp();
|
||||
PutsPopUp(buf);
|
||||
PutlPopUp(SubstBuffer);
|
||||
}
|
||||
else
|
||||
printf("%04d%c%02d%c%02d %s%s\n", y, DATESEP, m+1, DATESEP, d,
|
||||
SimpleTime(tim->ttime, NULL),
|
||||
SubstBuffer);
|
||||
#else
|
||||
printf("%04d%c%02d%c%02d %s%s\n", y, DATESEP, m+1, DATESEP, d,
|
||||
SimpleTime(tim->ttime, NULL),
|
||||
SubstBuffer);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Put the substituted string into the SubstBuffer */
|
||||
s2 = buf;
|
||||
*s2 = 0;
|
||||
if (UserFuncExists("msgprefix") == 1) {
|
||||
sprintf(PrioExpr, "msgprefix(%d)", t->priority);
|
||||
s = PrioExpr;
|
||||
r = EvalExpr(&s, &v);
|
||||
if (!r) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
sprintf(s2, "%s", v.v.str);
|
||||
s2 += strlen(s2);
|
||||
}
|
||||
DestroyValue(v);
|
||||
}
|
||||
}
|
||||
if ( (r=DoSubst(p, s2, t, tim, jul, NORMAL_MODE)) ) return r;
|
||||
s2 += strlen(s2);
|
||||
if (UserFuncExists("msgsuffix") == 1) {
|
||||
sprintf(PrioExpr, "msgsuffix(%d)", t->priority);
|
||||
s = PrioExpr;
|
||||
r = EvalExpr(&s, &v);
|
||||
if (!r) {
|
||||
if (!DoCoerce(STR_TYPE, &v)) {
|
||||
sprintf(s2, "%s", v.v.str);
|
||||
s2 += strlen(s2);
|
||||
}
|
||||
DestroyValue(v);
|
||||
}
|
||||
}
|
||||
if ((!MsgCommand && t->typ == MSG_TYPE) || t->typ == MSF_TYPE) {
|
||||
*s2++ = '\n';
|
||||
}
|
||||
*s2 = 0;
|
||||
|
||||
/* If we are sorting, just queue it up in the sort buffer */
|
||||
if (SortByDate) {
|
||||
if (InsertIntoSortBuffer(jul, tim->ttime, buf, t->typ, t->priority) == OK) {
|
||||
NumTriggered++;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we didn't insert the reminder into the sort buffer, issue the
|
||||
reminder now. */
|
||||
switch(t->typ) {
|
||||
case MSG_TYPE:
|
||||
if (MsgCommand) {
|
||||
DoMsgCommand(MsgCommand, buf);
|
||||
} else {
|
||||
#ifdef OS2_POPUP
|
||||
if (AsPopUp)
|
||||
PutlPopUp(buf);
|
||||
else
|
||||
printf("%s", buf);
|
||||
#else
|
||||
printf("%s", buf);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case MSF_TYPE:
|
||||
#ifdef OS2_POPUP
|
||||
if (AsPopUp) {
|
||||
StartPopUp();
|
||||
FillParagraph(buf, 1);
|
||||
EndPopUp();
|
||||
} else {
|
||||
FillParagraph(buf, 0);
|
||||
}
|
||||
#else
|
||||
FillParagraph(buf);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case RUN_TYPE:
|
||||
system(buf);
|
||||
break;
|
||||
|
||||
default: /* Unknown/illegal type? */
|
||||
return E_SWERR;
|
||||
}
|
||||
|
||||
NumTriggered++;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ShouldTriggerReminder */
|
||||
/* */
|
||||
/* Return 1 if we should trigger a reminder, based on today's */
|
||||
/* date and the trigger. Return 0 if reminder should not be */
|
||||
/* triggered. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef __TURBOC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul)
|
||||
#else
|
||||
int ShouldTriggerReminder(t, tim, jul)
|
||||
Trigger *t;
|
||||
TimeTrig *tim;
|
||||
int jul;
|
||||
#endif
|
||||
{
|
||||
int r;
|
||||
|
||||
/* Handle the ONCE modifier in the reminder. */
|
||||
if (!IgnoreOnce && t->once !=NO_ONCE && FileAccessDate == JulianToday)
|
||||
return 0;
|
||||
|
||||
if (jul < JulianToday) return 0;
|
||||
|
||||
/* Don't trigger timed reminders if DontIssueAts is true, and if the
|
||||
reminder is for today */
|
||||
|
||||
#ifdef HAVE_QUEUED
|
||||
if (jul == JulianToday && DontIssueAts && tim->ttime != NO_TIME) return 0;
|
||||
#endif
|
||||
|
||||
/* Don't trigger "old" timed reminders */
|
||||
/*** REMOVED...
|
||||
if (jul == JulianToday &&
|
||||
tim->ttime != NO_TIME &&
|
||||
tim->ttime < SystemTime(0) / 60) return 0;
|
||||
*** ...UNTIL HERE */
|
||||
|
||||
/* If "infinite delta" option is chosen, always trigger future reminders */
|
||||
if (InfiniteDelta || NextMode) return 1;
|
||||
|
||||
/* Move back by delta days, if any */
|
||||
if (t->delta != NO_DELTA) {
|
||||
if (t->delta < 0)
|
||||
jul = jul + t->delta;
|
||||
else {
|
||||
r = t->delta;
|
||||
while(r && jul > JulianToday) {
|
||||
jul--;
|
||||
if (!IsOmitted(jul, t->localomit)) r--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Should we trigger the reminder? */
|
||||
return (jul <= JulianToday);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoSatRemind */
|
||||
/* */
|
||||
/* Do the "satisfying..." remind calculation. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef __TURBOC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoSatRemind(Trigger *trig, TimeTrig *tim, ParsePtr p)
|
||||
#else
|
||||
int DoSatRemind(trig, tim, p)
|
||||
Trigger *trig;
|
||||
TimeTrig *tim;
|
||||
ParsePtr p;
|
||||
#endif
|
||||
{
|
||||
int iter, jul, r;
|
||||
Value v;
|
||||
char *s, *t;
|
||||
|
||||
t = p->pos;
|
||||
iter = 0;
|
||||
jul = trig->scanfrom;
|
||||
while (iter++ < MaxSatIter) {
|
||||
jul = ComputeTrigger(jul, trig, &r);
|
||||
if (r) {
|
||||
if (r == E_CANT_TRIG) return OK; else return r;
|
||||
}
|
||||
s = p->pos;
|
||||
r = EvaluateExpr(p, &v);
|
||||
t = p->pos;
|
||||
if (r) return r;
|
||||
if (v.type != INT_TYPE && v.type != STR_TYPE) return E_BAD_TYPE;
|
||||
if (v.type == INT_TYPE && v.v.val) return OK;
|
||||
if (v.type == STR_TYPE && *v.v.str) return OK;
|
||||
p->pos = s;
|
||||
jul++;
|
||||
}
|
||||
p->pos = t;
|
||||
LastTrigValid = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ParsePriority - parse the PRIORITY portion of a reminder */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int ParsePriority(ParsePtr s, Trigger *t)
|
||||
#else
|
||||
static int ParsePriority(s, t)
|
||||
ParsePtr s;
|
||||
Trigger *t;
|
||||
#endif
|
||||
{
|
||||
int p, r;
|
||||
char *u;
|
||||
|
||||
r = ParseToken(s, TokBuffer);
|
||||
if(r) return r;
|
||||
u = TokBuffer;
|
||||
|
||||
if (!isdigit(*u)) return E_EXPECTING_NUMBER;
|
||||
p = 0;
|
||||
while (isdigit(*u)) {
|
||||
p = p*10 + *u - '0';
|
||||
u++;
|
||||
}
|
||||
if (*u) return E_EXPECTING_NUMBER;
|
||||
|
||||
/* Tricky! The only way p can be < 0 is if overflow occurred; thus,
|
||||
E2HIGH is indeed the appropriate error message. */
|
||||
if (p<0 || p>9999) return E_2HIGH;
|
||||
t->priority = p;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoMsgCommand */
|
||||
/* */
|
||||
/* Execute the '-k' command, escaping shell chars in message. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void DoMsgCommand(char *cmd, char *msg)
|
||||
#else
|
||||
void DoMsgCommand(cmd, msg)
|
||||
char *cmd;
|
||||
char *msg;
|
||||
#endif
|
||||
{
|
||||
|
||||
#ifdef WANT_SHELL_ESCAPING
|
||||
char buf[2*LINELEN+TOKSIZE];
|
||||
char *s, *t;
|
||||
|
||||
/* Escape shell characters in msg INCLUDING WHITESPACE! */
|
||||
for (t=buf, s=msg; *s; s++) {
|
||||
if (isspace(*s) || strchr("\"'!$%^&*()|<>[]{}`~;?\\", *s)) *t++ = '\\';
|
||||
*t++ = *s;
|
||||
}
|
||||
*t = 0;
|
||||
|
||||
/* Use SubstBuffer -- not too safe, since no check for overflow... */
|
||||
sprintf(SubstBuffer, cmd, buf);
|
||||
#else
|
||||
sprintf(SubstBuffer, cmd, msg);
|
||||
#endif /* WANT_SHELL_ESCAPING */
|
||||
system(SubstBuffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
661
dosubst.c
Normal file
661
dosubst.c
Normal file
@@ -0,0 +1,661 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DOSUBST.C */
|
||||
/* */
|
||||
/* This performs all the "%" substitution functions when */
|
||||
/* reminders are triggered. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: dosubst.c,v 1.1 1996-03-27 03:25:52 dfs Exp $";
|
||||
|
||||
#define L_IN_DOSUBST
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
|
||||
#define UPPER(c) (islower(c) ? toupper(c) : c)
|
||||
#define ABS(x) ( (x) < 0 ? -(x) : (x) )
|
||||
#ifndef NL
|
||||
#define NL "\n"
|
||||
#endif
|
||||
|
||||
static char TODAY[] = L_TODAY;
|
||||
static char TOMORROW[] = L_TOMORROW;
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoSubst */
|
||||
/* */
|
||||
/* Process the % escapes in the reminder. If */
|
||||
/* mode==NORMAL_MODE, ignore the %" sequence. If */
|
||||
/* mode==CAL_MODE, process the %" sequence. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoSubst(ParsePtr p, char *out, Trigger *t, TimeTrig *tt, int jul, int mode)
|
||||
#else
|
||||
int DoSubst(p, out, t, tt, jul, mode)
|
||||
ParsePtr p;
|
||||
char *out;
|
||||
Trigger *t;
|
||||
TimeTrig *tt;
|
||||
int jul, mode;
|
||||
#endif
|
||||
{
|
||||
int diff = jul - JulianToday;
|
||||
int curtime = SystemTime(0) / 60;
|
||||
int err, done;
|
||||
int c;
|
||||
int d, m, y;
|
||||
int tim = tt->ttime;
|
||||
int h, min, hh, ch, cmin, chh;
|
||||
char *pm, *cpm;
|
||||
int tdiff, adiff, mdiff, hdiff;
|
||||
char *mplu, *hplu, *when, *plu;
|
||||
int has_quote = 0;
|
||||
char *s = out;
|
||||
char *os;
|
||||
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
|
||||
if (tim == NO_TIME) tim = curtime;
|
||||
tdiff = tim - curtime;
|
||||
adiff = ABS(tdiff);
|
||||
mdiff = adiff % 60;
|
||||
hdiff = adiff / 60;
|
||||
mplu = (mdiff == 1 ? "" : L_MPLU);
|
||||
hplu = (hdiff == 1 ? "" : L_HPLU);
|
||||
when = (tdiff < 0 ? L_AGO : L_FROMNOW);
|
||||
|
||||
h = tim / 60;
|
||||
min = tim % 60;
|
||||
|
||||
#ifdef L_AMPM_OVERRIDE
|
||||
L_AMPM_OVERRIDE (pm, h)
|
||||
#else
|
||||
pm = (h < 12) ? L_AM : L_PM;
|
||||
#endif
|
||||
hh = (h == 12) ? 12 : h % 12;
|
||||
|
||||
ch = curtime / 60;
|
||||
cmin = curtime % 60;
|
||||
|
||||
#ifdef L_AMPM_OVERRIDE
|
||||
L_AMPM_OVERRIDE (cpm, ch)
|
||||
#else
|
||||
cpm = (ch < 12) ? L_AM : L_PM;
|
||||
#endif
|
||||
chh = (ch == 12) ? 12 : ch % 12;
|
||||
|
||||
#ifdef L_ORDINAL_OVERRIDE
|
||||
L_ORDINAL_OVERRIDE
|
||||
#else
|
||||
switch(d) {
|
||||
case 1:
|
||||
case 21:
|
||||
case 31: plu = "st"; break;
|
||||
|
||||
case 2:
|
||||
case 22: plu = "nd"; break;
|
||||
|
||||
case 3:
|
||||
case 23: plu = "rd"; break;
|
||||
|
||||
default: plu = "th"; break;
|
||||
}
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) return err;
|
||||
if (c == '\n') continue;
|
||||
if (!c) {
|
||||
if (mode != CAL_MODE && t->typ != RUN_TYPE && !MsgCommand)
|
||||
*s++ = '\n';
|
||||
*s++ = 0;
|
||||
break;
|
||||
}
|
||||
if (c != '%') {
|
||||
*s++ = c;
|
||||
continue;
|
||||
}
|
||||
c = ParseChar(p, &err, 0);
|
||||
if (err) return err;
|
||||
if (!c) {
|
||||
*s++ = 0;
|
||||
break;
|
||||
}
|
||||
os = s;
|
||||
done = 0;
|
||||
if (diff <= 1) {
|
||||
switch(UPPER(c)) {
|
||||
#ifndef L_NOTOMORROW_A
|
||||
case 'A':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_B
|
||||
case 'B':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_C
|
||||
case 'C':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_E
|
||||
case 'E':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_F
|
||||
case 'F':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_G
|
||||
case 'G':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_H
|
||||
case 'H':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_I
|
||||
case 'I':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_J
|
||||
case 'J':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_K
|
||||
case 'K':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_L
|
||||
case 'L':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_U
|
||||
case 'U':
|
||||
#endif
|
||||
#ifndef L_NOTOMORROW_V
|
||||
case 'V':
|
||||
#endif
|
||||
sprintf(s, "%s", (diff ? TOMORROW : TODAY));
|
||||
s += strlen(s);
|
||||
done = 1;
|
||||
break;
|
||||
|
||||
default: done = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) switch(UPPER(c)) {
|
||||
case 'A':
|
||||
#ifdef L_A_OVER
|
||||
L_A_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s, %d %s, %d", L_ON, DayName[jul%7], d,
|
||||
MonthName[m], y);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
#ifdef L_B_OVER
|
||||
L_B_OVER
|
||||
#else
|
||||
sprintf(s, L_INXDAYS, diff);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
#ifdef L_C_OVER
|
||||
L_C_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s", L_ON, DayName[jul%7]);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
#ifdef L_D_OVER
|
||||
L_D_OVER
|
||||
#else
|
||||
sprintf(s, "%d", d);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
#ifdef L_E_OVER
|
||||
L_E_OVER
|
||||
#else
|
||||
sprintf(s, "%s %02d%c%02d%c%04d", L_ON, d, DATESEP,
|
||||
m+1, DATESEP, y);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
#ifdef L_F_OVER
|
||||
L_F_OVER
|
||||
#else
|
||||
sprintf(s, "%s %02d%c%02d%c%04d", L_ON, m+1, DATESEP, d, DATESEP, y);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
#ifdef L_G_OVER
|
||||
L_G_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s, %d %s", L_ON, DayName[jul%7], d, MonthName[m]);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
#ifdef L_H_OVER
|
||||
L_H_OVER
|
||||
#else
|
||||
sprintf(s, "%s %02d%c%02d", L_ON, d, DATESEP, m+1);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
#ifdef L_I_OVER
|
||||
L_I_OVER
|
||||
#else
|
||||
sprintf(s, "%s %02d%c%02d", L_ON, m+1, DATESEP, d);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
#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);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
#ifdef L_K_OVER
|
||||
L_K_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s, %s %d%s", L_ON, DayName[jul%7],
|
||||
MonthName[m], d, plu);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
#ifdef L_L_OVER
|
||||
L_L_OVER
|
||||
#else
|
||||
sprintf(s, "%s %04d%c%02d%c%02d", L_ON, y, DATESEP, m+1, DATESEP, d);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
#ifdef L_M_OVER
|
||||
L_M_OVER
|
||||
#else
|
||||
sprintf(s, "%s", MonthName[m]);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
#ifdef L_N_OVER
|
||||
L_N_OVER
|
||||
#else
|
||||
sprintf(s, "%d", m+1);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
#ifdef L_O_OVER
|
||||
L_O_OVER
|
||||
#else
|
||||
if (RealToday == JulianToday) sprintf(s, " (%s)", L_TODAY);
|
||||
else *s = 0;
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
#ifdef L_P_OVER
|
||||
L_P_OVER
|
||||
#else
|
||||
sprintf(s, (diff == 1 ? "" : L_PLURAL));
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
#ifdef L_Q_OVER
|
||||
L_Q_OVER
|
||||
#else
|
||||
sprintf(s, (diff == 1 ? "'s" : "s'"));
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
#ifdef L_R_OVER
|
||||
L_R_OVER
|
||||
#else
|
||||
sprintf(s, "%02d", d);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
#ifdef L_S_OVER
|
||||
L_S_OVER
|
||||
#else
|
||||
sprintf(s, plu);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
#ifdef L_T_OVER
|
||||
L_T_OVER
|
||||
#else
|
||||
sprintf(s, "%02d", m+1);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
#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);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
#ifdef L_V_OVER
|
||||
L_V_OVER
|
||||
#else
|
||||
sprintf(s, "%s %s, %d%s %s", L_ON, DayName[jul%7], d, plu,
|
||||
MonthName[m]);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
#ifdef L_W_OVER
|
||||
L_W_OVER
|
||||
#else
|
||||
sprintf(s, DayName[jul%7]);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
#ifdef L_X_OVER
|
||||
L_X_OVER
|
||||
#else
|
||||
sprintf(s, "%d", diff);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
#ifdef L_Y_OVER
|
||||
L_Y_OVER
|
||||
#else
|
||||
sprintf(s, "%d", y);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
#ifdef L_Z_OVER
|
||||
L_Z_OVER
|
||||
#else
|
||||
sprintf(s, "%d", y % 100);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '1':
|
||||
#ifdef L_1_OVER
|
||||
L_1_OVER
|
||||
#else
|
||||
if (tdiff == 0)
|
||||
sprintf(s, L_NOW);
|
||||
else if (hdiff == 0)
|
||||
sprintf(s, "%d %s%s %s", mdiff, L_MINUTE, mplu, when);
|
||||
else if (mdiff == 0)
|
||||
sprintf(s, "%d %s%s %s", hdiff, L_HOUR, hplu, when);
|
||||
else
|
||||
sprintf(s, "%d %s%s %s %d %s%s %s", hdiff, L_HOUR, hplu,
|
||||
L_AND, mdiff, L_MINUTE, mplu, when);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '2':
|
||||
#ifdef L_2_OVER
|
||||
L_2_OVER
|
||||
#else
|
||||
sprintf(s, "%s %d%c%02d%s", L_AT, hh, TIMESEP, min, pm);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '3':
|
||||
#ifdef L_3_OVER
|
||||
L_3_OVER
|
||||
#else
|
||||
|
||||
sprintf(s, "%s %02d%c%02d", L_AT, h, TIMESEP, min);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '4':
|
||||
#ifdef L_4_OVER
|
||||
L_4_OVER
|
||||
#else
|
||||
sprintf(s, "%d", tdiff);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '5':
|
||||
#ifdef L_5_OVER
|
||||
L_5_OVER
|
||||
#else
|
||||
sprintf(s, "%d", adiff);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '6':
|
||||
#ifdef L_6_OVER
|
||||
L_6_OVER
|
||||
#else
|
||||
sprintf(s, when);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '7':
|
||||
#ifdef L_7_OVER
|
||||
L_7_OVER
|
||||
#else
|
||||
sprintf(s, "%d", hdiff);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '8':
|
||||
#ifdef L_8_OVER
|
||||
L_8_OVER
|
||||
#else
|
||||
sprintf(s, "%d", mdiff);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '9':
|
||||
#ifdef L_9_OVER
|
||||
L_9_OVER
|
||||
#else
|
||||
sprintf(s, mplu);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '0':
|
||||
#ifdef L_0_OVER
|
||||
L_0_OVER
|
||||
#else
|
||||
sprintf(s, hplu);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '!':
|
||||
#ifdef L_BANG_OVER
|
||||
L_BANG_OVER
|
||||
#else
|
||||
sprintf(s, (tdiff >= 0 ? L_IS : L_WAS));
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '@':
|
||||
#ifdef L_AT_OVER
|
||||
L_AT_OVER
|
||||
#else
|
||||
sprintf(s, "%d%c%02d%s", chh, TIMESEP, cmin, cpm);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '#':
|
||||
#ifdef L_HASH_OVER
|
||||
L_HASH_OVER
|
||||
#else
|
||||
sprintf(s, "%02d%c%02d", ch, TIMESEP, cmin);
|
||||
#endif
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case '_':
|
||||
if (mode != CAL_MODE && !MsgCommand)
|
||||
sprintf(s, "%s", NL);
|
||||
else
|
||||
sprintf(s, " ");
|
||||
s += strlen(s);
|
||||
break;
|
||||
|
||||
case QUOTE_MARKER:
|
||||
/* Swallow any QUOTE_MARKERs which may somehow creep in... */
|
||||
break;
|
||||
|
||||
case '"':
|
||||
*s++ = QUOTE_MARKER;
|
||||
has_quote = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
*s++ = c;
|
||||
}
|
||||
if (isupper(c)) *os = UPPER(*os);
|
||||
}
|
||||
|
||||
/* We're outside the big while loop. The only way to get here is for c to
|
||||
be null. Now we go through and delete %" sequences, if it's the
|
||||
NORMAL_MODE, or retain only things within a %" sequence if it's the
|
||||
CAL_MODE. */
|
||||
|
||||
/* 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) *out = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* There ARE quotes. If in CAL_MODE, delete everything before first quote
|
||||
and after second quote. If in NORMAL_MODE, delete the %" sequences. */
|
||||
|
||||
s = out;
|
||||
os = out;
|
||||
if (mode == NORMAL_MODE) {
|
||||
while (*s) {
|
||||
if (*s != QUOTE_MARKER) *os++ = *s;
|
||||
s++;
|
||||
}
|
||||
*os = 0;
|
||||
} else {
|
||||
|
||||
/* Skip past the quote marker */
|
||||
while (*s && (*s != QUOTE_MARKER)) s++;
|
||||
|
||||
/* Security check... actually, *s must == QUOTE_MARKER at this point, but
|
||||
it doesn't hurt to make it a bit robust. */
|
||||
if (*s) s++;
|
||||
|
||||
/* Copy the output until the next QUOTE_MARKER */
|
||||
while (*s && (*s != QUOTE_MARKER)) *os++ = *s++;
|
||||
*os = 0;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoSubstFromString */
|
||||
/* */
|
||||
/* DoSubst consumes input from a parser. This function */
|
||||
/* consumes characters from a string. It also provides */
|
||||
/* default triggers and a mode of NORMAL_MODE. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoSubstFromString(char *source, char *dest, int jul, int tim)
|
||||
#else
|
||||
int DoSubstFromString(source, dest, jul, tim)
|
||||
char *source;
|
||||
char *dest;
|
||||
int jul;
|
||||
int tim;
|
||||
#endif
|
||||
{
|
||||
Trigger tempTrig;
|
||||
TimeTrig tempTime;
|
||||
Parser tempP;
|
||||
int r;
|
||||
|
||||
if (jul == NO_DATE) jul=JulianToday;
|
||||
if (tim == NO_TIME) tim=SystemTime(0)/60;
|
||||
CreateParser(source, &tempP);
|
||||
tempP.allownested = 0;
|
||||
tempTrig.typ = MSG_TYPE;
|
||||
tempTime.ttime = tim;
|
||||
|
||||
r = DoSubst(&tempP, dest, &tempTrig, &tempTime, jul, NORMAL_MODE);
|
||||
DestroyParser(&tempP);
|
||||
return r;
|
||||
}
|
||||
110
dutch.h
Normal file
110
dutch.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DUTCH.H */
|
||||
/* */
|
||||
/* Support for the DUTCH language. */
|
||||
/* */
|
||||
/* Author: Willem Kasdorp */
|
||||
/* */
|
||||
/* Modified slightly by David Skoll */
|
||||
/* */
|
||||
/* Further corrections by Erik-Jan Vens */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: dutch.h,v 1.1 1996-03-27 03:25:53 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Dutch"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "zondag"
|
||||
#define L_MONDAY "maandag"
|
||||
#define L_TUESDAY "dinsdag"
|
||||
#define L_WEDNESDAY "woensdag"
|
||||
#define L_THURSDAY "donderdag"
|
||||
#define L_FRIDAY "vrijdag"
|
||||
#define L_SATURDAY "zaterdag"
|
||||
|
||||
/* Day initials - first letter only */
|
||||
#define L_DAYINIT "zmdwdvz"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "januari"
|
||||
#define L_FEB "februari"
|
||||
#define L_MAR "maart"
|
||||
#define L_APR "april"
|
||||
#define L_MAY "mei"
|
||||
#define L_JUN "juni"
|
||||
#define L_JUL "juli"
|
||||
#define L_AUG "augustus"
|
||||
#define L_SEP "september"
|
||||
#define L_OCT "oktober"
|
||||
#define L_NOV "november"
|
||||
#define L_DEC "december"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "vandaag"
|
||||
#define L_TOMORROW "morgen"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Herinneringen voor %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "geleden"
|
||||
#define L_FROMNOW "vanaf nu"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "over %d dagen"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "op"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix. (Indeed..., wkasdo) */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nu"
|
||||
#define L_AT "op"
|
||||
#define L_MINUTE "minuut"
|
||||
#define L_HOUR "uur"
|
||||
#define L_IS "is"
|
||||
#define L_WAS "was"
|
||||
#define L_AND "en"
|
||||
/* What to add to make "hour" plural (should result in uren, not uuren (wkasdo) */
|
||||
#define L_HPLU "en"
|
||||
/* What to add to make "minute" plural (should be minuten, not minuuten) */
|
||||
#define L_MPLU "en"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
/* Willem - I fixed the uren/uuren problem here */
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "%d %s %s", mdiff, \
|
||||
(mdiff == 1 ? "minuut" : "minuten"), when); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "%d %s %s", hdiff, \
|
||||
(mdiff == 1 ? "uur" : "uren"), when); \
|
||||
else sprintf(s, "%d %s %s %d %s %s", hdiff, \
|
||||
(hdiff == 1 ? "uur" : "uren"), \
|
||||
L_AND, mdiff, \
|
||||
(mdiff == 1 ? "minuut" : "minuten"), \
|
||||
when);
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
87
english.h
Normal file
87
english.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ENGLISH.H */
|
||||
/* */
|
||||
/* Support for the English language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: english.h,v 1.1 1996-03-27 03:25:53 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "English"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Sunday"
|
||||
#define L_MONDAY "Monday"
|
||||
#define L_TUESDAY "Tuesday"
|
||||
#define L_WEDNESDAY "Wednesday"
|
||||
#define L_THURSDAY "Thursday"
|
||||
#define L_FRIDAY "Friday"
|
||||
#define L_SATURDAY "Saturday"
|
||||
|
||||
/* Day initials - first letter only */
|
||||
#define L_DAYINIT "SMTWTFS"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "January"
|
||||
#define L_FEB "February"
|
||||
#define L_MAR "March"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "May"
|
||||
#define L_JUN "June"
|
||||
#define L_JUL "July"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "October"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "December"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "today"
|
||||
#define L_TOMORROW "tomorrow"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Reminders for %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "ago"
|
||||
#define L_FROMNOW "from now"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "in %d days' time"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "on"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "now"
|
||||
#define L_AT "at"
|
||||
#define L_MINUTE "minute"
|
||||
#define L_HOUR "hour"
|
||||
#define L_IS "is"
|
||||
#define L_WAS "was"
|
||||
#define L_AND "and"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "s"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "s"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
234
err.h
Normal file
234
err.h
Normal file
@@ -0,0 +1,234 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ERR.H */
|
||||
/* */
|
||||
/* Error definitions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: err.h,v 1.1 1996-03-27 03:25:53 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
|
||||
index the ErrMsg array. */
|
||||
|
||||
#define OK 0
|
||||
#define E_MISS_END 1
|
||||
#define E_MISS_QUOTE 2
|
||||
#define E_OP_STK_OVER 3
|
||||
#define E_VA_STK_OVER 4
|
||||
#define E_MISS_RIGHT_PAREN 5
|
||||
#define E_UNDEF_FUNC 6
|
||||
#define E_ILLEGAL_CHAR 7
|
||||
#define E_EXPECTING_BINOP 8
|
||||
#define E_NO_MEM 9
|
||||
#define E_BAD_NUMBER 10
|
||||
#define E_OP_STK_UNDER 11
|
||||
#define E_VA_STK_UNDER 12
|
||||
#define E_CANT_COERCE 13
|
||||
#define E_BAD_TYPE 14
|
||||
#define E_DATE_OVER 15
|
||||
#define E_STACK_ERR 16
|
||||
#define E_DIV_ZERO 17
|
||||
#define E_NOSUCH_VAR 18
|
||||
#define E_EOLN 19
|
||||
#define E_EOF 20
|
||||
#define E_IO_ERR 21
|
||||
#define E_LINE_2_LONG 22
|
||||
#define E_SWERR 23
|
||||
#define E_BAD_DATE 24
|
||||
#define E_2FEW_ARGS 25
|
||||
#define E_2MANY_ARGS 26
|
||||
#define E_BAD_TIME 27
|
||||
#define E_2HIGH 28
|
||||
#define E_2LOW 29
|
||||
#define E_CANT_OPEN 30
|
||||
#define E_NESTED_INCLUDE 31
|
||||
#define E_PARSE_ERR 32
|
||||
#define E_CANT_TRIG 33
|
||||
#define E_NESTED_IF 34
|
||||
#define E_ELSE_NO_IF 35
|
||||
#define E_ENDIF_NO_IF 36
|
||||
#define E_2MANY_LOCALOMIT 37
|
||||
#define E_EXTRANEOUS_TOKEN 38
|
||||
#define E_POP_NO_PUSH 39
|
||||
#define E_RUN_DISABLED 40
|
||||
#define E_DOMAIN_ERR 41
|
||||
#define E_BAD_ID 42
|
||||
#define E_RECURSIVE 43
|
||||
#define E_PARSE_AS_REM 44 /* Not really an error - just returned by
|
||||
DoOmit to indicate line should be executed
|
||||
as a REM statement, also. */
|
||||
#define E_CANT_MODIFY 45
|
||||
#define E_MKTIME_PROBLEM 46
|
||||
#define E_REDEF_FUNC 47
|
||||
#define E_CANTNEST_FDEF 48
|
||||
#define E_REP_FULSPEC 49
|
||||
#define E_YR_TWICE 50
|
||||
#define E_MON_TWICE 51
|
||||
#define E_DAY_TWICE 52
|
||||
#define E_UNKNOWN_TOKEN 53
|
||||
#define E_SPEC_MON_DAY 54
|
||||
#define E_2MANY_PART 55
|
||||
#define E_2MANY_FULL 56
|
||||
#define E_PUSH_NOPOP 57
|
||||
#define E_ERR_READING 58
|
||||
#define E_EXPECTING_EOL 59
|
||||
#define E_BAD_HEBDATE 60
|
||||
#define E_IIF_ODD 61
|
||||
#define E_MISS_ENDIF 62
|
||||
#define E_EXPECT_COMMA 63
|
||||
#define E_WD_TWICE 64
|
||||
#define E_SKIP_ERR 65
|
||||
#define E_CANT_NEST_RTYPE 66
|
||||
#define E_REP_TWICE 67
|
||||
#define E_DELTA_TWICE 68
|
||||
#define E_BACK_TWICE 69
|
||||
#define E_ONCE_TWICE 70
|
||||
#define E_EXPECT_TIME 71
|
||||
#define E_UNTIL_TWICE 72
|
||||
#define E_INCOMPLETE 73
|
||||
#define E_SCAN_TWICE 74
|
||||
#define E_VAR 75
|
||||
#define E_VAL 76
|
||||
#define E_UNDEF 77
|
||||
#define E_ENTER_FUN 78
|
||||
#define E_LEAVE_FUN 79
|
||||
#define E_EXPIRED 80
|
||||
#define E_CANTFORK 81
|
||||
#define E_CANTACCESS 82
|
||||
#define M_BAD_SYS_DATE 83
|
||||
#define M_BAD_DB_FLAG 84
|
||||
#define M_BAD_OPTION 85
|
||||
#define M_BAD_USER 86
|
||||
#define M_NO_CHG_GID 87
|
||||
#define M_NO_CHG_UID 88
|
||||
#define M_NOMEM_ENV 89
|
||||
#define E_MISS_EQ 90
|
||||
#define E_MISS_VAR 91
|
||||
#define E_MISS_EXPR 92
|
||||
#define M_CANTSET_ACCESS 93
|
||||
#define M_I_OPTION 94
|
||||
#define E_NOREMINDERS 95
|
||||
#define M_QUEUED 96
|
||||
#define E_EXPECTING_NUMBER 97
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
#undef EXTERN
|
||||
#define EXTERN
|
||||
#else
|
||||
#undef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#ifndef L_ERR_OVERRIDE
|
||||
EXTERN char *ErrMsg[]
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
= {
|
||||
"Ok",
|
||||
"Missing ']'",
|
||||
"Missing quote",
|
||||
"Expression too complex - too many operators",
|
||||
"Expression too complex - too many operands",
|
||||
"Missing ')'",
|
||||
"Undefined function",
|
||||
"Illegal character",
|
||||
"Expecting binary operator",
|
||||
"Out of memory",
|
||||
"Ill-formed number",
|
||||
"Op stack underflow - internal error",
|
||||
"Va stack underflow - internal error",
|
||||
"Can't coerce",
|
||||
"Type mismatch",
|
||||
"Date overflow",
|
||||
"Stack error - internal error",
|
||||
"Division by zero",
|
||||
"Undefined variable",
|
||||
"Unexpected end of line",
|
||||
"Unexpected end of file",
|
||||
"I/O error",
|
||||
"Line too long",
|
||||
"Internal error",
|
||||
"Bad date specification",
|
||||
"Not enough arguments",
|
||||
"Too many arguments",
|
||||
"Ill-formed time",
|
||||
"Number too high",
|
||||
"Number too low",
|
||||
"Can't open file",
|
||||
"INCLUDE nested too deeply",
|
||||
"Parse error",
|
||||
"Can't compute trigger",
|
||||
"Too many nested IFs",
|
||||
"ELSE with no matching IF",
|
||||
"ENDIF with no matching IF",
|
||||
"Can't OMIT every weekday",
|
||||
"Extraneous token(s) on line",
|
||||
"POP-OMIT-CONTEXT without matching PUSH-OMIT-CONTEXT",
|
||||
"RUN disabled",
|
||||
"Domain error",
|
||||
"Invalid identifier",
|
||||
"Recursive function call detected",
|
||||
"",
|
||||
"Cannot modify system variable",
|
||||
"C library function can't represent date/time",
|
||||
"Attempt to redefine built-in function",
|
||||
"Can't nest function definition in expression",
|
||||
"Must fully specify date to use repeat factor",
|
||||
"Year specified twice",
|
||||
"Month specified twice",
|
||||
"Day specified twice",
|
||||
"Unknown token",
|
||||
"Must specify month and day in OMIT command",
|
||||
"Too many partial OMITs",
|
||||
"Too many full OMITs",
|
||||
"Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT",
|
||||
"Error reading file",
|
||||
"Expecting end-of-line",
|
||||
"Invalid Hebrew date",
|
||||
"IIF needs odd number of arguments",
|
||||
"Warning: Missing ENDIF",
|
||||
"Expecting comma",
|
||||
"Weekday specified twice",
|
||||
"Only use one of BEFORE, AFTER or SKIP",
|
||||
"Can't nest MSG, MSF, RUN, etc. in expression",
|
||||
"Repeat value specified twice",
|
||||
"Delta value specified twice",
|
||||
"Back value specified twice",
|
||||
"ONCE keyword used twice. (Hah.)",
|
||||
"Expecting time after AT",
|
||||
"UNTIL keyword used twice",
|
||||
"Incomplete date specification",
|
||||
"SCANFROM keyword used twice",
|
||||
"Variable",
|
||||
"Value",
|
||||
"*UNDEFINED*",
|
||||
"Entering UserFN",
|
||||
"Leaving UserFN",
|
||||
"Expired",
|
||||
"fork() failed - can't do queued reminders",
|
||||
"Can't access file",
|
||||
"Illegal system date: Year is less than %d\n",
|
||||
"Unknown debug flag '%c'\n",
|
||||
"Unknown option '%c'\n",
|
||||
"Unknown user '%s'\n",
|
||||
"Could not change gid to %d\n",
|
||||
"Could not change uid to %d\n",
|
||||
"Out of memory for environment\n",
|
||||
"Missing '=' sign",
|
||||
"Missing variable name",
|
||||
"Missing expression",
|
||||
"Can't reset access date of %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"No reminders.",
|
||||
"%d reminder(s) queued for later today.\n",
|
||||
"Expecting number"
|
||||
}
|
||||
#endif /* MK_GLOBALS */
|
||||
;
|
||||
#endif /* L_ERR_OVERRIDE */
|
||||
55
expr.h
Normal file
55
expr.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* EXPR.H */
|
||||
/* */
|
||||
/* Contains a few definitions used by expression evaluator. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: expr.h,v 1.1 1996-03-27 03:25:54 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 stuff for parsing expressions */
|
||||
#define BEG_OF_EXPR '['
|
||||
#define END_OF_EXPR ']'
|
||||
#define COMMA ','
|
||||
|
||||
#define UN_OP 0 /* Unary operator */
|
||||
#define BIN_OP 1 /* Binary Operator */
|
||||
#define FUNC 2 /* Function */
|
||||
|
||||
/* Make the pushing and popping of values and operators in-line code
|
||||
for speed. BEWARE: These macros invoke return if an error happens ! */
|
||||
|
||||
#define PushOpStack(op) \
|
||||
if (OpStackPtr >= OP_STACK_SIZE) \
|
||||
return E_OP_STK_OVER; \
|
||||
else \
|
||||
OpStack[OpStackPtr++] = (op)
|
||||
|
||||
#define PopOpStack(op) \
|
||||
if (OpStackPtr <= 0) \
|
||||
return E_OP_STK_UNDER; \
|
||||
else \
|
||||
(op) = OpStack[--OpStackPtr]
|
||||
|
||||
#define PushValStack(val) \
|
||||
if (ValStackPtr >= VAL_STACK_SIZE) \
|
||||
return E_VA_STK_OVER; \
|
||||
else \
|
||||
ValStack[ValStackPtr++] = (val)
|
||||
|
||||
#define PopValStack(val) \
|
||||
if (ValStackPtr <= 0) \
|
||||
return E_VA_STK_UNDER; \
|
||||
else \
|
||||
(val) = ValStack[--ValStackPtr]
|
||||
558
files.c
Normal file
558
files.c
Normal file
@@ -0,0 +1,558 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FILES.C */
|
||||
/* */
|
||||
/* Controls the opening and closing of files, etc. Also */
|
||||
/* handles caching of lines and reading of lines from */
|
||||
/* files. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: files.c,v 1.1 1996-03-27 03:25:55 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined(__MSDOS__)
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef __MSC__
|
||||
#include <dos.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
|
||||
/* Convenient macro for closing files */
|
||||
#define FCLOSE(fp) (((fp)&&((fp)!=stdin)) ? (fclose(fp),(fp)=NULL) : ((fp)=NULL))
|
||||
|
||||
/* Define the structures needed by the file caching system */
|
||||
typedef struct cache {
|
||||
struct cache *next;
|
||||
char *text;
|
||||
int LineNo;
|
||||
} CachedLine;
|
||||
|
||||
typedef struct cheader {
|
||||
struct cheader *next;
|
||||
char *filename;
|
||||
CachedLine *cache;
|
||||
} CachedFile;
|
||||
|
||||
/* Define the structures needed by the INCLUDE file system */
|
||||
typedef struct {
|
||||
char *filename;
|
||||
int LineNo;
|
||||
unsigned int IfFlags;
|
||||
int NumIfs;
|
||||
long offset;
|
||||
CachedLine *CLine;
|
||||
} IncludeStruct;
|
||||
|
||||
static CachedFile *CachedFiles = (CachedFile *) NULL;
|
||||
static CachedLine *CLine = (CachedLine *) NULL;
|
||||
|
||||
static FILE *fp;
|
||||
|
||||
static IncludeStruct IStack[INCLUDE_NEST];
|
||||
static int IStackPtr = 0;
|
||||
|
||||
PRIVATE int ReadLineFromFile ARGS ((void));
|
||||
PRIVATE int CacheFile ARGS ((const char *fname));
|
||||
PRIVATE void DestroyCache ARGS ((CachedFile *cf));
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ReadLine */
|
||||
/* */
|
||||
/* Read a line from the file or cache. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int ReadLine(void)
|
||||
#else
|
||||
int ReadLine()
|
||||
#endif
|
||||
{
|
||||
int r;
|
||||
|
||||
/* If we're at the end of a file, pop */
|
||||
while (!CLine && !fp) {
|
||||
r = PopFile();
|
||||
if (r) return r;
|
||||
}
|
||||
|
||||
/* If it's cached, read line from the cache */
|
||||
if (CLine) {
|
||||
CurLine = CLine->text;
|
||||
LineNo = CLine->LineNo;
|
||||
CLine = CLine->next;
|
||||
FreshLine = 1;
|
||||
if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Not cached. Read from the file. */
|
||||
return ReadLineFromFile();
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ReadLineFromFile */
|
||||
/* */
|
||||
/* Read a line from the file pointed to by fp. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int ReadLineFromFile(void)
|
||||
#else
|
||||
static ReadLineFromFile()
|
||||
#endif
|
||||
{
|
||||
int l;
|
||||
char *ptr;
|
||||
char *tmp;
|
||||
|
||||
CurLine = LineBuffer;
|
||||
*LineBuffer = (char) 0;
|
||||
l = 0;
|
||||
ptr = LineBuffer;
|
||||
while(fp) {
|
||||
tmp=fgets(ptr, LINELEN-l, fp);
|
||||
LineNo++;
|
||||
if (ferror(fp)) return E_IO_ERR;
|
||||
if (feof(fp) || !tmp) {
|
||||
FCLOSE(fp);
|
||||
}
|
||||
l = strlen(LineBuffer);
|
||||
if (l && (LineBuffer[l-1] == '\n')) LineBuffer[--l] = '\0';
|
||||
if (l && (LineBuffer[l-1] == '\\')) {
|
||||
l--;
|
||||
ptr = LineBuffer+l;
|
||||
if (l >= LINELEN-1) return E_LINE_2_LONG;
|
||||
continue;
|
||||
}
|
||||
FreshLine = 1;
|
||||
if (DebugFlag & DB_ECHO_LINE) OutputLine(ErrFp);
|
||||
return OK;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* OpenFile */
|
||||
/* */
|
||||
/* Open a file for reading. If it's in the cache, set */
|
||||
/* CLine. Otherwise, open it on disk and set fp. If */
|
||||
/* ShouldCache is 1, cache the file */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int OpenFile(const char *fname)
|
||||
#else
|
||||
int OpenFile(fname)
|
||||
char *fname;
|
||||
#endif
|
||||
{
|
||||
CachedFile *h = CachedFiles;
|
||||
int r;
|
||||
|
||||
/* If it's in the cache, get it from there. */
|
||||
|
||||
while (h) {
|
||||
if (!strcmp(fname, h->filename)) {
|
||||
CLine = h->cache;
|
||||
STRSET(FileName, fname);
|
||||
LineNo = 0;
|
||||
if (FileName) return OK; else return E_NO_MEM;
|
||||
}
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
/* If it's a dash, then it's stdin */
|
||||
if (!strcmp(fname, "-")) {
|
||||
fp = stdin;
|
||||
} else {
|
||||
fp = fopen(fname, "r");
|
||||
}
|
||||
if (!fp) return E_CANT_OPEN;
|
||||
CLine = NULL;
|
||||
if (ShouldCache) {
|
||||
LineNo = 0;
|
||||
r = CacheFile(fname);
|
||||
if (r == OK) {
|
||||
fp = NULL;
|
||||
CLine = CachedFiles->cache;
|
||||
} else {
|
||||
if (strcmp(fname, "-"))
|
||||
fp = fopen(fname, "r");
|
||||
else
|
||||
fp = stdin;
|
||||
if (!fp) return E_CANT_OPEN;
|
||||
}
|
||||
}
|
||||
STRSET(FileName, fname);
|
||||
LineNo = 0;
|
||||
if (FileName) return OK; else return E_NO_MEM;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* CacheFile */
|
||||
/* */
|
||||
/* Cache a file in memory. If we fail, set ShouldCache to 0 */
|
||||
/* Returns an indication of success or failure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int CacheFile(const char *fname)
|
||||
#else
|
||||
static int CacheFile(fname)
|
||||
char *fname;
|
||||
#endif
|
||||
{
|
||||
int r;
|
||||
CachedFile *cf;
|
||||
CachedLine *cl;
|
||||
char *s;
|
||||
|
||||
cl = NULL;
|
||||
/* Create a file header */
|
||||
cf = NEW(CachedFile);
|
||||
cf->cache = NULL;
|
||||
if (!cf) { ShouldCache = 0; FCLOSE(fp); return E_NO_MEM; }
|
||||
cf->filename = StrDup(fname);
|
||||
if (!cf->filename) {
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
free(cf);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
/* Read the file */
|
||||
while(fp) {
|
||||
r = ReadLineFromFile();
|
||||
if (r) {
|
||||
DestroyCache(cf);
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
return r;
|
||||
}
|
||||
/* Skip blank chars */
|
||||
s = LineBuffer;
|
||||
while (isspace(*s)) s++;
|
||||
if (*s && *s!=';' && *s!='#') {
|
||||
/* Add the line to the cache */
|
||||
if (!cl) {
|
||||
cf->cache = NEW(CachedLine);
|
||||
if (!cf->cache) {
|
||||
DestroyCache(cf);
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
cl = cf->cache;
|
||||
} else {
|
||||
cl->next = NEW(CachedLine);
|
||||
if (!cl->next) {
|
||||
DestroyCache(cf);
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
cl = cl->next;
|
||||
}
|
||||
cl->next = NULL;
|
||||
cl->LineNo = LineNo;
|
||||
cl->text = StrDup(s);
|
||||
if (!cl->text) {
|
||||
DestroyCache(cf);
|
||||
ShouldCache = 0;
|
||||
FCLOSE(fp);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Put the cached file at the head of the queue */
|
||||
cf->next = CachedFiles;
|
||||
CachedFiles = cf;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* PopFile - we've reached the end. Pop up to the previous */
|
||||
/* file, or return E_EOF */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int PopFile(void)
|
||||
#else
|
||||
int PopFile()
|
||||
#endif
|
||||
{
|
||||
IncludeStruct *i;
|
||||
|
||||
if (!Hush && NumIfs) Eprint("%s", ErrMsg[E_MISS_ENDIF]);
|
||||
if (!IStackPtr) return E_EOF;
|
||||
IStackPtr--;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
LineNo = i->LineNo;
|
||||
IfFlags = i->IfFlags;
|
||||
NumIfs = i->NumIfs;
|
||||
CLine = i->CLine;
|
||||
fp = NULL;
|
||||
STRSET(FileName, i->filename);
|
||||
if (!CLine && (i->offset != -1L)) {
|
||||
/* We must open the file, then seek to specified position */
|
||||
if (strcmp(i->filename, "-"))
|
||||
fp = fopen(i->filename, "r");
|
||||
else
|
||||
fp = stdin;
|
||||
if (!fp) return E_CANT_OPEN;
|
||||
if (fp != stdin)
|
||||
(void) fseek(fp, i->offset, 0); /* Trust that it works... */
|
||||
}
|
||||
free(i->filename);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoInclude */
|
||||
/* */
|
||||
/* The INCLUDE command. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoInclude(ParsePtr p)
|
||||
#else
|
||||
int DoInclude(p)
|
||||
ParsePtr p;
|
||||
#endif
|
||||
{
|
||||
char tok[TOKSIZE];
|
||||
int r, e;
|
||||
|
||||
if ( (r=ParseToken(p, tok)) ) return r;
|
||||
e = VerifyEoln(p);
|
||||
if (e) Eprint("%s", ErrMsg[e]);
|
||||
if ( (r=IncludeFile(tok)) ) return r;
|
||||
NumIfs = 0;
|
||||
IfFlags = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* IncludeFile */
|
||||
/* */
|
||||
/* Process the INCLUDE command - actually do the file */
|
||||
/* inclusion. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int IncludeFile(const char *fname)
|
||||
#else
|
||||
int IncludeFile(fname)
|
||||
char *fname;
|
||||
#endif
|
||||
{
|
||||
IncludeStruct *i;
|
||||
int r;
|
||||
|
||||
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
|
||||
i = &IStack[IStackPtr];
|
||||
|
||||
i->filename = StrDup(FileName);
|
||||
if (!i->filename) return E_NO_MEM;
|
||||
i->LineNo = LineNo;
|
||||
i->NumIfs = NumIfs;
|
||||
i->IfFlags = IfFlags;
|
||||
i->CLine = CLine;
|
||||
i->offset = -1L;
|
||||
if (fp) {
|
||||
i->offset = ftell(fp);
|
||||
FCLOSE(fp);
|
||||
}
|
||||
|
||||
IStackPtr++;
|
||||
|
||||
/* Try to open the new file */
|
||||
if (!OpenFile(fname)) {
|
||||
return OK;
|
||||
}
|
||||
/* Ugh! We failed! */
|
||||
if ( (r=PopFile()) ) return r;
|
||||
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], fname);
|
||||
return E_CANT_OPEN;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetAccessDate - get the access date of a file. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int GetAccessDate(char *file)
|
||||
#else
|
||||
int GetAccessDate(file)
|
||||
char *file;
|
||||
#endif
|
||||
{
|
||||
struct stat statbuf;
|
||||
struct tm *t1;
|
||||
|
||||
if (stat(file, &statbuf)) return -1;
|
||||
#ifdef __TURBOC__
|
||||
t1 = localtime( (time_t *) &(statbuf.st_atime) );
|
||||
#else
|
||||
t1 = localtime(&(statbuf.st_atime));
|
||||
#endif
|
||||
|
||||
if (t1->tm_year + 1900 < BASE)
|
||||
return 0;
|
||||
else
|
||||
return Julian(t1->tm_year+1900, t1->tm_mon, t1->tm_mday);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SetAccessDate */
|
||||
/* */
|
||||
/* Used only by DOS to set access date after we close the */
|
||||
/* file. Not needed for UNIX. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#if defined(__MSDOS__)
|
||||
/*
|
||||
* WARNING WARNING WARNING WARNING
|
||||
* In the version of Turbo C which I have, there is a bug in the
|
||||
* stdio.h file. The following lines correct the bug. YOU MAY
|
||||
* HAVE TO REMOVE THESE LINES FOR LATER VERSIONS OF TURBOC
|
||||
*/
|
||||
#ifdef __TURBOC__
|
||||
#ifndef fileno
|
||||
#define fileno(f) ((f)->fd)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int SetAccessDate(char *fname, int jul)
|
||||
#else
|
||||
int SetAccessDate(fname, jul)
|
||||
char *fname;
|
||||
int jul;
|
||||
#endif
|
||||
{
|
||||
|
||||
#ifdef __TURBOC__
|
||||
int y, m, d;
|
||||
struct ftime ft;
|
||||
FILE *f;
|
||||
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
ft.ft_tsec = 0;
|
||||
ft.ft_min = 0;
|
||||
ft.ft_hour = 12; /* Arbitrarily set time to noon. */
|
||||
ft.ft_day = (unsigned int) d;
|
||||
ft.ft_month = (unsigned int) m+1;
|
||||
ft.ft_year = (unsigned int) (y - 1980);
|
||||
|
||||
f = fopen(fname, "r");
|
||||
if (!f || setftime(fileno(f) , &ft)) {
|
||||
|
||||
#else /* Must be MSC */
|
||||
if (utime(fname, (struct utimbuf *) NULL)) {
|
||||
#endif
|
||||
fprintf(ErrFp, ErrMsg[M_CANTSET_ACCESS], fname);
|
||||
|
||||
#ifdef __TURBOC__
|
||||
if (f) FCLOSE(f);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __TURBOC__
|
||||
FCLOSE(f);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DestroyCache */
|
||||
/* */
|
||||
/* Free all the memory used by a cached file. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void DestroyCache(CachedFile *cf)
|
||||
#else
|
||||
static void DestroyCache(cf)
|
||||
CachedFile *cf;
|
||||
#endif
|
||||
{
|
||||
CachedLine *cl, *cnext;
|
||||
CachedFile *temp;
|
||||
if (cf->filename) free(cf->filename);
|
||||
cl = cf->cache;
|
||||
while (cl) {
|
||||
if (cl->text) free (cl->text);
|
||||
cnext = cl->next;
|
||||
free(cl);
|
||||
cl = cnext;
|
||||
}
|
||||
if (CachedFiles == cf) CachedFiles = cf->next;
|
||||
else {
|
||||
temp = CachedFiles;
|
||||
while(temp) {
|
||||
if (temp->next == cf) {
|
||||
temp->next = cf->next;
|
||||
break;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
free(cf);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* TopLevel */
|
||||
/* */
|
||||
/* Returns 1 if current file is top level, 0 otherwise. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int TopLevel(void)
|
||||
#else
|
||||
int TopLevel()
|
||||
#endif
|
||||
{
|
||||
return !IStackPtr;
|
||||
}
|
||||
617
finnish.h
Normal file
617
finnish.h
Normal file
@@ -0,0 +1,617 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FINNISH.H */
|
||||
/* */
|
||||
/* Support for the Finnish language. */
|
||||
/* */
|
||||
/* Author: Mikko Silvonen <Mikko.Silvonen@Helsinki.FI> */
|
||||
/* */
|
||||
/* Finnish holidays and name days for Remind are available */
|
||||
/* at ftp.funet.fi (pub/unix/misc/remind-fin*). */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* This file is Copyright (C) 1993, 1994 by Mikko Silvonen. */
|
||||
/* REMIND is Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: finnish.h,v 1.1 1996-03-27 03:25:55 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Finnish"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "sunnuntai"
|
||||
#define L_MONDAY "maanantai"
|
||||
#define L_TUESDAY "tiistai"
|
||||
#define L_WEDNESDAY "keskiviikko"
|
||||
#define L_THURSDAY "torstai"
|
||||
#define L_FRIDAY "perjantai"
|
||||
#define L_SATURDAY "lauantai"
|
||||
|
||||
/* Day initials - first letter only */
|
||||
#define L_DAYINIT "SMTKTPL"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "tammikuu"
|
||||
#define L_FEB "helmikuu"
|
||||
#define L_MAR "maaliskuu"
|
||||
#define L_APR "huhtikuu"
|
||||
#define L_MAY "toukokuu"
|
||||
#if defined(ISOLATIN1)
|
||||
#define L_JUN "kes\xE4kuu"
|
||||
#define L_JUL "hein\xE4kuu"
|
||||
#elif defined(IBMEXTENDED)
|
||||
#define L_JUN "kes\x84kuu"
|
||||
#define L_JUL "hein\x84kuu"
|
||||
#else
|
||||
#define L_JUN "kes{kuu"
|
||||
#define L_JUL "hein{kuu"
|
||||
#endif
|
||||
#define L_AUG "elokuu"
|
||||
#define L_SEP "syyskuu"
|
||||
#define L_OCT "lokakuu"
|
||||
#define L_NOV "marraskuu"
|
||||
#define L_DEC "joulukuu"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#if defined(ISOLATIN1)
|
||||
#define L_TODAY "t\xE4n\xE4\xE4n"
|
||||
#elif defined(IBMEXTENDED)
|
||||
#define L_TODAY "t\x84n\x84\x84n"
|
||||
#else
|
||||
#define L_TODAY "t{n{{n"
|
||||
#endif
|
||||
#define L_TOMORROW "huomenna"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Viestit %wna, %d. %mta %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "ap"
|
||||
#define L_PM "ip"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "sitten"
|
||||
#define L_FROMNOW "kuluttua"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#if defined(ISOLATIN1)
|
||||
#define L_INXDAYS "%d p\xE4iv\xE4n kuluttua"
|
||||
#elif defined(IBMEXTENDED)
|
||||
#define L_INXDAYS "%d p\x84iv\x84n kuluttua"
|
||||
#else
|
||||
#define L_INXDAYS "%d p{iv{n kuluttua"
|
||||
#endif
|
||||
|
||||
/* "on" as in "on date...", but in Finnish it is a case ending;
|
||||
L_PARTIT is the partitive ending appended to -kuu and -tai */
|
||||
#define L_ON "na"
|
||||
#define L_PARTIT "ta"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
/* The partitive ending of "day" */
|
||||
#if defined(ISOLATIN1)
|
||||
#define L_PLURAL "\xE4"
|
||||
#elif defined(IBMEXTENDED)
|
||||
#define L_PLURAL "\x84"
|
||||
#else
|
||||
#define L_PLURAL "{"
|
||||
#endif
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "nyt"
|
||||
#define L_AT "klo"
|
||||
#define L_MINUTE "minuutti"
|
||||
#define L_HOUR "tunti"
|
||||
#define L_IS "on"
|
||||
#define L_WAS "oli"
|
||||
#define L_AND "ja"
|
||||
|
||||
/* What to add to make "hour" plural (or actually partitive) */
|
||||
#define L_HPLU "a"
|
||||
/* What to add to make "minute" plural (or actually partitive) */
|
||||
#define L_MPLU "a"
|
||||
|
||||
/* Genitive form of "hour" */
|
||||
#define L_HGEN "tunnin"
|
||||
/* Genitive form of "minute" */
|
||||
#define L_MGEN "minuutin"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#if defined(ISOLATIN1)
|
||||
#define L_ORDINAL_OVERRIDE switch(d) { \
|
||||
case 1: plu = ":sen\xE4"; break; \
|
||||
case 2: plu = ":sena"; break; \
|
||||
default: \
|
||||
switch(d%10) { \
|
||||
case 2: \
|
||||
case 3: \
|
||||
case 6: \
|
||||
case 8: plu = ":ntena"; break; \
|
||||
default: plu = ":nten\xE4"; break; \
|
||||
} \
|
||||
}
|
||||
#elif defined(IBMEXTENDED)
|
||||
#define L_ORDINAL_OVERRIDE switch(d) { \
|
||||
case 1: plu = ":sen\x84"; break; \
|
||||
case 2: plu = ":sena"; break; \
|
||||
default: \
|
||||
switch(d%10) { \
|
||||
case 2: \
|
||||
case 3: \
|
||||
case 6: \
|
||||
case 8: plu = ":ntena"; break; \
|
||||
default: plu = ":nten\x84"; break; \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define L_ORDINAL_OVERRIDE switch(d) { \
|
||||
case 1: plu = ":sen{"; break; \
|
||||
case 2: plu = ":sena"; break; \
|
||||
default: \
|
||||
switch(d%10) { \
|
||||
case 2: \
|
||||
case 3: \
|
||||
case 6: \
|
||||
case 8: plu = ":ntena"; break; \
|
||||
default: plu = ":nten{"; break; \
|
||||
} \
|
||||
}
|
||||
#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_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_1_OVER if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else { \
|
||||
if (hdiff != 0) { \
|
||||
if (tdiff < 0) \
|
||||
sprintf(s, "%d %s%s ", hdiff, L_HOUR, hplu); \
|
||||
else \
|
||||
sprintf(s, "%d %s ", hdiff, L_HGEN); \
|
||||
s += strlen(s); \
|
||||
} \
|
||||
if (mdiff != 0) { \
|
||||
if (tdiff < 0) \
|
||||
sprintf(s, "%d %s%s ", mdiff, L_MINUTE, \
|
||||
mplu); \
|
||||
else \
|
||||
sprintf(s, "%d %s ", mdiff, L_MGEN); \
|
||||
s += strlen(s); \
|
||||
} \
|
||||
sprintf(s, when); \
|
||||
}
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
#if defined(ISOLATIN1)
|
||||
"Ok",
|
||||
"Puuttuva ']'",
|
||||
"Puuttuva lainausmerkki",
|
||||
"Liian monimutkainen lauseke - liikaa operaattoreita",
|
||||
"Liian monimutkainen lauseke - liikaa operandeja",
|
||||
"Puuttuva ')'",
|
||||
"M\xE4\xE4rittelem\xE4t\xF6n funktio",
|
||||
"Virheellinen merkki",
|
||||
"Kaksipaikkainen operaattori puuttuu",
|
||||
"Muisti loppui",
|
||||
"Virheellinen luku",
|
||||
"Operaattoripino tyhj\xE4 - sis\xE4inen virhe",
|
||||
"Muuttujapino tyhj\xE4 - sis\xE4inen virhe",
|
||||
"Tyyppimuunnos ei onnistu",
|
||||
"Virheellinen tyyppi",
|
||||
"Liian suuri p\xE4iv\xE4ys",
|
||||
"Pinovirhe - sis\xE4inen virhe",
|
||||
"Jako nollalla",
|
||||
"M\xE4\xE4rittelem\xE4t\xF6n funktio",
|
||||
"Odottamaton rivin loppu",
|
||||
"Odottamaton tiedoston loppu",
|
||||
"Sy\xF6tt\xF6- tai tulostusvirhe",
|
||||
"Liian pitk\xE4 rivi",
|
||||
"Sis\xE4inen virhe",
|
||||
"Virheellinen p\xE4iv\xE4ys",
|
||||
"Liian v\xE4h\xE4n argumentteja",
|
||||
"Liian paljon argumentteja",
|
||||
"Virheellinen aika",
|
||||
"Liian suuri luku",
|
||||
"Liian pieni luku",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Liian monta sis\xE4kk\xE4ist\xE4 INCLUDEa",
|
||||
"J\xE4sennysvirhe",
|
||||
"Laukaisuhetken laskenta ei onnistu",
|
||||
"Liian monta sis\xE4kk\xE4ist\xE4 IF-lausetta",
|
||||
"ELSE ilman IF-lausetta",
|
||||
"ENDIF ilman IF-lausetta",
|
||||
"Kaikkia viikonp\xE4ivi\xE4 ei voi j\xE4tt\xE4\xE4 pois",
|
||||
"Ylim\xE4\xE4r\xE4isi\xE4 merkkej\xE4 rivill\xE4",
|
||||
"POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia",
|
||||
"RUN-lauseen k\xE4ytt\xF6 estetty",
|
||||
"Arvoaluevirhe",
|
||||
"Virheellinen tunniste",
|
||||
"Rekursiivinen funktiokutsu havaittu",
|
||||
"",
|
||||
"J\xE4rjestelm\xE4muuttujan muuttaminen ei onnistu",
|
||||
"C-kirjastofunktio ei pysty esitt\xE4m\xE4\xE4n p\xE4iv\xE4yst\xE4 tai aikaa",
|
||||
"Sis\xE4isen funktion m\xE4\xE4ritelm\xE4\xE4 yritettiin muuttaa",
|
||||
"Lausekkeessa ei voi olla sis\xE4kk\xE4isi\xE4 funktiom\xE4\xE4ritelmi\xE4",
|
||||
"P\xE4iv\xE4yksen t\xE4ytyy olla t\xE4ydellinen toistokertoimessa",
|
||||
"Vuosi annettu kahdesti",
|
||||
"Kuukausi annettu kahdesti",
|
||||
"P\xE4iv\xE4 annettu kahdesti",
|
||||
"Tuntematon sana tai merkki",
|
||||
"OMIT-komennossa on annettava kuukausi ja p\xE4iv\xE4",
|
||||
"Liian monta osittaista OMIT-komentoa",
|
||||
"Liian monta t\xE4ydellist\xE4 OMIT-komentoa",
|
||||
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
|
||||
"Virhe tiedoston luvussa",
|
||||
"Pilkku puuttuu",
|
||||
"Virheellinen juutalainen p\xE4iv\xE4ys",
|
||||
"IIF vaatii parittoman m\xE4\xE4r\xE4n argumentteja",
|
||||
"Varoitus: puuttuva ENDIF",
|
||||
"Pilkku puuttuu",
|
||||
"Viikonp\xE4iv\xE4 annettu kahdesti",
|
||||
"K\xE4yt\xE4 vain yht\xE4 komennoista BEFORE, AFTER ja SKIP",
|
||||
"Sis\xE4kk\xE4isi\xE4 MSG-, MSF- ja RUN-lauseita ei voi k\xE4ytt\xE4\xE4 lausekkeessa",
|
||||
"Toistokerroin annettu kahdesti",
|
||||
"Delta-arvo annettu kahdesti",
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k\xE4ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per\xE4st\xE4 puuttuu aika",
|
||||
"UNTIL-sanaa k\xE4ytetty kahdesti",
|
||||
"Ep\xE4t\xE4ydellinen p\xE4iv\xE4ys",
|
||||
"SCANFROM-sanaa k\xE4ytetty kahdesti",
|
||||
"Muuttuja",
|
||||
"Arvo",
|
||||
"*M\xC4\xC4RITTELEM\xC4T\xD6N*",
|
||||
"Siirryt\xE4\xE4n funktioon",
|
||||
"Poistutaan funktiosta",
|
||||
"Vanhentunut",
|
||||
"fork() ep\xE4onnistui - jonomuistutukset eiv\xE4t toimi",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Virheellinen j\xE4rjestelm\xE4p\xE4iv\xE4ys: vuosi on v\xE4hemm\xE4n kuin %d\n",
|
||||
"Tuntematon virheenetsint\xE4tarkenne '%c'\n",
|
||||
"Tuntematon tarkenne '%c'\n",
|
||||
"Tuntematon k\xE4ytt\xE4j\xE4 '%s'\n",
|
||||
"Ryhm\xE4numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"K\xE4ytt\xE4j\xE4numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Muisti ei riit\xE4 ymp\xE4rist\xF6lle\n",
|
||||
"Puuttuva '='-merkki",
|
||||
"Puuttuva muuttujanimi",
|
||||
"Puuttuva lauseke",
|
||||
"P\xE4iv\xE4n asetus %s:ksi ei onnitus\n",
|
||||
"Remind: tarkenne '-i': %s\n",
|
||||
"Ei viestej\xE4.",
|
||||
"%d viesti(\xE4) t\xE4m\xE4n p\xE4iv\xE4n jonossa.\n",
|
||||
#elif defined(IBMEXTENDED)
|
||||
"Ok",
|
||||
"Puuttuva ']'",
|
||||
"Puuttuva lainausmerkki",
|
||||
"Liian monimutkainen lauseke - liikaa operaattoreita",
|
||||
"Liian monimutkainen lauseke - liikaa operandeja",
|
||||
"Puuttuva ')'",
|
||||
"M\x84\x84rittelem\x84t\x94n funktio",
|
||||
"Virheellinen merkki",
|
||||
"Kaksipaikkainen operaattori puuttuu",
|
||||
"Muisti loppui",
|
||||
"Virheellinen luku",
|
||||
"Operaattoripino tyhj\x84 - sis\x84inen virhe",
|
||||
"Muuttujapino tyhj\x84 - sis\x84inen virhe",
|
||||
"Tyyppimuunnos ei onnistu",
|
||||
"Virheellinen tyyppi",
|
||||
"Liian suuri p\x84iv\x84ys",
|
||||
"Pinovirhe - sis\x84inen virhe",
|
||||
"Jako nollalla",
|
||||
"M\x84\x84rittelem\x84t\x94n funktio",
|
||||
"Odottamaton rivin loppu",
|
||||
"Odottamaton tiedoston loppu",
|
||||
"Sy\x94tt\x94- tai tulostusvirhe",
|
||||
"Liian pitk\x84 rivi",
|
||||
"Sis\x84inen virhe",
|
||||
"Virheellinen p\x84iv\x84ys",
|
||||
"Liian v\x84h\x84n argumentteja",
|
||||
"Liian paljon argumentteja",
|
||||
"Virheellinen aika",
|
||||
"Liian suuri luku",
|
||||
"Liian pieni luku",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Liian monta sis\x84kk\x84ist\x84 INCLUDEa",
|
||||
"J\x84sennysvirhe",
|
||||
"Laukaisuhetken laskenta ei onnistu",
|
||||
"Liian monta sis\x84kk\x84ist\x84 IF-lausetta",
|
||||
"ELSE ilman IF-lausetta",
|
||||
"ENDIF ilman IF-lausetta",
|
||||
"Kaikkia viikonp\x84ivi\x84 ei voi j\x84tt\x84\x84 pois",
|
||||
"Ylim\x84\x84r\x84isi\x84 merkkej\x84 rivill\x84",
|
||||
"POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia",
|
||||
"RUN-lauseen k\x84ytt\x94 estetty",
|
||||
"Arvoaluevirhe",
|
||||
"Virheellinen tunniste",
|
||||
"Rekursiivinen funktiokutsu havaittu",
|
||||
"",
|
||||
"J\x84rjestelm\x84muuttujan muuttaminen ei onnistu",
|
||||
"C-kirjastofunktio ei pysty esitt\x84m\x84\x84n p\x84iv\x84yst\x84 tai aikaa",
|
||||
"Sis\x84isen funktion m\x84\x84ritelm\x84\x84 yritettiin muuttaa",
|
||||
"Lausekkeessa ei voi olla sis\x84kk\x84isi\x84 funktiom\x84\x84ritelmi\x84",
|
||||
"P\x84iv\x84yksen t\x84ytyy olla t\x84ydellinen toistokertoimessa",
|
||||
"Vuosi annettu kahdesti",
|
||||
"Kuukausi annettu kahdesti",
|
||||
"P\x84iv\x84 annettu kahdesti",
|
||||
"Tuntematon sana tai merkki",
|
||||
"OMIT-komennossa on annettava kuukausi ja p\x84iv\x84",
|
||||
"Liian monta osittaista OMIT-komentoa",
|
||||
"Liian monta t\x84ydellist\x84 OMIT-komentoa",
|
||||
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
|
||||
"Virhe tiedoston luvussa",
|
||||
"Pilkku puuttuu",
|
||||
"Virheellinen juutalainen p\x84iv\x84ys",
|
||||
"IIF vaatii parittoman m\x84\x84r\x84n argumentteja",
|
||||
"Varoitus: puuttuva ENDIF",
|
||||
"Pilkku puuttuu",
|
||||
"Viikonp\x84iv\x84 annettu kahdesti",
|
||||
"K\x84yt\x84 vain yht\x84 komennoista BEFORE, AFTER ja SKIP",
|
||||
"Sis\x84kk\x84isi\x84 MSG-, MSF- ja RUN-lauseita ei voi k\x84ytt\x84\x84 lausekkeessa",
|
||||
"Toistokerroin annettu kahdesti",
|
||||
"Delta-arvo annettu kahdesti",
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k\x84ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per\x84st\x84 puuttuu aika",
|
||||
"UNTIL-sanaa k\x84ytetty kahdesti",
|
||||
"Ep\x84t\x84ydellinen p\x84iv\x84ys",
|
||||
"SCANFROM-sanaa k\x84ytetty kahdesti",
|
||||
"Muuttuja",
|
||||
"Arvo",
|
||||
"*M\x8E\x8ERITTELEM\x8ET\x99N*",
|
||||
"Siirryt\x84\x84n funktioon",
|
||||
"Poistutaan funktiosta",
|
||||
"Vanhentunut",
|
||||
"fork() ep\x84onnistui - jonomuistutukset eiv\x84t toimi",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Virheellinen j\x84rjestelm\x84p\x84iv\x84ys: vuosi on v\x84hemm\x84n kuin %d\n",
|
||||
"Tuntematon virheenetsint\x84tarkenne '%c'\n",
|
||||
"Tuntematon tarkenne '%c'\n",
|
||||
"Tuntematon k\x84ytt\x84j\x84 '%s'\n",
|
||||
"Ryhm\x84numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"K\x84ytt\x84j\x84numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Muisti ei riit\x84 ymp\x84rist\x94lle\n",
|
||||
"Puuttuva '='-merkki",
|
||||
"Puuttuva muuttujanimi",
|
||||
"Puuttuva lauseke",
|
||||
"P\x84iv\x84n asetus %s:ksi ei onnitus\n",
|
||||
"Remind: tarkenne '-i': %s\n",
|
||||
"Ei viestej\x84.",
|
||||
"%d viesti(\x84) t\x84m\x84n p\x84iv\x84n jonossa.\n",
|
||||
"Numero puuttuu"
|
||||
#else
|
||||
"Ok",
|
||||
"Puuttuva ']'",
|
||||
"Puuttuva lainausmerkki",
|
||||
"Liian monimutkainen lauseke - liikaa operaattoreita",
|
||||
"Liian monimutkainen lauseke - liikaa operandeja",
|
||||
"Puuttuva ')'",
|
||||
"M{{rittelem{t|n funktio",
|
||||
"Virheellinen merkki",
|
||||
"Kaksipaikkainen operaattori puuttuu",
|
||||
"Muisti loppui",
|
||||
"Virheellinen luku",
|
||||
"Operaattoripino tyhj{ - sis{inen virhe",
|
||||
"Muuttujapino tyhj{ - sis{inen virhe",
|
||||
"Tyyppimuunnos ei onnistu",
|
||||
"Virheellinen tyyppi",
|
||||
"Liian suuri p{iv{ys",
|
||||
"Pinovirhe - sis{inen virhe",
|
||||
"Jako nollalla",
|
||||
"M{{rittelem{t|n funktio",
|
||||
"Odottamaton rivin loppu",
|
||||
"Odottamaton tiedoston loppu",
|
||||
"Sy|tt|- tai tulostusvirhe",
|
||||
"Liian pitk{ rivi",
|
||||
"Sis{inen virhe",
|
||||
"Virheellinen p{iv{ys",
|
||||
"Liian v{h{n argumentteja",
|
||||
"Liian paljon argumentteja",
|
||||
"Virheellinen aika",
|
||||
"Liian suuri luku",
|
||||
"Liian pieni luku",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Liian monta sis{kk{ist{ INCLUDEa",
|
||||
"J{sennysvirhe",
|
||||
"Laukaisuhetken laskenta ei onnistu",
|
||||
"Liian monta sis{kk{ist{ IF-lausetta",
|
||||
"ELSE ilman IF-lausetta",
|
||||
"ENDIF ilman IF-lausetta",
|
||||
"Kaikkia viikonp{ivi{ ei voi j{tt{{ pois",
|
||||
"Ylim{{r{isi{ merkkej{ rivill{",
|
||||
"POP-OMIT-CONTEXT ilman PUSH-OMIT-CONTEXTia",
|
||||
"RUN-lauseen k{ytt| estetty",
|
||||
"Arvoaluevirhe",
|
||||
"Virheellinen tunniste",
|
||||
"Rekursiivinen funktiokutsu havaittu",
|
||||
"",
|
||||
"J{rjestelm{muuttujan muuttaminen ei onnistu",
|
||||
"C-kirjastofunktio ei pysty esitt{m{{n p{iv{yst{ tai aikaa",
|
||||
"Sis{isen funktion m{{ritelm{{ yritettiin muuttaa",
|
||||
"Lausekkeessa ei voi olla sis{kk{isi{ funktiom{{ritelmi{",
|
||||
"P{iv{yksen t{ytyy olla t{ydellinen toistokertoimessa",
|
||||
"Vuosi annettu kahdesti",
|
||||
"Kuukausi annettu kahdesti",
|
||||
"P{iv{ annettu kahdesti",
|
||||
"Tuntematon sana tai merkki",
|
||||
"OMIT-komennossa on annettava kuukausi ja p{iv{",
|
||||
"Liian monta osittaista OMIT-komentoa",
|
||||
"Liian monta t{ydellist{ OMIT-komentoa",
|
||||
"Varoitus: PUSH-OMIT-CONTEXT ilman POP-OMIT-CONTEXTia",
|
||||
"Virhe tiedoston luvussa",
|
||||
"Pilkku puuttuu",
|
||||
"Virheellinen juutalainen p{iv{ys",
|
||||
"IIF vaatii parittoman m{{r{n argumentteja",
|
||||
"Varoitus: puuttuva ENDIF",
|
||||
"Pilkku puuttuu",
|
||||
"Viikonp{iv{ annettu kahdesti",
|
||||
"K{yt{ vain yht{ komennoista BEFORE, AFTER ja SKIP",
|
||||
"Sis{kk{isi{ MSG-, MSF- ja RUN-lauseita ei voi k{ytt{{ lausekkeessa",
|
||||
"Toistokerroin annettu kahdesti",
|
||||
"Delta-arvo annettu kahdesti",
|
||||
"Peruutusarvo annettu kahdesti",
|
||||
"ONCE-avainsanaa k{ytetty kahdesti. (Hah.)",
|
||||
"AT-sanan per{st{ puuttuu aika",
|
||||
"UNTIL-sanaa k{ytetty kahdesti",
|
||||
"Ep{t{ydellinen p{iv{ys",
|
||||
"SCANFROM-sanaa k{ytetty kahdesti",
|
||||
"Muuttuja",
|
||||
"Arvo",
|
||||
"*M[[RITTELEM[T\\N*",
|
||||
"Siirryt{{n funktioon",
|
||||
"Poistutaan funktiosta",
|
||||
"Vanhentunut",
|
||||
"fork() ep{onnistui - jonomuistutukset eiv{t toimi",
|
||||
"Tiedoston avaus ei onnistu",
|
||||
"Virheellinen j{rjestelm{p{iv{ys: vuosi on v{hemm{n kuin %d\n",
|
||||
"Tuntematon virheenetsint{tarkenne '%c'\n",
|
||||
"Tuntematon tarkenne '%c'\n",
|
||||
"Tuntematon k{ytt{j{ '%s'\n",
|
||||
"Ryhm{numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"K{ytt{j{numeron vaihto %d:ksi ei onnistunut\n",
|
||||
"Muisti ei riit{ ymp{rist|lle\n",
|
||||
"Puuttuva '='-merkki",
|
||||
"Puuttuva muuttujanimi",
|
||||
"Puuttuva lauseke",
|
||||
"P{iv{n asetus %s:ksi ei onnitus\n",
|
||||
"Remind: tarkenne '-i': %s\n",
|
||||
"Ei viestej{.",
|
||||
"%d viesti({) t{m{n p{iv{n jonossa.\n",
|
||||
"Numero puuttuu"
|
||||
#endif
|
||||
};
|
||||
#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 */
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1994 by David F. Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETAVERSIO <<<<\n");
|
||||
#endif
|
||||
#if defined(ISOLATIN1)
|
||||
fprintf(ErrFp, "K\xE4ytt\xF6: remind [tarkenteet] tiedosto [p\xE4iv\xE4ys] [aika] [*toisto]\n");
|
||||
fprintf(ErrFp, "Tarkenteet:\n");
|
||||
fprintf(ErrFp, " -n Tulosta viestien seuraavat esiintymiskerrat yksink. muodossa\n");
|
||||
fprintf(ErrFp, " -r Est\xE4 RUN-lauseiden k\xE4ytt\xF6\n");
|
||||
fprintf(ErrFp, " -c[n] Tulosta n:n kuukauden kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -c+[n] Tulosta n:n viikon kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja v\xE4lit\n");
|
||||
fprintf(ErrFp, " -s[+][n] Tulosta n:n kuukauden (viikon) 'yksink. kalenteri' (oletus 1)\n");
|
||||
fprintf(ErrFp, " -p[n] Kuten -s, mutta tulosta rem2ps:lle sopivassa muodossa\n");
|
||||
fprintf(ErrFp, " -v Laveat tulostukset\n");
|
||||
fprintf(ErrFp, " -o \xC4l\xE4 noudata ONCE-lauseita\n");
|
||||
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta v\xE4litt\xE4m\xE4tt\xE4\n");
|
||||
fprintf(ErrFp, " -h Suppeat tulostukset\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a \xC4l\xE4 laukaise viestej\xE4 heti - lis\xE4\xE4 ne jonoon\n");
|
||||
fprintf(ErrFp, " -q \xC4l\xE4 lis\xE4\xE4 viestej\xE4 jonoon\n");
|
||||
fprintf(ErrFp, " -f Laukaise viestit, pysy etualalla\n");
|
||||
fprintf(ErrFp, " -z[n] K\xE4ynnisty demonina, her\xE4tys n:n (5:n) minuutin v\xE4lein\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Virheenetsint\xE4: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Ohjaa virhetulostus stdout-vuohon\n");
|
||||
fprintf(ErrFp, " -b[n] Ajan ilmaisu: 0=ap/ip, 1=24 tuntia, 2=ei aikoja\n");
|
||||
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 150)\n");
|
||||
fprintf(ErrFp, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
|
||||
fprintf(ErrFp, " -g[ddd] Lajittele viestit p\xE4iv\xE4yksen, ajan ja t\xE4rkeyden mukaan\n");
|
||||
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja s\xE4ilyt\xE4 var\n");
|
||||
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eik\xE4 sunnuntaista\n");
|
||||
exit(1);
|
||||
#elif defined(IBMEXTENDED)
|
||||
fprintf(ErrFp, "K\x84ytt\x94: remind [tarkenteet] tiedosto [p\x84iv\x84ys] [aika] [*toisto]\n");
|
||||
fprintf(ErrFp, "Tarkenteet:\n");
|
||||
fprintf(ErrFp, " -n Tulosta viestien seuraavat esiintymiskerrat yksink. muodossa\n");
|
||||
fprintf(ErrFp, " -r Est\x84 RUN-lauseiden k\x84ytt\x94\n");
|
||||
fprintf(ErrFp, " -c[n] Tulosta n:n kuukauden kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -c+[n] Tulosta n:n viikon kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja v\x84lit\n");
|
||||
fprintf(ErrFp, " -s[+][n] Tulosta n:n kuukauden (viikon) 'yksink. kalenteri' (oletus 1)\n");
|
||||
fprintf(ErrFp, " -p[n] Kuten -s, mutta tulosta rem2ps:lle sopivassa muodossa\n");
|
||||
fprintf(ErrFp, " -v Laveat tulostukset\n");
|
||||
fprintf(ErrFp, " -o \x8El\x84 noudata ONCE-lauseita\n");
|
||||
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta v\x84litt\x84m\x84tt\x84\n");
|
||||
fprintf(ErrFp, " -h Suppeat tulostukset\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a \x8El\x84 laukaise viestej\x84 heti - lis\x84\x84 ne jonoon\n");
|
||||
fprintf(ErrFp, " -q \x8El\x84 lis\x84\x84 viestej\x84 jonoon\n");
|
||||
fprintf(ErrFp, " -f Laukaise viestit, pysy etualalla\n");
|
||||
fprintf(ErrFp, " -z[n] K\x84ynnisty demonina, her\x84tys n:n (5:n) minuutin v\x84lein\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Virheenetsint\x84: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Ohjaa virhetulostus stdout-vuohon\n");
|
||||
fprintf(ErrFp, " -b[n] Ajan ilmaisu: 0=ap/ip, 1=24 tuntia, 2=ei aikoja\n");
|
||||
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 150)\n");
|
||||
fprintf(ErrFp, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
|
||||
fprintf(ErrFp, " -g[ddd] Lajittele viestit p\x84iv\x84yksen, ajan ja t\x84rkeyden mukaan\n");
|
||||
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja s\x84ilyt\x84 var\n");
|
||||
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eik\x84 sunnuntaista\n");
|
||||
exit(1);
|
||||
#else
|
||||
fprintf(ErrFp, "K{ytt|: remind [tarkenteet] tiedosto [p{iv{ys] [aika] [*toisto]\n");
|
||||
fprintf(ErrFp, "Tarkenteet:\n");
|
||||
fprintf(ErrFp, " -n Tulosta viestien seuraavat esiintymiskerrat yksink. muodossa\n");
|
||||
fprintf(ErrFp, " -r Est{ RUN-lauseiden k{ytt|\n");
|
||||
fprintf(ErrFp, " -c[n] Tulosta n:n kuukauden kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -c+[n] Tulosta n:n viikon kalenteri (oletus 1)\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Aseta kalenterin leveys, tasaus ja v{lit\n");
|
||||
fprintf(ErrFp, " -s[+][n] Tulosta n:n kuukauden (viikon) 'yksink. kalenteri' (oletus 1)\n");
|
||||
fprintf(ErrFp, " -p[n] Kuten -s, mutta tulosta rem2ps:lle sopivassa muodossa\n");
|
||||
fprintf(ErrFp, " -v Laveat tulostukset\n");
|
||||
fprintf(ErrFp, " -o [l{ noudata ONCE-lauseita\n");
|
||||
fprintf(ErrFp, " -t Laukaise kaikki viestit deltan arvosta v{litt{m{tt{\n");
|
||||
fprintf(ErrFp, " -h Suppeat tulostukset\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a [l{ laukaise viestej{ heti - lis{{ ne jonoon\n");
|
||||
fprintf(ErrFp, " -q [l{ lis{{ viestej{ jonoon\n");
|
||||
fprintf(ErrFp, " -f Laukaise viestit, pysy etualalla\n");
|
||||
fprintf(ErrFp, " -z[n] K{ynnisty demonina, her{tys n:n (5:n) minuutin v{lein\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Virheenetsint{: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Ohjaa virhetulostus stdout-vuohon\n");
|
||||
fprintf(ErrFp, " -b[n] Ajan ilmaisu: 0=ap/ip, 1=24 tuntia, 2=ei aikoja\n");
|
||||
fprintf(ErrFp, " -x[n] SATISFY-lauseen toistoraja (oletus 150)\n");
|
||||
fprintf(ErrFp, " -kcmd Suorita 'cmd' MSG-tyyppisille viesteille\n");
|
||||
fprintf(ErrFp, " -g[ddd] Lajittele viestit p{iv{yksen, ajan ja t{rkeyden mukaan\n");
|
||||
fprintf(ErrFp, " -ivar=val Alusta muuttuja var arvolla val ja s{ilyt{ var\n");
|
||||
fprintf(ErrFp, " -m Aloita kalenteri maanantaista eik{ sunnuntaista\n");
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
426
french.h
Normal file
426
french.h
Normal file
@@ -0,0 +1,426 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FRENCH.H */
|
||||
/* */
|
||||
/* Support for the French language. */
|
||||
/* */
|
||||
/* Contributed by Laurent Duperval. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* */
|
||||
/* REMIND is Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* This file is Copyright (C) 1993 by Laurent Duperval and */
|
||||
/* David F. Skoll. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: french.h,v 1.1 1996-03-27 03:25:55 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "French"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "dimanche"
|
||||
#define L_MONDAY "lundi"
|
||||
#define L_TUESDAY "mardi"
|
||||
#define L_WEDNESDAY "mercredi"
|
||||
#define L_THURSDAY "jeudi"
|
||||
#define L_FRIDAY "vendredi"
|
||||
#define L_SATURDAY "samedi"
|
||||
|
||||
/* Day initials - first letter only */
|
||||
#define L_DAYINIT "dlmmjvs"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "janvier"
|
||||
#ifdef ISOLATIN1
|
||||
#define L_FEB "f\351vrier"
|
||||
#else
|
||||
#define L_FEB "fevrier"
|
||||
#endif
|
||||
#define L_MAR "mars"
|
||||
#define L_APR "avril"
|
||||
#define L_MAY "mai"
|
||||
#define L_JUN "juin"
|
||||
#define L_JUL "juillet"
|
||||
#ifdef ISOLATIN1
|
||||
#define L_AUG "ao\373t"
|
||||
#else
|
||||
#define L_AUG "aout"
|
||||
#endif
|
||||
#define L_SEP "septembre"
|
||||
#define L_OCT "octobre"
|
||||
#define L_NOV "novembre"
|
||||
#ifdef ISOLATIN1
|
||||
#define L_DEC "d\351cembre"
|
||||
#else
|
||||
#define L_DEC "decembre"
|
||||
#endif
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "aujourd'hui"
|
||||
#define L_TOMORROW "demain"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Rappels pour %w, %d%s %m, %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "il y a"
|
||||
#define L_FROMNOW "dans"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "dans %d jours"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "le"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "s"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "maintenant"
|
||||
#ifdef ISOLATIN1
|
||||
#define L_AT "\340"
|
||||
#else
|
||||
#define L_AT "a"
|
||||
#endif
|
||||
#define L_MINUTE "minute"
|
||||
#define L_HOUR "heure"
|
||||
#define L_IS "est"
|
||||
#ifdef ISOLATIN1
|
||||
#define L_WAS "\351tait"
|
||||
#else
|
||||
#define L_WAS "etait"
|
||||
#endif
|
||||
#define L_AND "et"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "s"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "s"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
|
||||
#define L_ORDINAL_OVERRIDE \
|
||||
switch(d) { \
|
||||
case 1: plu = "er"; break; \
|
||||
\
|
||||
default: plu = ""; break; \
|
||||
}
|
||||
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (tdiff < 0) { \
|
||||
if (mdiff == 0) \
|
||||
sprintf(s, "il y a %d heure%s", hdiff, hplu); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "il y a %d minute%s", mdiff, mplu); \
|
||||
else \
|
||||
sprintf(s, "il y a %d heure%s et %d minute%s", hdiff, hplu, mdiff, mplu); \
|
||||
} else { \
|
||||
if (mdiff == 0) \
|
||||
sprintf(s, "dans %d heure%s", hdiff, hplu); \
|
||||
else if (hdiff == 0) \
|
||||
sprintf(s, "dans %d minute%s", mdiff, mplu); \
|
||||
else \
|
||||
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_K_OVER \
|
||||
sprintf(s, "%s %s, %d%s %s", L_ON, DayName[jul%7], \
|
||||
d, plu, MonthName[m]);
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
#ifdef ISOLATIN1
|
||||
"Ok",
|
||||
"']' manquant",
|
||||
"Apostrophe manquant",
|
||||
"Expression trop complexe - trop d'op\351rateurs",
|
||||
"Expression trop complexe - trop d'op\351randes",
|
||||
"')' manquante",
|
||||
"Fonction non-d\351finie",
|
||||
"Caract\350re ill\351gal",
|
||||
"Op\351rateur binaire attendu",
|
||||
"Manque de m\351moire",
|
||||
"Nombre mal form\351",
|
||||
"Erreur interne - 'underflow' de la pile d'op\351rateurs",
|
||||
"Erreur interne - 'underflow' de la pile de variables",
|
||||
"Impossible de convertir",
|
||||
"Types non-\351quivalents",
|
||||
"D\351bordement de date",
|
||||
"Erreur interne - erreur de pile",
|
||||
"Division par z\351ro",
|
||||
"Variable non d\351finie",
|
||||
"Fin de ligne non attendue",
|
||||
"Fin de fichier non attendue",
|
||||
"Erreur I/O",
|
||||
"Ligne trop longue",
|
||||
"Erreur interne",
|
||||
"Mauvaise date sp\351cifi\351e",
|
||||
"Pas assez d'arguments",
|
||||
"Trop d'arguments",
|
||||
"Heure mal form\351e",
|
||||
"Nombre trop \351lev\351",
|
||||
"Nombre trop bas",
|
||||
"Impossible d'ouvrir le fichier",
|
||||
"Trop d'INCLUDE imbriqu\351s",
|
||||
"Erreur d'analyse",
|
||||
"Impossible de calculer le d\351clenchement",
|
||||
"Trop de IF imbriqu\351s",
|
||||
"ELSE sans IF correspondant",
|
||||
"ENDIF sans IF correspondant",
|
||||
"Impossible d'omettre (OMIT) tous les jours",
|
||||
"El\351ment(s) \351tranger(s) sur la ligne",
|
||||
"POP-OMIT-CONTEXT sans PUSH-OMIT-CONTEXT correspondant",
|
||||
"RUN d\351activ\351",
|
||||
"Erreur de domaine",
|
||||
"Identificateur invalide",
|
||||
"Appel r\351cursif d\351tect\351",
|
||||
"",
|
||||
"Impossible de modifier une variable syst\350me",
|
||||
"Fonction de la librairie C ne peut repr\351senter la date/l'heure",
|
||||
"Tentative de red\351finition d'une fonction intrins\350que",
|
||||
"Impossible d'imbriquer une d\351finition de fonction dans une expression",
|
||||
"Pour utiliser le facteur de r\351p\351tition la date doit \352tre sp\351cifi\351e au complet",
|
||||
"Ann\351e sp\351cifi\351e deux fois",
|
||||
"Mois sp\351cifi\351 deux fois",
|
||||
"Jour sp\351cifi\351 deux fois",
|
||||
"El\351ment inconnu",
|
||||
"Mois et jour doivent \352tre sp\351cifi\351s dans commande OMIT",
|
||||
"Trop de OMITs partiels",
|
||||
"Trop de OMITs complets",
|
||||
"Attention: PUSH-OMIT-CONTEXT sans POP-OMIT-CONTEXT correspondant",
|
||||
"Erreur \340 la lecture du fichier",
|
||||
"Fin de ligne attendue",
|
||||
"Date h\351breuse invalide",
|
||||
"IIF demande nombre d'arguments impair",
|
||||
"Attention: ENDIF manquant",
|
||||
"Virgule attendue",
|
||||
"Jour de la semaine sp\351cifi\351 deux fois",
|
||||
"Utiliser un seul parmi BEFORE, AFTER ou SKIP",
|
||||
"Impossible d'imbriquer MSG, MSF, RUN, etc. dans une expression",
|
||||
"Valeur de r\351p\351tition sp\351cifi\351e deux fois",
|
||||
"Valeur delta sp\351cifi\351e deux fois",
|
||||
"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",
|
||||
"Sp\351cification de date incompl\350te",
|
||||
"Mot-cl\351 SCANFROM utilis\351 deux fois",
|
||||
"Variable",
|
||||
"Valeur",
|
||||
"*NON-DEFINI*",
|
||||
"Entr\351e dans UserFN",
|
||||
"Sortie de UserFN",
|
||||
"Expir\351",
|
||||
"fork() \351chou\351 - impossible de faire les appels en queue",
|
||||
"Impossible d'acc\351der au fichier",
|
||||
"Date syst\350me ill\351gale: Ann\351e est inf\351rieure \340 %d\n",
|
||||
"Option de d\351verminage inconnue '%c'\n",
|
||||
"Option inconnue '%c'\n",
|
||||
"Usager inconnu '%s'\n",
|
||||
"Impossible de changer gid pour %d\n",
|
||||
"Impossible de changer uid pour %d\n",
|
||||
"Manque de m\351moire pour environnement\n",
|
||||
"Signe '=' manquant",
|
||||
"Nom de variable absent",
|
||||
"Expression absente",
|
||||
"Impossible de changer la date d'acc\350s de %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Pas de rappels.",
|
||||
"%d rappel(s) en file pour aujourd'hui.\n",
|
||||
"Nombre attendu"
|
||||
#else /* ISOLATIN1 */
|
||||
"Ok",
|
||||
"']' manquant",
|
||||
"Apostrophe manquant",
|
||||
"Expression trop complexe - trop d'operateurs",
|
||||
"Expression trop complexe - trop d'operandes",
|
||||
"')' manquante",
|
||||
"Fonction non-definie",
|
||||
"Caractere illegal",
|
||||
"Operateur binaire attendu",
|
||||
"Manque de memoire",
|
||||
"Nombre mal forme",
|
||||
"Erreur interne - 'underflow' de la pile d'operateurs",
|
||||
"Erreur interne - 'underflow' de la pile de variables",
|
||||
"Impossible de convertir",
|
||||
"Types non-equivalents",
|
||||
"Debordement de date",
|
||||
"Erreur interne - erreur de pile",
|
||||
"Division par zero",
|
||||
"Variable non definie",
|
||||
"Fin de ligne non attendue",
|
||||
"Fin de fichier non attendue",
|
||||
"Erreur I/O",
|
||||
"Ligne trop longue",
|
||||
"Erreur interne",
|
||||
"Mauvaise date specifiee",
|
||||
"Pas assez d'arguments",
|
||||
"Trop d'arguments",
|
||||
"Heure mal formee",
|
||||
"Nombre trop eleve",
|
||||
"Nombre trop bas",
|
||||
"Impossible d'ouvrir le fichier",
|
||||
"Trop d'INCLUDE imbriques",
|
||||
"erreur d'analyse",
|
||||
"Impossible de calculer le declenchement",
|
||||
"Trop de IF imbriques",
|
||||
"ELSE sans IF correspondant",
|
||||
"ENDIF sans IF correspondant",
|
||||
"Impossible d'omettre (OMIT) tous les jours",
|
||||
"Element(s) etranger(s) sur la ligne",
|
||||
"POP-OMIT-CONTEXT sans PUSH-OMIT-CONTEXT correspondant",
|
||||
"RUN desactive",
|
||||
"Erreur de domaine",
|
||||
"Identificateur invalide",
|
||||
"Appel recursif detecte",
|
||||
"",
|
||||
"Impossible de modifier une variable systeme",
|
||||
"Fonction de la librairie C ne peut representer la date/l'heure",
|
||||
"Tentative de redefinition d'une fonction intrinseque",
|
||||
"Impossible d'imbriquer une definition de fonction dans une expression",
|
||||
"Pour utiliser le facteur de repetition la date doit etre specifiee au complet",
|
||||
"Annee specifiee deux fois",
|
||||
"Mois specifie deux fois",
|
||||
"Jour specifie deux fois",
|
||||
"Element inconnu",
|
||||
"Mois et jour doivent etre specifies dans commande OMIT",
|
||||
"Trop de OMITs partiels",
|
||||
"Trop de OMITs complets",
|
||||
"Attention: PUSH-OMIT-CONTEXT sans POP-OMIT-CONTEXT correspondant",
|
||||
"Erreur a la lecture du fichier",
|
||||
"Fin de ligne attendue",
|
||||
"Date hebreuse invalide",
|
||||
"IIF demande nombre d'arguments impair",
|
||||
"Attention: ENDIF manquant",
|
||||
"Virgule attendue",
|
||||
"Jour de la semaine specifie deux fois",
|
||||
"Utiliser un seul parmi BEFORE, AFTER ou SKIP",
|
||||
"Impossible d'imbriquer MSG, MSF, RUN, etc. dans une expression",
|
||||
"Valeur de repetition specifiee deux fois",
|
||||
"Valeur delta specifiee deux fois",
|
||||
"Valeur de retour specifiee deux fois",
|
||||
"Mot-cle ONCE utilise deux fois. (Hah.)",
|
||||
"Heure attendue apres AT",
|
||||
"Mot-cle UNTIL utilise deux fois",
|
||||
"Specification de date incomplete",
|
||||
"Mot-cle SCANFROM utilise deux fois",
|
||||
"Variable",
|
||||
"Valeur",
|
||||
"*NON-DEFINI*",
|
||||
"Entree dans UserFN",
|
||||
"Sortie de UserFN",
|
||||
"Expire",
|
||||
"fork() echoue - impossible de faire les appels en queue",
|
||||
"Impossible d'acceder au fichier",
|
||||
"Date systeme illegale: Annee est inferieure a %d\n",
|
||||
"Option de deverminage inconnue '%c'\n",
|
||||
"Option inconnue '%c'\n",
|
||||
"Usager inconnu '%s'\n",
|
||||
"Impossible de changer gid pour %d\n",
|
||||
"Impossible de changer uid pour %d\n",
|
||||
"Manque de memoire pour environnement\n",
|
||||
"Signe '=' manquant",
|
||||
"Nom de variable absent",
|
||||
"Expression absente",
|
||||
"Impossible de changer la date d'acces de %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Pas de rappels.",
|
||||
"%d rappel(s) en file pour aujourd'hui.\n",
|
||||
"Nombre attendu"
|
||||
#endif /* ISOLATIN1 */
|
||||
};
|
||||
#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 */
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1996 by David F. Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
#ifdef ISOLATIN1
|
||||
fprintf(ErrFp, "\nUtilisation: remind [options] fichier [date] [heure] [*r\351p\351tition]\n");
|
||||
fprintf(ErrFp, "Options:\n");
|
||||
fprintf(ErrFp, " -n Afficher la prochaine occurence des rappels en format simple\n");
|
||||
fprintf(ErrFp, " -r D\351sactiver les instructions RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Produire un calendrier pour n (d\351faut 1) mois\n");
|
||||
fprintf(ErrFp, " -c+[n] Produire un calendrier pour n (d\351faut 1) semaines\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Sp\351cifier largeur, remplissage et espacement du calendrier\n");
|
||||
fprintf(ErrFp, " -s[+][n] Produire un 'calendrier simple' pour n (1) mois (semaines)\n");
|
||||
fprintf(ErrFp, " -p[n] Comme -s, mais avec entr\351e compatible avec rem2ps\n");
|
||||
fprintf(ErrFp, " -v Mode verbeux\n");
|
||||
fprintf(ErrFp, " -o Ignorer instructions ONCE\n");
|
||||
fprintf(ErrFp, " -t D\351clencher tous les rappels peu importe le delta\n");
|
||||
fprintf(ErrFp, " -h Mode silencieux\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a Ne pas d\351clencher les rappels minut\351s imm\351diatement - les mettre en file\n");
|
||||
fprintf(ErrFp, " -q Ne pas mettre les rappels minut\351s en file\n");
|
||||
fprintf(ErrFp, " -f D\351clencher les rappels minut\351s imm\351diatement en restant en avant-plan\n");
|
||||
fprintf(ErrFp, " -z[n] Entrer en mode 'daemon', r\351veil chaque n (5) minutes\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Envoyer les messages de stderr \340 stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Formats de l'heure pour le calendrier: 0=am/pm, 1=24hr, 2=aucun\n");
|
||||
fprintf(ErrFp, " -x[n] Limite d'it\351rations pour la clause SATISFY (def=150)\n");
|
||||
fprintf(ErrFp, " -kcmd Ex\351cuter 'cmd' pour les rappels de type MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorit\351 avant d'\351mettre\n");
|
||||
fprintf(ErrFp, " -ivar=val Initialiser var \340 val et conserver var\n");
|
||||
fprintf(ErrFp, " -m Commencer le calendrier avec lundi plut\364t que dimanche\n");
|
||||
#else /* ISOLATIN1 */
|
||||
fprintf(ErrFp, "\nUtilisation: remind [options] fichier [date] [heure] [*repetition]\n");
|
||||
fprintf(ErrFp, "Options:\n");
|
||||
fprintf(ErrFp, " -n Afficher la prochaine occurence des rappels en format simple\n");
|
||||
fprintf(ErrFp, " -r Desactiver les instructions RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Produire un calendrier pour n (defaut 1) mois\n");
|
||||
fprintf(ErrFp, " -c+[n] Produire un calendrier pour n (defaut 1) semaines\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Specifier largeur, remplissage et espacement du calendrier\n");
|
||||
fprintf(ErrFp, " -s[+][n] Produire un 'calendrier simple' pour n (1) mois (semaines)\n");
|
||||
fprintf(ErrFp, " -p[n] Comme -s, mais avec entree compatible avec rem2ps\n");
|
||||
fprintf(ErrFp, " -v Mode verbeux\n");
|
||||
fprintf(ErrFp, " -o Ignorer instructions ONCE\n");
|
||||
fprintf(ErrFp, " -t Declencher tous les rappels peu importe le delta\n");
|
||||
fprintf(ErrFp, " -h Mode silencieux\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a Ne pas declencher les rappels minutes immediatement - les mettre en file\n");
|
||||
fprintf(ErrFp, " -q Ne pas mettre les rappels minutes en file\n");
|
||||
fprintf(ErrFp, " -f Declencher les rappels minutes immediatement en restant en avant-plan\n");
|
||||
fprintf(ErrFp, " -z[n] Entrer en mode 'daemon', reveil chaque n (5) minutes\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Envoyer les messages de stderr a stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Formats de l'heure pour le calendrier: 0=am/pm, 1=24hr, 2=aucun\n");
|
||||
fprintf(ErrFp, " -x[n] Limite d'iterations pour la clause SATISFY (def=150)\n");
|
||||
fprintf(ErrFp, " -kcmd Executer 'cmd' pour les rappels de type MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Trier les rappels par date, heure et priorite avant d'emettre\n");
|
||||
fprintf(ErrFp, " -ivar=val Initialiser var a val et conserver var\n");
|
||||
fprintf(ErrFp, " -m Commencer le calendrier avec lundi plutot que dimanche\n");
|
||||
#endif /* ISOLATIN1 */
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
105
german.h
Normal file
105
german.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GERMAN.H */
|
||||
/* */
|
||||
/* Support for the German language. */
|
||||
/* */
|
||||
/* This file was derived from a patch submitted by Wolfgang */
|
||||
/* Thronicke. I don't guarantee that there are no mistakes - */
|
||||
/* I don't speak German. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: german.h,v 1.1 1996-03-27 03:25:56 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "German"
|
||||
|
||||
/* Day names */
|
||||
#define L_SUNDAY "Sonntag"
|
||||
#define L_MONDAY "Montag"
|
||||
#define L_TUESDAY "Dienstag"
|
||||
#define L_WEDNESDAY "Mittwoch"
|
||||
#define L_THURSDAY "Donnerstag"
|
||||
#define L_FRIDAY "Freitag"
|
||||
#define L_SATURDAY "Samstag"
|
||||
|
||||
/* Day initials - first letter only */
|
||||
#define L_DAYINIT "SMDMDFS"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
#define L_FEB "Februar"
|
||||
#ifdef ISOLATIN1
|
||||
# define L_MAR "M\344rz"
|
||||
#else
|
||||
# define L_MAR "Maerz"
|
||||
#endif
|
||||
#define L_APR "April"
|
||||
#define L_MAY "Mai"
|
||||
#define L_JUN "Juni"
|
||||
#define L_JUL "Juli"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "Oktober"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "Dezember"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "heute"
|
||||
#define L_TOMORROW "morgen"
|
||||
|
||||
/* The default banner */
|
||||
#ifdef ISOLATIN1
|
||||
# define L_BANNER "Termine f\374r %w, den %d. %m %y%o:"
|
||||
#else
|
||||
# define L_BANNER "Termine fuer %w, den %d. %m %y%o:"
|
||||
#endif
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "vorher"
|
||||
#define L_FROMNOW "von heute"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "in %d Tagen"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "am"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "en"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "jetzt"
|
||||
#define L_AT "um"
|
||||
#define L_MINUTE "Minute"
|
||||
#define L_HOUR "Stunde"
|
||||
#define L_IS "ist"
|
||||
#define L_WAS "war"
|
||||
#define L_AND "und"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "n"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "n"
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
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_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
22
globals.c
Normal file
22
globals.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GLOBALS.C */
|
||||
/* */
|
||||
/* This file simply instantiates all of the global variables. */
|
||||
/* */
|
||||
/* It does this by #defining MK_GLOBALS and #including */
|
||||
/* globals.h and err.h */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: globals.c,v 1.1 1996-03-27 03:25:57 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h> /* For defintion of FILE - sigh! */
|
||||
#include "types.h"
|
||||
#define MK_GLOBALS
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
182
globals.h
Normal file
182
globals.h
Normal file
@@ -0,0 +1,182 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GLOBALS.H */
|
||||
/* */
|
||||
/* This function contains declarations of global variables. */
|
||||
/* They are instantiated in main.c by defining */
|
||||
/* MK_GLOBALS. Also contains useful macro definitions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: globals.h,v 1.1 1996-03-27 03:25:57 dfs Exp $ */
|
||||
|
||||
#ifdef MK_GLOBALS
|
||||
#undef EXTERN
|
||||
#define EXTERN
|
||||
#define INIT(var, val) var = val
|
||||
#else
|
||||
#undef EXTERN
|
||||
#define EXTERN extern
|
||||
#define INIT(var, val) var
|
||||
#endif
|
||||
|
||||
#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))
|
||||
|
||||
#define DestroyValue(x) (void) (((x).type == STR_TYPE && (x).v.str) ? (free((x).v.str),(x).type = ERR_TYPE) : 0)
|
||||
|
||||
EXTERN int JulianToday;
|
||||
EXTERN int RealToday;
|
||||
EXTERN int CurDay;
|
||||
EXTERN int CurMon;
|
||||
EXTERN int CurYear;
|
||||
EXTERN int LineNo;
|
||||
EXTERN int FreshLine;
|
||||
EXTERN char LineBuffer[LINELEN];
|
||||
EXTERN char SubstBuffer[LINELEN];
|
||||
EXTERN char TokBuffer[TOKSIZE+1];
|
||||
EXTERN INIT( char *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 MondayFirst, 0);
|
||||
EXTERN INIT( int Iterations, 1);
|
||||
EXTERN INIT( int PsCal, 0);
|
||||
EXTERN INIT( int CalWidth, 80);
|
||||
EXTERN INIT( int CalWeeks, 0);
|
||||
EXTERN INIT( int CalMonths, 0);
|
||||
EXTERN INIT( int Hush, 0);
|
||||
EXTERN INIT( int NextMode, 0);
|
||||
EXTERN INIT( int InfiniteDelta, 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 DefaultPrio, NO_PRIORITY);
|
||||
EXTERN INIT( long SysTime, -1L);
|
||||
|
||||
EXTERN char *InitialFile;
|
||||
EXTERN int FileAccessDate;
|
||||
|
||||
EXTERN INIT( int DontFork, 0);
|
||||
EXTERN INIT( int DontQueue, 0);
|
||||
EXTERN INIT( int NumQueued, 0);
|
||||
EXTERN INIT( int DontIssueAts, 0);
|
||||
EXTERN INIT( int Daemon, 0);
|
||||
|
||||
|
||||
EXTERN INIT( int ScFormat, SC_AMPM);
|
||||
EXTERN INIT( int MaxSatIter, 150);
|
||||
EXTERN INIT( char *FileName, NULL);
|
||||
EXTERN INIT( int UseStdin, 0);
|
||||
EXTERN FILE *ErrFp;
|
||||
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 INIT( int NumTriggered, 0);
|
||||
EXTERN int ArgC;
|
||||
EXTERN char **ArgV;
|
||||
EXTERN INIT( int CalLines, CAL_LINES);
|
||||
EXTERN INIT( int CalPad, 1);
|
||||
|
||||
/* Latitude and longitude */
|
||||
EXTERN INIT( int LatDeg, LAT_DEG);
|
||||
EXTERN INIT( int LatMin, LAT_MIN);
|
||||
EXTERN INIT( int LatSec, LAT_SEC);
|
||||
EXTERN INIT( int LongDeg, LON_DEG);
|
||||
EXTERN INIT( int LongMin, LON_MIN);
|
||||
EXTERN INIT( int LongSec, LON_SEC);
|
||||
EXTERN INIT( char *Location, LOCATION);
|
||||
|
||||
/* UTC calculation stuff */
|
||||
EXTERN INIT( int MinsFromUTC, 0);
|
||||
EXTERN INIT( int CalculateUTC, 1);
|
||||
EXTERN INIT( int FoldYear, 0);
|
||||
|
||||
/* Parameters for formatting MSGF reminders */
|
||||
EXTERN INIT( int FormWidth, 72);
|
||||
EXTERN INIT( int FirstIndent, 0);
|
||||
EXTERN INIT( int SubsIndent, 0);
|
||||
EXTERN INIT( char *EndSent, ".?!");
|
||||
EXTERN INIT( char *EndSentIg, "\"')]}>");
|
||||
|
||||
/* We need the language stuff here... */
|
||||
|
||||
#include "lang.h"
|
||||
|
||||
EXTERN INIT( char Banner[LINELEN], L_BANNER);
|
||||
|
||||
/* List of months */
|
||||
EXTERN char *EnglishMonthName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"}
|
||||
#endif
|
||||
;
|
||||
|
||||
#if LANG == ENGLISH
|
||||
#define MonthName EnglishMonthName
|
||||
#else
|
||||
EXTERN char *MonthName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {L_JAN, L_FEB, L_MAR, L_APR, L_MAY, L_JUN,
|
||||
L_JUL, L_AUG, L_SEP, L_OCT, L_NOV, L_DEC}
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
|
||||
EXTERN char *EnglishDayName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
|
||||
"Saturday", "Sunday"}
|
||||
#endif
|
||||
;
|
||||
|
||||
#if LANG == ENGLISH
|
||||
#define DayName EnglishDayName
|
||||
#else
|
||||
EXTERN char *DayName[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {L_MONDAY, L_TUESDAY, L_WEDNESDAY, L_THURSDAY, L_FRIDAY,
|
||||
L_SATURDAY, L_SUNDAY}
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
|
||||
EXTERN int MonthDays[]
|
||||
#ifdef MK_GLOBALS
|
||||
= {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
||||
#endif
|
||||
;
|
||||
|
||||
/* The first day of each month expressed as number of days after Jan 1.
|
||||
Second row is for leap years. */
|
||||
|
||||
EXTERN int MonthIndex[2][12]
|
||||
#ifdef MK_GLOBALS
|
||||
= {
|
||||
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
|
||||
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
||||
#if defined(__OS2__)
|
||||
#if defined(_MSC_VER) || defined(__EMX__)
|
||||
#define OS2MODE (_osmode == OS2_MODE)
|
||||
#define DOSMODE (_osmode == DOS_MODE)
|
||||
#else
|
||||
#define OS2MODE 1
|
||||
#define DOSMODE 0
|
||||
#endif
|
||||
#endif
|
||||
544
hbcal.c
Normal file
544
hbcal.c
Normal file
@@ -0,0 +1,544 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HBCAL.C */
|
||||
/* */
|
||||
/* Support for the Hebrew calendar */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/* Derived from code written by Amos Shapir in 1978; revised */
|
||||
/* 1985. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: hbcal.c,v 1.1 1996-03-27 03:25:58 dfs Exp $";
|
||||
|
||||
#include <stdio.h> /* For FILE used by protos.h - sigh. */
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
#define HOUR 1080L
|
||||
#define DAY (24L*HOUR)
|
||||
#define WEEK (7L*DAY)
|
||||
#define M(h,p) ((long)(h*HOUR+p))
|
||||
#define MONTH (DAY+M(12,793))
|
||||
|
||||
/* Correction to convert base reference to 1990. NOTE: If you change
|
||||
the value of BASE in config.h, this will NOT WORK! You'll have to
|
||||
add the appropriate number of days to CORRECTION. */
|
||||
|
||||
#define CORRECTION 732774L
|
||||
|
||||
#define TISHREY 0
|
||||
#define HESHVAN 1
|
||||
#define KISLEV 2
|
||||
#define TEVET 3
|
||||
#define SHVAT 4
|
||||
#define ADARA 5
|
||||
#define ADARB 6
|
||||
#define NISAN 7
|
||||
#define IYAR 8
|
||||
#define SIVAN 9
|
||||
#define TAMUZ 10
|
||||
#define AV 11
|
||||
#define ELUL 12
|
||||
#define ADAR 13
|
||||
|
||||
#define JAHR_NONE 0
|
||||
#define JAHR_FORWARD 1
|
||||
#define JAHR_BACKWARD 2
|
||||
|
||||
#define ADAR2ADARB 0
|
||||
#define ADAR2ADARA 1
|
||||
#define ADAR2BOTH 2
|
||||
|
||||
static char *HebMonthNames[] = {
|
||||
"Tishrey", "Heshvan", "Kislev", "Tevet", "Shvat", "Adar A", "Adar B",
|
||||
"Nisan", "Iyar", "Sivan", "Tamuz", "Av", "Elul", "Adar"};
|
||||
|
||||
static char MaxMonLen[] = {
|
||||
30, 30, 30, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29, 29};
|
||||
|
||||
static char HebIsLeap[] = {0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1};
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* RoshHashana */
|
||||
/* */
|
||||
/* Return the Julian date for Rosh Hashana of specified */
|
||||
/* Hebrew year. (ie, 5751, not 1990) */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int RoshHashana(int i)
|
||||
#else
|
||||
int RoshHashana(i)
|
||||
int i;
|
||||
#endif
|
||||
{
|
||||
long j;
|
||||
j = DaysToHebYear(i-3744) - CORRECTION;
|
||||
return (int) j; /* No overflow check... very trusting! */
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DaysToHebYear */
|
||||
/* */
|
||||
/* Return the number of days to RH of specified Hebrew year */
|
||||
/* from new moon before Tishrey 1 5701. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC long DaysToHebYear(int y)
|
||||
#else
|
||||
long DaysToHebYear(y)
|
||||
int y;
|
||||
#endif
|
||||
{
|
||||
long m, nm, dw, s, l;
|
||||
|
||||
l = y*7+1; /* no. of leap months */
|
||||
m = y*12+l/19; /* total no. of months */
|
||||
nm = m*MONTH+M(1,779); /* molad at 197 cycles */
|
||||
s = m*28+nm/DAY-2;
|
||||
|
||||
nm %= WEEK;
|
||||
l %= 19L;
|
||||
dw = nm/DAY;
|
||||
nm %= DAY;
|
||||
|
||||
/* special cases of Molad Zaken */
|
||||
if (nm >= 18*HOUR ||
|
||||
(l < 12 && dw==3 && nm>=M(9,204)) ||
|
||||
(l < 7 && dw==2 && nm>=M(15,589)))
|
||||
s++,dw++;
|
||||
/* ADU */
|
||||
if(dw == 1 || dw == 4 || dw == 6)
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DaysInHebYear */
|
||||
/* */
|
||||
/* Return the number of days in the Hebrew year. */
|
||||
/* */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DaysInHebYear(int y)
|
||||
#else
|
||||
int DaysInHebYear(y)
|
||||
int y;
|
||||
#endif
|
||||
{
|
||||
long thisyear, nextyear;
|
||||
|
||||
thisyear = DaysToHebYear(y-3744);
|
||||
nextyear = DaysToHebYear(y-3743);
|
||||
return (int) (nextyear - thisyear);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DaysInHebMonths */
|
||||
/* */
|
||||
/* Return a pointer to an array giving lengths of months */
|
||||
/* given the LENGTH of the Hebrew year. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC char *DaysInHebMonths(int ylen)
|
||||
#else
|
||||
char *DaysInHebMonths(ylen)
|
||||
int ylen;
|
||||
#endif
|
||||
{
|
||||
static char monlen[13] =
|
||||
{30, 29, 30, 29, 30, 0, 29, 30, 29, 30, 29, 30, 29};
|
||||
|
||||
|
||||
if (ylen > 355) {
|
||||
monlen[ADARA] = 30;
|
||||
ylen -= 30;
|
||||
} else monlen[ADARA] = 0;
|
||||
|
||||
if (ylen == 353) monlen[KISLEV] = 29; else monlen[KISLEV] = 30;
|
||||
if (ylen == 355) monlen[HESHVAN] = 30; else monlen[HESHVAN] = 29;
|
||||
|
||||
return monlen;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HebToJul */
|
||||
/* */
|
||||
/* Convert a Hebrew date to Julian. */
|
||||
/* Hebrew months range from 0-12, but Adar A has 0 length in */
|
||||
/* non-leap-years. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int HebToJul(int hy, int hm, int hd)
|
||||
#else
|
||||
int HebToJul(hy, hm, hd)
|
||||
int hy, hm, hd;
|
||||
#endif
|
||||
{
|
||||
int ylen;
|
||||
char *monlens;
|
||||
int rh;
|
||||
int m;
|
||||
|
||||
/* Do some range checking */
|
||||
if (hy - 3761 < BASE || hy - 3760 > BASE+YR_RANGE) return -1;
|
||||
|
||||
ylen = DaysInHebYear(hy);
|
||||
monlens = DaysInHebMonths(ylen);
|
||||
|
||||
/* Get the Rosh Hashana of the year */
|
||||
rh = RoshHashana(hy);
|
||||
|
||||
/* Bump up to the appropriate month */
|
||||
for (m=0; m<hm; m++) rh += monlens[m];
|
||||
|
||||
/* Add in appropriate number of days */
|
||||
rh += hd - 1;
|
||||
return rh;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* JulToHeb */
|
||||
/* */
|
||||
/* Convert a Julian date to Hebrew. */
|
||||
/* Hebrew months range from 0-12, but Adar A has 0 length in */
|
||||
/* non-leap-years. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void JulToHeb(int jul, int *hy, int *hm, int *hd)
|
||||
#else
|
||||
void JulToHeb(jul, hy, hm, hd)
|
||||
int jul, *hy, *hm, *hd;
|
||||
#endif
|
||||
{
|
||||
int y, m, d;
|
||||
int rh;
|
||||
int ylen;
|
||||
char *monlen;
|
||||
/* Get the common year */
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
y += 3763; /* Over-estimate a bit to be on the safe side below... */
|
||||
|
||||
/* Find the RH just before desired date */
|
||||
while ((rh=RoshHashana(y))>jul) y--;
|
||||
|
||||
/* Got the year - now find the month */
|
||||
jul -= rh;
|
||||
ylen = DaysInHebYear(y);
|
||||
monlen = DaysInHebMonths(ylen);
|
||||
m = 0;
|
||||
while((jul >= monlen[m]) || !monlen[m]) {
|
||||
jul -= monlen[m];
|
||||
m++;
|
||||
}
|
||||
|
||||
*hy = y;
|
||||
*hm = m;
|
||||
*hd = jul+1;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HebNameToNum */
|
||||
/* */
|
||||
/* Convert a Hebrew month's name to its number, given the */
|
||||
/* year. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int HebNameToNum(const char *mname)
|
||||
#else
|
||||
int HebNameToNum(mname)
|
||||
char *mname;
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
int m=-1;
|
||||
|
||||
for (i=0; i<14; i++)
|
||||
if (!StrCmpi(mname, HebMonthNames[i])) {
|
||||
m = i;
|
||||
break;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HebMonthname */
|
||||
/* */
|
||||
/* Convert a Hebrew month's number to its name, given the */
|
||||
/* year. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC char *HebMonthName(int m, int y)
|
||||
#else
|
||||
char *HebMonthName(m, y)
|
||||
int m, y;
|
||||
#endif
|
||||
{
|
||||
if (m != ADARA && m != ADARB) return HebMonthNames[m];
|
||||
|
||||
if (!HebIsLeap[(y-1)%19]) return HebMonthNames[ADAR];
|
||||
else return HebMonthNames[m];
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetValidHebDate */
|
||||
/* */
|
||||
/* Given the day of a month, a Hebrew month number, and a */
|
||||
/* year, return a valid year number, month number, and day */
|
||||
/* number. Returns 0 for success, non-0 for failure. */
|
||||
/* If *dout is set to -1, then date is completely invalid. */
|
||||
/* Otherwise, date is only invalid in specified year. */
|
||||
/* */
|
||||
/* Algorithm: */
|
||||
/* - Convert references to Adar to Adar B. */
|
||||
/* If jahr == 0 then */
|
||||
/* - If no such date in current Hebrew year, return */
|
||||
/* failure. */
|
||||
/* else follow jahrzeit rules: */
|
||||
/* - If jahr == 1: Convert 30 Kislev to 1 Tevet and */
|
||||
/* 30 Heshvan to 1 Kislev if chaser. */
|
||||
/* Convert 30 Adar A to 1 Nisan in nonleap */
|
||||
/* This rule is NOT appropriate for a */
|
||||
/* jahrzeit on 30 Adar A. Use rule 2 for */
|
||||
/* that. However, I believe it is correct */
|
||||
/* for smachot. */
|
||||
/* - If jahr == 2: Convert 30 Kislev to 29 Kislev and */
|
||||
/* 30 Heshvan to 29 Heshvan if chaser. */
|
||||
/* Change 30 Adar A to 30 Shvat in nonleap */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int GetValidHebDate(int yin, int min, int din, int adarbehave,
|
||||
int *mout, int *dout, int jahr)
|
||||
#else
|
||||
int GetValidHebDate(yin, min, din, adarbehave, mout, dout, jahr)
|
||||
int yin, min, din, adarbehave, *mout, *dout, jahr;
|
||||
#endif
|
||||
{
|
||||
char *monlen;
|
||||
int ylen;
|
||||
|
||||
*mout = min;
|
||||
*dout = din;
|
||||
|
||||
/* Do some error checking */
|
||||
if (din < 1 || din > MaxMonLen[min] || min < 0 || min > 13) {
|
||||
*dout = -1;
|
||||
return E_BAD_HEBDATE;
|
||||
}
|
||||
|
||||
ylen = DaysInHebYear(yin);
|
||||
monlen = DaysInHebMonths(ylen);
|
||||
|
||||
/* Convert ADAR as necessary */
|
||||
if (min == ADAR) {
|
||||
switch(adarbehave) {
|
||||
case ADAR2ADARA: if (monlen[ADARA]) *mout = min = ADARA;
|
||||
else *mout = min = ADARB;
|
||||
break;
|
||||
|
||||
case ADAR2ADARB: *mout = min = ADARB; break;
|
||||
|
||||
default:
|
||||
Eprint("GetValidHebDate: Bad adarbehave value %d", adarbehave);
|
||||
return E_SWERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (din <= monlen[min]) return OK;
|
||||
|
||||
switch(jahr) {
|
||||
case JAHR_NONE: return E_BAD_DATE;
|
||||
|
||||
case JAHR_FORWARD:
|
||||
if (min == KISLEV) {
|
||||
*mout = TEVET;
|
||||
*dout = 1;
|
||||
return OK;
|
||||
} else if (min == HESHVAN) {
|
||||
*mout = KISLEV;
|
||||
*dout = 1;
|
||||
return OK;
|
||||
} else if (min == ADARA) {
|
||||
if (din > 29) {
|
||||
*dout = 1;
|
||||
*mout = NISAN;
|
||||
} else {
|
||||
*dout = din;
|
||||
*mout = ADARB;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
Eprint("GetValidHebDate: (1) software error! %d", jahr);
|
||||
return E_SWERR;
|
||||
|
||||
case JAHR_BACKWARD:
|
||||
if (min == KISLEV) {
|
||||
*mout = KISLEV;
|
||||
*dout = 29;
|
||||
return OK;
|
||||
} else if (min == HESHVAN) {
|
||||
*mout = HESHVAN;
|
||||
*dout = 29;
|
||||
return OK;
|
||||
} else if (min == ADARA) {
|
||||
if (din > 29) {
|
||||
*dout = 30;
|
||||
*mout = SHVAT;
|
||||
} else {
|
||||
*mout = ADARB;
|
||||
*dout = din;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
Eprint("GetValidHebDate: (2) software error! %d", jahr);
|
||||
return E_SWERR;
|
||||
|
||||
default:
|
||||
Eprint("GetValidHebDate: (3) software error! %d", jahr);
|
||||
return E_SWERR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetNextHebrewDate */
|
||||
/* */
|
||||
/* Get the next Hebrew date on or after specified date. */
|
||||
/* */
|
||||
/* Returns 0 for success, non-zero for failure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int GetNextHebrewDate(int julstart, int hm, int hd,
|
||||
int jahr, int adarbehave, int *ans)
|
||||
#else
|
||||
int GetNextHebrewDate(julstart, hm, hd, jahr, adarbehave, ans)
|
||||
int julstart, hm, hd, jahr, adarbehave, *ans;
|
||||
#endif
|
||||
{
|
||||
int r, yout, mout, dout, jul=1;
|
||||
int adarflag = adarbehave;
|
||||
|
||||
/* I initialize jul above to stop gcc from complaining about
|
||||
possible use of uninitialized variable. You can take it
|
||||
out if the small inefficiency really bothers you. */
|
||||
|
||||
/* If adarbehave == ADAR2BOTH, set adarflag to ADAR2ADARA for now */
|
||||
if (adarbehave == ADAR2BOTH) adarflag = ADAR2ADARA;
|
||||
|
||||
JulToHeb(julstart, &yout, &mout, &dout);
|
||||
|
||||
r = 1;
|
||||
while(r) {
|
||||
r = GetValidHebDate(yout, hm, hd, adarflag, &mout, &dout, jahr);
|
||||
if (dout == -1) return r;
|
||||
if (r) {
|
||||
if (adarbehave == ADAR2BOTH && hm == ADAR) {
|
||||
if (adarflag == ADAR2ADARA) {
|
||||
adarflag = ADAR2ADARB;
|
||||
} else {
|
||||
adarflag = ADAR2ADARA;
|
||||
yout++;
|
||||
}
|
||||
} else yout++;
|
||||
continue;
|
||||
}
|
||||
jul = HebToJul(yout, mout, dout);
|
||||
if (jul < 0) return E_DATE_OVER;
|
||||
if (jul >= julstart) break;
|
||||
else {
|
||||
if (adarbehave == ADAR2BOTH && hm == ADAR) {
|
||||
if (adarflag == ADAR2ADARA) {
|
||||
adarflag = ADAR2ADARB;
|
||||
} else {
|
||||
adarflag = ADAR2ADARA;
|
||||
yout++;
|
||||
}
|
||||
} else yout++;
|
||||
r=1; /* Force loop to continue */
|
||||
}
|
||||
}
|
||||
*ans = jul;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ComputeJahr */
|
||||
/* */
|
||||
/* Given a date of death, compute the value to use for jahr. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int ComputeJahr(int y, int m, int d, int *ans)
|
||||
#else
|
||||
int ComputeJahr(y, m, d, ans)
|
||||
int y, m, d, *ans;
|
||||
#endif
|
||||
{
|
||||
char *monlen;
|
||||
int len;
|
||||
|
||||
*ans = JAHR_NONE;
|
||||
|
||||
len = DaysInHebYear(y);
|
||||
monlen = DaysInHebMonths(len);
|
||||
|
||||
/* Check for Adar A */
|
||||
if (m == ADARA && monlen[m] == 0) {
|
||||
Eprint("No Adar A in %d", y);
|
||||
return E_BAD_HEBDATE;
|
||||
}
|
||||
|
||||
|
||||
if (d < 1 || d > MaxMonLen[m] || m < 0 || m > 13) {
|
||||
return E_BAD_HEBDATE;
|
||||
}
|
||||
|
||||
if (d > monlen[m]) {
|
||||
Eprint("%d %s %d: %s", d, HebMonthNames[m], y, ErrMsg[E_BAD_HEBDATE]);
|
||||
return E_BAD_HEBDATE;
|
||||
}
|
||||
|
||||
/* If the jahrzeit was in Adar A, we always use JAHR_BACKWARD */
|
||||
if (m == ADARA) {
|
||||
*ans = JAHR_BACKWARD;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Get lengths of months in year following jahrzeit */
|
||||
len = DaysInHebYear(y+1);
|
||||
monlen = DaysInHebMonths(len);
|
||||
|
||||
if (d > monlen[m]) *ans = JAHR_FORWARD;
|
||||
else *ans = JAHR_BACKWARD;
|
||||
|
||||
return OK;
|
||||
}
|
||||
633
init.c
Normal file
633
init.c
Normal file
@@ -0,0 +1,633 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* INIT.C */
|
||||
/* */
|
||||
/* Initialize remind; perform certain tasks between */
|
||||
/* iterations in calendar mode; do certain checks after end */
|
||||
/* in normal mode. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: init.c,v 1.1 1996-03-27 03:25:58 dfs Exp $";
|
||||
|
||||
#define L_IN_INIT 1
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#ifdef UNIX
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#ifdef HAVE_UNISTD
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
#include "err.h"
|
||||
#include "version.h"
|
||||
#include "globals.h"
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* Command line options recognized:
|
||||
*
|
||||
* -n = Output next trigger date of each reminder in
|
||||
* simple calendar format.
|
||||
* -r = Disallow RUN mode
|
||||
* -c[n] = Produce a calendar for n months (default = 1)
|
||||
* -w[n,n,n] = Specify output device width, padding and spacing
|
||||
* -s[n] = Produce calendar in "simple calendar" format
|
||||
* -p[n] = Produce calendar in format compatible with rem2ps
|
||||
* -v = Verbose mode
|
||||
* -o = Ignore ONCE directives
|
||||
* -a = Don't issue timed reminders which will be queued
|
||||
* -q = Don't queue timed reminders
|
||||
* -t = Trigger all reminders (infinite delta)
|
||||
* -h = Hush mode
|
||||
* -f = Do not fork
|
||||
* -dchars = Debugging mode: Chars are:
|
||||
* e = Echo input lines
|
||||
* x = Display expression evaluation
|
||||
* t = Display trigger dates
|
||||
* v = Dump variables at end
|
||||
* l = Display entire line in error messages
|
||||
* -e = Send messages normally sent to stderr to stdout instead
|
||||
* -z[n] = Daemon mode waking up every n (def 5) minutes.
|
||||
* -bn = Time format for cal (0, 1, or 2)
|
||||
* -xn = Max. number of iterations for SATISFY
|
||||
* -uname = Run as user 'name' - only valid when run by root. If run
|
||||
* by non-root, changes environment but not effective uid.
|
||||
* -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.
|
||||
* A minus sign alone indicates to take input from stdin
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
/* For parsing an integer */
|
||||
#define PARSENUM(var, s) \
|
||||
var = 0; \
|
||||
while (isdigit(*(s))) { \
|
||||
var *= 10; \
|
||||
var += *(s) - '0'; \
|
||||
s++; \
|
||||
}
|
||||
|
||||
#ifdef UNIX
|
||||
PRIVATE void ChgUser ARGS((char *uname));
|
||||
#endif
|
||||
|
||||
PRIVATE void InitializeVar ARGS ((char *str));
|
||||
|
||||
static char *BadDate = "Illegal date on command line\n";
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* InitRemind */
|
||||
/* */
|
||||
/* Initialize the system - called only once at beginning! */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void InitRemind(int argc, char *argv[])
|
||||
#else
|
||||
void InitRemind(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
#endif
|
||||
{
|
||||
char *arg;
|
||||
int i;
|
||||
int y, m, d, rep;
|
||||
Token tok;
|
||||
|
||||
y = NO_YR;
|
||||
m = NO_MON;
|
||||
d = NO_DAY;
|
||||
rep = NO_REP;
|
||||
|
||||
RealToday = SystemDate(&CurYear, &CurMon, &CurDay);
|
||||
if (RealToday < 0) {
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_SYS_DATE], BASE);
|
||||
exit(1);
|
||||
}
|
||||
JulianToday = RealToday;
|
||||
FromJulian(JulianToday, &CurYear, &CurMon, &CurDay);
|
||||
|
||||
#if !defined(HAVE_QUEUED)
|
||||
DontFork = 1;
|
||||
DontQueue = 1;
|
||||
NumQueued = 0;
|
||||
DontIssueAts = 0;
|
||||
Daemon = 0;
|
||||
#elif defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
DontFork = 1;
|
||||
#elif defined(__OS2__) && defined (__MSDOS__)
|
||||
if (DOSMODE)
|
||||
DontFork = 1;
|
||||
#endif
|
||||
|
||||
/* Parse the command-line options */
|
||||
i = 1;
|
||||
while (i < argc) {
|
||||
arg = argv[i];
|
||||
if (*arg != '-') break; /* Exit the loop if it's not an option */
|
||||
i++;
|
||||
arg++;
|
||||
if (!*arg) {
|
||||
UseStdin = 1;
|
||||
IgnoreOnce = 1;
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
while (*arg) {
|
||||
switch(*arg++) {
|
||||
|
||||
case 'i':
|
||||
case 'I':
|
||||
InitializeVar(arg);
|
||||
while(*arg) arg++;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
case 'N':
|
||||
NextMode = 1;
|
||||
#ifdef HAVE_QUEUED
|
||||
DontQueue = 1;
|
||||
Daemon = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
case 'R':
|
||||
RunDisabled = 1;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
MondayFirst = 1;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
case 'O':
|
||||
IgnoreOnce = 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
InfiniteDelta = 1;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
ErrFp = stdout;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case 'H':
|
||||
Hush = 1;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
case 'G':
|
||||
SortByDate = SORT_ASCEND;
|
||||
SortByTime = SORT_ASCEND;
|
||||
SortByPrio = SORT_ASCEND;
|
||||
if (*arg) {
|
||||
if (*arg == 'D' || *arg == 'd')
|
||||
SortByDate = SORT_DESCEND;
|
||||
arg++;
|
||||
}
|
||||
if (*arg) {
|
||||
if (*arg == 'D' || *arg == 'd')
|
||||
SortByTime = SORT_DESCEND;
|
||||
arg++;
|
||||
}
|
||||
if (*arg) {
|
||||
if (*arg == 'D' || *arg == 'd')
|
||||
SortByPrio = SORT_DESCEND;
|
||||
arg++;
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(UNIX) && defined(WANT_U_OPTION)
|
||||
case 'u':
|
||||
case 'U':
|
||||
ChgUser(arg);
|
||||
while (*arg) arg++;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_QUEUED
|
||||
case 'z':
|
||||
case 'Z':
|
||||
DontFork = 1;
|
||||
PARSENUM(Daemon, arg);
|
||||
if (Daemon<5) Daemon=5;
|
||||
else if (Daemon>60) Daemon=60;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
DontIssueAts = 1;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
case 'Q':
|
||||
DontQueue = 1;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
DontFork = 1;
|
||||
break;
|
||||
#endif
|
||||
case 'c':
|
||||
case 'C':
|
||||
DoCalendar = 1;
|
||||
if (*arg == '+') {
|
||||
arg++;
|
||||
PARSENUM(CalWeeks, arg);
|
||||
if (!CalWeeks) CalWeeks = 1;
|
||||
} else {
|
||||
PARSENUM(CalMonths, arg);
|
||||
if (!CalMonths) CalMonths = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'S':
|
||||
DoSimpleCalendar = 1;
|
||||
if (*arg == '+') {
|
||||
arg++;
|
||||
PARSENUM(CalWeeks, arg);
|
||||
if (!CalWeeks) CalWeeks = 1;
|
||||
} else {
|
||||
PARSENUM(CalMonths, arg);
|
||||
if (!CalMonths) CalMonths = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
case 'P':
|
||||
DoSimpleCalendar = 1;
|
||||
PsCal = 1;
|
||||
PARSENUM(CalMonths, arg);
|
||||
if (!CalMonths) CalMonths = 1;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
case 'W':
|
||||
if (*arg != ',') {
|
||||
PARSENUM(CalWidth, arg);
|
||||
if (CalWidth < 80) CalWidth = 80;
|
||||
}
|
||||
if (*arg == ',') {
|
||||
arg++;
|
||||
if (*arg != ',') {
|
||||
PARSENUM(CalLines, arg);
|
||||
if (CalLines > 20) CalLines = 20;
|
||||
}
|
||||
if (*arg == ',') {
|
||||
arg++;
|
||||
PARSENUM(CalPad, arg);
|
||||
if (CalPad > 20) CalPad = 20;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
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;
|
||||
default:
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_DB_FLAG], *(arg-1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
DebugFlag |= DB_PRTLINE;
|
||||
ShowAllErrors = 1;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
case 'B':
|
||||
PARSENUM(ScFormat, arg);
|
||||
if (ScFormat<0 || ScFormat>2) ScFormat=SC_AMPM;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
case 'X':
|
||||
PARSENUM(MaxSatIter, arg);
|
||||
if (MaxSatIter < 10) MaxSatIter=10;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
MsgCommand = arg;
|
||||
while (*arg) arg++; /* Chew up remaining chars in this arg */
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_OPTION], *(arg-1));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the filename. */
|
||||
if (i >= argc) {
|
||||
Usage();
|
||||
exit(1);
|
||||
}
|
||||
InitialFile = argv[i++];
|
||||
|
||||
/* Get the date, if any */
|
||||
if (i < argc) {
|
||||
while (i < argc) {
|
||||
arg = argv[i++];
|
||||
FindToken(arg, &tok);
|
||||
switch (tok.type) {
|
||||
case T_Time:
|
||||
if (SysTime != -1L) Usage();
|
||||
else {
|
||||
SysTime = (long) tok.val * 60L;
|
||||
#ifdef HAVE_QUEUED
|
||||
DontQueue = 1;
|
||||
Daemon = 0;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
if (m != NO_MON) Usage();
|
||||
else m = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
if (d != NO_DAY) Usage();
|
||||
else d = tok.val;
|
||||
break;
|
||||
|
||||
case T_Year:
|
||||
if (y != NO_YR) Usage();
|
||||
else y = tok.val;
|
||||
break;
|
||||
|
||||
case T_Rep:
|
||||
if (rep != NO_REP) Usage();
|
||||
else rep = tok.val;
|
||||
break;
|
||||
|
||||
default: Usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (rep > 0) {
|
||||
Iterations = rep;
|
||||
DontQueue = 1;
|
||||
Daemon = 0;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
if (rep == NO_REP) Usage();
|
||||
else if (m != NO_MON || y != NO_YR) Usage();
|
||||
else {
|
||||
m = CurMon;
|
||||
y = CurYear;
|
||||
if (d == NO_DAY) d = CurDay;
|
||||
}
|
||||
}
|
||||
if (d == NO_DAY) d=1;
|
||||
if (d > DaysInMonth(m, y)) {
|
||||
fprintf(ErrFp, BadDate);
|
||||
Usage();
|
||||
}
|
||||
JulianToday = Julian(y, m, d);
|
||||
if (JulianToday == -1) {
|
||||
fprintf(ErrFp, BadDate);
|
||||
Usage();
|
||||
}
|
||||
CurYear = y;
|
||||
CurMon = m;
|
||||
CurDay = d;
|
||||
if (JulianToday != RealToday) IgnoreOnce = 1;
|
||||
}
|
||||
|
||||
}
|
||||
/* Figure out the offset from UTC */
|
||||
if (CalculateUTC)
|
||||
(void) CalcMinsFromUTC(JulianToday, SystemTime(1)/60,
|
||||
&MinsFromUTC, NULL);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* Usage */
|
||||
/* */
|
||||
/* Print the usage info. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifndef L_USAGE_OVERRIDE
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void Usage(void)
|
||||
#else
|
||||
void Usage()
|
||||
#endif /* HAVE_PROTOS */
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1996 by David F. Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
fprintf(ErrFp, "Usage: remind [options] filename [date] [time] [*rep]\n");
|
||||
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, " -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, " -v Verbose mode\n");
|
||||
fprintf(ErrFp, " -o Ignore ONCE directives\n");
|
||||
fprintf(ErrFp, " -t Trigger all future reminders regardless of delta\n");
|
||||
fprintf(ErrFp, " -h 'Hush' mode - be very quiet\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
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");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\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, " -ivar=val Initialize var to val and preserve var\n");
|
||||
fprintf(ErrFp, " -m Start calendar with Monday rather than Sunday\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_USAGE_OVERRIDE */
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ChgUser */
|
||||
/* */
|
||||
/* Run as a specified user. Can only be used if Remind is */
|
||||
/* started by root. This changes the real and effective uid, */
|
||||
/* the real and effective gid, and sets the HOME, SHELL and */
|
||||
/* USER environment variables. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#if defined(UNIX) && defined(WANT_U_OPTION)
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void ChgUser(char *user)
|
||||
#else
|
||||
static void ChgUser(user)
|
||||
char *user;
|
||||
#endif /* HAVE_PROTOS */
|
||||
{
|
||||
#ifdef SYSV
|
||||
/* uid_t myuid; This seems to mess up on XENIX, so forget it... */
|
||||
int myuid;
|
||||
#else
|
||||
int myuid;
|
||||
#endif
|
||||
|
||||
struct passwd *pwent;
|
||||
static char *home, *shell, *username, *logname;
|
||||
|
||||
myuid = getuid();
|
||||
|
||||
pwent = getpwnam(user);
|
||||
|
||||
if (!pwent) {
|
||||
fprintf(ErrFp, ErrMsg[M_BAD_USER], user);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!myuid && setgid(pwent->pw_gid)) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_GID], pwent->pw_gid);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!myuid && setuid(pwent->pw_uid)) {
|
||||
fprintf(ErrFp, ErrMsg[M_NO_CHG_UID], pwent->pw_uid);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
home = malloc(strlen(pwent->pw_dir) + 6);
|
||||
if (!home) {
|
||||
fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(home, "HOME=%s", pwent->pw_dir);
|
||||
putenv(home);
|
||||
|
||||
shell = malloc(strlen(pwent->pw_shell) + 7);
|
||||
if (!shell) {
|
||||
fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(shell, "SHELL=%s", pwent->pw_shell);
|
||||
putenv(shell);
|
||||
|
||||
if (pwent->pw_uid) {
|
||||
username = malloc(strlen(pwent->pw_name) + 6);
|
||||
if (!username) {
|
||||
fprintf(ErrFp, 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]);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(logname, "LOGNAME=%s", pwent->pw_name);
|
||||
putenv(logname);
|
||||
}
|
||||
}
|
||||
#endif /* UNIX && WANT_U_OPTION */
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* InitializeVar */
|
||||
/* */
|
||||
/* Initialize and preserve a variable */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void InitializeVar(char *str)
|
||||
#else
|
||||
static void InitializeVar(str)
|
||||
char *str;
|
||||
#endif
|
||||
{
|
||||
char *varname, *expr;
|
||||
|
||||
Value val;
|
||||
|
||||
int r;
|
||||
|
||||
/* Scan for an '=' sign */
|
||||
varname = str;
|
||||
while (*str && *str != '=') str++;
|
||||
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;
|
||||
}
|
||||
expr = str+1;
|
||||
if (!*expr) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_EXPR]);
|
||||
return;
|
||||
}
|
||||
|
||||
r=EvalExpr(&expr, &val);
|
||||
if (r) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*varname == '$') {
|
||||
r=SetSysVar(varname+1, &val);
|
||||
if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
return;
|
||||
}
|
||||
|
||||
r=SetVar(varname, &val);
|
||||
if (r) {
|
||||
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
return;
|
||||
}
|
||||
r=PreserveVar(varname);
|
||||
if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
|
||||
return;
|
||||
}
|
||||
|
||||
42
kall
Normal file
42
kall
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $Id: kall,v 1.1 1996-03-27 03:25:59 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
|
||||
27
kall.1
Normal file
27
kall.1
Normal file
@@ -0,0 +1,27 @@
|
||||
.TH KALL 1 "26 February 1991"
|
||||
.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
|
||||
64
lang.h
Normal file
64
lang.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* LANG.H */
|
||||
/* */
|
||||
/* Header file for language support for various languages. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: lang.h,v 1.1 1996-03-27 03:25:59 dfs Exp $ */
|
||||
|
||||
/* I'm chauvinistic and name each language with its English name... */
|
||||
|
||||
#define ENGLISH 0 /* original by David F. Skoll */
|
||||
#define GERMAN 1 /* translated by Wolfgang Thronicke */
|
||||
#define DUTCH 2 /* translated by Willem Kasdorp and Erik-Jan Vens */
|
||||
#define FINNISH 3 /* translated by Mikko Silvonen */
|
||||
#define FRENCH 4 /* translated by Laurent Duperval */
|
||||
#define NORWEGIAN 5 /* translated by Trygve Randen */
|
||||
#define DANISH 6 /* translated by Mogens Lynnerup */
|
||||
#define POLISH 7 /* translated by Jerzy Sobczyk */
|
||||
|
||||
/* Add more languages here - but please e-mail dfs@doe.carleton.ca
|
||||
to have your favorite language assigned a number. If you add a
|
||||
language, please send me the header file, and permission to include
|
||||
it in future releases of Remind. Note that you'll get no remuneration
|
||||
for this service - just everlasting fame. :-)
|
||||
|
||||
Use the file tstlang.rem to test your new language file. */
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* Define the language you want to use here *
|
||||
* *
|
||||
************************************************************************/
|
||||
#ifndef LANG /* Allow for definition on compiler command line */
|
||||
#define LANG ENGLISH
|
||||
#endif
|
||||
|
||||
/* Pick up the appropriate header file */
|
||||
#if LANG == ENGLISH
|
||||
#include "english.h"
|
||||
#elif LANG == GERMAN
|
||||
#include "german.h"
|
||||
#elif LANG == DUTCH
|
||||
#include "dutch.h"
|
||||
#elif LANG == FINNISH
|
||||
#include "finnish.h"
|
||||
#elif LANG == FRENCH
|
||||
#include "french.h"
|
||||
#elif LANG == NORWEGIAN
|
||||
#include "norwgian.h"
|
||||
#elif LANG == DANISH
|
||||
#include "danish.h"
|
||||
#elif LANG == POLISH
|
||||
#include "polish.h"
|
||||
|
||||
/* If no sensible language, choose English. I intended to use
|
||||
the #error directive here, but some C compilers barf. */
|
||||
#else
|
||||
#include "english.h"
|
||||
#endif
|
||||
20
lnk.bcc
Normal file
20
lnk.bcc
Normal file
@@ -0,0 +1,20 @@
|
||||
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
|
||||
23
lnk.msc
Normal file
23
lnk.msc
Normal file
@@ -0,0 +1,23 @@
|
||||
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
|
||||
|
||||
|
||||
|
||||
19
lnk.tc
Normal file
19
lnk.tc
Normal file
@@ -0,0 +1,19 @@
|
||||
-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
|
||||
107
makefile.bcc
Normal file
107
makefile.bcc
Normal file
@@ -0,0 +1,107 @@
|
||||
# Makefile for REMIND for Borland C++
|
||||
# $Id: makefile.bcc,v 1.1 1996-03-27 03:26:01 dfs Exp $
|
||||
|
||||
VERSION= 03.00.13
|
||||
|
||||
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
|
||||
|
||||
MANIFEST= readme.uni readme.dos copyrigh $(HDRS) $(SRCS) makefile rem rem.1 \
|
||||
remind.1 remind-a.csh remind-a.sh test.rem test-rem test.cmp makefile.tc \
|
||||
makefile.msc lnk.msc lnk.tc manifest.dos manifest.unx whatsnew.30 kall kall.1 \
|
||||
tstlang.rem defs.rem readme.os2 makefile.os2 rem2ps.c rem2ps.h remind.def \
|
||||
rem2ps.1 makefile.bcc lnk.bcc test-rem.cmd test2.cmp
|
||||
|
||||
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
|
||||
|
||||
remind.zoo: $(MANIFEST)
|
||||
zoo aI remind.zoo < manifest.dos
|
||||
|
||||
74
makefile.msc
Normal file
74
makefile.msc
Normal file
@@ -0,0 +1,74 @@
|
||||
# Makefile for REMIND for Microsoft C for MSDOS
|
||||
# $Id: makefile.msc,v 1.1 1996-03-27 03:26:01 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,,,
|
||||
|
||||
110
makefile.os2
Normal file
110
makefile.os2
Normal file
@@ -0,0 +1,110 @@
|
||||
# Makefile for REMIND
|
||||
#
|
||||
# $Id: makefile.os2,v 1.1 1996-03-27 03:26:02 dfs Exp $
|
||||
#
|
||||
# - 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] "
|
||||
|
||||
|
||||
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=""
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
.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
|
||||
80
makefile.tc
Normal file
80
makefile.tc
Normal file
@@ -0,0 +1,80 @@
|
||||
# Makefile for REMIND for Turbo C for MSDOS
|
||||
# $Id: makefile.tc,v 1.1 1996-03-27 03:26:03 dfs Exp $
|
||||
|
||||
CC= tcc
|
||||
VERSION= 03.00.13
|
||||
|
||||
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
|
||||
|
||||
MANIFEST= readme.uni readme.dos copyrigh $(HDRS) $(SRCS) makefile rem rem.1 \
|
||||
remind.1 remind-a.csh remind-a.sh test.rem test-rem test.cmp makefile.tc \
|
||||
makefile.msc lnk.msc lnk.tc manifest.dos manifest.unx whatsnew.30 kall kall.1 \
|
||||
tstlang.rem defs.rem readme.os2 makefile.os2 rem2ps.c rem2ps.h remind.def \
|
||||
rem2ps.1 README.BCC lnk.bcc makefile.bcc os2func.c \
|
||||
test-rem.bat test-rem.cmd test1.cmp test2.cmp
|
||||
|
||||
|
||||
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
|
||||
|
||||
remind.zoo: $(MANIFEST)
|
||||
zoo aI remind.zoo < manifest.dos
|
||||
|
||||
640
moon.c
Normal file
640
moon.c
Normal file
@@ -0,0 +1,640 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* MOON.C */
|
||||
/* */
|
||||
/* Calculations for figuring out moon phases. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: moon.c,v 1.1 1996-03-27 03:26:03 dfs Exp $";
|
||||
|
||||
/* All of these routines were adapted from the program "moontool"
|
||||
by John Walker, February 1988. Here's the blurb from moontool:
|
||||
|
||||
... The information is generally accurate to within ten
|
||||
minutes.
|
||||
|
||||
The algorithms used in this program to calculate the positions Sun and
|
||||
Moon as seen from the Earth are given in the book "Practical Astronomy
|
||||
With Your Calculator" by Peter Duffett-Smith, Second Edition,
|
||||
Cambridge University Press, 1981. Ignore the word "Calculator" in the
|
||||
title; this is an essential reference if you're interested in
|
||||
developing software which calculates planetary positions, orbits,
|
||||
eclipses, and the like. If you're interested in pursuing such
|
||||
programming, you should also obtain:
|
||||
|
||||
"Astronomical Formulae for Calculators" by Jean Meeus, Third Edition,
|
||||
Willmann-Bell, 1985. A must-have.
|
||||
|
||||
"Planetary Programs and Tables from -4000 to +2800" by Pierre
|
||||
Bretagnon and Jean-Louis Simon, Willmann-Bell, 1986. If you want the
|
||||
utmost (outside of JPL) accuracy for the planets, it's here.
|
||||
|
||||
"Celestial BASIC" by Eric Burgess, Revised Edition, Sybex, 1985. Very
|
||||
cookbook oriented, and many of the algorithms are hard to dig out of
|
||||
the turgid BASIC code, but you'll probably want it anyway.
|
||||
|
||||
Many of these references can be obtained from Willmann-Bell, P.O. Box
|
||||
35025, Richmond, VA 23235, USA. Phone: (804) 320-7016. In addition
|
||||
to their own publications, they stock most of the standard references
|
||||
for mathematical and positional astronomy.
|
||||
|
||||
This program was written by:
|
||||
|
||||
John Walker
|
||||
Autodesk, Inc.
|
||||
2320 Marinship Way
|
||||
Sausalito, CA 94965
|
||||
(415) 332-2344 Ext. 829
|
||||
|
||||
Usenet: {sun!well}!acad!kelvin
|
||||
|
||||
This program is in the public domain: "Do what thou wilt shall be the
|
||||
whole of the law". I'd appreciate receiving any bug fixes and/or
|
||||
enhancements, which I'll incorporate in future versions of the
|
||||
program. Please leave the original attribution information intact so
|
||||
that credit and blame may be properly apportioned.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
/* Function prototypes */
|
||||
PRIVATE long jdate ARGS((int y, int mon, int day));
|
||||
PRIVATE double jtime ARGS((int y, int mon, int day, int hour, int min, int sec));
|
||||
PRIVATE void jyear ARGS((double td, int *yy, int *mm, int *dd));
|
||||
PRIVATE void jhms ARGS((double j, int *h, int *m, int *s));
|
||||
PRIVATE double meanphase ARGS((double sdate, double phase, double *usek));
|
||||
PRIVATE double truephase ARGS((double k, double phase));
|
||||
PRIVATE double kepler ARGS((double m, double ecc));
|
||||
PRIVATE double phase ARGS((double, double *, double *, double *, double *, double *, double *));
|
||||
|
||||
|
||||
/* Astronomical constants */
|
||||
|
||||
#define epoch 2444238.5 /* 1980 January 0.0 */
|
||||
|
||||
/* Constants defining the Sun's apparent orbit */
|
||||
|
||||
#define elonge 278.833540 /* Ecliptic longitude of the Sun
|
||||
at epoch 1980.0 */
|
||||
#define elongp 282.596403 /* Ecliptic longitude of the Sun at
|
||||
perigee */
|
||||
#define eccent 0.016718 /* Eccentricity of Earth's orbit */
|
||||
#define sunsmax 1.495985e8 /* Semi-major axis of Earth's orbit, km */
|
||||
#define sunangsiz 0.533128 /* Sun's angular size, degrees, at
|
||||
semi-major axis distance */
|
||||
|
||||
/* Elements of the Moon's orbit, epoch 1980.0 */
|
||||
|
||||
#define mmlong 64.975464 /* Moon's mean lonigitude at the epoch */
|
||||
#define mmlongp 349.383063 /* Mean longitude of the perigee at the
|
||||
epoch */
|
||||
#define mlnode 151.950429 /* Mean longitude of the node at the
|
||||
epoch */
|
||||
#define minc 5.145396 /* Inclination of the Moon's orbit */
|
||||
#define mecc 0.054900 /* Eccentricity of the Moon's orbit */
|
||||
#define mangsiz 0.5181 /* Moon's angular size at distance a
|
||||
from Earth */
|
||||
#define msmax 384401.0 /* Semi-major axis of Moon's orbit in km */
|
||||
#define mparallax 0.9507 /* Parallax at distance a from Earth */
|
||||
#define synmonth 29.53058868 /* Synodic month (new Moon to new Moon) */
|
||||
#define lunatbase 2423436.0 /* Base date for E. W. Brown's numbered
|
||||
series of lunations (1923 January 16) */
|
||||
|
||||
/* Properties of the Earth */
|
||||
|
||||
#define earthrad 6378.16 /* Radius of Earth in kilometres */
|
||||
#ifdef PI
|
||||
#undef PI
|
||||
#endif
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
/* Handy mathematical functions */
|
||||
|
||||
#ifdef sgn
|
||||
#undef sgn
|
||||
#endif
|
||||
#define sgn(x) (((x) < 0) ? -1 : ((x) > 0 ? 1 : 0)) /* Extract sign */
|
||||
|
||||
#ifdef abs
|
||||
#undef abs
|
||||
#endif
|
||||
#define abs(x) ((x) < 0 ? (-(x)) : (x)) /* Absolute val */
|
||||
|
||||
#define fixangle(a) ((a) - 360.0 * (floor((a) / 360.0))) /* Fix angle */
|
||||
#define torad(d) ((d) * (PI / 180.0)) /* Deg->Rad */
|
||||
#define todeg(d) ((d) * (180.0 / PI)) /* Rad->Deg */
|
||||
#define dsin(x) (sin(torad((x)))) /* Sin from deg */
|
||||
#define dcos(x) (cos(torad((x)))) /* Cos from deg */
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* jdate */
|
||||
/* */
|
||||
/* Convert a date and time to Julian day and fraction. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE long jdate(int y, int mon, int day)
|
||||
#else
|
||||
static long jdate(y, mon, day)
|
||||
int y, mon, day;
|
||||
#endif
|
||||
{
|
||||
long c, m;
|
||||
|
||||
m = mon+1;
|
||||
if (m>2) {
|
||||
m -= 3;
|
||||
} else {
|
||||
m += 9;
|
||||
y--;
|
||||
}
|
||||
c = y/100L; /* Century */
|
||||
y -= 100L * c;
|
||||
return day + (c*146097L)/4 + (y*1461L)/4 + (m*153L+2)/5 + 1721119L;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* jtime */
|
||||
/* */
|
||||
/* Convert a GMT date and time to astronomical Julian time, */
|
||||
/* i.e. Julian date plus day fraction, expressed as a double */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE double jtime(int y, int mon, int day, int hour, int min, int sec)
|
||||
#else
|
||||
static double jtime(y, mon, day, hour, min, sec)
|
||||
int y, mon, day, hour, min, sec;
|
||||
#endif
|
||||
{
|
||||
return (jdate(y, mon, day)-0.5) +
|
||||
(sec + 60L * (long) min + 3600L * (long) hour) / 86400.0;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* jyear */
|
||||
/* */
|
||||
/* Convert a Julian date to year, month, day. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void jyear(double td, int *yy, int *mm, int *dd)
|
||||
#else
|
||||
static void jyear(td, yy, mm, dd)
|
||||
double td;
|
||||
int *yy, *mm, *dd;
|
||||
#endif
|
||||
{
|
||||
double j, d, y, m;
|
||||
|
||||
td += 0.5; /* Astronomical to civil */
|
||||
j = floor(td);
|
||||
j = j - 1721119.0;
|
||||
y = floor(((4 * j) - 1) / 146097.0);
|
||||
j = (j * 4.0) - (1.0 + (146097.0 * y));
|
||||
d = floor(j / 4.0);
|
||||
j = floor(((4.0 * d) + 3.0) / 1461.0);
|
||||
d = ((4.0 * d) + 3.0) - (1461.0 * j);
|
||||
d = floor((d + 4.0) / 4.0);
|
||||
m = floor(((5.0 * d) - 3) / 153.0);
|
||||
d = (5.0 * d) - (3.0 + (153.0 * m));
|
||||
d = floor((d + 5.0) / 5.0);
|
||||
y = (100.0 * y) + j;
|
||||
if (m < 10.0)
|
||||
m = m + 2;
|
||||
else {
|
||||
m = m - 10;
|
||||
y = y + 1;
|
||||
}
|
||||
*yy = y;
|
||||
*mm = m;
|
||||
*dd = d;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* jhms */
|
||||
/* */
|
||||
/* Convert a Julian time to hour, minutes and seconds. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void jhms(double j, int *h, int *m, int *s)
|
||||
#else
|
||||
static void jhms(j, h, m, s)
|
||||
double j;
|
||||
int *h, *m, *s;
|
||||
#endif
|
||||
{
|
||||
long ij;
|
||||
|
||||
j += 0.5; /* Astronomical to civil */
|
||||
ij = (j - floor(j)) * 86400.0;
|
||||
*h = ij / 3600L;
|
||||
*m = (ij / 60L) % 60L;
|
||||
*s = ij % 60L;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* meanphase */
|
||||
/* */
|
||||
/* Calculates mean phase of the Moon for a */
|
||||
/* given base date and desired phase: */
|
||||
/* 0.0 New Moon */
|
||||
/* 0.25 First quarter */
|
||||
/* 0.5 Full moon */
|
||||
/* 0.75 Last quarter */
|
||||
/* Beware!!! This routine returns meaningless */
|
||||
/* results for any other phase arguments. Don't */
|
||||
/* attempt to generalise it without understanding */
|
||||
/* that the motion of the moon is far more complicated */
|
||||
/* than this calculation reveals. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE double meanphase(double sdate, double phase, double *usek)
|
||||
#else
|
||||
static double meanphase(sdate, phase, usek)
|
||||
double sdate, phase;
|
||||
double *usek;
|
||||
#endif
|
||||
{
|
||||
double k, t, t2, t3, nt1;
|
||||
|
||||
/*** The following was the original code: It gave roundoff errors
|
||||
causing moonphase info to fail for Dec 1994. ***/
|
||||
/* jyear(sdate, &yy, &mm, &dd);
|
||||
k = (yy + (mm/12.0) - 1900) * 12.368531; */
|
||||
|
||||
/*** The next line is the replacement ***/
|
||||
k = (sdate - 2415020.0) / synmonth;
|
||||
|
||||
/* Time in Julian centuries from 1900 January 0.5 */
|
||||
t = (sdate - 2415020.0) / 36525.0;
|
||||
t2 = t * t; /* Square for frequent use */
|
||||
t3 = t2 * t; /* Cube for frequent use */
|
||||
|
||||
*usek = k = floor(k) + phase;
|
||||
nt1 = 2415020.75933 + synmonth * k
|
||||
+ 0.0001178 * t2
|
||||
- 0.000000155 * t3
|
||||
+ 0.00033 * dsin(166.56 + 132.87 * t - 0.009173 * t2);
|
||||
|
||||
return nt1;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* truephase */
|
||||
/* */
|
||||
/* Given a K value used to determine the */
|
||||
/* mean phase of the new moon, and a phase */
|
||||
/* selector (0.0, 0.25, 0.5, 0.75), obtain */
|
||||
/* the true, corrected phase time. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE double truephase(double k, double phase)
|
||||
#else
|
||||
static double truephase(k, phase)
|
||||
double k, phase;
|
||||
#endif
|
||||
{
|
||||
double t, t2, t3, pt, m, mprime, f;
|
||||
int apcor = 0;
|
||||
|
||||
k += phase; /* Add phase to new moon time */
|
||||
t = k / 1236.8531; /* Time in Julian centuries from
|
||||
1900 January 0.5 */
|
||||
t2 = t * t; /* Square for frequent use */
|
||||
t3 = t2 * t; /* Cube for frequent use */
|
||||
pt = 2415020.75933 /* Mean time of phase */
|
||||
+ synmonth * k
|
||||
+ 0.0001178 * t2
|
||||
- 0.000000155 * t3
|
||||
+ 0.00033 * dsin(166.56 + 132.87 * t - 0.009173 * t2);
|
||||
|
||||
m = 359.2242 /* Sun's mean anomaly */
|
||||
+ 29.10535608 * k
|
||||
- 0.0000333 * t2
|
||||
- 0.00000347 * t3;
|
||||
mprime = 306.0253 /* Moon's mean anomaly */
|
||||
+ 385.81691806 * k
|
||||
+ 0.0107306 * t2
|
||||
+ 0.00001236 * t3;
|
||||
f = 21.2964 /* Moon's argument of latitude */
|
||||
+ 390.67050646 * k
|
||||
- 0.0016528 * t2
|
||||
- 0.00000239 * t3;
|
||||
if ((phase < 0.01) || (abs(phase - 0.5) < 0.01)) {
|
||||
|
||||
/* Corrections for New and Full Moon */
|
||||
|
||||
pt += (0.1734 - 0.000393 * t) * dsin(m)
|
||||
+ 0.0021 * dsin(2 * m)
|
||||
- 0.4068 * dsin(mprime)
|
||||
+ 0.0161 * dsin(2 * mprime)
|
||||
- 0.0004 * dsin(3 * mprime)
|
||||
+ 0.0104 * dsin(2 * f)
|
||||
- 0.0051 * dsin(m + mprime)
|
||||
- 0.0074 * dsin(m - mprime)
|
||||
+ 0.0004 * dsin(2 * f + m)
|
||||
- 0.0004 * dsin(2 * f - m)
|
||||
- 0.0006 * dsin(2 * f + mprime)
|
||||
+ 0.0010 * dsin(2 * f - mprime)
|
||||
+ 0.0005 * dsin(m + 2 * mprime);
|
||||
apcor = 1;
|
||||
} else if ((abs(phase - 0.25) < 0.01 || (abs(phase - 0.75) < 0.01))) {
|
||||
pt += (0.1721 - 0.0004 * t) * dsin(m)
|
||||
+ 0.0021 * dsin(2 * m)
|
||||
- 0.6280 * dsin(mprime)
|
||||
+ 0.0089 * dsin(2 * mprime)
|
||||
- 0.0004 * dsin(3 * mprime)
|
||||
+ 0.0079 * dsin(2 * f)
|
||||
- 0.0119 * dsin(m + mprime)
|
||||
- 0.0047 * dsin(m - mprime)
|
||||
+ 0.0003 * dsin(2 * f + m)
|
||||
- 0.0004 * dsin(2 * f - m)
|
||||
- 0.0006 * dsin(2 * f + mprime)
|
||||
+ 0.0021 * dsin(2 * f - mprime)
|
||||
+ 0.0003 * dsin(m + 2 * mprime)
|
||||
+ 0.0004 * dsin(m - 2 * mprime)
|
||||
- 0.0003 * dsin(2 * m + mprime);
|
||||
if (phase < 0.5)
|
||||
/* First quarter correction */
|
||||
pt += 0.0028 - 0.0004 * dcos(m) + 0.0003 * dcos(mprime);
|
||||
else
|
||||
/* Last quarter correction */
|
||||
pt += -0.0028 + 0.0004 * dcos(m) - 0.0003 * dcos(mprime);
|
||||
apcor = 1;
|
||||
}
|
||||
if (!apcor) return 0.0;
|
||||
return pt;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* kepler */
|
||||
/* */
|
||||
/* Solve the equation of Kepler. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE double kepler(double m, double ecc)
|
||||
#else
|
||||
static double kepler(m, ecc)
|
||||
double m, ecc;
|
||||
#endif
|
||||
{
|
||||
double e, delta;
|
||||
#define EPSILON 1E-6
|
||||
|
||||
e = m = torad(m);
|
||||
do {
|
||||
delta = e - ecc * sin(e) - m;
|
||||
e -= delta / (1 - ecc * cos(e));
|
||||
} while (abs(delta) > EPSILON);
|
||||
return e;
|
||||
}
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* PHASE -- Calculate phase of moon as a fraction: */
|
||||
/* */
|
||||
/* The argument is the time for which the phase is */
|
||||
/* Requested, expressed as a Julian date and */
|
||||
/* fraction. Returns the terminator phase angle as a */
|
||||
/* percentage of a full circle (i.e., 0 to 1), and */
|
||||
/* stores into pointer arguments the illuminated */
|
||||
/* fraction of the Moon's disc, the Moon's age in */
|
||||
/* days and fraction, the distance of the Moon from */
|
||||
/* the centre of the Earth, and the angular diameter */
|
||||
/* subtended by the Moon as seen by an observer at */
|
||||
/* the centre of the Earth. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE double phase(double pdate,
|
||||
double *pphase,
|
||||
double *mage,
|
||||
double *dist,
|
||||
double *angdia,
|
||||
double *sudist,
|
||||
double *suangdia)
|
||||
#else
|
||||
static double phase(pdate, pphase, mage, dist, angdia, sudist, suangdia)
|
||||
double pdate;
|
||||
double *pphase; /* Illuminated fraction */
|
||||
double *mage; /* Age of moon in days */
|
||||
double *dist; /* Distance in kilometres */
|
||||
double *angdia; /* Angular diameter in degrees */
|
||||
double *sudist; /* Distance to Sun */
|
||||
double *suangdia; /* Sun's angular diameter */
|
||||
#endif
|
||||
{
|
||||
|
||||
double Day, N, M, Ec, Lambdasun, ml, MM, MN, Ev, Ae, A3, MmP,
|
||||
mEc, A4, lP, V, lPP, NP, y, x, Lambdamoon,
|
||||
MoonAge, MoonPhase,
|
||||
MoonDist, MoonDFrac, MoonAng,
|
||||
F, SunDist, SunAng;
|
||||
|
||||
/* Calculation of the Sun's position */
|
||||
|
||||
Day = pdate - epoch; /* Date within epoch */
|
||||
N = fixangle((360 / 365.2422) * Day); /* Mean anomaly of the Sun */
|
||||
M = fixangle(N + elonge - elongp); /* Convert from perigee
|
||||
co-ordinates to epoch 1980.0 */
|
||||
Ec = kepler(M, eccent); /* Solve equation of Kepler */
|
||||
Ec = sqrt((1 + eccent) / (1 - eccent)) * tan(Ec / 2);
|
||||
Ec = 2 * todeg(atan(Ec)); /* 1 anomaly */
|
||||
Lambdasun = fixangle(Ec + elongp); /* Sun's geocentric ecliptic
|
||||
longitude */
|
||||
/* Orbital distance factor */
|
||||
F = ((1 + eccent * cos(torad(Ec))) / (1 - eccent * eccent));
|
||||
SunDist = sunsmax / F; /* Distance to Sun in km */
|
||||
SunAng = F * sunangsiz; /* Sun's angular size in degrees */
|
||||
|
||||
|
||||
/* Calculation of the Moon's position */
|
||||
|
||||
/* Moon's mean longitude */
|
||||
ml = fixangle(13.1763966 * Day + mmlong);
|
||||
|
||||
/* Moon's mean anomaly */
|
||||
MM = fixangle(ml - 0.1114041 * Day - mmlongp);
|
||||
|
||||
/* Moon's ascending node mean longitude */
|
||||
MN = fixangle(mlnode - 0.0529539 * Day);
|
||||
|
||||
/* Evection */
|
||||
Ev = 1.2739 * sin(torad(2 * (ml - Lambdasun) - MM));
|
||||
|
||||
/* Annual equation */
|
||||
Ae = 0.1858 * sin(torad(M));
|
||||
|
||||
/* Correction term */
|
||||
A3 = 0.37 * sin(torad(M));
|
||||
|
||||
/* Corrected anomaly */
|
||||
MmP = MM + Ev - Ae - A3;
|
||||
|
||||
/* Correction for the equation of the centre */
|
||||
mEc = 6.2886 * sin(torad(MmP));
|
||||
|
||||
/* Another correction term */
|
||||
A4 = 0.214 * sin(torad(2 * MmP));
|
||||
|
||||
/* Corrected longitude */
|
||||
lP = ml + Ev + mEc - Ae + A4;
|
||||
|
||||
/* Variation */
|
||||
V = 0.6583 * sin(torad(2 * (lP - Lambdasun)));
|
||||
|
||||
/* 1 longitude */
|
||||
lPP = lP + V;
|
||||
|
||||
/* Corrected longitude of the node */
|
||||
NP = MN - 0.16 * sin(torad(M));
|
||||
|
||||
/* Y inclination coordinate */
|
||||
y = sin(torad(lPP - NP)) * cos(torad(minc));
|
||||
|
||||
/* X inclination coordinate */
|
||||
x = cos(torad(lPP - NP));
|
||||
|
||||
/* Ecliptic longitude */
|
||||
Lambdamoon = todeg(atan2(y, x));
|
||||
Lambdamoon += NP;
|
||||
|
||||
/* Calculation of the phase of the Moon */
|
||||
|
||||
/* Age of the Moon in degrees */
|
||||
MoonAge = lPP - Lambdasun;
|
||||
|
||||
/* Phase of the Moon */
|
||||
MoonPhase = (1 - cos(torad(MoonAge))) / 2;
|
||||
|
||||
/* Calculate distance of moon from the centre of the Earth */
|
||||
|
||||
MoonDist = (msmax * (1 - mecc * mecc)) /
|
||||
(1 + mecc * cos(torad(MmP + mEc)));
|
||||
|
||||
/* Calculate Moon's angular diameter */
|
||||
|
||||
MoonDFrac = MoonDist / msmax;
|
||||
MoonAng = mangsiz / MoonDFrac;
|
||||
|
||||
if(pphase) *pphase = MoonPhase;
|
||||
if(mage) *mage = synmonth * (fixangle(MoonAge) / 360.0);
|
||||
if(dist) *dist = MoonDist;
|
||||
if(angdia) *angdia = MoonAng;
|
||||
if(sudist) *sudist = SunDist;
|
||||
if(suangdia) *suangdia = SunAng;
|
||||
return fixangle(MoonAge) / 360.0;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* MoonPhase */
|
||||
/* */
|
||||
/* Interface routine dealing in Remind representations. */
|
||||
/* Given a local date and time, returns the moon phase at */
|
||||
/* that date and time as a number from 0 to 360. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int MoonPhase(int date, int time)
|
||||
#else
|
||||
int MoonPhase(date, time)
|
||||
int date, time;
|
||||
#endif
|
||||
{
|
||||
int utcd, utct;
|
||||
int y, m, d;
|
||||
double jd, mp;
|
||||
|
||||
/* Convert from local to UTC */
|
||||
LocalToUTC(date, time, &utcd, &utct);
|
||||
|
||||
/* Convert from Remind representation to year/mon/day */
|
||||
FromJulian(utcd, &y, &m, &d);
|
||||
|
||||
/* Convert to a true Julian date -- sorry for the name clashes! */
|
||||
jd = jtime(y, m, d, (utct / 60), (utct % 60), 0);
|
||||
|
||||
/* Calculate moon phase */
|
||||
mp = 360.0 * phase(jd, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
return (int) mp;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HuntPhase */
|
||||
/* */
|
||||
/* Given a starting date and time and a target phase, find */
|
||||
/* the first date on or after the starting date and time when */
|
||||
/* the moon hits the specified phase. Phase must be from */
|
||||
/* 0 to 3 for new, 1stq, full, 3rdq */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void HuntPhase(int startdate, int starttim, int phas, int *date, int *time)
|
||||
#else
|
||||
void HuntPhase(startdate, starttim, phas, date, time)
|
||||
int startdate, starttim, phas, *date, *time;
|
||||
#endif
|
||||
{
|
||||
int utcd, utct;
|
||||
int y, m, d;
|
||||
int h, min, s;
|
||||
int d1, t1;
|
||||
double k1, k2, jd, jdorig;
|
||||
double nt1, nt2;
|
||||
|
||||
/* Convert from local to UTC */
|
||||
LocalToUTC(startdate, starttim, &utcd, &utct);
|
||||
|
||||
/* Convert from Remind representation to year/mon/day */
|
||||
FromJulian(utcd, &y, &m, &d);
|
||||
/* Convert to a true Julian date -- sorry for the name clashes! */
|
||||
jdorig = jtime(y, m, d, (utct / 60), (utct % 60), 0);
|
||||
jd = jdorig - 45.0;
|
||||
nt1 = meanphase(jd, 0.0, &k1);
|
||||
while(1) {
|
||||
jd += synmonth;
|
||||
nt2 = meanphase(jd, 0.0, &k2);
|
||||
if (nt1 <= jdorig && nt2 > jdorig) break;
|
||||
nt1 = nt2;
|
||||
k1 = k2;
|
||||
}
|
||||
jd = truephase(k1, phas/4.0);
|
||||
if (jd < jdorig) jd = truephase(k2, phas/4.0);
|
||||
|
||||
/* Convert back to Remind format */
|
||||
jyear(jd, &y, &m, &d);
|
||||
jhms(jd, &h, &min, &s);
|
||||
|
||||
d1 = Julian(y, m, d);
|
||||
t1 = h*60 + min;
|
||||
UTCToLocal(d1, t1, date, time);
|
||||
}
|
||||
114
norwgian.h
Normal file
114
norwgian.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* NORWGIAN.H */
|
||||
/* */
|
||||
/* Support for the Norwegian language. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* This file is Copyright (C) 1993 by Trygve Randen. */
|
||||
/* Remind is Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: norwgian.h,v 1.1 1996-03-27 03:26:03 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Norwegian"
|
||||
|
||||
/* Day names */
|
||||
#ifdef ISOLATIN1
|
||||
# define L_SUNDAY "S\370ndag"
|
||||
#else
|
||||
# define L_SUNDAY "Soendag"
|
||||
#endif
|
||||
#define L_MONDAY "Mandag"
|
||||
#define L_TUESDAY "Tirsdag"
|
||||
#define L_WEDNESDAY "Onsdag"
|
||||
#define L_THURSDAY "Torsdag"
|
||||
#define L_FRIDAY "Fredag"
|
||||
#ifdef ISOLATIN1
|
||||
# define L_SATURDAY "L\370rdag"
|
||||
#else
|
||||
# define L_SATURDAY "Loerdag"
|
||||
#endif
|
||||
|
||||
/* Day initials - first letter only */
|
||||
#define L_DAYINIT "SMTOTFL"
|
||||
|
||||
/* Month names */
|
||||
#define L_JAN "Januar"
|
||||
#define L_FEB "Februar"
|
||||
#define L_MAR "Mars"
|
||||
#define L_APR "April"
|
||||
#define L_MAY "Mai"
|
||||
#define L_JUN "Juni"
|
||||
#define L_JUL "Juli"
|
||||
#define L_AUG "August"
|
||||
#define L_SEP "September"
|
||||
#define L_OCT "Oktober"
|
||||
#define L_NOV "November"
|
||||
#define L_DEC "Desember"
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "i dag"
|
||||
#define L_TOMORROW "i morgen"
|
||||
|
||||
/* The default banner */
|
||||
#ifdef ISOLATIN1
|
||||
# define L_BANNER "P\345minnelse for %w, %d. %m, %y%o:"
|
||||
#else
|
||||
# define L_BANNER "Paaminnelse for %w, %d. %m, %y%o:"
|
||||
#endif
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "siden"
|
||||
#ifdef ISOLATIN1
|
||||
# define L_FROMNOW "fra n\345"
|
||||
#else
|
||||
# define L_FROMNOW "fra naa"
|
||||
#endif
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "om %d dager"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "den"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL "er"
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#ifdef ISOLATIN1
|
||||
# define L_NOW "n\345"
|
||||
#else
|
||||
# define L_NOW "naa"
|
||||
#endif
|
||||
#define L_AT "kl."
|
||||
#define L_MINUTE "minutt"
|
||||
#define L_HOUR "time"
|
||||
#define L_IS "er"
|
||||
#define L_WAS "var"
|
||||
#define L_AND "og"
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU "r"
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU "er"
|
||||
|
||||
/* 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_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
363
omit.c
Normal file
363
omit.c
Normal file
@@ -0,0 +1,363 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* OMIT.C */
|
||||
/* */
|
||||
/* This file handles all global OMIT commands, and maintains */
|
||||
/* the data structures for OMITted dates. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: omit.c,v 1.1 1996-03-27 03:26:04 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
PRIVATE int BexistsIntArray ARGS ((int array[], int num, int key));
|
||||
PRIVATE void InsertIntoSortedArray ARGS ((int *array, int num, int key));
|
||||
|
||||
/* Arrays for the global omits */
|
||||
static int FullOmitArray[MAX_FULL_OMITS];
|
||||
static int PartialOmitArray[MAX_PARTIAL_OMITS];
|
||||
|
||||
/* How many of each omit types do we have? */
|
||||
static int NumFullOmits, NumPartialOmits;
|
||||
|
||||
/* The structure for saving and restoring OMIT contexts */
|
||||
typedef struct omitcontext {
|
||||
struct omitcontext *next;
|
||||
int numfull, numpart;
|
||||
int *fullsave;
|
||||
int *partsave;
|
||||
} OmitContext;
|
||||
|
||||
/* The stack of saved omit contexts */
|
||||
static OmitContext *SavedOmitContexts = NULL;
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ClearGlobalOmits */
|
||||
/* */
|
||||
/* Clear all the global OMIT context. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int ClearGlobalOmits(void)
|
||||
#else
|
||||
int ClearGlobalOmits()
|
||||
#endif
|
||||
{
|
||||
NumFullOmits = NumPartialOmits = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoClear */
|
||||
/* */
|
||||
/* The command-line function CLEAR-OMIT-CONTEXT */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoClear(ParsePtr p)
|
||||
#else
|
||||
int DoClear(p)
|
||||
ParsePtr p;
|
||||
#endif
|
||||
{
|
||||
ClearGlobalOmits();
|
||||
return VerifyEoln(p);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DestroyOmitContexts */
|
||||
/* */
|
||||
/* Free all the memory used by saved OMIT contexts. */
|
||||
/* As a side effect, return the number of OMIT contexts */
|
||||
/* destroyed. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DestroyOmitContexts(void)
|
||||
#else
|
||||
int DestroyOmitContexts()
|
||||
#endif
|
||||
{
|
||||
OmitContext *c = SavedOmitContexts;
|
||||
OmitContext *d;
|
||||
int num = 0;
|
||||
|
||||
while (c) {
|
||||
num++;
|
||||
if (c->fullsave) free(c->fullsave);
|
||||
if (c->partsave) free(c->partsave);
|
||||
d = c->next;
|
||||
free(c);
|
||||
c = d;
|
||||
}
|
||||
SavedOmitContexts = NULL;
|
||||
return num;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* PushOmitContext */
|
||||
/* */
|
||||
/* Push the OMIT context on to the stack. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int PushOmitContext(ParsePtr p)
|
||||
#else
|
||||
int PushOmitContext(p)
|
||||
ParsePtr p;
|
||||
#endif
|
||||
{
|
||||
register int i;
|
||||
OmitContext *context;
|
||||
|
||||
/* Create the saved context */
|
||||
context = NEW(OmitContext);
|
||||
if (!context) return E_NO_MEM;
|
||||
|
||||
context->numfull = NumFullOmits;
|
||||
context->numpart = NumPartialOmits;
|
||||
context->fullsave = (int *) malloc(NumFullOmits * sizeof(int));
|
||||
if (NumFullOmits && !context->fullsave) {
|
||||
free(context);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
context->partsave = (int *) 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];
|
||||
|
||||
for (i=0; i<NumPartialOmits; i++)
|
||||
*(context->partsave + i) = PartialOmitArray[i];
|
||||
|
||||
/* Add the context to the stack */
|
||||
context->next = SavedOmitContexts;
|
||||
SavedOmitContexts = context;
|
||||
return VerifyEoln(p);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* PopOmitContext */
|
||||
/* */
|
||||
/* Pop the OMIT context off of the stack. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int PopOmitContext(ParsePtr p)
|
||||
#else
|
||||
int PopOmitContext(p)
|
||||
ParsePtr p;
|
||||
#endif
|
||||
{
|
||||
|
||||
register int i;
|
||||
OmitContext *c = SavedOmitContexts;
|
||||
|
||||
if (!c) return E_POP_NO_PUSH;
|
||||
NumFullOmits = c->numfull;
|
||||
NumPartialOmits = c->numpart;
|
||||
|
||||
/* Copy the context over */
|
||||
for (i=0; i<NumFullOmits; i++)
|
||||
FullOmitArray[i] = *(c->fullsave + i);
|
||||
|
||||
for (i=0; i<NumPartialOmits; i++)
|
||||
PartialOmitArray[i] = *(c->partsave + i);
|
||||
|
||||
/* Remove the context from the stack */
|
||||
SavedOmitContexts = c->next;
|
||||
|
||||
/* Free memory used by the saved context */
|
||||
if (c->partsave) free(c->partsave);
|
||||
if (c->fullsave) free(c->fullsave);
|
||||
free(c);
|
||||
|
||||
return VerifyEoln(p);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* IsOmitted */
|
||||
/* */
|
||||
/* Return non-zero if date is OMITted, zero if it is not. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int IsOmitted(int jul, int localomit)
|
||||
#else
|
||||
int IsOmitted(jul, localomit)
|
||||
int jul, localomit;
|
||||
#endif
|
||||
{
|
||||
int y, m, d;
|
||||
|
||||
/* Is it omitted because of local omits? */
|
||||
if (localomit & (1 << (jul % 7))) return 1;
|
||||
|
||||
/* Is it omitted because of fully-specified omits? */
|
||||
if (BexistsIntArray(FullOmitArray, NumFullOmits, jul)) return 1;
|
||||
|
||||
/* Get the syndrome */
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
if (BexistsIntArray(PartialOmitArray, NumPartialOmits, (m << 5) + d))
|
||||
return 1;
|
||||
|
||||
/* Not omitted */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* BexistsIntArray */
|
||||
/* */
|
||||
/* Perform a binary search on an integer array. Return 1 if */
|
||||
/* element is found, 0 otherwise. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int BexistsIntArray(int array[], int num, int key)
|
||||
#else
|
||||
static int BexistsIntArray(array, num, key)
|
||||
int array[], num, key;
|
||||
#endif
|
||||
{
|
||||
int top=num-1, bot=0, mid;
|
||||
|
||||
while (top >= bot) {
|
||||
mid = (top+bot)/2;
|
||||
if (array[mid] == key) return 1;
|
||||
else if (array[mid] > key) top = mid-1;
|
||||
else bot=mid+1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* InsertIntoSortedArray */
|
||||
/* */
|
||||
/* Insert a key into a sorted array. We assume that there is */
|
||||
/* room in the array for it. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void InsertIntoSortedArray(int *array, int num, int key)
|
||||
#else
|
||||
static void InsertIntoSortedArray(array, num, key)
|
||||
int *array, num, key;
|
||||
#endif
|
||||
{
|
||||
/* num is number of elements CURRENTLY in the array. */
|
||||
int *cur = array+num;
|
||||
|
||||
while (cur > array && *(cur-1) > key) {
|
||||
*cur = *(cur-1);
|
||||
cur--;
|
||||
}
|
||||
*cur = key;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoOmit */
|
||||
/* */
|
||||
/* Do a global OMIT command. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoOmit(ParsePtr p)
|
||||
#else
|
||||
int DoOmit(p)
|
||||
ParsePtr p;
|
||||
#endif
|
||||
{
|
||||
int y = NO_YR, m = NO_MON, d = NO_DAY, r;
|
||||
Token tok;
|
||||
int parsing=1;
|
||||
int syndrome;
|
||||
|
||||
/* Parse the OMIT. We need a month and day; year is optional. */
|
||||
while(parsing) {
|
||||
if ( (r=ParseToken(p, TokBuffer)) ) return r;
|
||||
FindToken(TokBuffer, &tok);
|
||||
switch (tok.type) {
|
||||
case T_Year:
|
||||
if (y != NO_YR) return E_YR_TWICE;
|
||||
y = tok.val;
|
||||
break;
|
||||
|
||||
case T_Month:
|
||||
if (m != NO_MON) return E_MON_TWICE;
|
||||
m = tok.val;
|
||||
break;
|
||||
|
||||
case T_Day:
|
||||
if (d != NO_DAY) return E_DAY_TWICE;
|
||||
d = tok.val;
|
||||
break;
|
||||
|
||||
case T_Delta:
|
||||
break;
|
||||
|
||||
case T_Empty:
|
||||
case T_Comment:
|
||||
case T_RemType:
|
||||
case T_Priority:
|
||||
parsing = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
Eprint("%s: '%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN], TokBuffer);
|
||||
return E_UNKNOWN_TOKEN;
|
||||
}
|
||||
}
|
||||
if (m == NO_MON || d == NO_DAY) return E_SPEC_MON_DAY;
|
||||
|
||||
if (y == NO_YR) {
|
||||
if (NumPartialOmits == MAX_PARTIAL_OMITS) return E_2MANY_PART;
|
||||
|
||||
if (d > MonthDays[m]) return E_BAD_DATE;
|
||||
syndrome = (m<<5) + d;
|
||||
if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
|
||||
InsertIntoSortedArray(PartialOmitArray, NumPartialOmits, syndrome);
|
||||
NumPartialOmits++;
|
||||
}
|
||||
} else {
|
||||
if (NumFullOmits == MAX_FULL_OMITS) return E_2MANY_FULL;
|
||||
|
||||
if (d > DaysInMonth(m, y)) return E_BAD_DATE;
|
||||
syndrome = Julian(y, m, d);
|
||||
if (!BexistsIntArray(FullOmitArray, NumFullOmits, syndrome)) {
|
||||
InsertIntoSortedArray(FullOmitArray, NumFullOmits, syndrome);
|
||||
NumFullOmits++;
|
||||
}
|
||||
}
|
||||
if (tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
|
||||
return OK;
|
||||
|
||||
}
|
||||
158
os2func.c
Normal file
158
os2func.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* 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-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: os2func.c,v 1.1 1996-03-27 03:26:04 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 "config.h"
|
||||
#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
|
||||
|
||||
464
polish.h
Normal file
464
polish.h
Normal file
@@ -0,0 +1,464 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* POLISH.H */
|
||||
/* */
|
||||
/* Support for the Polish language. */
|
||||
/* */
|
||||
/* This file was submitted by Jerzy Sobczyk. I don't */
|
||||
/* guarantee that there are no mistakes - I don't speak */
|
||||
/* Polish. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: polish.h,v 1.1 1996-03-27 03:26:05 dfs Exp $ */
|
||||
|
||||
/* The very first define in a language support file must be L_LANGNAME: */
|
||||
#define L_LANGNAME "Polish"
|
||||
|
||||
/* Day names */
|
||||
#ifdef ISOLATIN1
|
||||
# define L_SUNDAY "Niedziela"
|
||||
# define L_MONDAY "Poniedzia\263ek"
|
||||
# define L_TUESDAY "Wtorek"
|
||||
# define L_WEDNESDAY "\246roda"
|
||||
# define L_THURSDAY "Czwartek"
|
||||
# define L_FRIDAY "Pi\261tek"
|
||||
# define L_SATURDAY "Sobota"
|
||||
#else
|
||||
# define L_SUNDAY "Niedziela"
|
||||
# define L_MONDAY "Poniedzialek"
|
||||
# define L_TUESDAY "Wtorek"
|
||||
# define L_WEDNESDAY "Sroda"
|
||||
# define L_THURSDAY "Czwartek"
|
||||
# define L_FRIDAY "Piatek"
|
||||
# define L_SATURDAY "Sobota"
|
||||
#endif
|
||||
|
||||
/* Day initials - first letter only */
|
||||
#ifdef ISOLATIN1
|
||||
#define L_DAYINIT "NPW\246CPS"
|
||||
#else
|
||||
#define L_DAYINIT "NPWSCPS"
|
||||
#endif
|
||||
|
||||
/* Month names */
|
||||
#ifdef ISOLATIN1
|
||||
# define L_JAN "Stycze\361"
|
||||
# define L_FEB "Luty"
|
||||
# define L_MAR "Marzec"
|
||||
# define L_APR "Kwiecie\361"
|
||||
# define L_MAY "Maj"
|
||||
# define L_JUN "Czerwiec"
|
||||
# define L_JUL "Lipiec"
|
||||
# define L_AUG "Sierpie\361"
|
||||
# define L_SEP "Wrzesie\361"
|
||||
# define L_OCT "Pa\274dziernik"
|
||||
# define L_NOV "Listopad"
|
||||
# define L_DEC "Grudzie\361"
|
||||
#else
|
||||
# define L_JAN "Styczen"
|
||||
# define L_FEB "Luty"
|
||||
# define L_MAR "Marzec"
|
||||
# define L_APR "Kwiecien"
|
||||
# define L_MAY "Maj"
|
||||
# define L_JUN "Czerwiec"
|
||||
# define L_JUL "Lipiec"
|
||||
# define L_AUG "Sierpien"
|
||||
# define L_SEP "Wrzesien"
|
||||
# define L_OCT "Pazdziernik"
|
||||
# define L_NOV "Listopad"
|
||||
# define L_DEC "Grudzien"
|
||||
#endif
|
||||
|
||||
/* Today and tomorrow */
|
||||
#define L_TODAY "dzisiaj"
|
||||
#define L_TOMORROW "jutro"
|
||||
|
||||
/* The default banner */
|
||||
#define L_BANNER "Terminarz na %w, %d. %m %y%o:"
|
||||
|
||||
/* "am" and "pm" */
|
||||
#define L_AM "am"
|
||||
#define L_PM "pm"
|
||||
|
||||
/*** The following are only used in dosubst.c ***/
|
||||
#ifdef L_IN_DOSUBST
|
||||
|
||||
/* Ago and from now */
|
||||
#define L_AGO "temu"
|
||||
#define L_FROMNOW "od teraz"
|
||||
|
||||
/* "in %d days' time" */
|
||||
#define L_INXDAYS "za %d dni"
|
||||
|
||||
/* "on" as in "on date..." */
|
||||
#define L_ON "-"
|
||||
|
||||
/* Pluralizing - this is a problem for many languages and may require
|
||||
a more drastic fix */
|
||||
#define L_PLURAL ""
|
||||
|
||||
/* Minutes, hours, at, etc */
|
||||
#define L_NOW "teraz"
|
||||
#define L_AT "o"
|
||||
#define L_MINUTE "minut"
|
||||
#define L_HOUR "godzin"
|
||||
#ifdef ISOLATIN1
|
||||
# define L_IS "b\352dzie"
|
||||
# define L_WAS "by\263o"
|
||||
#else
|
||||
# define L_IS "bedzie"
|
||||
# define L_WAS "bylo"
|
||||
#endif
|
||||
#define L_AND "i"
|
||||
/* What to add to make "hour" or "minute" plural */
|
||||
#ifdef ISOLATIN1
|
||||
#define L_NPLU( N ) ((N == 1) ? "\352" : ((N==12) || (N==13) || (N==14)) ? "" : \
|
||||
((N%10==2) || (N%10==3) || (N%10==4)) ? "y" : "" )
|
||||
#else
|
||||
#define L_NPLU( N ) ((N == 1) ? "e" : ((N==12) || (N==13) || (N==14)) ? "" : \
|
||||
((N%10==2) || (N%10==3) || (N%10==4)) ? "y" : "" )
|
||||
#endif
|
||||
/* What to add to make "hour" plural */
|
||||
#define L_HPLU L_NPLU( hdiff )
|
||||
/* What to add to make "minute" plural */
|
||||
#define L_MPLU L_NPLU( mdiff )
|
||||
|
||||
/* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc.
|
||||
See the file dosubst.c for more info. */
|
||||
#ifdef ISOLATIN1
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) \
|
||||
ampm = (hour<12) ? \
|
||||
(hour<5) ? " w nocy" \
|
||||
: (hour<10) ? " rano" \
|
||||
: " przed po\263udniem" \
|
||||
: (hour<18) ? " po po\263udniu" \
|
||||
: (hour<22) ? " wieczorem" \
|
||||
: " w nocy";
|
||||
#else
|
||||
#define L_AMPM_OVERRIDE(ampm, hour) \
|
||||
ampm = (hour<12) ? \
|
||||
(hour<5) ? " w nocy" \
|
||||
: (hour<10) ? " rano" \
|
||||
: " przed poludniem" \
|
||||
: (hour<18) ? " po poludniu" \
|
||||
: (hour<22) ? " wieczorem" \
|
||||
: " 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_U_OVER L_A_OVER
|
||||
#define L_V_OVER L_G_OVER
|
||||
|
||||
#endif /* L_IN_DOSUBST */
|
||||
|
||||
#define L_0_OVER sprintf(s, L_HPLU);
|
||||
#define L_9_OVER sprintf(s, L_MPLU);
|
||||
#define L_1_OVER \
|
||||
if (tdiff == 0) \
|
||||
sprintf(s, L_NOW); \
|
||||
else if (tdiff > 0) \
|
||||
{ \
|
||||
if (hdiff == 0) \
|
||||
sprintf(s, "za %d %s%s", mdiff, L_MINUTE, L_MPLU); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "za %d %s%s", hdiff, L_HOUR, L_HPLU); \
|
||||
else \
|
||||
sprintf(s, "za %d %s%s %s %d %s%s", hdiff, L_HOUR, L_HPLU, \
|
||||
L_AND, mdiff, L_MINUTE, L_MPLU); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (hdiff == 0) \
|
||||
sprintf(s, "%d %s%s temu", mdiff, L_MINUTE, L_MPLU); \
|
||||
else if (mdiff == 0) \
|
||||
sprintf(s, "%d %s%s temu", hdiff, L_HOUR, L_HPLU); \
|
||||
else \
|
||||
sprintf(s, "%d %s%s %s %d %s%s temu", hdiff, L_HOUR, L_HPLU, \
|
||||
L_AND, mdiff, L_MINUTE, L_MPLU); \
|
||||
}
|
||||
|
||||
/* The next ones are used only when MK_GLOBALS is set */
|
||||
#ifdef MK_GLOBALS
|
||||
#define L_ERR_OVERRIDE 1
|
||||
EXTERN char *ErrMsg[] =
|
||||
{
|
||||
#ifdef ISOLATIN1
|
||||
"OK",
|
||||
"Brakuj\261cy ']'",
|
||||
"Brakuj\261cy nawias",
|
||||
"Zbyt skomplikowane wyra\277enie - za du\277o operator\363w",
|
||||
"Zbyt skomplikowane wyra\277enie - za du\277o argument\363w",
|
||||
"Brakuj\261cy ')'",
|
||||
"Nie zdefiniowana funkcja",
|
||||
"Nielegalny znak",
|
||||
"Spodziewany operator binarny",
|
||||
"Brak pami\352ci",
|
||||
"Niepoprawny numer",
|
||||
"Pusty stos operator\363w - b\263\261d wewn\352trzny",
|
||||
"Pusty stos zmiennych - b\263\261d wewn\352trzny",
|
||||
"Niemo\277liwa konwersja",
|
||||
"B\263\261d typu",
|
||||
"Nadmiar daty",
|
||||
"B\263\261d stosu - b\263\261d wewn\352trzny",
|
||||
"Dzielenie przez zero",
|
||||
"Niezdefiniowana zmienna",
|
||||
"Niespodziewany koniec linii",
|
||||
"Niespodziewany koniec pliku",
|
||||
"B\263\261d wejscia/wyjscia",
|
||||
"Za d\263uga linia",
|
||||
"B\263\261d wewn\352trzny",
|
||||
"Z\263a specyfikacja daty",
|
||||
"Za ma\263o argument\363w",
|
||||
"Za du\277o argument\363w",
|
||||
"Nieprawid\263owy czas",
|
||||
"Liczba za du\277a",
|
||||
"Liczba za ma\263a",
|
||||
"Nie mog\352 otworzy\346 pliku",
|
||||
"Zbyt zagnie\277d\277one INCLUDE",
|
||||
"B\263\261d sk\263adniowy",
|
||||
"Nie mog\352 obliczy\346 przypomnienia",
|
||||
"Zbyt zagnie\277d\277one IF",
|
||||
"ELSE bez IF do pary",
|
||||
"ENDIF bez IF do pary",
|
||||
"Nie mog\352 omin\261\346 (OMIT) wszystkich dni",
|
||||
"Niespodziewany wyraz w lini",
|
||||
"POP-OMIT-CONTEXT bez PUSH-OMIT-CONTEXT",
|
||||
"Komenda RUN zablokowana",
|
||||
"B\263\261d dziedziny",
|
||||
"Niepoprawny identyfikator",
|
||||
"Wykryto rekursywne wywo\263anie funkcji",
|
||||
"",
|
||||
"Nie mog\352 zmieni\346 zmiennej systemowej",
|
||||
"Funkcja biblioteki C nie mo\277e reprezentowac daty/czasu",
|
||||
"Pr\363ba redefinicji funkcji wbudowanej",
|
||||
"Nie wolno zagnie\277d\277a\346 definicji funkcji w wyra\277eniu",
|
||||
"Aby u\277yc powt\363rzenia trzeba w pe\263ni wyspecyfikowa\346 dat\352",
|
||||
"Rok podany dw\363krotnie",
|
||||
"Miesi\261c podany dw\363krotnie",
|
||||
"Dzie\361 podany dw\363krotnie",
|
||||
"Nieznane s\263owo",
|
||||
"W komendzie OMIT trzeba poda\346 miesi\261c i dzie\361",
|
||||
"Za du\277o cz\352\266ciowych komend OMIT",
|
||||
"Za du\277o pe\263nych komend OMIT",
|
||||
"Ostrze\277enie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",
|
||||
"B\263\261d odczytu pliku",
|
||||
"Oczekiwany koniec linii",
|
||||
"B\263\352dna data hebrajska",
|
||||
"IIF wymaga nieparzystej liczby argument\363w",
|
||||
"Ostrze\277enie: Brakujacy ENDIF",
|
||||
"Oczekiwany przecinek",
|
||||
"Dzie\361 tygodnia podany dw\363krotnie",
|
||||
"Dozwolone tylko jedno z: BEFORE, AFTER i SKIP",
|
||||
"Nie mo\277na zagnie\277d\277a\346 MSG, MSF, RUN, itp. w wyra\277eniu",
|
||||
"Warto\266\346 powtorzenia podana dw\363krotnie",
|
||||
"Warto\266\346 r\363\277nicy podana dw\363krotnie",
|
||||
"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",
|
||||
"Niekompletna specyfikacja daty",
|
||||
"S\263owo SCANFROM u\277yte dw\363krotnie",
|
||||
"Zmienna",
|
||||
"Warto\266\346",
|
||||
"*NIE ZDEFINIOWANE*",
|
||||
"Pocz\261tek UserFN",
|
||||
"Koniec UserFN",
|
||||
"Przemine\263o",
|
||||
"Niepowodzenie w funkcji fork() - nie mog\352 kolejkowa\346 przypomnie\361",
|
||||
"Nie ma dost\352pu do pliku",
|
||||
"B\263\352dna data systemowa: Rok mniejszy ni\277 %d\n",
|
||||
"Nieznana flaga odpluskwiania '%c'\n",
|
||||
"Nieznana opcja '%c'\n",
|
||||
"Nieznany u\277ytkownik '%s'\n",
|
||||
"Nie mog\352 zmieni\346 gid na %d\n",
|
||||
"Nie mog\352 zmieni\346 uid na %d\n",
|
||||
"Brak pami\352ci na zmienne \266rodowiska\n",
|
||||
"Brak znaku '='",
|
||||
"Brak nazwy zmiennej",
|
||||
"Brak wyra\277enia",
|
||||
"Nie mog\352 zmieni\346 daty dost\352pu pliku %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Brak przypomnie\361.",
|
||||
"%d Przypomnienia zakolejkowane na p\363\274niej.\n",
|
||||
"Spodziewana liczba"
|
||||
#else /* ISOLATIN1 */
|
||||
"OK",
|
||||
"Brakujacy ']'",
|
||||
"Brakujacy nawias",
|
||||
"Zbyt skomplikowane wyrazenie - za duzo operatorow",
|
||||
"Zbyt skomplikowane wyrazenie - za duzo argumentow",
|
||||
"Brakujacy ')'",
|
||||
"Niezdefiniowana funkcja",
|
||||
"Nielegalny znak",
|
||||
"Spodziewany operator binarny",
|
||||
"Brak pamieci",
|
||||
"Niepoprawny numer",
|
||||
"Pusty stos operatorow - blad wewnetrzny",
|
||||
"Pusty stos zmiennych - blad wewnetrzny",
|
||||
"Niemozliwa konwersja",
|
||||
"Blad typu",
|
||||
"Nadmiar daty",
|
||||
"Blad stosu - blad wewnetrzny",
|
||||
"Dzielenie przez zero",
|
||||
"Niezdefiniowana zmienna",
|
||||
"Niespodziewany koniec linii",
|
||||
"Niespodziewany koniec pliku",
|
||||
"Blad wejscia/wyjscia",
|
||||
"Za dluga linia",
|
||||
"Blad wewnetrzny",
|
||||
"Zla specyfikacja daty",
|
||||
"Za malo argumentow",
|
||||
"Za duzo argumentow",
|
||||
"Nieprawidlowy czas",
|
||||
"Liczba za duza",
|
||||
"Liczba za mala",
|
||||
"Nie moge otworzyc pliku",
|
||||
"INCLUDE zbyt zagniezdzone",
|
||||
"Blad skladniowy",
|
||||
"Nie moge obliczyc przypomnienia",
|
||||
"Zbyt zagniezdzone IF",
|
||||
"ELSE bez IF do pary",
|
||||
"ENDIF bez IF do pary",
|
||||
"Nie moge ominac (OMIT) wszystkich dni",
|
||||
"Niespodziewany wyraz w lini",
|
||||
"POP-OMIT-CONTEXT bez PUSH-OMIT-CONTEXT",
|
||||
"Komenda RUN zablokowana",
|
||||
"Blad dziedziny",
|
||||
"Niepoprawny identyfikator",
|
||||
"Wykryto rekursywne wywolanie funkcji",
|
||||
"",
|
||||
"Nie moga zmienic zmiennej systemowej",
|
||||
"Funkcja biblioteki C nie moze reprezentowac daty/czasu",
|
||||
"Proba redefinicji funkcji wbudowanej",
|
||||
"Nie wolno zagniezdzac definicji funkcji w wyrazeniu",
|
||||
"Aby uzyc powtorzenia trzeba w pelni wyspecyfikowac date",
|
||||
"Rok podany dwokrotnie",
|
||||
"Miesiac podany dwokrotnie",
|
||||
"Dzien podany dwokrotnie",
|
||||
"Nieznane slowo",
|
||||
"W komendzie OMIT trzeba podac miesiac i dzien",
|
||||
"Za duzo czesciowych komend OMIT",
|
||||
"Za duzo pelnych komend OMIT",
|
||||
"ostrzezenie: PUSH-OMIT-CONTEXT bez POP-OMIT-CONTEXT",
|
||||
"Blad odczytu pliku",
|
||||
"Oczekiwany koniec linii",
|
||||
"Bledna data hebrajska",
|
||||
"IIF wymaga nieparzystej liczby argumentow",
|
||||
"Ostrzezenie: Brakujacy ENDIF",
|
||||
"Oczekiwany przecinek",
|
||||
"Dzien tygodnia podany dwokrotnie",
|
||||
"Dozwolone tylko jedno z: BEFORE, AFTER i SKIP",
|
||||
"Nie mozna zagniezdzac MSG, MSF, RUN, itp. w wyrazeniu",
|
||||
"Wartosc powtorzenia podana dwokrotnie",
|
||||
"Wartosc roznicy podana dwokrotnie",
|
||||
"Wartosc cofniecia podana dwokrotnie",
|
||||
"Slowo ONCE uzyte dwokrotnie.",
|
||||
"Po AT oczekiwany jest czas",
|
||||
"Slowo UNTIL uzyte dwokrotnie",
|
||||
"Niekompletna specyfikacja daty",
|
||||
"Slowo SCANFROM uzyte dwokrotnie",
|
||||
"Zmienna",
|
||||
"Wartosc",
|
||||
"*UNDEFINED*",
|
||||
"Poczatek UserFN",
|
||||
"Koniec UserFN",
|
||||
"Przeminelo",
|
||||
"niepowodzenie w funkcji fork() - nie moge kolejkowac przypomnien",
|
||||
"Nie ma dostepu do pliku",
|
||||
"Bledna data systemowa: Rok mniejszy niz %d\n",
|
||||
"Nieznana flaga odpluskwiania '%c'\n",
|
||||
"Nieznana opcja '%c'\n",
|
||||
"Nieznany uzytkownik '%s'\n",
|
||||
"Nie moge zmienic gid na %d\n",
|
||||
"Nie moge zmienic uid na %d\n",
|
||||
"Brak pamieci na zmienne srodowiska\n",
|
||||
"Brak znaku '='",
|
||||
"Brak nazwy zmiennej",
|
||||
"Brak wyrazenia",
|
||||
"Nie moge zmienic daty dostepu pliku %s\n",
|
||||
"Remind: '-i' option: %s\n",
|
||||
"Brak przypomnien.",
|
||||
"%d Przypomnienia zakolejkowane na pozniej.\n",
|
||||
"Spodziewana liczba"
|
||||
#endif /* ISOLATIN1 */
|
||||
};
|
||||
#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 */
|
||||
{
|
||||
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1996 by David F. Skoll\n", VERSION, L_LANGNAME);
|
||||
#ifdef BETA
|
||||
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
|
||||
#endif
|
||||
#ifdef ISOLATIN1
|
||||
fprintf(ErrFp, "\nSpos\363b u\277ycia: remind [opcje] plik [data] [czas] [*powt\363rzenie]\n");
|
||||
fprintf(ErrFp, "Opcje:\n");
|
||||
fprintf(ErrFp, " -n Wypisz nast\352pne przypomnienia w prostym formacie\n");
|
||||
fprintf(ErrFp, " -r Zablokuj dyrektywy RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Wypisz kalendarz na n (domy\266lnie 1) miesi\352cy\n");
|
||||
fprintf(ErrFp, " -c+[n] Wypisz kalendarz na n (domy\266lnie 1) tygodni\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Ustaw szeroko\266\346, wype\263nienie i odst\352py w kalendarzu\n");
|
||||
fprintf(ErrFp, " -s[+][n] Wypisz uproszczony kalendarz na n (1) miesi\352cy (tygodni)\n");
|
||||
fprintf(ErrFp, " -p[n] To samo co -s, ale kompatybilne z rem2ps\n");
|
||||
fprintf(ErrFp, " -v Obszerniejsze komentarze\n");
|
||||
fprintf(ErrFp, " -o Ignoruj instrukcje ONCE\n");
|
||||
fprintf(ErrFp, " -t Odpal wszystkie przysz\263e przypomnienia niezale\277nie od delty\n");
|
||||
fprintf(ErrFp, " -h Praca bezszmerowa\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a Nie odpalaj przyponie\361 czasowych - kolejkuj je\n");
|
||||
fprintf(ErrFp, " -q Nie kolejkuj przyponie\361 czasowych\n");
|
||||
fprintf(ErrFp, " -f Nie przechod\274 do pracy w tle\n");
|
||||
fprintf(ErrFp, " -z[n] Pracuj jako demon, budz\261c si\352 co n (5) minut\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Odpluskwianie: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Komunikaty o b\263\352dach skieruj na stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=\277aden\n");
|
||||
fprintf(ErrFp, " -x[n] Limit powt\363rze\361 klauzuli SATISFY (domy\266lnie=150)\n");
|
||||
fprintf(ErrFp, " -kcmd Wywo\263aj 'cmd' dla przypomnie\361 typu MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia wed\263ug daty, czasu i priorytetu\n");
|
||||
fprintf(ErrFp, " -ivar=val Zainicjuj zmienn\261 var warto\266cia val i zachowaj ja\n");
|
||||
fprintf(ErrFp, " -m Rozpocznij kalendarz od poniedzia\263ku zamiast od niedzieli\n");
|
||||
#else /* ISOLATIN1 */
|
||||
fprintf(ErrFp, "\nSposob uzycia: remind [opcje] plik [data] [czas] [*powtorzenie]\n");
|
||||
fprintf(ErrFp, "Opcje:\n");
|
||||
fprintf(ErrFp, " -n Wypisz nastepne przypomnienia w prostym formacie\n");
|
||||
fprintf(ErrFp, " -r Zablokuj dyrektywy RUN\n");
|
||||
fprintf(ErrFp, " -c[n] Wypisz kalendarz na n (domyslnie 1) miesiecy\n");
|
||||
fprintf(ErrFp, " -c+[n] Wypisz kalendarz na n (domyslnie 1) tygodni\n");
|
||||
fprintf(ErrFp, " -w[n[,p[,s]]] Ustaw szerokosc, wypelnienie i odstepy w kalendarzu\n");
|
||||
fprintf(ErrFp, " -s[+][n] Wypisz uproszczony kalendarz na n (1) miesiecy (tygodni)\n");
|
||||
fprintf(ErrFp, " -p[n] To samo co -s, ale kompatybilne z rem2ps\n");
|
||||
fprintf(ErrFp, " -v Obszerniejsze komentarze\n");
|
||||
fprintf(ErrFp, " -o Ignoruj instrukcje ONCE\n");
|
||||
fprintf(ErrFp, " -t Odpal wszystkie przyszle przypomnienia niezaleznie od delty\n");
|
||||
fprintf(ErrFp, " -h Praca bezszmerowa\n");
|
||||
#ifdef HAVE_QUEUED
|
||||
fprintf(ErrFp, " -a Nie odpalaj przyponien czasowych - kolejkuj je\n");
|
||||
fprintf(ErrFp, " -q Nie kolejkuj przyponien czasowych\n");
|
||||
fprintf(ErrFp, " -f Nie przechodz do pracy w tle\n");
|
||||
fprintf(ErrFp, " -z[n] Pracuj jako demon, budzac sie co n (5) minut\n");
|
||||
#endif
|
||||
fprintf(ErrFp, " -d... Odpluskwianie: e=echo x=expr-eval t=trig v=dumpvars l=showline\n");
|
||||
fprintf(ErrFp, " -e Komunikaty o bledach skieruj na stdout\n");
|
||||
fprintf(ErrFp, " -b[n] Format czasu: 0=am/pm, 1=24godz., 2=zaden\n");
|
||||
fprintf(ErrFp, " -x[n] Limit powtorzen klauzuli SATISFY (domyslnie=150)\n");
|
||||
fprintf(ErrFp, " -kcmd Wywolaj 'cmd' dla przypomnien typu MSG\n");
|
||||
fprintf(ErrFp, " -g[ddd] Sortuj przypomnienia wedlug daty, czasu i priorytetu\n");
|
||||
fprintf(ErrFp, " -ivar=val Zainicjuj zmienna var wartoscia val i zachowaj ja\n");
|
||||
fprintf(ErrFp, " -m Rozpocznij kalendarz od poniedzialku zamiast od niedzieli\n");
|
||||
#endif /* ISOLATIN1 */
|
||||
exit(1);
|
||||
}
|
||||
#endif /* L_IN_INIT */
|
||||
171
protos.h
Normal file
171
protos.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* PROTOS.H */
|
||||
/* */
|
||||
/* Function Prototypes. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: protos.h,v 1.1 1996-03-27 03:26:05 dfs Exp $ */
|
||||
|
||||
#ifdef HAVE_PROTOS
|
||||
#define ARGS(x) x
|
||||
#else
|
||||
#define ARGS(x) ()
|
||||
#endif
|
||||
|
||||
/* 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)))
|
||||
|
||||
#ifdef NO_STRSTR
|
||||
char *strstr ARGS ((char *s1, char *s2));
|
||||
#endif
|
||||
|
||||
int CallUserFunc ARGS ((char *name, int nargs));
|
||||
int DoFset ARGS ((ParsePtr p));
|
||||
void ProduceCalendar ARGS ((void));
|
||||
char *SimpleTime ARGS ((int tim, char *out));
|
||||
int DoRem ARGS ((ParsePtr p));
|
||||
int DoFlush ARGS ((ParsePtr p));
|
||||
void DoExit ARGS ((ParsePtr p));
|
||||
int ParseRem ARGS ((ParsePtr s, Trigger *trig, TimeTrig *tim));
|
||||
#ifdef OS2_POPUP
|
||||
int TriggerReminder ARGS ((ParsePtr p, Trigger *t, TimeTrig *tim, int jul,
|
||||
int AsPopUp));
|
||||
#else
|
||||
int TriggerReminder ARGS ((ParsePtr p, Trigger *t, TimeTrig *tim, int jul));
|
||||
#endif
|
||||
int ShouldTriggerReminder ARGS ((Trigger *t, TimeTrig *tim, int jul));
|
||||
int DoSubst ARGS ((ParsePtr p, char *out, Trigger *t, TimeTrig *tt, int jul, int mode));
|
||||
int DoSubstFromString ARGS ((char *source, char *dest, int jul, int tim));
|
||||
int EvalExpr ARGS ((char **e, Value *v));
|
||||
int DoCoerce ARGS ((char type, Value *v));
|
||||
void PrintValue ARGS ((Value *v, FILE *fp));
|
||||
int CopyValue ARGS ((Value *dest, const Value *src));
|
||||
int ReadLine ARGS ((void));
|
||||
int OpenFile ARGS ((const char *fname));
|
||||
int PopFile ARGS ((void));
|
||||
int DoInclude ARGS ((ParsePtr p));
|
||||
int IncludeFile ARGS ((const char *fname));
|
||||
int GetAccessDate ARGS ((char *file));
|
||||
int SetAccessDate ARGS ((char *fname, int jul));
|
||||
int TopLevel ARGS ((void));
|
||||
int CallFunc ARGS ((Operator *f, int nargs));
|
||||
void InitRemind ARGS ((int argc, char *argv[]));
|
||||
void Usage ARGS ((void));
|
||||
int main ARGS ((int argc, char *argv[]));
|
||||
int Julian ARGS ((int year, int month, int day));
|
||||
void FromJulian ARGS ((int jul, int *y, int *m, int *d));
|
||||
int ParseChar ARGS ((ParsePtr p, int *err, int peek));
|
||||
int ParseToken ARGS ((ParsePtr p, char *out));
|
||||
int ParseIdentifier ARGS ((ParsePtr p, char *out));
|
||||
int EvaluateExpr ARGS ((ParsePtr p, Value *v));
|
||||
int Evaluate ARGS ((char **s, Var *locals));
|
||||
int FnPopValStack ARGS ((Value *val));
|
||||
void Eprint ARGS ((const char *fmt, ...));
|
||||
void OutputLine ARGS ((FILE *fp));
|
||||
void CreateParser ARGS ((char *s, ParsePtr p));
|
||||
void DestroyParser ARGS ((ParsePtr p));
|
||||
void PushToken ARGS ((const char *tok));
|
||||
long SystemTime ARGS ((int realtime));
|
||||
int SystemDate ARGS ((int *y, int *m, int *d));
|
||||
int DoIf ARGS ((ParsePtr p));
|
||||
int DoElse ARGS ((ParsePtr p));
|
||||
int DoEndif ARGS ((ParsePtr p));
|
||||
int DoIfTrig ARGS ((ParsePtr p));
|
||||
int ShouldIgnoreLine ARGS ((void));
|
||||
int VerifyEoln ARGS ((ParsePtr p));
|
||||
int DoDebug ARGS ((ParsePtr p));
|
||||
int DoBanner ARGS ((ParsePtr p));
|
||||
int DoRun ARGS ((ParsePtr p));
|
||||
int DoErrMsg ARGS ((ParsePtr p));
|
||||
int ClearGlobalOmits ARGS ((void));
|
||||
int DoClear ARGS ((ParsePtr p));
|
||||
int DestroyOmitContexts ARGS ((void));
|
||||
int PushOmitContext ARGS ((ParsePtr p));
|
||||
int PopOmitContext ARGS ((ParsePtr p));
|
||||
int IsOmitted ARGS ((int jul, int localomit));
|
||||
int DoOmit ARGS ((ParsePtr p));
|
||||
int QueueReminder ARGS ((ParsePtr p, int typ, TimeTrig *tim, const char *sched));
|
||||
void HandleQueuedReminders ARGS ((void));
|
||||
char *FindInitialToken ARGS ((Token *tok, char *s));
|
||||
void FindToken ARGS ((const char *s, Token *tok));
|
||||
void FindNumericToken ARGS ((const char *s, Token *t));
|
||||
int ComputeTrigger ARGS ((int today, Trigger *trig, int *err));
|
||||
char *StrnCpy ARGS ((char *dest, const char *source, int n));
|
||||
int StrMatch ARGS ((const char *s1, const char *s2, int n));
|
||||
int StrinCmp ARGS ((const char *s1, const char *s2, int n));
|
||||
char *StrDup ARGS ((const char *s));
|
||||
int StrCmpi ARGS ((const char *s1, const char *s2));
|
||||
Var *FindVar ARGS ((const char *str, int create));
|
||||
int DeleteVar ARGS ((const char *str));
|
||||
int SetVar ARGS ((const char *str, Value *val));
|
||||
int GetVarValue ARGS ((const char *str, Value *val, Var *locals));
|
||||
int DoSet ARGS ((Parser *p));
|
||||
int DoUnset ARGS ((Parser *p));
|
||||
int DoDump ARGS ((ParsePtr p));
|
||||
void DumpVarTable ARGS ((void));
|
||||
void DestroyVars ARGS ((int all));
|
||||
int PreserveVar ARGS ((char *name));
|
||||
int DoPreserve ARGS ((Parser *p));
|
||||
int DoSatRemind ARGS ((Trigger *trig, TimeTrig *tim, ParsePtr p));
|
||||
void DoMsgCommand ARGS ((char *cmd, char *msg));
|
||||
int ParseNonSpaceChar ARGS ((ParsePtr p, int *err, int peek));
|
||||
unsigned int HashVal ARGS ((const char *str));
|
||||
int DateOK ARGS ((int y, int m, int d));
|
||||
Operator *FindFunc ARGS ((char *name, Operator where[], int num));
|
||||
int InsertIntoSortBuffer ARGS ((int jul, int tim, char *body, int typ, int prio));
|
||||
void IssueSortedReminders ARGS ((void));
|
||||
int UserFuncExists ARGS ((char *fn));
|
||||
void JulToHeb ARGS((int jul, int *hy, int *hm, int *hd));
|
||||
int HebNameToNum ARGS((const char *mname));
|
||||
char *HebMonthName ARGS((int m, int y));
|
||||
int RoshHashana ARGS((int i));
|
||||
long DaysToHebYear ARGS((int y));
|
||||
int DaysInHebYear ARGS((int y));
|
||||
char *DaysInHebMonths ARGS((int ylen));
|
||||
int HebToJul ARGS((int hy, int hm, int hd));
|
||||
int GetValidHebDate ARGS((int yin, int min, int din, int adarbehave, int *mout, int *dout, int yahr));
|
||||
int GetNextHebrewDate ARGS((int julstart, int hm, int hd, int yahr, int adarbehave, int *ans));
|
||||
int ComputeJahr ARGS ((int y, int m, int d, int *ans));
|
||||
int GetSysVar ARGS ((const char *name, Value *val));
|
||||
int SetSysVar ARGS ((const char *name, Value *val));
|
||||
void DumpSysVarByName ARGS ((const char *name));
|
||||
int CalcMinsFromUTC ARGS ((int jul, int tim, int *mins, int *isdst));
|
||||
#ifdef OS2_POPUP
|
||||
void FillParagraph ARGS ((char *s, int AsPopUp));
|
||||
#else
|
||||
void FillParagraph ARGS ((char *s));
|
||||
#endif
|
||||
void LocalToUTC ARGS ((int locdate, int loctime, int *utcdate, int *utctime));
|
||||
void UTCToLocal ARGS ((int utcdate, int utctime, int *locdate, int *loctime));
|
||||
int MoonPhase ARGS ((int date, int time));
|
||||
void HuntPhase ARGS ((int startdate, int starttim, int phas, int *date, int *time));
|
||||
int CompareRems ARGS ((int dat1, int tim1, int prio1, int dat2, int tim2, int prio2, int bydate, int bytime, int byprio));
|
||||
#ifdef __BORLANDC__
|
||||
void __cdecl SigIntHandler ARGS ((int d));
|
||||
#else
|
||||
#ifdef SIGHANDLER_INT_ARG
|
||||
void SigIntHandler ARGS ((int d));
|
||||
#else
|
||||
void SigIntHandler ARGS ((void));
|
||||
#endif
|
||||
#endif
|
||||
void GotSigInt ARGS ((void));
|
||||
|
||||
#if defined(__OS2__)
|
||||
int fork ARGS ((void));
|
||||
#if defined(OS2_POPUP)
|
||||
void StartPopUp ARGS ((void));
|
||||
void EndPopUp ARGS ((void));
|
||||
int PutcPopUp ARGS ((int c));
|
||||
int PutlPopUp ARGS ((char *s));
|
||||
int PutsPopUp ARGS ((char *s));
|
||||
#endif
|
||||
#endif
|
||||
412
queue.c
Normal file
412
queue.c
Normal file
@@ -0,0 +1,412 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* QUEUE.C */
|
||||
/* */
|
||||
/* Queue up reminders for subsequent execution. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: queue.c,v 1.1 1996-03-27 03:26:05 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* We only want object code generated if we have queued reminders */
|
||||
#ifdef HAVE_QUEUED
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(__OS2__) || defined(__MSDOS__)
|
||||
#include <io.h>
|
||||
#if defined(__BORLANDC__)
|
||||
#include <dos.h>
|
||||
#endif
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
|
||||
/* List structure for holding queued reminders */
|
||||
typedef struct queuedrem {
|
||||
struct queuedrem *next;
|
||||
int typ;
|
||||
int RunDisabled;
|
||||
int ntrig;
|
||||
char *text;
|
||||
char sched[VAR_NAME_LEN+1];
|
||||
TimeTrig tt;
|
||||
} QueuedRem;
|
||||
|
||||
/* Global variables */
|
||||
|
||||
static QueuedRem *QueueHead;
|
||||
static time_t FileModTime;
|
||||
static struct stat StatBuf;
|
||||
|
||||
PRIVATE void CheckInitialFile ARGS ((void));
|
||||
PRIVATE int CalculateNextTime ARGS ((QueuedRem *q));
|
||||
PRIVATE QueuedRem *FindNextReminder ARGS ((void));
|
||||
PRIVATE int CalculateNextTimeUsingSched ARGS ((QueuedRem *q));
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* QueueReminder */
|
||||
/* */
|
||||
/* Put the reminder on a queue for later, if queueing is */
|
||||
/* enabled. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int QueueReminder(ParsePtr p, int typ, TimeTrig *tim, const char *sched)
|
||||
#else
|
||||
int QueueReminder(p, typ, tim, sched)
|
||||
ParsePtr p;
|
||||
int typ;
|
||||
TimeTrig *tim;
|
||||
char *sched;
|
||||
#endif
|
||||
{
|
||||
QueuedRem *qelem;
|
||||
|
||||
if (DontQueue ||
|
||||
tim->ttime == NO_TIME ||
|
||||
typ == CAL_TYPE ||
|
||||
tim->ttime < SystemTime(0) / 60 ||
|
||||
((typ == RUN_TYPE) && RunDisabled)) return OK;
|
||||
|
||||
qelem = NEW(QueuedRem);
|
||||
if (!qelem) {
|
||||
return E_NO_MEM;
|
||||
}
|
||||
qelem->text = StrDup(p->pos); /* Guaranteed that parser is not nested. */
|
||||
if (!qelem->text) {
|
||||
free(qelem);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
qelem->typ = typ;
|
||||
qelem->tt = *tim;
|
||||
qelem->next = QueueHead;
|
||||
qelem->RunDisabled = RunDisabled;
|
||||
qelem->ntrig = 0;
|
||||
strcpy(qelem->sched, sched);
|
||||
QueueHead = qelem;
|
||||
NumQueued++;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HandleQueuedReminders */
|
||||
/* */
|
||||
/* Handle the issuing of queued reminders in the background */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void HandleQueuedReminders(void)
|
||||
#else
|
||||
void HandleQueuedReminders()
|
||||
#endif
|
||||
{
|
||||
QueuedRem *q = QueueHead;
|
||||
long TimeToSleep;
|
||||
unsigned SleepTime;
|
||||
Parser p;
|
||||
Trigger trig;
|
||||
|
||||
/* Suppress the BANNER from being issued */
|
||||
NumTriggered = 1;
|
||||
|
||||
/* If we are not connected to a tty, then we must close the
|
||||
* standard file descriptors. This is to prevent someone
|
||||
* doing:
|
||||
* remind file | <filter> | >log
|
||||
* and have <filter> hung because the child (us) is still
|
||||
* connected to it. This means the only commands that will be
|
||||
* processed correctly are RUN commands, provided they mail
|
||||
* the result back or use their own resource (as a window).
|
||||
*/
|
||||
if (!DontFork && (!isatty(1) || !isatty(2))) {
|
||||
close(1);
|
||||
close(2);
|
||||
}
|
||||
|
||||
/* If we're a daemon, get the mod time of initial file */
|
||||
if (Daemon) {
|
||||
if (stat(InitialFile, &StatBuf)) {
|
||||
fprintf(ErrFp, "Cannot stat %s - not running as daemon!\n",
|
||||
InitialFile);
|
||||
Daemon = 0;
|
||||
} else FileModTime = StatBuf.st_mtime;
|
||||
}
|
||||
|
||||
/* Initialize the queue - initialize all the entries time of issue */
|
||||
|
||||
while (q) {
|
||||
q->tt.nexttime = (int) (SystemTime(0)/60 - 1);
|
||||
q->tt.nexttime = CalculateNextTime(q);
|
||||
q = q->next;
|
||||
}
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
signal(SIGINT, SigIntHandler);
|
||||
#else
|
||||
if (!DontFork || Daemon) signal(SIGINT, SigIntHandler);
|
||||
#endif
|
||||
|
||||
/* Sit in a loop, issuing reminders when necessary */
|
||||
while(1) {
|
||||
q = FindNextReminder();
|
||||
|
||||
/* If no more reminders to issue, we're done unless we're a daemon. */
|
||||
if (!q && !Daemon) break;
|
||||
|
||||
if (Daemon && !q)
|
||||
TimeToSleep = (long) 60*Daemon;
|
||||
else
|
||||
TimeToSleep = (long) q->tt.nexttime * 60L - SystemTime(0);
|
||||
|
||||
while (TimeToSleep > 0L) {
|
||||
SleepTime = (unsigned) ((TimeToSleep > 30000L) ? 30000 : TimeToSleep);
|
||||
|
||||
if (Daemon && SleepTime > 60*Daemon) SleepTime = 60*Daemon;
|
||||
|
||||
sleep(SleepTime);
|
||||
|
||||
if (Daemon && SleepTime) CheckInitialFile();
|
||||
|
||||
if (Daemon && !q)
|
||||
TimeToSleep = (long) 60*Daemon;
|
||||
else
|
||||
TimeToSleep = (long) q->tt.nexttime * 60L - SystemTime(0);
|
||||
}
|
||||
|
||||
/* Trigger the reminder */
|
||||
CreateParser(q->text, &p);
|
||||
trig.typ = q->typ;
|
||||
RunDisabled = q->RunDisabled;
|
||||
#ifdef OS2_POPUP
|
||||
(void) TriggerReminder(&p, &trig, &q->tt, JulianToday, 1);
|
||||
#else
|
||||
(void) TriggerReminder(&p, &trig, &q->tt, JulianToday);
|
||||
#endif
|
||||
fflush(stdout);
|
||||
|
||||
/* Calculate the next trigger time */
|
||||
q->tt.nexttime = CalculateNextTime(q);
|
||||
}
|
||||
#ifdef __BORLANDC__
|
||||
signal(SIGINT, SIG_DFL);
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* CalculateNextTime */
|
||||
/* */
|
||||
/* Calculate the next time when a reminder should be issued. */
|
||||
/* Return NO_TIME if reminder expired. */
|
||||
/* Strategy is: If a sched() function is defined, call it. */
|
||||
/* Otherwise, use AT time with delta and rep. If sched() */
|
||||
/* fails, revert to AT with delta and rep. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int CalculateNextTime(QueuedRem *q)
|
||||
#else
|
||||
static int CalculateNextTime(q)
|
||||
QueuedRem *q;
|
||||
#endif
|
||||
{
|
||||
int tim = q->tt.ttime;
|
||||
int rep = q->tt.rep;
|
||||
int delta = q->tt.delta;
|
||||
int curtime = q->tt.nexttime+1;
|
||||
int r;
|
||||
|
||||
/* Increment number of times this one has been triggered */
|
||||
q->ntrig++;
|
||||
if (q->sched[0]) {
|
||||
r = CalculateNextTimeUsingSched(q);
|
||||
if (r != NO_TIME) return r;
|
||||
}
|
||||
if (delta == NO_DELTA)
|
||||
if (tim < curtime) return NO_TIME; else return tim;
|
||||
|
||||
tim -= delta;
|
||||
if (rep == NO_REP) rep = delta;
|
||||
if (tim < curtime) tim += ((curtime - tim) / rep) * rep;
|
||||
if (tim < curtime) tim += rep;
|
||||
if (tim > q->tt.ttime) tim = q->tt.ttime;
|
||||
if (tim < curtime) return NO_TIME; else return tim;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindNextReminder */
|
||||
/* */
|
||||
/* Find the next reminder to trigger */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE QueuedRem *FindNextReminder(void)
|
||||
#else
|
||||
static QueuedRem *FindNextReminder()
|
||||
#endif
|
||||
{
|
||||
QueuedRem *q = QueueHead;
|
||||
QueuedRem *ans = NULL;
|
||||
|
||||
while (q) {
|
||||
if (q->tt.nexttime != NO_TIME) {
|
||||
if (!ans) ans = q;
|
||||
else if (q->tt.nexttime < ans->tt.nexttime) ans = q;
|
||||
}
|
||||
|
||||
q = q->next;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GotSigInt */
|
||||
/* */
|
||||
/* Split out what's done on a SIGINT from the SIGINT Handler. */
|
||||
/* This will be necessary for OS/2 multithreaded. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
void GotSigInt(void)
|
||||
#else
|
||||
void GotSigInt()
|
||||
#endif
|
||||
{
|
||||
QueuedRem *q = QueueHead;
|
||||
|
||||
printf("Contents of AT queue:%s", NL);
|
||||
|
||||
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.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")),
|
||||
q->text,
|
||||
NL, NL);
|
||||
}
|
||||
q = q->next;
|
||||
}
|
||||
printf(NL);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* CheckInitialFile */
|
||||
/* */
|
||||
/* If the initial file has been modified, then restart the */
|
||||
/* daemon. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void CheckInitialFile(void)
|
||||
#else
|
||||
static void CheckInitialFile()
|
||||
#endif
|
||||
{
|
||||
/* If date has rolled around, or file has changed, spawn a new version. */
|
||||
time_t tim = FileModTime;
|
||||
int y, m, d;
|
||||
|
||||
if (stat(InitialFile, &StatBuf) == 0) tim = StatBuf.st_mtime;
|
||||
if (tim != FileModTime ||
|
||||
RealToday != SystemDate(&y, &m, &d))
|
||||
execvp(ArgV[0], ArgV);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* CalculateNextTimeUsingSched */
|
||||
/* */
|
||||
/* Call the scheduling function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int CalculateNextTimeUsingSched(QueuedRem *q)
|
||||
#else
|
||||
static int CalculateNextTimeUsingSched(q)
|
||||
QueuedRem *q;
|
||||
#endif
|
||||
{
|
||||
/* Use LineBuffer for temp. string storage. */
|
||||
int r;
|
||||
Value v;
|
||||
char *s;
|
||||
int LastTime = -1;
|
||||
int ThisTime;
|
||||
|
||||
if (UserFuncExists(q->sched) != 1) {
|
||||
q->sched[0] = 0;
|
||||
return NO_TIME;
|
||||
}
|
||||
|
||||
RunDisabled = q->RunDisabled; /* Don't want weird scheduling functions
|
||||
to be a security hole! */
|
||||
while(1) {
|
||||
sprintf(LineBuffer, "%s(%d)", q->sched, q->ntrig);
|
||||
s = LineBuffer;
|
||||
r = EvalExpr(&s, &v);
|
||||
if (r) {
|
||||
q->sched[0] = 0;
|
||||
return NO_TIME;
|
||||
}
|
||||
if (v.type == TIM_TYPE) {
|
||||
ThisTime = v.v.val;
|
||||
} else if (v.type == INT_TYPE) {
|
||||
if (v.v.val > 0)
|
||||
ThisTime = q->tt.nexttime + v.v.val;
|
||||
else
|
||||
ThisTime = q->tt.ttime + v.v.val;
|
||||
|
||||
} else {
|
||||
DestroyValue(v);
|
||||
q->sched[0] = 0;
|
||||
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 > q->tt.nexttime) return ThisTime;
|
||||
if (ThisTime <= LastTime) {
|
||||
q->sched[0] = 0;
|
||||
return NO_TIME;
|
||||
}
|
||||
LastTime = ThisTime;
|
||||
q->ntrig++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_QUEUED from way at the top */
|
||||
45
rem
Normal file
45
rem
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# rem - by David Skoll - 26 February 1991
|
||||
#
|
||||
# $Id: rem,v 1.1 1996-03-27 03:26:06 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
|
||||
34
rem.1
Normal file
34
rem.1
Normal file
@@ -0,0 +1,34 @@
|
||||
.TH REM 1 "26 February 1991"
|
||||
.UC 4
|
||||
.SH NAME
|
||||
rem \- run 'remind' with a default reminder file
|
||||
.SH SYNOPSIS
|
||||
.B rem
|
||||
[\-F \fIfilename\fR] [\fIremind_options\fR] [\fIremind_params\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)
|
||||
.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
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
David F. Skoll
|
||||
.SH SEE ALSO
|
||||
remind, kall
|
||||
|
||||
319
rem2ps.1
Normal file
319
rem2ps.1
Normal file
@@ -0,0 +1,319 @@
|
||||
.TH REM2PS 1 "2 February 1994"
|
||||
.UC4
|
||||
.SH NAME
|
||||
rem2ps \- draw a PostScript calendar from Remind output
|
||||
.SH SYNOPSIS
|
||||
.B rem2ps [\fIoptions\fR]
|
||||
.SH DESCRIPTION
|
||||
\fBRem2ps\fR reads the standard input, which should be the results of running
|
||||
\fBRemind\fR with the \fB\-p\fR option. It emits PostScript code (which
|
||||
draws a calendar) to the standard output.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-v
|
||||
Be more verbose. This causes \fBRem2ps\fR to print progress messages
|
||||
to the standard error stream. Normally, it is silent.
|
||||
.TP
|
||||
.B \-n
|
||||
Produce a calendar whose first column is Monday (rather than Sunday.)
|
||||
.TP
|
||||
.B \-p file
|
||||
Include the contents of \fIfile\fR in the PostScript prologue. This
|
||||
allows you to define procedures, variables etc. which can be used
|
||||
by the \fBPS\fR and \fBPSFILE\fR reminders. You should not
|
||||
include any document structuring comments in your prologue.
|
||||
.TP
|
||||
.B \-l
|
||||
Produce the calendar in landscape mode rather than the default
|
||||
portrait mode.
|
||||
.TP
|
||||
\fB\-c\fR[\fIn\fR]
|
||||
If \fIn\fR is omitted, disables the small calendars for next and previous
|
||||
months which are normally generated. If \fIn\fR is supplied, it can range
|
||||
from 0 to 3, with the following meanings:
|
||||
.RS
|
||||
.TP
|
||||
.B 0
|
||||
Disable small calendars
|
||||
.TP
|
||||
.B 1
|
||||
Place the small calendars at the bottom-right if there is room; otherwise,
|
||||
place them at the top-left.
|
||||
.TP
|
||||
.B 2
|
||||
Place the small calendars at the top-left if there is room; otherwise,
|
||||
place them at the bottom-right.
|
||||
.TP
|
||||
.B 3
|
||||
Place the previous month's small calendar at the top-left and the next
|
||||
month's at the bottom-right if there is room; otherwise, follow \fIn\fR=1.
|
||||
A moment's thought reveals that an option which splits the calendars if
|
||||
there is room and otherwise follows \fIn\fR=2 yields the same results as
|
||||
\fIn\fR=3.
|
||||
.RE
|
||||
.TP
|
||||
.B \-i
|
||||
Use ISO 8859-1 standard encoding for the PostScript fonts. If you do
|
||||
not use this option, the default encoding is used.
|
||||
.TP
|
||||
.B \-e
|
||||
Make the calendar fill the entire page. By default, the calendar is
|
||||
slightly smaller than the page. This allows days with many reminders
|
||||
to "expand" as needed. However, if you don't have days which expand,
|
||||
you can use this option to make all of the boxes slightly bigger.
|
||||
One caveat: If you do use the \fB\-e\fR option and one day has many
|
||||
reminders, the calendar may expand off the page, losing some information.
|
||||
Experiment!
|
||||
.TP
|
||||
.B \-m media
|
||||
Set the page size. If you use the \-m option, you must specify the
|
||||
media type, which can be one of the
|
||||
following. (Sizes are approximate.)
|
||||
.RS
|
||||
.TP
|
||||
Letter
|
||||
8.5 x 11 in.
|
||||
.TP
|
||||
Legal
|
||||
11 x 17 in.
|
||||
.TP
|
||||
Ledger
|
||||
8.5 x 14 in.
|
||||
.TP
|
||||
Statement
|
||||
5.5 x 8.5 in.
|
||||
.TP
|
||||
Executive
|
||||
7.5 x 10 in.
|
||||
.TP
|
||||
A3
|
||||
29.7 x 42 cm.
|
||||
.TP
|
||||
A4
|
||||
21 x 29.7 cm.
|
||||
.TP
|
||||
A5
|
||||
14.8 x 21 cm.
|
||||
.TP
|
||||
B4
|
||||
25.7 x 36.4 cm.
|
||||
.TP
|
||||
B5
|
||||
18.3 x 25.7 cm.
|
||||
.TP
|
||||
Folio
|
||||
8.5 x 13 in.
|
||||
.TP
|
||||
Quarto
|
||||
8.5 x 10.8 in.
|
||||
.TP
|
||||
10x14
|
||||
10 x 14 in.
|
||||
.PP
|
||||
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"
|
||||
option will display the compiled-in default.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-f\fR[\fBtshed\fR] \fIfont\fR
|
||||
Set the font for the calendar title,
|
||||
the small calendars, the day-of-week headings, the calendar
|
||||
entries, and the day numbers, respectively. \fIFont\fR must be the
|
||||
name of a valid PostScript font. The default fonts are equivalent to
|
||||
specifying:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
-ftshe Helvetica -fd Helvetica-BoldOblique
|
||||
.fi
|
||||
.PP
|
||||
In other words, the heading, entry and small-calendar fonts are set
|
||||
to Helvetica, and the font for the day numbers is set to
|
||||
Helvetica-BoldOblique.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-s\fR[\fBthed\fR] \fIsize\fR
|
||||
Set the size (in points) of the text for the the calendar title,
|
||||
day-of-week headings, the calendar entries, and the day numbers,
|
||||
respectively. \fISize\fR must be a decimal number. The default sizes
|
||||
are equivalent to specifying:
|
||||
.RS
|
||||
.PP
|
||||
.nf
|
||||
-sthd 14 -se 8
|
||||
.fi
|
||||
.PP
|
||||
In other words, the heading and day numbers are 14-point fonts, and the
|
||||
calendar entries are printed in 8-point text.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-b\fR \fIsize\fR
|
||||
Set the size of the blank white border in each calendar box to \fIsize\fR
|
||||
points. The default border size is 6 points, or 1/12 in.
|
||||
.TP
|
||||
\fB\-t\fR \fIsize\fR
|
||||
Set the thickness of the black calendar grid lines. The default is 1,
|
||||
for a line thickness of one point (1/72 in.)
|
||||
.TP
|
||||
\fB\-o\fR[\fBlrtb\fR] \fIsize\fR
|
||||
Set the left, right, top, and/or bottom margins to \fIsize\fR points.
|
||||
For this option only, \fIsize\fR must be an integer. It represents the
|
||||
margin size in units of 1/72 in. The default margin sizes are 36, for
|
||||
half-inch margins. If you wish to punch holes in the calendar page to insert
|
||||
it into a binder, you may wish to increase the left margin to one inch.
|
||||
In that case, you should also decrease the heading font size to 12 points
|
||||
for good output:
|
||||
.PP
|
||||
.nf
|
||||
# This gives good results for putting into a binder
|
||||
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
|
||||
option to \fBRem2ps\fR, and then send the result to a printer. This is most easily
|
||||
illustrated with examples:
|
||||
.PP
|
||||
.nf
|
||||
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
|
||||
.fi
|
||||
.PP
|
||||
This reminder creates a calendar for the current month, filling in
|
||||
entries from the reminder file "~/.reminders." The calendar is produced
|
||||
in landscape mode, with a font size of 18 for the day numbers. The result
|
||||
is put in the PostScript file "cal.ps."
|
||||
.PP
|
||||
.SH VARIABLES AVAILABLE TO USER-SUPPLIED POSTSCRIPT CODE
|
||||
.PP
|
||||
The following variables are available to \fBPS\fR and
|
||||
\fBPSFILE\fR-type reminders. (This material is duplicated
|
||||
in the \fBRemind\fR manual page.)
|
||||
.TP
|
||||
LineWidth
|
||||
The width of the black grid lines making up the calendar.
|
||||
.TP
|
||||
Border
|
||||
The border between the center of the grid lines and the space used to print
|
||||
calendar entries. This border is normally blank space.
|
||||
.TP
|
||||
BoxWidth and BoxHeight
|
||||
The width and height of the calendar box, from center-to-center of the
|
||||
black gridlines.
|
||||
.TP
|
||||
InBoxHeight
|
||||
The height from the center of the bottom black gridline to the top
|
||||
of the regular calendar entry area. The space from here to the top
|
||||
of the box is used only to draw the day number.
|
||||
.TP
|
||||
/DayFont, /TitleFont, /EntryFont, /SmallFont and /HeadFont
|
||||
The fonts used to draw the day numbers, the month and year title,
|
||||
the calendar entries, the small
|
||||
calendars, and the day-of-week headings, respectively.
|
||||
.TP
|
||||
DaySize, TitleSize, EntrySize and HeadSize
|
||||
The sizes of the above fonts. (The size of the small calendar font
|
||||
is \fInot\fR defined here.) For example, if you wanted to print
|
||||
the Hebrew date next to the regular day number in the calendar, use:
|
||||
.PP
|
||||
.nf
|
||||
REM PS Border BoxHeight Border sub DaySize sub moveto \\
|
||||
/DayFont findfont DaySize scalefont setfont \\
|
||||
([hebday(today())] [hebmon(today())]) show
|
||||
.fi
|
||||
.PP
|
||||
.RS
|
||||
Note how /DayFont and DaySize are used.
|
||||
.RE
|
||||
.PP
|
||||
Note that if you supply PostScript code, it is possible to produce invalid
|
||||
PostScript files. Always test your PostScript thoroughly with a PostScript
|
||||
viewer before sending it to the printer. You should not use any document
|
||||
structuring comments in your PostScript code.
|
||||
.PP
|
||||
In addition, prior to drawing a calendar page, \fBRem2ps\fR emits
|
||||
the following PostScript code:
|
||||
.PP
|
||||
.nf
|
||||
save (mon) (yr) PreCal restore
|
||||
.fi
|
||||
.PP
|
||||
where \fImon\fR and \fIyr\fR are the month and year of the calendar
|
||||
page. The default \fBPreCal\fR procedure simply pops
|
||||
the arguments and does nothing. However, you can define a \fBPreCal\fR
|
||||
function in your prologue file to do whatever you want - it can draw a
|
||||
background for the entire calendar, for instance.
|
||||
.PP
|
||||
In the context of the \fBPreCal\fR procedure, the following conditions
|
||||
hold:
|
||||
.TP
|
||||
o
|
||||
The PostScript origin is at the bottom left-hand corner of the page, and
|
||||
PostScript units of 1/72" are in effect.
|
||||
.TP
|
||||
o
|
||||
The variables MinX, MinY, MaxX and MaxY define the bounding box within
|
||||
which the calendar will be drawn.
|
||||
.TP
|
||||
o
|
||||
The font and font-size variables, as well as Border and LineWidth described
|
||||
previously, are valid.
|
||||
.PP
|
||||
For an example, create a file called "myprolog" whose contents are:
|
||||
.PP
|
||||
.nf
|
||||
/PreCal {
|
||||
/yr exch def
|
||||
/mon exch def
|
||||
/xsiz1 MaxX MinX sub def
|
||||
/ysiz1 MaxY MinY sub def
|
||||
/xsiz xsiz1 MinX sub MinX sub def
|
||||
/ysiz ysiz1 MinY sub MinY sub def
|
||||
xsiz
|
||||
ysiz
|
||||
lt
|
||||
{/len xsiz 1.41 mul def
|
||||
MinX MinX add ysiz1 xsiz1 sub 2 div MinY add MinY add moveto}
|
||||
{/len ysiz 1.41 mul def
|
||||
xsiz1 ysiz1 sub 2 div MinX add MinX add MinY MinY add moveto}
|
||||
ifelse
|
||||
/Helvetica-Bold findfont 1 scalefont setfont
|
||||
mon stringwidth pop
|
||||
( ) stringwidth pop add
|
||||
yr stringwidth pop add
|
||||
len exch div /len exch def
|
||||
/Helvetica-Bold findfont len scalefont setfont
|
||||
0.95 setgray
|
||||
45 rotate
|
||||
mon show
|
||||
( ) show
|
||||
yr show
|
||||
} bind def
|
||||
.fi
|
||||
.PP
|
||||
Use that file with the \fBRem2ps\fR \fB\-p\fR option to create calendars
|
||||
with the year and month in large grey letters in the background of the
|
||||
calendar.
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
David F. Skoll
|
||||
.SH BUGS
|
||||
All \fBRem2ps\fR options are case-sensitive, unlike \fBRemind\fR.
|
||||
Any time you supply
|
||||
a font name or size, line thickness, or border width, it is treated as a
|
||||
string and sent straight to the PostScript interpreter. Thus, if you
|
||||
supply invalid fonts or sizes, \fBRem2ps\fR will not complain, but the
|
||||
resulting PostScript output will probably not work.
|
||||
.PP
|
||||
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
|
||||
957
rem2ps.c
Normal file
957
rem2ps.c
Normal file
@@ -0,0 +1,957 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* REM2PS.C */
|
||||
/* */
|
||||
/* Print a PostScript calendar. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: rem2ps.c,v 1.1 1996-03-27 03:26:07 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include "lang.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_UNISTD
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "rem2ps.h"
|
||||
#include "version.h"
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef __TURBOC__
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PROTOS
|
||||
#define ARGS(x) x
|
||||
#else
|
||||
#define ARGS(x) ()
|
||||
#endif
|
||||
#define NEW(type) ((type *) malloc(sizeof(type)))
|
||||
|
||||
typedef struct calentry {
|
||||
struct calentry *next;
|
||||
char *entry;
|
||||
} CalEntry;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int xsize, ysize;
|
||||
} PageType;
|
||||
|
||||
char Days[]=L_DAYINIT;
|
||||
|
||||
char *SmallCalLoc[] = {
|
||||
"",
|
||||
"bt",
|
||||
"tb",
|
||||
"sbt",
|
||||
};
|
||||
|
||||
#define NUMSMALL (sizeof(SmallCalLoc)/sizeof(SmallCalLoc[0]))
|
||||
char *SmallLocation;
|
||||
int SmallCol1, SmallCol2;
|
||||
|
||||
PageType Pages[] =
|
||||
{
|
||||
{"Letter", 612, 792}, /* 8.5 x 11 in. */
|
||||
{"Tabloid", 792, 1224}, /* 11 x 17 in. */
|
||||
{"Ledger", 1224, 792}, /* 17 x 11 in. */
|
||||
{"Legal", 612, 1008}, /* 8.5 x 14 in. */
|
||||
{"Statement", 396, 612}, /* 5.5 x 8.5 in. */
|
||||
{"Executive", 540, 720}, /* 7.5 x 10 in. */
|
||||
{"A3", 842, 1190},
|
||||
{"A4", 595, 842},
|
||||
{"A5", 420, 595},
|
||||
{"B4", 729, 1032},
|
||||
{"B5", 519, 729},
|
||||
{"Folio", 612, 936},
|
||||
{"Quarto", 612, 780},
|
||||
{"10x14", 720, 1008}
|
||||
};
|
||||
|
||||
PageType DefaultPage[1] =
|
||||
{
|
||||
DEFAULT_PAGE
|
||||
};
|
||||
|
||||
#define NUMPAGES (sizeof(Pages)/sizeof(Pages[0]))
|
||||
|
||||
CalEntry *CurEntries = NULL;
|
||||
CalEntry *PsEntries[32];
|
||||
PageType *CurPage;
|
||||
char PortraitMode;
|
||||
char NoSmallCal;
|
||||
char UseISO;
|
||||
|
||||
char LineBuffer[LINELEN];
|
||||
|
||||
char *HeadFont="Helvetica";
|
||||
char *TitleFont="Helvetica";
|
||||
char *DayFont="Helvetica-BoldOblique";
|
||||
char *EntryFont="Helvetica";
|
||||
char *SmallFont="Helvetica";
|
||||
char *LineWidth = "1";
|
||||
|
||||
char *HeadSize="14";
|
||||
char *TitleSize="14";
|
||||
char *DaySize="14";
|
||||
char *EntrySize="8";
|
||||
char *BorderSize = "6";
|
||||
|
||||
char *UserProlog = NULL;
|
||||
|
||||
int validfile = 0;
|
||||
|
||||
int CurDay;
|
||||
int MaxDay;
|
||||
int DayNum;
|
||||
int WkDayNum;
|
||||
int FirstWkDay;
|
||||
int MondayFirst;
|
||||
int LeftMarg, RightMarg, TopMarg, BotMarg;
|
||||
int FillPage;
|
||||
int Verbose = 0;
|
||||
|
||||
void Init ARGS ((int argc, char *argv[]));
|
||||
void Usage ARGS ((char *s));
|
||||
void DoPsCal ARGS ((void));
|
||||
int DoQueuedPs ARGS ((void));
|
||||
void DoSmallCal ARGS((char *m, int days, int first, int col, int which));
|
||||
void WriteProlog ARGS ((void));
|
||||
void WriteCalEntry ARGS ((void));
|
||||
void WriteOneEntry ARGS ((char *s));
|
||||
void GetSmallLocations ARGS ((void));
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* MAIN PROGRAM */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int main(int argc, char *argv[])
|
||||
#else
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char argv[];
|
||||
#endif
|
||||
{
|
||||
/* If stdin is a tty - probably wrong. */
|
||||
|
||||
Init(argc, argv);
|
||||
|
||||
if (isatty(0)) {
|
||||
Usage("Input should not come from a terminal");
|
||||
}
|
||||
|
||||
/* Search for a valid input file */
|
||||
while (!feof(stdin)) {
|
||||
gets(LineBuffer);
|
||||
if (!strcmp(LineBuffer, PSBEGIN)) {
|
||||
if (!validfile) {
|
||||
if (Verbose) {
|
||||
fprintf(stderr, "Rem2PS: Version %s Copyright 1992-1996 by David F. Skoll\n\n", VERSION);
|
||||
fprintf(stderr, "Generating PostScript calendar\n");
|
||||
}
|
||||
WriteProlog();
|
||||
}
|
||||
validfile++;
|
||||
DoPsCal();
|
||||
}
|
||||
}
|
||||
if (!validfile) {
|
||||
fprintf(stderr, "Rem2PS: Couldn't find any calendar data - are you\n");
|
||||
fprintf(stderr, " sure you fed me input produced by remind -p ...?\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("%%%%Trailer\n");
|
||||
printf("%%%%Pages: %d\n", validfile);
|
||||
if (Verbose) fprintf(stderr, "Rem2PS: Done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoPsCal - emit PostScript for the calendar. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
void DoPsCal(void)
|
||||
#else
|
||||
void DoPsCal()
|
||||
#endif
|
||||
{
|
||||
char month[40], year[40];
|
||||
char prevm[40], nextm[40];
|
||||
int days, wkday, prevdays, nextdays;
|
||||
int sfirst;
|
||||
int i;
|
||||
int is_ps;
|
||||
int firstcol;
|
||||
|
||||
CalEntry *c, *d;
|
||||
|
||||
/* Read the month and year name, followed by # days in month and 1st day of
|
||||
month */
|
||||
gets(LineBuffer);
|
||||
sscanf(LineBuffer, "%s %s %d %d", month, year, &days, &wkday);
|
||||
gets(LineBuffer);
|
||||
sscanf(LineBuffer, "%s %d", prevm, &prevdays);
|
||||
gets(LineBuffer);
|
||||
sscanf(LineBuffer, "%s %d", nextm, &nextdays);
|
||||
MaxDay = days;
|
||||
FirstWkDay = wkday;
|
||||
|
||||
/* Print a message for the user */
|
||||
if (Verbose) fprintf(stderr, " %s %s\n", month, year);
|
||||
|
||||
printf("%%%%Page: %c%c%c%c%c %d\n", month[0], month[1], month[2],
|
||||
year[2], year[3], validfile);
|
||||
|
||||
/* Emit PostScript to do the heading */
|
||||
if (!PortraitMode) printf("XSIZE 0 translate 90 rotate\n");
|
||||
printf("/SAVESTATE save def (%s) (%s) PreCal SAVESTATE restore\n", month, year);
|
||||
printf("(%s %s) doheading\n", month, year);
|
||||
|
||||
/* Figure out the column of the first day in the calendar */
|
||||
|
||||
if (MondayFirst) {
|
||||
firstcol = wkday-1;
|
||||
if (firstcol < 0) firstcol = 6;
|
||||
} else {
|
||||
firstcol = wkday;
|
||||
}
|
||||
|
||||
/* Calculate the minimum box size */
|
||||
if (!FillPage) {
|
||||
printf("/MinBoxSize ytop MinY sub 7 div def\n");
|
||||
} else {
|
||||
if ((days == 31 && firstcol >= 5) || (days == 30 && firstcol == 6))
|
||||
printf("/MinBoxSize ytop MinY sub 6 div def\n");
|
||||
else if (days == 28 && firstcol == 0 && NoSmallCal)
|
||||
printf("/MinBoxSize ytop MinY sub 4 div def\n");
|
||||
else
|
||||
printf("/MinBoxSize ytop MinY sub 5 div def\n");
|
||||
}
|
||||
|
||||
printf("/ysmalltop ytop def\n");
|
||||
|
||||
/* Do each entry */
|
||||
|
||||
CurEntries = NULL;
|
||||
CurDay = 1;
|
||||
WkDayNum = wkday;
|
||||
|
||||
while(1) {
|
||||
if (feof(stdin)) {
|
||||
fprintf(stderr, "Input from REMIND is corrupt!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
gets(LineBuffer);
|
||||
if (!strcmp(LineBuffer, PSEND)) break;
|
||||
|
||||
/* Read the day number - a bit of a hack! */
|
||||
DayNum = (LineBuffer[8] - '0') * 10 + LineBuffer[9] - '0';
|
||||
if (DayNum != CurDay) {
|
||||
for(; CurDay<DayNum; CurDay++) {
|
||||
WriteCalEntry();
|
||||
WkDayNum = (WkDayNum + 1) % 7;
|
||||
}
|
||||
}
|
||||
/* Add the text */
|
||||
c = NEW(CalEntry);
|
||||
if (!c) {
|
||||
fprintf(stderr, "malloc failed - aborting.\n");
|
||||
exit(1);
|
||||
}
|
||||
is_ps = (*LineBuffer == 'F' || *LineBuffer == 'P');
|
||||
c->next = NULL;
|
||||
c->entry = malloc(strlen(LineBuffer+10) + 1 + is_ps);
|
||||
if (!c->entry) {
|
||||
fprintf(stderr, "malloc failed - aborting.\n");
|
||||
exit(1);
|
||||
}
|
||||
strcpy(c->entry+is_ps, LineBuffer+10);
|
||||
|
||||
if (is_ps) {
|
||||
/* Save the 'P' or 'F' flag */
|
||||
*(c->entry) = *LineBuffer;
|
||||
if (!PsEntries[DayNum]) PsEntries[DayNum] = c;
|
||||
else {
|
||||
d = PsEntries[DayNum];
|
||||
while(d->next) d = d->next;
|
||||
d->next = c;
|
||||
}
|
||||
} else {
|
||||
/* Put on linked list */
|
||||
if (!CurEntries) CurEntries = c;
|
||||
else {
|
||||
d = CurEntries;
|
||||
while(d->next) d = d->next;
|
||||
d->next = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(; CurDay<=days; CurDay++) {
|
||||
WriteCalEntry();
|
||||
WkDayNum = (WkDayNum + 1) % 7;
|
||||
}
|
||||
|
||||
/* If wkday < 2, set ysmall. If necessary (only for feb) increase cal size. */
|
||||
printf("/ysmallbot ylast def\n");
|
||||
|
||||
/* Now draw the vertical lines */
|
||||
GetSmallLocations();
|
||||
for (i=0; i<=7; i++) {
|
||||
printf("%d xincr mul MinX add ymin %d xincr mul MinX add topy L\n",
|
||||
i, i);
|
||||
}
|
||||
|
||||
/* print the small calendars */
|
||||
if (!NoSmallCal) {
|
||||
sfirst = wkday - (prevdays % 7);
|
||||
if (sfirst < 0) sfirst += 7;
|
||||
DoSmallCal(prevm, prevdays, sfirst, SmallCol1, 1);
|
||||
sfirst = wkday + (days % 7);
|
||||
if (sfirst >6) sfirst -= 7;
|
||||
DoSmallCal(nextm, nextdays, sfirst, SmallCol2, 2);
|
||||
}
|
||||
/* Do it! */
|
||||
printf("showpage\n");
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* WriteProlog - write the PostScript prologue */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
void WriteProlog(void)
|
||||
#else
|
||||
void WriteProlog()
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
int x = CurPage->xsize;
|
||||
int y = CurPage->ysize;
|
||||
char *isostuff;
|
||||
FILE *fp;
|
||||
int nread;
|
||||
char buffer[LINELEN];
|
||||
|
||||
if (!PortraitMode) {
|
||||
i = x; x = y; y = i;
|
||||
}
|
||||
|
||||
if (UseISO)
|
||||
isostuff = "reencodeISO";
|
||||
else
|
||||
isostuff = "copyFont";
|
||||
|
||||
/* Write the document structuring stuff */
|
||||
printf("%%!PS-Adobe-\n");
|
||||
printf("%%%%DocumentFonts: %s", HeadFont);
|
||||
if (strcmp(TitleFont, HeadFont)) printf(" %s", TitleFont);
|
||||
if (strcmp(TitleFont, DayFont) &&
|
||||
strcmp(HeadFont, DayFont)) printf(" %s", DayFont);
|
||||
if (strcmp(EntryFont, HeadFont) &&
|
||||
strcmp(TitleFont, EntryFont) &&
|
||||
strcmp(EntryFont, DayFont)) printf(" %s", EntryFont);
|
||||
if (!NoSmallCal && strcmp(SmallFont, HeadFont) &&
|
||||
strcmp(SmallFont, DayFont) &&
|
||||
strcmp(TitleFont, SmallFont) &&
|
||||
strcmp(SmallFont, EntryFont)) printf(" %s", SmallFont);
|
||||
putchar('\n');
|
||||
printf("%%%%Creator: Rem2PS\n");
|
||||
printf("%%%%Pages: (atend)\n");
|
||||
printf("%%%%Orientation: %s\n", PortraitMode ? "Portrait" : "Landscape");
|
||||
printf("%%%%EndComments\n");
|
||||
|
||||
for (i=0; PSProlog1[i]; i++) puts(PSProlog1[i]);
|
||||
if (!MondayFirst)
|
||||
printf("[(%s) (%s) (%s) (%s) (%s) (%s) (%s)]\n",
|
||||
L_SUNDAY, L_MONDAY, L_TUESDAY, L_WEDNESDAY,
|
||||
L_THURSDAY, L_FRIDAY, L_SATURDAY);
|
||||
else
|
||||
printf("[(%s) (%s) (%s) (%s) (%s) (%s) (%s)]\n",
|
||||
L_MONDAY, L_TUESDAY, L_WEDNESDAY,
|
||||
L_THURSDAY, L_FRIDAY, L_SATURDAY, L_SUNDAY);
|
||||
for (i=0; PSProlog2[i]; i++) puts(PSProlog2[i]);
|
||||
|
||||
printf("/HeadFont /%s %s\n", HeadFont, isostuff);
|
||||
if (!NoSmallCal) printf("/SmallFont /%s %s\n", SmallFont, isostuff);
|
||||
printf("/DayFont /%s %s\n", DayFont, isostuff);
|
||||
printf("/EntryFont /%s %s\n", EntryFont, isostuff);
|
||||
printf("/TitleFont /%s %s\n", TitleFont, isostuff);
|
||||
printf("/HeadSize %s def\n", HeadSize);
|
||||
printf("/DaySize %s def\n", DaySize);
|
||||
printf("/EntrySize %s def\n", EntrySize);
|
||||
printf("/TitleSize %s def\n", TitleSize);
|
||||
printf("/XSIZE %d def\n", CurPage->xsize);
|
||||
printf("/MinX %d def\n", LeftMarg);
|
||||
printf("/MinY %d def\n", BotMarg);
|
||||
printf("/MaxX %d def\n", x-RightMarg);
|
||||
printf("/MaxY %d def\n", y-TopMarg);
|
||||
printf("/Border %s def\n", BorderSize);
|
||||
printf("/LineWidth %s def\n", LineWidth);
|
||||
printf("%s setlinewidth\n", LineWidth);
|
||||
|
||||
/* Check if smallfont is fixed pitch */
|
||||
if (!NoSmallCal) {
|
||||
printf("/SmallFont findfont /FontInfo get /isFixedPitch get\n");
|
||||
|
||||
/* Define SmallString used to set smallfont size */
|
||||
printf("{/SmallString (WW ) def}\n");
|
||||
printf("{/SmallString (WW) def}\nifelse\n");
|
||||
}
|
||||
|
||||
/* Do the user-supplied prolog file, if any */
|
||||
if (UserProlog) {
|
||||
fp = fopen(UserProlog, "r");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Could not open prologue file '%s'\n", UserProlog);
|
||||
} else {
|
||||
while(1) {
|
||||
nread = fread(buffer, sizeof(char), LINELEN, fp);
|
||||
if (!nread) break;
|
||||
fwrite(buffer, sizeof(char), nread, stdout);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
printf("%%%%EndProlog\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* WriteCalEntry - write all entries for one day */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
void WriteCalEntry(void)
|
||||
#else
|
||||
void WriteCalEntry()
|
||||
#endif
|
||||
{
|
||||
CalEntry *c = CurEntries;
|
||||
CalEntry *d;
|
||||
int begin, end, i, HadQPS;
|
||||
|
||||
/* Move to appropriate location */
|
||||
printf("/CAL%d {\n", CurDay);
|
||||
if (!MondayFirst)
|
||||
printf("Border ytop %d xincr mul MinX add xincr\n", WkDayNum);
|
||||
else
|
||||
printf("Border ytop %d xincr mul MinX add xincr\n", (WkDayNum ? WkDayNum-1 : 6));
|
||||
|
||||
/* Set up the text array */
|
||||
printf("[\n");
|
||||
|
||||
CurEntries = NULL;
|
||||
|
||||
while(c) {
|
||||
WriteOneEntry(c->entry);
|
||||
free(c->entry);
|
||||
d = c->next;
|
||||
free(c);
|
||||
c = d;
|
||||
}
|
||||
printf("]\n");
|
||||
|
||||
/* Print the day number */
|
||||
printf("(%d)\n", CurDay);
|
||||
/* Do it! */
|
||||
printf("DoCalBox\n");
|
||||
|
||||
/* Update ymin */
|
||||
printf("/y exch def y ymin lt {/ymin y def} if\n");
|
||||
printf("} def\n");
|
||||
|
||||
/* If WkDayNum is a Sunday or Monday, depending on MondayFirst,
|
||||
move to next row. Also handle the queued PS and PSFILE reminders */
|
||||
if ((!MondayFirst && WkDayNum == 6) ||
|
||||
(MondayFirst && WkDayNum == 0) || CurDay == MaxDay) {
|
||||
HadQPS = 0;
|
||||
if (MondayFirst) begin = CurDay - (WkDayNum ? WkDayNum-1 : 6);
|
||||
else begin = CurDay - WkDayNum;
|
||||
if (begin < 1) begin = 1;
|
||||
end = CurDay;
|
||||
for (i=begin; i<=end; i++) {
|
||||
if (PsEntries[i]) {
|
||||
HadQPS = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Avoid problems with blotching if PS printer has roundoff errors */
|
||||
if (HadQPS) printf("1 setgray\n");
|
||||
for (i=begin; i<=end; i++) {
|
||||
printf("CAL%d\n", i);
|
||||
}
|
||||
if (HadQPS) printf("0 setgray\n");
|
||||
printf("/y ytop MinBoxSize sub def y ymin lt {/ymin y def} if\n");
|
||||
|
||||
/* Draw the line at the bottom of the row */
|
||||
printf("MinX ymin MaxX ymin L\n");
|
||||
|
||||
/* Update ytop */
|
||||
printf("/ylast ytop def\n");
|
||||
printf("/ytop ymin def\n");
|
||||
|
||||
(void) DoQueuedPs();
|
||||
|
||||
/* Re-do the calendar stuff if there was any included PS code */
|
||||
if (HadQPS) {
|
||||
printf("/ytop ylast def\n");
|
||||
for (i=begin; i<=end; i++) {
|
||||
printf("CAL%d\n", i);
|
||||
}
|
||||
printf("/y ytop MinBoxSize sub def y ymin lt {/ymin y def} if\n");
|
||||
printf("MinX ymin MaxX ymin L\n");
|
||||
printf("/ylast ytop def\n");
|
||||
printf("/ytop ymin def\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* WriteOneEntry - write an entry for one day */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
void WriteOneEntry(char *s)
|
||||
#else
|
||||
void WriteOneEntry(s)
|
||||
char *s;
|
||||
#endif
|
||||
{
|
||||
int c;
|
||||
printf(" [");
|
||||
|
||||
/* Chew up leading spaces */
|
||||
while(isspace(*s)) s++;
|
||||
|
||||
putchar('(');
|
||||
while(*s) {
|
||||
c = *s++;
|
||||
if (c == '\\' || c == '(' || c == ')') putchar('\\');
|
||||
if (!isspace(c)) putchar(c);
|
||||
else {
|
||||
putchar(')');
|
||||
while(isspace(*s)) s++;
|
||||
if (!*s) {
|
||||
printf("]\n");
|
||||
return;
|
||||
}
|
||||
putchar('(');
|
||||
}
|
||||
}
|
||||
printf(")]\n");
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* Init - set up parameters */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void Init(int argc, char *argv[])
|
||||
#else
|
||||
void Init(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
#endif
|
||||
{
|
||||
char *s, *t;
|
||||
int i=1;
|
||||
int j;
|
||||
int offset;
|
||||
|
||||
PortraitMode = 1;
|
||||
NoSmallCal = 0;
|
||||
LeftMarg = 36;
|
||||
RightMarg = 36;
|
||||
TopMarg = 36;
|
||||
BotMarg = 36;
|
||||
UseISO = 0;
|
||||
FillPage = 0;
|
||||
MondayFirst = 0;
|
||||
SmallLocation = "bt";
|
||||
|
||||
for(j=0; j<32; j++) PsEntries[i] = NULL;
|
||||
|
||||
CurPage = DefaultPage; /* Letter size by default */
|
||||
|
||||
while (i < argc) {
|
||||
s = argv[i];
|
||||
i++;
|
||||
|
||||
if (*s++ != '-') Usage("Options must begin with '-'");
|
||||
|
||||
switch(*s++) {
|
||||
|
||||
case 'n':
|
||||
MondayFirst = 1;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if (i == argc) Usage("Prologue filename must be supplied");
|
||||
UserProlog = argv[i++];
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (i == argc) Usage("Size must be supplied");
|
||||
t = argv[i++];
|
||||
while(*s) {
|
||||
switch(*s++) {
|
||||
case 'h': HeadSize = t; break;
|
||||
case 'e': EntrySize = t; break;
|
||||
case 'd': DaySize = t; break;
|
||||
case 't': TitleSize = t; break;
|
||||
default: Usage("Size must specify h, t, e, or d");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (i == argc) Usage("Font must be supplied");
|
||||
t = argv[i++];
|
||||
while(*s) {
|
||||
switch(*s++) {
|
||||
case 'h': HeadFont = t; break;
|
||||
case 'e': EntryFont = t; break;
|
||||
case 'd': DayFont = t; break;
|
||||
case 's': SmallFont = t; break;
|
||||
case 't': TitleFont = t; break;
|
||||
default: Usage("Font must specify s, h, t, e, or d");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
Verbose = 1;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (i == argc) Usage("Media must be supplied");
|
||||
t = argv[i++];
|
||||
CurPage = NULL;
|
||||
for (j=0; j<NUMPAGES; j++)
|
||||
if (!strcmp(t, Pages[j].name)) {
|
||||
CurPage = &Pages[j];
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CurPage) {
|
||||
fprintf(stderr, "\nUnknown media specified.\n");
|
||||
fprintf(stderr, "\nAvailable media types:\n");
|
||||
for (j=0; j<NUMPAGES; j++)
|
||||
fprintf(stderr, " %s\n", Pages[j].name);
|
||||
fprintf(stderr, "Default media type is %s\n", DefaultPage[0].name);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
if (i == argc) Usage("Offset must be supplied");
|
||||
offset = atoi(argv[i++]);
|
||||
if (offset < 36) offset = 36;
|
||||
if (!*s) Usage("Offset must specify l, r, t or b");
|
||||
while(*s) {
|
||||
switch(*s++) {
|
||||
case 'l': LeftMarg = offset; break;
|
||||
case 'r': RightMarg = offset ; break;
|
||||
case 't': TopMarg = offset; break;
|
||||
case 'b': BotMarg = offset; break;
|
||||
default: Usage("Offset must specify l, r, t or b");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
if (i == argc) Usage("Border must be supplied");
|
||||
BorderSize = argv[i++];
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (i == argc) Usage("Line thickness must be supplied");
|
||||
LineWidth = argv[i++];
|
||||
break;
|
||||
|
||||
case 'l': PortraitMode = 0; break;
|
||||
|
||||
case 'i': UseISO = 1; break;
|
||||
|
||||
case 'c': j=(*s);
|
||||
if (!j) {
|
||||
SmallLocation = SmallCalLoc[0];
|
||||
} else {
|
||||
j -= '0';
|
||||
if (j>=0 && j<NUMSMALL) {
|
||||
SmallLocation = SmallCalLoc[j];
|
||||
} else {
|
||||
SmallLocation = SmallCalLoc[0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e': FillPage = 1; break;
|
||||
|
||||
default: Usage("Unrecognized option");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* Usage - print usage information */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void Usage(char *s)
|
||||
#else
|
||||
void Usage(s)
|
||||
char *s;
|
||||
#endif
|
||||
{
|
||||
if (s) fprintf(stderr, "Rem2PS: %s\n\n", s);
|
||||
|
||||
fprintf(stderr, "Rem2PS: Produce a PostScript calendar from output of Remind.\n\n");
|
||||
fprintf(stderr, "Usage: rem2ps [options]\n\n");
|
||||
fprintf(stderr, "Options:\n\n");
|
||||
fprintf(stderr, "-v Print progress messages to standard error\n");
|
||||
fprintf(stderr, "-p file Include user-supplied PostScript code in prologue\n");
|
||||
fprintf(stderr, "-l Do calendar in landscape mode\n");
|
||||
fprintf(stderr, "-c[n] Control small calendars: 0=none; 1=bt; 2=tb; 3=sbt\n");
|
||||
fprintf(stderr, " and next month\n");
|
||||
fprintf(stderr, "-i Use ISO 8859-1 encoding in PostScript output\n");
|
||||
fprintf(stderr, "-m media Set page size (eg, Letter, Legal, A4.) Case sensitive!\n");
|
||||
fprintf(stderr, " (Default page size is %s)\n", DefaultPage[0].name);
|
||||
fprintf(stderr, "-f[shted] font Set font for small cal, hdr, title, cal entries, day numbers\n");
|
||||
fprintf(stderr, "-s[hted] size Set size for header, title, calendar entries and/or day numbers\n");
|
||||
fprintf(stderr, "-b size Set border size for calendar entries\n");
|
||||
fprintf(stderr, "-t size Set line thickness\n");
|
||||
fprintf(stderr, "-e Make calendar fill entire page\n");
|
||||
fprintf(stderr, "-o[lrtb] marg Specify left, right, top and bottom margins\n");
|
||||
fprintf(stderr, "-n Start calendar with Monday rather than Sunday\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoSmallCal - do the small calendar for previous or next */
|
||||
/* month. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
void DoSmallCal(char *m, int days, int first, int col, int which)
|
||||
#else
|
||||
void DoSmallCal(m, days, first, col, which)
|
||||
char *m;
|
||||
int days, first, col;
|
||||
#endif
|
||||
{
|
||||
/* Do the small calendar */
|
||||
int i, j;
|
||||
int row = 2;
|
||||
|
||||
if (MondayFirst) {
|
||||
first--;
|
||||
if (first < 0) first = 6;
|
||||
}
|
||||
/* Figure out the font size */
|
||||
|
||||
printf("/SmallFontSize MinBoxSize Border sub Border sub 8 div 2 sub def\n");
|
||||
printf("/SmallFont findfont setfont\n");
|
||||
printf("SmallString stringwidth pop /SmallWidth exch def\n");
|
||||
printf("SmallWidth 7 mul xincr Border sub Border sub exch div /tmp exch def\n");
|
||||
printf("tmp SmallFontSize lt {/SmallFontSize tmp def} if\n");
|
||||
printf("/SmallFont findfont SmallFontSize scalefont setfont\n");
|
||||
|
||||
/* Recalculate SmallWidth */
|
||||
printf("SmallString stringwidth pop /SmallWidth exch def\n");
|
||||
|
||||
/* Save graphics state */
|
||||
printf("gsave\n");
|
||||
|
||||
/* Move origin to upper-left hand corner of appropriate box */
|
||||
printf("%d xincr mul MinX add ysmall%d translate\n", col, which);
|
||||
|
||||
/* Print the month */
|
||||
printf("SmallWidth 7 mul (%s) stringwidth pop sub 2 div Border add Border neg SmallFontSize sub moveto (%s) show\n", m, m);
|
||||
|
||||
/* Print the days of the week */
|
||||
for (i=0; i<7; i++) {
|
||||
if (MondayFirst) j=(i+1)%7;
|
||||
else j=i;
|
||||
printf("Border %d SmallWidth mul add Border neg SmallFontSize sub SmallFontSize sub 2 sub moveto (%c) show\n", i, Days[j]);
|
||||
}
|
||||
|
||||
/* Now do the days of the month */
|
||||
for (i=1; i<=days; i++) {
|
||||
printf("Border %d SmallWidth mul add Border neg SmallFontSize sub SmallFontSize 2 add %d mul sub moveto (%d) show\n", first, row, i);
|
||||
first++;
|
||||
if (first == 7) { first = 0; row++; }
|
||||
}
|
||||
|
||||
/* restore graphics state */
|
||||
printf("grestore\n");
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoQueuedPs - do the queued PS and PSFILE reminders. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoQueuedPs(void)
|
||||
#else
|
||||
int DoQueuedPs()
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
int HadPS = 0;
|
||||
int wd;
|
||||
int begin, end;
|
||||
int nread;
|
||||
CalEntry *e, *n;
|
||||
FILE *fp;
|
||||
int fnoff;
|
||||
char buffer[LINELEN];
|
||||
|
||||
if (!MondayFirst) begin = CurDay - WkDayNum;
|
||||
else begin = CurDay - (WkDayNum ? WkDayNum-1 : 6);
|
||||
wd = 0;
|
||||
while (begin < 1) begin++, wd++;
|
||||
end = CurDay;
|
||||
for (i=begin; i<=end; i++, wd++) {
|
||||
e = PsEntries[i];
|
||||
|
||||
if (e) {
|
||||
HadPS = 1;
|
||||
printf("/SAVESTATE save def\n");
|
||||
|
||||
/* Translate coordinates to bottom of calendar box */
|
||||
printf("%d xincr mul MinX add ytop translate\n", wd);
|
||||
|
||||
/* Set up convenient variables */
|
||||
printf("/BoxWidth xincr def\n/BoxHeight ylast ytop sub def\n");
|
||||
printf("/InBoxHeight BoxHeight border sub DaySize sub DaySize sub 2 add EntrySize add def \n");
|
||||
}
|
||||
|
||||
while (e) {
|
||||
|
||||
/* Now do the user's PostScript code */
|
||||
fnoff = 1;
|
||||
while (isspace(*(e->entry+fnoff))) fnoff++;
|
||||
if (*(e->entry) == 'P') {
|
||||
printf("%s\n", e->entry+fnoff);
|
||||
} else {
|
||||
fp = fopen(e->entry+fnoff, "r");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Could not open PostScript file '%s'\n", e->entry+1);
|
||||
} else {
|
||||
while(1) {
|
||||
nread = fread(buffer, sizeof(char), LINELEN, fp);
|
||||
if (!nread) break;
|
||||
fwrite(buffer, sizeof(char), nread, stdout);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the entry */
|
||||
free(e->entry);
|
||||
n = e->next;
|
||||
free(e);
|
||||
e = n;
|
||||
}
|
||||
if (PsEntries[i]) printf("\n SAVESTATE restore\n");
|
||||
PsEntries[i] = NULL;
|
||||
}
|
||||
return HadPS;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetSmallLocations */
|
||||
/* */
|
||||
/* Set up the locations for the small calendars. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void GetSmallLocations(void)
|
||||
#else
|
||||
void GetSmallLocations()
|
||||
#endif
|
||||
{
|
||||
char c;
|
||||
char *s = SmallLocation;
|
||||
int colfirst, collast;
|
||||
|
||||
/* Figure out the first and last columns */
|
||||
colfirst = FirstWkDay;
|
||||
collast = (FirstWkDay+MaxDay-1) % 7;
|
||||
if (MondayFirst) {
|
||||
colfirst = colfirst ? colfirst - 1 : 6;
|
||||
collast = collast ? collast - 1 : 6;
|
||||
}
|
||||
NoSmallCal = 0;
|
||||
|
||||
while((c = *s++) != 0) {
|
||||
switch(c) {
|
||||
case 'b':
|
||||
/* Adjust Feb. if we want it on the bottom */
|
||||
if (MaxDay == 28 && colfirst == 0) {
|
||||
printf("/ysmallbot ymin def /ymin ysmallbot MinBoxSize sub def\n");
|
||||
printf("MinX ymin MaxX ymin L\n");
|
||||
printf("/ysmall1 ysmallbot def /ysmall2 ysmallbot def\n");
|
||||
SmallCol1 = 5;
|
||||
SmallCol2 = 6;
|
||||
return;
|
||||
}
|
||||
if (collast <= 4) {
|
||||
printf("/ysmall1 ysmallbot def /ysmall2 ysmallbot def\n");
|
||||
SmallCol1 = 5;
|
||||
SmallCol2 = 6;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (colfirst >= 2) {
|
||||
printf("/ysmall1 ysmalltop def /ysmall2 ysmalltop def\n");
|
||||
SmallCol1 = 0;
|
||||
SmallCol2 = 1;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (colfirst >= 1 && collast<=5) {
|
||||
printf("/ysmall1 ysmalltop def /ysmall2 ysmallbot def\n");
|
||||
SmallCol1 = 0;
|
||||
SmallCol2 = 6;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
NoSmallCal = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
212
rem2ps.h
Normal file
212
rem2ps.h
Normal file
@@ -0,0 +1,212 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* REM2PS.H */
|
||||
/* */
|
||||
/* Define the PostScript prologue */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: rem2ps.h,v 1.1 1996-03-27 03:26:08 dfs Exp $ */
|
||||
|
||||
char *PSProlog1[] =
|
||||
{
|
||||
"% This file was produced by Remind and Rem2PS, written by",
|
||||
"% David F. Skoll.",
|
||||
"/ISOLatin1Encoding where { pop save true }{ false } ifelse",
|
||||
" /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus",
|
||||
" StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute",
|
||||
" /circumflex /tilde /macron /breve /dotaccent /dieresis /.notdef /ring",
|
||||
" /cedilla /.notdef /hungarumlaut /ogonek /caron /space /exclamdown /cent",
|
||||
" /sterling /currency /yen /brokenbar /section /dieresis /copyright",
|
||||
" /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron",
|
||||
" /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph",
|
||||
" /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright",
|
||||
" /onequarter /onehalf /threequarters /questiondown /Agrave /Aacute",
|
||||
" /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute",
|
||||
" /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth",
|
||||
" /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply",
|
||||
" /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn",
|
||||
" /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae",
|
||||
" /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute",
|
||||
" /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex",
|
||||
" /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex",
|
||||
" /udieresis /yacute /thorn /ydieresis ] def",
|
||||
"{ restore } if",
|
||||
"",
|
||||
"/reencodeISO { %def",
|
||||
" findfont dup length dict begin",
|
||||
" { 1 index /FID ne { def }{ pop pop } ifelse } forall",
|
||||
" /Encoding ISOLatin1Encoding def",
|
||||
" currentdict end definefont pop",
|
||||
"} bind def",
|
||||
"/copyFont { %def",
|
||||
" findfont dup length dict begin",
|
||||
" { 1 index /FID ne { def } { pop pop } ifelse } forall",
|
||||
" currentdict end definefont pop",
|
||||
"} bind def",
|
||||
"",
|
||||
"% L - Draw a line",
|
||||
"/L {",
|
||||
" newpath moveto lineto stroke",
|
||||
"} bind def",
|
||||
"% string1 string2 strcat string",
|
||||
"% Function: Concatenates two strings together.",
|
||||
"/strcat {",
|
||||
" 2 copy length exch length add",
|
||||
" string dup",
|
||||
" 4 2 roll",
|
||||
" 2 index 0 3 index",
|
||||
" putinterval",
|
||||
" exch length exch putinterval",
|
||||
"} bind def",
|
||||
"% string doheading",
|
||||
"/doheading",
|
||||
"{",
|
||||
" /monthyr exch def",
|
||||
"",
|
||||
" /TitleFont findfont",
|
||||
" TitleSize scalefont setfont",
|
||||
" monthyr stringwidth",
|
||||
" /hgt exch def",
|
||||
" 2 div MaxX MinX add 2 div exch sub /x exch def",
|
||||
" MaxY Border sub TitleSize sub /y exch def",
|
||||
" newpath x y moveto monthyr show",
|
||||
" newpath x y moveto monthyr false charpath flattenpath pathbbox",
|
||||
" pop pop Border sub /y exch def pop",
|
||||
" MinX y MaxX y L",
|
||||
" /topy y def",
|
||||
" /HeadFont findfont HeadSize scalefont setfont",
|
||||
"% Do the days of the week",
|
||||
" MaxX MinX sub 7 div /xincr exch def",
|
||||
" /x MinX def",
|
||||
NULL
|
||||
};
|
||||
char *PSProlog2[] =
|
||||
{
|
||||
" {",
|
||||
" HeadSize x y HeadSize 2 mul sub x xincr add y CenterText",
|
||||
" x xincr add /x exch def",
|
||||
" } forall",
|
||||
" y HeadSize 2 mul sub /y exch def",
|
||||
" MinX y MaxX y L",
|
||||
" /ytop y def /ymin y def",
|
||||
"}",
|
||||
"def",
|
||||
"/CenterText",
|
||||
"{",
|
||||
" /maxy exch def",
|
||||
" /maxx exch def",
|
||||
" /miny exch def",
|
||||
" /minx exch def",
|
||||
" /sz exch def",
|
||||
" /str exch def",
|
||||
" str stringwidth pop",
|
||||
" 2 div maxx minx add 2 div exch sub",
|
||||
" sz 2 div maxy miny add 2 div exch sub",
|
||||
" moveto str show",
|
||||
"} def",
|
||||
"% Variables:",
|
||||
"% curline - a string holding the current line",
|
||||
"% y - current y pos",
|
||||
"% yincr - increment to next line",
|
||||
"% xleft - left margin",
|
||||
"% width - max width.",
|
||||
"% EnterOneWord - given a word, enter it into the box.",
|
||||
"% string EnterOneWord",
|
||||
"/EnterOneWord {",
|
||||
" { EnterOneWordAux",
|
||||
" {exit} if }",
|
||||
" loop",
|
||||
"} bind def",
|
||||
"% EnterOneWordAux - if the word fits, enter it into box and return true.",
|
||||
"% If it doesn't fit, put as much as will fit and return the string and false.",
|
||||
"/EnterOneWordAux {",
|
||||
" /word exch def",
|
||||
" /tmpline curline word strcat def",
|
||||
" tmpline stringwidth pop width gt",
|
||||
" {MoveToNewLine}",
|
||||
" {/curline tmpline ( ) strcat def /word () def}",
|
||||
" ifelse",
|
||||
" word () eq",
|
||||
" {true}",
|
||||
" {word false}",
|
||||
" ifelse",
|
||||
"} bind def",
|
||||
"% MoveToNewLine - move to a new line, resetting word as appropriate",
|
||||
"/MoveToNewLine {",
|
||||
" curline () ne",
|
||||
" {newpath xleft y moveto curline show /curline () def /y y yincr add def} ",
|
||||
" {ChopWord}",
|
||||
" ifelse",
|
||||
"} bind def",
|
||||
"% ChopWord - word won't fit. Chop it and find biggest piece that will fit",
|
||||
"/ChopWord {",
|
||||
" /curline () def",
|
||||
" /len word length def",
|
||||
" /Fcount len 1 sub def",
|
||||
"",
|
||||
" {",
|
||||
" word 0 Fcount getinterval stringwidth pop width le",
|
||||
" {exit} if",
|
||||
" /Fcount Fcount 1 sub def",
|
||||
" } loop",
|
||||
"% Got the count. Display it and reset word",
|
||||
" newpath xleft y moveto word 0 Fcount getinterval show",
|
||||
" /y y yincr add def",
|
||||
" /word word Fcount len Fcount sub getinterval def",
|
||||
"} bind def",
|
||||
"/FinishFormatting {",
|
||||
" word () ne",
|
||||
" {newpath xleft y moveto word show /word () def",
|
||||
" /curline () def /y y yincr add def}",
|
||||
" {curline () ne",
|
||||
" {newpath xleft y moveto curline show /word () def",
|
||||
" /curline () def /y y yincr add def} if}",
|
||||
" ifelse",
|
||||
"} bind def",
|
||||
"% FillBoxWithText - fill a box with text",
|
||||
"% text-array xleft width yincr y FillBoxWithText new-y",
|
||||
"% Returns the new Y-coordinate.",
|
||||
"/FillBoxWithText {",
|
||||
" /y exch def",
|
||||
" /yincr exch def",
|
||||
" /width exch def",
|
||||
" /xleft exch def",
|
||||
" /curline () def",
|
||||
" {EnterOneWord} forall",
|
||||
" FinishFormatting",
|
||||
" y",
|
||||
"} bind def",
|
||||
"% Variables for calendar boxes:",
|
||||
"% ytop - current top position",
|
||||
"% ymin - minimum y reached for current row",
|
||||
"% border ytop xleft width textarray daynum DoCalBox ybot",
|
||||
"% Do the entries for one calendar box. Returns lowest Y-coordinate reached",
|
||||
"/DoCalBox {",
|
||||
" /daynum exch def",
|
||||
" /textarr exch def",
|
||||
" /wid exch def",
|
||||
" /xl exch def",
|
||||
" /yt exch def",
|
||||
" /border exch def",
|
||||
"% Do the day number",
|
||||
" /DayFont findfont DaySize scalefont setfont",
|
||||
" xl wid add border sub daynum stringwidth pop sub",
|
||||
" yt border sub DaySize sub moveto daynum show",
|
||||
"% Do the text entries. Precharge the stack with current y pos.",
|
||||
" /ycur yt border sub DaySize sub DaySize sub 2 add def",
|
||||
" /EntryFont findfont EntrySize scalefont setfont",
|
||||
" ycur",
|
||||
" textarr",
|
||||
" { exch 2 sub /ycur exch def xl border add wid border sub border sub EntrySize 2 add neg",
|
||||
" ycur FillBoxWithText }",
|
||||
" forall",
|
||||
"} bind def",
|
||||
"2 setlinecap",
|
||||
"% Define a default PreCal procedure",
|
||||
"/PreCal { pop pop } bind def",
|
||||
NULL
|
||||
};
|
||||
46
remind-all.csh
Normal file
46
remind-all.csh
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/bin/csh -f
|
||||
|
||||
# Shell script to mail all users reminders.
|
||||
|
||||
# $Id: remind-all.csh,v 1.1 1996-03-27 03:26:08 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
|
||||
54
remind-all.sh
Normal file
54
remind-all.sh
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
# Shell script to mail all users reminders.
|
||||
|
||||
# This file is part of REMIND
|
||||
#
|
||||
# $Id: remind-all.sh,v 1.1 1996-03-27 03:26:08 dfs Exp $
|
||||
#
|
||||
# REMIND is Copyright (C) 1992-1996 by David F. Skoll
|
||||
# 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
|
||||
1
remind.def
Normal file
1
remind.def
Normal file
@@ -0,0 +1 @@
|
||||
NAME WINDOWCOMPAT NEWFILES
|
||||
262
sort.c
Normal file
262
sort.c
Normal file
@@ -0,0 +1,262 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SORT.C */
|
||||
/* */
|
||||
/* Routines for sorting reminders by trigger date */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: sort.c,v 1.1 1996-03-27 03:26:10 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
#include "protos.h"
|
||||
#include "expr.h"
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
/* The structure of a sorted entry */
|
||||
typedef struct sortrem {
|
||||
struct sortrem *next;
|
||||
char *text;
|
||||
int trigdate;
|
||||
int trigtime;
|
||||
int typ;
|
||||
int priority;
|
||||
} Sortrem;
|
||||
|
||||
/* The sorted reminder queue */
|
||||
static Sortrem *SortedQueue = (Sortrem *) NULL;
|
||||
|
||||
PRIVATE Sortrem *MakeSortRem ARGS ((int jul, int tim, char *body, int typ, int prio));
|
||||
PRIVATE void IssueSortBanner ARGS ((int jul));
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* MakeSortRem */
|
||||
/* */
|
||||
/* Create a new Sortrem entry - return NULL on failure. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE Sortrem *MakeSortRem(int jul, int tim, char *body, int typ, int prio)
|
||||
#else
|
||||
static Sortrem *MakeSortRem(jul, tim, body, typ, prio)
|
||||
int jul, tim;
|
||||
char *body;
|
||||
int typ, prio;
|
||||
#endif
|
||||
{
|
||||
Sortrem *new = NEW(Sortrem);
|
||||
if (!new) return NULL;
|
||||
|
||||
new->text = StrDup(body);
|
||||
if (!new->text) {
|
||||
free(new);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new->trigdate = jul;
|
||||
new->trigtime = tim;
|
||||
new->typ = typ;
|
||||
new->priority = prio;
|
||||
new->next = NULL;
|
||||
return new;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* InsertIntoSortBuffer */
|
||||
/* */
|
||||
/* Insert a reminder into the sort buffer */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int InsertIntoSortBuffer(int jul, int tim, char *body, int typ, int prio)
|
||||
#else
|
||||
int InsertIntoSortBuffer(jul, tim, body, typ, prio)
|
||||
int jul;
|
||||
int tim;
|
||||
char *body;
|
||||
int typ, prio;
|
||||
#endif
|
||||
{
|
||||
Sortrem *new = MakeSortRem(jul, tim, body, typ, prio);
|
||||
Sortrem *cur = SortedQueue, *prev = NULL;
|
||||
int ShouldGoAfter;
|
||||
|
||||
if (!new) {
|
||||
Eprint("%s", ErrMsg[E_NO_MEM]);
|
||||
IssueSortedReminders();
|
||||
SortByDate = 0;
|
||||
SortByTime = 0;
|
||||
SortByPrio = 0;
|
||||
return E_NO_MEM;
|
||||
}
|
||||
|
||||
/* Find the correct place in the sorted list */
|
||||
if (!SortedQueue) {
|
||||
SortedQueue = new;
|
||||
return OK;
|
||||
}
|
||||
while (cur) {
|
||||
ShouldGoAfter = CompareRems(new->trigdate, new->trigtime, new->priority,
|
||||
cur->trigdate, cur->trigtime, cur->priority,
|
||||
SortByDate, SortByTime, SortByPrio);
|
||||
|
||||
if (ShouldGoAfter <= 0) {
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
} else {
|
||||
if (prev) {
|
||||
prev->next = new;
|
||||
new->next = cur;
|
||||
} else {
|
||||
SortedQueue = new;
|
||||
new->next = cur;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
}
|
||||
prev->next = new;
|
||||
new->next = cur; /* For safety - actually redundant */
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* IssueSortedReminders */
|
||||
/* */
|
||||
/* Issue all of the sorted reminders and free memory. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void IssueSortedReminders(void)
|
||||
#else
|
||||
void IssueSortedReminders()
|
||||
#endif
|
||||
{
|
||||
Sortrem *cur = SortedQueue;
|
||||
Sortrem *next;
|
||||
int olddate = NO_DATE;
|
||||
|
||||
while (cur) {
|
||||
next = cur->next;
|
||||
switch(cur->typ) {
|
||||
case MSG_TYPE:
|
||||
if (MsgCommand) {
|
||||
DoMsgCommand(MsgCommand, cur->text);
|
||||
} else {
|
||||
if (cur->trigdate != olddate) {
|
||||
IssueSortBanner(cur->trigdate);
|
||||
olddate = cur->trigdate;
|
||||
}
|
||||
printf("%s", cur->text);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSF_TYPE:
|
||||
#ifdef OS2_POPUP
|
||||
FillParagraph(cur->text, 0);
|
||||
#else
|
||||
FillParagraph(cur->text);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case RUN_TYPE:
|
||||
system(cur->text);
|
||||
break;
|
||||
}
|
||||
|
||||
free(cur->text);
|
||||
free(cur);
|
||||
cur = next;
|
||||
}
|
||||
SortedQueue = NULL;
|
||||
}
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* IssueSortBanner */
|
||||
/* */
|
||||
/* Issue a daily banner if the function sortbanner() is */
|
||||
/* defined to take one argument. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void IssueSortBanner(int jul)
|
||||
#else
|
||||
static void IssueSortBanner(jul)
|
||||
int jul;
|
||||
#endif
|
||||
{
|
||||
char BanExpr[25];
|
||||
int y, m, d;
|
||||
Value v;
|
||||
char *s = BanExpr;
|
||||
|
||||
if (UserFuncExists("sortbanner") != 1) return;
|
||||
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
sprintf(BanExpr, "sortbanner('%04d/%02d/%02d')", y, m+1, d);
|
||||
y = EvalExpr(&s, &v);
|
||||
if (y) return;
|
||||
if (DoCoerce(STR_TYPE, &v)) return;
|
||||
if (!DoSubstFromString(v.v.str, SubstBuffer, jul, NO_TIME))
|
||||
if (*SubstBuffer) printf("%s\n", SubstBuffer);
|
||||
DestroyValue(v);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* CompareRems */
|
||||
/* */
|
||||
/* Compare two reminders for sorting. Return 0 if they */
|
||||
/* compare equal; 1 if rem2 should come after rem1, -1 if */
|
||||
/* rem1 should come after rem2. bydate and bytime control */
|
||||
/* sorting direction by date and time, resp. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int CompareRems(int dat1, int tim1, int prio1,
|
||||
int dat2, int tim2, int prio2,
|
||||
int bydate, int bytime, int byprio)
|
||||
#else
|
||||
int CompareRems(dat1, tim1, prio1, dat2, tim2, prio2, bydate, bytime, byprio)
|
||||
int dat1, tim1, prio1, dat2, tim2, prio2, bydate, bytime, byprio;
|
||||
#endif
|
||||
{
|
||||
int dafter, tafter, pafter;
|
||||
|
||||
dafter = (bydate != SORT_DESCEND) ? 1 : -1;
|
||||
tafter = (bytime != SORT_DESCEND) ? 1 : -1;
|
||||
pafter = (byprio != SORT_DESCEND) ? 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 < tim2) return tafter;
|
||||
if (tim1 > tim2) return -tafter;
|
||||
|
||||
if (prio1 < prio2) return pafter;
|
||||
if (prio1 > prio2) return -pafter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
27
test-rem
Normal file
27
test-rem
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
# ---------------------------------------------------------------------------
|
||||
# TEST-REM
|
||||
#
|
||||
# $Id: test-rem,v 1.1 1996-03-27 03:26:10 dfs Exp $
|
||||
#
|
||||
# This file runs an acceptance test for Remind. To use it, type:
|
||||
# sh test-rem OR make test
|
||||
# in the build directory.
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-1996 by David F. Skoll
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
TEST_GETENV="foo bar baz" ; export TEST_GETENV
|
||||
./remind -e -dxte ./test.rem 16 feb 1991 > ./test.out
|
||||
cmp -s ./test.out ./test.cmp
|
||||
if [ "$?" = "0" ]; then
|
||||
echo "Remind: Acceptance test PASSED"
|
||||
exit 0
|
||||
else
|
||||
echo "Remind: Acceptance test FAILED"
|
||||
echo ""
|
||||
echo "Examine the file test.out to see where it differs from the"
|
||||
echo "reference file test.cmp."
|
||||
exit 1
|
||||
fi
|
||||
32
test-rem.bat
Normal file
32
test-rem.bat
Normal file
@@ -0,0 +1,32 @@
|
||||
@echo off
|
||||
rem ---------------------------------------------------------------------------
|
||||
rem TEST-REM
|
||||
rem
|
||||
rem $Id: test-rem.bat,v 1.1 1996-03-27 03:26:10 dfs Exp $
|
||||
rem
|
||||
rem This file runs an MSDOS acceptance test for Remind. To use it, type:
|
||||
rem test-rem
|
||||
rem in the build directory.
|
||||
rem
|
||||
rem This file is part of REMIND.
|
||||
rem Copyright (C) 1992-1996 by David F. Skoll
|
||||
rem ---------------------------------------------------------------------------
|
||||
|
||||
del test.out > nul
|
||||
set TEST_GETENV=foo bar baz
|
||||
if exist ..\msdos-ex\remind.exe goto bcc
|
||||
remind -e -dxte ./test.rem 16 feb 1991 > test.out
|
||||
goto cmp
|
||||
:bcc
|
||||
..\msdos-ex\remind -e -dxte .\test.rem 16 feb 1991 > test.out
|
||||
:cmp
|
||||
echo n | comp test.out test1.cmp
|
||||
if errorlevel 1 goto oops
|
||||
echo "Remind: Acceptance test PASSED"
|
||||
goto quit
|
||||
:oops
|
||||
echo "Remind: Acceptance test FAILED"
|
||||
echo ""
|
||||
echo "Examine the file test.out to see where it differs from the"
|
||||
echo "reference file test1.cmp."
|
||||
:quit
|
||||
34
test-rem.cmd
Normal file
34
test-rem.cmd
Normal file
@@ -0,0 +1,34 @@
|
||||
@echo off
|
||||
rem ---------------------------------------------------------------------------
|
||||
rem TEST-REM
|
||||
rem
|
||||
rem $Id: test-rem.cmd,v 1.1 1996-03-27 03:26:11 dfs Exp $
|
||||
rem
|
||||
rem This file runs an OS/2 acceptance test for Remind. To use it, type:
|
||||
rem test-rem
|
||||
rem in the build directory.
|
||||
rem
|
||||
rem This file is part of REMIND.
|
||||
rem Copyright (C) 1992-1996 by David F. Skoll
|
||||
rem ---------------------------------------------------------------------------
|
||||
|
||||
del /f test.out > nul
|
||||
setlocal
|
||||
set TEST_GETENV=foo bar baz
|
||||
if exist ..\os2-ex\remind.exe goto bcc
|
||||
remind -e -dxte ./test.rem 16 feb 1991 > .\test.out
|
||||
goto cmp
|
||||
:bcc
|
||||
..\os2-ex\remind -e -dxte .\test.rem 16 feb 1991 > .\test.out
|
||||
:cmp
|
||||
echo n | comp test.out test2.cmp
|
||||
if errorlevel 1 goto oops
|
||||
echo "Remind: Acceptance test PASSED"
|
||||
goto quit
|
||||
:oops
|
||||
echo "Remind: Acceptance test FAILED"
|
||||
echo ""
|
||||
echo "Examine the file test.out to see where it differs from the"
|
||||
echo "reference file test2.cmp."
|
||||
:quit
|
||||
endlocal
|
||||
832
test.cmp
Normal file
832
test.cmp
Normal file
@@ -0,0 +1,832 @@
|
||||
# Test file for REMIND
|
||||
#
|
||||
# $Id: test.cmp,v 1.1 1996-03-27 03:26:11 dfs Exp $
|
||||
#
|
||||
# Use this file to test the date calculation routines
|
||||
# of the REMIND program by typing:
|
||||
#
|
||||
# ./test-rem # From WITHIN Remind source directory!
|
||||
|
||||
REM MSG Today is [hebday(today())] [hebmon(today())] [hebyear(today())]
|
||||
./test.rem(8): Trig = Saturday, 16 February, 1991
|
||||
Reminders for Saturday, 16th February, 1991:
|
||||
|
||||
today() => 1991/02/16
|
||||
hebday(1991/02/16) => 2
|
||||
today() => 1991/02/16
|
||||
hebmon(1991/02/16) => "Adar"
|
||||
today() => 1991/02/16
|
||||
hebyear(1991/02/16) => 5751
|
||||
Today is 2 Adar 5751
|
||||
|
||||
fset _h(x, y) trigger(hebdate(x,y))
|
||||
|
||||
[_h(1, "Tishrey")] MSG Rosh Hashana 1
|
||||
Entering UserFN _h(1, "Tishrey")
|
||||
x => 1
|
||||
y => "Tishrey"
|
||||
hebdate(1, "Tishrey") => 1991/09/09
|
||||
trigger(1991/09/09) => "9 September 1991"
|
||||
Leaving UserFN _h() => "9 September 1991"
|
||||
./test.rem(11): Trig = Monday, 9 September, 1991
|
||||
[_h(2, "Tishrey")] MSG Rosh Hashana 2
|
||||
Entering UserFN _h(2, "Tishrey")
|
||||
x => 2
|
||||
y => "Tishrey"
|
||||
hebdate(2, "Tishrey") => 1991/09/10
|
||||
trigger(1991/09/10) => "10 September 1991"
|
||||
Leaving UserFN _h() => "10 September 1991"
|
||||
./test.rem(12): Trig = Tuesday, 10 September, 1991
|
||||
[_h(3, "Tishrey")] MSG Tzom Gedalia
|
||||
Entering UserFN _h(3, "Tishrey")
|
||||
x => 3
|
||||
y => "Tishrey"
|
||||
hebdate(3, "Tishrey") => 1991/09/11
|
||||
trigger(1991/09/11) => "11 September 1991"
|
||||
Leaving UserFN _h() => "11 September 1991"
|
||||
./test.rem(13): Trig = Wednesday, 11 September, 1991
|
||||
[_h(10, "Tishrey")] MSG Yom Kippur
|
||||
Entering UserFN _h(10, "Tishrey")
|
||||
x => 10
|
||||
y => "Tishrey"
|
||||
hebdate(10, "Tishrey") => 1991/09/18
|
||||
trigger(1991/09/18) => "18 September 1991"
|
||||
Leaving UserFN _h() => "18 September 1991"
|
||||
./test.rem(14): Trig = Wednesday, 18 September, 1991
|
||||
[_h(15, "Tishrey")] MSG Sukkot 1
|
||||
Entering UserFN _h(15, "Tishrey")
|
||||
x => 15
|
||||
y => "Tishrey"
|
||||
hebdate(15, "Tishrey") => 1991/09/23
|
||||
trigger(1991/09/23) => "23 September 1991"
|
||||
Leaving UserFN _h() => "23 September 1991"
|
||||
./test.rem(15): Trig = Monday, 23 September, 1991
|
||||
[_h(25, "Kislev")] MSG Channuka
|
||||
Entering UserFN _h(25, "Kislev")
|
||||
x => 25
|
||||
y => "Kislev"
|
||||
hebdate(25, "Kislev") => 1991/12/02
|
||||
trigger(1991/12/02) => "2 December 1991"
|
||||
Leaving UserFN _h() => "2 December 1991"
|
||||
./test.rem(16): Trig = Monday, 2 December, 1991
|
||||
[_h(10, "Tevet")] MSG Asara B'Tevet
|
||||
Entering UserFN _h(10, "Tevet")
|
||||
x => 10
|
||||
y => "Tevet"
|
||||
hebdate(10, "Tevet") => 1991/12/17
|
||||
trigger(1991/12/17) => "17 December 1991"
|
||||
Leaving UserFN _h() => "17 December 1991"
|
||||
./test.rem(17): Trig = Tuesday, 17 December, 1991
|
||||
[_h(15, "Shvat")] MSG Tu B'Shvat
|
||||
Entering UserFN _h(15, "Shvat")
|
||||
x => 15
|
||||
y => "Shvat"
|
||||
hebdate(15, "Shvat") => 1992/01/20
|
||||
trigger(1992/01/20) => "20 January 1992"
|
||||
Leaving UserFN _h() => "20 January 1992"
|
||||
./test.rem(18): Trig = Monday, 20 January, 1992
|
||||
[_h(15, "Adar A")] MSG Purim Katan
|
||||
Entering UserFN _h(15, "Adar A")
|
||||
x => 15
|
||||
y => "Adar A"
|
||||
hebdate(15, "Adar A") => 1992/02/19
|
||||
trigger(1992/02/19) => "19 February 1992"
|
||||
Leaving UserFN _h() => "19 February 1992"
|
||||
./test.rem(19): Trig = Wednesday, 19 February, 1992
|
||||
[_h(14, "Adar")] MSG Purim
|
||||
Entering UserFN _h(14, "Adar")
|
||||
x => 14
|
||||
y => "Adar"
|
||||
hebdate(14, "Adar") => 1991/02/28
|
||||
trigger(1991/02/28) => "28 February 1991"
|
||||
Leaving UserFN _h() => "28 February 1991"
|
||||
./test.rem(20): Trig = Thursday, 28 February, 1991
|
||||
[_h(15, "Nisan")] MSG Pesach
|
||||
Entering UserFN _h(15, "Nisan")
|
||||
x => 15
|
||||
y => "Nisan"
|
||||
hebdate(15, "Nisan") => 1991/03/30
|
||||
trigger(1991/03/30) => "30 March 1991"
|
||||
Leaving UserFN _h() => "30 March 1991"
|
||||
./test.rem(21): Trig = Saturday, 30 March, 1991
|
||||
[_h(27, "Nisan")] MSG Yom HaShoah
|
||||
Entering UserFN _h(27, "Nisan")
|
||||
x => 27
|
||||
y => "Nisan"
|
||||
hebdate(27, "Nisan") => 1991/04/11
|
||||
trigger(1991/04/11) => "11 April 1991"
|
||||
Leaving UserFN _h() => "11 April 1991"
|
||||
./test.rem(22): Trig = Thursday, 11 April, 1991
|
||||
[_h(4, "Iyar")] MSG Yom HaZikaron
|
||||
Entering UserFN _h(4, "Iyar")
|
||||
x => 4
|
||||
y => "Iyar"
|
||||
hebdate(4, "Iyar") => 1991/04/18
|
||||
trigger(1991/04/18) => "18 April 1991"
|
||||
Leaving UserFN _h() => "18 April 1991"
|
||||
./test.rem(23): Trig = Thursday, 18 April, 1991
|
||||
[_h(5, "Iyar")] MSG Yom Ha'atzmaut
|
||||
Entering UserFN _h(5, "Iyar")
|
||||
x => 5
|
||||
y => "Iyar"
|
||||
hebdate(5, "Iyar") => 1991/04/19
|
||||
trigger(1991/04/19) => "19 April 1991"
|
||||
Leaving UserFN _h() => "19 April 1991"
|
||||
./test.rem(24): Trig = Friday, 19 April, 1991
|
||||
[_h(28, "Iyar")] MSG Yom Yerushalayim
|
||||
Entering UserFN _h(28, "Iyar")
|
||||
x => 28
|
||||
y => "Iyar"
|
||||
hebdate(28, "Iyar") => 1991/05/12
|
||||
trigger(1991/05/12) => "12 May 1991"
|
||||
Leaving UserFN _h() => "12 May 1991"
|
||||
./test.rem(25): Trig = Sunday, 12 May, 1991
|
||||
[_h(6, "Sivan")] MSG Shavuot
|
||||
Entering UserFN _h(6, "Sivan")
|
||||
x => 6
|
||||
y => "Sivan"
|
||||
hebdate(6, "Sivan") => 1991/05/19
|
||||
trigger(1991/05/19) => "19 May 1991"
|
||||
Leaving UserFN _h() => "19 May 1991"
|
||||
./test.rem(26): Trig = Sunday, 19 May, 1991
|
||||
[_h(9, "Av")] MSG Tish'a B'Av
|
||||
Entering UserFN _h(9, "Av")
|
||||
x => 9
|
||||
y => "Av"
|
||||
hebdate(9, "Av") => 1991/07/20
|
||||
trigger(1991/07/20) => "20 July 1991"
|
||||
Leaving UserFN _h() => "20 July 1991"
|
||||
./test.rem(27): Trig = Saturday, 20 July, 1991
|
||||
|
||||
# Test some jahrzeit cases
|
||||
fset _i(x,y,z,a) trigger(hebdate(x,y,z,a))
|
||||
[_i(30, "Heshvan", today(), 5759)] MSG Complete-Complete
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Heshvan", 1991/02/16, 5759)
|
||||
x => 30
|
||||
y => "Heshvan"
|
||||
z => 1991/02/16
|
||||
a => 5759
|
||||
hebdate(30, "Heshvan", 1991/02/16, 5759) => 1991/11/07
|
||||
trigger(1991/11/07) => "7 November 1991"
|
||||
Leaving UserFN _i() => "7 November 1991"
|
||||
./test.rem(31): Trig = Thursday, 7 November, 1991
|
||||
[_i(30, "Heshvan", today(), 5760)] MSG Complete-Defective
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Heshvan", 1991/02/16, 5760)
|
||||
x => 30
|
||||
y => "Heshvan"
|
||||
z => 1991/02/16
|
||||
a => 5760
|
||||
hebdate(30, "Heshvan", 1991/02/16, 5760) => 1991/11/07
|
||||
trigger(1991/11/07) => "7 November 1991"
|
||||
Leaving UserFN _i() => "7 November 1991"
|
||||
./test.rem(32): Trig = Thursday, 7 November, 1991
|
||||
[_i(30, "Heshvan", today(), 5761)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Heshvan", 1991/02/16, 5761)
|
||||
x => 30
|
||||
y => "Heshvan"
|
||||
z => 1991/02/16
|
||||
a => 5761
|
||||
hebdate(30, "Heshvan", 1991/02/16, 5761) => ./test.rem(33): 30 Heshvan 5761: Invalid Hebrew date
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
|
||||
[_i(30, "Kislev", today(), 5759)] MSG Complete-Complete
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Kislev", 1991/02/16, 5759)
|
||||
x => 30
|
||||
y => "Kislev"
|
||||
z => 1991/02/16
|
||||
a => 5759
|
||||
hebdate(30, "Kislev", 1991/02/16, 5759) => 1991/12/07
|
||||
trigger(1991/12/07) => "7 December 1991"
|
||||
Leaving UserFN _i() => "7 December 1991"
|
||||
./test.rem(35): Trig = Saturday, 7 December, 1991
|
||||
[_i(30, "Kislev", today(), 5760)] MSG Complete-Defective
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Kislev", 1991/02/16, 5760)
|
||||
x => 30
|
||||
y => "Kislev"
|
||||
z => 1991/02/16
|
||||
a => 5760
|
||||
hebdate(30, "Kislev", 1991/02/16, 5760) => 1991/12/07
|
||||
trigger(1991/12/07) => "7 December 1991"
|
||||
Leaving UserFN _i() => "7 December 1991"
|
||||
./test.rem(36): Trig = Saturday, 7 December, 1991
|
||||
[_i(30, "Kislev", today(), 5761)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Kislev", 1991/02/16, 5761)
|
||||
x => 30
|
||||
y => "Kislev"
|
||||
z => 1991/02/16
|
||||
a => 5761
|
||||
hebdate(30, "Kislev", 1991/02/16, 5761) => ./test.rem(37): 30 Kislev 5761: Invalid Hebrew date
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
|
||||
[_i(30, "Adar A", today(), 5755)] MSG Leap
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Adar A", 1991/02/16, 5755)
|
||||
x => 30
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5755
|
||||
hebdate(30, "Adar A", 1991/02/16, 5755) => 1992/03/05
|
||||
trigger(1992/03/05) => "5 March 1992"
|
||||
Leaving UserFN _i() => "5 March 1992"
|
||||
./test.rem(39): Trig = Thursday, 5 March, 1992
|
||||
[_i(30, "Adar A", today(), 5756)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Adar A", 1991/02/16, 5756)
|
||||
x => 30
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5756
|
||||
hebdate(30, "Adar A", 1991/02/16, 5756) => ./test.rem(40): No Adar A in 5756
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
[_i(29, "Adar A", today(), 5755)] MSG Leap
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(29, "Adar A", 1991/02/16, 5755)
|
||||
x => 29
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5755
|
||||
hebdate(29, "Adar A", 1991/02/16, 5755) => 1991/03/15
|
||||
trigger(1991/03/15) => "15 March 1991"
|
||||
Leaving UserFN _i() => "15 March 1991"
|
||||
./test.rem(41): Trig = Friday, 15 March, 1991
|
||||
[_i(29, "Adar A", today(), 5756)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(29, "Adar A", 1991/02/16, 5756)
|
||||
x => 29
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5756
|
||||
hebdate(29, "Adar A", 1991/02/16, 5756) => ./test.rem(42): No Adar A in 5756
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
|
||||
# Test each possible case of the basic reminders.
|
||||
|
||||
REM MSG Every Day
|
||||
./test.rem(46): Trig = Saturday, 16 February, 1991
|
||||
Every Day
|
||||
|
||||
|
||||
REM 18 MSG Every 18th
|
||||
./test.rem(48): Trig = Monday, 18 February, 1991
|
||||
REM 15 MSG Every 15th
|
||||
./test.rem(49): Trig = Friday, 15 March, 1991
|
||||
|
||||
REM Feb MSG February
|
||||
./test.rem(51): Trig = Saturday, 16 February, 1991
|
||||
February
|
||||
|
||||
REM Jan MSG January
|
||||
./test.rem(52): Trig = Wednesday, 1 January, 1992
|
||||
REM March MSG March
|
||||
./test.rem(53): Trig = Friday, 1 March, 1991
|
||||
|
||||
REM 13 Jan MSG 13 Jan
|
||||
./test.rem(55): Trig = Monday, 13 January, 1992
|
||||
REM 15 Feb MSG 15 Feb
|
||||
./test.rem(56): Trig = Saturday, 15 February, 1992
|
||||
REM 28 Feb MSG 28 Feb
|
||||
./test.rem(57): Trig = Thursday, 28 February, 1991
|
||||
REM 29 Feb MSG 29 Feb
|
||||
./test.rem(58): Trig = Saturday, 29 February, 1992
|
||||
REM 5 Mar MSG 5 Mar
|
||||
./test.rem(59): Trig = Tuesday, 5 March, 1991
|
||||
|
||||
REM 1990 MSG 1990
|
||||
./test.rem(61): Expired
|
||||
REM 1991 MSG 1991
|
||||
./test.rem(62): Trig = Saturday, 16 February, 1991
|
||||
1991
|
||||
|
||||
REM 1992 MSG 1991
|
||||
./test.rem(63): Trig = Wednesday, 1 January, 1992
|
||||
|
||||
REM 1 1990 MSG 1 1990
|
||||
./test.rem(65): Expired
|
||||
REM 29 1991 MSG 29 1991
|
||||
./test.rem(66): Trig = Friday, 29 March, 1991
|
||||
REM 29 1992 MSG 29 1992
|
||||
./test.rem(67): Trig = Wednesday, 29 January, 1992
|
||||
REM 16 1991 MSG 16 1991
|
||||
./test.rem(68): Trig = Saturday, 16 February, 1991
|
||||
16 1991
|
||||
|
||||
|
||||
REM Jan 1990 MSG Jan 1990
|
||||
./test.rem(70): Expired
|
||||
REM Feb 1991 MSG Feb 1991
|
||||
./test.rem(71): Trig = Saturday, 16 February, 1991
|
||||
Feb 1991
|
||||
|
||||
REM Dec 1991 MSG Dec 1991
|
||||
./test.rem(72): Trig = Sunday, 1 December, 1991
|
||||
REM May 1992 MSG May 1992
|
||||
./test.rem(73): Trig = Friday, 1 May, 1992
|
||||
|
||||
REM 1 Jan 1991 MSG 1 Jan 1991
|
||||
./test.rem(75): Expired
|
||||
REM 16 Feb 1991 MSG 16 Feb 1991
|
||||
./test.rem(76): Trig = Saturday, 16 February, 1991
|
||||
16 Feb 1991
|
||||
|
||||
REM 29 Dec 1992 MSG 29 Dec 1992
|
||||
./test.rem(77): Trig = Tuesday, 29 December, 1992
|
||||
|
||||
REM Sun MSG Sun
|
||||
./test.rem(79): Trig = Sunday, 17 February, 1991
|
||||
REM Fri Sat Tue MSG Fri Sat Tue
|
||||
./test.rem(80): Trig = Saturday, 16 February, 1991
|
||||
Fri Sat Tue
|
||||
|
||||
|
||||
REM Sun 16 MSG Sun 16
|
||||
./test.rem(82): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue Wed Thu Fri 1 MSG Mon Tue Wed Thu Fri 1
|
||||
./test.rem(83): Trig = Friday, 1 March, 1991
|
||||
|
||||
REM Sun Feb MSG Sun Feb
|
||||
./test.rem(85): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue March MSG Mon Tue March
|
||||
./test.rem(86): Trig = Monday, 4 March, 1991
|
||||
|
||||
REM Sun 16 Feb MSG Sun 16 Feb
|
||||
./test.rem(88): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue 10 March MSG Mon Tue 10 March
|
||||
./test.rem(89): Trig = Monday, 11 March, 1991
|
||||
|
||||
REM Sat Sun 1991 MSG Sat Sun 1991
|
||||
./test.rem(91): Trig = Saturday, 16 February, 1991
|
||||
Sat Sun 1991
|
||||
|
||||
REM Mon Tue 1992 MSG Mon Tue 1992
|
||||
./test.rem(92): Trig = Monday, 6 January, 1992
|
||||
|
||||
REM Sun 16 1991 MSG Sun 16 1991
|
||||
./test.rem(94): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue Wed Thu Fri 1 1992 MSG Mon Tue Wed Thu Fri 1 1992
|
||||
./test.rem(95): Trig = Wednesday, 1 January, 1992
|
||||
|
||||
REM Mon Feb 1991 MSG Mon Feb 1991
|
||||
./test.rem(97): Trig = Monday, 18 February, 1991
|
||||
REM Tue Jan 1992 MSG Tue Jan 1992
|
||||
./test.rem(98): Trig = Tuesday, 7 January, 1992
|
||||
|
||||
REM Sun Mon 16 Feb 1991 MSG Sun Mon 16 Feb 1991
|
||||
./test.rem(100): Trig = Sunday, 17 February, 1991
|
||||
REM Tue 28 Jan 1992 MSG Tue 28 Jan 1992
|
||||
./test.rem(101): Trig = Tuesday, 28 January, 1992
|
||||
|
||||
# Try some Backs
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun
|
||||
./test.rem(105): Trig = Thursday, 28 February, 1991
|
||||
REM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun
|
||||
./test.rem(106): Trig = Thursday, 28 February, 1991
|
||||
|
||||
OMIT 28 Feb
|
||||
REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun (28 Feb omitted)
|
||||
./test.rem(109): Trig = Wednesday, 27 February, 1991
|
||||
REM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun (28 Feb omitted)
|
||||
./test.rem(110): Trig = Thursday, 28 February, 1991
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
|
||||
# Try out UNTIL
|
||||
REM Wed UNTIL 21 Feb 1991 MSG Wed UNTIL 21 Feb 1991
|
||||
./test.rem(115): Trig = Wednesday, 20 February, 1991
|
||||
|
||||
# Try playing with the OMIT context
|
||||
|
||||
OMIT 28 Feb 1991
|
||||
REM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
|
||||
./test.rem(120): Trig = Wednesday, 27 February, 1991
|
||||
REM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
|
||||
./test.rem(121): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
|
||||
./test.rem(122): Trig = Wednesday, 27 February, 1991
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
|
||||
./test.rem(123): Trig = Friday, 28 February, 1992
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
|
||||
./test.rem(124): Trig = Friday, 1 March, 1991
|
||||
|
||||
PUSH-OMIT-CONTEXT
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 1 Mar -1 MSG 1 mar -1
|
||||
./test.rem(128): Trig = Thursday, 28 February, 1991
|
||||
REM 1 Mar --1 MSG 1 mar --1
|
||||
./test.rem(129): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE
|
||||
./test.rem(130): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP
|
||||
./test.rem(131): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER
|
||||
./test.rem(132): Trig = Thursday, 28 February, 1991
|
||||
|
||||
POP-OMIT-CONTEXT
|
||||
REM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
|
||||
./test.rem(135): Trig = Wednesday, 27 February, 1991
|
||||
REM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
|
||||
./test.rem(136): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
|
||||
./test.rem(137): Trig = Wednesday, 27 February, 1991
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
|
||||
./test.rem(138): Trig = Friday, 28 February, 1992
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
|
||||
./test.rem(139): Trig = Friday, 1 March, 1991
|
||||
|
||||
|
||||
REM 13 March 1991 *1 UNTIL 19 March 1991 MSG 13-19 Mar 91
|
||||
./test.rem(142): Trig = Wednesday, 13 March, 1991
|
||||
|
||||
# Test BACK
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 18 Feb 1991 +1 MSG 18 Feb 1991 +1
|
||||
./test.rem(146): Trig = Monday, 18 February, 1991
|
||||
|
||||
OMIT 17 Feb 1991
|
||||
REM 18 Feb 1991 +1 MSG 18 Feb 1991 +1 (17Feb91 omitted)
|
||||
./test.rem(149): Trig = Monday, 18 February, 1991
|
||||
18 Feb 1991 +1 (17Feb91 omitted)
|
||||
|
||||
REM 18 Feb 1991 ++1 MSG 18 Feb 1991 ++1 (17Feb91 omitted)
|
||||
./test.rem(150): Trig = Monday, 18 February, 1991
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
# Test the scanfrom clause
|
||||
REM Fri SATISFY 1
|
||||
./test.rem(154): Trig = Friday, 22 February, 1991
|
||||
OMIT [trigger(trigdate())]
|
||||
trigdate() => 1991/02/22
|
||||
trigger(1991/02/22) => "22 February 1991"
|
||||
REM Fri after MSG 23 Feb 1991
|
||||
./test.rem(156): Trig = Saturday, 23 February, 1991
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM Fri SCANFROM [trigger(today()-7)] SATISFY 1
|
||||
today() => 1991/02/16
|
||||
1991/02/16 - 7 => 1991/02/09
|
||||
trigger(1991/02/09) => "9 February 1991"
|
||||
./test.rem(158): Trig = Friday, 15 February, 1991
|
||||
OMIT [trigger(trigdate())]
|
||||
trigdate() => 1991/02/15
|
||||
trigger(1991/02/15) => "15 February 1991"
|
||||
REM Fri after MSG 16 Feb 1991
|
||||
./test.rem(160): Trig = Saturday, 16 February, 1991
|
||||
16 Feb 1991
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
set a000 abs(1)
|
||||
abs(1) => 1
|
||||
set a001 abs(-1)
|
||||
- 1 => -1
|
||||
abs(-1) => 1
|
||||
set a002 asc("foo")
|
||||
asc("foo") => 102
|
||||
set a003 baseyr()
|
||||
baseyr() => 1990
|
||||
set a004 char(66,55,66,77,66)
|
||||
char(66, 55, 66, 77, 66) => "B7BMB"
|
||||
set a005 choose(3, "foo", "bar", "baz", "blech")
|
||||
choose(3, "foo", "bar", "baz", "blech") => "baz"
|
||||
set a006 coerce("string", 1)
|
||||
coerce("string", 1) => "1"
|
||||
set a007 coerce("string", today())
|
||||
today() => 1991/02/16
|
||||
coerce("string", 1991/02/16) => "1991/02/16"
|
||||
set a008 coerce("string", 11:44)
|
||||
coerce("string", 11:44) => "11:44"
|
||||
set a009 coerce("int", "badnews")
|
||||
coerce("int", "badnews") => Can't coerce
|
||||
./test.rem(171): Can't coerce
|
||||
set a010 coerce("int", "12")
|
||||
coerce("int", "12") => 12
|
||||
set a011 coerce("int", 11:44)
|
||||
coerce("int", 11:44) => 704
|
||||
set a012 coerce("int", today())
|
||||
today() => 1991/02/16
|
||||
coerce("int", 1991/02/16) => 411
|
||||
set a013 date(1992, 2, 2)
|
||||
date(1992, 2, 2) => 1992/02/02
|
||||
set a014 date(1993, 2, 29)
|
||||
date(1993, 2, 29) => Bad date specification
|
||||
./test.rem(176): Bad date specification
|
||||
set a015 day(today())
|
||||
today() => 1991/02/16
|
||||
day(1991/02/16) => 16
|
||||
set a016 daysinmon(2, 1991)
|
||||
daysinmon(2, 1991) => 28
|
||||
set a017 daysinmon(2, 1992)
|
||||
daysinmon(2, 1992) => 29
|
||||
set a018 defined("a017")
|
||||
defined("a017") => 1
|
||||
set a019 defined("a019")
|
||||
defined("a019") => 0
|
||||
set a020 filename()
|
||||
filename() => "./test.rem"
|
||||
set a021 getenv("TEST_GETENV")
|
||||
getenv("TEST_GETENV") => "foo bar baz"
|
||||
set a022 hour(11:22)
|
||||
hour(11:22) => 11
|
||||
set a023 iif(1, 1, 0)
|
||||
iif(1, 1, 0) => 1
|
||||
set a024 iif(0, 1, 0)
|
||||
iif(0, 1, 0) => 0
|
||||
set a025 index("barfoobar", "foo")
|
||||
index("barfoobar", "foo") => 4
|
||||
set a026 index("barfoobar", "bar", 2)
|
||||
index("barfoobar", "bar", 2) => 7
|
||||
set a027 isleap(today())
|
||||
today() => 1991/02/16
|
||||
isleap(1991/02/16) => 0
|
||||
set a028 isleap(1992)
|
||||
isleap(1992) => 1
|
||||
omit [trigger(today())]
|
||||
today() => 1991/02/16
|
||||
trigger(1991/02/16) => "16 February 1991"
|
||||
set a030 isomitted(today())
|
||||
today() => 1991/02/16
|
||||
isomitted(1991/02/16) => 1
|
||||
clear
|
||||
set a029 isomitted(today())
|
||||
today() => 1991/02/16
|
||||
isomitted(1991/02/16) => 0
|
||||
set a031 lower("FOOBARBAZ")
|
||||
lower("FOOBARBAZ") => "foobarbaz"
|
||||
set a032 max(1, 2, 34, 1, 3)
|
||||
max(1, 2, 34, 1, 3) => 34
|
||||
set a033 max("foo", "bar", "baz")
|
||||
max("foo", "bar", "baz") => "foo"
|
||||
set a034 max(today(), today()+1, today()-1)
|
||||
today() => 1991/02/16
|
||||
today() => 1991/02/16
|
||||
1991/02/16 + 1 => 1991/02/17
|
||||
today() => 1991/02/16
|
||||
1991/02/16 - 1 => 1991/02/15
|
||||
max(1991/02/16, 1991/02/17, 1991/02/15) => 1991/02/17
|
||||
set a035 min(1, 2, 34, 1, 3)
|
||||
min(1, 2, 34, 1, 3) => 1
|
||||
set a036 min("foo", "bar", "baz")
|
||||
min("foo", "bar", "baz") => "bar"
|
||||
set a037 min(today(), today()+1, today()-1)
|
||||
today() => 1991/02/16
|
||||
today() => 1991/02/16
|
||||
1991/02/16 + 1 => 1991/02/17
|
||||
today() => 1991/02/16
|
||||
1991/02/16 - 1 => 1991/02/15
|
||||
min(1991/02/16, 1991/02/17, 1991/02/15) => 1991/02/15
|
||||
set a038 minute(11:33)
|
||||
minute(11:33) => 33
|
||||
set a039 mon(today())
|
||||
today() => 1991/02/16
|
||||
mon(1991/02/16) => "February"
|
||||
set a040 monnum(today())
|
||||
today() => 1991/02/16
|
||||
monnum(1991/02/16) => 2
|
||||
set a041 ord(3)
|
||||
ord(3) => "3rd"
|
||||
set a042 ord(4)
|
||||
ord(4) => "4th"
|
||||
set a043 ostype()
|
||||
ostype() => "UNIX"
|
||||
set a044 plural(2)
|
||||
plural(2) => "s"
|
||||
set a045 plural(2, "ies")
|
||||
plural(2, "ies") => "iess"
|
||||
set a046 plural(2, "y", "ies")
|
||||
plural(2, "y", "ies") => "ies"
|
||||
set a047 sgn(-2)
|
||||
- 2 => -2
|
||||
sgn(-2) => -1
|
||||
set a048 shell("echo foo")
|
||||
shell("echo foo") => "foo"
|
||||
set a049 strlen("sadjflkhsldkfhsdlfjhk")
|
||||
strlen("sadjflkhsldkfhsdlfjhk") => 21
|
||||
set a050 substr(a049, 2)
|
||||
a049 => 21
|
||||
substr(21, 2) => Type mismatch
|
||||
./test.rem(214): Type mismatch
|
||||
set a051 substr(a050, 2, 6)
|
||||
a050 => ./test.rem(215): Undefined variable: a050
|
||||
set a052 time(1+2, 3+4)
|
||||
1 + 2 => 3
|
||||
3 + 4 => 7
|
||||
time(3, 7) => 03:07
|
||||
rem 10 jan 1992 AT 11:22 CAL
|
||||
./test.rem(217): Trig = Friday, 10 January, 1992
|
||||
set a053 trigdate()
|
||||
trigdate() => 1992/01/10
|
||||
set a054 trigtime()
|
||||
trigtime() => 11:22
|
||||
set a055 trigvalid()
|
||||
trigvalid() => 1
|
||||
set a056 upper("sdfjhsdf ksjdfh kjsdfh ksjdfh")
|
||||
upper("sdfjhsdf ksjdfh kjsdfh ksjdfh") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
set a057 value("a05"+"6")
|
||||
"a05" + "6" => "a056"
|
||||
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
set a058 version()
|
||||
version() => "03.00.13"
|
||||
set a059 wkday(today())
|
||||
today() => 1991/02/16
|
||||
wkday(1991/02/16) => "Saturday"
|
||||
set a060 wkdaynum(today())
|
||||
today() => 1991/02/16
|
||||
wkdaynum(1991/02/16) => 6
|
||||
set a061 year(today())
|
||||
today() => 1991/02/16
|
||||
year(1991/02/16) => 1991
|
||||
set a062 1+2*(3+4-(5*7/2))
|
||||
3 + 4 => 7
|
||||
5 * 7 => 35
|
||||
35 / 2 => 17
|
||||
7 - 17 => -10
|
||||
2 * -10 => -20
|
||||
1 + -20 => -19
|
||||
set a063 1>=2
|
||||
1 >= 2 => 0
|
||||
set a064 1<2 || 3 > 4
|
||||
1 < 2 => 1
|
||||
3 > 4 => 0
|
||||
1 || 0 => 1
|
||||
set a065 1 && 1
|
||||
1 && 1 => 1
|
||||
set a066 !a065
|
||||
a065 => 1
|
||||
! 1 => 0
|
||||
set a067 typeof(2)
|
||||
typeof(2) => "INT"
|
||||
set a068 typeof("foo")
|
||||
typeof("foo") => "STRING"
|
||||
set a069 typeof(11:33)
|
||||
typeof(11:33) => "TIME"
|
||||
set a070 typeof(today())
|
||||
today() => 1991/02/16
|
||||
typeof(1991/02/16) => "DATE"
|
||||
fset g(x,y) max(x,y)
|
||||
fset h(x,y) min(g(x+y, x*y), g(x-y, x/y))
|
||||
set a071 g(1, 2)
|
||||
Entering UserFN g(1, 2)
|
||||
x => 1
|
||||
y => 2
|
||||
max(1, 2) => 2
|
||||
Leaving UserFN g() => 2
|
||||
set a072 h(2, 3)
|
||||
Entering UserFN h(2, 3)
|
||||
x => 2
|
||||
y => 3
|
||||
2 + 3 => 5
|
||||
x => 2
|
||||
y => 3
|
||||
2 * 3 => 6
|
||||
Entering UserFN g(5, 6)
|
||||
x => 5
|
||||
y => 6
|
||||
max(5, 6) => 6
|
||||
Leaving UserFN g() => 6
|
||||
x => 2
|
||||
y => 3
|
||||
2 - 3 => -1
|
||||
x => 2
|
||||
y => 3
|
||||
2 / 3 => 0
|
||||
Entering UserFN g(-1, 0)
|
||||
x => -1
|
||||
y => 0
|
||||
max(-1, 0) => 0
|
||||
Leaving UserFN g() => 0
|
||||
min(6, 0) => 0
|
||||
Leaving UserFN h() => 0
|
||||
set a073 h("foo", 11:33)
|
||||
Entering UserFN h("foo", 11:33)
|
||||
x => "foo"
|
||||
y => 11:33
|
||||
"foo" + 11:33 => "foo11:33"
|
||||
x => "foo"
|
||||
y => 11:33
|
||||
"foo" * 11:33 => Type mismatch
|
||||
./test.rem(240): '*': Type mismatch
|
||||
Leaving UserFN h() => Type mismatch
|
||||
set a074 dosubst("%a %b %c %d %e %f %g %h", '1992/5/5')
|
||||
dosubst("%a %b %c %d %e %f %g %h", 1992/05/05) => "on Tuesday, 5 May, 1992 in 444 days' tim"...
|
||||
msg [a074]%
|
||||
./test.rem(242): Trig = Saturday, 16 February, 1991
|
||||
a074 => "on Tuesday, 5 May, 1992 in 444 days' tim"...
|
||||
on Tuesday, 5 May, 1992 in 444 days' time on Tuesday 5 on 05/05/1992 on 05/05/1992 on Tuesday, 5 May on 05/05
|
||||
set a075 dosubst("%i %j %k %l %m %n %o %p", '1992/5/5')
|
||||
dosubst("%i %j %k %l %m %n %o %p", 1992/05/05) => "on 05/05 on Tuesday, May 5th, 1992 on Tu"...
|
||||
msg [a075]%
|
||||
./test.rem(244): Trig = Saturday, 16 February, 1991
|
||||
a075 => "on 05/05 on Tuesday, May 5th, 1992 on Tu"...
|
||||
on 05/05 on Tuesday, May 5th, 1992 on Tuesday, May 5th on 1992/05/05 May 5 s
|
||||
set a076 dosubst("%q %r %s %t %u %v %w %x", '1992/5/5')
|
||||
dosubst("%q %r %s %t %u %v %w %x", 1992/05/05) => "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
|
||||
msg [a076]%
|
||||
./test.rem(246): Trig = Saturday, 16 February, 1991
|
||||
a076 => "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
|
||||
s' 05 th 05 on Tuesday, 5th May, 1992 on Tuesday, 5th May Tuesday 444
|
||||
set a077 dosubst("%y %z", '1992/5/5')
|
||||
dosubst("%y %z", 1992/05/05) => "1992 92
|
||||
"
|
||||
msg [a077]%
|
||||
./test.rem(248): Trig = Saturday, 16 February, 1991
|
||||
a077 => "1992 92
|
||||
"
|
||||
1992 92
|
||||
set a078 easterdate(today())
|
||||
today() => 1991/02/16
|
||||
easterdate(1991/02/16) => 1991/03/31
|
||||
set a079 easterdate(1992)
|
||||
easterdate(1992) => 1992/04/19
|
||||
set a080 easterdate(1995)
|
||||
easterdate(1995) => 1995/04/16
|
||||
set a081 ""
|
||||
dump
|
||||
Variable Value
|
||||
|
||||
a017 29
|
||||
a036 "bar"
|
||||
a055 1
|
||||
a074 "on Tuesday, 5 May, 1992 in 444 days' tim"...
|
||||
a008 "11:44"
|
||||
a027 0
|
||||
a046 "ies"
|
||||
a065 1
|
||||
a018 1
|
||||
a037 1991/02/15
|
||||
a056 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
a075 "on 05/05 on Tuesday, May 5th, 1992 on Tu"...
|
||||
a028 1
|
||||
a047 -1
|
||||
a066 0
|
||||
a019 0
|
||||
a038 33
|
||||
a057 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
a076 "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
|
||||
a029 0
|
||||
a048 "foo"
|
||||
a067 "INT"
|
||||
a039 "February"
|
||||
a058 "03.00.13"
|
||||
a077 "1992 92
|
||||
"
|
||||
a049 21
|
||||
a068 "STRING"
|
||||
a059 "Saturday"
|
||||
a078 1991/03/31
|
||||
a069 "TIME"
|
||||
a079 1992/04/19
|
||||
a000 1
|
||||
a010 12
|
||||
a001 1
|
||||
a020 "./test.rem"
|
||||
a011 704
|
||||
a030 1
|
||||
a002 102
|
||||
a021 "foo bar baz"
|
||||
a040 2
|
||||
a012 411
|
||||
a031 "foobarbaz"
|
||||
a003 1990
|
||||
a022 11
|
||||
a041 "3rd"
|
||||
a060 6
|
||||
a013 1992/02/02
|
||||
a032 34
|
||||
a070 "DATE"
|
||||
a004 "B7BMB"
|
||||
a023 1
|
||||
a042 "4th"
|
||||
a061 1991
|
||||
a080 1995/04/16
|
||||
a033 "foo"
|
||||
a052 03:07
|
||||
a071 2
|
||||
a005 "baz"
|
||||
a024 0
|
||||
a043 "UNIX"
|
||||
a062 -19
|
||||
a081 ""
|
||||
a015 16
|
||||
a034 1991/02/17
|
||||
a053 1992/01/10
|
||||
a072 0
|
||||
a006 "1"
|
||||
a025 4
|
||||
a044 "s"
|
||||
a063 0
|
||||
a016 28
|
||||
a035 1
|
||||
a054 11:22
|
||||
a007 "1991/02/16"
|
||||
a026 7
|
||||
a045 "iess"
|
||||
a064 1
|
||||
|
||||
255
test.rem
Normal file
255
test.rem
Normal file
@@ -0,0 +1,255 @@
|
||||
# Test file for REMIND
|
||||
#
|
||||
# $Id: test.rem,v 1.1 1996-03-27 03:26:12 dfs Exp $
|
||||
#
|
||||
# Use this file to test the date calculation routines
|
||||
# of the REMIND program by typing:
|
||||
#
|
||||
# ./test-rem # From WITHIN Remind source directory!
|
||||
|
||||
REM MSG Today is [hebday(today())] [hebmon(today())] [hebyear(today())]
|
||||
fset _h(x, y) trigger(hebdate(x,y))
|
||||
|
||||
[_h(1, "Tishrey")] MSG Rosh Hashana 1
|
||||
[_h(2, "Tishrey")] MSG Rosh Hashana 2
|
||||
[_h(3, "Tishrey")] MSG Tzom Gedalia
|
||||
[_h(10, "Tishrey")] MSG Yom Kippur
|
||||
[_h(15, "Tishrey")] MSG Sukkot 1
|
||||
[_h(25, "Kislev")] MSG Channuka
|
||||
[_h(10, "Tevet")] MSG Asara B'Tevet
|
||||
[_h(15, "Shvat")] MSG Tu B'Shvat
|
||||
[_h(15, "Adar A")] MSG Purim Katan
|
||||
[_h(14, "Adar")] MSG Purim
|
||||
[_h(15, "Nisan")] MSG Pesach
|
||||
[_h(27, "Nisan")] MSG Yom HaShoah
|
||||
[_h(4, "Iyar")] MSG Yom HaZikaron
|
||||
[_h(5, "Iyar")] MSG Yom Ha'atzmaut
|
||||
[_h(28, "Iyar")] MSG Yom Yerushalayim
|
||||
[_h(6, "Sivan")] MSG Shavuot
|
||||
[_h(9, "Av")] MSG Tish'a B'Av
|
||||
|
||||
# Test some jahrzeit cases
|
||||
fset _i(x,y,z,a) trigger(hebdate(x,y,z,a))
|
||||
[_i(30, "Heshvan", today(), 5759)] MSG Complete-Complete
|
||||
[_i(30, "Heshvan", today(), 5760)] MSG Complete-Defective
|
||||
[_i(30, "Heshvan", today(), 5761)] MSG Illegal
|
||||
|
||||
[_i(30, "Kislev", today(), 5759)] MSG Complete-Complete
|
||||
[_i(30, "Kislev", today(), 5760)] MSG Complete-Defective
|
||||
[_i(30, "Kislev", today(), 5761)] MSG Illegal
|
||||
|
||||
[_i(30, "Adar A", today(), 5755)] MSG Leap
|
||||
[_i(30, "Adar A", today(), 5756)] MSG Illegal
|
||||
[_i(29, "Adar A", today(), 5755)] MSG Leap
|
||||
[_i(29, "Adar A", today(), 5756)] MSG Illegal
|
||||
|
||||
# Test each possible case of the basic reminders.
|
||||
|
||||
REM MSG Every Day
|
||||
|
||||
REM 18 MSG Every 18th
|
||||
REM 15 MSG Every 15th
|
||||
|
||||
REM Feb MSG February
|
||||
REM Jan MSG January
|
||||
REM March MSG March
|
||||
|
||||
REM 13 Jan MSG 13 Jan
|
||||
REM 15 Feb MSG 15 Feb
|
||||
REM 28 Feb MSG 28 Feb
|
||||
REM 29 Feb MSG 29 Feb
|
||||
REM 5 Mar MSG 5 Mar
|
||||
|
||||
REM 1990 MSG 1990
|
||||
REM 1991 MSG 1991
|
||||
REM 1992 MSG 1991
|
||||
|
||||
REM 1 1990 MSG 1 1990
|
||||
REM 29 1991 MSG 29 1991
|
||||
REM 29 1992 MSG 29 1992
|
||||
REM 16 1991 MSG 16 1991
|
||||
|
||||
REM Jan 1990 MSG Jan 1990
|
||||
REM Feb 1991 MSG Feb 1991
|
||||
REM Dec 1991 MSG Dec 1991
|
||||
REM May 1992 MSG May 1992
|
||||
|
||||
REM 1 Jan 1991 MSG 1 Jan 1991
|
||||
REM 16 Feb 1991 MSG 16 Feb 1991
|
||||
REM 29 Dec 1992 MSG 29 Dec 1992
|
||||
|
||||
REM Sun MSG Sun
|
||||
REM Fri Sat Tue MSG Fri Sat Tue
|
||||
|
||||
REM Sun 16 MSG Sun 16
|
||||
REM Mon Tue Wed Thu Fri 1 MSG Mon Tue Wed Thu Fri 1
|
||||
|
||||
REM Sun Feb MSG Sun Feb
|
||||
REM Mon Tue March MSG Mon Tue March
|
||||
|
||||
REM Sun 16 Feb MSG Sun 16 Feb
|
||||
REM Mon Tue 10 March MSG Mon Tue 10 March
|
||||
|
||||
REM Sat Sun 1991 MSG Sat Sun 1991
|
||||
REM Mon Tue 1992 MSG Mon Tue 1992
|
||||
|
||||
REM Sun 16 1991 MSG Sun 16 1991
|
||||
REM Mon Tue Wed Thu Fri 1 1992 MSG Mon Tue Wed Thu Fri 1 1992
|
||||
|
||||
REM Mon Feb 1991 MSG Mon Feb 1991
|
||||
REM Tue Jan 1992 MSG Tue Jan 1992
|
||||
|
||||
REM Sun Mon 16 Feb 1991 MSG Sun Mon 16 Feb 1991
|
||||
REM Tue 28 Jan 1992 MSG Tue 28 Jan 1992
|
||||
|
||||
# Try some Backs
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun
|
||||
REM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun
|
||||
|
||||
OMIT 28 Feb
|
||||
REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun (28 Feb omitted)
|
||||
REM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun (28 Feb omitted)
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
|
||||
# Try out UNTIL
|
||||
REM Wed UNTIL 21 Feb 1991 MSG Wed UNTIL 21 Feb 1991
|
||||
|
||||
# Try playing with the OMIT context
|
||||
|
||||
OMIT 28 Feb 1991
|
||||
REM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
|
||||
REM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
|
||||
|
||||
PUSH-OMIT-CONTEXT
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 1 Mar -1 MSG 1 mar -1
|
||||
REM 1 Mar --1 MSG 1 mar --1
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER
|
||||
|
||||
POP-OMIT-CONTEXT
|
||||
REM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
|
||||
REM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
|
||||
|
||||
|
||||
REM 13 March 1991 *1 UNTIL 19 March 1991 MSG 13-19 Mar 91
|
||||
|
||||
# Test BACK
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 18 Feb 1991 +1 MSG 18 Feb 1991 +1
|
||||
|
||||
OMIT 17 Feb 1991
|
||||
REM 18 Feb 1991 +1 MSG 18 Feb 1991 +1 (17Feb91 omitted)
|
||||
REM 18 Feb 1991 ++1 MSG 18 Feb 1991 ++1 (17Feb91 omitted)
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
# Test the scanfrom clause
|
||||
REM Fri SATISFY 1
|
||||
OMIT [trigger(trigdate())]
|
||||
REM Fri after MSG 23 Feb 1991
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM Fri SCANFROM [trigger(today()-7)] SATISFY 1
|
||||
OMIT [trigger(trigdate())]
|
||||
REM Fri after MSG 16 Feb 1991
|
||||
CLEAR-OMIT-CONTEXT
|
||||
set a000 abs(1)
|
||||
set a001 abs(-1)
|
||||
set a002 asc("foo")
|
||||
set a003 baseyr()
|
||||
set a004 char(66,55,66,77,66)
|
||||
set a005 choose(3, "foo", "bar", "baz", "blech")
|
||||
set a006 coerce("string", 1)
|
||||
set a007 coerce("string", today())
|
||||
set a008 coerce("string", 11:44)
|
||||
set a009 coerce("int", "badnews")
|
||||
set a010 coerce("int", "12")
|
||||
set a011 coerce("int", 11:44)
|
||||
set a012 coerce("int", today())
|
||||
set a013 date(1992, 2, 2)
|
||||
set a014 date(1993, 2, 29)
|
||||
set a015 day(today())
|
||||
set a016 daysinmon(2, 1991)
|
||||
set a017 daysinmon(2, 1992)
|
||||
set a018 defined("a017")
|
||||
set a019 defined("a019")
|
||||
set a020 filename()
|
||||
set a021 getenv("TEST_GETENV")
|
||||
set a022 hour(11:22)
|
||||
set a023 iif(1, 1, 0)
|
||||
set a024 iif(0, 1, 0)
|
||||
set a025 index("barfoobar", "foo")
|
||||
set a026 index("barfoobar", "bar", 2)
|
||||
set a027 isleap(today())
|
||||
set a028 isleap(1992)
|
||||
omit [trigger(today())]
|
||||
set a030 isomitted(today())
|
||||
clear
|
||||
set a029 isomitted(today())
|
||||
set a031 lower("FOOBARBAZ")
|
||||
set a032 max(1, 2, 34, 1, 3)
|
||||
set a033 max("foo", "bar", "baz")
|
||||
set a034 max(today(), today()+1, today()-1)
|
||||
set a035 min(1, 2, 34, 1, 3)
|
||||
set a036 min("foo", "bar", "baz")
|
||||
set a037 min(today(), today()+1, today()-1)
|
||||
set a038 minute(11:33)
|
||||
set a039 mon(today())
|
||||
set a040 monnum(today())
|
||||
set a041 ord(3)
|
||||
set a042 ord(4)
|
||||
set a043 ostype()
|
||||
set a044 plural(2)
|
||||
set a045 plural(2, "ies")
|
||||
set a046 plural(2, "y", "ies")
|
||||
set a047 sgn(-2)
|
||||
set a048 shell("echo foo")
|
||||
set a049 strlen("sadjflkhsldkfhsdlfjhk")
|
||||
set a050 substr(a049, 2)
|
||||
set a051 substr(a050, 2, 6)
|
||||
set a052 time(1+2, 3+4)
|
||||
rem 10 jan 1992 AT 11:22 CAL
|
||||
set a053 trigdate()
|
||||
set a054 trigtime()
|
||||
set a055 trigvalid()
|
||||
set a056 upper("sdfjhsdf ksjdfh kjsdfh ksjdfh")
|
||||
set a057 value("a05"+"6")
|
||||
set a058 version()
|
||||
set a059 wkday(today())
|
||||
set a060 wkdaynum(today())
|
||||
set a061 year(today())
|
||||
set a062 1+2*(3+4-(5*7/2))
|
||||
set a063 1>=2
|
||||
set a064 1<2 || 3 > 4
|
||||
set a065 1 && 1
|
||||
set a066 !a065
|
||||
set a067 typeof(2)
|
||||
set a068 typeof("foo")
|
||||
set a069 typeof(11:33)
|
||||
set a070 typeof(today())
|
||||
fset g(x,y) max(x,y)
|
||||
fset h(x,y) min(g(x+y, x*y), g(x-y, x/y))
|
||||
set a071 g(1, 2)
|
||||
set a072 h(2, 3)
|
||||
set a073 h("foo", 11:33)
|
||||
set a074 dosubst("%a %b %c %d %e %f %g %h", '1992/5/5')
|
||||
msg [a074]%
|
||||
set a075 dosubst("%i %j %k %l %m %n %o %p", '1992/5/5')
|
||||
msg [a075]%
|
||||
set a076 dosubst("%q %r %s %t %u %v %w %x", '1992/5/5')
|
||||
msg [a076]%
|
||||
set a077 dosubst("%y %z", '1992/5/5')
|
||||
msg [a077]%
|
||||
set a078 easterdate(today())
|
||||
set a079 easterdate(1992)
|
||||
set a080 easterdate(1995)
|
||||
set a081 ""
|
||||
dump
|
||||
832
test1.cmp
Normal file
832
test1.cmp
Normal file
@@ -0,0 +1,832 @@
|
||||
# Test file for REMIND
|
||||
#
|
||||
# $Id: test1.cmp,v 1.1 1996-03-27 03:26:12 dfs Exp $
|
||||
#
|
||||
# Use this file to test the date calculation routines
|
||||
# of the REMIND program by typing:
|
||||
#
|
||||
# ./test-rem # From WITHIN Remind source directory!
|
||||
|
||||
REM MSG Today is [hebday(today())] [hebmon(today())] [hebyear(today())]
|
||||
.\test.rem(8): Trig = Saturday, 16 February, 1991
|
||||
Reminders for Saturday, 16th February, 1991:
|
||||
|
||||
today() => 1991/02/16
|
||||
hebday(1991/02/16) => 2
|
||||
today() => 1991/02/16
|
||||
hebmon(1991/02/16) => "Adar"
|
||||
today() => 1991/02/16
|
||||
hebyear(1991/02/16) => 5751
|
||||
Today is 2 Adar 5751
|
||||
|
||||
fset _h(x, y) trigger(hebdate(x,y))
|
||||
|
||||
[_h(1, "Tishrey")] MSG Rosh Hashana 1
|
||||
Entering UserFN _h(1, "Tishrey")
|
||||
x => 1
|
||||
y => "Tishrey"
|
||||
hebdate(1, "Tishrey") => 1991/09/09
|
||||
trigger(1991/09/09) => "9 September 1991"
|
||||
Leaving UserFN _h() => "9 September 1991"
|
||||
.\test.rem(11): Trig = Monday, 9 September, 1991
|
||||
[_h(2, "Tishrey")] MSG Rosh Hashana 2
|
||||
Entering UserFN _h(2, "Tishrey")
|
||||
x => 2
|
||||
y => "Tishrey"
|
||||
hebdate(2, "Tishrey") => 1991/09/10
|
||||
trigger(1991/09/10) => "10 September 1991"
|
||||
Leaving UserFN _h() => "10 September 1991"
|
||||
.\test.rem(12): Trig = Tuesday, 10 September, 1991
|
||||
[_h(3, "Tishrey")] MSG Tzom Gedalia
|
||||
Entering UserFN _h(3, "Tishrey")
|
||||
x => 3
|
||||
y => "Tishrey"
|
||||
hebdate(3, "Tishrey") => 1991/09/11
|
||||
trigger(1991/09/11) => "11 September 1991"
|
||||
Leaving UserFN _h() => "11 September 1991"
|
||||
.\test.rem(13): Trig = Wednesday, 11 September, 1991
|
||||
[_h(10, "Tishrey")] MSG Yom Kippur
|
||||
Entering UserFN _h(10, "Tishrey")
|
||||
x => 10
|
||||
y => "Tishrey"
|
||||
hebdate(10, "Tishrey") => 1991/09/18
|
||||
trigger(1991/09/18) => "18 September 1991"
|
||||
Leaving UserFN _h() => "18 September 1991"
|
||||
.\test.rem(14): Trig = Wednesday, 18 September, 1991
|
||||
[_h(15, "Tishrey")] MSG Sukkot 1
|
||||
Entering UserFN _h(15, "Tishrey")
|
||||
x => 15
|
||||
y => "Tishrey"
|
||||
hebdate(15, "Tishrey") => 1991/09/23
|
||||
trigger(1991/09/23) => "23 September 1991"
|
||||
Leaving UserFN _h() => "23 September 1991"
|
||||
.\test.rem(15): Trig = Monday, 23 September, 1991
|
||||
[_h(25, "Kislev")] MSG Channuka
|
||||
Entering UserFN _h(25, "Kislev")
|
||||
x => 25
|
||||
y => "Kislev"
|
||||
hebdate(25, "Kislev") => 1991/12/02
|
||||
trigger(1991/12/02) => "2 December 1991"
|
||||
Leaving UserFN _h() => "2 December 1991"
|
||||
.\test.rem(16): Trig = Monday, 2 December, 1991
|
||||
[_h(10, "Tevet")] MSG Asara B'Tevet
|
||||
Entering UserFN _h(10, "Tevet")
|
||||
x => 10
|
||||
y => "Tevet"
|
||||
hebdate(10, "Tevet") => 1991/12/17
|
||||
trigger(1991/12/17) => "17 December 1991"
|
||||
Leaving UserFN _h() => "17 December 1991"
|
||||
.\test.rem(17): Trig = Tuesday, 17 December, 1991
|
||||
[_h(15, "Shvat")] MSG Tu B'Shvat
|
||||
Entering UserFN _h(15, "Shvat")
|
||||
x => 15
|
||||
y => "Shvat"
|
||||
hebdate(15, "Shvat") => 1992/01/20
|
||||
trigger(1992/01/20) => "20 January 1992"
|
||||
Leaving UserFN _h() => "20 January 1992"
|
||||
.\test.rem(18): Trig = Monday, 20 January, 1992
|
||||
[_h(15, "Adar A")] MSG Purim Katan
|
||||
Entering UserFN _h(15, "Adar A")
|
||||
x => 15
|
||||
y => "Adar A"
|
||||
hebdate(15, "Adar A") => 1992/02/19
|
||||
trigger(1992/02/19) => "19 February 1992"
|
||||
Leaving UserFN _h() => "19 February 1992"
|
||||
.\test.rem(19): Trig = Wednesday, 19 February, 1992
|
||||
[_h(14, "Adar")] MSG Purim
|
||||
Entering UserFN _h(14, "Adar")
|
||||
x => 14
|
||||
y => "Adar"
|
||||
hebdate(14, "Adar") => 1991/02/28
|
||||
trigger(1991/02/28) => "28 February 1991"
|
||||
Leaving UserFN _h() => "28 February 1991"
|
||||
.\test.rem(20): Trig = Thursday, 28 February, 1991
|
||||
[_h(15, "Nisan")] MSG Pesach
|
||||
Entering UserFN _h(15, "Nisan")
|
||||
x => 15
|
||||
y => "Nisan"
|
||||
hebdate(15, "Nisan") => 1991/03/30
|
||||
trigger(1991/03/30) => "30 March 1991"
|
||||
Leaving UserFN _h() => "30 March 1991"
|
||||
.\test.rem(21): Trig = Saturday, 30 March, 1991
|
||||
[_h(27, "Nisan")] MSG Yom HaShoah
|
||||
Entering UserFN _h(27, "Nisan")
|
||||
x => 27
|
||||
y => "Nisan"
|
||||
hebdate(27, "Nisan") => 1991/04/11
|
||||
trigger(1991/04/11) => "11 April 1991"
|
||||
Leaving UserFN _h() => "11 April 1991"
|
||||
.\test.rem(22): Trig = Thursday, 11 April, 1991
|
||||
[_h(4, "Iyar")] MSG Yom HaZikaron
|
||||
Entering UserFN _h(4, "Iyar")
|
||||
x => 4
|
||||
y => "Iyar"
|
||||
hebdate(4, "Iyar") => 1991/04/18
|
||||
trigger(1991/04/18) => "18 April 1991"
|
||||
Leaving UserFN _h() => "18 April 1991"
|
||||
.\test.rem(23): Trig = Thursday, 18 April, 1991
|
||||
[_h(5, "Iyar")] MSG Yom Ha'atzmaut
|
||||
Entering UserFN _h(5, "Iyar")
|
||||
x => 5
|
||||
y => "Iyar"
|
||||
hebdate(5, "Iyar") => 1991/04/19
|
||||
trigger(1991/04/19) => "19 April 1991"
|
||||
Leaving UserFN _h() => "19 April 1991"
|
||||
.\test.rem(24): Trig = Friday, 19 April, 1991
|
||||
[_h(28, "Iyar")] MSG Yom Yerushalayim
|
||||
Entering UserFN _h(28, "Iyar")
|
||||
x => 28
|
||||
y => "Iyar"
|
||||
hebdate(28, "Iyar") => 1991/05/12
|
||||
trigger(1991/05/12) => "12 May 1991"
|
||||
Leaving UserFN _h() => "12 May 1991"
|
||||
.\test.rem(25): Trig = Sunday, 12 May, 1991
|
||||
[_h(6, "Sivan")] MSG Shavuot
|
||||
Entering UserFN _h(6, "Sivan")
|
||||
x => 6
|
||||
y => "Sivan"
|
||||
hebdate(6, "Sivan") => 1991/05/19
|
||||
trigger(1991/05/19) => "19 May 1991"
|
||||
Leaving UserFN _h() => "19 May 1991"
|
||||
.\test.rem(26): Trig = Sunday, 19 May, 1991
|
||||
[_h(9, "Av")] MSG Tish'a B'Av
|
||||
Entering UserFN _h(9, "Av")
|
||||
x => 9
|
||||
y => "Av"
|
||||
hebdate(9, "Av") => 1991/07/20
|
||||
trigger(1991/07/20) => "20 July 1991"
|
||||
Leaving UserFN _h() => "20 July 1991"
|
||||
.\test.rem(27): Trig = Saturday, 20 July, 1991
|
||||
|
||||
# Test some jahrzeit cases
|
||||
fset _i(x,y,z,a) trigger(hebdate(x,y,z,a))
|
||||
[_i(30, "Heshvan", today(), 5759)] MSG Complete-Complete
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Heshvan", 1991/02/16, 5759)
|
||||
x => 30
|
||||
y => "Heshvan"
|
||||
z => 1991/02/16
|
||||
a => 5759
|
||||
hebdate(30, "Heshvan", 1991/02/16, 5759) => 1991/11/07
|
||||
trigger(1991/11/07) => "7 November 1991"
|
||||
Leaving UserFN _i() => "7 November 1991"
|
||||
.\test.rem(31): Trig = Thursday, 7 November, 1991
|
||||
[_i(30, "Heshvan", today(), 5760)] MSG Complete-Defective
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Heshvan", 1991/02/16, 5760)
|
||||
x => 30
|
||||
y => "Heshvan"
|
||||
z => 1991/02/16
|
||||
a => 5760
|
||||
hebdate(30, "Heshvan", 1991/02/16, 5760) => 1991/11/07
|
||||
trigger(1991/11/07) => "7 November 1991"
|
||||
Leaving UserFN _i() => "7 November 1991"
|
||||
.\test.rem(32): Trig = Thursday, 7 November, 1991
|
||||
[_i(30, "Heshvan", today(), 5761)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Heshvan", 1991/02/16, 5761)
|
||||
x => 30
|
||||
y => "Heshvan"
|
||||
z => 1991/02/16
|
||||
a => 5761
|
||||
hebdate(30, "Heshvan", 1991/02/16, 5761) => .\test.rem(33): 30 Heshvan 5761: Invalid Hebrew date
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
|
||||
[_i(30, "Kislev", today(), 5759)] MSG Complete-Complete
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Kislev", 1991/02/16, 5759)
|
||||
x => 30
|
||||
y => "Kislev"
|
||||
z => 1991/02/16
|
||||
a => 5759
|
||||
hebdate(30, "Kislev", 1991/02/16, 5759) => 1991/12/07
|
||||
trigger(1991/12/07) => "7 December 1991"
|
||||
Leaving UserFN _i() => "7 December 1991"
|
||||
.\test.rem(35): Trig = Saturday, 7 December, 1991
|
||||
[_i(30, "Kislev", today(), 5760)] MSG Complete-Defective
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Kislev", 1991/02/16, 5760)
|
||||
x => 30
|
||||
y => "Kislev"
|
||||
z => 1991/02/16
|
||||
a => 5760
|
||||
hebdate(30, "Kislev", 1991/02/16, 5760) => 1991/12/07
|
||||
trigger(1991/12/07) => "7 December 1991"
|
||||
Leaving UserFN _i() => "7 December 1991"
|
||||
.\test.rem(36): Trig = Saturday, 7 December, 1991
|
||||
[_i(30, "Kislev", today(), 5761)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Kislev", 1991/02/16, 5761)
|
||||
x => 30
|
||||
y => "Kislev"
|
||||
z => 1991/02/16
|
||||
a => 5761
|
||||
hebdate(30, "Kislev", 1991/02/16, 5761) => .\test.rem(37): 30 Kislev 5761: Invalid Hebrew date
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
|
||||
[_i(30, "Adar A", today(), 5755)] MSG Leap
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Adar A", 1991/02/16, 5755)
|
||||
x => 30
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5755
|
||||
hebdate(30, "Adar A", 1991/02/16, 5755) => 1992/03/05
|
||||
trigger(1992/03/05) => "5 March 1992"
|
||||
Leaving UserFN _i() => "5 March 1992"
|
||||
.\test.rem(39): Trig = Thursday, 5 March, 1992
|
||||
[_i(30, "Adar A", today(), 5756)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Adar A", 1991/02/16, 5756)
|
||||
x => 30
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5756
|
||||
hebdate(30, "Adar A", 1991/02/16, 5756) => .\test.rem(40): No Adar A in 5756
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
[_i(29, "Adar A", today(), 5755)] MSG Leap
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(29, "Adar A", 1991/02/16, 5755)
|
||||
x => 29
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5755
|
||||
hebdate(29, "Adar A", 1991/02/16, 5755) => 1991/03/15
|
||||
trigger(1991/03/15) => "15 March 1991"
|
||||
Leaving UserFN _i() => "15 March 1991"
|
||||
.\test.rem(41): Trig = Friday, 15 March, 1991
|
||||
[_i(29, "Adar A", today(), 5756)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(29, "Adar A", 1991/02/16, 5756)
|
||||
x => 29
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5756
|
||||
hebdate(29, "Adar A", 1991/02/16, 5756) => .\test.rem(42): No Adar A in 5756
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
|
||||
# Test each possible case of the basic reminders.
|
||||
|
||||
REM MSG Every Day
|
||||
.\test.rem(46): Trig = Saturday, 16 February, 1991
|
||||
Every Day
|
||||
|
||||
|
||||
REM 18 MSG Every 18th
|
||||
.\test.rem(48): Trig = Monday, 18 February, 1991
|
||||
REM 15 MSG Every 15th
|
||||
.\test.rem(49): Trig = Friday, 15 March, 1991
|
||||
|
||||
REM Feb MSG February
|
||||
.\test.rem(51): Trig = Saturday, 16 February, 1991
|
||||
February
|
||||
|
||||
REM Jan MSG January
|
||||
.\test.rem(52): Trig = Wednesday, 1 January, 1992
|
||||
REM March MSG March
|
||||
.\test.rem(53): Trig = Friday, 1 March, 1991
|
||||
|
||||
REM 13 Jan MSG 13 Jan
|
||||
.\test.rem(55): Trig = Monday, 13 January, 1992
|
||||
REM 15 Feb MSG 15 Feb
|
||||
.\test.rem(56): Trig = Saturday, 15 February, 1992
|
||||
REM 28 Feb MSG 28 Feb
|
||||
.\test.rem(57): Trig = Thursday, 28 February, 1991
|
||||
REM 29 Feb MSG 29 Feb
|
||||
.\test.rem(58): Trig = Saturday, 29 February, 1992
|
||||
REM 5 Mar MSG 5 Mar
|
||||
.\test.rem(59): Trig = Tuesday, 5 March, 1991
|
||||
|
||||
REM 1990 MSG 1990
|
||||
.\test.rem(61): Expired
|
||||
REM 1991 MSG 1991
|
||||
.\test.rem(62): Trig = Saturday, 16 February, 1991
|
||||
1991
|
||||
|
||||
REM 1992 MSG 1991
|
||||
.\test.rem(63): Trig = Wednesday, 1 January, 1992
|
||||
|
||||
REM 1 1990 MSG 1 1990
|
||||
.\test.rem(65): Expired
|
||||
REM 29 1991 MSG 29 1991
|
||||
.\test.rem(66): Trig = Friday, 29 March, 1991
|
||||
REM 29 1992 MSG 29 1992
|
||||
.\test.rem(67): Trig = Wednesday, 29 January, 1992
|
||||
REM 16 1991 MSG 16 1991
|
||||
.\test.rem(68): Trig = Saturday, 16 February, 1991
|
||||
16 1991
|
||||
|
||||
|
||||
REM Jan 1990 MSG Jan 1990
|
||||
.\test.rem(70): Expired
|
||||
REM Feb 1991 MSG Feb 1991
|
||||
.\test.rem(71): Trig = Saturday, 16 February, 1991
|
||||
Feb 1991
|
||||
|
||||
REM Dec 1991 MSG Dec 1991
|
||||
.\test.rem(72): Trig = Sunday, 1 December, 1991
|
||||
REM May 1992 MSG May 1992
|
||||
.\test.rem(73): Trig = Friday, 1 May, 1992
|
||||
|
||||
REM 1 Jan 1991 MSG 1 Jan 1991
|
||||
.\test.rem(75): Expired
|
||||
REM 16 Feb 1991 MSG 16 Feb 1991
|
||||
.\test.rem(76): Trig = Saturday, 16 February, 1991
|
||||
16 Feb 1991
|
||||
|
||||
REM 29 Dec 1992 MSG 29 Dec 1992
|
||||
.\test.rem(77): Trig = Tuesday, 29 December, 1992
|
||||
|
||||
REM Sun MSG Sun
|
||||
.\test.rem(79): Trig = Sunday, 17 February, 1991
|
||||
REM Fri Sat Tue MSG Fri Sat Tue
|
||||
.\test.rem(80): Trig = Saturday, 16 February, 1991
|
||||
Fri Sat Tue
|
||||
|
||||
|
||||
REM Sun 16 MSG Sun 16
|
||||
.\test.rem(82): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue Wed Thu Fri 1 MSG Mon Tue Wed Thu Fri 1
|
||||
.\test.rem(83): Trig = Friday, 1 March, 1991
|
||||
|
||||
REM Sun Feb MSG Sun Feb
|
||||
.\test.rem(85): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue March MSG Mon Tue March
|
||||
.\test.rem(86): Trig = Monday, 4 March, 1991
|
||||
|
||||
REM Sun 16 Feb MSG Sun 16 Feb
|
||||
.\test.rem(88): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue 10 March MSG Mon Tue 10 March
|
||||
.\test.rem(89): Trig = Monday, 11 March, 1991
|
||||
|
||||
REM Sat Sun 1991 MSG Sat Sun 1991
|
||||
.\test.rem(91): Trig = Saturday, 16 February, 1991
|
||||
Sat Sun 1991
|
||||
|
||||
REM Mon Tue 1992 MSG Mon Tue 1992
|
||||
.\test.rem(92): Trig = Monday, 6 January, 1992
|
||||
|
||||
REM Sun 16 1991 MSG Sun 16 1991
|
||||
.\test.rem(94): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue Wed Thu Fri 1 1992 MSG Mon Tue Wed Thu Fri 1 1992
|
||||
.\test.rem(95): Trig = Wednesday, 1 January, 1992
|
||||
|
||||
REM Mon Feb 1991 MSG Mon Feb 1991
|
||||
.\test.rem(97): Trig = Monday, 18 February, 1991
|
||||
REM Tue Jan 1992 MSG Tue Jan 1992
|
||||
.\test.rem(98): Trig = Tuesday, 7 January, 1992
|
||||
|
||||
REM Sun Mon 16 Feb 1991 MSG Sun Mon 16 Feb 1991
|
||||
.\test.rem(100): Trig = Sunday, 17 February, 1991
|
||||
REM Tue 28 Jan 1992 MSG Tue 28 Jan 1992
|
||||
.\test.rem(101): Trig = Tuesday, 28 January, 1992
|
||||
|
||||
# Try some Backs
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun
|
||||
.\test.rem(105): Trig = Thursday, 28 February, 1991
|
||||
REM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun
|
||||
.\test.rem(106): Trig = Thursday, 28 February, 1991
|
||||
|
||||
OMIT 28 Feb
|
||||
REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun (28 Feb omitted)
|
||||
.\test.rem(109): Trig = Wednesday, 27 February, 1991
|
||||
REM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun (28 Feb omitted)
|
||||
.\test.rem(110): Trig = Thursday, 28 February, 1991
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
|
||||
# Try out UNTIL
|
||||
REM Wed UNTIL 21 Feb 1991 MSG Wed UNTIL 21 Feb 1991
|
||||
.\test.rem(115): Trig = Wednesday, 20 February, 1991
|
||||
|
||||
# Try playing with the OMIT context
|
||||
|
||||
OMIT 28 Feb 1991
|
||||
REM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
|
||||
.\test.rem(120): Trig = Wednesday, 27 February, 1991
|
||||
REM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
|
||||
.\test.rem(121): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
|
||||
.\test.rem(122): Trig = Wednesday, 27 February, 1991
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
|
||||
.\test.rem(123): Trig = Friday, 28 February, 1992
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
|
||||
.\test.rem(124): Trig = Friday, 1 March, 1991
|
||||
|
||||
PUSH-OMIT-CONTEXT
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 1 Mar -1 MSG 1 mar -1
|
||||
.\test.rem(128): Trig = Thursday, 28 February, 1991
|
||||
REM 1 Mar --1 MSG 1 mar --1
|
||||
.\test.rem(129): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE
|
||||
.\test.rem(130): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP
|
||||
.\test.rem(131): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER
|
||||
.\test.rem(132): Trig = Thursday, 28 February, 1991
|
||||
|
||||
POP-OMIT-CONTEXT
|
||||
REM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
|
||||
.\test.rem(135): Trig = Wednesday, 27 February, 1991
|
||||
REM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
|
||||
.\test.rem(136): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
|
||||
.\test.rem(137): Trig = Wednesday, 27 February, 1991
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
|
||||
.\test.rem(138): Trig = Friday, 28 February, 1992
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
|
||||
.\test.rem(139): Trig = Friday, 1 March, 1991
|
||||
|
||||
|
||||
REM 13 March 1991 *1 UNTIL 19 March 1991 MSG 13-19 Mar 91
|
||||
.\test.rem(142): Trig = Wednesday, 13 March, 1991
|
||||
|
||||
# Test BACK
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 18 Feb 1991 +1 MSG 18 Feb 1991 +1
|
||||
.\test.rem(146): Trig = Monday, 18 February, 1991
|
||||
|
||||
OMIT 17 Feb 1991
|
||||
REM 18 Feb 1991 +1 MSG 18 Feb 1991 +1 (17Feb91 omitted)
|
||||
.\test.rem(149): Trig = Monday, 18 February, 1991
|
||||
18 Feb 1991 +1 (17Feb91 omitted)
|
||||
|
||||
REM 18 Feb 1991 ++1 MSG 18 Feb 1991 ++1 (17Feb91 omitted)
|
||||
.\test.rem(150): Trig = Monday, 18 February, 1991
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
# Test the scanfrom clause
|
||||
REM Fri SATISFY 1
|
||||
.\test.rem(154): Trig = Friday, 22 February, 1991
|
||||
OMIT [trigger(trigdate())]
|
||||
trigdate() => 1991/02/22
|
||||
trigger(1991/02/22) => "22 February 1991"
|
||||
REM Fri after MSG 23 Feb 1991
|
||||
.\test.rem(156): Trig = Saturday, 23 February, 1991
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM Fri SCANFROM [trigger(today()-7)] SATISFY 1
|
||||
today() => 1991/02/16
|
||||
1991/02/16 - 7 => 1991/02/09
|
||||
trigger(1991/02/09) => "9 February 1991"
|
||||
.\test.rem(158): Trig = Friday, 15 February, 1991
|
||||
OMIT [trigger(trigdate())]
|
||||
trigdate() => 1991/02/15
|
||||
trigger(1991/02/15) => "15 February 1991"
|
||||
REM Fri after MSG 16 Feb 1991
|
||||
.\test.rem(160): Trig = Saturday, 16 February, 1991
|
||||
16 Feb 1991
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
set a000 abs(1)
|
||||
abs(1) => 1
|
||||
set a001 abs(-1)
|
||||
- 1 => -1
|
||||
abs(-1) => 1
|
||||
set a002 asc("foo")
|
||||
asc("foo") => 102
|
||||
set a003 baseyr()
|
||||
baseyr() => 1990
|
||||
set a004 char(66,55,66,77,66)
|
||||
char(66, 55, 66, 77, 66) => "B7BMB"
|
||||
set a005 choose(3, "foo", "bar", "baz", "blech")
|
||||
choose(3, "foo", "bar", "baz", "blech") => "baz"
|
||||
set a006 coerce("string", 1)
|
||||
coerce("string", 1) => "1"
|
||||
set a007 coerce("string", today())
|
||||
today() => 1991/02/16
|
||||
coerce("string", 1991/02/16) => "1991/02/16"
|
||||
set a008 coerce("string", 11:44)
|
||||
coerce("string", 11:44) => "11:44"
|
||||
set a009 coerce("int", "badnews")
|
||||
coerce("int", "badnews") => Can't coerce
|
||||
.\test.rem(171): Can't coerce
|
||||
set a010 coerce("int", "12")
|
||||
coerce("int", "12") => 12
|
||||
set a011 coerce("int", 11:44)
|
||||
coerce("int", 11:44) => 704
|
||||
set a012 coerce("int", today())
|
||||
today() => 1991/02/16
|
||||
coerce("int", 1991/02/16) => 411
|
||||
set a013 date(1992, 2, 2)
|
||||
date(1992, 2, 2) => 1992/02/02
|
||||
set a014 date(1993, 2, 29)
|
||||
date(1993, 2, 29) => Bad date specification
|
||||
.\test.rem(176): Bad date specification
|
||||
set a015 day(today())
|
||||
today() => 1991/02/16
|
||||
day(1991/02/16) => 16
|
||||
set a016 daysinmon(2, 1991)
|
||||
daysinmon(2, 1991) => 28
|
||||
set a017 daysinmon(2, 1992)
|
||||
daysinmon(2, 1992) => 29
|
||||
set a018 defined("a017")
|
||||
defined("a017") => 1
|
||||
set a019 defined("a019")
|
||||
defined("a019") => 0
|
||||
set a020 filename()
|
||||
filename() => ".\test.rem"
|
||||
set a021 getenv("TEST_GETENV")
|
||||
getenv("TEST_GETENV") => "foo bar baz"
|
||||
set a022 hour(11:22)
|
||||
hour(11:22) => 11
|
||||
set a023 iif(1, 1, 0)
|
||||
iif(1, 1, 0) => 1
|
||||
set a024 iif(0, 1, 0)
|
||||
iif(0, 1, 0) => 0
|
||||
set a025 index("barfoobar", "foo")
|
||||
index("barfoobar", "foo") => 4
|
||||
set a026 index("barfoobar", "bar", 2)
|
||||
index("barfoobar", "bar", 2) => 7
|
||||
set a027 isleap(today())
|
||||
today() => 1991/02/16
|
||||
isleap(1991/02/16) => 0
|
||||
set a028 isleap(1992)
|
||||
isleap(1992) => 1
|
||||
omit [trigger(today())]
|
||||
today() => 1991/02/16
|
||||
trigger(1991/02/16) => "16 February 1991"
|
||||
set a030 isomitted(today())
|
||||
today() => 1991/02/16
|
||||
isomitted(1991/02/16) => 1
|
||||
clear
|
||||
set a029 isomitted(today())
|
||||
today() => 1991/02/16
|
||||
isomitted(1991/02/16) => 0
|
||||
set a031 lower("FOOBARBAZ")
|
||||
lower("FOOBARBAZ") => "foobarbaz"
|
||||
set a032 max(1, 2, 34, 1, 3)
|
||||
max(1, 2, 34, 1, 3) => 34
|
||||
set a033 max("foo", "bar", "baz")
|
||||
max("foo", "bar", "baz") => "foo"
|
||||
set a034 max(today(), today()+1, today()-1)
|
||||
today() => 1991/02/16
|
||||
today() => 1991/02/16
|
||||
1991/02/16 + 1 => 1991/02/17
|
||||
today() => 1991/02/16
|
||||
1991/02/16 - 1 => 1991/02/15
|
||||
max(1991/02/16, 1991/02/17, 1991/02/15) => 1991/02/17
|
||||
set a035 min(1, 2, 34, 1, 3)
|
||||
min(1, 2, 34, 1, 3) => 1
|
||||
set a036 min("foo", "bar", "baz")
|
||||
min("foo", "bar", "baz") => "bar"
|
||||
set a037 min(today(), today()+1, today()-1)
|
||||
today() => 1991/02/16
|
||||
today() => 1991/02/16
|
||||
1991/02/16 + 1 => 1991/02/17
|
||||
today() => 1991/02/16
|
||||
1991/02/16 - 1 => 1991/02/15
|
||||
min(1991/02/16, 1991/02/17, 1991/02/15) => 1991/02/15
|
||||
set a038 minute(11:33)
|
||||
minute(11:33) => 33
|
||||
set a039 mon(today())
|
||||
today() => 1991/02/16
|
||||
mon(1991/02/16) => "February"
|
||||
set a040 monnum(today())
|
||||
today() => 1991/02/16
|
||||
monnum(1991/02/16) => 2
|
||||
set a041 ord(3)
|
||||
ord(3) => "3rd"
|
||||
set a042 ord(4)
|
||||
ord(4) => "4th"
|
||||
set a043 ostype()
|
||||
ostype() => "MSDOS"
|
||||
set a044 plural(2)
|
||||
plural(2) => "s"
|
||||
set a045 plural(2, "ies")
|
||||
plural(2, "ies") => "iess"
|
||||
set a046 plural(2, "y", "ies")
|
||||
plural(2, "y", "ies") => "ies"
|
||||
set a047 sgn(-2)
|
||||
- 2 => -2
|
||||
sgn(-2) => -1
|
||||
set a048 shell("echo foo")
|
||||
shell("echo foo") => "foo"
|
||||
set a049 strlen("sadjflkhsldkfhsdlfjhk")
|
||||
strlen("sadjflkhsldkfhsdlfjhk") => 21
|
||||
set a050 substr(a049, 2)
|
||||
a049 => 21
|
||||
substr(21, 2) => Type mismatch
|
||||
.\test.rem(214): Type mismatch
|
||||
set a051 substr(a050, 2, 6)
|
||||
a050 => .\test.rem(215): Undefined variable: a050
|
||||
set a052 time(1+2, 3+4)
|
||||
1 + 2 => 3
|
||||
3 + 4 => 7
|
||||
time(3, 7) => 03:07
|
||||
rem 10 jan 1992 AT 11:22 CAL
|
||||
.\test.rem(217): Trig = Friday, 10 January, 1992
|
||||
set a053 trigdate()
|
||||
trigdate() => 1992/01/10
|
||||
set a054 trigtime()
|
||||
trigtime() => 11:22
|
||||
set a055 trigvalid()
|
||||
trigvalid() => 1
|
||||
set a056 upper("sdfjhsdf ksjdfh kjsdfh ksjdfh")
|
||||
upper("sdfjhsdf ksjdfh kjsdfh ksjdfh") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
set a057 value("a05"+"6")
|
||||
"a05" + "6" => "a056"
|
||||
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
set a058 version()
|
||||
version() => "03.00.13"
|
||||
set a059 wkday(today())
|
||||
today() => 1991/02/16
|
||||
wkday(1991/02/16) => "Saturday"
|
||||
set a060 wkdaynum(today())
|
||||
today() => 1991/02/16
|
||||
wkdaynum(1991/02/16) => 6
|
||||
set a061 year(today())
|
||||
today() => 1991/02/16
|
||||
year(1991/02/16) => 1991
|
||||
set a062 1+2*(3+4-(5*7/2))
|
||||
3 + 4 => 7
|
||||
5 * 7 => 35
|
||||
35 / 2 => 17
|
||||
7 - 17 => -10
|
||||
2 * -10 => -20
|
||||
1 + -20 => -19
|
||||
set a063 1>=2
|
||||
1 >= 2 => 0
|
||||
set a064 1<2 || 3 > 4
|
||||
1 < 2 => 1
|
||||
3 > 4 => 0
|
||||
1 || 0 => 1
|
||||
set a065 1 && 1
|
||||
1 && 1 => 1
|
||||
set a066 !a065
|
||||
a065 => 1
|
||||
! 1 => 0
|
||||
set a067 typeof(2)
|
||||
typeof(2) => "INT"
|
||||
set a068 typeof("foo")
|
||||
typeof("foo") => "STRING"
|
||||
set a069 typeof(11:33)
|
||||
typeof(11:33) => "TIME"
|
||||
set a070 typeof(today())
|
||||
today() => 1991/02/16
|
||||
typeof(1991/02/16) => "DATE"
|
||||
fset g(x,y) max(x,y)
|
||||
fset h(x,y) min(g(x+y, x*y), g(x-y, x/y))
|
||||
set a071 g(1, 2)
|
||||
Entering UserFN g(1, 2)
|
||||
x => 1
|
||||
y => 2
|
||||
max(1, 2) => 2
|
||||
Leaving UserFN g() => 2
|
||||
set a072 h(2, 3)
|
||||
Entering UserFN h(2, 3)
|
||||
x => 2
|
||||
y => 3
|
||||
2 + 3 => 5
|
||||
x => 2
|
||||
y => 3
|
||||
2 * 3 => 6
|
||||
Entering UserFN g(5, 6)
|
||||
x => 5
|
||||
y => 6
|
||||
max(5, 6) => 6
|
||||
Leaving UserFN g() => 6
|
||||
x => 2
|
||||
y => 3
|
||||
2 - 3 => -1
|
||||
x => 2
|
||||
y => 3
|
||||
2 / 3 => 0
|
||||
Entering UserFN g(-1, 0)
|
||||
x => -1
|
||||
y => 0
|
||||
max(-1, 0) => 0
|
||||
Leaving UserFN g() => 0
|
||||
min(6, 0) => 0
|
||||
Leaving UserFN h() => 0
|
||||
set a073 h("foo", 11:33)
|
||||
Entering UserFN h("foo", 11:33)
|
||||
x => "foo"
|
||||
y => 11:33
|
||||
"foo" + 11:33 => "foo11:33"
|
||||
x => "foo"
|
||||
y => 11:33
|
||||
"foo" * 11:33 => Type mismatch
|
||||
.\test.rem(240): '*': Type mismatch
|
||||
Leaving UserFN h() => Type mismatch
|
||||
set a074 dosubst("%a %b %c %d %e %f %g %h", '1992/5/5')
|
||||
dosubst("%a %b %c %d %e %f %g %h", 1992/05/05) => "on Tuesday, 5 May, 1992 in 444 days' tim"...
|
||||
msg [a074]%
|
||||
.\test.rem(242): Trig = Saturday, 16 February, 1991
|
||||
a074 => "on Tuesday, 5 May, 1992 in 444 days' tim"...
|
||||
on Tuesday, 5 May, 1992 in 444 days' time on Tuesday 5 on 05/05/1992 on 05/05/1992 on Tuesday, 5 May on 05/05
|
||||
set a075 dosubst("%i %j %k %l %m %n %o %p", '1992/5/5')
|
||||
dosubst("%i %j %k %l %m %n %o %p", 1992/05/05) => "on 05/05 on Tuesday, May 5th, 1992 on Tu"...
|
||||
msg [a075]%
|
||||
.\test.rem(244): Trig = Saturday, 16 February, 1991
|
||||
a075 => "on 05/05 on Tuesday, May 5th, 1992 on Tu"...
|
||||
on 05/05 on Tuesday, May 5th, 1992 on Tuesday, May 5th on 1992/05/05 May 5 s
|
||||
set a076 dosubst("%q %r %s %t %u %v %w %x", '1992/5/5')
|
||||
dosubst("%q %r %s %t %u %v %w %x", 1992/05/05) => "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
|
||||
msg [a076]%
|
||||
.\test.rem(246): Trig = Saturday, 16 February, 1991
|
||||
a076 => "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
|
||||
s' 05 th 05 on Tuesday, 5th May, 1992 on Tuesday, 5th May Tuesday 444
|
||||
set a077 dosubst("%y %z", '1992/5/5')
|
||||
dosubst("%y %z", 1992/05/05) => "1992 92
|
||||
"
|
||||
msg [a077]%
|
||||
.\test.rem(248): Trig = Saturday, 16 February, 1991
|
||||
a077 => "1992 92
|
||||
"
|
||||
1992 92
|
||||
set a078 easterdate(today())
|
||||
today() => 1991/02/16
|
||||
easterdate(1991/02/16) => 1991/03/31
|
||||
set a079 easterdate(1992)
|
||||
easterdate(1992) => 1992/04/19
|
||||
set a080 easterdate(1995)
|
||||
easterdate(1995) => 1995/04/16
|
||||
set a081 ""
|
||||
dump
|
||||
Variable Value
|
||||
|
||||
a017 29
|
||||
a036 "bar"
|
||||
a055 1
|
||||
a074 "on Tuesday, 5 May, 1992 in 444 days' tim"...
|
||||
a008 "11:44"
|
||||
a027 0
|
||||
a046 "ies"
|
||||
a065 1
|
||||
a018 1
|
||||
a037 1991/02/15
|
||||
a056 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
a075 "on 05/05 on Tuesday, May 5th, 1992 on Tu"...
|
||||
a028 1
|
||||
a047 -1
|
||||
a066 0
|
||||
a019 0
|
||||
a038 33
|
||||
a057 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
a076 "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
|
||||
a029 0
|
||||
a048 "foo"
|
||||
a067 "INT"
|
||||
a039 "February"
|
||||
a058 "03.00.13"
|
||||
a077 "1992 92
|
||||
"
|
||||
a049 21
|
||||
a068 "STRING"
|
||||
a059 "Saturday"
|
||||
a078 1991/03/31
|
||||
a069 "TIME"
|
||||
a079 1992/04/19
|
||||
a000 1
|
||||
a010 12
|
||||
a001 1
|
||||
a020 ".\test.rem"
|
||||
a011 704
|
||||
a030 1
|
||||
a002 102
|
||||
a021 "foo bar baz"
|
||||
a040 2
|
||||
a012 411
|
||||
a031 "foobarbaz"
|
||||
a003 1990
|
||||
a022 11
|
||||
a041 "3rd"
|
||||
a060 6
|
||||
a013 1992/02/02
|
||||
a032 34
|
||||
a070 "DATE"
|
||||
a004 "B7BMB"
|
||||
a023 1
|
||||
a042 "4th"
|
||||
a061 1991
|
||||
a080 1995/04/16
|
||||
a033 "foo"
|
||||
a052 03:07
|
||||
a071 2
|
||||
a005 "baz"
|
||||
a024 0
|
||||
a043 "MSDOS"
|
||||
a062 -19
|
||||
a081 ""
|
||||
a015 16
|
||||
a034 1991/02/17
|
||||
a053 1992/01/10
|
||||
a072 0
|
||||
a006 "1"
|
||||
a025 4
|
||||
a044 "s"
|
||||
a063 0
|
||||
a016 28
|
||||
a035 1
|
||||
a054 11:22
|
||||
a007 "1991/02/16"
|
||||
a026 7
|
||||
a045 "iess"
|
||||
a064 1
|
||||
|
||||
832
test2.cmp
Normal file
832
test2.cmp
Normal file
@@ -0,0 +1,832 @@
|
||||
# Test file for REMIND
|
||||
#
|
||||
# $Id: test2.cmp,v 1.1 1996-03-27 03:26:13 dfs Exp $
|
||||
#
|
||||
# Use this file to test the date calculation routines
|
||||
# of the REMIND program by typing:
|
||||
#
|
||||
# ./test-rem # From WITHIN Remind source directory!
|
||||
|
||||
REM MSG Today is [hebday(today())] [hebmon(today())] [hebyear(today())]
|
||||
.\test.rem(8): Trig = Saturday, 16 February, 1991
|
||||
Reminders for Saturday, 16th February, 1991:
|
||||
|
||||
today() => 1991/02/16
|
||||
hebday(1991/02/16) => 2
|
||||
today() => 1991/02/16
|
||||
hebmon(1991/02/16) => "Adar"
|
||||
today() => 1991/02/16
|
||||
hebyear(1991/02/16) => 5751
|
||||
Today is 2 Adar 5751
|
||||
|
||||
fset _h(x, y) trigger(hebdate(x,y))
|
||||
|
||||
[_h(1, "Tishrey")] MSG Rosh Hashana 1
|
||||
Entering UserFN _h(1, "Tishrey")
|
||||
x => 1
|
||||
y => "Tishrey"
|
||||
hebdate(1, "Tishrey") => 1991/09/09
|
||||
trigger(1991/09/09) => "9 September 1991"
|
||||
Leaving UserFN _h() => "9 September 1991"
|
||||
.\test.rem(11): Trig = Monday, 9 September, 1991
|
||||
[_h(2, "Tishrey")] MSG Rosh Hashana 2
|
||||
Entering UserFN _h(2, "Tishrey")
|
||||
x => 2
|
||||
y => "Tishrey"
|
||||
hebdate(2, "Tishrey") => 1991/09/10
|
||||
trigger(1991/09/10) => "10 September 1991"
|
||||
Leaving UserFN _h() => "10 September 1991"
|
||||
.\test.rem(12): Trig = Tuesday, 10 September, 1991
|
||||
[_h(3, "Tishrey")] MSG Tzom Gedalia
|
||||
Entering UserFN _h(3, "Tishrey")
|
||||
x => 3
|
||||
y => "Tishrey"
|
||||
hebdate(3, "Tishrey") => 1991/09/11
|
||||
trigger(1991/09/11) => "11 September 1991"
|
||||
Leaving UserFN _h() => "11 September 1991"
|
||||
.\test.rem(13): Trig = Wednesday, 11 September, 1991
|
||||
[_h(10, "Tishrey")] MSG Yom Kippur
|
||||
Entering UserFN _h(10, "Tishrey")
|
||||
x => 10
|
||||
y => "Tishrey"
|
||||
hebdate(10, "Tishrey") => 1991/09/18
|
||||
trigger(1991/09/18) => "18 September 1991"
|
||||
Leaving UserFN _h() => "18 September 1991"
|
||||
.\test.rem(14): Trig = Wednesday, 18 September, 1991
|
||||
[_h(15, "Tishrey")] MSG Sukkot 1
|
||||
Entering UserFN _h(15, "Tishrey")
|
||||
x => 15
|
||||
y => "Tishrey"
|
||||
hebdate(15, "Tishrey") => 1991/09/23
|
||||
trigger(1991/09/23) => "23 September 1991"
|
||||
Leaving UserFN _h() => "23 September 1991"
|
||||
.\test.rem(15): Trig = Monday, 23 September, 1991
|
||||
[_h(25, "Kislev")] MSG Channuka
|
||||
Entering UserFN _h(25, "Kislev")
|
||||
x => 25
|
||||
y => "Kislev"
|
||||
hebdate(25, "Kislev") => 1991/12/02
|
||||
trigger(1991/12/02) => "2 December 1991"
|
||||
Leaving UserFN _h() => "2 December 1991"
|
||||
.\test.rem(16): Trig = Monday, 2 December, 1991
|
||||
[_h(10, "Tevet")] MSG Asara B'Tevet
|
||||
Entering UserFN _h(10, "Tevet")
|
||||
x => 10
|
||||
y => "Tevet"
|
||||
hebdate(10, "Tevet") => 1991/12/17
|
||||
trigger(1991/12/17) => "17 December 1991"
|
||||
Leaving UserFN _h() => "17 December 1991"
|
||||
.\test.rem(17): Trig = Tuesday, 17 December, 1991
|
||||
[_h(15, "Shvat")] MSG Tu B'Shvat
|
||||
Entering UserFN _h(15, "Shvat")
|
||||
x => 15
|
||||
y => "Shvat"
|
||||
hebdate(15, "Shvat") => 1992/01/20
|
||||
trigger(1992/01/20) => "20 January 1992"
|
||||
Leaving UserFN _h() => "20 January 1992"
|
||||
.\test.rem(18): Trig = Monday, 20 January, 1992
|
||||
[_h(15, "Adar A")] MSG Purim Katan
|
||||
Entering UserFN _h(15, "Adar A")
|
||||
x => 15
|
||||
y => "Adar A"
|
||||
hebdate(15, "Adar A") => 1992/02/19
|
||||
trigger(1992/02/19) => "19 February 1992"
|
||||
Leaving UserFN _h() => "19 February 1992"
|
||||
.\test.rem(19): Trig = Wednesday, 19 February, 1992
|
||||
[_h(14, "Adar")] MSG Purim
|
||||
Entering UserFN _h(14, "Adar")
|
||||
x => 14
|
||||
y => "Adar"
|
||||
hebdate(14, "Adar") => 1991/02/28
|
||||
trigger(1991/02/28) => "28 February 1991"
|
||||
Leaving UserFN _h() => "28 February 1991"
|
||||
.\test.rem(20): Trig = Thursday, 28 February, 1991
|
||||
[_h(15, "Nisan")] MSG Pesach
|
||||
Entering UserFN _h(15, "Nisan")
|
||||
x => 15
|
||||
y => "Nisan"
|
||||
hebdate(15, "Nisan") => 1991/03/30
|
||||
trigger(1991/03/30) => "30 March 1991"
|
||||
Leaving UserFN _h() => "30 March 1991"
|
||||
.\test.rem(21): Trig = Saturday, 30 March, 1991
|
||||
[_h(27, "Nisan")] MSG Yom HaShoah
|
||||
Entering UserFN _h(27, "Nisan")
|
||||
x => 27
|
||||
y => "Nisan"
|
||||
hebdate(27, "Nisan") => 1991/04/11
|
||||
trigger(1991/04/11) => "11 April 1991"
|
||||
Leaving UserFN _h() => "11 April 1991"
|
||||
.\test.rem(22): Trig = Thursday, 11 April, 1991
|
||||
[_h(4, "Iyar")] MSG Yom HaZikaron
|
||||
Entering UserFN _h(4, "Iyar")
|
||||
x => 4
|
||||
y => "Iyar"
|
||||
hebdate(4, "Iyar") => 1991/04/18
|
||||
trigger(1991/04/18) => "18 April 1991"
|
||||
Leaving UserFN _h() => "18 April 1991"
|
||||
.\test.rem(23): Trig = Thursday, 18 April, 1991
|
||||
[_h(5, "Iyar")] MSG Yom Ha'atzmaut
|
||||
Entering UserFN _h(5, "Iyar")
|
||||
x => 5
|
||||
y => "Iyar"
|
||||
hebdate(5, "Iyar") => 1991/04/19
|
||||
trigger(1991/04/19) => "19 April 1991"
|
||||
Leaving UserFN _h() => "19 April 1991"
|
||||
.\test.rem(24): Trig = Friday, 19 April, 1991
|
||||
[_h(28, "Iyar")] MSG Yom Yerushalayim
|
||||
Entering UserFN _h(28, "Iyar")
|
||||
x => 28
|
||||
y => "Iyar"
|
||||
hebdate(28, "Iyar") => 1991/05/12
|
||||
trigger(1991/05/12) => "12 May 1991"
|
||||
Leaving UserFN _h() => "12 May 1991"
|
||||
.\test.rem(25): Trig = Sunday, 12 May, 1991
|
||||
[_h(6, "Sivan")] MSG Shavuot
|
||||
Entering UserFN _h(6, "Sivan")
|
||||
x => 6
|
||||
y => "Sivan"
|
||||
hebdate(6, "Sivan") => 1991/05/19
|
||||
trigger(1991/05/19) => "19 May 1991"
|
||||
Leaving UserFN _h() => "19 May 1991"
|
||||
.\test.rem(26): Trig = Sunday, 19 May, 1991
|
||||
[_h(9, "Av")] MSG Tish'a B'Av
|
||||
Entering UserFN _h(9, "Av")
|
||||
x => 9
|
||||
y => "Av"
|
||||
hebdate(9, "Av") => 1991/07/20
|
||||
trigger(1991/07/20) => "20 July 1991"
|
||||
Leaving UserFN _h() => "20 July 1991"
|
||||
.\test.rem(27): Trig = Saturday, 20 July, 1991
|
||||
|
||||
# Test some jahrzeit cases
|
||||
fset _i(x,y,z,a) trigger(hebdate(x,y,z,a))
|
||||
[_i(30, "Heshvan", today(), 5759)] MSG Complete-Complete
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Heshvan", 1991/02/16, 5759)
|
||||
x => 30
|
||||
y => "Heshvan"
|
||||
z => 1991/02/16
|
||||
a => 5759
|
||||
hebdate(30, "Heshvan", 1991/02/16, 5759) => 1991/11/07
|
||||
trigger(1991/11/07) => "7 November 1991"
|
||||
Leaving UserFN _i() => "7 November 1991"
|
||||
.\test.rem(31): Trig = Thursday, 7 November, 1991
|
||||
[_i(30, "Heshvan", today(), 5760)] MSG Complete-Defective
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Heshvan", 1991/02/16, 5760)
|
||||
x => 30
|
||||
y => "Heshvan"
|
||||
z => 1991/02/16
|
||||
a => 5760
|
||||
hebdate(30, "Heshvan", 1991/02/16, 5760) => 1991/11/07
|
||||
trigger(1991/11/07) => "7 November 1991"
|
||||
Leaving UserFN _i() => "7 November 1991"
|
||||
.\test.rem(32): Trig = Thursday, 7 November, 1991
|
||||
[_i(30, "Heshvan", today(), 5761)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Heshvan", 1991/02/16, 5761)
|
||||
x => 30
|
||||
y => "Heshvan"
|
||||
z => 1991/02/16
|
||||
a => 5761
|
||||
hebdate(30, "Heshvan", 1991/02/16, 5761) => .\test.rem(33): 30 Heshvan 5761: Invalid Hebrew date
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
|
||||
[_i(30, "Kislev", today(), 5759)] MSG Complete-Complete
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Kislev", 1991/02/16, 5759)
|
||||
x => 30
|
||||
y => "Kislev"
|
||||
z => 1991/02/16
|
||||
a => 5759
|
||||
hebdate(30, "Kislev", 1991/02/16, 5759) => 1991/12/07
|
||||
trigger(1991/12/07) => "7 December 1991"
|
||||
Leaving UserFN _i() => "7 December 1991"
|
||||
.\test.rem(35): Trig = Saturday, 7 December, 1991
|
||||
[_i(30, "Kislev", today(), 5760)] MSG Complete-Defective
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Kislev", 1991/02/16, 5760)
|
||||
x => 30
|
||||
y => "Kislev"
|
||||
z => 1991/02/16
|
||||
a => 5760
|
||||
hebdate(30, "Kislev", 1991/02/16, 5760) => 1991/12/07
|
||||
trigger(1991/12/07) => "7 December 1991"
|
||||
Leaving UserFN _i() => "7 December 1991"
|
||||
.\test.rem(36): Trig = Saturday, 7 December, 1991
|
||||
[_i(30, "Kislev", today(), 5761)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Kislev", 1991/02/16, 5761)
|
||||
x => 30
|
||||
y => "Kislev"
|
||||
z => 1991/02/16
|
||||
a => 5761
|
||||
hebdate(30, "Kislev", 1991/02/16, 5761) => .\test.rem(37): 30 Kislev 5761: Invalid Hebrew date
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
|
||||
[_i(30, "Adar A", today(), 5755)] MSG Leap
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Adar A", 1991/02/16, 5755)
|
||||
x => 30
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5755
|
||||
hebdate(30, "Adar A", 1991/02/16, 5755) => 1992/03/05
|
||||
trigger(1992/03/05) => "5 March 1992"
|
||||
Leaving UserFN _i() => "5 March 1992"
|
||||
.\test.rem(39): Trig = Thursday, 5 March, 1992
|
||||
[_i(30, "Adar A", today(), 5756)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(30, "Adar A", 1991/02/16, 5756)
|
||||
x => 30
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5756
|
||||
hebdate(30, "Adar A", 1991/02/16, 5756) => .\test.rem(40): No Adar A in 5756
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
[_i(29, "Adar A", today(), 5755)] MSG Leap
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(29, "Adar A", 1991/02/16, 5755)
|
||||
x => 29
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5755
|
||||
hebdate(29, "Adar A", 1991/02/16, 5755) => 1991/03/15
|
||||
trigger(1991/03/15) => "15 March 1991"
|
||||
Leaving UserFN _i() => "15 March 1991"
|
||||
.\test.rem(41): Trig = Friday, 15 March, 1991
|
||||
[_i(29, "Adar A", today(), 5756)] MSG Illegal
|
||||
today() => 1991/02/16
|
||||
Entering UserFN _i(29, "Adar A", 1991/02/16, 5756)
|
||||
x => 29
|
||||
y => "Adar A"
|
||||
z => 1991/02/16
|
||||
a => 5756
|
||||
hebdate(29, "Adar A", 1991/02/16, 5756) => .\test.rem(42): No Adar A in 5756
|
||||
Invalid Hebrew date
|
||||
Leaving UserFN _i() => Invalid Hebrew date
|
||||
|
||||
# Test each possible case of the basic reminders.
|
||||
|
||||
REM MSG Every Day
|
||||
.\test.rem(46): Trig = Saturday, 16 February, 1991
|
||||
Every Day
|
||||
|
||||
|
||||
REM 18 MSG Every 18th
|
||||
.\test.rem(48): Trig = Monday, 18 February, 1991
|
||||
REM 15 MSG Every 15th
|
||||
.\test.rem(49): Trig = Friday, 15 March, 1991
|
||||
|
||||
REM Feb MSG February
|
||||
.\test.rem(51): Trig = Saturday, 16 February, 1991
|
||||
February
|
||||
|
||||
REM Jan MSG January
|
||||
.\test.rem(52): Trig = Wednesday, 1 January, 1992
|
||||
REM March MSG March
|
||||
.\test.rem(53): Trig = Friday, 1 March, 1991
|
||||
|
||||
REM 13 Jan MSG 13 Jan
|
||||
.\test.rem(55): Trig = Monday, 13 January, 1992
|
||||
REM 15 Feb MSG 15 Feb
|
||||
.\test.rem(56): Trig = Saturday, 15 February, 1992
|
||||
REM 28 Feb MSG 28 Feb
|
||||
.\test.rem(57): Trig = Thursday, 28 February, 1991
|
||||
REM 29 Feb MSG 29 Feb
|
||||
.\test.rem(58): Trig = Saturday, 29 February, 1992
|
||||
REM 5 Mar MSG 5 Mar
|
||||
.\test.rem(59): Trig = Tuesday, 5 March, 1991
|
||||
|
||||
REM 1990 MSG 1990
|
||||
.\test.rem(61): Expired
|
||||
REM 1991 MSG 1991
|
||||
.\test.rem(62): Trig = Saturday, 16 February, 1991
|
||||
1991
|
||||
|
||||
REM 1992 MSG 1991
|
||||
.\test.rem(63): Trig = Wednesday, 1 January, 1992
|
||||
|
||||
REM 1 1990 MSG 1 1990
|
||||
.\test.rem(65): Expired
|
||||
REM 29 1991 MSG 29 1991
|
||||
.\test.rem(66): Trig = Friday, 29 March, 1991
|
||||
REM 29 1992 MSG 29 1992
|
||||
.\test.rem(67): Trig = Wednesday, 29 January, 1992
|
||||
REM 16 1991 MSG 16 1991
|
||||
.\test.rem(68): Trig = Saturday, 16 February, 1991
|
||||
16 1991
|
||||
|
||||
|
||||
REM Jan 1990 MSG Jan 1990
|
||||
.\test.rem(70): Expired
|
||||
REM Feb 1991 MSG Feb 1991
|
||||
.\test.rem(71): Trig = Saturday, 16 February, 1991
|
||||
Feb 1991
|
||||
|
||||
REM Dec 1991 MSG Dec 1991
|
||||
.\test.rem(72): Trig = Sunday, 1 December, 1991
|
||||
REM May 1992 MSG May 1992
|
||||
.\test.rem(73): Trig = Friday, 1 May, 1992
|
||||
|
||||
REM 1 Jan 1991 MSG 1 Jan 1991
|
||||
.\test.rem(75): Expired
|
||||
REM 16 Feb 1991 MSG 16 Feb 1991
|
||||
.\test.rem(76): Trig = Saturday, 16 February, 1991
|
||||
16 Feb 1991
|
||||
|
||||
REM 29 Dec 1992 MSG 29 Dec 1992
|
||||
.\test.rem(77): Trig = Tuesday, 29 December, 1992
|
||||
|
||||
REM Sun MSG Sun
|
||||
.\test.rem(79): Trig = Sunday, 17 February, 1991
|
||||
REM Fri Sat Tue MSG Fri Sat Tue
|
||||
.\test.rem(80): Trig = Saturday, 16 February, 1991
|
||||
Fri Sat Tue
|
||||
|
||||
|
||||
REM Sun 16 MSG Sun 16
|
||||
.\test.rem(82): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue Wed Thu Fri 1 MSG Mon Tue Wed Thu Fri 1
|
||||
.\test.rem(83): Trig = Friday, 1 March, 1991
|
||||
|
||||
REM Sun Feb MSG Sun Feb
|
||||
.\test.rem(85): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue March MSG Mon Tue March
|
||||
.\test.rem(86): Trig = Monday, 4 March, 1991
|
||||
|
||||
REM Sun 16 Feb MSG Sun 16 Feb
|
||||
.\test.rem(88): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue 10 March MSG Mon Tue 10 March
|
||||
.\test.rem(89): Trig = Monday, 11 March, 1991
|
||||
|
||||
REM Sat Sun 1991 MSG Sat Sun 1991
|
||||
.\test.rem(91): Trig = Saturday, 16 February, 1991
|
||||
Sat Sun 1991
|
||||
|
||||
REM Mon Tue 1992 MSG Mon Tue 1992
|
||||
.\test.rem(92): Trig = Monday, 6 January, 1992
|
||||
|
||||
REM Sun 16 1991 MSG Sun 16 1991
|
||||
.\test.rem(94): Trig = Sunday, 17 February, 1991
|
||||
REM Mon Tue Wed Thu Fri 1 1992 MSG Mon Tue Wed Thu Fri 1 1992
|
||||
.\test.rem(95): Trig = Wednesday, 1 January, 1992
|
||||
|
||||
REM Mon Feb 1991 MSG Mon Feb 1991
|
||||
.\test.rem(97): Trig = Monday, 18 February, 1991
|
||||
REM Tue Jan 1992 MSG Tue Jan 1992
|
||||
.\test.rem(98): Trig = Tuesday, 7 January, 1992
|
||||
|
||||
REM Sun Mon 16 Feb 1991 MSG Sun Mon 16 Feb 1991
|
||||
.\test.rem(100): Trig = Sunday, 17 February, 1991
|
||||
REM Tue 28 Jan 1992 MSG Tue 28 Jan 1992
|
||||
.\test.rem(101): Trig = Tuesday, 28 January, 1992
|
||||
|
||||
# Try some Backs
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun
|
||||
.\test.rem(105): Trig = Thursday, 28 February, 1991
|
||||
REM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun
|
||||
.\test.rem(106): Trig = Thursday, 28 February, 1991
|
||||
|
||||
OMIT 28 Feb
|
||||
REM 1 -1 OMIT sat sun MSG 1 -1 OMIT Sat Sun (28 Feb omitted)
|
||||
.\test.rem(109): Trig = Wednesday, 27 February, 1991
|
||||
REM 1 --1 OMIT sat sun MSG 1 --1 OMIT Sat Sun (28 Feb omitted)
|
||||
.\test.rem(110): Trig = Thursday, 28 February, 1991
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
|
||||
# Try out UNTIL
|
||||
REM Wed UNTIL 21 Feb 1991 MSG Wed UNTIL 21 Feb 1991
|
||||
.\test.rem(115): Trig = Wednesday, 20 February, 1991
|
||||
|
||||
# Try playing with the OMIT context
|
||||
|
||||
OMIT 28 Feb 1991
|
||||
REM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
|
||||
.\test.rem(120): Trig = Wednesday, 27 February, 1991
|
||||
REM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
|
||||
.\test.rem(121): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
|
||||
.\test.rem(122): Trig = Wednesday, 27 February, 1991
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
|
||||
.\test.rem(123): Trig = Friday, 28 February, 1992
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
|
||||
.\test.rem(124): Trig = Friday, 1 March, 1991
|
||||
|
||||
PUSH-OMIT-CONTEXT
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 1 Mar -1 MSG 1 mar -1
|
||||
.\test.rem(128): Trig = Thursday, 28 February, 1991
|
||||
REM 1 Mar --1 MSG 1 mar --1
|
||||
.\test.rem(129): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE
|
||||
.\test.rem(130): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP
|
||||
.\test.rem(131): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER
|
||||
.\test.rem(132): Trig = Thursday, 28 February, 1991
|
||||
|
||||
POP-OMIT-CONTEXT
|
||||
REM 1 Mar -1 MSG 1 mar -1 (28feb91 omitted)
|
||||
.\test.rem(135): Trig = Wednesday, 27 February, 1991
|
||||
REM 1 Mar --1 MSG 1 mar --1 (28Feb91 omitted)
|
||||
.\test.rem(136): Trig = Thursday, 28 February, 1991
|
||||
REM 28 Feb BEFORE MSG 28 Feb BEFORE (28Feb91 omitted)
|
||||
.\test.rem(137): Trig = Wednesday, 27 February, 1991
|
||||
REM 28 Feb SKIP MSG 28 Feb SKIP (28Feb91 omitted)
|
||||
.\test.rem(138): Trig = Friday, 28 February, 1992
|
||||
REM 28 Feb AFTER MSG 28 Feb AFTER (28Feb91 omitted)
|
||||
.\test.rem(139): Trig = Friday, 1 March, 1991
|
||||
|
||||
|
||||
REM 13 March 1991 *1 UNTIL 19 March 1991 MSG 13-19 Mar 91
|
||||
.\test.rem(142): Trig = Wednesday, 13 March, 1991
|
||||
|
||||
# Test BACK
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM 18 Feb 1991 +1 MSG 18 Feb 1991 +1
|
||||
.\test.rem(146): Trig = Monday, 18 February, 1991
|
||||
|
||||
OMIT 17 Feb 1991
|
||||
REM 18 Feb 1991 +1 MSG 18 Feb 1991 +1 (17Feb91 omitted)
|
||||
.\test.rem(149): Trig = Monday, 18 February, 1991
|
||||
18 Feb 1991 +1 (17Feb91 omitted)
|
||||
|
||||
REM 18 Feb 1991 ++1 MSG 18 Feb 1991 ++1 (17Feb91 omitted)
|
||||
.\test.rem(150): Trig = Monday, 18 February, 1991
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
# Test the scanfrom clause
|
||||
REM Fri SATISFY 1
|
||||
.\test.rem(154): Trig = Friday, 22 February, 1991
|
||||
OMIT [trigger(trigdate())]
|
||||
trigdate() => 1991/02/22
|
||||
trigger(1991/02/22) => "22 February 1991"
|
||||
REM Fri after MSG 23 Feb 1991
|
||||
.\test.rem(156): Trig = Saturday, 23 February, 1991
|
||||
CLEAR-OMIT-CONTEXT
|
||||
REM Fri SCANFROM [trigger(today()-7)] SATISFY 1
|
||||
today() => 1991/02/16
|
||||
1991/02/16 - 7 => 1991/02/09
|
||||
trigger(1991/02/09) => "9 February 1991"
|
||||
.\test.rem(158): Trig = Friday, 15 February, 1991
|
||||
OMIT [trigger(trigdate())]
|
||||
trigdate() => 1991/02/15
|
||||
trigger(1991/02/15) => "15 February 1991"
|
||||
REM Fri after MSG 16 Feb 1991
|
||||
.\test.rem(160): Trig = Saturday, 16 February, 1991
|
||||
16 Feb 1991
|
||||
|
||||
CLEAR-OMIT-CONTEXT
|
||||
set a000 abs(1)
|
||||
abs(1) => 1
|
||||
set a001 abs(-1)
|
||||
- 1 => -1
|
||||
abs(-1) => 1
|
||||
set a002 asc("foo")
|
||||
asc("foo") => 102
|
||||
set a003 baseyr()
|
||||
baseyr() => 1990
|
||||
set a004 char(66,55,66,77,66)
|
||||
char(66, 55, 66, 77, 66) => "B7BMB"
|
||||
set a005 choose(3, "foo", "bar", "baz", "blech")
|
||||
choose(3, "foo", "bar", "baz", "blech") => "baz"
|
||||
set a006 coerce("string", 1)
|
||||
coerce("string", 1) => "1"
|
||||
set a007 coerce("string", today())
|
||||
today() => 1991/02/16
|
||||
coerce("string", 1991/02/16) => "1991/02/16"
|
||||
set a008 coerce("string", 11:44)
|
||||
coerce("string", 11:44) => "11:44"
|
||||
set a009 coerce("int", "badnews")
|
||||
coerce("int", "badnews") => Can't coerce
|
||||
.\test.rem(171): Can't coerce
|
||||
set a010 coerce("int", "12")
|
||||
coerce("int", "12") => 12
|
||||
set a011 coerce("int", 11:44)
|
||||
coerce("int", 11:44) => 704
|
||||
set a012 coerce("int", today())
|
||||
today() => 1991/02/16
|
||||
coerce("int", 1991/02/16) => 411
|
||||
set a013 date(1992, 2, 2)
|
||||
date(1992, 2, 2) => 1992/02/02
|
||||
set a014 date(1993, 2, 29)
|
||||
date(1993, 2, 29) => Bad date specification
|
||||
.\test.rem(176): Bad date specification
|
||||
set a015 day(today())
|
||||
today() => 1991/02/16
|
||||
day(1991/02/16) => 16
|
||||
set a016 daysinmon(2, 1991)
|
||||
daysinmon(2, 1991) => 28
|
||||
set a017 daysinmon(2, 1992)
|
||||
daysinmon(2, 1992) => 29
|
||||
set a018 defined("a017")
|
||||
defined("a017") => 1
|
||||
set a019 defined("a019")
|
||||
defined("a019") => 0
|
||||
set a020 filename()
|
||||
filename() => ".\test.rem"
|
||||
set a021 getenv("TEST_GETENV")
|
||||
getenv("TEST_GETENV") => "foo bar baz"
|
||||
set a022 hour(11:22)
|
||||
hour(11:22) => 11
|
||||
set a023 iif(1, 1, 0)
|
||||
iif(1, 1, 0) => 1
|
||||
set a024 iif(0, 1, 0)
|
||||
iif(0, 1, 0) => 0
|
||||
set a025 index("barfoobar", "foo")
|
||||
index("barfoobar", "foo") => 4
|
||||
set a026 index("barfoobar", "bar", 2)
|
||||
index("barfoobar", "bar", 2) => 7
|
||||
set a027 isleap(today())
|
||||
today() => 1991/02/16
|
||||
isleap(1991/02/16) => 0
|
||||
set a028 isleap(1992)
|
||||
isleap(1992) => 1
|
||||
omit [trigger(today())]
|
||||
today() => 1991/02/16
|
||||
trigger(1991/02/16) => "16 February 1991"
|
||||
set a030 isomitted(today())
|
||||
today() => 1991/02/16
|
||||
isomitted(1991/02/16) => 1
|
||||
clear
|
||||
set a029 isomitted(today())
|
||||
today() => 1991/02/16
|
||||
isomitted(1991/02/16) => 0
|
||||
set a031 lower("FOOBARBAZ")
|
||||
lower("FOOBARBAZ") => "foobarbaz"
|
||||
set a032 max(1, 2, 34, 1, 3)
|
||||
max(1, 2, 34, 1, 3) => 34
|
||||
set a033 max("foo", "bar", "baz")
|
||||
max("foo", "bar", "baz") => "foo"
|
||||
set a034 max(today(), today()+1, today()-1)
|
||||
today() => 1991/02/16
|
||||
today() => 1991/02/16
|
||||
1991/02/16 + 1 => 1991/02/17
|
||||
today() => 1991/02/16
|
||||
1991/02/16 - 1 => 1991/02/15
|
||||
max(1991/02/16, 1991/02/17, 1991/02/15) => 1991/02/17
|
||||
set a035 min(1, 2, 34, 1, 3)
|
||||
min(1, 2, 34, 1, 3) => 1
|
||||
set a036 min("foo", "bar", "baz")
|
||||
min("foo", "bar", "baz") => "bar"
|
||||
set a037 min(today(), today()+1, today()-1)
|
||||
today() => 1991/02/16
|
||||
today() => 1991/02/16
|
||||
1991/02/16 + 1 => 1991/02/17
|
||||
today() => 1991/02/16
|
||||
1991/02/16 - 1 => 1991/02/15
|
||||
min(1991/02/16, 1991/02/17, 1991/02/15) => 1991/02/15
|
||||
set a038 minute(11:33)
|
||||
minute(11:33) => 33
|
||||
set a039 mon(today())
|
||||
today() => 1991/02/16
|
||||
mon(1991/02/16) => "February"
|
||||
set a040 monnum(today())
|
||||
today() => 1991/02/16
|
||||
monnum(1991/02/16) => 2
|
||||
set a041 ord(3)
|
||||
ord(3) => "3rd"
|
||||
set a042 ord(4)
|
||||
ord(4) => "4th"
|
||||
set a043 ostype()
|
||||
ostype() => "OS/2"
|
||||
set a044 plural(2)
|
||||
plural(2) => "s"
|
||||
set a045 plural(2, "ies")
|
||||
plural(2, "ies") => "iess"
|
||||
set a046 plural(2, "y", "ies")
|
||||
plural(2, "y", "ies") => "ies"
|
||||
set a047 sgn(-2)
|
||||
- 2 => -2
|
||||
sgn(-2) => -1
|
||||
set a048 shell("echo foo")
|
||||
shell("echo foo") => "foo"
|
||||
set a049 strlen("sadjflkhsldkfhsdlfjhk")
|
||||
strlen("sadjflkhsldkfhsdlfjhk") => 21
|
||||
set a050 substr(a049, 2)
|
||||
a049 => 21
|
||||
substr(21, 2) => Type mismatch
|
||||
.\test.rem(214): Type mismatch
|
||||
set a051 substr(a050, 2, 6)
|
||||
a050 => .\test.rem(215): Undefined variable: a050
|
||||
set a052 time(1+2, 3+4)
|
||||
1 + 2 => 3
|
||||
3 + 4 => 7
|
||||
time(3, 7) => 03:07
|
||||
rem 10 jan 1992 AT 11:22 CAL
|
||||
.\test.rem(217): Trig = Friday, 10 January, 1992
|
||||
set a053 trigdate()
|
||||
trigdate() => 1992/01/10
|
||||
set a054 trigtime()
|
||||
trigtime() => 11:22
|
||||
set a055 trigvalid()
|
||||
trigvalid() => 1
|
||||
set a056 upper("sdfjhsdf ksjdfh kjsdfh ksjdfh")
|
||||
upper("sdfjhsdf ksjdfh kjsdfh ksjdfh") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
set a057 value("a05"+"6")
|
||||
"a05" + "6" => "a056"
|
||||
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
set a058 version()
|
||||
version() => "03.00.13"
|
||||
set a059 wkday(today())
|
||||
today() => 1991/02/16
|
||||
wkday(1991/02/16) => "Saturday"
|
||||
set a060 wkdaynum(today())
|
||||
today() => 1991/02/16
|
||||
wkdaynum(1991/02/16) => 6
|
||||
set a061 year(today())
|
||||
today() => 1991/02/16
|
||||
year(1991/02/16) => 1991
|
||||
set a062 1+2*(3+4-(5*7/2))
|
||||
3 + 4 => 7
|
||||
5 * 7 => 35
|
||||
35 / 2 => 17
|
||||
7 - 17 => -10
|
||||
2 * -10 => -20
|
||||
1 + -20 => -19
|
||||
set a063 1>=2
|
||||
1 >= 2 => 0
|
||||
set a064 1<2 || 3 > 4
|
||||
1 < 2 => 1
|
||||
3 > 4 => 0
|
||||
1 || 0 => 1
|
||||
set a065 1 && 1
|
||||
1 && 1 => 1
|
||||
set a066 !a065
|
||||
a065 => 1
|
||||
! 1 => 0
|
||||
set a067 typeof(2)
|
||||
typeof(2) => "INT"
|
||||
set a068 typeof("foo")
|
||||
typeof("foo") => "STRING"
|
||||
set a069 typeof(11:33)
|
||||
typeof(11:33) => "TIME"
|
||||
set a070 typeof(today())
|
||||
today() => 1991/02/16
|
||||
typeof(1991/02/16) => "DATE"
|
||||
fset g(x,y) max(x,y)
|
||||
fset h(x,y) min(g(x+y, x*y), g(x-y, x/y))
|
||||
set a071 g(1, 2)
|
||||
Entering UserFN g(1, 2)
|
||||
x => 1
|
||||
y => 2
|
||||
max(1, 2) => 2
|
||||
Leaving UserFN g() => 2
|
||||
set a072 h(2, 3)
|
||||
Entering UserFN h(2, 3)
|
||||
x => 2
|
||||
y => 3
|
||||
2 + 3 => 5
|
||||
x => 2
|
||||
y => 3
|
||||
2 * 3 => 6
|
||||
Entering UserFN g(5, 6)
|
||||
x => 5
|
||||
y => 6
|
||||
max(5, 6) => 6
|
||||
Leaving UserFN g() => 6
|
||||
x => 2
|
||||
y => 3
|
||||
2 - 3 => -1
|
||||
x => 2
|
||||
y => 3
|
||||
2 / 3 => 0
|
||||
Entering UserFN g(-1, 0)
|
||||
x => -1
|
||||
y => 0
|
||||
max(-1, 0) => 0
|
||||
Leaving UserFN g() => 0
|
||||
min(6, 0) => 0
|
||||
Leaving UserFN h() => 0
|
||||
set a073 h("foo", 11:33)
|
||||
Entering UserFN h("foo", 11:33)
|
||||
x => "foo"
|
||||
y => 11:33
|
||||
"foo" + 11:33 => "foo11:33"
|
||||
x => "foo"
|
||||
y => 11:33
|
||||
"foo" * 11:33 => Type mismatch
|
||||
.\test.rem(240): '*': Type mismatch
|
||||
Leaving UserFN h() => Type mismatch
|
||||
set a074 dosubst("%a %b %c %d %e %f %g %h", '1992/5/5')
|
||||
dosubst("%a %b %c %d %e %f %g %h", 1992/05/05) => "on Tuesday, 5 May, 1992 in 444 days' tim"...
|
||||
msg [a074]%
|
||||
.\test.rem(242): Trig = Saturday, 16 February, 1991
|
||||
a074 => "on Tuesday, 5 May, 1992 in 444 days' tim"...
|
||||
on Tuesday, 5 May, 1992 in 444 days' time on Tuesday 5 on 05/05/1992 on 05/05/1992 on Tuesday, 5 May on 05/05
|
||||
set a075 dosubst("%i %j %k %l %m %n %o %p", '1992/5/5')
|
||||
dosubst("%i %j %k %l %m %n %o %p", 1992/05/05) => "on 05/05 on Tuesday, May 5th, 1992 on Tu"...
|
||||
msg [a075]%
|
||||
.\test.rem(244): Trig = Saturday, 16 February, 1991
|
||||
a075 => "on 05/05 on Tuesday, May 5th, 1992 on Tu"...
|
||||
on 05/05 on Tuesday, May 5th, 1992 on Tuesday, May 5th on 1992/05/05 May 5 s
|
||||
set a076 dosubst("%q %r %s %t %u %v %w %x", '1992/5/5')
|
||||
dosubst("%q %r %s %t %u %v %w %x", 1992/05/05) => "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
|
||||
msg [a076]%
|
||||
.\test.rem(246): Trig = Saturday, 16 February, 1991
|
||||
a076 => "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
|
||||
s' 05 th 05 on Tuesday, 5th May, 1992 on Tuesday, 5th May Tuesday 444
|
||||
set a077 dosubst("%y %z", '1992/5/5')
|
||||
dosubst("%y %z", 1992/05/05) => "1992 92
|
||||
"
|
||||
msg [a077]%
|
||||
.\test.rem(248): Trig = Saturday, 16 February, 1991
|
||||
a077 => "1992 92
|
||||
"
|
||||
1992 92
|
||||
set a078 easterdate(today())
|
||||
today() => 1991/02/16
|
||||
easterdate(1991/02/16) => 1991/03/31
|
||||
set a079 easterdate(1992)
|
||||
easterdate(1992) => 1992/04/19
|
||||
set a080 easterdate(1995)
|
||||
easterdate(1995) => 1995/04/16
|
||||
set a081 ""
|
||||
dump
|
||||
Variable Value
|
||||
|
||||
a017 29
|
||||
a036 "bar"
|
||||
a055 1
|
||||
a074 "on Tuesday, 5 May, 1992 in 444 days' tim"...
|
||||
a008 "11:44"
|
||||
a027 0
|
||||
a046 "ies"
|
||||
a065 1
|
||||
a018 1
|
||||
a037 1991/02/15
|
||||
a056 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
a075 "on 05/05 on Tuesday, May 5th, 1992 on Tu"...
|
||||
a028 1
|
||||
a047 -1
|
||||
a066 0
|
||||
a019 0
|
||||
a038 33
|
||||
a057 "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
a076 "s' 05 th 05 on Tuesday, 5th May, 1992 on"...
|
||||
a029 0
|
||||
a048 "foo"
|
||||
a067 "INT"
|
||||
a039 "February"
|
||||
a058 "03.00.13"
|
||||
a077 "1992 92
|
||||
"
|
||||
a049 21
|
||||
a068 "STRING"
|
||||
a059 "Saturday"
|
||||
a078 1991/03/31
|
||||
a069 "TIME"
|
||||
a079 1992/04/19
|
||||
a000 1
|
||||
a010 12
|
||||
a001 1
|
||||
a020 ".\test.rem"
|
||||
a011 704
|
||||
a030 1
|
||||
a002 102
|
||||
a021 "foo bar baz"
|
||||
a040 2
|
||||
a012 411
|
||||
a031 "foobarbaz"
|
||||
a003 1990
|
||||
a022 11
|
||||
a041 "3rd"
|
||||
a060 6
|
||||
a013 1992/02/02
|
||||
a032 34
|
||||
a070 "DATE"
|
||||
a004 "B7BMB"
|
||||
a023 1
|
||||
a042 "4th"
|
||||
a061 1991
|
||||
a080 1995/04/16
|
||||
a033 "foo"
|
||||
a052 03:07
|
||||
a071 2
|
||||
a005 "baz"
|
||||
a024 0
|
||||
a043 "OS/2"
|
||||
a062 -19
|
||||
a081 ""
|
||||
a015 16
|
||||
a034 1991/02/17
|
||||
a053 1992/01/10
|
||||
a072 0
|
||||
a006 "1"
|
||||
a025 4
|
||||
a044 "s"
|
||||
a063 0
|
||||
a016 28
|
||||
a035 1
|
||||
a054 11:22
|
||||
a007 "1991/02/16"
|
||||
a026 7
|
||||
a045 "iess"
|
||||
a064 1
|
||||
|
||||
350
token.c
Normal file
350
token.c
Normal file
@@ -0,0 +1,350 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* TOKEN.C */
|
||||
/* */
|
||||
/* Contains routines for parsing the reminder file and */
|
||||
/* classifying the tokens parsed. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: token.c,v 1.1 1996-03-27 03:26:13 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "types.h"
|
||||
#include "globals.h"
|
||||
#include "protos.h"
|
||||
#include "err.h"
|
||||
|
||||
/* The macro PARSENUM parses a char pointer as an integer. It simply
|
||||
executes 'return' if an initial non-numeric char is found. */
|
||||
#define PARSENUM(var, string) \
|
||||
if (!isdigit(*(string))) return; \
|
||||
var = 0; \
|
||||
while (isdigit(*(string))) { \
|
||||
var *= 10; \
|
||||
var += *(string) - '0'; \
|
||||
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[] = {
|
||||
/* NAME MINLEN TYPE VALUE */
|
||||
|
||||
{ "after", 3, T_Skip, AFTER_SKIP },
|
||||
{ "april", 3, T_Month, 3 },
|
||||
{ "at", 2, T_At, 0 },
|
||||
{ "august", 3, T_Month, 7 },
|
||||
{ "banner", 3, T_Banner, 0 },
|
||||
{ "before", 3, T_Skip, BEFORE_SKIP },
|
||||
{ "cal", 3, T_RemType, CAL_TYPE },
|
||||
{ "clear-omit-context", 5, T_Clr, 0 },
|
||||
{ "debug", 5, T_Debug, 0 },
|
||||
{ "december", 3, T_Month, 11 },
|
||||
{ "dumpvars", 4, T_Dumpvars, 0 },
|
||||
{ "else", 4, T_Else, 0 },
|
||||
{ "endif", 5, T_EndIf, 0 },
|
||||
{ "errmsg", 6, T_ErrMsg, 0 },
|
||||
{ "exit", 4, T_Exit, 0 },
|
||||
{ "february", 3, T_Month, 1 },
|
||||
{ "flush", 5, T_Flush, 0 },
|
||||
{ "friday", 3, T_WkDay, 4 },
|
||||
{ "fset", 4, T_Fset, 0 },
|
||||
{ "if", 2, T_If, 0 },
|
||||
{ "iftrig", 6, T_IfTrig, 0 },
|
||||
{ "include", 3, T_Include, 0 },
|
||||
{ "january", 3, T_Month, 0 },
|
||||
{ "july", 3, T_Month, 6 },
|
||||
{ "june", 3, T_Month, 5 },
|
||||
{ "march", 3, T_Month, 2 },
|
||||
{ "may", 3, T_Month, 4 },
|
||||
{ "monday", 3, T_WkDay, 0 },
|
||||
{ "msf", 3, T_RemType, MSF_TYPE },
|
||||
{ "msg", 3, T_RemType, MSG_TYPE },
|
||||
{ "november", 3, T_Month, 10 },
|
||||
{ "october", 3, T_Month, 9 },
|
||||
{ "omit", 3, T_Omit, 0 },
|
||||
{ "once", 3, T_Once, 0 },
|
||||
{ "pop-omit-context", 3, T_Pop, 0 },
|
||||
{ "preserve", 8, T_Preserve, 0 },
|
||||
{ "priority", 8, T_Priority, 0 },
|
||||
{ "ps", 2, T_RemType, PS_TYPE },
|
||||
{ "psfile", 6, T_RemType, PSF_TYPE },
|
||||
{ "push-omit-context", 4, T_Push, 0 },
|
||||
{ "rem", 3, T_Rem, 0 },
|
||||
{ "run", 3, T_RemType, RUN_TYPE },
|
||||
{ "satisfy", 7, T_RemType, SAT_TYPE },
|
||||
{ "saturday", 3, T_WkDay, 5 },
|
||||
{ "scanfrom", 4, T_Scanfrom, 0 },
|
||||
{ "sched", 5, T_Sched, 0 },
|
||||
{ "september", 3, T_Month, 8 },
|
||||
{ "set", 3, T_Set, 0 },
|
||||
{ "skip", 3, T_Skip, SKIP_SKIP },
|
||||
{ "sunday", 3, T_WkDay, 6 },
|
||||
{ "thursday", 3, T_WkDay, 3 },
|
||||
{ "tuesday", 3, T_WkDay, 1 },
|
||||
{ "unset", 5, T_UnSet, 0 },
|
||||
{ "until", 3, T_Until, 0 },
|
||||
{ "wednesday", 3, T_WkDay, 2 }
|
||||
};
|
||||
|
||||
/* If language != English, we must also search the following... */
|
||||
#if LANG != ENGLISH
|
||||
Token NonEnglishToks[] = {
|
||||
/* NAME MINLEN TYPE VALUE */
|
||||
|
||||
{ L_MONDAY, 3, T_WkDay, 0 },
|
||||
{ L_TUESDAY, 3, T_WkDay, 1 },
|
||||
{ L_WEDNESDAY, 3, T_WkDay, 2 },
|
||||
{ L_THURSDAY, 3, T_WkDay, 3 },
|
||||
{ L_FRIDAY, 3, T_WkDay, 4 },
|
||||
{ L_SATURDAY, 3, T_WkDay, 5 },
|
||||
{ L_SUNDAY, 3, T_WkDay, 6 },
|
||||
{ L_JAN, 3, T_Month, 0 },
|
||||
{ L_FEB, 3, T_Month, 1 },
|
||||
{ L_MAR, 3, T_Month, 2 },
|
||||
{ L_APR, 3, T_Month, 3 },
|
||||
{ L_MAY, 3, T_Month, 4 },
|
||||
{ L_JUN, 3, T_Month, 5 },
|
||||
{ L_JUL, 3, T_Month, 6 },
|
||||
{ L_AUG, 3, T_Month, 7 },
|
||||
{ L_SEP, 3, T_Month, 8 },
|
||||
{ L_OCT, 3, T_Month, 9 },
|
||||
{ L_NOV, 3, T_Month, 10 },
|
||||
{ L_DEC, 3, T_Month, 11 }
|
||||
};
|
||||
#endif
|
||||
|
||||
PRIVATE int TokStrCmp ARGS((const Token *t, const char *s));
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindInitialToken */
|
||||
/* */
|
||||
/* Find the initial token on the command line. If it's a */
|
||||
/* left square bracket, return a T_Illegal type. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC char *FindInitialToken(Token *tok, char *s)
|
||||
#else
|
||||
char *FindInitialToken(tok, s)
|
||||
Token *tok;
|
||||
char *s;
|
||||
#endif
|
||||
{
|
||||
char *t;
|
||||
int len=0;
|
||||
|
||||
while (isspace(*s)) s++;
|
||||
|
||||
t = TokBuffer;
|
||||
|
||||
while (*s && !isspace(*s)) {
|
||||
if (len < TOKSIZE) {
|
||||
*t++ = *s++;
|
||||
len++;
|
||||
}else s++;
|
||||
}
|
||||
|
||||
*t = 0;
|
||||
|
||||
FindToken(TokBuffer, tok);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindToken */
|
||||
/* */
|
||||
/* Given a string, which token is it? */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void FindToken(const char *s, Token *tok)
|
||||
#else
|
||||
void FindToken(s, tok)
|
||||
char *s;
|
||||
Token *tok;
|
||||
#endif
|
||||
{
|
||||
register int top, bot, mid, r;
|
||||
int l;
|
||||
|
||||
tok->type = T_Illegal;
|
||||
if (! *s) {
|
||||
tok->type = T_Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*s == '#' || *s == ';') {
|
||||
tok->type = T_Comment;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Quickly give up the search if first char not a letter */
|
||||
if ( ! isalpha(*s)) {
|
||||
FindNumericToken(s, tok);
|
||||
return;
|
||||
}
|
||||
|
||||
l = strlen(s);
|
||||
bot = 0;
|
||||
top = sizeof(TokArray) / sizeof(TokArray[0]) - 1;
|
||||
|
||||
while(top >= bot) {
|
||||
mid = (top + bot) / 2;
|
||||
r = TokStrCmp(&TokArray[mid], s);
|
||||
if (!r) {
|
||||
if (l >= TokArray[mid].MinLen) {
|
||||
tok->type = TokArray[mid].type;
|
||||
tok->val = TokArray[mid].val;
|
||||
return;
|
||||
} else {
|
||||
while (mid && !TokStrCmp(&TokArray[mid-1],s)) mid--;
|
||||
while (!TokStrCmp(&TokArray[mid], s) && l < TokArray[mid].MinLen)
|
||||
mid++;
|
||||
if (!TokStrCmp(&TokArray[mid], s)) {
|
||||
tok->type = TokArray[mid].type;
|
||||
tok->val = TokArray[mid].val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (r > 0) top = mid-1; else bot=mid+1;
|
||||
}
|
||||
|
||||
/* If language is other than English, search the DayNames[] and MonthNames[]
|
||||
array. */
|
||||
#if LANG != ENGLISH
|
||||
for (r=0; r<(sizeof(NonEnglishToks) / sizeof(Token)); r++) {
|
||||
if (l >= NonEnglishToks[r].MinLen &&
|
||||
!TokStrCmp(&NonEnglishToks[r], s)) {
|
||||
tok->type = NonEnglishToks[r].type;
|
||||
tok->val = NonEnglishToks[r].val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindNumericToken */
|
||||
/* */
|
||||
/* Parse a numeric token: */
|
||||
/* Year - number between 1990 and 2085, or 90-99. */
|
||||
/* Day - number between 1 and 31 */
|
||||
/* Delta - +[+]n */
|
||||
/* Back - -[-]n */
|
||||
/* Rep - *n */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void FindNumericToken(const char *s, Token *t)
|
||||
#else
|
||||
void FindNumericToken(s, t)
|
||||
char *s;
|
||||
Token *t;
|
||||
#endif
|
||||
{
|
||||
int mult = 1, hour, min;
|
||||
|
||||
t->type = T_Illegal;
|
||||
t->val = 0;
|
||||
if (isdigit(*s)) {
|
||||
PARSENUM(t->val, s);
|
||||
|
||||
/* If we hit a colon or a period, we've probably got a time hr:min */
|
||||
if (*s == ':' || *s == '.' || *s == TIMESEP) {
|
||||
s++;
|
||||
hour = t->val;
|
||||
PARSENUM(min, s);
|
||||
if (*s || hour > 23 || min > 59) return; /* Illegal time */
|
||||
t->val = hour*60 + min; /* Convert to minutes past midnight */
|
||||
t->type = T_Time;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we hit a non-digit, error! */
|
||||
if (*s) return;
|
||||
|
||||
/* Special hack - convert years between 90 and 99 to 1990 and 1999 */
|
||||
if (t->val >= 90 && t->val <= 99) t->val += 1900;
|
||||
|
||||
/* Classify the number we've got */
|
||||
if (t->val >= BASE && t->val <= BASE+YR_RANGE) t->type = T_Year;
|
||||
else if (t->val >= 1 && t->val <= 31) t->type = T_Day;
|
||||
else t->type = T_Number;
|
||||
return;
|
||||
} else if (*s == '*') {
|
||||
s++;
|
||||
PARSENUM(t->val, s);
|
||||
if (*s) return; /* Illegal token if followed by non-numeric char */
|
||||
t->type = T_Rep;
|
||||
return;
|
||||
} else if (*s == '+') {
|
||||
s++;
|
||||
if (*s == '+') { mult = -1; s++; }
|
||||
PARSENUM(t->val, s);
|
||||
if (*s) return; /* Illegal token if followed by non-numeric char */
|
||||
t->type = T_Delta;
|
||||
t->val *= mult;
|
||||
return;
|
||||
} else if (*s == '-') {
|
||||
s++;
|
||||
if (*s == '-') { mult = -1; s++; }
|
||||
PARSENUM(t->val, s);
|
||||
if (*s) return; /* Illegal token if followed by non-numeric char */
|
||||
t->type = T_Back;
|
||||
t->val *= mult;
|
||||
return;
|
||||
}
|
||||
return; /* Unknown token type */
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* TokStrCmp */
|
||||
/* */
|
||||
/* Compare a token to a string. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int TokStrCmp(const Token *t, const char *s)
|
||||
#else
|
||||
static int TokStrCmp(t, s)
|
||||
Token *t;
|
||||
char *s;
|
||||
#endif
|
||||
{
|
||||
register int r;
|
||||
char *tk = t->name;
|
||||
while(*tk && *s) {
|
||||
r = UPPER(*tk) - UPPER(*s);
|
||||
tk++;
|
||||
s++;
|
||||
if (r) return r;
|
||||
}
|
||||
if (!*s) return 0;
|
||||
return (*tk - *s);
|
||||
}
|
||||
469
trigger.c
Normal file
469
trigger.c
Normal file
@@ -0,0 +1,469 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* TRIGGER.C */
|
||||
/* */
|
||||
/* Routines for figuring out the trigger date of a reminder */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: trigger.c,v 1.1 1996-03-27 03:26:14 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "types.h"
|
||||
#include "expr.h"
|
||||
#include "protos.h"
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
|
||||
#define GOT_DAY 1
|
||||
#define GOT_MON 2
|
||||
#define GOT_YR 4
|
||||
#define GOT_WD 8
|
||||
|
||||
static int JYear ARGS((int jul));
|
||||
static int JMonth ARGS((int jul));
|
||||
static int NextSimpleTrig ARGS((int startdate, Trigger *trig, int *err));
|
||||
static int GetNextTriggerDate ARGS((Trigger *trig, int start, int *err, int *nextstart));
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* NextSimpleTrig */
|
||||
/* */
|
||||
/* Compute the "simple" trigger date, taking into account */
|
||||
/* ONLY the day of week, day, month and year components. */
|
||||
/* Normally, returns -1 if the trigger has expired. As a */
|
||||
/* special case, if D, M, Y [WD] are specified, returns the */
|
||||
/* Julian date, regardless of whether it's expired. This is */
|
||||
/* so that dates with a REP can be handled properly. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int NextSimpleTrig(int startdate, Trigger *trig, int *err)
|
||||
#else
|
||||
static int NextSimpleTrig(startdate, trig, err)
|
||||
int startdate;
|
||||
Trigger *trig;
|
||||
int *err;
|
||||
#endif
|
||||
{
|
||||
int typ = 0;
|
||||
int d, m, y, j, d2, m2, y2;
|
||||
|
||||
*err = 0;
|
||||
FromJulian(startdate, &y, &m, &d);
|
||||
d2 = d;
|
||||
m2 = m;
|
||||
y2 = y;
|
||||
|
||||
if (trig->d != NO_DAY) typ |= GOT_DAY;
|
||||
if (trig->m != NO_MON) typ |= GOT_MON;
|
||||
if (trig->y != NO_YR) typ |= GOT_YR;
|
||||
if (trig->wd != NO_WD) typ |= GOT_WD;
|
||||
switch(typ) {
|
||||
case 0:
|
||||
case GOT_WD:
|
||||
if (trig->wd != NO_WD)
|
||||
while(! (trig->wd & (1 << (startdate%7)))) startdate++;
|
||||
return startdate;
|
||||
|
||||
case GOT_DAY:
|
||||
if (d > trig->d) {
|
||||
m++;
|
||||
if (m == 12) { m = 0; y++; }
|
||||
}
|
||||
while (trig->d > DaysInMonth(m, trig->y)) m++;
|
||||
j = Julian(y, m, trig->d);
|
||||
return j;
|
||||
|
||||
case GOT_MON:
|
||||
if (m == trig->m) return startdate;
|
||||
else if (m > trig->m) return Julian(y+1, trig->m, 1);
|
||||
else return Julian(y, trig->m, 1);
|
||||
|
||||
case GOT_YR:
|
||||
if (y == trig->y) return startdate;
|
||||
else if (y < trig->y) return Julian(trig->y, 0, 1);
|
||||
else return -1;
|
||||
|
||||
case GOT_DAY+GOT_MON:
|
||||
if (m > trig->m || (m == trig->m && d > trig->d)) y++;
|
||||
if (trig->d > MonthDays[trig->m]) {
|
||||
*err = E_BAD_DATE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Take care of Feb. 29 */
|
||||
while (trig->d > DaysInMonth(trig->m, y)) y++;
|
||||
return Julian(y, trig->m, trig->d);
|
||||
|
||||
case GOT_DAY+GOT_YR:
|
||||
if (y < trig->y) return Julian(trig->y, 0, trig->d);
|
||||
else if (y > trig->y) return -1;
|
||||
|
||||
if (d > trig->d) {
|
||||
m++;
|
||||
if (m == 12) return -1;
|
||||
}
|
||||
while (trig->d > DaysInMonth(m, trig->y)) m++;
|
||||
return Julian(trig->y, m, trig->d);
|
||||
|
||||
case GOT_MON+GOT_YR:
|
||||
if (y > trig->y || (y == trig->y && m > trig->m)) return -1;
|
||||
if (y < trig->y) return Julian(trig->y, trig->m, 1);
|
||||
if (m == trig->m) return startdate;
|
||||
return Julian(trig->y, trig->m, 1);
|
||||
|
||||
case GOT_DAY+GOT_MON+GOT_YR:
|
||||
if (trig->d > DaysInMonth(trig->m, trig->y)) {
|
||||
*err = E_BAD_DATE;
|
||||
return -1;
|
||||
}
|
||||
return Julian(trig->y, trig->m, trig->d);
|
||||
|
||||
case GOT_YR+GOT_WD:
|
||||
if (y > trig->y) return -1;
|
||||
if (y < trig->y) j = Julian(trig->y, 0, 1);
|
||||
else j = startdate;
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
if (JYear(j) > trig->y) return -1;
|
||||
return j;
|
||||
|
||||
case GOT_MON+GOT_WD:
|
||||
if (m == trig->m) {
|
||||
j = startdate;
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
if (JMonth(j) == trig->m) return j;
|
||||
}
|
||||
if (m >= trig->m) j = Julian(y+1, trig->m, 1);
|
||||
else j = Julian(y, trig->m, 1);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
return j; /* Guaranteed to be within the month */
|
||||
|
||||
case GOT_DAY+GOT_WD:
|
||||
if (m !=0 || y > BASE) {
|
||||
m2 = m-1;
|
||||
if (m2 < 0) { y2 = y-1; m2 = 11; }
|
||||
|
||||
/* If there are fewer days in previous month, no match */
|
||||
if (trig->d <= DaysInMonth(m2, y2)) {
|
||||
j = Julian(y2, m2, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
if (j >= startdate) return j;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Try this month */
|
||||
if (trig->d <= DaysInMonth(m, y)) {
|
||||
j = Julian(y, m, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
if (j >= startdate) return j;
|
||||
}
|
||||
|
||||
/* Argh! Try next avail. month */
|
||||
m2 = m+1;
|
||||
if (m2 > 11) { m2 = 0; y++; }
|
||||
while (trig->d > DaysInMonth(m2, y)) m2++;
|
||||
j = Julian(y, m2, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
return j;
|
||||
|
||||
case GOT_WD+GOT_YR+GOT_DAY:
|
||||
if (y > trig->y+1 || (y > trig->y && m>0)) return -1;
|
||||
if (y > trig->y) {
|
||||
j = Julian(trig->y, 11, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
if (j >= startdate) return j;
|
||||
} else if (y < trig->y) {
|
||||
j = Julian(trig->y, 0, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
return j;
|
||||
} else {
|
||||
/* Try last month */
|
||||
if (m > 0) {
|
||||
m2 = m-1;
|
||||
while (trig->d > DaysInMonth(m2, trig->y)) m2--;
|
||||
j = Julian(trig->y, m2, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
if (j >= startdate) return j;
|
||||
}
|
||||
}
|
||||
/* Try this month */
|
||||
if (trig->d <= DaysInMonth(m, trig->y)) {
|
||||
j = Julian(trig->y, m, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
if (j >= startdate) return j;
|
||||
}
|
||||
|
||||
/* Must be next month */
|
||||
if (m == 11) return -1;
|
||||
m++;
|
||||
while (trig->d > DaysInMonth(m, trig->d)) m++;
|
||||
j = Julian(trig->y, m, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
return j;
|
||||
|
||||
case GOT_DAY+GOT_MON+GOT_WD:
|
||||
/* Move up to the first valid year */
|
||||
while (trig->d > DaysInMonth(trig->m, y)) y++;
|
||||
|
||||
/* Try this year */
|
||||
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;
|
||||
while (trig->d > DaysInMonth(trig->m, y)) y++;
|
||||
j = Julian(y, trig->m, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
return j;
|
||||
|
||||
case GOT_WD+GOT_MON+GOT_YR:
|
||||
if (y > trig->y || (y == trig->y && m > trig->m)) return -1;
|
||||
if (trig->y > y || (trig->y == y && trig->m > m)) {
|
||||
j = Julian(trig->y, trig->m, 1);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
return j;
|
||||
} else {
|
||||
j = startdate;
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
FromJulian(j, &y2, &m2, &d2);
|
||||
if (m2 == trig->m) return j; else return -1;
|
||||
}
|
||||
|
||||
case GOT_WD+GOT_DAY+GOT_MON+GOT_YR:
|
||||
j = Julian(trig->y, trig->m, trig->d);
|
||||
while(! (trig->wd & (1 << (j%7)))) j++;
|
||||
return j;
|
||||
|
||||
default:
|
||||
Eprint("NextSimpleTrig %s %d", ErrMsg[E_SWERR], typ);
|
||||
*err = E_SWERR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* JMonth - Given a Julian date, what's the month? */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int JMonth(int jul)
|
||||
#else
|
||||
static int JMonth(jul)
|
||||
int jul;
|
||||
#endif
|
||||
{
|
||||
int y, m, d;
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
return m;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* JYear - Given a Julian date, what's the year? */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int JYear(int jul)
|
||||
#else
|
||||
static int JYear(jul)
|
||||
int jul;
|
||||
#endif
|
||||
{
|
||||
int y, m, d;
|
||||
FromJulian(jul, &y, &m, &d);
|
||||
return y;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetNextTriggerDate */
|
||||
/* */
|
||||
/* Given a trigger, compute the next trigger date. */
|
||||
/* */
|
||||
/* Returns the Julian date of next trigger, -1 if */
|
||||
/* expired, -2 if can't compute trigger date. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart)
|
||||
#else
|
||||
static int GetNextTriggerDate(trig, start, err, nextstart)
|
||||
Trigger *trig;
|
||||
int start;
|
||||
int *err;
|
||||
int *nextstart;
|
||||
#endif
|
||||
{
|
||||
int simple, mod;
|
||||
|
||||
/* First: Have we passed the UNTIL date? */
|
||||
if (trig->until != NO_UNTIL &&
|
||||
trig->until < start) 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--;
|
||||
|
||||
/* Find the next simple trigger */
|
||||
simple = NextSimpleTrig(start, trig, err);
|
||||
|
||||
/* Problems? */
|
||||
if (*err || (simple == -1)) return -1;
|
||||
|
||||
/* Suggested starting point for next attempt */
|
||||
*nextstart = simple+1;
|
||||
|
||||
/* 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 there's a REP, calculate the next occurrence */
|
||||
if (trig->rep != NO_REP) {
|
||||
if (simple < start) {
|
||||
mod = (start - simple) / trig->rep;
|
||||
simple = simple + mod * trig->rep;
|
||||
if (simple < start) simple += trig->rep;
|
||||
}
|
||||
}
|
||||
|
||||
/* If it's a "BEFORE"-type skip, back up */
|
||||
if (trig->skip == BEFORE_SKIP)
|
||||
while(IsOmitted(simple, trig->localomit)) simple--;
|
||||
|
||||
/* If it's an "AFTER"-type skip, jump ahead */
|
||||
if (trig->skip == AFTER_SKIP)
|
||||
while (IsOmitted(simple, trig->localomit)) simple++;
|
||||
|
||||
/* Return the date */
|
||||
return simple;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* ComputeTrigger */
|
||||
/* */
|
||||
/* The main function. Compute the next trigger date given */
|
||||
/* today's date. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int ComputeTrigger(int today, Trigger *trig, int *err)
|
||||
#else
|
||||
int ComputeTrigger(today, trig, err)
|
||||
int today;
|
||||
Trigger *trig;
|
||||
int *err;
|
||||
#endif
|
||||
{
|
||||
int nattempts = 0,
|
||||
start = today,
|
||||
nextstart,
|
||||
y, m, d,
|
||||
result;
|
||||
|
||||
LastTrigValid = 0;
|
||||
/* Assume everything works */
|
||||
*err = OK;
|
||||
|
||||
/* But check for obvious problems... */
|
||||
if (trig->localomit == 1 + 2 + 4 + 8 + 16 + 32 + 64) {
|
||||
*err = E_2MANY_LOCALOMIT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (trig->rep != NO_REP &&
|
||||
(trig->d == NO_DAY ||
|
||||
trig->m == NO_MON ||
|
||||
trig->y == NO_YR)) {
|
||||
Eprint("%s", ErrMsg[E_REP_FULSPEC]);
|
||||
*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) {
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%d): %s\n",
|
||||
FileName, LineNo, ErrMsg[E_EXPIRED]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If result is >= today, great! */
|
||||
if (result >= today &&
|
||||
(trig->skip != SKIP_SKIP || !IsOmitted(result, trig->localomit))) {
|
||||
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",
|
||||
FileName, LineNo,
|
||||
DayName[result % 7],
|
||||
d,
|
||||
MonthName[m],
|
||||
y);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* If it's a simple trigger, no point in rescanning */
|
||||
if (trig->back == NO_BACK &&
|
||||
trig->skip == NO_SKIP &&
|
||||
trig->rep == NO_REP) {
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%d): %s\n",
|
||||
FileName, LineNo, ErrMsg[E_EXPIRED]);
|
||||
}
|
||||
if (result != -1) {
|
||||
LastTriggerDate = result;
|
||||
LastTrigValid = 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/* Keep scanning... unless there's no point in doing it.*/
|
||||
if (nextstart <= start) {
|
||||
if (result != -1) {
|
||||
LastTriggerDate = result;
|
||||
LastTrigValid = 1;
|
||||
}
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%d): %s\n",
|
||||
FileName, LineNo, ErrMsg[E_EXPIRED]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
else start = nextstart;
|
||||
|
||||
}
|
||||
|
||||
/* We failed - too many attempts or trigger has expired*/
|
||||
*err = E_CANT_TRIG;
|
||||
return -1;
|
||||
}
|
||||
202
tstlang.rem
Normal file
202
tstlang.rem
Normal file
@@ -0,0 +1,202 @@
|
||||
#!remind -rq
|
||||
# ---------------------------------------------------------------------------
|
||||
#
|
||||
# TSTLANG.REM
|
||||
#
|
||||
# $Id: tstlang.rem,v 1.1 1996-03-27 03:26:14 dfs Exp $
|
||||
#
|
||||
# Use this file to test new language headers you may want to create.
|
||||
# Usage: remind -rq tstlang.rem
|
||||
#
|
||||
# Don't run it within about 2 hours of midnight (ie, between 10pm and 2am)
|
||||
#
|
||||
# Use the output to verify your translations.
|
||||
#
|
||||
# This file is part of REMIND.
|
||||
# Copyright (C) 1992-1996 by David F. Skoll
|
||||
#
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
if version()<"03.00.08"
|
||||
errmsg %
|
||||
errmsg This file only works with Remind version 03.00.08 and later - aborting
|
||||
exit
|
||||
endif
|
||||
|
||||
if !$RunOff || !$DontQueue || $DontTrigAts
|
||||
errmsg %
|
||||
errmsg Please run [filename()] with the -q and -r options, but%
|
||||
errmsg not the -a option.
|
||||
exit
|
||||
endif
|
||||
|
||||
# Set up a few useful definitions
|
||||
fset show(x) "%%" + x + " yields: " + char(34) + "%" + x + char(34) + "%"
|
||||
set a trigger(today()+2) + " ++2"
|
||||
set l language()
|
||||
set tt now()+134
|
||||
set tu now()-134
|
||||
set d a + " at " + tt
|
||||
set e a + " at " + tu
|
||||
|
||||
msg The above is the default banner for the [l] language.
|
||||
|
||||
msg The following are the two-day-in-advance substitutions:%
|
||||
[a] msg [show("a")]
|
||||
[a] msg [show("b")]
|
||||
[a] msg [show("c")]
|
||||
[a] msg [show("d")]
|
||||
[a] msg [show("e")]
|
||||
[a] msg [show("f")]
|
||||
[a] msg [show("g")]
|
||||
[a] msg [show("h")]
|
||||
[a] msg [show("i")]
|
||||
[a] msg [show("j")]
|
||||
[a] msg [show("k")]
|
||||
[a] msg [show("l")]
|
||||
[a] msg [show("m")]
|
||||
[a] msg [show("n")]
|
||||
[a] msg [show("o")]
|
||||
[a] msg [show("p")]
|
||||
[a] msg [show("q")]
|
||||
[a] msg [show("r")]
|
||||
[a] msg [show("s")]
|
||||
[a] msg [show("t")]
|
||||
[a] msg [show("u")]
|
||||
[a] msg [show("v")]
|
||||
[a] msg [show("w")]
|
||||
[a] msg [show("x")]
|
||||
[a] msg [show("y")]
|
||||
[a] msg [show("z")]
|
||||
|
||||
msg %_%_The following are the one-day-in-advance substitutions:%
|
||||
set a trigger(today()+1) + " ++1"
|
||||
set d a + " at " + tt
|
||||
set e a + " at " + tu
|
||||
[a] msg [show("a")]
|
||||
[a] msg [show("b")]
|
||||
[a] msg [show("c")]
|
||||
[a] msg [show("d")]
|
||||
[a] msg [show("e")]
|
||||
[a] msg [show("f")]
|
||||
[a] msg [show("g")]
|
||||
[a] msg [show("h")]
|
||||
[a] msg [show("i")]
|
||||
[a] msg [show("j")]
|
||||
[a] msg [show("k")]
|
||||
[a] msg [show("l")]
|
||||
[a] msg [show("m")]
|
||||
[a] msg [show("n")]
|
||||
[a] msg [show("o")]
|
||||
[a] msg [show("p")]
|
||||
[a] msg [show("q")]
|
||||
[a] msg [show("r")]
|
||||
[a] msg [show("s")]
|
||||
[a] msg [show("t")]
|
||||
[a] msg [show("u")]
|
||||
[a] msg [show("v")]
|
||||
[a] msg [show("w")]
|
||||
[a] msg [show("x")]
|
||||
[a] msg [show("y")]
|
||||
[a] msg [show("z")]
|
||||
|
||||
msg %_%_The following are the current-day substitutions:%
|
||||
set a trigger(today())
|
||||
set d a + " at " + tt
|
||||
set e a + " at " + tu
|
||||
[a] msg [show("a")]
|
||||
[a] msg [show("b")]
|
||||
[a] msg [show("c")]
|
||||
[a] msg [show("d")]
|
||||
[a] msg [show("e")]
|
||||
[a] msg [show("f")]
|
||||
[a] msg [show("g")]
|
||||
[a] msg [show("h")]
|
||||
[a] msg [show("i")]
|
||||
[a] msg [show("j")]
|
||||
[a] msg [show("k")]
|
||||
[a] msg [show("l")]
|
||||
[a] msg [show("m")]
|
||||
[a] msg [show("n")]
|
||||
[a] msg [show("o")]
|
||||
[a] msg [show("p")]
|
||||
[a] msg [show("q")]
|
||||
[a] msg [show("r")]
|
||||
[a] msg [show("s")]
|
||||
[a] msg [show("t")]
|
||||
[a] msg [show("u")]
|
||||
[a] msg [show("v")]
|
||||
[a] msg [show("w")]
|
||||
[a] msg [show("x")]
|
||||
[a] msg [show("y")]
|
||||
[a] msg [show("z")]
|
||||
|
||||
msg %_Time substititions for a time in the future:%
|
||||
[d] msg [show("1")]
|
||||
[d] msg [show("2")]
|
||||
[d] msg [show("3")]
|
||||
[d] msg [show("4")]
|
||||
[d] msg [show("5")]
|
||||
[d] msg [show("6")]
|
||||
[d] msg [show("7")]
|
||||
[d] msg [show("8")]
|
||||
[d] msg [show("9")]
|
||||
[d] msg [show("0")]
|
||||
[d] msg [show("!")]
|
||||
[d] msg [show("@")]
|
||||
[d] msg [show("#")]
|
||||
msg %_Time substititions for a time in the past:%
|
||||
[e] msg [show("1")]
|
||||
[e] msg [show("2")]
|
||||
[e] msg [show("3")]
|
||||
[e] msg [show("4")]
|
||||
[e] msg [show("5")]
|
||||
[e] msg [show("6")]
|
||||
[e] msg [show("7")]
|
||||
[e] msg [show("8")]
|
||||
[e] msg [show("9")]
|
||||
[e] msg [show("0")]
|
||||
[e] msg [show("!")]
|
||||
[e] msg [show("@")]
|
||||
[e] msg [show("#")]
|
||||
|
||||
msg %_Time substititions for the current time:%
|
||||
set e a + " at " + now()
|
||||
[e] msg [show("1")]
|
||||
[e] msg [show("2")]
|
||||
[e] msg [show("3")]
|
||||
[e] msg [show("4")]
|
||||
[e] msg [show("5")]
|
||||
[e] msg [show("6")]
|
||||
[e] msg [show("7")]
|
||||
[e] msg [show("8")]
|
||||
[e] msg [show("9")]
|
||||
[e] msg [show("0")]
|
||||
[e] msg [show("!")]
|
||||
[e] msg [show("@")]
|
||||
[e] msg [show("#")]
|
||||
|
||||
msg %_The following are the days of the week:
|
||||
fset showwd(x) "wkday("+x+") = " + wkday(x) + "%"
|
||||
msg [showwd(0)]
|
||||
msg [showwd(1)]
|
||||
msg [showwd(2)]
|
||||
msg [showwd(3)]
|
||||
msg [showwd(4)]
|
||||
msg [showwd(5)]
|
||||
msg [showwd(6)]
|
||||
|
||||
msg %_The following are the months of the year:
|
||||
fset showmon(x) "mon("+x+") = "+mon(x)+"%"
|
||||
msg [showmon(1)]
|
||||
msg [showmon(2)]
|
||||
msg [showmon(3)]
|
||||
msg [showmon(4)]
|
||||
msg [showmon(5)]
|
||||
msg [showmon(6)]
|
||||
msg [showmon(7)]
|
||||
msg [showmon(8)]
|
||||
msg [showmon(9)]
|
||||
msg [showmon(10)]
|
||||
msg [showmon(11)]
|
||||
msg [showmon(12)]
|
||||
176
types.h
Normal file
176
types.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* TYPES.H */
|
||||
/* */
|
||||
/* Type definitions all dumped here. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: types.h,v 1.1 1996-03-27 03:26:14 dfs Exp $ */
|
||||
|
||||
/* Values */
|
||||
typedef struct {
|
||||
char type;
|
||||
union {
|
||||
char *str;
|
||||
int val;
|
||||
} v;
|
||||
} Value;
|
||||
|
||||
/* Define the type of operators */
|
||||
typedef struct {
|
||||
char *name;
|
||||
char prec;
|
||||
char type;
|
||||
#ifdef HAVE_PROTOS
|
||||
int (*func)(void);
|
||||
#else
|
||||
int (*func) ();
|
||||
#endif
|
||||
} Operator;
|
||||
|
||||
/* Define the structure of a variable */
|
||||
typedef struct var {
|
||||
struct var *next;
|
||||
char name[VAR_NAME_LEN+1];
|
||||
char preserve;
|
||||
Value v;
|
||||
} Var;
|
||||
|
||||
/* A trigger */
|
||||
typedef struct {
|
||||
int wd;
|
||||
int d;
|
||||
int m;
|
||||
int y;
|
||||
int back;
|
||||
int delta;
|
||||
int rep;
|
||||
int localomit;
|
||||
int skip;
|
||||
int until;
|
||||
int typ;
|
||||
int once;
|
||||
int scanfrom;
|
||||
int priority;
|
||||
char sched[VAR_NAME_LEN+1]; /* Scheduling function */
|
||||
} Trigger;
|
||||
|
||||
/* A time trigger */
|
||||
typedef struct {
|
||||
int ttime;
|
||||
int nexttime;
|
||||
int delta;
|
||||
int rep;
|
||||
} TimeTrig;
|
||||
|
||||
/* The parse pointer */
|
||||
typedef struct {
|
||||
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 */
|
||||
} Parser;
|
||||
|
||||
typedef Parser *ParsePtr; /* Pointer to parser structure */
|
||||
|
||||
/* Some useful manifest constants */
|
||||
#define NO_BACK 0
|
||||
#define NO_DELTA 0
|
||||
#define NO_REP 0
|
||||
#define NO_WD 0
|
||||
#define NO_DAY -1
|
||||
#define NO_MON -1
|
||||
#define NO_YR -1
|
||||
#define NO_UNTIL -1
|
||||
#define NO_ONCE 0
|
||||
#define ONCE_ONCE 1
|
||||
#define NO_DATE -1
|
||||
#define NO_SKIP 0
|
||||
#define SKIP_SKIP 1
|
||||
#define BEFORE_SKIP 2
|
||||
#define AFTER_SKIP 3
|
||||
|
||||
#define NO_TIME 1500 /* >1440, ie > than the largest possible legal time */
|
||||
|
||||
#define NO_PRIORITY 5000 /* Default priority is midway between 0 and 9999 */
|
||||
|
||||
#define NO_TYPE 0
|
||||
#define MSG_TYPE 1
|
||||
#define RUN_TYPE 2
|
||||
#define CAL_TYPE 3
|
||||
#define SAT_TYPE 4
|
||||
#define PS_TYPE 5
|
||||
#define PSF_TYPE 6
|
||||
#define MSF_TYPE 7
|
||||
|
||||
/* 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
|
||||
|
||||
/* Enumeration of the tokens */
|
||||
enum TokTypes
|
||||
{ T_Illegal,
|
||||
/* Commands first */
|
||||
T_Rem, T_Push, T_Pop, T_Preserve, T_Include, T_If, T_Else, T_EndIf,
|
||||
T_IfTrig, T_ErrMsg,
|
||||
T_Set, T_UnSet, T_Fset, T_Omit, T_Banner, T_Exit,
|
||||
T_WkDay,
|
||||
T_Month, T_Time,
|
||||
T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta, T_Back,
|
||||
T_Once,
|
||||
T_Empty,
|
||||
T_Comment,
|
||||
T_Number,
|
||||
T_Clr,
|
||||
T_Debug,
|
||||
T_Dumpvars,
|
||||
T_Scanfrom,
|
||||
T_Flush,
|
||||
T_Priority,
|
||||
T_Sched
|
||||
};
|
||||
|
||||
/* The structure of a token */
|
||||
typedef struct {
|
||||
char *name;
|
||||
char MinLen;
|
||||
enum TokTypes type;
|
||||
int val;
|
||||
} Token;
|
||||
|
||||
/* Flags for the state of the "if" stack */
|
||||
#define IF_TRUE 0
|
||||
#define IF_FALSE 1
|
||||
#define BEFORE_ELSE 0
|
||||
#define AFTER_ELSE 2
|
||||
#define IF_MASK 3
|
||||
#define IF_TRUE_MASK 1
|
||||
#define IF_ELSE_MASK 2
|
||||
|
||||
/* Flags for the DoSubst function */
|
||||
#define NORMAL_MODE 0
|
||||
#define CAL_MODE 1
|
||||
#define QUOTE_MARKER 1 /* Unlikely character to appear in reminder */
|
||||
|
||||
/* Flags for disabling run */
|
||||
#define RUN_CMDLINE 1
|
||||
#define RUN_SCRIPT 2
|
||||
|
||||
/* Flags for the SimpleCalendar format */
|
||||
#define SC_AMPM 0 /* Time shown as 3:00am, etc. */
|
||||
#define SC_MIL 1 /* 24-hour time format */
|
||||
#define SC_NOTIME 2 /* Do not display time in SC format. */
|
||||
|
||||
/* Flags for sorting */
|
||||
#define SORT_NONE 0
|
||||
#define SORT_ASCEND 1
|
||||
#define SORT_DESCEND 2
|
||||
403
userfns.c
Normal file
403
userfns.c
Normal file
@@ -0,0 +1,403 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* USERFNS.C */
|
||||
/* */
|
||||
/* This file contains the routines to support user-defined */
|
||||
/* functions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: userfns.c,v 1.1 1996-03-27 03:26:15 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include "types.h"
|
||||
#include "globals.h"
|
||||
#include "protos.h"
|
||||
#include "err.h"
|
||||
#include "expr.h"
|
||||
|
||||
#define FUNC_HASH_SIZE 32 /* Size of User-defined function hash table */
|
||||
|
||||
/* Define the data structure used to hold a user-defined function */
|
||||
typedef struct udf_struct {
|
||||
struct udf_struct *next;
|
||||
char name[VAR_NAME_LEN+1];
|
||||
char *text;
|
||||
Var *locals;
|
||||
char IsCached;
|
||||
char IsActive;
|
||||
int nargs;
|
||||
} UserFunc;
|
||||
|
||||
/* The hash table */
|
||||
static UserFunc *FuncHash[FUNC_HASH_SIZE];
|
||||
|
||||
/* Access to built-in functions */
|
||||
extern int NumFuncs;
|
||||
extern Operator Func[];
|
||||
|
||||
/* We need access to the expression evaluation stack */
|
||||
extern Value ValStack[];
|
||||
extern int ValStackPtr;
|
||||
|
||||
PRIVATE void DestroyUserFunc ARGS ((UserFunc *f));
|
||||
PRIVATE void FUnset ARGS ((char *name));
|
||||
PRIVATE void FSet ARGS ((UserFunc *f));
|
||||
PRIVATE int SetUpLocalVars ARGS ((UserFunc *f));
|
||||
PRIVATE void DestroyLocalVals ARGS ((UserFunc *f));
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoFset */
|
||||
/* */
|
||||
/* Define a user-defined function - the FSET command. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoFset(ParsePtr p)
|
||||
#else
|
||||
int DoFset(p)
|
||||
ParsePtr p;
|
||||
#endif
|
||||
{
|
||||
int r;
|
||||
int c;
|
||||
UserFunc *func;
|
||||
Var *v;
|
||||
|
||||
/* Get the function name */
|
||||
if ( (r=ParseIdentifier(p, TokBuffer)) ) return r;
|
||||
if (*TokBuffer == '$') return E_BAD_ID;
|
||||
|
||||
/* Should be followed by '(' */
|
||||
c = ParseNonSpaceChar(p, &r, 0);
|
||||
if (r) return r;
|
||||
if (c != '(') return E_PARSE_ERR;
|
||||
|
||||
func = NEW(UserFunc);
|
||||
if (!func) return E_NO_MEM;
|
||||
StrnCpy(func->name, TokBuffer, VAR_NAME_LEN);
|
||||
if (!Hush) {
|
||||
if (FindFunc(TokBuffer, Func, NumFuncs)) {
|
||||
Eprint("%s: '%s'", ErrMsg[E_REDEF_FUNC],
|
||||
TokBuffer);
|
||||
}
|
||||
}
|
||||
func->locals = NULL;
|
||||
func->text = NULL;
|
||||
func->IsCached = 1;
|
||||
func->IsActive = 0;
|
||||
func->nargs = 0;
|
||||
|
||||
/* Get the local variables - we insert the local variables in REVERSE
|
||||
order, but that's OK, because we pop them off the stack in reverse
|
||||
order, too, so everything works out just fine. */
|
||||
|
||||
c=ParseNonSpaceChar(p, &r, 1);
|
||||
if (r) return r;
|
||||
if (c == ')') {
|
||||
(void) ParseNonSpaceChar(p, &r, 0);
|
||||
}
|
||||
else {
|
||||
while(1) {
|
||||
if ( (r=ParseIdentifier(p, TokBuffer)) ) return r;
|
||||
if (*TokBuffer == '$') return E_BAD_ID;
|
||||
v = NEW(Var);
|
||||
func->nargs++;
|
||||
v->v.type = ERR_TYPE;
|
||||
if (!v) {
|
||||
DestroyUserFunc(func);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
StrnCpy(v->name, TokBuffer, VAR_NAME_LEN);
|
||||
v->next = func->locals;
|
||||
func->locals = v;
|
||||
c = ParseNonSpaceChar(p, &r, 0);
|
||||
if (c == ')') break;
|
||||
else if (c != ',') {
|
||||
DestroyUserFunc(func);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy the text over */
|
||||
if (p->isnested) {
|
||||
Eprint("%s", ErrMsg[E_CANTNEST_FDEF]);
|
||||
DestroyUserFunc(func);
|
||||
return E_PARSE_ERR;
|
||||
}
|
||||
|
||||
/* A bit of trickery here - if the definition is already cached,
|
||||
no point in copying it. */
|
||||
if (CurLine != LineBuffer) {
|
||||
func->IsCached = 1;
|
||||
func->text = p->pos;
|
||||
} else {
|
||||
func->IsCached = 0;
|
||||
func->text = StrDup(p->pos);
|
||||
if (!func->text) {
|
||||
DestroyUserFunc(func);
|
||||
return E_NO_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* If an old definition of this function exists, destroy it */
|
||||
FUnset(func->name);
|
||||
|
||||
/* Add the function definition */
|
||||
FSet(func);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DestroyUserFunc */
|
||||
/* */
|
||||
/* Free up all the resources used by a user-defined function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void DestroyUserFunc(UserFunc *f)
|
||||
#else
|
||||
static void DestroyUserFunc(f)
|
||||
UserFunc *f;
|
||||
#endif
|
||||
{
|
||||
Var *v, *prev;
|
||||
|
||||
/* Free the local variables first */
|
||||
v = f->locals;
|
||||
while(v) {
|
||||
DestroyValue(v->v);
|
||||
prev = v;
|
||||
v = v->next;
|
||||
free(prev);
|
||||
}
|
||||
|
||||
/* Free the function definition */
|
||||
if (f->text && !f->IsCached) free(f->text);
|
||||
|
||||
/* Free the data structure itself */
|
||||
free(f);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FUnset */
|
||||
/* */
|
||||
/* Delete the function definition with the given name, if */
|
||||
/* it exists. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void FUnset(char *name)
|
||||
#else
|
||||
static void FUnset(name)
|
||||
char *name;
|
||||
#endif
|
||||
{
|
||||
UserFunc *cur, *prev;
|
||||
int h;
|
||||
|
||||
h = HashVal(name) % FUNC_HASH_SIZE;
|
||||
|
||||
cur = FuncHash[h];
|
||||
prev = NULL;
|
||||
while(cur) {
|
||||
if (! StrinCmp(name, cur->name, VAR_NAME_LEN)) break;
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
if (!cur) return;
|
||||
if (prev) prev->next = cur->next; else FuncHash[h] = cur->next;
|
||||
DestroyUserFunc(cur);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FSet */
|
||||
/* */
|
||||
/* Insert a user-defined function into the hash table. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void FSet(UserFunc *f)
|
||||
#else
|
||||
static void FSet(f)
|
||||
UserFunc *f;
|
||||
#endif
|
||||
{
|
||||
int h = HashVal(f->name) % FUNC_HASH_SIZE;
|
||||
f->next = FuncHash[h];
|
||||
FuncHash[h] = f;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* CallUserFunc */
|
||||
/* */
|
||||
/* Call a user-defined function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int CallUserFunc(char *name, int nargs)
|
||||
#else
|
||||
int CallUserFunc(name, nargs)
|
||||
char *name;
|
||||
int nargs;
|
||||
#endif
|
||||
{
|
||||
UserFunc *f;
|
||||
int h = HashVal(name) % FUNC_HASH_SIZE;
|
||||
int i;
|
||||
char *s;
|
||||
|
||||
/* Search for the function */
|
||||
f = FuncHash[h];
|
||||
while (f && StrinCmp(name, f->name, VAR_NAME_LEN)) f = f->next;
|
||||
if (!f) {
|
||||
Eprint("%s: '%s'", ErrMsg[E_UNDEF_FUNC], name);
|
||||
return E_UNDEF_FUNC;
|
||||
}
|
||||
/* Debugging stuff */
|
||||
if (DebugFlag & DB_PRTEXPR) {
|
||||
fprintf(ErrFp, "%s %s(", ErrMsg[E_ENTER_FUN], f->name);
|
||||
for (i=0; i<nargs; i++) {
|
||||
PrintValue(&ValStack[ValStackPtr - nargs + i], ErrFp);
|
||||
if (i<nargs-1) fprintf(ErrFp, ", ");
|
||||
}
|
||||
fprintf(ErrFp, ")\n");
|
||||
}
|
||||
/* Detect illegal recursive call */
|
||||
if (f->IsActive) {
|
||||
if (DebugFlag &DB_PRTEXPR) {
|
||||
fprintf(ErrFp, "%s %s() => ", ErrMsg[E_LEAVE_FUN], name);
|
||||
fprintf(ErrFp, "%s\n", ErrMsg[E_RECURSIVE]);
|
||||
}
|
||||
return E_RECURSIVE;
|
||||
}
|
||||
|
||||
/* Check number of args */
|
||||
if (nargs != f->nargs) {
|
||||
if (DebugFlag &DB_PRTEXPR) {
|
||||
fprintf(ErrFp, "%s %s() => ", ErrMsg[E_LEAVE_FUN], name);
|
||||
fprintf(ErrFp, "%s\n",
|
||||
ErrMsg[(nargs < f->nargs) ? E_2FEW_ARGS : E_2MANY_ARGS]);
|
||||
}
|
||||
return (nargs < f->nargs) ? E_2FEW_ARGS : E_2MANY_ARGS;
|
||||
}
|
||||
/* Found the function - set up a local variable frame */
|
||||
h = SetUpLocalVars(f);
|
||||
if (h) {
|
||||
if (DebugFlag &DB_PRTEXPR) {
|
||||
fprintf(ErrFp, "%s %s() => ", ErrMsg[E_LEAVE_FUN], name);
|
||||
fprintf(ErrFp, "%s\n", ErrMsg[h]);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Evaluate the expression */
|
||||
f->IsActive = 1;
|
||||
s = f->text;
|
||||
|
||||
/* Skip the opening bracket, if there's one */
|
||||
while (isspace(*s)) s++;
|
||||
if (*s == BEG_OF_EXPR) s++;
|
||||
h = Evaluate(&s, f->locals);
|
||||
f->IsActive = 0;
|
||||
DestroyLocalVals(f);
|
||||
if (DebugFlag &DB_PRTEXPR) {
|
||||
fprintf(ErrFp, "%s %s() => ", ErrMsg[E_LEAVE_FUN], name);
|
||||
if (h) fprintf(ErrFp, "%s\n", ErrMsg[h]);
|
||||
else {
|
||||
PrintValue(&ValStack[ValStackPtr-1], ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SetUpLocalVars */
|
||||
/* */
|
||||
/* Set up the local variables from the stack frame. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE int SetUpLocalVars(UserFunc *f)
|
||||
#else
|
||||
static int SetUpLocalVars(f)
|
||||
UserFunc *f;
|
||||
#endif
|
||||
{
|
||||
int i, r;
|
||||
Var *var;
|
||||
|
||||
for (i=0, var=f->locals; var && i<f->nargs; var=var->next, i++) {
|
||||
if ( (r=FnPopValStack(&(var->v))) ) {
|
||||
DestroyLocalVals(f);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DestroyLocalVals */
|
||||
/* */
|
||||
/* Destroy the values of all local variables after evaluating */
|
||||
/* the function. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void DestroyLocalVals(UserFunc *f)
|
||||
#else
|
||||
static void DestroyLocalVals(f)
|
||||
UserFunc *f;
|
||||
#endif
|
||||
{
|
||||
Var *v = f->locals;
|
||||
|
||||
while(v) {
|
||||
DestroyValue(v->v);
|
||||
v = v->next;
|
||||
}
|
||||
}
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* UserFuncExists */
|
||||
/* */
|
||||
/* Return the number of arguments accepted by the function if */
|
||||
/* it is defined, or -1 if it is not defined. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int UserFuncExists(char *fn)
|
||||
#else
|
||||
int UserFuncExists(fn)
|
||||
char *fn;
|
||||
#endif
|
||||
{
|
||||
UserFunc *f;
|
||||
int h = HashVal(fn) % FUNC_HASH_SIZE;
|
||||
|
||||
f = FuncHash[h];
|
||||
while (f && StrinCmp(fn, f->name, VAR_NAME_LEN)) f = f->next;
|
||||
if (!f) return -1;
|
||||
else return f->nargs;
|
||||
}
|
||||
|
||||
183
utils.c
Normal file
183
utils.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* UTILS.C */
|
||||
/* */
|
||||
/* Useful utility functions. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: utils.c,v 1.1 1996-03-27 03:26:15 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include "types.h"
|
||||
#include "globals.h"
|
||||
#include "protos.h"
|
||||
|
||||
#define UPPER(c) (islower(c) ? toupper(c) : c)
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* StrnCpy */
|
||||
/* */
|
||||
/* Just like strncpy EXCEPT we ALWAYS copy the trailing 0. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC char *StrnCpy(char *dest, const char *source, int n)
|
||||
#else
|
||||
char *StrnCpy(dest, source, n)
|
||||
char *dest, *source;
|
||||
int n;
|
||||
#endif
|
||||
{
|
||||
register char *odest = dest;
|
||||
|
||||
while (n-- && (*dest++ = *source++)) ;
|
||||
if (*(dest-1)) *dest = 0;
|
||||
return odest;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* StrMatch */
|
||||
/* */
|
||||
/* Checks that two strings match (case-insensitive) to at */
|
||||
/* least the specified number of characters, or the length */
|
||||
/* of the first string, whichever is greater. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int StrMatch(const char *s1, const char *s2, int n)
|
||||
#else
|
||||
int StrMatch(s1, s2, n)
|
||||
char *s1, *s2;
|
||||
int n;
|
||||
#endif
|
||||
{
|
||||
int l;
|
||||
if ((l = strlen(s1)) < n) return 0;
|
||||
return !StrinCmp(s1, s2, l);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* StrinCmp - compare strings, case-insensitive */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int StrinCmp(const char *s1, const char *s2, int n)
|
||||
#else
|
||||
int StrinCmp(s1, s2, n)
|
||||
char *s1, *s2;
|
||||
int n;
|
||||
#endif
|
||||
{
|
||||
register int r;
|
||||
while (n && *s1 && *s2) {
|
||||
n--;
|
||||
r = UPPER(*s1) - UPPER(*s2);
|
||||
if (r) return r;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
if (n) return (UPPER(*s1) - UPPER(*s2)); else return 0;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* StrDup */
|
||||
/* */
|
||||
/* Like ANSI strdup */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC char *StrDup(const char *s)
|
||||
#else
|
||||
char *StrDup(s)
|
||||
char *s;
|
||||
#endif
|
||||
{
|
||||
char *ret = (char *) malloc(strlen(s)+1);
|
||||
if (!ret) return (char *) NULL;
|
||||
strcpy(ret, s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* StrCmpi */
|
||||
/* */
|
||||
/* Compare strings, case insensitive. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int StrCmpi(const char *s1, const char *s2)
|
||||
#else
|
||||
int StrCmpi(s1, s2)
|
||||
char *s1, *s2;
|
||||
#endif
|
||||
{
|
||||
int r;
|
||||
while (*s1 && *s2) {
|
||||
r = UPPER(*s1) - UPPER(*s2);
|
||||
if (r) return r;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return UPPER(*s1) - UPPER(*s2);
|
||||
}
|
||||
|
||||
#ifdef NO_STRSTR
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC char *strstr(char *s1, char *s2)
|
||||
#else
|
||||
char *strstr(s1, s2)
|
||||
char *s1, *s2;
|
||||
#endif
|
||||
{
|
||||
char *s = s1;
|
||||
int len2 = strlen(s2);
|
||||
int len1 = strlen(s1);
|
||||
|
||||
while (s-s1 <= len1-len2) {
|
||||
if (!strncmp(s, s2, len2)) return s;
|
||||
s++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DateOK */
|
||||
/* */
|
||||
/* Return 1 if the date is OK, 0 otherwise. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DateOK(int y, int m, int d)
|
||||
#else
|
||||
int DateOK(y, m, d)
|
||||
int y, m, d;
|
||||
#endif
|
||||
{
|
||||
if (d < 1 ||
|
||||
m < 0 ||
|
||||
y < BASE ||
|
||||
m > 11 ||
|
||||
y > BASE + YR_RANGE ||
|
||||
d > DaysInMonth(m, y) ) return 0;
|
||||
else return 1;
|
||||
}
|
||||
655
var.c
Normal file
655
var.c
Normal file
@@ -0,0 +1,655 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* VAR.C */
|
||||
/* */
|
||||
/* This file contains routines, structures, etc for */
|
||||
/* user- and system-defined variables. */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
static char const RCSID[] = "$Id: var.c,v 1.1 1996-03-27 03:26:16 dfs Exp $";
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include "types.h"
|
||||
#include "expr.h"
|
||||
#include "globals.h"
|
||||
#include "protos.h"
|
||||
#include "err.h"
|
||||
|
||||
#define UPPER(c) (islower(c) ? toupper(c) : c)
|
||||
|
||||
/* The variable hash table */
|
||||
#define VAR_HASH_SIZE 64
|
||||
#define VARIABLE ErrMsg[E_VAR]
|
||||
#define VALUE ErrMsg[E_VAL]
|
||||
#define UNDEF ErrMsg[E_UNDEF]
|
||||
|
||||
static Var *VHashTbl[VAR_HASH_SIZE];
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* HashVal */
|
||||
/* Given a string, compute the hash value. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC unsigned int HashVal(const char *str)
|
||||
#else
|
||||
unsigned int HashVal(str)
|
||||
char *str;
|
||||
#endif
|
||||
{
|
||||
register unsigned int i=0;
|
||||
register unsigned int j=1;
|
||||
register unsigned int len=0;
|
||||
|
||||
while(*str && len < VAR_NAME_LEN) {
|
||||
i += j * (unsigned int) UPPER(*str);
|
||||
str++;
|
||||
len++;
|
||||
j = 3-j;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindVar */
|
||||
/* Given a string, find the variable whose name is that */
|
||||
/* string. If create is 1, create the variable. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC Var *FindVar(const char *str, int create)
|
||||
#else
|
||||
Var *FindVar(str, create)
|
||||
char *str;
|
||||
int create;
|
||||
#endif
|
||||
{
|
||||
register int h;
|
||||
register Var *v;
|
||||
register Var *prev;
|
||||
|
||||
h = HashVal(str) % VAR_HASH_SIZE;
|
||||
v = VHashTbl[h];
|
||||
prev = NULL;
|
||||
|
||||
while(v) {
|
||||
if (! StrinCmp(str, v->name, VAR_NAME_LEN)) return v;
|
||||
prev = v;
|
||||
v = v-> next;
|
||||
}
|
||||
if (!create) return v;
|
||||
|
||||
/* Create the variable */
|
||||
v = NEW(Var);
|
||||
if (!v) return v;
|
||||
v->next = NULL;
|
||||
v->v.type = INT_TYPE;
|
||||
v->v.v.val = 0;
|
||||
v->preserve = 0;
|
||||
StrnCpy(v->name, str, VAR_NAME_LEN);
|
||||
|
||||
if (prev) prev->next = v; else VHashTbl[h] = v;
|
||||
return v;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DeleteVar */
|
||||
/* Given a string, find the variable whose name is that */
|
||||
/* string and delete it. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DeleteVar(const char *str)
|
||||
#else
|
||||
int DeleteVar(str)
|
||||
char *str;
|
||||
#endif
|
||||
{
|
||||
register int h;
|
||||
register Var *v;
|
||||
register Var *prev;
|
||||
|
||||
h = HashVal(str) % VAR_HASH_SIZE;
|
||||
v = VHashTbl[h];
|
||||
prev = NULL;
|
||||
|
||||
while(v) {
|
||||
if (! StrinCmp(str, v->name, VAR_NAME_LEN)) break;
|
||||
prev = v;
|
||||
v = v-> next;
|
||||
}
|
||||
if (!v) return E_NOSUCH_VAR;
|
||||
DestroyValue(v->v);
|
||||
if (prev) prev->next = v->next; else VHashTbl[h] = v->next;
|
||||
free(v);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SetVar */
|
||||
/* */
|
||||
/* Set the indicate variable to the specified value. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int SetVar(const char *str, Value *val)
|
||||
#else
|
||||
int SetVar(str, val)
|
||||
char *str;
|
||||
Value *val;
|
||||
#endif
|
||||
{
|
||||
Var *v = FindVar(str, 1);
|
||||
|
||||
if (!v) return E_NO_MEM; /* Only way FindVar can fail */
|
||||
|
||||
DestroyValue(v->v);
|
||||
v->v = *val;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetVarValue */
|
||||
/* */
|
||||
/* Get a copy of the value of the variable. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int GetVarValue(const char *str, Value *val, Var *locals)
|
||||
#else
|
||||
int GetVarValue(str, val, locals)
|
||||
char *str;
|
||||
Value *val;
|
||||
Var *locals;
|
||||
#endif
|
||||
{
|
||||
Var *v;
|
||||
|
||||
/* Try searching local variables first */
|
||||
v = locals;
|
||||
while (v) {
|
||||
if (! StrinCmp(str, v->name, VAR_NAME_LEN))
|
||||
return CopyValue(val, &v->v);
|
||||
v = v->next;
|
||||
}
|
||||
|
||||
v=FindVar(str, 0);
|
||||
|
||||
if (!v) {
|
||||
Eprint("%s: %s", ErrMsg[E_NOSUCH_VAR], str);
|
||||
return E_NOSUCH_VAR;
|
||||
}
|
||||
return CopyValue(val, &v->v);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoSet - set a variable. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoSet (Parser *p)
|
||||
#else
|
||||
int DoSet (p)
|
||||
Parser *p;
|
||||
#endif
|
||||
{
|
||||
Value v;
|
||||
int r;
|
||||
|
||||
r = ParseIdentifier(p, TokBuffer);
|
||||
if (r) return r;
|
||||
|
||||
r = EvaluateExpr(p, &v);
|
||||
if (r) return r;
|
||||
|
||||
if (*TokBuffer == '$') return SetSysVar(TokBuffer+1, &v);
|
||||
else return SetVar(TokBuffer, &v);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoUnset - delete a bunch of variables. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoUnset (Parser *p)
|
||||
#else
|
||||
int DoUnset (p)
|
||||
Parser *p;
|
||||
#endif
|
||||
{
|
||||
int r;
|
||||
|
||||
r = ParseToken(p, TokBuffer);
|
||||
if (r) return r;
|
||||
if (!*TokBuffer) return E_EOLN;
|
||||
|
||||
(void) DeleteVar(TokBuffer); /* Ignore error - nosuchvar */
|
||||
|
||||
/* Keep going... */
|
||||
while(1) {
|
||||
r = ParseToken(p, TokBuffer);
|
||||
if (r) return r;
|
||||
if (!*TokBuffer) return OK;
|
||||
(void) DeleteVar(TokBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoDump */
|
||||
/* */
|
||||
/* Command file command to dump variable table. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoDump(ParsePtr p)
|
||||
#else
|
||||
int DoDump(p)
|
||||
ParsePtr p;
|
||||
#endif
|
||||
{
|
||||
int r;
|
||||
Var *v;
|
||||
|
||||
r = ParseToken(p, TokBuffer);
|
||||
if (r) return r;
|
||||
if (!*TokBuffer || *TokBuffer == '#' || *TokBuffer == ';') {
|
||||
DumpVarTable();
|
||||
return OK;
|
||||
}
|
||||
fprintf(ErrFp, "%*s %s\n\n", VAR_NAME_LEN, VARIABLE, VALUE);
|
||||
while(1) {
|
||||
if (*TokBuffer == '$') {
|
||||
DumpSysVarByName(TokBuffer+1);
|
||||
} else {
|
||||
v = FindVar(TokBuffer, 0);
|
||||
TokBuffer[VAR_NAME_LEN] = 0;
|
||||
if (!v) fprintf(ErrFp, "%*s %s\n", VAR_NAME_LEN, TokBuffer, UNDEF);
|
||||
else {
|
||||
fprintf(ErrFp, "%*s ", VAR_NAME_LEN, v->name);
|
||||
PrintValue(&(v->v), ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
}
|
||||
}
|
||||
r = ParseToken(p, TokBuffer);
|
||||
if (r) return r;
|
||||
if (!*TokBuffer || *TokBuffer == '#' || *TokBuffer == ';') return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DumpVarTable */
|
||||
/* */
|
||||
/* Dump the variable table to stderr. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void DumpVarTable(void)
|
||||
#else
|
||||
void DumpVarTable()
|
||||
#endif
|
||||
{
|
||||
register Var *v;
|
||||
register int i;
|
||||
|
||||
fprintf(ErrFp, "%*s %s\n\n", VAR_NAME_LEN, VARIABLE, VALUE);
|
||||
|
||||
for (i=0; i<VAR_HASH_SIZE; i++) {
|
||||
v = VHashTbl[i];
|
||||
while(v) {
|
||||
fprintf(ErrFp, "%*s ", VAR_NAME_LEN, v->name);
|
||||
PrintValue(&(v->v), ErrFp);
|
||||
fprintf(ErrFp, "\n");
|
||||
v = v->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DestroyVars */
|
||||
/* */
|
||||
/* Free all the memory used by variables, but don't delete */
|
||||
/* preserved variables unless ALL is non-zero. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void DestroyVars(int all)
|
||||
#else
|
||||
void DestroyVars(all)
|
||||
int all;
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
Var *v, *next, *prev;
|
||||
|
||||
for (i=0; i<VAR_HASH_SIZE; i++) {
|
||||
v = VHashTbl[i];
|
||||
VHashTbl[i] = NULL;
|
||||
prev = NULL;
|
||||
while(v) {
|
||||
if (all || !v->preserve) {
|
||||
DestroyValue(v->v);
|
||||
next = v->next;
|
||||
free(v);
|
||||
} else {
|
||||
if (prev) prev->next = v;
|
||||
else VHashTbl[i] = v;
|
||||
prev = v;
|
||||
next = v->next;
|
||||
v->next = NULL;
|
||||
}
|
||||
v = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* PreserveVar */
|
||||
/* */
|
||||
/* Given the name of a variable, "preserve" it. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int PreserveVar(char *name)
|
||||
#else
|
||||
int PreserveVar(name)
|
||||
char *name;
|
||||
#endif
|
||||
{
|
||||
Var *v;
|
||||
|
||||
v = FindVar(name, 1);
|
||||
if (!v) return E_NO_MEM;
|
||||
v->preserve = 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DoPreserve - preserve a bunch of variables. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int DoPreserve (Parser *p)
|
||||
#else
|
||||
int DoPreserve (p)
|
||||
Parser *p;
|
||||
#endif
|
||||
{
|
||||
int r;
|
||||
|
||||
r = ParseToken(p, TokBuffer);
|
||||
if (r) return r;
|
||||
if (!*TokBuffer) return E_EOLN;
|
||||
|
||||
r = PreserveVar(TokBuffer);
|
||||
if (r) return r;
|
||||
|
||||
/* Keep going... */
|
||||
while(1) {
|
||||
r = ParseToken(p, TokBuffer);
|
||||
if (r) return r;
|
||||
if (!*TokBuffer) return OK;
|
||||
r = PreserveVar(TokBuffer);
|
||||
if (r) return r;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SYSTEM VARIABLES */
|
||||
/* */
|
||||
/* Interface for modifying and reading system variables. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* The structure of a system variable */
|
||||
typedef struct {
|
||||
char *name;
|
||||
char modifiable;
|
||||
int type;
|
||||
void *value;
|
||||
int min;
|
||||
int max;
|
||||
} SysVar;
|
||||
|
||||
/* If the type of a sys variable is STR_TYPE, then min is redefined
|
||||
to be a flag indicating whether or not the value has been malloc'd. */
|
||||
#define been_malloced min
|
||||
|
||||
/* Flag for no min/max constraint */
|
||||
#define ANY 4532
|
||||
/* All of the system variables sorted alphabetically */
|
||||
static SysVar SysVarArr[] = {
|
||||
/* name mod type value min/mal max */
|
||||
{ "CalcUTC", 1, INT_TYPE, &CalculateUTC, 0, 1 },
|
||||
{ "CalMode", 0, INT_TYPE, &DoCalendar, 0, 0 },
|
||||
{ "Daemon", 0, INT_TYPE, &Daemon, 0, 0 },
|
||||
{ "DefaultPrio", 1, INT_TYPE, &DefaultPrio, 0, 9999 },
|
||||
{ "DontFork", 0, INT_TYPE, &DontFork, 0, 0 },
|
||||
{ "DontQueue", 0, INT_TYPE, &DontQueue, 0, 0 },
|
||||
{ "DontTrigAts", 0, INT_TYPE, &DontIssueAts, 0, 0 },
|
||||
{ "EndSent", 1, STR_TYPE, &EndSent, 0, 0 },
|
||||
{ "EndSentIg", 1, STR_TYPE, &EndSentIg, 0, 0 },
|
||||
{ "FirstIndent", 1, INT_TYPE, &FirstIndent, 0, 132 },
|
||||
{ "FoldYear", 1, INT_TYPE, &FoldYear, 0, 1 },
|
||||
{ "FormWidth", 1, INT_TYPE, &FormWidth, 20, 132 },
|
||||
{ "HushMode", 0, INT_TYPE, &Hush, 0, 0 },
|
||||
{ "IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 0, 0 },
|
||||
{ "InfDelta", 0, INT_TYPE, &InfiniteDelta, 0, 0 },
|
||||
{ "LatDeg", 1, INT_TYPE, &LatDeg, -90, 90 },
|
||||
{ "LatMin", 1, INT_TYPE, &LatMin, -59, 59 },
|
||||
{ "LatSec", 1, INT_TYPE, &LatSec, -59, 59 },
|
||||
{ "Location", 1, STR_TYPE, &Location, 0, 0 },
|
||||
{ "LongDeg", 1, INT_TYPE, &LongDeg, -180, 180 },
|
||||
{ "LongMin", 1, INT_TYPE, &LongMin, -59, 59 },
|
||||
{ "LongSec", 1, INT_TYPE, &LongSec, -59, 59 },
|
||||
{ "MaxSatIter", 1, INT_TYPE, &MaxSatIter, 10, ANY },
|
||||
{ "MinsFromUTC", 1, INT_TYPE, &MinsFromUTC, -13*60, 13*60 },
|
||||
{ "NextMode", 0, INT_TYPE, &NextMode, 0, 0 },
|
||||
{ "NumQueued", 0, INT_TYPE, &NumQueued, 0, 0 },
|
||||
{ "NumTrig", 0, INT_TYPE, &NumTriggered, 0, 0 },
|
||||
{ "PSCal", 0, INT_TYPE, &PsCal, 0, 0 },
|
||||
{ "RunOff", 0, INT_TYPE, &RunDisabled, 0, 0 },
|
||||
{ "SimpleCal", 0, INT_TYPE, &DoSimpleCalendar, 0, 0 },
|
||||
{ "SortByDate", 0, INT_TYPE, &SortByDate, 0, 0},
|
||||
{ "SortByPrio", 0, INT_TYPE, &SortByPrio, 0, 0},
|
||||
{ "SortByTime", 0, INT_TYPE, &SortByTime, 0, 0},
|
||||
{ "SubsIndent", 1, INT_TYPE, &SubsIndent, 0, 132}
|
||||
};
|
||||
|
||||
#define NUMSYSVARS ( sizeof(SysVarArr) / sizeof(SysVar) )
|
||||
PRIVATE SysVar *FindSysVar ARGS((const char *name));
|
||||
PRIVATE void DumpSysVar ARGS((const char *name, const SysVar *v));
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* SetSysVar */
|
||||
/* */
|
||||
/* Set a system variable to the indicated value. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int SetSysVar(const char *name, Value *value)
|
||||
#else
|
||||
int SetSysVar(name, value)
|
||||
char *name;
|
||||
Value *value;
|
||||
#endif
|
||||
{
|
||||
SysVar *v = FindSysVar(name);
|
||||
if (!v) return E_NOSUCH_VAR;
|
||||
if (v->type != value->type) return E_BAD_TYPE;
|
||||
if (!v->modifiable) {
|
||||
Eprint("%s: '$%s'", ErrMsg[E_CANT_MODIFY], name);
|
||||
return E_CANT_MODIFY;
|
||||
}
|
||||
|
||||
/* If it's a string variable, special measures must be taken */
|
||||
if (v->type == STR_TYPE) {
|
||||
if (v->been_malloced) free(*((char **)(v->value)));
|
||||
v->been_malloced = 1;
|
||||
*((char **) v->value) = value->v.str;
|
||||
value->type = ERR_TYPE; /* So that it's not accidentally freed */
|
||||
} else {
|
||||
if (v->max != ANY && value->v.val > v->max) return E_2HIGH;
|
||||
if (v->min != ANY && value->v.val < v->min) return E_2LOW;
|
||||
*((int *)v->value) = value->v.val;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* GetSysVar */
|
||||
/* */
|
||||
/* Get the value of a system variable */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC int GetSysVar(const char *name, Value *val)
|
||||
#else
|
||||
int GetSysVar(name, val)
|
||||
char *name;
|
||||
Value *val;
|
||||
#endif
|
||||
{
|
||||
SysVar *v = FindSysVar(name);
|
||||
|
||||
val->type = ERR_TYPE;
|
||||
if (!v) return E_NOSUCH_VAR;
|
||||
if (v->type == STR_TYPE) {
|
||||
val->v.str = StrDup(*((char **) v->value));
|
||||
if (!val->v.str) return E_NO_MEM;
|
||||
} else {
|
||||
val->v.val = *((int *) v->value);
|
||||
}
|
||||
val->type = v->type;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* FindSysVar */
|
||||
/* */
|
||||
/* Find a system var with specified name. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE SysVar *FindSysVar(const char *name)
|
||||
#else
|
||||
static SysVar *FindSysVar(name)
|
||||
char *name;
|
||||
#endif
|
||||
{
|
||||
int top=NUMSYSVARS-1, bottom=0;
|
||||
int mid=(top + bottom) / 2;
|
||||
int r;
|
||||
|
||||
while (top >= bottom) {
|
||||
r = StrCmpi(name, SysVarArr[mid].name);
|
||||
if (!r) return &SysVarArr[mid];
|
||||
else if (r>0) bottom = mid+1;
|
||||
else top = mid-1;
|
||||
mid = (top+bottom) / 2;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DumpSysVarByName */
|
||||
/* */
|
||||
/* Given the name of a system variable, display it. */
|
||||
/* If name is "", dump all system variables. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PUBLIC void DumpSysVarByName(const char *name)
|
||||
#else
|
||||
void DumpSysVarByName(name)
|
||||
char *name;
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
SysVar *v;
|
||||
|
||||
if (!name || !*name) {
|
||||
for (i=0; i<NUMSYSVARS; i++) DumpSysVar(name, SysVarArr + i);
|
||||
return;
|
||||
}
|
||||
|
||||
v = FindSysVar(name);
|
||||
DumpSysVar(name, v);
|
||||
return;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* DumpSysVar */
|
||||
/* */
|
||||
/* Dump the system variable. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
#ifdef HAVE_PROTOS
|
||||
PRIVATE void DumpSysVar(const char *name, const SysVar *v)
|
||||
#else
|
||||
static void DumpSysVar(name, v)
|
||||
char *name;
|
||||
SysVar *v;
|
||||
#endif
|
||||
{
|
||||
char buffer[VAR_NAME_LEN+10];
|
||||
|
||||
if (name && !*name) name=NULL;
|
||||
if (!v && !name) return; /* Shouldn't happen... */
|
||||
|
||||
buffer[0]='$'; buffer[1] = 0;
|
||||
if (name) strcat(buffer, name); else strcat(buffer, v->name);
|
||||
fprintf(ErrFp, "%*s ", VAR_NAME_LEN, buffer);
|
||||
if (v) {
|
||||
if (v->type == STR_TYPE) {
|
||||
char *s = *((char **)v->value);
|
||||
int y;
|
||||
putc('"', ErrFp);
|
||||
for (y=0; y<MAX_PRT_LEN && *s; y++) putc(*s++, ErrFp);
|
||||
putc('"', ErrFp);
|
||||
if (*s) fprintf(ErrFp, "...");
|
||||
putc('\n', ErrFp);
|
||||
} else {
|
||||
if (!v->modifiable) fprintf(ErrFp, "%d\n", *((int *)v->value));
|
||||
else {
|
||||
fprintf(ErrFp, "%-10d ", *((int *)v->value));
|
||||
if (v->min == ANY) fprintf(ErrFp, "(-Inf, ");
|
||||
else fprintf(ErrFp, "[%d, ", v->min);
|
||||
if (v->max == ANY) fprintf(ErrFp, "Inf)\n");
|
||||
else fprintf(ErrFp, "%d]\n", v->max);
|
||||
}
|
||||
}
|
||||
} else fprintf(ErrFp, "%s\n", UNDEF);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
13
version.h
Normal file
13
version.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/***************************************************************/
|
||||
/* */
|
||||
/* VERSION.H */
|
||||
/* */
|
||||
/* What version of remind do we have? */
|
||||
/* */
|
||||
/* This file is part of REMIND. */
|
||||
/* Copyright (C) 1992-1996 by David F. Skoll */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
|
||||
/* $Id: version.h,v 1.1 1996-03-27 03:26:16 dfs Exp $ */
|
||||
#define VERSION "03.00.13"
|
||||
Reference in New Issue
Block a user