├── .github ├── FUNDING.yml ├── README.md └── workflows │ └── github-action.yml ├── COPYRIGHT ├── MICROSOFT-AND-APPLE ├── Makefile ├── README ├── build.tk ├── configure ├── configure.in ├── contrib ├── README ├── ical2rem.pl ├── rem2ics-0.93 │ ├── Makefile │ ├── rem2ics │ └── rem2ics.spec └── remind-conf-mode │ ├── README │ ├── ac-remind.el │ ├── gpl.txt │ └── remind-conf-mode.el ├── docs ├── README.UNIX └── WHATSNEW ├── examples ├── defs.rem └── remind.vim ├── include ├── holidays │ ├── ca.rem │ └── us.rem ├── lang │ ├── auto.rem │ ├── da.rem │ ├── de.rem │ ├── en.rem │ ├── es.rem │ ├── fi.rem │ ├── fr.rem │ ├── is.rem │ ├── it.rem │ ├── nl.rem │ ├── no.rem │ ├── pl.rem │ ├── pt.rem │ └── ro.rem └── site │ └── README ├── install-sh ├── man ├── rem.1 ├── rem2ps.1 ├── remind.1 └── tkremind.1 ├── rem2html ├── Makefile.in ├── README.rem2html └── rem2html ├── rem2pdf ├── Makefile.PL.in ├── Makefile.top.in ├── README ├── bin │ └── rem2pdf.in └── lib │ └── Remind │ ├── PDF.pm │ └── PDF │ └── Entry.pm ├── scripts ├── README └── tkremind ├── src ├── Makefile.in ├── calendar.c ├── compare-language-mods.pl ├── config.h.in ├── custom.h ├── custom.h.in ├── dorem.c ├── dosubst.c ├── dynbuf.c ├── dynbuf.h ├── err.h ├── expr.c ├── expr.h ├── files.c ├── funcs.c ├── globals.c ├── globals.h ├── hbcal.c ├── init.c ├── json.c ├── json.h ├── lang.h ├── langs │ ├── danish.h │ ├── dutch.h │ ├── english.h │ ├── finnish.h │ ├── french.h │ ├── german.h │ ├── icelandic.h │ ├── italian.h │ ├── norwgian.h │ ├── polish.h │ ├── portbr.h │ ├── romanian.h │ └── spanish.h ├── main.c ├── md5.c ├── md5.h ├── moon.c ├── omit.c ├── protos.h ├── queue.c ├── rem2ps.c ├── rem2ps.h ├── sort.c ├── test-all-languages.sh ├── token.c ├── trigger.c ├── types.h ├── userfns.c ├── utils.c ├── var.c └── version.h.in ├── tests ├── colors.rem ├── file.ps ├── file2.ps ├── include_dir │ ├── 01.rem │ ├── 02.rem │ ├── 03.notrem │ ├── 04cantread.rem │ └── subdir │ │ └── 04.rem ├── include_dir_no_rems │ └── 03.notrem ├── include_test.rem ├── purge_dir │ ├── f1.rem │ ├── f2.rem │ └── f3.rem ├── runinc.rem ├── runtest.rem ├── scripts.rem ├── shade.rem ├── sun.rem ├── test-addomit.rem ├── test-for-backends.rem ├── test-rem ├── test.cmp ├── test.rem ├── test2.rem ├── test3.rem ├── tstlang.rem └── utf-8.rem ├── unconfigure └── www ├── Makefile.in ├── README ├── blank.rem ├── cal_dispatch-DIST ├── calendar.html-DIST ├── calps ├── firstquarter.png ├── fullmoon.png ├── hebdate ├── hebdate.rem-DIST ├── hebhtml ├── hebps ├── lastquarter.png ├── moon ├── moon.rem-DIST ├── newmoon.png ├── rem-default.css ├── sunrise ├── sunrise.rem-DIST ├── sunset └── sunset.rem-DIST /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | 2 | liberapay: dskoll 3 | -------------------------------------------------------------------------------- /.github/README.md: -------------------------------------------------------------------------------- 1 | # Remind has moved 2 | 3 | For various reasons, I have decided to move Remind off GitHub. This repo 4 | will be archived. To create merge requests or issues, please visit 5 | Remind's new home at https://salsa.debian.org/dskoll/remind 6 | 7 | -- Dianne Skoll 8 | -------------------------------------------------------------------------------- /.github/workflows/github-action.yml: -------------------------------------------------------------------------------- 1 | # language: bash 2 | --- 3 | 4 | name: Remind unit tests 5 | 6 | on: 7 | push 8 | 9 | jobs: 10 | tests: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout Remind 14 | uses: actions/checkout@v2 15 | - name: Add test user 16 | run: | 17 | sudo adduser --home /home/testuser --gecos 'Test User' --disabled-password testuser 18 | - name: Fix ownership 19 | run: | 20 | sudo chown -R testuser . 21 | - name: Build 22 | run: | 23 | sudo su -c './configure && make' testuser 24 | - name: Run Tests 25 | run: | 26 | sudo su -c 'make test' testuser 27 | - name: Fix up permissions so GitHub does not complain 28 | run: | 29 | sudo chmod -R a+rwX . 30 | -------------------------------------------------------------------------------- /MICROSOFT-AND-APPLE: -------------------------------------------------------------------------------- 1 | MICROSOFT WINDOWS 2 | ================= 3 | 4 | I used to prohibit porting Remind to Microsoft Windows. However, this 5 | may cause problems with the GPL, so I have removed that restriction. 6 | 7 | Although I cannot prevent you from porting Remind to Windows, I appeal 8 | to you not to do it. I am trying to encourage the growth of free 9 | software, not proprietary software. 10 | 11 | If you port Remind to Windows, I will not provide support or answers to 12 | questions -- you're on your own. On the other hand, I will feel no guilt 13 | in taking enhancements and merging them into the UNIX stream. 14 | 15 | APPLE 16 | ===== 17 | 18 | I can't prevent you from using Remind on Apple's products, but I hope 19 | you don't. Apple's corporate culture is the very antithesis of Free 20 | Software. Rather than using Mac OS X, I encourage you to switch to 21 | Linux or FreeBSD, two Free Software operating systems that are every 22 | bit as capable as Mac OS X and which are unencumbered by Apple's 23 | arbitrary restrictions. 24 | 25 | And if you're looking to port Remind to other Apple products like the 26 | iPhone or iPad, please don't. Those products enforce Apple's rigorous 27 | controls much more stringently than Mac OS X on an Apple PC. 28 | 29 | -- 30 | Dianne Skoll 31 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Top-level Makefile for Remind. 2 | 3 | all: src/Makefile 4 | @echo "" 5 | @echo "*******************" 6 | @echo "* *" 7 | @echo "* Building REMIND *" 8 | @echo "* *" 9 | @echo "*******************" 10 | @echo "" 11 | @cd src && $(MAKE) all LANGDEF=$(LANGDEF) 12 | @$(MAKE) -C rem2pdf -f Makefile.top 13 | install: 14 | @echo "" 15 | @echo "*********************" 16 | @echo "* *" 17 | @echo "* Installing REMIND *" 18 | @echo "* *" 19 | @echo "*********************" 20 | @echo "" 21 | @$(MAKE) -C src install 22 | @$(MAKE) -C rem2html install 23 | @$(MAKE) -C rem2pdf -f Makefile.top install INSTALL_BASE=$(INSTALL_BASE) 24 | clean: 25 | find . -name '*~' -exec rm {} \; 26 | -$(MAKE) -C src clean 27 | -$(MAKE) -C rem2pdf clean 28 | 29 | test: 30 | @$(MAKE) -C src -s test 31 | 32 | distclean: clean 33 | rm -f config.cache config.log config.status src/Makefile src/config.h tests/test.out www/Makefile rem2pdf/Makefile.top rem2pdf/Makefile.old rem2pdf/Makefile rem2pdf/Makefile.PL rem2pdf/bin/rem2pdf 34 | 35 | src/Makefile: src/Makefile.in 36 | ./configure 37 | 38 | # DO NOT DELETE 39 | 40 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | REMIND 2 | 3 | Remind is a full-featured calendar/alarm program. Copying policy is 4 | in the file "COPYRIGHT" in this directory. 5 | 6 | Installation notes for various operating systems are in "docs". See 7 | the appropriate README file for installation on your system. 8 | 9 | Manual pages are in "man". 10 | 11 | ----------------------------------------------------------------------------- 12 | 13 | Quick UNIX installation instructions for the very impatient: 14 | 15 | If you have Tcl/Tk (wish 4.1 or higher) installed and are running X Windows: 16 | -------------------------------------------------------------- 17 | 18 | 1) Type: wish ./build.tk from this directory. Fill in the various 19 | options and hit "Build Remind" 20 | 21 | 2) Type: "make install" -- you may need to be root to do this. 22 | 23 | If you do NOT have Tcl/Tk or are NOT running X Windows: 24 | ------------------------------------------------------- 25 | 26 | 1) Edit the file "src/custom.h" according to your preferences. 27 | 28 | 2) Edit the file "src/lang.h" to choose a language. 29 | 30 | 3) Type: "./configure" (You can supply options; type "./configure --help" 31 | for details.) 32 | 33 | 4) Type: "make" 34 | 35 | 5) Type: "make install" -- you may need to be root to do this. 36 | 37 | Contact info: mailto:dianne@skoll.ca 38 | Home page: https://dianne.skoll.ca/projects/remind/ 39 | -------------------------------------------------------------------------------- /configure.in: -------------------------------------------------------------------------------- 1 | dnl Process this file with autoconf to produce a configure script. 2 | 3 | AC_INIT(src/queue.c) 4 | 5 | cat <<'EOF' 6 | 7 | ********************** 8 | * * 9 | * Configuring REMIND * 10 | * * 11 | ********************** 12 | 13 | EOF 14 | 15 | AC_CONFIG_HEADER(src/config.h) 16 | 17 | AC_ARG_ENABLE(perl-build-artifacts, 18 | [ --disable-perl-build-artifacts 19 | Disable perllocal.pod and .packlist generation], ac_cv_perlartifacts=$enableval, ac_cv_perlartifacts=yes) 20 | 21 | AH_BOTTOM([#include ]) 22 | 23 | dnl Checks for programs. 24 | AC_PROG_CC 25 | AC_PROG_INSTALL 26 | AC_PROG_LN_S 27 | AC_PROG_MAKE_SET 28 | AC_PATH_PROG([PERL], [perl]) 29 | 30 | dnl Checks for libraries. 31 | AC_CHECK_LIB(m, sqrt) 32 | 33 | dnl Integer sizes 34 | AC_CHECK_SIZEOF(unsigned int) 35 | AC_CHECK_SIZEOF(unsigned long) 36 | 37 | dnl Checks for header files. 38 | AC_CHECK_HEADERS(sys/types.h sys/file.h glob.h wctype.h locale.h langinfo.h) 39 | 40 | dnl Checks for typedefs, structures, and compiler characteristics. 41 | AC_STRUCT_TM 42 | 43 | dnl Checks for library functions. 44 | AC_FUNC_UTIME_NULL 45 | AC_HEADER_TIME 46 | 47 | if test "$GCC" = yes; then 48 | CFLAGS="$CFLAGS -Wall -Wextra -Wstrict-prototypes" 49 | # Check for link-time optimization support 50 | for f in -flto=auto -ffat-lto-objects; do 51 | AC_MSG_CHECKING([whether $CC supports $f]) 52 | if $CC -E $f /dev/null > /dev/null 2>&1 ; then 53 | AC_MSG_RESULT([yes]) 54 | CFLAGS="$CFLAGS $f" 55 | else 56 | AC_MSG_RESULT([no]) 57 | fi 58 | done 59 | fi 60 | 61 | if test "$ac_cv_perlartifacts" = "yes" ; then 62 | PERLARTIFACTS= 63 | else 64 | PERLARTIFACTS='NO_PACKLIST=1 NO_PERLLOCAL=1' 65 | fi 66 | 67 | AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale initgroups) 68 | VERSION=04.00.01 69 | AC_SUBST(VERSION) 70 | AC_SUBST(PERL) 71 | AC_SUBST(PERLARTIFACTS) 72 | AC_OUTPUT(src/Makefile www/Makefile src/version.h rem2html/Makefile rem2pdf/Makefile.PL rem2pdf/Makefile.top rem2pdf/bin/rem2pdf) 73 | chmod a+x rem2pdf/bin/rem2pdf 74 | -------------------------------------------------------------------------------- /contrib/README: -------------------------------------------------------------------------------- 1 | This directory contains contributed scripts. They are provided 2 | "as-is" with no warranty. Please do not contact Dianne Skoll for help 3 | with these scripts; instead, contact the script authors. 4 | 5 | You should check the upstream sources; there may be newer versions 6 | of these scripts available. 7 | 8 | -- 9 | Dianne Skoll 10 | -------------------------------------------------------------------------------- /contrib/rem2ics-0.93/Makefile: -------------------------------------------------------------------------------- 1 | DESTDIR?= 2 | PREFIX?=/usr 3 | BINDIR?=$(PREFIX)/bin 4 | MANDIR?=$(PREFIX)/share/man 5 | 6 | default: rem2ics.1 7 | 8 | rem2ics.1: 9 | pod2man -c "" rem2ics > rem2ics.1 10 | 11 | install: rem2ics.1 12 | install -p -D rem2ics $(DESTDIR)$(BINDIR)/rem2ics 13 | install -p -D -m 0644 rem2ics.1 $(DESTDIR)$(MANDIR)/man1/rem2ics.1 14 | -------------------------------------------------------------------------------- /contrib/rem2ics-0.93/rem2ics.spec: -------------------------------------------------------------------------------- 1 | Name: rem2ics 2 | Version: 0.93 3 | Release: 1%{?dist} 4 | Summary: Converts the output of "remind -s" into RFC2445 iCalendar format 5 | 6 | Group: Applications/Productivity 7 | License: GPLv2+ 8 | URL: http://mark.atwood.name/code/rem2ics/ 9 | Source0: http://mark.atwood.name/code/rem2ics/rem2ics-%{version}.tar.gz 10 | Source1: rem2ics-Makefile 11 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 12 | 13 | BuildArch: noarch 14 | BuildRequires: perl 15 | 16 | 17 | %description 18 | rem2ics converts the output of "remind -s" into RFC2445 iCalendar format. 19 | You may want to install remind if you install this package. 20 | 21 | 22 | %prep 23 | %setup -q -c 24 | cp -a %SOURCE1 Makefile 25 | 26 | 27 | %build 28 | make %{?_smp_mflags} 29 | 30 | 31 | %install 32 | rm -rf $RPM_BUILD_ROOT 33 | mkdir $RPM_BUILD_ROOT 34 | make install DESTDIR=$RPM_BUILD_ROOT 35 | 36 | 37 | %clean 38 | rm -rf $RPM_BUILD_ROOT 39 | 40 | 41 | %files 42 | %defattr(-,root,root,-) 43 | %doc 44 | %{_bindir}/rem2ics 45 | %{_mandir}/man1/rem2ics.1* 46 | 47 | 48 | %changelog 49 | * Tue Mar 25 2008 Till Maas - 0.92-1 50 | - initial spec for Fedora 51 | -------------------------------------------------------------------------------- /contrib/remind-conf-mode/README: -------------------------------------------------------------------------------- 1 | Remind-conf-mode is a configuration mode designed to make it a little easier to configure remind using emacs. 2 | 3 | It offers a vibrant colour syntax highlighting for those who like lots of colour, simple indentation and some hopefully useful functions for entering times and dates. Those functions have been exposed in a special menu for remind for those who have not turned off the emacs menu system. 4 | 5 | Just copy remind-conf-mode.el to your elisp folder (whatever it is called) make sure it is in your path so emacs know where to look for it, and put (require 'remind-conf-mode) in your dotemacs file. 6 | 7 | There are some more complex instructions in the file itself. 8 | 9 | Have fun and if you can think of any improvements let me know, or fork it to your own git repository and experiment away. 10 | 11 | The faux-locale branch has code for choosing the language you use remind in. Please try it out and let me know if there are any problems with it. 12 | 13 | Shelagh -------------------------------------------------------------------------------- /contrib/remind-conf-mode/ac-remind.el: -------------------------------------------------------------------------------- 1 | ;;; setup for remind autocompletion (totally optional) 2 | 3 | ;; put something like 4 | ;; (add-hook 'remind-conf-mode '(load-library "ac-remind")) in your .emacs file. 5 | (require 'auto-complete) 6 | 7 | (define-key ac-complete-mode-map "\r" nil) 8 | 9 | (defvar ac-remind-keywords 10 | '((candidates 11 | . (lambda () 12 | (all-completions ac-target remind-keywords )))) 13 | "Source for remind-conf completion keywords.") 14 | 15 | (defvar ac-remind-time-words 16 | '((candidates 17 | . (lambda () 18 | (all-completions ac-target remind-time-words)))) 19 | "Source for remind-conf time words completions.") 20 | 21 | (defvar ac-remind-builtin-variables 22 | '((candidates 23 | . (lambda () 24 | (all-completions ac-target remind-builtin-variables)))) 25 | "Source for remind-conf builtin variables.") 26 | 27 | (defvar ac-remind-type-keywords 28 | '((candidates 29 | . (lambda () 30 | (all-completions ac-target remind-type-keywords)))) 31 | "Source for remind-conf type keywords.") 32 | 33 | (defvar ac-remind-builtin-functions 34 | '((candidates 35 | . (lambda () 36 | (all-completions ac-target remind-builtin-functions)))) 37 | "Source for remind-conf completion builtin functions.") 38 | 39 | (add-hook 'remind-conf-mode-hook 40 | (lambda () "Makes auto-completion work in remind-conf-mode" 41 | (make-local-variable 'ac-sources) 42 | (setq ac-sources '(ac-remind-keywords 43 | ac-remind-builtin-variables 44 | ac-remind-builtin-functions 45 | ac-remind-type-keywords 46 | ac-remind-time-words 47 | ac-source-abbrev)) 48 | (auto-complete-mode 1))) 49 | 50 | (provide 'ac-remind) 51 | ;; (define-skeleton ac-look 52 | ;; "" 53 | ;; (skeleton-read "well? ") 54 | ;; "(when (looking-at (regexp-opt remind-" str " 'words))" \n 55 | ;; >"(setq ac-sources '(ac-remind-" str ")))" 56 | ;; ) -------------------------------------------------------------------------------- /docs/README.UNIX: -------------------------------------------------------------------------------- 1 | REMIND version 3.2 for UNIX 2 | 3 | REMIND is a sophisticated alarm/calendar program. Details are given 4 | in the man page, "remind.1". 5 | 6 | INSTALLING REMIND: 7 | ----------------- 8 | 9 | If you have Tcl/Tk (wish 4.1 or higher) installed and are running X11: 10 | ---------------------------------------------------------------------- 11 | 12 | 1) Type: wish ./build.tk from the top-level Remind directory. 13 | Fill in the various options and hit "Build Remind" 14 | 15 | 2) Type: "make install" -- you may need to be root to do this. 16 | 17 | If you do NOT have Tcl/Tk or are NOT running X11: 18 | ------------------------------------------------- 19 | 20 | 1) Edit the file "src/custom.h" according to your preferences. 21 | 22 | 2) Edit the file "src/lang.h" to choose a language. 23 | 24 | 3) Type: "make" 25 | 26 | 4) Type: "make install" -- you may need to be root to do this. 27 | 28 | The subdirectory "www" contains scripts for making a nice calendar 29 | web server. See the files README and Makefile in that directory. 30 | 31 | The file "examples/defs.rem" has some sample Remind definitions and 32 | commands, as well as U.S. and Jewish holidays. 33 | 34 | OTHER LANGUAGE SUPPORT 35 | 36 | Remind has support for languages other than English. See the file 37 | "src/lang.h" for details. The language support may vary - you can change 38 | only the substitution filter, or you can translate all of the usage 39 | instructions and error messages as well. See "src/langs/french.h" for an 40 | example of the latter. 41 | 42 | To compile Remind for a non-english language, look at the constants 43 | defined in "src/lang.h". Then, to compile Remind for Italian (as an 44 | example), type: 45 | 46 | make "LANGDEF=-DLANG=ITALIAN" 47 | 48 | If you add support for a non-English language, Remind will accept both the 49 | English and non-English names of months and weekdays in an input script. 50 | However, you should not rely on this feature if you want to write portable 51 | Remind scripts. 52 | 53 | At a minimum, you should support month and day names in the foreign 54 | language, and should modify the substitution filter appropriately. 55 | If you are truly diligent, you can translate usage and error messages 56 | too. 57 | 58 | Take a look at the files "src/langs/english.h" and 59 | "src/langs/german.h" if you want to add support for your favourite 60 | language. If you do add another language to Remind, please let me 61 | know! Here are the basic guidelines: 62 | 63 | - Your language file should be called "src/langs/lxxx.h", where lxxx 64 | is the first 8 characters of the ENGLISH name of your language. 65 | 66 | - Your language file should define L_LANGNAME to be the full English 67 | name of your language, with the first letter capitalized and the rest 68 | lower-case. 69 | 70 | - You can test your language file with the script "tests/tstlang.rem" 71 | 72 | - Your localized strings must be encoded using UTF-8. 73 | 74 | RELEASE NOTES -- miscellaneous info that couldn't go anywhere else! 75 | 76 | 1. POPUP REMINDERS 77 | 78 | If you're running under X11 and you have the Tcl tools, you can create 79 | simple pop-up reminders by creating the following Tcl script called 80 | 'popup'. It pops a message on to the screen and waits for you to 81 | press the 'OK' button. If you don't press the OK button within 15 82 | seconds, it exits anyway. To use it, you can use the '-k' option for 83 | Remind as follows: 84 | 85 | remind "-kpopup '%s'&" .reminders 86 | 87 | Or use the following in your Remind script: 88 | 89 | REM AT 17:00 RUN popup 'Time to go home.' & 90 | 91 | This Tcl script is a slightly modified version of one submitted by 92 | Norman Walsh. 93 | 94 | -------------- Cut Here ---------- Cut Here ---------- Cut Here ------------- 95 | #!/usr/local/bin/wish 96 | wm withdraw . 97 | after 15000 { destroy . ; exit } 98 | tk_dialog .d { Message } $argv warning 0 { OK } 99 | destroy . 100 | exit 101 | -------------- Cut Here ---------- Cut Here ---------- Cut Here ------------- 102 | 103 | 104 | -- 105 | Dianne Skoll 106 | https://dianne.skoll.ca/projects/remind/ 107 | -------------------------------------------------------------------------------- /docs/WHATSNEW: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfskoll/remind/ef7742a3cccc49b490d46f3a6b738e5896a10d04/docs/WHATSNEW -------------------------------------------------------------------------------- /examples/remind.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: Remind 3 | " Maintainer: Davide Alberani 4 | " Last Change: 02 Nov 2015 + 13 Mar 2022 by Dianne Skoll 5 | " Version: 0.7+dianne1 6 | " URL: http://ismito.it/vim/syntax/remind.vim 7 | " 8 | " remind is a sophisticated reminder service 9 | " you can download remind from: 10 | " https://dianne.skoll.ca/projects/remind/ 11 | 12 | if version < 600 13 | syntax clear 14 | elseif exists("b:current_syntax") 15 | finish 16 | endif 17 | 18 | " shut case off. 19 | syn case ignore 20 | 21 | syn keyword remindCommands REM OMIT SET FSET UNSET 22 | syn keyword remindExpiry UNTIL FROM SCANFROM SCAN WARN SCHED THROUGH 23 | syn keyword remindTag PRIORITY TAG 24 | syn keyword remindTimed AT DURATION 25 | syn keyword remindMove ONCE SKIP BEFORE AFTER 26 | syn keyword remindSpecial INCLUDE INC BANNER PUSH-OMIT-CONTEXT PUSH CLEAR-OMIT-CONTEXT CLEAR POP-OMIT-CONTEXT POP COLOR COLOUR DO 27 | syn keyword remindRun MSG MSF RUN CAL SATISFY SPECIAL PS PSFILE SHADE MOON 28 | syn keyword remindConditional IF ELSE ENDIF IFTRIG 29 | syn keyword remindDebug DEBUG DUMPVARS DUMP ERRMSG FLUSH PRESERVE 30 | syn match remindComment "#.*$" 31 | syn region remindString start=+'+ end=+'+ skip=+\\\\\|\\'+ oneline 32 | syn region remindString start=+"+ end=+"+ skip=+\\\\\|\\"+ oneline 33 | syn match remindVar "\$[_a-zA-Z][_a-zA-Z0-9]*" 34 | syn match remindSubst "%[^ ]" 35 | syn match remindAdvanceNumber "\(\*\|+\|-\|++\|--\)[0-9]\+" 36 | " XXX: use different separators for dates and times? 37 | syn match remindDateSeparators "[/:@\.-]" contained 38 | syn match remindTimes "[0-9]\{1,2}[:\.][0-9]\{1,2}" contains=remindDateSeparators 39 | " XXX: why not match only valid dates? Ok, checking for 'Feb the 30' would 40 | " be impossible, but at least check for valid months and times. 41 | syn match remindDates "'[0-9]\{4}[/-][0-9]\{1,2}[/-][0-9]\{1,2}\(@[0-9]\{1,2}[:\.][0-9]\{1,2}\)\?'" contains=remindDateSeparators 42 | " This will match trailing whitespaces that seem to break rem2ps. 43 | " Courtesy of Michael Dunn. 44 | syn match remindWarning display excludenl "\S\s\+$"ms=s+1 45 | 46 | 47 | if version >= 508 || !exists("did_remind_syn_inits") 48 | if version < 508 49 | let did_remind_syn_inits = 1 50 | command -nargs=+ HiLink hi link 51 | else 52 | command -nargs=+ HiLink hi def link 53 | endif 54 | 55 | HiLink remindCommands Function 56 | HiLink remindExpiry Repeat 57 | HiLink remindTag Label 58 | HiLink remindTimed Statement 59 | HiLink remindMove Statement 60 | HiLink remindSpecial Include 61 | HiLink remindRun Function 62 | HiLink remindConditional Conditional 63 | HiLink remindComment Comment 64 | HiLink remindTimes String 65 | HiLink remindString String 66 | HiLink remindDebug Debug 67 | HiLink remindVar Identifier 68 | HiLink remindSubst Constant 69 | HiLink remindAdvanceNumber Number 70 | HiLink remindDateSeparators Comment 71 | HiLink remindDates String 72 | HiLink remindWarning Error 73 | 74 | delcommand HiLink 75 | endif 76 | 77 | let b:current_syntax = "remind" 78 | 79 | " vim: ts=8 sw=2 80 | -------------------------------------------------------------------------------- /include/holidays/ca.rem: -------------------------------------------------------------------------------- 1 | # Canadian holidays 2 | 3 | OMIT 1 Jan MSG New Year's Day 4 | 5 | # This varies by province 6 | REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG Family Day 7 | 8 | # This varies by province 9 | OMIT [easterdate($Uy) - 2] MSG Good Friday 10 | 11 | # This varies by province 12 | OMIT [easterdate($Uy) + 1] MSG Easter Monday 13 | 14 | REM Mon 18 May SCANFROM -7 ADDOMIT MSG Victoria Day 15 | OMIT 1 July MSG Canada Day 16 | 17 | # This varies by province 18 | REM First Monday in Aug SCANFROM -7 ADDOMIT MSG Civic Holiday 19 | 20 | REM First Monday in Sep SCANFROM -7 ADDOMIT MSG Labour Day 21 | 22 | REM Second Monday in Oct SCANFROM -7 ADDOMIT MSG Thanksgiving Day 23 | 24 | REM 11 November MSG Remembrance Day 25 | 26 | OMIT 25 Dec MSG Christmas 27 | 28 | OMIT 26 Dec MSG Boxing Day 29 | 30 | -------------------------------------------------------------------------------- /include/holidays/us.rem: -------------------------------------------------------------------------------- 1 | # US holidays 2 | # This file is part of REMIND. 3 | # Copyright (C) 1992-2022 Dianne Skoll 4 | 5 | REM [easterdate($Uy)-46] MSG %"Ash Wednesday%" 6 | REM [easterdate($Uy)-7] MSG %"Palm Sunday%" 7 | OMIT [easterdate($Uy)-2] MSG %"Good Friday%" 8 | OMIT [easterdate($Uy)] MSG %"Easter%" Sunday 9 | REM [easterdate($Uy)+39] MSG %"Ascension Day%" 10 | REM [easterdate($Uy)+49] MSG %"Pentecost%" 11 | 12 | # Some holidays are omitted, some are not. You may want to change 13 | # which ones are omitted. 14 | 15 | OMIT Jan 1 MSG %"New Year's Day%" 16 | REM Third Monday in Jan MSG Martin Luther King - %"MLK Day%" 17 | REM Feb 2 MSG %"Ground Hog Day%" 18 | REM Feb 14 MSG %"Valentine's Day%" 19 | REM Third Monday in Feb SCANFROM -7 ADDOMIT MSG %"President's Day%" 20 | REM Mar 17 MSG %"St. Patrick's Day%" 21 | 22 | # The DST rules are accurate for most locations in 23 | # North America 24 | REM Sun Apr 1 ++2 UNTIL 1 Jan 2007 MSG Daylight Saving Time - %"DST starts%" %b 25 | REM Sun Mar 8 ++2 FROM 1 Jan 2007 MSG Daylight Saving Time - %"DST starts%" %b 26 | 27 | REM Last Sunday in October ++2 UNTIL 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b 28 | REM First Sunday in November ++2 FROM 1 Jan 2007 MSG Daylight Saving Time - %"DST ends%" %b 29 | 30 | REM Apr 1 MSG %"April Fool's%" Day 31 | REM Mon Tue Wed Thu Fri Sat 15 Apr MSG %"Income tax%" due 32 | REM May 5 MSG %"Cinco de Mayo%" 33 | REM First Sat in May MSG %"Kentucky Derby%" 34 | REM Second Sun in May MSG %"Mother's Day%" 35 | REM Third Sat in May MSG %"Armed Forces Day%" 36 | REM Last Monday in May SCANFROM -7 ADDOMIT MSG %"Memorial Day%" 37 | REM Jun 14 MSG %"Flag Day%" 38 | REM Third Sun in June MSG %"Father's Day%" 39 | REM First Mon in Sep SCANFROM -7 ADDOMIT MSG %"Labor Day%" 40 | REM Second Mon in Oct MSG %"Columbus Day%" 41 | REM Nov 11 MSG %"Veterans Day%" 42 | 43 | REM Oct 30 MSG %"Mischief Night%" 44 | REM Oct 31 MSG %"Halloween%" 45 | REM Tue Nov 2 SCANFROM -7 SATISFY [($Ty % 4) == 0] MSG %"Election Day%" 46 | REM Last Thu in Nov SCANFROM -7 ADDOMIT MSG %"Thanksgiving Day%" 47 | REM Fri Nov [Week_4+1] SCANFROM -7 ADDOMIT MSG %"Thanksgiving (cont.)%" 48 | REM Dec 24 MSG %"Christmas Eve%" 49 | OMIT Dec 25 MSG %"Christmas%" Day 50 | -------------------------------------------------------------------------------- /include/lang/auto.rem: -------------------------------------------------------------------------------- 1 | SET autolang getenv("LC_ALL") 2 | IF autolang == "" 3 | SET autolang getenv("LANGUAGE") 4 | ENDIF 5 | IF autolang == "" 6 | SET autolang getenv("LANG") 7 | ENDIF 8 | 9 | IF autolang != "" 10 | IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 5)) + ".rem", "r") == 0 11 | INCLUDE [$SysInclude]/lang/[lower(substr(autolang, 1, 5))].rem 12 | ELSE 13 | IF access($SysInclude + "/lang/" + lower(substr(autolang, 1, 2)) + ".rem", "r") == 0 14 | INCLUDE [$SysInclude]/lang/[lower(substr(autolang, 1, 2))].rem 15 | ENDIF 16 | ENDIF 17 | ENDIF 18 | 19 | UNSET autolang 20 | -------------------------------------------------------------------------------- /include/lang/da.rem: -------------------------------------------------------------------------------- 1 | # Support for the Danish language. 2 | # This file is part of REMIND. 3 | # REMIND is Copyright (C) 1992-2022 by Dianne Skoll 4 | # This file is derived from a translation by Mogens Lynnerup. 5 | 6 | SET $Sunday "Søndag" 7 | SET $Monday "Mandag" 8 | SET $Tuesday "Tirsdag" 9 | SET $Wednesday "Onsdag" 10 | SET $Thursday "Torsdag" 11 | SET $Friday "Fredag" 12 | SET $Saturday "Lørdag" 13 | 14 | SET $January "Januar" 15 | SET $February "Februar" 16 | SET $March "Marts" 17 | SET $April "April" 18 | SET $May "Maj" 19 | SET $June "Juni" 20 | SET $July "Juli" 21 | SET $August "August" 22 | SET $September "September" 23 | SET $October "Oktober" 24 | SET $November "November" 25 | SET $December "December" 26 | 27 | SET $Today "i dag" 28 | SET $Tomorrow "i morgen" 29 | 30 | BANNER Påmindelse for %w, %d. %m, %y%o: 31 | 32 | SET $Am "am" 33 | SET $Pm "pm" 34 | 35 | SET $Ago "siden" 36 | SET $Fromnow "fra nu" 37 | 38 | SET $On "på" 39 | 40 | SET $Now "nu" 41 | SET $At "kl." 42 | SET $Minute "minut" 43 | SET $Hour "time" 44 | SET $Is "er" 45 | SET $Was "var" 46 | SET $And "og" 47 | SET $Hplu "r" 48 | SET $Mplu "ter" 49 | 50 | FSET subst_ampm(h) iif(h<5, " om natten", h < 12, " om formiddagen", h < 18, " om eftermiddagen", " om aftenen") 51 | FSET subst_ordinal(d) "." 52 | 53 | FSET subst_p(alt, d, t) iif(d==today()+1, "", "e") 54 | FSET zeropad(s, len) pad(s, "0", len) 55 | FSET subst_a_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) + " " + year(d) 56 | FSET subst_ax(alt, d, t) iif(alt, subst_a_alt(d), $On + " " + subst_a_alt(d)) 57 | 58 | FSET subst_bx(a, d, t) "om " + (d-today()) + " dage" 59 | 60 | FSET subst_ex(alt, d, t) "den " + zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2) + $DateSep + zeropad(year(d), 4) 61 | FSET subst_fx(alt, d, t) "den " + zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2) + $DateSep + zeropad(year(d), 4) 62 | 63 | FSET subst_g_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) 64 | FSET subst_gx(alt, d, t) iif(alt, subst_g_alt(d), $On + " " + subst_g_alt(d)) 65 | 66 | FSET subst_hx(alt, d, t) "den " + zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2) 67 | FSET subst_ix(alt, d, t) "den " + zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2) 68 | FSET subst_ux(alt, d, t) subst_ax(alt, d, t) 69 | FSET subst_vx(alt, d, t) subst_gx(alt, d, t) 70 | -------------------------------------------------------------------------------- /include/lang/de.rem: -------------------------------------------------------------------------------- 1 | # Support for the German language. 2 | # This file is part of REMIND. 3 | # REMIND is Copyright (C) 1992-2022 by Dianne Skoll 4 | # This file is derived from a translation by Wolfgang Thronicke 5 | 6 | # Day names 7 | SET $Sunday "Sonntag" 8 | SET $Monday "Montag" 9 | SET $Tuesday "Dienstag" 10 | SET $Wednesday "Mittwoch" 11 | SET $Thursday "Donnerstag" 12 | SET $Friday "Freitag" 13 | SET $Saturday "Samstag" 14 | 15 | # Month names 16 | SET $January "Januar" 17 | SET $February "Februar" 18 | SET $March "März" 19 | SET $April "April" 20 | SET $May "Mai" 21 | SET $June "Juni" 22 | SET $July "Juli" 23 | SET $August "August" 24 | SET $September "September" 25 | SET $October "Oktober" 26 | SET $November "November" 27 | SET $December "Dezember" 28 | 29 | SET $Today "heute" 30 | SET $Tomorrow "morgen" 31 | 32 | # Banner 33 | BANNER Termine für %w, den %d. %m %y%o: 34 | 35 | SET $Am "am" 36 | SET $Pm "pm" 37 | SET $On "am" 38 | SET $Hplu "n" 39 | SET $Mplu "n" 40 | SET $Now "jetzt" 41 | SET $At "um" 42 | SET $Minute "Minute" 43 | SET $Hour "Stunde" 44 | SET $Is "ist" 45 | SET $Was "war" 46 | SET $And "und" 47 | SET $Ago "vorher" 48 | SET $Fromnow "von heute" 49 | 50 | FSET subst_ampm(h) iif(h<5, " nachts", h<12, " vormittags", h<=17, " nachmittags", " abends") 51 | FSET subst_ordinal(d) "." 52 | 53 | FSET subst_a_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) + " " + year(d) 54 | FSET subst_ax(alt, d, t) iif(alt, subst_a_alt(d), $On + " " + subst_a_alt(d)) 55 | 56 | FSET subst_bx(a, d, t) "in " + (d-today()) + " Tagen" 57 | 58 | FSET subst_g_alt(d) wkday(d) + ", den " + day(d) + ". " + mon(d) 59 | FSET subst_gx(alt, d, t) iif(alt, subst_g_alt(d), $On + " " + subst_g_alt(d)) 60 | 61 | FSET subst_ux(alt, d, t) subst_ax(alt, d, t) 62 | FSET subst_vx(alt, d, t) subst_gx(alt, d, t) 63 | FSET subst_p(alt, d, t) iif(d == today()+1, "", "en") 64 | -------------------------------------------------------------------------------- /include/lang/en.rem: -------------------------------------------------------------------------------- 1 | # Support for the English language. 2 | # This file is part of REMIND. 3 | # REMIND is Copyright (C) 1992-2022 by Dianne Skoll 4 | # Nothing to do for English since it is the default. 5 | -------------------------------------------------------------------------------- /include/lang/es.rem: -------------------------------------------------------------------------------- 1 | # Support for the Spanish language. 2 | # This file is part of REMIND. 3 | # REMIND is Copyright (C) 1992-2022 by Dianne Skoll 4 | # This file is derived from a translation by Rafa Couto 5 | 6 | SET $Sunday "Domingo" 7 | SET $Monday "Lunes" 8 | SET $Tuesday "Martes" 9 | SET $Wednesday "Miércoles" 10 | SET $Thursday "Jueves" 11 | SET $Friday "Viernes" 12 | SET $Saturday "Sábado" 13 | 14 | SET $January "Enero" 15 | SET $February "Febrero" 16 | SET $March "Marzo" 17 | SET $April "Abril" 18 | SET $May "Mayo" 19 | SET $June "Junio" 20 | SET $July "Julio" 21 | SET $August "Agosto" 22 | SET $September "Septiembre" 23 | SET $October "Octubre" 24 | SET $November "Noviembre" 25 | SET $December "Diciembre" 26 | 27 | SET $Today "hoy" 28 | SET $Tomorrow "mañana" 29 | 30 | BANNER Agenda para el %w, %d%s %m, %y%o: 31 | 32 | SET $Am "am" 33 | SET $Pm "pm" 34 | 35 | SET $Ago "hace" 36 | SET $Fromnow "desde hoy" 37 | SET $On "el día" 38 | SET $Now "ahora" 39 | SET $At "a las" 40 | SET $Minute "minuto" 41 | SET $Hour "hora" 42 | SET $Is "es" 43 | SET $Was "fue" 44 | SET $And "y" 45 | SET $Hplu "s" 46 | SET $Mplu "s" 47 | 48 | FSET subst_bx(a, d, t) "dentro de " + (d-today()) + " días" 49 | -------------------------------------------------------------------------------- /include/lang/fi.rem: -------------------------------------------------------------------------------- 1 | # Support for the Finnish language. 2 | # This file is part of REMIND. 3 | # REMIND is Copyright (C) 1992-2022 by Dianne Skoll 4 | # This file is derived from a translation by Mikko Silvonen 5 | 6 | SET $Sunday "sunnuntai" 7 | SET $Monday "maanantai" 8 | SET $Tuesday "tiistai" 9 | SET $Wednesday "keskiviikko" 10 | SET $Thursday "torstai" 11 | SET $Friday "perjantai" 12 | SET $Saturday "lauantai" 13 | 14 | SET $January "tammikuu" 15 | SET $February "helmikuu" 16 | SET $March "maaliskuu" 17 | SET $April "huhtikuu" 18 | SET $May "toukokuu" 19 | SET $June "kesäkuu" 20 | SET $July "heinäkuu" 21 | SET $August "elokuu" 22 | SET $September "syyskuu" 23 | SET $October "lokakuu" 24 | SET $November "marraskuu" 25 | SET $December "joulukuu" 26 | 27 | SET $Today "tänään" 28 | SET $Tomorrow "huomenna" 29 | 30 | BANNER Viestit %wna %d. %mta %y%o: 31 | 32 | SET $Am " ap." 33 | SET $Pm " ip." 34 | 35 | SET $ago "sitten" 36 | SET $Fromnow "kuluttua" 37 | 38 | SET $On "na" 39 | 40 | SET $Now "nyt" 41 | SET $At "klo" 42 | SET $Minute "minuutti" 43 | SET $Hour "tunti" 44 | SET $Is "on" 45 | SET $Was "oli" 46 | SET $And "ja" 47 | SET $Hplu "a" 48 | SET $Mplu "a" 49 | 50 | FSET zeropad(s, len) pad(s, "0", len) 51 | 52 | FSET subst_ordinal(d) iif(d==1, ":senä", d==2, ":sena", (d%10)==2||(d%10)==3||(d%10)==6||(d%10)==8, ":ntena", ":ntenä") 53 | 54 | FSET subst_a_alt(d, o, p) wkday(d) + o + " " + day(d) + ". " + mon(d) + p + " " + year(d) 55 | FSET subst_ax(a, d, t) iif(a, subst_a_alt(d, "", ""), subst_a_alt(d, $On, "ta")) 56 | 57 | FSET subst_bx(a, d, t) (d-today()) + " päivän kuluttua" 58 | FSET subst_cx(a, d, t) iif(a, wkday(d), wkday(d) + $On) 59 | 60 | FSET subst_ex(a, d, t) zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2) + $DateSep + zeropad(year(d), 4) 61 | FSET subst_fx(a, d, t) zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2) + $DateSep + zeropad(year(d), 4) 62 | 63 | FSET subst_g_alt(d, o, p) wkday(d) + o + " " + day(d) + ". " + mon(d) + p 64 | FSET subst_gx(a, d, t) iif(a, subst_g_alt(d, "", ""), subst_g_alt(d, $On, "ta")) 65 | 66 | FSET subst_hx(a, d, t) zeropad(day(d), 2) + $DateSep + zeropad(monnum(d), 2) 67 | FSET subst_ix(a, d, t) zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2) 68 | 69 | FSET subst_j_alt(d, o) wkday(d) + o + " " + mon(d) + "n " + day(d) + subst_ordinal(day(d)) + " " + year(d) 70 | FSET subst_jx(a, d, t) iif(a, subst_j_alt(d, ""), subst_j_alt(d, $On)) 71 | 72 | FSET subst_k_alt(d, o) wkday(d) + o + " " + mon(d) + "n " + day(d) + subst_ordinal(day(d)) 73 | FSET subst_kx(a, d, t) iif(a, subst_k_alt(d, ""), subst_k_alt(d, $On)) 74 | 75 | FSET subst_lx(a, d, t) zeropad(year(d), 4) + $DateSep + zeropad(monnum(d), 2) + $DateSep + zeropad(day(d), 2) 76 | FSET subst_p(a, d, t) iif(d==today()+1, "", "ä") 77 | FSET subst_qx(a, d, t) "n" 78 | 79 | FSET subst_u_alt(d, o, p) wkday(d) + o + " " + day(d) + subst_ordinal(day(d)) + " " + mon(d) + p + " " + year(d) 80 | FSET subst_ux(a, d, t) iif(a, subst_u_alt(d, "", ""), subst_u_alt(d, $On, "ta")) 81 | 82 | FSET subst_v_alt(d, o, p) wkday(d) + o + " " + day(d) + subst_ordinal(day(d)) + " " + mon(d) + p 83 | FSET subst_vx(a, d, t) iif(a, subst_v_alt(d, "", ""), subst_v_alt(d, $On, "ta")) 84 | 85 | 86 | FSET subst_1(a, d, t) iif(t==now(), $Now, t now(), "dans " + subst_tdiff((time-now())/60, (time-now())%60), \ 55 | "il y a " + subst_tdiff ((now()-time)/60, (now()-time)%60)) 56 | 57 | FSET subst_bx(alt, date, time) "dans " + (date-today()) + " jours" 58 | FSET subst_j_alt(date) wkday(date) + ", " + day(date) + subst_ordinal(day(date)) + " " + mon(date) + ", " + year(date) 59 | FSET subst_jx(alt, date, time) iif(alt, subst_j_alt(date), $On + " " + subst_j_alt(date)) 60 | 61 | FSET subst_k_alt(date) wkday(date) + ", " + day(date) + subst_ordinal(day(date)) + " " + mon(date) 62 | FSET subst_kx(alt, date, time) iif(alt, subst_k_alt(date), $On + " " + subst_k_alt(date)) 63 | -------------------------------------------------------------------------------- /include/lang/is.rem: -------------------------------------------------------------------------------- 1 | # Support for the Icelanding language. 2 | # This file is part of REMIND. 3 | # REMIND is Copyright (C) 1992-2022 by Dianne Skoll 4 | # This file is derived from a translation by Björn Davíðsson (bjossi@snerpa.is) 5 | 6 | SET $Sunday "sunnudagur" 7 | SET $Monday "mánudagur" 8 | SET $Tuesday "þriðjudagur" 9 | SET $Wednesday "miðvikudagur" 10 | SET $Thursday "fimmtudagur" 11 | SET $Friday "föstudagur" 12 | SET $Saturday "laugardagur" 13 | 14 | SET $January "janúar" 15 | SET $February "febrúar" 16 | SET $March "mars" 17 | SET $April "apríl" 18 | SET $May "maí" 19 | SET $June "júní" 20 | SET $July "júlí" 21 | SET $August "ágúst" 22 | SET $September "september" 23 | SET $October "október" 24 | SET $November "nóvember" 25 | SET $December "desember" 26 | 27 | SET $Today "í dag" 28 | SET $Tomorrow "á morgun" 29 | 30 | BANNER Minnisatriði: %w, %d%s %m, %y%o: 31 | 32 | SET $Am "fh" 33 | SET $Pm "eh" 34 | 35 | SET $Ago "síðan" 36 | SET $Fromnow "frá því nú" 37 | 38 | SET $On "þann" 39 | 40 | SET $Now "núna" 41 | SET $At "kl." 42 | SET $Minute "mínútu" 43 | SET $Hour "klukkustund" 44 | SET $Is "er" 45 | SET $Was "var" 46 | SET $And "og" 47 | SET $Hplu "ir" 48 | SET $Mplu "r" 49 | 50 | FSET subst_bx(a, d, t) "eftir " + (d - today()) + " daga" 51 | fset subst_p(a, d, t) iif(d == today()+1, "", "a") 52 | -------------------------------------------------------------------------------- /include/lang/it.rem: -------------------------------------------------------------------------------- 1 | # Support for the Italian language. 2 | # This file is part of REMIND. 3 | # REMIND is Copyright (C) 1992-2022 by Dianne Skoll 4 | # This file is derived from a translation by Valerio Aimale 5 | 6 | SET $Sunday "Domenica" 7 | SET $Monday "Lunedí" 8 | SET $Tuesday "Martedí" 9 | SET $Wednesday "Mercoledí" 10 | SET $Thursday "Giovedí" 11 | SET $Friday "Venerdí" 12 | SET $Saturday "Sabato" 13 | 14 | SET $January "Gennaio" 15 | SET $February "Febbraio" 16 | SET $March "Marzo" 17 | SET $April "Aprile" 18 | SET $May "Maggio" 19 | SET $June "Giugno" 20 | SET $July "Luglio" 21 | SET $August "Agosto" 22 | SET $September "Settembre" 23 | SET $October "Ottobre" 24 | SET $November "Novembre" 25 | SET $December "Dicembre" 26 | 27 | SET $Today "oggi" 28 | SET $Tomorrow "domani" 29 | 30 | BANNER Promemoria per %w, %d %m %y%o: 31 | 32 | SET $Am "am" 33 | SET $Pm "pm" 34 | 35 | SET $Ago "fa" 36 | SET $Fromnow "da oggi" 37 | 38 | SET $On "" 39 | SET $Now "ora" 40 | SET $At "alle" 41 | SET $Minute "minuto" 42 | SET $Hour "ora" 43 | SET $Is "é" 44 | SET $Was "era" 45 | SET $And "e" 46 | SET $Hplu "a" 47 | SET $Mplu "i" 48 | 49 | FSET subst_bx(a, d, t) "fra " + (d-today()) + " giorni" 50 | FSET subst_p(a, d, t) iif(d==today()+1, "o", "i") 51 | FSET subst_q(a, d, t) iif(d==today()+1, "a", "e") 52 | 53 | FSET subst_ax(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d) + " " + year(d) 54 | FSET subst_jx(a, d, t) subst_ax(a, d, t) 55 | FSET subst_kx(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d) 56 | FSET subst_ux(a, d, t) subst_ax(a, d, t) 57 | FSET subst_vx(a, d, t) subst_kx(a, d, t) 58 | 59 | FSET subst_1(a, d, t) iif(t==now(), $Now, tnow(), "em " + subst_1help(t-now()), subst_1help(now()-t) + " " + $Ago) 67 | FSET subst_1help(diff) iif(diff/60==0, subst_mplu(diff%60), diff%60==0, subst_hplu(diff/60), subst_hplu(diff/60) + " " + $And + " " + subst_mplu(diff%60)) 68 | FSET subst_mplu(m) iif(m==1, "1 " + $Minute, m + " " + $Minute + $Mplu) 69 | FSET subst_hplu(h) iif(h==1, "1 " + $Hour, h + " " + $Hour + $Hplu) 70 | -------------------------------------------------------------------------------- /include/lang/ro.rem: -------------------------------------------------------------------------------- 1 | # Support for the Romanian language. 2 | # This file is part of REMIND. 3 | # REMIND is Copyright (C) 1992-2022 by Dianne Skoll 4 | # This file is derived from a translation by Liviu Daia 5 | 6 | SET $Sunday "Duminică" 7 | SET $Monday "Luni" 8 | SET $Tuesday "Marți" 9 | SET $Wednesday "Miercuri" 10 | SET $Thursday "Joi" 11 | SET $Friday "Vineri" 12 | SET $Saturday "Sâmbătă" 13 | 14 | SET $January "Ianuarie" 15 | SET $February "Februarie" 16 | SET $March "Martie" 17 | SET $April "Aprilie" 18 | SET $May "Mai" 19 | SET $June "Iunie" 20 | SET $July "Iulie" 21 | SET $August "August" 22 | SET $September "Septembrie" 23 | SET $October "Octombrie" 24 | SET $November "Noiembrie" 25 | SET $December "Decembrie" 26 | 27 | SET $Today "astăzi" 28 | SET $Tomorrow "mâine" 29 | 30 | BANNER Reamintiri pentru %w, %d %m %y%o: 31 | 32 | SET $Am "am" 33 | SET $Pm "pm" 34 | 35 | SET $Ago "acum" 36 | SET $Fromnow "peste" 37 | 38 | SET $On "pe" 39 | 40 | SET $Now "acum" 41 | SET $At "la ora" 42 | SET $Minute "minut" 43 | SET $Hour "or" 44 | SET $Is "este" 45 | SET $Was "a fost" 46 | SET $Mplu "e" 47 | SET $Hplu "e" 48 | SET $And "şi" 49 | 50 | FSET subst_bx(a, d, t) "peste " + (d-today()) + " zile" 51 | 52 | FSET subst_ampm(h) iif(h<4, " noaptea", h<12, " dimineaţa", h<18, " după-amiaza", " seara") 53 | FSET subst_ordinal(d) "" 54 | 55 | FSET subst_ax(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d) + " " + year(d) 56 | FSET subst_cx(a, d, t) wkday(d) 57 | FSET subst_gx(a, d, t) wkday(d) + ", " + day(d) + " " + mon(d) 58 | FSET subst_jx(a, d, t) wkday(d) + ", " + mon(d) + " " + day(d) + ", " + year(d) 59 | FSET subst_kx(a, d, t) wkday(d) + ", " + mon(d) + " " + day(d) 60 | FSET subst_ux(a, d, t) subst_ax(a, d, t) 61 | FSET subst_vx(a, d, t) subst_gx(a, d, t) 62 | FSET subst_p(a, d, t) iif(d==today()+1, "", "le") 63 | 64 | FSET subst_1(a, d, t) iif(t==now(), $Now, t 19 | .SH SEE ALSO 20 | \fBremind\fR 21 | -------------------------------------------------------------------------------- /rem2html/Makefile.in: -------------------------------------------------------------------------------- 1 | # Set by configure - don't touch. 2 | srcdir=@srcdir@ 3 | prefix=@prefix@ 4 | exec_prefix=@exec_prefix@ 5 | mandir=@mandir@ 6 | bindir=@bindir@ 7 | datadir=@datadir@ 8 | datarootdir=@datarootdir@ 9 | PERL=@PERL@ 10 | PERLMODS_NEEDED=JSON::MaybeXS Getopt::Long 11 | all: 12 | true 13 | 14 | install: 15 | @if test "$(PERL)" = "" ; then \ 16 | echo "Not installing rem2html; Perl is required"; exit 0; fi; \ 17 | for m in $(PERLMODS_NEEDED) ; \ 18 | do \ 19 | $(PERL) -M$$m -e 1 > /dev/null 2>&1; \ 20 | if test $$? != 0 ; then echo "Not installing rem2html; missing $$m"; exit 0; fi; \ 21 | done; \ 22 | pod2man rem2html > rem2html.1 && mkdir -p $(DESTDIR)$(mandir)/man1 && cp rem2html.1 $(DESTDIR)$(mandir)/man1/rem2html.1 || true; \ 23 | echo "Installing rem2html in $(DESTDIR)$(bindir)"; \ 24 | mkdir -p $(DESTDIR)$(bindir) && sed -e 's|^#!perl|#!$(PERL)|' < rem2html > $(DESTDIR)$(bindir)/rem2html && chmod 755 $(DESTDIR)$(bindir)/rem2html && exit 0; \ 25 | exit 1; 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /rem2html/README.rem2html: -------------------------------------------------------------------------------- 1 | REM2HTML 2 | -------- 3 | 4 | rem2html is a Perl script that transforms the output of `remind -pp 5 | ...' to HTML. Type `perl rem2html --help' for usage information. 6 | 7 | rem2html requires the Perl modules `JSON::Any' and `Getopt::Long'. It 8 | will not be installed unless you have those modules as well as Perl 9 | itself. 10 | 11 | -- 12 | Dianne Skoll 13 | -------------------------------------------------------------------------------- /rem2pdf/Makefile.PL.in: -------------------------------------------------------------------------------- 1 | use ExtUtils::MakeMaker; 2 | WriteMakefile( 3 | NAME => 'Remind::PDF', 4 | AUTHOR => q{Dianne Skoll }, 5 | VERSION => '@VERSION@', 6 | PREREQ_PM => { 7 | 'Getopt::Long' => 0, 8 | 'Cairo' => 0, 9 | 'Pango' => 0, 10 | }, 11 | EXE_FILES => [ 'bin/rem2pdf' ] 12 | ); 13 | -------------------------------------------------------------------------------- /rem2pdf/Makefile.top.in: -------------------------------------------------------------------------------- 1 | # Set by configure - don't touch. 2 | srcdir=@srcdir@ 3 | prefix=@prefix@ 4 | exec_prefix=@exec_prefix@ 5 | mandir=@mandir@ 6 | bindir=@bindir@ 7 | datadir=@datadir@ 8 | datarootdir=@datarootdir@ 9 | PERL=@PERL@ 10 | PERLMODS_NEEDED=Getopt::Long Cairo Pango 11 | 12 | all: Makefile 13 | @if test "$(PERL)" = "" ; then \ 14 | echo "Not building rem2pdf; Perl is required"; exit 0; fi; \ 15 | for m in $(PERLMODS_NEEDED) ; \ 16 | do \ 17 | $(PERL) -M$$m -e 1 > /dev/null 2>&1; \ 18 | if test $$? != 0 ; then echo "Not building rem2pdf; missing $$m"; exit 0; fi; \ 19 | done; \ 20 | $(MAKE) all && exit 0; \ 21 | exit 1; 22 | 23 | install: 24 | @if test "$(PERL)" = "" ; then \ 25 | echo "Not installing rem2pdf; Perl is required"; exit 0; fi; \ 26 | for m in $(PERLMODS_NEEDED) ; \ 27 | do \ 28 | $(PERL) -M$$m -e 1 > /dev/null 2>&1; \ 29 | if test $$? != 0 ; then echo "Not installing rem2pdf; missing $$m"; exit 0; fi; \ 30 | done; \ 31 | echo "Installing rem2pdf"; \ 32 | if test "$(INSTALL_BASE)" != "" ; then \ 33 | $(MAKE) install DESTDIR=$(DESTDIR) "INSTALL_BASE=$(INSTALL_BASE)" && exit 0; \ 34 | elif test "$(prefix)" = "/usr" ; then \ 35 | $(MAKE) install DESTDIR=$(DESTDIR) INSTALLDIRS=vendor && exit 0; \ 36 | elif test "$(prefix)" = "/usr/local" ; then \ 37 | $(MAKE) install DESTDIR=$(DESTDIR) && exit 0; \ 38 | else \ 39 | $(MAKE) install DESTDIR=$(DESTDIR) "INSTALL_BASE=$(prefix)" && exit 0; \ 40 | fi; \ 41 | exit 1; 42 | 43 | Makefile: Makefile.PL 44 | if test "$(prefix)" != "/usr" -a "$(prefix)" != "/usr/local" -a "$(INSTALL_BASE)" = "" ; then \ 45 | $(PERL) Makefile.PL @PERLARTIFACTS@ INSTALL_BASE=$(prefix) || true;\ 46 | else \ 47 | $(PERL) Makefile.PL @PERLARTIFACTS@ INSTALL_BASE=$(INSTALL_BASE) || true;\ 48 | fi 49 | -------------------------------------------------------------------------------- /rem2pdf/README: -------------------------------------------------------------------------------- 1 | rem2pdf is a Perl program that takes the output of "remind -p" and 2 | produces a PDF calendar. See "man rem2pdf" for details. 3 | 4 | rem2pdf has the following Perl modules as prerequisites: 5 | 6 | Pango - https://metacpan.org/pod/Pango 7 | Cairo - https://metacpan.org/pod/Cairo 8 | 9 | On Debian or Debian-derived systems, these can be installed with: 10 | 11 | apt install libpango-perl libcairo-perl 12 | 13 | On Red Hat or Red Hat-derived systems, you need to install the perl-Pango 14 | and perl-Cairo RPMs, which may require adding other repos to your list of 15 | RPM sources. 16 | 17 | rem2pdf is built and installed in the usual Perl program way: 18 | 19 | perl Makefile.PL && make && sudo make install 20 | 21 | -- 22 | Dianne Skoll - 23 | -------------------------------------------------------------------------------- /scripts/README: -------------------------------------------------------------------------------- 1 | Files in this directory: 2 | 3 | tkremind -- Tcl/Tk graphical calendar using Remind as engine 4 | -------------------------------------------------------------------------------- /src/Makefile.in: -------------------------------------------------------------------------------- 1 | # Makefile.in for REMIND 2 | # 3 | 4 | SHELL= /bin/sh 5 | BETA = 1 6 | srcdir=@srcdir@ 7 | prefix=@prefix@ 8 | exec_prefix=@exec_prefix@ 9 | mandir=@mandir@ 10 | bindir=@bindir@ 11 | datadir=@datadir@ 12 | datarootdir=@datarootdir@ 13 | VPATH=$(srcdir) 14 | VERSION=@VERSION@ 15 | 16 | INSTALL=@INSTALL@ 17 | INSTALL_PROGRAM=@INSTALL_PROGRAM@ 18 | INSTALL_DATA=@INSTALL_DATA@ 19 | 20 | PROGS= remind rem2ps 21 | SCRIPTS= $(srcdir)/../scripts/tkremind 22 | 23 | MANS= $(srcdir)/../man/rem2ps.1 $(srcdir)/../man/remind.1 \ 24 | $(srcdir)/../man/tkremind.1 $(srcdir)/../man/rem.1 25 | 26 | .SUFFIXES: 27 | .SUFFIXES: .c .o 28 | 29 | REMINDSRCS= calendar.c dynbuf.c dorem.c dosubst.c expr.c files.c funcs.c \ 30 | globals.c hbcal.c init.c main.c md5.c moon.c omit.c queue.c \ 31 | sort.c token.c trigger.c userfns.c utils.c var.c 32 | 33 | REMINDHDRS=config.h custom.h dynbuf.h err.h expr.h globals.h lang.h \ 34 | md5.h protos.h rem2ps.h types.h version.h 35 | REMINDOBJS= $(REMINDSRCS:.c=.o) 36 | 37 | all: remind rem2ps 38 | 39 | test: remind 40 | @sh ../tests/test-rem 41 | 42 | .c.o: 43 | @CC@ -c @CPPFLAGS@ @CFLAGS@ @DEFS@ $(CEXTRA) $(LANGDEF) -DSYSDIR=$(datarootdir)/remind -I. -I$(srcdir) $< 44 | 45 | $(REMINDOBJS): $(REMINDHDRS) 46 | 47 | rem2ps: rem2ps.o dynbuf.o json.o 48 | @CC@ @LDFLAGS@ $(LDEXTRA) -o rem2ps rem2ps.o dynbuf.o json.o -lm 49 | 50 | remind: $(REMINDOBJS) 51 | @CC@ @LDFLAGS@ $(LDEXTRA) -o remind $(REMINDOBJS) @LIBS@ 52 | 53 | install-nostripped: all 54 | -mkdir -p $(DESTDIR)$(bindir) || true 55 | for prog in $(PROGS) $(SCRIPTS) ; do \ 56 | $(INSTALL_PROGRAM) $$prog $(DESTDIR)$(bindir) || exit 1; \ 57 | done 58 | rm -f $(DESTDIR)$(bindir)/rem > /dev/null 2>&1 || true 59 | ln -s remind $(DESTDIR)$(bindir)/rem 60 | -mkdir -p $(DESTDIR)$(mandir)/man1 || true 61 | for man in $(MANS) ; do \ 62 | $(INSTALL_DATA) $$man $(DESTDIR)$(mandir)/man1 || exit 1; \ 63 | done 64 | -mkdir -p $(DESTDIR)$(datarootdir)/remind || true 65 | cp -R ../include/* $(DESTDIR)$(datarootdir)/remind 66 | 67 | install: install-nostripped 68 | strip $(DESTDIR)$(bindir)/remind || true 69 | strip $(DESTDIR)$(bindir)/rem2ps || true 70 | 71 | clean: 72 | rm -f *.o *~ core *.bak $(PROGS) 73 | 74 | clobber: 75 | rm -f *.o *~ remind rem2ps test.out core *.bak 76 | 77 | depend: 78 | gccmakedep @DEFS@ $(REMINDSRCS) rem2ps.c json.c 79 | 80 | # The next targets are not very useful to you. I use them to build 81 | # distributions, etc. 82 | 83 | # Build a tar file based on all files checked into git. 84 | distro: 85 | cd .. && git archive --worktree-attributes --format=tar --prefix=remind-$(VERSION)/ HEAD > src/remind-$(VERSION).tar 86 | gzip -f -v -9 remind-$(VERSION).tar 87 | gpg --detach-sign -u dianne@skoll.ca remind-$(VERSION).tar.gz 88 | 89 | beta-tgz: 90 | cd .. && git archive --worktree-attributes --format=tar --prefix=remind-$(VERSION)-BETA-$(BETA)/ HEAD > src/remind-$(VERSION)-BETA-$(BETA).tar 91 | gzip -f -v -9 remind-$(VERSION)-BETA-$(BETA).tar 92 | gpg --detach-sign -u dianne@skoll.ca remind-$(VERSION)-BETA-$(BETA).tar.gz 93 | 94 | #---------------- Stuff after this added by "make depend" ----------------- 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/compare-language-mods.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use warnings; 4 | 5 | my $language_map = { 6 | en => 'ENGLISH', 7 | de => 'GERMAN', 8 | nl => 'DUTCH', 9 | fi => 'FINNISH', 10 | fr => 'FRENCH', 11 | 'no' => 'NORWEGIAN', 12 | da => 'DANISH', 13 | pl => 'POLISH', 14 | is => 'ICELANDIC', 15 | pt => 'BRAZPORT', 16 | it => 'ITALIAN', 17 | ro => 'ROMANIAN', 18 | es => 'SPANISH', 19 | }; 20 | 21 | if (!$ARGV[0]) { 22 | print STDERR "Usage: $0 lang_code\n"; 23 | exit(1); 24 | } 25 | 26 | my $lang = $ARGV[0]; 27 | if (!exists($language_map->{$lang})) { 28 | print STDERR "$lang is not a valid language.\n"; 29 | exit(1); 30 | } 31 | 32 | my $flag = $language_map->{$lang}; 33 | print STDERR "Testing for: $lang - $flag.\n"; 34 | my_sys("make clean > /dev/null 2>&1") && die("make clean failed"); 35 | my_sys("make -j6 all LANGDEF=-DLANG=$flag > /dev/null 2>&1") && die("make all failed"); 36 | my_sys("./remind -q -r ../tests/tstlang.rem 2022-03-23 11:44 > test-$lang-compiled.out 2>&1"); 37 | 38 | my_sys("make clean > /dev/null 2>&1") && die("make clean failed"); 39 | my_sys("make -j6 all > /dev/null 2>&1") && die("make all failed"); 40 | my_sys("./remind -q -r -ii=\\\"../include/lang/$lang.rem\\\" ../tests/tstlang.rem 2022-03-23 11:44 > test-$lang-runtime.out 2>&1"); 41 | 42 | my $rc = my_sys("cmp test-$lang-compiled.out test-$lang-runtime.out > /dev/null 2>&1"); 43 | if ($rc == 0) { 44 | print STDERR "Congrats! Compiled and runtime language output matches for $lang.\n"; 45 | } else { 46 | print STDERR "Whoops. Compiled and runtime language output differs for $lang.\n" 47 | } 48 | exit(0); 49 | 50 | sub my_sys 51 | { 52 | #print STDERR "Running: " . join(' ', @_) . "\n"; 53 | return system(@_); 54 | } 55 | -------------------------------------------------------------------------------- /src/config.h.in: -------------------------------------------------------------------------------- 1 | /* Define if utime(file, NULL) sets file's timestamp to the present. */ 2 | #undef HAVE_UTIME_NULL 3 | 4 | /* Define if you can safely include both and . */ 5 | #undef TIME_WITH_SYS_TIME 6 | 7 | /* Define if your declares struct tm. */ 8 | #undef TM_IN_SYS_TIME 9 | 10 | /* Define if you have the header file. */ 11 | #undef HAVE_SYS_FILE_H 12 | 13 | /* Define if you have the header file. */ 14 | #undef HAVE_SYS_TYPES_H 15 | 16 | /* Define if you have the header file */ 17 | #undef HAVE_GLOB_H 18 | 19 | #undef HAVE_WCTYPE_H 20 | 21 | #undef HAVE_LOCALE_H 22 | 23 | #undef HAVE_LANGINFO_H 24 | 25 | #undef HAVE_GLOB 26 | 27 | #undef HAVE_SETENV 28 | 29 | #undef HAVE_INITGROUPS 30 | 31 | #undef HAVE_UNSETENV 32 | 33 | #undef HAVE_MBSTOWCS 34 | 35 | #undef HAVE_SETLOCALE 36 | 37 | /* The number of bytes in a unsigned int. */ 38 | #undef SIZEOF_UNSIGNED_INT 39 | 40 | /* The number of bytes in a unsigned long. */ 41 | #undef SIZEOF_UNSIGNED_LONG 42 | 43 | #include "custom.h" 44 | -------------------------------------------------------------------------------- /src/dynbuf.c: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* DYNBUF.C */ 4 | /* */ 5 | /* Implementation of functions for manipulating dynamic */ 6 | /* buffers. */ 7 | /* */ 8 | /* This file is part of REMIND. */ 9 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 10 | /* */ 11 | /***************************************************************/ 12 | 13 | #include "config.h" 14 | #include "dynbuf.h" 15 | #include "err.h" 16 | #include 17 | #include 18 | 19 | /********************************************************************** 20 | %FUNCTION: DBufMakeRoom 21 | %ARGUMENTS: 22 | dbuf -- pointer to a dynamic buffer 23 | n -- size to expand to 24 | %RETURNS: 25 | OK if all went well; E_NO_MEM if out of memory 26 | %DESCRIPTION: 27 | Doubles the size of dynamic buffer until it has room for at least 28 | 'n' characters, not including trailing '\0' 29 | **********************************************************************/ 30 | static int DBufMakeRoom(DynamicBuffer *dbuf, size_t n) 31 | { 32 | /* Double size until it's greater than n (strictly > to leave room 33 | for trailing '\0' */ 34 | size_t size = dbuf->allocatedLen; 35 | char *buf; 36 | 37 | if (size > n) return OK; 38 | 39 | while (size <= n) { 40 | size *= 2; 41 | } 42 | 43 | /* Allocate memory */ 44 | buf = malloc(size); 45 | if (!buf) return E_NO_MEM; 46 | 47 | /* Copy contents */ 48 | strcpy(buf, dbuf->buffer); 49 | 50 | /* Free contents if necessary */ 51 | if (dbuf->buffer != dbuf->staticBuf) free(dbuf->buffer); 52 | dbuf->buffer = buf; 53 | dbuf->allocatedLen = size; 54 | return OK; 55 | } 56 | 57 | /********************************************************************** 58 | %FUNCTION: DBufInit 59 | %ARGUMENTS: 60 | dbuf -- pointer to a dynamic buffer 61 | %RETURNS: 62 | Nothing 63 | %DESCRIPTION: 64 | Initializes a dynamic buffer 65 | **********************************************************************/ 66 | void DBufInit(DynamicBuffer *dbuf) 67 | { 68 | dbuf->buffer = dbuf->staticBuf; 69 | dbuf->len = 0; 70 | dbuf->allocatedLen = DBUF_STATIC_SIZE; 71 | dbuf->buffer[0] = 0; 72 | } 73 | 74 | /********************************************************************** 75 | %FUNCTION: DBufPutcFN 76 | %ARGUMENTS: 77 | dbuf -- pointer to a dynamic buffer 78 | c -- character to append to buffer 79 | %RETURNS: 80 | OK if all went well; E_NO_MEM if out of memory 81 | %DESCRIPTION: 82 | Appends a character to the buffer. 83 | **********************************************************************/ 84 | int DBufPutcFN(DynamicBuffer *dbuf, char c) 85 | { 86 | if (dbuf->allocatedLen == dbuf->len+1) { 87 | if (DBufMakeRoom(dbuf, dbuf->len+1) != OK) return E_NO_MEM; 88 | } 89 | dbuf->buffer[dbuf->len++] = c; 90 | dbuf->buffer[dbuf->len] = 0; 91 | return OK; 92 | } 93 | 94 | /********************************************************************** 95 | %FUNCTION: DBufPuts 96 | %ARGUMENTS: 97 | dbuf -- pointer to a dynamic buffer 98 | str -- string to append to buffer 99 | %RETURNS: 100 | OK if all went well; E_NO_MEM if out of memory 101 | %DESCRIPTION: 102 | Appends a string to the buffer. 103 | **********************************************************************/ 104 | int DBufPuts(DynamicBuffer *dbuf, char const *str) 105 | { 106 | int l = strlen(str); 107 | if (!l) return OK; 108 | 109 | if (DBufMakeRoom(dbuf, dbuf->len+l) != OK) return E_NO_MEM; 110 | strcpy((dbuf->buffer+dbuf->len), str); 111 | dbuf->len += l; 112 | return OK; 113 | } 114 | 115 | /********************************************************************** 116 | %FUNCTION: DBufFree 117 | %ARGUMENTS: 118 | dbuf -- pointer to a dynamic buffer 119 | %RETURNS: 120 | Nothing 121 | %DESCRIPTION: 122 | Frees and reinitializes a dynamic buffer 123 | **********************************************************************/ 124 | void DBufFree(DynamicBuffer *dbuf) 125 | { 126 | if (dbuf->buffer != dbuf->staticBuf) free(dbuf->buffer); 127 | DBufInit(dbuf); 128 | } 129 | 130 | /********************************************************************** 131 | %FUNCTION: DBufGets 132 | %ARGUMENTS: 133 | dbuf -- pointer to a dynamic buffer 134 | fp -- file to read from 135 | %RETURNS: 136 | OK or E_NO_MEM 137 | %DESCRIPTION: 138 | Reads an entire line from a file and appends to dbuf. Does not include 139 | trailing newline. 140 | **********************************************************************/ 141 | int DBufGets(DynamicBuffer *dbuf, FILE *fp) 142 | { 143 | char tmp[256]; /* Safe to hard-code */ 144 | int busy = 1; 145 | int l; 146 | 147 | DBufFree(dbuf); 148 | 149 | /* Try reading the first few bytes right into the buffer -- 150 | we can usually save some unnecessary copying */ 151 | 152 | *(dbuf->buffer) = 0; 153 | if (fgets(dbuf->buffer, dbuf->allocatedLen, fp) == NULL) { 154 | return OK; 155 | } 156 | if (!*(dbuf->buffer)) return OK; 157 | dbuf->len = strlen(dbuf->buffer); 158 | l = dbuf->len - 1; 159 | if (dbuf->buffer[l] == '\n') { 160 | dbuf->buffer[l] = 0; 161 | dbuf->len = l; 162 | return OK; 163 | } 164 | 165 | while(busy) { 166 | *tmp = 0; 167 | if (fgets(tmp, 256, fp) == NULL) return OK; 168 | if (!*tmp) return OK; 169 | l = strlen(tmp) - 1; 170 | if (tmp[l] == '\n') { 171 | tmp[l] = 0; 172 | busy = 0; 173 | } 174 | if (DBufPuts(dbuf, tmp) != OK) return E_NO_MEM; 175 | } 176 | return OK; 177 | } 178 | 179 | -------------------------------------------------------------------------------- /src/dynbuf.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* DYNBUF.H */ 4 | /* */ 5 | /* Declaration of functions for manipulating dynamic buffers */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 9 | /* */ 10 | /***************************************************************/ 11 | 12 | #ifndef DYNBUF_H 13 | #define DYNBUF_H 14 | 15 | #include /* For FILE */ 16 | 17 | #define DBUF_STATIC_SIZE 128 18 | typedef struct { 19 | char *buffer; 20 | size_t len; 21 | size_t allocatedLen; 22 | char staticBuf[DBUF_STATIC_SIZE]; 23 | } DynamicBuffer; 24 | 25 | void DBufInit(DynamicBuffer *dbuf); 26 | int DBufPutcFN(DynamicBuffer *dbuf, char c); 27 | int DBufPuts(DynamicBuffer *dbuf, char const *str); 28 | void DBufFree(DynamicBuffer *dbuf); 29 | int DBufGets(DynamicBuffer *dbuf, FILE *fp); 30 | 31 | #define DBufValue(bufPtr) ((bufPtr)->buffer) 32 | #define DBufLen(bufPtr) ((bufPtr)->len) 33 | 34 | #define DBufPutc(dbuf, c) ( (dbuf)->allocatedLen < (dbuf)->len+1 ) ? (dbuf)->buffer[(dbuf)->len++] = c, (dbuf)->buffer[(dbuf)->len] = 0, OK : DBufPutcFN((dbuf), c) 35 | 36 | #endif /* DYNBUF_H */ 37 | -------------------------------------------------------------------------------- /src/err.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* ERR.H */ 4 | /* */ 5 | /* Error definitions. */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 9 | /* */ 10 | /***************************************************************/ 11 | 12 | /* Note that not all of the "errors" are really errors - some are just 13 | messages for information purposes. Constants beginning with M_ should 14 | never be returned as error indicators - they should only be used to 15 | index the ErrMsg array. */ 16 | 17 | #define OK 0 18 | #define E_MISS_END 1 19 | #define E_MISS_QUOTE 2 20 | #define E_OP_STK_OVER 3 21 | #define E_VA_STK_OVER 4 22 | #define E_MISS_RIGHT_PAREN 5 23 | #define E_UNDEF_FUNC 6 24 | #define E_ILLEGAL_CHAR 7 25 | #define E_EXPECTING_BINOP 8 26 | #define E_NO_MEM 9 27 | #define E_BAD_NUMBER 10 28 | #define E_OP_STK_UNDER 11 29 | #define E_VA_STK_UNDER 12 30 | #define E_CANT_COERCE 13 31 | #define E_BAD_TYPE 14 32 | #define E_DATE_OVER 15 33 | #define E_STACK_ERR 16 34 | #define E_DIV_ZERO 17 35 | #define E_NOSUCH_VAR 18 36 | #define E_EOLN 19 37 | #define E_EOF 20 38 | #define E_IO_ERR 21 39 | #define E_LINE_2_LONG 22 40 | #define E_SWERR 23 41 | #define E_BAD_DATE 24 42 | #define E_2FEW_ARGS 25 43 | #define E_2MANY_ARGS 26 44 | #define E_BAD_TIME 27 45 | #define E_2HIGH 28 46 | #define E_2LOW 29 47 | #define E_CANT_OPEN 30 48 | #define E_NESTED_INCLUDE 31 49 | #define E_PARSE_ERR 32 50 | #define E_CANT_TRIG 33 51 | #define E_NESTED_IF 34 52 | #define E_ELSE_NO_IF 35 53 | #define E_ENDIF_NO_IF 36 54 | #define E_2MANY_LOCALOMIT 37 55 | #define E_EXTRANEOUS_TOKEN 38 56 | #define E_POP_NO_PUSH 39 57 | #define E_RUN_DISABLED 40 58 | #define E_DOMAIN_ERR 41 59 | #define E_BAD_ID 42 60 | #define E_RECURSIVE 43 61 | #define E_PARSE_AS_REM 44 /* Not really an error - just returned by 62 | DoOmit to indicate line should be executed 63 | as a REM statement, also. */ 64 | #define E_CANT_MODIFY 45 65 | #define E_MKTIME_PROBLEM 46 66 | #define E_REDEF_FUNC 47 67 | #define E_CANTNEST_FDEF 48 68 | #define E_REP_FULSPEC 49 69 | #define E_YR_TWICE 50 70 | #define E_MON_TWICE 51 71 | #define E_DAY_TWICE 52 72 | #define E_UNKNOWN_TOKEN 53 73 | #define E_SPEC_MON_DAY 54 74 | #define E_2MANY_PART 55 75 | #define E_2MANY_FULL 56 76 | #define E_PUSH_NOPOP 57 77 | #define E_ERR_READING 58 78 | #define E_EXPECTING_EOL 59 79 | #define E_BAD_HEBDATE 60 80 | #define E_IIF_ODD 61 81 | #define E_MISS_ENDIF 62 82 | #define E_EXPECT_COMMA 63 83 | #define E_WD_TWICE 64 84 | #define E_SKIP_ERR 65 85 | #define E_CANT_NEST_RTYPE 66 86 | #define E_REP_TWICE 67 87 | #define E_DELTA_TWICE 68 88 | #define E_BACK_TWICE 69 89 | #define E_ONCE_TWICE 70 90 | #define E_EXPECT_TIME 71 91 | #define E_UNTIL_TWICE 72 92 | #define E_INCOMPLETE 73 93 | #define E_SCAN_TWICE 74 94 | #define E_VAR 75 95 | #define E_VAL 76 96 | #define E_UNDEF 77 97 | #define E_ENTER_FUN 78 98 | #define E_LEAVE_FUN 79 99 | #define E_EXPIRED 80 100 | #define E_CANTFORK 81 101 | #define E_CANTACCESS 82 102 | #define M_BAD_SYS_DATE 83 103 | #define M_BAD_DB_FLAG 84 104 | #define M_BAD_OPTION 85 105 | #define M_BAD_USER 86 106 | #define M_NO_CHG_GID 87 107 | #define M_NO_CHG_UID 88 108 | #define M_NOMEM_ENV 89 109 | #define E_MISS_EQ 90 110 | #define E_MISS_VAR 91 111 | #define E_MISS_EXPR 92 112 | #define M_CANTSET_ACCESS 93 113 | #define M_I_OPTION 94 114 | #define E_NOREMINDERS 95 115 | #define M_QUEUED 96 116 | #define E_EXPECTING_NUMBER 97 117 | #define M_BAD_WARN_FUNC 98 118 | #define E_CANT_CONVERT_TZ 99 119 | #define E_NO_MATCHING_REMS 100 120 | #define E_STRING_TOO_LONG 101 121 | #define E_TIME_TWICE 102 122 | #define E_DURATION_NO_AT 103 123 | #ifdef MK_GLOBALS 124 | #undef EXTERN 125 | #define EXTERN 126 | #else 127 | #undef EXTERN 128 | #define EXTERN extern 129 | #endif 130 | 131 | #ifndef L_ERR_OVERRIDE 132 | EXTERN char *ErrMsg[] 133 | 134 | #ifdef MK_GLOBALS 135 | = { 136 | "Ok", 137 | "Missing ']'", 138 | "Missing quote", 139 | "Expression too complex - too many operators", 140 | "Expression too complex - too many operands", 141 | "Missing ')'", 142 | "Undefined function", 143 | "Illegal character", 144 | "Expecting binary operator", 145 | "Out of memory", 146 | "Ill-formed number", 147 | "Op stack underflow - internal error", 148 | "Va stack underflow - internal error", 149 | "Can't coerce", 150 | "Type mismatch", 151 | "Date overflow", 152 | "Stack error - internal error", 153 | "Division by zero", 154 | "Undefined variable", 155 | "Unexpected end of line", 156 | "Unexpected end of file", 157 | "I/O error", 158 | "Line too long", 159 | "Internal error", 160 | "Bad date specification", 161 | "Not enough arguments", 162 | "Too many arguments", 163 | "Ill-formed time", 164 | "Number too high", 165 | "Number too low", 166 | "Can't open file", 167 | "INCLUDE nested too deeply", 168 | "Parse error", 169 | "Can't compute trigger", 170 | "Too many nested IFs", 171 | "ELSE with no matching IF", 172 | "ENDIF with no matching IF", 173 | "Can't OMIT every weekday", 174 | "Extraneous token(s) on line", 175 | "POP-OMIT-CONTEXT without matching PUSH-OMIT-CONTEXT", 176 | "RUN disabled", 177 | "Domain error", 178 | "Invalid identifier", 179 | "Recursive function call detected", 180 | "", 181 | "Cannot modify system variable", 182 | "C library function can't represent date/time", 183 | "Attempt to redefine built-in function", 184 | "Can't nest function definition in expression", 185 | "Must fully specify date to use repeat factor", 186 | "Year specified twice", 187 | "Month specified twice", 188 | "Day specified twice", 189 | "Unknown token", 190 | "Must specify month and day in OMIT command", 191 | "Too many partial OMITs", 192 | "Too many full OMITs", 193 | "Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT", 194 | "Error reading", 195 | "Expecting end-of-line", 196 | "Invalid Hebrew date", 197 | "IIF needs odd number of arguments", 198 | "Warning: Missing ENDIF", 199 | "Expecting comma", 200 | "Weekday specified twice", 201 | "Only use one of BEFORE, AFTER or SKIP", 202 | "Can't nest MSG, MSF, RUN, etc. in expression", 203 | "Repeat value specified twice", 204 | "Delta value specified twice", 205 | "Back value specified twice", 206 | "ONCE keyword used twice. (Hah.)", 207 | "Expecting time after AT", 208 | "THROUGH/UNTIL keyword used twice", 209 | "Incomplete date specification", 210 | "FROM/SCANFROM keyword used twice", 211 | "Variable", 212 | "Value", 213 | "*UNDEFINED*", 214 | "Entering UserFN", 215 | "Leaving UserFN", 216 | "Expired", 217 | "fork() failed - can't do queued reminders", 218 | "Can't access file", 219 | "Illegal system date: Year is less than %d\n", 220 | "Unknown debug flag '%c'\n", 221 | "Unknown option '%c'\n", 222 | "Unknown user '%s'\n", 223 | "Could not change gid to %d\n", 224 | "Could not change uid to %d\n", 225 | "Out of memory for environment\n", 226 | "Missing '=' sign", 227 | "Missing variable name", 228 | "Missing expression", 229 | "Can't reset access date of %s\n", 230 | "Remind: '-i' option: %s\n", 231 | "No reminders.", 232 | "%d reminder(s) queued for later today.\n", 233 | "Expecting number", 234 | "Bad function in WARN clause", 235 | "Can't convert between time zones", 236 | "No files matching *.rem", 237 | "String too long", 238 | "Time specified twice", 239 | "Cannot specify DURATION without specifying AT" 240 | } 241 | #endif /* MK_GLOBALS */ 242 | ; 243 | #endif /* L_ERR_OVERRIDE */ 244 | -------------------------------------------------------------------------------- /src/expr.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* EXPR.H */ 4 | /* */ 5 | /* Contains a few definitions used by expression evaluator. */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 9 | /* */ 10 | /***************************************************************/ 11 | 12 | /* Define the types of values */ 13 | #define ERR_TYPE 0 14 | #define INT_TYPE 1 15 | #define TIME_TYPE 2 16 | #define DATE_TYPE 3 17 | #define STR_TYPE 4 18 | #define DATETIME_TYPE 5 19 | #define SPECIAL_TYPE 6 /* Only for system variables */ 20 | 21 | /* Define stuff for parsing expressions */ 22 | #define BEG_OF_EXPR '[' 23 | #define END_OF_EXPR ']' 24 | #define COMMA ',' 25 | 26 | #define UN_OP 0 /* Unary operator */ 27 | #define BIN_OP 1 /* Binary Operator */ 28 | #define FUNC 2 /* Function */ 29 | 30 | /* Make the pushing and popping of values and operators in-line code 31 | for speed. BEWARE: These macros invoke return if an error happens ! */ 32 | 33 | #define PushOpStack(op) \ 34 | if (OpStackPtr >= OP_STACK_SIZE) \ 35 | return E_OP_STK_OVER; \ 36 | else \ 37 | OpStack[OpStackPtr++] = (op) 38 | 39 | #define PopOpStack(op) \ 40 | if (OpStackPtr <= 0) \ 41 | return E_OP_STK_UNDER; \ 42 | else \ 43 | (op) = OpStack[--OpStackPtr] 44 | 45 | #define PushValStack(val) \ 46 | if (ValStackPtr >= VAL_STACK_SIZE) \ 47 | return E_VA_STK_OVER; \ 48 | else \ 49 | ValStack[ValStackPtr++] = (val) 50 | 51 | #define PopValStack(val) \ 52 | if (ValStackPtr <= 0) \ 53 | return E_VA_STK_UNDER; \ 54 | else \ 55 | (val) = ValStack[--ValStackPtr] 56 | 57 | /* These functions are in utils.c and are used to detect overflow 58 | in various arithmetic operators. They have to be in separate 59 | functions with extern linkage to defeat compiler optimizations 60 | that would otherwise break the overflow checks. */ 61 | extern int _private_mul_overflow(int a, int b); 62 | extern int _private_add_overflow(int a, int b); 63 | extern int _private_sub_overflow(int a, int b); 64 | 65 | -------------------------------------------------------------------------------- /src/globals.c: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* GLOBALS.C */ 4 | /* */ 5 | /* This file simply instantiates all of the global variables. */ 6 | /* */ 7 | /* It does this by #defining MK_GLOBALS and #including */ 8 | /* globals.h and err.h */ 9 | /* */ 10 | /* This file is part of REMIND. */ 11 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 12 | /* */ 13 | /***************************************************************/ 14 | 15 | #include "config.h" 16 | 17 | #include /* For definition of FILE - sigh! */ 18 | #include "types.h" 19 | #include "custom.h" 20 | #include "lang.h" 21 | #define MK_GLOBALS 1 22 | #include "globals.h" 23 | #include "err.h" 24 | -------------------------------------------------------------------------------- /src/globals.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* GLOBALS.H */ 4 | /* */ 5 | /* This function contains declarations of global variables. */ 6 | /* They are instantiated in main.c by defining */ 7 | /* MK_GLOBALS. Also contains useful macro definitions. */ 8 | /* */ 9 | /* This file is part of REMIND. */ 10 | /* Copyright (C) 1992-2021 by Dianne Skoll */ 11 | /* */ 12 | /***************************************************************/ 13 | 14 | 15 | #ifdef MK_GLOBALS 16 | #undef EXTERN 17 | #define EXTERN 18 | #define INIT(var, val) var = val 19 | #else 20 | #undef EXTERN 21 | #define EXTERN extern 22 | #define INIT(var, val) var 23 | #endif 24 | 25 | #ifdef HAVE_SYS_TYPES_H 26 | #include 27 | #endif 28 | EXTERN FILE *ErrFp; 29 | 30 | #include "dynbuf.h" 31 | #include "lang.h" 32 | 33 | #define MAX_TRUSTED_USERS 20 34 | 35 | #define MINUTES_PER_DAY 1440 36 | 37 | #define DaysInYear(y) (((y) % 4) ? 365 : ((!((y) % 100) && ((y) % 400)) ? 365 : 366 )) 38 | #define IsLeapYear(y) (((y) % 4) ? 0 : ((!((y) % 100) && ((y) % 400)) ? 0 : 1 )) 39 | #define DaysInMonth(m, y) ((m) != 1 ? MonthDays[m] : 28 + IsLeapYear(y)) 40 | 41 | #define DestroyValue(x) (void) (((x).type == STR_TYPE && (x).v.str) ? (free((x).v.str),(x).type = ERR_TYPE) : 0) 42 | 43 | EXTERN int JulianToday; 44 | EXTERN int RealToday; 45 | EXTERN int CurDay; 46 | EXTERN int CurMon; 47 | EXTERN int CurYear; 48 | EXTERN int LineNo; 49 | EXTERN int FreshLine; 50 | EXTERN uid_t TrustedUsers[MAX_TRUSTED_USERS]; 51 | 52 | EXTERN INIT( int NumTrustedUsers, 0); 53 | EXTERN INIT( char const *MsgCommand, NULL); 54 | EXTERN INIT( int ShowAllErrors, 0); 55 | EXTERN INIT( int DebugFlag, 0); 56 | EXTERN INIT( int DoCalendar, 0); 57 | EXTERN INIT( int DoSimpleCalendar, 0); 58 | EXTERN INIT( int DoSimpleCalDelta, 0); 59 | EXTERN INIT( int DoPrefixLineNo, 0); 60 | EXTERN INIT( int MondayFirst, 0); 61 | EXTERN INIT( int Iterations, 1); 62 | EXTERN INIT( int PsCal, 0); 63 | EXTERN INIT( int CalWidth, -1); 64 | EXTERN INIT( int CalWeeks, 0); 65 | EXTERN INIT( int CalMonths, 0); 66 | EXTERN INIT( int Hush, 0); 67 | EXTERN INIT( int NextMode, 0); 68 | EXTERN INIT( int InfiniteDelta, 0); 69 | EXTERN INIT( int DefaultTDelta, 0); 70 | EXTERN INIT( int DeltaOffset, 0); 71 | EXTERN INIT( int RunDisabled, 0); 72 | EXTERN INIT( int IgnoreOnce, 0); 73 | EXTERN INIT( int SortByTime, 0); 74 | EXTERN INIT( int SortByDate, 0); 75 | EXTERN INIT( int SortByPrio, 0); 76 | EXTERN INIT( int UntimedBeforeTimed, 0); 77 | EXTERN INIT( int DefaultPrio, NO_PRIORITY); 78 | EXTERN INIT( long SysTime, -1L); 79 | 80 | EXTERN char const *InitialFile; 81 | EXTERN int FileAccessDate; 82 | 83 | EXTERN INIT( int DontSuppressQuoteMarkers, 0); 84 | EXTERN INIT( int DontFork, 0); 85 | EXTERN INIT( int DontQueue, 0); 86 | EXTERN INIT( int NumQueued, 0); 87 | EXTERN INIT( int DontIssueAts, 0); 88 | EXTERN INIT( int Daemon, 0); 89 | EXTERN INIT( char DateSep, DATESEP); 90 | EXTERN INIT( char TimeSep, TIMESEP); 91 | EXTERN INIT( char DateTimeSep, DATETIMESEP); 92 | EXTERN INIT( int DefaultColorR, -1); 93 | EXTERN INIT( int DefaultColorB, -1); 94 | EXTERN INIT( int DefaultColorG, -1); 95 | EXTERN INIT( int SynthesizeTags, 0); 96 | EXTERN INIT( int ScFormat, SC_AMPM); 97 | EXTERN INIT( int MaxSatIter, 1000); 98 | EXTERN INIT( int MaxStringLen, MAX_STR_LEN); 99 | EXTERN INIT( char *FileName, NULL); 100 | EXTERN INIT( int UseStdin, 0); 101 | EXTERN INIT( int PurgeMode, 0); 102 | EXTERN INIT( int PurgeIncludeDepth, 0); 103 | EXTERN INIT( FILE *PurgeFP, NULL); 104 | EXTERN INIT( int NumIfs, 0); 105 | EXTERN INIT( unsigned int IfFlags, 0); 106 | EXTERN INIT( int LastTrigValid, 0); 107 | EXTERN Trigger LastTrigger; 108 | EXTERN TimeTrig LastTimeTrig; 109 | EXTERN INIT( int LastTriggerDate, 0); 110 | EXTERN INIT( int LastTriggerTime, 0); 111 | EXTERN INIT( int ShouldCache, 0); 112 | EXTERN char const *CurLine; 113 | EXTERN INIT( int NumTriggered, 0); 114 | EXTERN int ArgC; 115 | EXTERN char const **ArgV; 116 | EXTERN INIT( int CalLines, CAL_LINES); 117 | EXTERN INIT( int CalPad, 1); 118 | EXTERN INIT( int UseVTChars, 0); 119 | EXTERN INIT( int UseUTF8Chars, 0); 120 | EXTERN INIT( int UseVTColors, 0); 121 | EXTERN INIT( int Use256Colors, 0); 122 | EXTERN INIT( int UseTrueColors, 0); 123 | EXTERN INIT( int TerminalBackground, TERMINAL_BACKGROUND_UNKNOWN); 124 | 125 | /* Latitude and longitude */ 126 | EXTERN INIT( int LatDeg, 0); 127 | EXTERN INIT( int LatMin, 0); 128 | EXTERN INIT( int LatSec, 0); 129 | EXTERN INIT( int LongDeg, 0); 130 | EXTERN INIT( int LongMin, 0); 131 | EXTERN INIT( int LongSec, 0); 132 | EXTERN INIT( double Longitude, DEFAULT_LONGITUDE); 133 | EXTERN INIT( double Latitude, DEFAULT_LATITUDE); 134 | 135 | EXTERN INIT( char *Location, LOCATION); 136 | 137 | /* UTC calculation stuff */ 138 | EXTERN INIT( int MinsFromUTC, 0); 139 | EXTERN INIT( int CalculateUTC, 1); 140 | EXTERN INIT( int FoldYear, 0); 141 | 142 | /* Parameters for formatting MSGF reminders */ 143 | EXTERN INIT( int FormWidth, 72); 144 | EXTERN INIT( int FirstIndent, 0); 145 | EXTERN INIT( int SubsIndent, 0); 146 | EXTERN INIT( char *EndSent, ".?!"); 147 | EXTERN INIT( char *EndSentIg, "\"')]}>"); 148 | 149 | EXTERN DynamicBuffer Banner; 150 | EXTERN DynamicBuffer LineBuffer; 151 | EXTERN DynamicBuffer ExprBuf; 152 | /* List of months */ 153 | EXTERN char *EnglishMonthName[] 154 | #ifdef MK_GLOBALS 155 | = {"January", "February", "March", "April", "May", "June", 156 | "July", "August", "September", "October", "November", "December"} 157 | #endif 158 | ; 159 | 160 | #if LANG == ENGLISH 161 | #define MonthName EnglishMonthName 162 | #else 163 | EXTERN char *MonthName[] 164 | #ifdef MK_GLOBALS 165 | = {L_JAN, L_FEB, L_MAR, L_APR, L_MAY, L_JUN, 166 | L_JUL, L_AUG, L_SEP, L_OCT, L_NOV, L_DEC} 167 | #endif 168 | ; 169 | #endif 170 | 171 | EXTERN char *DynamicMonthName[] 172 | #ifdef MK_GLOBALS 173 | #if LANG == ENGLISH 174 | = {"January", "February", "March", "April", "May", "June", 175 | "July", "August", "September", "October", "November", "December"} 176 | #else 177 | = {L_JAN, L_FEB, L_MAR, L_APR, L_MAY, L_JUN, 178 | L_JUL, L_AUG, L_SEP, L_OCT, L_NOV, L_DEC} 179 | #endif 180 | #endif 181 | ; 182 | EXTERN char *EnglishDayName[] 183 | #ifdef MK_GLOBALS 184 | = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", 185 | "Saturday", "Sunday"} 186 | #endif 187 | ; 188 | 189 | #if LANG == ENGLISH 190 | #define DayName EnglishDayName 191 | #else 192 | EXTERN char *DayName[] 193 | #ifdef MK_GLOBALS 194 | = {L_MONDAY, L_TUESDAY, L_WEDNESDAY, L_THURSDAY, L_FRIDAY, 195 | L_SATURDAY, L_SUNDAY} 196 | #endif 197 | ; 198 | #endif 199 | 200 | EXTERN char *DynamicDayName [] 201 | #ifdef MK_GLOBALS 202 | #if LANG == ENGLISH 203 | = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", 204 | "Saturday", "Sunday"} 205 | #else 206 | = {L_MONDAY, L_TUESDAY, L_WEDNESDAY, L_THURSDAY, L_FRIDAY, 207 | L_SATURDAY, L_SUNDAY} 208 | #endif 209 | #endif 210 | ; 211 | 212 | EXTERN int MonthDays[] 213 | #ifdef MK_GLOBALS 214 | = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 215 | #endif 216 | ; 217 | 218 | /* The first day of each month expressed as number of days after Jan 1. 219 | Second row is for leap years. */ 220 | 221 | EXTERN int MonthIndex[2][12] 222 | #ifdef MK_GLOBALS 223 | = { 224 | { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, 225 | { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 } 226 | } 227 | #endif 228 | ; 229 | 230 | EXTERN char *DynamicAgo 231 | #ifdef MK_GLOBALS 232 | = L_AGO 233 | #endif 234 | ; 235 | EXTERN char *DynamicAm 236 | #ifdef MK_GLOBALS 237 | = L_AM 238 | #endif 239 | ; 240 | EXTERN char *DynamicAnd 241 | #ifdef MK_GLOBALS 242 | = L_AND 243 | #endif 244 | ; 245 | EXTERN char *DynamicAt 246 | #ifdef MK_GLOBALS 247 | = L_AT 248 | #endif 249 | ; 250 | EXTERN char *DynamicFromnow 251 | #ifdef MK_GLOBALS 252 | = L_FROMNOW 253 | #endif 254 | ; 255 | EXTERN char *DynamicHour 256 | #ifdef MK_GLOBALS 257 | = L_HOUR 258 | #endif 259 | ; 260 | EXTERN char *DynamicHplu 261 | #ifdef MK_GLOBALS 262 | = L_HPLU 263 | #endif 264 | ; 265 | EXTERN char *DynamicIs 266 | #ifdef MK_GLOBALS 267 | = L_IS 268 | #endif 269 | ; 270 | EXTERN char *DynamicMinute 271 | #ifdef MK_GLOBALS 272 | = L_MINUTE 273 | #endif 274 | ; 275 | EXTERN char *DynamicMplu 276 | #ifdef MK_GLOBALS 277 | = L_MPLU 278 | #endif 279 | ; 280 | EXTERN char *DynamicNow 281 | #ifdef MK_GLOBALS 282 | = L_NOW 283 | #endif 284 | ; 285 | EXTERN char *DynamicOn 286 | #ifdef MK_GLOBALS 287 | = L_ON 288 | #endif 289 | ; 290 | EXTERN char *DynamicPm 291 | #ifdef MK_GLOBALS 292 | = L_PM 293 | #endif 294 | ; 295 | EXTERN char *DynamicToday 296 | #ifdef MK_GLOBALS 297 | = L_TODAY 298 | #endif 299 | ; 300 | EXTERN char *DynamicTomorrow 301 | #ifdef MK_GLOBALS 302 | = L_TOMORROW 303 | #endif 304 | ; 305 | EXTERN char *DynamicWas 306 | #ifdef MK_GLOBALS 307 | = L_WAS 308 | #endif 309 | ; 310 | 311 | #define XSTR(x) #x 312 | #define STRSYSDIR(x) XSTR(x) 313 | 314 | EXTERN char *SysDir 315 | #ifdef MK_GLOBALS 316 | = STRSYSDIR(SYSDIR) 317 | #endif 318 | ; 319 | 320 | EXTERN int SuppressLRM 321 | #ifdef MK_GLOBALS 322 | = 0 323 | #endif 324 | ; 325 | -------------------------------------------------------------------------------- /src/json.h: -------------------------------------------------------------------------------- 1 | /* vim: set et ts=3 sw=3 sts=3 ft=c: 2 | * 3 | * Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved. 4 | * https://github.com/udp/json-parser 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef _JSON_H 31 | #define _JSON_H 32 | 33 | #ifndef json_char 34 | #define json_char char 35 | #endif 36 | 37 | #ifndef json_int_t 38 | #ifndef _MSC_VER 39 | #include 40 | #define json_int_t int64_t 41 | #else 42 | #define json_int_t __int64 43 | #endif 44 | #endif 45 | 46 | #include 47 | 48 | #ifdef __cplusplus 49 | 50 | #include 51 | 52 | extern "C" 53 | { 54 | 55 | #endif 56 | 57 | typedef struct 58 | { 59 | unsigned long max_memory; 60 | int settings; 61 | 62 | /* Custom allocator support (leave null to use malloc/free) 63 | */ 64 | 65 | void * (* mem_alloc) (size_t, int zero, void * user_data); 66 | void (* mem_free) (void *, void * user_data); 67 | 68 | void * user_data; /* will be passed to mem_alloc and mem_free */ 69 | 70 | size_t value_extra; /* how much extra space to allocate for values? */ 71 | 72 | } json_settings; 73 | 74 | #define json_enable_comments 0x01 75 | 76 | typedef enum 77 | { 78 | json_none, 79 | json_object, 80 | json_array, 81 | json_integer, 82 | json_double, 83 | json_string, 84 | json_boolean, 85 | json_null 86 | 87 | } json_type; 88 | 89 | extern const struct _json_value json_value_none; 90 | 91 | typedef struct _json_object_entry 92 | { 93 | json_char * name; 94 | unsigned int name_length; 95 | 96 | struct _json_value * value; 97 | 98 | } json_object_entry; 99 | 100 | typedef struct _json_value 101 | { 102 | struct _json_value * parent; 103 | 104 | json_type type; 105 | 106 | union 107 | { 108 | int boolean; 109 | json_int_t integer; 110 | double dbl; 111 | 112 | struct 113 | { 114 | unsigned int length; 115 | json_char * ptr; /* null terminated */ 116 | 117 | } string; 118 | 119 | struct 120 | { 121 | unsigned int length; 122 | 123 | json_object_entry * values; 124 | 125 | #if defined(__cplusplus) && __cplusplus >= 201103L 126 | decltype(values) begin () const 127 | { return values; 128 | } 129 | decltype(values) end () const 130 | { return values + length; 131 | } 132 | #endif 133 | 134 | } object; 135 | 136 | struct 137 | { 138 | unsigned int length; 139 | struct _json_value ** values; 140 | 141 | #if defined(__cplusplus) && __cplusplus >= 201103L 142 | decltype(values) begin () const 143 | { return values; 144 | } 145 | decltype(values) end () const 146 | { return values + length; 147 | } 148 | #endif 149 | 150 | } array; 151 | 152 | } u; 153 | 154 | union 155 | { 156 | struct _json_value * next_alloc; 157 | void * object_mem; 158 | 159 | } _reserved; 160 | 161 | #ifdef JSON_TRACK_SOURCE 162 | 163 | /* Location of the value in the source JSON 164 | */ 165 | unsigned int line, col; 166 | 167 | #endif 168 | 169 | 170 | /* Some C++ operator sugar */ 171 | 172 | #ifdef __cplusplus 173 | 174 | public: 175 | 176 | inline _json_value () 177 | { memset (this, 0, sizeof (_json_value)); 178 | } 179 | 180 | inline const struct _json_value &operator [] (int index) const 181 | { 182 | if (type != json_array || index < 0 183 | || ((unsigned int) index) >= u.array.length) 184 | { 185 | return json_value_none; 186 | } 187 | 188 | return *u.array.values [index]; 189 | } 190 | 191 | inline const struct _json_value &operator [] (const char * index) const 192 | { 193 | if (type != json_object) 194 | return json_value_none; 195 | 196 | for (unsigned int i = 0; i < u.object.length; ++ i) 197 | if (!strcmp (u.object.values [i].name, index)) 198 | return *u.object.values [i].value; 199 | 200 | return json_value_none; 201 | } 202 | 203 | inline operator const char * () const 204 | { 205 | switch (type) 206 | { 207 | case json_string: 208 | return u.string.ptr; 209 | 210 | default: 211 | return ""; 212 | }; 213 | } 214 | 215 | inline operator json_int_t () const 216 | { 217 | switch (type) 218 | { 219 | case json_integer: 220 | return u.integer; 221 | 222 | case json_double: 223 | return (json_int_t) u.dbl; 224 | 225 | default: 226 | return 0; 227 | }; 228 | } 229 | 230 | inline operator bool () const 231 | { 232 | if (type != json_boolean) 233 | return false; 234 | 235 | return u.boolean != 0; 236 | } 237 | 238 | inline operator double () const 239 | { 240 | switch (type) 241 | { 242 | case json_integer: 243 | return (double) u.integer; 244 | 245 | case json_double: 246 | return u.dbl; 247 | 248 | default: 249 | return 0; 250 | }; 251 | } 252 | 253 | #endif 254 | 255 | } json_value; 256 | 257 | json_value * json_parse (const json_char * json, 258 | size_t length); 259 | 260 | #define json_error_max 128 261 | json_value * json_parse_ex (json_settings * settings, 262 | const json_char * json, 263 | size_t length, 264 | char * error); 265 | 266 | void json_value_free (json_value *); 267 | 268 | 269 | /* Not usually necessary, unless you used a custom mem_alloc and now want to 270 | * use a custom mem_free. 271 | */ 272 | void json_value_free_ex (json_settings * settings, 273 | json_value *); 274 | 275 | 276 | #ifdef __cplusplus 277 | } /* extern "C" */ 278 | #endif 279 | 280 | #endif 281 | -------------------------------------------------------------------------------- /src/lang.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfskoll/remind/ef7742a3cccc49b490d46f3a6b738e5896a10d04/src/lang.h -------------------------------------------------------------------------------- /src/langs/danish.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* DANISH.H */ 4 | /* */ 5 | /* Support for the Danish language. */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* */ 9 | /* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */ 10 | /* This file is Copyright (C) 1993 by Mogens Lynnerup. */ 11 | /* */ 12 | /***************************************************************/ 13 | 14 | /* The very first define in a language support file must be L_LANGNAME: */ 15 | #define L_LANGNAME "Danish" 16 | 17 | /* Day names */ 18 | #define L_SUNDAY "Søndag" 19 | #define L_MONDAY "Mandag" 20 | #define L_TUESDAY "Tirsdag" 21 | #define L_WEDNESDAY "Onsdag" 22 | #define L_THURSDAY "Torsdag" 23 | #define L_FRIDAY "Fredag" 24 | #define L_SATURDAY "Lørdag" 25 | 26 | /* Month names */ 27 | #define L_JAN "Januar" 28 | #define L_FEB "Februar" 29 | #define L_MAR "Marts" 30 | #define L_APR "April" 31 | #define L_MAY "Maj" 32 | #define L_JUN "Juni" 33 | #define L_JUL "Juli" 34 | #define L_AUG "August" 35 | #define L_SEP "September" 36 | #define L_OCT "Oktober" 37 | #define L_NOV "November" 38 | #define L_DEC "December" 39 | 40 | /* Today and tomorrow */ 41 | #define L_TODAY "i dag" 42 | #define L_TOMORROW "i morgen" 43 | 44 | /* The default banner */ 45 | #define L_BANNER "Påmindelse for %w, %d. %m, %y%o:" 46 | 47 | /* "am" and "pm" */ 48 | #define L_AM "am" 49 | #define L_PM "pm" 50 | 51 | /* Ago and from now */ 52 | #define L_AGO "siden" 53 | #define L_FROMNOW "fra nu" 54 | 55 | /* "in %d days' time" */ 56 | #define L_INXDAYS "om %d dage" 57 | 58 | /* "on" as in "on date..." */ 59 | #define L_ON "på" 60 | 61 | /* Pluralizing - this is a problem for many languages and may require 62 | a more drastic fix */ 63 | #define L_PLURAL "e" 64 | 65 | /* Minutes, hours, at, etc */ 66 | #define L_NOW "nu" 67 | #define L_AT "kl." 68 | #define L_MINUTE "minut" 69 | #define L_HOUR "time" 70 | #define L_IS "er" 71 | #define L_WAS "var" 72 | #define L_AND "og" 73 | /* What to add to make "hour" plural */ 74 | #define L_HPLU "r" 75 | /* What to add to make "minute" plural */ 76 | #define L_MPLU "ter" 77 | 78 | /* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc. 79 | See the file dosubst.c for more info. */ 80 | 81 | #define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<5) ? " om natten" : " om formiddagen" : (hour > 17) ? " om aftenen" : " om eftermiddagen"; 82 | #define L_ORDINAL_OVERRIDE plu = "."; 83 | #define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); } 84 | #define L_E_OVER sprintf(s, "den %02d%c%02d%c%04d", d, DateSep, m+1, DateSep, y); 85 | #define L_F_OVER sprintf(s, "den %02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y); 86 | #define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); } 87 | #define L_H_OVER sprintf(s, "den %02d%c%02d", d, DateSep, m+1); 88 | #define L_I_OVER sprintf(s, "den %02d%c%02d", m+1, DateSep, d); 89 | #define L_U_OVER L_A_OVER 90 | #define L_V_OVER L_G_OVER 91 | -------------------------------------------------------------------------------- /src/langs/dutch.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* DUTCH.H */ 4 | /* */ 5 | /* Support for the DUTCH language. */ 6 | /* */ 7 | /* Author: Willem Kasdorp */ 8 | /* */ 9 | /* Modified slightly by Dianne Skoll */ 10 | /* */ 11 | /* Further corrections by Erik-Jan Vens */ 12 | /* */ 13 | /* This file is part of REMIND. */ 14 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 15 | /* */ 16 | /***************************************************************/ 17 | 18 | /* The very first define in a language support file must be L_LANGNAME: */ 19 | #define L_LANGNAME "Dutch" 20 | 21 | /* Day names */ 22 | #define L_SUNDAY "zondag" 23 | #define L_MONDAY "maandag" 24 | #define L_TUESDAY "dinsdag" 25 | #define L_WEDNESDAY "woensdag" 26 | #define L_THURSDAY "donderdag" 27 | #define L_FRIDAY "vrijdag" 28 | #define L_SATURDAY "zaterdag" 29 | 30 | /* Month names */ 31 | #define L_JAN "januari" 32 | #define L_FEB "februari" 33 | #define L_MAR "maart" 34 | #define L_APR "april" 35 | #define L_MAY "mei" 36 | #define L_JUN "juni" 37 | #define L_JUL "juli" 38 | #define L_AUG "augustus" 39 | #define L_SEP "september" 40 | #define L_OCT "oktober" 41 | #define L_NOV "november" 42 | #define L_DEC "december" 43 | 44 | /* Today and tomorrow */ 45 | #define L_TODAY "vandaag" 46 | #define L_TOMORROW "morgen" 47 | 48 | /* The default banner */ 49 | #define L_BANNER "Herinneringen voor %w, %d%s %m, %y%o:" 50 | 51 | /* "am" and "pm" */ 52 | #define L_AM "am" 53 | #define L_PM "pm" 54 | 55 | /* Ago and from now */ 56 | #define L_AGO "geleden" 57 | #define L_FROMNOW "vanaf nu" 58 | 59 | /* "in %d days' time" */ 60 | #define L_INXDAYS "over %d dagen" 61 | 62 | /* "on" as in "on date..." */ 63 | #define L_ON "op" 64 | 65 | /* Pluralizing - this is a problem for many languages and may require 66 | a more drastic fix. (Indeed..., wkasdo) */ 67 | #define L_PLURAL "s" 68 | 69 | /* Minutes, hours, at, etc */ 70 | #define L_NOW "nu" 71 | #define L_AT "op" 72 | #define L_MINUTE "minuut" 73 | #define L_HOUR "uur" 74 | #define L_IS "is" 75 | #define L_WAS "was" 76 | #define L_AND "en" 77 | /* What to add to make "hour" plural (should result in uren, not uuren (wkasdo) */ 78 | #define L_HPLU "en" 79 | /* What to add to make "minute" plural (should be minuten, not minuuten) */ 80 | #define L_MPLU "en" 81 | 82 | /* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc. 83 | See the file dosubst.c for more info. */ 84 | 85 | /* Willem - I fixed the uren/uuren problem here */ 86 | #define L_1_OVER \ 87 | if (tdiff == 0) \ 88 | sprintf(s, L_NOW); \ 89 | else if (hdiff == 0) \ 90 | sprintf(s, "%d %s %s", mdiff, \ 91 | ((mdiff == 1) ? "minuut" : "minuten"), when); \ 92 | else if (mdiff == 0) \ 93 | sprintf(s, "%d %s %s", hdiff, \ 94 | ((hdiff == 1) ? "uur" : "uren"), when); \ 95 | else sprintf(s, "%d %s %s %d %s %s", hdiff, \ 96 | (hdiff == 1 ? "uur" : "uren"), \ 97 | L_AND, mdiff, \ 98 | (mdiff == 1 ? "minuut" : "minuten"), \ 99 | when); 100 | 101 | 102 | -------------------------------------------------------------------------------- /src/langs/english.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* ENGLISH.H */ 4 | /* */ 5 | /* Support for the English language. */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 9 | /* */ 10 | /***************************************************************/ 11 | 12 | /* The very first define in a language support file must be L_LANGNAME: */ 13 | #define L_LANGNAME "English" 14 | 15 | /* Day names */ 16 | #define L_SUNDAY "Sunday" 17 | #define L_MONDAY "Monday" 18 | #define L_TUESDAY "Tuesday" 19 | #define L_WEDNESDAY "Wednesday" 20 | #define L_THURSDAY "Thursday" 21 | #define L_FRIDAY "Friday" 22 | #define L_SATURDAY "Saturday" 23 | 24 | /* Month names */ 25 | #define L_JAN "January" 26 | #define L_FEB "February" 27 | #define L_MAR "March" 28 | #define L_APR "April" 29 | #define L_MAY "May" 30 | #define L_JUN "June" 31 | #define L_JUL "July" 32 | #define L_AUG "August" 33 | #define L_SEP "September" 34 | #define L_OCT "October" 35 | #define L_NOV "November" 36 | #define L_DEC "December" 37 | 38 | /* Today and tomorrow */ 39 | #define L_TODAY "today" 40 | #define L_TOMORROW "tomorrow" 41 | 42 | /* The default banner */ 43 | #define L_BANNER "Reminders for %w, %d%s %m, %y%o:" 44 | 45 | /* "am" and "pm" */ 46 | #define L_AM "am" 47 | #define L_PM "pm" 48 | 49 | /* Ago and from now */ 50 | #define L_AGO "ago" 51 | #define L_FROMNOW "from now" 52 | 53 | /* "in %d days' time" */ 54 | #define L_INXDAYS "in %d days' time" 55 | 56 | /* "on" as in "on date..." */ 57 | #define L_ON "on" 58 | 59 | /* Pluralizing - this is a problem for many languages and may require 60 | a more drastic fix */ 61 | #define L_PLURAL "s" 62 | 63 | /* Minutes, hours, at, etc */ 64 | #define L_NOW "now" 65 | #define L_AT "at" 66 | #define L_MINUTE "minute" 67 | #define L_HOUR "hour" 68 | #define L_IS "is" 69 | #define L_WAS "was" 70 | #define L_AND "and" 71 | /* What to add to make "hour" plural */ 72 | #define L_HPLU "s" 73 | /* What to add to make "minute" plural */ 74 | #define L_MPLU "s" 75 | 76 | /* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc. 77 | See the file dosubst.c for more info. */ 78 | -------------------------------------------------------------------------------- /src/langs/german.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* GERMAN.H */ 4 | /* */ 5 | /* Support for the German language. */ 6 | /* */ 7 | /* This file was derived from a patch submitted by Wolfgang */ 8 | /* Thronicke. I don't guarantee that there are no mistakes - */ 9 | /* I don't speak German. */ 10 | /* */ 11 | /* This file is part of REMIND. */ 12 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 13 | /* */ 14 | /***************************************************************/ 15 | 16 | /* The very first define in a language support file must be L_LANGNAME: */ 17 | #define L_LANGNAME "German" 18 | 19 | /* Day names */ 20 | #define L_SUNDAY "Sonntag" 21 | #define L_MONDAY "Montag" 22 | #define L_TUESDAY "Dienstag" 23 | #define L_WEDNESDAY "Mittwoch" 24 | #define L_THURSDAY "Donnerstag" 25 | #define L_FRIDAY "Freitag" 26 | #define L_SATURDAY "Samstag" 27 | 28 | /* Month names */ 29 | #define L_JAN "Januar" 30 | #define L_FEB "Februar" 31 | #define L_MAR "März" 32 | #define L_APR "April" 33 | #define L_MAY "Mai" 34 | #define L_JUN "Juni" 35 | #define L_JUL "Juli" 36 | #define L_AUG "August" 37 | #define L_SEP "September" 38 | #define L_OCT "Oktober" 39 | #define L_NOV "November" 40 | #define L_DEC "Dezember" 41 | 42 | /* Today and tomorrow */ 43 | #define L_TODAY "heute" 44 | #define L_TOMORROW "morgen" 45 | 46 | /* The default banner */ 47 | #define L_BANNER "Termine für %w, den %d. %m %y%o:" 48 | 49 | /* "am" and "pm" */ 50 | #define L_AM "am" 51 | #define L_PM "pm" 52 | 53 | /* Ago and from now */ 54 | #define L_AGO "vorher" 55 | #define L_FROMNOW "von heute" 56 | 57 | /* "in %d days' time" */ 58 | #define L_INXDAYS "in %d Tagen" 59 | 60 | /* "on" as in "on date..." */ 61 | #define L_ON "am" 62 | 63 | /* Pluralizing - this is a problem for many languages and may require 64 | a more drastic fix */ 65 | #define L_PLURAL "en" 66 | 67 | /* Minutes, hours, at, etc */ 68 | #define L_NOW "jetzt" 69 | #define L_AT "um" 70 | #define L_MINUTE "Minute" 71 | #define L_HOUR "Stunde" 72 | #define L_IS "ist" 73 | #define L_WAS "war" 74 | #define L_AND "und" 75 | /* What to add to make "hour" plural */ 76 | #define L_HPLU "n" 77 | /* What to add to make "minute" plural */ 78 | #define L_MPLU "n" 79 | 80 | /* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc. 81 | See the file dosubst.c for more info. */ 82 | #define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<5) ? " nachts" : " vormittags" : (hour > 17) ? " abends" : " nachmittags"; 83 | #define L_ORDINAL_OVERRIDE plu = "."; 84 | #define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); } 85 | #define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); } 86 | #define L_U_OVER L_A_OVER 87 | #define L_V_OVER L_G_OVER 88 | -------------------------------------------------------------------------------- /src/langs/icelandic.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* ICELANDIC.H */ 4 | /* */ 5 | /* Support for the Icelandic language. */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 9 | /* Translated by Björn Davíðsson (bjossi@snerpa.is) */ 10 | /* */ 11 | /***************************************************************/ 12 | 13 | /* The very first define in a language support file must be L_LANGNAME: */ 14 | #define L_LANGNAME "Icelandic" 15 | 16 | /* Day names */ 17 | #define L_SUNDAY "sunnudagur" 18 | #define L_MONDAY "mánudagur" 19 | #define L_TUESDAY "þriðjudagur" 20 | #define L_WEDNESDAY "miðvikudagur" 21 | #define L_THURSDAY "fimmtudagur" 22 | #define L_FRIDAY "föstudagur" 23 | #define L_SATURDAY "laugardagur" 24 | 25 | /* Month names */ 26 | #define L_JAN "janúar" 27 | #define L_FEB "febrúar" 28 | #define L_MAR "mars" 29 | #define L_APR "apríl" 30 | #define L_MAY "maí" 31 | #define L_JUN "júní" 32 | #define L_JUL "júlí" 33 | #define L_AUG "ágúst" 34 | #define L_SEP "september" 35 | #define L_OCT "október" 36 | #define L_NOV "nóvember" 37 | #define L_DEC "desember" 38 | 39 | /* Today and tomorrow */ 40 | #define L_TODAY "í dag" 41 | #define L_TOMORROW "á morgun" 42 | 43 | /* The default banner */ 44 | #define L_BANNER "Minnisatriði: %w, %d%s %m, %y%o:" 45 | 46 | /* "am" and "pm" */ 47 | #define L_AM "fh" 48 | #define L_PM "eh" 49 | 50 | /* Ago and from now */ 51 | #define L_AGO "síðan" 52 | #define L_FROMNOW "frá því nú" 53 | 54 | /* "in %d days' time" */ 55 | #define L_INXDAYS "eftir %d daga" 56 | 57 | /* "on" as in "on date..." */ 58 | #define L_ON "þann" 59 | 60 | /* Pluralizing - this is a problem for many languages and may require 61 | a more drastic fix */ 62 | #define L_PLURAL "a" 63 | 64 | /* Minutes, hours, at, etc */ 65 | #define L_NOW "núna" 66 | #define L_AT "kl." 67 | #define L_MINUTE "mínútu" 68 | #define L_HOUR "klukkustund" 69 | #define L_IS "er" 70 | #define L_WAS "var" 71 | #define L_AND "og" 72 | /* What to add to make "hour" plural */ 73 | #define L_HPLU "ir" 74 | /* What to add to make "minute" plural */ 75 | #define L_MPLU "r" 76 | 77 | /* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc. 78 | See the file dosubst.c for more info. */ 79 | -------------------------------------------------------------------------------- /src/langs/italian.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* ITALIAN.H */ 4 | /* */ 5 | /* Support for the Italian language. */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* It is Copyright (C) 1996 by Valerio Aimale */ 9 | /* */ 10 | /* Remind is copyright (C) 1992-2022 by Dianne Skoll */ 11 | /* */ 12 | /***************************************************************/ 13 | 14 | /* The very first define in a language support file must be L_LANGNAME: */ 15 | #define L_LANGNAME "Italian" 16 | 17 | /* Day names */ 18 | #define L_SUNDAY "Domenica" 19 | #define L_MONDAY "Lunedí" 20 | #define L_TUESDAY "Martedí" 21 | #define L_WEDNESDAY "Mercoledí" 22 | #define L_THURSDAY "Giovedí" 23 | #define L_FRIDAY "Venerdí" 24 | #define L_SATURDAY "Sabato" 25 | 26 | /* Month names */ 27 | #define L_JAN "Gennaio" 28 | #define L_FEB "Febbraio" 29 | #define L_MAR "Marzo" 30 | #define L_APR "Aprile" 31 | #define L_MAY "Maggio" 32 | #define L_JUN "Giugno" 33 | #define L_JUL "Luglio" 34 | #define L_AUG "Agosto" 35 | #define L_SEP "Settembre" 36 | #define L_OCT "Ottobre" 37 | #define L_NOV "Novembre" 38 | #define L_DEC "Dicembre" 39 | 40 | /* Today and tomorrow */ 41 | #define L_TODAY "oggi" 42 | 43 | #define L_TOMORROW "domani" 44 | 45 | /* The default banner */ 46 | #define L_BANNER "Promemoria per %w, %d %m %y%o:" 47 | 48 | /* "am" and "pm" */ 49 | #define L_AM "am" 50 | #define L_PM "pm" 51 | 52 | /* Ago and from now */ 53 | #define L_AGO "fa" 54 | #define L_FROMNOW "da oggi" 55 | 56 | /* "in %d days' time" */ 57 | #define L_INXDAYS "fra %d giorni" 58 | 59 | /* "on" as in "on date..." */ 60 | #define L_ON "" 61 | 62 | /* Pluralizing - this is a problem for many languages and may require 63 | a more drastic fix */ 64 | 65 | /* Minutes, hours, at, etc */ 66 | #define L_NOW "ora" 67 | #define L_AT "alle" 68 | #define L_MINUTE "minut" 69 | #define L_HOUR "or" 70 | #define L_IS "é" 71 | #define L_WAS "era" 72 | #define L_AND "e" 73 | /* What to add to make "hour" plural */ 74 | #define L_HPLU "s" 75 | /* What to add to make "minute" plural */ 76 | #define L_MPLU "s" 77 | 78 | /* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc. 79 | See the file dosubst.c for more info. */ 80 | 81 | #define L_P_OVER sprintf(s, (diff == 1 ? "o" : "i")); 82 | #define L_Q_OVER sprintf(s, (diff == 1 ? "a" : "e")); 83 | 84 | #define L_HPLU_OVER hplu = (hdiff == 1 ? "a" : "e"); 85 | #define L_MPLU_OVER mplu = (mdiff == 1 ? "o" : "i"); 86 | 87 | #define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d,\ 88 | MonthName[m], y); 89 | #define L_C_OVER sprintf(s, "%s", DayName[jul%7]); 90 | 91 | #define L_E_OVER sprintf(s, "%02d%c%02d%c%04d", d, DateSep,\ 92 | m+1, DateSep, y); 93 | 94 | #define L_F_OVER sprintf(s, "%02d%c%02d%c%04d", m+1, DateSep, d, DateSep, y); 95 | 96 | #define L_G_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]); 97 | 98 | #define L_H_OVER sprintf(s, "%02d%c%02d", d, DateSep, m+1); 99 | 100 | #define L_I_OVER sprintf(s, "%02d%c%02d", m+1, DateSep, d); 101 | 102 | #define L_J_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, \ 103 | MonthName[m], y); 104 | 105 | #define L_K_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, \ 106 | MonthName[m]); 107 | #define L_L_OVER sprintf(s, "%04d%c%02d%c%02d", y, DateSep, m+1, DateSep, d); 108 | 109 | #define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, \ 110 | MonthName[m], y); 111 | 112 | #define L_V_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, \ 113 | MonthName[m]); 114 | -------------------------------------------------------------------------------- /src/langs/norwgian.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* NORWGIAN.H */ 4 | /* */ 5 | /* Support for the Norwegian language. */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* This file is Copyright (C) 1993 by Trygve Randen. */ 9 | /* Remind is Copyright (C) 1992-2022 by Dianne Skoll */ 10 | /* */ 11 | /***************************************************************/ 12 | 13 | /* The very first define in a language support file must be L_LANGNAME: */ 14 | #define L_LANGNAME "Norwegian" 15 | 16 | /* Day names */ 17 | #define L_SUNDAY "Søndag" 18 | #define L_MONDAY "Mandag" 19 | #define L_TUESDAY "Tirsdag" 20 | #define L_WEDNESDAY "Onsdag" 21 | #define L_THURSDAY "Torsdag" 22 | #define L_FRIDAY "Fredag" 23 | #define L_SATURDAY "Lørdag" 24 | 25 | /* Month names */ 26 | #define L_JAN "Januar" 27 | #define L_FEB "Februar" 28 | #define L_MAR "Mars" 29 | #define L_APR "April" 30 | #define L_MAY "Mai" 31 | #define L_JUN "Juni" 32 | #define L_JUL "Juli" 33 | #define L_AUG "August" 34 | #define L_SEP "September" 35 | #define L_OCT "Oktober" 36 | #define L_NOV "November" 37 | #define L_DEC "Desember" 38 | 39 | /* Today and tomorrow */ 40 | #define L_TODAY "i dag" 41 | #define L_TOMORROW "i morgen" 42 | 43 | /* The default banner */ 44 | #define L_BANNER "Påminnelse for %w, %d. %m, %y%o:" 45 | 46 | /* "am" and "pm" */ 47 | #define L_AM "am" 48 | #define L_PM "pm" 49 | 50 | /* Ago and from now */ 51 | #define L_AGO "siden" 52 | #define L_FROMNOW "fra nå" 53 | 54 | /* "in %d days' time" */ 55 | #define L_INXDAYS "om %d dager" 56 | 57 | /* "on" as in "on date..." */ 58 | #define L_ON "den" 59 | 60 | /* Pluralizing - this is a problem for many languages and may require 61 | a more drastic fix */ 62 | #define L_PLURAL "er" 63 | 64 | /* Minutes, hours, at, etc */ 65 | #define L_NOW "nå" 66 | #define L_AT "kl." 67 | #define L_MINUTE "minutt" 68 | #define L_HOUR "time" 69 | #define L_IS "er" 70 | #define L_WAS "var" 71 | #define L_AND "og" 72 | /* What to add to make "hour" plural */ 73 | #define L_HPLU "r" 74 | /* What to add to make "minute" plural */ 75 | #define L_MPLU "er" 76 | 77 | /* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc. 78 | See the file dosubst.c for more info. */ 79 | #define L_ORDINAL_OVERRIDE plu = "."; 80 | #define L_A_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s %d", DayName[jul%7], d, MonthName[m], y); } else { sprintf(s, "%s %s, den %d. %s %d", L_ON, DayName[jul%7], d, MonthName[m], y); } 81 | #define L_G_OVER if (altmode == '*') { sprintf(s, "%s, den %d. %s", DayName[jul%7], d, MonthName[m]); } else { sprintf(s, "%s %s, den %d. %s", L_ON, DayName[jul%7], d, MonthName[m]); } 82 | #define L_U_OVER L_A_OVER 83 | #define L_V_OVER L_G_OVER 84 | -------------------------------------------------------------------------------- /src/langs/romanian.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* ROMANIAN.H */ 4 | /* */ 5 | /* Support for the Romanian language. */ 6 | /* */ 7 | /* Contributed by Liviu Daia */ 8 | /* */ 9 | /* This file is part of REMIND. */ 10 | /* */ 11 | /* REMIND is Copyright (C) 1992-2022 by Dianne Skoll */ 12 | /* This file is Copyright (C) 1996-1998 by Liviu Daia */ 13 | /* */ 14 | /***************************************************************/ 15 | 16 | /* The very first define in a language support file must be L_LANGNAME: */ 17 | #define L_LANGNAME "Romanian" 18 | 19 | /* Day names */ 20 | # define L_SUNDAY "Duminică" 21 | # define L_MONDAY "Luni" 22 | # define L_TUESDAY "Marți" 23 | # define L_WEDNESDAY "Miercuri" 24 | # define L_THURSDAY "Joi" 25 | # define L_FRIDAY "Vineri" 26 | # define L_SATURDAY "Sâmbătă" 27 | 28 | /* Month names */ 29 | #define L_JAN "Ianuarie" 30 | #define L_FEB "Februarie" 31 | #define L_MAR "Martie" 32 | #define L_APR "Aprilie" 33 | #define L_MAY "Mai" 34 | #define L_JUN "Iunie" 35 | #define L_JUL "Iulie" 36 | #define L_AUG "August" 37 | #define L_SEP "Septembrie" 38 | #define L_OCT "Octombrie" 39 | #define L_NOV "Noiembrie" 40 | #define L_DEC "Decembrie" 41 | 42 | /* Today and tomorrow */ 43 | # define L_TODAY "astăzi" 44 | # define L_TOMORROW "mâine" 45 | 46 | /* The default banner */ 47 | #define L_BANNER "Reamintiri pentru %w, %d %m %y%o:" 48 | 49 | /* "am" and "pm" */ 50 | #define L_AM "am" 51 | #define L_PM "pm" 52 | 53 | /* Ago and from now */ 54 | #define L_AGO "acum" 55 | #define L_FROMNOW "peste" 56 | 57 | /* "in %d days' time" */ 58 | #define L_INXDAYS "peste %d zile" 59 | 60 | /* "on" as in "on date..." */ 61 | #define L_ON "pe" 62 | 63 | /* Pluralizing - this is a problem for many languages and may require 64 | a more drastic fix */ 65 | #define L_PLURAL "le" 66 | 67 | /* Minutes, hours, at, etc */ 68 | #define L_NOW "acum" 69 | #define L_AT "la ora" 70 | #define L_MINUTE "minut" 71 | #define L_HOUR "or" 72 | #define L_IS "este" 73 | #define L_WAS "a fost" 74 | /* What to add to make "minute" plural */ 75 | #define L_MPLU "e" 76 | #define L_HPLU "e" 77 | 78 | /* What to add to make "hour" plural */ 79 | #define L_HPLU_OVER hplu = (hdiff == 1 ? "ă" : "e"); 80 | #define L_AND "şi" 81 | 82 | /* Define any overrides here, such as L_ORDINAL_OVERRIDE, L_A_OVER, etc. 83 | See the file dosubst.c for more info. */ 84 | #define L_AMPM_OVERRIDE(ampm, hour) ampm = (hour < 12) ? (hour<4) ? " noaptea" : " dimineaţa" : (hour > 17) ? " seara" : " după-amiaza"; 85 | #define L_ORDINAL_OVERRIDE plu = ""; 86 | 87 | #define L_A_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, MonthName[m], y); 88 | #define L_C_OVER sprintf(s, "%s", DayName[jul%7]); 89 | #define L_G_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]); 90 | #define L_J_OVER sprintf(s, "%s, %s %d, %d", DayName[jul%7], MonthName[m], d, y); 91 | #define L_K_OVER sprintf(s, "%s, %s %d", DayName[jul%7], MonthName[m], d); 92 | #define L_S_OVER 93 | #define L_U_OVER sprintf(s, "%s, %d %s %d", DayName[jul%7], d, MonthName[m], y); 94 | #define L_V_OVER sprintf(s, "%s, %d %s", DayName[jul%7], d, MonthName[m]); 95 | #define L_1_OVER \ 96 | if (tdiff == 0) \ 97 | sprintf(s, L_NOW); \ 98 | else if (hdiff == 0) \ 99 | sprintf(s, "%s %d %s%s", when, mdiff, L_MINUTE, mplu); \ 100 | else if (mdiff == 0) \ 101 | sprintf(s, "%s %d %s%s", when, hdiff, L_HOUR, hplu); \ 102 | else \ 103 | sprintf(s, "%s %d %s%s %s %d %s%s", when, hdiff, \ 104 | L_HOUR, hplu, L_AND, mdiff, L_MINUTE, mplu); 105 | -------------------------------------------------------------------------------- /src/langs/spanish.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* SPANISH.H */ 4 | /* */ 5 | /* Support for the Spanish language. */ 6 | /* */ 7 | /* Author: Rafa Couto */ 8 | /* */ 9 | /* This file is part of REMIND. */ 10 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 11 | /* */ 12 | /***************************************************************/ 13 | 14 | #define L_LANGNAME "Spanish" 15 | 16 | /* Nombres de los di'as de la semana */ 17 | #define L_SUNDAY "Domingo" 18 | #define L_MONDAY "Lunes" 19 | #define L_TUESDAY "Martes" 20 | #define L_WEDNESDAY "Miércoles" 21 | #define L_THURSDAY "Jueves" 22 | #define L_FRIDAY "Viernes" 23 | #define L_SATURDAY "Sábado" 24 | 25 | /* Nombres de los meses */ 26 | #define L_JAN "Enero" 27 | #define L_FEB "Febrero" 28 | #define L_MAR "Marzo" 29 | #define L_APR "Abril" 30 | #define L_MAY "Mayo" 31 | #define L_JUN "Junio" 32 | #define L_JUL "Julio" 33 | #define L_AUG "Agosto" 34 | #define L_SEP "Septiembre" 35 | #define L_OCT "Octubre" 36 | #define L_NOV "Noviembre" 37 | #define L_DEC "Diciembre" 38 | 39 | /* Hoy y man~ana */ 40 | #define L_TODAY "hoy" 41 | #define L_TOMORROW "mañana" 42 | 43 | /* El titular habitual */ 44 | #define L_BANNER "Agenda para el %w, %d%s %m, %y%o:" 45 | 46 | /* "am" and "pm" */ 47 | #define L_AM "am" 48 | #define L_PM "pm" 49 | 50 | /* Hace y desde hoy */ 51 | #define L_AGO "hace" 52 | #define L_FROMNOW "desde hoy" 53 | 54 | /* "dentro de %d di'as" */ 55 | #define L_INXDAYS "dentro de %d días" 56 | #define L_ON "el día" 57 | 58 | /* "el di'a..." */ 59 | 60 | /* plurales */ 61 | #define L_PLURAL "s" 62 | 63 | /* Minutos, horas, a las, etc */ 64 | #define L_NOW "ahora" 65 | #define L_AT "a las" 66 | #define L_MINUTE "minuto" 67 | #define L_HOUR "hora" 68 | #define L_IS "es" 69 | #define L_WAS "fue" 70 | #define L_AND "y" 71 | #define L_HPLU "s" 72 | #define L_MPLU "s" 73 | 74 | -------------------------------------------------------------------------------- /src/md5.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This code implements the MD5 message-digest algorithm. 3 | * The algorithm is due to Ron Rivest. This code was 4 | * written by Colin Plumb in 1993, no copyright is claimed. 5 | * This code is in the public domain; do with it what you wish. 6 | * 7 | * Equivalent code is available from RSA Data Security, Inc. 8 | * This code has been tested against that, and is equivalent, 9 | * except that you don't need to include two pages of legalese 10 | * with every copy. 11 | * 12 | * LIC: GPL 13 | * 14 | * To compute the message digest of a chunk of bytes, declare an 15 | * MD5Context structure, pass it to MD5Init, call MD5Update as 16 | * needed on buffers full of bytes, and then call MD5Final, which 17 | * will fill a supplied 16-byte array with the digest. 18 | */ 19 | #include /* for memcpy() */ 20 | #include "md5.h" 21 | 22 | static void byteReverse(unsigned char *buf, unsigned longs); 23 | 24 | /* 25 | * Note: this code is harmless on little-endian machines. 26 | */ 27 | static void 28 | byteReverse(unsigned char *buf, unsigned longs) 29 | { 30 | uint32 t; 31 | do { 32 | t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | 33 | ((unsigned) buf[1] << 8 | buf[0]); 34 | *(uint32 *) buf = t; 35 | buf += 4; 36 | } while (--longs); 37 | } 38 | 39 | /* 40 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 41 | * initialization constants. 42 | */ 43 | void MD5Init(struct MD5Context *ctx) 44 | { 45 | ctx->buf[0] = 0x67452301; 46 | ctx->buf[1] = 0xefcdab89; 47 | ctx->buf[2] = 0x98badcfe; 48 | ctx->buf[3] = 0x10325476; 49 | 50 | ctx->bits[0] = 0; 51 | ctx->bits[1] = 0; 52 | } 53 | 54 | /* 55 | * Update context to reflect the concatenation of another buffer full 56 | * of bytes. 57 | */ 58 | void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) 59 | { 60 | uint32 t; 61 | 62 | /* Update bitcount */ 63 | 64 | t = ctx->bits[0]; 65 | if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) 66 | ctx->bits[1]++; /* Carry from low to high */ 67 | ctx->bits[1] += len >> 29; 68 | 69 | t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 70 | 71 | /* Handle any leading odd-sized chunks */ 72 | 73 | if (t) { 74 | unsigned char *p = (unsigned char *) ctx->in + t; 75 | 76 | t = 64 - t; 77 | if (len < t) { 78 | memcpy(p, buf, len); 79 | return; 80 | } 81 | memcpy(p, buf, t); 82 | byteReverse(ctx->in, 16); 83 | MD5Transform(ctx->buf, (uint32 *) ctx->in); 84 | buf += t; 85 | len -= t; 86 | } 87 | /* Process data in 64-byte chunks */ 88 | 89 | while (len >= 64) { 90 | memcpy(ctx->in, buf, 64); 91 | byteReverse(ctx->in, 16); 92 | MD5Transform(ctx->buf, (uint32 *) ctx->in); 93 | buf += 64; 94 | len -= 64; 95 | } 96 | 97 | /* Handle any remaining bytes of data. */ 98 | 99 | memcpy(ctx->in, buf, len); 100 | } 101 | 102 | /* 103 | * Final wrapup - pad to 64-byte boundary with the bit pattern 104 | * 1 0* (64-bit count of bits processed, MSB-first) 105 | */ 106 | void MD5Final(unsigned char digest[16], struct MD5Context *ctx) 107 | { 108 | unsigned count; 109 | unsigned char *p; 110 | 111 | /* Compute number of bytes mod 64 */ 112 | count = (ctx->bits[0] >> 3) & 0x3F; 113 | 114 | /* Set the first char of padding to 0x80. This is safe since there is 115 | always at least one byte free */ 116 | p = ctx->in + count; 117 | *p++ = 0x80; 118 | 119 | /* Bytes of padding needed to make 64 bytes */ 120 | count = 64 - 1 - count; 121 | 122 | /* Pad out to 56 mod 64 */ 123 | if (count < 8) { 124 | /* Two lots of padding: Pad the first block to 64 bytes */ 125 | memset(p, 0, count); 126 | byteReverse(ctx->in, 16); 127 | MD5Transform(ctx->buf, (uint32 *) ctx->in); 128 | 129 | /* Now fill the next block with 56 bytes */ 130 | memset(ctx->in, 0, 56); 131 | } else { 132 | /* Pad block to 56 bytes */ 133 | memset(p, 0, count - 8); 134 | } 135 | byteReverse(ctx->in, 14); 136 | 137 | /* Append length in bits and transform */ 138 | ((uint32 *) ctx->in)[14] = ctx->bits[0]; 139 | ((uint32 *) ctx->in)[15] = ctx->bits[1]; 140 | 141 | MD5Transform(ctx->buf, (uint32 *) ctx->in); 142 | byteReverse((unsigned char *) ctx->buf, 4); 143 | memcpy(digest, ctx->buf, 16); 144 | memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ 145 | } 146 | 147 | #ifndef ASM_MD5 148 | 149 | /* The four core functions - F1 is optimized somewhat */ 150 | 151 | /* #define F1(x, y, z) (x & y | ~x & z) */ 152 | #define F1(x, y, z) (z ^ (x & (y ^ z))) 153 | #define F2(x, y, z) F1(z, x, y) 154 | #define F3(x, y, z) (x ^ y ^ z) 155 | #define F4(x, y, z) (y ^ (x | ~z)) 156 | 157 | /* This is the central step in the MD5 algorithm. */ 158 | #define MD5STEP(f, w, x, y, z, data, s) \ 159 | ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) 160 | 161 | /* 162 | * The core of the MD5 algorithm, this alters an existing MD5 hash to 163 | * reflect the addition of 16 longwords of new data. MD5Update blocks 164 | * the data and converts bytes into longwords for this routine. 165 | */ 166 | void MD5Transform(uint32 buf[4], uint32 const in[16]) 167 | { 168 | register uint32 a, b, c, d; 169 | 170 | a = buf[0]; 171 | b = buf[1]; 172 | c = buf[2]; 173 | d = buf[3]; 174 | 175 | MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 176 | MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 177 | MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 178 | MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 179 | MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 180 | MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 181 | MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 182 | MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 183 | MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 184 | MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 185 | MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 186 | MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 187 | MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 188 | MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 189 | MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 190 | MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 191 | 192 | MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 193 | MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 194 | MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 195 | MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 196 | MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 197 | MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 198 | MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 199 | MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 200 | MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 201 | MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 202 | MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 203 | MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 204 | MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 205 | MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 206 | MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 207 | MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 208 | 209 | MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 210 | MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 211 | MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 212 | MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 213 | MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 214 | MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 215 | MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 216 | MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 217 | MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 218 | MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 219 | MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 220 | MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 221 | MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 222 | MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 223 | MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 224 | MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 225 | 226 | MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 227 | MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 228 | MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 229 | MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 230 | MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 231 | MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 232 | MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 233 | MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 234 | MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 235 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 236 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 237 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 238 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 239 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 240 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 241 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 242 | 243 | buf[0] += a; 244 | buf[1] += b; 245 | buf[2] += c; 246 | buf[3] += d; 247 | } 248 | 249 | #endif 250 | -------------------------------------------------------------------------------- /src/md5.h: -------------------------------------------------------------------------------- 1 | #ifndef MD5_H 2 | #define MD5_H 3 | /* 4 | * LIC: GPL 5 | */ 6 | 7 | #include "config.h" 8 | 9 | #if SIZEOF_UNSIGNED_INT == 4 10 | typedef unsigned int uint32; 11 | #elif SIZEOF_UNSIGNED_LONG == 4 12 | typedef unsigned long uint32; 13 | #else 14 | # error Could not find a 32-bit integer type 15 | #endif 16 | 17 | struct MD5Context { 18 | uint32 buf[4]; 19 | uint32 bits[2]; 20 | unsigned char in[64]; 21 | }; 22 | 23 | void MD5Init(struct MD5Context *context); 24 | void MD5Update(struct MD5Context *context, unsigned char const *buf, 25 | unsigned len); 26 | void MD5Final(unsigned char digest[16], struct MD5Context *context); 27 | void MD5Transform(uint32 buf[4], uint32 const in[16]); 28 | 29 | /* 30 | * This is needed to make RSAREF happy on some MS-DOS compilers. 31 | */ 32 | typedef struct MD5Context MD5_CTX; 33 | 34 | #endif /* !MD5_H */ 35 | -------------------------------------------------------------------------------- /src/protos.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* PROTOS.H */ 4 | /* */ 5 | /* Function Prototypes. */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 9 | /* */ 10 | /***************************************************************/ 11 | 12 | /* Suppress unused variable warnings */ 13 | #define UNUSED(x) (void) x 14 | 15 | /* Define a string assignment macro - be careful!!! */ 16 | #define STRSET(x, str) { if (x) free(x); (x) = StrDup(str); } 17 | 18 | /* Define a general malloc routine for creating pointers to objects */ 19 | #define NEW(type) (malloc(sizeof(type))) 20 | 21 | /* Characters to ignore */ 22 | #define isempty(c) (isspace(c) || ((c) == '\\')) 23 | 24 | #include "dynbuf.h" 25 | 26 | int CallUserFunc (char const *name, int nargs, ParsePtr p); 27 | int DoFset (ParsePtr p); 28 | void ProduceCalendar (void); 29 | char const *SimpleTime (int tim); 30 | char const *CalendarTime (int tim, int duration); 31 | int DoRem (ParsePtr p); 32 | int DoFlush (ParsePtr p); 33 | void DoExit (ParsePtr p); 34 | int ParseRem (ParsePtr s, Trigger *trig, TimeTrig *tim, int save_in_globals); 35 | int TriggerReminder (ParsePtr p, Trigger *t, TimeTrig *tim, int jul); 36 | int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int jul, int *err); 37 | int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul, int mode); 38 | int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int jul, int tim); 39 | int ParseLiteralDate (char const **s, int *jul, int *tim); 40 | int ParseLiteralTime (char const **s, int *tim); 41 | int EvalExpr (char const **e, Value *v, ParsePtr p); 42 | int DoCoerce (char type, Value *v); 43 | void PrintValue (Value *v, FILE *fp); 44 | int CopyValue (Value *dest, const Value *src); 45 | int ReadLine (void); 46 | int OpenFile (char const *fname); 47 | int DoInclude (ParsePtr p, enum TokTypes tok); 48 | int DoIncludeCmd (ParsePtr p); 49 | int IncludeFile (char const *fname); 50 | int GetAccessDate (char const *file); 51 | int SetAccessDate (char const *fname, int jul); 52 | int TopLevel (void); 53 | int CallFunc (BuiltinFunc *f, int nargs); 54 | void InitRemind (int argc, char const *argv[]); 55 | void Usage (void); 56 | int Julian (int year, int month, int day); 57 | void FromJulian (int jul, int *y, int *m, int *d); 58 | int ParseChar (ParsePtr p, int *err, int peek); 59 | int ParseToken (ParsePtr p, DynamicBuffer *dbuf); 60 | int ParseIdentifier (ParsePtr p, DynamicBuffer *dbuf); 61 | int EvaluateExpr (ParsePtr p, Value *v); 62 | int Evaluate (char const **s, Var *locals, ParsePtr p); 63 | int FnPopValStack (Value *val); 64 | void Eprint (char const *fmt, ...); 65 | void Wprint (char const *fmt, ...); 66 | void OutputLine (FILE *fp); 67 | void CreateParser (char const *s, ParsePtr p); 68 | void DestroyParser (ParsePtr p); 69 | int PushToken (char const *tok, ParsePtr p); 70 | long SystemTime (int realtime); 71 | int SystemDate (int *y, int *m, int *d); 72 | int DoIf (ParsePtr p); 73 | int DoElse (ParsePtr p); 74 | int DoEndif (ParsePtr p); 75 | int DoIfTrig (ParsePtr p); 76 | int ShouldIgnoreLine (void); 77 | int VerifyEoln (ParsePtr p); 78 | int DoDebug (ParsePtr p); 79 | int DoBanner (ParsePtr p); 80 | int DoRun (ParsePtr p); 81 | int DoErrMsg (ParsePtr p); 82 | int ClearGlobalOmits (void); 83 | int DoClear (ParsePtr p); 84 | int DestroyOmitContexts (void); 85 | int PushOmitContext (ParsePtr p); 86 | int PopOmitContext (ParsePtr p); 87 | int IsOmitted (int jul, int localomit, char const *omitfunc, int *omit); 88 | int DoOmit (ParsePtr p); 89 | int QueueReminder (ParsePtr p, Trigger *trig, TimeTrig *tim, char const *sched); 90 | void HandleQueuedReminders (void); 91 | char const *FindInitialToken (Token *tok, char const *s); 92 | void FindToken (char const *s, Token *tok); 93 | void FindNumericToken (char const *s, Token *t); 94 | int ComputeTrigger (int today, Trigger *trig, TimeTrig *tim, int *err, int save_in_globals); 95 | int ComputeTriggerNoAdjustDuration (int today, Trigger *trig, TimeTrig *tim, int *err, int save_in_globals, int duration_days); 96 | int AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int save_in_globals); 97 | int ComputeScanStart(int today, Trigger *trig, TimeTrig *tt); 98 | char *StrnCpy (char *dest, char const *source, int n); 99 | int StrMatch (char const *s1, char const *s2, int n); 100 | int StrinCmp (char const *s1, char const *s2, int n); 101 | char *StrDup (char const *s); 102 | int StrCmpi (char const *s1, char const *s2); 103 | Var *FindVar (char const *str, int create); 104 | int DeleteVar (char const *str); 105 | int SetVar (char const *str, Value *val); 106 | int GetVarValue (char const *str, Value *val, Var *locals, ParsePtr p); 107 | int DoSet (Parser *p); 108 | int DoUnset (Parser *p); 109 | int DoDump (ParsePtr p); 110 | void DumpVarTable (void); 111 | void DestroyVars (int all); 112 | int PreserveVar (char const *name); 113 | int DoPreserve (Parser *p); 114 | int DoSatRemind (Trigger *trig, TimeTrig *tt, ParsePtr p); 115 | int DoMsgCommand (char const *cmd, char const *msg); 116 | int ParseNonSpaceChar (ParsePtr p, int *err, int peek); 117 | unsigned int HashVal (char const *str); 118 | int DateOK (int y, int m, int d); 119 | Operator *FindOperator (char const *name, Operator where[], int num); 120 | BuiltinFunc *FindFunc (char const *name, BuiltinFunc where[], int num); 121 | int InsertIntoSortBuffer (int jul, int tim, char const *body, int typ, int prio); 122 | void IssueSortedReminders (void); 123 | int UserFuncExists (char const *fn); 124 | void JulToHeb (int jul, int *hy, int *hm, int *hd); 125 | int HebNameToNum (char const *mname); 126 | char const *HebMonthName (int m, int y); 127 | int RoshHashana (int i); 128 | long DaysToHebYear (int y); 129 | int DaysInHebYear (int y); 130 | char const *DaysInHebMonths (int ylen); 131 | int HebToJul (int hy, int hm, int hd); 132 | int GetValidHebDate (int yin, int min, int din, int adarbehave, int *mout, int *dout, int yahr); 133 | int GetNextHebrewDate (int julstart, int hm, int hd, int yahr, int adarbehave, int *ans); 134 | int ComputeJahr (int y, int m, int d, int *ans); 135 | int GetSysVar (char const *name, Value *val); 136 | int SetSysVar (char const *name, Value *val); 137 | void DumpSysVarByName (char const *name); 138 | int CalcMinsFromUTC (int jul, int tim, int *mins, int *isdst); 139 | void FillParagraph (char const *s); 140 | void LocalToUTC (int locdate, int loctime, int *utcdate, int *utctime); 141 | void UTCToLocal (int utcdate, int utctime, int *locdate, int *loctime); 142 | int MoonPhase (int date, int time); 143 | void HuntPhase (int startdate, int starttim, int phas, int *date, int *time); 144 | int CompareRems (int dat1, int tim1, int prio1, int dat2, int tim2, int prio2, int bydate, int bytime, int byprio, int untimed_first); 145 | void SigIntHandler (int d); 146 | void GotSigInt (void); 147 | void PurgeEchoLine(char const *fmt, ...); 148 | void FreeTrig(Trigger *t); 149 | void AppendTag(DynamicBuffer *buf, char const *s); 150 | char const *SynthesizeTag(void); 151 | void ClearLastTriggers(void); 152 | void SaveLastTrigger(Trigger const *t); 153 | void SaveLastTimeTrig(TimeTrig const *t); 154 | void SaveAllTriggerInfo(Trigger const *t, TimeTrig const *tt, int trigdate, int trigtime, int valid); 155 | 156 | void PerIterationInit(void); 157 | char const *Decolorize(int r, int g, int b); 158 | char const *Colorize(int r, int g, int b); 159 | void PrintJSONString(char const *s); 160 | void PrintJSONKeyPairInt(char const *name, int val); 161 | void PrintJSONKeyPairString(char const *name, char const *val); 162 | void PrintJSONKeyPairDate(char const *name, int jul); 163 | void PrintJSONKeyPairDateTime(char const *name, int dt); 164 | void PrintJSONKeyPairTime(char const *name, int t); 165 | void System(char const *cmd); 166 | int ShellEscape(char const *in, DynamicBuffer *out); 167 | int AddGlobalOmit(int jul); 168 | void set_lat_and_long_from_components(void); 169 | void set_components_from_lat_and_long(void); 170 | 171 | char const *get_day_name(int wkday); 172 | char const *get_month_name(int mon); 173 | 174 | int push_call(char const *filename, char const *func, int lineno); 175 | void clear_callstack(void); 176 | int have_callstack(void); 177 | int print_callstack(FILE *fp); 178 | void pop_call(void); 179 | -------------------------------------------------------------------------------- /src/rem2ps.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* REM2PS.H */ 4 | /* */ 5 | /* Define the PostScript prologue */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 9 | /* */ 10 | /***************************************************************/ 11 | 12 | char *PSProlog1[] = 13 | { 14 | "% This file was produced by Remind and Rem2PS, written by", 15 | "% Dianne Skoll.", 16 | "% Remind and Rem2PS are Copyright 1992-2022 Dianne Skoll.", 17 | "/ISOLatin1Encoding where { pop save true }{ false } ifelse", 18 | " /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus", 19 | " StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute", 20 | " /circumflex /tilde /macron /breve /dotaccent /dieresis /.notdef /ring", 21 | " /cedilla /.notdef /hungarumlaut /ogonek /caron /space /exclamdown /cent", 22 | " /sterling /currency /yen /brokenbar /section /dieresis /copyright", 23 | " /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron", 24 | " /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph", 25 | " /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright", 26 | " /onequarter /onehalf /threequarters /questiondown /Agrave /Aacute", 27 | " /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute", 28 | " /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth", 29 | " /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply", 30 | " /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn", 31 | " /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae", 32 | " /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute", 33 | " /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex", 34 | " /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex", 35 | " /udieresis /yacute /thorn /ydieresis ] def", 36 | "{ restore } if", 37 | "", 38 | "/reencodeISO { %def", 39 | " findfont dup length dict begin", 40 | " { 1 index /FID ne { def }{ pop pop } ifelse } forall", 41 | " /Encoding ISOLatin1Encoding def", 42 | " currentdict end definefont pop", 43 | "} bind def", 44 | "/copyFont { %def", 45 | " findfont dup length dict begin", 46 | " { 1 index /FID ne { def } { pop pop } ifelse } forall", 47 | " currentdict end definefont pop", 48 | "} bind def", 49 | "", 50 | "% L - Draw a line", 51 | "/L {", 52 | " newpath moveto lineto stroke", 53 | "} bind def", 54 | "% string1 string2 strcat string", 55 | "% Function: Concatenates two strings together.", 56 | "/strcat {", 57 | " 2 copy length exch length add", 58 | " string dup", 59 | " 4 2 roll", 60 | " 2 index 0 3 index", 61 | " putinterval", 62 | " exch length exch putinterval", 63 | "} bind def", 64 | "% string doheading", 65 | "/doheading", 66 | "{", 67 | " /monthyr exch def", 68 | "", 69 | " /TitleFont findfont", 70 | " TitleSize scalefont setfont", 71 | " monthyr stringwidth", 72 | " /hgt exch def", 73 | " 2 div MaxX MinX add 2 div exch sub /x exch def", 74 | " MaxY Border sub TitleSize sub /y exch def", 75 | " newpath x y moveto monthyr show", 76 | " newpath x y moveto monthyr false charpath flattenpath pathbbox", 77 | " pop pop Border sub /y exch def pop", 78 | " MinX y MaxX y L", 79 | " /topy y def", 80 | " /HeadFont findfont HeadSize scalefont setfont", 81 | "% Do the days of the week", 82 | " MaxX MinX sub 7 div /xincr exch def", 83 | " /x MinX def", 84 | NULL 85 | }; 86 | char *PSProlog2[] = 87 | { 88 | " {", 89 | " HeadSize x y HeadSize 2 mul sub x xincr add y CenterText", 90 | " x xincr add /x exch def", 91 | " } forall", 92 | " y HeadSize 2 mul sub /y exch def", 93 | " MinX y MaxX y L", 94 | " /ytop y def /ymin y def", 95 | "}", 96 | "def", 97 | "/CenterText", 98 | "{", 99 | " /maxy exch def", 100 | " /maxx exch def", 101 | " /miny exch def", 102 | " /minx exch def", 103 | " /sz exch def", 104 | " /str exch def", 105 | " str stringwidth pop", 106 | " 2 div maxx minx add 2 div exch sub", 107 | " sz 2 div maxy miny add 2 div exch sub", 108 | " moveto str show", 109 | "} def", 110 | "% Variables:", 111 | "% curline - a string holding the current line", 112 | "% y - current y pos", 113 | "% yincr - increment to next line", 114 | "% xleft - left margin", 115 | "% width - max width.", 116 | "% EnterOneWord - given a word, enter it into the box.", 117 | "% string EnterOneWord", 118 | "/EnterOneWord {", 119 | " { EnterOneWordAux", 120 | " {exit} if }", 121 | " loop", 122 | "} bind def", 123 | "% EnterOneWordAux - if the word fits, enter it into box and return true.", 124 | "% If it doesn't fit, put as much as will fit and return the string and false.", 125 | "/EnterOneWordAux {", 126 | " /word exch def", 127 | " /tmpline curline word strcat def", 128 | " tmpline stringwidth pop width gt", 129 | " {MoveToNewLine}", 130 | " {/curline tmpline ( ) strcat def /word () def}", 131 | " ifelse", 132 | " word () eq", 133 | " {true}", 134 | " {word false}", 135 | " ifelse", 136 | "} bind def", 137 | "% MoveToNewLine - move to a new line, resetting word as appropriate", 138 | "/MoveToNewLine {", 139 | " curline () ne", 140 | " {newpath xleft y moveto curline show /curline () def /y y yincr add def} ", 141 | " {ChopWord}", 142 | " ifelse", 143 | "} bind def", 144 | "% ChopWord - word won't fit. Chop it and find biggest piece that will fit", 145 | "/ChopWord {", 146 | " /curline () def", 147 | " /len word length def", 148 | " /Fcount len 1 sub def", 149 | "", 150 | " {", 151 | " word 0 Fcount getinterval stringwidth pop width le", 152 | " {exit} if", 153 | " /Fcount Fcount 1 sub def", 154 | " } loop", 155 | "% Got the count. Display it and reset word", 156 | " newpath xleft y moveto word 0 Fcount getinterval show", 157 | " /y y yincr add def", 158 | " /word word Fcount len Fcount sub getinterval def", 159 | "} bind def", 160 | "/FinishFormatting {", 161 | " word () ne", 162 | " {newpath xleft y moveto word show /word () def", 163 | " /curline () def /y y yincr add def}", 164 | " {curline () ne", 165 | " {newpath xleft y moveto curline show /word () def", 166 | " /curline () def /y y yincr add def} if}", 167 | " ifelse", 168 | "} bind def", 169 | "% FillBoxWithText - fill a box with text", 170 | "% text-array xleft width yincr y FillBoxWithText new-y", 171 | "% Returns the new Y-coordinate.", 172 | "/FillBoxWithText {", 173 | " /y exch def", 174 | " /yincr exch def", 175 | " /width exch def", 176 | " /xleft exch def", 177 | " /curline () def", 178 | " % The last two strings in the word array are actually the PostScript", 179 | " % code to execute before and after the entry is printed.", 180 | " dup dup", 181 | " length 1 sub", 182 | " get", 183 | " exch", 184 | " dup dup", 185 | " length 2 sub", 186 | " get", 187 | " dup length 0 gt", 188 | " {cvx exec} {pop} ifelse", 189 | " dup length 2 sub 0 exch getinterval", 190 | " {EnterOneWord} forall", 191 | " FinishFormatting", 192 | " dup length 0 gt", 193 | " {cvx exec} {pop} ifelse", 194 | " y", 195 | "} bind def", 196 | "% Variables for calendar boxes:", 197 | "% ytop - current top position", 198 | "% ymin - minimum y reached for current row", 199 | "% border ytop xleft width textarray daynum onright DoCalBox ybot", 200 | "% Do the entries for one calendar box. Returns lowest Y-coordinate reached", 201 | "/DoCalBox {", 202 | " /onright exch def", 203 | " /daynum exch def", 204 | " /textarr exch def", 205 | " /wid exch def", 206 | " /xl exch def", 207 | " /yt exch def", 208 | " /border exch def", 209 | "% Do the day number", 210 | " /DayFont findfont DaySize scalefont setfont", 211 | " onright 1 eq", 212 | " {xl wid add border sub daynum stringwidth pop sub yt border sub DaySize sub moveto daynum show}", 213 | " {xl border add yt border sub DaySize sub moveto daynum show}", 214 | " ifelse", 215 | "% Do the text entries. Precharge the stack with current y pos.", 216 | " /ycur yt border sub DaySize sub DaySize sub 2 add def", 217 | " /EntryFont findfont EntrySize scalefont setfont", 218 | " ycur", 219 | " textarr", 220 | " { exch 2 sub /ycur exch def xl border add wid border sub border sub EntrySize 2 add neg", 221 | " ycur FillBoxWithText }", 222 | " forall", 223 | "} bind def", 224 | "2 setlinecap", 225 | "% Define a default PreCal procedure", 226 | "/PreCal { pop pop } bind def", 227 | NULL 228 | }; 229 | -------------------------------------------------------------------------------- /src/sort.c: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* SORT.C */ 4 | /* */ 5 | /* Routines for sorting reminders by trigger date */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 9 | /* */ 10 | /***************************************************************/ 11 | 12 | #include "config.h" 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include "types.h" 19 | #include "protos.h" 20 | #include "expr.h" 21 | #include "globals.h" 22 | #include "err.h" 23 | 24 | /* The structure of a sorted entry */ 25 | typedef struct sortrem { 26 | struct sortrem *next; 27 | char const *text; 28 | int trigdate; 29 | int trigtime; 30 | int typ; 31 | int priority; 32 | } Sortrem; 33 | 34 | /* The sorted reminder queue */ 35 | static Sortrem *SortedQueue = (Sortrem *) NULL; 36 | 37 | static Sortrem *MakeSortRem (int jul, int tim, char const *body, int typ, int prio); 38 | static void IssueSortBanner (int jul); 39 | 40 | /***************************************************************/ 41 | /* */ 42 | /* MakeSortRem */ 43 | /* */ 44 | /* Create a new Sortrem entry - return NULL on failure. */ 45 | /* */ 46 | /***************************************************************/ 47 | static Sortrem *MakeSortRem(int jul, int tim, char const *body, int typ, int prio) 48 | { 49 | Sortrem *new = NEW(Sortrem); 50 | if (!new) return NULL; 51 | 52 | new->text = StrDup(body); 53 | if (!new->text) { 54 | free(new); 55 | return NULL; 56 | } 57 | 58 | new->trigdate = jul; 59 | new->trigtime = tim; 60 | new->typ = typ; 61 | new->priority = prio; 62 | new->next = NULL; 63 | return new; 64 | } 65 | 66 | /***************************************************************/ 67 | /* */ 68 | /* InsertIntoSortBuffer */ 69 | /* */ 70 | /* Insert a reminder into the sort buffer */ 71 | /* */ 72 | /***************************************************************/ 73 | int InsertIntoSortBuffer(int jul, int tim, char const *body, int typ, int prio) 74 | { 75 | Sortrem *new = MakeSortRem(jul, tim, body, typ, prio); 76 | Sortrem *cur = SortedQueue, *prev = NULL; 77 | int ShouldGoAfter; 78 | 79 | if (!new) { 80 | Eprint("%s", ErrMsg[E_NO_MEM]); 81 | IssueSortedReminders(); 82 | SortByDate = 0; 83 | SortByTime = 0; 84 | SortByPrio = 0; 85 | UntimedBeforeTimed = 0; 86 | return E_NO_MEM; 87 | } 88 | 89 | /* Find the correct place in the sorted list */ 90 | if (!SortedQueue) { 91 | SortedQueue = new; 92 | return OK; 93 | } 94 | while (cur) { 95 | ShouldGoAfter = CompareRems(new->trigdate, new->trigtime, new->priority, 96 | cur->trigdate, cur->trigtime, cur->priority, 97 | SortByDate, SortByTime, SortByPrio, UntimedBeforeTimed); 98 | 99 | if (ShouldGoAfter <= 0) { 100 | prev = cur; 101 | cur = cur->next; 102 | } else { 103 | if (prev) { 104 | prev->next = new; 105 | new->next = cur; 106 | } else { 107 | SortedQueue = new; 108 | new->next = cur; 109 | } 110 | return OK; 111 | } 112 | 113 | } 114 | prev->next = new; 115 | new->next = cur; /* For safety - actually redundant */ 116 | return OK; 117 | } 118 | 119 | 120 | /***************************************************************/ 121 | /* */ 122 | /* IssueSortedReminders */ 123 | /* */ 124 | /* Issue all of the sorted reminders and free memory. */ 125 | /* */ 126 | /***************************************************************/ 127 | void IssueSortedReminders(void) 128 | { 129 | Sortrem *cur = SortedQueue; 130 | Sortrem *next; 131 | int olddate = NO_DATE; 132 | 133 | while (cur) { 134 | next = cur->next; 135 | switch(cur->typ) { 136 | case MSG_TYPE: 137 | if (MsgCommand) { 138 | DoMsgCommand(MsgCommand, cur->text); 139 | } else { 140 | if (cur->trigdate != olddate) { 141 | IssueSortBanner(cur->trigdate); 142 | olddate = cur->trigdate; 143 | } 144 | printf("%s", cur->text); 145 | } 146 | break; 147 | 148 | case MSF_TYPE: 149 | FillParagraph(cur->text); 150 | break; 151 | 152 | case RUN_TYPE: 153 | System(cur->text); 154 | break; 155 | } 156 | 157 | free((char *) cur->text); 158 | free(cur); 159 | cur = next; 160 | } 161 | SortedQueue = NULL; 162 | } 163 | /***************************************************************/ 164 | /* */ 165 | /* IssueSortBanner */ 166 | /* */ 167 | /* Issue a daily banner if the function sortbanner() is */ 168 | /* defined to take one argument. */ 169 | /* */ 170 | /***************************************************************/ 171 | static void IssueSortBanner(int jul) 172 | { 173 | char BanExpr[64]; 174 | int y, m, d; 175 | Value v; 176 | char const *s = BanExpr; 177 | DynamicBuffer buf; 178 | 179 | if (UserFuncExists("sortbanner") != 1) return; 180 | 181 | FromJulian(jul, &y, &m, &d); 182 | sprintf(BanExpr, "sortbanner('%04d/%02d/%02d')", y, m+1, d); 183 | y = EvalExpr(&s, &v, NULL); 184 | if (y) return; 185 | if (DoCoerce(STR_TYPE, &v)) return; 186 | DBufInit(&buf); 187 | if (!DoSubstFromString(v.v.str, &buf, jul, NO_TIME)) { 188 | if (*DBufValue(&buf)) printf("%s\n", DBufValue(&buf)); 189 | DBufFree(&buf); 190 | } 191 | DestroyValue(v); 192 | } 193 | 194 | /***************************************************************/ 195 | /* */ 196 | /* CompareRems */ 197 | /* */ 198 | /* Compare two reminders for sorting. Return 0 if they */ 199 | /* compare equal; 1 if rem2 should come after rem1, -1 if */ 200 | /* rem1 should come after rem2. bydate and bytime control */ 201 | /* sorting direction by date and time, resp. */ 202 | /* */ 203 | /***************************************************************/ 204 | int CompareRems(int dat1, int tim1, int prio1, 205 | int dat2, int tim2, int prio2, 206 | int bydate, int bytime, int byprio, 207 | int untimed_first) 208 | { 209 | int dafter, tafter, pafter, uafter; 210 | 211 | dafter = (bydate != SORT_DESCEND) ? 1 : -1; 212 | tafter = (bytime != SORT_DESCEND) ? 1 : -1; 213 | pafter = (byprio != SORT_DESCEND) ? 1 : -1; 214 | uafter = (untimed_first) ? -1 : 1; 215 | 216 | if (dat1 < dat2) return dafter; 217 | if (dat1 > dat2) return -dafter; 218 | 219 | if (tim1 == NO_TIME && tim2 != NO_TIME) { 220 | return -uafter; 221 | } 222 | 223 | if (tim1 != NO_TIME && tim2 == NO_TIME) { 224 | return uafter; 225 | } 226 | 227 | if (tim1 < tim2) return tafter; 228 | if (tim1 > tim2) return -tafter; 229 | 230 | if (prio1 < prio2) return pafter; 231 | if (prio1 > prio2) return -pafter; 232 | 233 | return 0; 234 | } 235 | -------------------------------------------------------------------------------- /src/test-all-languages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Make sure Remind compiles with all supported languages; show 3 | # tstlang.rem output for each language. 4 | 5 | ALL=`grep ^#define lang.h | grep -v '#define LANG' | awk '{print $2}'` 6 | 7 | OUTPUT_COMPILED=lang-compiled.out 8 | OUTPUT_RUNTIME=lang-runtime.out 9 | cat /dev/null > $OUTPUT_COMPILED 10 | cat /dev/null > $OUTPUT_RUNTIME 11 | for i in $ALL ; do 12 | make clean 13 | make -j`nproc` all LANGDEF=-DLANG=$i || exit 1 14 | ./remind -q -r ../tests/tstlang.rem >> $OUTPUT_COMPILED 2>&1 15 | done 16 | 17 | # Rebuild English version 18 | make clean 19 | make -j`nproc` all || exit 1 20 | 21 | ALL=`ls ../include/lang/*.rem` 22 | for i in $ALL; do 23 | ./remind -q -r "-ii=\"$i\"" ../tests/tstlang.rem >> $OUTPUT_RUNTIME 2>&1 24 | done 25 | 26 | exit 0 27 | -------------------------------------------------------------------------------- /src/types.h: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* TYPES.H */ 4 | /* */ 5 | /* Type definitions all dumped here. */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 9 | /* */ 10 | /***************************************************************/ 11 | 12 | #include 13 | #include "dynbuf.h" 14 | 15 | /* Values */ 16 | typedef struct { 17 | char type; 18 | union { 19 | char *str; 20 | int val; 21 | } v; 22 | } Value; 23 | 24 | /* Define the type of operators */ 25 | typedef struct { 26 | char const *name; 27 | char prec; 28 | char type; 29 | int (*func)(void); 30 | } Operator; 31 | 32 | /* Structure for passing in Nargs and out RetVal from functions */ 33 | typedef struct { 34 | int nargs; 35 | Value retval; 36 | } func_info; 37 | 38 | /* Define the type of user-functions */ 39 | typedef struct { 40 | char const *name; 41 | char minargs; 42 | char maxargs; 43 | char is_constant; 44 | int (*func)(func_info *); 45 | } BuiltinFunc; 46 | 47 | /* Define the structure of a variable */ 48 | typedef struct var { 49 | struct var *next; 50 | char name[VAR_NAME_LEN+1]; 51 | char preserve; 52 | Value v; 53 | } Var; 54 | 55 | /* A trigger */ 56 | typedef struct { 57 | int expired; 58 | int wd; 59 | int d; 60 | int m; 61 | int y; 62 | int back; 63 | int delta; 64 | int rep; 65 | int localomit; 66 | int skip; 67 | int until; 68 | int typ; 69 | int once; 70 | int scanfrom; 71 | int from; 72 | int adj_for_last; /* Adjust month/year for use of LAST */ 73 | int need_wkday; /* Set if we *need* a weekday */ 74 | int priority; 75 | int duration_days; /* Duration converted to days to search */ 76 | int eventstart; /* Original event start (datetime) */ 77 | int eventduration; /* Original event duration (minutes) */ 78 | int maybe_uncomputable; /* Suppress "can't compute trigger" warnings */ 79 | int addomit; /* Add trigger date to global OMITs */ 80 | char sched[VAR_NAME_LEN+1]; /* Scheduling function */ 81 | char warn[VAR_NAME_LEN+1]; /* Warning function */ 82 | char omitfunc[VAR_NAME_LEN+1]; /* OMITFUNC function */ 83 | DynamicBuffer tags; 84 | char passthru[PASSTHRU_LEN+1]; 85 | } Trigger; 86 | 87 | /* A time trigger */ 88 | typedef struct { 89 | int ttime; 90 | int nexttime; 91 | int delta; 92 | int rep; 93 | int duration; 94 | } TimeTrig; 95 | 96 | /* The parse pointer */ 97 | typedef struct { 98 | DynamicBuffer pushedToken; /* Pushed-back token */ 99 | char const *text; /* Start of text */ 100 | char const *pos; /* Current position */ 101 | char const *etext; /* Substituted text */ 102 | char const *epos; /* Position in substituted text */ 103 | char const *tokenPushed; /* NULL if no pushed-back token */ 104 | unsigned char isnested; /* Is it a nested expression? */ 105 | unsigned char allownested; 106 | unsigned char expr_happened; /* Did we encounter an [expression] ? */ 107 | unsigned char nonconst_expr; /* Did we encounter a non-constant [expression] ? */ 108 | } Parser; 109 | 110 | typedef Parser *ParsePtr; /* Pointer to parser structure */ 111 | 112 | /* Some useful manifest constants */ 113 | #define NO_BACK 0 114 | #define NO_DELTA 0 115 | #define NO_REP 0 116 | #define NO_WD 0 117 | #define NO_DAY -1 118 | #define NO_MON -1 119 | #define NO_YR -1 120 | #define NO_UNTIL -1 121 | #define NO_ONCE 0 122 | #define ONCE_ONCE 1 123 | #define NO_DATE -1 124 | #define NO_SKIP 0 125 | #define SKIP_SKIP 1 126 | #define BEFORE_SKIP 2 127 | #define AFTER_SKIP 3 128 | 129 | #define NO_TIME INT_MAX 130 | 131 | #define NO_PRIORITY 5000 /* Default priority is midway between 0 and 9999 */ 132 | 133 | #define NO_TYPE 0 134 | #define MSG_TYPE 1 135 | #define RUN_TYPE 2 136 | #define CAL_TYPE 3 137 | #define SAT_TYPE 4 138 | #define PS_TYPE 5 139 | #define PSF_TYPE 6 140 | #define MSF_TYPE 7 141 | #define PASSTHRU_TYPE 8 142 | 143 | 144 | /* DEFINES for debugging flags */ 145 | #define DB_PRTLINE 1 146 | #define DB_PRTEXPR 2 147 | #define DB_PRTTRIG 4 148 | #define DB_DUMP_VARS 8 149 | #define DB_ECHO_LINE 16 150 | #define DB_TRACE_FILES 32 151 | 152 | /* Enumeration of the tokens */ 153 | enum TokTypes 154 | { T_Illegal, 155 | /* Commands first */ 156 | T_Rem, T_Push, T_Pop, T_Preserve, T_Include, T_IncludeR, T_IncludeCmd, T_If, T_Else, T_EndIf, 157 | T_IfTrig, T_ErrMsg, 158 | T_Set, T_UnSet, T_Fset, T_Omit, T_Banner, T_Exit, 159 | T_AddOmit, 160 | T_WkDay, 161 | T_Month, T_Time, T_Date, T_DateTime, 162 | T_Skip, T_At, T_RemType, T_Until, T_Year, T_Day, T_Rep, T_Delta, 163 | T_Back, T_BackAdj, 164 | T_Once, 165 | T_Empty, 166 | T_Comment, 167 | T_Number, 168 | T_Clr, 169 | T_Debug, 170 | T_Dumpvars, 171 | T_Scanfrom, 172 | T_Flush, 173 | T_Priority, 174 | T_Sched, 175 | T_Warn, 176 | T_Tag, 177 | T_Duration, 178 | T_LongTime, 179 | T_OmitFunc, 180 | T_Through, 181 | T_MaybeUncomputable, 182 | T_Ordinal, 183 | T_In, 184 | T_LastBack 185 | }; 186 | 187 | /* The structure of a token */ 188 | typedef struct { 189 | char *name; 190 | char MinLen; 191 | enum TokTypes type; 192 | int val; 193 | } Token; 194 | 195 | /* Flags for the state of the "if" stack */ 196 | #define IF_TRUE 0 197 | #define IF_FALSE 1 198 | #define BEFORE_ELSE 0 199 | #define AFTER_ELSE 2 200 | #define IF_MASK 3 201 | #define IF_TRUE_MASK 1 202 | #define IF_ELSE_MASK 2 203 | 204 | /* Flags for the DoSubst function */ 205 | #define NORMAL_MODE 0 206 | #define CAL_MODE 1 207 | #define ADVANCE_MODE 2 208 | 209 | #define QUOTE_MARKER 1 /* Unlikely character to appear in reminder */ 210 | 211 | /* Flags for disabling run */ 212 | #define RUN_CMDLINE 1 213 | #define RUN_SCRIPT 2 214 | #define RUN_NOTOWNER 4 215 | 216 | /* Flags for the SimpleCalendar format */ 217 | #define SC_AMPM 0 /* Time shown as 3:00am, etc. */ 218 | #define SC_MIL 1 /* 24-hour time format */ 219 | #define SC_NOTIME 2 /* Do not display time in SC format. */ 220 | 221 | /* Flags for sorting */ 222 | #define SORT_NONE 0 223 | #define SORT_ASCEND 1 224 | #define SORT_DESCEND 2 225 | 226 | /* Flags for FROM / SCANFROM */ 227 | #define SCANFROM_TYPE 0 228 | #define FROM_TYPE 1 229 | 230 | /* PS Calendar levels */ 231 | 232 | /* Original interchange format */ 233 | #define PSCAL_LEVEL1 1 234 | 235 | /* Line-by-line JSON */ 236 | #define PSCAL_LEVEL2 2 237 | 238 | /* Pure JSON */ 239 | #define PSCAL_LEVEL3 3 240 | 241 | #define TERMINAL_BACKGROUND_UNKNOWN 0 242 | #define TERMINAL_BACKGROUND_DARK 1 243 | #define TERMINAL_BACKGROUND_LIGHT 2 244 | -------------------------------------------------------------------------------- /src/utils.c: -------------------------------------------------------------------------------- 1 | /***************************************************************/ 2 | /* */ 3 | /* UTILS.C */ 4 | /* */ 5 | /* Useful utility functions. */ 6 | /* */ 7 | /* This file is part of REMIND. */ 8 | /* Copyright (C) 1992-2022 by Dianne Skoll */ 9 | /* */ 10 | /***************************************************************/ 11 | 12 | static char const DontEscapeMe[] = 13 | "1234567890_-=+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@.,/"; 14 | 15 | #include "config.h" 16 | #include "err.h" 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include "types.h" 24 | #include "globals.h" 25 | #include "protos.h" 26 | 27 | #define UPPER(c) toupper(c) 28 | 29 | /***************************************************************/ 30 | /* */ 31 | /* StrnCpy */ 32 | /* */ 33 | /* Just like strncpy EXCEPT we ALWAYS copy the trailing 0. */ 34 | /* */ 35 | /***************************************************************/ 36 | char *StrnCpy(char *dest, char const *source, int n) 37 | { 38 | char *odest = dest; 39 | 40 | while (n-- && (*dest++ = *source++)) ; 41 | if (*(dest-1)) *dest = 0; 42 | return odest; 43 | } 44 | 45 | /***************************************************************/ 46 | /* */ 47 | /* StrMatch */ 48 | /* */ 49 | /* Checks that two strings match (case-insensitive) to at */ 50 | /* least the specified number of characters, or the length */ 51 | /* of the first string, whichever is greater. */ 52 | /* */ 53 | /***************************************************************/ 54 | int StrMatch(char const *s1, char const *s2, int n) 55 | { 56 | int l; 57 | if ((l = strlen(s1)) < n) return 0; 58 | return !StrinCmp(s1, s2, l); 59 | } 60 | 61 | /***************************************************************/ 62 | /* */ 63 | /* StrinCmp - compare strings, case-insensitive */ 64 | /* */ 65 | /***************************************************************/ 66 | int StrinCmp(char const *s1, char const *s2, int n) 67 | { 68 | register int r; 69 | while (n && *s1 && *s2) { 70 | n--; 71 | r = UPPER(*s1) - UPPER(*s2); 72 | if (r) return r; 73 | s1++; 74 | s2++; 75 | } 76 | if (n) return (UPPER(*s1) - UPPER(*s2)); else return 0; 77 | } 78 | 79 | /***************************************************************/ 80 | /* */ 81 | /* StrDup */ 82 | /* */ 83 | /* Like ANSI strdup */ 84 | /* */ 85 | /***************************************************************/ 86 | char *StrDup(char const *s) 87 | { 88 | char *ret = malloc(strlen(s)+1); 89 | if (!ret) return NULL; 90 | strcpy(ret, s); 91 | return ret; 92 | } 93 | 94 | /***************************************************************/ 95 | /* */ 96 | /* StrCmpi */ 97 | /* */ 98 | /* Compare strings, case insensitive. */ 99 | /* */ 100 | /***************************************************************/ 101 | int StrCmpi(char const *s1, char const *s2) 102 | { 103 | int r; 104 | while (*s1 && *s2) { 105 | r = UPPER(*s1) - UPPER(*s2); 106 | if (r) return r; 107 | s1++; 108 | s2++; 109 | } 110 | return UPPER(*s1) - UPPER(*s2); 111 | } 112 | 113 | /***************************************************************/ 114 | /* */ 115 | /* DateOK */ 116 | /* */ 117 | /* Return 1 if the date is OK, 0 otherwise. */ 118 | /* */ 119 | /***************************************************************/ 120 | int DateOK(int y, int m, int d) 121 | { 122 | if (d < 1 || 123 | m < 0 || 124 | y < BASE || 125 | m > 11 || 126 | y > BASE + YR_RANGE || 127 | d > DaysInMonth(m, y) ) return 0; 128 | else return 1; 129 | } 130 | 131 | /* Functions designed to defeat gcc optimizer */ 132 | 133 | int _private_mul_overflow(int a, int b) 134 | { 135 | double aa = (double) a; 136 | double bb = (double) b; 137 | 138 | if (aa*bb > (double) INT_MAX || aa*bb < (double) INT_MIN) { 139 | return 1; 140 | } 141 | return 0; 142 | } 143 | 144 | int _private_add_overflow(int a, int b) 145 | { 146 | double aa = (double) a; 147 | double bb = (double) b; 148 | 149 | if (aa+bb < (double) INT_MIN) return 1; 150 | if (aa+bb > (double) INT_MAX) return 1; 151 | return 0; 152 | } 153 | int _private_sub_overflow(int a, int b) 154 | { 155 | double aa = (double) a; 156 | double bb = (double) b; 157 | 158 | if (aa-bb < (double) INT_MIN) return 1; 159 | if (aa-bb > (double) INT_MAX) return 1; 160 | return 0; 161 | } 162 | 163 | int 164 | ShellEscape(char const *in, DynamicBuffer *out) 165 | { 166 | while(*in) { 167 | if (!strchr(DontEscapeMe, *in)) { 168 | if (DBufPutc(out, '\\') != OK) return E_NO_MEM; 169 | } 170 | if (DBufPutc(out, *in++) != OK) return E_NO_MEM; 171 | } 172 | return OK; 173 | } 174 | 175 | /* Call-stack for printing errors from user-defined functions */ 176 | typedef struct cs_s { 177 | struct cs_s *next; 178 | char const *filename; 179 | char const *func; 180 | int lineno; 181 | } cs; 182 | 183 | static cs *callstack = NULL; 184 | 185 | static void 186 | destroy_cs(cs *entry) 187 | { 188 | if (entry->filename) free( (void *) entry->filename); 189 | if (entry->func) free( (void *) entry->func); 190 | free( (void *) entry); 191 | } 192 | 193 | 194 | int 195 | push_call(char const *filename, char const *func, int lineno) 196 | { 197 | cs *entry = NEW(cs); 198 | if (!entry) { 199 | return E_NO_MEM; 200 | } 201 | entry->next = NULL; 202 | entry->filename = StrDup(filename); 203 | entry->func = StrDup(func); 204 | entry->lineno = lineno; 205 | if (!entry->filename || !entry->func) { 206 | destroy_cs(entry); 207 | return E_NO_MEM; 208 | } 209 | entry->next = callstack; 210 | callstack = entry; 211 | return OK; 212 | } 213 | 214 | void 215 | clear_callstack(void) 216 | { 217 | cs *entry = callstack; 218 | cs *next; 219 | while(entry) { 220 | next = entry->next; 221 | destroy_cs(entry); 222 | entry = next; 223 | } 224 | callstack = NULL; 225 | } 226 | 227 | int 228 | have_callstack(void) 229 | { 230 | if (callstack) return 1; 231 | return 0; 232 | } 233 | 234 | static void 235 | print_callstack_aux(FILE *fp, cs *entry) 236 | { 237 | if (entry) { 238 | print_callstack_aux(fp, entry->next); 239 | fprintf(fp, "\n"); 240 | (void) fprintf(fp, "%s(%d): In function `%s'", entry->filename, entry->lineno, entry->func); 241 | } 242 | } 243 | 244 | int 245 | print_callstack(FILE *fp) 246 | { 247 | print_callstack_aux(fp, callstack); 248 | if (callstack) return 1; 249 | return 0; 250 | } 251 | 252 | void 253 | pop_call(void) 254 | { 255 | cs *entry = callstack; 256 | if (entry) { 257 | callstack = entry->next; 258 | destroy_cs(entry); 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /src/version.h.in: -------------------------------------------------------------------------------- 1 | #define VERSION "@VERSION@" 2 | -------------------------------------------------------------------------------- /tests/colors.rem: -------------------------------------------------------------------------------- 1 | REM 28 SPECIAL COLOR 0 0 0 Black 2 | REM 28 SPECIAL COLOR 65 0 0 Dim Red 3 | REM 28 SPECIAL COLOR 0 65 0 Dim Green 4 | REM 28 SPECIAL COLOR 0 0 65 Dim Blue 5 | REM 28 SPECIAL COLOR 0 65 65 Dim Cyan 6 | REM 28 SPECIAL COLOR 65 0 65 Dim Magenta 7 | REM 28 SPECIAL COLOR 65 65 0 Dim Yellow 8 | REM 28 SPECIAL COLOR 65 65 65 Dim White 9 | 10 | REM 28 SPECIAL COLOUR 129 0 0 Bright Red 11 | REM 28 SPECIAL COLOUR 0 129 0 Bright Green 12 | REM 28 SPECIAL COLOUR 0 0 129 Bright Blue 13 | REM 28 SPECIAL COLOUR 0 129 129 Bright Cyan 14 | REM 28 SPECIAL COLOUR 129 0 129 Bright Magenta 15 | REM 28 SPECIAL COLOUR 129 129 0 Bright Yellow 16 | REM 28 SPECIAL COLOUR 129 129 129 Bright White 17 | 18 | -------------------------------------------------------------------------------- /tests/file.ps: -------------------------------------------------------------------------------- 1 | (Second-Bit-Of-PS) 2 | -------------------------------------------------------------------------------- /tests/file2.ps: -------------------------------------------------------------------------------- 1 | (Fourth-Bit-Of-PS) -------------------------------------------------------------------------------- /tests/include_dir/01.rem: -------------------------------------------------------------------------------- 1 | REM 15 MSG 01 2 | -------------------------------------------------------------------------------- /tests/include_dir/02.rem: -------------------------------------------------------------------------------- 1 | REM 15 MSG 02 2 | DO subdir/04.rem 3 | INCLUDE subdir/04.rem 4 | -------------------------------------------------------------------------------- /tests/include_dir/03.notrem: -------------------------------------------------------------------------------- 1 | REM MSG IGNORE 2 | -------------------------------------------------------------------------------- /tests/include_dir/04cantread.rem: -------------------------------------------------------------------------------- 1 | REM 15 MSG You can't read this file. 2 | -------------------------------------------------------------------------------- /tests/include_dir/subdir/04.rem: -------------------------------------------------------------------------------- 1 | REM 16 MSG Should be included by 02.rem 2 | -------------------------------------------------------------------------------- /tests/include_dir_no_rems/03.notrem: -------------------------------------------------------------------------------- 1 | REM MSG IGNORE 2 | -------------------------------------------------------------------------------- /tests/include_test.rem: -------------------------------------------------------------------------------- 1 | INCLUDE include_dir 2 | INCLUDE include_dir_no_rems 3 | INCLUDE nonexistent_include_dir 4 | 5 | REM 15 MSG Whee!!!! 6 | -------------------------------------------------------------------------------- /tests/purge_dir/f1.rem: -------------------------------------------------------------------------------- 1 | # This is f1.rem 2 | INCLUDE [filedir()]/f2.rem 3 | INCLUDE [filedir()]/f2.rem 4 | 5 | REM 1 Oct 1991 MSG old1. 6 | 7 | REM Monday UNTIL 1 Oct 1991 MSG old2. -------------------------------------------------------------------------------- /tests/purge_dir/f2.rem: -------------------------------------------------------------------------------- 1 | # This is f2.rem 2 | 3 | REM 3 feb 2012 MSG new 4 | REM 3 1998 MSG old 5 | 6 | INCLUDE [filedir()]/f3.rem 7 | -------------------------------------------------------------------------------- /tests/purge_dir/f3.rem: -------------------------------------------------------------------------------- 1 | # This is f3.rem 2 | 3 | REM Mon MSG repeat 4 | 5 | REM Mon SATISFY [1] MSG repeat 6 | 7 | IF 0 8 | REM 1991 MSG wookie 9 | ENDIF 10 | 11 | IF 1 12 | REM 1991 MSG wookie 13 | ENDIF 14 | 15 | IFTRIG 1991 16 | REM MSG wookie 17 | ENDIF 18 | 19 | # More complex conditional statements 20 | IF 1 21 | IF 0 22 | REM 1991 MSG wookie 23 | ELSE 24 | REM 1991 MSG wookie 25 | ENDIF 26 | ELSE 27 | IF 1 28 | REM 1991 MSG wookie 29 | ELSE 30 | REM 1991 MSG wookie 31 | ENDIF 32 | ENDIF 33 | 34 | REM [1990+1] MSG old-with-constant-expression 35 | 36 | REM [1990+1] \ 37 | MSG Continued line-old-with-constant-expression 38 | 39 | REM 1990 \ 40 | MSG expired-continued-line 41 | 42 | set y 1990 43 | 44 | REM [y+1] MSG old-with-nonconstant-expression 45 | 46 | # A comment that should be preserved 47 | 48 | #!P A comment that should be nuked because it \ 49 | starts with #!P 50 | 51 | REM [y+1] \ 52 | MSG Continued-line-old-with-nonconstant-expression 53 | 54 | OMIT 25 Dec MSG woaaahh! 55 | OMIT 24 Dec 56 | 57 | OMIT 1 Jan 1992 MSG woaaahah... expired 58 | OMIT 2 Jan 1992 59 | 60 | # Complicated expressions 61 | SET a 3 62 | FSET const(x) x+3 63 | FSET nonconst(x) x+a 64 | 65 | REM [const(5)] Jan 1992 MSG expired... should be commented out 66 | REM [const(a)] Jan 1992 MSG nonconstant expression 67 | REM [nonconst(5)] Jan 1992 MSG nonconstant expression 68 | REM [value("a")] Jan 1992 MSG nonconstant expression 69 | 70 | IF 0 71 | # A comment in a false IF block 72 | #!P This should be nuked 73 | ENDIF 74 | 75 | # Busted line 76 | REM [0/0] Jan 1992 MSG ouch 77 | 78 | ERRMSG blorky 79 | FLUSH 80 | SET a 1 81 | FSET a(x) x*x 82 | UNSET a 83 | CLEAR-OMIT-CONTEXT 84 | PUSH-OMIT-CONTEXT 85 | POP-OMIT-CONTEXT 86 | BANNER wow 87 | DEBUG +x 88 | DEBUG -x 89 | DUMP $ 90 | EXIT 0 91 | PRESERVE i 92 | 93 | -------------------------------------------------------------------------------- /tests/runinc.rem: -------------------------------------------------------------------------------- 1 | set s shell("echo 3") 2 | run on 3 | set s shell("echo 3") 4 | -------------------------------------------------------------------------------- /tests/runtest.rem: -------------------------------------------------------------------------------- 1 | run off 2 | set a shell("echo 2") 3 | run on 4 | set a shell("echo 2") 5 | run off 6 | include ../tests/runinc.rem 7 | -------------------------------------------------------------------------------- /tests/scripts.rem: -------------------------------------------------------------------------------- 1 | # This is a test file that tests the 2 | # rendering of various Unicode characters. 3 | # It also tests some of the features of 4 | # the Pango/Cairo-based rem2pdf program. 5 | 6 | SET $Sunday "እሁድ" 7 | SET $Monday "一" 8 | SET $Tuesday "mardi" 9 | SET $Wednesday "水曜日" 10 | SET $Thursday "четвер" 11 | SET $Friday "piątek" 12 | SET $Saturday "יום שבת" 13 | 14 | SET $January "January" 15 | SET $February "février" 16 | SET $March "März" 17 | SET $April "אַפּרִיל" 18 | SET $May "ግንቦት" 19 | SET $June "Чэрвень" 20 | SET $July "تموز" 21 | SET $August "Наймдугаар сар" 22 | SET $September "Вересень" 23 | SET $October "październik" 24 | SET $November "נאוועמבער" 25 | SET $December "दिसंबर" 26 | 27 | REM 1 MSG Përkujtues 28 | REM 2 SPECIAL SHADE 192 192 255 29 | REM 2 MSG تذكير 30 | REM 3 MSG 提醒提醒提醒提醒提醒提醒提醒提醒 31 | REM 4 MSG રીમાઇન્ડર 32 | REM 5 MSG Emlékeztető 33 | REM 6 MSG Áminning 34 | REM 7 SPECIAL PANGO תִזכּוֹרֶת 35 | REM 8 MSG अनुस्मारक 36 | REM 9 SPECIAL COLOR 0 0 192 Эскертүү 37 | REM 10 SPECIAL COLOR 0 192 0 Напоминание 38 | REM 11 SPECIAL COLOR 192 0 0 Υπενθύμιση 39 | REM 12 SPECIAL PANGO Bold and Italic and underline 40 | REM 12 MSG Hello 41 | REM 28 SPECIAL PANGO Very Fancy 42 | 43 | REM 13 SPECIAL PANGO Invalid 44 | REM 13 MSG Hello Again 45 | 46 | REM 15 SPECIAL PANGO @1,-1 [hebday($U)] [hebmon($U)] Rise [sunrise($U)] Set [sunset($U)] 47 | 48 | REM 16 MSG یادآور 49 | REM 17 MSG Lời nhắc nhở 50 | REM 18 MSG Påminnelse 51 | REM 19 MSG דערמאָנונג 52 | REM 20 MSG Hatırlatma 53 | REM 21 SPECIAL PANGO Нагадування 54 | REM 22 MSG შეხსენება 55 | REM 23 MSG เตือนความจำ 56 | REM 24 MSG リマインダー 57 | REM 25 MSG Искә төшерү 58 | REM 26 MSG Напомняне 59 | REM 27 MSG ഓർമ്മപ്പെടുത്തൽ 60 | REM 28 MSG リaリaaリaaリaaリaaリaaリaaリaaリaaリaaリa 61 | REM 1 SPECIAL SHADE 192 255 192 62 | REM 14 SPECIAL SHADE 255 192 192 63 | REM 14 SPECIAL PANGO This is so fancy 64 | REM [moondate(0)] SPECIAL MOON 0 65 | REM [moondate(1)] SPECIAL MOON 1 66 | REM [moondate(2)] SPECIAL MOON 2 -1 -1 [moontime(2)] 67 | REM [moondate(3)] SPECIAL MOON 3 -1 -1 [moontime(3)] 68 | 69 | REM Mon SPECIAL WEEK (W[weekno(today())]) 70 | 71 | REM SATISFY [$Td != 15] SPECIAL PANGO @1,-1 Rise [sunrise($U)] Set [sunset($U)] 72 | -------------------------------------------------------------------------------- /tests/shade.rem: -------------------------------------------------------------------------------- 1 | set $MinsFromUTC -240 2 | set $CalcUTC 0 3 | set $Location "Ottawa" 4 | set $LongDeg 75 5 | set $LongMin 39 6 | set $LongSec 0 7 | set $LatDeg 45 8 | set $LatMin 24 9 | set $LatSec 0 10 | 11 | IF $PSCAL 12 | [trigger(moondate(0))] SPECIAL MOON 0 -1 -1 [moontime(0)] 13 | [trigger(moondate(1))] SPECIAL MOON 1 -1 -1 [moontime(1)] 14 | [trigger(moondate(2))] SPECIAL MOON 2 -1 -1 [moontime(2)] 15 | [trigger(moondate(3))] SPECIAL MOON 3 -1 -1 [moontime(3)] 16 | ENDIF 17 | 18 | REM 4 PS (First-Bit-Of-PS) 19 | REM 4 PSFILE file.ps 20 | REM 4 PS (Third-Bit-Of-PS) 21 | REM 4 PSFILE file2.ps 22 | 23 | REM Mon SPECIAL SHADE 255 255 255 24 | REM Tue SPECIAL SHADE 255 255 204 25 | REM Wed SPECIAL SHADE 255 204 255 26 | REM Thu SPECIAL SHADE 204 255 255 27 | REM Fri SPECIAL SHADE 255 204 204 28 | REM Sat SPECIAL SHADE 204 255 204 29 | REM Sun SPECIAL SHADE 204 204 255 30 | 31 | # This should be ignored by rem2ps 32 | REM SPECIAL HTML FOO 33 | -------------------------------------------------------------------------------- /tests/sun.rem: -------------------------------------------------------------------------------- 1 | SET $LatDeg 45 2 | SET $LatMin 24 3 | SET $LatSec 0 4 | SET $LongDeg 75 5 | SET $LongMin 39 6 | SET $LongSec 0 7 | SET $MinsFromUTC -300 8 | SET $CalcUTC 0 9 | 10 | MSG Dawn: [dawn()] 11 | MSG Sunrise: [sunrise()] 12 | MSG Sunset: [sunset()] 13 | MSG Dusk: [dusk()] 14 | -------------------------------------------------------------------------------- /tests/test-addomit.rem: -------------------------------------------------------------------------------- 1 | REM Mon 1 Sep SCANFROM -7 ADDOMIT MSG Labour Day 2 | REM 6 Sep 2021 AFTER MSG Should be bumped to Tuesday -------------------------------------------------------------------------------- /tests/test-for-backends.rem: -------------------------------------------------------------------------------- 1 | # This file is designed for testing how back-ends 2 | # handle SPECIALs, including SPECIALS they don't understand 3 | # If you're writing a back-end, test it by feeding it the output 4 | # of: remind -pp test-for-backends.rem 5 | 6 | # Color and shade 7 | REM 1 SPECIAL COLOR 128 0 0 Red 8 | REM 2 SPECIAL COLOUR 0 128 0 British Green 9 | REM 3 SPECIAL SHADE 192 192 255 10 | 11 | # Moon 12 | REM [moondate(0)] SPECIAL MOON 0 -1 -1 [moontime(0)] 13 | REM [moondate(1)] SPECIAL MOON 1 -1 -1 [moontime(1)] 14 | REM [moondate(2)] SPECIAL MOON 2 -1 -1 [moontime(2)] 15 | REM [moondate(3)] SPECIAL MOON 3 -1 -1 [moontime(3)] 16 | 17 | # Week 18 | REM Monday SPECIAL WEEK (W[weekno()]) 19 | 20 | # PostScript 21 | REM Wed PS Border Border 2 div moveto /Helvetica-Oblique findfont 6 scalefont setfont (oof!) show 22 | 23 | # A SPECIAL that should be ignored 24 | REM 15 SPECIAL RANDOM-STUFF ignore me and be happy 25 | 26 | # A normal reminder 27 | REM 16 MSG A normal reminder 28 | -------------------------------------------------------------------------------- /tests/test2.rem: -------------------------------------------------------------------------------- 1 | # Make things sane 2 | set $TimeSep ":" 3 | set $DateSep "/" 4 | set $LatDeg 45 5 | set $LatMin 24 6 | set $LatSec 0 7 | set $Location "Ottawa" 8 | set $LongDeg 75 9 | set $LongMin 39 10 | set $LongSec 0 11 | 12 | clear-omit-context 13 | 14 | omit 14 aug 15 | 16 | # Test the SPECIAL COLOR escapes 17 | REM WED +2 SPECIAL COLOR 0 0 255 %"Blue Wednesday%" is %b 18 | REM THU SPECIAL COLOR 255 0 0 Red Thursday 19 | 20 | # Test SPECIAL SHADE 21 | REM FRI SPECIAL SHADE 0 255 0 22 | 23 | # Test SPECIAL MOON 24 | REM 12 AUG SPECIAL MOON 0 25 | 26 | # Test nonomitted 27 | REM MSG [nonomitted('2007-08-01', today())] NonOmit-1 28 | REM MSG [nonomitted('2007-08-01', today(), "Sat", "Sun")] NonOmit-2 29 | 30 | # Test SPECIAL COLOR with an AT clause 31 | REM 20 AUG AT 13:45 SPECIAL COLOR 6 7 8 Mooo! 32 | 33 | # Test SPECIAL PostScript with and without AT clause 34 | REM 21 AUG AT 1:55 SPECIAL PostScript (wookie) show 35 | REM 22 AUG SPECIAL PostScript (cabbage) show 36 | 37 | # Test a random SPECIAL with and without AT 38 | REM 23 AUG AT 16:44 SPECIAL blort snoo glup 39 | REM 24 AUG SPECIAL blort gulp wookie 40 | 41 | # Bug discovered by Paul Pelzl 42 | OMIT 13 August 43 | REM 6 August 2007 *7 SKIP SATISFY [1] MSG Blort 44 | -------------------------------------------------------------------------------- /tests/test3.rem: -------------------------------------------------------------------------------- 1 | REM 1 AT 11:00 MSG Wookie 2 | REM 1 AT 12:00 MSG Cookie 3 | REM 1 AT 13:00 MSG Snookie 4 | 5 | REM 1 AT 11:00 DURATION 0:45 MSG Lettuce 6 | REM 1 AT 12:00 DURATION 0:45 MSG Cabbage 7 | REM 1 AT 13:00 DURATION 0:45 MSG Tomato 8 | 9 | REM 1 AT 11:00 DURATION 1:45 MSG Apple 10 | REM 1 AT 12:00 DURATION 2:45 MSG Pear 11 | REM 1 AT 13:00 DURATION 3:45 MSG Grape 12 | 13 | REM 1 AT 11:00 DURATION 14:45 MSG Green 14 | REM 1 AT 12:00 DURATION 14:45 MSG Blue 15 | REM 1 AT 13:00 DURATION 14:45 MSG Red 16 | 17 | REM 1 AT 11:00 DURATION 24:45 MSG Yellow 18 | REM 1 AT 12:00 DURATION 24:45 MSG Orange 19 | REM 1 AT 13:00 DURATION 24:45 MSG Magenta 20 | 21 | REM 1 AT 11:00 DURATION 36:45 MSG Purple 22 | REM 1 AT 12:00 DURATION 36:45 MSG Black 23 | REM 1 AT 13:00 DURATION 36:45 MSG Brown 24 | 25 | REM 1 AT 11:00 DURATION 48:45 MSG Sad 26 | REM 1 AT 12:00 DURATION 48:45 MSG Happy 27 | REM 1 AT 13:00 DURATION 48:45 MSG Strange 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/utf-8.rem: -------------------------------------------------------------------------------- 1 | MSG ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский ру́сский 2 | MSG עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית עִבְרִית 3 | 4 | Wed MSG With tabs and spaces -------------------------------------------------------------------------------- /unconfigure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Unconfiguring Remind..." 4 | echo rm -f config.cache config.log config.status src/Makefile src/config.h src/version.h www/Makefile rem2html/Makefile 5 | rm -f config.cache config.log config.status src/Makefile src/config.h src/version.h www/Makefile rem2html/Makefile 6 | exit 0 7 | -------------------------------------------------------------------------------- /www/Makefile.in: -------------------------------------------------------------------------------- 1 | # Makefile.in for installing WWW server calendar scripts 2 | # This file is part of REMIND. 3 | # Copyright (C) 1992-2018 by Dianne Skoll 4 | 5 | # The complete path to where the scripts actually live, as seen by 6 | # the UNIX operating system. 7 | SCRIPTDIR = /usr/lib/cgi-bin 8 | 9 | # Where the scripts live as seen by the web browser. 10 | CGIDIR = /cgi-bin 11 | 12 | # The complete path to the directory containing the HTML file "calendar.html". 13 | # This is a sample file containing links to all the scripts. This path 14 | # should be the path as seen by the UNIX operating system 15 | HTMLDIR = /var/www/remind 16 | 17 | # Where you stick images and CSS files, as seen by UNIX 18 | IMAGEDIR = /var/www/remind/resources 19 | 20 | # Where images and CSS files are, as seen by web browsers 21 | IMAGEBASE = /remind/resources 22 | 23 | # Set by configure - don't touch. 24 | srcdir=@srcdir@ 25 | prefix=@prefix@ 26 | exec_prefix=@exec_prefix@ 27 | mandir=@mandir@ 28 | bindir=@bindir@ 29 | datadir=@datadir@ 30 | datarootdir=@datarootdir@ 31 | 32 | # Where do Remind and Rem2PS executables live? 33 | REMIND = $(bindir)/remind 34 | REM2PS = $(bindir)/rem2ps 35 | REM2HTML = $(bindir)/rem2html 36 | # If your Web server requires CGI programs to have a .cgi suffix, use 37 | # the next line. Otherwise, comment it out 38 | CGISUFFIX=.cgi 39 | 40 | # Don't change stuff below here. 41 | # -------------------------------------------------------------------- 42 | 43 | # Construct a rotten mean nasty sed script to do the dirty work 44 | SEDSCRIPT = -e 's@%CGIDIR%@$(CGIDIR)@g' \ 45 | -e 's@%SCRIPTDIR%@$(SCRIPTDIR)@g' \ 46 | -e 's@%REMIND%@$(REMIND)@g' \ 47 | -e 's@%IMAGEBASE%@$(IMAGEBASE)@g' \ 48 | -e 's@%REM2PS%@$(REM2PS)@g' \ 49 | -e 's@%REM2HTML%@$(REM2HTML)@g' \ 50 | -e 's@cal_dispatch@cal_dispatch$(CGISUFFIX)@g' \ 51 | 52 | all: 53 | @echo "Edit the Makefile; then type 'make install' to install" 54 | @echo "the www server scripts." 55 | 56 | # OK, it's abominable. But it works... 57 | install: 58 | -mkdir -p $(DESTDIR)$(SCRIPTDIR) 59 | -mkdir -p $(DESTDIR)$(HTMLDIR) 60 | cp calps hebdate hebps hebhtml moon sunrise sunset $(DESTDIR)$(SCRIPTDIR) 61 | sed $(SEDSCRIPT) < cal_dispatch-DIST > $(DESTDIR)$(SCRIPTDIR)/cal_dispatch$(CGISUFFIX) 62 | sed $(SEDSCRIPT) < hebdate.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/hebdate.rem 63 | sed $(SEDSCRIPT) < moon.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/moon.rem 64 | sed $(SEDSCRIPT) < sunrise.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/sunrise.rem 65 | sed $(SEDSCRIPT) < sunset.rem-DIST > $(DESTDIR)$(SCRIPTDIR)/sunset.rem 66 | cp blank.rem $(DESTDIR)$(SCRIPTDIR)/blank.rem 67 | sed $(SEDSCRIPT) < calendar.html-DIST > $(DESTDIR)$(HTMLDIR)/calendar.html 68 | sed $(SEDSCRIPT) < hebhtml > $(DESTDIR)$(SCRIPTDIR)/hebhtml 69 | chmod 644 $(DESTDIR)$(SCRIPTDIR)/sunrise.rem 70 | chmod 644 $(DESTDIR)$(SCRIPTDIR)/moon.rem 71 | chmod 644 $(DESTDIR)$(SCRIPTDIR)/hebdate.rem 72 | chmod 644 $(DESTDIR)$(SCRIPTDIR)/sunset.rem 73 | chmod 644 $(DESTDIR)$(SCRIPTDIR)/blank.rem 74 | chmod 644 $(DESTDIR)$(HTMLDIR)/calendar.html 75 | chmod 755 $(DESTDIR)$(SCRIPTDIR)/cal_dispatch$(CGISUFFIX) 76 | chmod 755 $(DESTDIR)$(SCRIPTDIR)/calps $(DESTDIR)$(SCRIPTDIR)/hebdate \ 77 | $(DESTDIR)$(SCRIPTDIR)/hebps $(DESTDIR)$(SCRIPTDIR)/moon \ 78 | $(DESTDIR)$(SCRIPTDIR)/sunrise $(DESTDIR)$(SCRIPTDIR)/sunset \ 79 | $(DESTDIR)$(SCRIPTDIR)/hebhtml \ 80 | 81 | -mkdir -p $(DESTDIR)$(IMAGEDIR) 82 | cp rem-default.css *.png $(DESTDIR)$(IMAGEDIR) 83 | chmod 644 $(DESTDIR)$(IMAGEDIR)/rem-default.css $(DESTDIR)$(IMAGEDIR)/*.png 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /www/README: -------------------------------------------------------------------------------- 1 | README 2 | 3 | HTML Hebrew Calendar Server 4 | 5 | This is a rudimentary Hebrew calendar server for the WWW. It 6 | supplies local sunrise and sunset times, moon phases, upcoming Jewish 7 | holidays, and PostScript calendars. It only works under UNIX. I've 8 | only tested it with Linux running NCSA's httpd and Apache's httpd, but 9 | it should work on any UNIX web server. 10 | 11 | To install it, you need the Remind package, available via ftp from 12 | https://dianne.skoll.ca/projects/remind/ You should install Remind, 13 | setting the latitude, longitude, location and time zone as appropriate 14 | for your machine. 15 | 16 | Once you have Remind installed, follow these steps to set up your WWW 17 | server: 18 | 19 | 1) Edit the Makefile in this directory. See the comments in the Makefile 20 | for details. 21 | 22 | 2) Make sure "rem2html" is installed. 23 | 24 | 3) Type "make install" 25 | 26 | 4) Test it out. It will generate links of the form: 27 | 28 | http://www.your_server.com/your_cgi-bin/cal_dispatch?what 29 | 30 | where "what" is one of: 31 | sunrise -- show info about sunrise times. 32 | sunset -- show info about sunset times. 33 | hebdate -- show today's Hebrew date. 34 | calps -- get a blank PostScript calendar. 35 | moon -- show info about moon phases. 36 | hebps -- get a PostScript calendar with Jewish holidays. 37 | hebhtml -- get an HTML version of the above (requires Perl.) 38 | 39 | All of these links will be set up in a sample HTML document 40 | called "calendar.html" and installed in the HTMLDIR you specified 41 | in the Makefile. 42 | 43 | 4) Enjoy! 44 | -------------------------------------------------------------------------------- /www/blank.rem: -------------------------------------------------------------------------------- 1 | [moondate(0)] SPECIAL MOON 0 2 | [moondate(1)] SPECIAL MOON 1 3 | [moondate(2)] SPECIAL MOON 2 4 | [moondate(3)] SPECIAL MOON 3 5 | REM Monday SPECIAL WEEK (W[weekno()]) 6 | -------------------------------------------------------------------------------- /www/cal_dispatch-DIST: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of REMIND. 4 | # Copyright (C) 1992-2018 by Dianne Skoll 5 | 6 | # CAL_DISPATCH -- Shell script for CGI directory to dispatch calendar 7 | # commands. 8 | 9 | ######################### 10 | # 11 | # Parameters for you to change 12 | # 13 | ######################### 14 | 15 | # Set DIR to the directory in which all the scripts live. They must all 16 | # be in the same directory. The scripts are: 17 | # cal_dispatch, cal_ps, hebdate, hebps, moon, sunrise and sunset. 18 | # In addition, the reminder files hebbg.ps, hebdate.rem, moon.rem, 19 | # sunrise.rem and sunset.rem must live in $DIR. 20 | DIR=%SCRIPTDIR% 21 | export DIR 22 | 23 | # Set REMIND to the full pathname of the Remind executable. 24 | REMIND=%REMIND% 25 | export REMIND 26 | 27 | # Set REM2PS to the full pathname of the rem2ps executable 28 | REM2PS=%REM2PS% 29 | export REM2PS 30 | 31 | ######################### 32 | # 33 | # Don't change anything after this. 34 | # 35 | ######################### 36 | 37 | if [ "$1" = "" ] ; then 38 | exit 0 39 | fi 40 | 41 | 42 | case "$1" in 43 | sunrise) 44 | exec $DIR/sunrise 45 | ;; 46 | 47 | sunset) 48 | exec $DIR/sunset 49 | ;; 50 | 51 | hebdate) 52 | exec $DIR/hebdate 53 | ;; 54 | 55 | calps) 56 | exec $DIR/calps 57 | ;; 58 | 59 | moon) 60 | exec $DIR/moon 61 | ;; 62 | 63 | hebps) 64 | exec $DIR/hebps 65 | ;; 66 | 67 | hebhtml) 68 | if [ "$2" = "" -o "$3" = "" ] ; then 69 | exec $DIR/hebhtml 70 | else 71 | exec $DIR/hebhtml "$2" "$3" 72 | fi 73 | ;; 74 | 75 | esac 76 | 77 | exit 0 78 | -------------------------------------------------------------------------------- /www/calendar.html-DIST: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Remind Calendar Server 5 | 6 | 7 | 8 |

