diff --git a/ChangeLog b/ChangeLog index 8e55c472d..c188f5f07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,109 @@ +2003-07-18 Vera Albrecht + + * src/{main.c,tclspice.c} + src/frontend/{Makefile.am,control.c,control.h,display.c,dotcards.c, + hcomp.c,hpgl.c,outitf.c,parse.c,postcoms.c,postsc.c,runcoms.c, + spiceif.c,variable.c,variable.h,parser/complete.c,plotting/pvec.c} + src/include/{cktdefs.h,ngspice.h} + src/misc/{ivars.c,string.c,stringutil.h} + src/spicelib/analysis/{acan.c,ckt.h,dcop.c} + src/spicelib/devices/bsim3/b3temp.c + src/spicelib/parser/{ifnewuid.c,inp2dot.c,inperror.c} : + Memory leaks and some WINDOWS compile fixes. + +2003-07-17 Stefan Jones + + * src/frontend/{subckt.c,vectors.c} + src/spicelib/analysis/dctran.c + src/spicelib/parser/inperror.c + src/xspice/idn/idndig.c src/xspice/mif/mif_inp2.c : + More memory leak fixes + + * configure.in src/xspice/xspice.c : + Fix compile problems with garbage collector + + * configure.in : + Change --enable-tcl to --with-tcl[=dir] for non-std + install setup. + +2003-07-17 Steven Borley + + * src/frontend/resource.c src/frontend/parser/complete.c + src/spicelib/devices/txl/txlload.c : + #ifdef fixes to get ngspice to compile on Mac OSX + +2003-07-16 Vera Albrecht + + * frontend/{device.c,parse.c,vectors.c,com_compose.c} : + More memory leaks closed in utility commands and functions. + +2003-07-16 Stefan Jones + + * src/frontend/{com_compose.c,cpitf.c,device.c,subckt.c,vectors.c} + src/frontend/plotting/plotit.c src/include/ngspice.h + src/spicelib/parser/{inp2dot.c,inp2r.c,inpdomod.c,inpdpar.c,inpgmod.c,inppas3.c} : + Rest of the serious deck reader leaks, plus fixes for the last batch. + +2003-07-15 Stefan Jones + + * /src/frontend/{com_let.c,com_set.c,evaluate.c,parse.c,variable.c} + src/frontend/parser/complete.c : + Memory leaks plugged + +2003-04-14 Stefan Jones + + * Make all the devices in src/spicelib/devices be built as + archives not shared libraries, and don't install them + +2003-06-22 Stuart Brorson + + * Finally got SPICE2 POLY stuff working. This involved lots of changes + in src/xspice/mif and src/xspice/enh. Particular changes were made in: + -- MIF_INP2A: re-arranged logic to fix parsing problems. + -- two2three_translate: fixed some stupid pointer problems. + -- etc. + + * Revamped src/xspice/icm/ and src/xspice/icm/icm_spice2poly + directories to enable build of POLY codemodel. Makefiles were + fixed, and some stuff was added to enable cmpp (from SPICE Opus) + to build the codemodel precursors correctly. (Note that you need + to download and install SPICE Opus to rebuild the codemodel + stuff. See src/xspice/icm/README for more details.) + + * Hacked Makefile.am's for much of the directory hierarchy, particularly + for src/xspice/icm and src/xspice/icm/icm_spice2poly to build the POLY + codemodel correctly. Note that top level make still doesn't detect + changes in the xspice hierarchy; read the NOTES file for a workaround. + + * Added a SPICE netlist incorporating vendor models with SPICE2 + POLYs in tests/TransImpedanceAmp/. Running this model + successfully demonstrates that you have built the XSpice POLY + codemodel correctly and that life is good . . . . + + * Moved #define TRACE out of src/ngspice.h and made it a compiler + option (-DTRACE) invoked in src/Makefile when making spice.o. + +2003-05-02 Stuart Brorson + + * Added #define TRACE to main.c for use in debugging. Added lots + of printf's in the code which are turned on by defining TRACE. + This is used to help figure out what the program is doing at each + step . . . . . + + * Added lots of comments all over the source tree. This should + help explain what the prog is doing for future hackers. + + * Fixed parser to allow POLY attributes in dependent sources + (major changes in src/frontend/subckt.c, as well as move location + of call to ENHtranslate_poly in src/frontend/inp.c) + + * Fixed bug in device init files (src/spicelib/devices/*init.c) + so that Deviceinfo structures operated with XSPICE. + + * Fixed nasty malloc problem in src/xspice/mif/mifgetmod.c which + casuedfrequent segfaults (when compiled with XSPICE). + + 2002-01-03 Paolo Nenzi * acconfig.h: added define needed for Windows and some aesthetic diff --git a/Makefile.am b/Makefile.am index c0575051e..c88116027 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,3 +13,6 @@ mrproper: maintainer-clean rm -f `find . -type f -name "*~" -print` rm -f `find . -type f -name "*.orig" -print` rm -f `find . -type f -name "*.rej" -print` + +codemodels: + cd src/xspice/icm && make diff --git a/NOTES b/NOTES index 3851bcae1..add7eaf1b 100644 --- a/NOTES +++ b/NOTES @@ -1,3 +1,31 @@ +SPICE 2 POLY CODEMODEL + +SPICE2 POLY attributes are now available for controlled sources. To +use POLY attributes, configure tclspice/ngspice with the +--enable-xspice flag set as described above. After compilation of +ngspice, cd into $(top_srcdir)/src/xspice/icm and read the README file +there for instructions about how to get POLY support. (Hint: you have +to download some stuff from http://www.fe.uni-lj.si/ and edit the +Makefiles before you can do "make && make install" of the codemodel +stuff.) + +-- SDB 6.22.2003. + +-------------------------------------------------------------------- +COMPILING XSPICE CHANGES + +The dependencies in the Makefile don't seem to work when you are +compiling changes in the xspice stuff. Obviously, the best thing to +do is fix Makefile.am, but since I am not an expert at this, I have +been using the following workaround when making: + +touch src/main.c && make && make install + +I recommend you also do this if you hack anything under src/xspice. + +-- SDB 6.19.2003. + +--------------------------------------------------------------------- DEBUGGING SPICE To avoid a segmentation fault in the initial run, use the following diff --git a/acconfig.h b/acconfig.h index 63fdc6319..d26679b6d 100644 --- a/acconfig.h +++ b/acconfig.h @@ -38,6 +38,12 @@ /* We do not want spurios debug info into non-developer code */ #undef FTEDEBUG +/*The xspice enhancements*/ +#undef XSPICE + +/* Spice cluster support */ +#undef CLUSTER + /* Generate MS WINDOWS executable */ #undef HAS_WINDOWS diff --git a/configure.in b/configure.in index e3c783ee7..b16059e29 100644 --- a/configure.in +++ b/configure.in @@ -1,9 +1,6 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(src/main.c) -dnl Keep old autoconf version, procedure is not compatible to new 2.5.2 -AC_PREREQ(2.13) - dnl Create a configuration header AM_CONFIG_HEADER(config.h) @@ -54,6 +51,14 @@ dnl --enable-ekv: define HAVE_EKV in the code. This is for EKV model support AC_ARG_ENABLE(ekv, [ --enable-ekv Enables ekv model *not in standard distribution*]) +dnl --enable-xspice: define XSPICE in the code. This is for xspice support +AC_ARG_ENABLE(xspice, + [ --enable-xspice Enables XSpice enchancements, experimental *not in standard distribution*]) + +dnl --enable-cluster: define CLUSTER in the code. This is for tcl support +AC_ARG_ENABLE(cluster, + [ --enable-cluster Enables cluster support, experimental *not in standard distribution*]) + dnl Enable maintainer commands only if requested AM_MAINTAINER_MODE @@ -108,7 +113,7 @@ dnl Checks for programs AC_LIBTOOL_DLOPEN AM_PROG_LIBTOOL - +AC_PROG_LIBTOOL dnl --with-windows : the user wants to use generate the MS WINDOWS executable AC_ARG_WITH(windows, @@ -123,7 +128,7 @@ case $with_windows in yes ) AC_DEFINE(X_DISPLAY_MISSING) AC_MSG_RESULT(No X display!) - CFLAGS="$CFLAGS -mwindows";; + CFLAGS="$CFLAGS -mwindows"; *) dnl Checks for X11 header files and libraries - X11 support can be disabled @@ -141,12 +146,13 @@ dnl In CYGWIN library ordering has to be changed. Is this compatible to LINUX? dnl XShmAttach is a struct in CYGWIN, not a function if test ! "$no_x" = "yes" ; then - AC_CHECK_LIB(Xaw,main,X_LIBS="$X_LIBS -lXaw",AC_MSG_ERROR(Couldn't find Xaw librairies),$X_LIBS $X_EXTRA_LIBS) - X_LIBS="$X_LIBS -lXt" + X_LIBS="$X_LIBS -lX11 -lXt" + AC_CHECK_LIB(Xext, XShmAttach,X_LIBS="$X_LIBS -lXext",AC_MSG_ERROR(Couldn't find Xext librairies), $X_LIBS $X_EXTRA_LIBS) AC_CHECK_LIB(Xmu,main,X_LIBS="$X_LIBS -lXmu",AC_MSG_ERROR(Couldn't find Xmu librairies), $X_LIBS $X_EXTRA_LIBS) - AC_CHECK_LIB(Xext,main,X_LIBS="$X_LIBS -lXext",AC_MSG_ERROR(Couldn't find Xext librairies), $X_LIBS $X_EXTRA_LIBS) - X_LIBS="$X_LIBS -lX11 -lXpm" -fi ;; + AC_CHECK_LIB(Xaw,main,X_LIBS="$X_LIBS -lXaw",AC_MSG_ERROR(Couldn't find Xaw librairies),$X_LIBS $X_EXTRA_LIBS) + + +fi esac @@ -157,8 +163,8 @@ AC_TYPE_SIGNAL dnl Check for a few libraries and headers: dnl Look for ncurses first, then termcap -#AC_SEARCH_LIBS(tputs,ncurses termcap,AC_DEFINE(HAVE_TERMCAP), -# AC_MSG_ERROR(Found neither ncurses or termcap)) +AC_SEARCH_LIBS(tputs,ncurses termcap,AC_DEFINE(HAVE_TERMCAP), + AC_MSG_ERROR(Found neither ncurses or termcap)) AC_HEADER_DIRENT @@ -175,11 +181,11 @@ AC_CHECK_FUNCS(localtime) case $host_os in *cygwin* ) AC_CHECK_FUNCS(ftime) - AC_DEFINE(HAVE__MEMAVL) ;; + AC_DEFINE(HAVE__MEMAVL) ; * ) AC_CHECK_FUNCS(gettimeofday time ftime , break) AC_CHECK_FUNCS(getrusage utimes, break) - AC_CHECK_FUNCS(getrlimit ulimit, break) ;; + AC_CHECK_FUNCS(getrlimit ulimit, break) ; esac dnl Look for termios first (posix) @@ -208,6 +214,33 @@ AC_CHECK_LIB(gc,GC_malloc,AC_DEFINE(HAVE_LIBGC) LIBS="$LIBS -lgc") dnl Check for the asprintf function: AC_CHECK_FUNCS(asprintf,,AC_CHECK_LIB(iberty,asprintf,AC_DEFINE(HAVE_ASPRINTF) LIBS="$LIBS -liberty")) +dnl Check for va_copy +AC_CACHE_CHECK([for va_copy], ac_cv_c_va_copy, + AC_TRY_LINK( + [#include ], + [va_list ap1, ap2; + va_copy(ap1,ap2); + ], + [ac_cv_c_va_copy="yes"], + [ac_cv_c_va_copy="no"]) + ) +if test "$ac_cv_c_va_copy" = "yes" +then + AC_DEFINE(HAVE_VA_COPY, 1, [Define if we have va_copy]) +fi +AC_CACHE_CHECK([for __va_copy], ac_cv_c___va_copy, + AC_TRY_LINK( + [#include ], + [va_list ap1, ap2; + __va_copy(ap1,ap2); + ], + [ac_cv_c___va_copy="yes"], + [ac_cv_c___va_copy="no"]) + ) +if test "$ac_cv_c___va_copy" = "yes" +then + AC_DEFINE(HAVE___VA_COPY, 1, [Define if we have __va_copy]) +fi # AC_CHECK_FUNC(getopt_long, getopt_long=true) # AM_CONDITIONAL(HAVE_GETOPT_LONG, test "$getopt_long" = "true") @@ -277,6 +310,35 @@ fi AC_SUBST(EKVDIR) AC_SUBST(EKVLIB) +dnl Add new code models to the build by pointing to them here. +if test "$enable_xspice" = "yes"; then + AC_MSG_RESULT(X-Spice features included) + AC_DEFINE(XSPICE) + XSPICEDIR="xspice" + XSPICELIB1="$XSPICEDIR/xspice.o \ + $XSPICEDIR/mif/libmifxsp.a \ + $XSPICEDIR/cm/libcmxsp.a" + XSPICELIB2="$XSPICEDIR/evt/libevtxsp.a \ + $XSPICEDIR/enh/libenhxsp.a \ + $XSPICEDIR/ipc/libipcxsp.a \ + $XSPICEDIR/idn/libidnxsp.a \ + -ldl" + +else + XSPCIEDIR="" + XSPICELIB1="" + XSPICELIB2="" +fi +AC_SUBST(XSPICEDIR) +AC_SUBST(XSPICELIB1) +AC_SUBST(XSPICELIB2) + +dnl Cluster option +if test "$enable_cluster" = "yes"; then + AC_MSG_RESULT(Cluster version is being compiled) + AC_DEFINE(CLUSTER) + LIBS="$LIBS -lpthread" +fi dnl --with-readline : the user wants to use readline library AC_ARG_WITH(readline, @@ -312,6 +374,7 @@ src/spicelib/devices/cap/Makefile \ src/spicelib/devices/cccs/Makefile \ src/spicelib/devices/ccvs/Makefile \ src/spicelib/devices/csw/Makefile \ +src/spicelib/devices/cpl/Makefile \ src/spicelib/devices/dio/Makefile \ src/spicelib/devices/ekv/Makefile \ src/spicelib/devices/ind/Makefile \ @@ -332,6 +395,7 @@ src/spicelib/devices/res/Makefile \ src/spicelib/devices/soi3/Makefile \ src/spicelib/devices/sw/Makefile \ src/spicelib/devices/tra/Makefile \ +src/spicelib/devices/txl/Makefile \ src/spicelib/devices/urc/Makefile \ src/spicelib/devices/vccs/Makefile \ src/spicelib/devices/vcvs/Makefile \ @@ -350,6 +414,15 @@ src/maths/deriv/Makefile \ src/maths/poly/Makefile \ src/maths/sparse/Makefile \ src/misc/Makefile \ +src/xspice/Makefile \ +src/xspice/cm/Makefile \ +src/xspice/icm/Makefile \ +src/xspice/icm/icm_spice2poly/Makefile \ +src/xspice/mif/Makefile \ +src/xspice/evt/Makefile \ +src/xspice/enh/Makefile \ +src/xspice/ipc/Makefile \ +src/xspice/idn/Makefile \ tests/Makefile \ tests/filters/Makefile \ tests/polezero/Makefile \ @@ -357,6 +430,7 @@ tests/resistance/Makefile \ tests/bsim3soipd/Makefile \ tests/bsim3soifd/Makefile \ tests/bsim3soidd/Makefile \ -tests/bsim4/Makefile \ -tests/mesa/Makefile +tests/bsim4/Makefile \ +tests/mesa/Makefile \ +tests/TransImpedanceAmp/Makefile ) diff --git a/src/Makefile.am b/src/Makefile.am index 0967d3c83..a274d08f6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = misc maths frontend spicelib include +SUBDIRS = misc maths frontend spicelib include @XSPICEDIR@ bin_PROGRAMS = ngspice ngnutmeg nghelp ngsconvert ngproc2mod ngmultidec makeidx @@ -18,7 +18,6 @@ initdata_DATA = spinit setplot spectrum DYNAMIC_DEVICELIBS = \ spicelib/devices/asrc/libasrc.la \ spicelib/devices/bjt/libbjt.la \ -## spicelib/devices/bjt2/libbjt2.la \ spicelib/devices/bsim1/libbsim1.la \ spicelib/devices/bsim2/libbsim2.la \ spicelib/devices/bsim3/libbsim3.la \ @@ -32,6 +31,7 @@ DYNAMIC_DEVICELIBS = \ spicelib/devices/cccs/libcccs.la \ spicelib/devices/ccvs/libccvs.la \ spicelib/devices/ccvs/libccvs.la \ + spicelib/devices/cpl/libcpl.a \ spicelib/devices/csw/libcsw.la \ spicelib/devices/dio/libdio.la \ @EKVLIB@ \ @@ -52,12 +52,22 @@ DYNAMIC_DEVICELIBS = \ spicelib/devices/res/libres.la \ spicelib/devices/soi3/libsoi3.la \ spicelib/devices/sw/libsw.la \ + spicelib/devices/txl/libtxl.a \ spicelib/devices/tra/libtra.la \ spicelib/devices/urc/liburc.la \ spicelib/devices/vccs/libvccs.la \ spicelib/devices/vcvs/libvcvs.la \ spicelib/devices/vsrc/libvsrc.la + +## ----- Note that I moved this stuff to here because it was causing automake +## to choke when it was in the DYNAMIC_DEVICELIBS list above ----- +## This lib deleted from DYNAMIC_DEVICELIBS by sdb 'cause there's no source for it. +## spicelib/devices/bjt2/libbjt2.a \ +## poly added to dynamic libs by SDB on 6.1.2003 +## xspice/icm/poly/libpoly.a + + ## Build ngspice first: ngspice_SOURCES = \ @@ -71,10 +81,12 @@ ngspice_LDADD = \ frontend/libfte.a \ frontend/wdisp/libwindisp.a \ frontend/plotting/libplotting.a \ + @XSPICELIB1@ \ spicelib/devices/dev.o \ $(DYNAMIC_DEVICELIBS) \ spicelib/analysis/libckt.a \ spicelib/devices/libdev.a \ + @XSPICELIB2@ \ frontend/parser/libparser.a \ frontend/help/libhlp.a \ spicelib/parser/libinp.a \ diff --git a/src/frontend/ChangeLog b/src/frontend/ChangeLog index 72357a300..7903df20a 100644 --- a/src/frontend/ChangeLog +++ b/src/frontend/ChangeLog @@ -1,3 +1,22 @@ +2003-07-08 Stefan Jones + * quote.c: return the pointer to the start of malloced + memory so it can be freeded + +2003-05-02 Stuart Brorson + * Major changes in subckt.c to handle POLY attributes in + dependent sources. Added new case to switch in "translate" to + handle E, F, G, H sources. Many other fixes. + + * Moved location of call to ENHtranslate_poly in inp.c. This was + necessary to correctly process POLY attributes and the associated + netlists and voltage sources. + +2003-04-10 Stuart Brorson + * modified inp_readall (inpcom.c) to ignore blank + lines terminated by \r\n *and * \n. This fixes problems + associated with importing files from Windozeland. + * Added explanatory comments to many modules. + 2002-01-03 Paolo Nenzi * wdisp: added an entire directory containing windows frontend code diff --git a/src/frontend/Makefile.am b/src/frontend/Makefile.am index 0e78696e0..ce17b81a0 100644 --- a/src/frontend/Makefile.am +++ b/src/frontend/Makefile.am @@ -18,6 +18,8 @@ libfte_a_SOURCES = \ com_chdir.c \ com_compose.c \ com_compose.h \ + com_dl.c \ + com_dl.h \ com_display.c \ com_display.h \ com_dump.c \ @@ -100,6 +102,7 @@ libfte_a_SOURCES = \ fourier.h \ gens.c \ gens.h \ + hpgl.c \ inp.c \ inp.h \ inpcom.c \ diff --git a/src/frontend/com_compose.c b/src/frontend/com_compose.c index 1e0ee732e..f179c2ec5 100644 --- a/src/frontend/com_compose.c +++ b/src/frontend/com_compose.c @@ -118,7 +118,7 @@ com_compose(wordlist *wl) bool realflag = TRUE; int dims[MAXDIMS]; struct dvec *result, *vecs = NULL, *v, *lv = NULL; - struct pnode *pn, *first_pn; + struct pnode *pn, *first_pn=NULL; bool reverse = FALSE; resname = cp_unquote(wl->wl_word); @@ -141,7 +141,6 @@ com_compose(wordlist *wl) ; pn = pn->pn_next; } - free_pnode(first_pn); /* Now make sure these are all of the same dimensionality. We * can coerce the sizes... */ @@ -479,6 +478,7 @@ com_compose(wordlist *wl) result->v_dims[0] = length; vec_new(result); cp_addkword(CT_VECTOR, result->v_name); + free_pnode(first_pn); tfree(resname);/*DG: resname has been copied so its remains allocated: memory leak One can remove this and not copy resname*/ return; } diff --git a/src/frontend/com_let.c b/src/frontend/com_let.c index e27ef0901..22df936f3 100644 --- a/src/frontend/com_let.c +++ b/src/frontend/com_let.c @@ -41,6 +41,7 @@ com_let(wordlist *wl) *rhs++ = 0; } else { fprintf(cp_err, "Error: bad let syntax\n"); + tfree(p); return; } if ((s =strchr(p, '['))) { @@ -63,6 +64,7 @@ com_let(wordlist *wl) if (depth != 0 || !*q) { printf("syntax error specifyingstrchr\n"); + tfree(p); return; } @@ -86,6 +88,7 @@ com_let(wordlist *wl) /* sanity check */ if (eq(p, "all") ||strchr(p, '@')) { fprintf(cp_err, "Error: bad variable name %s\n", p); + tfree(p); return; } @@ -100,7 +103,8 @@ com_let(wordlist *wl) t = ft_evaluate(nn); if (!t) { fprintf(cp_err, "Error: Can't evaluate %s\n", rhs); - tfree(p); + free_pnode(nn); + tfree(p); return; } @@ -116,8 +120,7 @@ com_let(wordlist *wl) } else { if (numdims) { fprintf(cp_err, "Can't assign into a subindex of a new vector\n"); - tfree(p); - return; + goto quit; } /* create and assign a new vector */ @@ -175,16 +178,14 @@ com_let(wordlist *wl) length * cube); if (newvec) n->v_flags &= ~VF_PERMANENT; - tfree(p); - return; + goto quit; } if (isreal(t) != isreal(n)) { fprintf(cp_err, "Types of vectors are not the same (real vs. complex)\n"); if (newvec) n->v_flags &= ~VF_PERMANENT; - tfree(p); - return; + goto quit; } else if (isreal(t)) { bcopy((char *) t->v_realdata, (char *) (n->v_realdata + offset), length * sizeof (double)); @@ -201,7 +202,10 @@ com_let(wordlist *wl) if (newvec) cp_addkword(CT_VECTOR, n->v_name); - /* XXXX Free t !?! */ +quit: + /* va: garbage collection for t, if pnode nn is no simple value */ + if (nn->pn_value==NULL && t!=NULL) vec_free(t); + free_pnode(nn); /* frees also t, if pnode nn is simple value */ tfree(p); return; } diff --git a/src/frontend/com_set.c b/src/frontend/com_set.c index 9cc683d02..42c74993a 100644 --- a/src/frontend/com_set.c +++ b/src/frontend/com_set.c @@ -13,7 +13,7 @@ void com_set(wordlist *wl) { - struct variable *vars; + struct variable *vars, *oldvar; char *s; if (wl == NULL) { @@ -44,8 +44,16 @@ com_set(wordlist *wl) s = (char *) NULL; } cp_vset(vars->va_name, vars->va_type, s); + oldvar = vars; vars = vars->va_next; + /* va: avoid memory leak: free oldvar carefully */ + tfree(oldvar->va_name); + if (oldvar->va_type==VT_STRING) + tfree(oldvar->va_string); /* copied in cp_vset */ + /* don't free oldvar->va_list! This structure is used furthermore! */ + tfree(oldvar); } + return; } diff --git a/src/frontend/commands.c b/src/frontend/commands.c index c5e64b93c..104c0daff 100644 --- a/src/frontend/commands.c +++ b/src/frontend/commands.c @@ -52,6 +52,16 @@ #ifdef EXPERIMENTAL_CODE #include "com_option.h" +void com_loadsnap(wordlist *wl); +void com_savesnap(wordlist *wl); +#endif + +#include "com_dl.h" + +#ifdef XSPICE +/* gtri - begin - wbk - add include files */ +#include "evtproto.h" +/* gtri - end - wbk - add include files */ #endif /* FIXME: Integrate spcp_coms and nutcp_coms into one variable. */ @@ -83,6 +93,14 @@ struct comm spcp_coms[] = { { 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS, arg_set, "[option] [option = value] ... : Set a simulator option." } , + { "savesnap", com_savesnap, FALSE, FALSE, TRUE, + { 1, 040000, 040000, 040000 }, E_DEFHMASK, 1, 1, + (void (*)()) NULL, + "file : Save a snapshot." } , + { "loadsnap", com_loadsnap, FALSE, FALSE, TRUE, + { 1, 040000, 040000, 040000 }, E_DEFHMASK, 2, 2, + (void (*)()) NULL, + "file : Load a snapshot." } , #endif { "alias", com_alias, FALSE, FALSE, FALSE, @@ -149,6 +167,24 @@ struct comm spcp_coms[] = { { 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS, arg_print, "[col] expr ... : Print vector values." } , +#ifdef XSPICE +/* gtri - begin - wbk - add event print command */ + { "eprint", EVTprint, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS, + (void (*)()) NULL, + "node node ... : Print event values." } , +/* gtri - end - wbk - add event print command */ + { "codemodel", com_codemodel, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS, + (void (*)()) NULL, + "library library ... : Loads the opus librarys." } , +#endif +#ifdef DEVLIB + { "use", com_use, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS, + (void (*)()) NULL, + "library library ... : Loads the device librarys." } , +#endif { "load", com_load, FALSE, FALSE, TRUE, { 1, 1, 1, 1 }, E_BEGINNING | E_NOPLOTS, 1, LOTS, arg_load, diff --git a/src/frontend/control.c b/src/frontend/control.c index 3dd6fbb5f..2d9a99aa3 100644 --- a/src/frontend/control.c +++ b/src/frontend/control.c @@ -50,7 +50,7 @@ int stackp = 0; /* Notes by CDHW: * This routine leaked like a sieve because each getcommand() created a - * wordlist that was never freed becuase it might have been added into + * wordlist that was never freed because it might have been added into * the control structure. I've tackled this by making sure that everything * put into the cend[stackp] is a copy. This means that wlist can be * destroyed safely @@ -372,6 +372,8 @@ doblock(struct control *bl, int *num) /*...CDHW*/ while ((bl->co_timestodo > 0) || (bl->co_timestodo == -1)) { + if (bl->co_numtimes != -1) + bl->co_numtimes--; if (!bl->co_children) cp_periodic(); /*CDHW*/ @@ -569,7 +571,7 @@ getcommand(char *string) return (wlist); } - +/* va: TODO: free control structure(s) before overwriting (memory leakage) */ int cp_evloop(char *string) { @@ -616,7 +618,7 @@ cp_evloop(char *string) * CO_UNFILLED, the last line was the beginning of a block, * and this is the unfilled first statement. */ - + /* va: TODO: free old structure and its content, before overwriting */ if (cend[stackp] && (cend[stackp]->co_type != CO_UNFILLED)) { cend[stackp]->co_next = alloc(struct control); ZERO(cend[stackp]->co_next, struct control); @@ -641,8 +643,9 @@ cp_evloop(char *string) cend[stackp]->co_type = CO_DOWHILE; cend[stackp]->co_cond = wlist->wl_next; if (!cend[stackp]->co_cond) { + /* va: prevent misinterpretation as trigraph sequence with \-sign */ fprintf(stderr, - "Error: missing dowhile condition, '???' will be assumed.\n"); + "Error: missing dowhile condition, '\?\?\?' will be assumed.\n"); } newblock; } else if (eq(wlist->wl_word, "repeat")) { @@ -788,11 +791,11 @@ cp_evloop(char *string) break; case BROKEN: fprintf(cp_err, - "Error: break not in loop (or too many break levels given)\n"); + "Error: break not in loop or too many break levels given\n"); break; case CONTINUED: fprintf(cp_err, - "Error: continue not in loop (or too many continue levels given)\n"); + "Error: continue not in loop or too many continue levels given\n"); break; default: x = findlabel(i, control[stackp]); @@ -808,6 +811,7 @@ cp_evloop(char *string) return (1); /* The return value is irrelevant. */ } wl_free(wlist); wlist = NULL; + return (0); /* va: which value? */ } /* This blows away the control structures... */ diff --git a/src/frontend/cpitf.c b/src/frontend/cpitf.c index 4e869eabd..50b880220 100644 --- a/src/frontend/cpitf.c +++ b/src/frontend/cpitf.c @@ -265,23 +265,27 @@ cp_istrue(wordlist *wl) pn = ft_getpnames(wl, TRUE); v = ft_evaluate(pn); - free_pnode(pn); /* It makes no sense to say while (all), but what the heck... */ while (v) { if (isreal(v)) { for (i = 0; i < v->v_length; i++) - if (v->v_realdata[i] != 0.0) - return (TRUE); + if (v->v_realdata[i] != 0.0) { + free_pnode(pn); + return (TRUE); + } } else { for (i = 0; i < v->v_length; i++) if ((realpart(&v->v_compdata[i]) != 0.0) || - (imagpart(&v->v_compdata[i]) != 0.0)) + (imagpart(&v->v_compdata[i]) != 0.0)) { + free_pnode(pn); return (TRUE); + } } v = v->v_link2; } - return (FALSE); + free_pnode(pn); + return (FALSE); } /* This gets called before every command is executed... */ diff --git a/src/frontend/device.c b/src/frontend/device.c index 09667aa9b..962dd2510 100644 --- a/src/frontend/device.c +++ b/src/frontend/device.c @@ -235,16 +235,17 @@ all_show(wordlist *wl, int mode) int printstr(dgen *dg, char *name) { + /* va: ' ' is no flag for %s; \? avoids trigraph warning */ if (*name == 'n') { if (dg->instance) - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname); else - printf(" %*s", DEV_WIDTH, ""); + printf(" %*s", DEV_WIDTH, "<\?\?\?\?\?\?\?>"); } else if (*name == 'm') { if (dg->model) - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName); else - printf(" %*s", DEV_WIDTH, ""); + printf(" %*s", DEV_WIDTH, "<\?\?\?\?\?\?\?>"); } else printf(" %*s", DEV_WIDTH, ""); @@ -400,6 +401,7 @@ printvals(dgen *dg, IFparm *p, int i) } if (p->dataType & IF_VECTOR) { + /* va: ' ' is no flag for %s */ switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) { case IF_FLAG: printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]); @@ -417,13 +419,13 @@ printvals(dgen *dg, IFparm *p, int i) printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].imag); break; case IF_STRING: - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]); break; case IF_INSTANCE: - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]); break; default: - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); } } else { switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) { @@ -443,13 +445,13 @@ printvals(dgen *dg, IFparm *p, int i) printf(" % *.6g", DEV_WIDTH, val.cValue.imag); break; case IF_STRING: - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.sValue); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.sValue); break; case IF_INSTANCE: - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.uValue); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.uValue); break; default: - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); } } @@ -575,6 +577,7 @@ com_alter_common(wordlist *wl, int do_model) char *param; struct dvec *dv; struct pnode *names; + char *hlp=NULL; if (!ft_curckt) { fprintf(cp_err, "Error: no circuit loaded\n"); @@ -637,7 +640,6 @@ com_alter_common(wordlist *wl, int do_model) return; } dv = ft_evaluate(names); - free_pnode(names); if (!dv) return; if (dv->v_length < 1) { @@ -647,8 +649,9 @@ com_alter_common(wordlist *wl, int do_model) if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model); - /* Vector data (dv) should get garbage-collected. */ - + /* va: garbage collection for dv, if pnode names is no simple value */ + if (names->pn_value==NULL && dv!=NULL) vec_free(dv); + free_pnode(names); /* free also dv, if pnode names is simple value */ return; } diff --git a/src/frontend/display.c b/src/frontend/display.c index 96ca863fa..b2b3c9bea 100644 --- a/src/frontend/display.c +++ b/src/frontend/display.c @@ -55,6 +55,11 @@ extern int PS_Init(void), PS_NewViewport(GRAPH *graph), PS_Close(void), PS_Clea PS_DefineLinestyle(), PS_SetLinestyle(int linestyleid), PS_SetColor(int colorid), PS_Update(void); +extern int GL_Init(void), GL_NewViewport(GRAPH *graph), GL_Close(void), GL_Clear(void), + GL_DrawLine(int x1, int y1, int x2, int y2), GL_Arc(int x0, int y0, int r, double theta1, double theta2), GL_Text(char *text, int x, int y), + GL_DefineLinestyle(), GL_SetLinestyle(int linestyleid), GL_SetColor(int colorid), + GL_Update(void); + DISPDEVICE device[] = { {"error", 0, 0, 0, 0, 0, 0, nop, nop, @@ -106,6 +111,13 @@ DISPDEVICE device[] = { nodev, nodev, nodev, nodev, gen_DatatoScreen,}, + {"hpgl", 0, 0, 1000, 1000, 0, 0, GL_Init, GL_NewViewport, + GL_Close, GL_Clear, + GL_DrawLine, GL_Arc, GL_Text, nodev, nodev, + GL_SetLinestyle, GL_SetColor, GL_Update, + nodev, nodev, nodev, nodev, + gen_DatatoScreen,}, + {"printf", 0, 0, 24, 80, 0, 0, nodev, nodev, nodev, nodev, nodev, nodev, nodev, nodev, nodev, @@ -142,8 +154,9 @@ DISPDEVICE *FindDev(char *name) void DevInit(void) { - - char buf[128]; +#ifndef X_DISPLAY_MISSING + char buf[128]; /* va: used with NOT X_DISPLAY_MISSING only */ +#endif /* X_DISPLAY_MISSING */ /* note: do better determination */ @@ -157,10 +170,7 @@ DevInit(void) #ifndef X_DISPLAY_MISSING /* determine display type */ if (getenv("DISPLAY") || cp_getvar("display", VT_STRING, buf)) { - -#ifndef X_DISPLAY_MISSING - dispdev = FindDev("X11"); -#endif + dispdev = FindDev("X11"); } #endif diff --git a/src/frontend/evaluate.c b/src/frontend/evaluate.c index 45ed75169..6f91dcbe2 100644 --- a/src/frontend/evaluate.c +++ b/src/frontend/evaluate.c @@ -39,14 +39,16 @@ sig_matherr(void) /* Note that ft_evaluate will return NULL on invalid expressions. */ - +/* va: NOTE: ft_evaluate returns a new vector for expressions (func, op, ...) + and an existing vector (node->pn_value) when node->pn_value != NULL. + For garbage collection caller must vec_free() expression-vector. */ struct dvec * ft_evaluate(struct pnode *node) { struct dvec *d = NULL; if (!node) - return (NULL); + d = NULL; else if (node->pn_value) d = node->pn_value; else if (node->pn_func) @@ -60,15 +62,18 @@ ft_evaluate(struct pnode *node) (node->pn_left, node->pn_right)); } else { fprintf(cp_err, "ft_evaluate: Internal Error: bad node\n"); - return (NULL); + d = NULL; } - if (!d) { + if (d == NULL) { return NULL; } - if (node->pn_name && !ft_evdb && d && !d->v_link2) + if (node->pn_name && !ft_evdb && d && !d->v_link2) { + if(d->v_name) + tfree(d->v_name); d->v_name = copy(node->pn_name); + } if (!d->v_length) { fprintf(cp_err, "Error: no such vector %s\n", d->v_name); @@ -291,6 +296,9 @@ doop(char what, } } + /* va: garbage collection */ + if (arg1->pn_value==NULL && v1!=NULL) vec_free(v1); + if (arg2->pn_value==NULL && v2!=NULL) vec_free(v2); return (res); } @@ -490,6 +498,10 @@ op_range(struct pnode *arg1, struct pnode *arg2) */ vec_new(res); + + /* va: garbage collection */ + if (arg1->pn_value==NULL && v!=NULL) vec_free(v); + if (arg1->pn_value==NULL && ind!=NULL) vec_free(ind); return (res); } @@ -639,6 +651,10 @@ op_ind(struct pnode *arg1, struct pnode *arg2) */ vec_new(res); + + /* va: garbage collection */ + if (arg1->pn_value==NULL && v!=NULL) vec_free(v); + if (arg1->pn_value==NULL && ind!=NULL) vec_free(ind); return (res); } @@ -765,6 +781,8 @@ apply_func(struct func *func, struct pnode *arg) end = t; } + /* va: garbage collection */ + if (arg->pn_value==NULL && v!=NULL) vec_free(v); return (newv); } diff --git a/src/frontend/gens.c b/src/frontend/gens.c index ed4779a91..aa5400c80 100644 --- a/src/frontend/gens.c +++ b/src/frontend/gens.c @@ -62,7 +62,7 @@ dgen_for_n(dgen *dg, int n, int (*fn) (/* ??? */), void *data, int subindex) int dnum, i, j, k; dgxp = &dgx; - bcopy(dg, dgxp, sizeof(dgx)); + bcopy((void *)dg, (void *)dgxp, sizeof(dgx)); /* va: compatible pointer types */ dnum = dgxp->dev_type_no; diff --git a/src/frontend/hcomp.c b/src/frontend/hcomp.c index 657296618..6319fc7a5 100644 --- a/src/frontend/hcomp.c +++ b/src/frontend/hcomp.c @@ -1,4 +1,5 @@ #include +#include int hcomp(const void *a, const void *b) diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 44b4dc5ba..f9bdf8ff4 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -26,6 +26,12 @@ Author: 1985 Wayne A. Christopher #include "completion.h" #include "variable.h" +#ifdef XSPICE +/* gtri - add - 12/12/90 - wbk - include new stuff */ +#include "ipctiein.h" +#include "enh.h" +/* gtri - end - 12/12/90 */ +#endif /* static declarations */ static char * upper(register char *string); @@ -44,7 +50,7 @@ com_listing(wordlist *wl) bool expand = FALSE; char *s; - if (ft_curckt) { + if (ft_curckt) { /* if there is a current circuit . . . . */ while (wl) { s = wl->wl_word; switch (*s) { @@ -111,6 +117,13 @@ inp_list(FILE *file, struct line *deck, struct line *extras, int type) bool renumber; bool useout = (file == cp_out); int i = 1; +/* gtri - wbk - 03/07/91 - Don't use 'more' type output if ipc enabled */ +#ifdef XSPICE + if(g_ipc.enabled) { + useout = FALSE; + } +#endif +/* gtri - end - 03/07/91 */ if (useout) out_init(); @@ -272,9 +285,15 @@ line_free(struct line * deck, bool recurse) { /* The routine to source a spice input deck. We read the deck in, take * out the front-end commands, and create a CKT structure. Also we * filter out the following cards: .save, .width, .four, .print, and - * .plot, to perform after the run is over. */ + * .plot, to perform after the run is over. + * Then, we run dodeck, which parses up the deck. */ void inp_spsource(FILE *fp, bool comfile, char *filename) + /* arguments: + * *fp = pointer to the input file + * comfile = whether it is a command file. Values are TRUE/FALSE + * *filename = + */ { struct line *deck, *dd, *ld; struct line *realdeck, *options = NULL; @@ -285,8 +304,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename) FILE *lastin, *lastout, *lasterr; char c; + /* read in the deck from a file */ inp_readall(fp, &deck); - + + /* if nothing came back from inp_readall, just close fp and return to caller */ if (!deck) { /* MW. We must close fp always when returning */ fclose(fp); return; @@ -341,8 +362,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename) /* tfree(dd->li_line); tfree(dd); */ } - } else { - for (dd = deck->li_next; dd; dd = ld->li_next) { + } /* end if(comfile) */ + + else { /* must be regular deck . . . . */ + for (dd = deck->li_next; dd; dd = ld->li_next) { /* loop through deck and handle control cards */ for (s = dd->li_line; (c = *s) && c <= ' '; s++) ; if (c == '*' && (s != deck->li_line || s[1] != '#')) { @@ -359,8 +382,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename) if (ciprefix(".control", dd->li_line)) { ld->li_next = dd->li_next; line_free(dd,FALSE); /* SJB - free this line's memory */ + /* tfree(dd->li_line); tfree(dd); */ + if (commands) fprintf(cp_err, "Warning: redundant .control card\n"); @@ -369,8 +394,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename) } else if (ciprefix(".endc", dd->li_line)) { ld->li_next = dd->li_next; line_free(dd,FALSE); /* SJB - free this line's memory */ + /* tfree(dd->li_line); tfree(dd); */ + if (commands) commands = FALSE; else @@ -429,34 +456,67 @@ inp_spsource(FILE *fp, bool comfile, char *filename) } else ld = dd; } - } - if (deck->li_next) { + } /* end for(dd=deck->li_next . . . . */ + + + /* we are done handling the control stuff. Now process remainder of deck */ + if (deck->li_next) { /* There is something left after the controls. */ fprintf(cp_out, "\nCircuit: %s\n\n", tt); + /* Old location of ENHtranslate_poly. This didn't work, because it + * didn't handle models in .SUBCKTs correctly. Moved to new location below + * by SDB on 4.13.2003 + */ + /* Now expand subcircuit macros. Note that we have to fix * the case before we do this but after we deal with the * commands. */ if (!cp_getvar("nosubckt", VT_BOOL, (char *) &nosubckts)) - if((deck->li_next = inp_subcktexpand(deck->li_next)) == NULL){ - line_free(realdeck,TRUE); - line_free(deck->li_actual, TRUE); - return; - } + if( (deck->li_next = inp_subcktexpand(deck->li_next)) == NULL ){ + line_free(realdeck,TRUE); + line_free(deck->li_actual, TRUE); + return; + } /* done expanding subcircuit macros */ + + + /* Now handle translation of spice2c6 POLYs. */ +/* New location of ENHtranslate_poly. This should handle .SUBCKTs better . . . . + * SDB 4.13.2003. Comments? mailto:sdb@cloud9.net + */ +#ifdef XSPICE +/* gtri - wbk - Translate all SPICE 2G6 polynomial type sources */ + deck->li_next = ENHtranslate_poly(deck->li_next); +/* gtri - end - Translate all SPICE 2G6 polynomial type sources */ +#endif + line_free(deck->li_actual,FALSE); /* SJB - free memory used by old li_actual (if any) */ deck->li_actual = realdeck; - inp_dodeck(deck, tt, wl_first, FALSE, options, filename); - } - /* Now that the deck is loaded, do the commands */ - if (controls) { + /* now call inp_dodeck, which loads deck into ft_curckt -- the current circuit. */ + inp_dodeck(deck, tt, wl_first, FALSE, options, filename); + + } /* if (deck->li_next) */ + + +#ifdef TRACE + /* SDB debug statement */ + printf("In inp_spsource, done with dodeck.\n"); +#endif + + /* Now that the deck is loaded, do the commands, if there are any */ + if (controls) { for (end = wl = wl_reverse(controls); wl; wl = wl->wl_next) cp_evloop(wl->wl_word); wl_free(end); - } + } } + /*saj, to process save commands always, not just in batch mode + *(breaks encapsulation of frountend and parsing commands slightly)*/ + ft_dotsaves(); + /* Now reset everything. Pop the control stack, and fix up the IO * as it was before the source. */ cp_popcontrol(); @@ -472,9 +532,21 @@ inp_spsource(FILE *fp, bool comfile, char *filename) * follows also. End is the list of commands we execute when the job * is finished: we only bother with this if we might be running in * batch mode, since it isn't much use otherwise. */ +/*------------------------------------------------------------------ + * It appears that inp_dodeck adds the circuit described by *deck + * to the current circuit (ft_curckt). + *-----------------------------------------------------------------*/ void inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line *options, char *filename) + /*fcn arguments: + * *deck = the spice deck + * *tt = the title of the deck + * *end = pointer to the wordlist + * reuse + * *options + * *filename + */ { struct circ *ct; struct line *dd; @@ -504,15 +576,39 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, ft_curckt = ct = alloc(struct circ); } cp_getvar("noparse", VT_BOOL, (char *) &noparse); + + /*---------------------------------------------------- + * Now assuming that we wanna parse this deck, we call + * if_inpdeck which takes the deck and returns a + * a pointer to the circuit ckt. + *---------------------------------------------------*/ if (!noparse) ckt = if_inpdeck(deck, &tab); else ckt = NULL; out_init(); - for (dd = deck; dd; dd = dd->li_next) - if (dd->li_error) { - char *p, *q; + + /*---------------------------------------------------- + * Now run throuh the deck and look to see if there are + * errors on any line. + *---------------------------------------------------*/ + for (dd = deck; dd; dd = dd->li_next) { + +#ifdef TRACE + /* SDB debug statement */ + printf("In inp_dodeck, looking for errors and examining line %s . . . \n", dd->li_line); +#endif + + if (dd->li_error) { + char *p, *q; + +#ifdef XSPICE + /* gtri - modify - 12/12/90 - wbk - add setting of ipc syntax error flag */ + g_ipc.syntax_error = IPC_TRUE; +#endif +/* gtri - end - 12/12/90 */ + p = dd->li_error; do { q =strchr(p, '\n'); @@ -529,7 +625,10 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, *q++ = '\n'; p = q; } while (p && *p); - } + } /* end if (dd->li_error) */ + + } /* for (dd = deck; dd; dd = dd->li_next) */ + /* Add this circuit to the circuit list. If reuse is TRUE then use * the ft_curckt structure. */ @@ -542,7 +641,7 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, cp_kwswitch(CT_NODENAMES, ft_curckt->ci_nodes); ft_newcirc(ct); /* Assign current circuit */ - ft_curckt = ct; + ft_curckt = ct; } ct->ci_name = tt; ct->ci_deck = deck; @@ -551,7 +650,7 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, ct->ci_origdeck = deck->li_actual; else ct->ci_origdeck = ct->ci_deck; - ct->ci_ckt = ckt; + ct->ci_ckt = ckt; /* attach the input ckt to the list of circuits */ ct->ci_symtab = tab; ct->ci_inprogress = FALSE; ct->ci_runonce = FALSE; @@ -582,24 +681,24 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, static int one = 1; switch (eev->va_type) { case VT_BOOL: - if_option(ct->ci_ckt, eev->va_name, - eev->va_type, &one); - break; + if_option(ct->ci_ckt, eev->va_name, + eev->va_type, &one); + break; case VT_NUM: - if_option(ct->ci_ckt, eev->va_name, - eev->va_type, (char *) &eev->va_num); - break; + if_option(ct->ci_ckt, eev->va_name, + eev->va_type, (char *) &eev->va_num); + break; case VT_REAL: - if_option(ct->ci_ckt, eev->va_name, - eev->va_type, (char *) &eev->va_real); - break; + if_option(ct->ci_ckt, eev->va_name, + eev->va_type, (char *) &eev->va_real); + break; case VT_STRING: - if_option(ct->ci_ckt, eev->va_name, - eev->va_type, eev->va_string); - break; - } + if_option(ct->ci_ckt, eev->va_name, + eev->va_type, eev->va_string); + break; + } /* switch . . . */ } - } + } /* if (!noparse) . . . */ cp_addkword(CT_CKTNAMES, tt); return; diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 9bb9f6375..93736ebd2 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -25,14 +25,21 @@ Author: 1985 Wayne A. Christopher #include "inpcom.h" #include "variable.h" +#ifdef XSPICE +/* gtri - add - 12/12/90 - wbk - include new stuff */ +#include "ipctiein.h" +#include "enh.h" +/* gtri - end - 12/12/90 */ +#endif -/* This routine reads a line (of arbitrary length), up to a '\n' or 'EOF' - * and returns a pointer to the resulting null terminated string. - * The '\n' if found, is included in the returned string. - * From: jason@ucbopal.BERKELEY.EDU (Jason Venner) - * Newsgroups: net.sources - */ +/*-------------------------------------------------------------------------* + * This routine reads a line (of arbitrary length), up to a '\n' or 'EOF' * + * and returns a pointer to the resulting null terminated string. * + * The '\n' if found, is included in the returned string. * + * From: jason@ucbopal.BERKELEY.EDU (Jason Venner) * + * Newsgroups: net.sources * + *-------------------------------------------------------------------------*/ #define STRGROW 256 static char * @@ -73,10 +80,11 @@ readline(FILE *fd) return (strptr); } -/* Look up the variable sourcepath and try everything in the list in order - * if the file isn't in . and it isn't an abs path name. - */ +/*-------------------------------------------------------------------------* + * Look up the variable sourcepath and try everything in the list in order * + * if the file isn't in . and it isn't an abs path name. * + *-------------------------------------------------------------------------*/ FILE * inp_pathopen(char *name, char *mode) { @@ -111,43 +119,103 @@ inp_pathopen(char *name, char *mode) return (NULL); } -/* Read the entire input file and return a pointer to the first line of - * the linked list of 'card' records in data. - */ +/*------------------------------------------------------------------------- + * Read the entire input file and return a pointer to the first line of + * the linked list of 'card' records in data. The pointer is stored in + * *data. + *-------------------------------------------------------------------------*/ void inp_readall(FILE *fp, struct line **data) { struct line *end = NULL, *cc = NULL, *prev = NULL, *working, *newcard; - char *buffer, *s, *t, c,*copys; + char *buffer, *s, *t, c; + /* segfault fix */ + char *copys = NULL; int line = 1; FILE *newfp; +/* gtri - modify - 12/12/90 - wbk - read from mailbox if ipc enabled */ +#ifdef XSPICE + Ipc_Status_t ipc_status; + char ipc_buffer[1025]; /* Had better be big enough */ + int ipc_len; + + /* First read in all lines & put them in the struct cc */ + while (1) { + + /* If IPC is not enabled, do equivalent of what SPICE did before */ + if(! g_ipc.enabled) { + buffer = readline(fp); + if(! buffer) + break; + } + else { + /* else, get the line from the ipc channel. */ + /* We assume that newlines are not sent by the client */ + /* so we add them here */ + ipc_status = ipc_get_line(ipc_buffer, &ipc_len, IPC_WAIT); + if(ipc_status == IPC_STATUS_END_OF_DECK) { + buffer = NULL; + break; + } + else if(ipc_status == IPC_STATUS_OK) { + buffer = (void *) MALLOC(strlen(ipc_buffer) + 3); + strcpy(buffer, ipc_buffer); + strcat(buffer, "\n"); + } + else { /* No good way to report this so just die */ + exit(1); + } + } + +/* gtri - end - 12/12/90 */ +#else while ((buffer = readline(fp))) { + #endif + +#ifdef TRACE + /* SDB debug statement */ + printf ("in inp_readall, just read %s . . .\n", buffer); +#endif + + /* OK -- now we have loaded the next line into 'buffer'. Process it. */ + /* If input line is blank, ignore it & continue looping. */ + if ( (strcmp(buffer,"\n") == 0) + || (strcmp(buffer,"\r\n") == 0) ) { + continue; + } + if (*buffer == '@') { tfree(buffer); /* was allocated by readline() */ break; } - for (s = buffer; *s && (*s != '\n'); s++) - ; + /* loop through 'buffer' until end is reached. Then test for + premature end. If premature end is reached, spew + error and zap the line. */ + for (s = buffer; *s && (*s != '\n'); s++); if (!*s) { fprintf(cp_err, "Warning: premature EOF\n"); } *s = '\0'; /* Zap the newline. */ + if(*(s-1) == '\r') /* Zop the carriage return under windows */ + *(s-1) = '\0'; + + /* now handle .include statements */ if (ciprefix(".include", buffer)) { - for (s = buffer; *s && !isspace(*s); s++) + for (s = buffer; *s && !isspace(*s); s++)/* advance past non-space chars */ ; - while (isspace(*s)) + while (isspace(*s)) /* now advance past space chars */ s++; - if (!*s) { + if (!*s) { /* if at end of line, error */ fprintf(cp_err, "Error: .include filename missing\n"); tfree(buffer); /* was allocated by readline() */ continue; - } - for (t = s; *t && !isspace(*t); t++) + } /* Now s points to first char after .include */ + for (t = s; *t && !isspace(*t); t++) /* now advance past non-space chars */ ; - *t = '\0'; + *t = '\0'; /* place \0 and end of file name in buffer */ if (*s == '~') { copys = cp_tildexpand(s); /* allocates memory, but can also return NULL */ @@ -155,7 +223,8 @@ inp_readall(FILE *fp, struct line **data) s = copys; /* reuse s, but remember, buffer still points to allocated memory */ } } - + + /* open file specified by .include statement */ if (!(newfp = inp_pathopen(s, "r"))) { perror(s); if(copys) { @@ -169,17 +238,22 @@ inp_readall(FILE *fp, struct line **data) tfree(copys); /* allocated by the cp_tildexpand() above */ } - inp_readall(newfp, &newcard); + inp_readall(newfp, &newcard); /* read stuff in include file into netlist */ (void) fclose(newfp); /* Make the .include a comment */ *buffer = '*'; - if (end) { - end->li_next = alloc(struct line); - end = end->li_next; + /* now check if this is the first pass (i.e. end points to null) */ + if (end) { /* end already exists */ + end->li_next = alloc(struct line); /* create next card */ + end = end->li_next; /* make end point to next card */ } else { - end = cc = alloc(struct line); + end = cc = alloc(struct line); /* create the deck & end. cc will + point to beginning of deck, end to + the end */ } + + /* now fill out rest of struct end. */ end->li_next = NULL; end->li_error = NULL; end->li_actual = NULL; @@ -193,14 +267,18 @@ inp_readall(FILE *fp, struct line **data) /* Fix the buffer up a bit. */ (void) strncpy(buffer + 1, "end of:", 7); - } + } /* end of .include handling */ - if (end) { - end->li_next = alloc(struct line); - end = end->li_next; - } else { - end = cc = alloc(struct line); + /* now check if this is the first pass (i.e. end points to null) */ + if (end) { /* end already exists */ + end->li_next = alloc(struct line); /* create next card */ + end = end->li_next; /* point to next card */ + } else { /* End doesn't exist. Create it. */ + end = cc = alloc(struct line); /* note that cc points to beginning + of deck, end to the end */ } + + /* now put buffer into li */ end->li_next = NULL; end->li_error = NULL; end->li_actual = NULL; @@ -210,31 +288,44 @@ inp_readall(FILE *fp, struct line **data) if (!end) { /* No stuff here */ *data = NULL; return; - } + } /* end while ((buffer = readline(fp))) */ + + /* This should be freed because we are done with it. */ + /* tfree(buffer); */ + + + /* Now clean up li: remove comments & stitch together continuation lines. */ + working = cc->li_next; /* cc points to head of deck. Start with the + next card (skip title). */ - /* Now make logical lines. */ - working = cc->li_next; /* Skip title. */ while (working) { for (s = working->li_line; (c = *s) && c <= ' '; s++) ; + +#ifdef TRACE + /* SDB debug statement */ + printf("In inp_readall, processing linked list element s = %s . . . \n", s); +#endif + switch (c) { case '#': case '$': case '*': case '\0': - /* - prev = NULL; - */ - working = working->li_next; + /* this used to be commented out. Why? */ + /* prev = NULL; */ + working = working->li_next; /* for these chars, go to next card */ break; - case '+': + case '+': /* handle continuation */ if (!prev) { working->li_error = copy( "Illegal continuation line: ignored."); working = working->li_next; break; } + + /* create buffer and write last and current line into it. */ buffer = tmalloc(strlen(prev->li_line) + strlen(s) + 2); (void) sprintf(buffer, "%s %s", prev->li_line, s + 1); s = prev->li_line; @@ -258,7 +349,7 @@ inp_readall(FILE *fp, struct line **data) } working = prev->li_next; break; - default: + default: /* regular one-line card */ prev = working; working = working->li_next; break; @@ -270,6 +361,9 @@ inp_readall(FILE *fp, struct line **data) } +/*-------------------------------------------------------------------------* + * * + *-------------------------------------------------------------------------*/ void inp_casefix(char *string) { diff --git a/src/frontend/outitf.c b/src/frontend/outitf.c index e61ea0462..05b774faa 100644 --- a/src/frontend/outitf.c +++ b/src/frontend/outitf.c @@ -122,7 +122,17 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch bool saveall = TRUE; bool savealli = FALSE; char *an_name; - + + /*to resume a run saj + *All it does is reassign the file pointer and return (requires *runp to be NULL if this is not needed) + */ + if(dataType == 666 && numNames == 666){ + run = *runp; + run->writeOut = ft_getOutReq(&run->fp, &run->runPlot, &run->binary, + run->type, run->name); + + } else { + /*end saj*/ /* Check to see if we want to print informational data. */ if (cp_getvar("printinfo", VT_BOOL, (char *) &printinfo)) fprintf(cp_err, "(debug printing enabled)\n"); @@ -324,10 +334,8 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch } if (numNames && - (run->numData == 1 - && run->refIndex != -1 - || run->numData == 0 - && run->refIndex == -1)) + ( (run->numData == 1 && run->refIndex != -1) + || (run->numData == 0 && run->refIndex == -1)) ) /* va: suggested parentheses */ { fprintf(cp_err, "Error: no data saved for %s; analysis not run\n", spice_analysis_get_description(((JOB *) analysisPtr)->JOBtype)); diff --git a/src/frontend/parse.c b/src/frontend/parse.c index 3979efc86..97af32125 100644 --- a/src/frontend/parse.c +++ b/src/frontend/parse.c @@ -27,7 +27,7 @@ static struct pnode * mkunode(int op, struct pnode *arg); static struct pnode * mkfnode(char *func, struct pnode *arg); static struct pnode * mknnode(double number); static struct pnode * mksnode(char *string); - +void print_elem(struct element *elem); /* va: for debugging */ static int lasttoken = END, lasttype; static char *sbuf; @@ -115,7 +115,8 @@ checkvalid(struct pnode *pn) /* Everything else is a string or a number. Quoted strings are kept in * the form "string", and the lexer strips off the quotes... */ - +/* va: the structure returned is static, e_string is a copy + (in case of e_token==VALUE,e_type==STRING) */ static struct element * lexer(void) { @@ -405,13 +406,16 @@ static struct pnode * parse(void) { struct element stack[STACKSIZE]; - int sp = 0, st, i; + char *stringStack[STACKSIZE]; + int sp = 0, st, i, fsp = 0; struct element *top, *next; struct pnode *pn, *lpn, *rpn; char rel; stack[0].e_token = END; next = lexer(); + if(next->e_token == VALUE && next->e_type == STRING) + stringStack[fsp++] = next->e_string; while ((sp > 1) || (next->e_token != END)) { /* Find the top-most terminal. */ @@ -423,14 +427,16 @@ parse(void) switch (rel) { case L: case E: - /* Push the token read. */ - if (sp == (STACKSIZE - 1)) { + /* Push the token read. */ + if (sp == (STACKSIZE - 1) || fsp == (STACKSIZE-1)) { fprintf(cp_err, "Error: stack overflow\n"); return (NULL); } bcopy((char *) next, (char *) &stack[++sp], sizeof (struct element)); next = lexer(); + if(next->e_token == VALUE && next->e_type == STRING) + stringStack[fsp++] = next->e_string; continue; case R: @@ -491,6 +497,19 @@ parse(void) goto err; if (!(pn = mkfnode(stack[sp].e_string, lpn))) return (NULL); + /* va: avoid memory leakage: + in case of variablenames (i.e. i(vd)) mkfnode makes in + reality a snode, the old lpn (and its plotless vector) is + then a memory leak */ + if (pn->pn_func==NULL && pn->pn_value!=NULL) /* a snode */ + { + if (lpn->pn_value && lpn->pn_value->v_plot==NULL) + { + tfree(lpn->pn_value->v_name); + tfree(lpn->pn_value); + } + free_pnode(lpn); + } } else { /* node op node */ lpn = makepnode(&stack[sp]); rpn = makepnode(&stack[st]); @@ -506,6 +525,8 @@ parse(void) } } pn = makepnode(&stack[1]); + for(i=0;ie_token); + if (elem->e_token == VALUE) { + printf(", e_type = %d", elem->e_type); + switch (elem->e_type) { + case STRING: + printf(", e_string = %s(%p)", elem->e_string,elem->e_string); + break; + case NUM: + printf(", e_double = %g", elem->e_double); break; + case PNODE: + printf(", e_pnode = %p", elem->e_pnode); break; + default: + break; + } + } + printf("\n"); +} + + /* Some auxiliary functions for building the parse tree. */ static @@ -803,6 +845,12 @@ mksnode(char *string) end = nv; } p->pn_value = newv; + + /* va: tfree v in case of @xxx[par], because vec_get created a new vec and + nobody will free it elsewhere */ + if (v && v->v_name && *v->v_name=='@' && isreal(v) && v->v_realdata) { + vec_free(v); + } return (p); } @@ -815,6 +863,14 @@ free_pnode(struct pnode *t) free_pnode(t->pn_left); free_pnode(t->pn_right); free_pnode(t->pn_next); + tfree(t->pn_name); /* va: it is a copy() of original string, can be free'd */ + /* va: tfree struct func, allocated within parser */ + if (t->pn_func!=NULL) { + tfree(t->pn_func->fu_name); /* va: name is a copy of original string */ + tfree(t->pn_func); /* va: t->pn_func->fu_func must not tfree'd */ + } + if (t->pn_value) + vec_free(t->pn_value); /* patch by Stefan Jones */ tfree(t); } diff --git a/src/frontend/parser/complete.c b/src/frontend/parser/complete.c index 97e1d514c..f05f727b6 100644 --- a/src/frontend/parser/complete.c +++ b/src/frontend/parser/complete.c @@ -517,7 +517,7 @@ cp_addkword(int class, char *word) class); return; } - word = copy(word); +/* word = copy(word); va: not necessary, clookup copies itself (memory leak) */ cc = clookup(word, &keywords[class], FALSE, TRUE); cc->cc_invalid = 0; return; @@ -574,10 +574,12 @@ cp_ccrestart(bool kwords) void throwaway(struct ccom *dbase) { + if (!dbase) return; /* va: security first */ if (dbase->cc_child) throwaway(dbase->cc_child); if (dbase->cc_sibling) throwaway(dbase->cc_sibling); + tfree(dbase->cc_name); /* va: also tfree dbase->cc_name (memory leak) */ tfree(dbase); return; } @@ -727,8 +729,8 @@ cdelete(struct ccom *node, struct ccom **top) /* now free() everything and check the top */ if (node == *top) *top = node->cc_sibling; - free(node->cc_name); - free(node); + tfree(node->cc_name); /* va: we should allways use tfree */ + tfree(node); return; } diff --git a/src/frontend/plotting/graphdb.c b/src/frontend/plotting/graphdb.c index bf2e5b848..e868cace4 100644 --- a/src/frontend/plotting/graphdb.c +++ b/src/frontend/plotting/graphdb.c @@ -109,7 +109,7 @@ GRAPH *CopyGraph(GRAPH *graph) struct dveclist *link, *newlink; ret = NewGraph(); - bcopy(graph, ret, sizeof(struct graph)); + bcopy((void *)graph, (void *)ret, sizeof(GRAPH)); /* va: compatible pointer types */ ret->graphid = RunningId - 1; /* restore id */ diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c index d1ca6df48..f0c92137e 100644 --- a/src/frontend/plotting/plotit.c +++ b/src/frontend/plotting/plotit.c @@ -250,9 +250,12 @@ plotit(wordlist *wl, char *hcopy, char *devname) struct dvec *v, *newv_scale; double *newdata, *newscale; double tstep, tstart, tstop, ttime; + + /* return value, error by default */ + bool rtn = FALSE; if (!wl) - return FALSE; + goto quit1; wl_root = wl; /* First get the command line, without the limits. */ @@ -261,7 +264,9 @@ plotit(wordlist *wl, char *hcopy, char *devname) (void) getlims(wwl, "xlimit", 2); (void) getlims(wwl, "yl", 2); (void) getlims(wwl, "ylimit", 2); - (void) sprintf(cline, "plot %s", wl_flatten(wwl)); + pname = wl_flatten(wwl); + (void) sprintf(cline, "plot %s", pname); + tfree(pname); wl_free(wwl); @@ -513,9 +518,10 @@ plotit(wordlist *wl, char *hcopy, char *devname) nointerp = TRUE; wl = wl->wl_next; + tfree(tw); if (!wl) { fprintf(cp_err, "Error: no vectors given\n"); - return (FALSE); + goto quit1; } wl->wl_prev = NULL; @@ -531,7 +537,7 @@ plotit(wordlist *wl, char *hcopy, char *devname) names = ft_getpnames(wl, FALSE); if (names == NULL) - return (FALSE); + goto quit1; /* Now evaluate the names. */ for (n = names, lv = NULL; n; n = n->pn_next) { @@ -539,16 +545,16 @@ plotit(wordlist *wl, char *hcopy, char *devname) eq(n->pn_value->v_name, "vs")) { if (!lv) { fprintf(cp_err, "Error: misplaced vs arg\n"); - return (FALSE); + goto quit; } else { if (!(n = n->pn_next)) { fprintf(cp_err, "Error: missing vs arg\n"); - return (FALSE); + goto quit; } dv = ft_evaluate(n); if (!dv) - return (FALSE); + goto quit; if (lastvs) lv = lastvs->v_link2; else @@ -563,7 +569,7 @@ plotit(wordlist *wl, char *hcopy, char *devname) } dv = ft_evaluate(n); if (!dv) - return (FALSE); + goto quit; if (!d) vecs = dv; else @@ -572,7 +578,7 @@ plotit(wordlist *wl, char *hcopy, char *devname) ; lv = dv; } - free_pnode(names); +/* free_pnode(names); pn:really should be commented out ? */ d->v_link2 = NULL; /* Now check for 0-length vectors. */ @@ -580,7 +586,7 @@ plotit(wordlist *wl, char *hcopy, char *devname) if (!d->v_length) { fprintf(cp_err, "Error: %s: no such vector\n", d->v_name); - return (FALSE); + goto quit; } /* If there are higher dimensional vectors, transform them into a @@ -655,7 +661,7 @@ plotit(wordlist *wl, char *hcopy, char *devname) oneval ? 1 : 0) { fprintf(cp_err, "Error: plot must be either all pole-zero or contain no poles or zeros\n"); - return (FALSE); + goto quit; } if ((gtype == GRID_POLAR) || (gtype == GRID_SMITH @@ -837,13 +843,13 @@ plotit(wordlist *wl, char *hcopy, char *devname) (gtype == GRID_LOGLOG))) { fprintf(cp_err, "Error: X values must be > 0 for log scale\n"); - return (FALSE); + goto quit; } if ((ylims[0] <= 0.0) && ((gtype == GRID_YLOG) || (gtype == GRID_LOGLOG))) { fprintf(cp_err, "Error: Y values must be > 0 for log scale\n"); - return (FALSE); + goto quit; } /* Fix the plot limits for smith and polar grids. */ @@ -904,7 +910,7 @@ plotit(wordlist *wl, char *hcopy, char *devname) newscale, newlen, 1)) { fprintf(cp_err, "Error: can't interpolate %s\n", v->v_name); - return(FALSE); + goto quit; } tfree(v->v_realdata); @@ -922,7 +928,8 @@ plotit(wordlist *wl, char *hcopy, char *devname) ((gtype == GRID_XLOG) || (gtype == GRID_LOGLOG)), ((gtype == GRID_YLOG) || (gtype == GRID_LOGLOG)), nointerp); - return (TRUE); + rtn = TRUE; + goto quit; } /* See if there is one type we can give for the y scale... */ @@ -939,7 +946,8 @@ plotit(wordlist *wl, char *hcopy, char *devname) xlabel ? xlabel : ft_typabbrev(vecs->v_scale->v_type), ylabel ? ylabel : ft_typabbrev(j), gtype, ptype, vecs); - return (TRUE); + rtn = TRUE; + goto quit; } for (d = vecs, i = 0; d; d = d->v_link2) i++; @@ -954,7 +962,7 @@ plotit(wordlist *wl, char *hcopy, char *devname) title ? title : vecs->v_plot->pl_title, hcopy, i, xdelta ? *xdelta : 0.0, ydelta ? *ydelta : 0.0, gtype, ptype, xlabel, ylabel, xt, j, pname, cline)) - return (FALSE); + goto quit; /* Now plot all the graphs. */ for (d = vecs; d; d = d->v_link2) @@ -962,6 +970,10 @@ plotit(wordlist *wl, char *hcopy, char *devname) gr_clean(); - return (TRUE); + rtn = TRUE; +quit: + free_pnode(names); +quit1: + return rtn; } diff --git a/src/frontend/plotting/pvec.c b/src/frontend/plotting/pvec.c index b4584c861..0f4ff5742 100644 --- a/src/frontend/plotting/pvec.c +++ b/src/frontend/plotting/pvec.c @@ -47,8 +47,9 @@ pvec(struct dvec *d) case GRID_SMITHGRID: strcat(buf, ", grid = smithgrid (not xformed)"); break; - - default: + + default: /* va: GRID_NONE or GRID_LIN */ + break; } switch (d->v_plottype) { @@ -61,8 +62,10 @@ pvec(struct dvec *d) strcat(buf, ", plot = point"); break; - default: + default: /* va: PLOT_LIN, */ + break; } + if (d->v_defcolor) { sprintf(buf2, ", color = %s", d->v_defcolor); strcat(buf, buf2); diff --git a/src/frontend/postcoms.c b/src/frontend/postcoms.c index 15ee068f4..4a8ac6fc5 100644 --- a/src/frontend/postcoms.c +++ b/src/frontend/postcoms.c @@ -18,6 +18,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "postcoms.h" #include "quote.h" #include "variable.h" +#include "parser/complete.h" /* va: throwaway */ /* static declarations */ static void killplot(struct plot *pl); @@ -602,6 +603,7 @@ com_destroy(wordlist *wl) static void killplot(struct plot *pl) { + struct dvec *v, *nv = NULL; struct plot *op; @@ -609,10 +611,12 @@ killplot(struct plot *pl) fprintf(cp_err, "Error: can't destroy the constant plot\n"); return; } + /* pl_dvecs, pl_scale */ for (v = pl->pl_dvecs; v; v = nv) { nv = v->v_next; vec_free(v); } + /* unlink from plot_list (linked via pl_next) */ if (pl == plot_list) { plot_list = pl->pl_next; if (pl == plot_cur) @@ -632,9 +636,18 @@ killplot(struct plot *pl) tfree(pl->pl_name); tfree(pl->pl_typename); wl_free(pl->pl_commands); - - /* Never mind about the rest... */ - + tfree(pl->pl_date); /* va: also tfree (memory leak) */ + if (pl->pl_ccom) /* va: also tfree (memory leak) */ + { + throwaway((struct ccom *)pl->pl_ccom); + } + if (pl->pl_env) /* The 'environment' for this plot. */ + { + /* va: HOW to do? */ + printf("va: killplot should tfree pl->pl_env=(%p)\n", pl->pl_env); fflush(stdout); + } + tfree(pl); /* va: also tfree pl itself (memory leak) */ + return; } diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index d736b71bc..5046dc0b0 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -1,351 +1,472 @@ -/********** -Copyright 1990 Regents of the University of California. All rights reserved. -Author: 1988 Jeffrey M. Hsu -**********/ - -/* - Postscript driver -*/ - -#include "ngspice.h" -#include "cpdefs.h" -#include "graph.h" -#include "ftedbgra.h" -#include "ftedev.h" -#include "fteinput.h" - -#include "postsc.h" -#include "variable.h" - -#define RAD_TO_DEG (180.0 / M_PI) -#define DEVDEP(g) (*((PSdevdep *) (g)->devdep)) -#define MAX_PS_LINES 1000 -#define SOLID 0 -#define DOTTED 1 - -#define gtype graph->grid.gridtype -#define xoff dispdev->minx -#define yoff dispdev->miny -#define XOFF 48 /* printer left margin */ -#define YOFF 48 /* printer bottom margin */ -#define XTADJ 0 /* printer text adjustment x */ -#define YTADJ 4 /* printer text adjustment y */ - -#define GRIDSIZE 420 /* printer gridsize divisible by 10, [7-2] */ -#define GRIDSIZES 360 /* printer gridsize divisible by [10-8], [6-2] */ - -#define FONTSIZE 10 /* printer default fontsize */ -#define FONTWIDTH 6 /* printer default fontwidth */ -#define FONTHEIGHT 14 /* printer default fontheight */ - -typedef struct { - int lastlinestyle; /* initial invalid value */ - int lastx, lasty, linecount; -} PSdevdep; - -static char *linestyle[] = { - "[]", /* solid */ - "[1 2]", /* dotted */ - "[7 7]", /* longdashed */ - "[3 3]", /* shortdashed */ - "[7 2 2 2]", /* longdotdashed */ - "[3 2 1 2]", /* shortdotdashed */ - "[8 3 2 3]", - "[14 2]", - "[3 5 1 5]" /* dotdashed */ - }; - -static FILE *plotfile; -char psfont[128], psfontsize[32], psscale[32]; -static int fontsize = FONTSIZE; -static int fontwidth = FONTWIDTH; -static int fontheight = FONTHEIGHT; -static int screenflag = 0; -static double scale; /* Used for fine tuning */ -static int xtadj; /* text adjustment x */ -static int ytadj; /* text adjustment y */ -static int hcopygraphid; - - -extern int DestroyGraph (int id); -int PS_SetLinestyle (int linestyleid); -extern void internalerror (char *message); - -int -PS_Init(void) -{ - if (!cp_getvar("hcopyscale", VT_STRING, psscale)) { - scale = 1.0; - } else { - sscanf(psscale, "%lf", &scale); - if ((scale <= 0) || (scale > 10)) - scale = 1.0; - } - - dispdev->numlinestyles = NUMELEMS(linestyle); - dispdev->numcolors = 2; - - dispdev->width = 7.75 * 72.0 * scale; /* (8 1/2 - 3/4) * 72 */ - dispdev->height = dispdev->width; - - /* The following side effects have to be considered - * when the printer is called by com_hardcopy ! - * gr_init: - * viewportxoff = 8 * fontwidth - * viewportyoff = 4 * fontheight - * gr_resize_internal: - * viewport.width = absolute.width - 2 * viewportxoff - * viewport.height = absolute.height - 2 * viewportyoff - */ - - if (!cp_getvar("hcopyfont", VT_STRING, psfont)) - strcpy(psfont, "Helvetica"); - if (!cp_getvar("hcopyfontsize", VT_STRING, psfontsize)) { - fontsize = 10; - fontwidth = 6; - fontheight = 14; - xtadj = XTADJ * scale; - ytadj = YTADJ * scale; - } else { - sscanf(psfontsize, "%d", &fontsize); - if ((fontsize < 10) || (fontsize > 14)) - fontsize = 10; - fontwidth = 0.5 + 0.6 * fontsize; - fontheight = 2.5 + 1.2 * fontsize; - xtadj = XTADJ * scale * fontsize / 10; - ytadj = YTADJ * scale * fontsize / 10; - } - - screenflag = 0; - dispdev->minx = XOFF / scale; - dispdev->miny = YOFF / scale; - - return(0); - -} - -/* devdep initially contains name of output file */ -int -PS_NewViewport(GRAPH *graph) -{ - hcopygraphid = graph->graphid; - - if (!(plotfile = fopen(graph->devdep, "w"))) { - perror(graph->devdep); - graph->devdep = (char *) NULL; - return(1); - } - - if (graph->absolute.width) { - /* hardcopying from the screen */ - - screenflag = 1; - } - - /* reasonable values, used in gr_ for placement */ - graph->fontwidth = fontwidth * scale; /* was 12, p.w.h. */ - graph->fontheight = fontheight * scale; /* was 24, p.w.h. */ - - graph->absolute.width = dispdev->width; - graph->absolute.height = dispdev->height; - /* Also done in gr_init, if called . . . */ - graph->viewportxoff = 8 * fontwidth; - graph->viewportyoff = 4 * fontheight; - - xoff = scale * XOFF; - yoff = scale * YOFF; - - /* start file off with a % */ - fprintf(plotfile, "%%!PS-Adobe-3.0 EPSF-3.0\n"); - fprintf(plotfile, "%%%%Creator: nutmeg\n"); - fprintf(plotfile, "%%%%BoundingBox: %d %d %d %d\n", - (int) (.75 * 72), (int) (.75 * 72), - (int) (8.5 * 72), (int) (8.5 * 72)); - - fprintf(plotfile, "%g %g scale\n", 1.0 / scale, 1.0 / scale); - - /* set up a reasonable font */ - fprintf(plotfile, "/%s findfont %d scalefont setfont\n", - psfont, (int) (fontsize * scale)); - - graph->devdep = tmalloc(sizeof(PSdevdep)); - DEVDEP(graph).lastlinestyle = -1; - DEVDEP(graph).lastx = -1; - DEVDEP(graph).lasty = -1; - DEVDEP(graph).linecount = 0; - graph->linestyle = -1; - - return 0; -} - -void -PS_Close(void) -{ - - /* in case PS_Close is called as part of an abort, - w/o having reached PS_NewViewport */ - if (plotfile) { - if (DEVDEP(currentgraph).lastlinestyle != -1) { - /* haven't stroked last path */ - fprintf(plotfile, "stroke\n"); - DEVDEP(currentgraph).linecount = 0; - } - fprintf(plotfile, "showpage\n"); - fclose(plotfile); - plotfile = NULL; - } - /* In case of hardcopy command destroy the hardcopy graph - * and reset currentgraph to graphid 1, if possible - */ - if (!screenflag) { - DestroyGraph(hcopygraphid); - currentgraph = FindGraph(1); - } -} - -void -PS_Clear(void) -{ - - /* do nothing */ - -} - -void -PS_DrawLine(int x1, int y1, int x2, int y2) -{ - - /* note: this is not extendible to more than one graph - => will have to give NewViewport a writeable graph XXX */ - - if (DEVDEP(currentgraph).lastlinestyle != currentgraph->linestyle - || DEVDEP(currentgraph).linecount > MAX_PS_LINES) - { - fprintf(plotfile, "stroke\n"); - fprintf(plotfile, "newpath\n"); - DEVDEP(currentgraph).linecount = 0; - } - - if (DEVDEP(currentgraph).linecount == 0 - || x1 != DEVDEP(currentgraph).lastx - || y1 != DEVDEP(currentgraph).lasty) - { - fprintf(plotfile, "%d %d moveto ", x1 + xoff, y1 + yoff); - } - if (x1 != x2 || y1 != y2) { - fprintf(plotfile, "%d %d lineto\n", x2 + xoff, y2 + yoff); - DEVDEP(currentgraph).linecount += 1; - } - - DEVDEP(currentgraph).lastx = x2; - DEVDEP(currentgraph).lasty = y2; - DEVDEP(currentgraph).lastlinestyle = currentgraph->linestyle; - -} - - -void -PS_Arc(int x0, int y0, int r, double theta1, double theta2) -{ - double x1, y1; - double angle1, angle2; - - while (theta1 >= theta2) - theta2 += 2 * M_PI; - - angle1 = (double) (RAD_TO_DEG * theta1); - angle2 = (double) (RAD_TO_DEG * theta2); - x1 = (double) x0 + r * cos(theta1); - y1 = (double) y0 + r * sin(theta1); - - fprintf(plotfile, "%f %f moveto ", x1+(double)xoff, y1+(double)yoff); - fprintf(plotfile, "%d %d %d %f %f arc\n", x0+xoff, y0+yoff, r, - angle1, angle2); - fprintf(plotfile, "stroke\n"); - - DEVDEP(currentgraph).linecount = 0; -} - -void -PS_Text(char *text, int x, int y) -{ - - int savedlstyle; - - /* set linestyle to solid - or may get funny color text on some plotters */ - savedlstyle = currentgraph->linestyle; - PS_SetLinestyle(SOLID); - - if (DEVDEP(currentgraph).linecount) { - fprintf(plotfile, "stroke\n"); - fprintf(plotfile, "newpath\n"); - DEVDEP(currentgraph).linecount = 0; - } - /* move to (x, y) */ - fprintf(plotfile, "%d %d moveto\n", x + xoff + xtadj, y + yoff + ytadj); - fprintf(plotfile, "(%s) show\n", text); - - DEVDEP(currentgraph).lastx = -1; - DEVDEP(currentgraph).lasty = -1; - - /* restore old linestyle */ - PS_SetLinestyle(savedlstyle); - -} - -int -PS_SetLinestyle(int linestyleid) -{ - - /* special case - get it when PS_Text restores a -1 linestyle */ - if (linestyleid == -1) { - currentgraph->linestyle = -1; - return 0; - } - - if (linestyleid < 0 || linestyleid > dispdev->numlinestyles) { - internalerror("bad linestyleid"); - return 0; - } - - if (currentgraph->linestyle != linestyleid) { - if (DEVDEP(currentgraph).lastlinestyle != -1) { - fprintf(plotfile, "stroke\n"); - fprintf(plotfile, "newpath\n"); - DEVDEP(currentgraph).linecount = 0; - } - fprintf(plotfile, "%s 0 setdash\n", linestyle[linestyleid]); - currentgraph->linestyle = linestyleid; - } - return 0; - -} - - -void -PS_SetColor(int colorid) -{ - static int flag = 0; /* A hack */ - - /* XXXX Set line style dotted for smith grids */ - if ((colorid == 18) || (colorid == 19)) { - PS_SetLinestyle(DOTTED); - flag = 1; - } - if (flag && (colorid == 1)) { - PS_SetLinestyle(SOLID); - flag = 0; - } - -} - -void -PS_Update(void) -{ - - fflush(plotfile); - -} - +/********** + Copyright 1990 Regents of the University of California. All rights reserved. + Author: 1988 Jeffrey M. Hsu +**********/ + +/* + Postscript driver +*/ + +#include "ngspice.h" +#include "cpdefs.h" +#include "graph.h" +#include "ftedbgra.h" +#include "ftedev.h" +#include "fteinput.h" + +#include "postsc.h" +#include "variable.h" + +#define RAD_TO_DEG (180.0 / M_PI) +#define DEVDEP(g) (*((PSdevdep *) (g)->devdep)) +#define MAX_PS_LINES 1000 +#define SOLID 0 +#define DOTTED 1 + +#define gtype graph->grid.gridtype +#define xoff dispdev->minx +#define yoff dispdev->miny +#define XOFF 48 /* printer left margin */ +#define YOFF 48 /* printer bottom margin */ +#define XTADJ 0 /* printer text adjustment x */ +#define YTADJ 4 /* printer text adjustment y */ + +#define GRIDSIZE 420 /* printer gridsize divisible by 10, [7-2] */ +#define GRIDSIZES 360 /* printer gridsize divisible by [10-8], [6-2] */ + +#define FONTSIZE 10 /* printer default fontsize */ +#define FONTWIDTH 6 /* printer default fontwidth */ +#define FONTHEIGHT 14 /* printer default fontheight */ + +typedef struct { + int lastlinestyle, lastcolor; /* initial invalid value */ + int lastx, lasty, linecount; +} PSdevdep; + +static char *linestyle[] = { + "[]", /* solid */ + "[1 2]", /* dotted */ + "[7 7]", /* longdashed */ + "[3 3]", /* shortdashed */ + "[7 2 2 2]", /* longdotdashed */ + "[3 2 1 2]", /* shortdotdashed */ + "[8 3 2 3]", + "[14 2]", + "[3 5 1 5]" /* dotdashed */ +}; + +static FILE *plotfile; +char psfont[128], psfontsize[32], psscale[32], pscolor[32]; +static int fontsize = FONTSIZE; +static int fontwidth = FONTWIDTH; +static int fontheight = FONTHEIGHT; +static int screenflag = 0; +static int colorflag = 0; +static double scale; /* Used for fine tuning */ +static int xtadj; /* text adjustment x */ +static int ytadj; /* text adjustment y */ +static int hcopygraphid; + + +extern int DestroyGraph (int id); +extern void internalerror (char *message); +void PS_LinestyleColor(int linestyleid, int colorid); +void PS_SelectColor(int colorid); +void PS_Stroke(void); + +int +PS_Init(void) +{ + char pswidth[30], psheight[30]; + + if (!cp_getvar("hcopyscale", VT_STRING, psscale)) { + scale = 1.0; + } else { + sscanf(psscale, "%lf", &scale); + if ((scale <= 0) || (scale > 10)) + scale = 1.0; + } + + if (!cp_getvar("hcopypscolor", VT_STRING, pscolor)) { + colorflag = 0; + dispdev->numcolors = 2; + dispdev->numlinestyles = NUMELEMS(linestyle); + } else { + colorflag = 1; + dispdev->numcolors = 18; /* don't know what the maximum should be */ + dispdev->numlinestyles = 1; + } + pscolor[0]='\0'; + + if (!cp_getvar("hcopywidth", VT_STRING, pswidth)) { + dispdev->width = 7.75 * 72.0 * scale; /* (8 1/2 - 3/4) * 72 */ + } else { + sscanf(pswidth, "%d", &(dispdev->width)); + if (dispdev->width <= 100) + dispdev->width = 100; + if (dispdev->width >= 10000) + dispdev->width = 10000; + } + if (!cp_getvar("hcopyheight", VT_STRING, psheight)) { + dispdev->height = dispdev->width; + } else { + sscanf(psheight, "%d", &(dispdev->height)); + if (dispdev->height <= 100) + dispdev->height = 100; + if (dispdev->height >= 10000) + dispdev->height = 10000; + } + + /* The following side effects have to be considered + * when the printer is called by com_hardcopy ! + * gr_init: + * viewportxoff = 8 * fontwidth + * viewportyoff = 4 * fontheight + * gr_resize_internal: + * viewport.width = absolute.width - 2 * viewportxoff + * viewport.height = absolute.height - 2 * viewportyoff + */ + + if (!cp_getvar("hcopyfont", VT_STRING, psfont)) + strcpy(psfont, "Helvetica"); + if (!cp_getvar("hcopyfontsize", VT_STRING, psfontsize)) { + fontsize = 10; + fontwidth = 6; + fontheight = 14; + xtadj = XTADJ * scale; + ytadj = YTADJ * scale; + } else { + sscanf(psfontsize, "%d", &fontsize); + if ((fontsize < 10) || (fontsize > 14)) + fontsize = 10; + fontwidth = 0.5 + 0.6 * fontsize; + fontheight = 2.5 + 1.2 * fontsize; + xtadj = XTADJ * scale * fontsize / 10; + ytadj = YTADJ * scale * fontsize / 10; + } + + screenflag = 0; + dispdev->minx = XOFF / scale; + dispdev->miny = YOFF / scale; + return(0); +} + +/* devdep initially contains name of output file */ +int +PS_NewViewport(GRAPH *graph) +{ + int x1,x2,y1,y2; + hcopygraphid = graph->graphid; + + if (!(plotfile = fopen(graph->devdep, "w"))) { + perror(graph->devdep); + graph->devdep = (char *) NULL; + return(1); + } + + if (graph->absolute.width) { + /* hardcopying from the screen */ + + screenflag = 1; + } + + /* reasonable values, used in gr_ for placement */ + graph->fontwidth = fontwidth * scale; /* was 12, p.w.h. */ + graph->fontheight = fontheight * scale; /* was 24, p.w.h. */ + + graph->absolute.width = dispdev->width; + graph->absolute.height = dispdev->height; + /* Also done in gr_init, if called . . . */ + graph->viewportxoff = 8 * fontwidth; + graph->viewportyoff = 4 * fontheight; + + xoff = scale * XOFF; + yoff = scale * YOFF; + + x1 = 0.75 * 72; + y1 = x1; + x2 = graph->absolute.width + .75 * 72; + y2 = graph->absolute.height + .75 * 72; + /* start file off with a % */ + fprintf(plotfile, "%%!PS-Adobe-3.0 EPSF-3.0\n"); + fprintf(plotfile, "%%%%Creator: nutmeg\n"); + fprintf(plotfile, "%%%%BoundingBox: %d %d %d %d\n",x1,y1,x2,y2); + + fprintf(plotfile, "%g %g scale\n", 1.0 / scale, 1.0 / scale); + + if (colorflag == 1){ /* set the background to color0 */ + PS_SelectColor(0); + fprintf(plotfile,"%s setrgbcolor\n",pscolor); + fprintf(plotfile,"newpath\n"); + fprintf(plotfile,"%d %d moveto %d %d lineto\n",x1,y1,x2,y1); + fprintf(plotfile,"%d %d lineto %d %d lineto\n",x2,y2,x1,y2); + fprintf(plotfile,"closepath fill\n"); + } + + /* set up a reasonable font */ + fprintf(plotfile, "/%s findfont %d scalefont setfont\n\n", + psfont, (int) (fontsize * scale)); + + graph->devdep = tmalloc(sizeof(PSdevdep)); + DEVDEP(graph).lastlinestyle = -1; + DEVDEP(graph).lastcolor = -1; + DEVDEP(graph).lastx = -1; + DEVDEP(graph).lasty = -1; + DEVDEP(graph).linecount = 0; + PS_SelectColor(0); + graph->linestyle = -1; + + return 0; +} + +void +PS_Close(void) +{ + /* in case PS_Close is called as part of an abort, + w/o having reached PS_NewViewport */ + if (plotfile){ + PS_Stroke(); + fprintf(plotfile, "showpage\n%%%%EOF\n"); + fclose(plotfile); + plotfile = NULL; + } + + /* In case of hardcopy command destroy the hardcopy graph + * and reset currentgraph to graphid 1, if possible + */ + if (!screenflag) { + DestroyGraph(hcopygraphid); + currentgraph = FindGraph(1); + } +} + +void +PS_Clear(void) +{ + /* do nothing */ +} + +void +PS_DrawLine(int x1, int y1, int x2, int y2) +{ + /* note: this is not extendible to more than one graph + => will have to give NewViewport a writeable graph XXX */ + + if (DEVDEP(currentgraph).linecount > MAX_PS_LINES + || DEVDEP(currentgraph).linecount == 0 + || x1 != DEVDEP(currentgraph).lastx + || y1 != DEVDEP(currentgraph).lasty){ + PS_Stroke(); + fprintf(plotfile, "newpath\n"); + fprintf(plotfile, "%d %d moveto\n", x1 + xoff, y1 + yoff); + DEVDEP(currentgraph).linecount += 1; + } + if (x1 != x2 || y1 != y2) { + fprintf(plotfile, "%d %d lineto\n", x2 + xoff, y2 + yoff); + DEVDEP(currentgraph).linecount += 1; + } + + DEVDEP(currentgraph).lastx = x2; + DEVDEP(currentgraph).lasty = y2; +} + +void +PS_Arc(int x0, int y0, int r, double theta1, double theta2) +{ + double x1, y1; + double angle1, angle2; + PS_Stroke(); + while (theta1 >= theta2) + theta2 += 2 * M_PI; + + angle1 = (double) (RAD_TO_DEG * theta1); + angle2 = (double) (RAD_TO_DEG * theta2); + x1 = (double) x0 + r * cos(theta1); + y1 = (double) y0 + r * sin(theta1); + + fprintf(plotfile, "%f %f moveto ", x1+(double)xoff, y1+(double)yoff); + fprintf(plotfile, "%d %d %d %f %f arc\n", x0+xoff, y0+yoff, r, + angle1, angle2); + fprintf(plotfile, "stroke\n"); + + DEVDEP(currentgraph).linecount = 0; +} + +void +PS_Text(char *text, int x, int y) +{ + int savedlstyle, savedcolor; + + /* set linestyle to solid + or may get funny color text on some plotters */ + savedlstyle = currentgraph->linestyle; + savedcolor = currentgraph->currentcolor; + + PS_SetLinestyle(SOLID); + PS_SetColor(1); + + /* stroke the path if there's an open one */ + PS_Stroke(); + /* move to (x, y) */ + fprintf(plotfile, "%d %d moveto\n", x + xoff + xtadj, y + yoff + ytadj); + fprintf(plotfile, "(%s) show\n", text); + + DEVDEP(currentgraph).lastx = -1; + DEVDEP(currentgraph).lasty = -1; + + /* restore old linestyle */ + + PS_SetColor(savedcolor); + PS_SetLinestyle(savedlstyle); +} + +/* PS_DefineColor */ +/* PS_DefineLinestyle */ + +int +PS_SetLinestyle(int linestyleid) +{ + /* special case + get it when PS_Text restores a -1 linestyle */ + if (linestyleid == -1) { + currentgraph->linestyle = -1; + return 0; + } + if (linestyleid < 0 || linestyleid > dispdev->numlinestyles) { + internalerror("bad linestyleid inside PS_SetLinestyle"); + return 0; + } + PS_LinestyleColor(linestyleid, currentgraph->currentcolor); + return 0; +} + +void +PS_SetColor(int colorid) +{ + PS_LinestyleColor(currentgraph->linestyle, colorid); +} + +void +PS_Update(void) +{ + fflush(plotfile); +} + +/**************** PRIVAT FUNCTIONS OF PS FRONTEND *****************************/ + +void +PS_SelectColor(int colorid) /* should be replaced by PS_DefineColor */ +{ + char colorN[30]="", colorstring[30]=""; + char rgb[30], s_red[30]="0x", s_green[30]="0x", s_blue[30]="0x"; + long red=0, green=0, blue=0, scale=1; + int i; + typedef struct { int red, green, blue;} COLOR; + /* duplicated colors from src/frontend/plotting/x11.c in rgb-style */ + const COLOR colors[]= {{ 0, 0, 0}, /*0: black */ + {255, 255, 255}, /*1: white */ + {255, 0, 0}, /*2: red */ + { 0, 0, 255}, /*3: blue */ + {255, 165, 0}, /*4: orange */ + { 0, 255, 0}, /*5: green */ + {255, 192, 203}, /*6: pink */ + {165, 42, 42}, /*7: brown */ + {240, 230, 140}, /*8: khaki */ + {221, 160, 221}, /*9: plum */ + {218, 112, 214}, /*10: orchid */ + {238, 130, 238}, /*11: violet */ + {176, 48, 96}, /*12: maroon */ + { 64, 224, 208}, /*13: turqoise */ + {160, 82, 45}, /*14: sienna */ + {255, 127, 80}, /*15: coral */ + { 0, 255, 255}, /*16: cyan */ + {255, 0, 255}, /*17: magenta */ + /*{255, 215, 0}, 18: gold */ + { 96, 96, 96}, /*18: gray for smith grid */ + /*{255, 255, 0}, 19: yello */ + {150, 150, 150}, /*19: gray for smith grid */ + {128, 128, 128}}; /*20: gray for normal grid */ + + /* Extract the rgbcolor, format is: "rgb://" */ + sprintf(colorN, "color%d",colorid); + if (cp_getvar(colorN, VT_STRING, colorstring)){ + for (i=0; colorstring[i]; i++) + if (colorstring[i] == '/' || colorstring[i] == ':') + colorstring[i] = ' '; + + sscanf(colorstring,"%s %s %s %s",rgb, &(s_red[2]), &(s_green[2]), &(s_blue[2])); + + if ((strlen(s_blue) == strlen(s_red) && strlen(s_green) == strlen(s_red)) + && (strlen(s_blue) > 2) && (strlen(s_blue) < 7)){ + sscanf(s_red,"%lx",&red); + sscanf(s_green,"%lx",&green); + sscanf(s_blue,"%lx",&blue); + scale= (1 << (strlen(s_blue) - 2) * 4) - 1; + sprintf(colorstring,"%1.3f %1.3f %1.3f", + (float) red/scale, (float) green/scale, (float) blue/scale); + strcpy(pscolor, colorstring); + } + } + if (colorid < 0 || colorid > 20) { + internalerror("bad colorid inside PS_SelectColor"); + }else if (scale == 1){ /* colorN is not an rgbstring, use default color */ + sprintf(colorstring,"%1.3f %1.3f %1.3f",colors[colorid].red/255.0, + colors[colorid].green/255.0, colors[colorid].blue/255.0) ; + strcpy(pscolor, colorstring); + } +} + +void +PS_LinestyleColor(int linestyleid, int colorid) +{ + /* we have some different linestyles and colors: + - color and linestyle we got via function call + - color and linestyle we used last time for drawing + - generated color and linestyle we'll use for drawing this time */ + /* these are the rules: + DOTTED and colored ps -> color20 (used for grid) and SOLID + color18 or 19 and black-white -> linestyle is DOTTED */ + + int gencolor=0,genstyle=0; + + if (colorflag == 1){ + genstyle = SOLID; + if (linestyleid==DOTTED) + gencolor = 20; + else + gencolor = colorid; + } else { /* colorflag == 0 -> mono*/ + if ((colorid == 18) || (colorid == 19)) + genstyle=DOTTED; + else + genstyle=linestyleid; + } + + /* change color if nessecary */ + if (colorflag == 1 && gencolor != DEVDEP(currentgraph).lastcolor){ + PS_SelectColor(gencolor); + PS_Stroke(); + fprintf(plotfile,"%s setrgbcolor\n",pscolor); + DEVDEP(currentgraph).lastcolor = gencolor; + } + currentgraph->currentcolor = colorid; + + /* change linestyle if nessecary */ + if (colorflag == 0 && genstyle != DEVDEP(currentgraph).lastlinestyle){ + PS_Stroke(); + fprintf(plotfile, "%s 0 setdash\n", linestyle[genstyle]); + DEVDEP(currentgraph).lastlinestyle= genstyle; + } + currentgraph->linestyle = linestyleid; +} + +void +PS_Stroke(void) +{ + /* strokes an open path */ + if (DEVDEP(currentgraph).linecount > 0) { + fprintf(plotfile, "stroke\n"); + DEVDEP(currentgraph).linecount = 0; + } +} + diff --git a/src/frontend/quote.c b/src/frontend/quote.c index e4d8641af..60810a497 100644 --- a/src/frontend/quote.c +++ b/src/frontend/quote.c @@ -78,14 +78,15 @@ cp_unquote(char *string) char *s; int l; if (string) { - s = copy(string); + l = strlen(string); + s = MALLOC(l+1); + + if (*string == '"' && string[l-1] == '"') { + strncpy(s,string+1,l-2); + s[l-2] = '\0'; + } else + strcpy(s,string); - if (*s == '"') - s++; - - l = strlen(s) - 1; - if (s[l] == '"') - s[l] = '\0'; return (s); } else return 0; diff --git a/src/frontend/runcoms.c b/src/frontend/runcoms.c index 75ef97d21..97f801949 100644 --- a/src/frontend/runcoms.c +++ b/src/frontend/runcoms.c @@ -20,6 +20,12 @@ Modified: 2000 AlansFixes #include "runcoms.h" #include "variable.h" +#ifdef XSPICE +/* gtri - add - 12/12/90 - wbk - include ipc stuff */ +#include "ipctiein.h" +/* gtri - end - 12/12/90 */ +#endif + /* static declarations */ static int dosim(char *what, wordlist *wl); @@ -37,6 +43,9 @@ FILE *rawfileFp; bool rawfileBinary; #define RAWBUF_SIZE 32768 char rawfileBuf[RAWBUF_SIZE]; +/*To tell resume the rawfile name saj*/ +char *last_used_rawfile = NULL; +/*end saj */ void com_scirc(wordlist *wl) @@ -250,7 +259,16 @@ dosim(char *what, wordlist *wl) } else { rawfileFp = NULL; } - + /*save rawfile name saj*/ + if(last_used_rawfile) + tfree(last_used_rawfile); /* va: we should allways use tfree */ + if(rawfileFp){ + last_used_rawfile = copy(wl->wl_word); + }else { + last_used_rawfile = NULL; + } + /*end saj*/ + /* Spice calls wrd_init and wrd_end itself */ ft_curckt->ci_inprogress = TRUE; if (eq(what,"sens2")) { @@ -258,6 +276,13 @@ dosim(char *what, wordlist *wl) /* The circuit was interrupted somewhere. */ fprintf(cp_err, "%s simulation interrupted\n", what); +#ifdef XSPICE + /* gtri - add - 12/12/90 - wbk - record error and return errchk */ + g_ipc.run_error = IPC_TRUE; + if(g_ipc.enabled) + ipc_send_errchk(); + /* gtri - end - 12/12/90 */ +#endif } else ft_curckt->ci_inprogress = FALSE; } else { @@ -265,6 +290,13 @@ dosim(char *what, wordlist *wl) if (err == 1) { /* The circuit was interrupted somewhere. */ fprintf(cp_err, "%s simulation interrupted\n", what); +#ifdef XSPICE + /* gtri - add - 12/12/90 - wbk - record error and return errchk */ + g_ipc.run_error = IPC_TRUE; + if(g_ipc.enabled) + ipc_send_errchk(); + /* gtri - end - 12/12/90 */ +#endif err = 0; } else if (err == 2) { fprintf(cp_err, "%s simulation(s) aborted\n", what); @@ -283,6 +315,14 @@ dosim(char *what, wordlist *wl) } ft_curckt->ci_runonce = TRUE; ft_setflag = FALSE; + + /* va: garbage collection: unlink first word (inserted here) and tfree it */ + if (!dofile) { + tfree(ww->wl_word); + if (wl) + wl->wl_prev = NULL; + tfree(ww); + } return err; } diff --git a/src/frontend/runcoms2.c b/src/frontend/runcoms2.c index ea5094844..455a0f973 100644 --- a/src/frontend/runcoms2.c +++ b/src/frontend/runcoms2.c @@ -20,6 +20,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group extern FILE *rawfileFp; extern bool rawfileBinary; +/*rawfile output saj*/ +extern char *last_used_rawfile; +#define RAWBUF_SIZE 32768 +char rawfileBuf[RAWBUF_SIZE]; +/*end saj*/ extern struct dbcomm *dbs; /* Continue a simulation. If there is non in progress, this is the @@ -42,6 +47,22 @@ com_resume(wordlist *wl) { struct dbcomm *db; int err; + + /*rawfile output saj*/ + bool dofile = FALSE; + char buf[BSIZE_SP]; + bool ascii = AsciiRawFile; + /*end saj*/ + + /*saj fix segment*/ + if (!ft_curckt) { + fprintf(cp_err, "Error: there aren't any circuits loaded.\n"); + return; + } else if (ft_curckt->ci_ckt == NULL) { /* Set noparse? */ + fprintf(cp_err, "Error: circuit not parsed.\n"); + return; + } + /*saj*/ if (ft_curckt->ci_inprogress == FALSE) { fprintf(cp_err, "Note: run starting\n"); @@ -51,13 +72,70 @@ com_resume(wordlist *wl) ft_curckt->ci_inprogress = TRUE; ft_setflag = TRUE; + + reset_trace( ); for ( db = dbs, resumption = FALSE; db; db = db->db_next ) if( db->db_type == DB_IPLOT || db->db_type == DB_IPLOTALL ) { resumption = TRUE; } + + /*rawfile output saj*/ + if (last_used_rawfile) + dofile = TRUE; + + if (cp_getvar("filetype", VT_STRING, buf)) { + if (eq(buf, "binary")) + ascii = FALSE; + else if (eq(buf, "ascii")) + ascii = TRUE; + else + fprintf(cp_err, + "Warning: strange file type \"%s\" (using \"ascii\")\n", + buf); + } + + if (dofile) { +#ifdef PARALLEL_ARCH + if (ARCHme == 0) { +#endif /* PARALLEL_ARCH */ + if (!last_used_rawfile) + rawfileFp = stdout; + else if (!(rawfileFp = fopen(last_used_rawfile, "a"))) { + setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE); + perror(last_used_rawfile); + ft_setflag = FALSE; + return; + } + rawfileBinary = !ascii; +#ifdef PARALLEL_ARCH + } else { + rawfileFp = NULL; + } +#endif /* PARALLEL_ARCH */ + } else { + rawfileFp = NULL; + } + + + + + /*end saj*/ + err = if_run(ft_curckt->ci_ckt, "resume", (wordlist *) NULL, - ft_curckt->ci_symtab); + ft_curckt->ci_symtab); + + /*close rawfile saj*/ + if (rawfileFp){ + if (ftell(rawfileFp)==0) { + (void) fclose(rawfileFp); + (void) remove(last_used_rawfile); + } else { + (void) fclose(rawfileFp); + } + } + /*end saj*/ + if (err == 1) { /* The circuit was interrupted somewhere. */ diff --git a/src/frontend/spiceif.c b/src/frontend/spiceif.c index 69b5b6571..412eabc64 100644 --- a/src/frontend/spiceif.c +++ b/src/frontend/spiceif.c @@ -25,6 +25,17 @@ Modified: 2000 AlansFixes #include "spiceif.h" #include "variable.h" +#ifdef XSPICE +/* gtri - add - wbk - 11/9/90 - include MIF function prototypes */ +#include "mifproto.h" +/* gtri - end - wbk - 11/9/90 */ + +/* gtri - evt - wbk - 5/20/91 - Add stuff for user-defined nodes */ +#include "evtproto.h" +#include "evtudn.h" +/* gtri - end - wbk - 5/20/91 - Add stuff for user-defined nodes */ +#endif + /* static declarations */ static struct variable * parmtovar(IFvalue *pv, IFparm *opt); static IFparm * parmlookup(IFdevice *dev, GENinstance **inptr, char *param, @@ -98,6 +109,7 @@ if_inpdeck(struct line *deck, INPtables **tab) } ft_curckt->ci_curTask = ft_curckt->ci_defTask; + INPpas1((void *) ckt, (card *) deck->li_next,(INPtables *)*tab); INPpas2((void *) ckt, (card *) deck->li_next, (INPtables *) *tab,ft_curckt->ci_defTask); @@ -111,6 +123,16 @@ if_inpdeck(struct line *deck, INPtables **tab) (INPtables *) *tab,ft_curckt->ci_defTask, ft_sim->nodeParms, ft_sim->numNodeParms); +#ifdef XSPICE +/* gtri - begin - wbk - 6/6/91 - Finish initialization of event driven structures */ + err = EVTinit((void *) ckt); + if(err) { + ft_sperror(err,"EVTinit"); + return(NULL); + } +/* gtri - end - wbk - 6/6/91 - Finish initialization of event driven structures */ +#endif + return (ckt); } @@ -131,6 +153,7 @@ if_run(char *t, char *what, wordlist *args, char *tab) int j; int which = -1; IFuid specUid,optUid; + char *s; /* First parse the line... */ @@ -145,7 +168,9 @@ if_run(char *t, char *what, wordlist *args, char *tab) || eq(what,"tf") || eq(what, "noise")) { - (void) sprintf(buf, ".%s", wl_flatten(args)); + s = wl_flatten(args); /* va: tfree char's tmalloc'ed in wl_flatten */ + (void) sprintf(buf, ".%s", s); + tfree(s); deck.li_next = deck.li_actual = NULL; deck.li_error = NULL; deck.li_linenum = 0; @@ -259,7 +284,9 @@ if_run(char *t, char *what, wordlist *args, char *tab) /* -- A bug fix suggested by Cecil Aswell (aswell@netcom.com) to let */ /* -- the interactive analysis commands get the current temperature */ /* -- and other options. */ - +/*dw Hiermit wird auf der Eingabezeile mit "run" die letzte Simulation + wiederholt, sowie die letzte gültige Temperatur genutzt. (Warum die + in defOpt drin steht, steht in den Sternen!) */ if( eq(what,"run") ) { ft_curckt->ci_curTask = ft_curckt->ci_defTask; ft_curckt->ci_curOpt = ft_curckt->ci_defOpt; @@ -278,6 +305,8 @@ if_run(char *t, char *what, wordlist *args, char *tab) ||(eq(what, "sens")) ||(eq(what,"tf")) ||(eq(what, "run")) ) { +/*dw Nutzung der letzten gültigen Temperatur, z.B. nach "set temp" s.o. */ + ft_curckt->ci_curOpt = ft_curckt->ci_defOpt; if ((err = (*(ft_sim->doAnalyses))(ckt, 1, ft_curckt->ci_curTask))!=OK){ ft_sperror(err, "doAnalyses"); /* wrd_end(); */ @@ -938,3 +967,381 @@ if_getstat(void *ckt, char *name) } } +#ifdef EXPERIMENTAL_CODE + +#include +#include + +/* arg0: circuit file, arg1: data file */ +void com_loadsnap(wordlist *wl) { + int error = 0; + FILE *file; + int tmpI, i, size; + CKTcircuit *my_ckt, *ckt; + + /* + Phesudo code: + + source(file_name); + This should setup all the device structs, voltage nodes, etc. + + call cktsetup; + This is needed to setup vector mamory allocation for vectors and branch nodes + + load_binary_data(info); + Overwrite the allocated numbers, rhs etc, with saved data + */ + + + if (ft_curckt) { + fprintf(cp_err, "Error: there is already a circuit loaded.\n"); + return; + } + + /* source the circuit */ + inp_source(wl->wl_word); + if (!ft_curckt) { + return; + } + + /* allocate all the vectors, with luck! */ + if (!error) + error = CKTsetup((CKTcircuit *)ft_curckt->ci_ckt); + if (!error) + error = CKTtemp((CKTcircuit *)ft_curckt->ci_ckt); + + if(error) { + fprintf(cp_err,"Some error in the CKT setup fncts!\n"); + return; + } + + /* so it resumes ... */ + ft_curckt->ci_inprogress = TRUE; + + + /* now load the binary file */ + + + ckt = (CKTcircuit *)ft_curckt->ci_ckt; + + file = fopen(wl->wl_next->wl_word,"rb"); + + if(!file) { + fprintf(cp_err, + "Error: Couldn't open \"%s\" for reading\n", + wl->wl_next->wl_word); + return; + } + + fread(&tmpI,sizeof(int),1,file); + if(tmpI != sizeof(CKTcircuit) ) { + fprintf(cp_err,"loaded num: %d, expected num: %d\n",tmpI,sizeof(CKTcircuit)); + fprintf(cp_err, + "Error: snapshot saved with different version of spice\n"); + fclose(file); + return; + } + + my_ckt = (CKTcircuit *)tmalloc(sizeof(CKTcircuit)); + + fread(my_ckt,sizeof(CKTcircuit),1,file); + +#define _t(name) ckt->name = my_ckt->name +#define _ta(name,size)\ + do{ int __i; for(__i=0;__iCKTmaxOrder+1;i++) { + _foo(ckt->CKTstates[i],double,ckt->CKTnumStates); + } + + size = SMPmatSize(ckt->CKTmatrix) + 1; + _foo(ckt->CKTrhs, double,size); + _foo(ckt->CKTrhsOld, double,size); + _foo(ckt->CKTrhsSpare, double,size); + _foo(ckt->CKTirhs, double,size); + _foo(ckt->CKTirhsOld, double,size); + _foo(ckt->CKTirhsSpare, double,size); + _foo(ckt->CKTrhsOp, double,size); + _foo(ckt->CKTsenRhs, double,size); + _foo(ckt->CKTseniRhs, double,size); + + _foo(ckt->CKTtimePoints,double,-1); + _foo(ckt->CKTdeltaList,double,-1); + + _foo(ckt->CKTbreaks,double,ckt->CKTbreakSize); + + _foo((TSKtask *)ft_curckt->ci_curTask,TSKtask,1); + + /* To stop the Free */ + ((TSKtask *)ft_curckt->ci_curTask)->TSKname = NULL; + ((TSKtask *)ft_curckt->ci_curTask)->jobs = NULL; + + _foo(((TSKtask *)ft_curckt->ci_curTask)->TSKname,char,-1); + + _foo(((TRANan *)((TSKtask *)ft_curckt->ci_curTask)->jobs),TRANan,1); + ((TSKtask *)ft_curckt->ci_curTask)->jobs->JOBname = NULL; + ckt->CKTcurJob = (JOB *)((TSKtask *)ft_curckt->ci_curTask)->jobs; + + _foo(((TSKtask *)ft_curckt->ci_curTask)->jobs->JOBname,char,-1); + + ((TSKtask *)ft_curckt->ci_curTask)->jobs->JOBnextJob = NULL; + + ((TRANan *)((TSKtask *)ft_curckt->ci_curTask)->jobs)->TRANplot = NULL; + + _foo(ckt->CKTstat,STATistics,1); + + tfree(my_ckt); + fclose(file); + + /* Finally to resume the plot in some fashion */ + + /* a worked out version of this should be enough */ + { + IFuid *nameList; + int numNames; + IFuid timeUid; + + error = CKTnames(ckt,&numNames,&nameList); + if(error){ + fprintf(cp_err,"error in CKTnames\n"); + return; + } + (*(SPfrontEnd->IFnewUid))((void *)ckt,&timeUid,(IFuid)NULL, + "time", UID_OTHER, (void **)NULL); + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, + ckt->CKTcurJob->JOBname,timeUid,IF_REAL,numNames,nameList, + IF_REAL,&(((TRANan*)ckt->CKTcurJob)->TRANplot)); + if(error) { + fprintf(cp_err,"error in CKTnames\n"); + return; + } + } + + + + return ; +} + +void com_savesnap(wordlist *wl) { + FILE *file; + int i, size; + CKTcircuit *ckt; + TSKtask *task; + + if (!ft_curckt) { + fprintf(cp_err, "Error: there is no circuit loaded.\n"); + return; + } else if (ft_curckt->ci_ckt == NULL) { /* Set noparse? */ + fprintf(cp_err, "Error: circuit not parsed.\n"); + return; + } + + /* save the data */ + + ckt = (CKTcircuit *)ft_curckt->ci_ckt; + + task = (TSKtask *)ft_curckt->ci_curTask; + + if(task->jobs->JOBtype != 4) { + fprintf(cp_err,"Only saving of tran analysis is implemented\n"); + return; + } + + file = fopen(wl->wl_word,"wb"); + + if(!file) { + fprintf(cp_err, + "Error: Couldn't open \"%s\" for writing\n",wl->wl_word); + return; + } + +#undef _foo +#define _foo(name,type,num)\ + do {\ + int __i;\ + if(name) {\ + __i = (num) * sizeof(type); fwrite(&__i,sizeof(int),1,file);\ + if((num))\ + fwrite(name,sizeof(type),(num),file);\ + } else {\ + __i = 0;\ + fprintf(cp_err,#name " is NULL, zero written\n");\ + fwrite(&__i,sizeof(int),1,file);\ + }\ + } while(0) + + + _foo(ckt,CKTcircuit,1); + + /* To save list + + double *(CKTstates[8]); + double *CKTrhs; + double *CKTrhsOld; + double *CKTrhsSpare; + double *CKTirhs; + double *CKTirhsOld; + double *CKTirhsSpare; + double *CKTrhsOp; + double *CKTsenRhs; + double *CKTseniRhs; + double *CKTtimePoints; list of all accepted timepoints in + the current transient simulation + double *CKTdeltaList; list of all timesteps in the + current transient simulation + + */ + + + for(i=0;i<=ckt->CKTmaxOrder+1;i++) { + _foo(ckt->CKTstates[i],double,ckt->CKTnumStates); + } + + + + size = SMPmatSize(ckt->CKTmatrix) + 1; + + _foo(ckt->CKTrhs,double,size); + _foo(ckt->CKTrhsOld,double,size); + _foo(ckt->CKTrhsSpare,double,size); + _foo(ckt->CKTirhs,double,size); + _foo(ckt->CKTirhsOld,double,size); + _foo(ckt->CKTirhsSpare,double,size); + _foo(ckt->CKTrhsOp,double,size); + _foo(ckt->CKTsenRhs,double,size); + _foo(ckt->CKTseniRhs,double,size); + + _foo(ckt->CKTtimePoints,double,ckt->CKTtimeListSize); + _foo(ckt->CKTdeltaList,double,ckt->CKTtimeListSize); + + /* need to save the breakpoints, or something */ + + _foo(ckt->CKTbreaks,double,ckt->CKTbreakSize); + + + /* now save the TSK struct, ft_curckt->ci_curTask*/ + + _foo(task,TSKtask,1); + _foo(task->TSKname,char,(strlen(task->TSKname)+1)); + + /* now save the JOB struct task->jobs */ + /* lol, only allow one job, tough! */ + /* Note that JOB is a base class, need to save actual type!! */ + + _foo(task->jobs,TRANan,1); + + _foo(task->jobs->JOBname,char,(strlen(task->jobs->JOBname)+1)); + + + /* Finally the stats */ + + _foo(ckt->CKTstat,STATistics,1); + + + fclose(file); + + return; + +} + +#endif diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index 65c3f2ae1..eb5503dbe 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -4,42 +4,25 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group Modified: 2000 AlansFixes **********/ +/*------------------------------------------------------------------------------ + * re-written by SDB during 4.2003 to enable SPICE2 POLY statements to be processed + * properly. This is particularly important for dependent sources, whose argument + * list changes when POLY is used. + * Major changes include: + * -- Added lots of comments which (hopefully) elucidate the steps taken + * by the program during its processing. + * -- Re-wrote translate, which does the processing of each card. + * Please direct comments/questions/complaints to Stuart Brorson: + * mailto:sdb@cloud9.net + *-----------------------------------------------------------------------------*/ + /* * Expand subcircuits. This is very spice-dependent. Bug fixes by Norbert * Jeske on 10/5/85. */ -#include "ngspice.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "fteinp.h" - -#include "subckt.h" -#include "variable.h" - -/* static declarations */ -static struct line * doit(struct line *deck); -static int translate(struct line *deck, char *formal, char *actual, char *scname, - char *subname); -static void finishLine(char *dst, char *src, char *scname); -static int settrans(char *formal, char *actual, char *subname); -static char * gettrans(char *name); -static int numnodes(char *name); -static int numdevs(char *s); -static bool modtranslate(struct line *deck, char *subname); -static void devmodtranslate(struct line *deck, char *subname); - - - -struct subs { - char *su_name; /* The name. */ - char *su_args; /* The arguments, space seperated. */ - int su_numargs; - struct line *su_def; /* The deck that is to be substituted. */ - struct subs *su_next; -} ; - -/* Expand all subcircuits in the deck. This handles imbedded .subckt +/*======================================================================* + * Expand all subcircuits in the deck. This handles imbedded .subckt * definitions. The variables substart, subend, and subinvoke can be used * to redefine the controls used. The syntax is invariant though. * NOTE: the deck must be passed without the title line. @@ -52,7 +35,58 @@ struct subs { * Then we have to systematically change all references to the renamed * nodes. On top of that, we have to know how many args BJT's have, * so we have to keep track of model names. - */ + *======================================================================*/ + +#include "ngspice.h" +#include "cpdefs.h" +#include "ftedefs.h" +#include "fteinp.h" + +#ifdef XSPICE +/* gtri - add - wbk - 11/9/90 - include MIF function prototypes */ +#include "mifproto.h" +/* gtri - end - wbk - 11/9/90 */ +#endif + +#include "subckt.h" +#include "variable.h" + + +/* ----- static declarations ----- */ +static struct line * doit(struct line *deck); +static int translate(struct line *deck, char *formal, char *actual, char *scname, + char *subname); +static void finishLine(char *dst, char *src, char *scname); +static int settrans(char *formal, char *actual, char *subname); +static char * gettrans(char *name); +static int numnodes(char *name); +static int numdevs(char *s); +static bool modtranslate(struct line *deck, char *subname); +static void devmodtranslate(struct line *deck, char *subname); + +/*--------------------------------------------------------------------- + * table is used in settrans and gettrans -- it holds the netnames used + * in the .subckt definition (t_old), and in the subcircuit invocation + * (t_new) + *--------------------------------------------------------------------*/ +static struct tab { + char *t_old; + char *t_new; +} table[512]; /* That had better be enough. */ + + +/*--------------------------------------------------------------------- + * subs is the linked list which holds the .subckt definitions + * found during processing. + *--------------------------------------------------------------------*/ +struct subs { + char *su_name; /* The .subckt name. */ + char *su_args; /* The .subckt arguments, space seperated. */ + int su_numargs; + struct line *su_def; /* Pointer to the .subckt definition. */ + struct subs *su_next; +} ; + static wordlist *modnames, *submod; static struct subs *subs = NULL; @@ -60,6 +94,22 @@ static bool nobjthack = FALSE; static char start[32], sbend[32], invoke[32], model[32]; +/*-------------------------------------------------------------------*/ +/* inp_subcktexpand is the top level function which translates */ +/* .subckts into mainlined code. Note that there are two things */ +/* we need to do: 1. Find all .subckt definitions & stick them */ +/* into a list. 2. Find all subcircuit invocations (refdes X) */ +/* and replace them with the .subckt definition stored earlier. */ +/* */ +/* The algorithm is as follows: */ +/* 1. Define some aliases for .subckt, .ends, etc. */ +/* 2. Clean up parens around netnames */ +/* 3. Call doit, which does the actual translation. */ +/* 4. Check the results & return. */ +/* inp_subcktexpand takes as argument a pointer to deck, and */ +/* it returns a pointer to the same deck after the new subcircuits */ +/* are spliced in. */ +/*-------------------------------------------------------------------*/ struct line * inp_subcktexpand(struct line *deck) { @@ -81,38 +131,40 @@ inp_subcktexpand(struct line *deck) /* Let's do a few cleanup things first... Get rid of ( ) around node * lists... */ - for (c = deck; c; c = c->li_next) { - if (prefix(start, c->li_line)) { - for (s = c->li_line; *s && (*s != '('); s++) - ; - if (*s) { - while (s[0] && (s[1] != ')')) { - s[0] = s[1]; - s++; - } - while (s[1]) { - s[0] = s[2]; - s++; - } - } - } else { - for (s = c->li_line; *s && !isspace(*s); s++) - ; - while (isspace(*s)) - s++; - if (*s == '(') { - while (s[0] && (s[1] != ')')) { - s[0] = s[1]; - s++; - } - while (s[1]) { - s[0] = s[2]; - s++; - } - } - } - } + for (c = deck; c; c = c->li_next) { /* iterate on lines in deck */ + if (prefix(start, c->li_line)) { /* if we find .subckt . . . */ + for (s = c->li_line; *s && (*s != '('); s++) /* Iterate charwise along line until ( is found */ + ; + if (*s) { + while (s[0] && (s[1] != ')')) { + s[0] = s[1]; + s++; + } + while (s[1]) { + s[0] = s[2]; + s++; + } + } /* if (*s) . . . */ + } else { + for (s = c->li_line; *s && !isspace(*s); s++) /* Iterate charwise along line until space is found */ + ; + while (isspace(*s)) + s++; + if (*s == '(') { + while (s[0] && (s[1] != ')')) { + s[0] = s[1]; + s++; + } + while (s[1]) { + s[0] = s[2]; + s++; + } /* while */ + } /* if (*s == '(' . . . */ + } + } /* for (c = deck . . . */ + + /* doit does the actual splicing in of the .subckt . . . */ ll = doit(deck); /* Now check to see if there are still subckt instances undefined... */ @@ -123,16 +175,26 @@ inp_subcktexpand(struct line *deck) return NULL; } - return (ll); + return (ll); /* return the spliced deck. */ } -#define MAXNEST 21 +#define MAXNEST 21 +/*-------------------------------------------------------------------*/ +/* doit does the actual substitution of .subckts. */ +/* It takes two passes: the first extracts .subckts */ +/* and sticks pointer to them into the linked list sss. It does */ +/* the extraction recursively. Then, it look for subcircuit */ +/* invocations and substitutes the stored .subckt into */ +/* the main circuit file. */ +/* It takes as argument a pointer to the deck, and returns a */ +/* pointer to the deck after the subcircuit has been spliced in. */ +/*-------------------------------------------------------------------*/ static struct line * doit(struct line *deck) { struct line *c, *last, *lc, *lcc; - struct subs *sss = (struct subs *) NULL, *ks; + struct subs *sss = (struct subs *) NULL, *ks; /* *sss and *ks temporarily hold decks to substitute */ char *s, *t, *scname, *subname; int nest, numpasses = MAXNEST, i; bool gotone; @@ -147,51 +209,68 @@ doit(struct line *deck) subs = NULL; submod = NULL; - /* Extract all the .subckts */ - for (last = deck, lc = NULL; last; ) { - if (prefix(sbend, last->li_line)) { + /* First pass: xtract all the .subckts and stick pointers to them into sss. */ + for (last = deck, lc = NULL; last; ) { + if (prefix(sbend, last->li_line)) { /* if line == .ends */ fprintf(cp_err, "Error: misplaced %s line: %s\n", sbend, last->li_line); return (NULL); - } else if (prefix(start, last->li_line)) { - if (last->li_next == NULL) { + } + else if (prefix(start, last->li_line)) { /* if line == .subckt */ + if (last->li_next == NULL) { /* first check that next line is non null */ fprintf(cp_err, "Error: no %s line.\n", sbend); return (NULL); } - lcc = NULL; + lcc = NULL; wl_free(submod); submod = NULL; gotone = FALSE; - for (nest = 0, c = last->li_next; c; c = c->li_next) { - if (prefix(sbend, c->li_line)) { + + /* Here we loop through the deck looking for .subckt and .ends cards. + * At the end of this section, last will point to the location of the + * .subckt card, and lcc will point to the location of the .ends card. + */ + for (nest = 0, c = last->li_next; c; c = c->li_next) { + if (prefix(sbend, c->li_line)) { /* found a .ends */ if (!nest) - break; + break; /* nest = 0 means we have balanced .subckt and .ends */ else { - nest--; - lcc = c; - continue; + nest--; /* decrement nesting, and assign lcc to the current card */ + lcc = c; /* (lcc points to the position of the .ends) */ + continue; /* then continue looping */ } - } else if (prefix(start, c->li_line)) + } else if (prefix(start, c->li_line)) /* if .subckt, increment nesting */ nest++; - lcc = c; - } - if (!c) { + lcc = c; /* lcc points to current pos of c */ + } /* for (nest = 0 . . . */ + + /* Check to see if we have looped through remainder of deck without finding .ends */ + if (!c) { fprintf(cp_err, "Error: no %s line.\n", sbend); - return (NULL); + return (NULL); } + + sss = alloc(struct subs); - if (!lcc) + if (!lcc) /* if lcc is null, then no .ends was found. */ lcc = last; - lcc->li_next = NULL; + lcc->li_next = NULL; /* shouldn't we free some memory here????? */ + + /* At this point, last points to the .subckt card, and lcc points to the .ends card */ + + /* what does this do!??!?! */ if (lc) lc->li_next = c->li_next; else deck = c->li_next; - sss->su_def = last->li_next; - s = last->li_line; - (void) gettok(&s); + + /* Now put the .subckt definition found into sss */ + sss->su_def = last->li_next; + s = last->li_line; + txfree(gettok(&s)); sss->su_name = gettok(&s); sss->su_args = copy(s); + /* count the number of args in the .subckt line */ for (sss->su_numargs = 0, i = 0; s[i]; ) { while (isspace(s[i])) i++; @@ -201,51 +280,74 @@ doit(struct line *deck) i++; } } - sss->su_next = subs; - subs = sss; + sss->su_next = subs; + subs = sss; /* Now that sss is built, assign it to subs */ last = c->li_next; lcc = subs->su_def; - } else { - lc = last; + + } + else { /* line is neither .ends nor .subckt. */ + /* make lc point to this card, and advance last to next card. */ + lc = last; last = last->li_next; } - } + } /* for (last = deck . . . . */ - if (!sss) + + /* At this point, sss holds the .subckt definition found, subs holds + * all .subckt defs found, including this one, + * last points to the NULL at the end of the deck, + * lc points to the last non-.subckt or .ends card, + * and lcc points to the .ends card + */ + + if (!sss) /* if sss == FALSE, we have found no subckts. Just return. */ return (deck); - /* Expand sub-subcircuits. */ - for (ks = sss = subs; sss; sss = sss->su_next) + /* Otherwise, expand sub-subcircuits recursively. */ + for (ks = sss = subs; sss; sss = sss->su_next) /* iterate through the list of subcircuits */ if (!(sss->su_def = doit(sss->su_def))) return (NULL); - subs = ks; + subs = ks; /* ks has held pointer to start of subcircuits list. */ - /* Get all the model names so we can deal with BJT's. */ + + /* Get all the model names so we can deal with BJT's. + * Stick all the model names into the doubly-linked wordlist wl. + */ for (c = deck; c; c = c->li_next) if (prefix(model, c->li_line)) { s = c->li_line; - (void) gettok(&s); + txfree(gettok(&s)); wl = alloc(struct wordlist); wl->wl_next = modnames; if (modnames) modnames->wl_prev = wl; modnames = wl; - wl->wl_word = gettok(&s); + wl->wl_word = gettok(&s); /* wl->wl_word now holds name of model */ } error = 0; - /* Now do the replacements. */ - do { + /* Second pass: do the replacements. */ + do { /* while (!error && numpasses-- && gotone) */ gotone = FALSE; for (c = deck, lc = NULL; c; ) { - if (ciprefix(invoke, c->li_line)) { - gotone = TRUE; - t = s = copy(c->li_line); - scname = gettok(&s); - scname += strlen(invoke); + if (ciprefix(invoke, c->li_line)) { /* found reference to .subckt (i.e. component with refdes X) */ + char *tofree, *tofree2; + gotone = TRUE; + t = tofree = s = copy(c->li_line); /* s & t hold copy of component line */ + + /* make scname point to first non-whitepace chars after refdes invocation + * e.g. if invocation is Xreference, *scname = reference + */ + tofree2 = scname = gettok(&s); + scname += strlen(invoke); while ((*scname == ' ') || (*scname == '\t') || (*scname == ':')) scname++; + + /* Now set s to point to last non-space chars in line (i.e. + * the name of the model invoked + */ while(*s) s++; s--; @@ -254,32 +356,49 @@ doit(struct line *deck) while ((*s != ' ') && (*s != '\t')) s--; s++; - for (sss = subs; sss; sss = sss->su_next) + + /* iterate through .subckt list and look for .subckt name invoked */ + for (sss = subs; sss; sss = sss->su_next) if (eq(sss->su_name, s)) break; - /* Don't complain -- this might be an - * instance of a subckt that is defined above. + + + /* At this point, sss points to the .subckt invoked, + * and scname points to the netnames + * involved. + */ + + + /* If no .subckt is found, don't complain -- this might be an + * instance of a subckt that is defined above at higher level. */ if (!sss) { lc = c; c = c->li_next; continue; } + /* Now we have to replace this line with the * macro definition. */ - subname = copy(sss->su_name); - lcc = inp_deckcopy(sss->su_def); + subname = copy(sss->su_name); - /* Change the names of the models... */ - if (modtranslate(lcc, scname)) + /* make lcc point to a copy of the .subckt definition */ + lcc = inp_deckcopy(sss->su_def); + + /* Change the names of .models found in .subckts . . . */ + if (modtranslate(lcc, scname)) devmodtranslate(lcc, scname); s = sss->su_args; - (void) gettok(&t); /* Throw out the name. */ + txfree(gettok(&t)); /* Throw out the subcircuit refdes */ + /* now invoke translate, which handles the remainder of the + * translation. + */ if (!translate(lcc, s, t, scname, subname)) error = 1; + tfree(subname); /* Now splice the decks together. */ if (lc) @@ -291,13 +410,17 @@ doit(struct line *deck) lcc->li_next = c->li_next; c = lcc->li_next; lc = lcc; - } else { + tfree(tofree); + tfree(tofree2); + } /* if (ciprefix(invoke, c->li_line)) . . . */ + else { lc = c; c = c->li_next; } } } while (!error && numpasses-- && gotone); + if (!numpasses) { fprintf(cp_err, "Error: infinite subckt recursion\n"); return (NULL); @@ -314,8 +437,11 @@ doit(struct line *deck) return (deck); } -/* Copy a deck, including the actual lines. */ + +/*-------------------------------------------------------------------*/ +/* Copy a deck, including the actual lines. */ +/*-------------------------------------------------------------------*/ struct line * inp_deckcopy(struct line *deck) { @@ -337,111 +463,448 @@ inp_deckcopy(struct line *deck) return (nd); } -/* Translate all of the device names and node names in the deck. They are +/*------------------------------------------------------------------------------------------* + * Translate all of the device names and node names in the .subckt deck. They are * pre-pended with subname:, unless they are in the formal list, in which case * they are replaced with the corresponding entry in the actual list. * The one special case is node 0 -- this is always ground and we don't * touch it. - */ - + * + * Variable name meanings: + * *deck = pointer to subcircuit definition (lcc) (struct line) + * formal = copy of the .subckt definition line (e.g. ".subckt subcircuitname 1 2 3") (string) + * actual = copy of the .subcircuit invocation line (e.g. "Xexample 4 5 6 subcircuitname") (string) + * scname = refdes (- first letter) used at invocation (e.g. "example") (string) + * subname = copy of the subcircuit name + *-------------------------------------------------------------------------------------------*/ static int translate(struct line *deck, char *formal, char *actual, char *scname, char *subname) { struct line *c; - char *buffer, *name, *s, *t, ch; - int nnodes, i; - + char *buffer, *next_name, dev_type, *name, *s, *t, ch, *nametofree; + int nnodes, i, dim; + int rtn=0; + + /* settrans builds the table holding the translated netnames. */ i = settrans(formal, actual, subname); if (i < 0) { fprintf(stderr, "Too few parameters for subcircuit type \"%s\" (instance: x%s)\n", subname, scname); - return 0; + goto quit; } else if (i > 0) { fprintf(stderr, "Too many parameters for subcircuit type \"%s\" (instance: x%s)\n", subname, scname); - return 0; + goto quit; } - for (c = deck; c; c = c->li_next) { - /* Rename the device. */ - switch (*c->li_line) { + /* now iterate through the .subckt deck and translate the cards. */ + for (c = deck; c; c = c->li_next) { + +#ifdef TRACE + /* SDB debug statement */ + printf("\nIn translate, examining line %s \n", c->li_line); +#endif + + + dev_type = *(c->li_line); + + /* Rename the device. */ + switch (dev_type) { case '\0': case '*': case '.': - /* Nothing any good here. */ - continue; + /* Just a pointer to the line into s and then break */ + buffer = tmalloc(2000); /* XXXXX */ + s = c->li_line; + break; - default: - s = c->li_line; - name = gettok(&s); - if (!name) - continue; - if (!*name) { - tfree(name); - continue; - } - ch = *name; - buffer = tmalloc(10000); /* XXXXX */ - name++; - if (*name == ':') - name++; - if (*name) - (void) sprintf(buffer, "%c:%s:%s ", ch, scname, - name); - else - (void) sprintf(buffer, "%c:%s ", ch, scname); - nnodes = numnodes(c->li_line); - while (nnodes-- > 0) { - name = gettok(&s); - if (name == NULL) { - fprintf(cp_err, "Error: too few nodes: %s\n", - c->li_line); - return 0; - } - t = gettrans(name); - if (t) - (void) sprintf(buffer + strlen(buffer), "%s ", - t); - else - (void) sprintf(buffer + strlen(buffer), - "%s:%s ", scname, name); - } - nnodes = numdevs(c->li_line); - while (nnodes-- > 0) { - name = gettok(&s); - if (name == NULL) { - fprintf(cp_err, "Error: too few devs: %s\n", - c->li_line); - return 0; - } - ch = *name; - name++; - if (*name == ':') - name++; - if (*name) - (void) sprintf(buffer + strlen(buffer), - "%c:%s:%s ", ch, scname, name); - else - (void) sprintf(buffer + strlen(buffer), - "%c:%s ", ch, scname); - } - /* Now scan through the line for v(something) and - * i(something)... - */ - finishLine(buffer + strlen(buffer), s, scname); +#ifdef XSPICE +/*=================== case A ====================*/ +/* gtri - add - wbk - 10/23/90 - process A devices specially */ +/* since they have a more involved and variable length node syntax */ + + case 'a': + case 'A': + + /* translate the instance name according to normal rules */ + + buffer = tmalloc(2000); /* XXXXX */ + + s = c->li_line; + name = MIFgettok(&s); + + /* maschmann + sprintf(buffer, "%s:%s ", name, scname); */ + sprintf(buffer, "a:%s:%s ", scname, name+1 ); + + + + /* Now translate the nodes, looking ahead one token to recognize */ + /* when we reach the model name which should not be translated */ + /* here. */ + + next_name = MIFgettok(&s); + + while(1) { + + /* rotate the tokens and get the the next one */ + + name = next_name; + next_name = MIFgettok(&s); + + /* if next token is NULL, name holds the model name, so exit */ + + if(next_name == NULL) + break; + + /* Process the token in name. If it is special, then don't */ + /* translate it. */ + + switch(*name) { + + case '[': + case ']': + case '~': + sprintf(buffer + strlen(buffer), "%s ", name); + break; + + case '%': + + sprintf(buffer + strlen(buffer), "%%"); + + /* don't translate the port type identifier */ + + name = next_name; + next_name = MIFgettok(&s); + + sprintf(buffer + strlen(buffer), "%s ", name); + break; + + default: + + /* must be a node name at this point, so translate it */ + + t = gettrans(name); + if (t) + sprintf(buffer + strlen(buffer), "%s ", t); + else + /* maschmann: changed order + sprintf(buffer + strlen(buffer), "%s:%s ", name, scname); */ + if(name[0]=='v' || name[0]=='V') sprintf(buffer + strlen(buffer), "v:%s:%s ", scname, name+1); + else sprintf(buffer + strlen(buffer), "%s:%s ", scname, name); + + break; + + } /* switch */ + + } /* while */ + + + /* copy in the last token, which is the model name */ + + if(name) + sprintf(buffer + strlen(buffer), "%s ", name); + + /* Set s to null string for compatibility with code */ + /* after switch statement */ + s = ""; - } - (void) strcat(buffer, s); + break; + +/* gtri - end - wbk - 10/23/90 */ +#endif + +/*================ case E, F, G, H ================*/ +/* This section handles controlled sources and allows for SPICE2 POLY attributes. + * This is a new section, added by SDB to handle POLYs in sources. Significant + * changes were made in here. + * 4.21.2003 -- SDB. mailto:sdb@cloud9.net + */ + case 'E': case 'e': + case 'F': case 'f': + case 'G': case 'g': + case 'H': case 'h': + + + s = c->li_line; /* s now holds the SPICE line */ + t = name = gettok(&s); /* name points to the refdes */ + if (!name) + continue; + if (!*name) { + tfree(name); + continue; + } + +/* Here's where we translate the refdes to e.g. F:subcircuitname:57 + * and stick the translated name into buffer. + */ + ch = *name; /* ch identifies the type of component */ + buffer = tmalloc(2000); /* XXXXX */ + name++; + if (*name == ':') + name++; /* now name point to the rest of the refdes */ + + + if (*name) + (void) sprintf(buffer, "%c:%s:%s ", ch, scname, /* F:subcircuitname:refdesname */ + name); + else + (void) sprintf(buffer, "%c:%s ", ch, scname); /* F:subcircuitname */ + tfree(t); + + +/* Next iterate over all nodes (netnames) found and translate them. */ + nnodes = numnodes(c->li_line); + + while (nnodes-- > 0) { + name = gettok(&s); + if (name == NULL) { + fprintf(cp_err, "Error: too few nodes: %s\n", + c->li_line); + goto quit; + } + + /* call gettrans and see if netname was used in the invocation */ + t = gettrans(name); + + if (t) { /* the netname was used during the invocation; print it into the buffer */ + (void) sprintf(buffer + strlen(buffer), "%s ", t); + } + else { /* net netname was not used during the invocation; place a + * translated name into the buffer. + */ + (void) sprintf(buffer + strlen(buffer), + "%s:%s ", scname, name); + } + tfree(name); + } /* while (nnodes-- . . . . */ + + +/* Next we handle the POLY (if any) */ + /* get next token */ + t = s; + next_name = (char *)gettok_noparens(&t); + if ( (strcmp(next_name, "POLY") == 0) || + (strcmp(next_name, "poly") == 0)) { /* found POLY . . . . */ + +#ifdef TRACE + /* SDB debug statement */ + printf("In translate, looking at e, f, g, h found poly\n"); +#endif + + /* move pointer ahead of paren */ + if( get_l_paren(&s) == 1 ) { + fprintf(cp_err, "Error: no left paren after POLY %s\n", + c->li_line); + tfree(next_name); + goto quit; + } + + nametofree = gettok_noparens(&s); + dim = atoi(nametofree); /* convert returned string to int */ + tfree(nametofree); + + /* move pointer ahead of ) */ + if( get_r_paren(&s) == 1 ) { + fprintf(cp_err, "Error: no right paren after POLY %s\n", + c->li_line); + tfree(next_name); + goto quit; + } + + /* Write POLY(dim) into buffer */ + (void) sprintf(buffer + strlen(buffer), + "POLY( %d ) ", dim); + + + } /* if ( (strcmp(next_name, "POLY") == 0) . . . */ + else + dim = 1; /* only one controlling source . . . */ + tfree(next_name); + +/* Now translate the controlling source/nodes */ + nnodes = dim * numdevs(c->li_line); + while (nnodes-- > 0) { + nametofree = name = gettok(&s); /* name points to the returned token */ + if (name == NULL) { + fprintf(cp_err, "Error: too few devs: %s\n", + c->li_line); + goto quit; + } + + if ( (dev_type == 'f') || + (dev_type == 'F') || + (dev_type == 'h') || + (dev_type == 'H') ) { + + /* Handle voltage source name */ + +#ifdef TRACE + /* SDB debug statement */ + printf("In translate, found type f or h\n"); +#endif + + ch = *name; /* ch is the first char of the token. */ + name++; + if (*name == ':') + name++; /* name now points to the remainder of the token */ + (void) sprintf(buffer + strlen(buffer), + "%c:%s:%s ", ch, scname, name); + /* From Vsense and Urefdes creates V:Urefdes:sense */ + } + else { /* Handle netname */ + +#ifdef TRACE + /* SDB debug statement */ + printf("In translate, found type e or g\n"); +#endif + + /* call gettrans and see if netname was used in the invocation */ + t = gettrans(name); + + if (t) { /* the netname was used during the invocation; print it into the buffer */ + (void) sprintf(buffer + strlen(buffer), "%s ", t); + } + else { /* net netname was not used during the invocation; place a + * translated name into the buffer. + */ + (void) sprintf(buffer + strlen(buffer), + "%s:%s ", scname, name); + /* From netname and Urefdes creates Urefdes:netname */ + } + } + tfree(nametofree); + } /* while (nnodes--. . . . */ + +/* Now write out remainder of line (polynomial coeffs) */ + finishLine(buffer + strlen(buffer), s, scname); + s = ""; + break; + + +/*================= Default case ===================*/ + default: /* this section handles ordinary components */ + s = c->li_line; + nametofree = name = gettok(&s); + if (!name) + continue; + if (!*name) { + tfree(name); + continue; + } + +/* Here's where we translate the refdes to e.g. R:subcircuitname:57 + * and stick the translated name into buffer. + */ + ch = *name; + buffer = tmalloc(2000); /* XXXXX */ + name++; + if (*name == ':') + name++; + + if (*name) + (void) sprintf(buffer, "%c:%s:%s ", ch, scname, + name); + else + (void) sprintf(buffer, "%c:%s ", ch, scname); + tfree(nametofree); + + +/* Next iterate over all nodes (netnames) found and translate them. */ + nnodes = numnodes(c->li_line); + + while (nnodes-- > 0) { + name = gettok(&s); + if (name == NULL) { + fprintf(cp_err, "Error: too few nodes: %s\n", + c->li_line); + goto quit; + } + + /* call gettrans and see if netname was used in the invocation */ + t = gettrans(name); + + if (t) { /* the netname was used during the invocation; print it into the buffer */ + (void) sprintf(buffer + strlen(buffer), "%s ", t); + } + else { /* net netname was not used during the invocation; place a + * translated name into the buffer. + */ + (void) sprintf(buffer + strlen(buffer), + "%s:%s ", scname, name); + } + free(name); + } /* while (nnodes-- . . . . */ + +/* Now translate any devices (i.e. controlling sources). + * This may be supurfluous because we handle dependent + * source devices above . . . . + */ + nnodes = numdevs(c->li_line); + while (nnodes-- > 0) { + t = name = gettok(&s); + if (name == NULL) { + fprintf(cp_err, "Error: too few devs: %s\n", + c->li_line); + goto quit; + } + ch = *name; + name++; + if (*name == ':') + name++; + + if (*name) + (void) sprintf(buffer + strlen(buffer), + "%c:%s:%s ", ch, scname, name); + else + (void) sprintf(buffer + strlen(buffer), + "%c:%s ", ch, scname); + tfree(t); + } /* while (nnodes--. . . . */ + + +/* Now we finish off the line. For most components (R, C, etc), + * this involves adding the component value to the buffer. + * We also scan through the line for v(something) and + * i(something)... + */ + finishLine(buffer + strlen(buffer), s, scname); + s = ""; + + } /* switch(c->li_line . . . . */ + + (void) strcat(buffer, s); tfree(c->li_line); c->li_line = copy(buffer); + +#ifdef TRACE + /* SDB debug statement */ + printf("In translate, translated line = %s \n", c->li_line); +#endif + tfree(buffer); + } /* for (c = deck . . . . */ + rtn = 1; +quit: + for (i = 0; ; i++) { + if(!table[i].t_old && !table[i].t_new) + break; + FREE(table[i].t_old); + FREE(table[i].t_new); } - return 1; + return rtn; } + + +/*-------------------------------------------------------------------* + * finishLine now doesn't handle current or voltage sources. + * Therefore, it just writes out the final netnames, if required. + * Changes made by SDB on 4.29.2003. + *-------------------------------------------------------------------*/ static void finishLine(char *dst, char *src, char *scname) { @@ -490,10 +953,10 @@ finishLine(char *dst, char *src, char *scname) if (s) { while (*s) *dst++ = *s++; - } else { + } + else { /* just a normal netname . . . . */ /* - * i(vname) -> i(v:subckt:name) - * i(v:other:name) -> i(v:subckt:other:name) + * */ if (buf[0] == 'v' || buf[0] == 'V') { *dst++ = buf[0]; @@ -538,16 +1001,24 @@ finishLine(char *dst, char *src, char *scname) return; } -static struct tab { - char *t_old; - char *t_new; -} table[512]; /* That had better be enough. */ - +/*------------------------------------------------------------------------------* + * settrans builds the table which holds the old and new netnames. + * it also compares the number of nets present in the .subckt definition against + * the number of nets present in the subcircuit invocation. It returns 0 if they + * match, otherwise, it returns an error. + * + * Variable definitions: + * formal = copy of the .subckt definition line (e.g. ".subckt subcircuitname 1 2 3") (string) + * actual = copy of the .subcircuit invocation line (e.g. "Xexample 4 5 6 subcircuitname") (string) + * subname = copy of the subcircuit name + *------------------------------------------------------------------------------*/ static int settrans(char *formal, char *actual, char *subname) { int i; + bzero(table,sizeof(*table)); + for (i = 0; ; i++) { table[i].t_old = gettok(&formal); table[i].t_new = gettok(&actual); @@ -564,11 +1035,23 @@ settrans(char *formal, char *actual, char *subname) return 0; } + +/*------------------------------------------------------------------------------* + * gettrans returns the name of the top level net if it is in the list, + * otherwise it returns NULL. + *------------------------------------------------------------------------------*/ static char * gettrans(char *name) { int i; +#ifdef XSPICE + /* gtri - wbk - 2/27/91 - don't translate the reserved word 'null' */ + if (eq(name, "null")) + return (name); + /* gtri - end */ +#endif + if (eq(name, "0")) return (name); for (i = 0; table[i].t_old; i++) @@ -577,9 +1060,16 @@ gettrans(char *name) return (NULL); } +/*-------------------------------------------------------------------*/ +/*-------------------------------------------------------------------*/ static int numnodes(char *name) { +/* gtri - comment - wbk - 10/23/90 - Do not modify this routine for */ +/* 'A' type devices since the callers will not know how to find the */ +/* nodes even if they know how many there are. Modify the callers */ +/* instead. */ +/* gtri - end - wbk - 10/23/90 */ char c; struct subs *sss; char *s, *t, buf[4 * BSIZE_SP]; @@ -611,6 +1101,7 @@ numnodes(char *name) } return (sss->su_numargs); } + n = inp_numnodes(c); /* Added this code for variable number of nodes on BSIM3SOI devices */ @@ -621,75 +1112,105 @@ numnodes(char *name) /* I hope that works, this code is very very untested */ - if (c=='m') { /* IF this is a mos */ + if (c=='m') { /* IF this is a mos */ - i = 0; + i = 0; s = buf; gotit = 0; - t = gettok(&s); /* Skip component name */ + txfree(gettok(&s)); /* Skip component name */ while ((i < n) && (*s) && !gotit) { - t = gettok(&s); - for (wl = modnames; wl; wl = wl->wl_next) - if (eq(t, wl->wl_word)) - gotit = 1; - i++; - } + t = gettok(&s); + for (wl = modnames; wl; wl = wl->wl_next) + if (eq(t, wl->wl_word)) + gotit = 1; + i++; + tfree(t); + } /* while . . . . */ - /* Note: node checks must be done on #_of_node-1 because the */ - /* "while" cicle increments the counter even when a model is */ - /* recognized. This code may be better! */ + /* Note: node checks must be done on #_of_node-1 because the */ + /* "while" cicle increments the counter even when a model is */ + /* recognized. This code may be better! */ - if (i < 5) { - fprintf(cp_err, "Error: too few nodes for MOS: %s\n", name); - return(0); - } - return(i-1); /* compesate the unnecessary inrement in the while cicle */ - } + if (i < 5) { + fprintf(cp_err, "Error: too few nodes for MOS: %s\n", name); + return(0); + } + return(i-1); /* compesate the unnecessary inrement in the while cicle */ + } /* if (c=='m' . . . */ if (nobjthack || (c != 'q')) return (n); + for (s = buf, i = 0; *s && (i < 4); i++) - (void) gettok(&s); + txfree(gettok(&s)); + if (i == 3) return (3); + else if (i < 4) { fprintf(cp_err, "Error: too few nodes for BJT: %s\n", name); return (0); } + /* Now, is this a model? */ t = gettok(&s); for (wl = modnames; wl; wl = wl->wl_next) - if (eq(t, wl->wl_word)) - return (3); + if (eq(t, wl->wl_word)) { + tfree(t); + return (3); + } + tfree(t); return (4); } + +/*-------------------------------------------------------------------* + * This function returns the number of controlling voltage sources + * (for F, H) or controlling nodes (for G, E) attached to a dependent + * source. + *-------------------------------------------------------------------*/ static int numdevs(char *s) { - while (*s && isspace(*s)) - s++; - switch (*s) { - case 'K': - case 'k': - return (2); + while (*s && isspace(*s)) + s++; + switch (*s) { + case 'K': + case 'k': + return (2); - case 'F': - case 'f': - case 'H': - case 'h': + /* two nodes per voltage controlled source */ + case 'G': + case 'g': + case 'E': + case 'e': + return(2); + + /* one source per current controlled source */ + case 'F': + case 'f': + case 'H': + case 'h': /* 2 lines here added to fix w bug, NCF 1/31/95 */ - case 'W': - case 'w': - return (1); + case 'W': + case 'w': + return (1); default: return (0); } } +/*----------------------------------------------------------------------* + * modtranslate -- translates .model liness found in subckt definitions. + * Calling arguments are: + * *deck = pointer to the .subckt definition (linked list) + * *subname = pointer to the subcircuit name used at the subcircuit invocation (string) + * Modtranslate returns TRUE if it translated a model name, FALSE + * otherwise. + *----------------------------------------------------------------------*/ static bool modtranslate(struct line *deck, char *subname) { @@ -700,28 +1221,29 @@ modtranslate(struct line *deck, char *subname) (void) strcpy(model, ".model"); gotone = FALSE; - for (c = deck; c; c = c->li_next) { + for (c = deck; c; c = c->li_next) { /* iterate through model def . . . */ if (prefix(model, c->li_line)) { gotone = TRUE; t = c->li_line; - name = gettok(&t); + name = gettok(&t); /* at this point, name = .model */ buffer = tmalloc(strlen(name) + strlen(t) + strlen(subname) + 4); - (void) sprintf(buffer, "%s ",name); - name = gettok(&t); + (void) sprintf(buffer, "%s ",name); /* at this point, buffer = ".model " */ + tfree(name); + name = gettok(&t); /* name now holds model name */ wlsub = alloc(struct wordlist); wlsub->wl_next = submod; if (submod) submod->wl_prev = wlsub; submod = wlsub; wlsub->wl_word = name; - (void) sprintf(buffer + strlen(buffer), "%s:%s ", - subname, name); + (void) sprintf(buffer + strlen(buffer), "%s:%s ", + subname, name); /* buffer = "model subname:modelname " */ (void) strcat(buffer, t); tfree(c->li_line); c->li_line = buffer; t = c->li_line; - (void) gettok(&t); + txfree(gettok(&t)); wl = alloc(struct wordlist); wl->wl_next = modnames; if (modnames) @@ -733,6 +1255,11 @@ modtranslate(struct line *deck, char *subname) return(gotone); } + +/*-------------------------------------------------------------------* + * Devmodtranslate translates ?????? + * + *-------------------------------------------------------------------*/ static void devmodtranslate(struct line *deck, char *subname) { @@ -755,10 +1282,13 @@ devmodtranslate(struct line *deck, char *subname) case 'c': name = gettok(&t); (void) sprintf(buffer,"%s ",name); + tfree(name); name = gettok(&t); (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); name = gettok(&t); (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); if (*t) { name = gettok(&t); @@ -773,6 +1303,7 @@ devmodtranslate(struct line *deck, char *subname) } if (!found) (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); } found = FALSE; @@ -789,6 +1320,7 @@ devmodtranslate(struct line *deck, char *subname) } if (!found) (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); } (void) strcat(buffer, t); @@ -799,10 +1331,13 @@ devmodtranslate(struct line *deck, char *subname) case 'd': name = gettok(&t); (void) sprintf(buffer,"%s ",name); + tfree(name); name = gettok(&t); (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); name = gettok(&t); (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); name = gettok(&t); /* Now, is this a subcircuit model? */ @@ -817,6 +1352,7 @@ devmodtranslate(struct line *deck, char *subname) if (!found) (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); (void) strcat(buffer, t); tfree(s->li_line); s->li_line = buffer; @@ -858,14 +1394,19 @@ devmodtranslate(struct line *deck, char *subname) case 'm': name = gettok(&t); (void) sprintf(buffer,"%s ",name); + tfree(name); name = gettok(&t); (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); name = gettok(&t); (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); name = gettok(&t); (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); name = gettok(&t); (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); name = gettok(&t); /* Now, is this a subcircuit model? */ @@ -883,17 +1424,22 @@ devmodtranslate(struct line *deck, char *subname) (void) strcat(buffer, t); tfree(s->li_line); s->li_line = buffer; + tfree(name); break; case 'q': name = gettok(&t); (void) sprintf(buffer,"%s ",name); + tfree(name); name = gettok(&t); (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); name = gettok(&t); (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); name = gettok(&t); (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); name = gettok(&t); /* Now, is this a subcircuit model? */ @@ -907,6 +1453,7 @@ devmodtranslate(struct line *deck, char *subname) } if (!found) (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); found = FALSE; if (*t) { @@ -922,6 +1469,7 @@ devmodtranslate(struct line *deck, char *subname) } if (!found) (void) sprintf(buffer + strlen(buffer), "%s ", name); + tfree(name); } (void) strcat(buffer, t); @@ -937,11 +1485,13 @@ devmodtranslate(struct line *deck, char *subname) return; } -/* This is a spice-dependent thing. It should probably go somewhere +/*----------------------------------------------------------------------* + * inp_numnodes returns the number of nodes (netnames) attached to the + * component. + * This is a spice-dependent thing. It should probably go somewhere * else, but... Note that we pretend that dependent sources and mutual * inductors have more nodes than they really do... - */ - + *----------------------------------------------------------------------*/ int inp_numnodes(char c) { @@ -958,9 +1508,9 @@ inp_numnodes(char c) case 'b': return (2); case 'c': return (2); case 'd': return (2); - case 'e': return (4); + case 'e': return (2); /* changed from 4 to 2 by SDB on 4.22.2003 to enable POLY */ case 'f': return (2); - case 'g': return (4); + case 'g': return (2); /* changed from 4 to 2 by SDB on 4.22.2003 to enable POLY */ case 'h': return (2); case 'i': return (2); case 'j': return (3); @@ -984,3 +1534,10 @@ inp_numnodes(char c) } } + + + + + + + diff --git a/src/frontend/variable.c b/src/frontend/variable.c index 8a0fbc8e2..706bd504a 100644 --- a/src/frontend/variable.c +++ b/src/frontend/variable.c @@ -216,9 +216,20 @@ cp_vset(char *varname, char type, char *value) v->va_next = ft_curckt->ci_vars; ft_curckt->ci_vars = v; } else { + /* va: avoid memory leak within bcopy */ + if (u->va_type==VT_STRING) tfree(u->va_string); + else if (u->va_type==VT_LIST) tfree(u->va_vlist); + u->va_V = v->va_V; + /* va_name is the same string */ + u->va_type = v->va_type; + /* va_next left unchanged */ + tfree(v->va_name); + tfree(v); +/* va: old version with memory leaks w = u->va_next; bcopy(v, u, sizeof(*u)); u->va_next = w; +*/ } } break; @@ -241,13 +252,15 @@ cp_vset(char *varname, char type, char *value) struct variable * cp_setparse(wordlist *wl) { - char *name, *val, *copyval, *s, *ss; + char *name=NULL, *val, *copyval, *s, *ss; double *td; struct variable *listv = NULL, *vv, *lv = NULL; struct variable *vars = NULL; int balance; while (wl) { + if(name) + tfree(name); name = cp_unquote(wl->wl_word); wl = wl->wl_next; if (((wl == NULL) || (*wl->wl_word != '=')) && @@ -330,6 +343,7 @@ cp_setparse(wordlist *wl) } if (balance && !wl) { fprintf(cp_err, "Error: bad set form.\n"); + tfree(name); /* va: cp_unquote memory leak: free name before exiting */ return (NULL); } @@ -359,7 +373,10 @@ cp_setparse(wordlist *wl) vv->va_string = copy(val); } tfree(copyval);/*DG: must free ss any way to avoid cp_unquote memory leak */ + tfree(name); /* va: cp_unquote memory leak: free name for every loop */ } + if(name) + tfree(name); return (vars); } diff --git a/src/frontend/vectors.c b/src/frontend/vectors.c index 1deecf6a9..37dd4db53 100644 --- a/src/frontend/vectors.c +++ b/src/frontend/vectors.c @@ -19,6 +19,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "vectors.h" #include "plotting/plotting.h" +#ifdef XSPICE +/* gtri - begin - add function prototype for EVTfindvec */ +struct dvec *EVTfindvec(char *node); +/* gtri - end - add function prototype for EVTfindvec */ +#endif /* Find a named vector in a plot. We are careful to copy the vector if * v_link2 is set, because otherwise we will get screwed up. */ @@ -58,6 +63,14 @@ findvec(char *word, struct plot *pl) if (cieq(buf, d->v_name) && (d->v_flags & VF_PERMANENT)) break; } +#ifdef XSPICE +/* gtri - begin - Add processing for getting event-driven vector */ + + if(!d) + d = EVTfindvec(word); + +/* gtri - end - Add processing for getting event-driven vector */ +#endif if (d && d->v_link2) { d = vec_copy(d); vec_new(d); @@ -341,11 +354,9 @@ vec_get(char *word) d = newv; if (!d) { fprintf(cp_err, - "Error: plot wildcard (name %s) matches nothing\n", + "Error: plot wildcard (name %s) matches nothing\n", word); - - /* MW. I don't want core leaks here */ - tfree(wd); + tfree(wd); /* MW. I don't want core leaks here */ return (NULL); } } @@ -354,13 +365,12 @@ vec_get(char *word) /* This is a special quantity... */ if (ft_nutmeg) { fprintf(cp_err, - "Error: circuit parameters only available with spice\n"); - - tfree(wd); /* MW. Memory leak fixed again */ - return (FALSE); + "Error: circuit parameters only available with spice\n"); + tfree(wd); /* MW. Memory leak fixed again */ + return (NULL); /* va: use NULL */ } - whole=copy(word); + whole=copy(word); name = ++word; for (param = name; *param && (*param != '['); param++) ; @@ -398,10 +408,11 @@ vec_get(char *word) d->v_length = 1; *d->v_realdata = vv->va_real; + tfree(vv->va_name); + tfree(vv); /* va: tfree vv->va_name and vv (avoid memory leakages) */ tfree(wd); vec_new(d); tfree(whole); - tfree(wd); return (d); } @@ -504,9 +515,11 @@ plot_alloc(char *name) } while (tp); pl->pl_typename = copy(buf); cp_addkword(CT_PLOT, buf); + /* va: create a new, empty keyword tree for class CT_VECTOR, s=old tree */ s = cp_kwswitch(CT_VECTOR, (char *) NULL); cp_addkword(CT_VECTOR, "all"); pl->pl_ccom = cp_kwswitch(CT_VECTOR, s); + /* va: keyword tree is old tree again, new tree is linked to pl->pl_ccom */ return (pl); } @@ -587,8 +600,7 @@ vec_free(struct dvec *v) pl = v->v_plot; /* Now we have to take this dvec out of the plot list. */ - if (pl == NULL) - fprintf(cp_err, "vec_free: Internal Error: plot ptr is 0\n"); + if (pl != NULL) { if (pl->pl_dvecs == v) pl->pl_dvecs = v->v_next; else { @@ -607,12 +619,15 @@ vec_free(struct dvec *v) else pl->pl_scale = NULL; } + } tfree(v->v_name); + if(v->v_length) { if (isreal(v)) { tfree(v->v_realdata); } else { tfree(v->v_compdata); } + } tfree(v); return; } @@ -625,6 +640,7 @@ bool vec_eq(struct dvec *v1, struct dvec *v2) { char *s1, *s2; + bool rtn; if (v1->v_plot != v2->v_plot) return (FALSE); @@ -633,9 +649,13 @@ vec_eq(struct dvec *v1, struct dvec *v2) s2 = vec_basename(v2); if (cieq(s1, s2)) - return (TRUE); + rtn = TRUE; else - return (FALSE); + rtn = FALSE; + + tfree(s1); + tfree(s2); + return rtn; } /* Return the name of the vector with the plot prefix stripped off. This @@ -677,6 +697,8 @@ vec_basename(struct dvec *v) /* Make a plot the current one. This gets called by cp_usrset() when one * does a 'set curplot = name'. + * va: ATTENTION: has unlinked old keyword-class-tree from keywords[CT_VECTOR] + * (potentially memory leak) */ void @@ -700,8 +722,15 @@ plot_setcur(char *name) fprintf(cp_err, "Error: no such plot named %s\n", name); return; } +/* va: we skip cp_kwswitch, because it confuses the keyword-tree management for + * repeated op-commands. When however cp_kwswitch is necessary for other + * reasons, we should hold the original keyword table pointer in an + * permanent variable, since it will lost here, and can never tfree'd. if (plot_cur) + { plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom); + } +*/ plot_cur = pl; return; } diff --git a/src/include/ChangeLog b/src/include/ChangeLog index eff6e1a0b..144d094d3 100644 --- a/src/include/ChangeLog +++ b/src/include/ChangeLog @@ -1,3 +1,6 @@ +2003.4.10 Stuart Brorson + * Added declaration for INPgetNetTok to inpdefs.h + 2002-01-03 Paolo Nenzi * wstdio.h: Standard input/output for Windows (Holger Vogt patch). diff --git a/src/include/cktdefs.h b/src/include/cktdefs.h index 30554cc52..4439ccfe2 100644 --- a/src/include/cktdefs.h +++ b/src/include/cktdefs.h @@ -6,6 +6,14 @@ #ifndef CKT #define CKT "CKTdefs.h $Revision$ on $Date$ " +/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */ +#ifdef XSPICE +#include "evt.h" +#include "enh.h" +#endif +/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */ + + #define MAXNUMDEVS 40 /* Max number of possible devices PN:XXX may cause toubles*/ extern int DEVmaxnum; /* Not sure if still used */ #define MAXNUMDEVNODES 4 /* Max No. of nodes per device */ @@ -247,6 +255,13 @@ typedef struct { int CKTtroubleNode; /* Non-convergent node number */ GENinstance *CKTtroubleElt; /* Non-convergent device instance */ +/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */ +#ifdef XSPICE + Evt_Ckt_Data_t *evt; /* all data about event driven stuff */ + Enh_Ckt_Data_t *enh; /* data used by general enhancements */ +#endif +/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */ + } CKTcircuit; /* Now function prottypes */ @@ -271,6 +286,7 @@ extern int CKTdestroy( void *); extern int CKTdltAnal( void *, void *, void *); extern int CKTdltInst( void *, void *); extern int CKTdltMod( void *, void *); +extern int CKTdltNNum(void *, int ); extern int CKTdltNod( void *, void *); extern int CKTdoJob( void *, int , void *); extern void CKTdump( CKTcircuit *, double, void *); @@ -333,7 +349,7 @@ extern int DCOaskQuest( CKTcircuit *, void *, int , IFvalue *); extern int DCOsetParm( CKTcircuit *, void *, int , IFvalue *); extern int DCTaskQuest( CKTcircuit *, void *, int , IFvalue *); extern int DCTsetParm( CKTcircuit *, void *, int , IFvalue *); -extern int DCop( CKTcircuit *); +extern int DCop( CKTcircuit *, int ); /* va: int avoids "init from incompatible pointer type" */ extern int DCtrCurv( CKTcircuit *, int ); extern int DCtran( CKTcircuit *, int ); extern int DISTOan(CKTcircuit *, int); diff --git a/src/include/fteinp.h b/src/include/fteinp.h index 0efc28c43..22eabc40c 100644 --- a/src/include/fteinp.h +++ b/src/include/fteinp.h @@ -13,6 +13,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "inpdefs.h" +/* This struct defines a linked list of lines from a SPICE file. */ struct line { int li_linenum; char *li_line; diff --git a/src/include/ifsim.h b/src/include/ifsim.h index c1fa00b3b..6121b1dcd 100644 --- a/src/include/ifsim.h +++ b/src/include/ifsim.h @@ -6,6 +6,13 @@ Author: 1986 Thomas L. Quarles #ifndef IFSIMULATOR #define IFSIMULATOR +/* gtri - add - wbk - 10/11/90 - for structs referenced in IFdevice */ +#ifdef XSPICE +#include "mifparse.h" +#include "mifcmdat.h" +#endif +/* gtri - end - wbk - 10/11/90 */ + /* * structure: IFparm @@ -269,6 +276,21 @@ typedef struct sIFdevice { int *numModelParms; /* number of model parameter descriptors */ IFparm *modelParms; /* array of model parameter descriptors */ +/* gtri - modify - wbk - 10/11/90 - add entries to hold data required */ +/* by new parser */ +#ifdef XSPICE + void ((*cm_func)(Mif_Private_t *)); /* pointer to code model function */ + + int num_conn; /* number of code model connections */ + Mif_Conn_Info_t *conn; /* array of connection info for mif parser */ + + int num_param; /* number of parameters = numModelParms */ + Mif_Param_Info_t *param; /* array of parameter info for mif parser */ + + int num_inst_var; /* number of instance vars = numInstanceParms */ + Mif_Inst_Var_Info_t *inst_var; /* array of instance var info for mif parser */ +/* gtri - end - wbk - 10/11/90 */ +#endif int flags; /* DEV_ */ } IFdevice; diff --git a/src/include/inpdefs.h b/src/include/inpdefs.h index c739a8699..232e5b908 100644 --- a/src/include/inpdefs.h +++ b/src/include/inpdefs.h @@ -74,6 +74,11 @@ typedef struct sINPmodel{ void *INPmodfast; /* high speed pointer to model for access */ } INPmodel; + +/* global input model table. */ +extern INPmodel *modtab; + + /* listing types - used for debug listings */ #define LOGICAL 1 #define PHYSICAL 2 @@ -93,6 +98,7 @@ double INPevaluate(char**,int*,int); char * INPfindLev(char*,int*); char * INPgetMod(void*,char*,INPmodel**,INPtables*); int INPgetTok(char**,char**,int); +int INPgetNetTok(char**,char**,int); void INPgetTree(char**,INPparseTree**,void*,INPtables*); IFvalue * INPgetValue(void*,char**,int,INPtables*); int INPgndInsert(void*,char**,INPtables*,void**); @@ -123,6 +129,7 @@ void INP2K(void*,INPtables*,card*); void INP2L(void*,INPtables*,card*); void INP2M(void*,INPtables*,card*); void INP2O(void*,INPtables*,card*); +void INP2P(void*,INPtables*,card*); void INP2Q(void*,INPtables*,card*,void*); void INP2R(void*,INPtables*,card*); void INP2S(void*,INPtables*,card*); @@ -130,6 +137,7 @@ void INP2T(void*,INPtables*,card*); void INP2U(void*,INPtables*,card*); void INP2V(void*,INPtables*,card*); void INP2W(void*,INPtables*,card*); +void INP2Y(void*,INPtables*,card*); void INP2Z(void*,INPtables*,card*); int INP2dot(void*,INPtables*,card*,void*,void*); INPtables *INPtabInit(int); diff --git a/src/include/memory.h b/src/include/memory.h index 2453b1b36..5bfe00ee5 100644 --- a/src/include/memory.h +++ b/src/include/memory.h @@ -17,6 +17,8 @@ extern void txfree(void *ptr); #define txfree(m) #endif +#include "../misc/stringutil.h" /* va: spice3 internally bzero */ + #define alloc(TYPE) ((TYPE *) tmalloc(sizeof(TYPE))) #define MALLOC(x) tmalloc((unsigned)(x)) #define FREE(x) {if (x) {txfree((char *)(x));(x) = 0;}} diff --git a/src/include/ngspice.h b/src/include/ngspice.h index b34250dfb..ddbddc8b0 100644 --- a/src/include/ngspice.h +++ b/src/include/ngspice.h @@ -2,6 +2,12 @@ * Main header file for ngspice * 1999 E. Rouat ************/ +#ifndef NGSPICE_H_INCLUDED /* va */ +#define NGSPICE_H_INCLUDED + +/* #include "memwatch.h" + #define MEMWATCH */ + /* * This file will eventually replace spice.h and lots of other @@ -97,6 +103,11 @@ struct timeb timebegin; #ifdef HAVE_INDEX # define strchr index # define strrchr rindex +#else /* va: no index, but strchr */ + #ifdef HAVE_STRCHR + #define index strchr + #define rindex strrchr + #endif /* va: no index, but strchr */ #endif #ifdef HAS_TIME_ @@ -113,6 +124,9 @@ struct timeb timebegin; #endif extern char *gettok(char **s); +extern char *gettok_noparens(char **s); +extern int get_l_paren(char **s); +extern int get_r_paren(char **s); extern void appendc(char *s, char c); extern int scannum(char *str); extern int ciprefix(register char *p, register char *s); @@ -152,3 +166,5 @@ extern char *Lib_Path; extern int ARCHme; /* My logical process number */ extern int ARCHsize; /* Total number of processes */ + +#endif /* NGSPICE_H_INCLUDED */ diff --git a/src/include/optdefs.h b/src/include/optdefs.h index 0b83067ff..5df48e853 100644 --- a/src/include/optdefs.h +++ b/src/include/optdefs.h @@ -116,4 +116,18 @@ typedef struct { #define OPT_ABSDV 66 /* Original: 51 (Node_Damping) */ #define OPT_RELDV 67 /* Original: 52 (Node_Damping) */ +#ifdef XSPICE +/* gtri - begin - wbk - add new options */ +#define OPT_ENH_NOOPALTER 100 +#define OPT_ENH_RAMPTIME 101 +#define OPT_EVT_MAX_EVT_PASSES 102 +#define OPT_EVT_MAX_OP_ALTER 103 +#define OPT_ENH_CONV_LIMIT 104 +#define OPT_ENH_CONV_ABS_STEP 105 +#define OPT_ENH_CONV_STEP 106 +#define OPT_MIF_AUTO_PARTIAL 107 +#define OPT_ENH_RSHUNT 108 +/* gtri - end - wbk - add new options */ +#endif + #endif /*OPT*/ diff --git a/src/main.c b/src/main.c index 12893fb55..9ee4a72b2 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,9 @@ #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ +#ifdef __MINGW32__ +#define srandom(a) srand(a) /* srandom */ +#endif /* __MINGW32__ */ #include #include @@ -23,11 +26,17 @@ #include #include #include -#if !defined(__CYGWIN__) #include -#endif #include #include +#include "frontend/display.h" /* va */ + +/* saj xspice headers */ +#ifdef XSPICE +#include "ipctiein.h" +#include "mif.h" +#include "enh.h" +#endif #ifdef HAVE_PWD_H #include @@ -39,6 +48,8 @@ #endif #endif +extern void DevInit(void); + /* Main options */ static bool ft_servermode = FALSE; static bool ft_batchmode = FALSE; @@ -151,6 +162,40 @@ if_getstat(char *n, char *c) return (NULL); } +#ifdef EXPERIMENTAL_CODE +void com_loadsnap(wordlist *wl) { return; } +void com_savesnap(wordlist *wl) { return; } +#endif + + +#ifdef XSPICE +/* saj to get nutmeg to compile, not nice but necessary */ +Ipc_Tiein_t g_ipc; +Ipc_Status_t ipc_send_errchk(void ) { + Ipc_Status_t x=0; + return(x); +} +Ipc_Status_t ipc_get_line(char *str , int *len , Ipc_Wait_t wait ){ + Ipc_Status_t x=0; + return(x); +} +struct line *ENHtranslate_poly(struct line *deck){ + return(NULL); +} +int load_opus(char *name){ + return(1); +} +char *MIFgettok(char **s){ + return(NULL); +} +void EVTprint(wordlist *wl){ + return; +} +struct dvec *EVTfindvec(char *node){ + return NULL; +} +#endif + #endif /* SIMULATOR */ char *hlp_filelist[] = { "ngspice", 0 }; @@ -173,7 +218,9 @@ int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator) SIMinfo.numDevices = DEVmaxnum = num_devices(); SIMinfo.devices = devices_ptr(); SIMinfo.numAnalyses = spice_num_analysis(); - SIMinfo.analyses = spice_analysis_ptr(); + SIMinfo.analyses = (IFanalysis **)spice_analysis_ptr(); /* va: we recast, because we use + * only the public part + */ #endif /* SIMULATOR */ SPfrontEnd = frontEnd; @@ -227,11 +274,11 @@ show_version(void) { printf("%s compiled from %s revision %s\n" "Written originally by Berkeley University\n" - "Currently maintained by the NG-Spice Project\n\n" + "Currently maintained by the NGSpice Project\n\n" "Copyright (C) 1985-1996," " The Regents of the University of California\n" "Copyright (C) 1999-2000," - " The NG-Spice Project\n", cp_program, PACKAGE, VERSION); + " The NGSpice Project\n", cp_program, PACKAGE, VERSION); } void @@ -292,6 +339,17 @@ main(int argc, char **argv) FILE *fp; FILE *circuit_file; +#ifdef TRACE + /* this is used to detect memory leaks during debugging */ + /* added by SDB during debug . . . . */ + /* mtrace(); */ +#endif + +#ifdef TRACE + /* this is also used for memory leak plugging . . . */ + /* added by SDB during debug . . . . */ + /* mwDoFlush(1); */ +#endif /* MFB tends to jump to 0 on errors. This tends to catch it. */ if (started) { @@ -408,11 +466,12 @@ main(int argc, char **argv) #else sprintf (buf, "%s", optarg); #endif -/* if (!(freopen (buf, "w", stdout))) { +#ifdef HAS_WINDOWS + if (!(freopen (buf, "w", stdout))) { perror (buf); shutdown (EXIT_BAD); } -*/ +#endif // *** Log-File öffnen ******* if (!(flogp = fopen(buf, "w"))) { perror(buf); @@ -422,7 +481,7 @@ main(int argc, char **argv) com_version(NULL); // hvogt 11.11.2001 fprintf(stdout, "\nBatch mode\n\n"); fprintf(stdout, "Simulation output goes to rawfile: %s\n\n", ft_rawfile); - fprintf(stdout, "Comments and warnigs go to log-file: %s\n", buf); + fprintf(stdout, "Comments and warnings go to log-file: %s\n", buf); oflag = TRUE; } break; @@ -507,7 +566,9 @@ main(int argc, char **argv) signal(SIGBUS, sigbus); #endif #ifdef SIGSEGV - signal(SIGSEGV, sigsegv); +/* Want core files! + * signal(SIGSEGV, sigsegv); + */ #endif #ifdef SIGSYS signal(SIGSYS, sig_sys); @@ -525,14 +586,11 @@ main(int argc, char **argv) pw = getpwuid(getuid()); -#ifdef HAVE_ASPRINTF - asprintf(&s, "%s/.spiceinit", pw->pw_dir); -#else /* ~ HAVE_ASPRINTF */ #define INITSTR "/.spiceinit" -if ( (s=(char *) malloc(1 + strlen(pw->pw_dir)+strlen(INITSTR))) == NULL){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } +#ifdef HAVE_ASPRINTF + asprintf(&s, "%s%s", pw->pw_dir,INITSTR); +#else /* ~ HAVE_ASPRINTF */ /* va: we use tmalloc */ + s=(char *) tmalloc(1 + strlen(pw->pw_dir)+strlen(INITSTR)); sprintf(s,"%s%s",pw->pw_dir,INITSTR); #endif /* HAVE_ASPRINTF */ @@ -648,7 +706,7 @@ evl: * save too much. */ cp_interactive = FALSE; if (rflag) { - ft_dotsaves(); + /* saj done already in inp_spsource ft_dotsaves();*/ error2 = ft_dorun(ft_rawfile); if (ft_cktcoms(TRUE) || error2) shutdown(EXIT_BAD); diff --git a/src/maths/ni/niiter.c b/src/maths/ni/niiter.c index cbe4b63c9..2f57fb5e9 100644 --- a/src/maths/ni/niiter.c +++ b/src/maths/ni/niiter.c @@ -38,7 +38,7 @@ NIiter(register CKTcircuit *ckt, int maxIter) CKTnode *node; /* current matrix entry */ - double diff, maxdiff, damp_factor, *OldCKTstate0; + double diff, maxdiff, damp_factor, *OldCKTstate0=NULL; iterno=0; ipass=0; @@ -157,7 +157,10 @@ NIiter(register CKTcircuit *ckt, int maxIter) return(error); } } - + /*moved it to here as if xspice is included then CKTload changes + CKTnumStates the first time it is run */ + if(!OldCKTstate0) + OldCKTstate0=(double *)MALLOC((ckt->CKTnumStates+1)*sizeof(double)); for(i=0;iCKTnumStates;i++) { *(OldCKTstate0+i) = *(ckt->CKTstate0+i); }; diff --git a/src/misc/ivars.c b/src/misc/ivars.c index 858ed3d33..e6fc50d6a 100644 --- a/src/misc/ivars.c +++ b/src/misc/ivars.c @@ -40,21 +40,15 @@ mkvar(char **p, char *path_prefix, char *var_dir, char *env_var) asprintf(p, "%s", buffer); else asprintf(p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir); -#else /* ~ HAVE_ASPRINTF */ +#else /* ~ HAVE_ASPRINTF */ /* va: we use tmalloc */ if (buffer){ - if ( (*p = (char *) malloc(strlen(buffer)+1)) == NULL){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } + *p = (char *) tmalloc(strlen(buffer)+1); sprintf(*p,"%s",buffer); /* asprintf(p, "%s", buffer); */ } else{ - if ( (*p = (char *) malloc(strlen(path_prefix) + - strlen(DIR_PATHSEP) + strlen(var_dir) + 1)) == NULL){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } + *p = (char *) tmalloc(strlen(path_prefix) + + strlen(DIR_PATHSEP) + strlen(var_dir) + 1); sprintf(*p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir); /* asprintf(p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir); */ } @@ -89,9 +83,9 @@ ivars(void) void cleanvars(void) { - free(News_File); - free(Default_MFB_Cap); - free(Help_Path); - free(Lib_Path); - free(Spice_Path); + tfree(News_File); + tfree(Default_MFB_Cap); + tfree(Help_Path); + tfree(Lib_Path); + tfree(Spice_Path); } diff --git a/src/misc/string.c b/src/misc/string.c index e0c9a7642..d0a6c34c1 100644 --- a/src/misc/string.c +++ b/src/misc/string.c @@ -159,14 +159,86 @@ gettok(char **s) return (copy(buf)); } +/*-------------------------------------------------------------------------* + * gettok_noparens was added by SDB on 4.21.2003. + * It acts like gettok, except that it stops parsing when it hits a paren + * (i.e. it treats parens like whitespace). It is used in translate (subckt.c) + * while looking for the POLY token. + *-------------------------------------------------------------------------*/ +char * +gettok_noparens(char **s) +{ + char buf[BSIZE_SP]; + int i = 0; + char c; + + while (isspace(**s)) + (*s)++; + if (!**s) + return (NULL); + while ((c = **s) && !isspace(c) && + ( **s != '(' ) && ( **s != ')' ) ) { + buf[i++] = *(*s)++; + } + buf[i] = '\0'; + while (isspace(**s)) + (*s)++; + return (copy(buf)); +} + +/*-------------------------------------------------------------------------* + * get_l_paren iterates the pointer forward in a string until it hits + * the position after the next left paren "(". It returns 0 if it found a left + * paren, and 1 if no left paren is found. + *-------------------------------------------------------------------------*/ +int +get_l_paren(char **s) +{ + while (**s && ( **s != '(' ) ) + (*s)++; + if (!**s) + return (1); + + (*s)++; + + if (!**s) + return (1); + else + return 0; +} + + +/*-------------------------------------------------------------------------* + * get_r_paren iterates the pointer forward in a string until it hits + * the position after the next right paren ")". It returns 0 if it found a right + * paren, and 1 if no right paren is found. + *-------------------------------------------------------------------------*/ +int +get_r_paren(char **s) +{ + while (**s && ( **s != ')' ) ) + (*s)++; + if (!**s) + return (1); + + (*s)++; + + if (!**s) + return (1); + else + return 0; +} + #ifndef HAVE_BCOPY #ifndef bcopy void -bcopy(register char *from, register char *to, register int num) +bcopy(const void *vfrom, void *vto, size_t num) { + register const char *from = vfrom; + register char *to = vto; while (num-- > 0) *to++ = *from++; return; @@ -176,12 +248,13 @@ bcopy(register char *from, register char *to, register int num) #ifndef bzero /* can't declare void here, because we've already used it in this file */ /* and haven't declared it void before the use */ -int -bzero(register char *ptr, register int num) +void +bzero(void *vptr, size_t num) { + register char *ptr=vptr; while (num-- > 0) *ptr++ = '\0'; - return (0); + return; } #endif diff --git a/src/misc/stringutil.h b/src/misc/stringutil.h index 350c2fdd3..c41ac754b 100644 --- a/src/misc/stringutil.h +++ b/src/misc/stringutil.h @@ -25,8 +25,8 @@ char * rindex(register char *s,register char c ); #ifndef HAVE_BCOPY -void bcopy(register char *from, register char *to, register int num); -int bzero(register char *ptr, register int num); +void bcopy(const void *from, void *to, size_t num); +void bzero(void *ptr, size_t num); #endif /* HAVE_BCOPY */ diff --git a/src/spicelib/analysis/Makefile.am b/src/spicelib/analysis/Makefile.am index 8a99d9591..9162a819b 100644 --- a/src/spicelib/analysis/Makefile.am +++ b/src/spicelib/analysis/Makefile.am @@ -96,6 +96,7 @@ libckt_a_SOURCES = \ tranaskq.c \ traninit.c \ transetp.c \ + cluster.c \ ckt.h diff --git a/src/spicelib/analysis/acan.c b/src/spicelib/analysis/acan.c index 1ee8720a2..809c5eb2b 100644 --- a/src/spicelib/analysis/acan.c +++ b/src/spicelib/analysis/acan.c @@ -11,6 +11,13 @@ Modified 2001: AlansFixes #include "devdefs.h" #include "sperror.h" +#ifdef XSPICE +/* gtri - add - wbk - 12/19/90 - Add headers */ +#include "mif.h" +#include "evtproto.h" +#include "ipctiein.h" +/* gtri - end - wbk */ + #ifdef HAS_WINDOWS void SetAnalyse( char * Analyse, int Percent); #endif @@ -30,10 +37,22 @@ ACan(CKTcircuit *ckt, int restart) double startTime; int error; int numNames; - IFuid *nameList; + IFuid *nameList; /* va: tmalloc'ed list of names */ IFuid freqUid; - static void *acPlot; - void *plot; + static void *acPlot = NULL; + void *plot = NULL; + +/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */ +#ifdef XSPICE + /* Tell the beginPlot routine what mode we're in */ + g_ipc.anal_type = IPC_ANAL_AC; + + /* Tell the code models what mode we're in */ + g_mif_info.circuit.anal_type = MIF_DC; + + g_mif_info.circuit.anal_init = MIF_TRUE; +#endif +/* gtri - end - wbk */ if(((ACAN*)ckt->CKTcurJob)->ACsaveFreq == 0 || restart) { /* start at beginning */ @@ -66,6 +85,30 @@ ACan(CKTcircuit *ckt, int restart) default: return(E_BADPARM); } +#ifdef XSPICE +/* gtri - begin - wbk - Call EVTop if event-driven instances exist */ + if(ckt->evt->counts.num_insts == 0) { + /* If no event-driven instances, do what SPICE normally does */ + error = CKTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter); + if(error) return(error); + } + else { + /* Else, use new DCOP algorithm */ + error = EVTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter, + MIF_TRUE); + EVTdump(ckt, IPC_ANAL_DCOP, 0.0); + EVTop_save(ckt, MIF_TRUE, 0.0); + if(error) + return(error); + } +/* gtri - end - wbk - Call EVTop if event-driven instances exist */ +#else error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, @@ -75,7 +118,36 @@ ACan(CKTcircuit *ckt, int restart) CKTncDump(ckt); return(error); } +#endif + +#ifdef XSPICE +/* gtri - add - wbk - 12/19/90 - Add IPC stuff */ + /* Send the operating point results for Mspice compatibility */ + if(g_ipc.enabled) + { + /* Call CKTnames to get names of nodes/branches used by BeginPlot */ + /* Probably should free nameList after this block since called again... */ + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + + /* We have to do a beginPlot here since the data to return is */ + /* different for the DCOP than it is for the AC analysis. Moreover */ + /* the begin plot has not even been done yet at this point... */ + (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,(void*)ckt->CKTcurJob, + ckt->CKTcurJob->JOBname,(IFuid)NULL,IF_REAL,numNames,nameList, + IF_REAL,&acPlot); + tfree(nameList); + + ipc_send_dcop_prefix(); + CKTdump(ckt,(double)0,acPlot); + ipc_send_dcop_suffix(); + + (*(SPfrontEnd->OUTendPlot))(acPlot); + } + +/* gtri - end - wbk */ +#endif ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG; error = CKTload(ckt); if(error) return(error); @@ -91,6 +163,7 @@ ACan(CKTcircuit *ckt, int restart) if(error) return(error); CKTdump(ckt,(double)0,plot); (*(SPfrontEnd->OUTendPlot))(plot); + plot = NULL; } (*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL, @@ -99,6 +172,7 @@ ACan(CKTcircuit *ckt, int restart) (void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList, IF_COMPLEX,&acPlot); + tfree(nameList); if(error) return(error); if (((ACAN*)ckt->CKTcurJob)->ACstepType != LINEAR) { @@ -110,7 +184,14 @@ ACan(CKTcircuit *ckt, int restart) } else { /* continue previous analysis */ freq = ((ACAN*)ckt->CKTcurJob)->ACsaveFreq; ((ACAN*)ckt->CKTcurJob)->ACsaveFreq = 0; /* clear the 'old' frequency */ + /* fix resume? saj*/ + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, + ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList, + IF_COMPLEX,&acPlot); + /* saj*/ } + switch(((ACAN*)ckt->CKTcurJob)->ACstepType) { case DECADE: case OCTAVE: @@ -124,6 +205,15 @@ ACan(CKTcircuit *ckt, int restart) return(E_BADPARM); } +/* gtri - add - wbk - 12/19/90 - Set anal_init and anal_type */ +#ifdef XSPICE + g_mif_info.circuit.anal_init = MIF_TRUE; + + /* Tell the code models what mode we're in */ + g_mif_info.circuit.anal_type = MIF_AC; +#endif +/* gtri - end - wbk */ + startTime = SPfrontEnd->IFseconds(); startdTime = ckt->CKTstat->STATdecompTime; startsTime = ckt->CKTstat->STATsolveTime; @@ -177,8 +267,20 @@ ACan(CKTcircuit *ckt, int restart) ckt->CKTsenInfo->SENmode = save1; } #endif +/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ +#ifdef XSPICE + if(g_ipc.enabled) + ipc_send_data_prefix(freq); error = CKTacDump(ckt,freq,acPlot); + + if(g_ipc.enabled) + ipc_send_data_suffix(); + +/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ +#else + error = CKTacDump(ckt,freq,acPlot); +#endif if (error) { ckt->CKTcurrentAnalysis = DOING_AC; ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime; @@ -239,6 +341,7 @@ ACan(CKTcircuit *ckt, int restart) } endsweep: (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot = NULL; ckt->CKTcurrentAnalysis = 0; ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime; ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime - @@ -265,7 +368,7 @@ endsweep: int CKTacLoad(CKTcircuit *ckt) { - extern SPICEdev *DEVices[]; + extern SPICEdev **DEVices; int i; int size; int error; @@ -292,6 +395,35 @@ CKTacLoad(CKTcircuit *ckt) #endif /* PARALLEL_ARCH */ } } + +#ifdef XSPICE + /* gtri - begin - Put resistors to ground at all nodes. */ + /* Value of resistor is set by new "rshunt" option. */ + + if(ckt->enh->rshunt_data.enabled) { + for(i = 0; i < ckt->enh->rshunt_data.num_nodes; i++) { + *(ckt->enh->rshunt_data.diag[i]) += + ckt->enh->rshunt_data.gshunt; + } + } + + /* gtri - end - Put resistors to ground at all nodes */ + + + + /* gtri - add - wbk - 11/26/90 - reset the MIF init flags */ + + /* init is set by CKTinit and should be true only for first load call */ + g_mif_info.circuit.init = MIF_FALSE; + + /* anal_init is set by CKTdoJob and is true for first call */ + /* of a particular analysis type */ + g_mif_info.circuit.anal_init = MIF_FALSE; + + /* gtri - end - wbk - 11/26/90 */ +#endif + + #ifdef PARALLEL_ARCH combine: ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime; diff --git a/src/spicelib/analysis/ckt.h b/src/spicelib/analysis/ckt.h index 301002e9e..013dacedf 100644 --- a/src/spicelib/analysis/ckt.h +++ b/src/spicelib/analysis/ckt.h @@ -90,7 +90,7 @@ int DCOaskQuest( CKTcircuit *, void *, int , IFvalue *); int DCOsetParm( CKTcircuit *, void *, int , IFvalue *); int DCTaskQuest( CKTcircuit *, void *, int , IFvalue *); int DCTsetParm( CKTcircuit *, void *, int , IFvalue *); -int DCop( CKTcircuit *); +int DCop( CKTcircuit *, int); int DCtrCurv( CKTcircuit *, int ); int DCtran( CKTcircuit *, int ); int DISTOan(CKTcircuit *, int); diff --git a/src/spicelib/analysis/cktdest.c b/src/spicelib/analysis/cktdest.c index b372e95e1..5a3ccf728 100644 --- a/src/spicelib/analysis/cktdest.c +++ b/src/spicelib/analysis/cktdest.c @@ -20,7 +20,7 @@ Author: 1985 Thomas L. Quarles -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; int CKTdestroy(void *inCkt) { diff --git a/src/spicelib/analysis/cktdisto.c b/src/spicelib/analysis/cktdisto.c index 5db0a4564..71f45c42d 100644 --- a/src/spicelib/analysis/cktdisto.c +++ b/src/spicelib/analysis/cktdisto.c @@ -22,7 +22,7 @@ Author: 1988 Jaijeet S Roychowdhury int CKTdisto (CKTcircuit *ckt, int mode) { - extern SPICEdev *DEVices[]; + extern SPICEdev **DEVices; DISTOAN* cv = (DISTOAN*) (ckt->CKTcurJob); int i; int error=0; diff --git a/src/spicelib/analysis/cktdojob.c b/src/spicelib/analysis/cktdojob.c index 45f36fafd..693a79e9c 100644 --- a/src/spicelib/analysis/cktdojob.c +++ b/src/spicelib/analysis/cktdojob.c @@ -12,6 +12,13 @@ Modified: 2000 AlansFixes #include "analysis.h" +#ifdef XSPICE +/* gtri - add - wbk - 11/26/90 - add include for MIF and EVT global data */ +#include "mif.h" +#include "evtproto.h" +/* gtri - end - wbk - 11/26/90 */ +#endif + extern SPICEanalysis *analInfo[]; int @@ -139,8 +146,19 @@ printf("Doing analysis at TEMP = %f and TNOM = %f\n", error = (*(analInfo[i]->an_init))(ckt, job); if (!error && analInfo[i]->do_ic) error = CKTic(ckt); - if (!error) + if (!error){ +#ifdef XSPICE + /* gtri - begin - 6/10/91 - wbk - Setup event-driven data */ + error = EVTsetup(ckt); + if(error) { + ckt->CKTstat->STATtotAnalTime += + (*(SPfrontEnd->IFseconds))()-startTime; + return(error); + } + /* gtri - end - 6/10/91 - wbk - Setup event-driven data */ +#endif error = (*(analInfo[i]->an_func))(ckt, reset); + } if (error) error2 = error; } diff --git a/src/spicelib/analysis/cktfbran.c b/src/spicelib/analysis/cktfbran.c index b6d5d9fbf..15e7ff646 100644 --- a/src/spicelib/analysis/cktfbran.c +++ b/src/spicelib/analysis/cktfbran.c @@ -21,7 +21,7 @@ Author: 1985 Thomas L. Quarles int CKTfndBranch(CKTcircuit *ckt, IFuid name) { - extern SPICEdev *DEVices[]; + extern SPICEdev **DEVices; int i; int j; diff --git a/src/spicelib/analysis/ckti2nod.c b/src/spicelib/analysis/ckti2nod.c index cfaa7af99..3adef7552 100644 --- a/src/spicelib/analysis/ckti2nod.c +++ b/src/spicelib/analysis/ckti2nod.c @@ -20,7 +20,7 @@ Author: 1985 Thomas L. Quarles -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; int CKTinst2Node(void *ckt, void *instPtr, int terminal, void **node, IFuid *nodeName) diff --git a/src/spicelib/analysis/cktic.c b/src/spicelib/analysis/cktic.c index 8bf0f03d8..f70a9c21f 100644 --- a/src/spicelib/analysis/cktic.c +++ b/src/spicelib/analysis/cktic.c @@ -12,7 +12,7 @@ Author: 1985 Thomas L. Quarles -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; int CKTic(CKTcircuit *ckt) diff --git a/src/spicelib/analysis/cktload.c b/src/spicelib/analysis/cktload.c index 987f2b72c..dd76317cb 100644 --- a/src/spicelib/analysis/cktload.c +++ b/src/spicelib/analysis/cktload.c @@ -19,13 +19,18 @@ Modified: 2000 AlansFixes #include "devdefs.h" #include "sperror.h" +#ifdef XSPICE +/* gtri - add - wbk - 11/26/90 - add include for MIF global data */ +#include "mif.h" +/* gtri - end - wbk - 11/26/90 */ +#endif static int ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum); int CKTload(CKTcircuit *ckt) { - extern SPICEdev *DEVices[]; + extern SPICEdev **DEVices; int i; int size; double startTime; @@ -39,6 +44,16 @@ CKTload(CKTcircuit *ckt) int noncon; #endif /* STEPDEBUG */ +#ifdef XSPICE + /* gtri - begin - Put resistors to ground at all nodes */ + /* SMPmatrix *matrix; maschmann : deleted , because unused */ + + double gshunt; + int num_nodes; + + /* gtri - begin - Put resistors to ground at all nodes */ +#endif + startTime = (*(SPfrontEnd->IFseconds))(); size = SMPmatSize(ckt->CKTmatrix); for (i=0;i<=size;i++) { @@ -68,6 +83,31 @@ CKTload(CKTcircuit *ckt) #endif /* PARALLEL_ARCH */ } } + + /* gtri - add - wbk - 11/26/90 - reset the MIF init flags */ +#ifdef XSPICE + /* init is set by CKTinit and should be true only for first load call */ + g_mif_info.circuit.init = MIF_FALSE; + + /* anal_init is set by CKTdoJob and is true for first call */ + /* of a particular analysis type */ + g_mif_info.circuit.anal_init = MIF_FALSE; + + /* gtri - end - wbk - 11/26/90 */ + + /* gtri - begin - Put resistors to ground at all nodes. */ + /* Value of resistor is set by new "rshunt" option. */ + + if(ckt->enh->rshunt_data.enabled) { + gshunt = ckt->enh->rshunt_data.gshunt; + num_nodes = ckt->enh->rshunt_data.num_nodes; + for(i = 0; i < num_nodes; i++) { + *(ckt->enh->rshunt_data.diag[i]) += gshunt; + } + } +#endif + /* gtri - end - Put resistors to ground at all nodes */ + if(ckt->CKTmode & MODEDC) { /* consider doing nodeset & ic assignments */ if(ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) { diff --git a/src/spicelib/analysis/cktmask.c b/src/spicelib/analysis/cktmask.c index 8a27c21e8..95147576c 100644 --- a/src/spicelib/analysis/cktmask.c +++ b/src/spicelib/analysis/cktmask.c @@ -15,7 +15,7 @@ Author: 1985 Thomas L. Quarles #include "sperror.h" -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; /* ARGSUSED */ int diff --git a/src/spicelib/analysis/cktmcrt.c b/src/spicelib/analysis/cktmcrt.c index 73fb7d76a..b1b210fed 100644 --- a/src/spicelib/analysis/cktmcrt.c +++ b/src/spicelib/analysis/cktmcrt.c @@ -21,13 +21,13 @@ Author: 1985 Thomas L. Quarles int CKTmodCrt(void *ckt, int type, void **modfast, IFuid name) { - extern SPICEdev *DEVices[]; + extern SPICEdev **DEVices; GENmodel *mymodfast = NULL; int error; error = CKTfndMod(ckt,&type,(void**)&mymodfast,name); if(error == E_NOMOD) { - mymodfast = (GENmodel *)MALLOC(*DEVices[type]->DEVmodSize); + mymodfast = (GENmodel *)MALLOC(*(DEVices[type]->DEVmodSize)); if(mymodfast == (GENmodel *)NULL) return(E_NOMEM); mymodfast->GENmodType = type; mymodfast->GENmodName = name; diff --git a/src/spicelib/analysis/cktmpar.c b/src/spicelib/analysis/cktmpar.c index 6ec6f79dd..96e3b159d 100644 --- a/src/spicelib/analysis/cktmpar.c +++ b/src/spicelib/analysis/cktmpar.c @@ -15,7 +15,7 @@ Author: 1985 Thomas L. Quarles #include "sperror.h" -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; /* ARGSUSED */ int diff --git a/src/spicelib/analysis/cktnoise.c b/src/spicelib/analysis/cktnoise.c index 02805b2f6..bc6e92b60 100644 --- a/src/spicelib/analysis/cktnoise.c +++ b/src/spicelib/analysis/cktnoise.c @@ -26,7 +26,7 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data) { double outNdens; int i; - extern SPICEdev *DEVices[]; + extern SPICEdev **DEVices; IFvalue outData; /* output variable (points to list of outputs)*/ IFvalue refVal; /* reference variable (always 0)*/ int error; diff --git a/src/spicelib/analysis/cktop.c b/src/spicelib/analysis/cktop.c index 7565bdc2c..f318a8a5c 100644 --- a/src/spicelib/analysis/cktop.c +++ b/src/spicelib/analysis/cktop.c @@ -354,7 +354,7 @@ CKTop(CKTcircuit *ckt, long int firstmode, long int continuemode, int iterlim) int CKTconvTest(CKTcircuit *ckt) { - extern SPICEdev *DEVices[]; + extern SPICEdev **DEVices; int i; int error = OK; #ifdef PARALLEL_ARCH diff --git a/src/spicelib/analysis/cktparam.c b/src/spicelib/analysis/cktparam.c index 9c04af32f..f274e0f0a 100644 --- a/src/spicelib/analysis/cktparam.c +++ b/src/spicelib/analysis/cktparam.c @@ -16,7 +16,7 @@ Author: 1985 Thomas L. Quarles -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; /* ARGSUSED */ int diff --git a/src/spicelib/analysis/cktpartn.c b/src/spicelib/analysis/cktpartn.c index 58876ddf4..300be2f72 100644 --- a/src/spicelib/analysis/cktpartn.c +++ b/src/spicelib/analysis/cktpartn.c @@ -18,7 +18,10 @@ Author: 1992 David A. Gates, UC Berkeley CADgroup -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; +#ifdef XSPICE +extern int *DEVicesfl; +#endif int CKTpartition(CKTcircuit *ckt) @@ -28,7 +31,11 @@ CKTpartition(CKTcircuit *ckt) GENinstance *inst; for (i=0;iCKThead[i] != NULL) ) { + if ( (ckt->CKThead[i] != NULL) +#ifdef XSPICE +&& DEVicesfl[i] == 0 +#endif + ){ for (model = ckt->CKThead[i]; model; model = model->GENnextModel) { for (inst = model->GENinstances; inst; inst = inst->GENnextInstance) { diff --git a/src/spicelib/analysis/cktpmnam.c b/src/spicelib/analysis/cktpmnam.c index 6743d6e3b..6c8d35518 100644 --- a/src/spicelib/analysis/cktpmnam.c +++ b/src/spicelib/analysis/cktpmnam.c @@ -19,7 +19,7 @@ Author: 1985 Thomas L. Quarles -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; /* ARGSUSED */ int diff --git a/src/spicelib/analysis/cktpname.c b/src/spicelib/analysis/cktpname.c index 187e5df3a..b35310149 100644 --- a/src/spicelib/analysis/cktpname.c +++ b/src/spicelib/analysis/cktpname.c @@ -21,7 +21,7 @@ Author: 1985 Thomas L. Quarles -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; /* ARGSUSED */ int diff --git a/src/spicelib/analysis/cktpzld.c b/src/spicelib/analysis/cktpzld.c index ada52b194..0de8e283c 100644 --- a/src/spicelib/analysis/cktpzld.c +++ b/src/spicelib/analysis/cktpzld.c @@ -12,7 +12,7 @@ Copyright 1990 Regents of the University of California. All rights reserved. #include "sperror.h" -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; int CKTpzLoad(CKTcircuit *ckt, SPcomplex *s) diff --git a/src/spicelib/analysis/cktpzset.c b/src/spicelib/analysis/cktpzset.c index 76eb06125..cce41cd51 100644 --- a/src/spicelib/analysis/cktpzset.c +++ b/src/spicelib/analysis/cktpzset.c @@ -19,7 +19,7 @@ Copyright 1990 Regents of the University of California. All rights reserved. int CKTpzSetup(CKTcircuit *ckt, int type) { - extern SPICEdev *DEVices[]; + extern SPICEdev **DEVices; PZAN *pzan = (PZAN *) ckt->CKTcurJob; SMPmatrix *matrix; int error; diff --git a/src/spicelib/analysis/cktsens.c b/src/spicelib/analysis/cktsens.c index 7efd971ef..928f47ac8 100644 --- a/src/spicelib/analysis/cktsens.c +++ b/src/spicelib/analysis/cktsens.c @@ -33,7 +33,7 @@ static int sens_temp(sgen *sg, CKTcircuit *ckt); static int count_steps(int type, double low, double high, int steps, double *stepsize); static double inc_freq(double freq, int type, double step_size); -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; /* * Procedure: @@ -70,8 +70,8 @@ int sens_sens(CKTcircuit *ckt, int restart) int (*fn)( ); static int is_dc; int k, j, n; - int num_vars, branch_eq; - char *sen_data; + int num_vars, branch_eq=0; + char *sen_data=NULL; char namebuf[513]; IFuid *output_names, freq_name; int bypass; @@ -600,7 +600,7 @@ inc_freq(double freq, int type, double step_size) double next_freq(int type, double freq, double stepsize) { - double s; + double s=0; switch (type) { case SENS_DC: diff --git a/src/spicelib/analysis/cktsetup.c b/src/spicelib/analysis/cktsetup.c index 59343bc22..963bf40ab 100644 --- a/src/spicelib/analysis/cktsetup.c +++ b/src/spicelib/analysis/cktsetup.c @@ -23,14 +23,19 @@ Author: 1985 Thomas L. Quarles return(E_NOMEM);\ } -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; int CKTsetup(CKTcircuit *ckt) { int i; int error; - +#ifdef XSPICE + /* gtri - begin - Setup for adding rshunt option resistors */ + CKTnode *node; + int num_nodes; + /* gtri - end - Setup for adding rshunt option resistors */ +#endif SMPmatrix *matrix; ckt->CKTnumStates=0; @@ -74,7 +79,38 @@ CKTsetup(CKTcircuit *ckt) error = NIreinit(ckt); if(error) return(error); } +#ifdef XSPICE + /* gtri - begin - Setup for adding rshunt option resistors */ + if(ckt->enh->rshunt_data.enabled) { + + /* Count number of voltage nodes in circuit */ + for(num_nodes = 0, node = ckt->CKTnodes; node; node = node->next) + if((node->type == NODE_VOLTAGE) && (node->number != 0)) + num_nodes++; + + /* Allocate space for the matrix diagonal data */ + if(num_nodes > 0) { + ckt->enh->rshunt_data.diag = + (double **) MALLOC(num_nodes * sizeof(double *)); + } + + /* Set the number of nodes in the rshunt data */ + ckt->enh->rshunt_data.num_nodes = num_nodes; + + /* Get/create matrix diagonal entry following what RESsetup does */ + for(i = 0, node = ckt->CKTnodes; node; node = node->next) { + if((node->type == NODE_VOLTAGE) && (node->number != 0)) { + ckt->enh->rshunt_data.diag[i] = + SMPmakeElt(matrix,node->number,node->number); + i++; + } + } + + } + + /* gtri - end - Setup for adding rshunt option resistors */ +#endif return(OK); } diff --git a/src/spicelib/analysis/cktsgen.c b/src/spicelib/analysis/cktsgen.c index 78f122450..4760a2ff3 100644 --- a/src/spicelib/analysis/cktsgen.c +++ b/src/spicelib/analysis/cktsgen.c @@ -10,7 +10,8 @@ Copyright 1991 Regents of the University of California. All rights reserved. #include "sensgen.h" #include -extern SPICEdev *DEVices[]; /* XXX */ +extern SPICEdev **DEVices; + /* XXX */ extern char *Sfilter; sgen * diff --git a/src/spicelib/analysis/cktsopt.c b/src/spicelib/analysis/cktsopt.c index 01e672353..f7cb8ab1c 100644 --- a/src/spicelib/analysis/cktsopt.c +++ b/src/spicelib/analysis/cktsopt.c @@ -21,6 +21,13 @@ Modified: 2000 AlansFixes #include "analysis.h" +#ifdef XSPICE +/* gtri - begin - wbk - add includes */ +#include "mif.h" +/* gtri - end - wbk - add includes */ +#endif + + /* ARGSUSED */ int CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val) @@ -142,12 +149,72 @@ CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val) case OPT_RELDV: task->TSKrelDv = val->rValue; break; +/* gtri - begin - wbk - add new options */ +#ifdef XSPICE + case OPT_EVT_MAX_OP_ALTER: + ((CKTcircuit *) ckt)->evt->limits.max_op_alternations = val->iValue; + break; + + case OPT_EVT_MAX_EVT_PASSES: + ((CKTcircuit *) ckt)->evt->limits.max_event_passes = val->iValue; + break; + + case OPT_ENH_NOOPALTER: + ((CKTcircuit *) ckt)->evt->options.op_alternate = MIF_FALSE; + break; + + case OPT_ENH_RAMPTIME: + ((CKTcircuit *) ckt)->enh->ramp.ramptime = val->rValue; + break; + + case OPT_ENH_CONV_LIMIT: + ((CKTcircuit *) ckt)->enh->conv_limit.enabled = MIF_TRUE; + break; + + case OPT_ENH_CONV_STEP: + ((CKTcircuit *) ckt)->enh->conv_limit.step = val->rValue; + ((CKTcircuit *) ckt)->enh->conv_limit.enabled = MIF_TRUE; + break; + + case OPT_ENH_CONV_ABS_STEP: + ((CKTcircuit *) ckt)->enh->conv_limit.abs_step = val->rValue; + ((CKTcircuit *) ckt)->enh->conv_limit.enabled = MIF_TRUE; + break; + + case OPT_MIF_AUTO_PARTIAL: + g_mif_info.auto_partial.global = MIF_TRUE; + break; + + case OPT_ENH_RSHUNT: + if(val->rValue > 1.0e-30) { + ((CKTcircuit *) ckt)->enh->rshunt_data.enabled = MIF_TRUE; + ((CKTcircuit *) ckt)->enh->rshunt_data.gshunt = 1.0 / val->rValue; + } + else { + printf("WARNING - Rshunt option too small. Ignored.\n"); + } + break; +#endif +/* gtri - end - wbk - add new options */ default: return(-1); } return(0); } static IFparm OPTtbl[] = { +#ifdef XSPICE +/* gtri - begin - wbk - add new options */ + { "maxopalter", OPT_EVT_MAX_OP_ALTER, IF_SET|IF_INTEGER, "Maximum analog/event alternations in DCOP" }, + { "maxevtiter", OPT_EVT_MAX_EVT_PASSES, IF_SET|IF_INTEGER, "Maximum event iterations at analysis point" }, + { "noopalter", OPT_ENH_NOOPALTER, IF_SET|IF_FLAG, "Do not do analog/event alternation in DCOP" }, + { "ramptime", OPT_ENH_RAMPTIME, IF_SET|IF_REAL, "Transient analysis supply ramping time" }, + { "convlimit", OPT_ENH_CONV_LIMIT, IF_SET|IF_FLAG, "Enable convergence assistance on code models" }, + { "convstep", OPT_ENH_CONV_STEP, IF_SET|IF_REAL, "Fractional step allowed by code model inputs between iterations" }, + { "convabsstep", OPT_ENH_CONV_ABS_STEP, IF_SET|IF_REAL, "Absolute step allowed by code model inputs between iterations" }, + { "autopartial", OPT_MIF_AUTO_PARTIAL, IF_SET|IF_FLAG, "Use auto-partial computation for all models" }, + { "rshunt", OPT_ENH_RSHUNT, IF_SET|IF_REAL, "Shunt resistance from analog nodes to ground" }, +/* gtri - end - wbk - add new options */ +#endif { "noopiter", OPT_NOOPITER,IF_SET|IF_FLAG,"Go directly to gmin stepping" }, { "gmin", OPT_GMIN,IF_SET|IF_REAL,"Minimum conductance" }, { "gshunt", OPT_GSHUNT,IF_SET|IF_REAL,"Shunt conductance" }, diff --git a/src/spicelib/analysis/ckttemp.c b/src/spicelib/analysis/ckttemp.c index 0be324dc1..680943878 100644 --- a/src/spicelib/analysis/ckttemp.c +++ b/src/spicelib/analysis/ckttemp.c @@ -19,7 +19,7 @@ Author: 1985 Thomas L. Quarles -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; int CKTtemp(CKTcircuit *ckt) diff --git a/src/spicelib/analysis/cktterr.c b/src/spicelib/analysis/cktterr.c index 611c413de..ef45889fd 100644 --- a/src/spicelib/analysis/cktterr.c +++ b/src/spicelib/analysis/cktterr.c @@ -20,7 +20,7 @@ CKTterr(int qcap, CKTcircuit *ckt, double *timeStep) double del; double diff[8]; double deltmp[8]; - double factor; + double factor=0; int i; int j; static double gearCoeff[] = { diff --git a/src/spicelib/analysis/ckttroub.c b/src/spicelib/analysis/ckttroub.c index 86541a15d..23902b1d6 100644 --- a/src/spicelib/analysis/ckttroub.c +++ b/src/spicelib/analysis/ckttroub.c @@ -13,7 +13,7 @@ Copyright 1990 Regents of the University of California. All rights reserved. #include "analysis.h" -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; extern SPICEanalysis *analInfo[]; char * diff --git a/src/spicelib/analysis/ckttrunc.c b/src/spicelib/analysis/ckttrunc.c index 367a2f080..d10872af2 100644 --- a/src/spicelib/analysis/ckttrunc.c +++ b/src/spicelib/analysis/ckttrunc.c @@ -18,7 +18,7 @@ Author: 1985 Thomas L. Quarles -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; int CKTtrunc(CKTcircuit *ckt, double *timeStep) diff --git a/src/spicelib/analysis/ckttyplk.c b/src/spicelib/analysis/ckttyplk.c index 2c7655dfc..9177cc9dc 100644 --- a/src/spicelib/analysis/ckttyplk.c +++ b/src/spicelib/analysis/ckttyplk.c @@ -13,7 +13,7 @@ Author: 1985 Thomas L. Quarles -extern SPICEdev *DEVices[]; +extern SPICEdev **DEVices; int CKTtypelook(char *type) diff --git a/src/spicelib/analysis/dcop.c b/src/spicelib/analysis/dcop.c index 1a6841ec4..0f72e1082 100644 --- a/src/spicelib/analysis/dcop.c +++ b/src/spicelib/analysis/dcop.c @@ -12,20 +12,21 @@ Modified: 2000 AlansFixes int -DCop(CKTcircuit *ckt) +DCop(CKTcircuit *ckt, int notused) { int CKTload(CKTcircuit *ckt); int converged; int error; - IFuid *nameList; + IFuid *nameList; /* va: tmalloc'ed list */ int numNames; - void *plot; + void *plot = NULL; error = CKTnames(ckt,&numNames,&nameList); if(error) return(error); error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, (void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname, (IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&plot); + tfree(nameList); /* va: nameList not used any longer, it was a memory leak */ if(error) return(error); converged = CKTop(ckt, diff --git a/src/spicelib/analysis/dctran.c b/src/spicelib/analysis/dctran.c index 88d4e70a1..a5b49421a 100644 --- a/src/spicelib/analysis/dctran.c +++ b/src/spicelib/analysis/dctran.c @@ -13,6 +13,21 @@ Modified: 2000 AlansFixes #include #include +#ifdef XSPICE +/* gtri - add - wbk - Add headers */ +#include "miftypes.h" +/* gtri - end - wbk - Add headers */ + +/* gtri - add - wbk - Add headers */ +#include "evt.h" +#include "mif.h" +#include "evtproto.h" +#include "ipctiein.h" +/* gtri - end - wbk - Add headers */ +#endif + +#ifdef CLUSTER +#include "cluster.h" #ifdef HAS_WINDOWS /* hvogt 10.03.99, nach W. Mues */ void SetAnalyse( char * Analyse, int Percent); @@ -55,7 +70,18 @@ DCtran(CKTcircuit *ckt, #ifdef PARALLEL_ARCH long type = MT_TRANAN, length = 1; #endif /* PARALLEL_ARCH */ - +#ifdef XSPICE +/* gtri - add - wbk - 12/19/90 - Add IPC stuff */ + Ipc_Boolean_t ipc_firsttime = IPC_TRUE; + Ipc_Boolean_t ipc_secondtime = IPC_FALSE; + Ipc_Boolean_t ipc_delta_cut = IPC_FALSE; + double ipc_last_time = 0.0; + double ipc_last_delta = 0.0; +/* gtri - end - wbk - 12/19/90 - Add IPC stuff */ +#endif +#ifdef CLUSTER + int redostep; +#endif if(restart || ckt->CKTtime == 0) { delta=MIN(ckt->CKTfinalTime/200,ckt->CKTstep)/10; @@ -83,7 +109,19 @@ DCtran(CKTcircuit *ckt, *(ckt->CKTbreaks+1)=ckt->CKTfinalTime; ckt->CKTbreakSize=2; if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5; +#ifdef XSPICE +/* gtri - add - wbk - 12/19/90 - Add IPC stuff and set anal_init and anal_type */ + /* Tell the beginPlot routine what mode we're in */ + g_ipc.anal_type = IPC_ANAL_TRAN; + + /* Tell the code models what mode we're in */ + g_mif_info.circuit.anal_type = MIF_DC; + + g_mif_info.circuit.anal_init = MIF_TRUE; + +/* gtri - end - wbk */ +#endif error = CKTnames(ckt,&numNames,&nameList); if(error) return(error); (*(SPfrontEnd->IFnewUid))((void *)ckt,&timeUid,(IFuid)NULL, @@ -92,6 +130,7 @@ DCtran(CKTcircuit *ckt, (void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname,timeUid,IF_REAL,numNames,nameList, IF_REAL,&(((TRANan*)ckt->CKTcurJob)->TRANplot)); + tfree(nameList); if(error) return(error); ckt->CKTtime = 0; @@ -100,6 +139,28 @@ DCtran(CKTcircuit *ckt, firsttime = 1; save_mode = (ckt->CKTmode&MODEUIC)|MODETRANOP | MODEINITJCT; save_order = ckt->CKTorder; +#ifdef XSPICE +/* gtri - begin - wbk - set a breakpoint at end of supply ramping time */ + /* must do this after CKTtime set to 0 above */ + if(ckt->enh->ramp.ramptime > 0.0) + CKTsetBreak(ckt, ckt->enh->ramp.ramptime); +/* gtri - end - wbk - set a breakpoint at end of supply ramping time */ + +/* gtri - begin - wbk - Call EVTop if event-driven instances exist */ + if(ckt->evt->counts.num_insts != 0){ + /* use new DCOP algorithm */ + converged = EVTop(ckt, + (ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT, + ckt->CKTdcMaxIter, + MIF_TRUE); + EVTdump(ckt, IPC_ANAL_DCOP, 0.0); + + EVTop_save(ckt, MIF_FALSE, 0.0); + + /* gtri - end - wbk - Call EVTop if event-driven instances exist */ + } else +#endif converged = CKTop(ckt, (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITJCT, (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT, @@ -152,6 +213,36 @@ DCtran(CKTcircuit *ckt, fprintf(stdout,"\n"); fflush(stdout); if(converged != 0) return(converged); +#ifdef XSPICE +/* gtri - add - wbk - 12/19/90 - Add IPC stuff */ + + /* Send the operating point results for Mspice compatibility */ + if(g_ipc.enabled) { + ipc_send_dcop_prefix(); + CKTdump(ckt,(double)0,(((TRANan*)ckt->CKTcurJob)->TRANplot)); + ipc_send_dcop_suffix(); + } + +/* gtri - end - wbk */ + + +/* gtri - add - wbk - 12/19/90 - set anal_init and anal_type */ + + g_mif_info.circuit.anal_init = MIF_TRUE; + + /* Tell the code models what mode we're in */ + g_mif_info.circuit.anal_type = MIF_TRAN; + +/* gtri - end - wbk */ + +/* gtri - begin - wbk - Add Breakpoint stuff */ + + /* Initialize the temporary breakpoint variables to infinity */ + g_mif_info.breakpoint.current = 1.0e30; + g_mif_info.breakpoint.last = 1.0e30; + +/* gtri - end - wbk - Add Breakpoint stuff */ +#endif ckt->CKTstat->STATtimePts ++; ckt->CKTorder=1; for(i=0;i<7;i++) { @@ -202,7 +293,13 @@ DCtran(CKTcircuit *ckt, startlTime = ckt->CKTstat->STATloadTime; startcTime = ckt->CKTstat->STATcombineTime; startkTime = ckt->CKTstat->STATsyncTime; +#ifdef CLUSTER + CLUsetup(ckt); +#endif } else { + /*saj As traninit resets CKTmode */ + ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED; + /* saj */ startTime=(*(SPfrontEnd->IFseconds))(); startIters = ckt->CKTstat->STATnumIter; startdTime = ckt->CKTstat->STATdecompTime; @@ -212,6 +309,15 @@ DCtran(CKTcircuit *ckt, startkTime = ckt->CKTstat->STATsyncTime; if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5; firsttime=0; + /* To get rawfile working saj*/ + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, (void*)ckt->CKTcurJob, + ckt->CKTcurJob->JOBname,timeUid,IF_REAL,666,nameList, + 666,&(((TRANan*)ckt->CKTcurJob)->TRANplot));/*magic 666 nums as flags */ + if(error) { + fprintf(stderr, "Couldn't relink rawfile\n"); + return error; + } + /*end saj*/ goto resume; } @@ -275,8 +381,67 @@ nextTime: startkTime; return(error); } +#ifdef XSPICE +/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ + + if(g_ipc.enabled) { + + /* Send event-driven results */ + EVTdump(ckt, IPC_ANAL_TRAN, 0.0); + + /* Then follow with analog results... */ + + /* Test to see if delta was cut by a breakpoint, */ + /* a non-convergence, or a too large truncation error */ + if(ipc_firsttime) + ipc_delta_cut = IPC_FALSE; + else if(ckt->CKTtime < (ipc_last_time + (0.999 * ipc_last_delta))) + ipc_delta_cut = IPC_TRUE; + else + ipc_delta_cut = IPC_FALSE; + + /* Record the data required to check for delta cuts */ + ipc_last_time = ckt->CKTtime; + ipc_last_delta = MIN(ckt->CKTdelta, ckt->CKTmaxStep); + + /* Send results data if time since last dump is greater */ + /* than 'mintime', or if first or second timepoints, */ + /* or if delta was cut */ + if( (ckt->CKTtime >= (g_ipc.mintime + g_ipc.last_time)) || + ipc_firsttime || ipc_secondtime || ipc_delta_cut ) { + + ipc_send_data_prefix(ckt->CKTtime); + CKTdump(ckt,ckt->CKTtime, + (((TRANan*)ckt->CKTcurJob)->TRANplot)); + ipc_send_data_suffix(); + + if(ipc_firsttime) { + ipc_firsttime = IPC_FALSE; + ipc_secondtime = IPC_TRUE; + } + else if(ipc_secondtime) + ipc_secondtime = IPC_FALSE; + + g_ipc.last_time = ckt->CKTtime; + } + } + else +/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ +#endif +#ifdef CLUSTER + CLUoutput(ckt); +#endif if(ckt->CKTtime >= ckt->CKTinitTime) CKTdump(ckt,ckt->CKTtime, (((TRANan*)ckt->CKTcurJob)->TRANplot)); +#ifdef XSPICE +/* gtri - begin - wbk - Update event queues/data for accepted timepoint */ + + /* Note: this must be done AFTER sending results to SI so it can't */ + /* go next to CKTaccept() above */ + if(ckt->evt->counts.num_insts > 0) + EVTaccept(ckt, ckt->CKTtime); +/* gtri - end - wbk - Update event queues/data for accepted timepoint */ +#endif ckt->CKTstat->STAToldIter = ckt->CKTstat->STATnumIter; if(fabs(ckt->CKTtime - ckt->CKTfinalTime) < ckt->CKTminBreak) { /*printf(" done: time is %g, final time is %g, and tol is %g\n",*/ @@ -381,11 +546,59 @@ resume: #endif ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */ } - +#ifdef CLUSTER + if(!CLUsync(ckt->CKTtime,&ckt->CKTdelta,0)){ + printf("Sync error!\n"); + exit(0); + } +#endif #ifdef PARALLEL_ARCH DGOP_( &type, &(ckt->CKTdelta), &length, "min" ); #endif /* PARALLEL_ARCH */ +#ifdef XSPICE +/* gtri - begin - wbk - Do event solution */ + if(ckt->evt->counts.num_insts > 0) { + + /* if time = 0 and op_alternate was specified as false during */ + /* dcop analysis, call any changed instances to let them */ + /* post their outputs with their associated delays */ + if((ckt->CKTtime == 0.0) && (! ckt->evt->options.op_alternate)) + EVTiter(ckt); + + /* while there are events on the queue with event time <= next */ + /* projected analog time, process them */ + while((g_mif_info.circuit.evt_step = EVTnext_time(ckt)) + <= (ckt->CKTtime + ckt->CKTdelta)) { + + /* Initialize temp analog bkpt to infinity */ + g_mif_info.breakpoint.current = 1e30; + + /* Pull items off queue and process them */ + EVTdequeue(ckt, g_mif_info.circuit.evt_step); + EVTiter(ckt); + + /* If any instances have forced an earlier */ + /* next analog time, cut the delta */ + if(*(ckt->CKTbreaks) < g_mif_info.breakpoint.current) + if(*(ckt->CKTbreaks) > (ckt->CKTtime + ckt->CKTminBreak)) + g_mif_info.breakpoint.current = *(ckt->CKTbreaks); + if(g_mif_info.breakpoint.current < (ckt->CKTtime + ckt->CKTdelta)) { + /* Breakpoint must be > last accepted timepoint */ + /* and >= current event time */ + if(g_mif_info.breakpoint.current > (ckt->CKTtime + ckt->CKTminBreak) + && (g_mif_info.breakpoint.current >= g_mif_info.circuit.evt_step)) { + ckt->CKTsaveDelta = ckt->CKTdelta; + ckt->CKTdelta = g_mif_info.breakpoint.current - ckt->CKTtime; + g_mif_info.breakpoint.last = ckt->CKTtime + ckt->CKTdelta; + } + } + + } /* end while next event time <= next analog time */ + } /* end if there are event instances */ + +/* gtri - end - wbk - Do event solution */ +#endif for(i=5;i>=0;i--) { ckt->CKTdeltaOld[i+1]=ckt->CKTdeltaOld[i]; } @@ -399,9 +612,25 @@ resume: /* 600 */ while (1) { +#ifdef CLUSTER + redostep = 1; +#endif +#ifdef XSPICE +/* gtri - add - wbk - 4/17/91 - Fix Berkeley bug */ +/* This is needed here to allow CAPask to output currents */ +/* during Transient analysis. A grep for CKTcurrentAnalysis */ +/* indicates that it should not hurt anything else ... */ + + ckt->CKTcurrentAnalysis = DOING_TRAN; + +/* gtri - end - wbk - 4/17/91 - Fix Berkeley bug */ +#endif olddelta=ckt->CKTdelta; /* time abort? */ ckt->CKTtime += ckt->CKTdelta; +#ifdef CLUSTER + CLUinput(ckt); +#endif ckt->CKTdeltaOld[0]=ckt->CKTdelta; NIcomCof(ckt); #ifdef PREDICTOR @@ -409,7 +638,46 @@ resume: #endif /* PREDICTOR */ save_mode = ckt->CKTmode; save_order = ckt->CKTorder; +#ifdef XSPICE +/* gtri - begin - wbk - Add Breakpoint stuff */ + + /* Initialize temporary breakpoint to infinity */ + g_mif_info.breakpoint.current = 1.0e30; + +/* gtri - end - wbk - Add Breakpoint stuff */ + + +/* gtri - begin - wbk - add convergence problem reporting flags */ + /* delta is forced to equal delmin on last attempt near line 650 */ + if(ckt->CKTdelta <= ckt->CKTdelmin) + ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE; + else + ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; +/* gtri - begin - wbk - add convergence problem reporting flags */ + + + +/* gtri - begin - wbk - Call all hybrids */ + +/* gtri - begin - wbk - Set evt_step */ + + if(ckt->evt->counts.num_insts > 0) { + g_mif_info.circuit.evt_step = ckt->CKTtime; + } +/* gtri - end - wbk - Set evt_step */ +#endif + converged = NIiter(ckt,ckt->CKTtranMaxIter); + +#ifdef XSPICE + if(ckt->evt->counts.num_insts > 0) + { + g_mif_info.circuit.evt_step = ckt->CKTtime; + EVTcall_hybrids(ckt); + } +/* gtri - end - wbk - Call all hybrids */ + +#endif ckt->CKTstat->STATtimePts ++; ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED; if(firsttime) { @@ -419,8 +687,10 @@ resume: } } if(converged != 0) { +#ifndef CLUSTER ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta; ckt->CKTstat->STATrejected ++; +#endif ckt->CKTdelta = ckt->CKTdelta/8; #ifdef STEPDEBUG (void)printf("delta cut to %g for non-convergance\n",ckt->CKTdelta); @@ -444,9 +714,14 @@ resume: } #endif firsttime =0; +#ifndef CLUSTER goto nextTime; /* no check on * first time point */ +#else + redostep = 0; + goto chkStep; +#endif } new = ckt->CKTdelta; error = CKTtrunc(ckt,&new); @@ -514,11 +789,18 @@ resume: ckt->CKTorder = save2; } #endif - /* go to 650 - trapezoidal */ +#ifndef CLUSTER + /* go to 650 - trapezoidal */ goto nextTime; +#else + redostep = 0; + goto chkStep; +#endif } else { +#ifndef CLUSTER ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta; ckt->CKTstat->STATrejected ++; +#endif ckt->CKTdelta = new; #ifdef STEPDEBUG (void)printf( @@ -556,6 +838,23 @@ resume: return(E_TIMESTEP); } } +#ifdef XSPICE +/* gtri - begin - wbk - Do event backup */ + + if(ckt->evt->counts.num_insts > 0) + EVTbackup(ckt, ckt->CKTtime + ckt->CKTdelta); + +/* gtri - end - wbk - Do event backup */ +#endif +#ifdef CLUSTER + chkStep: + if(CLUsync(ckt->CKTtime,&ckt->CKTdelta,redostep)){ + goto nextTime; + } else { + ckt->CKTtime -= olddelta; + ckt->CKTstat->STATrejected ++; + } +#endif } /* NOTREACHED */ } diff --git a/src/spicelib/analysis/dctrcurv.c b/src/spicelib/analysis/dctrcurv.c index 867a93bc8..3ab359add 100644 --- a/src/spicelib/analysis/dctrcurv.c +++ b/src/spicelib/analysis/dctrcurv.c @@ -15,6 +15,8 @@ Modified: 1999 Paolo Nenzi #include "const.h" #include "sperror.h" +#include +extern SPICEdev **DEVices; int DCtrCurv(CKTcircuit *ckt, int restart) @@ -34,7 +36,7 @@ DCtrCurv(CKTcircuit *ckt, int restart) IFuid *nameList; int numNames; int firstTime=1; - static void *plot; + static void *plot=NULL; #ifdef WANT_SENSE2 #ifdef SENSDEBUG @@ -52,6 +54,10 @@ DCtrCurv(CKTcircuit *ckt, int restart) if(!restart && cv->TRCVnestState >= 0) { /* continuing */ i = cv->TRCVnestState; + /* resume to work? saj*/ + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname, + varUid,IF_REAL,666,nameList, 666,&plot); goto resume; } ckt->CKTtime = 0; @@ -259,7 +265,11 @@ resume: 1/(((RESinstance *)(cv->TRCVvElt[i]))->RESresist); /* Note: changing the resistance does nothing */ /* changing the conductance 1/r instead */ - RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + DEVices[rcode]->DEVload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + + /* + * RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + */ } /* else not possible */ @@ -357,7 +367,10 @@ nextstep:; /* This code should update resistance and conductance */ ((RESinstance*)(cv->TRCVvElt[i]))->RESconduct = 1/(((RESinstance*)(cv->TRCVvElt[i]))->RESresist); - RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + DEVices[rcode]->DEVload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + /* + * RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + */ } /* PN Temp Sweep - serban */ else if (cv->TRCVvType[i]==TEMP_CODE) @@ -392,7 +405,11 @@ nextstep:; 1/(((RESinstance*)(cv->TRCVvElt[i]))->RESresist); ((RESinstance*)(cv->TRCVvElt[i]))->RESresGiven = cv->TRCVgSave[i]; - RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + DEVices[rcode]->DEVload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + + /* + * RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + */ } else if(cv->TRCVvType[i] == TEMP_CODE) { ckt->CKTtemp = cv->TRCVvSave[i]; diff --git a/src/spicelib/analysis/distoan.c b/src/spicelib/analysis/distoan.c index c7a978f87..3fea7804c 100644 --- a/src/spicelib/analysis/distoan.c +++ b/src/spicelib/analysis/distoan.c @@ -58,7 +58,7 @@ DISTOan(CKTcircuit *ckt, int restart) int numNames; IFuid *nameList; IFuid freqUid; - void *acPlot; + void *acPlot=NULL; DISTOAN* job = (DISTOAN *) (ckt->CKTcurJob); static char *nof2src = "No source with f2 distortion input"; #ifdef DISTODEBUG @@ -120,6 +120,7 @@ time1 = (*(SPfrontEnd->IFseconds))(); if(error) return(error); CKTdump(ckt,(double)0,acPlot); (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot=NULL; } #ifdef D_DBG_BLOCKTIMES @@ -540,6 +541,7 @@ time1 = (*(SPfrontEnd->IFseconds))(); if(error) return(error); } (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot=NULL; error = CKTnames(ckt,&numNames,&nameList); if(error) return(error); @@ -558,6 +560,7 @@ time1 = (*(SPfrontEnd->IFseconds))(); error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot); } (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot=NULL; } else { @@ -580,6 +583,7 @@ time1 = (*(SPfrontEnd->IFseconds))(); if(error) return(error); } (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot=NULL; error = CKTnames(ckt,&numNames,&nameList); if(error) return(error); @@ -600,6 +604,7 @@ time1 = (*(SPfrontEnd->IFseconds))(); if(error) return(error); } (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot=NULL; error = CKTnames(ckt,&numNames,&nameList); if(error) return(error); @@ -620,6 +625,7 @@ time1 = (*(SPfrontEnd->IFseconds))(); if(error) return(error); } (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot=NULL; } FREE(job->r1H1ptr); diff --git a/src/spicelib/analysis/noisean.c b/src/spicelib/analysis/noisean.c index 1b0726143..368f76da1 100644 --- a/src/spicelib/analysis/noisean.c +++ b/src/spicelib/analysis/noisean.c @@ -164,6 +164,12 @@ NOISEan (CKTcircuit *ckt, int restart) job->NsavFstp = 0; data->outNoiz = job->NsavOnoise; data->inNoise = job->NsavInoise; + /* saj resume rawfile fix*/ + error = (*(SPfrontEnd->OUTpBeginPlot))(ckt,(void *)(ckt->CKTcurJob), + "Noise Spectral Density Curves - (V^2 or A^2)/Hz", + freqUid,IF_REAL,666,data->namelist,666, + &(data->NplotPtr)); + /*saj*/ } switch (job->NstpType) { diff --git a/src/spicelib/analysis/pzan.c b/src/spicelib/analysis/pzan.c index 40e1dad7a..0e7c7db6a 100644 --- a/src/spicelib/analysis/pzan.c +++ b/src/spicelib/analysis/pzan.c @@ -22,7 +22,7 @@ PZan(CKTcircuit *ckt, int reset) int error; int numNames; IFuid *nameList; - void *plot; + void *plot=NULL; error = PZinit(ckt); if (error != OK) return error; @@ -123,7 +123,7 @@ int PZpost(CKTcircuit *ckt) { PZAN *pzan = (PZAN *) ckt->CKTcurJob; - void *pzPlotPtr; /* the plot pointer for front end */ + void *pzPlotPtr=NULL; /* the plot pointer for front end */ IFcomplex *out_list; IFvalue outData; /* output variable (points to out_list) */ IFuid *namelist; diff --git a/src/spicelib/analysis/tfanal.c b/src/spicelib/analysis/tfanal.c index cef6f6614..b92a315bf 100644 --- a/src/spicelib/analysis/tfanal.c +++ b/src/spicelib/analysis/tfanal.c @@ -29,7 +29,7 @@ TFanal(CKTcircuit *ckt, int restart) int error; int converged; int i; - void *plotptr; /* pointer to out plot */ + void *plotptr=NULL; /* pointer to out plot */ void *ptr = NULL; IFuid uids[3]; int Itype; diff --git a/src/spicelib/devices/ChangeLog b/src/spicelib/devices/ChangeLog index 1f60c35fa..bfdcbaac3 100644 --- a/src/spicelib/devices/ChangeLog +++ b/src/spicelib/devices/ChangeLog @@ -1,3 +1,8 @@ +5.2.2003 -- Stuart Brorson * bsim3v1/b3v1noi.c, bsim3v2/b3v2noi.c: Both models had a diff --git a/src/spicelib/devices/Makefile.am b/src/spicelib/devices/Makefile.am index f43a805c4..686187710 100644 --- a/src/spicelib/devices/Makefile.am +++ b/src/spicelib/devices/Makefile.am @@ -3,7 +3,6 @@ SUBDIRS = \ asrc \ bjt \ -## bjt2 \ bsim1 \ bsim2 \ bsim3 \ @@ -16,6 +15,7 @@ SUBDIRS = \ cap \ cccs \ ccvs \ + cpl \ csw \ dio \ @EKVDIR@ \ @@ -37,12 +37,18 @@ SUBDIRS = \ soi3 \ sw \ tra \ + txl \ urc \ vccs \ vcvs \ vsrc -lib_LIBRARIES = libdev.a +## This line move to here 'cause it was causing automake to choke +## when it was in the list of subdirs +## bjt2 \ + + +noinst_LIBRARIES = libdev.a libdev_a_SOURCES = \ dev.c \ @@ -56,6 +62,6 @@ libdev_a_SOURCES = \ cktfinddev.c \ cktinit.c -INCLUDES = -I$(top_srcdir)/src/include +INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/asrc/Makefile.am b/src/spicelib/devices/asrc/Makefile.am index fa2349d3f..e8644972b 100644 --- a/src/spicelib/devices/asrc/Makefile.am +++ b/src/spicelib/devices/asrc/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libasrc.la +noinst_LIBRARIES = libasrc.a -libasrc_la_SOURCES = \ +libasrc_a_SOURCES = \ asrc.c \ asrcacld.c \ asrcask.c \ diff --git a/src/spicelib/devices/asrc/asrcinit.c b/src/spicelib/devices/asrc/asrcinit.c index 85abf9816..abb429b4e 100644 --- a/src/spicelib/devices/asrc/asrcinit.c +++ b/src/spicelib/devices/asrc/asrcinit.c @@ -21,6 +21,23 @@ SPICEdev ASRCinfo = { 0, NULL, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + + DEV_DEFAULT }, diff --git a/src/spicelib/devices/bjt/Makefile.am b/src/spicelib/devices/bjt/Makefile.am index 5d0e4655c..e0ebc3acb 100644 --- a/src/spicelib/devices/bjt/Makefile.am +++ b/src/spicelib/devices/bjt/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libbjt.la +noinst_LIBRARIES = libbjt.a -libbjt_la_SOURCES = \ +libbjt_a_SOURCES = \ bjt.c \ bjtacld.c \ bjtask.c \ diff --git a/src/spicelib/devices/bjt/bjtdisto.c b/src/spicelib/devices/bjt/bjtdisto.c index a5bfc39bd..9810f72ec 100644 --- a/src/spicelib/devices/bjt/bjtdisto.c +++ b/src/spicelib/devices/bjt/bjtdisto.c @@ -24,21 +24,21 @@ BJTdisto(int mode, GENmodel *genmodel, CKTcircuit *ckt) DISTOAN* job = (DISTOAN*) ckt->CKTcurJob; double td; DpassStr pass; - double r1h1x,i1h1x; - double r1h1y,i1h1y; - double r1h1z, i1h1z; - double r1h2x, i1h2x; - double r1h2y, i1h2y; - double r1h2z, i1h2z; - double r1hm2x,i1hm2x; - double r1hm2y,i1hm2y; - double r1hm2z, i1hm2z; - double r2h11x,i2h11x; - double r2h11y,i2h11y; - double r2h11z, i2h11z; - double r2h1m2x,i2h1m2x; - double r2h1m2y,i2h1m2y; - double r2h1m2z, i2h1m2z; + double r1h1x = 0, i1h1x = 0; + double r1h1y = 0, i1h1y = 0; + double r1h1z = 0, i1h1z = 0; + double r1h2x = 0, i1h2x = 0; + double r1h2y = 0, i1h2y = 0; + double r1h2z = 0, i1h2z = 0; + double r1hm2x = 0, i1hm2x = 0; + double r1hm2y = 0, i1hm2y = 0; + double r1hm2z = 0, i1hm2z = 0; + double r2h11x = 0, i2h11x = 0; + double r2h11y = 0, i2h11y = 0; + double r2h11z = 0, i2h11z = 0; + double r2h1m2x = 0, i2h1m2x = 0; + double r2h1m2y = 0, i2h1m2y = 0; + double r2h1m2z = 0, i2h1m2z = 0; double temp, itemp; BJTinstance *here; #ifdef DISTODEBUG diff --git a/src/spicelib/devices/bjt/bjtdset.c b/src/spicelib/devices/bjt/bjtdset.c index 884c95390..89c4af610 100644 --- a/src/spicelib/devices/bjt/bjtdset.c +++ b/src/spicelib/devices/bjt/bjtdset.c @@ -28,9 +28,9 @@ BJTdSetup(GENmodel *inModel, CKTcircuit *ckt) double arg; double c2; double c4; - double lcapbe1,lcapbe2,lcapbe3; - double lcapbx1,lcapbx2,lcapbx3; - double cb; + double lcapbe1, lcapbe2, lcapbe3; + double lcapbx1, lcapbx2, lcapbx3; + double cb = 0; double cbc; double cbcn; double cbe; @@ -54,16 +54,16 @@ BJTdSetup(GENmodel *inModel, CKTcircuit *ckt) double f3; double fcpc; double fcpe; - double gbb1; + double gbb1 = 0; double gbc; double gbcn; double gbe; - double gbe2,gbe3; + double gbe2, gbe3; double gbc2,gbc3; double gben2,gben3; double gbcn2,gbcn3; double gben; - double gbb2, gbb3; + double gbb2 = 0, gbb3 = 0; double oik; double oikr; double ovtf; diff --git a/src/spicelib/devices/bjt/bjtinit.c b/src/spicelib/devices/bjt/bjtinit.c index ffd8ecca3..3cab0bcbd 100644 --- a/src/spicelib/devices/bjt/bjtinit.c +++ b/src/spicelib/devices/bjt/bjtinit.c @@ -7,23 +7,39 @@ #include "bjtinit.h" -SPICEdev BJTinfo = { +SPICEdev BJTinfo = { /* description from struct IFdevice */ { - "BJT", - "Bipolar Junction Transistor", + "BJT", /* char *name */ + "Bipolar Junction Transistor", /* char *description */ + + &BJTnSize, /* int *terms */ + &BJTnSize, /* int *numNames */ + BJTnames, /* char **termnames */ + + &BJTpTSize, /* int *numInstanceparms */ + BJTpTable, /* IFparm *instanceParms */ + + &BJTmPTSize, /* int *numModelparms */ + BJTmPTable, /* IFparm *modelParms */ - &BJTnSize, - &BJTnSize, - BJTnames, +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ - &BJTpTSize, - BJTpTable, + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ - &BJTmPTSize, - BJTmPTable, - DEV_DEFAULT + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + + DEV_DEFAULT /* int flags */ }, - + DEVparam : BJTparam, DEVmodParam : BJTmParam, DEVload : BJTload, diff --git a/src/spicelib/devices/bjt/bjtload.c b/src/spicelib/devices/bjt/bjtload.c index 8868fa7b4..226547ea2 100644 --- a/src/spicelib/devices/bjt/bjtload.c +++ b/src/spicelib/devices/bjt/bjtload.c @@ -114,9 +114,9 @@ BJTload(inModel,ckt) double tr; double vbc; double vbe; - double vbx; + double vbx=0; double vce; - double vcs; + double vcs=0; double vt; double vtc; double vte; diff --git a/src/spicelib/devices/bsim1/Makefile.am b/src/spicelib/devices/bsim1/Makefile.am index 70ad8239a..73fc90f76 100644 --- a/src/spicelib/devices/bsim1/Makefile.am +++ b/src/spicelib/devices/bsim1/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libbsim1.la +noinst_LIBRARIES = libbsim1.a -libbsim1_la_SOURCES = \ +libbsim1_a_SOURCES = \ b1.c \ b1acld.c \ b1ask.c \ diff --git a/src/spicelib/devices/bsim1/bsim1init.c b/src/spicelib/devices/bsim1/bsim1init.c index 2a23bc028..b0ae16bbe 100644 --- a/src/spicelib/devices/bsim1/bsim1init.c +++ b/src/spicelib/devices/bsim1/bsim1init.c @@ -21,6 +21,22 @@ SPICEdev B1info = { &B1mPTSize, B1mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/bsim2/Makefile.am b/src/spicelib/devices/bsim2/Makefile.am index e30a04bf4..886255fbc 100644 --- a/src/spicelib/devices/bsim2/Makefile.am +++ b/src/spicelib/devices/bsim2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libbsim2.la +noinst_LIBRARIES = libbsim2.a -libbsim2_la_SOURCES = \ +libbsim2_a_SOURCES = \ b2.c \ b2acld.c \ b2ask.c \ diff --git a/src/spicelib/devices/bsim2/bsim2init.c b/src/spicelib/devices/bsim2/bsim2init.c index 92c44dc35..8d139fe57 100644 --- a/src/spicelib/devices/bsim2/bsim2init.c +++ b/src/spicelib/devices/bsim2/bsim2init.c @@ -21,6 +21,22 @@ SPICEdev B2info = { &B2mPTSize, B2mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/bsim3/Makefile.am b/src/spicelib/devices/bsim3/Makefile.am index fa3ed4ec1..3efd7a2fa 100644 --- a/src/spicelib/devices/bsim3/Makefile.am +++ b/src/spicelib/devices/bsim3/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libbsim3.la +noinst_LIBRARIES = libbsim3.a -libbsim3_la_SOURCES = \ +libbsim3_a_SOURCES = \ b3.c \ b3acld.c \ b3ask.c \ diff --git a/src/spicelib/devices/bsim3/b3temp.c b/src/spicelib/devices/bsim3/b3temp.c index 2fe8580a1..077066e46 100644 --- a/src/spicelib/devices/bsim3/b3temp.c +++ b/src/spicelib/devices/bsim3/b3temp.c @@ -56,6 +56,8 @@ int Size_Not_Found; { model->BSIM3GatesidewallJctPotential = 0.1; fprintf(stderr, "Given pbswg is less than 0.1. Pbswg is set to 0.1.\n"); } + /* va: was memory leakage - free old node, (or better use again?) */ + FREE(model->pSizeDependParamKnot); model->pSizeDependParamKnot = NULL; pLastKnot = NULL; @@ -788,6 +790,11 @@ int Size_Not_Found; * pParam->BSIM3sqrtPhi; /* End of vfbzb */ } + else /* !Size_Not_Found */ + { + /* va: pParam might be uninitialized, if !Size_Not_Found */ + pParam = here->pParam; + } /* process source/drain series resistance */ here->BSIM3drainConductance = model->BSIM3sheetResistance diff --git a/src/spicelib/devices/bsim3/bsim3init.c b/src/spicelib/devices/bsim3/bsim3init.c index 9afd8ee9f..5efbcbcb1 100644 --- a/src/spicelib/devices/bsim3/bsim3init.c +++ b/src/spicelib/devices/bsim3/bsim3init.c @@ -20,6 +20,22 @@ SPICEdev BSIM3info = { &BSIM3mPTSize, BSIM3mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/bsim3soi_dd/Makefile.am b/src/spicelib/devices/bsim3soi_dd/Makefile.am index 7dd8b444c..b25219734 100644 --- a/src/spicelib/devices/bsim3soi_dd/Makefile.am +++ b/src/spicelib/devices/bsim3soi_dd/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libbsim3soidd.la +noinst_LIBRARIES = libbsim3soidd.a -libbsim3soidd_la_SOURCES = \ +libbsim3soidd_a_SOURCES = \ b3soidd.c \ b3soiddacld.c \ b3soiddask.c \ diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c index 3d96f0879..e84560ab1 100644 --- a/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c @@ -19,6 +19,22 @@ SPICEdev B3SOIDDinfo = { &B3SOIDDmPTSize, B3SOIDDmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT} , @@ -54,7 +70,7 @@ DEVmodSize: &B3SOIDDmSize }; SPICEdev * -get_b3soidd_info (void) +get_bsim3soidd_info (void) { return &B3SOIDDinfo; } diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidditf.h b/src/spicelib/devices/bsim3soi_dd/b3soidditf.h index f2adf8593..cb7ee9faf 100644 --- a/src/spicelib/devices/bsim3soi_dd/b3soidditf.h +++ b/src/spicelib/devices/bsim3soi_dd/b3soidditf.h @@ -9,6 +9,6 @@ File: b3soidditf.h #include "b3soiddext.h" -SPICEdev *get_b3soidd_info (void); +SPICEdev *get_bsim3soidd_info (void); #endif diff --git a/src/spicelib/devices/bsim3soi_fd/Makefile.am b/src/spicelib/devices/bsim3soi_fd/Makefile.am index bc6b3a2f1..39a29352a 100644 --- a/src/spicelib/devices/bsim3soi_fd/Makefile.am +++ b/src/spicelib/devices/bsim3soi_fd/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libbsim3soifd.la +noinst_LIBRARIES = libbsim3soifd.a -libbsim3soifd_la_SOURCES = \ +libbsim3soifd_a_SOURCES = \ b3soifd.c \ b3soifdacld.c \ b3soifdask.c \ diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdinit.c b/src/spicelib/devices/bsim3soi_fd/b3soifdinit.c index f1860cff0..67211c731 100644 --- a/src/spicelib/devices/bsim3soi_fd/b3soifdinit.c +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdinit.c @@ -19,6 +19,22 @@ SPICEdev B3SOIFDinfo = { &B3SOIFDmPTSize, B3SOIFDmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT} , @@ -59,7 +75,7 @@ DEVmodSize: &B3SOIFDmSize SPICEdev * -get_b3soifd_info (void) +get_bsim3soifd_info (void) { return &B3SOIFDinfo; } diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifditf.h b/src/spicelib/devices/bsim3soi_fd/b3soifditf.h index 1228aff59..5c4f4f2d0 100644 --- a/src/spicelib/devices/bsim3soi_fd/b3soifditf.h +++ b/src/spicelib/devices/bsim3soi_fd/b3soifditf.h @@ -8,7 +8,7 @@ File: b3soifditf.h #include "b3soifdext.h" -SPICEdev *get_b3soifd_info (void); +SPICEdev *get_bsim3soifd_info (void); #endif diff --git a/src/spicelib/devices/bsim3soi_pd/Makefile.am b/src/spicelib/devices/bsim3soi_pd/Makefile.am index 23ff43e8a..7d90a3d51 100644 --- a/src/spicelib/devices/bsim3soi_pd/Makefile.am +++ b/src/spicelib/devices/bsim3soi_pd/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libbsim3soipd.la +noinst_LIBRARIES = libbsim3soipd.a -libbsim3soipd_la_SOURCES = \ +libbsim3soipd_a_SOURCES = \ b3soipd.c \ b3soipdacld.c \ b3soipdask.c \ diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdinit.c b/src/spicelib/devices/bsim3soi_pd/b3soipdinit.c index b9fdc4606..58148348b 100644 --- a/src/spicelib/devices/bsim3soi_pd/b3soipdinit.c +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdinit.c @@ -20,6 +20,22 @@ SPICEdev B3SOIPDinfo = { &B3SOIPDmPTSize, B3SOIPDmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT} , @@ -56,7 +72,7 @@ DEVmodSize:&B3SOIPDmSize }; SPICEdev * -get_b3soipd_info (void) +get_bsim3soipd_info (void) { return &B3SOIPDinfo; } diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipditf.h b/src/spicelib/devices/bsim3soi_pd/b3soipditf.h index 2f5ce892f..2d2c6a987 100644 --- a/src/spicelib/devices/bsim3soi_pd/b3soipditf.h +++ b/src/spicelib/devices/bsim3soi_pd/b3soipditf.h @@ -8,6 +8,6 @@ File: b3soipditf.h #include "b3soipdext.h" -SPICEdev *get_b3soipd_info (void); +SPICEdev *get_bsim3soipd_info (void); #endif diff --git a/src/spicelib/devices/bsim3v1/Makefile.am b/src/spicelib/devices/bsim3v1/Makefile.am index 256fbd07b..96c18b12f 100644 --- a/src/spicelib/devices/bsim3v1/Makefile.am +++ b/src/spicelib/devices/bsim3v1/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libbsim3v1.la +noinst_LIBRARIES = libbsim3v1.a -libbsim3v1_la_SOURCES = \ +libbsim3v1_a_SOURCES = \ b3v1.c \ b3v1acld.c \ b3v1ask.c \ diff --git a/src/spicelib/devices/bsim3v1/bsim3v1init.c b/src/spicelib/devices/bsim3v1/bsim3v1init.c index 5adacdfea..60af2d9a2 100644 --- a/src/spicelib/devices/bsim3v1/bsim3v1init.c +++ b/src/spicelib/devices/bsim3v1/bsim3v1init.c @@ -21,6 +21,22 @@ SPICEdev BSIM3V1info = { &BSIM3V1mPTSize, BSIM3V1mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT, }, diff --git a/src/spicelib/devices/bsim3v2/Makefile.am b/src/spicelib/devices/bsim3v2/Makefile.am index 19ef09e8a..7de6dd908 100644 --- a/src/spicelib/devices/bsim3v2/Makefile.am +++ b/src/spicelib/devices/bsim3v2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libbsim3v2.la +noinst_LIBRARIES = libbsim3v2.a -libbsim3v2_la_SOURCES = \ +libbsim3v2_a_SOURCES = \ b3v2.c \ b3v2acld.c \ b3v2ask.c \ diff --git a/src/spicelib/devices/bsim3v2/bsim3v2init.c b/src/spicelib/devices/bsim3v2/bsim3v2init.c index 4a82a3901..e47c492cd 100644 --- a/src/spicelib/devices/bsim3v2/bsim3v2init.c +++ b/src/spicelib/devices/bsim3v2/bsim3v2init.c @@ -20,7 +20,23 @@ SPICEdev BSIM3V2info = { &BSIM3V2mPTSize, BSIM3V2mPTable, - DEV_DEFAULT + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + + DEV_DEFAULT }, DEVparam : BSIM3V2param, diff --git a/src/spicelib/devices/bsim4/Makefile.am b/src/spicelib/devices/bsim4/Makefile.am index f5e3b51ee..c9bf85550 100644 --- a/src/spicelib/devices/bsim4/Makefile.am +++ b/src/spicelib/devices/bsim4/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libbsim4.la +noinst_LIBRARIES = libbsim4.a -libbsim4_la_SOURCES = \ +libbsim4_a_SOURCES = \ b4.c \ b4acld.c \ b4ask.c \ diff --git a/src/spicelib/devices/bsim4/bsim4init.c b/src/spicelib/devices/bsim4/bsim4init.c index 6d906ef90..35f7a01ee 100644 --- a/src/spicelib/devices/bsim4/bsim4init.c +++ b/src/spicelib/devices/bsim4/bsim4init.c @@ -21,6 +21,22 @@ SPICEdev BSIM4info = { &BSIM4mPTSize, BSIM4mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/cap/Makefile.am b/src/spicelib/devices/cap/Makefile.am index 79545d4c4..f4c9d220c 100644 --- a/src/spicelib/devices/cap/Makefile.am +++ b/src/spicelib/devices/cap/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libcap.la +noinst_LIBRARIES = libcap.a -libcap_la_SOURCES = \ +libcap_a_SOURCES = \ cap.c \ capacld.c \ capask.c \ diff --git a/src/spicelib/devices/cap/capinit.c b/src/spicelib/devices/cap/capinit.c index 4954d563b..ec9352318 100644 --- a/src/spicelib/devices/cap/capinit.c +++ b/src/spicelib/devices/cap/capinit.c @@ -20,6 +20,22 @@ SPICEdev CAPinfo = { &CAPmPTSize, CAPmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + 0 }, diff --git a/src/spicelib/devices/cccs/Makefile.am b/src/spicelib/devices/cccs/Makefile.am index 97ad77d9e..f0757d68c 100644 --- a/src/spicelib/devices/cccs/Makefile.am +++ b/src/spicelib/devices/cccs/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libcccs.la +noinst_LIBRARIES = libcccs.a -libcccs_la_SOURCES = \ +libcccs_a_SOURCES = \ cccs.c \ cccsask.c \ cccsdefs.h \ diff --git a/src/spicelib/devices/cccs/cccsinit.c b/src/spicelib/devices/cccs/cccsinit.c index f061a39f2..b00123636 100644 --- a/src/spicelib/devices/cccs/cccsinit.c +++ b/src/spicelib/devices/cccs/cccsinit.c @@ -20,6 +20,22 @@ SPICEdev CCCSinfo = { 0, NULL, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/ccvs/Makefile.am b/src/spicelib/devices/ccvs/Makefile.am index 276650832..146db18de 100644 --- a/src/spicelib/devices/ccvs/Makefile.am +++ b/src/spicelib/devices/ccvs/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libccvs.la +noinst_LIBRARIES = libccvs.a -libccvs_la_SOURCES = \ +libccvs_a_SOURCES = \ ccvs.c \ ccvsask.c \ ccvsdefs.h \ diff --git a/src/spicelib/devices/ccvs/ccvsinit.c b/src/spicelib/devices/ccvs/ccvsinit.c index 1df05d896..03f643bbf 100644 --- a/src/spicelib/devices/ccvs/ccvsinit.c +++ b/src/spicelib/devices/ccvs/ccvsinit.c @@ -21,6 +21,22 @@ SPICEdev CCVSinfo = { 0, NULL, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/cktcrte.c b/src/spicelib/devices/cktcrte.c index 7afd64893..9ce11a073 100644 --- a/src/spicelib/devices/cktcrte.c +++ b/src/spicelib/devices/cktcrte.c @@ -17,16 +17,19 @@ Author: 1985 Thomas L. Quarles int CKTcrtElt(void *ckt, void *inModPtr, void **inInstPtr, IFuid name) { - GENinstance *instPtr = NULL; - GENmodel *modPtr=(GENmodel*)inModPtr; + GENinstance *instPtr = NULL; /* instPtr points to the data struct for per-instance data */ + GENmodel *modPtr = (GENmodel*)inModPtr; /* modPtr points to the data struct for per-model data */ + SPICEdev **DEVices; int error; int type; DEVices = devices(); - if((GENmodel *)modPtr==(GENmodel*)NULL) + + if( (GENmodel *)modPtr == (GENmodel*)NULL ) return E_NOMOD; - type = ((GENmodel*)modPtr)->GENmodType; + + type = ((GENmodel*)modPtr)->GENmodType; error = CKTfndDev(ckt, &type, (void**)&instPtr, name, inModPtr, (char *)NULL ); @@ -37,13 +40,21 @@ CKTcrtElt(void *ckt, void *inModPtr, void **inInstPtr, IFuid name) } else if (error != E_NODEV) return error; +#ifdef TRACE + /*------ SDB debug statement -------*/ + printf("In CKTcrtElt, about to tmalloc new model, type = %d. . . \n", type); +#endif + instPtr = (GENinstance *) tmalloc(*DEVices[type]->DEVinstSize); if (instPtr == (GENinstance *)NULL) return E_NOMEM; instPtr->GENname = name; - instPtr->GENmodPtr = modPtr; - instPtr->GENnextInstance = modPtr->GENinstances; + + instPtr->GENmodPtr = modPtr; + + instPtr->GENnextInstance = modPtr->GENinstances; + modPtr->GENinstances = instPtr; if(inInstPtr != NULL) diff --git a/src/spicelib/devices/cktinit.c b/src/spicelib/devices/cktinit.c index cb29e0b65..bfd7d966a 100644 --- a/src/spicelib/devices/cktinit.c +++ b/src/spicelib/devices/cktinit.c @@ -9,20 +9,28 @@ Modifed: 2000 AlansFixes #include #include +#include #include +#include +#include +#include +#ifdef XSPICE +/* gtri - add - wbk - 11/26/90 - add include for MIF global data */ +#include "mif.h" +/* gtri - end - wbk - 11/26/90 */ +#endif int CKTinit(void **ckt) /* new circuit to create */ { + extern void load_alldevs(void); int i; CKTcircuit *sckt; - *ckt = (void *) tmalloc(sizeof(CKTcircuit)); sckt = (CKTcircuit *)(*ckt); if (sckt == NULL) return(E_NOMEM); - /* gtri - begin - dynamically allocate the array of model lists */ /* CKThead used to be statically sized in CKTdefs.h, but has been changed */ /* to a ** pointer */ @@ -76,5 +84,43 @@ CKTinit(void **ckt) /* new circuit to create */ sckt->CKTabsDv = 0.5; sckt->CKTrelDv = 2.0; +#ifdef XSPICE +/* gtri - begin - wbk - allocate/initialize substructs */ + + /* Allocate evt data structure */ + (sckt)->evt = (void *) MALLOC(sizeof(Evt_Ckt_Data_t)); + if(! (sckt)->evt) + return(E_NOMEM); + + /* Initialize options data */ + (sckt)->evt->options.op_alternate = MIF_TRUE; + + /* Allocate enh data structure */ + (sckt)->enh = (void *) MALLOC(sizeof(Enh_Ckt_Data_t)); + if(! (sckt)->enh) + return(E_NOMEM); + + /* Initialize non-zero, non-NULL data */ + (sckt)->enh->breakpoint.current = 1.0e30; + (sckt)->enh->breakpoint.last = 1.0e30; + (sckt)->enh->ramp.ramptime = 0.0; + (sckt)->enh->conv_limit.enabled = MIF_TRUE; + (sckt)->enh->conv_limit.step = 0.25; + (sckt)->enh->conv_limit.abs_step = 0.1; + (sckt)->enh->rshunt_data.enabled = MIF_FALSE; + +/* gtri - end - wbk - allocate/initialize substructs */ + +/* gtri - add - wbk - 01/12/91 - initialize g_mif_info */ + g_mif_info.circuit.init = MIF_TRUE; + g_mif_info.circuit.anal_init = MIF_TRUE; + g_mif_info.circuit.anal_type = MIF_DC; + g_mif_info.instance = NULL; + g_mif_info.ckt = sckt; + g_mif_info.errmsg = NULL; + g_mif_info.auto_partial.global = MIF_FALSE; + g_mif_info.auto_partial.local = MIF_FALSE; +/* gtri - end - wbk - 01/12/91 */ +#endif return OK; } diff --git a/src/spicelib/devices/csw/Makefile.am b/src/spicelib/devices/csw/Makefile.am index ba1cf6364..0b7fe6b26 100644 --- a/src/spicelib/devices/csw/Makefile.am +++ b/src/spicelib/devices/csw/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libcsw.la +noinst_LIBRARIES = libcsw.a -libcsw_la_SOURCES = \ +libcsw_a_SOURCES = \ csw.c \ cswacld.c \ cswask.c \ diff --git a/src/spicelib/devices/csw/cswinit.c b/src/spicelib/devices/csw/cswinit.c index ee8d05852..bdb43009c 100644 --- a/src/spicelib/devices/csw/cswinit.c +++ b/src/spicelib/devices/csw/cswinit.c @@ -23,6 +23,22 @@ SPICEdev CSWinfo = { &CSWmPTSize, CSWmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + 0 }, diff --git a/src/spicelib/devices/dev.c b/src/spicelib/devices/dev.c index e1deb61a4..aed7ed36e 100644 --- a/src/spicelib/devices/dev.c +++ b/src/spicelib/devices/dev.c @@ -34,6 +34,24 @@ #include #include "dev.h" +#include "memory.h" /* to alloc, realloc devices*/ + +#ifdef XSPICE +/*saj headers for xspice*/ +#include /* for strcpy, strcat*/ +#include /* to load librarys*/ +#include "dllitf.h" /* the coreInfo Structure*/ +#include "evtudn.h" /*Use defined nodes */ + +Evt_Udn_Info_t **g_evt_udn_info = NULL; +int g_evt_num_udn_types = 0; + +/*The digital node type */ +extern Evt_Udn_Info_t idn_digital_info; + +int add_udn(int,Evt_Udn_Info_t **); +/*saj*/ +#endif #define DEVICES_USED "asrc bjt bjt2 bsim1 bsim2 bsim3 bsim3v2 bsim3v1 bsim4 bsim3soipd bsim3soifd \ bsim3soidd cap cccs ccvs csw dio hfet hfet2 ind isrc jfet ltra mes mesa mos1 \ @@ -87,31 +105,65 @@ #include "mos3/mos3itf.h" #include "mos6/mos6itf.h" #include "mos9/mos9itf.h" +#include "cpl/cplitf.h" #include "res/resitf.h" #include "soi3/soi3itf.h" #include "sw/switf.h" #include "tra/traitf.h" +#include "txl/txlitf.h" #include "urc/urcitf.h" #include "vccs/vccsitf.h" #include "vcvs/vcvsitf.h" #include "vsrc/vsrcitf.h" - +/*saj in xspice the DEVices size can be varied so DEVNUM is an int*/ #ifdef HAVE_EKV #include "ekv/ekvitf.h" -#define DEVNUM 41 - +#ifdef XSPICE +static int DEVNUM = 43; #else - -#define DEVNUM 40 +#define DEVNUM 43 +#endif +#else +#ifdef XSPICE +static int DEVNUM = 42; +#else +#define DEVNUM 42 +#endif #endif +/*Make this dynamic for later attempt to make all devices dynamic*/ +SPICEdev **DEVices=NULL; + +/*Flag to indicate that device type it is, + *0 = normal spice device + *1 = xspice device + */ +#ifdef XSPICE +int *DEVicesfl=NULL; +int DEVflag(int type){ + if(type < DEVNUM && type >= 0) + return DEVicesfl[type]; + else + return -1; +} +#endif -SPICEdev *DEVices[DEVNUM]; void spice_init_devices(void) { +#ifdef XSPICE + /*Initilise the structs and add digital node type */ + g_evt_udn_info = (Evt_Udn_Info_t **)MALLOC(sizeof(Evt_Udn_Info_t *)); + g_evt_num_udn_types = 1; + g_evt_udn_info[0] = &idn_digital_info; + + DEVicesfl = (int *)tmalloc(DEVNUM*sizeof(int)); + /* tmalloc should automaticlly zero the array! */ +#endif + + DEVices = (SPICEdev **)tmalloc(DEVNUM*sizeof(SPICEdev *)); /* URC device MUST precede both resistors and capacitors */ DEVices[ 0] = get_urc_info(); DEVices[ 1] = get_asrc_info(); @@ -124,42 +176,46 @@ spice_init_devices(void) DEVices[ 7] = get_bsim3v1_info(); DEVices[ 8] = get_bsim3v2_info(); DEVices[ 9] = get_bsim4_info(); - DEVices[10] = get_b3soipd_info(); - DEVices[11] = get_b3soifd_info(); - DEVices[12] = get_b3soidd_info(); + DEVices[10] = get_bsim3soipd_info(); + DEVices[11] = get_bsim3soifd_info(); + DEVices[12] = get_bsim3soidd_info(); DEVices[13] = get_cap_info(); DEVices[14] = get_cccs_info(); DEVices[15] = get_ccvs_info(); - DEVices[16] = get_csw_info(); - DEVices[17] = get_dio_info(); - DEVices[18] = get_hfeta_info(); - DEVices[19] = get_hfet2_info(); - DEVices[20] = get_ind_info(); - DEVices[21] = get_mut_info(); - DEVices[22] = get_isrc_info(); - DEVices[23] = get_jfet_info(); - DEVices[24] = get_jfet2_info(); - DEVices[25] = get_ltra_info(); - DEVices[26] = get_mes_info(); - DEVices[27] = get_mesa_info(); - DEVices[28] = get_mos1_info(); - DEVices[29] = get_mos2_info(); - DEVices[30] = get_mos3_info(); - DEVices[31] = get_mos6_info(); - DEVices[32] = get_mos9_info(); - DEVices[33] = get_res_info(); - DEVices[34] = get_soi3_info(); - DEVices[35] = get_sw_info(); - DEVices[36] = get_tra_info(); - DEVices[37] = get_vccs_info(); - DEVices[38] = get_vcvs_info(); - DEVices[39] = get_vsrc_info(); + DEVices[16] = get_cpl_info(); + DEVices[17] = get_csw_info(); + DEVices[18] = get_dio_info(); + DEVices[19] = get_hfeta_info(); + DEVices[20] = get_hfet2_info(); + DEVices[21] = get_ind_info(); + DEVices[22] = get_mut_info(); + DEVices[23] = get_isrc_info(); + DEVices[24] = get_jfet_info(); + DEVices[25] = get_jfet2_info(); + DEVices[26] = get_ltra_info(); + DEVices[27] = get_mes_info(); + DEVices[28] = get_mesa_info(); + DEVices[29] = get_mos1_info(); + DEVices[30] = get_mos2_info(); + DEVices[31] = get_mos3_info(); + DEVices[32] = get_mos6_info(); + DEVices[33] = get_mos9_info(); + DEVices[34] = get_res_info(); + DEVices[35] = get_soi3_info(); + DEVices[36] = get_sw_info(); + DEVices[37] = get_tra_info(); + DEVices[38] = get_txl_info(); + DEVices[39] = get_vccs_info(); + DEVices[40] = get_vcvs_info(); + DEVices[41] = get_vsrc_info(); + #ifdef HAVE_EKV - DEVices[40] = get_ekv_info(); - assert(41 == DEVNUM); + DEVices[42] = get_ekv_info(); + assert(43 == DEVNUM); #else - assert(40 == DEVNUM); + assert(42 == DEVNUM); #endif +return; } @@ -183,6 +239,195 @@ devices(void) return DEVices; } +#ifdef DEVLIB +/*not yet usable*/ +#ifdef HAVE_EKV +#define DEVICES_USED {"asrc", "bjt", "bjt2", "bsim1", "bsim2", "bsim3", "bsim3v2", "bsim3v1", "bsim4", "bsim3soipd", "bsim3soifd", \ + "bsim3soidd", "cap", "cccs", "ccvs", "csw", "dio", "hfet", "hfet2", "ind", "isrc", "jfet", "ltra", "mes", "mesa" ,"mos1", \ + "mos2", "mos3", "mos6", "mos9", "res", "soi3", "sw", "tra", "urc", "vccs", "vcvs", "vsrc", "ekv" } +#else +#define DEVICES_USED {"asrc", "bjt", "bjt2", "bsim1", "bsim2", "bsim3", "bsim3v2", "bsim3v1", "bsim4", "bsim3soipd", "bsim3soifd", \ + "bsim3soidd", "cap", "cccs", "ccvs", "csw", "dio", "hfet", "hfet2", "ind", "isrc", "jfet", "ltra", "mes", "mesa" ,"mos1", \ + "mos2", "mos3", "mos6", "mos9", "res", "soi3", "sw", "tra", "urc", "vccs", "vcvs", "vsrc"} +#endif +int load_dev(char *name) { + char *msg; + char libname[50]; + void *lib; + SPICEdev *(*fetch)(void)=NULL; + SPICEdev *device; + + strcpy(libname, "lib"); + strcat(libname,name); + strcat(libname,".so"); + + lib = dlopen(libname,RTLD_NOW); + if(!lib){ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + strcpy(libname, "get_"); + strcat(libname,name); + strcat(libname,"_info"); + fetch = dlsym(lib,libname); + + if(!fetch){ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + device = fetch(); + add_device(1,&device,0); + return 0; +} + +void load_alldevs(void){ + char *devs[] = DEVICES_USED; + int num = sizeof(devs)/sizeof(char *); + int i; + for(i=0; i< num;i++) + load_dev(devs[i]); + return; +} +#endif + +/*-------------------- XSPICE additions below ----------------------*/ +#ifdef XSPICE +#include +#include +#include +#include /*for ft_sim*/ +#include /*for DEVmaxnum*/ + +static void relink() { + /* added by SDB; DEVmaxnum is an external int defined in cktdefs.h */ + extern int DEVmaxnum; + +/* + * This replacement done by SDB on 6.11.2003 + * + * ft_sim->numDevices = num_devices(); + * DEVmaxnum = num_devices(); + */ + ft_sim->numDevices = DEVNUM; + DEVmaxnum = DEVNUM; + + ft_sim->devices = devices_ptr(); + return; +} + +int add_device(int n, SPICEdev **devs, int flag){ + int i; + DEVices = (SPICEdev **)trealloc(DEVices,(DEVNUM+n)*sizeof(SPICEdev *)); + DEVicesfl = (int *)trealloc(DEVicesfl,(DEVNUM+n)*sizeof(int)); + for(i = 0; i < n;i++){ + /*debug*/printf("Added device: %s\n",devs[i]->DEVpublic.name); + DEVices[DEVNUM+i] = devs[i]; + + /* added by SDB on 6.20.2003 */ + DEVices[DEVNUM+i]->DEVinstSize = &MIFiSize; + + DEVicesfl[DEVNUM+i] = flag; + } + DEVNUM += n; + relink(); + return 0; +} + +int add_udn(int n,Evt_Udn_Info_t **udns){ + int i; + g_evt_udn_info = (Evt_Udn_Info_t **)trealloc(g_evt_udn_info,(g_evt_num_udn_types+n)*sizeof(Evt_Udn_Info_t *)); + for(i = 0; i < n;i++){ + /*debug*/printf("Added udn: %s\n",udns[i]->name); + g_evt_udn_info[g_evt_num_udn_types+i] = udns[i]; + } + g_evt_num_udn_types += n; + return 0; +} + + +extern struct coreInfo_t coreInfo; + + +int load_opus(char *name){ + void *lib; + char *msg; + int *num=NULL; + struct coreInfo_t **core; + SPICEdev **devs; + Evt_Udn_Info_t **udns; + void *(*fetch)(void)=NULL; + + lib = dlopen(name,RTLD_NOW); + if(!lib){ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + fetch = dlsym(lib,"CMdevNum"); + if(fetch){ + num = (int *)(*fetch)(); + printf("Got %u devices.\n",*num); + fetch = NULL; + }else{ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + fetch = dlsym(lib,"CMdevs"); + if(fetch){ + devs = (SPICEdev **)(*fetch)(); + fetch = NULL; + }else{ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + fetch = dlsym(lib,"CMgetCoreItfPtr"); + if(fetch){ + core = (struct coreInfo_t **)(*fetch)(); + *core = &coreInfo; + fetch = NULL; + }else{ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + add_device(*num,devs,1); + + fetch = dlsym(lib,"CMudnNum"); + if(fetch){ + num = (int *)(*fetch)(); + printf("Got %u udns.\n",*num); + fetch = NULL; + }else{ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + fetch = dlsym(lib,"CMudns"); + if(fetch){ + udns = (Evt_Udn_Info_t **)(*fetch)(); + fetch = NULL; + }else{ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + add_udn(*num,udns); + + return 0; +} + +#endif +/*-------------------- end of XSPICE additions ----------------------*/ #ifdef __MINGW32__ @@ -231,4 +476,4 @@ isnan(double value) /* * end isnan.c */ -#endif \ No newline at end of file +#endif diff --git a/src/spicelib/devices/dev.h b/src/spicelib/devices/dev.h index 295f437cc..be6a07b03 100644 --- a/src/spicelib/devices/dev.h +++ b/src/spicelib/devices/dev.h @@ -6,6 +6,13 @@ void spice_init_devices(void); int num_devices(void); IFdevice **devices_ptr(void); SPICEdev **devices(void); - +#ifdef XSPICE +int load_opus(char *); +int DEVflag(int type); +#endif +#ifdef DEVLIB +void load_alldevs(void); +int load_dev(char *name); +#endif #endif diff --git a/src/spicelib/devices/dio/Makefile.am b/src/spicelib/devices/dio/Makefile.am index 6d96b7935..f73c31d89 100644 --- a/src/spicelib/devices/dio/Makefile.am +++ b/src/spicelib/devices/dio/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libdio.la +noinst_LIBRARIES = libdio.a -libdio_la_SOURCES = \ +libdio_a_SOURCES = \ dio.c \ dioacld.c \ dioask.c \ diff --git a/src/spicelib/devices/dio/dioinit.c b/src/spicelib/devices/dio/dioinit.c index b1d673ac8..f1df1ff4e 100644 --- a/src/spicelib/devices/dio/dioinit.c +++ b/src/spicelib/devices/dio/dioinit.c @@ -23,6 +23,22 @@ SPICEdev DIOinfo = { &DIOmPTSize, DIOmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/hfet1/Makefile.am b/src/spicelib/devices/hfet1/Makefile.am index 8d5ba5c2a..23291d981 100644 --- a/src/spicelib/devices/hfet1/Makefile.am +++ b/src/spicelib/devices/hfet1/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libhfet.la +noinst_LIBRARIES = libhfet.a -libhfet_la_SOURCES = \ +libhfet_a_SOURCES = \ hfet.c \ hfetacl.c \ hfetask.c \ diff --git a/src/spicelib/devices/hfet1/hfetinit.c b/src/spicelib/devices/hfet1/hfetinit.c index 345ce7047..eab29cdb0 100644 --- a/src/spicelib/devices/hfet1/hfetinit.c +++ b/src/spicelib/devices/hfet1/hfetinit.c @@ -21,6 +21,22 @@ SPICEdev HFETAinfo = { &HFETAmPTSize, HFETAmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/hfet2/Makefile.am b/src/spicelib/devices/hfet2/Makefile.am index 7ea86fa7b..e013a1a53 100644 --- a/src/spicelib/devices/hfet2/Makefile.am +++ b/src/spicelib/devices/hfet2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libhfet2.la +noinst_LIBRARIES = libhfet2.a -libhfet2_la_SOURCES = \ +libhfet2_a_SOURCES = \ hfet2.c \ hfet2acl.c \ hfet2ask.c \ diff --git a/src/spicelib/devices/hfet2/hfet2init.c b/src/spicelib/devices/hfet2/hfet2init.c index 55bfb6dd9..1c141a19d 100644 --- a/src/spicelib/devices/hfet2/hfet2init.c +++ b/src/spicelib/devices/hfet2/hfet2init.c @@ -21,6 +21,22 @@ SPICEdev HFET2info = { &HFET2mPTSize, HFET2mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/ind/Makefile.am b/src/spicelib/devices/ind/Makefile.am index e864492c2..abe6e9b6c 100644 --- a/src/spicelib/devices/ind/Makefile.am +++ b/src/spicelib/devices/ind/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libind.la +noinst_LIBRARIES = libind.a -libind_la_SOURCES = \ +libind_a_SOURCES = \ ind.c \ indacld.c \ indask.c \ diff --git a/src/spicelib/devices/ind/indinit.c b/src/spicelib/devices/ind/indinit.c index 7847de3e5..3bb334cad 100644 --- a/src/spicelib/devices/ind/indinit.c +++ b/src/spicelib/devices/ind/indinit.c @@ -21,6 +21,21 @@ SPICEdev INDinfo = { 0, NULL, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif 0 }, @@ -71,6 +86,22 @@ SPICEdev MUTinfo = { 0, NULL, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + 0 }, diff --git a/src/spicelib/devices/isrc/Makefile.am b/src/spicelib/devices/isrc/Makefile.am index 19a4882f1..db407b76a 100644 --- a/src/spicelib/devices/isrc/Makefile.am +++ b/src/spicelib/devices/isrc/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libisrc.la +noinst_LIBRARIES = libisrc.a -libisrc_la_SOURCES = \ +libisrc_a_SOURCES = \ isrc.c \ isrcacct.c \ isrcacld.c \ diff --git a/src/spicelib/devices/isrc/isrcinit.c b/src/spicelib/devices/isrc/isrcinit.c index 903288a80..535187d29 100644 --- a/src/spicelib/devices/isrc/isrcinit.c +++ b/src/spicelib/devices/isrc/isrcinit.c @@ -21,6 +21,22 @@ SPICEdev ISRCinfo = { 0, NULL, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/jfet/Makefile.am b/src/spicelib/devices/jfet/Makefile.am index fb69c4940..78c4ed50e 100644 --- a/src/spicelib/devices/jfet/Makefile.am +++ b/src/spicelib/devices/jfet/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libjfet.la +noinst_LIBRARIES = libjfet.a -libjfet_la_SOURCES = \ +libjfet_a_SOURCES = \ jfet.c \ jfetacld.c \ jfetask.c \ diff --git a/src/spicelib/devices/jfet/jfetinit.c b/src/spicelib/devices/jfet/jfetinit.c index 77d169a56..805a3305c 100644 --- a/src/spicelib/devices/jfet/jfetinit.c +++ b/src/spicelib/devices/jfet/jfetinit.c @@ -21,6 +21,22 @@ SPICEdev JFETinfo = { &JFETmPTSize, JFETmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/jfet2/Makefile.am b/src/spicelib/devices/jfet2/Makefile.am index 73beb344e..b564836e5 100644 --- a/src/spicelib/devices/jfet2/Makefile.am +++ b/src/spicelib/devices/jfet2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libjfet2.la +noinst_LIBRARIES = libjfet2.a -libjfet2_la_SOURCES = \ +libjfet2_a_SOURCES = \ jfet2.c \ jfet2acld.c \ jfet2ask.c \ diff --git a/src/spicelib/devices/jfet2/jfet2init.c b/src/spicelib/devices/jfet2/jfet2init.c index 0b4f1ee84..506ba4779 100644 --- a/src/spicelib/devices/jfet2/jfet2init.c +++ b/src/spicelib/devices/jfet2/jfet2init.c @@ -21,6 +21,22 @@ SPICEdev JFET2info = { &JFET2mPTSize, JFET2mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/ltra/Makefile.am b/src/spicelib/devices/ltra/Makefile.am index fcd8ad18a..8324ffdb3 100644 --- a/src/spicelib/devices/ltra/Makefile.am +++ b/src/spicelib/devices/ltra/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libltra.la +noinst_LIBRARIES = libltra.a -libltra_la_SOURCES = \ +libltra_a_SOURCES = \ ltra.c \ ltraacct.c \ ltraacld.c \ diff --git a/src/spicelib/devices/ltra/ltrainit.c b/src/spicelib/devices/ltra/ltrainit.c index 5c62e3573..bd9e658fe 100644 --- a/src/spicelib/devices/ltra/ltrainit.c +++ b/src/spicelib/devices/ltra/ltrainit.c @@ -21,6 +21,22 @@ SPICEdev LTRAinfo = { <RAmPTSize, LTRAmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + 0 }, diff --git a/src/spicelib/devices/mes/Makefile.am b/src/spicelib/devices/mes/Makefile.am index bb2bcf82d..db36235c6 100644 --- a/src/spicelib/devices/mes/Makefile.am +++ b/src/spicelib/devices/mes/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libmes.la +noinst_LIBRARIES = libmes.a -libmes_la_SOURCES = \ +libmes_a_SOURCES = \ mes.c \ mesacl.c \ mesask.c \ diff --git a/src/spicelib/devices/mes/mesinit.c b/src/spicelib/devices/mes/mesinit.c index 18abd8deb..fa100c20e 100644 --- a/src/spicelib/devices/mes/mesinit.c +++ b/src/spicelib/devices/mes/mesinit.c @@ -21,6 +21,22 @@ SPICEdev MESinfo = { &MESmPTSize, MESmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/mesa/Makefile.am b/src/spicelib/devices/mesa/Makefile.am index 1e5c48fed..d86d483be 100644 --- a/src/spicelib/devices/mesa/Makefile.am +++ b/src/spicelib/devices/mesa/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libmesa.la +noinst_LIBRARIES = libmesa.a -libmesa_la_SOURCES = \ +libmesa_a_SOURCES = \ mesa.c \ mesaacl.c \ mesaask.c \ diff --git a/src/spicelib/devices/mesa/mesainit.c b/src/spicelib/devices/mesa/mesainit.c index 5e1cc38ad..cd0b7f8b0 100644 --- a/src/spicelib/devices/mesa/mesainit.c +++ b/src/spicelib/devices/mesa/mesainit.c @@ -21,6 +21,22 @@ SPICEdev MESAinfo = { &MESAmPTSize, MESAmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/mos1/Makefile.am b/src/spicelib/devices/mos1/Makefile.am index 0bda56f8d..81f44026e 100644 --- a/src/spicelib/devices/mos1/Makefile.am +++ b/src/spicelib/devices/mos1/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libmos1.la +noinst_LIBRARIES = libmos1.a -libmos1_la_SOURCES = \ +libmos1_a_SOURCES = \ mos1.c \ mos1acld.c \ mos1ask.c \ diff --git a/src/spicelib/devices/mos1/mos1init.c b/src/spicelib/devices/mos1/mos1init.c index 915b65af0..23e10f624 100644 --- a/src/spicelib/devices/mos1/mos1init.c +++ b/src/spicelib/devices/mos1/mos1init.c @@ -21,6 +21,22 @@ SPICEdev MOS1info = { &MOS1mPTSize, MOS1mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/mos2/Makefile.am b/src/spicelib/devices/mos2/Makefile.am index e43de05a9..a307a789d 100644 --- a/src/spicelib/devices/mos2/Makefile.am +++ b/src/spicelib/devices/mos2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libmos2.la +noinst_LIBRARIES = libmos2.a -libmos2_la_SOURCES = \ +libmos2_a_SOURCES = \ mos2.c \ mos2acld.c \ mos2ask.c \ diff --git a/src/spicelib/devices/mos2/mos2init.c b/src/spicelib/devices/mos2/mos2init.c index 70fd535b0..3f58f6b14 100644 --- a/src/spicelib/devices/mos2/mos2init.c +++ b/src/spicelib/devices/mos2/mos2init.c @@ -21,6 +21,22 @@ SPICEdev MOS2info = { &MOS2mPTSize, MOS2mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/mos3/Makefile.am b/src/spicelib/devices/mos3/Makefile.am index ea4407ffa..c73d67bcb 100644 --- a/src/spicelib/devices/mos3/Makefile.am +++ b/src/spicelib/devices/mos3/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libmos3.la +noinst_LIBRARIES = libmos3.a -libmos3_la_SOURCES = \ +libmos3_a_SOURCES = \ mos3.c \ mos3acld.c \ mos3ask.c \ diff --git a/src/spicelib/devices/mos3/mos3init.c b/src/spicelib/devices/mos3/mos3init.c index 4c847b5f5..2f4a564f9 100644 --- a/src/spicelib/devices/mos3/mos3init.c +++ b/src/spicelib/devices/mos3/mos3init.c @@ -21,6 +21,22 @@ SPICEdev MOS3info = { &MOS3mPTSize, MOS3mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/mos6/Makefile.am b/src/spicelib/devices/mos6/Makefile.am index beaf1e061..c4367d188 100644 --- a/src/spicelib/devices/mos6/Makefile.am +++ b/src/spicelib/devices/mos6/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libmos6.la +noinst_LIBRARIES = libmos6.a -libmos6_la_SOURCES = \ +libmos6_a_SOURCES = \ mos6.c \ mos6ask.c \ mos6conv.c \ diff --git a/src/spicelib/devices/mos6/mos6init.c b/src/spicelib/devices/mos6/mos6init.c index 06c6e908f..3d7340bb9 100644 --- a/src/spicelib/devices/mos6/mos6init.c +++ b/src/spicelib/devices/mos6/mos6init.c @@ -21,6 +21,22 @@ SPICEdev MOS6info = { &MOS6mPTSize, MOS6mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/mos9/Makefile.am b/src/spicelib/devices/mos9/Makefile.am index 16d3d4359..1c3817268 100644 --- a/src/spicelib/devices/mos9/Makefile.am +++ b/src/spicelib/devices/mos9/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libmos9.la +noinst_LIBRARIES = libmos9.a -libmos9_la_SOURCES = \ +libmos9_a_SOURCES = \ mos9.c \ mos9acld.c \ mos9ask.c \ diff --git a/src/spicelib/devices/mos9/mos9init.c b/src/spicelib/devices/mos9/mos9init.c index 7f5b9a6ac..b6bd91d50 100644 --- a/src/spicelib/devices/mos9/mos9init.c +++ b/src/spicelib/devices/mos9/mos9init.c @@ -21,6 +21,22 @@ SPICEdev MOS9info = { &MOS9mPTSize, MOS9mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/mos9/mos9itf.h b/src/spicelib/devices/mos9/mos9itf.h index 26fbb3472..98c13c194 100644 --- a/src/spicelib/devices/mos9/mos9itf.h +++ b/src/spicelib/devices/mos9/mos9itf.h @@ -7,4 +7,4 @@ Copyright 1990 Regents of the University of California. All rights reserved. SPICEdev *get_mos9_info(void); -#endif \ No newline at end of file +#endif diff --git a/src/spicelib/devices/res/Makefile.am b/src/spicelib/devices/res/Makefile.am index 1b6abeab7..b37d40cc2 100644 --- a/src/spicelib/devices/res/Makefile.am +++ b/src/spicelib/devices/res/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libres.la +noinst_LIBRARIES = libres.a -libres_la_SOURCES = \ +libres_a_SOURCES = \ res.c \ resask.c \ resdefs.h \ diff --git a/src/spicelib/devices/res/resinit.c b/src/spicelib/devices/res/resinit.c index d7780225e..d731b07b8 100644 --- a/src/spicelib/devices/res/resinit.c +++ b/src/spicelib/devices/res/resinit.c @@ -21,6 +21,22 @@ SPICEdev RESinfo = { &RESmPTSize, RESmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + 0 }, diff --git a/src/spicelib/devices/soi3/Makefile.am b/src/spicelib/devices/soi3/Makefile.am index 1cadd6d21..d90f63961 100644 --- a/src/spicelib/devices/soi3/Makefile.am +++ b/src/spicelib/devices/soi3/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libsoi3.la +noinst_LIBRARIES = libsoi3.a -libsoi3_la_SOURCES = \ +libsoi3_a_SOURCES = \ soi3.c \ soi3acld.c \ soi3ask.c \ diff --git a/src/spicelib/devices/soi3/soi3init.c b/src/spicelib/devices/soi3/soi3init.c index 3a9744878..730055f6b 100644 --- a/src/spicelib/devices/soi3/soi3init.c +++ b/src/spicelib/devices/soi3/soi3init.c @@ -21,6 +21,22 @@ SPICEdev SOI3info = { &SOI3mPTSize, SOI3mPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/sw/Makefile.am b/src/spicelib/devices/sw/Makefile.am index f4236ee5c..5960e5abf 100644 --- a/src/spicelib/devices/sw/Makefile.am +++ b/src/spicelib/devices/sw/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libsw.la +noinst_LIBRARIES = libsw.a -libsw_la_SOURCES = \ +libsw_a_SOURCES = \ sw.c \ swacload.c \ swask.c \ diff --git a/src/spicelib/devices/sw/swinit.c b/src/spicelib/devices/sw/swinit.c index 0e2bdd381..1162d738c 100644 --- a/src/spicelib/devices/sw/swinit.c +++ b/src/spicelib/devices/sw/swinit.c @@ -22,6 +22,22 @@ SPICEdev SWinfo = { &SWmPTSize, SWmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + 0 }, diff --git a/src/spicelib/devices/tra/Makefile.am b/src/spicelib/devices/tra/Makefile.am index 8eed1f73d..8ea816a30 100644 --- a/src/spicelib/devices/tra/Makefile.am +++ b/src/spicelib/devices/tra/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libtra.la +noinst_LIBRARIES = libtra.a -libtra_la_SOURCES = \ +libtra_a_SOURCES = \ tra.c \ traacct.c \ traacld.c \ diff --git a/src/spicelib/devices/tra/trainit.c b/src/spicelib/devices/tra/trainit.c index 8159d0b6e..fc5fc932b 100644 --- a/src/spicelib/devices/tra/trainit.c +++ b/src/spicelib/devices/tra/trainit.c @@ -21,6 +21,22 @@ SPICEdev TRAinfo = { 0, NULL, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + 0 }, diff --git a/src/spicelib/devices/urc/Makefile.am b/src/spicelib/devices/urc/Makefile.am index b5de9045c..4a60136b3 100644 --- a/src/spicelib/devices/urc/Makefile.am +++ b/src/spicelib/devices/urc/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = liburc.la +noinst_LIBRARIES = liburc.a -liburc_la_SOURCES = \ +liburc_a_SOURCES = \ urc.c \ urcask.c \ urcdefs.h \ diff --git a/src/spicelib/devices/urc/urcinit.c b/src/spicelib/devices/urc/urcinit.c index b28c413db..938331f93 100644 --- a/src/spicelib/devices/urc/urcinit.c +++ b/src/spicelib/devices/urc/urcinit.c @@ -21,6 +21,22 @@ SPICEdev URCinfo = { &URCmPTSize, URCmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + 0 }, diff --git a/src/spicelib/devices/vccs/Makefile.am b/src/spicelib/devices/vccs/Makefile.am index 34a64e6ef..59ef5e385 100644 --- a/src/spicelib/devices/vccs/Makefile.am +++ b/src/spicelib/devices/vccs/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libvccs.la +noinst_LIBRARIES = libvccs.a -libvccs_la_SOURCES = \ +libvccs_a_SOURCES = \ vccs.c \ vccsask.c \ vccsdefs.h \ diff --git a/src/spicelib/devices/vccs/vccsinit.c b/src/spicelib/devices/vccs/vccsinit.c index 65b5504ac..5c008b9ed 100644 --- a/src/spicelib/devices/vccs/vccsinit.c +++ b/src/spicelib/devices/vccs/vccsinit.c @@ -21,6 +21,22 @@ SPICEdev VCCSinfo = { 0, NULL, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/vcvs/Makefile.am b/src/spicelib/devices/vcvs/Makefile.am index caff738c7..8da46ea46 100644 --- a/src/spicelib/devices/vcvs/Makefile.am +++ b/src/spicelib/devices/vcvs/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libvcvs.la +noinst_LIBRARIES = libvcvs.a -libvcvs_la_SOURCES = \ +libvcvs_a_SOURCES = \ vcvs.c \ vcvsask.c \ vcvsdefs.h \ diff --git a/src/spicelib/devices/vcvs/vcvsinit.c b/src/spicelib/devices/vcvs/vcvsinit.c index 6d3e29dae..7ae22f51c 100644 --- a/src/spicelib/devices/vcvs/vcvsinit.c +++ b/src/spicelib/devices/vcvs/vcvsinit.c @@ -21,6 +21,22 @@ SPICEdev VCVSinfo = { 0, NULL, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/devices/vsrc/Makefile.am b/src/spicelib/devices/vsrc/Makefile.am index 246577fc0..92ece971a 100644 --- a/src/spicelib/devices/vsrc/Makefile.am +++ b/src/spicelib/devices/vsrc/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -pkglib_LTLIBRARIES = libvsrc.la +noinst_LIBRARIES = libvsrc.a -libvsrc_la_SOURCES = \ +libvsrc_a_SOURCES = \ vsrc.c \ vsrcacct.c \ vsrcacld.c \ diff --git a/src/spicelib/devices/vsrc/vsrcinit.c b/src/spicelib/devices/vsrc/vsrcinit.c index 672ce4baa..055bda1e3 100644 --- a/src/spicelib/devices/vsrc/vsrcinit.c +++ b/src/spicelib/devices/vsrc/vsrcinit.c @@ -21,6 +21,22 @@ SPICEdev VSRCinfo = { 0, NULL, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + DEV_DEFAULT }, diff --git a/src/spicelib/parser/ChangeLog b/src/spicelib/parser/ChangeLog index 2a81fff41..61e2adfce 100644 --- a/src/spicelib/parser/ChangeLog +++ b/src/spicelib/parser/ChangeLog @@ -1,3 +1,8 @@ +2003.4.10 Stuart Brorson + * Cloned INPgetNetTok from INPgetTok in inpgtok.c + * Modified inpg2*.c to use INPgetNetTok for all netnames. + * Added explanatory comments to many files. + 2000-10-12 Arno W. Peters * inpeval.c: Bugfix for subcircuits contributed by Michael diff --git a/src/spicelib/parser/Makefile.am b/src/spicelib/parser/Makefile.am index 04336fd86..b38ce4c70 100644 --- a/src/spicelib/parser/Makefile.am +++ b/src/spicelib/parser/Makefile.am @@ -19,6 +19,7 @@ libinp_a_SOURCES = \ inp2l.c \ inp2m.c \ inp2o.c \ + inp2p.c \ inp2q.c \ inp2r.c \ inp2s.c \ @@ -26,6 +27,7 @@ libinp_a_SOURCES = \ inp2u.c \ inp2v.c \ inp2w.c \ + inp2y.c \ inp2z.c \ inpaname.c \ inpapnam.c \ diff --git a/src/spicelib/parser/ifnewuid.c b/src/spicelib/parser/ifnewuid.c index ee59dcc9c..fac0e5e8d 100644 --- a/src/spicelib/parser/ifnewuid.c +++ b/src/spicelib/parser/ifnewuid.c @@ -22,6 +22,7 @@ Author: 1988 Thomas L. Quarles #include "inp.h" +/* va: we should use tmalloc, whith also makes failure test */ int IFnewUid(void *ckt, IFuid * newuid, IFuid olduid, char *suffix, int type, void **nodedata) @@ -32,25 +33,18 @@ IFnewUid(void *ckt, IFuid * newuid, IFuid olduid, char *suffix, int type, if (olduid) { #ifdef HAVE_ASPRINTF asprintf(&newname, "%s#%s", (char *) olduid, suffix); -#else /* ~ HAVE_ASPRINTF */ - if ( (newname = (char *) malloc(strlen((char *) olduid) + - strlen(suffix) + 2)) /* 2 = strlen("#\0") */ - == NULL){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } +#else /* ~ HAVE_ASPRINTF */ + newname = (char *) tmalloc(strlen((char *) olduid) + + strlen(suffix) + 2); /* 2 = strlen("#\0") */ sprintf(newname, "%s#%s", (char *) olduid, suffix); -#endif /* HAVE_ASPRINTF */ - +#endif /* HAVE_ASPRINTF */ + } else { #ifdef HAVE_ASPRINTF asprintf(&newname, "%s", suffix); #else /* ~ HAVE_ASPRINTF */ - if ( (newname = (char *) malloc(strlen(suffix) + 2 )) == NULL){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } + newname = (char *) tmalloc(strlen(suffix) + 1 ); sprintf(newname, "%s", suffix); #endif /* HAVE_ASPRINTF */ } diff --git a/src/spicelib/parser/inp.h b/src/spicelib/parser/inp.h index 9d17b7bda..7de4abcde 100644 --- a/src/spicelib/parser/inp.h +++ b/src/spicelib/parser/inp.h @@ -32,6 +32,7 @@ void INP2K(void *ckt, INPtables *tab, card *current); void INP2L(void *ckt, INPtables *tab, card *current); void INP2M(void *ckt, INPtables *tab, card *current); void INP2O(void *ckt, INPtables *tab, card *current); +void INP2P(void *ckt, INPtables *tab, card *current); void INP2Q(void *ckt, INPtables *tab, card *current, void *gnode); void INP2R(void *ckt, INPtables *tab, card *current); void INP2S(void *ckt, INPtables *tab, card *current); @@ -39,6 +40,7 @@ void INP2T(void *ckt, INPtables *tab, card *current); void INP2U(void *ckt, INPtables *tab, card *current); void INP2V(void *ckt, INPtables *tab, card *current); void INP2W(void *ckt, INPtables *tab, card *current); +void INP2Y(void *ckt, INPtables *tab, card *current); void INP2Z(void *ckt, INPtables *tab, card *current); int INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode); diff --git a/src/spicelib/parser/inp2b.c b/src/spicelib/parser/inp2b.c index 8448ebeb7..209ba15e8 100644 --- a/src/spicelib/parser/inp2b.c +++ b/src/spicelib/parser/inp2b.c @@ -40,10 +40,10 @@ void INP2B(void *ckt, INPtables * tab, card * current) INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); error = INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); error = INPtermInsert(ckt, &nname2, tab, &node2); if (!tab->defBmod) { diff --git a/src/spicelib/parser/inp2c.c b/src/spicelib/parser/inp2c.c index c1f2ac855..3ca3b6b2c 100644 --- a/src/spicelib/parser/inp2c.c +++ b/src/spicelib/parser/inp2c.c @@ -44,9 +44,9 @@ void INP2C(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); val = INPevaluate(&line, &error, 1); if (error == 0) { /* Looks like a number */ diff --git a/src/spicelib/parser/inp2d.c b/src/spicelib/parser/inp2d.c index 2d65f4544..393fc375e 100644 --- a/src/spicelib/parser/inp2d.c +++ b/src/spicelib/parser/inp2d.c @@ -42,9 +42,9 @@ void INP2D(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); INPgetTok(&line, &model, 1); INPinsert(&model, tab); diff --git a/src/spicelib/parser/inp2dot.c b/src/spicelib/parser/inp2dot.c index ef7616664..3ccb8c1c0 100644 --- a/src/spicelib/parser/inp2dot.c +++ b/src/spicelib/parser/inp2dot.c @@ -57,13 +57,13 @@ dot_noise(char *line, void *ckt, INPtables *tab, card *current, length = strlen(name); if (((*name == 'V') || (*name == 'v')) && (length == 1)) { - INPgetTok(&line, &nname1, 0); + INPgetNetTok(&line, &nname1, 0); INPtermInsert(ckt, &nname1, tab, &node1); ptemp.nValue = (IFnode) node1; GCA(INPapName, (ckt, which, foo, "output", &ptemp)) if (*line != ')') { - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); ptemp.nValue = (IFnode) node2; } else { @@ -215,6 +215,7 @@ dot_ac(char *line, void *ckt, INPtables *tab, card *current, INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */ ptemp.iValue = 1; GCA(INPapName, (ckt, which, foo, steptype, &ptemp)); + tfree(steptype); parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* number of points */ GCA(INPapName, (ckt, which, foo, "numsteps", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */ @@ -306,11 +307,11 @@ dot_dc(char *line, void *ckt, INPtables *tab, card *current, INPinsert(&name, tab); ptemp.uValue = name; GCA(INPapName, (ckt, which, foo, "name2", &ptemp)); - parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstart1 */ + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstart2 */ GCA(INPapName, (ckt, which, foo, "start2", parm)); - parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstop1 */ + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstop2 */ GCA(INPapName, (ckt, which, foo, "stop2", parm)); - parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vinc1 */ + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vinc2 */ GCA(INPapName, (ckt, which, foo, "step2", parm)); } return 0; @@ -351,12 +352,12 @@ dot_tf(char *line, void *ckt, INPtables *tab, card *current, if (*line != '(' ) { /* error, bad input format */ } - INPgetTok(&line, &nname1, 0); + INPgetNetTok(&line, &nname1, 0); INPtermInsert(ckt, &nname1, tab, &node1); ptemp.nValue = (IFnode) node1; GCA(INPapName, (ckt, which, foo, "outpos", &ptemp)); if (*line != ')') { - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); ptemp.nValue = (IFnode) node2; GCA(INPapName, (ckt, which, foo, "outneg", &ptemp)); @@ -486,13 +487,13 @@ dot_sens(char *line, void *ckt, INPtables *tab, card *current, LITERR("Syntax error: '(' expected after 'v'\n"); return 0; } - INPgetTok(&line, &nname1, 0); + INPgetNetTok(&line, &nname1, 0); INPtermInsert(ckt, &nname1, tab, &node1); ptemp.nValue = (IFnode) node1; GCA(INPapName, (ckt, which, foo, "outpos", &ptemp)) if (*line != ')') { - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); ptemp.nValue = (IFnode) node2; GCA(INPapName, (ckt, which, foo, "outneg", &ptemp)); @@ -636,78 +637,93 @@ INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode) { /* . Many possibilities */ - char *token; /* a token from the line */ + char *token; /* a token from the line, tmalloc'ed */ void *foo = NULL; /* pointer to analysis */ /* the part of the current line left to parse */ char *line = current->line; - + int rtn = 0; + INPgetTok(&line, &token, 1); if (strcmp(token, ".model") == 0) { /* don't have to do anything, since models were all done in * pass 1 */ - return (0); + goto quit; } else if ((strcmp(token, ".width") == 0) || strcmp(token, ".print") == 0 || strcmp(token, ".plot") == 0) { /* obsolete - ignore */ LITERR(" Warning: obsolete control card - ignored \n"); - return (0); + goto quit; } else if ((strcmp(token, ".temp") == 0)) { /* .temp temp1 temp2 temp3 temp4 ..... */ /* not yet implemented - warn & ignore */ LITERR(" Warning: .TEMP card obsolete - use .options TEMP and TNOM\n"); - return (0); + goto quit; } else if ((strcmp(token, ".op") == 0)) { - return dot_op(line, ckt, tab, current, task, gnode, foo); + rtn = dot_op(line, ckt, tab, current, task, gnode, foo); + goto quit; } else if ((strcmp(token, ".nodeset") == 0)) { - return(0); + goto quit; } else if ((strcmp(token, ".disto") == 0)) { - return dot_disto(line, ckt, tab, current, task, gnode, foo); + rtn = dot_disto(line, ckt, tab, current, task, gnode, foo); + goto quit; } else if ((strcmp(token, ".noise") == 0)) { - return dot_noise(line, ckt, tab, current, task, gnode, foo); + rtn = dot_noise(line, ckt, tab, current, task, gnode, foo); + goto quit; } else if ((strcmp(token, ".four") == 0) || (strcmp(token, ".fourier") == 0)) { /* .four */ /* not implemented - warn & ignore */ LITERR("Use fourier command to obtain fourier analysis\n"); - return (0); + goto quit; } else if ((strcmp(token, ".ic") == 0)) { - return (0); + goto quit; } else if ((strcmp(token, ".ac") == 0)) { - return dot_ac(line, ckt, tab, current, task, gnode, foo); + rtn = dot_ac(line, ckt, tab, current, task, gnode, foo); + goto quit; } else if ((strcmp(token, ".pz") == 0)) { - return dot_pz(line, ckt, tab, current, task, gnode, foo); + rtn = dot_pz(line, ckt, tab, current, task, gnode, foo); + goto quit; } else if ((strcmp(token, ".dc") == 0)) { - return dot_dc(line, ckt, tab, current, task, gnode, foo); + rtn = dot_dc(line, ckt, tab, current, task, gnode, foo); + goto quit; } else if ((strcmp(token, ".tf") == 0)) { - return dot_tf(line, ckt, tab, current, task, gnode, foo); + rtn = dot_tf(line, ckt, tab, current, task, gnode, foo); + goto quit; } else if ((strcmp(token, ".tran") == 0)) { - return dot_tran(line, ckt, tab, current, task, gnode, foo); + rtn = dot_tran(line, ckt, tab, current, task, gnode, foo); + goto quit; } else if ((strcmp(token, ".subckt") == 0) || (strcmp(token, ".ends") == 0)) { /* not yet implemented - warn & ignore */ LITERR(" Warning: Subcircuits not yet implemented - ignored \n"); - return (0); + goto quit; } else if ((strcmp(token, ".end") == 0)) { /* .end - end of input */ /* not allowed to pay attention to additional input - return */ - return (1); + rtn = 1; + goto quit; } else if (strcmp(token, ".sens") == 0) { - return dot_sens(line, ckt, tab, current, task, gnode, foo); + rtn = dot_sens(line, ckt, tab, current, task, gnode, foo); + goto quit; } #ifdef WANT_SENSE2 else if ((strcmp(token, ".sens2") == 0)) { - return dot_sens2(line, ckt, tab, current, task, gnode, foo); + rtn = dot_sens2(line, ckt, tab, current, task, gnode, foo); + goto quit; } #endif else if ((strcmp(token, ".probe") == 0)) { /* Maybe generate a "probe" format file in the future. */ - return 0; + goto quit; } else if ((strcmp(token, ".options") == 0)|| (strcmp(token,".option")==0) || (strcmp(token,".opt")==0)) { - return dot_options(line, ckt, tab, current, task, gnode, foo); + rtn = dot_options(line, ckt, tab, current, task, gnode, foo); + goto quit; } LITERR(" unimplemented control card - error \n"); - return (0); +quit: + tfree(token); + return rtn; } diff --git a/src/spicelib/parser/inp2e.c b/src/spicelib/parser/inp2e.c index cd88609be..0c5909df3 100644 --- a/src/spicelib/parser/inp2e.c +++ b/src/spicelib/parser/inp2e.c @@ -42,13 +42,13 @@ void INP2E(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); - INPgetTok(&line, &nname3, 1); + INPgetNetTok(&line, &nname3, 1); INPtermInsert(ckt, &nname3, tab, &node3); - INPgetTok(&line, &nname4, 1); + INPgetNetTok(&line, &nname4, 1); INPtermInsert(ckt, &nname4, tab, &node4); if (!tab->defEmod) { /* create default E model */ diff --git a/src/spicelib/parser/inp2f.c b/src/spicelib/parser/inp2f.c index 32c477863..a986af7dc 100644 --- a/src/spicelib/parser/inp2f.c +++ b/src/spicelib/parser/inp2f.c @@ -26,10 +26,10 @@ void INP2F(void *ckt, INPtables * tab, card * current) int error; /* error code temporary */ void *fast; /* pointer to the actual instance */ IFvalue ptemp; /* a value structure to package resistance into */ - IFvalue *parm; /* a pointer to a value structure to pick things up into */ + IFvalue *parm; /* pointer to a value structure for functions which return one */ int waslead; /* flag to indicate that funny unlabeled number was found */ double leadval; /* actual value of unlabeled number */ - IFuid uid; /* uid for default model */ + IFuid uid; /* uid of default model to be created */ type = INPtypelook("CCCS"); if (type < 0) { @@ -39,23 +39,37 @@ void INP2F(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); if (!tab->defFmod) { /* create default F model */ IFnewUid(ckt, &uid, (IFuid) NULL, "F", UID_MODEL, (void **) NULL); IFC(newModel, (ckt, type, &(tab->defFmod), uid)); } + + /* call newInstance with macro IFC */ IFC(newInstance, (ckt, tab->defFmod, &fast, name)); + + /* call bindNode with macro IFC */ IFC(bindNode, (ckt, fast, 1, node1)); + + /* call bindNode with macro IFC */ IFC(bindNode, (ckt, fast, 2, node2)); + parm = INPgetValue(ckt, &line, IF_INSTANCE, tab); + + /* call INPpName with macro GCA */ GCA(INPpName, ("control", parm, ckt, type, fast)); + + /* call INPdevParse with macro PARSECALL */ PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { ptemp.rValue = leadval; + + /* call INPpName with macro GCA */ GCA(INPpName, ("gain", &ptemp, ckt, type, fast)); } } diff --git a/src/spicelib/parser/inp2g.c b/src/spicelib/parser/inp2g.c index 60ad74de0..ed77c7f8f 100644 --- a/src/spicelib/parser/inp2g.c +++ b/src/spicelib/parser/inp2g.c @@ -42,13 +42,13 @@ void INP2G(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); - INPgetTok(&line, &nname3, 1); + INPgetNetTok(&line, &nname3, 1); INPtermInsert(ckt, &nname3, tab, &node3); - INPgetTok(&line, &nname4, 1); + INPgetNetTok(&line, &nname4, 1); INPtermInsert(ckt, &nname4, tab, &node4); if (!tab->defGmod) { /* create default G model */ diff --git a/src/spicelib/parser/inp2h.c b/src/spicelib/parser/inp2h.c index 04d386358..e16c77482 100644 --- a/src/spicelib/parser/inp2h.c +++ b/src/spicelib/parser/inp2h.c @@ -39,9 +39,9 @@ void INP2H(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); if (!tab->defHmod) { /* create default H model */ diff --git a/src/spicelib/parser/inp2i.c b/src/spicelib/parser/inp2i.c index 9bb01c5d5..22208bfa1 100644 --- a/src/spicelib/parser/inp2i.c +++ b/src/spicelib/parser/inp2i.c @@ -39,9 +39,9 @@ void INP2I(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); if (!tab->defImod) { /* create default I model */ diff --git a/src/spicelib/parser/inp2j.c b/src/spicelib/parser/inp2j.c index 565fc12a6..0396dded8 100644 --- a/src/spicelib/parser/inp2j.c +++ b/src/spicelib/parser/inp2j.c @@ -38,11 +38,11 @@ void INP2J(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); - INPgetTok(&line, &nname3, 1); + INPgetNetTok(&line, &nname3, 1); INPtermInsert(ckt, &nname3, tab, &node3); INPgetTok(&line, &model, 1); INPinsert(&model, tab); diff --git a/src/spicelib/parser/inp2l.c b/src/spicelib/parser/inp2l.c index 341463dc7..15faeb4ee 100644 --- a/src/spicelib/parser/inp2l.c +++ b/src/spicelib/parser/inp2l.c @@ -38,9 +38,9 @@ void INP2L(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); if (!tab->defLmod) { /* create default L model */ diff --git a/src/spicelib/parser/inp2m.c b/src/spicelib/parser/inp2m.c index 4dcefee26..64ae1fb9a 100644 --- a/src/spicelib/parser/inp2m.c +++ b/src/spicelib/parser/inp2m.c @@ -31,6 +31,8 @@ INP2M (void *ckt, INPtables * tab, card * current) char *nname5; /* the fifth node's name */ char *nname6; /* the sixt node's name */ char *nname7; /* the seventh node's name */ + char *save; /* saj - used to save the posn of the start of + the parameters if the model is a mosfet*/ void *node1; /* the first node's node pointer */ void *node2; /* the second node's node pointer */ void *node3; /* the third node's node pointer */ @@ -52,30 +54,32 @@ INP2M (void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok (&line, &name, 1); INPinsert (&name, tab); - INPgetTok (&line, &nname1, 1); + INPgetNetTok (&line, &nname1, 1); INPtermInsert (ckt, &nname1, tab, &node1); - INPgetTok (&line, &nname2, 1); + INPgetNetTok (&line, &nname2, 1); INPtermInsert (ckt, &nname2, tab, &node2); - INPgetTok (&line, &nname3, 1); + INPgetNetTok (&line, &nname3, 1); INPtermInsert (ckt, &nname3, tab, &node3); - INPgetTok (&line, &nname4, 1); + INPgetNetTok (&line, &nname4, 1); INPtermInsert (ckt, &nname4, tab, &node4); /* See if 5th token after device specification is a model name */ - INPgetTok (&line, &nname5, 1); /* get 5th token */ + INPgetNetTok (&line, &nname5, 1); /* get 5th token */ + save = line; /*saj - save the posn for later if + the default mosfet model is used */ thismodel = (INPmodel *) NULL; INPgetMod (ckt, nname5, &thismodel, tab); if (thismodel == NULL) { /* 5th token is not a model in the table */ nodeflag = 1; /* now specify a 5 node device */ - INPgetTok (&line, &nname6, 1); /* get next token */ + INPgetNetTok (&line, &nname6, 1); /* get next token */ thismodel = (INPmodel *) NULL; INPgetMod (ckt, nname6, &thismodel, tab); if (thismodel == NULL) { /* 6th token is not a model in the table */ nodeflag = 2; /* now specify a 6 node device */ - INPgetTok (&line, &nname7, 1); /* get next token */ + INPgetNetTok (&line, &nname7, 1); /* get next token */ thismodel = (INPmodel *) NULL; INPgetMod (ckt, nname7, &thismodel, tab); if (thismodel == NULL) @@ -100,6 +104,12 @@ INP2M (void *ckt, INPtables * tab, card * current) INPtermInsert (ckt, &nname7, tab, &node7); } } + /*saj unbreak the default model creation*/ + else{ + model = nname5;/*mosfet*/ + line = save; /* reset the posn to what it sould be */ + } + /*saj*/ } else { /* 7th token is a model - only have 6 terminal device */ @@ -200,10 +210,11 @@ INP2M (void *ckt, INPtables * tab, card * current) IFC (bindNode, (ckt, fast, 2, node2)); IFC (bindNode, (ckt, fast, 3, node3)); IFC (bindNode, (ckt, fast, 4, node4)); - if ((thismodel->INPmodType == INPtypelook ("B3SOIPD")) || - (thismodel->INPmodType == INPtypelook ("B3SOIFD")) || - (thismodel->INPmodType == INPtypelook ("B3SOIDD")) || - (thismodel->INPmodType == INPtypelook ("SOI3"))) + /*use type not thismodel->INPmodType as it might not exist!*/ + if ((type == INPtypelook ("B3SOIPD")) || + (type == INPtypelook ("B3SOIFD")) || + (type == INPtypelook ("B3SOIDD")) || + (type == INPtypelook ("SOI3"))) { switch (nodeflag) { diff --git a/src/spicelib/parser/inp2o.c b/src/spicelib/parser/inp2o.c index 33e7cf59c..9e4cc3490 100644 --- a/src/spicelib/parser/inp2o.c +++ b/src/spicelib/parser/inp2o.c @@ -46,13 +46,13 @@ void INP2O(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); - INPgetTok(&line, &nname3, 1); + INPgetNetTok(&line, &nname3, 1); INPtermInsert(ckt, &nname3, tab, &node3); - INPgetTok(&line, &nname4, 1); + INPgetNetTok(&line, &nname4, 1); INPtermInsert(ckt, &nname4, tab, &node4); INPgetTok(&line, &model, 1); if (INPlookMod(model)) { diff --git a/src/spicelib/parser/inp2q.c b/src/spicelib/parser/inp2q.c index 0d6423926..ca72ad01c 100644 --- a/src/spicelib/parser/inp2q.c +++ b/src/spicelib/parser/inp2q.c @@ -47,11 +47,11 @@ void INP2Q(void *ckt, INPtables * tab, card * current, void *gnode) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); - INPgetTok(&line, &nname3, 1); + INPgetNetTok(&line, &nname3, 1); INPtermInsert(ckt, &nname3, tab, &node3); INPgetTok(&line, &model, 1); if (INPlookMod(model)) { @@ -83,6 +83,12 @@ void INP2Q(void *ckt, INPtables * tab, card * current, void *gnode) } mdfast = tab->defQmod; } + +#ifdef TRACE + /* --- SDB debug statement --- */ + printf ("In INP2Q, just about to dive into newInstance\n"); +#endif + IFC(newInstance, (ckt, mdfast, &fast, name)); IFC(bindNode, (ckt, fast, 1, node1)); IFC(bindNode, (ckt, fast, 2, node2)); diff --git a/src/spicelib/parser/inp2r.c b/src/spicelib/parser/inp2r.c index 858392238..131e9d097 100644 --- a/src/spicelib/parser/inp2r.c +++ b/src/spicelib/parser/inp2r.c @@ -49,9 +49,9 @@ void INP2R(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); val = INPevaluate(&line, &error1, 1); /* either not a number -> model, or @@ -80,6 +80,7 @@ void INP2R(void *ckt, INPtables * tab, card * current) } } else { /* It is not a model */ + tfree(model); line = saveline; /* go back */ type = mytype; if (!tab->defRmod) { /* create default R model */ diff --git a/src/spicelib/parser/inp2s.c b/src/spicelib/parser/inp2s.c index 9c50f5ef3..7d584fc58 100644 --- a/src/spicelib/parser/inp2s.c +++ b/src/spicelib/parser/inp2s.c @@ -46,13 +46,13 @@ void INP2S(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); - INPgetTok(&line, &nname3, 1); + INPgetNetTok(&line, &nname3, 1); INPtermInsert(ckt, &nname3, tab, &node3); - INPgetTok(&line, &nname4, 1); + INPgetNetTok(&line, &nname4, 1); INPtermInsert(ckt, &nname4, tab, &node4); INPgetTok(&line, &model, 1); INPinsert(&model, tab); diff --git a/src/spicelib/parser/inp2t.c b/src/spicelib/parser/inp2t.c index 1530306dd..ee92b4c69 100644 --- a/src/spicelib/parser/inp2t.c +++ b/src/spicelib/parser/inp2t.c @@ -43,13 +43,13 @@ void INP2T(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); - INPgetTok(&line, &nname3, 1); + INPgetNetTok(&line, &nname3, 1); INPtermInsert(ckt, &nname3, tab, &node3); - INPgetTok(&line, &nname4, 1); + INPgetNetTok(&line, &nname4, 1); INPtermInsert(ckt, &nname4, tab, &node4); if (!tab->defTmod) { /* create deafult T model */ diff --git a/src/spicelib/parser/inp2u.c b/src/spicelib/parser/inp2u.c index 6d03cfadf..092537bd6 100644 --- a/src/spicelib/parser/inp2u.c +++ b/src/spicelib/parser/inp2u.c @@ -43,11 +43,11 @@ void INP2U(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); - INPgetTok(&line, &nname3, 1); + INPgetNetTok(&line, &nname3, 1); INPtermInsert(ckt, &nname3, tab, &node3); INPgetTok(&line, &model, 1); INPinsert(&model, tab); diff --git a/src/spicelib/parser/inp2v.c b/src/spicelib/parser/inp2v.c index c8775cade..fc93000d0 100644 --- a/src/spicelib/parser/inp2v.c +++ b/src/spicelib/parser/inp2v.c @@ -39,9 +39,9 @@ void INP2V(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); if (!tab->defVmod) { /* create default V model */ diff --git a/src/spicelib/parser/inp2w.c b/src/spicelib/parser/inp2w.c index 39f9f9ba1..ec1856702 100644 --- a/src/spicelib/parser/inp2w.c +++ b/src/spicelib/parser/inp2w.c @@ -44,9 +44,9 @@ void INP2W(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); parm = INPgetValue(ckt, &line, IF_INSTANCE, tab); ptemp.uValue = parm->uValue; diff --git a/src/spicelib/parser/inp2z.c b/src/spicelib/parser/inp2z.c index 4d46283e9..1c7b9003c 100644 --- a/src/spicelib/parser/inp2z.c +++ b/src/spicelib/parser/inp2z.c @@ -46,11 +46,11 @@ void INP2Z(void *ckt, INPtables * tab, card * current) line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); - INPgetTok(&line, &nname1, 1); + INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetTok(&line, &nname2, 1); + INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); - INPgetTok(&line, &nname3, 1); + INPgetNetTok(&line, &nname3, 1); INPtermInsert(ckt, &nname3, tab, &node3); INPgetTok(&line, &model, 1); INPinsert(&model, tab); @@ -90,7 +90,7 @@ void INP2Z(void *ckt, INPtables * tab, card * current) IFC(bindNode, (ckt, fast, 2, node2)); IFC(bindNode, (ckt, fast, 3, node3)); PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); - if ( (waslead) && ( thismodel != INPtypelook("MES") ) ) { + if ( (waslead) && ( thismodel->INPmodType != INPtypelook("MES") ) ) { ptemp.rValue = leadval; GCA(INPpName, ("area", &ptemp, ckt, type, fast)); } diff --git a/src/spicelib/parser/inpdomod.c b/src/spicelib/parser/inpdomod.c index 09f0ad9f0..98d1694b9 100644 --- a/src/spicelib/parser/inpdomod.c +++ b/src/spicelib/parser/inpdomod.c @@ -9,7 +9,13 @@ Author: 1985 Thomas L. Quarles #include "inpdefs.h" #include "inp.h" - +/*-------------------------------------------------------------- + * This fcn takes the model card & examines it. Depending upon + * model type, it parses the model line, and then calls + * INPmakeMod to stick the model name into the model list. + * Note that multi-line models are handled in the calling fcn + * (INPpas1). + *-------------------------------------------------------------*/ char *INPdomodel(void *ckt, card * image, INPtables * tab) { @@ -21,10 +27,19 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) char *line; line = image->line; + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPdomodel, examining line %s . . . \n", line); +#endif + INPgetTok(&line, &modname, 1); /* throw away '.model' */ - INPgetTok(&line, &modname, 1); - INPinsert(&modname, tab); - INPgetTok(&line, &typename, 1); + tfree(modname); + INPgetTok(&line, &modname, 1); /* get model name */ + INPinsert(&modname, tab); /* stick model name into table */ + INPgetTok(&line, &typename, 1); /* get model type */ + + /* ----- Check if model is a BJT --------- */ if ((strcmp(typename, "npn") == 0) || (strcmp(typename, "pnp") == 0)) { err = INPfindLev(line,&lev); switch(lev) { @@ -50,7 +65,10 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) } INPmakeMod(modname, type, image); - } else if (strcmp(typename, "d") == 0) { + } /* end if ((strcmp(typename, "npn") == 0) || (strcmp(typename, "pnp") == 0)) */ + + /* -------- Check if model is a diode --------- */ + else if (strcmp(typename, "d") == 0) { type = INPtypelook("Diode"); if (type < 0) { err = @@ -58,7 +76,10 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) ("Device type Diode not available in this binary\n"); } INPmakeMod(modname, type, image); - } else if ((strcmp(typename, "njf") == 0) + } /* else if (strcmp(typename, "d") == 0) { */ + + /* -------- Check if model is a jfet --------- */ + else if ((strcmp(typename, "njf") == 0) || (strcmp(typename, "pjf") == 0)) { err = INPfindLev(line, &lev); switch (lev) { @@ -86,7 +107,10 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) break; } INPmakeMod(modname, type, image); - } else if ((strcmp(typename, "nmf") == 0) + } /* end else if ((strcmp(typename, "njf") == 0) */ + + /* -------- Check if model is a MES or an HFET --------- */ + else if ((strcmp(typename, "nmf") == 0) || (strcmp(typename, "pmf") == 0) || (strcmp(typename, "nhfet") == 0) || (strcmp(typename, "phfet") == 0)) { @@ -142,7 +166,10 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) break; } INPmakeMod(modname, type, image); - } else if (strcmp(typename, "urc") == 0) { + } + + /* -------- Check if model is a Uniform Distrib. RC line --------- */ + else if (strcmp(typename, "urc") == 0) { type = INPtypelook("URC"); if (type < 0) { err = @@ -150,7 +177,10 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) ("Device type URC not available in this binary\n"); } INPmakeMod(modname, type, image); - } else if ((strcmp(typename, "nmos") == 0) + } + + /* -------- Check if model is a MOSFET --------- */ + else if ((strcmp(typename, "nmos") == 0) || (strcmp(typename, "pmos") == 0) || (strcmp(typename, "nsoi") == 0) || (strcmp(typename, "psoi") == 0)) { @@ -332,7 +362,10 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) break; } INPmakeMod(modname, type, image); - } else if (strcmp(typename, "r") == 0) { + } + + /* -------- Check if model is a resistor --------- */ + else if (strcmp(typename, "r") == 0) { type = INPtypelook("Resistor"); if (type < 0) { err = @@ -340,7 +373,59 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) ("Device type Resistor not available in this binary\n"); } INPmakeMod(modname, type, image); - } else if (strcmp(typename, "c") == 0) { + } + + /* -------- Check if model is a transmission line of some sort --------- */ + else if(strcmp(typename,"txl") == 0) { + char *val; + double rval=0, lval=0; + INPgetTok(&line,&val,1); + while (*line != '\0') { + if (*val == 'R' || *val == 'r') { + INPgetTok(&line,&val,1); + rval = atof(val); + } + if ((strcmp(val,"L") == 0) || (strcmp(val,"l") == 0)) { + INPgetTok(&line,&val,1); + lval = atof(val); + } + INPgetTok(&line,&val,1); + } + if(lval) + rval = rval/lval; + if (rval > 1.6e10) { + type = INPtypelook("TransLine"); + INPmakeMod(modname,type,image); + } + if (rval > 1.6e9) { + type = INPtypelook("CplLines"); + INPmakeMod(modname,type,image); + } + else { + type = INPtypelook("TransLine"); + INPmakeMod(modname,type,image); + } + if(type < 0) { + err = INPmkTemp( + "Device type TransLine not available in this binary\n"); + } + + } + + /* -------- Check if model is a ???? --------- */ + else if(strcmp(typename,"cpl") == 0) { + type = INPtypelook("CplLines"); + if(type < 0) { + err = INPmkTemp( + "Device type CplLines not available in this binary\n"); + } + INPmakeMod(modname,type,image); + + } + + + /* -------- Check if model is a cap --------- */ + else if (strcmp(typename, "c") == 0) { type = INPtypelook("Capacitor"); if (type < 0) { err = @@ -348,7 +433,10 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) ("Device type Capacitor not available in this binary\n"); } INPmakeMod(modname, type, image); - } else if (strcmp(typename, "sw") == 0) { + } + + /* -------- Check if model is a switch --------- */ + else if (strcmp(typename, "sw") == 0) { type = INPtypelook("Switch"); if (type < 0) { err = @@ -356,7 +444,10 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) ("Device type Switch not available in this binary\n"); } INPmakeMod(modname, type, image); - } else if (strcmp(typename, "csw") == 0) { + } + + /* -------- Check if model is a Current Controlled Switch --------- */ + else if (strcmp(typename, "csw") == 0) { type = INPtypelook("CSwitch"); if (type < 0) { err = @@ -364,7 +455,10 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) ("Device type CSwitch not available in this binary\n"); } INPmakeMod(modname, type, image); - } else if (strcmp(typename, "ltra") == 0) { + } + + /* -------- Check if model is a Lossy TransLine --------- */ + else if (strcmp(typename, "ltra") == 0) { type = INPtypelook("LTRA"); if (type < 0) { err = @@ -372,10 +466,63 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) ("Device type LTRA not available in this binary\n"); } INPmakeMod(modname, type, image); - } else { + } + + /* type poly added by SDB . . . */ +#ifdef XSPICE + /* -------- Check if model is a poly (specific to xspice) --------- */ + else if ( (strcmp(typename, "poly") == 0) || + (strcmp(typename, "POLY") == 0) ) { + type = INPtypelook("POLY"); + if (type < 0) { + err = + INPmkTemp + ("Device type POLY not available in this binary\n"); + } + INPmakeMod(modname, type, image); + } +#endif + + /* -------- Default action --------- */ + else { +#ifndef XSPICE type = -1; err = (char *) MALLOC(35 + strlen(typename)); (void) sprintf(err, "unknown model type %s - ignored\n", typename); +#else + /* gtri - modify - wbk - 10/23/90 - modify to look for code models */ + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPdomodel, found unknown model type, typename = %s . . .\n", typename); +#endif + + /* look for this model type and put it in the table of models */ + type = INPtypelook(typename); + if(type < 0) { + err = (char *) MALLOC(35 + strlen(typename)); + sprintf(err,"Unknown model type %s - ignored\n",typename); + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPdomodel, ignoring unknown model typ typename = %s . . .\n", typename); +#endif + + } + else { + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPdomodel, adding unknown model typename = %s to model list. . .\n", typename); +#endif + + INPmakeMod(modname,type,image); + } + + /* gtri - end - wbk - 10/23/90 */ +#endif + } + tfree(typename); return (err); } diff --git a/src/spicelib/parser/inpdpar.c b/src/spicelib/parser/inpdpar.c index 1b6d0cf35..37a723fc4 100644 --- a/src/spicelib/parser/inpdpar.c +++ b/src/spicelib/parser/inpdpar.c @@ -30,10 +30,11 @@ char *INPdevParse(char **line, void *ckt, int dev, void *fast, /* flag - 1 if leading double given, 0 otherwise */ { int error; /* int to store evaluate error return codes in */ - char *parm; + char *parm=NULL; char *errbuf; int i; IFvalue *val; + char *rtn=NULL; /* check for leading value */ *waslead = 0; @@ -44,10 +45,14 @@ char *INPdevParse(char **line, void *ckt, int dev, void *fast, *leading = 0.0; while (**line != (char) 0) { error = INPgetTok(line, &parm, 1); - if (!*parm) + if (!*parm) { + FREE(parm); continue; - if (error) - return (INPerror(error)); + } + if (error) { + rtn = (INPerror(error)); + goto quit; + } for (i = 0; i < (*(*(ft_sim->devices)[dev]).numInstanceParms); i++) { if (strcmp(parm, ((*(ft_sim->devices)[dev]).instanceParms[i]. @@ -56,25 +61,32 @@ char *INPdevParse(char **line, void *ckt, int dev, void *fast, INPgetValue(ckt, line, ((*(ft_sim->devices)[dev]). instanceParms[i].dataType), tab); - if (!val) - return (INPerror(E_PARMVAL)); + if (!val) { + rtn = (INPerror(E_PARMVAL)); + goto quit; + } error = (*(ft_sim->setInstanceParm)) (ckt, fast, (*(ft_sim->devices) [dev]). instanceParms[i].id, val, (IFvalue *) NULL); - if (error) - return (INPerror(error)); + if (error) { + rtn = (INPerror(error)); + goto quit; + } break; } } if (i == (*(*(ft_sim->devices)[dev]).numInstanceParms)) { errbuf = MALLOC(strlen(parm) + 25); (void) sprintf(errbuf, " unknown parameter (%s) \n", parm); - return (errbuf); + rtn = (errbuf); + goto quit; } FREE(parm); } - return ((char *) NULL); +quit: + FREE(parm); + return rtn; } diff --git a/src/spicelib/parser/inperror.c b/src/spicelib/parser/inperror.c index fd5286e55..5276c6c11 100644 --- a/src/spicelib/parser/inperror.c +++ b/src/spicelib/parser/inperror.c @@ -20,18 +20,18 @@ Author: 1985 Thomas L. Quarles char *INPerror(int type) { - char *val; + const char *val; char *ebuf; /*CDHW Lots of things set errMsg but it is never used so let's hack it in CDHW*/ if ( errMsg ) { - val = errMsg; errMsg=NULL; } + val = errMsg; errMsg = NULL;} else /*CDHW end of hack CDHW*/ val = SPerror(type); if (!val) - return (val); + return NULL; #ifdef HAVE_ASPRINTF if (errRtn) @@ -40,20 +40,14 @@ char *INPerror(int type) asprintf(&ebuf, "%s\n", val); #else /* ~ HAVE_ASPRINTF */ if (errRtn){ - if ( (ebuf = (char *) malloc(strlen(val) + - strlen(errRtn) + 25)) == NULL){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } + ebuf = (char *) tmalloc(strlen(val) + strlen(errRtn) + 25); sprintf(ebuf, "%s detected in routine \"%s\"\n", val, errRtn); } else{ - if ( (ebuf = (char *) malloc(strlen(val) + 2)) == NULL){ - fprintf(stderr,"malloc failed\n"); - exit(1); - } + ebuf = (char *) tmalloc(strlen(val) + 2); sprintf(ebuf, "%s\n", val); } #endif /* HAVE_ASPRINTF */ + FREE(errMsg); /* pn: really needed ? */ return ebuf; } diff --git a/src/spicelib/parser/inpfindl.c b/src/spicelib/parser/inpfindl.c index 52aed3be5..f6a049521 100644 --- a/src/spicelib/parser/inpfindl.c +++ b/src/spicelib/parser/inpfindl.c @@ -20,7 +20,9 @@ char *INPfindLev(char *line, int *level) { char *where; - where = line; + /* + * where = line; + */ where = strstr(line, "level"); @@ -58,7 +60,7 @@ char *INPfindLev(char *line, int *level) else { /* no level on the line => default */ *level = 1; - printf("Level not specified: Using level 1.\n"); + printf("Warning -- Level not specified on line \"%s\"\nUsing level 1.\n", line); return ((char *) NULL); } diff --git a/src/spicelib/parser/inpgmod.c b/src/spicelib/parser/inpgmod.c index 5631eeecb..0a52a28c7 100644 --- a/src/spicelib/parser/inpgmod.c +++ b/src/spicelib/parser/inpgmod.c @@ -24,21 +24,40 @@ char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab) char *temp; int error; +#ifdef TRACE + /* SDB debug statement */ + printf("In INPgetMod, examining model %s . . . \n", name); +#endif + for (modtmp = modtab; modtmp != (INPmodel *) NULL; modtmp = ((modtmp)->INPnextModel)) { + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPgetMod, comparing against stored model %s . . . \n", (modtmp)->INPmodName); +#endif + if (strcmp((modtmp)->INPmodName, name) == 0) { /* found the model in question - now instantiate if necessary */ /* and return an appropriate pointer to it */ - if (modtmp->INPmodType < 0) { + + if (modtmp->INPmodType < 0) { /* First check for illegal model type */ /* illegal device type, so can't handle */ *model = (INPmodel *) NULL; err = (char *) MALLOC((35 + strlen(name)) * sizeof(char)); (void) sprintf(err, "Unknown device type for model %s \n", name); + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPgetMod, illegal device type for model %s . . . \n", name); +#endif + return (err); - } - if (!((modtmp)->INPmodUsed)) { + } /* end of checking for illegal model */ + + if (!((modtmp)->INPmodUsed)) { /* Check if model is already defined */ /* not already defined, so create & give parameters */ error = (*(ft_sim->newModel)) (ckt, (modtmp)->INPmodType, &((modtmp)->INPmodfast), @@ -47,49 +66,47 @@ char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab) return (INPerror(error)); /* parameter isolation, identification, binding */ line = ((modtmp)->INPmodLine)->line; + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPgetMod, inserting new model into table. line = %s . . . \n", line); +#endif + + INPgetTok(&line, &parm, 1); /* throw away '.model' */ + tfree(parm); INPgetTok(&line, &parm, 1); /* throw away 'modname' */ + tfree(parm); while (*line != 0) { INPgetTok(&line, &parm, 1); if (!*parm) continue; - for (j = 0; - j < - (* - (*(ft_sim->devices) - [(modtmp)->INPmodType]).numModelParms); j++) { - if (strcmp - (parm, - ((*(ft_sim->devices)[(modtmp)->INPmodType]). - modelParms[j].keyword)) == 0) { - val = - INPgetValue(ckt, &line, - ((* - (ft_sim-> - devices)[ - (modtmp)->INPmodType]). - modelParms[j].dataType), tab); - error = - (*(ft_sim->setModelParm)) (ckt, - ((modtmp)-> - INPmodfast), - (* - (ft_sim-> - devices)[ - (modtmp)-> - INPmodType]).modelParms - [j].id, val, - (IFvalue *) - NULL); - if (error) - return (INPerror(error)); - break; + + for (j = 0; j < (* (*(ft_sim->devices)[(modtmp)->INPmodType]).numModelParms); j++) { + + if (strcmp(parm, "txl") == 0) { + if (strcmp("cpl", ((*(ft_sim->devices) [ (modtmp)->INPmodType ]).modelParms[j].keyword)) == 0) { + strcpy(parm, "cpl"); } - } + } + + if (strcmp(parm,((*(ft_sim->devices)[(modtmp)->INPmodType]).modelParms[j].keyword)) == 0) { + + val = INPgetValue(ckt, &line, ((* (ft_sim->devices)[(modtmp)->INPmodType]).modelParms[j].dataType), tab); + + error = (*(ft_sim->setModelParm)) (ckt, ((modtmp)->INPmodfast), + (* (ft_sim->devices)[(modtmp)->INPmodType]).modelParms[j].id, + val, (IFvalue *) NULL); + if (error) + return (INPerror(error)); + break; + } + } /* end for(j = 0 . . .*/ + if (strcmp(parm, "level") == 0) { - /* just grab the level number and throw away */ - /* since we already have that info from pass1 */ - val = INPgetValue(ckt, &line, IF_REAL, tab); + /* just grab the level number and throw away */ + /* since we already have that info from pass1 */ + val = INPgetValue(ckt, &line, IF_REAL, tab); } else if (j >= (* (*(ft_sim->devices) @@ -117,5 +134,11 @@ char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab) (void) sprintf(err, " unable to find definition of model %s - default assumed \n", name); + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPgetMod, didn't find model for %s, using default . . . \n", name); +#endif + return (err); } diff --git a/src/spicelib/parser/inpgtok.c b/src/spicelib/parser/inpgtok.c index ecc423d28..7e8013dbc 100644 --- a/src/spicelib/parser/inpgtok.c +++ b/src/spicelib/parser/inpgtok.c @@ -19,18 +19,25 @@ Modified: 2000 AlansFixes #include "inpdefs.h" #include "inp.h" +/*------------------------------------------------------------------- + * INPgetTok -- this fcn extracts a generic input token from + * 'line' and returns a pointer to it in 'token'. + *------------------------------------------------------------------*/ int INPgetTok(char **line, char **token, int gobble) /* eat non-whitespace trash AFTER token? */ { char *point; int signstate; - /* scan along throwing away garbage characters */ + /* scan along throwing away garbage characters until end of line + or a separation char is found */ for (point = *line; *point != '\0'; point++) { if (*point == ' ') continue; if (*point == '\t') continue; + if (*point == '\r') + continue; if (*point == '=') continue; if (*point == '(') @@ -43,13 +50,17 @@ int INPgetTok(char **line, char **token, int gobble) } /* mark beginning of token */ *line = point; - /* now find all good characters */ + + /* now find all good characters up to next occurance of a + separation character. */ signstate = 0; for (point = *line; *point != '\0'; point++) { if (*point == ' ') break; if (*point == '\t') break; + if (*point == '\r') + break; if (*point == '=') break; if (*point == '(') @@ -58,7 +69,8 @@ int INPgetTok(char **line, char **token, int gobble) break; if (*point == ',') break; - /* This is not complex enough to catch all errors, but it will get the "good" parses */ + /* This is not complex enough to catch all errors, + but it will get the "good" parses */ if ((*point == '+') || (*point == '-')){ /* Treat '+' signs same as '-' signs */ if (signstate == 1 || signstate == 3) break; @@ -96,16 +108,114 @@ int INPgetTok(char **line, char **token, int gobble) continue; if (**line == '\t') continue; + if (**line == '\r') + continue; if ((**line == '=') && gobble) continue; if ((**line == ',') && gobble) continue; break; } - /*printf("found token (%s) and rest of line (%s)\n",*token,*line); */ + +#ifdef TRACE + /* SDB debug statement */ + /*printf("found generic token (%s) and rest of line (%s)\n",*token,*line); */ +#endif + return (OK); } + + +/*------------------------------------------------------------------- + * INPgetNetTok -- this fcn extracts an input netname token from + * 'line' and returns a pointer to it in 'token'. + * This fcn cloned from INPgetTok by SDB to enable + * complex netnames (e.g. netnames like '+VCC' and 'IN-'). + * mailto:sdb@cloud9.net -- 4.7.2003 + *------------------------------------------------------------------*/ +int INPgetNetTok(char **line, char **token, int gobble) + /* eat non-whitespace trash AFTER token? */ +{ + char *point; + int signstate; + + /* scan along throwing away garbage characters until end of line + or a separation char is found */ + for (point = *line; *point != '\0'; point++) { + if (*point == ' ') + continue; + if (*point == '\t') + continue; + if (*point == '=') + continue; + if (*point == '(') + continue; + if (*point == ')') + continue; + if (*point == ',') + continue; + break; + } + + /* mark beginning of token */ + *line = point; + + /* now find all good characters up to next occurance of a + separation character. INPgetNetTok is very liberal about + what it accepts. */ + signstate = 0; + for (point = *line; *point != '\0'; point++) { + if (*point == ' ') + break; + if (*point == '\t') + break; + if (*point == '\r') + break; + if (*point == '=') + break; + if (*point == ',') + break; + } + + /* now copy found token into *token */ + if (point == *line && *point) /* Weird items, 1 char */ + point++; + *token = (char *) MALLOC(1 + point - *line); + if (!*token) + return (E_NOMEM); + (void) strncpy(*token, *line, point - *line); + *(*token + (point - *line)) = '\0'; + *line = point; + + /* gobble garbage to next token */ + for (; **line != '\0'; (*line)++) { + if (**line == ' ') + continue; + if (**line == '\t') + continue; + if (**line == '\r') + continue; + if ((**line == '=') && gobble) + continue; + if ((**line == ',') && gobble) + continue; + break; + } + +#ifdef TRACE + /* SDB debug statement */ + /* printf("found netname token (%s) and rest of line (%s)\n", *token, *line); */ +#endif + + return (OK); +} + + +/*------------------------------------------------------------------- + * INPgetUTok -- this fcn extracts an input refdes token from + * 'line' and returns a pointer to it in 'token'. + *------------------------------------------------------------------*/ int INPgetUTok(char **line, char **token, int gobble) @@ -212,6 +322,11 @@ int INPgetUTok(char **line, char **token, int gobble) break; } *line = point; - /* printf("found token (%s) and rest of line (%s)\n",*token,*line); */ + +#ifdef TRACE + /* SDB debug statement */ + /* printf("found refdes token (%s) and rest of line (%s)\n",*token,*line); */ +#endif + return (OK); } diff --git a/src/spicelib/parser/inplkmod.c b/src/spicelib/parser/inplkmod.c index d1c534bab..ebd77a542 100644 --- a/src/spicelib/parser/inplkmod.c +++ b/src/spicelib/parser/inplkmod.c @@ -13,7 +13,11 @@ Author: 1985 Thomas L. Quarles extern INPmodel *modtab; - +/*----------------------------------------------------------------- + * This fcn accepts a pointer to the model name, and returns 1 if + * the model exists in the model table, and returns 0 if hte model + * doesn't exist in the model table. + *----------------------------------------------------------------*/ int INPlookMod(char *name) { register INPmodel **i; diff --git a/src/spicelib/parser/inpmkmod.c b/src/spicelib/parser/inpmkmod.c index a9b9705d3..e86e92e25 100644 --- a/src/spicelib/parser/inpmkmod.c +++ b/src/spicelib/parser/inpmkmod.c @@ -11,25 +11,46 @@ Author: 1985 Thomas L. Quarles INPmodel *modtab; - /* create/lookup a 'model' entry */ +/*-------------------------------------------------------------- + * This fcn takes the model name and looks to see if it is already + * in the model table. If it is, then just return. Otherwise, + * stick the model into the model table. + * Note that the model table INPmodel + *--------------------------------------------------------------*/ int INPmakeMod(char *token, int type, 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 != (INPmodel *) NULL; i = &((*i)->INPnextModel)) { if (strcmp((*i)->INPmodName, token) == 0) { return (OK); } } + + /* Model name was not already in model table. Therefore stick + it in the model table. Then reutrn. */ + +#ifdef TRACE + /* debug statement */ + printf("In INPmakeMod, about to insert new model name = %s . . .\n", token); +#endif + *i = (INPmodel *) MALLOC(sizeof(INPmodel)); if (*i == NULL) - return (E_NOMEM); - (*i)->INPmodName = token; - (*i)->INPmodType = type; - (*i)->INPnextModel = (INPmodel *) NULL; - (*i)->INPmodUsed = 0; - (*i)->INPmodLine = line; + return (E_NOMEM); + + (*i)->INPmodName = token; /* model name */ + (*i)->INPmodType = type; /* model type */ + (*i)->INPnextModel = (INPmodel *) NULL; /* pointer to next model (end of list) */ + (*i)->INPmodUsed = 0; /* model is unused */ + (*i)->INPmodLine = line; /* model line */ (*i)->INPmodfast = NULL; return (OK); } + + + + diff --git a/src/spicelib/parser/inppas1.c b/src/spicelib/parser/inppas1.c index 596df381b..96d6f5af8 100644 --- a/src/spicelib/parser/inppas1.c +++ b/src/spicelib/parser/inppas1.c @@ -29,6 +29,15 @@ void INPpas1(void *ckt, card * deck, INPtables * tab) if (*thisline == '.') { if (strncmp(thisline, ".model", 6) == 0) { + /* First check to see if model is multi-line. If so, + read in all lines & stick them into tab. */ + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPpas1, handling line = %s \n", thisline); +#endif + + /* Now invoke INPdomodel to stick model into model table. */ temp = INPdomodel(ckt, current, tab); current->error = INPerrCat(current->error, temp); } diff --git a/src/spicelib/parser/inppas2.c b/src/spicelib/parser/inppas2.c index 7830da5a0..041fe5dea 100644 --- a/src/spicelib/parser/inppas2.c +++ b/src/spicelib/parser/inppas2.c @@ -10,6 +10,12 @@ Author: 1985 Thomas L. Quarles #include "inppas2.h" +#ifdef XSPICE +/* gtri - add - wbk - 11/9/90 - include function prototypes */ +#include "mifproto.h" +/* gtri - end - wbk - 11/9/90 */ +#endif + /* pass 2 - Scan through the lines. ".model" cards have processed in * pass1 and are ignored here. */ @@ -23,6 +29,11 @@ void INPpas2(void *ckt, card * data, INPtables * tab, void *task) void *gnode; int error; /* used by the macros defined above */ +#ifdef TRACE + /* SDB debug statement */ + printf("Entered INPpas2 . . . .\n"); +#endif + error = INPgetTok(&groundname, &gname, 1); if (error) data->error = @@ -39,6 +50,11 @@ void INPpas2(void *ckt, card * data, INPtables * tab, void *task) for (current = data; current != NULL; current = current->nextcard) { +#ifdef TRACE + /* SDB debug statement */ + printf("In INPpas2, examining card %s . . .\n", current->line); +#endif + c = *(current->line); c = islower(c) ? toupper(c) : c; @@ -50,6 +66,16 @@ void INPpas2(void *ckt, card * data, INPtables * tab, void *task) /* blank line (tab leading) */ break; +#ifdef XSPICE + /* gtri - add - wbk - 10/23/90 - add case for 'A' devices */ + + case 'A': /* Aname */ + MIF_INP2A(ckt,tab,current); + break; + + /* gtri - end - wbk - 10/23/90 */ +#endif + case 'R': /* Rname [][][w=][l=] */ INP2R(ckt, tab, current); @@ -156,6 +182,18 @@ void INPpas2(void *ckt, card * data, INPtables * tab, void *task) INP2U(ckt, tab, current); break; + /* Kspice addition - saj */ + case 'P': + /* Pname ...... */ + /* R= L= G= C= l= */ + INP2P(ckt, tab,current); + break; + case 'Y': + /* Yname R= L= G= C= l= */ + INP2Y(ckt, tab,current); + break; + /* end Kspice */ + case 'K': /* Kname Lname Lname */ INP2K(ckt, tab, current); diff --git a/src/spicelib/parser/inppas3.c b/src/spicelib/parser/inppas3.c index db8b2bf1d..9afab1f41 100644 --- a/src/spicelib/parser/inppas3.c +++ b/src/spicelib/parser/inppas3.c @@ -30,7 +30,7 @@ INPpas3(void *ckt, card *data, INPtables *tab, void *task, char *line; /* the part of the current line left to parse */ char *name; /* the node's name */ - char *token; /* a token from the line */ + char *token=NULL; /* a token from the line */ IFparm *prm; /* pointer to parameter to search through array */ IFvalue ptemp; /* a value structure to package @@ -39,8 +39,14 @@ INPpas3(void *ckt, card *data, INPtables *tab, void *task, int length; /* length of a name */ void *node1; /* the first node's node pointer */ +#ifdef TRACE + /* SDB debug statement */ + printf("In INPpas3 . . . \n"); +#endif + for(current = data; current != NULL; current = current->nextcard) { line = current->line; + FREE(token) INPgetTok(&line,&token,1); if (strcmp(token,".nodeset")==0) { @@ -55,7 +61,7 @@ INPpas3(void *ckt, card *data, INPtables *tab, void *task, if(which == -1) { LITERR("nodeset unknown to simulator. \n") - return; + goto quit; } for(;;) { @@ -90,7 +96,7 @@ INPpas3(void *ckt, card *data, INPtables *tab, void *task, if(which==-1) { LITERR("ic unknown to simulator. \n") - return; + goto quit; } for(;;) { @@ -114,6 +120,8 @@ INPpas3(void *ckt, card *data, INPtables *tab, void *task, } } } - return; +quit: + FREE(token); + return; } diff --git a/src/spicelib/parser/inptyplk.c b/src/spicelib/parser/inptyplk.c index 13efc98c3..40598c1f3 100644 --- a/src/spicelib/parser/inptyplk.c +++ b/src/spicelib/parser/inptyplk.c @@ -18,11 +18,35 @@ int INPtypelook(char *type) { int i; + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPtypelook, examining model type = %s . . .\n", type); +#endif + for (i = 0; i < ft_sim->numDevices; i++) { + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPtypelook, checking model type = %s against existing model = %s, . . .\n", type, (*(ft_sim->devices)[i]).name ); +#endif + if (strcmp(type, (*(ft_sim->devices)[i]).name) == 0) { /*found the device - return it */ + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPtypelook, found the device -- returning it!!!\n"); +#endif + return i; } } + +#ifdef TRACE + /* SDB debug statement */ + printf("In INPtypelook, device not found!\n"); +#endif + return -1; } diff --git a/src/spinit b/src/spinit index 31c8095d3..6695ff437 100644 --- a/src/spinit +++ b/src/spinit @@ -2,3 +2,6 @@ alias exit quit alias acct rusage all set x11lineararcs +* For SPICE2 POLYs, edit the below line to point to the location +* of your codemode. +* codemodel /usr/local/src/ngspice/src/xspice/icm/spice2poly.cm