Compare commits

..

27 Commits

Author SHA1 Message Date
Dianne Skoll
244677e524 Prep for 3.3.7 release. 2021-05-10 16:53:16 -04:00
Dianne Skoll
f5a094a973 Fix bug in handling of WKDAY DAY YEAR date specification. 2021-04-15 12:29:30 -04:00
Dianne Skoll
5681ebdb12 Simplify "REM MSG ..." case. 2021-04-13 20:54:54 -04:00
Dianne Skoll
664fa5f08f Fix bug: Remind would sometimes compute incorrect trigger date for:
REM 29 Feb SOME_WEEKDAY MSG ...
2021-04-13 12:21:37 -04:00
Dianne Skoll
14edec5eae Pass in wd to macro explicitly. 2021-04-13 12:11:13 -04:00
Dianne Skoll
6adfd2e739 Wrap code to advance to next specified weekday in a macro. 2021-04-13 12:08:20 -04:00
Dianne Skoll
34409f7a7d Update copyright year. 2021-04-02 10:43:54 -04:00
Dianne Skoll
7e13d1052c Don't run test suite as "root". 2021-04-01 19:41:19 -04:00
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
54 changed files with 354 additions and 95 deletions

View File

@@ -3,7 +3,7 @@ THE REMIND COPYRIGHT
1. REMIND refers to the entire set of files and documentation in the
REMIND package.
2. REMIND is Copyright 1992-2020 Dianne Skoll, except where noted in
2. REMIND is Copyright 1992-2021 Dianne Skoll, except where noted in
individual files.
3. DISTRIBUTION AND USE

2
configure vendored
View File

@@ -3991,7 +3991,7 @@ _ACEOF
fi
done
VERSION=03.03.05
VERSION=03.03.07
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
AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale)
VERSION=03.03.05
VERSION=03.03.07
AC_SUBST(VERSION)
AC_OUTPUT(src/Makefile www/Makefile src/version.h)

View File

@@ -1,5 +1,29 @@
CHANGES TO REMIND
* VERSION 3.3 Patch 7 - 2021-05-10
- MINOR FIX: Refuse to run "make test" as root --- it would fail
anyway with an obscure message.
- BUG FIX: Remind would sometimes compute incorrect trigger date for:
REM Tue 29 Feb MSG ...
- BUG FIX: Remind would sometimes compute incorrect trigger date for
a date spec like: Tue 31 2021 MSG ...
* 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

View File

@@ -1,4 +1,4 @@
.TH REM 1 "1 January 2020"
.TH REM 1 "1 January 2021"
.UC 4
.SH NAME
rem \- Invoke Remind with a default filename

View File

@@ -1,4 +1,4 @@
.TH REMIND 1 "1 January 2020"
.TH REMIND 1 "1 January 2021"
.UC 4
.SH NAME
remind \- a sophisticated reminder service
@@ -1868,6 +1868,11 @@ otherwise.
.PP
.B NOTES
.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
to right, except where parentheses dictate otherwise. This is important,
because the enhanced "+" operator is not necessarily associative.
@@ -2060,6 +2065,14 @@ then \fBONCE\fR directives will be ignored.
.B $InfDelta (read-only)
If non-zero, then the \fB\-t\fR option was supplied on the command line.
.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
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

View File

@@ -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
extra features as you become a more sophisticated \fBRemind\fR programmer.
\fBTkRemind\fR is written in Tcl, and requires version 8.0
(or higher). It also requires a \fBwish\fR binary.
\fBTkRemind\fR is written in Tcl, and requires version 8.5 (or higher)
as well as the tcllib extension. It also requires a \fBwish\fR
binary. If you are using Tcl/Tk 8.5, you may also need either the Img
or the tkpng extension to handle PNG images.
.SH OPTIONS
\fBTkRemind\fR itself has no options. However, it passes certain options

View File

