]>
cvs.zerfleddert.de Git - micropolis/blob - src/tcl/tclbasic.c
90a656d0affbedf4515a366c3a3d254688eb7026
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.
8 * Copyright 1987-1992 Regents of the University of California
9 * Permission to use, copy, modify, and distribute this
10 * software and its documentation for any purpose and without
11 * fee is hereby granted, provided that the above copyright
12 * notice appear in all copies. The University of California
13 * makes no representations about the suitability of this
14 * software for any purpose. It is provided "as is" without
15 * express or implied warranty.
19 static char rcsid
[] = "$Header: /user6/ouster/tcl/RCS/tclBasic.c,v 1.131 92/06/21 14:09:41 ouster Exp $ SPRITE (Berkeley)";
25 * The following structure defines all of the commands in the Tcl core,
26 * and the C procedures that execute them.
30 char *name
; /* Name of command. */
31 Tcl_CmdProc
*proc
; /* Procedure that executes command. */
35 * Built-in commands, and the procedures associated with them:
38 static CmdInfo builtInCmds
[] = {
40 * Commands in the generic core:
43 {"append", Tcl_AppendCmd
},
44 {"array", Tcl_ArrayCmd
},
45 {"break", Tcl_BreakCmd
},
46 {"case", Tcl_CaseCmd
},
47 {"catch", Tcl_CatchCmd
},
48 {"concat", Tcl_ConcatCmd
},
49 {"continue", Tcl_ContinueCmd
},
50 {"error", Tcl_ErrorCmd
},
51 {"eval", Tcl_EvalCmd
},
52 {"expr", Tcl_ExprCmd
},
54 {"foreach", Tcl_ForeachCmd
},
55 {"format", Tcl_FormatCmd
},
56 {"global", Tcl_GlobalCmd
},
58 {"incr", Tcl_IncrCmd
},
59 {"info", Tcl_InfoCmd
},
60 {"join", Tcl_JoinCmd
},
61 {"lappend", Tcl_LappendCmd
},
62 {"lindex", Tcl_LindexCmd
},
63 {"linsert", Tcl_LinsertCmd
},
64 {"list", Tcl_ListCmd
},
65 {"llength", Tcl_LlengthCmd
},
66 {"lrange", Tcl_LrangeCmd
},
67 {"lreplace", Tcl_LreplaceCmd
},
68 {"lsearch", Tcl_LsearchCmd
},
69 {"lsort", Tcl_LsortCmd
},
70 {"proc", Tcl_ProcCmd
},
71 {"regexp", Tcl_RegexpCmd
},
72 {"regsub", Tcl_RegsubCmd
},
73 {"rename", Tcl_RenameCmd
},
74 {"return", Tcl_ReturnCmd
},
75 {"scan", Tcl_ScanCmd
},
77 {"split", Tcl_SplitCmd
},
78 {"string", Tcl_StringCmd
},
79 {"trace", Tcl_TraceCmd
},
80 {"unset", Tcl_UnsetCmd
},
81 {"uplevel", Tcl_UplevelCmd
},
82 {"upvar", Tcl_UpvarCmd
},
83 {"while", Tcl_WhileCmd
},
86 * Commands in the UNIX core:
89 #ifndef TCL_GENERIC_ONLY
91 {"close", Tcl_CloseCmd
},
93 {"exec", Tcl_ExecCmd
},
94 {"exit", Tcl_ExitCmd
},
95 {"file", Tcl_FileCmd
},
96 {"flush", Tcl_FlushCmd
},
97 {"gets", Tcl_GetsCmd
},
98 {"glob", Tcl_GlobCmd
},
99 {"open", Tcl_OpenCmd
},
100 {"puts", Tcl_PutsCmd
},
102 {"read", Tcl_ReadCmd
},
103 {"seek", Tcl_SeekCmd
},
104 {"source", Tcl_SourceCmd
},
105 {"tell", Tcl_TellCmd
},
106 {"time", Tcl_TimeCmd
},
107 #endif /* TCL_GENERIC_ONLY */
108 {NULL
, (Tcl_CmdProc
*) NULL
}
112 *----------------------------------------------------------------------
114 * Tcl_CreateInterp --
116 * Create a new TCL command interpreter.
119 * The return value is a token for the interpreter, which may be
120 * used in calls to procedures like Tcl_CreateCmd, Tcl_Eval, or
124 * The command interpreter is initialized with an empty variable
125 * table and the built-in commands.
127 *----------------------------------------------------------------------
133 register Interp
*iPtr
;
134 register Command
*cmdPtr
;
135 register CmdInfo
*cmdInfoPtr
;
138 iPtr
= (Interp
*) ckalloc(sizeof(Interp
));
139 iPtr
->result
= iPtr
->resultSpace
;
142 Tcl_InitHashTable(&iPtr
->commandTable
, TCL_STRING_KEYS
);
143 Tcl_InitHashTable(&iPtr
->globalTable
, TCL_STRING_KEYS
);
145 iPtr
->framePtr
= NULL
;
146 iPtr
->varFramePtr
= NULL
;
147 iPtr
->activeTracePtr
= NULL
;
151 iPtr
->curEventNum
= 0;
153 iPtr
->historyFirst
= NULL
;
154 iPtr
->revDisables
= 1;
155 iPtr
->evalFirst
= iPtr
->evalLast
= NULL
;
156 iPtr
->appendResult
= NULL
;
158 iPtr
->appendUsed
= 0;
160 iPtr
->filePtrArray
= NULL
;
161 for (i
= 0; i
< NUM_REGEXPS
; i
++) {
162 iPtr
->patterns
[i
] = NULL
;
163 iPtr
->patLengths
[i
] = -1;
164 iPtr
->regexps
[i
] = NULL
;
168 iPtr
->scriptFile
= NULL
;
170 iPtr
->tracePtr
= NULL
;
171 iPtr
->resultSpace
[0] = 0;
174 * Create the built-in commands. Do it here, rather than calling
175 * Tcl_CreateCommand, because it's faster (there's no need to
176 * check for a pre-existing command by the same name).
179 for (cmdInfoPtr
= builtInCmds
; cmdInfoPtr
->name
!= NULL
; cmdInfoPtr
++) {
183 hPtr
= Tcl_CreateHashEntry(&iPtr
->commandTable
,
184 cmdInfoPtr
->name
, &new);
186 cmdPtr
= (Command
*) ckalloc(sizeof(Command
));
187 cmdPtr
->proc
= cmdInfoPtr
->proc
;
188 cmdPtr
->clientData
= (ClientData
) NULL
;
189 cmdPtr
->deleteProc
= NULL
;
190 Tcl_SetHashValue(hPtr
, cmdPtr
);
194 #ifndef TCL_GENERIC_ONLY
195 TclSetupEnv((Tcl_Interp
*) iPtr
);
198 return (Tcl_Interp
*) iPtr
;
202 *----------------------------------------------------------------------
204 * Tcl_DeleteInterp --
206 * Delete an interpreter and free up all of the resources associated
213 * The interpreter is destroyed. The caller should never again
214 * use the interp token.
216 *----------------------------------------------------------------------
220 Tcl_DeleteInterp(interp
)
221 Tcl_Interp
*interp
; /* Token for command interpreter (returned
222 * by a previous call to Tcl_CreateInterp). */
224 Interp
*iPtr
= (Interp
*) interp
;
226 Tcl_HashSearch search
;
227 register Command
*cmdPtr
;
231 * If the interpreter is in use, delay the deletion until later.
234 iPtr
->flags
|= DELETED
;
235 if (iPtr
->numLevels
!= 0) {
240 * Free up any remaining resources associated with the
244 for (hPtr
= Tcl_FirstHashEntry(&iPtr
->commandTable
, &search
);
245 hPtr
!= NULL
; hPtr
= Tcl_NextHashEntry(&search
)) {
246 cmdPtr
= (Command
*) Tcl_GetHashValue(hPtr
);
247 if (cmdPtr
->deleteProc
!= NULL
) {
248 (*cmdPtr
->deleteProc
)(cmdPtr
->clientData
);
250 ckfree((char *) cmdPtr
);
252 Tcl_DeleteHashTable(&iPtr
->commandTable
);
253 TclDeleteVars(iPtr
, &iPtr
->globalTable
);
254 if (iPtr
->events
!= NULL
) {
257 for (i
= 0; i
< iPtr
->numEvents
; i
++) {
258 ckfree(iPtr
->events
[i
].command
);
260 ckfree((char *) iPtr
->events
);
262 while (iPtr
->revPtr
!= NULL
) {
263 HistoryRev
*nextPtr
= iPtr
->revPtr
->nextPtr
;
265 ckfree((char *) iPtr
->revPtr
);
266 iPtr
->revPtr
= nextPtr
;
268 if (iPtr
->appendResult
!= NULL
) {
269 ckfree(iPtr
->appendResult
);
271 #ifndef TCL_GENERIC_ONLY
272 if (iPtr
->numFiles
> 0) {
273 for (i
= 0; i
< iPtr
->numFiles
; i
++) {
276 filePtr
= iPtr
->filePtrArray
[i
];
277 if (filePtr
== NULL
) {
282 if (filePtr
->f2
!= NULL
) {
285 if (filePtr
->numPids
> 0) {
286 Tcl_DetachPids(filePtr
->numPids
, filePtr
->pidPtr
);
287 ckfree((char *) filePtr
->pidPtr
);
290 ckfree((char *) filePtr
);
292 ckfree((char *) iPtr
->filePtrArray
);
295 for (i
= 0; i
< NUM_REGEXPS
; i
++) {
296 if (iPtr
->patterns
[i
] == NULL
) {
299 ckfree(iPtr
->patterns
[i
]);
300 ckfree((char *) iPtr
->regexps
[i
]);
302 while (iPtr
->tracePtr
!= NULL
) {
303 Trace
*nextPtr
= iPtr
->tracePtr
->nextPtr
;
305 ckfree((char *) iPtr
->tracePtr
);
306 iPtr
->tracePtr
= nextPtr
;
308 ckfree((char *) iPtr
);
312 *----------------------------------------------------------------------
314 * Tcl_CreateCommand --
316 * Define a new command in a command table.
322 * If a command named cmdName already exists for interp, it is
323 * deleted. In the future, when cmdName is seen as the name of
324 * a command by Tcl_Eval, proc will be called. When the command
325 * is deleted from the table, deleteProc will be called. See the
326 * manual entry for details on the calling sequence.
328 *----------------------------------------------------------------------
332 Tcl_CreateCommand(interp
, cmdName
, proc
, clientData
, deleteProc
)
333 Tcl_Interp
*interp
; /* Token for command interpreter (returned
334 * by a previous call to Tcl_CreateInterp). */
335 char *cmdName
; /* Name of command. */
336 Tcl_CmdProc
*proc
; /* Command procedure to associate with
338 ClientData clientData
; /* Arbitrary one-word value to pass to proc. */
339 Tcl_CmdDeleteProc
*deleteProc
;
340 /* If not NULL, gives a procedure to call when
341 * this command is deleted. */
343 Interp
*iPtr
= (Interp
*) interp
;
344 register Command
*cmdPtr
;
348 hPtr
= Tcl_CreateHashEntry(&iPtr
->commandTable
, cmdName
, &new);
351 * Command already exists: delete the old one.
354 cmdPtr
= (Command
*) Tcl_GetHashValue(hPtr
);
355 if (cmdPtr
->deleteProc
!= NULL
) {
356 (*cmdPtr
->deleteProc
)(cmdPtr
->clientData
);
359 cmdPtr
= (Command
*) ckalloc(sizeof(Command
));
360 Tcl_SetHashValue(hPtr
, cmdPtr
);
363 cmdPtr
->clientData
= clientData
;
364 cmdPtr
->deleteProc
= deleteProc
;
368 *----------------------------------------------------------------------
370 * Tcl_DeleteCommand --
372 * Remove the given command from the given interpreter.
375 * 0 is returned if the command was deleted successfully.
376 * -1 is returned if there didn't exist a command by that
380 * CmdName will no longer be recognized as a valid command for
383 *----------------------------------------------------------------------
387 Tcl_DeleteCommand(interp
, cmdName
)
388 Tcl_Interp
*interp
; /* Token for command interpreter (returned
389 * by a previous call to Tcl_CreateInterp). */
390 char *cmdName
; /* Name of command to remove. */
392 Interp
*iPtr
= (Interp
*) interp
;
396 hPtr
= Tcl_FindHashEntry(&iPtr
->commandTable
, cmdName
);
400 cmdPtr
= (Command
*) Tcl_GetHashValue(hPtr
);
401 if (cmdPtr
->deleteProc
!= NULL
) {
402 (*cmdPtr
->deleteProc
)(cmdPtr
->clientData
);
404 ckfree((char *) cmdPtr
);
405 Tcl_DeleteHashEntry(hPtr
);
410 *-----------------------------------------------------------------
414 * Parse and execute a command in the Tcl language.
417 * The return value is one of the return codes defined in tcl.hd
418 * (such as TCL_OK), and interp->result contains a string value
419 * to supplement the return code. The value of interp->result
420 * will persist only until the next call to Tcl_Eval: copy it or
421 * lose it! *TermPtr is filled in with the character just after
422 * the last one that was part of the command (usually a NULL
423 * character or a closing bracket).
426 * Almost certainly; depends on the command.
428 *-----------------------------------------------------------------
432 Tcl_Eval(interp
, cmd
, flags
, termPtr
)
433 Tcl_Interp
*interp
; /* Token for command interpreter (returned
434 * by a previous call to Tcl_CreateInterp). */
435 char *cmd
; /* Pointer to TCL command to interpret. */
436 int flags
; /* OR-ed combination of flags like
437 * TCL_BRACKET_TERM and TCL_RECORD_BOUNDS. */
438 char **termPtr
; /* If non-NULL, fill in the address it points
439 * to with the address of the char. just after
440 * the last one that was part of cmd. See
441 * the man page for details on this. */
444 * The storage immediately below is used to generate a copy
445 * of the command, after all argument substitutions. Pv will
446 * contain the argv values passed to the command procedure.
449 # define NUM_CHARS 200
450 char copyStorage
[NUM_CHARS
];
455 * This procedure generates an (argv, argc) array for the command,
456 * It starts out with stack-allocated space but uses dynamically-
457 * allocated storage to increase it if needed.
461 char *(argStorage
[NUM_ARGS
]);
462 char **argv
= argStorage
;
464 int argSize
= NUM_ARGS
;
466 register char *src
; /* Points to current character
468 char termChar
; /* Return when this character is found
469 * (either ']' or '\0'). Zero means
470 * that newlines terminate commands. */
471 int result
; /* Return value. */
472 register Interp
*iPtr
= (Interp
*) interp
;
475 char *dummy
; /* Make termPtr point here if it was
476 * originally NULL. */
477 char *cmdStart
; /* Points to first non-blank char. in
478 * command (used in calling trace
480 char *ellipsis
= ""; /* Used in setting errorInfo variable;
481 * set to "..." to indicate that not
482 * all of offending command is included
483 * in errorInfo. "" means that the
484 * command is all there. */
485 register Trace
*tracePtr
;
488 * Initialize the result to an empty string and clear out any
489 * error information. This makes sure that we return an empty
490 * result if there are no commands in the command string.
493 Tcl_FreeResult((Tcl_Interp
*) iPtr
);
494 iPtr
->result
= iPtr
->resultSpace
;
495 iPtr
->resultSpace
[0] = 0;
499 * Check depth of nested calls to Tcl_Eval: if this gets too large,
500 * it's probably because of an infinite loop somewhere.
504 if (iPtr
->numLevels
> MAX_NESTING_DEPTH
) {
506 iPtr
->result
= "too many nested calls to Tcl_Eval (infinite loop?)";
511 * Initialize the area in which command copies will be assembled.
514 pv
.buffer
= copyStorage
;
515 pv
.end
= copyStorage
+ NUM_CHARS
- 1;
516 pv
.expandProc
= TclExpandParseValue
;
517 pv
.clientData
= (ClientData
) NULL
;
520 if (flags
& TCL_BRACKET_TERM
) {
525 if (termPtr
== NULL
) {
532 * There can be many sub-commands (separated by semi-colons or
533 * newlines) in one command string. This outer loop iterates over
534 * individual commands.
537 while (*src
!= termChar
) {
538 iPtr
->flags
&= ~(ERR_IN_PROGRESS
| ERROR_CODE_SET
);
541 * Skim off leading white space and semi-colons, and skip
546 register char c
= *src
;
548 if ((CHAR_TYPE(c
) != TCL_SPACE
) && (c
!= ';') && (c
!= '\n')) {
554 for (src
++; *src
!= 0; src
++) {
565 * Parse the words of the command, generating the argc and
566 * argv for the command procedure. May have to call
567 * TclParseWords several times, expanding the argv array
571 pv
.next
= oldBuffer
= pv
.buffer
;
574 int newArgs
, maxArgs
;
579 * Note: the "- 2" below guarantees that we won't use the
580 * last two argv slots here. One is for a NULL pointer to
581 * mark the end of the list, and the other is to leave room
582 * for inserting the command name "unknown" as the first
583 * argument (see below).
586 maxArgs
= argSize
- argc
- 2;
587 result
= TclParseWords((Tcl_Interp
*) iPtr
, src
, flags
,
588 maxArgs
, termPtr
, &newArgs
, &argv
[argc
], &pv
);
590 if (result
!= TCL_OK
) {
596 * Careful! Buffer space may have gotten reallocated while
597 * parsing words. If this happened, be sure to update all
598 * of the older argv pointers to refer to the new space.
601 if (oldBuffer
!= pv
.buffer
) {
604 for (i
= 0; i
< argc
; i
++) {
605 argv
[i
] = pv
.buffer
+ (argv
[i
] - oldBuffer
);
607 oldBuffer
= pv
.buffer
;
610 if (newArgs
< maxArgs
) {
611 argv
[argc
] = (char *) NULL
;
616 * Args didn't all fit in the current array. Make it bigger.
621 ckalloc((unsigned) argSize
* sizeof(char *));
622 for (i
= 0; i
< argc
; i
++) {
623 newArgv
[i
] = argv
[i
];
625 if (argv
!= argStorage
) {
626 ckfree((char *) argv
);
632 * If this is an empty command (or if we're just parsing
633 * commands without evaluating them), then just skip to the
637 if ((argc
== 0) || iPtr
->noEval
) {
643 * Save information for the history module, if needed.
646 if (flags
& TCL_RECORD_BOUNDS
) {
647 iPtr
->evalFirst
= cmdStart
;
648 iPtr
->evalLast
= src
-1;
652 * Find the procedure to execute this command. If there isn't
653 * one, then see if there is a command "unknown". If so,
654 * invoke it instead, passing it the words of the original
655 * command as arguments.
658 hPtr
= Tcl_FindHashEntry(&iPtr
->commandTable
, argv
[0]);
662 hPtr
= Tcl_FindHashEntry(&iPtr
->commandTable
, "unknown");
664 Tcl_ResetResult(interp
);
665 Tcl_AppendResult(interp
, "invalid command name: \"",
666 argv
[0], "\"", (char *) NULL
);
670 for (i
= argc
; i
>= 0; i
--) {
676 cmdPtr
= (Command
*) Tcl_GetHashValue(hPtr
);
679 * Call trace procedures, if any.
682 for (tracePtr
= iPtr
->tracePtr
; tracePtr
!= NULL
;
683 tracePtr
= tracePtr
->nextPtr
) {
686 if (tracePtr
->level
< iPtr
->numLevels
) {
691 (*tracePtr
->proc
)(tracePtr
->clientData
, interp
, iPtr
->numLevels
,
692 cmdStart
, cmdPtr
->proc
, cmdPtr
->clientData
, argc
, argv
);
697 * At long last, invoke the command procedure. Reset the
698 * result to its default empty value first (it could have
699 * gotten changed by earlier commands in the same command
704 Tcl_FreeResult(iPtr
);
705 iPtr
->result
= iPtr
->resultSpace
;
706 iPtr
->resultSpace
[0] = 0;
707 result
= (*cmdPtr
->proc
)(cmdPtr
->clientData
, interp
, argc
, argv
);
708 if (result
!= TCL_OK
) {
714 * Free up any extra resources that were allocated.
718 if (pv
.buffer
!= copyStorage
) {
719 ckfree((char *) pv
.buffer
);
721 if (argv
!= argStorage
) {
722 ckfree((char *) argv
);
725 if (iPtr
->numLevels
== 0) {
726 if (result
== TCL_RETURN
) {
729 if ((result
!= TCL_OK
) && (result
!= TCL_ERROR
)) {
730 Tcl_ResetResult(interp
);
731 if (result
== TCL_BREAK
) {
732 iPtr
->result
= "invoked \"break\" outside of a loop";
733 } else if (result
== TCL_CONTINUE
) {
734 iPtr
->result
= "invoked \"continue\" outside of a loop";
736 iPtr
->result
= iPtr
->resultSpace
;
737 sprintf(iPtr
->resultSpace
, "command returned bad code: %d",
742 if (iPtr
->flags
& DELETED
) {
743 Tcl_DeleteInterp(interp
);
748 * If an error occurred, record information about what was being
749 * executed when the error occurred.
752 if ((result
== TCL_ERROR
) && !(iPtr
->flags
& ERR_ALREADY_LOGGED
)) {
757 * Compute the line number where the error occurred.
761 for (p
= cmd
; p
!= cmdStart
; p
++) {
766 for ( ; isspace(*p
) || (*p
== ';'); p
++) {
773 * Figure out how much of the command to print in the error
774 * message (up to a certain number of characters, or up to
775 * the first new-line).
778 numChars
= src
- cmdStart
;
779 if (numChars
> (NUM_CHARS
-50)) {
780 numChars
= NUM_CHARS
-50;
784 if (!(iPtr
->flags
& ERR_IN_PROGRESS
)) {
785 sprintf(copyStorage
, "\n while executing\n\"%.*s%s\"",
786 numChars
, cmdStart
, ellipsis
);
788 sprintf(copyStorage
, "\n invoked from within\n\"%.*s%s\"",
789 numChars
, cmdStart
, ellipsis
);
791 Tcl_AddErrorInfo(interp
, copyStorage
);
792 iPtr
->flags
&= ~ERR_ALREADY_LOGGED
;
794 iPtr
->flags
&= ~ERR_ALREADY_LOGGED
;
800 *----------------------------------------------------------------------
804 * Arrange for a procedure to be called to trace command execution.
807 * The return value is a token for the trace, which may be passed
808 * to Tcl_DeleteTrace to eliminate the trace.
811 * From now on, proc will be called just before a command procedure
812 * is called to execute a Tcl command. Calls to proc will have the
816 * proc(clientData, interp, level, command, cmdProc, cmdClientData,
818 * ClientData clientData;
819 * Tcl_Interp *interp;
823 * ClientData cmdClientData;
829 * The clientData and interp arguments to proc will be the same
830 * as the corresponding arguments to this procedure. Level gives
831 * the nesting level of command interpretation for this interpreter
832 * (0 corresponds to top level). Command gives the ASCII text of
833 * the raw command, cmdProc and cmdClientData give the procedure that
834 * will be called to process the command and the ClientData value it
835 * will receive, and argc and argv give the arguments to the
836 * command, after any argument parsing and substitution. Proc
837 * does not return a value.
839 *----------------------------------------------------------------------
843 Tcl_CreateTrace(interp
, level
, proc
, clientData
)
844 Tcl_Interp
*interp
; /* Interpreter in which to create the trace. */
845 int level
; /* Only call proc for commands at nesting level
846 * <= level (1 => top level). */
847 Tcl_CmdTraceProc
*proc
; /* Procedure to call before executing each
849 ClientData clientData
; /* Arbitrary one-word value to pass to proc. */
851 register Trace
*tracePtr
;
852 register Interp
*iPtr
= (Interp
*) interp
;
854 tracePtr
= (Trace
*) ckalloc(sizeof(Trace
));
855 tracePtr
->level
= level
;
856 tracePtr
->proc
= proc
;
857 tracePtr
->clientData
= clientData
;
858 tracePtr
->nextPtr
= iPtr
->tracePtr
;
859 iPtr
->tracePtr
= tracePtr
;
861 return (Tcl_Trace
) tracePtr
;
865 *----------------------------------------------------------------------
875 * From now on there will be no more calls to the procedure given
878 *----------------------------------------------------------------------
882 Tcl_DeleteTrace(interp
, trace
)
883 Tcl_Interp
*interp
; /* Interpreter that contains trace. */
884 Tcl_Trace trace
; /* Token for trace (returned previously by
885 * Tcl_CreateTrace). */
887 register Interp
*iPtr
= (Interp
*) interp
;
888 register Trace
*tracePtr
= (Trace
*) trace
;
889 register Trace
*tracePtr2
;
891 if (iPtr
->tracePtr
== tracePtr
) {
892 iPtr
->tracePtr
= tracePtr
->nextPtr
;
893 ckfree((char *) tracePtr
);
895 for (tracePtr2
= iPtr
->tracePtr
; tracePtr2
!= NULL
;
896 tracePtr2
= tracePtr2
->nextPtr
) {
897 if (tracePtr2
->nextPtr
== tracePtr
) {
898 tracePtr2
->nextPtr
= tracePtr
->nextPtr
;
899 ckfree((char *) tracePtr
);
907 *----------------------------------------------------------------------
909 * Tcl_AddErrorInfo --
911 * Add information to a message being accumulated that describes
918 * The contents of message are added to the "errorInfo" variable.
919 * If Tcl_Eval has been called since the current value of errorInfo
920 * was set, errorInfo is cleared before adding the new message.
922 *----------------------------------------------------------------------
926 Tcl_AddErrorInfo(interp
, message
)
927 Tcl_Interp
*interp
; /* Interpreter to which error information
929 char *message
; /* Message to record. */
931 register Interp
*iPtr
= (Interp
*) interp
;
934 * If an error is already being logged, then the new errorInfo
935 * is the concatenation of the old info and the new message.
936 * If this is the first piece of info for the error, then the
937 * new errorInfo is the concatenation of the message in
938 * interp->result and the new message.
941 if (!(iPtr
->flags
& ERR_IN_PROGRESS
)) {
942 Tcl_SetVar2(interp
, "errorInfo", (char *) NULL
, interp
->result
,
944 iPtr
->flags
|= ERR_IN_PROGRESS
;
947 * If the errorCode variable wasn't set by the code that generated
948 * the error, set it to "NONE".
951 if (!(iPtr
->flags
& ERROR_CODE_SET
)) {
952 (void) Tcl_SetVar2(interp
, "errorCode", (char *) NULL
, "NONE",
956 Tcl_SetVar2(interp
, "errorInfo", (char *) NULL
, message
,
957 TCL_GLOBAL_ONLY
|TCL_APPEND_VALUE
);
961 *----------------------------------------------------------------------
965 * Given a variable number of string arguments, concatenate them
966 * all together and execute the result as a Tcl command.
969 * A standard Tcl return result. An error message or other
970 * result may be left in interp->result.
973 * Depends on what was done by the command.
975 *----------------------------------------------------------------------
978 Tcl_VarEval(Tcl_Interp
*interp
, ...)
981 #define FIXED_SIZE 200
982 char fixedSpace
[FIXED_SIZE
+1];
983 int spaceAvl
, spaceUsed
, length
;
988 * Copy the strings one after the other into a single larger
989 * string. Use stack-allocated space for small commands, but if
990 * the commands gets too large than call ckalloc to create the
994 va_start(argList
, interp
);
995 spaceAvl
= FIXED_SIZE
;
999 string
= va_arg(argList
, char *);
1000 if (string
== NULL
) {
1003 length
= strlen(string
);
1004 if ((spaceUsed
+ length
) > spaceAvl
) {
1007 spaceAvl
= spaceUsed
+ length
;
1008 spaceAvl
+= spaceAvl
/2;
1009 new = ckalloc((unsigned) spaceAvl
);
1010 memcpy((VOID
*) new, (VOID
*) cmd
, spaceUsed
);
1011 if (cmd
!= fixedSpace
) {
1016 strcpy(cmd
+ spaceUsed
, string
);
1017 spaceUsed
+= length
;
1020 cmd
[spaceUsed
] = '\0';
1022 result
= Tcl_Eval(interp
, cmd
, 0, (char **) NULL
);
1023 if (cmd
!= fixedSpace
) {
1030 *----------------------------------------------------------------------
1034 * Evaluate a command at global level in an interpreter.
1037 * A standard Tcl result is returned, and interp->result is
1038 * modified accordingly.
1041 * The command string is executed in interp, and the execution
1042 * is carried out in the variable context of global level (no
1043 * procedures active), just as if an "uplevel #0" command were
1046 *----------------------------------------------------------------------
1050 Tcl_GlobalEval(interp
, command
)
1051 Tcl_Interp
*interp
; /* Interpreter in which to evaluate command. */
1052 char *command
; /* Command to evaluate. */
1054 register Interp
*iPtr
= (Interp
*) interp
;
1056 CallFrame
*savedVarFramePtr
;
1058 savedVarFramePtr
= iPtr
->varFramePtr
;
1059 iPtr
->varFramePtr
= NULL
;
1060 result
= Tcl_Eval(interp
, command
, 0, (char **) NULL
);
1061 iPtr
->varFramePtr
= savedVarFramePtr
;