252884ae7e
These implementations of the bc and dc programs offer a number of advantages compared to the current implementations in the FreeBSD base system: - They do not depend on external large number functions (i.e. no dependency on OpenSSL or any other large number library) - They implements all features found in GNU bc/dc (with the exception of the forking of sub-processes, which the author of this version considers as a security issue). - They are significantly faster than the current code in base (more than 2 orders of magnitude in some of my tests, e.g. for 12345^100000). - They should be fully compatible with all features and the behavior of the current implementations in FreeBSD (not formally verified). - They support POSIX message catalogs and come with localized messages in Chinese, Dutch, English, French, German, Japanese, Polish, Portugueze, and Russian. - They offer very detailed man-pages that provide far more information than the current ones. The upstream sources contain a large number of tests, which are not imported with this commit. They could be integrated into our test framework at a latter time. Installation of this version is controlled by the option "MK_GH_BC=yes". This option will be set to yes by default in 13-CURRENT, but will be off by default in 12-STABLE. Approved by: imp Obtained from: https://git.yzena.com/gavin/bc MFC after: 4 weeks Relnotes: yes Differential Revision: https://reviews.freebsd.org/D19982
116 lines
3.5 KiB
C
116 lines
3.5 KiB
C
/*
|
|
* *****************************************************************************
|
|
*
|
|
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* *****************************************************************************
|
|
*
|
|
* Definitions for bc's parser.
|
|
*
|
|
*/
|
|
|
|
#ifndef BC_PARSE_H
|
|
#define BC_PARSE_H
|
|
|
|
#include <limits.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#include <status.h>
|
|
#include <vector.h>
|
|
#include <lex.h>
|
|
#include <lang.h>
|
|
|
|
#define BC_PARSE_REL (UINTMAX_C(1)<<0)
|
|
#define BC_PARSE_PRINT (UINTMAX_C(1)<<1)
|
|
#define BC_PARSE_NOCALL (UINTMAX_C(1)<<2)
|
|
#define BC_PARSE_NOREAD (UINTMAX_C(1)<<3)
|
|
#define BC_PARSE_ARRAY (UINTMAX_C(1)<<4)
|
|
#define BC_PARSE_NEEDVAL (UINTMAX_C(1)<<5)
|
|
|
|
#if BC_ENABLED
|
|
#define BC_PARSE_CAN_PARSE(p) \
|
|
((p).l.t != BC_LEX_EOF && (p).l.t != BC_LEX_KW_DEFINE)
|
|
#else // BC_ENABLED
|
|
#define BC_PARSE_CAN_PARSE(p) ((p).l.t != BC_LEX_EOF)
|
|
#endif // BC_ENABLED
|
|
|
|
#define bc_parse_push(p, i) (bc_vec_pushByte(&(p)->func->code, (uchar) (i)))
|
|
#define bc_parse_pushIndex(p, idx) (bc_vec_pushIndex(&(p)->func->code, (idx)))
|
|
|
|
#define bc_parse_err(p, e) (bc_vm_error((e), (p)->l.line))
|
|
#define bc_parse_verr(p, e, ...) (bc_vm_error((e), (p)->l.line, __VA_ARGS__))
|
|
|
|
typedef struct BcParseNext {
|
|
uchar len;
|
|
uchar tokens[4];
|
|
} BcParseNext;
|
|
|
|
#define BC_PARSE_NEXT_TOKENS(...) .tokens = { __VA_ARGS__ }
|
|
#define BC_PARSE_NEXT(a, ...) \
|
|
{ .len = (uchar) (a), BC_PARSE_NEXT_TOKENS(__VA_ARGS__) }
|
|
|
|
struct BcParse;
|
|
struct BcProgram;
|
|
|
|
typedef void (*BcParseParse)(struct BcParse*);
|
|
typedef void (*BcParseExpr)(struct BcParse*, uint8_t);
|
|
|
|
typedef struct BcParse {
|
|
|
|
BcLex l;
|
|
|
|
#if BC_ENABLED
|
|
BcVec flags;
|
|
BcVec exits;
|
|
BcVec conds;
|
|
BcVec ops;
|
|
BcVec buf;
|
|
#endif // BC_ENABLED
|
|
|
|
struct BcProgram *prog;
|
|
BcFunc *func;
|
|
size_t fidx;
|
|
|
|
bool auto_part;
|
|
|
|
} BcParse;
|
|
|
|
void bc_parse_init(BcParse *p, struct BcProgram *prog, size_t func);
|
|
void bc_parse_free(BcParse *p);
|
|
void bc_parse_reset(BcParse *p);
|
|
|
|
void bc_parse_addString(BcParse *p);
|
|
void bc_parse_number(BcParse *p);
|
|
void bc_parse_updateFunc(BcParse *p, size_t fidx);
|
|
void bc_parse_pushName(const BcParse* p, char *name, bool var);
|
|
void bc_parse_text(BcParse *p, const char *text);
|
|
|
|
extern const char bc_parse_one[];
|
|
|
|
#endif // BC_PARSE_H
|