Removed gmp/demos directory, which is not needed

This commit is contained in:
Juanjo Garcia-Ripoll 2013-10-06 09:28:22 +02:00
parent 77bc5c85d2
commit 45fee7d599
46 changed files with 0 additions and 18312 deletions

View file

@ -1,41 +0,0 @@
## Process this file with automake to generate Makefile.in
# Copyright 2000, 2001, 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 the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or (at your
# option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
SUBDIRS = calc expr
EXTRA_DIST = perl
INCLUDES = -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

View file

@ -1,646 +0,0 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 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, 2001, 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 the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or (at your
# option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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@
ANSI2KNR = $(top_builddir)/ansi2knr
LIBOBJDIR =
EXTRA_PROGRAMS = factorize$(EXEEXT) isprime$(EXEEXT) pexpr$(EXEEXT) \
primes$(EXEEXT) qcn$(EXEEXT)
subdir = demos
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/pexpr-config-h.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES = pexpr-config.h
factorize_SOURCES = factorize.c
factorize_OBJECTS = factorize$U.$(OBJEXT)
factorize_LDADD = $(LDADD)
factorize_DEPENDENCIES = $(top_builddir)/libgmp.la
isprime_SOURCES = isprime.c
isprime_OBJECTS = isprime$U.$(OBJEXT)
isprime_LDADD = $(LDADD)
isprime_DEPENDENCIES = $(top_builddir)/libgmp.la
pexpr_SOURCES = pexpr.c
pexpr_OBJECTS = pexpr$U.$(OBJEXT)
pexpr_LDADD = $(LDADD)
pexpr_DEPENDENCIES = $(top_builddir)/libgmp.la
primes_SOURCES = primes.c
primes_OBJECTS = primes$U.$(OBJEXT)
am__DEPENDENCIES_1 = $(top_builddir)/libgmp.la
am__DEPENDENCIES_2 =
primes_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
qcn_SOURCES = qcn.c
qcn_OBJECTS = qcn$U.$(OBJEXT)
qcn_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp =
am__depfiles_maybe =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
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 dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
install-recursive installcheck-recursive installdirs-recursive \
pdf-recursive ps-recursive uninstall-info-recursive \
uninstall-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ABI = @ABI@
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BITS_PER_MP_LIMB = @BITS_PER_MP_LIMB@
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@
ENABLE_STATIC_FALSE = @ENABLE_STATIC_FALSE@
ENABLE_STATIC_TRUE = @ENABLE_STATIC_TRUE@
EXEEXT = @EXEEXT@
EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
FGREP = @FGREP@
GMP_LDFLAGS = @GMP_LDFLAGS@
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_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@
M4 = @M4@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
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_SQR_OBJ = @TUNE_SQR_OBJ@
U = @U@
U_FOR_BUILD = @U_FOR_BUILD@
VERSION = @VERSION@
WANT_CXX_FALSE = @WANT_CXX_FALSE@
WANT_CXX_TRUE = @WANT_CXX_TRUE@
WANT_MPBSD_FALSE = @WANT_MPBSD_FALSE@
WANT_MPBSD_TRUE = @WANT_MPBSD_TRUE@
WITH_READLINE_01 = @WITH_READLINE_01@
YACC = @YACC@
YFLAGS = @YFLAGS@
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@
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@
mpn_objs_in_libmp = @mpn_objs_in_libmp@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
SUBDIRS = calc expr
EXTRA_DIST = perl
INCLUDES = -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 \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps demos/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu --ignore-deps demos/Makefile
.PRECIOUS: 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
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)
@rm -f factorize$(EXEEXT)
$(LINK) $(factorize_LDFLAGS) $(factorize_OBJECTS) $(factorize_LDADD) $(LIBS)
isprime$(EXEEXT): $(isprime_OBJECTS) $(isprime_DEPENDENCIES)
@rm -f isprime$(EXEEXT)
$(LINK) $(isprime_LDFLAGS) $(isprime_OBJECTS) $(isprime_LDADD) $(LIBS)
pexpr$(EXEEXT): $(pexpr_OBJECTS) $(pexpr_DEPENDENCIES)
@rm -f pexpr$(EXEEXT)
$(LINK) $(pexpr_LDFLAGS) $(pexpr_OBJECTS) $(pexpr_LDADD) $(LIBS)
primes$(EXEEXT): $(primes_OBJECTS) $(primes_DEPENDENCIES)
@rm -f primes$(EXEEXT)
$(LINK) $(primes_LDFLAGS) $(primes_OBJECTS) $(primes_LDADD) $(LIBS)
qcn$(EXEEXT): $(qcn_OBJECTS) $(qcn_DEPENDENCIES)
@rm -f qcn$(EXEEXT)
$(LINK) $(qcn_LDFLAGS) $(qcn_OBJECTS) $(qcn_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
$(top_builddir)/ansi2knr:
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) ansi2knr
mostlyclean-kr:
-test "$U" = "" || rm -f *_.c
.c.o:
$(COMPILE) -c $<
.c.obj:
$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
$(LTCOMPILE) -c -o $@ $<
factorize_.c: factorize.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/factorize.c; then echo $(srcdir)/factorize.c; else echo factorize.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
isprime_.c: isprime.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/isprime.c; then echo $(srcdir)/isprime.c; else echo isprime.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
pexpr_.c: pexpr.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/pexpr.c; then echo $(srcdir)/pexpr.c; else echo pexpr.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
primes_.c: primes.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/primes.c; then echo $(srcdir)/primes.c; else echo primes.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
qcn_.c: qcn.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/qcn.c; then echo $(srcdir)/qcn.c; else echo qcn.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
factorize_.$(OBJEXT) factorize_.lo isprime_.$(OBJEXT) isprime_.lo \
pexpr_.$(OBJEXT) pexpr_.lo primes_.$(OBJEXT) primes_.lo qcn_.$(OBJEXT) \
qcn_.lo : $(ANSI2KNR)
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
uninstall-info-am:
# 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.
$(RECURSIVE_TARGETS):
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; 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; \
(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"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
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 || \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
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)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$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 \
test -d "$(distdir)/$$subdir" \
|| $(mkdir_p) "$(distdir)/$$subdir" \
|| exit 1; \
distdir=`$(am__cd) $(distdir) && pwd`; \
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$top_distdir" \
distdir="$$distdir/$$subdir" \
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:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-libtool distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
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-kr \
mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \
clean clean-generic clean-libtool clean-recursive ctags \
ctags-recursive distclean distclean-compile distclean-generic \
distclean-libtool distclean-recursive distclean-tags distdir \
dvi dvi-am html html-am info info-am install install-am \
install-data install-data-am install-exec install-exec-am \
install-info install-info-am install-man install-strip \
installcheck installcheck-am installdirs installdirs-am \
maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-kr mostlyclean-libtool \
mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
uninstall uninstall-am uninstall-info-am
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:

