OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [generic/] [tclBasic.c] - Blame information for rev 578

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tclBasic.c --
3
 *
4
 *      Contains the basic facilities for TCL command interpretation,
5
 *      including interpreter creation and deletion, command creation
6
 *      and deletion, and command parsing and execution.
7
 *
8
 * Copyright (c) 1987-1994 The Regents of the University of California.
9
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
10
 * Copyright (c) 1998 by Scriptics Corporation.
11
 *
12
 * See the file "license.terms" for information on usage and redistribution
13
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14
 *
15
 * RCS: @(#) $Id: tclBasic.c,v 1.1.1.1 2002-01-16 10:25:25 markom Exp $
16
 */
17
 
18
#include "tclInt.h"
19
#include "tclCompile.h"
20
#ifndef TCL_GENERIC_ONLY
21
#   include "tclPort.h"
22
#endif
23
 
24
/*
25
 * Static procedures in this file:
26
 */
27
 
28
static void             DeleteInterpProc _ANSI_ARGS_((Tcl_Interp *interp));
29
static void             HiddenCmdsDeleteProc _ANSI_ARGS_((
30
                            ClientData clientData, Tcl_Interp *interp));
31
 
32
/*
33
 * The following structure defines the commands in the Tcl core.
34
 */
35
 
36
typedef struct {
37
    char *name;                 /* Name of object-based command. */
38
    Tcl_CmdProc *proc;          /* String-based procedure for command. */
39
    Tcl_ObjCmdProc *objProc;    /* Object-based procedure for command. */
40
    CompileProc *compileProc;   /* Procedure called to compile command. */
41
    int isSafe;                 /* If non-zero, command will be present
42
                                 * in safe interpreter. Otherwise it will
43
                                 * be hidden. */
44
} CmdInfo;
45
 
46
/*
47
 * The built-in commands, and the procedures that implement them:
48
 */
49
 
50
static CmdInfo builtInCmds[] = {
51
    /*
52
     * Commands in the generic core. Note that at least one of the proc or
53
     * objProc members should be non-NULL. This avoids infinitely recursive
54
     * calls between TclInvokeObjectCommand and TclInvokeStringCommand if a
55
     * command name is computed at runtime and results in the name of a
56
     * compiled command.
57
     */
58
 
59
    {"append",          (Tcl_CmdProc *) NULL,   Tcl_AppendObjCmd,
60
        (CompileProc *) NULL,           1},
61
    {"array",           (Tcl_CmdProc *) NULL,   Tcl_ArrayObjCmd,
62
        (CompileProc *) NULL,           1},
63
    {"binary",          (Tcl_CmdProc *) NULL,   Tcl_BinaryObjCmd,
64
        (CompileProc *) NULL,           1},
65
    {"break",           Tcl_BreakCmd,           (Tcl_ObjCmdProc *) NULL,
66
        TclCompileBreakCmd,             1},
67
    {"case",            (Tcl_CmdProc *) NULL,   Tcl_CaseObjCmd,
68
        (CompileProc *) NULL,           1},
69
    {"catch",           (Tcl_CmdProc *) NULL,   Tcl_CatchObjCmd,
70
        TclCompileCatchCmd,             1},
71
    {"clock",           (Tcl_CmdProc *) NULL,   Tcl_ClockObjCmd,
72
        (CompileProc *) NULL,           1},
73
    {"concat",          (Tcl_CmdProc *) NULL,   Tcl_ConcatObjCmd,
74
        (CompileProc *) NULL,           1},
75
    {"continue",        Tcl_ContinueCmd,        (Tcl_ObjCmdProc *) NULL,
76
        TclCompileContinueCmd,          1},
77
    {"error",           (Tcl_CmdProc *) NULL,   Tcl_ErrorObjCmd,
78
        (CompileProc *) NULL,           1},
79
    {"eval",            (Tcl_CmdProc *) NULL,   Tcl_EvalObjCmd,
80
        (CompileProc *) NULL,           1},
81
    {"exit",            (Tcl_CmdProc *) NULL,   Tcl_ExitObjCmd,
82
        (CompileProc *) NULL,           0},
83
    {"expr",            (Tcl_CmdProc *) NULL,   Tcl_ExprObjCmd,
84
        TclCompileExprCmd,              1},
85
    {"fcopy",           (Tcl_CmdProc *) NULL,   Tcl_FcopyObjCmd,
86
        (CompileProc *) NULL,           1},
87
    {"fileevent",       Tcl_FileEventCmd,       (Tcl_ObjCmdProc *) NULL,
88
        (CompileProc *) NULL,           1},
89
    {"for",             Tcl_ForCmd,             (Tcl_ObjCmdProc *) NULL,
90
        TclCompileForCmd,               1},
91
    {"foreach",         (Tcl_CmdProc *) NULL,   Tcl_ForeachObjCmd,
92
        TclCompileForeachCmd,           1},
93
    {"format",          (Tcl_CmdProc *) NULL,   Tcl_FormatObjCmd,
94
        (CompileProc *) NULL,           1},
95
    {"global",          (Tcl_CmdProc *) NULL,   Tcl_GlobalObjCmd,
96
        (CompileProc *) NULL,           1},
97
    {"if",              Tcl_IfCmd,              (Tcl_ObjCmdProc *) NULL,
98
        TclCompileIfCmd,                1},
99
    {"incr",            Tcl_IncrCmd,            (Tcl_ObjCmdProc *) NULL,
100
        TclCompileIncrCmd,              1},
101
    {"info",            (Tcl_CmdProc *) NULL,   Tcl_InfoObjCmd,
102
        (CompileProc *) NULL,           1},
103
    {"interp",          (Tcl_CmdProc *) NULL,   Tcl_InterpObjCmd,
104
        (CompileProc *) NULL,           1},
105
    {"join",            (Tcl_CmdProc *) NULL,   Tcl_JoinObjCmd,
106
        (CompileProc *) NULL,           1},
107
    {"lappend",         (Tcl_CmdProc *) NULL,   Tcl_LappendObjCmd,
108
        (CompileProc *) NULL,           1},
109
    {"lindex",          (Tcl_CmdProc *) NULL,   Tcl_LindexObjCmd,
110
        (CompileProc *) NULL,           1},
111
    {"linsert",         (Tcl_CmdProc *) NULL,   Tcl_LinsertObjCmd,
112
        (CompileProc *) NULL,           1},
113
    {"list",            (Tcl_CmdProc *) NULL,   Tcl_ListObjCmd,
114
        (CompileProc *) NULL,           1},
115
    {"llength",         (Tcl_CmdProc *) NULL,   Tcl_LlengthObjCmd,
116
        (CompileProc *) NULL,           1},
117
    {"load",            Tcl_LoadCmd,            (Tcl_ObjCmdProc *) NULL,
118
        (CompileProc *) NULL,           0},
119
    {"lrange",          (Tcl_CmdProc *) NULL,   Tcl_LrangeObjCmd,
120
        (CompileProc *) NULL,           1},
121
    {"lreplace",        (Tcl_CmdProc *) NULL,   Tcl_LreplaceObjCmd,
122
        (CompileProc *) NULL,           1},
123
    {"lsearch",         (Tcl_CmdProc *) NULL,   Tcl_LsearchObjCmd,
124
        (CompileProc *) NULL,           1},
125
    {"lsort",           (Tcl_CmdProc *) NULL,   Tcl_LsortObjCmd,
126
        (CompileProc *) NULL,           1},
127
    {"namespace",       (Tcl_CmdProc *) NULL,   Tcl_NamespaceObjCmd,
128
        (CompileProc *) NULL,           1},
129
    {"package",         Tcl_PackageCmd,         (Tcl_ObjCmdProc *) NULL,
130
        (CompileProc *) NULL,           1},
131
    {"proc",            (Tcl_CmdProc *) NULL,   Tcl_ProcObjCmd,
132
        (CompileProc *) NULL,           1},
133
    {"regexp",          Tcl_RegexpCmd,          (Tcl_ObjCmdProc *) NULL,
134
        (CompileProc *) NULL,           1},
135
    {"regsub",          Tcl_RegsubCmd,          (Tcl_ObjCmdProc *) NULL,
136
        (CompileProc *) NULL,           1},
137
    {"rename",          (Tcl_CmdProc *) NULL,   Tcl_RenameObjCmd,
138
        (CompileProc *) NULL,           1},
139
    {"return",          (Tcl_CmdProc *) NULL,   Tcl_ReturnObjCmd,
140
        (CompileProc *) NULL,           1},
141
    {"scan",            Tcl_ScanCmd,            (Tcl_ObjCmdProc *) NULL,
142
        (CompileProc *) NULL,           1},
143
    {"set",             Tcl_SetCmd,             (Tcl_ObjCmdProc *) NULL,
144
        TclCompileSetCmd,               1},
145
    {"split",           (Tcl_CmdProc *) NULL,   Tcl_SplitObjCmd,
146
        (CompileProc *) NULL,           1},
147
    {"string",          (Tcl_CmdProc *) NULL,   Tcl_StringObjCmd,
148
        (CompileProc *) NULL,           1},
149
    {"subst",           Tcl_SubstCmd,           (Tcl_ObjCmdProc *) NULL,
150
        (CompileProc *) NULL,           1},
151
    {"switch",          (Tcl_CmdProc *) NULL,   Tcl_SwitchObjCmd,
152
        (CompileProc *) NULL,           1},
153
    {"trace",           Tcl_TraceCmd,           (Tcl_ObjCmdProc *) NULL,
154
        (CompileProc *) NULL,           1},
155
    {"unset",           (Tcl_CmdProc *) NULL,   Tcl_UnsetObjCmd,
156
        (CompileProc *) NULL,           1},
157
    {"uplevel",         (Tcl_CmdProc *) NULL,   Tcl_UplevelObjCmd,
158
        (CompileProc *) NULL,           1},
159
    {"upvar",           (Tcl_CmdProc *) NULL,   Tcl_UpvarObjCmd,
160
        (CompileProc *) NULL,           1},
161
    {"variable",        (Tcl_CmdProc *) NULL,   Tcl_VariableObjCmd,
162
        (CompileProc *) NULL,           1},
163
    {"while",           Tcl_WhileCmd,           (Tcl_ObjCmdProc *) NULL,
164
        TclCompileWhileCmd,             1},
165
 
166
    /*
167
     * Commands in the UNIX core:
168
     */
169
 
170
#ifndef TCL_GENERIC_ONLY
171
    {"after",           (Tcl_CmdProc *) NULL,   Tcl_AfterObjCmd,
172
        (CompileProc *) NULL,           1},
173
    {"cd",              (Tcl_CmdProc *) NULL,   Tcl_CdObjCmd,
174
        (CompileProc *) NULL,           0},
175
    {"close",           (Tcl_CmdProc *) NULL,   Tcl_CloseObjCmd,
176
        (CompileProc *) NULL,           1},
177
    {"eof",             (Tcl_CmdProc *) NULL,   Tcl_EofObjCmd,
178
        (CompileProc *) NULL,           1},
179
    {"fblocked",        (Tcl_CmdProc *) NULL,   Tcl_FblockedObjCmd,
180
        (CompileProc *) NULL,           1},
181
    {"fconfigure",      Tcl_FconfigureCmd,      (Tcl_ObjCmdProc *) NULL,
182
        (CompileProc *) NULL,           0},
183
    {"file",            (Tcl_CmdProc *) NULL,   Tcl_FileObjCmd,
184
        (CompileProc *) NULL,           0},
185
    {"flush",           (Tcl_CmdProc *) NULL,   Tcl_FlushObjCmd,
186
        (CompileProc *) NULL,           1},
187
    {"gets",            (Tcl_CmdProc *) NULL,   Tcl_GetsObjCmd,
188
        (CompileProc *) NULL,           1},
189
    {"glob",            Tcl_GlobCmd,            (Tcl_ObjCmdProc *) NULL,
190
        (CompileProc *) NULL,           0},
191
    {"open",            Tcl_OpenCmd,            (Tcl_ObjCmdProc *) NULL,
192
        (CompileProc *) NULL,           0},
193
    {"pid",             (Tcl_CmdProc *) NULL,   Tcl_PidObjCmd,
194
        (CompileProc *) NULL,           1},
195
    {"puts",            (Tcl_CmdProc *) NULL,   Tcl_PutsObjCmd,
196
        (CompileProc *) NULL,           1},
197
    {"pwd",             Tcl_PwdCmd,             (Tcl_ObjCmdProc *) NULL,
198
        (CompileProc *) NULL,           0},
199
    {"read",            (Tcl_CmdProc *) NULL,   Tcl_ReadObjCmd,
200
        (CompileProc *) NULL,           1},
201
    {"seek",            Tcl_SeekCmd,            (Tcl_ObjCmdProc *) NULL,
202
        (CompileProc *) NULL,           1},
203
    {"socket",          Tcl_SocketCmd,          (Tcl_ObjCmdProc *) NULL,
204
        (CompileProc *) NULL,           0},
205
    {"tell",            Tcl_TellCmd,            (Tcl_ObjCmdProc *) NULL,
206
        (CompileProc *) NULL,           1},
207
    {"time",            (Tcl_CmdProc *) NULL,   Tcl_TimeObjCmd,
208
        (CompileProc *) NULL,           1},
209
    {"update",          Tcl_UpdateCmd,          (Tcl_ObjCmdProc *) NULL,
210
        (CompileProc *) NULL,           1},
211
    {"vwait",           Tcl_VwaitCmd,           (Tcl_ObjCmdProc *) NULL,
212
        (CompileProc *) NULL,           1},
213
 
214
#ifdef MAC_TCL
215
    {"beep",            (Tcl_CmdProc *) NULL,   Tcl_BeepObjCmd,
216
        (CompileProc *) NULL,           0},
217
    {"echo",            Tcl_EchoCmd,            (Tcl_ObjCmdProc *) NULL,
218
        (CompileProc *) NULL,           0},
219
    {"ls",              Tcl_LsCmd,              (Tcl_ObjCmdProc *) NULL,
220
        (CompileProc *) NULL,           0},
221
    {"resource",        (Tcl_CmdProc *) NULL,   Tcl_ResourceObjCmd,
222
        (CompileProc *) NULL,           1},
223
    {"source",          (Tcl_CmdProc *) NULL,   Tcl_MacSourceObjCmd,
224
        (CompileProc *) NULL,           0},
225
#else
226
    {"exec",            Tcl_ExecCmd,            (Tcl_ObjCmdProc *) NULL,
227
        (CompileProc *) NULL,           0},
228
    {"source",          (Tcl_CmdProc *) NULL,   Tcl_SourceObjCmd,
229
        (CompileProc *) NULL,           0},
230
#endif /* MAC_TCL */
231
 
232
#endif /* TCL_GENERIC_ONLY */
233
    {NULL,              (Tcl_CmdProc *) NULL,   (Tcl_ObjCmdProc *) NULL,
234
        (CompileProc *) NULL,           0}
235
};
236
 
237
/*
238
 *----------------------------------------------------------------------
239
 *
240
 * Tcl_CreateInterp --
241
 *
242
 *      Create a new TCL command interpreter.
243
 *
244
 * Results:
245
 *      The return value is a token for the interpreter, which may be
246
 *      used in calls to procedures like Tcl_CreateCmd, Tcl_Eval, or
247
 *      Tcl_DeleteInterp.
248
 *
249
 * Side effects:
250
 *      The command interpreter is initialized with an empty variable
251
 *      table and the built-in commands.
252
 *
253
 *----------------------------------------------------------------------
254
 */
255
 
256
Tcl_Interp *
257
Tcl_CreateInterp()
258
{
259
    register Interp *iPtr;
260
    register Command *cmdPtr;
261
    register CmdInfo *cmdInfoPtr;
262
    union {
263
        char c[sizeof(short)];
264
        short s;
265
    } order;
266
    int i;
267
 
268
    /*
269
     * Panic if someone updated the CallFrame structure without
270
     * also updating the Tcl_CallFrame structure (or vice versa).
271
     */
272
 
273
    if (sizeof(Tcl_CallFrame) != sizeof(CallFrame)) {
274
        /*NOTREACHED*/
275
        panic("Tcl_CallFrame and CallFrame are not the same size");
276
    }
277
 
278
    /*
279
     * Initialize support for namespaces and create the global namespace
280
     * (whose name is ""; an alias is "::"). This also initializes the
281
     * Tcl object type table and other object management code.
282
     */
283
 
284
    TclInitNamespaces();
285
 
286
    iPtr = (Interp *) ckalloc(sizeof(Interp));
287
    iPtr->result = iPtr->resultSpace;
288
    iPtr->freeProc = 0;
289
    iPtr->objResultPtr = Tcl_NewObj(); /* an empty object */
290
    Tcl_IncrRefCount(iPtr->objResultPtr);
291
    iPtr->errorLine = 0;
292
    Tcl_InitHashTable(&iPtr->mathFuncTable, TCL_STRING_KEYS);
293
    iPtr->numLevels = 0;
294
    iPtr->maxNestingDepth = 1000;
295
    iPtr->framePtr = NULL;
296
    iPtr->varFramePtr = NULL;
297
    iPtr->activeTracePtr = NULL;
298
    iPtr->returnCode = TCL_OK;
299
    iPtr->errorInfo = NULL;
300
    iPtr->errorCode = NULL;
301
    iPtr->appendResult = NULL;
302
    iPtr->appendAvl = 0;
303
    iPtr->appendUsed = 0;
304
    for (i = 0; i < NUM_REGEXPS; i++) {
305
        iPtr->patterns[i] = NULL;
306
        iPtr->patLengths[i] = -1;
307
        iPtr->regexps[i] = NULL;
308
    }
309
    Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS);
310
    iPtr->packageUnknown = NULL;
311
    iPtr->cmdCount = 0;
312
    iPtr->termOffset = 0;
313
    iPtr->compileEpoch = 0;
314
    iPtr->compiledProcPtr = NULL;
315
    iPtr->resolverPtr = NULL;
316
    iPtr->evalFlags = 0;
317
    iPtr->scriptFile = NULL;
318
    iPtr->flags = 0;
319
    iPtr->tracePtr = NULL;
320
    iPtr->assocData = (Tcl_HashTable *) NULL;
321
    iPtr->execEnvPtr = NULL;          /* set after namespaces initialized */
322
    iPtr->emptyObjPtr = Tcl_NewObj(); /* another empty object */
323
    Tcl_IncrRefCount(iPtr->emptyObjPtr);
324
    iPtr->resultSpace[0] = 0;
325
 
326
    iPtr->globalNsPtr = NULL;   /* force creation of global ns below */
327
    iPtr->globalNsPtr = (Namespace *) Tcl_CreateNamespace(
328
            (Tcl_Interp *) iPtr, "", (ClientData) NULL,
329
            (Tcl_NamespaceDeleteProc *) NULL);
330
    if (iPtr->globalNsPtr == NULL) {
331
        panic("Tcl_CreateInterp: can't create global namespace");
332
    }
333
 
334
    /*
335
     * Initialize support for code compilation. Do this after initializing
336
     * namespaces since TclCreateExecEnv will try to reference a Tcl
337
     * variable (it links to the Tcl "tcl_traceExec" variable).
338
     */
339
 
340
    iPtr->execEnvPtr = TclCreateExecEnv((Tcl_Interp *) iPtr);
341
 
342
    /*
343
     * Create the core commands. Do it here, rather than calling
344
     * Tcl_CreateCommand, because it's faster (there's no need to check for
345
     * a pre-existing command by the same name). If a command has a
346
     * Tcl_CmdProc but no Tcl_ObjCmdProc, set the Tcl_ObjCmdProc to
347
     * TclInvokeStringCommand. This is an object-based wrapper procedure
348
     * that extracts strings, calls the string procedure, and creates an
349
     * object for the result. Similarly, if a command has a Tcl_ObjCmdProc
350
     * but no Tcl_CmdProc, set the Tcl_CmdProc to TclInvokeObjectCommand.
351
     */
352
 
353
    for (cmdInfoPtr = builtInCmds;  cmdInfoPtr->name != NULL;
354
            cmdInfoPtr++) {
355
        int new;
356
        Tcl_HashEntry *hPtr;
357
 
358
        if ((cmdInfoPtr->proc == (Tcl_CmdProc *) NULL)
359
                && (cmdInfoPtr->objProc == (Tcl_ObjCmdProc *) NULL)
360
                && (cmdInfoPtr->compileProc == (CompileProc *) NULL)) {
361
            panic("Tcl_CreateInterp: builtin command with NULL string and object command procs and a NULL compile proc\n");
362
        }
363
 
364
        hPtr = Tcl_CreateHashEntry(&iPtr->globalNsPtr->cmdTable,
365
                cmdInfoPtr->name, &new);
366
        if (new) {
367
            cmdPtr = (Command *) ckalloc(sizeof(Command));
368
            cmdPtr->hPtr = hPtr;
369
            cmdPtr->nsPtr = iPtr->globalNsPtr;
370
            cmdPtr->refCount = 1;
371
            cmdPtr->cmdEpoch = 0;
372
            cmdPtr->compileProc = cmdInfoPtr->compileProc;
373
            if (cmdInfoPtr->proc == (Tcl_CmdProc *) NULL) {
374
                cmdPtr->proc = TclInvokeObjectCommand;
375
                cmdPtr->clientData = (ClientData) cmdPtr;
376
            } else {
377
                cmdPtr->proc = cmdInfoPtr->proc;
378
                cmdPtr->clientData = (ClientData) NULL;
379
            }
380
            if (cmdInfoPtr->objProc == (Tcl_ObjCmdProc *) NULL) {
381
                cmdPtr->objProc = TclInvokeStringCommand;
382
                cmdPtr->objClientData = (ClientData) cmdPtr;
383
            } else {
384
                cmdPtr->objProc = cmdInfoPtr->objProc;
385
                cmdPtr->objClientData = (ClientData) NULL;
386
            }
387
            cmdPtr->deleteProc = NULL;
388
            cmdPtr->deleteData = (ClientData) NULL;
389
            cmdPtr->deleted = 0;
390
            cmdPtr->importRefPtr = NULL;
391
            Tcl_SetHashValue(hPtr, cmdPtr);
392
        }
393
    }
394
 
395
    /*
396
     *  Initialize/Create "errorInfo" and "errorCode" global vars
397
     *  (because some part of the C code assume they exists
398
     *   and we can get a seg fault otherwise (in multiple
399
     *   interps loading of extensions for instance) --dl)
400
     */
401
     /*
402
      *  We can't assume that because we initialize
403
      *  the variables here, they won't be unset later.
404
      *  so we had 2 choices:
405
      *    + Check every place where a GetVar of those is used
406
      *      and the NULL result is not checked (like in tclLoad.c)
407
      *    + Make SetVar,... NULL friendly
408
      *  We choosed the second option because :
409
      *    + It is easy and low cost to check for NULL pointer before
410
      *      calling strlen()
411
      *    + It can be helpfull to other people using those API
412
      *    + Passing a NULL value to those closest 'meaning' is empty string
413
      *      (specially with the new objects where 0 bytes strings are ok)
414
      * So the following init is commented out:              -- dl
415
      */
416
    /*
417
      (void)Tcl_SetVar2((Tcl_Interp *)iPtr, "errorInfo", (char *) NULL, "",
418
         TCL_GLOBAL_ONLY);
419
      (void)Tcl_SetVar2((Tcl_Interp *)iPtr, "errorCode", (char *) NULL, "NONE",
420
            TCL_GLOBAL_ONLY);
421
     */
422
 
423
#ifndef TCL_GENERIC_ONLY
424
    TclSetupEnv((Tcl_Interp *) iPtr);
425
#endif
426
 
427
    /*
428
     * Do Multiple/Safe Interps Tcl init stuff
429
     */
430
    (void) TclInterpInit((Tcl_Interp *)iPtr);
431
 
432
    /*
433
     * Set up variables such as tcl_version.
434
     */
435
 
436
    TclPlatformInit((Tcl_Interp *)iPtr);
437
    Tcl_SetVar((Tcl_Interp *) iPtr, "tcl_patchLevel", TCL_PATCH_LEVEL,
438
            TCL_GLOBAL_ONLY);
439
    Tcl_SetVar((Tcl_Interp *) iPtr, "tcl_version", TCL_VERSION,
440
            TCL_GLOBAL_ONLY);
441
    Tcl_TraceVar2((Tcl_Interp *) iPtr, "tcl_precision", (char *) NULL,
442
            TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
443
            TclPrecTraceProc, (ClientData) NULL);
444
 
445
    /*
446
     * Compute the byte order of this machine.
447
     */
448
 
449
    order.s = 1;
450
    Tcl_SetVar2((Tcl_Interp *) iPtr, "tcl_platform", "byteOrder",
451
            (order.c[0] == 1) ? "littleEndian" : "bigEndian",
452
            TCL_GLOBAL_ONLY);
453
 
454
    /*
455
     * Register Tcl's version number.
456
     */
457
 
458
    Tcl_PkgProvide((Tcl_Interp *) iPtr, "Tcl", TCL_VERSION);
459
 
460
    return (Tcl_Interp *) iPtr;
461
}
462
 
