mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
prep for 2.16.0.0 release with value address arithmetic restrictions
This commit is contained in:
36
CHANGES
36
CHANGES
@@ -1,3 +1,37 @@
|
|||||||
|
The following are the changes from calc version 2.15.1.2 to 2.16.0.0:
|
||||||
|
|
||||||
|
Starting with calc version 2.16.0.0, the ability to perform arithmetic
|
||||||
|
on addresses of values in calc objects has been greatly restricted.
|
||||||
|
|
||||||
|
Most arithmetic on of value addresses could easily cause calc to
|
||||||
|
crash. For example, prior to calc version 2.16.0.0, the following
|
||||||
|
command was likely to crash calc:
|
||||||
|
|
||||||
|
calc '*((&.)+1e9)'
|
||||||
|
|
||||||
|
Subtracting two value addresses is permitted, however there is NO
|
||||||
|
guarantee that the address of a value will remain consistent across
|
||||||
|
calc runs. Addresses of values depend on the circumstances of when
|
||||||
|
the calc values were formed.
|
||||||
|
|
||||||
|
The above restrictions and caveats apply to addresses of values.
|
||||||
|
Such restrictions and caveats to NOT apply to the addresses of
|
||||||
|
octets, NOR to the addresses within strings. If isptr(x) == 2, then
|
||||||
|
x is value-pointer and the above mentioned restrictions and caveats apply.
|
||||||
|
|
||||||
|
See "help address" for more information on value address arithmetic.
|
||||||
|
|
||||||
|
Added E_INVALID_DEREF (10610) error code to indicate the invalid
|
||||||
|
dereferencing a non-variable.
|
||||||
|
|
||||||
|
Added E_INVALID_ADDR_OP (10611) error code to indicate an invalid
|
||||||
|
arithmetic address operation.
|
||||||
|
|
||||||
|
We plan to let this most recent change settle down before performing
|
||||||
|
the calc v2 to calc v3 fork. Therefore, version 2.16.1.0 will form
|
||||||
|
the basis for the calc v2 to calc v3 fork.
|
||||||
|
|
||||||
|
|
||||||
The following are the changes from calc version 2.15.1.2 to 2.15.1.2:
|
The following are the changes from calc version 2.15.1.2 to 2.15.1.2:
|
||||||
|
|
||||||
Removed use of HAVE_MEMMOVE as well have_memmv.c. Removed the
|
Removed use of HAVE_MEMMOVE as well have_memmv.c. Removed the
|
||||||
@@ -17,8 +51,6 @@ The following are the changes from calc version 2.15.1.1 to 2.15.1.1:
|
|||||||
|
|
||||||
Put full date range (1989-2025) of calc source into version.h.
|
Put full date range (1989-2025) of calc source into version.h.
|
||||||
|
|
||||||
Version 2.16.0.0 will form the basis for the calc v2 to calc v3 fork.
|
|
||||||
|
|
||||||
|
|
||||||
The following are the changes from calc version 2.15.0.7 to 2.15.1.0:
|
The following are the changes from calc version 2.15.0.7 to 2.15.1.0:
|
||||||
|
|
||||||
|
@@ -1245,11 +1245,11 @@ EXT=
|
|||||||
|
|
||||||
# The calc version in the form of x.y.z.w
|
# The calc version in the form of x.y.z.w
|
||||||
#
|
#
|
||||||
VERSION= 2.15.1.2
|
VERSION= 2.16.0.0
|
||||||
|
|
||||||
# The calc major version in the form of x.y.z
|
# The calc major version in the form of x.y.z
|
||||||
#
|
#
|
||||||
VER= 2.15.1
|
VER= 2.16.0
|
||||||
|
|
||||||
# Names of shared libraries with versions
|
# Names of shared libraries with versions
|
||||||
#
|
#
|
||||||
|
@@ -7916,7 +7916,7 @@ print '180: define g7500e(a,b) = *a = b'
|
|||||||
*/
|
*/
|
||||||
define test_ptr()
|
define test_ptr()
|
||||||
{
|
{
|
||||||
local a, b, c, A, B, B1, B2, M, L, p, q, p0, q0;
|
local a, b, c, A, B, B1, B2, M, L, p, q, r, p0, q0;
|
||||||
|
|
||||||
print '7500: Beginning test_ptr';
|
print '7500: Beginning test_ptr';
|
||||||
|
|
||||||
@@ -8042,22 +8042,21 @@ define test_ptr()
|
|||||||
p = &M[0], *p = 5;
|
p = &M[0], *p = 5;
|
||||||
print '7587: p = &M[0], *p = 5;';
|
print '7587: p = &M[0], *p = 5;';
|
||||||
vrfy(M[0] == 5, '7588: M[0] == 5');
|
vrfy(M[0] == 5, '7588: M[0] == 5');
|
||||||
*++p = 6;
|
q = &M[1], *q = 6;
|
||||||
print '7589: *++p = 6;';
|
print '7589: q = &M[1], *q = 6;';
|
||||||
vrfy(M[1] == 6, '7590: M[1] == 6');
|
vrfy(M[1] == 6, '7588: M[1] == 6');
|
||||||
q = p++;
|
vrfy(M[0] == 5, '7588: M[0] == 5');
|
||||||
print '7591: q = p++;';
|
|
||||||
vrfy(q == &M[1], '7592: q == &M[1]');
|
vrfy(q == &M[1], '7592: q == &M[1]');
|
||||||
vrfy(p == &M[2], '7593: p == &M[2]');
|
vrfy(p == &M[0], '7593: p == &M[0]');
|
||||||
quomod(17,5,*q,*p);
|
quomod(17,5,*q,*p);
|
||||||
print '7594: quomod(17,5,*p,*q);';
|
print '7594: quomod(17,5,*p,*q);';
|
||||||
vrfy(M[1] == 3 && M[2] == 2, '7595: M[1] == 3 && M[2] == 2');
|
vrfy(M[1] == 3 && M[0] == 2, '7595: M[1] == 3 && M[0] == 2');
|
||||||
swap(*p, *q);
|
swap(*p, *q);
|
||||||
print '7596: swap(*p, *q);';
|
print '7596: swap(*p, *q);';
|
||||||
vrfy(M[1] == 2 && M[2] == 3, '7597: M[1] == 2 && M[2] == 3');
|
vrfy(M[1] == 2 && M[0] == 3, '7597: M[1] == 2 && M[0] == 3');
|
||||||
A = *M = {7,8};
|
A = *M = {7,8};
|
||||||
print '7598: A = *M = {7,8};';
|
print '7598: A = *M = {7,8};';
|
||||||
vrfy(M == (mat[4] = {5,2,3,4}), '7599: M == (mat[4] = {5,2,3,4})');
|
vrfy(M == (mat[4] = {3,2,3,4}), '7599: M == (mat[4] = {3,2,3,4})');
|
||||||
vrfy(A == (mat[4] = {7,8,3,4}), '7600: A == (mat[4] = {7,8,3,4})');
|
vrfy(A == (mat[4] = {7,8,3,4}), '7600: A == (mat[4] = {7,8,3,4})');
|
||||||
|
|
||||||
/* Values which point to themselves */
|
/* Values which point to themselves */
|
||||||
@@ -8069,46 +8068,64 @@ define test_ptr()
|
|||||||
print '7603: A = &B, B = &A;';
|
print '7603: A = &B, B = &A;';
|
||||||
vrfy(**A == A && ***A == B, '7604: **A == A && ***A == B');
|
vrfy(**A == A && ***A == B, '7604: **A == A && ***A == B');
|
||||||
|
|
||||||
/* Testing functions that return pointers */
|
/* verify arithmetic value address operation restrictions */
|
||||||
|
|
||||||
M[3] = 7;
|
M = mat[10] = {0,1,2,3,4,5,6,7,8,9};
|
||||||
print '7605: M[3] = 7;';
|
print '7605: M = mat[10] = {0,1,2,3,4,5,6,7,8,9};';
|
||||||
vrfy(*g7500b(&M[1], 2) == 7, '7606: *g7500b(&M[1], 2) == 7');
|
/* NOTE: The next set of tests will trigger 10 errors by design */
|
||||||
|
ecnt += 10;
|
||||||
*g7500b(&M[1], 2) = 8;
|
print '7606: ecnt += 10';
|
||||||
print '7607: *g7500b(&M[1], 2) = 8;';
|
p = &M[3];
|
||||||
vrfy(M[3] == 8, '7608: M[3] == 8');
|
print '7607: p = &M[3]';
|
||||||
M[3] = list(9,10);
|
++p;
|
||||||
print '7609: M[3] = list(9,10);';
|
print '7608: ++p';
|
||||||
vrfy((*g7500b(&M[1], 2))[[1]] == 10,
|
vrfy(p == error("E_INVALID_ADDR_OP"),
|
||||||
'7610: (*g7500b(&M[1], 2))[[1]] == 10');
|
'7609: p == error("E_INVALID_ADDR_OP")');
|
||||||
|
p = &M[4];
|
||||||
|
print '7610: p = &M[4]';
|
||||||
|
p++;
|
||||||
|
print '7611: p++';
|
||||||
|
vrfy(p == error("E_INVALID_ADDR_OP"),
|
||||||
|
'7612: p == error("E_INVALID_ADDR_OP")');
|
||||||
|
p = &M[5];
|
||||||
|
print '7613: p = &M[5]';
|
||||||
|
q = &M[8];
|
||||||
|
print '7614: q = &M[8]';
|
||||||
|
vrfy(q+5 == error("E_INVALID_ADDR_OP"),
|
||||||
|
'7615: q+5 == error("E_INVALID_ADDR_OP")');
|
||||||
|
vrfy(q-7 == error("E_INVALID_ADDR_OP"),
|
||||||
|
'7616: q-7 == error("E_INVALID_ADDR_OP")');
|
||||||
|
vrfy(p+q == error("E_INVALID_ADDR_OP"),
|
||||||
|
'7617: p+q == error("E_INVALID_ADDR_OP")');
|
||||||
|
r = p-q;
|
||||||
|
print '7618: r = p-q;';
|
||||||
|
|
||||||
/* Testing number and string pointers */
|
/* Testing number and string pointers */
|
||||||
|
|
||||||
a = 24, b = 4 * 6, c = 4!;
|
a = 24, b = 4 * 6, c = 4!;
|
||||||
print '7611: a = 24, b = 4 * 6, c= 4!;';
|
print '7619: a = 24, b = 4 * 6, c= 4!;';
|
||||||
vrfy(isptr(&*a) == 4, '7612: isptr(&*a) == 4');
|
vrfy(isptr(&*a) == 4, '7620: isptr(&*a) == 4');
|
||||||
vrfy(&*a == &24, '7613: &*a == &24');
|
vrfy(&*a == &24, '7621: &*a == &24');
|
||||||
vrfy(&*a == &*b, '7614: &*a == &*b');
|
vrfy(&*a == &*b, '7622: &*a == &*b');
|
||||||
vrfy(&*a != &*c, '7615: &*a != &*c');
|
vrfy(&*a != &*c, '7623: &*a != &*c');
|
||||||
|
|
||||||
a = b = "abc", c = strcat("a", "bc");
|
a = b = "abc", c = strcat("a", "bc");
|
||||||
print '7616: a = b = "abc", c = strcat("a", "bc");';
|
print '7624: a = b = "abc", c = strcat("a", "bc");';
|
||||||
vrfy(isptr(&*a) == 3, '7617: isptr(&*a) == 3');
|
vrfy(isptr(&*a) == 3, '7625: isptr(&*a) == 3');
|
||||||
vrfy(&*a == &"abc", '7618: &*a == &"abc"');
|
vrfy(&*a == &"abc", '7626: &*a == &"abc"');
|
||||||
vrfy(&*a == &*b, '7619: &*a == &*b');
|
vrfy(&*a == &*b, '7627: &*a == &*b');
|
||||||
vrfy(&*a != &*c, '7620: &*a != &*c');
|
vrfy(&*a != &*c, '7628: &*a != &*c');
|
||||||
a = c;
|
a = c;
|
||||||
print '7621: a = c;';
|
print '7629: a = c;';
|
||||||
vrfy(&*a == &*c, '7622: &*a == &*c');
|
vrfy(&*a == &*c, '7630: &*a == &*c');
|
||||||
|
|
||||||
/* Verifying null-ness of freed numbers */
|
/* Verifying null-ness of freed numbers */
|
||||||
|
|
||||||
c = 4!, p = &*c, free(c);
|
c = 4!, p = &*c, free(c);
|
||||||
print '7623: c = 4!, p = &*c, free(c)';
|
print '7631: c = 4!, p = &*c, free(c)';
|
||||||
vrfy(isnull(*p), '7624: isnull(*p)');
|
vrfy(isnull(*p), '7632: isnull(*p)');
|
||||||
|
|
||||||
print '7625: Ending test_ptr';
|
print '7633: Ending test_ptr';
|
||||||
}
|
}
|
||||||
print '181: parsed test_ptr()';
|
print '181: parsed test_ptr()';
|
||||||
|
|
||||||
@@ -9165,8 +9182,8 @@ read -once "test8900.special";
|
|||||||
print '8902: about to run test8900(1,,8903)';
|
print '8902: about to run test8900(1,,8903)';
|
||||||
testnum = test8900(1,,8903);
|
testnum = test8900(1,,8903);
|
||||||
print "8941: ecnt ==", ecnt;
|
print "8941: ecnt ==", ecnt;
|
||||||
print '8942: ecnt = 214;'
|
print '8942: ecnt = 224;'
|
||||||
ecnt = 214;
|
ecnt = 224;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
2
errtbl.c
2
errtbl.c
@@ -759,6 +759,8 @@ CONST struct errtbl error_table[] =
|
|||||||
{ 10607, "E_LOG_5", "Cannot calculate log of 0" },
|
{ 10607, "E_LOG_5", "Cannot calculate log of 0" },
|
||||||
{ 10608, "E_LOG2_4", "Cannot calculate log base 2 of 0" },
|
{ 10608, "E_LOG2_4", "Cannot calculate log base 2 of 0" },
|
||||||
{ 10609, "E_LOGN_6", "Cannot calculate log base n of 0" },
|
{ 10609, "E_LOGN_6", "Cannot calculate log base n of 0" },
|
||||||
|
{ 10610, "E_INVALID_DEREF", "Dereferencing a non-variable" },
|
||||||
|
{ 10611, "E_INVALID_ADDR_OP", "Invalid arithmetic address operation" },
|
||||||
/* IMPORTANT NOTE: add new entries above here and be sure their errnum numeric value is consecutive! */
|
/* IMPORTANT NOTE: add new entries above here and be sure their errnum numeric value is consecutive! */
|
||||||
|
|
||||||
/* The next NULL entry must be last */
|
/* The next NULL entry must be last */
|
||||||
|
75
help/address
75
help/address
@@ -113,7 +113,7 @@ DESCRIPTION
|
|||||||
|
|
||||||
(the case of f(0) is exceptional since 27 + 0 simply copies the 27
|
(the case of f(0) is exceptional since 27 + 0 simply copies the 27
|
||||||
rather than creating a new number value). Here it is clearly more
|
rather than creating a new number value). Here it is clearly more
|
||||||
efficient to use
|
efficient to use:
|
||||||
|
|
||||||
; A = B = C = f(2);
|
; A = B = C = f(2);
|
||||||
|
|
||||||
@@ -125,11 +125,74 @@ DESCRIPTION
|
|||||||
and number-pointer respectively, and 0 otherwise.
|
and number-pointer respectively, and 0 otherwise.
|
||||||
|
|
||||||
The output when addresses are printed consists of a description (o_ptr,
|
The output when addresses are printed consists of a description (o_ptr,
|
||||||
v_ptr, s_ptr, n_ptr) followed by : and the address printed in
|
v_ptr, s_ptr, n_ptr) followed by : and the address printed in %p format.
|
||||||
%p format.
|
|
||||||
|
|
||||||
Iteration of & is not permitted; &&X causes a "non-variable operand"
|
Iteration of & is not permitted; &(&X) causes a "Addressing
|
||||||
scan error.
|
non-addressable type" scan error.
|
||||||
|
|
||||||
|
RESTRICTIONS ON VALUE ADDRESS ARITHMETIC
|
||||||
|
Most arithmetic operations on addresses of values are not permitted.
|
||||||
|
For example one may not perform arithmetic operations (like +, ++,
|
||||||
|
-, --, *, /, etc.) on an address of a value with a numeric value.
|
||||||
|
|
||||||
|
The reason why most arithmetic operations were removed from calc
|
||||||
|
because arithmetic on addresses of calc objects could easily cause
|
||||||
|
calc to crash. Consider this horrific expression that was allowed
|
||||||
|
in calc prior to version 2.16.0.0:
|
||||||
|
|
||||||
|
; *((&.)+1e9) /* INVALID: for calc version >= 2.16.0.0 */
|
||||||
|
|
||||||
|
Prior to calc version 2.16.0.0, some arithmetic operations on
|
||||||
|
addresses of values were permitted. Starting with calc version
|
||||||
|
2.16.0.0, arithmetic operations between an addresses and an integer
|
||||||
|
will return an error code:
|
||||||
|
|
||||||
|
; ++p; /* INVALID: will be set to E_INVALID_ADDR_OP */
|
||||||
|
; r = q - 2; /* INVALID: will be set to E_INVALID_ADDR_OP */
|
||||||
|
|
||||||
|
Adding two value addresses is NOT permitted:
|
||||||
|
|
||||||
|
; mat A[3];
|
||||||
|
; p = &A[1];
|
||||||
|
; q = &A[2];
|
||||||
|
; s = p + q; /* INVALID: will be set to E_INVALID_ADDR_OP */
|
||||||
|
|
||||||
|
Subtracting two value addresses is permitted, however there is NO
|
||||||
|
guarantee that the address of a value will remain consistent across
|
||||||
|
calc runs. Addresses of values depend on the circumstances of when
|
||||||
|
the calc values were formed. For example:
|
||||||
|
|
||||||
|
; a = 3; pa = &a;
|
||||||
|
; /* ... stuff happens ... */
|
||||||
|
; b = 5; pb = &b;
|
||||||
|
; t = pa - pb; /* permitted: value depends on circumstances */
|
||||||
|
|
||||||
|
Subtracting value addresses of components with the same compound
|
||||||
|
object, such as a matrix, is permitted. For example:
|
||||||
|
|
||||||
|
; mat M[10] = {0,1,2,3,4,5,6,7,8,9};
|
||||||
|
; i = 4; j = 5;
|
||||||
|
; p = &M[i]; q = &M[j];
|
||||||
|
; v = p - q; /* permitted: value depends on circumstances */
|
||||||
|
|
||||||
|
Comparison between two value addresses is permitted, however the
|
||||||
|
same caveats apply as to the subtracting of addresses:
|
||||||
|
|
||||||
|
; if (p < q) {
|
||||||
|
;; print "permitted: p is less than q";
|
||||||
|
;; } else if (p == q) {
|
||||||
|
;; print "permitted: p is equal to q";
|
||||||
|
;; } else {
|
||||||
|
;; print "permitted: p is greater than q";
|
||||||
|
;; }
|
||||||
|
|
||||||
|
PLEASE NOTE:
|
||||||
|
|
||||||
|
The above restrictions and caveats apply to addresses of values.
|
||||||
|
Such restrictions and caveats to NOT apply to the addresses of
|
||||||
|
octets, NOR to the addresses within strings. If isptr(x) == 2,
|
||||||
|
then x is value-pointer and the above mentioned restrictions
|
||||||
|
and caveats apply it.
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
Addresses for particular systems may differ from those displayed here.
|
Addresses for particular systems may differ from those displayed here.
|
||||||
@@ -160,7 +223,7 @@ LINK LIBRARY
|
|||||||
SEE ALSO
|
SEE ALSO
|
||||||
dereference, isptr
|
dereference, isptr
|
||||||
|
|
||||||
## Copyright (C) 1999-2006,2021 Landon Curt Noll
|
## Copyright (C) 1999-2006,2021,2025 Landon Curt Noll
|
||||||
##
|
##
|
||||||
## Calc is open software; you can redistribute it and/or modify it under
|
## Calc is open software; you can redistribute it and/or modify it under
|
||||||
## the terms of the version 2.1 of the GNU Lesser General Public License
|
## the terms of the version 2.1 of the GNU Lesser General Public License
|
||||||
|
@@ -959,8 +959,8 @@ o_deref(FUNC *UNUSED(fp))
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stack->v_type != V_ADDR) {
|
if (stack->v_type != V_ADDR) {
|
||||||
math_error("Dereferencing a non-variable");
|
*stack = error_value(E_INVALID_DEREF);
|
||||||
not_reached();
|
return;
|
||||||
}
|
}
|
||||||
vp = vp->v_addr;
|
vp = vp->v_addr;
|
||||||
switch (vp->v_type) {
|
switch (vp->v_type) {
|
||||||
|
23
value.c
23
value.c
@@ -434,6 +434,8 @@ addvalue(VALUE *v1, VALUE *v2, VALUE *vres)
|
|||||||
*vres = error_value(E_STRADD);
|
*vres = error_value(E_STRADD);
|
||||||
return;
|
return;
|
||||||
case TWOVAL(V_VPTR, V_NUM):
|
case TWOVAL(V_VPTR, V_NUM):
|
||||||
|
#if defined(PERMIT_DANGEROUS_ADDRESS_ARITHMETIC)
|
||||||
|
/* NOTE: Defining PERMIT_DANGEROUS_ADDRESS_ARITHMETIC is NOT supported! */
|
||||||
q = v2->v_num;
|
q = v2->v_num;
|
||||||
if (qisfrac(q)) {
|
if (qisfrac(q)) {
|
||||||
math_error("Adding non-integer to address");
|
math_error("Adding non-integer to address");
|
||||||
@@ -442,6 +444,12 @@ addvalue(VALUE *v1, VALUE *v2, VALUE *vres)
|
|||||||
i = qtoi(q);
|
i = qtoi(q);
|
||||||
vres->v_addr = v1->v_addr + i;
|
vres->v_addr = v1->v_addr + i;
|
||||||
vres->v_type = V_VPTR;
|
vres->v_type = V_VPTR;
|
||||||
|
#else /* Disable arithmetic on addresses */
|
||||||
|
*vres = error_value(E_INVALID_ADDR_OP);
|
||||||
|
#endif /* Disable arithmetic on addresses */
|
||||||
|
return;
|
||||||
|
case TWOVAL(V_VPTR, V_VPTR):
|
||||||
|
*vres = error_value(E_INVALID_ADDR_OP);
|
||||||
return;
|
return;
|
||||||
case TWOVAL(V_OPTR, V_NUM):
|
case TWOVAL(V_OPTR, V_NUM):
|
||||||
q = v2->v_num;
|
q = v2->v_num;
|
||||||
@@ -515,6 +523,8 @@ subvalue(VALUE *v1, VALUE *v2, VALUE *vres)
|
|||||||
*vres = error_value(E_STRSUB);
|
*vres = error_value(E_STRSUB);
|
||||||
return;
|
return;
|
||||||
case TWOVAL(V_VPTR, V_NUM):
|
case TWOVAL(V_VPTR, V_NUM):
|
||||||
|
#if defined(PERMIT_DANGEROUS_ADDRESS_ARITHMETIC)
|
||||||
|
/* NOTE: Defining PERMIT_DANGEROUS_ADDRESS_ARITHMETIC is NOT supported! */
|
||||||
q = v2->v_num;
|
q = v2->v_num;
|
||||||
if (qisfrac(q)) {
|
if (qisfrac(q)) {
|
||||||
math_error("Subtracting non-integer from address");
|
math_error("Subtracting non-integer from address");
|
||||||
@@ -523,6 +533,9 @@ subvalue(VALUE *v1, VALUE *v2, VALUE *vres)
|
|||||||
i = qtoi(q);
|
i = qtoi(q);
|
||||||
vres->v_addr = v1->v_addr - i;
|
vres->v_addr = v1->v_addr - i;
|
||||||
vres->v_type = V_VPTR;
|
vres->v_type = V_VPTR;
|
||||||
|
#else /* Disable arithmetic on addresses */
|
||||||
|
*vres = error_value(E_INVALID_ADDR_OP);
|
||||||
|
#endif /* Disable arithmetic on addresses */
|
||||||
return;
|
return;
|
||||||
case TWOVAL(V_OPTR, V_NUM):
|
case TWOVAL(V_OPTR, V_NUM):
|
||||||
q = v2->v_num;
|
q = v2->v_num;
|
||||||
@@ -1407,7 +1420,12 @@ incvalue(VALUE *vp, VALUE *vres)
|
|||||||
vres->v_octet = vp->v_octet + 1;
|
vres->v_octet = vp->v_octet + 1;
|
||||||
break;
|
break;
|
||||||
case V_VPTR:
|
case V_VPTR:
|
||||||
|
#if defined(PERMIT_DANGEROUS_ADDRESS_ARITHMETIC)
|
||||||
|
/* NOTE: Defining PERMIT_DANGEROUS_ADDRESS_ARITHMETIC is NOT supported! */
|
||||||
vres->v_addr = vp->v_addr + 1;
|
vres->v_addr = vp->v_addr + 1;
|
||||||
|
#else /* Disable arithmetic on addresses */
|
||||||
|
*vres = error_value(E_INVALID_ADDR_OP);
|
||||||
|
#endif /* Disable arithmetic on addresses */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (vp->v_type > 0)
|
if (vp->v_type > 0)
|
||||||
@@ -1443,7 +1461,12 @@ decvalue(VALUE *vp, VALUE *vres)
|
|||||||
vres->v_octet = vp->v_octet - 1;
|
vres->v_octet = vp->v_octet - 1;
|
||||||
break;
|
break;
|
||||||
case V_VPTR:
|
case V_VPTR:
|
||||||
|
#if defined(PERMIT_DANGEROUS_ADDRESS_ARITHMETIC)
|
||||||
|
/* NOTE: Defining PERMIT_DANGEROUS_ADDRESS_ARITHMETIC is NOT supported! */
|
||||||
vres->v_addr = vp->v_addr - 1;
|
vres->v_addr = vp->v_addr - 1;
|
||||||
|
#else /* Disable arithmetic on addresses */
|
||||||
|
*vres = error_value(E_INVALID_ADDR_OP);
|
||||||
|
#endif /* Disable arithmetic on addresses */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (vp->v_type >= 0)
|
if (vp->v_type >= 0)
|
||||||
|
13
version.h
13
version.h
@@ -66,5 +66,18 @@
|
|||||||
#define MAJOR_PATCH 1 /* level 3: major software version level */
|
#define MAJOR_PATCH 1 /* level 3: major software version level */
|
||||||
#define MINOR_PATCH 2 /* level 4: minor software version level */
|
#define MINOR_PATCH 2 /* level 4: minor software version level */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defining PERMIT_DANGEROUS_ADDRESS_ARITHMETIC is NOT supported!
|
||||||
|
*
|
||||||
|
* If someone were to be a foolish as to permit dangerous address arithmetic, then we
|
||||||
|
* negate the major version to further "disavow" such a calc compile.
|
||||||
|
*/
|
||||||
|
#if defined(PERMIT_DANGEROUS_ADDRESS_ARITHMETIC)
|
||||||
|
# undef TEMP_MAJOR_VER
|
||||||
|
# define TEMP_MAJOR_VER MAJOR_VER
|
||||||
|
# undef MAJOR_VER
|
||||||
|
# define MAJOR_VER (-TEMP_MAJOR_VER)
|
||||||
|
# undef TEMP_MAJOR_VER
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* !INCLUDE_VERSION_H*/
|
#endif /* !INCLUDE_VERSION_H*/
|
||||||
|
Reference in New Issue
Block a user