Remind Calendar Server

9 | 10 | 11 | Sunrise Information

12 | 13 | Sunset Information

14 | 15 | Moon Phase Information

16 | 17 | Blank PostScript Calendar (Approximately 20kB)

18 | 19 | Today's Hebrew Date

20 | 21 | PostScript Calendar with Jewish Holidays (Approximately 35 kB)

22 | 23 | HTML Calendar with Jewish Holidays 24 |


25 | 26 | Get the Remind software that provides this service.

27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /www/calps: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # PostScript calendar shell script 3 | # 4 | # This file is part of REMIND. 5 | # Copyright (C) 1992-2018 by Dianne Skoll 6 | 7 | echo "Content-type: application/postscript" 8 | echo 9 | 10 | $REMIND -p $DIR/blank.rem | $REM2PS -e -c3 -l 11 | exit 0 12 | -------------------------------------------------------------------------------- /www/firstquarter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfskoll/remind/ef7742a3cccc49b490d46f3a6b738e5896a10d04/www/firstquarter.png -------------------------------------------------------------------------------- /www/fullmoon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfskoll/remind/ef7742a3cccc49b490d46f3a6b738e5896a10d04/www/fullmoon.png -------------------------------------------------------------------------------- /www/hebdate: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Hebrew date shell script 3 | # 4 | # This file is part of REMIND. 5 | # Copyright (C) 1992-2018 by Dianne Skoll 6 | 7 | echo Content-type: text/html 8 | echo "" 9 | 10 | cat < 12 | 13 | Hebrew date 14 | 15 | 16 | 17 |