463
/*
464
 *----------------------------------------------------------------------
465
 *
466
 * TclHideUnsafeCommands --
467
 *
468
 *      Hides base commands that are not marked as safe from this
469
 *      interpreter.
470
 *
471
 * Results:
472
 *      TCL_OK if it succeeds, TCL_ERROR else.
473
 *
474
 * Side effects:
475
 *      Hides functionality in an interpreter.
476
 *
477
 *----------------------------------------------------------------------
478
 */
479
 
480
int
481
TclHideUnsafeCommands(interp)
482
    Tcl_Interp *interp;         /* Hide commands in this interpreter. */
483
{
484
    register CmdInfo *cmdInfoPtr;
485
 
486
    if (interp == (Tcl_Interp *) NULL) {
487
        return TCL_ERROR;
488
    }
489
    for (cmdInfoPtr = builtInCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
490
        if (!cmdInfoPtr->isSafe) {
491
            Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name);
492
        }
493
    }
494
    return TCL_OK;
495
}
496
 
497
/*
498
 *--------------------------------------------------------------
499
 *
500
 * Tcl_CallWhenDeleted --
501
 *
502
 *      Arrange for a procedure to be called before a given
503
 *      interpreter is deleted. The procedure is called as soon
504
 *      as Tcl_DeleteInterp is called; if Tcl_CallWhenDeleted is
505
 *      called on an interpreter that has already been deleted,
506
 *      the procedure will be called when the last Tcl_Release is
507
 *      done on the interpreter.
508
 *
509
 * Results:
510
 *      None.
511
 *
512
 * Side effects:
513
 *      When Tcl_DeleteInterp is invoked to delete interp,
514
 *      proc will be invoked.  See the manual entry for
515
 *      details.
516
 *
517
 *--------------------------------------------------------------
518
 */
519
 
520
void
521
Tcl_CallWhenDeleted(interp, proc, clientData)
522
    Tcl_Interp *interp;         /* Interpreter to watch. */
523
    Tcl_InterpDeleteProc *proc; /* Procedure to call when interpreter
524
                                 * is about to be deleted. */
525
    ClientData clientData;      /* One-word value to pass to proc. */
526
{
527
    Interp *iPtr = (Interp *) interp;
528
    static int assocDataCounter = 0;
529
    int new;
530
    char buffer[128];
531
    AssocData *dPtr = (AssocData *) ckalloc(sizeof(AssocData));
532
    Tcl_HashEntry *hPtr;
533
 
534
    sprintf(buffer, "Assoc Data Key #%d", assocDataCounter);
535
    assocDataCounter++;
536
 
537
    if (iPtr->assocData == (Tcl_HashTable *) NULL) {
538
        iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
539
        Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
540
    }
541
    hPtr = Tcl_CreateHashEntry(iPtr->assocData, buffer, &new);
542
    dPtr->proc = proc;
543
    dPtr->clientData = clientData;
544
    Tcl_SetHashValue(hPtr, dPtr);
545
}
546
 
547
/*
548
 *--------------------------------------------------------------
549
 *
550
 * Tcl_DontCallWhenDeleted --
551
 *
552
 *      Cancel the arrangement for a procedure to be called when
553
 *      a given interpreter is deleted.
554
 *
555
 * Results:
556
 *      None.
557
 *
558
 * Side effects:
559
 *      If proc and clientData were previously registered as a
560
 *      callback via Tcl_CallWhenDeleted, they are unregistered.
561
 *      If they weren't previously registered then nothing
562
 *      happens.
563
 *
564
 *--------------------------------------------------------------
565
 */
566
 
567
void
568
Tcl_DontCallWhenDeleted(interp, proc, clientData)
569
    Tcl_Interp *interp;         /* Interpreter to watch. */
570
    Tcl_InterpDeleteProc *proc; /* Procedure to call when interpreter
571
                                 * is about to be deleted. */
572
    ClientData clientData;      /* One-word value to pass to proc. */
573
{
574
    Interp *iPtr = (Interp *) interp;
575
    Tcl_HashTable *hTablePtr;
576
    Tcl_HashSearch hSearch;
577
    Tcl_HashEntry *hPtr;
578
    AssocData *dPtr;
579
 
580
    hTablePtr = iPtr->assocData;
581
    if (hTablePtr == (Tcl_HashTable *) NULL) {
582
        return;
583
    }
584
    for (hPtr = Tcl_FirstHashEntry(hTablePtr, &hSearch); hPtr != NULL;
585
            hPtr = Tcl_NextHashEntry(&hSearch)) {
586
        dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
587
        if ((dPtr->proc == proc) && (dPtr->clientData == clientData)) {
588
            ckfree((char *) dPtr);
589
            Tcl_DeleteHashEntry(hPtr);
590
            return;
591
        }
592
    }
593
}
594
 
595
/*
596
 *----------------------------------------------------------------------
597
 *
598
 * Tcl_SetAssocData --
599
 *
600
 *      Creates a named association between user-specified data, a delete
601
 *      function and this interpreter. If the association already exists
602
 *      the data is overwritten with the new data. The delete function will
603
 *      be invoked when the interpreter is deleted.
604
 *
605
 * Results:
606
 *      None.
607
 *
608
 * Side effects:
609
 *      Sets the associated data, creates the association if needed.
610
 *
611
 *----------------------------------------------------------------------
612
 */
613
 
614
void
615
Tcl_SetAssocData(interp, name, proc, clientData)
616
    Tcl_Interp *interp;         /* Interpreter to associate with. */
617
    char *name;                 /* Name for association. */
618
    Tcl_InterpDeleteProc *proc; /* Proc to call when interpreter is
619
                                 * about to be deleted. */
620
    ClientData clientData;      /* One-word value to pass to proc. */
621
{
622
    Interp *iPtr = (Interp *) interp;
623
    AssocData *dPtr;
624
    Tcl_HashEntry *hPtr;
625
    int new;
626
 
627
    if (iPtr->assocData == (Tcl_HashTable *) NULL) {
628
        iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
629
        Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
630
    }
631
    hPtr = Tcl_CreateHashEntry(iPtr->assocData, name, &new);
632
    if (new == 0) {
633
        dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
634
    } else {
635
        dPtr = (AssocData *) ckalloc(sizeof(AssocData));
636
    }
637
    dPtr->proc = proc;
638
    dPtr->clientData = clientData;
639
 
640
    Tcl_SetHashValue(hPtr, dPtr);
641
}
642
 
643
/*
644
 *----------------------------------------------------------------------
645
 *
646
 * Tcl_DeleteAssocData --
647
 *
648
 *      Deletes a named association of user-specified data with
649
 *      the specified interpreter.
650
 *
651
 * Results:
652
 *      None.
653
 *
654
 * Side effects:
655
 *      Deletes the association.
656
 *
657
 *----------------------------------------------------------------------
658
 */
659
 
660
void
661
Tcl_DeleteAssocData(interp, name)
662
    Tcl_Interp *interp;                 /* Interpreter to associate with. */
663
    char *name;                         /* Name of association. */
664
{
665
    Interp *iPtr = (Interp *) interp;
666
    AssocData *dPtr;
667
    Tcl_HashEntry *hPtr;
668
 
669
    if (iPtr->assocData == (Tcl_HashTable *) NULL) {
670
        return;
671
    }
672
    hPtr = Tcl_FindHashEntry(iPtr->assocData, name);
673
    if (hPtr == (Tcl_HashEntry *) NULL) {
674
        return;
675
    }
676
    dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
677
    if (dPtr->proc != NULL) {
678
        (dPtr->proc) (dPtr->clientData, interp);
679
    }
680
    ckfree((char *) dPtr);
681
    Tcl_DeleteHashEntry(hPtr);
682
}
683
 
684
/*
685
 *----------------------------------------------------------------------
686
 *
687
 * Tcl_GetAssocData --
688
 *
689
 *      Returns the client data associated with this name in the
690
 *      specified interpreter.
691
 *
692
 * Results:
693
 *      The client data in the AssocData record denoted by the named
694
 *      association, or NULL.
695
 *
696
 * Side effects:
697
 *      None.
698
 *
699
 *----------------------------------------------------------------------
700
 */
701
 
702
ClientData
703
Tcl_GetAssocData(interp, name, procPtr)
704
    Tcl_Interp *interp;                 /* Interpreter associated with. */
705
    char *name;                         /* Name of association. */
706
    Tcl_InterpDeleteProc **procPtr;     /* Pointer to place to store address
707
                                         * of current deletion callback. */
708
{
709
    Interp *iPtr = (Interp *) interp;
710
    AssocData *dPtr;
711
    Tcl_HashEntry *hPtr;
712
 
713
    if (iPtr->assocData == (Tcl_HashTable *) NULL) {
714
        return (ClientData) NULL;
715
    }
716
    hPtr = Tcl_FindHashEntry(iPtr->assocData, name);
717
    if (hPtr == (Tcl_HashEntry *) NULL) {
718
        return (ClientData) NULL;
719
    }
720
    dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
721
    if (procPtr != (Tcl_InterpDeleteProc **) NULL) {
722
        *procPtr = dPtr->proc;
723
    }
724
    return dPtr->clientData;
725
}
726
 
727
/*
728
 *----------------------------------------------------------------------
729
 *
730
 * DeleteInterpProc --
731
 *
732
 *      Helper procedure to delete an interpreter. This procedure is
733
 *      called when the last call to Tcl_Preserve on this interpreter
734
 *      is matched by a call to Tcl_Release. The procedure cleans up
735
 *      all resources used in the interpreter and calls all currently
736
 *      registered interpreter deletion callbacks.
737
 *
738
 * Results:
739
 *      None.
740
 *
741
 * Side effects:
742
 *      Whatever the interpreter deletion callbacks do. Frees resources
743
 *      used by the interpreter.
744
 *
745
 *----------------------------------------------------------------------
746
 */
747
 
748
static void
749
DeleteInterpProc(interp)
750
    Tcl_Interp *interp;                 /* Interpreter to delete. */
751
{
752
    Interp *iPtr = (Interp *) interp;
753
    Tcl_HashEntry *hPtr;
754
    Tcl_HashSearch search;
755
    Tcl_HashTable *hTablePtr;
756
    AssocData *dPtr;
757
    ResolverScheme *resPtr, *nextResPtr;
758
    int i;
759
 
760
    /*
761
     * Punt if there is an error in the Tcl_Release/Tcl_Preserve matchup.
762
     */
763
 
764
    if (iPtr->numLevels > 0) {
765
        panic("DeleteInterpProc called with active evals");
766
    }
767
 
768
    /*
769
     * The interpreter should already be marked deleted; otherwise how
770
     * did we get here?
771
     */
772
 
773
    if (!(iPtr->flags & DELETED)) {
774
        panic("DeleteInterpProc called on interpreter not marked deleted");
775
    }
776
 
777
    /*
778
     * Dismantle everything in the global namespace except for the
779
     * "errorInfo" and "errorCode" variables. These remain until the
780
     * namespace is actually destroyed, in case any errors occur.
781
     *
782
     * Dismantle the namespace here, before we clear the assocData. If any
783
     * background errors occur here, they will be deleted below.
784
     */
785
 
786
    TclTeardownNamespace(iPtr->globalNsPtr);
787
 
788
    /*
789
     * Tear down the math function table.
790
     */
791
 
792
    for (hPtr = Tcl_FirstHashEntry(&iPtr->mathFuncTable, &search);
793
             hPtr != NULL;
794
             hPtr = Tcl_NextHashEntry(&search)) {
795
        ckfree((char *) Tcl_GetHashValue(hPtr));
796
    }
797
    Tcl_DeleteHashTable(&iPtr->mathFuncTable);
798
 
799
    /*
800
     * Invoke deletion callbacks; note that a callback can create new
801
     * callbacks, so we iterate.
802
     */
803
 
804
    while (iPtr->assocData != (Tcl_HashTable *) NULL) {
805
        hTablePtr = iPtr->assocData;
806
        iPtr->assocData = (Tcl_HashTable *) NULL;
807
        for (hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
808
                 hPtr != NULL;
809
                 hPtr = Tcl_FirstHashEntry(hTablePtr, &search)) {
810
            dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
811
            Tcl_DeleteHashEntry(hPtr);
812
            if (dPtr->proc != NULL) {
813
                (*dPtr->proc)(dPtr->clientData, interp);
814
            }
815
            ckfree((char *) dPtr);
816
        }
817
        Tcl_DeleteHashTable(hTablePtr);
818
        ckfree((char *) hTablePtr);
819
    }
820
 
821
    /*
822
     * Finish deleting the global namespace.
823
     */
824
 
825
    Tcl_DeleteNamespace((Tcl_Namespace *) iPtr->globalNsPtr);
826
 
827
    /*
828
     * Free up the result *after* deleting variables, since variable
829
     * deletion could have transferred ownership of the result string
830
     * to Tcl.
831
     */
832
 
833
    Tcl_FreeResult(interp);
834
    interp->result = NULL;
835
    Tcl_DecrRefCount(iPtr->objResultPtr);
836
    iPtr->objResultPtr = NULL;
837
    if (iPtr->errorInfo != NULL) {
838
        ckfree(iPtr->errorInfo);
839
        iPtr->errorInfo = NULL;
840
    }
841
    if (iPtr->errorCode != NULL) {
842
        ckfree(iPtr->errorCode);
843
        iPtr->errorCode = NULL;
844
    }
845
    if (iPtr->appendResult != NULL) {
846
        ckfree(iPtr->appendResult);
847
        iPtr->appendResult = NULL;
848
    }
849
    for (i = 0; i < NUM_REGEXPS; i++) {
850
        if (iPtr->patterns[i] == NULL) {
851
            break;
852
        }
853
        ckfree(iPtr->patterns[i]);
854
        ckfree((char *) iPtr->regexps[i]);
855
        iPtr->regexps[i] = NULL;
856
    }
857
    TclFreePackageInfo(iPtr);
858
    while (iPtr->tracePtr != NULL) {
859
        Trace *nextPtr = iPtr->tracePtr->nextPtr;
860
 
861
        ckfree((char *) iPtr->tracePtr);
862
        iPtr->tracePtr = nextPtr;
863
    }
864
    if (iPtr->execEnvPtr != NULL) {
865
        TclDeleteExecEnv(iPtr->execEnvPtr);
866
    }
867
    Tcl_DecrRefCount(iPtr->emptyObjPtr);
868
    iPtr->emptyObjPtr = NULL;
869
 
870
    resPtr = iPtr->resolverPtr;
871
    while (resPtr) {
872
        nextResPtr = resPtr->nextPtr;
873
        ckfree(resPtr->name);
874
        ckfree((char *) resPtr);
875
        resPtr = nextResPtr;
876
    }
877
 
878
    ckfree((char *) iPtr);
879
}
880
 
881
/*
882
 *----------------------------------------------------------------------
883
 *
884
 * Tcl_InterpDeleted --
885
 *
886
 *      Returns nonzero if the interpreter has been deleted with a call
887
 *      to Tcl_DeleteInterp.
888
 *
889
 * Results:
890
 *      Nonzero if the interpreter is deleted, zero otherwise.
891
 *
892
 * Side effects:
893
 *      None.
894
 *
895
 *----------------------------------------------------------------------
896
 */
897
 
898
int
899
Tcl_InterpDeleted(interp)
900
    Tcl_Interp *interp;
901
{
902
    return (((Interp *) interp)->flags & DELETED) ? 1 : 0;
903
}
904
 
