/*1* *****************************************************************************2*3* SPDX-License-Identifier: BSD-2-Clause4*5* Copyright (c) 2018-2025 Gavin D. Howard and contributors.6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions are met:9*10* * Redistributions of source code must retain the above copyright notice, this11* list of conditions and the following disclaimer.12*13* * Redistributions in binary form must reproduce the above copyright notice,14* this list of conditions and the following disclaimer in the documentation15* and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"18* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE21* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS24* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN25* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)26* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE27* POSSIBILITY OF SUCH DAMAGE.28*29* *****************************************************************************30*31* The entry point for bc.32*33*/3435#include <assert.h>36#include <stdlib.h>37#include <string.h>3839#if BC_ENABLE_NLS40#include <locale.h>41#endif // BC_ENABLE_NLS4243#ifndef _WIN3244#include <libgen.h>45#endif // _WIN324647#include <setjmp.h>4849#include <status.h>50#include <vm.h>51#include <bc.h>52#include <dc.h>5354int55main(int argc, const char* argv[])56{57BcStatus s;58char* name;59size_t len = strlen(BC_EXECPREFIX);6061#if BC_ENABLE_NLS62// Must set the locale properly in order to have the right error messages.63vm->locale = setlocale(LC_ALL, "");64#endif // BC_ENABLE_NLS6566// Set the start pledge().67bc_pledge(bc_pledge_start, NULL);6869// Sometimes, argv[0] can be NULL. Better make sure to be robust against it.70if (argv[0] != NULL)71{72// Figure out the name of the calculator we are using. We can't use73// basename because it's not portable, but yes, this is stripping off74// the directory.75name = strrchr(argv[0], BC_FILE_SEP);76vm->name = (name == NULL) ? argv[0] : name + 1;77}78else79{80#if !DC_ENABLED81vm->name = "bc";82#elif !BC_ENABLED83vm->name = "dc";84#else85// Just default to bc in that case.86vm->name = "bc";87#endif88}8990// If the name is longer than the length of the prefix, skip the prefix.91if (strlen(vm->name) > len) vm->name += len;9293BC_SIG_LOCK;9495// We *must* do this here. Otherwise, other code could not jump out all of96// the way.97bc_vec_init(&vm->jmp_bufs, sizeof(sigjmp_buf), BC_DTOR_NONE);9899BC_SETJMP_LOCKED(vm, exit);100101#if BC_CLANG102#pragma clang diagnostic push103#pragma clang diagnostic ignored "-Wcast-qual"104#endif // BC_CLANG105#if !DC_ENABLED106s = bc_main(argc, (const char**) argv);107#elif !BC_ENABLED108s = dc_main(argc, (const char**) argv);109#else110// BC_IS_BC uses vm->name, which was set above. So we're good.111if (BC_IS_BC) s = bc_main(argc, (const char**) argv);112else s = dc_main(argc, (const char**) argv);113#endif114#if BC_CLANG115#pragma clang diagnostic pop116#endif // BC_CLANG117118vm->status = (sig_atomic_t) s;119120exit:121BC_SIG_MAYLOCK;122123s = bc_vm_atexit((BcStatus) vm->status);124125return (int) s;126}127128129