Hebrew date

18 | 19 | EOM 20 | 21 | $REMIND -arqh $DIR/hebdate.rem 22 | 23 | echo "" 24 | echo "" 25 | exit 0 26 | -------------------------------------------------------------------------------- /www/hebdate.rem-DIST: -------------------------------------------------------------------------------- 1 | # Hebrew date reminder file 2 | # 3 | # This file is part of REMIND. 4 | # Copyright (C) 1992-2018 by Dianne Skoll 5 | 6 | BANNER % 7 | IF !$PSCAL 8 | FSET _hstr(x) HEBDAY(x) + " " + HEBMON(x) + ", " + HEBYEAR(x) 9 | 10 | FSET msgsuffix(x) "

" 11 | 12 | MSG The Hebrew date for today, %d %m, %y, is [_hstr(today())]. % 13 | MSG And the Hebrew date for tomorrow is [_hstr(today()+1)]. % 14 | 15 | fset msgprefix(x) iif($NumTrig==OldTrig, "

Upcoming Holidays

"+char(13,10),"") 16 | set oldtrig $numtrig 17 | ENDIF 18 | 19 | #JHOLS 20 | ########################################################################## 21 | # # 22 | # This portion of the file contains reminders for Jewish holidays. The # 23 | # dates were obtained from "The First Jewish Catalog" by Richard Siegel # 24 | # and Michael and Sharon Strassfeld, published by the Jewish Publication # 25 | # Society of America. The Reform version of the calendar was guessed # 26 | # at by Dianne Skoll based on experience. Additional corrections were # 27 | # made from the paper "Calendrical Calculations" by Nachum Dershowitz # 28 | # and Edward M. Reingold. Any further corrections are welcome. # 29 | # # 30 | ########################################################################## 31 | 32 | SET n $NumTrig 33 | 34 | # --- HERE ARE THE JEWISH HOLIDAYS --- 35 | # Set the variable InIsrael to 1 if you live in Israel. Otherwise, 36 | # you get the Diaspora versions of Jewish holidays 37 | SET InIsrael 0 38 | 39 | # Set the variable Reform to 1 if you want the Reform version of the 40 | # Jewish calendar. Otherwise, you get the traditional version 41 | SET Reform 0 42 | 43 | # Convenient function definition to save typing 44 | FSET _h(x, y) TRIGGER(HEBDATE(x,y)) 45 | FSET _h2(x, y) HEBDATE(x, y, TODAY()-7) 46 | FSET _PastSat(x, y) IIF(WKDAYNUM(_h2(x,y))!=6, \ 47 | TRIGGER(_h2(x,y)), \ 48 | TRIGGER(_h2(x,y)+1)) 49 | 50 | # Default values in case InIsrael and Reform are not set 51 | SET InIsrael VALUE("InIsrael", 0) 52 | SET Reform VALUE("Reform", 0) 53 | 54 | [_h(1, "Tishrey")] ++12 MSG %"Rosh Hashana 1%" is %b. 55 | 56 | # No RH-2 or Tzom Gedalia in Reform 57 | IF !Reform 58 | [_h(2, "Tishrey")] ++12 MSG %"Rosh Hashana 2%" is %b. 59 | [_PastSat(3, "Tishrey")] ++12 MSG %"Tzom Gedalia%" is %b. 60 | ENDIF 61 | 62 | [_h(10, "Tishrey")] ++12 MSG %"Yom Kippur%" is %b. 63 | [_h(15, "Tishrey")] ++12 MSG %"Sukkot 1%" is %b. 64 | 65 | IF !InIsrael 66 | [_h(16, "Tishrey")] MSG %"Sukkot 2%" 67 | ENDIF 68 | 69 | [_h(21, "Tishrey")] ++12 MSG %"Hoshana Rabba%" is %b. 70 | [_h(22, "Tishrey")] ++12 MSG %"Shemini Atzeret%" is %b. 71 | 72 | IF InIsrael 73 | [_h(22, "Tishrey")] ++12 MSG %"Simchat Torah%" is %b. 74 | ELSE 75 | [_h(23, "Tishrey")] ++12 MSG %"Simchat Torah%" is %b. 76 | ENDIF 77 | 78 | # Because Kislev can change length, we must be more careful about Chanukah 79 | FSET _chan(x) TRIGGER(HEBDATE(24, "Kislev", today()-9)+x) 80 | [_chan(1)] ++12 MSG %"Chanukah 1%" is %b. 81 | [_chan(2)] MSG %"Chanukah 2%" 82 | [_chan(3)] MSG %"Chanukah 3%" 83 | [_chan(4)] MSG %"Chanukah 4%" 84 | [_chan(5)] MSG %"Chanukah 5%" 85 | [_chan(6)] MSG %"Chanukah 6%" 86 | [_chan(7)] MSG %"Chanukah 7%" 87 | [_chan(8)] MSG %"Chanukah 8%" 88 | 89 | # Not sure about Reform's position on the next one. 90 | IF !Reform 91 | # The fast is moved to the 11th if the 10th is a Saturday 92 | REM [_PastSat(10, "Tevet")] MSG %"Tzom Tevet%" is %b. 93 | ENDIF 94 | 95 | [_h(15, "Shvat")] ++12 MSG %"Tu B'Shvat%" is %b. 96 | [_h(15, "Adar A")] ++12 MSG %"Purim Katan%" is %b. 97 | 98 | # If Purim is on Sunday, then Fast of Esther is 11 Adar. 99 | IF WKDAYNUM(_h2(13, "Adar")) != 6 100 | REM [TRIGGER(_h2(13, "Adar"))] ++12 MSG %"Fast of Esther%" is %b. 101 | ELSE 102 | REM [TRIGGER(_h2(11, "Adar"))] ++12 MSG %"Fast of Esther%" is %b. 103 | ENDIF 104 | [_h(14, "Adar")] ++12 MSG %"Purim%" is %b. 105 | [_h(15, "Nisan")] ++12 MSG %"Pesach%" is %b. 106 | 107 | IF !InIsrael 108 | [_h(16, "Nisan")] MSG %"Pesach 2%" is %b. 109 | ENDIF 110 | 111 | [_h(21, "Nisan")] MSG %"Pesach 7%" is %b. 112 | 113 | IF !InIsrael && !Reform 114 | [_h(22, "Nisan")] MSG %"Pesach 8%" is %b. 115 | ENDIF 116 | 117 | [_h(27, "Nisan")] ++12 MSG %"Yom HaShoah%" is %b. 118 | [_h(4, "Iyar")] ++12 MSG %"Yom HaZikaron%" is %b. 119 | [_h(5, "Iyar")] ++12 MSG %"Yom Ha'atzmaut%" is %b. 120 | 121 | # Not sure about Reform's position on Lag B'Omer 122 | IF !Reform 123 | [_h(18, "Iyar")] ++12 MSG %"Lag B'Omer%" is %b. 124 | ENDIF 125 | 126 | [_h(28, "Iyar")] ++12 MSG %"Yom Yerushalayim%" is %b. 127 | [_h(6, "Sivan")] ++12 MSG %"Shavuot%" is %b. 128 | 129 | IF !InIsrael && !Reform 130 | [_h(7, "Sivan")] MSG %"Shavuot 2%" is %b. 131 | ENDIF 132 | 133 | # Fairly sure Reform Jews don't observe the next two 134 | IF !Reform 135 | # Tzom Tamuz and Tish'a B'Av are moved to Sunday if they normally 136 | # fall on a Saturday 137 | [_PastSat(17, "Tamuz")] ++12 MSG %"Tzom Tammuz%" is %b. 138 | [_PastSat(9, "Av")] ++12 MSG %"Tish'a B'Av%" is %b. 139 | ENDIF 140 | 141 | fset msgprefix(x) "" 142 | 143 | IF $NumTrig > n 144 | REM SPECIAL SHADE 224 224 255 145 | ENDIF 146 | 147 | # Counting the omer - do the whole spiel, i.e: 148 | # "This is the xth day of the omer, being y weeks and z days of the omer." 149 | # Nice Remind programming example here! 150 | SET ostart HEBDATE(16, "Nisan", TODAY()-50) 151 | IF ostart <= TODAY() && (TODAY() - ostart < 49) 152 | SET odays TODAY()-ostart+1 153 | IF odays < 7 154 | MSG %"%"Today is the [ORD(odays)] day of the Omer. 155 | ELSE 156 | IF !(odays % 7) 157 | MSG %"%"Today is the [ORD(odays)] day of the Omer, being [odays / 7] [PLURAL(odays/7, "week")] of the Omer. 158 | ELSE 159 | 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. 160 | ENDIF 161 | ENDIF 162 | CAL [ORD(odays)] of Omer 163 | ENDIF 164 | 165 | IF !$PSCAL 166 | REM 20 ++40 msg Also available: a PostScript calendar (about 35KB) for %m %y, complete with Hebrew dates, Jewish holidays, and moon phases for [$Location]. 167 | REM 20 ++40 msg And: an HTML version of the above. 168 | ELSE 169 | [trigger(moondate(0))] SPECIAL MOON 0 170 | [trigger(moondate(1))] SPECIAL MOON 1 171 | [trigger(moondate(2))] SPECIAL MOON 2 172 | [trigger(moondate(3))] SPECIAL MOON 3 173 | REM PS Border Border moveto /DayFont findfont 10 scalefont setfont ([hebday(today())] [hebmon(today())]) show 174 | REM SPECIAL HTML

