1 #include "stdafx.h"
2 #include <sstream>
3 #include <math.h>
4 
5 #include "alglibmisc.h"
6 #include "alglibinternal.h"
7 #include "linalg.h"
8 #include "statistics.h"
9 #include "dataanalysis.h"
10 #include "specialfunctions.h"
11 #include "solvers.h"
12 #include "optimization.h"
13 #include "diffequations.h"
14 #include "fasttransforms.h"
15 #include "integration.h"
16 #include "interpolation.h"
17 
18 #if !defined(AE_NO_EXCEPTIONS)
19 #error "This test should be compiled with AE_NO_EXCEPTIONS defined"
20 #endif
21 
22 using namespace alglib;
23 
24 const char *fmt_str = "%-29s %s\n";
25 
main()26 int main()
27 {
28     printf("Test exception-free error handling:\n");
29 
30 #ifdef AE_USE_ALLOC_COUNTER
31     printf("Allocation counter activated...\n");
32     alglib_impl::_use_alloc_counter = ae_true;
33     if( alglib_impl::_alloc_counter!=0 )
34     {
35         printf("FAILURE: alloc_counter is non-zero on start!\n");
36         return 1;
37     }
38     {
39         {
40             alglib::real_1d_array x;
41             x.setlength(1);
42             if( alglib_impl::_alloc_counter==0 )
43                 printf(":::: WARNING: ALLOC_COUNTER IS INACTIVE!!! :::::\\n");
44         }
45         if( alglib_impl::_alloc_counter!=0 )
46         {
47             printf("FAILURE: alloc_counter does not decrease!\n");
48             return 1;
49         }
50     }
51 #endif
52 
53     //
54     // Test default state of the error flag
55     //
56     {
57         bool passed = true;
58         passed = passed && !alglib::get_error_flag();
59         printf(fmt_str, "* default flag value", passed ? "OK" : "FAILED");
60         fflush(stdout);
61         if( !passed )
62             return 1;
63     }
64 
65     //
66     // Test errors during array creation
67     //
68     {
69         bool passed = true;
70         alglib::clear_error_flag();
71 
72         // constructors succeeded with working malloc()
73         alglib::clear_error_flag();
74         alglib::real_1d_array r1;
75         passed = passed && !alglib::get_error_flag();
76 
77         // even with broken malloc() constructor succeeded()
78         alglib::clear_error_flag();
79         alglib_impl::_force_malloc_failure = true;
80         alglib::real_1d_array r2;
81         passed = passed && !alglib::get_error_flag();
82 
83         // but setlength() fails without malloc()
84         alglib::clear_error_flag();
85         r2.setlength(5);
86         passed = passed &&  alglib::get_error_flag();
87 
88         // clear_error_flag() clears error flag
89         alglib::clear_error_flag();
90         passed = passed && !alglib::get_error_flag();
91 
92         // without clear_error_flag(), error flag is not reset by successful calls
93         alglib::clear_error_flag();
94         alglib_impl::_force_malloc_failure = true;
95         r2.setlength(5);
96         passed = passed &&  alglib::get_error_flag() && r2.length()==0;
97         alglib_impl::_force_malloc_failure = false;
98         r2.setlength(6);
99         passed = passed &&  alglib::get_error_flag() && r2.length()==6;
100         alglib::clear_error_flag();
101         r2.setlength(7);
102         passed = passed && !alglib::get_error_flag() && r2.length()==7;
103 
104         // assignment to empty array requires malloc()
105         alglib::clear_error_flag();
106         alglib_impl::_force_malloc_failure = false;
107         alglib::real_1d_array r3;
108         r2.setlength(1);
109         r2[0] = 123.25;
110         alglib_impl::_force_malloc_failure = true;
111         r3 = r2;
112         passed = passed &&  alglib::get_error_flag() && r3.length()==0;
113         alglib_impl::_force_malloc_failure = false;
114         alglib::clear_error_flag();
115         r3 = r2;
116         passed = passed && !alglib::get_error_flag() && r3.length()==1 && r3[0]==123.25;
117 
118         // assignment to non-empty array does NOT require malloc()
119         alglib::clear_error_flag();
120         alglib_impl::_force_malloc_failure = true;
121         r2[0] = 345;
122         r3 = r2;
123         passed = passed && !alglib::get_error_flag() && r3.length()==1 && r3[0]==345;
124         alglib_impl::_force_malloc_failure = false;
125 
126         printf(fmt_str, "* 1D arrays", passed ? "OK" : "FAILED");
127         fflush(stdout);
128         if( !passed )
129             return 1;
130     }
131     {
132         bool passed = true;
133         alglib::clear_error_flag();
134 
135         // constructors succeeded with working malloc()
136         alglib::clear_error_flag();
137         alglib::real_2d_array r1;
138         passed = passed && !alglib::get_error_flag();
139 
140         // even with broken malloc() constructor succeeded()
141         alglib::clear_error_flag();
142         alglib_impl::_force_malloc_failure = true;
143         alglib::real_2d_array r2;
144         passed = passed && !alglib::get_error_flag();
145 
146         // but setlength() fails without malloc()
147         alglib::clear_error_flag();
148         r2.setlength(5,6);
149         passed = passed &&  alglib::get_error_flag();
150 
151         // clear_error_flag() clears error flag
152         alglib::clear_error_flag();
153         passed = passed && !alglib::get_error_flag();
154 
155         // without clear_error_flag(), error flag is not reset by successful calls
156         alglib::clear_error_flag();
157         alglib_impl::_force_malloc_failure = true;
158         r2.setlength(5,6);
159         passed = passed &&  alglib::get_error_flag() && r2.rows()==0 && r2.cols()==0;
160         alglib_impl::_force_malloc_failure = false;
161         r2.setlength(6,7);
162         passed = passed &&  alglib::get_error_flag() && r2.rows()==6 && r2.cols()==7;
163         alglib::clear_error_flag();
164         r2.setlength(7,8);
165         passed = passed && !alglib::get_error_flag() && r2.rows()==7 && r2.cols()==8;
166 
167         // assignment to empty array requires malloc()
168         alglib::clear_error_flag();
169         alglib_impl::_force_malloc_failure = false;
170         alglib::real_2d_array r3;
171         r2.setlength(1,1);
172         r2[0][0] = 123.25;
173         alglib_impl::_force_malloc_failure = true;
174         r3 = r2;
175         passed = passed &&  alglib::get_error_flag() && r3.rows()==0 && r3.cols()==0;
176         alglib_impl::_force_malloc_failure = false;
177         alglib::clear_error_flag();
178         r3 = r2;
179         passed = passed && !alglib::get_error_flag() && r3.rows()==1 && r3.cols()==1 && r3[0][0]==123.25;
180 
181         // assignment to non-empty array does NOT require malloc()
182         alglib::clear_error_flag();
183         alglib_impl::_force_malloc_failure = true;
184         r2[0][0] = 345;
185         r3 = r2;
186         passed = passed && !alglib::get_error_flag() && r3.rows()==1 && r3.cols()==1 && r3[0][0]==345;
187         alglib_impl::_force_malloc_failure = false;
188 
189         printf(fmt_str, "* 2D arrays", passed ? "OK" : "FAILED");
190         fflush(stdout);
191         if( !passed )
192             return 1;
193     }
194 
195     //
196     // Test ALGLIB objects
197     //
198     {
199         bool passed = true;
200         alglib::clear_error_flag();
201 
202         // prepare data for tests
203         alglib::real_1d_array x, y;
204         x.setlength(2);
205         x[0] = 0;
206         x[1] = 1;
207         y.setlength(2);
208         y[0] = 2;
209         y[1] = 3;
210 
211         // constructors succeeded with working malloc()
212         alglib::clear_error_flag();
213         alglib::spline1dinterpolant s1;
214         passed = passed && !alglib::get_error_flag();
215 
216         // with broken malloc() constructor fails()
217         alglib::clear_error_flag();
218         alglib_impl::_force_malloc_failure = true;
219         alglib::spline1dinterpolant s2;
220         passed = passed &&  alglib::get_error_flag();
221         alglib_impl::_force_malloc_failure = false;
222 
223         // construction with correct malloc() succeeds
224         alglib::clear_error_flag();
225         alglib::spline1dbuildlinear(x, y, 2, s1);
226         passed = passed && !alglib::get_error_flag() && fabs(alglib::spline1dcalc(s1,0.5)-2.5)<1.0E-12;
227 
228         // assignment with broken malloc() fails
229         alglib::clear_error_flag();
230         alglib::spline1dinterpolant s3;
231         alglib_impl::_force_malloc_failure = true;
232         s3 = s1;
233         alglib_impl::_force_malloc_failure = false;
234         passed = passed &&  alglib::get_error_flag();
235 
236         // assignment with broken object fails, but does not crash
237         alglib::clear_error_flag();
238         alglib_impl::_force_malloc_failure = true;
239         alglib::spline1dinterpolant s3b;
240         passed = passed && s3b.c_ptr()==NULL;
241         s3b = s1;
242         alglib_impl::_force_malloc_failure = false;
243         passed = passed &&  alglib::get_error_flag();
244 
245         // assignment with working malloc() succeeds
246         alglib::clear_error_flag();
247         s3 = s1;
248         passed = passed && !alglib::get_error_flag() && fabs(alglib::spline1dcalc(s3,0.5)-2.5)<1.0E-12;
249 
250         // copy constructor with broken malloc fails
251         alglib::clear_error_flag();
252         alglib_impl::_force_malloc_failure = true;
253         alglib::spline1dinterpolant s4(s1);
254         alglib_impl::_force_malloc_failure = false;
255         passed = passed &&  alglib::get_error_flag();
256 
257         // copy constructor with working malloc succeeds
258         alglib::clear_error_flag();
259         alglib::spline1dinterpolant s5(s1);
260         passed = passed && !alglib::get_error_flag() && fabs(alglib::spline1dcalc(s5,0.5)-2.5)<1.0E-12;
261 
262         printf(fmt_str, "* ALGLIB objects", passed ? "OK" : "FAILED");
263         fflush(stdout);
264         if( !passed )
265             return 1;
266     }
267 
268     //
269     // Test ALGLIB functions
270     //
271     {
272         bool passed = true;
273         //
274         alglib::clear_error_flag();
275         alglib::spline1dinterpolant s1;
276         alglib::real_1d_array x, y;
277         x.setlength(2);
278         x[0] = 0;
279         x[1] = 1;
280         y.setlength(2);
281         y[0] = 2;
282         y[1] = alglib::fp_nan;
283         passed = passed && !alglib::get_error_flag();
284         alglib::spline1dbuildlinear(x, y, 2, s1);
285         passed = passed &&  alglib::get_error_flag();
286 
287         printf(fmt_str, "* ALGLIB functions", passed ? "OK" : "FAILED");
288         fflush(stdout);
289         if( !passed )
290             return 1;
291     }
292 
293     //
294     // Allocation counter
295     //
296 #ifdef AE_USE_ALLOC_COUNTER
297     printf("Allocation counter checked... ");
298     if( alglib_impl::_alloc_counter!=0 )
299     {
300         printf("FAILURE: alloc_counter is non-zero on end!\n");
301         return 1;
302     }
303     else
304         printf("OK\n");
305 #endif
306 
307     //
308     // Return
309     //
310     return 0;
311 }
312