klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit e09e6368f9d85f2baf328edd75de7bd0d8712f12
parent 7e3c12424c595583a28bf2292d6b8d22fbe24f9d
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Tue, 13 Dec 2011 21:23:07 -0300

Bugfix: properly rooted the environment in standalone interpreter -r switch (dorfile). More indent adjusting.

Diffstat:
MTODO | 4----
Msrc/imath.c | 4118++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/imath.h | 248++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/imrat.c | 586++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/imrat.h | 122++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/kapplicative.c | 2+-
Msrc/kapplicative.h | 14+++++++-------
Msrc/kauxlib.c | 22+++++++++++-----------
Msrc/kbytevector.c | 60++++++++++++++++++++++++++++++------------------------------
Msrc/kbytevector.h | 4++--
Msrc/kcontinuation.c | 10+++++-----
Msrc/kcontinuation.h | 2+-
Msrc/kenvironment.c | 278++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/klisp.c | 5+++--
14 files changed, 2736 insertions(+), 2739 deletions(-)

diff --git a/TODO b/TODO @@ -1,13 +1,9 @@ * Release 0.3 ** modules: *** simple modules (something inspired in r7rs) (r7rs) -*** add modules support to the interpreter (r7rs) ** documentation: *** update the manual with the current features *** add a section to the manual with the interpreter usage -** refactor -*** convert all tabs to spaces (use sed) - * Release 0.4+ ** refactor: *** clean stand alone interpreter diff --git a/src/imath.c b/src/imath.c @@ -38,29 +38,29 @@ /* {{{ Constants */ -const mp_result MP_OK = 0; /* no error, all is well */ -const mp_result MP_FALSE = 0; /* boolean false */ -const mp_result MP_TRUE = -1; /* boolean true */ -const mp_result MP_MEMORY = -2; /* out of memory */ +const mp_result MP_OK = 0; /* no error, all is well */ +const mp_result MP_FALSE = 0; /* boolean false */ +const mp_result MP_TRUE = -1; /* boolean true */ +const mp_result MP_MEMORY = -2; /* out of memory */ const mp_result MP_RANGE = -3; /* argument out of range */ -const mp_result MP_UNDEF = -4; /* result undefined */ -const mp_result MP_TRUNC = -5; /* output truncated */ +const mp_result MP_UNDEF = -4; /* result undefined */ +const mp_result MP_TRUNC = -5; /* output truncated */ const mp_result MP_BADARG = -6; /* invalid null argument */ const mp_result MP_MINERR = -6; const mp_sign MP_NEG = 1; /* value is strictly negative */ -const mp_sign MP_ZPOS = 0; /* value is non-negative */ +const mp_sign MP_ZPOS = 0; /* value is non-negative */ STATIC const char *s_unknown_err = "unknown result code"; STATIC const char *s_error_msg[] = { - "error code 0", - "boolean true", - "out of memory", - "argument out of range", - "result undefined", - "output truncated", - "invalid argument", - NULL + "error code 0", + "boolean true", + "out of memory", + "argument out of range", + "result undefined", + "output truncated", + "invalid argument", + NULL }; /* }}} */ @@ -80,66 +80,66 @@ STATIC const char *s_error_msg[] = { The use of this table eliminates a dependency upon linkage against the standard math libraries. - */ +*/ STATIC const double s_log2[] = { - 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* 0 1 2 3 */ - 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */ - 0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */ - 0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */ - 0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */ - 0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */ - 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */ - 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */ - 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */ - 0.193426404, /* 36 */ + 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* 0 1 2 3 */ + 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */ + 0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */ + 0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */ + 0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */ + 0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */ + 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */ + 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */ + 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */ + 0.193426404, /* 36 */ }; /* }}} */ /* {{{ Various macros */ /* Return the number of digits needed to represent a static value */ -#define MP_VALUE_DIGITS(V) \ -((sizeof(V)+(sizeof(mp_digit)-1))/sizeof(mp_digit)) +#define MP_VALUE_DIGITS(V) \ + ((sizeof(V)+(sizeof(mp_digit)-1))/sizeof(mp_digit)) /* Round precision P to nearest word boundary */ #define ROUND_PREC(P) ((mp_size)(2*(((P)+1)/2))) /* Set array P of S digits to zero */ -#define ZERO(P, S) \ -do{ \ - mp_size i__ = (S) * sizeof(mp_digit); \ - mp_digit *p__ = (P); \ - memset(p__, 0, i__); \ -} while(0) +#define ZERO(P, S) \ + do{ \ + mp_size i__ = (S) * sizeof(mp_digit); \ + mp_digit *p__ = (P); \ + memset(p__, 0, i__); \ + } while(0) /* Copy S digits from array P to array Q */ -#define COPY(P, Q, S) \ -do{ \ - mp_size i__ = (S) * sizeof(mp_digit); \ - mp_digit *p__ = (P), *q__ = (Q); \ - memcpy(q__, p__, i__); \ -} while(0) +#define COPY(P, Q, S) \ + do{ \ + mp_size i__ = (S) * sizeof(mp_digit); \ + mp_digit *p__ = (P), *q__ = (Q); \ + memcpy(q__, p__, i__); \ + } while(0) /* Reverse N elements of type T in array A */ -#define REV(T, A, N) \ -do{ \ - T *u_ = (A), *v_ = u_ + (N) - 1; \ - while (u_ < v_) { \ - T xch = *u_; \ - *u_++ = *v_; \ - *v_-- = xch; \ - } \ -} while(0) - -#define CLAMP(Z) \ -do{ \ - mp_int z_ = (Z); \ - mp_size uz_ = MP_USED(z_); \ - mp_digit *dz_ = MP_DIGITS(z_) + uz_ -1; \ - while (uz_ > 1 && (*dz_-- == 0)) \ - --uz_; \ - MP_USED(z_) = uz_; \ -} while(0) +#define REV(T, A, N) \ + do{ \ + T *u_ = (A), *v_ = u_ + (N) - 1; \ + while (u_ < v_) { \ + T xch = *u_; \ + *u_++ = *v_; \ + *v_-- = xch; \ + } \ + } while(0) + +#define CLAMP(Z) \ + do{ \ + mp_int z_ = (Z); \ + mp_size uz_ = MP_USED(z_); \ + mp_digit *dz_ = MP_DIGITS(z_) + uz_ -1; \ + while (uz_ > 1 && (*dz_-- == 0)) \ + --uz_; \ + MP_USED(z_) = uz_; \ + } while(0) /* Select min/max. Do not provide expressions for which multiple evaluation would be problematic, e.g. x++ */ @@ -148,52 +148,52 @@ do{ \ /* Exchange lvalues A and B of type T, e.g. SWAP(int, x, y) where x and y are variables of type int. */ -#define SWAP(T, A, B) \ -do{ \ - T t_ = (A); \ - A = (B); \ - B = t_; \ -} while(0) +#define SWAP(T, A, B) \ + do{ \ + T t_ = (A); \ + A = (B); \ + B = t_; \ + } while(0) /* Used to set up and access simple temp stacks within functions. */ #define TEMP(K) (temp + (K)) -#define SETUP(E, C) \ -do{ \ - if ((res = (E)) != MP_OK) \ - goto CLEANUP; \ - ++(C); \ -} while(0) +#define SETUP(E, C) \ + do{ \ + if ((res = (E)) != MP_OK) \ + goto CLEANUP; \ + ++(C); \ + } while(0) /* Compare value to zero. */ -#define CMPZ(Z) \ -(((Z)->used==1&&(Z)->digits[0]==0)?0:((Z)->sign==MP_NEG)?-1:1) +#define CMPZ(Z) \ + (((Z)->used==1&&(Z)->digits[0]==0)?0:((Z)->sign==MP_NEG)?-1:1) /* Multiply X by Y into Z, ignoring signs. Requires that Z have enough storage preallocated to hold the result. */ -#define UMUL(K, X, Y, Z) \ -do{ \ - mp_size ua_ = MP_USED(X), ub_ = MP_USED(Y); \ - mp_size o_ = ua_ + ub_; \ - ZERO(MP_DIGITS(Z), o_); \ - (void) s_kmul((K), MP_DIGITS(X), MP_DIGITS(Y), MP_DIGITS(Z), ua_, ub_); \ - MP_USED(Z) = o_; \ - CLAMP(Z); \ -} while(0) +#define UMUL(K, X, Y, Z) \ + do{ \ + mp_size ua_ = MP_USED(X), ub_ = MP_USED(Y); \ + mp_size o_ = ua_ + ub_; \ + ZERO(MP_DIGITS(Z), o_); \ + (void) s_kmul((K), MP_DIGITS(X), MP_DIGITS(Y), MP_DIGITS(Z), ua_, ub_); \ + MP_USED(Z) = o_; \ + CLAMP(Z); \ + } while(0) /* Square X into Z. Requires that Z have enough storage to hold the result. */ -#define USQR(K, X, Z) \ -do{ \ - mp_size ua_ = MP_USED(X), o_ = ua_ + ua_; \ - ZERO(MP_DIGITS(Z), o_); \ - (void) s_ksqr((K), MP_DIGITS(X), MP_DIGITS(Z), ua_); \ - MP_USED(Z) = o_; \ - CLAMP(Z); \ -} while(0) - -#define UPPER_HALF(W) ((mp_word)((W) >> MP_DIGIT_BIT)) -#define LOWER_HALF(W) ((mp_digit)(W)) -#define HIGH_BIT_SET(W) ((W) >> (MP_WORD_BIT - 1)) +#define USQR(K, X, Z) \ + do{ \ + mp_size ua_ = MP_USED(X), o_ = ua_ + ua_; \ + ZERO(MP_DIGITS(Z), o_); \ + (void) s_ksqr((K), MP_DIGITS(X), MP_DIGITS(Z), ua_); \ + MP_USED(Z) = o_; \ + CLAMP(Z); \ + } while(0) + +#define UPPER_HALF(W) ((mp_word)((W) >> MP_DIGIT_BIT)) +#define LOWER_HALF(W) ((mp_digit)(W)) +#define HIGH_BIT_SET(W) ((W) >> (MP_WORD_BIT - 1)) #define ADD_WILL_OVERFLOW(W, V) ((MP_WORD_MAX - (V)) < (W)) /* }}} */ @@ -227,96 +227,96 @@ STATIC void s_free(klisp_State *K, void *ptr, mp_size size); STATIC int s_pad(klisp_State *K, mp_int z, mp_size min); /* Fill in a "fake" mp_int on the stack with a given value */ -STATIC void s_fake(mp_int z, mp_small value, mp_digit vbuf[]); +STATIC void s_fake(mp_int z, mp_small value, mp_digit vbuf[]); /* Compare two runs of digits of given length, returns <0, 0, >0 */ -STATIC int s_cdig(mp_digit *da, mp_digit *db, mp_size len); +STATIC int s_cdig(mp_digit *da, mp_digit *db, mp_size len); /* Pack the unsigned digits of v into array t */ -STATIC int s_vpack(mp_small v, mp_digit t[]); +STATIC int s_vpack(mp_small v, mp_digit t[]); /* Compare magnitudes of a and b, returns <0, 0, >0 */ -STATIC int s_ucmp(mp_int a, mp_int b); +STATIC int s_ucmp(mp_int a, mp_int b); /* Compare magnitudes of a and v, returns <0, 0, >0 */ -STATIC int s_vcmp(mp_int a, mp_small v); +STATIC int s_vcmp(mp_int a, mp_small v); /* Unsigned magnitude addition; assumes dc is big enough. Carry out is returned (no memory allocated). */ STATIC mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b); + mp_size size_a, mp_size size_b); /* Unsigned magnitude subtraction. Assumes dc is big enough. */ -STATIC void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b); +STATIC void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b); /* Unsigned recursive multiplication. Assumes dc is big enough. */ -STATIC int s_kmul(klisp_State *K, mp_digit *da, mp_digit *db, - mp_digit *dc, mp_size size_a, mp_size size_b); +STATIC int s_kmul(klisp_State *K, mp_digit *da, mp_digit *db, + mp_digit *dc, mp_size size_a, mp_size size_b); /* Unsigned magnitude multiplication. Assumes dc is big enough. */ -STATIC void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b); +STATIC void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b); /* Unsigned recursive squaring. Assumes dc is big enough. */ /* Andres Navarro: allocs temporaries */ -STATIC int s_ksqr(klisp_State *K, mp_digit *da, mp_digit *dc, - mp_size size_a); +STATIC int s_ksqr(klisp_State *K, mp_digit *da, mp_digit *dc, + mp_size size_a); /* Unsigned magnitude squaring. Assumes dc is big enough. */ -STATIC void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a); +STATIC void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a); /* Single digit addition. Assumes a is big enough. */ -STATIC void s_dadd(mp_int a, mp_digit b); +STATIC void s_dadd(mp_int a, mp_digit b); /* Single digit multiplication. Assumes a is big enough. */ -STATIC void s_dmul(mp_int a, mp_digit b); +STATIC void s_dmul(mp_int a, mp_digit b); /* Single digit multiplication on buffers; assumes dc is big enough. */ -STATIC void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, - mp_size size_a); +STATIC void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, + mp_size size_a); /* Single digit division. Replaces a with the quotient, returns the remainder. */ STATIC mp_digit s_ddiv(mp_int a, mp_digit b); /* Quick division by a power of 2, replaces z (no allocation) */ -STATIC void s_qdiv(mp_int z, mp_size p2); +STATIC void s_qdiv(mp_int z, mp_size p2); /* Quick remainder by a power of 2, replaces z (no allocation) */ -STATIC void s_qmod(mp_int z, mp_size p2); +STATIC void s_qmod(mp_int z, mp_size p2); /* Quick multiplication by a power of 2, replaces z. Allocates if necessary; returns false in case this fails. */ -STATIC int s_qmul(klisp_State *K, mp_int z, mp_size p2); +STATIC int s_qmul(klisp_State *K, mp_int z, mp_size p2); /* Quick subtraction from a power of 2, replaces z. Allocates if necessary; returns false in case this fails. */ -STATIC int s_qsub(klisp_State *K, mp_int z, mp_size p2); +STATIC int s_qsub(klisp_State *K, mp_int z, mp_size p2); /* Return maximum k such that 2^k divides z. */ -STATIC int s_dp2k(mp_int z); +STATIC int s_dp2k(mp_int z); /* Return k >= 0 such that z = 2^k, or -1 if there is no such k. */ -STATIC int s_isp2(mp_int z); +STATIC int s_isp2(mp_int z); /* Set z to 2^k. May allocate; returns false in case this fails. */ -STATIC int s_2expt(klisp_State *K, mp_int z, mp_small k); +STATIC int s_2expt(klisp_State *K, mp_int z, mp_small k); /* Normalize a and b for division, returns normalization constant */ -STATIC int s_norm(klisp_State *K, mp_int a, mp_int b); +STATIC int s_norm(klisp_State *K, mp_int a, mp_int b); /* Compute constant mu for Barrett reduction, given modulus m, result replaces z, m is untouched. */ STATIC mp_result s_brmu(klisp_State *K, mp_int z, mp_int m); /* Reduce a modulo m, using Barrett's algorithm. */ -STATIC int s_reduce(klisp_State *K, mp_int x, mp_int m, mp_int mu, - mp_int q1, mp_int q2); +STATIC int s_reduce(klisp_State *K, mp_int x, mp_int m, mp_int mu, + mp_int q1, mp_int q2); /* Modular exponentiation, using Barrett reduction */ STATIC mp_result s_embar(klisp_State *K, mp_int a, mp_int b, mp_int m, - mp_int mu, mp_int c); + mp_int mu, mp_int c); /* Unsigned magnitude division. Assumes |a| > |b|. Allocates temporaries; overwrites a with quotient, b with remainder. */ @@ -324,7 +324,7 @@ STATIC mp_result s_udiv(klisp_State *K, mp_int a, mp_int b); /* Compute the number of digits in radix r required to represent the given value. Does not account for sign flags, terminators, etc. */ -STATIC int s_outlen(mp_int z, mp_size r); +STATIC int s_outlen(mp_int z, mp_size r); /* Guess how many digits of precision will be needed to represent a radix r value of the specified number of digits. Returns a value @@ -333,13 +333,13 @@ STATIC mp_size s_inlen(int len, mp_size r); /* Convert a character to a digit value in radix r, or -1 if out of range */ -STATIC int s_ch2val(char c, int r); +STATIC int s_ch2val(char c, int r); /* Convert a digit value to a character */ -STATIC char s_val2ch(int v, int caps); +STATIC char s_val2ch(int v, int caps); /* Take 2's complement of a buffer in place */ -STATIC void s_2comp(unsigned char *buf, int len); +STATIC void s_2comp(unsigned char *buf, int len); /* Convert a value to binary, ignoring sign. On input, *limpos is the bound on how many bytes should be written to buf; on output, *limpos @@ -348,24 +348,24 @@ STATIC mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad); #if DEBUG /* Dump a representation of the mp_int to standard output */ -void s_print(char *tag, mp_int z); -void s_print_buf(char *tag, mp_digit *buf, mp_size num); +void s_print(char *tag, mp_int z); +void s_print_buf(char *tag, mp_digit *buf, mp_size num); #endif /* {{{ mp_int_init(z) */ mp_result mp_int_init(mp_int z) { - if(z == NULL) - return MP_BADARG; + if(z == NULL) + return MP_BADARG; - z->single = 0; - z->digits = &(z->single); - z->alloc = 1; - z->used = 1; - z->sign = MP_ZPOS; + z->single = 0; + z->digits = &(z->single); + z->alloc = 1; + z->used = 1; + z->sign = MP_ZPOS; - return MP_OK; + return MP_OK; } /* }}} */ @@ -374,12 +374,12 @@ mp_result mp_int_init(mp_int z) mp_int mp_int_alloc(klisp_State *K) { - mp_int out = klispM_new(K, mpz_t); + mp_int out = klispM_new(K, mpz_t); - if(out != NULL) - mp_int_init(out); + if(out != NULL) + mp_int_init(out); - return out; + return out; } /* }}} */ @@ -388,24 +388,24 @@ mp_int mp_int_alloc(klisp_State *K) mp_result mp_int_init_size(klisp_State *K, mp_int z, mp_size prec) { - CHECK(z != NULL); + CHECK(z != NULL); - if(prec == 0) - prec = default_precision; - else if(prec == 1) - return mp_int_init(z); - else - prec = (mp_size) ROUND_PREC(prec); + if(prec == 0) + prec = default_precision; + else if(prec == 1) + return mp_int_init(z); + else + prec = (mp_size) ROUND_PREC(prec); - if((MP_DIGITS(z) = s_alloc(K, prec)) == NULL) - return MP_MEMORY; + if((MP_DIGITS(z) = s_alloc(K, prec)) == NULL) + return MP_MEMORY; - z->digits[0] = 0; - MP_USED(z) = 1; - MP_ALLOC(z) = prec; - MP_SIGN(z) = MP_ZPOS; + z->digits[0] = 0; + MP_USED(z) = 1; + MP_ALLOC(z) = prec; + MP_SIGN(z) = MP_ZPOS; - return MP_OK; + return MP_OK; } /* }}} */ @@ -414,27 +414,27 @@ mp_result mp_int_init_size(klisp_State *K, mp_int z, mp_size prec) mp_result mp_int_init_copy(klisp_State *K, mp_int z, mp_int old) { - mp_result res; - mp_size uold; + mp_result res; + mp_size uold; - CHECK(z != NULL && old != NULL); + CHECK(z != NULL && old != NULL); - uold = MP_USED(old); - if(uold == 1) { - mp_int_init(z); - } - else { - mp_size target = MAX(uold, default_precision); + uold = MP_USED(old); + if(uold == 1) { + mp_int_init(z); + } + else { + mp_size target = MAX(uold, default_precision); - if((res = mp_int_init_size(K, z, target)) != MP_OK) - return res; - } + if((res = mp_int_init_size(K, z, target)) != MP_OK) + return res; + } - MP_USED(z) = uold; - MP_SIGN(z) = MP_SIGN(old); - COPY(MP_DIGITS(old), MP_DIGITS(z), uold); + MP_USED(z) = uold; + MP_SIGN(z) = MP_SIGN(old); + COPY(MP_DIGITS(old), MP_DIGITS(z), uold); - return MP_OK; + return MP_OK; } /* }}} */ @@ -443,11 +443,11 @@ mp_result mp_int_init_copy(klisp_State *K, mp_int z, mp_int old) mp_result mp_int_init_value(klisp_State *K, mp_int z, mp_small value) { - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; - s_fake(&vtmp, value, vbuf); - return mp_int_init_copy(K, z, &vtmp); + s_fake(&vtmp, value, vbuf); + return mp_int_init_copy(K, z, &vtmp); } /* }}} */ @@ -456,39 +456,39 @@ mp_result mp_int_init_value(klisp_State *K, mp_int z, mp_small value) mp_result mp_int_set_value(klisp_State *K, mp_int z, mp_small value) { - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; - s_fake(&vtmp, value, vbuf); - return mp_int_copy(K, &vtmp, z); + s_fake(&vtmp, value, vbuf); + return mp_int_copy(K, &vtmp, z); } /* }}} */ /* {{{ mp_int_clear(z) */ -void mp_int_clear(klisp_State *K, mp_int z) +void mp_int_clear(klisp_State *K, mp_int z) { - if(z == NULL) - return; + if(z == NULL) + return; - if(MP_DIGITS(z) != NULL) { - if((void *) MP_DIGITS(z) != (void *) &MP_SINGLE(z)) - s_free(K, MP_DIGITS(z), MP_ALLOC(z)); - MP_DIGITS(z) = NULL; - } + if(MP_DIGITS(z) != NULL) { + if((void *) MP_DIGITS(z) != (void *) &MP_SINGLE(z)) + s_free(K, MP_DIGITS(z), MP_ALLOC(z)); + MP_DIGITS(z) = NULL; + } } /* }}} */ /* {{{ mp_int_free(z) */ -void mp_int_free(klisp_State *K, mp_int z) +void mp_int_free(klisp_State *K, mp_int z) { - NRCHECK(z != NULL); + NRCHECK(z != NULL); - mp_int_clear(K, z); - klispM_free(K, z); /* note: NOT s_free() */ + mp_int_clear(K, z); + klispM_free(K, z); /* note: NOT s_free() */ } /* }}} */ @@ -497,57 +497,57 @@ void mp_int_free(klisp_State *K, mp_int z) mp_result mp_int_copy(klisp_State *K, mp_int a, mp_int c) { - CHECK(a != NULL && c != NULL); + CHECK(a != NULL && c != NULL); - if(a != c) { - mp_size ua = MP_USED(a); - mp_digit *da, *dc; + if(a != c) { + mp_size ua = MP_USED(a); + mp_digit *da, *dc; - if(!s_pad(K, c, ua)) - return MP_MEMORY; + if(!s_pad(K, c, ua)) + return MP_MEMORY; - da = MP_DIGITS(a); dc = MP_DIGITS(c); - COPY(da, dc, ua); + da = MP_DIGITS(a); dc = MP_DIGITS(c); + COPY(da, dc, ua); - MP_USED(c) = ua; - MP_SIGN(c) = MP_SIGN(a); - } + MP_USED(c) = ua; + MP_SIGN(c) = MP_SIGN(a); + } - return MP_OK; + return MP_OK; } /* }}} */ /* {{{ mp_int_swap(a, c) */ -void mp_int_swap(mp_int a, mp_int c) +void mp_int_swap(mp_int a, mp_int c) { - if(a != c) { - mpz_t tmp = *a; + if(a != c) { + mpz_t tmp = *a; - *a = *c; - *c = tmp; - /* Andres Navarro: bugfix */ - /* correct if digits was pointing to single */ - if (a->digits == &c->single) - a->digits = &a->single; - if (c->digits == &a->single) - c->digits = &c->single; - /* Andres Navarro: /bugfix */ - } + *a = *c; + *c = tmp; + /* Andres Navarro: bugfix */ + /* correct if digits was pointing to single */ + if (a->digits == &c->single) + a->digits = &a->single; + if (c->digits == &a->single) + c->digits = &c->single; + /* Andres Navarro: /bugfix */ + } } /* }}} */ /* {{{ mp_int_zero(z) */ -void mp_int_zero(mp_int z) +void mp_int_zero(mp_int z) { - NRCHECK(z != NULL); + NRCHECK(z != NULL); - z->digits[0] = 0; - MP_USED(z) = 1; - MP_SIGN(z) = MP_ZPOS; + z->digits[0] = 0; + MP_USED(z) = 1; + MP_SIGN(z) = MP_ZPOS; } /* }}} */ @@ -556,15 +556,15 @@ void mp_int_zero(mp_int z) mp_result mp_int_abs(klisp_State *K, mp_int a, mp_int c) { - mp_result res; + mp_result res; - CHECK(a != NULL && c != NULL); + CHECK(a != NULL && c != NULL); - if((res = mp_int_copy(K, a, c)) != MP_OK) - return res; + if((res = mp_int_copy(K, a, c)) != MP_OK) + return res; - MP_SIGN(c) = MP_ZPOS; - return MP_OK; + MP_SIGN(c) = MP_ZPOS; + return MP_OK; } /* }}} */ @@ -573,17 +573,17 @@ mp_result mp_int_abs(klisp_State *K, mp_int a, mp_int c) mp_result mp_int_neg(klisp_State *K, mp_int a, mp_int c) { - mp_result res; + mp_result res; - CHECK(a != NULL && c != NULL); + CHECK(a != NULL && c != NULL); - if((res = mp_int_copy(K, a, c)) != MP_OK) - return res; + if((res = mp_int_copy(K, a, c)) != MP_OK) + return res; - if(CMPZ(c) != 0) - MP_SIGN(c) = 1 - MP_SIGN(a); + if(CMPZ(c) != 0) + MP_SIGN(c) = 1 - MP_SIGN(a); - return MP_OK; + return MP_OK; } /* }}} */ @@ -592,67 +592,67 @@ mp_result mp_int_neg(klisp_State *K, mp_int a, mp_int c) mp_result mp_int_add(klisp_State *K, mp_int a, mp_int b, mp_int c) { - mp_size ua, ub, uc, max; - - CHECK(a != NULL && b != NULL && c != NULL); + mp_size ua, ub, uc, max; - ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c); - max = MAX(ua, ub); + CHECK(a != NULL && b != NULL && c != NULL); - if(MP_SIGN(a) == MP_SIGN(b)) { - /* Same sign -- add magnitudes, preserve sign of addends */ - mp_digit carry; + ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c); + max = MAX(ua, ub); - if(!s_pad(K, c, max)) - return MP_MEMORY; + if(MP_SIGN(a) == MP_SIGN(b)) { + /* Same sign -- add magnitudes, preserve sign of addends */ + mp_digit carry; - carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); - uc = max; + if(!s_pad(K, c, max)) + return MP_MEMORY; - if(carry) { - if(!s_pad(K, c, max + 1)) - return MP_MEMORY; + carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); + uc = max; - c->digits[max] = carry; - ++uc; - } + if(carry) { + if(!s_pad(K, c, max + 1)) + return MP_MEMORY; - MP_USED(c) = uc; - MP_SIGN(c) = MP_SIGN(a); + c->digits[max] = carry; + ++uc; + } - } - else { - /* Different signs -- subtract magnitudes, preserve sign of greater */ - mp_int x, y; - int cmp = s_ucmp(a, b); /* magnitude comparision, sign ignored */ + MP_USED(c) = uc; + MP_SIGN(c) = MP_SIGN(a); - /* Set x to max(a, b), y to min(a, b) to simplify later code. - A special case yields zero for equal magnitudes. - */ - if(cmp == 0) { - mp_int_zero(c); - return MP_OK; - } - else if(cmp < 0) { - x = b; y = a; - } + } else { - x = a; y = b; - } - - if(!s_pad(K, c, MP_USED(x))) - return MP_MEMORY; - - /* Subtract smaller from larger */ - s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); - MP_USED(c) = MP_USED(x); - CLAMP(c); + /* Different signs -- subtract magnitudes, preserve sign of greater */ + mp_int x, y; + int cmp = s_ucmp(a, b); /* magnitude comparision, sign ignored */ + + /* Set x to max(a, b), y to min(a, b) to simplify later code. + A special case yields zero for equal magnitudes. + */ + if(cmp == 0) { + mp_int_zero(c); + return MP_OK; + } + else if(cmp < 0) { + x = b; y = a; + } + else { + x = a; y = b; + } + + if(!s_pad(K, c, MP_USED(x))) + return MP_MEMORY; + + /* Subtract smaller from larger */ + s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); + MP_USED(c) = MP_USED(x); + CLAMP(c); - /* Give result the sign of the larger */ - MP_SIGN(c) = MP_SIGN(x); - } + /* Give result the sign of the larger */ + MP_SIGN(c) = MP_SIGN(x); + } - return MP_OK; + return MP_OK; } /* }}} */ @@ -661,12 +661,12 @@ mp_result mp_int_add(klisp_State *K, mp_int a, mp_int b, mp_int c) mp_result mp_int_add_value(klisp_State *K, mp_int a, mp_small value, mp_int c) { - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; - s_fake(&vtmp, value, vbuf); + s_fake(&vtmp, value, vbuf); - return mp_int_add(K, a, &vtmp, c); + return mp_int_add(K, a, &vtmp, c); } /* }}} */ @@ -675,62 +675,62 @@ mp_result mp_int_add_value(klisp_State *K, mp_int a, mp_small value, mp_int c) mp_result mp_int_sub(klisp_State *K, mp_int a, mp_int b, mp_int c) { - mp_size ua, ub, uc, max; - - CHECK(a != NULL && b != NULL && c != NULL); + mp_size ua, ub, uc, max; - ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c); - max = MAX(ua, ub); + CHECK(a != NULL && b != NULL && c != NULL); - if(MP_SIGN(a) != MP_SIGN(b)) { - /* Different signs -- add magnitudes and keep sign of a */ - mp_digit carry; + ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c); + max = MAX(ua, ub); - if(!s_pad(K, c, max)) - return MP_MEMORY; + if(MP_SIGN(a) != MP_SIGN(b)) { + /* Different signs -- add magnitudes and keep sign of a */ + mp_digit carry; - carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); - uc = max; + if(!s_pad(K, c, max)) + return MP_MEMORY; - if(carry) { - if(!s_pad(K, c, max + 1)) - return MP_MEMORY; + carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); + uc = max; - c->digits[max] = carry; - ++uc; - } + if(carry) { + if(!s_pad(K, c, max + 1)) + return MP_MEMORY; - MP_USED(c) = uc; - MP_SIGN(c) = MP_SIGN(a); + c->digits[max] = carry; + ++uc; + } - } - else { - /* Same signs -- subtract magnitudes */ - mp_int x, y; - mp_sign osign; - int cmp = s_ucmp(a, b); + MP_USED(c) = uc; + MP_SIGN(c) = MP_SIGN(a); - if(!s_pad(K, c, max)) - return MP_MEMORY; - - if(cmp >= 0) { - x = a; y = b; osign = MP_ZPOS; } else { - x = b; y = a; osign = MP_NEG; - } + /* Same signs -- subtract magnitudes */ + mp_int x, y; + mp_sign osign; + int cmp = s_ucmp(a, b); - if(MP_SIGN(a) == MP_NEG && cmp != 0) - osign = 1 - osign; + if(!s_pad(K, c, max)) + return MP_MEMORY; - s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); - MP_USED(c) = MP_USED(x); - CLAMP(c); + if(cmp >= 0) { + x = a; y = b; osign = MP_ZPOS; + } + else { + x = b; y = a; osign = MP_NEG; + } - MP_SIGN(c) = osign; - } + if(MP_SIGN(a) == MP_NEG && cmp != 0) + osign = 1 - osign; + + s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); + MP_USED(c) = MP_USED(x); + CLAMP(c); + + MP_SIGN(c) = osign; + } - return MP_OK; + return MP_OK; } /* }}} */ @@ -739,12 +739,12 @@ mp_result mp_int_sub(klisp_State *K, mp_int a, mp_int b, mp_int c) mp_result mp_int_sub_value(klisp_State *K, mp_int a, mp_small value, mp_int c) { - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; - s_fake(&vtmp, value, vbuf); + s_fake(&vtmp, value, vbuf); - return mp_int_sub(K, a, &vtmp, c); + return mp_int_sub(K, a, &vtmp, c); } /* }}} */ @@ -753,60 +753,60 @@ mp_result mp_int_sub_value(klisp_State *K, mp_int a, mp_small value, mp_int c) mp_result mp_int_mul(klisp_State *K, mp_int a, mp_int b, mp_int c) { - mp_digit *out; - mp_size osize, ua, ub, p = 0; - mp_sign osign; + mp_digit *out; + mp_size osize, ua, ub, p = 0; + mp_sign osign; - CHECK(a != NULL && b != NULL && c != NULL); + CHECK(a != NULL && b != NULL && c != NULL); - /* If either input is zero, we can shortcut multiplication */ - if(mp_int_compare_zero(a) == 0 || mp_int_compare_zero(b) == 0) { - mp_int_zero(c); - return MP_OK; - } + /* If either input is zero, we can shortcut multiplication */ + if(mp_int_compare_zero(a) == 0 || mp_int_compare_zero(b) == 0) { + mp_int_zero(c); + return MP_OK; + } - /* Output is positive if inputs have same sign, otherwise negative */ - osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG; - - /* If the output is not identical to any of the inputs, we'll write - the results directly; otherwise, allocate a temporary space. */ - ua = MP_USED(a); ub = MP_USED(b); - osize = MAX(ua, ub); - osize = 4 * ((osize + 1) / 2); - - if(c == a || c == b) { - p = ROUND_PREC(osize); - p = MAX(p, default_precision); - - if((out = s_alloc(K, p)) == NULL) - return MP_MEMORY; - } - else { - if(!s_pad(K, c, osize)) - return MP_MEMORY; + /* Output is positive if inputs have same sign, otherwise negative */ + osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG; + + /* If the output is not identical to any of the inputs, we'll write + the results directly; otherwise, allocate a temporary space. */ + ua = MP_USED(a); ub = MP_USED(b); + osize = MAX(ua, ub); + osize = 4 * ((osize + 1) / 2); + + if(c == a || c == b) { + p = ROUND_PREC(osize); + p = MAX(p, default_precision); + + if((out = s_alloc(K, p)) == NULL) + return MP_MEMORY; + } + else { + if(!s_pad(K, c, osize)) + return MP_MEMORY; - out = MP_DIGITS(c); - } - ZERO(out, osize); - - if(!s_kmul(K, MP_DIGITS(a), MP_DIGITS(b), out, ua, ub)) - return MP_MEMORY; - - /* If we allocated a new buffer, get rid of whatever memory c was - already using, and fix up its fields to reflect that. - */ - if(out != MP_DIGITS(c)) { - if((void *) MP_DIGITS(c) != (void *) &MP_SINGLE(c)) - s_free(K, MP_DIGITS(c), MP_ALLOC(c)); - MP_DIGITS(c) = out; - MP_ALLOC(c) = p; - } - - MP_USED(c) = osize; /* might not be true, but we'll fix it ... */ - CLAMP(c); /* ... right here */ - MP_SIGN(c) = osign; + out = MP_DIGITS(c); + } + ZERO(out, osize); + + if(!s_kmul(K, MP_DIGITS(a), MP_DIGITS(b), out, ua, ub)) + return MP_MEMORY; + + /* If we allocated a new buffer, get rid of whatever memory c was + already using, and fix up its fields to reflect that. + */ + if(out != MP_DIGITS(c)) { + if((void *) MP_DIGITS(c) != (void *) &MP_SINGLE(c)) + s_free(K, MP_DIGITS(c), MP_ALLOC(c)); + MP_DIGITS(c) = out; + MP_ALLOC(c) = p; + } + + MP_USED(c) = osize; /* might not be true, but we'll fix it ... */ + CLAMP(c); /* ... right here */ + MP_SIGN(c) = osign; - return MP_OK; + return MP_OK; } /* }}} */ @@ -814,14 +814,14 @@ mp_result mp_int_mul(klisp_State *K, mp_int a, mp_int b, mp_int c) /* {{{ mp_int_mul_value(a, value, c) */ mp_result mp_int_mul_value(klisp_State *K, mp_int a, mp_small value, - mp_int c) + mp_int c) { - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; - s_fake(&vtmp, value, vbuf); + s_fake(&vtmp, value, vbuf); - return mp_int_mul(K, a, &vtmp, c); + return mp_int_mul(K, a, &vtmp, c); } /* }}} */ @@ -830,16 +830,16 @@ mp_result mp_int_mul_value(klisp_State *K, mp_int a, mp_small value, mp_result mp_int_mul_pow2(klisp_State *K, mp_int a, mp_small p2, mp_int c) { - mp_result res; - CHECK(a != NULL && c != NULL && p2 >= 0); + mp_result res; + CHECK(a != NULL && c != NULL && p2 >= 0); - if((res = mp_int_copy(K, a, c)) != MP_OK) - return res; + if((res = mp_int_copy(K, a, c)) != MP_OK) + return res; - if(s_qmul(K, c, (mp_size) p2)) - return MP_OK; - else - return MP_MEMORY; + if(s_qmul(K, c, (mp_size) p2)) + return MP_OK; + else + return MP_MEMORY; } /* }}} */ @@ -848,45 +848,45 @@ mp_result mp_int_mul_pow2(klisp_State *K, mp_int a, mp_small p2, mp_int c) mp_result mp_int_sqr(klisp_State *K, mp_int a, mp_int c) { - mp_digit *out; - mp_size osize, p = 0; - - CHECK(a != NULL && c != NULL); - - /* Get a temporary buffer big enough to hold the result */ - osize = (mp_size) 4 * ((MP_USED(a) + 1) / 2); - if(a == c) { - p = ROUND_PREC(osize); - p = MAX(p, default_precision); - - if((out = s_alloc(K, p)) == NULL) - return MP_MEMORY; - } - else { - if(!s_pad(K, c, osize)) - return MP_MEMORY; - - out = MP_DIGITS(c); - } - ZERO(out, osize); - - s_ksqr(K, MP_DIGITS(a), out, MP_USED(a)); - - /* Get rid of whatever memory c was already using, and fix up its - fields to reflect the new digit array it's using - */ - if(out != MP_DIGITS(c)) { - if((void *) MP_DIGITS(c) != (void *) &MP_SINGLE(c)) - s_free(K, MP_DIGITS(c), MP_ALLOC(c)); - MP_DIGITS(c) = out; - MP_ALLOC(c) = p; - } - - MP_USED(c) = osize; /* might not be true, but we'll fix it ... */ - CLAMP(c); /* ... right here */ - MP_SIGN(c) = MP_ZPOS; + mp_digit *out; + mp_size osize, p = 0; + + CHECK(a != NULL && c != NULL); + + /* Get a temporary buffer big enough to hold the result */ + osize = (mp_size) 4 * ((MP_USED(a) + 1) / 2); + if(a == c) { + p = ROUND_PREC(osize); + p = MAX(p, default_precision); + + if((out = s_alloc(K, p)) == NULL) + return MP_MEMORY; + } + else { + if(!s_pad(K, c, osize)) + return MP_MEMORY; + + out = MP_DIGITS(c); + } + ZERO(out, osize); + + s_ksqr(K, MP_DIGITS(a), out, MP_USED(a)); + + /* Get rid of whatever memory c was already using, and fix up its + fields to reflect the new digit array it's using + */ + if(out != MP_DIGITS(c)) { + if((void *) MP_DIGITS(c) != (void *) &MP_SINGLE(c)) + s_free(K, MP_DIGITS(c), MP_ALLOC(c)); + MP_DIGITS(c) = out; + MP_ALLOC(c) = p; + } + + MP_USED(c) = osize; /* might not be true, but we'll fix it ... */ + CLAMP(c); /* ... right here */ + MP_SIGN(c) = MP_ZPOS; - return MP_OK; + return MP_OK; } /* }}} */ @@ -895,103 +895,103 @@ mp_result mp_int_sqr(klisp_State *K, mp_int a, mp_int c) mp_result mp_int_div(klisp_State *K, mp_int a, mp_int b, mp_int q, mp_int r) { - int cmp, last = 0, lg; - mp_result res = MP_OK; - mpz_t temp[2]; - mp_int qout, rout; - mp_sign sa = MP_SIGN(a), sb = MP_SIGN(b); + int cmp, last = 0, lg; + mp_result res = MP_OK; + mpz_t temp[2]; + mp_int qout, rout; + mp_sign sa = MP_SIGN(a), sb = MP_SIGN(b); - CHECK(a != NULL && b != NULL && q != r); + CHECK(a != NULL && b != NULL && q != r); - if(CMPZ(b) == 0) - return MP_UNDEF; - else if((cmp = s_ucmp(a, b)) < 0) { - /* If |a| < |b|, no division is required: - q = 0, r = a - */ - if(r && (res = mp_int_copy(K, a, r)) != MP_OK) - return res; - - if(q) - mp_int_zero(q); - - return MP_OK; - } - else if(cmp == 0) { - /* If |a| = |b|, no division is required: - q = 1 or -1, r = 0 - */ - if(r) - mp_int_zero(r); - - if(q) { - mp_int_zero(q); - q->digits[0] = 1; - - if(sa != sb) - MP_SIGN(q) = MP_NEG; - } - - return MP_OK; - } - - /* When |a| > |b|, real division is required. We need someplace to - store quotient and remainder, but q and r are allowed to be NULL - or to overlap with the inputs. - */ - if((lg = s_isp2(b)) < 0) { - if(q && b != q) { - if((res = mp_int_copy(K, a, q)) != MP_OK) - goto CLEANUP; - else - qout = q; + if(CMPZ(b) == 0) + return MP_UNDEF; + else if((cmp = s_ucmp(a, b)) < 0) { + /* If |a| < |b|, no division is required: + q = 0, r = a + */ + if(r && (res = mp_int_copy(K, a, r)) != MP_OK) + return res; + + if(q) + mp_int_zero(q); + + return MP_OK; + } + else if(cmp == 0) { + /* If |a| = |b|, no division is required: + q = 1 or -1, r = 0 + */ + if(r) + mp_int_zero(r); + + if(q) { + mp_int_zero(q); + q->digits[0] = 1; + + if(sa != sb) + MP_SIGN(q) = MP_NEG; + } + + return MP_OK; } - else { - qout = TEMP(last); - SETUP(mp_int_init_copy(K, TEMP(last), a), last); - } - if(r && a != r) { - if((res = mp_int_copy(K, b, r)) != MP_OK) - goto CLEANUP; - else - rout = r; + /* When |a| > |b|, real division is required. We need someplace to + store quotient and remainder, but q and r are allowed to be NULL + or to overlap with the inputs. + */ + if((lg = s_isp2(b)) < 0) { + if(q && b != q) { + if((res = mp_int_copy(K, a, q)) != MP_OK) + goto CLEANUP; + else + qout = q; + } + else { + qout = TEMP(last); + SETUP(mp_int_init_copy(K, TEMP(last), a), last); + } + + if(r && a != r) { + if((res = mp_int_copy(K, b, r)) != MP_OK) + goto CLEANUP; + else + rout = r; + } + else { + rout = TEMP(last); + SETUP(mp_int_init_copy(K, TEMP(last), b), last); + } + + if((res = s_udiv(K, qout, rout)) != MP_OK) goto CLEANUP; } else { - rout = TEMP(last); - SETUP(mp_int_init_copy(K, TEMP(last), b), last); - } + if(q && (res = mp_int_copy(K, a, q)) != MP_OK) goto CLEANUP; + if(r && (res = mp_int_copy(K, a, r)) != MP_OK) goto CLEANUP; - if((res = s_udiv(K, qout, rout)) != MP_OK) goto CLEANUP; - } - else { - if(q && (res = mp_int_copy(K, a, q)) != MP_OK) goto CLEANUP; - if(r && (res = mp_int_copy(K, a, r)) != MP_OK) goto CLEANUP; - - if(q) s_qdiv(q, (mp_size) lg); qout = q; - if(r) s_qmod(r, (mp_size) lg); rout = r; - } + if(q) s_qdiv(q, (mp_size) lg); qout = q; + if(r) s_qmod(r, (mp_size) lg); rout = r; + } - /* Recompute signs for output */ - if(rout) { - MP_SIGN(rout) = sa; - if(CMPZ(rout) == 0) - MP_SIGN(rout) = MP_ZPOS; - } - if(qout) { - MP_SIGN(qout) = (sa == sb) ? MP_ZPOS : MP_NEG; - if(CMPZ(qout) == 0) - MP_SIGN(qout) = MP_ZPOS; - } + /* Recompute signs for output */ + if(rout) { + MP_SIGN(rout) = sa; + if(CMPZ(rout) == 0) + MP_SIGN(rout) = MP_ZPOS; + } + if(qout) { + MP_SIGN(qout) = (sa == sb) ? MP_ZPOS : MP_NEG; + if(CMPZ(qout) == 0) + MP_SIGN(qout) = MP_ZPOS; + } - if(q && (res = mp_int_copy(K, qout, q)) != MP_OK) goto CLEANUP; - if(r && (res = mp_int_copy(K, rout, r)) != MP_OK) goto CLEANUP; + if(q && (res = mp_int_copy(K, qout, q)) != MP_OK) goto CLEANUP; + if(r && (res = mp_int_copy(K, rout, r)) != MP_OK) goto CLEANUP; - CLEANUP: - while(--last >= 0) - mp_int_clear(K, TEMP(last)); +CLEANUP: + while(--last >= 0) + mp_int_clear(K, TEMP(last)); - return res; + return res; } /* }}} */ @@ -1000,31 +1000,31 @@ mp_result mp_int_div(klisp_State *K, mp_int a, mp_int b, mp_int q, mp_int r) mp_result mp_int_mod(klisp_State *K, mp_int a, mp_int m, mp_int c) { - mp_result res; - mpz_t tmp; - mp_int out; + mp_result res; + mpz_t tmp; + mp_int out; - if(m == c) { - mp_int_init(&tmp); - out = &tmp; - } - else { - out = c; - } + if(m == c) { + mp_int_init(&tmp); + out = &tmp; + } + else { + out = c; + } - if((res = mp_int_div(K, a, m, NULL, out)) != MP_OK) - goto CLEANUP; + if((res = mp_int_div(K, a, m, NULL, out)) != MP_OK) + goto CLEANUP; - if(CMPZ(out) < 0) - res = mp_int_add(K, out, m, c); - else - res = mp_int_copy(K, out, c); + if(CMPZ(out) < 0) + res = mp_int_add(K, out, m, c); + else + res = mp_int_copy(K, out, c); - CLEANUP: - if(out != c) - mp_int_clear(K, &tmp); +CLEANUP: + if(out != c) + mp_int_clear(K, &tmp); - return res; + return res; } /* }}} */ @@ -1032,24 +1032,24 @@ mp_result mp_int_mod(klisp_State *K, mp_int a, mp_int m, mp_int c) /* {{{ mp_int_div_value(a, value, q, r) */ mp_result mp_int_div_value(klisp_State *K, mp_int a, mp_small value, - mp_int q, mp_small *r) + mp_int q, mp_small *r) { - mpz_t vtmp, rtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; - mp_result res; + mpz_t vtmp, rtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + mp_result res; - mp_int_init(&rtmp); - s_fake(&vtmp, value, vbuf); + mp_int_init(&rtmp); + s_fake(&vtmp, value, vbuf); - if((res = mp_int_div(K, a, &vtmp, q, &rtmp)) != MP_OK) - goto CLEANUP; + if((res = mp_int_div(K, a, &vtmp, q, &rtmp)) != MP_OK) + goto CLEANUP; - if(r) - (void) mp_int_to_int(&rtmp, r); /* can't fail */ + if(r) + (void) mp_int_to_int(&rtmp, r); /* can't fail */ - CLEANUP: - mp_int_clear(K, &rtmp); - return res; +CLEANUP: + mp_int_clear(K, &rtmp); + return res; } /* }}} */ @@ -1057,19 +1057,19 @@ mp_result mp_int_div_value(klisp_State *K, mp_int a, mp_small value, /* {{{ mp_int_div_pow2(a, p2, q, r) */ mp_result mp_int_div_pow2(klisp_State *K, mp_int a, mp_small p2, mp_int q, - mp_int r) + mp_int r) { - mp_result res = MP_OK; + mp_result res = MP_OK; - CHECK(a != NULL && p2 >= 0 && q != r); + CHECK(a != NULL && p2 >= 0 && q != r); - if(q != NULL && (res = mp_int_copy(K, a, q)) == MP_OK) - s_qdiv(q, (mp_size) p2); + if(q != NULL && (res = mp_int_copy(K, a, q)) == MP_OK) + s_qdiv(q, (mp_size) p2); - if(res == MP_OK && r != NULL && (res = mp_int_copy(K, a, r)) == MP_OK) - s_qmod(r, (mp_size) p2); + if(res == MP_OK && r != NULL && (res = mp_int_copy(K, a, r)) == MP_OK) + s_qmod(r, (mp_size) p2); - return res; + return res; } /* }}} */ @@ -1078,34 +1078,34 @@ mp_result mp_int_div_pow2(klisp_State *K, mp_int a, mp_small p2, mp_int q, mp_result mp_int_expt(klisp_State *K, mp_int a, mp_small b, mp_int c) { - mpz_t t; - mp_result res; - unsigned int v = abs(b); + mpz_t t; + mp_result res; + unsigned int v = abs(b); - CHECK(c != NULL); + CHECK(c != NULL); - CHECK(b >= 0 && c != NULL); + CHECK(b >= 0 && c != NULL); - if((res = mp_int_init_copy(K, &t, a)) != MP_OK) - return res; + if((res = mp_int_init_copy(K, &t, a)) != MP_OK) + return res; - (void) mp_int_set_value(K, c, 1); - while(v != 0) { - if(v & 1) { - if((res = mp_int_mul(K, c, &t, c)) != MP_OK) - goto CLEANUP; - } + (void) mp_int_set_value(K, c, 1); + while(v != 0) { + if(v & 1) { + if((res = mp_int_mul(K, c, &t, c)) != MP_OK) + goto CLEANUP; + } - v >>= 1; - if(v == 0) break; + v >>= 1; + if(v == 0) break; - if((res = mp_int_sqr(K, &t, &t)) != MP_OK) - goto CLEANUP; - } + if((res = mp_int_sqr(K, &t, &t)) != MP_OK) + goto CLEANUP; + } - CLEANUP: - mp_int_clear(K, &t); - return res; +CLEANUP: + mp_int_clear(K, &t); + return res; } /* }}} */ @@ -1114,32 +1114,32 @@ mp_result mp_int_expt(klisp_State *K, mp_int a, mp_small b, mp_int c) mp_result mp_int_expt_value(klisp_State *K, mp_small a, mp_small b, mp_int c) { - mpz_t t; - mp_result res; - unsigned int v = abs(b); + mpz_t t; + mp_result res; + unsigned int v = abs(b); - CHECK(b >= 0 && c != NULL); + CHECK(b >= 0 && c != NULL); - if((res = mp_int_init_value(K, &t, a)) != MP_OK) - return res; + if((res = mp_int_init_value(K, &t, a)) != MP_OK) + return res; - (void) mp_int_set_value(K, c, 1); - while(v != 0) { - if(v & 1) { - if((res = mp_int_mul(K, c, &t, c)) != MP_OK) - goto CLEANUP; - } + (void) mp_int_set_value(K, c, 1); + while(v != 0) { + if(v & 1) { + if((res = mp_int_mul(K, c, &t, c)) != MP_OK) + goto CLEANUP; + } - v >>= 1; - if(v == 0) break; + v >>= 1; + if(v == 0) break; - if((res = mp_int_sqr(K, &t, &t)) != MP_OK) - goto CLEANUP; - } + if((res = mp_int_sqr(K, &t, &t)) != MP_OK) + goto CLEANUP; + } - CLEANUP: - mp_int_clear(K, &t); - return res; +CLEANUP: + mp_int_clear(K, &t); + return res; } /* }}} */ @@ -1148,120 +1148,120 @@ mp_result mp_int_expt_value(klisp_State *K, mp_small a, mp_small b, mp_int c) mp_result mp_int_expt_full(klisp_State *K, mp_int a, mp_int b, mp_int c) { - mpz_t t; - mp_result res; - int ix, jx; + mpz_t t; + mp_result res; + int ix, jx; - CHECK(a != NULL && b != NULL && c != NULL); + CHECK(a != NULL && b != NULL && c != NULL); - if ((res = mp_int_init_copy(K, &t, a)) != MP_OK) - return res; + if ((res = mp_int_init_copy(K, &t, a)) != MP_OK) + return res; - (void) mp_int_set_value(K, c, 1); - for (ix = 0; ix < MP_USED(b); ++ix) { - mp_digit d = b->digits[ix]; + (void) mp_int_set_value(K, c, 1); + for (ix = 0; ix < MP_USED(b); ++ix) { + mp_digit d = b->digits[ix]; - for (jx = 0; jx < MP_DIGIT_BIT; ++jx) { - if (d & 1) { - if ((res = mp_int_mul(K, c, &t, c)) != MP_OK) - goto CLEANUP; - } + for (jx = 0; jx < MP_DIGIT_BIT; ++jx) { + if (d & 1) { + if ((res = mp_int_mul(K, c, &t, c)) != MP_OK) + goto CLEANUP; + } - d >>= 1; - if (d == 0 && ix + 1 == MP_USED(b)) - break; - if ((res = mp_int_sqr(K, &t, &t)) != MP_OK) - goto CLEANUP; + d >>= 1; + if (d == 0 && ix + 1 == MP_USED(b)) + break; + if ((res = mp_int_sqr(K, &t, &t)) != MP_OK) + goto CLEANUP; + } } - } - CLEANUP: - mp_int_clear(K, &t); - return res; +CLEANUP: + mp_int_clear(K, &t); + return res; } /* }}} */ /* {{{ mp_int_compare(a, b) */ -int mp_int_compare(mp_int a, mp_int b) +int mp_int_compare(mp_int a, mp_int b) { - mp_sign sa; + mp_sign sa; - CHECK(a != NULL && b != NULL); + CHECK(a != NULL && b != NULL); - sa = MP_SIGN(a); - if(sa == MP_SIGN(b)) { - int cmp = s_ucmp(a, b); + sa = MP_SIGN(a); + if(sa == MP_SIGN(b)) { + int cmp = s_ucmp(a, b); - /* If they're both zero or positive, the normal comparison - applies; if both negative, the sense is reversed. */ - if(sa == MP_ZPOS) - return cmp; - else - return -cmp; + /* If they're both zero or positive, the normal comparison + applies; if both negative, the sense is reversed. */ + if(sa == MP_ZPOS) + return cmp; + else + return -cmp; - } - else { - if(sa == MP_ZPOS) - return 1; - else - return -1; - } + } + else { + if(sa == MP_ZPOS) + return 1; + else + return -1; + } } /* }}} */ /* {{{ mp_int_compare_unsigned(a, b) */ -int mp_int_compare_unsigned(mp_int a, mp_int b) +int mp_int_compare_unsigned(mp_int a, mp_int b) { - NRCHECK(a != NULL && b != NULL); + NRCHECK(a != NULL && b != NULL); - return s_ucmp(a, b); + return s_ucmp(a, b); } /* }}} */ /* {{{ mp_int_compare_zero(z) */ -int mp_int_compare_zero(mp_int z) +int mp_int_compare_zero(mp_int z) { - NRCHECK(z != NULL); + NRCHECK(z != NULL); - if(MP_USED(z) == 1 && z->digits[0] == 0) - return 0; - else if(MP_SIGN(z) == MP_ZPOS) - return 1; - else - return -1; + if(MP_USED(z) == 1 && z->digits[0] == 0) + return 0; + else if(MP_SIGN(z) == MP_ZPOS) + return 1; + else + return -1; } /* }}} */ /* {{{ mp_int_compare_value(z, value) */ -int mp_int_compare_value(mp_int z, mp_small value) +int mp_int_compare_value(mp_int z, mp_small value) { - mp_sign vsign = (value < 0) ? MP_NEG : MP_ZPOS; - int cmp; + mp_sign vsign = (value < 0) ? MP_NEG : MP_ZPOS; + int cmp; - CHECK(z != NULL); + CHECK(z != NULL); - if(vsign == MP_SIGN(z)) { - cmp = s_vcmp(z, value); + if(vsign == MP_SIGN(z)) { + cmp = s_vcmp(z, value); - if(vsign == MP_ZPOS) - return cmp; - else - return -cmp; - } - else { - if(value < 0) - return 1; - else - return -1; - } + if(vsign == MP_ZPOS) + return cmp; + else + return -cmp; + } + else { + if(value < 0) + return 1; + else + return -1; + } } /* }}} */ @@ -1269,48 +1269,48 @@ int mp_int_compare_value(mp_int z, mp_small value) /* {{{ mp_int_exptmod(a, b, m, c) */ mp_result mp_int_exptmod(klisp_State *K, mp_int a, mp_int b, mp_int m, - mp_int c) + mp_int c) { - mp_result res; - mp_size um; - mpz_t temp[3]; - mp_int s; - int last = 0; - - CHECK(a != NULL && b != NULL && c != NULL && m != NULL); - - /* Zero moduli and negative exponents are not considered. */ - if(CMPZ(m) == 0) - return MP_UNDEF; - if(CMPZ(b) < 0) - return MP_RANGE; - - um = MP_USED(m); - SETUP(mp_int_init_size(K, TEMP(0), 2 * um), last); - SETUP(mp_int_init_size(K, TEMP(1), 2 * um), last); - - if(c == b || c == m) { - SETUP(mp_int_init_size(K, TEMP(2), 2 * um), last); - s = TEMP(2); - } - else { - s = c; - } + mp_result res; + mp_size um; + mpz_t temp[3]; + mp_int s; + int last = 0; + + CHECK(a != NULL && b != NULL && c != NULL && m != NULL); + + /* Zero moduli and negative exponents are not considered. */ + if(CMPZ(m) == 0) + return MP_UNDEF; + if(CMPZ(b) < 0) + return MP_RANGE; + + um = MP_USED(m); + SETUP(mp_int_init_size(K, TEMP(0), 2 * um), last); + SETUP(mp_int_init_size(K, TEMP(1), 2 * um), last); + + if(c == b || c == m) { + SETUP(mp_int_init_size(K, TEMP(2), 2 * um), last); + s = TEMP(2); + } + else { + s = c; + } - if((res = mp_int_mod(K, a, m, TEMP(0))) != MP_OK) goto CLEANUP; + if((res = mp_int_mod(K, a, m, TEMP(0))) != MP_OK) goto CLEANUP; - if((res = s_brmu(K, TEMP(1), m)) != MP_OK) goto CLEANUP; + if((res = s_brmu(K, TEMP(1), m)) != MP_OK) goto CLEANUP; - if((res = s_embar(K, TEMP(0), b, m, TEMP(1), s)) != MP_OK) - goto CLEANUP; + if((res = s_embar(K, TEMP(0), b, m, TEMP(1), s)) != MP_OK) + goto CLEANUP; - res = mp_int_copy(K, s, c); + res = mp_int_copy(K, s, c); - CLEANUP: - while(--last >= 0) - mp_int_clear(K, TEMP(last)); +CLEANUP: + while(--last >= 0) + mp_int_clear(K, TEMP(last)); - return res; + return res; } /* }}} */ @@ -1318,14 +1318,14 @@ mp_result mp_int_exptmod(klisp_State *K, mp_int a, mp_int b, mp_int m, /* {{{ mp_int_exptmod_evalue(a, value, m, c) */ mp_result mp_int_exptmod_evalue(klisp_State *K, mp_int a, mp_small value, - mp_int m, mp_int c) + mp_int m, mp_int c) { - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; - s_fake(&vtmp, value, vbuf); + s_fake(&vtmp, value, vbuf); - return mp_int_exptmod(K, a, &vtmp, m, c); + return mp_int_exptmod(K, a, &vtmp, m, c); } /* }}} */ @@ -1333,14 +1333,14 @@ mp_result mp_int_exptmod_evalue(klisp_State *K, mp_int a, mp_small value, /* {{{ mp_int_exptmod_bvalue(v, b, m, c) */ mp_result mp_int_exptmod_bvalue(klisp_State *K, mp_small value, mp_int b, - mp_int m, mp_int c) + mp_int m, mp_int c) { - mpz_t vtmp; - mp_digit vbuf[MP_VALUE_DIGITS(value)]; + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; - s_fake(&vtmp, value, vbuf); + s_fake(&vtmp, value, vbuf); - return mp_int_exptmod(K, &vtmp, b, m, c); + return mp_int_exptmod(K, &vtmp, b, m, c); } /* }}} */ @@ -1348,45 +1348,45 @@ mp_result mp_int_exptmod_bvalue(klisp_State *K, mp_small value, mp_int b, /* {{{ mp_int_exptmod_known(a, b, m, mu, c) */ mp_result mp_int_exptmod_known(klisp_State *K, mp_int a, mp_int b, mp_int m, - mp_int mu, mp_int c) + mp_int mu, mp_int c) { - mp_result res; - mp_size um; - mpz_t temp[2]; - mp_int s; - int last = 0; + mp_result res; + mp_size um; + mpz_t temp[2]; + mp_int s; + int last = 0; - CHECK(a && b && m && c); + CHECK(a && b && m && c); - /* Zero moduli and negative exponents are not considered. */ - if(CMPZ(m) == 0) - return MP_UNDEF; - if(CMPZ(b) < 0) - return MP_RANGE; + /* Zero moduli and negative exponents are not considered. */ + if(CMPZ(m) == 0) + return MP_UNDEF; + if(CMPZ(b) < 0) + return MP_RANGE; - um = MP_USED(m); - SETUP(mp_int_init_size(K, TEMP(0), 2 * um), last); + um = MP_USED(m); + SETUP(mp_int_init_size(K, TEMP(0), 2 * um), last); - if(c == b || c == m) { - SETUP(mp_int_init_size(K, TEMP(1), 2 * um), last); - s = TEMP(1); - } - else { - s = c; - } + if(c == b || c == m) { + SETUP(mp_int_init_size(K, TEMP(1), 2 * um), last); + s = TEMP(1); + } + else { + s = c; + } - if((res = mp_int_mod(K, a, m, TEMP(0))) != MP_OK) goto CLEANUP; + if((res = mp_int_mod(K, a, m, TEMP(0))) != MP_OK) goto CLEANUP; - if((res = s_embar(K, TEMP(0), b, m, mu, s)) != MP_OK) - goto CLEANUP; + if((res = s_embar(K, TEMP(0), b, m, mu, s)) != MP_OK) + goto CLEANUP; - res = mp_int_copy(K, s, c); + res = mp_int_copy(K, s, c); - CLEANUP: - while(--last >= 0) - mp_int_clear(K, TEMP(last)); +CLEANUP: + while(--last >= 0) + mp_int_clear(K, TEMP(last)); - return res; + return res; } /* }}} */ @@ -1395,9 +1395,9 @@ mp_result mp_int_exptmod_known(klisp_State *K, mp_int a, mp_int b, mp_int m, mp_result mp_int_redux_const(klisp_State *K, mp_int m, mp_int c) { - CHECK(m != NULL && c != NULL && m != c); + CHECK(m != NULL && c != NULL && m != c); - return s_brmu(K, c, m); + return s_brmu(K, c, m); } /* }}} */ @@ -1406,48 +1406,48 @@ mp_result mp_int_redux_const(klisp_State *K, mp_int m, mp_int c) mp_result mp_int_invmod(klisp_State *K, mp_int a, mp_int m, mp_int c) { - mp_result res; - mp_sign sa; - int last = 0; - mpz_t temp[2]; + mp_result res; + mp_sign sa; + int last = 0; + mpz_t temp[2]; - CHECK(a != NULL && m != NULL && c != NULL); + CHECK(a != NULL && m != NULL && c != NULL); - if(CMPZ(a) == 0 || CMPZ(m) <= 0) - return MP_RANGE; + if(CMPZ(a) == 0 || CMPZ(m) <= 0) + return MP_RANGE; - sa = MP_SIGN(a); /* need this for the result later */ + sa = MP_SIGN(a); /* need this for the result later */ - for(last = 0; last < 2; ++last) - mp_int_init(TEMP(last)); + for(last = 0; last < 2; ++last) + mp_int_init(TEMP(last)); - if((res = mp_int_egcd(K, a, m, TEMP(0), TEMP(1), NULL)) != MP_OK) - goto CLEANUP; + if((res = mp_int_egcd(K, a, m, TEMP(0), TEMP(1), NULL)) != MP_OK) + goto CLEANUP; - if(mp_int_compare_value(TEMP(0), 1) != 0) { - res = MP_UNDEF; - goto CLEANUP; - } + if(mp_int_compare_value(TEMP(0), 1) != 0) { + res = MP_UNDEF; + goto CLEANUP; + } - /* It is first necessary to constrain the value to the proper range */ - if((res = mp_int_mod(K, TEMP(1), m, TEMP(1))) != MP_OK) - goto CLEANUP; + /* It is first necessary to constrain the value to the proper range */ + if((res = mp_int_mod(K, TEMP(1), m, TEMP(1))) != MP_OK) + goto CLEANUP; - /* Now, if 'a' was originally negative, the value we have is - actually the magnitude of the negative representative; to get the - positive value we have to subtract from the modulus. Otherwise, - the value is okay as it stands. - */ - if(sa == MP_NEG) - res = mp_int_sub(K, m, TEMP(1), c); - else - res = mp_int_copy(K, TEMP(1), c); + /* Now, if 'a' was originally negative, the value we have is + actually the magnitude of the negative representative; to get the + positive value we have to subtract from the modulus. Otherwise, + the value is okay as it stands. + */ + if(sa == MP_NEG) + res = mp_int_sub(K, m, TEMP(1), c); + else + res = mp_int_copy(K, TEMP(1), c); - CLEANUP: - while(--last >= 0) - mp_int_clear(K, TEMP(last)); +CLEANUP: + while(--last >= 0) + mp_int_clear(K, TEMP(last)); - return res; + return res; } /* }}} */ @@ -1457,76 +1457,76 @@ mp_result mp_int_invmod(klisp_State *K, mp_int a, mp_int m, mp_int c) /* Binary GCD algorithm due to Josef Stein, 1961 */ mp_result mp_int_gcd(klisp_State *K, mp_int a, mp_int b, mp_int c) { - int ca, cb, k = 0; - mpz_t u, v, t; - mp_result res; - - CHECK(a != NULL && b != NULL && c != NULL); - - ca = CMPZ(a); - cb = CMPZ(b); - if(ca == 0 && cb == 0) - return MP_UNDEF; - else if(ca == 0) - return mp_int_abs(K, b, c); - else if(cb == 0) - return mp_int_abs(K, a, c); - - mp_int_init(&t); - if((res = mp_int_init_copy(K, &u, a)) != MP_OK) - goto U; - if((res = mp_int_init_copy(K, &v, b)) != MP_OK) - goto V; - - MP_SIGN(&u) = MP_ZPOS; MP_SIGN(&v) = MP_ZPOS; - - { /* Divide out common factors of 2 from u and v */ - int div2_u = s_dp2k(&u), div2_v = s_dp2k(&v); + int ca, cb, k = 0; + mpz_t u, v, t; + mp_result res; + + CHECK(a != NULL && b != NULL && c != NULL); + + ca = CMPZ(a); + cb = CMPZ(b); + if(ca == 0 && cb == 0) + return MP_UNDEF; + else if(ca == 0) + return mp_int_abs(K, b, c); + else if(cb == 0) + return mp_int_abs(K, a, c); + + mp_int_init(&t); + if((res = mp_int_init_copy(K, &u, a)) != MP_OK) + goto U; + if((res = mp_int_init_copy(K, &v, b)) != MP_OK) + goto V; + + MP_SIGN(&u) = MP_ZPOS; MP_SIGN(&v) = MP_ZPOS; + + { /* Divide out common factors of 2 from u and v */ + int div2_u = s_dp2k(&u), div2_v = s_dp2k(&v); - k = MIN(div2_u, div2_v); - s_qdiv(&u, (mp_size) k); - s_qdiv(&v, (mp_size) k); - } + k = MIN(div2_u, div2_v); + s_qdiv(&u, (mp_size) k); + s_qdiv(&v, (mp_size) k); + } - if(mp_int_is_odd(&u)) { - if((res = mp_int_neg(K, &v, &t)) != MP_OK) - goto CLEANUP; - } - else { - if((res = mp_int_copy(K, &u, &t)) != MP_OK) - goto CLEANUP; - } - - for(;;) { - s_qdiv(&t, s_dp2k(&t)); - - if(CMPZ(&t) > 0) { - if((res = mp_int_copy(K, &t, &u)) != MP_OK) - goto CLEANUP; + if(mp_int_is_odd(&u)) { + if((res = mp_int_neg(K, &v, &t)) != MP_OK) + goto CLEANUP; } else { - if((res = mp_int_neg(K, &t, &v)) != MP_OK) - goto CLEANUP; + if((res = mp_int_copy(K, &u, &t)) != MP_OK) + goto CLEANUP; } - if((res = mp_int_sub(K, &u, &v, &t)) != MP_OK) - goto CLEANUP; + for(;;) { + s_qdiv(&t, s_dp2k(&t)); + + if(CMPZ(&t) > 0) { + if((res = mp_int_copy(K, &t, &u)) != MP_OK) + goto CLEANUP; + } + else { + if((res = mp_int_neg(K, &t, &v)) != MP_OK) + goto CLEANUP; + } - if(CMPZ(&t) == 0) - break; - } + if((res = mp_int_sub(K, &u, &v, &t)) != MP_OK) + goto CLEANUP; - if((res = mp_int_abs(K, &u, c)) != MP_OK) - goto CLEANUP; - if(!s_qmul(K, c, (mp_size) k)) - res = MP_MEMORY; + if(CMPZ(&t) == 0) + break; + } + + if((res = mp_int_abs(K, &u, c)) != MP_OK) + goto CLEANUP; + if(!s_qmul(K, c, (mp_size) k)) + res = MP_MEMORY; - CLEANUP: - mp_int_clear(K, &v); - V: mp_int_clear(K, &u); - U: mp_int_clear(K, &t); +CLEANUP: + mp_int_clear(K, &v); +V: mp_int_clear(K, &u); +U: mp_int_clear(K, &t); - return res; + return res; } /* }}} */ @@ -1536,116 +1536,116 @@ mp_result mp_int_gcd(klisp_State *K, mp_int a, mp_int b, mp_int c) /* This is the binary GCD algorithm again, but this time we keep track of the elementary matrix operations as we go, so we can get values x and y satisfying c = ax + by. - */ +*/ mp_result mp_int_egcd(klisp_State *K, mp_int a, mp_int b, mp_int c, - mp_int x, mp_int y) + mp_int x, mp_int y) { - int k, last = 0, ca, cb; - mpz_t temp[8]; - mp_result res; + int k, last = 0, ca, cb; + mpz_t temp[8]; + mp_result res; - CHECK(a != NULL && b != NULL && c != NULL && - (x != NULL || y != NULL)); - - ca = CMPZ(a); - cb = CMPZ(b); - if(ca == 0 && cb == 0) - return MP_UNDEF; - else if(ca == 0) { - if((res = mp_int_abs(K, b, c)) != MP_OK) return res; - mp_int_zero(x); (void) mp_int_set_value(K, y, 1); return MP_OK; - } - else if(cb == 0) { - if((res = mp_int_abs(K, a, c)) != MP_OK) return res; - (void) mp_int_set_value(K, x, 1); mp_int_zero(y); return MP_OK; - } - - /* Initialize temporaries: - A:0, B:1, C:2, D:3, u:4, v:5, ou:6, ov:7 */ - for(last = 0; last < 4; ++last) - mp_int_init(TEMP(last)); - TEMP(0)->digits[0] = 1; - TEMP(3)->digits[0] = 1; - - SETUP(mp_int_init_copy(K, TEMP(4), a), last); - SETUP(mp_int_init_copy(K, TEMP(5), b), last); - - /* We will work with absolute values here */ - MP_SIGN(TEMP(4)) = MP_ZPOS; - MP_SIGN(TEMP(5)) = MP_ZPOS; - - { /* Divide out common factors of 2 from u and v */ - int div2_u = s_dp2k(TEMP(4)), div2_v = s_dp2k(TEMP(5)); - - k = MIN(div2_u, div2_v); - s_qdiv(TEMP(4), k); - s_qdiv(TEMP(5), k); - } - - SETUP(mp_int_init_copy(K, TEMP(6), TEMP(4)), last); - SETUP(mp_int_init_copy(K, TEMP(7), TEMP(5)), last); - - for(;;) { - while(mp_int_is_even(TEMP(4))) { - s_qdiv(TEMP(4), 1); - - if(mp_int_is_odd(TEMP(0)) || mp_int_is_odd(TEMP(1))) { - if((res = mp_int_add(K, TEMP(0), TEMP(7), TEMP(0))) != MP_OK) - goto CLEANUP; - if((res = mp_int_sub(K, TEMP(1), TEMP(6), TEMP(1))) != MP_OK) - goto CLEANUP; - } - - s_qdiv(TEMP(0), 1); - s_qdiv(TEMP(1), 1); + CHECK(a != NULL && b != NULL && c != NULL && + (x != NULL || y != NULL)); + + ca = CMPZ(a); + cb = CMPZ(b); + if(ca == 0 && cb == 0) + return MP_UNDEF; + else if(ca == 0) { + if((res = mp_int_abs(K, b, c)) != MP_OK) return res; + mp_int_zero(x); (void) mp_int_set_value(K, y, 1); return MP_OK; + } + else if(cb == 0) { + if((res = mp_int_abs(K, a, c)) != MP_OK) return res; + (void) mp_int_set_value(K, x, 1); mp_int_zero(y); return MP_OK; } - - while(mp_int_is_even(TEMP(5))) { - s_qdiv(TEMP(5), 1); - if(mp_int_is_odd(TEMP(2)) || mp_int_is_odd(TEMP(3))) { - if((res = mp_int_add(K, TEMP(2), TEMP(7), TEMP(2))) != MP_OK) - goto CLEANUP; - if((res = mp_int_sub(K, TEMP(3), TEMP(6), TEMP(3))) != MP_OK) - goto CLEANUP; - } + /* Initialize temporaries: + A:0, B:1, C:2, D:3, u:4, v:5, ou:6, ov:7 */ + for(last = 0; last < 4; ++last) + mp_int_init(TEMP(last)); + TEMP(0)->digits[0] = 1; + TEMP(3)->digits[0] = 1; + + SETUP(mp_int_init_copy(K, TEMP(4), a), last); + SETUP(mp_int_init_copy(K, TEMP(5), b), last); + + /* We will work with absolute values here */ + MP_SIGN(TEMP(4)) = MP_ZPOS; + MP_SIGN(TEMP(5)) = MP_ZPOS; - s_qdiv(TEMP(2), 1); - s_qdiv(TEMP(3), 1); + { /* Divide out common factors of 2 from u and v */ + int div2_u = s_dp2k(TEMP(4)), div2_v = s_dp2k(TEMP(5)); + + k = MIN(div2_u, div2_v); + s_qdiv(TEMP(4), k); + s_qdiv(TEMP(5), k); } - if(mp_int_compare(TEMP(4), TEMP(5)) >= 0) { - if((res = mp_int_sub(K, TEMP(4), TEMP(5), TEMP(4))) != MP_OK) goto CLEANUP; - if((res = mp_int_sub(K, TEMP(0), TEMP(2), TEMP(0))) != MP_OK) goto CLEANUP; - if((res = mp_int_sub(K, TEMP(1), TEMP(3), TEMP(1))) != MP_OK) goto CLEANUP; - } - else { - if((res = mp_int_sub(K, TEMP(5), TEMP(4), TEMP(5))) != MP_OK) goto CLEANUP; - if((res = mp_int_sub(K, TEMP(2), TEMP(0), TEMP(2))) != MP_OK) goto CLEANUP; - if((res = mp_int_sub(K, TEMP(3), TEMP(1), TEMP(3))) != MP_OK) goto CLEANUP; - } - - if(CMPZ(TEMP(4)) == 0) { - if(x && (res = mp_int_copy(K, TEMP(2), x)) != MP_OK) goto CLEANUP; - if(y && (res = mp_int_copy(K, TEMP(3), y)) != MP_OK) goto CLEANUP; - if(c) { - if(!s_qmul(K, TEMP(5), k)) { - res = MP_MEMORY; - goto CLEANUP; - } + SETUP(mp_int_init_copy(K, TEMP(6), TEMP(4)), last); + SETUP(mp_int_init_copy(K, TEMP(7), TEMP(5)), last); + + for(;;) { + while(mp_int_is_even(TEMP(4))) { + s_qdiv(TEMP(4), 1); + + if(mp_int_is_odd(TEMP(0)) || mp_int_is_odd(TEMP(1))) { + if((res = mp_int_add(K, TEMP(0), TEMP(7), TEMP(0))) != MP_OK) + goto CLEANUP; + if((res = mp_int_sub(K, TEMP(1), TEMP(6), TEMP(1))) != MP_OK) + goto CLEANUP; + } + + s_qdiv(TEMP(0), 1); + s_qdiv(TEMP(1), 1); + } + + while(mp_int_is_even(TEMP(5))) { + s_qdiv(TEMP(5), 1); + + if(mp_int_is_odd(TEMP(2)) || mp_int_is_odd(TEMP(3))) { + if((res = mp_int_add(K, TEMP(2), TEMP(7), TEMP(2))) != MP_OK) + goto CLEANUP; + if((res = mp_int_sub(K, TEMP(3), TEMP(6), TEMP(3))) != MP_OK) + goto CLEANUP; + } + + s_qdiv(TEMP(2), 1); + s_qdiv(TEMP(3), 1); + } + + if(mp_int_compare(TEMP(4), TEMP(5)) >= 0) { + if((res = mp_int_sub(K, TEMP(4), TEMP(5), TEMP(4))) != MP_OK) goto CLEANUP; + if((res = mp_int_sub(K, TEMP(0), TEMP(2), TEMP(0))) != MP_OK) goto CLEANUP; + if((res = mp_int_sub(K, TEMP(1), TEMP(3), TEMP(1))) != MP_OK) goto CLEANUP; + } + else { + if((res = mp_int_sub(K, TEMP(5), TEMP(4), TEMP(5))) != MP_OK) goto CLEANUP; + if((res = mp_int_sub(K, TEMP(2), TEMP(0), TEMP(2))) != MP_OK) goto CLEANUP; + if((res = mp_int_sub(K, TEMP(3), TEMP(1), TEMP(3))) != MP_OK) goto CLEANUP; + } + + if(CMPZ(TEMP(4)) == 0) { + if(x && (res = mp_int_copy(K, TEMP(2), x)) != MP_OK) goto CLEANUP; + if(y && (res = mp_int_copy(K, TEMP(3), y)) != MP_OK) goto CLEANUP; + if(c) { + if(!s_qmul(K, TEMP(5), k)) { + res = MP_MEMORY; + goto CLEANUP; + } - res = mp_int_copy(K, TEMP(5), c); - } + res = mp_int_copy(K, TEMP(5), c); + } - break; + break; + } } - } - CLEANUP: - while(--last >= 0) - mp_int_clear(K, TEMP(last)); +CLEANUP: + while(--last >= 0) + mp_int_clear(K, TEMP(last)); - return res; + return res; } /* }}} */ @@ -1654,57 +1654,57 @@ mp_result mp_int_egcd(klisp_State *K, mp_int a, mp_int b, mp_int c, mp_result mp_int_lcm(klisp_State *K, mp_int a, mp_int b, mp_int c) { - mpz_t lcm; - mp_result res; - - CHECK(a != NULL && b != NULL && c != NULL); + mpz_t lcm; + mp_result res; - /* Since a * b = gcd(a, b) * lcm(a, b), we can compute - lcm(a, b) = (a / gcd(a, b)) * b. - - This formulation insures everything works even if the input - variables share space. - */ - if((res = mp_int_init(&lcm)) != MP_OK) - return res; - if((res = mp_int_gcd(K, a, b, &lcm)) != MP_OK) - goto CLEANUP; - if((res = mp_int_div(K, a, &lcm, &lcm, NULL)) != MP_OK) - goto CLEANUP; - if((res = mp_int_mul(K, &lcm, b, &lcm)) != MP_OK) - goto CLEANUP; + CHECK(a != NULL && b != NULL && c != NULL); - res = mp_int_copy(K, &lcm, c); + /* Since a * b = gcd(a, b) * lcm(a, b), we can compute + lcm(a, b) = (a / gcd(a, b)) * b. - CLEANUP: + This formulation insures everything works even if the input + variables share space. + */ + if((res = mp_int_init(&lcm)) != MP_OK) + return res; + if((res = mp_int_gcd(K, a, b, &lcm)) != MP_OK) + goto CLEANUP; + if((res = mp_int_div(K, a, &lcm, &lcm, NULL)) != MP_OK) + goto CLEANUP; + if((res = mp_int_mul(K, &lcm, b, &lcm)) != MP_OK) + goto CLEANUP; + + res = mp_int_copy(K, &lcm, c); + +CLEANUP: mp_int_clear(K, &lcm); - return res; + return res; } /* }}} */ /* {{{ mp_int_divisible_value(a, v) */ -int mp_int_divisible_value(klisp_State *K, mp_int a, mp_small v) +int mp_int_divisible_value(klisp_State *K, mp_int a, mp_small v) { - mp_small rem = 0; + mp_small rem = 0; - if(mp_int_div_value(K, a, v, NULL, &rem) != MP_OK) - return 0; + if(mp_int_div_value(K, a, v, NULL, &rem) != MP_OK) + return 0; - return rem == 0; + return rem == 0; } /* }}} */ /* {{{ mp_int_is_pow2(z) */ -int mp_int_is_pow2(mp_int z) +int mp_int_is_pow2(mp_int z) { - CHECK(z != NULL); + CHECK(z != NULL); - return s_isp2(z); + return s_isp2(z); } /* }}} */ @@ -1714,73 +1714,73 @@ int mp_int_is_pow2(mp_int z) /* Implementation of Newton's root finding method, based loosely on a patch contributed by Hal Finkel <half@halssoftware.com> modified by M. J. Fromberger. - */ +*/ mp_result mp_int_root(klisp_State *K, mp_int a, mp_small b, mp_int c) { - mp_result res = MP_OK; - mpz_t temp[5]; - int last = 0; - int flips = 0; + mp_result res = MP_OK; + mpz_t temp[5]; + int last = 0; + int flips = 0; - CHECK(a != NULL && c != NULL && b > 0); + CHECK(a != NULL && c != NULL && b > 0); - if(b == 1) { - return mp_int_copy(K, a, c); - } - if(MP_SIGN(a) == MP_NEG) { - if(b % 2 == 0) - return MP_UNDEF; /* root does not exist for negative a with even b */ - else - flips = 1; - } - - SETUP(mp_int_init_copy(K, TEMP(last), a), last); - SETUP(mp_int_init_copy(K, TEMP(last), a), last); - SETUP(mp_int_init(TEMP(last)), last); - SETUP(mp_int_init(TEMP(last)), last); - SETUP(mp_int_init(TEMP(last)), last); - - (void) mp_int_abs(K, TEMP(0), TEMP(0)); - (void) mp_int_abs(K, TEMP(1), TEMP(1)); - - for(;;) { - if((res = mp_int_expt(K, TEMP(1), b, TEMP(2))) != MP_OK) - goto CLEANUP; - - if(mp_int_compare_unsigned(TEMP(2), TEMP(0)) <= 0) - break; - - if((res = mp_int_sub(K, TEMP(2), TEMP(0), TEMP(2))) != MP_OK) - goto CLEANUP; - if((res = mp_int_expt(K, TEMP(1), b - 1, TEMP(3))) != MP_OK) - goto CLEANUP; - if((res = mp_int_mul_value(K, TEMP(3), b, TEMP(3))) != MP_OK) - goto CLEANUP; - if((res = mp_int_div(K, TEMP(2), TEMP(3), TEMP(4), NULL)) != MP_OK) - goto CLEANUP; - if((res = mp_int_sub(K, TEMP(1), TEMP(4), TEMP(4))) != MP_OK) - goto CLEANUP; - - if(mp_int_compare_unsigned(TEMP(1), TEMP(4)) == 0) { - if((res = mp_int_sub_value(K, TEMP(4), 1, TEMP(4))) != MP_OK) - goto CLEANUP; - } - if((res = mp_int_copy(K, TEMP(4), TEMP(1))) != MP_OK) - goto CLEANUP; - } + if(b == 1) { + return mp_int_copy(K, a, c); + } + if(MP_SIGN(a) == MP_NEG) { + if(b % 2 == 0) + return MP_UNDEF; /* root does not exist for negative a with even b */ + else + flips = 1; + } + + SETUP(mp_int_init_copy(K, TEMP(last), a), last); + SETUP(mp_int_init_copy(K, TEMP(last), a), last); + SETUP(mp_int_init(TEMP(last)), last); + SETUP(mp_int_init(TEMP(last)), last); + SETUP(mp_int_init(TEMP(last)), last); + + (void) mp_int_abs(K, TEMP(0), TEMP(0)); + (void) mp_int_abs(K, TEMP(1), TEMP(1)); + + for(;;) { + if((res = mp_int_expt(K, TEMP(1), b, TEMP(2))) != MP_OK) + goto CLEANUP; + + if(mp_int_compare_unsigned(TEMP(2), TEMP(0)) <= 0) + break; + + if((res = mp_int_sub(K, TEMP(2), TEMP(0), TEMP(2))) != MP_OK) + goto CLEANUP; + if((res = mp_int_expt(K, TEMP(1), b - 1, TEMP(3))) != MP_OK) + goto CLEANUP; + if((res = mp_int_mul_value(K, TEMP(3), b, TEMP(3))) != MP_OK) + goto CLEANUP; + if((res = mp_int_div(K, TEMP(2), TEMP(3), TEMP(4), NULL)) != MP_OK) + goto CLEANUP; + if((res = mp_int_sub(K, TEMP(1), TEMP(4), TEMP(4))) != MP_OK) + goto CLEANUP; + + if(mp_int_compare_unsigned(TEMP(1), TEMP(4)) == 0) { + if((res = mp_int_sub_value(K, TEMP(4), 1, TEMP(4))) != MP_OK) + goto CLEANUP; + } + if((res = mp_int_copy(K, TEMP(4), TEMP(1))) != MP_OK) + goto CLEANUP; + } - if((res = mp_int_copy(K, TEMP(1), c)) != MP_OK) - goto CLEANUP; + if((res = mp_int_copy(K, TEMP(1), c)) != MP_OK) + goto CLEANUP; - /* If the original value of a was negative, flip the output sign. */ - if(flips) - (void) mp_int_neg(K, c, c); /* cannot fail */ + /* If the original value of a was negative, flip the output sign. */ + if(flips) + (void) mp_int_neg(K, c, c); /* cannot fail */ - CLEANUP: - while(--last >= 0) - mp_int_clear(K, TEMP(last)); +CLEANUP: + while(--last >= 0) + mp_int_clear(K, TEMP(last)); - return res; + return res; } /* }}} */ @@ -1789,32 +1789,32 @@ mp_result mp_int_root(klisp_State *K, mp_int a, mp_small b, mp_int c) mp_result mp_int_to_int(mp_int z, mp_small *out) { - mp_usmall uv = 0; - mp_size uz; - mp_digit *dz; - mp_sign sz; - - CHECK(z != NULL); - - /* Make sure the value is representable as an int */ - sz = MP_SIGN(z); - if((sz == MP_ZPOS && mp_int_compare_value(z, MP_SMALL_MAX) > 0) || - mp_int_compare_value(z, MP_SMALL_MIN) < 0) - return MP_RANGE; - - uz = MP_USED(z); - dz = MP_DIGITS(z) + uz - 1; + mp_usmall uv = 0; + mp_size uz; + mp_digit *dz; + mp_sign sz; + + CHECK(z != NULL); + + /* Make sure the value is representable as an int */ + sz = MP_SIGN(z); + if((sz == MP_ZPOS && mp_int_compare_value(z, MP_SMALL_MAX) > 0) || + mp_int_compare_value(z, MP_SMALL_MIN) < 0) + return MP_RANGE; + + uz = MP_USED(z); + dz = MP_DIGITS(z) + uz - 1; - while(uz > 0) { - uv <<= MP_DIGIT_BIT/2; - uv = (uv << (MP_DIGIT_BIT/2)) | *dz--; - --uz; - } + while(uz > 0) { + uv <<= MP_DIGIT_BIT/2; + uv = (uv << (MP_DIGIT_BIT/2)) | *dz--; + --uz; + } - if(out) - *out = (sz == MP_NEG) ? -(mp_small)uv : (mp_small)uv; + if(out) + *out = (sz == MP_NEG) ? -(mp_small)uv : (mp_small)uv; - return MP_OK; + return MP_OK; } /* }}} */ @@ -1823,31 +1823,31 @@ mp_result mp_int_to_int(mp_int z, mp_small *out) mp_result mp_int_to_uint(mp_int z, mp_usmall *out) { - mp_usmall uv = 0; - mp_size uz; - mp_digit *dz; - mp_sign sz; + mp_usmall uv = 0; + mp_size uz; + mp_digit *dz; + mp_sign sz; - CHECK(z != NULL); - - /* Make sure the value is representable as an int */ - sz = MP_SIGN(z); - if(!(sz == MP_ZPOS && mp_int_compare_value(z, UINT_MAX) <= 0)) - return MP_RANGE; - - uz = MP_USED(z); - dz = MP_DIGITS(z) + uz - 1; + CHECK(z != NULL); + + /* Make sure the value is representable as an int */ + sz = MP_SIGN(z); + if(!(sz == MP_ZPOS && mp_int_compare_value(z, UINT_MAX) <= 0)) + return MP_RANGE; + + uz = MP_USED(z); + dz = MP_DIGITS(z) + uz - 1; - while(uz > 0) { - uv <<= MP_DIGIT_BIT/2; - uv = (uv << (MP_DIGIT_BIT/2)) | *dz--; - --uz; - } + while(uz > 0) { + uv <<= MP_DIGIT_BIT/2; + uv = (uv << (MP_DIGIT_BIT/2)) | *dz--; + --uz; + } - if(out) - *out = uv; + if(out) + *out = uv; - return MP_OK; + return MP_OK; } /* }}} */ @@ -1855,59 +1855,59 @@ mp_result mp_int_to_uint(mp_int z, mp_usmall *out) /* {{{ mp_int_to_string(z, radix, str, limit) */ mp_result mp_int_to_string(klisp_State *K, mp_int z, mp_size radix, - char *str, int limit) + char *str, int limit) { - mp_result res; - int cmp = 0; - - CHECK(z != NULL && str != NULL && limit >= 2); + mp_result res; + int cmp = 0; - if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) - return MP_RANGE; + CHECK(z != NULL && str != NULL && limit >= 2); - if(CMPZ(z) == 0) { - *str++ = s_val2ch(0, 0); /* changed to lowercase, Andres Navarro */ - } - else { - mpz_t tmp; - char *h, *t; - - if((res = mp_int_init_copy(K, &tmp, z)) != MP_OK) - return res; - - if(MP_SIGN(z) == MP_NEG) { - *str++ = '-'; - --limit; - } - h = str; + if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) + return MP_RANGE; - /* Generate digits in reverse order until finished or limit reached */ - for(/* */; limit > 0; --limit) { - mp_digit d; - - if((cmp = CMPZ(&tmp)) == 0) - break; - - d = s_ddiv(&tmp, (mp_digit)radix); - *str++ = s_val2ch(d, 0); /* changed to lowercase, Andres Navarro */ - } - t = str - 1; - - /* Put digits back in correct output order */ - while(h < t) { - char tc = *h; - *h++ = *t; - *t-- = tc; + if(CMPZ(z) == 0) { + *str++ = s_val2ch(0, 0); /* changed to lowercase, Andres Navarro */ + } + else { + mpz_t tmp; + char *h, *t; + + if((res = mp_int_init_copy(K, &tmp, z)) != MP_OK) + return res; + + if(MP_SIGN(z) == MP_NEG) { + *str++ = '-'; + --limit; + } + h = str; + + /* Generate digits in reverse order until finished or limit reached */ + for(/* */; limit > 0; --limit) { + mp_digit d; + + if((cmp = CMPZ(&tmp)) == 0) + break; + + d = s_ddiv(&tmp, (mp_digit)radix); + *str++ = s_val2ch(d, 0); /* changed to lowercase, Andres Navarro */ + } + t = str - 1; + + /* Put digits back in correct output order */ + while(h < t) { + char tc = *h; + *h++ = *t; + *t-- = tc; + } + + mp_int_clear(K, &tmp); } - mp_int_clear(K, &tmp); - } - - *str = '\0'; - if(cmp == 0) - return MP_OK; - else - return MP_TRUNC; + *str = '\0'; + if(cmp == 0) + return MP_OK; + else + return MP_TRUNC; } /* }}} */ @@ -1916,20 +1916,20 @@ mp_result mp_int_to_string(klisp_State *K, mp_int z, mp_size radix, mp_result mp_int_string_len(mp_int z, mp_size radix) { - int len; + int len; - CHECK(z != NULL); + CHECK(z != NULL); - if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) - return MP_RANGE; + if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) + return MP_RANGE; - len = s_outlen(z, radix) + 1; /* for terminator */ + len = s_outlen(z, radix) + 1; /* for terminator */ - /* Allow for sign marker on negatives */ - if(MP_SIGN(z) == MP_NEG) - len += 1; + /* Allow for sign marker on negatives */ + if(MP_SIGN(z) == MP_NEG) + len += 1; - return len; + return len; } /* }}} */ @@ -1938,9 +1938,9 @@ mp_result mp_int_string_len(mp_int z, mp_size radix) /* Read zero-terminated string into z */ mp_result mp_int_read_string(klisp_State *K, mp_int z, mp_size radix, - const char *str) + const char *str) { - return mp_int_read_cstring(K, z, radix, str, NULL); + return mp_int_read_cstring(K, z, radix, str, NULL); } /* }}} */ @@ -1948,64 +1948,64 @@ mp_result mp_int_read_string(klisp_State *K, mp_int z, mp_size radix, /* {{{ mp_int_read_cstring(z, radix, *str, **end) */ mp_result mp_int_read_cstring(klisp_State *K, mp_int z, mp_size radix, - const char *str, char **end) + const char *str, char **end) { - int ch; - - CHECK(z != NULL && str != NULL); - - if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) - return MP_RANGE; - - /* Skip leading whitespace */ - while(isspace((int)*str)) - ++str; - - /* Handle leading sign tag (+/-, positive default) */ - switch(*str) { - case '-': - MP_SIGN(z) = MP_NEG; - ++str; - break; - case '+': - ++str; /* fallthrough */ - default: - MP_SIGN(z) = MP_ZPOS; - break; - } + int ch; + + CHECK(z != NULL && str != NULL); + + if(radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) + return MP_RANGE; + + /* Skip leading whitespace */ + while(isspace((int)*str)) + ++str; + + /* Handle leading sign tag (+/-, positive default) */ + switch(*str) { + case '-': + MP_SIGN(z) = MP_NEG; + ++str; + break; + case '+': + ++str; /* fallthrough */ + default: + MP_SIGN(z) = MP_ZPOS; + break; + } - /* Skip leading zeroes */ - while((ch = s_ch2val(*str, radix)) == 0) - ++str; + /* Skip leading zeroes */ + while((ch = s_ch2val(*str, radix)) == 0) + ++str; - /* Make sure there is enough space for the value */ - if(!s_pad(K, z, s_inlen(strlen(str), radix))) - return MP_MEMORY; + /* Make sure there is enough space for the value */ + if(!s_pad(K, z, s_inlen(strlen(str), radix))) + return MP_MEMORY; - MP_USED(z) = 1; z->digits[0] = 0; + MP_USED(z) = 1; z->digits[0] = 0; - while(*str != '\0' && ((ch = s_ch2val(*str, radix)) >= 0)) { - s_dmul(z, (mp_digit)radix); - s_dadd(z, (mp_digit)ch); - ++str; - } + while(*str != '\0' && ((ch = s_ch2val(*str, radix)) >= 0)) { + s_dmul(z, (mp_digit)radix); + s_dadd(z, (mp_digit)ch); + ++str; + } - CLAMP(z); + CLAMP(z); - /* Override sign for zero, even if negative specified. */ - if(CMPZ(z) == 0) - MP_SIGN(z) = MP_ZPOS; + /* Override sign for zero, even if negative specified. */ + if(CMPZ(z) == 0) + MP_SIGN(z) = MP_ZPOS; - if(end != NULL) - *end = (char *)str; - - /* Return a truncation error if the string has unprocessed - characters remaining, so the caller can tell if the whole string - was done */ - if(*str != '\0') - return MP_TRUNC; - else - return MP_OK; + if(end != NULL) + *end = (char *)str; + + /* Return a truncation error if the string has unprocessed + characters remaining, so the caller can tell if the whole string + was done */ + if(*str != '\0') + return MP_TRUNC; + else + return MP_OK; } /* }}} */ @@ -2014,25 +2014,25 @@ mp_result mp_int_read_cstring(klisp_State *K, mp_int z, mp_size radix, mp_result mp_int_count_bits(mp_int z) { - mp_size nbits = 0, uz; - mp_digit d; + mp_size nbits = 0, uz; + mp_digit d; - CHECK(z != NULL); + CHECK(z != NULL); - uz = MP_USED(z); - if(uz == 1 && z->digits[0] == 0) - return 1; + uz = MP_USED(z); + if(uz == 1 && z->digits[0] == 0) + return 1; - --uz; - nbits = uz * MP_DIGIT_BIT; - d = z->digits[uz]; + --uz; + nbits = uz * MP_DIGIT_BIT; + d = z->digits[uz]; - while(d != 0) { - d >>= 1; - ++nbits; - } + while(d != 0) { + d >>= 1; + ++nbits; + } - return nbits; + return nbits; } /* }}} */ @@ -2040,21 +2040,21 @@ mp_result mp_int_count_bits(mp_int z) /* {{{ mp_int_to_binary(z, buf, limit) */ mp_result mp_int_to_binary(klisp_State *K, mp_int z, unsigned char *buf, - int limit) + int limit) { - static const int PAD_FOR_2C = 1; + static const int PAD_FOR_2C = 1; - mp_result res; - int limpos = limit; + mp_result res; + int limpos = limit; - CHECK(z != NULL && buf != NULL); + CHECK(z != NULL && buf != NULL); - res = s_tobin(z, buf, &limpos, PAD_FOR_2C); + res = s_tobin(z, buf, &limpos, PAD_FOR_2C); - if(MP_SIGN(z) == MP_NEG) - s_2comp(buf, limpos); + if(MP_SIGN(z) == MP_NEG) + s_2comp(buf, limpos); - return res; + return res; } /* }}} */ @@ -2062,39 +2062,39 @@ mp_result mp_int_to_binary(klisp_State *K, mp_int z, unsigned char *buf, /* {{{ mp_int_read_binary(z, buf, len) */ mp_result mp_int_read_binary(klisp_State *K, mp_int z, unsigned char *buf, - int len) + int len) { - mp_size need, i; - unsigned char *tmp; - mp_digit *dz; + mp_size need, i; + unsigned char *tmp; + mp_digit *dz; - CHECK(z != NULL && buf != NULL && len > 0); + CHECK(z != NULL && buf != NULL && len > 0); - /* Figure out how many digits are needed to represent this value */ - need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; - if(!s_pad(K, z, need)) - return MP_MEMORY; + /* Figure out how many digits are needed to represent this value */ + need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; + if(!s_pad(K, z, need)) + return MP_MEMORY; - mp_int_zero(z); + mp_int_zero(z); - /* If the high-order bit is set, take the 2's complement before - reading the value (it will be restored afterward) */ - if(buf[0] >> (CHAR_BIT - 1)) { - MP_SIGN(z) = MP_NEG; - s_2comp(buf, len); - } + /* If the high-order bit is set, take the 2's complement before + reading the value (it will be restored afterward) */ + if(buf[0] >> (CHAR_BIT - 1)) { + MP_SIGN(z) = MP_NEG; + s_2comp(buf, len); + } - dz = MP_DIGITS(z); - for(tmp = buf, i = len; i > 0; --i, ++tmp) { - s_qmul(K, z, (mp_size) CHAR_BIT); - *dz |= *tmp; - } + dz = MP_DIGITS(z); + for(tmp = buf, i = len; i > 0; --i, ++tmp) { + s_qmul(K, z, (mp_size) CHAR_BIT); + *dz |= *tmp; + } - /* Restore 2's complement if we took it before */ - if(MP_SIGN(z) == MP_NEG) - s_2comp(buf, len); + /* Restore 2's complement if we took it before */ + if(MP_SIGN(z) == MP_NEG) + s_2comp(buf, len); - return MP_OK; + return MP_OK; } /* }}} */ @@ -2103,21 +2103,21 @@ mp_result mp_int_read_binary(klisp_State *K, mp_int z, unsigned char *buf, mp_result mp_int_binary_len(mp_int z) { - mp_result res = mp_int_count_bits(z); - int bytes = mp_int_unsigned_len(z); + mp_result res = mp_int_count_bits(z); + int bytes = mp_int_unsigned_len(z); - if(res <= 0) - return res; + if(res <= 0) + return res; - bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT; + bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT; - /* If the highest-order bit falls exactly on a byte boundary, we - need to pad with an extra byte so that the sign will be read - correctly when reading it back in. */ - if(bytes * CHAR_BIT == res) - ++bytes; + /* If the highest-order bit falls exactly on a byte boundary, we + need to pad with an extra byte so that the sign will be read + correctly when reading it back in. */ + if(bytes * CHAR_BIT == res) + ++bytes; - return bytes; + return bytes; } /* }}} */ @@ -2125,13 +2125,13 @@ mp_result mp_int_binary_len(mp_int z) /* {{{ mp_int_to_unsigned(z, buf, limit) */ mp_result mp_int_to_unsigned(klisp_State *K, mp_int z, unsigned char *buf, - int limit) + int limit) { - static const int NO_PADDING = 0; + static const int NO_PADDING = 0; - CHECK(z != NULL && buf != NULL); + CHECK(z != NULL && buf != NULL); - return s_tobin(z, buf, &limit, NO_PADDING); + return s_tobin(z, buf, &limit, NO_PADDING); } /* }}} */ @@ -2140,26 +2140,26 @@ mp_result mp_int_to_unsigned(klisp_State *K, mp_int z, unsigned char *buf, mp_result mp_int_read_unsigned(klisp_State *K, mp_int z, unsigned char *buf, int len) { - mp_size need, i; - unsigned char *tmp; - mp_digit *dz; + mp_size need, i; + unsigned char *tmp; + mp_digit *dz; - CHECK(z != NULL && buf != NULL && len > 0); + CHECK(z != NULL && buf != NULL && len > 0); - /* Figure out how many digits are needed to represent this value */ - need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; - if(!s_pad(K, z, need)) - return MP_MEMORY; + /* Figure out how many digits are needed to represent this value */ + need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; + if(!s_pad(K, z, need)) + return MP_MEMORY; - mp_int_zero(z); + mp_int_zero(z); - dz = MP_DIGITS(z); - for(tmp = buf, i = len; i > 0; --i, ++tmp) { - (void) s_qmul(K, z, CHAR_BIT); - *dz |= *tmp; - } + dz = MP_DIGITS(z); + for(tmp = buf, i = len; i > 0; --i, ++tmp) { + (void) s_qmul(K, z, CHAR_BIT); + *dz |= *tmp; + } - return MP_OK; + return MP_OK; } /* }}} */ @@ -2168,15 +2168,15 @@ mp_result mp_int_read_unsigned(klisp_State *K, mp_int z, unsigned char *buf, int mp_result mp_int_unsigned_len(mp_int z) { - mp_result res = mp_int_count_bits(z); - int bytes; + mp_result res = mp_int_count_bits(z); + int bytes; - if(res <= 0) - return res; + if(res <= 0) + return res; - bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT; + bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT; - return bytes; + return bytes; } /* }}} */ @@ -2185,43 +2185,43 @@ mp_result mp_int_unsigned_len(mp_int z) const char *mp_error_string(mp_result res) { - int ix; - if(res > 0) - return s_unknown_err; + int ix; + if(res > 0) + return s_unknown_err; - res = -res; - for(ix = 0; ix < res && s_error_msg[ix] != NULL; ++ix) - ; + res = -res; + for(ix = 0; ix < res && s_error_msg[ix] != NULL; ++ix) + ; - if(s_error_msg[ix] != NULL) - return s_error_msg[ix]; - else - return s_unknown_err; + if(s_error_msg[ix] != NULL) + return s_error_msg[ix]; + else + return s_unknown_err; } /* }}} */ /*------------------------------------------------------------------------*/ -/* Private functions for internal use. These make assumptions. */ +/* Private functions for internal use. These make assumptions. */ /* {{{ s_alloc(num) */ STATIC mp_digit *s_alloc(klisp_State *K, mp_size num) { - mp_digit *out = klispM_malloc(K, num * sizeof(mp_digit)); + mp_digit *out = klispM_malloc(K, num * sizeof(mp_digit)); - assert(out != NULL); /* for debugging */ + assert(out != NULL); /* for debugging */ #if DEBUG > 1 - { - mp_digit v = (mp_digit) 0xdeadbeef; - int ix; + { + mp_digit v = (mp_digit) 0xdeadbeef; + int ix; - for(ix = 0; ix < num; ++ix) - out[ix] = v; - } + for(ix = 0; ix < num; ++ix) + out[ix] = v; + } #endif - return out; + return out; } /* }}} */ @@ -2229,23 +2229,23 @@ STATIC mp_digit *s_alloc(klisp_State *K, mp_size num) /* {{{ s_realloc(old, osize, nsize) */ STATIC mp_digit *s_realloc(klisp_State *K, mp_digit *old, mp_size osize, - mp_size nsize) + mp_size nsize) { #if DEBUG > 1 - mp_digit *new = s_alloc(K, nsize); - int ix; + mp_digit *new = s_alloc(K, nsize); + int ix; - for(ix = 0; ix < nsize; ++ix) - new[ix] = (mp_digit) 0xdeadbeef; + for(ix = 0; ix < nsize; ++ix) + new[ix] = (mp_digit) 0xdeadbeef; - memcpy(new, old, osize * sizeof(mp_digit)); + memcpy(new, old, osize * sizeof(mp_digit)); #else - mp_digit *new = klispM_realloc_(K, old, osize * sizeof(mp_digit), - nsize * sizeof(mp_digit)); + mp_digit *new = klispM_realloc_(K, old, osize * sizeof(mp_digit), + nsize * sizeof(mp_digit)); - assert(new != NULL); /* for debugging */ + assert(new != NULL); /* for debugging */ #endif - return new; + return new; } /* }}} */ @@ -2254,122 +2254,122 @@ STATIC mp_digit *s_realloc(klisp_State *K, mp_digit *old, mp_size osize, STATIC void s_free(klisp_State *K, void *ptr, mp_size size) { - klispM_freemem(K, ptr, size * sizeof(mp_digit)); + klispM_freemem(K, ptr, size * sizeof(mp_digit)); } /* }}} */ /* {{{ s_pad(z, min) */ -STATIC int s_pad(klisp_State *K, mp_int z, mp_size min) +STATIC int s_pad(klisp_State *K, mp_int z, mp_size min) { - if(MP_ALLOC(z) < min) { - mp_size nsize = ROUND_PREC(min); - mp_digit *tmp; + if(MP_ALLOC(z) < min) { + mp_size nsize = ROUND_PREC(min); + mp_digit *tmp; - if((void *)z->digits == (void *)&(z->single)) { - if((tmp = s_alloc(K, nsize)) == NULL) - return 0; + if((void *)z->digits == (void *)&(z->single)) { + if((tmp = s_alloc(K, nsize)) == NULL) + return 0; - COPY(MP_DIGITS(z), tmp, MP_USED(z)); - } else if((tmp = s_realloc(K, MP_DIGITS(z), MP_ALLOC(z), nsize)) == NULL) - return 0; + COPY(MP_DIGITS(z), tmp, MP_USED(z)); + } else if((tmp = s_realloc(K, MP_DIGITS(z), MP_ALLOC(z), nsize)) == NULL) + return 0; - MP_DIGITS(z) = tmp; - MP_ALLOC(z) = nsize; - } + MP_DIGITS(z) = tmp; + MP_ALLOC(z) = nsize; + } - return 1; + return 1; } /* }}} */ /* {{{ s_fake(z, value, vbuf) */ -STATIC void s_fake(mp_int z, mp_small value, mp_digit vbuf[]) +STATIC void s_fake(mp_int z, mp_small value, mp_digit vbuf[]) { - mp_size uv = (mp_size) s_vpack(value, vbuf); + mp_size uv = (mp_size) s_vpack(value, vbuf); - z->used = uv; - z->alloc = MP_VALUE_DIGITS(value); - z->sign = (value < 0) ? MP_NEG : MP_ZPOS; - z->digits = vbuf; + z->used = uv; + z->alloc = MP_VALUE_DIGITS(value); + z->sign = (value < 0) ? MP_NEG : MP_ZPOS; + z->digits = vbuf; } /* }}} */ /* {{{ s_cdig(da, db, len) */ -STATIC int s_cdig(mp_digit *da, mp_digit *db, mp_size len) +STATIC int s_cdig(mp_digit *da, mp_digit *db, mp_size len) { - mp_digit *dat = da + len - 1, *dbt = db + len - 1; + mp_digit *dat = da + len - 1, *dbt = db + len - 1; - for(/* */; len != 0; --len, --dat, --dbt) { - if(*dat > *dbt) - return 1; - else if(*dat < *dbt) - return -1; - } + for(/* */; len != 0; --len, --dat, --dbt) { + if(*dat > *dbt) + return 1; + else if(*dat < *dbt) + return -1; + } - return 0; + return 0; } /* }}} */ /* {{{ s_vpack(v, t[]) */ -STATIC int s_vpack(mp_small v, mp_digit t[]) +STATIC int s_vpack(mp_small v, mp_digit t[]) { - mp_usmall uv = (mp_usmall) ((v < 0) ? -v : v); - int ndig = 0; + mp_usmall uv = (mp_usmall) ((v < 0) ? -v : v); + int ndig = 0; - if(uv == 0) - t[ndig++] = 0; - else { - while(uv != 0) { - t[ndig++] = (mp_digit) uv; - uv >>= MP_DIGIT_BIT/2; - uv >>= MP_DIGIT_BIT/2; + if(uv == 0) + t[ndig++] = 0; + else { + while(uv != 0) { + t[ndig++] = (mp_digit) uv; + uv >>= MP_DIGIT_BIT/2; + uv >>= MP_DIGIT_BIT/2; + } } - } - return ndig; + return ndig; } /* }}} */ /* {{{ s_ucmp(a, b) */ -STATIC int s_ucmp(mp_int a, mp_int b) +STATIC int s_ucmp(mp_int a, mp_int b) { - mp_size ua = MP_USED(a), ub = MP_USED(b); + mp_size ua = MP_USED(a), ub = MP_USED(b); - if(ua > ub) - return 1; - else if(ub > ua) - return -1; - else - return s_cdig(MP_DIGITS(a), MP_DIGITS(b), ua); + if(ua > ub) + return 1; + else if(ub > ua) + return -1; + else + return s_cdig(MP_DIGITS(a), MP_DIGITS(b), ua); } /* }}} */ /* {{{ s_vcmp(a, v) */ -STATIC int s_vcmp(mp_int a, mp_small v) +STATIC int s_vcmp(mp_int a, mp_small v) { - mp_digit vdig[MP_VALUE_DIGITS(v)]; - int ndig = 0; - mp_size ua = MP_USED(a); + mp_digit vdig[MP_VALUE_DIGITS(v)]; + int ndig = 0; + mp_size ua = MP_USED(a); - ndig = s_vpack(v, vdig); + ndig = s_vpack(v, vdig); - if(ua > ndig) - return 1; - else if(ua < ndig) - return -1; - else - return s_cdig(MP_DIGITS(a), vdig, ndig); + if(ua > ndig) + return 1; + else if(ua < ndig) + return -1; + else + return s_cdig(MP_DIGITS(a), vdig, ndig); } /* }}} */ @@ -2377,373 +2377,373 @@ STATIC int s_vcmp(mp_int a, mp_small v) /* {{{ s_uadd(da, db, dc, size_a, size_b) */ STATIC mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b) + mp_size size_a, mp_size size_b) { - mp_size pos; - mp_word w = 0; + mp_size pos; + mp_word w = 0; - /* Insure that da is the longer of the two to simplify later code */ - if(size_b > size_a) { - SWAP(mp_digit *, da, db); - SWAP(mp_size, size_a, size_b); - } + /* Insure that da is the longer of the two to simplify later code */ + if(size_b > size_a) { + SWAP(mp_digit *, da, db); + SWAP(mp_size, size_a, size_b); + } - /* Add corresponding digits until the shorter number runs out */ - for(pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) { - w = w + (mp_word) *da + (mp_word) *db; - *dc = LOWER_HALF(w); - w = UPPER_HALF(w); - } + /* Add corresponding digits until the shorter number runs out */ + for(pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) { + w = w + (mp_word) *da + (mp_word) *db; + *dc = LOWER_HALF(w); + w = UPPER_HALF(w); + } - /* Propagate carries as far as necessary */ - for(/* */; pos < size_a; ++pos, ++da, ++dc) { - w = w + *da; + /* Propagate carries as far as necessary */ + for(/* */; pos < size_a; ++pos, ++da, ++dc) { + w = w + *da; - *dc = LOWER_HALF(w); - w = UPPER_HALF(w); - } + *dc = LOWER_HALF(w); + w = UPPER_HALF(w); + } - /* Return carry out */ - return (mp_digit)w; + /* Return carry out */ + return (mp_digit)w; } /* }}} */ /* {{{ s_usub(da, db, dc, size_a, size_b) */ -STATIC void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b) +STATIC void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b) { - mp_size pos; - mp_word w = 0; + mp_size pos; + mp_word w = 0; - /* We assume that |a| >= |b| so this should definitely hold */ - assert(size_a >= size_b); + /* We assume that |a| >= |b| so this should definitely hold */ + assert(size_a >= size_b); - /* Subtract corresponding digits and propagate borrow */ - for(pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) { - w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */ - (mp_word)*da) - w - (mp_word)*db; + /* Subtract corresponding digits and propagate borrow */ + for(pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) { + w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */ + (mp_word)*da) - w - (mp_word)*db; - *dc = LOWER_HALF(w); - w = (UPPER_HALF(w) == 0); - } + *dc = LOWER_HALF(w); + w = (UPPER_HALF(w) == 0); + } - /* Finish the subtraction for remaining upper digits of da */ - for(/* */; pos < size_a; ++pos, ++da, ++dc) { - w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */ - (mp_word)*da) - w; + /* Finish the subtraction for remaining upper digits of da */ + for(/* */; pos < size_a; ++pos, ++da, ++dc) { + w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */ + (mp_word)*da) - w; - *dc = LOWER_HALF(w); - w = (UPPER_HALF(w) == 0); - } + *dc = LOWER_HALF(w); + w = (UPPER_HALF(w) == 0); + } - /* If there is a borrow out at the end, it violates the precondition */ - assert(w == 0); + /* If there is a borrow out at the end, it violates the precondition */ + assert(w == 0); } /* }}} */ /* {{{ s_kmul(da, db, dc, size_a, size_b) */ -STATIC int s_kmul(klisp_State *K, mp_digit *da, mp_digit *db, - mp_digit *dc, mp_size size_a, mp_size size_b) -{ - mp_size bot_size; - - /* Make sure b is the smaller of the two input values */ - if(size_b > size_a) { - SWAP(mp_digit *, da, db); - SWAP(mp_size, size_a, size_b); - } - - /* Insure that the bottom is the larger half in an odd-length split; - the code below relies on this being true. - */ - bot_size = (size_a + 1) / 2; - - /* If the values are big enough to bother with recursion, use the - Karatsuba algorithm to compute the product; otherwise use the - normal multiplication algorithm - */ - if(multiply_threshold && - size_a >= multiply_threshold && - size_b > bot_size) { - - mp_digit *t1, *t2, *t3, carry; - - mp_digit *a_top = da + bot_size; - mp_digit *b_top = db + bot_size; - - mp_size at_size = size_a - bot_size; - mp_size bt_size = size_b - bot_size; - mp_size buf_size = 2 * bot_size; - - /* Do a single allocation for all three temporary buffers needed; - each buffer must be big enough to hold the product of two - bottom halves, and one buffer needs space for the completed - product; twice the space is plenty. - */ - if((t1 = s_alloc(K, 4 * buf_size)) == NULL) return 0; - t2 = t1 + buf_size; - t3 = t2 + buf_size; - ZERO(t1, 4 * buf_size); - - /* t1 and t2 are initially used as temporaries to compute the inner product - (a1 + a0)(b1 + b0) = a1b1 + a1b0 + a0b1 + a0b0 - */ - carry = s_uadd(da, a_top, t1, bot_size, at_size); /* t1 = a1 + a0 */ - t1[bot_size] = carry; - - carry = s_uadd(db, b_top, t2, bot_size, bt_size); /* t2 = b1 + b0 */ - t2[bot_size] = carry; - - /* t3 = t1 * t2 */ - (void) s_kmul(K, t1, t2, t3, bot_size + 1, bot_size + 1); - - /* Now we'll get t1 = a0b0 and t2 = a1b1, and subtract them out so that - we're left with only the pieces we want: t3 = a1b0 + a0b1 - */ - ZERO(t1, buf_size); - ZERO(t2, buf_size); - (void) s_kmul(K, da, db, t1, bot_size, bot_size); /* t1 = a0 * b0 */ - (void) s_kmul(K, a_top, b_top, t2, at_size, bt_size); /* t2 = a1 * b1 */ - - /* Subtract out t1 and t2 to get the inner product */ - s_usub(t3, t1, t3, buf_size + 2, buf_size); - s_usub(t3, t2, t3, buf_size + 2, buf_size); - - /* Assemble the output value */ - COPY(t1, dc, buf_size); - carry = s_uadd(t3, dc + bot_size, dc + bot_size, - buf_size + 1, buf_size); - assert(carry == 0); +STATIC int s_kmul(klisp_State *K, mp_digit *da, mp_digit *db, + mp_digit *dc, mp_size size_a, mp_size size_b) +{ + mp_size bot_size; + + /* Make sure b is the smaller of the two input values */ + if(size_b > size_a) { + SWAP(mp_digit *, da, db); + SWAP(mp_size, size_a, size_b); + } + + /* Insure that the bottom is the larger half in an odd-length split; + the code below relies on this being true. + */ + bot_size = (size_a + 1) / 2; + + /* If the values are big enough to bother with recursion, use the + Karatsuba algorithm to compute the product; otherwise use the + normal multiplication algorithm + */ + if(multiply_threshold && + size_a >= multiply_threshold && + size_b > bot_size) { + + mp_digit *t1, *t2, *t3, carry; + + mp_digit *a_top = da + bot_size; + mp_digit *b_top = db + bot_size; + + mp_size at_size = size_a - bot_size; + mp_size bt_size = size_b - bot_size; + mp_size buf_size = 2 * bot_size; + + /* Do a single allocation for all three temporary buffers needed; + each buffer must be big enough to hold the product of two + bottom halves, and one buffer needs space for the completed + product; twice the space is plenty. + */ + if((t1 = s_alloc(K, 4 * buf_size)) == NULL) return 0; + t2 = t1 + buf_size; + t3 = t2 + buf_size; + ZERO(t1, 4 * buf_size); + + /* t1 and t2 are initially used as temporaries to compute the inner product + (a1 + a0)(b1 + b0) = a1b1 + a1b0 + a0b1 + a0b0 + */ + carry = s_uadd(da, a_top, t1, bot_size, at_size); /* t1 = a1 + a0 */ + t1[bot_size] = carry; + + carry = s_uadd(db, b_top, t2, bot_size, bt_size); /* t2 = b1 + b0 */ + t2[bot_size] = carry; + + /* t3 = t1 * t2 */ + (void) s_kmul(K, t1, t2, t3, bot_size + 1, bot_size + 1); + + /* Now we'll get t1 = a0b0 and t2 = a1b1, and subtract them out so that + we're left with only the pieces we want: t3 = a1b0 + a0b1 + */ + ZERO(t1, buf_size); + ZERO(t2, buf_size); + (void) s_kmul(K, da, db, t1, bot_size, bot_size); /* t1 = a0 * b0 */ + (void) s_kmul(K, a_top, b_top, t2, at_size, bt_size); /* t2 = a1 * b1 */ + + /* Subtract out t1 and t2 to get the inner product */ + s_usub(t3, t1, t3, buf_size + 2, buf_size); + s_usub(t3, t2, t3, buf_size + 2, buf_size); + + /* Assemble the output value */ + COPY(t1, dc, buf_size); + carry = s_uadd(t3, dc + bot_size, dc + bot_size, + buf_size + 1, buf_size); + assert(carry == 0); - carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size, - buf_size, buf_size); - assert(carry == 0); + carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size, + buf_size, buf_size); + assert(carry == 0); - /* note t2 and t3 are just internal pointers to t1 */ - s_free(K, t1, 4 * buf_size); - } - else { - s_umul(da, db, dc, size_a, size_b); - } + /* note t2 and t3 are just internal pointers to t1 */ + s_free(K, t1, 4 * buf_size); + } + else { + s_umul(da, db, dc, size_a, size_b); + } - return 1; + return 1; } /* }}} */ /* {{{ s_umul(da, db, dc, size_a, size_b) */ -STATIC void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b) +STATIC void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b) { - mp_size a, b; - mp_word w; + mp_size a, b; + mp_word w; - for(a = 0; a < size_a; ++a, ++dc, ++da) { - mp_digit *dct = dc; - mp_digit *dbt = db; + for(a = 0; a < size_a; ++a, ++dc, ++da) { + mp_digit *dct = dc; + mp_digit *dbt = db; - if(*da == 0) - continue; + if(*da == 0) + continue; - w = 0; - for(b = 0; b < size_b; ++b, ++dbt, ++dct) { - w = (mp_word)*da * (mp_word)*dbt + w + (mp_word)*dct; + w = 0; + for(b = 0; b < size_b; ++b, ++dbt, ++dct) { + w = (mp_word)*da * (mp_word)*dbt + w + (mp_word)*dct; - *dct = LOWER_HALF(w); - w = UPPER_HALF(w); - } + *dct = LOWER_HALF(w); + w = UPPER_HALF(w); + } - *dct = (mp_digit)w; - } + *dct = (mp_digit)w; + } } /* }}} */ /* {{{ s_ksqr(da, dc, size_a) */ -STATIC int s_ksqr(klisp_State *K, mp_digit *da, mp_digit *dc, - mp_size size_a) -{ - if(multiply_threshold && size_a > multiply_threshold) { - mp_size bot_size = (size_a + 1) / 2; - mp_digit *a_top = da + bot_size; - mp_digit *t1, *t2, *t3, carry; - mp_size at_size = size_a - bot_size; - mp_size buf_size = 2 * bot_size; - - if((t1 = s_alloc(K, 4 * buf_size)) == NULL) return 0; - t2 = t1 + buf_size; - t3 = t2 + buf_size; - ZERO(t1, 4 * buf_size); - - (void) s_ksqr(K, da, t1, bot_size); /* t1 = a0 ^ 2 */ - (void) s_ksqr(K, a_top, t2, at_size); /* t2 = a1 ^ 2 */ - - (void) s_kmul(K, da, a_top, t3, bot_size, at_size); /* t3 = a0 * a1 */ - - /* Quick multiply t3 by 2, shifting left (can't overflow) */ - { - int i, top = bot_size + at_size; - mp_word w, save = 0; - - for(i = 0; i < top; ++i) { - w = t3[i]; - w = (w << 1) | save; - t3[i] = LOWER_HALF(w); - save = UPPER_HALF(w); - } - t3[i] = LOWER_HALF(save); +STATIC int s_ksqr(klisp_State *K, mp_digit *da, mp_digit *dc, + mp_size size_a) +{ + if(multiply_threshold && size_a > multiply_threshold) { + mp_size bot_size = (size_a + 1) / 2; + mp_digit *a_top = da + bot_size; + mp_digit *t1, *t2, *t3, carry; + mp_size at_size = size_a - bot_size; + mp_size buf_size = 2 * bot_size; + + if((t1 = s_alloc(K, 4 * buf_size)) == NULL) return 0; + t2 = t1 + buf_size; + t3 = t2 + buf_size; + ZERO(t1, 4 * buf_size); + + (void) s_ksqr(K, da, t1, bot_size); /* t1 = a0 ^ 2 */ + (void) s_ksqr(K, a_top, t2, at_size); /* t2 = a1 ^ 2 */ + + (void) s_kmul(K, da, a_top, t3, bot_size, at_size); /* t3 = a0 * a1 */ + + /* Quick multiply t3 by 2, shifting left (can't overflow) */ + { + int i, top = bot_size + at_size; + mp_word w, save = 0; + + for(i = 0; i < top; ++i) { + w = t3[i]; + w = (w << 1) | save; + t3[i] = LOWER_HALF(w); + save = UPPER_HALF(w); + } + t3[i] = LOWER_HALF(save); + } + + /* Assemble the output value */ + COPY(t1, dc, 2 * bot_size); + carry = s_uadd(t3, dc + bot_size, dc + bot_size, + buf_size + 1, buf_size); + assert(carry == 0); + + carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size, + buf_size, buf_size); + assert(carry == 0); + + /* note that t2 and t2 are internal pointers only */ + s_free(K, t1, 4 * buf_size); + } + else { + s_usqr(da, dc, size_a); } - /* Assemble the output value */ - COPY(t1, dc, 2 * bot_size); - carry = s_uadd(t3, dc + bot_size, dc + bot_size, - buf_size + 1, buf_size); - assert(carry == 0); - - carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size, - buf_size, buf_size); - assert(carry == 0); - - /* note that t2 and t2 are internal pointers only */ - s_free(K, t1, 4 * buf_size); - } - else { - s_usqr(da, dc, size_a); - } - - return 1; + return 1; } /* }}} */ /* {{{ s_usqr(da, dc, size_a) */ -STATIC void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a) +STATIC void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a) { - mp_size i, j; - mp_word w; + mp_size i, j; + mp_word w; - for(i = 0; i < size_a; ++i, dc += 2, ++da) { - mp_digit *dct = dc, *dat = da; + for(i = 0; i < size_a; ++i, dc += 2, ++da) { + mp_digit *dct = dc, *dat = da; - if(*da == 0) - continue; + if(*da == 0) + continue; - /* Take care of the first digit, no rollover */ - w = (mp_word)*dat * (mp_word)*dat + (mp_word)*dct; - *dct = LOWER_HALF(w); - w = UPPER_HALF(w); - ++dat; ++dct; + /* Take care of the first digit, no rollover */ + w = (mp_word)*dat * (mp_word)*dat + (mp_word)*dct; + *dct = LOWER_HALF(w); + w = UPPER_HALF(w); + ++dat; ++dct; - for(j = i + 1; j < size_a; ++j, ++dat, ++dct) { - mp_word t = (mp_word)*da * (mp_word)*dat; - mp_word u = w + (mp_word)*dct, ov = 0; + for(j = i + 1; j < size_a; ++j, ++dat, ++dct) { + mp_word t = (mp_word)*da * (mp_word)*dat; + mp_word u = w + (mp_word)*dct, ov = 0; - /* Check if doubling t will overflow a word */ - if(HIGH_BIT_SET(t)) - ov = 1; + /* Check if doubling t will overflow a word */ + if(HIGH_BIT_SET(t)) + ov = 1; - w = t + t; + w = t + t; - /* Check if adding u to w will overflow a word */ - if(ADD_WILL_OVERFLOW(w, u)) - ov = 1; + /* Check if adding u to w will overflow a word */ + if(ADD_WILL_OVERFLOW(w, u)) + ov = 1; - w += u; + w += u; - *dct = LOWER_HALF(w); - w = UPPER_HALF(w); - if(ov) { - w += MP_DIGIT_MAX; /* MP_RADIX */ - ++w; - } - } + *dct = LOWER_HALF(w); + w = UPPER_HALF(w); + if(ov) { + w += MP_DIGIT_MAX; /* MP_RADIX */ + ++w; + } + } - w = w + *dct; - *dct = (mp_digit)w; - while((w = UPPER_HALF(w)) != 0) { - ++dct; w = w + *dct; - *dct = LOWER_HALF(w); - } + w = w + *dct; + *dct = (mp_digit)w; + while((w = UPPER_HALF(w)) != 0) { + ++dct; w = w + *dct; + *dct = LOWER_HALF(w); + } - assert(w == 0); - } + assert(w == 0); + } } /* }}} */ /* {{{ s_dadd(a, b) */ -STATIC void s_dadd(mp_int a, mp_digit b) +STATIC void s_dadd(mp_int a, mp_digit b) { - mp_word w = 0; - mp_digit *da = MP_DIGITS(a); - mp_size ua = MP_USED(a); + mp_word w = 0; + mp_digit *da = MP_DIGITS(a); + mp_size ua = MP_USED(a); - w = (mp_word)*da + b; - *da++ = LOWER_HALF(w); - w = UPPER_HALF(w); + w = (mp_word)*da + b; + *da++ = LOWER_HALF(w); + w = UPPER_HALF(w); - for(ua -= 1; ua > 0; --ua, ++da) { - w = (mp_word)*da + w; + for(ua -= 1; ua > 0; --ua, ++da) { + w = (mp_word)*da + w; - *da = LOWER_HALF(w); - w = UPPER_HALF(w); - } + *da = LOWER_HALF(w); + w = UPPER_HALF(w); + } - if(w) { - *da = (mp_digit)w; - MP_USED(a) += 1; - } + if(w) { + *da = (mp_digit)w; + MP_USED(a) += 1; + } } /* }}} */ /* {{{ s_dmul(a, b) */ -STATIC void s_dmul(mp_int a, mp_digit b) +STATIC void s_dmul(mp_int a, mp_digit b) { - mp_word w = 0; - mp_digit *da = MP_DIGITS(a); - mp_size ua = MP_USED(a); + mp_word w = 0; + mp_digit *da = MP_DIGITS(a); + mp_size ua = MP_USED(a); - while(ua > 0) { - w = (mp_word)*da * b + w; - *da++ = LOWER_HALF(w); - w = UPPER_HALF(w); - --ua; - } + while(ua > 0) { + w = (mp_word)*da * b + w; + *da++ = LOWER_HALF(w); + w = UPPER_HALF(w); + --ua; + } - if(w) { - *da = (mp_digit)w; - MP_USED(a) += 1; - } + if(w) { + *da = (mp_digit)w; + MP_USED(a) += 1; + } } /* }}} */ /* {{{ s_dbmul(da, b, dc, size_a) */ -STATIC void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a) +STATIC void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a) { - mp_word w = 0; + mp_word w = 0; - while(size_a > 0) { - w = (mp_word)*da++ * (mp_word)b + w; + while(size_a > 0) { + w = (mp_word)*da++ * (mp_word)b + w; - *dc++ = LOWER_HALF(w); - w = UPPER_HALF(w); - --size_a; - } + *dc++ = LOWER_HALF(w); + w = UPPER_HALF(w); + --size_a; + } - if(w) - *dc = LOWER_HALF(w); + if(w) + *dc = LOWER_HALF(w); } /* }}} */ @@ -2752,155 +2752,155 @@ STATIC void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a) STATIC mp_digit s_ddiv(mp_int a, mp_digit b) { - mp_word w = 0, qdigit; - mp_size ua = MP_USED(a); - mp_digit *da = MP_DIGITS(a) + ua - 1; + mp_word w = 0, qdigit; + mp_size ua = MP_USED(a); + mp_digit *da = MP_DIGITS(a) + ua - 1; - for(/* */; ua > 0; --ua, --da) { - w = (w << MP_DIGIT_BIT) | *da; - - if(w >= b) { - qdigit = w / b; - w = w % b; - } - else { - qdigit = 0; + for(/* */; ua > 0; --ua, --da) { + w = (w << MP_DIGIT_BIT) | *da; + + if(w >= b) { + qdigit = w / b; + w = w % b; + } + else { + qdigit = 0; + } + + *da = (mp_digit)qdigit; } - - *da = (mp_digit)qdigit; - } - CLAMP(a); - return (mp_digit)w; + CLAMP(a); + return (mp_digit)w; } /* }}} */ /* {{{ s_qdiv(z, p2) */ -STATIC void s_qdiv(mp_int z, mp_size p2) +STATIC void s_qdiv(mp_int z, mp_size p2) { - mp_size ndig = p2 / MP_DIGIT_BIT, nbits = p2 % MP_DIGIT_BIT; - mp_size uz = MP_USED(z); + mp_size ndig = p2 / MP_DIGIT_BIT, nbits = p2 % MP_DIGIT_BIT; + mp_size uz = MP_USED(z); - if(ndig) { - mp_size mark; - mp_digit *to, *from; + if(ndig) { + mp_size mark; + mp_digit *to, *from; - if(ndig >= uz) { - mp_int_zero(z); - return; - } + if(ndig >= uz) { + mp_int_zero(z); + return; + } - to = MP_DIGITS(z); from = to + ndig; + to = MP_DIGITS(z); from = to + ndig; - for(mark = ndig; mark < uz; ++mark) - *to++ = *from++; + for(mark = ndig; mark < uz; ++mark) + *to++ = *from++; - MP_USED(z) = uz - ndig; - } + MP_USED(z) = uz - ndig; + } - if(nbits) { - mp_digit d = 0, *dz, save; - mp_size up = MP_DIGIT_BIT - nbits; + if(nbits) { + mp_digit d = 0, *dz, save; + mp_size up = MP_DIGIT_BIT - nbits; - uz = MP_USED(z); - dz = MP_DIGITS(z) + uz - 1; + uz = MP_USED(z); + dz = MP_DIGITS(z) + uz - 1; - for(/* */; uz > 0; --uz, --dz) { - save = *dz; + for(/* */; uz > 0; --uz, --dz) { + save = *dz; - *dz = (*dz >> nbits) | (d << up); - d = save; - } + *dz = (*dz >> nbits) | (d << up); + d = save; + } - CLAMP(z); - } + CLAMP(z); + } - if(MP_USED(z) == 1 && z->digits[0] == 0) - MP_SIGN(z) = MP_ZPOS; + if(MP_USED(z) == 1 && z->digits[0] == 0) + MP_SIGN(z) = MP_ZPOS; } /* }}} */ /* {{{ s_qmod(z, p2) */ -STATIC void s_qmod(mp_int z, mp_size p2) +STATIC void s_qmod(mp_int z, mp_size p2) { - mp_size start = p2 / MP_DIGIT_BIT + 1, rest = p2 % MP_DIGIT_BIT; - mp_size uz = MP_USED(z); - mp_digit mask = (1 << rest) - 1; + mp_size start = p2 / MP_DIGIT_BIT + 1, rest = p2 % MP_DIGIT_BIT; + mp_size uz = MP_USED(z); + mp_digit mask = (1 << rest) - 1; - if(start <= uz) { - MP_USED(z) = start; - z->digits[start - 1] &= mask; - CLAMP(z); - } + if(start <= uz) { + MP_USED(z) = start; + z->digits[start - 1] &= mask; + CLAMP(z); + } } /* }}} */ /* {{{ s_qmul(z, p2) */ -STATIC int s_qmul(klisp_State *K, mp_int z, mp_size p2) +STATIC int s_qmul(klisp_State *K, mp_int z, mp_size p2) { - mp_size uz, need, rest, extra, i; - mp_digit *from, *to, d; + mp_size uz, need, rest, extra, i; + mp_digit *from, *to, d; - if(p2 == 0) - return 1; - - uz = MP_USED(z); - need = p2 / MP_DIGIT_BIT; rest = p2 % MP_DIGIT_BIT; + if(p2 == 0) + return 1; - /* Figure out if we need an extra digit at the top end; this occurs - if the topmost `rest' bits of the high-order digit of z are not - zero, meaning they will be shifted off the end if not preserved */ - extra = 0; - if(rest != 0) { - mp_digit *dz = MP_DIGITS(z) + uz - 1; + uz = MP_USED(z); + need = p2 / MP_DIGIT_BIT; rest = p2 % MP_DIGIT_BIT; - if((*dz >> (MP_DIGIT_BIT - rest)) != 0) - extra = 1; - } + /* Figure out if we need an extra digit at the top end; this occurs + if the topmost `rest' bits of the high-order digit of z are not + zero, meaning they will be shifted off the end if not preserved */ + extra = 0; + if(rest != 0) { + mp_digit *dz = MP_DIGITS(z) + uz - 1; - if(!s_pad(K, z, uz + need + extra)) - return 0; + if((*dz >> (MP_DIGIT_BIT - rest)) != 0) + extra = 1; + } - /* If we need to shift by whole digits, do that in one pass, then - to back and shift by partial digits. - */ - if(need > 0) { - from = MP_DIGITS(z) + uz - 1; - to = from + need; + if(!s_pad(K, z, uz + need + extra)) + return 0; - for(i = 0; i < uz; ++i) - *to-- = *from--; + /* If we need to shift by whole digits, do that in one pass, then + to back and shift by partial digits. + */ + if(need > 0) { + from = MP_DIGITS(z) + uz - 1; + to = from + need; - ZERO(MP_DIGITS(z), need); - uz += need; - } + for(i = 0; i < uz; ++i) + *to-- = *from--; - if(rest) { - d = 0; - for(i = need, from = MP_DIGITS(z) + need; i < uz; ++i, ++from) { - mp_digit save = *from; - - *from = (*from << rest) | (d >> (MP_DIGIT_BIT - rest)); - d = save; + ZERO(MP_DIGITS(z), need); + uz += need; } - d >>= (MP_DIGIT_BIT - rest); - if(d != 0) { - *from = d; - uz += extra; + if(rest) { + d = 0; + for(i = need, from = MP_DIGITS(z) + need; i < uz; ++i, ++from) { + mp_digit save = *from; + + *from = (*from << rest) | (d >> (MP_DIGIT_BIT - rest)); + d = save; + } + + d >>= (MP_DIGIT_BIT - rest); + if(d != 0) { + *from = d; + uz += extra; + } } - } - MP_USED(z) = uz; - CLAMP(z); + MP_USED(z) = uz; + CLAMP(z); - return 1; + return 1; } /* }}} */ @@ -2909,130 +2909,130 @@ STATIC int s_qmul(klisp_State *K, mp_int z, mp_size p2) /* Compute z = 2^p2 - |z|; requires that 2^p2 >= |z| The sign of the result is always zero/positive. - */ -STATIC int s_qsub(klisp_State *K, mp_int z, mp_size p2) +*/ +STATIC int s_qsub(klisp_State *K, mp_int z, mp_size p2) { - mp_digit hi = (1 << (p2 % MP_DIGIT_BIT)), *zp; - mp_size tdig = (p2 / MP_DIGIT_BIT), pos; - mp_word w = 0; + mp_digit hi = (1 << (p2 % MP_DIGIT_BIT)), *zp; + mp_size tdig = (p2 / MP_DIGIT_BIT), pos; + mp_word w = 0; - if(!s_pad(K, z, tdig + 1)) - return 0; + if(!s_pad(K, z, tdig + 1)) + return 0; - for(pos = 0, zp = MP_DIGITS(z); pos < tdig; ++pos, ++zp) { - w = ((mp_word) MP_DIGIT_MAX + 1) - w - (mp_word)*zp; + for(pos = 0, zp = MP_DIGITS(z); pos < tdig; ++pos, ++zp) { + w = ((mp_word) MP_DIGIT_MAX + 1) - w - (mp_word)*zp; - *zp = LOWER_HALF(w); - w = UPPER_HALF(w) ? 0 : 1; - } + *zp = LOWER_HALF(w); + w = UPPER_HALF(w) ? 0 : 1; + } - w = ((mp_word) MP_DIGIT_MAX + 1 + hi) - w - (mp_word)*zp; - *zp = LOWER_HALF(w); + w = ((mp_word) MP_DIGIT_MAX + 1 + hi) - w - (mp_word)*zp; + *zp = LOWER_HALF(w); - assert(UPPER_HALF(w) != 0); /* no borrow out should be possible */ + assert(UPPER_HALF(w) != 0); /* no borrow out should be possible */ - MP_SIGN(z) = MP_ZPOS; - CLAMP(z); + MP_SIGN(z) = MP_ZPOS; + CLAMP(z); - return 1; + return 1; } /* }}} */ /* {{{ s_dp2k(z) */ -STATIC int s_dp2k(mp_int z) +STATIC int s_dp2k(mp_int z) { - int k = 0; - mp_digit *dp = MP_DIGITS(z), d; + int k = 0; + mp_digit *dp = MP_DIGITS(z), d; - if(MP_USED(z) == 1 && *dp == 0) - return 1; + if(MP_USED(z) == 1 && *dp == 0) + return 1; - while(*dp == 0) { - k += MP_DIGIT_BIT; - ++dp; - } + while(*dp == 0) { + k += MP_DIGIT_BIT; + ++dp; + } - d = *dp; - while((d & 1) == 0) { - d >>= 1; - ++k; - } + d = *dp; + while((d & 1) == 0) { + d >>= 1; + ++k; + } - return k; + return k; } /* }}} */ /* {{{ s_isp2(z) */ -STATIC int s_isp2(mp_int z) +STATIC int s_isp2(mp_int z) { - mp_size uz = MP_USED(z), k = 0; - mp_digit *dz = MP_DIGITS(z), d; + mp_size uz = MP_USED(z), k = 0; + mp_digit *dz = MP_DIGITS(z), d; - while(uz > 1) { - if(*dz++ != 0) - return -1; - k += MP_DIGIT_BIT; - --uz; - } + while(uz > 1) { + if(*dz++ != 0) + return -1; + k += MP_DIGIT_BIT; + --uz; + } - d = *dz; - while(d > 1) { - if(d & 1) - return -1; - ++k; d >>= 1; - } + d = *dz; + while(d > 1) { + if(d & 1) + return -1; + ++k; d >>= 1; + } - return (int) k; + return (int) k; } /* }}} */ /* {{{ s_2expt(z, k) */ -STATIC int s_2expt(klisp_State *K, mp_int z, mp_small k) +STATIC int s_2expt(klisp_State *K, mp_int z, mp_small k) { - mp_size ndig, rest; - mp_digit *dz; + mp_size ndig, rest; + mp_digit *dz; - ndig = (k + MP_DIGIT_BIT) / MP_DIGIT_BIT; - rest = k % MP_DIGIT_BIT; + ndig = (k + MP_DIGIT_BIT) / MP_DIGIT_BIT; + rest = k % MP_DIGIT_BIT; - if(!s_pad(K, z, ndig)) - return 0; + if(!s_pad(K, z, ndig)) + return 0; - dz = MP_DIGITS(z); - ZERO(dz, ndig); - *(dz + ndig - 1) = (1 << rest); - MP_USED(z) = ndig; + dz = MP_DIGITS(z); + ZERO(dz, ndig); + *(dz + ndig - 1) = (1 << rest); + MP_USED(z) = ndig; - return 1; + return 1; } /* }}} */ /* {{{ s_norm(a, b) */ -STATIC int s_norm(klisp_State *K, mp_int a, mp_int b) +STATIC int s_norm(klisp_State *K, mp_int a, mp_int b) { - mp_digit d = b->digits[MP_USED(b) - 1]; - int k = 0; + mp_digit d = b->digits[MP_USED(b) - 1]; + int k = 0; - while(d < (mp_digit) (1 << (MP_DIGIT_BIT - 1))) { /* d < (MP_RADIX / 2) */ - d <<= 1; - ++k; - } + while(d < (mp_digit) (1 << (MP_DIGIT_BIT - 1))) { /* d < (MP_RADIX / 2) */ + d <<= 1; + ++k; + } - /* These multiplications can't fail */ - if(k != 0) { - (void) s_qmul(K, a, (mp_size) k); - (void) s_qmul(K, b, (mp_size) k); - } + /* These multiplications can't fail */ + if(k != 0) { + (void) s_qmul(K, a, (mp_size) k); + (void) s_qmul(K, b, (mp_size) k); + } - return k; + return k; } /* }}} */ @@ -3041,61 +3041,61 @@ STATIC int s_norm(klisp_State *K, mp_int a, mp_int b) STATIC mp_result s_brmu(klisp_State *K, mp_int z, mp_int m) { - mp_size um = MP_USED(m) * 2; + mp_size um = MP_USED(m) * 2; - if(!s_pad(K, z, um)) - return MP_MEMORY; + if(!s_pad(K, z, um)) + return MP_MEMORY; - s_2expt(K, z, MP_DIGIT_BIT * um); - return mp_int_div(K, z, m, z, NULL); + s_2expt(K, z, MP_DIGIT_BIT * um); + return mp_int_div(K, z, m, z, NULL); } /* }}} */ /* {{{ s_reduce(x, m, mu, q1, q2) */ -STATIC int s_reduce(klisp_State *K, mp_int x, mp_int m, mp_int mu, - mp_int q1, mp_int q2) +STATIC int s_reduce(klisp_State *K, mp_int x, mp_int m, mp_int mu, + mp_int q1, mp_int q2) { - mp_size um = MP_USED(m), umb_p1, umb_m1; + mp_size um = MP_USED(m), umb_p1, umb_m1; - umb_p1 = (um + 1) * MP_DIGIT_BIT; - umb_m1 = (um - 1) * MP_DIGIT_BIT; + umb_p1 = (um + 1) * MP_DIGIT_BIT; + umb_m1 = (um - 1) * MP_DIGIT_BIT; - if(mp_int_copy(K, x, q1) != MP_OK) - return 0; + if(mp_int_copy(K, x, q1) != MP_OK) + return 0; - /* Compute q2 = floor((floor(x / b^(k-1)) * mu) / b^(k+1)) */ - s_qdiv(q1, umb_m1); - UMUL(K, q1, mu, q2); - s_qdiv(q2, umb_p1); - - /* Set x = x mod b^(k+1) */ - s_qmod(x, umb_p1); - - /* Now, q is a guess for the quotient a / m. - Compute x - q * m mod b^(k+1), replacing x. This may be off - by a factor of 2m, but no more than that. - */ - UMUL(K, q2, m, q1); - s_qmod(q1, umb_p1); - (void) mp_int_sub(K, x, q1, x); /* can't fail */ - - /* The result may be < 0; if it is, add b^(k+1) to pin it in the - proper range. */ - if((CMPZ(x) < 0) && !s_qsub(K, x, umb_p1)) - return 0; + /* Compute q2 = floor((floor(x / b^(k-1)) * mu) / b^(k+1)) */ + s_qdiv(q1, umb_m1); + UMUL(K, q1, mu, q2); + s_qdiv(q2, umb_p1); + + /* Set x = x mod b^(k+1) */ + s_qmod(x, umb_p1); - /* If x > m, we need to back it off until it is in range. - This will be required at most twice. */ - if(mp_int_compare(x, m) >= 0) { - (void) mp_int_sub(K, x, m, x); - if(mp_int_compare(x, m) >= 0) - (void) mp_int_sub(K, x, m, x); - } + /* Now, q is a guess for the quotient a / m. + Compute x - q * m mod b^(k+1), replacing x. This may be off + by a factor of 2m, but no more than that. + */ + UMUL(K, q2, m, q1); + s_qmod(q1, umb_p1); + (void) mp_int_sub(K, x, q1, x); /* can't fail */ + + /* The result may be < 0; if it is, add b^(k+1) to pin it in the + proper range. */ + if((CMPZ(x) < 0) && !s_qsub(K, x, umb_p1)) + return 0; - /* At this point, x has been properly reduced. */ - return 1; + /* If x > m, we need to back it off until it is in range. + This will be required at most twice. */ + if(mp_int_compare(x, m) >= 0) { + (void) mp_int_sub(K, x, m, x); + if(mp_int_compare(x, m) >= 0) + (void) mp_int_sub(K, x, m, x); + } + + /* At this point, x has been properly reduced. */ + return 1; } /* }}} */ @@ -3105,77 +3105,77 @@ STATIC int s_reduce(klisp_State *K, mp_int x, mp_int m, mp_int mu, /* Perform modular exponentiation using Barrett's method, where mu is the reduction constant for m. Assumes a < m, b > 0. */ STATIC mp_result s_embar(klisp_State *K, mp_int a, mp_int b, mp_int m, - mp_int mu, mp_int c) + mp_int mu, mp_int c) { - mp_digit *db, *dbt, umu, d; - mpz_t temp[3]; - mp_result res; - int last = 0; + mp_digit *db, *dbt, umu, d; + mpz_t temp[3]; + mp_result res; + int last = 0; - umu = MP_USED(mu); db = MP_DIGITS(b); dbt = db + MP_USED(b) - 1; + umu = MP_USED(mu); db = MP_DIGITS(b); dbt = db + MP_USED(b) - 1; - while(last < 3) { - SETUP(mp_int_init_size(K, TEMP(last), 4 * umu), last); - ZERO(MP_DIGITS(TEMP(last - 1)), MP_ALLOC(TEMP(last - 1))); - } + while(last < 3) { + SETUP(mp_int_init_size(K, TEMP(last), 4 * umu), last); + ZERO(MP_DIGITS(TEMP(last - 1)), MP_ALLOC(TEMP(last - 1))); + } - (void) mp_int_set_value(K, c, 1); + (void) mp_int_set_value(K, c, 1); - /* Take care of low-order digits */ - while(db < dbt) { - int i; + /* Take care of low-order digits */ + while(db < dbt) { + int i; - for(d = *db, i = MP_DIGIT_BIT; i > 0; --i, d >>= 1) { - if(d & 1) { - /* The use of a second temporary avoids allocation */ - UMUL(K, c, a, TEMP(0)); - if(!s_reduce(K, TEMP(0), m, mu, TEMP(1), TEMP(2))) { - res = MP_MEMORY; goto CLEANUP; - } - mp_int_copy(K, TEMP(0), c); - } + for(d = *db, i = MP_DIGIT_BIT; i > 0; --i, d >>= 1) { + if(d & 1) { + /* The use of a second temporary avoids allocation */ + UMUL(K, c, a, TEMP(0)); + if(!s_reduce(K, TEMP(0), m, mu, TEMP(1), TEMP(2))) { + res = MP_MEMORY; goto CLEANUP; + } + mp_int_copy(K, TEMP(0), c); + } - USQR(K, a, TEMP(0)); - assert(MP_SIGN(TEMP(0)) == MP_ZPOS); - if(!s_reduce(K, TEMP(0), m, mu, TEMP(1), TEMP(2))) { - res = MP_MEMORY; goto CLEANUP; - } - assert(MP_SIGN(TEMP(0)) == MP_ZPOS); - mp_int_copy(K, TEMP(0), a); + USQR(K, a, TEMP(0)); + assert(MP_SIGN(TEMP(0)) == MP_ZPOS); + if(!s_reduce(K, TEMP(0), m, mu, TEMP(1), TEMP(2))) { + res = MP_MEMORY; goto CLEANUP; + } + assert(MP_SIGN(TEMP(0)) == MP_ZPOS); + mp_int_copy(K, TEMP(0), a); - } + } - ++db; - } - - /* Take care of highest-order digit */ - d = *dbt; - for(;;) { - if(d & 1) { - UMUL(K, c, a, TEMP(0)); - if(!s_reduce(K, TEMP(0), m, mu, TEMP(1), TEMP(2))) { - res = MP_MEMORY; goto CLEANUP; - } - mp_int_copy(K, TEMP(0), c); + ++db; } - - d >>= 1; - if(!d) break; - USQR(K, a, TEMP(0)); - if(!s_reduce(K, TEMP(0), m, mu, TEMP(1), TEMP(2))) { - res = MP_MEMORY; goto CLEANUP; + /* Take care of highest-order digit */ + d = *dbt; + for(;;) { + if(d & 1) { + UMUL(K, c, a, TEMP(0)); + if(!s_reduce(K, TEMP(0), m, mu, TEMP(1), TEMP(2))) { + res = MP_MEMORY; goto CLEANUP; + } + mp_int_copy(K, TEMP(0), c); + } + + d >>= 1; + if(!d) break; + + USQR(K, a, TEMP(0)); + if(!s_reduce(K, TEMP(0), m, mu, TEMP(1), TEMP(2))) { + res = MP_MEMORY; goto CLEANUP; + } + (void) mp_int_copy(K, TEMP(0), a); } - (void) mp_int_copy(K, TEMP(0), a); - } - CLEANUP: - while(--last >= 0) - mp_int_clear(K, TEMP(last)); +CLEANUP: + while(--last >= 0) + mp_int_clear(K, TEMP(last)); - return res; + return res; } /* }}} */ @@ -3184,112 +3184,112 @@ STATIC mp_result s_embar(klisp_State *K, mp_int a, mp_int b, mp_int m, /* Precondition: a >= b and b > 0 Postcondition: a' = a / b, b' = a % b - */ +*/ STATIC mp_result s_udiv(klisp_State *K, mp_int a, mp_int b) { - mpz_t q, r, t; - mp_size ua, ub, qpos = 0; - mp_digit *da, btop; - mp_result res = MP_OK; - int k, skip = 0; - - /* Force signs to positive */ - MP_SIGN(a) = MP_ZPOS; - MP_SIGN(b) = MP_ZPOS; - - /* Normalize, per Knuth */ - k = s_norm(K, a, b); - - ua = MP_USED(a); ub = MP_USED(b); btop = b->digits[ub - 1]; - if((res = mp_int_init_size(K, &q, ua)) != MP_OK) return res; - if((res = mp_int_init_size(K, &t, ua + 1)) != MP_OK) goto CLEANUP; - - da = MP_DIGITS(a); - r.digits = da + ua - 1; /* The contents of r are shared with a */ - r.used = 1; - r.sign = MP_ZPOS; - r.alloc = MP_ALLOC(a); - ZERO(t.digits, t.alloc); - - /* Solve for quotient digits, store in q.digits in reverse order */ - while(r.digits >= da) { - assert(qpos <= q.alloc); - - if(s_ucmp(b, &r) > 0) { - r.digits -= 1; - r.used += 1; - - if(++skip > 1 && qpos > 0) - q.digits[qpos++] = 0; - - CLAMP(&r); + mpz_t q, r, t; + mp_size ua, ub, qpos = 0; + mp_digit *da, btop; + mp_result res = MP_OK; + int k, skip = 0; + + /* Force signs to positive */ + MP_SIGN(a) = MP_ZPOS; + MP_SIGN(b) = MP_ZPOS; + + /* Normalize, per Knuth */ + k = s_norm(K, a, b); + + ua = MP_USED(a); ub = MP_USED(b); btop = b->digits[ub - 1]; + if((res = mp_int_init_size(K, &q, ua)) != MP_OK) return res; + if((res = mp_int_init_size(K, &t, ua + 1)) != MP_OK) goto CLEANUP; + + da = MP_DIGITS(a); + r.digits = da + ua - 1; /* The contents of r are shared with a */ + r.used = 1; + r.sign = MP_ZPOS; + r.alloc = MP_ALLOC(a); + ZERO(t.digits, t.alloc); + + /* Solve for quotient digits, store in q.digits in reverse order */ + while(r.digits >= da) { + assert(qpos <= q.alloc); + + if(s_ucmp(b, &r) > 0) { + r.digits -= 1; + r.used += 1; + + if(++skip > 1 && qpos > 0) + q.digits[qpos++] = 0; + + CLAMP(&r); + } + else { + mp_word pfx = r.digits[r.used - 1]; + mp_word qdigit; + + // Bugfix (was pfx <= btop in imath <= 1.17) Andres Navarro + if(r.used > 1 && pfx < btop) { + pfx <<= MP_DIGIT_BIT / 2; + pfx <<= MP_DIGIT_BIT / 2; + pfx |= r.digits[r.used - 2]; + } + + qdigit = pfx / btop; + if(qdigit > MP_DIGIT_MAX) { + qdigit = MP_DIGIT_MAX; + } + + s_dbmul(MP_DIGITS(b), (mp_digit) qdigit, t.digits, ub); + t.used = ub + 1; CLAMP(&t); + while(s_ucmp(&t, &r) > 0) { + --qdigit; + (void) mp_int_sub(K, &t, b, &t); /* cannot fail */ + } + + s_usub(r.digits, t.digits, r.digits, r.used, t.used); + CLAMP(&r); + + q.digits[qpos++] = (mp_digit) qdigit; + ZERO(t.digits, t.used); + skip = 0; + } } - else { - mp_word pfx = r.digits[r.used - 1]; - mp_word qdigit; - - // Bugfix (was pfx <= btop in imath <= 1.17) Andres Navarro - if(r.used > 1 && pfx < btop) { - pfx <<= MP_DIGIT_BIT / 2; - pfx <<= MP_DIGIT_BIT / 2; - pfx |= r.digits[r.used - 2]; - } - - qdigit = pfx / btop; - if(qdigit > MP_DIGIT_MAX) { - qdigit = MP_DIGIT_MAX; - } - - s_dbmul(MP_DIGITS(b), (mp_digit) qdigit, t.digits, ub); - t.used = ub + 1; CLAMP(&t); - while(s_ucmp(&t, &r) > 0) { - --qdigit; - (void) mp_int_sub(K, &t, b, &t); /* cannot fail */ - } - - s_usub(r.digits, t.digits, r.digits, r.used, t.used); - CLAMP(&r); - - q.digits[qpos++] = (mp_digit) qdigit; - ZERO(t.digits, t.used); - skip = 0; - } - } - - /* Put quotient digits in the correct order, and discard extra zeroes */ - q.used = qpos; - REV(mp_digit, q.digits, qpos); - CLAMP(&q); - - /* Denormalize the remainder */ - CLAMP(a); - if(k != 0) - s_qdiv(a, k); + + /* Put quotient digits in the correct order, and discard extra zeroes */ + q.used = qpos; + REV(mp_digit, q.digits, qpos); + CLAMP(&q); + + /* Denormalize the remainder */ + CLAMP(a); + if(k != 0) + s_qdiv(a, k); - mp_int_copy(K, a, b); /* ok: 0 <= r < b */ - mp_int_copy(K, &q, a); /* ok: q <= a */ + mp_int_copy(K, a, b); /* ok: 0 <= r < b */ + mp_int_copy(K, &q, a); /* ok: q <= a */ - mp_int_clear(K, &t); - CLEANUP: - mp_int_clear(K, &q); - return res; + mp_int_clear(K, &t); +CLEANUP: + mp_int_clear(K, &q); + return res; } /* }}} */ /* {{{ s_outlen(z, r) */ -STATIC int s_outlen(mp_int z, mp_size r) +STATIC int s_outlen(mp_int z, mp_size r) { - mp_result bits; - double raw; + mp_result bits; + double raw; - assert(r >= MP_MIN_RADIX && r <= MP_MAX_RADIX); + assert(r >= MP_MIN_RADIX && r <= MP_MAX_RADIX); - bits = mp_int_count_bits(z); - raw = (double)bits * s_log2[r]; + bits = mp_int_count_bits(z); + raw = (double)bits * s_log2[r]; - return (int)(raw + 0.999999); + return (int)(raw + 0.999999); } /* }}} */ @@ -3298,70 +3298,70 @@ STATIC int s_outlen(mp_int z, mp_size r) STATIC mp_size s_inlen(int len, mp_size r) { - double raw = (double)len / s_log2[r]; - mp_size bits = (mp_size)(raw + 0.5); + double raw = (double)len / s_log2[r]; + mp_size bits = (mp_size)(raw + 0.5); - return (mp_size)((bits + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT); + return (mp_size)((bits + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT); } /* }}} */ /* {{{ s_ch2val(c, r) */ -STATIC int s_ch2val(char c, int r) +STATIC int s_ch2val(char c, int r) { - int out; + int out; - if(isdigit((unsigned char) c)) - out = c - '0'; - else if(r > 10 && isalpha((unsigned char) c)) - out = toupper(c) - 'A' + 10; - else - return -1; + if(isdigit((unsigned char) c)) + out = c - '0'; + else if(r > 10 && isalpha((unsigned char) c)) + out = toupper(c) - 'A' + 10; + else + return -1; - return (out >= r) ? -1 : out; + return (out >= r) ? -1 : out; } /* }}} */ /* {{{ s_val2ch(v, caps) */ -STATIC char s_val2ch(int v, int caps) +STATIC char s_val2ch(int v, int caps) { - assert(v >= 0); + assert(v >= 0); - if(v < 10) - return v + '0'; - else { - char out = (v - 10) + 'a'; + if(v < 10) + return v + '0'; + else { + char out = (v - 10) + 'a'; - if(caps) - return toupper(out); - else - return out; - } + if(caps) + return toupper(out); + else + return out; + } } /* }}} */ /* {{{ s_2comp(buf, len) */ -STATIC void s_2comp(unsigned char *buf, int len) +STATIC void s_2comp(unsigned char *buf, int len) { - int i; - unsigned short s = 1; + int i; + unsigned short s = 1; - for(i = len - 1; i >= 0; --i) { - unsigned char c = ~buf[i]; + for(i = len - 1; i >= 0; --i) { + unsigned char c = ~buf[i]; - s = c + s; - c = s & UCHAR_MAX; - s >>= CHAR_BIT; + s = c + s; + c = s & UCHAR_MAX; + s >>= CHAR_BIT; - buf[i] = c; - } + buf[i] = c; + } - /* last carry out is ignored */ + /* last carry out is ignored */ } /* }}} */ @@ -3370,44 +3370,44 @@ STATIC void s_2comp(unsigned char *buf, int len) STATIC mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad) { - mp_size uz; - mp_digit *dz; - int pos = 0, limit = *limpos; + mp_size uz; + mp_digit *dz; + int pos = 0, limit = *limpos; - uz = MP_USED(z); dz = MP_DIGITS(z); - while(uz > 0 && pos < limit) { - mp_digit d = *dz++; - int i; + uz = MP_USED(z); dz = MP_DIGITS(z); + while(uz > 0 && pos < limit) { + mp_digit d = *dz++; + int i; - for(i = sizeof(mp_digit); i > 0 && pos < limit; --i) { - buf[pos++] = (unsigned char)d; - d >>= CHAR_BIT; + for(i = sizeof(mp_digit); i > 0 && pos < limit; --i) { + buf[pos++] = (unsigned char)d; + d >>= CHAR_BIT; - /* Don't write leading zeroes */ - if(d == 0 && uz == 1) - i = 0; /* exit loop without signaling truncation */ - } + /* Don't write leading zeroes */ + if(d == 0 && uz == 1) + i = 0; /* exit loop without signaling truncation */ + } - /* Detect truncation (loop exited with pos >= limit) */ - if(i > 0) break; + /* Detect truncation (loop exited with pos >= limit) */ + if(i > 0) break; - --uz; - } + --uz; + } - if(pad != 0 && (buf[pos - 1] >> (CHAR_BIT - 1))) { - if(pos < limit) - buf[pos++] = 0; - else - uz = 1; - } + if(pad != 0 && (buf[pos - 1] >> (CHAR_BIT - 1))) { + if(pos < limit) + buf[pos++] = 0; + else + uz = 1; + } - /* Digits are in reverse order, fix that */ - REV(unsigned char, buf, pos); + /* Digits are in reverse order, fix that */ + REV(unsigned char, buf, pos); - /* Return the number of bytes actually written */ - *limpos = pos; + /* Return the number of bytes actually written */ + *limpos = pos; - return (uz == 0) ? MP_OK : MP_TRUNC; + return (uz == 0) ? MP_OK : MP_TRUNC; } /* }}} */ @@ -3415,30 +3415,30 @@ STATIC mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad) /* {{{ s_print(tag, z) */ #if DEBUG -void s_print(char *tag, mp_int z) +void s_print(char *tag, mp_int z) { - int i; + int i; - fprintf(stderr, "%s: %c ", tag, - (MP_SIGN(z) == MP_NEG) ? '-' : '+'); + fprintf(stderr, "%s: %c ", tag, + (MP_SIGN(z) == MP_NEG) ? '-' : '+'); - for(i = MP_USED(z) - 1; i >= 0; --i) - fprintf(stderr, "%0*X", (int)(MP_DIGIT_BIT / 4), z->digits[i]); + for(i = MP_USED(z) - 1; i >= 0; --i) + fprintf(stderr, "%0*X", (int)(MP_DIGIT_BIT / 4), z->digits[i]); - fputc('\n', stderr); + fputc('\n', stderr); } -void s_print_buf(char *tag, mp_digit *buf, mp_size num) +void s_print_buf(char *tag, mp_digit *buf, mp_size num) { - int i; + int i; - fprintf(stderr, "%s: ", tag); + fprintf(stderr, "%s: ", tag); - for(i = num - 1; i >= 0; --i) - fprintf(stderr, "%0*X", (int)(MP_DIGIT_BIT / 4), buf[i]); + for(i = num - 1; i >= 0; --i) + fprintf(stderr, "%0*X", (int)(MP_DIGIT_BIT / 4), buf[i]); - fputc('\n', stderr); + fputc('\n', stderr); } #endif diff --git a/src/imath.h b/src/imath.h @@ -34,39 +34,39 @@ extern "C" { #endif #if USE_C99 -typedef unsigned char mp_sign; -typedef uint32_t mp_size; -typedef int mp_result; -typedef int32_t mp_small; /* must be a signed type */ -typedef uint32_t mp_usmall; /* must be an unsigned type */ -typedef uint32_t mp_digit; -typedef uint64_t mp_word; + typedef unsigned char mp_sign; + typedef uint32_t mp_size; + typedef int mp_result; + typedef int32_t mp_small; /* must be a signed type */ + typedef uint32_t mp_usmall; /* must be an unsigned type */ + typedef uint32_t mp_digit; + typedef uint64_t mp_word; #else /* USE_C99 */ -typedef unsigned char mp_sign; -typedef unsigned int mp_size; -typedef int mp_result; -typedef long mp_small; /* must be a signed type */ -typedef unsigned long mp_usmall; /* must be an unsigned type */ + typedef unsigned char mp_sign; + typedef unsigned int mp_size; + typedef int mp_result; + typedef long mp_small; /* must be a signed type */ + typedef unsigned long mp_usmall; /* must be an unsigned type */ #ifdef USE_LONG_LONG -typedef unsigned int mp_digit; -typedef unsigned long long mp_word; + typedef unsigned int mp_digit; + typedef unsigned long long mp_word; #else /* USE_LONG_LONG */ -typedef unsigned short mp_digit; -typedef unsigned int mp_word; + typedef unsigned short mp_digit; + typedef unsigned int mp_word; #endif /* USE_LONG_LONG */ #endif /* USE_C99 */ /* Andres Navarro: Use kobject type instead */ -typedef Bigint mpz_t, *mp_int; + typedef Bigint mpz_t, *mp_int; #if 0 -typedef struct mpz { - mp_digit single; - mp_digit *digits; - mp_size alloc; - mp_size used; - mp_sign sign; -} mpz_t, *mp_int; + typedef struct mpz { + mp_digit single; + mp_digit *digits; + mp_size alloc; + mp_size used; + mp_sign sign; + } mpz_t, *mp_int; #endif #define MP_SINGLE(Z) ((Z)->single) /* added to correct check in mp_int_clear */ @@ -75,18 +75,18 @@ typedef struct mpz { #define MP_USED(Z) ((Z)->used) #define MP_SIGN(Z) ((Z)->sign) -extern const mp_result MP_OK; -extern const mp_result MP_FALSE; -extern const mp_result MP_TRUE; -extern const mp_result MP_MEMORY; -extern const mp_result MP_RANGE; -extern const mp_result MP_UNDEF; -extern const mp_result MP_TRUNC; -extern const mp_result MP_BADARG; -extern const mp_result MP_MINERR; + extern const mp_result MP_OK; + extern const mp_result MP_FALSE; + extern const mp_result MP_TRUE; + extern const mp_result MP_MEMORY; + extern const mp_result MP_RANGE; + extern const mp_result MP_UNDEF; + extern const mp_result MP_TRUNC; + extern const mp_result MP_BADARG; + extern const mp_result MP_MINERR; #define MP_DIGIT_BIT (sizeof(mp_digit) * CHAR_BIT) -#define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT) +#define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT) /* Andres Navarro: USE_C99 */ #ifdef USE_C99 #define MP_SMALL_MIN INT32_MIN @@ -103,16 +103,16 @@ extern const mp_result MP_MINERR; #ifdef USE_LONG_LONG # ifndef ULONG_LONG_MAX # ifdef ULLONG_MAX -# define ULONG_LONG_MAX ULLONG_MAX +# define ULONG_LONG_MAX ULLONG_MAX # else -# error "Maximum value of unsigned long long not defined!" +# error "Maximum value of unsigned long long not defined!" # endif # endif # define MP_DIGIT_MAX (UINT_MAX * 1ULL) # define MP_WORD_MAX ULONG_LONG_MAX #else /* USE_LONG_LONG */ # define MP_DIGIT_MAX (USHRT_MAX * 1UL) -# define MP_WORD_MAX (UINT_MAX * 1UL) +# define MP_WORD_MAX (UINT_MAX * 1UL) #endif /* USE_LONG_LONG */ #endif /* USE_C99 */ @@ -122,174 +122,174 @@ extern const mp_result MP_MINERR; /* Values with fewer than this many significant digits use the standard multiplication algorithm; otherwise, a recursive algorithm is used. Choose a value to suit your platform. - */ +*/ #define MP_MULT_THRESH 22 #define MP_DEFAULT_PREC 8 /* default memory allocation, in digits */ -extern const mp_sign MP_NEG; -extern const mp_sign MP_ZPOS; + extern const mp_sign MP_NEG; + extern const mp_sign MP_ZPOS; #define mp_int_is_odd(Z) ((Z)->digits[0] & 1) #define mp_int_is_even(Z) !((Z)->digits[0] & 1) /* NOTE: this doesn't use the allocator */ -mp_result mp_int_init(mp_int z); -mp_int mp_int_alloc(klisp_State *K); -mp_result mp_int_init_size(klisp_State *K, mp_int z, mp_size prec); -mp_result mp_int_init_copy(klisp_State *K, mp_int z, mp_int old); -mp_result mp_int_init_value(klisp_State *K, mp_int z, mp_small value); -mp_result mp_int_set_value(klisp_State *K, mp_int z, mp_small value); -void mp_int_clear(klisp_State *K, mp_int z); -void mp_int_free(klisp_State *K, mp_int z); - -mp_result mp_int_copy(klisp_State *K, mp_int a, mp_int c); /* c = a */ + mp_result mp_int_init(mp_int z); + mp_int mp_int_alloc(klisp_State *K); + mp_result mp_int_init_size(klisp_State *K, mp_int z, mp_size prec); + mp_result mp_int_init_copy(klisp_State *K, mp_int z, mp_int old); + mp_result mp_int_init_value(klisp_State *K, mp_int z, mp_small value); + mp_result mp_int_set_value(klisp_State *K, mp_int z, mp_small value); + void mp_int_clear(klisp_State *K, mp_int z); + void mp_int_free(klisp_State *K, mp_int z); + + mp_result mp_int_copy(klisp_State *K, mp_int a, mp_int c); /* c = a */ /* NOTE: this doesn't use the allocator */ -void mp_int_swap(mp_int a, mp_int c); /* swap a, c */ + void mp_int_swap(mp_int a, mp_int c); /* swap a, c */ /* NOTE: this doesn't use the allocator */ -void mp_int_zero(mp_int z); /* z = 0 */ -mp_result mp_int_abs(klisp_State *K, mp_int a, mp_int c); /* c = |a| */ -mp_result mp_int_neg(klisp_State *K, mp_int a, mp_int c); /* c = -a */ + void mp_int_zero(mp_int z); /* z = 0 */ + mp_result mp_int_abs(klisp_State *K, mp_int a, mp_int c); /* c = |a| */ + mp_result mp_int_neg(klisp_State *K, mp_int a, mp_int c); /* c = -a */ /* c = a + b */ -mp_result mp_int_add(klisp_State *K, mp_int a, mp_int b, mp_int c); -mp_result mp_int_add_value(klisp_State *K, mp_int a, mp_small value, - mp_int c); + mp_result mp_int_add(klisp_State *K, mp_int a, mp_int b, mp_int c); + mp_result mp_int_add_value(klisp_State *K, mp_int a, mp_small value, + mp_int c); /* c = a - b */ -mp_result mp_int_sub(klisp_State *K, mp_int a, mp_int b, mp_int c); -mp_result mp_int_sub_value(klisp_State *K, mp_int a, mp_small value, - mp_int c); + mp_result mp_int_sub(klisp_State *K, mp_int a, mp_int b, mp_int c); + mp_result mp_int_sub_value(klisp_State *K, mp_int a, mp_small value, + mp_int c); /* c = a * b */ -mp_result mp_int_mul(klisp_State *K, mp_int a, mp_int b, mp_int c); -mp_result mp_int_mul_value(klisp_State *K, mp_int a, mp_small value, - mp_int c); -mp_result mp_int_mul_pow2(klisp_State *K, mp_int a, mp_small p2, mp_int c); -mp_result mp_int_sqr(klisp_State *K, mp_int a, mp_int c); /* c = a * a */ + mp_result mp_int_mul(klisp_State *K, mp_int a, mp_int b, mp_int c); + mp_result mp_int_mul_value(klisp_State *K, mp_int a, mp_small value, + mp_int c); + mp_result mp_int_mul_pow2(klisp_State *K, mp_int a, mp_small p2, mp_int c); + mp_result mp_int_sqr(klisp_State *K, mp_int a, mp_int c); /* c = a * a */ /* q = a / b */ /* r = a % b */ -mp_result mp_int_div(klisp_State *K, mp_int a, mp_int b, mp_int q, - mp_int r); + mp_result mp_int_div(klisp_State *K, mp_int a, mp_int b, mp_int q, + mp_int r); /* q = a / value */ /* r = a % value */ -mp_result mp_int_div_value(klisp_State *K, mp_int a, mp_small value, - mp_int q, mp_small *r); + mp_result mp_int_div_value(klisp_State *K, mp_int a, mp_small value, + mp_int q, mp_small *r); /* q = a / 2^p2 */ /* r = q % 2^p2 */ -mp_result mp_int_div_pow2(klisp_State *K, mp_int a, mp_small p2, - mp_int q, mp_int r); + mp_result mp_int_div_pow2(klisp_State *K, mp_int a, mp_small p2, + mp_int q, mp_int r); /* c = a % m */ -mp_result mp_int_mod(klisp_State *K, mp_int a, mp_int m, mp_int c); -#define mp_int_mod_value(K, A, V, R) \ + mp_result mp_int_mod(klisp_State *K, mp_int a, mp_int m, mp_int c); +#define mp_int_mod_value(K, A, V, R) \ mp_int_div_value((K), (A), (V), 0, (R)) /* c = a^b */ -mp_result mp_int_expt(klisp_State *K, mp_int a, mp_small b, mp_int c); + mp_result mp_int_expt(klisp_State *K, mp_int a, mp_small b, mp_int c); /* c = a^b */ -mp_result mp_int_expt_value(klisp_State *K, mp_small a, mp_small b, mp_int c); + mp_result mp_int_expt_value(klisp_State *K, mp_small a, mp_small b, mp_int c); /* c = a^b */ -mp_result mp_int_expt_full(klisp_State *K, mp_int a, mp_int b, mp_int c); + mp_result mp_int_expt_full(klisp_State *K, mp_int a, mp_int b, mp_int c); /* NOTE: this doesn't use the allocator */ -int mp_int_compare(mp_int a, mp_int b); /* a <=> b */ + int mp_int_compare(mp_int a, mp_int b); /* a <=> b */ /* NOTE: this doesn't use the allocator */ -int mp_int_compare_unsigned(mp_int a, mp_int b); /* |a| <=> |b| */ + int mp_int_compare_unsigned(mp_int a, mp_int b); /* |a| <=> |b| */ /* NOTE: this doesn't use the allocator */ -int mp_int_compare_zero(mp_int z); /* a <=> 0 */ + int mp_int_compare_zero(mp_int z); /* a <=> 0 */ /* NOTE: this doesn't use the allocator */ -int mp_int_compare_value(mp_int z, mp_small value); /* a <=> v */ + int mp_int_compare_value(mp_int z, mp_small value); /* a <=> v */ /* Returns true if v|a, false otherwise (including errors) */ -int mp_int_divisible_value(klisp_State *K, mp_int a, mp_small v); + int mp_int_divisible_value(klisp_State *K, mp_int a, mp_small v); /* NOTE: this doesn't use the allocator */ /* Returns k >= 0 such that z = 2^k, if one exists; otherwise < 0 */ -int mp_int_is_pow2(mp_int z); - -mp_result mp_int_exptmod(klisp_State *K, mp_int a, mp_int b, mp_int m, - mp_int c); /* c = a^b (mod m) */ -mp_result mp_int_exptmod_evalue(klisp_State *K, mp_int a, mp_small value, - mp_int m, mp_int c); /* c = a^v (mod m) */ -mp_result mp_int_exptmod_bvalue(klisp_State *K, mp_small value, mp_int b, - mp_int m, mp_int c); /* c = v^b (mod m) */ -mp_result mp_int_exptmod_known(klisp_State *K, mp_int a, mp_int b, - mp_int m, mp_int mu, - mp_int c); /* c = a^b (mod m) */ -mp_result mp_int_redux_const(klisp_State *K, mp_int m, mp_int c); + int mp_int_is_pow2(mp_int z); + + mp_result mp_int_exptmod(klisp_State *K, mp_int a, mp_int b, mp_int m, + mp_int c); /* c = a^b (mod m) */ + mp_result mp_int_exptmod_evalue(klisp_State *K, mp_int a, mp_small value, + mp_int m, mp_int c); /* c = a^v (mod m) */ + mp_result mp_int_exptmod_bvalue(klisp_State *K, mp_small value, mp_int b, + mp_int m, mp_int c); /* c = v^b (mod m) */ + mp_result mp_int_exptmod_known(klisp_State *K, mp_int a, mp_int b, + mp_int m, mp_int mu, + mp_int c); /* c = a^b (mod m) */ + mp_result mp_int_redux_const(klisp_State *K, mp_int m, mp_int c); /* c = 1/a (mod m) */ -mp_result mp_int_invmod(klisp_State *K, mp_int a, mp_int m, mp_int c); + mp_result mp_int_invmod(klisp_State *K, mp_int a, mp_int m, mp_int c); /* c = gcd(a, b) */ -mp_result mp_int_gcd(klisp_State *K, mp_int a, mp_int b, mp_int c); + mp_result mp_int_gcd(klisp_State *K, mp_int a, mp_int b, mp_int c); /* c = gcd(a, b) */ -/* c = ax + by */ -mp_result mp_int_egcd(klisp_State *K, mp_int a, mp_int b, mp_int c, - mp_int x, mp_int y); +/* c = ax + by */ + mp_result mp_int_egcd(klisp_State *K, mp_int a, mp_int b, mp_int c, + mp_int x, mp_int y); /* c = lcm(a, b) */ -mp_result mp_int_lcm(klisp_State *K, mp_int a, mp_int b, mp_int c); + mp_result mp_int_lcm(klisp_State *K, mp_int a, mp_int b, mp_int c); /* c = floor(a^{1/b}) */ -mp_result mp_int_root(klisp_State *K, mp_int a, mp_small b, mp_int c); + mp_result mp_int_root(klisp_State *K, mp_int a, mp_small b, mp_int c); /* c = floor(sqrt(a)) */ -#define mp_int_sqrt(K, a, c) mp_int_root((K), a, 2, c) +#define mp_int_sqrt(K, a, c) mp_int_root((K), a, 2, c) /* Convert to a small int, if representable; else MP_RANGE */ /* NOTE: this doesn't use the allocator */ -mp_result mp_int_to_int(mp_int z, mp_small *out); + mp_result mp_int_to_int(mp_int z, mp_small *out); /* NOTE: this doesn't use the allocator */ -mp_result mp_int_to_uint(mp_int z, mp_usmall *out); + mp_result mp_int_to_uint(mp_int z, mp_usmall *out); /* Convert to nul-terminated string with the specified radix, writing at most limit characters including the nul terminator */ -mp_result mp_int_to_string(klisp_State *K, mp_int z, mp_size radix, - char *str, int limit); + mp_result mp_int_to_string(klisp_State *K, mp_int z, mp_size radix, + char *str, int limit); /* Return the number of characters required to represent z in the given radix. May over-estimate. */ /* NOTE: this doesn't use the allocator */ -mp_result mp_int_string_len(mp_int z, mp_size radix); + mp_result mp_int_string_len(mp_int z, mp_size radix); /* Read zero-terminated string into z */ -mp_result mp_int_read_string(klisp_State *K, mp_int z, mp_size radix, - const char *str); -mp_result mp_int_read_cstring(klisp_State *K, mp_int z, mp_size radix, - const char *str, char **end); + mp_result mp_int_read_string(klisp_State *K, mp_int z, mp_size radix, + const char *str); + mp_result mp_int_read_cstring(klisp_State *K, mp_int z, mp_size radix, + const char *str, char **end); /* Return the number of significant bits in z */ /* NOTE: this doesn't use the allocator */ -mp_result mp_int_count_bits(mp_int z); + mp_result mp_int_count_bits(mp_int z); /* Convert z to two's complement binary, writing at most limit bytes */ -mp_result mp_int_to_binary(klisp_State *K, mp_int z, unsigned char *buf, - int limit); + mp_result mp_int_to_binary(klisp_State *K, mp_int z, unsigned char *buf, + int limit); /* Read a two's complement binary value into z from the given buffer */ -mp_result mp_int_read_binary(klisp_State *K, mp_int z, unsigned char *buf, - int len); + mp_result mp_int_read_binary(klisp_State *K, mp_int z, unsigned char *buf, + int len); /* Return the number of bytes required to represent z in binary. */ /* NOTE: this doesn't use the allocator */ -mp_result mp_int_binary_len(mp_int z); + mp_result mp_int_binary_len(mp_int z); /* Convert z to unsigned binary, writing at most limit bytes */ -mp_result mp_int_to_unsigned(klisp_State *K, mp_int z, unsigned char *buf, - int limit); + mp_result mp_int_to_unsigned(klisp_State *K, mp_int z, unsigned char *buf, + int limit); /* Read an unsigned binary value into z from the given buffer */ -mp_result mp_int_read_unsigned(klisp_State *K, mp_int z, unsigned char *buf, - int len); + mp_result mp_int_read_unsigned(klisp_State *K, mp_int z, unsigned char *buf, + int len); /* Return the number of bytes required to represent z as unsigned output */ /* NOTE: this doesn't use the allocator */ -mp_result mp_int_unsigned_len(mp_int z); + mp_result mp_int_unsigned_len(mp_int z); /* Return a statically allocated string describing error code res */ /* NOTE: this doesn't use the allocator */ -const char *mp_error_string(mp_result res); + const char *mp_error_string(mp_result res); #if DEBUG -void s_print(char *tag, mp_int z); -void s_print_buf(char *tag, mp_digit *buf, mp_size num); + void s_print(char *tag, mp_int z); + void s_print_buf(char *tag, mp_digit *buf, mp_size num); #endif #ifdef __cplusplus diff --git a/src/imrat.c b/src/imrat.c @@ -26,7 +26,7 @@ /* {{{ Useful macros */ #define TEMP(K) (temp + (K)) -#define SETUP(E, C) \ +#define SETUP(E, C) \ do{if((res = (E)) != MP_OK) goto CLEANUP; ++(C);}while(0) /* Argument checking: @@ -43,8 +43,8 @@ static mp_result s_rat_reduce(klisp_State *K, mp_rat r); /* Common code for addition and subtraction operations on rationals. */ static mp_result s_rat_combine(klisp_State *K, mp_rat a, mp_rat b, mp_rat c, - mp_result (*comb_f) - (klisp_State *,mp_int, mp_int, mp_int)); + mp_result (*comb_f) + (klisp_State *,mp_int, mp_int, mp_int)); /* {{{ mp_rat_init(r) */ @@ -62,10 +62,10 @@ mp_rat mp_rat_alloc(klisp_State *K) mp_rat out = klispM_new(K, mpq_t); if(out != NULL) { - if(mp_rat_init(K, out) != MP_OK) { - klispM_free(K, out); - return NULL; - } + if(mp_rat_init(K, out) != MP_OK) { + klispM_free(K, out); + return NULL; + } } return out; @@ -76,15 +76,15 @@ mp_rat mp_rat_alloc(klisp_State *K) /* {{{ mp_rat_init_size(r, n_prec, d_prec) */ mp_result mp_rat_init_size(klisp_State *K, mp_rat r, mp_size n_prec, - mp_size d_prec) + mp_size d_prec) { mp_result res; if((res = mp_int_init_size(K, MP_NUMER_P(r), n_prec)) != MP_OK) - return res; + return res; if((res = mp_int_init_size(K, MP_DENOM_P(r), d_prec)) != MP_OK) { - mp_int_clear(K, MP_NUMER_P(r)); - return res; + mp_int_clear(K, MP_NUMER_P(r)); + return res; } return mp_int_set_value(K, MP_DENOM_P(r), 1); @@ -99,9 +99,9 @@ mp_result mp_rat_init_copy(klisp_State *K, mp_rat r, mp_rat old) mp_result res; if((res = mp_int_init_copy(K, MP_NUMER_P(r), MP_NUMER_P(old))) != MP_OK) - return res; + return res; if((res = mp_int_init_copy(K, MP_DENOM_P(r), MP_DENOM_P(old))) != MP_OK) - mp_int_clear(K, MP_NUMER_P(r)); + mp_int_clear(K, MP_NUMER_P(r)); return res; } @@ -115,12 +115,12 @@ mp_result mp_rat_set_value(klisp_State *K, mp_rat r, int numer, int denom) mp_result res; if(denom == 0) - return MP_UNDEF; + return MP_UNDEF; if((res = mp_int_set_value(K, MP_NUMER_P(r), numer)) != MP_OK) - return res; + return res; if((res = mp_int_set_value(K, MP_DENOM_P(r), denom)) != MP_OK) - return res; + return res; return s_rat_reduce(K, r); } @@ -129,7 +129,7 @@ mp_result mp_rat_set_value(klisp_State *K, mp_rat r, int numer, int denom) /* {{{ mp_rat_clear(r) */ -void mp_rat_clear(klisp_State *K, mp_rat r) +void mp_rat_clear(klisp_State *K, mp_rat r) { mp_int_clear(K, MP_NUMER_P(r)); mp_int_clear(K, MP_DENOM_P(r)); @@ -139,14 +139,14 @@ void mp_rat_clear(klisp_State *K, mp_rat r) /* {{{ mp_rat_free(r) */ -void mp_rat_free(klisp_State *K, mp_rat r) +void mp_rat_free(klisp_State *K, mp_rat r) { NRCHECK(r != NULL); if(r->num.digits != NULL) - mp_rat_clear(K, r); + mp_rat_clear(K, r); - klispM_free(K, r); + klispM_free(K, r); } /* }}} */ @@ -185,7 +185,7 @@ mp_result mp_rat_copy(klisp_State *K, mp_rat a, mp_rat c) mp_result res; if((res = mp_int_copy(K, MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK) - return res; + return res; res = mp_int_copy(K, MP_DENOM_P(a), MP_DENOM_P(c)); return res; @@ -195,7 +195,7 @@ mp_result mp_rat_copy(klisp_State *K, mp_rat a, mp_rat c) /* {{{ mp_rat_zero(r) */ -void mp_rat_zero(klisp_State *K, mp_rat r) +void mp_rat_zero(klisp_State *K, mp_rat r) { mp_int_zero(MP_NUMER_P(r)); mp_int_set_value(K, MP_DENOM_P(r), 1); @@ -210,7 +210,7 @@ mp_result mp_rat_abs(klisp_State *K, mp_rat a, mp_rat c) mp_result res; if((res = mp_int_abs(K, MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK) - return res; + return res; res = mp_int_abs(K, MP_DENOM_P(a), MP_DENOM_P(c)); return res; @@ -225,8 +225,8 @@ mp_result mp_rat_neg(klisp_State *K, mp_rat a, mp_rat c) mp_result res; if((res = mp_int_neg(K, MP_NUMER_P(a), - MP_NUMER_P(c))) != MP_OK) - return res; + MP_NUMER_P(c))) != MP_OK) + return res; res = mp_int_copy(K, MP_DENOM_P(a), MP_DENOM_P(c)); return res; @@ -241,19 +241,19 @@ mp_result mp_rat_recip(klisp_State *K, mp_rat a, mp_rat c) mp_result res; if(mp_rat_compare_zero(a) == 0) - return MP_UNDEF; + return MP_UNDEF; if((res = mp_rat_copy(K, a, c)) != MP_OK) - return res; + return res; mp_int_swap(MP_NUMER_P(c), MP_DENOM_P(c)); /* Restore the signs of the swapped elements */ { - mp_sign tmp = MP_SIGN(MP_NUMER_P(c)); + mp_sign tmp = MP_SIGN(MP_NUMER_P(c)); - MP_SIGN(MP_NUMER_P(c)) = MP_SIGN(MP_DENOM_P(c)); - MP_SIGN(MP_DENOM_P(c)) = tmp; + MP_SIGN(MP_NUMER_P(c)) = MP_SIGN(MP_DENOM_P(c)); + MP_SIGN(MP_DENOM_P(c)) = tmp; } return MP_OK; @@ -288,13 +288,13 @@ mp_result mp_rat_mul(klisp_State *K, mp_rat a, mp_rat b, mp_rat c) mp_result res; if((res = mp_int_mul(K, MP_NUMER_P(a), MP_NUMER_P(b), - MP_NUMER_P(c))) != MP_OK) - return res; + MP_NUMER_P(c))) != MP_OK) + return res; if(mp_int_compare_zero(MP_NUMER_P(c)) != 0) { - if((res = mp_int_mul(K, MP_DENOM_P(a), MP_DENOM_P(b), - MP_DENOM_P(c))) != MP_OK) - return res; + if((res = mp_int_mul(K, MP_DENOM_P(a), MP_DENOM_P(b), + MP_DENOM_P(c))) != MP_OK) + return res; } return s_rat_reduce(K, c); @@ -309,35 +309,35 @@ mp_result mp_rat_div(klisp_State *K, mp_rat a, mp_rat b, mp_rat c) mp_result res = MP_OK; if(mp_rat_compare_zero(b) == 0) - return MP_UNDEF; + return MP_UNDEF; if(c == a || c == b) { - mpz_t tmp; + mpz_t tmp; - if((res = mp_int_init(&tmp)) != MP_OK) return res; - if((res = mp_int_mul(K, MP_NUMER_P(a), MP_DENOM_P(b), &tmp)) != MP_OK) - goto CLEANUP; - if((res = mp_int_mul(K, MP_DENOM_P(a), MP_NUMER_P(b), - MP_DENOM_P(c))) != MP_OK) - goto CLEANUP; - res = mp_int_copy(K, &tmp, MP_NUMER_P(c)); + if((res = mp_int_init(&tmp)) != MP_OK) return res; + if((res = mp_int_mul(K, MP_NUMER_P(a), MP_DENOM_P(b), &tmp)) != MP_OK) + goto CLEANUP; + if((res = mp_int_mul(K, MP_DENOM_P(a), MP_NUMER_P(b), + MP_DENOM_P(c))) != MP_OK) + goto CLEANUP; + res = mp_int_copy(K, &tmp, MP_NUMER_P(c)); CLEANUP: - mp_int_clear(K, &tmp); + mp_int_clear(K, &tmp); } else { - if((res = mp_int_mul(K, MP_NUMER_P(a), MP_DENOM_P(b), - MP_NUMER_P(c))) != MP_OK) - return res; - if((res = mp_int_mul(K, MP_DENOM_P(a), MP_NUMER_P(b), - MP_DENOM_P(c))) != MP_OK) - return res; + if((res = mp_int_mul(K, MP_NUMER_P(a), MP_DENOM_P(b), + MP_NUMER_P(c))) != MP_OK) + return res; + if((res = mp_int_mul(K, MP_DENOM_P(a), MP_NUMER_P(b), + MP_DENOM_P(c))) != MP_OK) + return res; } if(res != MP_OK) - return res; + return res; else - return s_rat_reduce(K, c); + return s_rat_reduce(K, c); } /* }}} */ @@ -350,16 +350,16 @@ mp_result mp_rat_add_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c) mp_result res; if((res = mp_int_init_copy(K, &tmp, b)) != MP_OK) - return res; + return res; if((res = mp_int_mul(K, &tmp, MP_DENOM_P(a), &tmp)) != MP_OK) - goto CLEANUP; + goto CLEANUP; if((res = mp_rat_copy(K, a, c)) != MP_OK) - goto CLEANUP; + goto CLEANUP; if((res = mp_int_add(K, MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK) - goto CLEANUP; + goto CLEANUP; res = s_rat_reduce(K, c); @@ -378,16 +378,16 @@ mp_result mp_rat_sub_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c) mp_result res; if((res = mp_int_init_copy(K, &tmp, b)) != MP_OK) - return res; + return res; if((res = mp_int_mul(K, &tmp, MP_DENOM_P(a), &tmp)) != MP_OK) - goto CLEANUP; + goto CLEANUP; if((res = mp_rat_copy(K, a, c)) != MP_OK) - goto CLEANUP; + goto CLEANUP; if((res = mp_int_sub(K, MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK) - goto CLEANUP; + goto CLEANUP; res = s_rat_reduce(K, c); @@ -405,10 +405,10 @@ mp_result mp_rat_mul_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c) mp_result res; if((res = mp_rat_copy(K, a, c)) != MP_OK) - return res; + return res; if((res = mp_int_mul(K, MP_NUMER_P(c), b, MP_NUMER_P(c))) != MP_OK) - return res; + return res; return s_rat_reduce(K, c); } @@ -422,13 +422,13 @@ mp_result mp_rat_div_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c) mp_result res; if(mp_int_compare_zero(b) == 0) - return MP_UNDEF; + return MP_UNDEF; if((res = mp_rat_copy(K, a, c)) != MP_OK) - return res; + return res; if((res = mp_int_mul(K, MP_DENOM_P(c), b, MP_DENOM_P(c))) != MP_OK) - return res; + return res; return s_rat_reduce(K, c); } @@ -443,14 +443,14 @@ mp_result mp_rat_expt(klisp_State *K, mp_rat a, mp_small b, mp_rat c) /* Special cases for easy powers. */ if(b == 0) - return mp_rat_set_value(K, c, 1, 1); + return mp_rat_set_value(K, c, 1, 1); else if(b == 1) - return mp_rat_copy(K, a, c); + return mp_rat_copy(K, a, c); /* Since rationals are always stored in lowest terms, it is not necessary to reduce again when raising to an integer power. */ if((res = mp_int_expt(K, MP_NUMER_P(a), b, MP_NUMER_P(c))) != MP_OK) - return res; + return res; return mp_int_expt(K, MP_DENOM_P(a), b, MP_DENOM_P(c)); } @@ -459,25 +459,25 @@ mp_result mp_rat_expt(klisp_State *K, mp_rat a, mp_small b, mp_rat c) /* {{{ mp_rat_compare(a, b) */ -int mp_rat_compare(klisp_State *K, mp_rat a, mp_rat b) +int mp_rat_compare(klisp_State *K, mp_rat a, mp_rat b) { /* Quick check for opposite signs. Works because the sign of the numerator is always definitive. */ if(MP_SIGN(MP_NUMER_P(a)) != MP_SIGN(MP_NUMER_P(b))) { - if(MP_SIGN(MP_NUMER_P(a)) == MP_ZPOS) - return 1; - else - return -1; + if(MP_SIGN(MP_NUMER_P(a)) == MP_ZPOS) + return 1; + else + return -1; } else { - /* Compare absolute magnitudes; if both are positive, the answer - stands, otherwise it needs to be reflected about zero. */ - int cmp = mp_rat_compare_unsigned(K, a, b); - - if(MP_SIGN(MP_NUMER_P(a)) == MP_ZPOS) - return cmp; - else - return -cmp; + /* Compare absolute magnitudes; if both are positive, the answer + stands, otherwise it needs to be reflected about zero. */ + int cmp = mp_rat_compare_unsigned(K, a, b); + + if(MP_SIGN(MP_NUMER_P(a)) == MP_ZPOS) + return cmp; + else + return -cmp; } } @@ -485,33 +485,33 @@ int mp_rat_compare(klisp_State *K, mp_rat a, mp_rat b) /* {{{ mp_rat_compare_unsigned(a, b) */ -int mp_rat_compare_unsigned(klisp_State *K, mp_rat a, mp_rat b) +int mp_rat_compare_unsigned(klisp_State *K, mp_rat a, mp_rat b) { /* If the denominators are equal, we can quickly compare numerators without multiplying. Otherwise, we actually have to do some work. */ if(mp_int_compare_unsigned(MP_DENOM_P(a), MP_DENOM_P(b)) == 0) - return mp_int_compare_unsigned(MP_NUMER_P(a), MP_NUMER_P(b)); + return mp_int_compare_unsigned(MP_NUMER_P(a), MP_NUMER_P(b)); else { - mpz_t temp[2]; - mp_result res; - int cmp = INT_MAX, last = 0; + mpz_t temp[2]; + mp_result res; + int cmp = INT_MAX, last = 0; - /* t0 = num(a) * den(b), t1 = num(b) * den(a) */ - SETUP(mp_int_init_copy(K, TEMP(last), MP_NUMER_P(a)), last); - SETUP(mp_int_init_copy(K, TEMP(last), MP_NUMER_P(b)), last); + /* t0 = num(a) * den(b), t1 = num(b) * den(a) */ + SETUP(mp_int_init_copy(K, TEMP(last), MP_NUMER_P(a)), last); + SETUP(mp_int_init_copy(K, TEMP(last), MP_NUMER_P(b)), last); - if((res = mp_int_mul(K, TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK || - (res = mp_int_mul(K, TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK) - goto CLEANUP; + if((res = mp_int_mul(K, TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK || + (res = mp_int_mul(K, TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK) + goto CLEANUP; - cmp = mp_int_compare_unsigned(TEMP(0), TEMP(1)); + cmp = mp_int_compare_unsigned(TEMP(0), TEMP(1)); CLEANUP: - while(--last >= 0) - mp_int_clear(K, TEMP(last)); + while(--last >= 0) + mp_int_clear(K, TEMP(last)); - return cmp; + return cmp; } } @@ -519,7 +519,7 @@ int mp_rat_compare_unsigned(klisp_State *K, mp_rat a, mp_rat b) /* {{{ mp_rat_compare_zero(r) */ -int mp_rat_compare_zero(mp_rat r) +int mp_rat_compare_zero(mp_rat r) { return mp_int_compare_zero(MP_NUMER_P(r)); @@ -536,9 +536,9 @@ int mp_rat_compare_value(klisp_State *K, mp_rat r, mp_small n, mp_small d) int out = INT_MAX; if((res = mp_rat_init(K, &tmp)) != MP_OK) - return out; + return out; if((res = mp_rat_set_value(K, &tmp, n, d)) != MP_OK) - goto CLEANUP; + goto CLEANUP; out = mp_rat_compare(K, r, &tmp); @@ -551,7 +551,7 @@ CLEANUP: /* {{{ mp_rat_is_integer(r) */ -int mp_rat_is_integer(mp_rat r) +int mp_rat_is_integer(mp_rat r) { return (mp_int_compare_value(MP_DENOM_P(r), 1) == 0); } @@ -565,7 +565,7 @@ mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den) mp_result res; if((res = mp_int_to_int(MP_NUMER_P(r), num)) != MP_OK) - return res; + return res; res = mp_int_to_int(MP_DENOM_P(r), den); return res; @@ -576,7 +576,7 @@ mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den) /* {{{ mp_rat_to_string(r, radix, *str, limit) */ mp_result mp_rat_to_string(klisp_State *K, mp_rat r, mp_size radix, char *str, - int limit) + int limit) { char *start; int len; @@ -585,11 +585,11 @@ mp_result mp_rat_to_string(klisp_State *K, mp_rat r, mp_size radix, char *str, /* Write the numerator. The sign of the rational number is written by the underlying integer implementation. */ if((res = mp_int_to_string(K, MP_NUMER_P(r), radix, str, limit)) != MP_OK) - return res; + return res; /* If the value is zero, don't bother writing any denominator */ if(mp_int_compare_zero(MP_NUMER_P(r)) == 0) - return MP_OK; + return MP_OK; /* Locate the end of the numerator, and make sure we are not going to exceed the limit by writing a slash. */ @@ -597,7 +597,7 @@ mp_result mp_rat_to_string(klisp_State *K, mp_rat r, mp_size radix, char *str, start = str + len; limit -= len; if(limit == 0) - return MP_TRUNC; + return MP_TRUNC; *start++ = '/'; limit -= 1; @@ -610,8 +610,8 @@ mp_result mp_rat_to_string(klisp_State *K, mp_rat r, mp_size radix, char *str, /* {{{ mp_rat_to_decimal(r, radix, prec, *str, limit) */ mp_result mp_rat_to_decimal(klisp_State *K, mp_rat r, mp_size radix, - mp_size prec, mp_round_mode round, char *str, - int limit) + mp_size prec, mp_round_mode round, char *str, + int limit) { mpz_t temp[3]; mp_result res; @@ -626,31 +626,31 @@ mp_result mp_rat_to_decimal(klisp_State *K, mp_rat r, mp_size radix, absolute value of the numerator. */ mp_int_abs(K, TEMP(0), TEMP(0)); if((res = mp_int_div(K, TEMP(0), MP_DENOM_P(r), TEMP(0), - TEMP(1))) != MP_OK) - goto CLEANUP; + TEMP(1))) != MP_OK) + goto CLEANUP; /* Now: T0 = integer portion, unsigned; T1 = remainder, from which fractional part is computed. */ /* Count up leading zeroes after the radix point. */ for(lead_0 = 0; lead_0 < prec && mp_int_compare(TEMP(1), MP_DENOM_P(r)) < 0; - ++lead_0) { - if((res = mp_int_mul_value(K, TEMP(1), radix, TEMP(1))) != MP_OK) - goto CLEANUP; + ++lead_0) { + if((res = mp_int_mul_value(K, TEMP(1), radix, TEMP(1))) != MP_OK) + goto CLEANUP; } /* Multiply remainder by a power of the radix sufficient to get the right number of significant figures. */ if(prec > lead_0) { - if((res = mp_int_expt_value(K, radix, prec - lead_0, - TEMP(2))) != MP_OK) - goto CLEANUP; - if((res = mp_int_mul(K, TEMP(1), TEMP(2), TEMP(1))) != MP_OK) - goto CLEANUP; + if((res = mp_int_expt_value(K, radix, prec - lead_0, + TEMP(2))) != MP_OK) + goto CLEANUP; + if((res = mp_int_mul(K, TEMP(1), TEMP(2), TEMP(1))) != MP_OK) + goto CLEANUP; } if((res = mp_int_div(K, TEMP(1), MP_DENOM_P(r), TEMP(1), - TEMP(2))) != MP_OK) - goto CLEANUP; + TEMP(2))) != MP_OK) + goto CLEANUP; /* Now: T1 = significant digits of fractional part; T2 = leftovers, to use for rounding. @@ -660,40 +660,40 @@ mp_result mp_rat_to_decimal(klisp_State *K, mp_rat r, mp_size radix, already. */ switch(round) { - int cmp; + int cmp; case MP_ROUND_UP: - if(mp_int_compare_zero(TEMP(2)) != 0) { - if(prec == 0) - res = mp_int_add_value(K, TEMP(0), 1, TEMP(0)); - else - res = mp_int_add_value(K, TEMP(1), 1, TEMP(1)); - } - break; + if(mp_int_compare_zero(TEMP(2)) != 0) { + if(prec == 0) + res = mp_int_add_value(K, TEMP(0), 1, TEMP(0)); + else + res = mp_int_add_value(K, TEMP(1), 1, TEMP(1)); + } + break; case MP_ROUND_HALF_UP: case MP_ROUND_HALF_DOWN: - if((res = mp_int_mul_pow2(K, TEMP(2), 1, TEMP(2))) != MP_OK) - goto CLEANUP; + if((res = mp_int_mul_pow2(K, TEMP(2), 1, TEMP(2))) != MP_OK) + goto CLEANUP; - cmp = mp_int_compare(TEMP(2), MP_DENOM_P(r)); + cmp = mp_int_compare(TEMP(2), MP_DENOM_P(r)); - if(round == MP_ROUND_HALF_UP) - cmp += 1; + if(round == MP_ROUND_HALF_UP) + cmp += 1; - if(cmp > 0) { - if(prec == 0) - res = mp_int_add_value(K, TEMP(0), 1, TEMP(0)); - else - res = mp_int_add_value(K, TEMP(1), 1, TEMP(1)); - } - break; + if(cmp > 0) { + if(prec == 0) + res = mp_int_add_value(K, TEMP(0), 1, TEMP(0)); + else + res = mp_int_add_value(K, TEMP(1), 1, TEMP(1)); + } + break; case MP_ROUND_DOWN: - break; /* No action required */ + break; /* No action required */ default: - return MP_BADARG; /* Invalid rounding specifier */ + return MP_BADARG; /* Invalid rounding specifier */ } /* The sign of the output should be the sign of the numerator, but @@ -701,27 +701,27 @@ mp_result mp_rat_to_decimal(klisp_State *K, mp_rat r, mp_size radix, negative shouldn't be shown. */ if(MP_SIGN(MP_NUMER_P(r)) == MP_NEG && (mp_int_compare_zero(TEMP(0)) != 0 || - mp_int_compare_zero(TEMP(1)) != 0)) { - *start++ = '-'; - left -= 1; + mp_int_compare_zero(TEMP(1)) != 0)) { + *start++ = '-'; + left -= 1; } if((res = mp_int_to_string(K, TEMP(0), radix, start, left)) != MP_OK) - goto CLEANUP; + goto CLEANUP; len = strlen(start); start += len; left -= len; if(prec == 0) - goto CLEANUP; + goto CLEANUP; *start++ = '.'; left -= 1; if(left < prec + 1) { - res = MP_TRUNC; - goto CLEANUP; + res = MP_TRUNC; + goto CLEANUP; } memset(start, '0', lead_0 - 1); @@ -732,7 +732,7 @@ mp_result mp_rat_to_decimal(klisp_State *K, mp_rat r, mp_size radix, CLEANUP: while(--last >= 0) - mp_int_clear(K, TEMP(last)); + mp_int_clear(K, TEMP(last)); return res; } @@ -748,7 +748,7 @@ mp_result mp_rat_string_len(mp_rat r, mp_size radix) n_len = mp_int_string_len(MP_NUMER_P(r), radix); if(mp_int_compare_zero(MP_NUMER_P(r)) != 0) - d_len = mp_int_string_len(MP_DENOM_P(r), radix); + d_len = mp_int_string_len(MP_DENOM_P(r), radix); /* Though simplistic, this formula is correct. Space for the sign flag is included in n_len, and the space for the NUL that is @@ -770,9 +770,9 @@ mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec) z_len = mp_int_string_len(MP_NUMER_P(r), radix); if(prec == 0) - f_len = 1; /* terminator only */ + f_len = 1; /* terminator only */ else - f_len = 1 + prec + 1; /* decimal point, digits, terminator */ + f_len = 1 + prec + 1; /* decimal point, digits, terminator */ return z_len + f_len; } @@ -782,7 +782,7 @@ mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec) /* {{{ mp_rat_read_string(r, radix, *str) */ mp_result mp_rat_read_string(klisp_State *K, mp_rat r, mp_size radix, - const char *str) + const char *str) { return mp_rat_read_cstring(K, r, radix, str, NULL); } @@ -792,34 +792,34 @@ mp_result mp_rat_read_string(klisp_State *K, mp_rat r, mp_size radix, /* {{{ mp_rat_read_cstring(r, radix, *str, **end) */ mp_result mp_rat_read_cstring(klisp_State *K, mp_rat r, mp_size radix, - const char *str, char **end) + const char *str, char **end) { mp_result res; char *endp; if((res = mp_int_read_cstring(K, MP_NUMER_P(r), radix, str, - &endp)) != MP_OK && (res != MP_TRUNC)) - return res; + &endp)) != MP_OK && (res != MP_TRUNC)) + return res; /* Skip whitespace between numerator and (possible) separator */ while(isspace((unsigned char) *endp)) - ++endp; + ++endp; /* If there is no separator, we will stop reading at this point. */ if(*endp != '/') { - mp_int_set_value(K, MP_DENOM_P(r), 1); - if(end != NULL) - *end = endp; - return res; + mp_int_set_value(K, MP_DENOM_P(r), 1); + if(end != NULL) + *end = endp; + return res; } ++endp; /* skip separator */ if((res = mp_int_read_cstring(K, MP_DENOM_P(r), radix, endp, end)) != MP_OK) - return res; + return res; /* Make sure the value is well-defined */ if(mp_int_compare_zero(MP_DENOM_P(r)) == 0) - return MP_UNDEF; + return MP_UNDEF; /* Reduce to lowest terms */ return s_rat_reduce(K, r); @@ -835,25 +835,25 @@ mp_result mp_rat_read_cstring(klisp_State *K, mp_rat r, mp_size radix, This function will accept either a/b notation or decimal notation. */ mp_result mp_rat_read_ustring(klisp_State *K, mp_rat r, mp_size radix, - const char *str, char **end) + const char *str, char **end) { - char *endp; + char *endp; mp_result res; if(radix == 0) - radix = 10; /* default to decimal input */ + radix = 10; /* default to decimal input */ if((res = mp_rat_read_cstring(K, r, radix, str, &endp)) != MP_OK) { - if(res == MP_TRUNC) { - if(*endp == '.') - res = mp_rat_read_cdecimal(K, r, radix, str, &endp); - } - else - return res; + if(res == MP_TRUNC) { + if(*endp == '.') + res = mp_rat_read_cdecimal(K, r, radix, str, &endp); + } + else + return res; } if(end != NULL) - *end = endp; + *end = endp; return res; } @@ -863,7 +863,7 @@ mp_result mp_rat_read_ustring(klisp_State *K, mp_rat r, mp_size radix, /* {{{ mp_rat_read_decimal(r, radix, *str) */ mp_result mp_rat_read_decimal(klisp_State *K, mp_rat r, mp_size radix, - const char *str) + const char *str) { return mp_rat_read_cdecimal(K, r, radix, str, NULL); } @@ -873,34 +873,34 @@ mp_result mp_rat_read_decimal(klisp_State *K, mp_rat r, mp_size radix, /* {{{ mp_rat_read_cdecimal(r, radix, *str, **end) */ mp_result mp_rat_read_cdecimal(klisp_State *K, mp_rat r, mp_size radix, - const char *str, char **end) + const char *str, char **end) { mp_result res; mp_sign osign; char *endp; while(isspace((unsigned char) *str)) - ++str; + ++str; switch(*str) { case '-': - osign = MP_NEG; - break; + osign = MP_NEG; + break; default: - osign = MP_ZPOS; + osign = MP_ZPOS; } if((res = mp_int_read_cstring(K, MP_NUMER_P(r), radix, str, - &endp)) != MP_OK && (res != MP_TRUNC)) - return res; + &endp)) != MP_OK && (res != MP_TRUNC)) + return res; /* This needs to be here. */ (void) mp_int_set_value(K, MP_DENOM_P(r), 1); if(*endp != '.') { - if(end != NULL) - *end = endp; - return res; + if(end != NULL) + *end = endp; + return res; } /* If the character following the decimal point is whitespace or a @@ -914,92 +914,92 @@ mp_result mp_rat_read_cdecimal(klisp_State *K, mp_rat r, mp_size radix, */ ++endp; if(*endp == '\0') { - if(end != NULL) - *end = endp; - return MP_OK; + if(end != NULL) + *end = endp; + return MP_OK; } else if(isspace((unsigned char) *endp) || *endp == '-' || *endp == '+') { - return MP_TRUNC; + return MP_TRUNC; } else { - mpz_t frac; - mp_result save_res; - char *save = endp; - int num_lz = 0; - - /* Make a temporary to hold the part after the decimal point. */ - if((res = mp_int_init(&frac)) != MP_OK) - return res; + mpz_t frac; + mp_result save_res; + char *save = endp; + int num_lz = 0; + + /* Make a temporary to hold the part after the decimal point. */ + if((res = mp_int_init(&frac)) != MP_OK) + return res; - if((res = mp_int_read_cstring(K, &frac, radix, endp, &endp)) != MP_OK && - (res != MP_TRUNC)) - goto CLEANUP; + if((res = mp_int_read_cstring(K, &frac, radix, endp, &endp)) != MP_OK && + (res != MP_TRUNC)) + goto CLEANUP; - /* Save this response for later. */ - save_res = res; + /* Save this response for later. */ + save_res = res; - if(mp_int_compare_zero(&frac) == 0) - goto FINISHED; + if(mp_int_compare_zero(&frac) == 0) + goto FINISHED; - /* Discard trailing zeroes (somewhat inefficiently) */ - while(mp_int_divisible_value(K, &frac, radix)) - if((res = mp_int_div_value(K, &frac, radix, &frac, NULL)) != MP_OK) - goto CLEANUP; + /* Discard trailing zeroes (somewhat inefficiently) */ + while(mp_int_divisible_value(K, &frac, radix)) + if((res = mp_int_div_value(K, &frac, radix, &frac, NULL)) != MP_OK) + goto CLEANUP; - /* Count leading zeros after the decimal point */ - while(save[num_lz] == '0') - ++num_lz; - - /* Find the least power of the radix that is at least as large as - the significant value of the fractional part, ignoring leading - zeroes. */ - (void) mp_int_set_value(K, MP_DENOM_P(r), radix); + /* Count leading zeros after the decimal point */ + while(save[num_lz] == '0') + ++num_lz; + + /* Find the least power of the radix that is at least as large as + the significant value of the fractional part, ignoring leading + zeroes. */ + (void) mp_int_set_value(K, MP_DENOM_P(r), radix); - while(mp_int_compare(MP_DENOM_P(r), &frac) < 0) { - if((res = mp_int_mul_value(K, MP_DENOM_P(r), radix, - MP_DENOM_P(r))) != MP_OK) - goto CLEANUP; - } + while(mp_int_compare(MP_DENOM_P(r), &frac) < 0) { + if((res = mp_int_mul_value(K, MP_DENOM_P(r), radix, + MP_DENOM_P(r))) != MP_OK) + goto CLEANUP; + } - /* Also shift by enough to account for leading zeroes */ - while(num_lz > 0) { - if((res = mp_int_mul_value(K, MP_DENOM_P(r), radix, - MP_DENOM_P(r))) != MP_OK) - goto CLEANUP; - - --num_lz; - } - - /* Having found this power, shift the numerator leftward that - many, digits, and add the nonzero significant digits of the - fractional part to get the result. */ - if((res = mp_int_mul(K, MP_NUMER_P(r), MP_DENOM_P(r), - MP_NUMER_P(r))) != MP_OK) - goto CLEANUP; + /* Also shift by enough to account for leading zeroes */ + while(num_lz > 0) { + if((res = mp_int_mul_value(K, MP_DENOM_P(r), radix, + MP_DENOM_P(r))) != MP_OK) + goto CLEANUP; + + --num_lz; + } + + /* Having found this power, shift the numerator leftward that + many, digits, and add the nonzero significant digits of the + fractional part to get the result. */ + if((res = mp_int_mul(K, MP_NUMER_P(r), MP_DENOM_P(r), + MP_NUMER_P(r))) != MP_OK) + goto CLEANUP; - { /* This addition needs to be unsigned. */ - MP_SIGN(MP_NUMER_P(r)) = MP_ZPOS; - if((res = mp_int_add(K, MP_NUMER_P(r), &frac, - MP_NUMER_P(r))) != MP_OK) - goto CLEANUP; - - MP_SIGN(MP_NUMER_P(r)) = osign; - } - if((res = s_rat_reduce(K, r)) != MP_OK) - goto CLEANUP; - - /* At this point, what we return depends on whether reading the - fractional part was truncated or not. That information is - saved from when we called mp_int_read_string() above. */ + { /* This addition needs to be unsigned. */ + MP_SIGN(MP_NUMER_P(r)) = MP_ZPOS; + if((res = mp_int_add(K, MP_NUMER_P(r), &frac, + MP_NUMER_P(r))) != MP_OK) + goto CLEANUP; + + MP_SIGN(MP_NUMER_P(r)) = osign; + } + if((res = s_rat_reduce(K, r)) != MP_OK) + goto CLEANUP; + + /* At this point, what we return depends on whether reading the + fractional part was truncated or not. That information is + saved from when we called mp_int_read_string() above. */ FINISHED: - res = save_res; - if(end != NULL) - *end = endp; + res = save_res; + if(end != NULL) + *end = endp; CLEANUP: - mp_int_clear(K, &frac); + mp_int_clear(K, &frac); - return res; + return res; } } @@ -1016,33 +1016,33 @@ static mp_result s_rat_reduce(klisp_State *K, mp_rat r) mp_result res = MP_OK; if(mp_int_compare_zero(MP_NUMER_P(r)) == 0) { - mp_int_set_value(K, MP_DENOM_P(r), 1); - return MP_OK; + mp_int_set_value(K, MP_DENOM_P(r), 1); + return MP_OK; } /* If the greatest common divisor of the numerator and denominator is greater than 1, divide it out. */ if((res = mp_int_init(&gcd)) != MP_OK) - return res; + return res; if((res = mp_int_gcd(K, MP_NUMER_P(r), MP_DENOM_P(r), &gcd)) != MP_OK) - goto CLEANUP; + goto CLEANUP; if(mp_int_compare_value(&gcd, 1) != 0) { - if((res = mp_int_div(K, MP_NUMER_P(r), &gcd, MP_NUMER_P(r), - NULL)) != MP_OK) - goto CLEANUP; - if((res = mp_int_div(K, MP_DENOM_P(r), &gcd, MP_DENOM_P(r), - NULL)) != MP_OK) - goto CLEANUP; + if((res = mp_int_div(K, MP_NUMER_P(r), &gcd, MP_NUMER_P(r), + NULL)) != MP_OK) + goto CLEANUP; + if((res = mp_int_div(K, MP_DENOM_P(r), &gcd, MP_DENOM_P(r), + NULL)) != MP_OK) + goto CLEANUP; } /* Fix up the signs of numerator and denominator */ if(MP_SIGN(MP_NUMER_P(r)) == MP_SIGN(MP_DENOM_P(r))) - MP_SIGN(MP_NUMER_P(r)) = MP_SIGN(MP_DENOM_P(r)) = MP_ZPOS; + MP_SIGN(MP_NUMER_P(r)) = MP_SIGN(MP_DENOM_P(r)) = MP_ZPOS; else { - MP_SIGN(MP_NUMER_P(r)) = MP_NEG; - MP_SIGN(MP_DENOM_P(r)) = MP_ZPOS; + MP_SIGN(MP_NUMER_P(r)) = MP_NEG; + MP_SIGN(MP_DENOM_P(r)) = MP_ZPOS; } CLEANUP: @@ -1056,45 +1056,45 @@ CLEANUP: /* {{{ s_rat_combine(a, b, c, comb_f) */ static mp_result s_rat_combine(klisp_State *K, mp_rat a, mp_rat b, mp_rat c, - mp_result (*comb_f)(klisp_State *K, mp_int, - mp_int, mp_int)) + mp_result (*comb_f)(klisp_State *K, mp_int, + mp_int, mp_int)) { mp_result res; /* Shortcut when denominators are already common */ if(mp_int_compare(MP_DENOM_P(a), MP_DENOM_P(b)) == 0) { - if((res = (comb_f)(K, MP_NUMER_P(a), MP_NUMER_P(b), - MP_NUMER_P(c))) != MP_OK) - return res; - if((res = mp_int_copy(K, MP_DENOM_P(a), MP_DENOM_P(c))) != MP_OK) - return res; + if((res = (comb_f)(K, MP_NUMER_P(a), MP_NUMER_P(b), + MP_NUMER_P(c))) != MP_OK) + return res; + if((res = mp_int_copy(K, MP_DENOM_P(a), MP_DENOM_P(c))) != MP_OK) + return res; - return s_rat_reduce(K, c); + return s_rat_reduce(K, c); } else { - mpz_t temp[2]; - int last = 0; + mpz_t temp[2]; + int last = 0; - SETUP(mp_int_init_copy(K, TEMP(last), MP_NUMER_P(a)), last); - SETUP(mp_int_init_copy(K, TEMP(last), MP_NUMER_P(b)), last); + SETUP(mp_int_init_copy(K, TEMP(last), MP_NUMER_P(a)), last); + SETUP(mp_int_init_copy(K, TEMP(last), MP_NUMER_P(b)), last); - if((res = mp_int_mul(K, TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK) - goto CLEANUP; - if((res = mp_int_mul(K, TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK) - goto CLEANUP; - if((res = (comb_f)(K, TEMP(0), TEMP(1), MP_NUMER_P(c))) != MP_OK) - goto CLEANUP; + if((res = mp_int_mul(K, TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK) + goto CLEANUP; + if((res = mp_int_mul(K, TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK) + goto CLEANUP; + if((res = (comb_f)(K, TEMP(0), TEMP(1), MP_NUMER_P(c))) != MP_OK) + goto CLEANUP; - res = mp_int_mul(K, MP_DENOM_P(a), MP_DENOM_P(b), MP_DENOM_P(c)); + res = mp_int_mul(K, MP_DENOM_P(a), MP_DENOM_P(b), MP_DENOM_P(c)); CLEANUP: - while(--last >= 0) - mp_int_clear(K, TEMP(last)); + while(--last >= 0) + mp_int_clear(K, TEMP(last)); - if(res == MP_OK) - return s_rat_reduce(K, c); - else - return res; + if(res == MP_OK) + return s_rat_reduce(K, c); + else + return res; } } diff --git a/src/imrat.h b/src/imrat.h @@ -29,13 +29,13 @@ extern "C" { #endif /* Andres Navarro: Use kobject type instead */ -typedef Bigrat mpq_t, *mp_rat; + typedef Bigrat mpq_t, *mp_rat; #if 0 -typedef struct mpq { - mpz_t num; /* Numerator */ - mpz_t den; /* Denominator, <> 0 */ -} mpq_t, *mp_rat; + typedef struct mpq { + mpz_t num; /* Numerator */ + mpz_t den; /* Denominator, <> 0 */ + } mpq_t, *mp_rat; #endif #define MP_NUMER_P(Q) (&((Q)->num)) /* Pointer to numerator */ @@ -43,99 +43,99 @@ typedef struct mpq { /* Rounding constants */ /* TODO: klisp add MP_ROUND_HALF_EVEN for compatibility with floating point */ -typedef enum { - MP_ROUND_DOWN, - MP_ROUND_HALF_UP, - MP_ROUND_UP, - MP_ROUND_HALF_DOWN -} mp_round_mode; - -mp_result mp_rat_init(klisp_State *K, mp_rat r); -mp_rat mp_rat_alloc(klisp_State *K); -mp_result mp_rat_init_size(klisp_State *K, mp_rat r, mp_size n_prec, - mp_size d_prec); -mp_result mp_rat_init_copy(klisp_State *K, mp_rat r, mp_rat old); -mp_result mp_rat_set_value(klisp_State *K, mp_rat r, int numer, int denom); -void mp_rat_clear(klisp_State *K, mp_rat r); -void mp_rat_free(klisp_State *K, mp_rat r); -mp_result mp_rat_numer(klisp_State *K, mp_rat r, mp_int z); /* z = num(r) */ -mp_result mp_rat_denom(klisp_State *K, mp_rat r, mp_int z); /* z = den(r) */ + typedef enum { + MP_ROUND_DOWN, + MP_ROUND_HALF_UP, + MP_ROUND_UP, + MP_ROUND_HALF_DOWN + } mp_round_mode; + + mp_result mp_rat_init(klisp_State *K, mp_rat r); + mp_rat mp_rat_alloc(klisp_State *K); + mp_result mp_rat_init_size(klisp_State *K, mp_rat r, mp_size n_prec, + mp_size d_prec); + mp_result mp_rat_init_copy(klisp_State *K, mp_rat r, mp_rat old); + mp_result mp_rat_set_value(klisp_State *K, mp_rat r, int numer, int denom); + void mp_rat_clear(klisp_State *K, mp_rat r); + void mp_rat_free(klisp_State *K, mp_rat r); + mp_result mp_rat_numer(klisp_State *K, mp_rat r, mp_int z); /* z = num(r) */ + mp_result mp_rat_denom(klisp_State *K, mp_rat r, mp_int z); /* z = den(r) */ /* NOTE: this doesn't use the allocator */ -mp_sign mp_rat_sign(mp_rat r); + mp_sign mp_rat_sign(mp_rat r); -mp_result mp_rat_copy(klisp_State *K, mp_rat a, mp_rat c); /* c = a */ -void mp_rat_zero(klisp_State *K, mp_rat r); /* r = 0 */ -mp_result mp_rat_abs(klisp_State *K, mp_rat a, mp_rat c); /* c = |a| */ -mp_result mp_rat_neg(klisp_State *K, mp_rat a, mp_rat c); /* c = -a */ -mp_result mp_rat_recip(klisp_State *K, mp_rat a, mp_rat c); /* c = 1 / a */ + mp_result mp_rat_copy(klisp_State *K, mp_rat a, mp_rat c); /* c = a */ + void mp_rat_zero(klisp_State *K, mp_rat r); /* r = 0 */ + mp_result mp_rat_abs(klisp_State *K, mp_rat a, mp_rat c); /* c = |a| */ + mp_result mp_rat_neg(klisp_State *K, mp_rat a, mp_rat c); /* c = -a */ + mp_result mp_rat_recip(klisp_State *K, mp_rat a, mp_rat c); /* c = 1 / a */ /* c = a + b */ -mp_result mp_rat_add(klisp_State *K, mp_rat a, mp_rat b, mp_rat c); + mp_result mp_rat_add(klisp_State *K, mp_rat a, mp_rat b, mp_rat c); /* c = a - b */ -mp_result mp_rat_sub(klisp_State *K, mp_rat a, mp_rat b, mp_rat c); + mp_result mp_rat_sub(klisp_State *K, mp_rat a, mp_rat b, mp_rat c); /* c = a * b */ -mp_result mp_rat_mul(klisp_State *K, mp_rat a, mp_rat b, mp_rat c); + mp_result mp_rat_mul(klisp_State *K, mp_rat a, mp_rat b, mp_rat c); /* c = a / b */ -mp_result mp_rat_div(klisp_State *K, mp_rat a, mp_rat b, mp_rat c); + mp_result mp_rat_div(klisp_State *K, mp_rat a, mp_rat b, mp_rat c); /* c = a + b */ -mp_result mp_rat_add_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c); + mp_result mp_rat_add_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c); /* c = a - b */ -mp_result mp_rat_sub_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c); + mp_result mp_rat_sub_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c); /* c = a * b */ -mp_result mp_rat_mul_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c); + mp_result mp_rat_mul_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c); /* c = a / b */ -mp_result mp_rat_div_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c); + mp_result mp_rat_div_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c); /* c = a ^ b */ -mp_result mp_rat_expt(klisp_State *K, mp_rat a, mp_small b, mp_rat c); + mp_result mp_rat_expt(klisp_State *K, mp_rat a, mp_small b, mp_rat c); /* NOTE: because we may need to do multiplications, some of these take a klisp_State */ -int mp_rat_compare(klisp_State *K, mp_rat a, mp_rat b); /* a <=> b */ + int mp_rat_compare(klisp_State *K, mp_rat a, mp_rat b); /* a <=> b */ /* |a| <=> |b| */ -int mp_rat_compare_unsigned(klisp_State *K, mp_rat a, mp_rat b); + int mp_rat_compare_unsigned(klisp_State *K, mp_rat a, mp_rat b); /* NOTE: this doesn't use the allocator */ -int mp_rat_compare_zero(mp_rat r); /* r <=> 0 */ -int mp_rat_compare_value(klisp_State *K, mp_rat r, mp_small n, - mp_small d); /* r <=> n/d */ + int mp_rat_compare_zero(mp_rat r); /* r <=> 0 */ + int mp_rat_compare_value(klisp_State *K, mp_rat r, mp_small n, + mp_small d); /* r <=> n/d */ /* NOTE: this doesn't use the allocator */ -int mp_rat_is_integer(mp_rat r); + int mp_rat_is_integer(mp_rat r); /* Convert to integers, if representable (returns MP_RANGE if not). */ /* NOTE: this doesn't use the allocator */ -mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den); + mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den); /* Convert to nul-terminated string with the specified radix, writing at most limit characters including the nul terminator. */ -mp_result mp_rat_to_string(klisp_State *K, mp_rat r, mp_size radix, char *str, - int limit); + mp_result mp_rat_to_string(klisp_State *K, mp_rat r, mp_size radix, char *str, + int limit); /* Convert to decimal format in the specified radix and precision, writing at most limit characters including a nul terminator. */ -mp_result mp_rat_to_decimal(klisp_State *K, mp_rat r, mp_size radix, - mp_size prec, mp_round_mode round, - char *str, int limit); + mp_result mp_rat_to_decimal(klisp_State *K, mp_rat r, mp_size radix, + mp_size prec, mp_round_mode round, + char *str, int limit); /* Return the number of characters required to represent r in the given radix. May over-estimate. */ -mp_result mp_rat_string_len(mp_rat r, mp_size radix); + mp_result mp_rat_string_len(mp_rat r, mp_size radix); /* Return the number of characters required to represent r in decimal format with the given radix and precision. May over-estimate. */ -mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec); + mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec); /* Read zero-terminated string into r */ -mp_result mp_rat_read_string(klisp_State *K, mp_rat r, mp_size radix, - const char *str); -mp_result mp_rat_read_cstring(klisp_State *K, mp_rat r, mp_size radix, - const char *str, char **end); -mp_result mp_rat_read_ustring(klisp_State *K, mp_rat r, mp_size radix, - const char *str, char **end); + mp_result mp_rat_read_string(klisp_State *K, mp_rat r, mp_size radix, + const char *str); + mp_result mp_rat_read_cstring(klisp_State *K, mp_rat r, mp_size radix, + const char *str, char **end); + mp_result mp_rat_read_ustring(klisp_State *K, mp_rat r, mp_size radix, + const char *str, char **end); /* Read zero-terminated string in decimal format into r */ -mp_result mp_rat_read_decimal(klisp_State *K, mp_rat r, mp_size radix, - const char *str); -mp_result mp_rat_read_cdecimal(klisp_State *K, mp_rat r, mp_size radix, - const char *str, char **end); + mp_result mp_rat_read_decimal(klisp_State *K, mp_rat r, mp_size radix, + const char *str); + mp_result mp_rat_read_cdecimal(klisp_State *K, mp_rat r, mp_size radix, + const char *str, char **end); #ifdef __cplusplus } diff --git a/src/kapplicative.c b/src/kapplicative.c @@ -17,7 +17,7 @@ TValue kwrap(klisp_State *K, TValue underlying) /* header + gc_fields */ klispC_link(K, (GCObject *) new_app, K_TAPPLICATIVE, - K_FLAG_CAN_HAVE_NAME); + K_FLAG_CAN_HAVE_NAME); /* applicative specific fields */ new_app->underlying = underlying; diff --git a/src/kapplicative.h b/src/kapplicative.h @@ -15,13 +15,13 @@ TValue kwrap(klisp_State *K, TValue underlying); /* GC: Assumes all argps are rooted */ -#define kmake_applicative(K_, ...) \ - ({ klisp_State *K__ = (K_); \ - TValue op = kmake_operative(K__, __VA_ARGS__); \ - krooted_tvs_push(K__, op); \ - TValue app = kwrap(K__, op); \ - krooted_tvs_pop(K__); \ - (app); }) +#define kmake_applicative(K_, ...) \ + ({ klisp_State *K__ = (K_); \ + TValue op = kmake_operative(K__, __VA_ARGS__); \ + krooted_tvs_push(K__, op); \ + TValue app = kwrap(K__, op); \ + krooted_tvs_pop(K__); \ + (app); }) inline TValue kunwrap(TValue app) { return (tv2app(app)->underlying); } diff --git a/src/kauxlib.c b/src/kauxlib.c @@ -16,15 +16,15 @@ /* generic alloc function */ static void *k_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { - (void)ud; - (void)osize; + (void)ud; + (void)osize; - if (nsize == 0) { - free(ptr); - return NULL; - } else { - return realloc(ptr, nsize); - } + if (nsize == 0) { + free(ptr); + return NULL; + } else { + return realloc(ptr, nsize); + } } /* @@ -32,8 +32,8 @@ static void *k_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { */ klisp_State *klispL_newstate (void) { - klisp_State *K = klisp_newstate(k_alloc, NULL); - /* TODO: set any panic functions or something like that... */ - return K; + klisp_State *K = klisp_newstate(k_alloc, NULL); + /* TODO: set any panic functions or something like that... */ + return K; } diff --git a/src/kbytevector.c b/src/kbytevector.c @@ -18,10 +18,10 @@ /* General constructor for bytevectors */ TValue kbytevector_new_bs_g(klisp_State *K, bool m, const uint8_t *buf, - uint32_t size) + uint32_t size) { return m? kbytevector_new_bs(K, buf, size) : - kbytevector_new_bs_imm(K, buf, size); + kbytevector_new_bs_imm(K, buf, size); } /* @@ -34,24 +34,24 @@ TValue kbytevector_new_bs_imm(klisp_State *K, const uint8_t *buf, uint32_t size) /* first check to see if it's in the stringtable */ uint32_t h = size; /* seed */ size_t step = (size>>5)+1; /* if bytevector is too long, don't hash all - its bytes */ + its bytes */ size_t size1; for (size1 = size; size1 >= step; size1 -= step) /* compute hash */ - h = h ^ ((h<<5)+(h>>2)+ buf[size1-1]); + h = h ^ ((h<<5)+(h>>2)+ buf[size1-1]); for (GCObject *o = K->strt.hash[lmod(h, K->strt.size)]; - o != NULL; o = o->gch.next) { - klisp_assert(o->gch.tt == K_TKEYWORD || o->gch.tt == K_TSYMBOL || - o->gch.tt == K_TSTRING || o->gch.tt == K_TBYTEVECTOR); - - if (o->gch.tt != K_TBYTEVECTOR) continue; - - Bytevector *tb = (Bytevector *) o; - if (tb->size == size && (memcmp(buf, tb->b, size) == 0)) { - /* bytevector may be dead */ - if (isdead(K, o)) changewhite(o); - return gc2bytevector(o); - } + o != NULL; o = o->gch.next) { + klisp_assert(o->gch.tt == K_TKEYWORD || o->gch.tt == K_TSYMBOL || + o->gch.tt == K_TSTRING || o->gch.tt == K_TBYTEVECTOR); + + if (o->gch.tt != K_TBYTEVECTOR) continue; + + Bytevector *tb = (Bytevector *) o; + if (tb->size == size && (memcmp(buf, tb->b, size) == 0)) { + /* bytevector may be dead */ + if (isdead(K, o)) changewhite(o); + return gc2bytevector(o); + } } /* If it exits the loop, it means it wasn't found, hash is still in h */ @@ -59,7 +59,7 @@ TValue kbytevector_new_bs_imm(klisp_State *K, const uint8_t *buf, uint32_t size) Bytevector *new_bb; if (size > (SIZE_MAX - sizeof(Bytevector))) - klispM_toobig(K); + klispM_toobig(K); new_bb = (Bytevector *) klispM_malloc(K, sizeof(Bytevector) + size); @@ -77,7 +77,7 @@ TValue kbytevector_new_bs_imm(klisp_State *K, const uint8_t *buf, uint32_t size) new_bb->size = size; if (size != 0) { - memcpy(new_bb->b, buf, size); + memcpy(new_bb->b, buf, size); } /* add to the string/symbol table (and link it) */ @@ -89,9 +89,9 @@ TValue kbytevector_new_bs_imm(klisp_State *K, const uint8_t *buf, uint32_t size) tb->nuse++; TValue ret_tv = gc2bytevector(new_bb); if (tb->nuse > ((uint32_t) tb->size) && tb->size <= INT32_MAX / 2) { - krooted_tvs_push(K, ret_tv); /* save in case of gc */ - klispS_resize(K, tb->size*2); /* too crowded */ - krooted_tvs_pop(K); + krooted_tvs_push(K, ret_tv); /* save in case of gc */ + klispS_resize(K, tb->size*2); /* too crowded */ + krooted_tvs_pop(K); } return ret_tv; @@ -108,8 +108,8 @@ TValue kbytevector_new_s(klisp_State *K, uint32_t size) Bytevector *new_bb; if (size == 0) { - klisp_assert(ttisbytevector(K->empty_bytevector)); - return K->empty_bytevector; + klisp_assert(ttisbytevector(K->empty_bytevector)); + return K->empty_bytevector; } new_bb = klispM_malloc(K, sizeof(Bytevector) + size); @@ -130,8 +130,8 @@ TValue kbytevector_new_s(klisp_State *K, uint32_t size) TValue kbytevector_new_bs(klisp_State *K, const uint8_t *buf, uint32_t size) { if (size == 0) { - klisp_assert(ttisbytevector(K->empty_bytevector)); - return K->empty_bytevector; + klisp_assert(ttisbytevector(K->empty_bytevector)); + return K->empty_bytevector; } TValue new_bb = kbytevector_new_s(K, size); @@ -143,8 +143,8 @@ TValue kbytevector_new_bs(klisp_State *K, const uint8_t *buf, uint32_t size) TValue kbytevector_new_sf(klisp_State *K, uint32_t size, uint8_t fill) { if (size == 0) { - klisp_assert(ttisbytevector(K->empty_bytevector)); - return K->empty_bytevector; + klisp_assert(ttisbytevector(K->empty_bytevector)); + return K->empty_bytevector; } TValue new_bb = kbytevector_new_s(K, size); @@ -161,10 +161,10 @@ bool kbytevector_equalp(TValue obj1, TValue obj2) Bytevector *bytevector2 = tv2bytevector(obj2); if (bytevector1->size == bytevector2->size) { - return (bytevector1->size == 0) || - (memcmp(bytevector1->b, bytevector2->b, bytevector1->size) == 0); + return (bytevector1->size == 0) || + (memcmp(bytevector1->b, bytevector2->b, bytevector1->size) == 0); } else { - return false; + return false; } } diff --git a/src/kbytevector.h b/src/kbytevector.h @@ -14,7 +14,7 @@ /* General constructor for bytevectors */ TValue kbytevector_new_bs_g(klisp_State *K, bool m, const uint8_t *buf, - uint32_t size); + uint32_t size); /* ** Constructors for immutable bytevectors @@ -37,7 +37,7 @@ TValue kbytevector_new_bs(klisp_State *K, const uint8_t *buf, uint32_t size); TValue kbytevector_new_sf(klisp_State *K, uint32_t size, uint8_t fill); /* both obj1 and obj2 should be bytevectors, this compares byte by byte - and doesn't differentiate immutable from mutable bytevectors */ + and doesn't differentiate immutable from mutable bytevectors */ bool kbytevector_equalp(TValue obj1, TValue obj2); bool kbytevectorp(TValue obj); bool kimmutable_bytevectorp(TValue obj); diff --git a/src/kcontinuation.c b/src/kcontinuation.c @@ -13,16 +13,16 @@ #include "kgc.h" TValue kmake_continuation(klisp_State *K, TValue parent, klisp_CFunction fn, - int32_t xcount, ...) + int32_t xcount, ...) { va_list argp; Continuation *new_cont = (Continuation *) - klispM_malloc(K, sizeof(Continuation) + sizeof(TValue) * xcount); + klispM_malloc(K, sizeof(Continuation) + sizeof(TValue) * xcount); /* header + gc_fields */ klispC_link(K, (GCObject *) new_cont, K_TCONTINUATION, - K_FLAG_CAN_HAVE_NAME); + K_FLAG_CAN_HAVE_NAME); /* continuation specific fields */ @@ -31,7 +31,7 @@ TValue kmake_continuation(klisp_State *K, TValue parent, klisp_CFunction fn, TValue comb = K->next_obj; if (ttiscontinuation(comb)) - comb = tv2cont(comb)->comb; + comb = tv2cont(comb)->comb; new_cont->comb = comb; new_cont->fn = fn; @@ -39,7 +39,7 @@ TValue kmake_continuation(klisp_State *K, TValue parent, klisp_CFunction fn, va_start(argp, xcount); for (int i = 0; i < xcount; i++) { - new_cont->extra[i] = va_arg(argp, TValue); + new_cont->extra[i] = va_arg(argp, TValue); } va_end(argp); diff --git a/src/kcontinuation.h b/src/kcontinuation.h @@ -12,6 +12,6 @@ /* TODO: make some specialized constructors for 0, 1 and 2 parameters */ TValue kmake_continuation(klisp_State *K, TValue parent, klisp_CFunction fn, - int xcount, ...); + int xcount, ...); #endif diff --git a/src/kenvironment.c b/src/kenvironment.c @@ -33,7 +33,7 @@ TValue kmake_environment(klisp_State *K, TValue parents) /* header + gc_fields */ klispC_link(K, (GCObject *) new_env, K_TENVIRONMENT, - K_FLAG_CAN_HAVE_NAME); + K_FLAG_CAN_HAVE_NAME); /* environment specific fields */ new_env->mark = KFALSE; @@ -49,40 +49,40 @@ TValue kmake_environment(klisp_State *K, TValue parents) /* MAYBE: this could be optimized to avoid repetition of parents */ TValue kparents; if (ttisnil(parents)) { - kparents = KNIL; + kparents = KNIL; } else if (ttisenvironment(parents)) { - kparents = env_is_keyed(parents)? parents : env_keyed_parents(parents); + kparents = env_is_keyed(parents)? parents : env_keyed_parents(parents); } else { - /* list of parents, for now, just append them */ - krooted_tvs_push(K, gc2env(new_env)); /* keep the new env rooted */ - TValue plist = kcons(K, KNIL, KNIL); /* keep the list rooted */ - krooted_vars_push(K, &plist); - TValue tail = plist; - while(!ttisnil(parents)) { - TValue parent = kcar(parents); - TValue pkparents = env_keyed_parents(parent); - while(!ttisnil(pkparents)) { - TValue next; - if (ttisenvironment(pkparents)) { - next = pkparents; - pkparents = KNIL; - } else { - next = kcar(pkparents); - pkparents = kcdr(pkparents); - } - TValue new_pair = kcons(K, next, KNIL); - kset_cdr(tail, new_pair); - tail = new_pair; - } - parents = kcdr(parents); - } - /* all alocation done */ - kparents = kcdr(plist); - krooted_vars_pop(K); - krooted_tvs_pop(K); - /* if it's just one env switch from (env) to env. */ - if (ttispair(kparents) && ttisnil(kcdr(kparents))) - kparents = kcar(kparents); + /* list of parents, for now, just append them */ + krooted_tvs_push(K, gc2env(new_env)); /* keep the new env rooted */ + TValue plist = kcons(K, KNIL, KNIL); /* keep the list rooted */ + krooted_vars_push(K, &plist); + TValue tail = plist; + while(!ttisnil(parents)) { + TValue parent = kcar(parents); + TValue pkparents = env_keyed_parents(parent); + while(!ttisnil(pkparents)) { + TValue next; + if (ttisenvironment(pkparents)) { + next = pkparents; + pkparents = KNIL; + } else { + next = kcar(pkparents); + pkparents = kcdr(pkparents); + } + TValue new_pair = kcons(K, next, KNIL); + kset_cdr(tail, new_pair); + tail = new_pair; + } + parents = kcdr(parents); + } + /* all alocation done */ + kparents = kcdr(plist); + krooted_vars_pop(K); + krooted_tvs_pop(K); + /* if it's just one env switch from (env) to env. */ + if (ttispair(kparents) && ttisnil(kcdr(kparents))) + kparents = kcar(kparents); } new_env->keyed_parents = kparents; /* overwrite with the proper value */ return gc2env(new_env); @@ -98,12 +98,12 @@ TValue kfind_local_binding(klisp_State *K, TValue bindings, TValue sym) UNUSED(K); while(!ttisnil(bindings)) { - TValue first = kcar(bindings); - TValue first_sym = kcar(first); - /* symbols can't be compared with tv_equal! */ - if (tv_sym_equal(sym, first_sym)) - return first; - bindings = kcdr(bindings); + TValue first = kcar(bindings); + TValue first_sym = kcar(first); + /* symbols can't be compared with tv_equal! */ + if (tv_sym_equal(sym, first_sym)) + return first; + bindings = kcdr(bindings); } return KNIL; } @@ -119,29 +119,29 @@ TValue kfind_local_binding(klisp_State *K, TValue bindings, TValue sym) void ktry_set_name(klisp_State *K, TValue obj, TValue sym) { if (kcan_have_name(obj) && !khas_name(obj)) { - /* TODO: maybe we could have some kind of inheritance so - that if this object receives a name it can pass on that - name to other objs, like applicatives to operatives & - some applicatives to objects */ - gcvalue(obj)->gch.kflags |= K_FLAG_HAS_NAME; - TValue *node = klispH_set(K, tv2table(K->name_table), obj); - *node = sym; + /* TODO: maybe we could have some kind of inheritance so + that if this object receives a name it can pass on that + name to other objs, like applicatives to operatives & + some applicatives to objects */ + gcvalue(obj)->gch.kflags |= K_FLAG_HAS_NAME; + TValue *node = klispH_set(K, tv2table(K->name_table), obj); + *node = sym; - /* TEMP: use this until we have a general mechanism to add - objects to be named after some other obj */ - if (ttisapplicative(obj)) { - /* underlying is rooted by means of obj */ - TValue underlying = kunwrap(obj); - while (kcan_have_name(underlying) && !khas_name(underlying)) { - gcvalue(underlying)->gch.kflags |= K_FLAG_HAS_NAME; - node = klispH_set(K, tv2table(K->name_table), underlying); - *node = sym; - if (ttisapplicative(underlying)) - underlying = kunwrap(underlying); - else - break; - } - } + /* TEMP: use this until we have a general mechanism to add + objects to be named after some other obj */ + if (ttisapplicative(obj)) { + /* underlying is rooted by means of obj */ + TValue underlying = kunwrap(obj); + while (kcan_have_name(underlying) && !khas_name(underlying)) { + gcvalue(underlying)->gch.kflags |= K_FLAG_HAS_NAME; + node = klispH_set(K, tv2table(K->name_table), underlying); + *node = sym; + if (ttisapplicative(underlying)) + underlying = kunwrap(underlying); + else + break; + } + } } } @@ -149,7 +149,7 @@ void ktry_set_name(klisp_State *K, TValue obj, TValue sym) TValue kget_name(klisp_State *K, TValue obj) { const TValue *node = klispH_get(tv2table(K->name_table), - obj); + obj); klisp_assert(node != &kfree); return *node; } @@ -167,64 +167,64 @@ void kadd_binding(klisp_State *K, TValue env, TValue sym, TValue val) TValue bindings = kenv_bindings(K, env); if (ttistable(bindings)) { - TValue *cell = klispH_setsym(K, tv2table(bindings), tv2sym(sym)); - *cell = val; + TValue *cell = klispH_setsym(K, tv2table(bindings), tv2sym(sym)); + *cell = val; } else { - TValue oldb = kfind_local_binding(K, bindings, sym); + TValue oldb = kfind_local_binding(K, bindings, sym); - if (ttisnil(oldb)) { - TValue new_pair = kcons(K, sym, val); - krooted_tvs_push(K, new_pair); - kenv_bindings(K, env) = kcons(K, new_pair, bindings); - krooted_tvs_pop(K); - } else { - kset_cdr(oldb, val); - } + if (ttisnil(oldb)) { + TValue new_pair = kcons(K, sym, val); + krooted_tvs_push(K, new_pair); + kenv_bindings(K, env) = kcons(K, new_pair, bindings); + krooted_tvs_pop(K); + } else { + kset_cdr(oldb, val); + } } } /* This works no matter if parents is a list or a single environment */ /* GC: assumes env & sym are rooted */ inline bool try_get_binding(klisp_State *K, TValue env, TValue sym, - TValue *value) + TValue *value) { /* assume the stack may be in use, keep track of pushed objs */ int pushed = 1; ks_spush(K, env); while(pushed) { - TValue obj = ks_spop(K); - --pushed; - if (ttisnil(obj)) { - continue; - } else if (ttisenvironment(obj)) { - TValue bindings = kenv_bindings(K, obj); - if (ttistable(bindings)) { - const TValue *cell = klispH_getsym(tv2table(bindings), - tv2sym(sym)); - if (cell != &kfree) { - /* remember to leave the stack as it was */ - ks_sdiscardn(K, pushed); - *value = *cell; - return true; - } - } else { - TValue oldb = kfind_local_binding(K, bindings, sym); - if (!ttisnil(oldb)) { - /* remember to leave the stack as it was */ - ks_sdiscardn(K, pushed); - *value = kcdr(oldb); - return true; - } - } - TValue parents = kenv_parents(K, obj); - ks_spush(K, parents); - ++pushed; - } else { /* parent list */ - ks_spush(K, kcdr(obj)); - ks_spush(K, kcar(obj)); - pushed += 2; - } + TValue obj = ks_spop(K); + --pushed; + if (ttisnil(obj)) { + continue; + } else if (ttisenvironment(obj)) { + TValue bindings = kenv_bindings(K, obj); + if (ttistable(bindings)) { + const TValue *cell = klispH_getsym(tv2table(bindings), + tv2sym(sym)); + if (cell != &kfree) { + /* remember to leave the stack as it was */ + ks_sdiscardn(K, pushed); + *value = *cell; + return true; + } + } else { + TValue oldb = kfind_local_binding(K, bindings, sym); + if (!ttisnil(oldb)) { + /* remember to leave the stack as it was */ + ks_sdiscardn(K, pushed); + *value = kcdr(oldb); + return true; + } + } + TValue parents = kenv_parents(K, obj); + ks_spush(K, parents); + ++pushed; + } else { /* parent list */ + ks_spush(K, kcdr(obj)); + ks_spush(K, kcar(obj)); + pushed += 2; + } } *value = KINERT; @@ -237,11 +237,11 @@ TValue kget_binding(klisp_State *K, TValue env, TValue sym) klisp_assert(ttissymbol(sym)); TValue value; if (try_get_binding(K, env, sym, &value)) { - return value; + return value; } else { - klispE_throw_simple_with_irritants(K, "Unbound symbol", 1, sym); - /* avoid warning */ - return KINERT; + klispE_throw_simple_with_irritants(K, "Unbound symbol", 1, sym); + /* avoid warning */ + return KINERT; } } @@ -256,7 +256,7 @@ bool kbinds(klisp_State *K, TValue env, TValue sym) /* MAYBE: This could be combined with the default constructor */ /* GC: assumes parent, key & val are rooted */ TValue kmake_keyed_static_env(klisp_State *K, TValue parent, TValue key, - TValue val) + TValue val) { TValue new_env = kmake_environment(K, parent); krooted_tvs_push(K, new_env); /* keep the env rooted */ @@ -267,38 +267,38 @@ TValue kmake_keyed_static_env(klisp_State *K, TValue parent, TValue key, /* GC: assumes parent, key & env are rooted */ inline bool try_get_keyed(klisp_State *K, TValue env, TValue key, - TValue *value) + TValue *value) { /* MAYBE: this could be optimized to mark environments to avoid - repetition */ + repetition */ /* assume the stack may be in use, keep track of pushed objs */ int pushed = 1; if (!env_is_keyed(env)) - env = env_keyed_parents(env); + env = env_keyed_parents(env); ks_spush(K, env); while(pushed) { - TValue obj = ks_spop(K); - --pushed; - if (ttisnil(obj)) { - continue; - } else if (ttisenvironment(obj)) { - /* obj is guaranteed to be a keyed env */ - if (env_has_key(obj, key)) { - /* remember to leave the stack as it was */ - ks_sdiscardn(K, pushed); - *value = env_keyed_val(obj); - return true; - } else { - TValue parents = env_keyed_parents(obj); - ks_spush(K, parents); - ++pushed; - } - } else { /* parent list */ - ks_spush(K, kcdr(obj)); - ks_spush(K, kcar(obj)); - pushed += 2; - } + TValue obj = ks_spop(K); + --pushed; + if (ttisnil(obj)) { + continue; + } else if (ttisenvironment(obj)) { + /* obj is guaranteed to be a keyed env */ + if (env_has_key(obj, key)) { + /* remember to leave the stack as it was */ + ks_sdiscardn(K, pushed); + *value = env_keyed_val(obj); + return true; + } else { + TValue parents = env_keyed_parents(obj); + ks_spush(K, parents); + ++pushed; + } + } else { /* parent list */ + ks_spush(K, kcdr(obj)); + ks_spush(K, kcar(obj)); + pushed += 2; + } } *value = KINERT; return false; @@ -308,11 +308,11 @@ TValue kget_keyed_static_var(klisp_State *K, TValue env, TValue key) { TValue value; if (try_get_keyed(K, env, key, &value)) { - return value; + return value; } else { - klispE_throw_simple(K, "Unbound keyed static variable"); - /* avoid warning */ - return KINERT; + klispE_throw_simple(K, "Unbound keyed static variable"); + /* avoid warning */ + return KINERT; } } diff --git a/src/klisp.c b/src/klisp.c @@ -457,9 +457,10 @@ static int dorfile(klisp_State *K, const char *name) and return #inert instead, it will also signal via rootp = false that the evaluation didn't explicitly invoke the root continuation */ + /* XXX for now, GC protect the environment in this discard continuation */ + /* TODO use a more elegant way! */ TValue discard_cont = kmake_continuation(K, inner_cont, do_int_mark_root, - 1, p2tv(&rootp)); - + 2, p2tv(&rootp), K->next_env); krooted_tvs_pop(K); /* pop inner cont */ /* set the cont & call require */