[hebday(today())] [hebmon(today())]

175 | 176 | ENDIF 177 | 178 | -------------------------------------------------------------------------------- /www/hebhtml: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # HTML calendar shell script 3 | # 4 | # This file is part of REMIND. 5 | # Copyright (C) 1992-2018 by Dianne Skoll 6 | 7 | echo "Content-Type: text/html" 8 | echo "" 9 | 10 | if [ "$1 $2" = " " ] ; then 11 | $REMIND - <<'EOR' 12 | set thismon monnum(today()) 13 | set thisyear year(today()) 14 | set nextmon iif(thismon+1 > 12, 1, thismon+1) 15 | set nextyear iif(nextmon==1, thisyear+1, thisyear) 16 | set lastmon iif(thismon-1 < 1, 12, thismon-1) 17 | set lastyear iif(lastmon==12, thisyear-1, thisyear) 18 | set nextmon mon(nextmon) 19 | set lastmon mon(lastmon) 20 | BANNER % 21 | REM RUN $REMIND -iHTML=1 -p $DIR/hebdate.rem %m %y | %REM2HTML% --forwurl "cal_dispatch?hebhtml+[nextmon]+[nextyear]" --backurl "cal_dispatch?hebhtml+[lastmon]+[lastyear]" --imgbase "%IMAGEBASE%" --stylesheet rem-default.css --pngs 22 | EOR 23 | 24 | else 25 | 26 | $REMIND - "$1" "$2" <<'EOR' 27 | set thismon monnum(today()) 28 | set thisyear year(today()) 29 | set nextmon iif(thismon+1 > 12, 1, thismon+1) 30 | set nextyear iif(nextmon==1, thisyear+1, thisyear) 31 | set lastmon iif(thismon-1 < 1, 12, thismon-1) 32 | set lastyear iif(lastmon==12, thisyear-1, thisyear) 33 | set nextmon mon(nextmon) 34 | set lastmon mon(lastmon) 35 | BANNER % 36 | REM RUN $REMIND -iHTML=1 -p $DIR/hebdate.rem %m %y | %REM2HTML% --forwurl "cal_dispatch?hebhtml+[nextmon]+[nextyear]" --backurl "cal_dispatch?hebhtml+[lastmon]+[lastyear]" --imgbase "%IMAGEBASE%" --stylesheet rem-default.css --pngs 37 | EOR 38 | 39 | fi 40 | 41 | exit 0 42 | -------------------------------------------------------------------------------- /www/hebps: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Hebrew PostScript calendar shell script 3 | # 4 | # This file is part of REMIND. 5 | # Copyright (C) 1992-2018 by Dianne Skoll 6 | 7 | # Figure out the month: If day <= 20, use this month; otherwise, use 8 | # next month. 9 | echo "Content-type: application/postscript" 10 | echo "" 11 | 12 | $REMIND - <" 10 | $REMIND $DIR/moon.rem 11 | echo "" 12 | exit 0 13 | 14 | -------------------------------------------------------------------------------- /www/moon.rem-DIST: -------------------------------------------------------------------------------- 1 | # File for giving moon phase info. 2 | # 3 | # This file is part of REMIND. 4 | # Copyright (C) 1992-2018 by Dianne Skoll 5 | 6 | set now now() 7 | 8 | banner % 9 | 10 | MSG % 11 | MSG Moon over [$Location]% 12 | MSG % 13 | 14 | MSG 15 | MSG

