mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 14:59:20 +02:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb1998c888 | ||
|
|
543252cbaf | ||
|
|
6df7c59876 | ||
|
|
f780e0afc3 | ||
|
|
310e8d3287 | ||
|
|
ba51bdf258 | ||
|
|
ef88b844fb | ||
|
|
67b96b0a26 | ||
|
|
562da30fb5 | ||
|
|
21175e8cf6 | ||
|
|
80d01f7158 | ||
|
|
90cac447e4 | ||
|
|
04bf5b0a8b | ||
|
|
d667c15b25 | ||
|
|
2123bf4b18 | ||
|
|
429a64f29e | ||
|
|
f39381dd6c | ||
|
|
0a9eb07f6f | ||
|
|
9c287e3fd7 |
2
configure
vendored
2
configure
vendored
@@ -3991,7 +3991,7 @@ _ACEOF
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
VERSION=03.03.05
|
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"
|
||||||
|
|
||||||
|
|||||||
@@ -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.05
|
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)
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
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
|
* VERSION 3.3 Patch 5 - 2021-01-21
|
||||||
|
|
||||||
- NEW FEATURE: tkremind: Add ability to change fonts and colors from
|
- NEW FEATURE: tkremind: Add ability to change fonts and colors from
|
||||||
|
|||||||
13
man/remind.1
13
man/remind.1
@@ -1868,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.
|
||||||
@@ -2060,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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -16,11 +16,22 @@ exec wish "$0" "$@"
|
|||||||
|
|
||||||
# We need at least version 8.5 because of {*} list expansion operator
|
# We need at least version 8.5 because of {*} list expansion operator
|
||||||
if {[catch {package require Tcl 8.5}]} {
|
if {[catch {package require Tcl 8.5}]} {
|
||||||
puts "This program requires Tcl 8.5 or higher."
|
puts stderr "This program requires Tcl 8.5 or higher."
|
||||||
puts "You have version [info tclversion]"
|
puts stderr "You have version [info tclversion]"
|
||||||
exit 1
|
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]
|
||||||
@@ -113,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
|
||||||
@@ -927,7 +931,7 @@ proc LoadOptions {} {
|
|||||||
}
|
}
|
||||||
foreach {key val} $line {}
|
foreach {key val} $line {}
|
||||||
if {![info exists Option($key)]} {
|
if {![info exists Option($key)]} {
|
||||||
puts "Unknown option in $ConfigFile: $key"
|
puts stderr "Unknown option in $ConfigFile: $key"
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
set Option($key) $val
|
set Option($key) $val
|
||||||
@@ -2569,7 +2573,7 @@ proc DaemonReadable { file } {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
default {
|
default {
|
||||||
puts "Unknown message from daemon: $line\n"
|
puts stderr "Unknown message from daemon: $line\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
44
src/expr.c
44
src/expr.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
src/expr.h
11
src/expr.h
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
23
src/utils.c
23
src/utils.c
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 },
|
||||||
|
|||||||
@@ -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 $?
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.05"
|
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.05"
|
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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user