summaryrefslogtreecommitdiffstats
path: root/generic/tclEnsemble.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2010-12-09 15:09:07 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2010-12-09 15:09:07 (GMT)
commitee6985ab9eed245164bf1078496d5b7efbabdd9c (patch)
treece38d69f9ab51ef0a83d6e83b49177e042a74a31 /generic/tclEnsemble.c
parent04d3371ea6033290def691a38224ba78356f0a9a (diff)
downloadtcl-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.c43
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);
}