Index: TODO =================================================================== diff -u -N -rd79efb10b92ad2045196990af50bc042e60b88f4 -r9cead8929011bb4dcc6c44630a91bc5d597520b2 --- TODO (.../TODO) (revision d79efb10b92ad2045196990af50bc042e60b88f4) +++ TODO (.../TODO) (revision 9cead8929011bb4dcc6c44630a91bc5d597520b2) @@ -4472,6 +4472,16 @@ /obj/ info object methods ... ?-type all|scripted|builtin|alias|forwarder|object|setter|nsfproc? ... /obj/ info lookup methods ... ?-type all|scripted|builtin|alias|forwarder|object|setter|nsfproc? ... +- removed some TODOs from tests/parameters.test + +- parameter dispositions: + We differentiate now between "initcmd" and "cmd": an "initcmd" is only + evaluated once, but one can provide configure values for this parameter + later. a "cmd" is executed on every evaluation, it is only possible + to pass cmds to it. The trailing argument of the configure parameters + (used e.g. for scripted object/class definitions) is now of type "cmd". + Implementation not yet complete (object cases are not correct). + ======================================================================== TODO: - valuechangedcmd implemented via initcmd does Index: generic/nsf.c =================================================================== diff -u -N -rd79efb10b92ad2045196990af50bc042e60b88f4 -r9cead8929011bb4dcc6c44630a91bc5d597520b2 --- generic/nsf.c (.../nsf.c) (revision d79efb10b92ad2045196990af50bc042e60b88f4) +++ generic/nsf.c (.../nsf.c) (revision 9cead8929011bb4dcc6c44630a91bc5d597520b2) @@ -9075,6 +9075,8 @@ } if ((paramPtr->flags & NSF_ARG_INITCMD)) { ParamDefsFormatOption(nameStringObj, "initcmd", &colonWritten, &first); + } else if ((paramPtr->flags & NSF_ARG_CMD)) { + ParamDefsFormatOption(nameStringObj, "cmd", &colonWritten, &first); } else if ((paramPtr->flags & NSF_ARG_ALIAS)) { ParamDefsFormatOption(nameStringObj, "alias", &colonWritten, &first); } else if ((paramPtr->flags & NSF_ARG_FORWARD)) { @@ -11930,23 +11932,38 @@ paramPtr->flags |= NSF_ARG_IS_CONVERTER; } else if (strncmp(option, "initcmd", 7) == 0) { + if (unlikely(paramPtr->flags & (NSF_ARG_CMD|NSF_ARG_ALIAS|NSF_ARG_FORWARD))) { + return NsfPrintError(interp, "parameter option 'initcmd' not valid in this option combination"); + } paramPtr->flags |= NSF_ARG_INITCMD; + } else if (strncmp(option, "cmd", 3) == 0) { + if (unlikely(paramPtr->flags & (NSF_ARG_INITCMD|NSF_ARG_ALIAS|NSF_ARG_FORWARD))) { + return NsfPrintError(interp, "parameter option 'cmd' not valid in this option combination"); + } + paramPtr->flags |= NSF_ARG_CMD; + } else if (strncmp(option, "alias", 5) == 0) { + if (unlikely(paramPtr->flags & (NSF_ARG_INITCMD|NSF_ARG_CMD|NSF_ARG_FORWARD))) { + return NsfPrintError(interp, "parameter option 'alias' not valid in this option combination"); + } paramPtr->flags |= NSF_ARG_ALIAS; } else if (strncmp(option, "forward", 7) == 0) { + if (unlikely(paramPtr->flags & (NSF_ARG_INITCMD|NSF_ARG_CMD|NSF_ARG_ALIAS))) { + return NsfPrintError(interp, "parameter option 'forward' not valid in this option combination"); + } paramPtr->flags |= NSF_ARG_FORWARD; } else if (strncmp(option, "slotassign", 10) == 0) { if (unlikely(paramPtr->slotObj == NULL)) { - return NsfPrintError(interp, "option 'slotassign' must follow 'slot='"); + return NsfPrintError(interp, "parameter option 'slotassign' must follow 'slot='"); } paramPtr->flags |= NSF_ARG_SLOTASSIGN; } else if (strncmp(option, "slotinitialize", 14) == 0) { if (unlikely(paramPtr->slotObj == NULL)) { - return NsfPrintError(interp, "option 'slotinit' must follow 'slot='"); + return NsfPrintError(interp, "parameter option 'slotinit' must follow 'slot='"); } paramPtr->flags |= NSF_ARG_SLOTINITIALIZE; @@ -11971,7 +11988,7 @@ } else if (strncmp(option, "noarg", 5) == 0) { if ((paramPtr->flags & NSF_ARG_ALIAS) == 0) { - return NsfPrintError(interp, "option \"noarg\" only allowed for parameter type \"alias\""); + return NsfPrintError(interp, "parameter option \"noarg\" only allowed for parameter type \"alias\""); } paramPtr->flags |= NSF_ARG_NOARG; paramPtr->nrArgs = 0; @@ -12158,13 +12175,7 @@ } if (unlikely((paramPtr->flags & NSF_ARG_METHOD_INVOCATION) && (paramPtr->flags & NSF_ARG_NOCONFIG))) { - return NsfPrintError(interp, "option 'noconfig' cannot used together with this type of object parameter"); - } else if (unlikely((paramPtr->flags & (NSF_ARG_ALIAS|NSF_ARG_FORWARD)) == (NSF_ARG_ALIAS|NSF_ARG_FORWARD))) { - return NsfPrintError(interp, "parameter types 'alias' and 'forward' cannot be used together"); - } else if (unlikely((paramPtr->flags & (NSF_ARG_ALIAS|NSF_ARG_INITCMD)) == (NSF_ARG_ALIAS|NSF_ARG_INITCMD))) { - return NsfPrintError(interp, "parameter types 'alias' and 'initcmd' cannot be used together"); - } else if (unlikely((paramPtr->flags & (NSF_ARG_FORWARD|NSF_ARG_INITCMD)) == (NSF_ARG_FORWARD|NSF_ARG_INITCMD))) { - return NsfPrintError(interp, "parameter types 'forward' and 'initcmd' cannot be used together"); + return NsfPrintError(interp, "parameter option 'noconfig' cannot used together with this type of object parameter"); } return result; @@ -12676,7 +12687,7 @@ NSF_CSC_TYPE_PLAIN, 0, NsfGlobalStrings[NSF_CONFIGURE]); Nsf_PushFrameCsc(interp, cscPtr, framePtr2); - if (paramPtr->flags & NSF_ARG_INITCMD) { + if (paramPtr->flags & (NSF_ARG_INITCMD|NSF_ARG_CMD)) { /* cscPtr->cmdPtr = NSFindCommand(interp, "::eval"); */ result = Tcl_EvalObjEx(interp, newValue, TCL_EVAL_DIRECT); @@ -15549,7 +15560,7 @@ */ object->flags &= ~NSF_INIT_CALLED; /* - * Make sure, the object survives initialization; the initcmd might + * Make sure, the object survives initialization; the cmd/initcmd might * destroy it. */ NsfObjectRefCountIncr(object); @@ -16844,7 +16855,7 @@ */ if ((unlikely((doCheckArguments & NSF_ARGPARSE_CHECK) == 0) && (pPtr->flags & (NSF_ARG_IS_CONVERTER)) == 0 - ) || (pPtr->flags & (NSF_ARG_INITCMD))) { + ) || (pPtr->flags & (NSF_ARG_INITCMD|NSF_ARG_CMD))) { /* fprintf(stderr, "*** omit argument check for arg %s flags %.6x\n", pPtr->name, pPtr->flags); */ *clientData = ObjStr(objPtr); return TCL_OK; @@ -22422,7 +22433,7 @@ /* * Special setter methods for invoking methods calls; handles types - * "initcmd", "alias" and "forward". + * "cmd", "initcmd", "alias" and "forward". */ if ((paramPtr->flags & NSF_ARG_METHOD_INVOCATION) //&& (paramPtr->flags & NSF_ARG_METHOD_CALL || object->flags & NSF_INIT_CALLED) @@ -22438,7 +22449,54 @@ /*fprintf(stderr, "%s consuming nrargs %d no value\n", paramPtr->name, paramPtr->nrArgs);*/ continue; } - // oooo; + + if ((paramPtr->flags & NSF_ARG_INITCMD)) { + // oooo; + + if (paramPtr->defaultValue) { + /* + * The "defaultValue" holds the initcmd to be executed + */ + Tcl_Obj *varObj = Tcl_ObjGetVar2(interp, NsfGlobalObjs[NSF_INITCMD], + paramPtr->nameObj, 0); + // TODO cleanup + /*fprintf(stderr, "INITCMD isdefault %d default %s value %p var %p\n", + (pc.flags[i-1] & NSF_PC_IS_DEFAULT), + paramPtr->defaultValue ? ObjStr(paramPtr->defaultValue) : "NONE", + ObjStr(newValue), + varObj + );*/ + if (varObj == NULL) { + /* + * The variable is not set. Therefore, we assume, we have to + * execute the initcmd. On success, we note the execution in the NSF_INITCMD + * variable (usually __initcmd(name)) + */ + result = ParameterMethodDispatch(interp, object, paramPtr, paramPtr->defaultValue, + uplevelVarFramePtr, initString, + objv[pc.lastObjc], (Tcl_Obj **)&objv[pc.lastObjc + 1], + objc - pc.lastObjc); + if (result != TCL_OK) { + Nsf_PopFrameObj(interp, framePtr); + goto configure_exit; + } + Tcl_ObjSetVar2(interp, NsfGlobalObjs[NSF_INITCMD], + paramPtr->nameObj, Tcl_NewIntObj(1), 0); + } + + } else { + //TODO should we require a default? + + } + /* + * if we have a new actual value, proceed to setvars + */ + if ((pc.flags[i-1] & NSF_PC_IS_DEFAULT) == 0) { + goto setvars; + } + continue; + } + result = ParameterMethodDispatch(interp, object, paramPtr, newValue, uplevelVarFramePtr, initString, objv[pc.lastObjc], (Tcl_Obj **)&objv[pc.lastObjc + 1], @@ -22450,6 +22508,7 @@ continue; } + setvars: if (newValue == NsfGlobalObjs[NSF___UNKNOWN__]) { /* * Nothing to do, we have a value setter, but no value is specified and Index: generic/nsfInt.h =================================================================== diff -u -N -r98b60429d7f10bf637fa2cfa2bb88d4069e2445f -r9cead8929011bb4dcc6c44630a91bc5d597520b2 --- generic/nsfInt.h (.../nsfInt.h) (revision 98b60429d7f10bf637fa2cfa2bb88d4069e2445f) +++ generic/nsfInt.h (.../nsfInt.h) (revision 9cead8929011bb4dcc6c44630a91bc5d597520b2) @@ -409,33 +409,34 @@ /* flags for NsfParams */ -#define NSF_ARG_REQUIRED 0x000001 -#define NSF_ARG_MULTIVALUED 0x000002 -#define NSF_ARG_NOARG 0x000004 -#define NSF_ARG_NOCONFIG 0x000008 -#define NSF_ARG_CURRENTLY_UNKNOWN 0x000010 -#define NSF_ARG_SUBST_DEFAULT 0x000020 -#define NSF_ARG_ALLOW_EMPTY 0x000040 -#define NSF_ARG_INITCMD 0x000080 -#define NSF_ARG_ALIAS 0x000100 -#define NSF_ARG_FORWARD 0x000200 -#define NSF_ARG_SWITCH 0x000400 -#define NSF_ARG_BASECLASS 0x000800 -#define NSF_ARG_METACLASS 0x001000 -#define NSF_ARG_HAS_DEFAULT 0x002000 -#define NSF_ARG_IS_CONVERTER 0x004000 -#define NSF_ARG_IS_ENUMERATION 0x008000 -#define NSF_ARG_CHECK_NONPOS 0x010000 -#define NSF_ARG_SET 0x020000 -#define NSF_ARG_WARN 0x040000 -#define NSF_ARG_UNNAMED 0x080000 -#define NSF_ARG_IS_RETURNVALUE 0x100000 -#define NSF_ARG_NOLEADINGDASH 0x200000 -#define NSF_ARG_SLOTASSIGN 0x400000 -#define NSF_ARG_SLOTINITIALIZE 0x800000 +#define NSF_ARG_REQUIRED 0x00000001 +#define NSF_ARG_MULTIVALUED 0x00000002 +#define NSF_ARG_NOARG 0x00000004 +#define NSF_ARG_NOCONFIG 0x00000008 +#define NSF_ARG_CURRENTLY_UNKNOWN 0x00000010 +#define NSF_ARG_SUBST_DEFAULT 0x00000020 +#define NSF_ARG_ALLOW_EMPTY 0x00000040 +#define NSF_ARG_INITCMD 0x00000080 +#define NSF_ARG_CMD 0x00000100 +#define NSF_ARG_ALIAS 0x00000200 +#define NSF_ARG_FORWARD 0x00000400 +#define NSF_ARG_SWITCH 0x00000800 +#define NSF_ARG_BASECLASS 0x00001000 +#define NSF_ARG_METACLASS 0x00002000 +#define NSF_ARG_HAS_DEFAULT 0x00004000 +#define NSF_ARG_IS_CONVERTER 0x00008000 +#define NSF_ARG_IS_ENUMERATION 0x00010000 +#define NSF_ARG_CHECK_NONPOS 0x00020000 +#define NSF_ARG_SET 0x00040000 +#define NSF_ARG_WARN 0x00080000 +#define NSF_ARG_UNNAMED 0x00100000 +#define NSF_ARG_IS_RETURNVALUE 0x00200000 +#define NSF_ARG_NOLEADINGDASH 0x00400000 +#define NSF_ARG_SLOTASSIGN 0x00800000 +#define NSF_ARG_SLOTINITIALIZE 0x01000000 /* method invocations */ -#define NSF_ARG_METHOD_INVOCATION (NSF_ARG_ALIAS|NSF_ARG_FORWARD|NSF_ARG_INITCMD) +#define NSF_ARG_METHOD_INVOCATION (NSF_ARG_ALIAS|NSF_ARG_FORWARD|NSF_ARG_INITCMD|NSF_ARG_CMD) #define NSF_ARG_METHOD_CALL (NSF_ARG_ALIAS|NSF_ARG_FORWARD) /* Disallowed parameter options */ @@ -626,7 +627,7 @@ /* methods called internally */ NSF_CONFIGURE, NSF_INITIALIZE, NSF_ASSIGN, NSF_GET_PARAMETER_SPEC, /* var names */ - NSF_AUTONAMES, NSF_DEFAULTMETACLASS, NSF_DEFAULTSUPERCLASS, + NSF_AUTONAMES, NSF_DEFAULTMETACLASS, NSF_DEFAULTSUPERCLASS, NSF_INITCMD, NSF_ALIAS_ARRAY, NSF_POSITION, NSF_POSITIONAL, NSF_CONFIG, NSF_PARAMETERSPEC, /* object/class names */ NSF_METHOD_PARAMETER_SLOT_OBJ, @@ -647,7 +648,7 @@ /* methods called internally */ "configure", "initialize", "assign", "getParameterSpec", /* var names */ - "__autonames", "__default_metaclass", "__default_superclass", + "__autonames", "__default_metaclass", "__default_superclass", "__initcmd", "::nsf::alias", "position", "positional", "config", "parameterSpec", /* object/class names */ "::nx::methodParameterSlot", Index: library/nx/nx.tcl =================================================================== diff -u -N -rd79efb10b92ad2045196990af50bc042e60b88f4 -r9cead8929011bb4dcc6c44630a91bc5d597520b2 --- library/nx/nx.tcl (.../nx.tcl) (revision d79efb10b92ad2045196990af50bc042e60b88f4) +++ library/nx/nx.tcl (.../nx.tcl) (revision 9cead8929011bb4dcc6c44630a91bc5d597520b2) @@ -983,7 +983,7 @@ lappend opts -methodname [string range $property 7 end] } elseif {$property eq "optional"} { lappend opts -required 0 - } elseif {$property in [list "alias" "forward" "initcmd"]} { + } elseif {$property in [list "alias" "forward" "cmd" "initcmd"]} { set class [:requireClass ::nx::ObjectParameterSlot $class] lappend opts -disposition $property set class [:requireClass ::nx::ObjectParameterSlot $class] @@ -1335,10 +1335,12 @@ if {[info exists :initcmd]} { lappend options initcmd if {[info exists :default]} { - append initcmd "::nsf::var::set \[::nsf::self\] ${:name} [list ${:default}]\n" + append initcmd "\n::nsf::var::set \[::nsf::self\] ${:name} [list ${:default}]\n" + #puts stderr ================append-default-to-initcmd-old=<${:initcmd}> } append initcmd ${:initcmd} set :parameterSpec [list [:namedParameterSpec $prefix ${:name} $options] $initcmd] + #puts stderr ================${:parameterSpec} } elseif {[info exists :default]} { # deactivated for now: || [string first {$} ${:default}] > -1 @@ -1570,7 +1572,7 @@ # Define the initcmd as a positional ObjectParameterSlot # ::nx::ObjectParameterSlot create ::nx::Object::slot::__initcmd \ - -disposition initcmd \ + -disposition cmd \ -noleadingdash true \ -positional true \ -position 2 @@ -1663,6 +1665,7 @@ substdefault noconfig initcmd + cmd required } |]] @@ -1689,8 +1692,8 @@ if {[info exists :type]} { set type ${:type} if {$type eq "switch" && !$forObjectParameter} {set type boolean} - if {$type eq "initcmd"} { - lappend options initcmd + if {$type in {cmd initcmd}} { + lappend options $type } elseif {[string match ::* $type]} { lappend options [expr {[::nsf::is metaclass $type] ? "class" : "object"}] type=$type } else { Index: library/xotcl/tests/slottest.xotcl =================================================================== diff -u -N -rf858f142f5fab4f88996b3eb709c3afa55114be9 -r9cead8929011bb4dcc6c44630a91bc5d597520b2 --- library/xotcl/tests/slottest.xotcl (.../slottest.xotcl) (revision f858f142f5fab4f88996b3eb709c3afa55114be9) +++ library/xotcl/tests/slottest.xotcl (.../slottest.xotcl) (revision 9cead8929011bb4dcc6c44630a91bc5d597520b2) @@ -481,9 +481,9 @@ Attribute create x -defaultcmd {incr ::hu; set x 101} } C c1 -? {c1 info vars} "" +? {c1 info vars} "__initcmd" ? {c1 set x} 101 -? {c1 info vars} "x" +? {c1 info vars} "x __initcmd" ? {set ::hu 1} 1 ####################################################### Index: tests/disposition.test =================================================================== diff -u -N -r35c0d6ecb3c83cc6d6b0dfe251ba1a0d9071dc30 -r9cead8929011bb4dcc6c44630a91bc5d597520b2 --- tests/disposition.test (.../disposition.test) (revision 35c0d6ecb3c83cc6d6b0dfe251ba1a0d9071dc30) +++ tests/disposition.test (.../disposition.test) (revision 9cead8929011bb4dcc6c44630a91bc5d597520b2) @@ -306,16 +306,16 @@ ? {C new} "parameter option 'method=' only allowed for parameter types 'alias' and 'forward'" C setObjectParams [list [list -foo:alias,forward]] - ? {C new} "parameter types 'alias' and 'forward' cannot be used together" + ? {C new} "parameter option 'forward' not valid in this option combination" C setObjectParams [list [list -foo:forward,alias]] - ? {C new} "parameter types 'alias' and 'forward' cannot be used together" + ? {C new} "parameter option 'alias' not valid in this option combination" C setObjectParams [list [list -foo:alias,initcmd]] - ? {C new} "parameter types 'alias' and 'initcmd' cannot be used together" + ? {C new} "parameter option 'initcmd' not valid in this option combination" C setObjectParams [list [list -foo:forward,initcmd]] - ? {C new} "parameter types 'forward' and 'initcmd' cannot be used together" + ? {C new} "parameter option 'initcmd' not valid in this option combination" } nx::Test case dispo-multiplicities { @@ -654,7 +654,7 @@ # # initcmd with default # - C setObjectParams {{__init:initcmd :foo}} + C setObjectParams {{__init:cmd :foo}} C create c1 ? {c1 eval {info exists :foo}} 1 @@ -670,14 +670,14 @@ # # optional initcmd, like in nx # - C setObjectParams {initcmd:initcmd,optional} + C setObjectParams {initcmd:cmd,optional} C create c1 {set :x 1} ? {c1 eval {info exists :x}} 1 # # using a default value for initcmd # - C setObjectParams {{initcmd:initcmd ""}} + C setObjectParams {{initcmd:cmd ""}} C create c1 {set :x 1} C create c2 ? {c1 eval {info exists :x}} 1 @@ -687,7 +687,7 @@ # optional initcmd + non-consuming (nrargs==0) posarg, provided # initcmd # - C setObjectParams {foo:alias,noarg initcmd:initcmd,optional} + C setObjectParams {foo:alias,noarg initcmd:cmd,optional} C create c1 {set :x 1} ? {c1 eval {info exists :x}} 1 ? {c1 eval {info exists :foo}} 1 @@ -697,7 +697,7 @@ # optional initcmd + non-consuming (nrargs==0) posarg, no value for # initcmd # - C setObjectParams {foo:alias,noarg initcmd:initcmd,optional} + C setObjectParams {foo:alias,noarg initcmd:cmd,optional} C create c1 ? {c1 eval {info exists :x}} 0 ? {c1 eval {info exists :foo}} 1 @@ -707,7 +707,7 @@ # initcmd with default + non-consuming (nrargs==0) posarg, no value # for initcmd # - C setObjectParams {foo:alias,noarg {initcmd:initcmd ""}} + C setObjectParams {foo:alias,noarg {initcmd:cmd ""}} C create c1 ? {c1 eval {info exists :x}} 0 ? {c1 eval {info exists :foo}} 1 @@ -716,7 +716,7 @@ # # non-consuming alias, nonpos alias with noarg, initcmd provided # - C setObjectParams {foo:alias,noarg -bar:alias,noarg initcmd:initcmd,optional} + C setObjectParams {foo:alias,noarg -bar:alias,noarg initcmd:cmd,optional} C create c1 {set :x 1} ? {c1 eval {info exists :foo}} 1 ? {c1 eval {info exists :bar}} 0 @@ -725,7 +725,7 @@ # # non-consuming alias, nonpos alias with noarg, nonpos called, initcmd provided # - C setObjectParams {foo:alias,noarg -bar:alias,noarg initcmd:initcmd,optional} + C setObjectParams {foo:alias,noarg -bar:alias,noarg initcmd:cmd,optional} C create c1 -bar {set :x 1} ? {c1 eval {info exists :foo}} 1 ? {c1 eval {info exists :bar}} 1 @@ -734,7 +734,7 @@ # # non-consuming alias, nonpos alias with noarg, no initcmd provided # - C setObjectParams {foo:alias,noarg -bar:alias,noarg initcmd:initcmd,optional} + C setObjectParams {foo:alias,noarg -bar:alias,noarg initcmd:cmd,optional} C create c1 ? {c1 eval {info exists :foo}} 1 ? {c1 eval {info exists :bar}} 0 @@ -744,7 +744,7 @@ # non-consuming alias, nonpos alias with noarg, nonpos called, no # initcmd provided # - C setObjectParams {foo:alias,noarg -bar:alias,noarg initcmd:initcmd,optional} + C setObjectParams {foo:alias,noarg -bar:alias,noarg initcmd:cmd,optional} C create c1 -bar ? {c1 eval {info exists :foo}} 1 ? {c1 eval {info exists :bar}} 1 @@ -762,8 +762,8 @@ } } - C setObjectParams {initcmd:initcmd,noarg} - ? {C create c1} {option "noarg" only allowed for parameter type "alias"} + C setObjectParams {initcmd:cmd,noarg} + ? {C create c1} {parameter option "noarg" only allowed for parameter type "alias"} } # Index: tests/info-method.test =================================================================== diff -u -N -rd79efb10b92ad2045196990af50bc042e60b88f4 -r9cead8929011bb4dcc6c44630a91bc5d597520b2 --- tests/info-method.test (.../info-method.test) (revision d79efb10b92ad2045196990af50bc042e60b88f4) +++ tests/info-method.test (.../info-method.test) (revision 9cead8929011bb4dcc6c44630a91bc5d597520b2) @@ -718,7 +718,7 @@ ? {C info configure syntax} "/::C/ ?-a /value/? ?-b /value/? ?-volatile? ?-noinit? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initcmd/?" # ? {C info configure syntax a} "/::C/ ?-a /value/?" - ? {C info configure parameters } "-a {-b 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" + ? {C info configure parameters } "-a {-b 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" # ? {C info parameter list} "-a -b -volatile -noinit -object-mixin -class -object-filter __initcmd" # ? {C info parameter names} "a b volatile noinit object-mixin class object-filter __initcmd" Index: tests/info-variable.test =================================================================== diff -u -N -r2d9fcf7f4dc9ccd8ac52702850f60724a04bcba4 -r9cead8929011bb4dcc6c44630a91bc5d597520b2 --- tests/info-variable.test (.../info-variable.test) (revision 2d9fcf7f4dc9ccd8ac52702850f60724a04bcba4) +++ tests/info-variable.test (.../info-variable.test) (revision 9cead8929011bb4dcc6c44630a91bc5d597520b2) @@ -38,7 +38,7 @@ -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n -__initcmd:initcmd,optional,noleadingdash" +__initcmd:cmd,optional,noleadingdash" ? {Person info configure parameters age} "-age:integer" ? {Person info configure parameters {*a[gs]*}} "-age:integer -class:class,alias,method=::nsf::methods::object::class" Index: tests/parameters.test =================================================================== diff -u -N -r6fd5b9d632efe378ecf7df0ecfb0a2ef6b39b7c1 -r9cead8929011bb4dcc6c44630a91bc5d597520b2 --- tests/parameters.test (.../parameters.test) (revision 6fd5b9d632efe378ecf7df0ecfb0a2ef6b39b7c1) +++ tests/parameters.test (.../parameters.test) (revision 9cead8929011bb4dcc6c44630a91bc5d597520b2) @@ -275,7 +275,7 @@ C create c1 ? {C eval :__objectparameter} \ - "{-superclass:class,alias,method=::nsf::methods::class::superclass,1..n ::nx::Object} -mixin:mixinreg,alias,1..n -filter:filterreg,alias,1..n -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" + "{-superclass:class,alias,method=::nsf::methods::class::superclass,1..n ::nx::Object} -mixin:mixinreg,alias,1..n -filter:filterreg,alias,1..n -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" #### TOOD: remove or add #? {c1 eval :__objectparameter} \ @@ -307,7 +307,7 @@ "::D::slot::d ::C::slot::a ::C::slot::b ::C::slot::c" ? {d1 eval :__objectparameter} \ - "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" + "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" } ####################################################### @@ -336,29 +336,29 @@ D mixin M ? {d1 eval :__objectparameter} \ - "-b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" \ + "-b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" \ "mixin added" M mixin M2 ? {d1 eval :__objectparameter} \ - "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" \ + "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" \ "transitive mixin added" D mixin "" #we should have again the old interface ? {d1 eval :__objectparameter} \ - "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" + "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" C mixin M ? {d1 eval :__objectparameter} \ - "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" \ + "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" \ "mixin added" C mixin "" #we should have again the old interface ? {d1 eval :__objectparameter} \ - "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" + "-d:required -a -b:boolean {-c 1} -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" } ####################################################### @@ -628,10 +628,10 @@ "-instance:switch -reset:switch name" \ "query parameter for C-defined method 'autoname'" - # TODO: how to query the params/instparams of info subcommands? - #? {::xotcl::objectInfo info params params} \ - # "xxx" \ - # "query instparams for info method 'params' method" + D method "a b" {x y} {return $x-$y} + D object method "c d" {x y z} {return $x-$y} + ? {D info method parameters "a b"} "x y" + ? {D info object method parameters "c d"} "x y z" } ####################################################### @@ -993,21 +993,15 @@ :property {x:object,1..* {o}} } - # TODO: we have no good interface for querying the slot notation for parameters - proc ::parameterFromSlot {class objectparameter} { - set slot ${class}::slot::$objectparameter - return [$slot getParameterSpec] - } + ? {ParamTest info configure parameters o} "-o:object" + ? {ParamTest info configure parameters c} "-c:class" + ? {ParamTest info configure parameters c1} "-c1:class,type=::MC" + ? {ParamTest info configure parameters d} "-d:object,type=::C" + ? {ParamTest info configure parameters d1} "-d1:object,type=::C" + ? {ParamTest info configure parameters x} "{-x:object,1..* o}" + ? {ParamTest info configure parameters u} "-u:upper,slot=::ParamTest::slot::u" + ? {ParamTest info configure parameters us} "-us:upper,slot=::ParamTest::slot::us,1..*" - ? {::parameterFromSlot ParamTest o} "-o:object" - ? {::parameterFromSlot ParamTest c} "-c:class" - ? {::parameterFromSlot ParamTest c1} "-c1:class,type=::MC" - ? {::parameterFromSlot ParamTest d} "-d:object,type=::C" - ? {::parameterFromSlot ParamTest d1} "-d1:object,type=::C" - ? {::parameterFromSlot ParamTest x} "-x:object,1..* o" - ? {::parameterFromSlot ParamTest u} "-u:upper,slot=::ParamTest::slot::u" - ? {::parameterFromSlot ParamTest us} "-us:upper,slot=::ParamTest::slot::us,1..*" - ? {ParamTest create p -o o} ::p ? {ParamTest create p -o xxx} \ {expected object but got "xxx" for parameter "-o"} \ @@ -1392,8 +1386,17 @@ ? {o a 1} 2 ? {o a} 2 ? {o a 2} 3 - # per-class: + ? {o eval {info exists :A}} 0 + o object property {A 0} { + set :valuechangedcmd {::nsf::var::set $obj $var [expr [list [::nsf::var::set $obj $var] + 1]]} + } + ? {o eval {info exists :A}} 1 + ? {o cget -A} 0 + ? {o configure -A 1} "" + ? {o cget -A} 3 + + # per-class: Class create Klass ? {Klass property {a 0} { @@ -1505,9 +1508,6 @@ ? {f1 metaclassarg ::Foo} ::Foo } -## TODO regression test for type checking, parameter options (initcmd, -## substdefault, combinations with defaults, ...), etc. - nx::Test parameter count 100 nx::Test case checktype { @@ -1843,13 +1843,13 @@ nx::Class create M1 {:property b1:required} nx::Class create M2 {:property b2:required} - ? {c1 eval :__objectparameter} "-a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" + ? {c1 eval :__objectparameter} "-a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" c1 object mixin M1 ? {c1 info precedence} "::M1 ::C ::nx::Object" - ? {c1 eval :__objectparameter} "-b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" + ? {c1 eval :__objectparameter} "-b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" # # Invalidate the object parameter and expect that the per-class @@ -1858,7 +1858,7 @@ ::nsf::parameter:invalidate::classcache C # - # We have now "-b1:required" in the object parameters. + # We have now "-b1:required" in the configure parameters. # # TODO: Actually we should enforce it. We could check, if the # associate variable is already set, but this does not work for @@ -1950,7 +1950,7 @@ ? {C info slots -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::object-mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::object-filter" - ? {c1 eval :__objectparameter} "-a2 -b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" + ? {c1 eval :__objectparameter} "-a2 -b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" # # invalidate object parameter and expect that the per-class mixin @@ -1964,7 +1964,7 @@ ? {C info slots -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::object-mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::object-filter" - ? {c1 eval :__objectparameter} "-a2 -b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:initcmd,optional,noleadingdash" + ? {c1 eval :__objectparameter} "-a2 -b1:required -a1 -volatile:alias,slot=::nx::Object::slot::volatile,slotassign,noarg -noinit:alias,method=::nsf::methods::object::noinit,noarg -object-mixin:mixinreg,alias,method=::nx::Object::slot::__object::mixin,1..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,alias,method=::nx::Object::slot::__object::filter,1..n __initcmd:cmd,optional,noleadingdash" # should not require b1 ? {C create c2} ::c2