xref: /aosp_15_r20/external/bc/src/lang.c (revision 5a6e848804d15c18a0125914844ee4eb0bda4fcf)
1*5a6e8488SAndroid Build Coastguard Worker /*
2*5a6e8488SAndroid Build Coastguard Worker  * *****************************************************************************
3*5a6e8488SAndroid Build Coastguard Worker  *
4*5a6e8488SAndroid Build Coastguard Worker  * SPDX-License-Identifier: BSD-2-Clause
5*5a6e8488SAndroid Build Coastguard Worker  *
6*5a6e8488SAndroid Build Coastguard Worker  * Copyright (c) 2018-2024 Gavin D. Howard and contributors.
7*5a6e8488SAndroid Build Coastguard Worker  *
8*5a6e8488SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
9*5a6e8488SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions are met:
10*5a6e8488SAndroid Build Coastguard Worker  *
11*5a6e8488SAndroid Build Coastguard Worker  * * Redistributions of source code must retain the above copyright notice, this
12*5a6e8488SAndroid Build Coastguard Worker  *   list of conditions and the following disclaimer.
13*5a6e8488SAndroid Build Coastguard Worker  *
14*5a6e8488SAndroid Build Coastguard Worker  * * Redistributions in binary form must reproduce the above copyright notice,
15*5a6e8488SAndroid Build Coastguard Worker  *   this list of conditions and the following disclaimer in the documentation
16*5a6e8488SAndroid Build Coastguard Worker  *   and/or other materials provided with the distribution.
17*5a6e8488SAndroid Build Coastguard Worker  *
18*5a6e8488SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19*5a6e8488SAndroid Build Coastguard Worker  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*5a6e8488SAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*5a6e8488SAndroid Build Coastguard Worker  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22*5a6e8488SAndroid Build Coastguard Worker  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*5a6e8488SAndroid Build Coastguard Worker  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*5a6e8488SAndroid Build Coastguard Worker  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25*5a6e8488SAndroid Build Coastguard Worker  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26*5a6e8488SAndroid Build Coastguard Worker  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27*5a6e8488SAndroid Build Coastguard Worker  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28*5a6e8488SAndroid Build Coastguard Worker  * POSSIBILITY OF SUCH DAMAGE.
29*5a6e8488SAndroid Build Coastguard Worker  *
30*5a6e8488SAndroid Build Coastguard Worker  * *****************************************************************************
31*5a6e8488SAndroid Build Coastguard Worker  *
32*5a6e8488SAndroid Build Coastguard Worker  * Code to manipulate data structures in programs.
33*5a6e8488SAndroid Build Coastguard Worker  *
34*5a6e8488SAndroid Build Coastguard Worker  */
35*5a6e8488SAndroid Build Coastguard Worker 
36*5a6e8488SAndroid Build Coastguard Worker #include <assert.h>
37*5a6e8488SAndroid Build Coastguard Worker #include <stdlib.h>
38*5a6e8488SAndroid Build Coastguard Worker #include <string.h>
39*5a6e8488SAndroid Build Coastguard Worker 
40*5a6e8488SAndroid Build Coastguard Worker #include <lang.h>
41*5a6e8488SAndroid Build Coastguard Worker #include <program.h>
42*5a6e8488SAndroid Build Coastguard Worker #include <vm.h>
43*5a6e8488SAndroid Build Coastguard Worker 
44*5a6e8488SAndroid Build Coastguard Worker void
bc_const_free(void * constant)45*5a6e8488SAndroid Build Coastguard Worker bc_const_free(void* constant)
46*5a6e8488SAndroid Build Coastguard Worker {
47*5a6e8488SAndroid Build Coastguard Worker 	BcConst* c = constant;
48*5a6e8488SAndroid Build Coastguard Worker 
49*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
50*5a6e8488SAndroid Build Coastguard Worker 
51*5a6e8488SAndroid Build Coastguard Worker 	assert(c->val != NULL);
52*5a6e8488SAndroid Build Coastguard Worker 
53*5a6e8488SAndroid Build Coastguard Worker 	bc_num_free(&c->num);
54*5a6e8488SAndroid Build Coastguard Worker }
55*5a6e8488SAndroid Build Coastguard Worker 
56*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
57*5a6e8488SAndroid Build Coastguard Worker void
bc_func_insert(BcFunc * f,BcProgram * p,char * name,BcType type,size_t line)58*5a6e8488SAndroid Build Coastguard Worker bc_func_insert(BcFunc* f, BcProgram* p, char* name, BcType type, size_t line)
59*5a6e8488SAndroid Build Coastguard Worker {
60*5a6e8488SAndroid Build Coastguard Worker 	BcAuto a;
61*5a6e8488SAndroid Build Coastguard Worker 	size_t i, idx;
62*5a6e8488SAndroid Build Coastguard Worker 
63*5a6e8488SAndroid Build Coastguard Worker 	// The function must *always* be valid.
64*5a6e8488SAndroid Build Coastguard Worker 	assert(f != NULL);
65*5a6e8488SAndroid Build Coastguard Worker 
66*5a6e8488SAndroid Build Coastguard Worker 	// Get the index of the variable.
67*5a6e8488SAndroid Build Coastguard Worker 	idx = bc_program_search(p, name, type == BC_TYPE_VAR);
68*5a6e8488SAndroid Build Coastguard Worker 
69*5a6e8488SAndroid Build Coastguard Worker 	// Search through all of the other autos/parameters.
70*5a6e8488SAndroid Build Coastguard Worker 	for (i = 0; i < f->autos.len; ++i)
71*5a6e8488SAndroid Build Coastguard Worker 	{
72*5a6e8488SAndroid Build Coastguard Worker 		// Get the auto.
73*5a6e8488SAndroid Build Coastguard Worker 		BcAuto* aptr = bc_vec_item(&f->autos, i);
74*5a6e8488SAndroid Build Coastguard Worker 
75*5a6e8488SAndroid Build Coastguard Worker 		// If they match, barf.
76*5a6e8488SAndroid Build Coastguard Worker 		if (BC_ERR(idx == aptr->idx && type == aptr->type))
77*5a6e8488SAndroid Build Coastguard Worker 		{
78*5a6e8488SAndroid Build Coastguard Worker 			const char* array = type == BC_TYPE_ARRAY ? "[]" : "";
79*5a6e8488SAndroid Build Coastguard Worker 
80*5a6e8488SAndroid Build Coastguard Worker 			bc_error(BC_ERR_PARSE_DUP_LOCAL, line, name, array);
81*5a6e8488SAndroid Build Coastguard Worker 		}
82*5a6e8488SAndroid Build Coastguard Worker 	}
83*5a6e8488SAndroid Build Coastguard Worker 
84*5a6e8488SAndroid Build Coastguard Worker 	// Set the auto.
85*5a6e8488SAndroid Build Coastguard Worker 	a.idx = idx;
86*5a6e8488SAndroid Build Coastguard Worker 	a.type = type;
87*5a6e8488SAndroid Build Coastguard Worker 
88*5a6e8488SAndroid Build Coastguard Worker 	// Push it.
89*5a6e8488SAndroid Build Coastguard Worker 	bc_vec_push(&f->autos, &a);
90*5a6e8488SAndroid Build Coastguard Worker }
91*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
92*5a6e8488SAndroid Build Coastguard Worker 
93*5a6e8488SAndroid Build Coastguard Worker void
bc_func_init(BcFunc * f,const char * name)94*5a6e8488SAndroid Build Coastguard Worker bc_func_init(BcFunc* f, const char* name)
95*5a6e8488SAndroid Build Coastguard Worker {
96*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
97*5a6e8488SAndroid Build Coastguard Worker 
98*5a6e8488SAndroid Build Coastguard Worker 	assert(f != NULL && name != NULL);
99*5a6e8488SAndroid Build Coastguard Worker 
100*5a6e8488SAndroid Build Coastguard Worker 	bc_vec_init(&f->code, sizeof(uchar), BC_DTOR_NONE);
101*5a6e8488SAndroid Build Coastguard Worker 
102*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
103*5a6e8488SAndroid Build Coastguard Worker 
104*5a6e8488SAndroid Build Coastguard Worker 	// Only bc needs these things.
105*5a6e8488SAndroid Build Coastguard Worker 	if (BC_IS_BC)
106*5a6e8488SAndroid Build Coastguard Worker 	{
107*5a6e8488SAndroid Build Coastguard Worker 		bc_vec_init(&f->autos, sizeof(BcAuto), BC_DTOR_NONE);
108*5a6e8488SAndroid Build Coastguard Worker 		bc_vec_init(&f->labels, sizeof(size_t), BC_DTOR_NONE);
109*5a6e8488SAndroid Build Coastguard Worker 
110*5a6e8488SAndroid Build Coastguard Worker 		f->nparams = 0;
111*5a6e8488SAndroid Build Coastguard Worker 		f->voidfn = false;
112*5a6e8488SAndroid Build Coastguard Worker 	}
113*5a6e8488SAndroid Build Coastguard Worker 
114*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
115*5a6e8488SAndroid Build Coastguard Worker 
116*5a6e8488SAndroid Build Coastguard Worker 	f->name = name;
117*5a6e8488SAndroid Build Coastguard Worker }
118*5a6e8488SAndroid Build Coastguard Worker 
119*5a6e8488SAndroid Build Coastguard Worker void
bc_func_reset(BcFunc * f)120*5a6e8488SAndroid Build Coastguard Worker bc_func_reset(BcFunc* f)
121*5a6e8488SAndroid Build Coastguard Worker {
122*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
123*5a6e8488SAndroid Build Coastguard Worker 	assert(f != NULL);
124*5a6e8488SAndroid Build Coastguard Worker 
125*5a6e8488SAndroid Build Coastguard Worker 	bc_vec_popAll(&f->code);
126*5a6e8488SAndroid Build Coastguard Worker 
127*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
128*5a6e8488SAndroid Build Coastguard Worker 	if (BC_IS_BC)
129*5a6e8488SAndroid Build Coastguard Worker 	{
130*5a6e8488SAndroid Build Coastguard Worker 		bc_vec_popAll(&f->autos);
131*5a6e8488SAndroid Build Coastguard Worker 		bc_vec_popAll(&f->labels);
132*5a6e8488SAndroid Build Coastguard Worker 
133*5a6e8488SAndroid Build Coastguard Worker 		f->nparams = 0;
134*5a6e8488SAndroid Build Coastguard Worker 		f->voidfn = false;
135*5a6e8488SAndroid Build Coastguard Worker 	}
136*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
137*5a6e8488SAndroid Build Coastguard Worker }
138*5a6e8488SAndroid Build Coastguard Worker 
139*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG || BC_ENABLE_MEMCHECK
140*5a6e8488SAndroid Build Coastguard Worker void
bc_func_free(void * func)141*5a6e8488SAndroid Build Coastguard Worker bc_func_free(void* func)
142*5a6e8488SAndroid Build Coastguard Worker {
143*5a6e8488SAndroid Build Coastguard Worker 	BcFunc* f = (BcFunc*) func;
144*5a6e8488SAndroid Build Coastguard Worker 
145*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
146*5a6e8488SAndroid Build Coastguard Worker 	assert(f != NULL);
147*5a6e8488SAndroid Build Coastguard Worker 
148*5a6e8488SAndroid Build Coastguard Worker 	bc_vec_free(&f->code);
149*5a6e8488SAndroid Build Coastguard Worker 
150*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
151*5a6e8488SAndroid Build Coastguard Worker 	if (BC_IS_BC)
152*5a6e8488SAndroid Build Coastguard Worker 	{
153*5a6e8488SAndroid Build Coastguard Worker 		bc_vec_free(&f->autos);
154*5a6e8488SAndroid Build Coastguard Worker 		bc_vec_free(&f->labels);
155*5a6e8488SAndroid Build Coastguard Worker 	}
156*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
157*5a6e8488SAndroid Build Coastguard Worker }
158*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG || BC_ENABLE_MEMCHECK
159*5a6e8488SAndroid Build Coastguard Worker 
160*5a6e8488SAndroid Build Coastguard Worker void
bc_array_init(BcVec * a,bool nums)161*5a6e8488SAndroid Build Coastguard Worker bc_array_init(BcVec* a, bool nums)
162*5a6e8488SAndroid Build Coastguard Worker {
163*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
164*5a6e8488SAndroid Build Coastguard Worker 
165*5a6e8488SAndroid Build Coastguard Worker 	// Set the proper vector.
166*5a6e8488SAndroid Build Coastguard Worker 	if (nums) bc_vec_init(a, sizeof(BcNum), BC_DTOR_NUM);
167*5a6e8488SAndroid Build Coastguard Worker 	else bc_vec_init(a, sizeof(BcVec), BC_DTOR_VEC);
168*5a6e8488SAndroid Build Coastguard Worker 
169*5a6e8488SAndroid Build Coastguard Worker 	// We always want at least one item in the array.
170*5a6e8488SAndroid Build Coastguard Worker 	bc_array_expand(a, 1);
171*5a6e8488SAndroid Build Coastguard Worker }
172*5a6e8488SAndroid Build Coastguard Worker 
173*5a6e8488SAndroid Build Coastguard Worker void
bc_array_copy(BcVec * d,const BcVec * s)174*5a6e8488SAndroid Build Coastguard Worker bc_array_copy(BcVec* d, const BcVec* s)
175*5a6e8488SAndroid Build Coastguard Worker {
176*5a6e8488SAndroid Build Coastguard Worker 	size_t i;
177*5a6e8488SAndroid Build Coastguard Worker 
178*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
179*5a6e8488SAndroid Build Coastguard Worker 
180*5a6e8488SAndroid Build Coastguard Worker 	assert(d != NULL && s != NULL);
181*5a6e8488SAndroid Build Coastguard Worker 	assert(d != s && d->size == s->size && d->dtor == s->dtor);
182*5a6e8488SAndroid Build Coastguard Worker 
183*5a6e8488SAndroid Build Coastguard Worker 	// Make sure to destroy everything currently in d. This will put a lot of
184*5a6e8488SAndroid Build Coastguard Worker 	// temps on the reuse list, so allocating later is not going to be as
185*5a6e8488SAndroid Build Coastguard Worker 	// expensive as it seems. Also, it makes it easier to copy numbers that are
186*5a6e8488SAndroid Build Coastguard Worker 	// strings.
187*5a6e8488SAndroid Build Coastguard Worker 	bc_vec_popAll(d);
188*5a6e8488SAndroid Build Coastguard Worker 
189*5a6e8488SAndroid Build Coastguard Worker 	// Preexpand.
190*5a6e8488SAndroid Build Coastguard Worker 	bc_vec_expand(d, s->cap);
191*5a6e8488SAndroid Build Coastguard Worker 	d->len = s->len;
192*5a6e8488SAndroid Build Coastguard Worker 
193*5a6e8488SAndroid Build Coastguard Worker 	for (i = 0; i < s->len; ++i)
194*5a6e8488SAndroid Build Coastguard Worker 	{
195*5a6e8488SAndroid Build Coastguard Worker 		BcNum* dnum;
196*5a6e8488SAndroid Build Coastguard Worker 		BcNum* snum;
197*5a6e8488SAndroid Build Coastguard Worker 
198*5a6e8488SAndroid Build Coastguard Worker 		dnum = bc_vec_item(d, i);
199*5a6e8488SAndroid Build Coastguard Worker 		snum = bc_vec_item(s, i);
200*5a6e8488SAndroid Build Coastguard Worker 
201*5a6e8488SAndroid Build Coastguard Worker 		// We have to create a copy of the number as well.
202*5a6e8488SAndroid Build Coastguard Worker 		if (BC_PROG_STR(snum))
203*5a6e8488SAndroid Build Coastguard Worker 		{
204*5a6e8488SAndroid Build Coastguard Worker 			// NOLINTNEXTLINE
205*5a6e8488SAndroid Build Coastguard Worker 			memcpy(dnum, snum, sizeof(BcNum));
206*5a6e8488SAndroid Build Coastguard Worker 		}
207*5a6e8488SAndroid Build Coastguard Worker 		else bc_num_createCopy(dnum, snum);
208*5a6e8488SAndroid Build Coastguard Worker 	}
209*5a6e8488SAndroid Build Coastguard Worker }
210*5a6e8488SAndroid Build Coastguard Worker 
211*5a6e8488SAndroid Build Coastguard Worker void
bc_array_expand(BcVec * a,size_t len)212*5a6e8488SAndroid Build Coastguard Worker bc_array_expand(BcVec* a, size_t len)
213*5a6e8488SAndroid Build Coastguard Worker {
214*5a6e8488SAndroid Build Coastguard Worker 	assert(a != NULL);
215*5a6e8488SAndroid Build Coastguard Worker 
216*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
217*5a6e8488SAndroid Build Coastguard Worker 
218*5a6e8488SAndroid Build Coastguard Worker 	bc_vec_expand(a, len);
219*5a6e8488SAndroid Build Coastguard Worker 
220*5a6e8488SAndroid Build Coastguard Worker 	// If this is true, then we have a num array.
221*5a6e8488SAndroid Build Coastguard Worker 	if (a->size == sizeof(BcNum) && a->dtor == BC_DTOR_NUM)
222*5a6e8488SAndroid Build Coastguard Worker 	{
223*5a6e8488SAndroid Build Coastguard Worker 		// Initialize numbers until we reach the target.
224*5a6e8488SAndroid Build Coastguard Worker 		while (len > a->len)
225*5a6e8488SAndroid Build Coastguard Worker 		{
226*5a6e8488SAndroid Build Coastguard Worker 			BcNum* n = bc_vec_pushEmpty(a);
227*5a6e8488SAndroid Build Coastguard Worker 			bc_num_init(n, BC_NUM_DEF_SIZE);
228*5a6e8488SAndroid Build Coastguard Worker 		}
229*5a6e8488SAndroid Build Coastguard Worker 	}
230*5a6e8488SAndroid Build Coastguard Worker 	else
231*5a6e8488SAndroid Build Coastguard Worker 	{
232*5a6e8488SAndroid Build Coastguard Worker 		assert(a->size == sizeof(BcVec) && a->dtor == BC_DTOR_VEC);
233*5a6e8488SAndroid Build Coastguard Worker 
234*5a6e8488SAndroid Build Coastguard Worker 		// Recursively initialize arrays until we reach the target. Having the
235*5a6e8488SAndroid Build Coastguard Worker 		// second argument of bc_array_init() be true will activate the base
236*5a6e8488SAndroid Build Coastguard Worker 		// case, so we're safe.
237*5a6e8488SAndroid Build Coastguard Worker 		while (len > a->len)
238*5a6e8488SAndroid Build Coastguard Worker 		{
239*5a6e8488SAndroid Build Coastguard Worker 			BcVec* v = bc_vec_pushEmpty(a);
240*5a6e8488SAndroid Build Coastguard Worker 			bc_array_init(v, true);
241*5a6e8488SAndroid Build Coastguard Worker 		}
242*5a6e8488SAndroid Build Coastguard Worker 	}
243*5a6e8488SAndroid Build Coastguard Worker }
244*5a6e8488SAndroid Build Coastguard Worker 
245*5a6e8488SAndroid Build Coastguard Worker void
bc_result_clear(BcResult * r)246*5a6e8488SAndroid Build Coastguard Worker bc_result_clear(BcResult* r)
247*5a6e8488SAndroid Build Coastguard Worker {
248*5a6e8488SAndroid Build Coastguard Worker 	r->t = BC_RESULT_TEMP;
249*5a6e8488SAndroid Build Coastguard Worker 	bc_num_clear(&r->d.n);
250*5a6e8488SAndroid Build Coastguard Worker }
251*5a6e8488SAndroid Build Coastguard Worker 
252*5a6e8488SAndroid Build Coastguard Worker #if DC_ENABLED
253*5a6e8488SAndroid Build Coastguard Worker void
bc_result_copy(BcResult * d,BcResult * src)254*5a6e8488SAndroid Build Coastguard Worker bc_result_copy(BcResult* d, BcResult* src)
255*5a6e8488SAndroid Build Coastguard Worker {
256*5a6e8488SAndroid Build Coastguard Worker 	assert(d != NULL && src != NULL);
257*5a6e8488SAndroid Build Coastguard Worker 
258*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
259*5a6e8488SAndroid Build Coastguard Worker 
260*5a6e8488SAndroid Build Coastguard Worker 	// d is assumed to not be valid yet.
261*5a6e8488SAndroid Build Coastguard Worker 	d->t = src->t;
262*5a6e8488SAndroid Build Coastguard Worker 
263*5a6e8488SAndroid Build Coastguard Worker 	// Yes, it depends on what type.
264*5a6e8488SAndroid Build Coastguard Worker 	switch (d->t)
265*5a6e8488SAndroid Build Coastguard Worker 	{
266*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_TEMP:
267*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_IBASE:
268*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_SCALE:
269*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_OBASE:
270*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
271*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_SEED:
272*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
273*5a6e8488SAndroid Build Coastguard Worker 		{
274*5a6e8488SAndroid Build Coastguard Worker 			bc_num_createCopy(&d->d.n, &src->d.n);
275*5a6e8488SAndroid Build Coastguard Worker 			break;
276*5a6e8488SAndroid Build Coastguard Worker 		}
277*5a6e8488SAndroid Build Coastguard Worker 
278*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_VAR:
279*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_ARRAY:
280*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_ARRAY_ELEM:
281*5a6e8488SAndroid Build Coastguard Worker 		{
282*5a6e8488SAndroid Build Coastguard Worker 			// NOLINTNEXTLINE
283*5a6e8488SAndroid Build Coastguard Worker 			memcpy(&d->d.loc, &src->d.loc, sizeof(BcLoc));
284*5a6e8488SAndroid Build Coastguard Worker 			break;
285*5a6e8488SAndroid Build Coastguard Worker 		}
286*5a6e8488SAndroid Build Coastguard Worker 
287*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_STR:
288*5a6e8488SAndroid Build Coastguard Worker 		{
289*5a6e8488SAndroid Build Coastguard Worker 			// NOLINTNEXTLINE
290*5a6e8488SAndroid Build Coastguard Worker 			memcpy(&d->d.n, &src->d.n, sizeof(BcNum));
291*5a6e8488SAndroid Build Coastguard Worker 			break;
292*5a6e8488SAndroid Build Coastguard Worker 		}
293*5a6e8488SAndroid Build Coastguard Worker 
294*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_ZERO:
295*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_ONE:
296*5a6e8488SAndroid Build Coastguard Worker 		{
297*5a6e8488SAndroid Build Coastguard Worker 			// Do nothing.
298*5a6e8488SAndroid Build Coastguard Worker 			break;
299*5a6e8488SAndroid Build Coastguard Worker 		}
300*5a6e8488SAndroid Build Coastguard Worker 
301*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
302*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_VOID:
303*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_LAST:
304*5a6e8488SAndroid Build Coastguard Worker 		{
305*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG
306*5a6e8488SAndroid Build Coastguard Worker 			// We should *never* try copying either of these.
307*5a6e8488SAndroid Build Coastguard Worker 			abort();
308*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG
309*5a6e8488SAndroid Build Coastguard Worker 		}
310*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
311*5a6e8488SAndroid Build Coastguard Worker 	}
312*5a6e8488SAndroid Build Coastguard Worker }
313*5a6e8488SAndroid Build Coastguard Worker #endif // DC_ENABLED
314*5a6e8488SAndroid Build Coastguard Worker 
315*5a6e8488SAndroid Build Coastguard Worker void
bc_result_free(void * result)316*5a6e8488SAndroid Build Coastguard Worker bc_result_free(void* result)
317*5a6e8488SAndroid Build Coastguard Worker {
318*5a6e8488SAndroid Build Coastguard Worker 	BcResult* r = (BcResult*) result;
319*5a6e8488SAndroid Build Coastguard Worker 
320*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
321*5a6e8488SAndroid Build Coastguard Worker 
322*5a6e8488SAndroid Build Coastguard Worker 	assert(r != NULL);
323*5a6e8488SAndroid Build Coastguard Worker 
324*5a6e8488SAndroid Build Coastguard Worker 	switch (r->t)
325*5a6e8488SAndroid Build Coastguard Worker 	{
326*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_TEMP:
327*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_IBASE:
328*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_SCALE:
329*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_OBASE:
330*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
331*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_SEED:
332*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
333*5a6e8488SAndroid Build Coastguard Worker 		{
334*5a6e8488SAndroid Build Coastguard Worker 			bc_num_free(&r->d.n);
335*5a6e8488SAndroid Build Coastguard Worker 			break;
336*5a6e8488SAndroid Build Coastguard Worker 		}
337*5a6e8488SAndroid Build Coastguard Worker 
338*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_VAR:
339*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_ARRAY:
340*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_ARRAY_ELEM:
341*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_STR:
342*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_ZERO:
343*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_ONE:
344*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
345*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_VOID:
346*5a6e8488SAndroid Build Coastguard Worker 		case BC_RESULT_LAST:
347*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
348*5a6e8488SAndroid Build Coastguard Worker 		{
349*5a6e8488SAndroid Build Coastguard Worker 			// Do nothing.
350*5a6e8488SAndroid Build Coastguard Worker 			break;
351*5a6e8488SAndroid Build Coastguard Worker 		}
352*5a6e8488SAndroid Build Coastguard Worker 	}
353*5a6e8488SAndroid Build Coastguard Worker }
354