905
/*
906
 *----------------------------------------------------------------------
907
 *
908
 * Tcl_DeleteInterp --
909
 *
910
 *      Ensures that the interpreter will be deleted eventually. If there
911
 *      are no Tcl_Preserve calls in effect for this interpreter, it is
912
 *      deleted immediately, otherwise the interpreter is deleted when
913
 *      the last Tcl_Preserve is matched by a call to Tcl_Release. In either
914
 *      case, the procedure runs the currently registered deletion callbacks.
915
 *
916
 * Results:
917
 *      None.
918
 *
919
 * Side effects:
920
 *      The interpreter is marked as deleted. The caller may still use it
921
 *      safely if there are calls to Tcl_Preserve in effect for the
922
 *      interpreter, but further calls to Tcl_Eval etc in this interpreter
923
 *      will fail.
924
 *
925
 *----------------------------------------------------------------------
926
 */
927
 
928
void
929
Tcl_DeleteInterp(interp)
930
    Tcl_Interp *interp;         /* Token for command interpreter (returned
931
                                 * by a previous call to Tcl_CreateInterp). */
932
{
933
    Interp *iPtr = (Interp *) interp;
934
 
935
    /*
936
     * If the interpreter has already been marked deleted, just punt.
937
     */
938
 
939
    if (iPtr->flags & DELETED) {
940
        return;
941
    }
942
 
943
    /*
944
     * Mark the interpreter as deleted. No further evals will be allowed.
945
     */
946
 
947
    iPtr->flags |= DELETED;
948
 
949
    /*
950
     * Ensure that the interpreter is eventually deleted.
951
     */
952
 
953
    Tcl_EventuallyFree((ClientData) interp,
954
            (Tcl_FreeProc *) DeleteInterpProc);
955
}
956
 
957
/*
958
 *----------------------------------------------------------------------
959
 *
960
 * HiddenCmdsDeleteProc --
961
 *
962
 *      Called on interpreter deletion to delete all the hidden
963
 *      commands in an interpreter.
964
 *
965
 * Results:
966
 *      None.
967
 *
968
 * Side effects:
969
 *      Frees up memory.
970
 *
971
 *----------------------------------------------------------------------
972
 */
973
 
974
static void
975
HiddenCmdsDeleteProc(clientData, interp)
976
    ClientData clientData;              /* The hidden commands hash table. */
977
    Tcl_Interp *interp;                 /* The interpreter being deleted. */
978
{
979
    Tcl_HashTable *hiddenCmdTblPtr;
980
    Tcl_HashEntry *hPtr;
981
    Tcl_HashSearch hSearch;
982
    Command *cmdPtr;
983
 
984
    hiddenCmdTblPtr = (Tcl_HashTable *) clientData;
985
    for (hPtr = Tcl_FirstHashEntry(hiddenCmdTblPtr, &hSearch);
986
             hPtr != NULL;
987
             hPtr = Tcl_FirstHashEntry(hiddenCmdTblPtr, &hSearch)) {
988
 
989
        /*
990
         * Cannot use Tcl_DeleteCommand because (a) the command is not
991
         * in the command hash table, and (b) that table has already been
992
         * deleted above. Hence we emulate what it does, below.
993
         */
994
 
995
        cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
996
 
997
        /*
998
         * The code here is tricky.  We can't delete the hash table entry
999
         * before invoking the deletion callback because there are cases
1000
         * where the deletion callback needs to invoke the command (e.g.
1001
         * object systems such as OTcl).  However, this means that the
1002
         * callback could try to delete or rename the command.  The deleted
1003
         * flag allows us to detect these cases and skip nested deletes.
1004
         */
1005
 
1006
        if (cmdPtr->deleted) {
1007
 
1008
            /*
1009
             * Another deletion is already in progress.  Remove the hash
1010
             * table entry now, but don't invoke a callback or free the
1011
             * command structure.
1012
             */
1013
 
1014
            Tcl_DeleteHashEntry(cmdPtr->hPtr);
1015
            cmdPtr->hPtr = NULL;
1016
            continue;
1017
        }
1018
        cmdPtr->deleted = 1;
1019
        if (cmdPtr->deleteProc != NULL) {
1020
            (*cmdPtr->deleteProc)(cmdPtr->deleteData);
1021
        }
1022
 
1023
        /*
1024
         * Bump the command epoch counter. This will invalidate all cached
1025
         * references that refer to this command.
1026
         */
1027
 
1028
        cmdPtr->cmdEpoch++;
1029
 
1030
        /*
1031
         * Don't use hPtr to delete the hash entry here, because it's
1032
         * possible that the deletion callback renamed the command.
1033
         * Instead, use cmdPtr->hptr, and make sure that no-one else
1034
         * has already deleted the hash entry.
1035
         */
1036
 
1037
        if (cmdPtr->hPtr != NULL) {
1038
            Tcl_DeleteHashEntry(cmdPtr->hPtr);
1039
        }
1040
 
1041
        /*
1042
         * Now free the Command structure, unless there is another reference
1043
         * to it from a CmdName Tcl object in some ByteCode code
1044
         * sequence. In that case, delay the cleanup until all references
1045
         * are either discarded (when a ByteCode is freed) or replaced by a
1046
         * new reference (when a cached CmdName Command reference is found
1047
         * to be invalid and TclExecuteByteCode looks up the command in the
1048
         * command hashtable).
1049
         */
1050
 
1051
        TclCleanupCommand(cmdPtr);
1052
    }
1053
    Tcl_DeleteHashTable(hiddenCmdTblPtr);
1054
    ckfree((char *) hiddenCmdTblPtr);
1055
}
1056
 
1057
/*
1058
 *----------------------------------------------------------------------
1059
 *
1060
 * Tcl_HideCommand --
1061
 *
1062
 *      Makes a command hidden so that it cannot be invoked from within
1063
 *      an interpreter, only from within an ancestor.
1064
 *
1065
 * Results:
1066
 *      A standard Tcl result; also leaves a message in interp->result
1067
 *      if an error occurs.
1068
 *
1069
 * Side effects:
1070
 *      Removes a command from the command table and create an entry
1071
 *      into the hidden command table under the specified token name.
1072
 *
1073
 *----------------------------------------------------------------------
1074
 */
1075
 
1076
int
1077
Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
1078
    Tcl_Interp *interp;         /* Interpreter in which to hide command. */
1079
    char *cmdName;              /* Name of command to hide. */
1080
    char *hiddenCmdToken;       /* Token name of the to-be-hidden command. */
1081
{
1082
    Interp *iPtr = (Interp *) interp;
1083
    Tcl_Command cmd;
1084
    Command *cmdPtr;
1085
    Tcl_HashTable *hTblPtr;
1086
    Tcl_HashEntry *hPtr;
1087
    int new;
1088
 
1089
    if (iPtr->flags & DELETED) {
1090
 
1091
        /*
1092
         * The interpreter is being deleted. Do not create any new
1093
         * structures, because it is not safe to modify the interpreter.
1094
         */
1095
 
1096
        return TCL_ERROR;
1097
    }
1098
 
1099
    /*
1100
     * Disallow hiding of commands that are currently in a namespace or
1101
     * renaming (as part of hiding) into a namespace.
1102
     *
1103
     * (because the current implementation with a single global table
1104
     *  and the needed uniqueness of names cause problems with namespaces)
1105
     *
1106
     * we don't need to check for "::" in cmdName because the real check is
1107
     * on the nsPtr below.
1108
     *
1109
     * hiddenCmdToken is just a string which is not interpreted in any way.
1110
     * It may contain :: but the string is not interpreted as a namespace
1111
     * qualifier command name. Thus, hiding foo::bar to foo::bar and then
1112
     * trying to expose or invoke ::foo::bar will NOT work; but if the
1113
     * application always uses the same strings it will get consistent
1114
     * behaviour.
1115
     *
1116
     * But as we currently limit ourselves to the global namespace only
1117
     * for the source, in order to avoid potential confusion,
1118
     * lets prevent "::" in the token too.  --dl
1119
     */
1120
 
1121
    if (strstr(hiddenCmdToken, "::") != NULL) {
1122
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1123
                "cannot use namespace qualifiers as hidden command",
1124
                "token (rename)", (char *) NULL);
1125
        return TCL_ERROR;
1126
    }
1127
 
1128
    /*
1129
     * Find the command to hide. An error is returned if cmdName can't
1130
     * be found. Look up the command only from the global namespace.
1131
     * Full path of the command must be given if using namespaces.
1132
     */
1133
 
1134
    cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
1135
            /*flags*/ TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
1136
    if (cmd == (Tcl_Command) NULL) {
1137
        return TCL_ERROR;
1138
    }
1139
    cmdPtr = (Command *) cmd;
1140
 
1141
    /*
1142
     * Check that the command is really in global namespace
1143
     */
1144
 
1145
    if ( cmdPtr->nsPtr != iPtr->globalNsPtr ) {
1146
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1147
                "can only hide global namespace commands",
1148
                " (use rename then hide)", (char *) NULL);
1149
        return TCL_ERROR;
1150
    }
1151
 
1152
    /*
1153
     * Initialize the hidden command table if necessary.
1154
     */
1155
 
1156
    hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclHiddenCmds",
1157
            NULL);
1158
    if (hTblPtr == (Tcl_HashTable *) NULL) {
1159
        hTblPtr = (Tcl_HashTable *)
1160
                ckalloc((unsigned) sizeof(Tcl_HashTable));
1161
        Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS);
1162
        Tcl_SetAssocData(interp, "tclHiddenCmds", HiddenCmdsDeleteProc,
1163
                (ClientData) hTblPtr);
1164
    }
1165
 
1166
    /*
1167
     * It is an error to move an exposed command to a hidden command with
1168
     * hiddenCmdToken if a hidden command with the name hiddenCmdToken already
1169
     * exists.
1170
     */
1171
 
1172
    hPtr = Tcl_CreateHashEntry(hTblPtr, hiddenCmdToken, &new);
1173
    if (!new) {
1174
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1175
                "hidden command named \"", hiddenCmdToken, "\" already exists",
1176
                (char *) NULL);
1177
        return TCL_ERROR;
1178
    }
1179
 
1180
    /*
1181
     * Nb : This code is currently 'like' a rename to a specialy set apart
1182
     * name table. Changes here and in TclRenameCommand must
1183
     * be kept in synch untill the common parts are actually
1184
     * factorized out.
1185
     */
1186
 
1187
    /*
1188
     * Remove the hash entry for the command from the interpreter command
1189
     * table. This is like deleting the command, so bump its command epoch;
1190
     * this invalidates any cached references that point to the command.
1191
     */
1192
 
1193
    if (cmdPtr->hPtr != NULL) {
1194
        Tcl_DeleteHashEntry(cmdPtr->hPtr);
1195
        cmdPtr->hPtr = (Tcl_HashEntry *) NULL;
1196
        cmdPtr->cmdEpoch++;
1197
    }
1198
 
1199
    /*
1200
     * Now link the hash table entry with the command structure.
1201
     * We ensured above that the nsPtr was right.
1202
     */
1203
 
1204
    cmdPtr->hPtr = hPtr;
1205
    Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
1206
 
1207
    /*
1208
     * If the command being hidden has a compile procedure, increment the
1209
     * interpreter's compileEpoch to invalidate its compiled code. This
1210
     * makes sure that we don't later try to execute old code compiled with
1211
     * command-specific (i.e., inline) bytecodes for the now-hidden
1212
     * command. This field is checked in Tcl_EvalObj and ObjInterpProc,
1213
     * and code whose compilation epoch doesn't match is recompiled.
1214
     */
1215
 
1216
    if (cmdPtr->compileProc != NULL) {
1217
        iPtr->compileEpoch++;
1218
    }
1219
    return TCL_OK;
1220
}
1221
 
1222
/*
1223
 *----------------------------------------------------------------------
1224
 *
1225
 * Tcl_ExposeCommand --
1226
 *
1227
 *      Makes a previously hidden command callable from inside the
1228
 *      interpreter instead of only by its ancestors.
1229
 *
1230
 * Results:
1231
 *      A standard Tcl result. If an error occurs, a message is left
1232
 *      in interp->result.
1233
 *
1234
 * Side effects:
1235
 *      Moves commands from one hash table to another.
1236
 *
1237
 *----------------------------------------------------------------------
1238
 */
1239
 
1240
int
1241
Tcl_ExposeCommand(interp, hiddenCmdToken, cmdName)
1242
    Tcl_Interp *interp;         /* Interpreter in which to make command
1243
                                 * callable. */
1244
    char *hiddenCmdToken;       /* Name of hidden command. */
1245
    char *cmdName;              /* Name of to-be-exposed command. */
1246
{
1247
    Interp *iPtr = (Interp *) interp;
1248
    Command *cmdPtr;
1249
    Namespace *nsPtr;
1250
    Tcl_HashEntry *hPtr;
1251
    Tcl_HashTable *hTblPtr;
1252
    int new;
1253
 
1254
    if (iPtr->flags & DELETED) {
1255
        /*
1256
         * The interpreter is being deleted. Do not create any new
1257
         * structures, because it is not safe to modify the interpreter.
1258
         */
1259
 
1260
        return TCL_ERROR;
1261
    }
1262
 
1263
    /*
1264
     * Check that we have a regular name for the command
1265
     * (that the user is not trying to do an expose and a rename
1266
     *  (to another namespace) at the same time)
1267
     */
1268
 
1269
    if (strstr(cmdName, "::") != NULL) {
1270
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1271
                "can not expose to a namespace ",
1272
                "(use expose to toplevel, then rename)",
1273
                 (char *) NULL);
1274
        return TCL_ERROR;
1275
    }
1276
 
1277
    /*
1278
     * Find the hash table for the hidden commands; error out if there
1279
     * is none.
1280
     */
1281
 
1282
    hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclHiddenCmds",
1283
            NULL);
1284
    if (hTblPtr == NULL) {
1285
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1286
                "unknown hidden command \"", hiddenCmdToken,
1287
                "\"", (char *) NULL);
1288
        return TCL_ERROR;
1289
    }
1290
 
1291
    /*
1292
     * Get the command from the hidden command table:
1293
     */
1294
 
1295
    hPtr = Tcl_FindHashEntry(hTblPtr, hiddenCmdToken);
1296
    if (hPtr == (Tcl_HashEntry *) NULL) {
1297
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1298
                "unknown hidden command \"", hiddenCmdToken,
1299
                "\"", (char *) NULL);
1300
        return TCL_ERROR;
1301
    }
1302
    cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
1303
 
1304
 
1305
    /*
1306
     * Check that we have a true global namespace
1307
     * command (enforced by Tcl_HideCommand() but let's double
1308
     * check. (If it was not, we would not really know how to
1309
     * handle it).
1310
     */
1311
    if ( cmdPtr->nsPtr != iPtr->globalNsPtr ) {
1312
        /*
1313
         * This case is theoritically impossible,
1314
         * we might rather panic() than 'nicely' erroring out ?
1315
         */
1316
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1317
                "trying to expose a non global command name space command",
1318
                (char *) NULL);
1319
        return TCL_ERROR;
1320
    }
1321
 
1322
    /* This is the global table */
1323
    nsPtr = cmdPtr->nsPtr;
1324
 
1325
    /*
1326
     * It is an error to overwrite an existing exposed command as a result
1327
     * of exposing a previously hidden command.
1328
     */
1329
 
1330
    hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &new);
1331
    if (!new) {
1332
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1333
                "exposed command \"", cmdName,
1334
                "\" already exists", (char *) NULL);
1335
        return TCL_ERROR;
1336
    }
1337
 
1338
    /*
1339
     * Remove the hash entry for the command from the interpreter hidden
1340
     * command table.
1341
     */
1342
 
1343
    if (cmdPtr->hPtr != NULL) {
1344
        Tcl_DeleteHashEntry(cmdPtr->hPtr);
1345
        cmdPtr->hPtr = NULL;
1346
    }
1347
 
1348
    /*
1349
     * Now link the hash table entry with the command structure.
1350
     * This is like creating a new command, so deal with any shadowing
1351
     * of commands in the global namespace.
1352
     */
1353
 
1354
    cmdPtr->hPtr = hPtr;
1355
 
1356
    Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
1357
 
1358
    /*
1359
     * Not needed as we are only in the global namespace
1360
     * (but would be needed again if we supported namespace command hiding)
1361
     *
1362
     * TclResetShadowedCmdRefs(interp, cmdPtr);
1363
     */
1364
 
1365
 
1366
    /*
1367
     * If the command being exposed has a compile procedure, increment
1368
     * interpreter's compileEpoch to invalidate its compiled code. This
1369
     * makes sure that we don't later try to execute old code compiled
1370
     * assuming the command is hidden. This field is checked in Tcl_EvalObj
1371
     * and ObjInterpProc, and code whose compilation epoch doesn't match is
1372
     * recompiled.
1373
     */
1374
 
1375
    if (cmdPtr->compileProc != NULL) {
1376
        iPtr->compileEpoch++;
1377
    }
1378
    return TCL_OK;
1379
}
1380
 
1381
/*
1382
 *----------------------------------------------------------------------
1383
 *
1384
 * Tcl_CreateCommand --
1385
 *
1386
 *      Define a new command in a command table.
1387
 *
1388
 * Results:
1389
 *      The return value is a token for the command, which can
1390
 *      be used in future calls to Tcl_GetCommandName.
1391
 *
1392
 * Side effects:
1393
 *      If a command named cmdName already exists for interp, it is deleted.
1394
 *      In the future, when cmdName is seen as the name of a command by
1395
 *      Tcl_Eval, proc will be called. To support the bytecode interpreter,
1396
 *      the command is created with a wrapper Tcl_ObjCmdProc
1397
 *      (TclInvokeStringCommand) that eventially calls proc. When the
1398
 *      command is deleted from the table, deleteProc will be called.
1399
 *      See the manual entry for details on the calling sequence.
1400
 *
1401
 *----------------------------------------------------------------------
1402
 */
1403
 
1404
Tcl_Command
1405
Tcl_CreateCommand(interp, cmdName, proc, clientData, deleteProc)
1406
    Tcl_Interp *interp;         /* Token for command interpreter returned by
1407
                                 * a previous call to Tcl_CreateInterp. */
1408
    char *cmdName;              /* Name of command. If it contains namespace
1409
                                 * qualifiers, the new command is put in the
1410
                                 * specified namespace; otherwise it is put
1411
                                 * in the global namespace. */
1412
    Tcl_CmdProc *proc;          /* Procedure to associate with cmdName. */
1413
    ClientData clientData;      /* Arbitrary value passed to string proc. */
1414
    Tcl_CmdDeleteProc *deleteProc;
1415
                                /* If not NULL, gives a procedure to call
1416
                                 * when this command is deleted. */
