| File: | d/tclobj.c |
| Warning: | line 104, column 32 Using a fixed address is not portable because that address will probably not be valid in all environments or platforms |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | |||
| 2 | * The contents of this file are subject to the Mozilla Public License | |||
| 3 | * Version 1.1 (the "License"); you may not use this file except in | |||
| 4 | * compliance with the License. You may obtain a copy of the License at | |||
| 5 | * http://mozilla.org/. | |||
| 6 | * | |||
| 7 | * Software distributed under the License is distributed on an "AS IS" | |||
| 8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See | |||
| 9 | * the License for the specific language governing rights and limitations | |||
| 10 | * under the License. | |||
| 11 | * | |||
| 12 | * The Original Code is AOLserver Code and related documentation | |||
| 13 | * distributed by AOL. | |||
| 14 | * | |||
| 15 | * The Initial Developer of the Original Code is America Online, | |||
| 16 | * Inc. Portions created by AOL are Copyright (C) 1999 America Online, | |||
| 17 | * Inc. All Rights Reserved. | |||
| 18 | * | |||
| 19 | * Alternatively, the contents of this file may be used under the terms | |||
| 20 | * of the GNU General Public License (the "GPL"), in which case the | |||
| 21 | * provisions of GPL are applicable instead of those above. If you wish | |||
| 22 | * to allow use of your version of this file only under the terms of the | |||
| 23 | * GPL and not to allow others to use your version of this file under the | |||
| 24 | * License, indicate your decision by deleting the provisions above and | |||
| 25 | * replace them with the notice and other provisions required by the GPL. | |||
| 26 | * If you do not delete the provisions above, a recipient may use your | |||
| 27 | * version of this file under either the License or the GPL. | |||
| 28 | */ | |||
| 29 | ||||
| 30 | ||||
| 31 | /* | |||
| 32 | * tclobj.c -- | |||
| 33 | * | |||
| 34 | * Helper routines for managing Tcl_Obj types. | |||
| 35 | */ | |||
| 36 | ||||
| 37 | #include "nsd.h" | |||
| 38 | ||||
| 39 | /* | |||
| 40 | * Local functions defined in this file. | |||
| 41 | */ | |||
| 42 | ||||
| 43 | static Tcl_UpdateStringProc UpdateStringOfAddr; | |||
| 44 | static Tcl_SetFromAnyProc SetAddrFromAny; | |||
| 45 | ||||
| 46 | /* | |||
| 47 | * Local variables defined in this file. | |||
| 48 | */ | |||
| 49 | ||||
| 50 | static const Tcl_ObjType addrType = { | |||
| 51 | "ns:addr", | |||
| 52 | NULL((void*)0), | |||
| 53 | NULL((void*)0), | |||
| 54 | UpdateStringOfAddr, | |||
| 55 | SetAddrFromAny | |||
| 56 | }; | |||
| 57 | ||||
| 58 | static const Tcl_ObjType *byteArrayTypePtr; /* For NsTclObjIsByteArray(). */ | |||
| 59 | static const Tcl_ObjType *properByteArrayTypePtr; /* For NsTclObjIsByteArray(). */ | |||
| 60 | ||||
| 61 | /* | |||
| 62 | *---------------------------------------------------------------------- | |||
| 63 | * | |||
| 64 | * NsTclInitAddrType -- | |||
| 65 | * | |||
| 66 | * Initialize the Tcl address object type and cache the bytearray Tcl | |||
| 67 | * built-in type. Starting with Tcl 8.7a1, Tcl has actually two different | |||
| 68 | * types for bytearrays, the old "tclByteArrayType" and a new | |||
| 69 | * "properByteArrayType", where both have the string name "bytearray". | |||
| 70 | * | |||
| 71 | * Results: | |||
| 72 | * None. | |||
| 73 | * | |||
| 74 | * Side effects: | |||
| 75 | * None. | |||
| 76 | * | |||
| 77 | *---------------------------------------------------------------------- | |||
| 78 | */ | |||
| 79 | ||||
| 80 | void | |||
| 81 | NsTclInitAddrType(void) | |||
| 82 | { | |||
| 83 | Tcl_Obj *newByteObj; | |||
| 84 | ||||
| 85 | Tcl_RegisterObjType(&addrType); | |||
| 86 | /* | |||
| 87 | * Get the "tclByteArrayType" via name "bytearray". | |||
| 88 | */ | |||
| 89 | byteArrayTypePtr = Tcl_GetObjType("bytearray"); | |||
| 90 | ||||
| 91 | /* | |||
| 92 | * Get the "properByteArrayType" via a TclObj. | |||
| 93 | * In versions before Tcl 8.7, both values will be the same. | |||
| 94 | */ | |||
| 95 | newByteObj = Tcl_NewByteArrayObj(NULL((void*)0), 0); | |||
| 96 | properByteArrayTypePtr = newByteObj->typePtr; | |||
| 97 | if (properByteArrayTypePtr == byteArrayTypePtr) { | |||
| ||||
| 98 | /* | |||
| 99 | * When both values are the same, we are in a Tcl version before 8.7, | |||
| 100 | * where we have no properByteArrayTypePtr. So set it to an invalid | |||
| 101 | * value to avoid potential confusions. Without this stunt, we would | |||
| 102 | * need several ifdefs. | |||
| 103 | */ | |||
| 104 | properByteArrayTypePtr = (Tcl_ObjType *)INT2PTR(0xffffff)((void *)(intptr_t)(0xffffff)); | |||
| ||||
| 105 | } | |||
| 106 | Tcl_DecrRefCount(newByteObj)do { Tcl_Obj *_objPtr = (newByteObj); if (_objPtr->refCount -- <= 1) { TclFreeObj(_objPtr); } } while(0); | |||
| 107 | } | |||
| 108 | ||||
| 109 | ||||
| 110 | /* | |||
| 111 | *---------------------------------------------------------------------- | |||
| 112 | * | |||
| 113 | * Ns_TclResetObjType -- | |||
| 114 | * | |||
| 115 | * Reset the given Tcl_Obj type, freeing any type specific | |||
| 116 | * internal representation. The new Tcl_Obj type might be NULL. | |||
| 117 | * | |||
| 118 | * Results: | |||
| 119 | * None. | |||
| 120 | * | |||
| 121 | * Side effects: | |||
| 122 | * Depends on object type. | |||
| 123 | * | |||
| 124 | *---------------------------------------------------------------------- | |||
| 125 | */ | |||
| 126 | ||||
| 127 | void | |||
| 128 | Ns_TclResetObjType(Tcl_Obj *objPtr, const Tcl_ObjType *newTypePtr) | |||
| 129 | { | |||
| 130 | const Tcl_ObjType *typePtr; | |||
| 131 | ||||
| 132 | NS_NONNULL_ASSERT(objPtr != NULL)((void) (0)); | |||
| 133 | ||||
| 134 | typePtr = objPtr->typePtr; | |||
| 135 | if (typePtr != NULL((void*)0) && typePtr->freeIntRepProc != NULL((void*)0)) { | |||
| 136 | (*typePtr->freeIntRepProc)(objPtr); | |||
| 137 | } | |||
| 138 | objPtr->typePtr = newTypePtr; | |||
| 139 | } | |||
| 140 | ||||
| 141 | ||||
| 142 | /* | |||
| 143 | *---------------------------------------------------------------------- | |||
| 144 | * | |||
| 145 | * Ns_TclSetTwoPtrValue -- | |||
| 146 | * | |||
| 147 | * Reset the given objects type and values, freeing any existing | |||
| 148 | * internal rep. | |||
| 149 | * | |||
| 150 | * Results: | |||
| 151 | * None. | |||
| 152 | * | |||
| 153 | * Side effects: | |||
| 154 | * Depends on object type. | |||
| 155 | * | |||
| 156 | *---------------------------------------------------------------------- | |||
| 157 | */ | |||
| 158 | ||||
| 159 | void | |||
| 160 | Ns_TclSetTwoPtrValue(Tcl_Obj *objPtr, const Tcl_ObjType *newTypePtr, | |||
| 161 | void *ptr1, void *ptr2) | |||
| 162 | { | |||
| 163 | NS_NONNULL_ASSERT(objPtr != NULL)((void) (0)); | |||
| 164 | ||||
| 165 | Ns_TclResetObjType(objPtr, newTypePtr); | |||
| 166 | objPtr->internalRep.twoPtrValue.ptr1 = ptr1; | |||
| 167 | objPtr->internalRep.twoPtrValue.ptr2 = ptr2; | |||
| 168 | } | |||
| 169 | ||||
| 170 | ||||
| 171 | /* | |||
| 172 | *---------------------------------------------------------------------- | |||
| 173 | * | |||
| 174 | * Ns_TclSetOtherValuePtr -- | |||
| 175 | * | |||
| 176 | * Reset the given objects type and value, freeing any existing | |||
| 177 | * internal rep. | |||
| 178 | * | |||
| 179 | * Results: | |||
| 180 | * None. | |||
| 181 | * | |||
| 182 | * Side effects: | |||
| 183 | * Depends on object type. | |||
| 184 | * | |||
| 185 | *---------------------------------------------------------------------- | |||
| 186 | */ | |||
| 187 | ||||
| 188 | void | |||
| 189 | Ns_TclSetOtherValuePtr(Tcl_Obj *objPtr, const Tcl_ObjType *newTypePtr, void *value) | |||
| 190 | { | |||
| 191 | NS_NONNULL_ASSERT(objPtr != NULL)((void) (0)); | |||
| 192 | NS_NONNULL_ASSERT(newTypePtr != NULL)((void) (0)); | |||
| 193 | NS_NONNULL_ASSERT(value != NULL)((void) (0)); | |||
| 194 | ||||
| 195 | Ns_TclResetObjType(objPtr, newTypePtr); | |||
| 196 | objPtr->internalRep.otherValuePtr = value; | |||
| 197 | } | |||
| 198 | ||||
| 199 | ||||
| 200 | /* | |||
| 201 | *---------------------------------------------------------------------- | |||
| 202 | * | |||
| 203 | * Ns_TclSetStringRep -- | |||
| 204 | * | |||
| 205 | * Copy length bytes and set objects string rep. The objects | |||
| 206 | * existing string rep *must* have already been freed. Tcl uses | |||
| 207 | * as well "int" and not "size" (internally and via interface) | |||
| 208 | * | |||
| 209 | * Results: | |||
| 210 | * None. | |||
| 211 | * | |||
| 212 | * Side effects: | |||
| 213 | * Memory is allocated. | |||
| 214 | * | |||
| 215 | *---------------------------------------------------------------------- | |||
| 216 | */ | |||
| 217 | ||||
| 218 | void | |||
| 219 | Ns_TclSetStringRep(Tcl_Obj *objPtr, const char *bytes, int length) | |||
| 220 | { | |||
| 221 | NS_NONNULL_ASSERT(objPtr != NULL)((void) (0)); | |||
| 222 | NS_NONNULL_ASSERT(bytes != NULL)((void) (0)); | |||
| 223 | ||||
| 224 | if (length < 1) { | |||
| 225 | length = (int)strlen(bytes); | |||
| 226 | } | |||
| 227 | objPtr->length = length; | |||
| 228 | objPtr->bytes = ckalloc((unsigned) length + 1u)((void *) Tcl_Alloc((unsigned)((unsigned) length + 1u))); | |||
| 229 | memcpy(objPtr->bytes, bytes, (size_t) length + 1u); | |||
| 230 | } | |||
| 231 | ||||
| 232 | ||||
| 233 | ||||
| 234 | /* | |||
| 235 | *---------------------------------------------------------------------- | |||
| 236 | * | |||
| 237 | * Ns_TclSetFromAnyError -- | |||
| 238 | * | |||
| 239 | * This procedure is registered as the setFromAnyProc for an | |||
| 240 | * object type when it doesn't make sense to generate its internal | |||
| 241 | * form from the string representation alone. | |||
| 242 | * | |||
| 243 | * Results: | |||
| 244 | * The return value is always TCL_ERROR, and an error message is | |||
| 245 | * left in interp's result if interp isn't NULL. | |||
| 246 | * | |||
| 247 | * Side effects: | |||
| 248 | * None. | |||
| 249 | * | |||
| 250 | *---------------------------------------------------------------------- | |||
| 251 | */ | |||
| 252 | ||||
| 253 | int | |||
| 254 | Ns_TclSetFromAnyError(Tcl_Interp *interp, Tcl_Obj *UNUSED(objPtr)UNUSED_objPtr __attribute__((__unused__))) | |||
| 255 | { | |||
| 256 | Tcl_AppendToObj(Tcl_GetObjResult(interp), | |||
| 257 | "can't convert value to requested type except via prescribed API", | |||
| 258 | -1); | |||
| 259 | return TCL_ERROR1; | |||
| 260 | } | |||
| 261 | ||||
| 262 | ||||
| 263 | /* | |||
| 264 | *---------------------------------------------------------------------- | |||
| 265 | * | |||
| 266 | * Ns_TclGetAddrFromObj -- | |||
| 267 | * | |||
| 268 | * Return the internal pointer of an address Tcl_Obj. | |||
| 269 | * | |||
| 270 | * Results: | |||
| 271 | * TCL_OK or TCL_ERROR if conversion failed or not the correct type. | |||
| 272 | * | |||
| 273 | * Side effects: | |||
| 274 | * Object may be converted to address type. | |||
| 275 | * | |||
| 276 | *---------------------------------------------------------------------- | |||
| 277 | */ | |||
| 278 | ||||
| 279 | int | |||
| 280 | Ns_TclGetAddrFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, | |||
| 281 | const char *type, void **addrPtrPtr) | |||
| 282 | { | |||
| 283 | int result = TCL_OK0; | |||
| 284 | ||||
| 285 | NS_NONNULL_ASSERT(objPtr != NULL)((void) (0)); | |||
| 286 | NS_NONNULL_ASSERT(type != NULL)((void) (0)); | |||
| 287 | NS_NONNULL_ASSERT(addrPtrPtr != NULL)((void) (0)); | |||
| 288 | ||||
| 289 | if (Tcl_ConvertToType(interp, objPtr, &addrType) != TCL_OK0) { | |||
| 290 | result = TCL_ERROR1; | |||
| 291 | ||||
| 292 | } else if (objPtr->internalRep.twoPtrValue.ptr1 != (void *) type) { | |||
| 293 | Ns_TclPrintfResult(interp, "incorrect type: %s", Tcl_GetString(objPtr)); | |||
| 294 | result = TCL_ERROR1; | |||
| 295 | ||||
| 296 | } else { | |||
| 297 | *addrPtrPtr = objPtr->internalRep.twoPtrValue.ptr2; | |||
| 298 | } | |||
| 299 | ||||
| 300 | return result; | |||
| 301 | } | |||
| 302 | ||||
| 303 | ||||
| 304 | /* | |||
| 305 | *---------------------------------------------------------------------- | |||
| 306 | * | |||
| 307 | * Ns_TclSetAddrObj -- | |||
| 308 | * | |||
| 309 | * Convert the given object to the ns:addr type. | |||
| 310 | * | |||
| 311 | * Results: | |||
| 312 | * None. | |||
| 313 | * | |||
| 314 | * Side effects: | |||
| 315 | * None. | |||
| 316 | * | |||
| 317 | *---------------------------------------------------------------------- | |||
| 318 | */ | |||
| 319 | ||||
| 320 | void | |||
| 321 | Ns_TclSetAddrObj(Tcl_Obj *objPtr, const char *type, void *addr) | |||
| 322 | { | |||
| 323 | NS_NONNULL_ASSERT(objPtr != NULL)((void) (0)); | |||
| 324 | NS_NONNULL_ASSERT(type != NULL)((void) (0)); | |||
| 325 | NS_NONNULL_ASSERT(addr != NULL)((void) (0)); | |||
| 326 | ||||
| 327 | if (Tcl_IsShared(objPtr)((objPtr)->refCount > 1)) { | |||
| 328 | Tcl_Panic("Ns_TclSetAddrObj called with shared object"); | |||
| 329 | } | |||
| 330 | Ns_TclSetTwoPtrValue(objPtr, &addrType, (void *) type, addr); | |||
| 331 | Tcl_InvalidateStringRep(objPtr); | |||
| 332 | } | |||
| 333 | ||||
| 334 | ||||
| 335 | /* | |||
| 336 | *---------------------------------------------------------------------- | |||
| 337 | * | |||
| 338 | * Ns_TclGetOpaqueFromObj -- | |||
| 339 | * | |||
| 340 | * Get the internal pointer of an address Tcl_Obj. | |||
| 341 | * | |||
| 342 | * Results: | |||
| 343 | * TCL_OK or TCL_ERROR if object was not of the ns:addr type. | |||
| 344 | * | |||
| 345 | * Side effects: | |||
| 346 | * None. | |||
| 347 | * | |||
| 348 | *---------------------------------------------------------------------- | |||
| 349 | */ | |||
| 350 | ||||
| 351 | int | |||
| 352 | Ns_TclGetOpaqueFromObj(const Tcl_Obj *objPtr, const char *type, void **addrPtrPtr) | |||
| 353 | { | |||
| 354 | int result = TCL_OK0; | |||
| 355 | ||||
| 356 | NS_NONNULL_ASSERT(objPtr != NULL)((void) (0)); | |||
| 357 | NS_NONNULL_ASSERT(type != NULL)((void) (0)); | |||
| 358 | NS_NONNULL_ASSERT(addrPtrPtr != NULL)((void) (0)); | |||
| 359 | ||||
| 360 | if (objPtr->typePtr == &addrType | |||
| 361 | && objPtr->internalRep.twoPtrValue.ptr1 == (void *) type) { | |||
| 362 | *addrPtrPtr = objPtr->internalRep.twoPtrValue.ptr2; | |||
| 363 | } else { | |||
| 364 | char s[33] = {0}; | |||
| 365 | uintptr_t t = 0u, a = 0u; | |||
| 366 | ||||
| 367 | if ((sscanf(Tcl_GetString((Tcl_Obj *) objPtr), "t%20" SCNxPTR"l" "x" "-a%20" SCNxPTR"l" "x" "-%32s", &t, &a, s) != 3) | |||
| 368 | || (strcmp(s, type) != 0) | |||
| 369 | || (t != (uintptr_t)type) | |||
| 370 | ) { | |||
| 371 | result = TCL_ERROR1; | |||
| 372 | } else { | |||
| 373 | *addrPtrPtr = (void *)a; | |||
| 374 | } | |||
| 375 | } | |||
| 376 | ||||
| 377 | return result; | |||
| 378 | } | |||
| 379 | ||||
| 380 | ||||
| 381 | /* | |||
| 382 | *---------------------------------------------------------------------- | |||
| 383 | * | |||
| 384 | * Ns_TclSetOpaqueObj -- | |||
| 385 | * | |||
| 386 | * Convert the given object to the ns:addr type without | |||
| 387 | * invalidating the current string rep. It is OK if the object | |||
| 388 | * is shared. | |||
| 389 | * | |||
| 390 | * Results: | |||
| 391 | * None. | |||
| 392 | * | |||
| 393 | * Side effects: | |||
| 394 | * None. | |||
| 395 | * | |||
| 396 | *---------------------------------------------------------------------- | |||
| 397 | */ | |||
| 398 | ||||
| 399 | void | |||
| 400 | Ns_TclSetOpaqueObj(Tcl_Obj *objPtr, const char *type, void *addr) | |||
| 401 | { | |||
| 402 | NS_NONNULL_ASSERT(objPtr != NULL)((void) (0)); | |||
| 403 | NS_NONNULL_ASSERT(type != NULL)((void) (0)); | |||
| 404 | ||||
| 405 | Ns_TclSetTwoPtrValue(objPtr, &addrType, (void *) type, addr); | |||
| 406 | } | |||
| 407 | ||||
| 408 | ||||
| 409 | /* | |||
| 410 | *---------------------------------------------------------------------- | |||
| 411 | * | |||
| 412 | * NsTclObjIsByteArray -- | |||
| 413 | * | |||
| 414 | * Does the given Tcl_Obj have a byte array internal rep? The | |||
| 415 | * function determines when it is safe to interpret a string as a | |||
| 416 | * byte array directly. | |||
| 417 | * | |||
| 418 | * Results: | |||
| 419 | * Boolean. | |||
| 420 | * | |||
| 421 | * Side effects: | |||
| 422 | * None. | |||
| 423 | * | |||
| 424 | *---------------------------------------------------------------------- | |||
| 425 | */ | |||
| 426 | ||||
| 427 | bool_Bool | |||
| 428 | NsTclObjIsByteArray(const Tcl_Obj *objPtr) | |||
| 429 | { | |||
| 430 | bool_Bool result; | |||
| 431 | ||||
| 432 | NS_NONNULL_ASSERT(objPtr != NULL)((void) (0)); | |||
| 433 | ||||
| 434 | /* | |||
| 435 | * This function resembles the tclInt.h function for testing pure byte | |||
| 436 | * arrays. In versions up to at least on Tcl 8.6, a pure byte array was | |||
| 437 | * defined as a byte array without a string rep. Starting with Tcl | |||
| 438 | * 8.7a1, Tcl has introduced the properByteArrayTypePtr, which allows as | |||
| 439 | * well a string rep. | |||
| 440 | */ | |||
| 441 | #ifdef NS_TCL_PRE87 | |||
| 442 | result = ((objPtr->typePtr == byteArrayTypePtr) && (objPtr->bytes == NULL((void*)0))); | |||
| 443 | #else | |||
| 444 | result = (objPtr->typePtr == properByteArrayTypePtr); | |||
| 445 | #endif | |||
| 446 | ||||
| 447 | #if 0 | |||
| 448 | fprintf(stderr, "NsTclObjIsByteArray? %p type %p proper %d old %d bytes %p name %s => %d\n",__fprintf_chk (stderr, 2 - 1, "NsTclObjIsByteArray? %p type %p proper %d old %d bytes %p name %s => %d\n" , (void*)objPtr, (void*)(objPtr->typePtr), (objPtr->typePtr == properByteArrayTypePtr), (objPtr->typePtr == byteArrayTypePtr ), (void*)(objPtr->bytes), objPtr->typePtr == ((void*)0 ) ? "string" : objPtr->typePtr->name, result) | |||
| 449 | (void*)objPtr,__fprintf_chk (stderr, 2 - 1, "NsTclObjIsByteArray? %p type %p proper %d old %d bytes %p name %s => %d\n" , (void*)objPtr, (void*)(objPtr->typePtr), (objPtr->typePtr == properByteArrayTypePtr), (objPtr->typePtr == byteArrayTypePtr ), (void*)(objPtr->bytes), objPtr->typePtr == ((void*)0 ) ? "string" : objPtr->typePtr->name, result) | |||
| 450 | (void*)(objPtr->typePtr),__fprintf_chk (stderr, 2 - 1, "NsTclObjIsByteArray? %p type %p proper %d old %d bytes %p name %s => %d\n" , (void*)objPtr, (void*)(objPtr->typePtr), (objPtr->typePtr == properByteArrayTypePtr), (objPtr->typePtr == byteArrayTypePtr ), (void*)(objPtr->bytes), objPtr->typePtr == ((void*)0 ) ? "string" : objPtr->typePtr->name, result) | |||
| 451 | (objPtr->typePtr == properByteArrayTypePtr),__fprintf_chk (stderr, 2 - 1, "NsTclObjIsByteArray? %p type %p proper %d old %d bytes %p name %s => %d\n" , (void*)objPtr, (void*)(objPtr->typePtr), (objPtr->typePtr == properByteArrayTypePtr), (objPtr->typePtr == byteArrayTypePtr ), (void*)(objPtr->bytes), objPtr->typePtr == ((void*)0 ) ? "string" : objPtr->typePtr->name, result) | |||
| 452 | (objPtr->typePtr == byteArrayTypePtr),__fprintf_chk (stderr, 2 - 1, "NsTclObjIsByteArray? %p type %p proper %d old %d bytes %p name %s => %d\n" , (void*)objPtr, (void*)(objPtr->typePtr), (objPtr->typePtr == properByteArrayTypePtr), (objPtr->typePtr == byteArrayTypePtr ), (void*)(objPtr->bytes), objPtr->typePtr == ((void*)0 ) ? "string" : objPtr->typePtr->name, result) | |||
| 453 | (void*)(objPtr->bytes),__fprintf_chk (stderr, 2 - 1, "NsTclObjIsByteArray? %p type %p proper %d old %d bytes %p name %s => %d\n" , (void*)objPtr, (void*)(objPtr->typePtr), (objPtr->typePtr == properByteArrayTypePtr), (objPtr->typePtr == byteArrayTypePtr ), (void*)(objPtr->bytes), objPtr->typePtr == ((void*)0 ) ? "string" : objPtr->typePtr->name, result) | |||
| 454 | objPtr->typePtr == NULL ? "string" : objPtr->typePtr->name,__fprintf_chk (stderr, 2 - 1, "NsTclObjIsByteArray? %p type %p proper %d old %d bytes %p name %s => %d\n" , (void*)objPtr, (void*)(objPtr->typePtr), (objPtr->typePtr == properByteArrayTypePtr), (objPtr->typePtr == byteArrayTypePtr ), (void*)(objPtr->bytes), objPtr->typePtr == ((void*)0 ) ? "string" : objPtr->typePtr->name, result) | |||
| 455 | result)__fprintf_chk (stderr, 2 - 1, "NsTclObjIsByteArray? %p type %p proper %d old %d bytes %p name %s => %d\n" , (void*)objPtr, (void*)(objPtr->typePtr), (objPtr->typePtr == properByteArrayTypePtr), (objPtr->typePtr == byteArrayTypePtr ), (void*)(objPtr->bytes), objPtr->typePtr == ((void*)0 ) ? "string" : objPtr->typePtr->name, result); | |||
| 456 | #endif | |||
| 457 | ||||
| 458 | return result; | |||
| 459 | } | |||
| 460 | ||||
| 461 | ||||
| 462 | /* | |||
| 463 | *---------------------------------------------------------------------- | |||
| 464 | * | |||
| 465 | * NsTclObjIsEncodedByteArray -- | |||
| 466 | * | |||
| 467 | * This function is true, when we encounter a bytearray with a string | |||
| 468 | * rep. In this cases, it is necessary to use Tcl_UtfToExternalDString() | |||
| 469 | * to obtain the proper byte array. | |||
| 470 | * | |||
| 471 | * Results: | |||
| 472 | * Boolean. | |||
| 473 | * | |||
| 474 | * Side effects: | |||
| 475 | * None. | |||
| 476 | * | |||
| 477 | *---------------------------------------------------------------------- | |||
| 478 | */ | |||
| 479 | ||||
| 480 | bool_Bool | |||
| 481 | NsTclObjIsEncodedByteArray(const Tcl_Obj *objPtr) | |||
| 482 | { | |||
| 483 | NS_NONNULL_ASSERT(objPtr != NULL)((void) (0)); | |||
| 484 | ||||
| 485 | return ((objPtr->typePtr == byteArrayTypePtr) && (objPtr->bytes != NULL((void*)0))); | |||
| 486 | } | |||
| 487 | ||||
| 488 | ||||
| 489 | /* | |||
| 490 | *---------------------------------------------------------------------- | |||
| 491 | * | |||
| 492 | * UpdateStringOfAddr -- | |||
| 493 | * | |||
| 494 | * Update the string representation for an address object. | |||
| 495 | * Note: This procedure does not free an existing old string rep | |||
| 496 | * so storage will be lost if this has not already been done. | |||
| 497 | * | |||
| 498 | * Results: | |||
| 499 | * None. | |||
| 500 | * | |||
| 501 | * Side effects: | |||
| 502 | * None. | |||
| 503 | * | |||
| 504 | *---------------------------------------------------------------------- | |||
| 505 | */ | |||
| 506 | ||||
| 507 | static void | |||
| 508 | UpdateStringOfAddr(Tcl_Obj *objPtr) | |||
| 509 | { | |||
| 510 | const char *type = objPtr->internalRep.twoPtrValue.ptr1; | |||
| 511 | const void *addr = objPtr->internalRep.twoPtrValue.ptr2; | |||
| 512 | char buf[128]; | |||
| 513 | int len; | |||
| 514 | ||||
| 515 | len = snprintf(buf, sizeof(buf), "t%" PRIxPTR "-a%" PRIxPTR "-%s", (uintptr_t)type, (uintptr_t)addr, type)__builtin___snprintf_chk (buf, sizeof(buf), 2 - 1, __builtin_object_size (buf, 2 > 1), "t%" "l" "x" "-a%" "l" "x" "-%s", (uintptr_t )type, (uintptr_t)addr, type); | |||
| 516 | Ns_TclSetStringRep(objPtr, buf, len); | |||
| 517 | } | |||
| 518 | ||||
| 519 | ||||
| 520 | /* | |||
| 521 | *---------------------------------------------------------------------- | |||
| 522 | * | |||
| 523 | * SetAddrFromAny -- | |||
| 524 | * | |||
| 525 | * Attempt to generate an address internal form for the Tcl_Obj. | |||
| 526 | * | |||
| 527 | * Results: | |||
| 528 | * The return value is a standard Tcl result. If an error occurs | |||
| 529 | * during conversion, an error message is left in the interpreter's | |||
| 530 | * result unless interp is NULL. | |||
| 531 | * | |||
| 532 | * Side effects: | |||
| 533 | * None. | |||
| 534 | * | |||
| 535 | *---------------------------------------------------------------------- | |||
| 536 | */ | |||
| 537 | ||||
| 538 | static int | |||
| 539 | SetAddrFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) | |||
| 540 | { | |||
| 541 | int result = TCL_OK0; | |||
| 542 | void *type, *addr; | |||
| 543 | char *chars; | |||
| 544 | ||||
| 545 | chars = Tcl_GetString(objPtr); | |||
| 546 | if ((sscanf(chars, "t%20p-a%20p", &type, &addr) != 2) | |||
| 547 | || (type == NULL((void*)0)) | |||
| 548 | || (addr == NULL((void*)0)) | |||
| 549 | ) { | |||
| 550 | Ns_TclPrintfResult(interp, "invalid address \"%s\"", chars); | |||
| 551 | result = TCL_ERROR1; | |||
| 552 | } else { | |||
| 553 | Ns_TclSetTwoPtrValue(objPtr, &addrType, type, addr); | |||
| 554 | } | |||
| 555 | ||||
| 556 | return result; | |||
| 557 | } | |||
| 558 | ||||
| 559 | ||||
| 560 | /* | |||
| 561 | * Local Variables: | |||
| 562 | * mode: c | |||
| 563 | * c-basic-offset: 4 | |||
| 564 | * fill-column: 78 | |||
| 565 | * indent-tabs-mode: nil | |||
| 566 | * End: | |||
| 567 | */ |