xref: /freebsd/contrib/bc/tests/bcl.c (revision 175a4d10)
150696a6eSStefan Eßer /*
250696a6eSStefan Eßer  * *****************************************************************************
350696a6eSStefan Eßer  *
450696a6eSStefan Eßer  * SPDX-License-Identifier: BSD-2-Clause
550696a6eSStefan Eßer  *
6d101cdd6SStefan Eßer  * Copyright (c) 2018-2023 Gavin D. Howard and contributors.
750696a6eSStefan Eßer  *
850696a6eSStefan Eßer  * Redistribution and use in source and binary forms, with or without
950696a6eSStefan Eßer  * modification, are permitted provided that the following conditions are met:
1050696a6eSStefan Eßer  *
1150696a6eSStefan Eßer  * * Redistributions of source code must retain the above copyright notice, this
1250696a6eSStefan Eßer  *   list of conditions and the following disclaimer.
1350696a6eSStefan Eßer  *
1450696a6eSStefan Eßer  * * Redistributions in binary form must reproduce the above copyright notice,
1550696a6eSStefan Eßer  *   this list of conditions and the following disclaimer in the documentation
1650696a6eSStefan Eßer  *   and/or other materials provided with the distribution.
1750696a6eSStefan Eßer  *
1850696a6eSStefan Eßer  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1950696a6eSStefan Eßer  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2050696a6eSStefan Eßer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2150696a6eSStefan Eßer  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2250696a6eSStefan Eßer  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2350696a6eSStefan Eßer  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2450696a6eSStefan Eßer  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2550696a6eSStefan Eßer  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2650696a6eSStefan Eßer  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2750696a6eSStefan Eßer  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2850696a6eSStefan Eßer  * POSSIBILITY OF SUCH DAMAGE.
2950696a6eSStefan Eßer  *
3050696a6eSStefan Eßer  * *****************************************************************************
3150696a6eSStefan Eßer  *
3250696a6eSStefan Eßer  * Tests for bcl(3).
3350696a6eSStefan Eßer  *
3450696a6eSStefan Eßer  */
3550696a6eSStefan Eßer 
3650696a6eSStefan Eßer #include <stdlib.h>
3750696a6eSStefan Eßer #include <stdbool.h>
3850696a6eSStefan Eßer #include <string.h>
3950696a6eSStefan Eßer 
4050696a6eSStefan Eßer #include <bcl.h>
4150696a6eSStefan Eßer 
4244d4804dSStefan Eßer /**
4344d4804dSStefan Eßer  * Takes an error code and aborts if it actually is an error.
4444d4804dSStefan Eßer  * @param e  The error code.
4544d4804dSStefan Eßer  */
4678bc019dSStefan Eßer static void
err(BclError e)4778bc019dSStefan Eßer err(BclError e)
4878bc019dSStefan Eßer {
4950696a6eSStefan Eßer 	if (e != BCL_ERROR_NONE) abort();
5050696a6eSStefan Eßer }
5150696a6eSStefan Eßer 
5278bc019dSStefan Eßer int
main(void)5378bc019dSStefan Eßer main(void)
5478bc019dSStefan Eßer {
5550696a6eSStefan Eßer 	BclError e;
5650696a6eSStefan Eßer 	BclContext ctxt;
5750696a6eSStefan Eßer 	size_t scale;
58175a4d10SStefan Eßer 	BclNumber n, n2, n3, n4, n5, n6, n7;
5950696a6eSStefan Eßer 	char* res;
6050696a6eSStefan Eßer 	BclBigDig b = 0;
6150696a6eSStefan Eßer 
62d101cdd6SStefan Eßer 	e = bcl_start();
63d101cdd6SStefan Eßer 	err(e);
64d101cdd6SStefan Eßer 
6544d4804dSStefan Eßer 	// We do this twice to test the reference counting code.
6644d4804dSStefan Eßer 	e = bcl_init();
6744d4804dSStefan Eßer 	err(e);
6850696a6eSStefan Eßer 	e = bcl_init();
6950696a6eSStefan Eßer 	err(e);
7050696a6eSStefan Eßer 
7144d4804dSStefan Eßer 	// If bcl is set to abort on fatal error, that is a bug because it should
7244d4804dSStefan Eßer 	// default to off.
7350696a6eSStefan Eßer 	if (bcl_abortOnFatalError()) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
7450696a6eSStefan Eßer 
7550696a6eSStefan Eßer 	bcl_setAbortOnFatalError(true);
7650696a6eSStefan Eßer 
7744d4804dSStefan Eßer 	// Now it *should* be set.
7850696a6eSStefan Eßer 	if (!bcl_abortOnFatalError()) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
7950696a6eSStefan Eßer 
8044d4804dSStefan Eßer 	// We do this twice to test the context stack.
8150696a6eSStefan Eßer 	ctxt = bcl_ctxt_create();
8244d4804dSStefan Eßer 	bcl_pushContext(ctxt);
8344d4804dSStefan Eßer 	ctxt = bcl_ctxt_create();
8450696a6eSStefan Eßer 	bcl_pushContext(ctxt);
8550696a6eSStefan Eßer 
8644d4804dSStefan Eßer 	// Ensure that the scale is properly set.
8750696a6eSStefan Eßer 	scale = 10;
8850696a6eSStefan Eßer 	bcl_ctxt_setScale(ctxt, scale);
8950696a6eSStefan Eßer 	scale = bcl_ctxt_scale(ctxt);
9050696a6eSStefan Eßer 	if (scale != 10) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
9150696a6eSStefan Eßer 
9250696a6eSStefan Eßer 	scale = 16;
9350696a6eSStefan Eßer 	bcl_ctxt_setIbase(ctxt, scale);
9450696a6eSStefan Eßer 	scale = bcl_ctxt_ibase(ctxt);
9550696a6eSStefan Eßer 	if (scale != 16) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
9650696a6eSStefan Eßer 
9744d4804dSStefan Eßer 	// Now the obase.
9850696a6eSStefan Eßer 	bcl_ctxt_setObase(ctxt, scale);
9950696a6eSStefan Eßer 	scale = bcl_ctxt_obase(ctxt);
10050696a6eSStefan Eßer 	if (scale != 16) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
10150696a6eSStefan Eßer 
10244d4804dSStefan Eßer 	// Set the back for the tests
10350696a6eSStefan Eßer 	bcl_ctxt_setIbase(ctxt, 10);
10444d4804dSStefan Eßer 	scale = bcl_ctxt_ibase(ctxt);
10544d4804dSStefan Eßer 	if (scale != 10) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
10650696a6eSStefan Eßer 	bcl_ctxt_setObase(ctxt, 10);
10744d4804dSStefan Eßer 	scale = bcl_ctxt_obase(ctxt);
10844d4804dSStefan Eßer 	if (scale != 10) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
10950696a6eSStefan Eßer 
11044d4804dSStefan Eßer 	// Ensure that creating, duping, and copying works.
11150696a6eSStefan Eßer 	n = bcl_num_create();
11250696a6eSStefan Eßer 	n2 = bcl_dup(n);
11350696a6eSStefan Eßer 	bcl_copy(n, n2);
11450696a6eSStefan Eßer 
11544d4804dSStefan Eßer 	// Ensure that parsing works.
11650696a6eSStefan Eßer 	n3 = bcl_parse("2938");
11750696a6eSStefan Eßer 	err(bcl_err(n3));
11850696a6eSStefan Eßer 	n4 = bcl_parse("-28390.9108273");
11950696a6eSStefan Eßer 	err(bcl_err(n4));
12050696a6eSStefan Eßer 
12144d4804dSStefan Eßer 	// We also want to be sure that negatives work. This is a special case
12244d4804dSStefan Eßer 	// because bc and dc generate a negative instruction; they don't actually
12344d4804dSStefan Eßer 	// parse numbers as negative.
12450696a6eSStefan Eßer 	if (!bcl_num_neg(n4)) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
12550696a6eSStefan Eßer 
12644d4804dSStefan Eßer 	// Add them and check the result.
127175a4d10SStefan Eßer 	n5 = bcl_add_keep(n3, n4);
128175a4d10SStefan Eßer 	err(bcl_err(n5));
129175a4d10SStefan Eßer 	res = bcl_string(n5);
130175a4d10SStefan Eßer 	if (res == NULL) err(BCL_ERROR_FATAL_ALLOC_ERR);
131175a4d10SStefan Eßer 	if (strcmp(res, "-25452.9108273")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
132175a4d10SStefan Eßer 
133175a4d10SStefan Eßer 	// We want to ensure all memory gets freed because we run this under
134175a4d10SStefan Eßer 	// Valgrind.
135175a4d10SStefan Eßer 	free(res);
136175a4d10SStefan Eßer 
137175a4d10SStefan Eßer 	// Add them and check the result.
13850696a6eSStefan Eßer 	n3 = bcl_add(n3, n4);
13950696a6eSStefan Eßer 	err(bcl_err(n3));
140175a4d10SStefan Eßer 	res = bcl_string_keep(n3);
141175a4d10SStefan Eßer 	if (res == NULL) err(BCL_ERROR_FATAL_ALLOC_ERR);
14250696a6eSStefan Eßer 	if (strcmp(res, "-25452.9108273")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
14350696a6eSStefan Eßer 
14444d4804dSStefan Eßer 	// We want to ensure all memory gets freed because we run this under
14544d4804dSStefan Eßer 	// Valgrind.
14650696a6eSStefan Eßer 	free(res);
14750696a6eSStefan Eßer 
14844d4804dSStefan Eßer 	// Ensure that divmod, a special case, works.
14950696a6eSStefan Eßer 	n4 = bcl_parse("8937458902.2890347");
15050696a6eSStefan Eßer 	err(bcl_err(n4));
151175a4d10SStefan Eßer 	e = bcl_divmod_keep(n4, n3, &n5, &n6);
152175a4d10SStefan Eßer 	err(e);
153175a4d10SStefan Eßer 
154175a4d10SStefan Eßer 	res = bcl_string(n5);
155175a4d10SStefan Eßer 	if (strcmp(res, "-351137.0060159482")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
156175a4d10SStefan Eßer 	free(res);
157175a4d10SStefan Eßer 
158175a4d10SStefan Eßer 	res = bcl_string(n6);
159175a4d10SStefan Eßer 	if (strcmp(res, ".00000152374405414")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
160175a4d10SStefan Eßer 	free(res);
161175a4d10SStefan Eßer 
162175a4d10SStefan Eßer 	// Ensure that divmod, a special case, works.
163175a4d10SStefan Eßer 	n4 = bcl_parse("8937458902.2890347");
164175a4d10SStefan Eßer 	err(bcl_err(n4));
16550696a6eSStefan Eßer 	e = bcl_divmod(bcl_dup(n4), n3, &n5, &n6);
16650696a6eSStefan Eßer 	err(e);
16750696a6eSStefan Eßer 
16850696a6eSStefan Eßer 	res = bcl_string(n5);
16978bc019dSStefan Eßer 	if (strcmp(res, "-351137.0060159482")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
17050696a6eSStefan Eßer 	free(res);
17150696a6eSStefan Eßer 
17250696a6eSStefan Eßer 	res = bcl_string(n6);
17378bc019dSStefan Eßer 	if (strcmp(res, ".00000152374405414")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
17450696a6eSStefan Eßer 	free(res);
17550696a6eSStefan Eßer 
17644d4804dSStefan Eßer 	// Ensure that sqrt works. This is also a special case. The reason is
17744d4804dSStefan Eßer 	// because it is a one-argument function. Since all binary operators go
17844d4804dSStefan Eßer 	// through the same code (basically), we can test add and be done. However,
17944d4804dSStefan Eßer 	// sqrt does not, so we want to specifically test it.
18050696a6eSStefan Eßer 	n4 = bcl_sqrt(n4);
18150696a6eSStefan Eßer 	err(bcl_err(n4));
18250696a6eSStefan Eßer 
18350696a6eSStefan Eßer 	res = bcl_string(bcl_dup(n4));
18450696a6eSStefan Eßer 
18578bc019dSStefan Eßer 	if (strcmp(res, "94538.1346457028")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
18650696a6eSStefan Eßer 
18750696a6eSStefan Eßer 	free(res);
18850696a6eSStefan Eßer 
18944d4804dSStefan Eßer 	// We want to check that numbers are properly extended...
19050696a6eSStefan Eßer 	e = bcl_num_setScale(n4, 20);
19150696a6eSStefan Eßer 	err(e);
19250696a6eSStefan Eßer 
19350696a6eSStefan Eßer 	res = bcl_string(bcl_dup(n4));
19450696a6eSStefan Eßer 
19550696a6eSStefan Eßer 	if (strcmp(res, "94538.13464570280000000000"))
19650696a6eSStefan Eßer 		err(BCL_ERROR_FATAL_UNKNOWN_ERR);
19750696a6eSStefan Eßer 
19850696a6eSStefan Eßer 	free(res);
19950696a6eSStefan Eßer 
20044d4804dSStefan Eßer 	// ...and truncated.
20150696a6eSStefan Eßer 	e = bcl_num_setScale(n4, 0);
20250696a6eSStefan Eßer 	err(e);
20350696a6eSStefan Eßer 
20450696a6eSStefan Eßer 	res = bcl_string(bcl_dup(n4));
20550696a6eSStefan Eßer 
20678bc019dSStefan Eßer 	if (strcmp(res, "94538")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
20750696a6eSStefan Eßer 
20850696a6eSStefan Eßer 	free(res);
20950696a6eSStefan Eßer 
21044d4804dSStefan Eßer 	// Check conversion to hardware integers...
21150696a6eSStefan Eßer 	e = bcl_bigdig(n4, &b);
21250696a6eSStefan Eßer 	err(e);
21350696a6eSStefan Eßer 
21450696a6eSStefan Eßer 	if (b != 94538) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
21550696a6eSStefan Eßer 
21644d4804dSStefan Eßer 	// ...and back.
21750696a6eSStefan Eßer 	n4 = bcl_bigdig2num(b);
21850696a6eSStefan Eßer 	err(bcl_err(n4));
21950696a6eSStefan Eßer 
22050696a6eSStefan Eßer 	res = bcl_string(bcl_dup(n4));
22150696a6eSStefan Eßer 
22278bc019dSStefan Eßer 	if (strcmp(res, "94538")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
22350696a6eSStefan Eßer 
22450696a6eSStefan Eßer 	free(res);
22550696a6eSStefan Eßer 
22644d4804dSStefan Eßer 	// Check rand.
22750696a6eSStefan Eßer 	n4 = bcl_frand(10);
22850696a6eSStefan Eßer 	err(bcl_err(n4));
22950696a6eSStefan Eßer 
23044d4804dSStefan Eßer 	// Check that no asserts fire in shifting.
23150696a6eSStefan Eßer 	n4 = bcl_lshift(n4, bcl_bigdig2num(10));
23250696a6eSStefan Eßer 	err(bcl_err(n4));
23350696a6eSStefan Eßer 
23444d4804dSStefan Eßer 	// Repeat.
23550696a6eSStefan Eßer 	n3 = bcl_irand(n4);
23650696a6eSStefan Eßer 	err(bcl_err(n3));
23750696a6eSStefan Eßer 
23844d4804dSStefan Eßer 	// Repeat.
239175a4d10SStefan Eßer 	n2 = bcl_ifrand_keep(n3, 10);
240175a4d10SStefan Eßer 	err(bcl_err(n2));
241175a4d10SStefan Eßer 
242175a4d10SStefan Eßer 	// Repeat.
24350696a6eSStefan Eßer 	n2 = bcl_ifrand(bcl_dup(n3), 10);
24450696a6eSStefan Eßer 	err(bcl_err(n2));
24550696a6eSStefan Eßer 
24644d4804dSStefan Eßer 	// Still checking asserts.
247175a4d10SStefan Eßer 	e = bcl_rand_seedWithNum_keep(n3);
248175a4d10SStefan Eßer 	err(e);
249175a4d10SStefan Eßer 
250175a4d10SStefan Eßer 	// Still checking asserts.
25150696a6eSStefan Eßer 	e = bcl_rand_seedWithNum(n3);
25250696a6eSStefan Eßer 	err(e);
25350696a6eSStefan Eßer 
25444d4804dSStefan Eßer 	// Still checking asserts.
25550696a6eSStefan Eßer 	n4 = bcl_rand_seed2num();
25650696a6eSStefan Eßer 	err(bcl_err(n4));
25750696a6eSStefan Eßer 
25844d4804dSStefan Eßer 	// Finally, check modexp, yet another special case.
25950696a6eSStefan Eßer 	n5 = bcl_parse("10");
26050696a6eSStefan Eßer 	err(bcl_err(n5));
26150696a6eSStefan Eßer 
262175a4d10SStefan Eßer 	n6 = bcl_modexp_keep(n5, n5, n5);
26350696a6eSStefan Eßer 	err(bcl_err(n6));
26450696a6eSStefan Eßer 
265175a4d10SStefan Eßer 	n7 = bcl_modexp(bcl_dup(n5), bcl_dup(n5), bcl_dup(n5));
266175a4d10SStefan Eßer 	err(bcl_err(n7));
267175a4d10SStefan Eßer 
26844d4804dSStefan Eßer 	// Clean up.
26950696a6eSStefan Eßer 	bcl_num_free(n);
27050696a6eSStefan Eßer 
271d43fa8efSStefan Eßer 	// Test leading zeroes.
27278bc019dSStefan Eßer 	if (bcl_leadingZeroes()) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
273d43fa8efSStefan Eßer 
274d43fa8efSStefan Eßer 	n = bcl_parse("0.01");
275d43fa8efSStefan Eßer 	err(bcl_err(n));
276d43fa8efSStefan Eßer 
277d43fa8efSStefan Eßer 	n2 = bcl_parse("-0.01");
278d43fa8efSStefan Eßer 	err(bcl_err(n2));
279d43fa8efSStefan Eßer 
280d43fa8efSStefan Eßer 	n3 = bcl_parse("1.01");
281d43fa8efSStefan Eßer 	err(bcl_err(n3));
282d43fa8efSStefan Eßer 
283d43fa8efSStefan Eßer 	n4 = bcl_parse("-1.01");
284d43fa8efSStefan Eßer 	err(bcl_err(n4));
285d43fa8efSStefan Eßer 
286175a4d10SStefan Eßer 	res = bcl_string_keep(n);
287175a4d10SStefan Eßer 	if (strcmp(res, ".01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
288175a4d10SStefan Eßer 
289175a4d10SStefan Eßer 	free(res);
290175a4d10SStefan Eßer 
291d43fa8efSStefan Eßer 	res = bcl_string(bcl_dup(n));
29278bc019dSStefan Eßer 	if (strcmp(res, ".01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
293d43fa8efSStefan Eßer 
294d43fa8efSStefan Eßer 	free(res);
295d43fa8efSStefan Eßer 
296d43fa8efSStefan Eßer 	res = bcl_string(bcl_dup(n2));
29778bc019dSStefan Eßer 	if (strcmp(res, "-.01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
298d43fa8efSStefan Eßer 
299d43fa8efSStefan Eßer 	free(res);
300d43fa8efSStefan Eßer 
301d43fa8efSStefan Eßer 	res = bcl_string(bcl_dup(n3));
30278bc019dSStefan Eßer 	if (strcmp(res, "1.01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
303d43fa8efSStefan Eßer 
304d43fa8efSStefan Eßer 	free(res);
305d43fa8efSStefan Eßer 
306d43fa8efSStefan Eßer 	res = bcl_string(bcl_dup(n4));
30778bc019dSStefan Eßer 	if (strcmp(res, "-1.01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
308d43fa8efSStefan Eßer 
309d43fa8efSStefan Eßer 	free(res);
310d43fa8efSStefan Eßer 
311d43fa8efSStefan Eßer 	bcl_setLeadingZeroes(true);
312d43fa8efSStefan Eßer 
31378bc019dSStefan Eßer 	if (!bcl_leadingZeroes()) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
314d43fa8efSStefan Eßer 
315d43fa8efSStefan Eßer 	res = bcl_string(bcl_dup(n));
31678bc019dSStefan Eßer 	if (strcmp(res, "0.01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
317d43fa8efSStefan Eßer 
318d43fa8efSStefan Eßer 	free(res);
319d43fa8efSStefan Eßer 
320d43fa8efSStefan Eßer 	res = bcl_string(bcl_dup(n2));
32178bc019dSStefan Eßer 	if (strcmp(res, "-0.01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
322d43fa8efSStefan Eßer 
323d43fa8efSStefan Eßer 	free(res);
324d43fa8efSStefan Eßer 
325d43fa8efSStefan Eßer 	res = bcl_string(bcl_dup(n3));
32678bc019dSStefan Eßer 	if (strcmp(res, "1.01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
327d43fa8efSStefan Eßer 
328d43fa8efSStefan Eßer 	free(res);
329d43fa8efSStefan Eßer 
330d43fa8efSStefan Eßer 	res = bcl_string(bcl_dup(n4));
33178bc019dSStefan Eßer 	if (strcmp(res, "-1.01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
332d43fa8efSStefan Eßer 
333d43fa8efSStefan Eßer 	free(res);
334d43fa8efSStefan Eßer 
335d43fa8efSStefan Eßer 	bcl_setLeadingZeroes(false);
336d43fa8efSStefan Eßer 
33778bc019dSStefan Eßer 	if (bcl_leadingZeroes()) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
338d43fa8efSStefan Eßer 
339d43fa8efSStefan Eßer 	res = bcl_string(n);
34078bc019dSStefan Eßer 	if (strcmp(res, ".01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
341d43fa8efSStefan Eßer 
342d43fa8efSStefan Eßer 	free(res);
343d43fa8efSStefan Eßer 
344d43fa8efSStefan Eßer 	res = bcl_string(n2);
34578bc019dSStefan Eßer 	if (strcmp(res, "-.01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
346d43fa8efSStefan Eßer 
347d43fa8efSStefan Eßer 	free(res);
348d43fa8efSStefan Eßer 
349d43fa8efSStefan Eßer 	res = bcl_string(n3);
35078bc019dSStefan Eßer 	if (strcmp(res, "1.01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
351d43fa8efSStefan Eßer 
352d43fa8efSStefan Eßer 	free(res);
353d43fa8efSStefan Eßer 
354d43fa8efSStefan Eßer 	res = bcl_string(n4);
35578bc019dSStefan Eßer 	if (strcmp(res, "-1.01")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
356d43fa8efSStefan Eßer 
357d43fa8efSStefan Eßer 	free(res);
358d43fa8efSStefan Eßer 
35950696a6eSStefan Eßer 	bcl_ctxt_freeNums(ctxt);
36050696a6eSStefan Eßer 
36150696a6eSStefan Eßer 	bcl_gc();
36250696a6eSStefan Eßer 
36344d4804dSStefan Eßer 	// We need to pop both contexts and free them.
36450696a6eSStefan Eßer 	bcl_popContext();
36550696a6eSStefan Eßer 
36650696a6eSStefan Eßer 	bcl_ctxt_free(ctxt);
36750696a6eSStefan Eßer 
36850696a6eSStefan Eßer 	ctxt = bcl_context();
36950696a6eSStefan Eßer 
37050696a6eSStefan Eßer 	bcl_popContext();
37150696a6eSStefan Eßer 
37250696a6eSStefan Eßer 	bcl_ctxt_free(ctxt);
37350696a6eSStefan Eßer 
37444d4804dSStefan Eßer 	// Decrement the reference counter to ensure all is freed.
37550696a6eSStefan Eßer 	bcl_free();
37650696a6eSStefan Eßer 
37750696a6eSStefan Eßer 	bcl_free();
37850696a6eSStefan Eßer 
379d101cdd6SStefan Eßer 	bcl_end();
380d101cdd6SStefan Eßer 
38150696a6eSStefan Eßer 	return 0;
38250696a6eSStefan Eßer }
383