1417
{
1418
    Interp *iPtr = (Interp *) interp;
1419
    ImportRef *oldRefPtr = NULL;
1420
    Namespace *nsPtr, *dummy1, *dummy2;
1421
    Command *cmdPtr, *refCmdPtr;
1422
    Tcl_HashEntry *hPtr;
1423
    char *tail;
1424
    int new, result;
1425
    ImportedCmdData *dataPtr;
1426
 
1427
    if (iPtr->flags & DELETED) {
1428
        /*
1429
         * The interpreter is being deleted.  Don't create any new
1430
         * commands; it's not safe to muck with the interpreter anymore.
1431
         */
1432
 
1433
        return (Tcl_Command) NULL;
1434
    }
1435
 
1436
    /*
1437
     * Determine where the command should reside. If its name contains
1438
     * namespace qualifiers, we put it in the specified namespace;
1439
     * otherwise, we always put it in the global namespace.
1440
     */
1441
 
1442
    if (strstr(cmdName, "::") != NULL) {
1443
        result = TclGetNamespaceForQualName(interp, cmdName,
1444
                (Namespace *) NULL, CREATE_NS_IF_UNKNOWN, &nsPtr,
1445
                &dummy1, &dummy2, &tail);
1446
        if ((result != TCL_OK) || (nsPtr == NULL) || (tail == NULL)) {
1447
            return (Tcl_Command) NULL;
1448
        }
1449
    } else {
1450
        nsPtr = iPtr->globalNsPtr;
1451
        tail = cmdName;
1452
    }
1453
 
1454
    hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
1455
    if (!new) {
1456
        /*
1457
         * Command already exists. Delete the old one.
1458
         * Be careful to preserve any existing import links so we can
1459
         * restore them down below.  That way, you can redefine a
1460
         * command and its import status will remain intact.
1461
         */
1462
 
1463
        cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
1464
        oldRefPtr = cmdPtr->importRefPtr;
1465
        cmdPtr->importRefPtr = NULL;
1466
 
1467
        Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
1468
        hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
1469
        if (!new) {
1470
            /*
1471
             * If the deletion callback recreated the command, just throw
1472
             * away the new command (if we try to delete it again, we
1473
             * could get stuck in an infinite loop).
1474
             */
1475
 
1476
             ckfree((char*) cmdPtr);
1477
        }
1478
    }
1479
    cmdPtr = (Command *) ckalloc(sizeof(Command));
1480
    Tcl_SetHashValue(hPtr, cmdPtr);
1481
    cmdPtr->hPtr = hPtr;
1482
    cmdPtr->nsPtr = nsPtr;
1483
    cmdPtr->refCount = 1;
1484
    cmdPtr->cmdEpoch = 0;
1485
    cmdPtr->compileProc = (CompileProc *) NULL;
1486
    cmdPtr->objProc = TclInvokeStringCommand;
1487
    cmdPtr->objClientData = (ClientData) cmdPtr;
1488
    cmdPtr->proc = proc;
1489
    cmdPtr->clientData = clientData;
1490
    cmdPtr->deleteProc = deleteProc;
1491
    cmdPtr->deleteData = clientData;
1492
    cmdPtr->deleted = 0;
1493
    cmdPtr->importRefPtr = NULL;
1494
 
1495
    /*
1496
     * Plug in any existing import references found above.  Be sure
1497
     * to update all of these references to point to the new command.
1498
     */
1499
 
1500
    if (oldRefPtr != NULL) {
1501
        cmdPtr->importRefPtr = oldRefPtr;
1502
        while (oldRefPtr != NULL) {
1503
            refCmdPtr = oldRefPtr->importedCmdPtr;
1504
            dataPtr = (ImportedCmdData*)refCmdPtr->objClientData;
1505
            dataPtr->realCmdPtr = cmdPtr;
1506
            oldRefPtr = oldRefPtr->nextPtr;
1507
        }
1508
    }
1509
 
1510
    /*
1511
     * We just created a command, so in its namespace and all of its parent
1512
     * namespaces, it may shadow global commands with the same name. If any
1513
     * shadowed commands are found, invalidate all cached command references
1514
     * in the affected namespaces.
1515
     */
1516
 
1517
    TclResetShadowedCmdRefs(interp, cmdPtr);
1518
    return (Tcl_Command) cmdPtr;
1519
}
1520
 
1521
/*
1522
 *----------------------------------------------------------------------
1523
 *
1524
 * Tcl_CreateObjCommand --
1525
 *
1526
 *      Define a new object-based command in a command table.
1527
 *
1528
 * Results:
1529
 *      The return value is a token for the command, which can
1530
 *      be used in future calls to Tcl_NameOfCommand.
1531
 *
1532
 * Side effects:
1533
 *      If no command named "cmdName" already exists for interp, one is
1534
 *      created. Otherwise, if a command does exist, then if the
1535
 *      object-based Tcl_ObjCmdProc is TclInvokeStringCommand, we assume
1536
 *      Tcl_CreateCommand was called previously for the same command and
1537
 *      just set its Tcl_ObjCmdProc to the argument "proc"; otherwise, we
1538
 *      delete the old command.
1539
 *
1540
 *      In the future, during bytecode evaluation when "cmdName" is seen as
1541
 *      the name of a command by Tcl_EvalObj or Tcl_Eval, the object-based
1542
 *      Tcl_ObjCmdProc proc will be called. When the command is deleted from
1543
 *      the table, deleteProc will be called. See the manual entry for
1544
 *      details on the calling sequence.
1545
 *
1546
 *----------------------------------------------------------------------
1547
 */
1548
 
1549
Tcl_Command
1550
Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc)
1551
    Tcl_Interp *interp;         /* Token for command interpreter (returned
1552
                                 * by previous call to Tcl_CreateInterp). */
1553
    char *cmdName;              /* Name of command. If it contains namespace
1554
                                 * qualifiers, the new command is put in the
1555
                                 * specified namespace; otherwise it is put
1556
                                 * in the global namespace. */
1557
    Tcl_ObjCmdProc *proc;       /* Object-based procedure to associate with
1558
                                 * name. */
1559
    ClientData clientData;      /* Arbitrary value to pass to object
1560
                                 * procedure. */
1561
    Tcl_CmdDeleteProc *deleteProc;
1562
                                /* If not NULL, gives a procedure to call
1563
                                 * when this command is deleted. */
1564
{
1565
    Interp *iPtr = (Interp *) interp;
1566
    ImportRef *oldRefPtr = NULL;
1567
    Namespace *nsPtr, *dummy1, *dummy2;
1568
    Command *cmdPtr, *refCmdPtr;
1569
    Tcl_HashEntry *hPtr;
1570
    char *tail;
1571
    int new, result;
1572
    ImportedCmdData *dataPtr;
1573
 
1574
    if (iPtr->flags & DELETED) {
1575
        /*
1576
         * The interpreter is being deleted.  Don't create any new
1577
         * commands;  it's not safe to muck with the interpreter anymore.
1578
         */
1579
 
1580
        return (Tcl_Command) NULL;
1581
    }
1582
 
1583
    /*
1584
     * Determine where the command should reside. If its name contains
1585
     * namespace qualifiers, we put it in the specified namespace;
1586
     * otherwise, we always put it in the global namespace.
1587
     */
1588
 
1589
    if (strstr(cmdName, "::") != NULL) {
1590
        result = TclGetNamespaceForQualName(interp, cmdName,
1591
                (Namespace *) NULL, CREATE_NS_IF_UNKNOWN, &nsPtr,
1592
                &dummy1, &dummy2, &tail);
1593
        if ((result != TCL_OK) || (nsPtr == NULL) || (tail == NULL)) {
1594
            return (Tcl_Command) NULL;
1595
        }
1596
    } else {
1597
        nsPtr = iPtr->globalNsPtr;
1598
        tail = cmdName;
1599
    }
1600
 
1601
    hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
1602
    if (!new) {
1603
        cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
1604
 
1605
        /*
1606
         * Command already exists. If its object-based Tcl_ObjCmdProc is
1607
         * TclInvokeStringCommand, we just set its Tcl_ObjCmdProc to the
1608
         * argument "proc". Otherwise, we delete the old command.
1609
         */
1610
 
1611
        if (cmdPtr->objProc == TclInvokeStringCommand) {
1612
            cmdPtr->objProc = proc;
1613
            cmdPtr->objClientData = clientData;
1614
            cmdPtr->deleteProc = deleteProc;
1615
            cmdPtr->deleteData = clientData;
1616
            return (Tcl_Command) cmdPtr;
1617
        }
1618
 
1619
        /*
1620
         * Otherwise, we delete the old command.  Be careful to preserve
1621
         * any existing import links so we can restore them down below.
1622
         * That way, you can redefine a command and its import status
1623
         * will remain intact.
1624
         */
1625
 
1626
        oldRefPtr = cmdPtr->importRefPtr;
1627
        cmdPtr->importRefPtr = NULL;
1628
 
1629
        Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
1630
        hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
1631
        if (!new) {
1632
            /*
1633
             * If the deletion callback recreated the command, just throw
1634
             * away the new command (if we try to delete it again, we
1635
             * could get stuck in an infinite loop).
1636
             */
1637
 
1638
             ckfree((char *) Tcl_GetHashValue(hPtr));
1639
        }
1640
    }
1641
    cmdPtr = (Command *) ckalloc(sizeof(Command));
1642
    Tcl_SetHashValue(hPtr, cmdPtr);
1643
    cmdPtr->hPtr = hPtr;
1644
    cmdPtr->nsPtr = nsPtr;
1645
    cmdPtr->refCount = 1;
1646
    cmdPtr->cmdEpoch = 0;
1647
    cmdPtr->compileProc = (CompileProc *) NULL;
1648
    cmdPtr->objProc = proc;
1649
    cmdPtr->objClientData = clientData;
1650
    cmdPtr->proc = TclInvokeObjectCommand;
1651
    cmdPtr->clientData = (ClientData) cmdPtr;
1652
    cmdPtr->deleteProc = deleteProc;
1653
    cmdPtr->deleteData = clientData;
1654
    cmdPtr->deleted = 0;
1655
    cmdPtr->importRefPtr = NULL;
1656
 
1657
    /*
1658
     * Plug in any existing import references found above.  Be sure
1659
     * to update all of these references to point to the new command.
1660
     */
1661
 
1662
    if (oldRefPtr != NULL) {
1663
        cmdPtr->importRefPtr = oldRefPtr;
1664
        while (oldRefPtr != NULL) {
1665
            refCmdPtr = oldRefPtr->importedCmdPtr;
1666
            dataPtr = (ImportedCmdData*)refCmdPtr->objClientData;
1667
            dataPtr->realCmdPtr = cmdPtr;
1668
            oldRefPtr = oldRefPtr->nextPtr;
1669
        }
1670
    }
1671
 
1672
    /*
1673
     * We just created a command, so in its namespace and all of its parent
1674
     * namespaces, it may shadow global commands with the same name. If any
1675
     * shadowed commands are found, invalidate all cached command references
1676
     * in the affected namespaces.
1677
     */
1678
 
1679
    TclResetShadowedCmdRefs(interp, cmdPtr);
1680
    return (Tcl_Command) cmdPtr;
1681
}
1682
 
1683
/*
1684
 *----------------------------------------------------------------------
1685
 *
1686
 * TclInvokeStringCommand --
1687
 *
1688
 *      "Wrapper" Tcl_ObjCmdProc used to call an existing string-based
1689
 *      Tcl_CmdProc if no object-based procedure exists for a command. A
1690
 *      pointer to this procedure is stored as the Tcl_ObjCmdProc in a
1691
 *      Command structure. It simply turns around and calls the string
1692
 *      Tcl_CmdProc in the Command structure.
1693
 *
1694
 * Results:
1695
 *      A standard Tcl object result value.
1696
 *
1697
 * Side effects:
1698
 *      Besides those side effects of the called Tcl_CmdProc,
1699
 *      TclInvokeStringCommand allocates and frees storage.
1700
 *
1701
 *----------------------------------------------------------------------
1702
 */
1703
 
1704
int
1705
TclInvokeStringCommand(clientData, interp, objc, objv)
1706
    ClientData clientData;      /* Points to command's Command structure. */
1707
    Tcl_Interp *interp;         /* Current interpreter. */
1708
    register int objc;          /* Number of arguments. */
1709
    Tcl_Obj *CONST objv[];      /* Argument objects. */
1710
{
1711
    register Command *cmdPtr = (Command *) clientData;
1712
    register int i;
1713
    int result;
1714
 
1715
    /*
1716
     * This procedure generates an argv array for the string arguments. It
1717
     * starts out with stack-allocated space but uses dynamically-allocated
1718
     * storage if needed.
1719
     */
1720
 
1721
#define NUM_ARGS 20
1722
    char *(argStorage[NUM_ARGS]);
1723
    char **argv = argStorage;
1724
 
1725
    /*
1726
     * Create the string argument array "argv". Make sure argv is large
1727
     * enough to hold the objc arguments plus 1 extra for the zero
1728
     * end-of-argv word.
1729
     * THIS FAILS IF ANY ARGUMENT OBJECT CONTAINS AN EMBEDDED NULL.
1730
     */
1731
 
1732
    if ((objc + 1) > NUM_ARGS) {
1733
        argv = (char **) ckalloc((unsigned)(objc + 1) * sizeof(char *));
1734
    }
1735
 
1736
    for (i = 0;  i < objc;  i++) {
1737
        argv[i] = Tcl_GetStringFromObj(objv[i], (int *) NULL);
1738
    }
1739
    argv[objc] = 0;
1740
 
1741
    /*
1742
     * Invoke the command's string-based Tcl_CmdProc.
1743
     */
1744
 
1745
    result = (*cmdPtr->proc)(cmdPtr->clientData, interp, objc, argv);
1746
 
1747
    /*
1748
     * Free the argv array if malloc'ed storage was used.
1749
     */
1750
 
1751
    if (argv != argStorage) {
1752
        ckfree((char *) argv);
1753
    }
1754
    return result;
1755
#undef NUM_ARGS
1756
}
1757
 
1758
/*
1759
 *----------------------------------------------------------------------
1760
 *
1761
 * TclInvokeObjectCommand --
1762
 *
1763
 *      "Wrapper" Tcl_CmdProc used to call an existing object-based
1764
 *      Tcl_ObjCmdProc if no string-based procedure exists for a command.
1765
 *      A pointer to this procedure is stored as the Tcl_CmdProc in a
1766
 *      Command structure. It simply turns around and calls the object
1767
 *      Tcl_ObjCmdProc in the Command structure.
1768
 *
1769
 * Results:
1770
 *      A standard Tcl string result value.
1771
 *
1772
 * Side effects:
1773
 *      Besides those side effects of the called Tcl_CmdProc,
1774
 *      TclInvokeStringCommand allocates and frees storage.
1775
 *
1776
 *----------------------------------------------------------------------
1777
 */
1778
 
1779
int
1780
TclInvokeObjectCommand(clientData, interp, argc, argv)
1781
    ClientData clientData;      /* Points to command's Command structure. */
1782
    Tcl_Interp *interp;         /* Current interpreter. */
1783
    int argc;                   /* Number of arguments. */
1784
    register char **argv;       /* Argument strings. */
1785
{
1786
    Command *cmdPtr = (Command *) clientData;
1787
    register Tcl_Obj *objPtr;
1788
    register int i;
1789
    int length, result;
1790
 
1791
    /*
1792
     * This procedure generates an objv array for object arguments that hold
1793
     * the argv strings. It starts out with stack-allocated space but uses
1794
     * dynamically-allocated storage if needed.
1795
     */
1796
 
1797
#define NUM_ARGS 20
1798
    Tcl_Obj *(argStorage[NUM_ARGS]);
1799
    register Tcl_Obj **objv = argStorage;
1800
 
1801
    /*
1802
     * Create the object argument array "objv". Make sure objv is large
1803
     * enough to hold the objc arguments plus 1 extra for the zero
1804
     * end-of-objv word.
1805
     */
1806
 
1807
    if ((argc + 1) > NUM_ARGS) {
1808
        objv = (Tcl_Obj **)
1809
            ckalloc((unsigned)(argc + 1) * sizeof(Tcl_Obj *));
1810
    }
1811
 
1812
    for (i = 0;  i < argc;  i++) {
1813
        length = strlen(argv[i]);
1814
        TclNewObj(objPtr);
1815
        TclInitStringRep(objPtr, argv[i], length);
1816
        Tcl_IncrRefCount(objPtr);
1817
        objv[i] = objPtr;
1818
    }
1819
    objv[argc] = 0;
1820
 
1821
    /*
1822
     * Invoke the command's object-based Tcl_ObjCmdProc.
1823
     */
1824
 
1825
    result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, argc, objv);
1826
 
1827
    /*
1828
     * Move the interpreter's object result to the string result,
1829
     * then reset the object result.
1830
     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULL BYTES.
1831
     */
1832
 
1833
    Tcl_SetResult(interp,
1834
            TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
1835
            TCL_VOLATILE);
1836
 
1837
    /*
1838
     * Decrement the ref counts for the argument objects created above,
1839
     * then free the objv array if malloc'ed storage was used.
1840
     */
1841
 
1842
    for (i = 0;  i < argc;  i++) {
1843
        objPtr = objv[i];
1844
        Tcl_DecrRefCount(objPtr);
1845
    }
1846
    if (objv != argStorage) {
1847
        ckfree((char *) objv);
1848
    }
1849
    return result;
1850
#undef NUM_ARGS
1851
}
1852
 
1853
/*
1854
 *----------------------------------------------------------------------
1855
 *
1856
 * TclRenameCommand --
1857
 *
1858
 *      Called to give an existing Tcl command a different name. Both the
1859
 *      old command name and the new command name can have "::" namespace
1860
 *      qualifiers. If the new command has a different namespace context,
1861
 *      the command will be moved to that namespace and will execute in
1862
 *      the context of that new namespace.
1863
 *
1864
 *      If the new command name is NULL or the null string, the command is
1865
 *      deleted.
1866
 *
1867
 * Results:
1868
 *      Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
1869
 *
1870
 * Side effects:
1871
 *      If anything goes wrong, an error message is returned in the
1872
 *      interpreter's result object.
1873
 *
1874
 *----------------------------------------------------------------------
1875
 */
1876
 
1877
int
1878
TclRenameCommand(interp, oldName, newName)
1879
    Tcl_Interp *interp;                 /* Current interpreter. */
1880
    char *oldName;                      /* Existing command name. */
1881
    char *newName;                      /* New command name. */
1882
{
1883
    Interp *iPtr = (Interp *) interp;
1884
    char *newTail;
1885
    Namespace *cmdNsPtr, *newNsPtr, *dummy1, *dummy2;
1886
    Tcl_Command cmd;
1887
    Command *cmdPtr;
1888
    Tcl_HashEntry *hPtr, *oldHPtr;
1889
    int new, result;
1890
 
1891
    /*
1892
     * Find the existing command. An error is returned if cmdName can't
1893
     * be found.
1894
     */
1895
 
1896
    cmd = Tcl_FindCommand(interp, oldName, (Tcl_Namespace *) NULL,
1897
        /*flags*/ 0);
1898
    cmdPtr = (Command *) cmd;
1899
    if (cmdPtr == NULL) {
1900
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "can't ",
1901
                ((newName == NULL)||(*newName == '\0'))? "delete":"rename",
1902
                " \"", oldName, "\": command doesn't exist", (char *) NULL);
1903
        return TCL_ERROR;
1904
    }
1905
    cmdNsPtr = cmdPtr->nsPtr;
1906
 
1907
    /*
1908
     * If the new command name is NULL or empty, delete the command. Do this
1909
     * with Tcl_DeleteCommandFromToken, since we already have the command.
1910
     */
1911
 
1912
    if ((newName == NULL) || (*newName == '\0')) {
1913
        Tcl_DeleteCommandFromToken(interp, cmd);
1914
        return TCL_OK;
1915
    }
1916
 
1917
    /*
1918
     * Make sure that the destination command does not already exist.
1919
     * The rename operation is like creating a command, so we should
1920
     * automatically create the containing namespaces just like
1921
     * Tcl_CreateCommand would.
1922
     */
1923
 
1924
    result = TclGetNamespaceForQualName(interp, newName, (Namespace *) NULL,
1925
            (CREATE_NS_IF_UNKNOWN | TCL_LEAVE_ERR_MSG),
1926
            &newNsPtr, &dummy1, &dummy2, &newTail);
1927
    if (result != TCL_OK) {
1928
        return result;
1929
    }
1930
    if ((newNsPtr == NULL) || (newTail == NULL)) {
1931
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1932
                 "can't rename to \"", newName, "\": bad command name",
1933
                 (char *) NULL);
1934
        return TCL_ERROR;
1935
    }
1936
    if (Tcl_FindHashEntry(&newNsPtr->cmdTable, newTail) != NULL) {
1937
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1938
                 "can't rename to \"", newName,
1939
                 "\": command already exists", (char *) NULL);
1940
        return TCL_ERROR;
1941
    }
1942
 
1943
 
1944
    /*
1945
     * Warning: any changes done in the code here are likely
1946
     * to be needed in Tcl_HideCommand() code too.
1947
     * (until the common parts are extracted out)     --dl
1948
     */
1949
 
1950
    /*
1951
     * Put the command in the new namespace so we can check for an alias
1952
     * loop. Since we are adding a new command to a namespace, we must
1953
     * handle any shadowing of the global commands that this might create.
1954
     */
1955
 
1956
    oldHPtr = cmdPtr->hPtr;
1957
    hPtr = Tcl_CreateHashEntry(&newNsPtr->cmdTable, newTail, &new);
1958
    Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
1959
    cmdPtr->hPtr = hPtr;
1960
    cmdPtr->nsPtr = newNsPtr;
1961
    TclResetShadowedCmdRefs(interp, cmdPtr);
1962
 
1963
    /*
1964
     * Now check for an alias loop. If we detect one, put everything back
1965
     * the way it was and report the error.
1966
     */
1967
 
1968
    result = TclPreventAliasLoop(interp, interp, (Tcl_Command) cmdPtr);
