Index: TODO =================================================================== diff -u -r91c0f6d233633e6e7c76b911377b97609749bd49 -r1f7ecfcf5b0643ce05b96405c77d5da7fe10268e --- TODO (.../TODO) (revision 91c0f6d233633e6e7c76b911377b97609749bd49) +++ TODO (.../TODO) (revision 1f7ecfcf5b0643ce05b96405c77d5da7fe10268e) @@ -2725,6 +2725,10 @@ "info slot handle /name/" "info slot parameter /name/" +- nsf.c: Since the method "objectparameter" is just based on the class + (and object parameters are invalidates as well over the class), we + moved the method from obj to class to avoid potential confusions + TODO: - missing in c-based "info slots": Index: generic/nsf.c =================================================================== diff -u -r8eb8f0692e858ee3b4a7f90d0e16bae6f835330f -r1f7ecfcf5b0643ce05b96405c77d5da7fe10268e --- generic/nsf.c (.../nsf.c) (revision 8eb8f0692e858ee3b4a7f90d0e16bae6f835330f) +++ generic/nsf.c (.../nsf.c) (revision 1f7ecfcf5b0643ce05b96405c77d5da7fe10268e) @@ -17154,11 +17154,11 @@ */ static int -GetObjectParameterDefinition(Tcl_Interp *interp, Tcl_Obj *procNameObj, NsfObject *object, +GetObjectParameterDefinition(Tcl_Interp *interp, Tcl_Obj *procNameObj, NsfClass *class, NsfParsedParam *parsedParamPtr) { int result; Tcl_Obj *rawConfArgs; - NsfParsedParam *clParsedParamPtr = object->cl->parsedParamPtr; + NsfParsedParam *clParsedParamPtr = class->parsedParamPtr; /* * Parameter definitions are cached in the class, for which @@ -17188,11 +17188,11 @@ * There is no parameter definition available, get a new one in * the the string representation. */ - Tcl_Obj *methodObj = NsfMethodObj(object, NSF_o_objectparameter_idx); + Tcl_Obj *methodObj = NsfMethodObj(&class->object, NSF_c_objectparameter_idx); if (methodObj) { /* fprintf(stderr, "=== calling %s objectparameter\n", ObjectName(object));*/ - result = CallMethod((ClientData) object, interp, methodObj, + result = CallMethod((ClientData) class, interp, methodObj, 2, 0, NSF_CM_NO_PROTECT|NSF_CSC_IMMEDIATE); if (result == TCL_OK) { @@ -17211,7 +17211,7 @@ NsfParsedParam *ppDefPtr = NEW(NsfParsedParam); ppDefPtr->paramDefs = parsedParamPtr->paramDefs; ppDefPtr->possibleUnknowns = parsedParamPtr->possibleUnknowns; - object->cl->parsedParamPtr = ppDefPtr; + class->parsedParamPtr = ppDefPtr; } DECR_REF_COUNT(rawConfArgs); } @@ -17366,7 +17366,7 @@ #endif /* Get the object parameter definition */ - result = GetObjectParameterDefinition(interp, objv[0], object, &parsedParam); + result = GetObjectParameterDefinition(interp, objv[0], object->cl, &parsedParam); if (result != TCL_OK || !parsedParam.paramDefs) { /*fprintf(stderr, "... nothing to do for method %s\n", ObjStr(objv[0]));*/ goto configure_exit; Index: generic/nsfInt.h =================================================================== diff -u -ra5e4ab3a3f85b51e855adb3fe981833c2534ee8b -r1f7ecfcf5b0643ce05b96405c77d5da7fe10268e --- generic/nsfInt.h (.../nsfInt.h) (revision a5e4ab3a3f85b51e855adb3fe981833c2534ee8b) +++ generic/nsfInt.h (.../nsfInt.h) (revision 1f7ecfcf5b0643ce05b96405c77d5da7fe10268e) @@ -533,6 +533,7 @@ NSF_c_alloc_idx, NSF_c_create_idx, NSF_c_dealloc_idx, + NSF_c_objectparameter_idx, NSF_c_recreate_idx, NSF_c_requireobject_idx, NSF_o_cleanup_idx, @@ -541,7 +542,6 @@ NSF_o_destroy_idx, NSF_o_init_idx, NSF_o_move_idx, - NSF_o_objectparameter_idx, NSF_o_residualargs_idx, NSF_o_unknown_idx } SystemMethodsIdx; @@ -553,6 +553,7 @@ "-class.alloc", "-class.create", "-class.dealloc", + "-class.objectparameter", "-class.recreate", "-class.requireobject", "-object.cleanup", @@ -561,7 +562,6 @@ "-object.destroy", "-object.init", "-object.move", - "-object.objectparameter", "-object.residualargs", "-object.unknown", NULL Index: library/nx/nx.tcl =================================================================== diff -u -r91c0f6d233633e6e7c76b911377b97609749bd49 -r1f7ecfcf5b0643ce05b96405c77d5da7fe10268e --- library/nx/nx.tcl (.../nx.tcl) (revision 91c0f6d233633e6e7c76b911377b97609749bd49) +++ library/nx/nx.tcl (.../nx.tcl) (revision 1f7ecfcf5b0643ce05b96405c77d5da7fe10268e) @@ -19,14 +19,14 @@ -class.alloc {alloc ::nsf::methods::class::alloc} -class.create create -class.dealloc {dealloc ::nsf::methods::class::dealloc} + -class.objectparameter objectparameter -class.recreate {recreate ::nsf::methods::class::recreate} -class.requireobject __unknown -object.configure configure -object.defaultmethod {defaultmethod ::nsf::methods::object::defaultmethod} -object.destroy destroy -object.init {init ::nsf::methods::object::init} -object.move move - -object.objectparameter objectparameter -object.unknown unknown } @@ -270,7 +270,7 @@ # provide a placeholder for the bootup process. The real definition # is based on slots, which are not available at this point. - Object protected method objectparameter {} {;} + Class protected method objectparameter {} {;} # # Define forward methods @@ -977,14 +977,12 @@ # ::nsf::invalidateobjectparameter MetaSlot - Object protected method objectparameter {} { + Class protected method objectparameter {} { # # Collect the object parameter slots in per-position lists to # ensure partial ordering and avoid sorting. # - set class [::nsf::relation [self] class] - foreach slot [nsf::dispatch $class ::nsf::methods::class::info::slots -closure -type ::nx::Slot] { - #foreach slot [nsf::dispatch [self] ::nsf::methods::object::info::lookupslots -type ::nx::Slot] {} + foreach slot [nsf::dispatch [self] ::nsf::methods::class::info::slots -closure -type ::nx::Slot] { lappend defs([$slot position]) [$slot getParameterSpec] } # Index: library/xotcl/library/xotcl2.tcl =================================================================== diff -u -rf7e340c5779999c9495abbb4a2112057b34e1a97 -r1f7ecfcf5b0643ce05b96405c77d5da7fe10268e --- library/xotcl/library/xotcl2.tcl (.../xotcl2.tcl) (revision f7e340c5779999c9495abbb4a2112057b34e1a97) +++ library/xotcl/library/xotcl2.tcl (.../xotcl2.tcl) (revision 1f7ecfcf5b0643ce05b96405c77d5da7fe10268e) @@ -24,6 +24,7 @@ -class.alloc alloc -class.create create -class.dealloc dealloc + -class.objectparameter objectparameter -class.recreate recreate -class.requireobject __unknown -object.configure configure @@ -32,7 +33,6 @@ -object.destroy destroy -object.init init -object.move move - -object.objectparameter objectparameter -object.residualargs residualargs -object.unknown unknown } @@ -367,9 +367,9 @@ # Method objectparameter, backwards upward compatible. We use # here the definition of parametersfromslots from nx.tcl # - ::xotcl::Object instproc objectparameter {} { + ::xotcl::Class instproc objectparameter {} { set parameterdefinitions [list] - foreach slot [::nsf::dispatch [self] ::nsf::methods::object::info::lookupslots -type ::nx::Slot] { + foreach slot [nsf::dispatch [self] ::nsf::methods::class::info::slots -closure -type ::nx::Slot] { lappend parameterdefinitions [$slot getParameterSpec] } lappend parameterdefinitions args Index: library/xotcl/tests/slottest.xotcl =================================================================== diff -u -re02cb00ae815bd6f8561a6a03fceacc13fd91903 -r1f7ecfcf5b0643ce05b96405c77d5da7fe10268e --- library/xotcl/tests/slottest.xotcl (.../slottest.xotcl) (revision e02cb00ae815bd6f8561a6a03fceacc13fd91903) +++ library/xotcl/tests/slottest.xotcl (.../slottest.xotcl) (revision 1f7ecfcf5b0643ce05b96405c77d5da7fe10268e) @@ -112,7 +112,7 @@ ? {o1 class} "::O" o1 class Object ? {o1 class} "::xotcl::Object" -? {o1 objectparameter} "-mixin:alias -filter:alias -class:alias args" +? {Object objectparameter} "-mixin:alias -filter:alias -class:alias args" ? {o1 class add M} {class: expected a class but got "M ::xotcl::Object"} Index: library/xotcl/tests/testx.xotcl =================================================================== diff -u -re4cc1570b184d6ae7f6d9f8daaa783e1df470e88 -r1f7ecfcf5b0643ce05b96405c77d5da7fe10268e --- library/xotcl/tests/testx.xotcl (.../testx.xotcl) (revision e4cc1570b184d6ae7f6d9f8daaa783e1df470e88) +++ library/xotcl/tests/testx.xotcl (.../testx.xotcl) (revision 1f7ecfcf5b0643ce05b96405c77d5da7fe10268e) @@ -398,7 +398,7 @@ SC($i) destroy } - ::errorCheck $::filterCount 1080 \ + ::errorCheck $::filterCount 960 \ "Filter Test - Filter Count -- Got: $::filterCount" # @@ -544,7 +544,8 @@ Class D D filter f D d1 - ::errorCheck $::r "::D-d1 ::D-alloc ::D-create ::D-unknown" "filter state after next" + ::errorCheck $::r "::D-d1 ::D-alloc ::D-objectparameter ::D-create ::D-unknown" \ + "filter state after next" Object instproc f {} {} D destroy } @@ -1148,7 +1149,7 @@ TransferDialog$i destroy } - ::errorCheck $::filterCount 260 \ + ::errorCheck $::filterCount 240 \ "Simple Observer - Filter Count" } @@ -2931,7 +2932,7 @@ Recreated recreateObj recreateObj destroy errorCheck [set ::recreateFilterResult] \ - " ::recreateObj+::xotcl::Object->configure ::recreateObj+::xotcl::Object->objectparameter ::recreateObj+::xotcl::Object->init ::recreateObj+::xotcl::Object->cleanup ::recreateObj+::xotcl::Object->configure ::recreateObj+::xotcl::Object->init ::recreateObj+::xotcl::Object->destroy" \ + " ::recreateObj+::xotcl::Object->configure ::recreateObj+::xotcl::Object->init ::recreateObj+::xotcl::Object->cleanup ::recreateObj+::xotcl::Object->configure ::recreateObj+::xotcl::Object->init ::recreateObj+::xotcl::Object->destroy" \ "recreateObj - recreateFilterResult" if {$i == 0} { errorCheck [set ::recreateMixinResult] \ @@ -3162,12 +3163,12 @@ ::errorCheck [b info procs] objproc "info procs" ::errorCheck [B info instprocs] myProc2 "info instprocs" - ::errorCheck [lsort [b info methods]] "abstract append array autoname check class cleanup configure contains copy defaultmethod destroy eval exists extractConfigureArg f filter filterguard filtersearch forward hasclass incr info init instvar invar isclass ismetaclass ismixin isobject istype lappend method mixin mixinguard move myProc myProc2 myProcMix1 myProcMix2 noinit objectparameter objproc parametercmd proc procsearch requireNamespace residualargs self set setFilter signature subst trace unknown unset uplevel upvar volatile vwait" "b info methods" + ::errorCheck [lsort [b info methods]] "abstract append array autoname check class cleanup configure contains copy defaultmethod destroy eval exists extractConfigureArg f filter filterguard filtersearch forward hasclass incr info init instvar invar isclass ismetaclass ismixin isobject istype lappend method mixin mixinguard move myProc myProc2 myProcMix1 myProcMix2 noinit objproc parametercmd proc procsearch requireNamespace residualargs self set setFilter signature subst trace unknown unset uplevel upvar volatile vwait" "b info methods" - ::errorCheck [lsort [b info methods -nocmds]] "abstract check extractConfigureArg f filtersearch forward hasclass init isclass ismetaclass ismixin isobject istype method myProc myProc2 myProcMix1 myProcMix2 objectparameter objproc proc procsearch self setFilter signature unknown vwait" "b info methods -nocmds" + ::errorCheck [lsort [b info methods -nocmds]] "abstract check extractConfigureArg f filtersearch forward hasclass init isclass ismetaclass ismixin isobject istype method myProc myProc2 myProcMix1 myProcMix2 objproc proc procsearch self setFilter signature unknown vwait" "b info methods -nocmds" ::errorCheck [lsort [b info methods -noprocs]] "append array autoname class cleanup configure destroy eval exists filter filterguard incr info instvar invar lappend mixin mixinguard noinit parametercmd requireNamespace residualargs set subst trace unset uplevel upvar volatile" "b info methods -noprocs" - ::errorCheck [lsort [b info methods -nocmds -nomixins]] "abstract check extractConfigureArg f filtersearch forward hasclass init isclass ismetaclass ismixin isobject istype method myProc myProc2 objectparameter objproc proc procsearch self setFilter signature unknown vwait" "b info methods -nocmds -nomixins" + ::errorCheck [lsort [b info methods -nocmds -nomixins]] "abstract check extractConfigureArg f filtersearch forward hasclass init isclass ismetaclass ismixin isobject istype method myProc myProc2 objproc proc procsearch self setFilter signature unknown vwait" "b info methods -nocmds -nomixins" ::errorCheck [b info methods -nocmds -noprocs] "" "b info methods -nocmds -noprocs" ::errorCheck [lsort [B info methods -nocmds]] "abstract allinstances check extractConfigureArg f filtersearch forward hasclass init instforward instproc isclass ismetaclass ismixin isobject istype method objectparameter proc procsearch self setFilter signature unknown uses vwait" "B info methods -nocmds" @@ -3561,9 +3562,9 @@ set ::context payrollApp - ::errorCheck [lsort [jim info methods]] "abstract age append array autoname check class cleanup configure contains copy defaultmethod destroy driving-license eval exists extractConfigureArg filter filterguard filtersearch forward hasclass id incr info init instvar invar isclass ismetaclass ismixin isobject istype lappend method mixin mixinguard move name noinit objectparameter parametercmd print proc procsearch requireNamespace residualargs salary self set signature subst trace unknown unset uplevel upvar volatile vwait" "condmixin all methods" + ::errorCheck [lsort [jim info methods]] "abstract age append array autoname check class cleanup configure contains copy defaultmethod destroy driving-license eval exists extractConfigureArg filter filterguard filtersearch forward hasclass id incr info init instvar invar isclass ismetaclass ismixin isobject istype lappend method mixin mixinguard move name noinit parametercmd print proc procsearch requireNamespace residualargs salary self set signature subst trace unknown unset uplevel upvar volatile vwait" "condmixin all methods" - ::errorCheck "[lsort [jim info methods -incontext]]" "abstract age append array autoname check class cleanup configure contains copy defaultmethod destroy eval exists extractConfigureArg filter filterguard filtersearch forward hasclass id incr info init instvar invar isclass ismetaclass ismixin isobject istype lappend method mixin mixinguard move name noinit objectparameter parametercmd print proc procsearch requireNamespace residualargs salary self set signature subst trace unknown unset uplevel upvar volatile vwait" "all methods in context" + ::errorCheck "[lsort [jim info methods -incontext]]" "abstract age append array autoname check class cleanup configure contains copy defaultmethod destroy eval exists extractConfigureArg filter filterguard filtersearch forward hasclass id incr info init instvar invar isclass ismetaclass ismixin isobject istype lappend method mixin mixinguard move name noinit parametercmd print proc procsearch requireNamespace residualargs salary self set signature subst trace unknown unset uplevel upvar volatile vwait" "all methods in context" ::errorCheck [my show payrollApp jim] "{payrollApp: jim info methods salary => salary} {payrollApp: jim info methods -incontext salary => salary} {payrollApp: jim info methods driv* => driving-license} {payrollApp: jim info methods -incontext driv* => }" "payrollApp jim" ::errorCheck [my show shipmentApp jim] "{shipmentApp: jim info methods salary => salary} {shipmentApp: jim info methods -incontext salary => } {shipmentApp: jim info methods driv* => driving-license} {shipmentApp: jim info methods -incontext driv* => driving-license}" "shipmentApp jim" Index: tests/object-system.test =================================================================== diff -u -rda6586782390b02ed7660b56417c3db00d63d1c3 -r1f7ecfcf5b0643ce05b96405c77d5da7fe10268e --- tests/object-system.test (.../object-system.test) (revision da6586782390b02ed7660b56417c3db00d63d1c3) +++ tests/object-system.test (.../object-system.test) (revision 1f7ecfcf5b0643ce05b96405c77d5da7fe10268e) @@ -19,7 +19,7 @@ } } -? {::nsf::configure objectsystem} "{::nx::Object ::nx::Class {-class.alloc alloc -class.create create -class.dealloc dealloc -class.recreate recreate -class.requireobject __unknown -object.configure configure -object.defaultmethod defaultmethod -object.destroy destroy -object.init init -object.move move -object.objectparameter objectparameter -object.unknown unknown}}" +? {::nsf::configure objectsystem} "{::nx::Object ::nx::Class {-class.alloc alloc -class.create create -class.dealloc dealloc -class.objectparameter objectparameter -class.recreate recreate -class.requireobject __unknown -object.configure configure -object.defaultmethod defaultmethod -object.destroy destroy -object.init init -object.move move -object.unknown unknown}}" ? {::nsf::object::exists Object} 1 ? {::nsf::is class Object} 1 Index: tests/parameters.test =================================================================== diff -u -r620972f9a159f83b824f229ab406331e6bd238de -r1f7ecfcf5b0643ce05b96405c77d5da7fe10268e --- tests/parameters.test (.../parameters.test) (revision 620972f9a159f83b824f229ab406331e6bd238de) +++ tests/parameters.test (.../parameters.test) (revision 1f7ecfcf5b0643ce05b96405c77d5da7fe10268e) @@ -248,11 +248,11 @@ Class create C -attributes {a {b:boolean} {c 1}} C create c1 - ? {C eval {:objectparameter}} \ - "{-superclass:alias,arg=::nsf::methods::class::superclass ::nx::Object} -object-mixin:alias,arg=::nsf::classes::nx::Object::mixin -mixin:alias -object-filter:alias,arg=::nsf::classes::nx::Object::filter -filter:alias -attributes:alias -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -class:alias,arg=::nsf::methods::object::class __initcmd:initcmd,optional" - - ? {c1 eval {:objectparameter}} \ + ? {C eval :objectparameter} \ "-a -b:boolean {-c 1} -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -mixin:alias -class:alias,arg=::nsf::methods::object::class -filter:alias __initcmd:initcmd,optional" + + ? {c1 eval :objectparameter} \ + "::c1: unable to dispatch method 'objectparameter'" } ####################################################### @@ -263,14 +263,19 @@ Class create C -attributes {a {b:boolean} {c 1}} C create c1 + ? {c1 info lookup slots -source application} "::C::slot::a ::C::slot::b ::C::slot::c" + c1 configure -class Object - ? {c1 eval :objectparameter} \ - "-volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -mixin:alias -class:alias,arg=::nsf::methods::object::class -filter:alias __initcmd:initcmd,optional" + + ? {c1 info lookup slots -source application} "" Class create D -superclass C -attributes {d:required} D create d1 -d 100 + + ? {d1 info lookup slots -source application} \ + "::D::slot::d ::C::slot::a ::C::slot::b ::C::slot::c" - ? {d1 eval :objectparameter} \ + ? {D eval :objectparameter} \ "-d:required -a -b:boolean {-c 1} -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -mixin:alias -class:alias,arg=::nsf::methods::object::class -filter:alias __initcmd:initcmd,optional" } @@ -286,27 +291,30 @@ Class create M -attributes {m1 m2 b} Class create M2 -attributes {b2} D mixin M - ? {d1 eval :objectparameter} \ + + ? {D eval :objectparameter} \ "-b -m1 -m2 -d:required -a {-c 1} -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -mixin:alias -class:alias,arg=::nsf::methods::object::class -filter:alias __initcmd:initcmd,optional" \ "mixin added" + M mixin M2 - ? {d1 eval :objectparameter} \ + + ? {D eval :objectparameter} \ "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -mixin:alias -class:alias,arg=::nsf::methods::object::class -filter:alias __initcmd:initcmd,optional" \ "transitive mixin added" D mixin "" #we should have again the old interface - ? {d1 eval :objectparameter} \ + ? {D eval :objectparameter} \ "-d:required -a -b:boolean {-c 1} -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -mixin:alias -class:alias,arg=::nsf::methods::object::class -filter:alias __initcmd:initcmd,optional" C mixin M - ? {d1 eval :objectparameter} \ + ? {D eval :objectparameter} \ "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -mixin:alias -class:alias,arg=::nsf::methods::object::class -filter:alias __initcmd:initcmd,optional" \ "mixin added" C mixin "" #we should have again the old interface - ? {d1 eval :objectparameter} \ + ? {D eval :objectparameter} \ "-d:required -a -b:boolean {-c 1} -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -mixin:alias -class:alias,arg=::nsf::methods::object::class -filter:alias __initcmd:initcmd,optional" } @@ -1570,7 +1578,7 @@ # # Test potential incfluence on parameters # -Test case parameter-alias-default { +Test case parameter-object-mixin-dependency { Class create C { :attribute a1 :create c1 { @@ -1588,7 +1596,7 @@ ? {C info slots -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" - ? {C eval :objectparameter} "{-superclass:alias,arg=::nsf::methods::class::superclass ::nx::Object} -object-mixin:alias,arg=::nsf::classes::nx::Object::mixin -mixin:alias -object-filter:alias,arg=::nsf::classes::nx::Object::filter -filter:alias -attributes:alias -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -class:alias,arg=::nsf::methods::object::class __initcmd:initcmd,optional" + ? {C eval :objectparameter} "-a1 -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -mixin:alias -class:alias,arg=::nsf::methods::object::class -filter:alias __initcmd:initcmd,optional" # # invalidate object parameter and expect that the per-class mixin @@ -1602,8 +1610,8 @@ ? {C info slots -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" - ? {C eval :objectparameter} "{-superclass:alias,arg=::nsf::methods::class::superclass ::nx::Object} -object-mixin:alias,arg=::nsf::classes::nx::Object::mixin -mixin:alias -object-filter:alias,arg=::nsf::classes::nx::Object::filter -filter:alias -attributes:alias -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -class:alias,arg=::nsf::methods::object::class __initcmd:initcmd,optional" - + ? {C eval :objectparameter} "-a1 -volatile:alias,noarg -noinit:alias,arg=::nsf::methods::object::noinit,noarg -mixin:alias -class:alias,arg=::nsf::methods::object::class -filter:alias __initcmd:initcmd,optional" + # should not require b1 ? {C create c2} ::c2