View file

@ -1,38 +0,0 @@
## Process this file with automake to generate Makefile.in
# Copyright 2000, 2001, 2002, 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 the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or (at your
# option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
INCLUDES = -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)

View file

@ -1,548 +0,0 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 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, 2001, 2002, 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 the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or (at your
# option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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@
ANSI2KNR = $(top_builddir)/ansi2knr
LIBOBJDIR =
EXTRA_PROGRAMS = calc$(EXEEXT)
subdir = demos/calc
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/calc-config-h.in calc.c calc.h calclex.c
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES = calc-config.h
am_calc_OBJECTS = calc$U.$(OBJEXT) calclex$U.$(OBJEXT) \
calcread$U.$(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)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp =
am__depfiles_maybe =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
LTLEXCOMPILE = $(LIBTOOL) --mode=compile $(LEX) $(LFLAGS) $(AM_LFLAGS)
YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
LTYACCCOMPILE = $(LIBTOOL) --mode=compile $(YACC) $(YFLAGS) \
$(AM_YFLAGS)
SOURCES = $(calc_SOURCES)
DIST_SOURCES = $(calc_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ABI = @ABI@
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BITS_PER_MP_LIMB = @BITS_PER_MP_LIMB@
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@
ENABLE_STATIC_FALSE = @ENABLE_STATIC_FALSE@
ENABLE_STATIC_TRUE = @ENABLE_STATIC_TRUE@
EXEEXT = @EXEEXT@
EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
FGREP = @FGREP@
GMP_LDFLAGS = @GMP_LDFLAGS@
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_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@
M4 = @M4@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
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_SQR_OBJ = @TUNE_SQR_OBJ@
U = @U@
U_FOR_BUILD = @U_FOR_BUILD@
VERSION = @VERSION@
WANT_CXX_FALSE = @WANT_CXX_FALSE@
WANT_CXX_TRUE = @WANT_CXX_TRUE@
WANT_MPBSD_FALSE = @WANT_MPBSD_FALSE@
WANT_MPBSD_TRUE = @WANT_MPBSD_TRUE@
WITH_READLINE_01 = @WITH_READLINE_01@
YACC = @YACC@
YFLAGS = @YFLAGS@
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@
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@
mpn_objs_in_libmp = @mpn_objs_in_libmp@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
INCLUDES = -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 \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps demos/calc/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu --ignore-deps demos/calc/Makefile
.PRECIOUS: 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
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; \
$(MAKE) calc.c; \
else :; fi
calc$(EXEEXT): $(calc_OBJECTS) $(calc_DEPENDENCIES)
@rm -f calc$(EXEEXT)
$(LINK) $(calc_LDFLAGS) $(calc_OBJECTS) $(calc_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
$(top_builddir)/ansi2knr:
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) ansi2knr
mostlyclean-kr:
-test "$U" = "" || rm -f *_.c
.c.o:
$(COMPILE) -c $<
.c.obj:
$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
$(LTCOMPILE) -c -o $@ $<
calc_.c: calc.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/calc.c; then echo $(srcdir)/calc.c; else echo calc.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
calclex_.c: calclex.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/calclex.c; then echo $(srcdir)/calclex.c; else echo calclex.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
calcread_.c: calcread.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/calcread.c; then echo $(srcdir)/calcread.c; else echo calcread.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
calc_.$(OBJEXT) calc_.lo calclex_.$(OBJEXT) calclex_.lo \
calcread_.$(OBJEXT) calcread_.lo : $(ANSI2KNR)
.l.c:
$(LEXCOMPILE) $<
sed '/^#/ s|$(LEX_OUTPUT_ROOT)\.c|$@|' $(LEX_OUTPUT_ROOT).c >$@
rm -f $(LEX_OUTPUT_ROOT).c
.y.c:
$(YACCCOMPILE) $<
if test -f y.tab.h; then \
to=`echo "$*_H" | sed \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
-e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \
sed -e "/^#/!b" -e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" \
y.tab.h >$*.ht; \
rm -f y.tab.h; \
if cmp -s $*.ht $*.h; then \
rm -f $*.ht ;\
else \
mv $*.ht $*.h; \
fi; \
fi
if test -f y.output; then \
mv y.output $*.output; \
fi
sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@
rm -f y.tab.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
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)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$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:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
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-kr \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool ctags 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-exec install-exec-am \
install-info install-info-am install-man install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-kr mostlyclean-libtool pdf \
pdf-am ps ps-am tags uninstall uninstall-am uninstall-info-am
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:

View file

@ -1,66 +0,0 @@
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 2 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, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. */
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:

View file

@ -1,36 +0,0 @@
/* 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#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);

View file

@ -1,22 +0,0 @@
/* 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Define if GNU readline should be used. */
#define WITH_READLINE @WITH_READLINE_01@

File diff suppressed because it is too large Load diff

View file

@ -1,43 +0,0 @@
#ifndef BISON_CALC_H
# define BISON_CALC_H
#ifndef YYSTYPE
typedef union {
char *str;
int var;
} yystype;
# define YYSTYPE yystype
#endif
# define EOS 257
# define BAD 258
# define HELP 259
# define HEX 260
# define DECIMAL 261
# define QUIT 262
# define ABS 263
# define BIN 264
# define FIB 265
# define GCD 266
# define KRON 267
# define LCM 268
# define LUCNUM 269
# define NEXTPRIME 270
# define POWM 271
# define ROOT 272
# define SQRT 273
# define NUMBER 274
# define VARIABLE 275
# define LOR 276
# define LAND 277
# define EQ 278
# define NE 279
# define LE 280
# define GE 281
# define LSHIFT 282
# define RSHIFT 283
# define UMINUS 284
extern YYSTYPE yylval;
#endif /* not BISON_CALC_H */

View file

@ -1,319 +0,0 @@
%{
/* A simple integer desk calculator using yacc and gmp.
Copyright 2000, 2001, 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* 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)]) \
{ \
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 ();
}

File diff suppressed because it is too large Load diff

View file

@ -1,114 +0,0 @@
/* Lexical analyzer for calc program.
Copyright 2000, 2001, 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. */
%{
#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;
}

View file

@ -1,147 +0,0 @@
/* 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#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 */

View file

@ -1,45 +0,0 @@
## Process this file with automake to generate Makefile.in
# Copyright 2001, 2002, 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 the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or (at your
# option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
INCLUDES = -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

View file

@ -1,541 +0,0 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 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, 2002, 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 the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or (at your
# option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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@
ANSI2KNR = $(top_builddir)/ansi2knr
LIBOBJDIR =
EXTRA_PROGRAMS = run-expr$(EXEEXT) t-expr$(EXEEXT)
subdir = demos/expr
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
libexpr_a_AR = $(AR) $(ARFLAGS)
libexpr_a_LIBADD =
am_libexpr_a_OBJECTS = expr$U.$(OBJEXT) exprv$U.$(OBJEXT) \
exprz$U.$(OBJEXT) exprza$U.$(OBJEXT) exprq$U.$(OBJEXT) \
exprqa$U.$(OBJEXT) exprf$U.$(OBJEXT) exprfa$U.$(OBJEXT)
libexpr_a_OBJECTS = $(am_libexpr_a_OBJECTS)
run_expr_SOURCES = run-expr.c
run_expr_OBJECTS = run-expr$U.$(OBJEXT)
run_expr_LDADD = $(LDADD)
run_expr_DEPENDENCIES = libexpr.a $(top_builddir)/libgmp.la
t_expr_SOURCES = t-expr.c
t_expr_OBJECTS = t-expr$U.$(OBJEXT)
am__DEPENDENCIES_1 = libexpr.a $(top_builddir)/libgmp.la
t_expr_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
$(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp =
am__depfiles_maybe =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libexpr_a_SOURCES) run-expr.c t-expr.c
DIST_SOURCES = $(libexpr_a_SOURCES) run-expr.c t-expr.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ABI = @ABI@
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BITS_PER_MP_LIMB = @BITS_PER_MP_LIMB@
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@
ENABLE_STATIC_FALSE = @ENABLE_STATIC_FALSE@
ENABLE_STATIC_TRUE = @ENABLE_STATIC_TRUE@
EXEEXT = @EXEEXT@
EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
FGREP = @FGREP@
GMP_LDFLAGS = @GMP_LDFLAGS@
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_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@
M4 = @M4@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
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_SQR_OBJ = @TUNE_SQR_OBJ@
U = @U@
U_FOR_BUILD = @U_FOR_BUILD@
VERSION = @VERSION@
WANT_CXX_FALSE = @WANT_CXX_FALSE@
WANT_CXX_TRUE = @WANT_CXX_TRUE@
WANT_MPBSD_FALSE = @WANT_MPBSD_FALSE@
WANT_MPBSD_TRUE = @WANT_MPBSD_TRUE@
WITH_READLINE_01 = @WITH_READLINE_01@
YACC = @YACC@
YFLAGS = @YFLAGS@
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@
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@
mpn_objs_in_libmp = @mpn_objs_in_libmp@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
INCLUDES = -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 \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps demos/expr/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu --ignore-deps demos/expr/Makefile
.PRECIOUS: 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
libexpr.a: $(libexpr_a_OBJECTS) $(libexpr_a_DEPENDENCIES)
-rm -f libexpr.a
$(libexpr_a_AR) libexpr.a $(libexpr_a_OBJECTS) $(libexpr_a_LIBADD)
$(RANLIB) libexpr.a
run-expr$(EXEEXT): $(run_expr_OBJECTS) $(run_expr_DEPENDENCIES)
@rm -f run-expr$(EXEEXT)
$(LINK) $(run_expr_LDFLAGS) $(run_expr_OBJECTS) $(run_expr_LDADD) $(LIBS)
t-expr$(EXEEXT): $(t_expr_OBJECTS) $(t_expr_DEPENDENCIES)
@rm -f t-expr$(EXEEXT)
$(LINK) $(t_expr_LDFLAGS) $(t_expr_OBJECTS) $(t_expr_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
$(top_builddir)/ansi2knr:
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) ansi2knr
mostlyclean-kr:
-test "$U" = "" || rm -f *_.c
.c.o:
$(COMPILE) -c $<
.c.obj:
$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
$(LTCOMPILE) -c -o $@ $<
expr_.c: expr.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/expr.c; then echo $(srcdir)/expr.c; else echo expr.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
exprf_.c: exprf.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/exprf.c; then echo $(srcdir)/exprf.c; else echo exprf.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
exprfa_.c: exprfa.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/exprfa.c; then echo $(srcdir)/exprfa.c; else echo exprfa.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
exprq_.c: exprq.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/exprq.c; then echo $(srcdir)/exprq.c; else echo exprq.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
exprqa_.c: exprqa.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/exprqa.c; then echo $(srcdir)/exprqa.c; else echo exprqa.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
exprv_.c: exprv.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/exprv.c; then echo $(srcdir)/exprv.c; else echo exprv.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
exprz_.c: exprz.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/exprz.c; then echo $(srcdir)/exprz.c; else echo exprz.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
exprza_.c: exprza.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/exprza.c; then echo $(srcdir)/exprza.c; else echo exprza.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
run-expr_.c: run-expr.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/run-expr.c; then echo $(srcdir)/run-expr.c; else echo run-expr.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
t-expr_.c: t-expr.c $(ANSI2KNR)
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/t-expr.c; then echo $(srcdir)/t-expr.c; else echo t-expr.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
expr_.$(OBJEXT) expr_.lo exprf_.$(OBJEXT) exprf_.lo exprfa_.$(OBJEXT) \
exprfa_.lo exprq_.$(OBJEXT) exprq_.lo exprqa_.$(OBJEXT) exprqa_.lo \
exprv_.$(OBJEXT) exprv_.lo exprz_.$(OBJEXT) exprz_.lo \
exprza_.$(OBJEXT) exprza_.lo run-expr_.$(OBJEXT) run-expr_.lo \
t-expr_.$(OBJEXT) t-expr_.lo : $(ANSI2KNR)
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
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)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$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:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
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-kr \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool ctags 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-exec install-exec-am \
install-info install-info-am install-man install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-kr mostlyclean-libtool pdf \
pdf-am ps ps-am tags uninstall uninstall-am uninstall-info-am
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:

View file

@ -1,492 +0,0 @@
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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
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 varargs 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 parethesis 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:

View file

@ -1,137 +0,0 @@
/* Implementation specifics for expression evaluation.
Copyright 2000, 2001, 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/* Same tests as gmp.h. */
#if defined (__STDC__) \
|| defined (__cplusplus) \
|| defined (_AIX) \
|| defined (__DECC) \
|| (defined (__mips) && defined (_SYSTYPE_SVR4)) \
|| defined (_MSC_VER) \
|| defined (_WIN32)
#define HAVE_STDARG 1
#include <stdarg.h>
#else
#define HAVE_STDARG 0
#include <varargs.h>
#endif
#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 __gmp_const union mpX_t *mpX_srcptr;
typedef void (*mpexpr_fun_one_t) __GMP_PROTO ((mpX_ptr));
typedef unsigned long (*mpexpr_fun_ui_one_t) __GMP_PROTO ((mpX_ptr));
typedef void (*mpexpr_fun_0ary_t) __GMP_PROTO ((mpX_ptr));
typedef int (*mpexpr_fun_i_0ary_t) __GMP_PROTO ((void));
typedef void (*mpexpr_fun_unary_t) __GMP_PROTO ((mpX_ptr, mpX_srcptr));
typedef void (*mpexpr_fun_unary_ui_t) __GMP_PROTO ((mpX_ptr, unsigned long));
typedef int (*mpexpr_fun_i_unary_t) __GMP_PROTO ((mpX_srcptr));
typedef int (*mpexpr_fun_i_unary_ui_t) __GMP_PROTO ((unsigned long));
typedef void (*mpexpr_fun_binary_t) __GMP_PROTO ((mpX_ptr, mpX_srcptr, mpX_srcptr));
typedef void (*mpexpr_fun_binary_ui_t) __GMP_PROTO ((mpX_ptr, mpX_srcptr, unsigned long));
typedef int (*mpexpr_fun_i_binary_t) __GMP_PROTO ((mpX_srcptr, mpX_srcptr));
typedef int (*mpexpr_fun_i_binary_ui_t) __GMP_PROTO ((mpX_srcptr, unsigned long));
typedef void (*mpexpr_fun_ternary_t)
__GMP_PROTO ((mpX_ptr, mpX_srcptr, mpX_srcptr, mpX_srcptr));
typedef void (*mpexpr_fun_ternary_ui_t)
__GMP_PROTO ((mpX_ptr, mpX_srcptr, mpX_srcptr, unsigned long));
typedef int (*mpexpr_fun_i_ternary_t)
__GMP_PROTO ((mpX_srcptr, mpX_srcptr, mpX_srcptr));
typedef int (*mpexpr_fun_i_ternary_ui_t)
__GMP_PROTO ((mpX_srcptr, mpX_srcptr, unsigned long));
typedef size_t (*mpexpr_fun_number_t)
__GMP_PROTO ((mpX_ptr, __gmp_const char *str, size_t len, int base));
typedef void (*mpexpr_fun_swap_t) __GMP_PROTO ((mpX_ptr, mpX_ptr));
typedef unsigned long (*mpexpr_fun_get_ui_t) __GMP_PROTO ((mpX_srcptr));
typedef void (*mpexpr_fun_set_si_t) __GMP_PROTO ((mpX_srcptr, long));
struct mpexpr_control_t {
__gmp_const struct mpexpr_operator_t *op;
int argcount;
};
#define MPEXPR_VARIABLES 26
struct mpexpr_parse_t {
__gmp_const struct mpexpr_operator_t *table;
mpX_ptr res;
int base;
unsigned long prec;
__gmp_const char *e;
size_t elen;
mpX_srcptr *var;
int error_code;
int token;
__gmp_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 __GMP_PROTO ((struct mpexpr_parse_t *p));
int mpexpr_va_to_var __GMP_PROTO ((void *var[], va_list ap));
size_t mpexpr_mpz_number __GMP_PROTO ((mpz_ptr res,
__gmp_const char *e, size_t elen, int base));

View file

@ -1,825 +0,0 @@
/* mpexpr_evaluate -- shared code for simple expression evaluation
Copyright 2000, 2001, 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#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)
{
__gmp_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 { \
__gmp_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 __gmp_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;
}

View file

@ -1,131 +0,0 @@
/* Header for expression evaluation.
Copyright 2000, 2001, 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#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
typedef void (*mpexpr_fun_t) __GMP_PROTO ((void));
struct mpexpr_operator_t {
__gmp_const char *name;
mpexpr_fun_t fun;
int type;
int precedence;
};
int mpf_expr_a __GMP_PROTO ((__gmp_const struct mpexpr_operator_t *table,
mpf_ptr res, int base, unsigned long prec,
__gmp_const char *e, size_t elen,
mpf_srcptr var[26]));
int mpf_expr __GMP_PROTO ((mpf_ptr res, int base, __gmp_const char *e, ...));
int mpq_expr_a __GMP_PROTO ((__gmp_const struct mpexpr_operator_t *table,
mpq_ptr res, int base,
__gmp_const char *e, size_t elen,
mpq_srcptr var[26]));
int mpq_expr __GMP_PROTO ((mpq_ptr res, int base, __gmp_const char *e, ...));
int mpz_expr_a __GMP_PROTO ((__gmp_const struct mpexpr_operator_t *table,
mpz_ptr res, int base,
__gmp_const char *e, size_t elen,
mpz_srcptr var[26]));
int mpz_expr __GMP_PROTO ((mpz_ptr res, int base, __gmp_const char *e, ...));
#endif

View file

@ -1,129 +0,0 @@
/* mpf expression evaluation
Copyright 2000, 2001, 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#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 __gmp_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 }
};
__gmp_const struct mpexpr_operator_t * __gmp_const mpf_expr_standard_table
= _mpf_expr_standard_table;
int
#if HAVE_STDARG
mpf_expr (mpf_ptr res, int base, __gmp_const char *e, ...)
#else
mpf_expr (va_alist)
va_dcl
#endif
{
mpf_srcptr var[MPEXPR_VARIABLES];
va_list ap;
int ret;
#if HAVE_STDARG
va_start (ap, e);
#else
mpf_ptr res;
int base;
__gmp_const char *e;
va_start (ap);
res = va_arg (ap, mpf_ptr);
base = va_arg (ap, int);
e = va_arg (ap, __gmp_const char *);
#endif
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);
}

View file

@ -1,182 +0,0 @@
/* mpf expression evaluation
Copyright 2000, 2001, 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/* 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, __gmp_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 (__gmp_const struct mpexpr_operator_t *table,
mpf_ptr res, int base, unsigned long prec,
__gmp_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);
}

View file

@ -1,161 +0,0 @@
/* mpq expression evaluation
Copyright 2000, 2001, 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#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 __gmp_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 }
};
__gmp_const struct mpexpr_operator_t * __gmp_const mpq_expr_standard_table
= _mpq_expr_standard_table;
int
#if HAVE_STDARG
mpq_expr (mpq_ptr res, int base, __gmp_const char *e, ...)
#else
mpq_expr (va_alist)
va_dcl
#endif
{
mpq_srcptr var[MPEXPR_VARIABLES];
va_list ap;
int ret;
#if HAVE_STDARG
va_start (ap, e);
#else
mpq_ptr res;
int base;
__gmp_const char *e;
va_start (ap);
res = va_arg (ap, mpq_ptr);
base = va_arg (ap, int);
e = va_arg (ap, __gmp_const char *);
#endif
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);
}

View file

@ -1,91 +0,0 @@
/* 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#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, __gmp_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 (__gmp_const struct mpexpr_operator_t *table,
mpq_ptr res, int base,
__gmp_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);
}

View file

@ -1,49 +0,0 @@
/* 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#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;
}

View file

@ -1,213 +0,0 @@
/* mpz expression evaluation, simple part
Copyright 2000, 2001, 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#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 __gmp_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. */
__gmp_const struct mpexpr_operator_t * __gmp_const mpz_expr_standard_table
= _mpz_expr_standard_table;
int
#if HAVE_STDARG
mpz_expr (mpz_ptr res, int base, __gmp_const char *e, ...)
#else
mpz_expr (va_alist)
va_dcl
#endif
{
mpz_srcptr var[MPEXPR_VARIABLES];
va_list ap;
int ret;
#if HAVE_STDARG
va_start (ap, e);
#else
mpz_ptr res;
int base;
__gmp_const char *e;
va_start (ap);
res = va_arg (ap, mpz_ptr);
base = va_arg (ap, int);
e = va_arg (ap, __gmp_const char *);
#endif
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);
}

View file

@ -1,99 +0,0 @@
/* mpz expression evaluation
Copyright 2000, 2001, 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#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, __gmp_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 (__gmp_const struct mpexpr_operator_t *table,
mpz_ptr res, int base,
__gmp_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);
}

View file

@ -1,233 +0,0 @@
/* Demo program to run expression evaluation.
Copyright 2000, 2001, 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/* 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;
}

View file

@ -1,501 +0,0 @@
/* Test expression evaluation (print nothing and exit 0 if successful).
Copyright 2000, 2001, 2002, 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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#include <stdio.h>
#include <stdlib.h>
#include "gmp.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);
}

View file

@ -1,368 +0,0 @@
/* Factoring with Pollard's rho method.
Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005 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 2, 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; see the file COPYING. If not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "gmp.h"
int flag_verbose = 0;
static unsigned add[] = {4, 2, 4, 2, 4, 6, 2, 6};
void
factor_using_division (mpz_t t, unsigned int limit)
{
mpz_t q, r;
unsigned long int f;
int ai;
unsigned *addv = add;
unsigned int failures;
if (flag_verbose)
{
printf ("[trial division (%u)] ", limit);
fflush (stdout);
}
mpz_init (q);
mpz_init (r);
f = mpz_scan1 (t, 0);
mpz_div_2exp (t, t, f);
while (f)
{
printf ("2 ");
fflush (stdout);
--f;
}
for (;;)
{
mpz_tdiv_qr_ui (q, r, t, 3);
if (mpz_cmp_ui (r, 0) != 0)
break;
mpz_set (t, q);
printf ("3 ");
fflush (stdout);
}
for (;;)
{
mpz_tdiv_qr_ui (q, r, t, 5);
if (mpz_cmp_ui (r, 0) != 0)
break;
mpz_set (t, q);
printf ("5 ");
fflush (stdout);
}
failures = 0;
f = 7;
ai = 0;
while (mpz_cmp_ui (t, 1) != 0)
{
mpz_tdiv_qr_ui (q, r, t, f);
if (mpz_cmp_ui (r, 0) != 0)
{
f += addv[ai];
if (mpz_cmp_ui (q, f) < 0)
break;
ai = (ai + 1) & 7;
failures++;
if (failures > limit)
break;
}
else
{
mpz_swap (t, q);
printf ("%lu ", f);
fflush (stdout);
failures = 0;
}
}
mpz_clear (q);
mpz_clear (r);
}
void
factor_using_division_2kp (mpz_t t, unsigned int limit, unsigned long p)
{
mpz_t r;
mpz_t f;
unsigned int k;
if (flag_verbose)
{
printf ("[trial division (%u)] ", limit);
fflush (stdout);
}
mpz_init (r);
mpz_init_set_ui (f, 2 * p);
mpz_add_ui (f, f, 1);
for (k = 1; k < limit; k++)
{
mpz_tdiv_r (r, t, f);
while (mpz_cmp_ui (r, 0) == 0)
{
mpz_tdiv_q (t, t, f);
mpz_tdiv_r (r, t, f);
mpz_out_str (stdout, 10, f);
fflush (stdout);
fputc (' ', stdout);
}
mpz_add_ui (f, f, 2 * p);
}
mpz_clear (f);
mpz_clear (r);
}
void
factor_using_pollard_rho (mpz_t n, int a_int, unsigned long p)
{
mpz_t x, x1, y, P;
mpz_t a;
mpz_t g;
mpz_t t1, t2;
int k, l, c, i;
if (flag_verbose)
{
printf ("[pollard-rho (%d)] ", a_int);
fflush (stdout);
}
mpz_init (g);
mpz_init (t1);
mpz_init (t2);
mpz_init_set_si (a, a_int);
mpz_init_set_si (y, 2);
mpz_init_set_si (x, 2);
mpz_init_set_si (x1, 2);
k = 1;
l = 1;
mpz_init_set_ui (P, 1);
c = 0;
while (mpz_cmp_ui (n, 1) != 0)
{
S2:
if (p != 0)
{
mpz_powm_ui (x, x, p, n); mpz_add (x, x, a);
}
else
{
mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);
}
mpz_sub (t1, x1, x); mpz_mul (t2, P, t1); mpz_mod (P, t2, n);
c++;
if (c == 20)
{
c = 0;
mpz_gcd (g, P, n);
if (mpz_cmp_ui (g, 1) != 0)
goto S4;
mpz_set (y, x);
}
S3:
k--;
if (k > 0)
goto S2;
mpz_gcd (g, P, n);
if (mpz_cmp_ui (g, 1) != 0)
goto S4;
mpz_set (x1, x);
k = l;
l = 2 * l;
for (i = 0; i < k; i++)
{
if (p != 0)
{
mpz_powm_ui (x, x, p, n); mpz_add (x, x, a);
}
else
{
mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);
}
}
mpz_set (y, x);
c = 0;
goto S2;
S4:
do
{
if (p != 0)
{
mpz_powm_ui (y, y, p, n); mpz_add (y, y, a);
}
else
{
mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n);
}
mpz_sub (t1, x1, y); mpz_gcd (g, t1, n);
}
while (mpz_cmp_ui (g, 1) == 0);
mpz_div (n, n, g); /* divide by g, before g is overwritten */
if (!mpz_probab_prime_p (g, 3))
{
do
{
mp_limb_t a_limb;
mpn_random (&a_limb, (mp_size_t) 1);
a_int = (int) a_limb;
}
while (a_int == -2 || a_int == 0);
if (flag_verbose)
{
printf ("[composite factor--restarting pollard-rho] ");
fflush (stdout);
}
factor_using_pollard_rho (g, a_int, p);
}
else
{
mpz_out_str (stdout, 10, g);
fflush (stdout);
fputc (' ', stdout);
}
mpz_mod (x, x, n);
mpz_mod (x1, x1, n);
mpz_mod (y, y, n);
if (mpz_probab_prime_p (n, 3))
{
mpz_out_str (stdout, 10, n);
fflush (stdout);
fputc (' ', stdout);
break;
}
}
mpz_clear (g);
mpz_clear (P);
mpz_clear (t2);
mpz_clear (t1);
mpz_clear (a);
mpz_clear (x1);
mpz_clear (x);
mpz_clear (y);
}
void
factor (mpz_t t, unsigned long p)
{
unsigned int division_limit;
if (mpz_sgn (t) == 0)
return;
/* Set the trial division limit according the size of t. */
division_limit = mpz_sizeinbase (t, 2);
if (division_limit > 1000)
division_limit = 1000 * 1000;
else
division_limit = division_limit * division_limit;
if (p != 0)
factor_using_division_2kp (t, division_limit / 10, p);
else
factor_using_division (t, division_limit);
if (mpz_cmp_ui (t, 1) != 0)
{
if (flag_verbose)
{
printf ("[is number prime?] ");
fflush (stdout);
}
if (mpz_probab_prime_p (t, 3))
mpz_out_str (stdout, 10, t);
else
factor_using_pollard_rho (t, 1, p);
}
}
main (int argc, char *argv[])
{
mpz_t t;
unsigned long p;
int i;
if (argc > 1 && !strcmp (argv[1], "-v"))
{
flag_verbose = 1;
argv++;
argc--;
}
mpz_init (t);
if (argc > 1)
{
p = 0;
for (i = 1; i < argc; i++)
{
if (!strncmp (argv[i], "-Mp", 3))
{
p = atoi (argv[i] + 3);
mpz_set_ui (t, 1);
mpz_mul_2exp (t, t, p);
mpz_sub_ui (t, t, 1);
}
else if (!strncmp (argv[i], "-2kp", 4))
{
p = atoi (argv[i] + 4);
continue;
}
else
{
mpz_set_str (t, argv[i], 0);
}
if (mpz_cmp_ui (t, 0) == 0)
puts ("-");
else
{
factor (t, p);
puts ("");
}
}
}
else
{
for (;;)
{
mpz_inp_str (t, stdin, 0);
if (feof (stdin))
break;
mpz_out_str (stdout, 10, t); printf (" = ");
factor (t, 0);
puts ("");
}
}
exit (0);
}

View file

@ -1,68 +0,0 @@
/* Classify numbers as probable primes, primes or composites.
With -q return true if the folowing argument is a (probable) prime.
Copyright 1999, 2000, 2002, 2005 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include <stdlib.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, 5) == 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, 5);
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);
}

View file

@ -1,653 +0,0 @@
# GMP perl module
# Copyright 2001, 2002, 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 the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
# [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/multiplicty 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
apropriate 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, 2002, 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 the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License, or (at
your option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
=cut
# Local variables:
# perl-indent-level: 2
# fill-column: 76
# End:

File diff suppressed because it is too large Load diff

View file

@ -1,97 +0,0 @@
# 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 the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
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:

View file

@ -1,80 +0,0 @@
# 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 the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
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:

View file

@ -1,92 +0,0 @@
# GMP mpz module.
# Copyright 2001, 2002, 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 the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
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:

View file

@ -1,35 +0,0 @@
# 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 the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
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__

View file

@ -1,79 +0,0 @@
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 the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
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

View file

@ -1,73 +0,0 @@
# 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 the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
# 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:

View file

@ -1,45 +0,0 @@
#!/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 the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
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";

File diff suppressed because it is too large Load diff

View file

@ -1,66 +0,0 @@
# 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 the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
# 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:

View file

@ -1,99 +0,0 @@
# 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 the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# 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 Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
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));

View file

@ -1,46 +0,0 @@
/* 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* 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@

File diff suppressed because it is too large Load diff

View file

@ -1,388 +0,0 @@
/* 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 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#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 __GMP_PROTO ((unsigned char *, mpz_t, unsigned long, mpz_t));
void sieve_region __GMP_PROTO ((unsigned char *, mpz_t, unsigned long));
void make_primelist __GMP_PROTO ((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 divisable */
}
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, 3))
report (tmp);
}
}
}
}
out:
mpz_clear (tmp);
}
/* Generate a lits 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
}

View file

@ -1,173 +0,0 @@
/* 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, 2000, 2001, 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* 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;
}