1969
    if (result != TCL_OK) {
1970
        Tcl_DeleteHashEntry(cmdPtr->hPtr);
1971
        cmdPtr->hPtr = oldHPtr;
1972
        cmdPtr->nsPtr = cmdNsPtr;
1973
        return result;
1974
    }
1975
 
1976
    /*
1977
     * The new command name is okay, so remove the command from its
1978
     * current namespace. This is like deleting the command, so bump
1979
     * the cmdEpoch to invalidate any cached references to the command.
1980
     */
1981
 
1982
    Tcl_DeleteHashEntry(oldHPtr);
1983
    cmdPtr->cmdEpoch++;
1984
 
1985
    /*
1986
     * If the command being renamed has a compile procedure, increment the
1987
     * interpreter's compileEpoch to invalidate its compiled code. This
1988
     * makes sure that we don't later try to execute old code compiled for
1989
     * the now-renamed command.
1990
     */
1991
 
1992
    if (cmdPtr->compileProc != NULL) {
1993
        iPtr->compileEpoch++;
1994
    }
1995
 
1996
    return TCL_OK;
1997
}
1998
 
1999
/*
2000
 *----------------------------------------------------------------------
2001
 *
2002
 * Tcl_SetCommandInfo --
2003
 *
2004
 *      Modifies various information about a Tcl command. Note that
2005
 *      this procedure will not change a command's namespace; use
2006
 *      Tcl_RenameCommand to do that. Also, the isNativeObjectProc
2007
 *      member of *infoPtr is ignored.
2008
 *
2009
 * Results:
2010
 *      If cmdName exists in interp, then the information at *infoPtr
2011
 *      is stored with the command in place of the current information
2012
 *      and 1 is returned. If the command doesn't exist then 0 is
2013
 *      returned.
2014
 *
2015
 * Side effects:
2016
 *      None.
2017
 *
2018
 *----------------------------------------------------------------------
2019
 */
2020
 
2021
int
2022
Tcl_SetCommandInfo(interp, cmdName, infoPtr)
2023
    Tcl_Interp *interp;                 /* Interpreter in which to look
2024
                                         * for command. */
2025
    char *cmdName;                      /* Name of desired command. */
2026
    Tcl_CmdInfo *infoPtr;               /* Where to store information about
2027
                                         * command. */
2028
{
2029
    Tcl_Command cmd;
2030
    Command *cmdPtr;
2031
 
2032
    cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
2033
            /*flags*/ 0);
2034
    if (cmd == (Tcl_Command) NULL) {
2035
        return 0;
2036
    }
2037
 
2038
    /*
2039
     * The isNativeObjectProc and nsPtr members of *infoPtr are ignored.
2040
     */
2041
 
2042
    cmdPtr = (Command *) cmd;
2043
    cmdPtr->proc = infoPtr->proc;
2044
    cmdPtr->clientData = infoPtr->clientData;
2045
    if (infoPtr->objProc == (Tcl_ObjCmdProc *) NULL) {
2046
        cmdPtr->objProc = TclInvokeStringCommand;
2047
        cmdPtr->objClientData = (ClientData) cmdPtr;
2048
    } else {
2049
        cmdPtr->objProc = infoPtr->objProc;
2050
        cmdPtr->objClientData = infoPtr->objClientData;
2051
    }
2052
    cmdPtr->deleteProc = infoPtr->deleteProc;
2053
    cmdPtr->deleteData = infoPtr->deleteData;
2054
    return 1;
2055
}
2056
 
2057
/*
2058
 *----------------------------------------------------------------------
2059
 *
2060
 * Tcl_GetCommandInfo --
2061
 *
2062
 *      Returns various information about a Tcl command.
2063
 *
2064
 * Results:
2065
 *      If cmdName exists in interp, then *infoPtr is modified to
2066
 *      hold information about cmdName and 1 is returned.  If the
2067
 *      command doesn't exist then 0 is returned and *infoPtr isn't
2068
 *      modified.
2069
 *
2070
 * Side effects:
2071
 *      None.
2072
 *
2073
 *----------------------------------------------------------------------
2074
 */
2075
 
2076
int
2077
Tcl_GetCommandInfo(interp, cmdName, infoPtr)
2078
    Tcl_Interp *interp;                 /* Interpreter in which to look
2079
                                         * for command. */
2080
    char *cmdName;                      /* Name of desired command. */
2081
    Tcl_CmdInfo *infoPtr;               /* Where to store information about
2082
                                         * command. */
2083
{
2084
    Tcl_Command cmd;
2085
    Command *cmdPtr;
2086
 
2087
    cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
2088
            /*flags*/ 0);
2089
    if (cmd == (Tcl_Command) NULL) {
2090
        return 0;
2091
    }
2092
 
2093
    /*
2094
     * Set isNativeObjectProc 1 if objProc was registered by a call to
2095
     * Tcl_CreateObjCommand. Otherwise set it to 0.
2096
     */
2097
 
2098
    cmdPtr = (Command *) cmd;
2099
    infoPtr->isNativeObjectProc =
2100
            (cmdPtr->objProc != TclInvokeStringCommand);
2101
    infoPtr->objProc = cmdPtr->objProc;
2102
    infoPtr->objClientData = cmdPtr->objClientData;
2103
    infoPtr->proc = cmdPtr->proc;
2104
    infoPtr->clientData = cmdPtr->clientData;
2105
    infoPtr->deleteProc = cmdPtr->deleteProc;
2106
    infoPtr->deleteData = cmdPtr->deleteData;
2107
    infoPtr->namespacePtr = (Tcl_Namespace *) cmdPtr->nsPtr;
2108
    return 1;
2109
}
2110
 
2111
/*
2112
 *----------------------------------------------------------------------
2113
 *
2114
 * Tcl_GetCommandName --
2115
 *
2116
 *      Given a token returned by Tcl_CreateCommand, this procedure
2117
 *      returns the current name of the command (which may have changed
2118
 *      due to renaming).
2119
 *
2120
 * Results:
2121
 *      The return value is the name of the given command.
2122
 *
2123
 * Side effects:
2124
 *      None.
2125
 *
2126
 *----------------------------------------------------------------------
2127
 */
2128
 
2129
char *
2130
Tcl_GetCommandName(interp, command)
2131
    Tcl_Interp *interp;         /* Interpreter containing the command. */
2132
    Tcl_Command command;        /* Token for command returned by a previous
2133
                                 * call to Tcl_CreateCommand. The command
2134
                                 * must not have been deleted. */
2135
{
2136
    Command *cmdPtr = (Command *) command;
2137
 
2138
    if ((cmdPtr == NULL) || (cmdPtr->hPtr == NULL)) {
2139
 
2140
        /*
2141
         * This should only happen if command was "created" after the
2142
         * interpreter began to be deleted, so there isn't really any
2143
         * command. Just return an empty string.
2144
         */
2145
 
2146
        return "";
2147
    }
2148
    return Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr);
2149
}
2150
 
2151
/*
2152
 *----------------------------------------------------------------------
2153
 *
2154
 * Tcl_GetCommandFullName --
2155
 *
2156
 *      Given a token returned by, e.g., Tcl_CreateCommand or
2157
 *      Tcl_FindCommand, this procedure appends to an object the command's
2158
 *      full name, qualified by a sequence of parent namespace names. The
2159
 *      command's fully-qualified name may have changed due to renaming.
2160
 *
2161
 * Results:
2162
 *      None.
2163
 *
2164
 * Side effects:
2165
 *      The command's fully-qualified name is appended to the string
2166
 *      representation of objPtr.
2167
 *
2168
 *----------------------------------------------------------------------
2169
 */
2170
 
2171
void
2172
Tcl_GetCommandFullName(interp, command, objPtr)
2173
    Tcl_Interp *interp;         /* Interpreter containing the command. */
2174
    Tcl_Command command;        /* Token for command returned by a previous
2175
                                 * call to Tcl_CreateCommand. The command
2176
                                 * must not have been deleted. */
2177
    Tcl_Obj *objPtr;            /* Points to the object onto which the
2178
                                 * command's full name is appended. */
2179
 
2180
{
2181
    Interp *iPtr = (Interp *) interp;
2182
    register Command *cmdPtr = (Command *) command;
2183
    char *name;
2184
 
2185
    /*
2186
     * Add the full name of the containing namespace, followed by the "::"
2187
     * separator, and the command name.
2188
     */
2189
 
2190
    if (cmdPtr != NULL) {
2191
        if (cmdPtr->nsPtr != NULL) {
2192
            Tcl_AppendToObj(objPtr, cmdPtr->nsPtr->fullName, -1);
2193
            if (cmdPtr->nsPtr != iPtr->globalNsPtr) {
2194
                Tcl_AppendToObj(objPtr, "::", 2);
2195
            }
2196
        }
2197
        if (cmdPtr->hPtr != NULL) {
2198
            name = Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr);
2199
            Tcl_AppendToObj(objPtr, name, -1);
2200
        }
2201
    }
2202
}
2203
 
2204
/*
2205
 *----------------------------------------------------------------------
2206
 *
2207
 * Tcl_DeleteCommand --
2208
 *
2209
 *      Remove the given command from the given interpreter.
2210
 *
2211
 * Results:
2212
 *      0 is returned if the command was deleted successfully.
2213
 *      -1 is returned if there didn't exist a command by that name.
2214
 *
2215
 * Side effects:
2216
 *      cmdName will no longer be recognized as a valid command for
2217
 *      interp.
2218
 *
2219
 *----------------------------------------------------------------------
2220
 */
2221
 
2222
int
2223
Tcl_DeleteCommand(interp, cmdName)
2224
    Tcl_Interp *interp;         /* Token for command interpreter (returned
2225
                                 * by a previous Tcl_CreateInterp call). */
2226
    char *cmdName;              /* Name of command to remove. */
2227
{
2228
    Tcl_Command cmd;
2229
 
2230
    /*
2231
     *  Find the desired command and delete it.
2232
     */
2233
 
2234
    cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
2235
            /*flags*/ 0);
2236
    if (cmd == (Tcl_Command) NULL) {
2237
        return -1;
2238
    }
2239
    return Tcl_DeleteCommandFromToken(interp, cmd);
2240
}
2241
 
2242
/*
2243
 *----------------------------------------------------------------------
2244
 *
2245
 * Tcl_DeleteCommandFromToken --
2246
 *
2247
 *      Removes the given command from the given interpreter. This procedure
2248
 *      resembles Tcl_DeleteCommand, but takes a Tcl_Command token instead
2249
 *      of a command name for efficiency.
2250
 *
2251
 * Results:
2252
 *      0 is returned if the command was deleted successfully.
2253
 *      -1 is returned if there didn't exist a command by that name.
2254
 *
2255
 * Side effects:
2256
 *      The command specified by "cmd" will no longer be recognized as a
2257
 *      valid command for "interp".
2258
 *
2259
 *----------------------------------------------------------------------
2260
 */
2261
 
2262
int
2263
Tcl_DeleteCommandFromToken(interp, cmd)
2264
    Tcl_Interp *interp;         /* Token for command interpreter returned by
2265
                                 * a previous call to Tcl_CreateInterp. */
2266
    Tcl_Command cmd;            /* Token for command to delete. */
2267
{
2268
    Interp *iPtr = (Interp *) interp;
2269
    Command *cmdPtr = (Command *) cmd;
2270
    ImportRef *refPtr, *nextRefPtr;
2271
    Tcl_Command importCmd;
2272
 
2273
    /*
2274
     * The code here is tricky.  We can't delete the hash table entry
2275
     * before invoking the deletion callback because there are cases
2276
     * where the deletion callback needs to invoke the command (e.g.
2277
     * object systems such as OTcl). However, this means that the
2278
     * callback could try to delete or rename the command. The deleted
2279
     * flag allows us to detect these cases and skip nested deletes.
2280
     */
2281
 
2282
    if (cmdPtr->deleted) {
2283
        /*
2284
         * Another deletion is already in progress.  Remove the hash
2285
         * table entry now, but don't invoke a callback or free the
2286
         * command structure.
2287
         */
2288
 
2289
        Tcl_DeleteHashEntry(cmdPtr->hPtr);
2290
        cmdPtr->hPtr = NULL;
2291
        return 0;
2292
    }
2293
 
2294
    /*
2295
     * If the command being deleted has a compile procedure, increment the
2296
     * interpreter's compileEpoch to invalidate its compiled code. This
2297
     * makes sure that we don't later try to execute old code compiled with
2298
     * command-specific (i.e., inline) bytecodes for the now-deleted
2299
     * command. This field is checked in Tcl_EvalObj and ObjInterpProc, and
2300
     * code whose compilation epoch doesn't match is recompiled.
2301
     */
2302
 
2303
    if (cmdPtr->compileProc != NULL) {
2304
        iPtr->compileEpoch++;
2305
    }
2306
 
2307
    cmdPtr->deleted = 1;
2308
    if (cmdPtr->deleteProc != NULL) {
2309
        /*
2310
         * Delete the command's client data. If this was an imported command
2311
         * created when a command was imported into a namespace, this client
2312
         * data will be a pointer to a ImportedCmdData structure describing
2313
         * the "real" command that this imported command refers to.
2314
         */
2315
 
2316
        (*cmdPtr->deleteProc)(cmdPtr->deleteData);
2317
    }
2318
 
2319
    /*
2320
     * Bump the command epoch counter. This will invalidate all cached
2321
     * references that point to this command.
2322
     */
2323
 
2324
    cmdPtr->cmdEpoch++;
2325
 
2326
    /*
2327
     * If this command was imported into other namespaces, then imported
2328
     * commands were created that refer back to this command. Delete these
2329
     * imported commands now.
2330
     */
2331
 
2332
    for (refPtr = cmdPtr->importRefPtr;  refPtr != NULL;
2333
            refPtr = nextRefPtr) {
2334
        nextRefPtr = refPtr->nextPtr;
2335
        importCmd = (Tcl_Command) refPtr->importedCmdPtr;
2336
        Tcl_DeleteCommandFromToken(interp, importCmd);
2337
    }
2338
 
2339
    /*
2340
     * Don't use hPtr to delete the hash entry here, because it's
2341
     * possible that the deletion callback renamed the command.
2342
     * Instead, use cmdPtr->hptr, and make sure that no-one else
2343
     * has already deleted the hash entry.
2344
     */
2345
 
2346
    if (cmdPtr->hPtr != NULL) {
2347
        Tcl_DeleteHashEntry(cmdPtr->hPtr);
2348
    }
2349
 
2350
    /*
2351
     * Mark the Command structure as no longer valid. This allows
2352
     * TclExecuteByteCode to recognize when a Command has logically been
2353
     * deleted and a pointer to this Command structure cached in a CmdName
2354
     * object is invalid. TclExecuteByteCode will look up the command again
2355
     * in the interpreter's command hashtable.
2356
     */
2357
 
2358
    cmdPtr->objProc = NULL;
2359
 
2360
    /*
2361
     * Now free the Command structure, unless there is another reference to
2362
     * it from a CmdName Tcl object in some ByteCode code sequence. In that
2363
     * case, delay the cleanup until all references are either discarded
2364
     * (when a ByteCode is freed) or replaced by a new reference (when a
2365
     * cached CmdName Command reference is found to be invalid and
2366
     * TclExecuteByteCode looks up the command in the command hashtable).
2367
     */
2368
 
2369
    TclCleanupCommand(cmdPtr);
2370
    return 0;
2371
}
2372
 
2373
/*
2374
 *----------------------------------------------------------------------
2375
 *
2376
 * TclCleanupCommand --
2377
 *
2378
 *      This procedure frees up a Command structure unless it is still
2379
 *      referenced from an interpreter's command hashtable or from a CmdName
2380
 *      Tcl object representing the name of a command in a ByteCode
2381
 *      instruction sequence.
2382
 *
2383
 * Results:
2384
 *      None.
2385
 *
2386
 * Side effects:
2387
 *      Memory gets freed unless a reference to the Command structure still
2388
 *      exists. In that case the cleanup is delayed until the command is
2389
 *      deleted or when the last ByteCode referring to it is freed.
2390
 *
2391
 *----------------------------------------------------------------------
2392
 */
2393
 
2394
void
2395
TclCleanupCommand(cmdPtr)
2396
    register Command *cmdPtr;   /* Points to the Command structure to
2397
                                 * be freed. */
2398
{
2399
    cmdPtr->refCount--;
2400
    if (cmdPtr->refCount <= 0) {
2401
        ckfree((char *) cmdPtr);
2402
    }
2403
}
2404
 
2405
/*
2406
 *----------------------------------------------------------------------
2407
 *
2408
 * Tcl_Eval --
2409
 *
2410
 *      Execute a Tcl command in a string.
2411
 *
2412
 * Results:
2413
 *      The return value is one of the return codes defined in tcl.h
2414
 *      (such as TCL_OK), and interp->result contains a string value
2415
 *      to supplement the return code. The value of interp->result
2416
 *      will persist only until the next call to Tcl_Eval or Tcl_EvalObj:
2417
 *      you must copy it or lose it!
2418
 *
2419
 * Side effects:
2420
 *      The string is compiled to produce a ByteCode object that holds the
2421
 *      command's bytecode instructions. However, this ByteCode object is
2422
 *      lost after executing the command. The command's execution will
2423
 *      almost certainly have side effects. interp->termOffset is set to the
2424
 *      offset of the character in "string" just after the last one
2425
 *      successfully compiled or executed.
2426
 *
2427
 *----------------------------------------------------------------------
2428
 */
2429
 
2430
int
2431
Tcl_Eval(interp, string)
2432
    Tcl_Interp *interp;         /* Token for command interpreter (returned
2433
                                 * by previous call to Tcl_CreateInterp). */
2434
    char *string;               /* Pointer to TCL command to execute. */
2435
{
2436
    register Tcl_Obj *cmdPtr;
2437
    int length = strlen(string);
2438
    int result;
2439
 
2440
    if (length > 0) {
2441
        /*
2442
         * Initialize a Tcl object from the command string.
2443
         */
2444
 
2445
        TclNewObj(cmdPtr);
2446
        TclInitStringRep(cmdPtr, string, length);
2447
        Tcl_IncrRefCount(cmdPtr);
2448
 
2449
        /*
2450
         * Compile and execute the bytecodes.
2451
         */
2452
 
2453
        result = Tcl_EvalObj(interp, cmdPtr);
2454
 
2455
        /*
2456
         * Move the interpreter's object result to the string result,
2457
         * then reset the object result.
2458
         * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
2459
         */
2460
 
2461
        Tcl_SetResult(interp,
2462
                TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
2463
                TCL_VOLATILE);
2464
 
2465
        /*
2466
         * Discard the Tcl object created to hold the command and its code.
2467
         */
2468
 
2469
        Tcl_DecrRefCount(cmdPtr);
2470
    } else {
2471
        /*
2472
         * An empty string. Just reset the interpreter's result.
2473
         */
2474
 
2475
        Tcl_ResetResult(interp);
2476
        result = TCL_OK;
2477
    }
2478
    return result;
2479
}
2480
 
2481
/*
2482
 *----------------------------------------------------------------------
2483
 *
2484
 * Tcl_EvalObj --
2485
 *
2486
 *      Execute Tcl commands stored in a Tcl object. These commands are
2487
 *      compiled into bytecodes if necessary.
2488
 *
2489
 * Results:
2490
 *      The return value is one of the return codes defined in tcl.h
2491
 *      (such as TCL_OK), and the interpreter's result contains a value
2492
 *      to supplement the return code.
2493
 *
2494
 * Side effects:
2495
 *      The object is converted, if necessary, to a ByteCode object that
2496
 *      holds the bytecode instructions for the commands. Executing the
2497
 *      commands will almost certainly have side effects that depend
2498
 *      on those commands.
2499
 *
2500
 *      Just as in Tcl_Eval, interp->termOffset is set to the offset of the
2501
 *      last character executed in the objPtr's string.
2502
 *
2503
 *----------------------------------------------------------------------
2504
 */
2505
 
2506
#undef Tcl_EvalObj
2507
 
2508
int
2509
Tcl_EvalObj(interp, objPtr)
2510
    Tcl_Interp *interp;                 /* Token for command interpreter
2511
                                         * (returned by a previous call to
2512
                                         * Tcl_CreateInterp). */
2513
    Tcl_Obj *objPtr;                    /* Pointer to object containing
2514
                                         * commands to execute. */
