Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit fdb9e97

Browse files
committed
Merge pull request #2041 from peter-b/bugfix-14679
com.livecode.math: Fix various broken/skipped tests
2 parents 181207e + 1a8a714 commit fdb9e97

File tree

5 files changed

+100
-21
lines changed

5 files changed

+100
-21
lines changed

docs/lcb/notes/14678.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# LiveCode Builder Standard Library
2+
## Mathematical functions
3+
4+
* Several mathematical functions now throw "domain errors" when
5+
applied to values that the function is not defined for, including
6+
`log10()`, `ln()`, `asin()` and `acos()`, and `x ^ y`.
7+
8+
# [14678] Throw error on domain error in log10() and ln()
9+
# [14679] Throw error on domain error in pow()
10+
# [14681] Throw error on domain error in asin() and acos()

engine/src/modules.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,15 @@ extern "C"
134134
}
135135

136136
extern bool MCForeignModuleInitialize(void);
137+
extern bool MCMathModuleInitialize(void);
137138
extern bool MCCanvasModuleInitialize(void);
138139
extern bool MCEngineModuleInitialize(void);
139140
bool MCModulesInitialize(void)
140141
{
141142
if (!MCForeignModuleInitialize())
142143
return false;
144+
if (!MCMathModuleInitialize())
145+
return false;
143146
if (!MCCanvasModuleInitialize())
144147
return false;
145148
if (!MCEngineModuleInitialize())
@@ -148,11 +151,13 @@ bool MCModulesInitialize(void)
148151
}
149152

150153
extern void MCForeignModuleFinalize(void);
154+
extern void MCMathModuleFinalize(void);
151155
extern void MCCanvasModuleFinalize(void);
152156
extern void MCEngineModuleFinalize(void);
153157
void MCModulesFinalize(void)
154158
{
155159
MCEngineModuleFinalize();
156160
MCCanvasModuleFinalize();
161+
MCMathModuleFinalize();
157162
MCForeignModuleFinalize();
158163
}

libscript/src/module-math.cpp

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,28 @@
1919
#include <foundation-system.h>
2020

2121
#include <float.h>
22+
#include <errno.h>
2223

2324
// Older versions of MSVC don't supply "trunc"
2425
#ifdef _WIN32
2526
double trunc(double f) { return f < 0 ? ceil(f) : floor(f); }
2627
#endif
2728

29+
////////////////////////////////////////////////////////////////
30+
31+
MCTypeInfoRef kMCMathDomainErrorTypeInfo;
32+
33+
////////////////////////////////////////////////////////////////
34+
2835
extern "C" MC_DLLEXPORT void MCMathEvalRealToPowerOfReal(double p_left, double p_right, double& r_output)
2936
{
30-
if (p_right == 0)
31-
{
32-
r_output = 1.0;
33-
return;
34-
}
35-
37+
errno = 0;
3638
r_output = pow(p_left, p_right);
39+
40+
if (errno == EDOM)
41+
{
42+
MCErrorCreateAndThrow (kMCMathDomainErrorTypeInfo, nil);
43+
}
3744
}
3845

