aboutsummaryrefslogtreecommitdiff
path: root/vendor/gmp-6.3.0/demos
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gmp-6.3.0/demos')
-rw-r--r--vendor/gmp-6.3.0/demos/Makefile.am50
-rw-r--r--vendor/gmp-6.3.0/demos/Makefile.in785
-rw-r--r--vendor/gmp-6.3.0/demos/calc/Makefile.am47
-rw-r--r--vendor/gmp-6.3.0/demos/calc/Makefile.in677
-rw-r--r--vendor/gmp-6.3.0/demos/calc/README65
-rw-r--r--vendor/gmp-6.3.0/demos/calc/calc-common.h35
-rw-r--r--vendor/gmp-6.3.0/demos/calc/calc-config-h.in21
-rw-r--r--vendor/gmp-6.3.0/demos/calc/calc.c2012
-rw-r--r--vendor/gmp-6.3.0/demos/calc/calc.h146
-rw-r--r--vendor/gmp-6.3.0/demos/calc/calc.y318
-rw-r--r--vendor/gmp-6.3.0/demos/calc/calclex.c1933
-rw-r--r--vendor/gmp-6.3.0/demos/calc/calclex.l113
-rw-r--r--vendor/gmp-6.3.0/demos/calc/calcread.c146
-rw-r--r--vendor/gmp-6.3.0/demos/expr/Makefile.am54
-rw-r--r--vendor/gmp-6.3.0/demos/expr/Makefile.in666
-rw-r--r--vendor/gmp-6.3.0/demos/expr/README501
-rw-r--r--vendor/gmp-6.3.0/demos/expr/expr-impl.h125
-rw-r--r--vendor/gmp-6.3.0/demos/expr/expr.c834
-rw-r--r--vendor/gmp-6.3.0/demos/expr/expr.h142
-rw-r--r--vendor/gmp-6.3.0/demos/expr/exprf.c123
-rw-r--r--vendor/gmp-6.3.0/demos/expr/exprfa.c191
-rw-r--r--vendor/gmp-6.3.0/demos/expr/exprq.c155
-rw-r--r--vendor/gmp-6.3.0/demos/expr/exprqa.c100
-rw-r--r--vendor/gmp-6.3.0/demos/expr/exprv.c57
-rw-r--r--vendor/gmp-6.3.0/demos/expr/exprz.c206
-rw-r--r--vendor/gmp-6.3.0/demos/expr/exprza.c108
-rw-r--r--vendor/gmp-6.3.0/demos/expr/run-expr.c242
-rw-r--r--vendor/gmp-6.3.0/demos/expr/t-expr.c510
-rw-r--r--vendor/gmp-6.3.0/demos/factorize.c447
-rw-r--r--vendor/gmp-6.3.0/demos/isprime.c69
-rw-r--r--vendor/gmp-6.3.0/demos/perl/GMP.pm671
-rw-r--r--vendor/gmp-6.3.0/demos/perl/GMP.xs3212
-rw-r--r--vendor/gmp-6.3.0/demos/perl/GMP/Mpf.pm106
-rw-r--r--vendor/gmp-6.3.0/demos/perl/GMP/Mpq.pm89
-rw-r--r--vendor/gmp-6.3.0/demos/perl/GMP/Mpz.pm101
-rw-r--r--vendor/gmp-6.3.0/demos/perl/GMP/Rand.pm44
-rw-r--r--vendor/gmp-6.3.0/demos/perl/INSTALL88
-rw-r--r--vendor/gmp-6.3.0/demos/perl/Makefile.PL82
-rw-r--r--vendor/gmp-6.3.0/demos/perl/sample.pl54
-rw-r--r--vendor/gmp-6.3.0/demos/perl/test.pl2179
-rw-r--r--vendor/gmp-6.3.0/demos/perl/test2.pl75
-rw-r--r--vendor/gmp-6.3.0/demos/perl/typemap108
-rw-r--r--vendor/gmp-6.3.0/demos/pexpr-config-h.in45
-rw-r--r--vendor/gmp-6.3.0/demos/pexpr.c1380
-rw-r--r--vendor/gmp-6.3.0/demos/primes.c387
-rw-r--r--vendor/gmp-6.3.0/demos/primes.h552
-rw-r--r--vendor/gmp-6.3.0/demos/qcn.c172
47 files changed, 20223 insertions, 0 deletions
diff --git a/vendor/gmp-6.3.0/demos/Makefile.am b/vendor/gmp-6.3.0/demos/Makefile.am
new file mode 100644
index 0000000..64010a6
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/Makefile.am
@@ -0,0 +1,50 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2000-2002, 2012 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/.
+
+
+SUBDIRS = calc expr
+EXTRA_DIST = perl primes.h
+
+AM_CPPFLAGS = -I$(top_srcdir)
+LDADD = $(top_builddir)/libgmp.la
+
+qcn_LDADD = $(LDADD) $(LIBM)
+primes_LDADD = $(LDADD) $(LIBM)
+
+# None of these programs are built by default, but "make <whatever>" will
+# build them once libgmp.la is built.
+#
+EXTRA_PROGRAMS = factorize isprime pexpr primes qcn
+
+CLEANFILES = $(EXTRA_PROGRAMS)
+
+allprogs: $(EXTRA_PROGRAMS)
+ cd calc; $(MAKE) $(AM_MAKEFLAGS) allprogs
+ cd expr; $(MAKE) $(AM_MAKEFLAGS) allprogs
diff --git a/vendor/gmp-6.3.0/demos/Makefile.in b/vendor/gmp-6.3.0/demos/Makefile.in
new file mode 100644
index 0000000..276c96e
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/Makefile.in
@@ -0,0 +1,785 @@
+# 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 2000-2002, 2012 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 = factorize$(EXEEXT) isprime$(EXEEXT) pexpr$(EXEEXT) \
+ primes$(EXEEXT) qcn$(EXEEXT)
+subdir = demos
+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 = pexpr-config.h
+CONFIG_CLEAN_VPATH_FILES =
+factorize_SOURCES = factorize.c
+factorize_OBJECTS = factorize.$(OBJEXT)
+factorize_LDADD = $(LDADD)
+factorize_DEPENDENCIES = $(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 =
+isprime_SOURCES = isprime.c
+isprime_OBJECTS = isprime.$(OBJEXT)
+isprime_LDADD = $(LDADD)
+isprime_DEPENDENCIES = $(top_builddir)/libgmp.la
+pexpr_SOURCES = pexpr.c
+pexpr_OBJECTS = pexpr.$(OBJEXT)
+pexpr_LDADD = $(LDADD)
+pexpr_DEPENDENCIES = $(top_builddir)/libgmp.la
+primes_SOURCES = primes.c
+primes_OBJECTS = primes.$(OBJEXT)
+am__DEPENDENCIES_1 =
+primes_DEPENDENCIES = $(LDADD) $(am__DEPENDENCIES_1)
+qcn_SOURCES = qcn.c
+qcn_OBJECTS = qcn.$(OBJEXT)
+qcn_DEPENDENCIES = $(LDADD) $(am__DEPENDENCIES_1)
+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 = factorize.c isprime.c pexpr.c primes.c qcn.c
+DIST_SOURCES = factorize.c isprime.c pexpr.c primes.c qcn.c
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+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
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/pexpr-config-h.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+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@
+SUBDIRS = calc expr
+EXTRA_DIST = perl primes.h
+AM_CPPFLAGS = -I$(top_srcdir)
+LDADD = $(top_builddir)/libgmp.la
+qcn_LDADD = $(LDADD) $(LIBM)
+primes_LDADD = $(LDADD) $(LIBM)
+CLEANFILES = $(EXTRA_PROGRAMS)
+all: all-recursive
+
+.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/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps demos/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):
+pexpr-config.h: $(top_builddir)/config.status $(srcdir)/pexpr-config-h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+factorize$(EXEEXT): $(factorize_OBJECTS) $(factorize_DEPENDENCIES) $(EXTRA_factorize_DEPENDENCIES)
+ @rm -f factorize$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(factorize_OBJECTS) $(factorize_LDADD) $(LIBS)
+
+isprime$(EXEEXT): $(isprime_OBJECTS) $(isprime_DEPENDENCIES) $(EXTRA_isprime_DEPENDENCIES)
+ @rm -f isprime$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(isprime_OBJECTS) $(isprime_LDADD) $(LIBS)
+
+pexpr$(EXEEXT): $(pexpr_OBJECTS) $(pexpr_DEPENDENCIES) $(EXTRA_pexpr_DEPENDENCIES)
+ @rm -f pexpr$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(pexpr_OBJECTS) $(pexpr_LDADD) $(LIBS)
+
+primes$(EXEEXT): $(primes_OBJECTS) $(primes_DEPENDENCIES) $(EXTRA_primes_DEPENDENCIES)
+ @rm -f primes$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(primes_OBJECTS) $(primes_LDADD) $(LIBS)
+
+qcn$(EXEEXT): $(qcn_OBJECTS) $(qcn_DEPENDENCIES) $(EXTRA_qcn_DEPENDENCIES)
+ @rm -f qcn$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(qcn_OBJECTS) $(qcn_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
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(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-recursive
+
+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-recursive
+
+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
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) 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 installdirs-am 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)
+ cd calc; $(MAKE) $(AM_MAKEFLAGS) allprogs
+ cd expr; $(MAKE) $(AM_MAKEFLAGS) allprogs
+
+# 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:
diff --git a/vendor/gmp-6.3.0/demos/calc/Makefile.am b/vendor/gmp-6.3.0/demos/calc/Makefile.am
new file mode 100644
index 0000000..1cb5335
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/calc/Makefile.am
@@ -0,0 +1,47 @@
+## Process this file with automake to generate Makefile.in
+
+# 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/.
+
+
+AM_CPPFLAGS = -I$(top_srcdir)
+
+# $(LEXLIB) is not actually needed for flex (which means the distributed
+# calclex.c), but it's included here for the benefit of anyone rebuilding
+# with some other lex.
+#
+LDADD = $(top_builddir)/libgmp.la $(LIBREADLINE) $(LIBCURSES) $(LEXLIB)
+
+EXTRA_PROGRAMS = calc
+AM_YFLAGS = -d
+calc_SOURCES = calc.y calclex.l calcread.c calc-common.h
+BUILT_SOURCES = calc.h
+
+CLEANFILES = $(EXTRA_PROGRAMS)
+
+allprogs: $(EXTRA_PROGRAMS)
diff --git a/vendor/gmp-6.3.0/demos/calc/Makefile.in b/vendor/gmp-6.3.0/demos/calc/Makefile.in
new file mode 100644
index 0000000..5feb9a8
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/calc/Makefile.in
@@ -0,0 +1,677 @@
+# 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 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/.
+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 = calc$(EXEEXT)
+subdir = demos/calc
+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 = calc-config.h
+CONFIG_CLEAN_VPATH_FILES =
+am_calc_OBJECTS = calc.$(OBJEXT) calclex.$(OBJEXT) calcread.$(OBJEXT)
+calc_OBJECTS = $(am_calc_OBJECTS)
+calc_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+calc_DEPENDENCIES = $(top_builddir)/libgmp.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+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 =
+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 =
+@MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ ||
+LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS)
+LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS)
+AM_V_LEX = $(am__v_LEX_@AM_V@)
+am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@)
+am__v_LEX_0 = @echo " LEX " $@;
+am__v_LEX_1 =
+YLWRAP = $(top_srcdir)/ylwrap
+@MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ ||
+am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \
+ -e s/c++$$/h++/ -e s/c$$/h/
+YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS)
+LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS)
+AM_V_YACC = $(am__v_YACC_@AM_V@)
+am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@)
+am__v_YACC_0 = @echo " YACC " $@;
+am__v_YACC_1 =
+SOURCES = $(calc_SOURCES)
+DIST_SOURCES = $(calc_SOURCES)
+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 $(srcdir)/calc-config-h.in \
+ $(top_srcdir)/ylwrap README calc.c calc.h calclex.c
+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)
+
+# $(LEXLIB) is not actually needed for flex (which means the distributed
+# calclex.c), but it's included here for the benefit of anyone rebuilding
+# with some other lex.
+#
+LDADD = $(top_builddir)/libgmp.la $(LIBREADLINE) $(LIBCURSES) $(LEXLIB)
+AM_YFLAGS = -d
+calc_SOURCES = calc.y calclex.l calcread.c calc-common.h
+BUILT_SOURCES = calc.h
+CLEANFILES = $(EXTRA_PROGRAMS)
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .l .lo .o .obj .y
+$(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/calc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps demos/calc/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):
+calc-config.h: $(top_builddir)/config.status $(srcdir)/calc-config-h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+calc.h: calc.c
+ @if test ! -f $@; then rm -f calc.c; else :; fi
+ @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) calc.c; else :; fi
+
+calc$(EXEEXT): $(calc_OBJECTS) $(calc_DEPENDENCIES) $(EXTRA_calc_DEPENDENCIES)
+ @rm -f calc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(calc_OBJECTS) $(calc_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 $@ $<
+
+.l.c:
+ $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE)
+
+.y.c:
+ $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE)
+
+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: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile
+installdirs:
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) 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."
+ -rm -f calc.c
+ -rm -f calc.h
+ -rm -f calclex.c
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+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: all check install 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)
+
+# 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:
diff --git a/vendor/gmp-6.3.0/demos/calc/README b/vendor/gmp-6.3.0/demos/calc/README
new file mode 100644
index 0000000..660394e
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/calc/README
@@ -0,0 +1,65 @@
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/.
+
+
+
+
+ DEMONSTRATION CALCULATOR PROGRAM
+
+
+This is a simple program, meant only to show one way to use GMP with yacc
+and lex to make a calculator. Usage and comments on the implementation can
+be found in calc.y.
+
+Within a GMP build tree, the generated Makefile can be used to build the
+program,
+
+ make calc
+
+(or on a DOS system, "make calc.exe").
+
+Elsewhere, once GMP has been installed, the program can be compiled with for
+instance
+
+ gcc calc.c calclex.c -lgmp -o calc
+
+Or if GNU readline is used then
+
+ gcc calc.c calclex.c calcread.c -lgmp -lreadline -o calc
+
+(again, on a DOS system "-o calc.exe").
+
+Readline support can be enabled or disabled in calc-config.h. That file is
+created by the GMP ./configure based on the --with-readline option. The
+default is --with-readline=detect, which means to use readline if available.
+"yes" can be used to force it to be used, or "no" to not use it.
+
+The supplied calc.c was generated by GNU bison, but a standard yacc should
+work too.
+
+The supplied calclex.c was generated by GNU flex, but a standard lex should
+work too. The readline support may or may not work with a standard lex (see
+comments with input() in calcread.c). Note also that a standard lex will
+require its library "-ll" on the compile command line. "./configure" sets
+this up in the GMP build tree Makefile.
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/vendor/gmp-6.3.0/demos/calc/calc-common.h b/vendor/gmp-6.3.0/demos/calc/calc-common.h
new file mode 100644
index 0000000..7a91878
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/calc/calc-common.h
@@ -0,0 +1,35 @@
+/* Prototypes etc for calc program.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+#include <stddef.h> /* for size_t */
+#ifndef NO_CALC_H
+#include "calc.h"
+#endif
+#include "calc-config.h"
+
+struct calc_keywords_t {
+ char *name;
+ int value;
+};
+
+extern int calc_option_readline;
+extern int calc_more_input;
+extern const struct calc_keywords_t calc_keywords[];
+
+int calc_input (char *buf, size_t max_size);
+void calc_init_readline (void);
diff --git a/vendor/gmp-6.3.0/demos/calc/calc-config-h.in b/vendor/gmp-6.3.0/demos/calc/calc-config-h.in
new file mode 100644
index 0000000..42cdd44
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/calc/calc-config-h.in
@@ -0,0 +1,21 @@
+/* Templates for calc program configuration. -*- mode:c -*-
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* Define if GNU readline should be used. */
+#define WITH_READLINE @WITH_READLINE_01@
diff --git a/vendor/gmp-6.3.0/demos/calc/calc.c b/vendor/gmp-6.3.0/demos/calc/calc.c
new file mode 100644
index 0000000..908c31b
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/calc/calc.c
@@ -0,0 +1,2012 @@
+/* A Bison parser, made by GNU Bison 3.8.2. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output, and Bison version. */
+#define YYBISON 30802
+
+/* Bison version string. */
+#define YYBISON_VERSION "3.8.2"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+
+
+
+/* First part of user prologue. */
+#line 1 "../../../gmp/demos/calc/calc.y"
+
+/* A simple integer desk calculator using yacc and gmp.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* This is a simple program, meant only to show one way to use GMP for this
+ sort of thing. There's few features, and error checking is minimal.
+ Standard input is read, calc_help() below shows the inputs accepted.
+
+ Expressions are evaluated as they're read. If user defined functions
+ were wanted it'd be necessary to build a parse tree like pexpr.c does, or
+ a list of operations for a stack based evaluator. That would also make
+ it possible to detect and optimize evaluations "mod m" like pexpr.c does.
+
+ A stack is used for intermediate values in the expression evaluation,
+ separate from the yacc parser stack. This is simple, makes error
+ recovery easy, minimizes the junk around mpz calls in the rules, and
+ saves initializing or clearing "mpz_t"s during a calculation. A
+ disadvantage though is that variables must be copied to the stack to be
+ worked on. A more sophisticated calculator or language system might be
+ able to avoid that when executing a compiled or semi-compiled form.
+
+ Avoiding repeated initializing and clearing of "mpz_t"s is important. In
+ this program the time spent parsing is obviously much greater than any
+ possible saving from this, but a proper calculator or language should
+ take some trouble over it. Don't be surprised if an init/clear takes 3
+ or more times as long as a 10 limb addition, depending on the system (see
+ the mpz_init_realloc_clear example in tune/README). */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gmp.h"
+#define NO_CALC_H /* because it conflicts with normal calc.c stuff */
+#include "calc-common.h"
+
+
+#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
+
+
+void
+calc_help (void)
+{
+ printf ("Examples:\n");
+ printf (" 2+3*4 expressions are evaluated\n");
+ printf (" x=5^6 variables a to z can be set and used\n");
+ printf ("Operators:\n");
+ printf (" + - * arithmetic\n");
+ printf (" / %% division and remainder (rounding towards negative infinity)\n");
+ printf (" ^ exponentiation\n");
+ printf (" ! factorial\n");
+ printf (" << >> left and right shifts\n");
+ printf (" <= >= > \\ comparisons, giving 1 if true, 0 if false\n");
+ printf (" == != < /\n");
+ printf (" && || logical and/or, giving 1 if true, 0 if false\n");
+ printf ("Functions:\n");
+ printf (" abs(n) absolute value\n");
+ printf (" bin(n,m) binomial coefficient\n");
+ printf (" fib(n) fibonacci number\n");
+ printf (" gcd(a,b,..) greatest common divisor\n");
+ printf (" kron(a,b) kronecker symbol\n");
+ printf (" lcm(a,b,..) least common multiple\n");
+ printf (" lucnum(n) lucas number\n");
+ printf (" nextprime(n) next prime after n\n");
+ printf (" powm(b,e,m) modulo powering, b^e%%m\n");
+ printf (" root(n,r) r-th root\n");
+ printf (" sqrt(n) square root\n");
+ printf ("Other:\n");
+ printf (" hex \\ set hex or decimal for input and output\n");
+ printf (" decimal / (\"0x\" can be used for hex too)\n");
+ printf (" quit exit program (EOF works too)\n");
+ printf (" ; statements are separated with a ; or newline\n");
+ printf (" \\ continue expressions with \\ before newline\n");
+ printf (" # xxx comments are # though to newline\n");
+ printf ("Hex numbers must be entered in upper case, to distinguish them from the\n");
+ printf ("variables a to f (like in bc).\n");
+}
+
+
+int ibase = 0;
+int obase = 10;
+
+
+/* The stack is a fixed size, which means there's a limit on the nesting
+ allowed in expressions. A more sophisticated program could let it grow
+ dynamically. */
+
+mpz_t stack[100];
+mpz_ptr sp = stack[0];
+
+#define CHECK_OVERFLOW() \
+ if (sp >= stack[numberof(stack)]) /* FIXME */ \
+ { \
+ fprintf (stderr, \
+ "Value stack overflow, too much nesting in expression\n"); \
+ YYERROR; \
+ }
+
+#define CHECK_EMPTY() \
+ if (sp != stack[0]) \
+ { \
+ fprintf (stderr, "Oops, expected the value stack to be empty\n"); \
+ sp = stack[0]; \
+ }
+
+
+mpz_t variable[26];
+
+#define CHECK_VARIABLE(var) \
+ if ((var) < 0 || (var) >= numberof (variable)) \
+ { \
+ fprintf (stderr, "Oops, bad variable somehow: %d\n", var); \
+ YYERROR; \
+ }
+
+
+#define CHECK_UI(name,z) \
+ if (! mpz_fits_ulong_p (z)) \
+ { \
+ fprintf (stderr, "%s too big\n", name); \
+ YYERROR; \
+ }
+
+
+#line 212 "calc.c"
+
+# ifndef YY_CAST
+# ifdef __cplusplus
+# define YY_CAST(Type, Val) static_cast<Type> (Val)
+# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
+# else
+# define YY_CAST(Type, Val) ((Type) (Val))
+# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
+# endif
+# endif
+# ifndef YY_NULLPTR
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# else
+# define YY_NULLPTR ((void*)0)
+# endif
+# endif
+
+/* Use api.header.include to #include this header
+ instead of duplicating it here. */
+#ifndef YY_YY_CALC_H_INCLUDED
+# define YY_YY_CALC_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token kinds. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ YYEMPTY = -2,
+ YYEOF = 0, /* "end of file" */
+ YYerror = 256, /* error */
+ YYUNDEF = 257, /* "invalid token" */
+ EOS = 258, /* EOS */
+ BAD = 259, /* BAD */
+ HELP = 260, /* HELP */
+ HEX = 261, /* HEX */
+ DECIMAL = 262, /* DECIMAL */
+ QUIT = 263, /* QUIT */
+ ABS = 264, /* ABS */
+ BIN = 265, /* BIN */
+ FIB = 266, /* FIB */
+ GCD = 267, /* GCD */
+ KRON = 268, /* KRON */
+ LCM = 269, /* LCM */
+ LUCNUM = 270, /* LUCNUM */
+ NEXTPRIME = 271, /* NEXTPRIME */
+ POWM = 272, /* POWM */
+ ROOT = 273, /* ROOT */
+ SQRT = 274, /* SQRT */
+ NUMBER = 275, /* NUMBER */
+ VARIABLE = 276, /* VARIABLE */
+ LOR = 277, /* LOR */
+ LAND = 278, /* LAND */
+ EQ = 279, /* EQ */
+ NE = 280, /* NE */
+ LE = 281, /* LE */
+ GE = 282, /* GE */
+ LSHIFT = 283, /* LSHIFT */
+ RSHIFT = 284, /* RSHIFT */
+ UMINUS = 285 /* UMINUS */
+ };
+ typedef enum yytokentype yytoken_kind_t;
+#endif
+/* Token kinds. */
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYerror 256
+#define YYUNDEF 257
+#define EOS 258
+#define BAD 259
+#define HELP 260
+#define HEX 261
+#define DECIMAL 262
+#define QUIT 263
+#define ABS 264
+#define BIN 265
+#define FIB 266
+#define GCD 267
+#define KRON 268
+#define LCM 269
+#define LUCNUM 270
+#define NEXTPRIME 271
+#define POWM 272
+#define ROOT 273
+#define SQRT 274
+#define NUMBER 275
+#define VARIABLE 276
+#define LOR 277
+#define LAND 278
+#define EQ 279
+#define NE 280
+#define LE 281
+#define GE 282
+#define LSHIFT 283
+#define RSHIFT 284
+#define UMINUS 285
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+union YYSTYPE
+{
+#line 142 "../../../gmp/demos/calc/calc.y"
+
+ char *str;
+ int var;
+
+#line 330 "calc.c"
+
+};
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+
+int yyparse (void);
+
+
+#endif /* !YY_YY_CALC_H_INCLUDED */
+/* Symbol kind. */
+enum yysymbol_kind_t
+{
+ YYSYMBOL_YYEMPTY = -2,
+ YYSYMBOL_YYEOF = 0, /* "end of file" */
+ YYSYMBOL_YYerror = 1, /* error */
+ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */
+ YYSYMBOL_EOS = 3, /* EOS */
+ YYSYMBOL_BAD = 4, /* BAD */
+ YYSYMBOL_HELP = 5, /* HELP */
+ YYSYMBOL_HEX = 6, /* HEX */
+ YYSYMBOL_DECIMAL = 7, /* DECIMAL */
+ YYSYMBOL_QUIT = 8, /* QUIT */
+ YYSYMBOL_ABS = 9, /* ABS */
+ YYSYMBOL_BIN = 10, /* BIN */
+ YYSYMBOL_FIB = 11, /* FIB */
+ YYSYMBOL_GCD = 12, /* GCD */
+ YYSYMBOL_KRON = 13, /* KRON */
+ YYSYMBOL_LCM = 14, /* LCM */
+ YYSYMBOL_LUCNUM = 15, /* LUCNUM */
+ YYSYMBOL_NEXTPRIME = 16, /* NEXTPRIME */
+ YYSYMBOL_POWM = 17, /* POWM */
+ YYSYMBOL_ROOT = 18, /* ROOT */
+ YYSYMBOL_SQRT = 19, /* SQRT */
+ YYSYMBOL_NUMBER = 20, /* NUMBER */
+ YYSYMBOL_VARIABLE = 21, /* VARIABLE */
+ YYSYMBOL_LOR = 22, /* LOR */
+ YYSYMBOL_LAND = 23, /* LAND */
+ YYSYMBOL_24_ = 24, /* '<' */
+ YYSYMBOL_25_ = 25, /* '>' */
+ YYSYMBOL_EQ = 26, /* EQ */
+ YYSYMBOL_NE = 27, /* NE */
+ YYSYMBOL_LE = 28, /* LE */
+ YYSYMBOL_GE = 29, /* GE */
+ YYSYMBOL_LSHIFT = 30, /* LSHIFT */
+ YYSYMBOL_RSHIFT = 31, /* RSHIFT */
+ YYSYMBOL_32_ = 32, /* '+' */
+ YYSYMBOL_33_ = 33, /* '-' */
+ YYSYMBOL_34_ = 34, /* '*' */
+ YYSYMBOL_35_ = 35, /* '/' */
+ YYSYMBOL_36_ = 36, /* '%' */
+ YYSYMBOL_UMINUS = 37, /* UMINUS */
+ YYSYMBOL_38_ = 38, /* '^' */
+ YYSYMBOL_39_ = 39, /* '!' */
+ YYSYMBOL_40_ = 40, /* '=' */
+ YYSYMBOL_41_ = 41, /* '(' */
+ YYSYMBOL_42_ = 42, /* ')' */
+ YYSYMBOL_43_ = 43, /* ',' */
+ YYSYMBOL_YYACCEPT = 44, /* $accept */
+ YYSYMBOL_top = 45, /* top */
+ YYSYMBOL_statements = 46, /* statements */
+ YYSYMBOL_statement = 47, /* statement */
+ YYSYMBOL_e = 48, /* e */
+ YYSYMBOL_gcdlist = 49, /* gcdlist */
+ YYSYMBOL_lcmlist = 50 /* lcmlist */
+};
+typedef enum yysymbol_kind_t yysymbol_kind_t;
+
+
+
+
+#ifdef short
+# undef short
+#endif
+
+/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
+ <limits.h> and (if available) <stdint.h> are included
+ so that the code can choose integer types of a good width. */
+
+#ifndef __PTRDIFF_MAX__
+# include <limits.h> /* INFRINGES ON USER NAME SPACE */
+# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_STDINT_H
+# endif
+#endif
+
+/* Narrow types that promote to a signed type and that can represent a
+ signed or unsigned integer of at least N bits. In tables they can
+ save space and decrease cache pressure. Promoting to a signed type
+ helps avoid bugs in integer arithmetic. */
+
+#ifdef __INT_LEAST8_MAX__
+typedef __INT_LEAST8_TYPE__ yytype_int8;
+#elif defined YY_STDINT_H
+typedef int_least8_t yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef __INT_LEAST16_MAX__
+typedef __INT_LEAST16_TYPE__ yytype_int16;
+#elif defined YY_STDINT_H
+typedef int_least16_t yytype_int16;
+#else
+typedef short yytype_int16;
+#endif
+
+/* Work around bug in HP-UX 11.23, which defines these macros
+ incorrectly for preprocessor constants. This workaround can likely
+ be removed in 2023, as HPE has promised support for HP-UX 11.23
+ (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
+ <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */
+#ifdef __hpux
+# undef UINT_LEAST8_MAX
+# undef UINT_LEAST16_MAX
+# define UINT_LEAST8_MAX 255
+# define UINT_LEAST16_MAX 65535
+#endif
+
+#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST8_TYPE__ yytype_uint8;
+#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
+ && UINT_LEAST8_MAX <= INT_MAX)
+typedef uint_least8_t yytype_uint8;
+#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
+typedef unsigned char yytype_uint8;
+#else
+typedef short yytype_uint8;
+#endif
+
+#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST16_TYPE__ yytype_uint16;
+#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
+ && UINT_LEAST16_MAX <= INT_MAX)
+typedef uint_least16_t yytype_uint16;
+#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
+typedef unsigned short yytype_uint16;
+#else
+typedef int yytype_uint16;
+#endif
+
+#ifndef YYPTRDIFF_T
+# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
+# define YYPTRDIFF_T __PTRDIFF_TYPE__
+# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
+# elif defined PTRDIFF_MAX
+# ifndef ptrdiff_t
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# endif
+# define YYPTRDIFF_T ptrdiff_t
+# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
+# else
+# define YYPTRDIFF_T long
+# define YYPTRDIFF_MAXIMUM LONG_MAX
+# endif
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM \
+ YY_CAST (YYPTRDIFF_T, \
+ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
+ ? YYPTRDIFF_MAXIMUM \
+ : YY_CAST (YYSIZE_T, -1)))
+
+#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
+
+
+/* Stored state numbers (used for stacks). */
+typedef yytype_int8 yy_state_t;
+
+/* State numbers in computations. */
+typedef int yy_state_fast_t;
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+
+#ifndef YY_ATTRIBUTE_PURE
+# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
+# else
+# define YY_ATTRIBUTE_PURE
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+# else
+# define YY_ATTRIBUTE_UNUSED
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YY_USE(E) ((void) (E))
+#else
+# define YY_USE(E) /* empty */
+#endif
+
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
+# else
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# endif
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_USELESS_CAST_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
+# define YY_IGNORE_USELESS_CAST_END \
+ _Pragma ("GCC diagnostic pop")
+#endif
+#ifndef YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_END
+#endif
+
+
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
+#if !defined yyoverflow
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* !defined yyoverflow */
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yy_state_t yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYPTRDIFF_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / YYSIZEOF (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYPTRDIFF_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 41
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 552
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 44
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 7
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 49
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 118
+
+/* YYMAXUTOK -- Last valid token kind. */
+#define YYMAXUTOK 285
+
+
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
+#define YYTRANSLATE(YYX) \
+ (0 <= (YYX) && (YYX) <= YYMAXUTOK \
+ ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \
+ : YYSYMBOL_YYUNDEF)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex. */
+static const yytype_int8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 39, 2, 2, 2, 36, 2, 2,
+ 41, 42, 34, 32, 43, 33, 2, 35, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 24, 40, 25, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 38, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 26,
+ 27, 28, 29, 30, 31, 37
+};
+
+#if YYDEBUG
+/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_int16 yyrline[] =
+{
+ 0, 167, 167, 168, 171, 172, 173, 175, 177, 182,
+ 188, 189, 190, 191, 197, 198, 199, 200, 201, 202,
+ 203, 205, 207, 209, 211, 213, 214, 215, 216, 217,
+ 218, 220, 221, 223, 224, 226, 228, 229, 231, 232,
+ 234, 235, 236, 238, 240, 246, 257, 258, 261, 262
+};
+#endif
+
+/** Accessing symbol of state STATE. */
+#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
+
+#if YYDEBUG || 0
+/* The user-facing name of the symbol whose (internal) number is
+ YYSYMBOL. No bounds checking. */
+static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
+
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "\"end of file\"", "error", "\"invalid token\"", "EOS", "BAD", "HELP",
+ "HEX", "DECIMAL", "QUIT", "ABS", "BIN", "FIB", "GCD", "KRON", "LCM",
+ "LUCNUM", "NEXTPRIME", "POWM", "ROOT", "SQRT", "NUMBER", "VARIABLE",
+ "LOR", "LAND", "'<'", "'>'", "EQ", "NE", "LE", "GE", "LSHIFT", "RSHIFT",
+ "'+'", "'-'", "'*'", "'/'", "'%'", "UMINUS", "'^'", "'!'", "'='", "'('",
+ "')'", "','", "$accept", "top", "statements", "statement", "e",
+ "gcdlist", "lcmlist", YY_NULLPTR
+};
+
+static const char *
+yysymbol_name (yysymbol_kind_t yysymbol)
+{
+ return yytname[yysymbol];
+}
+#endif
+
+#define YYPACT_NINF (-39)
+
+#define yypact_value_is_default(Yyn) \
+ ((Yyn) == YYPACT_NINF)
+
+#define YYTABLE_NINF (-8)
+
+#define yytable_value_is_error(Yyn) \
+ ((Yyn) == YYTABLE_NINF)
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int16 yypact[] =
+{
+ 41, 3, -39, -39, -39, -39, 2, 4, 27, 32,
+ 35, 36, 39, 42, 45, 46, 47, -39, -18, 124,
+ 124, 89, 91, 87, 464, -39, 124, 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, -39, -36,
+ 254, -39, 88, -39, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ -39, 275, 144, 296, 464, -38, 166, 464, 29, 317,
+ 338, 188, 210, 359, 464, -39, -39, 481, 497, 513,
+ 513, 513, 513, 513, 513, 31, 31, -15, -15, -36,
+ -36, -36, -36, -39, 124, -39, -39, 124, 124, -39,
+ 124, -39, -39, 124, 124, -39, 380, 464, 401, 464,
+ 232, 422, -39, -39, 124, -39, 443, -39
+};
+
+/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_int8 yydefact[] =
+{
+ 0, 0, 10, 11, 12, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 45, 44, 0,
+ 0, 0, 7, 2, 8, 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 44, 24,
+ 0, 1, 3, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 23, 0, 0, 0, 46, 0, 0, 48, 0, 0,
+ 0, 0, 0, 0, 9, 14, 5, 32, 31, 25,
+ 30, 27, 28, 26, 29, 21, 22, 15, 16, 17,
+ 18, 19, 20, 33, 0, 35, 36, 0, 0, 38,
+ 0, 39, 40, 0, 0, 43, 0, 47, 0, 49,
+ 0, 0, 34, 37, 0, 42, 0, 41
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
+{
+ -39, -39, -39, 70, -19, -39, -39
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] =
+{
+ 0, 21, 22, 23, 24, 65, 68
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_int8 yytable[] =
+{
+ 39, 40, 59, 60, 96, 97, 25, 61, 62, 63,
+ 64, 66, 67, 69, 70, 71, 72, 73, 74, 56,
+ 57, 58, 37, 59, 60, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, -7, 1, 26, -7, 27, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 54, 55, 56, 57, 58, 28, 59,
+ 60, 99, 100, 29, 19, 106, 30, 31, 107, 108,
+ 32, 109, 20, 33, 110, 111, 34, 35, 36, 41,
+ 43, 76, 42, 0, 0, 116, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 19, 0, 0, 0, 0, 0,
+ 0, 0, 20, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 38, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 19, 0, 0,
+ 0, 0, 0, 0, 0, 20, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 0, 59, 60, 0, 0, 0, 94, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 0, 59, 60, 0, 0, 0, 98,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 0, 59, 60, 0, 0,
+ 0, 103, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 0, 59, 60,
+ 0, 0, 0, 104, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 0,
+ 59, 60, 0, 0, 0, 114, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 0, 59, 60, 0, 0, 75, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 0, 59, 60, 0, 0, 93, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 0, 59, 60, 0, 0, 95, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 0, 59, 60, 0, 0, 101,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 0, 59, 60, 0, 0,
+ 102, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 0, 59, 60, 0,
+ 0, 105, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 0, 59, 60,
+ 0, 0, 112, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 0, 59,
+ 60, 0, 0, 113, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 0,
+ 59, 60, 0, 0, 115, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 0, 59, 60, 0, 0, 117, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 0, 59, 60, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 0, 59,
+ 60, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 0, 59, 60, -8, -8, -8,
+ -8, -8, -8, 52, 53, 54, 55, 56, 57, 58,
+ 0, 59, 60
+};
+
+static const yytype_int8 yycheck[] =
+{
+ 19, 20, 38, 39, 42, 43, 3, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 34,
+ 35, 36, 40, 38, 39, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 0, 1, 41, 3, 41, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 32, 33, 34, 35, 36, 41, 38,
+ 39, 42, 43, 41, 33, 94, 41, 41, 97, 98,
+ 41, 100, 41, 41, 103, 104, 41, 41, 41, 0,
+ 3, 3, 22, -1, -1, 114, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 33, -1, -1, -1, -1, -1,
+ -1, -1, 41, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 33, -1, -1,
+ -1, -1, -1, -1, -1, 41, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, -1, 38, 39, -1, -1, -1, 43, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, -1, 38, 39, -1, -1, -1, 43,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, -1, 38, 39, -1, -1,
+ -1, 43, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, -1, 38, 39,
+ -1, -1, -1, 43, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, -1,
+ 38, 39, -1, -1, -1, 43, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, -1, 38, 39, -1, -1, 42, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, -1, 38, 39, -1, -1, 42, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, -1, 38, 39, -1, -1, 42, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, -1, 38, 39, -1, -1, 42,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, -1, 38, 39, -1, -1,
+ 42, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, -1, 38, 39, -1,
+ -1, 42, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, -1, 38, 39,
+ -1, -1, 42, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, -1, 38,
+ 39, -1, -1, 42, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, -1,
+ 38, 39, -1, -1, 42, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ -1, 38, 39, -1, -1, 42, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, -1, 38, 39, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, -1, 38,
+ 39, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, -1, 38, 39, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ -1, 38, 39
+};
+
+/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
+ state STATE-NUM. */
+static const yytype_int8 yystos[] =
+{
+ 0, 1, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 33,
+ 41, 45, 46, 47, 48, 3, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 40, 21, 48,
+ 48, 0, 47, 3, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 38,
+ 39, 48, 48, 48, 48, 49, 48, 48, 50, 48,
+ 48, 48, 48, 48, 48, 42, 3, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 42, 43, 42, 42, 43, 43, 42,
+ 43, 42, 42, 43, 43, 42, 48, 48, 48, 48,
+ 48, 48, 42, 42, 43, 42, 48, 42
+};
+
+/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
+static const yytype_int8 yyr1[] =
+{
+ 0, 44, 45, 45, 46, 46, 46, 47, 47, 47,
+ 47, 47, 47, 47, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 49, 49, 50, 50
+};
+
+/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
+static const yytype_int8 yyr2[] =
+{
+ 0, 2, 1, 2, 2, 3, 2, 0, 1, 3,
+ 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 2, 2, 3, 3, 3, 3, 3,
+ 3, 3, 3, 4, 6, 4, 4, 6, 4, 4,
+ 4, 8, 6, 4, 1, 1, 1, 3, 1, 3
+};
+
+
+enum { YYENOMEM = -2 };
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+#define YYNOMEM goto yyexhaustedlab
+
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
+
+/* Backward compatibility with an undocumented macro.
+ Use YYerror or YYUNDEF. */
+#define YYERRCODE YYUNDEF
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+
+
+
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Kind, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyo,
+ yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
+{
+ FILE *yyoutput = yyo;
+ YY_USE (yyoutput);
+ if (!yyvaluep)
+ return;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YY_USE (yykind);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
+
+static void
+yy_symbol_print (FILE *yyo,
+ yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
+{
+ YYFPRINTF (yyo, "%s %s (",
+ yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
+
+ yy_symbol_value_print (yyo, yykind, yyvaluep);
+ YYFPRINTF (yyo, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,
+ int yyrule)
+{
+ int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr,
+ YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
+ &yyvsp[(yyi + 1) - (yynrhs)]);
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args) ((void) 0)
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg,
+ yysymbol_kind_t yykind, YYSTYPE *yyvaluep)
+{
+ YY_USE (yyvaluep);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YY_USE (yykind);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+/* Lookahead token kind. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int
+yyparse (void)
+{
+ yy_state_fast_t yystate = 0;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus = 0;
+
+ /* Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* Their size. */
+ YYPTRDIFF_T yystacksize = YYINITDEPTH;
+
+ /* The state stack: array, bottom, top. */
+ yy_state_t yyssa[YYINITDEPTH];
+ yy_state_t *yyss = yyssa;
+ yy_state_t *yyssp = yyss;
+
+ /* The semantic value stack: array, bottom, top. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp = yyvs;
+
+ int yyn;
+ /* The return value of yyparse. */
+ int yyresult;
+ /* Lookahead symbol kind. */
+ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ goto yysetstate;
+
+
+/*------------------------------------------------------------.
+| yynewstate -- push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+
+/*--------------------------------------------------------------------.
+| yysetstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
+ YY_IGNORE_USELESS_CAST_BEGIN
+ *yyssp = YY_CAST (yy_state_t, yystate);
+ YY_IGNORE_USELESS_CAST_END
+ YY_STACK_PRINT (yyss, yyssp);
+
+ if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ YYNOMEM;
+#else
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYPTRDIFF_T yysize = yyssp - yyss + 1;
+
+# if defined yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ yy_state_t *yyss1 = yyss;
+ YYSTYPE *yyvs1 = yyvs;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * YYSIZEOF (*yyssp),
+ &yyvs1, yysize * YYSIZEOF (*yyvsp),
+ &yystacksize);
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+# else /* defined YYSTACK_RELOCATE */
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ YYNOMEM;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yy_state_t *yyss1 = yyss;
+ union yyalloc *yyptr =
+ YY_CAST (union yyalloc *,
+ YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
+ if (! yyptr)
+ YYNOMEM;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YY_IGNORE_USELESS_CAST_BEGIN
+ YYDPRINTF ((stderr, "Stack size increased to %ld\n",
+ YY_CAST (long, yystacksize)));
+ YY_IGNORE_USELESS_CAST_END
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token\n"));
+ yychar = yylex ();
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = YYEOF;
+ yytoken = YYSYMBOL_YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else if (yychar == YYerror)
+ {
+ /* The scanner already issued an error message, process directly
+ to error recovery. But do not keep the error token as
+ lookahead, it is too special and may lead us to an endless
+ loop in error recovery. */
+ yychar = YYUNDEF;
+ yytoken = YYSYMBOL_YYerror;
+ goto yyerrlab1;
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 6: /* statements: error EOS */
+#line 173 "../../../gmp/demos/calc/calc.y"
+ { sp = stack[0]; yyerrok; }
+#line 1508 "calc.c"
+ break;
+
+ case 8: /* statement: e */
+#line 177 "../../../gmp/demos/calc/calc.y"
+ {
+ mpz_out_str (stdout, obase, sp); putchar ('\n');
+ sp--;
+ CHECK_EMPTY ();
+ }
+#line 1518 "calc.c"
+ break;
+
+ case 9: /* statement: VARIABLE '=' e */
+#line 182 "../../../gmp/demos/calc/calc.y"
+ {
+ CHECK_VARIABLE ((yyvsp[-2].var));
+ mpz_swap (variable[(yyvsp[-2].var)], sp);
+ sp--;
+ CHECK_EMPTY ();
+ }
+#line 1529 "calc.c"
+ break;
+
+ case 10: /* statement: HELP */
+#line 188 "../../../gmp/demos/calc/calc.y"
+ { calc_help (); }
+#line 1535 "calc.c"
+ break;
+
+ case 11: /* statement: HEX */
+#line 189 "../../../gmp/demos/calc/calc.y"
+ { ibase = 16; obase = -16; }
+#line 1541 "calc.c"
+ break;
+
+ case 12: /* statement: DECIMAL */
+#line 190 "../../../gmp/demos/calc/calc.y"
+ { ibase = 0; obase = 10; }
+#line 1547 "calc.c"
+ break;
+
+ case 13: /* statement: QUIT */
+#line 191 "../../../gmp/demos/calc/calc.y"
+ { exit (0); }
+#line 1553 "calc.c"
+ break;
+
+ case 15: /* e: e '+' e */
+#line 198 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_add (sp, sp, sp+1); }
+#line 1559 "calc.c"
+ break;
+
+ case 16: /* e: e '-' e */
+#line 199 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_sub (sp, sp, sp+1); }
+#line 1565 "calc.c"
+ break;
+
+ case 17: /* e: e '*' e */
+#line 200 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_mul (sp, sp, sp+1); }
+#line 1571 "calc.c"
+ break;
+
+ case 18: /* e: e '/' e */
+#line 201 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_fdiv_q (sp, sp, sp+1); }
+#line 1577 "calc.c"
+ break;
+
+ case 19: /* e: e '%' e */
+#line 202 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_fdiv_r (sp, sp, sp+1); }
+#line 1583 "calc.c"
+ break;
+
+ case 20: /* e: e '^' e */
+#line 203 "../../../gmp/demos/calc/calc.y"
+ { CHECK_UI ("Exponent", sp);
+ sp--; mpz_pow_ui (sp, sp, mpz_get_ui (sp+1)); }
+#line 1590 "calc.c"
+ break;
+
+ case 21: /* e: e LSHIFT e */
+#line 205 "../../../gmp/demos/calc/calc.y"
+ { CHECK_UI ("Shift count", sp);
+ sp--; mpz_mul_2exp (sp, sp, mpz_get_ui (sp+1)); }
+#line 1597 "calc.c"
+ break;
+
+ case 22: /* e: e RSHIFT e */
+#line 207 "../../../gmp/demos/calc/calc.y"
+ { CHECK_UI ("Shift count", sp);
+ sp--; mpz_fdiv_q_2exp (sp, sp, mpz_get_ui (sp+1)); }
+#line 1604 "calc.c"
+ break;
+
+ case 23: /* e: e '!' */
+#line 209 "../../../gmp/demos/calc/calc.y"
+ { CHECK_UI ("Factorial", sp);
+ mpz_fac_ui (sp, mpz_get_ui (sp)); }
+#line 1611 "calc.c"
+ break;
+
+ case 24: /* e: '-' e */
+#line 211 "../../../gmp/demos/calc/calc.y"
+ { mpz_neg (sp, sp); }
+#line 1617 "calc.c"
+ break;
+
+ case 25: /* e: e '<' e */
+#line 213 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) < 0); }
+#line 1623 "calc.c"
+ break;
+
+ case 26: /* e: e LE e */
+#line 214 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) <= 0); }
+#line 1629 "calc.c"
+ break;
+
+ case 27: /* e: e EQ e */
+#line 215 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) == 0); }
+#line 1635 "calc.c"
+ break;
+
+ case 28: /* e: e NE e */
+#line 216 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) != 0); }
+#line 1641 "calc.c"
+ break;
+
+ case 29: /* e: e GE e */
+#line 217 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) >= 0); }
+#line 1647 "calc.c"
+ break;
+
+ case 30: /* e: e '>' e */
+#line 218 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) > 0); }
+#line 1653 "calc.c"
+ break;
+
+ case 31: /* e: e LAND e */
+#line 220 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_set_ui (sp, mpz_sgn (sp) && mpz_sgn (sp+1)); }
+#line 1659 "calc.c"
+ break;
+
+ case 32: /* e: e LOR e */
+#line 221 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_set_ui (sp, mpz_sgn (sp) || mpz_sgn (sp+1)); }
+#line 1665 "calc.c"
+ break;
+
+ case 33: /* e: ABS '(' e ')' */
+#line 223 "../../../gmp/demos/calc/calc.y"
+ { mpz_abs (sp, sp); }
+#line 1671 "calc.c"
+ break;
+
+ case 34: /* e: BIN '(' e ',' e ')' */
+#line 224 "../../../gmp/demos/calc/calc.y"
+ { sp--; CHECK_UI ("Binomial base", sp+1);
+ mpz_bin_ui (sp, sp, mpz_get_ui (sp+1)); }
+#line 1678 "calc.c"
+ break;
+
+ case 35: /* e: FIB '(' e ')' */
+#line 226 "../../../gmp/demos/calc/calc.y"
+ { CHECK_UI ("Fibonacci", sp);
+ mpz_fib_ui (sp, mpz_get_ui (sp)); }
+#line 1685 "calc.c"
+ break;
+
+ case 37: /* e: KRON '(' e ',' e ')' */
+#line 229 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_set_si (sp,
+ mpz_kronecker (sp, sp+1)); }
+#line 1692 "calc.c"
+ break;
+
+ case 39: /* e: LUCNUM '(' e ')' */
+#line 232 "../../../gmp/demos/calc/calc.y"
+ { CHECK_UI ("Lucas number", sp);
+ mpz_lucnum_ui (sp, mpz_get_ui (sp)); }
+#line 1699 "calc.c"
+ break;
+
+ case 40: /* e: NEXTPRIME '(' e ')' */
+#line 234 "../../../gmp/demos/calc/calc.y"
+ { mpz_nextprime (sp, sp); }
+#line 1705 "calc.c"
+ break;
+
+ case 41: /* e: POWM '(' e ',' e ',' e ')' */
+#line 235 "../../../gmp/demos/calc/calc.y"
+ { sp -= 2; mpz_powm (sp, sp, sp+1, sp+2); }
+#line 1711 "calc.c"
+ break;
+
+ case 42: /* e: ROOT '(' e ',' e ')' */
+#line 236 "../../../gmp/demos/calc/calc.y"
+ { sp--; CHECK_UI ("Nth-root", sp+1);
+ mpz_root (sp, sp, mpz_get_ui (sp+1)); }
+#line 1718 "calc.c"
+ break;
+
+ case 43: /* e: SQRT '(' e ')' */
+#line 238 "../../../gmp/demos/calc/calc.y"
+ { mpz_sqrt (sp, sp); }
+#line 1724 "calc.c"
+ break;
+
+ case 44: /* e: VARIABLE */
+#line 240 "../../../gmp/demos/calc/calc.y"
+ {
+ sp++;
+ CHECK_OVERFLOW ();
+ CHECK_VARIABLE ((yyvsp[0].var));
+ mpz_set (sp, variable[(yyvsp[0].var)]);
+ }
+#line 1735 "calc.c"
+ break;
+
+ case 45: /* e: NUMBER */
+#line 246 "../../../gmp/demos/calc/calc.y"
+ {
+ sp++;
+ CHECK_OVERFLOW ();
+ if (mpz_set_str (sp, (yyvsp[0].str), ibase) != 0)
+ {
+ fprintf (stderr, "Invalid number: %s\n", (yyvsp[0].str));
+ YYERROR;
+ }
+ }
+#line 1749 "calc.c"
+ break;
+
+ case 47: /* gcdlist: gcdlist ',' e */
+#line 258 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_gcd (sp, sp, sp+1); }
+#line 1755 "calc.c"
+ break;
+
+ case 49: /* lcmlist: lcmlist ',' e */
+#line 262 "../../../gmp/demos/calc/calc.y"
+ { sp--; mpz_lcm (sp, sp, sp+1); }
+#line 1761 "calc.c"
+ break;
+
+
+#line 1765 "calc.c"
+
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+
+ *++yyvsp = yyval;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+ ? yytable[yyi]
+ : yydefgoto[yylhs]);
+ }
+
+ goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+ yyerror (YY_("syntax error"));
+ }
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
+ ++yynerrs;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ /* Pop stack until we find a state that shifts the error token. */
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYSYMBOL_YYerror;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ YY_ACCESSING_SYMBOL (yystate), yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturnlab;
+
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturnlab;
+
+
+/*-----------------------------------------------------------.
+| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
+`-----------------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ goto yyreturnlab;
+
+
+/*----------------------------------------------------------.
+| yyreturnlab -- parsing is finished, clean up and return. |
+`----------------------------------------------------------*/
+yyreturnlab:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ YY_ACCESSING_SYMBOL (+*yyssp), yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+
+ return yyresult;
+}
+
+#line 264 "../../../gmp/demos/calc/calc.y"
+
+
+yyerror (char *s)
+{
+ fprintf (stderr, "%s\n", s);
+}
+
+int calc_option_readline = -1;
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], "--readline") == 0)
+ calc_option_readline = 1;
+ else if (strcmp (argv[i], "--noreadline") == 0)
+ calc_option_readline = 0;
+ else if (strcmp (argv[i], "--help") == 0)
+ {
+ printf ("Usage: calc [--option]...\n");
+ printf (" --readline use readline\n");
+ printf (" --noreadline don't use readline\n");
+ printf (" --help this message\n");
+ printf ("Readline is only available when compiled in,\n");
+ printf ("and in that case it's the default on a tty.\n");
+ exit (0);
+ }
+ else
+ {
+ fprintf (stderr, "Unrecognised option: %s\n", argv[i]);
+ exit (1);
+ }
+ }
+
+#if WITH_READLINE
+ calc_init_readline ();
+#else
+ if (calc_option_readline == 1)
+ {
+ fprintf (stderr, "Readline support not available\n");
+ exit (1);
+ }
+#endif
+
+ for (i = 0; i < numberof (variable); i++)
+ mpz_init (variable[i]);
+
+ for (i = 0; i < numberof (stack); i++)
+ mpz_init (stack[i]);
+
+ return yyparse ();
+}
diff --git a/vendor/gmp-6.3.0/demos/calc/calc.h b/vendor/gmp-6.3.0/demos/calc/calc.h
new file mode 100644
index 0000000..4622aa9
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/calc/calc.h
@@ -0,0 +1,146 @@
+/* A Bison parser, made by GNU Bison 3.8.2. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
+#ifndef YY_YY_CALC_H_INCLUDED
+# define YY_YY_CALC_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token kinds. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ YYEMPTY = -2,
+ YYEOF = 0, /* "end of file" */
+ YYerror = 256, /* error */
+ YYUNDEF = 257, /* "invalid token" */
+ EOS = 258, /* EOS */
+ BAD = 259, /* BAD */
+ HELP = 260, /* HELP */
+ HEX = 261, /* HEX */
+ DECIMAL = 262, /* DECIMAL */
+ QUIT = 263, /* QUIT */
+ ABS = 264, /* ABS */
+ BIN = 265, /* BIN */
+ FIB = 266, /* FIB */
+ GCD = 267, /* GCD */
+ KRON = 268, /* KRON */
+ LCM = 269, /* LCM */
+ LUCNUM = 270, /* LUCNUM */
+ NEXTPRIME = 271, /* NEXTPRIME */
+ POWM = 272, /* POWM */
+ ROOT = 273, /* ROOT */
+ SQRT = 274, /* SQRT */
+ NUMBER = 275, /* NUMBER */
+ VARIABLE = 276, /* VARIABLE */
+ LOR = 277, /* LOR */
+ LAND = 278, /* LAND */
+ EQ = 279, /* EQ */
+ NE = 280, /* NE */
+ LE = 281, /* LE */
+ GE = 282, /* GE */
+ LSHIFT = 283, /* LSHIFT */
+ RSHIFT = 284, /* RSHIFT */
+ UMINUS = 285 /* UMINUS */
+ };
+ typedef enum yytokentype yytoken_kind_t;
+#endif
+/* Token kinds. */
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYerror 256
+#define YYUNDEF 257
+#define EOS 258
+#define BAD 259
+#define HELP 260
+#define HEX 261
+#define DECIMAL 262
+#define QUIT 263
+#define ABS 264
+#define BIN 265
+#define FIB 266
+#define GCD 267
+#define KRON 268
+#define LCM 269
+#define LUCNUM 270
+#define NEXTPRIME 271
+#define POWM 272
+#define ROOT 273
+#define SQRT 274
+#define NUMBER 275
+#define VARIABLE 276
+#define LOR 277
+#define LAND 278
+#define EQ 279
+#define NE 280
+#define LE 281
+#define GE 282
+#define LSHIFT 283
+#define RSHIFT 284
+#define UMINUS 285
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+union YYSTYPE
+{
+#line 142 "../../../gmp/demos/calc/calc.y"
+
+ char *str;
+ int var;
+
+#line 132 "calc.h"
+
+};
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+
+int yyparse (void);
+
+
+#endif /* !YY_YY_CALC_H_INCLUDED */
diff --git a/vendor/gmp-6.3.0/demos/calc/calc.y b/vendor/gmp-6.3.0/demos/calc/calc.y
new file mode 100644
index 0000000..0fa1206
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/calc/calc.y
@@ -0,0 +1,318 @@
+%{
+/* A simple integer desk calculator using yacc and gmp.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* This is a simple program, meant only to show one way to use GMP for this
+ sort of thing. There's few features, and error checking is minimal.
+ Standard input is read, calc_help() below shows the inputs accepted.
+
+ Expressions are evaluated as they're read. If user defined functions
+ were wanted it'd be necessary to build a parse tree like pexpr.c does, or
+ a list of operations for a stack based evaluator. That would also make
+ it possible to detect and optimize evaluations "mod m" like pexpr.c does.
+
+ A stack is used for intermediate values in the expression evaluation,
+ separate from the yacc parser stack. This is simple, makes error
+ recovery easy, minimizes the junk around mpz calls in the rules, and
+ saves initializing or clearing "mpz_t"s during a calculation. A
+ disadvantage though is that variables must be copied to the stack to be
+ worked on. A more sophisticated calculator or language system might be
+ able to avoid that when executing a compiled or semi-compiled form.
+
+ Avoiding repeated initializing and clearing of "mpz_t"s is important. In
+ this program the time spent parsing is obviously much greater than any
+ possible saving from this, but a proper calculator or language should
+ take some trouble over it. Don't be surprised if an init/clear takes 3
+ or more times as long as a 10 limb addition, depending on the system (see
+ the mpz_init_realloc_clear example in tune/README). */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gmp.h"
+#define NO_CALC_H /* because it conflicts with normal calc.c stuff */
+#include "calc-common.h"
+
+
+#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
+
+
+void
+calc_help (void)
+{
+ printf ("Examples:\n");
+ printf (" 2+3*4 expressions are evaluated\n");
+ printf (" x=5^6 variables a to z can be set and used\n");
+ printf ("Operators:\n");
+ printf (" + - * arithmetic\n");
+ printf (" / %% division and remainder (rounding towards negative infinity)\n");
+ printf (" ^ exponentiation\n");
+ printf (" ! factorial\n");
+ printf (" << >> left and right shifts\n");
+ printf (" <= >= > \\ comparisons, giving 1 if true, 0 if false\n");
+ printf (" == != < /\n");
+ printf (" && || logical and/or, giving 1 if true, 0 if false\n");
+ printf ("Functions:\n");
+ printf (" abs(n) absolute value\n");
+ printf (" bin(n,m) binomial coefficient\n");
+ printf (" fib(n) fibonacci number\n");
+ printf (" gcd(a,b,..) greatest common divisor\n");
+ printf (" kron(a,b) kronecker symbol\n");
+ printf (" lcm(a,b,..) least common multiple\n");
+ printf (" lucnum(n) lucas number\n");
+ printf (" nextprime(n) next prime after n\n");
+ printf (" powm(b,e,m) modulo powering, b^e%%m\n");
+ printf (" root(n,r) r-th root\n");
+ printf (" sqrt(n) square root\n");
+ printf ("Other:\n");
+ printf (" hex \\ set hex or decimal for input and output\n");
+ printf (" decimal / (\"0x\" can be used for hex too)\n");
+ printf (" quit exit program (EOF works too)\n");
+ printf (" ; statements are separated with a ; or newline\n");
+ printf (" \\ continue expressions with \\ before newline\n");
+ printf (" # xxx comments are # though to newline\n");
+ printf ("Hex numbers must be entered in upper case, to distinguish them from the\n");
+ printf ("variables a to f (like in bc).\n");
+}
+
+
+int ibase = 0;
+int obase = 10;
+
+
+/* The stack is a fixed size, which means there's a limit on the nesting
+ allowed in expressions. A more sophisticated program could let it grow
+ dynamically. */
+
+mpz_t stack[100];
+mpz_ptr sp = stack[0];
+
+#define CHECK_OVERFLOW() \
+ if (sp >= stack[numberof(stack)]) /* FIXME */ \
+ { \
+ fprintf (stderr, \
+ "Value stack overflow, too much nesting in expression\n"); \
+ YYERROR; \
+ }
+
+#define CHECK_EMPTY() \
+ if (sp != stack[0]) \
+ { \
+ fprintf (stderr, "Oops, expected the value stack to be empty\n"); \
+ sp = stack[0]; \
+ }
+
+
+mpz_t variable[26];
+
+#define CHECK_VARIABLE(var) \
+ if ((var) < 0 || (var) >= numberof (variable)) \
+ { \
+ fprintf (stderr, "Oops, bad variable somehow: %d\n", var); \
+ YYERROR; \
+ }
+
+
+#define CHECK_UI(name,z) \
+ if (! mpz_fits_ulong_p (z)) \
+ { \
+ fprintf (stderr, "%s too big\n", name); \
+ YYERROR; \
+ }
+
+%}
+
+%union {
+ char *str;
+ int var;
+}
+
+%token EOS BAD
+%token HELP HEX DECIMAL QUIT
+%token ABS BIN FIB GCD KRON LCM LUCNUM NEXTPRIME POWM ROOT SQRT
+%token <str> NUMBER
+%token <var> VARIABLE
+
+/* operators, increasing precedence */
+%left LOR
+%left LAND
+%nonassoc '<' '>' EQ NE LE GE
+%left LSHIFT RSHIFT
+%left '+' '-'
+%left '*' '/' '%'
+%nonassoc UMINUS
+%right '^'
+%nonassoc '!'
+
+%%
+
+top:
+ statement
+ | statements statement;
+
+statements:
+ statement EOS
+ | statements statement EOS
+ | error EOS { sp = stack[0]; yyerrok; };
+
+statement:
+ /* empty */
+ | e {
+ mpz_out_str (stdout, obase, sp); putchar ('\n');
+ sp--;
+ CHECK_EMPTY ();
+ }
+ | VARIABLE '=' e {
+ CHECK_VARIABLE ($1);
+ mpz_swap (variable[$1], sp);
+ sp--;
+ CHECK_EMPTY ();
+ }
+ | HELP { calc_help (); }
+ | HEX { ibase = 16; obase = -16; }
+ | DECIMAL { ibase = 0; obase = 10; }
+ | QUIT { exit (0); };
+
+/* "e" leaves it's value on the top of the mpz stack. A rule like "e '+' e"
+ will have done a reduction for the first "e" first and the second "e"
+ second, so the code receives the values in that order on the stack. */
+e:
+ '(' e ')' /* value on stack */
+ | e '+' e { sp--; mpz_add (sp, sp, sp+1); }
+ | e '-' e { sp--; mpz_sub (sp, sp, sp+1); }
+ | e '*' e { sp--; mpz_mul (sp, sp, sp+1); }
+ | e '/' e { sp--; mpz_fdiv_q (sp, sp, sp+1); }
+ | e '%' e { sp--; mpz_fdiv_r (sp, sp, sp+1); }
+ | e '^' e { CHECK_UI ("Exponent", sp);
+ sp--; mpz_pow_ui (sp, sp, mpz_get_ui (sp+1)); }
+ | e LSHIFT e { CHECK_UI ("Shift count", sp);
+ sp--; mpz_mul_2exp (sp, sp, mpz_get_ui (sp+1)); }
+ | e RSHIFT e { CHECK_UI ("Shift count", sp);
+ sp--; mpz_fdiv_q_2exp (sp, sp, mpz_get_ui (sp+1)); }
+ | e '!' { CHECK_UI ("Factorial", sp);
+ mpz_fac_ui (sp, mpz_get_ui (sp)); }
+ | '-' e %prec UMINUS { mpz_neg (sp, sp); }
+
+ | e '<' e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) < 0); }
+ | e LE e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) <= 0); }
+ | e EQ e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) == 0); }
+ | e NE e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) != 0); }
+ | e GE e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) >= 0); }
+ | e '>' e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) > 0); }
+
+ | e LAND e { sp--; mpz_set_ui (sp, mpz_sgn (sp) && mpz_sgn (sp+1)); }
+ | e LOR e { sp--; mpz_set_ui (sp, mpz_sgn (sp) || mpz_sgn (sp+1)); }
+
+ | ABS '(' e ')' { mpz_abs (sp, sp); }
+ | BIN '(' e ',' e ')' { sp--; CHECK_UI ("Binomial base", sp+1);
+ mpz_bin_ui (sp, sp, mpz_get_ui (sp+1)); }
+ | FIB '(' e ')' { CHECK_UI ("Fibonacci", sp);
+ mpz_fib_ui (sp, mpz_get_ui (sp)); }
+ | GCD '(' gcdlist ')' /* value on stack */
+ | KRON '(' e ',' e ')' { sp--; mpz_set_si (sp,
+ mpz_kronecker (sp, sp+1)); }
+ | LCM '(' lcmlist ')' /* value on stack */
+ | LUCNUM '(' e ')' { CHECK_UI ("Lucas number", sp);
+ mpz_lucnum_ui (sp, mpz_get_ui (sp)); }
+ | NEXTPRIME '(' e ')' { mpz_nextprime (sp, sp); }
+ | POWM '(' e ',' e ',' e ')' { sp -= 2; mpz_powm (sp, sp, sp+1, sp+2); }
+ | ROOT '(' e ',' e ')' { sp--; CHECK_UI ("Nth-root", sp+1);
+ mpz_root (sp, sp, mpz_get_ui (sp+1)); }
+ | SQRT '(' e ')' { mpz_sqrt (sp, sp); }
+
+ | VARIABLE {
+ sp++;
+ CHECK_OVERFLOW ();
+ CHECK_VARIABLE ($1);
+ mpz_set (sp, variable[$1]);
+ }
+ | NUMBER {
+ sp++;
+ CHECK_OVERFLOW ();
+ if (mpz_set_str (sp, $1, ibase) != 0)
+ {
+ fprintf (stderr, "Invalid number: %s\n", $1);
+ YYERROR;
+ }
+ };
+
+gcdlist:
+ e /* value on stack */
+ | gcdlist ',' e { sp--; mpz_gcd (sp, sp, sp+1); };
+
+lcmlist:
+ e /* value on stack */
+ | lcmlist ',' e { sp--; mpz_lcm (sp, sp, sp+1); };
+
+%%
+
+yyerror (char *s)
+{
+ fprintf (stderr, "%s\n", s);
+}
+
+int calc_option_readline = -1;
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], "--readline") == 0)
+ calc_option_readline = 1;
+ else if (strcmp (argv[i], "--noreadline") == 0)
+ calc_option_readline = 0;
+ else if (strcmp (argv[i], "--help") == 0)
+ {
+ printf ("Usage: calc [--option]...\n");
+ printf (" --readline use readline\n");
+ printf (" --noreadline don't use readline\n");
+ printf (" --help this message\n");
+ printf ("Readline is only available when compiled in,\n");
+ printf ("and in that case it's the default on a tty.\n");
+ exit (0);
+ }
+ else
+ {
+ fprintf (stderr, "Unrecognised option: %s\n", argv[i]);
+ exit (1);
+ }
+ }
+
+#if WITH_READLINE
+ calc_init_readline ();
+#else
+ if (calc_option_readline == 1)
+ {
+ fprintf (stderr, "Readline support not available\n");
+ exit (1);
+ }
+#endif
+
+ for (i = 0; i < numberof (variable); i++)
+ mpz_init (variable[i]);
+
+ for (i = 0; i < numberof (stack); i++)
+ mpz_init (stack[i]);
+
+ return yyparse ();
+}
diff --git a/vendor/gmp-6.3.0/demos/calc/calclex.c b/vendor/gmp-6.3.0/demos/calc/calclex.c
new file mode 100644
index 0000000..7884001
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/calc/calclex.c
@@ -0,0 +1,1933 @@
+
+#line 3 "calclex.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 37
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+#if defined(__FreeBSD__)
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+#include <sys/cdefs.h>
+#include <stdint.h>
+#else
+#define __dead2
+#endif
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined(__FreeBSD__) || \
+ (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ yy_size_t yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+#define yy_current_buffer YY_CURRENT_BUFFER
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */
+yy_size_t yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len );
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] ) __dead2;
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 19
+#define YY_END_OF_BUFFER 20
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[39] =
+ { 0,
+ 0, 0, 20, 18, 1, 2, 7, 6, 7, 18,
+ 16, 16, 2, 7, 7, 7, 16, 17, 18, 18,
+ 11, 6, 5, 6, 14, 16, 0, 12, 8, 10,
+ 9, 13, 16, 17, 3, 15, 4, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 1, 5, 1, 6, 7, 1, 6,
+ 6, 6, 6, 6, 6, 1, 6, 8, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 1, 10, 11,
+ 12, 13, 1, 1, 14, 14, 14, 14, 14, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 16, 15, 15,
+ 1, 17, 1, 6, 1, 1, 15, 15, 15, 15,
+
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 16,
+ 15, 15, 1, 18, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[19] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 2, 2, 1,
+ 1, 1, 1, 2, 3, 2, 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[43] =
+ { 0,
+ 0, 0, 39, 49, 49, 49, 26, 16, 49, 30,
+ 20, 19, 49, 9, 22, 10, 9, 0, 29, 13,
+ 49, 23, 49, 24, 49, 0, 0, 49, 49, 49,
+ 49, 49, 13, 0, 49, 49, 49, 49, 41, 28,
+ 43, 45
+ } ;
+
+static yyconst flex_int16_t yy_def[43] =
+ { 0,
+ 38, 1, 38, 38, 38, 38, 38, 39, 38, 38,
+ 40, 40, 38, 38, 38, 38, 41, 42, 38, 38,
+ 38, 39, 38, 39, 38, 12, 12, 38, 38, 38,
+ 38, 38, 41, 42, 38, 38, 38, 0, 38, 38,
+ 38, 38
+ } ;
+
+static yyconst flex_int16_t yy_nxt[68] =
+ { 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 18, 19, 20, 23, 28,
+ 29, 31, 32, 34, 34, 23, 37, 34, 34, 26,
+ 36, 35, 24, 30, 38, 27, 25, 21, 38, 24,
+ 24, 22, 22, 22, 33, 33, 34, 34, 3, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38
+ } ;
+
+static yyconst flex_int16_t yy_chk[68] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 8, 14,
+ 14, 16, 16, 17, 17, 22, 24, 33, 33, 40,
+ 20, 19, 8, 15, 12, 11, 10, 7, 3, 22,
+ 24, 39, 39, 39, 41, 41, 42, 42, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "../../../gmp/demos/calc/calclex.l"
+/* Lexical analyzer for calc program.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+#line 20 "../../../gmp/demos/calc/calclex.l"
+#include <string.h>
+#include "calc-common.h"
+
+
+#if WITH_READLINE
+/* Let GNU flex use readline. See the calcread.c redefined input() for a
+ way that might work for a standard lex too. */
+#define YY_INPUT(buf,result,max_size) \
+ result = calc_input (buf, max_size);
+#endif
+
+
+/* Non-zero when reading the second or subsequent line of an expression,
+ used to give a different prompt when using readline. */
+int calc_more_input = 0;
+
+
+const struct calc_keywords_t calc_keywords[] = {
+ { "abs", ABS },
+ { "bin", BIN },
+ { "decimal", DECIMAL },
+ { "fib", FIB },
+ { "hex", HEX },
+ { "help", HELP },
+ { "gcd", GCD },
+ { "kron", KRON },
+ { "lcm", LCM },
+ { "lucnum", LUCNUM },
+ { "nextprime", NEXTPRIME },
+ { "powm", POWM },
+ { "quit", QUIT },
+ { "root", ROOT },
+ { "sqrt", SQRT },
+ { NULL }
+};
+#line 539 "calclex.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * out_str );
+
+yy_size_t yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+ static void yyunput (int c,char *buf_ptr );
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+
+#line 57 "../../../gmp/demos/calc/calclex.l"
+
+
+#line 726 "calclex.c"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 39 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 49 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 59 "../../../gmp/demos/calc/calclex.l"
+{ /* white space is skipped */ }
+ YY_BREAK
+case 2:
+/* rule 2 can match eol */
+YY_RULE_SETUP
+#line 61 "../../../gmp/demos/calc/calclex.l"
+{ /* semicolon or newline separates statements */
+ calc_more_input = 0;
+ return EOS; }
+ YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 64 "../../../gmp/demos/calc/calclex.l"
+{ /* escaped newlines are skipped */ }
+ YY_BREAK
+case 4:
+/* rule 4 can match eol */
+YY_RULE_SETUP
+#line 67 "../../../gmp/demos/calc/calclex.l"
+{
+ /* comment through to escaped newline is skipped */ }
+ YY_BREAK
+case 5:
+/* rule 5 can match eol */
+YY_RULE_SETUP
+#line 69 "../../../gmp/demos/calc/calclex.l"
+{ /* comment through to newline is a separator */
+ calc_more_input = 0;
+ return EOS; }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 72 "../../../gmp/demos/calc/calclex.l"
+{ /* comment through to EOF skipped */ }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 75 "../../../gmp/demos/calc/calclex.l"
+{ return yytext[0]; }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 76 "../../../gmp/demos/calc/calclex.l"
+{ return LE; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 77 "../../../gmp/demos/calc/calclex.l"
+{ return GE; }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 78 "../../../gmp/demos/calc/calclex.l"
+{ return EQ; }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 79 "../../../gmp/demos/calc/calclex.l"
+{ return NE; }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 80 "../../../gmp/demos/calc/calclex.l"
+{ return LSHIFT; }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 81 "../../../gmp/demos/calc/calclex.l"
+{ return RSHIFT; }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 82 "../../../gmp/demos/calc/calclex.l"
+{ return LAND; }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 83 "../../../gmp/demos/calc/calclex.l"
+{ return LOR; }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 85 "../../../gmp/demos/calc/calclex.l"
+{
+ yylval.str = yytext;
+ return NUMBER; }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 89 "../../../gmp/demos/calc/calclex.l"
+{
+ int i;
+
+ for (i = 0; calc_keywords[i].name != NULL; i++)
+ if (strcmp (yytext, calc_keywords[i].name) == 0)
+ return calc_keywords[i].value;
+
+ if (yytext[0] >= 'a' && yytext[0] <= 'z' && yytext[1] == '\0')
+ {
+ yylval.var = yytext[0] - 'a';
+ return VARIABLE;
+ }
+
+ return BAD;
+}
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 105 "../../../gmp/demos/calc/calclex.l"
+{ return BAD; }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 107 "../../../gmp/demos/calc/calclex.l"
+ECHO;
+ YY_BREAK
+#line 929 "calclex.c"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = (yytext_ptr);
+ int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ yy_size_t num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ yy_size_t new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 39 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ int yy_is_jam;
+ char *yy_cp = (yy_c_buf_p);
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 39 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 38);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+ static void yyunput (int c, char * yy_bp )
+{
+ char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up yytext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ yy_size_t number_to_move = (yy_n_chars) + 2;
+ char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+#endif /* ifndef YY_NO_UNPUT */
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf );
+
+ yyfree((void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ yy_size_t num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ yy_size_t i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+yy_size_t yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void yyset_lineno (int line_number )
+{
+
+ yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str )
+{
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str )
+{
+ yyout = out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int bdebug )
+{
+ yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 107 "../../../gmp/demos/calc/calclex.l"
+
+
+
+int
+yywrap ()
+{
+ return 1;
+}
+
diff --git a/vendor/gmp-6.3.0/demos/calc/calclex.l b/vendor/gmp-6.3.0/demos/calc/calclex.l
new file mode 100644
index 0000000..44df848
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/calc/calclex.l
@@ -0,0 +1,113 @@
+/* Lexical analyzer for calc program.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+%{
+#include <string.h>
+#include "calc-common.h"
+
+
+#if WITH_READLINE
+/* Let GNU flex use readline. See the calcread.c redefined input() for a
+ way that might work for a standard lex too. */
+#define YY_INPUT(buf,result,max_size) \
+ result = calc_input (buf, max_size);
+#endif
+
+
+/* Non-zero when reading the second or subsequent line of an expression,
+ used to give a different prompt when using readline. */
+int calc_more_input = 0;
+
+
+const struct calc_keywords_t calc_keywords[] = {
+ { "abs", ABS },
+ { "bin", BIN },
+ { "decimal", DECIMAL },
+ { "fib", FIB },
+ { "hex", HEX },
+ { "help", HELP },
+ { "gcd", GCD },
+ { "kron", KRON },
+ { "lcm", LCM },
+ { "lucnum", LUCNUM },
+ { "nextprime", NEXTPRIME },
+ { "powm", POWM },
+ { "quit", QUIT },
+ { "root", ROOT },
+ { "sqrt", SQRT },
+ { NULL }
+};
+%}
+
+%%
+
+[ \t\f] { /* white space is skipped */ }
+
+[;\n] { /* semicolon or newline separates statements */
+ calc_more_input = 0;
+ return EOS; }
+\\\n { /* escaped newlines are skipped */ }
+
+
+#(([^\\\n]*)\\)+\n {
+ /* comment through to escaped newline is skipped */ }
+#[^\n]*\n { /* comment through to newline is a separator */
+ calc_more_input = 0;
+ return EOS; }
+#[^\n]* { /* comment through to EOF skipped */ }
+
+
+[-+*/%()<>^!=,] { return yytext[0]; }
+"<=" { return LE; }
+">=" { return GE; }
+"==" { return EQ; }
+"!=" { return NE; }
+"<<" { return LSHIFT; }
+">>" { return RSHIFT; }
+"&&" { return LAND; }
+"||" { return LOR; }
+
+(0[xX])?[0-9A-F]+ {
+ yylval.str = yytext;
+ return NUMBER; }
+
+[a-zA-Z][a-zA-Z0-9]* {
+ int i;
+
+ for (i = 0; calc_keywords[i].name != NULL; i++)
+ if (strcmp (yytext, calc_keywords[i].name) == 0)
+ return calc_keywords[i].value;
+
+ if (yytext[0] >= 'a' && yytext[0] <= 'z' && yytext[1] == '\0')
+ {
+ yylval.var = yytext[0] - 'a';
+ return VARIABLE;
+ }
+
+ return BAD;
+}
+
+. { return BAD; }
+
+%%
+
+int
+yywrap ()
+{
+ return 1;
+}
diff --git a/vendor/gmp-6.3.0/demos/calc/calcread.c b/vendor/gmp-6.3.0/demos/calc/calcread.c
new file mode 100644
index 0000000..4043368
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/calc/calcread.c
@@ -0,0 +1,146 @@
+/* Readline support for calc program.
+
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+#include "calc-common.h"
+
+#if WITH_READLINE
+#include <stdio.h> /* for FILE for old versions of readline/readline.h */
+#include <stdlib.h> /* for free */
+#include <string.h> /* for strdup */
+#include <unistd.h> /* for isatty */
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#include "gmp.h"
+
+
+/* change this to "#define TRACE(x) x" for a few diagnostics */
+#define TRACE(x)
+
+
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+
+char *
+calc_completion_entry (const char *text, int state)
+{
+ static int index, len;
+ char *name;
+
+ if (!state)
+ {
+ index = 0;
+ len = strlen (text);
+ }
+ TRACE (printf ("calc_completion_entry %s %d, index=%d len=%d\n",
+ text, state, index, len));
+ while ((name = calc_keywords[index].name) != NULL)
+ {
+ index++;
+ if (memcmp (name, text, len) == 0)
+ return (strdup (name));
+ }
+ return NULL;
+}
+
+void
+calc_init_readline (void)
+{
+ /* By default use readline when the input is a tty. It's a bit contrary
+ to the GNU interface conventions to make the behaviour depend on where
+ the input is coming from, but this is pretty convenient. */
+ if (calc_option_readline == -1)
+ {
+ calc_option_readline = isatty (fileno (stdin));
+ TRACE (printf ("calc_option_readline %d\n", calc_option_readline));
+ }
+
+ if (calc_option_readline)
+ {
+ printf ("GNU MP demo calculator program, gmp version %s\n", gmp_version);
+ printf ("Type \"help\" for help.\n");
+ rl_readline_name = "gmp-calc";
+ rl_completion_entry_function = calc_completion_entry;
+ }
+}
+
+
+/* This function is supposed to return YY_NULL to indicate EOF, but that
+ constant is only in calclex.c and we don't want to clutter calclex.l with
+ this readline stuff, so instead just hard code 0 for YY_NULL. That's
+ it's defined value on unix anyway. */
+
+int
+calc_input (char *buf, size_t max_size)
+{
+ if (calc_option_readline)
+ {
+ static char *line = NULL;
+ static size_t line_size = 0;
+ static size_t upto = 0;
+ size_t copy_size;
+
+ if (upto >= line_size)
+ {
+ if (line != NULL)
+ free (line);
+
+ line = readline (calc_more_input ? "more> " : "> ");
+ calc_more_input = 1;
+ if (line == NULL)
+ return 0;
+ TRACE (printf ("readline: %s\n", line));
+
+ if (line[0] != '\0')
+ add_history (line);
+
+ line_size = strlen (line);
+ line[line_size] = '\n';
+ line_size++;
+ upto = 0;
+ }
+
+ copy_size = MIN (line_size-upto, max_size);
+ memcpy (buf, line+upto, copy_size);
+ upto += copy_size;
+ return copy_size;
+ }
+ else
+ {
+ /* not readline */
+ return fread (buf, 1, max_size, stdin);
+ }
+}
+
+
+/* This redefined input() might let a traditional lex use the readline
+ support here. Apparently POSIX doesn't specify whether an override like
+ this will work, so maybe it'll work or maybe it won't. This function is
+ also not particularly efficient, but don't worry about that, since flex
+ is the preferred parser. */
+
+int
+input (void)
+{
+ char c;
+ if (calc_input (&c, 1) != 1)
+ return EOF;
+ else
+ return (int) c;
+}
+
+#endif /* WITH_READLINE */
diff --git a/vendor/gmp-6.3.0/demos/expr/Makefile.am b/vendor/gmp-6.3.0/demos/expr/Makefile.am
new file mode 100644
index 0000000..252300a
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/Makefile.am
@@ -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
diff --git a/vendor/gmp-6.3.0/demos/expr/Makefile.in b/vendor/gmp-6.3.0/demos/expr/Makefile.in
new file mode 100644
index 0000000..354e239
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/Makefile.in
@@ -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:
diff --git a/vendor/gmp-6.3.0/demos/expr/README b/vendor/gmp-6.3.0/demos/expr/README
new file mode 100644
index 0000000..a54fe42
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/README
@@ -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:
diff --git a/vendor/gmp-6.3.0/demos/expr/expr-impl.h b/vendor/gmp-6.3.0/demos/expr/expr-impl.h
new file mode 100644
index 0000000..9b6458f
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/expr-impl.h
@@ -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);
diff --git a/vendor/gmp-6.3.0/demos/expr/expr.c b/vendor/gmp-6.3.0/demos/expr/expr.c
new file mode 100644
index 0000000..42dd796
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/expr.c
@@ -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;
+}
diff --git a/vendor/gmp-6.3.0/demos/expr/expr.h b/vendor/gmp-6.3.0/demos/expr/expr.h
new file mode 100644
index 0000000..d3b7c77
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/expr.h
@@ -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
diff --git a/vendor/gmp-6.3.0/demos/expr/exprf.c b/vendor/gmp-6.3.0/demos/expr/exprf.c
new file mode 100644
index 0000000..1f7e21f
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/exprf.c
@@ -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);
+}
diff --git a/vendor/gmp-6.3.0/demos/expr/exprfa.c b/vendor/gmp-6.3.0/demos/expr/exprfa.c
new file mode 100644
index 0000000..1918cb5
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/exprfa.c
@@ -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);
+}
diff --git a/vendor/gmp-6.3.0/demos/expr/exprq.c b/vendor/gmp-6.3.0/demos/expr/exprq.c
new file mode 100644
index 0000000..9643200
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/exprq.c
@@ -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);
+}
diff --git a/vendor/gmp-6.3.0/demos/expr/exprqa.c b/vendor/gmp-6.3.0/demos/expr/exprqa.c
new file mode 100644
index 0000000..f3b6ecb
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/exprqa.c
@@ -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);
+}
diff --git a/vendor/gmp-6.3.0/demos/expr/exprv.c b/vendor/gmp-6.3.0/demos/expr/exprv.c
new file mode 100644
index 0000000..c25741b
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/exprv.c
@@ -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;
+}
diff --git a/vendor/gmp-6.3.0/demos/expr/exprz.c b/vendor/gmp-6.3.0/demos/expr/exprz.c
new file mode 100644
index 0000000..bac1a99
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/exprz.c
@@ -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);
+}
diff --git a/vendor/gmp-6.3.0/demos/expr/exprza.c b/vendor/gmp-6.3.0/demos/expr/exprza.c
new file mode 100644
index 0000000..eda830d
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/exprza.c
@@ -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);
+}
diff --git a/vendor/gmp-6.3.0/demos/expr/run-expr.c b/vendor/gmp-6.3.0/demos/expr/run-expr.c
new file mode 100644
index 0000000..706b910
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/run-expr.c
@@ -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;
+}
diff --git a/vendor/gmp-6.3.0/demos/expr/t-expr.c b/vendor/gmp-6.3.0/demos/expr/t-expr.c
new file mode 100644
index 0000000..64fbfab
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/expr/t-expr.c
@@ -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);
+}
diff --git a/vendor/gmp-6.3.0/demos/factorize.c b/vendor/gmp-6.3.0/demos/factorize.c
new file mode 100644
index 0000000..91e6455
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/factorize.c
@@ -0,0 +1,447 @@
+/* Factoring with Pollard's rho method.
+
+Copyright 1995, 1997-2003, 2005, 2009, 2012, 2015 Free Software
+Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "gmp.h"
+
+static unsigned char primes_diff[] = {
+#define P(a,b,c) a,
+#include "primes.h"
+#undef P
+};
+#define PRIMES_PTAB_ENTRIES (sizeof(primes_diff) / sizeof(primes_diff[0]))
+
+int flag_verbose = 0;
+
+/* Prove primality or run probabilistic tests. */
+int flag_prove_primality = 1;
+
+/* Number of Miller-Rabin tests to run when not proving primality. */
+#define MR_REPS 25
+
+struct factors
+{
+ mpz_t *p;
+ unsigned long *e;
+ long nfactors;
+};
+
+void factor (mpz_t, struct factors *);
+
+void
+factor_init (struct factors *factors)
+{
+ factors->p = malloc (1);
+ factors->e = malloc (1);
+ factors->nfactors = 0;
+}
+
+void
+factor_clear (struct factors *factors)
+{
+ int i;
+
+ for (i = 0; i < factors->nfactors; i++)
+ mpz_clear (factors->p[i]);
+
+ free (factors->p);
+ free (factors->e);
+}
+
+void
+factor_insert (struct factors *factors, mpz_t prime)
+{
+ long nfactors = factors->nfactors;
+ mpz_t *p = factors->p;
+ unsigned long *e = factors->e;
+ long i, j;
+
+ /* Locate position for insert new or increment e. */
+ for (i = nfactors - 1; i >= 0; i--)
+ {
+ if (mpz_cmp (p[i], prime) <= 0)
+ break;
+ }
+
+ if (i < 0 || mpz_cmp (p[i], prime) != 0)
+ {
+ p = realloc (p, (nfactors + 1) * sizeof p[0]);
+ e = realloc (e, (nfactors + 1) * sizeof e[0]);
+
+ mpz_init (p[nfactors]);
+ for (j = nfactors - 1; j > i; j--)
+ {
+ mpz_set (p[j + 1], p[j]);
+ e[j + 1] = e[j];
+ }
+ mpz_set (p[i + 1], prime);
+ e[i + 1] = 1;
+
+ factors->p = p;
+ factors->e = e;
+ factors->nfactors = nfactors + 1;
+ }
+ else
+ {
+ e[i] += 1;
+ }
+}
+
+void
+factor_insert_ui (struct factors *factors, unsigned long prime)
+{
+ mpz_t pz;
+
+ mpz_init_set_ui (pz, prime);
+ factor_insert (factors, pz);
+ mpz_clear (pz);
+}
+
+
+void
+factor_using_division (mpz_t t, struct factors *factors)
+{
+ mpz_t q;
+ unsigned long int p;
+ int i;
+
+ if (flag_verbose > 0)
+ {
+ printf ("[trial division] ");
+ }
+
+ mpz_init (q);
+
+ p = mpz_scan1 (t, 0);
+ mpz_fdiv_q_2exp (t, t, p);
+ while (p)
+ {
+ factor_insert_ui (factors, 2);
+ --p;
+ }
+
+ p = 3;
+ for (i = 1; i <= PRIMES_PTAB_ENTRIES;)
+ {
+ if (! mpz_divisible_ui_p (t, p))
+ {
+ p += primes_diff[i++];
+ if (mpz_cmp_ui (t, p * p) < 0)
+ break;
+ }
+ else
+ {
+ mpz_tdiv_q_ui (t, t, p);
+ factor_insert_ui (factors, p);
+ }
+ }
+
+ mpz_clear (q);
+}
+
+static int
+mp_millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y,
+ mpz_srcptr q, unsigned long int k)
+{
+ unsigned long int i;
+
+ mpz_powm (y, x, q, n);
+
+ if (mpz_cmp_ui (y, 1) == 0 || mpz_cmp (y, nm1) == 0)
+ return 1;
+
+ for (i = 1; i < k; i++)
+ {
+ mpz_powm_ui (y, y, 2, n);
+ if (mpz_cmp (y, nm1) == 0)
+ return 1;
+ if (mpz_cmp_ui (y, 1) == 0)
+ return 0;
+ }
+ return 0;
+}
+
+int
+mp_prime_p (mpz_t n)
+{
+ int k, r, is_prime;
+ mpz_t q, a, nm1, tmp;
+ struct factors factors;
+
+ if (mpz_cmp_ui (n, 1) <= 0)
+ return 0;
+
+ /* We have already casted out small primes. */
+ if (mpz_cmp_ui (n, (long) FIRST_OMITTED_PRIME * FIRST_OMITTED_PRIME) < 0)
+ return 1;
+
+ mpz_inits (q, a, nm1, tmp, NULL);
+
+ /* Precomputation for Miller-Rabin. */
+ mpz_sub_ui (nm1, n, 1);
+
+ /* Find q and k, where q is odd and n = 1 + 2**k * q. */
+ k = mpz_scan1 (nm1, 0);
+ mpz_tdiv_q_2exp (q, nm1, k);
+
+ mpz_set_ui (a, 2);
+
+ /* Perform a Miller-Rabin test, finds most composites quickly. */
+ if (!mp_millerrabin (n, nm1, a, tmp, q, k))
+ {
+ is_prime = 0;
+ goto ret2;
+ }
+
+ if (flag_prove_primality)
+ {
+ /* Factor n-1 for Lucas. */
+ mpz_set (tmp, nm1);
+ factor (tmp, &factors);
+ }
+
+ /* Loop until Lucas proves our number prime, or Miller-Rabin proves our
+ number composite. */
+ for (r = 0; r < PRIMES_PTAB_ENTRIES; r++)
+ {
+ int i;
+
+ if (flag_prove_primality)
+ {
+ is_prime = 1;
+ for (i = 0; i < factors.nfactors && is_prime; i++)
+ {
+ mpz_divexact (tmp, nm1, factors.p[i]);
+ mpz_powm (tmp, a, tmp, n);
+ is_prime = mpz_cmp_ui (tmp, 1) != 0;
+ }
+ }
+ else
+ {
+ /* After enough Miller-Rabin runs, be content. */
+ is_prime = (r == MR_REPS - 1);
+ }
+
+ if (is_prime)
+ goto ret1;
+
+ mpz_add_ui (a, a, primes_diff[r]); /* Establish new base. */
+
+ if (!mp_millerrabin (n, nm1, a, tmp, q, k))
+ {
+ is_prime = 0;
+ goto ret1;
+ }
+ }
+
+ fprintf (stderr, "Lucas prime test failure. This should not happen\n");
+ abort ();
+
+ ret1:
+ if (flag_prove_primality)
+ factor_clear (&factors);
+ ret2:
+ mpz_clears (q, a, nm1, tmp, NULL);
+
+ return is_prime;
+}
+
+void
+factor_using_pollard_rho (mpz_t n, unsigned long a, struct factors *factors)
+{
+ mpz_t x, z, y, P;
+ mpz_t t, t2;
+ unsigned long long k, l, i;
+
+ if (flag_verbose > 0)
+ {
+ printf ("[pollard-rho (%lu)] ", a);
+ }
+
+ mpz_inits (t, t2, NULL);
+ mpz_init_set_si (y, 2);
+ mpz_init_set_si (x, 2);
+ mpz_init_set_si (z, 2);
+ mpz_init_set_ui (P, 1);
+ k = 1;
+ l = 1;
+
+ while (mpz_cmp_ui (n, 1) != 0)
+ {
+ for (;;)
+ {
+ do
+ {
+ mpz_mul (t, x, x);
+ mpz_mod (x, t, n);
+ mpz_add_ui (x, x, a);
+
+ mpz_sub (t, z, x);
+ mpz_mul (t2, P, t);
+ mpz_mod (P, t2, n);
+
+ if (k % 32 == 1)
+ {
+ mpz_gcd (t, P, n);
+ if (mpz_cmp_ui (t, 1) != 0)
+ goto factor_found;
+ mpz_set (y, x);
+ }
+ }
+ while (--k != 0);
+
+ mpz_set (z, x);
+ k = l;
+ l = 2 * l;
+ for (i = 0; i < k; i++)
+ {
+ mpz_mul (t, x, x);
+ mpz_mod (x, t, n);
+ mpz_add_ui (x, x, a);
+ }
+ mpz_set (y, x);
+ }
+
+ factor_found:
+ do
+ {
+ mpz_mul (t, y, y);
+ mpz_mod (y, t, n);
+ mpz_add_ui (y, y, a);
+
+ mpz_sub (t, z, y);
+ mpz_gcd (t, t, n);
+ }
+ while (mpz_cmp_ui (t, 1) == 0);
+
+ mpz_divexact (n, n, t); /* divide by t, before t is overwritten */
+
+ if (!mp_prime_p (t))
+ {
+ if (flag_verbose > 0)
+ {
+ printf ("[composite factor--restarting pollard-rho] ");
+ }
+ factor_using_pollard_rho (t, a + 1, factors);
+ }
+ else
+ {
+ factor_insert (factors, t);
+ }
+
+ if (mp_prime_p (n))
+ {
+ factor_insert (factors, n);
+ break;
+ }
+
+ mpz_mod (x, x, n);
+ mpz_mod (z, z, n);
+ mpz_mod (y, y, n);
+ }
+
+ mpz_clears (P, t2, t, z, x, y, NULL);
+}
+
+void
+factor (mpz_t t, struct factors *factors)
+{
+ factor_init (factors);
+
+ if (mpz_sgn (t) != 0)
+ {
+ factor_using_division (t, factors);
+
+ if (mpz_cmp_ui (t, 1) != 0)
+ {
+ if (flag_verbose > 0)
+ {
+ printf ("[is number prime?] ");
+ }
+ if (mp_prime_p (t))
+ factor_insert (factors, t);
+ else
+ factor_using_pollard_rho (t, 1, factors);
+ }
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpz_t t;
+ int i, j, k;
+ struct factors factors;
+
+ while (argc > 1)
+ {
+ if (!strcmp (argv[1], "-v"))
+ flag_verbose = 1;
+ else if (!strcmp (argv[1], "-w"))
+ flag_prove_primality = 0;
+ else
+ break;
+
+ argv++;
+ argc--;
+ }
+
+ mpz_init (t);
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; i++)
+ {
+ mpz_set_str (t, argv[i], 0);
+
+ gmp_printf ("%Zd:", t);
+ factor (t, &factors);
+
+ for (j = 0; j < factors.nfactors; j++)
+ for (k = 0; k < factors.e[j]; k++)
+ gmp_printf (" %Zd", factors.p[j]);
+
+ puts ("");
+ factor_clear (&factors);
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ mpz_inp_str (t, stdin, 0);
+ if (feof (stdin))
+ break;
+
+ gmp_printf ("%Zd:", t);
+ factor (t, &factors);
+
+ for (j = 0; j < factors.nfactors; j++)
+ for (k = 0; k < factors.e[j]; k++)
+ gmp_printf (" %Zd", factors.p[j]);
+
+ puts ("");
+ factor_clear (&factors);
+ }
+ }
+
+ exit (0);
+}
diff --git a/vendor/gmp-6.3.0/demos/isprime.c b/vendor/gmp-6.3.0/demos/isprime.c
new file mode 100644
index 0000000..bf06945
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/isprime.c
@@ -0,0 +1,69 @@
+/* Classify numbers as probable primes, primes or composites.
+ With -q return true if the following argument is a (probable) prime.
+
+Copyright 1999, 2000, 2002, 2005, 2012 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "gmp.h"
+
+char *progname;
+
+void
+print_usage_and_exit ()
+{
+ fprintf (stderr, "usage: %s -q nnn\n", progname);
+ fprintf (stderr, "usage: %s nnn ...\n", progname);
+ exit (-1);
+}
+
+int
+main (int argc, char **argv)
+{
+ mpz_t n;
+ int i;
+
+ progname = argv[0];
+
+ if (argc < 2)
+ print_usage_and_exit ();
+
+ mpz_init (n);
+
+ if (argc == 3 && strcmp (argv[1], "-q") == 0)
+ {
+ if (mpz_set_str (n, argv[2], 0) != 0)
+ print_usage_and_exit ();
+ exit (mpz_probab_prime_p (n, 25) == 0);
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ int class;
+ if (mpz_set_str (n, argv[i], 0) != 0)
+ print_usage_and_exit ();
+ class = mpz_probab_prime_p (n, 25);
+ mpz_out_str (stdout, 10, n);
+ if (class == 0)
+ puts (" is composite");
+ else if (class == 1)
+ puts (" is a probable prime");
+ else /* class == 2 */
+ puts (" is a prime");
+ }
+ exit (0);
+}
diff --git a/vendor/gmp-6.3.0/demos/perl/GMP.pm b/vendor/gmp-6.3.0/demos/perl/GMP.pm
new file mode 100644
index 0000000..46bc707
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/GMP.pm
@@ -0,0 +1,671 @@
+# GMP perl module
+
+# 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/.
+
+# [Note: The above copyright notice is repeated in the documentation section
+# below, in order to get it into man pages etc generated by the various pod
+# conversions. When changing, be sure to update below too.]
+
+
+# This code is designed to work with perl 5.005, so it and the sub-packages
+# aren't as modern as they could be.
+
+package GMP;
+
+require Symbol;
+require Exporter;
+require DynaLoader;
+@ISA = qw(Exporter DynaLoader);
+
+@EXPORT = qw();
+@EXPORT_OK = qw(version);
+%EXPORT_TAGS = ('all' => [qw(
+ get_d get_d_2exp get_si get_str integer_p
+ printf sgn sprintf)],
+ 'constants' => [()]);
+Exporter::export_ok_tags('all');
+
+$VERSION = '2.00';
+bootstrap GMP $VERSION;
+
+
+# The format string is cut up into "%" specifiers so GMP types can be
+# passed to GMP::sprintf_internal. Any "*"s are interpolated before
+# calling sprintf_internal, which saves worrying about variable
+# argument lists there.
+#
+# Because sprintf_internal is only called after the conversion and
+# operand have been checked there won't be any crashes from a bad
+# format string.
+#
+sub sprintf {
+ my $fmt = shift;
+ my $out = '';
+ my ($pre, $dummy, $pat, $rest);
+
+ while (($pre, $dummy, $pat, $rest) = ($fmt =~ /^((%%|[^%])*)(%[- +#.*hlLqv\d]*[bcdfeEgGinopsuxX])(.*)$/s)) {
+
+ $out .= $pre;
+
+ my $pat2 = $pat; # $pat with "*"s expanded
+ my @params = (); # arguments per "*"s
+ while ($pat2 =~ /[*]/) {
+ my $arg = shift;
+ $pat2 =~ s/[*]/$arg/;
+ push @params, $arg;
+ }
+
+ if (UNIVERSAL::isa($_[0],"GMP::Mpz")) {
+ if ($pat2 !~ /[dioxX]$/) {
+ die "GMP::sprintf: unsupported output format for mpz: $pat2\n";
+ }
+ $pat2 =~ s/(.)$/Z$1/;
+ $out .= sprintf_internal ($pat2, shift);
+
+ } elsif (UNIVERSAL::isa($_[0],"GMP::Mpq")) {
+ if ($pat2 !~ /[dioxX]$/) {
+ die "GMP::sprintf: unsupported output format for mpq: $pat2\n";
+ }
+ $pat2 =~ s/(.)$/Q$1/;
+ $out .= sprintf_internal ($pat2, shift);
+
+ } elsif (UNIVERSAL::isa($_[0],"GMP::Mpf")) {
+ if ($pat2 !~ /[eEfgG]$/) {
+ die "GMP::sprintf: unsupported output format for mpf: $pat2\n";
+ }
+ $pat2 =~ s/(.)$/F$1/;
+ $out .= sprintf_internal ($pat2, shift);
+
+ } elsif ($pat =~ /n$/) {
+ # do it this way so h, l or V type modifiers are respected, and use a
+ # dummy variable to avoid a warning about discarding the value
+ my $dummy = sprintf "%s$pat", $out, $_[0];
+ shift;
+
+ } else {
+ $out .= sprintf $pat, @params, shift;
+ }
+
+ $fmt = $rest;
+ }
+ $out .= $fmt;
+ return $out;
+}
+
+sub printf {
+ if (ref($_[0]) eq 'GLOB') {
+ my $h = Symbol::qualify_to_ref(shift, caller);
+ print $h GMP::sprintf(@_);
+ } else {
+ print STDOUT GMP::sprintf(@_);
+ }
+}
+
+1;
+__END__
+
+
+
+=head1 NAME
+
+GMP - Perl interface to the GNU Multiple Precision Arithmetic Library
+
+=head1 SYNOPSIS
+
+ use GMP;
+ use GMP::Mpz;
+ use GMP::Mpq;
+ use GMP::Mpf;
+ use GMP::Rand;
+
+=head1 DESCRIPTION
+
+This module provides access to GNU MP arbitrary precision integers,
+rationals and floating point.
+
+No functions are exported from these packages by default, but can be
+selected in the usual way, or the tag :all for everything.
+
+ use GMP::Mpz qw(gcd, lcm); # just these functions
+ use GMP::Mpq qw(:all); # everything in mpq
+
+=head2 GMP::Mpz
+
+This class provides arbitrary precision integers. A new mpz can be
+constructed with C<mpz>. The initial value can be an integer, float,
+string, mpz, mpq or mpf. Floats, mpq and mpf will be automatically
+truncated to an integer.
+
+ use GMP::Mpz qw(:all);
+ my $a = mpz(123);
+ my $b = mpz("0xFFFF");
+ my $c = mpz(1.5); # truncated
+
+The following overloaded operators are available, and corresponding
+assignment forms like C<+=>,
+
+=over 4
+
+=item
+
++ - * / % E<lt>E<lt> E<gt>E<gt> ** & | ^ ! E<lt> E<lt>= == != E<gt> E<gt>=
+E<lt>=E<gt> abs not sqrt
+
+=back
+
+C</> and C<%> round towards zero (as per the C<tdiv> functions in GMP).
+
+The following functions are available, behaving the same as the
+corresponding GMP mpz functions,
+
+=over 4
+
+=item
+
+bin, cdiv, cdiv_2exp, clrbit, combit, congruent_p, congruent_2exp_p,
+divexact, divisible_p, divisible_2exp_p, even_p, fac, fdiv, fdiv_2exp, fib,
+fib2, gcd, gcdext, hamdist, invert, jacobi, kronecker, lcm, lucnum, lucnum2,
+mod, mpz_export, mpz_import, nextprime, odd_p, perfect_power_p,
+perfect_square_p, popcount, powm, probab_prime_p, realloc, remove, root,
+roote, scan0, scan1, setbit, sizeinbase, sqrtrem, tdiv, tdiv_2exp, tstbit
+
+=back
+
+C<cdiv>, C<fdiv> and C<tdiv> and their C<2exp> variants return a
+quotient/remainder pair. C<fib2> returns a pair F[n] and F[n-1], similarly
+C<lucnum2>. C<gcd> and C<lcm> accept a variable number of arguments (one or
+more). C<gcdext> returns a triplet of gcd and two cofactors, for example
+
+ use GMP::Mpz qw(:all);
+ $a = 7257;
+ $b = 10701;
+ ($g, $x, $y) = gcdext ($a, $b);
+ print "gcd($a,$b) is $g, and $g == $a*$x + $b*$y\n";
+
+C<mpz_import> and C<mpz_export> are so named to avoid the C<import> keyword.
+Their parameters are as follows,
+
+ $z = mpz_import ($order, $size, $endian, $nails, $string);
+ $string = mpz_export ($order, $size, $endian, $nails, $z);
+
+The order, size, endian and nails parameters are as per the corresponding C
+functions. The string input for C<mpz_import> is interpreted as byte data
+and must be a multiple of $size bytes. C<mpz_export> conversely returns a
+string of byte data, which will be a multiple of $size bytes.
+
+C<invert> returns the inverse, or undef if it doesn't exist. C<remove>
+returns a remainder/multiplicity pair. C<root> returns the nth root, and
+C<roote> returns a root/bool pair, the bool indicating whether the root is
+exact. C<sqrtrem> and C<rootrem> return a root/remainder pair.
+
+C<clrbit>, C<combit> and C<setbit> expect a variable which they can modify,
+it doesn't make sense to pass a literal constant. Only the given variable
+is modified, if other variables are referencing the same mpz object then a
+new copy is made of it. If the variable isn't an mpz it will be coerced to
+one. For instance,
+
+ use GMP::Mpz qw(setbit);
+ setbit (123, 0); # wrong, don't pass a constant
+ $a = mpz(6);
+ $b = $a;
+ setbit ($a, 0); # $a becomes 7, $b stays at 6
+
+C<scan0> and C<scan1> return ~0 if no 0 or 1 bit respectively is found.
+
+=head2 GMP::Mpq
+
+This class provides rationals with arbitrary precision numerators and
+denominators. A new mpq can be constructed with C<mpq>. The initial value
+can be an integer, float, string, mpz, mpq or mpf, or a pair of integers or
+mpz's. No precision is lost when converting a float or mpf, the exact value
+is retained.
+
+ use GMP::Mpq qw(:all);
+ $a = mpq(); # zero
+ $b = mpq(0.5); # gives 1/2
+ $b = mpq(14); # integer 14
+ $b = mpq(3,4); # fraction 3/4
+ $b = mpq("7/12"); # fraction 7/12
+ $b = mpq("0xFF/0x100"); # fraction 255/256
+
+When a fraction is given, it should be in the canonical form specified in
+the GMP manual, which is denominator positive, no common factors, and zero
+always represented as 0/1. If not then C<canonicalize> can be called to put
+it in that form. For example,
+
+ use GMP::Mpq qw(:all);
+ $q = mpq(21,15); # eek! common factor 3
+ canonicalize($q); # get rid of it
+
+The following overloaded operators are available, and corresponding
+assignment forms like C<+=>,
+
+=over 4
+
+=item
+
++ - * / E<lt>E<lt> E<gt>E<gt> ** ! E<lt> E<lt>= == != E<gt> E<gt>=
+E<lt>=E<gt> abs not
+
+=back
+
+The following functions are available,
+
+=over 4
+
+=item
+
+den, inv, num
+
+=back
+
+C<inv> calculates 1/q, as per the corresponding GMP function. C<num> and
+C<den> return an mpz copy of the numerator or denominator respectively. In
+the future C<num> and C<den> might give lvalues so the original mpq can be
+modified through them, but this is not done currently.
+
+=head2 GMP::Mpf
+
+This class provides arbitrary precision floating point numbers. The
+mantissa is an arbitrary user-selected precision and the exponent is a fixed
+size (one machine word).
+
+A new mpf can be constructed with C<mpf>. The initial value can be an
+integer, float, string, mpz, mpq or mpf. The second argument specifies the
+desired precision in bits, or if omitted then the default precision is used.
+
+ use GMP::Mpf qw(:all);
+ $a = mpf(); # zero
+ $b = mpf(-7.5); # default precision
+ $c = mpf(1.5, 500); # 500 bits precision
+ $d = mpf("1.0000000000000001");
+
+The following overloaded operators are available, with the corresponding
+assignment forms like C<+=>,
+
+=over 4
+
+=item
+
++ - * / E<lt>E<lt> E<gt>E<gt> ** ! E<lt> E<lt>= == != E<gt> E<gt>=
+E<lt>=E<gt> abs not sqrt
+
+=back
+
+The following functions are available, behaving the same as the
+corresponding GMP mpf functions,
+
+=over 4
+
+=item
+
+ceil, floor, get_default_prec, get_prec, mpf_eq, set_default_prec, set_prec,
+trunc
+
+=back
+
+C<mpf_eq> is so named to avoid clashing with the perl C<eq> operator.
+
+C<set_prec> expects a variable which it can modify, it doesn't make sense to
+pass a literal constant. Only the given variable is modified, if other
+variables are referencing the same mpf object then a new copy is made of it.
+If the variable isn't an mpf it will be coerced to one.
+
+Results are the same precision as inputs, or if two mpf's are given to a
+binary operator then the precision of the first is used. For example,
+
+ use GMP::Mpf qw(mpf);
+ $a = mpf(2.0, 100);
+ $b = mpf(2.0, 500);
+ $c = $a + $b; # gives 100 bits precision
+
+Mpf to string conversion via "" or the usual string contexts uses C<$#> the
+same as normal float to string conversions, or defaults to C<%.g> if C<$#>
+is not defined. C<%.g> means all significant digits in the selected
+precision.
+
+=head2 GMP class
+
+The following functions are available in the GMP class,
+
+=over 4
+
+=item
+
+fits_slong_p, get_d, get_d_2exp, get_si, get_str, integer_p, printf, sgn,
+sprintf, version
+
+=back
+
+C<get_d_2exp> accepts any integer, string, float, mpz, mpq or mpf operands
+and returns a float and an integer exponent,
+
+ ($dbl, $exp) = get_d_2exp (mpf ("3.0"));
+ # dbl is 0.75, exp is 2
+
+C<get_str> takes an optional second argument which is the base, defaulting
+to decimal. A negative base means upper case, as per the C functions. For
+integer, integer string, mpz or mpq operands a string is returned.
+
+ use GMP qw(:all);
+ use GMP::Mpq qw(:all);
+ print get_str(mpq(-5,8)),"\n"; # -5/8
+ print get_str(255,16),"\n"; # ff
+
+For float, float strings or mpf operands, C<get_str> accepts an optional
+third parameter being how many digits to produce, defaulting to 0 which
+means all digits. (Only as many digits as can be accurately represented by
+the float precision are ever produced though.) A string/exponent pair is
+returned, as per the C mpf_get_str function. For example,
+
+ use GMP qw(:all);
+ use GMP::Mpf qw(:all);
+ ($s, $e) = get_str(111.111111111, 10, 4);
+ printf ".$se$e\n"; # .1111e3
+ ($s, $e) = get_str(1.625, 10);
+ print "0.$s*10^$e\n"; # 0.1625*10^1
+ ($s, $e) = get_str(mpf(2)**20, 16);
+ printf ".%s@%x\n", $s, $e; # .1@14
+
+C<printf> and C<sprintf> allow formatted output of GMP types. mpz and mpq
+values can be used with integer conversions (d, o, x, X) and mpf with float
+conversions (f, e, E, g, G). All the standard perl printf features are
+available too. For example,
+
+ use GMP::Mpz qw(mpz);
+ use GMP::Mpf qw(mpf);
+ GMP::printf ("%d %d %s", 123, mpz(2)**128, 'foo');
+ GMP::printf STDERR "%.40f", mpf(1.234);
+
+In perl 5.6.1 it doesn't seem to work to export C<printf>, the plain builtin
+C<printf> is reached unless calls are C<&printf()> style. Explicit use of
+C<GMP::printf> is suggested. C<sprintf> doesn't suffer this problem.
+
+ use GMP qw(sprintf);
+ use GMP::Mpq qw(mpq);
+ $s = sprintf "%x", mpq(15,16);
+
+C<version> is not exported by default or by tag :all, calling it as
+C<GMP::version()> is recommended. It returns the GMP library version
+string, which is not to be confused with the module version number.
+
+The other GMP module functions behave as per the corresponding GMP routines,
+and accept any integer, string, float, mpz, mpq or mpf. For example,
+
+ use GMP qw(:all);
+ use GMP::Mpz qw(mpz);
+ $z = mpz(123);
+ print sgn($z); # gives 1
+
+Because each of GMP::Mpz, GMP::Mpq and GMP::Mpf is a sub-class of GMP,
+C<-E<gt>> style calls work too.
+
+ use GMP qw(:all);
+ use GMP::Mpq qw(mpf);
+ $q = mpq(-5,7);
+ if ($q->integer_p()) # false
+ ...
+
+=head2 GMP::Rand
+
+This class provides objects holding an algorithm and state for random number
+generation. C<randstate> creates a new object, for example,
+
+ use GMP::Rand qw(randstate);
+ $r = randstate();
+ $r = randstate('lc_2exp_size', 64);
+ $r = randstate('lc_2exp', 43840821, 1, 32);
+ $r = randstate('mt');
+ $r = randstate($another_r);
+
+With no parameters this corresponds to the C function
+C<gmp_randinit_default>, and is a compromise between speed and randomness.
+'lc_2exp_size' corresponds to C<gmp_randinit_lc_2exp_size>, 'lc_2exp'
+corresponds to C<gmp_randinit_lc_2exp>, and 'mt' corresponds to
+C<gmp_randinit_mt>. Or when passed another randstate object, a copy of that
+object is made.
+
+'lc_2exp_size' can fail if the requested size is bigger than the internal
+table provides for, in which case undef is returned. The maximum size
+currently supported is 128. The other forms always succeed.
+
+A randstate can be seeded with an integer or mpz, using the C<seed> method.
+/dev/random might be a good source of randomness, or time() or
+Time::HiRes::time() might be adequate, depending on the application.
+
+ $r->seed(time()));
+
+Random numbers can be generated with the following functions,
+
+=over 4
+
+=item
+
+mpf_urandomb, mpz_rrandomb, mpz_urandomb, mpz_urandomm,
+gmp_urandomb_ui, gmp_urandomm_ui
+
+=back
+
+Each constructs a new mpz or mpf and with a distribution per the
+corresponding GMP function. For example,
+
+ use GMP::Rand (:all);
+ $r = randstate();
+ $a = mpz_urandomb($r,256); # uniform mpz, 256 bits
+ $b = mpz_urandomm($r,mpz(3)**100); # uniform mpz, 0 to 3**100-1
+ $c = mpz_rrandomb($r,1024); # special mpz, 1024 bits
+ $f = mpf_urandomb($r,128); # uniform mpf, 128 bits, 0<=$f<1
+ $f = gmp_urandomm_ui($r,56); # uniform int, 0 to 55
+
+=head2 Coercion
+
+Arguments to operators and functions are converted as necessary to the
+appropriate type. For instance C<**> requires an unsigned integer exponent,
+and an mpq argument will be converted, so long as it's an integer in the
+appropriate range.
+
+ use GMP::Mpz (mpz);
+ use GMP::Mpq (mpq);
+ $p = mpz(3) ** mpq(45); # allowed, 45 is an integer
+
+It's an error if a conversion to an integer or mpz would cause any
+truncation. For example,
+
+ use GMP::Mpz (mpz);
+ $p = mpz(3) + 1.25; # not allowed
+ $p = mpz(3) + mpz(1.25); # allowed, explicit truncation
+
+Comparisons, however, accept any combination of operands and are always done
+exactly. For example,
+
+ use GMP::Mpz (mpz);
+ print mpz(3) < 3.1; # true
+
+Variables used on the left of an assignment operator like C<+=> are subject
+to coercion too. An integer, float or string will change type when an mpz,
+mpq or mpf is applied to it. For example,
+
+ use GMP::Mpz (mpz);
+ $a = 1;
+ $a += mpz(1234); # $a becomes an mpz
+
+=head2 Overloading
+
+The rule for binary operators in the C<overload> mechanism is that if both
+operands are class objects then the method from the first is used. This
+determines the result type when mixing GMP classes. For example,
+
+ use GMP::Mpz (mpz);
+ use GMP::Mpq (mpq);
+ use GMP::Mpf (mpf);
+ $z = mpz(123);
+ $q = mpq(3,2);
+ $f = mpf(1.375)
+ print $q+$f; # gives an mpq
+ print $f+$z; # gives an mpf
+ print $z+$f; # not allowed, would lose precision
+
+=head2 Constants
+
+A special tag C<:constants> is recognised in the module exports list. It
+doesn't select any functions, but indicates that perl constants should be
+GMP objects. This can only be used on one of GMP::Mpz, GMP::Mpq or GMP::Mpf
+at any one time, since they apply different rules.
+
+GMP::Mpz will treat constants as mpz's if they're integers, or ordinary
+floats if not. For example,
+
+ use GMP::Mpz qw(:constants);
+ print 764861287634126387126378128,"\n"; # an mpz
+ print 1.25,"\n"; # a float
+
+GMP::Mpq is similar, treating integers as mpq's and leaving floats to the
+normal perl handling. Something like 3/4 is read as two integer mpq's and a
+division, but that's fine since it gives the intended fraction.
+
+ use GMP::Mpq qw(:constants);
+ print 3/4,"\n"; # an mpq
+ print 1.25,"\n"; # a float
+
+GMP::Mpf will treat all constants as mpf's using the default precision.
+BEGIN blocks can be used to set that precision while the code is parsed.
+For example,
+
+ use GMP::Mpf qw(:constants);
+ BEGIN { GMP::Mpf::set_default_prec(256); }
+ print 1/3;
+ BEGIN { GMP::Mpf::set_default_prec(64); }
+ print 5/7;
+
+A similar special tag :noconstants is recognised to turn off the constants
+feature. For example,
+
+ use GMP::Mpz qw(:constants);
+ print 438249738748174928193,"\n"; # an mpz
+ use GMP::Mpz qw(:noconstants);
+ print 438249738748174928193,"\n"; # now a float
+
+All three 'integer', 'binary' and 'float' constant methods are captured.
+'float' is captured even for GMP::Mpz and GMP::Mpq since perl by default
+treats integer strings as floats if they don't fit a plain integer.
+
+=head1 SEE ALSO
+
+GMP manual, L<perl>, L<overload>.
+
+=head1 BUGS
+
+In perl 5.005_03 on i386 FreeBSD, the overloaded constants sometimes provoke
+seg faults. Don't know if that's a perl bug or a GMP module bug, though it
+does seem to go bad before reaching anything in GMP.xs.
+
+There's no way to specify an arbitrary base when converting a string to an
+mpz (or mpq or mpf), only hex or octal with 0x or 0 (for mpz and mpq, but
+not for mpf).
+
+These modules are not reentrant or thread safe, due to the implementation of
+the XSUBs.
+
+Returning a new object from the various functions is convenient, but
+assignment versions could avoid creating new objects. Perhaps they could be
+named after the C language functions, eg. mpq_inv($q,$q);
+
+It'd be good if C<num> and C<den> gave lvalues so the underlying mpq could
+be manipulated.
+
+C<printf> could usefully accept %b for mpz, mpq and mpf, and perhaps %x for
+mpf too.
+
+C<get_str> returning different style values for integer versus float is a
+bit unfortunate. With mpz, mpq and mpf objects there's no doubt what it
+will do, but on a plain scalar its action depends on whether the scalar was
+promoted to a float at any stage, and then on the GMP module rules about
+using the integer or float part.
+
+=head1 INTERNALS
+
+In usual perl object style, an mpz is a reference to an object blessed into
+class C<GMP::Mpz>. The object holds a pointer to the C language C<mpz_t>
+structure. Similarly for mpq, mpf and randstate.
+
+A free list of mpz and mpq values is kept to avoid repeated initializing and
+clearing when objects are created and destroyed. This aims to help speed,
+but it's not clear whether it's really needed.
+
+mpf doesn't use a free list because the precision of new objects can be
+different each time.
+
+No interface to C<mpf_set_prec_raw> is provided. It wouldn't be very useful
+since there's no way to make an operation store its result in a particular
+object. The plain C<set_prec> is useful though, for truncating to a lower
+precision, or as a sort of directive that subsequent calculations involving
+that variable should use a higher precision.
+
+The overheads of perl dynamic typing (operator dispatch, operand type
+checking or coercion) will mean this interface is slower than using C
+directly.
+
+Some assertion checking is available as a compile-time option.
+
+=head1 COPYRIGHT
+
+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/.
+
+=cut
+
+# Local variables:
+# perl-indent-level: 2
+# fill-column: 76
+# End:
diff --git a/vendor/gmp-6.3.0/demos/perl/GMP.xs b/vendor/gmp-6.3.0/demos/perl/GMP.xs
new file mode 100644
index 0000000..8f5acc9
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/GMP.xs
@@ -0,0 +1,3212 @@
+/* GMP module external subroutines.
+
+Copyright 2001-2003, 2015 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/.
+
+
+/* Notes:
+
+ Routines are grouped with the alias feature and a table of function
+ pointers where possible, since each xsub routine ends up with quite a bit
+ of code size. Different combinations of arguments and return values have
+ to be separate though.
+
+ The "INTERFACE:" feature isn't available in perl 5.005 and so isn't used.
+ "ALIAS:" requires a table lookup with CvXSUBANY(cv).any_i32 (which is
+ "ix") whereas "INTERFACE:" would have CvXSUBANY(cv).any_dptr as the
+ function pointer immediately.
+
+ Mixed-type swapped-order assignments like "$a = 123; $a += mpz(456);"
+ invoke the plain overloaded "+", not "+=", which makes life easier.
+
+ mpz_assume etc types are used with the overloaded operators since such
+ operators are always called with a class object as the first argument, we
+ don't need an sv_derived_from() lookup to check. There's assert()s in
+ MPX_ASSUME() for this though.
+
+ The overload_constant routines reached via overload::constant get 4
+ arguments in perl 5.6, not the 3 as documented. This is apparently a
+ bug, using "..." lets us ignore the extra one.
+
+ There's only a few "si" functions in gmp, so usually SvIV values get
+ handled with an mpz_set_si into a temporary and then a full precision mpz
+ routine. This is reasonably efficient.
+
+ Argument types are checked, with a view to preserving all bits in the
+ operand. Perl is a bit looser in its arithmetic, allowing rounding or
+ truncation to an intended operand type (IV, UV or NV).
+
+ Bugs:
+
+ The memory leak detection attempted in GMP::END() doesn't work when mpz's
+ are created as constants because END() is called before they're
+ destroyed. What's the right place to hook such a check?
+
+ See the bugs section of GMP.pm too. */
+
+
+/* Comment this out to get assertion checking. */
+#define NDEBUG
+
+/* Change this to "#define TRACE(x) x" for some diagnostics. */
+#define TRACE(x)
+
+
+#include <assert.h>
+#include <float.h>
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "patchlevel.h"
+
+#include "gmp.h"
+
+
+/* Perl 5.005 doesn't have SvIsUV, only 5.6 and up.
+ Perl 5.8 has SvUOK, but not 5.6, so we don't use that. */
+#ifndef SvIsUV
+#define SvIsUV(sv) 0
+#endif
+#ifndef SvUVX
+#define SvUVX(sv) (croak("GMP: oops, shouldn't be using SvUVX"), 0)
+#endif
+
+
+/* Code which doesn't check anything itself, but exists to support other
+ assert()s. */
+#ifdef NDEBUG
+#define assert_support(x)
+#else
+#define assert_support(x) x
+#endif
+
+/* LONG_MAX + 1 and ULONG_MAX + 1, as a doubles */
+#define LONG_MAX_P1_AS_DOUBLE ((double) ((unsigned long) LONG_MAX + 1))
+#define ULONG_MAX_P1_AS_DOUBLE (2.0 * (double) ((unsigned long) ULONG_MAX/2 + 1))
+
+/* Check for perl version "major.minor".
+ Perl 5.004 doesn't have PERL_REVISION and PERL_VERSION, but that's ok,
+ we're only interested in tests above that. */
+#if defined (PERL_REVISION) && defined (PERL_VERSION)
+#define PERL_GE(major,minor) \
+ (PERL_REVISION > (major) \
+ || ((major) == PERL_REVISION && PERL_VERSION >= (minor)))
+#else
+#define PERL_GE(major,minor) (0)
+#endif
+#define PERL_LT(major,minor) (! PERL_GE(major,minor))
+
+/* sv_derived_from etc in 5.005 took "char *" rather than "const char *".
+ Avoid some compiler warnings by using const only where it works. */
+#if PERL_LT (5,6)
+#define classconst
+#else
+#define classconst const
+#endif
+
+/* In a MINGW or Cygwin DLL build of gmp, the various gmp functions are
+ given with dllimport directives, which prevents them being used as
+ initializers for constant data. We give function tables as
+ "static_functable const ...", which is normally "static const", but for
+ mingw expands to just "const" making the table an automatic with a
+ run-time initializer.
+
+ In gcc 3.3.1, the function tables initialized like this end up getting
+ all the __imp__foo values fetched, even though just one or two will be
+ used. This is wasteful, but probably not too bad. */
+
+#if defined (__MINGW32__) || defined (__CYGWIN__)
+#define static_functable
+#else
+#define static_functable static
+#endif
+
+#define GMP_MALLOC_ID 42
+
+static classconst char mpz_class[] = "GMP::Mpz";
+static classconst char mpq_class[] = "GMP::Mpq";
+static classconst char mpf_class[] = "GMP::Mpf";
+static classconst char rand_class[] = "GMP::Rand";
+
+static HV *mpz_class_hv;
+static HV *mpq_class_hv;
+static HV *mpf_class_hv;
+
+assert_support (static long mpz_count = 0;)
+assert_support (static long mpq_count = 0;)
+assert_support (static long mpf_count = 0;)
+assert_support (static long rand_count = 0;)
+
+#define TRACE_ACTIVE() \
+ assert_support \
+ (TRACE (printf (" active %ld mpz, %ld mpq, %ld mpf, %ld randstate\n", \
+ mpz_count, mpq_count, mpf_count, rand_count)))
+
+
+/* Each "struct mpz_elem" etc is an mpz_t with a link field tacked on the
+ end so they can be held on a linked list. */
+
+#define CREATE_MPX(type) \
+ \
+ /* must have mpz_t etc first, for sprintf below */ \
+ struct type##_elem { \
+ type##_t m; \
+ struct type##_elem *next; \
+ }; \
+ typedef struct type##_elem *type; \
+ typedef struct type##_elem *type##_assume; \
+ typedef type##_ptr type##_coerce; \
+ \
+ static type type##_freelist = NULL; \
+ \
+ static type \
+ new_##type (void) \
+ { \
+ type p; \
+ TRACE (printf ("new %s\n", type##_class)); \
+ if (type##_freelist != NULL) \
+ { \
+ p = type##_freelist; \
+ type##_freelist = type##_freelist->next; \
+ } \
+ else \
+ { \
+ New (GMP_MALLOC_ID, p, 1, struct type##_elem); \
+ type##_init (p->m); \
+ } \
+ TRACE (printf (" p=%p\n", p)); \
+ assert_support (type##_count++); \
+ TRACE_ACTIVE (); \
+ return p; \
+ } \
+
+CREATE_MPX (mpz)
+CREATE_MPX (mpq)
+
+typedef mpf_ptr mpf;
+typedef mpf_ptr mpf_assume;
+typedef mpf_ptr mpf_coerce_st0;
+typedef mpf_ptr mpf_coerce_def;
+
+
+static mpf
+new_mpf (unsigned long prec)
+{
+ mpf p;
+ New (GMP_MALLOC_ID, p, 1, __mpf_struct);
+ mpf_init2 (p, prec);
+ TRACE (printf (" mpf p=%p\n", p));
+ assert_support (mpf_count++);
+ TRACE_ACTIVE ();
+ return p;
+}
+
+
+/* tmp_mpf_t records an allocated precision with an mpf_t so changes of
+ precision can be done with just an mpf_set_prec_raw. */
+
+struct tmp_mpf_struct {
+ mpf_t m;
+ unsigned long allocated_prec;
+};
+typedef const struct tmp_mpf_struct *tmp_mpf_srcptr;
+typedef struct tmp_mpf_struct *tmp_mpf_ptr;
+typedef struct tmp_mpf_struct tmp_mpf_t[1];
+
+#define tmp_mpf_init(f) \
+ do { \
+ mpf_init (f->m); \
+ f->allocated_prec = mpf_get_prec (f->m); \
+ } while (0)
+
+static void
+tmp_mpf_grow (tmp_mpf_ptr f, unsigned long prec)
+{
+ mpf_set_prec_raw (f->m, f->allocated_prec);
+ mpf_set_prec (f->m, prec);
+ f->allocated_prec = mpf_get_prec (f->m);
+}
+
+#define tmp_mpf_shrink(f) tmp_mpf_grow (f, 1L)
+
+#define tmp_mpf_set_prec(f,prec) \
+ do { \
+ if (prec > f->allocated_prec) \
+ tmp_mpf_grow (f, prec); \
+ else \
+ mpf_set_prec_raw (f->m, prec); \
+ } while (0)
+
+
+static mpz_t tmp_mpz_0, tmp_mpz_1, tmp_mpz_2;
+static mpq_t tmp_mpq_0, tmp_mpq_1;
+static tmp_mpf_t tmp_mpf_0, tmp_mpf_1;
+
+/* for GMP::Mpz::export */
+#define tmp_mpz_4 tmp_mpz_2
+
+
+#define FREE_MPX_FREELIST(p,type) \
+ do { \
+ TRACE (printf ("free %s\n", type##_class)); \
+ p->next = type##_freelist; \
+ type##_freelist = p; \
+ assert_support (type##_count--); \
+ TRACE_ACTIVE (); \
+ assert (type##_count >= 0); \
+ } while (0)
+
+/* this version for comparison, if desired */
+#define FREE_MPX_NOFREELIST(p,type) \
+ do { \
+ TRACE (printf ("free %s\n", type##_class)); \
+ type##_clear (p->m); \
+ Safefree (p); \
+ assert_support (type##_count--); \
+ TRACE_ACTIVE (); \
+ assert (type##_count >= 0); \
+ } while (0)
+
+#define free_mpz(z) FREE_MPX_FREELIST (z, mpz)
+#define free_mpq(q) FREE_MPX_FREELIST (q, mpq)
+
+
+/* Return a new mortal SV holding the given mpx_ptr pointer.
+ class_hv should be one of mpz_class_hv etc. */
+#define MPX_NEWMORTAL(mpx_ptr, class_hv) \
+ sv_bless (sv_setref_pv (sv_newmortal(), NULL, mpx_ptr), class_hv)
+
+/* Aliases for use in typemaps */
+typedef char *malloced_string;
+typedef const char *const_string;
+typedef const char *const_string_assume;
+typedef char *string;
+typedef SV *order_noswap;
+typedef SV *dummy;
+typedef SV *SV_copy_0;
+typedef unsigned long ulong_coerce;
+typedef __gmp_randstate_struct *randstate;
+typedef UV gmp_UV;
+
+#define SvMPX(s,type) ((type) SvIV((SV*) SvRV(s)))
+#define SvMPZ(s) SvMPX(s,mpz)
+#define SvMPQ(s) SvMPX(s,mpq)
+#define SvMPF(s) SvMPX(s,mpf)
+#define SvRANDSTATE(s) SvMPX(s,randstate)
+
+#define MPX_ASSUME(x,sv,type) \
+ do { \
+ assert (sv_derived_from (sv, type##_class)); \
+ x = SvMPX(sv,type); \
+ } while (0)
+
+#define MPZ_ASSUME(z,sv) MPX_ASSUME(z,sv,mpz)
+#define MPQ_ASSUME(q,sv) MPX_ASSUME(q,sv,mpq)
+#define MPF_ASSUME(f,sv) MPX_ASSUME(f,sv,mpf)
+
+#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
+#define SGN(x) ((x)<0 ? -1 : (x) != 0)
+#define ABS(x) ((x)>=0 ? (x) : -(x))
+#define double_integer_p(d) (floor (d) == (d))
+
+#define x_mpq_integer_p(q) \
+ (mpz_cmp_ui (mpq_denref(q), 1L) == 0)
+
+#define assert_table(ix) assert (ix >= 0 && ix < numberof (table))
+
+#define SV_PTR_SWAP(x,y) \
+ do { SV *__tmp = (x); (x) = (y); (y) = __tmp; } while (0)
+#define MPF_PTR_SWAP(x,y) \
+ do { mpf_ptr __tmp = (x); (x) = (y); (y) = __tmp; } while (0)
+
+
+static void
+class_or_croak (SV *sv, classconst char *cl)
+{
+ if (! sv_derived_from (sv, cl))
+ croak("not type %s", cl);
+}
+
+
+/* These are macros, wrap them in functions. */
+static int
+x_mpz_odd_p (mpz_srcptr z)
+{
+ return mpz_odd_p (z);
+}
+static int
+x_mpz_even_p (mpz_srcptr z)
+{
+ return mpz_even_p (z);
+}
+
+static void
+x_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);
+}
+
+
+static void *
+my_gmp_alloc (size_t n)
+{
+ void *p;
+ TRACE (printf ("my_gmp_alloc %u\n", n));
+ New (GMP_MALLOC_ID, p, n, char);
+ TRACE (printf (" p=%p\n", p));
+ return p;
+}
+
+static void *
+my_gmp_realloc (void *p, size_t oldsize, size_t newsize)
+{
+ TRACE (printf ("my_gmp_realloc %p, %u to %u\n", p, oldsize, newsize));
+ Renew (p, newsize, char);
+ TRACE (printf (" p=%p\n", p));
+ return p;
+}
+
+static void
+my_gmp_free (void *p, size_t n)
+{
+ TRACE (printf ("my_gmp_free %p %u\n", p, n));
+ Safefree (p);
+}
+
+
+#define my_mpx_set_svstr(type) \
+ static void \
+ my_##type##_set_svstr (type##_ptr x, SV *sv) \
+ { \
+ const char *str; \
+ STRLEN len; \
+ TRACE (printf (" my_" #type "_set_svstr\n")); \
+ assert (SvPOK(sv) || SvPOKp(sv)); \
+ str = SvPV (sv, len); \
+ TRACE (printf (" str \"%s\"\n", str)); \
+ if (type##_set_str (x, str, 0) != 0) \
+ croak ("%s: invalid string: %s", type##_class, str); \
+ }
+
+my_mpx_set_svstr(mpz)
+my_mpx_set_svstr(mpq)
+my_mpx_set_svstr(mpf)
+
+
+/* very slack */
+static int
+x_mpq_cmp_si (mpq_srcptr x, long yn, unsigned long yd)
+{
+ mpq y;
+ int ret;
+ y = new_mpq ();
+ mpq_set_si (y->m, yn, yd);
+ ret = mpq_cmp (x, y->m);
+ free_mpq (y);
+ return ret;
+}
+
+static int
+x_mpq_fits_slong_p (mpq_srcptr q)
+{
+ return x_mpq_cmp_si (q, LONG_MIN, 1L) >= 0
+ && mpq_cmp_ui (q, LONG_MAX, 1L) <= 0;
+}
+
+static int
+x_mpz_cmp_q (mpz_ptr x, mpq_srcptr y)
+{
+ int ret;
+ mpz_set_ui (mpq_denref(tmp_mpq_0), 1L);
+ mpz_swap (mpq_numref(tmp_mpq_0), x);
+ ret = mpq_cmp (tmp_mpq_0, y);
+ mpz_swap (mpq_numref(tmp_mpq_0), x);
+ return ret;
+}
+
+static int
+x_mpz_cmp_f (mpz_srcptr x, mpf_srcptr y)
+{
+ tmp_mpf_set_prec (tmp_mpf_0, mpz_sizeinbase (x, 2));
+ mpf_set_z (tmp_mpf_0->m, x);
+ return mpf_cmp (tmp_mpf_0->m, y);
+}
+
+
+#define USE_UNKNOWN 0
+#define USE_IVX 1
+#define USE_UVX 2
+#define USE_NVX 3
+#define USE_PVX 4
+#define USE_MPZ 5
+#define USE_MPQ 6
+#define USE_MPF 7
+
+/* mg_get is called every time we get a value, even if the private flags are
+ still set from a previous such call. This is the same as as SvIV and
+ friends do.
+
+ When POK, we use the PV, even if there's an IV or NV available. This is
+ because it's hard to be sure there wasn't any rounding in establishing
+ the IV and/or NV. Cases of overflow, where the PV should definitely be
+ used, are easy enough to spot, but rounding is hard. So although IV or
+ NV would be more efficient, we must use the PV to be sure of getting all
+ the data. Applications should convert once to mpz, mpq or mpf when using
+ a value repeatedly.
+
+ Zany dual-type scalars like $! where the IV is an error code and the PV
+ is an error description string won't work with this preference for PV,
+ but that's too bad. Such scalars should be rare, and unlikely to be used
+ in bignum calculations.
+
+ When IOK and NOK are both set, we would prefer to use the IV since it can
+ be converted more efficiently, and because on a 64-bit system the NV may
+ have less bits than the IV. The following rules are applied,
+
+ - If the NV is not an integer, then we must use that NV, since clearly
+ the IV was merely established by rounding and is not the full value.
+
+ - In perl prior to 5.8, an NV too big for an IV leaves an overflow value
+ 0xFFFFFFFF. If the NV is too big to fit an IV then clearly it's the NV
+ which is the true value and must be used.
+
+ - In perl 5.8 and up, such an overflow doesn't set IOK, so that test is
+ unnecessary. However when coming from get-magic, IOKp _is_ set, and we
+ must check for overflow the same as in older perl.
+
+ FIXME:
+
+ We'd like to call mg_get just once, but unfortunately sv_derived_from()
+ will call it for each of our checks. We could do a string compare like
+ sv_isa ourselves, but that only tests the exact class, it doesn't
+ recognise subclassing. There doesn't seem to be a public interface to
+ the subclassing tests (in the internal isa_lookup() function). */
+
+int
+use_sv (SV *sv)
+{
+ double d;
+
+ if (SvGMAGICAL(sv))
+ {
+ mg_get(sv);
+
+ if (SvPOKp(sv))
+ return USE_PVX;
+
+ if (SvIOKp(sv))
+ {
+ if (SvIsUV(sv))
+ {
+ if (SvNOKp(sv))
+ goto u_or_n;
+ return USE_UVX;
+ }
+ else
+ {
+ if (SvNOKp(sv))
+ goto i_or_n;
+ return USE_IVX;
+ }
+ }
+
+ if (SvNOKp(sv))
+ return USE_NVX;
+
+ goto rok_or_unknown;
+ }
+
+ if (SvPOK(sv))
+ return USE_PVX;
+
+ if (SvIOK(sv))
+ {
+ if (SvIsUV(sv))
+ {
+ if (SvNOK(sv))
+ {
+ if (PERL_LT (5, 8))
+ {
+ u_or_n:
+ d = SvNVX(sv);
+ if (d >= ULONG_MAX_P1_AS_DOUBLE || d < 0.0)
+ return USE_NVX;
+ }
+ d = SvNVX(sv);
+ if (d != floor (d))
+ return USE_NVX;
+ }
+ return USE_UVX;
+ }
+ else
+ {
+ if (SvNOK(sv))
+ {
+ if (PERL_LT (5, 8))
+ {
+ i_or_n:
+ d = SvNVX(sv);
+ if (d >= LONG_MAX_P1_AS_DOUBLE || d < (double) LONG_MIN)
+ return USE_NVX;
+ }
+ d = SvNVX(sv);
+ if (d != floor (d))
+ return USE_NVX;
+ }
+ return USE_IVX;
+ }
+ }
+
+ if (SvNOK(sv))
+ return USE_NVX;
+
+ rok_or_unknown:
+ if (SvROK(sv))
+ {
+ if (sv_derived_from (sv, mpz_class))
+ return USE_MPZ;
+ if (sv_derived_from (sv, mpq_class))
+ return USE_MPQ;
+ if (sv_derived_from (sv, mpf_class))
+ return USE_MPF;
+ }
+
+ return USE_UNKNOWN;
+}
+
+
+/* Coerce sv to an mpz. Use tmp to hold the converted value if sv isn't
+ already an mpz (or an mpq of which the numerator can be used). Return
+ the chosen mpz (tmp or the contents of sv). */
+
+static mpz_ptr
+coerce_mpz_using (mpz_ptr tmp, SV *sv, int use)
+{
+ switch (use) {
+ case USE_IVX:
+ mpz_set_si (tmp, SvIVX(sv));
+ return tmp;
+
+ case USE_UVX:
+ mpz_set_ui (tmp, SvUVX(sv));
+ return tmp;
+
+ case USE_NVX:
+ {
+ double d;
+ d = SvNVX(sv);
+ if (! double_integer_p (d))
+ croak ("cannot coerce non-integer double to mpz");
+ mpz_set_d (tmp, d);
+ return tmp;
+ }
+
+ case USE_PVX:
+ my_mpz_set_svstr (tmp, sv);
+ return tmp;
+
+ case USE_MPZ:
+ return SvMPZ(sv)->m;
+
+ case USE_MPQ:
+ {
+ mpq q = SvMPQ(sv);
+ if (! x_mpq_integer_p (q->m))
+ croak ("cannot coerce non-integer mpq to mpz");
+ return mpq_numref(q->m);
+ }
+
+ case USE_MPF:
+ {
+ mpf f = SvMPF(sv);
+ if (! mpf_integer_p (f))
+ croak ("cannot coerce non-integer mpf to mpz");
+ mpz_set_f (tmp, f);
+ return tmp;
+ }
+
+ default:
+ croak ("cannot coerce to mpz");
+ }
+}
+static mpz_ptr
+coerce_mpz (mpz_ptr tmp, SV *sv)
+{
+ return coerce_mpz_using (tmp, sv, use_sv (sv));
+}
+
+
+/* Coerce sv to an mpq. If sv is an mpq then just return that, otherwise
+ use tmp to hold the converted value and return that. */
+
+static mpq_ptr
+coerce_mpq_using (mpq_ptr tmp, SV *sv, int use)
+{
+ TRACE (printf ("coerce_mpq_using %p %d\n", tmp, use));
+ switch (use) {
+ case USE_IVX:
+ mpq_set_si (tmp, SvIVX(sv), 1L);
+ return tmp;
+
+ case USE_UVX:
+ mpq_set_ui (tmp, SvUVX(sv), 1L);
+ return tmp;
+
+ case USE_NVX:
+ mpq_set_d (tmp, SvNVX(sv));
+ return tmp;
+
+ case USE_PVX:
+ my_mpq_set_svstr (tmp, sv);
+ return tmp;
+
+ case USE_MPZ:
+ mpq_set_z (tmp, SvMPZ(sv)->m);
+ return tmp;
+
+ case USE_MPQ:
+ return SvMPQ(sv)->m;
+
+ case USE_MPF:
+ mpq_set_f (tmp, SvMPF(sv));
+ return tmp;
+
+ default:
+ croak ("cannot coerce to mpq");
+ }
+}
+static mpq_ptr
+coerce_mpq (mpq_ptr tmp, SV *sv)
+{
+ return coerce_mpq_using (tmp, sv, use_sv (sv));
+}
+
+
+static void
+my_mpf_set_sv_using (mpf_ptr f, SV *sv, int use)
+{
+ switch (use) {
+ case USE_IVX:
+ mpf_set_si (f, SvIVX(sv));
+ break;
+
+ case USE_UVX:
+ mpf_set_ui (f, SvUVX(sv));
+ break;
+
+ case USE_NVX:
+ mpf_set_d (f, SvNVX(sv));
+ break;
+
+ case USE_PVX:
+ my_mpf_set_svstr (f, sv);
+ break;
+
+ case USE_MPZ:
+ mpf_set_z (f, SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ mpf_set_q (f, SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ mpf_set (f, SvMPF(sv));
+ break;
+
+ default:
+ croak ("cannot coerce to mpf");
+ }
+}
+
+/* Coerce sv to an mpf. If sv is an mpf then just return that, otherwise
+ use tmp to hold the converted value (with prec precision). */
+static mpf_ptr
+coerce_mpf_using (tmp_mpf_ptr tmp, SV *sv, unsigned long prec, int use)
+{
+ if (use == USE_MPF)
+ return SvMPF(sv);
+
+ tmp_mpf_set_prec (tmp, prec);
+ my_mpf_set_sv_using (tmp->m, sv, use);
+ return tmp->m;
+}
+static mpf_ptr
+coerce_mpf (tmp_mpf_ptr tmp, SV *sv, unsigned long prec)
+{
+ return coerce_mpf_using (tmp, sv, prec, use_sv (sv));
+}
+
+
+/* Coerce xv to an mpf and store the pointer in x, ditto for yv to x. If
+ one of xv or yv is an mpf then use it for the precision, otherwise use
+ the default precision. */
+unsigned long
+coerce_mpf_pair (mpf *xp, SV *xv, mpf *yp, SV *yv)
+{
+ int x_use = use_sv (xv);
+ int y_use = use_sv (yv);
+ unsigned long prec;
+ mpf x, y;
+
+ if (x_use == USE_MPF)
+ {
+ x = SvMPF(xv);
+ prec = mpf_get_prec (x);
+ y = coerce_mpf_using (tmp_mpf_0, yv, prec, y_use);
+ }
+ else
+ {
+ y = coerce_mpf_using (tmp_mpf_0, yv, mpf_get_default_prec(), y_use);
+ prec = mpf_get_prec (y);
+ x = coerce_mpf_using (tmp_mpf_1, xv, prec, x_use);
+ }
+ *xp = x;
+ *yp = y;
+ return prec;
+}
+
+
+/* Note that SvUV is not used, since it merely treats the signed IV as if it
+ was unsigned. We get an IV and check its sign. */
+static unsigned long
+coerce_ulong (SV *sv)
+{
+ long n;
+
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ n = SvIVX(sv);
+ negative_check:
+ if (n < 0)
+ goto range_error;
+ return n;
+
+ case USE_UVX:
+ return SvUVX(sv);
+
+ case USE_NVX:
+ {
+ double d;
+ d = SvNVX(sv);
+ if (! double_integer_p (d))
+ goto integer_error;
+ n = SvIV(sv);
+ }
+ goto negative_check;
+
+ case USE_PVX:
+ /* FIXME: Check the string is an integer. */
+ n = SvIV(sv);
+ goto negative_check;
+
+ case USE_MPZ:
+ {
+ mpz z = SvMPZ(sv);
+ if (! mpz_fits_ulong_p (z->m))
+ goto range_error;
+ return mpz_get_ui (z->m);
+ }
+
+ case USE_MPQ:
+ {
+ mpq q = SvMPQ(sv);
+ if (! x_mpq_integer_p (q->m))
+ goto integer_error;
+ if (! mpz_fits_ulong_p (mpq_numref (q->m)))
+ goto range_error;
+ return mpz_get_ui (mpq_numref (q->m));
+ }
+
+ case USE_MPF:
+ {
+ mpf f = SvMPF(sv);
+ if (! mpf_integer_p (f))
+ goto integer_error;
+ if (! mpf_fits_ulong_p (f))
+ goto range_error;
+ return mpf_get_ui (f);
+ }
+
+ default:
+ croak ("cannot coerce to ulong");
+ }
+
+ integer_error:
+ croak ("not an integer");
+
+ range_error:
+ croak ("out of range for ulong");
+}
+
+
+static long
+coerce_long (SV *sv)
+{
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ return SvIVX(sv);
+
+ case USE_UVX:
+ {
+ UV u = SvUVX(sv);
+ if (u > (UV) LONG_MAX)
+ goto range_error;
+ return u;
+ }
+
+ case USE_NVX:
+ {
+ double d = SvNVX(sv);
+ if (! double_integer_p (d))
+ goto integer_error;
+ return SvIV(sv);
+ }
+
+ case USE_PVX:
+ /* FIXME: Check the string is an integer. */
+ return SvIV(sv);
+
+ case USE_MPZ:
+ {
+ mpz z = SvMPZ(sv);
+ if (! mpz_fits_slong_p (z->m))
+ goto range_error;
+ return mpz_get_si (z->m);
+ }
+
+ case USE_MPQ:
+ {
+ mpq q = SvMPQ(sv);
+ if (! x_mpq_integer_p (q->m))
+ goto integer_error;
+ if (! mpz_fits_slong_p (mpq_numref (q->m)))
+ goto range_error;
+ return mpz_get_si (mpq_numref (q->m));
+ }
+
+ case USE_MPF:
+ {
+ mpf f = SvMPF(sv);
+ if (! mpf_integer_p (f))
+ goto integer_error;
+ if (! mpf_fits_slong_p (f))
+ goto range_error;
+ return mpf_get_si (f);
+ }
+
+ default:
+ croak ("cannot coerce to long");
+ }
+
+ integer_error:
+ croak ("not an integer");
+
+ range_error:
+ croak ("out of range for ulong");
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+MODULE = GMP PACKAGE = GMP
+
+BOOT:
+ TRACE (printf ("GMP boot\n"));
+ mp_set_memory_functions (my_gmp_alloc, my_gmp_realloc, my_gmp_free);
+ mpz_init (tmp_mpz_0);
+ mpz_init (tmp_mpz_1);
+ mpz_init (tmp_mpz_2);
+ mpq_init (tmp_mpq_0);
+ mpq_init (tmp_mpq_1);
+ tmp_mpf_init (tmp_mpf_0);
+ tmp_mpf_init (tmp_mpf_1);
+ mpz_class_hv = gv_stashpv (mpz_class, 1);
+ mpq_class_hv = gv_stashpv (mpq_class, 1);
+ mpf_class_hv = gv_stashpv (mpf_class, 1);
+
+
+void
+END()
+CODE:
+ TRACE (printf ("GMP end\n"));
+ TRACE_ACTIVE ();
+ /* These are not always true, see Bugs at the top of the file. */
+ /* assert (mpz_count == 0); */
+ /* assert (mpq_count == 0); */
+ /* assert (mpf_count == 0); */
+ /* assert (rand_count == 0); */
+
+
+const_string
+version()
+CODE:
+ RETVAL = gmp_version;
+OUTPUT:
+ RETVAL
+
+
+bool
+fits_slong_p (sv)
+ SV *sv
+CODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ RETVAL = 1;
+ break;
+
+ case USE_UVX:
+ {
+ UV u = SvUVX(sv);
+ RETVAL = (u <= LONG_MAX);
+ }
+ break;
+
+ case USE_NVX:
+ {
+ double d = SvNVX(sv);
+ RETVAL = (d >= (double) LONG_MIN && d < LONG_MAX_P1_AS_DOUBLE);
+ }
+ break;
+
+ case USE_PVX:
+ {
+ STRLEN len;
+ const char *str = SvPV (sv, len);
+ if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
+ RETVAL = x_mpq_fits_slong_p (tmp_mpq_0);
+ else
+ {
+ /* enough precision for a long */
+ tmp_mpf_set_prec (tmp_mpf_0, 2*mp_bits_per_limb);
+ if (mpf_set_str (tmp_mpf_0->m, str, 10) != 0)
+ croak ("GMP::fits_slong_p invalid string format");
+ RETVAL = mpf_fits_slong_p (tmp_mpf_0->m);
+ }
+ }
+ break;
+
+ case USE_MPZ:
+ RETVAL = mpz_fits_slong_p (SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ RETVAL = x_mpq_fits_slong_p (SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ RETVAL = mpf_fits_slong_p (SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::fits_slong_p invalid argument");
+ }
+OUTPUT:
+ RETVAL
+
+
+double
+get_d (sv)
+ SV *sv
+CODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ RETVAL = (double) SvIVX(sv);
+ break;
+
+ case USE_UVX:
+ RETVAL = (double) SvUVX(sv);
+ break;
+
+ case USE_NVX:
+ RETVAL = SvNVX(sv);
+ break;
+
+ case USE_PVX:
+ {
+ STRLEN len;
+ RETVAL = atof(SvPV(sv, len));
+ }
+ break;
+
+ case USE_MPZ:
+ RETVAL = mpz_get_d (SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ RETVAL = mpq_get_d (SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ RETVAL = mpf_get_d (SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::get_d invalid argument");
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+get_d_2exp (sv)
+ SV *sv
+PREINIT:
+ double ret;
+ long exp;
+PPCODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ ret = (double) SvIVX(sv);
+ goto use_frexp;
+
+ case USE_UVX:
+ ret = (double) SvUVX(sv);
+ goto use_frexp;
+
+ case USE_NVX:
+ {
+ int i_exp;
+ ret = SvNVX(sv);
+ use_frexp:
+ ret = frexp (ret, &i_exp);
+ exp = i_exp;
+ }
+ break;
+
+ case USE_PVX:
+ /* put strings through mpf to give full exp range */
+ tmp_mpf_set_prec (tmp_mpf_0, DBL_MANT_DIG);
+ my_mpf_set_svstr (tmp_mpf_0->m, sv);
+ ret = mpf_get_d_2exp (&exp, tmp_mpf_0->m);
+ break;
+
+ case USE_MPZ:
+ ret = mpz_get_d_2exp (&exp, SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ tmp_mpf_set_prec (tmp_mpf_0, DBL_MANT_DIG);
+ mpf_set_q (tmp_mpf_0->m, SvMPQ(sv)->m);
+ ret = mpf_get_d_2exp (&exp, tmp_mpf_0->m);
+ break;
+
+ case USE_MPF:
+ ret = mpf_get_d_2exp (&exp, SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::get_d_2exp invalid argument");
+ }
+ PUSHs (sv_2mortal (newSVnv (ret)));
+ PUSHs (sv_2mortal (newSViv (exp)));
+
+
+long
+get_si (sv)
+ SV *sv
+CODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ RETVAL = SvIVX(sv);
+ break;
+
+ case USE_UVX:
+ RETVAL = SvUVX(sv);
+ break;
+
+ case USE_NVX:
+ RETVAL = (long) SvNVX(sv);
+ break;
+
+ case USE_PVX:
+ RETVAL = SvIV(sv);
+ break;
+
+ case USE_MPZ:
+ RETVAL = mpz_get_si (SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ mpz_set_q (tmp_mpz_0, SvMPQ(sv)->m);
+ RETVAL = mpz_get_si (tmp_mpz_0);
+ break;
+
+ case USE_MPF:
+ RETVAL = mpf_get_si (SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::get_si invalid argument");
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+get_str (sv, ...)
+ SV *sv
+PREINIT:
+ char *str;
+ mp_exp_t exp;
+ mpz_ptr z;
+ mpq_ptr q;
+ mpf f;
+ int base;
+ int ndigits;
+PPCODE:
+ TRACE (printf ("GMP::get_str\n"));
+
+ if (items >= 2)
+ base = coerce_long (ST(1));
+ else
+ base = 10;
+ TRACE (printf (" base=%d\n", base));
+
+ if (items >= 3)
+ ndigits = coerce_long (ST(2));
+ else
+ ndigits = 10;
+ TRACE (printf (" ndigits=%d\n", ndigits));
+
+ EXTEND (SP, 2);
+
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ mpz_set_si (tmp_mpz_0, SvIVX(sv));
+ get_tmp_mpz_0:
+ z = tmp_mpz_0;
+ goto get_mpz;
+
+ case USE_UVX:
+ mpz_set_ui (tmp_mpz_0, SvUVX(sv));
+ goto get_tmp_mpz_0;
+
+ case USE_NVX:
+ /* only digits in the original double, not in the coerced form */
+ if (ndigits == 0)
+ ndigits = DBL_DIG;
+ mpf_set_d (tmp_mpf_0->m, SvNVX(sv));
+ f = tmp_mpf_0->m;
+ goto get_mpf;
+
+ case USE_PVX:
+ {
+ /* get_str on a string is not much more than a base conversion */
+ STRLEN len;
+ str = SvPV (sv, len);
+ if (mpz_set_str (tmp_mpz_0, str, 0) == 0)
+ {
+ z = tmp_mpz_0;
+ goto get_mpz;
+ }
+ else if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
+ {
+ q = tmp_mpq_0;
+ goto get_mpq;
+ }
+ else
+ {
+ /* FIXME: Would like perhaps a precision equivalent to the
+ number of significant digits of the string, in its given
+ base. */
+ tmp_mpf_set_prec (tmp_mpf_0, strlen(str));
+ if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0)
+ {
+ f = tmp_mpf_0->m;
+ goto get_mpf;
+ }
+ else
+ croak ("GMP::get_str invalid string format");
+ }
+ }
+ break;
+
+ case USE_MPZ:
+ z = SvMPZ(sv)->m;
+ get_mpz:
+ str = mpz_get_str (NULL, base, z);
+ push_str:
+ PUSHs (sv_2mortal (newSVpv (str, 0)));
+ break;
+
+ case USE_MPQ:
+ q = SvMPQ(sv)->m;
+ get_mpq:
+ str = mpq_get_str (NULL, base, q);
+ goto push_str;
+
+ case USE_MPF:
+ f = SvMPF(sv);
+ get_mpf:
+ str = mpf_get_str (NULL, &exp, base, 0, f);
+ PUSHs (sv_2mortal (newSVpv (str, 0)));
+ PUSHs (sv_2mortal (newSViv (exp)));
+ break;
+
+ default:
+ croak ("GMP::get_str invalid argument");
+ }
+
+
+bool
+integer_p (sv)
+ SV *sv
+CODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ case USE_UVX:
+ RETVAL = 1;
+ break;
+
+ case USE_NVX:
+ RETVAL = double_integer_p (SvNVX(sv));
+ break;
+
+ case USE_PVX:
+ {
+ /* FIXME: Maybe this should be done by parsing the string, not by an
+ actual conversion. */
+ STRLEN len;
+ const char *str = SvPV (sv, len);
+ if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
+ RETVAL = x_mpq_integer_p (tmp_mpq_0);
+ else
+ {
+ /* enough for all digits of the string */
+ tmp_mpf_set_prec (tmp_mpf_0, strlen(str)+64);
+ if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0)
+ RETVAL = mpf_integer_p (tmp_mpf_0->m);
+ else
+ croak ("GMP::integer_p invalid string format");
+ }
+ }
+ break;
+
+ case USE_MPZ:
+ RETVAL = 1;
+ break;
+
+ case USE_MPQ:
+ RETVAL = x_mpq_integer_p (SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ RETVAL = mpf_integer_p (SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::integer_p invalid argument");
+ }
+OUTPUT:
+ RETVAL
+
+
+int
+sgn (sv)
+ SV *sv
+CODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ RETVAL = SGN (SvIVX(sv));
+ break;
+
+ case USE_UVX:
+ RETVAL = (SvUVX(sv) > 0);
+ break;
+
+ case USE_NVX:
+ RETVAL = SGN (SvNVX(sv));
+ break;
+
+ case USE_PVX:
+ {
+ /* FIXME: Maybe this should be done by parsing the string, not by an
+ actual conversion. */
+ STRLEN len;
+ const char *str = SvPV (sv, len);
+ if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
+ RETVAL = mpq_sgn (tmp_mpq_0);
+ else
+ {
+ /* enough for all digits of the string */
+ tmp_mpf_set_prec (tmp_mpf_0, strlen(str)+64);
+ if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0)
+ RETVAL = mpf_sgn (tmp_mpf_0->m);
+ else
+ croak ("GMP::sgn invalid string format");
+ }
+ }
+ break;
+
+ case USE_MPZ:
+ RETVAL = mpz_sgn (SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ RETVAL = mpq_sgn (SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ RETVAL = mpf_sgn (SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::sgn invalid argument");
+ }
+OUTPUT:
+ RETVAL
+
+
+# currently undocumented
+void
+shrink ()
+CODE:
+#define x_mpz_shrink(z) \
+ mpz_set_ui (z, 0L); _mpz_realloc (z, 1)
+#define x_mpq_shrink(q) \
+ x_mpz_shrink (mpq_numref(q)); x_mpz_shrink (mpq_denref(q))
+
+ x_mpz_shrink (tmp_mpz_0);
+ x_mpz_shrink (tmp_mpz_1);
+ x_mpz_shrink (tmp_mpz_2);
+ x_mpq_shrink (tmp_mpq_0);
+ x_mpq_shrink (tmp_mpq_1);
+ tmp_mpf_shrink (tmp_mpf_0);
+ tmp_mpf_shrink (tmp_mpf_1);
+
+
+
+malloced_string
+sprintf_internal (fmt, sv)
+ const_string fmt
+ SV *sv
+CODE:
+ assert (strlen (fmt) >= 3);
+ assert (SvROK(sv));
+ assert ((sv_derived_from (sv, mpz_class) && fmt[strlen(fmt)-2] == 'Z')
+ || (sv_derived_from (sv, mpq_class) && fmt[strlen(fmt)-2] == 'Q')
+ || (sv_derived_from (sv, mpf_class) && fmt[strlen(fmt)-2] == 'F'));
+ TRACE (printf ("GMP::sprintf_internal\n");
+ printf (" fmt |%s|\n", fmt);
+ printf (" sv |%p|\n", SvMPZ(sv)));
+
+ /* cheat a bit here, SvMPZ works for mpq and mpf too */
+ gmp_asprintf (&RETVAL, fmt, SvMPZ(sv));
+
+ TRACE (printf (" result |%s|\n", RETVAL));
+OUTPUT:
+ RETVAL
+
+
+
+#------------------------------------------------------------------------------
+
+MODULE = GMP PACKAGE = GMP::Mpz
+
+mpz
+mpz (...)
+ALIAS:
+ GMP::Mpz::new = 1
+PREINIT:
+ SV *sv;
+CODE:
+ TRACE (printf ("%s new, ix=%ld, items=%d\n", mpz_class, ix, (int) items));
+ RETVAL = new_mpz();
+
+ switch (items) {
+ case 0:
+ mpz_set_ui (RETVAL->m, 0L);
+ break;
+
+ case 1:
+ sv = ST(0);
+ TRACE (printf (" use %d\n", use_sv (sv)));
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ mpz_set_si (RETVAL->m, SvIVX(sv));
+ break;
+
+ case USE_UVX:
+ mpz_set_ui (RETVAL->m, SvUVX(sv));
+ break;
+
+ case USE_NVX:
+ mpz_set_d (RETVAL->m, SvNVX(sv));
+ break;
+
+ case USE_PVX:
+ my_mpz_set_svstr (RETVAL->m, sv);
+ break;
+
+ case USE_MPZ:
+ mpz_set (RETVAL->m, SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ mpz_set_q (RETVAL->m, SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ mpz_set_f (RETVAL->m, SvMPF(sv));
+ break;
+
+ default:
+ goto invalid;
+ }
+ break;
+
+ default:
+ invalid:
+ croak ("%s new: invalid arguments", mpz_class);
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+overload_constant (str, pv, d1, ...)
+ const_string_assume str
+ SV *pv
+ dummy d1
+PREINIT:
+ mpz z;
+PPCODE:
+ TRACE (printf ("%s constant: %s\n", mpz_class, str));
+ z = new_mpz();
+ if (mpz_set_str (z->m, str, 0) == 0)
+ {
+ PUSHs (MPX_NEWMORTAL (z, mpz_class_hv));
+ }
+ else
+ {
+ free_mpz (z);
+ PUSHs(pv);
+ }
+
+
+mpz
+overload_copy (z, d1, d2)
+ mpz_assume z
+ dummy d1
+ dummy d2
+CODE:
+ RETVAL = new_mpz();
+ mpz_set (RETVAL->m, z->m);
+OUTPUT:
+ RETVAL
+
+
+void
+DESTROY (z)
+ mpz_assume z
+CODE:
+ TRACE (printf ("%s DESTROY %p\n", mpz_class, z));
+ free_mpz (z);
+
+
+malloced_string
+overload_string (z, d1, d2)
+ mpz_assume z
+ dummy d1
+ dummy d2
+CODE:
+ TRACE (printf ("%s overload_string %p\n", mpz_class, z));
+ RETVAL = mpz_get_str (NULL, 10, z->m);
+OUTPUT:
+ RETVAL
+
+
+mpz
+overload_add (xv, yv, order)
+ SV *xv
+ SV *yv
+ SV *order
+ALIAS:
+ GMP::Mpz::overload_sub = 1
+ GMP::Mpz::overload_mul = 2
+ GMP::Mpz::overload_div = 3
+ GMP::Mpz::overload_rem = 4
+ GMP::Mpz::overload_and = 5
+ GMP::Mpz::overload_ior = 6
+ GMP::Mpz::overload_xor = 7
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
+ } table[] = {
+ { mpz_add }, /* 0 */
+ { mpz_sub }, /* 1 */
+ { mpz_mul }, /* 2 */
+ { mpz_tdiv_q }, /* 3 */
+ { mpz_tdiv_r }, /* 4 */
+ { mpz_and }, /* 5 */
+ { mpz_ior }, /* 6 */
+ { mpz_xor }, /* 7 */
+ };
+CODE:
+ assert_table (ix);
+ if (order == &PL_sv_yes)
+ SV_PTR_SWAP (xv, yv);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m,
+ coerce_mpz (tmp_mpz_0, xv),
+ coerce_mpz (tmp_mpz_1, yv));
+OUTPUT:
+ RETVAL
+
+
+void
+overload_addeq (x, y, o)
+ mpz_assume x
+ mpz_coerce y
+ order_noswap o
+ALIAS:
+ GMP::Mpz::overload_subeq = 1
+ GMP::Mpz::overload_muleq = 2
+ GMP::Mpz::overload_diveq = 3
+ GMP::Mpz::overload_remeq = 4
+ GMP::Mpz::overload_andeq = 5
+ GMP::Mpz::overload_ioreq = 6
+ GMP::Mpz::overload_xoreq = 7
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
+ } table[] = {
+ { mpz_add }, /* 0 */
+ { mpz_sub }, /* 1 */
+ { mpz_mul }, /* 2 */
+ { mpz_tdiv_q }, /* 3 */
+ { mpz_tdiv_r }, /* 4 */
+ { mpz_and }, /* 5 */
+ { mpz_ior }, /* 6 */
+ { mpz_xor }, /* 7 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (x->m, x->m, y);
+ XPUSHs (ST(0));
+
+
+mpz
+overload_lshift (zv, nv, order)
+ SV *zv
+ SV *nv
+ SV *order
+ALIAS:
+ GMP::Mpz::overload_rshift = 1
+ GMP::Mpz::overload_pow = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, unsigned long);
+ } table[] = {
+ { mpz_mul_2exp }, /* 0 */
+ { mpz_fdiv_q_2exp }, /* 1 */
+ { mpz_pow_ui }, /* 2 */
+ };
+CODE:
+ assert_table (ix);
+ if (order == &PL_sv_yes)
+ SV_PTR_SWAP (zv, nv);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m, coerce_mpz (RETVAL->m, zv), coerce_ulong (nv));
+OUTPUT:
+ RETVAL
+
+
+void
+overload_lshifteq (z, n, o)
+ mpz_assume z
+ ulong_coerce n
+ order_noswap o
+ALIAS:
+ GMP::Mpz::overload_rshifteq = 1
+ GMP::Mpz::overload_poweq = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, unsigned long);
+ } table[] = {
+ { mpz_mul_2exp }, /* 0 */
+ { mpz_fdiv_q_2exp }, /* 1 */
+ { mpz_pow_ui }, /* 2 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (z->m, z->m, n);
+ XPUSHs(ST(0));
+
+
+mpz
+overload_abs (z, d1, d2)
+ mpz_assume z
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpz::overload_neg = 1
+ GMP::Mpz::overload_com = 2
+ GMP::Mpz::overload_sqrt = 3
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr w, mpz_srcptr x);
+ } table[] = {
+ { mpz_abs }, /* 0 */
+ { mpz_neg }, /* 1 */
+ { mpz_com }, /* 2 */
+ { mpz_sqrt }, /* 3 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m, z->m);
+OUTPUT:
+ RETVAL
+
+
+void
+overload_inc (z, d1, d2)
+ mpz_assume z
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpz::overload_dec = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr w, mpz_srcptr x, unsigned long y);
+ } table[] = {
+ { mpz_add_ui }, /* 0 */
+ { mpz_sub_ui }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ (*table[ix].op) (z->m, z->m, 1L);
+
+
+int
+overload_spaceship (xv, yv, order)
+ SV *xv
+ SV *yv
+ SV *order
+PREINIT:
+ mpz x;
+CODE:
+ TRACE (printf ("%s overload_spaceship\n", mpz_class));
+ MPZ_ASSUME (x, xv);
+ switch (use_sv (yv)) {
+ case USE_IVX:
+ RETVAL = mpz_cmp_si (x->m, SvIVX(yv));
+ break;
+ case USE_UVX:
+ RETVAL = mpz_cmp_ui (x->m, SvUVX(yv));
+ break;
+ case USE_PVX:
+ RETVAL = mpz_cmp (x->m, coerce_mpz (tmp_mpz_0, yv));
+ break;
+ case USE_NVX:
+ RETVAL = mpz_cmp_d (x->m, SvNVX(yv));
+ break;
+ case USE_MPZ:
+ RETVAL = mpz_cmp (x->m, SvMPZ(yv)->m);
+ break;
+ case USE_MPQ:
+ RETVAL = x_mpz_cmp_q (x->m, SvMPQ(yv)->m);
+ break;
+ case USE_MPF:
+ RETVAL = x_mpz_cmp_f (x->m, SvMPF(yv));
+ break;
+ default:
+ croak ("%s <=>: invalid operand", mpz_class);
+ }
+ RETVAL = SGN (RETVAL);
+ if (order == &PL_sv_yes)
+ RETVAL = -RETVAL;
+OUTPUT:
+ RETVAL
+
+
+bool
+overload_bool (z, d1, d2)
+ mpz_assume z
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpz::overload_not = 1
+CODE:
+ RETVAL = (mpz_sgn (z->m) != 0) ^ ix;
+OUTPUT:
+ RETVAL
+
+
+mpz
+bin (n, k)
+ mpz_coerce n
+ ulong_coerce k
+ALIAS:
+ GMP::Mpz::root = 1
+PREINIT:
+ /* mpz_root returns an int, hence the cast */
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, unsigned long);
+ } table[] = {
+ { mpz_bin_ui }, /* 0 */
+ { (void (*)(mpz_ptr, mpz_srcptr, unsigned long)) mpz_root }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m, n, k);
+OUTPUT:
+ RETVAL
+
+
+void
+cdiv (a, d)
+ mpz_coerce a
+ mpz_coerce d
+ALIAS:
+ GMP::Mpz::fdiv = 1
+ GMP::Mpz::tdiv = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
+ } table[] = {
+ { mpz_cdiv_qr }, /* 0 */
+ { mpz_fdiv_qr }, /* 1 */
+ { mpz_tdiv_qr }, /* 2 */
+ };
+ mpz q, r;
+PPCODE:
+ assert_table (ix);
+ q = new_mpz();
+ r = new_mpz();
+ (*table[ix].op) (q->m, r->m, a, d);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (q, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (r, mpz_class_hv));
+
+
+void
+cdiv_2exp (a, d)
+ mpz_coerce a
+ ulong_coerce d
+ALIAS:
+ GMP::Mpz::fdiv_2exp = 1
+ GMP::Mpz::tdiv_2exp = 2
+PREINIT:
+ static_functable const struct {
+ void (*q) (mpz_ptr, mpz_srcptr, unsigned long);
+ void (*r) (mpz_ptr, mpz_srcptr, unsigned long);
+ } table[] = {
+ { mpz_cdiv_q_2exp, mpz_cdiv_r_2exp }, /* 0 */
+ { mpz_fdiv_q_2exp, mpz_fdiv_r_2exp }, /* 1 */
+ { mpz_tdiv_q_2exp, mpz_tdiv_r_2exp }, /* 2 */
+ };
+ mpz q, r;
+PPCODE:
+ assert_table (ix);
+ q = new_mpz();
+ r = new_mpz();
+ (*table[ix].q) (q->m, a, d);
+ (*table[ix].r) (r->m, a, d);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (q, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (r, mpz_class_hv));
+
+
+bool
+congruent_p (a, c, d)
+ mpz_coerce a
+ mpz_coerce c
+ mpz_coerce d
+PREINIT:
+CODE:
+ RETVAL = mpz_congruent_p (a, c, d);
+OUTPUT:
+ RETVAL
+
+
+bool
+congruent_2exp_p (a, c, d)
+ mpz_coerce a
+ mpz_coerce c
+ ulong_coerce d
+PREINIT:
+CODE:
+ RETVAL = mpz_congruent_2exp_p (a, c, d);
+OUTPUT:
+ RETVAL
+
+
+mpz
+divexact (a, d)
+ mpz_coerce a
+ mpz_coerce d
+ALIAS:
+ GMP::Mpz::mod = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
+ } table[] = {
+ { mpz_divexact }, /* 0 */
+ { mpz_mod }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m, a, d);
+OUTPUT:
+ RETVAL
+
+
+bool
+divisible_p (a, d)
+ mpz_coerce a
+ mpz_coerce d
+CODE:
+ RETVAL = mpz_divisible_p (a, d);
+OUTPUT:
+ RETVAL
+
+
+bool
+divisible_2exp_p (a, d)
+ mpz_coerce a
+ ulong_coerce d
+CODE:
+ RETVAL = mpz_divisible_2exp_p (a, d);
+OUTPUT:
+ RETVAL
+
+
+bool
+even_p (z)
+ mpz_coerce z
+ALIAS:
+ GMP::Mpz::odd_p = 1
+ GMP::Mpz::perfect_square_p = 2
+ GMP::Mpz::perfect_power_p = 3
+PREINIT:
+ static_functable const struct {
+ int (*op) (mpz_srcptr z);
+ } table[] = {
+ { x_mpz_even_p }, /* 0 */
+ { x_mpz_odd_p }, /* 1 */
+ { mpz_perfect_square_p }, /* 2 */
+ { mpz_perfect_power_p }, /* 3 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = (*table[ix].op) (z);
+OUTPUT:
+ RETVAL
+
+
+mpz
+fac (n)
+ ulong_coerce n
+ALIAS:
+ GMP::Mpz::fib = 1
+ GMP::Mpz::lucnum = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr r, unsigned long n);
+ } table[] = {
+ { mpz_fac_ui }, /* 0 */
+ { mpz_fib_ui }, /* 1 */
+ { mpz_lucnum_ui }, /* 2 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m, n);
+OUTPUT:
+ RETVAL
+
+
+void
+fib2 (n)
+ ulong_coerce n
+ALIAS:
+ GMP::Mpz::lucnum2 = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr r, mpz_ptr r2, unsigned long n);
+ } table[] = {
+ { mpz_fib2_ui }, /* 0 */
+ { mpz_lucnum2_ui }, /* 1 */
+ };
+ mpz r, r2;
+PPCODE:
+ assert_table (ix);
+ r = new_mpz();
+ r2 = new_mpz();
+ (*table[ix].op) (r->m, r2->m, n);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (r, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (r2, mpz_class_hv));
+
+
+mpz
+gcd (x, ...)
+ mpz_coerce x
+ALIAS:
+ GMP::Mpz::lcm = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr w, mpz_srcptr x, mpz_srcptr y);
+ void (*op_ui) (mpz_ptr w, mpz_srcptr x, unsigned long y);
+ } table[] = {
+ /* cast to ignore ulong return from mpz_gcd_ui */
+ { mpz_gcd,
+ (void (*) (mpz_ptr, mpz_srcptr, unsigned long)) mpz_gcd_ui }, /* 0 */
+ { mpz_lcm, mpz_lcm_ui }, /* 1 */
+ };
+ int i;
+ SV *yv;
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ if (items == 1)
+ mpz_set (RETVAL->m, x);
+ else
+ {
+ for (i = 1; i < items; i++)
+ {
+ yv = ST(i);
+ if (SvIOK(yv))
+ (*table[ix].op_ui) (RETVAL->m, x, ABS(SvIVX(yv)));
+ else
+ (*table[ix].op) (RETVAL->m, x, coerce_mpz (tmp_mpz_1, yv));
+ x = RETVAL->m;
+ }
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+gcdext (a, b)
+ mpz_coerce a
+ mpz_coerce b
+PREINIT:
+ mpz g, x, y;
+ SV *sv;
+PPCODE:
+ g = new_mpz();
+ x = new_mpz();
+ y = new_mpz();
+ mpz_gcdext (g->m, x->m, y->m, a, b);
+ EXTEND (SP, 3);
+ PUSHs (MPX_NEWMORTAL (g, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (x, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (y, mpz_class_hv));
+
+
+unsigned long
+hamdist (x, y)
+ mpz_coerce x
+ mpz_coerce y
+CODE:
+ RETVAL = mpz_hamdist (x, y);
+OUTPUT:
+ RETVAL
+
+
+mpz
+invert (a, m)
+ mpz_coerce a
+ mpz_coerce m
+CODE:
+ RETVAL = new_mpz();
+ if (! mpz_invert (RETVAL->m, a, m))
+ {
+ free_mpz (RETVAL);
+ XSRETURN_UNDEF;
+ }
+OUTPUT:
+ RETVAL
+
+
+int
+jacobi (a, b)
+ mpz_coerce a
+ mpz_coerce b
+CODE:
+ RETVAL = mpz_jacobi (a, b);
+OUTPUT:
+ RETVAL
+
+
+int
+kronecker (a, b)
+ SV *a
+ SV *b
+CODE:
+ if (SvIOK(b))
+ RETVAL = mpz_kronecker_si (coerce_mpz(tmp_mpz_0,a), SvIVX(b));
+ else if (SvIOK(a))
+ RETVAL = mpz_si_kronecker (SvIVX(a), coerce_mpz(tmp_mpz_0,b));
+ else
+ RETVAL = mpz_kronecker (coerce_mpz(tmp_mpz_0,a),
+ coerce_mpz(tmp_mpz_1,b));
+OUTPUT:
+ RETVAL
+
+
+void
+mpz_export (order, size, endian, nails, z)
+ int order
+ size_t size
+ int endian
+ size_t nails
+ mpz_coerce z
+PREINIT:
+ size_t numb, count, bytes, actual_count;
+ char *data;
+ SV *sv;
+PPCODE:
+ numb = 8*size - nails;
+ count = (mpz_sizeinbase (z, 2) + numb-1) / numb;
+ bytes = count * size;
+ New (GMP_MALLOC_ID, data, bytes+1, char);
+ mpz_export (data, &actual_count, order, size, endian, nails, z);
+ assert (count == actual_count);
+ data[bytes] = '\0';
+ sv = sv_newmortal(); sv_usepvn_mg (sv, data, bytes); PUSHs(sv);
+
+
+mpz
+mpz_import (order, size, endian, nails, sv)
+ int order
+ size_t size
+ int endian
+ size_t nails
+ SV *sv
+PREINIT:
+ size_t count;
+ const char *data;
+ STRLEN len;
+CODE:
+ data = SvPV (sv, len);
+ if ((len % size) != 0)
+ croak ("%s mpz_import: string not a multiple of the given size",
+ mpz_class);
+ count = len / size;
+ RETVAL = new_mpz();
+ mpz_import (RETVAL->m, count, order, size, endian, nails, data);
+OUTPUT:
+ RETVAL
+
+
+mpz
+nextprime (z)
+ mpz_coerce z
+CODE:
+ RETVAL = new_mpz();
+ mpz_nextprime (RETVAL->m, z);
+OUTPUT:
+ RETVAL
+
+
+unsigned long
+popcount (x)
+ mpz_coerce x
+CODE:
+ RETVAL = mpz_popcount (x);
+OUTPUT:
+ RETVAL
+
+
+mpz
+powm (b, e, m)
+ mpz_coerce b
+ mpz_coerce e
+ mpz_coerce m
+CODE:
+ RETVAL = new_mpz();
+ mpz_powm (RETVAL->m, b, e, m);
+OUTPUT:
+ RETVAL
+
+
+bool
+probab_prime_p (z, n)
+ mpz_coerce z
+ ulong_coerce n
+CODE:
+ RETVAL = mpz_probab_prime_p (z, n);
+OUTPUT:
+ RETVAL
+
+
+# No attempt to coerce here, only an mpz makes sense.
+void
+realloc (z, limbs)
+ mpz z
+ int limbs
+CODE:
+ _mpz_realloc (z->m, limbs);
+
+
+void
+remove (z, f)
+ mpz_coerce z
+ mpz_coerce f
+PREINIT:
+ SV *sv;
+ mpz rem;
+ unsigned long mult;
+PPCODE:
+ rem = new_mpz();
+ mult = mpz_remove (rem->m, z, f);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (rem, mpz_class_hv));
+ PUSHs (sv_2mortal (newSViv (mult)));
+
+
+void
+roote (z, n)
+ mpz_coerce z
+ ulong_coerce n
+PREINIT:
+ SV *sv;
+ mpz root;
+ int exact;
+PPCODE:
+ root = new_mpz();
+ exact = mpz_root (root->m, z, n);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (root, mpz_class_hv));
+ sv = (exact ? &PL_sv_yes : &PL_sv_no); sv_2mortal(sv); PUSHs(sv);
+
+
+void
+rootrem (z, n)
+ mpz_coerce z
+ ulong_coerce n
+PREINIT:
+ SV *sv;
+ mpz root;
+ mpz rem;
+PPCODE:
+ root = new_mpz();
+ rem = new_mpz();
+ mpz_rootrem (root->m, rem->m, z, n);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (root, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (rem, mpz_class_hv));
+
+
+# In the past scan0 and scan1 were described as returning ULONG_MAX which
+# could be obtained in perl with ~0. That wasn't true on 64-bit systems
+# (eg. alpha) with perl 5.005, since in that version IV and UV were still
+# 32-bits.
+#
+# We changed in gmp 4.2 to just say ~0 for the not-found return. It's
+# likely most people have used ~0 rather than POSIX::ULONG_MAX(), so this
+# change should match existing usage. It only actually makes a difference
+# in old perl, since recent versions have gone to 64-bits for IV and UV, the
+# same as a ulong.
+#
+# In perl 5.005 we explicitly mask the mpz return down to 32-bits to get ~0.
+# UV_MAX is no good, it reflects the size of the UV type (64-bits), rather
+# than the size of the values one ought to be storing in an SV (32-bits).
+
+gmp_UV
+scan0 (z, start)
+ mpz_coerce z
+ ulong_coerce start
+ALIAS:
+ GMP::Mpz::scan1 = 1
+PREINIT:
+ static_functable const struct {
+ unsigned long (*op) (mpz_srcptr, unsigned long);
+ } table[] = {
+ { mpz_scan0 }, /* 0 */
+ { mpz_scan1 }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = (*table[ix].op) (z, start);
+ if (PERL_LT (5,6))
+ RETVAL &= 0xFFFFFFFF;
+OUTPUT:
+ RETVAL
+
+
+void
+setbit (sv, bit)
+ SV *sv
+ ulong_coerce bit
+ALIAS:
+ GMP::Mpz::clrbit = 1
+ GMP::Mpz::combit = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, unsigned long);
+ } table[] = {
+ { mpz_setbit }, /* 0 */
+ { mpz_clrbit }, /* 1 */
+ { mpz_combit }, /* 2 */
+ };
+ int use;
+ mpz z;
+CODE:
+ use = use_sv (sv);
+ if (use == USE_MPZ && SvREFCNT(SvRV(sv)) == 1 && ! SvSMAGICAL(sv))
+ {
+ /* our operand is a non-magical mpz with a reference count of 1, so
+ we can just modify it */
+ (*table[ix].op) (SvMPZ(sv)->m, bit);
+ }
+ else
+ {
+ /* otherwise we need to make a new mpz, from whatever we have, and
+ operate on that, possibly invoking magic when storing back */
+ SV *new_sv;
+ mpz z = new_mpz ();
+ mpz_ptr coerce_ptr = coerce_mpz_using (z->m, sv, use);
+ if (coerce_ptr != z->m)
+ mpz_set (z->m, coerce_ptr);
+ (*table[ix].op) (z->m, bit);
+ new_sv = sv_bless (sv_setref_pv (sv_newmortal(), NULL, z),
+ mpz_class_hv);
+ SvSetMagicSV (sv, new_sv);
+ }
+
+
+void
+sqrtrem (z)
+ mpz_coerce z
+PREINIT:
+ SV *sv;
+ mpz root;
+ mpz rem;
+PPCODE:
+ root = new_mpz();
+ rem = new_mpz();
+ mpz_sqrtrem (root->m, rem->m, z);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (root, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (rem, mpz_class_hv));
+
+
+size_t
+sizeinbase (z, base)
+ mpz_coerce z
+ int base
+CODE:
+ RETVAL = mpz_sizeinbase (z, base);
+OUTPUT:
+ RETVAL
+
+
+int
+tstbit (z, bit)
+ mpz_coerce z
+ ulong_coerce bit
+CODE:
+ RETVAL = mpz_tstbit (z, bit);
+OUTPUT:
+ RETVAL
+
+
+
+#------------------------------------------------------------------------------
+
+MODULE = GMP PACKAGE = GMP::Mpq
+
+
+mpq
+mpq (...)
+ALIAS:
+ GMP::Mpq::new = 1
+CODE:
+ TRACE (printf ("%s new, ix=%ld, items=%d\n", mpq_class, ix, (int) items));
+ RETVAL = new_mpq();
+ switch (items) {
+ case 0:
+ mpq_set_ui (RETVAL->m, 0L, 1L);
+ break;
+ case 1:
+ {
+ mpq_ptr rp = RETVAL->m;
+ mpq_ptr cp = coerce_mpq (rp, ST(0));
+ if (cp != rp)
+ mpq_set (rp, cp);
+ }
+ break;
+ case 2:
+ {
+ mpz_ptr rp, cp;
+ rp = mpq_numref (RETVAL->m);
+ cp = coerce_mpz (rp, ST(0));
+ if (cp != rp)
+ mpz_set (rp, cp);
+ rp = mpq_denref (RETVAL->m);
+ cp = coerce_mpz (rp, ST(1));
+ if (cp != rp)
+ mpz_set (rp, cp);
+ }
+ break;
+ default:
+ croak ("%s new: invalid arguments", mpq_class);
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+overload_constant (str, pv, d1, ...)
+ const_string_assume str
+ SV *pv
+ dummy d1
+PREINIT:
+ SV *sv;
+ mpq q;
+PPCODE:
+ TRACE (printf ("%s constant: %s\n", mpq_class, str));
+ q = new_mpq();
+ if (mpq_set_str (q->m, str, 0) == 0)
+ { sv = sv_bless (sv_setref_pv (sv_newmortal(), NULL, q), mpq_class_hv); }
+ else
+ { free_mpq (q); sv = pv; }
+ XPUSHs(sv);
+
+
+mpq
+overload_copy (q, d1, d2)
+ mpq_assume q
+ dummy d1
+ dummy d2
+CODE:
+ RETVAL = new_mpq();
+ mpq_set (RETVAL->m, q->m);
+OUTPUT:
+ RETVAL
+
+
+void
+DESTROY (q)
+ mpq_assume q
+CODE:
+ TRACE (printf ("%s DESTROY %p\n", mpq_class, q));
+ free_mpq (q);
+
+
+malloced_string
+overload_string (q, d1, d2)
+ mpq_assume q
+ dummy d1
+ dummy d2
+CODE:
+ TRACE (printf ("%s overload_string %p\n", mpq_class, q));
+ RETVAL = mpq_get_str (NULL, 10, q->m);
+OUTPUT:
+ RETVAL
+
+
+mpq
+overload_add (xv, yv, order)
+ SV *xv
+ SV *yv
+ SV *order
+ALIAS:
+ GMP::Mpq::overload_sub = 1
+ GMP::Mpq::overload_mul = 2
+ GMP::Mpq::overload_div = 3
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpq_ptr, mpq_srcptr, mpq_srcptr);
+ } table[] = {
+ { mpq_add }, /* 0 */
+ { mpq_sub }, /* 1 */
+ { mpq_mul }, /* 2 */
+ { mpq_div }, /* 3 */
+ };
+CODE:
+ TRACE (printf ("%s binary\n", mpf_class));
+ assert_table (ix);
+ if (order == &PL_sv_yes)
+ SV_PTR_SWAP (xv, yv);
+ RETVAL = new_mpq();
+ (*table[ix].op) (RETVAL->m,
+ coerce_mpq (tmp_mpq_0, xv),
+ coerce_mpq (tmp_mpq_1, yv));
+OUTPUT:
+ RETVAL
+
+
+void
+overload_addeq (x, y, o)
+ mpq_assume x
+ mpq_coerce y
+ order_noswap o
+ALIAS:
+ GMP::Mpq::overload_subeq = 1
+ GMP::Mpq::overload_muleq = 2
+ GMP::Mpq::overload_diveq = 3
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpq_ptr, mpq_srcptr, mpq_srcptr);
+ } table[] = {
+ { mpq_add }, /* 0 */
+ { mpq_sub }, /* 1 */
+ { mpq_mul }, /* 2 */
+ { mpq_div }, /* 3 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (x->m, x->m, y);
+ XPUSHs(ST(0));
+
+
+mpq
+overload_lshift (qv, nv, order)
+ SV *qv
+ SV *nv
+ SV *order
+ALIAS:
+ GMP::Mpq::overload_rshift = 1
+ GMP::Mpq::overload_pow = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpq_ptr, mpq_srcptr, unsigned long);
+ } table[] = {
+ { mpq_mul_2exp }, /* 0 */
+ { mpq_div_2exp }, /* 1 */
+ { x_mpq_pow_ui }, /* 2 */
+ };
+CODE:
+ assert_table (ix);
+ if (order == &PL_sv_yes)
+ SV_PTR_SWAP (qv, nv);
+ RETVAL = new_mpq();
+ (*table[ix].op) (RETVAL->m, coerce_mpq (RETVAL->m, qv), coerce_ulong (nv));
+OUTPUT:
+ RETVAL
+
+
+void
+overload_lshifteq (q, n, o)
+ mpq_assume q
+ ulong_coerce n
+ order_noswap o
+ALIAS:
+ GMP::Mpq::overload_rshifteq = 1
+ GMP::Mpq::overload_poweq = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpq_ptr, mpq_srcptr, unsigned long);
+ } table[] = {
+ { mpq_mul_2exp }, /* 0 */
+ { mpq_div_2exp }, /* 1 */
+ { x_mpq_pow_ui }, /* 2 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (q->m, q->m, n);
+ XPUSHs(ST(0));
+
+
+void
+overload_inc (q, d1, d2)
+ mpq_assume q
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpq::overload_dec = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
+ } table[] = {
+ { mpz_add }, /* 0 */
+ { mpz_sub }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ (*table[ix].op) (mpq_numref(q->m), mpq_numref(q->m), mpq_denref(q->m));
+
+
+mpq
+overload_abs (q, d1, d2)
+ mpq_assume q
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpq::overload_neg = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpq_ptr w, mpq_srcptr x);
+ } table[] = {
+ { mpq_abs }, /* 0 */
+ { mpq_neg }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpq();
+ (*table[ix].op) (RETVAL->m, q->m);
+OUTPUT:
+ RETVAL
+
+
+int
+overload_spaceship (x, y, order)
+ mpq_assume x
+ mpq_coerce y
+ SV *order
+CODE:
+ RETVAL = mpq_cmp (x->m, y);
+ RETVAL = SGN (RETVAL);
+ if (order == &PL_sv_yes)
+ RETVAL = -RETVAL;
+OUTPUT:
+ RETVAL
+
+
+bool
+overload_bool (q, d1, d2)
+ mpq_assume q
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpq::overload_not = 1
+CODE:
+ RETVAL = (mpq_sgn (q->m) != 0) ^ ix;
+OUTPUT:
+ RETVAL
+
+
+bool
+overload_eq (x, yv, d)
+ mpq_assume x
+ SV *yv
+ dummy d
+ALIAS:
+ GMP::Mpq::overload_ne = 1
+PREINIT:
+ int use;
+CODE:
+ use = use_sv (yv);
+ switch (use) {
+ case USE_IVX:
+ case USE_UVX:
+ case USE_MPZ:
+ RETVAL = 0;
+ if (x_mpq_integer_p (x->m))
+ {
+ switch (use) {
+ case USE_IVX:
+ RETVAL = (mpz_cmp_si (mpq_numref(x->m), SvIVX(yv)) == 0);
+ break;
+ case USE_UVX:
+ RETVAL = (mpz_cmp_ui (mpq_numref(x->m), SvUVX(yv)) == 0);
+ break;
+ case USE_MPZ:
+ RETVAL = (mpz_cmp (mpq_numref(x->m), SvMPZ(yv)->m) == 0);
+ break;
+ }
+ }
+ break;
+
+ case USE_MPQ:
+ RETVAL = (mpq_equal (x->m, SvMPQ(yv)->m) != 0);
+ break;
+
+ default:
+ RETVAL = (mpq_equal (x->m, coerce_mpq_using (tmp_mpq_0, yv, use)) != 0);
+ break;
+ }
+ RETVAL ^= ix;
+OUTPUT:
+ RETVAL
+
+
+void
+canonicalize (q)
+ mpq q
+CODE:
+ mpq_canonicalize (q->m);
+
+
+mpq
+inv (q)
+ mpq_coerce q
+CODE:
+ RETVAL = new_mpq();
+ mpq_inv (RETVAL->m, q);
+OUTPUT:
+ RETVAL
+
+
+mpz
+num (q)
+ mpq q
+ALIAS:
+ GMP::Mpq::den = 1
+CODE:
+ RETVAL = new_mpz();
+ mpz_set (RETVAL->m, (ix == 0 ? mpq_numref(q->m) : mpq_denref(q->m)));
+OUTPUT:
+ RETVAL
+
+
+
+#------------------------------------------------------------------------------
+
+MODULE = GMP PACKAGE = GMP::Mpf
+
+
+mpf
+mpf (...)
+ALIAS:
+ GMP::Mpf::new = 1
+PREINIT:
+ unsigned long prec;
+CODE:
+ TRACE (printf ("%s new\n", mpf_class));
+ if (items > 2)
+ croak ("%s new: invalid arguments", mpf_class);
+ prec = (items == 2 ? coerce_ulong (ST(1)) : mpf_get_default_prec());
+ RETVAL = new_mpf (prec);
+ if (items >= 1)
+ {
+ SV *sv = ST(0);
+ my_mpf_set_sv_using (RETVAL, sv, use_sv(sv));
+ }
+OUTPUT:
+ RETVAL
+
+
+mpf
+overload_constant (sv, d1, d2, ...)
+ SV *sv
+ dummy d1
+ dummy d2
+CODE:
+ assert (SvPOK (sv));
+ TRACE (printf ("%s constant: %s\n", mpq_class, SvPVX(sv)));
+ RETVAL = new_mpf (mpf_get_default_prec());
+ my_mpf_set_svstr (RETVAL, sv);
+OUTPUT:
+ RETVAL
+
+
+mpf
+overload_copy (f, d1, d2)
+ mpf_assume f
+ dummy d1
+ dummy d2
+CODE:
+ TRACE (printf ("%s copy\n", mpf_class));
+ RETVAL = new_mpf (mpf_get_prec (f));
+ mpf_set (RETVAL, f);
+OUTPUT:
+ RETVAL
+
+
+void
+DESTROY (f)
+ mpf_assume f
+CODE:
+ TRACE (printf ("%s DESTROY %p\n", mpf_class, f));
+ mpf_clear (f);
+ Safefree (f);
+ assert_support (mpf_count--);
+ TRACE_ACTIVE ();
+
+
+mpf
+overload_add (x, y, order)
+ mpf_assume x
+ mpf_coerce_st0 y
+ SV *order
+ALIAS:
+ GMP::Mpf::overload_sub = 1
+ GMP::Mpf::overload_mul = 2
+ GMP::Mpf::overload_div = 3
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr, mpf_srcptr, mpf_srcptr);
+ } table[] = {
+ { mpf_add }, /* 0 */
+ { mpf_sub }, /* 1 */
+ { mpf_mul }, /* 2 */
+ { mpf_div }, /* 3 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpf (mpf_get_prec (x));
+ if (order == &PL_sv_yes)
+ MPF_PTR_SWAP (x, y);
+ (*table[ix].op) (RETVAL, x, y);
+OUTPUT:
+ RETVAL
+
+
+void
+overload_addeq (x, y, o)
+ mpf_assume x
+ mpf_coerce_st0 y
+ order_noswap o
+ALIAS:
+ GMP::Mpf::overload_subeq = 1
+ GMP::Mpf::overload_muleq = 2
+ GMP::Mpf::overload_diveq = 3
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr, mpf_srcptr, mpf_srcptr);
+ } table[] = {
+ { mpf_add }, /* 0 */
+ { mpf_sub }, /* 1 */
+ { mpf_mul }, /* 2 */
+ { mpf_div }, /* 3 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (x, x, y);
+ XPUSHs(ST(0));
+
+
+mpf
+overload_lshift (fv, nv, order)
+ SV *fv
+ SV *nv
+ SV *order
+ALIAS:
+ GMP::Mpf::overload_rshift = 1
+ GMP::Mpf::overload_pow = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr, mpf_srcptr, unsigned long);
+ } table[] = {
+ { mpf_mul_2exp }, /* 0 */
+ { mpf_div_2exp }, /* 1 */
+ { mpf_pow_ui }, /* 2 */
+ };
+ mpf f;
+ unsigned long prec;
+CODE:
+ assert_table (ix);
+ MPF_ASSUME (f, fv);
+ prec = mpf_get_prec (f);
+ if (order == &PL_sv_yes)
+ SV_PTR_SWAP (fv, nv);
+ f = coerce_mpf (tmp_mpf_0, fv, prec);
+ RETVAL = new_mpf (prec);
+ (*table[ix].op) (RETVAL, f, coerce_ulong (nv));
+OUTPUT:
+ RETVAL
+
+
+void
+overload_lshifteq (f, n, o)
+ mpf_assume f
+ ulong_coerce n
+ order_noswap o
+ALIAS:
+ GMP::Mpf::overload_rshifteq = 1
+ GMP::Mpf::overload_poweq = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr, mpf_srcptr, unsigned long);
+ } table[] = {
+ { mpf_mul_2exp }, /* 0 */
+ { mpf_div_2exp }, /* 1 */
+ { mpf_pow_ui }, /* 2 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (f, f, n);
+ XPUSHs(ST(0));
+
+
+mpf
+overload_abs (f, d1, d2)
+ mpf_assume f
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpf::overload_neg = 1
+ GMP::Mpf::overload_sqrt = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr w, mpf_srcptr x);
+ } table[] = {
+ { mpf_abs }, /* 0 */
+ { mpf_neg }, /* 1 */
+ { mpf_sqrt }, /* 2 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpf (mpf_get_prec (f));
+ (*table[ix].op) (RETVAL, f);
+OUTPUT:
+ RETVAL
+
+
+void
+overload_inc (f, d1, d2)
+ mpf_assume f
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpf::overload_dec = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr w, mpf_srcptr x, unsigned long y);
+ } table[] = {
+ { mpf_add_ui }, /* 0 */
+ { mpf_sub_ui }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ (*table[ix].op) (f, f, 1L);
+
+
+int
+overload_spaceship (xv, yv, order)
+ SV *xv
+ SV *yv
+ SV *order
+PREINIT:
+ mpf x;
+CODE:
+ MPF_ASSUME (x, xv);
+ switch (use_sv (yv)) {
+ case USE_IVX:
+ RETVAL = mpf_cmp_si (x, SvIVX(yv));
+ break;
+ case USE_UVX:
+ RETVAL = mpf_cmp_ui (x, SvUVX(yv));
+ break;
+ case USE_NVX:
+ RETVAL = mpf_cmp_d (x, SvNVX(yv));
+ break;
+ case USE_PVX:
+ {
+ STRLEN len;
+ const char *str = SvPV (yv, len);
+ /* enough for all digits of the string */
+ tmp_mpf_set_prec (tmp_mpf_0, strlen(str)+64);
+ if (mpf_set_str (tmp_mpf_0->m, str, 10) != 0)
+ croak ("%s <=>: invalid string format", mpf_class);
+ RETVAL = mpf_cmp (x, tmp_mpf_0->m);
+ }
+ break;
+ case USE_MPZ:
+ RETVAL = - x_mpz_cmp_f (SvMPZ(yv)->m, x);
+ break;
+ case USE_MPF:
+ RETVAL = mpf_cmp (x, SvMPF(yv));
+ break;
+ default:
+ RETVAL = mpq_cmp (coerce_mpq (tmp_mpq_0, xv),
+ coerce_mpq (tmp_mpq_1, yv));
+ break;
+ }
+ RETVAL = SGN (RETVAL);
+ if (order == &PL_sv_yes)
+ RETVAL = -RETVAL;
+OUTPUT:
+ RETVAL
+
+
+bool
+overload_bool (f, d1, d2)
+ mpf_assume f
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpf::overload_not = 1
+CODE:
+ RETVAL = (mpf_sgn (f) != 0) ^ ix;
+OUTPUT:
+ RETVAL
+
+
+mpf
+ceil (f)
+ mpf_coerce_def f
+ALIAS:
+ GMP::Mpf::floor = 1
+ GMP::Mpf::trunc = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr w, mpf_srcptr x);
+ } table[] = {
+ { mpf_ceil }, /* 0 */
+ { mpf_floor }, /* 1 */
+ { mpf_trunc }, /* 2 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpf (mpf_get_prec (f));
+ (*table[ix].op) (RETVAL, f);
+OUTPUT:
+ RETVAL
+
+
+unsigned long
+get_default_prec ()
+CODE:
+ RETVAL = mpf_get_default_prec();
+OUTPUT:
+ RETVAL
+
+
+unsigned long
+get_prec (f)
+ mpf_coerce_def f
+CODE:
+ RETVAL = mpf_get_prec (f);
+OUTPUT:
+ RETVAL
+
+
+bool
+mpf_eq (xv, yv, bits)
+ SV *xv
+ SV *yv
+ ulong_coerce bits
+PREINIT:
+ mpf x, y;
+CODE:
+ TRACE (printf ("%s eq\n", mpf_class));
+ coerce_mpf_pair (&x,xv, &y,yv);
+ RETVAL = mpf_eq (x, y, bits);
+OUTPUT:
+ RETVAL
+
+
+mpf
+reldiff (xv, yv)
+ SV *xv
+ SV *yv
+PREINIT:
+ mpf x, y;
+ unsigned long prec;
+CODE:
+ TRACE (printf ("%s reldiff\n", mpf_class));
+ prec = coerce_mpf_pair (&x,xv, &y,yv);
+ RETVAL = new_mpf (prec);
+ mpf_reldiff (RETVAL, x, y);
+OUTPUT:
+ RETVAL
+
+
+void
+set_default_prec (prec)
+ ulong_coerce prec
+CODE:
+ TRACE (printf ("%s set_default_prec %lu\n", mpf_class, prec));
+ mpf_set_default_prec (prec);
+
+
+void
+set_prec (sv, prec)
+ SV *sv
+ ulong_coerce prec
+PREINIT:
+ mpf_ptr old_f, new_f;
+ int use;
+CODE:
+ TRACE (printf ("%s set_prec to %lu\n", mpf_class, prec));
+ use = use_sv (sv);
+ if (use == USE_MPF)
+ {
+ old_f = SvMPF(sv);
+ if (SvREFCNT(SvRV(sv)) == 1)
+ mpf_set_prec (old_f, prec);
+ else
+ {
+ TRACE (printf (" fork new mpf\n"));
+ new_f = new_mpf (prec);
+ mpf_set (new_f, old_f);
+ goto setref;
+ }
+ }
+ else
+ {
+ TRACE (printf (" coerce to mpf\n"));
+ new_f = new_mpf (prec);
+ my_mpf_set_sv_using (new_f, sv, use);
+ setref:
+ sv_bless (sv_setref_pv (sv, NULL, new_f), mpf_class_hv);
+ }
+
+
+
+#------------------------------------------------------------------------------
+
+MODULE = GMP PACKAGE = GMP::Rand
+
+randstate
+new (...)
+ALIAS:
+ GMP::Rand::randstate = 1
+CODE:
+ TRACE (printf ("%s new\n", rand_class));
+ New (GMP_MALLOC_ID, RETVAL, 1, __gmp_randstate_struct);
+ TRACE (printf (" RETVAL %p\n", RETVAL));
+ assert_support (rand_count++);
+ TRACE_ACTIVE ();
+
+ if (items == 0)
+ {
+ gmp_randinit_default (RETVAL);
+ }
+ else
+ {
+ if (SvROK (ST(0)) && sv_derived_from (ST(0), rand_class))
+ {
+ if (items != 1)
+ goto invalid;
+ gmp_randinit_set (RETVAL, SvRANDSTATE (ST(0)));
+ }
+ else
+ {
+ STRLEN len;
+ const char *method = SvPV (ST(0), len);
+ assert (len == strlen (method));
+ if (strcmp (method, "lc_2exp") == 0)
+ {
+ if (items != 4)
+ goto invalid;
+ gmp_randinit_lc_2exp (RETVAL,
+ coerce_mpz (tmp_mpz_0, ST(1)),
+ coerce_ulong (ST(2)),
+ coerce_ulong (ST(3)));
+ }
+ else if (strcmp (method, "lc_2exp_size") == 0)
+ {
+ if (items != 2)
+ goto invalid;
+ if (! gmp_randinit_lc_2exp_size (RETVAL, coerce_ulong (ST(1))))
+ {
+ Safefree (RETVAL);
+ XSRETURN_UNDEF;
+ }
+ }
+ else if (strcmp (method, "mt") == 0)
+ {
+ if (items != 1)
+ goto invalid;
+ gmp_randinit_mt (RETVAL);
+ }
+ else
+ {
+ invalid:
+ croak ("%s new: invalid arguments", rand_class);
+ }
+ }
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+DESTROY (r)
+ randstate r
+CODE:
+ TRACE (printf ("%s DESTROY\n", rand_class));
+ gmp_randclear (r);
+ Safefree (r);
+ assert_support (rand_count--);
+ TRACE_ACTIVE ();
+
+
+void
+seed (r, z)
+ randstate r
+ mpz_coerce z
+CODE:
+ gmp_randseed (r, z);
+
+
+mpz
+mpz_urandomb (r, bits)
+ randstate r
+ ulong_coerce bits
+ALIAS:
+ GMP::Rand::mpz_rrandomb = 1
+PREINIT:
+ static_functable const struct {
+ void (*fun) (mpz_ptr, gmp_randstate_t r, unsigned long bits);
+ } table[] = {
+ { mpz_urandomb }, /* 0 */
+ { mpz_rrandomb }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ (*table[ix].fun) (RETVAL->m, r, bits);
+OUTPUT:
+ RETVAL
+
+
+mpz
+mpz_urandomm (r, m)
+ randstate r
+ mpz_coerce m
+CODE:
+ RETVAL = new_mpz();
+ mpz_urandomm (RETVAL->m, r, m);
+OUTPUT:
+ RETVAL
+
+
+mpf
+mpf_urandomb (r, bits)
+ randstate r
+ ulong_coerce bits
+CODE:
+ RETVAL = new_mpf (bits);
+ mpf_urandomb (RETVAL, r, bits);
+OUTPUT:
+ RETVAL
+
+
+unsigned long
+gmp_urandomb_ui (r, bits)
+ randstate r
+ ulong_coerce bits
+ALIAS:
+ GMP::Rand::gmp_urandomm_ui = 1
+PREINIT:
+ static_functable const struct {
+ unsigned long (*fun) (gmp_randstate_t r, unsigned long bits);
+ } table[] = {
+ { gmp_urandomb_ui }, /* 0 */
+ { gmp_urandomm_ui }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = (*table[ix].fun) (r, bits);
+OUTPUT:
+ RETVAL
diff --git a/vendor/gmp-6.3.0/demos/perl/GMP/Mpf.pm b/vendor/gmp-6.3.0/demos/perl/GMP/Mpf.pm
new file mode 100644
index 0000000..4c0dec6
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/GMP/Mpf.pm
@@ -0,0 +1,106 @@
+# GMP mpf module.
+
+# Copyright 2001, 2003 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/.
+
+
+package GMP::Mpf;
+
+require GMP;
+require Exporter;
+@ISA = qw(GMP Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw();
+%EXPORT_TAGS = ('all' => [qw(
+ ceil floor get_default_prec get_prec mpf mpf_eq
+ reldiff set_default_prec set_prec trunc)],
+ 'constants' => [@EXPORT],
+ 'noconstants' => [@EXPORT]);
+Exporter::export_ok_tags('all');
+
+use overload
+ '+' => \&overload_add, '+=' => \&overload_addeq,
+ '-' => \&overload_sub, '-=' => \&overload_subeq,
+ '*' => \&overload_mul, '*=' => \&overload_muleq,
+ '/' => \&overload_div, '/=' => \&overload_diveq,
+ '**' => \&overload_pow, '**=' => \&overload_poweq,
+ '<<' => \&overload_lshift, '<<=' => \&overload_lshifteq,
+ '>>' => \&overload_rshift, '>>=' => \&overload_rshifteq,
+
+ 'bool' => \&overload_bool,
+ 'not' => \&overload_not,
+ '!' => \&overload_not,
+ '<=>' => \&overload_spaceship,
+ '++' => \&overload_inc,
+ '--' => \&overload_dec,
+ 'abs' => \&overload_abs,
+ 'neg' => \&overload_neg,
+ 'sqrt' => \&overload_sqrt,
+ '=' => \&overload_copy,
+ '""' => \&overload_string;
+
+sub import {
+ foreach (@_) {
+ if ($_ eq ':constants') {
+ overload::constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ } elsif ($_ eq ':noconstants') {
+ overload::remove_constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ }
+ }
+ goto &Exporter::import;
+}
+
+
+sub overload_string {
+ my $fmt;
+ BEGIN { $^W = 0; }
+ if (defined ($#)) {
+ $fmt = $#;
+ BEGIN { $^W = 1; }
+ # protect against calling sprintf_internal with a bad format
+ if ($fmt !~ /^((%%|[^%])*%[-+ .\d]*)([eEfgG](%%|[^%])*)$/) {
+ die "GMP::Mpf: invalid \$# format: $#\n";
+ }
+ $fmt = $1 . 'F' . $3;
+ } else {
+ $fmt = '%.Fg';
+ }
+ GMP::sprintf_internal ($fmt, $_[0]);
+}
+
+1;
+__END__
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/vendor/gmp-6.3.0/demos/perl/GMP/Mpq.pm b/vendor/gmp-6.3.0/demos/perl/GMP/Mpq.pm
new file mode 100644
index 0000000..fe01084
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/GMP/Mpq.pm
@@ -0,0 +1,89 @@
+# GMP mpq module.
+
+# Copyright 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/.
+
+
+package GMP::Mpq;
+
+require GMP;
+require Exporter;
+@ISA = qw(GMP Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw();
+%EXPORT_TAGS = ('all' => [qw(canonicalize den inv mpq num)],
+ 'constants' => [@EXPORT],
+ 'noconstants' => [@EXPORT] );
+Exporter::export_ok_tags('all');
+
+use overload
+ '+' => \&overload_add, '+=' => \&overload_addeq,
+ '-' => \&overload_sub, '-=' => \&overload_subeq,
+ '*' => \&overload_mul, '*=' => \&overload_muleq,
+ '/' => \&overload_div, '/=' => \&overload_diveq,
+ '**' => \&overload_pow, '**=' => \&overload_poweq,
+ '<<' => \&overload_lshift, '<<=' => \&overload_lshifteq,
+ '>>' => \&overload_rshift, '>>=' => \&overload_rshifteq,
+
+ 'bool' => \&overload_bool,
+ 'not' => \&overload_not,
+ '!' => \&overload_not,
+ '==' => \&overload_eq,
+ '!=' => \&overload_ne,
+ '<=>' => \&overload_spaceship,
+ '++' => \&overload_inc,
+ '--' => \&overload_dec,
+ 'abs' => \&overload_abs,
+ 'neg' => \&overload_neg,
+ '=' => \&overload_copy,
+ '""' => \&overload_string;
+
+my $constants = { };
+
+sub import {
+ foreach (@_) {
+ if ($_ eq ':constants') {
+ overload::constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ } elsif ($_ eq ':noconstants') {
+ overload::remove_constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ }
+ }
+ goto &Exporter::import;
+}
+
+1;
+__END__
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/vendor/gmp-6.3.0/demos/perl/GMP/Mpz.pm b/vendor/gmp-6.3.0/demos/perl/GMP/Mpz.pm
new file mode 100644
index 0000000..27e6336
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/GMP/Mpz.pm
@@ -0,0 +1,101 @@
+# GMP mpz module.
+
+# Copyright 2001-2003 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/.
+
+
+package GMP::Mpz;
+
+require GMP;
+require Exporter;
+@ISA = qw(GMP Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw();
+%EXPORT_TAGS = ('all' => [qw(
+ bin cdiv cdiv_2exp clrbit combit congruent_p
+ congruent_2exp_p divexact divisible_p
+ divisible_2exp_p even_p fac fdiv fdiv_2exp fib
+ fib2 gcd gcdext hamdist invert jacobi kronecker
+ lcm lucnum lucnum2 mod mpz mpz_export
+ mpz_import nextprime odd_p perfect_power_p
+ perfect_square_p popcount powm probab_prime_p
+ realloc remove root roote rootrem scan0 scan1
+ setbit sizeinbase sqrtrem tdiv tdiv_2exp
+ tstbit)],
+ 'constants' => [@EXPORT],
+ 'noconstants' => [@EXPORT]);
+Exporter::export_ok_tags('all');
+
+use overload
+ '+' => \&overload_add, '+=' => \&overload_addeq,
+ '-' => \&overload_sub, '-=' => \&overload_subeq,
+ '*' => \&overload_mul, '*=' => \&overload_muleq,
+ '/' => \&overload_div, '/=' => \&overload_diveq,
+ '%' => \&overload_rem, '%=' => \&overload_remeq,
+ '<<' => \&overload_lshift, '<<=' => \&overload_lshifteq,
+ '>>' => \&overload_rshift, '>>=' => \&overload_rshifteq,
+ '**' => \&overload_pow, '**=' => \&overload_poweq,
+ '&' => \&overload_and, '&=' => \&overload_andeq,
+ '|' => \&overload_ior, '|=' => \&overload_ioreq,
+ '^' => \&overload_xor, '^=' => \&overload_xoreq,
+
+ 'bool' => \&overload_bool,
+ 'not' => \&overload_not,
+ '!' => \&overload_not,
+ '~' => \&overload_com,
+ '<=>' => \&overload_spaceship,
+ '++' => \&overload_inc,
+ '--' => \&overload_dec,
+ '=' => \&overload_copy,
+ 'abs' => \&overload_abs,
+ 'neg' => \&overload_neg,
+ 'sqrt' => \&overload_sqrt,
+ '""' => \&overload_string;
+
+sub import {
+ foreach (@_) {
+ if ($_ eq ':constants') {
+ overload::constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ } elsif ($_ eq ':noconstants') {
+ overload::remove_constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ }
+ }
+ goto &Exporter::import;
+}
+
+1;
+__END__
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/vendor/gmp-6.3.0/demos/perl/GMP/Rand.pm b/vendor/gmp-6.3.0/demos/perl/GMP/Rand.pm
new file mode 100644
index 0000000..9f7d763
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/GMP/Rand.pm
@@ -0,0 +1,44 @@
+# GMP random numbers module.
+
+# Copyright 2001, 2003 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/.
+
+
+package GMP::Rand;
+
+require GMP;
+require Exporter;
+@ISA = qw(GMP Exporter);
+@EXPORT = qw();
+%EXPORT_TAGS = ('all' => [qw(
+ randstate mpf_urandomb mpz_rrandomb
+ mpz_urandomb mpz_urandomm gmp_urandomb_ui
+ gmp_urandomm_ui)]);
+Exporter::export_ok_tags('all');
+1;
+__END__
diff --git a/vendor/gmp-6.3.0/demos/perl/INSTALL b/vendor/gmp-6.3.0/demos/perl/INSTALL
new file mode 100644
index 0000000..f3d7c53
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/INSTALL
@@ -0,0 +1,88 @@
+Copyright 2001, 2003, 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 PERL MODULE INSTALLATION
+
+
+This module can be compiled within the GMP source directory or moved
+elsewhere and compiled. An installed GMP can be used, or a specified
+GMP build tree. Both static and shared GMP builds will work.
+
+The simplest case is when GMP has been installed to a standard system
+location
+
+ perl Makefile.PL
+ make
+
+If not yet installed then the top-level GMP build directory must be
+specified
+
+ perl Makefile.PL GMP_BUILDDIR=/my/gmp/build
+ make
+
+In any case, with the module built, the sample program provided can be
+run
+
+ perl -Iblib/arch sample.pl
+
+If you built a shared version of libgmp but haven't yet installed it,
+then it might be necessary to add a run-time path to it. For example
+
+ LD_LIBRARY_PATH=/my/gmp/build/.libs perl -Iblib/arch sample.pl
+
+Documentation is provided in pod format in GMP.pm, and will have been
+"man"-ified in the module build
+
+ man -l blib/man3/GMP.3pm
+or
+ man -M`pwd`/blib GMP
+
+A test script is provided, running a large number of more or less
+trivial checks
+
+ make test
+
+The module and its documentation can be installed in the usual way
+
+ make install
+
+This will be into /usr/local or wherever the perl Config module
+directs, but that can be controlled back at the Makefile.PL stage with
+the usual ExtUtils::MakeMaker options.
+
+Once installed, programs using the GMP module become simply
+
+ perl sample.pl
+
+And the documentation read directly too
+
+ man GMP
diff --git a/vendor/gmp-6.3.0/demos/perl/Makefile.PL b/vendor/gmp-6.3.0/demos/perl/Makefile.PL
new file mode 100644
index 0000000..a676710
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/Makefile.PL
@@ -0,0 +1,82 @@
+# Makefile for GMP perl module.
+
+# Copyright 2001, 2003, 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/.
+
+
+# Bugs:
+#
+# When the generated Makefile re-runs "perl Makefile.PL" the GMP_BUILDDIR
+# parameter is lost.
+
+
+use ExtUtils::MakeMaker;
+
+
+# Find and remove our parameters
+@ARGV = map {
+ if (/^GMP_BUILDDIR=(.*)/) {
+ $GMP_BUILDDIR=$1; ();
+ } else {
+ $_;
+ }
+} (@ARGV);
+
+$INC = "";
+$LIBS = "-lgmp";
+$OBJECT = "GMP.o";
+
+if (defined $GMP_BUILDDIR) {
+ if (! -f "$GMP_BUILDDIR/libgmp.la") {
+ die "$GMP_BUILDDIR doesn't contain libgmp.la\n" .
+ "if it's really a gmp build directory then go there and run \"make libgmp.la\"\n";
+ }
+ $INC = "-I$GMP_BUILDDIR $INC";
+ $LIBS = "-L$GMP_BUILDDIR/.libs $LIBS";
+}
+
+WriteMakefile(
+ NAME => 'GMP',
+ VERSION => '2.00',
+ LIBS => [$LIBS],
+ OBJECT => $OBJECT,
+ INC => $INC,
+ clean => { FILES => 'test.tmp' },
+ PM => {
+ 'GMP.pm' => '$(INST_LIBDIR)/GMP.pm',
+ 'GMP/Mpz.pm' => '$(INST_LIBDIR)/GMP/Mpz.pm',
+ 'GMP/Mpq.pm' => '$(INST_LIBDIR)/GMP/Mpq.pm',
+ 'GMP/Mpf.pm' => '$(INST_LIBDIR)/GMP/Mpf.pm',
+ 'GMP/Rand.pm' => '$(INST_LIBDIR)/GMP/Rand.pm',
+ }
+ );
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/vendor/gmp-6.3.0/demos/perl/sample.pl b/vendor/gmp-6.3.0/demos/perl/sample.pl
new file mode 100644
index 0000000..8a10ee1
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/sample.pl
@@ -0,0 +1,54 @@
+#!/usr/bin/perl -w
+
+# Some sample GMP module operations
+
+# 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/.
+
+use strict;
+
+
+use GMP;
+print "using GMP module $GMP::VERSION and GMP library ",GMP::version(),"\n";
+
+
+use GMP::Mpz qw(:all);
+print "the 200th fibonacci number is ", fib(200), "\n";
+print "next prime after 10**30 is (probably) ", nextprime(mpz(10)**30), "\n";
+
+
+use GMP::Mpq qw(:constants);
+print "the 7th harmonic number is ", 1+1/2+1/3+1/4+1/5+1/6+1/7, "\n";
+use GMP::Mpq qw(:noconstants);
+
+
+use GMP::Mpf qw(mpf);
+my $f = mpf(1,180);
+$f >>= 180;
+$f += 1;
+print "a sample mpf is $f\n";
diff --git a/vendor/gmp-6.3.0/demos/perl/test.pl b/vendor/gmp-6.3.0/demos/perl/test.pl
new file mode 100644
index 0000000..2b54089
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/test.pl
@@ -0,0 +1,2179 @@
+#!/usr/bin/perl -w
+
+# GMP perl module tests
+
+# Copyright 2001-2003 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/.
+
+
+# These tests aim to exercise the many possible combinations of operands
+# etc, and to run all functions at least once, which if nothing else will
+# check everything intended is in the :all list.
+#
+# Use the following in .emacs to match test failure messages.
+#
+# ;; perl "Test" module error messages
+# (eval-after-load "compile"
+# '(add-to-list
+# 'compilation-error-regexp-alist
+# '("^.*Failed test [0-9]+ in \\([^ ]+\\) at line \\([0-9]+\\)" 1 2)))
+
+
+use strict;
+use Test;
+
+BEGIN {
+ plan tests => 123,
+ onfail => sub { print "there were failures\n" },
+}
+
+use GMP qw(:all);
+use GMP::Mpz qw(:all);
+use GMP::Mpq qw(:all);
+use GMP::Mpf qw(:all);
+use GMP::Rand qw(:all);
+
+use GMP::Mpz qw(:constants);
+use GMP::Mpz qw(:noconstants);
+use GMP::Mpq qw(:constants);
+use GMP::Mpq qw(:noconstants);
+use GMP::Mpf qw(:constants);
+use GMP::Mpf qw(:noconstants);
+
+package Mytie;
+use Exporter;
+use vars qw($val $fetched $stored);
+$val = 0;
+$fetched = 0;
+$stored = 0;
+sub TIESCALAR {
+ my ($class, $newval) = @_;
+ my $var = 'mytie dummy refed var';
+ $val = $newval;
+ $fetched = 0;
+ $stored = 0;
+ return bless \$var, $class;
+}
+sub FETCH {
+ my ($self) = @_;
+ $fetched++;
+ return $val;
+}
+sub STORE {
+ my ($self, $newval) = @_;
+ $val = $newval;
+ $stored++;
+}
+package main;
+
+# check Mytie does what it should
+{ tie my $t, 'Mytie', 123;
+ ok ($Mytie::val == 123);
+ $Mytie::val = 456;
+ ok ($t == 456);
+ $t = 789;
+ ok ($Mytie::val == 789);
+}
+
+
+# Usage: str(x)
+# Return x forced to a string, not a PVIV.
+#
+sub str {
+ my $s = "$_[0]" . "";
+ return $s;
+}
+
+my $ivnv_2p128 = 65536.0 * 65536.0 * 65536.0 * 65536.0
+ * 65536.0 * 65536.0 * 65536.0 * 65536.0;
+kill (0, $ivnv_2p128);
+my $str_2p128 = '340282366920938463463374607431768211456';
+
+my $uv_max = ~ 0;
+my $uv_max_str = ~ 0;
+$uv_max_str = "$uv_max_str";
+$uv_max_str = "" . "$uv_max_str";
+
+
+#------------------------------------------------------------------------------
+# GMP::version
+
+use GMP qw(version);
+print '$GMP::VERSION ',$GMP::VERSION,' GMP::version() ',version(),"\n";
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::new
+
+ok (mpz(0) == 0);
+ok (mpz('0') == 0);
+ok (mpz(substr('101',1,1)) == 0);
+ok (mpz(0.0) == 0);
+ok (mpz(mpz(0)) == 0);
+ok (mpz(mpq(0)) == 0);
+ok (mpz(mpf(0)) == 0);
+
+{ tie my $t, 'Mytie', 0;
+ ok (mpz($t) == 0);
+ ok ($Mytie::fetched > 0);
+}
+{ tie my $t, 'Mytie', '0';
+ ok (mpz($t) == 0);
+ ok ($Mytie::fetched > 0);
+}
+{ tie my $t, 'Mytie', substr('101',1,1); ok (mpz($t) == 0); }
+{ tie my $t, 'Mytie', 0.0; ok (mpz($t) == 0); }
+{ tie my $t, 'Mytie', mpz(0); ok (mpz($t) == 0); }
+{ tie my $t, 'Mytie', mpq(0); ok (mpz($t) == 0); }
+{ tie my $t, 'Mytie', mpf(0); ok (mpz($t) == 0); }
+
+ok (mpz(-123) == -123);
+ok (mpz('-123') == -123);
+ok (mpz(substr('1-1231',1,4)) == -123);
+ok (mpz(-123.0) == -123);
+ok (mpz(mpz(-123)) == -123);
+ok (mpz(mpq(-123)) == -123);
+ok (mpz(mpf(-123)) == -123);
+
+{ tie my $t, 'Mytie', -123; ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', '-123'; ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', substr('1-1231',1,4); ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', -123.0; ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', mpz(-123); ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', mpq(-123); ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', mpf(-123); ok (mpz($t) == -123); }
+
+ok (mpz($ivnv_2p128) == $str_2p128);
+{ tie my $t, 'Mytie', $ivnv_2p128; ok (mpz($t) == $str_2p128); }
+
+ok (mpz($uv_max) > 0);
+ok (mpz($uv_max) == mpz($uv_max_str));
+{ tie my $t, 'Mytie', $uv_max; ok (mpz($t) > 0); }
+{ tie my $t, 'Mytie', $uv_max; ok (mpz($t) == mpz($uv_max_str)); }
+
+{ my $s = '999999999999999999999999999999';
+ kill (0, $s);
+ ok (mpz($s) == '999999999999999999999999999999');
+ tie my $t, 'Mytie', $s;
+ ok (mpz($t) == '999999999999999999999999999999');
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_abs
+
+ok (abs(mpz(0)) == 0);
+ok (abs(mpz(123)) == 123);
+ok (abs(mpz(-123)) == 123);
+
+{ my $x = mpz(-123); $x = abs($x); ok ($x == 123); }
+{ my $x = mpz(0); $x = abs($x); ok ($x == 0); }
+{ my $x = mpz(123); $x = abs($x); ok ($x == 123); }
+
+{ tie my $t, 'Mytie', mpz(0); ok (abs($t) == 0); }
+{ tie my $t, 'Mytie', mpz(123); ok (abs($t) == 123); }
+{ tie my $t, 'Mytie', mpz(-123); ok (abs($t) == 123); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_add
+
+ok (mpz(0) + 1 == 1);
+ok (mpz(-1) + 1 == 0);
+ok (1 + mpz(0) == 1);
+ok (1 + mpz(-1) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_addeq
+
+{ my $a = mpz(7); $a += 1; ok ($a == 8); }
+{ my $a = mpz(7); my $b = $a; $a += 1; ok ($a == 8); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_and
+
+ok ((mpz(3) & 1) == 1);
+ok ((mpz(3) & 4) == 0);
+
+{ my $a = mpz(3); $a &= 1; ok ($a == 1); }
+{ my $a = mpz(3); $a &= 4; ok ($a == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_bool
+
+if (mpz(0)) { ok (0); } else { ok (1); }
+if (mpz(123)) { ok (1); } else { ok (0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_com
+
+ok (~ mpz(0) == -1);
+ok (~ mpz(1) == -2);
+ok (~ mpz(-2) == 1);
+ok (~ mpz(0xFF) == -0x100);
+ok (~ mpz(-0x100) == 0xFF);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_dec
+
+{ my $a = mpz(0); ok ($a-- == 0); ok ($a == -1); }
+{ my $a = mpz(0); ok (--$a == -1); }
+
+{ my $a = mpz(0); my $b = $a; $a--; ok ($a == -1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_div
+
+ok (mpz(6) / 2 == 3);
+ok (mpz(-6) / 2 == -3);
+ok (mpz(6) / -2 == -3);
+ok (mpz(-6) / -2 == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_diveq
+
+{ my $a = mpz(21); $a /= 3; ok ($a == 7); }
+{ my $a = mpz(21); my $b = $a; $a /= 3; ok ($a == 7); ok ($b == 21); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_eq
+
+{ my $a = mpz(0);
+ my $b = $a;
+ $a = mpz(1);
+ ok ($a == 1);
+ ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_inc
+
+{ my $a = mpz(0); ok ($a++ == 0); ok ($a == 1); }
+{ my $a = mpz(0); ok (++$a == 1); }
+
+{ my $a = mpz(0); my $b = $a; $a++; ok ($a == 1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_ior
+
+ok ((mpz(3) | 1) == 3);
+ok ((mpz(3) | 4) == 7);
+
+{ my $a = mpz(3); $a |= 1; ok ($a == 3); }
+{ my $a = mpz(3); $a |= 4; ok ($a == 7); }
+
+ok ((mpz("0xAA") | mpz("0x55")) == mpz("0xFF"));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_lshift
+
+{ my $a = mpz(7) << 1; ok ($a == 14); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_lshifteq
+
+{ my $a = mpz(7); $a <<= 1; ok ($a == 14); }
+{ my $a = mpz(7); my $b = $a; $a <<= 1; ok ($a == 14); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_mul
+
+ok (mpz(2) * 3 == 6);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_muleq
+
+{ my $a = mpz(7); $a *= 3; ok ($a == 21); }
+{ my $a = mpz(7); my $b = $a; $a *= 3; ok ($a == 21); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_neg
+
+ok (- mpz(0) == 0);
+ok (- mpz(123) == -123);
+ok (- mpz(-123) == 123);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_not
+
+if (not mpz(0)) { ok (1); } else { ok (0); }
+if (not mpz(123)) { ok (0); } else { ok (1); }
+
+ok ((! mpz(0)) == 1);
+ok ((! mpz(123)) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_pow
+
+ok (mpz(0) ** 1 == 0);
+ok (mpz(1) ** 1 == 1);
+ok (mpz(2) ** 0 == 1);
+ok (mpz(2) ** 1 == 2);
+ok (mpz(2) ** 2 == 4);
+ok (mpz(2) ** 3 == 8);
+ok (mpz(2) ** 4 == 16);
+
+ok (mpz(0) ** mpz(1) == 0);
+ok (mpz(1) ** mpz(1) == 1);
+ok (mpz(2) ** mpz(0) == 1);
+ok (mpz(2) ** mpz(1) == 2);
+ok (mpz(2) ** mpz(2) == 4);
+ok (mpz(2) ** mpz(3) == 8);
+ok (mpz(2) ** mpz(4) == 16);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_poweq
+
+{ my $a = mpz(3); $a **= 4; ok ($a == 81); }
+{ my $a = mpz(3); my $b = $a; $a **= 4; ok ($a == 81); ok ($b == 3); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_rem
+
+ok (mpz(-8) % 3 == -2);
+ok (mpz(-7) % 3 == -1);
+ok (mpz(-6) % 3 == 0);
+ok (mpz(6) % 3 == 0);
+ok (mpz(7) % 3 == 1);
+ok (mpz(8) % 3 == 2);
+
+{ my $a = mpz(24); $a %= 7; ok ($a == 3); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_rshift
+
+{ my $a = mpz(32) >> 1; ok ($a == 16); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_rshifteq
+
+{ my $a = mpz(32); $a >>= 1; ok ($a == 16); }
+{ my $a = mpz(32); my $b = $a; $a >>= 1; ok ($a == 16); ok ($b == 32); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_spaceship
+
+ok (mpz(0) < 1);
+ok (mpz(0) > -1);
+
+ok (mpz(0) != 1);
+ok (mpz(0) != -1);
+ok (mpz(1) != 0);
+ok (mpz(1) != -1);
+ok (mpz(-1) != 0);
+ok (mpz(-1) != 1);
+
+ok (mpz(0) < 1.0);
+ok (mpz(0) < '1');
+ok (mpz(0) < substr('-1',1,1));
+ok (mpz(0) < mpz(1));
+ok (mpz(0) < mpq(1));
+ok (mpz(0) < mpf(1));
+ok (mpz(0) < $uv_max);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_sqrt
+
+ok (sqrt(mpz(0)) == 0);
+ok (sqrt(mpz(1)) == 1);
+ok (sqrt(mpz(4)) == 2);
+ok (sqrt(mpz(81)) == 9);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_string
+
+{ my $x = mpz(0); ok("$x" eq "0"); }
+{ my $x = mpz(123); ok("$x" eq "123"); }
+{ my $x = mpz(-123); ok("$x" eq "-123"); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_sub
+
+ok (mpz(0) - 1 == -1);
+ok (mpz(1) - 1 == 0);
+ok (1 - mpz(0) == 1);
+ok (1 - mpz(1) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_subeq
+
+{ my $a = mpz(7); $a -= 1; ok ($a == 6); }
+{ my $a = mpz(7); my $b = $a; $a -= 1; ok ($a == 6); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_xor
+
+ok ((mpz(3) ^ 1) == 2);
+ok ((mpz(3) ^ 4) == 7);
+
+{ my $a = mpz(3); $a ^= 1; ok ($a == 2); }
+{ my $a = mpz(3); $a ^= 4; ok ($a == 7); }
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::bin
+
+ok (bin(2,0) == 1);
+ok (bin(2,1) == 2);
+ok (bin(2,2) == 1);
+
+ok (bin(3,0) == 1);
+ok (bin(3,1) == 3);
+ok (bin(3,2) == 3);
+ok (bin(3,3) == 1);
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::cdiv
+
+{ my ($q, $r);
+ ($q, $r) = cdiv (16, 3);
+ ok ($q == 6);
+ ok ($r == -2);
+ ($q, $r) = cdiv (16, -3);
+ ok ($q == -5);
+ ok ($r == 1);
+ ($q, $r) = cdiv (-16, 3);
+ ok ($q == -5);
+ ok ($r == -1);
+ ($q, $r) = cdiv (-16, -3);
+ ok ($q == 6);
+ ok ($r == 2);
+}
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::cdiv_2exp
+
+{ my ($q, $r);
+ ($q, $r) = cdiv_2exp (23, 2);
+ ok ($q == 6);
+ ok ($r == -1);
+ ($q, $r) = cdiv_2exp (-23, 2);
+ ok ($q == -5);
+ ok ($r == -3);
+}
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::clrbit
+
+{ my $a = mpz(3); clrbit ($a, 1); ok ($a == 1);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+{ my $a = mpz(3); clrbit ($a, 2); ok ($a == 3);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+
+{ my $a = 3; clrbit ($a, 1); ok ($a == 1);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+{ my $a = 3; clrbit ($a, 2); ok ($a == 3);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+
+# mutate only given variable
+{ my $a = mpz(3);
+ my $b = $a;
+ clrbit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+}
+{ my $a = 3;
+ my $b = $a;
+ clrbit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+}
+
+{ tie my $a, 'Mytie', mpz(3);
+ clrbit ($a, 1);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 1); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+{ tie my $a, 'Mytie', 3;
+ clrbit ($a, 1);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 1); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+
+{ my $b = mpz(3);
+ tie my $a, 'Mytie', $b;
+ clrbit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+ ok (tied($a));
+}
+{ my $b = 3;
+ tie my $a, 'Mytie', $b;
+ clrbit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+ ok (tied($a));
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::combit
+
+{ my $a = mpz(3); combit ($a, 1); ok ($a == 1);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+{ my $a = mpz(3); combit ($a, 2); ok ($a == 7);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+
+{ my $a = 3; combit ($a, 1); ok ($a == 1);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+{ my $a = 3; combit ($a, 2); ok ($a == 7);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+
+# mutate only given variable
+{ my $a = mpz(3);
+ my $b = $a;
+ combit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+}
+{ my $a = 3;
+ my $b = $a;
+ combit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+}
+
+{ tie my $a, 'Mytie', mpz(3);
+ combit ($a, 2);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 7); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+{ tie my $a, 'Mytie', 3;
+ combit ($a, 2);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 7); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+
+{ my $b = mpz(3);
+ tie my $a, 'Mytie', $b;
+ combit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+ ok (tied($a));
+}
+{ my $b = 3;
+ tie my $a, 'Mytie', $b;
+ combit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+ ok (tied($a));
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::congruent_p
+
+ok ( congruent_p (21, 0, 7));
+ok (! congruent_p (21, 1, 7));
+ok ( congruent_p (21, 5, 8));
+ok (! congruent_p (21, 6, 8));
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::congruent_2exp_p
+
+ok ( congruent_2exp_p (20, 0, 2));
+ok (! congruent_2exp_p (21, 0, 2));
+ok (! congruent_2exp_p (20, 1, 2));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::divexact
+
+ok (divexact(27,3) == 9);
+ok (divexact(27,-3) == -9);
+ok (divexact(-27,3) == -9);
+ok (divexact(-27,-3) == 9);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::divisible_p
+
+ok ( divisible_p (21, 7));
+ok (! divisible_p (21, 8));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::divisible_2exp_p
+
+ok ( divisible_2exp_p (20, 2));
+ok (! divisible_2exp_p (21, 2));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::even_p
+
+ok (! even_p(mpz(-3)));
+ok ( even_p(mpz(-2)));
+ok (! even_p(mpz(-1)));
+ok ( even_p(mpz(0)));
+ok (! even_p(mpz(1)));
+ok ( even_p(mpz(2)));
+ok (! even_p(mpz(3)));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::export
+
+{ my $s = mpz_export (1, 2, 1, 0, "0x61626364");
+ ok ($s eq 'abcd'); }
+{ my $s = mpz_export (-1, 2, 1, 0, "0x61626364");
+ ok ($s eq 'cdab'); }
+{ my $s = mpz_export (1, 2, -1, 0, "0x61626364");
+ ok ($s eq 'badc'); }
+{ my $s = mpz_export (-1, 2, -1, 0, "0x61626364");
+ ok ($s eq 'dcba'); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::fac
+
+ok (fac(0) == 1);
+ok (fac(1) == 1);
+ok (fac(2) == 2);
+ok (fac(3) == 6);
+ok (fac(4) == 24);
+ok (fac(5) == 120);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::fdiv
+
+{ my ($q, $r);
+ ($q, $r) = fdiv (16, 3);
+ ok ($q == 5);
+ ok ($r == 1);
+ ($q, $r) = fdiv (16, -3);
+ ok ($q == -6);
+ ok ($r == -2);
+ ($q, $r) = fdiv (-16, 3);
+ ok ($q == -6);
+ ok ($r == 2);
+ ($q, $r) = fdiv (-16, -3);
+ ok ($q == 5);
+ ok ($r == -1);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::fdiv_2exp
+
+{ my ($q, $r);
+ ($q, $r) = fdiv_2exp (23, 2);
+ ok ($q == 5);
+ ok ($r == 3);
+ ($q, $r) = fdiv_2exp (-23, 2);
+ ok ($q == -6);
+ ok ($r == 1);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::fib
+
+ok (fib(0) == 0);
+ok (fib(1) == 1);
+ok (fib(2) == 1);
+ok (fib(3) == 2);
+ok (fib(4) == 3);
+ok (fib(5) == 5);
+ok (fib(6) == 8);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::fib2
+
+{ my ($a, $b) = fib2(0); ok($a==0); ok($b==1); }
+{ my ($a, $b) = fib2(1); ok($a==1); ok($b==0); }
+{ my ($a, $b) = fib2(2); ok($a==1); ok($b==1); }
+{ my ($a, $b) = fib2(3); ok($a==2); ok($b==1); }
+{ my ($a, $b) = fib2(4); ok($a==3); ok($b==2); }
+{ my ($a, $b) = fib2(5); ok($a==5); ok($b==3); }
+{ my ($a, $b) = fib2(6); ok($a==8); ok($b==5); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::gcd
+
+ok (gcd (21) == 21);
+ok (gcd (21,15) == 3);
+ok (gcd (21,15,30,57) == 3);
+ok (gcd (21,-15) == 3);
+ok (gcd (-21,15) == 3);
+ok (gcd (-21,-15) == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::gcdext
+
+{
+ my ($g, $x, $y) = gcdext (3,5);
+ ok ($g == 1);
+ ok ($x == 2);
+ ok ($y == -1);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::hamdist
+
+ok (hamdist(5,7) == 1);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::import
+
+{ my $z = mpz_import (1, 2, 1, 0, 'abcd');
+ ok ($z == 0x61626364); }
+{ my $z = mpz_import (-1, 2, 1, 0, 'abcd');
+ ok ($z == 0x63646162); }
+{ my $z = mpz_import (1, 2, -1, 0, 'abcd');
+ ok ($z == 0x62616463); }
+{ my $z = mpz_import (-1, 2, -1, 0, 'abcd');
+ ok ($z == 0x64636261); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::invert
+
+ok (invert(1,123) == 1);
+ok (invert(6,7) == 6);
+ok (! defined invert(2,8));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::jacobi, GMP::Mpz::kronecker
+
+foreach my $i ([ 1, 19, 1 ],
+ [ 4, 19, 1 ],
+ [ 5, 19, 1 ],
+ [ 6, 19, 1 ],
+ [ 7, 19, 1 ],
+ [ 9, 19, 1 ],
+ [ 11, 19, 1 ],
+ [ 16, 19, 1 ],
+ [ 17, 19, 1 ],
+ [ 2, 19, -1 ],
+ [ 3, 19, -1 ],
+ [ 8, 19, -1 ],
+ [ 10, 19, -1 ],
+ [ 12, 19, -1 ],
+ [ 13, 19, -1 ],
+ [ 14, 19, -1 ],
+ [ 15, 19, -1 ],
+ [ 18, 19, -1 ]) {
+ foreach my $fun (\&jacobi, \&kronecker) {
+ ok (&$fun ($$i[0], $$i[1]) == $$i[2]);
+
+ ok (&$fun ($$i[0], str($$i[1])) == $$i[2]);
+ ok (&$fun (str($$i[0]), $$i[1]) == $$i[2]);
+ ok (&$fun (str($$i[0]), str($$i[1])) == $$i[2]);
+
+ ok (&$fun ($$i[0], mpz($$i[1])) == $$i[2]);
+ ok (&$fun (mpz($$i[0]), $$i[1]) == $$i[2]);
+ ok (&$fun (mpz($$i[0]), mpz($$i[1])) == $$i[2]);
+ }
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::lcm
+
+ok (lcm (2) == 2);
+ok (lcm (0) == 0);
+ok (lcm (0,0) == 0);
+ok (lcm (0,0,0) == 0);
+ok (lcm (0,0,0,0) == 0);
+ok (lcm (2,0) == 0);
+ok (lcm (-2,0) == 0);
+ok (lcm (2,3) == 6);
+ok (lcm (2,3,4) == 12);
+ok (lcm (2,-3) == 6);
+ok (lcm (-2,3) == 6);
+ok (lcm (-2,-3) == 6);
+ok (lcm (mpz(2)**512,1) == mpz(2)**512);
+ok (lcm (mpz(2)**512,-1) == mpz(2)**512);
+ok (lcm (-mpz(2)**512,1) == mpz(2)**512);
+ok (lcm (-mpz(2)**512,-1) == mpz(2)**512);
+ok (lcm (mpz(2)**512,mpz(2)**512) == mpz(2)**512);
+ok (lcm (mpz(2)**512,-mpz(2)**512) == mpz(2)**512);
+ok (lcm (-mpz(2)**512,mpz(2)**512) == mpz(2)**512);
+ok (lcm (-mpz(2)**512,-mpz(2)**512) == mpz(2)**512);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::lucnum
+
+ok (lucnum(0) == 2);
+ok (lucnum(1) == 1);
+ok (lucnum(2) == 3);
+ok (lucnum(3) == 4);
+ok (lucnum(4) == 7);
+ok (lucnum(5) == 11);
+ok (lucnum(6) == 18);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::lucnum2
+
+{ my ($a, $b) = lucnum2(0); ok($a==2); ok($b==-1); }
+{ my ($a, $b) = lucnum2(1); ok($a==1); ok($b==2); }
+{ my ($a, $b) = lucnum2(2); ok($a==3); ok($b==1); }
+{ my ($a, $b) = lucnum2(3); ok($a==4); ok($b==3); }
+{ my ($a, $b) = lucnum2(4); ok($a==7); ok($b==4); }
+{ my ($a, $b) = lucnum2(5); ok($a==11); ok($b==7); }
+{ my ($a, $b) = lucnum2(6); ok($a==18); ok($b==11); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::nextprime
+
+ok (nextprime(2) == 3);
+ok (nextprime(3) == 5);
+ok (nextprime(5) == 7);
+ok (nextprime(7) == 11);
+ok (nextprime(11) == 13);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::perfect_power_p
+
+# ok ( perfect_power_p(mpz(-27)));
+# ok (! perfect_power_p(mpz(-9)));
+# ok (! perfect_power_p(mpz(-1)));
+ok ( perfect_power_p(mpz(0)));
+ok ( perfect_power_p(mpz(1)));
+ok (! perfect_power_p(mpz(2)));
+ok (! perfect_power_p(mpz(3)));
+ok ( perfect_power_p(mpz(4)));
+ok ( perfect_power_p(mpz(9)));
+ok ( perfect_power_p(mpz(27)));
+ok ( perfect_power_p(mpz(81)));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::perfect_square_p
+
+ok (! perfect_square_p(mpz(-9)));
+ok (! perfect_square_p(mpz(-1)));
+ok ( perfect_square_p(mpz(0)));
+ok ( perfect_square_p(mpz(1)));
+ok (! perfect_square_p(mpz(2)));
+ok (! perfect_square_p(mpz(3)));
+ok ( perfect_square_p(mpz(4)));
+ok ( perfect_square_p(mpz(9)));
+ok (! perfect_square_p(mpz(27)));
+ok ( perfect_square_p(mpz(81)));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::popcount
+
+ok (popcount(7) == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::powm
+
+ok (powm (3,2,8) == 1);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::probab_prime_p
+
+ok ( probab_prime_p(89,1));
+ok (! probab_prime_p(81,1));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::realloc
+
+{ my $z = mpz(123);
+ realloc ($z, 512); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::remove
+
+{
+ my ($rem, $mult);
+ ($rem, $mult) = remove(12,3);
+ ok ($rem == 4);
+ ok ($mult == 1);
+ ($rem, $mult) = remove(12,2);
+ ok ($rem == 3);
+ ok ($mult == 2);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::root
+
+ok (root(0,2) == 0);
+ok (root(8,3) == 2);
+ok (root(-8,3) == -2);
+ok (root(81,4) == 3);
+ok (root(243,5) == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::roote
+
+{ my ($r,$e);
+ ($r, $e) = roote(0,2);
+ ok ($r == 0);
+ ok ($e);
+ ($r, $e) = roote(81,4);
+ ok ($r == 3);
+ ok ($e);
+ ($r, $e) = roote(85,4);
+ ok ($r == 3);
+ ok (! $e);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::rootrem
+
+{ my ($root, $rem) = rootrem (mpz(0), 1);
+ ok ($root == 0); ok ($rem == 0); }
+{ my ($root, $rem) = rootrem (mpz(0), 2);
+ ok ($root == 0); ok ($rem == 0); }
+{ my ($root, $rem) = rootrem (mpz(64), 2);
+ ok ($root == 8); ok ($rem == 0); }
+{ my ($root, $rem) = rootrem (mpz(64), 3);
+ ok ($root == 4); ok ($rem == 0); }
+{ my ($root, $rem) = rootrem (mpz(65), 3);
+ ok ($root == 4); ok ($rem == 1); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::scan0
+
+ok (scan0 (0, 0) == 0);
+ok (scan0 (1, 0) == 1);
+ok (scan0 (3, 0) == 2);
+ok (scan0 (-1, 0) == ~0);
+ok (scan0 (-2, 1) == ~0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::scan1
+
+ok (scan1 (1, 0) == 0);
+ok (scan1 (2, 0) == 1);
+ok (scan1 (4, 0) == 2);
+ok (scan1 (0, 0) == ~0);
+ok (scan1 (3, 2) == ~0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::setbit
+
+{ my $a = mpz(3); setbit ($a, 1); ok ($a == 3); }
+{ my $a = mpz(3); setbit ($a, 2); ok ($a == 7); }
+
+{ my $a = 3; setbit ($a, 1); ok ($a == 3); }
+{ my $a = 3; setbit ($a, 2); ok ($a == 7); }
+
+# mutate only given variable
+{ my $a = mpz(0);
+ my $b = $a;
+ setbit ($a, 0);
+ ok ($a == 1);
+ ok ($b == 0);
+}
+{ my $a = 0;
+ my $b = $a;
+ setbit ($a, 0);
+ ok ($a == 1);
+ ok ($b == 0);
+}
+
+{ tie my $a, 'Mytie', mpz(3);
+ setbit ($a, 2);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 7); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+{ tie my $a, 'Mytie', 3;
+ setbit ($a, 2);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 7); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+
+{ my $b = mpz(2);
+ tie my $a, 'Mytie', $b;
+ setbit ($a, 0);
+ ok ($a == 3);
+ ok ($b == 2);
+ ok (tied($a));
+}
+{ my $b = 2;
+ tie my $a, 'Mytie', $b;
+ setbit ($a, 0);
+ ok ($a == 3);
+ ok ($b == 2);
+ ok (tied($a));
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::sizeinbase
+
+ok (sizeinbase(1,10) == 1);
+ok (sizeinbase(100,10) == 3);
+ok (sizeinbase(9999,10) == 5);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::sqrtrem
+
+{
+ my ($root, $rem) = sqrtrem(mpz(0));
+ ok ($root == 0);
+ ok ($rem == 0);
+}
+{
+ my ($root, $rem) = sqrtrem(mpz(1));
+ ok ($root == 1);
+ ok ($rem == 0);
+}
+{
+ my ($root, $rem) = sqrtrem(mpz(2));
+ ok ($root == 1);
+ ok ($rem == 1);
+}
+{
+ my ($root, $rem) = sqrtrem(mpz(9));
+ ok ($root == 3);
+ ok ($rem == 0);
+}
+{
+ my ($root, $rem) = sqrtrem(mpz(35));
+ ok ($root == 5);
+ ok ($rem == 10);
+}
+{
+ my ($root, $rem) = sqrtrem(mpz(0));
+ ok ($root == 0);
+ ok ($rem == 0);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::tdiv
+
+{ my ($q, $r);
+ ($q, $r) = tdiv (16, 3);
+ ok ($q == 5);
+ ok ($r == 1);
+ ($q, $r) = tdiv (16, -3);
+ ok ($q == -5);
+ ok ($r == 1);
+ ($q, $r) = tdiv (-16, 3);
+ ok ($q == -5);
+ ok ($r == -1);
+ ($q, $r) = tdiv (-16, -3);
+ ok ($q == 5);
+ ok ($r == -1);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::tdiv_2exp
+
+{ my ($q, $r);
+ ($q, $r) = tdiv_2exp (23, 2);
+ ok ($q == 5);
+ ok ($r == 3);
+ ($q, $r) = tdiv_2exp (-23, 2);
+ ok ($q == -5);
+ ok ($r == -3);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::tstbit
+
+ok (tstbit (6, 0) == 0);
+ok (tstbit (6, 1) == 1);
+ok (tstbit (6, 2) == 1);
+ok (tstbit (6, 3) == 0);
+
+
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpq
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::new
+
+ok (mpq(0) == 0);
+ok (mpq('0') == 0);
+ok (mpq(substr('101',1,1)) == 0);
+ok (mpq(0.0) == 0);
+ok (mpq(mpz(0)) == 0);
+ok (mpq(mpq(0)) == 0);
+ok (mpq(mpf(0)) == 0);
+
+{ tie my $t, 'Mytie', 0; ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', '0'; ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', substr('101',1,1); ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', 0.0; ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', mpz(0); ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', mpq(0); ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', mpf(0); ok (mpq($t) == 0); }
+
+ok (mpq(-123) == -123);
+ok (mpq('-123') == -123);
+ok (mpq(substr('1-1231',1,4)) == -123);
+ok (mpq(-123.0) == -123);
+ok (mpq(mpz(-123)) == -123);
+ok (mpq(mpq(-123)) == -123);
+ok (mpq(mpf(-123)) == -123);
+
+{ tie my $t, 'Mytie', -123; ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', '-123'; ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', substr('1-1231',1,4); ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', -123.0; ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', mpz(-123); ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', mpq(-123); ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', mpf(-123); ok (mpq($t) == -123); }
+
+ok (mpq($ivnv_2p128) == $str_2p128);
+{ tie my $t, 'Mytie', $ivnv_2p128; ok (mpq($t) == $str_2p128); }
+
+ok (mpq('3/2') == mpq(3,2));
+ok (mpq('3/1') == mpq(3,1));
+ok (mpq('-3/2') == mpq(-3,2));
+ok (mpq('-3/1') == mpq(-3,1));
+ok (mpq('0x3') == mpq(3,1));
+ok (mpq('0b111') == mpq(7,1));
+ok (mpq('0b0') == mpq(0,1));
+
+ok (mpq($uv_max) > 0);
+ok (mpq($uv_max) == mpq($uv_max_str));
+{ tie my $t, 'Mytie', $uv_max; ok (mpq($t) > 0); }
+{ tie my $t, 'Mytie', $uv_max; ok (mpq($t) == mpq($uv_max_str)); }
+
+{ my $x = 123.5;
+ kill (0, $x);
+ ok (mpq($x) == 123.5);
+ tie my $t, 'Mytie', $x;
+ ok (mpq($t) == 123.5);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_abs
+
+ok (abs(mpq(0)) == 0);
+ok (abs(mpq(123)) == 123);
+ok (abs(mpq(-123)) == 123);
+
+{ my $x = mpq(-123); $x = abs($x); ok ($x == 123); }
+{ my $x = mpq(0); $x = abs($x); ok ($x == 0); }
+{ my $x = mpq(123); $x = abs($x); ok ($x == 123); }
+
+{ tie my $t, 'Mytie', mpq(0); ok (abs($t) == 0); }
+{ tie my $t, 'Mytie', mpq(123); ok (abs($t) == 123); }
+{ tie my $t, 'Mytie', mpq(-123); ok (abs($t) == 123); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_add
+
+ok (mpq(0) + 1 == 1);
+ok (mpq(-1) + 1 == 0);
+ok (1 + mpq(0) == 1);
+ok (1 + mpq(-1) == 0);
+
+ok (mpq(1,2)+mpq(1,3) == mpq(5,6));
+ok (mpq(1,2)+mpq(-1,3) == mpq(1,6));
+ok (mpq(-1,2)+mpq(1,3) == mpq(-1,6));
+ok (mpq(-1,2)+mpq(-1,3) == mpq(-5,6));
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_addeq
+
+{ my $a = mpq(7); $a += 1; ok ($a == 8); }
+{ my $a = mpq(7); my $b = $a; $a += 1; ok ($a == 8); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_bool
+
+if (mpq(0)) { ok (0); } else { ok (1); }
+if (mpq(123)) { ok (1); } else { ok (0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_dec
+
+{ my $a = mpq(0); ok ($a-- == 0); ok ($a == -1); }
+{ my $a = mpq(0); ok (--$a == -1); }
+
+{ my $a = mpq(0); my $b = $a; $a--; ok ($a == -1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_div
+
+ok (mpq(6) / 2 == 3);
+ok (mpq(-6) / 2 == -3);
+ok (mpq(6) / -2 == -3);
+ok (mpq(-6) / -2 == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_diveq
+
+{ my $a = mpq(21); $a /= 3; ok ($a == 7); }
+{ my $a = mpq(21); my $b = $a; $a /= 3; ok ($a == 7); ok ($b == 21); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_eq
+
+{ my $a = mpq(0);
+ my $b = $a;
+ $a = mpq(1);
+ ok ($a == 1);
+ ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_inc
+
+{ my $a = mpq(0); ok ($a++ == 0); ok ($a == 1); }
+{ my $a = mpq(0); ok (++$a == 1); }
+
+{ my $a = mpq(0); my $b = $a; $a++; ok ($a == 1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_lshift
+
+{ my $a = mpq(7) << 1; ok ($a == 14); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_lshifteq
+
+{ my $a = mpq(7); $a <<= 1; ok ($a == 14); }
+{ my $a = mpq(7); my $b = $a; $a <<= 1; ok ($a == 14); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_mul
+
+ok (mpq(2) * 3 == 6);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_muleq
+
+{ my $a = mpq(7); $a *= 3; ok ($a == 21); }
+{ my $a = mpq(7); my $b = $a; $a *= 3; ok ($a == 21); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_neg
+
+ok (- mpq(0) == 0);
+ok (- mpq(123) == -123);
+ok (- mpq(-123) == 123);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_not
+
+if (not mpq(0)) { ok (1); } else { ok (0); }
+if (not mpq(123)) { ok (0); } else { ok (1); }
+
+ok ((! mpq(0)) == 1);
+ok ((! mpq(123)) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_pow
+
+ok (mpq(0) ** 1 == 0);
+ok (mpq(1) ** 1 == 1);
+ok (mpq(2) ** 0 == 1);
+ok (mpq(2) ** 1 == 2);
+ok (mpq(2) ** 2 == 4);
+ok (mpq(2) ** 3 == 8);
+ok (mpq(2) ** 4 == 16);
+
+ok (mpq(0) ** mpq(1) == 0);
+ok (mpq(1) ** mpq(1) == 1);
+ok (mpq(2) ** mpq(0) == 1);
+ok (mpq(2) ** mpq(1) == 2);
+ok (mpq(2) ** mpq(2) == 4);
+ok (mpq(2) ** mpq(3) == 8);
+ok (mpq(2) ** mpq(4) == 16);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_poweq
+
+{ my $a = mpq(3); $a **= 4; ok ($a == 81); }
+{ my $a = mpq(3); my $b = $a; $a **= 4; ok ($a == 81); ok ($b == 3); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_rshift
+
+{ my $a = mpq(32) >> 1; ok ($a == 16); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_rshifteq
+
+{ my $a = mpq(32); $a >>= 1; ok ($a == 16); }
+{ my $a = mpq(32); my $b = $a; $a >>= 1; ok ($a == 16); ok ($b == 32); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_spaceship
+
+ok (mpq(0) < 1);
+ok (mpq(0) > -1);
+
+ok (mpq(0) != 1);
+ok (mpq(0) != -1);
+ok (mpq(1) != 0);
+ok (mpq(1) != -1);
+ok (mpq(-1) != 0);
+ok (mpq(-1) != 1);
+
+ok (mpq(3,2) > 1);
+ok (mpq(3,2) < 2);
+
+ok (mpq(0) < 1.0);
+ok (mpq(0) < '1');
+ok (mpq(0) < substr('-1',1,1));
+ok (mpq(0) < mpz(1));
+ok (mpq(0) < mpq(1));
+ok (mpq(0) < mpf(1));
+ok (mpq(0) < $uv_max);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_string
+
+{ my $x = mpq(0); ok("$x" eq "0"); }
+{ my $x = mpq(123); ok("$x" eq "123"); }
+{ my $x = mpq(-123); ok("$x" eq "-123"); }
+
+{ my $q = mpq(5,7); ok("$q" eq "5/7"); }
+{ my $q = mpq(-5,7); ok("$q" eq "-5/7"); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_sub
+
+ok (mpq(0) - 1 == -1);
+ok (mpq(1) - 1 == 0);
+ok (1 - mpq(0) == 1);
+ok (1 - mpq(1) == 0);
+
+ok (mpq(1,2)-mpq(1,3) == mpq(1,6));
+ok (mpq(1,2)-mpq(-1,3) == mpq(5,6));
+ok (mpq(-1,2)-mpq(1,3) == mpq(-5,6));
+ok (mpq(-1,2)-mpq(-1,3) == mpq(-1,6));
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_subeq
+
+{ my $a = mpq(7); $a -= 1; ok ($a == 6); }
+{ my $a = mpq(7); my $b = $a; $a -= 1; ok ($a == 6); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::canonicalize
+
+{ my $q = mpq(21,15); canonicalize($q);
+ ok (num($q) == 7);
+ ok (den($q) == 5);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::den
+
+{ my $q = mpq(5,9); ok (den($q) == 9); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::num
+
+{ my $q = mpq(5,9); ok (num($q) == 5); }
+
+
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpf
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::new
+
+ok (mpf(0) == 0);
+ok (mpf('0') == 0);
+ok (mpf(substr('101',1,1)) == 0);
+ok (mpf(0.0) == 0);
+ok (mpf(mpz(0)) == 0);
+ok (mpf(mpq(0)) == 0);
+ok (mpf(mpf(0)) == 0);
+
+{ tie my $t, 'Mytie', 0; ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', '0'; ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', substr('101',1,1); ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', 0.0; ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', mpz(0); ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', mpq(0); ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', mpf(0); ok (mpf($t) == 0); }
+
+ok (mpf(-123) == -123);
+ok (mpf('-123') == -123);
+ok (mpf(substr('1-1231',1,4)) == -123);
+ok (mpf(-123.0) == -123);
+ok (mpf(mpz(-123)) == -123);
+ok (mpf(mpq(-123)) == -123);
+ok (mpf(mpf(-123)) == -123);
+
+{ tie my $t, 'Mytie', -123; ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', '-123'; ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', substr('1-1231',1,4); ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', -123.0; ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', mpz(-123); ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', mpq(-123); ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', mpf(-123); ok (mpf($t) == -123); }
+
+ok (mpf($ivnv_2p128) == $str_2p128);
+{ tie my $t, 'Mytie', $ivnv_2p128; ok (mpf($t) == $str_2p128); }
+
+ok (mpf(-1.5) == -1.5);
+ok (mpf(-1.0) == -1.0);
+ok (mpf(-0.5) == -0.5);
+ok (mpf(0) == 0);
+ok (mpf(0.5) == 0.5);
+ok (mpf(1.0) == 1.0);
+ok (mpf(1.5) == 1.5);
+
+ok (mpf("-1.5") == -1.5);
+ok (mpf("-1.0") == -1.0);
+ok (mpf("-0.5") == -0.5);
+ok (mpf("0") == 0);
+ok (mpf("0.5") == 0.5);
+ok (mpf("1.0") == 1.0);
+ok (mpf("1.5") == 1.5);
+
+ok (mpf($uv_max) > 0);
+ok (mpf($uv_max) == mpf($uv_max_str));
+{ tie my $t, 'Mytie', $uv_max; ok (mpf($t) > 0); }
+{ tie my $t, 'Mytie', $uv_max; ok (mpf($t) == mpf($uv_max_str)); }
+
+{ my $x = 123.5;
+ kill (0, $x);
+ ok (mpf($x) == 123.5);
+ tie my $t, 'Mytie', $x;
+ ok (mpf($t) == 123.5);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_abs
+
+ok (abs(mpf(0)) == 0);
+ok (abs(mpf(123)) == 123);
+ok (abs(mpf(-123)) == 123);
+
+{ my $x = mpf(-123); $x = abs($x); ok ($x == 123); }
+{ my $x = mpf(0); $x = abs($x); ok ($x == 0); }
+{ my $x = mpf(123); $x = abs($x); ok ($x == 123); }
+
+{ tie my $t, 'Mytie', mpf(0); ok (abs($t) == 0); }
+{ tie my $t, 'Mytie', mpf(123); ok (abs($t) == 123); }
+{ tie my $t, 'Mytie', mpf(-123); ok (abs($t) == 123); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_add
+
+ok (mpf(0) + 1 == 1);
+ok (mpf(-1) + 1 == 0);
+ok (1 + mpf(0) == 1);
+ok (1 + mpf(-1) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_addeq
+
+{ my $a = mpf(7); $a += 1; ok ($a == 8); }
+{ my $a = mpf(7); my $b = $a; $a += 1; ok ($a == 8); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_bool
+
+if (mpf(0)) { ok (0); } else { ok (1); }
+if (mpf(123)) { ok (1); } else { ok (0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_dec
+
+{ my $a = mpf(0); ok ($a-- == 0); ok ($a == -1); }
+{ my $a = mpf(0); ok (--$a == -1); }
+
+{ my $a = mpf(0); my $b = $a; $a--; ok ($a == -1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_div
+
+ok (mpf(6) / 2 == 3);
+ok (mpf(-6) / 2 == -3);
+ok (mpf(6) / -2 == -3);
+ok (mpf(-6) / -2 == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_diveq
+
+{ my $a = mpf(21); $a /= 3; ok ($a == 7); }
+{ my $a = mpf(21); my $b = $a; $a /= 3; ok ($a == 7); ok ($b == 21); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_eq
+
+{ my $a = mpf(0);
+ my $b = $a;
+ $a = mpf(1);
+ ok ($a == 1);
+ ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_inc
+
+{ my $a = mpf(0); ok ($a++ == 0); ok ($a == 1); }
+{ my $a = mpf(0); ok (++$a == 1); }
+
+{ my $a = mpf(0); my $b = $a; $a++; ok ($a == 1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_lshift
+
+{ my $a = mpf(7) << 1; ok ($a == 14); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_lshifteq
+
+{ my $a = mpf(7); $a <<= 1; ok ($a == 14); }
+{ my $a = mpf(7); my $b = $a; $a <<= 1; ok ($a == 14); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_mul
+
+ok (mpf(2) * 3 == 6);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_muleq
+
+{ my $a = mpf(7); $a *= 3; ok ($a == 21); }
+{ my $a = mpf(7); my $b = $a; $a *= 3; ok ($a == 21); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_neg
+
+ok (- mpf(0) == 0);
+ok (- mpf(123) == -123);
+ok (- mpf(-123) == 123);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_not
+
+if (not mpf(0)) { ok (1); } else { ok (0); }
+if (not mpf(123)) { ok (0); } else { ok (1); }
+
+ok ((! mpf(0)) == 1);
+ok ((! mpf(123)) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_pow
+
+ok (mpf(0) ** 1 == 0);
+ok (mpf(1) ** 1 == 1);
+ok (mpf(2) ** 0 == 1);
+ok (mpf(2) ** 1 == 2);
+ok (mpf(2) ** 2 == 4);
+ok (mpf(2) ** 3 == 8);
+ok (mpf(2) ** 4 == 16);
+
+ok (mpf(0) ** mpf(1) == 0);
+ok (mpf(1) ** mpf(1) == 1);
+ok (mpf(2) ** mpf(0) == 1);
+ok (mpf(2) ** mpf(1) == 2);
+ok (mpf(2) ** mpf(2) == 4);
+ok (mpf(2) ** mpf(3) == 8);
+ok (mpf(2) ** mpf(4) == 16);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_poweq
+
+{ my $a = mpf(3); $a **= 4; ok ($a == 81); }
+{ my $a = mpf(3); my $b = $a; $a **= 4; ok ($a == 81); ok ($b == 3); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_rshift
+
+{ my $a = mpf(32) >> 1; ok ($a == 16); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_rshifteq
+
+{ my $a = mpf(32); $a >>= 1; ok ($a == 16); }
+{ my $a = mpf(32); my $b = $a; $a >>= 1; ok ($a == 16); ok ($b == 32); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_sqrt
+
+ok (sqrt(mpf(0)) == 0);
+ok (sqrt(mpf(1)) == 1);
+ok (sqrt(mpf(4)) == 2);
+ok (sqrt(mpf(81)) == 9);
+
+ok (sqrt(mpf(0.25)) == 0.5);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_spaceship
+
+ok (mpf(0) < 1);
+ok (mpf(0) > -1);
+
+ok (mpf(0) != 1);
+ok (mpf(0) != -1);
+ok (mpf(1) != 0);
+ok (mpf(1) != -1);
+ok (mpf(-1) != 0);
+ok (mpf(-1) != 1);
+
+ok (mpf(0) < 1.0);
+ok (mpf(0) < '1');
+ok (mpf(0) < substr('-1',1,1));
+ok (mpf(0) < mpz(1));
+ok (mpf(0) < mpq(1));
+ok (mpf(0) < mpf(1));
+ok (mpf(0) < $uv_max);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_string
+
+{ my $x = mpf(0); ok ("$x" eq "0"); }
+{ my $x = mpf(123); ok ("$x" eq "123"); }
+{ my $x = mpf(-123); ok ("$x" eq "-123"); }
+
+{ my $f = mpf(0.25); ok ("$f" eq "0.25"); }
+{ my $f = mpf(-0.25); ok ("$f" eq "-0.25"); }
+{ my $f = mpf(1.25); ok ("$f" eq "1.25"); }
+{ my $f = mpf(-1.25); ok ("$f" eq "-1.25"); }
+{ my $f = mpf(1000000); ok ("$f" eq "1000000"); }
+{ my $f = mpf(-1000000); ok ("$f" eq "-1000000"); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_sub
+
+ok (mpf(0) - 1 == -1);
+ok (mpf(1) - 1 == 0);
+ok (1 - mpf(0) == 1);
+ok (1 - mpf(1) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_subeq
+
+{ my $a = mpf(7); $a -= 1; ok ($a == 6); }
+{ my $a = mpf(7); my $b = $a; $a -= 1; ok ($a == 6); ok ($b == 7); }
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::ceil
+
+ok (ceil (mpf(-7.5)) == -7.0);
+ok (ceil (mpf(7.5)) == 8.0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::floor
+
+ok (floor(mpf(-7.5)) == -8.0);
+ok (floor(mpf(7.5)) == 7.0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::mpf_eq
+
+{ my $old_prec = get_default_prec();
+ set_default_prec(128);
+
+ ok ( mpf_eq (mpz("0x10000000000000001"), mpz("0x10000000000000002"), 1));
+ ok (! mpf_eq (mpz("0x11"), mpz("0x12"), 128));
+
+ set_default_prec($old_prec);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::get_default_prec
+
+get_default_prec();
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::get_prec
+
+{ my $x = mpf(1.0, 512);
+ ok (get_prec ($x) == 512);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::reldiff
+
+ok (reldiff (2,4) == 1);
+ok (reldiff (4,2) == 0.5);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::set_default_prec
+
+{ my $old_prec = get_default_prec();
+
+ set_default_prec(512);
+ ok (get_default_prec () == 512);
+
+ set_default_prec($old_prec);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::set_prec
+
+{ my $x = mpf(1.0, 512);
+ my $y = $x;
+ set_prec ($x, 1024);
+ ok (get_prec ($x) == 1024);
+ ok (get_prec ($y) == 512);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::trunc
+
+ok (trunc(mpf(-7.5)) == -7.0);
+ok (trunc(mpf(7.5)) == 7.0);
+
+
+
+#------------------------------------------------------------------------------
+# GMP::Rand
+
+#------------------------------------------------------------------------------
+# GMP::Rand::new
+
+{ my $r = randstate(); ok (defined $r); }
+{ my $r = randstate('lc_2exp', 1, 2, 3); ok (defined $r); }
+{ my $r = randstate('lc_2exp_size', 64); ok (defined $r); }
+{ my $r = randstate('lc_2exp_size', 999999999); ok (! defined $r); }
+{ my $r = randstate('mt'); ok (defined $r); }
+
+{ # copying a randstate results in same sequence
+ my $r1 = randstate('lc_2exp_size', 64);
+ $r1->seed(123);
+ my $r2 = randstate($r1);
+ for (1 .. 20) {
+ my $z1 = mpz_urandomb($r1, 20);
+ my $z2 = mpz_urandomb($r2, 20);
+ ok ($z1 == $z2);
+ }
+}
+
+#------------------------------------------------------------------------------
+# GMP::Rand::seed
+
+{ my $r = randstate();
+ $r->seed(123);
+ $r->seed(time());
+}
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpf_urandomb
+
+{ my $r = randstate();
+ my $f = mpf_urandomb($r,1024);
+ ok (UNIVERSAL::isa($f,"GMP::Mpf")); }
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpz_urandomb
+
+{ my $r = randstate();
+ my $z = mpz_urandomb($r, 1024);
+ ok (UNIVERSAL::isa($z,"GMP::Mpz")); }
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpz_rrandomb
+
+{ my $r = randstate();
+ my $z = mpz_rrandomb($r, 1024);
+ ok (UNIVERSAL::isa($z,"GMP::Mpz")); }
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpz_urandomm
+
+{ my $r = randstate();
+ my $z = mpz_urandomm($r, mpz(3)**100);
+ ok (UNIVERSAL::isa($z,"GMP::Mpz")); }
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpz_urandomb_ui
+
+{ my $r = randstate();
+ foreach (1 .. 20) {
+ my $u = gmp_urandomb_ui($r,8);
+ ok ($u >= 0);
+ ok ($u < 256);
+ }
+}
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpz_urandomm_ui
+
+{ my $r = randstate();
+ foreach (1 .. 20) {
+ my $u = gmp_urandomm_ui($r,8);
+ ok ($u >= 0);
+ ok ($u < 8);
+ }
+}
+
+
+
+
+#------------------------------------------------------------------------------
+# GMP module
+
+#------------------------------------------------------------------------------
+# GMP::fits_slong_p
+
+ok (GMP::fits_slong_p(0));
+
+# in perl 5.005 uv_max is only 32-bits on a 64-bit system, so won't exceed a
+# long
+# ok (! GMP::fits_slong_p($uv_max));
+
+ok (GMP::fits_slong_p(0.0));
+
+ok (GMP::fits_slong_p('0'));
+
+ok (GMP::fits_slong_p(substr('999999999999999999999999999999',1,1)));
+
+ok (! mpz("-9999999999999999999999999999999999999999999")->fits_slong_p());
+ok ( mpz(-123)->fits_slong_p());
+ok ( mpz(0)->fits_slong_p());
+ok ( mpz(123)->fits_slong_p());
+ok (! mpz("9999999999999999999999999999999999999999999")->fits_slong_p());
+
+ok (! mpq("-9999999999999999999999999999999999999999999")->fits_slong_p());
+ok ( mpq(-123)->fits_slong_p());
+ok ( mpq(0)->fits_slong_p());
+ok ( mpq(123)->fits_slong_p());
+ok (! mpq("9999999999999999999999999999999999999999999")->fits_slong_p());
+
+ok (! mpf("-9999999999999999999999999999999999999999999")->fits_slong_p());
+ok ( mpf(-123)->fits_slong_p());
+ok ( mpf(0)->fits_slong_p());
+ok ( mpf(123)->fits_slong_p());
+ok (! mpf("9999999999999999999999999999999999999999999")->fits_slong_p());
+
+#------------------------------------------------------------------------------
+# GMP::get_d
+
+ok (GMP::get_d(123) == 123.0);
+
+ok (GMP::get_d($uv_max) > 0);
+
+ok (GMP::get_d(123.0) == 123.0);
+
+ok (GMP::get_d('123') == 123.0);
+
+ok (GMP::get_d(mpz(123)) == 123.0);
+
+ok (GMP::get_d(mpq(123)) == 123.0);
+
+ok (GMP::get_d(mpf(123)) == 123.0);
+
+#------------------------------------------------------------------------------
+# GMP::get_d_2exp
+
+{ my ($dbl, $exp) = get_d_2exp (0);
+ ok ($dbl == 0); ok ($exp == 0); }
+{ my ($dbl, $exp) = get_d_2exp (1);
+ ok ($dbl == 0.5); ok ($exp == 1); }
+
+{ my ($dbl, $exp) = get_d_2exp ($uv_max);
+ ok ($dbl > 0.0); ok ($exp > 0); }
+
+{ my ($dbl, $exp) = get_d_2exp (0.5);
+ ok ($dbl == 0.5); ok ($exp == 0); }
+{ my ($dbl, $exp) = get_d_2exp (0.25);
+ ok ($dbl == 0.5); ok ($exp == -1); }
+
+{ my ($dbl, $exp) = get_d_2exp ("1.0");
+ ok ($dbl == 0.5); ok ($exp == 1); }
+
+{ my ($dbl, $exp) = get_d_2exp (mpz ("256"));
+ ok ($dbl == 0.5); ok ($exp == 9); }
+
+{ my ($dbl, $exp) = get_d_2exp (mpq ("1/16"));
+ ok ($dbl == 0.5); ok ($exp == -3); }
+
+{ my ($dbl, $exp) = get_d_2exp (mpf ("1.5"));
+ ok ($dbl == 0.75); ok ($exp == 1); }
+{ my ($dbl, $exp) = get_d_2exp (mpf ("3.0"));
+ ok ($dbl == 0.75); ok ($exp == 2); }
+
+#------------------------------------------------------------------------------
+# GMP::get_str
+
+ok (get_str(-123) eq '-123');
+ok (get_str('-123') eq '-123');
+ok (get_str(substr('x-123x',1,4)) eq '-123');
+ok (get_str(mpz(-123)) eq '-123');
+ok (get_str(mpq(-123)) eq '-123');
+
+ok (get_str(-123,10) eq '-123');
+ok (get_str('-123',10) eq '-123');
+ok (get_str(substr('x-123x',1,4),10) eq '-123');
+ok (get_str(mpz(-123),10) eq '-123');
+ok (get_str(mpq(-123),10) eq '-123');
+
+ok (get_str(-123,16) eq '-7b');
+ok (get_str('-123',16) eq '-7b');
+ok (get_str(substr('x-123x',1,4),16) eq '-7b');
+ok (get_str(mpz(-123),16) eq '-7b');
+ok (get_str(mpq(-123),16) eq '-7b');
+
+ok (get_str(-123,-16) eq '-7B');
+ok (get_str('-123',-16) eq '-7B');
+ok (get_str(substr('x-123x',1,4),-16) eq '-7B');
+ok (get_str(mpz(-123),-16) eq '-7B');
+ok (get_str(mpq(-123),-16) eq '-7B');
+
+# is a float in past versions of perl without UV type
+{ my ($str, $exp) = get_str($uv_max);
+ ok ($str eq $uv_max_str); }
+
+ok (get_str(mpq(5/8)) eq "5/8");
+ok (get_str(mpq(-5/8)) eq "-5/8");
+ok (get_str(mpq(255/256),16) eq "ff/100");
+ok (get_str(mpq(255/256),-16) eq "FF/100");
+ok (get_str(mpq(-255/256),16) eq "-ff/100");
+ok (get_str(mpq(-255/256),-16) eq "-FF/100");
+
+{ my ($s,$e) = get_str(1.5, 10); ok ($s eq '15'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(1.5), 10); ok ($s eq '15'); ok ($e == 1); }
+
+{ my ($s,$e) = get_str(-1.5, 10); ok ($s eq '-15'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(-1.5), 10); ok ($s eq '-15'); ok ($e == 1); }
+
+{ my ($s,$e) = get_str(1.5, 16); ok ($s eq '18'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(1.5), 16); ok ($s eq '18'); ok ($e == 1); }
+
+{ my ($s,$e) = get_str(-1.5, 16); ok ($s eq '-18'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(-1.5), 16); ok ($s eq '-18'); ok ($e == 1); }
+
+{ my ($s,$e) = get_str(65536.0, 16); ok ($s eq '1'); ok ($e == 5); }
+{ my ($s,$e) = get_str(mpf(65536.0), 16); ok ($s eq '1'); ok ($e == 5); }
+
+{ my ($s,$e) = get_str(1.625, 16); ok ($s eq '1a'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(1.625), 16); ok ($s eq '1a'); ok ($e == 1); }
+
+{ my ($s,$e) = get_str(1.625, -16); ok ($s eq '1A'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(1.625), -16); ok ($s eq '1A'); ok ($e == 1); }
+
+{ my ($s, $e) = get_str(255.0,16,0); ok ($s eq "ff"); ok ($e == 2); }
+{ my ($s, $e) = get_str(mpf(255.0),16,0); ok ($s eq "ff"); ok ($e == 2); }
+
+{ my ($s, $e) = get_str(255.0,-16,0); ok ($s eq "FF"); ok ($e == 2); }
+{ my ($s, $e) = get_str(mpf(255.0),-16,0); ok ($s eq "FF"); ok ($e == 2); }
+
+#------------------------------------------------------------------------------
+# GMP::get_si
+
+ok (GMP::get_si(123) == 123.0);
+
+# better not assume anything about the relatives sizes of long and UV
+ok (GMP::get_si($uv_max) != 0);
+
+ok (GMP::get_si(123.0) == 123.0);
+
+ok (GMP::get_si('123') == 123.0);
+
+ok (GMP::get_si(mpz(123)) == 123.0);
+
+ok (GMP::get_si(mpq(123)) == 123.0);
+
+ok (GMP::get_si(mpf(123)) == 123.0);
+
+#------------------------------------------------------------------------------
+# GMP::integer_p
+
+ok ( GMP::integer_p (0));
+ok ( GMP::integer_p (123));
+ok ( GMP::integer_p (-123));
+
+ok ( GMP::integer_p ($uv_max));
+
+ok ( GMP::integer_p (0.0));
+ok ( GMP::integer_p (123.0));
+ok ( GMP::integer_p (-123.0));
+ok (! GMP::integer_p (0.5));
+ok (! GMP::integer_p (123.5));
+ok (! GMP::integer_p (-123.5));
+
+ok ( GMP::integer_p ('0'));
+ok ( GMP::integer_p ('123'));
+ok ( GMP::integer_p ('-123'));
+ok (! GMP::integer_p ('0.5'));
+ok (! GMP::integer_p ('123.5'));
+ok (! GMP::integer_p ('-123.5'));
+ok (! GMP::integer_p ('5/8'));
+
+ok ( GMP::integer_p (mpz(1)));
+
+ok ( GMP::integer_p (mpq(1)));
+ok (! GMP::integer_p (mpq(1,2)));
+
+ok ( GMP::integer_p (mpf(1.0)));
+ok (! GMP::integer_p (mpf(1.5)));
+
+#------------------------------------------------------------------------------
+# GMP::odd_p
+
+ok (! odd_p(0));
+ok ( odd_p(1));
+ok (! odd_p(2));
+
+ok ( odd_p($uv_max));
+
+ok ( odd_p(mpz(-3)));
+ok (! odd_p(mpz(-2)));
+ok ( odd_p(mpz(-1)));
+ok (! odd_p(mpz(0)));
+ok ( odd_p(mpz(1)));
+ok (! odd_p(mpz(2)));
+ok ( odd_p(mpz(3)));
+
+#------------------------------------------------------------------------------
+# GMP::printf
+
+GMP::printf ("hello world\n");
+
+sub via_printf {
+ my $s;
+ open TEMP, ">test.tmp" or die;
+ GMP::printf TEMP @_;
+ close TEMP or die;
+ open TEMP, "<test.tmp" or die;
+ read (TEMP, $s, 1024);
+ close TEMP or die;
+ unlink 'test.tmp';
+ return $s;
+}
+
+ok (sprintf ("%d", mpz(123)) eq '123');
+ok (sprintf ("%d %d %d", 456, mpz(123), 789) eq '456 123 789');
+ok (sprintf ("%d", mpq(15,16)) eq '15/16');
+ok (sprintf ("%f", mpf(1.5)) eq '1.500000');
+ok (sprintf ("%.2f", mpf(1.5)) eq '1.50');
+
+ok (sprintf ("%*d", 6, 123) eq ' 123');
+ok (sprintf ("%*d", 6, mpz(123)) eq ' 123');
+ok (sprintf ("%*d", 6, mpq(15,16)) eq ' 15/16');
+
+ok (sprintf ("%x", 123) eq '7b');
+ok (sprintf ("%x", mpz(123)) eq '7b');
+ok (sprintf ("%X", 123) eq '7B');
+ok (sprintf ("%X", mpz(123)) eq '7B');
+ok (sprintf ("%#x", 123) eq '0x7b');
+ok (sprintf ("%#x", mpz(123)) eq '0x7b');
+ok (sprintf ("%#X", 123) eq '0X7B');
+ok (sprintf ("%#X", mpz(123)) eq '0X7B');
+
+ok (sprintf ("%x", mpq(15,16)) eq 'f/10');
+ok (sprintf ("%X", mpq(15,16)) eq 'F/10');
+ok (sprintf ("%#x", mpq(15,16)) eq '0xf/0x10');
+ok (sprintf ("%#X", mpq(15,16)) eq '0XF/0X10');
+
+ok (sprintf ("%*.*f", 10, 3, 1.25) eq ' 1.250');
+ok (sprintf ("%*.*f", 10, 3, mpf(1.5)) eq ' 1.500');
+
+ok (via_printf ("%d", mpz(123)) eq '123');
+ok (via_printf ("%d %d %d", 456, mpz(123), 789) eq '456 123 789');
+ok (via_printf ("%d", mpq(15,16)) eq '15/16');
+ok (via_printf ("%f", mpf(1.5)) eq '1.500000');
+ok (via_printf ("%.2f", mpf(1.5)) eq '1.50');
+
+ok (via_printf ("%*d", 6, 123) eq ' 123');
+ok (via_printf ("%*d", 6, mpz(123)) eq ' 123');
+ok (via_printf ("%*d", 6, mpq(15,16)) eq ' 15/16');
+
+ok (via_printf ("%x", 123) eq '7b');
+ok (via_printf ("%x", mpz(123)) eq '7b');
+ok (via_printf ("%X", 123) eq '7B');
+ok (via_printf ("%X", mpz(123)) eq '7B');
+ok (via_printf ("%#x", 123) eq '0x7b');
+ok (via_printf ("%#x", mpz(123)) eq '0x7b');
+ok (via_printf ("%#X", 123) eq '0X7B');
+ok (via_printf ("%#X", mpz(123)) eq '0X7B');
+
+ok (via_printf ("%x", mpq(15,16)) eq 'f/10');
+ok (via_printf ("%X", mpq(15,16)) eq 'F/10');
+ok (via_printf ("%#x", mpq(15,16)) eq '0xf/0x10');
+ok (via_printf ("%#X", mpq(15,16)) eq '0XF/0X10');
+
+ok (via_printf ("%*.*f", 10, 3, 1.25) eq ' 1.250');
+ok (via_printf ("%*.*f", 10, 3, mpf(1.5)) eq ' 1.500');
+
+#------------------------------------------------------------------------------
+# GMP::sgn
+
+ok (sgn(-123) == -1);
+ok (sgn(0) == 0);
+ok (sgn(123) == 1);
+
+ok (sgn($uv_max) == 1);
+
+ok (sgn(-123.0) == -1);
+ok (sgn(0.0) == 0);
+ok (sgn(123.0) == 1);
+
+ok (sgn('-123') == -1);
+ok (sgn('0') == 0);
+ok (sgn('123') == 1);
+ok (sgn('-123.0') == -1);
+ok (sgn('0.0') == 0);
+ok (sgn('123.0') == 1);
+
+ok (sgn(substr('x-123x',1,4)) == -1);
+ok (sgn(substr('x0x',1,1)) == 0);
+ok (sgn(substr('x123x',1,3)) == 1);
+
+ok (mpz(-123)->sgn() == -1);
+ok (mpz(0) ->sgn() == 0);
+ok (mpz(123) ->sgn() == 1);
+
+ok (mpq(-123)->sgn() == -1);
+ok (mpq(0) ->sgn() == 0);
+ok (mpq(123) ->sgn() == 1);
+
+ok (mpf(-123)->sgn() == -1);
+ok (mpf(0) ->sgn() == 0);
+ok (mpf(123) ->sgn() == 1);
+
+
+
+#------------------------------------------------------------------------------
+# overloaded constants
+
+if ($] > 5.00503) {
+ if (! do 'test2.pl') {
+ die "Cannot run test2.pl\n";
+ }
+}
+
+
+
+
+#------------------------------------------------------------------------------
+# $# stuff
+#
+# For some reason "local $#" doesn't leave $# back at its default undefined
+# state when exiting the block.
+
+{ local $# = 'hi %.0f there';
+ my $f = mpf(123);
+ ok ("$f" eq 'hi 123 there'); }
+
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/vendor/gmp-6.3.0/demos/perl/test2.pl b/vendor/gmp-6.3.0/demos/perl/test2.pl
new file mode 100644
index 0000000..31a1d6b
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/test2.pl
@@ -0,0 +1,75 @@
+# GMP perl module tests (part 2)
+
+# Copyright 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/.
+
+
+# The following uses of :constants seem to provoke segvs in perl 5.005_03,
+# so they're kept separate file to be run only on suitable perl versions.
+
+
+use GMP::Mpz qw(:constants);
+{
+ my $a = 123;
+ ok (UNIVERSAL::isa ($a, "GMP::Mpz"));
+}
+use GMP::Mpz qw(:noconstants);
+
+use GMP::Mpq qw(:constants);
+{
+ my $a = 123;
+ ok (UNIVERSAL::isa ($a, "GMP::Mpq"));
+}
+use GMP::Mpq qw(:noconstants);
+
+use GMP::Mpf qw(:constants);
+{
+ my $a = 123;
+ ok (UNIVERSAL::isa ($a, "GMP::Mpf"));
+}
+use GMP::Mpf qw(:noconstants);
+
+
+# compiled constants unchanged by clrbit etc when re-executed
+foreach (0, 1, 2) {
+ use GMP::Mpz qw(:constants);
+ my $a = 15;
+ my $b = 6;
+ use GMP::Mpz qw(:noconstants);
+ clrbit ($a, 0);
+ ok ($a == 14);
+ setbit ($b, 0);
+ ok ($b == 7);
+}
+
+1;
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/vendor/gmp-6.3.0/demos/perl/typemap b/vendor/gmp-6.3.0/demos/perl/typemap
new file mode 100644
index 0000000..e863a9c
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/perl/typemap
@@ -0,0 +1,108 @@
+# GMP module external subroutine type mappings.
+
+# Copyright 2001, 2003 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/.
+
+
+TYPEMAP
+const_string T_PV
+const_string_assume CONST_STRING_ASSUME
+mpz MPZ
+mpq MPQ
+mpf MPF
+mpz_assume MPZ_ASSUME
+mpq_assume MPQ_ASSUME
+mpf_assume MPF_ASSUME
+mpz_coerce MPZ_COERCE
+mpq_coerce MPQ_COERCE
+mpf_coerce_st0 MPF_COERCE_ST0
+mpf_coerce_def MPF_COERCE_DEF
+randstate RANDSTATE
+ulong_coerce ULONG_COERCE
+malloced_string MALLOCED_STRING
+order_noswap ORDER_NOSWAP
+dummy DUMMY
+# perl 5.005 doesn't have UV in its standard typemap, so use this instead
+gmp_UV GMP_UV
+
+
+INPUT
+MPZ
+ class_or_croak ($arg, mpz_class); $var = SvMPZ($arg);
+MPQ
+ class_or_croak ($arg, mpq_class); $var = SvMPQ($arg);
+MPF
+ class_or_croak ($arg, mpf_class); $var = SvMPF($arg);
+MPZ_ASSUME
+ MPZ_ASSUME ($var, $arg)
+MPQ_ASSUME
+ MPQ_ASSUME ($var, $arg)
+MPF_ASSUME
+ MPF_ASSUME ($var, $arg)
+MPZ_COERCE
+ $var = coerce_mpz (tmp_mpz_${(my $stnum=$arg)=~s/[^0-9]//g;\$stnum}, $arg)
+MPQ_COERCE
+ $var = coerce_mpq (tmp_mpq_${(my $stnum=$arg)=~s/[^0-9]//g;\$stnum}, $arg)
+MPF_COERCE_ST0
+ /* precision follows ST(0) */
+ assert (sv_derived_from (ST(0), mpf_class));
+ $var = coerce_mpf (tmp_mpf_${(my $stnum=$arg)=~s/[^0-9]//g;\$stnum},
+ $arg, mpf_get_prec (SvMPF(ST(0))))
+MPF_COERCE_DEF
+ /* default precision used */
+ $var = coerce_mpf (tmp_mpf_${(my $stnum=$arg)=~s/[^0-9]//g;\$stnum},
+ $arg, mpf_get_default_prec())
+RANDSTATE
+ class_or_croak ($arg, rand_class); $var = SvRANDSTATE($arg);
+ULONG_COERCE
+ $var = coerce_ulong ($arg)
+ORDER_NOSWAP
+ assert ($arg != &PL_sv_yes);
+DUMMY
+ /* dummy $var */
+CONST_STRING_ASSUME
+ /* No need to check for SvPOKp and use SvPV, this mapping is
+ only used for overload_constant, which always gets literal
+ strings. */
+ assert (SvPOK ($arg));
+ $var = SvPVX ($arg);
+
+
+OUTPUT
+MPZ
+ sv_bless (sv_setref_pv ($arg, NULL, $var), mpz_class_hv);
+MPQ
+ sv_bless (sv_setref_pv ($arg, NULL, $var), mpq_class_hv);
+MPF
+ sv_bless (sv_setref_pv ($arg, NULL, $var), mpf_class_hv);
+RANDSTATE
+ sv_setref_pv ($arg, rand_class, $var);
+MALLOCED_STRING
+ sv_usepvn_mg ($arg, $var, strlen($var));
+GMP_UV
+ sv_setuv ($arg, (UV) ($var));
diff --git a/vendor/gmp-6.3.0/demos/pexpr-config-h.in b/vendor/gmp-6.3.0/demos/pexpr-config-h.in
new file mode 100644
index 0000000..b3e7f5d
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/pexpr-config-h.in
@@ -0,0 +1,45 @@
+/* Templates for pexpr program configuration. -*- mode:c -*-
+
+Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* Define if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H @HAVE_SYS_RESOURCE_H_01@
+
+/* Define if you have the `clock' function. */
+#define HAVE_CLOCK @HAVE_CLOCK_01@
+
+/* Define if you have the `cputime' function. */
+#define HAVE_CPUTIME @HAVE_CPUTIME_01@
+
+/* Define if you have the `getrusage' function. */
+#define HAVE_GETRUSAGE @HAVE_GETRUSAGE_01@
+
+/* Define if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY @HAVE_GETTIMEOFDAY_01@
+
+/* Define if you have the `sigaction' function. */
+#define HAVE_SIGACTION @HAVE_SIGACTION_01@
+
+/* Define if you have the `sigaltstack' function. */
+#define HAVE_SIGALTSTACK @HAVE_SIGALTSTACK_01@
+
+/* Define if you have the `sigstack' function. */
+#define HAVE_SIGSTACK @HAVE_SIGSTACK_01@
+
+/* Define if the system has the type `stack_t'. */
+#define HAVE_STACK_T @HAVE_STACK_T_01@
diff --git a/vendor/gmp-6.3.0/demos/pexpr.c b/vendor/gmp-6.3.0/demos/pexpr.c
new file mode 100644
index 0000000..d5009e9
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/pexpr.c
@@ -0,0 +1,1380 @@
+/* Program for computing integer expressions using the GNU Multiple Precision
+ Arithmetic Library.
+
+Copyright 1997, 1999-2002, 2005, 2008, 2012, 2015 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* This expressions evaluator works by building an expression tree (using a
+ recursive descent parser) which is then evaluated. The expression tree is
+ useful since we want to optimize certain expressions (like a^b % c).
+
+ Usage: pexpr [options] expr ...
+ (Assuming you called the executable `pexpr' of course.)
+
+ Command line options:
+
+ -b print output in binary
+ -o print output in octal
+ -d print output in decimal (the default)
+ -x print output in hexadecimal
+ -b<NUM> print output in base NUM
+ -t print timing information
+ -html output html
+ -wml output wml
+ -split split long lines each 80th digit
+*/
+
+/* Define LIMIT_RESOURCE_USAGE if you want to make sure the program doesn't
+ use up extensive resources (cpu, memory). Useful for the GMP demo on the
+ GMP web site, since we cannot load the server too much. */
+
+#include "pexpr-config.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <ctype.h>
+
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#if HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#include "gmp.h"
+
+/* SunOS 4 and HPUX 9 don't define a canonical SIGSTKSZ, use a default. */
+#ifndef SIGSTKSZ
+#define SIGSTKSZ 4096
+#endif
+
+
+#define TIME(t,func) \
+ do { int __t0, __tmp; \
+ __t0 = cputime (); \
+ {func;} \
+ __tmp = cputime () - __t0; \
+ (t) = __tmp; \
+ } while (0)
+
+/* GMP version 1.x compatibility. */
+#if ! (__GNU_MP_VERSION >= 2)
+typedef MP_INT __mpz_struct;
+typedef __mpz_struct mpz_t[1];
+typedef __mpz_struct *mpz_ptr;
+#define mpz_fdiv_q mpz_div
+#define mpz_fdiv_r mpz_mod
+#define mpz_tdiv_q_2exp mpz_div_2exp
+#define mpz_sgn(Z) ((Z)->size < 0 ? -1 : (Z)->size > 0)
+#endif
+
+/* GMP version 2.0 compatibility. */
+#if ! (__GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1)
+#define mpz_swap(a,b) \
+ do { __mpz_struct __t; __t = *a; *a = *b; *b = __t;} while (0)
+#endif
+
+jmp_buf errjmpbuf;
+
+enum op_t {NOP, LIT, NEG, NOT, PLUS, MINUS, MULT, DIV, MOD, REM, INVMOD, POW,
+ AND, IOR, XOR, SLL, SRA, POPCNT, HAMDIST, GCD, LCM, SQRT, ROOT, FAC,
+ LOG, LOG2, FERMAT, MERSENNE, FIBONACCI, RANDOM, NEXTPRIME, BINOM,
+ TIMING};
+
+/* Type for the expression tree. */
+struct expr
+{
+ enum op_t op;
+ union
+ {
+ struct {struct expr *lhs, *rhs;} ops;
+ mpz_t val;
+ } operands;
+};
+
+typedef struct expr *expr_t;
+
+void cleanup_and_exit (int);
+
+char *skipspace (char *);
+void makeexp (expr_t *, enum op_t, expr_t, expr_t);
+void free_expr (expr_t);
+char *expr (char *, expr_t *);
+char *term (char *, expr_t *);
+char *power (char *, expr_t *);
+char *factor (char *, expr_t *);
+int match (char *, char *);
+int matchp (char *, char *);
+int cputime (void);
+
+void mpz_eval_expr (mpz_ptr, expr_t);
+void mpz_eval_mod_expr (mpz_ptr, expr_t, mpz_ptr);
+
+char *error;
+int flag_print = 1;
+int print_timing = 0;
+int flag_html = 0;
+int flag_wml = 0;
+int flag_splitup_output = 0;
+char *newline = "";
+gmp_randstate_t rstate;
+
+
+
+/* cputime() returns user CPU time measured in milliseconds. */
+#if ! HAVE_CPUTIME
+#if HAVE_GETRUSAGE
+int
+cputime (void)
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#else
+#if HAVE_CLOCK
+int
+cputime (void)
+{
+ if (CLOCKS_PER_SEC < 100000)
+ return clock () * 1000 / CLOCKS_PER_SEC;
+ return clock () / (CLOCKS_PER_SEC / 1000);
+}
+#else
+int
+cputime (void)
+{
+ return 0;
+}
+#endif
+#endif
+#endif
+
+
+int
+stack_downwards_helper (char *xp)
+{
+ char y;
+ return &y < xp;
+}
+int
+stack_downwards_p (void)
+{
+ char x;
+ return stack_downwards_helper (&x);
+}
+
+
+void
+setup_error_handler (void)
+{
+#if HAVE_SIGACTION
+ struct sigaction act;
+ act.sa_handler = cleanup_and_exit;
+ sigemptyset (&(act.sa_mask));
+#define SIGNAL(sig) sigaction (sig, &act, NULL)
+#else
+ struct { int sa_flags; } act;
+#define SIGNAL(sig) signal (sig, cleanup_and_exit)
+#endif
+ act.sa_flags = 0;
+
+ /* Set up a stack for signal handling. A typical cause of error is stack
+ overflow, and in such situation a signal can not be delivered on the
+ overflown stack. */
+#if HAVE_SIGALTSTACK
+ {
+ /* AIX uses stack_t, MacOS uses struct sigaltstack, various other
+ systems have both. */
+#if HAVE_STACK_T
+ stack_t s;
+#else
+ struct sigaltstack s;
+#endif
+ s.ss_sp = malloc (SIGSTKSZ);
+ s.ss_size = SIGSTKSZ;
+ s.ss_flags = 0;
+ if (sigaltstack (&s, NULL) != 0)
+ perror("sigaltstack");
+ act.sa_flags = SA_ONSTACK;
+ }
+#else
+#if HAVE_SIGSTACK
+ {
+ struct sigstack s;
+ s.ss_sp = malloc (SIGSTKSZ);
+ if (stack_downwards_p ())
+ s.ss_sp += SIGSTKSZ;
+ s.ss_onstack = 0;
+ if (sigstack (&s, NULL) != 0)
+ perror("sigstack");
+ act.sa_flags = SA_ONSTACK;
+ }
+#else
+#endif
+#endif
+
+#ifdef LIMIT_RESOURCE_USAGE
+ {
+ struct rlimit limit;
+
+ limit.rlim_cur = limit.rlim_max = 0;
+ setrlimit (RLIMIT_CORE, &limit);
+
+ limit.rlim_cur = 3;
+ limit.rlim_max = 4;
+ setrlimit (RLIMIT_CPU, &limit);
+
+ limit.rlim_cur = limit.rlim_max = 16 * 1024 * 1024;
+ setrlimit (RLIMIT_DATA, &limit);
+
+ getrlimit (RLIMIT_STACK, &limit);
+ limit.rlim_cur = 4 * 1024 * 1024;
+ setrlimit (RLIMIT_STACK, &limit);
+
+ SIGNAL (SIGXCPU);
+ }
+#endif /* LIMIT_RESOURCE_USAGE */
+
+ SIGNAL (SIGILL);
+ SIGNAL (SIGSEGV);
+#ifdef SIGBUS /* not in mingw */
+ SIGNAL (SIGBUS);
+#endif
+ SIGNAL (SIGFPE);
+ SIGNAL (SIGABRT);
+}
+
+int
+main (int argc, char **argv)
+{
+ struct expr *e;
+ int i;
+ mpz_t r;
+ int errcode = 0;
+ char *str;
+ int base = 10;
+
+ setup_error_handler ();
+
+ gmp_randinit (rstate, GMP_RAND_ALG_LC, 128);
+
+ {
+#if HAVE_GETTIMEOFDAY
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ gmp_randseed_ui (rstate, tv.tv_sec + tv.tv_usec);
+#else
+ time_t t;
+ time (&t);
+ gmp_randseed_ui (rstate, t);
+#endif
+ }
+
+ mpz_init (r);
+
+ while (argc > 1 && argv[1][0] == '-')
+ {
+ char *arg = argv[1];
+
+ if (arg[1] >= '0' && arg[1] <= '9')
+ break;
+
+ if (arg[1] == 't')
+ print_timing = 1;
+ else if (arg[1] == 'b' && arg[2] >= '0' && arg[2] <= '9')
+ {
+ base = atoi (arg + 2);
+ if (base < 2 || base > 62)
+ {
+ fprintf (stderr, "error: invalid output base\n");
+ exit (-1);
+ }
+ }
+ else if (arg[1] == 'b' && arg[2] == 0)
+ base = 2;
+ else if (arg[1] == 'x' && arg[2] == 0)
+ base = 16;
+ else if (arg[1] == 'X' && arg[2] == 0)
+ base = -16;
+ else if (arg[1] == 'o' && arg[2] == 0)
+ base = 8;
+ else if (arg[1] == 'd' && arg[2] == 0)
+ base = 10;
+ else if (arg[1] == 'v' && arg[2] == 0)
+ {
+ printf ("pexpr linked to gmp %s\n", __gmp_version);
+ }
+ else if (strcmp (arg, "-html") == 0)
+ {
+ flag_html = 1;
+ newline = "<br>";
+ }
+ else if (strcmp (arg, "-wml") == 0)
+ {
+ flag_wml = 1;
+ newline = "<br/>";
+ }
+ else if (strcmp (arg, "-split") == 0)
+ {
+ flag_splitup_output = 1;
+ }
+ else if (strcmp (arg, "-noprint") == 0)
+ {
+ flag_print = 0;
+ }
+ else
+ {
+ fprintf (stderr, "error: unknown option `%s'\n", arg);
+ exit (-1);
+ }
+ argv++;
+ argc--;
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ int s;
+ int jmpval;
+
+ /* Set up error handler for parsing expression. */
+ jmpval = setjmp (errjmpbuf);
+ if (jmpval != 0)
+ {
+ fprintf (stderr, "error: %s%s\n", error, newline);
+ fprintf (stderr, " %s%s\n", argv[i], newline);
+ if (! flag_html)
+ {
+ /* ??? Dunno how to align expression position with arrow in
+ HTML ??? */
+ fprintf (stderr, " ");
+ for (s = jmpval - (long) argv[i]; --s >= 0; )
+ putc (' ', stderr);
+ fprintf (stderr, "^\n");
+ }
+
+ errcode |= 1;
+ continue;
+ }
+
+ str = expr (argv[i], &e);
+
+ if (str[0] != 0)
+ {
+ fprintf (stderr,
+ "error: garbage where end of expression expected%s\n",
+ newline);
+ fprintf (stderr, " %s%s\n", argv[i], newline);
+ if (! flag_html)
+ {
+ /* ??? Dunno how to align expression position with arrow in
+ HTML ??? */
+ fprintf (stderr, " ");
+ for (s = str - argv[i]; --s; )
+ putc (' ', stderr);
+ fprintf (stderr, "^\n");
+ }
+
+ errcode |= 1;
+ free_expr (e);
+ continue;
+ }
+
+ /* Set up error handler for evaluating expression. */
+ if (setjmp (errjmpbuf))
+ {
+ fprintf (stderr, "error: %s%s\n", error, newline);
+ fprintf (stderr, " %s%s\n", argv[i], newline);
+ if (! flag_html)
+ {
+ /* ??? Dunno how to align expression position with arrow in
+ HTML ??? */
+ fprintf (stderr, " ");
+ for (s = str - argv[i]; --s >= 0; )
+ putc (' ', stderr);
+ fprintf (stderr, "^\n");
+ }
+
+ errcode |= 2;
+ continue;
+ }
+
+ if (print_timing)
+ {
+ int t;
+ TIME (t, mpz_eval_expr (r, e));
+ printf ("computation took %d ms%s\n", t, newline);
+ }
+ else
+ mpz_eval_expr (r, e);
+
+ if (flag_print)
+ {
+ size_t out_len;
+ char *tmp, *s;
+
+ out_len = mpz_sizeinbase (r, base >= 0 ? base : -base) + 2;
+#ifdef LIMIT_RESOURCE_USAGE
+ if (out_len > 100000)
+ {
+ printf ("result is about %ld digits, not printing it%s\n",
+ (long) out_len - 3, newline);
+ exit (-2);
+ }
+#endif
+ tmp = malloc (out_len);
+
+ if (print_timing)
+ {
+ int t;
+ printf ("output conversion ");
+ TIME (t, mpz_get_str (tmp, base, r));
+ printf ("took %d ms%s\n", t, newline);
+ }
+ else
+ mpz_get_str (tmp, base, r);
+
+ out_len = strlen (tmp);
+ if (flag_splitup_output)
+ {
+ for (s = tmp; out_len > 80; s += 80)
+ {
+ fwrite (s, 1, 80, stdout);
+ printf ("%s\n", newline);
+ out_len -= 80;
+ }
+
+ fwrite (s, 1, out_len, stdout);
+ }
+ else
+ {
+ fwrite (tmp, 1, out_len, stdout);
+ }
+
+ free (tmp);
+ printf ("%s\n", newline);
+ }
+ else
+ {
+ printf ("result is approximately %ld digits%s\n",
+ (long) mpz_sizeinbase (r, base >= 0 ? base : -base),
+ newline);
+ }
+
+ free_expr (e);
+ }
+
+ mpz_clear (r);
+
+ exit (errcode);
+}
+
+char *
+expr (char *str, expr_t *e)
+{
+ expr_t e2;
+
+ str = skipspace (str);
+ if (str[0] == '+')
+ {
+ str = term (str + 1, e);
+ }
+ else if (str[0] == '-')
+ {
+ str = term (str + 1, e);
+ makeexp (e, NEG, *e, NULL);
+ }
+ else if (str[0] == '~')
+ {
+ str = term (str + 1, e);
+ makeexp (e, NOT, *e, NULL);
+ }
+ else
+ {
+ str = term (str, e);
+ }
+
+ for (;;)
+ {
+ str = skipspace (str);
+ switch (str[0])
+ {
+ case 'p':
+ if (match ("plus", str))
+ {
+ str = term (str + 4, &e2);
+ makeexp (e, PLUS, *e, e2);
+ }
+ else
+ return str;
+ break;
+ case 'm':
+ if (match ("minus", str))
+ {
+ str = term (str + 5, &e2);
+ makeexp (e, MINUS, *e, e2);
+ }
+ else
+ return str;
+ break;
+ case '+':
+ str = term (str + 1, &e2);
+ makeexp (e, PLUS, *e, e2);
+ break;
+ case '-':
+ str = term (str + 1, &e2);
+ makeexp (e, MINUS, *e, e2);
+ break;
+ default:
+ return str;
+ }
+ }
+}
+
+char *
+term (char *str, expr_t *e)
+{
+ expr_t e2;
+
+ str = power (str, e);
+ for (;;)
+ {
+ str = skipspace (str);
+ switch (str[0])
+ {
+ case 'm':
+ if (match ("mul", str))
+ {
+ str = power (str + 3, &e2);
+ makeexp (e, MULT, *e, e2);
+ break;
+ }
+ if (match ("mod", str))
+ {
+ str = power (str + 3, &e2);
+ makeexp (e, MOD, *e, e2);
+ break;
+ }
+ return str;
+ case 'd':
+ if (match ("div", str))
+ {
+ str = power (str + 3, &e2);
+ makeexp (e, DIV, *e, e2);
+ break;
+ }
+ return str;
+ case 'r':
+ if (match ("rem", str))
+ {
+ str = power (str + 3, &e2);
+ makeexp (e, REM, *e, e2);
+ break;
+ }
+ return str;
+ case 'i':
+ if (match ("invmod", str))
+ {
+ str = power (str + 6, &e2);
+ makeexp (e, REM, *e, e2);
+ break;
+ }
+ return str;
+ case 't':
+ if (match ("times", str))
+ {
+ str = power (str + 5, &e2);
+ makeexp (e, MULT, *e, e2);
+ break;
+ }
+ if (match ("thru", str))
+ {
+ str = power (str + 4, &e2);
+ makeexp (e, DIV, *e, e2);
+ break;
+ }
+ if (match ("through", str))
+ {
+ str = power (str + 7, &e2);
+ makeexp (e, DIV, *e, e2);
+ break;
+ }
+ return str;
+ case '*':
+ str = power (str + 1, &e2);
+ makeexp (e, MULT, *e, e2);
+ break;
+ case '/':
+ str = power (str + 1, &e2);
+ makeexp (e, DIV, *e, e2);
+ break;
+ case '%':
+ str = power (str + 1, &e2);
+ makeexp (e, MOD, *e, e2);
+ break;
+ default:
+ return str;
+ }
+ }
+}
+
+char *
+power (char *str, expr_t *e)
+{
+ expr_t e2;
+
+ str = factor (str, e);
+ while (str[0] == '!')
+ {
+ str++;
+ makeexp (e, FAC, *e, NULL);
+ }
+ str = skipspace (str);
+ if (str[0] == '^')
+ {
+ str = power (str + 1, &e2);
+ makeexp (e, POW, *e, e2);
+ }
+ return str;
+}
+
+int
+match (char *s, char *str)
+{
+ char *ostr = str;
+ int i;
+
+ for (i = 0; s[i] != 0; i++)
+ {
+ if (str[i] != s[i])
+ return 0;
+ }
+ str = skipspace (str + i);
+ return str - ostr;
+}
+
+int
+matchp (char *s, char *str)
+{
+ char *ostr = str;
+ int i;
+
+ for (i = 0; s[i] != 0; i++)
+ {
+ if (str[i] != s[i])
+ return 0;
+ }
+ str = skipspace (str + i);
+ if (str[0] == '(')
+ return str - ostr + 1;
+ return 0;
+}
+
+struct functions
+{
+ char *spelling;
+ enum op_t op;
+ int arity; /* 1 or 2 means real arity; 0 means arbitrary. */
+};
+
+struct functions fns[] =
+{
+ {"sqrt", SQRT, 1},
+#if __GNU_MP_VERSION >= 2
+ {"root", ROOT, 2},
+ {"popc", POPCNT, 1},
+ {"hamdist", HAMDIST, 2},
+#endif
+ {"gcd", GCD, 0},
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ {"lcm", LCM, 0},
+#endif
+ {"and", AND, 0},
+ {"ior", IOR, 0},
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ {"xor", XOR, 0},
+#endif
+ {"plus", PLUS, 0},
+ {"pow", POW, 2},
+ {"minus", MINUS, 2},
+ {"mul", MULT, 0},
+ {"div", DIV, 2},
+ {"mod", MOD, 2},
+ {"rem", REM, 2},
+#if __GNU_MP_VERSION >= 2
+ {"invmod", INVMOD, 2},
+#endif
+ {"log", LOG, 2},
+ {"log2", LOG2, 1},
+ {"F", FERMAT, 1},
+ {"M", MERSENNE, 1},
+ {"fib", FIBONACCI, 1},
+ {"Fib", FIBONACCI, 1},
+ {"random", RANDOM, 1},
+ {"nextprime", NEXTPRIME, 1},
+ {"binom", BINOM, 2},
+ {"binomial", BINOM, 2},
+ {"fac", FAC, 1},
+ {"fact", FAC, 1},
+ {"factorial", FAC, 1},
+ {"time", TIMING, 1},
+ {"", NOP, 0}
+};
+
+char *
+factor (char *str, expr_t *e)
+{
+ expr_t e1, e2;
+
+ str = skipspace (str);
+
+ if (isalpha (str[0]))
+ {
+ int i;
+ int cnt;
+
+ for (i = 0; fns[i].op != NOP; i++)
+ {
+ if (fns[i].arity == 1)
+ {
+ cnt = matchp (fns[i].spelling, str);
+ if (cnt != 0)
+ {
+ str = expr (str + cnt, &e1);
+ str = skipspace (str);
+ if (str[0] != ')')
+ {
+ error = "expected `)'";
+ longjmp (errjmpbuf, (int) (long) str);
+ }
+ makeexp (e, fns[i].op, e1, NULL);
+ return str + 1;
+ }
+ }
+ }
+
+ for (i = 0; fns[i].op != NOP; i++)
+ {
+ if (fns[i].arity != 1)
+ {
+ cnt = matchp (fns[i].spelling, str);
+ if (cnt != 0)
+ {
+ str = expr (str + cnt, &e1);
+ str = skipspace (str);
+
+ if (str[0] != ',')
+ {
+ error = "expected `,' and another operand";
+ longjmp (errjmpbuf, (int) (long) str);
+ }
+
+ str = skipspace (str + 1);
+ str = expr (str, &e2);
+ str = skipspace (str);
+
+ if (fns[i].arity == 0)
+ {
+ while (str[0] == ',')
+ {
+ makeexp (&e1, fns[i].op, e1, e2);
+ str = skipspace (str + 1);
+ str = expr (str, &e2);
+ str = skipspace (str);
+ }
+ }
+
+ if (str[0] != ')')
+ {
+ error = "expected `)'";
+ longjmp (errjmpbuf, (int) (long) str);
+ }
+
+ makeexp (e, fns[i].op, e1, e2);
+ return str + 1;
+ }
+ }
+ }
+ }
+
+ if (str[0] == '(')
+ {
+ str = expr (str + 1, e);
+ str = skipspace (str);
+ if (str[0] != ')')
+ {
+ error = "expected `)'";
+ longjmp (errjmpbuf, (int) (long) str);
+ }
+ str++;
+ }
+ else if (str[0] >= '0' && str[0] <= '9')
+ {
+ expr_t res;
+ char *s, *sc;
+
+ res = malloc (sizeof (struct expr));
+ res -> op = LIT;
+ mpz_init (res->operands.val);
+
+ s = str;
+ while (isalnum (str[0]))
+ str++;
+ sc = malloc (str - s + 1);
+ memcpy (sc, s, str - s);
+ sc[str - s] = 0;
+
+ mpz_set_str (res->operands.val, sc, 0);
+ *e = res;
+ free (sc);
+ }
+ else
+ {
+ error = "operand expected";
+ longjmp (errjmpbuf, (int) (long) str);
+ }
+ return str;
+}
+
+char *
+skipspace (char *str)
+{
+ while (str[0] == ' ')
+ str++;
+ return str;
+}
+
+/* Make a new expression with operation OP and right hand side
+ RHS and left hand side lhs. Put the result in R. */
+void
+makeexp (expr_t *r, enum op_t op, expr_t lhs, expr_t rhs)
+{
+ expr_t res;
+ res = malloc (sizeof (struct expr));
+ res -> op = op;
+ res -> operands.ops.lhs = lhs;
+ res -> operands.ops.rhs = rhs;
+ *r = res;
+ return;
+}
+
+/* Free the memory used by expression E. */
+void
+free_expr (expr_t e)
+{
+ if (e->op != LIT)
+ {
+ free_expr (e->operands.ops.lhs);
+ if (e->operands.ops.rhs != NULL)
+ free_expr (e->operands.ops.rhs);
+ }
+ else
+ {
+ mpz_clear (e->operands.val);
+ }
+}
+
+/* Evaluate the expression E and put the result in R. */
+void
+mpz_eval_expr (mpz_ptr r, expr_t e)
+{
+ mpz_t lhs, rhs;
+
+ switch (e->op)
+ {
+ case LIT:
+ mpz_set (r, e->operands.val);
+ return;
+ case PLUS:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_add (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case MINUS:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_sub (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case MULT:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_mul (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case DIV:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_fdiv_q (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case MOD:
+ mpz_init (rhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_abs (rhs, rhs);
+ mpz_eval_mod_expr (r, e->operands.ops.lhs, rhs);
+ mpz_clear (rhs);
+ return;
+ case REM:
+ /* Check if lhs operand is POW expression and optimize for that case. */
+ if (e->operands.ops.lhs->op == POW)
+ {
+ mpz_t powlhs, powrhs;
+ mpz_init (powlhs);
+ mpz_init (powrhs);
+ mpz_init (rhs);
+ mpz_eval_expr (powlhs, e->operands.ops.lhs->operands.ops.lhs);
+ mpz_eval_expr (powrhs, e->operands.ops.lhs->operands.ops.rhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_powm (r, powlhs, powrhs, rhs);
+ if (mpz_cmp_si (rhs, 0L) < 0)
+ mpz_neg (r, r);
+ mpz_clear (powlhs);
+ mpz_clear (powrhs);
+ mpz_clear (rhs);
+ return;
+ }
+
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_fdiv_r (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#if __GNU_MP_VERSION >= 2
+ case INVMOD:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_invert (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#endif
+ case POW:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ if (mpz_cmpabs_ui (lhs, 1) <= 0)
+ {
+ /* For 0^rhs and 1^rhs, we just need to verify that
+ rhs is well-defined. For (-1)^rhs we need to
+ determine (rhs mod 2). For simplicity, compute
+ (rhs mod 2) for all three cases. */
+ expr_t two, et;
+ two = malloc (sizeof (struct expr));
+ two -> op = LIT;
+ mpz_init_set_ui (two->operands.val, 2L);
+ makeexp (&et, MOD, e->operands.ops.rhs, two);
+ e->operands.ops.rhs = et;
+ }
+
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ if (mpz_cmp_si (rhs, 0L) == 0)
+ /* x^0 is 1 */
+ mpz_set_ui (r, 1L);
+ else if (mpz_cmp_si (lhs, 0L) == 0)
+ /* 0^y (where y != 0) is 0 */
+ mpz_set_ui (r, 0L);
+ else if (mpz_cmp_ui (lhs, 1L) == 0)
+ /* 1^y is 1 */
+ mpz_set_ui (r, 1L);
+ else if (mpz_cmp_si (lhs, -1L) == 0)
+ /* (-1)^y just depends on whether y is even or odd */
+ mpz_set_si (r, (mpz_get_ui (rhs) & 1) ? -1L : 1L);
+ else if (mpz_cmp_si (rhs, 0L) < 0)
+ /* x^(-n) is 0 */
+ mpz_set_ui (r, 0L);
+ else
+ {
+ unsigned long int cnt;
+ unsigned long int y;
+ /* error if exponent does not fit into an unsigned long int. */
+ if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
+ goto pow_err;
+
+ y = mpz_get_ui (rhs);
+ /* x^y == (x/(2^c))^y * 2^(c*y) */
+#if __GNU_MP_VERSION >= 2
+ cnt = mpz_scan1 (lhs, 0);
+#else
+ cnt = 0;
+#endif
+ if (cnt != 0)
+ {
+ if (y * cnt / cnt != y)
+ goto pow_err;
+ mpz_tdiv_q_2exp (lhs, lhs, cnt);
+ mpz_pow_ui (r, lhs, y);
+ mpz_mul_2exp (r, r, y * cnt);
+ }
+ else
+ mpz_pow_ui (r, lhs, y);
+ }
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ pow_err:
+ error = "result of `pow' operator too large";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ case GCD:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_gcd (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ case LCM:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_lcm (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#endif
+ case AND:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_and (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case IOR:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_ior (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ case XOR:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_xor (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#endif
+ case NEG:
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ mpz_neg (r, r);
+ return;
+ case NOT:
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ mpz_com (r, r);
+ return;
+ case SQRT:
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ if (mpz_sgn (lhs) < 0)
+ {
+ error = "cannot take square root of negative numbers";
+ mpz_clear (lhs);
+ longjmp (errjmpbuf, 1);
+ }
+ mpz_sqrt (r, lhs);
+ return;
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ case ROOT:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ if (mpz_sgn (rhs) <= 0)
+ {
+ error = "cannot take non-positive root orders";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ }
+ if (mpz_sgn (lhs) < 0 && (mpz_get_ui (rhs) & 1) == 0)
+ {
+ error = "cannot take even root orders of negative numbers";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ }
+
+ {
+ unsigned long int nth = mpz_get_ui (rhs);
+ if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
+ {
+ /* If we are asked to take an awfully large root order, cheat and
+ ask for the largest order we can pass to mpz_root. This saves
+ some error prone special cases. */
+ nth = ~(unsigned long int) 0;
+ }
+ mpz_root (r, lhs, nth);
+ }
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#endif
+ case FAC:
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ if (mpz_size (r) > 1)
+ {
+ error = "result of `!' operator too large";
+ longjmp (errjmpbuf, 1);
+ }
+ mpz_fac_ui (r, mpz_get_ui (r));
+ return;
+#if __GNU_MP_VERSION >= 2
+ case POPCNT:
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ { long int cnt;
+ cnt = mpz_popcount (r);
+ mpz_set_si (r, cnt);
+ }
+ return;
+ case HAMDIST:
+ { long int cnt;
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ cnt = mpz_hamdist (lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ mpz_set_si (r, cnt);
+ }
+ return;
+#endif
+ case LOG2:
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ { unsigned long int cnt;
+ if (mpz_sgn (r) <= 0)
+ {
+ error = "logarithm of non-positive number";
+ longjmp (errjmpbuf, 1);
+ }
+ cnt = mpz_sizeinbase (r, 2);
+ mpz_set_ui (r, cnt - 1);
+ }
+ return;
+ case LOG:
+ { unsigned long int cnt;
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ if (mpz_sgn (lhs) <= 0)
+ {
+ error = "logarithm of non-positive number";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ }
+ if (mpz_cmp_ui (rhs, 256) >= 0)
+ {
+ error = "logarithm base too large";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ }
+ cnt = mpz_sizeinbase (lhs, mpz_get_ui (rhs));
+ mpz_set_ui (r, cnt - 1);
+ mpz_clear (lhs); mpz_clear (rhs);
+ }
+ return;
+ case FERMAT:
+ {
+ unsigned long int t;
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ t = (unsigned long int) 1 << mpz_get_ui (lhs);
+ if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0 || t == 0)
+ {
+ error = "too large Mersenne number index";
+ mpz_clear (lhs);
+ longjmp (errjmpbuf, 1);
+ }
+ mpz_set_ui (r, 1);
+ mpz_mul_2exp (r, r, t);
+ mpz_add_ui (r, r, 1);
+ mpz_clear (lhs);
+ }
+ return;
+ case MERSENNE:
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0)
+ {
+ error = "too large Mersenne number index";
+ mpz_clear (lhs);
+ longjmp (errjmpbuf, 1);
+ }
+ mpz_set_ui (r, 1);
+ mpz_mul_2exp (r, r, mpz_get_ui (lhs));
+ mpz_sub_ui (r, r, 1);
+ mpz_clear (lhs);
+ return;
+ case FIBONACCI:
+ { mpz_t t;
+ unsigned long int n, i;
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
+ {
+ error = "Fibonacci index out of range";
+ mpz_clear (lhs);
+ longjmp (errjmpbuf, 1);
+ }
+ n = mpz_get_ui (lhs);
+ mpz_clear (lhs);
+
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ mpz_fib_ui (r, n);
+#else
+ mpz_init_set_ui (t, 1);
+ mpz_set_ui (r, 1);
+
+ if (n <= 2)
+ mpz_set_ui (r, 1);
+ else
+ {
+ for (i = 3; i <= n; i++)
+ {
+ mpz_add (t, t, r);
+ mpz_swap (t, r);
+ }
+ }
+ mpz_clear (t);
+#endif
+ }
+ return;
+ case RANDOM:
+ {
+ unsigned long int n;
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
+ {
+ error = "random number size out of range";
+ mpz_clear (lhs);
+ longjmp (errjmpbuf, 1);
+ }
+ n = mpz_get_ui (lhs);
+ mpz_clear (lhs);
+ mpz_urandomb (r, rstate, n);
+ }
+ return;
+ case NEXTPRIME:
+ {
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ mpz_nextprime (r, r);
+ }
+ return;
+ case BINOM:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ {
+ unsigned long int k;
+ if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
+ {
+ error = "k too large in (n over k) expression";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ }
+ k = mpz_get_ui (rhs);
+ mpz_bin_ui (r, lhs, k);
+ }
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case TIMING:
+ {
+ int t0;
+ t0 = cputime ();
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ printf ("time: %d\n", cputime () - t0);
+ }
+ return;
+ default:
+ abort ();
+ }
+}
+
+/* Evaluate the expression E modulo MOD and put the result in R. */
+void
+mpz_eval_mod_expr (mpz_ptr r, expr_t e, mpz_ptr mod)
+{
+ mpz_t lhs, rhs;
+
+ switch (e->op)
+ {
+ case POW:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_powm (r, lhs, rhs, mod);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case PLUS:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
+ mpz_eval_mod_expr (rhs, e->operands.ops.rhs, mod);
+ mpz_add (r, lhs, rhs);
+ if (mpz_cmp_si (r, 0L) < 0)
+ mpz_add (r, r, mod);
+ else if (mpz_cmp (r, mod) >= 0)
+ mpz_sub (r, r, mod);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case MINUS:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
+ mpz_eval_mod_expr (rhs, e->operands.ops.rhs, mod);
+ mpz_sub (r, lhs, rhs);
+ if (mpz_cmp_si (r, 0L) < 0)
+ mpz_add (r, r, mod);
+ else if (mpz_cmp (r, mod) >= 0)
+ mpz_sub (r, r, mod);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case MULT:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
+ mpz_eval_mod_expr (rhs, e->operands.ops.rhs, mod);
+ mpz_mul (r, lhs, rhs);
+ mpz_mod (r, r, mod);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ default:
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e);
+ mpz_mod (r, lhs, mod);
+ mpz_clear (lhs);
+ return;
+ }
+}
+
+void
+cleanup_and_exit (int sig)
+{
+ switch (sig) {
+#ifdef LIMIT_RESOURCE_USAGE
+ case SIGXCPU:
+ printf ("expression took too long to evaluate%s\n", newline);
+ break;
+#endif
+ case SIGFPE:
+ printf ("divide by zero%s\n", newline);
+ break;
+ default:
+ printf ("expression required too much memory to evaluate%s\n", newline);
+ break;
+ }
+ exit (-2);
+}
diff --git a/vendor/gmp-6.3.0/demos/primes.c b/vendor/gmp-6.3.0/demos/primes.c
new file mode 100644
index 0000000..3cb32e2
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/primes.c
@@ -0,0 +1,387 @@
+/* List and count primes.
+ Written by tege while on holiday in Rodupp, August 2001.
+ Between 10 and 500 times faster than previous program.
+
+Copyright 2001, 2002, 2006, 2012 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+
+/* IDEAS:
+ * Do not fill primes[] with real primes when the range [fr,to] is small,
+ when fr,to are relatively large. Fill primes[] with odd numbers instead.
+ [Probably a bad idea, since the primes[] array would become very large.]
+ * Separate small primes and large primes when sieving. Either the Montgomery
+ way (i.e., having a large array a multiple of L1 cache size), or just
+ separate loops for primes <= S and primes > S. The latter primes do not
+ require an inner loop, since they will touch the sieving array at most once.
+ * Pre-fill sieving array with an appropriately aligned ...00100100... pattern,
+ then omit 3 from primes array. (May require similar special handling of 3
+ as we now have for 2.)
+ * A large SIEVE_LIMIT currently implies very large memory usage, mainly due
+ to the sieving array in make_primelist, but also because of the primes[]
+ array. We might want to stage the program, using sieve_region/find_primes
+ to build primes[]. Make report() a function pointer, as part of achieving
+ this.
+ * Store primes[] as two arrays, one array with primes represented as delta
+ values using just 8 bits (if gaps are too big, store bogus primes!)
+ and one array with "rem" values. The latter needs 32-bit values.
+ * A new entry point, mpz_probab_prime_likely_p, would be useful.
+ * Improve command line syntax and versatility. "primes -f FROM -t TO",
+ allow either to be omitted for open interval. (But disallow
+ "primes -c -f FROM" since that would be infinity.) Allow printing a
+ limited *number* of primes using syntax like "primes -f FROM -n NUMBER".
+ * When looking for maxgaps, we should not perform any primality testing until
+ we find possible record gaps. Should speed up the searches tremendously.
+ */
+
+#include "gmp.h"
+
+struct primes
+{
+ unsigned int prime;
+ int rem;
+};
+
+struct primes *primes;
+unsigned long n_primes;
+
+void find_primes (unsigned char *, mpz_t, unsigned long, mpz_t);
+void sieve_region (unsigned char *, mpz_t, unsigned long);
+void make_primelist (unsigned long);
+
+int flag_print = 1;
+int flag_count = 0;
+int flag_maxgap = 0;
+unsigned long maxgap = 0;
+unsigned long total_primes = 0;
+
+void
+report (mpz_t prime)
+{
+ total_primes += 1;
+ if (flag_print)
+ {
+ mpz_out_str (stdout, 10, prime);
+ printf ("\n");
+ }
+ if (flag_maxgap)
+ {
+ static unsigned long prev_prime_low = 0;
+ unsigned long gap;
+ if (prev_prime_low != 0)
+ {
+ gap = mpz_get_ui (prime) - prev_prime_low;
+ if (maxgap < gap)
+ maxgap = gap;
+ }
+ prev_prime_low = mpz_get_ui (prime);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *progname = argv[0];
+ mpz_t fr, to;
+ mpz_t fr2, to2;
+ unsigned long sieve_lim;
+ unsigned long est_n_primes;
+ unsigned char *s;
+ mpz_t tmp;
+ mpz_t siev_sqr_lim;
+
+ while (argc != 1)
+ {
+ if (strcmp (argv[1], "-c") == 0)
+ {
+ flag_count = 1;
+ argv++;
+ argc--;
+ }
+ else if (strcmp (argv[1], "-p") == 0)
+ {
+ flag_print = 2;
+ argv++;
+ argc--;
+ }
+ else if (strcmp (argv[1], "-g") == 0)
+ {
+ flag_maxgap = 1;
+ argv++;
+ argc--;
+ }
+ else
+ break;
+ }
+
+ if (flag_count || flag_maxgap)
+ flag_print--; /* clear unless an explicit -p */
+
+ mpz_init (fr);
+ mpz_init (to);
+ mpz_init (fr2);
+ mpz_init (to2);
+
+ if (argc == 3)
+ {
+ mpz_set_str (fr, argv[1], 0);
+ if (argv[2][0] == '+')
+ {
+ mpz_set_str (to, argv[2] + 1, 0);
+ mpz_add (to, to, fr);
+ }
+ else
+ mpz_set_str (to, argv[2], 0);
+ }
+ else if (argc == 2)
+ {
+ mpz_set_ui (fr, 0);
+ mpz_set_str (to, argv[1], 0);
+ }
+ else
+ {
+ fprintf (stderr, "usage: %s [-c] [-p] [-g] [from [+]]to\n", progname);
+ exit (1);
+ }
+
+ mpz_set (fr2, fr);
+ if (mpz_cmp_ui (fr2, 3) < 0)
+ {
+ mpz_set_ui (fr2, 2);
+ report (fr2);
+ mpz_set_ui (fr2, 3);
+ }
+ mpz_setbit (fr2, 0); /* make odd */
+ mpz_sub_ui (to2, to, 1);
+ mpz_setbit (to2, 0); /* make odd */
+
+ mpz_init (tmp);
+ mpz_init (siev_sqr_lim);
+
+ mpz_sqrt (tmp, to2);
+#define SIEVE_LIMIT 10000000
+ if (mpz_cmp_ui (tmp, SIEVE_LIMIT) < 0)
+ {
+ sieve_lim = mpz_get_ui (tmp);
+ }
+ else
+ {
+ sieve_lim = SIEVE_LIMIT;
+ mpz_sub (tmp, to2, fr2);
+ if (mpz_cmp_ui (tmp, sieve_lim) < 0)
+ sieve_lim = mpz_get_ui (tmp); /* limit sieving for small ranges */
+ }
+ mpz_set_ui (siev_sqr_lim, sieve_lim + 1);
+ mpz_mul_ui (siev_sqr_lim, siev_sqr_lim, sieve_lim + 1);
+
+ est_n_primes = (size_t) (sieve_lim / log((double) sieve_lim) * 1.13) + 10;
+ primes = malloc (est_n_primes * sizeof primes[0]);
+ make_primelist (sieve_lim);
+ assert (est_n_primes >= n_primes);
+
+#if DEBUG
+ printf ("sieve_lim = %lu\n", sieve_lim);
+ printf ("n_primes = %lu (3..%u)\n",
+ n_primes, primes[n_primes - 1].prime);
+#endif
+
+#define S (1 << 15) /* FIXME: Figure out L1 cache size */
+ s = malloc (S/2);
+ while (mpz_cmp (fr2, to2) <= 0)
+ {
+ unsigned long rsize;
+ rsize = S;
+ mpz_add_ui (tmp, fr2, rsize);
+ if (mpz_cmp (tmp, to2) > 0)
+ {
+ mpz_sub (tmp, to2, fr2);
+ rsize = mpz_get_ui (tmp) + 2;
+ }
+#if DEBUG
+ printf ("Sieving region ["); mpz_out_str (stdout, 10, fr2);
+ printf (","); mpz_add_ui (tmp, fr2, rsize - 2);
+ mpz_out_str (stdout, 10, tmp); printf ("]\n");
+#endif
+ sieve_region (s, fr2, rsize);
+ find_primes (s, fr2, rsize / 2, siev_sqr_lim);
+
+ mpz_add_ui (fr2, fr2, S);
+ }
+ free (s);
+
+ if (flag_count)
+ printf ("Pi(interval) = %lu\n", total_primes);
+
+ if (flag_maxgap)
+ printf ("max gap: %lu\n", maxgap);
+
+ return 0;
+}
+
+/* Find primes in region [fr,fr+rsize). Requires that fr is odd and that
+ rsize is even. The sieving array s should be aligned for "long int" and
+ have rsize/2 entries, rounded up to the nearest multiple of "long int". */
+void
+sieve_region (unsigned char *s, mpz_t fr, unsigned long rsize)
+{
+ unsigned long ssize = rsize / 2;
+ unsigned long start, start2, prime;
+ unsigned long i;
+ mpz_t tmp;
+
+ mpz_init (tmp);
+
+#if 0
+ /* initialize sieving array */
+ for (ii = 0; ii < (ssize + sizeof (long) - 1) / sizeof (long); ii++)
+ ((long *) s) [ii] = ~0L;
+#else
+ {
+ long k;
+ long *se = (long *) (s + ((ssize + sizeof (long) - 1) & -sizeof (long)));
+ for (k = -((ssize + sizeof (long) - 1) / sizeof (long)); k < 0; k++)
+ se[k] = ~0L;
+ }
+#endif
+
+ for (i = 0; i < n_primes; i++)
+ {
+ prime = primes[i].prime;
+
+ if (primes[i].rem >= 0)
+ {
+ start2 = primes[i].rem;
+ }
+ else
+ {
+ mpz_set_ui (tmp, prime);
+ mpz_mul_ui (tmp, tmp, prime);
+ if (mpz_cmp (fr, tmp) <= 0)
+ {
+ mpz_sub (tmp, tmp, fr);
+ if (mpz_cmp_ui (tmp, 2 * ssize) > 0)
+ break; /* avoid overflow at next line, also speedup */
+ start = mpz_get_ui (tmp);
+ }
+ else
+ {
+ start = (prime - mpz_tdiv_ui (fr, prime)) % prime;
+ if (start % 2 != 0)
+ start += prime; /* adjust if even divisible */
+ }
+ start2 = start / 2;
+ }
+
+#if 0
+ for (ii = start2; ii < ssize; ii += prime)
+ s[ii] = 0;
+ primes[i].rem = ii - ssize;
+#else
+ {
+ long k;
+ unsigned char *se = s + ssize; /* point just beyond sieving range */
+ for (k = start2 - ssize; k < 0; k += prime)
+ se[k] = 0;
+ primes[i].rem = k;
+ }
+#endif
+ }
+ mpz_clear (tmp);
+}
+
+/* Find primes in region [fr,fr+rsize), using the previously sieved s[]. */
+void
+find_primes (unsigned char *s, mpz_t fr, unsigned long ssize,
+ mpz_t siev_sqr_lim)
+{
+ unsigned long j, ij;
+ mpz_t tmp;
+
+ mpz_init (tmp);
+ for (j = 0; j < (ssize + sizeof (long) - 1) / sizeof (long); j++)
+ {
+ if (((long *) s) [j] != 0)
+ {
+ for (ij = 0; ij < sizeof (long); ij++)
+ {
+ if (s[j * sizeof (long) + ij] != 0)
+ {
+ if (j * sizeof (long) + ij >= ssize)
+ goto out;
+ mpz_add_ui (tmp, fr, (j * sizeof (long) + ij) * 2);
+ if (mpz_cmp (tmp, siev_sqr_lim) < 0 ||
+ mpz_probab_prime_p (tmp, 10))
+ report (tmp);
+ }
+ }
+ }
+ }
+ out:
+ mpz_clear (tmp);
+}
+
+/* Generate a list of primes and store in the global array primes[]. */
+void
+make_primelist (unsigned long maxprime)
+{
+#if 1
+ unsigned char *s;
+ unsigned long ssize = maxprime / 2;
+ unsigned long i, ii, j;
+
+ s = malloc (ssize);
+ memset (s, ~0, ssize);
+ for (i = 3; ; i += 2)
+ {
+ unsigned long isqr = i * i;
+ if (isqr >= maxprime)
+ break;
+ if (s[i * i / 2 - 1] == 0)
+ continue; /* only sieve with primes */
+ for (ii = i * i / 2 - 1; ii < ssize; ii += i)
+ s[ii] = 0;
+ }
+ n_primes = 0;
+ for (j = 0; j < ssize; j++)
+ {
+ if (s[j] != 0)
+ {
+ primes[n_primes].prime = j * 2 + 3;
+ primes[n_primes].rem = -1;
+ n_primes++;
+ }
+ }
+ /* FIXME: This should not be needed if fencepost errors were fixed... */
+ if (primes[n_primes - 1].prime > maxprime)
+ n_primes--;
+ free (s);
+#else
+ unsigned long i;
+ n_primes = 0;
+ for (i = 3; i <= maxprime; i += 2)
+ {
+ if (i < 7 || (i % 3 != 0 && i % 5 != 0 && i % 7 != 0))
+ {
+ primes[n_primes].prime = i;
+ primes[n_primes].rem = -1;
+ n_primes++;
+ }
+ }
+#endif
+}
diff --git a/vendor/gmp-6.3.0/demos/primes.h b/vendor/gmp-6.3.0/demos/primes.h
new file mode 100644
index 0000000..b85c7e1
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/primes.h
@@ -0,0 +1,552 @@
+P( 1, 0xaaaaaaaaaaaaaaabUL, 0x5555555555555555UL) /* 3 */
+P( 2, 0xcccccccccccccccdUL, 0x3333333333333333UL) /* 5 */
+P( 2, 0x6db6db6db6db6db7UL, 0x2492492492492492UL) /* 7 */
+P( 4, 0x2e8ba2e8ba2e8ba3UL, 0x1745d1745d1745d1UL) /* 11 */
+P( 2, 0x4ec4ec4ec4ec4ec5UL, 0x13b13b13b13b13b1UL) /* 13 */
+P( 4, 0xf0f0f0f0f0f0f0f1UL, 0x0f0f0f0f0f0f0f0fUL) /* 17 */
+P( 2, 0x86bca1af286bca1bUL, 0x0d79435e50d79435UL) /* 19 */
+P( 4, 0xd37a6f4de9bd37a7UL, 0x0b21642c8590b216UL) /* 23 */
+P( 6, 0x34f72c234f72c235UL, 0x08d3dcb08d3dcb08UL) /* 29 */
+P( 2, 0xef7bdef7bdef7bdfUL, 0x0842108421084210UL) /* 31 */
+P( 6, 0x14c1bacf914c1badUL, 0x06eb3e45306eb3e4UL) /* 37 */
+P( 4, 0x8f9c18f9c18f9c19UL, 0x063e7063e7063e70UL) /* 41 */
+P( 2, 0x82fa0be82fa0be83UL, 0x05f417d05f417d05UL) /* 43 */
+P( 4, 0x51b3bea3677d46cfUL, 0x0572620ae4c415c9UL) /* 47 */
+P( 6, 0x21cfb2b78c13521dUL, 0x04d4873ecade304dUL) /* 53 */
+P( 6, 0xcbeea4e1a08ad8f3UL, 0x0456c797dd49c341UL) /* 59 */
+P( 2, 0x4fbcda3ac10c9715UL, 0x04325c53ef368eb0UL) /* 61 */
+P( 6, 0xf0b7672a07a44c6bUL, 0x03d226357e16ece5UL) /* 67 */
+P( 4, 0x193d4bb7e327a977UL, 0x039b0ad12073615aUL) /* 71 */
+P( 2, 0x7e3f1f8fc7e3f1f9UL, 0x0381c0e070381c0eUL) /* 73 */
+P( 6, 0x9b8b577e613716afUL, 0x033d91d2a2067b23UL) /* 79 */
+P( 4, 0xa3784a062b2e43dbUL, 0x03159721ed7e7534UL) /* 83 */
+P( 6, 0xf47e8fd1fa3f47e9UL, 0x02e05c0b81702e05UL) /* 89 */
+P( 8, 0xa3a0fd5c5f02a3a1UL, 0x02a3a0fd5c5f02a3UL) /* 97 */
+P( 4, 0x3a4c0a237c32b16dUL, 0x0288df0cac5b3f5dUL) /* 101 */
+P( 2, 0xdab7ec1dd3431b57UL, 0x027c45979c95204fUL) /* 103 */
+P( 4, 0x77a04c8f8d28ac43UL, 0x02647c69456217ecUL) /* 107 */
+P( 2, 0xa6c0964fda6c0965UL, 0x02593f69b02593f6UL) /* 109 */
+P( 4, 0x90fdbc090fdbc091UL, 0x0243f6f0243f6f02UL) /* 113 */
+P(14, 0x7efdfbf7efdfbf7fUL, 0x0204081020408102UL) /* 127 */
+P( 4, 0x03e88cb3c9484e2bUL, 0x01f44659e4a42715UL) /* 131 */
+P( 6, 0xe21a291c077975b9UL, 0x01de5d6e3f8868a4UL) /* 137 */
+P( 2, 0x3aef6ca970586723UL, 0x01d77b654b82c339UL) /* 139 */
+P(10, 0xdf5b0f768ce2cabdUL, 0x01b7d6c3dda338b2UL) /* 149 */
+P( 2, 0x6fe4dfc9bf937f27UL, 0x01b2036406c80d90UL) /* 151 */
+P( 6, 0x5b4fe5e92c0685b5UL, 0x01a16d3f97a4b01aUL) /* 157 */
+P( 6, 0x1f693a1c451ab30bUL, 0x01920fb49d0e228dUL) /* 163 */
+P( 4, 0x8d07aa27db35a717UL, 0x01886e5f0abb0499UL) /* 167 */
+P( 6, 0x882383b30d516325UL, 0x017ad2208e0ecc35UL) /* 173 */
+P( 6, 0xed6866f8d962ae7bUL, 0x016e1f76b4337c6cUL) /* 179 */
+P( 2, 0x3454dca410f8ed9dUL, 0x016a13cd15372904UL) /* 181 */
+P(10, 0x1d7ca632ee936f3fUL, 0x01571ed3c506b39aUL) /* 191 */
+P( 2, 0x70bf015390948f41UL, 0x015390948f40feacUL) /* 193 */
+P( 4, 0xc96bdb9d3d137e0dUL, 0x014cab88725af6e7UL) /* 197 */
+P( 2, 0x2697cc8aef46c0f7UL, 0x0149539e3b2d066eUL) /* 199 */
+P(12, 0xc0e8f2a76e68575bUL, 0x013698df3de07479UL) /* 211 */
+P(12, 0x687763dfdb43bb1fUL, 0x0125e22708092f11UL) /* 223 */
+P( 4, 0x1b10ea929ba144cbUL, 0x0120b470c67c0d88UL) /* 227 */
+P( 2, 0x1d10c4c0478bbcedUL, 0x011e2ef3b3fb8744UL) /* 229 */
+P( 4, 0x63fb9aeb1fdcd759UL, 0x0119453808ca29c0UL) /* 233 */
+P( 6, 0x64afaa4f437b2e0fUL, 0x0112358e75d30336UL) /* 239 */
+P( 2, 0xf010fef010fef011UL, 0x010fef010fef010fUL) /* 241 */
+P(10, 0x28cbfbeb9a020a33UL, 0x0105197f7d734041UL) /* 251 */
+P( 6, 0xff00ff00ff00ff01UL, 0x00ff00ff00ff00ffUL) /* 257 */
+P( 6, 0xd624fd1470e99cb7UL, 0x00f92fb2211855a8UL) /* 263 */
+P( 6, 0x8fb3ddbd6205b5c5UL, 0x00f3a0d52cba8723UL) /* 269 */
+P( 2, 0xd57da36ca27acdefUL, 0x00f1d48bcee0d399UL) /* 271 */
+P( 6, 0xee70c03b25e4463dUL, 0x00ec979118f3fc4dUL) /* 277 */
+P( 4, 0xc5b1a6b80749cb29UL, 0x00e939651fe2d8d3UL) /* 281 */
+P( 2, 0x47768073c9b97113UL, 0x00e79372e225fe30UL) /* 283 */
+P(10, 0x2591e94884ce32adUL, 0x00dfac1f74346c57UL) /* 293 */
+P(14, 0xf02806abc74be1fbUL, 0x00d578e97c3f5fe5UL) /* 307 */
+P( 4, 0x7ec3e8f3a7198487UL, 0x00d2ba083b445250UL) /* 311 */
+P( 2, 0x58550f8a39409d09UL, 0x00d161543e28e502UL) /* 313 */
+P( 4, 0xec9e48ae6f71de15UL, 0x00cebcf8bb5b4169UL) /* 317 */
+P(14, 0x2ff3a018bfce8063UL, 0x00c5fe740317f9d0UL) /* 331 */
+P( 6, 0x7f9ec3fcf61fe7b1UL, 0x00c2780613c0309eUL) /* 337 */
+P(10, 0x89f5abe570e046d3UL, 0x00bcdd535db1cc5bUL) /* 347 */
+P( 2, 0xda971b23f1545af5UL, 0x00bbc8408cd63069UL) /* 349 */
+P( 4, 0x79d5f00b9a7862a1UL, 0x00b9a7862a0ff465UL) /* 353 */
+P( 6, 0x4dba1df32a128a57UL, 0x00b68d31340e4307UL) /* 359 */
+P( 8, 0x87530217b7747d8fUL, 0x00b2927c29da5519UL) /* 367 */
+P( 6, 0x30baae53bb5e06ddUL, 0x00afb321a1496fdfUL) /* 373 */
+P( 6, 0xee70206c12e9b5b3UL, 0x00aceb0f891e6551UL) /* 379 */
+P( 4, 0xcdde9462ec9dbe7fUL, 0x00ab1cbdd3e2970fUL) /* 383 */
+P( 6, 0xafb64b05ec41cf4dUL, 0x00a87917088e262bUL) /* 389 */
+P( 8, 0x02944ff5aec02945UL, 0x00a513fd6bb00a51UL) /* 397 */
+P( 4, 0x2cb033128382df71UL, 0x00a36e71a2cb0331UL) /* 401 */
+P( 8, 0x1ccacc0c84b1c2a9UL, 0x00a03c1688732b30UL) /* 409 */
+P(10, 0x19a93db575eb3a0bUL, 0x009c69169b30446dUL) /* 419 */
+P( 2, 0xcebeef94fa86fe2dUL, 0x009baade8e4a2f6eUL) /* 421 */
+P(10, 0x6faa77fb3f8df54fUL, 0x00980e4156201301UL) /* 431 */
+P( 2, 0x68a58af00975a751UL, 0x00975a750ff68a58UL) /* 433 */
+P( 6, 0xd56e36d0c3efac07UL, 0x009548e4979e0829UL) /* 439 */
+P( 4, 0xd8b44c47a8299b73UL, 0x0093efd1c50e726bUL) /* 443 */
+P( 6, 0x02d9ccaf9ba70e41UL, 0x0091f5bcb8bb02d9UL) /* 449 */
+P( 8, 0x0985e1c023d9e879UL, 0x008f67a1e3fdc261UL) /* 457 */
+P( 4, 0x2a343316c494d305UL, 0x008e2917e0e702c6UL) /* 461 */
+P( 2, 0x70cb7916ab67652fUL, 0x008d8be33f95d715UL) /* 463 */
+P( 4, 0xd398f132fb10fe5bUL, 0x008c55841c815ed5UL) /* 467 */
+P(12, 0x6f2a38a6bf54fa1fUL, 0x0088d180cd3a4133UL) /* 479 */
+P( 8, 0x211df689b98f81d7UL, 0x00869222b1acf1ceUL) /* 487 */
+P( 4, 0x0e994983e90f1ec3UL, 0x0085797b917765abUL) /* 491 */
+P( 8, 0xad671e44bed87f3bUL, 0x008355ace3c897dbUL) /* 499 */
+P( 4, 0xf9623a0516e70fc7UL, 0x00824a4e60b3262bUL) /* 503 */
+P( 6, 0x4b7129be9dece355UL, 0x0080c121b28bd1baUL) /* 509 */
+P(12, 0x190f3b7473f62c39UL, 0x007dc9f3397d4c29UL) /* 521 */
+P( 2, 0x63dacc9aad46f9a3UL, 0x007d4ece8fe88139UL) /* 523 */
+P(18, 0xc1108fda24e8d035UL, 0x0079237d65bcce50UL) /* 541 */
+P( 6, 0xb77578472319bd8bUL, 0x0077cf53c5f7936cUL) /* 547 */
+P(10, 0x473d20a1c7ed9da5UL, 0x0075a8accfbdd11eUL) /* 557 */
+P( 6, 0xfbe85af0fea2c8fbUL, 0x007467ac557c228eUL) /* 563 */
+P( 6, 0x58a1f7e6ce0f4c09UL, 0x00732d70ed8db8e9UL) /* 569 */
+P( 2, 0x1a00e58c544986f3UL, 0x0072c62a24c3797fUL) /* 571 */
+P( 6, 0x7194a17f55a10dc1UL, 0x007194a17f55a10dUL) /* 577 */
+P(10, 0x7084944785e33763UL, 0x006fa549b41da7e7UL) /* 587 */
+P( 6, 0xba10679bd84886b1UL, 0x006e8419e6f61221UL) /* 593 */
+P( 6, 0xebe9c6bb31260967UL, 0x006d68b5356c207bUL) /* 599 */
+P( 2, 0x97a3fe4bd1ff25e9UL, 0x006d0b803685c01bUL) /* 601 */
+P( 6, 0x6c6388395b84d99fUL, 0x006bf790a8b2d207UL) /* 607 */
+P( 6, 0x8c51da6a1335df6dUL, 0x006ae907ef4b96c2UL) /* 613 */
+P( 4, 0x46f3234475d5add9UL, 0x006a37991a23aeadUL) /* 617 */
+P( 2, 0x905605ca3c619a43UL, 0x0069dfbdd4295b66UL) /* 619 */
+P(12, 0xcee8dff304767747UL, 0x0067dc4c45c8033eUL) /* 631 */
+P(10, 0xff99c27f00663d81UL, 0x00663d80ff99c27fUL) /* 641 */
+P( 2, 0xacca407f671ddc2bUL, 0x0065ec17e3559948UL) /* 643 */
+P( 4, 0xe71298bac1e12337UL, 0x00654ac835cfba5cUL) /* 647 */
+P( 6, 0xfa1e94309cd09045UL, 0x00645c854ae10772UL) /* 653 */
+P( 6, 0xbebccb8e91496b9bUL, 0x006372990e5f901fUL) /* 659 */
+P( 2, 0x312fa30cc7d7b8bdUL, 0x006325913c07beefUL) /* 661 */
+P(12, 0x6160ff9e9f006161UL, 0x006160ff9e9f0061UL) /* 673 */
+P( 4, 0x6b03673b5e28152dUL, 0x0060cdb520e5e88eUL) /* 677 */
+P( 6, 0xfe802ffa00bfe803UL, 0x005ff4017fd005ffUL) /* 683 */
+P( 8, 0xe66fe25c9e907c7bUL, 0x005ed79e31a4dccdUL) /* 691 */
+P(10, 0x3f8b236c76528895UL, 0x005d7d42d48ac5efUL) /* 701 */
+P( 8, 0xf6f923bf01ce2c0dUL, 0x005c6f35ccba5028UL) /* 709 */
+P(10, 0x6c3d3d98bed7c42fUL, 0x005b2618ec6ad0a5UL) /* 719 */
+P( 8, 0x30981efcd4b010e7UL, 0x005a2553748e42e7UL) /* 727 */
+P( 6, 0x6f691fc81ebbe575UL, 0x0059686cf744cd5bUL) /* 733 */
+P( 6, 0xb10480ddb47b52cbUL, 0x0058ae97bab79976UL) /* 739 */
+P( 4, 0x74cd59ed64f3f0d7UL, 0x0058345f1876865fUL) /* 743 */
+P( 8, 0x0105cb81316d6c0fUL, 0x005743d5bb24795aUL) /* 751 */
+P( 6, 0x9be64c6d91c1195dUL, 0x005692c4d1ab74abUL) /* 757 */
+P( 4, 0x71b3f945a27b1f49UL, 0x00561e46a4d5f337UL) /* 761 */
+P( 8, 0x77d80d50e508fd01UL, 0x005538ed06533997UL) /* 769 */
+P( 4, 0xa5eb778e133551cdUL, 0x0054c807f2c0bec2UL) /* 773 */
+P(14, 0x18657d3c2d8a3f1bUL, 0x005345efbc572d36UL) /* 787 */
+P(10, 0x2e40e220c34ad735UL, 0x00523a758f941345UL) /* 797 */
+P(12, 0xa76593c70a714919UL, 0x005102370f816c89UL) /* 809 */
+P( 2, 0x1eef452124eea383UL, 0x0050cf129fb94acfUL) /* 811 */
+P(10, 0x38206dc242ba771dUL, 0x004fd31941cafdd1UL) /* 821 */
+P( 2, 0x4cd4c35807772287UL, 0x004fa1704aa75945UL) /* 823 */
+P( 4, 0x83de917d5e69ddf3UL, 0x004f3ed6d45a63adUL) /* 827 */
+P( 2, 0x882ef0403b4a6c15UL, 0x004f0de57154ebedUL) /* 829 */
+P(10, 0xf8fb6c51c606b677UL, 0x004e1cae8815f811UL) /* 839 */
+P(14, 0xb4abaac446d3e1fdUL, 0x004cd47ba5f6ff19UL) /* 853 */
+P( 4, 0xa9f83bbe484a14e9UL, 0x004c78ae734df709UL) /* 857 */
+P( 2, 0x0bebbc0d1ce874d3UL, 0x004c4b19ed85cfb8UL) /* 859 */
+P( 4, 0xbd418eaf0473189fUL, 0x004bf093221d1218UL) /* 863 */
+P(14, 0x44e3af6f372b7e65UL, 0x004aba3c21dc633fUL) /* 877 */
+P( 4, 0xc87fdace4f9e5d91UL, 0x004a6360c344de00UL) /* 881 */
+P( 2, 0xec93479c446bd9bbUL, 0x004a383e9f74d68aUL) /* 883 */
+P( 4, 0xdac4d592e777c647UL, 0x0049e28fbabb9940UL) /* 887 */
+P(20, 0xa63ea8c8f61f0c23UL, 0x0048417b57c78cd7UL) /* 907 */
+P( 4, 0xe476062ea5cbbb6fUL, 0x0047f043713f3a2bUL) /* 911 */
+P( 8, 0xdf68761c69daac27UL, 0x00474ff2a10281cfUL) /* 919 */
+P(10, 0xb813d737637aa061UL, 0x00468b6f9a978f91UL) /* 929 */
+P( 8, 0xa3a77aac1fb15099UL, 0x0045f13f1caff2e2UL) /* 937 */
+P( 4, 0x17f0c3e0712c5825UL, 0x0045a5228cec23e9UL) /* 941 */
+P( 6, 0xfd912a70ff30637bUL, 0x0045342c556c66b9UL) /* 947 */
+P( 6, 0xfbb3b5dc01131289UL, 0x0044c4a23feeced7UL) /* 953 */
+P(14, 0x856d560a0f5acdf7UL, 0x0043c5c20d3c9fe6UL) /* 967 */
+P( 4, 0x96472f314d3f89e3UL, 0x00437e494b239798UL) /* 971 */
+P( 6, 0xa76f5c7ed2253531UL, 0x0043142d118e47cbUL) /* 977 */
+P( 6, 0x816eae7c7bf69fe7UL, 0x0042ab5c73a13458UL) /* 983 */
+P( 8, 0xb6a2bea4cfb1781fUL, 0x004221950db0f3dbUL) /* 991 */
+P( 6, 0xa3900c53318e81edUL, 0x0041bbb2f80a4553UL) /* 997 */
+P(12, 0x60aa7f5d9f148d11UL, 0x0040f391612c6680UL) /* 1009 */
+P( 4, 0x6be8c0102c7a505dUL, 0x0040b1e94173fefdUL) /* 1013 */
+P( 6, 0x8ff3f0ed28728f33UL, 0x004050647d9d0445UL) /* 1019 */
+P( 2, 0x680e0a87e5ec7155UL, 0x004030241b144f3bUL) /* 1021 */
+P(10, 0xbbf70fa49fe829b7UL, 0x003f90c2ab542cb1UL) /* 1031 */
+P( 2, 0xd69d1e7b6a50ca39UL, 0x003f71412d59f597UL) /* 1033 */
+P( 6, 0x1a1e0f46b6d26aefUL, 0x003f137701b98841UL) /* 1039 */
+P(10, 0x7429f9a7a8251829UL, 0x003e79886b60e278UL) /* 1049 */
+P( 2, 0xd9c2219d1b863613UL, 0x003e5b1916a7181dUL) /* 1051 */
+P(10, 0x91406c1820d077adUL, 0x003dc4a50968f524UL) /* 1061 */
+P( 2, 0x521f4ec02e3d2b97UL, 0x003da6e4c9550321UL) /* 1063 */
+P( 6, 0xbb8283b63dc8eba5UL, 0x003d4e4f06f1def3UL) /* 1069 */
+P(18, 0x431eda153229ebbfUL, 0x003c4a6bdd24f9a4UL) /* 1087 */
+P( 4, 0xaf0bf78d7e01686bUL, 0x003c11d54b525c73UL) /* 1091 */
+P( 2, 0xa9ced0742c086e8dUL, 0x003bf5b1c5721065UL) /* 1093 */
+P( 4, 0xc26458ad9f632df9UL, 0x003bbdb9862f23b4UL) /* 1097 */
+P( 6, 0xbbff1255dff892afUL, 0x003b6a8801db5440UL) /* 1103 */
+P( 6, 0xcbd49a333f04d8fdUL, 0x003b183cf0fed886UL) /* 1109 */
+P( 8, 0xec84ed6f9cfdeff5UL, 0x003aabe394bdc3f4UL) /* 1117 */
+P( 6, 0x97980cc40bda9d4bUL, 0x003a5ba3e76156daUL) /* 1123 */
+P( 6, 0x777f34d524f5cbd9UL, 0x003a0c3e953378dbUL) /* 1129 */
+P(22, 0x2797051d94cbbb7fUL, 0x0038f03561320b1eUL) /* 1151 */
+P( 2, 0xea769051b4f43b81UL, 0x0038d6ecaef5908aUL) /* 1153 */
+P(10, 0xce7910f3034d4323UL, 0x003859cf221e6069UL) /* 1163 */
+P( 8, 0x92791d1374f5b99bUL, 0x0037f7415dc9588aUL) /* 1171 */
+P(10, 0x89a5645cc68ea1b5UL, 0x00377df0d3902626UL) /* 1181 */
+P( 6, 0x5f8aacf796c0cf0bUL, 0x00373622136907faUL) /* 1187 */
+P( 6, 0xf2e90a15e33edf99UL, 0x0036ef0c3b39b92fUL) /* 1193 */
+P( 8, 0x8e99e5feb897c451UL, 0x0036915f47d55e6dUL) /* 1201 */
+P(12, 0xaca2eda38fb91695UL, 0x0036072cf3f866fdUL) /* 1213 */
+P( 4, 0x5d9b737be5ea8b41UL, 0x0035d9b737be5ea8UL) /* 1217 */
+P( 6, 0x4aefe1db93fd7cf7UL, 0x0035961559cc81c7UL) /* 1223 */
+P( 6, 0xa0994ef20b3f8805UL, 0x0035531c897a4592UL) /* 1229 */
+P( 2, 0x103890bda912822fUL, 0x00353ceebd3e98a4UL) /* 1231 */
+P( 6, 0xb441659d13a9147dUL, 0x0034fad381585e5eUL) /* 1237 */
+P(12, 0x1e2134440c4c3f21UL, 0x00347884d1103130UL) /* 1249 */
+P(10, 0x263a27727a6883c3UL, 0x00340dd3ac39bf56UL) /* 1259 */
+P(18, 0x78e221472ab33855UL, 0x003351fdfecc140cUL) /* 1277 */
+P( 2, 0x95eac88e82e6faffUL, 0x00333d72b089b524UL) /* 1279 */
+P( 4, 0xf66c258317be8dabUL, 0x0033148d44d6b261UL) /* 1283 */
+P( 6, 0x09ee202c7cb91939UL, 0x0032d7aef8412458UL) /* 1289 */
+P( 2, 0x8d2fca1042a09ea3UL, 0x0032c3850e79c0f1UL) /* 1291 */
+P( 6, 0x82779c856d8b8bf1UL, 0x00328766d59048a2UL) /* 1297 */
+P( 4, 0x3879361cba8a223dUL, 0x00325fa18cb11833UL) /* 1301 */
+P( 2, 0xf23f43639c3182a7UL, 0x00324bd659327e22UL) /* 1303 */
+P( 4, 0xa03868fc474bcd13UL, 0x0032246e784360f4UL) /* 1307 */
+P(12, 0x651e78b8c5311a97UL, 0x0031afa5f1a33a08UL) /* 1319 */
+P( 2, 0x8ffce639c00c6719UL, 0x00319c63ff398e70UL) /* 1321 */
+P( 6, 0xf7b460754b0b61cfUL, 0x003162f7519a86a7UL) /* 1327 */
+P(34, 0x7b03f3359b8e63b1UL, 0x0030271fc9d3fc3cUL) /* 1361 */
+P( 6, 0xa55c5326041eb667UL, 0x002ff104ae89750bUL) /* 1367 */
+P( 6, 0x647f88ab896a76f5UL, 0x002fbb62a236d133UL) /* 1373 */
+P( 8, 0x8fd971434a55a46dUL, 0x002f74997d2070b4UL) /* 1381 */
+P(18, 0x9fbf969958046447UL, 0x002ed84aa8b6fce3UL) /* 1399 */
+P(10, 0x9986feba69be3a81UL, 0x002e832df7a46dbdUL) /* 1409 */
+P(14, 0xa668b3e6d053796fUL, 0x002e0e0846857cabUL) /* 1423 */
+P( 4, 0x97694e6589f4e09bUL, 0x002decfbdfb55ee6UL) /* 1427 */
+P( 2, 0x37890c00b7721dbdUL, 0x002ddc876f3ff488UL) /* 1429 */
+P( 4, 0x5ac094a235f37ea9UL, 0x002dbbc1d4c482c4UL) /* 1433 */
+P( 6, 0x31cff775f2d5d65fUL, 0x002d8af0e0de0556UL) /* 1439 */
+P( 8, 0xddad8e6b36505217UL, 0x002d4a7b7d14b30aUL) /* 1447 */
+P( 4, 0x5a27df897062cd03UL, 0x002d2a85073bcf4eUL) /* 1451 */
+P( 2, 0xe2396fe0fdb5a625UL, 0x002d1a9ab13e8be4UL) /* 1453 */
+P( 6, 0xb352a4957e82317bUL, 0x002ceb1eb4b9fd8bUL) /* 1459 */
+P(12, 0xd8ab3f2c60c2ea3fUL, 0x002c8d503a79794cUL) /* 1471 */
+P(10, 0x6893f702f0452479UL, 0x002c404d708784edUL) /* 1481 */
+P( 2, 0x9686fdc182acf7e3UL, 0x002c31066315ec52UL) /* 1483 */
+P( 4, 0x6854037173dce12fUL, 0x002c1297d80f2664UL) /* 1487 */
+P( 2, 0x7f0ded1685c27331UL, 0x002c037044c55f6bUL) /* 1489 */
+P( 4, 0xeeda72e1fe490b7dUL, 0x002be5404cd13086UL) /* 1493 */
+P( 6, 0x9e7bfc959a8e6e53UL, 0x002bb845adaf0cceUL) /* 1499 */
+P(12, 0x49b314d6d4753dd7UL, 0x002b5f62c639f16dUL) /* 1511 */
+P(12, 0x2e8f8c5ac4aa1b3bUL, 0x002b07e6734f2b88UL) /* 1523 */
+P( 8, 0xb8ef723481163d33UL, 0x002ace569d8342b7UL) /* 1531 */
+P(12, 0x6a2ec96a594287b7UL, 0x002a791d5dbd4dcfUL) /* 1543 */
+P( 6, 0xdba41c6d13aab8c5UL, 0x002a4eff8113017cUL) /* 1549 */
+P( 4, 0xc2adbe648dc3aaf1UL, 0x002a3319e156df32UL) /* 1553 */
+P( 6, 0x87a2bade565f91a7UL, 0x002a0986286526eaUL) /* 1559 */
+P( 8, 0x4d6fe8798c01f5dfUL, 0x0029d29551d91e39UL) /* 1567 */
+P( 4, 0x3791310c8c23d98bUL, 0x0029b7529e109f0aUL) /* 1571 */
+P( 8, 0xf80e446b01228883UL, 0x00298137491ea465UL) /* 1579 */
+P( 4, 0x9aed1436fbf500cfUL, 0x0029665e1eb9f9daUL) /* 1583 */
+P(14, 0x7839b54cc8b24115UL, 0x002909752e019a5eUL) /* 1597 */
+P( 4, 0xc128c646ad0309c1UL, 0x0028ef35e2e5efb0UL) /* 1601 */
+P( 6, 0x14de631624a3c377UL, 0x0028c815aa4b8278UL) /* 1607 */
+P( 2, 0x3f7b9fe68b0ecbf9UL, 0x0028bb1b867199daUL) /* 1609 */
+P( 4, 0x284ffd75ec00a285UL, 0x0028a13ff5d7b002UL) /* 1613 */
+P( 6, 0x37803cb80dea2ddbUL, 0x00287ab3f173e755UL) /* 1619 */
+P( 2, 0x86b63f7c9ac4c6fdUL, 0x00286dead67713bdUL) /* 1621 */
+P( 6, 0x8b6851d1bd99b9d3UL, 0x002847bfcda6503eUL) /* 1627 */
+P(10, 0xb62fda77ca343b6dUL, 0x002808c1ea6b4777UL) /* 1637 */
+P(20, 0x1f0dc009e34383c9UL, 0x00278d0e0f23ff61UL) /* 1657 */
+P( 6, 0x496dc21ddd35b97fUL, 0x002768863c093c7fUL) /* 1663 */
+P( 4, 0xb0e96ce17090f82bUL, 0x0027505115a73ca8UL) /* 1667 */
+P( 2, 0xaadf05acdd7d024dUL, 0x00274441a61dc1b9UL) /* 1669 */
+P(24, 0xcb138196746eafb5UL, 0x0026b5c166113cf0UL) /* 1693 */
+P( 4, 0x347f523736755d61UL, 0x00269e65ad07b18eUL) /* 1697 */
+P( 2, 0xd14a48a051f7dd0bUL, 0x002692c25f877560UL) /* 1699 */
+P(10, 0x474d71b1ce914d25UL, 0x002658fa7523cd11UL) /* 1709 */
+P(12, 0x386063f5e28c1f89UL, 0x0026148710cf0f9eUL) /* 1721 */
+P( 2, 0x1db7325e32d04e73UL, 0x002609363b22524fUL) /* 1723 */
+P(10, 0xfef748d3893b880dUL, 0x0025d1065a1c1122UL) /* 1733 */
+P( 8, 0x2f3351506e935605UL, 0x0025a48a382b863fUL) /* 1741 */
+P( 6, 0x7a3637fa2376415bUL, 0x0025837190eccdbcUL) /* 1747 */
+P( 6, 0x4ac525d2baa21969UL, 0x00256292e95d510cUL) /* 1753 */
+P( 6, 0x3a11c16b42cd351fUL, 0x002541eda98d068cUL) /* 1759 */
+P(18, 0x6c7abde0049c2a11UL, 0x0024e15087fed8f5UL) /* 1777 */
+P( 6, 0x54dad0303e069ac7UL, 0x0024c18b20979e5dUL) /* 1783 */
+P( 4, 0xebf1ac9fdfe91433UL, 0x0024ac7b336de0c5UL) /* 1787 */
+P( 2, 0xfafdda8237cec655UL, 0x0024a1fc478c60bbUL) /* 1789 */
+P(12, 0xdce3ff6e71ffb739UL, 0x002463801231c009UL) /* 1801 */
+P(10, 0xbed5737d6286db1bUL, 0x0024300fd506ed33UL) /* 1811 */
+P(12, 0xe479e431fe08b4dfUL, 0x0023f314a494da81UL) /* 1823 */
+P( 8, 0x9dd9b0dd7742f897UL, 0x0023cadedd2fad3aUL) /* 1831 */
+P(16, 0x8f09d7402c5a5e87UL, 0x00237b7ed2664a03UL) /* 1847 */
+P(14, 0x9216d5c4d958738dUL, 0x0023372967dbaf1dUL) /* 1861 */
+P( 6, 0xb3139ba11d34ca63UL, 0x00231a308a371f20UL) /* 1867 */
+P( 4, 0x47d54f7ed644afafUL, 0x002306fa63e1e600UL) /* 1871 */
+P( 2, 0x92a81d85cf11a1b1UL, 0x0022fd6731575684UL) /* 1873 */
+P( 4, 0x754b26533253bdfdUL, 0x0022ea507805749cUL) /* 1877 */
+P( 2, 0xbbe0efc980bfd467UL, 0x0022e0cce8b3d720UL) /* 1879 */
+P(10, 0xc0d8d594f024dca1UL, 0x0022b1887857d161UL) /* 1889 */
+P(12, 0x8238d43bcaac1a65UL, 0x00227977fcc49cc0UL) /* 1901 */
+P( 6, 0x27779c1fae6175bbUL, 0x00225db37b5e5f4fUL) /* 1907 */
+P( 6, 0xa746ca9af708b2c9UL, 0x0022421b91322ed6UL) /* 1913 */
+P(18, 0x93f3cd9f389be823UL, 0x0021f05b35f52102UL) /* 1931 */
+P( 2, 0x5cb4a4c04c489345UL, 0x0021e75de5c70d60UL) /* 1933 */
+P(16, 0xbf6047743e85b6b5UL, 0x0021a01d6c19be96UL) /* 1949 */
+P( 2, 0x61c147831563545fUL, 0x0021974a6615c81aUL) /* 1951 */
+P(22, 0xedb47c0ae62dee9dUL, 0x00213767697cf36aUL) /* 1973 */
+P( 6, 0x0a3824386673a573UL, 0x00211d9f7fad35f1UL) /* 1979 */
+P( 8, 0xa4a77d19e575a0ebUL, 0x0020fb7d9dd36c18UL) /* 1987 */
+P( 6, 0xa2bee045e066c279UL, 0x0020e2123d661e0eUL) /* 1993 */
+P( 4, 0xc23618de8ab43d05UL, 0x0020d135b66ae990UL) /* 1997 */
+P( 2, 0x266b515216cb9f2fUL, 0x0020c8cded4d7a8eUL) /* 1999 */
+P( 4, 0xe279edd9e9c2e85bUL, 0x0020b80b3f43ddbfUL) /* 2003 */
+P( 8, 0xd0c591c221dc9c53UL, 0x002096b9180f46a6UL) /* 2011 */
+P( 6, 0x06da8ee9c9ee7c21UL, 0x00207de7e28de5daUL) /* 2017 */
+P(10, 0x9dfebcaf4c27e8c3UL, 0x002054dec8cf1fb3UL) /* 2027 */
+P( 2, 0x49aeff9f19dd6de5UL, 0x00204cb630b3aab5UL) /* 2029 */
+P(10, 0x86976a57a296e9c7UL, 0x00202428adc37bebUL) /* 2039 */
+P(14, 0xa3b9abf4872b84cdUL, 0x001fec0c7834def4UL) /* 2053 */
+P(10, 0x34fca6483895e6efUL, 0x001fc46fae98a1d0UL) /* 2063 */
+P( 6, 0x34b5a333988f873dUL, 0x001facda430ff619UL) /* 2069 */
+P(12, 0xd9dd4f19b5f17be1UL, 0x001f7e17dd8e15e5UL) /* 2081 */
+P( 2, 0xb935b507fd0ce78bUL, 0x001f765a3556a4eeUL) /* 2083 */
+P( 4, 0xb450f5540660e797UL, 0x001f66ea49d802f1UL) /* 2087 */
+P( 2, 0x63ff82831ffc1419UL, 0x001f5f3800faf9c0UL) /* 2089 */
+P(10, 0x8992f718c22a32fbUL, 0x001f38f4e6c0f1f9UL) /* 2099 */
+P(12, 0x5f3253ad0d37e7bfUL, 0x001f0b8546752578UL) /* 2111 */
+P( 2, 0x007c0ffe0fc007c1UL, 0x001f03ff83f001f0UL) /* 2113 */
+P(16, 0x4d8ebadc0c0640b1UL, 0x001ec853b0a3883cUL) /* 2129 */
+P( 2, 0xe2729af831037bdbUL, 0x001ec0ee573723ebUL) /* 2131 */
+P( 6, 0xb8f64bf30feebfe9UL, 0x001eaad38e6f6894UL) /* 2137 */
+P( 4, 0xda93124b544c0bf5UL, 0x001e9c28a765fe53UL) /* 2141 */
+P( 2, 0x9cf7ff0b593c539fUL, 0x001e94d8758c2003UL) /* 2143 */
+P(10, 0xd6bd8861fa0e07d9UL, 0x001e707ba8f65e68UL) /* 2153 */
+P( 8, 0x5cfe75c0bd8ab891UL, 0x001e53a2a68f574eUL) /* 2161 */
+P(18, 0x43e808757c2e862bUL, 0x001e1380a56b438dUL) /* 2179 */
+P(24, 0x90caa96d595c9d93UL, 0x001dbf9f513a3802UL) /* 2203 */
+P( 4, 0x8fd550625d07135fUL, 0x001db1d1d58bc600UL) /* 2207 */
+P( 6, 0x76b010a86e209f2dUL, 0x001d9d358f53de38UL) /* 2213 */
+P( 8, 0xecc0426447769b25UL, 0x001d81e6df6165c7UL) /* 2221 */
+P(16, 0xe381339caabe3295UL, 0x001d4bdf7fd40e30UL) /* 2237 */
+P( 2, 0xd1b190a2d0c7673fUL, 0x001d452c7a1c958dUL) /* 2239 */
+P( 4, 0xc3bce3cf26b0e7ebUL, 0x001d37cf9b902659UL) /* 2243 */
+P( 8, 0x5f87e76f56c61ce3UL, 0x001d1d3a5791e97bUL) /* 2251 */
+P(16, 0xc06c6857a124b353UL, 0x001ce89fe6b47416UL) /* 2267 */
+P( 2, 0x38c040fcba630f75UL, 0x001ce219f3235071UL) /* 2269 */
+P( 4, 0xd078bc4fbd533b21UL, 0x001cd516dcf92139UL) /* 2273 */
+P( 8, 0xde8e15c5dd354f59UL, 0x001cbb33bd1c2b8bUL) /* 2281 */
+P( 6, 0xca61d53d7414260fUL, 0x001ca7e7d2546688UL) /* 2287 */
+P( 6, 0xb56bf5ba8eae635dUL, 0x001c94b5c1b3dbd3UL) /* 2293 */
+P( 4, 0x44a72cb0fb6e3949UL, 0x001c87f7f9c241c1UL) /* 2297 */
+P(12, 0x879839a714f45bcdUL, 0x001c6202706c35a9UL) /* 2309 */
+P( 2, 0x02a8994fde5314b7UL, 0x001c5bb8a9437632UL) /* 2311 */
+P(22, 0xb971920cf2b90135UL, 0x001c174343b4111eUL) /* 2333 */
+P( 6, 0x8a8fd0b7df9a6e8bUL, 0x001c04d0d3e46b42UL) /* 2339 */
+P( 2, 0xb31f9a84c1c6eaadUL, 0x001bfeb00fbf4308UL) /* 2341 */
+P( 6, 0x92293b02823c6d83UL, 0x001bec5dce0b202dUL) /* 2347 */
+P( 4, 0xeee77ff20fe5ddcfUL, 0x001be03444620037UL) /* 2351 */
+P( 6, 0x0e1ea0f6c496c11dUL, 0x001bce09c66f6fc3UL) /* 2357 */
+P(14, 0xfdf2d3d6f88ccb6bUL, 0x001ba40228d02b30UL) /* 2371 */
+P( 6, 0xfa9d74a3457738f9UL, 0x001b9225b1cf8919UL) /* 2377 */
+P( 4, 0xefc3ca3db71a5785UL, 0x001b864a2ff3f53fUL) /* 2381 */
+P( 2, 0x8e2071718d0d6dafUL, 0x001b80604150e49bUL) /* 2383 */
+P( 6, 0xbc0fdbfeb6cfabfdUL, 0x001b6eb1aaeaacf3UL) /* 2389 */
+P( 4, 0x1eeab613e5e5aee9UL, 0x001b62f48da3c8ccUL) /* 2393 */
+P( 6, 0x2d2388e90e9e929fUL, 0x001b516babe96092UL) /* 2399 */
+P(12, 0x81dbafba588ddb43UL, 0x001b2e9cef1e0c87UL) /* 2411 */
+P( 6, 0x52eebc51c4799791UL, 0x001b1d56bedc849bUL) /* 2417 */
+P( 6, 0x1c6bc4693b45a047UL, 0x001b0c267546aec0UL) /* 2423 */
+P(14, 0x06eee0974498874dUL, 0x001ae45f62024fa0UL) /* 2437 */
+P( 4, 0xd85b7377a9953cb9UL, 0x001ad917631b5f54UL) /* 2441 */
+P( 6, 0x4b6df412d4caf56fUL, 0x001ac83d18cb608fUL) /* 2447 */
+P(12, 0x6b8afbbb4a053493UL, 0x001aa6c7ad8c063fUL) /* 2459 */
+P( 8, 0xcc5299c96ac7720bUL, 0x001a90a7b1228e2aUL) /* 2467 */
+P( 6, 0xadce84b5c710aa99UL, 0x001a8027c03ba059UL) /* 2473 */
+P( 4, 0x9d673f5aa3804225UL, 0x001a7533289deb89UL) /* 2477 */
+P(26, 0xe6541268efbce7f7UL, 0x001a2ed7ce16b49fUL) /* 2503 */
+P(18, 0xfcf41e76cf5be669UL, 0x0019fefc0a279a73UL) /* 2521 */
+P(10, 0x5c3eb5dc31c383cbUL, 0x0019e4b0cd873b5fUL) /* 2531 */
+P( 8, 0x301832d11d8ad6c3UL, 0x0019cfcdfd60e514UL) /* 2539 */
+P( 4, 0x2e9c0942f1ce450fUL, 0x0019c56932d66c85UL) /* 2543 */
+P( 6, 0x97f3f2be37a39a5dUL, 0x0019b5e1ab6fc7c2UL) /* 2549 */
+P( 2, 0xe8b7d8a9654187c7UL, 0x0019b0b8a62f2a73UL) /* 2551 */
+P( 6, 0xb5d024d7da5b1b55UL, 0x0019a149fc98942cUL) /* 2557 */
+P(22, 0xb8ba9d6e7ae3501bUL, 0x001969517ec25b85UL) /* 2579 */
+P(12, 0xf50865f71b90f1dfUL, 0x00194b3083360ba8UL) /* 2591 */
+P( 2, 0x739c1682847df9e1UL, 0x00194631f4bebdc1UL) /* 2593 */
+P(16, 0xc470a4d842b90ed1UL, 0x00191e84127268fdUL) /* 2609 */
+P( 8, 0x1fb1be11698cc409UL, 0x00190adbb543984fUL) /* 2617 */
+P( 4, 0xd8d5512a7cd35d15UL, 0x001901130bd18200UL) /* 2621 */
+P(12, 0xa5496821723e07f9UL, 0x0018e3e6b889ac94UL) /* 2633 */
+P(14, 0xbcc8c6d7abaa8167UL, 0x0018c233420e1ec1UL) /* 2647 */
+P(10, 0x52c396c95eb619a1UL, 0x0018aa5872d92bd6UL) /* 2657 */
+P( 2, 0x6eb7e380878ec74bUL, 0x0018a5989945ccf9UL) /* 2659 */
+P( 4, 0x3d5513b504537157UL, 0x00189c1e60b57f60UL) /* 2663 */
+P( 8, 0x314391f8862e948fUL, 0x0018893fbc8690b9UL) /* 2671 */
+P( 6, 0xdc0b17cfcd81f5ddUL, 0x00187b2bb3e1041cUL) /* 2677 */
+P( 6, 0x2f6bea3ec89044b3UL, 0x00186d27c9cdcfb8UL) /* 2683 */
+P( 4, 0xce13a05869f1b57fUL, 0x001863d8bf4f2c1cUL) /* 2687 */
+P( 2, 0x7593474e8ace3581UL, 0x00185f33e2ad7593UL) /* 2689 */
+P( 4, 0x07fc329295a05e4dUL, 0x001855ef75973e13UL) /* 2693 */
+P( 6, 0xb05377cba4908d23UL, 0x001848160153f134UL) /* 2699 */
+P( 8, 0xe7b2131a628aa39bUL, 0x001835b72e6f0656UL) /* 2707 */
+P( 4, 0x9031dbed7de01527UL, 0x00182c922d83eb39UL) /* 2711 */
+P( 2, 0x76844b1c670aa9a9UL, 0x0018280243c0365aUL) /* 2713 */
+P( 6, 0x6a03f4533b08915fUL, 0x00181a5cd5898e73UL) /* 2719 */
+P(10, 0x1dbca579db0a3999UL, 0x001803c0961773aaUL) /* 2729 */
+P( 2, 0x002ffe800bffa003UL, 0x0017ff4005ffd001UL) /* 2731 */
+P(10, 0x478ab1a3e936139dUL, 0x0017e8d670433edbUL) /* 2741 */
+P( 8, 0x66e722bc4c5cc095UL, 0x0017d7066cf4bb5dUL) /* 2749 */
+P( 4, 0x7a8f63c717278541UL, 0x0017ce285b806b1fUL) /* 2753 */
+P(14, 0xdf6eee24d292bc2fUL, 0x0017af52cdf27e02UL) /* 2767 */
+P(10, 0x9fc20d17237dd569UL, 0x0017997d47d01039UL) /* 2777 */
+P(12, 0xcdf9932356bda2edUL, 0x00177f7ec2c6d0baUL) /* 2789 */
+P( 2, 0x97b5e332e80f68d7UL, 0x00177b2f3cd00756UL) /* 2791 */
+P( 6, 0x46eee26fd875e2e5UL, 0x00176e4a22f692a0UL) /* 2797 */
+P( 4, 0x3548a8e65157a611UL, 0x001765b94271e11bUL) /* 2801 */
+P( 2, 0xc288d03be9b71e3bUL, 0x001761732b044ae4UL) /* 2803 */
+P(16, 0x8151186db38937abUL, 0x00173f7a5300a2bcUL) /* 2819 */
+P(14, 0x7800b910895a45f1UL, 0x001722112b48be1fUL) /* 2833 */
+P( 4, 0xaee0b024182eec3dUL, 0x001719b7a16eb843UL) /* 2837 */
+P( 6, 0x96323eda173b5713UL, 0x00170d3c99cc5052UL) /* 2843 */
+P( 8, 0x0ed0dbd03ae77c8bUL, 0x0016fcad7aed3bb6UL) /* 2851 */
+P( 6, 0xf73800b7828dc119UL, 0x0016f051b8231ffdUL) /* 2857 */
+P( 4, 0x1b61715ec22b7ca5UL, 0x0016e81beae20643UL) /* 2861 */
+P(18, 0xa8533a991ead64bfUL, 0x0016c3721584c1d8UL) /* 2879 */
+P( 8, 0x7f6c7290e46c2e77UL, 0x0016b34c2ba09663UL) /* 2887 */
+P(10, 0x6325e8d907b01db1UL, 0x00169f3ce292ddcdUL) /* 2897 */
+P( 6, 0x28909f70152a1067UL, 0x00169344b2220a0dUL) /* 2903 */
+P( 6, 0xea7077af0997a0f5UL, 0x001687592593c1b1UL) /* 2909 */
+P( 8, 0x7e605cad10c32e6dUL, 0x00167787f1418ec9UL) /* 2917 */
+P(10, 0x471b33570635b38fUL, 0x001663e190395ff2UL) /* 2927 */
+P(12, 0xab559fa997a61bb3UL, 0x00164c7a4b6eb5b3UL) /* 2939 */
+P(14, 0xad4bdae562bddab9UL, 0x0016316a061182fdUL) /* 2953 */
+P( 4, 0x055e1b2f2ed62f45UL, 0x001629ba914584e4UL) /* 2957 */
+P( 6, 0x03cd328b1a2dca9bUL, 0x00161e3d57de21b2UL) /* 2963 */
+P( 6, 0xd28f4e08733218a9UL, 0x001612cc01b977f0UL) /* 2969 */
+P( 2, 0xb6800b077f186293UL, 0x00160efe30c525ffUL) /* 2971 */
+P(28, 0x6fbd138c3fd9c207UL, 0x0015da45249ec5deUL) /* 2999 */
+P( 2, 0xb117ccd12ae88a89UL, 0x0015d68ab4acff92UL) /* 3001 */
+P(10, 0x2f1a1a044046bcebUL, 0x0015c3f989d1eb15UL) /* 3011 */
+P( 8, 0x548aba0b060541e3UL, 0x0015b535ad11b8f0UL) /* 3019 */
+P( 4, 0xcf4e808cea111b2fUL, 0x0015addb3f424ec1UL) /* 3023 */
+P(14, 0xdbec1b4fa855a475UL, 0x00159445cb91be6bUL) /* 3037 */
+P( 4, 0xe3f794eb600d7821UL, 0x00158d0199771e63UL) /* 3041 */
+P( 8, 0x34fae0d9a11f7c59UL, 0x00157e87d9b69e04UL) /* 3049 */
+P(12, 0xf006b0ccbbac085dUL, 0x001568f58bc01ac3UL) /* 3061 */
+P( 6, 0x3f45076dc3114733UL, 0x00155e3c993fda9bUL) /* 3067 */
+P(12, 0xeef49bfa58a1a1b7UL, 0x001548eacc5e1e6eUL) /* 3079 */
+P( 4, 0x12c4218bea691fa3UL, 0x001541d8f91ba6a7UL) /* 3083 */
+P( 6, 0xbc7504e3bd5e64f1UL, 0x00153747060cc340UL) /* 3089 */
+P(20, 0x4ee21c292bb92fadUL, 0x001514569f93f7c4UL) /* 3109 */
+P(10, 0x34338b7327a4bacfUL, 0x00150309705d3d79UL) /* 3119 */
+P( 2, 0x3fe5c0833d6fccd1UL, 0x0014ff97020cf5bfUL) /* 3121 */
+P(16, 0xb1e70743535203c1UL, 0x0014e42c114cf47eUL) /* 3137 */
+P(26, 0xefbb5dcdfb4e43d3UL, 0x0014b835bdcb6447UL) /* 3163 */
+P( 4, 0xca68467ca5394f9fUL, 0x0014b182b53a9ab7UL) /* 3167 */
+P( 2, 0x8c51c081408b97a1UL, 0x0014ae2ad094a3d3UL) /* 3169 */
+P(12, 0x3275a899dfa5dd65UL, 0x00149a320ea59f96UL) /* 3181 */
+P( 6, 0x9e674cb62e1b78bbUL, 0x001490441de1a2fbUL) /* 3187 */
+P( 4, 0xa37ff5bb2a998d47UL, 0x001489aacce57200UL) /* 3191 */
+P(12, 0x792a999db131a22bUL, 0x001475f82ad6ff99UL) /* 3203 */
+P( 6, 0x1b48841bc30d29b9UL, 0x00146c2cfe53204fUL) /* 3209 */
+P( 8, 0xf06721d2011d3471UL, 0x00145f2ca490d4a1UL) /* 3217 */
+P( 4, 0x93fd2386dff85ebdUL, 0x001458b2aae0ec87UL) /* 3221 */
+P( 8, 0x4ce72f54c07ed9b5UL, 0x00144bcb0a3a3150UL) /* 3229 */
+P(22, 0xd6d0fd3e71dd827bUL, 0x001428a1e65441d4UL) /* 3251 */
+P( 2, 0x856405fb1eed819dUL, 0x00142575a6c210d7UL) /* 3253 */
+P( 4, 0x8ea8aceb7c443989UL, 0x00141f2025ba5c46UL) /* 3257 */
+P( 2, 0x34a13026f62e5873UL, 0x00141bf6e35420fdUL) /* 3259 */
+P(12, 0x1eea0208ec0af4f7UL, 0x001409141d1d313aUL) /* 3271 */
+P(28, 0x63679853cea598cbUL, 0x0013dd8bc19c3513UL) /* 3299 */
+P( 2, 0xc30b3ebd61f2d0edUL, 0x0013da76f714dc8fUL) /* 3301 */
+P( 6, 0x7eb9037bc7f43bc3UL, 0x0013d13e50f8f49eUL) /* 3307 */
+P( 6, 0xa583e6f6ce016411UL, 0x0013c80e37ca3819UL) /* 3313 */
+P( 6, 0xf1938d895f1a74c7UL, 0x0013bee69fa99ccfUL) /* 3319 */
+P( 4, 0x80cf1491c1e81e33UL, 0x0013b8d0ede55835UL) /* 3323 */
+P( 6, 0x3c0f12886ba8f301UL, 0x0013afb7680bb054UL) /* 3329 */
+P( 2, 0x0e4b786e0dfcc5abUL, 0x0013acb0c3841c96UL) /* 3331 */
+P(12, 0x672684c93f2d41efUL, 0x00139a9c5f434fdeUL) /* 3343 */
+P( 4, 0xe00757badb35c51bUL, 0x0013949cf33a0d9dUL) /* 3347 */
+P(12, 0xd6d84afe66472edfUL, 0x001382b4a00c31b0UL) /* 3359 */
+P( 2, 0xfbbc0eedcbbfb6e1UL, 0x00137fbbc0eedcbbUL) /* 3361 */
+P(10, 0x250f43aa08a84983UL, 0x001370ecf047b069UL) /* 3371 */
+P( 2, 0x04400e927b1acaa5UL, 0x00136df9790e3155UL) /* 3373 */
+P(16, 0x56572be34b9d3215UL, 0x0013567dd8defd5bUL) /* 3389 */
+P( 2, 0x87964ef7781c62bfUL, 0x0013539261fdbc34UL) /* 3391 */
+P(16, 0x29ed84051c06e9afUL, 0x00133c564292d28aUL) /* 3407 */
+P( 6, 0xb00acd11ed3f87fdUL, 0x001333ae178d6388UL) /* 3413 */
+P(20, 0x06307881744152d9UL, 0x0013170ad00d1fd7UL) /* 3433 */
+P(16, 0x7a786459f5c1ccc9UL, 0x0013005f01db0947UL) /* 3449 */
+P( 8, 0x1308125d74563281UL, 0x0012f51d40342210UL) /* 3457 */
+P( 4, 0x395310a480b3e34dUL, 0x0012ef815e4ed950UL) /* 3461 */
+P( 2, 0x35985baa8b202837UL, 0x0012ecb4abccd827UL) /* 3463 */
+P( 4, 0x96304a6e052b3223UL, 0x0012e71dc1d3d820UL) /* 3467 */
+P( 2, 0xbd8265fc9af8fd45UL, 0x0012e45389a16495UL) /* 3469 */
+P(22, 0x1b6d0b383ec58e0bUL, 0x0012c5d9226476ccUL) /* 3491 */
+P( 8, 0xc21a7c3b68b28503UL, 0x0012badc391156fdUL) /* 3499 */
+P(12, 0x236fa180fbfd6007UL, 0x0012aa78e412f522UL) /* 3511 */
+P( 6, 0xc42accd440ed9595UL, 0x0012a251f5f47fd1UL) /* 3517 */
+P(10, 0x7acf7128236ba3f7UL, 0x001294cb85c53534UL) /* 3527 */
+P( 2, 0xf909367a987b9c79UL, 0x0012921963beb65eUL) /* 3529 */
+P( 4, 0xb64efb252bfba705UL, 0x00128cb777c69ca8UL) /* 3533 */
+P( 6, 0x980d4f5a7e4cd25bUL, 0x001284aa6cf07294UL) /* 3539 */
+P( 2, 0xe1ecc4ef27b0c37dUL, 0x001281fcf6ac7f87UL) /* 3541 */
+P( 6, 0x9111aebb81d72653UL, 0x001279f937367db9UL) /* 3547 */
+P(10, 0x8951f985cb2c67edUL, 0x00126cad0488be94UL) /* 3557 */
+P( 2, 0xc439d4fc54e0b5d7UL, 0x00126a06794646a2UL) /* 3559 */
+P(12, 0xe857bf31896d533bUL, 0x00125a2f2bcd3e95UL) /* 3571 */
+P(10, 0xb614bb4cb5023755UL, 0x00124d108389e6b1UL) /* 3581 */
+P( 2, 0x938a89e5473bf1ffUL, 0x00124a73083771acUL) /* 3583 */
+P(10, 0xeac481aca34de039UL, 0x00123d6acda0620aUL) /* 3593 */
+P(14, 0x14b961badf4809a7UL, 0x00122b4b2917eafdUL) /* 3607 */
+P( 6, 0x76784fecba352435UL, 0x00122391bfce1e2fUL) /* 3613 */
+P( 4, 0xefa689bb58aef5e1UL, 0x00121e6f1ea579f2UL) /* 3617 */
+P( 6, 0xb2b2c4db9c3a8197UL, 0x001216c09e471568UL) /* 3623 */
+P( 8, 0x2503bc992279f8cfUL, 0x00120c8cb9d93909UL) /* 3631 */
+P( 6, 0xd2ab9aec5ca1541dUL, 0x001204ed58e64ef9UL) /* 3637 */
+P( 6, 0x3e78ba1460f99af3UL, 0x0011fd546578f00cUL) /* 3643 */
+P(16, 0x0a01426572cfcb63UL, 0x0011e9310b8b4c9cUL) /* 3659 */
+P(12, 0xbea857968f3cbd67UL, 0x0011da3405db9911UL) /* 3671 */
+P( 2, 0x78db213eefe659e9UL, 0x0011d7b6f4eb055dUL) /* 3673 */
+P( 4, 0x963e8541a74d35f5UL, 0x0011d2bee748c145UL) /* 3677 */
+P(14, 0x9e22d152776f2e43UL, 0x0011c1706ddce7a7UL) /* 3691 */
+P( 6, 0x05d10d39d1e1f291UL, 0x0011ba0fed2a4f14UL) /* 3697 */
+P( 4, 0x374468dccaced1ddUL, 0x0011b528538ed64aUL) /* 3701 */
+P( 8, 0x8d145c7d110c5ad5UL, 0x0011ab61404242acUL) /* 3709 */
+P(10, 0x3251a39f5acb5737UL, 0x00119f378ce81d2fUL) /* 3719 */
+P( 8, 0xa66e50171443506fUL, 0x001195889ece79daUL) /* 3727 */
+P( 6, 0x124f69ad91dd4cbdUL, 0x00118e4c65387077UL) /* 3733 */
+P( 6, 0xec24f8f2a61a2793UL, 0x001187161d70e725UL) /* 3739 */
+P(22, 0xb472148e656b7a51UL, 0x00116cd6d1c85239UL) /* 3761 */
+P( 6, 0x0adf9570e1142f07UL, 0x001165bbe7ce86b1UL) /* 3767 */
+P( 2, 0x89bf33b065119789UL, 0x0011635ee344ce36UL) /* 3769 */
+P(10, 0x8f0149803cb291ebUL, 0x0011579767b6d679UL) /* 3779 */
+P(14, 0x8334b63afd190a31UL, 0x00114734711e2b54UL) /* 3793 */
+P( 4, 0x920908d50d6aba7dUL, 0x0011428b90147f05UL) /* 3797 */
+P( 6, 0x57d8b018c5a33d53UL, 0x00113b92f3021636UL) /* 3803 */
+P(18, 0xea1773092dc27ee5UL, 0x001126cabc886884UL) /* 3821 */
+P( 2, 0xcae5f38b7bf2e00fUL, 0x0011247eb1b85976UL) /* 3823 */
+P(10, 0x2bd02df34f695349UL, 0x0011190bb01efd65UL) /* 3833 */
+P(14, 0xddfecd5be62e2eb7UL, 0x0011091de0fd679cUL) /* 3847 */
+P( 4, 0xdbf849ebec96c4a3UL, 0x001104963c7e4e0bUL) /* 3851 */
+P( 2, 0xda31d4d0187357c5UL, 0x00110253516420b0UL) /* 3853 */
+P(10, 0xe34e21cc2d5418a7UL, 0x0010f70db7c41797UL) /* 3863 */
+P(14, 0x68ca5137a9e574adUL, 0x0010e75ee2bf9ecdUL) /* 3877 */
+P( 4, 0x3eaa0d0f804bfd19UL, 0x0010e2e91c6e0676UL) /* 3881 */
+P( 8, 0x554fb753cc20e9d1UL, 0x0010da049b9d428dUL) /* 3889 */
+P(18, 0x797afcca1300756bUL, 0x0010c6248fe3b1a2UL) /* 3907 */
+P( 4, 0x8b8d950b52eeea77UL, 0x0010c1c03ed690ebUL) /* 3911 */
+P( 6, 0xfb6cd166acabc185UL, 0x0010bb2e1379e3a2UL) /* 3917 */
+P( 2, 0x4eb6c5ed9437a7afUL, 0x0010b8fe7f61228eUL) /* 3919 */
+P( 4, 0xd1eddbd91b790cdbUL, 0x0010b4a10d60a4f7UL) /* 3923 */
+P( 6, 0x93d714ea4d8948e9UL, 0x0010ae192681ec0fUL) /* 3929 */
+P( 2, 0x3ca13ed8145188d3UL, 0x0010abecfbe5b0aeUL) /* 3931 */
+P(12, 0x829086016da89c57UL, 0x00109eefd568b96dUL) /* 3943 */
+P( 4, 0xd7da1f432124a543UL, 0x00109a9ff178b40cUL) /* 3947 */
+P(20, 0x7ead5581632fb07fUL, 0x00108531e22f9ff9UL) /* 3967 */
+P(22, 0x35443837f63ec3bdUL, 0x00106ddec1af4417UL) /* 3989 */
+
+#undef FIRST_OMITTED_PRIME
+#define FIRST_OMITTED_PRIME 4001
diff --git a/vendor/gmp-6.3.0/demos/qcn.c b/vendor/gmp-6.3.0/demos/qcn.c
new file mode 100644
index 0000000..9d76446
--- /dev/null
+++ b/vendor/gmp-6.3.0/demos/qcn.c
@@ -0,0 +1,172 @@
+/* Use mpz_kronecker_ui() to calculate an estimate for the quadratic
+ class number h(d), for a given negative fundamental discriminant, using
+ Dirichlet's analytic formula.
+
+Copyright 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3 of the License, or (at your option)
+any later version.
+
+This program 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 a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* Usage: qcn [-p limit] <discriminant>...
+
+ A fundamental discriminant means one of the form D or 4*D with D
+ square-free. Each argument is checked to see it's congruent to 0 or 1
+ mod 4 (as all discriminants must be), and that it's negative, but there's
+ no check on D being square-free.
+
+ This program is a bit of a toy, there are better methods for calculating
+ the class number and class group structure.
+
+ Reference:
+
+ Daniel Shanks, "Class Number, A Theory of Factorization, and Genera",
+ Proc. Symp. Pure Math., vol 20, 1970, pages 415-440.
+
+*/
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+
+/* A simple but slow primality test. */
+int
+prime_p (unsigned long n)
+{
+ unsigned long i, limit;
+
+ if (n == 2)
+ return 1;
+ if (n < 2 || !(n&1))
+ return 0;
+
+ limit = (unsigned long) floor (sqrt ((double) n));
+ for (i = 3; i <= limit; i+=2)
+ if ((n % i) == 0)
+ return 0;
+
+ return 1;
+}
+
+
+/* The formula is as follows, with d < 0.
+
+ w * sqrt(-d) inf p
+ h(d) = ------------ * product --------
+ 2 * pi p=2 p - (d/p)
+
+
+ (d/p) is the Kronecker symbol and the product is over primes p. w is 6
+ when d=-3, 4 when d=-4, or 2 otherwise.
+
+ Calculating the product up to p=infinity would take a long time, so for
+ the estimate primes up to 132,000 are used. Shanks found this giving an
+ accuracy of about 1 part in 1000, in normal cases. */
+
+unsigned long p_limit = 132000;
+
+double
+qcn_estimate (mpz_t d)
+{
+ double h;
+ unsigned long p;
+
+ /* p=2 */
+ h = sqrt (-mpz_get_d (d)) / M_PI
+ * 2.0 / (2.0 - mpz_kronecker_ui (d, 2));
+
+ if (mpz_cmp_si (d, -3) == 0) h *= 3;
+ else if (mpz_cmp_si (d, -4) == 0) h *= 2;
+
+ for (p = 3; p <= p_limit; p += 2)
+ if (prime_p (p))
+ h *= (double) p / (double) (p - mpz_kronecker_ui (d, p));
+
+ return h;
+}
+
+
+void
+qcn_str (char *num)
+{
+ mpz_t z;
+
+ mpz_init_set_str (z, num, 0);
+
+ if (mpz_sgn (z) >= 0)
+ {
+ mpz_out_str (stdout, 0, z);
+ printf (" is not supported (negatives only)\n");
+ }
+ else if (mpz_fdiv_ui (z, 4) != 0 && mpz_fdiv_ui (z, 4) != 1)
+ {
+ mpz_out_str (stdout, 0, z);
+ printf (" is not a discriminant (must == 0 or 1 mod 4)\n");
+ }
+ else
+ {
+ printf ("h(");
+ mpz_out_str (stdout, 0, z);
+ printf (") approx %.1f\n", qcn_estimate (z));
+ }
+ mpz_clear (z);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ int saw_number = 0;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], "-p") == 0)
+ {
+ i++;
+ if (i >= argc)
+ {
+ fprintf (stderr, "Missing argument to -p\n");
+ exit (1);
+ }
+ p_limit = atoi (argv[i]);
+ }
+ else
+ {
+ qcn_str (argv[i]);
+ saw_number = 1;
+ }
+ }
+
+ if (! saw_number)
+ {
+ /* some default output */
+ qcn_str ("-85702502803"); /* is 16259 */
+ qcn_str ("-328878692999"); /* is 1499699 */
+ qcn_str ("-928185925902146563"); /* is 52739552 */
+ qcn_str ("-84148631888752647283"); /* is 496652272 */
+ return 0;
+ }
+
+ return 0;
+}