Index: TODO =================================================================== diff -u -r821c3ed7b14ad8137bee7d31ebadcc537c153d39 -rd62bca12731d1c7a1a5cf63f950275852c5b05a2 --- TODO (.../TODO) (revision 821c3ed7b14ad8137bee7d31ebadcc537c153d39) +++ TODO (.../TODO) (revision d62bca12731d1c7a1a5cf63f950275852c5b05a2) @@ -3594,28 +3594,29 @@ - don't convert obj types tclCmdName and parsedVarNameType to instanceMethodObjType +nx: added traits package +nonleadingdash handling: + - doc: added "nonleadingdash" to UML class diagramm + - nsf.c: added error message, when "noleadingdash" is used on + non-positional parameters + - nsf.c: use same logic for "nonleadingdash" to "value in argument" + - nsf.c: deactivated rudimentary unknown handler for the time being + - nx.tcl: added handling of parameter option "noleadingdash" + in objectParameterSlots + + TODO: - - unknown arg handler must find a way to aviod method deletions or redefinitions - or to recover from these gracefully - - methodEpoch should go into interp state. - - cleanup yyyy - warnings for "numeric" names for args and nonpos-args? - - NsfUnexpectedNonposArgumentError() for valueInArgument, when structure settles - - ouput of noleadingdash in introspection - - ouput of noleadingdash in objectParameterSlots - - handling of noleadingdash vor values of nonpos args - special handling of values looking like nonpos-flags, but wich are not ones (-1, "- a b c", ....) in detection when to throw unknow. - - check flag reuses in ~/scripts/nonposargs-speed.xotcl - NSF_WITH_OS_RESOLVER - private: * document private in tutorial - add "property" and "attribute" and "info property" and "info slot ..." to migration guide - - add traits package - naming of slot classes * should we switch from "-class" to "-slotclass"? @@ -3871,9 +3872,13 @@ to make lookup faster. * Serializer: handing of xo::at_cleanup in serializer - (either generailization or move to OpenACS/aolserver init/naviserver init) + (either generalization or move to OpenACS/aolserver init/naviserver init) * Parameter/argument handling + - Add an unknown handler for unknown non-pos args to Argument parser. + The problem is to find a way to aviod method deletions or redefinitions + or to recover from these gracefully (when e.g. the unknown handler + deletes the parameters currenlty being worked on). - Canonical parameter representations: "p:integer,multivalued" => "-name p -type integer -multivalued" "x:type,arg=::D d1" => "-name x -type type -arg ::D -default d1" Index: generic/nsf.c =================================================================== diff -u -r821c3ed7b14ad8137bee7d31ebadcc537c153d39 -rd62bca12731d1c7a1a5cf63f950275852c5b05a2 --- generic/nsf.c (.../nsf.c) (revision 821c3ed7b14ad8137bee7d31ebadcc537c153d39) +++ generic/nsf.c (.../nsf.c) (revision d62bca12731d1c7a1a5cf63f950275852c5b05a2) @@ -1284,6 +1284,7 @@ return result; } +#if 0 static int NsfCallArgumentUnknownHandler(Tcl_Interp *interp, Tcl_Obj *methodObj, @@ -1293,7 +1294,6 @@ Tcl_Obj *ov[4]; int result, oc = 3; - // yyyy /*fprintf(stderr, "try ::nsf::argument::unknown for '%s'\n", ObjStr(nameObj));*/ ov[0] = NsfGlobalObjs[NSF_ARGUMENT_UNKNOWN_HANDLER]; @@ -1310,6 +1310,7 @@ return result; } +#endif /* *---------------------------------------------------------------------- @@ -10992,7 +10993,10 @@ paramPtr->flags |= NSF_ARG_NOARG; paramPtr->nrArgs = 0; - } else if (strncmp(option, "noleadingdash", 8) == 0) { + } else if (strncmp(option, "noleadingdash", 13) == 0) { + if (*paramPtr->name == '-') { + return NsfPrintError(interp, "Parameter option 'noleadingdash' only allowed for positional parameters"); + } paramPtr->flags |= NSF_ARG_NOLEADINGDASH; } else if (strncmp(option, "noconfig", 8) == 0) { @@ -11003,7 +11007,7 @@ } else if (strncmp(option, "args", 4) == 0) { if ((paramPtr->flags & NSF_ARG_ALIAS) == 0) { - return NsfPrintError(interp, "option \"args\" only allowed for parameter type \"alias\""); + return NsfPrintError(interp, "Parameter option \"args\" only allowed for parameter type \"alias\""); } result = ParamOptionSetConverter(interp, paramPtr, "args", ConvertToNothing); @@ -15966,8 +15970,15 @@ } } if (!found) { - SkipNonposParamDefs(currentParamPtr); - pPtr = currentParamPtr; + Nsf_Param CONST *nextParamPtr = NextParam(currentParamPtr, lastParamPtr); + if (nextParamPtr > lastParamPtr + || (nextParamPtr->flags & NSF_ARG_NOLEADINGDASH)) { + return NsfUnexpectedNonposArgumentError(interp, argumentString, + (Nsf_Object *)object, + currentParamPtr, paramPtr, + procNameObj); + } + pPtr = currentParamPtr = nextParamPtr; } } else { /* @@ -15996,7 +16007,11 @@ nextParamPtr, nextParamPtr->name);*/ if (nextParamPtr > lastParamPtr || (nextParamPtr->flags & NSF_ARG_NOLEADINGDASH)) { - /// yyyy work in progress +#if 0 + /* + * Currently, we can't recover from a deletion of the + * parameters in the unknown handler + */ int result, refcountBefore = procNameObj->refCount; /*fprintf(stderr, "### refcount of %s before -> %d objc %d\n", ObjStr(procNameObj), procNameObj->refCount, pcPtr->objc);*/ @@ -16012,6 +16027,7 @@ return NsfPrintError(interp, "Unknown handler for '%s' must not alter definition", ObjStr(argumentObj)); } +#endif return NsfUnexpectedNonposArgumentError(interp, argumentString, (Nsf_Object *)object, currentParamPtr, paramPtr, Index: generic/nsfError.c =================================================================== diff -u -r24724ebae83af4e0104b349a2fb582bfc71a7475 -rd62bca12731d1c7a1a5cf63f950275852c5b05a2 --- generic/nsfError.c (.../nsfError.c) (revision 24724ebae83af4e0104b349a2fb582bfc71a7475) +++ generic/nsfError.c (.../nsfError.c) (revision d62bca12731d1c7a1a5cf63f950275852c5b05a2) @@ -278,6 +278,9 @@ Tcl_DStringAppend(dsPtr, argumentString, -1); Tcl_DStringAppend(dsPtr, "', valid are : ", -1); for (pPtr = currentParamPtr; pPtr->name && *pPtr->name == '-'; pPtr ++) { + if (pPtr->flags & NSF_ARG_NOCONFIG) { + continue; + } Tcl_DStringAppend(dsPtr, pPtr->name, -1); Tcl_DStringAppend(dsPtr, ", ", -1); } Index: library/nx/nx.tcl =================================================================== diff -u -rbfdad656af33451da0213dd66789a3d0f625ba18 -rd62bca12731d1c7a1a5cf63f950275852c5b05a2 --- library/nx/nx.tcl (.../nx.tcl) (revision bfdad656af33451da0213dd66789a3d0f625ba18) +++ library/nx/nx.tcl (.../nx.tcl) (revision d62bca12731d1c7a1a5cf63f950275852c5b05a2) @@ -831,7 +831,7 @@ set parameterOptions [string range $spec [expr {$colonPos+1}] end] set name [string range $spec 0 [expr {$colonPos -1}]] foreach property [split $parameterOptions ,] { - if {$property in [list "required" "convert" "substdefault" "noarg"]} { + if {$property in [list "required" "convert" "substdefault" "noarg" "noleadingdash"]} { if {$property eq "convert" } {set class [:requireClass ::nx::VariableSlot $class]} lappend opts -$property 1 } elseif {$property eq "noaccessor"} { @@ -1023,6 +1023,7 @@ {accessor false} {config true} {noarg} + {noleadingdash} {disposition alias} {required false} {default} @@ -1136,6 +1137,7 @@ } } if {[info exists :noarg] && ${:noarg}} {lappend options noarg} + if {[info exists :noleadingdash] && ${:noleadingdash}} {lappend options noleadingdash} if {$withMultiplicity && [info exists :multiplicity] && ${:multiplicity} ne "1..1"} { #puts stderr "### [self] added multiplicity ${:multiplicity}" lappend options ${:multiplicity} @@ -1383,6 +1385,7 @@ # ::nx::ObjectParameterSlot create ${os}::Object::slot::__initcmd \ -disposition initcmd \ + -noleadingdash true \ -positional true \ -position 2 Index: tests/info-method.test =================================================================== diff -u -rbfdad656af33451da0213dd66789a3d0f625ba18 -rd62bca12731d1c7a1a5cf63f950275852c5b05a2 --- tests/info-method.test (.../info-method.test) (revision bfdad656af33451da0213dd66789a3d0f625ba18) +++ tests/info-method.test (.../info-method.test) (revision d62bca12731d1c7a1a5cf63f950275852c5b05a2) @@ -526,7 +526,7 @@ ? {C info parameter syntax} "?-a value? ?-b value? ?-volatile? ?-properties value? ?-noinit? ?-mixin mixinreg ...? ?-class class? ?-filter filterreg ...? ?__initcmd?" ? {C info parameter syntax a} "?-a value?" - ? {C info parameter definition} "-a {-b 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" + ? {C info parameter definition} "-a {-b 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional,noleadingdash" ? {C info parameter list} "-a -b -volatile -properties -noinit -mixin -class -filter __initcmd" ? {C info parameter names} "a b volatile properties noinit mixin class filter __initcmd" Index: tests/method-parameter.test =================================================================== diff -u -re52f2dd0f35e8a12230a20e90575f242da4e0e5c -rd62bca12731d1c7a1a5cf63f950275852c5b05a2 --- tests/method-parameter.test (.../method-parameter.test) (revision e52f2dd0f35e8a12230a20e90575f242da4e0e5c) +++ tests/method-parameter.test (.../method-parameter.test) (revision d62bca12731d1c7a1a5cf63f950275852c5b05a2) @@ -42,7 +42,7 @@ nsf::proc p2a {-x args} {return [list [info exists x] $args]} nsf::proc p2b {-x args:noleadingdash} {return [list [info exists x] $args]} - nsf::proc p2c {-x:noleadingdash args:noleadingdash} {return [list [info exists x] $args]} + nsf::proc p2c {-x args:noleadingdash} {return [list [info exists x] $args]} ? {p2a -x -y} {1 {}} ;# "-y" is the value of "x" ? {p2b -x -y} {1 {}} ;# "-y" is the value of "x" Index: tests/parameters.test =================================================================== diff -u -r4e8faf5bc42abdcfc1deb53176ee34cc8a1cbd51 -rd62bca12731d1c7a1a5cf63f950275852c5b05a2 --- tests/parameters.test (.../parameters.test) (revision 4e8faf5bc42abdcfc1deb53176ee34cc8a1cbd51) +++ tests/parameters.test (.../parameters.test) (revision d62bca12731d1c7a1a5cf63f950275852c5b05a2) @@ -274,7 +274,7 @@ C create c1 ? {C eval :objectparameter} \ - "-a -b:boolean {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" + "-a -b:boolean {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional,noleadingdash" ? {c1 eval :objectparameter} \ "::c1: unable to dispatch method 'objectparameter'" @@ -305,7 +305,7 @@ "::D::slot::d ::C::slot::a ::C::slot::b ::C::slot::c" ? {D eval :objectparameter} \ - "-d:required -a -b:boolean {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" + "-d:required -a -b:boolean {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional,noleadingdash" } ####################################################### @@ -334,29 +334,29 @@ D mixin M ? {D eval :objectparameter} \ - "-b -m1 -m2 -d:required -a {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" \ + "-b -m1 -m2 -d:required -a {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional,noleadingdash" \ "mixin added" M mixin M2 ? {D eval :objectparameter} \ - "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" \ + "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional,noleadingdash" \ "transitive mixin added" D mixin "" #we should have again the old interface ? {D eval :objectparameter} \ - "-d:required -a -b:boolean {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" + "-d:required -a -b:boolean {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional,noleadingdash" C mixin M ? {D eval :objectparameter} \ - "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" \ + "-b2 -b -m1 -m2 -d:required -a {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional,noleadingdash" \ "mixin added" C mixin "" #we should have again the old interface ? {D eval :objectparameter} \ - "-d:required -a -b:boolean {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" + "-d:required -a -b:boolean {-c 1} -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional,noleadingdash" } ####################################################### @@ -1669,7 +1669,7 @@ ? {C info slot objects -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::properties ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" - ? {C eval :objectparameter} "-a1 -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" + ? {C eval :objectparameter} "-a1 -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional,noleadingdash" # # invalidate object parameter and expect that the per-class mixin @@ -1683,7 +1683,7 @@ ? {C info slot objects -closure} "::C::slot::a1 ::nx::Object::slot::volatile ::nx::Object::slot::properties ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" - ? {C eval :objectparameter} "-a1 -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional" + ? {C eval :objectparameter} "-a1 -volatile:alias,noarg -properties:alias,method=::nx::internal::addProperties -noinit:alias,method=::nsf::methods::object::noinit,noarg -mixin:mixinreg,alias,1..n -class:class,alias,method=::nsf::methods::object::class -filter:filterreg,alias,1..n __initcmd:initcmd,optional,noleadingdash" # should not require b1 ? {C create c2} ::c2 @@ -1993,12 +1993,10 @@ ? {C info parameter list v} "" ? {C info parameter syntax v} "" - # TODO: the error message for the invalid object parameter should be - # improved. The problem is, that "-v" is passed to the initcmd, so - # just "10" is invalid. ? {C create c2 -a 10} ::c2 ? {C create c2 -v 10} \ - {Invalid argument '10', maybe too many arguments; should be "::c2 configure ?-a value? ?-volatile? ?-properties value? ?-noinit? ?-mixin mixinreg ...? ?-class class? ?-filter filterreg ...? ?__initcmd?"} + {Invalid non-positional argument '-v', valid are : -a, -volatile, -properties, -noinit, -mixin, -class, -filter; + should be "::c2 configure ?-a value? ?-volatile? ?-properties value? ?-noinit? ?-mixin mixinreg ...? ?-class class? ?-filter filterreg ...? ?__initcmd?"} # # We expect a setter for "a" but not for "v".