blob: 7a48e1e03494e814086e2569c6298292e91dae7f [file] [log] [blame]
Gavin Howard5715b042018-02-12 16:11:42 -07001/*
2 * Copyright 2018 Contributors
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13
14 * 3. Neither the name of the copyright holder nor the names of its contributors
15 * may be used to endorse or promote products derived from this software without
16 * specific prior written permission.
17
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *
30 *******************************************************************************
31 *
Gavin Howard0dbafb52018-02-15 10:03:30 -070032 * A special license exemption is granted to the Toybox project to use this
33 * source under the following BSD 0-Clause License:
Gavin Howard5715b042018-02-12 16:11:42 -070034 *
35 * Permission to use, copy, modify, and/or distribute this software for any
36 * purpose with or without fee is hereby granted.
37 *
38 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
39 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
40 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
41 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
42 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
43 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
44 * PERFORMANCE OF THIS SOFTWARE.
45 *
46 *******************************************************************************
47 *
48 * The entry point for bc.
49 *
50 */
51
Gavin Howard3e7cf052018-01-27 00:50:45 -070052#include <stdio.h>
Gavin Howarddce6dc92018-01-26 12:08:43 -070053#include <string.h>
54
Gavin Howardbc9fa772018-01-24 11:49:33 -070055#include <locale.h>
56
Gavin Howarddce6dc92018-01-26 12:08:43 -070057#include <getopt.h>
58
Gavin Howard13ccc4a2018-02-15 14:09:41 -070059#include <bc.h>
Gavin Howarddec399f2018-01-23 12:09:11 -070060
Gavin Howarddce6dc92018-01-26 12:08:43 -070061static const struct option bc_opts[] = {
62
Gavin Howard914030d2018-02-08 20:05:19 -070063 { "code", no_argument, NULL, 'c' },
Gavin Howarddce6dc92018-01-26 12:08:43 -070064 { "help", no_argument, NULL, 'h' },
65 { "interactive", no_argument, NULL, 'i' },
66 { "mathlib", no_argument, NULL, 'l' },
67 { "quiet", no_argument, NULL, 'q' },
68 { "standard", no_argument, NULL, 's' },
69 { "version", no_argument, NULL, 'v' },
70 { "warn", no_argument, NULL, 'w' },
71 { 0, 0, 0, 0 },
72
73};
74
Gavin Howardb206b0a2018-02-08 21:39:29 -070075static const char* const bc_short_opts = "chilqsvw";
Gavin Howard3e7cf052018-01-27 00:50:45 -070076
77static const char* const bc_help =
78 "usage: bc [-hilqsvw] [long-options] [ file ... ]\n"
79 "\n"
80 "bc is a command-line calculator with a Turing-complete language.\n"
81 "\n"
Gavin Howard91072cf2018-02-08 21:07:51 -070082 " -c --code print bytecode instead of executing it\n"
Gavin Howard3e7cf052018-01-27 00:50:45 -070083 " -h --help print this usage message and exit\n"
84 " -i --interactive force interactive mode\n"
85 " -l --mathlib use predefined math routines:\n\n"
86 " s(expr) = sine of expr in radians\n"
87 " c(expr) = cosine of expr in radians\n"
88 " a(expr) = arctangent of expr, returning radians\n"
89 " l(expr) = natural log of expr\n"
90 " e(expr) = raises e to the power of expr\n"
91 " j(n, x) = Bessel function of integer order n of x\n"
92 "\n"
93 " -q --quiet don't print version and copyright\n"
94 " -s --standard error if any non-POSIX extensions are used\n"
95 " -w --warn warn if any non-POSIX extensions are used\n"
96 " -v --version print version information and copyright and exit\n\n";
97
Gavin Howard32aee402018-02-08 21:38:14 -070098long bc_code = 0;
Gavin Howard3e7cf052018-01-27 00:50:45 -070099long bc_interactive = 0;
100long bc_std = 0;
101long bc_warn = 0;
102
Gavin Howarda0b34532018-02-10 15:17:18 -0700103long bc_signal = 0;
Gavin Howarddce6dc92018-01-26 12:08:43 -0700104
Gavin Howard361bfd32018-01-29 15:24:44 -0700105const char* const bc_mathlib = BC_MATHLIB_PATH "mathlib.bc";
106
107const char* const bc_version = VERSION;
108
Gavin Howarddec399f2018-01-23 12:09:11 -0700109int main(int argc, char* argv[]) {
Gavin Howarddce6dc92018-01-26 12:08:43 -0700110
111 unsigned int flags;
112 unsigned int filec;
113 const char** filev;
114
Gavin Howard4bc73ee2018-01-26 11:39:20 -0700115 setlocale(LC_ALL, "");
Gavin Howarddce6dc92018-01-26 12:08:43 -0700116
117 flags = 0;
118
119 // Getopt needs this.
120 int opt_idx = 0;
121
122 int c = getopt_long(argc, argv, bc_short_opts, bc_opts, &opt_idx);
123
124 while (c != -1) {
125
126 switch (c) {
127
128 case 0:
129 {
130 // This is the case when a long option is
131 // found, so we don't need to do anything.
132 break;
133 }
134
Gavin Howard914030d2018-02-08 20:05:19 -0700135 case 'c':
136 {
Gavin Howardee110332018-02-08 20:52:41 -0700137 flags |= BC_FLAG_CODE;
138 break;
Gavin Howard914030d2018-02-08 20:05:19 -0700139 }
140
Gavin Howarddce6dc92018-01-26 12:08:43 -0700141 case 'h':
142 {
143 flags |= BC_FLAG_HELP;
144 break;
145 }
146
147 case 'i':
148 {
149 flags |= BC_FLAG_INTERACTIVE;
150 break;
151 }
152
153 case 'l':
154 {
155 flags |= BC_FLAG_MATHLIB;
156 break;
157 }
158
159 case 'q':
160 {
161 flags |= BC_FLAG_QUIET;
162 break;
163 }
164
165 case 's':
166 {
167 flags |= BC_FLAG_STANDARD;
168 break;
169 }
170
171 case 'v':
172 {
173 flags |= BC_FLAG_VERSION;
174 break;
175 }
176
177 case 'w':
178 {
179 flags |= BC_FLAG_WARN;
180 break;
181 }
182
183 // Getopt printed an error message, but we should exit.
184 case '?':
185 default:
186 {
187 return BC_STATUS_INVALID_OPTION;
188 break;
189 }
190 }
191
192 c = getopt_long(argc, argv, bc_short_opts, bc_opts, &opt_idx);
193 }
194
Gavin Howard3e7cf052018-01-27 00:50:45 -0700195 if (flags & BC_FLAG_HELP) printf(bc_help);
196
Gavin Howard37b1a202018-01-26 12:28:49 -0700197 if (argv[optind] && strcmp(argv[optind], "--") == 0) {
Gavin Howarddce6dc92018-01-26 12:08:43 -0700198 ++optind;
199 }
200
201 filec = argc - optind;
202 filev = (const char**) (argv + optind);
203
204 return bc_exec(flags, filec, filev);
Gavin Howarddec399f2018-01-23 12:09:11 -0700205}