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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [insight/] [tcl/] [generic/] [tclTestProcBodyObj.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tclTestProcBodyObj.c --
3
 *
4
 *      Implements the "procbodytest" package, which contains commands
5
 *      to test creation of Tcl procedures whose body argument is a
6
 *      Tcl_Obj of type "procbody" rather than a string.
7
 *
8
 * Copyright (c) 1998 by Scriptics Corporation.
9
 *
10
 * See the file "license.terms" for information on usage and redistribution
11
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12
 *
13
 * RCS: @(#) $Id: tclTestProcBodyObj.c,v 1.1.1.1 2002-01-16 10:25:29 markom Exp $
14
 */
15
 
16
#include "tclInt.h"
17
 
18
/*
19
 * name and version of this package
20
 */
21
 
22
static char packageName[] = "procbodytest";
23
static char packageVersion[] = "1.0";
24
 
25
/*
26
 * Name of the commands exported by this package
27
 */
28
 
29
static char procCommand[] = "proc";
30
 
31
/*
32
 * this struct describes an entry in the table of command names and command
33
 * procs
34
 */
35
 
36
typedef struct CmdTable
37
{
38
    char *cmdName;              /* command name */
39
    Tcl_ObjCmdProc *proc;       /* command proc */
40
    int exportIt;               /* if 1, export the command */
41
} CmdTable;
42
 
43
/*
44
 * Declarations for functions defined in this file.
45
 */
46
 
47
static int      ProcBodyTestProcObjCmd _ANSI_ARGS_((ClientData dummy,
48
                        Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
49
static int      ProcBodyTestInitInternal _ANSI_ARGS_((Tcl_Interp *interp,
50
                        int isSafe));
51
static int      RegisterCommand _ANSI_ARGS_((Tcl_Interp* interp,
52
                        char *namespace, CONST CmdTable *cmdTablePtr));
53
int             Procbodytest_Init _ANSI_ARGS_((Tcl_Interp * interp));
54
int             Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp * interp));
55
 
56
/*
57
 * List of commands to create when the package is loaded; must go after the
58
 * declarations of the enable command procedure.
59
 */
60
 
61
static CONST CmdTable commands[] =
62
{
63
    { procCommand,      ProcBodyTestProcObjCmd, 1 },
64
 
65
    { 0, 0, 0 }
66
};
67
 
68
static CONST CmdTable safeCommands[] =
69
{
70
    { procCommand,      ProcBodyTestProcObjCmd, 1 },
71
 
72
    { 0, 0, 0 }
73
};
74
 
75
/*
76
 *----------------------------------------------------------------------
77
 *
78
 * Procbodytest_Init --
79
 *
80
 *  This procedure initializes the "procbodytest" package.
81
 *
82
 * Results:
83
 *  A standard Tcl result.
84
 *
85
 * Side effects:
86
 *  None.
87
 *
88
 *----------------------------------------------------------------------
89
 */
90
 
91
int
92
Procbodytest_Init(interp)
93
    Tcl_Interp *interp;         /* the Tcl interpreter for which the package
94
                                 * is initialized */
95
{
96
    return ProcBodyTestInitInternal(interp, 0);
97
}
98
 
99
/*
100
 *----------------------------------------------------------------------
101
 *
102
 * Procbodytest_SafeInit --
103
 *
104
 *  This procedure initializes the "procbodytest" package.
105
 *
106
 * Results:
107
 *  A standard Tcl result.
108
 *
109
 * Side effects:
110
 *  None.
111
 *
112
 *----------------------------------------------------------------------
113
 */
114
 
115
int
116
Procbodytest_SafeInit(interp)
117
    Tcl_Interp *interp;         /* the Tcl interpreter for which the package
118
                                 * is initialized */
119
{
120
    return ProcBodyTestInitInternal(interp, 1);
121
}
122
 
123
/*
124
 *----------------------------------------------------------------------
125
 *
126
 * RegisterCommand --
127
 *
128
 *  This procedure registers a command in the context of the given namespace.
129
 *
130
 * Results:
131
 *  A standard Tcl result.
132
 *
133
 * Side effects:
134
 *  None.
135
 *
136
 *----------------------------------------------------------------------
137
 */
138
 
139
static int RegisterCommand(interp, namespace, cmdTablePtr)
140
    Tcl_Interp* interp;                 /* the Tcl interpreter for which the
141
                                         * operation is performed */
142
    char *namespace;                    /* the namespace in which the command
143
                                         * is registered */
144
    CONST CmdTable *cmdTablePtr;        /* the command to register */
145
{
146
    char buf[128];
147
 
148
    if (cmdTablePtr->exportIt) {
149
        sprintf(buf, "namespace eval %s { namespace export %s }",
150
                namespace, cmdTablePtr->cmdName);
151
        if (Tcl_Eval(interp, buf) != TCL_OK)
152
            return TCL_ERROR;
153
    }
154
 
155
    sprintf(buf, "%s::%s", namespace, cmdTablePtr->cmdName);
156
    Tcl_CreateObjCommand(interp, buf, cmdTablePtr->proc, 0, 0);
157
 
158
    return TCL_OK;
159
}
160
 
161
/*
162
 *----------------------------------------------------------------------
163
 *
164
 * ProcBodyTestInitInternal --
165
 *
166
 *  This procedure initializes the Loader package.
167
 *  The isSafe flag is 1 if the interpreter is safe, 0 otherwise.
168
 *
169
 * Results:
170
 *  A standard Tcl result.
171
 *
172
 * Side effects:
173
 *  None.
174
 *
175
 *----------------------------------------------------------------------
176
 */
177
 
178
static int
179
ProcBodyTestInitInternal(interp, isSafe)
180
    Tcl_Interp *interp;         /* the Tcl interpreter for which the package
181
                                 * is initialized */
182
    int isSafe;                 /* 1 if this is a safe interpreter */
183
{
184
    CONST CmdTable *cmdTablePtr;
185
 
186
    cmdTablePtr = (isSafe) ? &safeCommands[0] : &commands[0];
187
    for ( ; cmdTablePtr->cmdName ; cmdTablePtr++) {
188
        if (RegisterCommand(interp, packageName, cmdTablePtr) != TCL_OK) {
189
            return TCL_ERROR;
190
        }
191
    }
192
 
193
    return Tcl_PkgProvide(interp, packageName, packageVersion);
194
}
195
 
196
/*
197
 *----------------------------------------------------------------------
198
 *
199
 * ProcBodyTestProcObjCmd --
200
 *
201
 *  Implements the "procbodytest::proc" command. Here is the command
202
 *  description:
203
 *      procbodytest::proc newName argList bodyName
204
 *  Looks up a procedure called $bodyName and, if the procedure exists,
205
 *  constructs a Tcl_Obj of type "procbody" and calls Tcl_ProcObjCmd.
206
 *  Arguments:
207
 *    newName           the name of the procedure to be created
208
 *    argList           the argument list for the procedure
209
 *    bodyName          the name of an existing procedure from which the
210
 *                      body is to be copied.
211
 *  This command can be used to trigger the branches in Tcl_ProcObjCmd that
212
 *  construct a proc from a "procbody", for example:
213
 *      proc a {x} {return $x}
214
 *      a 123
215
 *      procbodytest::proc b {x} a
216
 *  Note the call to "a 123", which is necessary so that the Proc pointer
217
 *  for "a" is filled in by the internal compiler; this is a hack.
218
 *
219
 * Results:
220
 *  Returns a standard Tcl code.
221
 *
222
 * Side effects:
223
 *  A new procedure is created.
224
 *  Leaves an error message in the interp's result on error.
225
 *
226
 *----------------------------------------------------------------------
227
 */
228
 
229
static int
230
ProcBodyTestProcObjCmd (dummy, interp, objc, objv)
231
    ClientData dummy;           /* context; not used */
232
    Tcl_Interp *interp;         /* the current interpreter */
233
    int objc;                   /* argument count */
234
    Tcl_Obj *CONST objv[];      /* arguments */
235
{
236
    char *fullName;
237
    Tcl_Command procCmd;
238
    Command *cmdPtr;
239
    Proc *procPtr = (Proc *) NULL;
240
    Tcl_Obj *bodyObjPtr;
241
    Tcl_Obj *myobjv[5];
242
    int result;
243
 
244
    if (objc != 4) {
245
        Tcl_WrongNumArgs(interp, 1, objv, "newName argsList bodyName");
246
        return TCL_ERROR;
247
    }
248
 
249
    /*
250
     * Find the Command pointer to this procedure
251
     */
252
 
253
    fullName = Tcl_GetStringFromObj(objv[3], (int *) NULL);
254
    procCmd = Tcl_FindCommand(interp, fullName, (Tcl_Namespace *) NULL,
255
            TCL_LEAVE_ERR_MSG);
256
    if (procCmd == NULL) {
257
        return TCL_ERROR;
258
    }
259
 
260
    cmdPtr = (Command *) procCmd;
261
 
262
    /*
263
     * check that this is a procedure and not a builtin command:
264
     * If a procedure, cmdPtr->objProc is either 0 or TclObjInterpProc,
265
     * and cmdPtr->proc is either 0 or TclProcInterpProc.
266
     * Also, the compile proc should be 0, but we don't check for that.
267
     */
268
 
269
    if (((cmdPtr->objProc != NULL)
270
            && (cmdPtr->objProc != TclGetObjInterpProc()))
271
            || ((cmdPtr->proc != NULL)
272
                    && (cmdPtr->proc != TclGetInterpProc()))) {
273
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
274
                "command \"", fullName,
275
                "\" is not a Tcl procedure", (char *) NULL);
276
        return TCL_ERROR;
277
    }
278
 
279
    /*
280
     * it is a Tcl procedure: the client data is the Proc structure
281
     */
282
 
283
    if (cmdPtr->objProc != NULL) {
284
        procPtr = (Proc *) cmdPtr->objClientData;
285
    } else if (cmdPtr->proc != NULL) {
286
        procPtr = (Proc *) cmdPtr->clientData;
287
    }
288
 
289
    if (procPtr == NULL) {
290
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
291
                "procedure \"", fullName,
292
                "\" does not have a Proc struct!", (char *) NULL);
293
        return TCL_ERROR;
294
    }
295
 
296
    /*
297
     * create a new object, initialize our argument vector, call into Tcl
298
     */
299
 
300
    bodyObjPtr = TclNewProcBodyObj(procPtr);
301
    if (bodyObjPtr == NULL) {
302
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
303
                "failed to create a procbody object for procedure \"",
304
                fullName, "\"", (char *) NULL);
305
        return TCL_ERROR;
306
    }
307
    Tcl_IncrRefCount(bodyObjPtr);
308
 
309
    myobjv[0] = objv[0];
310
    myobjv[1] = objv[1];
311
    myobjv[2] = objv[2];
312
    myobjv[3] = bodyObjPtr;
313
    myobjv[4] = (Tcl_Obj *) NULL;
314
 
315
    result = Tcl_ProcObjCmd((ClientData) NULL, interp, objc, myobjv);
316
    Tcl_DecrRefCount(bodyObjPtr);
317
 
318
    return result;
319
}

powered by: WebSVN 2.1.0

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