Deutsch   English   Français   Italiano  
<vgru54$q1g9$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder2.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Kevin Walzer <kw@codebykevin.com>
Newsgroups: comp.lang.tcl
Subject: Values being overwritten in Tcl_HashTable
Date: Sun, 10 Nov 2024 22:37:07 -0500
Organization: A noiseless patient Spider
Lines: 182
Message-ID: <vgru54$q1g9$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Mon, 11 Nov 2024 04:37:08 +0100 (CET)
Injection-Info: dont-email.me; posting-host="4f904a8dfe047400e0aa44456831801e";
	logging-data="853513"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1+iTvFi3VXzZVKmMIVuY8K7ToG8vp3bGLw="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:ij1es5TAC7VGR4XyNlHxCeWuznk=
Content-Language: en-US
Bytes: 6066

I am trying to write mulitple key-value pairs to a Tcl_HashTable, but 
when I call  Tcl_SetObjResult(ip, Tcl_GetHashValue(hPtr2)), it reads the 
last value written to the hash table - even if that value is not 
associated with the key that I am using.

Is there a best practice I am missing here? I thought that differing 
keys would be tracked in the hash table and the Tcl_FindHashEntry call 
would return different data depending on the key.

Tcl_ResetResult does not change the result in the interpreter, which 
tells me the issue is with the table - calls to the key for "role" and 
"name" return the value for "name" - seems like the "role" value has 
been overwritten.

My C code is below. Any help is appreciated.

int
Tk_SetAccessibleRole(
		     TCL_UNUSED(void *),
		     Tcl_Interp *ip,		/* Current interpreter. */
		     int objc,			/* Number of arguments. */
		     Tcl_Obj *const objv[])	/* Argument objects. */
{	
   if (objc < 3) {
     Tcl_WrongNumArgs(ip, 1, objv, "window? role?");
     return TCL_ERROR;
   }
	
   Tk_Window win;
   char *role;
   Tcl_HashEntry *hPtr, *hPtr2;

   Tcl_HashTable *AccessibleAttributes;
   AccessibleAttributes = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
   Tcl_InitHashTable(AccessibleAttributes,TCL_STRING_KEYS);

   int isNew;
   win = Tk_NameToWindow(ip, Tcl_GetString(objv[1]), Tk_MainWindow(ip));
   if (win == NULL) {
     return TCL_ERROR;
   }

   /* Set accessible role for window.  */
   hPtr=Tcl_CreateHashEntry(TkAccessibilityObject, win, &isNew);

   Tcl_SetHashValue(hPtr, AccessibleAttributes);

   hPtr2 =  Tcl_CreateHashEntry(AccessibleAttributes, role, &isNew);
   if (!isNew) {
     Tcl_DecrRefCount(Tcl_GetHashValue(hPtr2));
   }
   Tcl_IncrRefCount(objv[2]);
   Tcl_SetHashValue(hPtr2, objv[2]);

   Tcl_SetObjResult(ip, Tcl_GetHashValue(hPtr2));
   return TCL_OK;
}


int
Tk_SetAccessibleName(
		     TCL_UNUSED(void *),
		     Tcl_Interp *ip,		/* Current interpreter. */
		     int objc,			/* Number of arguments. */
		     Tcl_Obj *const objv[])	/* Argument objects. */
{	
   if (objc < 3) {
     Tcl_WrongNumArgs(ip, 1, objv, "window? name?");
     return TCL_ERROR;
   }

   Tk_Window win;
   char *name;
   Tcl_HashEntry *hPtr, *hPtr2;
   int isNew;
   Tcl_HashTable *AccessibleAttributes;
	
   win = Tk_NameToWindow(ip, Tcl_GetString(objv[1]), Tk_MainWindow(ip));
   if (win == NULL) {
     return TCL_ERROR;
   }

   /* Set accessible name for window.  */

   hPtr=Tcl_FindHashEntry(TkAccessibilityObject, win);
   if (!hPtr) {
     Tcl_AppendResult(ip, "No table found", (char *) NULL);
     return TCL_ERROR;
   }

   AccessibleAttributes = Tcl_GetHashValue(hPtr);
   hPtr2 =  Tcl_CreateHashEntry(AccessibleAttributes, name, &isNew);
   if (!isNew) {
     Tcl_DecrRefCount(Tcl_GetHashValue(hPtr2));
   }
   Tcl_IncrRefCount(objv[2]);
   Tcl_SetHashValue(hPtr2, objv[2]);

   Tcl_SetObjResult(ip, Tcl_GetHashValue(hPtr2));
   return TCL_OK;
}

int
Tk_GetAccessibleRole(
		     TCL_UNUSED(void *),
		     Tcl_Interp *ip,		/* Current interpreter. */
		     int objc,			/* Number of arguments. */
		     Tcl_Obj *const objv[])	/* Argument objects. */
{	
   if (objc < 2) {
     Tcl_WrongNumArgs(ip, 1, objv, "window?");
     return TCL_ERROR;
   }
	
   Tk_Window win;
   char *role;
   Tcl_HashEntry *hPtr, *hPtr2;

   Tcl_HashTable *AccessibleAttributes;

   win = Tk_NameToWindow(ip, Tcl_GetString(objv[1]), Tk_MainWindow(ip));
   if (win == NULL) {
     return TCL_ERROR;
   }

   /* Get accessible role for window.  */
   hPtr=Tcl_FindHashEntry(TkAccessibilityObject, win);
   if (!hPtr) {
     Tcl_AppendResult(ip, "No table found", (char *) NULL);
     return TCL_ERROR;
   }
   AccessibleAttributes = Tcl_GetHashValue(hPtr);
   hPtr2=Tcl_FindHashEntry(AccessibleAttributes, (char*)  role);
   if (!hPtr2) {
     Tcl_AppendResult(ip, "No role found", (char *) NULL);
     return TCL_ERROR;
   }

   Tcl_SetObjResult(ip, Tcl_GetHashValue(hPtr2));
   return TCL_OK;
}

int
Tk_GetAccessibleName(
		     TCL_UNUSED(void *),
		     Tcl_Interp *ip,		/* Current interpreter. */
		     int objc,			/* Number of arguments. */
		     Tcl_Obj *const objv[])	/* Argument objects. */
{	
   if (objc < 2) {
     Tcl_WrongNumArgs(ip, 1, objv, "window?");
     return TCL_ERROR;
   }

   Tk_Window win;
   char *name;
   Tcl_HashEntry *hPtr, *hPtr2;

   Tcl_HashTable *AccessibleAttributes;

   win = Tk_NameToWindow(ip, Tcl_GetString(objv[1]), Tk_MainWindow(ip));
   if (win == NULL) {
     return TCL_ERROR;
   }

   /* Get accessible name for window.  */
   hPtr=Tcl_FindHashEntry(TkAccessibilityObject, win);
   if (!hPtr) {
     Tcl_AppendResult(ip, "No table found", (char *) NULL);
     return TCL_ERROR;
   }
   AccessibleAttributes = Tcl_GetHashValue(hPtr);
   hPtr2=Tcl_FindHashEntry(AccessibleAttributes, (char *) name);
   if (!hPtr2) {
     Tcl_AppendResult(ip, "No name found", (char *) NULL);
     return TCL_ERROR;
   }

   Tcl_SetObjResult(ip, Tcl_GetHashValue(hPtr2));
   return TCL_OK;
}
========== REMAINDER OF ARTICLE TRUNCATED ==========