mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-15 05:43:19 -08:00
Removed gmp/demos directory, which is not needed
This commit is contained in:
parent
77bc5c85d2
commit
45fee7d599
46 changed files with 0 additions and 18312 deletions
|
|
@ -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
|
||||
|
|
@ -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:
|
||||
|
|
@ -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)
|
||||
|
|
@ -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:
|
||||
|
|
@ -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:
|
||||
|
|
@ -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);
|
||||
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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
|
||||
|
|
@ -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:
|
||||
|
|
@ -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:
|
||||
|
|
@ -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));
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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:
|
||||
|
|
@ -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:
|
||||
|
|
@ -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:
|
||||
|
|
@ -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__
|
||||
|
|
@ -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
|
||||
|
|
@ -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:
|
||||
|
|
@ -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
|
|
@ -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:
|
||||
|
|
@ -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));
|
||||
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue