Compare commits

..

51 Commits

Author SHA1 Message Date
Dianne Skoll
eb1998c888 Update version 2021-03-30 16:34:24 -04:00
Dianne Skoll
543252cbaf Update docs. 2021-03-30 16:28:54 -04:00
Dianne Skoll
6df7c59876 Don't change locale to en_US.utf-8 if it is already a UTF-8 locale. 2021-03-25 09:43:42 -04:00
Dianne Skoll
f780e0afc3 Fix typo. 2021-02-28 10:03:05 -05:00
Dianne Skoll
310e8d3287 Clarify comment. 2021-02-15 16:37:20 -05:00
Dianne Skoll
ba51bdf258 Add tests for arithmetic overflow. 2021-02-15 16:35:23 -05:00
Dianne Skoll
ef88b844fb Catch integer overflow with "/". 2021-02-15 10:50:56 -05:00
Dianne Skoll
67b96b0a26 Send error messages to stderr 2021-02-09 12:13:21 -05:00
Dianne Skoll
562da30fb5 Update TkRemind requirements. 2021-02-09 12:08:43 -05:00
Dianne Skoll
21175e8cf6 Add $IntMax and $IntMin special variables. 2021-02-02 17:10:17 -05:00
Dianne Skoll
80d01f7158 Check for overflow in abs() 2021-02-02 17:04:14 -05:00
Dianne Skoll
90cac447e4 Document how Remind handles overflow. 2021-02-01 19:54:31 -05:00
Dianne Skoll
04bf5b0a8b Add explanatory comments about overflow-checking functions 2021-01-30 21:04:44 -05:00
Dianne Skoll
d667c15b25 Add overflow checks for unary minus. 2021-01-30 21:02:56 -05:00
Dianne Skoll
2123bf4b18 Check all Subtract implementations for overflow. 2021-01-30 15:15:02 -05:00
Dianne Skoll
429a64f29e Make all + implementations consistent 2021-01-30 15:12:46 -05:00
Dianne Skoll
f39381dd6c Check for overflow on addition of all integer types. 2021-01-30 15:07:55 -05:00
Dianne Skoll
0a9eb07f6f Check for overflow on addition, subtraction, multiplication of integers 2021-01-30 12:56:37 -05:00
Dianne Skoll
9c287e3fd7 Check for overflow when parsing integer constant. 2021-01-29 18:09:35 -05:00
Dianne Skoll
cce4b2cb14 Update docs. 2021-01-21 15:48:26 -05:00
Dianne Skoll
e49d9f8ab6 Bump version to 03.03.05 2021-01-21 15:44:18 -05:00
Dianne Skoll
48cbeb28f4 Make options file configurable. 2021-01-16 09:49:44 -05:00
Dianne Skoll
57d5c54559 Tidy up color options. 2021-01-15 21:16:44 -05:00
Dianne Skoll
3b2260f67e Tweak appearance 2021-01-15 19:19:13 -05:00
Dianne Skoll
d423a62327 Add ability to change fg/bg colors. 2021-01-15 18:55:38 -05:00
Dianne Skoll
ac8da00030 Update man page for new font-change options; document keyboard shortcuts for navigating. 2021-01-15 09:52:40 -05:00
Dianne Skoll
77eb7fb99d Update copyright date. 2021-01-15 09:46:55 -05:00
Dianne Skoll
a751149dd3 Fix typo. 2021-01-15 08:15:58 -05:00
Dianne Skoll
69d45618c6 Ensure we have Tcl/Tk 8.5 or newer. 2021-01-13 19:56:23 -05:00
Dianne Skoll
22fa1a28e5 Get rid of "Apply Options". "Save Options" is all that's needed. 2021-01-13 19:49:33 -05:00
Dianne Skoll
f4cc233009 Make the month heading also use HeadingFont. 2021-01-13 13:57:55 -05:00
Dianne Skoll
1d6e4edd0f Add dialog box for changing calendar fonts. 2021-01-13 13:08:31 -05:00
Dianne Skoll
daffa8cba0 Add missing release note. 2021-01-12 10:47:30 -05:00
Dianne Skoll
2e161a1bc1 Rebuild configure from configure.in 2021-01-12 10:13:13 -05:00
Dianne Skoll
204bb00060 Update docs; prep 3.3.4 release. 2021-01-12 10:13:00 -05:00
Dianne Skoll
d6029a54aa Remove unnecessary line of code; add space after "sub" operator. 2021-01-10 17:38:25 -05:00
Dianne Skoll
f99b5c5a66 Update man page date. 2021-01-05 21:30:21 -05:00
Dianne Skoll
2df4119c1a Fix test. 2021-01-05 19:14:16 -05:00
Dianne Skoll
d06b4e5dcd Update copyright date 2021-01-05 19:13:11 -05:00
Dianne Skoll
bf8a25137d Right-align moon indicators when day numbers are left-aligned. 2021-01-05 19:08:10 -05:00
Dianne Skoll
0f302ad0fc Add clarifying comment. 2021-01-05 17:38:33 -05:00
Dianne Skoll
e3d6b283c5 Fix setpagedevice for landscape mode. 2021-01-05 17:23:47 -05:00
Dianne Skoll
2e3ed09039 Update test for setpagedevice patch. 2021-01-05 17:20:27 -05:00
Dianne Skoll
37971a3f07 Set page size (patch from Jonathan Kamens) 2021-01-05 17:19:20 -05:00
Dianne Skoll
2a1960f257 Add TkRemind option for drawing day numbers on left. 2021-01-05 16:39:57 -05:00
Dianne Skoll
350564c304 Add "-x" option to rem2ps to put day numbers at the top-left of each box.
By default, day numbers are placed at the top-right.
2021-01-05 16:32:20 -05:00
Dianne Skoll
9e2a9fea37 Use "-q" option with inotifywait 2020-12-30 11:01:25 -05:00
Dianne Skoll
3592b43629 If inotifywait is available, use it to react instantly to changes to reminder file/dir. 2020-12-30 10:59:00 -05:00
Dianne Skoll
becf1fc459 Wait 100ms to update after changes. 2020-12-29 12:48:24 -05:00
Dianne Skoll
2bccd058ed Refactor code in TkRemind to prepare for possibly using inotify to react to changes. 2020-12-29 12:46:23 -05:00
Dianne Skoll
12c6621051 Fix typo 2020-11-09 17:32:16 -05:00
18 changed files with 746 additions and 235 deletions

2
configure vendored
View File

@@ -3991,7 +3991,7 @@ _ACEOF
fi fi
done done
VERSION=03.03.03 VERSION=03.03.06
ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h" ac_config_files="$ac_config_files src/Makefile www/Makefile src/version.h"

View File

@@ -75,6 +75,6 @@ if test "$GCC" = yes; then
fi fi
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale) AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale)
VERSION=03.03.03 VERSION=03.03.06
AC_SUBST(VERSION) AC_SUBST(VERSION)
AC_OUTPUT(src/Makefile www/Makefile src/version.h) AC_OUTPUT(src/Makefile www/Makefile src/version.h)

View File

@@ -1,5 +1,52 @@
CHANGES TO REMIND CHANGES TO REMIND
* VERSION 3.3 Patch 6 - 2021-03-30
- test/test.rem: Change local to en_US.utf-8 only if current locale
is not a UTF-8 locale.
- MINOR CHANGE: Remind's arithemtic operators (+, -, *, /) give errors
on overflow rather than silently giving the wrong answer.
- MINOR CHANGE: Add $IntMin and $IntMax system variables.
- DOCUMENTATION FIX: Document that TkRemind now requires Tcl/Tk version
8.5 or newer.
* VERSION 3.3 Patch 5 - 2021-01-21
- NEW FEATURE: tkremind: Add ability to change fonts and colors from
within TkRemind "Options" dialog.
- CHANGE: tkremind: TkRemind now requires Tcl/Tk 8.5 or newer.
- CHANGE: tkremind: You can specify the location of the options
file on the command-line if you want to use one other than ~/.tkremindrc
- CLEANUP: tkremind: Remove "Apply Options" from Options dialog; we only
need "Save Options".
- DOC FIX: Add missing release note in 3.3.4 notes regarding
setpagedevice patch
- DOC FIX: tkremind: Document shortcut keys.
* VERSION 3.3 Patch 4 - 2021-01-12
- NEW FEATURE: If "inotifywait" is installed, TkRemind uses it to refresh
the calendar display right away when the reminders file/directory is updated.
This makes TkRemind react almost instantly if external tools are editing
or updating reminders.
- MINOR NEW FEATURE: rem2ps has a new '-x' option; this puts the day numbers
on the top-left of the day's box instead of the top-right.
- MINOR FIXES: A typo in remind.1 was fixed; additional comments regarding
UNTIL were added.
- BUG FIX: rem2ps: Call setpagedevice to set page size. Based on a patch
from Jonathan Kamens.
* VERSION 3.3 Patch 3 - 2020-11-09 * VERSION 3.3 Patch 3 - 2020-11-09
- BUG FIX: Fix startup crash in TkRemind if "Show Today's Reminders on - BUG FIX: Fix startup crash in TkRemind if "Show Today's Reminders on

View File

@@ -1,4 +1,4 @@
.TH REM2PS 1 "1 January 2020" .TH REM2PS 1 "5 January 2021"
.UC 4 .UC 4
.SH NAME .SH NAME
rem2ps \- draw a PostScript calendar from Remind output rem2ps \- draw a PostScript calendar from Remind output
@@ -29,6 +29,11 @@ include any document structuring comments in your prologue.
Produce the calendar in landscape mode rather than the default Produce the calendar in landscape mode rather than the default
portrait mode. portrait mode.
.TP .TP
.B \-x
When printing the calendar, place the day numbers in the top-left of each
day's box. If this option is omitted, the day numbers appear in the
top-right.
.TP
\fB\-c\fR[\fIn\fR] \fB\-c\fR[\fIn\fR]
If \fIn\fR is omitted, disables the small calendars for next and previous If \fIn\fR is omitted, disables the small calendars for next and previous
months which are normally generated. If \fIn\fR is supplied, it can range months which are normally generated. If \fIn\fR is supplied, it can range

View File

@@ -860,6 +860,20 @@ As a special case, you can use the \fBTHROUGH\fR keyword instead of
REM 1992-11-30 +2 THROUGH 1992-12-04 MSG Jury duty REM 1992-11-30 +2 THROUGH 1992-12-04 MSG Jury duty
.fi .fi
.PP .PP
If you have an expiry date via the use of \fBTHROUGH\fR or \fBUNTIL\fR,
then Remind will \fInever\fR trigger the reminder after the expiry
date. For example, if you have this:
.PP
.nf
OMIT 2021-01-08
REM 2021-01-01 THROUGH 2021-01-08 AFTER MSG Test
.fi
.PP
the reminder will not be triggered on 2021-01-08, and nor will it be
triggered on 2021-01-09; even though the AFTER keyword would normally
move the 8th's reminder to the 9th, the expiry date of 2021-01-08
overrides that.
.PP
.B THE ONCE KEYWORD .B THE ONCE KEYWORD
.PP .PP
Sometimes, it is necessary to ensure that reminders are run only once Sometimes, it is necessary to ensure that reminders are run only once
@@ -1854,6 +1868,11 @@ otherwise.
.PP .PP
.B NOTES .B NOTES
.PP .PP
If the result of an addition, subtraction or multiplication operation
would not fit in a C "int" type, \fBRemind\fR issues a "Number too
high" error. Unlike C, integer operations will not simply give the
wrong answer in case of overflow.
.PP
Operators of equal precedence are \fIalways\fR evaluated from left Operators of equal precedence are \fIalways\fR evaluated from left
to right, except where parentheses dictate otherwise. This is important, to right, except where parentheses dictate otherwise. This is important,
because the enhanced "+" operator is not necessarily associative. because the enhanced "+" operator is not necessarily associative.
@@ -2046,6 +2065,14 @@ then \fBONCE\fR directives will be ignored.
.B $InfDelta (read-only) .B $InfDelta (read-only)
If non-zero, then the \fB\-t\fR option was supplied on the command line. If non-zero, then the \fB\-t\fR option was supplied on the command line.
.TP .TP
.B $IntMax (read-only)
The largest representable \fBINT\fR. On a machine with 32-bit signed integers
using twos-complement representation, this will be 2147483647.
.TP
.B $IntMin (read-only)
The smallest representable \fBINT\fR. On a machine with 32-bit signed integers
using twos-complement representation, this will be -2147483648.
.TP
.B $LatDeg, $LatMin, $LatSec .B $LatDeg, $LatMin, $LatSec
These specify the latitude of your location. \fB$LatDeg\fR can These specify the latitude of your location. \fB$LatDeg\fR can
range from \-90 to 90, and the others from \-59 to 59. Northern latitudes range from \-90 to 90, and the others from \-59 to 59. Northern latitudes
@@ -3671,7 +3698,7 @@ and sometimes an \fBOMITFUNC\fR; experiment and use whichever seems clearer.
.SH POSSIBLY-UNCOMPUTABLE TRIGGERS .SH POSSIBLY-UNCOMPUTABLE TRIGGERS
.PP .PP
Occasionally, you may wish to suppress the "Can't compute trigger" warnings Occasionally, you may wish to suppress the "Can't compute trigger" warnings
for reminders for which a trigger date cannot be compute. For example, for reminders for which a trigger date cannot be computed. For example,
the following reminder is triggered on a Monday that is not a holiday the following reminder is triggered on a Monday that is not a holiday
if the following Tuesday is a holiday: if the following Tuesday is a holiday:
.PP .PP

