예제 #1
0
        internal static void create(Interp interp, Interp slaveInterp, Interp masterInterp, TclObject name, TclObject targetName, int objIx, TclObject[] objv)
        {
            string inString = name.ToString();

            InterpAliasCmd alias = new InterpAliasCmd();

            alias.name = name;
            name.Preserve();

            alias.slaveInterp  = slaveInterp;
            alias.targetInterp = masterInterp;

            alias.prefix = TclList.NewInstance();
            alias.prefix.Preserve();
            TclList.Append(interp, alias.prefix, targetName);
            TclList.insert(interp, alias.prefix, 1, objv, objIx, objv.Length - 1);

            slaveInterp.CreateCommand(inString, alias);
            alias.slaveCmd = NamespaceCmd.findCommand(slaveInterp, inString, null, 0);

            try
            {
                interp.preventAliasLoop(slaveInterp, alias.slaveCmd);
            }
            catch (TclException e)
            {
                // Found an alias loop!  The last call to Tcl_CreateObjCommand made
                // the alias point to itself.  Delete the command and its alias
                // record.  Be careful to wipe out its client data first, so the
                // command doesn't try to delete itself.

                slaveInterp.DeleteCommandFromToken(alias.slaveCmd);
                throw;
            }

            // Make an entry in the alias table. If it already exists delete
            // the alias command. Then retry.

            if (slaveInterp._aliasTable.ContainsKey(inString))
            {
                InterpAliasCmd oldAlias = (InterpAliasCmd)slaveInterp._aliasTable[inString];
                slaveInterp.DeleteCommandFromToken(oldAlias.slaveCmd);
            }

            alias.aliasEntry = inString;
            SupportClass.PutElement(slaveInterp._aliasTable, inString, alias);

            // Create the new command. We must do it after deleting any old command,
            // because the alias may be pointing at a renamed alias, as in:
            //
            // interp alias {} foo {} bar		# Create an alias "foo"
            // rename foo zop				# Now rename the alias
            // interp alias {} foo {} zop		# Now recreate "foo"...

            SupportClass.PutElement(masterInterp._targetTable, alias.slaveCmd, slaveInterp);

            interp.SetResult(name);
        }
예제 #2
0
        /// <summary>
        /// Load the class that implements the given command and execute it.
        /// </summary>
        /// <param name="interp">
        /// the current interpreter.
        /// </param>
        /// <param name="argv">
        /// command arguments.
        /// </param>
        /// <exception cref="">
        /// TclException if error happens inside the real command proc.
        /// </exception>
        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            Type     cmdClass = null;
            ICommand cmd;

            try { cmdClass = Type.GetType(className, true); }
            catch (Exception) { throw new TclException(interp, "ClassNotFoundException for class \"" + className + "\""); }
            try { cmd = (ICommand)SupportClass.CreateNewInstance(cmdClass); }
            catch (UnauthorizedAccessException) { throw new TclException(interp, "IllegalAccessException for class \"" + cmdClass.FullName + "\""); }
            catch (InvalidCastException) { throw new TclException(interp, "ClassCastException for class \"" + cmdClass.FullName + "\""); }
            catch (Exception) { throw new TclException(interp, "InstantiationException for class \"" + cmdClass.FullName + "\""); }
            interp.CreateCommand(argv[0].ToString(), cmd);
            TCL.CompletionCode rc = cmd.CmdProc(interp, argv);
            return(rc == TCL.CompletionCode.EXIT ? TCL.CompletionCode.EXIT : TCL.CompletionCode.RETURN);
        }