Moon over [$Location]

16 | 17 | set ndate moondate(0) 18 | set ntime moontime(0) 19 | set fdate moondate(2) 20 | set ftime moontime(2) 21 | 22 | fset t(x) wkday(x)+", "+day(x)+" "+mon(x)+", "+year(x) 23 | msg Today is %w, %d %m, %y.

24 | msg The local time in [$Location] is [now].

25 | 26 | if ndate < fdate 27 | msg The next new moon is on [t(ndate)] at [ntime], [$Location] time.

28 | msg The next full moon is on [t(fdate)] at [ftime], [$Location] time.

29 | else 30 | msg The next full moon is on [t(fdate)] at [ftime], [$Location] time.

31 | msg The next new moon is on [t(ndate)] at [ntime], [$Location] time.

32 | endif 33 | -------------------------------------------------------------------------------- /www/newmoon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfskoll/remind/ef7742a3cccc49b490d46f3a6b738e5896a10d04/www/newmoon.png -------------------------------------------------------------------------------- /www/rem-default.css: -------------------------------------------------------------------------------- 1 | table.rem-cal { 2 | font-family: helvetica, arial, sans-serif; 3 | font-size: 12pt; 4 | width: 100%; 5 | border-collapse: collapse; 6 | } 7 | 8 | table.rem-sc-table { 9 | font-family: helvetica, arial, sans-serif; 10 | font-size: 10pt; 11 | width: 95%; 12 | float: left; 13 | } 14 | 15 | caption.rem-cal-caption { 16 | font-size: 14pt; 17 | font-weight: bold; 18 | } 19 | 20 | th.rem-cal-hdr { 21 | width: 14%; 22 | border-style: solid; 23 | border-width: 1px; 24 | vertical-align: top; 25 | } 26 | td.rem-empty, td.rem-cell, td.rem-small-calendar { 27 | width: 14%; 28 | height: 7em; 29 | border-style: solid; 30 | border-width: 1px; 31 | vertical-align: top; 32 | } 33 | td.rem-today { 34 | width: 14%; 35 | height: 7em; 36 | border-style: solid; 37 | border-width: 2px; 38 | border-color: #EE3333; 39 | vertical-align: top; 40 | } 41 | 42 | div.rem-daynumber { 43 | float: right; 44 | text-align: right; 45 | vertical-align: top; 46 | font-size: 14pt; 47 | } 48 | 49 | p.rem-entry { 50 | clear: both; 51 | } 52 | 53 | div.rem-moon { 54 | float: left; 55 | text-align: left; 56 | vertical-align: top; 57 | } 58 | 59 | th.rem-sc-hdr { 60 | text-align: right; 61 | } 62 | 63 | td.rem-sc-empty-cell, td.rem-sc-cell { 64 | text-align: right; 65 | width: 14%; 66 | } 67 | 68 | caption.rem-sc-caption { 69 | font-size: 12pt; 70 | } 71 | -------------------------------------------------------------------------------- /www/sunrise: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Sunrise shell script 3 | # 4 | # This file is part of REMIND. 5 | # Copyright (C) 1992-2018 by Dianne Skoll 6 | 7 | echo Content-type: text/html 8 | echo 9 | echo "" 10 | $REMIND -arqh $DIR/sunrise.rem 11 | echo "" 12 | 13 | exit 0 14 | -------------------------------------------------------------------------------- /www/sunrise.rem-DIST: -------------------------------------------------------------------------------- 1 | # File for giving sunrise info 2 | # 3 | # This file is part of REMIND. 4 | # Copyright (C) 1992-2018 by Dianne Skoll 5 | 6 | set now now() 7 | 8 | banner % 9 | MSG % 10 | MSG Sunrise in [$Location]% 11 | MSG % 12 | 13 | MSG 14 | MSG

Sunrise in [$Location]

15 | 16 | set tod sunrise(today()) 17 | set tom sunrise(today()+1) 18 | 19 | set len1 sunset(today())-sunrise(today()) 20 | set len2 sunset(today()+1)-sunrise(today()+1) 21 | set dlen len2-len1 22 | set slen iif(dlen==0, "the same length as", dlen<0, abs(dlen)+plural(abs(dlen)," minute", " minutes")+" shorter than", dlen+plural(dlen, " minute", " minutes")+" longer than") 23 | 24 | set diff tod-now 25 | set adiff abs(diff) 26 | set hdiff adiff/60 27 | set mdiff adiff%60 28 | 29 | set mstr iif(mdiff==0, "", mdiff == 1, "1 minute", mdiff + " minutes") 30 | set hstr iif(hdiff==0, "", hdiff == 1, "1 hour", hdiff + " hours") 31 | set astr iif(mdiff!=0 && hdiff!=0, " and ", "") 32 | set fn iif(diff==0, "now", diff <0, "ago", "from now") 33 | set iw iif(diff<0, "was", "is") 34 | set aw iif(tod==tom, " as well.", ".") 35 | msg Today is %w, %d %m, %y.

36 | msg The local time in [$Location] is [now].

37 | msg Sunrise today [iw] at [tod]; in other words, [hstr][astr][mstr] [fn].

38 | msg Sunrise tomorrow is at [tom][aw]

39 | msg The daylight portion of tomorrow will be [slen] today.

40 | msg 41 | -------------------------------------------------------------------------------- /www/sunset: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Sunset shell script 3 | # 4 | # This file is part of REMIND. 5 | # Copyright (C) 1992-2018 by Dianne Skoll 6 | 7 | echo Content-type: text/html 8 | echo 9 | echo "" 10 | $REMIND -arqh $DIR/sunset.rem 11 | echo "" 12 | 13 | exit 0 14 | -------------------------------------------------------------------------------- /www/sunset.rem-DIST: -------------------------------------------------------------------------------- 1 | # File for giving sunset info 2 | # 3 | # This file is part of REMIND. 4 | # Copyright (C) 1992-2018 by Dianne Skoll 5 | 6 | set now now() 7 | 8 | banner % 9 | 10 | MSG % 11 | MSG Sunset in [$Location]% 12 | MSG % 13 | 14 | MSG 15 | MSG

Sunset in [$Location]

16 | 17 | set tod sunset(today()) 18 | set tom sunset(today()+1) 19 | 20 | set len1 sunset(today())-sunrise(today()) 21 | set len2 sunset(today()+1)-sunrise(today()+1) 22 | set dlen len2-len1 23 | set slen iif(dlen==0, "the same length as", dlen<0, abs(dlen)+plural(abs(dlen)," minute", " minutes")+" shorter than", dlen+plural(dlen, " minute", " minutes")+" longer than") 24 | 25 | set diff tod-now 26 | set adiff abs(diff) 27 | set hdiff adiff/60 28 | set mdiff adiff%60 29 | 30 | set mstr iif(mdiff==0, "", mdiff == 1, "1 minute", mdiff + " minutes") 31 | set hstr iif(hdiff==0, "", hdiff == 1, "1 hour", hdiff + " hours") 32 | set astr iif(mdiff!=0 && hdiff!=0, " and ", "") 33 | set fn iif(diff==0, "now", diff <0, "ago", "from now") 34 | set iw iif(diff<0, "was", "is") 35 | set aw iif(tod==tom, " as well.", ".") 36 | msg Today is %w, %d %m, %y.

37 | msg The local time in [$Location] is [now].

38 | msg Sunset today [iw] at [tod]; in other words, [hstr][astr][mstr] [fn].

39 | msg Sunset tomorrow is at [tom][aw]

40 | msg The daylight portion of tomorrow will be [slen] today.

41 | msg 42 | --------------------------------------------------------------------------------