diff options
Diffstat (limited to 'vendor/gmp-6.3.0/demos')
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; +} |