/TCL/src/commands/InfoCmd.cs
C# | 1309 lines | 656 code | 164 blank | 489 comment | 169 complexity | aa19eb71b0b39e253f51573cfe772417 MD5 | raw file
- /*
- * InfoCmd.java
- *
- * Copyright (c) 1997 Cornell University.
- * Copyright (c) 1997 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and
- * redistribution of this file, and for a DISCLAIMER OF ALL
- * WARRANTIES.
- *
- * Included in SQLite3 port to C# for use in testharness only; 2008 Noah B Hart
- *
- * RCS @(#) $Id: InfoCmd.java,v 1.8 2001/11/16 23:57:13 mdejong Exp $
- *
- */
- using System;
- using System.Collections;
- namespace tcl.lang
- {
- /// <summary> This class implements the built-in "info" command in Tcl.</summary>
- class InfoCmd : Command
- {
- private static readonly string[] validCmds = new string[] { "args", "body", "cmdcount", "commands", "complete", "default", "exists", "globals", "hostname", "level", "library", "loaded", "locals", "nameofexecutable", "patchlevel", "procs", "script", "sharedlibextension", "tclversion", "vars" };
- internal const int OPT_ARGS = 0;
- internal const int OPT_BODY = 1;
- internal const int OPT_CMDCOUNT = 2;
- internal const int OPT_COMMANDS = 3;
- internal const int OPT_COMPLETE = 4;
- internal const int OPT_DEFAULT = 5;
- internal const int OPT_EXISTS = 6;
- internal const int OPT_GLOBALS = 7;
- internal const int OPT_HOSTNAME = 8;
- internal const int OPT_LEVEL = 9;
- internal const int OPT_LIBRARY = 10;
- internal const int OPT_LOADED = 11;
- internal const int OPT_LOCALS = 12;
- internal const int OPT_NAMEOFEXECUTABLE = 13;
- internal const int OPT_PATCHLEVEL = 14;
- internal const int OPT_PROCS = 15;
- internal const int OPT_SCRIPT = 16;
- internal const int OPT_SHAREDLIBEXTENSION = 17;
- internal const int OPT_TCLVERSION = 18;
- internal const int OPT_VARS = 19;
- /// <summary> Tcl_InfoObjCmd -> InfoCmd.cmdProc
- ///
- /// This procedure is invoked to process the "info" Tcl command.
- /// See the user documentation for details on what it does.
- ///
- /// </summary>
- /// <param name="interp">the current interpreter.
- /// </param>
- /// <param name="argv">command arguments.
- /// </param>
- /// <exception cref=""> TclException if wrong # of args or invalid argument(s).
- /// </exception>
- public TCL.CompletionCode cmdProc( Interp interp, TclObject[] objv )
- {
- int index;
- if ( objv.Length < 2 )
- {
- throw new TclNumArgsException( interp, 1, objv, "option ?arg arg ...?" );
- }
- index = TclIndex.get( interp, objv[1], validCmds, "option", 0 );
- switch ( index )
- {
- case OPT_ARGS:
- InfoArgsCmd( interp, objv );
- break;
- case OPT_BODY:
- InfoBodyCmd( interp, objv );
- break;
- case OPT_CMDCOUNT:
- InfoCmdCountCmd( interp, objv );
- break;
- case OPT_COMMANDS:
- InfoCommandsCmd( interp, objv );
- break;
- case OPT_COMPLETE:
- InfoCompleteCmd( interp, objv );
- break;
- case OPT_DEFAULT:
- InfoDefaultCmd( interp, objv );
- break;
- case OPT_EXISTS:
- InfoExistsCmd( interp, objv );
- break;
- case OPT_GLOBALS:
- InfoGlobalsCmd( interp, objv );
- break;
- case OPT_HOSTNAME:
- InfoHostnameCmd( interp, objv );
- break;
- case OPT_LEVEL:
- InfoLevelCmd( interp, objv );
- break;
- case OPT_LIBRARY:
- InfoLibraryCmd( interp, objv );
- break;
- case OPT_LOADED:
- InfoLoadedCmd( interp, objv );
- break;
- case OPT_LOCALS:
- InfoLocalsCmd( interp, objv );
- break;
- case OPT_NAMEOFEXECUTABLE:
- InfoNameOfExecutableCmd( interp, objv );
- break;
- case OPT_PATCHLEVEL:
- InfoPatchLevelCmd( interp, objv );
- break;
- case OPT_PROCS:
- InfoProcsCmd( interp, objv );
- break;
- case OPT_SCRIPT:
- InfoScriptCmd( interp, objv );
- break;
- case OPT_SHAREDLIBEXTENSION:
- InfoSharedlibCmd( interp, objv );
- break;
- case OPT_TCLVERSION:
- InfoTclVersionCmd( interp, objv );
- break;
- case OPT_VARS:
- InfoVarsCmd( interp, objv );
- break;
- }
- return TCL.CompletionCode.RETURN;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoArgsCmd --
- *
- * Called to implement the "info args" command that returns the
- * argument list for a procedure. Handles the following syntax:
- *
- * info args procName
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoArgsCmd( Interp interp, TclObject[] objv )
- {
- string name;
- Procedure proc;
- TclObject listObj;
- if ( objv.Length != 3 )
- {
- throw new TclNumArgsException( interp, 2, objv, "procname" );
- }
- name = objv[2].ToString();
- proc = Procedure.findProc( interp, name );
- if ( proc == null )
- {
- throw new TclException( interp, "\"" + name + "\" isn't a procedure" );
- }
- // Build a return list containing the arguments.
- listObj = TclList.newInstance();
- for ( int i = 0; i < proc.argList.Length; i++ )
- {
- TclObject s = TclString.newInstance( proc.argList[i][0] );
- TclList.append( interp, listObj, s );
- }
- interp.setResult( listObj );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoBodyCmd --
- *
- * Called to implement the "info body" command that returns the body
- * for a procedure. Handles the following syntax:
- *
- * info body procName
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoBodyCmd( Interp interp, TclObject[] objv )
- {
- string name;
- Procedure proc;
- //TclObject body, result;
- if ( objv.Length != 3 )
- {
- throw new TclNumArgsException( interp, 2, objv, "procname" );
- }
- name = objv[2].ToString();
- proc = Procedure.findProc( interp, name );
- if ( proc == null )
- {
- throw new TclException( interp, "\"" + name + "\" isn't a procedure" );
- }
- interp.setResult( proc.body.ToString() );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoCmdCountCmd --
- *
- * Called to implement the "info cmdcount" command that returns the
- * number of commands that have been executed. Handles the following
- * syntax:
- *
- * info cmdcount
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoCmdCountCmd( Interp interp, TclObject[] objv )
- {
- if ( objv.Length != 2 )
- {
- throw new TclNumArgsException( interp, 2, objv, null );
- }
- interp.setResult( interp.cmdCount );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoCommandsCmd --
- *
- * Called to implement the "info commands" command that returns the
- * list of commands in the interpreter that match an optional pattern.
- * The pattern, if any, consists of an optional sequence of namespace
- * names separated by "::" qualifiers, which is followed by a
- * glob-style pattern that restricts which commands are returned.
- * Handles the following syntax:
- *
- * info commands ?pattern?
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoCommandsCmd( Interp interp, TclObject[] objv )
- {
- string cmdName, pattern, simplePattern;
- IDictionaryEnumerator search;
- NamespaceCmd.Namespace ns;
- NamespaceCmd.Namespace globalNs = NamespaceCmd.getGlobalNamespace( interp );
- NamespaceCmd.Namespace currNs = NamespaceCmd.getCurrentNamespace( interp );
- TclObject list, elemObj;
- bool specificNsInPattern = false; // Init. to avoid compiler warning.
- WrappedCommand cmd;
- // Get the pattern and find the "effective namespace" in which to
- // list commands.
- if ( objv.Length == 2 )
- {
- simplePattern = null;
- ns = currNs;
- specificNsInPattern = false;
- }
- else if ( objv.Length == 3 )
- {
- // From the pattern, get the effective namespace and the simple
- // pattern (no namespace qualifiers or ::'s) at the end. If an
- // error was found while parsing the pattern, return it. Otherwise,
- // if the namespace wasn't found, just leave ns NULL: we will
- // return an empty list since no commands there can be found.
- pattern = objv[2].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[] dummy1Arr = new NamespaceCmd.Namespace[1];
- NamespaceCmd.Namespace[] dummy2Arr = new NamespaceCmd.Namespace[1];
- string[] simplePatternArr = new string[1];
- NamespaceCmd.getNamespaceForQualName( interp, pattern, null, 0, nsArr, dummy1Arr, dummy2Arr, simplePatternArr );
- // Get the values out of the arrays!
- ns = nsArr[0];
- simplePattern = simplePatternArr[0];
- if ( ns != null )
- {
- // we successfully found the pattern's ns
- specificNsInPattern = ( simplePattern.CompareTo( pattern ) != 0 );
- }
- }
- else
- {
- throw new TclNumArgsException( interp, 2, objv, "?pattern?" );
- }
- // Scan through the effective namespace's command table and create a
- // list with all commands that match the pattern. If a specific
- // namespace was requested in the pattern, qualify the command names
- // with the namespace name.
- list = TclList.newInstance();
- if ( ns != null )
- {
- search = ns.cmdTable.GetEnumerator();
- while ( search.MoveNext() )
- {
- cmdName = ( (string)search.Key );
- if ( ( (System.Object)simplePattern == null ) || Util.stringMatch( cmdName, simplePattern ) )
- {
- if ( specificNsInPattern )
- {
- cmd = (WrappedCommand)search.Value;
- elemObj = TclString.newInstance( interp.getCommandFullName( cmd ) );
- }
- else
- {
- elemObj = TclString.newInstance( cmdName );
- }
- TclList.append( interp, list, elemObj );
- }
- }
- // If the effective namespace isn't the global :: namespace, and a
- // specific namespace wasn't requested in the pattern, then add in
- // all global :: commands that match the simple pattern. Of course,
- // we add in only those commands that aren't hidden by a command in
- // the effective namespace.
- if ( ( ns != globalNs ) && !specificNsInPattern )
- {
- search = globalNs.cmdTable.GetEnumerator();
- while ( search.MoveNext() )
- {
- cmdName = ( (string)search.Key );
- if ( ( (System.Object)simplePattern == null ) || Util.stringMatch( cmdName, simplePattern ) )
- {
- if ( ns.cmdTable[cmdName] == null )
- {
- TclList.append( interp, list, TclString.newInstance( cmdName ) );
- }
- }
- }
- }
- }
- interp.setResult( list );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoCompleteCmd --
- *
- * Called to implement the "info complete" command that determines
- * whether a string is a complete Tcl command. Handles the following
- * syntax:
- *
- * info complete command
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoCompleteCmd( Interp interp, TclObject[] objv )
- {
- if ( objv.Length != 3 )
- {
- throw new TclNumArgsException( interp, 2, objv, "command" );
- }
- interp.setResult( tcl.lang.Interp.commandComplete( objv[2].ToString() ) );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoDefaultCmd --
- *
- * Called to implement the "info default" command that returns the
- * default value for a procedure argument. Handles the following
- * syntax:
- *
- * info default procName arg varName
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoDefaultCmd( Interp interp, TclObject[] objv )
- {
- string procName, argName, varName;
- Procedure proc;
- //TclObject valueObj;
- if ( objv.Length != 5 )
- {
- throw new TclNumArgsException( interp, 2, objv, "procname arg varname" );
- }
- procName = objv[2].ToString();
- argName = objv[3].ToString();
- proc = Procedure.findProc( interp, procName );
- if ( proc == null )
- {
- throw new TclException( interp, "\"" + procName + "\" isn't a procedure" );
- }
- for ( int i = 0; i < proc.argList.Length; i++ )
- {
- if ( argName.Equals( proc.argList[i][0].ToString() ) )
- {
- varName = objv[4].ToString();
- try
- {
- if ( proc.argList[i][1] != null )
- {
- interp.setVar( varName, proc.argList[i][1], 0 );
- interp.setResult( 1 );
- }
- else
- {
- interp.setVar( varName, "", 0 );
- interp.setResult( 0 );
- }
- }
- catch ( TclException excp )
- {
- throw new TclException( interp, "couldn't store default value in variable \"" + varName + "\"" );
- }
- return;
- }
- }
- throw new TclException( interp, "procedure \"" + procName + "\" doesn't have an argument \"" + argName + "\"" );
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoExistsCmd --
- *
- * Called to implement the "info exists" command that determines
- * whether a variable exists. Handles the following syntax:
- *
- * info exists varName
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoExistsCmd( Interp interp, TclObject[] objv )
- {
- string varName;
- Var var = null;
- if ( objv.Length != 3 )
- {
- throw new TclNumArgsException( interp, 2, objv, "varName" );
- }
- varName = objv[2].ToString();
- Var[] result = Var.lookupVar( interp, varName, null, 0, "access", false, false );
- if ( result != null )
- {
- var = result[0];
- }
- if ( ( var != null ) && !var.isVarUndefined() )
- {
- interp.setResult( true );
- }
- else
- {
- interp.setResult( false );
- }
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoGlobalsCmd --
- *
- * Called to implement the "info globals" command that returns the list
- * of global variables matching an optional pattern. Handles the
- * following syntax:
- *
- * info globals ?pattern?*
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoGlobalsCmd( Interp interp, TclObject[] objv )
- {
- string varName, pattern;
- NamespaceCmd.Namespace globalNs = NamespaceCmd.getGlobalNamespace( interp );
- IDictionaryEnumerator search;
- Var var;
- TclObject list;
- if ( objv.Length == 2 )
- {
- pattern = null;
- }
- else if ( objv.Length == 3 )
- {
- pattern = objv[2].ToString();
- }
- else
- {
- throw new TclNumArgsException( interp, 2, objv, "?pattern?" );
- }
- // Scan through the global :: namespace's variable table and create a
- // list of all global variables that match the pattern.
- list = TclList.newInstance();
- for ( search = globalNs.varTable.GetEnumerator(); search.MoveNext(); )
- {
- varName = ( (string)search.Key );
- var = (Var)search.Value;
- if ( var.isVarUndefined() )
- {
- continue;
- }
- if ( ( (System.Object)pattern == null ) || Util.stringMatch( varName, pattern ) )
- {
- TclList.append( interp, list, TclString.newInstance( varName ) );
- }
- }
- interp.setResult( list );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoHostnameCmd --
- *
- * Called to implement the "info hostname" command that returns the
- * host name. Handles the following syntax:
- *
- * info hostname
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoHostnameCmd( Interp interp, TclObject[] objv )
- {
- string name;
- if ( objv.Length != 2 )
- {
- throw new TclNumArgsException( interp, 2, objv, null );
- }
- // FIXME : how can we find the hostname
- name = null;
- if ( (System.Object)name != null )
- {
- interp.setResult( name );
- return;
- }
- else
- {
- interp.setResult( "unable to determine name of host" );
- return;
- }
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoLevelCmd --
- *
- * Called to implement the "info level" command that returns
- * information about the call stack. Handles the following syntax:
- *
- * info level ?number?
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoLevelCmd( Interp interp, TclObject[] objv )
- {
- int level;
- CallFrame frame;
- TclObject list;
- if ( objv.Length == 2 )
- {
- // just "info level"
- if ( interp.varFrame == null )
- {
- interp.setResult( 0 );
- }
- else
- {
- interp.setResult( interp.varFrame.level );
- }
- return;
- }
- else if ( objv.Length == 3 )
- {
- level = TclInteger.get( interp, objv[2] );
- if ( level <= 0 )
- {
- if ( interp.varFrame == null )
- {
- throw new TclException( interp, "bad level \"" + objv[2].ToString() + "\"" );
- }
- level += interp.varFrame.level;
- }
- for ( frame = interp.varFrame; frame != null; frame = frame.callerVar )
- {
- if ( frame.level == level )
- {
- break;
- }
- }
- if ( ( frame == null ) || frame.objv == null )
- {
- throw new TclException( interp, "bad level \"" + objv[2].ToString() + "\"" );
- }
- list = TclList.newInstance();
- for ( int i = 0; i < frame.objv.Length; i++ )
- {
- TclList.append( interp, list, TclString.newInstance( frame.objv[i] ) );
- }
- interp.setResult( list );
- return;
- }
- throw new TclNumArgsException( interp, 2, objv, "?number?" );
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoLibraryCmd --
- *
- * Called to implement the "info library" command that returns the
- * library directory for the Tcl installation. Handles the following
- * syntax:
- *
- * info library
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoLibraryCmd( Interp interp, TclObject[] objv )
- {
- if ( objv.Length != 2 )
- {
- throw new TclNumArgsException( interp, 2, objv, null );
- }
- try
- {
- interp.setResult( interp.getVar( "tcl_library", TCL.VarFlag.GLOBAL_ONLY ) );
- return;
- }
- catch ( TclException e )
- {
- // If the variable has not been defined
- throw new TclException( interp, "no library has been specified for Tcl" );
- }
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoLoadedCmd --
- *
- * Called to implement the "info loaded" command that returns the
- * packages that have been loaded into an interpreter. Handles the
- * following syntax:
- *
- * info loaded ?interp?
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoLoadedCmd( Interp interp, TclObject[] objv )
- {
- if ( objv.Length != 2 && objv.Length != 3 )
- {
- throw new TclNumArgsException( interp, 2, objv, "?interp?" );
- }
- // FIXME : what should "info loaded" return?
- throw new TclException( interp, "info loaded not implemented" );
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoLocalsCmd --
- *
- * Called to implement the "info locals" command to return a list of
- * local variables that match an optional pattern. Handles the
- * following syntax:
- *
- * info locals ?pattern?
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoLocalsCmd( Interp interp, TclObject[] objv )
- {
- string pattern;
- TclObject list;
- if ( objv.Length == 2 )
- {
- pattern = null;
- }
- else if ( objv.Length == 3 )
- {
- pattern = objv[2].ToString();
- }
- else
- {
- throw new TclNumArgsException( interp, 2, objv, "?pattern?" );
- }
- if ( interp.varFrame == null || !interp.varFrame.isProcCallFrame )
- {
- return;
- }
- // Return a list containing names of first the compiled locals (i.e. the
- // ones stored in the call frame), then the variables in the local hash
- // table (if one exists).
- list = TclList.newInstance();
- AppendLocals( interp, list, pattern, false );
- interp.setResult( list );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * AppendLocals --
- *
- * Append the local variables for the current frame to the
- * specified list object.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- private static void AppendLocals( Interp interp, TclObject list, string pattern, bool includeLinks )
- {
- Var var;
- string varName;
- Hashtable localVarTable;
- IDictionaryEnumerator search;
- localVarTable = interp.varFrame.varTable;
- // Compiled locals do not exist in Jacl
- if ( localVarTable != null )
- {
- for ( search = localVarTable.GetEnumerator(); search.MoveNext(); )
- {
- var = (Var)search.Value;
- varName = (string)search.Key;
- if ( !var.isVarUndefined() && ( includeLinks || !var.isVarLink() ) )
- {
- if ( ( (System.Object)pattern == null ) || Util.stringMatch( varName, pattern ) )
- {
- TclList.append( interp, list, TclString.newInstance( varName ) );
- }
- }
- }
- }
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoNameOfExecutableCmd --
- *
- * Called to implement the "info nameofexecutable" command that returns
- * the name of the binary file running this application. Handles the
- * following syntax:
- *
- * info nameofexecutable
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoNameOfExecutableCmd( Interp interp, TclObject[] objv )
- {
- if ( objv.Length != 2 )
- {
- throw new TclNumArgsException( interp, 2, objv, null );
- }
- // We depend on a user defined property named "JAVA" since
- // the JDK provides no means to learn the name of the executable
- // that launched the application.
- string nameOfExecutable = "nacl";
- if ( (System.Object)nameOfExecutable != null )
- {
- TclObject result = TclList.newInstance();
- TclList.append( interp, result, TclString.newInstance( nameOfExecutable ) );
- TclList.append( interp, result, TclString.newInstance( "tcl.lang.Shell" ) );
- interp.setResult( result );
- }
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoPatchLevelCmd --
- *
- * Called to implement the "info patchlevel" command that returns the
- * default value for an argument to a procedure. Handles the following
- * syntax:
- *
- * info patchlevel
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoPatchLevelCmd( Interp interp, TclObject[] objv )
- {
- if ( objv.Length != 2 )
- {
- throw new TclNumArgsException( interp, 2, objv, null );
- }
- interp.setResult( interp.getVar( "tcl_patchLevel", TCL.VarFlag.GLOBAL_ONLY ) );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoProcsCmd --
- *
- * Called to implement the "info procs" command that returns the
- * procedures in the current namespace that match an optional pattern.
- * Handles the following syntax:
- *
- * info procs ?pattern?
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoProcsCmd( Interp interp, TclObject[] objv )
- {
- string cmdName, pattern;
- NamespaceCmd.Namespace currNs = NamespaceCmd.getCurrentNamespace( interp );
- IDictionaryEnumerator search;
- WrappedCommand cmd, realCmd;
- TclObject list;
- if ( objv.Length == 2 )
- {
- pattern = null;
- }
- else if ( objv.Length == 3 )
- {
- pattern = objv[2].ToString();
- }
- else
- {
- throw new TclNumArgsException( interp, 2, objv, "?pattern?" );
- }
- // Scan through the current namespace's command table and return a list
- // of all procs that match the pattern.
- list = TclList.newInstance();
- for ( search = currNs.cmdTable.GetEnumerator(); search.MoveNext(); )
- {
- cmdName = ( (string)search.Key );
- cmd = (WrappedCommand)search.Value;
- // If the command isn't itself a proc, it still might be an
- // imported command that points to a "real" proc in a different
- // namespace.
- realCmd = NamespaceCmd.getOriginalCommand( cmd );
- if ( Procedure.isProc( cmd ) || ( ( realCmd != null ) && Procedure.isProc( realCmd ) ) )
- {
- if ( ( (System.Object)pattern == null ) || Util.stringMatch( cmdName, pattern ) )
- {
- TclList.append( interp, list, TclString.newInstance( cmdName ) );
- }
- }
- }
- interp.setResult( list );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoScriptCmd --
- *
- * Called to implement the "info script" command that returns the
- * script file that is currently being evaluated. Handles the
- * following syntax:
- *
- * info script
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoScriptCmd( Interp interp, TclObject[] objv )
- {
- if ( objv.Length != 2 )
- {
- throw new TclNumArgsException( interp, 2, objv, null );
- }
- interp.setResult( interp.scriptFile );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoSharedlibCmd --
- *
- * Called to implement the "info sharedlibextension" command that
- * returns the file extension used for shared libraries. Handles the
- * following syntax:
- *
- * info sharedlibextension
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoSharedlibCmd( Interp interp, TclObject[] objv )
- {
- if ( objv.Length != 2 )
- {
- throw new TclNumArgsException( interp, 2, objv, null );
- }
- interp.setResult( ".jar" );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoTclVersionCmd --
- *
- * Called to implement the "info tclversion" command that returns the
- * version number for this Tcl library. Handles the following syntax:
- *
- * info tclversion
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoTclVersionCmd( Interp interp, TclObject[] objv )
- {
- if ( objv.Length != 2 )
- {
- throw new TclNumArgsException( interp, 2, objv, null );
- }
- interp.setResult( interp.getVar( "tcl_version", TCL.VarFlag.GLOBAL_ONLY ) );
- return;
- }
- /*
- *----------------------------------------------------------------------
- *
- * InfoVarsCmd --
- *
- * Called to implement the "info vars" command that returns the
- * list of variables in the interpreter that match an optional pattern.
- * The pattern, if any, consists of an optional sequence of namespace
- * names separated by "::" qualifiers, which is followed by a
- * glob-style pattern that restricts which variables are returned.
- * Handles the following syntax:
- *
- * info vars ?pattern?
- *
- * Results:
- * Returns if successful, raises TclException otherwise.
- *
- * Side effects:
- * Returns a result in the interpreter's result object.
- *
- *----------------------------------------------------------------------
- */
- private static void InfoVarsCmd( Interp interp, TclObject[] objv )
- {
- string varName, pattern, simplePattern;
- IDictionaryEnumerator search;
- Var var;
- NamespaceCmd.Namespace ns;
- NamespaceCmd.Namespace globalNs = NamespaceCmd.getGlobalNamespace( interp );
- NamespaceCmd.Namespace currNs = NamespaceCmd.getCurrentNamespace( interp );
- TclObject list, elemObj;
- bool specificNsInPattern = false; // Init. to avoid compiler warning.
- // Get the pattern and find the "effective namespace" in which to
- // list variables. We only use this effective namespace if there's
- // no active Tcl procedure frame.
- if ( objv.Length == 2 )
- {
- simplePattern = null;
- ns = currNs;
- specificNsInPattern = false;
- }
- else if ( objv.Length == 3 )
- {
- // From the pattern, get the effective namespace and the simple
- // pattern (no namespace qualifiers or ::'s) at the end. If an
- // error was found while parsing the pattern, return it. Otherwise,
- // if the namespace wasn't found, just leave ns = null: we will
- // return an empty list since no variables there can be found.
- pattern = objv[2].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[] dummy1Arr = new NamespaceCmd.Namespace[1];
- NamespaceCmd.Namespace[] dummy2Arr = new NamespaceCmd.Namespace[1];
- string[] simplePatternArr = new string[1];
- NamespaceCmd.getNamespaceForQualName( interp, pattern, null, 0, nsArr, dummy1Arr, dummy2Arr, simplePatternArr );
- // Get the values out of the arrays!
- ns = nsArr[0];
- simplePattern = simplePatternArr[0];
- if ( ns != null )
- {
- // we successfully found the pattern's ns
- specificNsInPattern = ( simplePattern.CompareTo( pattern ) != 0 );
- }
- }
- else
- {
- throw new TclNumArgsException( interp, 2, objv, "?pattern?" );
- }
- // If the namespace specified in the pattern wasn't found, just return.
- if ( ns == null )
- {
- return;
- }
- list = TclList.newInstance();
- if ( ( interp.varFrame == null ) || !interp.varFrame.isProcCallFrame || specificNsInPattern )
- {
- // There is no frame pointer, the frame pointer was pushed only
- // to activate a namespace, or we are in a procedure call frame
- // but a specific namespace was specified. Create a list containing
- // only the variables in the effective namespace's variable table.
- search = ns.varTable.GetEnumerator();
- while ( search.MoveNext() )
- {
- varName = ( (string)search.Key );
- var = (Var)search.Value;
- if ( !var.isVarUndefined() || ( ( var.flags & VarFlags.NAMESPACE_VAR ) != 0 ) )
- {
- if ( ( (System.Object)simplePattern == null ) || Util.stringMatch( varName, simplePattern ) )
- {
- if ( specificNsInPattern )
- {
- elemObj = TclString.newInstance( Var.getVariableFullName( interp, var ) );
- }
- else
- {
- elemObj = TclString.newInstance( varName );
- }
- TclList.append( interp, list, elemObj );
- }
- }
- }
- // If the effective namespace isn't the global :: namespace, and a
- // specific namespace wasn't requested in the pattern (i.e., the
- // pattern only specifies variable names), then add in all global ::
- // variables that match the simple pattern. Of course, add in only
- // those variables that aren't hidden by a variable in the effective
- // namespace.
- if ( ( ns != globalNs ) && !specificNsInPattern )
- {
- search = globalNs.varTable.GetEnumerator();
- while ( search.MoveNext() )
- {
- varName = ( (string)search.Key );
- var = (Var)search.Value;
- if ( !var.isVarUndefined() || ( ( var.flags & VarFlags.NAMESPACE_VAR ) != 0 ) )
- {
- if ( ( (System.Object)simplePattern == null ) || Util.stringMatch( varName, simplePattern ) )
- {
- // Skip vars defined in current namespace
- if ( ns.varTable[varName] == null )
- {
- TclList.append( interp, list, TclString.newInstance( varName ) );
- }
- }
- }
- }
- }
- }
- else
- {
- AppendLocals( interp, list, simplePattern, true );
- }
- interp.setResult( list );
- return;
- }
- }
- }