2515
{
2516
    register Interp *iPtr = (Interp *) interp;
2517
    int flags;                          /* Interp->evalFlags value when the
2518
                                         * procedure was called. */
2519
    register ByteCode* codePtr;         /* Tcl Internal type of bytecode. */
2520
    int oldCount = iPtr->cmdCount;      /* Used to tell whether any commands
2521
                                         * at all were executed. */
2522
    int numSrcChars;
2523
    register int result;
2524
    Namespace *namespacePtr;
2525
 
2526
    /*
2527
     * Reset both the interpreter's string and object results and clear out
2528
     * any error information. This makes sure that we return an empty
2529
     * result if there are no commands in the command string.
2530
     */
2531
 
2532
    Tcl_ResetResult(interp);
2533
 
2534
    /*
2535
     * Check depth of nested calls to Tcl_Eval:  if this gets too large,
2536
     * it's probably because of an infinite loop somewhere.
2537
     */
2538
 
2539
    iPtr->numLevels++;
2540
    if (iPtr->numLevels > iPtr->maxNestingDepth) {
2541
        iPtr->numLevels--;
2542
        Tcl_AppendToObj(Tcl_GetObjResult(interp),
2543
                "too many nested calls to Tcl_EvalObj (infinite loop?)", -1);
2544
        return TCL_ERROR;
2545
    }
2546
 
2547
    /*
2548
     * On the Mac, we will never reach the default recursion limit before blowing
2549
     * the stack. So we need to do a check here.
2550
     */
2551
 
2552
    if (TclpCheckStackSpace() == 0) {
2553
        /*NOTREACHED*/
2554
        iPtr->numLevels--;
2555
        Tcl_AppendToObj(Tcl_GetObjResult(interp),
2556
                "too many nested calls to Tcl_EvalObj (infinite loop?)", -1);
2557
        return TCL_ERROR;
2558
    }
2559
 
2560
    /*
2561
     * If the interpreter has been deleted, return an error.
2562
     */
2563
 
2564
    if (iPtr->flags & DELETED) {
2565
        Tcl_ResetResult(interp);
2566
        Tcl_AppendToObj(Tcl_GetObjResult(interp),
2567
                "attempt to call eval in deleted interpreter", -1);
2568
        Tcl_SetErrorCode(interp, "CORE", "IDELETE",
2569
                "attempt to call eval in deleted interpreter", (char *) NULL);
2570
        iPtr->numLevels--;
2571
        return TCL_ERROR;
2572
    }
2573
 
2574
    /*
2575
     * Get the ByteCode from the object. If it exists, make sure it hasn't
2576
     * been invalidated by, e.g., someone redefining a command with a
2577
     * compile procedure (this might make the compiled code wrong). If
2578
     * necessary, convert the object to be a ByteCode object and compile it.
2579
     * Also, if the code was compiled in/for a different interpreter,
2580
     * or for a different namespace, or for the same namespace but
2581
     * with different name resolution rules, we recompile it.
2582
     *
2583
     * Precompiled objects, however, are immutable and therefore
2584
     * they are not recompiled, even if the epoch has changed.
2585
     */
2586
 
2587
    if (iPtr->varFramePtr != NULL) {
2588
        namespacePtr = iPtr->varFramePtr->nsPtr;
2589
    } else {
2590
        namespacePtr = iPtr->globalNsPtr;
2591
    }
2592
 
2593
    if (objPtr->typePtr == &tclByteCodeType) {
2594
        codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
2595
 
2596
        if ((codePtr->iPtr != iPtr)
2597
                || (codePtr->compileEpoch != iPtr->compileEpoch)
2598
                || (codePtr->nsPtr != namespacePtr)
2599
                || (codePtr->nsEpoch != namespacePtr->resolverEpoch)) {
2600
            if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
2601
                if (codePtr->iPtr != iPtr) {
2602
                    panic("Tcl_EvalObj: compiled script jumped interps");
2603
                }
2604
                codePtr->compileEpoch = iPtr->compileEpoch;
2605
            } else {
2606
                tclByteCodeType.freeIntRepProc(objPtr);
2607
            }
2608
        }
2609
    }
2610
    if (objPtr->typePtr != &tclByteCodeType) {
2611
        /*
2612
         * First reset any error line number information.
2613
         */
2614
 
2615
        iPtr->errorLine = 1;   /* no correct line # information yet */
2616
        result = tclByteCodeType.setFromAnyProc(interp, objPtr);
2617
        if (result != TCL_OK) {
2618
            iPtr->numLevels--;
2619
            return result;
2620
        }
2621
    }
2622
    codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
2623
 
2624
    /*
2625
     * Extract then reset the compilation flags in the interpreter.
2626
     * Resetting the flags must be done after any compilation.
2627
     */
2628
 
2629
    flags = iPtr->evalFlags;
2630
    iPtr->evalFlags = 0;
2631
 
2632
    /*
2633
     * Execute the commands. If the code was compiled from an empty string,
2634
     * don't bother executing the code.
2635
     */
2636
 
2637
    numSrcChars = codePtr->numSrcChars;
2638
    if ((numSrcChars > 0) || (codePtr->flags & TCL_BYTECODE_PRECOMPILED)) {
2639
        /*
2640
         * Increment the code's ref count while it is being executed. If
2641
         * afterwards no references to it remain, free the code.
2642
         */
2643
 
2644
        codePtr->refCount++;
2645
        result = TclExecuteByteCode(interp, codePtr);
2646
        codePtr->refCount--;
2647
        if (codePtr->refCount <= 0) {
2648
            TclCleanupByteCode(codePtr);
2649
        }
2650
    } else {
2651
        Tcl_ResetResult(interp);
2652
        result = TCL_OK;
2653
    }
2654
 
2655
    /*
2656
     * If no commands at all were executed, check for asynchronous
2657
     * handlers so that they at least get one change to execute.
2658
     * This is needed to handle event loops written in Tcl with
2659
     * empty bodies.
2660
     */
2661
 
2662
    if ((oldCount == iPtr->cmdCount) && (Tcl_AsyncReady())) {
2663
        result = Tcl_AsyncInvoke(interp, result);
2664
    }
2665
 
2666
    /*
2667
     * Free up any extra resources that were allocated.
2668
     */
2669
 
2670
    iPtr->numLevels--;
2671
    if (iPtr->numLevels == 0) {
2672
        if (result == TCL_RETURN) {
2673
            result = TclUpdateReturnInfo(iPtr);
2674
        }
2675
        if ((result != TCL_OK) && (result != TCL_ERROR)
2676
                && !(flags & TCL_ALLOW_EXCEPTIONS)) {
2677
            Tcl_ResetResult(interp);
2678
            if (result == TCL_BREAK) {
2679
                Tcl_AppendToObj(Tcl_GetObjResult(interp),
2680
                        "invoked \"break\" outside of a loop", -1);
2681
            } else if (result == TCL_CONTINUE) {
2682
                Tcl_AppendToObj(Tcl_GetObjResult(interp),
2683
                        "invoked \"continue\" outside of a loop", -1);
2684
            } else {
2685
                char buf[50];
2686
                sprintf(buf, "command returned bad code: %d", result);
2687
                Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
2688
            }
2689
            result = TCL_ERROR;
2690
        }
2691
    }
2692
 
2693
    /*
2694
     * If an error occurred, record information about what was being
2695
     * executed when the error occurred.
2696
     */
2697
 
2698
    if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
2699
        char buf[200];
2700
        char *ellipsis = "";
2701
        char *bytes;
2702
        int length;
2703
 
2704
        /*
2705
         * Figure out how much of the command to print in the error
2706
         * message (up to a certain number of characters, or up to
2707
         * the first new-line).
2708
         * THIS FAILS IF THE OBJECT'S STRING REP CONTAINS A NULL.
2709
         */
2710
 
2711
        bytes = Tcl_GetStringFromObj(objPtr, &length);
2712
        length = TclMin(numSrcChars, length);
2713
        if (length > 150) {
2714
            length = 150;
2715
            ellipsis = " ...";
2716
        }
2717
 
2718
        if (!(iPtr->flags & ERR_IN_PROGRESS)) {
2719
            sprintf(buf, "\n    while executing\n\"%.*s%s\"",
2720
                    length, bytes, ellipsis);
2721
        } else {
2722
            sprintf(buf, "\n    invoked from within\n\"%.*s%s\"",
2723
                    length, bytes, ellipsis);
2724
        }
2725
        Tcl_AddObjErrorInfo(interp, buf, -1);
2726
    }
2727
 
2728
    /*
2729
     * Set the interpreter's termOffset member to the offset of the
2730
     * character just after the last one executed. We approximate the offset
2731
     * of the last character executed by using the number of characters
2732
     * compiled.
2733
     */
2734
 
2735
    iPtr->termOffset = numSrcChars;
2736
    iPtr->flags &= ~ERR_ALREADY_LOGGED;
2737
    return result;
2738
}
2739
 
2740
/*
2741
 *--------------------------------------------------------------
2742
 *
2743
 * Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean --
2744
 *
2745
 *      Procedures to evaluate an expression and return its value in a
2746
 *      particular form.
2747
 *
2748
 * Results:
2749
 *      Each of the procedures below returns a standard Tcl result. If an
2750
 *      error occurs then an error message is left in interp->result.
2751
 *      Otherwise the value of the expression, in the appropriate form, is
2752
 *      stored at *ptr. If the expression had a result that was
2753
 *      incompatible with the desired form then an error is returned.
2754
 *
2755
 * Side effects:
2756
 *      None.
2757
 *
2758
 *--------------------------------------------------------------
2759
 */
2760
 
2761
int
2762
Tcl_ExprLong(interp, string, ptr)
2763
    Tcl_Interp *interp;         /* Context in which to evaluate the
2764
                                 * expression. */
2765
    char *string;               /* Expression to evaluate. */
2766
    long *ptr;                  /* Where to store result. */
2767
{
2768
    register Tcl_Obj *exprPtr;
2769
    Tcl_Obj *resultPtr;
2770
    int length = strlen(string);
2771
    int result = TCL_OK;
2772
 
2773
    if (length > 0) {
2774
        exprPtr = Tcl_NewStringObj(string, length);
2775
        Tcl_IncrRefCount(exprPtr);
2776
        result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
2777
        if (result == TCL_OK) {
2778
            /*
2779
             * Store an integer based on the expression result.
2780
             */
2781
 
2782
            if (resultPtr->typePtr == &tclIntType) {
2783
                *ptr = resultPtr->internalRep.longValue;
2784
            } else if (resultPtr->typePtr == &tclDoubleType) {
2785
                *ptr = (long) resultPtr->internalRep.doubleValue;
2786
            } else {
2787
                Tcl_SetResult(interp,
2788
                        "expression didn't have numeric value", TCL_STATIC);
2789
                result = TCL_ERROR;
2790
            }
2791
            Tcl_DecrRefCount(resultPtr);  /* discard the result object */
2792
        } else {
2793
            /*
2794
             * Move the interpreter's object result to the string result,
2795
             * then reset the object result.
2796
             * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
2797
             */
2798
 
2799
            Tcl_SetResult(interp,
2800
                    TclGetStringFromObj(Tcl_GetObjResult(interp),
2801
                            (int *) NULL),
2802
                    TCL_VOLATILE);
2803
        }
2804
        Tcl_DecrRefCount(exprPtr);  /* discard the expression object */
2805
    } else {
2806
        /*
2807
         * An empty string. Just set the result integer to 0.
2808
         */
2809
 
2810
        *ptr = 0;
2811
    }
2812
    return result;
2813
}
2814
 
2815
int
2816
Tcl_ExprDouble(interp, string, ptr)
2817
    Tcl_Interp *interp;         /* Context in which to evaluate the
2818
                                 * expression. */
2819
    char *string;               /* Expression to evaluate. */
2820
    double *ptr;                /* Where to store result. */
2821
{
2822
    register Tcl_Obj *exprPtr;
2823
    Tcl_Obj *resultPtr;
2824
    int length = strlen(string);
2825
    int result = TCL_OK;
2826
 
2827
    if (length > 0) {
2828
        exprPtr = Tcl_NewStringObj(string, length);
2829
        Tcl_IncrRefCount(exprPtr);
2830
        result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
2831
        if (result == TCL_OK) {
2832
            /*
2833
             * Store a double  based on the expression result.
2834
             */
2835
 
2836
            if (resultPtr->typePtr == &tclIntType) {
2837
                *ptr = (double) resultPtr->internalRep.longValue;
2838
            } else if (resultPtr->typePtr == &tclDoubleType) {
2839
                *ptr = resultPtr->internalRep.doubleValue;
2840
            } else {
2841
                Tcl_SetResult(interp,
2842
                        "expression didn't have numeric value", TCL_STATIC);
2843
                result = TCL_ERROR;
2844
            }
2845
            Tcl_DecrRefCount(resultPtr);  /* discard the result object */
2846
        } else {
2847
            /*
2848
             * Move the interpreter's object result to the string result,
2849
             * then reset the object result.
2850
             * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
2851
             */
2852
 
2853
            Tcl_SetResult(interp,
2854
                    TclGetStringFromObj(Tcl_GetObjResult(interp),
2855
                            (int *) NULL),
2856
                    TCL_VOLATILE);
2857
        }
2858
        Tcl_DecrRefCount(exprPtr);  /* discard the expression object */
2859
    } else {
2860
        /*
2861
         * An empty string. Just set the result double to 0.0.
2862
         */
2863
 
2864
        *ptr = 0.0;
2865
    }
2866
    return result;
2867
}
2868
 
2869
int
2870
Tcl_ExprBoolean(interp, string, ptr)
2871
    Tcl_Interp *interp;         /* Context in which to evaluate the
2872
                                 * expression. */
2873
    char *string;               /* Expression to evaluate. */
2874
    int *ptr;                   /* Where to store 0/1 result. */
2875
{
2876
    register Tcl_Obj *exprPtr;
2877
    Tcl_Obj *resultPtr;
2878
    int length = strlen(string);
2879
    int result = TCL_OK;
2880
 
2881
    if (length > 0) {
2882
        exprPtr = Tcl_NewStringObj(string, length);
2883
        Tcl_IncrRefCount(exprPtr);
2884
        result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
2885
        if (result == TCL_OK) {
2886
            /*
2887
             * Store a boolean based on the expression result.
2888
             */
2889
 
2890
            if (resultPtr->typePtr == &tclIntType) {
2891
                *ptr = (resultPtr->internalRep.longValue != 0);
2892
            } else if (resultPtr->typePtr == &tclDoubleType) {
2893
                *ptr = (resultPtr->internalRep.doubleValue != 0.0);
2894
            } else {
2895
                result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
2896
            }
2897
            Tcl_DecrRefCount(resultPtr);  /* discard the result object */
2898
        }
2899
        if (result != TCL_OK) {
2900
            /*
2901
             * Move the interpreter's object result to the string result,
2902
             * then reset the object result.
2903
             * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
2904
             */
2905
 
2906
            Tcl_SetResult(interp,
2907
                    TclGetStringFromObj(Tcl_GetObjResult(interp),
2908
                            (int *) NULL),
2909
                    TCL_VOLATILE);
2910
        }
2911
        Tcl_DecrRefCount(exprPtr); /* discard the expression object */
2912
    } else {
2913
        /*
2914
         * An empty string. Just set the result boolean to 0 (false).
2915
         */
2916
 
2917
        *ptr = 0;
2918
    }
2919
    return result;
2920
}
2921
 
2922
/*
2923
 *--------------------------------------------------------------
2924
 *
2925
 * Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj --
2926
 *
2927
 *      Procedures to evaluate an expression in an object and return its
2928
 *      value in a particular form.
2929
 *
2930
 * Results:
2931
 *      Each of the procedures below returns a standard Tcl result
2932
 *      object. If an error occurs then an error message is left in the
2933
 *      interpreter's result. Otherwise the value of the expression, in the
2934
 *      appropriate form, is stored at *ptr. If the expression had a result
2935
 *      that was incompatible with the desired form then an error is
2936
 *      returned.
2937
 *
2938
 * Side effects:
2939
 *      None.
2940
 *
2941
 *--------------------------------------------------------------
2942
 */
2943
 
2944
int
2945
Tcl_ExprLongObj(interp, objPtr, ptr)
2946
    Tcl_Interp *interp;                 /* Context in which to evaluate the
2947
                                         * expression. */
2948
    register Tcl_Obj *objPtr;           /* Expression to evaluate. */
2949
    long *ptr;                          /* Where to store long result. */
2950
{
2951
    Tcl_Obj *resultPtr;
2952
    int result;
2953
 
2954
    result = Tcl_ExprObj(interp, objPtr, &resultPtr);
2955
    if (result == TCL_OK) {
2956
        if (resultPtr->typePtr == &tclIntType) {
2957
            *ptr = resultPtr->internalRep.longValue;
2958
        } else if (resultPtr->typePtr == &tclDoubleType) {
2959
            *ptr = (long) resultPtr->internalRep.doubleValue;
2960
        } else {
2961
            result = Tcl_GetLongFromObj(interp, resultPtr, ptr);
2962
            if (result != TCL_OK) {
2963
                return result;
2964
            }
2965
        }
2966
        Tcl_DecrRefCount(resultPtr);  /* discard the result object */
2967
    }
2968
    return result;
2969
}
2970
 
2971
int
2972
Tcl_ExprDoubleObj(interp, objPtr, ptr)
2973
    Tcl_Interp *interp;                 /* Context in which to evaluate the
2974
                                         * expression. */
2975
    register Tcl_Obj *objPtr;           /* Expression to evaluate. */
2976
    double *ptr;                        /* Where to store double result. */
2977
{
2978
    Tcl_Obj *resultPtr;
2979
    int result;
2980
 
2981
    result = Tcl_ExprObj(interp, objPtr, &resultPtr);
2982
    if (result == TCL_OK) {
2983
        if (resultPtr->typePtr == &tclIntType) {
2984
            *ptr = (double) resultPtr->internalRep.longValue;
2985
        } else if (resultPtr->typePtr == &tclDoubleType) {
2986
            *ptr = resultPtr->internalRep.doubleValue;
2987
        } else {
2988
            result = Tcl_GetDoubleFromObj(interp, resultPtr, ptr);
2989
            if (result != TCL_OK) {
2990
                return result;
2991
            }
2992
        }
2993
        Tcl_DecrRefCount(resultPtr);  /* discard the result object */
2994
    }
2995
    return result;
2996
}
2997
 
2998
int
2999
Tcl_ExprBooleanObj(interp, objPtr, ptr)
3000
    Tcl_Interp *interp;                 /* Context in which to evaluate the
3001
                                         * expression. */
3002
    register Tcl_Obj *objPtr;           /* Expression to evaluate. */
3003
    int *ptr;                           /* Where to store 0/1 result. */
3004
{
3005
    Tcl_Obj *resultPtr;
3006
    int result;
3007
 
3008
    result = Tcl_ExprObj(interp, objPtr, &resultPtr);
3009
    if (result == TCL_OK) {
3010
        if (resultPtr->typePtr == &tclIntType) {
3011
            *ptr = (resultPtr->internalRep.longValue != 0);
3012
        } else if (resultPtr->typePtr == &tclDoubleType) {
3013
            *ptr = (resultPtr->internalRep.doubleValue != 0.0);
3014
        } else {
3015
            result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
3016
            if (result != TCL_OK) {
3017
                return result;
3018
            }
3019
        }
3020
        Tcl_DecrRefCount(resultPtr);  /* discard the result object */
3021
    }
3022
    return result;
3023
}
3024
 
3025
/*
3026
 *----------------------------------------------------------------------
3027
 *
3028
 * TclInvoke --
3029
 *
3030
 *      Invokes a Tcl command, given an argv/argc, from either the
3031
 *      exposed or the hidden sets of commands in the given interpreter.
3032
 *      NOTE: The command is invoked in the current stack frame of
3033
 *      the interpreter, thus it can modify local variables.
3034
 *
3035
 * Results:
3036
 *      A standard Tcl result.
3037
 *
3038
 * Side effects:
3039
 *      Whatever the command does.
3040
 *
3041
 *----------------------------------------------------------------------
3042
 */
3043
 
3044
int
3045
TclInvoke(interp, argc, argv, flags)
3046
    Tcl_Interp *interp;         /* Where to invoke the command. */
3047
    int argc;                   /* Count of args. */
