Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/tcl8.5.2/generic/tclStubLib.c @ 35

Last change on this file since 35 was 25, checked in by landauf, 17 years ago

added tcl to libs

File size: 5.0 KB
Line 
1/*
2 * tclStubLib.c --
3 *
4 *      Stub object that will be statically linked into extensions that want
5 *      to access Tcl.
6 *
7 * Copyright (c) 1998-1999 by Scriptics Corporation.
8 * Copyright (c) 1998 Paul Duffin.
9 *
10 * See the file "license.terms" for information on usage and redistribution of
11 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 *
13 * RCS: @(#) $Id: tclStubLib.c,v 1.21 2007/12/13 15:23:20 dgp Exp $
14 */
15
16/*
17 * We need to ensure that we use the stub macros so that this file contains no
18 * references to any of the stub functions. This will make it possible to
19 * build an extension that references Tcl_InitStubs but doesn't end up
20 * including the rest of the stub functions.
21 */
22
23#ifndef USE_TCL_STUBS
24#define USE_TCL_STUBS
25#endif
26#undef USE_TCL_STUB_PROCS
27
28#include "tclInt.h"
29
30/*
31 * Tcl_InitStubs and stub table pointers are built as exported symbols.
32 */
33
34TclStubs *tclStubsPtr = NULL;
35TclPlatStubs *tclPlatStubsPtr = NULL;
36TclIntStubs *tclIntStubsPtr = NULL;
37TclIntPlatStubs *tclIntPlatStubsPtr = NULL;
38TclTomMathStubs* tclTomMathStubsPtr = NULL;
39
40static TclStubs *
41HasStubSupport(
42    Tcl_Interp *interp)
43{
44    Interp *iPtr = (Interp *) interp;
45
46    if (iPtr->stubTable && (iPtr->stubTable->magic == TCL_STUB_MAGIC)) {
47        return iPtr->stubTable;
48    }
49
50    interp->result =
51            "This interpreter does not support stubs-enabled extensions.";
52    interp->freeProc = TCL_STATIC;
53    return NULL;
54}
55
56/*
57 * Use our own isdigit to avoid linking to libc on windows
58 */
59
60static int isDigit(const int c)
61{
62    return (c >= '0' && c <= '9');
63}
64
65/*
66 *----------------------------------------------------------------------
67 *
68 * Tcl_InitStubs --
69 *
70 *      Tries to initialise the stub table pointers and ensures that the
71 *      correct version of Tcl is loaded.
72 *
73 * Results:
74 *      The actual version of Tcl that satisfies the request, or NULL to
75 *      indicate that an error occurred.
76 *
77 * Side effects:
78 *      Sets the stub table pointers.
79 *
80 *----------------------------------------------------------------------
81 */
82
83#ifdef Tcl_InitStubs
84#undef Tcl_InitStubs
85#endif
86
87CONST char *
88Tcl_InitStubs(
89    Tcl_Interp *interp,
90    CONST char *version,
91    int exact)
92{
93    CONST char *actualVersion = NULL;
94    ClientData pkgData = NULL;
95
96    /*
97     * We can't optimize this check by caching tclStubsPtr because that
98     * prevents apps from being able to load/unload Tcl dynamically multiple
99     * times. [Bug 615304]
100     */
101
102    tclStubsPtr = HasStubSupport(interp);
103    if (!tclStubsPtr) {
104        return NULL;
105    }
106
107    actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, 0, &pkgData);
108    if (actualVersion == NULL) {
109        return NULL;
110    }
111    if (exact) {
112        CONST char *p = version;
113        int count = 0;
114
115        while (*p) {
116            count += !isDigit(*p++);
117        }
118        if (count == 1) {
119            CONST char *q = actualVersion;
120
121            p = version;
122            while (*p && (*p == *q)) {
123                p++; q++;
124            }
125            if (*p) {
126                return NULL;
127            }
128        } else {
129            actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
130            if (actualVersion == NULL) {
131                return NULL;
132            }
133        }
134    }
135    tclStubsPtr = (TclStubs*)pkgData;
136
137    if (tclStubsPtr->hooks) {
138        tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs;
139        tclIntStubsPtr = tclStubsPtr->hooks->tclIntStubs;
140        tclIntPlatStubsPtr = tclStubsPtr->hooks->tclIntPlatStubs;
141    } else {
142        tclPlatStubsPtr = NULL;
143        tclIntStubsPtr = NULL;
144        tclIntPlatStubsPtr = NULL;
145    }
146
147    return actualVersion;
148}
149
150/*
151 *----------------------------------------------------------------------
152 *
153 * TclTomMathInitStubs --
154 *
155 *      Initializes the Stubs table for Tcl's subset of libtommath
156 *
157 * Results:
158 *      Returns a standard Tcl result.
159 *
160 * This procedure should not be called directly, but rather through
161 * the TclTomMath_InitStubs macro, to insure that the Stubs table
162 * matches the header files used in compilation.
163 *
164 *----------------------------------------------------------------------
165 */
166
167#ifdef TclTomMathInitializeStubs
168#undef TclTomMathInitializeStubs
169#endif
170
171CONST char*
172TclTomMathInitializeStubs(
173    Tcl_Interp* interp,         /* Tcl interpreter */
174    CONST char* version,        /* Tcl version needed */
175    int epoch,                  /* Stubs table epoch from the header files */
176    int revision                /* Stubs table revision number from the
177                                 * header files */
178) {
179    int exact = 0;
180    const char* packageName = "tcl::tommath";
181    const char* errMsg = NULL;
182    ClientData pkgClientData = NULL;
183    const char* actualVersion = 
184        Tcl_PkgRequireEx(interp, packageName, version, exact, &pkgClientData);
185    TclTomMathStubs* stubsPtr = (TclTomMathStubs*) pkgClientData;
186    if (actualVersion == NULL) {
187        return NULL;
188    }
189    if (pkgClientData == NULL) {
190        errMsg = "missing stub table pointer";
191    } else if ((stubsPtr->tclBN_epoch)() != epoch) {
192        errMsg = "epoch number mismatch";
193    } else if ((stubsPtr->tclBN_revision)() != revision) {
194        errMsg = "requires a later revision";
195    } else {
196        tclTomMathStubsPtr = stubsPtr;
197        return actualVersion;
198    }
199    Tcl_ResetResult(interp);
200    Tcl_AppendResult(interp, "error loading ", packageName,
201                     " (requested version ", version,
202                     ", actual version ", actualVersion,
203                     "): ", errMsg, NULL);
204    return NULL;
205}
Note: See TracBrowser for help on using the repository browser.