📄 util.c
字号:
/* * @(#)util.c 1.7 02/09/27 * * Copyright 1995-1999 by Sun Microsystems, Inc., * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. * All rights reserved. * * This software is the confidential and proprietary information * of Sun Microsystems, Inc. ("Confidential Information"). You * shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with Sun. * Use is subject to license terms. *//*========================================================================= * SYSTEM: Verifier * SUBSYSTEM: Utility functions. * FILE: util.c * OVERVIEW: Utility routines needed by both the compiler and the interpreter. * * AUTHOR: Sheng Liang, Sun Microsystems, Inc. * Edited by Tasneem Sayeed, Sun Microsystems *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include <stdio.h>#include <string.h>#include <ctype.h>#include <stddef.h>#include <oobj.h>#include <utf.h>#include <sys_api.h>#include <path.h> /* DIR_SEPARATOR *//*========================================================================= * Globals and extern declarations *=======================================================================*/extern struct StrIDhash *nameTypeHash;extern struct StrIDhash *stringHash;unicode *str2unicode(char *str, unicode *ustr, long len){ unicode *dst = ustr; memset((char *) dst, 0, len * sizeof(*dst)); while (*str && --len >= 0) *ustr++ = 0xff & *str++; return dst;}voidunicode2str(unicode *src, char *dst, long len){ while (--len >= 0) *dst++ = (char)(*src++); *dst = '\0';}intjio_printf (const char *format, ...){ int len; va_list args; va_start(args, format); len = jio_vfprintf(stdout, format, args); va_end(args); return len;}intjio_fprintf (FILE *handle, const char *format, ...){ int len; va_list args; va_start(args, format); len = jio_vfprintf(handle, format, args); va_end(args); return len;}intjio_vfprintf (FILE *handle, const char *format, va_list args){ return vfprintf(handle, format, args);}/* * Print s null terminated C-style character string. */voidprints(char *s){ jio_fprintf(stdout, "%s", s);}#undef HTSIZE /* Avoid conflict on PC */#define HTSIZE 2003 /* Default size -- must be prime */#define HTOVERFLOWPOINT(h) (h->size * 4 / 5)/* * We store most of the result of the hash in hash_bits to quickly * reject impossible matches because strcmp() is fairly expensive, * especially when many strings will have common prefixes. */typedef struct { char *hash; /* the string for this entry */ unsigned is_malloced : 1; /* 1 if hash was malloced */ unsigned hash_bits : 31; /* low 31 bits of the hash */} StrIDhashSlot;typedef void (*hash_fn)(const char *s, unsigned *h1, unsigned *h2);typedef struct StrIDhash { int size; /* number of entries */ hash_fn hash; /* hash function for this table */ struct StrIDhash *next; /* next bucket */ short used; /* number of full entries */ short baseid; /* ID for item in slot[0] */ void **params; /* param table, if needed */ StrIDhashSlot slot[1]; /* expanded to be number of slots */} StrIDhash;/* Hash a string into a primary and secondary hash value */static voiddefault_hash(const char *s, unsigned *h1, unsigned *h2){ int i; unsigned raw_hash; for (raw_hash = 0; (i = *s) != '\0'; ++s) raw_hash = raw_hash * 37 + i; *h1 = raw_hash; *h2 = (raw_hash & 7) + 1; /* between 1 and 8 */}/* Create a hash table of the specified size */static StrIDhash *createHash(int entries){ StrIDhash *h; int size = offsetof(struct StrIDhash, slot) + (entries * sizeof(h->slot)); h = (StrIDhash *)sysCalloc(1, size); if (h != NULL) { h->size = entries; h->hash = default_hash; /* only custom tables get something else */ h->next = NULL; } return h;}/* * Given a string, return a unique 16 bit id number. * If param isn't null, we also set up an array of void * for holding info * about each object. The address of this void * is stored into param * If CopyNeeded is true, then the name argument "s" must be dup'ed, since * the current item is allocated on the stack. * * Note about returning 0 in the case of out of memory errors: 0 is *not* * a valid ID! The out of memory error should be thrown by the calling code. */unsigned shortStr2ID(StrIDhash **hash_ptr, register char *s, void ***param, int CopyNeeded){ /* * The database is a hash table. When the hash table overflows, a new * hashtable is created chained onto the previous one. This is done so * that we can use the hashtable slot index as the ID, without worrying * about having the IDs change when the hashtable grows. */ StrIDhash *h = *hash_ptr; long i; unsigned primary_hash; unsigned secondary_hash; unsigned hash_bits; hash_fn current_hash_func = NULL; if (h == NULL) goto not_found; /* Create the hash values */ current_hash_func = h->hash; current_hash_func(s, &primary_hash, &secondary_hash); hash_bits = primary_hash & ((1u << 31) - 1); for (;;) { char *s2; int bucketSize = h->size; /* See if the new hash table has a different hash function */ if (h->hash != current_hash_func) { current_hash_func = h->hash; current_hash_func(s, &primary_hash, &secondary_hash); hash_bits = primary_hash & ((1u << 31) - 1); } i = primary_hash % bucketSize; while ((s2 = h->slot[i].hash) != NULL) { if (h->slot[i].hash_bits == hash_bits && strcmp(s2, s) == 0) goto found_it; if ((i -= secondary_hash) < 0) i += bucketSize; } /* Not found in this table. Try the next table. */ if (h->next == NULL) break; h = h->next; } not_found: /* Either the hash table is empty, or the item isn't yet found. */ if (h == NULL || (h->used >= HTOVERFLOWPOINT(h))) { /* Need to create a new bucket */ StrIDhash *next; if (h && h->baseid > 30000 && *hash_ptr != stringHash) { panic("16-bit string hash table overflow"); } next = createHash(HTSIZE); if (next == NULL) { /* Calling code should signal OutOfMemoryError */ return 0; } if (h == NULL) { /* Create a new table */ *hash_ptr = h = next; h->baseid = 1; /* guarantee that no ID is 0 */ } else { next->baseid = h->baseid + h->size; h->next = next; h = next; } if (h->hash != current_hash_func) { current_hash_func = h->hash; current_hash_func(s, &primary_hash, &secondary_hash); hash_bits = primary_hash & ((1u << 31) - 1); } i = primary_hash % h->size; } if (CopyNeeded) { char *d = strdup(s); if (d == NULL) { /* Calling code should signal OutOfMemoryError */ return 0; } s = d; h->slot[i].is_malloced = 1; } h->slot[i].hash = s; h->slot[i].hash_bits = hash_bits; h->used++;found_it: /* We have found or created slot "i" in hash bucket "h" */ if (param != NULL) { if (h->params == NULL) { h->params = sysCalloc(h->size, sizeof(void *)); if (h->params == NULL) { /* Calling code should signal OutOfMemoryError */ return 0; } } *param = &(h->params[i]); } return (unsigned short)(h->baseid + i);}/* Free an StrIDhash table and all the entries in it */void Str2IDFree(StrIDhash **hash_ptr){ StrIDhash *hash = *hash_ptr; while (hash != NULL) { StrIDhash *next = hash->next; StrIDhashSlot *ptr, *endPtr; for (ptr = &hash->slot[0], endPtr = ptr + hash->size; ptr < endPtr; ptr++) { if (ptr->is_malloced) sysFree(ptr->hash); } if (hash->params != NULL) sysFree(hash->params); sysFree(hash); hash = next; } *hash_ptr = 0;}/* * Call the callback function on every entry in the table. This * should only be invoked holding the string hash table lock. */void Str2IDCallback(StrIDhash **hash_ptr, void (*callback)(char *, void *)){ StrIDhash *hash, *next; int i; hash = *hash_ptr; while (hash) { void **params = hash->params; next = hash->next; for (i = 0; i < hash->size; i++) { if (hash->slot[i].hash != 0) { callback(hash->slot[i].hash, params ? params[i] : NULL); } } hash = next; }}/* * Returns NULL in the case of an error. */char *ID2Str(StrIDhash *h, unsigned short ID, void ***param){ int entry; while ((long)(ID - h->baseid) >= h->size) { h = h->next; } entry = ID - h->baseid; if (param != NULL) { if (h->params == NULL) { h->params = (void **)sysCalloc(h->size, sizeof(*param)); if (h->params == NULL) { /* Calling code should signal OutOfMemoryError */ return NULL; } } *param = &h->params[entry]; } return h->slot[entry].hash;}char *addstr(char *s, char *buf, char *limit, char term){ char c; while ((c = *s) && c != term && buf < limit) { *buf++ = c; s++; } return buf;}char *unicode2rd(unicode *s, long len){ /* unicode string to readable C string */#define CSTRLEN 40 static char buf[CSTRLEN+1]; char *dp = buf; int c; if (s == 0) return "NULL"; *dp++ = '"'; while (--len>=0 && (c = *s++) != 0 && dp < buf + sizeof buf - 10) if (040 <= c && c < 0177) *dp++ = c; else switch (c) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -