do { /* read the identifier */
if (++pos < idfsize) {
*tg++ = ch;
- hash = ENHASH(hash, ch, pos);
+ hash = ENHASH(hash, ch);
}
ch = GetChar();
} while (in_idf(ch));
hash = STARTHASH();
while (++pos < idfsize && (ch = *cp++)) {
*ncp++ = ch;
- hash = ENHASH(hash, ch, pos);
+ hash = ENHASH(hash, ch);
}
hash = STOPHASH(hash);
*ncp++ = '\0';
fm = tmp;
}
}
-
-char hmask[IDFSIZE];
-
-init_hmask()
-{
- /* A simple congruence random number generator, as
- described in Knuth, vol 2.
- */
- register int h, rnd = HASH_X;
-
- for (h = 0; h < IDFSIZE; h++) {
- hmask[h] = rnd;
- rnd = (HASH_A * rnd + HASH_C) & HASHMASK;
- }
-}
#include "nopp.h"
-/* Since the % operation in the calculation of the hash function
- turns out to be expensive, it is replaced by the cheaper XOR (^).
- Each character of the identifier is xored with an 8-bit mask which
- depends on the position of the character; the sum of these results
- is the hash value. The random masks are obtained from a
- congruence generator in idf.c.
-*/
+#define HASHSIZE 307 /* must be odd */
-#define HASHSIZE 256 /* must be a power of 2 */
-#define HASH_X 0253 /* Knuth's X */
-#define HASH_A 77 /* Knuth's a */
-#define HASH_C 153 /* Knuth's c */
-
-extern char hmask[]; /* the random masks */
-#define HASHMASK (HASHSIZE-1) /* since it is a power of 2 */
#define STARTHASH() (0)
-#define ENHASH(hs,ch,ps) (hs + (ch ^ hmask[ps]))
-#define STOPHASH(hs) (hs & HASHMASK)
+#define ENHASH(hs,ch) ((hs << 2) + ch)
+#define STOPHASH(hs) ((unsigned)hs % HASHSIZE)
struct idf {
struct idf *next;
/* parse and interpret the command line options */
prog_name = argv[0];
- init_hmask();
#ifndef NOPP
inctable = (char **) Malloc(10 * sizeof(char *));
inctable[0] = "";
char *source = 0;
+#ifdef GEN_NM_LIST
char *nmlist = 0;
+#endif GEN_NM_LIST
compile(argc, argv)
char *argv[];
case 2:
destination = argv[1];
break;
+#ifdef GEN_NM_LIST
case 3:
nmlist = argv[2];
destination = argv[1];
break;
+#endif GEN_NM_LIST
#endif LINT
default:
#ifndef LINT
+#ifdef GEN_NM_LIST
fatal("use: %s source destination [namelist]", prog_name);
+#else GEN_NM_LIST
+ fatal("use: %s source destination", prog_name);
+#endif GEN_NM_LIST
#else LINT
fatal("use: %s source", prog_name);
#endif LINT
do {
if (++pos < idfsize) {
*p++ = ch;
- hash = ENHASH(hash, ch, pos);
+ hash = ENHASH(hash, ch);
}
ch = GetChar();
} while (in_idf(ch));
lint_global_level(local_level);
#endif LINT
+#ifdef GEN_NM_LIST
open_name_list();
+#endif GEN_NM_LIST
while (se) {
register struct idf *idf = se->se_idf;
&& !def->df_initialized) {
/* space must be allocated */
bss(idf);
+#ifdef GEN_NM_LIST
if (def->df_sc != STATIC)
namelist(idf->id_text); /* may be common */
+#endif GEN_NM_LIST
def->df_alloc = ALLOC_DONE; /* see Note below */
}
se = se->next;
*/
}
+#ifdef GEN_NM_LIST
/* A list of potential common names is kept, to be fed to
an understanding loader. The list is written to a file
the name of which is nmlist. If nmlist == NULL, no name
sys_write(nfp, "\n", 1);
}
}
+#endif GEN_NM_LIST