From 08d34592f06a37ece6c8a4715e8efdcfa61849d2 Mon Sep 17 00:00:00 2001 From: Ralph Ronnquist Date: Mon, 25 Jul 2022 14:49:07 +1000 Subject: [PATCH] portability fixes --- typing/ItemKeyFun.c | 60 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/typing/ItemKeyFun.c b/typing/ItemKeyFun.c index 2b1d372..6ca7ce0 100644 --- a/typing/ItemKeyFun.c +++ b/typing/ItemKeyFun.c @@ -2,7 +2,6 @@ * Trampoline functions for the ItemKeyFun callbacks. */ -#include #include /** @@ -12,8 +11,8 @@ */ unsigned long ItemKeyFun_hashcode(void *this,void *key) { ItemKeyFun *type = (ItemKeyFun*) this; - assert( type ); - return type->hashcode? type->hashcode( type, key ) : (unsigned long) key; + return (type && type->hashcode)? type->hashcode( type, key ) + : (unsigned long) key; } /** @@ -48,6 +47,39 @@ void ItemKeyFun_releasekey(void *this,void *key) { } } +/** + * Write a value in hexadecimal form, with "0x" followed by digits, if + * it fits within the given limit. Returns characters written, which + * is either 0 or all. + */ +static int ItemKeyFun_puthexlong(char *p,unsigned long x,int limit) { + int n = 3; + if ( x ) { + unsigned long y = x; + char *q = p; + for ( ; y; y >>= 4, q++ ); + n = q - p + 2; + if ( n >= limit ) { + return 0; + } + *(p++) = '0'; + *(p++) = 'x'; + for ( q++; x; x >>= 4, q-- ) { + *q = x & 0xf; + } + p += n - 2; + } else { + if ( 3 >= limit ) { + return 0; + } + *(p++) = '0'; + *(p++) = 'x'; + *(p++) = '0'; + } + *(p++) = 0; + return n; +} + /** * \brief Trampoline function for the ItemKeyFun.tostring callback. */ @@ -56,8 +88,28 @@ int ItemKeyFun_tostring(void *this,void *item,char *buffer,int limit) { if( type && type->tostring ) { return type->tostring( type, item, buffer, limit ); } + if ( limit < 14 ) { + return 0; + } void *key = ItemKeyFun_itemkey( this, item ); - int n = snprintf( buffer, limit, "{%p/%p@%p}", type, key, item ); + // Portable snprintf + void *code[] = { type, key, item }; ItemKeyFun_releasekey( this, key ); + char *tail = "/@}"; + char *p = buffer; + int i, k, n = 2; + if ( n >= limit ) { + return 0; + } + *(p++) = '{'; + for ( k = 0; k < 3; k++ ) { + i = ItemKeyFun_puthexlong( p, (unsigned long) code[ k ], limit - n ); + n += i + 1; + if ( i == 0 || n >= limit ) { + return 0; + } + *(p++) = tail[k]; + } + *(p++) = 0; return n; } -- 2.39.2