tclTomMathInterface.c

Go to the documentation of this file.
00001 /*
00002  *----------------------------------------------------------------------
00003  *
00004  * tclTomMathInterface.c --
00005  *
00006  *      This file contains procedures that are used as a 'glue' layer between
00007  *      Tcl and libtommath.
00008  *
00009  * Copyright (c) 2005 by Kevin B. Kenny.  All rights reserved.
00010  *
00011  * See the file "license.terms" for information on usage and redistribution of
00012  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
00013  *
00014  * RCS: @(#) $Id: tclTomMathInterface.c,v 1.10 2007/12/13 15:23:20 dgp Exp $
00015  */
00016 
00017 #include "tclInt.h"
00018 #include "tommath.h"
00019 #include <limits.h>
00020 
00021 extern TclTomMathStubs tclTomMathStubs;
00022 
00023 /*
00024  *----------------------------------------------------------------------
00025  *
00026  * TclTommath_Init --
00027  *
00028  *      Initializes the TclTomMath 'package', which exists as a
00029  *      placeholder so that the package data can be used to hold
00030  *      a stub table pointer.
00031  *
00032  * Results:
00033  *      Returns a standard Tcl result.
00034  *
00035  * Side effects:
00036  *      Installs the stub table for tommath.
00037  *
00038  *----------------------------------------------------------------------
00039  */
00040 
00041 int
00042 TclTommath_Init(
00043     Tcl_Interp* interp          /* Tcl interpreter */
00044 ) {
00045     /* TIP #268: Full patchlevel instead of just major.minor */
00046 
00047     if (Tcl_PkgProvideEx(interp, "tcl::tommath", TCL_PATCH_LEVEL,
00048                          (ClientData)&tclTomMathStubs) != TCL_OK) {
00049         return TCL_ERROR;
00050     }
00051     return TCL_OK;
00052 }
00053 
00054 /*
00055  *----------------------------------------------------------------------
00056  *
00057  * TclBN_epoch --
00058  *
00059  *      Return the epoch number of the TclTomMath stubs table
00060  *
00061  * Results:
00062  *      Returns an arbitrary integer that does not decrease with
00063  *      release.  Stubs tables with different epochs are incompatible.
00064  *
00065  *----------------------------------------------------------------------
00066  */
00067 
00068 int
00069 TclBN_epoch(void)
00070 {
00071     return TCLTOMMATH_EPOCH;
00072 }
00073 
00074 /*
00075  *----------------------------------------------------------------------
00076  *
00077  * TclBN_revision --
00078  *
00079  *      Returns the revision level of the TclTomMath stubs table
00080  *
00081  * Results:
00082  *      Returns an arbitrary integer that increases with revisions.
00083  *      If a client requires a given epoch and revision, any Stubs table
00084  *      with the same epoch and an equal or higher revision satisfies
00085  *      the request.
00086  *
00087  *----------------------------------------------------------------------
00088  */
00089 
00090 int
00091 TclBN_revision(void)
00092 {
00093     return TCLTOMMATH_REVISION;
00094 }
00095 #if 0
00096 
00097 /*
00098  *----------------------------------------------------------------------
00099  *
00100  * TclBNAlloc --
00101  *
00102  *      Allocate memory for libtommath.
00103  *
00104  * Results:
00105  *      Returns a pointer to the allocated block.
00106  *
00107  * This procedure is a wrapper around Tcl_Alloc, needed because of a
00108  * mismatched type signature between Tcl_Alloc and malloc.
00109  *
00110  *----------------------------------------------------------------------
00111  */
00112 
00113 extern void *
00114 TclBNAlloc(
00115     size_t x)
00116 {
00117     return (void *) Tcl_Alloc((unsigned int) x);
00118 }
00119 
00120 /*
00121  *----------------------------------------------------------------------
00122  *
00123  * TclBNRealloc --
00124  *
00125  *      Change the size of an allocated block of memory in libtommath
00126  *
00127  * Results:
00128  *      Returns a pointer to the allocated block.
00129  *
00130  * This procedure is a wrapper around Tcl_Realloc, needed because of a
00131  * mismatched type signature between Tcl_Realloc and realloc.
00132  *
00133  *----------------------------------------------------------------------
00134  */
00135 
00136 void *
00137 TclBNRealloc(
00138     void *p,
00139     size_t s)
00140 {
00141     return (void *) Tcl_Realloc((char *) p, (unsigned int) s);
00142 }
00143 
00144 /*
00145  *----------------------------------------------------------------------
00146  *
00147  * TclBNFree --
00148  *
00149  *      Free allocated memory in libtommath.
00150  *
00151  * Results:
00152  *      None.
00153  *
00154  * Side effects:
00155  *      Memory is freed.
00156  *
00157  * This function is simply a wrapper around Tcl_Free, needed in libtommath
00158  * because of a type mismatch between free and Tcl_Free.
00159  *
00160  *----------------------------------------------------------------------
00161  */
00162 
00163 extern void
00164 TclBNFree(
00165     void *p)
00166 {
00167     Tcl_Free((char *) p);
00168 }
00169 #endif
00170 
00171 /*
00172  *----------------------------------------------------------------------
00173  *
00174  * TclBNInitBignumFromLong --
00175  *
00176  *      Allocate and initialize a 'bignum' from a native 'long'.
00177  *
00178  * Results:
00179  *      None.
00180  *
00181  * Side effects:
00182  *      The 'bignum' is constructed.
00183  *
00184  *----------------------------------------------------------------------
00185  */
00186 
00187 extern void
00188 TclBNInitBignumFromLong(
00189     mp_int *a,
00190     long initVal)
00191 {
00192     int status;
00193     unsigned long v;
00194     mp_digit* p;
00195 
00196     /*
00197      * Allocate enough memory to hold the largest possible long
00198      */
00199 
00200     status = mp_init_size(a,
00201             (CHAR_BIT * sizeof(long) + DIGIT_BIT - 1) / DIGIT_BIT);
00202     if (status != MP_OKAY) {
00203         Tcl_Panic("initialization failure in TclBNInitBignumFromLong");
00204     }
00205 
00206     /*
00207      * Convert arg to sign and magnitude.
00208      */
00209 
00210     if (initVal < 0) {
00211         a->sign = MP_NEG;
00212         v = -initVal;
00213     } else {
00214         a->sign = MP_ZPOS;
00215         v = initVal;
00216     }
00217 
00218     /*
00219      * Store the magnitude in the bignum.
00220      */
00221 
00222     p = a->dp;
00223     while (v) {
00224         *p++ = (mp_digit) (v & MP_MASK);
00225         v >>= MP_DIGIT_BIT;
00226     }
00227     a->used = p - a->dp;
00228 }
00229 
00230 /*
00231  *----------------------------------------------------------------------
00232  *
00233  * TclBNInitBignumFromWideInt --
00234  *
00235  *      Allocate and initialize a 'bignum' from a Tcl_WideInt
00236  *
00237  * Results:
00238  *      None.
00239  *
00240  * Side effects:
00241  *      The 'bignum' is constructed.
00242  *
00243  *----------------------------------------------------------------------
00244  */
00245 
00246 extern void
00247 TclBNInitBignumFromWideInt(
00248     mp_int *a,                  /* Bignum to initialize */
00249     Tcl_WideInt v)              /* Initial value */
00250 {
00251     if (v < (Tcl_WideInt)0) {
00252         TclBNInitBignumFromWideUInt(a, (Tcl_WideUInt)(-v));
00253         mp_neg(a, a);
00254     } else {
00255         TclBNInitBignumFromWideUInt(a, (Tcl_WideUInt)v);
00256     }
00257 }
00258 
00259 /*
00260  *----------------------------------------------------------------------
00261  *
00262  * TclBNInitBignumFromWideUInt --
00263  *
00264  *      Allocate and initialize a 'bignum' from a Tcl_WideUInt
00265  *
00266  * Results:
00267  *      None.
00268  *
00269  * Side effects:
00270  *      The 'bignum' is constructed.
00271  *
00272  *----------------------------------------------------------------------
00273  */
00274 
00275 extern void
00276 TclBNInitBignumFromWideUInt(
00277     mp_int *a,                  /* Bignum to initialize */
00278     Tcl_WideUInt v)             /* Initial value */
00279 {
00280     int status;
00281     mp_digit *p;
00282 
00283     /*
00284      * Allocate enough memory to hold the largest possible Tcl_WideUInt.
00285      */
00286 
00287     status = mp_init_size(a,
00288             (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT);
00289     if (status != MP_OKAY) {
00290         Tcl_Panic("initialization failure in TclBNInitBignumFromWideUInt");
00291     }
00292 
00293     a->sign = MP_ZPOS;
00294 
00295     /*
00296      * Store the magnitude in the bignum.
00297      */
00298 
00299     p = a->dp;
00300     while (v) {
00301         *p++ = (mp_digit) (v & MP_MASK);
00302         v >>= MP_DIGIT_BIT;
00303     }
00304     a->used = p - a->dp;
00305 }
00306 
00307 /*
00308  * Local Variables:
00309  * mode: c
00310  * c-basic-offset: 4
00311  * fill-column: 78
00312  * End:
00313  */



Generated on Wed Mar 12 12:18:23 2008 by  doxygen 1.5.1