3048
    register char **argv;       /* The arg strings; argv[0] is the name of
3049
                                 * the command to invoke. */
3050
    int flags;                  /* Combination of flags controlling the
3051
                                 * call: TCL_INVOKE_HIDDEN and
3052
                                 * TCL_INVOKE_NO_UNKNOWN. */
3053
{
3054
    register Tcl_Obj *objPtr;
3055
    register int i;
3056
    int length, result;
3057
 
3058
    /*
3059
     * This procedure generates an objv array for object arguments that hold
3060
     * the argv strings. It starts out with stack-allocated space but uses
3061
     * dynamically-allocated storage if needed.
3062
     */
3063
 
3064
#define NUM_ARGS 20
3065
    Tcl_Obj *(objStorage[NUM_ARGS]);
3066
    register Tcl_Obj **objv = objStorage;
3067
 
3068
    /*
3069
     * Create the object argument array "objv". Make sure objv is large
3070
     * enough to hold the objc arguments plus 1 extra for the zero
3071
     * end-of-objv word.
3072
     */
3073
 
3074
    if ((argc + 1) > NUM_ARGS) {
3075
        objv = (Tcl_Obj **)
3076
            ckalloc((unsigned)(argc + 1) * sizeof(Tcl_Obj *));
3077
    }
3078
 
3079
    for (i = 0;  i < argc;  i++) {
3080
        length = strlen(argv[i]);
3081
        objv[i] = Tcl_NewStringObj(argv[i], length);
3082
        Tcl_IncrRefCount(objv[i]);
3083
    }
3084
    objv[argc] = 0;
3085
 
3086
    /*
3087
     * Use TclObjInterpProc to actually invoke the command.
3088
     */
3089
 
3090
    result = TclObjInvoke(interp, argc, objv, flags);
3091
 
3092
    /*
3093
     * Move the interpreter's object result to the string result,
3094
     * then reset the object result.
3095
     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
3096
     */
3097
 
3098
    Tcl_SetResult(interp,
3099
            TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
3100
            TCL_VOLATILE);
3101
 
3102
    /*
3103
     * Decrement the ref counts on the objv elements since we are done
3104
     * with them.
3105
     */
3106
 
3107
    for (i = 0;  i < argc;  i++) {
3108
        objPtr = objv[i];
3109
        Tcl_DecrRefCount(objPtr);
3110
    }
3111
 
3112
    /*
3113
     * Free the objv array if malloc'ed storage was used.
3114
     */
3115
 
3116
    if (objv != objStorage) {
3117
        ckfree((char *) objv);
3118
    }
3119
    return result;
3120
#undef NUM_ARGS
3121
}
3122
 
3123
/*
3124
 *----------------------------------------------------------------------
3125
 *
3126
 * TclGlobalInvoke --
3127
 *
3128
 *      Invokes a Tcl command, given an argv/argc, from either the
3129
 *      exposed or hidden sets of commands in the given interpreter.
3130
 *      NOTE: The command is invoked in the global stack frame of
3131
 *      the interpreter, thus it cannot see any current state on
3132
 *      the stack for that interpreter.
3133
 *
3134
 * Results:
3135
 *      A standard Tcl result.
3136
 *
3137
 * Side effects:
3138
 *      Whatever the command does.
3139
 *
3140
 *----------------------------------------------------------------------
3141
 */
3142
 
3143
int
3144
TclGlobalInvoke(interp, argc, argv, flags)
3145
    Tcl_Interp *interp;         /* Where to invoke the command. */
3146
    int argc;                   /* Count of args. */
3147
    register char **argv;       /* The arg strings; argv[0] is the name of
3148
                                 * the command to invoke. */
3149
    int flags;                  /* Combination of flags controlling the
3150
                                 * call: TCL_INVOKE_HIDDEN and
3151
                                 * TCL_INVOKE_NO_UNKNOWN. */
3152
{
3153
    register Interp *iPtr = (Interp *) interp;
3154
    int result;
3155
    CallFrame *savedVarFramePtr;
3156
 
3157
    savedVarFramePtr = iPtr->varFramePtr;
3158
    iPtr->varFramePtr = NULL;
3159
    result = TclInvoke(interp, argc, argv, flags);
3160
    iPtr->varFramePtr = savedVarFramePtr;
3161
    return result;
3162
}
3163
 
3164
/*
3165
 *----------------------------------------------------------------------
3166
 *
3167
 * TclObjInvokeGlobal --
3168
 *
3169
 *      Object version: Invokes a Tcl command, given an objv/objc, from
3170
 *      either the exposed or hidden set of commands in the given
3171
 *      interpreter.
3172
 *      NOTE: The command is invoked in the global stack frame of the
3173
 *      interpreter, thus it cannot see any current state on the
3174
 *      stack of that interpreter.
3175
 *
3176
 * Results:
3177
 *      A standard Tcl result.
3178
 *
3179
 * Side effects:
3180
 *      Whatever the command does.
3181
 *
3182
 *----------------------------------------------------------------------
3183
 */
3184
 
3185
int
3186
TclObjInvokeGlobal(interp, objc, objv, flags)
3187
    Tcl_Interp *interp;         /* Interpreter in which command is
3188
                                 * to be invoked. */
3189
    int objc;                   /* Count of arguments. */
3190
    Tcl_Obj *CONST objv[];      /* Argument value objects; objv[0]
3191
                                 * points to the name of the
3192
                                 * command to invoke. */
3193
    int flags;                  /* Combination of flags controlling
3194
                                 * the call: TCL_INVOKE_HIDDEN and
3195
                                 * TCL_INVOKE_NO_UNKNOWN. */
3196
{
3197
    register Interp *iPtr = (Interp *) interp;
3198
    int result;
3199
    CallFrame *savedVarFramePtr;
3200
 
3201
    savedVarFramePtr = iPtr->varFramePtr;
3202
    iPtr->varFramePtr = NULL;
3203
    result = TclObjInvoke(interp, objc, objv, flags);
3204
    iPtr->varFramePtr = savedVarFramePtr;
3205
    return result;
3206
}
3207
 
3208
/*
3209
 *----------------------------------------------------------------------
3210
 *
3211
 * TclObjInvoke --
3212
 *
3213
 *      Invokes a Tcl command, given an objv/objc, from either the
3214
 *      exposed or the hidden sets of commands in the given interpreter.
3215
 *
3216
 * Results:
3217
 *      A standard Tcl object result.
3218
 *
3219
 * Side effects:
3220
 *      Whatever the command does.
3221
 *
3222
 *----------------------------------------------------------------------
3223
 */
3224
 
3225
int
3226
TclObjInvoke(interp, objc, objv, flags)
3227
    Tcl_Interp *interp;         /* Interpreter in which command is
3228
                                 * to be invoked. */
3229
    int objc;                   /* Count of arguments. */
3230
    Tcl_Obj *CONST objv[];      /* Argument value objects; objv[0]
3231
                                 * points to the name of the
3232
                                 * command to invoke. */
3233
    int flags;                  /* Combination of flags controlling
3234
                                 * the call: TCL_INVOKE_HIDDEN and
3235
                                 * TCL_INVOKE_NO_UNKNOWN. */
3236
{
3237
    register Interp *iPtr = (Interp *) interp;
3238
    Tcl_HashTable *hTblPtr;     /* Table of hidden commands. */
3239
    char *cmdName;              /* Name of the command from objv[0]. */
3240
    register Tcl_HashEntry *hPtr;
3241
    Tcl_Command cmd;
3242
    Command *cmdPtr;
3243
    int localObjc;              /* Used to invoke "unknown" if the */
3244
    Tcl_Obj **localObjv = NULL; /* command is not found. */
3245
    register int i;
3246
    int length, result;
3247
    char *bytes;
3248
 
3249
    if (interp == (Tcl_Interp *) NULL) {
3250
        return TCL_ERROR;
3251
    }
3252
 
3253
    if ((objc < 1) || (objv == (Tcl_Obj **) NULL)) {
3254
        Tcl_AppendToObj(Tcl_GetObjResult(interp),
3255
                "illegal argument vector", -1);
3256
        return TCL_ERROR;
3257
    }
3258
 
3259
    /*
3260
     * THE FOLLOWING CODE FAILS IF THE STRING REP CONTAINS NULLS.
3261
     */
3262
 
3263
    cmdName = Tcl_GetStringFromObj(objv[0], (int *) NULL);
3264
    if (flags & TCL_INVOKE_HIDDEN) {
3265
        /*
3266
         * Find the table of hidden commands; error out if none.
3267
         */
3268
 
3269
        hTblPtr = (Tcl_HashTable *)
3270
                Tcl_GetAssocData(interp, "tclHiddenCmds", NULL);
3271
        if (hTblPtr == (Tcl_HashTable *) NULL) {
3272
            badhiddenCmdToken:
3273
            Tcl_ResetResult(interp);
3274
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
3275
                     "invalid hidden command name \"", cmdName, "\"",
3276
                     (char *) NULL);
3277
            return TCL_ERROR;
3278
        }
3279
        hPtr = Tcl_FindHashEntry(hTblPtr, cmdName);
3280
 
3281
        /*
3282
         * We never invoke "unknown" for hidden commands.
3283
         */
3284
 
3285
        if (hPtr == NULL) {
3286
            goto badhiddenCmdToken;
3287
        }
3288
        cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
3289
    } else {
3290
        cmdPtr = NULL;
3291
        cmd = Tcl_FindCommand(interp, cmdName,
3292
                (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
3293
        if (cmd != (Tcl_Command) NULL) {
3294
            cmdPtr = (Command *) cmd;
3295
        }
3296
        if (cmdPtr == NULL) {
3297
            if (!(flags & TCL_INVOKE_NO_UNKNOWN)) {
3298
                cmd = Tcl_FindCommand(interp, "unknown",
3299
                        (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
3300
                if (cmd != (Tcl_Command) NULL) {
3301
                    cmdPtr = (Command *) cmd;
3302
                }
3303
                if (cmdPtr != NULL) {
3304
                    localObjc = (objc + 1);
3305
                    localObjv = (Tcl_Obj **)
3306
                        ckalloc((unsigned) (sizeof(Tcl_Obj *) * localObjc));
3307
                    localObjv[0] = Tcl_NewStringObj("unknown", -1);
3308
                    Tcl_IncrRefCount(localObjv[0]);
3309
                    for (i = 0;  i < objc;  i++) {
3310
                        localObjv[i+1] = objv[i];
3311
                    }
3312
                    objc = localObjc;
3313
                    objv = localObjv;
3314
                }
3315
            }
3316
 
3317
            /*
3318
             * Check again if we found the command. If not, "unknown" is
3319
             * not present and we cannot help, or the caller said not to
3320
             * call "unknown" (they specified TCL_INVOKE_NO_UNKNOWN).
3321
             */
3322
 
3323
            if (cmdPtr == NULL) {
3324
                Tcl_ResetResult(interp);
3325
                Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
3326
                        "invalid command name \"",  cmdName, "\"",
3327
                         (char *) NULL);
3328
                return TCL_ERROR;
3329
            }
3330
        }
3331
    }
3332
 
3333
    /*
3334
     * Invoke the command procedure. First reset the interpreter's string
3335
     * and object results to their default empty values since they could
3336
     * have gotten changed by earlier invocations.
3337
     */
3338
 
3339
    Tcl_ResetResult(interp);
3340
    iPtr->cmdCount++;
3341
    result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, objc, objv);
3342
 
3343
    /*
3344
     * If an error occurred, record information about what was being
3345
     * executed when the error occurred.
3346
     */
3347
 
3348
    if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
3349
        Tcl_DString ds;
3350
 
3351
        Tcl_DStringInit(&ds);
3352
        if (!(iPtr->flags & ERR_IN_PROGRESS)) {
3353
            Tcl_DStringAppend(&ds, "\n    while invoking\n\"", -1);
3354
        } else {
3355
            Tcl_DStringAppend(&ds, "\n    invoked from within\n\"", -1);
3356
        }
3357
        for (i = 0;  i < objc;  i++) {
3358
            bytes = Tcl_GetStringFromObj(objv[i], &length);
3359
            Tcl_DStringAppend(&ds, bytes, length);
3360
            if (i < (objc - 1)) {
3361
                Tcl_DStringAppend(&ds, " ", -1);
3362
            } else if (Tcl_DStringLength(&ds) > 100) {
3363
                Tcl_DStringSetLength(&ds, 100);
3364
                Tcl_DStringAppend(&ds, "...", -1);
3365
                break;
3366
            }
3367
        }
3368
 
3369
        Tcl_DStringAppend(&ds, "\"", -1);
3370
        Tcl_AddObjErrorInfo(interp, Tcl_DStringValue(&ds), -1);
3371
        Tcl_DStringFree(&ds);
3372
        iPtr->flags &= ~ERR_ALREADY_LOGGED;
3373
    }
3374
 
3375
    /*
3376
     * Free any locally allocated storage used to call "unknown".
3377
     */
3378
 
3379
    if (localObjv != (Tcl_Obj **) NULL) {
3380
        ckfree((char *) localObjv);
3381
    }
3382
    return result;
3383
}
3384
 
3385
/*
3386
 *--------------------------------------------------------------
3387
 *
3388
 * Tcl_ExprString --
3389
 *
3390
 *      Evaluate an expression in a string and return its value in string
3391
 *      form.
3392
 *
3393
 * Results:
3394
 *      A standard Tcl result. If the result is TCL_OK, then the
3395
 *      interpreter's result is set to the string value of the
3396
 *      expression. If the result is TCL_OK, then interp->result
3397
 *      contains an error message.
3398
 *
3399
 * Side effects:
3400
 *      A Tcl object is allocated to hold a copy of the expression string.
3401
 *      This expression object is passed to Tcl_ExprObj and then
3402
 *      deallocated.
3403
 *
3404
 *--------------------------------------------------------------
3405
 */
3406
 
3407
int
3408
Tcl_ExprString(interp, string)
3409
    Tcl_Interp *interp;         /* Context in which to evaluate the
3410
                                 * expression. */
3411
    char *string;               /* Expression to evaluate. */
3412
{
3413
    register Tcl_Obj *exprPtr;
3414
    Tcl_Obj *resultPtr;
3415
    int length = strlen(string);
3416
    char buf[100];
3417
    int result = TCL_OK;
3418
 
3419
    if (length > 0) {
3420
        TclNewObj(exprPtr);
3421
        TclInitStringRep(exprPtr, string, length);
3422
        Tcl_IncrRefCount(exprPtr);
3423
 
3424
        result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
3425
        if (result == TCL_OK) {
3426
            /*
3427
             * Set the interpreter's string result from the result object.
3428
             */
3429
 
3430
            if (resultPtr->typePtr == &tclIntType) {
3431
                sprintf(buf, "%ld", resultPtr->internalRep.longValue);
3432
                Tcl_SetResult(interp, buf, TCL_VOLATILE);
3433
            } else if (resultPtr->typePtr == &tclDoubleType) {
3434
                Tcl_PrintDouble((Tcl_Interp *) NULL,
3435
                        resultPtr->internalRep.doubleValue, buf);
3436
                Tcl_SetResult(interp, buf, TCL_VOLATILE);
3437
            } else {
3438
                /*
3439
                 * Set interpreter's string result from the result object.
3440
                 * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
3441
                 */
3442
 
3443
                Tcl_SetResult(interp,
3444
                        TclGetStringFromObj(resultPtr, (int *) NULL),
3445
                        TCL_VOLATILE);
3446
            }
3447
            Tcl_DecrRefCount(resultPtr);  /* discard the result object */
3448
        } else {
3449
            /*
3450
             * Move the interpreter's object result to the string result,
3451
             * then reset the object result.
3452
             * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
3453
             */
3454
 
3455
            Tcl_SetResult(interp,
3456
                    TclGetStringFromObj(Tcl_GetObjResult(interp),
3457
                            (int *) NULL),
3458
                    TCL_VOLATILE);
3459
        }
3460
        Tcl_DecrRefCount(exprPtr); /* discard the expression object */
3461
    } else {
3462
        /*
3463
         * An empty string. Just set the interpreter's result to 0.
3464
         */
3465
 
3466
        Tcl_SetResult(interp, "0", TCL_VOLATILE);
3467
    }
3468
    return result;
3469
}
3470
 
3471
/*
3472
 *--------------------------------------------------------------
3473
 *
3474
 * Tcl_ExprObj --
3475
 *
3476
 *      Evaluate an expression in a Tcl_Obj.
3477
 *
3478
 * Results:
3479
 *      A standard Tcl object result. If the result is other than TCL_OK,
3480
 *      then the interpreter's result contains an error message. If the
3481
 *      result is TCL_OK, then a pointer to the expression's result value
3482
 *      object is stored in resultPtrPtr. In that case, the object's ref
3483
 *      count is incremented to reflect the reference returned to the
3484
 *      caller; the caller is then responsible for the resulting object
3485
 *      and must, for example, decrement the ref count when it is finished
3486
 *      with the object.
3487
 *
3488
 * Side effects:
3489
 *      Any side effects caused by subcommands in the expression, if any.
3490
 *      The interpreter result is not modified unless there is an error.
3491
 *
3492
 *--------------------------------------------------------------
3493
 */
3494
 
3495
int
3496
Tcl_ExprObj(interp, objPtr, resultPtrPtr)
3497
    Tcl_Interp *interp;         /* Context in which to evaluate the
3498
                                 * expression. */
3499
    register Tcl_Obj *objPtr;   /* Points to Tcl object containing
3500
                                 * expression to evaluate. */
3501
    Tcl_Obj **resultPtrPtr;     /* Where the Tcl_Obj* that is the expression
3502
                                 * result is stored if no errors occur. */
3503
{
3504
    Interp *iPtr = (Interp *) interp;
3505
    CompileEnv compEnv;         /* Compilation environment structure
3506
                                 * allocated in frame. */
3507
    register ByteCode *codePtr = NULL;
3508
                                /* Tcl Internal type of bytecode.
3509
                                 * Initialized to avoid compiler warning. */
3510
    AuxData *auxDataPtr;
3511
    Interp dummy;
3512
    Tcl_Obj *saveObjPtr;
3513
    char *string;
3514
    int result;
3515
    int i;
3516
 
3517
    /*
3518
     * Get the ByteCode from the object. If it exists, make sure it hasn't
3519
     * been invalidated by, e.g., someone redefining a command with a
3520
     * compile procedure (this might make the compiled code wrong). If
3521
     * necessary, convert the object to be a ByteCode object and compile it.
3522
     * Also, if the code was compiled in/for a different interpreter, we
3523
     * recompile it.
3524
     *
3525
     * Precompiled expressions, however, are immutable and therefore
3526
     * they are not recompiled, even if the epoch has changed.
3527
     *
3528
     * THIS FAILS IF THE OBJECT'S STRING REP HAS A NULL BYTE.
3529
     */
3530
 
3531
    if (objPtr->typePtr == &tclByteCodeType) {
3532
        codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
3533
        if ((codePtr->iPtr != iPtr)
3534
                || (codePtr->compileEpoch != iPtr->compileEpoch)) {
3535
            if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
3536
                if (codePtr->iPtr != iPtr) {
3537
                    panic("Tcl_ExprObj: compiled expression jumped interps");
3538
                }
3539
                codePtr->compileEpoch = iPtr->compileEpoch;
3540
            } else {
3541
                tclByteCodeType.freeIntRepProc(objPtr);
3542
                objPtr->typePtr = (Tcl_ObjType *) NULL;
3543
            }
3544
        }
3545
    }
