mirror of
https://github.com/RTimothyEdwards/magic.git
synced 2026-08-30 09:58:55 +02:00
client data generated by ext2spice and attached to a node's nodeClient record; there is an initNodeClient() routine but no corresponding freeNodeClient() routine. Eventually had to add a callback function passed to EFDone() and EFFlatDone() to clean up these entries. After doing that, valgrind reports clean for all memory allocated within ext2spice (there are other things that are not freed but not related to a specific command, so do not need to be treated as leaks).
264 lines
6.8 KiB
C
264 lines
6.8 KiB
C
/*
|
|
* EFdef.c -
|
|
*
|
|
* Procedures for managing the database of Defs.
|
|
* There is a single Def for each .ext file in a hierarchically
|
|
* extracted circuit.
|
|
*
|
|
* *********************************************************************
|
|
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
|
* * Permission to use, copy, modify, and distribute this *
|
|
* * software and its documentation for any purpose and without *
|
|
* * fee is hereby granted, provided that the above copyright *
|
|
* * notice appear in all copies. The University of California *
|
|
* * makes no representations about the suitability of this *
|
|
* * software for any purpose. It is provided "as is" without *
|
|
* * express or implied warranty. Export of this software outside *
|
|
* * of the United States of America may require an export license. *
|
|
* *********************************************************************
|
|
*/
|
|
|
|
#ifndef lint
|
|
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/extflat/EFdef.c,v 1.2 2008/12/03 14:12:09 tim Exp $";
|
|
#endif /* not lint */
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "utils/magic.h"
|
|
#include "utils/geometry.h"
|
|
#include "utils/hash.h"
|
|
#include "utils/utils.h"
|
|
#include "utils/malloc.h"
|
|
#include "extflat/extflat.h"
|
|
#include "extflat/EFint.h"
|
|
|
|
/* Initial size of def hash table */
|
|
#define INITDEFSIZE 128
|
|
|
|
/* Initial size of node hash table in each def */
|
|
#define INITNODESIZE 32
|
|
|
|
/* Def hash table itself; maps from def names into pointers to Defs */
|
|
HashTable efDefHashTable;
|
|
|
|
/* Hash table used for checking for malloc leaks */
|
|
HashTable efFreeHashTable;
|
|
|
|
/* Hash table used for keeping subcircuit parameter names for a device */
|
|
HashTable efDevParamTable;
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* EFInit --
|
|
*
|
|
* Initialize the hash table of def names and global signal names.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* See above.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
EFInit()
|
|
{
|
|
EFLayerNumNames = 1;
|
|
EFDevNumTypes = 0;
|
|
EFCompat = TRUE;
|
|
|
|
HashInit(&efFreeHashTable, 32, HT_WORDKEYS);
|
|
HashInit(&efDefHashTable, INITDEFSIZE, 0);
|
|
HashInit(&efDevParamTable, 8, HT_STRINGKEYS);
|
|
efSymInit();
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* EFDone --
|
|
*
|
|
* Overall cleanup. For use of func(), see efFreeNodeList() in EFbuild.c.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* Eliminates the def and global name hash tables.
|
|
* If malloc tracing is enabled, also frees everything else we
|
|
* allocated with malloc.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
EFDone(func)
|
|
int (*func)();
|
|
{
|
|
Connection *conn;
|
|
HashSearch hs;
|
|
HashEntry *he;
|
|
Kill *kill;
|
|
Def *def;
|
|
Use *use;
|
|
int n;
|
|
|
|
HashStartSearch(&hs);
|
|
while (he = HashNext(&efDefHashTable, &hs))
|
|
{
|
|
def = (Def *) HashGetValue(he);
|
|
freeMagic(def->def_name);
|
|
efFreeNodeTable(&def->def_nodes);
|
|
efFreeNodeList(&def->def_firstn, func);
|
|
efFreeUseTable(&def->def_uses);
|
|
efFreeDevTable(&def->def_devs);
|
|
HashKill(&def->def_nodes);
|
|
HashKill(&def->def_dists);
|
|
HashKill(&def->def_uses);
|
|
HashKill(&def->def_devs);
|
|
for (conn = def->def_conns; conn; conn = conn->conn_next)
|
|
efFreeConn(conn);
|
|
for (conn = def->def_caps; conn; conn = conn->conn_next)
|
|
efFreeConn(conn);
|
|
for (conn = def->def_resistors; conn; conn = conn->conn_next)
|
|
efFreeConn(conn);
|
|
|
|
for (kill = def->def_kills; kill; kill = kill->kill_next)
|
|
{
|
|
freeMagic(kill->kill_name);
|
|
freeMagic((char *) kill);
|
|
}
|
|
freeMagic((char *) def);
|
|
}
|
|
|
|
/* Misc cleanup */
|
|
for (n = 0; n < EFDevNumTypes; n++) freeMagic(EFDevTypes[n]);
|
|
EFDevNumTypes = 0;
|
|
|
|
/* Changed from n = 0 to n = 1; First entry "space" is predefined, */
|
|
/* not malloc'd. ---Tim 9/3/02 */
|
|
for (n = 1; n < EFLayerNumNames; n++) freeMagic(EFLayerNames[n]);
|
|
|
|
if (EFTech)
|
|
{
|
|
freeMagic(EFTech);
|
|
EFTech = (char *)NULL;
|
|
}
|
|
|
|
/* Free up the parameter name tables for each device */
|
|
|
|
HashStartSearch(&hs);
|
|
while (he = HashNext(&efDevParamTable, &hs))
|
|
{
|
|
DevParam *plist = (DevParam *)HashGetValue(he);
|
|
while (plist != NULL)
|
|
{
|
|
freeMagic(plist->parm_name);
|
|
freeMagic(plist);
|
|
plist = plist->parm_next;
|
|
}
|
|
}
|
|
HashKill(&efDevParamTable);
|
|
|
|
HashStartSearch(&hs);
|
|
while (he = HashNext(&efFreeHashTable, &hs))
|
|
{
|
|
/* Keys of this table are entries to be free'd */
|
|
freeMagic(he->h_key.h_ptr);
|
|
}
|
|
HashKill(&efFreeHashTable);
|
|
|
|
/* Final cleanup */
|
|
HashKill(&efDefHashTable);
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* efDefLook --
|
|
*
|
|
* Look for a def by the given name in the hash table.
|
|
* If the def doesn't exist, return NULL; otherwise, return
|
|
* a pointer to the def.
|
|
*
|
|
* Results:
|
|
* Returns a pointer to a def, or NULL if none by that
|
|
* name exists.
|
|
*
|
|
* Side effects:
|
|
* None.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
Def *
|
|
efDefLook(name)
|
|
char *name;
|
|
{
|
|
HashEntry *he;
|
|
|
|
he = HashLookOnly(&efDefHashTable, name);
|
|
if (he == (HashEntry*) NULL)
|
|
return ((Def *) NULL);
|
|
|
|
return ((Def *) HashGetValue(he));
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* efDefNew --
|
|
*
|
|
* Allocate a new def by the given name.
|
|
*
|
|
* Results:
|
|
* Returns a pointer to a def.
|
|
*
|
|
* Side effects:
|
|
* Allocates a new def and initializes it.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
Def *
|
|
efDefNew(name)
|
|
char *name;
|
|
{
|
|
HashEntry *he;
|
|
Def *newdef;
|
|
|
|
he = HashFind(&efDefHashTable, name);
|
|
newdef = (Def *) mallocMagic((unsigned) (sizeof (Def)));
|
|
HashSetValue(he, (char *) newdef);
|
|
|
|
newdef->def_name = StrDup((char **) NULL, name);
|
|
newdef->def_flags = 0;
|
|
newdef->def_scale = 1.0;
|
|
newdef->def_conns = (Connection *) NULL;
|
|
newdef->def_caps = (Connection *) NULL;
|
|
newdef->def_resistors = (Connection *) NULL;
|
|
newdef->def_kills = (Kill *) NULL;
|
|
|
|
/* Initialize circular list of nodes */
|
|
newdef->def_firstn.efnode_next = (EFNodeHdr *) &newdef->def_firstn;
|
|
newdef->def_firstn.efnode_prev = (EFNodeHdr *) &newdef->def_firstn;
|
|
|
|
/* Initialize hash table of uses */
|
|
HashInit(&newdef->def_uses, INITNODESIZE, HT_STRINGKEYS);
|
|
|
|
/* Initialize hash table of node names */
|
|
HashInit(&newdef->def_nodes, INITNODESIZE, HT_STRINGKEYS);
|
|
|
|
/* Initialize hash table of devices */
|
|
HashInit(&newdef->def_devs, INITNODESIZE, HT_STRINGKEYS);
|
|
|
|
/* Initialize hash table of distances */
|
|
HashInitClient(&newdef->def_dists, INITNODESIZE, HT_CLIENTKEYS,
|
|
efHNDistCompare, efHNDistCopy, efHNDistHash, efHNDistKill);
|
|
|
|
return (newdef);
|
|
}
|