3946
extern "C" MC_DLLEXPORT void MCMathEvalNumberToPowerOfNumber(MCNumberRef p_left, MCNumberRef p_right, MCNumberRef& r_output)
@@ -51,7 +58,13 @@ extern "C" MC_DLLEXPORT void MCMathEvalNumberToPowerOfNumber(MCNumberRef p_left,
5158

5259
extern "C" MC_DLLEXPORT void MCMathEvalBase10LogReal(double p_operand, double& r_output)
5360
{
61+
errno = 0;
5462
r_output = log10(p_operand);
63+
64+
if (errno == EDOM)
65+
{
66+
MCErrorCreateAndThrow (kMCMathDomainErrorTypeInfo, nil);
67+
}
5568
}
5669

5770
extern "C" MC_DLLEXPORT void MCMathEvalBase10LogNumber(MCNumberRef p_operand, MCNumberRef& r_output)
@@ -68,7 +81,13 @@ extern "C" MC_DLLEXPORT void MCMathEvalBase10LogNumber(MCNumberRef p_operand, MC
6881

6982
extern "C" MC_DLLEXPORT void MCMathEvalNaturalLogReal(double p_operand, double& r_output)
7083
{
84+
errno = 0;
7185
r_output = log(p_operand);
86+
87+
if (errno == EDOM)
88+
{
89+
MCErrorCreateAndThrow (kMCMathDomainErrorTypeInfo, nil);
90+
}
7291
}
7392

7493
extern "C" MC_DLLEXPORT void MCMathEvalNaturalLogNumber(MCNumberRef p_operand, MCNumberRef& r_output)
@@ -153,7 +172,13 @@ extern "C" MC_DLLEXPORT void MCMathEvalTanNumber(MCNumberRef p_operand, MCNumber
153172

154173
extern "C" MC_DLLEXPORT void MCMathEvalAsinReal(double p_operand, double& r_output)
155174
{
175+
errno = 0;
156176
r_output = asin(p_operand);
177+
178+
if (errno == EDOM)
179+
{
180+
MCErrorCreateAndThrow (kMCMathDomainErrorTypeInfo, nil);
181+
}
157182
}
158183

159184
extern "C" MC_DLLEXPORT void MCMathEvalAsinNumber(MCNumberRef p_operand, MCNumberRef& r_output)
@@ -170,7 +195,13 @@ extern "C" MC_DLLEXPORT void MCMathEvalAsinNumber(MCNumberRef p_operand, MCNumbe
170195

171196
extern "C" MC_DLLEXPORT void MCMathEvalAcosReal(double p_operand, double& r_output)
172197
{
198+
errno = 0;
173199
r_output = acos(p_operand);
200+
201+
if (errno == EDOM)
202+
{
203+
MCErrorCreateAndThrow (kMCMathDomainErrorTypeInfo, nil);
204+
}
174205
}
175206

176207
extern "C" MC_DLLEXPORT void MCMathEvalAcosNumber(MCNumberRef p_operand, MCNumberRef& r_output)
@@ -417,4 +448,21 @@ extern "C" MC_DLLEXPORT void MCMathEvalConvertBase(MCStringRef p_operand, intege
417448
MCErrorCreateAndThrow(kMCGenericErrorTypeInfo, "reason", MCSTR("integer overflow, or invalid character in source"), nil);
418449
}
419450

451+
////////////////////////////////////////////////////////////////
452+
453+
bool
454+
MCMathModuleInitialize (void)
455+
{
456+
if (!MCNamedErrorTypeInfoCreate (MCNAME("com.livecode.math.DomainError"), MCNAME("math"), MCSTR("mathematical function domain error"), kMCMathDomainErrorTypeInfo))
457+
return false;
458+
459+
return true;
460+
}
461+
462+
void
463+
MCMathModuleFinalize (void)
464+
{
465+
MCValueRelease (kMCMathDomainErrorTypeInfo);
466+
}
467+
420468
////////////////////////////////////////////////////////////////////////////////////////////////////

tests/lcb/stdlib/math.lcb

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ public handler TestPow()
5757
test "pow (-ve, 0)" when (-2) ^ 0 is 1
5858
end handler
5959

60-
handler TestPowDomain_Imag() as undefined
61-
variable tVar
62-
put (-1) ^ 0.5 into tVar
60+
handler TestPowDomain_Imag()
61+
return (-1) ^ 0.5
6362
end handler
6463
public handler TestPowDomain()
65-
MCUnitTestHandlerThrowsBroken(TestPowDomain_Imag, "pow (imaginary)", "bug 14679")
64+
-- bug 14679
65+
MCUnitTestHandlerThrows(TestPowDomain_Imag, "pow (imaginary)")
6666
end handler
6767

6868
public handler TestPowPrecedence()
@@ -84,7 +84,9 @@ handler TestLog10Domain_Zero() as undefined
8484
put the log of 0 into tVar
8585
end handler
8686
public handler TestLog10Domain()
87-
MCUnitTestHandlerThrowsBroken(TestLog10Domain_Negative, "log10 (syntax, -ve)", "bug 14678")
87+
-- bug 14678
88+
MCUnitTestHandlerThrows(TestLog10Domain_Negative, "log10 (syntax, -ve)")
89+
8890
MCUnitTestHandlerThrowsBroken(TestLog10Domain_Zero, "log10 (syntax, 0)", "bug 14678")
8991
end handler
9092

@@ -120,17 +122,15 @@ public handler TestArctan()
120122
test "arctan2 (function)" when the binary arctangent of -1 and -1 is -3 * pi / 4
121123
end handler
122124

123-
handler TestTrigonometricDomain_Arcsin() as undefined
124-
variable t
125-
put asin((1 + any number) / any number) into t
125+
handler TestTrigonometricDomain_Arcsin()
126+
return asin((1 + any number) / any number)
126127
end handler
127128
handler TestTrigonometricDomain_Arccos() as undefined
128-
variable t
129-
put acos((1 + any number) / any number) into t
129+
return acos((1 + any number) / any number)
130130
end handler
131131
public handler TestTrigonometricDomain()
132-
MCUnitTestHandlerThrowsBroken(TestTrigonometricDomain_Arcsin, "arcsin (> 1)", "bug 14681")
133-
MCUnitTestHandlerThrowsBroken(TestTrigonometricDomain_Arccos, "arccos (> 1)", "bug 14681")
132+
MCUnitTestHandlerThrows(TestTrigonometricDomain_Arcsin, "arcsin (> 1)")
133+
MCUnitTestHandlerThrows(TestTrigonometricDomain_Arccos, "arccos (> 1)")
134134
end handler
135135

136136
public handler TestExp()
@@ -160,7 +160,8 @@ handler TestLnDomain_Zero() as undefined
160160
put the natural log of 0 into tVar
161161
end handler
162162
public handler TestLnDomain()
163-
MCUnitTestHandlerThrowsBroken(TestLnDomain_Negative, "ln (syntax, -ve)", "bug 14678")
163+
-- bug 14678
164+
MCUnitTestHandlerThrows(TestLnDomain_Negative, "ln (syntax, -ve)")
164165
MCUnitTestHandlerThrowsBroken(TestLnDomain_Zero, "ln (syntax, 0)", "bug 14678")
165166
end handler
166167

@@ -184,19 +185,27 @@ public handler TestMinBinary()
184185
test "min (function)" when min(4, 5) is 4
185186
end handler
186187

188+
handler TestMinList_Empty()
189+
return the minimum value of []
190+
end handler
187191
public handler TestMinList()
188192
test "min (list)" when the minimum value of [2, 1, 3] is 1
189-
skip test "min (empty list)" because "Can't test for errors"
193+
194+
MCUnitTestHandlerThrows(TestMinList_Empty, "min (empty list)")
190195
end handler
191196

192197
public handler TestMaxBinary()
193198
test "max (syntax)" when the maximum of 3 and 5 is 5
194199
test "max (function)" when max(4, 5) is 5
195200
end handler
196201

202+
handler TestMaxList_Empty()
203+
return the maximum value of []
204+
end handler
197205
public handler TestMaxList()
198206
test "max (list)" when the maximum value of [2, 1, 3] is 3
199-
skip test "max (empty list)" because "Can't test for errors"
207+
208+
MCUnitTestHandlerThrows(TestMaxList_Empty, "max (empty list)")
200209
end handler
201210

202211
handler TestBaseConvert_InvalidFormat() as LCUInt

toolchain/lc-compile/src/module-helper.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,15 +130,22 @@ void *g_builtin_ptrs[] =
130130
}
131131

132132
extern bool MCForeignModuleInitialize(void);
133+
extern bool MCMathModuleInitialize(void);
134+
133135
bool MCModulesInitialize(void)
134136
{
135137
if (!MCForeignModuleInitialize())
136138
return false;
139+
if (!MCMathModuleInitialize())
140+
return false;
137141
return true;
138142
}
139143

140144
extern void MCForeignModuleFinalize(void);
145+
extern void MCMathModuleFinalize(void);
146+
141147
void MCModulesFinalize(void)
142148
{
149+
MCMathModuleFinalize();
143150
MCForeignModuleFinalize();
144151
}

0 commit comments

Comments
 (0)