| File: | src/Convert.c |
| Location: | line 410, column 22 |
| Description: | Dereference of null pointer |
| 1 | /*********************************************************** | |||
| 2 | Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved. | |||
| 3 | ||||
| 4 | Permission is hereby granted, free of charge, to any person obtaining a | |||
| 5 | copy of this software and associated documentation files (the "Software"), | |||
| 6 | to deal in the Software without restriction, including without limitation | |||
| 7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| 8 | and/or sell copies of the Software, and to permit persons to whom the | |||
| 9 | Software is furnished to do so, subject to the following conditions: | |||
| 10 | ||||
| 11 | The above copyright notice and this permission notice (including the next | |||
| 12 | paragraph) shall be included in all copies or substantial portions of the | |||
| 13 | Software. | |||
| 14 | ||||
| 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| 18 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 21 | DEALINGS IN THE SOFTWARE. | |||
| 22 | ||||
| 23 | Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. | |||
| 24 | ||||
| 25 | All Rights Reserved | |||
| 26 | ||||
| 27 | Permission to use, copy, modify, and distribute this software and its | |||
| 28 | documentation for any purpose and without fee is hereby granted, | |||
| 29 | provided that the above copyright notice appear in all copies and that | |||
| 30 | both that copyright notice and this permission notice appear in | |||
| 31 | supporting documentation, and that the name of Digital not be | |||
| 32 | used in advertising or publicity pertaining to distribution of the | |||
| 33 | software without specific, written prior permission. | |||
| 34 | ||||
| 35 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |||
| 36 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |||
| 37 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |||
| 38 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |||
| 39 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
| 40 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |||
| 41 | SOFTWARE. | |||
| 42 | ||||
| 43 | ******************************************************************/ | |||
| 44 | ||||
| 45 | /* | |||
| 46 | ||||
| 47 | Copyright 1987, 1988, 1998 The Open Group | |||
| 48 | ||||
| 49 | Permission to use, copy, modify, distribute, and sell this software and its | |||
| 50 | documentation for any purpose is hereby granted without fee, provided that | |||
| 51 | the above copyright notice appear in all copies and that both that | |||
| 52 | copyright notice and this permission notice appear in supporting | |||
| 53 | documentation. | |||
| 54 | ||||
| 55 | The above copyright notice and this permission notice shall be included in | |||
| 56 | all copies or substantial portions of the Software. | |||
| 57 | ||||
| 58 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 59 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 60 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| 61 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
| 62 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
| 63 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
| 64 | ||||
| 65 | Except as contained in this notice, the name of The Open Group shall not be | |||
| 66 | used in advertising or otherwise to promote the sale, use or other dealings | |||
| 67 | in this Software without prior written authorization from The Open Group. | |||
| 68 | ||||
| 69 | */ | |||
| 70 | ||||
| 71 | #ifdef HAVE_CONFIG_H1 | |||
| 72 | #include <config.h> | |||
| 73 | #endif | |||
| 74 | #include "IntrinsicI.h" | |||
| 75 | #include "StringDefs.h" | |||
| 76 | #include "Intrinsic.h" | |||
| 77 | ||||
| 78 | /* Conversion procedure hash table */ | |||
| 79 | ||||
| 80 | #define CONVERTHASHSIZE((unsigned)256) ((unsigned)256) | |||
| 81 | #define CONVERTHASHMASK255 255 | |||
| 82 | #define ProcHash(from_type, to_type)(2 * (from_type) + to_type) (2 * (from_type) + to_type) | |||
| 83 | ||||
| 84 | typedef struct _ConverterRec *ConverterPtr; | |||
| 85 | typedef struct _ConverterRec { | |||
| 86 | ConverterPtr next; | |||
| 87 | XrmRepresentation from, to; | |||
| 88 | XtTypeConverter converter; | |||
| 89 | XtDestructor destructor; | |||
| 90 | unsigned short num_args; | |||
| 91 | unsigned int do_ref_count:1; | |||
| 92 | unsigned int new_style:1; | |||
| 93 | unsigned int global:1; | |||
| 94 | char cache_type; | |||
| 95 | } ConverterRec; | |||
| 96 | ||||
| 97 | #define ConvertArgs(p)((XtConvertArgList)((p)+1)) ((XtConvertArgList)((p)+1)) | |||
| 98 | ||||
| 99 | /* used for old-style type converter cache only */ | |||
| 100 | static Heap globalHeap = {NULL((void*)0), NULL((void*)0), 0}; | |||
| 101 | ||||
| 102 | void _XtSetDefaultConverterTable( | |||
| 103 | ConverterTable *table) | |||
| 104 | { | |||
| 105 | register ConverterTable globalConverterTable; | |||
| 106 | ||||
| 107 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 108 | globalConverterTable = _XtGetProcessContext()->globalConverterTable; | |||
| 109 | ||||
| 110 | *table = (ConverterTable) | |||
| 111 | __XtCalloc(CONVERTHASHSIZE((unsigned)256), (unsigned)sizeof(ConverterPtr)); | |||
| 112 | _XtAddDefaultConverters(*table); | |||
| 113 | ||||
| 114 | if (globalConverterTable) { | |||
| 115 | ConverterPtr rec; | |||
| 116 | int i; | |||
| 117 | XtCacheType cache_type; | |||
| 118 | for (i = CONVERTHASHSIZE((unsigned)256); --i >= 0; ) { | |||
| 119 | for (rec = *globalConverterTable++; rec; rec = rec->next) { | |||
| 120 | cache_type = rec->cache_type; | |||
| 121 | if (rec->do_ref_count) | |||
| 122 | cache_type |= XtCacheRefCount0x100; | |||
| 123 | _XtTableAddConverter(*table, rec->from, rec->to, rec->converter, | |||
| 124 | ConvertArgs(rec)((XtConvertArgList)((rec)+1)), rec->num_args, | |||
| 125 | rec->new_style, cache_type, | |||
| 126 | rec->destructor, True1); | |||
| 127 | } | |||
| 128 | } | |||
| 129 | } | |||
| 130 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 131 | } | |||
| 132 | ||||
| 133 | void _XtFreeConverterTable( | |||
| 134 | ConverterTable table) | |||
| 135 | { | |||
| 136 | register Cardinal i; | |||
| 137 | register ConverterPtr p; | |||
| 138 | ||||
| 139 | for (i = 0; i < CONVERTHASHSIZE((unsigned)256); i++) { | |||
| 140 | for (p = table[i]; p; ) { | |||
| 141 | register ConverterPtr next = p->next; | |||
| 142 | XtFree((char*)p); | |||
| 143 | p = next; | |||
| 144 | } | |||
| 145 | } | |||
| 146 | XtFree((char*)table); | |||
| 147 | } | |||
| 148 | ||||
| 149 | /* Data cache hash table */ | |||
| 150 | ||||
| 151 | typedef struct _CacheRec *CachePtr; | |||
| 152 | ||||
| 153 | typedef struct _CacheRec { | |||
| 154 | CachePtr next; | |||
| 155 | XtPointer tag; | |||
| 156 | int hash; | |||
| 157 | XtTypeConverter converter; | |||
| 158 | unsigned short num_args; | |||
| 159 | unsigned int conversion_succeeded:1; | |||
| 160 | unsigned int has_ext:1; | |||
| 161 | unsigned int is_refcounted:1; | |||
| 162 | unsigned int must_be_freed:1; | |||
| 163 | unsigned int from_is_value:1; | |||
| 164 | unsigned int to_is_value:1; | |||
| 165 | XrmValue from; | |||
| 166 | XrmValue to; | |||
| 167 | } CacheRec; | |||
| 168 | ||||
| 169 | typedef struct _CacheRecExt { | |||
| 170 | CachePtr *prev; | |||
| 171 | XtDestructor destructor; | |||
| 172 | XtPointer closure; | |||
| 173 | long ref_count; | |||
| 174 | } CacheRecExt; | |||
| 175 | ||||
| 176 | #define CEXT(p)((CacheRecExt *)((p)+1)) ((CacheRecExt *)((p)+1)) | |||
| 177 | #define CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) : (XrmValue *)((p)+1)) ((p)->has_ext ? (XrmValue *)(CEXT(p)((CacheRecExt *)((p)+1))+1) : (XrmValue *)((p)+1)) | |||
| 178 | ||||
| 179 | #define CACHEHASHSIZE256 256 | |||
| 180 | #define CACHEHASHMASK255 255 | |||
| 181 | typedef CachePtr CacheHashTable[CACHEHASHSIZE256]; | |||
| 182 | ||||
| 183 | static CacheHashTable cacheHashTable; | |||
| 184 | ||||
| 185 | void _XtTableAddConverter( | |||
| 186 | ConverterTable table, | |||
| 187 | XrmRepresentation from_type, | |||
| 188 | XrmRepresentation to_type, | |||
| 189 | XtTypeConverter converter, | |||
| 190 | XtConvertArgList convert_args, | |||
| 191 | Cardinal num_args, | |||
| 192 | _XtBooleanint new_style, | |||
| 193 | XtCacheType cache_type, | |||
| 194 | XtDestructor destructor, | |||
| 195 | _XtBooleanint global) | |||
| 196 | { | |||
| 197 | register ConverterPtr *pp; | |||
| 198 | register ConverterPtr p; | |||
| 199 | XtConvertArgList args; | |||
| 200 | ||||
| 201 | pp= &table[ProcHash(from_type, to_type)(2 * (from_type) + to_type) & CONVERTHASHMASK255]; | |||
| 202 | while ((p = *pp) && (p->from != from_type || p->to != to_type)) | |||
| 203 | pp = &p->next; | |||
| 204 | ||||
| 205 | if (p) { | |||
| 206 | *pp = p->next; | |||
| 207 | XtFree((char *)p); | |||
| 208 | } | |||
| 209 | ||||
| 210 | p = (ConverterPtr) __XtMalloc(sizeof(ConverterRec) + | |||
| 211 | sizeof(XtConvertArgRec) * num_args); | |||
| 212 | p->next = *pp; | |||
| 213 | *pp = p; | |||
| 214 | p->from = from_type; | |||
| 215 | p->to = to_type; | |||
| 216 | p->converter = converter; | |||
| 217 | p->destructor = destructor; | |||
| 218 | p->num_args = num_args; | |||
| 219 | p->global = global; | |||
| 220 | args = ConvertArgs(p)((XtConvertArgList)((p)+1)); | |||
| 221 | while (num_args--) | |||
| 222 | *args++ = *convert_args++; | |||
| 223 | p->new_style = new_style; | |||
| 224 | p->do_ref_count = False0; | |||
| 225 | if (destructor || (cache_type & 0xff)) { | |||
| 226 | p->cache_type = cache_type & 0xff; | |||
| 227 | if (cache_type & XtCacheRefCount0x100) | |||
| 228 | p->do_ref_count = True1; | |||
| 229 | } else { | |||
| 230 | p->cache_type = XtCacheNone0x001; | |||
| 231 | } | |||
| 232 | } | |||
| 233 | ||||
| 234 | void XtSetTypeConverter( | |||
| 235 | register _Xconstconst char* from_type, | |||
| 236 | register _Xconstconst char* to_type, | |||
| 237 | XtTypeConverter converter, | |||
| 238 | XtConvertArgList convert_args, | |||
| 239 | Cardinal num_args, | |||
| 240 | XtCacheType cache_type, | |||
| 241 | XtDestructor destructor | |||
| 242 | ) | |||
| 243 | { | |||
| 244 | ProcessContext process; | |||
| 245 | XtAppContext app; | |||
| 246 | XrmRepresentation from; | |||
| 247 | XrmRepresentation to; | |||
| 248 | ||||
| 249 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 250 | process = _XtGetProcessContext(); | |||
| 251 | app = process->appContextList; | |||
| 252 | from = XrmStringToRepresentation(from_type)XrmStringToQuark(from_type); | |||
| 253 | to = XrmStringToRepresentation(to_type)XrmStringToQuark(to_type); | |||
| 254 | ||||
| 255 | if (!process->globalConverterTable) { | |||
| 256 | process->globalConverterTable = (ConverterTable) | |||
| 257 | __XtCalloc(CONVERTHASHSIZE((unsigned)256), (unsigned)sizeof(ConverterPtr)); | |||
| 258 | } | |||
| 259 | _XtTableAddConverter(process->globalConverterTable, from, to, | |||
| 260 | converter, convert_args, | |||
| 261 | num_args, True1, cache_type, destructor, True1); | |||
| 262 | while (app) { | |||
| 263 | _XtTableAddConverter(app->converterTable, from, to, | |||
| 264 | converter, convert_args, | |||
| 265 | num_args, True1, cache_type, destructor, True1); | |||
| 266 | app = app->next; | |||
| 267 | } | |||
| 268 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 269 | } | |||
| 270 | ||||
| 271 | void XtAppSetTypeConverter( | |||
| 272 | XtAppContext app, | |||
| 273 | register _Xconstconst char* from_type, | |||
| 274 | register _Xconstconst char* to_type, | |||
| 275 | XtTypeConverter converter, | |||
| 276 | XtConvertArgList convert_args, | |||
| 277 | Cardinal num_args, | |||
| 278 | XtCacheType cache_type, | |||
| 279 | XtDestructor destructor | |||
| 280 | ) | |||
| 281 | { | |||
| 282 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 283 | _XtTableAddConverter(app->converterTable, | |||
| 284 | XrmStringToRepresentation(from_type)XrmStringToQuark(from_type), | |||
| 285 | XrmStringToRepresentation(to_type)XrmStringToQuark(to_type), | |||
| 286 | converter, convert_args, num_args, | |||
| 287 | True1, cache_type, destructor, False0); | |||
| 288 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 289 | } | |||
| 290 | ||||
| 291 | /* old interface */ | |||
| 292 | void XtAddConverter( | |||
| 293 | register _Xconstconst char* from_type, | |||
| 294 | register _Xconstconst char* to_type, | |||
| 295 | XtConverter converter, | |||
| 296 | XtConvertArgList convert_args, | |||
| 297 | Cardinal num_args | |||
| 298 | ) | |||
| 299 | { | |||
| 300 | ProcessContext process; | |||
| 301 | XtAppContext app; | |||
| 302 | XrmRepresentation from; | |||
| 303 | XrmRepresentation to; | |||
| 304 | ||||
| 305 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 306 | process = _XtGetProcessContext(); | |||
| 307 | app = process->appContextList; | |||
| 308 | from = XrmStringToRepresentation(from_type)XrmStringToQuark(from_type); | |||
| 309 | to = XrmStringToRepresentation(to_type)XrmStringToQuark(to_type); | |||
| 310 | ||||
| 311 | if (!process->globalConverterTable) { | |||
| 312 | process->globalConverterTable = (ConverterTable) | |||
| 313 | __XtCalloc(CONVERTHASHSIZE((unsigned)256), (unsigned)sizeof(ConverterPtr)); | |||
| 314 | } | |||
| 315 | _XtTableAddConverter(process->globalConverterTable, from, to, | |||
| 316 | (XtTypeConverter)converter, convert_args, num_args, | |||
| 317 | False0, XtCacheAll0x002, (XtDestructor)NULL((void*)0), True1); | |||
| 318 | while (app) { | |||
| 319 | _XtTableAddConverter(app->converterTable, from, to, | |||
| 320 | (XtTypeConverter)converter, convert_args, | |||
| 321 | num_args, False0, XtCacheAll0x002, (XtDestructor)NULL((void*)0), | |||
| 322 | True1); | |||
| 323 | app = app->next; | |||
| 324 | } | |||
| 325 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 326 | } | |||
| 327 | ||||
| 328 | /* old interface */ | |||
| 329 | void XtAppAddConverter( | |||
| 330 | XtAppContext app, | |||
| 331 | register _Xconstconst char* from_type, | |||
| 332 | register _Xconstconst char* to_type, | |||
| 333 | XtConverter converter, | |||
| 334 | XtConvertArgList convert_args, | |||
| 335 | Cardinal num_args | |||
| 336 | ) | |||
| 337 | { | |||
| 338 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 339 | _XtTableAddConverter(app->converterTable, | |||
| 340 | XrmStringToRepresentation(from_type)XrmStringToQuark(from_type), | |||
| 341 | XrmStringToRepresentation(to_type)XrmStringToQuark(to_type), | |||
| 342 | (XtTypeConverter)converter, convert_args, num_args, | |||
| 343 | False0, XtCacheAll0x002, (XtDestructor)NULL((void*)0), False0); | |||
| 344 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 345 | } | |||
| 346 | ||||
| 347 | static CachePtr | |||
| 348 | CacheEnter( | |||
| 349 | Heap* heap, | |||
| 350 | register XtTypeConverter converter, | |||
| 351 | register XrmValuePtr args, | |||
| 352 | Cardinal num_args, | |||
| 353 | XrmValuePtr from, | |||
| 354 | XrmValuePtr to, | |||
| 355 | Boolean succeeded, | |||
| 356 | register int hash, | |||
| 357 | Boolean do_ref, | |||
| 358 | Boolean do_free, | |||
| 359 | XtDestructor destructor, | |||
| 360 | XtPointer closure) | |||
| 361 | { | |||
| 362 | register CachePtr *pHashEntry; | |||
| 363 | register CachePtr p; | |||
| 364 | register Cardinal i; | |||
| 365 | ||||
| 366 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 367 | pHashEntry = &cacheHashTable[hash & CACHEHASHMASK255]; | |||
| 368 | ||||
| 369 | if ((succeeded && destructor) || do_ref) { | |||
| 370 | p = (CachePtr) _XtHeapAlloc(heap, (sizeof(CacheRec) + | |||
| 371 | sizeof(CacheRecExt) + | |||
| 372 | num_args * sizeof(XrmValue))); | |||
| 373 | CEXT(p)((CacheRecExt *)((p)+1))->prev = pHashEntry; | |||
| 374 | CEXT(p)((CacheRecExt *)((p)+1))->destructor = succeeded ? destructor : NULL((void*)0); | |||
| 375 | CEXT(p)((CacheRecExt *)((p)+1))->closure = closure; | |||
| 376 | CEXT(p)((CacheRecExt *)((p)+1))->ref_count = 1; | |||
| 377 | p->has_ext = True1; | |||
| 378 | } | |||
| 379 | else { | |||
| 380 | p = (CachePtr)_XtHeapAlloc(heap, (sizeof(CacheRec) + | |||
| 381 | num_args * sizeof(XrmValue))); | |||
| 382 | p->has_ext = False0; | |||
| 383 | } | |||
| 384 | if (!to->addr) | |||
| 385 | succeeded = False0; | |||
| 386 | p->conversion_succeeded = succeeded; | |||
| 387 | p->is_refcounted = do_ref; | |||
| 388 | p->must_be_freed = do_free; | |||
| 389 | p->next = *pHashEntry; | |||
| 390 | if (p->next && p->next->has_ext) | |||
| 391 | CEXT(p->next)((CacheRecExt *)((p->next)+1))->prev = &p->next; | |||
| 392 | ||||
| 393 | *pHashEntry = p; | |||
| 394 | p->tag = (XtPointer)heap; | |||
| 395 | p->hash = hash; | |||
| 396 | p->converter = converter; | |||
| 397 | p->from.size = from->size; | |||
| 398 | if (from->size <= sizeof(p->from.addr)) { | |||
| 399 | p->from_is_value = True1; | |||
| 400 | XtMemmove(&p->from.addr, from->addr, from->size)if ((char *)(&p->from.addr) != (char *)(from->addr) ) { (void) __builtin___memcpy_chk ((char *) (&p->from. addr), (char *) (from->addr), (int) (from->size), __builtin_object_size ((char *) (&p->from.addr), 0)); }; | |||
| 401 | } else { | |||
| 402 | p->from_is_value = False0; | |||
| 403 | p->from.addr = (XPointer)_XtHeapAlloc(heap, from->size); | |||
| 404 | (void) memmove((char *)p->from.addr, (char *)from->addr, from->size)__builtin___memmove_chk ((char *)p->from.addr, (char *)from ->addr, from->size, __builtin_object_size ((char *)p-> from.addr, 0)); | |||
| 405 | } | |||
| 406 | p->num_args = num_args; | |||
| 407 | if (num_args) { | |||
| 408 | XrmValue *pargs = CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) : (XrmValue *)((p)+1)); | |||
| 409 | for (i = 0; i < num_args; i++) { | |||
| 410 | pargs[i].size = args[i].size; | |||
| ||||
| 411 | pargs[i].addr = (XPointer)_XtHeapAlloc(heap, args[i].size); | |||
| 412 | XtMemmove(pargs[i].addr, args[i].addr, args[i].size)if ((char *)(pargs[i].addr) != (char *)(args[i].addr)) { (void ) __builtin___memcpy_chk ((char *) (pargs[i].addr), (char *) ( args[i].addr), (int) (args[i].size), __builtin_object_size (( char *) (pargs[i].addr), 0)); }; | |||
| 413 | } | |||
| 414 | } | |||
| 415 | p->to.size = to->size; | |||
| 416 | if (!succeeded) { | |||
| 417 | p->to_is_value = False0; | |||
| 418 | p->to.addr = NULL((void*)0); | |||
| 419 | } else if (to->size <= sizeof(p->to.addr)) { | |||
| 420 | p->to_is_value = True1; | |||
| 421 | XtMemmove(&p->to.addr, to->addr, to->size)if ((char *)(&p->to.addr) != (char *)(to->addr)) { ( void) __builtin___memcpy_chk ((char *) (&p->to.addr), ( char *) (to->addr), (int) (to->size), __builtin_object_size ((char *) (&p->to.addr), 0)); }; | |||
| 422 | } else { | |||
| 423 | p->to_is_value = False0; | |||
| 424 | p->to.addr = (XPointer)_XtHeapAlloc(heap, to->size); | |||
| 425 | (void) memmove((char *)p->to.addr, (char *)to->addr, to->size)__builtin___memmove_chk ((char *)p->to.addr, (char *)to-> addr, to->size, __builtin_object_size ((char *)p->to.addr , 0)); | |||
| 426 | } | |||
| 427 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 428 | return p; | |||
| 429 | } | |||
| 430 | ||||
| 431 | static void FreeCacheRec( | |||
| 432 | XtAppContext app, | |||
| 433 | CachePtr p, | |||
| 434 | CachePtr *prev) | |||
| 435 | { | |||
| 436 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 437 | if (p->has_ext) { | |||
| 438 | if (CEXT(p)((CacheRecExt *)((p)+1))->destructor) { | |||
| 439 | Cardinal num_args = p->num_args; | |||
| 440 | XrmValue *args = NULL((void*)0); | |||
| 441 | XrmValue toc; | |||
| 442 | if (num_args) | |||
| 443 | args = CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) : (XrmValue *)((p)+1)); | |||
| 444 | toc.size = p->to.size; | |||
| 445 | if (p->to_is_value) | |||
| 446 | toc.addr = (XPointer)&p->to.addr; | |||
| 447 | else | |||
| 448 | toc.addr = p->to.addr; | |||
| 449 | (*CEXT(p)((CacheRecExt *)((p)+1))->destructor) (app, &toc, CEXT(p)((CacheRecExt *)((p)+1))->closure, args, | |||
| 450 | &num_args); | |||
| 451 | } | |||
| 452 | *(CEXT(p)((CacheRecExt *)((p)+1))->prev) = p->next; | |||
| 453 | if (p->next && p->next->has_ext) | |||
| 454 | CEXT(p->next)((CacheRecExt *)((p->next)+1))->prev = CEXT(p)((CacheRecExt *)((p)+1))->prev; | |||
| 455 | } else { | |||
| 456 | *prev = p->next; | |||
| 457 | if (p->next && p->next->has_ext) | |||
| 458 | CEXT(p->next)((CacheRecExt *)((p->next)+1))->prev = prev; | |||
| 459 | } | |||
| 460 | if (p->must_be_freed) { | |||
| 461 | register int i; | |||
| 462 | if (!p->from_is_value) | |||
| 463 | XtFree(p->from.addr); | |||
| 464 | if ((i = p->num_args)) { | |||
| 465 | XrmValue *pargs = CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) : (XrmValue *)((p)+1)); | |||
| 466 | while (i--) | |||
| 467 | XtFree(pargs[i].addr); | |||
| 468 | } | |||
| 469 | if (!p->to_is_value) | |||
| 470 | XtFree(p->to.addr); | |||
| 471 | XtFree((char*)p); | |||
| 472 | } | |||
| 473 | /* else on private heap; will free entire heap later */ | |||
| 474 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 475 | } | |||
| 476 | ||||
| 477 | ||||
| 478 | void _XtCacheFlushTag( | |||
| 479 | XtAppContext app, | |||
| 480 | XtPointer tag) | |||
| 481 | { | |||
| 482 | int i; | |||
| 483 | register CachePtr *prev; | |||
| 484 | register CachePtr rec; | |||
| 485 | ||||
| 486 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 487 | for (i = CACHEHASHSIZE256; --i >= 0;) { | |||
| 488 | prev = &cacheHashTable[i]; | |||
| 489 | while ((rec = *prev)) { | |||
| 490 | if (rec->tag == tag) | |||
| 491 | FreeCacheRec(app, rec, prev); | |||
| 492 | else | |||
| 493 | prev = &rec->next; | |||
| 494 | } | |||
| 495 | } | |||
| 496 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 497 | } | |||
| 498 | ||||
| 499 | #ifdef DEBUG | |||
| 500 | #include <stdio.h> | |||
| 501 | ||||
| 502 | void _XtConverterCacheStats(void) | |||
| 503 | { | |||
| 504 | register Cardinal i; | |||
| 505 | register CachePtr p; | |||
| 506 | register Cardinal entries; | |||
| 507 | ||||
| 508 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 509 | for (i = 0; i < CACHEHASHSIZE256; i++) { | |||
| 510 | p = cacheHashTable[i]; | |||
| 511 | if (p) { | |||
| 512 | for (entries = 0; p; p = p->next) { | |||
| 513 | entries++; | |||
| 514 | } | |||
| 515 | (void) fprintf(stdout, "Index: %4d Entries: %d\n", i, entries); | |||
| 516 | for (p = cacheHashTable[i]; p; p = p->next) { | |||
| 517 | (void) fprintf(stdout, " Size: %3d Refs: %3d '", | |||
| 518 | p->from.size, | |||
| 519 | p->has_ext ? CEXT(p)((CacheRecExt *)((p)+1))->ref_count : 0); | |||
| 520 | (void) fprintf(stdout, "'\n"); | |||
| 521 | } | |||
| 522 | (void) fprintf(stdout, "\n"); | |||
| 523 | } | |||
| 524 | } | |||
| 525 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 526 | } | |||
| 527 | #endif /*DEBUG*/ | |||
| 528 | ||||
| 529 | static Boolean ResourceQuarkToOffset( | |||
| 530 | WidgetClass widget_class, | |||
| 531 | XrmName name, | |||
| 532 | Cardinal *offset) | |||
| 533 | { | |||
| 534 | register WidgetClass wc; | |||
| 535 | register Cardinal i; | |||
| 536 | register XrmResourceList res, *resources; | |||
| 537 | ||||
| 538 | for (wc = widget_class; wc; wc = wc->core_class.superclass) { | |||
| 539 | resources = (XrmResourceList*) wc->core_class.resources; | |||
| 540 | for (i = 0; i < wc->core_class.num_resources; i++, resources++) { | |||
| 541 | res = *resources; | |||
| 542 | if (res->xrm_name == name) { | |||
| 543 | *offset = -res->xrm_offset - 1; | |||
| 544 | return True1; | |||
| 545 | } | |||
| 546 | } /* for i in resources */ | |||
| 547 | } /* for wc in widget classes */ | |||
| 548 | (*offset) = 0; | |||
| 549 | return False0; | |||
| 550 | } | |||
| 551 | ||||
| 552 | ||||
| 553 | static void ComputeArgs( | |||
| 554 | Widget widget, | |||
| 555 | XtConvertArgList convert_args, | |||
| 556 | Cardinal num_args, | |||
| 557 | XrmValuePtr args) | |||
| 558 | { | |||
| 559 | register Cardinal i; | |||
| 560 | Cardinal offset; | |||
| 561 | String params[1]; | |||
| 562 | Cardinal num_params = 1; | |||
| 563 | Widget ancestor = NULL((void*)0); | |||
| 564 | ||||
| 565 | for (i = 0; i < num_args; i++) { | |||
| 566 | args[i].size = convert_args[i].size; | |||
| 567 | switch (convert_args[i].address_mode) { | |||
| 568 | case XtAddress: | |||
| 569 | args[i].addr = convert_args[i].address_id; | |||
| 570 | break; | |||
| 571 | ||||
| 572 | case XtBaseOffset: | |||
| 573 | args[i].addr = | |||
| 574 | (XPointer)((char *)widget + (long)convert_args[i].address_id); | |||
| 575 | break; | |||
| 576 | ||||
| 577 | case XtWidgetBaseOffset: | |||
| 578 | if (!ancestor) { | |||
| 579 | if (XtIsWidget(widget)(((Object)(widget))->object.widget_class->core_class.class_inited & 0x04)) | |||
| 580 | ancestor = widget; | |||
| 581 | else | |||
| 582 | ancestor = _XtWindowedAncestor(widget); | |||
| 583 | } | |||
| 584 | ||||
| 585 | args[i].addr = | |||
| 586 | (XPointer)((char *)ancestor + (long)convert_args[i].address_id); | |||
| 587 | break; | |||
| 588 | ||||
| 589 | case XtImmediate: | |||
| 590 | args[i].addr = (XPointer) &(convert_args[i].address_id); | |||
| 591 | break; | |||
| 592 | ||||
| 593 | case XtProcedureArg: | |||
| 594 | (*(XtConvertArgProc)convert_args[i].address_id) | |||
| 595 | (widget, &convert_args[i].size, &args[i]); | |||
| 596 | break; | |||
| 597 | ||||
| 598 | case XtResourceString: | |||
| 599 | /* Convert in place for next usage */ | |||
| 600 | convert_args[i].address_mode = XtResourceQuark; | |||
| 601 | convert_args[i].address_id = | |||
| 602 | (XtPointer)(long)XrmStringToQuark((String)convert_args[i].address_id); | |||
| 603 | /* Fall through */ | |||
| 604 | ||||
| 605 | case XtResourceQuark: | |||
| 606 | if (! ResourceQuarkToOffset(widget->core.widget_class, | |||
| 607 | (XrmQuark)(long) convert_args[i].address_id, &offset)) { | |||
| 608 | params[0]= | |||
| 609 | XrmQuarkToString((XrmQuark)(long) convert_args[i].address_id); | |||
| 610 | XtAppWarningMsg(XtWidgetToApplicationContext(widget), | |||
| 611 | "invalidResourceName","computeArgs",XtCXtToolkitError, | |||
| 612 | "Cannot find resource name %s as argument to conversion", | |||
| 613 | params,&num_params); | |||
| 614 | offset = 0; | |||
| 615 | } | |||
| 616 | args[i].addr = (XPointer)((char *)widget + offset); | |||
| 617 | break; | |||
| 618 | default: | |||
| 619 | params[0] = XtName(widget); | |||
| 620 | XtAppWarningMsg(XtWidgetToApplicationContext(widget), | |||
| 621 | "invalidAddressMode", "computeArgs", XtCXtToolkitError, | |||
| 622 | "Conversion arguments for widget '%s' contain an unsupported address mode", | |||
| 623 | params,&num_params); | |||
| 624 | args[i].addr = NULL((void*)0); | |||
| 625 | args[i].size = 0; | |||
| 626 | } /* switch */ | |||
| 627 | } /* for */ | |||
| 628 | } /* ComputeArgs */ | |||
| 629 | ||||
| 630 | void XtDirectConvert( | |||
| 631 | XtConverter converter, | |||
| 632 | XrmValuePtr args, | |||
| 633 | Cardinal num_args, | |||
| 634 | register XrmValuePtr from, | |||
| 635 | XrmValuePtr to) | |||
| 636 | { | |||
| 637 | register CachePtr p; | |||
| 638 | register int hash; | |||
| 639 | register Cardinal i; | |||
| 640 | ||||
| 641 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 642 | /* Try to find cache entry for conversion */ | |||
| 643 | hash = ((long) converter >> 2) + from->size + *((char *) from->addr); | |||
| 644 | if (from->size > 1) hash += ((char *) from->addr)[1]; | |||
| 645 | ||||
| 646 | for (p = cacheHashTable[hash & CACHEHASHMASK255]; p; p = p->next) { | |||
| 647 | if ((p->hash == hash) | |||
| 648 | && (p->converter == (XtTypeConverter)converter) | |||
| 649 | && (p->from.size == from->size) | |||
| 650 | && !(p->from_is_value ? | |||
| 651 | XtMemcmp(&p->from.addr, from->addr, from->size)memcmp((char *) (&p->from.addr), (char *) (from->addr ), (int) (from->size)) : | |||
| 652 | memcmp((char *)p->from.addr, (char *)from->addr, from->size)) | |||
| 653 | && (p->num_args == num_args)) { | |||
| 654 | if ((i = num_args)) { | |||
| 655 | XrmValue *pargs = CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) : (XrmValue *)((p)+1)); | |||
| 656 | /* Are all args the same data ? */ | |||
| 657 | while (i) { | |||
| 658 | i--; /* do not move to while test, broken compilers */ | |||
| 659 | if (pargs[i].size != args[i].size || | |||
| 660 | XtMemcmp(pargs[i].addr, args[i].addr, args[i].size)memcmp((char *) (pargs[i].addr), (char *) (args[i].addr), (int ) (args[i].size))) { | |||
| 661 | i++; | |||
| 662 | break; | |||
| 663 | } | |||
| 664 | } | |||
| 665 | } | |||
| 666 | if (!i) { | |||
| 667 | /* Perfect match */ | |||
| 668 | to->size = p->to.size; | |||
| 669 | if (p->to_is_value) | |||
| 670 | to->addr = (XPointer)&p->to.addr; | |||
| 671 | else | |||
| 672 | to->addr = p->to.addr; | |||
| 673 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 674 | return; | |||
| 675 | } | |||
| 676 | } | |||
| 677 | } | |||
| 678 | ||||
| 679 | /* Didn't find it, call converter procedure and entry result in cache */ | |||
| 680 | (*to).size = 0; | |||
| 681 | (*to).addr = NULL((void*)0); | |||
| 682 | (*converter)(args, &num_args, from, to); | |||
| 683 | /* This memory can never be freed since we don't know the Display | |||
| 684 | * or app context from which to compute the persistance */ | |||
| 685 | { | |||
| 686 | CacheEnter(&globalHeap, (XtTypeConverter)converter, args, num_args, | |||
| 687 | from, to, (to->addr != NULL((void*)0)), hash, False0, False0, | |||
| 688 | (XtDestructor)NULL((void*)0), NULL((void*)0)); | |||
| 689 | } | |||
| 690 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 691 | } | |||
| 692 | ||||
| 693 | ||||
| 694 | static ConverterPtr GetConverterEntry( | |||
| 695 | XtAppContext app, | |||
| 696 | XtTypeConverter converter) | |||
| 697 | { | |||
| 698 | Cardinal entry; | |||
| 699 | register ConverterPtr cP; | |||
| 700 | ConverterTable converterTable; | |||
| 701 | ||||
| 702 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 703 | converterTable = app->converterTable; | |||
| 704 | cP = NULL((void*)0); | |||
| 705 | for (entry = 0; (entry < CONVERTHASHSIZE((unsigned)256)) && !cP; entry++) { | |||
| 706 | cP = converterTable[entry]; | |||
| 707 | while (cP && (cP->converter != converter)) cP = cP->next; | |||
| 708 | } | |||
| 709 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 710 | return cP; | |||
| 711 | } | |||
| 712 | ||||
| 713 | ||||
| 714 | static Boolean | |||
| 715 | CallConverter( | |||
| 716 | Display* dpy, | |||
| 717 | XtTypeConverter converter, | |||
| 718 | XrmValuePtr args, | |||
| 719 | Cardinal num_args, | |||
| 720 | register XrmValuePtr from, | |||
| 721 | XrmValuePtr to, | |||
| 722 | XtCacheRef *cache_ref_return, | |||
| 723 | register ConverterPtr cP) | |||
| 724 | { | |||
| 725 | CachePtr p; | |||
| 726 | int hash; | |||
| 727 | Cardinal i; | |||
| 728 | Boolean retval; | |||
| 729 | ||||
| 730 | if (!cP || ((cP->cache_type == XtCacheNone0x001) && !cP->destructor)) { | |||
| 731 | XtPointer closure; | |||
| 732 | if (cache_ref_return) *cache_ref_return = NULL((void*)0); | |||
| 733 | retval = (*(XtTypeConverter)converter) | |||
| 734 | (dpy, args, &num_args, from, to, &closure); | |||
| 735 | return retval; | |||
| 736 | } | |||
| 737 | ||||
| 738 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 739 | /* Try to find cache entry for conversion */ | |||
| 740 | hash = ((long)(converter) >> 2) + from->size + *((char *) from->addr); | |||
| 741 | if (from->size > 1) hash += ((char *) from->addr)[1]; | |||
| 742 | ||||
| 743 | if (cP->cache_type != XtCacheNone0x001) { | |||
| 744 | for (p = cacheHashTable[hash & CACHEHASHMASK255]; p; p = p->next){ | |||
| 745 | if ((p->hash == hash) | |||
| 746 | && (p->converter == converter) | |||
| 747 | && (p->from.size == from->size) | |||
| 748 | && !(p->from_is_value ? | |||
| 749 | XtMemcmp(&p->from.addr, from->addr, from->size)memcmp((char *) (&p->from.addr), (char *) (from->addr ), (int) (from->size)) : | |||
| 750 | memcmp((char *)p->from.addr, (char *)from->addr, from->size)) | |||
| 751 | && (p->num_args == num_args)) { | |||
| 752 | if ((i = num_args)) { | |||
| 753 | XrmValue *pargs = CARGS(p)((p)->has_ext ? (XrmValue *)(((CacheRecExt *)((p)+1))+1) : (XrmValue *)((p)+1)); | |||
| 754 | /* Are all args the same data ? */ | |||
| 755 | while (i) { | |||
| 756 | i--; /* do not move to while test, broken compilers */ | |||
| 757 | if (pargs[i].size != args[i].size || | |||
| 758 | XtMemcmp(pargs[i].addr, args[i].addr, args[i].size)memcmp((char *) (pargs[i].addr), (char *) (args[i].addr), (int ) (args[i].size))){ | |||
| 759 | i++; | |||
| 760 | break; | |||
| 761 | } | |||
| 762 | } | |||
| 763 | } | |||
| 764 | if (!i) { | |||
| 765 | /* Perfect match */ | |||
| 766 | if (p->conversion_succeeded) { | |||
| 767 | if (to->addr) { /* new-style call */ | |||
| 768 | if (to->size < p->to.size) { | |||
| 769 | to->size = p->to.size; | |||
| 770 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 771 | return False0; | |||
| 772 | } | |||
| 773 | to->size = p->to.size; | |||
| 774 | if (p->to_is_value) { | |||
| 775 | XtMemmove(to->addr, &p->to.addr,if ((char *)(to->addr) != (char *)(&p->to.addr)) { ( void) __builtin___memcpy_chk ((char *) (to->addr), (char * ) (&p->to.addr), (int) (to->size), __builtin_object_size ((char *) (to->addr), 0)); } | |||
| 776 | to->size)if ((char *)(to->addr) != (char *)(&p->to.addr)) { ( void) __builtin___memcpy_chk ((char *) (to->addr), (char * ) (&p->to.addr), (int) (to->size), __builtin_object_size ((char *) (to->addr), 0)); }; | |||
| 777 | } else { | |||
| 778 | (void) memmove((char *)to->addr,__builtin___memmove_chk ((char *)to->addr, (char *)p->to .addr, to->size, __builtin_object_size ((char *)to->addr , 0)) | |||
| 779 | (char *)p->to.addr, to->size)__builtin___memmove_chk ((char *)to->addr, (char *)p->to .addr, to->size, __builtin_object_size ((char *)to->addr , 0)); | |||
| 780 | } | |||
| 781 | } else { /* old-style call */ | |||
| 782 | to->size = p->to.size; | |||
| 783 | if (p->to_is_value) | |||
| 784 | to->addr = (XPointer)&p->to.addr; | |||
| 785 | else | |||
| 786 | to->addr = p->to.addr; | |||
| 787 | } | |||
| 788 | } | |||
| 789 | if (p->is_refcounted) { | |||
| 790 | CEXT(p)((CacheRecExt *)((p)+1))->ref_count++; | |||
| 791 | if (cache_ref_return) | |||
| 792 | *cache_ref_return = (XtCacheRef)p; | |||
| 793 | else | |||
| 794 | p->is_refcounted = False0; | |||
| 795 | } | |||
| 796 | else { | |||
| 797 | if (cache_ref_return) | |||
| 798 | *cache_ref_return = NULL((void*)0); | |||
| 799 | } | |||
| 800 | retval = (p->conversion_succeeded); | |||
| 801 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 802 | return retval; | |||
| 803 | } | |||
| 804 | } | |||
| 805 | } | |||
| 806 | } | |||
| 807 | ||||
| 808 | /* No cache entry, call converter procedure and enter result in cache */ | |||
| 809 | { | |||
| 810 | Heap *heap; | |||
| 811 | XtPointer closure = NULL((void*)0); | |||
| 812 | unsigned int supplied_size = to->size; | |||
| 813 | Boolean do_ref = cP->do_ref_count && cache_ref_return; | |||
| 814 | Boolean do_free = False0; | |||
| 815 | Boolean retval = | |||
| 816 | (*(XtTypeConverter)converter)(dpy, args, &num_args, from, to, &closure); | |||
| 817 | ||||
| 818 | if (retval == False0 && supplied_size < to->size) { | |||
| 819 | /* programmer error: caller must allocate sufficient storage */ | |||
| 820 | if (cache_ref_return) | |||
| 821 | *cache_ref_return = NULL((void*)0); | |||
| 822 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 823 | return False0; | |||
| 824 | } | |||
| 825 | ||||
| 826 | if ((cP->cache_type == XtCacheNone0x001) || do_ref) { | |||
| 827 | heap = NULL((void*)0); | |||
| 828 | do_free = True1; | |||
| 829 | } | |||
| 830 | else if (cP->cache_type == XtCacheByDisplay0x003) | |||
| 831 | heap = &_XtGetPerDisplay(dpy)->heap; | |||
| 832 | else if (cP->global) | |||
| 833 | heap = &globalHeap; | |||
| 834 | else | |||
| 835 | heap = &XtDisplayToApplicationContext(dpy)->heap; | |||
| 836 | ||||
| 837 | p = CacheEnter(heap, converter, args, num_args, from, to, retval, | |||
| 838 | hash, do_ref, do_free, cP->destructor, closure); | |||
| 839 | if (do_ref) | |||
| 840 | *cache_ref_return = (XtCacheRef)p; | |||
| 841 | else if (cache_ref_return) | |||
| 842 | *cache_ref_return = NULL((void*)0); | |||
| 843 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 844 | return retval; | |||
| 845 | } | |||
| 846 | } | |||
| 847 | ||||
| 848 | Boolean | |||
| 849 | XtCallConverter( | |||
| 850 | Display* dpy, | |||
| 851 | XtTypeConverter converter, | |||
| 852 | XrmValuePtr args, | |||
| 853 | Cardinal num_args, | |||
| 854 | register XrmValuePtr from, | |||
| 855 | XrmValuePtr to, | |||
| 856 | XtCacheRef *cache_ref_return) | |||
| 857 | { | |||
| 858 | ConverterPtr cP; | |||
| 859 | Boolean retval; | |||
| 860 | XtAppContext app = XtDisplayToApplicationContext(dpy); | |||
| 861 | ||||
| 862 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||
| 863 | if ((cP = GetConverterEntry(app, converter)) == NULL((void*)0)) { | |||
| 864 | XtAppSetTypeConverter(XtDisplayToApplicationContext(dpy), | |||
| 865 | "_XtUnk1", "_XtUnk2", | |||
| 866 | converter, NULL((void*)0), 0, | |||
| 867 | XtCacheAll0x002, NULL((void*)0)); | |||
| 868 | cP = GetConverterEntry(app, converter); | |||
| 869 | } | |||
| 870 | retval = CallConverter(dpy, converter, args, num_args, from, to, | |||
| 871 | cache_ref_return, cP); | |||
| 872 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||
| 873 | return retval; | |||
| 874 | } | |||
| 875 | ||||
| 876 | Boolean _XtConvert( | |||
| 877 | Widget widget, | |||
| 878 | register XrmRepresentation from_type, | |||
| 879 | XrmValuePtr from, | |||
| 880 | register XrmRepresentation to_type, | |||
| 881 | register XrmValuePtr to, | |||
| 882 | XtCacheRef *cache_ref_return) | |||
| 883 | { | |||
| 884 | XtAppContext app = XtWidgetToApplicationContext(widget); | |||
| 885 | register ConverterPtr p; | |||
| 886 | Cardinal num_args; | |||
| 887 | XrmValue *args; | |||
| 888 | ||||
| 889 | /* Look for type converter */ | |||
| 890 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 891 | p = app->converterTable[ProcHash(from_type, to_type)(2 * (from_type) + to_type) & CONVERTHASHMASK255]; | |||
| 892 | for (; p; p = p->next) { | |||
| 893 | if (from_type == p->from && to_type == p->to) { | |||
| 894 | Boolean retval = False0; | |||
| 895 | /* Compute actual arguments from widget and arg descriptor */ | |||
| 896 | num_args = p->num_args; | |||
| 897 | if (num_args != 0) { | |||
| 898 | args = (XrmValue*) | |||
| 899 | ALLOCATE_LOCAL( num_args * sizeof (XrmValue) )__builtin_alloca((int)(num_args * sizeof (XrmValue))); | |||
| 900 | if (!args) _XtAllocError("alloca"); | |||
| 901 | ComputeArgs(widget, ConvertArgs(p)((XtConvertArgList)((p)+1)), num_args, args); | |||
| 902 | } else args = NULL((void*)0); | |||
| 903 | if (p->new_style) { | |||
| 904 | retval = | |||
| 905 | CallConverter(XtDisplayOfObject(widget)((((Object)(widget))->object.widget_class->core_class.class_inited & 0x04) ? (widget)->core.screen->display : _XtIsHookObject (widget) ? ((HookObject)(widget))->hooks.screen->display : _XtWindowedAncestor(widget)->core.screen->display), | |||
| 906 | p->converter, args, num_args, | |||
| 907 | from, to, cache_ref_return, p); | |||
| 908 | } | |||
| 909 | else { /* is old-style (non-display) converter */ | |||
| 910 | XrmValue tempTo; | |||
| 911 | XtDirectConvert((XtConverter)p->converter, args, num_args, | |||
| 912 | from, &tempTo); | |||
| 913 | if (cache_ref_return) | |||
| 914 | *cache_ref_return = NULL((void*)0); | |||
| 915 | if (tempTo.addr) { | |||
| 916 | if (to->addr) { /* new-style caller */ | |||
| 917 | if (to->size >= tempTo.size) { | |||
| 918 | if (to_type == _XtQString) | |||
| 919 | *(String*)(to->addr) = tempTo.addr; | |||
| 920 | else { | |||
| 921 | XtMemmove(to->addr, tempTo.addr,if ((char *)(to->addr) != (char *)(tempTo.addr)) { (void) __builtin___memcpy_chk ((char *) (to->addr), (char *) (tempTo.addr), (int) (tempTo .size), __builtin_object_size ((char *) (to->addr), 0)); } | |||
| 922 | tempTo.size)if ((char *)(to->addr) != (char *)(tempTo.addr)) { (void) __builtin___memcpy_chk ((char *) (to->addr), (char *) (tempTo.addr), (int) (tempTo .size), __builtin_object_size ((char *) (to->addr), 0)); }; | |||
| 923 | } | |||
| 924 | retval = True1; | |||
| 925 | } | |||
| 926 | to->size = tempTo.size; | |||
| 927 | } else { /* old-style caller */ | |||
| 928 | *to = tempTo; | |||
| 929 | retval = True1; | |||
| 930 | } | |||
| 931 | } | |||
| 932 | } | |||
| 933 | if (args) DEALLOCATE_LOCAL( (XtPointer)args )do {} while(0); | |||
| 934 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 935 | return retval; | |||
| 936 | } | |||
| 937 | } | |||
| 938 | ||||
| 939 | { | |||
| 940 | String params[2]; | |||
| 941 | Cardinal num_params = 2; | |||
| 942 | params[0] = XrmRepresentationToString(from_type)XrmQuarkToString(from_type); | |||
| 943 | params[1] = XrmRepresentationToString(to_type)XrmQuarkToString(to_type); | |||
| 944 | XtAppWarningMsg(app, "typeConversionError", "noConverter", XtCXtToolkitError, | |||
| 945 | "No type converter registered for '%s' to '%s' conversion.", | |||
| 946 | params, &num_params); | |||
| 947 | } | |||
| 948 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 949 | return False0; | |||
| 950 | } | |||
| 951 | ||||
| 952 | void XtConvert( | |||
| 953 | Widget widget, | |||
| 954 | _Xconstconst char* from_type_str, | |||
| 955 | XrmValuePtr from, | |||
| 956 | _Xconstconst char* to_type_str, | |||
| 957 | XrmValuePtr to) | |||
| 958 | { | |||
| 959 | XrmQuark from_type, to_type; | |||
| 960 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | |||
| 961 | ||||
| 962 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||
| 963 | from_type = XrmStringToRepresentation(from_type_str)XrmStringToQuark(from_type_str); | |||
| 964 | to_type = XrmStringToRepresentation(to_type_str)XrmStringToQuark(to_type_str); | |||
| 965 | if (from_type != to_type) { | |||
| ||||
| 966 | /* It's not safe to ref count these resources, 'cause we | |||
| 967 | don't know what older clients may have assumed about | |||
| 968 | the resource lifetimes. | |||
| 969 | XtCacheRef ref; | |||
| 970 | */ | |||
| 971 | to->addr = NULL((void*)0); | |||
| 972 | to->size = 0; | |||
| 973 | _XtConvert(widget, from_type, from, to_type, to, /*&ref*/ NULL((void*)0)); | |||
| 974 | /* | |||
| 975 | if (ref) { | |||
| 976 | XtAddCallback( widget, XtNdestroyCallback, | |||
| 977 | XtCallbackReleaseCacheRef, (XtPointer)ref ); | |||
| 978 | } | |||
| 979 | */ | |||
| 980 | } | |||
| 981 | else | |||
| 982 | (*to) = *from; | |||
| 983 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||
| 984 | } | |||
| 985 | ||||
| 986 | Boolean XtConvertAndStore( | |||
| 987 | Widget object, | |||
| 988 | _Xconstconst char* from_type_str, | |||
| 989 | XrmValuePtr from, | |||
| 990 | _Xconstconst char* to_type_str, | |||
| 991 | XrmValuePtr to) | |||
| 992 | { | |||
| 993 | XrmQuark from_type, to_type; | |||
| 994 | WIDGET_TO_APPCON(object)XtAppContext app = (object && _XtProcessLock ? XtWidgetToApplicationContext (object) : ((void*)0)); | |||
| 995 | ||||
| 996 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||
| 997 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 998 | from_type = XrmStringToRepresentation(from_type_str)XrmStringToQuark(from_type_str); | |||
| 999 | to_type = XrmStringToRepresentation(to_type_str)XrmStringToQuark(to_type_str); | |||
| 1000 | if (from_type != to_type) { | |||
| 1001 | static XtPointer local_valueP = NULL((void*)0); | |||
| 1002 | static Cardinal local_valueS = 128; | |||
| 1003 | XtCacheRef ref; | |||
| 1004 | Boolean local = False0; | |||
| 1005 | do { | |||
| 1006 | if (!to->addr) { | |||
| 1007 | if (!local_valueP) | |||
| 1008 | local_valueP = _XtHeapAlloc(&globalHeap, local_valueS); | |||
| 1009 | to->addr = local_valueP; | |||
| 1010 | to->size = local_valueS; | |||
| 1011 | local = True1; | |||
| 1012 | } | |||
| 1013 | if (!_XtConvert(object, from_type, from, to_type, to, &ref)) { | |||
| 1014 | if (local && (to->size > local_valueS)) { | |||
| 1015 | to->addr = | |||
| 1016 | local_valueP = _XtHeapAlloc(&globalHeap, to->size); | |||
| 1017 | local_valueS = to->size; | |||
| 1018 | continue; | |||
| 1019 | } else { | |||
| 1020 | if (local) { | |||
| 1021 | to->addr = NULL((void*)0); | |||
| 1022 | to->size = 0; | |||
| 1023 | } | |||
| 1024 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 1025 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||
| 1026 | return False0; | |||
| 1027 | } | |||
| 1028 | } | |||
| 1029 | if (ref) { | |||
| 1030 | XtAddCallback( object, XtNdestroyCallback((char*)&XtStrings[169]), | |||
| 1031 | XtCallbackReleaseCacheRef, (XtPointer)ref ); | |||
| 1032 | } | |||
| 1033 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 1034 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||
| 1035 | return True1; | |||
| 1036 | } while (local /* && local_valueS < to->size */); | |||
| 1037 | } | |||
| 1038 | if (to->addr) { | |||
| 1039 | if (to->size < from->size) { | |||
| 1040 | to->size = from->size; | |||
| 1041 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 1042 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||
| 1043 | return False0; | |||
| 1044 | } | |||
| 1045 | (void) memmove(to->addr, from->addr, from->size )__builtin___memmove_chk (to->addr, from->addr, from-> size, __builtin_object_size (to->addr, 0)); | |||
| 1046 | to->size = from->size; | |||
| 1047 | } else /* from_type == to_type */ | |||
| 1048 | *to = *from; | |||
| 1049 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 1050 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||
| 1051 | return True1; | |||
| 1052 | } | |||
| 1053 | ||||
| 1054 | void XtAppReleaseCacheRefs( | |||
| 1055 | XtAppContext app, | |||
| 1056 | XtCacheRef *refs) | |||
| 1057 | { | |||
| 1058 | register CachePtr *r; | |||
| 1059 | register CachePtr p; | |||
| 1060 | ||||
| 1061 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||
| 1062 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||
| 1063 | for (r = (CachePtr*)refs; (p = *r); r++) { | |||
| 1064 | if (p->is_refcounted && --(CEXT(p)((CacheRecExt *)((p)+1))->ref_count) == 0) { | |||
| 1065 | FreeCacheRec(app, p, NULL((void*)0)); | |||
| 1066 | } | |||
| 1067 | } | |||
| 1068 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||
| 1069 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||
| 1070 | } | |||
| 1071 | ||||
| 1072 | ||||
| 1073 | /* ARGSUSED */ | |||
| 1074 | void XtCallbackReleaseCacheRefList( | |||
| 1075 | Widget widget, /* unused */ | |||
| 1076 | XtPointer closure, | |||
| 1077 | XtPointer call_data) /* unused */ | |||
| 1078 | { | |||
| 1079 | XtAppReleaseCacheRefs( XtWidgetToApplicationContext(widget), | |||
| 1080 | (XtCacheRef*)closure ); | |||
| 1081 | XtFree(closure); | |||
| 1082 | } | |||
| 1083 | ||||
| 1084 | ||||
| 1085 | /* ARGSUSED */ | |||
| 1086 | void XtCallbackReleaseCacheRef( | |||
| 1087 | Widget widget, /* unused */ | |||
| 1088 | XtPointer closure, | |||
| 1089 | XtPointer call_data) /* unused */ | |||
| 1090 | { | |||
| 1091 | XtCacheRef cache_refs[2]; | |||
| 1092 | cache_refs[0] = (XtCacheRef)closure; | |||
| 1093 | cache_refs[1] = NULL((void*)0); | |||
| 1094 | XtAppReleaseCacheRefs( XtWidgetToApplicationContext(widget), cache_refs ); | |||
| 1095 | } |