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