This is eltfuncs.m in view mode; [Download] [Up]
/* Functions for dealing with elt unions Copyright (C) 1993 Free Software Foundation, Inc. Written by: R. Andrew McCallum <mccallum@cs.rochester.edu> Dept. of Computer Science, U. of Rochester, Rochester, NY 14627 This file is part of the GNU Objective-C Collection library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <coll/eltfuncs.h> #include <objc/Object.h> #include <objc/objc-api.h> //#include <objc/hash.h> //#include <coll/collstd.h> /* for -compare: */ /* Is there a better (shorter) way to specify all this junk? */ unsigned int elt_hash_int (elt key) { return (key.int_u); } int elt_compare_ints (elt k1, elt k2) { if (k1.int_u == k2.int_u) return 0; else if (k1.int_u > k2.int_u) return 1; else return -1; } unsigned int elt_hash_unsigned_int (elt key) { return (key.unsigned_int_u); } int elt_compare_unsigned_ints (elt k1, elt k2) { if (k1.unsigned_int_u == k2.unsigned_int_u) return 0; else if (k1.unsigned_int_u > k2.unsigned_int_u) return 1; else return -1; } unsigned int elt_hash_long_int (elt key) { return ((unsigned int)key.long_int_u); } int elt_compare_long_ints (elt k1, elt k2) { if (k1.long_int_u == k2.long_int_u) return 0; else if (k1.long_int_u > k2.long_int_u) return 1; else return -1; } unsigned int elt_hash_unsigned_long_int (elt key) { return ((unsigned int)key.unsigned_long_int_u); } int elt_compare_unsigned_long_ints (elt k1, elt k2) { if (k1.unsigned_long_int_u == k2.unsigned_long_int_u) return 0; else if (k1.unsigned_long_int_u > k2.unsigned_long_int_u) return 1; else return -1; } unsigned int elt_hash_char (elt key) { return ((unsigned int)key.char_u); } int elt_compare_chars (elt k1, elt k2) { if (k1.char_u == k2.char_u) return 0; else if (k1.char_u > k2.char_u) return 1; else return -1; } unsigned int elt_hash_unsigned_char (elt key) { return ((unsigned int)key.unsigned_char_u); } int elt_compare_unsigned_chars (elt k1, elt k2) { if (k1.unsigned_char_u == k2.unsigned_char_u) return 0; else if (k1.unsigned_char_u > k2.unsigned_char_u) return 1; else return -1; } unsigned int elt_hash_short (elt key) { return ((unsigned int)key.short_int_u); } int elt_compare_shorts (elt k1, elt k2) { if (k1.short_int_u == k2.short_int_u) return 0; else if (k1.short_int_u > k2.short_int_u) return 1; else return -1; } unsigned int elt_hash_unsigned_short (elt key) { return ((unsigned int)key.unsigned_short_int_u); } int elt_compare_unsigned_shorts (elt k1, elt k2) { if (k1.unsigned_short_int_u == k2.unsigned_short_int_u) return 0; else if (k1.unsigned_short_int_u > k2.unsigned_short_int_u) return 1; else return -1; } unsigned int elt_hash_float (elt key) { /* There must be a better hash function for floats than this */ return ((unsigned int)key.float_u); } int elt_compare_floats (elt k1, elt k2) { float diff = k1.float_u - k2.float_u; if (diff == 0) return 0; else if (diff > 0) return 1; else return -1; } #if (ELT_INCLUDES_DOUBLE) unsigned int elt_hash_double (elt key) { /* There must be a better hash function for doubles than this. Fix this nonsense: */ return ((unsigned int)key.double_u); } int elt_compare_doubles (elt k1, elt k2) { double diff = k1.double_u - k2.double_u; if (diff == 0) return 0; else if (diff > 0) return 1; else return -1; } #endif int elt_compare_strings (elt k1, elt k2) { return strcmp (k1.char_ptr_u, k2.char_ptr_u); } unsigned int elt_hash_string (elt key) { unsigned int ret = 0; unsigned int ctr = 0; while (*key.char_ptr_u) { ret ^= *key.char_ptr_u++ << ctr; ctr = (ctr + 1) % sizeof (void *); } return ret; } int elt_compare_void_ptrs (elt k1, elt k2) { if (k1.void_ptr_u == k2.void_ptr_u) return 0; else if (k1.void_ptr_u > k2.void_ptr_u) return 1; else return -1; } unsigned int elt_hash_void_ptr (elt key) { return ((unsigned)key.void_ptr_u) / sizeof(void *); } unsigned int elt_hash_object (elt key) { return [key.id_u hash]; } int elt_compare_objects (elt k1, elt k2) { return [k1.id_u compare:k2.id_u]; } int (*(elt_get_comparison_function(const char *encoding)))(elt,elt) { switch (*encoding) { case _C_CHARPTR: case _C_ATOM: return elt_compare_strings; case _C_ID: case _C_CLASS: /* isEqual: on classes works well? */ return elt_compare_objects; case _C_PTR: return elt_compare_void_ptrs; case _C_INT: return elt_compare_ints; case _C_SEL: /* is this where this belongs? */ case _C_UINT: return elt_compare_unsigned_ints; case _C_FLT: return elt_compare_floats; case _C_LNG: return elt_compare_long_ints; case _C_ULNG: return elt_compare_unsigned_long_ints; case _C_CHR: return elt_compare_chars; case _C_UCHR: return elt_compare_unsigned_chars; case _C_SHT: return elt_compare_shorts; case _C_USHT: return elt_compare_unsigned_shorts; default : return 0; } } unsigned int (*(elt_get_hash_function(const char *encoding)))(elt) { switch (*encoding) { case _C_CHARPTR: case _C_ATOM: return elt_hash_string; case _C_ID: case _C_CLASS: /* I can send classes isEqual:? */ return elt_hash_object; case _C_PTR: return elt_hash_void_ptr; case _C_INT: return elt_hash_int; case _C_SEL: /* is this where this belongs? */ case _C_UINT: return elt_hash_unsigned_int; case _C_FLT: return elt_hash_float; case _C_LNG: return elt_hash_long_int; case _C_ULNG: return elt_hash_unsigned_long_int; case _C_CHR: return elt_hash_char; case _C_UCHR: return elt_hash_unsigned_char; case _C_SHT: return elt_hash_short; case _C_USHT: return elt_hash_unsigned_short; default : return 0; } } static cache_ptr __comp_func_hashtable = 0; #define INIT_COMP_FUNC_HASHTABLE_SIZE 32 static inline void __init_comp_func_hashtable() { __comp_func_hashtable = hash_new(INIT_COMP_FUNC_HASHTABLE_SIZE, (hash_func_type)hash_ptr, (compare_func_type)compare_ptrs); hash_add(&__comp_func_hashtable, (void*)elt_compare_ints, @encode(int)); hash_add(&__comp_func_hashtable, (void*)elt_compare_unsigned_ints, @encode(unsigned int)); hash_add(&__comp_func_hashtable, (void*)elt_compare_long_ints, @encode(long int)); hash_add(&__comp_func_hashtable, (void*)elt_compare_unsigned_long_ints, @encode(unsigned long int)); hash_add(&__comp_func_hashtable, (void*)elt_compare_chars, @encode(char)); hash_add(&__comp_func_hashtable, (void*)elt_compare_unsigned_chars, @encode(unsigned char)); hash_add(&__comp_func_hashtable, (void*)elt_compare_shorts, @encode(short)); hash_add(&__comp_func_hashtable, (void*)elt_compare_unsigned_shorts, @encode(unsigned short)); hash_add(&__comp_func_hashtable, (void*)elt_compare_floats, @encode(float)); #if (ELT_INCLUDES_DOUBLE) hash_add(&__comp_func_hashtable, (void*)elt_compare_doubles, @encode(double)); #endif hash_add(&__comp_func_hashtable, (void*)elt_compare_strings, @encode(char*)); hash_add(&__comp_func_hashtable, (void*)elt_compare_void_ptrs, @encode(void*)); hash_add(&__comp_func_hashtable, (void*)elt_compare_objects, @encode(id)); } const char * elt_get_encoding(int(*comparison_function)(elt,elt)) { if (!__comp_func_hashtable) __init_comp_func_hashtable(); return (const char *) hash_value_for_key(__comp_func_hashtable, (void*)comparison_function); } /* Is this really necessary? Can I count on element members always starting at the beginning? */ extern void *elt_get_ptr_to_member(const char *encoding, elt *anElement) { switch (*encoding) { case _C_CHARPTR: case _C_ATOM: return &(anElement->char_ptr_u); case _C_ID: case _C_CLASS: return &(anElement->id_u); case _C_PTR: return &(anElement->void_ptr_u); case _C_SEL: return &(anElement->SEL_u); case _C_CHR: return &(anElement->char_u); case _C_UCHR: return &(anElement->unsigned_char_u); case _C_SHT: return &(anElement->short_int_u); case _C_USHT: return &(anElement->unsigned_short_int_u); break; case _C_INT: return &(anElement->int_u); case _C_UINT: return &(anElement->unsigned_int_u); case _C_LNG: return &(anElement->long_int_u); case _C_ULNG: return &(anElement->unsigned_long_int_u); case _C_FLT: return &(anElement->float_u); #if (ELT_INCLUDES_DOUBLE) case _C_DBL: return &(anElement->double_u); #endif default : return 0; } } // This printing stuff will change when we get Stream objects; void elt_fprintf_elt(FILE *fp, const char *encoding, elt anElement) { switch (*encoding) { case _C_CHARPTR: case _C_ATOM: fprintf(fp, "\"%s\"", anElement.char_ptr_u); break; case _C_ID: case _C_CLASS: fprintf(fp, "%s:0x%x", [anElement.id_u name], anElement.unsigned_int_u); break; case _C_PTR: fprintf(fp, "0x%x", anElement.unsigned_int_u); break; case _C_SEL: fprintf(fp, "%s", sel_get_name(anElement.SEL_u)); break; case _C_CHR: fprintf(fp, "%c", anElement.char_u); break; case _C_UCHR: fprintf(fp, "%c", anElement.unsigned_char_u); break; case _C_SHT: fprintf(fp, "%d", anElement.short_int_u); break; case _C_USHT: fprintf(fp, "%d", anElement.unsigned_short_int_u); break; case _C_INT: fprintf(fp, "%d", anElement.int_u); break; case _C_UINT: fprintf(fp, "%d", anElement.unsigned_int_u); break; case _C_LNG: fprintf(fp, "%d", anElement.long_int_u); break; case _C_ULNG: fprintf(fp, "%d", anElement.unsigned_long_int_u); break; case _C_FLT: fprintf(fp, "%f", anElement.float_u); break; #if (ELT_INCLUDES_DOUBLE) case _C_DBL: fprintf(fp, "%lf", anElement.double_u); break; #endif default : fprintf(fp, "unknown?"); } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.