View File

@@ -1,9 +1,9 @@
.TH TKREMIND 1 "1 January 2020" .TH TKREMIND 1 "15 January 2021"
.UC 4 .UC 4
.SH NAME .SH NAME
tkremind \- graphical front-end to Remind calendar program tkremind \- graphical front-end to Remind calendar program
.SH SYNOPSIS .SH SYNOPSIS
.B tkremind \fR[\fIoptions\fR] [\fIread_file\fR] [\fIwrite_file\fR] .B tkremind \fR[\fIoptions\fR] [\fIread_file\fR] [\fIwrite_file\fR] [\fIconfig_file\fR]
.SH DESCRIPTION .SH DESCRIPTION
\fBTkRemind\fR is a graphical front-end to the \fBRemind\fR program. \fBTkRemind\fR is a graphical front-end to the \fBRemind\fR program.
It provides a friendly graphical interface which allows you to view It provides a friendly graphical interface which allows you to view
@@ -13,8 +13,10 @@ Although not all of \fBRemind\fR's features are available with \fBTkRemind\fR,
it creates. This allows you to learn \fBRemind\fR's syntax and then add it creates. This allows you to learn \fBRemind\fR's syntax and then add
extra features as you become a more sophisticated \fBRemind\fR programmer. extra features as you become a more sophisticated \fBRemind\fR programmer.
\fBTkRemind\fR is written in Tcl, and requires version 8.0 \fBTkRemind\fR is written in Tcl, and requires version 8.5 (or higher)
(or higher). It also requires a \fBwish\fR binary. as well as the tcllib extension. It also requires a \fBwish\fR
binary. If you are using Tcl/Tk 8.5, you may also need either the Img
or the tkpng extension to handle PNG images.
.SH OPTIONS .SH OPTIONS
\fBTkRemind\fR itself has no options. However, it passes certain options \fBTkRemind\fR itself has no options. However, it passes certain options
@@ -41,6 +43,9 @@ include the line:
.fi .fi
.PP .PP
\fIConfig_file\fR is the file in which \fBTkRemind\fR stores
its options. If it is omitted, it defaults to \fI$HOME/.tkremindrt\fR.
.SH THE CALENDAR WINDOW .SH THE CALENDAR WINDOW
When you start \fBTkRemind\fR, it displays a calendar for the current When you start \fBTkRemind\fR, it displays a calendar for the current
month, with today's date highlighted. Reminders are filled into each month, with today's date highlighted. Reminders are filled into each
@@ -51,11 +56,14 @@ notice that the box appears completely full.
.SH NAVIGATING .SH NAVIGATING
To change to the previous or next month, click the \fB<\-\fR To change to the previous or next month, click the \fB<\-\fR
or \fB\->\fR button, respectively. To change back to or \fB\->\fR button, respectively. You can also use the left/right arrow
the current month, click \fBToday\fR. To go to a specific month, keys or PageUp/PageDown to navigate.
click \fBGo To Date...\fR. This pops up a dialog box which allows you
to select a month and enter a year. Once you've done this, click To change back to the current month, click \fBToday\fR or press the
\fBGo\fR to go to the date, or \fBCancel\fR to cancel. Home key. To go to a specific month, click \fBGo To Date...\fR. This
pops up a dialog box which allows you to select a month and enter a
year. Once you've done this, click \fBGo\fR to go to the date, or
\fBCancel\fR to cancel.
To exit \fBTkRemind\fR, click \fBQuit\fR. To exit \fBTkRemind\fR, click \fBQuit\fR.
@@ -233,6 +241,22 @@ The characters "%d" are replaced with the lined number of the file
containing the reminder, and "%s" are replaced with the file name. containing the reminder, and "%s" are replaced with the file name.
Useful strings might be "emacs +%d %s" or "gvim +%d %s" Useful strings might be "emacs +%d %s" or "gvim +%d %s"
.TP
.B Extra Argument for Remind
This specifies any extra arguments that should be passed to Remind
when \BTkRemind\fR invokes \fBremind\fR. Unless you know what
you are doing, leave this blank.
.TP
.B Change entry font...
This button pops up a font selection dialog that lets you change the
font used to draw calendar items in the calendar boxes.
.TP
.B Change heading font...
Similar to Change entry font, but applies to calendar heading
(the month and day names and the day numbers.)
.PP .PP
Once you've configured the options the way you like them, Once you've configured the options the way you like them,
press \fBApply Options\fR to put them into effect, \fBSave Options\fR press \fBApply Options\fR to put them into effect, \fBSave Options\fR

View File

