コード例 #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
ファイル: RegexpCmd.cs プロジェクト: Belxjander/Asuna
		internal static void  init(Interp interp)
		// Current interpreter. 
		{
			interp.createCommand("regexp", new tcl.lang.RegexpCmd());
			interp.createCommand("regsub", new tcl.lang.RegsubCmd());
		}
コード例 #3
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 ) );
    }
コード例 #4
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;
      Command cmd;
      try
      {
        cmdClass = System.Type.GetType( className, true );
      }
      catch ( System.Exception e )
      {
        throw new TclException( interp, "ClassNotFoundException for class \"" + className + "\"" );
      }

      try
      {
        cmd = (Command)SupportClass.CreateNewInstance( cmdClass );
      }
      catch ( System.UnauthorizedAccessException e1 )
      {
        throw new TclException( interp, "IllegalAccessException for class \"" + cmdClass.FullName + "\"" );
      }
      catch ( System.InvalidCastException e3 )
      {
        throw new TclException( interp, "ClassCastException for class \"" + cmdClass.FullName + "\"" );
      }
      catch ( System.Exception e2 )
      {
        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;
    }
コード例 #5
0
ファイル: NamespaceCmd.cs プロジェクト: Belxjander/Asuna
		/*
		*----------------------------------------------------------------------
		*
		* Tcl_Import -> importList
		*
		*	Imports all of the commands matching a pattern into the namespace
		*	specified by namespace (or the current namespace if namespace
		*	is null). This is done by creating a new command (the "imported
		*	command") that points to the real command in its original namespace.
		*
		*      If matching commands are on the autoload path but haven't been
		*	loaded yet, this command forces them to be loaded, then creates
		*	the links to them.
		*
		* Results:
		*  Returns if successful, raises TclException if something goes wrong.
		*
		* Side effects:
		*	Creates new commands in the importing namespace. These indirect
		*	calls back to the real command and are deleted if the real commands
		*	are deleted.
		*
		*----------------------------------------------------------------------
		*/
		
		internal static void  importList(Interp interp, Namespace namespace_Renamed, string pattern, bool allowOverwrite)
		{
			Namespace ns, importNs;
			Namespace currNs = getCurrentNamespace(interp);
			string simplePattern, cmdName;
			IEnumerator search;
			WrappedCommand cmd, realCmd;
			ImportRef ref_Renamed;
			WrappedCommand autoCmd, importedCmd;
			ImportedCmdData data;
			bool wasExported;
			int i, result;
			
			// If the specified namespace is null, use the current namespace.
			
			if (namespace_Renamed == null)
			{
				ns = currNs;
			}
			else
			{
				ns = namespace_Renamed;
			}
			
			// First, invoke the "auto_import" command with the pattern
			// being imported.  This command is part of the Tcl library.
			// It looks for imported commands in autoloaded libraries and
			// loads them in.  That way, they will be found when we try
			// to create links below.
			
			autoCmd = findCommand(interp, "auto_import", null, TCL.VarFlag.GLOBAL_ONLY);
			
			if (autoCmd != null)
			{
				TclObject[] objv = new TclObject[2];
				
				objv[0] = TclString.newInstance("auto_import");
				objv[0].preserve();
				objv[1] = TclString.newInstance(pattern);
				objv[1].preserve();
				
				cmd = autoCmd;
				try
				{
					// Invoke the command with the arguments
					cmd.cmd.cmdProc(interp, objv);
				}
				finally
				{
					objv[0].release();
					objv[1].release();
				}
				
				interp.resetResult();
			}
			
			// From the pattern, find the namespace from which we are importing
			// and get the simple pattern (no namespace qualifiers or ::'s) at
			// the end.
			
			if (pattern.Length == 0)
			{
				throw new TclException(interp, "empty import pattern");
			}
			
			// Java does not support passing an address so we pass
			// an array of size 1 and then assign arr[0] to the value
			Namespace[] importNsArr = new Namespace[1];
			Namespace[] dummyArr = new Namespace[1];
			string[] simplePatternArr = new string[1];
			
			getNamespaceForQualName(interp, pattern, ns, TCL.VarFlag.LEAVE_ERR_MSG, importNsArr, dummyArr, dummyArr, simplePatternArr);
			
			importNs = importNsArr[0];
			simplePattern = simplePatternArr[0];
			
			if (importNs == null)
			{
				throw new TclException(interp, "unknown namespace in import pattern \"" + pattern + "\"");
			}
			if (importNs == ns)
			{
				if ((System.Object) pattern == (System.Object) simplePattern)
				{
					throw new TclException(interp, "no namespace specified in import pattern \"" + pattern + "\"");
				}
				else
				{
					throw new TclException(interp, "import pattern \"" + pattern + "\" tries to import from namespace \"" + importNs.name + "\" into itself");
				}
			}
			
			// Scan through the command table in the source namespace and look for
			// exported commands that match the string pattern. Create an "imported
			// command" in the current namespace for each imported command; these
			// commands redirect their invocations to the "real" command.
			
			
			for (search = importNs.cmdTable.Keys.GetEnumerator(); search.MoveNext(); )
			{
				
				cmdName = ((string) search.Current);
				if (Util.stringMatch(cmdName, simplePattern))
				{
					// The command cmdName in the source namespace matches the
					// pattern. Check whether it was exported. If it wasn't,
					// we ignore it.
					
					wasExported = false;
					for (i = 0; i < importNs.numExportPatterns; i++)
					{
						if (Util.stringMatch(cmdName, importNs.exportArray[i]))
						{
							wasExported = true;
							break;
						}
					}
					if (!wasExported)
					{
						continue;
					}
					
					// Unless there is a name clash, create an imported command
					// in the current namespace that refers to cmdPtr.
					
					if ((ns.cmdTable[cmdName] == null) || allowOverwrite)
					{
						// Create the imported command and its client data.
						// To create the new command in the current namespace, 
						// generate a fully qualified name for it.
						
						System.Text.StringBuilder ds;
						
						ds = new System.Text.StringBuilder();
						ds.Append(ns.fullName);
						if (ns != interp.globalNs)
						{
							ds.Append("::");
						}
						ds.Append(cmdName);
						
						// Check whether creating the new imported command in the
						// current namespace would create a cycle of imported->real
						// command references that also would destroy an existing
						// "real" command already in the current namespace.
						
						cmd = (WrappedCommand) importNs.cmdTable[cmdName];
						
						if (cmd.cmd is ImportedCmdData)
						{
							// This is actually an imported command, find
							// the real command it references
							realCmd = getOriginalCommand(cmd);
							if ((realCmd != null) && (realCmd.ns == currNs) && (currNs.cmdTable[cmdName] != null))
							{
								throw new TclException(interp, "import pattern \"" + pattern + "\" would create a loop containing command \"" + ds.ToString() + "\"");
							}
						}
						
						data = new ImportedCmdData();
						
						// Create the imported command inside the interp
						interp.createCommand(ds.ToString(), data);
						
						// Lookup in the namespace for the new WrappedCommand
						importedCmd = findCommand(interp, ds.ToString(), ns, (TCL.VarFlag.NAMESPACE_ONLY | TCL.VarFlag.LEAVE_ERR_MSG));
						
						data.realCmd = cmd;
						data.self = importedCmd;
						
						// Create an ImportRef structure describing this new import
						// command and add it to the import ref list in the "real"
						// command.
						
						ref_Renamed = new ImportRef();
						ref_Renamed.importedCmd = importedCmd;
						ref_Renamed.next = cmd.importRef;
						cmd.importRef = ref_Renamed;
					}
					else
					{
						throw new TclException(interp, "can't import command \"" + cmdName + "\": already exists");
					}
				}
			}
			return ;
		}
コード例 #6
0
ファイル: ProcCmd.cs プロジェクト: Belxjander/Asuna
		/// <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;
			Command cmd;
			System.Text.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 System.Text.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;
		}