I'm running tclkit on a Linux ppc64 machine. When I do a mk::get, I always get row 0's data regardless of the index requested. The mk1basic.3 unit test illustrates the problem.
bmueller@power6-1:/usr0/bmueller/tclkit.orig/src/mk/tcl/test> ../../../../tclkit-power6-1 application-specific initialization failed: couldn't open "setup.tcl": no such file or directory % mk::file open db db % mk::view layout db.a {s i:I} db.a % set n [mk::row append db.a s one i 1] db.a!0 % mk::get $n s one i 1 % set n [mk::row append db.a s two i 2] db.a!1 % mk::get $n s two i 2 % mk::view size db.a 2 % mk::view size db.a 1 1 % mk::get db.a!0 s one i 1 % mk::get db.a!1 s one i 1
On a system that works correctly, mk::get db.a!1 should return "view index is out of range"
The source of the problem is the AsIndex() function which casts a address of a void* struct member to a int&. On a 64 bit platform, a void* is 8 bytes and an int is 4 bytes. The pointer to the struct member on big-endian platforms points to the 4 high order bytes not the 4 low order bytes. The high order bytes in the example above are all 0x00 so y = AsIndex(obj) is always zero.
diff -Nur tclkit.orig/src/mk/tcl/mk4tcl.cpp tclkit/src/mk/tcl//mk4tcl.cpp --- tclkit.orig/src/mk/tcl/mk4tcl.cpp 2007-06-18 17:05:24.000000000 -0400 +++ tclkit/src/mk/tcl//mk4tcl.cpp 2009-02-11 14:29:14.000000000 -0500 @@ -1043,11 +1043,11 @@
return *(MkPath*)obj_->internalRep.twoPtrValue.ptr2; }
-int &AsIndex(Tcl_Obj *obj_) { +long &AsIndex(Tcl_Obj *obj_) {
d4_assert(obj_->typePtr == &mkCursorType); d4_assert(obj_->internalRep.twoPtrValue.ptr2 != 0);
- return (int &)obj_->internalRep.twoPtrValue.ptr1; + return (long &)obj_->internalRep.twoPtrValue.ptr1;
}
static void FreeCursorInternalRep(Tcl_Obj *cursorPtr) {
@@ -1455,7 +1455,7 @@
return AsPath(obj_)._view; }
-int &MkTcl::changeIndex(Tcl_Obj *obj_) { +long &MkTcl::changeIndex(Tcl_Obj *obj_) {
SetCursorFromAny(interp, obj_); Tcl_InvalidateStringRep(obj_); return AsIndex(obj_);
diff -Nur tclkit.orig/src/mk/tcl/mk4tcl.h tclkit/src/mk/tcl//mk4tcl.h --- tclkit.orig/src/mk/tcl/mk4tcl.h 2007-06-15 19:26:40.000000000 -0400 +++ tclkit/src/mk/tcl//mk4tcl.h 2009-02-11 14:29:29.000000000 -0500 @@ -274,7 +274,7 @@
// Cursors in Tcl are implemented as a pointer to an MkPath plus an index. MkPath &AsPath(Tcl_Obj *obj_);
-int &AsIndex(Tcl_Obj *obj_); +long &AsIndex(Tcl_Obj *obj_);
int SetCursorFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); // 24nov02: added to support releasing mutex lock during loop eval's
@@ -367,7 +367,7 @@
~MkTcl();
c4_View asView(Tcl_Obj *obj_);
- int &changeIndex(Tcl_Obj *obj_); + long &changeIndex(Tcl_Obj *obj_);
c4_RowRef asRowRef(Tcl_Obj *obj_, int type_ = kExistingRow);
int GetCmd();
int SetValues(const c4_RowRef &row_, int objc, Tcl_Obj *const * objv);
- 2009-02-11 Brian Mueller
Created
