Index: TODO =================================================================== diff -u -N -rf5848823b019e587de395d838de3e913f452fd30 -r896f9013e125e965474ea7fdbda099ca22b152c2 --- TODO (.../TODO) (revision f5848823b019e587de395d838de3e913f452fd30) +++ TODO (.../TODO) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -5415,17 +5415,20 @@ - removed memcopy() in call-directy for "create" - some more cleanup -genttclAPI.tcl: +gentclAPI.tcl: - added option "-flags", which can be used for every parameter. example: .... -flags NSF_ARG_NOLEADINGDASH .... - experimental: use NSF_ARG_NOLEADINGDASH for pattern "info subclass" to improve error messages. - extended regression test +nsf.c: +- relax the meaning of noleadingdash to allow negative numbers +- rename noleadingdash to e.g. nodashalnum + ======================================================================== TODO: -- make test for all CallDirectly() cases, where method is dispatched (no direct call) - shouldn't "info subclass" be named "info subclasses"? Index: generic/nsf.c =================================================================== diff -u -N -r209e0e530b64680d890b5cc80664e6441bd4b3c3 -r896f9013e125e965474ea7fdbda099ca22b152c2 --- generic/nsf.c (.../nsf.c) (revision 209e0e530b64680d890b5cc80664e6441bd4b3c3) +++ generic/nsf.c (.../nsf.c) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -14753,11 +14753,11 @@ paramPtr->flags |= NSF_ARG_NOARG; paramPtr->nrArgs = 0; - } else if (strncmp(option, "noleadingdash", 13) == 0) { + } else if (strncmp(option, "nodashalnum", 11) == 0) { if (*paramPtr->name == '-') { - return NsfPrintError(interp, "parameter option 'noleadingdash' only allowed for positional parameters"); + return NsfPrintError(interp, "parameter option 'nodashalnum' only allowed for positional parameters"); } - paramPtr->flags |= NSF_ARG_NOLEADINGDASH; + paramPtr->flags |= NSF_ARG_NODASHALNUM; } else if (strncmp(option, "noconfig", 8) == 0) { if (disallowedOptions != NSF_DISALLOWED_ARG_OBJECT_PARAMETER) { @@ -21155,7 +21155,7 @@ if (!found) { Nsf_Param CONST *nextParamPtr = NextParam(currentParamPtr, lastParamPtr); if (nextParamPtr > lastParamPtr - || (nextParamPtr->flags & NSF_ARG_NOLEADINGDASH)) { + || (nextParamPtr->flags & NSF_ARG_NODASHALNUM)) { Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, CallStackGetTclFrame(interp, NULL, 0), NsfMethodName(procNameObj)); return NsfUnexpectedNonposArgumentError(interp, argumentString, @@ -21167,8 +21167,8 @@ } } else { /* - * Must be a classical nonpos arg; check for the string in - * the parameter definitions. + * Must be a classical nonpos arg; check for a matching parameter + * definition. */ int found = 0; @@ -21183,37 +21183,47 @@ break; } } + + /* + * We might have found the argument starting with the dash in the + * parameter definitions or not. If it was not found, then we can + * advance to the next positional parameter and stuff the value in + * there, if the parameter definition allows this. + */ if (!found) { + int nonposArgError = 0; Nsf_Param CONST *nextParamPtr = NextParam(currentParamPtr, lastParamPtr); + /*fprintf(stderr, "non-pos-arg '%s' not found, current %p %s last %p %s next %p %s\n", argumentString, currentParamPtr, currentParamPtr->name, lastParamPtr, lastParamPtr->name, nextParamPtr, nextParamPtr->name);*/ - if (nextParamPtr > lastParamPtr - || (nextParamPtr->flags & NSF_ARG_NOLEADINGDASH)) { -#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);*/ - result = NsfCallArgumentUnknownHandler(interp, - procNameObj, - argumentObj, - object); - /*fprintf(stderr, "### refcount of %s after -> %d\n", - ObjStr(procNameObj), procNameObj->refCount);*/ - if (procNameObj->refCount != refcountBefore) { - pcPtr->objc = nrParams ; - /*fprintf(stderr, "trigger error pcPtr->objc %d\n", pcPtr->objc);*/ - return NsfPrintError(interp, "unknown handler for '%s' must not alter definition", - ObjStr(argumentObj)); - } -#endif - Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, CallStackGetTclFrame(interp, NULL, 0), + + if (nextParamPtr > lastParamPtr) { + nonposArgError = 1; + } else if (nextParamPtr->flags & NSF_ARG_NODASHALNUM) { + /* + * Check if argment is numeric, since we want to allow it as + * value even when NSF_ARG_NODASHALNUM was specified. + */ + nonposArgError = 1; + + if (argumentString[1] >= '0' && argumentString[1] <= '9') { + char *p; + + strtod(&argumentString[1], &p); + if (*p == '\0') { + /* argument is numeric */ + //fprintf(stderr,"===== FOUND negative NUMERIC argument <%s>\n", argumentString); + nonposArgError = 0; + } + } + } + + if (nonposArgError) { + Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, + CallStackGetTclFrame(interp, NULL, 0), NsfMethodName(procNameObj)); return NsfUnexpectedNonposArgumentError(interp, argumentString, (Nsf_Object *)object, @@ -21405,7 +21415,7 @@ } } - /* + /* * Set lastObjc as index of the first "unprocessed" parameter. */ if (processFlags & NSF_ARGPARSE_START_ZERO) { Index: generic/nsf.h =================================================================== diff -u -N -r75383021cb9f2f2db883583779a02eef6f1801f5 -r896f9013e125e965474ea7fdbda099ca22b152c2 --- generic/nsf.h (.../nsf.h) (revision 75383021cb9f2f2db883583779a02eef6f1801f5) +++ generic/nsf.h (.../nsf.h) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -342,7 +342,7 @@ #define NSF_ARG_WARN 0x00080000 #define NSF_ARG_UNNAMED 0x00100000 #define NSF_ARG_IS_RETURNVALUE 0x00200000 -#define NSF_ARG_NOLEADINGDASH 0x00400000 +#define NSF_ARG_NODASHALNUM 0x00400000 #define NSF_ARG_SLOTSET 0x00800000 #define NSF_ARG_SLOTINITIALIZE 0x01000000 Index: generic/nsfAPI.decls =================================================================== diff -u -N -ra776a484c3001069d1c8ebbbac4dbdf639a81900 -r896f9013e125e965474ea7fdbda099ca22b152c2 --- generic/nsfAPI.decls (.../nsfAPI.decls) (revision a776a484c3001069d1c8ebbbac4dbdf639a81900) +++ generic/nsfAPI.decls (.../nsfAPI.decls) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -546,7 +546,7 @@ classInfoMethod subclass NsfClassInfoSubclassMethod { {-argName "-closure" -nrargs 0 -type switch} {-argName "-dependent" -nrargs 0 -type switch} - {-argName "pattern" -type objpattern -flags NSF_ARG_NOLEADINGDASH} + {-argName "pattern" -type objpattern -flags NSF_ARG_NODASHALNUM} } classInfoMethod superclass NsfClassInfoSuperclassMethod { {-argName "-closure" -nrargs 0 -type switch} Index: generic/nsfAPI.h =================================================================== diff -u -N -ra776a484c3001069d1c8ebbbac4dbdf639a81900 -r896f9013e125e965474ea7fdbda099ca22b152c2 --- generic/nsfAPI.h (.../nsfAPI.h) (revision a776a484c3001069d1c8ebbbac4dbdf639a81900) +++ generic/nsfAPI.h (.../nsfAPI.h) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -3298,7 +3298,7 @@ {"::nsf::methods::class::info::subclass", NsfClassInfoSubclassMethodStub, 3, { {"-closure", 0, 0, Nsf_ConvertTo_Boolean, NULL,NULL,"switch",NULL,NULL,NULL,NULL,NULL}, {"-dependent", 0, 0, Nsf_ConvertTo_Boolean, NULL,NULL,"switch",NULL,NULL,NULL,NULL,NULL}, - {"pattern", NSF_ARG_NOLEADINGDASH, 1, ConvertToObjpattern, NULL,NULL,"objpattern",NULL,NULL,NULL,NULL,NULL}} + {"pattern", NSF_ARG_NODASHALNUM, 1, ConvertToObjpattern, NULL,NULL,"objpattern",NULL,NULL,NULL,NULL,NULL}} }, {"::nsf::methods::class::info::superclass", NsfClassInfoSuperclassMethodStub, 2, { {"-closure", 0, 0, Nsf_ConvertTo_Boolean, NULL,NULL,"switch",NULL,NULL,NULL,NULL,NULL}, Index: library/nx/nx.tcl =================================================================== diff -u -N -r804f6d5bf7071b0146225c528c8828ea76adc865 -r896f9013e125e965474ea7fdbda099ca22b152c2 --- library/nx/nx.tcl (.../nx.tcl) (revision 804f6d5bf7071b0146225c528c8828ea76adc865) +++ library/nx/nx.tcl (.../nx.tcl) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -992,7 +992,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" "noleadingdash"]} { + if {$property in [list "required" "convert" "substdefault" "noarg" "nodashalnum"]} { if {$property eq "convert" } {set class [:requireClass ::nx::VariableSlot $class]} lappend opts -$property 1 } elseif {$property eq "noconfig"} { @@ -1213,7 +1213,7 @@ {incremental:boolean false} {configurable true} {noarg} - {noleadingdash} + {nodashalnum} {disposition alias} {required false} {default} @@ -1380,7 +1380,7 @@ } } if {[info exists :noarg] && ${:noarg}} {lappend options noarg} - if {[info exists :noleadingdash] && ${:noleadingdash}} {lappend options noleadingdash} + if {[info exists :nodashalnum] && ${:nodashalnum}} {lappend options nodashalnum} if {$withMultiplicity && [info exists :multiplicity] && ${:multiplicity} ne "1..1"} { #puts stderr "### [self] added multiplicity ${:multiplicity}" lappend options ${:multiplicity} @@ -1652,7 +1652,7 @@ # ::nx::ObjectParameterSlot create ::nx::Object::slot::__initblock \ -disposition cmd \ - -noleadingdash true \ + -nodashalnum true \ -positional true \ -position 2 Index: library/nx/nxdocIndex.tcl =================================================================== diff -u -N -r46688d146087a76aa06b15391708736fa68fc05a -r896f9013e125e965474ea7fdbda099ca22b152c2 --- library/nx/nxdocIndex.tcl (.../nxdocIndex.tcl) (revision 46688d146087a76aa06b15391708736fa68fc05a) +++ library/nx/nxdocIndex.tcl (.../nxdocIndex.tcl) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -172,8 +172,8 @@ set ::nxdoc::include(::nsf::classes::nx::ObjectParameterSlot::config) 1 set ::nxdoc::include(::nx::ObjectParameterSlot::slot::noarg) 1 set ::nxdoc::include(::nsf::classes::nx::ObjectParameterSlot::noarg) 1 -set ::nxdoc::include(::nx::ObjectParameterSlot::slot::noleadingdash) 1 -set ::nxdoc::include(::nsf::classes::nx::ObjectParameterSlot::noleadingdash) 1 +set ::nxdoc::include(::nx::ObjectParameterSlot::slot::nodashalnum) 1 +set ::nxdoc::include(::nsf::classes::nx::ObjectParameterSlot::nodashalnum) 1 set ::nxdoc::include(::nx::ObjectParameterSlot::slot::disposition) 1 set ::nxdoc::include(::nsf::classes::nx::ObjectParameterSlot::disposition) 1 set ::nxdoc::include(::nx::ObjectParameterSlot::slot::required) 1 Index: tests/info-method.test =================================================================== diff -u -N -r0c0db605f12565e52679f75889d5cc868d454059 -r896f9013e125e965474ea7fdbda099ca22b152c2 --- tests/info-method.test (.../info-method.test) (revision 0c0db605f12565e52679f75889d5cc868d454059) +++ tests/info-method.test (.../info-method.test) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -721,7 +721,7 @@ ? {C info lookup syntax create} "/objectName/ ?-a /value/? ?-b /value/? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?" ? {C info lookup syntax create a} "?-a /value/?" - ? {C info lookup parameters create } "objectName -a {-b 1} -object-mixin:mixinreg,slot=::nx::Object::slot::object-mixin,slotset,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,slot=::nx::Object::slot::object-filter,slotset,0..n __initblock:cmd,optional,noleadingdash" + ? {C info lookup parameters create } "objectName -a {-b 1} -object-mixin:mixinreg,slot=::nx::Object::slot::object-mixin,slotset,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,slot=::nx::Object::slot::object-filter,slotset,0..n __initblock:cmd,optional,nodashalnum" #? {C info parameter list} "-a -b -noinit -object-mixin -class -object-filter __initblock" #? {C info lookup args create} "methodName a b noinit object-mixin class object-filter __initblock" Index: tests/info-variable.test =================================================================== diff -u -N -r2f793442bb2a7860acc5620811dcafddc43074d3 -r896f9013e125e965474ea7fdbda099ca22b152c2 --- tests/info-variable.test (.../info-variable.test) (revision 2f793442bb2a7860acc5620811dcafddc43074d3) +++ tests/info-variable.test (.../info-variable.test) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -37,7 +37,7 @@ -object-mixin:mixinreg,slot=::nx::Object::slot::object-mixin,slotset,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,slot=::nx::Object::slot::object-filter,slotset,0..n -__initblock:cmd,optional,noleadingdash" +__initblock:cmd,optional,nodashalnum" ? {Person info lookup parameters create age} "-age:integer" ? {Person info lookup parameters create {*a[gs]*}} "-age:integer -class:class,alias,method=::nsf::methods::object::class" Index: tests/method-parameter.test =================================================================== diff -u -N -r061c1a079618bc5c9e44f127baaba5134691362f -r896f9013e125e965474ea7fdbda099ca22b152c2 --- tests/method-parameter.test (.../method-parameter.test) (revision 061c1a079618bc5c9e44f127baaba5134691362f) +++ tests/method-parameter.test (.../method-parameter.test) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -41,26 +41,25 @@ # -# test behavior of parameter option noleadingdash +# test behavior of parameter option nodashalnum # -nx::test case noleadingdash { +nx::test case nodashalnum { 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 args:noleadingdash} {return [list [info exists x] $args]} + nsf::proc p2b {-x args:nodashalnum} {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" - ? {p2c -x -y} {1 {}} ;# "-y" is the value of "x"; TODO: noleadindash currently only for posargs ? {p2a -x 1 -y} {1 -y} + ? {p2a -x 1 -100} {1 -100} + ? {p2b -x 1 -y} {invalid non-positional argument '-y', valid are : -x; should be "p2b ?-x /value/? ?/arg .../?"} - ? {p2c -x 1 -y} {invalid non-positional argument '-y', valid are : -x; - should be "p2c ?-x /value/? ?/arg .../?"} + ? {p2b -x 1 -100} {1 -100} - nsf::proc p3a {a -x -y b:noleadingdash -z} {return [list $a [info exists x] [info exists y] $b]} + nsf::proc p3a {a -x -y b:nodashalnum -z} {return [list $a [info exists x] [info exists y] $b]} ? {p3a 100 -x 1 -y 1 200} {100 1 1 200} ? {p3a 100 -xx 1 -y 1 200} {invalid non-positional argument '-xx', valid are : -x, -y; @@ -122,7 +121,7 @@ # Testing error messages in info subclass, when too many arguments are # specified, or when wrong non-positional arguments are given. The # argument "pattern" in "info subclass" has parameter option -# "noleadingdash" set. +# "nodashalnum" set. # nx::test case info-subclass-error-messages { @@ -143,7 +142,7 @@ # # The argument definition of "pattern" for subclass has - # "noleadingdash" option, therefore we can deduce that "-a" must be + # "nodashalnum" option, therefore we can deduce that "-a" must be # a flag. OTOH, if "-a" is a proper value (e.g. value of a # variable), then the following command would be perfectly fine. # @@ -156,11 +155,11 @@ should be "::C info subclass ?-closure? ?-dependent? ?/pattern/?"} ? {C info subclass -- -a} "" + ? {C info subclass -1} "" + ? {C info subclass -- -1} "" + ? {C info subclass -1 --} \ + {invalid argument '--', maybe too many arguments; should be "::C info subclass ?-closure? ?-dependent? ?/pattern/?"} - ? {C info subclass -1} \ - {invalid non-positional argument '-1', valid are : -closure, -dependent; - should be "::C info subclass ?-closure? ?-dependent? ?/pattern/?"} - # # two arguments # @@ -231,7 +230,7 @@ # Testing error messages in info superclass, when too many arguments # are specified, or when wrong non-positional arguments are # given. The argument "pattern" in "info superclass" has parameter option -# "noleadingdash" NOT set. +# "nodashalnum" NOT set. # nx::test case info-superclass-error-messages { @@ -251,7 +250,7 @@ # # The argument definition of "pattern" for superclass has no - # "noleadingdash" option, "-a" is treated like a pattern. + # "nodashalnum" option, "-a" is treated like a pattern. # ? {D info superclass -a} "" ? {D info superclass -a --} \ @@ -319,7 +318,7 @@ } # -# Test interactions of parameter option noleadingdash in "pattern" +# Test interactions of parameter option nodashalnum in "pattern" # with values starting with a dash. # Index: tests/nsf-cmd.test =================================================================== diff -u -N -r2f793442bb2a7860acc5620811dcafddc43074d3 -r896f9013e125e965474ea7fdbda099ca22b152c2 --- tests/nsf-cmd.test (.../nsf-cmd.test) (revision 2f793442bb2a7860acc5620811dcafddc43074d3) +++ tests/nsf-cmd.test (.../nsf-cmd.test) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -203,7 +203,7 @@ "?-name /value/? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?" ? {nsf::cmd::info parameter -context p1 $::handle1} \ - "-name -object-mixin:mixinreg,slot=::nx::Object::slot::object-mixin,slotset,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,slot=::nx::Object::slot::object-filter,slotset,0..n __initblock:cmd,optional,noleadingdash" + "-name -object-mixin:mixinreg,slot=::nx::Object::slot::object-mixin,slotset,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,slot=::nx::Object::slot::object-filter,slotset,0..n __initblock:cmd,optional,nodashalnum" ? {nsf::cmd::info args -context p1 $::handle1} \ "name object-mixin class object-filter __initblock" @@ -227,7 +227,7 @@ "/objectName/ ?-name /value/? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?" ? {nsf::cmd::info parameter -context Person $::handle2} \ - "objectName -name -object-mixin:mixinreg,slot=::nx::Object::slot::object-mixin,slotset,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,slot=::nx::Object::slot::object-filter,slotset,0..n __initblock:cmd,optional,noleadingdash" + "objectName -name -object-mixin:mixinreg,slot=::nx::Object::slot::object-mixin,slotset,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,slot=::nx::Object::slot::object-filter,slotset,0..n __initblock:cmd,optional,nodashalnum" ? {nsf::cmd::info args -context Person $::handle2} \ "objectName name object-mixin class object-filter __initblock" @@ -239,7 +239,7 @@ ? {nsf::cmd::info syntax -context Person $::handle3} \ "?-childof /value/? ?-name /value/? ?-object-mixin /mixinreg .../? ?-class /class/? ?-object-filter /filterreg .../? ?/__initblock/?" ? {nsf::cmd::info parameter -context Person $::handle3} \ - "-childof -name -object-mixin:mixinreg,slot=::nx::Object::slot::object-mixin,slotset,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,slot=::nx::Object::slot::object-filter,slotset,0..n __initblock:cmd,optional,noleadingdash" + "-childof -name -object-mixin:mixinreg,slot=::nx::Object::slot::object-mixin,slotset,0..n -class:class,alias,method=::nsf::methods::object::class -object-filter:filterreg,slot=::nx::Object::slot::object-filter,slotset,0..n __initblock:cmd,optional,nodashalnum" ? {nsf::cmd::info args -context Person $::handle3} \ "-childof name object-mixin class object-filter __initblock" Index: tests/parameters.test =================================================================== diff -u -N -r75383021cb9f2f2db883583779a02eef6f1801f5 -r896f9013e125e965474ea7fdbda099ca22b152c2 --- tests/parameters.test (.../parameters.test) (revision 75383021cb9f2f2db883583779a02eef6f1801f5) +++ tests/parameters.test (.../parameters.test) (revision 896f9013e125e965474ea7fdbda099ca22b152c2) @@ -6,7 +6,7 @@ set objectFilter "-object-filter:filterreg,slot=::nx::Object::slot::object-filter,slotset,0..n" set objectMixin "-object-mixin:mixinreg,slot=::nx::Object::slot::object-mixin,slotset,0..n" -set initBlock "__initblock:cmd,optional,noleadingdash" +set initBlock "__initblock:cmd,optional,nodashalnum" set filter "-filter:filterreg,slot=::nx::Class::slot::filter,slotset,method=class-filter,0..n" set ::trailer "$objectMixin -class:class,alias,method=::nsf::methods::object::class $objectFilter $initBlock"