2 * ------------------------------------------------------------------------
4 * DESCRIPTION: Object-Oriented Extensions to Tcl
6 * [incr Tcl] provides object-oriented extensions to Tcl, much as
7 * C++ provides object-oriented extensions to C. It provides a means
8 * of encapsulating related procedures together with their shared data
9 * in a local namespace that is hidden from the outside world. It
10 * promotes code re-use through inheritance. More than anything else,
11 * it encourages better organization of Tcl applications through the
12 * object-oriented paradigm, leading to code that is easier to
13 * understand and maintain.
15 * These procedures handle built-in class methods, including the
16 * "isa" method (to query hierarchy info) and the "info" method
17 * (to query class/object data).
19 * ========================================================================
20 * AUTHOR: Michael J. McLennan
21 * Bell Labs Innovations for Lucent Technologies
22 * mmclennan@lucent.com
23 * http://www.tcltk.com/itcl
25 * overhauled version author: Arnulf Wiedemann
26 * ========================================================================
27 * Copyright (c) 1993-1998 Lucent Technologies, Inc.
28 * ------------------------------------------------------------------------
29 * See the file "license.terms" for information on usage and redistribution
30 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
34 static char initHullCmdsScript[] =
35 "namespace eval ::itcl {\n"
36 " proc _find_hull_init {} {\n"
37 " global env tcl_library\n"
39 " variable patchLevel\n"
40 " rename _find_hull_init {}\n"
41 " if {[info exists library]} {\n"
42 " lappend dirs $library\n"
45 " if {[info exists env(ITCL_LIBRARY)]} {\n"
46 " lappend dirs $env(ITCL_LIBRARY)\n"
48 " lappend dirs [file join [file dirname $tcl_library] itcl$patchLevel]\n"
49 " set bindir [file dirname [info nameofexecutable]]\n"
50 " lappend dirs [file join . library]\n"
51 " lappend dirs [file join $bindir .. lib itcl$patchLevel]\n"
52 " lappend dirs [file join $bindir .. library]\n"
53 " lappend dirs [file join $bindir .. .. library]\n"
54 " lappend dirs [file join $bindir .. .. itcl library]\n"
55 " lappend dirs [file join $bindir .. .. .. itcl library]\n"
56 " lappend dirs [file join $bindir .. .. itcl-ng itcl library]\n"
57 " # On MacOSX, check the directories in the tcl_pkgPath\n"
58 " if {[string equal $::tcl_platform(platform) \"unix\"] && "
59 " [string equal $::tcl_platform(os) \"Darwin\"]} {\n"
60 " foreach d $::tcl_pkgPath {\n"
61 " lappend dirs [file join $d itcl$patchLevel]\n"
64 " # On *nix, check the directories in the tcl_pkgPath\n"
65 " if {[string equal $::tcl_platform(platform) \"unix\"]} {\n"
66 " foreach d $::tcl_pkgPath {\n"
68 " lappend dirs [file join $d itcl$patchLevel]\n"
72 " foreach i $dirs {\n"
74 " set itclfile [file join $i itclHullCmds.tcl]\n"
75 " if {![catch {uplevel #0 [list source $itclfile]} msg]} {\n"
78 "puts stderr \"MSG!$msg!\"\n"
80 " set msg \"Can't find a usable itclHullCmds.tcl in the following directories:\n\"\n"
81 " append msg \" $dirs\n\"\n"
82 " append msg \"This probably means that Itcl/Tcl weren't installed properly.\n\"\n"
83 " append msg \"If you know where the Itcl library directory was installed,\n\"\n"
84 " append msg \"you can set the environment variable ITCL_LIBRARY to point\n\"\n"
85 " append msg \"to the library directory.\n\"\n"
91 static Tcl_ObjCmdProc Itcl_BiDestroyCmd;
92 static Tcl_ObjCmdProc ItclExtendedConfigure;
93 static Tcl_ObjCmdProc ItclExtendedCget;
94 static Tcl_ObjCmdProc ItclExtendedSetGet;
95 static Tcl_ObjCmdProc Itcl_BiCreateHullCmd;
96 static Tcl_ObjCmdProc Itcl_BiSetupComponentCmd;
97 static Tcl_ObjCmdProc Itcl_BiKeepComponentOptionCmd;
98 static Tcl_ObjCmdProc Itcl_BiIgnoreComponentOptionCmd;
99 static Tcl_ObjCmdProc Itcl_BiInitOptionsCmd;
102 * FORWARD DECLARATIONS
104 static Tcl_Obj* ItclReportPublicOpt(Tcl_Interp *interp,
105 ItclVariable *ivPtr, ItclObject *contextIoPtr);
107 static Tcl_ObjCmdProc ItclBiClassUnknownCmd;
109 * Standard list of built-in methods for all objects.
111 typedef struct BiMethod {
112 const char* name; /* method name */
113 const char* usage; /* string describing usage */
114 const char* registration;/* registration name for C proc */
115 Tcl_ObjCmdProc *proc; /* implementation C proc */
116 int flags; /* flag for which type of class to be used */
119 static const BiMethod BiMethodList[] = {
122 "@itcl-builtin-callinstance",
123 Itcl_BiCallInstanceCmd,
124 ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR
128 "@itcl-builtin-getinstancevar",
129 Itcl_BiGetInstanceVarCmd,
130 ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR
134 "@itcl-builtin-cget",
136 ITCL_CLASS|ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR
139 "?-option? ?value -option value...?",
140 "@itcl-builtin-configure",
142 ITCL_CLASS|ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR
145 "widgetType widgetPath ?-class className? ?optionName value ...?",
146 "@itcl-builtin-createhull",
147 Itcl_BiCreateHullCmd,
152 "@itcl-builtin-destroy",
154 ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR
156 { "installcomponent",
157 "<componentName> using <classname> <winpath> ?-option value...?",
158 "@itcl-builtin-installcomponent",
159 Itcl_BiInstallComponentCmd,
164 "@itcl-builtin-itcl_hull",
166 ITCL_WIDGET|ITCL_WIDGETADAPTOR
172 ITCL_CLASS|ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET
175 "?optionName value ...?",
176 "@itcl-builtin-initoptions",
177 Itcl_BiInitOptionsCmd,
182 "@itcl-builtin-mymethod",
184 ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR
188 "@itcl-builtin-myvar",
190 ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR
194 "@itcl-builtin-myproc",
196 ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR
200 "@itcl-builtin-mytypemethod",
201 Itcl_BiMyTypeMethodCmd,
202 ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR
206 "@itcl-builtin-mytypevar",
208 ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR
212 "@itcl-builtin-setget",
218 "@itcl-builtin-classunknown",
219 ItclBiClassUnknownCmd,
220 ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR
222 {"keepcomponentoption",
223 "componentName optionName ?optionName ...?",
224 "@itcl-builtin-keepcomponentoption",
225 Itcl_BiKeepComponentOptionCmd,
228 {"ignorecomponentoption",
229 "componentName optionName ?optionName ...?",
230 "@itcl-builtin-ignorecomponentoption",
231 Itcl_BiIgnoreComponentOptionCmd,
234 /* the next 3 are defined in library/itclHullCmds.tcl */
235 {"addoptioncomponent",
236 "componentName optionName ?optionName ...?",
237 "@itcl-builtin-addoptioncomponent",
241 {"ignoreoptioncomponent",
242 "componentName optionName ?optionName ...?",
243 "@itcl-builtin-ignoreoptioncomponent",
247 {"renameoptioncomponent",
248 "componentName optionName ?optionName ...?",
249 "@itcl-builtin-renameoptioncomponent",
254 "componentName using widgetType widgetPath ?optionName value ...?",
255 "@itcl-builtin-setupcomponent",
256 Itcl_BiSetupComponentCmd,
260 static int BiMethodListLen = sizeof(BiMethodList)/sizeof(BiMethod);
264 * ------------------------------------------------------------------------
265 * ItclRestoreInfoVars()
267 * Delete callback to restore original "info" ensemble (revert inject of Itcl)
269 * ------------------------------------------------------------------------
274 ClientData clientData)
276 ItclObjectInfo *infoPtr = (ItclObjectInfo *)clientData;
277 Tcl_Interp *interp = infoPtr->interp;
281 cmd = Tcl_FindCommand(interp, "info", NULL, TCL_GLOBAL_ONLY);
282 if (cmd == NULL || !Tcl_IsEnsemble(cmd)) {
285 Tcl_GetEnsembleMappingDict(NULL, cmd, &mapDict);
286 if (mapDict == NULL) {
289 if (infoPtr->infoVarsPtr == NULL || infoPtr->infoVars4Ptr == NULL) {
293 Tcl_DictObjPut(NULL, mapDict, infoPtr->infoVars4Ptr, infoPtr->infoVarsPtr);
294 Tcl_SetEnsembleMappingDict(interp, cmd, mapDict);
297 if (infoPtr->infoVarsPtr) {
298 Tcl_DecrRefCount(infoPtr->infoVarsPtr);
299 infoPtr->infoVarsPtr = NULL;
301 if (infoPtr->infoVars4Ptr) {
302 Tcl_DecrRefCount(infoPtr->infoVars4Ptr);
303 infoPtr->infoVars4Ptr = NULL;
309 * ------------------------------------------------------------------------
312 * Creates a namespace full of built-in methods/procs for [incr Tcl]
313 * classes. This includes things like the "isa" method and "info"
314 * for querying class info. Usually invoked by Itcl_Init() when
315 * [incr Tcl] is first installed into an interpreter.
317 * Returns TCL_OK/TCL_ERROR to indicate success/failure.
318 * ------------------------------------------------------------------------
323 Tcl_Interp *interp, /* current interpreter */
324 ItclObjectInfo *infoPtr)
326 Tcl_Namespace *itclBiNs;
334 * "::itcl::builtin" commands.
335 * These commands are imported into each class
336 * just before the class definition is parsed.
338 Tcl_DStringInit(&buffer);
339 for (i=0; i < BiMethodListLen; i++) {
340 Tcl_DStringSetLength(&buffer, 0);
341 Tcl_DStringAppend(&buffer, "::itcl::builtin::", -1);
342 Tcl_DStringAppend(&buffer, BiMethodList[i].name, -1);
343 Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer),
344 BiMethodList[i].proc, infoPtr, NULL);
346 Tcl_DStringFree(&buffer);
348 Tcl_CreateObjCommand(interp, "::itcl::builtin::chain", Itcl_BiChainCmd,
351 Tcl_CreateObjCommand(interp, "::itcl::builtin::classunknown",
352 ItclBiClassUnknownCmd, infoPtr, NULL);
354 ItclInfoInit(interp, infoPtr);
356 * Export all commands in the built-in namespace so we can
357 * import them later on.
359 itclBiNs = Tcl_FindNamespace(interp, "::itcl::builtin",
360 NULL, TCL_LEAVE_ERR_MSG);
362 if ((itclBiNs == NULL) ||
363 Tcl_Export(interp, itclBiNs, "[a-z]*", /* resetListFirst */ 1) != TCL_OK) {
367 * Install into the [info] ensemble.
370 infoCmd = Tcl_FindCommand(interp, "info", NULL, TCL_GLOBAL_ONLY);
371 if (infoCmd != NULL && Tcl_IsEnsemble(infoCmd)) {
372 Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict);
373 if (mapDict != NULL) {
374 infoPtr->infoVars4Ptr = Tcl_NewStringObj("vars", -1);
375 Tcl_IncrRefCount(infoPtr->infoVars4Ptr);
376 result = Tcl_DictObjGet(NULL, mapDict, infoPtr->infoVars4Ptr,
377 &infoPtr->infoVarsPtr);
378 if (result == TCL_OK && infoPtr->infoVarsPtr) {
379 Tcl_IncrRefCount(infoPtr->infoVarsPtr);
380 Tcl_DictObjPut(NULL, mapDict, infoPtr->infoVars4Ptr,
381 Tcl_NewStringObj("::itcl::builtin::Info::vars", -1));
382 Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict);
384 * Note that ItclRestoreInfoVars is called in callback
385 * if built-in Itcl command info::vars or the ensemble get
386 * deleted (see ItclInfoInit registering that). */
388 Tcl_DecrRefCount(infoPtr->infoVars4Ptr);
389 infoPtr->infoVars4Ptr = NULL;
399 * ------------------------------------------------------------------------
400 * Itcl_InstallBiMethods()
402 * Invoked when a class is first created, just after the class
403 * definition has been parsed, to add definitions for built-in
404 * methods to the class. If a method already exists in the class
405 * with the same name as the built-in, then the built-in is skipped.
406 * Otherwise, a method definition for the built-in method is added.
408 * Returns TCL_OK if successful, or TCL_ERROR (along with an error
409 * message in the interpreter) if anything goes wrong.
410 * ------------------------------------------------------------------------
413 Itcl_InstallBiMethods(
414 Tcl_Interp *interp, /* current interpreter */
415 ItclClass *iclsPtr) /* class definition to be updated */
424 * Scan through all of the built-in methods and see if
425 * that method already exists in the class. If not, add
428 * TRICKY NOTE: The virtual tables haven't been built yet,
429 * so look for existing methods the hard way--by scanning
430 * through all classes.
432 Tcl_Obj *objPtr = Tcl_NewStringObj("", 0);
433 for (i=0; i < BiMethodListLen; i++) {
434 Tcl_HashEntry *hPtr = NULL;
436 Itcl_InitHierIter(&hier, iclsPtr);
437 Tcl_SetStringObj(objPtr, BiMethodList[i].name, -1);
438 superPtr = Itcl_AdvanceHierIter(&hier);
440 hPtr = Tcl_FindHashEntry(&superPtr->functions, (char *)objPtr);
444 superPtr = Itcl_AdvanceHierIter(&hier);
446 Itcl_DeleteHierIter(&hier);
449 if (iclsPtr->flags & BiMethodList[i].flags) {
450 result = Itcl_CreateMethod(interp, iclsPtr,
451 Tcl_NewStringObj(BiMethodList[i].name, -1),
452 BiMethodList[i].usage, BiMethodList[i].registration);
454 if (result != TCL_OK) {
462 * Every Itcl class gets an info method installed so that each has
463 * a proper context for the subcommands to do their context senstive
468 && (iclsPtr->flags & (ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR))) {
469 result = Itcl_CreateMethod(interp, iclsPtr,
470 Tcl_NewStringObj("info", -1), NULL, "@itcl-builtin-info");
473 Tcl_DecrRefCount(objPtr);
478 * ------------------------------------------------------------------------
481 * Invoked whenever the user issues the "isa" method for an object.
482 * Handles the following syntax:
484 * <objName> isa <className>
486 * Checks to see if the object has the given <className> anywhere
487 * in its heritage. Returns 1 if so, and 0 otherwise.
488 * ------------------------------------------------------------------------
493 void *dummy, /* class definition */
494 Tcl_Interp *interp, /* current interpreter */
495 int objc, /* number of arguments */
496 Tcl_Obj *const objv[]) /* argument objects */
501 ItclClass *contextIclsPtr;
502 ItclObject *contextIoPtr;
506 * Make sure that this command is being invoked in the proper
509 contextIclsPtr = NULL;
510 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
514 if (contextIoPtr == NULL) {
515 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
516 "improper usage: should be \"object isa className\"",
521 token = Tcl_GetString(objv[0]);
522 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
523 "wrong # args: should be \"object ", token, " className\"",
529 * Look for the requested class. If it is not found, then
530 * try to autoload it. If it absolutely cannot be found,
533 token = Tcl_GetString(objv[1]);
534 iclsPtr = Itcl_FindClass(interp, token, /* autoload */ 1);
535 if (iclsPtr == NULL) {
539 if (Itcl_ObjectIsa(contextIoPtr, iclsPtr)) {
540 Tcl_SetWideIntObj(Tcl_GetObjResult(interp), 1);
542 Tcl_SetWideIntObj(Tcl_GetObjResult(interp), 0);
549 * ------------------------------------------------------------------------
550 * Itcl_BiConfigureCmd()
552 * Invoked whenever the user issues the "configure" method for an object.
553 * Handles the following syntax:
555 * <objName> configure ?-<option>? ?<value> -<option> <value>...?
557 * Allows access to public variables as if they were configuration
558 * options. With no arguments, this command returns the current
559 * list of public variable options. If -<option> is specified,
560 * this returns the information for just one option:
562 * -<optionName> <initVal> <currentVal>
564 * Otherwise, the list of arguments is parsed, and values are
565 * assigned to the various public variable options. When each
566 * option changes, a big of "config" code associated with the option
567 * is executed, to bring the object up to date.
568 * ------------------------------------------------------------------------
573 void *dummy, /* class definition */
574 Tcl_Interp *interp, /* current interpreter */
575 int objc, /* number of arguments */
576 Tcl_Obj *const objv[]) /* argument objects */
578 ItclClass *contextIclsPtr;
579 ItclObject *contextIoPtr;
585 Tcl_HashSearch place;
587 Tcl_Namespace *saveNsPtr;
588 Tcl_Obj * const *unparsedObjv;
591 ItclVarLookup *vlookup;
592 ItclMemberCode *mcode;
594 ItclObjectInfo *infoPtr;
603 ItclShowArgs(1, "Itcl_BiConfigureCmd", objc, objv);
609 Tcl_DStringInit(&buffer);
610 Tcl_DStringInit(&buffer2);
613 * Make sure that this command is being invoked in the proper
616 contextIclsPtr = NULL;
617 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
621 if (contextIoPtr == NULL) {
622 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
623 "improper usage: should be ",
624 "\"object configure ?-option? ?value -option value...?\"",
630 * BE CAREFUL: work in the virtual scope!
632 if (contextIoPtr != NULL) {
633 contextIclsPtr = contextIoPtr->iclsPtr;
636 infoPtr = contextIclsPtr->infoPtr;
637 if (!(contextIclsPtr->flags & ITCL_CLASS)) {
638 /* first check if it is an option */
640 hPtr = Tcl_FindHashEntry(&contextIclsPtr->options,
643 result = ItclExtendedConfigure(contextIclsPtr, interp, objc, objv);
644 if (result != TCL_CONTINUE) {
647 if (infoPtr->unparsedObjc > 0) {
648 unparsedObjc = infoPtr->unparsedObjc;
649 unparsedObjv = infoPtr->unparsedObjv;
657 if (unparsedObjc == 1) {
658 resultPtr = Tcl_NewListObj(0, NULL);
660 Itcl_InitHierIter(&hier, contextIclsPtr);
661 while ((iclsPtr=Itcl_AdvanceHierIter(&hier)) != NULL) {
662 hPtr = Tcl_FirstHashEntry(&iclsPtr->variables, &place);
664 ivPtr = (ItclVariable*)Tcl_GetHashValue(hPtr);
665 if (ivPtr->protection == ITCL_PUBLIC) {
666 objPtr = ItclReportPublicOpt(interp, ivPtr, contextIoPtr);
668 Tcl_ListObjAppendElement(NULL, resultPtr,
671 hPtr = Tcl_NextHashEntry(&place);
674 Itcl_DeleteHierIter(&hier);
676 Tcl_SetObjResult(interp, resultPtr);
681 * HANDLE: configure -option
683 if (unparsedObjc == 2) {
684 token = Tcl_GetString(unparsedObjv[1]);
686 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
687 "improper usage: should be ",
688 "\"object configure ?-option? ?value -option value...?\"",
694 hPtr = ItclResolveVarEntry(contextIclsPtr, token+1);
696 vlookup = (ItclVarLookup*)Tcl_GetHashValue(hPtr);
698 if (vlookup->ivPtr->protection != ITCL_PUBLIC) {
703 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
704 "unknown option \"", token, "\"",
708 resultPtr = ItclReportPublicOpt(interp,
709 vlookup->ivPtr, contextIoPtr);
710 Tcl_SetObjResult(interp, resultPtr);
716 * HANDLE: configure -option value -option value...
718 * Be careful to work in the virtual scope. If this "configure"
719 * method was defined in a base class, the current namespace
720 * (from Itcl_ExecMethod()) will be that base class. Activate
721 * the derived class namespace here, so that instance variables
722 * are accessed properly.
726 for (i=1; i < unparsedObjc; i+=2) {
727 if (i+1 >= unparsedObjc) {
728 Tcl_AppendResult(interp, "need option value pair", NULL);
733 token = Tcl_GetString(unparsedObjv[i]);
735 hPtr = ItclResolveVarEntry(contextIclsPtr, token+1);
737 hPtr = ItclResolveVarEntry(contextIclsPtr, token);
740 vlookup = (ItclVarLookup*)Tcl_GetHashValue(hPtr);
744 if (!vlookup || (vlookup->ivPtr->protection != ITCL_PUBLIC)) {
745 Tcl_AppendResult(interp, "unknown option \"", token, "\"",
750 if (i == unparsedObjc-1) {
751 Tcl_AppendResult(interp, "value for \"", token, "\" missing",
757 ivPtr = vlookup->ivPtr;
758 Tcl_DStringSetLength(&buffer2, 0);
759 if (!(ivPtr->flags & ITCL_COMMON)) {
760 Tcl_DStringAppend(&buffer2,
761 Tcl_GetString(contextIoPtr->varNsNamePtr), -1);
763 Tcl_DStringAppend(&buffer2,
764 Tcl_GetString(ivPtr->iclsPtr->fullNamePtr), -1);
765 Tcl_DStringAppend(&buffer2, "::", 2);
766 Tcl_DStringAppend(&buffer2,
767 Tcl_GetString(ivPtr->namePtr), -1);
768 varName = Tcl_DStringValue(&buffer2);
769 lastval = Tcl_GetVar2(interp, varName, NULL, 0);
770 Tcl_DStringSetLength(&buffer, 0);
771 Tcl_DStringAppend(&buffer, (lastval) ? lastval : "", -1);
773 token = Tcl_GetString(unparsedObjv[i+1]);
774 if (Tcl_SetVar2(interp, varName, NULL, token,
775 TCL_LEAVE_ERR_MSG) == NULL) {
776 Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
777 "\n (error in configuration of public variable \"%s\")",
778 Tcl_GetString(ivPtr->fullNamePtr)));
784 * If this variable has some "config" code, invoke it now.
786 * TRICKY NOTE: Be careful to evaluate the code one level
787 * up in the call stack, so that it's executed in the
788 * calling context, and not in the context that we've
789 * set up for public variable access.
791 mcode = ivPtr->codePtr;
792 if (mcode && Itcl_IsMemberCodeImplemented(mcode)) {
793 if (!ivPtr->iclsPtr->infoPtr->useOldResolvers) {
794 Itcl_SetCallFrameResolver(interp, contextIoPtr->resolvePtr);
796 saveNsPtr = Tcl_GetCurrentNamespace(interp);
797 Itcl_SetCallFrameNamespace(interp, ivPtr->iclsPtr->nsPtr);
798 result = Tcl_EvalObjEx(interp, mcode->bodyPtr, 0);
799 Itcl_SetCallFrameNamespace(interp, saveNsPtr);
800 if (result == TCL_OK) {
801 Tcl_ResetResult(interp);
803 Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
804 "\n (error in configuration of public variable \"%s\")",
805 Tcl_GetString(ivPtr->fullNamePtr)));
806 Tcl_SetVar2(interp, varName,NULL,
807 Tcl_DStringValue(&buffer), 0);
815 if (infoPtr->unparsedObjc > 0) {
816 while (infoPtr->unparsedObjc-- > 1) {
817 Tcl_DecrRefCount(infoPtr->unparsedObjv[infoPtr->unparsedObjc]);
819 ckfree ((char *)infoPtr->unparsedObjv);
820 infoPtr->unparsedObjv = NULL;
821 infoPtr->unparsedObjc = 0;
823 Tcl_DStringFree(&buffer2);
824 Tcl_DStringFree(&buffer);
831 * ------------------------------------------------------------------------
834 * Invoked whenever the user issues the "cget" method for an object.
835 * Handles the following syntax:
837 * <objName> cget -<option>
839 * Allows access to public variables as if they were configuration
840 * options. Mimics the behavior of the usual "cget" method for
841 * Tk widgets. Returns the current value of the public variable
842 * with name <option>.
843 * ------------------------------------------------------------------------
848 void *dummy, /* class definition */
849 Tcl_Interp *interp, /* current interpreter */
850 int objc, /* number of arguments */
851 Tcl_Obj *const objv[]) /* argument objects */
853 ItclClass *contextIclsPtr;
854 ItclObject *contextIoPtr;
857 ItclVarLookup *vlookup;
863 ItclShowArgs(1,"Itcl_BiCgetCmd", objc, objv);
865 * Make sure that this command is being invoked in the proper
868 contextIclsPtr = NULL;
869 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
872 if ((contextIoPtr == NULL) || objc != 2) {
873 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
874 "improper usage: should be \"object cget -option\"",
880 * BE CAREFUL: work in the virtual scope!
882 if (contextIoPtr != NULL) {
883 contextIclsPtr = contextIoPtr->iclsPtr;
886 if (!(contextIclsPtr->flags & ITCL_CLASS)) {
887 result = ItclExtendedCget(contextIclsPtr, interp, objc, objv);
888 if (result != TCL_CONTINUE) {
892 name = Tcl_GetString(objv[1]);
895 hPtr = ItclResolveVarEntry(contextIclsPtr, name+1);
897 vlookup = (ItclVarLookup*)Tcl_GetHashValue(hPtr);
900 if ((vlookup == NULL) || (vlookup->ivPtr->protection != ITCL_PUBLIC)) {
901 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
902 "unknown option \"", name, "\"",
907 val = Itcl_GetInstanceVar(interp,
908 Tcl_GetString(vlookup->ivPtr->namePtr),
909 contextIoPtr, vlookup->ivPtr->iclsPtr);
912 Tcl_SetObjResult(interp, Tcl_NewStringObj(val, -1));
914 Tcl_SetObjResult(interp, Tcl_NewStringObj("<undefined>", -1));
921 * ------------------------------------------------------------------------
922 * ItclReportPublicOpt()
924 * Returns information about a public variable formatted as a
925 * configuration option:
927 * -<varName> <initVal> <currentVal>
929 * Used by Itcl_BiConfigureCmd() to report configuration options.
930 * Returns a Tcl_Obj containing the information.
931 * ------------------------------------------------------------------------
935 Tcl_Interp *interp, /* interpreter containing the object */
936 ItclVariable *ivPtr, /* public variable to be reported */
937 ItclObject *contextIoPtr) /* object containing this variable */
942 ItclVarLookup *vlookup;
947 listPtr = Tcl_NewListObj(0, NULL);
950 * Determine how the option name should be reported.
951 * If the simple name can be used to find it in the virtual
952 * data table, then use the simple name. Otherwise, this
953 * is a shadowed variable; use the full name.
955 Tcl_DStringInit(&optName);
956 Tcl_DStringAppend(&optName, "-", -1);
958 iclsPtr = (ItclClass*)contextIoPtr->iclsPtr;
959 hPtr = ItclResolveVarEntry(iclsPtr,
960 Tcl_GetString(ivPtr->fullNamePtr));
961 assert(hPtr != NULL);
962 vlookup = (ItclVarLookup*)Tcl_GetHashValue(hPtr);
963 Tcl_DStringAppend(&optName, vlookup->leastQualName, -1);
965 objPtr = Tcl_NewStringObj(Tcl_DStringValue(&optName), -1);
966 Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
967 Tcl_DStringFree(&optName);
971 objPtr = ivPtr->init;
973 objPtr = Tcl_NewStringObj("<undefined>", -1);
975 Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
977 val = Itcl_GetInstanceVar(interp, Tcl_GetString(ivPtr->namePtr),
978 contextIoPtr, ivPtr->iclsPtr);
981 objPtr = Tcl_NewStringObj((const char *)val, -1);
983 objPtr = Tcl_NewStringObj("<undefined>", -1);
985 Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
991 * ------------------------------------------------------------------------
994 * Returns information about an option formatted as a
995 * configuration option:
997 * <optionName> <initVal> <currentVal>
999 * Used by ItclExtendedConfigure() to report configuration options.
1000 * Returns a Tcl_Obj containing the information.
1001 * ------------------------------------------------------------------------
1005 Tcl_Interp *interp, /* interpreter containing the object */
1006 ItclOption *ioptPtr, /* option to be reported */
1007 ItclObject *contextIoPtr) /* object containing this variable */
1011 ItclDelegatedOption *idoPtr;
1014 listPtr = Tcl_NewListObj(0, NULL);
1015 idoPtr = ioptPtr->iclsPtr->infoPtr->currIdoPtr;
1016 if (idoPtr != NULL) {
1017 Tcl_ListObjAppendElement(NULL, listPtr, idoPtr->namePtr);
1018 if (idoPtr->resourceNamePtr == NULL) {
1019 Tcl_ListObjAppendElement(NULL, listPtr,
1020 Tcl_NewStringObj("", -1));
1021 /* FIXME possible memory leak */
1023 Tcl_ListObjAppendElement(NULL, listPtr,
1024 idoPtr->resourceNamePtr);
1026 if (idoPtr->classNamePtr == NULL) {
1027 Tcl_ListObjAppendElement(NULL, listPtr,
1028 Tcl_NewStringObj("", -1));
1029 /* FIXME possible memory leak */
1031 Tcl_ListObjAppendElement(NULL, listPtr,
1032 idoPtr->classNamePtr);
1035 Tcl_ListObjAppendElement(NULL, listPtr, ioptPtr->namePtr);
1036 Tcl_ListObjAppendElement(NULL, listPtr,
1037 ioptPtr->resourceNamePtr);
1038 Tcl_ListObjAppendElement(NULL, listPtr,
1039 ioptPtr->classNamePtr);
1041 if (ioptPtr->defaultValuePtr) {
1042 objPtr = ioptPtr->defaultValuePtr;
1044 objPtr = Tcl_NewStringObj("<undefined>", -1);
1046 Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
1047 val = ItclGetInstanceVar(interp, "itcl_options",
1048 Tcl_GetString(ioptPtr->namePtr),
1049 contextIoPtr, ioptPtr->iclsPtr);
1051 objPtr = Tcl_NewStringObj((const char *)val, -1);
1053 objPtr = Tcl_NewStringObj("<undefined>", -1);
1055 Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
1062 * ------------------------------------------------------------------------
1065 * Invoked to handle the "chain" command, to access the version of
1066 * a method or proc that exists in a base class. Handles the
1069 * chain ?<arg> <arg>...?
1071 * Looks up the inheritance hierarchy for another implementation
1072 * of the method/proc that is currently executing. If another
1073 * implementation is found, it is invoked with the specified
1074 * <arg> arguments. If it is not found, this command does nothing.
1075 * This allows a base class method to be called out in a generic way,
1076 * so the code will not have to change if the base class changes.
1077 * ------------------------------------------------------------------------
1082 void *dummy, /* not used */
1083 Tcl_Interp *interp, /* current interpreter */
1084 int objc, /* number of arguments */
1085 Tcl_Obj *const objv[]) /* argument objects */
1087 int result = TCL_OK;
1089 ItclClass *contextIclsPtr;
1090 ItclObject *contextIoPtr;
1097 Tcl_HashEntry *hPtr;
1098 ItclMemberFunc *imPtr;
1100 Tcl_Obj *cmdlinePtr;
1102 Tcl_Obj * const *cObjv;
1108 ItclShowArgs(1, "Itcl_BiChainCmd", objc, objv);
1111 * If this command is not invoked within a class namespace,
1114 contextIclsPtr = NULL;
1115 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
1116 Tcl_ResetResult(interp);
1117 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1118 "cannot chain functions outside of a class context",
1124 * Try to get the command name from the current call frame.
1125 * If it cannot be determined, do nothing. Otherwise, trim
1126 * off any leading path names.
1128 cObjv = Itcl_GetCallVarFrameObjv(interp);
1129 if (cObjv == NULL) {
1132 cObjc = Itcl_GetCallVarFrameObjc(interp);
1134 if ((Itcl_GetCallFrameClientData(interp) == NULL) || (objc == 1)) {
1135 /* that has been a direct call, so no object in front !! */
1136 if (objc == 1 && cObjc >= 2) {
1144 cmd1 = (char *)ckalloc(strlen(Tcl_GetString(cObjv[idx]))+1);
1145 strcpy(cmd1, Tcl_GetString(cObjv[idx]));
1146 Itcl_ParseNamespPath(cmd1, &buffer, &head, &cmd);
1149 * Look for the specified command in one of the base classes.
1150 * If we have an object context, then start from the most-specific
1151 * class and walk up the hierarchy to the current context. If
1152 * there is multiple inheritance, having the entire inheritance
1153 * hierarchy will allow us to jump over to another branch of
1154 * the inheritance tree.
1156 * If there is no object context, just start with the current
1159 if (contextIoPtr != NULL) {
1160 Itcl_InitHierIter(&hier, contextIoPtr->iclsPtr);
1161 while ((iclsPtr = Itcl_AdvanceHierIter(&hier)) != NULL) {
1162 if (iclsPtr == contextIclsPtr) {
1167 Itcl_InitHierIter(&hier, contextIclsPtr);
1168 Itcl_AdvanceHierIter(&hier); /* skip the current class */
1172 * Now search up the class hierarchy for the next implementation.
1173 * If found, execute it. Otherwise, do nothing.
1175 objPtr = Tcl_NewStringObj(cmd, -1);
1177 Tcl_IncrRefCount(objPtr);
1178 while ((iclsPtr = Itcl_AdvanceHierIter(&hier)) != NULL) {
1179 hPtr = Tcl_FindHashEntry(&iclsPtr->functions, (char *)objPtr);
1182 imPtr = (ItclMemberFunc*)Tcl_GetHashValue(hPtr);
1185 * NOTE: Avoid the usual "virtual" behavior of
1186 * methods by passing the full name as
1187 * the command argument.
1190 cmdlinePtr = Itcl_CreateArgs(interp,
1191 Tcl_GetString(imPtr->fullNamePtr), objc-1, objv+1);
1193 (void) Tcl_ListObjGetElements(NULL, cmdlinePtr,
1194 &my_objc, &newobjv);
1196 if (imPtr->flags & ITCL_CONSTRUCTOR) {
1197 contextIoPtr = imPtr->iclsPtr->infoPtr->currIoPtr;
1199 ItclShowArgs(1, "___chain", objc-1, newobjv+1);
1200 result = Itcl_EvalMemberCode(interp, imPtr, contextIoPtr,
1201 my_objc-1, newobjv+1);
1202 Tcl_DecrRefCount(cmdlinePtr);
1206 Tcl_DecrRefCount(objPtr);
1208 Tcl_DStringFree(&buffer);
1209 Itcl_DeleteHierIter(&hier);
1218 Tcl_Obj *const *objv)
1220 return Tcl_NRCallObjProc(interp, NRBiChainCmd, clientData, objc, objv);
1229 Tcl_CallFrame frame;
1230 Tcl_Namespace *nsPtr;
1231 ItclClass *iclsPtr = (ItclClass *)data[0];
1232 int objc = PTR2INT(data[1]);
1233 Tcl_Obj *const *objv = (Tcl_Obj *const *)data[2];
1235 if (result != TCL_OK) {
1238 nsPtr = Itcl_GetUplevelNamespace(interp, 1);
1239 if (Itcl_PushCallFrame(interp, &frame, nsPtr,
1240 /*isProcCallFrame*/0) != TCL_OK) {
1243 result = ItclClassCreateObject(iclsPtr->infoPtr, interp, objc, objv);
1244 Itcl_PopCallFrame(interp);
1245 Tcl_DecrRefCount(objv[2]);
1246 Tcl_DecrRefCount(objv[1]);
1247 Tcl_DecrRefCount(objv[0]);
1252 PrepareCreateObject(
1256 Tcl_Obj * const *objv)
1258 Tcl_HashEntry *hPtr;
1261 const char *funcName;
1266 funcName = Tcl_GetString(objv[1]);
1267 if (strcmp(funcName, "itcl_hull") == 0) {
1268 hPtr = Tcl_FindHashEntry(&iclsPtr->resolveCmds, (char *)objv[1]);
1270 Tcl_AppendResult(interp, "INTERNAL ERROR ",
1271 "cannot find itcl_hull method", NULL);
1274 result = Itcl_ExecProc(Tcl_GetHashValue(hPtr), interp, objc, objv);
1277 if (strcmp(funcName, "create") == 0) {
1278 /* allow typeClassName create objectName */
1281 /* allow typeClassName objectName */
1283 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc+3-offset));
1284 newObjv[0] = objv[0];
1285 Tcl_IncrRefCount(newObjv[0]);
1286 newObjv[1] = iclsPtr->namePtr;
1287 Tcl_IncrRefCount(newObjv[1]);
1288 newObjv[2] = Tcl_NewStringObj(iclsPtr->nsPtr->fullName, -1);
1289 Tcl_IncrRefCount(newObjv[2]);
1290 memcpy(newObjv+3, objv+offset, (objc-offset) * sizeof(Tcl_Obj *));
1291 callbackPtr = Itcl_GetCurrentCallbackPtr(interp);
1292 ItclShowArgs(1, "CREATE", objc+3-offset, newObjv);
1293 Tcl_NRAddCallback(interp, CallCreateObject, iclsPtr,
1294 INT2PTR(objc+3-offset), newObjv, NULL);
1295 result = Itcl_NRRunCallbacks(interp, callbackPtr);
1296 if (result != TCL_OK) {
1297 if (iclsPtr->infoPtr->currIoPtr != NULL) {
1298 /* we are in a constructor call */
1299 if (iclsPtr->infoPtr->currIoPtr->hadConstructorError == 0) {
1300 iclsPtr->infoPtr->currIoPtr->hadConstructorError = 1;
1304 ckfree((char *)newObjv);
1308 * ------------------------------------------------------------------------
1309 * ItclBiClassUnknownCmd()
1311 * Invoked to handle the "classunknown" command
1312 * this is called whenever an object is called with an unknown method/proc
1315 * classunknown <object> <methodname> ?<arg> <arg>...?
1317 * ------------------------------------------------------------------------
1321 ItclBiClassUnknownCmd(
1322 void *clientData, /* ItclObjectInfo Ptr */
1323 Tcl_Interp *interp, /* current interpreter */
1324 int objc, /* number of arguments */
1325 Tcl_Obj *const objv[]) /* argument objects */
1328 Tcl_HashEntry *hPtr2;
1336 ItclObjectInfo *infoPtr;
1337 ItclComponent *icPtr;
1338 ItclDelegatedFunction *idmPtr;
1339 ItclDelegatedFunction *idmPtr2;
1340 ItclDelegatedFunction *starIdmPtr;
1343 const char *funcName;
1354 ItclShowArgs(1, "ItclBiClassUnknownCmd", objc, objv);
1361 infoPtr = (ItclObjectInfo *)clientData;
1362 hPtr = Tcl_FindHashEntry(&infoPtr->namespaceClasses,
1363 (char *)Tcl_GetCurrentNamespace(interp));
1365 Tcl_AppendResult(interp, "INTERNAL ERROR: ItclBiClassUnknownCmd ",
1366 "cannot find class\n", NULL);
1369 iclsPtr = (ItclClass *)Tcl_GetHashValue(hPtr);
1370 funcName = Tcl_GetString(objv[1]);
1371 if (strcmp(funcName, "create") == 0) {
1372 /* check if we have a user method create. If not, it is the builtin
1373 * create method and we don't need to check for delegation
1374 * and components with ITCL_COMPONENT_INHERIT
1376 hPtr = Tcl_FindHashEntry(&iclsPtr->resolveCmds, (char *)objv[1]);
1378 return PrepareCreateObject(interp, iclsPtr, objc, objv);
1381 if (strcmp(funcName, "itcl_hull") == 0) {
1385 FOREACH_HASH_VALUE(icPtr, &iclsPtr->components) {
1386 if (icPtr->flags & ITCL_COMPONENT_INHERIT) {
1387 val = Tcl_GetVar2(interp, Tcl_GetString(icPtr->namePtr),
1389 if ((val != NULL) && (strlen(val) > 0)) {
1390 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc));
1391 newObjv[0] = Tcl_NewStringObj(val, -1);
1392 Tcl_IncrRefCount(newObjv[0]);
1393 memcpy(newObjv+1, objv+1, sizeof(Tcl_Obj *) * (objc-1));
1394 ItclShowArgs(1, "UK EVAL1", objc, newObjv);
1395 result = Tcl_EvalObjv(interp, objc, newObjv, 0);
1396 Tcl_DecrRefCount(newObjv[0]);
1397 ckfree((char *)newObjv);
1403 /* from a class object only typemethods can be called directly
1404 * if delegated, so check for that, otherwise create an object
1405 * for ITCL_ECLASS we allow calling too
1409 FOREACH_HASH_VALUE(idmPtr, &iclsPtr->delegatedFunctions) {
1410 if (strcmp(Tcl_GetString(idmPtr->namePtr), funcName) == 0) {
1411 if (idmPtr->flags & ITCL_TYPE_METHOD) {
1414 if (iclsPtr->flags & ITCL_ECLASS) {
1419 if (strcmp(Tcl_GetString(idmPtr->namePtr), "*") == 0) {
1420 if (idmPtr->flags & ITCL_TYPE_METHOD) {
1423 starIdmPtr = idmPtr;
1429 hPtr = Tcl_FindHashEntry(&iclsPtr->delegatedFunctions, (char *)objv[1]);
1431 objPtr = Tcl_NewStringObj("*", -1);
1432 Tcl_IncrRefCount(objPtr);
1433 hPtr = Tcl_FindHashEntry(&iclsPtr->delegatedFunctions,
1435 Tcl_DecrRefCount(objPtr);
1437 idmPtr = (ItclDelegatedFunction *)Tcl_GetHashValue(hPtr);
1442 /* check if the function is in the exceptions */
1443 hPtr2 = Tcl_FindHashEntry(&starIdmPtr->exceptions, (char *)objv[1]);
1444 if (hPtr2 != NULL) {
1445 const char *sep = "";
1446 objPtr = Tcl_NewStringObj("unknown subcommand \"", -1);
1447 Tcl_AppendToObj(objPtr, funcName, -1);
1448 Tcl_AppendToObj(objPtr, "\": must be ", -1);
1449 FOREACH_HASH_VALUE(idmPtr,
1450 &iclsPtr->delegatedFunctions) {
1451 funcName = Tcl_GetString(idmPtr->namePtr);
1452 if (strcmp(funcName, "*") != 0) {
1453 if (strlen(sep) > 0) {
1454 Tcl_AppendToObj(objPtr, sep, -1);
1456 Tcl_AppendToObj(objPtr, funcName, -1);
1460 Tcl_SetObjResult(interp, objPtr);
1465 idmPtr = (ItclDelegatedFunction *)Tcl_GetHashValue(hPtr);
1467 if (idmPtr->icPtr != NULL) {
1468 if (idmPtr->icPtr->ivPtr->flags & ITCL_COMMON) {
1469 val = Tcl_GetVar2(interp,
1470 Tcl_GetString(idmPtr->icPtr->namePtr), NULL, 0);
1472 ItclClass *contextIclsPtr;
1473 ItclObject *contextIoPtr;
1474 contextIclsPtr = NULL;
1475 contextIoPtr = NULL;
1476 Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr);
1477 Tcl_DStringInit(&buffer);
1478 Tcl_DStringAppend(&buffer,
1479 Tcl_GetString(contextIoPtr->varNsNamePtr), -1);
1480 Tcl_DStringAppend(&buffer,
1481 Tcl_GetString(idmPtr->icPtr->ivPtr->fullNamePtr),
1483 val = Tcl_GetVar2(interp, Tcl_DStringValue(&buffer),
1485 Tcl_DStringFree(&buffer);
1488 Tcl_AppendResult(interp, "INTERNAL ERROR: ",
1489 "ItclBiClassUnknownCmd contents ",
1490 "of component == NULL\n", NULL);
1496 if ((idmPtr->asPtr != NULL) || (idmPtr->usingPtr != NULL)) {
1498 listPtr = Tcl_NewListObj(0, NULL);
1499 result = ExpandDelegateAs(interp, NULL, iclsPtr,
1500 idmPtr, funcName, listPtr);
1501 if (result != TCL_OK) {
1504 result = Tcl_ListObjGetElements(interp, listPtr,
1506 if (result != TCL_OK) {
1507 Tcl_DecrRefCount(listPtr);
1510 if (idmPtr->usingPtr != NULL) {
1515 if ((val == NULL) || (strlen(val) == 0)) {
1516 Tcl_AppendResult(interp, "component \"",
1517 Tcl_GetString(idmPtr->icPtr->namePtr),
1518 "\" is not initialized", NULL);
1522 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) *
1523 (objc + lObjc - offset + useComponent));
1525 newObjv[0] = Tcl_NewStringObj(val, -1);
1526 Tcl_IncrRefCount(newObjv[0]);
1528 for (idx = 0; idx < lObjc; idx++) {
1529 newObjv[useComponent+idx] = lObjv[idx];
1531 if (objc-offset > 0) {
1532 memcpy(newObjv+useComponent+lObjc, objv+offset,
1533 sizeof(Tcl_Obj *) * (objc-offset));
1535 ItclShowArgs(1, "OBJ UK EVAL", objc+lObjc-offset+useComponent,
1537 result = Tcl_EvalObjv(interp,
1538 objc+lObjc-offset+useComponent, newObjv, 0);
1539 if (isStar && (result == TCL_OK)) {
1540 if (Tcl_FindHashEntry(&iclsPtr->delegatedFunctions,
1541 (char *)newObjv[1]) == NULL) {
1542 result = ItclCreateDelegatedFunction(interp, iclsPtr,
1543 newObjv[1], idmPtr->icPtr, NULL, NULL,
1545 if (result == TCL_OK) {
1547 idmPtr2->flags |= ITCL_TYPE_METHOD;
1549 idmPtr2->flags |= ITCL_METHOD;
1551 hPtr2 = Tcl_CreateHashEntry(
1552 &iclsPtr->delegatedFunctions,
1553 (char *)newObjv[1], &isNew);
1554 Tcl_SetHashValue(hPtr2, idmPtr2);
1559 Tcl_DecrRefCount(newObjv[0]);
1561 ckfree((char *)newObjv);
1562 if (listPtr != NULL) {
1563 Tcl_DecrRefCount(listPtr);
1565 if (result == TCL_ERROR) {
1566 resStr = Tcl_GetString(Tcl_GetObjResult(interp));
1567 /* FIXME ugly hack at the moment !! */
1568 if (strncmp(resStr, "wrong # args: should be ", 24) == 0) {
1569 resPtr = Tcl_NewStringObj("", -1);
1570 Tcl_AppendToObj(resPtr, resStr, 25);
1572 Tcl_AppendToObj(resPtr, Tcl_GetString(iclsPtr->namePtr),
1574 resStr += strlen(val);
1575 Tcl_AppendToObj(resPtr, resStr, -1);
1576 Tcl_ResetResult(interp);
1577 Tcl_SetObjResult(interp, resPtr);
1583 return PrepareCreateObject(interp, iclsPtr, objc, objv);
1587 * ------------------------------------------------------------------------
1590 * The unknown method handler of the itcl::Root class -- all Itcl
1591 * objects land here when they cannot find a method.
1593 * ------------------------------------------------------------------------
1598 ItclObject *ioPtr, /* The ItclObject seeking method */
1599 Tcl_Interp *interp, /* current interpreter */
1600 int objc, /* number of arguments */
1601 Tcl_Obj *const objv[]) /* argument objects */
1604 Tcl_HashEntry *hPtr2;
1607 Tcl_Obj *listPtr = NULL;
1612 ItclComponent *icPtr;
1613 ItclDelegatedFunction *idmPtr;
1614 ItclDelegatedFunction *idmPtr2;
1617 const char *funcName;
1630 Tcl_AppendResult(interp, "wrong # args: should be one of...",
1632 ItclReportObjectUsage(interp, ioPtr, NULL, NULL);
1635 iclsPtr = ioPtr->iclsPtr;
1644 funcName = Tcl_GetString(objv[1]);
1645 if (strcmp(funcName, "itcl_hull") == 0) {
1650 FOREACH_HASH_VALUE(icPtr, &ioPtr->objectComponents) {
1651 if (icPtr->flags & ITCL_COMPONENT_INHERIT) {
1652 val = Itcl_GetInstanceVar(interp,
1653 Tcl_GetString(icPtr->namePtr), ioPtr,
1654 icPtr->ivPtr->iclsPtr);
1655 if ((val != NULL) && (strlen(val) > 0)) {
1656 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) *
1658 newObjv[0] = Tcl_NewStringObj(val, -1);
1659 Tcl_IncrRefCount(newObjv[0]);
1660 memcpy(newObjv+1, objv+1, sizeof(Tcl_Obj *) * (objc-1));
1661 result = Tcl_EvalObjv(interp, objc, newObjv, 0);
1662 Tcl_DecrRefCount(newObjv[0]);
1663 ckfree((char *)newObjv);
1671 FOREACH_HASH_VALUE(idmPtr, &iclsPtr->delegatedFunctions) {
1672 if (strcmp(Tcl_GetString(idmPtr->namePtr), funcName) == 0) {
1673 if (idmPtr->flags & ITCL_TYPE_METHOD) {
1679 if (strcmp(Tcl_GetString(idmPtr->namePtr), "*") == 0) {
1680 if (idmPtr->flags & ITCL_TYPE_METHOD) {
1690 iclsPtr = ioPtr->iclsPtr;
1692 hPtr = Tcl_FindHashEntry(&iclsPtr->delegatedFunctions, (char *)objv[1]);
1694 objPtr = Tcl_NewStringObj("*", -1);
1695 Tcl_IncrRefCount(objPtr);
1696 hPtr = Tcl_FindHashEntry(&iclsPtr->delegatedFunctions,
1698 Tcl_DecrRefCount(objPtr);
1700 idmPtr = (ItclDelegatedFunction *)Tcl_GetHashValue(hPtr);
1705 idmPtr = (ItclDelegatedFunction *)Tcl_GetHashValue(hPtr);
1708 /* check if the function is in the exceptions */
1709 hPtr2 = Tcl_FindHashEntry(&idmPtr->exceptions, (char *)objv[1]);
1710 if (hPtr2 != NULL) {
1711 const char *sep = "";
1712 objPtr = Tcl_NewStringObj("unknown subcommand \"", -1);
1713 Tcl_AppendToObj(objPtr, funcName, -1);
1714 Tcl_AppendToObj(objPtr, "\": must be ", -1);
1715 FOREACH_HASH_VALUE(idmPtr,
1716 &iclsPtr->delegatedFunctions) {
1717 funcName = Tcl_GetString(idmPtr->namePtr);
1718 if (strcmp(funcName, "*") != 0) {
1719 if (strlen(sep) > 0) {
1720 Tcl_AppendToObj(objPtr, sep, -1);
1722 Tcl_AppendToObj(objPtr, funcName, -1);
1726 Tcl_SetObjResult(interp, objPtr);
1731 if ((idmPtr != NULL) && (idmPtr->icPtr != NULL)) {
1733 /* we cannot use Itcl_GetInstanceVar here as the object is not
1734 * yet completely built. So use the varNsNamePtr
1736 if (idmPtr->icPtr->ivPtr->flags & ITCL_COMMON) {
1737 objPtr = Tcl_NewStringObj(ITCL_VARIABLES_NAMESPACE, -1);
1738 Tcl_AppendToObj(objPtr,
1739 (Tcl_GetObjectNamespace(iclsPtr->oPtr))->fullName, -1);
1740 Tcl_AppendToObj(objPtr, "::", -1);
1741 Tcl_AppendToObj(objPtr,
1742 Tcl_GetString(idmPtr->icPtr->namePtr), -1);
1743 val = Tcl_GetVar2(interp, Tcl_GetString(objPtr), NULL, 0);
1744 Tcl_DecrRefCount(objPtr);
1746 Tcl_DStringInit(&buffer);
1747 Tcl_DStringAppend(&buffer,
1748 Tcl_GetString(ioPtr->varNsNamePtr), -1);
1749 Tcl_DStringAppend(&buffer,
1750 Tcl_GetString(idmPtr->icPtr->ivPtr->fullNamePtr), -1);
1751 val = Tcl_GetVar2(interp, Tcl_DStringValue(&buffer),
1753 Tcl_DStringFree(&buffer);
1757 Tcl_AppendResult(interp, "ItclBiObjectUnknownCmd contents of ",
1758 "component == NULL\n", NULL);
1765 hPtr = Tcl_FindHashEntry(&idmPtr->exceptions, (char *)objv[1]);
1766 /* we have no method name in that case in the caller */
1768 const char *sep = "";
1769 objPtr = Tcl_NewStringObj("unknown subcommand \"", -1);
1770 Tcl_AppendToObj(objPtr, funcName, -1);
1771 Tcl_AppendToObj(objPtr, "\": must be ", -1);
1772 FOREACH_HASH_VALUE(idmPtr, &iclsPtr->delegatedFunctions) {
1773 funcName = Tcl_GetString(idmPtr->namePtr);
1774 if (strcmp(funcName, "*") != 0) {
1775 if (strlen(sep) > 0) {
1776 Tcl_AppendToObj(objPtr, sep, -1);
1778 Tcl_AppendToObj(objPtr, funcName, -1);
1784 if (idmPtr == NULL) {
1785 Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
1786 "\": should be one of...", NULL);
1787 ItclReportObjectUsage(interp, ioPtr, NULL, NULL);
1791 if ((idmPtr != NULL) && ((idmPtr->asPtr != NULL) ||
1792 (idmPtr->usingPtr != NULL))) {
1794 listPtr = Tcl_NewListObj(0, NULL);
1795 result = ExpandDelegateAs(interp, NULL, iclsPtr,
1796 idmPtr, funcName, listPtr);
1797 if (result != TCL_OK) {
1798 Tcl_DecrRefCount(listPtr);
1801 result = Tcl_ListObjGetElements(interp, listPtr,
1803 if (result != TCL_OK) {
1804 Tcl_DecrRefCount(listPtr);
1807 if (idmPtr->usingPtr != NULL) {
1812 if ((val == NULL) || (strlen(val) == 0)) {
1813 Tcl_AppendResult(interp, "component \"",
1814 Tcl_GetString(idmPtr->icPtr->namePtr),
1815 "\" is not initialized", NULL);
1819 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) *
1820 (objc + lObjc - offset + useComponent));
1822 newObjv[0] = Tcl_NewStringObj(val, -1);
1823 Tcl_IncrRefCount(newObjv[0]);
1825 for (idx = 0; idx < lObjc; idx++) {
1826 newObjv[useComponent+idx] = lObjv[idx];
1828 if (objc-offset > 0) {
1829 memcpy(newObjv+useComponent+lObjc, objv+offset,
1830 sizeof(Tcl_Obj *) * (objc-offset));
1832 ItclShowArgs(1, "UK EVAL2", objc+lObjc-offset+useComponent,
1834 result = Tcl_EvalObjv(interp, objc+lObjc-offset+useComponent,
1836 if (isStar && (result == TCL_OK)) {
1837 if (Tcl_FindHashEntry(&iclsPtr->delegatedFunctions,
1838 (char *)newObjv[1]) == NULL) {
1839 result = ItclCreateDelegatedFunction(interp, iclsPtr,
1840 newObjv[1], idmPtr->icPtr, NULL, NULL,
1842 if (result == TCL_OK) {
1844 idmPtr2->flags |= ITCL_TYPE_METHOD;
1846 idmPtr2->flags |= ITCL_METHOD;
1848 hPtr2 = Tcl_CreateHashEntry(
1849 &iclsPtr->delegatedFunctions, (char *)newObjv[1],
1851 Tcl_SetHashValue(hPtr2, idmPtr2);
1856 Tcl_DecrRefCount(newObjv[0]);
1858 if (listPtr != NULL) {
1859 Tcl_DecrRefCount(listPtr);
1861 ckfree((char *)newObjv);
1862 if (result == TCL_OK) {
1865 resStr = Tcl_GetString(Tcl_GetObjResult(interp));
1866 /* FIXME ugly hack at the moment !! */
1867 if (strncmp(resStr, "wrong # args: should be ", 24) == 0) {
1868 resPtr = Tcl_NewStringObj("", -1);
1869 Tcl_AppendToObj(resPtr, resStr, 25);
1871 Tcl_AppendToObj(resPtr, Tcl_GetString(iclsPtr->namePtr), -1);
1872 resStr += strlen(val);
1873 Tcl_AppendToObj(resPtr, resStr, -1);
1874 Tcl_ResetResult(interp);
1875 Tcl_SetObjResult(interp, resPtr);
1880 static Tcl_Obj *makeAsOptionInfo(
1882 Tcl_Obj *optNamePtr,
1883 ItclDelegatedOption *idoPtr,
1885 Tcl_Obj * const *lObjv2)
1890 objPtr = Tcl_NewListObj(0, NULL);
1891 Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(
1892 Tcl_GetString(optNamePtr), -1));
1893 Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(
1894 Tcl_GetString(idoPtr->resourceNamePtr), -1));
1895 Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(
1896 Tcl_GetString(idoPtr->classNamePtr), -1));
1897 for (j = 3; j < lObjc2; j++) {
1898 Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(
1899 Tcl_GetString(lObjv2[j]), -1));
1905 * ------------------------------------------------------------------------
1906 * ItclExtendedConfigure()
1908 * Invoked whenever the user issues the "configure" method for an object.
1909 * If the class is not ITCL_CLASS
1910 * Handles the following syntax:
1912 * <objName> configure ?-<option>? ?<value> -<option> <value>...?
1914 * Allows access to public variables as if they were configuration
1915 * options. With no arguments, this command returns the current
1916 * list of public variable options. If -<option> is specified,
1917 * this returns the information for just one option:
1919 * -<optionName> <initVal> <currentVal>
1921 * Otherwise, the list of arguments is parsed, and values are
1922 * assigned to the various public variable options. When each
1923 * option changes, a big of "config" code associated with the option
1924 * is executed, to bring the object up to date.
1925 * ------------------------------------------------------------------------
1929 ItclExtendedConfigure(
1930 void *dummy, /* class definition */
1931 Tcl_Interp *interp, /* current interpreter */
1932 int objc, /* number of arguments */
1933 Tcl_Obj *const objv[]) /* argument objects */
1936 Tcl_HashTable unique;
1937 Tcl_HashEntry *hPtr2;
1938 Tcl_HashEntry *hPtr3;
1944 Tcl_Obj *optNamePtr;
1945 Tcl_Obj *methodNamePtr;
1946 Tcl_Obj *configureMethodPtr;
1949 Tcl_Obj *lObjvOne[1];
1952 Tcl_Namespace *saveNsPtr;
1953 Tcl_Namespace *evalNsPtr;
1954 ItclClass *contextIclsPtr;
1955 ItclClass *iclsPtr2;
1956 ItclComponent *componentIcPtr;
1957 ItclObject *contextIoPtr;
1958 ItclDelegatedFunction *idmPtr;
1959 ItclDelegatedOption *idoPtr;
1960 ItclDelegatedOption *saveIdoPtr;
1962 ItclComponent *icPtr;
1963 ItclOption *ioptPtr;
1964 ItclObjectInfo *infoPtr;
1976 ItclShowArgs(1, "ItclExtendedConfigure", objc, objv);
1980 * Make sure that this command is being invoked in the proper
1983 contextIclsPtr = NULL;
1984 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
1988 if (contextIoPtr == NULL) {
1989 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
1990 "improper usage: should be ",
1991 "\"object configure ?-option? ?value -option value...?\"",
1997 * BE CAREFUL: work in the virtual scope!
1999 if (contextIoPtr != NULL) {
2000 contextIclsPtr = contextIoPtr->iclsPtr;
2002 infoPtr = contextIclsPtr->infoPtr;
2003 if (infoPtr->currContextIclsPtr != NULL) {
2004 contextIclsPtr = infoPtr->currContextIclsPtr;
2008 /* first check if method configure is delegated */
2009 methodNamePtr = Tcl_NewStringObj("*", -1);
2010 hPtr = Tcl_FindHashEntry(&contextIclsPtr->delegatedFunctions, (char *)
2013 /* all methods are delegated */
2014 idmPtr = (ItclDelegatedFunction *)Tcl_GetHashValue(hPtr);
2015 Tcl_SetStringObj(methodNamePtr, "configure", -1);
2016 hPtr = Tcl_FindHashEntry(&idmPtr->exceptions, (char *)methodNamePtr);
2018 icPtr = idmPtr->icPtr;
2019 val = ItclGetInstanceVar(interp, Tcl_GetString(icPtr->namePtr),
2020 NULL, contextIoPtr, contextIclsPtr);
2022 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *)*(objc+5));
2023 newObjv[0] = Tcl_NewStringObj(val, -1);
2024 Tcl_IncrRefCount(newObjv[0]);
2025 newObjv[1] = Tcl_NewStringObj("configure", -1);
2026 Tcl_IncrRefCount(newObjv[1]);
2027 for(i=1;i<objc;i++) {
2028 newObjv[i+1] = objv[i];
2030 objPtr = Tcl_NewStringObj(val, -1);
2031 Tcl_IncrRefCount(objPtr);
2032 oPtr = Tcl_GetObjectFromObj(interp, objPtr);
2034 ioPtr = (ItclObject *)Tcl_ObjectGetMetadata(oPtr,
2035 infoPtr->object_meta_type);
2036 infoPtr->currContextIclsPtr = ioPtr->iclsPtr;
2038 ItclShowArgs(1, "EXTENDED CONFIGURE EVAL1", objc+1, newObjv);
2039 result = Tcl_EvalObjv(interp, objc+1, newObjv, TCL_EVAL_DIRECT);
2040 Tcl_DecrRefCount(newObjv[0]);
2041 Tcl_DecrRefCount(newObjv[1]);
2042 ckfree((char *)newObjv);
2043 Tcl_DecrRefCount(objPtr);
2045 infoPtr->currContextIclsPtr = NULL;
2047 Tcl_DecrRefCount(methodNamePtr);
2051 /* configure is not delegated, so reset hPtr for checks later on! */
2055 Tcl_DecrRefCount(methodNamePtr);
2056 /* now do the hard work */
2058 Tcl_InitObjHashTable(&unique);
2059 /* plain configure */
2060 listPtr = Tcl_NewListObj(0, NULL);
2061 if (contextIclsPtr->flags & ITCL_ECLASS) {
2062 result = Tcl_EvalEx(interp, "::itcl::builtin::getEclassOptions", -1, 0);
2065 FOREACH_HASH_VALUE(ioptPtr, &contextIoPtr->objectOptions) {
2066 hPtr2 = Tcl_CreateHashEntry(&unique,
2067 (char *)ioptPtr->namePtr, &isNew);
2071 objPtr = Tcl_NewListObj(0, NULL);
2072 Tcl_ListObjAppendElement(interp, objPtr,
2073 Tcl_NewStringObj(Tcl_GetString(ioptPtr->namePtr), -1));
2074 Tcl_ListObjAppendElement(interp, objPtr,
2076 Tcl_GetString(ioptPtr->resourceNamePtr), -1));
2077 Tcl_ListObjAppendElement(interp, objPtr,
2078 Tcl_NewStringObj(Tcl_GetString(ioptPtr->classNamePtr), -1));
2079 if (ioptPtr->defaultValuePtr != NULL) {
2080 Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(
2081 Tcl_GetString(ioptPtr->defaultValuePtr), -1));
2083 Tcl_ListObjAppendElement(interp, objPtr,
2084 Tcl_NewStringObj("", -1));
2086 val = ItclGetInstanceVar(interp, "itcl_options",
2087 Tcl_GetString(ioptPtr->namePtr), contextIoPtr,
2090 val = "<undefined>";
2092 Tcl_ListObjAppendElement(interp, objPtr,
2093 Tcl_NewStringObj(val, -1));
2094 Tcl_ListObjAppendElement(interp, listPtr, objPtr);
2096 /* now check for delegated options */
2097 FOREACH_HASH_VALUE(idoPtr, &contextIoPtr->objectDelegatedOptions) {
2099 if (idoPtr->icPtr != NULL) {
2100 icPtr = idoPtr->icPtr;
2101 val = ItclGetInstanceVar(interp, Tcl_GetString(icPtr->namePtr),
2102 NULL, contextIoPtr, icPtr->ivPtr->iclsPtr);
2103 if ((val != NULL) && (strlen(val) != 0)) {
2105 objPtr = Tcl_NewStringObj(val, -1);
2106 Tcl_IncrRefCount(objPtr);
2107 Tcl_AppendToObj(objPtr, " configure ", -1);
2109 if (strcmp(Tcl_GetString(idoPtr->namePtr), "*") != 0) {
2110 Tcl_AppendToObj(objPtr, " ", -1);
2111 if (idoPtr->asPtr != NULL) {
2112 Tcl_AppendToObj(objPtr, Tcl_GetString(
2113 idoPtr->asPtr), -1);
2115 Tcl_AppendToObj(objPtr, Tcl_GetString(
2116 idoPtr->namePtr), -1);
2120 result = Tcl_EvalObjEx(interp, objPtr, 0);
2121 Tcl_DecrRefCount(objPtr);
2122 if (result != TCL_OK) {
2125 listPtr2 = Tcl_GetObjResult(interp);
2128 lObjvOne[0] = listPtr2;
2129 lObjv = &lObjvOne[0];
2131 Tcl_ListObjGetElements(interp, listPtr2,
2134 for (i = 0; i < lObjc; i++) {
2136 Tcl_ListObjGetElements(interp, objPtr,
2138 optNamePtr = idoPtr->namePtr;
2142 hPtr = Tcl_FindHashEntry(&idoPtr->exceptions,
2145 /* avoid wrong name where asPtr != NULL */
2146 optNamePtr = idoPtr->namePtr;
2148 optNamePtr = lObjv2[0];
2151 if ((hPtr == NULL) && (lObjc2 > 0)) {
2152 if (icPtr->haveKeptOptions) {
2153 hPtr = Tcl_FindHashEntry(&icPtr->keptOptions,
2154 (char *)optNamePtr);
2156 if (idoPtr->asPtr != NULL) {
2157 if (strcmp(Tcl_GetString(idoPtr->asPtr),
2158 Tcl_GetString(lObjv2[0])) == 0) {
2159 hPtr = Tcl_FindHashEntry(
2160 &icPtr->keptOptions,
2161 (char *)optNamePtr);
2163 /* not in kept list, so ignore */
2166 objPtr = makeAsOptionInfo(interp,
2167 optNamePtr, idoPtr, lObjc2,
2173 hPtr2 = Tcl_CreateHashEntry(&unique,
2174 (char *)optNamePtr, &isNew);
2178 /* add the option */
2179 if (idoPtr->asPtr != NULL) {
2180 objPtr = makeAsOptionInfo(interp,
2181 optNamePtr, idoPtr, lObjc2,
2184 Tcl_ListObjAppendElement(interp, listPtr,
2188 Tcl_ListObjGetElements(interp, lObjv2[i],
2190 hPtr2 = Tcl_CreateHashEntry(&unique,
2191 (char *)lObjv3[0], &isNew);
2195 /* add the option */
2196 if (idoPtr->asPtr != NULL) {
2197 objPtr = makeAsOptionInfo(interp,
2198 optNamePtr, idoPtr, lObjc2,
2201 Tcl_ListObjAppendElement(interp, listPtr,
2209 Tcl_SetObjResult(interp, listPtr);
2210 Tcl_DeleteHashTable(&unique);
2214 /* first handle delegated options */
2215 hPtr = Tcl_FindHashEntry(&contextIoPtr->objectDelegatedOptions, (char *)
2219 objPtr = Tcl_NewStringObj("*",1);
2220 Tcl_IncrRefCount(objPtr);
2221 /* check if all options are delegated */
2222 hPtr = Tcl_FindHashEntry(&contextIoPtr->objectDelegatedOptions,
2224 Tcl_DecrRefCount(objPtr);
2226 /* now check the exceptions */
2227 idoPtr = (ItclDelegatedOption *)Tcl_GetHashValue(hPtr);
2228 hPtr2 = Tcl_FindHashEntry(&idoPtr->exceptions, (char *)objv[1]);
2229 if (hPtr2 != NULL) {
2230 /* found in exceptions, so no delegation for this option */
2235 componentIcPtr = NULL;
2236 /* check if it is not a local option defined before delegate option "*"
2238 hPtr2 = Tcl_FindHashEntry(&contextIoPtr->objectOptions,
2241 idoPtr = (ItclDelegatedOption *)Tcl_GetHashValue(hPtr);
2242 icPtr = idoPtr->icPtr;
2243 if (icPtr != NULL) {
2244 if (icPtr->haveKeptOptions) {
2245 hPtr3 = Tcl_FindHashEntry(&icPtr->keptOptions, (char *)objv[1]);
2246 if (hPtr3 != NULL) {
2247 /* ignore if it is an object option only */
2252 Itcl_InitHierIter(&hier, contextIoPtr->iclsPtr);
2253 iclsPtr2 = Itcl_AdvanceHierIter(&hier);
2254 while (iclsPtr2 != NULL) {
2255 if (Tcl_FindHashEntry(&iclsPtr2->options,
2256 (char *)objv[1]) != NULL) {
2260 iclsPtr2 = Itcl_AdvanceHierIter(&hier);
2262 Itcl_DeleteHierIter(&hier);
2265 componentIcPtr = icPtr;
2271 if ((objc <= 3) && (hPtr != NULL) && (hPtr2 == NULL)) {
2272 /* the option is delegated */
2273 idoPtr = (ItclDelegatedOption *)Tcl_GetHashValue(hPtr);
2274 if (componentIcPtr != NULL) {
2275 icPtr = componentIcPtr;
2277 icPtr = idoPtr->icPtr;
2279 val = ItclGetInstanceVar(interp,
2280 Tcl_GetString(icPtr->namePtr),
2281 NULL, contextIoPtr, icPtr->ivPtr->iclsPtr);
2282 if ((val != NULL) && (strlen(val) > 0)) {
2283 if (idoPtr->asPtr != NULL) {
2284 icPtr->ivPtr->iclsPtr->infoPtr->currIdoPtr = idoPtr;
2286 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *)*(objc+2));
2287 newObjv[0] = Tcl_NewStringObj(val, -1);
2288 Tcl_IncrRefCount(newObjv[0]);
2289 newObjv[1] = Tcl_NewStringObj("configure", 9);
2290 Tcl_IncrRefCount(newObjv[1]);
2291 if (idoPtr->asPtr != NULL) {
2292 newObjv[2] = idoPtr->asPtr;
2294 newObjv[2] = objv[1];
2296 Tcl_IncrRefCount(newObjv[2]);
2297 for(i=2;i<objc;i++) {
2298 newObjv[i+1] = objv[i];
2300 objPtr = Tcl_NewStringObj(val, -1);
2301 Tcl_IncrRefCount(objPtr);
2302 oPtr = Tcl_GetObjectFromObj(interp, objPtr);
2304 ioPtr = (ItclObject *)Tcl_ObjectGetMetadata(oPtr,
2305 infoPtr->object_meta_type);
2306 infoPtr->currContextIclsPtr = ioPtr->iclsPtr;
2308 Tcl_DecrRefCount(objPtr);
2309 ItclShowArgs(1, "extended eval delegated option", objc + 1,
2311 result = Tcl_EvalObjv(interp, objc+1, newObjv, TCL_EVAL_DIRECT);
2312 Tcl_DecrRefCount(newObjv[2]);
2313 Tcl_DecrRefCount(newObjv[1]);
2314 Tcl_DecrRefCount(newObjv[0]);
2315 ckfree((char *)newObjv);
2316 icPtr->ivPtr->iclsPtr->infoPtr->currIdoPtr = NULL;
2318 infoPtr->currContextIclsPtr = NULL;
2322 Tcl_AppendResult(interp, "INTERNAL ERROR component \"",
2323 Tcl_GetString(icPtr->namePtr), "\" not found",
2324 " or not set in ItclExtendedConfigure delegated option",
2331 saveIdoPtr = infoPtr->currIdoPtr;
2332 /* now look if it is an option at all */
2333 if (hPtr2 == NULL) {
2334 hPtr2 = Tcl_FindHashEntry(&contextIclsPtr->options,
2336 if (hPtr2 == NULL) {
2337 hPtr2 = Tcl_FindHashEntry(&contextIoPtr->objectOptions,
2340 infoPtr->currIdoPtr = NULL;
2343 if (hPtr2 == NULL) {
2344 if (contextIclsPtr->flags & ITCL_ECLASS) {
2345 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc));
2346 newObjv[0] = Tcl_NewStringObj("::itcl::builtin::eclassConfigure", -1);
2347 Tcl_IncrRefCount(newObjv[0]);
2348 for (j = 1; j < objc; j++) {
2349 newObjv[j] = objv[j];
2350 Tcl_IncrRefCount(newObjv[j]);
2352 result = Tcl_EvalObjv(interp, objc, newObjv, TCL_EVAL_DIRECT);
2353 for (j = 0; j < objc; j++) {
2354 Tcl_DecrRefCount(newObjv[j]);
2356 ckfree((char *)newObjv);
2357 if (result == TCL_OK) {
2361 /* no option at all, let the normal configure do the job */
2362 infoPtr->currIdoPtr = saveIdoPtr;
2363 return TCL_CONTINUE;
2365 ioptPtr = (ItclOption *)Tcl_GetHashValue(hPtr2);
2366 resultPtr = ItclReportOption(interp, ioptPtr, contextIoPtr);
2367 infoPtr->currIdoPtr = saveIdoPtr;
2368 Tcl_SetObjResult(interp, resultPtr);
2372 /* set one or more options */
2373 for (i=1; i < objc; i+=2) {
2375 Tcl_AppendResult(interp, "need option value pair", NULL);
2379 hPtr = Tcl_FindHashEntry(&contextIoPtr->objectOptions,
2382 if (contextIclsPtr->flags & ITCL_ECLASS) {
2383 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc));
2384 newObjv[0] = Tcl_NewStringObj("::itcl::builtin::eclassConfigure", -1);
2385 Tcl_IncrRefCount(newObjv[0]);
2386 for (j = 1; j < objc; j++) {
2387 newObjv[j] = objv[j];
2388 Tcl_IncrRefCount(newObjv[j]);
2390 result = Tcl_EvalObjv(interp, objc, newObjv, TCL_EVAL_DIRECT);
2391 for (j = 0; j < objc; j++) {
2392 Tcl_DecrRefCount(newObjv[j]);
2394 ckfree((char *)newObjv);
2395 if (result == TCL_OK) {
2399 hPtr = Tcl_FindHashEntry(&contextIoPtr->objectDelegatedOptions,
2402 /* the option is delegated */
2403 idoPtr = (ItclDelegatedOption *)Tcl_GetHashValue(hPtr);
2404 icPtr = idoPtr->icPtr;
2405 val = ItclGetInstanceVar(interp,
2406 Tcl_GetString(icPtr->ivPtr->namePtr),
2407 NULL, contextIoPtr, icPtr->ivPtr->iclsPtr);
2408 if ((val != NULL) && (strlen(val) > 0)) {
2409 if (idoPtr->asPtr != NULL) {
2410 icPtr->ivPtr->iclsPtr->infoPtr->currIdoPtr = idoPtr;
2412 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *)*(objc+2));
2413 newObjv[0] = Tcl_NewStringObj(val, -1);
2414 Tcl_IncrRefCount(newObjv[0]);
2415 newObjv[1] = Tcl_NewStringObj("configure", 9);
2416 Tcl_IncrRefCount(newObjv[1]);
2417 if (idoPtr->asPtr != NULL) {
2418 newObjv[2] = idoPtr->asPtr;
2420 newObjv[2] = objv[i];
2422 Tcl_IncrRefCount(newObjv[2]);
2423 newObjv[3] = objv[i+1];
2424 objPtr = Tcl_NewStringObj(val, -1);
2425 Tcl_IncrRefCount(objPtr);
2426 oPtr = Tcl_GetObjectFromObj(interp, objPtr);
2428 ioPtr = (ItclObject *)Tcl_ObjectGetMetadata(oPtr,
2429 infoPtr->object_meta_type);
2430 infoPtr->currContextIclsPtr = ioPtr->iclsPtr;
2432 Tcl_DecrRefCount(objPtr);
2433 ItclShowArgs(1, "extended eval delegated option", 4,
2435 result = Tcl_EvalObjv(interp, 4, newObjv, TCL_EVAL_DIRECT);
2436 Tcl_DecrRefCount(newObjv[2]);
2437 Tcl_DecrRefCount(newObjv[1]);
2438 Tcl_DecrRefCount(newObjv[0]);
2439 ckfree((char *)newObjv);
2440 icPtr->ivPtr->iclsPtr->infoPtr->currIdoPtr = NULL;
2442 infoPtr->currContextIclsPtr = NULL;
2446 Tcl_AppendResult(interp, "INTERNAL ERROR component not ",
2447 "found or not set in ItclExtendedConfigure ",
2448 "delegated option", NULL);
2454 infoPtr->unparsedObjc += 2;
2455 if (infoPtr->unparsedObjv == NULL) {
2456 infoPtr->unparsedObjc++; /* keep the first slot for
2457 correct working !! */
2458 infoPtr->unparsedObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *)
2459 *(infoPtr->unparsedObjc));
2460 infoPtr->unparsedObjv[0] = objv[0];
2462 infoPtr->unparsedObjv = (Tcl_Obj **)ckrealloc(
2463 (char *)infoPtr->unparsedObjv, sizeof(Tcl_Obj *)
2464 *(infoPtr->unparsedObjc));
2466 infoPtr->unparsedObjv[infoPtr->unparsedObjc-2] = objv[i];
2467 Tcl_IncrRefCount(infoPtr->unparsedObjv[infoPtr->unparsedObjc-2]);
2468 infoPtr->unparsedObjv[infoPtr->unparsedObjc-1] = objv[i+1];
2469 Tcl_IncrRefCount(infoPtr->unparsedObjv[infoPtr->unparsedObjc-1]);
2470 /* check if normal public variable/common ? */
2471 /* FIXME !!! temporary */
2474 ioptPtr = (ItclOption *)Tcl_GetHashValue(hPtr);
2475 if (ioptPtr->flags & ITCL_OPTION_READONLY) {
2476 if (infoPtr->currIoPtr == NULL) {
2477 /* allow only setting during instance creation
2478 * infoPtr->currIoPtr != NULL during instance creation
2480 Tcl_AppendResult(interp, "option \"",
2481 Tcl_GetString(ioptPtr->namePtr),
2482 "\" can only be set at instance creation", NULL);
2486 if (ioptPtr->validateMethodPtr != NULL) {
2487 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * 3);
2488 newObjv[0] = ioptPtr->validateMethodPtr;
2489 newObjv[1] = objv[i];
2490 newObjv[2] = objv[i+1];
2491 infoPtr->inOptionHandling = 1;
2492 saveNsPtr = Tcl_GetCurrentNamespace(interp);
2493 Itcl_SetCallFrameNamespace(interp, contextIclsPtr->nsPtr);
2494 ItclShowArgs(1, "EVAL validatemethod", 3, newObjv);
2495 result = Tcl_EvalObjv(interp, 3, newObjv, TCL_EVAL_DIRECT);
2496 Itcl_SetCallFrameNamespace(interp, saveNsPtr);
2497 infoPtr->inOptionHandling = 0;
2498 ckfree((char *)newObjv);
2499 if (result != TCL_OK) {
2503 configureMethodPtr = NULL;
2505 if (ioptPtr->configureMethodPtr != NULL) {
2506 configureMethodPtr = ioptPtr->configureMethodPtr;
2507 Tcl_IncrRefCount(configureMethodPtr);
2508 evalNsPtr = ioptPtr->iclsPtr->nsPtr;
2510 if (ioptPtr->configureMethodVarPtr != NULL) {
2511 val = ItclGetInstanceVar(interp,
2512 Tcl_GetString(ioptPtr->configureMethodVarPtr), NULL,
2513 contextIoPtr, ioptPtr->iclsPtr);
2515 Tcl_AppendResult(interp, "configure cannot get value for",
2516 " configuremethodvar \"",
2517 Tcl_GetString(ioptPtr->configureMethodVarPtr),
2521 objPtr = Tcl_NewStringObj(val, -1);
2522 hPtr = Tcl_FindHashEntry(&contextIoPtr->iclsPtr->resolveCmds,
2524 Tcl_DecrRefCount(objPtr);
2526 ItclMemberFunc *imPtr;
2527 ItclCmdLookup *clookup;
2528 clookup = (ItclCmdLookup *)Tcl_GetHashValue(hPtr);
2529 imPtr = clookup->imPtr;
2530 evalNsPtr = imPtr->iclsPtr->nsPtr;
2532 Tcl_AppendResult(interp, "cannot find method \"",
2533 val, "\" found in configuremethodvar", NULL);
2536 configureMethodPtr = Tcl_NewStringObj(val, -1);
2537 Tcl_IncrRefCount(configureMethodPtr);
2539 if (configureMethodPtr != NULL) {
2540 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *)*3);
2541 newObjv[0] = configureMethodPtr;
2542 Tcl_IncrRefCount(newObjv[0]);
2543 newObjv[1] = objv[i];
2544 Tcl_IncrRefCount(newObjv[1]);
2545 newObjv[2] = objv[i+1];
2546 Tcl_IncrRefCount(newObjv[2]);
2547 saveNsPtr = Tcl_GetCurrentNamespace(interp);
2548 Itcl_SetCallFrameNamespace(interp, evalNsPtr);
2549 ItclShowArgs(1, "EVAL configuremethod", 3, newObjv);
2550 result = Tcl_EvalObjv(interp, 3, newObjv, TCL_EVAL_DIRECT);
2551 Tcl_DecrRefCount(newObjv[0]);
2552 Tcl_DecrRefCount(newObjv[1]);
2553 Tcl_DecrRefCount(newObjv[2]);
2554 ckfree((char *)newObjv);
2555 Itcl_SetCallFrameNamespace(interp, saveNsPtr);
2556 Tcl_DecrRefCount(configureMethodPtr);
2557 if (result != TCL_OK) {
2561 if (ItclSetInstanceVar(interp, "itcl_options",
2562 Tcl_GetString(objv[i]), Tcl_GetString(objv[i+1]),
2563 contextIoPtr, ioptPtr->iclsPtr) == NULL) {
2568 Tcl_ResetResult(interp);
2571 if (infoPtr->unparsedObjc > 0) {
2572 if (result == TCL_OK) {
2573 return TCL_CONTINUE;
2580 * ------------------------------------------------------------------------
2581 * ItclExtendedCget()
2583 * Invoked whenever the user issues the "cget" method for an object.
2584 * If the class is NOT ITCL_CLASS
2585 * Handles the following syntax:
2587 * <objName> cget -<option>
2589 * Allows access to public variables as if they were configuration
2590 * options. Mimics the behavior of the usual "cget" method for
2591 * Tk widgets. Returns the current value of the public variable
2592 * with name <option>.
2593 * ------------------------------------------------------------------------
2598 void *dummy, /* class definition */
2599 Tcl_Interp *interp, /* current interpreter */
2600 int objc, /* number of arguments */
2601 Tcl_Obj *const objv[]) /* argument objects */
2603 Tcl_HashEntry *hPtr;
2604 Tcl_HashEntry *hPtr2;
2605 Tcl_HashEntry *hPtr3;
2609 Tcl_Obj *methodNamePtr;
2611 ItclClass *contextIclsPtr;
2612 ItclObject *contextIoPtr;
2613 ItclDelegatedFunction *idmPtr;
2614 ItclDelegatedOption *idoPtr;
2615 ItclComponent *icPtr;
2616 ItclObjectInfo *infoPtr;
2617 ItclOption *ioptPtr;
2624 ItclShowArgs(1,"ItclExtendedCget", objc, objv);
2626 * Make sure that this command is being invoked in the proper
2629 contextIclsPtr = NULL;
2630 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
2633 if ((contextIoPtr == NULL) || objc != 2) {
2634 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
2635 "improper usage: should be \"object cget -option\"",
2641 * BE CAREFUL: work in the virtual scope!
2643 if (contextIoPtr != NULL) {
2644 contextIclsPtr = contextIoPtr->iclsPtr;
2646 infoPtr = contextIclsPtr->infoPtr;
2647 if (infoPtr->currContextIclsPtr != NULL) {
2648 contextIclsPtr = infoPtr->currContextIclsPtr;
2652 /* first check if method cget is delegated */
2653 methodNamePtr = Tcl_NewStringObj("*", -1);
2654 hPtr = Tcl_FindHashEntry(&contextIclsPtr->delegatedFunctions, (char *)
2657 idmPtr = (ItclDelegatedFunction *)Tcl_GetHashValue(hPtr);
2658 Tcl_SetStringObj(methodNamePtr, "cget", -1);
2659 hPtr = Tcl_FindHashEntry(&idmPtr->exceptions, (char *)methodNamePtr);
2661 icPtr = idmPtr->icPtr;
2662 val = ItclGetInstanceVar(interp, Tcl_GetString(icPtr->namePtr),
2663 NULL, contextIoPtr, contextIclsPtr);
2665 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *)*(objc+1));
2666 newObjv[0] = Tcl_NewStringObj(val, -1);
2667 Tcl_IncrRefCount(newObjv[0]);
2668 newObjv[1] = Tcl_NewStringObj("cget", 4);
2669 Tcl_IncrRefCount(newObjv[1]);
2670 for(i=1;i<objc;i++) {
2671 newObjv[i+1] = objv[i];
2673 objPtr = Tcl_NewStringObj(val, -1);
2674 Tcl_IncrRefCount(objPtr);
2675 oPtr = Tcl_GetObjectFromObj(interp, objPtr);
2677 ioPtr = (ItclObject *)Tcl_ObjectGetMetadata(oPtr,
2678 infoPtr->object_meta_type);
2679 infoPtr->currContextIclsPtr = ioPtr->iclsPtr;
2681 ItclShowArgs(1, "DELEGATED EVAL", objc+1, newObjv);
2682 result = Tcl_EvalObjv(interp, objc+1, newObjv, TCL_EVAL_DIRECT);
2683 Tcl_DecrRefCount(newObjv[0]);
2684 Tcl_DecrRefCount(newObjv[1]);
2685 Tcl_DecrRefCount(objPtr);
2687 infoPtr->currContextIclsPtr = NULL;
2689 Tcl_DecrRefCount(methodNamePtr);
2694 Tcl_DecrRefCount(methodNamePtr);
2696 Tcl_WrongNumArgs(interp, 1, objv, "option");
2699 /* now do the hard work */
2700 /* first handle delegated options */
2701 hPtr = Tcl_FindHashEntry(&contextIoPtr->objectDelegatedOptions, (char *)
2703 hPtr3 = Tcl_FindHashEntry(&contextIoPtr->objectOptions, (char *)
2707 objPtr2 = Tcl_NewStringObj("*", -1);
2708 /* check for "*" option delegated */
2709 hPtr = Tcl_FindHashEntry(&contextIoPtr->objectDelegatedOptions, (char *)
2711 Tcl_DecrRefCount(objPtr2);
2712 hPtr2 = Tcl_FindHashEntry(&contextIoPtr->objectOptions, (char *)
2715 if ((hPtr != NULL) && (hPtr2 == NULL) && (hPtr3 == NULL)) {
2716 /* the option is delegated */
2717 idoPtr = (ItclDelegatedOption *)Tcl_GetHashValue(hPtr);
2718 /* if the option is in the exceptions, do nothing */
2719 hPtr = Tcl_FindHashEntry(&idoPtr->exceptions, (char *)
2722 return TCL_CONTINUE;
2724 icPtr = idoPtr->icPtr;
2725 if (icPtr->ivPtr->flags & ITCL_COMMON) {
2726 val = ItclGetInstanceVar(interp, Tcl_GetString(icPtr->namePtr),
2727 NULL, contextIoPtr, icPtr->ivPtr->iclsPtr);
2729 val = ItclGetInstanceVar(interp, Tcl_GetString(icPtr->namePtr),
2730 NULL, contextIoPtr, icPtr->ivPtr->iclsPtr);
2732 if ((val != NULL) && (strlen(val) > 0)) {
2733 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *)*(objc+1));
2734 newObjv[0] = Tcl_NewStringObj(val, -1);
2735 Tcl_IncrRefCount(newObjv[0]);
2736 newObjv[1] = Tcl_NewStringObj("cget", 4);
2737 Tcl_IncrRefCount(newObjv[1]);
2738 for(i=1;i<objc;i++) {
2739 if (strcmp(Tcl_GetString(idoPtr->namePtr),
2740 Tcl_GetString(objv[i])) == 0) {
2741 if (idoPtr->asPtr != NULL) {
2742 newObjv[i+1] = idoPtr->asPtr;
2744 newObjv[i+1] = objv[i];
2747 newObjv[i+1] = objv[i];
2750 objPtr = Tcl_NewStringObj(val, -1);
2751 Tcl_IncrRefCount(objPtr);
2752 oPtr = Tcl_GetObjectFromObj(interp, objPtr);
2754 ioPtr = (ItclObject *)Tcl_ObjectGetMetadata(oPtr,
2755 infoPtr->object_meta_type);
2756 infoPtr->currContextIclsPtr = ioPtr->iclsPtr;
2758 ItclShowArgs(1, "ExtendedCget delegated option", objc+1, newObjv);
2759 result = Tcl_EvalObjv(interp, objc+1, newObjv, TCL_EVAL_DIRECT);
2760 Tcl_DecrRefCount(newObjv[0]);
2761 Tcl_DecrRefCount(newObjv[1]);
2762 Tcl_DecrRefCount(objPtr);
2764 infoPtr->currContextIclsPtr = NULL;
2766 ckfree((char *)newObjv);
2769 Tcl_ResetResult(interp);
2770 Tcl_AppendResult(interp, "component \"",
2771 Tcl_GetString(icPtr->namePtr),
2772 "\" is undefined, needed for option \"",
2773 Tcl_GetString(objv[1]),
2779 /* now look if it is an option at all */
2780 if ((hPtr2 == NULL) && (hPtr3 == NULL)) {
2781 /* no option at all, let the normal configure do the job */
2782 return TCL_CONTINUE;
2784 if (hPtr3 != NULL) {
2785 ioptPtr = (ItclOption *)Tcl_GetHashValue(hPtr3);
2787 ioptPtr = (ItclOption *)Tcl_GetHashValue(hPtr2);
2789 result = TCL_CONTINUE;
2790 if (ioptPtr->cgetMethodPtr != NULL) {
2791 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *)*2);
2792 newObjv[0] = ioptPtr->cgetMethodPtr;
2793 Tcl_IncrRefCount(newObjv[0]);
2794 newObjv[1] = objv[1];
2795 Tcl_IncrRefCount(newObjv[1]);
2796 ItclShowArgs(1, "eval cget method", objc, newObjv);
2797 result = Tcl_EvalObjv(interp, objc, newObjv, TCL_EVAL_DIRECT);
2798 Tcl_DecrRefCount(newObjv[1]);
2799 Tcl_DecrRefCount(newObjv[0]);
2800 ckfree((char *)newObjv);
2802 val = ItclGetInstanceVar(interp, "itcl_options",
2803 Tcl_GetString(ioptPtr->namePtr),
2804 contextIoPtr, ioptPtr->iclsPtr);
2806 Tcl_SetObjResult(interp, Tcl_NewStringObj(val, -1));
2808 Tcl_SetObjResult(interp, Tcl_NewStringObj("<undefined>", -1));
2816 * ------------------------------------------------------------------------
2817 * ItclExtendedSetGet()
2819 * Invoked whenever the user writes to a methodvariable or calls the method
2820 * with the same name as the variable.
2821 * only for not ITCL_CLASS classes
2822 * Handles the following syntax:
2824 * <objName> setget varName ?<value>?
2826 * Allows access to methodvariables as if they hat a setter and getter
2828 * With no arguments, this command returns the current
2829 * value of the variable. If <value> is specified,
2830 * this sets the variable to the value calling a callback if exists:
2832 * ------------------------------------------------------------------------
2837 void *dummy, /* class definition */
2838 Tcl_Interp *interp, /* current interpreter */
2839 int objc, /* number of arguments */
2840 Tcl_Obj *const objv[]) /* argument objects */
2842 ItclClass *contextIclsPtr;
2843 ItclObject *contextIoPtr;
2845 Tcl_HashEntry *hPtr;
2847 ItclMethodVariable *imvPtr;
2848 ItclObjectInfo *infoPtr;
2849 const char *usageStr;
2855 ItclShowArgs(1, "ItclExtendedSetGet", objc, objv);
2859 * Make sure that this command is being invoked in the proper
2862 contextIclsPtr = NULL;
2863 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
2867 usageStr = "improper usage: should be \"object setget varName ?value?\"";
2868 if (contextIoPtr == NULL) {
2869 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
2875 * BE CAREFUL: work in the virtual scope!
2877 if (contextIoPtr != NULL) {
2878 contextIclsPtr = contextIoPtr->iclsPtr;
2880 infoPtr = contextIclsPtr->infoPtr;
2881 if (infoPtr->currContextIclsPtr != NULL) {
2882 contextIclsPtr = infoPtr->currContextIclsPtr;
2887 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
2891 /* look if it is an methodvariable at all */
2892 hPtr = Tcl_FindHashEntry(&contextIoPtr->objectMethodVariables,
2895 Tcl_AppendResult(interp, "no such methodvariable \"",
2896 Tcl_GetString(objv[1]), "\"", NULL);
2899 imvPtr = (ItclMethodVariable *)Tcl_GetHashValue(hPtr);
2901 val = ItclGetInstanceVar(interp, Tcl_GetString(objv[1]), NULL,
2902 contextIoPtr, imvPtr->iclsPtr);
2906 Tcl_SetObjResult(interp, Tcl_NewStringObj(val, -1));
2910 imvPtr = (ItclMethodVariable *)Tcl_GetHashValue(hPtr);
2913 if (imvPtr->callbackPtr != NULL) {
2914 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *)*3);
2915 newObjv[0] = imvPtr->callbackPtr;
2916 Tcl_IncrRefCount(newObjv[0]);
2917 newObjv[1] = objv[1];
2918 Tcl_IncrRefCount(newObjv[1]);
2919 newObjv[2] = objv[2];
2920 Tcl_IncrRefCount(newObjv[2]);
2921 result = Tcl_EvalObjv(interp, 3, newObjv, TCL_EVAL_DIRECT);
2922 Tcl_DecrRefCount(newObjv[0]);
2923 Tcl_DecrRefCount(newObjv[1]);
2924 Tcl_DecrRefCount(newObjv[2]);
2925 ckfree((char *)newObjv);
2927 if (result == TCL_OK) {
2928 Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &setValue);
2929 /* if setValue != 0 set the new value of the variable here */
2931 if (ItclSetInstanceVar(interp, Tcl_GetString(objv[1]), NULL,
2932 Tcl_GetString(objv[2]), contextIoPtr,
2933 imvPtr->iclsPtr) == NULL) {
2941 * ------------------------------------------------------------------------
2942 * Itcl_BiInstallComponentCmd()
2944 * Invoked whenever the user issues the "installcomponent" method for an
2946 * Handles the following syntax:
2948 * installcomponent <componentName> using <widgetClassName> <widgetPathName>
2949 * ?-option value -option value ...?
2951 * ------------------------------------------------------------------------
2955 Itcl_BiInstallComponentCmd(
2956 void *dummy, /* class definition */
2957 Tcl_Interp *interp, /* current interpreter */
2958 int objc, /* number of arguments */
2959 Tcl_Obj *const objv[]) /* argument objects */
2963 ItclClass *contextIclsPtr;
2964 ItclObject *contextIoPtr;
2965 ItclDelegatedOption *idoPtr;
2966 const char *usageStr;
2967 const char *componentName;
2968 const char *componentValue;
2974 ItclShowArgs(1, "Itcl_BiInstallComponentCmd", objc, objv);
2976 * Make sure that this command is being invoked in the proper
2979 contextIclsPtr = NULL;
2980 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
2984 if (contextIoPtr == NULL) {
2985 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
2986 "improper usage: should be \"object installcomponent \"",
2991 /* FIXME strip off the :: parts here properly*/
2992 token = Tcl_GetString(objv[0])+2;
2993 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
2994 "wrong # args: should be \"", token, " <componentName> using",
2995 " <widgetClassName> <widgetPathName>",
2996 " ?-option value -option value ...?\"",
3001 /* get component name and check, if it exists */
3002 token = Tcl_GetString(objv[1]);
3003 if (contextIclsPtr == NULL) {
3004 Tcl_AppendResult(interp, "cannot find context class for object \"",
3005 Tcl_GetCommandName(interp, contextIoPtr->accessCmd), "\"",
3009 if (!(contextIclsPtr->flags & (ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR))) {
3010 Tcl_AppendResult(interp, "no such method \"installcomponent\"", NULL);
3013 hPtr = Tcl_FindHashEntry(&contextIclsPtr->components, (char *)objv[1]);
3016 FOREACH_HASH_VALUE(idoPtr, &contextIoPtr->objectDelegatedOptions) {
3017 if (idoPtr == NULL) {
3018 /* FIXME need code here !! */
3023 /* there are no delegated options, so no problem that the
3024 * component does not exist. We have nothing to do */
3027 Tcl_AppendResult(interp, "class \"",
3028 Tcl_GetString(contextIclsPtr->namePtr),
3029 "\" has no component \"",
3030 Tcl_GetString(objv[1]), "\"", NULL);
3033 if (contextIclsPtr->flags & ITCL_TYPE) {
3035 usageStr = "usage: installcomponent <componentName> using <widgetType> <widgetPath> ?-option value ...?";
3037 Tcl_AppendResult(interp, usageStr, NULL);
3040 if (strcmp(Tcl_GetString(objv[2]), "using") != 0) {
3041 Tcl_AppendResult(interp, usageStr, NULL);
3044 componentName = Tcl_GetString(objv[1]);
3045 /* as it is no widget, we don't need to check for delegated option */
3046 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc - 3));
3047 memcpy(newObjv, objv + 3, sizeof(Tcl_Obj *) * ((objc - 3)));
3048 ItclShowArgs(1, "BiInstallComponent", objc - 3, newObjv);
3049 result = Tcl_EvalObjv(interp, objc - 3, newObjv, 0);
3050 ckfree((char *)newObjv);
3051 if (result != TCL_OK) {
3054 componentValue = Tcl_GetString(Tcl_GetObjResult(interp));
3055 objPtr = Tcl_NewStringObj(ITCL_VARIABLES_NAMESPACE, -1);
3056 Tcl_AppendToObj(objPtr,
3057 (Tcl_GetObjectNamespace(contextIclsPtr->oPtr))->fullName, -1);
3058 Tcl_AppendToObj(objPtr, "::", -1);
3059 Tcl_AppendToObj(objPtr, componentName, -1);
3061 Tcl_SetVar2(interp, Tcl_GetString(objPtr), NULL, componentValue, 0);
3062 Tcl_DecrRefCount(objPtr);
3065 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 1));
3066 newObjv[0] = Tcl_NewStringObj("::itcl::builtin::installcomponent", -1);
3067 Tcl_IncrRefCount(newObjv[0]);
3068 memcpy(newObjv, objv + 1, sizeof(Tcl_Obj *) * ((objc - 1)));
3069 result = Tcl_EvalObjv(interp, objc, newObjv, 0);
3070 Tcl_DecrRefCount(newObjv[0]);
3071 ckfree((char *)newObjv);
3077 * ------------------------------------------------------------------------
3078 * Itcl_BiDestroyCmd()
3080 * Invoked whenever the user issues the "destroy" method for an
3082 * Handles the following syntax:
3086 * ------------------------------------------------------------------------
3091 void *dummy, /* class definition */
3092 Tcl_Interp *interp, /* current interpreter */
3093 int objc, /* number of arguments */
3094 Tcl_Obj *const objv[]) /* argument objects */
3097 ItclClass *contextIclsPtr;
3098 ItclObject *contextIoPtr;
3103 * Make sure that this command is being invoked in the proper
3106 ItclShowArgs(1, "Itcl_BiDestroyCmd", objc, objv);
3107 contextIoPtr = NULL;
3108 contextIclsPtr = NULL;
3109 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
3113 if (contextIclsPtr == NULL) {
3114 Tcl_AppendResult(interp, "cannot find context class for object \"",
3115 Tcl_GetCommandName(interp, contextIoPtr->accessCmd), "\"",
3119 if ((objc > 1) || !(contextIclsPtr->flags &
3120 (ITCL_ECLASS|ITCL_TYPE|ITCL_WIDGET|ITCL_WIDGETADAPTOR))) {
3121 /* try to execute destroy in uplevel namespace */
3122 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + 2));
3123 newObjv[0] = Tcl_NewStringObj("uplevel", -1);
3124 Tcl_IncrRefCount(newObjv[0]);
3125 newObjv[1] = Tcl_NewStringObj("#0", -1);
3126 Tcl_IncrRefCount(newObjv[1]);
3127 newObjv[2] = Tcl_NewStringObj("destroy", -1);
3128 Tcl_IncrRefCount(newObjv[2]);
3129 memcpy(newObjv + 3, objv + 1, sizeof(Tcl_Obj *) * (objc - 1));
3130 ItclShowArgs(1, "DESTROY", objc + 2, newObjv);
3131 result = Tcl_EvalObjv(interp, objc + 2, newObjv, 0);
3132 Tcl_DecrRefCount(newObjv[2]);
3133 Tcl_DecrRefCount(newObjv[1]);
3134 Tcl_DecrRefCount(newObjv[0]);
3138 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
3139 "wrong # args: should be \"", Tcl_GetString(objv[0]), NULL);
3143 if (contextIoPtr != NULL) {
3144 Tcl_Obj *objPtr = Tcl_NewObj();
3145 Tcl_GetCommandFullName(interp, contextIoPtr->accessCmd, objPtr);
3146 Itcl_RenameCommand(interp, Tcl_GetString(objPtr), "");
3147 Tcl_DecrRefCount(objPtr);
3150 result = Itcl_DeleteClass(interp, contextIclsPtr);
3155 * ------------------------------------------------------------------------
3156 * Itcl_BiCallInstanceCmd()
3158 * Invoked whenever the a script generated by mytypemethod, mymethod or
3159 * myproc is evauated later on:
3160 * Handles the following syntax:
3162 * callinstance <instanceName> ?arg arg ...?
3164 * ------------------------------------------------------------------------
3168 Itcl_BiCallInstanceCmd(
3169 void *dummy, /* class definition */
3170 Tcl_Interp *interp, /* current interpreter */
3171 int objc, /* number of arguments */
3172 Tcl_Obj *const objv[]) /* argument objects */
3174 Tcl_HashEntry *hPtr;
3177 ItclClass *contextIclsPtr;
3178 ItclObject *contextIoPtr;
3185 * Make sure that this command is being invoked in the proper
3188 ItclShowArgs(1, "Itcl_BiCallInstanceCmd", objc, objv);
3189 contextIclsPtr = NULL;
3190 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
3195 token = Tcl_GetString(objv[0]);
3196 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
3197 "wrong # args: should be \"", token, " <instanceName>",
3202 hPtr = Tcl_FindHashEntry(&contextIclsPtr->infoPtr->instances,
3203 Tcl_GetString(objv[1]));
3205 Tcl_AppendResult(interp,
3206 "no such instanceName \"",
3207 Tcl_GetString(objv[1]), "\"", NULL);
3210 ioPtr = (ItclObject *)Tcl_GetHashValue(hPtr);
3211 objPtr =Tcl_NewObj();
3212 Tcl_GetCommandFullName(interp, ioPtr->accessCmd, objPtr);
3213 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj*) * (objc - 1));
3214 newObjv[0] = objPtr;
3215 Tcl_IncrRefCount(newObjv[0]);
3216 memcpy(newObjv + 1, objv + 2, sizeof(Tcl_Obj *) * (objc - 2));
3217 result = Tcl_EvalObjv(interp, objc - 1, newObjv, 0);
3218 Tcl_DecrRefCount(newObjv[0]);
3219 ckfree((char *)newObjv);
3223 * ------------------------------------------------------------------------
3224 * Itcl_BiGetInstanceVarCmd()
3226 * Invoked whenever the a script generated by mytypevar, myvar or
3227 * mycommon is evauated later on:
3228 * Handles the following syntax:
3230 * getinstancevar <instanceName> ?arg arg ...?
3232 * ------------------------------------------------------------------------
3236 Itcl_BiGetInstanceVarCmd(
3237 void *dummy, /* class definition */
3238 Tcl_Interp *interp, /* current interpreter */
3239 int objc, /* number of arguments */
3240 Tcl_Obj *const objv[]) /* argument objects */
3242 Tcl_HashEntry *hPtr;
3245 ItclClass *contextIclsPtr;
3246 ItclObject *contextIoPtr;
3253 * Make sure that this command is being invoked in the proper
3256 ItclShowArgs(1, "Itcl_BiGetInstanceVarCmd", objc, objv);
3257 contextIclsPtr = NULL;
3258 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
3263 token = Tcl_GetString(objv[0]);
3264 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
3265 "wrong # args: should be \"", token, " <instanceName>",
3270 hPtr = Tcl_FindHashEntry(&contextIclsPtr->infoPtr->instances,
3271 Tcl_GetString(objv[1]));
3273 Tcl_AppendResult(interp,
3274 "no such instanceName \"",
3275 Tcl_GetString(objv[1]), "\"", NULL);
3278 ioPtr = (ItclObject *)Tcl_GetHashValue(hPtr);
3279 objPtr = Tcl_NewObj();
3280 Tcl_GetCommandFullName(interp, ioPtr->accessCmd, objPtr);
3281 newObjv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj*) * (objc - 1));
3282 newObjv[0] = objPtr;
3283 Tcl_IncrRefCount(newObjv[0]);
3284 memcpy(newObjv + 1, objv + 2, sizeof(Tcl_Obj *) * (objc - 2));
3285 result = Tcl_EvalObjv(interp, objc - 1, newObjv, 0);
3286 Tcl_DecrRefCount(newObjv[0]);
3290 * ------------------------------------------------------------------------
3291 * Itcl_BiMyTypeMethodCmd()
3293 * Invoked when a user calls mytypemethod
3295 * Handles the following syntax:
3297 * mytypemethod ?arg arg ...?
3299 * ------------------------------------------------------------------------
3303 Itcl_BiMyTypeMethodCmd(
3304 void *dummy, /* class definition */
3305 Tcl_Interp *interp, /* current interpreter */
3306 int objc, /* number of arguments */
3307 Tcl_Obj *const objv[]) /* argument objects */
3311 ItclClass *contextIclsPtr;
3312 ItclObject *contextIoPtr;
3317 * Make sure that this command is being invoked in the proper
3320 ItclShowArgs(1, "Itcl_BiMyTypeMethodCmd", objc, objv);
3321 contextIclsPtr = NULL;
3322 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
3326 Tcl_AppendResult(interp, "usage: mytypemethod <name>", NULL);
3329 objPtr = Tcl_NewStringObj(contextIclsPtr->nsPtr->fullName, -1);
3330 resultPtr = Tcl_NewListObj(0, NULL);
3331 Tcl_ListObjAppendElement(interp, resultPtr, objPtr);
3333 for (i = 1; i < objc; i++) {
3334 Tcl_ListObjAppendElement(interp, resultPtr, objv[i]);
3336 Tcl_SetObjResult(interp, resultPtr);
3341 * ------------------------------------------------------------------------
3342 * Itcl_BiMyMethodCmd()
3344 * Invoked when a user calls mymethod
3346 * Handles the following syntax:
3348 * mymethod ?arg arg ...?
3350 * ------------------------------------------------------------------------
3355 void *dummy, /* class definition */
3356 Tcl_Interp *interp, /* current interpreter */
3357 int objc, /* number of arguments */
3358 Tcl_Obj *const objv[]) /* argument objects */
3362 ItclClass *contextIclsPtr;
3363 ItclObject *contextIoPtr;
3367 * Make sure that this command is being invoked in the proper
3370 ItclShowArgs(1, "Itcl_BiMyMethodCmd", objc, objv);
3371 contextIclsPtr = NULL;
3372 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
3375 if (contextIoPtr != NULL) {
3376 resultPtr = Tcl_NewListObj(0, NULL);
3377 Tcl_ListObjAppendElement(interp, resultPtr,
3378 Tcl_NewStringObj("::itcl::builtin::callinstance", -1));
3379 Tcl_ListObjAppendElement(interp, resultPtr, Tcl_NewStringObj(
3380 (Tcl_GetObjectNamespace(contextIoPtr->oPtr))->fullName, -1));
3381 for (i = 1; i < objc; i++) {
3382 Tcl_ListObjAppendElement(interp, resultPtr, objv[i]);
3384 Tcl_SetObjResult(interp, resultPtr);
3391 * ------------------------------------------------------------------------
3392 * Itcl_BiMyProcCmd()
3394 * Invoked when a user calls myproc
3396 * Handles the following syntax:
3398 * myproc ?arg arg ...?
3400 * ------------------------------------------------------------------------
3405 void *dummy, /* class definition */
3406 Tcl_Interp *interp, /* current interpreter */
3407 int objc, /* number of arguments */
3408 Tcl_Obj *const objv[]) /* argument objects */
3412 ItclClass *contextIclsPtr;
3413 ItclObject *contextIoPtr;
3418 * Make sure that this command is being invoked in the proper
3421 ItclShowArgs(1, "Itcl_BiMyProcCmd", objc, objv);
3422 contextIclsPtr = NULL;
3423 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
3427 Tcl_AppendResult(interp, "usage: myproc <name>", NULL);
3430 objPtr = Tcl_NewStringObj(contextIclsPtr->nsPtr->fullName, -1);
3431 Tcl_AppendToObj(objPtr, "::", -1);
3432 Tcl_AppendToObj(objPtr, Tcl_GetString(objv[1]), -1);
3433 resultPtr = Tcl_NewListObj(0, NULL);
3434 Tcl_ListObjAppendElement(interp, resultPtr, objPtr);
3436 for (i = 2; i < objc; i++) {
3437 Tcl_ListObjAppendElement(interp, resultPtr, objv[i]);
3439 Tcl_SetObjResult(interp, resultPtr);
3443 * ------------------------------------------------------------------------
3444 * Itcl_BiMyTypeVarCmd()
3446 * Invoked when a user calls mytypevar
3448 * Handles the following syntax:
3450 * mytypevar ?arg arg ...?
3452 * ------------------------------------------------------------------------
3456 Itcl_BiMyTypeVarCmd(
3457 void *dummy, /* class definition */
3458 Tcl_Interp *interp, /* current interpreter */
3459 int objc, /* number of arguments */
3460 Tcl_Obj *const objv[]) /* argument objects */
3464 ItclClass *contextIclsPtr;
3465 ItclObject *contextIoPtr;
3470 * Make sure that this command is being invoked in the proper
3473 ItclShowArgs(1, "Itcl_BiMyTypeVarCmd", objc, objv);
3474 contextIclsPtr = NULL;
3475 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
3479 Tcl_AppendResult(interp, "usage: mytypevar <name>", NULL);
3482 objPtr = Tcl_NewStringObj(contextIclsPtr->nsPtr->fullName, -1);
3483 Tcl_AppendToObj(objPtr, "::", -1);
3484 Tcl_AppendToObj(objPtr, Tcl_GetString(objv[1]), -1);
3485 resultPtr = Tcl_NewListObj(0, NULL);
3486 Tcl_ListObjAppendElement(interp, resultPtr, objPtr);
3488 for (i = 2; i < objc; i++) {
3489 Tcl_ListObjAppendElement(interp, resultPtr, objv[i]);
3491 Tcl_SetObjResult(interp, resultPtr);
3496 * ------------------------------------------------------------------------
3499 * Invoked when a user calls myvar
3501 * Handles the following syntax:
3503 * myvar ?arg arg ...?
3505 * ------------------------------------------------------------------------
3510 void *dummy, /* class definition */
3511 Tcl_Interp *interp, /* current interpreter */
3512 int objc, /* number of arguments */
3513 Tcl_Obj *const objv[]) /* argument objects */
3516 ItclClass *contextIclsPtr;
3517 ItclObject *contextIoPtr;
3521 * Make sure that this command is being invoked in the proper
3524 ItclShowArgs(1, "Itcl_BiMyVarCmd", objc, objv);
3525 contextIclsPtr = NULL;
3526 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
3529 if ((contextIoPtr != NULL) && (objc > 1)) {
3530 resultPtr = Tcl_NewStringObj(Tcl_GetString(contextIoPtr->varNsNamePtr),
3532 Tcl_AppendToObj(resultPtr, "::", -1);
3533 Tcl_AppendToObj(resultPtr, Tcl_GetString(contextIclsPtr->namePtr), -1);
3534 Tcl_AppendToObj(resultPtr, "::", -1);
3535 Tcl_AppendToObj(resultPtr, Tcl_GetString(objv[1]), -1);
3536 Tcl_SetObjResult(interp, resultPtr);
3541 * ------------------------------------------------------------------------
3542 * Itcl_BiItclHullCmd()
3544 * Invoked when a user calls itcl_hull
3546 * Handles the following syntax:
3548 * itcl_hull ?arg arg ...?
3550 * ------------------------------------------------------------------------
3555 void *dummy, /* class definition */
3556 Tcl_Interp *interp, /* current interpreter */
3557 int objc, /* number of arguments */
3558 Tcl_Obj *const objv[]) /* argument objects */
3560 ItclClass *contextIclsPtr;
3561 ItclObject *contextIoPtr;
3568 * Make sure that this command is being invoked in the proper
3571 ItclShowArgs(1, "Itcl_BiItclHullCmd", objc, objv);
3572 contextIclsPtr = NULL;
3573 if (Itcl_GetContext(interp, &contextIclsPtr, &contextIoPtr) != TCL_OK) {
3576 if (contextIoPtr != NULL) {
3577 val = ItclGetInstanceVar(interp, "itcl_hull", NULL,
3578 contextIoPtr, contextIclsPtr);
3579 Tcl_SetObjResult(interp, Tcl_NewStringObj(val, -1));
3585 * ------------------------------------------------------------------------
3586 * Itcl_BiCreateHullCmd()
3588 * Invoked by Tcl normally during evaluating constructor
3589 * the "createhull" command is invoked to install and setup an
3590 * ::itcl::extendedclass itcl_hull
3591 * for an object. Handles the following syntax:
3593 * createhull <widget_type> <widget_path> ?-class <widgetClassName>?
3594 * ?<optionName> <optionValue> <optionName> <optionValue> ...?
3596 * ------------------------------------------------------------------------
3599 Itcl_BiCreateHullCmd(
3600 void *clientData, /* info for all known objects */
3601 Tcl_Interp *interp, /* current interpreter */
3602 int objc, /* number of arguments */
3603 Tcl_Obj *const objv[]) /* argument objects */
3606 ItclObjectInfo *infoPtr = (ItclObjectInfo*)clientData;
3608 ItclShowArgs(1, "Itcl_BiCreateHullCmd", objc, objv);
3609 if (!infoPtr->itclHullCmdsInitted) {
3610 result = Tcl_EvalEx(interp, initHullCmdsScript, -1, 0);
3611 if (result != TCL_OK) {
3614 infoPtr->itclHullCmdsInitted = 1;
3616 return Tcl_EvalObjv(interp, objc, objv, 0);
3620 * ------------------------------------------------------------------------
3621 * Itcl_BiSetupComponentCmd()
3623 * Invoked by Tcl during evaluating constructor whenever
3624 * the "setupcomponent" command is invoked to install and setup an
3625 * ::itcl::extendedclass component
3626 * for an object. Handles the following syntax:
3628 * setupcomponent <componentName> using <widgetType> <widget_path>
3629 * ?<optionName> <optionValue> <optionName> <optionValue> ...?
3631 * ------------------------------------------------------------------------
3634 Itcl_BiSetupComponentCmd(
3635 void *clientData, /* info for all known objects */
3636 Tcl_Interp *interp, /* current interpreter */
3637 int objc, /* number of arguments */
3638 Tcl_Obj *const objv[]) /* argument objects */
3641 ItclObjectInfo *infoPtr = (ItclObjectInfo*)clientData;
3643 ItclShowArgs(1, "Itcl_BiSetupComponentCmd", objc, objv);
3644 if (!infoPtr->itclHullCmdsInitted) {
3645 result = Tcl_EvalEx(interp, initHullCmdsScript, -1, 0);
3646 if (result != TCL_OK) {
3649 infoPtr->itclHullCmdsInitted = 1;
3651 return Tcl_EvalObjv(interp, objc, objv, 0);
3655 * ------------------------------------------------------------------------
3656 * Itcl_BiInitOptionsCmd()
3658 * Invoked by Tcl during evaluating constructor whenever
3659 * the "itcl_initoptions" command is invoked to install and setup an
3660 * ::itcl::extendedclass options
3661 * for an object. Handles the following syntax:
3664 * ?<optionName> <optionValue> <optionName> <optionValue> ...?
3665 * FIXME !!!! seems no longer been used !!!
3667 * ------------------------------------------------------------------------
3670 Itcl_BiInitOptionsCmd(
3671 void *clientData, /* info for all known objects */
3672 Tcl_Interp *interp, /* current interpreter */
3673 int objc, /* number of arguments */
3674 Tcl_Obj *const objv[]) /* argument objects */
3677 ItclObjectInfo *infoPtr = (ItclObjectInfo*)clientData;
3680 ItclDelegatedOption *idoptPtr;
3681 ItclOption *ioptPtr;
3684 /* instead ::itcl::builtin::initoptions in ../library/itclHullCmds.tcl is used !! */
3685 ItclShowArgs(1, "Itcl_BiInitOptionsCmd", objc, objv);
3686 if (!infoPtr->itclHullCmdsInitted) {
3687 result = Tcl_EvalEx(interp, initHullCmdsScript, -1, 0);
3688 if (result != TCL_OK) {
3691 infoPtr->itclHullCmdsInitted = 1;
3693 result = Tcl_EvalObjv(interp, objc, objv, 0);
3695 if (Itcl_GetContext(interp, &iclsPtr, &ioPtr) != TCL_OK) {
3698 /* first handle delegated options */
3699 FOREACH_HASH_VALUE(idoptPtr, &ioPtr->objectDelegatedOptions) {
3700 fprintf(stderr, "delopt!%s!\n", Tcl_GetString(idoptPtr->namePtr));
3702 FOREACH_HASH_VALUE(ioptPtr, &ioPtr->objectOptions) {
3703 fprintf(stderr, "opt!%s!\n", Tcl_GetString(ioptPtr->namePtr));
3709 * ------------------------------------------------------------------------
3710 * Itcl_BiKeepComponentOptionCmd()
3712 * Invoked by Tcl during evaluating constructor whenever
3713 * the "keepcomponentoption" command is invoked to list the options
3714 * to be kept when and ::itcl::extendedclass component has been setup
3715 * for an object. Handles the following syntax:
3717 * keepcomponentoption <componentName> <optionName> ?<optionName> ...?
3719 * ------------------------------------------------------------------------
3722 Itcl_BiKeepComponentOptionCmd(
3723 void *clientData, /* info for all known objects */
3724 Tcl_Interp *interp, /* current interpreter */
3725 int objc, /* number of arguments */
3726 Tcl_Obj *const objv[]) /* argument objects */
3729 ItclObjectInfo *infoPtr = (ItclObjectInfo*)clientData;
3731 ItclShowArgs(1, "Itcl_BiKeepComponentOptionCmd", objc, objv);
3732 if (!infoPtr->itclHullCmdsInitted) {
3733 result = Tcl_EvalEx(interp, initHullCmdsScript, -1, 0);
3734 if (result != TCL_OK) {
3737 infoPtr->itclHullCmdsInitted = 1;
3739 result = Tcl_EvalObjv(interp, objc, objv, 0);
3744 * ------------------------------------------------------------------------
3745 * Itcl_BiIgnoreComponentOptionCmd()
3747 * Invoked by Tcl during evaluating constructor whenever
3748 * the "keepcomponentoption" command is invoked to list the options
3749 * to be kept when and ::itcl::extendedclass component has been setup
3750 * for an object. Handles the following syntax:
3752 * ignorecomponentoption <componentName> <optionName> ?<optionName> ...?
3754 * ------------------------------------------------------------------------
3757 Itcl_BiIgnoreComponentOptionCmd(
3758 void *clientData, /* info for all known objects */
3759 Tcl_Interp *interp, /* current interpreter */
3760 int objc, /* number of arguments */
3761 Tcl_Obj *const objv[]) /* argument objects */
3763 Tcl_HashEntry *hPtr;
3764 Tcl_HashEntry *hPtr2;
3768 ItclDelegatedOption *idoPtr;
3769 ItclComponent *icPtr;
3774 ItclObjectInfo *infoPtr = (ItclObjectInfo*)clientData;
3776 ItclShowArgs(0, "Itcl_BiIgnoreComponentOptionCmd", objc, objv);
3777 if (!infoPtr->itclHullCmdsInitted) {
3778 result = Tcl_Eval(interp, initHullCmdsScript);
3779 if (result != TCL_OK) {
3782 infoPtr->itclHullCmdsInitted = 1;
3785 if (Itcl_GetContext(interp, &iclsPtr, &ioPtr) != TCL_OK) {
3789 Tcl_AppendResult(interp, "wrong # args, should be: ",
3790 "ignorecomponentoption component option ?option ...?", NULL);
3793 if (ioPtr != NULL) {
3794 hPtr = Tcl_FindHashEntry(&ioPtr->objectComponents, (char *)objv[1]);
3796 Tcl_AppendResult(interp,
3797 "ignorecomponentoption cannot find component \"",
3798 Tcl_GetString(objv[1]), "\"", NULL);
3801 icPtr = (ItclComponent *)Tcl_GetHashValue(hPtr);
3802 icPtr->haveKeptOptions = 1;
3803 for (idx = 2; idx < objc; idx++) {
3804 hPtr = Tcl_CreateHashEntry(&icPtr->keptOptions, (char *)objv[idx],
3807 Tcl_SetHashValue(hPtr, objv[idx]);
3809 hPtr2 = Tcl_CreateHashEntry(&ioPtr->objectDelegatedOptions,
3810 (char *)objv[idx], &isNew);
3812 idoPtr = (ItclDelegatedOption *)ckalloc(sizeof(
3813 ItclDelegatedOption));
3814 memset(idoPtr, 0, sizeof(ItclDelegatedOption));
3815 Tcl_InitObjHashTable(&idoPtr->exceptions);
3816 idoPtr->namePtr = objv[idx];
3817 Tcl_IncrRefCount(idoPtr->namePtr);
3818 idoPtr->resourceNamePtr = NULL;
3819 if (idoPtr->resourceNamePtr != NULL) {
3820 Tcl_IncrRefCount(idoPtr->resourceNamePtr);
3822 idoPtr->classNamePtr = NULL;
3823 if (idoPtr->classNamePtr != NULL) {
3824 Tcl_IncrRefCount(idoPtr->classNamePtr);
3826 idoPtr->icPtr = icPtr;
3827 idoPtr->ioptPtr = NULL;
3828 Tcl_SetHashValue(hPtr2, idoPtr);
3829 val = ItclGetInstanceVar(interp, Tcl_GetString(icPtr->namePtr),
3830 NULL, ioPtr, iclsPtr);
3832 objPtr = Tcl_NewStringObj(val, -1);
3833 Tcl_AppendToObj(objPtr, " cget ", -1);
3834 Tcl_AppendToObj(objPtr, Tcl_GetString(objv[idx]), -1);
3835 Tcl_IncrRefCount(objPtr);
3836 result = Tcl_EvalObjEx(interp, objPtr, 0);
3837 Tcl_DecrRefCount(objPtr);
3838 if (result == TCL_OK) {
3839 ItclSetInstanceVar(interp, "itcl_options",
3840 Tcl_GetString(objv[idx]),
3841 Tcl_GetString(Tcl_GetObjResult(interp)), ioPtr, iclsPtr);
3846 ItclAddClassComponentDictInfo(interp, iclsPtr, icPtr);