예제 #3
0
        /// <summary>
        /// Tcl_ProcObjCmd -> ProcCmd.cmdProc
        ///
        /// Creates a new Tcl procedure.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="objv">command arguments.
        /// </param>
        /// <exception cref=""> TclException If incorrect number of arguments.
        /// </exception>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv)
        {
            Procedure proc;
            string    fullName, procName;

            NamespaceCmd.Namespace ns, altNs, cxtNs;
            ICommand      cmd;
            StringBuilder ds;

            if (objv.Length != 4)
            {
                throw new TclNumArgsException(interp, 1, objv, "name args body");
            }

            // Determine the namespace where the procedure should reside. Unless
            // the command name includes namespace qualifiers, this will be the
            // current namespace.


            fullName = objv[1].ToString();

            // Java does not support passing an address so we pass
            // an array of size 1 and then assign arr[0] to the value
            NamespaceCmd.Namespace[] nsArr    = new NamespaceCmd.Namespace[1];
            NamespaceCmd.Namespace[] altNsArr = new NamespaceCmd.Namespace[1];
            NamespaceCmd.Namespace[] cxtNsArr = new NamespaceCmd.Namespace[1];
            string[] procNameArr = new string[1];

            NamespaceCmd.getNamespaceForQualName(interp, fullName, null, 0, nsArr, altNsArr, cxtNsArr, procNameArr);

            // Get the values out of the arrays
            ns       = nsArr[0];
            altNs    = altNsArr[0];
            cxtNs    = cxtNsArr[0];
            procName = procNameArr[0];

            if (ns == null)
            {
                throw new TclException(interp, "can't create procedure \"" + fullName + "\": unknown namespace");
            }
            if ((System.Object)procName == null)
            {
                throw new TclException(interp, "can't create procedure \"" + fullName + "\": bad procedure name");
            }
            // FIXME : could there be a problem with a command named ":command" ?
            if ((ns != NamespaceCmd.getGlobalNamespace(interp)) && ((System.Object)procName != null) && ((procName.Length > 0) && (procName[0] == ':')))
            {
                throw new TclException(interp, "can't create procedure \"" + procName + "\" in non-global namespace with name starting with \":\"");
            }

            //  Create the data structure to represent the procedure.

            proc = new Procedure(interp, ns, procName, objv[2], objv[3], interp.ScriptFile, interp.getArgLineNumber(3));

            // Now create a command for the procedure. This will initially be in
            // the current namespace unless the procedure's name included namespace
            // qualifiers. To create the new command in the right namespace, we
            // generate a fully qualified name for it.

            ds = new StringBuilder();
            if (ns != NamespaceCmd.getGlobalNamespace(interp))
            {
                ds.Append(ns.fullName);
                ds.Append("::");
            }
            ds.Append(procName);

            interp.CreateCommand(ds.ToString(), proc);

            // Now initialize the new procedure's cmdPtr field. This will be used
            // later when the procedure is called to determine what namespace the
            // procedure will run in. This will be different than the current
            // namespace if the proc was renamed into a different namespace.

            // FIXME : we do not handle renaming into another namespace correctly yet!
            //procPtr->cmdPtr = (Command *) cmd;

            return(TCL.CompletionCode.RETURN);
        }
예제 #4
0
 internal static void Init(Interp interp)
 // Current interpreter.
 {
     interp.CreateCommand("regexp", new Tcl.Lang.RegexpCmd());
     interp.CreateCommand("regsub", new Tcl.Lang.RegsubCmd());
 }
예제 #5
0
        internal static Interp create(Interp interp, TclObject path, bool safe)
        {
            Interp masterInterp;
            string pathString;

            TclObject[] objv = TclList.getElements(interp, path);

            if (objv.Length < 2)
            {
                masterInterp = interp;

                pathString = path.ToString();
            }
            else
            {
                TclObject obj = TclList.NewInstance();

                TclList.insert(interp, obj, 0, objv, 0, objv.Length - 2);
                masterInterp = InterpCmd.getInterp(interp, obj);

                pathString = objv[objv.Length - 1].ToString();
            }
            if (!safe)
            {
                safe = masterInterp._isSafe;
            }

            if (masterInterp._slaveTable.ContainsKey(pathString))
            {
                throw new TclException(interp, "interpreter named \"" + pathString + "\" already exists, cannot create");
            }

            Interp         slaveInterp = new Interp();
            InterpSlaveCmd slave       = new InterpSlaveCmd();

            slaveInterp._slave = slave;
            slaveInterp.SetAssocData("InterpSlaveCmd", slave);

            slave.masterInterp = masterInterp;
            slave.path         = pathString;
            slave.slaveInterp  = slaveInterp;

            masterInterp.CreateCommand(pathString, slaveInterp._slave);
            slaveInterp._slave.interpCmd = NamespaceCmd.findCommand(masterInterp, pathString, null, 0);

            SupportClass.PutElement(masterInterp._slaveTable, pathString, slaveInterp._slave);

            slaveInterp.SetVar("tcl_interactive", "0", TCL.VarFlag.GLOBAL_ONLY);

            // Inherit the recursion limit.

            slaveInterp._maxNestingDepth = masterInterp._maxNestingDepth;

            if (safe)
            {
                try
                {
                    makeSafe(slaveInterp);
                }
                catch (TclException e)
                {
                    SupportClass.WriteStackTrace(e, Console.Error);
                }
            }
            else
            {
                //Tcl_Init(slaveInterp);
            }

            return(slaveInterp);
        }
예제 #6
0
 /// <summary>
 /// Create a stub command which autoloads the real command the first time the stub command is invoked. Register the stub command in the	 interpreter.
 /// </summary>
 /// <param name="interp">
 /// current interp.
 /// </param>
 /// <param name="cmdName">
 /// name of the command, e.g., "after".
 /// </param>
 /// <param name="clsName">
 /// name of the Java class that implements this command, e.g. "tcl.lang.AfterCmd"
 /// </param>
 public static void LoadOnDemand(Interp interp, string cmdName, string clsName)
 {
     interp.CreateCommand(cmdName, new AutoloadStub(clsName));
 }