diff --git a/src/frontend/runcoms.c b/src/frontend/runcoms.c index 9d52e192e..613be5d9e 100644 --- a/src/frontend/runcoms.c +++ b/src/frontend/runcoms.c @@ -14,6 +14,7 @@ Modified: 2000 AlansFixes #include "ngspice/ftedev.h" #include "ngspice/ftedebug.h" #include "ngspice/dvec.h" +#include "ngspice/hash.h" #include "numparam/numpaif.h" @@ -33,6 +34,7 @@ Modified: 2000 AlansFixes static int dosim(char *what, wordlist *wl); extern struct INPmodel *modtab; +extern NGHASHPTR modtabhash; extern struct dbcomm *dbs; extern void NIresetwarnmsg(void); @@ -107,6 +109,7 @@ com_scirc(wordlist *wl) ft_curckt = p; /* get the model table for the current circuit, store it in the global variable modtab */ modtab = ft_curckt->ci_modtab; + modtabhash = ft_curckt->ci_modtabhash; /* get the database for save, iplot, stop */ dbs = ft_curckt->ci_dbs; /* set the numparam dicos structure for use with measure */ diff --git a/src/frontend/runcoms2.c b/src/frontend/runcoms2.c index ac6c9dead..baf43ee79 100644 --- a/src/frontend/runcoms2.c +++ b/src/frontend/runcoms2.c @@ -14,6 +14,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice/ftedebug.h" #include "ngspice/dvec.h" #include "ngspice/trandefs.h" +#include "ngspice/hash.h" #include "circuits.h" #include "runcoms2.h" @@ -33,6 +34,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group extern void line_free_x(struct card *deck, bool recurse); extern INPmodel *modtab; +extern NGHASHPTR modtabhash; #ifdef SHARED_MODULE extern void exec_controls(wordlist *newcontrols); @@ -273,10 +275,11 @@ com_remcirc(wordlist *wl) prev = p; } - /* make first entry in ft_circuits the actual circuit (or NULL) */ + /* make first entry in ft_circuits the current circuit (or NULL) */ ft_curckt = ft_circuits; if (ft_curckt) { modtab = ft_curckt->ci_modtab; + modtabhash = ft_curckt->ci_modtabhash; dbs = ft_curckt->ci_dbs; nupa_set_dicoslist(ft_curckt->ci_dicos); } diff --git a/src/frontend/spiceif.c b/src/frontend/spiceif.c index 724e4f879..c135b37db 100644 --- a/src/frontend/spiceif.c +++ b/src/frontend/spiceif.c @@ -54,6 +54,7 @@ CDHW*/ #include "ngspice/inpdefs.h" #include "ngspice/iferrmsg.h" #include "ngspice/ifsim.h" +#include "ngspice/hash.h" #include "circuits.h" #include "spiceif.h" @@ -75,6 +76,7 @@ CDHW*/ #endif extern INPmodel *modtab; +extern NGHASHPTR modtabhash; extern bool ft_batchmode; static struct variable *parmtovar(IFvalue *pv, IFparm *opt); @@ -160,9 +162,11 @@ if_inpdeck(struct card *deck, INPtables **tab) /* Parse the .model lines. Enter the model into the global model table modtab. */ modtab = NULL; + modtabhash = NULL; INPpas1(ckt, deck->nextcard, *tab); /* store the new model table in the current circuit */ ft_curckt->ci_modtab = modtab; + ft_curckt->ci_modtabhash = modtabhash; /* Scan through the instance lines and parse the circuit. */ INPpas2(ckt, deck->nextcard, *tab, ft_curckt->ci_defTask); diff --git a/src/include/ngspice/ftedefs.h b/src/include/ngspice/ftedefs.h index 471f1c9b2..639707250 100644 --- a/src/include/ngspice/ftedefs.h +++ b/src/include/ngspice/ftedefs.h @@ -17,6 +17,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice/fteparse.h" #include "ngspice/fteinp.h" #include "ngspice/fteoptdefs.h" +#include "ngspice/hash.h" struct ccom; @@ -34,6 +35,7 @@ struct circ { CKTcircuit *ci_ckt; /* The CKTcircuit structure. */ INPtables *ci_symtab; /* The INP symbol table. */ INPmodel *ci_modtab; /* The INP model table. */ + NGHASHPTR ci_modtabhash; /* The INP model hash table. */ struct dbcomm *ci_dbs; /* The database storing save, iplot, stop data */ struct card *ci_deck; /* The input deck. */ struct card *ci_origdeck; /* The input deck, before subckt expansion. */ diff --git a/src/spicelib/parser/inpgmod.c b/src/spicelib/parser/inpgmod.c index 6450abf6d..44dc93989 100644 --- a/src/spicelib/parser/inpgmod.c +++ b/src/spicelib/parser/inpgmod.c @@ -39,6 +39,7 @@ static int INPfindParm(char *name, IFparm *table, int numParms); #endif extern INPmodel *modtab; +extern NGHASHPTR modtabhash; static IFparm * @@ -342,6 +343,33 @@ INPgetMod(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab) printf("In INPgetMod, examining model %s ...\n", name); #endif + modtmp = nghash_find(modtabhash, name); + if (modtmp) { + /* found the model in question - now instantiate if necessary */ + /* and return an appropriate pointer to it */ + +/* if illegal device type */ + if (modtmp->INPmodType < 0) { +#ifdef TRACE + printf("In INPgetMod, illegal device type for model %s ...\n", name); +#endif + * model = NULL; + return tprintf("Unknown device type for model %s\n", name); + } + + /* create unless model is already defined */ + if (!modtmp->INPmodfast) { + int error = create_model(ckt, modtmp, tab); + if (error) { + *model = NULL; + return INPerror(error); + } + } + + *model = modtmp; + return NULL; + } +#if (0) for (modtmp = modtab; modtmp; modtmp = modtmp->INPnextModel) { #ifdef TRACE @@ -374,7 +402,7 @@ INPgetMod(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab) return NULL; } } - +#endif #ifdef TRACE printf("In INPgetMod, didn't find model for %s, using default ...\n", name); #endif diff --git a/src/spicelib/parser/inpkmods.c b/src/spicelib/parser/inpkmods.c index 8e356a840..40c68be51 100644 --- a/src/spicelib/parser/inpkmods.c +++ b/src/spicelib/parser/inpkmods.c @@ -13,6 +13,7 @@ Author: 1985 Thomas L. Quarles extern INPmodel *modtab; +extern NGHASHPTR modtabhash; void INPkillMods(void) { @@ -28,4 +29,11 @@ void INPkillMods(void) FREE(prev); modtab = NULL; ft_curckt->ci_modtab = NULL; + /* free the hash table */ + if (modtabhash) { + nghash_free(modtabhash, NULL, NULL); + modtabhash = NULL; + } + ft_curckt->ci_modtabhash = NULL; + } diff --git a/src/spicelib/parser/inpmkmod.c b/src/spicelib/parser/inpmkmod.c index 456c4f5e4..055d7a66b 100644 --- a/src/spicelib/parser/inpmkmod.c +++ b/src/spicelib/parser/inpmkmod.c @@ -7,10 +7,14 @@ Author: 1985 Thomas L. Quarles #include #include "ngspice/inpdefs.h" #include "ngspice/iferrmsg.h" +#include "ngspice/hash.h" #include "inpxx.h" /* global input model table. */ INPmodel *modtab = NULL; +/* Global input model hash table. + The modelname is the key, the return value is the pointer to the model. */ +NGHASHPTR modtabhash = NULL; /*-------------------------------------------------------------- * This fcn takes the model name and looks to see if it is already @@ -21,33 +25,40 @@ INPmodel *modtab = NULL; int INPmakeMod(char *token, int type, struct card *line) { - register INPmodel **i; - - /* First cycle through model table and see if model name - already exists in there. If it does, just return. */ - for (i = &modtab; *i != NULL; i = &((*i)->INPnextModel)) { - if (strcmp((*i)->INPmodName, token) == 0) { - return (OK); - } + register INPmodel *newm; + /* Initialze the hash table. The default key type is string. + The default comparison function is strcmp.*/ + if (!modtabhash) { + modtabhash = nghash_init(NGHASH_MIN_SIZE); + nghash_unique(modtabhash, TRUE); } + /* If the model is already there, just return. */ + else if (nghash_find(modtabhash, token)) + return (OK); - /* Model name was not already in model table. Therefore stick - it in the model table. Then return. */ + /* Model name was not already in model table. Therefore stick + it in the front of the model table, also into the model hash table. + Then return. */ #ifdef TRACE /* debug statement */ printf("In INPmakeMod, about to insert new model name = %s . . .\n", token); #endif - *i = TMALLOC(INPmodel, 1); - if (*i == NULL) + newm = TMALLOC(INPmodel, 1); + if (newm == NULL) return (E_NOMEM); - (*i)->INPmodName = token; /* model name */ - (*i)->INPmodType = type; /* model type */ - (*i)->INPnextModel = NULL; /* pointer to next model (end of list) */ - (*i)->INPmodLine = line; /* model line */ - (*i)->INPmodfast = NULL; + newm->INPmodName = token; /* model name */ + newm->INPmodType = type; /* model type */ + newm->INPnextModel = modtab; /* pointer to second model */ + newm->INPmodLine = line; /* model line */ + newm->INPmodfast = NULL; + + nghash_insert(modtabhash, token, newm); + + modtab = newm; + return (OK); }