diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2010-12-09 15:09:07 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2010-12-09 15:09:07 (GMT) |
commit | ee6985ab9eed245164bf1078496d5b7efbabdd9c (patch) | |
tree | ce38d69f9ab51ef0a83d6e83b49177e042a74a31 /generic/tclEnsemble.c | |
parent | 04d3371ea6033290def691a38224ba78356f0a9a (diff) | |
download | tcl-ee6985ab9eed245164bf1078496d5b7efbabdd9c.zip tcl-ee6985ab9eed245164bf1078496d5b7efbabdd9c.tar.gz tcl-ee6985ab9eed245164bf1078496d5b7efbabdd9c.tar.bz2 |
* generic/tclCmdAH.c (TclInitFileCmd, TclMakeFileCommandSafe, ...):
Break up [file] into an ensemble. Note that the ensemble is safe in
itself, but the majority of its subcommands are not.
* generic/tclFCmd.c (FileCopyRename,TclFileDeleteCmd,TclFileAttrsCmd)
(TclFileMakeDirsCmd): Adjust these subcommand implementations to work
inside an ensemble.
(TclFileLinkCmd, TclFileReadLinkCmd, TclFileTemporaryCmd): Move these
subcommand implementations from tclCmdAH.c, where they didn't really
belong.
* generic/tclIOCmd.c (TclChannelNamesCmd): Move to more appropriate
source file.
* generic/tclEnsemble.c (TclMakeEnsemble): Start of code to make
partially-safe ensembles. Currently does not function as expected due
to various shortcomings in how safe interpreters are constructed.
* tests/cmdAH.test, tests/fCmd.test, tests/interp.test: Test updates
to take into account systematization of error messages.
Diffstat (limited to 'generic/tclEnsemble.c')
-rw-r--r-- | generic/tclEnsemble.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index c4750c5..cfdeb94 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclEnsemble.c,v 1.5 2010/03/05 14:34:04 dkf Exp $ + * RCS: @(#) $Id: tclEnsemble.c,v 1.6 2010/12/09 15:09:07 dkf Exp $ */ #include "tclInt.h" @@ -1417,16 +1417,21 @@ TclMakeEnsemble( { Tcl_Command ensemble; Tcl_Namespace *ns; - Tcl_DString buf; + Tcl_DString buf, hiddenBuf; const char **nameParts = NULL; const char *cmdName = NULL; - int i, nameCount = 0, ensembleFlags = 0; + int i, nameCount = 0, ensembleFlags = 0, hiddenLen; /* * Construct the path for the ensemble namespace and create it. */ Tcl_DStringInit(&buf); + Tcl_DStringInit(&hiddenBuf); + Tcl_DStringAppend(&hiddenBuf, "tcl:", -1); + Tcl_DStringAppend(&hiddenBuf, name, -1); + Tcl_DStringAppend(&hiddenBuf, ":", -1); + hiddenLen = Tcl_DStringLength(&hiddenBuf); if (name[0] == ':' && name[1] == ':') { /* * An absolute name, so use it directly. @@ -1491,10 +1496,35 @@ TclMakeEnsemble( Tcl_DStringLength(&buf)); Tcl_AppendToObj(toObj, map[i].name, -1); Tcl_DictObjPut(NULL, mapDict, fromObj, toObj); + if (map[i].proc || map[i].nreProc) { - cmdPtr = (Command *) - Tcl_NRCreateCommand(interp, TclGetString(toObj), - map[i].proc, map[i].nreProc, map[i].clientData, NULL); + /* + * If the command is unsafe, hide it when we're in a safe + * interpreter. The code to do this is really hokey! It also + * doesn't work properly yet; this function is always + * currently called before the safe-interp flag is set so the + * Tcl_IsSafe check fails. + */ + + if (map[i].unsafe && Tcl_IsSafe(interp)) { + cmdPtr = (Command *) + Tcl_NRCreateCommand(interp, "___tmp", map[i].proc, + map[i].nreProc, map[i].clientData, NULL); + Tcl_DStringSetLength(&hiddenBuf, hiddenLen); + if (Tcl_HideCommand(interp, "___tmp", + Tcl_DStringAppend(&hiddenBuf, map[i].name, -1))) { + Tcl_Panic(Tcl_GetString(Tcl_GetObjResult(interp))); + } + } else { + /* + * Not hidden, so just create it. Yay! + */ + + cmdPtr = (Command *) + Tcl_NRCreateCommand(interp, TclGetString(toObj), + map[i].proc, map[i].nreProc, map[i].clientData, + NULL); + } cmdPtr->compileProc = map[i].compileProc; if (map[i].compileProc != NULL) { ensembleFlags |= ENSEMBLE_COMPILE; @@ -1508,6 +1538,7 @@ TclMakeEnsemble( } Tcl_DStringFree(&buf); + Tcl_DStringFree(&hiddenBuf); if (nameParts != NULL) { Tcl_Free((char *) nameParts); } |