diff --git a/.gitattributes b/.gitattributes index eccd0100b87239b8076ea22f437dfd1a7b20a379..812f7c78807f5fcd8f366378bc92d198c41da603 100644 --- a/.gitattributes +++ b/.gitattributes @@ -67,7 +67,14 @@ testfont binary /src/mapping.c foreign_ident /src/modules/Gdbm/acconfig.h foreign_ident /src/modules/Gdbm/gdbmmod.c foreign_ident +/src/modules/Gmp/Makefile.in foreign_ident +/src/modules/Gmp/configure.in foreign_ident +/src/modules/Gmp/gmp_machine.h.in foreign_ident /src/modules/Gmp/mpz_glue.c foreign_ident +/src/modules/Gmp/my_gmp.h foreign_ident +/src/modules/Gmp/next_prime.c foreign_ident +/src/modules/Gmp/prime_table.c foreign_ident +/src/modules/Gmp/testsuite.in foreign_ident /src/modules/Gz/acconfig.h foreign_ident /src/modules/Gz/zlibmod.c foreign_ident /src/modules/Image/acconfig.h foreign_ident diff --git a/src/modules/Gmp/Makefile.in b/src/modules/Gmp/Makefile.in index 35c6748e511b591cbbf61f17afbbba166868b719..ea6c1ef9612bf1b33c2f1fe4cb901704bcfbea69 100644 --- a/src/modules/Gmp/Makefile.in +++ b/src/modules/Gmp/Makefile.in @@ -1,3 +1,4 @@ +# $Id: Makefile.in,v 1.8 1998/07/11 18:35:19 grubba Exp $ SRCDIR=@srcdir@ VPATH=@srcdir@:@srcdir@/../..:../.. MODULE_LDFLAGS=@LDFLAGS@ @LIBS@ diff --git a/src/modules/Gmp/configure.in b/src/modules/Gmp/configure.in index 0df3eec9246412a615eb05ac4a7721ec12630c80..ea3ba815e71a71870e43e189d04d2595aafc3725 100644 --- a/src/modules/Gmp/configure.in +++ b/src/modules/Gmp/configure.in @@ -1,3 +1,4 @@ +# $Id: configure.in,v 1.2 1998/07/11 18:35:20 grubba Exp $ AC_INIT(mpz_glue.c) AC_CONFIG_HEADER(gmp_machine.h) AC_ARG_WITH(gmp, [ --with(out)-gmp Support bignums],[],[with_gmp=yes]) @@ -5,9 +6,16 @@ AC_ARG_WITH(gmp, [ --with(out)-gmp Support bignums],[],[with_gmp=yes sinclude(../module_configure.in) if test x$with_gmp = xyes ; then - AC_CHECK_HEADERS(gmp.h) - if test $ac_cv_header_gmp_h = yes ; then - AC_CHECK_LIB(gmp, mpz_set_d) + AC_CHECK_HEADERS(gmp2/gmp.h) + AC_CHECK_LIB(gmp2, mpz_set_d) + if test "$ac_cv_header_gmp2_gmp_h$ac_cv_lib_gmp2_mpz_set_d" = "yesyes"; + then + echo Using gmp2. + else + AC_CHECK_HEADERS(gmp.h) + if test $ac_cv_header_gmp_h = yes ; then + AC_CHECK_LIB(gmp, mpz_set_d) + fi fi fi diff --git a/src/modules/Gmp/gmp_machine.h.in b/src/modules/Gmp/gmp_machine.h.in index f304d6b576f6b85fcce987ff7044b6c9d77386ee..95ba342dbdf19e0126285ed6a22a099c6e04589d 100644 --- a/src/modules/Gmp/gmp_machine.h.in +++ b/src/modules/Gmp/gmp_machine.h.in @@ -1,6 +1,13 @@ +/* $Id: gmp_machine.h.in,v 1.2 1998/07/11 18:35:22 grubba Exp $ */ #ifndef GMP_MACHINE_H #define GMP_MACHINE_H +/* Define this if you have <gmp2/gmp.h> */ +#undef HAVE_GMP2_GMP_H + +/* Define this if you have -lgmp2 */ +#undef HAVE_LIBGMP2 + /* Define this if you have <gmp.h> */ #undef HAVE_GMP_H diff --git a/src/modules/Gmp/mpz_glue.c b/src/modules/Gmp/mpz_glue.c index 1d128598775b732a49ebc68efb2553301877322f..62e003a0ee7d4fae198775aa512ca115fb8a858d 100644 --- a/src/modules/Gmp/mpz_glue.c +++ b/src/modules/Gmp/mpz_glue.c @@ -4,14 +4,18 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: mpz_glue.c,v 1.26 1998/03/04 22:09:55 hubbe Exp $"); +RCSID("$Id: mpz_glue.c,v 1.27 1998/07/11 18:35:23 grubba Exp $"); #include "gmp_machine.h" -#if !defined(HAVE_LIBGMP) -#undef HAVE_GMP_H -#endif +#if defined(HAVE_GMP2_GMP_H) && defined(HAVE_LIBGMP2) +#define USE_GMP2 +#else /* !HAVE_GMP2_GMP_H || !HAVE_LIBGMP2 */ +#if defined(HAVE_GMP_H) && defined(HAVE_LIBGMP) +#define USE_GMP +#endif /* HAVE_GMP_H && HAVE_LIBGMP */ +#endif /* HAVE_GMP2_GMP_H && HAVE_LIBGMP2 */ -#ifdef HAVE_GMP_H +#if defined(USE_GMP) || defined(USE_GMP2) #include "interpret.h" #include "svalue.h" @@ -27,11 +31,17 @@ RCSID("$Id: mpz_glue.c,v 1.26 1998/03/04 22:09:55 hubbe Exp $"); #include "opcodes.h" #include "module_support.h" +#ifdef USE_GMP2 +#include <gmp2/gmp.h> +#else /* !USE_GMP2 */ #include <gmp.h> +#endif /* USE_GMP2 */ + #include "my_gmp.h" #include <limits.h> +#undef THIS #define THIS ((MP_INT *)(fp->current_storage)) #define OBTOMPZ(o) ((MP_INT *)(o->storage)) @@ -165,11 +175,14 @@ static struct pike_string *low_get_digits(MP_INT *mpz, int base) } else if (base == 256) { - INT32 i; + unsigned INT32 i; +#if 0 mpz_t tmp; - +#endif + if (mpz_sgn(mpz) < 0) error("only non-negative numbers can be converted to base 256.\n"); +#if 0 len = (mpz_sizeinbase(mpz, 2) + 7) / 8; s = begin_shared_string(len); mpz_init_set(tmp, mpz); @@ -180,6 +193,34 @@ static struct pike_string *low_get_digits(MP_INT *mpz, int base) mpz_fdiv_q_2exp(tmp, tmp, 8); } mpz_clear(tmp); +#endif + + /* lets optimize this /Mirar & Per */ + + /* len = mpz->_mp_size*sizeof(mp_limb_t); */ + /* This function should not return any leading zeros. /Nisse */ + len = (mpz_sizeinbase(mpz, 2) + 7) / 8; + s = begin_shared_string(len); + + if (!mpz->_mp_size) + { + /* Zero is a special case. There are no limbs at all, but + * the size is still 1 bit, and one digit should be produced. */ + if (len != 1) + fatal("mpz->low_get_digits: strange mpz state!\n"); + s->str[0] = 0; + } else { + mp_limb_t *src = mpz->_mp_d; + unsigned char *dst = (unsigned char *)s->str+s->len; + + while (len > 0) + { + mp_limb_t x=*(src++); + for (i=0; i<sizeof(mp_limb_t); i++) + *(--dst)=x&0xff,x>>=8; + len-=sizeof(mp_limb_t); + } + } s = end_shared_string(s); } else @@ -245,73 +286,85 @@ static void mpzmod_size(INT32 args) static void mpzmod_cast(INT32 args) { + struct pike_string *s; + if(args < 1) error("mpz->cast() called without arguments.\n"); if(sp[-args].type != T_STRING) error("Bad argument 1 to mpz->cast().\n"); - switch(sp[-args].u.string->str[0]) + s = sp[-args].u.string; + add_ref(s); + + pop_n_elems(args); + + switch(s->str[0]) { case 'i': - if(!strcmp(sp[-args].u.string->str, "int")) + if(!strcmp(s->str, "int")) { - mpzmod_get_int(args); + free_string(s); + mpzmod_get_int(0); return; } break; case 's': - if(!strcmp(sp[-args].u.string->str, "string")) + if(!strcmp(s->str, "string")) { - mpzmod_get_string(args); + free_string(s); + mpzmod_get_string(0); return; } break; case 'f': - if(!strcmp(sp[-args].u.string->str, "float")) + if(!strcmp(s->str, "float")) { - mpzmod_get_float(args); + free_string(s); + mpzmod_get_float(0); return; } break; case 'o': - if(!strcmp(sp[-args].u.string->str, "object")) + if(!strcmp(s->str, "object")) { - pop_n_elems(args); push_object(this_object()); } break; case 'm': - if(!strcmp(sp[-args].u.string->str, "mixed")) + if(!strcmp(s->str, "mixed")) { - pop_n_elems(args); push_object(this_object()); } break; } - error("mpz->cast() to other type than string, int or float.\n"); + push_string(s); /* To get it freed when error() pops the stack. */ + + error("mpz->cast() to \"%s\" is other type than string, int or float.\n", + s->str); } -/* Converts an svalue, located on the stack, to an mpz object */ -#if defined(__GNUC__) && defined(DEBUG_MALLOC) -#define get_mpz(X,Y) ({ check_svalue(X); debug_get_mpz((X), (Y)); }) +#ifdef DEBUG_MALLOC +#define get_mpz(X,Y) \ + (debug_get_mpz((X),(Y)),( (X)->type==T_OBJECT? debug_malloc_touch((X)->u.object) :0 ),debug_get_mpz((X),(Y))) #else -#define get_mpz(X,Y) debug_get_mpz((X), (Y)) +#define get_mpz debug_get_mpz #endif +/* Converts an svalue, located on the stack, to an mpz object */ static MP_INT *debug_get_mpz(struct svalue *s, int throw_error) { -#define ERROR(x) if (throw_error) error(x) +#define MPZ_ERROR(x) if (throw_error) error(x) struct object *o; switch(s->type) { default: - ERROR("Wrong type of object, cannot convert to mpz.\n"); + MPZ_ERROR("Wrong type of object, cannot convert to mpz.\n"); return 0; case T_INT: @@ -321,7 +374,6 @@ static MP_INT *debug_get_mpz(struct svalue *s, int throw_error) case T_ARRAY: #endif o=clone_object(mpzmod_program,0); - debug_malloc_touch(o); get_new_mpz(OBTOMPZ(o), s); free_svalue(s); s->u.object=o; @@ -331,7 +383,7 @@ static MP_INT *debug_get_mpz(struct svalue *s, int throw_error) case T_OBJECT: if(s->u.object->prog != mpzmod_program) { - ERROR("Wrong type of object, cannot convert to mpz.\n"); + MPZ_ERROR("Wrong type of object, cannot convert to mpz.\n"); return 0; } return (MP_INT *)s->u.object->storage; @@ -833,14 +885,14 @@ static void exit_mpz_glue(struct object *o) void pike_module_exit(void) { -#ifdef HAVE_GMP_H +#if defined(USE_GMP) || defined(USE_GMP2) free_program(mpzmod_program); #endif } void pike_module_init(void) { -#ifdef HAVE_GMP_H +#if defined(USE_GMP) || defined(USE_GMP2) start_new_program(); add_storage(sizeof(MP_INT)); diff --git a/src/modules/Gmp/my_gmp.h b/src/modules/Gmp/my_gmp.h index fde101801145ebb0ce51f15f98599d9920e72dff..aa9b46ed6409e52887efd5586dd2933b312e5541 100644 --- a/src/modules/Gmp/my_gmp.h +++ b/src/modules/Gmp/my_gmp.h @@ -1,4 +1,4 @@ -/* my_gmp.h +/* $Id: my_gmp.h,v 1.3 1998/07/11 18:35:24 grubba Exp $ * * These functions or something similar will hopefully be included * with Gmp-2.1 . diff --git a/src/modules/Gmp/next_prime.c b/src/modules/Gmp/next_prime.c index 1d96d7816fa7e815c86f033761f6cdacde3a76dc..c463f81befd4097818ae03e7f53ab7b117305478 100644 --- a/src/modules/Gmp/next_prime.c +++ b/src/modules/Gmp/next_prime.c @@ -1,4 +1,4 @@ -/* next_prime.c +/* $Id: next_prime.c,v 1.6 1998/07/11 18:35:26 grubba Exp $ * * Prime number test using trial division for small primes and then * Miller-Rabin, as suggested in Schneier's Applied Cryptography. @@ -9,17 +9,27 @@ #include "global.h" -#include "gmp_machine.h" +RCSID("$Id: next_prime.c,v 1.6 1998/07/11 18:35:26 grubba Exp $"); -#if !defined(HAVE_LIBGMP) -#undef HAVE_GMP_H -#endif +#include "gmp_machine.h" +#if defined(HAVE_GMP2_GMP_H) && defined(HAVE_LIBGMP2) +#define USE_GMP2 +#else /* !HAVE_GMP2_GMP_H || !HAVE_LIBGMP2 */ +#if defined(HAVE_GMP_H) && defined(HAVE_LIBGMP) +#define USE_GMP +#endif /* HAVE_GMP_H && HAVE_LIBGMP */ +#endif /* HAVE_GMP2_GMP_H && HAVE_LIBGMP2 */ -#ifdef HAVE_GMP_H +#if defined(USE_GMP) || defined(USE_GMP2) #include <limits.h> + +#ifdef USE_GMP2 +#include <gmp2/gmp.h> +#else /* !USE_GMP2 */ #include <gmp.h> +#endif /* USE_GMP2 */ #include "my_gmp.h" diff --git a/src/modules/Gmp/prime_table.c b/src/modules/Gmp/prime_table.c index a9263cfe8a55eb4f1c37cb09cc9bf62f427f4d96..254e69ee11ca754cc78adc6e67ab6625bd87c93d 100644 --- a/src/modules/Gmp/prime_table.c +++ b/src/modules/Gmp/prime_table.c @@ -1,4 +1,4 @@ -/* prime_table.c +/* $Id: prime_table.c,v 1.3 1998/07/11 18:35:27 grubba Exp $ * * Generates a table of small odd primes. */ diff --git a/src/modules/Gmp/testsuite.in b/src/modules/Gmp/testsuite.in index 6c8c34e3d3d42847b4d96e872e90e068f3257233..606458da53d8041717cc4083422c0dbf303c8cc3 100644 --- a/src/modules/Gmp/testsuite.in +++ b/src/modules/Gmp/testsuite.in @@ -1,8 +1,11 @@ +// $Id: testsuite.in,v 1.8 1998/07/11 18:35:28 grubba Exp $ + // mpz cond( [[ master()->resolv("Gmp")->mpz ]], [[ test_true(programp(Gmp.mpz)) test_false(clone(Gmp.mpz)) + test_false(!Gmp.mpz(1)) test_do(destruct(clone(Gmp.mpz))) test_eq(Gmp.mpz(10),10) @@ -36,6 +39,7 @@ cond( [[ master()->resolv("Gmp")->mpz ]], test_binop(17,|,7,23) test_binop(17,&,18,16) + test_eq([[`+(1,1,1,Gmp.mpz(1),1,1)]],6) test_eq(-clone(Gmp.mpz,17),-17) test_eq((~clone(Gmp.mpz,17)) & 255,238) test_true(stringp((string)clone(Gmp.mpz,17))) @@ -45,28 +49,51 @@ cond( [[ master()->resolv("Gmp")->mpz ]], test_false(clone(Gmp.mpz,0)) test_true(clone(Gmp.mpz,1)) test_eq(clone(Gmp.mpz,17)->powm(12,4711),85) +]]) define([[mpz_test_cmp]],[[ - test_cmp(clone(Gmp.mpz,$1), $2) - test_cmp($1, clone(Gmp.mpz,$2)) - test_cmp(clone(Gmp.mpz, $1), clone(Gmp.mpz, $2)) + cond( [[ master()->resolv("Gmp")->mpz ]], + [[ + test_cmp3(Gmp.mpz($1), $2, $3) + test_cmp3($1, Gmp.mpz($2), $3) + ]]) + cond( [[ master()->resolv("Gmp")->mpz ]], + [[ + test_cmp3(Gmp.mpz($1), Gmp.mpz($2), $3) + test_cmp3(Gmp.mpz($1), $2, Gmp.mpz($3)) + ]]) + cond( [[ master()->resolv("Gmp")->mpz ]], + [[ + test_cmp3($1, Gmp.mpz($2), Gmp.mpz($3)) + test_cmp3(Gmp.mpz($1), Gmp.mpz($2), Gmp.mpz($3)) + ]]) ]]) define([[mpz_test_type1]],[[ - mpz_test_cmp($1,$2) - mpz_test_cmp($1.0,$2) + mpz_test_cmp($1,$2,$3) + mpz_test_cmp($1.0,$2,$3) ]]) define([[mpz_test_type2]],[[ - mpz_test_type1($1,$2) - mpz_test_type1($1,$2.0) + mpz_test_type1($1,$2,$3) + mpz_test_type1($1,$2.0,$3) + ]]) + + define([[mpz_test_type3]],[[ + mpz_test_type2($1,$2,$3) + mpz_test_type2($1,$2,$3.0) ]]) - mpz_test_type2(1,2) - mpz_test_type2(-2,1) + mpz_test_type3(1,2,3) + mpz_test_type3(-2,1,4) + mpz_test_type3(-2,-1,4) +cond( [[ master()->resolv("Gmp")->mpz ]], +[[ test_true(catch(Gmp.mpz("abcd", 47))) test_true(catch(Gmp.mpz(-17)->digits(256))) + test_eq(Gmp.mpz(0)->digits(256), "\0"); + test_eq(Gmp.mpz(17)->digits(256), "\021"); test_eq(Gmp.mpz(4711)->size(2), 13) test_true(catch(Gmp.mpz(17) + 18 + "19")) test_true(catch(Gmp.mpz(17) - 18 - "19"))