@@ -16,11 +16,22 @@ exec wish "$0" "$@"
# We need at least version 8.5 because of {*} list expansion operator
if {[catch {package require Tcl 8.5}]} {
puts "This program requires Tcl 8.5 or higher."
puts "You have version [info tclversion]"
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 .
set Hostname [exec hostname]
@@ -113,13 +124,6 @@ if {[catch {package require 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"} {
tk_dialog .error Error "Please do not port Remind to Windows" error 0 OK
exit 1
@@ -927,7 +931,7 @@ proc LoadOptions {} {
}
foreach {key val} $line {}
if {![info exists Option($key)]} {
puts "Unknown option in $ConfigFile: $key"
puts stderr "Unknown option in $ConfigFile: $key"
continue
}
set Option($key) $val
@@ -2569,7 +2573,7 @@ proc DaemonReadable { file } {
}
}
default {
puts "Unknown message from daemon: $line\n"
puts stderr "Unknown message from daemon: $line\n"
}
}
}

View File

@@ -5,7 +5,7 @@
/* The code for generating a calendar. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -6,7 +6,7 @@
/* which you can customize. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -6,7 +6,7 @@
/* which you can customize. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -7,7 +7,7 @@
/* commands. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -6,7 +6,7 @@
/* reminders are triggered. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -6,7 +6,7 @@
/* buffers. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Declaration of functions for manipulating dynamic buffers */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Error definitions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

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

View File

@@ -5,7 +5,7 @@
/* Contains a few definitions used by expression evaluator. */
/* */
/* 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; \
else \
(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

@@ -7,7 +7,7 @@
/* files. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -6,7 +6,7 @@
/* expressions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/
@@ -866,12 +866,14 @@ static int FTime(func_info *info)
/***************************************************************/
static int FAbs(func_info *info)
{
int v;
volatile int v;
ASSERT_TYPE(0, INT_TYPE);
v = ARGV(0);
RetVal.type = INT_TYPE;
RETVAL = (v < 0) ? (-v) : v;
v = RETVAL;
if (v < 0) return E_2HIGH;
return OK;
}

View File

@@ -8,7 +8,7 @@
/* globals.h and err.h */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -7,7 +7,7 @@
/* MK_GLOBALS. Also contains useful macro definitions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Support for the Hebrew calendar */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/* Derived from code written by Amos Shapir in 1978; revised */
/* 1985. */

View File

@@ -7,7 +7,7 @@
/* in normal mode. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/
@@ -649,7 +649,7 @@ void InitRemind(int argc, char const *argv[])
#ifndef L_USAGE_OVERRIDE
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2020 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif

View File

@@ -5,7 +5,7 @@
/* Header file for language support for various languages. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -6,7 +6,7 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2020 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
/* This file is Copyright (C) 1993 by Mogens Lynnerup. */
/* */
/***************************************************************/

View File

@@ -11,7 +11,7 @@
/* Further corrections by Erik-Jan Vens */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Support for the English language. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -11,7 +11,7 @@
/* */
/* This file is part of REMIND. */
/* This file is Copyright (C) 1993-1998 by Mikko Silvonen. */
/* REMIND is Copyright (C) 1992-2020 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/
@@ -527,7 +527,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2020 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETAVERSIO <<<<\n");
#endif

View File

@@ -8,7 +8,7 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2020 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
/* This file is Copyright (C) 1993 by Laurent Duperval and */
/* Dianne Skoll. */
/* */
@@ -359,7 +359,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2020 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif

View File

@@ -9,7 +9,7 @@
/* I don't speak German. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Support for the Icelandic language. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* Translated by Björn Davíðsson (bjossi@snerpa.is) */
/* */
/***************************************************************/

View File

@@ -7,7 +7,7 @@
/* This file is part of REMIND. */
/* It is Copyright (C) 1996 by Valerio Aimale */
/* */
/* Remind is copyright (C) 1992-2020 by Dianne Skoll */
/* Remind is copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -6,7 +6,7 @@
/* */
/* This file is part of REMIND. */
/* This file is Copyright (C) 1993 by Trygve Randen. */
/* Remind is Copyright (C) 1992-2020 by Dianne Skoll */
/* Remind is Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -9,7 +9,7 @@
/* Polish. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/
@@ -397,7 +397,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2020 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif

View File

@@ -8,7 +8,7 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2020 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
/* This file is Copyright (C) 1996 by Marco Paganini and */
/* Dianne Skoll. */
/* */
@@ -257,7 +257,7 @@ EXTERN char *ErrMsg[] =
#define L_USAGE_OVERRIDE 1
void Usage(void)
{
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2020 Dianne Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (versao %s) (C) 1992-2021 Dianne Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> VERSAO BETA <<<<\n");
#endif

View File

@@ -8,7 +8,7 @@
/* */
/* This file is part of REMIND. */
/* */
/* REMIND is Copyright (C) 1992-2020 by Dianne Skoll */
/* REMIND is Copyright (C) 1992-2021 by Dianne Skoll */
/* This file is Copyright (C) 1996-1998 by Liviu Daia */
/* */
/***************************************************************/

View File

@@ -7,7 +7,7 @@
/* Author: Rafa Couto <rafacouto@biogate.com> */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -6,7 +6,7 @@
/* routines, etc. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Calculations for figuring out moon phases. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -6,7 +6,7 @@
/* the data structures for OMITted dates. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Function Prototypes. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Queue up reminders for subsequent execution. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Routines for sorting reminders by trigger date */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -6,7 +6,7 @@
/* classifying the tokens parsed. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Routines for figuring out the trigger date of a reminder */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/
@@ -24,6 +24,8 @@
#define GOT_YR 4
#define GOT_WD 8
#define ADVANCE_TO_WD(x, wd) while (! ((wd) & (1 << ((x)%7)))) (x)++
static int JYear(int jul);
static int JMonth(int jul);
static int NextSimpleTrig(int startdate, Trigger *trig, int *err);
@@ -58,9 +60,10 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
if (trig->wd != NO_WD) typ |= GOT_WD;
switch(typ) {
case 0:
return startdate;
case GOT_WD:
if (trig->wd != NO_WD)
while(! (trig->wd & (1 << (startdate%7)))) startdate++;
ADVANCE_TO_WD(startdate, trig->wd);
return startdate;
case GOT_DAY:
@@ -83,12 +86,12 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
else return -1;
case GOT_DAY+GOT_MON:
if (m > trig->m || (m == trig->m && d > trig->d)) y++;
if (trig->d > MonthDays[trig->m]) {
*err = E_BAD_DATE;
return -1;
}
if (m > trig->m || (m == trig->m && d > trig->d)) y++;
/* Take care of Feb. 29 */
while (trig->d > DaysInMonth(trig->m, y)) y++;
return Julian(y, trig->m, trig->d);
@@ -121,19 +124,19 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
if (y > trig->y) return -1;
if (y < trig->y) j = Julian(trig->y, 0, 1);
else j = startdate;
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
if (JYear(j) > trig->y) return -1;
return j;
case GOT_MON+GOT_WD:
if (m == trig->m) {
j = startdate;
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
if (JMonth(j) == trig->m) return j;
}
if (m >= trig->m) j = Julian(y+1, trig->m, 1);
else j = Julian(y, trig->m, 1);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
return j; /* Guaranteed to be within the month */
case GOT_DAY+GOT_WD:
@@ -144,7 +147,7 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
/* If there are fewer days in previous month, no match */
if (trig->d <= DaysInMonth(m2, y2)) {
j = Julian(y2, m2, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
if (j >= startdate) return j;
}
@@ -153,7 +156,7 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
/* Try this month */
if (trig->d <= DaysInMonth(m, y)) {
j = Julian(y, m, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
if (j >= startdate) return j;
}
@@ -162,18 +165,18 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
if (m2 > 11) { m2 = 0; y++; }
while (trig->d > DaysInMonth(m2, y)) m2++;
j = Julian(y, m2, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
return j;
case GOT_WD+GOT_YR+GOT_DAY:
if (y > trig->y+1 || (y > trig->y && m>0)) return -1;
if (y > trig->y) {
j = Julian(trig->y, 11, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
if (j >= startdate) return j;
} else if (y < trig->y) {
j = Julian(trig->y, 0, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
return j;
} else {
/* Try last month */
@@ -181,14 +184,16 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
m2 = m-1;
while (trig->d > DaysInMonth(m2, trig->y)) m2--;
j = Julian(trig->y, m2, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
if (JYear(j) > trig->y) return -1;
if (j >= startdate) return j;
}
}
/* Try this month */
if (trig->d <= DaysInMonth(m, trig->y)) {
j = Julian(trig->y, m, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
if (JYear(j) > trig->y) return -1;
if (j >= startdate) return j;
}
@@ -197,7 +202,8 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
m++;
while (trig->d > DaysInMonth(m, trig->d)) m++;
j = Julian(trig->y, m, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
if (JYear(j) > trig->y) return -1;
return j;
case GOT_DAY+GOT_MON+GOT_WD:
@@ -215,31 +221,32 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
/* Try last year */
j = Julian(y, trig->m, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
if (j >= startdate) return j;
/* Try this year */
y++;
while (trig->d > DaysInMonth(trig->m, y)) y++;
j = Julian(y, trig->m, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
if (j >= startdate) return j;
/* Must be next year */
y++;
while (trig->d > DaysInMonth(trig->m, y)) y++;
j = Julian(y, trig->m, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
return j;
case GOT_WD+GOT_MON+GOT_YR:
if (y > trig->y || (y == trig->y && m > trig->m)) return -1;
if (trig->y > y || (trig->y == y && trig->m > m)) {
j = Julian(trig->y, trig->m, 1);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
return j;
} else {
j = startdate;
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
FromJulian(j, &y2, &m2, &d2);
if (m2 == trig->m) return j; else return -1;
}
@@ -250,7 +257,7 @@ static int NextSimpleTrig(int startdate, Trigger *trig, int *err)
return -1;
}
j = Julian(trig->y, trig->m, trig->d);
while(! (trig->wd & (1 << (j%7)))) j++;
ADVANCE_TO_WD(j, trig->wd);
return j;
default:

View File

@@ -5,7 +5,7 @@
/* Type definitions all dumped here. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -6,7 +6,7 @@
/* functions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/

View File

@@ -5,7 +5,7 @@
/* Useful utility functions. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/
@@ -123,3 +123,26 @@ int DateOK(int y, int m, int d)
d > DaysInMonth(m, y) ) return 0;
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

@@ -6,7 +6,7 @@
/* user- and system-defined variables. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992-2020 by Dianne Skoll */
/* Copyright (C) 1992-2021 by Dianne Skoll */
/* */
/***************************************************************/
@@ -17,6 +17,7 @@
#include <ctype.h>
#include <stdlib.h>
#include <limits.h>
#include "types.h"
#include "expr.h"
#include "globals.h"
@@ -31,6 +32,9 @@
#define VALUE ErrMsg[E_VAL]
#define UNDEF ErrMsg[E_UNDEF]
static int IntMin = INT_MIN;
static int IntMax = INT_MAX;
static Var *VHashTbl[VAR_HASH_SIZE];
typedef int (*SysVarFunc)(int, Value *);
@@ -661,6 +665,8 @@ static SysVar SysVarArr[] = {
{"HushMode", 0, INT_TYPE, &Hush, 0, 0 },
{"IgnoreOnce", 0, INT_TYPE, &IgnoreOnce, 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 },
{"LatMin", 1, INT_TYPE, &LatMin, -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/*~
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 $?

View File

@@ -7,13 +7,22 @@
# in the build directory.
#
# This file is part of REMIND.
# Copyright (C) 1992-2018 Dianne Skoll
# Copyright (C) 1992-2021 Dianne Skoll
# ---------------------------------------------------------------------------
DIR=`dirname $0`
cd $DIR
if test $? != 0 ; then
echo ""
echo "Unable to cd $DIR" >&2
echo ""
exit 1
fi
if test `id -u` = 0 ; then
echo ""
echo "*** Please do not run the test suite as root; it will fail."
echo ""
exit 1
fi
@@ -56,6 +65,14 @@ echo "" >> ../tests/test.out
chmod 644 include_dir/04cantread.rem
# Feb 29 bug
echo "Feb 29 Bug Test" >> ../tests/test.out
echo 'REM Sun 29 Feb MSG [$T]' | ../src/remind -dt - 1 feb 2021 >> ../tests/test.out 2>&1
# Day Weekday Year out-of-year bug
echo "Mon 31 Dec Bug Test" >> ../tests/test.out
echo 'REM Mon 31 2021 MSG [$T]' | ../src/remind -dt - 31 dec 2021 >> ../tests/test.out 2>&1
echo "Color Test" >> ../tests/test.out
../src/remind -ccl ../tests/colors.rem 1 aug 2007 >> ../tests/test.out 2>&1
@@ -289,8 +306,17 @@ rem 24 SPECIAL COLOR 200 200 0 BRIGHT YELLOW
rem 25 SPECIAL COLOR 200 200 200 BRIGHT WHITE
EOF
export LC_ALL=en_US.utf-8
export LANG=en_US.utf-8
# If we're already in a utf-8 locale, do
# 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
cmp -s ../tests/test.out ../tests/test.cmp
if [ "$?" = "0" ]; then

View File

@@ -857,7 +857,7 @@ set a057 value("a05"+"6")
"a05" + "6" => "a056"
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
set a058 version()
version() => "03.03.05"
version() => "03.03.07"
set a059 wkday(today())
today() => 1991-02-16
wkday(1991-02-16) => "Saturday"
@@ -2426,7 +2426,7 @@ a086 4
a109 2012-01-01
a128 2018-02-03@16:45
a039 "February"
a058 "03.03.05"
a058 "03.03.07"
a077 "1992 92
"
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")
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
EXIT
@@ -4161,6 +4240,12 @@ September 30
# fileinfo 5 ../tests/include_test.rem
2007/08/15 * * * * Whee!!!!
# rem2ps end
Feb 29 Bug Test
-(1): Trig = Sunday, 3 March, 2024
No reminders.
Mon 31 Dec Bug Test
-(1): Expired
No reminders.
Color Test
(0lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk(B
(0x(B August 2007 (0x(B

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@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
EXIT