tclStubLib.cGo to the documentation of this file.00001 /* 00002 * tclStubLib.c -- 00003 * 00004 * Stub object that will be statically linked into extensions that want 00005 * to access Tcl. 00006 * 00007 * Copyright (c) 1998-1999 by Scriptics Corporation. 00008 * Copyright (c) 1998 Paul Duffin. 00009 * 00010 * See the file "license.terms" for information on usage and redistribution of 00011 * this file, and for a DISCLAIMER OF ALL WARRANTIES. 00012 * 00013 * RCS: @(#) $Id: tclStubLib.c,v 1.21 2007/12/13 15:23:20 dgp Exp $ 00014 */ 00015 00016 /* 00017 * We need to ensure that we use the stub macros so that this file contains no 00018 * references to any of the stub functions. This will make it possible to 00019 * build an extension that references Tcl_InitStubs but doesn't end up 00020 * including the rest of the stub functions. 00021 */ 00022 00023 #ifndef USE_TCL_STUBS 00024 #define USE_TCL_STUBS 00025 #endif 00026 #undef USE_TCL_STUB_PROCS 00027 00028 #include "tclInt.h" 00029 00030 /* 00031 * Tcl_InitStubs and stub table pointers are built as exported symbols. 00032 */ 00033 00034 TclStubs *tclStubsPtr = NULL; 00035 TclPlatStubs *tclPlatStubsPtr = NULL; 00036 TclIntStubs *tclIntStubsPtr = NULL; 00037 TclIntPlatStubs *tclIntPlatStubsPtr = NULL; 00038 TclTomMathStubs* tclTomMathStubsPtr = NULL; 00039 00040 static TclStubs * 00041 HasStubSupport( 00042 Tcl_Interp *interp) 00043 { 00044 Interp *iPtr = (Interp *) interp; 00045 00046 if (iPtr->stubTable && (iPtr->stubTable->magic == TCL_STUB_MAGIC)) { 00047 return iPtr->stubTable; 00048 } 00049 00050 interp->result = 00051 "This interpreter does not support stubs-enabled extensions."; 00052 interp->freeProc = TCL_STATIC; 00053 return NULL; 00054 } 00055 00056 /* 00057 * Use our own isdigit to avoid linking to libc on windows 00058 */ 00059 00060 static int isDigit(const int c) 00061 { 00062 return (c >= '0' && c <= '9'); 00063 } 00064 00065 /* 00066 *---------------------------------------------------------------------- 00067 * 00068 * Tcl_InitStubs -- 00069 * 00070 * Tries to initialise the stub table pointers and ensures that the 00071 * correct version of Tcl is loaded. 00072 * 00073 * Results: 00074 * The actual version of Tcl that satisfies the request, or NULL to 00075 * indicate that an error occurred. 00076 * 00077 * Side effects: 00078 * Sets the stub table pointers. 00079 * 00080 *---------------------------------------------------------------------- 00081 */ 00082 00083 #ifdef Tcl_InitStubs 00084 #undef Tcl_InitStubs 00085 #endif 00086 00087 CONST char * 00088 Tcl_InitStubs( 00089 Tcl_Interp *interp, 00090 CONST char *version, 00091 int exact) 00092 { 00093 CONST char *actualVersion = NULL; 00094 ClientData pkgData = NULL; 00095 00096 /* 00097 * We can't optimize this check by caching tclStubsPtr because that 00098 * prevents apps from being able to load/unload Tcl dynamically multiple 00099 * times. [Bug 615304] 00100 */ 00101 00102 tclStubsPtr = HasStubSupport(interp); 00103 if (!tclStubsPtr) { 00104 return NULL; 00105 } 00106 00107 actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, 0, &pkgData); 00108 if (actualVersion == NULL) { 00109 return NULL; 00110 } 00111 if (exact) { 00112 CONST char *p = version; 00113 int count = 0; 00114 00115 while (*p) { 00116 count += !isDigit(*p++); 00117 } 00118 if (count == 1) { 00119 CONST char *q = actualVersion; 00120 00121 p = version; 00122 while (*p && (*p == *q)) { 00123 p++; q++; 00124 } 00125 if (*p) { 00126 return NULL; 00127 } 00128 } else { 00129 actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL); 00130 if (actualVersion == NULL) { 00131 return NULL; 00132 } 00133 } 00134 } 00135 tclStubsPtr = (TclStubs*)pkgData; 00136 00137 if (tclStubsPtr->hooks) { 00138 tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs; 00139 tclIntStubsPtr = tclStubsPtr->hooks->tclIntStubs; 00140 tclIntPlatStubsPtr = tclStubsPtr->hooks->tclIntPlatStubs; 00141 } else { 00142 tclPlatStubsPtr = NULL; 00143 tclIntStubsPtr = NULL; 00144 tclIntPlatStubsPtr = NULL; 00145 } 00146 00147 return actualVersion; 00148 } 00149 00150 /* 00151 *---------------------------------------------------------------------- 00152 * 00153 * TclTomMathInitStubs -- 00154 * 00155 * Initializes the Stubs table for Tcl's subset of libtommath 00156 * 00157 * Results: 00158 * Returns a standard Tcl result. 00159 * 00160 * This procedure should not be called directly, but rather through 00161 * the TclTomMath_InitStubs macro, to insure that the Stubs table 00162 * matches the header files used in compilation. 00163 * 00164 *---------------------------------------------------------------------- 00165 */ 00166 00167 #ifdef TclTomMathInitializeStubs 00168 #undef TclTomMathInitializeStubs 00169 #endif 00170 00171 CONST char* 00172 TclTomMathInitializeStubs( 00173 Tcl_Interp* interp, /* Tcl interpreter */ 00174 CONST char* version, /* Tcl version needed */ 00175 int epoch, /* Stubs table epoch from the header files */ 00176 int revision /* Stubs table revision number from the 00177 * header files */ 00178 ) { 00179 int exact = 0; 00180 const char* packageName = "tcl::tommath"; 00181 const char* errMsg = NULL; 00182 ClientData pkgClientData = NULL; 00183 const char* actualVersion = 00184 Tcl_PkgRequireEx(interp, packageName, version, exact, &pkgClientData); 00185 TclTomMathStubs* stubsPtr = (TclTomMathStubs*) pkgClientData; 00186 if (actualVersion == NULL) { 00187 return NULL; 00188 } 00189 if (pkgClientData == NULL) { 00190 errMsg = "missing stub table pointer"; 00191 } else if ((stubsPtr->tclBN_epoch)() != epoch) { 00192 errMsg = "epoch number mismatch"; 00193 } else if ((stubsPtr->tclBN_revision)() != revision) { 00194 errMsg = "requires a later revision"; 00195 } else { 00196 tclTomMathStubsPtr = stubsPtr; 00197 return actualVersion; 00198 } 00199 Tcl_ResetResult(interp); 00200 Tcl_AppendResult(interp, "error loading ", packageName, 00201 " (requested version ", version, 00202 ", actual version ", actualVersion, 00203 "): ", errMsg, NULL); 00204 return NULL; 00205 }
Generated on Wed Mar 12 12:18:21 2008 by 1.5.1 |