1 /**********************************************************************
4 * Identifier Processing *
7 **********************************************************************/
12 #include "constants.h"
16 /* partain: special version for strings that may have NULs (etc) in them
17 (used in UgenUtil.lhs)
34 installHstring(length, s)
42 /* fprintf(stderr, "installHstring: %d, %s\n",length, s); */
44 if (length > 999999) { /* too long */
45 fprintf(stderr,"String length more than six digits\n");
47 } else if (length < 0) { /* too short */
48 fprintf(stderr,"String length < 0 !!\n");
52 /* alloc the struct and store the length */
53 str = (hstring) xmalloc(sizeof(Hstring));
62 /* now store the string */
63 for (i = 0; i < length; i++) {
72 /**********************************************************************
75 * Hashed Identifiers *
78 **********************************************************************/
81 extern BOOLEAN hashIds; /* Whether to use hashed ids. */
83 unsigned hash_table_size = HASH_TABLE_SIZE;
85 static char **hashtab = NULL;
87 static unsigned max_hash_table_entries = 0;
97 /* Create an initialised hash table */
98 hashtab = (char **) calloc( hash_table_size, sizeof(char *) );
101 fprintf(stderr,"Cannot allocate a hash table with %d entries -- insufficient memory\n",hash_table_size);
105 fprintf(stderr,"hashtab = %x\n",hashtab);
108 /* Allow no more than 90% occupancy -- Divide first to avoid overflows with BIG tables! */
109 max_hash_table_entries = (hash_table_size / 10) * 9;
120 printf("%u ",hash_table_size);
122 for(i=0; i < hash_table_size; ++i)
123 if(hashtab[i] != NULL)
124 printf("(%u,%s) ",i,hashtab[i]);
133 return((char **) /* YURGH */ ident - hashtab);
138 The hash function. Returns 0 for Null strings.
141 static unsigned hash_fn(char *ident)
143 unsigned len = (unsigned) strlen(ident);
149 /* does not work well for hash tables with more than 35K elements */
150 res = (((unsigned)ident[0]*631)+((unsigned)ident[len/2-1]*217)+((unsigned)ident[len-1]*43)+len)
154 fprintf(stderr,"\"%s\" hashes to %d\n",ident,res);
161 Install a literal identifier, such as "+" in hsparser.
162 If we are not using hashing, just return the string.
169 return( hashIds? installid(s): s);
177 return( hashIds? *(char **)sp: (char *)sp );
184 unsigned hash, count;
189 for(hash = hash_fn(s),count=0; count<max_hash_table_entries; ++hash,++count)
191 if (hash >= hash_table_size) hash = 0;
193 if(hashtab[hash] == NULL)
195 hashtab[hash] = xstrdup(s);
197 fprintf(stderr,"New Hash Entry %x\n",(char *)&hashtab[hash]);
199 if ( count >= 100 ) {
200 fprintf(stderr, "installid: %d collisions for %s\n", count, s);
203 return((char *)&hashtab[hash]);
206 if(strcmp(hashtab[hash],s) == 0)
209 fprintf(stderr,"Old Hash Entry %x (%s)\n",(char *)&hashtab[hash],hashtab[hash]);
211 if ( count >= 100 ) {
212 fprintf(stderr, "installid: %d collisions for %s\n", count, s);
215 return((char *)&hashtab[hash]);
218 fprintf(stderr,"Hash Table Contains more than %d entries -- make larger?\n",max_hash_table_entries);
222 /**********************************************************************
228 **********************************************************************/
237 return(gnoqual((struct Snoqual *)q));
239 return(gqualname((struct Saqual *)q));
241 return(gidname((struct Sgid *)q));
249 return(id_to_string(qid_to_id(q)));
261 return(id_to_string(gqualmod((struct Saqual *)q)));
271 char *mod = qid_to_mod(q);
272 if (mod == NULL) mod = "?";
276 /* Darkly mysterious function used to construct "special-syntax"
277 identifiers. These mean their prelude versions regardless of
278 context, which is why they are distinguished.
280 We build a gid node (rather than a qual or non-qual name node;
281 look at qid.ugn) with a key (number) and a string. Here's the
286 ARROWCON function arrow ->
287 LISTCON list type constructor [], or the empty list []
288 UNITCON unit type constructor (), or the unity value ()
289 n n-tuple type constructor (,,,)
298 return(mkgid(i,install_literal("->")));
300 return(mkgid(i,install_literal("[]")));
302 return(mkgid(i,install_literal("()")));
305 char tmp[64]; int c = 0;
307 while (c <= i) tmp[c++] = ',';
310 return(mkgid(i,installid(tmp)));
315 /**********************************************************************
318 * Memory Allocation *
321 **********************************************************************/
323 /* Malloc with error checking */
329 char *stuff = malloc(length);
332 fprintf(stderr, "xmalloc failed on a request for %d bytes\n", length);
339 xrealloc(ptr, length)
343 char *stuff = realloc(ptr, length);
346 fprintf(stderr, "xrealloc failed on a request for %d bytes\n", length);
352 /* Strdup with error checking */
358 unsigned len = strlen(s);
359 return xstrndup(s, len);
363 * Strdup for possibly unterminated strings (e.g. substrings of longer strings)
364 * with error checking. Handles NULs as well.
372 char *p = xmalloc(len + 1);