xref: /aosp_15_r20/external/bc/src/args.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 for processing command-line arguments.
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 <ctype.h>
38*5a6e8488SAndroid Build Coastguard Worker #include <stdbool.h>
39*5a6e8488SAndroid Build Coastguard Worker #include <stdlib.h>
40*5a6e8488SAndroid Build Coastguard Worker #include <string.h>
41*5a6e8488SAndroid Build Coastguard Worker 
42*5a6e8488SAndroid Build Coastguard Worker #ifndef _WIN32
43*5a6e8488SAndroid Build Coastguard Worker #include <unistd.h>
44*5a6e8488SAndroid Build Coastguard Worker #endif // _WIN32
45*5a6e8488SAndroid Build Coastguard Worker 
46*5a6e8488SAndroid Build Coastguard Worker #include <vector.h>
47*5a6e8488SAndroid Build Coastguard Worker #include <read.h>
48*5a6e8488SAndroid Build Coastguard Worker #include <args.h>
49*5a6e8488SAndroid Build Coastguard Worker #include <opt.h>
50*5a6e8488SAndroid Build Coastguard Worker #include <num.h>
51*5a6e8488SAndroid Build Coastguard Worker #include <vm.h>
52*5a6e8488SAndroid Build Coastguard Worker 
53*5a6e8488SAndroid Build Coastguard Worker /**
54*5a6e8488SAndroid Build Coastguard Worker  * Adds @a str to the list of expressions to execute later.
55*5a6e8488SAndroid Build Coastguard Worker  * @param str  The string to add to the list of expressions.
56*5a6e8488SAndroid Build Coastguard Worker  */
57*5a6e8488SAndroid Build Coastguard Worker static void
bc_args_exprs(const char * str)58*5a6e8488SAndroid Build Coastguard Worker bc_args_exprs(const char* str)
59*5a6e8488SAndroid Build Coastguard Worker {
60*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
61*5a6e8488SAndroid Build Coastguard Worker 
62*5a6e8488SAndroid Build Coastguard Worker 	if (vm->exprs.v == NULL)
63*5a6e8488SAndroid Build Coastguard Worker 	{
64*5a6e8488SAndroid Build Coastguard Worker 		bc_vec_init(&vm->exprs, sizeof(uchar), BC_DTOR_NONE);
65*5a6e8488SAndroid Build Coastguard Worker 	}
66*5a6e8488SAndroid Build Coastguard Worker 
67*5a6e8488SAndroid Build Coastguard Worker 	bc_vec_concat(&vm->exprs, str);
68*5a6e8488SAndroid Build Coastguard Worker 	bc_vec_concat(&vm->exprs, "\n");
69*5a6e8488SAndroid Build Coastguard Worker }
70*5a6e8488SAndroid Build Coastguard Worker 
71*5a6e8488SAndroid Build Coastguard Worker /**
72*5a6e8488SAndroid Build Coastguard Worker  * Adds the contents of @a file to the list of expressions to execute later.
73*5a6e8488SAndroid Build Coastguard Worker  * @param file  The name of the file whose contents should be added to the list
74*5a6e8488SAndroid Build Coastguard Worker  *              of expressions to execute.
75*5a6e8488SAndroid Build Coastguard Worker  */
76*5a6e8488SAndroid Build Coastguard Worker static void
bc_args_file(const char * file)77*5a6e8488SAndroid Build Coastguard Worker bc_args_file(const char* file)
78*5a6e8488SAndroid Build Coastguard Worker {
79*5a6e8488SAndroid Build Coastguard Worker 	char* buf;
80*5a6e8488SAndroid Build Coastguard Worker 
81*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
82*5a6e8488SAndroid Build Coastguard Worker 
83*5a6e8488SAndroid Build Coastguard Worker 	vm->file = file;
84*5a6e8488SAndroid Build Coastguard Worker 
85*5a6e8488SAndroid Build Coastguard Worker 	buf = bc_read_file(file);
86*5a6e8488SAndroid Build Coastguard Worker 
87*5a6e8488SAndroid Build Coastguard Worker 	assert(buf != NULL);
88*5a6e8488SAndroid Build Coastguard Worker 
89*5a6e8488SAndroid Build Coastguard Worker 	bc_args_exprs(buf);
90*5a6e8488SAndroid Build Coastguard Worker 	free(buf);
91*5a6e8488SAndroid Build Coastguard Worker }
92*5a6e8488SAndroid Build Coastguard Worker 
93*5a6e8488SAndroid Build Coastguard Worker static BcBigDig
bc_args_builtin(const char * arg)94*5a6e8488SAndroid Build Coastguard Worker bc_args_builtin(const char* arg)
95*5a6e8488SAndroid Build Coastguard Worker {
96*5a6e8488SAndroid Build Coastguard Worker 	bool strvalid;
97*5a6e8488SAndroid Build Coastguard Worker 	BcNum n;
98*5a6e8488SAndroid Build Coastguard Worker 	BcBigDig res;
99*5a6e8488SAndroid Build Coastguard Worker 
100*5a6e8488SAndroid Build Coastguard Worker 	strvalid = bc_num_strValid(arg);
101*5a6e8488SAndroid Build Coastguard Worker 
102*5a6e8488SAndroid Build Coastguard Worker 	if (BC_ERR(!strvalid))
103*5a6e8488SAndroid Build Coastguard Worker 	{
104*5a6e8488SAndroid Build Coastguard Worker 		bc_verr(BC_ERR_FATAL_ARG, arg);
105*5a6e8488SAndroid Build Coastguard Worker 	}
106*5a6e8488SAndroid Build Coastguard Worker 
107*5a6e8488SAndroid Build Coastguard Worker 	bc_num_init(&n, 0);
108*5a6e8488SAndroid Build Coastguard Worker 
109*5a6e8488SAndroid Build Coastguard Worker 	bc_num_parse(&n, arg, 10);
110*5a6e8488SAndroid Build Coastguard Worker 
111*5a6e8488SAndroid Build Coastguard Worker 	res = bc_num_bigdig(&n);
112*5a6e8488SAndroid Build Coastguard Worker 
113*5a6e8488SAndroid Build Coastguard Worker 	bc_num_free(&n);
114*5a6e8488SAndroid Build Coastguard Worker 
115*5a6e8488SAndroid Build Coastguard Worker 	return res;
116*5a6e8488SAndroid Build Coastguard Worker }
117*5a6e8488SAndroid Build Coastguard Worker 
118*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
119*5a6e8488SAndroid Build Coastguard Worker 
120*5a6e8488SAndroid Build Coastguard Worker /**
121*5a6e8488SAndroid Build Coastguard Worker  * Redefines a keyword, if it exists and is not a POSIX keyword. Otherwise, it
122*5a6e8488SAndroid Build Coastguard Worker  * throws a fatal error.
123*5a6e8488SAndroid Build Coastguard Worker  * @param keyword  The keyword to redefine.
124*5a6e8488SAndroid Build Coastguard Worker  */
125*5a6e8488SAndroid Build Coastguard Worker static void
bc_args_redefine(const char * keyword)126*5a6e8488SAndroid Build Coastguard Worker bc_args_redefine(const char* keyword)
127*5a6e8488SAndroid Build Coastguard Worker {
128*5a6e8488SAndroid Build Coastguard Worker 	size_t i;
129*5a6e8488SAndroid Build Coastguard Worker 
130*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
131*5a6e8488SAndroid Build Coastguard Worker 
132*5a6e8488SAndroid Build Coastguard Worker 	for (i = 0; i < bc_lex_kws_len; ++i)
133*5a6e8488SAndroid Build Coastguard Worker 	{
134*5a6e8488SAndroid Build Coastguard Worker 		const BcLexKeyword* kw = bc_lex_kws + i;
135*5a6e8488SAndroid Build Coastguard Worker 
136*5a6e8488SAndroid Build Coastguard Worker 		if (!strcmp(keyword, kw->name))
137*5a6e8488SAndroid Build Coastguard Worker 		{
138*5a6e8488SAndroid Build Coastguard Worker 			if (BC_LEX_KW_POSIX(kw)) break;
139*5a6e8488SAndroid Build Coastguard Worker 
140*5a6e8488SAndroid Build Coastguard Worker 			vm->redefined_kws[i] = true;
141*5a6e8488SAndroid Build Coastguard Worker 
142*5a6e8488SAndroid Build Coastguard Worker 			return;
143*5a6e8488SAndroid Build Coastguard Worker 		}
144*5a6e8488SAndroid Build Coastguard Worker 	}
145*5a6e8488SAndroid Build Coastguard Worker 
146*5a6e8488SAndroid Build Coastguard Worker 	bc_error(BC_ERR_FATAL_ARG, 0, keyword);
147*5a6e8488SAndroid Build Coastguard Worker }
148*5a6e8488SAndroid Build Coastguard Worker 
149*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
150*5a6e8488SAndroid Build Coastguard Worker 
151*5a6e8488SAndroid Build Coastguard Worker void
bc_args(int argc,const char * argv[],bool exit_exprs,BcBigDig * scale,BcBigDig * ibase,BcBigDig * obase)152*5a6e8488SAndroid Build Coastguard Worker bc_args(int argc, const char* argv[], bool exit_exprs, BcBigDig* scale,
153*5a6e8488SAndroid Build Coastguard Worker         BcBigDig* ibase, BcBigDig* obase)
154*5a6e8488SAndroid Build Coastguard Worker {
155*5a6e8488SAndroid Build Coastguard Worker 	int c;
156*5a6e8488SAndroid Build Coastguard Worker 	size_t i;
157*5a6e8488SAndroid Build Coastguard Worker 	bool do_exit = false, version = false;
158*5a6e8488SAndroid Build Coastguard Worker 	BcOpt opts;
159*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
160*5a6e8488SAndroid Build Coastguard Worker 	const char* seed = NULL;
161*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
162*5a6e8488SAndroid Build Coastguard Worker 
163*5a6e8488SAndroid Build Coastguard Worker 	BC_SIG_ASSERT_LOCKED;
164*5a6e8488SAndroid Build Coastguard Worker 
165*5a6e8488SAndroid Build Coastguard Worker 	bc_opt_init(&opts, argv);
166*5a6e8488SAndroid Build Coastguard Worker 
167*5a6e8488SAndroid Build Coastguard Worker 	// This loop should look familiar to anyone who has used getopt() or
168*5a6e8488SAndroid Build Coastguard Worker 	// getopt_long() in C.
169*5a6e8488SAndroid Build Coastguard Worker 	while ((c = bc_opt_parse(&opts, bc_args_lopt)) != -1)
170*5a6e8488SAndroid Build Coastguard Worker 	{
171*5a6e8488SAndroid Build Coastguard Worker 		switch (c)
172*5a6e8488SAndroid Build Coastguard Worker 		{
173*5a6e8488SAndroid Build Coastguard Worker 			case 'c':
174*5a6e8488SAndroid Build Coastguard Worker 			{
175*5a6e8488SAndroid Build Coastguard Worker 				vm->flags |= BC_FLAG_DIGIT_CLAMP;
176*5a6e8488SAndroid Build Coastguard Worker 				break;
177*5a6e8488SAndroid Build Coastguard Worker 			}
178*5a6e8488SAndroid Build Coastguard Worker 
179*5a6e8488SAndroid Build Coastguard Worker 			case 'C':
180*5a6e8488SAndroid Build Coastguard Worker 			{
181*5a6e8488SAndroid Build Coastguard Worker 				vm->flags &= ~BC_FLAG_DIGIT_CLAMP;
182*5a6e8488SAndroid Build Coastguard Worker 				break;
183*5a6e8488SAndroid Build Coastguard Worker 			}
184*5a6e8488SAndroid Build Coastguard Worker 
185*5a6e8488SAndroid Build Coastguard Worker 			case 'e':
186*5a6e8488SAndroid Build Coastguard Worker 			{
187*5a6e8488SAndroid Build Coastguard Worker 				// Barf if not allowed.
188*5a6e8488SAndroid Build Coastguard Worker 				if (vm->no_exprs)
189*5a6e8488SAndroid Build Coastguard Worker 				{
190*5a6e8488SAndroid Build Coastguard Worker 					bc_verr(BC_ERR_FATAL_OPTION, "-e (--expression)");
191*5a6e8488SAndroid Build Coastguard Worker 				}
192*5a6e8488SAndroid Build Coastguard Worker 
193*5a6e8488SAndroid Build Coastguard Worker 				// Add the expressions and set exit.
194*5a6e8488SAndroid Build Coastguard Worker 				bc_args_exprs(opts.optarg);
195*5a6e8488SAndroid Build Coastguard Worker 				vm->exit_exprs = (exit_exprs || vm->exit_exprs);
196*5a6e8488SAndroid Build Coastguard Worker 
197*5a6e8488SAndroid Build Coastguard Worker 				break;
198*5a6e8488SAndroid Build Coastguard Worker 			}
199*5a6e8488SAndroid Build Coastguard Worker 
200*5a6e8488SAndroid Build Coastguard Worker 			case 'f':
201*5a6e8488SAndroid Build Coastguard Worker 			{
202*5a6e8488SAndroid Build Coastguard Worker 				// Figure out if exiting on expressions is disabled.
203*5a6e8488SAndroid Build Coastguard Worker 				if (!strcmp(opts.optarg, "-")) vm->no_exprs = true;
204*5a6e8488SAndroid Build Coastguard Worker 				else
205*5a6e8488SAndroid Build Coastguard Worker 				{
206*5a6e8488SAndroid Build Coastguard Worker 					// Barf if not allowed.
207*5a6e8488SAndroid Build Coastguard Worker 					if (vm->no_exprs)
208*5a6e8488SAndroid Build Coastguard Worker 					{
209*5a6e8488SAndroid Build Coastguard Worker 						bc_verr(BC_ERR_FATAL_OPTION, "-f (--file)");
210*5a6e8488SAndroid Build Coastguard Worker 					}
211*5a6e8488SAndroid Build Coastguard Worker 
212*5a6e8488SAndroid Build Coastguard Worker 					// Add the expressions and set exit.
213*5a6e8488SAndroid Build Coastguard Worker 					bc_args_file(opts.optarg);
214*5a6e8488SAndroid Build Coastguard Worker 					vm->exit_exprs = (exit_exprs || vm->exit_exprs);
215*5a6e8488SAndroid Build Coastguard Worker 				}
216*5a6e8488SAndroid Build Coastguard Worker 
217*5a6e8488SAndroid Build Coastguard Worker 				break;
218*5a6e8488SAndroid Build Coastguard Worker 			}
219*5a6e8488SAndroid Build Coastguard Worker 
220*5a6e8488SAndroid Build Coastguard Worker 			case 'h':
221*5a6e8488SAndroid Build Coastguard Worker 			{
222*5a6e8488SAndroid Build Coastguard Worker 				bc_vm_info(vm->help);
223*5a6e8488SAndroid Build Coastguard Worker 				do_exit = true;
224*5a6e8488SAndroid Build Coastguard Worker 				break;
225*5a6e8488SAndroid Build Coastguard Worker 			}
226*5a6e8488SAndroid Build Coastguard Worker 
227*5a6e8488SAndroid Build Coastguard Worker 			case 'i':
228*5a6e8488SAndroid Build Coastguard Worker 			{
229*5a6e8488SAndroid Build Coastguard Worker 				vm->flags |= BC_FLAG_I;
230*5a6e8488SAndroid Build Coastguard Worker 				break;
231*5a6e8488SAndroid Build Coastguard Worker 			}
232*5a6e8488SAndroid Build Coastguard Worker 
233*5a6e8488SAndroid Build Coastguard Worker 			case 'I':
234*5a6e8488SAndroid Build Coastguard Worker 			{
235*5a6e8488SAndroid Build Coastguard Worker 				*ibase = bc_args_builtin(opts.optarg);
236*5a6e8488SAndroid Build Coastguard Worker 				break;
237*5a6e8488SAndroid Build Coastguard Worker 			}
238*5a6e8488SAndroid Build Coastguard Worker 
239*5a6e8488SAndroid Build Coastguard Worker 			case 'z':
240*5a6e8488SAndroid Build Coastguard Worker 			{
241*5a6e8488SAndroid Build Coastguard Worker 				vm->flags |= BC_FLAG_Z;
242*5a6e8488SAndroid Build Coastguard Worker 				break;
243*5a6e8488SAndroid Build Coastguard Worker 			}
244*5a6e8488SAndroid Build Coastguard Worker 
245*5a6e8488SAndroid Build Coastguard Worker 			case 'L':
246*5a6e8488SAndroid Build Coastguard Worker 			{
247*5a6e8488SAndroid Build Coastguard Worker 				vm->line_len = 0;
248*5a6e8488SAndroid Build Coastguard Worker 				break;
249*5a6e8488SAndroid Build Coastguard Worker 			}
250*5a6e8488SAndroid Build Coastguard Worker 
251*5a6e8488SAndroid Build Coastguard Worker 			case 'O':
252*5a6e8488SAndroid Build Coastguard Worker 			{
253*5a6e8488SAndroid Build Coastguard Worker 				*obase = bc_args_builtin(opts.optarg);
254*5a6e8488SAndroid Build Coastguard Worker 				break;
255*5a6e8488SAndroid Build Coastguard Worker 			}
256*5a6e8488SAndroid Build Coastguard Worker 
257*5a6e8488SAndroid Build Coastguard Worker 			case 'P':
258*5a6e8488SAndroid Build Coastguard Worker 			{
259*5a6e8488SAndroid Build Coastguard Worker 				vm->flags &= ~(BC_FLAG_P);
260*5a6e8488SAndroid Build Coastguard Worker 				break;
261*5a6e8488SAndroid Build Coastguard Worker 			}
262*5a6e8488SAndroid Build Coastguard Worker 
263*5a6e8488SAndroid Build Coastguard Worker 			case 'R':
264*5a6e8488SAndroid Build Coastguard Worker 			{
265*5a6e8488SAndroid Build Coastguard Worker 				vm->flags &= ~(BC_FLAG_R);
266*5a6e8488SAndroid Build Coastguard Worker 				break;
267*5a6e8488SAndroid Build Coastguard Worker 			}
268*5a6e8488SAndroid Build Coastguard Worker 
269*5a6e8488SAndroid Build Coastguard Worker 			case 'S':
270*5a6e8488SAndroid Build Coastguard Worker 			{
271*5a6e8488SAndroid Build Coastguard Worker 				*scale = bc_args_builtin(opts.optarg);
272*5a6e8488SAndroid Build Coastguard Worker 				break;
273*5a6e8488SAndroid Build Coastguard Worker 			}
274*5a6e8488SAndroid Build Coastguard Worker 
275*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
276*5a6e8488SAndroid Build Coastguard Worker 			case 'E':
277*5a6e8488SAndroid Build Coastguard Worker 			{
278*5a6e8488SAndroid Build Coastguard Worker 				if (BC_ERR(!bc_num_strValid(opts.optarg)))
279*5a6e8488SAndroid Build Coastguard Worker 				{
280*5a6e8488SAndroid Build Coastguard Worker 					bc_verr(BC_ERR_FATAL_ARG, opts.optarg);
281*5a6e8488SAndroid Build Coastguard Worker 				}
282*5a6e8488SAndroid Build Coastguard Worker 
283*5a6e8488SAndroid Build Coastguard Worker 				seed = opts.optarg;
284*5a6e8488SAndroid Build Coastguard Worker 
285*5a6e8488SAndroid Build Coastguard Worker 				break;
286*5a6e8488SAndroid Build Coastguard Worker 			}
287*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
288*5a6e8488SAndroid Build Coastguard Worker 
289*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLED
290*5a6e8488SAndroid Build Coastguard Worker 			case 'g':
291*5a6e8488SAndroid Build Coastguard Worker 			{
292*5a6e8488SAndroid Build Coastguard Worker 				assert(BC_IS_BC);
293*5a6e8488SAndroid Build Coastguard Worker 				vm->flags |= BC_FLAG_G;
294*5a6e8488SAndroid Build Coastguard Worker 				break;
295*5a6e8488SAndroid Build Coastguard Worker 			}
296*5a6e8488SAndroid Build Coastguard Worker 
297*5a6e8488SAndroid Build Coastguard Worker 			case 'l':
298*5a6e8488SAndroid Build Coastguard Worker 			{
299*5a6e8488SAndroid Build Coastguard Worker 				assert(BC_IS_BC);
300*5a6e8488SAndroid Build Coastguard Worker 				vm->flags |= BC_FLAG_L;
301*5a6e8488SAndroid Build Coastguard Worker 				break;
302*5a6e8488SAndroid Build Coastguard Worker 			}
303*5a6e8488SAndroid Build Coastguard Worker 
304*5a6e8488SAndroid Build Coastguard Worker 			case 'q':
305*5a6e8488SAndroid Build Coastguard Worker 			{
306*5a6e8488SAndroid Build Coastguard Worker 				assert(BC_IS_BC);
307*5a6e8488SAndroid Build Coastguard Worker 				vm->flags &= ~(BC_FLAG_Q);
308*5a6e8488SAndroid Build Coastguard Worker 				break;
309*5a6e8488SAndroid Build Coastguard Worker 			}
310*5a6e8488SAndroid Build Coastguard Worker 
311*5a6e8488SAndroid Build Coastguard Worker 			case 'r':
312*5a6e8488SAndroid Build Coastguard Worker 			{
313*5a6e8488SAndroid Build Coastguard Worker 				bc_args_redefine(opts.optarg);
314*5a6e8488SAndroid Build Coastguard Worker 				break;
315*5a6e8488SAndroid Build Coastguard Worker 			}
316*5a6e8488SAndroid Build Coastguard Worker 
317*5a6e8488SAndroid Build Coastguard Worker 			case 's':
318*5a6e8488SAndroid Build Coastguard Worker 			{
319*5a6e8488SAndroid Build Coastguard Worker 				assert(BC_IS_BC);
320*5a6e8488SAndroid Build Coastguard Worker 				vm->flags |= BC_FLAG_S;
321*5a6e8488SAndroid Build Coastguard Worker 				break;
322*5a6e8488SAndroid Build Coastguard Worker 			}
323*5a6e8488SAndroid Build Coastguard Worker 
324*5a6e8488SAndroid Build Coastguard Worker 			case 'w':
325*5a6e8488SAndroid Build Coastguard Worker 			{
326*5a6e8488SAndroid Build Coastguard Worker 				assert(BC_IS_BC);
327*5a6e8488SAndroid Build Coastguard Worker 				vm->flags |= BC_FLAG_W;
328*5a6e8488SAndroid Build Coastguard Worker 				break;
329*5a6e8488SAndroid Build Coastguard Worker 			}
330*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLED
331*5a6e8488SAndroid Build Coastguard Worker 
332*5a6e8488SAndroid Build Coastguard Worker 			case 'V':
333*5a6e8488SAndroid Build Coastguard Worker 			case 'v':
334*5a6e8488SAndroid Build Coastguard Worker 			{
335*5a6e8488SAndroid Build Coastguard Worker 				do_exit = version = true;
336*5a6e8488SAndroid Build Coastguard Worker 				break;
337*5a6e8488SAndroid Build Coastguard Worker 			}
338*5a6e8488SAndroid Build Coastguard Worker 
339*5a6e8488SAndroid Build Coastguard Worker #if DC_ENABLED
340*5a6e8488SAndroid Build Coastguard Worker 			case 'x':
341*5a6e8488SAndroid Build Coastguard Worker 			{
342*5a6e8488SAndroid Build Coastguard Worker 				assert(BC_IS_DC);
343*5a6e8488SAndroid Build Coastguard Worker 				vm->flags |= DC_FLAG_X;
344*5a6e8488SAndroid Build Coastguard Worker 				break;
345*5a6e8488SAndroid Build Coastguard Worker 			}
346*5a6e8488SAndroid Build Coastguard Worker #endif // DC_ENABLED
347*5a6e8488SAndroid Build Coastguard Worker 
348*5a6e8488SAndroid Build Coastguard Worker #if BC_DEBUG
349*5a6e8488SAndroid Build Coastguard Worker 			// We shouldn't get here because bc_opt_error()/bc_error() should
350*5a6e8488SAndroid Build Coastguard Worker 			// longjmp() out.
351*5a6e8488SAndroid Build Coastguard Worker 			case '?':
352*5a6e8488SAndroid Build Coastguard Worker 			case ':':
353*5a6e8488SAndroid Build Coastguard Worker 			default:
354*5a6e8488SAndroid Build Coastguard Worker 			{
355*5a6e8488SAndroid Build Coastguard Worker 				BC_UNREACHABLE
356*5a6e8488SAndroid Build Coastguard Worker #if !BC_CLANG
357*5a6e8488SAndroid Build Coastguard Worker 				abort();
358*5a6e8488SAndroid Build Coastguard Worker #endif // !BC_CLANG
359*5a6e8488SAndroid Build Coastguard Worker 			}
360*5a6e8488SAndroid Build Coastguard Worker #endif // BC_DEBUG
361*5a6e8488SAndroid Build Coastguard Worker 		}
362*5a6e8488SAndroid Build Coastguard Worker 	}
363*5a6e8488SAndroid Build Coastguard Worker 
364*5a6e8488SAndroid Build Coastguard Worker 	if (version) bc_vm_info(NULL);
365*5a6e8488SAndroid Build Coastguard Worker 	if (do_exit)
366*5a6e8488SAndroid Build Coastguard Worker 	{
367*5a6e8488SAndroid Build Coastguard Worker 		vm->status = (sig_atomic_t) BC_STATUS_QUIT;
368*5a6e8488SAndroid Build Coastguard Worker 		BC_JMP;
369*5a6e8488SAndroid Build Coastguard Worker 	}
370*5a6e8488SAndroid Build Coastguard Worker 
371*5a6e8488SAndroid Build Coastguard Worker 	// We do not print the banner if expressions are used or dc is used.
372*5a6e8488SAndroid Build Coastguard Worker 	if (BC_ARGS_SHOULD_BE_QUIET) vm->flags &= ~(BC_FLAG_Q);
373*5a6e8488SAndroid Build Coastguard Worker 
374*5a6e8488SAndroid Build Coastguard Worker 	// We need to make sure the files list is initialized. We don't want to
375*5a6e8488SAndroid Build Coastguard Worker 	// initialize it if there are no files because it's just a waste of memory.
376*5a6e8488SAndroid Build Coastguard Worker 	if (opts.optind < (size_t) argc && vm->files.v == NULL)
377*5a6e8488SAndroid Build Coastguard Worker 	{
378*5a6e8488SAndroid Build Coastguard Worker 		bc_vec_init(&vm->files, sizeof(char*), BC_DTOR_NONE);
379*5a6e8488SAndroid Build Coastguard Worker 	}
380*5a6e8488SAndroid Build Coastguard Worker 
381*5a6e8488SAndroid Build Coastguard Worker 	// Add all the files to the vector.
382*5a6e8488SAndroid Build Coastguard Worker 	for (i = opts.optind; i < (size_t) argc; ++i)
383*5a6e8488SAndroid Build Coastguard Worker 	{
384*5a6e8488SAndroid Build Coastguard Worker 		bc_vec_push(&vm->files, argv + i);
385*5a6e8488SAndroid Build Coastguard Worker 	}
386*5a6e8488SAndroid Build Coastguard Worker 
387*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_EXTRA_MATH
388*5a6e8488SAndroid Build Coastguard Worker 	if (seed != NULL)
389*5a6e8488SAndroid Build Coastguard Worker 	{
390*5a6e8488SAndroid Build Coastguard Worker 		BcNum n;
391*5a6e8488SAndroid Build Coastguard Worker 
392*5a6e8488SAndroid Build Coastguard Worker 		bc_num_init(&n, strlen(seed));
393*5a6e8488SAndroid Build Coastguard Worker 
394*5a6e8488SAndroid Build Coastguard Worker 		BC_SIG_UNLOCK;
395*5a6e8488SAndroid Build Coastguard Worker 
396*5a6e8488SAndroid Build Coastguard Worker 		bc_num_parse(&n, seed, BC_BASE);
397*5a6e8488SAndroid Build Coastguard Worker 
398*5a6e8488SAndroid Build Coastguard Worker 		bc_program_assignSeed(&vm->prog, &n);
399*5a6e8488SAndroid Build Coastguard Worker 
400*5a6e8488SAndroid Build Coastguard Worker 		BC_SIG_LOCK;
401*5a6e8488SAndroid Build Coastguard Worker 
402*5a6e8488SAndroid Build Coastguard Worker 		bc_num_free(&n);
403*5a6e8488SAndroid Build Coastguard Worker 	}
404*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_EXTRA_MATH
405*5a6e8488SAndroid Build Coastguard Worker }
406