@@ -7,13 +7,31 @@
# A cheesy graphical front/back end for Remind using Tcl/Tk # A cheesy graphical front/back end for Remind using Tcl/Tk
# #
# This file is part of REMIND. # This file is part of REMIND.
# Copyright (C) 1992-2020 Dianne Skoll # Copyright (C) 1992-2021 Dianne Skoll
# #
#-------------------------------------------------------------- #--------------------------------------------------------------
# the next line restarts using wish \ # the next line restarts using wish \
exec wish "$0" "$@" exec wish "$0" "$@"
# We need at least version 8.5 because of {*} list expansion operator
if {[catch {package require Tcl 8.5}]} {
puts stderr "This program requires Tcl 8.5 or higher."
puts stderr "You have version [info tclversion]"
exit 1
}
# If it's 8.5, try using the Img or the TkPNG package to
# get PNG support
if {[info tclversion] == 8.5} {
if {[catch {package require Img}]} {
if {[catch {package require tkpng}]} {
puts stderr "Tcl/Tk version 8.5 might require either the Img or tkpng"
puts stderr "package to handle PNG images correctly. TkRemind may"
puts stderr "crash because neither of these packages was found."
}
}
}
wm withdraw . wm withdraw .
set Hostname [exec hostname] set Hostname [exec hostname]
@@ -106,13 +124,6 @@ if {[catch {package require json}]} {
missing_tcllib json missing_tcllib json
} }
# Check that we have the right version of wish
if {$tcl_version < 8.0} {
tk_dialog .error Error "You need wish version 8.0 or higher to run TkRemind; you have $tcl_version" error 0 OK
exit 1
}
if {$tcl_platform(platform) == "windows"} { if {$tcl_platform(platform) == "windows"} {
tk_dialog .error Error "Please do not port Remind to Windows" error 0 OK tk_dialog .error Error "Please do not port Remind to Windows" error 0 OK
exit 1 exit 1
@@ -155,6 +166,26 @@ set OptDescr(SMTPServer) "(String) IP address or host name of SMTP server to use
set Option(ExtraRemindArgs) "" set Option(ExtraRemindArgs) ""
set OptDescr(ExtraRemindArgs) "(String) Extra arguments when invoking remind" set OptDescr(ExtraRemindArgs) "(String) Extra arguments when invoking remind"
set Option(CalboxFont) [font actual TkFixedFont]
set OptDescr(CalboxFont) "Font to use in calendar boxes in Tk font format"
set Option(HeadingFont) [font actual TkDefaultFont]
set OptDescr(HeadingFont) "Font to use in calendar headings in Tk font format"
set Option(BackgroundColor) "#d9d9d9"
set OptDescr(BackgroundColor) "Default background color of calendar boxes"
set Option(TextColor) "#000000"
set OptDescr(TextColor) "Default text color in calendar boxes"
set Option(LabelColor) "#000000"
set OptDescr(LabelColor) "Default label color for headings"
set Option(WinBackground) "#d9d9d9"
set OptDescr(WinBackground) "Background color of calendar window"
set TimerUpdateForChanges ""
# Remind program to execute -- supply full path if you want # Remind program to execute -- supply full path if you want
set Remind "remind" set Remind "remind"
#set Remind "/home/dfs/Remind/src/remind" #set Remind "/home/dfs/Remind/src/remind"
@@ -166,8 +197,14 @@ set Rem2PS "rem2ps"
set ReminderFile {NOSUCHFILE} set ReminderFile {NOSUCHFILE}
set ReminderFile [file nativename "~/.reminders"] set ReminderFile [file nativename "~/.reminders"]
# Default options file
set ConfigFile ~/.tkremindrc
set EditorPid -1 set EditorPid -1
# Inotify file
set InotifyFP ""
# Reminder file to append to -- default # Reminder file to append to -- default
set AppendFile {NOSUCHFILE} set AppendFile {NOSUCHFILE}
catch {set AppendFile $ReminderFile} catch {set AppendFile $ReminderFile}
@@ -218,6 +255,7 @@ set PrintDest file
set PrintSize letter set PrintSize letter
set PrintOrient landscape set PrintOrient landscape
set PrintFill 1 set PrintFill 1
set PrintDaysRight 1
set PrintEncoding 0 set PrintEncoding 0
set PrintMargins 36pt set PrintMargins 36pt
set PrintSmallCalendars 1 set PrintSmallCalendars 1
@@ -263,7 +301,7 @@ proc Initialize {} {
global DayNames argc argv CommandLine ReminderFile AppendFile Remind PSCmd global DayNames argc argv CommandLine ReminderFile AppendFile Remind PSCmd
global MondayFirst TwentyFourHourMode ReminderFileModTime global MondayFirst TwentyFourHourMode ReminderFileModTime
global Option global Option ConfigFile
set CommandLine "|$Remind -itkremind=1 -pp -y -l EXTRA" set CommandLine "|$Remind -itkremind=1 -pp -y -l EXTRA"
set PSCmd "$Remind -itkremind=1 -itkprint=1 -pp -l EXTRA" set PSCmd "$Remind -itkremind=1 -itkprint=1 -pp -l EXTRA"
set i 0 set i 0
@@ -289,6 +327,10 @@ proc Initialize {} {
if {$i < $argc} { if {$i < $argc} {
set AppendFile [lindex $argv $i] set AppendFile [lindex $argv $i]
incr i incr i
if {$i < $argc} {
set ConfigFile [lindex $argv $i]
incr i
}
} }
} }
@@ -375,8 +417,7 @@ proc MonitorReminderFile {} {
# Redraw calendar and restart daemon if needed # Redraw calendar and restart daemon if needed
if {$ReminderFileModTime < $mtime} { if {$ReminderFileModTime < $mtime} {
set ReminderFileModTime $mtime set ReminderFileModTime $mtime
FillCalWindow ScheduleUpdateForChanges
RestartBackgroundRemindDaemon
} }
} }
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
@@ -447,6 +488,7 @@ proc CalEntryOffset { firstDay } {
proc CreateCalFrame { w dayNames } { proc CreateCalFrame { w dayNames } {
# Figure out reasonable height for text frames # Figure out reasonable height for text frames
global SetFontsWorked global SetFontsWorked
global Option
set h [winfo screenheight .] set h [winfo screenheight .]
if {$h <= 480} { if {$h <= 480} {
if {$SetFontsWorked} { if {$SetFontsWorked} {
@@ -461,7 +503,7 @@ proc CreateCalFrame { w dayNames } {
} }
global MondayFirst global MondayFirst
frame $w frame $w -background $Option(WinBackground)
for {set i 0} {$i < 7} {incr i} { for {set i 0} {$i < 7} {incr i} {
if {$MondayFirst} { if {$MondayFirst} {
set index [expr ($i+1)%7] set index [expr ($i+1)%7]
@@ -469,7 +511,7 @@ proc CreateCalFrame { w dayNames } {
set index $i set index $i
} }
label $w.day$i -border 1 -text [lindex $dayNames $index] -justify center label $w.day$i -border 1 -text [lindex $dayNames $index] -justify center -font HeadingFont -foreground $Option(LabelColor) -background $Option(WinBackground)
grid configure $w.day$i -row 0 -column $i -sticky ew grid configure $w.day$i -row 0 -column $i -sticky ew
} }
for {set i 0} {$i < 6} {incr i} { for {set i 0} {$i < 6} {incr i} {
@@ -477,9 +519,9 @@ proc CreateCalFrame { w dayNames } {
for {set j 0} {$j < 7} {incr j} { for {set j 0} {$j < 7} {incr j} {
set f [expr $n+$j] set f [expr $n+$j]
button $w.l$f -text "" -justify center -command "" \ button $w.l$f -text "" -justify center -command "" \
-state disabled -relief flat -border 0 -padx 0 -pady 0 -state disabled -relief flat -border 0 -padx 0 -pady 0 -font HeadingFont
text $w.t$f -width 12 -height $h -border 1 -spacing3 3 -wrap word -relief flat \ text $w.t$f -width 12 -height $h -border 1 -spacing3 3 -wrap word -relief flat \
-state disabled -takefocus 0 -cursor {} -state disabled -takefocus 0 -cursor {} -font CalboxFont -foreground $Option(TextColor) -background $Option(BackgroundColor)
$w.t$f tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$f" $w.t$f tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$f"
$w.t$f tag bind REM <ButtonPress-3> "FireEditor $w.t$f" $w.t$f tag bind REM <ButtonPress-3> "FireEditor $w.t$f"
@@ -509,18 +551,17 @@ proc CreateCalFrame { w dayNames } {
#*********************************************************************** #***********************************************************************
proc ConfigureCalFrame { w firstDay numDays } { proc ConfigureCalFrame { w firstDay numDays } {
global CurMonth CurYear TodayMonth TodayYear TodayDay global CurMonth CurYear TodayMonth TodayYear TodayDay
global tk_version global tk_version Option
set offset [CalEntryOffset $firstDay] set offset [CalEntryOffset $firstDay]
set first [expr $offset+1] set first [expr $offset+1]
set last [expr $offset+$numDays] set last [expr $offset+$numDays]
set bg [lindex [. configure -background] 3]
for {set i 0} {$i < $first} {incr i} { for {set i 0} {$i < $first} {incr i} {
grid $w.l$i $w.t$i grid $w.l$i $w.t$i
$w.l$i configure -text "" -command "" -state disabled -relief flat $w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground)
$w.l$i configure -state disabled
balloon_add_help $w.l$i "" balloon_add_help $w.l$i ""
$w.t$i configure -relief flat -takefocus 0 -state normal $w.t$i configure -relief flat -takefocus 0 -state normal -background $Option(WinBackground)
$w.t$i delete 1.0 end $w.t$i delete 1.0 end
foreach t [$w.t$i tag names] { foreach t [$w.t$i tag names] {
$w.t$i tag delete $t $w.t$i tag delete $t
@@ -528,16 +569,14 @@ proc ConfigureCalFrame { w firstDay numDays } {
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i" $w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i" $w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled $w.t$i configure -state disabled
$w.t$i configure -background $bg
$w.l$i configure -background $bg
} }
for {set i $first} {$i <= $last} {incr i} { for {set i $first} {$i <= $last} {incr i} {
grid $w.l$i $w.t$i grid $w.l$i $w.t$i
set d [expr $i-$first+1] set d [expr $i-$first+1]
$w.l$i configure -text $d -state normal -relief flat \ $w.l$i configure -text $d -state normal -relief flat \
-command "ModifyDay $d $firstDay" -command "ModifyDay $d $firstDay" -foreground $Option(LabelColor) -background $Option(WinBackground)
balloon_add_help $w.l$i "Add a reminder..." balloon_add_help $w.l$i "Add a reminder..."
$w.t$i configure -relief sunken -takefocus 1 -state normal $w.t$i configure -relief sunken -takefocus 1 -state normal -foreground $Option(TextColor) -background $Option(BackgroundColor)
$w.t$i delete 1.0 end $w.t$i delete 1.0 end
foreach t [$w.t$i tag names] { foreach t [$w.t$i tag names] {
$w.t$i tag delete $t $w.t$i tag delete $t
@@ -545,8 +584,6 @@ proc ConfigureCalFrame { w firstDay numDays } {
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i" $w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i" $w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled $w.t$i configure -state disabled
$w.t$i configure -background $bg
$w.l$i configure -background $bg
} }
set forgetIt 0 set forgetIt 0
for {set i [expr $last+1]} {$i < 42} {incr i} { for {set i [expr $last+1]} {$i < 42} {incr i} {
@@ -559,11 +596,13 @@ proc ConfigureCalFrame { w firstDay numDays } {
grid rowconfigure $w $row -weight 0 grid rowconfigure $w $row -weight 0
grid rowconfigure $w [expr $row+1] -weight 0 grid rowconfigure $w [expr $row+1] -weight 0
} else { } else {
grid $w.l$i $w.t$i
grid rowconfigure $w [expr $row+1] -weight 1 grid rowconfigure $w [expr $row+1] -weight 1
} }
$w.l$i configure -text "" -command "" -state disabled -relief flat $w.l$i configure -text "" -command "" -state normal -relief flat -foreground $Option(LabelColor) -background $Option(WinBackground)
$w.l$i configure -state disabled
balloon_add_help $w.l$i "" balloon_add_help $w.l$i ""
$w.t$i configure -relief flat -takefocus 0 -state normal $w.t$i configure -relief flat -takefocus 0 -state normal -background $Option(WinBackground)
$w.t$i delete 1.0 end $w.t$i delete 1.0 end
foreach t [$w.t$i tag names] { foreach t [$w.t$i tag names] {
$w.t$i tag delete $t $w.t$i tag delete $t
@@ -571,8 +610,6 @@ proc ConfigureCalFrame { w firstDay numDays } {
$w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i" $w.t$i tag bind TAGGED <ButtonPress-1> "EditTaggedReminder $w.t$i"
$w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i" $w.t$i tag bind REM <ButtonPress-3> "FireEditor $w.t$i"
$w.t$i configure -state disabled $w.t$i configure -state disabled
$w.t$i configure -background $bg
$w.l$i configure -background $bg
} }
if { $CurMonth == $TodayMonth && $CurYear == $TodayYear } { if { $CurMonth == $TodayMonth && $CurYear == $TodayYear } {
set n [expr $TodayDay + $offset] set n [expr $TodayDay + $offset]
@@ -593,14 +630,14 @@ proc DoQueue {} {
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
proc CreateCalWindow { dayNames } { proc CreateCalWindow { dayNames } {
global Option global Option
frame .h frame .h -background $Option(WinBackground);
label .h.title -text "" -justify center -pady 1 -border 1 -relief raised label .h.title -text "" -justify center -pady 1 -border 1 -relief raised -font HeadingFont -background $Option(WinBackground) -foreground $Option(LabelColor)
pack .h.title -side top -fill x pack .h.title -side top -fill x
pack .h -side top -expand 0 -fill x pack .h -side top -expand 0 -fill x
CreateCalFrame .cal $dayNames CreateCalFrame .cal $dayNames
frame .b frame .b -background $Option(WinBackground);
button .b.prev -image leftarrow -width 24 -command {MoveMonth -1} -border 1 button .b.prev -image leftarrow -width 24 -command {MoveMonth -1} -border 1
balloon_add_help .b.prev "Go to previous month" balloon_add_help .b.prev "Go to previous month"
button .b.this -text {Today} -command {ThisMonth} -border 1 button .b.this -text {Today} -command {ThisMonth} -border 1
@@ -635,6 +672,7 @@ proc CreateCalWindow { dayNames } {
bind . <KeyPress-Next> ".b.next flash; .b.next invoke" bind . <KeyPress-Next> ".b.next flash; .b.next invoke"
bind . <KeyPress-Home> ".b.this flash; .b.this invoke" bind . <KeyPress-Home> ".b.this flash; .b.this invoke"
. configure -background $Option(WinBackground)
if {$Option(StartIconified)} { if {$Option(StartIconified)} {
wm iconify . wm iconify .
} }
@@ -736,6 +774,30 @@ proc EditOptions {} {
pack $w.extraargs -in $w.eaf -side left -expand 1 -fill x pack $w.extraargs -in $w.eaf -side left -expand 1 -fill x
$w.extraargs insert 0 $tmpOpt(ExtraRemindArgs) $w.extraargs insert 0 $tmpOpt(ExtraRemindArgs)
# Fonts
frame $w.fframe
button $w.font -text "Change entry font..." -command "ChooseCalboxFont"
button $w.hfont -text "Change heading font..." -command "ChooseHeadingFont"
pack $w.font $w.hfont -in $w.fframe -side left -expand 1 -fill x
# Colors
frame $w.colors1
label $w.textcolor -text "Text Color:"
button $w.btextcolor -background $Option(TextColor) -command [list PickColor TextColor $w.btextcolor] -text ...
label $w.bgcolor -text " Background color:"
button $w.bbgcolor -background $Option(BackgroundColor) -command [list PickColor BackgroundColor $w.bbgcolor] -text ...
grid $w.textcolor $w.btextcolor $w.bgcolor $w.bbgcolor -in $w.colors1
grid $w.bgcolor $w.bbgcolor -in $w.colors1
label $w.headcolor -text "Heading Color:"
button $w.bheadcolor -background $Option(LabelColor) -command [list PickColor LabelColor $w.bheadcolor] -text ...
label $w.wincolor -text " Window color:"
button $w.bwincolor -background $Option(WinBackground) -command [list PickColor WinBackground $w.bwincolor] -text ...
grid $w.headcolor $w.bheadcolor $w.wincolor $w.bwincolor -in $w.colors1
grid columnconfigure $w.colors1 0 -weight 1
grid columnconfigure $w.colors1 2 -weight 1
frame $w.sep1 -border 1 -relief sunken frame $w.sep1 -border 1 -relief sunken
frame $w.sep2 -border 1 -relief sunken frame $w.sep2 -border 1 -relief sunken
@@ -757,16 +819,23 @@ proc EditOptions {} {
pack $w.fsmtp -in $w.f -side top -expand 0 -fill x pack $w.fsmtp -in $w.f -side top -expand 0 -fill x
pack $w.ef -in $w.f -side top -expand 0 -fill x pack $w.ef -in $w.f -side top -expand 0 -fill x
pack $w.eaf -in $w.f -side top -expand 0 -fill x pack $w.eaf -in $w.f -side top -expand 0 -fill x
pack $w.fframe -in $w.f -side top -expand 0 -fill x
pack $w.colors1 -in $w.f -side top -expand 0 -fill x
pack $w.sep2 -in $w.f -side top -expand 0 -fill x -ipady 1 pack $w.sep2 -in $w.f -side top -expand 0 -fill x -ipady 1
button $w.apply -text "Apply Options" -command "ApplyOptions $w; destroy $w"
button $w.save -text "Save Options" -command "SaveOptions $w; destroy $w" button $w.save -text "Save Options" -command "SaveOptions $w; destroy $w"
button $w.cancel -text "Cancel" -command "destroy $w" button $w.cancel -text "Cancel" -command "CancelOptions; destroy $w"
wm protocol $w WM_DELETE_WINDOW "CancelOptions; destroy $w"
pack $w.apply $w.save $w.cancel -in $w.b -side left -expand 0 -fill x pack $w.save $w.cancel -in $w.b -side left -expand 0 -fill x
CenterWindow $w . CenterWindow $w .
} }
proc CancelOptions { } {
global Option
font configure CalboxFont {*}$Option(CalboxFont)
font configure HeadingFont {*}$Option(HeadingFont)
}
#*********************************************************************** #***********************************************************************
# %PROCEDURE: ApplyOptions # %PROCEDURE: ApplyOptions
# %ARGUMENTS: # %ARGUMENTS:
@@ -807,15 +876,15 @@ proc ApplyOptions { w } {
# %RETURNS: # %RETURNS:
# Nothing # Nothing
# %DESCRIPTION: # %DESCRIPTION:
# Saves options in $HOME/.tkremindrc # Saves options in specified config file
#*********************************************************************** #***********************************************************************
proc SaveOptions { w } { proc SaveOptions { w } {
global Option OptDescr global Option OptDescr ConfigFile
ApplyOptions $w ApplyOptions $w
set problem [catch {set f [open ~/.tkremindrc "w"]} err] set problem [catch {set f [open $ConfigFile "w"]} err]
if {$problem} { if {$problem} {
tk_dialog .error Error "Can't write ~/.tkremindrc: $err" 0 OK tk_dialog .error Error "Can't write $ConfigFile: $err" 0 OK
return return
} }
@@ -831,6 +900,11 @@ proc SaveOptions { w } {
} }
puts $f "" puts $f ""
close $f close $f
FillCalWindow
.h.title configure -background $Option(WinBackground) -foreground $Option(LabelColor)
for {set i 0} {$i < 7} {incr i} {
.cal.day$i configure -foreground $Option(LabelColor) -background $Option(WinBackground)
}
} }
#*********************************************************************** #***********************************************************************
@@ -840,25 +914,31 @@ proc SaveOptions { w } {
# %RETURNS: # %RETURNS:
# Nothing # Nothing
# %DESCRIPTION: # %DESCRIPTION:
# Loads options from ~/.tkremindrc # Loads options from $ConfigFile
#*********************************************************************** #***********************************************************************
proc LoadOptions {} { proc LoadOptions {} {
global Option global Option ConfigFile
set problem [catch {set f [open "~/.tkremindrc" "r"]}] set problem [catch {set f [open "$ConfigFile" "r"]}]
if {$problem} { if {$problem} {
return return
} }
while {[gets $f line] >= 0} { while {[gets $f line] >= 0} {
if {[string match "#*" $line]} { continue } if {[string match "#*" $line]} {
if {$line == ""} { continue } continue
foreach {key val} $line {} }
if {![info exists Option($key)]} { if {$line == ""} {
puts "Unknown option in ~/.tkremindrc: $key" continue
continue }
} foreach {key val} $line {}
set Option($key) $val if {![info exists Option($key)]} {
puts stderr "Unknown option in $ConfigFile: $key"
continue
}
set Option($key) $val
} }
close $f close $f
font configure CalboxFont {*}$Option(CalboxFont)
font configure HeadingFont {*}$Option(HeadingFont)
} }
@@ -1078,7 +1158,7 @@ proc Status { stuff } {
# None # None
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
proc DoPrint {} { proc DoPrint {} {
global PrintDest PrintSize PrintMargins PrintOrient PrintFill PrintEncoding PrintSmallCalendars PrintStatus Rem2PS PSCmd Option global PrintDest PrintSize PrintMargins PrintOrient PrintFill PrintDaysRight PrintEncoding PrintSmallCalendars PrintStatus Rem2PS PSCmd Option
global CurMonth CurYear MonthNames global CurMonth CurYear MonthNames
catch {destroy .p} catch {destroy .p}
toplevel .p toplevel .p
@@ -1114,6 +1194,7 @@ proc DoPrint {} {
radiobutton .p.portrait -text "Portrait" -variable PrintOrient -value portrait radiobutton .p.portrait -text "Portrait" -variable PrintOrient -value portrait
checkbutton .p.fill -text "Fill page" -variable PrintFill checkbutton .p.fill -text "Fill page" -variable PrintFill
checkbutton .p.right -text "Day numbers at top-right" -variable PrintDaysRight
checkbutton .p.encoding -text "ISO 8859-1 PostScript encoding" -variable PrintEncoding checkbutton .p.encoding -text "ISO 8859-1 PostScript encoding" -variable PrintEncoding
checkbutton .p.calendars -text "Print small calendars" -variable PrintSmallCalendars checkbutton .p.calendars -text "Print small calendars" -variable PrintSmallCalendars
@@ -1122,7 +1203,7 @@ proc DoPrint {} {
pack .p.f1 .p.f2 .p.f2a .p.f3 .p.f3a \ pack .p.f1 .p.f2 .p.f2a .p.f3 .p.f3a \
-side top -fill both -expand 1 -anchor w -side top -fill both -expand 1 -anchor w
pack .p.fill .p.encoding .p.calendars -in .p.f3a \ pack .p.fill .p.right .p.encoding .p.calendars -in .p.f3a \
-side top -anchor w -fill none -expand 0 -side top -anchor w -fill none -expand 0
pack .p.f4 -side top -fill both -expand 1 -anchor w pack .p.f4 -side top -fill both -expand 1 -anchor w
pack .p.f11 .p.f12 -in .p.f1 -side top -fill none -expand 0 -anchor w pack .p.f11 .p.f12 -in .p.f1 -side top -fill none -expand 0 -anchor w
@@ -1194,6 +1275,9 @@ proc DoPrint {} {
append cmd " -e" append cmd " -e"
} }
if {!$PrintDaysRight} {
append cmd " -x"
}
if {$PrintEncoding} { if {$PrintEncoding} {
append cmd " -i" append cmd " -i"
} }
@@ -1296,15 +1380,20 @@ proc DoGoto {} {
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
proc Quit {} { proc Quit {} {
global Option global Option
global InotifyFP
if { !$Option(ConfirmQuit) } { if { !$Option(ConfirmQuit) } {
destroy . destroy .
StopBackgroundRemindDaemon StopBackgroundRemindDaemon
exit catch { exec kill [pid $InotifyFP] }
catch { close $InotifyFP }
exit 0
} }
if { [tk_dialog .question "Confirm..." {Really quit?} question 0 No Yes] } { if { [tk_dialog .question "Confirm..." {Really quit?} question 0 No Yes] } {
destroy . destroy .
StopBackgroundRemindDaemon StopBackgroundRemindDaemon
exit catch { exec kill [pid $InotifyFP] }
catch { close $InotifyFP }
exit 0
} }
} }
@@ -1777,8 +1866,7 @@ proc ModifyDay {d firstDay} {
WriteReminder $f TKTAG$HighestTagSoFar $rem $opts WriteReminder $f TKTAG$HighestTagSoFar $rem $opts
close $f close $f
FillCalWindow ScheduleUpdateForChanges
RestartBackgroundRemindDaemon
return 0 return 0
} }
} }
@@ -2485,7 +2573,7 @@ proc DaemonReadable { file } {
} }
} }
default { default {
puts "Unknown message from daemon: $line\n" puts stderr "Unknown message from daemon: $line\n"
} }
} }
} }
@@ -2613,27 +2701,33 @@ proc CommandWritable { f msg } {
proc main {} { proc main {} {
# If no ~/.tkremindrc file, create an empty one global ConfigFile
if {![file exists ~/.tkremindrc]} {
catch { font create CalboxFont {*}[font actual TkFixedFont]
set f [open ~/.tkremindrc "w"] font create HeadingFont {*}[font actual TkDefaultFont]
close $f
}
}
global AppendFile HighestTagSoFar DayNames global AppendFile HighestTagSoFar DayNames
catch { catch {
puts "\nTkRemind Copyright (C) 1996-2020 Dianne Skoll" puts "\nTkRemind Copyright (C) 1996-2021 Dianne Skoll"
} }
catch { SetFonts } catch { SetFonts }
Initialize
# If no $ConfigFile file, create an empty one
if {![file exists $ConfigFile]} {
catch {
set f [open $ConfigFile "w"]
close $f
}
}
LoadOptions LoadOptions
CreateMoonImages CreateMoonImages
Initialize
ShowTodaysReminders ShowTodaysReminders
ScanForTags $AppendFile ScanForTags $AppendFile
CreateCalWindow $DayNames CreateCalWindow $DayNames
FillCalWindow FillCalWindow
StartBackgroundRemindDaemon StartBackgroundRemindDaemon
SetupInotify
DisplayTimeContinuously DisplayTimeContinuously
} }
@@ -3048,12 +3142,13 @@ proc TaggedEnter { w } {
# Removes highlight from an "editable" reminder as mouse leaves it # Removes highlight from an "editable" reminder as mouse leaves it
#*********************************************************************** #***********************************************************************
proc TaggedLeave { w } { proc TaggedLeave { w } {
global Option
set tag [GetCurrentReminder $w] set tag [GetCurrentReminder $w]
if {$tag != ""} { if {$tag != ""} {
set tags [$w tag names current] set tags [$w tag names current]
set index [lsearch -glob $tags "clr*"] set index [lsearch -glob $tags "clr*"]
if {$index < 0} { if {$index < 0} {
set fg "#000000" set fg $Option(TextColor)
} else { } else {
set fg [string range [lindex $tags $index] 3 end] set fg [string range [lindex $tags $index] 3 end]
set fg "#$fg" set fg "#$fg"
@@ -3134,12 +3229,38 @@ proc EditTaggedReminder { w } {
return 1 return 1
} }
FillCalWindow ScheduleUpdateForChanges
RestartBackgroundRemindDaemon
return 0 return 0
} }
} }
#***********************************************************************
# %PROCEDURE: UpdateForChanges
# Updates the calendar window and restarts background daemon because
# something has changed.
# %ARGUMENTS:
# None
# %RETURNS:
# Nothing
#***********************************************************************
proc UpdateForChanges {} {
global TimerUpdateForChanges
catch { after cancel $TimerUpdateForChanges }
FillCalWindow
RestartBackgroundRemindDaemon
}
# Schedule an update for 100ms in the future.
# That way, if we get a rapid succession of
# change notifications, we (probably) only
# end up doing one call to UpdateForChanges
proc ScheduleUpdateForChanges {} {
global TimerUpdateForChanges
catch { after cancel $TimerUpdateForChanges }
set TimerUpdateForChanges [after 100 UpdateForChanges]
}
#*********************************************************************** #***********************************************************************
# %PROCEDURE: UniqueFileName # %PROCEDURE: UniqueFileName
# %ARGUMENTS: # %ARGUMENTS:
@@ -3468,8 +3589,7 @@ proc InteractiveDeleteReminder { tag } {
set ans [tk_dialog .error "Really Delete" "Really delete reminder?" warning 0 No Yes] set ans [tk_dialog .error "Really Delete" "Really delete reminder?" warning 0 No Yes]
if {$ans == 1} { if {$ans == 1} {
DeleteTaggedReminder $tag DeleteTaggedReminder $tag
FillCalWindow ScheduleUpdateForChanges
RestartBackgroundRemindDaemon
} }
} }
@@ -3522,10 +3642,35 @@ proc SetFonts {} {
set SetFontsWorked 1 set SetFontsWorked 1
} }
# Set up inotify to watch for changes to reminder file/directory
proc SetupInotify {} {
global InotifyFP
global ReminderFile
set failed [catch {set InotifyFP [open "|inotifywait -q -m -e close_write -e move -e create -e delete $ReminderFile" "r"] } ]
if {$failed} {
# inotifywait probably not available... meh.
return
}
fileevent $InotifyFP readable [list InotifyReadable $InotifyFP]
}
# Called when inotifywait reports an event. Schedule a calendar update
# and daemon reload.
proc InotifyReadable { fp } {
catch { set num [gets $fp line] }
if {$num < 0} {
catch { exec kill [pid $fp] }
close $fp
return
}
ScheduleUpdateForChanges
}
### Balloon help ### Balloon help
set Balloon(HelpTime) 400 set Balloon(HelpTime) 400
set Balloon(StayTime) 3500 set Balloon(StayTime) 3500
set Balloon(Font) fixed set Balloon(Font) fixed
set Balloon(MustLeave) 0
proc balloon_reset_timer { w } { proc balloon_reset_timer { w } {
balloon_destroy_help_window balloon_destroy_help_window
@@ -3639,4 +3784,40 @@ proc balloon_calculate_geometry { w } {
return "+$tx+$ty" return "+$tx+$ty"
} }
proc ChooseCalboxFont {} {
tk fontchooser show
tk fontchooser configure -font [font actual CalboxFont]
tk fontchooser configure -command SetCalboxFont
}
proc SetCalboxFont {font} {
global tmpOpt
font configure CalboxFont {*}[font actual $font]
set tmpOpt(CalboxFont) [font actual $font]
raise .opt
}
proc ChooseHeadingFont {} {
tk fontchooser show
tk fontchooser configure -font [font actual HeadingFont]
tk fontchooser configure -command SetHeadingFont
}
proc SetHeadingFont {font} {
global tmpOpt
font configure HeadingFont {*}[font actual $font]
set tmpOpt(HeadingFont) [font actual $font]
raise .opt
}
proc PickColor {index button} {
global tmpOpt
set x [tk_chooseColor -initialcolor $tmpOpt($index)]
if {"$x" != ""} {
set tmpOpt($index) $x
$button configure -background $x
}
raise .opt
}
main main

View File

@@ -13,6 +13,7 @@
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <limits.h>
#include <stdlib.h> #include <stdlib.h>
@@ -493,6 +494,7 @@ static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
int len; int len;
int h, m, r; int h, m, r;
int ampm = 0; int ampm = 0;
int prev_val;
if (*s == '\"') { /* It's a literal string "*/ if (*s == '\"') { /* It's a literal string "*/
len = strlen(s)-1; len = strlen(s)-1;
@@ -519,9 +521,15 @@ static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
return OK; return OK;
} else if (isdigit(*s)) { /* It's a number - use len to hold it.*/ } else if (isdigit(*s)) { /* It's a number - use len to hold it.*/
len = 0; len = 0;
prev_val = 0;
while (*s && isdigit(*s)) { while (*s && isdigit(*s)) {
len *= 10; len *= 10;
len += (*s++ - '0'); len += (*s++ - '0');
if (len < prev_val) {
/* We overflowed */
return E_2HIGH;
}
prev_val = len;
} }
if (*s == ':' || *s == '.' || *s == TimeSep) { /* Must be a literal time */ if (*s == ':' || *s == '.' || *s == TimeSep) { /* Must be a literal time */
s++; s++;
@@ -758,15 +766,22 @@ static int Add(void)
/* If both are ints, just add 'em */ /* If both are ints, just add 'em */
if (v2.type == INT_TYPE && v1.type == INT_TYPE) { if (v2.type == INT_TYPE && v1.type == INT_TYPE) {
v2.v.val += v1.v.val; int old = v1.v.val;
PushValStack(v2); v1.v.val += v2.v.val;
/* Check for overflow */
if (_private_add_overflow(v1.v.val, v2.v.val, old)) {
return E_2HIGH;
}
PushValStack(v1);
return OK; return OK;
} }
/* If it's a date plus an int, add 'em */ /* If it's a date plus an int, add 'em */
if ((v1.type == DATE_TYPE && v2.type == INT_TYPE) || if ((v1.type == DATE_TYPE && v2.type == INT_TYPE) ||
(v1.type == INT_TYPE && v2.type == DATE_TYPE)) { (v1.type == INT_TYPE && v2.type == DATE_TYPE)) {
int old = v1.v.val;
v1.v.val += v2.v.val; v1.v.val += v2.v.val;
if (_private_add_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
if (v1.v.val < 0) return E_DATE_OVER; if (v1.v.val < 0) return E_DATE_OVER;
v1.type = DATE_TYPE; v1.type = DATE_TYPE;
PushValStack(v1); PushValStack(v1);
@@ -776,7 +791,9 @@ static int Add(void)
/* If it's a datetime plus an int or a time, add 'em */ /* If it's a datetime plus an int or a time, add 'em */
if ((v1.type == DATETIME_TYPE && (v2.type == INT_TYPE || v2.type == TIME_TYPE)) || if ((v1.type == DATETIME_TYPE && (v2.type == INT_TYPE || v2.type == TIME_TYPE)) ||
((v1.type == INT_TYPE || v1.type == TIME_TYPE) && v2.type == DATETIME_TYPE)) { ((v1.type == INT_TYPE || v1.type == TIME_TYPE) && v2.type == DATETIME_TYPE)) {
int old = v1.v.val;
v1.v.val += v2.v.val; v1.v.val += v2.v.val;
if (_private_add_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
if (v1.v.val < 0) return E_DATE_OVER; if (v1.v.val < 0) return E_DATE_OVER;
v1.type = DATETIME_TYPE; v1.type = DATETIME_TYPE;
PushValStack(v1); PushValStack(v1);
@@ -788,7 +805,10 @@ static int Add(void)
if ((v1.type == TIME_TYPE && v2.type == INT_TYPE) || if ((v1.type == TIME_TYPE && v2.type == INT_TYPE) ||
(v1.type == INT_TYPE && v2.type == TIME_TYPE) || (v1.type == INT_TYPE && v2.type == TIME_TYPE) ||
(v1.type == TIME_TYPE && v2.type == TIME_TYPE)) { (v1.type == TIME_TYPE && v2.type == TIME_TYPE)) {
v1.v.val = (v1.v.val + v2.v.val) % MINUTES_PER_DAY; int old = v1.v.val;
v1.v.val += v2.v.val;
if (_private_add_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
v1.v.val = v1.v.val % MINUTES_PER_DAY;
if (v1.v.val < 0) v1.v.val += MINUTES_PER_DAY; if (v1.v.val < 0) v1.v.val += MINUTES_PER_DAY;
v1.type = TIME_TYPE; v1.type = TIME_TYPE;
PushValStack(v1); PushValStack(v1);
@@ -848,14 +868,18 @@ static int Subtract(void)
/* If they're both INTs, do subtraction */ /* If they're both INTs, do subtraction */
if (v1.type == INT_TYPE && v2.type == INT_TYPE) { if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
int old = v1.v.val;
v1.v.val -= v2.v.val; v1.v.val -= v2.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_2HIGH;
PushValStack(v1); PushValStack(v1);
return OK; return OK;
} }
/* If it's a date minus an int, do subtraction, checking for underflow */ /* If it's a date minus an int, do subtraction, checking for underflow */
if (v1.type == DATE_TYPE && v2.type == INT_TYPE) { if (v1.type == DATE_TYPE && v2.type == INT_TYPE) {
int old = v1.v.val;
v1.v.val -= v2.v.val; v1.v.val -= v2.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
if (v1.v.val < 0) return E_DATE_OVER; if (v1.v.val < 0) return E_DATE_OVER;
PushValStack(v1); PushValStack(v1);
return OK; return OK;
@@ -864,7 +888,9 @@ static int Subtract(void)
/* If it's a datetime minus an int or a time, do subtraction, /* If it's a datetime minus an int or a time, do subtraction,
* checking for underflow */ * checking for underflow */
if (v1.type == DATETIME_TYPE && (v2.type == INT_TYPE || v2.type == TIME_TYPE)) { if (v1.type == DATETIME_TYPE && (v2.type == INT_TYPE || v2.type == TIME_TYPE)) {
int old = v1.v.val;
v1.v.val -= v2.v.val; v1.v.val -= v2.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
if (v1.v.val < 0) return E_DATE_OVER; if (v1.v.val < 0) return E_DATE_OVER;
PushValStack(v1); PushValStack(v1);
return OK; return OK;
@@ -882,7 +908,9 @@ static int Subtract(void)
if ((v1.type == TIME_TYPE && v2.type == TIME_TYPE) || if ((v1.type == TIME_TYPE && v2.type == TIME_TYPE) ||
(v1.type == DATETIME_TYPE && v2.type == DATETIME_TYPE) || (v1.type == DATETIME_TYPE && v2.type == DATETIME_TYPE) ||
(v1.type == DATE_TYPE && v2.type == DATE_TYPE)) { (v1.type == DATE_TYPE && v2.type == DATE_TYPE)) {
int old = v1.v.val;
v1.v.val -= v2.v.val; v1.v.val -= v2.v.val;
if (_private_sub_overflow(v1.v.val, v2.v.val, old)) return E_DATE_OVER;
v1.type = INT_TYPE; v1.type = INT_TYPE;
PushValStack(v1); PushValStack(v1);
return OK; return OK;
@@ -912,7 +940,11 @@ static int Multiply(void)
} }
if (v1.type == INT_TYPE && v2.type == INT_TYPE) { if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
int old = v1.v.val;
v1.v.val *= v2.v.val; v1.v.val *= v2.v.val;
if (v2.v.val != 0) {
if (_private_div(v1.v.val, v2.v.val) != old) return E_2HIGH;
}
PushValStack(v1); PushValStack(v1);
return OK; return OK;
} }
@@ -940,6 +972,10 @@ static int Divide(void)
if (v1.type == INT_TYPE && v2.type == INT_TYPE) { if (v1.type == INT_TYPE && v2.type == INT_TYPE) {
if (v2.v.val == 0) return E_DIV_ZERO; if (v2.v.val == 0) return E_DIV_ZERO;
/* This is the only way it can overflow */
if (v2.v.val == -1 && v1.v.val == INT_MIN) {
return E_2HIGH;
}
v1.v.val /= v2.v.val; v1.v.val /= v2.v.val;
PushValStack(v1); PushValStack(v1);
return OK; return OK;
@@ -1114,7 +1150,9 @@ static int UnMinus(void)
{ {
Value *v = &ValStack[ValStackPtr-1]; Value *v = &ValStack[ValStackPtr-1];
if (v->type != INT_TYPE) return E_BAD_TYPE; if (v->type != INT_TYPE) return E_BAD_TYPE;
int old = v->v.val;
v->v.val = -v->v.val; v->v.val = -v->v.val;
if (_private_unminus_overflow(old, v->v.val)) return E_2HIGH;
return OK; return OK;
} }

View File

@@ -5,7 +5,7 @@
/* Contains a few definitions used by expression evaluator. */ /* Contains a few definitions used by expression evaluator. */
/* */ /* */
/* This file is part of REMIND. */ /* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */ /* Copyright (C) 1992-2021 by Dianne Skoll */
/* */ /* */
/***************************************************************/ /***************************************************************/
@@ -53,3 +53,12 @@ if (ValStackPtr <= 0) \
return E_VA_STK_UNDER; \ return E_VA_STK_UNDER; \
else \ else \
(val) = ValStack[--ValStackPtr] (val) = ValStack[--ValStackPtr]
/* These functions are in utils.c and are used to detect overflow
in various arithmetic operators. They have to be in separate
functions with extern linkage to defeat compiler optimizations
that would otherwise break the overflow checks. */
extern int _private_div(int a, int b);
extern int _private_add_overflow(int result, int b, int old);
extern int _private_sub_overflow(int result, int b, int old);
extern int _private_unminus_overflow(int a, int b);

View File

@@ -866,12 +866,14 @@ static int FTime(func_info *info)
/***************************************************************/ /***************************************************************/
static int FAbs(func_info *info) static int FAbs(func_info *info)
{ {
int v; volatile int v;
ASSERT_TYPE(0, INT_TYPE); ASSERT_TYPE(0, INT_TYPE);
v = ARGV(0); v = ARGV(0);
RetVal.type = INT_TYPE; RetVal.type = INT_TYPE;
RETVAL = (v < 0) ? (-v) : v; RETVAL = (v < 0) ? (-v) : v;
v = RETVAL;
if (v < 0) return E_2HIGH;
return OK; return OK;
} }

View File

@@ -5,7 +5,7 @@
/* Print a PostScript calendar. */ /* Print a PostScript calendar. */
/* */ /* */
/* This file is part of REMIND. */ /* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */ /* Copyright (C) 1992-2021 by Dianne Skoll */
/* */ /* */
/***************************************************************/ /***************************************************************/
@@ -99,6 +99,7 @@ CalEntry *CurEntries = NULL;
CalEntry *PsEntries[32]; CalEntry *PsEntries[32];
PageType *CurPage; PageType *CurPage;
char PortraitMode; char PortraitMode;
char DaynumRight;
char NoSmallCal; char NoSmallCal;
char UseISO; char UseISO;
@@ -140,6 +141,18 @@ void WriteOneEntry (CalEntry *c);
void GetSmallLocations (void); void GetSmallLocations (void);
char const *EatToken(char const *in, char *out, int maxlen); char const *EatToken(char const *in, char *out, int maxlen);
static void
put_escaped_string(char const *s)
{
while(*s) {
if (*s == '\\' || *s == '(' || *s == ')') {
PutChar('\\');
}
PutChar(*s);
s++;
}
}
/***************************************************************/ /***************************************************************/
/* */ /* */
/* StrCmpi */ /* StrCmpi */
@@ -336,7 +349,7 @@ int main(int argc, char *argv[])
!strcmp(DBufValue(&buf), PSBEGIN2)) { !strcmp(DBufValue(&buf), PSBEGIN2)) {
if (!validfile) { if (!validfile) {
if (Verbose) { if (Verbose) {
fprintf(stderr, "Rem2PS: Version %s Copyright 1992-2020 by Dianne Skoll\n\n", VERSION); fprintf(stderr, "Rem2PS: Version %s Copyright 1992-2021 by Dianne Skoll\n\n", VERSION);
fprintf(stderr, "Generating PostScript calendar\n"); fprintf(stderr, "Generating PostScript calendar\n");
} }
} }
@@ -587,6 +600,12 @@ void WriteProlog(void)
printf("%%%%Pages: (atend)\n"); printf("%%%%Pages: (atend)\n");
printf("%%%%Orientation: %s\n", PortraitMode ? "Portrait" : "Landscape"); printf("%%%%Orientation: %s\n", PortraitMode ? "Portrait" : "Landscape");
printf("%%%%EndComments\n"); printf("%%%%EndComments\n");
if (PortraitMode) {
printf("<< /PageSize [%d %d] >> setpagedevice\n", x, y);
} else {
/* They were swapped up above, so swap them back or we'll get rotated output */
printf("<< /PageSize [%d %d] >> setpagedevice\n", y, x);
}
for (i=0; PSProlog1[i]; i++) puts(PSProlog1[i]); for (i=0; PSProlog1[i]; i++) puts(PSProlog1[i]);
if (!MondayFirst) if (!MondayFirst)
@@ -679,7 +698,7 @@ void WriteCalEntry(void)
printf("]\n"); printf("]\n");
/* Print the day number */ /* Print the day number */
printf("(%d)\n", CurDay); printf("(%d) %d\n", CurDay, (int) DaynumRight);
/* Do it! */ /* Do it! */
printf("DoCalBox\n"); printf("DoCalBox\n");
@@ -819,6 +838,7 @@ void Init(int argc, char *argv[])
FillPage = 0; FillPage = 0;
MondayFirst = 0; MondayFirst = 0;
SmallLocation = "bt"; SmallLocation = "bt";
DaynumRight = 1;
for(j=0; j<32; j++) PsEntries[i] = NULL; for(j=0; j<32; j++) PsEntries[i] = NULL;
@@ -935,6 +955,7 @@ void Init(int argc, char *argv[])
case 'i': UseISO = 1; break; case 'i': UseISO = 1; break;
case 'x': DaynumRight = 0; break;
case 'c': k=(*s); case 'c': k=(*s);
if (!k) { if (!k) {
SmallLocation = SmallCalLoc[0]; SmallLocation = SmallCalLoc[0];
@@ -979,6 +1000,7 @@ void Usage(char const *s)
fprintf(stderr, "-b size Set border size for calendar entries\n"); fprintf(stderr, "-b size Set border size for calendar entries\n");
fprintf(stderr, "-t size Set line thickness\n"); fprintf(stderr, "-t size Set line thickness\n");
fprintf(stderr, "-e Make calendar fill entire page\n"); fprintf(stderr, "-e Make calendar fill entire page\n");
fprintf(stderr, "-x Put day numbers on left instead of right\n");
fprintf(stderr, "-o[lrtb] marg Specify left, right, top and bottom margins\n"); fprintf(stderr, "-o[lrtb] marg Specify left, right, top and bottom margins\n");
exit(1); exit(1);
} }
@@ -1054,10 +1076,10 @@ int DoQueuedPs(void)
FILE *fp; FILE *fp;
int fnoff; int fnoff;
char buffer[512]; char buffer[512];
char const *size, *extra; char fbuffer[512];
char const *size, *fsize, *extra;
char const *s; char const *s;
int num, r, g, b, phase, fontsize, moonsize; int num, r, g, b, phase, fontsize, moonsize;
unsigned char c;
if (!MondayFirst) begin = CurDay - WkDayNum; if (!MondayFirst) begin = CurDay - WkDayNum;
else begin = CurDay - (WkDayNum ? WkDayNum-1 : 6); else begin = CurDay - (WkDayNum ? WkDayNum-1 : 6);
@@ -1129,19 +1151,28 @@ int DoQueuedPs(void)
while(*s && isspace(*s)) { while(*s && isspace(*s)) {
s++; s++;
} }
while(*s) { put_escaped_string(s);
if (*s == '\\' || *s == '(' || *s == ')') {
PutChar('\\');
}
PutChar(*s);
s++;
}
printf(") show grestore\n"); printf(") show grestore\n");
break; break;
case SPECIAL_MOON: /* Moon phase */ case SPECIAL_MOON: /* Moon phase */
num = sscanf(e->entry+fnoff, "%d %d %d", &phase, &moonsize, num = sscanf(e->entry+fnoff, "%d %d %d", &phase, &moonsize,
&fontsize); &fontsize);
/* See if we have extra stuff */
extra = e->entry+fnoff;
/* Skip phase */
while(*extra && !isspace(*extra)) extra++;
while(*extra && isspace(*extra)) extra++;
/* Skip moon size */
while(*extra && !isspace(*extra)) extra++;
while(*extra && isspace(*extra)) extra++;
/* Skip font size */
while(*extra && !isspace(*extra)) extra++;
while(*extra && isspace(*extra)) extra++;
if (num == 1) { if (num == 1) {
moonsize = -1; moonsize = -1;
fontsize = -1; fontsize = -1;
@@ -1163,7 +1194,27 @@ int DoQueuedPs(void)
size = buffer; size = buffer;
} }
printf("gsave 0 setgray newpath Border %s add BoxHeight Border sub %s sub\n", size, size); /* Store the starting X coordinate in "moonstartx" */
if (DaynumRight) {
printf("Border %s add /moonstartx exch def", size);
} else {
printf("xincr Border sub %s sub ", size);
if (*extra) {
if (fontsize < 0) {
fsize = "EntrySize";
} else {
sprintf(fbuffer, "%d", fontsize);
fsize = fbuffer;
}
printf("/EntryFont findfont %s scalefont setfont (",
fsize);
put_escaped_string(extra);
printf(") stringwidth pop sub Border sub ");
}
printf("/moonstartx exch def\n");
}
printf(" gsave 0 setgray newpath ");
printf("moonstartx BoxHeight Border sub %s sub\n", size);
printf(" %s 0 360 arc closepath\n", size); printf(" %s 0 360 arc closepath\n", size);
switch(phase) { switch(phase) {
case 0: case 0:
@@ -1174,49 +1225,28 @@ int DoQueuedPs(void)
break; break;
case 1: case 1:
printf("stroke\n"); printf("stroke\nnewpath ");
printf("newpath Border %s add BoxHeight Border sub %s sub\n", printf("moonstartx BoxHeight Border sub %s sub\n", size);
size, size);
printf("%s 90 270 arc closepath fill\n", size); printf("%s 90 270 arc closepath fill\n", size);
break; break;
default: default:
printf("stroke\n"); printf("stroke\nnewpath ");
printf("newpath Border %s add BoxHeight Border sub %s sub\n", printf("moonstartx BoxHeight Border sub %s sub\n", size);
size, size);
printf("%s 270 90 arc closepath fill\n", size); printf("%s 270 90 arc closepath fill\n", size);
break; break;
} }
/* See if we have extra stuff */
extra = e->entry+fnoff;
/* Skip phase */
while(*extra && !isspace(*extra)) extra++;
while(*extra && isspace(*extra)) extra++;
/* Skip moon size */
while(*extra && !isspace(*extra)) extra++;
while(*extra && isspace(*extra)) extra++;
/* Skip font size */
while(*extra && !isspace(*extra)) extra++;
while(*extra && isspace(*extra)) extra++;
/* Anything left? */ /* Anything left? */
if (*extra) { if (*extra) {
printf("Border %s add %s add Border add BoxHeight border sub %s sub %s sub moveto\n", size, size, size, size); printf("moonstartx %s add Border add BoxHeight border sub %s sub %s sub moveto\n", size, size, size);
if (fontsize < 0) { if (fontsize < 0) {
size = "EntrySize"; fsize = "EntrySize";
} else { } else {
sprintf(buffer, "%d", fontsize); sprintf(fbuffer, "%d", fontsize);
size = buffer; fsize = fbuffer;
} }
printf("/EntryFont findfont %s scalefont setfont (", printf("/EntryFont findfont %s scalefont setfont (",
size); fsize);
while(*extra) { put_escaped_string(extra);
c = (unsigned char) *extra++;
if (c == '\\' || c == '(' || c == ')') PutChar('\\');
PutChar(c);
}
printf(") show\n"); printf(") show\n");
} }

View File

@@ -5,7 +5,7 @@
/* Define the PostScript prologue */ /* Define the PostScript prologue */
/* */ /* */
/* This file is part of REMIND. */ /* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */ /* Copyright (C) 1992-2021 by Dianne Skoll */
/* */ /* */
/***************************************************************/ /***************************************************************/
@@ -13,7 +13,7 @@ char *PSProlog1[] =
{ {
"% This file was produced by Remind and Rem2PS, written by", "% This file was produced by Remind and Rem2PS, written by",
"% Dianne Skoll.", "% Dianne Skoll.",
"% Remind and Rem2PS are Copyright 1992-2020 Dianne Skoll.", "% Remind and Rem2PS are Copyright 1992-2021 Dianne Skoll.",
"/ISOLatin1Encoding where { pop save true }{ false } ifelse", "/ISOLatin1Encoding where { pop save true }{ false } ifelse",
" /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus", " /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus",
" StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute", " StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute",
@@ -196,9 +196,10 @@ char *PSProlog2[] =
"% Variables for calendar boxes:", "% Variables for calendar boxes:",
"% ytop - current top position", "% ytop - current top position",
"% ymin - minimum y reached for current row", "% ymin - minimum y reached for current row",
"% border ytop xleft width textarray daynum DoCalBox ybot", "% border ytop xleft width textarray daynum onright DoCalBox ybot",
"% Do the entries for one calendar box. Returns lowest Y-coordinate reached", "% Do the entries for one calendar box. Returns lowest Y-coordinate reached",
"/DoCalBox {", "/DoCalBox {",
" /onright exch def",
" /daynum exch def", " /daynum exch def",
" /textarr exch def", " /textarr exch def",
" /wid exch def", " /wid exch def",
@@ -207,8 +208,10 @@ char *PSProlog2[] =
" /border exch def", " /border exch def",
"% Do the day number", "% Do the day number",
" /DayFont findfont DaySize scalefont setfont", " /DayFont findfont DaySize scalefont setfont",
" xl wid add border sub daynum stringwidth pop sub", " onright 1 eq",
" yt border sub DaySize sub moveto daynum show", " {xl wid add border sub daynum stringwidth pop sub yt border sub DaySize sub moveto daynum show}",
" {xl border add yt border sub DaySize sub moveto daynum show}",
" ifelse",
"% Do the text entries. Precharge the stack with current y pos.", "% Do the text entries. Precharge the stack with current y pos.",
" /ycur yt border sub DaySize sub DaySize sub 2 add def", " /ycur yt border sub DaySize sub DaySize sub 2 add def",
" /EntryFont findfont EntrySize scalefont setfont", " /EntryFont findfont EntrySize scalefont setfont",

View File

@@ -123,3 +123,26 @@ int DateOK(int y, int m, int d)
d > DaysInMonth(m, y) ) return 0; d > DaysInMonth(m, y) ) return 0;
else return 1; else return 1;
} }
/* Functions designed to defeat gcc optimizer */
int _private_div(int a, int b) { return a/b; }
int _private_add_overflow(int result, int b, int old)
{
if (b > 0 && result < old) return 1;
if (b < 0 && result > old) return 1;
return 0;
}
int _private_sub_overflow(int result, int b, int old)
{
if (b < 0 && result < old) return 1;
if (b > 0 && result > old) return 1;
return 0;
}
int _private_unminus_overflow(int a, int b)
{
if (a > 0 && b > 0) return 1;
if (a < 0 && b < 0) return 1;
return 0;
}

View File

@@ -17,6 +17,7 @@
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h>
#include "types.h" #include "types.h"
#include "expr.h" #include "expr.h"
#include "globals.h" #include "globals.h"
@@ -31,6 +32,9 @@
#define VALUE ErrMsg[E_VAL] #define VALUE ErrMsg[E_VAL]
#define UNDEF ErrMsg[E_UNDEF] #define UNDEF ErrMsg[E_UNDEF]
static int IntMin = INT_MIN;
static int IntMax = INT_MAX;
static Var *VHashTbl[VAR_HASH_SIZE]; static Var *VHashTbl[VAR_HASH_SIZE];
typedef int (*SysVarFunc)(int, Value *); typedef int (*SysVarFunc)(int, Value *);
@@ -661,6 +665,8 @@ static SysVar SysVarArr[] = {
{"HushMode", 0, INT_TYPE, &Hush, 0, 0 }, {"HushMode", 0, INT_TYPE, &Hush, 0, 0 },
{"IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 0, 0 }, {"IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 0, 0 },
{"InfDelta", 0, INT_TYPE, &InfiniteDelta, 0, 0 }, {"InfDelta", 0, INT_TYPE, &InfiniteDelta, 0, 0 },
{"IntMax", 0, INT_TYPE, &IntMax, 0, 0 },
{"IntMin", 0, INT_TYPE, &IntMin, 0, 0 },
{"LatDeg", 1, INT_TYPE, &LatDeg, -90, 90 }, {"LatDeg", 1, INT_TYPE, &LatDeg, -90, 90 },
{"LatMin", 1, INT_TYPE, &LatMin, -59, 59 }, {"LatMin", 1, INT_TYPE, &LatMin, -59, 59 },
{"LatSec", 1, INT_TYPE, &LatSec, -59, 59 }, {"LatSec", 1, INT_TYPE, &LatSec, -59, 59 },

View File

@@ -3,6 +3,6 @@ cd /home/dfs/Software/Remind.git || exit 1
rm -f .git/COMMIT_EDITMSG .git/*~ rm -f .git/COMMIT_EDITMSG .git/*~
git update-server-info && cd .git && rsync --archive --verbose --progress --delete ./ dianne.skoll.ca:web/projects/remind/git/Remind.git/ git update-server-info && cd .git && rsync --exclude HEADER.html --archive --verbose --progress --delete ./ dianne.skoll.ca:web/projects/remind/git/Remind.git/
exit $? exit $?

View File

@@ -289,8 +289,17 @@ rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF EOF
export LC_ALL=en_US.utf-8 # If we're already in a utf-8 locale, do
export LANG=en_US.utf-8 # nothing
if ! echo $LC_ALL | grep -i utf-8 > /dev/null 2>&1 ; then
export LC_ALL=en_US.utf-8
fi
if ! echo $LANG | grep -i utf-8 > /dev/null 2>&1 ; then
export LANG=en_US.utf-8
fi
../src/remind -w128 -c ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out ../src/remind -w128 -c ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out
cmp -s ../tests/test.out ../tests/test.cmp cmp -s ../tests/test.out ../tests/test.cmp
if [ "$?" = "0" ]; then if [ "$?" = "0" ]; then

View File

@@ -857,7 +857,7 @@ set a057 value("a05"+"6")
"a05" + "6" => "a056" "a05" + "6" => "a056"
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH" value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
set a058 version() set a058 version()
version() => "03.03.03" version() => "03.03.06"
set a059 wkday(today()) set a059 wkday(today())
today() => 1991-02-16 today() => 1991-02-16
wkday(1991-02-16) => "Saturday" wkday(1991-02-16) => "Saturday"
@@ -2426,7 +2426,7 @@ a086 4
a109 2012-01-01 a109 2012-01-01
a128 2018-02-03@16:45 a128 2018-02-03@16:45
a039 "February" a039 "February"
a058 "03.03.03" a058 "03.03.06"
a077 "1992 92 a077 "1992 92
" "
a096 -4 a096 -4
@@ -3043,6 +3043,85 @@ coerce("DATETIME", "2020-05-05@12:45") => 2020-05-05@12:45
set x coerce("DATETIME", "2020-05-05@1:45pm") set x coerce("DATETIME", "2020-05-05@1:45pm")
coerce("DATETIME", "2020-05-05@1:45pm") => 2020-05-05@13:45 coerce("DATETIME", "2020-05-05@1:45pm") => 2020-05-05@13:45
# Overflow - these tests only work on machines with 32-bit
# twos-complement signed integers. You may get test failures on
# machines with different architectures.
set a $IntMin - 1
$IntMin => -2147483648
-2147483648 - 1 => Number too high
../tests/test.rem(539): `-': Number too high
set a $IntMin - $IntMax
$IntMin => -2147483648
$IntMax => 2147483647
-2147483648 - 2147483647 => Number too high
../tests/test.rem(540): `-': Number too high
set a $IntMax - $IntMin
$IntMax => 2147483647
$IntMin => -2147483648
2147483647 - -2147483648 => Number too high
../tests/test.rem(541): `-': Number too high
set a $IntMax - (-1)
$IntMax => 2147483647
- 1 => -1
2147483647 - -1 => Number too high
../tests/test.rem(542): `-': Number too high
set a $IntMax + 1
$IntMax => 2147483647
2147483647 + 1 => Number too high
../tests/test.rem(543): `+': Number too high
set a $IntMax + $IntMax
$IntMax => 2147483647
$IntMax => 2147483647
2147483647 + 2147483647 => Number too high
../tests/test.rem(544): `+': Number too high
set a $IntMin + (-1)
$IntMin => -2147483648
- 1 => -1
-2147483648 + -1 => Number too high
../tests/test.rem(545): `+': Number too high
set a $IntMin + $IntMin
$IntMin => -2147483648
$IntMin => -2147483648
-2147483648 + -2147483648 => Number too high
../tests/test.rem(546): `+': Number too high
set a $IntMax * 2
$IntMax => 2147483647
2147483647 * 2 => Number too high
../tests/test.rem(547): `*': Number too high
set a $IntMax * $IntMax
$IntMax => 2147483647
$IntMax => 2147483647
2147483647 * 2147483647 => Number too high
../tests/test.rem(548): `*': Number too high
set a $IntMax * $IntMin
$IntMax => 2147483647
$IntMin => -2147483648
2147483647 * -2147483648 => Number too high
../tests/test.rem(549): `*': Number too high
set a $IntMin * 2
$IntMin => -2147483648
-2147483648 * 2 => Number too high
../tests/test.rem(550): `*': Number too high
set a $IntMin * $IntMin
$IntMin => -2147483648
$IntMin => -2147483648
-2147483648 * -2147483648 => Number too high
../tests/test.rem(551): `*': Number too high
set a $IntMin * $IntMax
$IntMin => -2147483648
$IntMax => 2147483647
-2147483648 * 2147483647 => Number too high
../tests/test.rem(552): `*': Number too high
set a $IntMin / (-1)
$IntMin => -2147483648
- 1 => -1
-2147483648 / -1 => Number too high
../tests/test.rem(553): `/': Number too high
set a abs($IntMin)
$IntMin => -2147483648
abs(-2147483648) => Number too high
../tests/test.rem(554): Number too high
# Don't want Remind to queue reminders # Don't want Remind to queue reminders
EXIT EXIT
@@ -4392,9 +4471,10 @@ No reminders.
%%Pages: (atend) %%Pages: (atend)
%%Orientation: Landscape %%Orientation: Landscape
%%EndComments %%EndComments
<< /PageSize [612 792] >> setpagedevice
% This file was produced by Remind and Rem2PS, written by % This file was produced by Remind and Rem2PS, written by
% Dianne Skoll. % Dianne Skoll.
% Remind and Rem2PS are Copyright 1992-2020 Dianne Skoll. % Remind and Rem2PS are Copyright 1992-2021 Dianne Skoll.
/ISOLatin1Encoding where { pop save true }{ false } ifelse /ISOLatin1Encoding where { pop save true }{ false } ifelse
/ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus
StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute
@@ -4574,9 +4654,10 @@ def
% Variables for calendar boxes: % Variables for calendar boxes:
% ytop - current top position % ytop - current top position
% ymin - minimum y reached for current row % ymin - minimum y reached for current row
% border ytop xleft width textarray daynum DoCalBox ybot % border ytop xleft width textarray daynum onright DoCalBox ybot
% Do the entries for one calendar box. Returns lowest Y-coordinate reached % Do the entries for one calendar box. Returns lowest Y-coordinate reached
/DoCalBox { /DoCalBox {
/onright exch def
/daynum exch def /daynum exch def
/textarr exch def /textarr exch def
/wid exch def /wid exch def
@@ -4585,8 +4666,10 @@ def
/border exch def /border exch def
% Do the day number % Do the day number
/DayFont findfont DaySize scalefont setfont /DayFont findfont DaySize scalefont setfont
xl wid add border sub daynum stringwidth pop sub onright 1 eq
yt border sub DaySize sub moveto daynum show {xl wid add border sub daynum stringwidth pop sub yt border sub DaySize sub moveto daynum show}
{xl border add yt border sub DaySize sub moveto daynum show}
ifelse
% Do the text entries. Precharge the stack with current y pos. % Do the text entries. Precharge the stack with current y pos.
/ycur yt border sub DaySize sub DaySize sub 2 add def /ycur yt border sub DaySize sub DaySize sub 2 add def
/EntryFont findfont EntrySize scalefont setfont /EntryFont findfont EntrySize scalefont setfont
@@ -4632,7 +4715,7 @@ ifelse
Border ytop 6 xincr mul MinX add xincr Border ytop 6 xincr mul MinX add xincr
[ [
] ]
(1) (1) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4664,7 +4747,7 @@ MinX ymin MaxX ymin L
Border ytop 0 xincr mul MinX add xincr Border ytop 0 xincr mul MinX add xincr
[ [
] ]
(2) (2) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4672,7 +4755,7 @@ DoCalBox
Border ytop 1 xincr mul MinX add xincr Border ytop 1 xincr mul MinX add xincr
[ [
] ]
(3) (3) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4680,7 +4763,7 @@ DoCalBox
Border ytop 2 xincr mul MinX add xincr Border ytop 2 xincr mul MinX add xincr
[ [
] ]
(4) (4) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4688,7 +4771,7 @@ DoCalBox
Border ytop 3 xincr mul MinX add xincr Border ytop 3 xincr mul MinX add xincr
[ [
] ]
(5) (5) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4696,7 +4779,7 @@ DoCalBox
Border ytop 4 xincr mul MinX add xincr Border ytop 4 xincr mul MinX add xincr
[ [
] ]
(6) (6) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4704,7 +4787,7 @@ DoCalBox
Border ytop 5 xincr mul MinX add xincr Border ytop 5 xincr mul MinX add xincr
[ [
] ]
(7) (7) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4712,7 +4795,7 @@ DoCalBox
Border ytop 6 xincr mul MinX add xincr Border ytop 6 xincr mul MinX add xincr
[ [
] ]
(8) (8) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4774,10 +4857,10 @@ _A BoxHeight _A sub lineto closepath
BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto
_A BoxHeight _A sub lineto closepath _A BoxHeight _A sub lineto closepath
1 0.8 1 setrgbcolor fill 0.0 setgray 1 0.8 1 setrgbcolor fill 0.0 setgray
gsave 0 setgray newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub Border DaySize 2 div add /moonstartx exch def gsave 0 setgray newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 0 360 arc closepath DaySize 2 div 0 360 arc closepath
stroke stroke
Border DaySize 2 div add DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto moonstartx DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto
/EntryFont findfont EntrySize scalefont setfont (20:56) show /EntryFont findfont EntrySize scalefont setfont (20:56) show
grestore grestore
@@ -4831,7 +4914,7 @@ MinX ymin MaxX ymin L
Border ytop 0 xincr mul MinX add xincr Border ytop 0 xincr mul MinX add xincr
[ [
] ]
(9) (9) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4839,7 +4922,7 @@ DoCalBox
Border ytop 1 xincr mul MinX add xincr Border ytop 1 xincr mul MinX add xincr
[ [
] ]
(10) (10) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4847,7 +4930,7 @@ DoCalBox
Border ytop 2 xincr mul MinX add xincr Border ytop 2 xincr mul MinX add xincr
[ [
] ]
(11) (11) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4855,7 +4938,7 @@ DoCalBox
Border ytop 3 xincr mul MinX add xincr Border ytop 3 xincr mul MinX add xincr
[ [
] ]
(12) (12) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4863,7 +4946,7 @@ DoCalBox
Border ytop 4 xincr mul MinX add xincr Border ytop 4 xincr mul MinX add xincr
[ [
] ]
(13) (13) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4871,7 +4954,7 @@ DoCalBox
Border ytop 5 xincr mul MinX add xincr Border ytop 5 xincr mul MinX add xincr
[ [
] ]
(14) (14) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4879,7 +4962,7 @@ DoCalBox
Border ytop 6 xincr mul MinX add xincr Border ytop 6 xincr mul MinX add xincr
[ [
] ]
(15) (15) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -4949,12 +5032,12 @@ _A BoxHeight _A sub lineto closepath
BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto
_A BoxHeight _A sub lineto closepath _A BoxHeight _A sub lineto closepath
0.8 1 1 setrgbcolor fill 0.0 setgray 0.8 1 1 setrgbcolor fill 0.0 setgray
gsave 0 setgray newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub Border DaySize 2 div add /moonstartx exch def gsave 0 setgray newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 0 360 arc closepath DaySize 2 div 0 360 arc closepath
stroke stroke
newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 270 90 arc closepath fill DaySize 2 div 270 90 arc closepath fill
Border DaySize 2 div add DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto moonstartx DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto
/EntryFont findfont EntrySize scalefont setfont (14:56) show /EntryFont findfont EntrySize scalefont setfont (14:56) show
grestore grestore
@@ -4997,7 +5080,7 @@ MinX ymin MaxX ymin L
Border ytop 0 xincr mul MinX add xincr Border ytop 0 xincr mul MinX add xincr
[ [
] ]
(16) (16) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5005,7 +5088,7 @@ DoCalBox
Border ytop 1 xincr mul MinX add xincr Border ytop 1 xincr mul MinX add xincr
[ [
] ]
(17) (17) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5013,7 +5096,7 @@ DoCalBox
Border ytop 2 xincr mul MinX add xincr Border ytop 2 xincr mul MinX add xincr
[ [
] ]
(18) (18) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5021,7 +5104,7 @@ DoCalBox
Border ytop 3 xincr mul MinX add xincr Border ytop 3 xincr mul MinX add xincr
[ [
] ]
(19) (19) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5029,7 +5112,7 @@ DoCalBox
Border ytop 4 xincr mul MinX add xincr Border ytop 4 xincr mul MinX add xincr
[ [
] ]
(20) (20) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5037,7 +5120,7 @@ DoCalBox
Border ytop 5 xincr mul MinX add xincr Border ytop 5 xincr mul MinX add xincr
[ [
] ]
(21) (21) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5045,7 +5128,7 @@ DoCalBox
Border ytop 6 xincr mul MinX add xincr Border ytop 6 xincr mul MinX add xincr
[ [
] ]
(22) (22) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5115,10 +5198,10 @@ _A BoxHeight _A sub lineto closepath
BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto
_A BoxHeight _A sub lineto closepath _A BoxHeight _A sub lineto closepath
0.8 1 1 setrgbcolor fill 0.0 setgray 0.8 1 1 setrgbcolor fill 0.0 setgray
gsave 0 setgray newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub Border DaySize 2 div add /moonstartx exch def gsave 0 setgray newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 0 360 arc closepath DaySize 2 div 0 360 arc closepath
fill fill
Border DaySize 2 div add DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto moonstartx DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto
/EntryFont findfont EntrySize scalefont setfont (06:02) show /EntryFont findfont EntrySize scalefont setfont (06:02) show
grestore grestore
@@ -5161,7 +5244,7 @@ MinX ymin MaxX ymin L
Border ytop 0 xincr mul MinX add xincr Border ytop 0 xincr mul MinX add xincr
[ [
] ]
(23) (23) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5169,7 +5252,7 @@ DoCalBox
Border ytop 1 xincr mul MinX add xincr Border ytop 1 xincr mul MinX add xincr
[ [
] ]
(24) (24) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5177,7 +5260,7 @@ DoCalBox
Border ytop 2 xincr mul MinX add xincr Border ytop 2 xincr mul MinX add xincr
[ [
] ]
(25) (25) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5185,7 +5268,7 @@ DoCalBox
Border ytop 3 xincr mul MinX add xincr Border ytop 3 xincr mul MinX add xincr
[ [
] ]
(26) (26) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5193,7 +5276,7 @@ DoCalBox
Border ytop 4 xincr mul MinX add xincr Border ytop 4 xincr mul MinX add xincr
[ [
] ]
(27) (27) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5201,7 +5284,7 @@ DoCalBox
Border ytop 5 xincr mul MinX add xincr Border ytop 5 xincr mul MinX add xincr
[ [
] ]
(28) (28) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5209,7 +5292,7 @@ DoCalBox
Border ytop 6 xincr mul MinX add xincr Border ytop 6 xincr mul MinX add xincr
[ [
] ]
(29) (29) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5279,12 +5362,12 @@ _A BoxHeight _A sub lineto closepath
BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto
_A BoxHeight _A sub lineto closepath _A BoxHeight _A sub lineto closepath
0.8 1 1 setrgbcolor fill 0.0 setgray 0.8 1 1 setrgbcolor fill 0.0 setgray
gsave 0 setgray newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub Border DaySize 2 div add /moonstartx exch def gsave 0 setgray newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 0 360 arc closepath DaySize 2 div 0 360 arc closepath
stroke stroke
newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 90 270 arc closepath fill DaySize 2 div 90 270 arc closepath fill
Border DaySize 2 div add DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto moonstartx DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto
/EntryFont findfont EntrySize scalefont setfont (07:42) show /EntryFont findfont EntrySize scalefont setfont (07:42) show
grestore grestore
@@ -5327,7 +5410,7 @@ MinX ymin MaxX ymin L
Border ytop 0 xincr mul MinX add xincr Border ytop 0 xincr mul MinX add xincr
[ [
] ]
(30) (30) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5335,7 +5418,7 @@ DoCalBox
Border ytop 1 xincr mul MinX add xincr Border ytop 1 xincr mul MinX add xincr
[ [
] ]
(31) (31) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5492,9 +5575,10 @@ showpage
%%Pages: (atend) %%Pages: (atend)
%%Orientation: Landscape %%Orientation: Landscape
%%EndComments %%EndComments
<< /PageSize [612 792] >> setpagedevice
% This file was produced by Remind and Rem2PS, written by % This file was produced by Remind and Rem2PS, written by
% Dianne Skoll. % Dianne Skoll.
% Remind and Rem2PS are Copyright 1992-2020 Dianne Skoll. % Remind and Rem2PS are Copyright 1992-2021 Dianne Skoll.
/ISOLatin1Encoding where { pop save true }{ false } ifelse /ISOLatin1Encoding where { pop save true }{ false } ifelse
/ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus /ISOLatin1Encoding [ StandardEncoding 0 45 getinterval aload pop /minus
StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute StandardEncoding 46 98 getinterval aload pop /dotlessi /grave /acute
@@ -5674,9 +5758,10 @@ def
% Variables for calendar boxes: % Variables for calendar boxes:
% ytop - current top position % ytop - current top position
% ymin - minimum y reached for current row % ymin - minimum y reached for current row
% border ytop xleft width textarray daynum DoCalBox ybot % border ytop xleft width textarray daynum onright DoCalBox ybot
% Do the entries for one calendar box. Returns lowest Y-coordinate reached % Do the entries for one calendar box. Returns lowest Y-coordinate reached
/DoCalBox { /DoCalBox {
/onright exch def
/daynum exch def /daynum exch def
/textarr exch def /textarr exch def
/wid exch def /wid exch def
@@ -5685,8 +5770,10 @@ def
/border exch def /border exch def
% Do the day number % Do the day number
/DayFont findfont DaySize scalefont setfont /DayFont findfont DaySize scalefont setfont
xl wid add border sub daynum stringwidth pop sub onright 1 eq
yt border sub DaySize sub moveto daynum show {xl wid add border sub daynum stringwidth pop sub yt border sub DaySize sub moveto daynum show}
{xl border add yt border sub DaySize sub moveto daynum show}
ifelse
% Do the text entries. Precharge the stack with current y pos. % Do the text entries. Precharge the stack with current y pos.
/ycur yt border sub DaySize sub DaySize sub 2 add def /ycur yt border sub DaySize sub DaySize sub 2 add def
/EntryFont findfont EntrySize scalefont setfont /EntryFont findfont EntrySize scalefont setfont
@@ -5732,7 +5819,7 @@ ifelse
Border ytop 6 xincr mul MinX add xincr Border ytop 6 xincr mul MinX add xincr
[ [
] ]
(1) (1) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5764,7 +5851,7 @@ MinX ymin MaxX ymin L
Border ytop 0 xincr mul MinX add xincr Border ytop 0 xincr mul MinX add xincr
[ [
] ]
(2) (2) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5772,7 +5859,7 @@ DoCalBox
Border ytop 1 xincr mul MinX add xincr Border ytop 1 xincr mul MinX add xincr
[ [
] ]
(3) (3) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5780,7 +5867,7 @@ DoCalBox
Border ytop 2 xincr mul MinX add xincr Border ytop 2 xincr mul MinX add xincr
[ [
] ]
(4) (4) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5788,7 +5875,7 @@ DoCalBox
Border ytop 3 xincr mul MinX add xincr Border ytop 3 xincr mul MinX add xincr
[ [
] ]
(5) (5) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5796,7 +5883,7 @@ DoCalBox
Border ytop 4 xincr mul MinX add xincr Border ytop 4 xincr mul MinX add xincr
[ [
] ]
(6) (6) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5804,7 +5891,7 @@ DoCalBox
Border ytop 5 xincr mul MinX add xincr Border ytop 5 xincr mul MinX add xincr
[ [
] ]
(7) (7) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5812,7 +5899,7 @@ DoCalBox
Border ytop 6 xincr mul MinX add xincr Border ytop 6 xincr mul MinX add xincr
[ [
] ]
(8) (8) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5874,10 +5961,10 @@ _A BoxHeight _A sub lineto closepath
BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto
_A BoxHeight _A sub lineto closepath _A BoxHeight _A sub lineto closepath
1 0.8 1 setrgbcolor fill 0.0 setgray 1 0.8 1 setrgbcolor fill 0.0 setgray
gsave 0 setgray newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub Border DaySize 2 div add /moonstartx exch def gsave 0 setgray newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 0 360 arc closepath DaySize 2 div 0 360 arc closepath
stroke stroke
Border DaySize 2 div add DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto moonstartx DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto
/EntryFont findfont EntrySize scalefont setfont (20:56) show /EntryFont findfont EntrySize scalefont setfont (20:56) show
grestore grestore
@@ -5931,7 +6018,7 @@ MinX ymin MaxX ymin L
Border ytop 0 xincr mul MinX add xincr Border ytop 0 xincr mul MinX add xincr
[ [
] ]
(9) (9) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5939,7 +6026,7 @@ DoCalBox
Border ytop 1 xincr mul MinX add xincr Border ytop 1 xincr mul MinX add xincr
[ [
] ]
(10) (10) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5947,7 +6034,7 @@ DoCalBox
Border ytop 2 xincr mul MinX add xincr Border ytop 2 xincr mul MinX add xincr
[ [
] ]
(11) (11) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5955,7 +6042,7 @@ DoCalBox
Border ytop 3 xincr mul MinX add xincr Border ytop 3 xincr mul MinX add xincr
[ [
] ]
(12) (12) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5963,7 +6050,7 @@ DoCalBox
Border ytop 4 xincr mul MinX add xincr Border ytop 4 xincr mul MinX add xincr
[ [
] ]
(13) (13) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5971,7 +6058,7 @@ DoCalBox
Border ytop 5 xincr mul MinX add xincr Border ytop 5 xincr mul MinX add xincr
[ [
] ]
(14) (14) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -5979,7 +6066,7 @@ DoCalBox
Border ytop 6 xincr mul MinX add xincr Border ytop 6 xincr mul MinX add xincr
[ [
] ]
(15) (15) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6049,12 +6136,12 @@ _A BoxHeight _A sub lineto closepath
BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto
_A BoxHeight _A sub lineto closepath _A BoxHeight _A sub lineto closepath
0.8 1 1 setrgbcolor fill 0.0 setgray 0.8 1 1 setrgbcolor fill 0.0 setgray
gsave 0 setgray newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub Border DaySize 2 div add /moonstartx exch def gsave 0 setgray newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 0 360 arc closepath DaySize 2 div 0 360 arc closepath
stroke stroke
newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 270 90 arc closepath fill DaySize 2 div 270 90 arc closepath fill
Border DaySize 2 div add DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto moonstartx DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto
/EntryFont findfont EntrySize scalefont setfont (14:56) show /EntryFont findfont EntrySize scalefont setfont (14:56) show
grestore grestore
@@ -6097,7 +6184,7 @@ MinX ymin MaxX ymin L
Border ytop 0 xincr mul MinX add xincr Border ytop 0 xincr mul MinX add xincr
[ [
] ]
(16) (16) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6105,7 +6192,7 @@ DoCalBox
Border ytop 1 xincr mul MinX add xincr Border ytop 1 xincr mul MinX add xincr
[ [
] ]
(17) (17) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6113,7 +6200,7 @@ DoCalBox
Border ytop 2 xincr mul MinX add xincr Border ytop 2 xincr mul MinX add xincr
[ [
] ]
(18) (18) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6121,7 +6208,7 @@ DoCalBox
Border ytop 3 xincr mul MinX add xincr Border ytop 3 xincr mul MinX add xincr
[ [
] ]
(19) (19) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6129,7 +6216,7 @@ DoCalBox
Border ytop 4 xincr mul MinX add xincr Border ytop 4 xincr mul MinX add xincr
[ [
] ]
(20) (20) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6137,7 +6224,7 @@ DoCalBox
Border ytop 5 xincr mul MinX add xincr Border ytop 5 xincr mul MinX add xincr
[ [
] ]
(21) (21) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6145,7 +6232,7 @@ DoCalBox
Border ytop 6 xincr mul MinX add xincr Border ytop 6 xincr mul MinX add xincr
[ [
] ]
(22) (22) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6215,10 +6302,10 @@ _A BoxHeight _A sub lineto closepath
BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto
_A BoxHeight _A sub lineto closepath _A BoxHeight _A sub lineto closepath
0.8 1 1 setrgbcolor fill 0.0 setgray 0.8 1 1 setrgbcolor fill 0.0 setgray
gsave 0 setgray newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub Border DaySize 2 div add /moonstartx exch def gsave 0 setgray newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 0 360 arc closepath DaySize 2 div 0 360 arc closepath
fill fill
Border DaySize 2 div add DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto moonstartx DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto
/EntryFont findfont EntrySize scalefont setfont (06:02) show /EntryFont findfont EntrySize scalefont setfont (06:02) show
grestore grestore
@@ -6261,7 +6348,7 @@ MinX ymin MaxX ymin L
Border ytop 0 xincr mul MinX add xincr Border ytop 0 xincr mul MinX add xincr
[ [
] ]
(23) (23) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6269,7 +6356,7 @@ DoCalBox
Border ytop 1 xincr mul MinX add xincr Border ytop 1 xincr mul MinX add xincr
[ [
] ]
(24) (24) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6277,7 +6364,7 @@ DoCalBox
Border ytop 2 xincr mul MinX add xincr Border ytop 2 xincr mul MinX add xincr
[ [
] ]
(25) (25) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6285,7 +6372,7 @@ DoCalBox
Border ytop 3 xincr mul MinX add xincr Border ytop 3 xincr mul MinX add xincr
[ [
] ]
(26) (26) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6293,7 +6380,7 @@ DoCalBox
Border ytop 4 xincr mul MinX add xincr Border ytop 4 xincr mul MinX add xincr
[ [
] ]
(27) (27) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6301,7 +6388,7 @@ DoCalBox
Border ytop 5 xincr mul MinX add xincr Border ytop 5 xincr mul MinX add xincr
[ [
] ]
(28) (28) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6309,7 +6396,7 @@ DoCalBox
Border ytop 6 xincr mul MinX add xincr Border ytop 6 xincr mul MinX add xincr
[ [
] ]
(29) (29) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6379,12 +6466,12 @@ _A BoxHeight _A sub lineto closepath
BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto BoxWidth _A sub _A lineto BoxWidth _A sub BoxHeight _A sub lineto
_A BoxHeight _A sub lineto closepath _A BoxHeight _A sub lineto closepath
0.8 1 1 setrgbcolor fill 0.0 setgray 0.8 1 1 setrgbcolor fill 0.0 setgray
gsave 0 setgray newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub Border DaySize 2 div add /moonstartx exch def gsave 0 setgray newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 0 360 arc closepath DaySize 2 div 0 360 arc closepath
stroke stroke
newpath Border DaySize 2 div add BoxHeight Border sub DaySize 2 div sub newpath moonstartx BoxHeight Border sub DaySize 2 div sub
DaySize 2 div 90 270 arc closepath fill DaySize 2 div 90 270 arc closepath fill
Border DaySize 2 div add DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto moonstartx DaySize 2 div add Border add BoxHeight border sub DaySize 2 div sub DaySize 2 div sub moveto
/EntryFont findfont EntrySize scalefont setfont (07:42) show /EntryFont findfont EntrySize scalefont setfont (07:42) show
grestore grestore
@@ -6427,7 +6514,7 @@ MinX ymin MaxX ymin L
Border ytop 0 xincr mul MinX add xincr Border ytop 0 xincr mul MinX add xincr
[ [
] ]
(30) (30) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def
@@ -6435,7 +6522,7 @@ DoCalBox
Border ytop 1 xincr mul MinX add xincr Border ytop 1 xincr mul MinX add xincr
[ [
] ]
(31) (31) 1
DoCalBox DoCalBox
/y exch def y ymin lt {/ymin y def} if /y exch def y ymin lt {/ymin y def} if
} def } def

View File

@@ -533,6 +533,26 @@ set x coerce("DATETIME", "2020-05-05@12:45am")
set x coerce("DATETIME", "2020-05-05@12:45") set x coerce("DATETIME", "2020-05-05@12:45")
set x coerce("DATETIME", "2020-05-05@1:45pm") set x coerce("DATETIME", "2020-05-05@1:45pm")
# Overflow - these tests only work on machines with 32-bit
# twos-complement signed integers. You may get test failures on
# machines with different architectures.
set a $IntMin - 1
set a $IntMin - $IntMax
set a $IntMax - $IntMin
set a $IntMax - (-1)
set a $IntMax + 1
set a $IntMax + $IntMax
set a $IntMin + (-1)
set a $IntMin + $IntMin
set a $IntMax * 2
set a $IntMax * $IntMax
set a $IntMax * $IntMin
set a $IntMin * 2
set a $IntMin * $IntMin
set a $IntMin * $IntMax
set a $IntMin / (-1)
set a abs($IntMin)
# Don't want Remind to queue reminders # Don't want Remind to queue reminders
EXIT EXIT