Add Chromium-only Blender WebEngine parity work
This commit is contained in:
54
blender-5.2.0/extern/gmp-source/demos/expr/Makefile.am
vendored
Normal file
54
blender-5.2.0/extern/gmp-source/demos/expr/Makefile.am
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
## Process this file with automake to generate Makefile.in
|
||||
|
||||
# Copyright 2001-2004 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of the GNU MP Library.
|
||||
#
|
||||
# The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of either:
|
||||
#
|
||||
# * the GNU Lesser General Public License as published by the Free
|
||||
# Software Foundation; either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# or
|
||||
#
|
||||
# * the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option) any
|
||||
# later version.
|
||||
#
|
||||
# or both in parallel, as here.
|
||||
#
|
||||
# The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received copies of the GNU General Public License and the
|
||||
# GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
# see https://www.gnu.org/licenses/.
|
||||
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/tests
|
||||
|
||||
# FIXME: This is a workaround for a bug in automake 1.8.4. When the only
|
||||
# library is in EXTRA_LIBRARIES, $(ARFLAGS) is used but no default setting
|
||||
# for that variable is established. We give an explicit ARFLAGS=cru the
|
||||
# same as generated for lib_LIBRARIES or noinst_LIBRARIES.
|
||||
#
|
||||
ARFLAGS = cru
|
||||
|
||||
EXTRA_LIBRARIES = libexpr.a
|
||||
libexpr_a_SOURCES = expr.h expr-impl.h \
|
||||
expr.c exprv.c exprz.c exprza.c exprq.c exprqa.c exprf.c exprfa.c
|
||||
|
||||
EXTRA_PROGRAMS = run-expr t-expr
|
||||
LDADD = libexpr.a $(top_builddir)/libgmp.la
|
||||
t_expr_LDADD = $(top_builddir)/tests/libtests.la $(LDADD)
|
||||
|
||||
CLEANFILES = $(EXTRA_PROGRAMS) $(EXTRA_LIBRARIES)
|
||||
|
||||
allprogs: $(EXTRA_PROGRAMS)
|
||||
|
||||
$(top_builddir)/tests/libtests.la:
|
||||
cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
|
||||
666
blender-5.2.0/extern/gmp-source/demos/expr/Makefile.in
vendored
Normal file
666
blender-5.2.0/extern/gmp-source/demos/expr/Makefile.in
vendored
Normal file
@@ -0,0 +1,666 @@
|
||||
# Makefile.in generated by automake 1.15 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# Copyright 2001-2004 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of the GNU MP Library.
|
||||
#
|
||||
# The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of either:
|
||||
#
|
||||
# * the GNU Lesser General Public License as published by the Free
|
||||
# Software Foundation; either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# or
|
||||
#
|
||||
# * the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option) any
|
||||
# later version.
|
||||
#
|
||||
# or both in parallel, as here.
|
||||
#
|
||||
# The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received copies of the GNU General Public License and the
|
||||
# GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
# see https://www.gnu.org/licenses/.
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
EXTRA_PROGRAMS = run-expr$(EXEEXT) t-expr$(EXEEXT)
|
||||
subdir = demos/expr
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_AR = $(am__v_AR_@AM_V@)
|
||||
am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
|
||||
am__v_AR_0 = @echo " AR " $@;
|
||||
am__v_AR_1 =
|
||||
libexpr_a_AR = $(AR) $(ARFLAGS)
|
||||
libexpr_a_LIBADD =
|
||||
am_libexpr_a_OBJECTS = expr.$(OBJEXT) exprv.$(OBJEXT) exprz.$(OBJEXT) \
|
||||
exprza.$(OBJEXT) exprq.$(OBJEXT) exprqa.$(OBJEXT) \
|
||||
exprf.$(OBJEXT) exprfa.$(OBJEXT)
|
||||
libexpr_a_OBJECTS = $(am_libexpr_a_OBJECTS)
|
||||
run_expr_SOURCES = run-expr.c
|
||||
run_expr_OBJECTS = run-expr.$(OBJEXT)
|
||||
run_expr_LDADD = $(LDADD)
|
||||
run_expr_DEPENDENCIES = libexpr.a $(top_builddir)/libgmp.la
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
am__v_lt_0 = --silent
|
||||
am__v_lt_1 =
|
||||
t_expr_SOURCES = t-expr.c
|
||||
t_expr_OBJECTS = t-expr.$(OBJEXT)
|
||||
t_expr_DEPENDENCIES = $(top_builddir)/tests/libtests.la $(LDADD)
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
|
||||
depcomp =
|
||||
am__depfiles_maybe =
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CFLAGS) $(CFLAGS)
|
||||
AM_V_CC = $(am__v_CC_@AM_V@)
|
||||
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
am__v_CC_1 =
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
|
||||
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_CCLD_1 =
|
||||
SOURCES = $(libexpr_a_SOURCES) run-expr.c t-expr.c
|
||||
DIST_SOURCES = $(libexpr_a_SOURCES) run-expr.c t-expr.c
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
am__uniquify_input = $(AWK) '\
|
||||
BEGIN { nonempty = 0; } \
|
||||
{ items[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in items) print i; }; } \
|
||||
'
|
||||
# Make sure the list of sources is unique. This is necessary because,
|
||||
# e.g., the same source file might be shared among _SOURCES variables
|
||||
# for different programs/libraries.
|
||||
am__define_uniq_tagged_files = \
|
||||
list='$(am__tagged_files)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in README
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ABI = @ABI@
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AS = @AS@
|
||||
ASMFLAGS = @ASMFLAGS@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CALLING_CONVENTIONS_OBJS = @CALLING_CONVENTIONS_OBJS@
|
||||
CC = @CC@
|
||||
CCAS = @CCAS@
|
||||
CC_FOR_BUILD = @CC_FOR_BUILD@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CPP_FOR_BUILD = @CPP_FOR_BUILD@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFN_LONG_LONG_LIMB = @DEFN_LONG_LONG_LIMB@
|
||||
DEFS = @DEFS@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
|
||||
FGREP = @FGREP@
|
||||
GMP_LDFLAGS = @GMP_LDFLAGS@
|
||||
GMP_LIMB_BITS = @GMP_LIMB_BITS@
|
||||
GMP_NAIL_BITS = @GMP_NAIL_BITS@
|
||||
GREP = @GREP@
|
||||
HAVE_CLOCK_01 = @HAVE_CLOCK_01@
|
||||
HAVE_CPUTIME_01 = @HAVE_CPUTIME_01@
|
||||
HAVE_GETRUSAGE_01 = @HAVE_GETRUSAGE_01@
|
||||
HAVE_GETTIMEOFDAY_01 = @HAVE_GETTIMEOFDAY_01@
|
||||
HAVE_HOST_CPU_FAMILY_power = @HAVE_HOST_CPU_FAMILY_power@
|
||||
HAVE_HOST_CPU_FAMILY_powerpc = @HAVE_HOST_CPU_FAMILY_powerpc@
|
||||
HAVE_SIGACTION_01 = @HAVE_SIGACTION_01@
|
||||
HAVE_SIGALTSTACK_01 = @HAVE_SIGALTSTACK_01@
|
||||
HAVE_SIGSTACK_01 = @HAVE_SIGSTACK_01@
|
||||
HAVE_STACK_T_01 = @HAVE_STACK_T_01@
|
||||
HAVE_SYS_RESOURCE_H_01 = @HAVE_SYS_RESOURCE_H_01@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LEX = @LEX@
|
||||
LEXLIB = @LEXLIB@
|
||||
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
|
||||
LIBCURSES = @LIBCURSES@
|
||||
LIBGMPXX_LDFLAGS = @LIBGMPXX_LDFLAGS@
|
||||
LIBGMP_DLL = @LIBGMP_DLL@
|
||||
LIBGMP_LDFLAGS = @LIBGMP_LDFLAGS@
|
||||
LIBM = @LIBM@
|
||||
LIBM_FOR_BUILD = @LIBM_FOR_BUILD@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBREADLINE = @LIBREADLINE@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
M4 = @M4@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
SPEED_CYCLECOUNTER_OBJ = @SPEED_CYCLECOUNTER_OBJ@
|
||||
STRIP = @STRIP@
|
||||
TAL_OBJECT = @TAL_OBJECT@
|
||||
TUNE_LIBS = @TUNE_LIBS@
|
||||
TUNE_SQR_OBJ = @TUNE_SQR_OBJ@
|
||||
U_FOR_BUILD = @U_FOR_BUILD@
|
||||
VERSION = @VERSION@
|
||||
WITH_READLINE_01 = @WITH_READLINE_01@
|
||||
YACC = @YACC@
|
||||
YFLAGS = @YFLAGS@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
gmp_srclinks = @gmp_srclinks@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
mpn_objects = @mpn_objects@
|
||||
mpn_objs_in_libgmp = @mpn_objs_in_libgmp@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/tests
|
||||
|
||||
# FIXME: This is a workaround for a bug in automake 1.8.4. When the only
|
||||
# library is in EXTRA_LIBRARIES, $(ARFLAGS) is used but no default setting
|
||||
# for that variable is established. We give an explicit ARFLAGS=cru the
|
||||
# same as generated for lib_LIBRARIES or noinst_LIBRARIES.
|
||||
#
|
||||
ARFLAGS = cru
|
||||
EXTRA_LIBRARIES = libexpr.a
|
||||
libexpr_a_SOURCES = expr.h expr-impl.h \
|
||||
expr.c exprv.c exprz.c exprza.c exprq.c exprqa.c exprf.c exprfa.c
|
||||
|
||||
LDADD = libexpr.a $(top_builddir)/libgmp.la
|
||||
t_expr_LDADD = $(top_builddir)/tests/libtests.la $(LDADD)
|
||||
CLEANFILES = $(EXTRA_PROGRAMS) $(EXTRA_LIBRARIES)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps demos/expr/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu --ignore-deps demos/expr/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
libexpr.a: $(libexpr_a_OBJECTS) $(libexpr_a_DEPENDENCIES) $(EXTRA_libexpr_a_DEPENDENCIES)
|
||||
$(AM_V_at)-rm -f libexpr.a
|
||||
$(AM_V_AR)$(libexpr_a_AR) libexpr.a $(libexpr_a_OBJECTS) $(libexpr_a_LIBADD)
|
||||
$(AM_V_at)$(RANLIB) libexpr.a
|
||||
|
||||
run-expr$(EXEEXT): $(run_expr_OBJECTS) $(run_expr_DEPENDENCIES) $(EXTRA_run_expr_DEPENDENCIES)
|
||||
@rm -f run-expr$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(run_expr_OBJECTS) $(run_expr_LDADD) $(LIBS)
|
||||
|
||||
t-expr$(EXEEXT): $(t_expr_OBJECTS) $(t_expr_DEPENDENCIES) $(EXTRA_t_expr_DEPENDENCIES)
|
||||
@rm -f t-expr$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(t_expr_OBJECTS) $(t_expr_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
.c.o:
|
||||
$(AM_V_CC)$(COMPILE) -c -o $@ $<
|
||||
|
||||
.c.obj:
|
||||
$(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
$(AM_V_CC)$(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
ID: $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-am
|
||||
TAGS: tags
|
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-am
|
||||
|
||||
CTAGS: ctags
|
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-am
|
||||
|
||||
cscopelist-am: $(am__tagged_files)
|
||||
list='$(am__tagged_files)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile
|
||||
installdirs:
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am:
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
|
||||
clean-libtool cscopelist-am ctags ctags-am distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
|
||||
pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
allprogs: $(EXTRA_PROGRAMS)
|
||||
|
||||
$(top_builddir)/tests/libtests.la:
|
||||
cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
501
blender-5.2.0/extern/gmp-source/demos/expr/README
vendored
Normal file
501
blender-5.2.0/extern/gmp-source/demos/expr/README
vendored
Normal file
@@ -0,0 +1,501 @@
|
||||
Copyright 2001, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GMP EXPRESSION EVALUATION
|
||||
-------------------------
|
||||
|
||||
|
||||
|
||||
THIS CODE IS PRELIMINARY AND MAY BE SUBJECT TO INCOMPATIBLE CHANGES IN
|
||||
FUTURE VERSIONS OF GMP.
|
||||
|
||||
|
||||
|
||||
The files in this directory implement a simple scheme of string based
|
||||
expression parsing and evaluation, supporting mpz, mpq and mpf.
|
||||
|
||||
This will be slower than direct GMP library calls, but may be convenient in
|
||||
various circumstances, such as while prototyping, or for letting a user
|
||||
enter values in symbolic form. "2**5723-7" for example is a lot easier to
|
||||
enter or maintain than the equivalent written out in decimal.
|
||||
|
||||
|
||||
|
||||
BUILDING
|
||||
|
||||
Nothing in this directory is a normal part of libgmp, and nothing is built
|
||||
or installed, but various Makefile rules are available to compile
|
||||
everything.
|
||||
|
||||
All the functions are available through a little library (there's no shared
|
||||
library since upward binary compatibility is not guaranteed).
|
||||
|
||||
make libexpr.a
|
||||
|
||||
In a program, prototypes are available using
|
||||
|
||||
#include "expr.h"
|
||||
|
||||
run-expr.c is a sample program doing evaluations from the command line.
|
||||
|
||||
make run-expr
|
||||
./run-expr '1+2*3'
|
||||
|
||||
t-expr.c is self-test program, it prints nothing if successful.
|
||||
|
||||
make t-expr
|
||||
./t-expr
|
||||
|
||||
The expr*.c sources don't depend on gmp-impl.h and can be compiled with just
|
||||
a standard installed GMP. This isn't true of t-expr though, since it uses
|
||||
some of the internal tests/libtests.la.
|
||||
|
||||
|
||||
|
||||
SIMPLE USAGE
|
||||
|
||||
int mpz_expr (mpz_t res, int base, const char *e, ...);
|
||||
int mpq_expr (mpq_t res, int base, const char *e, ...);
|
||||
int mpf_expr (mpf_t res, int base, const char *e, ...);
|
||||
|
||||
These functions evaluate simple arithmetic expressions. For example,
|
||||
|
||||
mpz_expr (result, 0, "123+456", NULL);
|
||||
|
||||
Numbers are parsed by mpz_expr and mpq_expr the same as mpz_set_str with the
|
||||
given base. mpf_expr follows mpf_set_str, but supporting an "0x" prefix for
|
||||
hex when base==0.
|
||||
|
||||
mpz_expr (result, 0, "0xAAAA * 0x5555", NULL);
|
||||
|
||||
White space, as indicated by <ctype.h> isspace(), is ignored except for the
|
||||
purpose of separating tokens.
|
||||
|
||||
Variables can be included in expressions by putting them in the stdarg list
|
||||
after the string. "a", "b", "c" etc in the expression string designate
|
||||
those values. For example,
|
||||
|
||||
mpq_t foo, bar;
|
||||
...
|
||||
mpq_expr (q, 10, "2/3 + 1/a + b/2", foo, bar, NULL);
|
||||
|
||||
Here "a" will be the value from foo and "b" from bar. Up to 26 variables
|
||||
can be included this way. The NULL must be present to indicate the end of
|
||||
the list.
|
||||
|
||||
Variables can also be written "$a", "$b" etc. This is necessary when using
|
||||
bases greater than 10 since plain "a", "b" etc will otherwise be interpreted
|
||||
as numbers. For example,
|
||||
|
||||
mpf_t quux;
|
||||
mpf_expr (f, 16, "F00F@-6 * $a", quux, NULL);
|
||||
|
||||
All the standard C operators are available, with the usual precedences, plus
|
||||
"**" for exponentiation at the highest precedence (and right associative).
|
||||
|
||||
Operators Precedence
|
||||
** 220
|
||||
~ ! - (unary) 210
|
||||
* / % 200
|
||||
+ - 190
|
||||
<< >> 180
|
||||
<= < >= > 170
|
||||
== != 160
|
||||
& 150
|
||||
^ 140
|
||||
| 130
|
||||
&& 120
|
||||
|| 110
|
||||
? : 100/101
|
||||
|
||||
Currently only mpz_expr has the bitwise ~ % & ^ and | operators. The
|
||||
precedence numbers are of interest in the advanced usage described below.
|
||||
|
||||
Various functions are available too. For example,
|
||||
|
||||
mpz_expr (res, 10, "gcd(123,456,789) * abs(a)", var, NULL);
|
||||
|
||||
The following is the full set of functions,
|
||||
|
||||
mpz_expr
|
||||
abs bin clrbit cmp cmpabs congruent_p divisible_p even_p fib fac
|
||||
gcd hamdist invert jacobi kronecker lcm lucnum max min nextprime
|
||||
odd_p perfect_power_p perfect_square_p popcount powm
|
||||
probab_prime_p root scan0 scan1 setbit sgn sqrt
|
||||
|
||||
mpq_expr
|
||||
abs, cmp, den, max, min, num, sgn
|
||||
|
||||
mpf_expr
|
||||
abs, ceil, cmp, eq, floor, integer_p, max, min, reldiff, sgn,
|
||||
sqrt, trunc
|
||||
|
||||
All these are the same as the GMP library functions, except that min and max
|
||||
don't exist in the library. Note also that min, max, gcd and lcm take any
|
||||
number of arguments, not just two.
|
||||
|
||||
mpf_expr does all calculations to the precision of the destination variable.
|
||||
|
||||
|
||||
Expression parsing can succeed or fail. The return value indicates this,
|
||||
and will be one of the following
|
||||
|
||||
MPEXPR_RESULT_OK
|
||||
MPEXPR_RESULT_BAD_VARIABLE
|
||||
MPEXPR_RESULT_BAD_TABLE
|
||||
MPEXPR_RESULT_PARSE_ERROR
|
||||
MPEXPR_RESULT_NOT_UI
|
||||
|
||||
BAD_VARIABLE is when a variable is referenced that hasn't been provided.
|
||||
For example if "c" is used when only two parameters have been passed.
|
||||
BAD_TABLE is applicable to the advanced usage described below.
|
||||
|
||||
PARSE_ERROR is a general syntax error, returned for any mal-formed input
|
||||
string.
|
||||
|
||||
NOT_UI is returned when an attempt is made to use an operand that's bigger
|
||||
than an "unsigned long" with a function that's restricted to that range.
|
||||
For example "fib" is mpz_fib_ui and only accepts an "unsigned long".
|
||||
|
||||
|
||||
|
||||
|
||||
ADVANCED USAGE
|
||||
|
||||
int mpz_expr_a (const struct mpexpr_operator_t *table,
|
||||
mpz_ptr res, int base, const char *e, size_t elen,
|
||||
mpz_srcptr var[26])
|
||||
int mpq_expr_a (const struct mpexpr_operator_t *table,
|
||||
mpq_ptr res, int base, const char *e, size_t elen,
|
||||
mpq_srcptr var[26])
|
||||
int mpf_expr_a (const struct mpexpr_operator_t *table,
|
||||
mpf_ptr res, int base, unsigned long prec,
|
||||
const char *e, size_t elen,
|
||||
mpf_srcptr var[26])
|
||||
|
||||
These functions are an advanced interface to expression parsing.
|
||||
|
||||
The string is taken as pointer and length. This makes it possible to parse
|
||||
an expression in the middle of somewhere without copying and null
|
||||
terminating it.
|
||||
|
||||
Variables are an array of 26 pointers to the appropriate operands, or NULL
|
||||
for variables that are not available. Any combination of variables can be
|
||||
given, for example just "x" and "y" (var[23] and var[24]) could be set.
|
||||
|
||||
Operators and functions are specified with a table. This makes it possible
|
||||
to provide additional operators or functions, or to completely change the
|
||||
syntax. The standard tables used by the simple functions above are
|
||||
available as
|
||||
|
||||
const struct mpexpr_operator_t * const mpz_expr_standard_table;
|
||||
const struct mpexpr_operator_t * const mpq_expr_standard_table;
|
||||
const struct mpexpr_operator_t * const mpf_expr_standard_table;
|
||||
|
||||
struct mpexpr_operator_t is the following
|
||||
|
||||
struct mpexpr_operator_t {
|
||||
const char *name;
|
||||
mpexpr_fun_t fun;
|
||||
int type;
|
||||
int precedence;
|
||||
};
|
||||
|
||||
typedef void (*mpexpr_fun_t) (void);
|
||||
|
||||
As an example, the standard mpz_expr table entry for multiplication is as
|
||||
follows. See the source code for the full set of standard entries.
|
||||
|
||||
{ "*", (mpexpr_fun_t) mpz_mul, MPEXPR_TYPE_BINARY, 200 },
|
||||
|
||||
"name" is the string to parse, "fun" is the function to call for it, "type"
|
||||
indicates what parameters the function takes (among other things), and
|
||||
"precedence" sets its operator precedence.
|
||||
|
||||
A NULL for "name" indicates the end of the table, so for example an mpf
|
||||
table with nothing but addition could be
|
||||
|
||||
struct mpexpr_operator_t table[] = {
|
||||
{ "+", (mpexpr_fun_t) mpf_add, MPEXPR_TYPE_BINARY, 190 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
A special type MPEXPR_TYPE_NEW_TABLE makes it possible to chain from one
|
||||
table to another. For example the following would add a "mod" operator to
|
||||
the standard mpz table,
|
||||
|
||||
struct mpexpr_operator_t table[] = {
|
||||
{ "mod", (mpexpr_fun_t) mpz_fdiv_r, MPEXPR_TYPE_BINARY, 125 },
|
||||
{ (const char *) mpz_expr_standard_table, NULL, MPEXPR_TYPE_NEW_TABLE }
|
||||
};
|
||||
|
||||
Notice the low precedence on "mod", so that for instance "45+26 mod 7"
|
||||
parses as "(45+26)mod7".
|
||||
|
||||
|
||||
Functions are designated by a precedence of 0. They always occur as
|
||||
"foo(expr)" and so have no need for a precedence level. mpq_abs in the
|
||||
standard mpq table is
|
||||
|
||||
{ "abs", (mpexpr_fun_t) mpq_abs, MPEXPR_TYPE_UNARY },
|
||||
|
||||
Functions expecting no arguments as in "foo()" can be given with
|
||||
MPEXPR_TYPE_0ARY, or actual constants to be parsed as just "foo" are
|
||||
MPEXPR_TYPE_CONSTANT. For example if a "void mpf_const_pi(mpf_t f)"
|
||||
function existed (which it doesn't) it could be,
|
||||
|
||||
{ "pi", (mpexpr_fun_t) mpf_const_pi, MPEXPR_TYPE_CONSTANT },
|
||||
|
||||
|
||||
Parsing of operator names is done by seeking the table entry with the
|
||||
longest matching name. So for instance operators "<" and "<=" exist, and
|
||||
when presented with "x <= y" the parser matches "<=" because it's longer.
|
||||
|
||||
Parsing of function names, on the other hand, is done by requiring a whole
|
||||
alphanumeric word to match. For example presented with "fib2zz(5)" the
|
||||
parser will attempt to find a function called "fib2zz". A function "fib"
|
||||
wouldn't be used because it doesn't match the whole word.
|
||||
|
||||
The flag MPEXPR_TYPE_WHOLEWORD can be ORed into an operator type to override
|
||||
the default parsing style. Similarly MPEXPR_TYPE_OPERATOR into a function.
|
||||
|
||||
|
||||
Binary operators are left associative by default, meaning they're evaluated
|
||||
from left to right, so for example "1+2+3" is treated as "(1+2)+3".
|
||||
MPEXPR_TYPE_RIGHTASSOC can be ORed into the operator type to work from right
|
||||
to left as in "1+(2+3)". This is generally what's wanted for
|
||||
exponentiation, and for example the standard mpz table has
|
||||
|
||||
{ "**", (mpexpr_fun_t) mpz_pow_ui,
|
||||
MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 220 }
|
||||
|
||||
Unary operators are postfix by default. For example a factorial to be used
|
||||
as "123!" might be
|
||||
|
||||
{ "!", (mpexpr_fun_t) mpz_fac_ui, MPEXPR_TYPE_UNARY_UI, 215 }
|
||||
|
||||
MPEXPR_TYPE_PREFIX can be ORed into the type to get a prefix operator. For
|
||||
instance negation (unary minus) in the standard mpf table is
|
||||
|
||||
{ "-", (mpexpr_fun_t) mpf_neg,
|
||||
MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
|
||||
|
||||
|
||||
The same operator can exist as a prefix unary and a binary, or as a prefix
|
||||
and postfix unary, simply by putting two entries in the table. While
|
||||
parsing the context determines which style is sought. But note that the
|
||||
same operator can't be both a postfix unary and a binary, since the parser
|
||||
doesn't try to look ahead to decide which ought to be used.
|
||||
|
||||
When there's two entries for an operator, both prefix or both postfix (or
|
||||
binary), then the first in the table will be used. This makes it possible
|
||||
to override an entry in a standard table, for example to change the function
|
||||
it calls, or perhaps its precedence level. The following would change mpz
|
||||
division from tdiv to cdiv,
|
||||
|
||||
struct mpexpr_operator_t table[] = {
|
||||
{ "/", (mpexpr_fun_t) mpz_cdiv_q, MPEXPR_TYPE_BINARY, 200 },
|
||||
{ "%", (mpexpr_fun_t) mpz_cdiv_r, MPEXPR_TYPE_BINARY, 200 },
|
||||
{ (char *) mpz_expr_standard_table, NULL, MPEXPR_TYPE_NEW_TABLE }
|
||||
};
|
||||
|
||||
|
||||
The type field indicates what parameters the given function expects. The
|
||||
following styles of functions are supported. mpz_t is shown, but of course
|
||||
this is mpq_t for mpq_expr_a, mpf_t for mpf_expr_a, etc.
|
||||
|
||||
MPEXPR_TYPE_CONSTANT void func (mpz_t result);
|
||||
|
||||
MPEXPR_TYPE_0ARY void func (mpz_t result);
|
||||
MPEXPR_TYPE_I_0ARY int func (void);
|
||||
|
||||
MPEXPR_TYPE_UNARY void func (mpz_t result, mpz_t op);
|
||||
MPEXPR_TYPE_UNARY_UI void func (mpz_t result, unsigned long op);
|
||||
MPEXPR_TYPE_I_UNARY int func (mpz_t op);
|
||||
MPEXPR_TYPE_I_UNARY_UI int func (unsigned long op);
|
||||
|
||||
MPEXPR_TYPE_BINARY void func (mpz_t result, mpz_t op1, mpz_t op2);
|
||||
MPEXPR_TYPE_BINARY_UI void func (mpz_t result,
|
||||
mpz_t op1, unsigned long op2);
|
||||
MPEXPR_TYPE_I_BINARY int func (mpz_t op1, mpz_t op2);
|
||||
MPEXPR_TYPE_I_BINARY_UI int func (mpz_t op1, unsigned long op2);
|
||||
|
||||
MPEXPR_TYPE_TERNARY void func (mpz_t result,
|
||||
mpz_t op1, mpz_t op2, mpz_t op3);
|
||||
MPEXPR_TYPE_TERNARY_UI void func (mpz_t result, mpz_t op1, mpz_t op2,
|
||||
unsigned long op3);
|
||||
MPEXPR_TYPE_I_TERNARY int func (mpz_t op1, mpz_t op2, mpz_t op3);
|
||||
MPEXPR_TYPE_I_TERNARY_UI int func (mpz_t op1, mpz_t op2,
|
||||
unsigned long op3);
|
||||
|
||||
Notice the pattern of "UI" for the last parameter as an unsigned long, or
|
||||
"I" for the result as an "int" return value.
|
||||
|
||||
It's important that the declared type for an operator or function matches
|
||||
the function pointer given. Any mismatch will have unpredictable results.
|
||||
|
||||
For binary functions, a further type attribute is MPEXPR_TYPE_PAIRWISE which
|
||||
indicates that any number of arguments should be accepted, and evaluated by
|
||||
applying the given binary function to them pairwise. This is used by gcd,
|
||||
lcm, min and max. For example the standard mpz gcd is
|
||||
|
||||
{ "gcd", (mpexpr_fun_t) mpz_gcd,
|
||||
MPEXPR_TYPE_BINARY | MPEXPR_TYPE_PAIRWISE },
|
||||
|
||||
Some special types exist for comparison operators (or functions).
|
||||
MPEXPR_TYPE_CMP_LT through MPEXPR_TYPE_CMP_GE expect an MPEXPR_TYPE_I_BINARY
|
||||
function, returning positive, negative or zero like mpz_cmp and similar.
|
||||
For example the standard mpf "!=" operator is
|
||||
|
||||
{ "!=", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_NE, 160 },
|
||||
|
||||
But there's no obligation to use these types, for instance the standard mpq
|
||||
table just uses a plain MPEXPR_TYPE_I_BINARY and mpq_equal for "==".
|
||||
|
||||
Further special types MPEXPR_TYPE_MIN and MPEXPR_TYPE_MAX exist to implement
|
||||
the min and max functions, and they take a function like mpf_cmp similarly.
|
||||
The standard mpf max function is
|
||||
|
||||
{ "max", (mpexpr_fun_t) mpf_cmp,
|
||||
MPEXPR_TYPE_MAX | MPEXPR_TYPE_PAIRWISE },
|
||||
|
||||
These can be used as operators too, for instance the following would be the
|
||||
>? operator which is a feature of GNU C++,
|
||||
|
||||
{ ">?", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_MAX, 175 },
|
||||
|
||||
Other special types are used to define "(" ")" parentheses, "," function
|
||||
argument separator, "!" through "||" logical booleans, ternary "?" ":", and
|
||||
the "$" which introduces variables. See the sources for how they should be
|
||||
used.
|
||||
|
||||
|
||||
User definable operator tables will have various uses. For example,
|
||||
|
||||
- a subset of the C operators, to be rid of infrequently used things
|
||||
- a more mathematical syntax like "." for multiply, "^" for powering,
|
||||
and "!" for factorial
|
||||
- a boolean evaluator with "^" for AND, "v" for OR
|
||||
- variables introduced with "%" instead of "$"
|
||||
- brackets as "[" and "]" instead of "(" and ")"
|
||||
|
||||
The only fixed parts of the parsing are the treatment of numbers, whitespace
|
||||
and the two styles of operator/function name recognition.
|
||||
|
||||
As a final example, the following would be a complete mpz table implementing
|
||||
some operators with a more mathematical syntax. Notice there's no need to
|
||||
preserve the standard precedence values, anything can be used so long as
|
||||
they're in the desired relation to each other. There's also no need to have
|
||||
entries in precedence order, but it's convenient to do so to show what comes
|
||||
where.
|
||||
|
||||
static const struct mpexpr_operator_t table[] = {
|
||||
{ "^", (mpexpr_fun_t) mpz_pow_ui,
|
||||
MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 9 },
|
||||
|
||||
{ "!", (mpexpr_fun_t) mpz_fac_ui, MPEXPR_TYPE_UNARY_UI, 8 },
|
||||
{ "-", (mpexpr_fun_t) mpz_neg,
|
||||
MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 7 },
|
||||
|
||||
{ "*", (mpexpr_fun_t) mpz_mul, MPEXPR_TYPE_BINARY, 6 },
|
||||
{ "/", (mpexpr_fun_t) mpz_fdiv_q, MPEXPR_TYPE_BINARY, 6 },
|
||||
|
||||
{ "+", (mpexpr_fun_t) mpz_add, MPEXPR_TYPE_BINARY, 5 },
|
||||
{ "-", (mpexpr_fun_t) mpz_sub, MPEXPR_TYPE_BINARY, 5 },
|
||||
|
||||
{ "mod", (mpexpr_fun_t) mpz_mod, MPEXPR_TYPE_BINARY, 6 },
|
||||
|
||||
{ ")", NULL, MPEXPR_TYPE_CLOSEPAREN, 4 },
|
||||
{ "(", NULL, MPEXPR_TYPE_OPENPAREN, 3 },
|
||||
{ ",", NULL, MPEXPR_TYPE_ARGSEP, 2 },
|
||||
|
||||
{ "$", NULL, MPEXPR_TYPE_VARIABLE, 1 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
INTERNALS
|
||||
|
||||
Operator precedence is implemented using a control and data stack, there's
|
||||
no C recursion. When an expression like 1+2*3 is read the "+" is held on
|
||||
the control stack and 1 on the data stack until "*" has been parsed and
|
||||
applied to 2 and 3. This happens any time a higher precedence operator
|
||||
follows a lower one, or when a right-associative operator like "**" is
|
||||
repeated.
|
||||
|
||||
Parentheses are handled by making "(" a special prefix unary with a low
|
||||
precedence so a whole following expression is read. The special operator
|
||||
")" knows to discard the pending "(". Function arguments are handled
|
||||
similarly, with the function pretending to be a low precedence prefix unary
|
||||
operator, and with "," allowed within functions. The same special ")"
|
||||
operator recognises a pending function and will invoke it appropriately.
|
||||
|
||||
The ternary "? :" operator is also handled using precedences. ":" is one
|
||||
level higher than "?", so when a valid a?b:c is parsed the ":" finds a "?"
|
||||
on the control stack. It's a parse error for ":" to find anything else.
|
||||
|
||||
|
||||
|
||||
FUTURE
|
||||
|
||||
The ternary "?:" operator evaluates the "false" side of its pair, which is
|
||||
wasteful, though it ought to be harmless. It'd be better if it could
|
||||
evaluate only the "true" side. Similarly for the logical booleans "&&" and
|
||||
"||" if they know their result already.
|
||||
|
||||
Functions like MPEXPR_TYPE_BINARY could return a status indicating operand
|
||||
out of range or whatever, to get an error back through mpz_expr etc. That
|
||||
would want to be just an option, since plain mpz_add etc have no such
|
||||
return.
|
||||
|
||||
Could have assignments like "a = b*c" modifying the input variables.
|
||||
Assignment could be an operator attribute, making it expect an lvalue.
|
||||
There would want to be a standard table without assignments available
|
||||
though, so user input could be safely parsed.
|
||||
|
||||
The closing parenthesis table entry could specify the type of open paren it
|
||||
expects, so that "(" and ")" could match and "[" and "]" match but not a
|
||||
mixture of the two. Currently "[" and "]" can be added, but there's no
|
||||
error on writing a mixed expression like "2*(3+4]". Maybe also there could
|
||||
be a way to say that functions can only be written with one or the other
|
||||
style of parens.
|
||||
|
||||
|
||||
|
||||
----------------
|
||||
Local variables:
|
||||
mode: text
|
||||
fill-column: 76
|
||||
End:
|
||||
125
blender-5.2.0/extern/gmp-source/demos/expr/expr-impl.h
vendored
Normal file
125
blender-5.2.0/extern/gmp-source/demos/expr/expr-impl.h
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/* Implementation specifics for expression evaluation.
|
||||
|
||||
Copyright 2000-2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "expr.h"
|
||||
|
||||
|
||||
#define isasciidigit(c) (isascii (c) && isdigit (c))
|
||||
#define isasciicsym(c) (isascii (c) && (isalnum(c) || (c) == '_'))
|
||||
|
||||
#define isasciidigit_in_base(c,base) \
|
||||
(isascii (c) \
|
||||
&& ((isdigit (c) && (c)-'0' < (base)) \
|
||||
|| (isupper (c) && (c)-'A'+10 < (base)) \
|
||||
|| (islower (c) && (c)-'a'+10 < (base))))
|
||||
|
||||
|
||||
union mpX_t {
|
||||
mpz_t z;
|
||||
mpq_t q;
|
||||
mpf_t f;
|
||||
};
|
||||
|
||||
typedef union mpX_t *mpX_ptr;
|
||||
typedef const union mpX_t *mpX_srcptr;
|
||||
|
||||
typedef void (*mpexpr_fun_one_t) (mpX_ptr);
|
||||
typedef unsigned long (*mpexpr_fun_ui_one_t) (mpX_ptr);
|
||||
|
||||
typedef void (*mpexpr_fun_0ary_t) (mpX_ptr);
|
||||
typedef int (*mpexpr_fun_i_0ary_t) (void);
|
||||
|
||||
typedef void (*mpexpr_fun_unary_t) (mpX_ptr, mpX_srcptr);
|
||||
typedef void (*mpexpr_fun_unary_ui_t) (mpX_ptr, unsigned long);
|
||||
typedef int (*mpexpr_fun_i_unary_t) (mpX_srcptr);
|
||||
typedef int (*mpexpr_fun_i_unary_ui_t) (unsigned long);
|
||||
|
||||
typedef void (*mpexpr_fun_binary_t) (mpX_ptr, mpX_srcptr, mpX_srcptr);
|
||||
typedef void (*mpexpr_fun_binary_ui_t) (mpX_ptr, mpX_srcptr, unsigned long);
|
||||
typedef int (*mpexpr_fun_i_binary_t) (mpX_srcptr, mpX_srcptr);
|
||||
typedef int (*mpexpr_fun_i_binary_ui_t) (mpX_srcptr, unsigned long);
|
||||
|
||||
typedef void (*mpexpr_fun_ternary_t) (mpX_ptr, mpX_srcptr, mpX_srcptr, mpX_srcptr);
|
||||
typedef void (*mpexpr_fun_ternary_ui_t) (mpX_ptr, mpX_srcptr, mpX_srcptr, unsigned long);
|
||||
typedef int (*mpexpr_fun_i_ternary_t) (mpX_srcptr, mpX_srcptr, mpX_srcptr);
|
||||
typedef int (*mpexpr_fun_i_ternary_ui_t) (mpX_srcptr, mpX_srcptr, unsigned long);
|
||||
|
||||
typedef size_t (*mpexpr_fun_number_t) (mpX_ptr, const char *str, size_t len, int base);
|
||||
typedef void (*mpexpr_fun_swap_t) (mpX_ptr, mpX_ptr);
|
||||
typedef unsigned long (*mpexpr_fun_get_ui_t) (mpX_srcptr);
|
||||
typedef void (*mpexpr_fun_set_si_t) (mpX_srcptr, long);
|
||||
|
||||
struct mpexpr_control_t {
|
||||
const struct mpexpr_operator_t *op;
|
||||
int argcount;
|
||||
};
|
||||
|
||||
#define MPEXPR_VARIABLES 26
|
||||
|
||||
struct mpexpr_parse_t {
|
||||
const struct mpexpr_operator_t *table;
|
||||
|
||||
mpX_ptr res;
|
||||
int base;
|
||||
unsigned long prec;
|
||||
const char *e;
|
||||
size_t elen;
|
||||
mpX_srcptr *var;
|
||||
int error_code;
|
||||
|
||||
int token;
|
||||
const struct mpexpr_operator_t *token_op;
|
||||
|
||||
union mpX_t *data_stack;
|
||||
int data_top;
|
||||
int data_alloc;
|
||||
int data_inited;
|
||||
|
||||
struct mpexpr_control_t *control_stack;
|
||||
int control_top;
|
||||
int control_alloc;
|
||||
|
||||
mpexpr_fun_0ary_t mpX_clear;
|
||||
mpexpr_fun_i_unary_t mpX_ulong_p;
|
||||
mpexpr_fun_get_ui_t mpX_get_ui;
|
||||
mpexpr_fun_unary_ui_t mpX_init;
|
||||
mpexpr_fun_number_t mpX_number;
|
||||
mpexpr_fun_unary_t mpX_set;
|
||||
mpexpr_fun_unary_t mpX_set_or_swap;
|
||||
mpexpr_fun_set_si_t mpX_set_si;
|
||||
mpexpr_fun_swap_t mpX_swap;
|
||||
};
|
||||
|
||||
|
||||
int mpexpr_evaluate (struct mpexpr_parse_t *p);
|
||||
int mpexpr_va_to_var (void *var[], va_list ap);
|
||||
size_t mpexpr_mpz_number (mpz_ptr res, const char *e, size_t elen, int base);
|
||||
834
blender-5.2.0/extern/gmp-source/demos/expr/expr.c
vendored
Normal file
834
blender-5.2.0/extern/gmp-source/demos/expr/expr.c
vendored
Normal file
@@ -0,0 +1,834 @@
|
||||
/* mpexpr_evaluate -- shared code for simple expression evaluation
|
||||
|
||||
Copyright 2000-2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gmp.h"
|
||||
#include "expr-impl.h"
|
||||
|
||||
|
||||
/* Change this to "#define TRACE(x) x" to get some traces. The trace
|
||||
printfs junk up the code a bit, but it's very hard to tell what's going
|
||||
on without them. Set MPX_TRACE to a suitable output function for the
|
||||
mpz/mpq/mpf being run (if you have the wrong trace function it'll
|
||||
probably segv). */
|
||||
|
||||
#define TRACE(x)
|
||||
#define MPX_TRACE mpz_trace
|
||||
|
||||
|
||||
/* A few helper macros copied from gmp-impl.h */
|
||||
#define ALLOCATE_FUNC_TYPE(n,type) \
|
||||
((type *) (*allocate_func) ((n) * sizeof (type)))
|
||||
#define ALLOCATE_FUNC_LIMBS(n) ALLOCATE_FUNC_TYPE (n, mp_limb_t)
|
||||
#define REALLOCATE_FUNC_TYPE(p, old_size, new_size, type) \
|
||||
((type *) (*reallocate_func) \
|
||||
(p, (old_size) * sizeof (type), (new_size) * sizeof (type)))
|
||||
#define REALLOCATE_FUNC_LIMBS(p, old_size, new_size) \
|
||||
REALLOCATE_FUNC_TYPE(p, old_size, new_size, mp_limb_t)
|
||||
#define FREE_FUNC_TYPE(p,n,type) (*free_func) (p, (n) * sizeof (type))
|
||||
#define FREE_FUNC_LIMBS(p,n) FREE_FUNC_TYPE (p, n, mp_limb_t)
|
||||
#define ASSERT(x)
|
||||
|
||||
|
||||
|
||||
/* All the error strings are just for diagnostic traces. Only the error
|
||||
code is actually returned. */
|
||||
#define ERROR(str,code) \
|
||||
{ \
|
||||
TRACE (printf ("%s\n", str)); \
|
||||
p->error_code = (code); \
|
||||
goto done; \
|
||||
}
|
||||
|
||||
|
||||
#define REALLOC(ptr, alloc, incr, type) \
|
||||
do { \
|
||||
int new_alloc = (alloc) + (incr); \
|
||||
ptr = REALLOCATE_FUNC_TYPE (ptr, alloc, new_alloc, type); \
|
||||
(alloc) = new_alloc; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* data stack top element */
|
||||
#define SP (p->data_stack + p->data_top)
|
||||
|
||||
/* Make sure there's room for another data element above current top.
|
||||
reallocate_func is fetched for when this macro is used in lookahead(). */
|
||||
#define DATA_SPACE() \
|
||||
do { \
|
||||
if (p->data_top + 1 >= p->data_alloc) \
|
||||
{ \
|
||||
void *(*reallocate_func) (void *, size_t, size_t); \
|
||||
mp_get_memory_functions (NULL, &reallocate_func, NULL); \
|
||||
TRACE (printf ("grow stack from %d\n", p->data_alloc)); \
|
||||
REALLOC (p->data_stack, p->data_alloc, 20, union mpX_t); \
|
||||
} \
|
||||
ASSERT (p->data_top + 1 <= p->data_inited); \
|
||||
if (p->data_top + 1 == p->data_inited) \
|
||||
{ \
|
||||
TRACE (printf ("initialize %d\n", p->data_top + 1)); \
|
||||
(*p->mpX_init) (&p->data_stack[p->data_top + 1], p->prec); \
|
||||
p->data_inited++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DATA_PUSH() \
|
||||
do { \
|
||||
p->data_top++; \
|
||||
ASSERT (p->data_top < p->data_alloc); \
|
||||
ASSERT (p->data_top < p->data_inited); \
|
||||
} while (0)
|
||||
|
||||
/* the last stack entry is never popped, so top>=0 will be true */
|
||||
#define DATA_POP(n) \
|
||||
do { \
|
||||
p->data_top -= (n); \
|
||||
ASSERT (p->data_top >= 0); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* lookahead() parses the next token. Return 1 if successful, with some
|
||||
extra data. Return 0 if fail, with reason in p->error_code.
|
||||
|
||||
"prefix" is MPEXPR_TYPE_PREFIX if an operator with that attribute is
|
||||
preferred, or 0 if an operator without is preferred. */
|
||||
|
||||
#define TOKEN_EOF -1 /* no extra data */
|
||||
#define TOKEN_VALUE -2 /* pushed onto data stack */
|
||||
#define TOKEN_OPERATOR -3 /* stored in p->token_op */
|
||||
#define TOKEN_FUNCTION -4 /* stored in p->token_op */
|
||||
|
||||
#define TOKEN_NAME(n) \
|
||||
((n) == TOKEN_EOF ? "TOKEN_EOF" \
|
||||
: (n) == TOKEN_VALUE ? "TOKEN_VALUE" \
|
||||
: (n) == TOKEN_OPERATOR ? "TOKEN_OPERATOR" \
|
||||
: (n) == TOKEN_VALUE ? "TOKEN_FUNCTION" \
|
||||
: "UNKNOWN TOKEN")
|
||||
|
||||
/* Functions default to being parsed as whole words, operators to match just
|
||||
at the start of the string. The type flags override this. */
|
||||
#define WHOLEWORD(op) \
|
||||
(op->precedence == 0 \
|
||||
? (! (op->type & MPEXPR_TYPE_OPERATOR)) \
|
||||
: (op->type & MPEXPR_TYPE_WHOLEWORD))
|
||||
|
||||
#define isasciispace(c) (isascii (c) && isspace (c))
|
||||
|
||||
static int
|
||||
lookahead (struct mpexpr_parse_t *p, int prefix)
|
||||
{
|
||||
const struct mpexpr_operator_t *op, *op_found;
|
||||
size_t oplen, oplen_found, wlen;
|
||||
int i;
|
||||
|
||||
/* skip white space */
|
||||
while (p->elen > 0 && isasciispace (*p->e))
|
||||
p->e++, p->elen--;
|
||||
|
||||
if (p->elen == 0)
|
||||
{
|
||||
TRACE (printf ("lookahead EOF\n"));
|
||||
p->token = TOKEN_EOF;
|
||||
return 1;
|
||||
}
|
||||
|
||||
DATA_SPACE ();
|
||||
|
||||
/* Get extent of whole word. */
|
||||
for (wlen = 0; wlen < p->elen; wlen++)
|
||||
if (! isasciicsym (p->e[wlen]))
|
||||
break;
|
||||
|
||||
TRACE (printf ("lookahead at: \"%.*s\" length %u, word %u\n",
|
||||
(int) p->elen, p->e, p->elen, wlen));
|
||||
|
||||
op_found = NULL;
|
||||
oplen_found = 0;
|
||||
for (op = p->table; op->name != NULL; op++)
|
||||
{
|
||||
if (op->type == MPEXPR_TYPE_NEW_TABLE)
|
||||
{
|
||||
printf ("new\n");
|
||||
op = (struct mpexpr_operator_t *) op->name - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
oplen = strlen (op->name);
|
||||
if (! ((WHOLEWORD (op) ? wlen == oplen : p->elen >= oplen)
|
||||
&& memcmp (p->e, op->name, oplen) == 0))
|
||||
continue;
|
||||
|
||||
/* Shorter matches don't replace longer previous ones. */
|
||||
if (op_found && oplen < oplen_found)
|
||||
continue;
|
||||
|
||||
/* On a match of equal length to a previous one, the old match isn't
|
||||
replaced if it has the preferred prefix, and if it doesn't then
|
||||
it's not replaced if the new one also doesn't. */
|
||||
if (op_found && oplen == oplen_found
|
||||
&& ((op_found->type & MPEXPR_TYPE_PREFIX) == prefix
|
||||
|| (op->type & MPEXPR_TYPE_PREFIX) != prefix))
|
||||
continue;
|
||||
|
||||
/* This is now either the first match seen, or a longer than previous
|
||||
match, or an equal to previous one but with a preferred prefix. */
|
||||
op_found = op;
|
||||
oplen_found = oplen;
|
||||
}
|
||||
|
||||
if (op_found)
|
||||
{
|
||||
p->e += oplen_found, p->elen -= oplen_found;
|
||||
|
||||
if (op_found->type == MPEXPR_TYPE_VARIABLE)
|
||||
{
|
||||
if (p->elen == 0)
|
||||
ERROR ("end of string expecting a variable",
|
||||
MPEXPR_RESULT_PARSE_ERROR);
|
||||
i = p->e[0] - 'a';
|
||||
if (i < 0 || i >= MPEXPR_VARIABLES)
|
||||
ERROR ("bad variable name", MPEXPR_RESULT_BAD_VARIABLE);
|
||||
goto variable;
|
||||
}
|
||||
|
||||
if (op_found->precedence == 0)
|
||||
{
|
||||
TRACE (printf ("lookahead function: %s\n", op_found->name));
|
||||
p->token = TOKEN_FUNCTION;
|
||||
p->token_op = op_found;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE (printf ("lookahead operator: %s\n", op_found->name));
|
||||
p->token = TOKEN_OPERATOR;
|
||||
p->token_op = op_found;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
oplen = (*p->mpX_number) (SP+1, p->e, p->elen, p->base);
|
||||
if (oplen != 0)
|
||||
{
|
||||
p->e += oplen, p->elen -= oplen;
|
||||
p->token = TOKEN_VALUE;
|
||||
DATA_PUSH ();
|
||||
TRACE (MPX_TRACE ("lookahead number", SP));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Maybe an unprefixed one character variable */
|
||||
i = p->e[0] - 'a';
|
||||
if (wlen == 1 && i >= 0 && i < MPEXPR_VARIABLES)
|
||||
{
|
||||
variable:
|
||||
p->e++, p->elen--;
|
||||
if (p->var[i] == NULL)
|
||||
ERROR ("NULL variable", MPEXPR_RESULT_BAD_VARIABLE);
|
||||
TRACE (printf ("lookahead variable: var[%d] = ", i);
|
||||
MPX_TRACE ("", p->var[i]));
|
||||
p->token = TOKEN_VALUE;
|
||||
DATA_PUSH ();
|
||||
(*p->mpX_set) (SP, p->var[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ERROR ("no token matched", MPEXPR_RESULT_PARSE_ERROR);
|
||||
|
||||
done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* control stack current top element */
|
||||
#define CP (p->control_stack + p->control_top)
|
||||
|
||||
/* make sure there's room for another control element above current top */
|
||||
#define CONTROL_SPACE() \
|
||||
do { \
|
||||
if (p->control_top + 1 >= p->control_alloc) \
|
||||
{ \
|
||||
TRACE (printf ("grow control stack from %d\n", p->control_alloc)); \
|
||||
REALLOC (p->control_stack, p->control_alloc, 20, \
|
||||
struct mpexpr_control_t); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Push an operator on the control stack, claiming currently to have the
|
||||
given number of args ready. Local variable "op" is used in case opptr is
|
||||
a reference through CP. */
|
||||
#define CONTROL_PUSH(opptr,args) \
|
||||
do { \
|
||||
const struct mpexpr_operator_t *op = opptr; \
|
||||
struct mpexpr_control_t *cp; \
|
||||
CONTROL_SPACE (); \
|
||||
p->control_top++; \
|
||||
ASSERT (p->control_top < p->control_alloc); \
|
||||
cp = CP; \
|
||||
cp->op = op; \
|
||||
cp->argcount = (args); \
|
||||
TRACE_CONTROL("control stack push:"); \
|
||||
} while (0)
|
||||
|
||||
/* The special operator_done is never popped, so top>=0 will hold. */
|
||||
#define CONTROL_POP() \
|
||||
do { \
|
||||
p->control_top--; \
|
||||
ASSERT (p->control_top >= 0); \
|
||||
TRACE_CONTROL ("control stack pop:"); \
|
||||
} while (0)
|
||||
|
||||
#define TRACE_CONTROL(str) \
|
||||
TRACE ({ \
|
||||
int i; \
|
||||
printf ("%s depth %d:", str, p->control_top); \
|
||||
for (i = 0; i <= p->control_top; i++) \
|
||||
printf (" \"%s\"(%d)", \
|
||||
p->control_stack[i].op->name, \
|
||||
p->control_stack[i].argcount); \
|
||||
printf ("\n"); \
|
||||
});
|
||||
|
||||
|
||||
#define LOOKAHEAD(prefix) \
|
||||
do { \
|
||||
if (! lookahead (p, prefix)) \
|
||||
goto done; \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_UI(n) \
|
||||
do { \
|
||||
if (! (*p->mpX_ulong_p) (n)) \
|
||||
ERROR ("operand doesn't fit ulong", MPEXPR_RESULT_NOT_UI); \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_ARGCOUNT(str,n) \
|
||||
do { \
|
||||
if (CP->argcount != (n)) \
|
||||
{ \
|
||||
TRACE (printf ("wrong number of arguments for %s, got %d want %d", \
|
||||
str, CP->argcount, n)); \
|
||||
ERROR ("", MPEXPR_RESULT_PARSE_ERROR); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* There's two basic states here. In both p->token is the next token.
|
||||
|
||||
"another_expr" is when a whole expression should be parsed. This means a
|
||||
literal or variable value possibly followed by an operator, or a function
|
||||
or prefix operator followed by a further whole expression.
|
||||
|
||||
"another_operator" is when an expression has been parsed and its value is
|
||||
on the top of the data stack (SP) and an optional further postfix or
|
||||
infix operator should be parsed.
|
||||
|
||||
In "another_operator" precedences determine whether to push the operator
|
||||
onto the control stack, or instead go to "apply_control" to reduce the
|
||||
operator currently on top of the control stack.
|
||||
|
||||
When an operator has both a prefix and postfix/infix form, a LOOKAHEAD()
|
||||
for "another_expr" will seek the prefix form, a LOOKAHEAD() for
|
||||
"another_operator" will seek the postfix/infix form. The grammar is
|
||||
simple enough that the next state is known before reading the next token.
|
||||
|
||||
Argument count checking guards against functions consuming the wrong
|
||||
number of operands from the data stack. The same checks are applied to
|
||||
operators, but will always pass since a UNARY or BINARY will only ever
|
||||
parse with the correct operands. */
|
||||
|
||||
int
|
||||
mpexpr_evaluate (struct mpexpr_parse_t *p)
|
||||
{
|
||||
void *(*allocate_func) (size_t);
|
||||
void *(*reallocate_func) (void *, size_t, size_t);
|
||||
void (*free_func) (void *, size_t);
|
||||
|
||||
mp_get_memory_functions (&allocate_func, &reallocate_func, &free_func);
|
||||
|
||||
TRACE (printf ("mpexpr_evaluate() base %d \"%.*s\"\n",
|
||||
p->base, (int) p->elen, p->e));
|
||||
|
||||
/* "done" is a special sentinel at the bottom of the control stack,
|
||||
precedence -1 is lower than any normal operator. */
|
||||
{
|
||||
static const struct mpexpr_operator_t operator_done
|
||||
= { "DONE", NULL, MPEXPR_TYPE_DONE, -1 };
|
||||
|
||||
p->control_alloc = 20;
|
||||
p->control_stack = ALLOCATE_FUNC_TYPE (p->control_alloc,
|
||||
struct mpexpr_control_t);
|
||||
p->control_top = 0;
|
||||
CP->op = &operator_done;
|
||||
CP->argcount = 1;
|
||||
}
|
||||
|
||||
p->data_inited = 0;
|
||||
p->data_alloc = 20;
|
||||
p->data_stack = ALLOCATE_FUNC_TYPE (p->data_alloc, union mpX_t);
|
||||
p->data_top = -1;
|
||||
|
||||
p->error_code = MPEXPR_RESULT_OK;
|
||||
|
||||
|
||||
another_expr_lookahead:
|
||||
LOOKAHEAD (MPEXPR_TYPE_PREFIX);
|
||||
TRACE (printf ("another expr\n"));
|
||||
|
||||
/*another_expr:*/
|
||||
switch (p->token) {
|
||||
case TOKEN_VALUE:
|
||||
goto another_operator_lookahead;
|
||||
|
||||
case TOKEN_OPERATOR:
|
||||
TRACE (printf ("operator %s\n", p->token_op->name));
|
||||
if (! (p->token_op->type & MPEXPR_TYPE_PREFIX))
|
||||
ERROR ("expected a prefix operator", MPEXPR_RESULT_PARSE_ERROR);
|
||||
|
||||
CONTROL_PUSH (p->token_op, 1);
|
||||
goto another_expr_lookahead;
|
||||
|
||||
case TOKEN_FUNCTION:
|
||||
CONTROL_PUSH (p->token_op, 1);
|
||||
|
||||
if (p->token_op->type & MPEXPR_TYPE_CONSTANT)
|
||||
goto apply_control_lookahead;
|
||||
|
||||
LOOKAHEAD (MPEXPR_TYPE_PREFIX);
|
||||
if (! (p->token == TOKEN_OPERATOR
|
||||
&& p->token_op->type == MPEXPR_TYPE_OPENPAREN))
|
||||
ERROR ("expected open paren for function", MPEXPR_RESULT_PARSE_ERROR);
|
||||
|
||||
TRACE (printf ("open paren for function \"%s\"\n", CP->op->name));
|
||||
|
||||
if ((CP->op->type & MPEXPR_TYPE_MASK_ARGCOUNT) == MPEXPR_TYPE_NARY(0))
|
||||
{
|
||||
LOOKAHEAD (0);
|
||||
if (! (p->token == TOKEN_OPERATOR
|
||||
&& p->token_op->type == MPEXPR_TYPE_CLOSEPAREN))
|
||||
ERROR ("expected close paren for 0ary function",
|
||||
MPEXPR_RESULT_PARSE_ERROR);
|
||||
goto apply_control_lookahead;
|
||||
}
|
||||
|
||||
goto another_expr_lookahead;
|
||||
}
|
||||
ERROR ("unrecognised start of expression", MPEXPR_RESULT_PARSE_ERROR);
|
||||
|
||||
|
||||
another_operator_lookahead:
|
||||
LOOKAHEAD (0);
|
||||
another_operator:
|
||||
TRACE (printf ("another operator maybe: %s\n", TOKEN_NAME(p->token)));
|
||||
|
||||
switch (p->token) {
|
||||
case TOKEN_EOF:
|
||||
goto apply_control;
|
||||
|
||||
case TOKEN_OPERATOR:
|
||||
/* The next operator is compared to the one on top of the control stack.
|
||||
If the next is lower precedence, or the same precedence and not
|
||||
right-associative, then reduce using the control stack and look at
|
||||
the next operator again later. */
|
||||
|
||||
#define PRECEDENCE_TEST_REDUCE(tprec,cprec,ttype,ctype) \
|
||||
((tprec) < (cprec) \
|
||||
|| ((tprec) == (cprec) && ! ((ttype) & MPEXPR_TYPE_RIGHTASSOC)))
|
||||
|
||||
if (PRECEDENCE_TEST_REDUCE (p->token_op->precedence, CP->op->precedence,
|
||||
p->token_op->type, CP->op->type))
|
||||
{
|
||||
TRACE (printf ("defer operator: %s (prec %d vs %d, type 0x%X)\n",
|
||||
p->token_op->name,
|
||||
p->token_op->precedence, CP->op->precedence,
|
||||
p->token_op->type));
|
||||
goto apply_control;
|
||||
}
|
||||
|
||||
/* An argsep is a binary operator, but is never pushed on the control
|
||||
stack, it just accumulates an extra argument for a function. */
|
||||
if (p->token_op->type == MPEXPR_TYPE_ARGSEP)
|
||||
{
|
||||
if (CP->op->precedence != 0)
|
||||
ERROR ("ARGSEP not in a function call", MPEXPR_RESULT_PARSE_ERROR);
|
||||
|
||||
TRACE (printf ("argsep for function \"%s\"(%d)\n",
|
||||
CP->op->name, CP->argcount));
|
||||
|
||||
#define IS_PAIRWISE(type) \
|
||||
(((type) & (MPEXPR_TYPE_MASK_ARGCOUNT | MPEXPR_TYPE_PAIRWISE)) \
|
||||
== (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_PAIRWISE))
|
||||
|
||||
if (IS_PAIRWISE (CP->op->type) && CP->argcount >= 2)
|
||||
{
|
||||
TRACE (printf (" will reduce pairwise now\n"));
|
||||
CP->argcount--;
|
||||
CONTROL_PUSH (CP->op, 2);
|
||||
goto apply_control;
|
||||
}
|
||||
|
||||
CP->argcount++;
|
||||
goto another_expr_lookahead;
|
||||
}
|
||||
|
||||
switch (p->token_op->type & MPEXPR_TYPE_MASK_ARGCOUNT) {
|
||||
case MPEXPR_TYPE_NARY(1):
|
||||
/* Postfix unary operators can always be applied immediately. The
|
||||
easiest way to do this is just push it on the control stack and go
|
||||
to the normal control stack reduction code. */
|
||||
|
||||
TRACE (printf ("postfix unary operator: %s\n", p->token_op->name));
|
||||
if (p->token_op->type & MPEXPR_TYPE_PREFIX)
|
||||
ERROR ("prefix unary operator used postfix",
|
||||
MPEXPR_RESULT_PARSE_ERROR);
|
||||
CONTROL_PUSH (p->token_op, 1);
|
||||
goto apply_control_lookahead;
|
||||
|
||||
case MPEXPR_TYPE_NARY(2):
|
||||
CONTROL_PUSH (p->token_op, 2);
|
||||
goto another_expr_lookahead;
|
||||
|
||||
case MPEXPR_TYPE_NARY(3):
|
||||
CONTROL_PUSH (p->token_op, 1);
|
||||
goto another_expr_lookahead;
|
||||
}
|
||||
|
||||
TRACE (printf ("unrecognised operator \"%s\" type: 0x%X",
|
||||
CP->op->name, CP->op->type));
|
||||
ERROR ("", MPEXPR_RESULT_PARSE_ERROR);
|
||||
break;
|
||||
|
||||
default:
|
||||
TRACE (printf ("expecting an operator, got token %d", p->token));
|
||||
ERROR ("", MPEXPR_RESULT_PARSE_ERROR);
|
||||
}
|
||||
|
||||
|
||||
apply_control_lookahead:
|
||||
LOOKAHEAD (0);
|
||||
apply_control:
|
||||
/* Apply the top element CP of the control stack. Data values are SP,
|
||||
SP-1, etc. Result is left as stack top SP after popping consumed
|
||||
values.
|
||||
|
||||
The use of sp as a duplicate of SP will help compilers that can't
|
||||
otherwise recognise the various uses of SP as common subexpressions. */
|
||||
|
||||
TRACE (printf ("apply control: nested %d, \"%s\" 0x%X, %d args\n",
|
||||
p->control_top, CP->op->name, CP->op->type, CP->argcount));
|
||||
|
||||
TRACE (printf ("apply 0x%X-ary\n",
|
||||
CP->op->type & MPEXPR_TYPE_MASK_ARGCOUNT));
|
||||
switch (CP->op->type & MPEXPR_TYPE_MASK_ARGCOUNT) {
|
||||
case MPEXPR_TYPE_NARY(0):
|
||||
{
|
||||
mpX_ptr sp;
|
||||
DATA_SPACE ();
|
||||
DATA_PUSH ();
|
||||
sp = SP;
|
||||
switch (CP->op->type & MPEXPR_TYPE_MASK_ARGSTYLE) {
|
||||
case 0:
|
||||
(* (mpexpr_fun_0ary_t) CP->op->fun) (sp);
|
||||
break;
|
||||
case MPEXPR_TYPE_RESULT_INT:
|
||||
(*p->mpX_set_si) (sp, (long) (* (mpexpr_fun_i_0ary_t) CP->op->fun) ());
|
||||
break;
|
||||
default:
|
||||
ERROR ("unrecognised 0ary argument calling style",
|
||||
MPEXPR_RESULT_BAD_TABLE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MPEXPR_TYPE_NARY(1):
|
||||
{
|
||||
mpX_ptr sp = SP;
|
||||
CHECK_ARGCOUNT ("unary", 1);
|
||||
TRACE (MPX_TRACE ("before", sp));
|
||||
|
||||
switch (CP->op->type & MPEXPR_TYPE_MASK_SPECIAL) {
|
||||
case 0:
|
||||
/* not a special */
|
||||
break;
|
||||
|
||||
case MPEXPR_TYPE_DONE & MPEXPR_TYPE_MASK_SPECIAL:
|
||||
TRACE (printf ("special done\n"));
|
||||
goto done;
|
||||
|
||||
case MPEXPR_TYPE_LOGICAL_NOT & MPEXPR_TYPE_MASK_SPECIAL:
|
||||
TRACE (printf ("special logical not\n"));
|
||||
(*p->mpX_set_si)
|
||||
(sp, (long) ((* (mpexpr_fun_i_unary_t) CP->op->fun) (sp) == 0));
|
||||
goto apply_control_done;
|
||||
|
||||
case MPEXPR_TYPE_CLOSEPAREN & MPEXPR_TYPE_MASK_SPECIAL:
|
||||
CONTROL_POP ();
|
||||
if (CP->op->type == MPEXPR_TYPE_OPENPAREN)
|
||||
{
|
||||
TRACE (printf ("close paren matching open paren\n"));
|
||||
CONTROL_POP ();
|
||||
goto another_operator;
|
||||
}
|
||||
if (CP->op->precedence == 0)
|
||||
{
|
||||
TRACE (printf ("close paren for function\n"));
|
||||
goto apply_control;
|
||||
}
|
||||
ERROR ("unexpected close paren", MPEXPR_RESULT_PARSE_ERROR);
|
||||
|
||||
default:
|
||||
TRACE (printf ("unrecognised special unary operator 0x%X",
|
||||
CP->op->type & MPEXPR_TYPE_MASK_SPECIAL));
|
||||
ERROR ("", MPEXPR_RESULT_BAD_TABLE);
|
||||
}
|
||||
|
||||
switch (CP->op->type & MPEXPR_TYPE_MASK_ARGSTYLE) {
|
||||
case 0:
|
||||
(* (mpexpr_fun_unary_t) CP->op->fun) (sp, sp);
|
||||
break;
|
||||
case MPEXPR_TYPE_LAST_UI:
|
||||
CHECK_UI (sp);
|
||||
(* (mpexpr_fun_unary_ui_t) CP->op->fun)
|
||||
(sp, (*p->mpX_get_ui) (sp));
|
||||
break;
|
||||
case MPEXPR_TYPE_RESULT_INT:
|
||||
(*p->mpX_set_si)
|
||||
(sp, (long) (* (mpexpr_fun_i_unary_t) CP->op->fun) (sp));
|
||||
break;
|
||||
case MPEXPR_TYPE_RESULT_INT | MPEXPR_TYPE_LAST_UI:
|
||||
CHECK_UI (sp);
|
||||
(*p->mpX_set_si)
|
||||
(sp,
|
||||
(long) (* (mpexpr_fun_i_unary_ui_t) CP->op->fun)
|
||||
((*p->mpX_get_ui) (sp)));
|
||||
break;
|
||||
default:
|
||||
ERROR ("unrecognised unary argument calling style",
|
||||
MPEXPR_RESULT_BAD_TABLE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MPEXPR_TYPE_NARY(2):
|
||||
{
|
||||
mpX_ptr sp;
|
||||
|
||||
/* pairwise functions are allowed to have just one argument */
|
||||
if ((CP->op->type & MPEXPR_TYPE_PAIRWISE)
|
||||
&& CP->op->precedence == 0
|
||||
&& CP->argcount == 1)
|
||||
goto apply_control_done;
|
||||
|
||||
CHECK_ARGCOUNT ("binary", 2);
|
||||
DATA_POP (1);
|
||||
sp = SP;
|
||||
TRACE (MPX_TRACE ("lhs", sp);
|
||||
MPX_TRACE ("rhs", sp+1));
|
||||
|
||||
if (CP->op->type & MPEXPR_TYPE_MASK_CMP)
|
||||
{
|
||||
int type = CP->op->type;
|
||||
int cmp = (* (mpexpr_fun_i_binary_t) CP->op->fun)
|
||||
(sp, sp+1);
|
||||
(*p->mpX_set_si)
|
||||
(sp,
|
||||
(long)
|
||||
(( (cmp < 0) & ((type & MPEXPR_TYPE_MASK_CMP_LT) != 0))
|
||||
| ((cmp == 0) & ((type & MPEXPR_TYPE_MASK_CMP_EQ) != 0))
|
||||
| ((cmp > 0) & ((type & MPEXPR_TYPE_MASK_CMP_GT) != 0))));
|
||||
goto apply_control_done;
|
||||
}
|
||||
|
||||
switch (CP->op->type & MPEXPR_TYPE_MASK_SPECIAL) {
|
||||
case 0:
|
||||
/* not a special */
|
||||
break;
|
||||
|
||||
case MPEXPR_TYPE_QUESTION & MPEXPR_TYPE_MASK_SPECIAL:
|
||||
ERROR ("'?' without ':'", MPEXPR_RESULT_PARSE_ERROR);
|
||||
|
||||
case MPEXPR_TYPE_COLON & MPEXPR_TYPE_MASK_SPECIAL:
|
||||
TRACE (printf ("special colon\n"));
|
||||
CONTROL_POP ();
|
||||
if (CP->op->type != MPEXPR_TYPE_QUESTION)
|
||||
ERROR ("':' without '?'", MPEXPR_RESULT_PARSE_ERROR);
|
||||
|
||||
CP->argcount--;
|
||||
DATA_POP (1);
|
||||
sp--;
|
||||
TRACE (MPX_TRACE ("query", sp);
|
||||
MPX_TRACE ("true", sp+1);
|
||||
MPX_TRACE ("false", sp+2));
|
||||
(*p->mpX_set)
|
||||
(sp, (* (mpexpr_fun_i_unary_t) CP->op->fun) (sp)
|
||||
? sp+1 : sp+2);
|
||||
goto apply_control_done;
|
||||
|
||||
case MPEXPR_TYPE_LOGICAL_AND & MPEXPR_TYPE_MASK_SPECIAL:
|
||||
TRACE (printf ("special logical and\n"));
|
||||
(*p->mpX_set_si)
|
||||
(sp,
|
||||
(long)
|
||||
((* (mpexpr_fun_i_unary_t) CP->op->fun) (sp)
|
||||
&& (* (mpexpr_fun_i_unary_t) CP->op->fun) (sp+1)));
|
||||
goto apply_control_done;
|
||||
|
||||
case MPEXPR_TYPE_LOGICAL_OR & MPEXPR_TYPE_MASK_SPECIAL:
|
||||
TRACE (printf ("special logical and\n"));
|
||||
(*p->mpX_set_si)
|
||||
(sp,
|
||||
(long)
|
||||
((* (mpexpr_fun_i_unary_t) CP->op->fun) (sp)
|
||||
|| (* (mpexpr_fun_i_unary_t) CP->op->fun) (sp+1)));
|
||||
goto apply_control_done;
|
||||
|
||||
case MPEXPR_TYPE_MAX & MPEXPR_TYPE_MASK_SPECIAL:
|
||||
TRACE (printf ("special max\n"));
|
||||
if ((* (mpexpr_fun_i_binary_t) CP->op->fun) (sp, sp+1) < 0)
|
||||
(*p->mpX_swap) (sp, sp+1);
|
||||
goto apply_control_done;
|
||||
case MPEXPR_TYPE_MIN & MPEXPR_TYPE_MASK_SPECIAL:
|
||||
TRACE (printf ("special min\n"));
|
||||
if ((* (mpexpr_fun_i_binary_t) CP->op->fun) (sp, sp+1) > 0)
|
||||
(*p->mpX_swap) (sp, sp+1);
|
||||
goto apply_control_done;
|
||||
|
||||
default:
|
||||
ERROR ("unrecognised special binary operator",
|
||||
MPEXPR_RESULT_BAD_TABLE);
|
||||
}
|
||||
|
||||
switch (CP->op->type & MPEXPR_TYPE_MASK_ARGSTYLE) {
|
||||
case 0:
|
||||
(* (mpexpr_fun_binary_t) CP->op->fun) (sp, sp, sp+1);
|
||||
break;
|
||||
case MPEXPR_TYPE_LAST_UI:
|
||||
CHECK_UI (sp+1);
|
||||
(* (mpexpr_fun_binary_ui_t) CP->op->fun)
|
||||
(sp, sp, (*p->mpX_get_ui) (sp+1));
|
||||
break;
|
||||
case MPEXPR_TYPE_RESULT_INT:
|
||||
(*p->mpX_set_si)
|
||||
(sp,
|
||||
(long) (* (mpexpr_fun_i_binary_t) CP->op->fun) (sp, sp+1));
|
||||
break;
|
||||
case MPEXPR_TYPE_LAST_UI | MPEXPR_TYPE_RESULT_INT:
|
||||
CHECK_UI (sp+1);
|
||||
(*p->mpX_set_si)
|
||||
(sp,
|
||||
(long) (* (mpexpr_fun_i_binary_ui_t) CP->op->fun)
|
||||
(sp, (*p->mpX_get_ui) (sp+1)));
|
||||
break;
|
||||
default:
|
||||
ERROR ("unrecognised binary argument calling style",
|
||||
MPEXPR_RESULT_BAD_TABLE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MPEXPR_TYPE_NARY(3):
|
||||
{
|
||||
mpX_ptr sp;
|
||||
|
||||
CHECK_ARGCOUNT ("ternary", 3);
|
||||
DATA_POP (2);
|
||||
sp = SP;
|
||||
TRACE (MPX_TRACE ("arg1", sp);
|
||||
MPX_TRACE ("arg2", sp+1);
|
||||
MPX_TRACE ("arg3", sp+1));
|
||||
|
||||
switch (CP->op->type & MPEXPR_TYPE_MASK_ARGSTYLE) {
|
||||
case 0:
|
||||
(* (mpexpr_fun_ternary_t) CP->op->fun) (sp, sp, sp+1, sp+2);
|
||||
break;
|
||||
case MPEXPR_TYPE_LAST_UI:
|
||||
CHECK_UI (sp+2);
|
||||
(* (mpexpr_fun_ternary_ui_t) CP->op->fun)
|
||||
(sp, sp, sp+1, (*p->mpX_get_ui) (sp+2));
|
||||
break;
|
||||
case MPEXPR_TYPE_RESULT_INT:
|
||||
(*p->mpX_set_si)
|
||||
(sp,
|
||||
(long) (* (mpexpr_fun_i_ternary_t) CP->op->fun)
|
||||
(sp, sp+1, sp+2));
|
||||
break;
|
||||
case MPEXPR_TYPE_LAST_UI | MPEXPR_TYPE_RESULT_INT:
|
||||
CHECK_UI (sp+2);
|
||||
(*p->mpX_set_si)
|
||||
(sp,
|
||||
(long) (* (mpexpr_fun_i_ternary_ui_t) CP->op->fun)
|
||||
(sp, sp+1, (*p->mpX_get_ui) (sp+2)));
|
||||
break;
|
||||
default:
|
||||
ERROR ("unrecognised binary argument calling style",
|
||||
MPEXPR_RESULT_BAD_TABLE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
TRACE (printf ("unrecognised operator type: 0x%X\n", CP->op->type));
|
||||
ERROR ("", MPEXPR_RESULT_PARSE_ERROR);
|
||||
}
|
||||
|
||||
apply_control_done:
|
||||
TRACE (MPX_TRACE ("result", SP));
|
||||
CONTROL_POP ();
|
||||
goto another_operator;
|
||||
|
||||
done:
|
||||
if (p->error_code == MPEXPR_RESULT_OK)
|
||||
{
|
||||
if (p->data_top != 0)
|
||||
{
|
||||
TRACE (printf ("data stack want top at 0, got %d\n", p->data_top));
|
||||
p->error_code = MPEXPR_RESULT_PARSE_ERROR;
|
||||
}
|
||||
else
|
||||
(*p->mpX_set_or_swap) (p->res, SP);
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < p->data_inited; i++)
|
||||
{
|
||||
TRACE (printf ("clear %d\n", i));
|
||||
(*p->mpX_clear) (p->data_stack+i);
|
||||
}
|
||||
}
|
||||
|
||||
FREE_FUNC_TYPE (p->data_stack, p->data_alloc, union mpX_t);
|
||||
FREE_FUNC_TYPE (p->control_stack, p->control_alloc, struct mpexpr_control_t);
|
||||
|
||||
return p->error_code;
|
||||
}
|
||||
142
blender-5.2.0/extern/gmp-source/demos/expr/expr.h
vendored
Normal file
142
blender-5.2.0/extern/gmp-source/demos/expr/expr.h
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/* Header for expression evaluation.
|
||||
|
||||
Copyright 2000-2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
|
||||
#ifndef __EXPR_H__
|
||||
#define __EXPR_H__
|
||||
|
||||
#define MPEXPR_RESULT_OK 0
|
||||
#define MPEXPR_RESULT_BAD_VARIABLE 1
|
||||
#define MPEXPR_RESULT_BAD_TABLE 2
|
||||
#define MPEXPR_RESULT_PARSE_ERROR 3
|
||||
#define MPEXPR_RESULT_NOT_UI 4
|
||||
|
||||
|
||||
/* basic types */
|
||||
#define MPEXPR_TYPE_NARY(n) ((n) * 0x0100)
|
||||
#define MPEXPR_TYPE_MASK_ARGCOUNT MPEXPR_TYPE_NARY(0xF)
|
||||
#define MPEXPR_TYPE_0ARY MPEXPR_TYPE_NARY(0)
|
||||
#define MPEXPR_TYPE_UNARY MPEXPR_TYPE_NARY(1)
|
||||
#define MPEXPR_TYPE_BINARY MPEXPR_TYPE_NARY(2)
|
||||
#define MPEXPR_TYPE_TERNARY MPEXPR_TYPE_NARY(3)
|
||||
|
||||
/* options for all */
|
||||
#define MPEXPR_TYPE_LAST_UI 0x0010
|
||||
#define MPEXPR_TYPE_RESULT_INT 0x0020
|
||||
#define MPEXPR_TYPE_MASK_ARGSTYLE 0x0030
|
||||
|
||||
#define MPEXPR_TYPE_UNARY_UI (MPEXPR_TYPE_UNARY | MPEXPR_TYPE_LAST_UI)
|
||||
#define MPEXPR_TYPE_I_UNARY (MPEXPR_TYPE_UNARY | MPEXPR_TYPE_RESULT_INT)
|
||||
#define MPEXPR_TYPE_I_UNARY_UI (MPEXPR_TYPE_I_UNARY | MPEXPR_TYPE_LAST_UI)
|
||||
#define MPEXPR_TYPE_BINARY_UI (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_LAST_UI)
|
||||
#define MPEXPR_TYPE_I_BINARY (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_RESULT_INT)
|
||||
#define MPEXPR_TYPE_I_BINARY_UI (MPEXPR_TYPE_I_BINARY| MPEXPR_TYPE_LAST_UI)
|
||||
#define MPEXPR_TYPE_TERNARY_UI (MPEXPR_TYPE_TERNARY | MPEXPR_TYPE_LAST_UI)
|
||||
#define MPEXPR_TYPE_I_TERNARY (MPEXPR_TYPE_TERNARY | MPEXPR_TYPE_RESULT_INT)
|
||||
#define MPEXPR_TYPE_I_TERNARY_UI (MPEXPR_TYPE_I_TERNARY|MPEXPR_TYPE_LAST_UI)
|
||||
|
||||
/* 0ary with options */
|
||||
#define MPEXPR_TYPE_CONSTANT (MPEXPR_TYPE_0ARY | 0x0040)
|
||||
|
||||
/* unary options */
|
||||
#define MPEXPR_TYPE_PREFIX 0x0040
|
||||
|
||||
/* binary options */
|
||||
#define MPEXPR_TYPE_RIGHTASSOC 0x0040
|
||||
#define MPEXPR_TYPE_PAIRWISE 0x0080
|
||||
|
||||
#define MPEXPR_TYPE_MASK_SPECIAL 0x000F
|
||||
|
||||
/* unary specials */
|
||||
#define MPEXPR_TYPE_NEW_TABLE (MPEXPR_TYPE_UNARY | 0x001)
|
||||
#define MPEXPR_TYPE_DONE (MPEXPR_TYPE_UNARY | 0x002)
|
||||
#define MPEXPR_TYPE_VARIABLE (MPEXPR_TYPE_UNARY | 0x003)
|
||||
#define MPEXPR_TYPE_LOGICAL_NOT (MPEXPR_TYPE_UNARY | 0x004)
|
||||
#define MPEXPR_TYPE_CLOSEPAREN (MPEXPR_TYPE_UNARY | 0x005)
|
||||
#define MPEXPR_TYPE_OPENPAREN (MPEXPR_TYPE_CLOSEPAREN | MPEXPR_TYPE_PREFIX)
|
||||
|
||||
/* binary specials */
|
||||
#define MPEXPR_TYPE_LOGICAL_AND (MPEXPR_TYPE_BINARY | 0x001)
|
||||
#define MPEXPR_TYPE_LOGICAL_OR (MPEXPR_TYPE_BINARY | 0x002)
|
||||
#define MPEXPR_TYPE_ARGSEP (MPEXPR_TYPE_BINARY | 0x003)
|
||||
#define MPEXPR_TYPE_QUESTION (MPEXPR_TYPE_BINARY | 0x004)
|
||||
#define MPEXPR_TYPE_COLON (MPEXPR_TYPE_BINARY | 0x005)
|
||||
#define MPEXPR_TYPE_MAX (MPEXPR_TYPE_BINARY | 0x006)
|
||||
#define MPEXPR_TYPE_MIN (MPEXPR_TYPE_BINARY | 0x007)
|
||||
#define MPEXPR_TYPE_MASK_CMP 0x008
|
||||
#define MPEXPR_TYPE_MASK_CMP_LT 0x001
|
||||
#define MPEXPR_TYPE_MASK_CMP_EQ 0x002
|
||||
#define MPEXPR_TYPE_MASK_CMP_GT 0x004
|
||||
#define MPEXPR_TYPE_CMP_LT (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_MASK_CMP \
|
||||
| MPEXPR_TYPE_MASK_CMP_LT)
|
||||
#define MPEXPR_TYPE_CMP_EQ (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_MASK_CMP \
|
||||
| MPEXPR_TYPE_MASK_CMP_EQ)
|
||||
#define MPEXPR_TYPE_CMP_GT (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_MASK_CMP \
|
||||
| MPEXPR_TYPE_MASK_CMP_GT)
|
||||
#define MPEXPR_TYPE_CMP_LE (MPEXPR_TYPE_CMP_LT | MPEXPR_TYPE_MASK_CMP_EQ)
|
||||
#define MPEXPR_TYPE_CMP_NE (MPEXPR_TYPE_CMP_LT | MPEXPR_TYPE_MASK_CMP_GT)
|
||||
#define MPEXPR_TYPE_CMP_GE (MPEXPR_TYPE_CMP_GT | MPEXPR_TYPE_MASK_CMP_EQ)
|
||||
|
||||
/* parse options */
|
||||
#define MPEXPR_TYPE_WHOLEWORD 0x1000
|
||||
#define MPEXPR_TYPE_OPERATOR 0x2000
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*mpexpr_fun_t) (void);
|
||||
|
||||
struct mpexpr_operator_t {
|
||||
const char *name;
|
||||
mpexpr_fun_t fun;
|
||||
int type;
|
||||
int precedence;
|
||||
};
|
||||
|
||||
|
||||
int mpf_expr_a (const struct mpexpr_operator_t *, mpf_ptr, int,
|
||||
unsigned long, const char *, size_t, mpf_srcptr [26]);
|
||||
int mpf_expr (mpf_ptr, int, const char *, ...);
|
||||
|
||||
int mpq_expr_a (const struct mpexpr_operator_t *, mpq_ptr,
|
||||
int, const char *, size_t, mpq_srcptr [26]);
|
||||
int mpq_expr (mpq_ptr, int, const char *, ...);
|
||||
|
||||
int mpz_expr_a (const struct mpexpr_operator_t *, mpz_ptr, int,
|
||||
const char *, size_t, mpz_srcptr [26]);
|
||||
int mpz_expr (mpz_ptr, int, const char *, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
123
blender-5.2.0/extern/gmp-source/demos/expr/exprf.c
vendored
Normal file
123
blender-5.2.0/extern/gmp-source/demos/expr/exprf.c
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/* mpf expression evaluation
|
||||
|
||||
Copyright 2000-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gmp.h"
|
||||
#include "expr-impl.h"
|
||||
|
||||
|
||||
/* Change this to "#define TRACE(x) x" to get some traces. */
|
||||
#define TRACE(x)
|
||||
|
||||
|
||||
static int
|
||||
e_mpf_sgn (mpf_srcptr x)
|
||||
{
|
||||
return mpf_sgn (x);
|
||||
}
|
||||
|
||||
|
||||
static const struct mpexpr_operator_t _mpf_expr_standard_table[] = {
|
||||
|
||||
{ "**", (mpexpr_fun_t) mpf_pow_ui,
|
||||
MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 220 },
|
||||
|
||||
{ "!", (mpexpr_fun_t) e_mpf_sgn,
|
||||
MPEXPR_TYPE_LOGICAL_NOT | MPEXPR_TYPE_PREFIX, 210 },
|
||||
{ "-", (mpexpr_fun_t) mpf_neg,
|
||||
MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
|
||||
|
||||
{ "*", (mpexpr_fun_t) mpf_mul, MPEXPR_TYPE_BINARY, 200 },
|
||||
{ "/", (mpexpr_fun_t) mpf_div, MPEXPR_TYPE_BINARY, 200 },
|
||||
|
||||
{ "+", (mpexpr_fun_t) mpf_add, MPEXPR_TYPE_BINARY, 190 },
|
||||
{ "-", (mpexpr_fun_t) mpf_sub, MPEXPR_TYPE_BINARY, 190 },
|
||||
|
||||
{ "<<", (mpexpr_fun_t) mpf_mul_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
|
||||
{ ">>", (mpexpr_fun_t) mpf_div_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
|
||||
|
||||
{ "<=", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_LE, 170 },
|
||||
{ "<", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_LT, 170 },
|
||||
{ ">=", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_GE, 170 },
|
||||
{ ">", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_GT, 170 },
|
||||
|
||||
{ "==", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_EQ, 160 },
|
||||
{ "!=", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_NE, 160 },
|
||||
|
||||
{ "&&", (mpexpr_fun_t) e_mpf_sgn, MPEXPR_TYPE_LOGICAL_AND, 120 },
|
||||
{ "||", (mpexpr_fun_t) e_mpf_sgn, MPEXPR_TYPE_LOGICAL_OR, 110 },
|
||||
|
||||
{ ":", NULL, MPEXPR_TYPE_COLON, 101 },
|
||||
{ "?", (mpexpr_fun_t) e_mpf_sgn, MPEXPR_TYPE_QUESTION, 100 },
|
||||
|
||||
{ ")", NULL, MPEXPR_TYPE_CLOSEPAREN, 4 },
|
||||
{ "(", NULL, MPEXPR_TYPE_OPENPAREN, 3 },
|
||||
{ ",", NULL, MPEXPR_TYPE_ARGSEP, 2 },
|
||||
{ "$", NULL, MPEXPR_TYPE_VARIABLE, 1 },
|
||||
|
||||
{ "abs", (mpexpr_fun_t) mpf_abs, MPEXPR_TYPE_UNARY },
|
||||
{ "ceil", (mpexpr_fun_t) mpf_ceil, MPEXPR_TYPE_UNARY },
|
||||
{ "cmp", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_I_BINARY },
|
||||
{ "eq", (mpexpr_fun_t) mpf_eq, MPEXPR_TYPE_I_TERNARY_UI },
|
||||
{ "floor", (mpexpr_fun_t) mpf_floor, MPEXPR_TYPE_UNARY },
|
||||
{ "integer_p",(mpexpr_fun_t) mpf_integer_p, MPEXPR_TYPE_I_UNARY },
|
||||
{ "max", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_MAX | MPEXPR_TYPE_PAIRWISE },
|
||||
{ "min", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_MIN | MPEXPR_TYPE_PAIRWISE },
|
||||
{ "reldiff", (mpexpr_fun_t) mpf_reldiff, MPEXPR_TYPE_BINARY },
|
||||
{ "sgn", (mpexpr_fun_t) e_mpf_sgn, MPEXPR_TYPE_I_UNARY },
|
||||
{ "sqrt", (mpexpr_fun_t) mpf_sqrt, MPEXPR_TYPE_UNARY },
|
||||
{ "trunc", (mpexpr_fun_t) mpf_trunc, MPEXPR_TYPE_UNARY },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
const struct mpexpr_operator_t * const mpf_expr_standard_table
|
||||
= _mpf_expr_standard_table;
|
||||
|
||||
|
||||
int
|
||||
mpf_expr (mpf_ptr res, int base, const char *e, ...)
|
||||
{
|
||||
mpf_srcptr var[MPEXPR_VARIABLES];
|
||||
va_list ap;
|
||||
int ret;
|
||||
va_start (ap, e);
|
||||
|
||||
TRACE (printf ("mpf_expr(): base %d, %s\n", base, e));
|
||||
ret = mpexpr_va_to_var ((void **) var, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (ret != MPEXPR_RESULT_OK)
|
||||
return ret;
|
||||
|
||||
return mpf_expr_a (mpf_expr_standard_table, res, base,
|
||||
mpf_get_prec (res), e, strlen(e), var);
|
||||
}
|
||||
191
blender-5.2.0/extern/gmp-source/demos/expr/exprfa.c
vendored
Normal file
191
blender-5.2.0/extern/gmp-source/demos/expr/exprfa.c
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
/* mpf expression evaluation
|
||||
|
||||
Copyright 2000-2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
|
||||
/* Future: Bitwise "&", "|" and "&" could be done, if desired. Not sure
|
||||
those functions would be much value though. */
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gmp.h"
|
||||
#include "expr-impl.h"
|
||||
|
||||
|
||||
/* Change this to "#define TRACE(x) x" to get some traces. */
|
||||
#define TRACE(x)
|
||||
|
||||
|
||||
static size_t
|
||||
e_mpf_number (mpf_ptr res, const char *e, size_t elen, int base)
|
||||
{
|
||||
char *edup;
|
||||
size_t i, ret, extra=0;
|
||||
int mant_base, exp_base;
|
||||
void *(*allocate_func) (size_t);
|
||||
void (*free_func) (void *, size_t);
|
||||
|
||||
TRACE (printf ("mpf_number base=%d \"%.*s\"\n", base, (int) elen, e));
|
||||
|
||||
/* mpf_set_str doesn't currently accept 0x for hex in base==0, so do it
|
||||
here instead. FIXME: Would prefer to let mpf_set_str handle this. */
|
||||
if (base == 0 && elen >= 2 && e[0] == '0' && (e[1] == 'x' || e[1] == 'X'))
|
||||
{
|
||||
base = 16;
|
||||
extra = 2;
|
||||
e += extra;
|
||||
elen -= extra;
|
||||
}
|
||||
|
||||
if (base == 0)
|
||||
mant_base = 10;
|
||||
else if (base < 0)
|
||||
mant_base = -base;
|
||||
else
|
||||
mant_base = base;
|
||||
|
||||
/* exponent in decimal if base is negative */
|
||||
if (base < 0)
|
||||
exp_base = 10;
|
||||
else if (base == 0)
|
||||
exp_base = 10;
|
||||
else
|
||||
exp_base = base;
|
||||
|
||||
#define IS_EXPONENT(c) \
|
||||
(c == '@' || (base <= 10 && base >= -10 && (e[i] == 'e' || e[i] == 'E')))
|
||||
|
||||
i = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (i >= elen)
|
||||
goto parsed;
|
||||
if (e[i] == '.')
|
||||
break;
|
||||
if (IS_EXPONENT (e[i]))
|
||||
goto exponent;
|
||||
if (! isasciidigit_in_base (e[i], mant_base))
|
||||
goto parsed;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* fraction */
|
||||
i++;
|
||||
for (;;)
|
||||
{
|
||||
if (i >= elen)
|
||||
goto parsed;
|
||||
if (IS_EXPONENT (e[i]))
|
||||
goto exponent;
|
||||
if (! isasciidigit_in_base (e[i], mant_base))
|
||||
goto parsed;
|
||||
i++;
|
||||
}
|
||||
|
||||
exponent:
|
||||
i++;
|
||||
if (i >= elen)
|
||||
goto parsed;
|
||||
if (e[i] == '-')
|
||||
i++;
|
||||
for (;;)
|
||||
{
|
||||
if (i >= elen)
|
||||
goto parsed;
|
||||
if (! isasciidigit_in_base (e[i], exp_base))
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
parsed:
|
||||
TRACE (printf (" parsed i=%u \"%.*s\"\n", i, (int) i, e));
|
||||
|
||||
mp_get_memory_functions (&allocate_func, NULL, &free_func);
|
||||
edup = (*allocate_func) (i+1);
|
||||
memcpy (edup, e, i);
|
||||
edup[i] = '\0';
|
||||
|
||||
if (mpf_set_str (res, edup, base) == 0)
|
||||
ret = i + extra;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
(*free_func) (edup, i+1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
e_mpf_ulong_p (mpf_srcptr f)
|
||||
{
|
||||
return mpf_integer_p (f) && mpf_fits_ulong_p (f);
|
||||
}
|
||||
|
||||
/* Don't want to change the precision of w, can only do an actual swap when
|
||||
w and x have the same precision. */
|
||||
static void
|
||||
e_mpf_set_or_swap (mpf_ptr w, mpf_ptr x)
|
||||
{
|
||||
if (mpf_get_prec (w) == mpf_get_prec (x))
|
||||
mpf_swap (w, x);
|
||||
else
|
||||
mpf_set (w, x);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mpf_expr_a (const struct mpexpr_operator_t *table,
|
||||
mpf_ptr res, int base, unsigned long prec,
|
||||
const char *e, size_t elen,
|
||||
mpf_srcptr var[26])
|
||||
{
|
||||
struct mpexpr_parse_t p;
|
||||
|
||||
p.table = table;
|
||||
p.res = (mpX_ptr) res;
|
||||
p.base = base;
|
||||
p.prec = prec;
|
||||
p.e = e;
|
||||
p.elen = elen;
|
||||
p.var = (mpX_srcptr *) var;
|
||||
|
||||
p.mpX_clear = (mpexpr_fun_one_t) mpf_clear;
|
||||
p.mpX_ulong_p = (mpexpr_fun_i_unary_t) e_mpf_ulong_p;
|
||||
p.mpX_get_ui = (mpexpr_fun_get_ui_t) mpf_get_ui;
|
||||
p.mpX_init = (mpexpr_fun_unary_ui_t) mpf_init2;
|
||||
p.mpX_number = (mpexpr_fun_number_t) e_mpf_number;
|
||||
p.mpX_set = (mpexpr_fun_unary_t) mpf_set;
|
||||
p.mpX_set_or_swap = (mpexpr_fun_unary_t) e_mpf_set_or_swap;
|
||||
p.mpX_set_si = (mpexpr_fun_set_si_t) mpf_set_si;
|
||||
p.mpX_swap = (mpexpr_fun_swap_t) mpf_swap;
|
||||
|
||||
return mpexpr_evaluate (&p);
|
||||
}
|
||||
155
blender-5.2.0/extern/gmp-source/demos/expr/exprq.c
vendored
Normal file
155
blender-5.2.0/extern/gmp-source/demos/expr/exprq.c
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
/* mpq expression evaluation
|
||||
|
||||
Copyright 2000-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gmp.h"
|
||||
#include "expr-impl.h"
|
||||
|
||||
|
||||
/* Change this to "#define TRACE(x) x" to get some traces. */
|
||||
#define TRACE(x)
|
||||
|
||||
|
||||
static void
|
||||
e_mpq_pow_ui (mpq_ptr r, mpq_srcptr b, unsigned long e)
|
||||
{
|
||||
mpz_pow_ui (mpq_numref(r), mpq_numref(b), e);
|
||||
mpz_pow_ui (mpq_denref(r), mpq_denref(b), e);
|
||||
}
|
||||
|
||||
/* Wrapped because mpq_sgn is a macro. */
|
||||
static int
|
||||
e_mpq_sgn (mpq_srcptr x)
|
||||
{
|
||||
return mpq_sgn (x);
|
||||
}
|
||||
|
||||
/* Wrapped because mpq_equal only guarantees a non-zero return, whereas we
|
||||
want 1 or 0 for == and !=. */
|
||||
static int
|
||||
e_mpq_equal (mpq_srcptr x, mpq_srcptr y)
|
||||
{
|
||||
return mpq_equal (x, y) != 0;
|
||||
}
|
||||
static int
|
||||
e_mpq_notequal (mpq_srcptr x, mpq_srcptr y)
|
||||
{
|
||||
return ! mpq_equal (x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
e_mpq_num (mpq_ptr w, mpq_srcptr x)
|
||||
{
|
||||
if (w != x)
|
||||
mpz_set (mpq_numref(w), mpq_numref(x));
|
||||
mpz_set_ui (mpq_denref(w), 1L);
|
||||
}
|
||||
static void
|
||||
e_mpq_den (mpq_ptr w, mpq_srcptr x)
|
||||
{
|
||||
if (w == x)
|
||||
mpz_swap (mpq_numref(w), mpq_denref(w));
|
||||
else
|
||||
mpz_set (mpq_numref(w), mpq_denref(x));
|
||||
mpz_set_ui (mpq_denref(w), 1L);
|
||||
}
|
||||
|
||||
|
||||
static const struct mpexpr_operator_t _mpq_expr_standard_table[] = {
|
||||
|
||||
{ "**", (mpexpr_fun_t) e_mpq_pow_ui,
|
||||
MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 220 },
|
||||
|
||||
{ "!", (mpexpr_fun_t) e_mpq_sgn,
|
||||
MPEXPR_TYPE_LOGICAL_NOT | MPEXPR_TYPE_PREFIX, 210 },
|
||||
{ "-", (mpexpr_fun_t) mpq_neg,
|
||||
MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
|
||||
|
||||
{ "*", (mpexpr_fun_t) mpq_mul, MPEXPR_TYPE_BINARY, 200 },
|
||||
{ "/", (mpexpr_fun_t) mpq_div, MPEXPR_TYPE_BINARY, 200 },
|
||||
|
||||
{ "+", (mpexpr_fun_t) mpq_add, MPEXPR_TYPE_BINARY, 190 },
|
||||
{ "-", (mpexpr_fun_t) mpq_sub, MPEXPR_TYPE_BINARY, 190 },
|
||||
|
||||
{ "<<", (mpexpr_fun_t) mpq_mul_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
|
||||
{ ">>", (mpexpr_fun_t) mpq_div_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
|
||||
|
||||
{ "<=", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_LE, 170 },
|
||||
{ "<", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_LT, 170 },
|
||||
{ ">=", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_GE, 170 },
|
||||
{ ">", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_GT, 170 },
|
||||
|
||||
{ "==", (mpexpr_fun_t) e_mpq_equal, MPEXPR_TYPE_I_BINARY, 160 },
|
||||
{ "!=", (mpexpr_fun_t) e_mpq_notequal, MPEXPR_TYPE_I_BINARY, 160 },
|
||||
|
||||
{ "&&", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_LOGICAL_AND, 120 },
|
||||
{ "||", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_LOGICAL_OR, 110 },
|
||||
|
||||
{ ":", NULL, MPEXPR_TYPE_COLON, 101 },
|
||||
{ "?", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_QUESTION, 100 },
|
||||
|
||||
{ ")", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_CLOSEPAREN, 4 },
|
||||
{ "(", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_OPENPAREN, 3 },
|
||||
{ ",", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_ARGSEP, 2 },
|
||||
{ "$", NULL, MPEXPR_TYPE_VARIABLE, 1 },
|
||||
|
||||
{ "abs", (mpexpr_fun_t) mpq_abs, MPEXPR_TYPE_UNARY },
|
||||
{ "cmp", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_I_BINARY },
|
||||
{ "den", (mpexpr_fun_t) e_mpq_den, MPEXPR_TYPE_UNARY },
|
||||
{ "max", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_MAX | MPEXPR_TYPE_PAIRWISE },
|
||||
{ "min", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_MIN | MPEXPR_TYPE_PAIRWISE },
|
||||
{ "num", (mpexpr_fun_t) e_mpq_num, MPEXPR_TYPE_UNARY },
|
||||
{ "sgn", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_I_UNARY },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
const struct mpexpr_operator_t * const mpq_expr_standard_table
|
||||
= _mpq_expr_standard_table;
|
||||
|
||||
|
||||
int
|
||||
mpq_expr (mpq_ptr res, int base, const char *e, ...)
|
||||
{
|
||||
mpq_srcptr var[MPEXPR_VARIABLES];
|
||||
va_list ap;
|
||||
int ret;
|
||||
va_start (ap, e);
|
||||
|
||||
TRACE (printf ("mpq_expr(): base %d, %s\n", base, e));
|
||||
ret = mpexpr_va_to_var ((void **) var, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (ret != MPEXPR_RESULT_OK)
|
||||
return ret;
|
||||
|
||||
return mpq_expr_a (mpq_expr_standard_table, res, base, e, strlen(e), var);
|
||||
}
|
||||
100
blender-5.2.0/extern/gmp-source/demos/expr/exprqa.c
vendored
Normal file
100
blender-5.2.0/extern/gmp-source/demos/expr/exprqa.c
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
/* mpq expression evaluation
|
||||
|
||||
Copyright 2000, 2001, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "gmp.h"
|
||||
#include "expr-impl.h"
|
||||
|
||||
|
||||
static int
|
||||
e_mpq_ulong_p (mpq_srcptr q)
|
||||
{
|
||||
return mpz_fits_ulong_p (mpq_numref (q))
|
||||
&& mpz_cmp_ui (mpq_denref (q), 1L) == 0;
|
||||
}
|
||||
|
||||
/* get value as a ui, on the assumption it fits */
|
||||
static int
|
||||
e_mpq_get_ui_fits (mpq_srcptr q)
|
||||
{
|
||||
return mpz_get_ui (mpq_numref (q));
|
||||
}
|
||||
|
||||
static void
|
||||
e_mpq_set_si1 (mpq_ptr q, long num)
|
||||
{
|
||||
mpq_set_si (q, num, 1L);
|
||||
}
|
||||
|
||||
/* The same as mpz, but putting the result in the numerator. Negatives and
|
||||
fractions aren't parsed here because '-' and '/' are operators. */
|
||||
static size_t
|
||||
e_mpq_number (mpq_ptr res, const char *e, size_t elen, int base)
|
||||
{
|
||||
mpz_set_ui (mpq_denref (res), 1L);
|
||||
return mpexpr_mpz_number (mpq_numref (res), e, elen, base);
|
||||
}
|
||||
|
||||
|
||||
/* ignoring prec */
|
||||
static void
|
||||
e_mpq_init (mpq_ptr q, unsigned long prec)
|
||||
{
|
||||
mpq_init (q);
|
||||
}
|
||||
|
||||
int
|
||||
mpq_expr_a (const struct mpexpr_operator_t *table,
|
||||
mpq_ptr res, int base,
|
||||
const char *e, size_t elen,
|
||||
mpq_srcptr var[26])
|
||||
{
|
||||
struct mpexpr_parse_t p;
|
||||
|
||||
p.table = table;
|
||||
p.res = (mpX_ptr) res;
|
||||
p.base = base;
|
||||
p.e = e;
|
||||
p.elen = elen;
|
||||
p.var = (mpX_srcptr *) var;
|
||||
|
||||
p.mpX_clear = (mpexpr_fun_one_t) mpq_clear;
|
||||
p.mpX_ulong_p = (mpexpr_fun_i_unary_t) e_mpq_ulong_p;
|
||||
p.mpX_get_ui = (mpexpr_fun_get_ui_t) e_mpq_get_ui_fits;
|
||||
p.mpX_init = (mpexpr_fun_unary_ui_t) e_mpq_init;
|
||||
p.mpX_number = (mpexpr_fun_number_t) e_mpq_number;
|
||||
p.mpX_set = (mpexpr_fun_unary_t) mpq_set;
|
||||
p.mpX_set_or_swap = (mpexpr_fun_unary_t) mpq_swap;
|
||||
p.mpX_set_si = (mpexpr_fun_set_si_t) e_mpq_set_si1;
|
||||
p.mpX_swap = (mpexpr_fun_swap_t) mpq_swap;
|
||||
|
||||
return mpexpr_evaluate (&p);
|
||||
}
|
||||
57
blender-5.2.0/extern/gmp-source/demos/expr/exprv.c
vendored
Normal file
57
blender-5.2.0/extern/gmp-source/demos/expr/exprv.c
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/* mpz expression evaluation, simple part */
|
||||
|
||||
/*
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "gmp.h"
|
||||
#include "expr-impl.h"
|
||||
|
||||
|
||||
int
|
||||
mpexpr_va_to_var (void *var[], va_list ap)
|
||||
{
|
||||
int i = 0;
|
||||
void *v;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
v = va_arg (ap, void *);
|
||||
if (v == NULL)
|
||||
break;
|
||||
if (i >= MPEXPR_VARIABLES)
|
||||
return MPEXPR_RESULT_BAD_VARIABLE;
|
||||
var[i++] = v;
|
||||
}
|
||||
|
||||
while (i < MPEXPR_VARIABLES)
|
||||
var[i++] = NULL;
|
||||
|
||||
return MPEXPR_RESULT_OK;
|
||||
}
|
||||
206
blender-5.2.0/extern/gmp-source/demos/expr/exprz.c
vendored
Normal file
206
blender-5.2.0/extern/gmp-source/demos/expr/exprz.c
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
/* mpz expression evaluation, simple part
|
||||
|
||||
Copyright 2000-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gmp.h"
|
||||
#include "expr-impl.h"
|
||||
|
||||
|
||||
/* Change this to "#define TRACE(x) x" to get some traces. */
|
||||
#define TRACE(x)
|
||||
|
||||
|
||||
/* These are macros, so need function wrappers. */
|
||||
static int
|
||||
e_mpz_sgn (mpz_srcptr x)
|
||||
{
|
||||
return mpz_sgn (x);
|
||||
}
|
||||
static int
|
||||
e_mpz_odd_p (mpz_srcptr x)
|
||||
{
|
||||
return mpz_odd_p (x);
|
||||
}
|
||||
static int
|
||||
e_mpz_even_p (mpz_srcptr x)
|
||||
{
|
||||
return mpz_even_p (x);
|
||||
}
|
||||
|
||||
/* These wrapped because MPEXPR_TYPE_I_ functions are expected to return
|
||||
"int" whereas these return "unsigned long". */
|
||||
static void
|
||||
e_mpz_hamdist (mpz_ptr w, mpz_srcptr x, mpz_srcptr y)
|
||||
{
|
||||
mpz_set_ui (w, mpz_hamdist (x, y));
|
||||
}
|
||||
static void
|
||||
e_mpz_popcount (mpz_ptr w, mpz_srcptr x)
|
||||
{
|
||||
mpz_set_ui (w, mpz_popcount (x));
|
||||
}
|
||||
static void
|
||||
e_mpz_scan0 (mpz_ptr w, mpz_srcptr x, unsigned long start)
|
||||
{
|
||||
mpz_set_ui (w, mpz_scan0 (x, start));
|
||||
}
|
||||
static void
|
||||
e_mpz_scan1 (mpz_ptr w, mpz_srcptr x, unsigned long start)
|
||||
{
|
||||
mpz_set_ui (w, mpz_scan1 (x, start));
|
||||
}
|
||||
|
||||
/* These wrapped because they're in-place whereas MPEXPR_TYPE_BINARY_UI
|
||||
expects a separate source and destination. Actually the parser will
|
||||
normally pass w==x anyway. */
|
||||
static void
|
||||
e_mpz_setbit (mpz_ptr w, mpz_srcptr x, unsigned long n)
|
||||
{
|
||||
if (w != x)
|
||||
mpz_set (w, x);
|
||||
mpz_setbit (w, n);
|
||||
}
|
||||
static void
|
||||
e_mpz_clrbit (mpz_ptr w, mpz_srcptr x, unsigned long n)
|
||||
{
|
||||
if (w != x)
|
||||
mpz_set (w, x);
|
||||
mpz_clrbit (w, n);
|
||||
}
|
||||
|
||||
static const struct mpexpr_operator_t _mpz_expr_standard_table[] = {
|
||||
|
||||
{ "**", (mpexpr_fun_t) mpz_pow_ui,
|
||||
MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 220 },
|
||||
|
||||
{ "~", (mpexpr_fun_t) mpz_com,
|
||||
MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
|
||||
{ "!", (mpexpr_fun_t) e_mpz_sgn,
|
||||
MPEXPR_TYPE_LOGICAL_NOT | MPEXPR_TYPE_PREFIX, 210 },
|
||||
{ "-", (mpexpr_fun_t) mpz_neg,
|
||||
MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
|
||||
|
||||
{ "*", (mpexpr_fun_t) mpz_mul, MPEXPR_TYPE_BINARY, 200 },
|
||||
{ "/", (mpexpr_fun_t) mpz_tdiv_q, MPEXPR_TYPE_BINARY, 200 },
|
||||
{ "%", (mpexpr_fun_t) mpz_tdiv_r, MPEXPR_TYPE_BINARY, 200 },
|
||||
|
||||
{ "+", (mpexpr_fun_t) mpz_add, MPEXPR_TYPE_BINARY, 190 },
|
||||
{ "-", (mpexpr_fun_t) mpz_sub, MPEXPR_TYPE_BINARY, 190 },
|
||||
|
||||
{ "<<", (mpexpr_fun_t) mpz_mul_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
|
||||
{ ">>", (mpexpr_fun_t) mpz_tdiv_q_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
|
||||
|
||||
{ "<=", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_LE, 170 },
|
||||
{ "<", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_LT, 170 },
|
||||
{ ">=", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_GE, 170 },
|
||||
{ ">", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_GT, 170 },
|
||||
|
||||
{ "==", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_EQ, 160 },
|
||||
{ "!=", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_NE, 160 },
|
||||
|
||||
{ "&", (mpexpr_fun_t) mpz_and, MPEXPR_TYPE_BINARY, 150 },
|
||||
{ "^", (mpexpr_fun_t) mpz_xor, MPEXPR_TYPE_BINARY, 140 },
|
||||
{ "|", (mpexpr_fun_t) mpz_ior, MPEXPR_TYPE_BINARY, 130 },
|
||||
{ "&&", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_LOGICAL_AND, 120 },
|
||||
{ "||", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_LOGICAL_OR, 110 },
|
||||
|
||||
{ ":", NULL, MPEXPR_TYPE_COLON, 101 },
|
||||
{ "?", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_QUESTION, 100 },
|
||||
|
||||
{ ")", NULL, MPEXPR_TYPE_CLOSEPAREN, 4 },
|
||||
{ "(", NULL, MPEXPR_TYPE_OPENPAREN, 3 },
|
||||
{ ",", NULL, MPEXPR_TYPE_ARGSEP, 2 },
|
||||
{ "$", NULL, MPEXPR_TYPE_VARIABLE, 1 },
|
||||
|
||||
{ "abs", (mpexpr_fun_t) mpz_abs, MPEXPR_TYPE_UNARY },
|
||||
{ "bin", (mpexpr_fun_t) mpz_bin_ui, MPEXPR_TYPE_BINARY_UI },
|
||||
{ "clrbit", (mpexpr_fun_t) e_mpz_clrbit, MPEXPR_TYPE_BINARY_UI },
|
||||
{ "cmp", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_I_BINARY },
|
||||
{ "cmpabs", (mpexpr_fun_t) mpz_cmpabs, MPEXPR_TYPE_I_BINARY },
|
||||
{ "congruent_p",(mpexpr_fun_t)mpz_congruent_p, MPEXPR_TYPE_I_TERNARY },
|
||||
{ "divisible_p",(mpexpr_fun_t)mpz_divisible_p, MPEXPR_TYPE_I_BINARY },
|
||||
{ "even_p", (mpexpr_fun_t) e_mpz_even_p, MPEXPR_TYPE_I_UNARY },
|
||||
{ "fib", (mpexpr_fun_t) mpz_fib_ui, MPEXPR_TYPE_UNARY_UI },
|
||||
{ "fac", (mpexpr_fun_t) mpz_fac_ui, MPEXPR_TYPE_UNARY_UI },
|
||||
{ "gcd", (mpexpr_fun_t) mpz_gcd, MPEXPR_TYPE_BINARY
|
||||
| MPEXPR_TYPE_PAIRWISE },
|
||||
{ "hamdist", (mpexpr_fun_t) e_mpz_hamdist, MPEXPR_TYPE_BINARY },
|
||||
{ "invert", (mpexpr_fun_t) mpz_invert, MPEXPR_TYPE_BINARY },
|
||||
{ "jacobi", (mpexpr_fun_t) mpz_jacobi, MPEXPR_TYPE_I_BINARY },
|
||||
{ "kronecker", (mpexpr_fun_t) mpz_kronecker, MPEXPR_TYPE_I_BINARY },
|
||||
{ "lcm", (mpexpr_fun_t) mpz_lcm, MPEXPR_TYPE_BINARY
|
||||
| MPEXPR_TYPE_PAIRWISE },
|
||||
{ "lucnum", (mpexpr_fun_t) mpz_lucnum_ui, MPEXPR_TYPE_UNARY_UI },
|
||||
{ "max", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_MAX
|
||||
| MPEXPR_TYPE_PAIRWISE },
|
||||
{ "min", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_MIN
|
||||
| MPEXPR_TYPE_PAIRWISE },
|
||||
{ "nextprime", (mpexpr_fun_t) mpz_nextprime, MPEXPR_TYPE_UNARY },
|
||||
{ "odd_p", (mpexpr_fun_t) e_mpz_odd_p, MPEXPR_TYPE_I_UNARY },
|
||||
{ "perfect_power_p", (mpexpr_fun_t)mpz_perfect_power_p, MPEXPR_TYPE_I_UNARY},
|
||||
{ "perfect_square_p",(mpexpr_fun_t)mpz_perfect_square_p,MPEXPR_TYPE_I_UNARY},
|
||||
{ "popcount", (mpexpr_fun_t) e_mpz_popcount, MPEXPR_TYPE_UNARY },
|
||||
{ "powm", (mpexpr_fun_t) mpz_powm, MPEXPR_TYPE_TERNARY },
|
||||
{ "probab_prime_p", (mpexpr_fun_t)mpz_probab_prime_p, MPEXPR_TYPE_I_UNARY},
|
||||
{ "root", (mpexpr_fun_t) mpz_root, MPEXPR_TYPE_BINARY_UI },
|
||||
{ "scan0", (mpexpr_fun_t) e_mpz_scan0, MPEXPR_TYPE_BINARY_UI },
|
||||
{ "scan1", (mpexpr_fun_t) e_mpz_scan1, MPEXPR_TYPE_BINARY_UI },
|
||||
{ "setbit", (mpexpr_fun_t) e_mpz_setbit, MPEXPR_TYPE_BINARY_UI },
|
||||
{ "tstbit", (mpexpr_fun_t) mpz_tstbit, MPEXPR_TYPE_I_BINARY_UI },
|
||||
{ "sgn", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_I_UNARY },
|
||||
{ "sqrt", (mpexpr_fun_t) mpz_sqrt, MPEXPR_TYPE_UNARY },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* The table is available globally only through a pointer, so the table size
|
||||
can change without breaking binary compatibility. */
|
||||
const struct mpexpr_operator_t * const mpz_expr_standard_table
|
||||
= _mpz_expr_standard_table;
|
||||
|
||||
|
||||
int
|
||||
mpz_expr (mpz_ptr res, int base, const char *e, ...)
|
||||
{
|
||||
mpz_srcptr var[MPEXPR_VARIABLES];
|
||||
va_list ap;
|
||||
int ret;
|
||||
va_start (ap, e);
|
||||
|
||||
TRACE (printf ("mpz_expr(): base %d, %s\n", base, e));
|
||||
ret = mpexpr_va_to_var ((void **) var, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (ret != MPEXPR_RESULT_OK)
|
||||
return ret;
|
||||
|
||||
return mpz_expr_a (mpz_expr_standard_table, res, base, e, strlen(e), var);
|
||||
}
|
||||
108
blender-5.2.0/extern/gmp-source/demos/expr/exprza.c
vendored
Normal file
108
blender-5.2.0/extern/gmp-source/demos/expr/exprza.c
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
/* mpz expression evaluation
|
||||
|
||||
Copyright 2000-2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gmp.h"
|
||||
#include "expr-impl.h"
|
||||
|
||||
|
||||
/* No need to parse '-' since that's handled as an operator.
|
||||
This function also by mpq_expr_a, so it's not static. */
|
||||
size_t
|
||||
mpexpr_mpz_number (mpz_ptr res, const char *e, size_t elen, int base)
|
||||
{
|
||||
char *edup;
|
||||
size_t i, ret;
|
||||
int base_effective = (base == 0 ? 10 : base);
|
||||
void *(*allocate_func) (size_t);
|
||||
void (*free_func) (void *, size_t);
|
||||
|
||||
i = 0;
|
||||
if (e[i] == '0')
|
||||
{
|
||||
i++;
|
||||
if (e[i] == 'x' || e[i] == 'b')
|
||||
i++;
|
||||
}
|
||||
|
||||
for ( ; i < elen; i++)
|
||||
if (! isasciidigit_in_base (e[i], base_effective))
|
||||
break;
|
||||
|
||||
mp_get_memory_functions (&allocate_func, NULL, &free_func);
|
||||
edup = (*allocate_func) (i+1);
|
||||
memcpy (edup, e, i);
|
||||
edup[i] = '\0';
|
||||
|
||||
if (mpz_set_str (res, edup, base) == 0)
|
||||
ret = i;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
(*free_func) (edup, i+1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ignoring prec */
|
||||
static void
|
||||
e_mpz_init (mpz_ptr z, unsigned long prec)
|
||||
{
|
||||
mpz_init (z);
|
||||
}
|
||||
|
||||
int
|
||||
mpz_expr_a (const struct mpexpr_operator_t *table,
|
||||
mpz_ptr res, int base,
|
||||
const char *e, size_t elen,
|
||||
mpz_srcptr var[26])
|
||||
{
|
||||
struct mpexpr_parse_t p;
|
||||
|
||||
p.table = table;
|
||||
p.res = (mpX_ptr) res;
|
||||
p.base = base;
|
||||
p.e = e;
|
||||
p.elen = elen;
|
||||
p.var = (mpX_srcptr *) var;
|
||||
|
||||
p.mpX_clear = (mpexpr_fun_one_t) mpz_clear;
|
||||
p.mpX_ulong_p = (mpexpr_fun_i_unary_t) mpz_fits_ulong_p;
|
||||
p.mpX_get_ui = (mpexpr_fun_get_ui_t) mpz_get_ui;
|
||||
p.mpX_init = (mpexpr_fun_unary_ui_t) e_mpz_init;
|
||||
p.mpX_number = (mpexpr_fun_number_t) mpexpr_mpz_number;
|
||||
p.mpX_set = (mpexpr_fun_unary_t) mpz_set;
|
||||
p.mpX_set_or_swap = (mpexpr_fun_unary_t) mpz_swap;
|
||||
p.mpX_set_si = (mpexpr_fun_set_si_t) mpz_set_si;
|
||||
p.mpX_swap = (mpexpr_fun_swap_t) mpz_swap;
|
||||
|
||||
return mpexpr_evaluate (&p);
|
||||
}
|
||||
242
blender-5.2.0/extern/gmp-source/demos/expr/run-expr.c
vendored
Normal file
242
blender-5.2.0/extern/gmp-source/demos/expr/run-expr.c
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
/* Demo program to run expression evaluation.
|
||||
|
||||
Copyright 2000-2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
|
||||
/* Usage: ./run-expr [-z] [-q] [-f] [-p prec] [-b base] expression...
|
||||
|
||||
Evaluate each argument as a simple expression. By default this is in mpz
|
||||
integers, but -q selects mpq or -f selects mpf. For mpf the float
|
||||
precision can be set with -p. In all cases the input base can be set
|
||||
with -b, or the default is "0" meaning decimal with "0x" allowed.
|
||||
|
||||
This is a pretty trivial program, it's just an easy way to experiment
|
||||
with the evaluation functions. */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gmp.h"
|
||||
#include "expr.h"
|
||||
|
||||
|
||||
void
|
||||
run_expr (int type, int base, unsigned long prec, char *str)
|
||||
{
|
||||
int outbase = (base == 0 ? 10 : base);
|
||||
int ret;
|
||||
|
||||
switch (type) {
|
||||
case 'z':
|
||||
default:
|
||||
{
|
||||
mpz_t res, var_a, var_b;
|
||||
|
||||
mpz_init (res);
|
||||
mpz_init_set_ui (var_a, 55L);
|
||||
mpz_init_set_ui (var_b, 99L);
|
||||
|
||||
ret = mpz_expr (res, base, str, var_a, var_b, NULL);
|
||||
printf ("\"%s\" base %d: ", str, base);
|
||||
if (ret == MPEXPR_RESULT_OK)
|
||||
{
|
||||
printf ("result ");
|
||||
mpz_out_str (stdout, outbase, res);
|
||||
printf ("\n");
|
||||
}
|
||||
else
|
||||
printf ("invalid (return code %d)\n", ret);
|
||||
|
||||
mpz_clear (res);
|
||||
mpz_clear (var_a);
|
||||
mpz_clear (var_b);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
{
|
||||
mpq_t res, var_a, var_b;
|
||||
|
||||
mpq_init (res);
|
||||
mpq_init (var_a);
|
||||
mpq_init (var_b);
|
||||
|
||||
mpq_set_ui (var_a, 55L, 1);
|
||||
mpq_set_ui (var_b, 99L, 1);
|
||||
|
||||
ret = mpq_expr (res, base, str, var_a, var_b, NULL);
|
||||
printf ("\"%s\" base %d: ", str, base);
|
||||
if (ret == MPEXPR_RESULT_OK)
|
||||
{
|
||||
printf ("result ");
|
||||
mpq_out_str (stdout, outbase, res);
|
||||
printf ("\n");
|
||||
}
|
||||
else
|
||||
printf ("invalid (return code %d)\n", ret);
|
||||
|
||||
mpq_clear (res);
|
||||
mpq_clear (var_a);
|
||||
mpq_clear (var_b);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
{
|
||||
mpf_t res, var_a, var_b;
|
||||
|
||||
mpf_init2 (res, prec);
|
||||
mpf_init_set_ui (var_a, 55L);
|
||||
mpf_init_set_ui (var_b, 99L);
|
||||
|
||||
ret = mpf_expr (res, base, str, var_a, var_b, NULL);
|
||||
printf ("\"%s\" base %d: ", str, base);
|
||||
if (ret == MPEXPR_RESULT_OK)
|
||||
{
|
||||
printf ("result ");
|
||||
mpf_out_str (stdout, outbase, (size_t) 0, res);
|
||||
printf ("\n");
|
||||
}
|
||||
else
|
||||
printf ("invalid (return code %d)\n", ret);
|
||||
|
||||
mpf_clear (res);
|
||||
mpf_clear (var_a);
|
||||
mpf_clear (var_b);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int type = 'z';
|
||||
int base = 0;
|
||||
unsigned long prec = 64;
|
||||
int seen_expr = 0;
|
||||
int opt;
|
||||
char *arg;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
argv++;
|
||||
arg = argv[0];
|
||||
if (arg == NULL)
|
||||
break;
|
||||
|
||||
if (arg[0] == '-')
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
arg++;
|
||||
opt = arg[0];
|
||||
|
||||
switch (opt) {
|
||||
case '\0':
|
||||
goto end_opt;
|
||||
|
||||
case 'f':
|
||||
case 'q':
|
||||
case 'z':
|
||||
type = opt;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
arg++;
|
||||
if (arg[0] == '\0')
|
||||
{
|
||||
argv++;
|
||||
arg = argv[0];
|
||||
if (arg == NULL)
|
||||
{
|
||||
need_arg:
|
||||
fprintf (stderr, "Need argument for -%c\n", opt);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
base = atoi (arg);
|
||||
goto end_opt;
|
||||
|
||||
case 'p':
|
||||
arg++;
|
||||
if (arg[0] == '\0')
|
||||
{
|
||||
argv++;
|
||||
arg = argv[0];
|
||||
if (arg == NULL)
|
||||
goto need_arg;
|
||||
}
|
||||
prec = atoi (arg);
|
||||
goto end_opt;
|
||||
|
||||
case '-':
|
||||
arg++;
|
||||
if (arg[0] != '\0')
|
||||
{
|
||||
/* no "--foo" options */
|
||||
fprintf (stderr, "Unrecognised option --%s\n", arg);
|
||||
exit (1);
|
||||
}
|
||||
/* stop option interpretation at "--" */
|
||||
for (;;)
|
||||
{
|
||||
argv++;
|
||||
arg = argv[0];
|
||||
if (arg == NULL)
|
||||
goto done;
|
||||
run_expr (type, base, prec, arg);
|
||||
seen_expr = 1;
|
||||
}
|
||||
|
||||
default:
|
||||
fprintf (stderr, "Unrecognised option -%c\n", opt);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
end_opt:
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
run_expr (type, base, prec, arg);
|
||||
seen_expr = 1;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (! seen_expr)
|
||||
{
|
||||
printf ("Usage: %s [-z] [-q] [-f] [-p prec] [-b base] expression...\n", argv[0]);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
510
blender-5.2.0/extern/gmp-source/demos/expr/t-expr.c
vendored
Normal file
510
blender-5.2.0/extern/gmp-source/demos/expr/t-expr.c
vendored
Normal file
@@ -0,0 +1,510 @@
|
||||
/* Test expression evaluation (print nothing and exit 0 if successful).
|
||||
|
||||
Copyright 2000-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
* the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
or
|
||||
|
||||
* the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
or both in parallel, as here.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received copies of the GNU General Public License and the
|
||||
GNU Lesser General Public License along with the GNU MP Library. If not,
|
||||
see https://www.gnu.org/licenses/. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gmp-impl.h"
|
||||
#include "tests.h"
|
||||
#include "expr-impl.h"
|
||||
|
||||
|
||||
int option_trace = 0;
|
||||
|
||||
|
||||
struct data_t {
|
||||
int base;
|
||||
const char *expr;
|
||||
const char *want;
|
||||
};
|
||||
|
||||
#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
|
||||
|
||||
|
||||
/* These data_xxx[] arrays are tables to be tested with one or more of the
|
||||
mp?_t types. z=mpz_t, q=mpz_t, f=mpf_t. */
|
||||
|
||||
struct data_t data_zqf[] = {
|
||||
|
||||
/* various deliberately wrong expressions */
|
||||
{ 0, "", NULL },
|
||||
{ 0, "1+", NULL },
|
||||
{ 0, "+2", NULL },
|
||||
{ 0, "1,2", NULL },
|
||||
{ 0, "foo(1,2)", NULL },
|
||||
{ 0, "1+foo", NULL },
|
||||
{ 10, "0fff", NULL },
|
||||
{ 0, "!", NULL },
|
||||
{ 0, "10!", NULL },
|
||||
{ 0, "-10!", NULL },
|
||||
{ 0, "gcd((4,6))", NULL },
|
||||
{ 0, "()", NULL },
|
||||
{ 0, "fac(2**1000)", NULL },
|
||||
{ 0, "$", NULL },
|
||||
{ 0, "$-", NULL },
|
||||
|
||||
/* some basics */
|
||||
{ 10, "123", "123" },
|
||||
{ 10, "-123", "-123" },
|
||||
{ 10, "1+2", "3" },
|
||||
{ 10, "1+2+3", "6" },
|
||||
{ 10, "1+2*3", "7" },
|
||||
{ 10, "3*2+1", "7" },
|
||||
{ 10, "$a", "55" },
|
||||
{ 10, "b", "99" },
|
||||
{ 16, "b", "11" },
|
||||
{ 10, "4**3 * 2 + 1", "129" },
|
||||
{ 10, "1<2", "1" },
|
||||
{ 10, "1>2", "0" },
|
||||
|
||||
{ 10, "(123)", "123" },
|
||||
|
||||
{ 10, "sgn(-123)", "-1" },
|
||||
{ 10, "5-7", "-2" },
|
||||
|
||||
{ 0, "cmp(0,0)", "0" },
|
||||
{ 0, "cmp(1,0)", "1" },
|
||||
{ 0, "cmp(0,1)", "-1" },
|
||||
{ 0, "cmp(-1,0)", "-1" },
|
||||
{ 0, "cmp(0,-1)", "1" },
|
||||
|
||||
{ 10, "0 ? 123 : 456", "456" },
|
||||
{ 10, "1 ? 4+5 : 6+7", "9" },
|
||||
|
||||
{ 10, "(123)", "123" },
|
||||
{ 10, "(2+3)", "5" },
|
||||
{ 10, "(4+5)*(5+6)", "99" },
|
||||
|
||||
{ 0, "1 << 16", "65536" },
|
||||
{ 0, "256 >> 4", "16" },
|
||||
{ 0, "-256 >> 4", "-16" },
|
||||
|
||||
{ 0, "!1", "0" },
|
||||
{ 0, "!9", "0" },
|
||||
{ 0, "!0", "1" },
|
||||
|
||||
{ 0, "2**2**2", "16" },
|
||||
{ 0, "-2**2**2", "-16" },
|
||||
|
||||
{ 0, "0x100", "256" },
|
||||
{ 10, "0x100", NULL },
|
||||
{ 10, "0x 100", NULL },
|
||||
|
||||
{ 0, " max ( 1, 2, 3, 4, 5, 6, 7, 8)", "8" },
|
||||
{ 0, " max ( 1, 9, 2, 3, 4, 5, 6, 7, 8)", "9" },
|
||||
{ 0, " min ( 1, 9, 2, 3, 4, 5, 6, 7, 8)", "1" },
|
||||
|
||||
{ 10, "abs(123)", "123" },
|
||||
{ 10, "abs(-123)", "123" },
|
||||
{ 10, "abs(0)", "0" },
|
||||
|
||||
/* filling data stack */
|
||||
{ 0, "1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+1))))))))))))))", "16" },
|
||||
|
||||
/* filling control stack */
|
||||
{ 0, "----------------------------------------------------1", "1" },
|
||||
};
|
||||
|
||||
|
||||
const struct data_t data_z[] = {
|
||||
{ 0, "divisible_p(333,3)", "1" },
|
||||
{ 0, "congruent_p(7,1,3)", "1" },
|
||||
|
||||
{ 0, "cmpabs(0,0)", "0" },
|
||||
{ 0, "cmpabs(1,0)", "1" },
|
||||
{ 0, "cmpabs(0,1)", "-1" },
|
||||
{ 0, "cmpabs(-1,0)", "1" },
|
||||
{ 0, "cmpabs(0,-1)", "-1" },
|
||||
|
||||
{ 0, "odd_p(1)", "1" },
|
||||
{ 0, "odd_p(0)", "0" },
|
||||
{ 0, "odd_p(-1)", "1" },
|
||||
|
||||
{ 0, "even_p(1)", "0" },
|
||||
{ 0, "even_p(0)", "1" },
|
||||
{ 0, "even_p(-1)", "0" },
|
||||
|
||||
{ 0, "fac(0)", "1" },
|
||||
{ 0, "fac(1)", "1" },
|
||||
{ 0, "fac(2)", "2" },
|
||||
{ 0, "fac(3)", "6" },
|
||||
{ 0, "fac(10)", "3628800" },
|
||||
|
||||
{ 10, "root(81,4)", "3" },
|
||||
|
||||
{ 10, "gcd(4,6)", "2" },
|
||||
{ 10, "gcd(4,6,9)", "1" },
|
||||
|
||||
{ 10, "powm(3,2,9)", "0" },
|
||||
{ 10, "powm(3,2,8)", "1" },
|
||||
|
||||
/* filling data stack */
|
||||
{ 0, "1 ? 1 : 1 || 1 && 1 | 1 ^ 1 & 1 == 1 >= 1 << 1 - 1 * 1 ** 1", "1" },
|
||||
|
||||
/* filling control stack */
|
||||
{ 0, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1", "1" },
|
||||
|
||||
{ 0, "fib(10)", "55" },
|
||||
|
||||
{ 0, "setbit(0,5)", "32" },
|
||||
{ 0, "clrbit(32,5)", "0" },
|
||||
{ 0, "tstbit(32,5)", "1" },
|
||||
{ 0, "tstbit(32,4)", "0" },
|
||||
{ 0, "scan0(7,0)", "3" },
|
||||
{ 0, "scan1(7,0)", "0" },
|
||||
};
|
||||
|
||||
const struct data_t data_zq[] = {
|
||||
/* expecting failure */
|
||||
{ 0, "1.2", NULL },
|
||||
};
|
||||
|
||||
const struct data_t data_q[] = {
|
||||
{ 10, "(1/2 + 1/3 + 1/4 + 1/5 + 1/6)*20", "29" },
|
||||
{ 0, "num(5/9)", "5" },
|
||||
{ 0, "den(5/9)", "9" },
|
||||
};
|
||||
|
||||
const struct data_t data_zf[] = {
|
||||
{ 10, "sqrt ( 49 )", "7" },
|
||||
{ 10, "sqrt ( 49 ) + 1", "8" },
|
||||
{ 10, "sqrt((49))", "7" },
|
||||
{ 10, "sqrt((((((((49))))))))", "7" },
|
||||
};
|
||||
|
||||
const struct data_t data_f[] = {
|
||||
{ 0, "1@10", "10000000000" },
|
||||
{ 0, "1.5@10", "15000000000" },
|
||||
{ 0, "1000@-1", "100" },
|
||||
{ 0, "10.00@-1", "1" },
|
||||
|
||||
{ 0, "1e10", "10000000000" },
|
||||
{ 0, "1.5e10", "15000000000" },
|
||||
{ 0, "1000e-1", "100" },
|
||||
{ 0, "10.00e-1", "1" },
|
||||
|
||||
{ 16, "1@9", "68719476736" },
|
||||
|
||||
{ 16, "1@10", "18446744073709551616" },
|
||||
{ -16, "1@10", "1099511627776" },
|
||||
|
||||
{ 0, "ceil(0)", "0" },
|
||||
{ 0, "ceil(0.25)", "1" },
|
||||
{ 0, "ceil(0.5)", "1" },
|
||||
{ 0, "ceil(1.5)", "2" },
|
||||
{ 0, "ceil(-0.5)", "0" },
|
||||
{ 0, "ceil(-1.5)", "-1" },
|
||||
|
||||
/* only simple cases because mpf_eq currently only works on whole limbs */
|
||||
{ 0, "eq(0xFFFFFFFFFFFFFFFF1111111111111111,0xFFFFFFFFFFFFFFFF2222222222222222,64)", "1" },
|
||||
{ 0, "eq(0xFFFFFFFFFFFFFFFF1111111111111111,0xFFFFFFFFFFFFFFFF2222222222222222,128)", "0" },
|
||||
|
||||
{ 0, "floor(0)", "0" },
|
||||
{ 0, "floor(0.25)", "0" },
|
||||
{ 0, "floor(0.5)", "0" },
|
||||
{ 0, "floor(1.5)", "1" },
|
||||
{ 0, "floor(-0.5)", "-1" },
|
||||
{ 0, "floor(-1.5)", "-2" },
|
||||
|
||||
{ 0, "integer_p(1)", "1" },
|
||||
{ 0, "integer_p(0.5)", "0" },
|
||||
|
||||
{ 0, "trunc(0)", "0" },
|
||||
{ 0, "trunc(0.25)", "0" },
|
||||
{ 0, "trunc(0.5)", "0" },
|
||||
{ 0, "trunc(1.5)", "1" },
|
||||
{ 0, "trunc(-0.5)", "0" },
|
||||
{ 0, "trunc(-1.5)", "-1" },
|
||||
};
|
||||
|
||||
struct datalist_t {
|
||||
const struct data_t *data;
|
||||
int num;
|
||||
};
|
||||
|
||||
#define DATALIST(data) { data, numberof (data) }
|
||||
|
||||
struct datalist_t list_z[] = {
|
||||
DATALIST (data_z),
|
||||
DATALIST (data_zq),
|
||||
DATALIST (data_zf),
|
||||
DATALIST (data_zqf),
|
||||
};
|
||||
|
||||
struct datalist_t list_q[] = {
|
||||
DATALIST (data_q),
|
||||
DATALIST (data_zq),
|
||||
DATALIST (data_zqf),
|
||||
};
|
||||
|
||||
struct datalist_t list_f[] = {
|
||||
DATALIST (data_zf),
|
||||
DATALIST (data_zqf),
|
||||
DATALIST (data_f),
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
check_z (void)
|
||||
{
|
||||
const struct data_t *data;
|
||||
mpz_t a, b, got, want;
|
||||
int l, i, ret;
|
||||
|
||||
mpz_init (got);
|
||||
mpz_init (want);
|
||||
mpz_init_set_ui (a, 55);
|
||||
mpz_init_set_ui (b, 99);
|
||||
|
||||
for (l = 0; l < numberof (list_z); l++)
|
||||
{
|
||||
data = list_z[l].data;
|
||||
|
||||
for (i = 0; i < list_z[l].num; i++)
|
||||
{
|
||||
if (option_trace)
|
||||
printf ("mpz_expr \"%s\"\n", data[i].expr);
|
||||
|
||||
ret = mpz_expr (got, data[i].base, data[i].expr, a, b, NULL);
|
||||
|
||||
if (data[i].want == NULL)
|
||||
{
|
||||
/* expect to fail */
|
||||
if (ret == MPEXPR_RESULT_OK)
|
||||
{
|
||||
printf ("mpz_expr wrong return value, got %d, expected failure\n", ret);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mpz_set_str (want, data[i].want, 0) != 0)
|
||||
{
|
||||
printf ("Cannot parse wanted value string\n");
|
||||
goto error;
|
||||
}
|
||||
if (ret != MPEXPR_RESULT_OK)
|
||||
{
|
||||
printf ("mpz_expr failed unexpectedly\n");
|
||||
printf (" return value %d\n", ret);
|
||||
goto error;
|
||||
}
|
||||
if (mpz_cmp (got, want) != 0)
|
||||
{
|
||||
printf ("mpz_expr wrong result\n");
|
||||
printf (" got "); mpz_out_str (stdout, 10, got);
|
||||
printf ("\n");
|
||||
printf (" want "); mpz_out_str (stdout, 10, want);
|
||||
printf ("\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mpz_clear (a);
|
||||
mpz_clear (b);
|
||||
mpz_clear (got);
|
||||
mpz_clear (want);
|
||||
return;
|
||||
|
||||
error:
|
||||
printf (" base %d\n", data[i].base);
|
||||
printf (" expr \"%s\"\n", data[i].expr);
|
||||
if (data[i].want != NULL)
|
||||
printf (" want \"%s\"\n", data[i].want);
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
check_q (void)
|
||||
{
|
||||
const struct data_t *data;
|
||||
mpq_t a, b, got, want;
|
||||
int l, i, ret;
|
||||
|
||||
mpq_init (got);
|
||||
mpq_init (want);
|
||||
mpq_init (a);
|
||||
mpq_init (b);
|
||||
|
||||
mpq_set_ui (a, 55, 1);
|
||||
mpq_set_ui (b, 99, 1);
|
||||
|
||||
for (l = 0; l < numberof (list_q); l++)
|
||||
{
|
||||
data = list_q[l].data;
|
||||
|
||||
for (i = 0; i < list_q[l].num; i++)
|
||||
{
|
||||
if (option_trace)
|
||||
printf ("mpq_expr \"%s\"\n", data[i].expr);
|
||||
|
||||
ret = mpq_expr (got, data[i].base, data[i].expr, a, b, NULL);
|
||||
|
||||
if (data[i].want == NULL)
|
||||
{
|
||||
/* expect to fail */
|
||||
if (ret == MPEXPR_RESULT_OK)
|
||||
{
|
||||
printf ("mpq_expr wrong return value, got %d, expected failure\n", ret);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mpz_set_str (mpq_numref(want), data[i].want, 0) != 0)
|
||||
{
|
||||
printf ("Cannot parse wanted value string\n");
|
||||
goto error;
|
||||
}
|
||||
mpz_set_ui (mpq_denref(want), 1);
|
||||
|
||||
if (ret != MPEXPR_RESULT_OK)
|
||||
{
|
||||
printf ("mpq_expr failed unexpectedly\n");
|
||||
printf (" return value %d\n", ret);
|
||||
goto error;
|
||||
}
|
||||
if (mpq_cmp (got, want) != 0)
|
||||
{
|
||||
printf ("mpq_expr wrong result\n");
|
||||
printf (" got "); mpq_out_str (stdout, 10, got);
|
||||
printf ("\n");
|
||||
printf (" want "); mpq_out_str (stdout, 10, want);
|
||||
printf ("\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mpq_clear (a);
|
||||
mpq_clear (b);
|
||||
mpq_clear (got);
|
||||
mpq_clear (want);
|
||||
return;
|
||||
|
||||
error:
|
||||
printf (" base %d\n", data[i].base);
|
||||
printf (" expr \"%s\"\n", data[i].expr);
|
||||
if (data[i].want != NULL)
|
||||
printf (" want \"%s\"\n", data[i].want);
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
check_f (void)
|
||||
{
|
||||
const struct data_t *data;
|
||||
mpf_t a, b, got, want;
|
||||
int l, i, ret;
|
||||
|
||||
mpf_set_default_prec (200L);
|
||||
|
||||
mpf_init (got);
|
||||
mpf_init (want);
|
||||
mpf_init_set_ui (a, 55);
|
||||
mpf_init_set_ui (b, 99);
|
||||
|
||||
for (l = 0; l < numberof (list_f); l++)
|
||||
{
|
||||
data = list_f[l].data;
|
||||
|
||||
for (i = 0; i < list_f[l].num; i++)
|
||||
{
|
||||
if (option_trace)
|
||||
printf ("mpf_expr \"%s\"\n", data[i].expr);
|
||||
|
||||
ret = mpf_expr (got, data[i].base, data[i].expr, a, b, NULL);
|
||||
|
||||
if (data[i].want == NULL)
|
||||
{
|
||||
/* expect to fail */
|
||||
if (ret == MPEXPR_RESULT_OK)
|
||||
{
|
||||
printf ("mpf_expr wrong return value, got %d, expected failure\n", ret);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mpf_set_str (want, data[i].want, 0) != 0)
|
||||
{
|
||||
printf ("Cannot parse wanted value string\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ret != MPEXPR_RESULT_OK)
|
||||
{
|
||||
printf ("mpf_expr failed unexpectedly\n");
|
||||
printf (" return value %d\n", ret);
|
||||
goto error;
|
||||
}
|
||||
if (mpf_cmp (got, want) != 0)
|
||||
{
|
||||
printf ("mpf_expr wrong result\n");
|
||||
printf (" got "); mpf_out_str (stdout, 10, 20, got);
|
||||
printf ("\n");
|
||||
printf (" want "); mpf_out_str (stdout, 10, 20, want);
|
||||
printf ("\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mpf_clear (a);
|
||||
mpf_clear (b);
|
||||
mpf_clear (got);
|
||||
mpf_clear (want);
|
||||
return;
|
||||
|
||||
error:
|
||||
printf (" base %d\n", data[i].base);
|
||||
printf (" expr \"%s\"\n", data[i].expr);
|
||||
if (data[i].want != NULL)
|
||||
printf (" want \"%s\"\n", data[i].want);
|
||||
abort ();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
tests_start ();
|
||||
|
||||
if (argc >= 2)
|
||||
option_trace = 1;
|
||||
|
||||
check_z ();
|
||||
check_q ();
|
||||
check_f ();
|
||||
|
||||
tests_end ();
|
||||
exit (0);
|
||||
}
|
||||
Reference in New Issue
Block a user