3546
    if (objPtr->typePtr != &tclByteCodeType) {
3547
        int length;
3548
        string = Tcl_GetStringFromObj(objPtr, &length);
3549
        TclInitCompileEnv(interp, &compEnv, string);
3550
        result = TclCompileExpr(interp, string, string + length,
3551
                /*flags*/ 0, &compEnv);
3552
        if (result == TCL_OK) {
3553
            /*
3554
             * If the expression yielded no instructions (e.g., was empty),
3555
             * push an integer zero object as the expressions's result.
3556
             */
3557
 
3558
            if (compEnv.codeNext == NULL) {
3559
                int objIndex = TclObjIndexForString("0", 0,
3560
                        /*allocStrRep*/ 0, /*inHeap*/ 0, &compEnv);
3561
                Tcl_Obj *objPtr = compEnv.objArrayPtr[objIndex];
3562
 
3563
                Tcl_InvalidateStringRep(objPtr);
3564
                objPtr->internalRep.longValue = 0;
3565
                objPtr->typePtr = &tclIntType;
3566
 
3567
                TclEmitPush(objIndex, &compEnv);
3568
            }
3569
 
3570
            /*
3571
             * Add done instruction at the end of the instruction sequence.
3572
             */
3573
 
3574
            TclEmitOpcode(INST_DONE, &compEnv);
3575
 
3576
            TclInitByteCodeObj(objPtr, &compEnv);
3577
            codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
3578
            if (tclTraceCompile == 2) {
3579
                TclPrintByteCodeObj(interp, objPtr);
3580
            }
3581
            TclFreeCompileEnv(&compEnv);
3582
        } else {
3583
            /*
3584
             * Compilation errors. Decrement the ref counts on any objects
3585
             * in the object array before freeing the compilation
3586
             * environment.
3587
             */
3588
 
3589
            for (i = 0;  i < compEnv.objArrayNext;  i++) {
3590
                Tcl_Obj *elemPtr = compEnv.objArrayPtr[i];
3591
                Tcl_DecrRefCount(elemPtr);
3592
            }
3593
 
3594
            auxDataPtr = compEnv.auxDataArrayPtr;
3595
            for (i = 0;  i < compEnv.auxDataArrayNext;  i++) {
3596
                if (auxDataPtr->type->freeProc != NULL) {
3597
                    auxDataPtr->type->freeProc(auxDataPtr->clientData);
3598
                }
3599
                auxDataPtr++;
3600
            }
3601
            TclFreeCompileEnv(&compEnv);
3602
            return result;
3603
        }
3604
    }
3605
 
3606
    /*
3607
     * Execute the expression after first saving the interpreter's result.
3608
     */
3609
 
3610
    dummy.objResultPtr = Tcl_NewObj();
3611
    Tcl_IncrRefCount(dummy.objResultPtr);
3612
    if (interp->freeProc == 0) {
3613
        dummy.freeProc = (Tcl_FreeProc *) 0;
3614
        dummy.result = "";
3615
        Tcl_SetResult((Tcl_Interp *) &dummy, interp->result,
3616
                TCL_VOLATILE);
3617
    } else {
3618
        dummy.freeProc = interp->freeProc;
3619
        dummy.result = interp->result;
3620
        interp->freeProc = (Tcl_FreeProc *) 0;
3621
    }
3622
 
3623
    saveObjPtr = Tcl_GetObjResult(interp);
3624
    Tcl_IncrRefCount(saveObjPtr);
3625
 
3626
    /*
3627
     * Increment the code's ref count while it is being executed. If
3628
     * afterwards no references to it remain, free the code.
3629
     */
3630
 
3631
    codePtr->refCount++;
3632
    result = TclExecuteByteCode(interp, codePtr);
3633
    codePtr->refCount--;
3634
    if (codePtr->refCount <= 0) {
3635
        TclCleanupByteCode(codePtr);
3636
    }
3637
 
3638
    /*
3639
     * If the expression evaluated successfully, store a pointer to its
3640
     * value object in resultPtrPtr then restore the old interpreter result.
3641
     * We increment the object's ref count to reflect the reference that we
3642
     * are returning to the caller. We also decrement the ref count of the
3643
     * interpreter's result object after calling Tcl_SetResult since we
3644
     * next store into that field directly.
3645
     */
3646
 
3647
    if (result == TCL_OK) {
3648
        *resultPtrPtr = iPtr->objResultPtr;
3649
        Tcl_IncrRefCount(iPtr->objResultPtr);
3650
 
3651
        Tcl_SetResult(interp, dummy.result,
3652
                ((dummy.freeProc == 0) ? TCL_VOLATILE : dummy.freeProc));
3653
        Tcl_DecrRefCount(iPtr->objResultPtr);
3654
        iPtr->objResultPtr = saveObjPtr;
3655
    } else {
3656
        Tcl_DecrRefCount(saveObjPtr);
3657
        Tcl_FreeResult((Tcl_Interp *) &dummy);
3658
    }
3659
 
3660
    Tcl_DecrRefCount(dummy.objResultPtr);
3661
    dummy.objResultPtr = NULL;
3662
    return result;
3663
}
3664
 
3665
/*
3666
 *----------------------------------------------------------------------
3667
 *
3668
 * Tcl_CreateTrace --
3669
 *
3670
 *      Arrange for a procedure to be called to trace command execution.
3671
 *
3672
 * Results:
3673
 *      The return value is a token for the trace, which may be passed
3674
 *      to Tcl_DeleteTrace to eliminate the trace.
3675
 *
3676
 * Side effects:
3677
 *      From now on, proc will be called just before a command procedure
3678
 *      is called to execute a Tcl command.  Calls to proc will have the
3679
 *      following form:
3680
 *
3681
 *      void
3682
 *      proc(clientData, interp, level, command, cmdProc, cmdClientData,
3683
 *              argc, argv)
3684
 *          ClientData clientData;
3685
 *          Tcl_Interp *interp;
3686
 *          int level;
3687
 *          char *command;
3688
 *          int (*cmdProc)();
3689
 *          ClientData cmdClientData;
3690
 *          int argc;
3691
 *          char **argv;
3692
 *      {
3693
 *      }
3694
 *
3695
 *      The clientData and interp arguments to proc will be the same
3696
 *      as the corresponding arguments to this procedure.  Level gives
3697
 *      the nesting level of command interpretation for this interpreter
3698
 *      (0 corresponds to top level).  Command gives the ASCII text of
3699
 *      the raw command, cmdProc and cmdClientData give the procedure that
3700
 *      will be called to process the command and the ClientData value it
3701
 *      will receive, and argc and argv give the arguments to the
3702
 *      command, after any argument parsing and substitution.  Proc
3703
 *      does not return a value.
3704
 *
3705
 *----------------------------------------------------------------------
3706
 */
3707
 
3708
Tcl_Trace
3709
Tcl_CreateTrace(interp, level, proc, clientData)
3710
    Tcl_Interp *interp;         /* Interpreter in which to create trace. */
3711
    int level;                  /* Only call proc for commands at nesting
3712
                                 * level<=argument level (1=>top level). */
3713
    Tcl_CmdTraceProc *proc;     /* Procedure to call before executing each
3714
                                 * command. */
3715
    ClientData clientData;      /* Arbitrary value word to pass to proc. */
3716
{
3717
    register Trace *tracePtr;
3718
    register Interp *iPtr = (Interp *) interp;
3719
 
3720
    /*
3721
     * Invalidate existing compiled code for this interpreter and arrange
3722
     * (by setting the DONT_COMPILE_CMDS_INLINE flag) that when compiling
3723
     * new code, no commands will be compiled inline (i.e., into an inline
3724
     * sequence of instructions). We do this because commands that were
3725
     * compiled inline will never result in a command trace being called.
3726
     */
3727
 
3728
    iPtr->compileEpoch++;
3729
    iPtr->flags |= DONT_COMPILE_CMDS_INLINE;
3730
 
3731
    tracePtr = (Trace *) ckalloc(sizeof(Trace));
3732
    tracePtr->level = level;
3733
    tracePtr->proc = proc;
3734
    tracePtr->clientData = clientData;
3735
    tracePtr->nextPtr = iPtr->tracePtr;
3736
    iPtr->tracePtr = tracePtr;
3737
 
3738
    return (Tcl_Trace) tracePtr;
3739
}
3740
 
3741
/*
3742
 *----------------------------------------------------------------------
3743
 *
3744
 * Tcl_DeleteTrace --
3745
 *
3746
 *      Remove a trace.
3747
 *
3748
 * Results:
3749
 *      None.
3750
 *
3751
 * Side effects:
3752
 *      From now on there will be no more calls to the procedure given
3753
 *      in trace.
3754
 *
3755
 *----------------------------------------------------------------------
3756
 */
3757
 
3758
void
3759
Tcl_DeleteTrace(interp, trace)
3760
    Tcl_Interp *interp;         /* Interpreter that contains trace. */
3761
    Tcl_Trace trace;            /* Token for trace (returned previously by
3762
                                 * Tcl_CreateTrace). */
3763
{
3764
    register Interp *iPtr = (Interp *) interp;
3765
    register Trace *tracePtr = (Trace *) trace;
3766
    register Trace *tracePtr2;
3767
 
3768
    if (iPtr->tracePtr == tracePtr) {
3769
        iPtr->tracePtr = tracePtr->nextPtr;
3770
        ckfree((char *) tracePtr);
3771
    } else {
3772
        for (tracePtr2 = iPtr->tracePtr; tracePtr2 != NULL;
3773
                tracePtr2 = tracePtr2->nextPtr) {
3774
            if (tracePtr2->nextPtr == tracePtr) {
3775
                tracePtr2->nextPtr = tracePtr->nextPtr;
3776
                ckfree((char *) tracePtr);
3777
                break;
3778
            }
3779
        }
3780
    }
3781
 
3782
    if (iPtr->tracePtr == NULL) {
3783
        /*
3784
         * When compiling new code, allow commands to be compiled inline.
3785
         */
3786
 
3787
        iPtr->flags &= ~DONT_COMPILE_CMDS_INLINE;
3788
    }
3789
}
3790
 
3791
/*
3792
 *----------------------------------------------------------------------
3793
 *
3794
 * Tcl_AddErrorInfo --
3795
 *
3796
 *      Add information to the "errorInfo" variable that describes the
3797
 *      current error.
3798
 *
3799
 * Results:
3800
 *      None.
3801
 *
3802
 * Side effects:
3803
 *      The contents of message are added to the "errorInfo" variable.
3804
 *      If Tcl_Eval has been called since the current value of errorInfo
3805
 *      was set, errorInfo is cleared before adding the new message.
3806
 *      If we are just starting to log an error, errorInfo is initialized
3807
 *      from the error message in the interpreter's result.
3808
 *
3809
 *----------------------------------------------------------------------
3810
 */
3811
 
3812
void
3813
Tcl_AddErrorInfo(interp, message)
3814
    Tcl_Interp *interp;         /* Interpreter to which error information
3815
                                 * pertains. */
3816
    char *message;              /* Message to record. */
3817
{
3818
    Tcl_AddObjErrorInfo(interp, message, -1);
3819
}
3820
 
3821
/*
3822
 *----------------------------------------------------------------------
3823
 *
3824
 * Tcl_AddObjErrorInfo --
3825
 *
3826
 *      Add information to the "errorInfo" variable that describes the
3827
 *      current error. This routine differs from Tcl_AddErrorInfo by
3828
 *      taking a byte pointer and length.
3829
 *
3830
 * Results:
3831
 *      None.
3832
 *
3833
 * Side effects:
3834
 *      "length" bytes from "message" are added to the "errorInfo" variable.
3835
 *      If "length" is negative, use bytes up to the first NULL byte.
3836
 *      If Tcl_EvalObj has been called since the current value of errorInfo
3837
 *      was set, errorInfo is cleared before adding the new message.
3838
 *      If we are just starting to log an error, errorInfo is initialized
3839
 *      from the error message in the interpreter's result.
3840
 *
3841
 *----------------------------------------------------------------------
3842
 */
3843
 
3844
void
3845
Tcl_AddObjErrorInfo(interp, message, length)
3846
    Tcl_Interp *interp;         /* Interpreter to which error information
3847
                                 * pertains. */
3848
    char *message;              /* Points to the first byte of an array of
3849
                                 * bytes of the message. */
3850
    register int length;        /* The number of bytes in the message.
3851
                                 * If < 0, then append all bytes up to a
3852
                                 * NULL byte. */
3853
{
3854
    register Interp *iPtr = (Interp *) interp;
3855
    Tcl_Obj *namePtr, *messagePtr;
3856
 
3857
    /*
3858
     * If we are just starting to log an error, errorInfo is initialized
3859
     * from the error message in the interpreter's result.
3860
     */
3861
 
3862
    namePtr = Tcl_NewStringObj("errorInfo", -1);
3863
    Tcl_IncrRefCount(namePtr);
3864
 
3865
    if (!(iPtr->flags & ERR_IN_PROGRESS)) { /* just starting to log error */
3866
        iPtr->flags |= ERR_IN_PROGRESS;
3867
 
3868
        if (iPtr->result[0] == 0) {
3869
            (void) Tcl_ObjSetVar2(interp, namePtr, (Tcl_Obj *) NULL,
3870
                    iPtr->objResultPtr, TCL_GLOBAL_ONLY);
3871
        } else {                /* use the string result */
3872
            Tcl_SetVar2(interp, "errorInfo", (char *) NULL, interp->result,
3873
                    TCL_GLOBAL_ONLY);
3874
        }
3875
 
3876
        /*
3877
         * If the errorCode variable wasn't set by the code that generated
3878
         * the error, set it to "NONE".
3879
         */
3880
 
3881
        if (!(iPtr->flags & ERROR_CODE_SET)) {
3882
            (void) Tcl_SetVar2(interp, "errorCode", (char *) NULL, "NONE",
3883
                    TCL_GLOBAL_ONLY);
3884
        }
3885
    }
3886
 
3887
    /*
3888
     * Now append "message" to the end of errorInfo.
3889
     */
3890
 
3891
    if (length != 0) {
3892
        messagePtr = Tcl_NewStringObj(message, length);
3893
        Tcl_IncrRefCount(messagePtr);
3894
        Tcl_ObjSetVar2(interp, namePtr, (Tcl_Obj *) NULL, messagePtr,
3895
                (TCL_GLOBAL_ONLY | TCL_APPEND_VALUE));
3896
        Tcl_DecrRefCount(messagePtr); /* free msg object appended above */
3897
    }
3898
 
3899
    Tcl_DecrRefCount(namePtr);    /* free the name object */
3900
}
3901
 
3902
/*
3903
 *----------------------------------------------------------------------
3904
 *
3905
 * Tcl_VarEval --
3906
 *
3907
 *      Given a variable number of string arguments, concatenate them
3908
 *      all together and execute the result as a Tcl command.
3909
 *
3910
 * Results:
3911
 *      A standard Tcl return result.  An error message or other
3912
 *      result may be left in interp->result.
3913
 *
3914
 * Side effects:
3915
 *      Depends on what was done by the command.
3916
 *
3917
 *----------------------------------------------------------------------
3918
 */
3919
        /* VARARGS2 */ /* ARGSUSED */
3920
int
3921
Tcl_VarEval TCL_VARARGS_DEF(Tcl_Interp *,arg1)
3922
{
3923
    va_list argList;
3924
    Tcl_DString buf;
3925
    char *string;
3926
    Tcl_Interp *interp;
3927
    int result;
3928
 
3929
    /*
3930
     * Copy the strings one after the other into a single larger
3931
     * string.  Use stack-allocated space for small commands, but if
3932
     * the command gets too large than call ckalloc to create the
3933
     * space.
3934
     */
3935
 
3936
    interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
3937
    Tcl_DStringInit(&buf);
3938
    while (1) {
3939
        string = va_arg(argList, char *);
3940
        if (string == NULL) {
3941
            break;
3942
        }
3943
        Tcl_DStringAppend(&buf, string, -1);
3944
    }
3945
    va_end(argList);
3946
 
3947
    result = Tcl_Eval(interp, Tcl_DStringValue(&buf));
3948
    Tcl_DStringFree(&buf);
3949
    return result;
3950
}
3951
 
3952
/*
3953
 *----------------------------------------------------------------------
3954
 *
3955
 * Tcl_GlobalEval --
3956
 *
3957
 *      Evaluate a command at global level in an interpreter.
3958
 *
3959
 * Results:
3960
 *      A standard Tcl result is returned, and interp->result is
3961
 *      modified accordingly.
3962
 *
3963
 * Side effects:
3964
 *      The command string is executed in interp, and the execution
3965
 *      is carried out in the variable context of global level (no
3966
 *      procedures active), just as if an "uplevel #0" command were
3967
 *      being executed.
3968
 *
3969
 *----------------------------------------------------------------------
3970
 */
3971
 
3972
int
3973
Tcl_GlobalEval(interp, command)
3974
    Tcl_Interp *interp;         /* Interpreter in which to evaluate command. */
3975
    char *command;              /* Command to evaluate. */
3976
{
3977
    register Interp *iPtr = (Interp *) interp;
3978
    int result;
3979
    CallFrame *savedVarFramePtr;
3980
 
3981
    savedVarFramePtr = iPtr->varFramePtr;
3982
    iPtr->varFramePtr = NULL;
3983
    result = Tcl_Eval(interp, command);
3984
    iPtr->varFramePtr = savedVarFramePtr;
3985
    return result;
3986
}
3987
 
3988
/*
3989
 *----------------------------------------------------------------------
3990
 *
3991
 * Tcl_GlobalEvalObj --
3992
 *
3993
 *      Execute Tcl commands stored in a Tcl object at global level in
3994
 *      an interpreter. These commands are compiled into bytecodes if
3995
 *      necessary.
3996
 *
3997
 * Results:
3998
 *      A standard Tcl result is returned, and the interpreter's result
3999
 *      contains a Tcl object value to supplement the return code.
4000
 *
4001
 * Side effects:
4002
 *      The object is converted, if necessary, to a ByteCode object that
4003
 *      holds the bytecode instructions for the commands. Executing the
4004
 *      commands will almost certainly have side effects that depend on
4005
 *      those commands.
4006
 *
4007
 *      The commands are executed in interp, and the execution
4008
 *      is carried out in the variable context of global level (no
4009
 *      procedures active), just as if an "uplevel #0" command were
4010
 *      being executed.
4011
 *
4012
 *----------------------------------------------------------------------
4013
 */
4014
 
4015
int
4016
Tcl_GlobalEvalObj(interp, objPtr)
4017
    Tcl_Interp *interp;         /* Interpreter in which to evaluate
4018
                                 * commands. */
4019
    Tcl_Obj *objPtr;            /* Pointer to object containing commands
4020
                                 * to execute. */
4021
{
4022
    register Interp *iPtr = (Interp *) interp;
4023
    int result;
4024
    CallFrame *savedVarFramePtr;
4025
 
4026
    savedVarFramePtr = iPtr->varFramePtr;
4027
    iPtr->varFramePtr = NULL;
4028
    result = Tcl_EvalObj(interp, objPtr);
4029
    iPtr->varFramePtr = savedVarFramePtr;
4030
    return result;
4031
}
4032
 
4033
/*
4034
 *----------------------------------------------------------------------
4035
 *
4036
 * Tcl_SetRecursionLimit --
4037
 *
4038
 *      Set the maximum number of recursive calls that may be active
4039
 *      for an interpreter at once.
4040
 *
4041
 * Results:
4042
 *      The return value is the old limit on nesting for interp.
4043
 *
4044
 * Side effects:
4045
 *      None.
4046
 *
4047
 *----------------------------------------------------------------------
4048
 */
4049
 
4050
int
4051
Tcl_SetRecursionLimit(interp, depth)
4052
    Tcl_Interp *interp;                 /* Interpreter whose nesting limit
4053
                                         * is to be set. */
4054
    int depth;                          /* New value for maximimum depth. */
4055
{
4056
    Interp *iPtr = (Interp *) interp;
4057
    int old;
4058
 
4059
    old = iPtr->maxNestingDepth;
4060
    if (depth > 0) {
4061
        iPtr->maxNestingDepth = depth;
4062
    }
4063
    return old;
4064
}
4065
 
4066
/*
4067
 *----------------------------------------------------------------------
4068
 *
4069
 * Tcl_AllowExceptions --
4070
 *
4071
 *      Sets a flag in an interpreter so that exceptions can occur
4072
 *      in the next call to Tcl_Eval without them being turned into
4073
 *      errors.
4074
 *
4075
 * Results:
4076
 *      None.
4077
 *
4078
 * Side effects:
4079
 *      The TCL_ALLOW_EXCEPTIONS flag gets set in the interpreter's
4080
 *      evalFlags structure.  See the reference documentation for
4081
 *      more details.
4082
 *
4083
 *----------------------------------------------------------------------
4084
 */
4085
 
4086
void
4087
Tcl_AllowExceptions(interp)
4088
    Tcl_Interp *interp;         /* Interpreter in which to set flag. */
4089
{
4090
    Interp *iPtr = (Interp *) interp;
4091
 
4092
    iPtr->evalFlags |= TCL_ALLOW_EXCEPTIONS;
4093
}
4094
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.