summaryrefslogtreecommitdiffstats
path: root/generic/tclNamesp.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2007-11-21 14:30:22 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2007-11-21 14:30:22 (GMT)
commit6e360c3d1ad0bbf16377cf5d2d9f8eac1f8092a8 (patch)
tree833b08f4554fe3791997147f2fbf9f826b62860b /generic/tclNamesp.c
parent98ce25af617901be6af682a617c9b35abee2c548 (diff)
downloadtcl-6e360c3d1ad0bbf16377cf5d2d9f8eac1f8092a8.zip
tcl-6e360c3d1ad0bbf16377cf5d2d9f8eac1f8092a8.tar.gz
tcl-6e360c3d1ad0bbf16377cf5d2d9f8eac1f8092a8.tar.bz2
Factor out the core compiled-ensemble builder for simplicity.
Diffstat (limited to 'generic/tclNamesp.c')
-rw-r--r--generic/tclNamesp.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c
index bab0684..d8023a7 100644
--- a/generic/tclNamesp.c
+++ b/generic/tclNamesp.c
@@ -23,7 +23,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclNamesp.c,v 1.157 2007/11/19 11:02:40 dkf Exp $
+ * RCS: @(#) $Id: tclNamesp.c,v 1.158 2007/11/21 14:30:34 dkf Exp $
*/
#include "tclInt.h"
@@ -5875,6 +5875,80 @@ Tcl_IsEnsemble(
/*
*----------------------------------------------------------------------
*
+ * TclMakeEnsemble --
+ *
+ * Create an ensemble from a table of implementation commands. The
+ * ensemble will be subject to (limited) compilation if any of the
+ * implementation commands are compilable.
+ *
+ * Results:
+ * Handle for the ensemble, or NULL if creation of it fails.
+ *
+ * Side effects:
+ * May advance bytecode compilation epoch.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+TclMakeEnsemble(
+ Tcl_Interp *interp,
+ const char *name,
+ const EnsembleImplMap map[])
+{
+ Tcl_Command ensemble; /* The overall ensemble. */
+ Tcl_Namespace *tclNsPtr; /* Reference to the "::tcl" namespace. */
+ Tcl_DString buf;
+
+ tclNsPtr = Tcl_FindNamespace(interp, "::tcl", NULL,
+ TCL_CREATE_NS_IF_UNKNOWN);
+ if (tclNsPtr == NULL) {
+ Tcl_Panic("unable to find or create ::tcl namespace!");
+ }
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, "::tcl::", -1);
+ Tcl_DStringAppend(&buf, name, -1);
+ tclNsPtr = Tcl_FindNamespace(interp, Tcl_DStringValue(&buf), NULL,
+ TCL_CREATE_NS_IF_UNKNOWN);
+ if (tclNsPtr == NULL) {
+ Tcl_Panic("unable to find or create %s namespace!",
+ Tcl_DStringValue(&buf));
+ }
+ ensemble = Tcl_CreateEnsemble(interp, Tcl_DStringValue(&buf)+5, tclNsPtr,
+ TCL_ENSEMBLE_PREFIX);
+ Tcl_DStringAppend(&buf, "::", -1);
+ if (ensemble != NULL) {
+ Tcl_Obj *mapDict;
+ int i, compile = 0;
+
+ TclNewObj(mapDict);
+ for (i=0 ; map[i].name != NULL ; i++) {
+ Tcl_Obj *fromObj, *toObj;
+ Command *cmdPtr;
+
+ fromObj = Tcl_NewStringObj(map[i].name, -1);
+ TclNewStringObj(toObj, Tcl_DStringValue(&buf),
+ Tcl_DStringLength(&buf));
+ Tcl_AppendToObj(toObj, map[i].name, -1);
+ Tcl_DictObjPut(NULL, mapDict, fromObj, toObj);
+ cmdPtr = (Command *) Tcl_CreateObjCommand(interp,
+ TclGetString(toObj), map[i].proc, NULL, NULL);
+ cmdPtr->compileProc = map[i].compileProc;
+ compile |= (map[i].compileProc != NULL);
+ }
+ Tcl_SetEnsembleMappingDict(interp, ensemble, mapDict);
+ if (compile) {
+ Tcl_SetEnsembleFlags(interp, ensemble,
+ TCL_ENSEMBLE_PREFIX | ENSEMBLE_COMPILE);
+ }
+ }
+
+ return ensemble;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* NsEnsembleImplementationCmd --
*
* Implements an ensemble of commands (being those exported by a