Index: xotcl/ChangeLog =================================================================== diff -u -rf58919af57edbcf2e5a65a143618ab5add3c930a -r727f20fd9df6aac95b2dc4bbf510830ecc9ddb20 --- xotcl/ChangeLog (.../ChangeLog) (revision f58919af57edbcf2e5a65a143618ab5add3c930a) +++ xotcl/ChangeLog (.../ChangeLog) (revision 727f20fd9df6aac95b2dc4bbf510830ecc9ddb20) @@ -1,4 +1,11 @@ 2004-08-01 Gustaf.Neumann@wu-wien.ac.at + * changes to forward and instforward: + providing positional arguments for the forwarder. It is now + possible to prefix the arguments with "%@POS ", where + POS can be a positive or negative number or "end". A negative + offset can be used to address relative to the end + +2004-08-01 Gustaf.Neumann@wu-wien.ac.at * xotcl.c: calling __unknown when an object with an unknown parent namespace is called (for handling nested object classes in Zoran's ttrace package) Index: xotcl/generic/xotcl.c =================================================================== diff -u -rf58919af57edbcf2e5a65a143618ab5add3c930a -r727f20fd9df6aac95b2dc4bbf510830ecc9ddb20 --- xotcl/generic/xotcl.c (.../xotcl.c) (revision f58919af57edbcf2e5a65a143618ab5add3c930a) +++ xotcl/generic/xotcl.c (.../xotcl.c) (revision 727f20fd9df6aac95b2dc4bbf510830ecc9ddb20) @@ -1,4 +1,4 @@ -/* $Id: xotcl.c,v 1.20 2004/08/02 22:17:22 neumann Exp $ +/* $Id: xotcl.c,v 1.21 2004/08/03 23:09:14 neumann Exp $ * * XOTcl - Extended OTcl * @@ -7399,15 +7399,48 @@ #endif static int -forwardArg(Tcl_Interp *in, int objc, Tcl_Obj *o, forwardCmdClientData *tcd, - Tcl_Obj *CONST objv[], Tcl_Obj **out, Tcl_Obj **freeList, int *inputarg) { - char *element = ObjStr(o); - if (*element == '%') { - char c = *(++element); +forwardArg(Tcl_Interp *in, int objc, Tcl_Obj *CONST objv[], + Tcl_Obj *o, forwardCmdClientData *tcd, Tcl_Obj **out, + Tcl_Obj **freeList, int *inputarg, int *mapvalue) { + char *element = ObjStr(o), *p = element; + char c = *element; + int totalargs = objc + tcd->nr_args - 1; + + if (c == '%' && *(element+1) == '@') { + char *remainder = NULL; + long pos; + element += 2; + pos = strtol(element,&remainder,0); + /*fprintf(stderr,"strtol('%s) returned %ld '%s'\n",element,pos,remainder);*/ + if (element == remainder && *element == 'e' && !strncmp(element,"end",3)) { + pos = totalargs; + remainder += 3; + } + if (element == remainder || abs(pos) > totalargs) { + return XOTclVarErrMsg(in, "forward: invalid index specified in argument ", + ObjStr(o), (char *)NULL); + } + if (!remainder || *remainder != ' ') { + return XOTclVarErrMsg(in, "forward: invaild syntax in '", ObjStr(o), + "' use: %@ ",(char *)NULL); + } + + element = ++remainder; + if (pos<0) pos = totalargs + pos; + /*fprintf(stderr,"remainder = '%s' pos = %ld\n",remainder,pos);*/ + *mapvalue = pos; + element = remainder; + c = *element; + } + /*fprintf(stderr,"c==%c element = '%s'\n",c,element);*/ + if (c == '%') { + c = *++element; + /*fprintf(stderr,"...c==%c element = '%s'\n",c,element);*/ if (c == 's' && !strcmp(element,"self")) { *out = tcd->obj->cmdName; } else if (c == 'p' && !strcmp(element,"proc")) { *out = objv[0]; + /*fprintf(stderr,"+++ %%proc returns '%s'\n", ObjStr(objv[0]));*/ } else if (c == '1' && (*(element+1) == '\0')) { int nrargs = objc-1; /*fprintf(stderr, " nrargs=%d, subcommands=%d inputarg=%d, objc=%d\n", @@ -7437,9 +7470,16 @@ goto add_to_freelist; } } else { - *out = o; + if (p==element) + *out = o; + else { + Tcl_Obj *newarg = Tcl_NewStringObj(element,-1); + *out = newarg; + goto add_to_freelist; + } } return TCL_OK; + add_to_freelist: if (!*freeList) { *freeList = Tcl_NewListObj(1, out); @@ -7458,9 +7498,12 @@ { Tcl_Obj **ov, *freeList=NULL; - DEFINE_NEW_TCL_OBJS_ON_STACK(objc + tcd->nr_args + 3, OV); + int totalargs = objc + tcd->nr_args + 3; + int objvmap[totalargs]; + DEFINE_NEW_TCL_OBJS_ON_STACK(totalargs, OV); ov = &OV[1]; + for (j=0; jcs.top->currentFramePtr, @@ -7479,22 +7522,25 @@ #endif /* the first argument is always the command, to which we forward */ - - if ((result = forwardArg(in, objc, tcd->cmdName, tcd, objv, - &ov[outputarg++], &freeList, &inputarg)) != TCL_OK) { + + if ((result = forwardArg(in, objc, objv, tcd->cmdName, tcd, + &ov[outputarg], &freeList, &inputarg, + &objvmap[outputarg])) != TCL_OK) { if (freeList) {DECR_REF_COUNT(freeList);} return result; } + outputarg++; if (tcd->args) { /* copy argument list from definition */ Tcl_Obj **listElements; int nrElements; Tcl_ListObjGetElements(in, tcd->args, &nrElements, &listElements); - for (j=0; jpos) { + for(i=j; i>pos; i--) { + /*fprintf(stderr,"...moving right %d to %d\n",i-1,i);*/ + ov[i] = ov[i-1]; + objvmap[i] = objvmap[i-1]; + } + } else { + for(i=j; i %s\n",pos,ObjStr(tmp)); */ + ov[pos] = tmp; + objvmap[pos] = -1; + } + if (tcd->prefix) { /* prepend a prefix for the subcommands to avoid name clashes */ Tcl_Obj *methodName = Tcl_DuplicateObj(tcd->prefix); @@ -7524,7 +7603,7 @@ #if 0 for(j=0; j