cc65/src/ar65/exports.c
cuz 76e67e2f97 Changed the object file and library format. There is now an additional
string table in the object file that (currently) holds all identifiers
from the import, export and debug info sections. The plan is to put all
strings into this table, so we have them in a central place and don't
waste memory. Apart from that, the indices are unique, so comparing strings
should be a lot easier than before (as soon as the programs take advantage
of this fact, which is currently not the case).


git-svn-id: svn://svn.cc65.org/cc65/trunk@2169 b7a2c559-68d2-44c3-8de9-860c34a00d81
2003-05-25 17:57:50 +00:00

151 lines
5.1 KiB
C

/*****************************************************************************/
/* */
/* exports.c */
/* */
/* Duplicate export checking for the ar65 archiver */
/* */
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#include <string.h>
/* common */
#include "hashstr.h"
#include "xmalloc.h"
/* ar65 */
#include "error.h"
#include "objdata.h"
#include "exports.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* A hash table entry */
typedef struct HashEntry HashEntry;
struct HashEntry {
HashEntry* Next; /* Next in list */
unsigned Module; /* Module index */
char Name [1]; /* Name of identifier */
};
/* Hash table */
#define HASHTAB_SIZE 4783
static HashEntry* HashTab [HASHTAB_SIZE];
/*****************************************************************************/
/* Code */
/*****************************************************************************/
static HashEntry* NewHashEntry (const char* Name, unsigned Module)
/* Create and return a new hash entry */
{
/* Get the length of the name */
unsigned Len = strlen (Name);
/* Get memory for the struct */
HashEntry* H = xmalloc (sizeof (HashEntry) + Len);
/* Initialize the fields and return it */
H->Next = 0;
H->Module = Module;
memcpy (H->Name, Name, Len);
H->Name [Len] = '\0';
return H;
}
void ExpInsert (const char* Name, unsigned Module)
/* Insert an exported identifier and check if it's already in the list */
{
HashEntry* L;
/* Create a hash value for the given name */
unsigned HashVal = HashStr (Name) % HASHTAB_SIZE;
/* Create a new hash entry */
HashEntry* H = NewHashEntry (Name, Module);
/* Search through the list in that slot and print matching duplicates */
if (HashTab [HashVal] == 0) {
/* The slot is empty */
HashTab [HashVal] = H;
return;
}
L = HashTab [HashVal];
while (1) {
if (strcmp (L->Name, Name) == 0) {
/* Duplicate entry */
Warning ("External symbol `%s' in module `%s' is duplicated in "
"module `%s'",
Name, GetObjName (L->Module), GetObjName (Module));
}
if (L->Next == 0) {
break;
} else {
L = L->Next;
}
}
L->Next = H;
}
int ExpFind (const char* Name)
/* Check for an identifier in the list. Return -1 if not found, otherwise
* return the number of the module, that exports the identifer.
*/
{
/* Get a pointer to the list with the symbols hash value */
HashEntry* L = HashTab [HashStr (Name) % HASHTAB_SIZE];
while (L) {
/* Search through the list in that slot */
if (strcmp (L->Name, Name) == 0) {
/* Entry found */
return L->Module;
}
L = L->Next;
}
/* Not found */
return -1;
}