ack/util/led/sym.c

148 lines
4 KiB
C
Raw Permalink Normal View History

1987-03-09 19:15:41 +00:00
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
1985-01-10 13:35:39 +00:00
#ifndef lint
1994-06-24 11:31:16 +00:00
static char rcsid[] = "$Id$";
1985-01-10 13:35:39 +00:00
#endif
/*
* Symbol table management.
*/
#include <stdio.h>
2017-01-18 18:55:56 +00:00
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "out.h"
1985-01-10 13:35:39 +00:00
#include "const.h"
#include "error.h"
1985-01-10 13:35:39 +00:00
#include "memory.h"
#include "debug.h"
#include "save.h"
#include "sym.h"
1985-01-10 13:35:39 +00:00
/*
* Symbol table types. Each hash table entry contains the offset of a symbol
* struct. `Sy_name' contains the offset the name in the piece of global
* names. `Sy_next' contains the offset of the next symbol of which the
* corresponding name has the same hash value.
*/
struct symbol {
ind_t sy_name;
ind_t sy_next;
};
#define NHASH 307 /* Size of hash table. Must be odd. */
1985-01-10 13:35:39 +00:00
static ind_t hashtable[NHASH];
unsigned short NLocals = 0; /* Number of local names to be saved. */
unsigned short NGlobals = 0; /* Number of global names. */
1985-01-10 13:35:39 +00:00
/*
* Initialize the symbol table. All indices should be noticeably invalid.
*/
void init_symboltable(void)
1985-01-10 13:35:39 +00:00
{
register ind_t *rap;
for (rap = hashtable; rap < &hashtable[NHASH]; rap++)
*rap = BADOFF;
}
/*
* Search for `string' in the symboltable. The hash value of `string' is in
* `hashval'. The linked list belonging to the entry of hashval
* in the hash table is followed. If the names match, a pointer to the outname
* in this element of the list is returned. When a match cannot be found,
* NIL is returned.
2017-01-18 18:55:56 +00:00
*/
struct outname *searchname(char *string, int hashval)
1985-01-10 13:35:39 +00:00
{
register char *rcp;
register char *namestring;
register ind_t symindex;
register struct outname *name;
register struct symbol *sym;
symindex = hashtable[hashval];
debug("looking for %s %d %z:", string, hashval,
(size_t)hashtable[hashval], 0);
1985-01-10 13:35:39 +00:00
while (symindex != BADOFF) {
sym = (struct symbol *)address(ALLOSYMB, symindex);
name = (struct outname *)address(ALLOGLOB, sym->sy_name);
namestring = address(ALLOGCHR, (ind_t)name->on_foff);
rcp = string;
debug("comp %s;", namestring, 0, 0, 0);
1985-01-10 13:35:39 +00:00
while (*rcp == *namestring++)
if (*rcp++ == '\0') {
debug("found %x, %x, %lx\n",
name->on_type, name->on_desc,
(unsigned long)name->on_valu, 0);
1985-01-10 13:35:39 +00:00
return name;
2017-01-18 18:55:56 +00:00
}
1985-01-10 13:35:39 +00:00
symindex = sym->sy_next;
}
/* Not found. */
debug("not found\n", 0, 0, 0, 0);
1985-01-10 13:35:39 +00:00
return (struct outname *)0;
}
/*
* Enter a new name in the symbol table. We must copy everything to a
* new entry. `Name' is a private copy, i.e. the pointer to it will not be
* destroyed by allocation. However, the string of which name->on_foff is the
* offset can be destroyed, so we save it first.
*/
void entername(struct outname* name, int hashval)
1985-01-10 13:35:39 +00:00
{
ind_t savindex;
ind_t symindex;
ind_t namindex;
register struct symbol *sym;
1985-01-10 13:35:39 +00:00
struct outname *newname;
debug("entername %s %d %x %x", modulptr((ind_t)name->on_foff), hashval, name->on_type, name->on_desc);
1985-01-10 13:35:39 +00:00
savindex = savechar(ALLOGCHR, (ind_t)name->on_foff);
symindex = hard_alloc(ALLOSYMB, (long)sizeof(struct symbol));
debug("; %z\n", (size_t)symindex, 0, 0, 0);
namindex = hard_alloc(ALLOGLOB, (long)sizeof(struct outname));
1985-01-10 13:35:39 +00:00
if (savindex == BADOFF || symindex == BADOFF || namindex == BADOFF)
fatal("symbol table overflow");
sym = (struct symbol *)address(ALLOSYMB, symindex);
sym->sy_name = namindex;
newname = (struct outname *)address(ALLOGLOB, namindex);
*newname = *name;
newname->on_foff = savindex;
sym->sy_next = hashtable[hashval];
hashtable[hashval] = symindex;
NGlobals++;
1985-01-10 13:35:39 +00:00
}
/*
* Return the index of `name' in the symbol table in the order in which
* it was entered. We need a REAL index, not a byte offset.
*/
unsigned int indexof(struct outname *name)
1985-01-10 13:35:39 +00:00
{
return name - (struct outname *)address(ALLOGLOB, (ind_t)0);
}
/*
* Assign an integer to the string in p.
* 0 <= hash(p) < NHASH, so it can - and will - be used
* as index in a hash table.
*/
int hash(register char* p)
1985-01-10 13:35:39 +00:00
{
register unsigned short h = 0;
1985-01-10 13:35:39 +00:00
register int c;
while ((c = *p++) != '\0') {
1985-01-10 13:35:39 +00:00
h <<= 2;
h += c;
}
return h % NHASH;
1985-01-10 13:35:39 +00:00
}