Source Code Cross Referenced for NamespaceCmd.java in  » Scripting » jacl » tcl » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » jacl » tcl.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * NamespaceCmd.java
0003:         *
0004:         * Copyright (c) 1993-1997 Lucent Technologies.
0005:         * Copyright (c) 1997 Sun Microsystems, Inc.
0006:         * Copyright (c) 1998-1999 by Scriptics Corporation.
0007:         * Copyright (c) 1999 Moses DeJong
0008:         *
0009:         * Originally implemented by
0010:         *   Michael J. McLennan
0011:         *   Bell Labs Innovations for Lucent Technologies
0012:         *   mmclennan@lucent.com
0013:         *
0014:         * See the file "license.terms" for information on usage and
0015:         * redistribution of this file, and for a DISCLAIMER OF ALL
0016:         * WARRANTIES.
0017:         *
0018:         * RCS: @(#) $Id: NamespaceCmd.java,v 1.21 2006/01/26 19:49:18 mdejong Exp $
0019:         */
0020:
0021:        package tcl.lang;
0022:
0023:        import java.util.*;
0024:
0025:        /**
0026:         * This class implements the built-in "namespace" command in Tcl.
0027:         * See the user documentation for details on what it does.
0028:         */
0029:
0030:        public class NamespaceCmd implements  InternalRep, Command {
0031:            // This value corresponds to the Tcl_Obj.otherValuePtr pointer used
0032:            // in the C version of Tcl 8.1. Use it to keep track of a ResolvedNsName.
0033:
0034:            Namespace.ResolvedNsName otherValue = null;
0035:
0036:            /*
0037:             *----------------------------------------------------------------------
0038:             *
0039:             * Tcl_NamespaceObjCmd -> cmdProc
0040:             *
0041:             *	Invoked to implement the "namespace" command that creates, deletes,
0042:             *	or manipulates Tcl namespaces. Handles the following syntax:
0043:             *
0044:             *	    namespace children ?name? ?pattern?
0045:             *	    namespace code arg
0046:             *	    namespace current
0047:             *	    namespace delete ?name name...?
0048:             *	    namespace eval name arg ?arg...?
0049:             *	    namespace export ?-clear? ?pattern pattern...?
0050:             *	    namespace forget ?pattern pattern...?
0051:             *	    namespace import ?-force? ?pattern pattern...?
0052:             *	    namespace inscope name arg ?arg...?
0053:             *	    namespace origin name
0054:             *	    namespace parent ?name?
0055:             *	    namespace qualifiers string
0056:             *	    namespace tail string
0057:             *	    namespace which ?-command? ?-variable? name
0058:             *
0059:             * Results:
0060:             *	Returns if the command is successful. Raises Exception if
0061:             *	anything goes wrong.
0062:             *
0063:             * Side effects:
0064:             *	Based on the subcommand name (e.g., "import"), this procedure
0065:             *	dispatches to a corresponding member commands in this class.
0066:             *  This method's side effects depend on whatever that subcommand does.
0067:             *----------------------------------------------------------------------
0068:             */
0069:
0070:            private static final String[] validCmds = { "children", "code",
0071:                    "current", "delete", "eval", "export", "forget", "import",
0072:                    "inscope", "origin", "parent", "qualifiers", "tail",
0073:                    "which" };
0074:
0075:            static final private int OPT_CHILDREN = 0;
0076:            static final private int OPT_CODE = 1;
0077:            static final private int OPT_CURRENT = 2;
0078:            static final private int OPT_DELETE = 3;
0079:            static final private int OPT_EVAL = 4;
0080:            static final private int OPT_EXPORT = 5;
0081:            static final private int OPT_FORGET = 6;
0082:            static final private int OPT_IMPORT = 7;
0083:            static final private int OPT_INSCOPE = 8;
0084:            static final private int OPT_ORIGIN = 9;
0085:            static final private int OPT_PARENT = 10;
0086:            static final private int OPT_QUALIFIERS = 11;
0087:            static final private int OPT_TAIL = 12;
0088:            static final private int OPT_WHICH = 13;
0089:
0090:            public void cmdProc(Interp interp, TclObject[] objv)
0091:                    throws TclException {
0092:
0093:                int i, opt;
0094:
0095:                if (objv.length < 2) {
0096:                    throw new TclNumArgsException(interp, 1, objv,
0097:                            "subcommand ?arg ...?");
0098:                }
0099:
0100:                opt = TclIndex.get(interp, objv[1], validCmds, "option", 0);
0101:
0102:                switch (opt) {
0103:                case OPT_CHILDREN: {
0104:                    childrenCmd(interp, objv);
0105:                    return;
0106:                }
0107:                case OPT_CODE: {
0108:                    codeCmd(interp, objv);
0109:                    return;
0110:                }
0111:                case OPT_CURRENT: {
0112:                    currentCmd(interp, objv);
0113:                    return;
0114:                }
0115:                case OPT_DELETE: {
0116:                    deleteCmd(interp, objv);
0117:                    return;
0118:                }
0119:                case OPT_EVAL: {
0120:                    evalCmd(interp, objv);
0121:                    return;
0122:                }
0123:                case OPT_EXPORT: {
0124:                    exportCmd(interp, objv);
0125:                    return;
0126:                }
0127:                case OPT_FORGET: {
0128:                    forgetCmd(interp, objv);
0129:                    return;
0130:                }
0131:                case OPT_IMPORT: {
0132:                    importCmd(interp, objv);
0133:                    return;
0134:                }
0135:                case OPT_INSCOPE: {
0136:                    inscopeCmd(interp, objv);
0137:                    return;
0138:                }
0139:                case OPT_ORIGIN: {
0140:                    originCmd(interp, objv);
0141:                    return;
0142:                }
0143:                case OPT_PARENT: {
0144:                    parentCmd(interp, objv);
0145:                    return;
0146:                }
0147:                case OPT_QUALIFIERS: {
0148:                    qualifiersCmd(interp, objv);
0149:                    return;
0150:                }
0151:                case OPT_TAIL: {
0152:                    tailCmd(interp, objv);
0153:                    return;
0154:                }
0155:                case OPT_WHICH: {
0156:                    whichCmd(interp, objv);
0157:                    return;
0158:                }
0159:                } // end switch(opt)
0160:
0161:            }
0162:
0163:            /*
0164:             *----------------------------------------------------------------------
0165:             *
0166:             * NamespaceChildrenCmd -> childrenCmd
0167:             *
0168:             *	Invoked to implement the "namespace children" command that returns a
0169:             *	list containing the fully-qualified names of the child namespaces of
0170:             *	a given namespace. Handles the following syntax:
0171:             *
0172:             *	    namespace children ?name? ?pattern?
0173:             *
0174:             * Results:
0175:             *  Nothing.
0176:             *
0177:             * Side effects:
0178:             *	Returns a result in the interpreter's result object. If anything
0179:             *	goes wrong, the result is an error message.
0180:             *
0181:             *----------------------------------------------------------------------
0182:             */
0183:
0184:            private static void childrenCmd(Interp interp, TclObject[] objv)
0185:                    throws TclException {
0186:                Namespace namespace;
0187:                Namespace ns, childNs;
0188:                Namespace globalNs = Namespace.getGlobalNamespace(interp);
0189:                String pattern = null;
0190:                StringBuffer buffer;
0191:                Enumeration search;
0192:                TclObject list, elem;
0193:
0194:                // Get a pointer to the specified namespace, or the current namespace.
0195:
0196:                if (objv.length == 2) {
0197:                    ns = Namespace.getCurrentNamespace(interp);
0198:                } else if ((objv.length == 3) || (objv.length == 4)) {
0199:                    ns = getNamespaceFromObj(interp, objv[2]);
0200:                    if (ns == null) {
0201:                        throw new TclException(interp, "unknown namespace \""
0202:                                + objv[2].toString()
0203:                                + "\" in namespace children command");
0204:                    }
0205:                } else {
0206:                    throw new TclNumArgsException(interp, 2, objv,
0207:                            "?name? ?pattern?");
0208:                }
0209:
0210:                // Get the glob-style pattern, if any, used to narrow the search.
0211:
0212:                buffer = new StringBuffer();
0213:                if (objv.length == 4) {
0214:                    String name = objv[3].toString();
0215:
0216:                    if (name.startsWith("::")) {
0217:                        pattern = name;
0218:                    } else {
0219:                        buffer.append(ns.fullName);
0220:                        if (ns != globalNs) {
0221:                            buffer.append("::");
0222:                        }
0223:                        buffer.append(name);
0224:                        pattern = buffer.toString();
0225:                    }
0226:                }
0227:
0228:                // Create a list containing the full names of all child namespaces
0229:                // whose names match the specified pattern, if any.
0230:
0231:                list = TclList.newInstance();
0232:                for (Iterator iter = ns.childTable.entrySet().iterator(); iter
0233:                        .hasNext();) {
0234:                    Map.Entry entry = (Map.Entry) iter.next();
0235:                    childNs = (Namespace) entry.getValue();
0236:                    if ((pattern == null)
0237:                            || Util.stringMatch(childNs.fullName, pattern)) {
0238:                        elem = TclString.newInstance(childNs.fullName);
0239:                        TclList.append(interp, list, elem);
0240:                    }
0241:                }
0242:
0243:                interp.setResult(list);
0244:                return;
0245:            }
0246:
0247:            /*
0248:             *----------------------------------------------------------------------
0249:             *
0250:             * NamespaceCodeCmd -> codeCmd
0251:             *
0252:             *	Invoked to implement the "namespace code" command to capture the
0253:             *	namespace context of a command. Handles the following syntax:
0254:             *
0255:             *	    namespace code arg
0256:             *
0257:             *	Here "arg" can be a list. "namespace code arg" produces a result
0258:             *	equivalent to that produced by the command
0259:             *
0260:             *	    list namespace inscope [namespace current] $arg
0261:             *
0262:             *	However, if "arg" is itself a scoped value starting with
0263:             *	"namespace inscope", then the result is just "arg".
0264:             *
0265:             * Results:
0266:             *  Nothing.
0267:             *
0268:             * Side effects:
0269:             *	If anything goes wrong, this procedure returns an error
0270:             *	message as the result in the interpreter's result object.
0271:             *
0272:             *----------------------------------------------------------------------
0273:             */
0274:
0275:            private static void codeCmd(Interp interp, TclObject[] objv)
0276:                    throws TclException {
0277:                Namespace currNs;
0278:                TclObject list, obj;
0279:                String arg, p;
0280:                int length;
0281:                int p_ind;
0282:
0283:                if (objv.length != 3) {
0284:                    throw new TclNumArgsException(interp, 2, objv, "arg");
0285:                }
0286:
0287:                // If "arg" is already a scoped value, then return it directly.
0288:
0289:                arg = objv[2].toString();
0290:                length = arg.length();
0291:
0292:                // FIXME : we need a test for this inscope code if there is not one already!
0293:                if ((length > 17) && (arg.charAt(0) == 'n')
0294:                        && arg.startsWith("namespace")) {
0295:                    for (p_ind = 9; (p_ind < length)
0296:                            && (arg.charAt(p_ind) == ' '); p_ind++) {
0297:                        // empty body: skip over spaces
0298:                    }
0299:                    if (((length - p_ind) >= 7) && (arg.charAt(p_ind) == 'i')
0300:                            && arg.startsWith("inscope", p_ind)) {
0301:                        interp.setResult(objv[2]);
0302:                        return;
0303:                    }
0304:                }
0305:
0306:                // Otherwise, construct a scoped command by building a list with
0307:                // "namespace inscope", the full name of the current namespace, and 
0308:                // the argument "arg". By constructing a list, we ensure that scoped
0309:                // commands are interpreted properly when they are executed later,
0310:                // by the "namespace inscope" command.
0311:
0312:                list = TclList.newInstance();
0313:                TclList
0314:                        .append(interp, list, TclString
0315:                                .newInstance("namespace"));
0316:                TclList.append(interp, list, TclString.newInstance("inscope"));
0317:
0318:                currNs = Namespace.getCurrentNamespace(interp);
0319:                if (currNs == Namespace.getGlobalNamespace(interp)) {
0320:                    obj = TclString.newInstance("::");
0321:                } else {
0322:                    obj = TclString.newInstance(currNs.fullName);
0323:                }
0324:
0325:                TclList.append(interp, list, obj);
0326:                TclList.append(interp, list, objv[2]);
0327:
0328:                interp.setResult(list);
0329:                return;
0330:            }
0331:
0332:            /*
0333:             *----------------------------------------------------------------------
0334:             *
0335:             * NamespaceCurrentCmd -> currentCmd
0336:             *
0337:             *	Invoked to implement the "namespace current" command which returns
0338:             *	the fully-qualified name of the current namespace. Handles the
0339:             *	following syntax:
0340:             *
0341:             *	    namespace current
0342:             *
0343:             * Results:
0344:             *  Returns if successful, raises TclException if something goes wrong.
0345:             *
0346:             * Side effects:
0347:             *	Returns a result in the interpreter's result object. If anything
0348:             *	goes wrong, the result is an error message.
0349:             *
0350:             *----------------------------------------------------------------------
0351:             */
0352:
0353:            private static void currentCmd(Interp interp, TclObject[] objv)
0354:                    throws TclException {
0355:
0356:                Namespace currNs;
0357:
0358:                if (objv.length != 2) {
0359:                    throw new TclNumArgsException(interp, 2, objv, null);
0360:                }
0361:
0362:                // The "real" name of the global namespace ("::") is the null string,
0363:                // but we return "::" for it as a convenience to programmers. Note that
0364:                // "" and "::" are treated as synonyms by the namespace code so that it
0365:                // is still easy to do things like:
0366:                //
0367:                //    namespace [namespace current]::bar { ... }
0368:
0369:                currNs = Namespace.getCurrentNamespace(interp);
0370:
0371:                if (currNs == Namespace.getGlobalNamespace(interp)) {
0372:                    // FIXME : appending to te result really screws everything up!
0373:                    // need to figure out how to disallow this!
0374:                    //TclString.append(interp.getResult(), "::");
0375:                    interp.setResult("::");
0376:                } else {
0377:                    //TclString.append(interp.getResult(), currNs.fullName);
0378:                    interp.setResult(currNs.fullName);
0379:                }
0380:            }
0381:
0382:            /*
0383:             *----------------------------------------------------------------------
0384:             *
0385:             * NamespaceDeleteCmd -> deleteCmd
0386:             *
0387:             *	Invoked to implement the "namespace delete" command to delete
0388:             *	namespace(s). Handles the following syntax:
0389:             *
0390:             *	    namespace delete ?name name...?
0391:             *
0392:             *	Each name identifies a namespace. It may include a sequence of
0393:             *	namespace qualifiers separated by "::"s. If a namespace is found, it
0394:             *	is deleted: all variables and procedures contained in that namespace
0395:             *	are deleted. If that namespace is being used on the call stack, it
0396:             *	is kept alive (but logically deleted) until it is removed from the
0397:             *	call stack: that is, it can no longer be referenced by name but any
0398:             *	currently executing procedure that refers to it is allowed to do so
0399:             *	until the procedure returns. If the namespace can't be found, this
0400:             *	procedure returns an error. If no namespaces are specified, this
0401:             *	command does nothing.
0402:             *
0403:             * Results:
0404:             *  Returns if successful, raises TclException if something goes wrong.
0405:             *
0406:             * Side effects:
0407:             *	Deletes the specified namespaces. If anything goes wrong, this
0408:             *	procedure returns an error message in the interpreter's
0409:             *	result object.
0410:             *
0411:             *----------------------------------------------------------------------
0412:             */
0413:
0414:            private static void deleteCmd(Interp interp, TclObject[] objv)
0415:                    throws TclException {
0416:                Namespace namespace;
0417:                String name;
0418:                int i;
0419:
0420:                if (objv.length < 2) {
0421:                    throw new TclNumArgsException(interp, 2, objv,
0422:                            "?name name...?");
0423:                }
0424:
0425:                // Destroying one namespace may cause another to be destroyed. Break
0426:                // this into two passes: first check to make sure that all namespaces on
0427:                // the command line are valid, and report any errors.
0428:
0429:                for (i = 2; i < objv.length; i++) {
0430:                    name = objv[i].toString();
0431:                    namespace = Namespace.findNamespace(interp, name, null, 0);
0432:
0433:                    if (namespace == null) {
0434:                        throw new TclException(interp, "unknown namespace \""
0435:                                + objv[i].toString()
0436:                                + "\" in namespace delete command");
0437:                    }
0438:                }
0439:
0440:                // Okay, now delete each namespace.
0441:
0442:                for (i = 2; i < objv.length; i++) {
0443:                    name = objv[i].toString();
0444:                    namespace = Namespace.findNamespace(interp, name, null, 0);
0445:
0446:                    if (namespace != null) {
0447:                        Namespace.deleteNamespace(namespace);
0448:                    }
0449:                }
0450:            }
0451:
0452:            /*
0453:             *----------------------------------------------------------------------
0454:             *
0455:             * NamespaceEvalCmd -> evalCmd
0456:             *
0457:             *	Invoked to implement the "namespace eval" command. Executes
0458:             *	commands in a namespace. If the namespace does not already exist,
0459:             *	it is created. Handles the following syntax:
0460:             *
0461:             *	    namespace eval name arg ?arg...?
0462:             *
0463:             *	If more than one arg argument is specified, the command that is
0464:             *	executed is the result of concatenating the arguments together with
0465:             *	a space between each argument.
0466:             *
0467:             * Results:
0468:             *  Returns if successful, raises TclException if something goes wrong.
0469:             *
0470:             * Side effects:
0471:             *	Returns the result of the command in the interpreter's result
0472:             *	object. If anything goes wrong, this procedure returns an error
0473:             *	message as the result.
0474:             *
0475:             *----------------------------------------------------------------------
0476:             */
0477:
0478:            private static void evalCmd(Interp interp, TclObject[] objv)
0479:                    throws TclException {
0480:                Namespace namespace;
0481:                CallFrame frame;
0482:                String cmd;
0483:                String name;
0484:                int length;
0485:
0486:                if (objv.length < 4) {
0487:                    throw new TclNumArgsException(interp, 2, objv,
0488:                            "name arg ?arg...?");
0489:                }
0490:
0491:                // Try to resolve the namespace reference, caching the result in the
0492:                // namespace object along the way.
0493:
0494:                namespace = getNamespaceFromObj(interp, objv[2]);
0495:
0496:                // If the namespace wasn't found, try to create it.
0497:
0498:                if (namespace == null) {
0499:                    name = objv[2].toString();
0500:                    namespace = Namespace.createNamespace(interp, name, null);
0501:                    if (namespace == null) {
0502:                        // FIXME : result hack, we get the interp result and throw it!
0503:                        throw new TclException(interp, interp.getResult()
0504:                                .toString());
0505:                    }
0506:                }
0507:
0508:                // Make the specified namespace the current namespace and evaluate
0509:                // the command(s).
0510:
0511:                frame = interp.newCallFrame();
0512:                Namespace.pushCallFrame(interp, frame, namespace, false);
0513:
0514:                try {
0515:                    if (objv.length == 4) {
0516:                        interp.eval(objv[3], 0);
0517:                    } else {
0518:                        TclObject obj = Util.concat(3, objv.length, objv);
0519:
0520:                        // eval() will delete the object when it decrements its
0521:                        // refcount after eval'ing it.
0522:
0523:                        interp.eval(obj, 0); // do not pass TCL_EVAL_DIRECT, for compiler only
0524:                    }
0525:                } catch (TclException ex) {
0526:                    if (ex.getCompletionCode() == TCL.ERROR) {
0527:                        interp.addErrorInfo("\n    (in namespace eval \""
0528:                                + namespace.fullName + "\" script line "
0529:                                + interp.errorLine + ")");
0530:                    }
0531:                    throw ex;
0532:                } finally {
0533:                    Namespace.popCallFrame(interp);
0534:                }
0535:
0536:                return;
0537:            }
0538:
0539:            /*
0540:             *----------------------------------------------------------------------
0541:             *
0542:             * NamespaceExportCmd -> exportCmd
0543:             *
0544:             *	Invoked to implement the "namespace export" command that specifies
0545:             *	which commands are exported from a namespace. The exported commands
0546:             *	are those that can be imported into another namespace using
0547:             *	"namespace import". Both commands defined in a namespace and
0548:             *	commands the namespace has imported can be exported by a
0549:             *	namespace. This command has the following syntax:
0550:             *
0551:             *	    namespace export ?-clear? ?pattern pattern...?
0552:             *
0553:             *	Each pattern may contain "string match"-style pattern matching
0554:             *	special characters, but the pattern may not include any namespace
0555:             *	qualifiers: that is, the pattern must specify commands in the
0556:             *	current (exporting) namespace. The specified patterns are appended
0557:             *	onto the namespace's list of export patterns.
0558:             *
0559:             *	To reset the namespace's export pattern list, specify the "-clear"
0560:             *	flag.
0561:             *
0562:             *	If there are no export patterns and the "-clear" flag isn't given,
0563:             *	this command returns the namespace's current export list.
0564:             *
0565:             * Results:
0566:             *  Returns if successful, raises TclException if something goes wrong.
0567:             *
0568:             * Side effects:
0569:             *	Returns a result in the interpreter's result object. If anything
0570:             *	goes wrong, the result is an error message.
0571:             *
0572:             *----------------------------------------------------------------------
0573:             */
0574:
0575:            private static void exportCmd(Interp interp, TclObject[] objv)
0576:                    throws TclException {
0577:                Namespace currNs = Namespace.getCurrentNamespace(interp);
0578:                String pattern, string;
0579:                boolean resetListFirst = false;
0580:                int firstArg, patternCt, i;
0581:
0582:                if (objv.length < 2) {
0583:                    throw new TclNumArgsException(interp, 2, objv,
0584:                            "?-clear? ?pattern pattern...?");
0585:                }
0586:
0587:                // Process the optional "-clear" argument.
0588:
0589:                firstArg = 2;
0590:                if (firstArg < objv.length) {
0591:                    string = objv[firstArg].toString();
0592:                    if (string.equals("-clear")) {
0593:                        resetListFirst = true;
0594:                        firstArg++;
0595:                    }
0596:                }
0597:
0598:                // If no pattern arguments are given, and "-clear" isn't specified,
0599:                // return the namespace's current export pattern list.
0600:
0601:                patternCt = (objv.length - firstArg);
0602:                if (patternCt == 0) {
0603:                    if (firstArg > 2) {
0604:                        return;
0605:                    } else { // create list with export patterns
0606:                        TclObject list = TclList.newInstance();
0607:                        Namespace.appendExportList(interp, currNs, list);
0608:                        interp.setResult(list);
0609:                        return;
0610:                    }
0611:                }
0612:
0613:                // Add each pattern to the namespace's export pattern list.
0614:
0615:                for (i = firstArg; i < objv.length; i++) {
0616:                    pattern = objv[i].toString();
0617:                    Namespace.exportList(interp, currNs, pattern,
0618:                            ((i == firstArg) ? resetListFirst : false));
0619:                }
0620:                return;
0621:            }
0622:
0623:            /*
0624:             *----------------------------------------------------------------------
0625:             *
0626:             * NamespaceForgetCmd -> forgetCmd
0627:             *
0628:             *	Invoked to implement the "namespace forget" command to remove
0629:             *	imported commands from a namespace. Handles the following syntax:
0630:             *
0631:             *	    namespace forget ?pattern pattern...?
0632:             *
0633:             *	Each pattern is a name like "foo::*" or "a::b::x*". That is, the
0634:             *	pattern may include the special pattern matching characters
0635:             *	recognized by the "string match" command, but only in the command
0636:             *	name at the end of the qualified name; the special pattern
0637:             *	characters may not appear in a namespace name. All of the commands
0638:             *	that match that pattern are checked to see if they have an imported
0639:             *	command in the current namespace that refers to the matched
0640:             *	command. If there is an alias, it is removed.
0641:             *	
0642:             * Results:
0643:             *  Returns if successful, raises TclException if something goes wrong.
0644:             *
0645:             * Side effects:
0646:             *	Imported commands are removed from the current namespace. If
0647:             *	anything goes wrong, this procedure returns an error message in the
0648:             *	interpreter's result object.
0649:             *
0650:             *----------------------------------------------------------------------
0651:             */
0652:
0653:            private static void forgetCmd(Interp interp, TclObject[] objv)
0654:                    throws TclException {
0655:
0656:                String pattern;
0657:                int i;
0658:
0659:                if (objv.length < 2) {
0660:                    throw new TclNumArgsException(interp, 2, objv,
0661:                            "?pattern pattern...?");
0662:                }
0663:
0664:                for (i = 2; i < objv.length; i++) {
0665:                    pattern = objv[i].toString();
0666:                    Namespace.forgetImport(interp, null, pattern);
0667:                }
0668:                return;
0669:            }
0670:
0671:            /*
0672:             *----------------------------------------------------------------------
0673:             *
0674:             * NamespaceImportCmd -> importCmd
0675:             *
0676:             *	Invoked to implement the "namespace import" command that imports
0677:             *	commands into a namespace. Handles the following syntax:
0678:             *
0679:             *	    namespace import ?-force? ?pattern pattern...?
0680:             *
0681:             *	Each pattern is a namespace-qualified name like "foo::*",
0682:             *	"a::b::x*", or "bar::p". That is, the pattern may include the
0683:             *	special pattern matching characters recognized by the "string match"
0684:             *	command, but only in the command name at the end of the qualified
0685:             *	name; the special pattern characters may not appear in a namespace
0686:             *	name. All of the commands that match the pattern and which are
0687:             *	exported from their namespace are made accessible from the current
0688:             *	namespace context. This is done by creating a new "imported command"
0689:             *	in the current namespace that points to the real command in its
0690:             *	original namespace; when the imported command is called, it invokes
0691:             *	the real command.
0692:             *
0693:             *	If an imported command conflicts with an existing command, it is
0694:             *	treated as an error. But if the "-force" option is included, then
0695:             *	existing commands are overwritten by the imported commands.
0696:             *	
0697:             * Results:
0698:             *  Returns if successful, raises TclException if something goes wrong.
0699:             *
0700:             * Side effects:
0701:             *	Adds imported commands to the current namespace. If anything goes
0702:             *	wrong, this procedure returns an error message in the interpreter's
0703:             *	result object.
0704:             *
0705:             *----------------------------------------------------------------------
0706:             */
0707:
0708:            private static void importCmd(Interp interp, TclObject[] objv)
0709:                    throws TclException {
0710:
0711:                boolean allowOverwrite = false;
0712:                String string, pattern;
0713:                int i;
0714:                int firstArg;
0715:
0716:                if (objv.length < 2) {
0717:                    throw new TclNumArgsException(interp, 2, objv,
0718:                            "?-force? ?pattern pattern...?");
0719:                }
0720:
0721:                // Skip over the optional "-force" as the first argument.
0722:
0723:                firstArg = 2;
0724:                if (firstArg < objv.length) {
0725:                    string = objv[firstArg].toString();
0726:                    if (string.equals("-force")) {
0727:                        allowOverwrite = true;
0728:                        firstArg++;
0729:                    }
0730:                }
0731:
0732:                // Handle the imports for each of the patterns.
0733:
0734:                for (i = firstArg; i < objv.length; i++) {
0735:                    pattern = objv[i].toString();
0736:                    Namespace.importList(interp, null, pattern, allowOverwrite);
0737:                }
0738:                return;
0739:            }
0740:
0741:            /*
0742:             *----------------------------------------------------------------------
0743:             *
0744:             * NamespaceInscopeCmd -> inscopeCmd
0745:             *
0746:             *	Invoked to implement the "namespace inscope" command that executes a
0747:             *	script in the context of a particular namespace. This command is not
0748:             *	expected to be used directly by programmers; calls to it are
0749:             *	generated implicitly when programs use "namespace code" commands
0750:             *	to register callback scripts. Handles the following syntax:
0751:             *
0752:             *	    namespace inscope name arg ?arg...?
0753:             *
0754:             *	The "namespace inscope" command is much like the "namespace eval"
0755:             *	command except that it has lappend semantics and the namespace must
0756:             *	already exist. It treats the first argument as a list, and appends
0757:             *	any arguments after the first onto the end as proper list elements.
0758:             *	For example,
0759:             *
0760:             *	    namespace inscope ::foo a b c d
0761:             *
0762:             *	is equivalent to
0763:             *
0764:             *	    namespace eval ::foo [concat a [list b c d]]
0765:             *
0766:             *	This lappend semantics is important because many callback scripts
0767:             *	are actually prefixes.
0768:             *
0769:             * Results:
0770:             *  Returns if successful, raises TclException if something goes wrong.
0771:             *
0772:             * Side effects:
0773:             *	Returns a result in the Tcl interpreter's result object.
0774:             *
0775:             *----------------------------------------------------------------------
0776:             */
0777:
0778:            private static void inscopeCmd(Interp interp, TclObject[] objv)
0779:                    throws TclException {
0780:                Namespace namespace;
0781:                CallFrame frame;
0782:                int i, result;
0783:
0784:                if (objv.length < 4) {
0785:                    throw new TclNumArgsException(interp, 2, objv,
0786:                            "name arg ?arg...?");
0787:                }
0788:
0789:                // Resolve the namespace reference.
0790:
0791:                namespace = getNamespaceFromObj(interp, objv[2]);
0792:                if (namespace == null) {
0793:                    throw new TclException(interp, "unknown namespace \""
0794:                            + objv[2].toString()
0795:                            + "\" in inscope namespace command");
0796:                }
0797:
0798:                // Make the specified namespace the current namespace.
0799:
0800:                frame = interp.newCallFrame();
0801:                Namespace.pushCallFrame(interp, frame, namespace, false);
0802:
0803:                // Execute the command. If there is just one argument, just treat it as
0804:                // a script and evaluate it. Otherwise, create a list from the arguments
0805:                // after the first one, then concatenate the first argument and the list
0806:                // of extra arguments to form the command to evaluate.
0807:
0808:                try {
0809:                    if (objv.length == 4) {
0810:                        interp.eval(objv[3], 0);
0811:                    } else {
0812:                        TclObject[] concatObjv = new TclObject[2];
0813:                        TclObject list;
0814:                        TclObject cmd;
0815:
0816:                        list = TclList.newInstance();
0817:                        for (i = 4; i < objv.length; i++) {
0818:                            try {
0819:                                TclList.append(interp, list, objv[i]);
0820:                            } catch (TclException ex) {
0821:                                list.release(); // free unneeded obj
0822:                                throw ex;
0823:                            }
0824:                        }
0825:
0826:                        concatObjv[0] = objv[3];
0827:                        concatObjv[1] = list;
0828:                        list.preserve();
0829:                        cmd = Util.concat(0, 1, concatObjv);
0830:                        try {
0831:                            interp.eval(cmd, 0); // do not pass TCL_EVAL_DIRECT, for compiler only
0832:                        } finally {
0833:                            list.release(); // we're done with the list object
0834:                        }
0835:                    }
0836:                } catch (TclException ex) {
0837:                    if (ex.getCompletionCode() == TCL.ERROR) {
0838:                        interp.addErrorInfo("\n    (in namespace inscope \""
0839:                                + namespace.fullName + "\" script line "
0840:                                + interp.errorLine + ")");
0841:                    }
0842:                    throw ex;
0843:                } finally {
0844:                    Namespace.popCallFrame(interp);
0845:                }
0846:
0847:                return;
0848:            }
0849:
0850:            /*
0851:             *----------------------------------------------------------------------
0852:             *
0853:             * NamespaceOriginCmd -> originCmd
0854:             *
0855:             *	Invoked to implement the "namespace origin" command to return the
0856:             *	fully-qualified name of the "real" command to which the specified
0857:             *	"imported command" refers. Handles the following syntax:
0858:             *
0859:             *	    namespace origin name
0860:             *
0861:             * Results:
0862:             *	An imported command is created in an namespace when that namespace
0863:             *	imports a command from another namespace. If a command is imported
0864:             *	into a sequence of namespaces a, b,...,n where each successive
0865:             *	namespace just imports the command from the previous namespace, this
0866:             *	command returns the fully-qualified name of the original command in
0867:             *	the first namespace, a. If "name" does not refer to an alias, its
0868:             *	fully-qualified name is returned. The returned name is stored in the
0869:             *	interpreter's result object. This procedure returns TCL_OK if
0870:             *	successful, and TCL_ERROR if anything goes wrong.
0871:             *
0872:             * Side effects:
0873:             *	If anything goes wrong, this procedure returns an error message in
0874:             *	the interpreter's result object.
0875:             *
0876:             *----------------------------------------------------------------------
0877:             */
0878:
0879:            private static void originCmd(Interp interp, TclObject[] objv)
0880:                    throws TclException {
0881:                WrappedCommand command, origCommand;
0882:
0883:                if (objv.length != 3) {
0884:                    throw new TclNumArgsException(interp, 2, objv, "name");
0885:                }
0886:
0887:                // FIXME : is this the right way to search for a command?
0888:
0889:                //command = Tcl_GetCommandFromObj(interp, objv[2]);
0890:                command = Namespace.findCommand(interp, objv[2].toString(),
0891:                        null, 0);
0892:
0893:                if (command == null) {
0894:                    throw new TclException(interp, "invalid command name \""
0895:                            + objv[2].toString() + "\"");
0896:                }
0897:
0898:                origCommand = Namespace.getOriginalCommand(command);
0899:                if (origCommand == null) {
0900:                    // The specified command isn't an imported command. Return the
0901:                    // command's name qualified by the full name of the namespace it
0902:                    // was defined in.
0903:
0904:                    interp.setResult(interp.getCommandFullName(command));
0905:                } else {
0906:                    interp.setResult(interp.getCommandFullName(origCommand));
0907:                }
0908:                return;
0909:            }
0910:
0911:            /*
0912:             *----------------------------------------------------------------------
0913:             *
0914:             * NamespaceParentCmd -> parentCmd
0915:             *
0916:             *	Invoked to implement the "namespace parent" command that returns the
0917:             *	fully-qualified name of the parent namespace for a specified
0918:             *	namespace. Handles the following syntax:
0919:             *
0920:             *	    namespace parent ?name?
0921:             *
0922:             * Results:
0923:             *  Returns if successful, raises TclException if something goes wrong.
0924:             *
0925:             * Side effects:
0926:             *	Returns a result in the interpreter's result object. If anything
0927:             *	goes wrong, the result is an error message.
0928:             *
0929:             *----------------------------------------------------------------------
0930:             */
0931:
0932:            private static void parentCmd(Interp interp, TclObject[] objv)
0933:                    throws TclException {
0934:                Namespace ns;
0935:
0936:                if (objv.length == 2) {
0937:                    ns = Namespace.getCurrentNamespace(interp);
0938:                } else if (objv.length == 3) {
0939:                    ns = getNamespaceFromObj(interp, objv[2]);
0940:                    if (ns == null) {
0941:                        throw new TclException(interp, "unknown namespace \""
0942:                                + objv[2].toString()
0943:                                + "\" in namespace parent command");
0944:                    }
0945:                } else {
0946:                    throw new TclNumArgsException(interp, 2, objv, "?name?");
0947:                }
0948:
0949:                // Report the parent of the specified namespace.
0950:
0951:                if (ns.parent != null) {
0952:                    interp.setResult(ns.parent.fullName);
0953:                }
0954:            }
0955:
0956:            /*
0957:             *----------------------------------------------------------------------
0958:             *
0959:             * NamespaceQualifiersCmd -> qualifiersCmd
0960:             *
0961:             *	Invoked to implement the "namespace qualifiers" command that returns
0962:             *	any leading namespace qualifiers in a string. These qualifiers are
0963:             *	namespace names separated by "::"s. For example, for "::foo::p" this
0964:             *	command returns "::foo", and for "::" it returns "". This command
0965:             *	is the complement of the "namespace tail" command. Note that this
0966:             *	command does not check whether the "namespace" names are, in fact,
0967:             *	the names of currently defined namespaces. Handles the following
0968:             *	syntax:
0969:             *
0970:             *	    namespace qualifiers string
0971:             *
0972:             * Results:
0973:             *  Returns if successful, raises TclException if something goes wrong.
0974:             *
0975:             * Side effects:
0976:             *	Returns a result in the interpreter's result object. If anything
0977:             *	goes wrong, the result is an error message.
0978:             *
0979:             *----------------------------------------------------------------------
0980:             */
0981:
0982:            private static void qualifiersCmd(Interp interp, TclObject[] objv)
0983:                    throws TclException {
0984:                String name;
0985:                int p;
0986:
0987:                if (objv.length != 3) {
0988:                    throw new TclNumArgsException(interp, 2, objv, "string");
0989:                }
0990:
0991:                // Find the end of the string, then work backward and find
0992:                // the start of the last "::" qualifier.
0993:
0994:                name = objv[2].toString();
0995:                p = name.length();
0996:
0997:                while (--p >= 0) {
0998:                    if ((name.charAt(p) == ':') && (p > 0)
0999:                            && (name.charAt(p - 1) == ':')) {
1000:                        p -= 2; // back up over the ::
1001:                        while ((p >= 0) && (name.charAt(p) == ':')) {
1002:                            p--; // back up over the preceeding :
1003:                        }
1004:                        break;
1005:                    }
1006:                }
1007:
1008:                if (p >= 0) {
1009:                    interp.setResult(name.substring(0, p + 1));
1010:                }
1011:                // When no result is set the empty string is the result
1012:                return;
1013:            }
1014:
1015:            /*
1016:             *----------------------------------------------------------------------
1017:             *
1018:             * NamespaceTailCmd -> tailCmd
1019:             *
1020:             *	Invoked to implement the "namespace tail" command that returns the
1021:             *	trailing name at the end of a string with "::" namespace
1022:             *	qualifiers. These qualifiers are namespace names separated by
1023:             *	"::"s. For example, for "::foo::p" this command returns "p", and for
1024:             *	"::" it returns "". This command is the complement of the "namespace
1025:             *	qualifiers" command. Note that this command does not check whether
1026:             *	the "namespace" names are, in fact, the names of currently defined
1027:             *	namespaces. Handles the following syntax:
1028:             *
1029:             *	    namespace tail string
1030:             *
1031:             * Results:
1032:             *  Returns if successful, raises TclException if something goes wrong.
1033:             *
1034:             * Side effects:
1035:             *	Returns a result in the interpreter's result object. If anything
1036:             *	goes wrong, the result is an error message.
1037:             *
1038:             *----------------------------------------------------------------------
1039:             */
1040:
1041:            private static void tailCmd(Interp interp, TclObject[] objv)
1042:                    throws TclException {
1043:                String name, tail;
1044:
1045:                if (objv.length != 3) {
1046:                    throw new TclNumArgsException(interp, 2, objv, "string");
1047:                }
1048:
1049:                name = objv[2].toString();
1050:                tail = NamespaceCmd.tail(name);
1051:                interp.setResult(tail);
1052:                return;
1053:            }
1054:
1055:            // Given a possibly qualified name, return the namespace tail
1056:            // substring that appears after the last pair of colons "::".
1057:
1058:            static String tail(String qname) {
1059:
1060:                // Find the last location of "::" in the string.
1061:
1062:                int i = qname.lastIndexOf("::");
1063:                String tail;
1064:
1065:                if (i == -1) {
1066:                    tail = qname;
1067:                } else {
1068:                    i += 2; // just after last "::"
1069:                    if (i >= qname.length()) {
1070:                        tail = "";
1071:                    } else {
1072:                        tail = qname.substring(i);
1073:                    }
1074:                }
1075:                return tail;
1076:            }
1077:
1078:            /*
1079:             *----------------------------------------------------------------------
1080:             *
1081:             * NamespaceWhichCmd -> whichCmd
1082:             *
1083:             *	Invoked to implement the "namespace which" command that returns the
1084:             *	fully-qualified name of a command or variable. If the specified
1085:             *	command or variable does not exist, it returns "". Handles the
1086:             *	following syntax:
1087:             *
1088:             *	    namespace which ?-command? ?-variable? name
1089:             *
1090:             * Results:
1091:             *  Returns if successful, raises TclException if something goes wrong.
1092:             *
1093:             * Side effects:
1094:             *	Returns a result in the interpreter's result object. If anything
1095:             *	goes wrong, the result is an error message.
1096:             *
1097:             *----------------------------------------------------------------------
1098:             */
1099:
1100:            private static void whichCmd(Interp interp, TclObject[] objv)
1101:                    throws TclException {
1102:                String arg;
1103:                WrappedCommand cmd;
1104:                Var variable;
1105:                int argIndex, lookup;
1106:
1107:                if (objv.length < 3) {
1108:                    throw new TclNumArgsException(interp, 2, objv,
1109:                            "?-command? ?-variable? name");
1110:                }
1111:
1112:                // Look for a flag controlling the lookup.
1113:
1114:                argIndex = 2;
1115:                lookup = 0; // assume command lookup by default
1116:                arg = objv[2].toString();
1117:                if ((arg.length() > 1) && (arg.charAt(0) == '-')) {
1118:                    if (arg.equals("-command")) {
1119:                        lookup = 0;
1120:                    } else if (arg.equals("-variable")) {
1121:                        lookup = 1;
1122:                    } else {
1123:                        throw new TclNumArgsException(interp, 2, objv,
1124:                                "?-command? ?-variable? name");
1125:                    }
1126:                    argIndex = 3;
1127:                }
1128:                if (objv.length != (argIndex + 1)) {
1129:                    throw new TclNumArgsException(interp, 2, objv,
1130:                            "?-command? ?-variable? name");
1131:                }
1132:
1133:                // FIXME : check that this implementation works!
1134:
1135:                switch (lookup) {
1136:                case 0: // -command
1137:                    arg = objv[argIndex].toString();
1138:
1139:                    // FIXME : is this the right way to lookup a Command token?
1140:                    //cmd = Tcl_GetCommandFromObj(interp, objv[argIndex]);
1141:                    cmd = Namespace.findCommand(interp, arg, null, 0);
1142:
1143:                    if (cmd == null) {
1144:                        return; // cmd not found, just return (no error)
1145:                    }
1146:                    interp.setResult(interp.getCommandFullName(cmd));
1147:                    return;
1148:
1149:                case 1: // -variable
1150:                    arg = objv[argIndex].toString();
1151:                    variable = Namespace.findNamespaceVar(interp, arg, null, 0);
1152:                    if (variable != null) {
1153:                        interp.setResult(Var.getVariableFullName(interp,
1154:                                variable));
1155:                    }
1156:                    return;
1157:                }
1158:
1159:                return;
1160:            }
1161:
1162:            /*
1163:             *----------------------------------------------------------------------
1164:             *
1165:             * FreeNsNameInternalRep -> dispose
1166:             *
1167:             *	Frees the resources associated with a object's internal
1168:             *	representation. See src/tcljava/tcl/lang/InternalRep.java
1169:             *
1170:             * Results:
1171:             *	None.
1172:             *
1173:             * Side effects:
1174:             *	Decrements the ref count of any Namespace structure pointed
1175:             *	to by the nsName's internal representation. If there are no more
1176:             *	references to the namespace, it's structure will be freed.
1177:             *
1178:             *----------------------------------------------------------------------
1179:             */
1180:
1181:            public void dispose() {
1182:                final boolean debug = false;
1183:                if (debug) {
1184:                    System.out.println("dispose() called for namespace object "
1185:                            + (otherValue == null ? null : otherValue.ns));
1186:                }
1187:
1188:                Namespace.ResolvedNsName resName = otherValue;
1189:                Namespace ns;
1190:
1191:                // Decrement the reference count of the namespace. If there are no
1192:                // more references, free it up.
1193:
1194:                if (resName != null) {
1195:                    resName.refCount--;
1196:                    if (resName.refCount == 0) {
1197:
1198:                        // Decrement the reference count for the cached namespace.  If
1199:                        // the namespace is dead, and there are no more references to
1200:                        // it, free it.
1201:
1202:                        ns = resName.ns;
1203:                        ns.refCount--;
1204:                        if ((ns.refCount == 0)
1205:                                && ((ns.flags & Namespace.NS_DEAD) != 0)) {
1206:                            Namespace.free(ns);
1207:                        }
1208:                        otherValue = null;
1209:                    }
1210:                }
1211:            }
1212:
1213:            /*
1214:             *----------------------------------------------------------------------
1215:             *
1216:             * DupNsNameInternalRep -> duplicate
1217:             *
1218:             *	Get a copy of this Object for copy-on-write
1219:             *	operations. We just increment its useCount and return the same
1220:             *	ReflectObject because ReflectObject's cannot be modified, so
1221:             *	they don't need copy-on-write protections.
1222:             *
1223:             * Results:
1224:             *	None.
1225:             *
1226:             * Side effects:
1227:             *  None.
1228:             *
1229:             *----------------------------------------------------------------------
1230:             */
1231:
1232:            public InternalRep duplicate() {
1233:                final boolean debug = false;
1234:                if (debug) {
1235:                    System.out
1236:                            .println("duplicate() called for namespace object "
1237:                                    + (otherValue == null ? null
1238:                                            : otherValue.ns));
1239:                }
1240:
1241:                Namespace.ResolvedNsName resName = otherValue;
1242:
1243:                if (resName != null) {
1244:                    resName.refCount++;
1245:                }
1246:
1247:                return this ;
1248:            }
1249:
1250:            /*
1251:             *----------------------------------------------------------------------
1252:             *
1253:             * SetNsNameFromAny -> setNsNameFromAny
1254:             *
1255:             *	Attempt to generate a nsName internal representation for a
1256:             *	TclObject.
1257:             *
1258:             * Results:
1259:             *	Returns if the value could be converted to a proper
1260:             *	namespace reference. Otherwise, raises TclException.
1261:             *
1262:             * Side effects:
1263:             *	If successful, the object is made a nsName object. Its internal rep
1264:             *	is set to point to a ResolvedNsName, which contains a cached pointer
1265:             *	to the Namespace. Reference counts are kept on both the
1266:             *	ResolvedNsName and the Namespace, so we can keep track of their
1267:             *	usage and free them when appropriate.
1268:             *
1269:             *----------------------------------------------------------------------
1270:             */
1271:
1272:            static void setNsNameFromAny(Interp interp, // Reference to the namespace in which to
1273:                    // resolve name. Also used for error
1274:                    // reporting if not null.
1275:                    TclObject tobj // The TclObject to convert.
1276:            ) throws TclException // If object could not be converted
1277:            {
1278:                String name;
1279:                Namespace ns;
1280:                Namespace.ResolvedNsName resName;
1281:
1282:                // Get the string representation.
1283:                name = tobj.toString();
1284:
1285:                // Look for the namespace "name" in the current namespace. If there is
1286:                // an error parsing the (possibly qualified) name, return an error.
1287:                // If the namespace isn't found, we convert the object to an nsName
1288:                // object with a null ResolvedNsName internal rep.
1289:
1290:                Namespace.GetNamespaceForQualNameResult gnfqnr = interp.getnfqnResult;
1291:                Namespace.getNamespaceForQualName(interp, name, null,
1292:                        Namespace.FIND_ONLY_NS, gnfqnr);
1293:                ns = gnfqnr.ns;
1294:
1295:                // If we found a namespace, then create a new ResolvedNsName structure
1296:                // that holds a reference to it.
1297:
1298:                if (ns != null) {
1299:                    Namespace currNs = Namespace.getCurrentNamespace(interp);
1300:
1301:                    ns.refCount++;
1302:                    resName = new Namespace.ResolvedNsName();
1303:                    resName.ns = ns;
1304:                    resName.nsId = ns.nsId;
1305:                    resName.refNs = currNs;
1306:                    resName.refCount = 1;
1307:                } else {
1308:                    resName = null;
1309:                }
1310:
1311:                // By setting the new internal rep we free up the old one.
1312:
1313:                // FIXME : should a NamespaceCmd wrap a ResolvedNsName?
1314:                // this is confusing because it seems like the C code uses
1315:                // a ResolvedNsName like it is the InternalRep.
1316:
1317:                NamespaceCmd wrap = new NamespaceCmd();
1318:                wrap.otherValue = resName;
1319:                tobj.setInternalRep(wrap);
1320:
1321:                return;
1322:            }
1323:
1324:            /*
1325:             *----------------------------------------------------------------------
1326:             *
1327:             * GetNamespaceFromObj -> getNamespaceFromObj
1328:             *
1329:             *	Returns the namespace specified by the name in a TclObject.
1330:             *
1331:             * Results:
1332:             *  This method will return the Namespace object whose name
1333:             *  is stored in the obj argument. If the namespace can't be found,
1334:             *  a TclException is raised.
1335:             *
1336:             * Side effects:
1337:             *	May update the internal representation for the object, caching the
1338:             *	namespace reference. The next time this procedure is called, the
1339:             *	namespace value can be found quickly.
1340:             *
1341:             *	If anything goes wrong, an error message is left in the
1342:             *	interpreter's result object.
1343:             *
1344:             *----------------------------------------------------------------------
1345:             */
1346:
1347:            static Namespace getNamespaceFromObj(Interp interp, // The current interpreter.
1348:                    TclObject obj // The object to be resolved as the name
1349:            // of a namespace.
1350:            ) throws TclException {
1351:                Namespace.ResolvedNsName resName;
1352:                Namespace ns;
1353:                Namespace currNs = Namespace.getCurrentNamespace(interp);
1354:                int result;
1355:
1356:                // Get the internal representation, converting to a namespace type if
1357:                // needed. The internal representation is a ResolvedNsName that points
1358:                // to the actual namespace.
1359:
1360:                if (!(obj.getInternalRep() instanceof  NamespaceCmd)) {
1361:                    NamespaceCmd.setNsNameFromAny(interp, obj);
1362:                }
1363:                resName = ((NamespaceCmd) obj.getInternalRep()).otherValue;
1364:
1365:                // Check the context namespace of the resolved symbol to make sure that
1366:                // it is fresh. If not, then force another conversion to the namespace
1367:                // type, to discard the old rep and create a new one. Note that we
1368:                // verify that the namespace id of the cached namespace is the same as
1369:                // the id when we cached it; this insures that the namespace wasn't
1370:                // deleted and a new one created at the same address.
1371:
1372:                ns = null;
1373:                if ((resName != null) && (resName.refNs == currNs)
1374:                        && (resName.nsId == resName.ns.nsId)) {
1375:                    ns = resName.ns;
1376:                    if ((ns.flags & Namespace.NS_DEAD) != 0) {
1377:                        ns = null;
1378:                    }
1379:                }
1380:                if (ns == null) { // try again
1381:                    NamespaceCmd.setNsNameFromAny(interp, obj);
1382:                    resName = ((NamespaceCmd) obj.getInternalRep()).otherValue;
1383:                    if (resName != null) {
1384:                        ns = resName.ns;
1385:                        if ((ns.flags & Namespace.NS_DEAD) != 0) {
1386:                            ns = null;
1387:                        }
1388:                    }
1389:                }
1390:                return ns;
1391:            }
1392:
1393:            /*
1394:             *----------------------------------------------------------------------
1395:             *
1396:             * UpdateStringOfNsName -> toString
1397:             *
1398:             *	Return the string representation for a nsName object.
1399:             *  This method is called only by TclObject.toString()
1400:             *  when TclObject.stringRep is null.
1401:             *
1402:             * Results:
1403:             *	None.
1404:             *
1405:             * Side effects:
1406:             *   None.
1407:             *
1408:             *----------------------------------------------------------------------
1409:             */
1410:
1411:            public String toString() {
1412:                final boolean debug = false;
1413:
1414:                if (debug) {
1415:                    System.out
1416:                            .println("toString() called for namespace object "
1417:                                    + (otherValue == null ? null
1418:                                            : otherValue.ns));
1419:                }
1420:
1421:                Namespace.ResolvedNsName resName = otherValue;
1422:                Namespace ns;
1423:                String name = "";
1424:
1425:                if ((resName != null) && (resName.nsId == resName.ns.nsId)) {
1426:                    ns = resName.ns;
1427:                    if ((ns.flags & Namespace.NS_DEAD) != 0) {
1428:                        ns = null;
1429:                    }
1430:                    if (ns != null) {
1431:                        name = ns.fullName;
1432:                    }
1433:                }
1434:
1435:                return name;
1436:            }
1437:
1438:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.