Browse Source

CIDER integration. Code updated for cider support.

pre-master-46
pnenzi 23 years ago
parent
commit
8d893d890a
  1. 31
      src/Makefile.am
  2. 27
      src/frontend/resource.c
  3. 162
      src/include/Makefile.am
  4. 5
      src/include/bool.h
  5. 2
      src/include/cktdefs.h
  6. 64
      src/include/complex.h
  7. 2
      src/include/defines.h
  8. 20
      src/include/devdefs.h
  9. 22
      src/include/macros.h
  10. 17
      src/include/ngspice.h
  11. 57
      src/main.c
  12. 2
      src/maths/Makefile.am
  13. 4
      src/maths/cmaths/cmath1.c
  14. 1
      src/maths/cmaths/test_cx_ph.c
  15. 3
      src/maths/ni/nidest.c
  16. 2
      src/maths/ni/nipred.h
  17. 1
      src/maths/ni/nireinit.c
  18. 6
      src/misc/misc_time.c
  19. 63
      src/misc/string.c
  20. 7
      src/misc/stringutil.h
  21. 11
      src/ngnutmeg.c
  22. 2
      src/ngspice.c
  23. 1
      src/spicelib/analysis/cktdltn.c
  24. 1
      src/spicelib/analysis/cktdojob.c
  25. 77
      src/spicelib/analysis/cktdump.c
  26. 1
      src/spicelib/analysis/cktload.c
  27. 1
      src/spicelib/analysis/cktmknod.c
  28. 1
      src/spicelib/analysis/cktntask.c
  29. 1
      src/spicelib/analysis/cktpzstr.c
  30. 14
      src/spicelib/analysis/cktsens.c
  31. 1
      src/spicelib/analysis/cktsetup.c
  32. 7
      src/spicelib/analysis/cktsgen.c
  33. 1
      src/spicelib/analysis/cktsopt.c
  34. 18
      src/spicelib/parser/inp2d.c
  35. 30
      src/spicelib/parser/inp2m.c
  36. 18
      src/spicelib/parser/inp2q.c
  37. 134
      src/spicelib/parser/inpdomod.c
  38. 273
      src/spicelib/parser/inpgmod.c

31
src/Makefile.am

@ -1,10 +1,11 @@
## Process this file with automake to produce Makefile.in
## PN: remember to add CIDERSCRIPTS
SUBDIRS = misc maths frontend spicelib include @XSPICEDIR@
SUBDIRS = misc maths frontend spicelib include @XSPICEDIR@ @CIDERDIR@
bin_PROGRAMS = ngspice ngnutmeg nghelp ngsconvert ngproc2mod ngmultidec makeidx
EXTRA_DIST = ngspice.txt ngspice.idx spinit setplot spectrum
EXTRA_DIST = ngspice.txt ngspice.idx spinit setplot spectrum @CIDERSCRIPTS@
helpdatadir = $(pkgdatadir)/helpdir
@ -12,19 +13,23 @@ helpdata_DATA = ngspice.idx ngspice.txt
initdatadir = $(pkgdatadir)/scripts
initdata_DATA = spinit setplot spectrum
initdata_DATA = spinit setplot spectrum @CIDERSCRIPTS@
DYNAMIC_DEVICELIBS = \
spicelib/devices/asrc/libasrc.a \
spicelib/devices/bjt/libbjt.a \
spicelib/devices/bjt2/libbjt2.a \
spicelib/devices/bsim1/libbsim1.a \
spicelib/devices/bsim2/libbsim2.a \
spicelib/devices/bsim3/libbsim3.a \
spicelib/devices/bsim3v0/libbsim3v0.a \
spicelib/devices/bsim3v1/libbsim3v1.a \
spicelib/devices/bsim3v2/libbsim3v2.a \
spicelib/devices/bsim3v1s/libbsim3v1s.a \
spicelib/devices/bsim3v1a/libbsim3v1a.a \
spicelib/devices/bsim4/libbsim4.a \
spicelib/devices/cap/libcap.a \
spicelib/devices/libbsim3soi.a \
spicelib/devices/bsim3soi_pd/libbsim3soipd.a \
spicelib/devices/bsim3soi_fd/libbsim3soifd.a \
spicelib/devices/bsim3soi_dd/libbsim3soidd.a \
@ -39,6 +44,7 @@ DYNAMIC_DEVICELIBS = \
spicelib/devices/isrc/libisrc.a \
spicelib/devices/hfet1/libhfet.a \
spicelib/devices/hfet2/libhfet2.a \
spicelib/devices/hisim/libhisim.a \
spicelib/devices/jfet/libjfet.a \
spicelib/devices/jfet2/libjfet2.a \
spicelib/devices/ltra/libltra.a \
@ -57,17 +63,10 @@ DYNAMIC_DEVICELIBS = \
spicelib/devices/urc/liburc.a \
spicelib/devices/vccs/libvccs.a \
spicelib/devices/vcvs/libvcvs.a \
spicelib/devices/vsrc/libvsrc.a
## ----- 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
spicelib/devices/vsrc/libvsrc.a \
@NUMDEV@
## Build ngspice first:
ngspice_SOURCES = \
@ -88,10 +87,12 @@ ngspice_LDADD = \
spicelib/devices/libdev.a \
@XSPICELIB2@ \
frontend/parser/libparser.a \
@CIDERSIM@
frontend/help/libhlp.a \
spicelib/parser/libinp.a \
maths/deriv/libderiv.a \
maths/cmaths/libcmaths.a \
maths/misc/libmathsmisc.a \
maths/poly/libpoly.a \
maths/ni/libni.a \
maths/sparse/libsparse.a \

27
src/frontend/resource.c

@ -168,6 +168,9 @@ ft_ckspace(void)
static void
printres(char *name)
{
#ifdef CIDER
char *paramname = NULL;
#endif
bool yy = FALSE;
static long lastsec = 0, lastusec = 0;
struct variable *v;
@ -314,11 +317,24 @@ printres(char *name)
/* Now get all the spice resource stuff. */
if (ft_curckt && ft_curckt->ci_ckt) {
#ifdef CIDER
/* begin cider integration */
if (!name || eq(name, "circuit") || eq(name, "task")) {
paramname = NULL;
} else {
paramname = name;
}
v = if_getstat(ft_curckt->ci_ckt, paramname);
if (paramname && v) {
/* end cider integration */
#else /* ~CIDER */
if (name && eq(name, "task"))
v = if_getstat(ft_curckt->ci_ckt, NULL);
else
v = if_getstat(ft_curckt->ci_ckt, name);
if (name && v) {
#endif
fprintf(cp_out, "%s = ", v->va_name);
wl_print(cp_varwl(v), cp_out);
(void) putc('\n', cp_out);
@ -333,6 +349,17 @@ printres(char *name)
}
yy = TRUE;
}
#ifdef CIDER
/* begin cider integration */
/* Now print out interesting stuff about numerical devices. */
if (!name || eq(name, "devices")) {
(void) NDEVacct(ft_curckt->ci_ckt, cp_out);
yy = TRUE;
}
/* end cider integration */
#endif
}
if (!yy) {

162
src/include/Makefile.am

@ -1,60 +1,110 @@
## Process this file with automake to produce Makefile.in
noinst_HEADERS = \
acdefs.h \
bool.h \
cktdefs.h \
complex.h \
const.h \
cpdefs.h \
cpextern.h \
cpstd.h \
defines.h \
devdefs.h \
dgen.h \
distodef.h \
dvec.h \
ftedbgra.h \
ftedebug.h \
ftedefs.h \
ftedev.h \
fteext.h \
fteinp.h \
fteinput.h \
fteparse.h \
gendefs.h \
graph.h \
grid.h \
hlpdefs.h \
iferrmsg.h \
ifsim.h \
inpdefs.h \
inpmacs.h \
inpptree.h \
jobdefs.h \
macros.h \
memory.h \
missing_math.h \
ngspice.h \
noisedef.h \
opdefs.h \
optdefs.h \
plot.h \
pnode.h \
pzdefs.h \
sen2defs.h \
sensdefs.h \
sensgen.h \
sim.h \
smpdefs.h \
sperror.h \
spmatrix.h \
suffix.h \
terminal.h \
tfdefs.h \
trandefs.h \
trcvdefs.h \
tskdefs.h \
wordlist.h
noinst_HEADERS = \
acdefs.h \
bdrydefs.h \
bool.h \
carddefs.h \
ciderinp.h \
cidersupt.h \
cktdefs.h \
cluster.h \
cmconstants.h \
cm.h \
cmproto.h \
cmtypes.h \
complex.h \
const.h \
contdefs.h \
cpdefs.h \
cpextern.h \
cpstd.h \
defines.h \
devdefs.h \
dgen.h \
distodef.h \
dllitf.h \
domndefs.h \
dvec.h \
elctdefs.h \
enh.h \
evt.h \
evtproto.h \
evtudn.h \
ftedbgra.h \
ftedebug.h \
ftedefs.h \
ftedev.h \
fteext.h \
fteinp.h \
fteinput.h \
fteparse.h \
gendefs.h \
gendev.h \
graph.h \
grid.h \
hlpdefs.h \
iferrmsg.h \
ifsim.h \
inpdefs.h \
inpmacs.h \
inpptree.h \
ipc.h \
ipcproto.h \
ipctiein.h \
jobdefs.h \
lsort.h \
macros.h \
material.h \
matldefs.h \
memory.h \
meshdefs.h \
meshext.h \
methdefs.h \
mifcmdat.h \
mifdefs.h \
mif.h \
mifparse.h \
mifproto.h \
miftypes.h \
missing_math.h \
mobdefs.h \
modldefs.h \
multi_line.h \
ngspice.h \
noisedef.h \
numcards.h \
numconst.h \
numenum.h \
numgen.h \
numglobs.h \
onedev.h \
onemesh.h \
opdefs.h \
optdefs.h \
optndefs.h \
outpdefs.h \
plot.h \
pnode.h \
profile.h \
pzdefs.h \
sen2defs.h \
sensdefs.h \
sensgen.h \
sim.h \
smpdefs.h \
sperror.h \
spmatrix.h \
suffix.h \
swec.h \
terminal.h \
tfdefs.h \
trandefs.h \
trcvdefs.h \
tskdefs.h \
twodev.h \
twomesh.h \
wordlist.h \
wstdio.h
MAINTAINERCLEANFILES = Makefile.in

5
src/include/bool.h

@ -2,7 +2,12 @@
#define _BOOL_H
typedef unsigned char bool;
#define BOOLEAN int
#define TRUE 1
#define FALSE 0
#define NO 0
#define YES 1
#endif

2
src/include/cktdefs.h

@ -14,7 +14,7 @@
/* 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*/
#define MAXNUMDEVS 64 /* 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 */
/* Need to change for SOI devs ? */

64
src/include/complex.h

@ -17,6 +17,22 @@ typedef struct _complex1 complex;
#define realpart(cval) ((struct _complex1 *) (cval))->cx_real
#define imagpart(cval) ((struct _complex1 *) (cval))->cx_imag
#ifdef CIDER
/* From Cider numcomplex.h
pn:leave it here until I decide what to do about
struct mosAdmittances {
complex yIdVdb;
complex yIdVsb;
complex yIdVgb;
complex yIsVdb;
complex yIsVsb;
complex yIsVgb;
complex yIgVdb;
complex yIgVsb;
complex yIgVgb;
};
*/
#endif
/*
* Each expects two arguments for each complex number - a real and an
@ -270,6 +286,11 @@ typedef struct
/* Macro function that returns the approx absolute value of a complex
number. */
#define ELEMENT_MAG(ptr) (ABS((ptr)->Real) + ABS((ptr)->Imag))
#define CMPLX_ASSIGN_VALUE(cnum, vReal, vImag) \
{ (cnum).Real = vReal; \
(cnum).Imag = vImag; \
}
/* Complex assignment statements. */
#define CMPLX_ASSIGN(to,from) \
@ -288,12 +309,21 @@ typedef struct
{ (to).Real = -(from).Real; \
(to).Imag = (from).Imag; \
}
#define CMPLX_CONJ(a) (a).Imag = -(a).Imag
#define CONJUGATE(a) (a).Imag = -(a).Imag
#define CMPLX_NEGATE(a) \
{ (a).Real = -(a).Real; \
(a).Imag = -(a).Imag; \
}
#define CMPLX_NEGATE_SELF(cnum) \
{ (cnum).real = -(cnum).Real; \
(cnum).imag = -(cnum).Imag; \
}
/* Macro that returns the approx magnitude (L-1 norm) of a complex number. */
#define CMPLX_1_NORM(a) (ABS((a).Real) + ABS((a).Imag))
@ -309,6 +339,11 @@ typedef struct
(to).Imag = (from_a).Imag + (from_b).Imag; \
}
/* Macro function that performs addition of a complex and a scalar. */
#define CMPLX_ADD_SELF_SCALAR(cnum, scalar) \
{ (cnum).Real += scalar; \
}
/* Macro function that performs complex subtraction. */
#define CMPLX_SUBT(to,from_a,from_b) \
{ (to).Real = (from_a).Real - (from_b).Real; \
@ -326,7 +361,7 @@ typedef struct
{ (to).Real -= (from).Real; \
(to).Imag -= (from).Imag; \
}
/* Macro function that multiplies a complex number by a scalar. */
#define SCLR_MULT(to,sclr,cmplx) \
{ (to).Real = (sclr) * (cmplx).Real; \
@ -339,6 +374,33 @@ typedef struct
(to).Imag *= (sclr); \
}
/* Macro function that multiplies two complex numbers. */
#define CMPLX_MULT(to,from_a,from_b) \
{ (to).real = (from_a).Real * (from_b).Real - \
(from_a).Imag * (from_b).Imag; \
(to).imag = (from_a).Real * (from_b).Imag + \
(from_a).Imag * (from_b).Real; \
}
/* Macro function that multiplies a complex number and a scalar. */
#define CMPLX_MULT_SCALAR(to,from, scalar) \
{ (to).Real = (from).Real * scalar; \
(to).Imag = (from).Imag * scalar; \
}
/* Macro function that implements *= for a complex and a scalar number. */
#define CMPLX_MULT_SELF_SCALAR(cnum, scalar) \
{ (cnum).Real *= scalar; \
(cnum).Imag *= scalar; \
}
/* Macro function that multiply-assigns a complex number by a scalar. */
#define SCLR_MULT_ASSIGN(to,sclr) \
{ (to).Real *= (sclr); \
(to).Imag *= (sclr); \
}
/* Macro function that multiplies two complex numbers. */
#define CMPLX_MULT(to,from_a,from_b) \
{ (to).Real = (from_a).Real * (from_b).Real - \

2
src/include/defines.h

@ -97,7 +97,7 @@
#define HAS_ASCII
#define HAS_TTY_
#define HAS_TIME_
#define HAS_TIME_H
#define HAS_RLIMIT_

20
src/include/devdefs.h

@ -22,6 +22,19 @@ void DEVqmeyer(double,double,double,double,double,double*,double*,double*,
double,double);
double DEVpred(CKTcircuit*,int);
#ifdef CIDER
/* Cider integration */
double limitResistorVoltage( double, double, int * );
double limitJunctionVoltage( double, double, int * );
double limitVbe( double, double, int * );
double limitVce( double, double, int * );
double limitVgb( double, double, int * );
#endif
typedef struct SPICEdev {
IFdevice DEVpublic;
@ -80,6 +93,13 @@ typedef struct SPICEdev {
/* procedure to do distortion operations */
int (*DEVnoise)(int, int, GENmodel*,CKTcircuit*, Ndata *, double *);
/* noise routine */
#ifdef CIDER
void (*DEVdump)(GENmodel *, CKTcircuit *);
void (*DEVacct)(GENmodel *, CKTcircuit *, FILE *);
/* routines to report device internals
* now used only by cider numerical devices
*/
#endif
int *DEVinstSize; /* size of an instance */
int *DEVmodSize; /* size of a model */

22
src/include/macros.h

@ -14,6 +14,8 @@
#define NUMELEMS(ARRAY) (sizeof(ARRAY)/sizeof(*ARRAY))
/* String macros */
#define eq(a,b) (!strcmp((a), (b)))
#define eqc(a,b) (cieq((a), (b)))
#define isalphanum(c) (isalpha(c) || isdigit(c))
@ -22,10 +24,17 @@
((c) <= 'F')) ? ((c) - 'A' + 10) : 0)))
/* Mathematical macros */
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define ABS(a) ((a) < 0.0 ? -(a) : (a))
#define SGN(a) ((a) < 0.0 ? -(1.0) : (1.0))
#define SIGN(a,b) ( b >= 0 ? (a >= 0 ? a : - a) : (a >= 0 ? - a : a))
#define SWAP(type, a, b) {type swapx; swapx = a; a = b; b = swapx;}
#define NIL(type) ((type *)0)
#define ABORT() fflush(stderr);fflush(stdout);abort();
#define ERROR(CODE,MESSAGE) { \
@ -60,4 +69,15 @@
#define DEBUGMSG(testargs)
#endif
/* Macro that queries the system to find the process time. */
#define ELAPSED_TIME( time ) \
{ struct tms {int user, sys, cuser, csys;} buffer; \
\
times(&buffer); \
time = buffer.user / 60.0; \
}
#endif /* _MACROS_H_ */

17
src/include/ngspice.h

@ -25,6 +25,8 @@
#include "memory.h"
#include "defines.h"
#include "macros.h"
#include "bool.h"
#include "complex.h"
#include <math.h>
#include <stdio.h>
@ -110,7 +112,7 @@ struct timeb timebegin;
#endif /* va: no index, but strchr */
#endif
#ifdef HAS_TIME_
#ifdef HAS_TIME_H
#include <time.h>
#endif
@ -167,4 +169,17 @@ extern char *Lib_Path;
extern int ARCHme; /* My logical process number */
extern int ARCHsize; /* Total number of processes */
#ifdef CIDER
/* Definitions of globals for Machine Accuracy Limits
* Imported from cider
*/
extern double BMin; /* lower limit for B(x) */
extern double BMax; /* upper limit for B(x) */
extern double ExpLim; /* limit for exponential */
extern double Accuracy; /* accuracy of the machine */
extern double Acc, MuLim, MutLim;
#endif /* CIDER */
#endif /* NGSPICE_H_INCLUDED */

57
src/main.c

@ -49,6 +49,10 @@
#endif
#endif
#ifdef CIDER
#include "numenum.h"
#endif
extern void DevInit(void);
/* Main options */
@ -72,10 +76,57 @@ IFsimulator *ft_sim = NULL;
int ARCHme;
int ARCHsize;
#ifdef CIDER
/* Globals definitions for Machine Accuracy Limits
* (needed by CIDER)
*/
double BMin; /* lower limit for B(x) */
double BMax; /* upper limit for B(x) */
double ExpLim; /* limit for exponential */
double Accuracy; /* accuracy of the machine */
double Acc, MuLim, MutLim;
#endif
char *errRtn;
char *errMsg;
char *cp_program;
#ifdef CIDER
/* Global debug flags from CIDER, soon they will become
* spice variables :)
*/
BOOLEAN ONEacDebug = FALSE;
BOOLEAN ONEdcDebug = TRUE;
BOOLEAN ONEtranDebug = TRUE;
BOOLEAN ONEjacDebug = FALSE;
BOOLEAN TWOacDebug = FALSE;
BOOLEAN TWOdcDebug = TRUE;
BOOLEAN TWOtranDebug = TRUE;
BOOLEAN TWOjacDebug = FALSE;
/* CIDER Global Variable Declarations */
char *LogFileName = "cider.log"; /* This will go somewhere else */
int BandGapNarrowing;
int TempDepMobility, ConcDepMobility, FieldDepMobility, TransDepMobility;
int SurfaceMobility, MatchingMobility, MobDeriv;
int CCScattering;
int Srh, Auger, ConcDepLifetime, AvalancheGen;
int FreezeOut = FALSE;
int OneCarrier;
int MaxIterations = 100;
int AcAnalysisMethod = DIRECT;
double Temp, RelTemp, Vt;
double RefPsi;/* potential at Infinity */
double EpsNorm, VNorm, NNorm, LNorm, TNorm, JNorm, GNorm, ENorm;
/* end cider globals */
#endif /* CIDER */
struct variable *(*if_getparam)( );
@ -225,6 +276,12 @@ int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator)
SIMinfo.analyses = (IFanalysis **)spice_analysis_ptr(); /* va: we recast, because we use
* only the public part
*/
#ifdef CIDER
/* Evaluates limits of machine accuracy for CIDER */
evalAccLimits();
#endif /* CIDER */
#endif /* SIMULATOR */
SPfrontEnd = frontEnd;

2
src/maths/Makefile.am

@ -1,4 +1,4 @@
# Process this file with automake
SUBDIRS = cmaths ni sparse poly deriv
SUBDIRS = cmaths ni sparse poly deriv misc
MAINTAINERCLEANFILES = Makefile.in

4
src/maths/cmaths/cmath1.c

@ -315,8 +315,8 @@ cx_exp(void *data, short int type, int length, int *newlength, short int *newtyp
void *
cx_sqrt(void *data, short int type, int length, int *newlength, short int *newtype)
{
double *d;
complex *c;
double *d = NULL;
complex *c = NULL;
double *dd = (double *) data;
complex *cc = (complex *) data;
int i, cres = (type == VF_REAL) ? 0 : 1;

1
src/maths/cmaths/test_cx_ph.c

@ -6,7 +6,6 @@
#include <memory.h>
#include <dvec.h>
#include <complex.h>
#include <defines.h>
#include "cmath.h"
#include "cmath1.h"

3
src/maths/ni/nidest.c

@ -10,7 +10,6 @@ Author: 1985 Thomas L. Quarles
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "nidest.h"
@ -20,7 +19,7 @@ NIdestroy(register CKTcircuit *ckt)
{
if (ckt->CKTmatrix)
SMPdestroy(ckt->CKTmatrix);
ckt->CKTmatrix = 0;
ckt->CKTmatrix = NULL;
if(ckt->CKTrhs) FREE(ckt->CKTrhs);
if(ckt->CKTrhsOld) FREE(ckt->CKTrhsOld);
if(ckt->CKTrhsSpare) FREE(ckt->CKTrhsSpare);

2
src/maths/ni/nipred.h

@ -8,7 +8,7 @@
#ifdef PREDICTOR
intNIpred(register CKTcircuit * ckt);
int NIpred(register CKTcircuit * ckt);
#endif /* PREDICTOR */

1
src/maths/ni/nireinit.c

@ -11,7 +11,6 @@ Author: 1985 Thomas L. Quarles
#include "ngspice.h"
#include "cktdefs.h"
#include <stdio.h>
#include "smpdefs.h"
#include "sperror.h"
#include "nireinit.h"

6
src/misc/misc_time.c

@ -8,7 +8,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
#include <config.h>
#include "ngspice.h"
#include <stdio.h>
#include <string.h>
#include "misc_time.h"
@ -90,7 +89,10 @@ void timediff(struct timeb *now, struct timeb *begin, int *sec, int *msec)
#endif
#endif
/* How many seconds have elapsed in running time. */
/*
* How many seconds have elapsed in running time.
* This is the routine called in IFseconds
*/
double
seconds(void)

63
src/misc/string.c

@ -131,6 +131,69 @@ strtolower(char *str)
}
}
#ifdef CIDER
/*
* Imported from cider file support/strmatch.c
* Original copyright notice:
* Author: 1991 David A. Gates, U. C. Berkeley CAD Group
*
*/
/*
* Case-insensitive test of whether p is a prefix of s and at least the
* first n characters are the same
*/
int
cinprefix(p, s, n)
register char *p, *s;
register int n;
{
if (!p || !s) return( 0 );
while (*p) {
if ((isupper(*p) ? tolower(*p) : *p) != (isupper(*s) ? tolower(*s) : *s))
return( 0 );
p++;
s++;
n--;
}
if (n > 0)
return( 0 );
else
return( 1 );
}
/*
* Case-insensitive match of prefix string p against string s
* returns the number of matching characters
*
*/
int
cimatch(p, s)
register char *p, *s;
{
register int n = 0;
if (!p || !s) return( 0 );
while (*p) {
if ((isupper(*p) ? tolower(*p) : *p) != (isupper(*s) ? tolower(*s) : *s))
return( n );
p++;
s++;
n++;
}
return( n );
}
#endif /* CIDER */
char *
gettok(char **s)
{

7
src/misc/stringutil.h

@ -16,6 +16,13 @@ int ciprefix(register char *p, register char *s);
void strtolower(char *str);
char * gettok(char **s);
#ifdef CIDER
/* cider integration */
int cinprefix(register char *p, register char *s, register int n);
int cimatch(register char *p, register char *s);
#endif
#if !defined(HAVE_INDEX) && !defined(HAVE_STRCHR)
char * index(register char *s, register char c);

11
src/ngnutmeg.c

@ -23,7 +23,7 @@ Copyright 1990 Regents of the University of California. All rights reserved.
#include "suffix.h"
IFsimulator SIMinfo = {
"nutmeg", /* my name */
"ngnutmeg", /* my name */
"data analysis and manipulation program", /* more about me */
Spice_Version, /* my version */
NULL, /* newCircuit function */
@ -62,3 +62,12 @@ IFsimulator SIMinfo = {
0,
NULL,
};
#ifdef CIDER
/* An ugly hack */
void
NDEVacct(void *ckt, FILE *file)
{
fprintf(file, "Ouch, you have called NDEV from ngnutmeg\n");
}
#endif

2
src/ngspice.c

@ -13,8 +13,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
#define CONFIG
#include <stdio.h>
#include "devdefs.h"
#include "noisedef.h"
#include "suffix.h"

1
src/spicelib/analysis/cktdltn.c

@ -6,7 +6,6 @@ Copyright 1992 Regents of the University of California. All rights reserved.
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"

1
src/spicelib/analysis/cktdojob.c

@ -6,7 +6,6 @@ Modified: 2000 AlansFixes
#include "ngspice.h"
#include "cktdefs.h"
#include <stdio.h>
#include "sperror.h"
#include "trandefs.h"

77
src/spicelib/analysis/cktdump.c

@ -1,8 +1,16 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Author: 1985 Thomas L. Quarles, 1991 David A. Gates
**********/
/*
TODO:
Ngspice and cider integration note:
This file must be changed to be consistent with the ngspice interface.
The SPICEdev structure must be changed by adding a pointer to DEVdump
and DEVacct routines (as suggested below).
Paolo Nenzi Dec 2001
No more sure about this notice (2003)
*/
/* CKTdump(ckt)
@ -10,20 +18,85 @@ Author: 1985 Thomas L. Quarles
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#ifdef CIDER
/* Begin cider integration */
#include "gendefs.h"
#include "devdefs.h"
extern SPICEdev **DEVices;
/* End cider integration */
#endif
void
CKTdump(CKTcircuit *ckt, double ref, void *plot)
{
IFvalue refData;
IFvalue valData;
#ifdef CIDER
int i;
#endif
refData.rValue = ref;
valData.v.numValue = ckt->CKTmaxEqNum-1;
valData.v.vec.rVec = ckt->CKTrhsOld+1;
(*(SPfrontEnd->OUTpData))(plot,&refData,&valData);
#ifdef CIDER
/*
* Begin cider integration:
* This code has been hacked changing the SPICEdev structure.
* SPICEdev now has DEVdump and DEVacct as members. The
* following code works for any devices but as of this
* comment is written, only numerical devices have DEVdump
* and DEVacct routine (NUMD, NBJT, NUMD2, NBJT2, NUMOS).
*/
for (i=0; i<DEVmaxnum; i++) {
if ( ((*DEVices[i]).DEVdump != NULL) &&
(ckt->CKThead[i] != NULL) ){
(*((*DEVices[i]).DEVdump))(ckt->CKThead[i],ckt);
}
}
/* End cider integration */
#endif /* CIDER */
}
#ifdef CIDER
/*
* Routine to dump statistics about numerical devices
*
* The following lines are historical:
* This is inefficient, because we have to look up the indices
* of the devices in the device table. Would be simpler if
* DEVices had an entry for an accounting function, so that indirection
* could be used.
* ------------------
* The SPICEdev structure has been hacked and now has a DEVacct entry.
*/
void
NDEVacct(CKTcircuit *ckt, FILE *file)
{
int i;
if ( !ckt->CKTisSetup ) {
return;
}
for (i=0; i<DEVmaxnum; i++) {
if ( ((*DEVices[i]).DEVacct != NULL) &&
(ckt->CKThead[i] != NULL) ){
(*((*DEVices[i]).DEVacct))(ckt->CKThead[i],ckt, file);
}
}
return;
}
/* End cider integration */
#endif /* CIDER */

1
src/spicelib/analysis/cktload.c

@ -13,7 +13,6 @@ Modified: 2000 AlansFixes
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "devdefs.h"

1
src/spicelib/analysis/cktmknod.c

@ -9,7 +9,6 @@ Author: 1985 Thomas L. Quarles
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "smpdefs.h"

1
src/spicelib/analysis/cktntask.c

@ -7,7 +7,6 @@ Modified: 2000 AlansFixes
*/
#include "ngspice.h"
#include <stdio.h>
#include "tskdefs.h"
#include "ifsim.h"
#include "cktdefs.h"

1
src/spicelib/analysis/cktpzstr.c

@ -7,7 +7,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
*/
#include "ngspice.h"
#include <stdio.h>
#include "pzdefs.h"
#include "complex.h"
#include "cktdefs.h"

14
src/spicelib/analysis/cktsens.c

@ -221,8 +221,18 @@ int sens_sens(CKTcircuit *ckt, int restart)
/* The unknown vector of node voltages overwrites rhs */
E = ckt->CKTrhs;
iE = ckt->CKTirhs;
ckt->CKTrhsOld = E;
ckt->CKTirhsOld = iE;
/* The following two lines assigned a pointer to another shadowing
* the previous definition and creating trouble when xfree() in
* NIdestroy tried to deallocate a non malloc'ed pointer
*
* Original code:
* ckt->CKTrhsOld = E;
* ckt->CKTirhsOld = iE;
*/
*ckt->CKTrhsOld = *E;
*ckt->CKTirhsOld = *iE;
Y = ckt->CKTmatrix;
#ifdef ASDEBUG
DEBUG(1) {

1
src/spicelib/analysis/cktsetup.c

@ -10,7 +10,6 @@ Author: 1985 Thomas L. Quarles
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "devdefs.h"

7
src/spicelib/analysis/cktsgen.c

@ -8,13 +8,18 @@ Copyright 1991 Regents of the University of California. All rights reserved.
#include "cktdefs.h"
#include "ifsim.h"
#include "sensgen.h"
#include <stdio.h>
extern SPICEdev **DEVices;
/* XXX */
extern char *Sfilter;
int set_model(sgen *);
int set_param(sgen *);
int set_inst(sgen *);
int set_dev(sgen *);
extern int sens_getp(sgen *, CKTcircuit *, IFvalue *);
sgen *
sgen_init(CKTcircuit *ckt, int is_dc)
{

1
src/spicelib/analysis/cktsopt.c

@ -11,7 +11,6 @@ Modified: 2000 AlansFixes
*/
#include "ngspice.h"
#include <stdio.h>
#include "const.h"
#include "optdefs.h"
#include "tskdefs.h"

18
src/spicelib/parser/inp2d.c

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Thomas L. Quarles
Modified: 2001 Paolo Nenzi (Cider Integration)
**********/
#include "ngspice.h"
@ -50,7 +51,13 @@ void INP2D(void *ckt, INPtables * tab, card * current)
INPinsert(&model, tab);
current->error = INPgetMod(ckt, model, &thismodel, tab);
if (thismodel != NULL) {
if (mytype != thismodel->INPmodType) {
if ((mytype != thismodel->INPmodType)
#ifdef CIDER
&& (thismodel->INPmodType != INPtypelook("NUMD"))
&& (thismodel->INPmodType != INPtypelook("NUMD2"))
#endif
){
LITERR("incorrect model type");
return;
}
@ -71,7 +78,16 @@ void INP2D(void *ckt, INPtables * tab, card * current)
IFC(bindNode, (ckt, fast, 2, node2));
PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab));
if (waslead) {
#ifdef CIDER
if( type == INPtypelook("NUMD2") ) {
LITERR(" error: no unlabelled parameter permitted on NUMD2\n")
} else {
#endif
ptemp.rValue = leadval;
GCA(INPpName, ("area", &ptemp, ckt, type, fast));
}
#ifdef CIDER
}
#endif
}

30
src/spicelib/parser/inp2m.c

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Thomas L. Quarles
Modified: 2001 Paolo Nenzi (Cider Integration)
**********/
#include "ngspice.h"
@ -89,13 +90,14 @@ INP2M (void *ckt, INPtables * tab, card * current)
INPgetMod (ckt, model, &thismodel, tab); /* get pointer to the model */
if (thismodel != NULL)
{
if ((thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
if ((thismodel->INPmodType != INPtypelook ("B3SOI")) &&
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) &&
(thismodel->INPmodType != INPtypelook ("B3SOIDD"))
)
{
/* if model is not variable node B3SOIPD/FD/DD model, error! */
LITERR ("only level 9-10 B3SOI(PD | FD | DD) can have 7 nodes") return;
LITERR ("only level 9, 29-31 B3SOI(PD | FD | DD) can have 7 nodes") return;
}
else
{ /* if looking at B3SOIPD/FD/DD model, allocate the 7th node */
@ -113,14 +115,15 @@ INP2M (void *ckt, INPtables * tab, card * current)
}
else
{ /* 7th token is a model - only have 6 terminal device */
if ((thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
if ((thismodel->INPmodType != INPtypelook ("B3SOI")) &&
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) &&
(thismodel->INPmodType != INPtypelook ("B3SOIDD")) &&
(thismodel->INPmodType != INPtypelook ("SOI3"))
)
{
/* if model is not variable node B3SOIPD/FD/DD or STAG model, error! */
LITERR ("only level 9-10 B3SOI(PD | FD | DD) and STAG (SOI3) can have 6 nodes") return;
LITERR ("only level 9, 29-31 B3SOI(PD | FD | DD) and STAG (SOI3) can have 6 nodes") return;
}
else
{ /* if looking at B3SOIPD/FD/DD or STAG (SOI3) model, allocate the 6th node */
@ -132,14 +135,15 @@ INP2M (void *ckt, INPtables * tab, card * current)
}
else
{ /* 6th token is a model - only have 5 terminal device */
if ((thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
if ((thismodel->INPmodType != INPtypelook ("B3SOI")) &&
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) &&
(thismodel->INPmodType != INPtypelook ("B3SOIDD")) &&
(thismodel->INPmodType != INPtypelook ("SOI3"))
)
{
/* if model is not variable node B3SOIPD/FD/DD model, error! */
LITERR ("only level 9-10 B3SOI(PD | FD | DD) and STAG (SOI3) can have 5 nodes") return;
LITERR ("only level 9, 29-31 B3SOI(PD | FD | DD) and STAG (SOI3) can have 5 nodes") return;
}
else
{ /* if looking at B3SOIPD/FD/DD or STAG (SOI3) model, allocate the 5th node */
@ -171,16 +175,23 @@ INP2M (void *ckt, INPtables * tab, card * current)
&& thismodel->INPmodType != INPtypelook ("BSIM1")
&& thismodel->INPmodType != INPtypelook ("BSIM2")
&& thismodel->INPmodType != INPtypelook ("BSIM3")
&& thismodel->INPmodType != INPtypelook ("B3SOI")
&& thismodel->INPmodType != INPtypelook ("B3SOIPD")
&& thismodel->INPmodType != INPtypelook ("B3SOIFD")
&& thismodel->INPmodType != INPtypelook ("B3SOIDD")
&& thismodel->INPmodType != INPtypelook ("BSIM4")
&& thismodel->INPmodType != INPtypelook ("BSIM3V1")
&& thismodel->INPmodType != INPtypelook ("BSIM3V2")
&& thismodel->INPmodType != INPtypelook ("BSIM3v0")
&& thismodel->INPmodType != INPtypelook ("BSIM3v1")
&& thismodel->INPmodType != INPtypelook ("BSIM3v1S")
&& thismodel->INPmodType != INPtypelook ("BSIM3v1A")
&& thismodel->INPmodType != INPtypelook ("SOI3")
#ifdef CIDER
&& thismodel->INPmodType != INPtypelook ("NUMOS")
#endif
#ifdef HAVE_EKV
&& thismodel->INPmodType != INPtypelook ("EKV")
#endif
&& thismodel->INPmodType != INPtypelook ("HiSIM1")
)
{
LITERR ("incorrect model type");
@ -211,7 +222,8 @@ INP2M (void *ckt, INPtables * tab, card * current)
IFC (bindNode, (ckt, fast, 3, node3));
IFC (bindNode, (ckt, fast, 4, node4));
/*use type not thismodel->INPmodType as it might not exist!*/
if ((type == INPtypelook ("B3SOIPD")) ||
if ((type == INPtypelook ("B3SOI")) ||
(type == INPtypelook ("B3SOIPD")) ||
(type == INPtypelook ("B3SOIFD")) ||
(type == INPtypelook ("B3SOIDD")) ||
(type == INPtypelook ("SOI3")))

18
src/spicelib/parser/inp2q.c

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Thomas L. Quarles
Modified: 2001 Paolo Nenzi (Cider Integration)
**********/
#include "ngspice.h"
@ -66,8 +67,13 @@ void INP2Q(void *ckt, INPtables * tab, card * current, void *gnode)
INPinsert(&model, tab);
current->error = INPgetMod(ckt, model, &thismodel, tab);
if (thismodel != NULL) {
if(thismodel->INPmodType != INPtypelook("BJT") &&
thismodel->INPmodType != INPtypelook("BJT2")) {
if((thismodel->INPmodType != INPtypelook("BJT"))
&& (thismodel->INPmodType != INPtypelook("BJT2"))
#ifdef CIDER
&& (thismodel->INPmodType != INPtypelook("NBJT"))
&& (thismodel->INPmodType != INPtypelook("NBJT2"))
#endif
) {
LITERR("incorrect model type")
return;
}
@ -96,7 +102,15 @@ void INP2Q(void *ckt, INPtables * tab, card * current, void *gnode)
IFC(bindNode, (ckt, fast, 4, node4));
PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab));
if (waslead) {
#ifdef CIDER
if( type == INPtypelook("NBJT2") ) {
LITERR(" error: no unlabelled parameter permitted on NBJT2\n")
} else {
#endif
ptemp.rValue = leadval;
GCA(INPpName, ("area", &ptemp, ckt, type, fast));
}
#ifdef CIDER
}
#endif
}

134
src/spicelib/parser/inpdomod.c

@ -255,55 +255,71 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab)
case 9:
type = INPtypelook("Mos9");
if(type < 0) {
err = INPmkTemp(
"Device type MOS9 not available in this binary\n");
err = INPmkTemp
("Device type MOS9 not available in this binary\n");
}
break;
case 10:
type = INPtypelook("B3SOIPD");
type = INPtypelook("B3SOI");
if (type < 0) {
err =
INPmkTemp
("Device type B3SOIPD not available in this binary\n");
("Device type B3SOI V3.0 not available in this binary\n");
}
break;
case 11:
type = INPtypelook("B3SOIFD");
case 14:
type = INPtypelook("BSIM4");
if (type < 0) {
err =
INPmkTemp
("Device type B3SOIFD not available in this binary\n");
("Device type BSIM4 not available in this binary\n");
}
break;
case 12:
type = INPtypelook("B3SOIDD");
case 15:
type = INPtypelook("BSIM5");
if (type < 0) {
err =
INPmkTemp
("Device type B3SOIDD not available in this binary\n");
("Device type BSIM5 not available in this binary\n");
}
break;
case 14:
type = INPtypelook("BSIM4");
case 16:
type = INPtypelook("BSIM6");
if (type < 0) {
err =
INPmkTemp
("Device type BSIM4 not available in this binary\n");}
("Device type BSIM6 not available in this binary\n");}
break;
case 15:
type = INPtypelook("BSIM5");
case 17:
type = INPtypelook("HiSIM1");
if (type < 0) {
err =
INPmkTemp
("Placeholder: Device type BSIM5 not available in this binary\n");
("Placeholder: Device type HiSIM1 not available in this binary\n");
}
break;
case 16:
type = INPtypelook("BSIM6");
case 29:
type = INPtypelook("B3SOIPD");
if (type < 0) {
err =
INPmkTemp
("Placeholder: Device type B3SOIPD not available in this binary\n");
}
break;
case 30:
type = INPtypelook("B3SOIFD");
if (type < 0) {
err =
INPmkTemp
("Placeholder: Device type B3SOIFD not available in this binary\n");
}
break;
case 31:
type = INPtypelook("B3SOIDD");
if (type < 0) {
err =
INPmkTemp
("Placeholder: Device type BSIM6 not available in this binary\n");
("Placeholder: Device type B3SOIDD not available in this binary\n");
}
break;
case 44:
@ -315,21 +331,37 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab)
}
break;
case 49:
type = INPtypelook("BSIM3V1");
type = INPtypelook("BSIM3v1S");
if (type < 0) {
err =
INPmkTemp
("Device type BSIM3V1 not available in this binary\n");
("Device type BSIM3v1S not available in this binary\n");
}
break;
case 50:
type = INPtypelook("BSIM3V2");
type = INPtypelook("BSIM3v1");
if (type < 0) {
err =
INPmkTemp
("Device type BSIM3v1 not available in this binary\n");
}
break;
case 51:
type = INPtypelook("BSIM3v1A");
if (type < 0) {
err =
INPmkTemp
("Device type BSIM3V2 not available in this binary\n");
("Device type BSIM3v1A not available in this binary\n");
}
break;
case 52:
type = INPtypelook("BSIM3v0");
if (type < 0) {
err =
INPmkTemp
("Device type BSIM3v0 not available in this binary\n");
}
break;
case 60:
type = INPtypelook("SOI");
if (type < 0) {
@ -468,6 +500,62 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab)
INPmakeMod(modname, type, image);
}
#ifdef CIDER
else if(strcmp(typename,"numd") == 0) {
err = INPfindLev(line,&lev);
switch( lev ) {
case 1:
default:
type = INPtypelook("NUMD");
if(type < 0) {
err =
INPmkTemp
("Device type NUMD not available in this binary\n");
}
break;
case 2:
type = INPtypelook("NUMD2");
if(type < 0) {
err =
INPmkTemp
("Device type NUMD2 not available in this binary\n");
}
break;
}
INPmakeMod(modname,type,image);
} else if(strcmp(typename,"nbjt") == 0) {
err = INPfindLev(line,&lev);
switch( lev ) {
case 1:
default:
type = INPtypelook("NBJT");
if(type < 0) {
err =
INPmkTemp
("Device type NBJT not available in this binary\n");
}
break;
case 2:
type = INPtypelook("NBJT2");
if(type < 0) {
err =
INPmkTemp
("Device type NBJT2 not available in this binary\n");
}
break;
}
INPmakeMod(modname,type,image);
} else if(strcmp(typename,"numos") == 0) {
type = INPtypelook("NUMOS");
if(type < 0) {
err =
INPmkTemp
("Device type NUMOS not available in this binary\n");
}
INPmakeMod(modname,type,image);
}
#endif /* CIDER */
/* type poly added by SDB . . . */
#ifdef XSPICE
/* -------- Check if model is a poly (specific to xspice) --------- */

273
src/spicelib/parser/inpgmod.c

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Author: 1985 Thomas L. Quarles, 1991 David A. Gates
Modified: 2001 Paolo Nenzi (Cider Integration)
**********/
#include "ngspice.h"
@ -11,6 +12,21 @@ Author: 1985 Thomas L. Quarles
#include "fteext.h"
#include "inp.h"
#ifdef CIDER
/* begin Cider Integration */
#include "numcards.h"
#include "carddefs.h"
#include "numgen.h"
#include "suffix.h"
extern IFcardInfo *INPcardTab[];
extern int INPnumCards;
#define E_MISSING -1
#define E_AMBIGUOUS -2
/* end Cider Integration */
#endif /* CIDER */
extern INPmodel *modtab;
char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab)
@ -65,6 +81,21 @@ char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab)
if (error)
return (INPerror(error));
/* parameter isolation, identification, binding */
#ifdef CIDER
/* begin cider integration */
/* Handle Numerical Models Differently */
if ( ((modtmp)->INPmodType == INPtypelook("NUMD")) ||
((modtmp)->INPmodType == INPtypelook("NBJT")) ||
((modtmp)->INPmodType == INPtypelook("NUMD2")) ||
((modtmp)->INPmodType == INPtypelook("NBJT2")) ||
((modtmp)->INPmodType == INPtypelook("NUMOS")) ) {
error = INPparseNumMod( ckt, modtmp, tab, &err );
if (error) return(INPerror(error));
} else {
/* It's an analytical model */
#endif /* CIDER */
line = ((modtmp)->INPmodLine)->line;
#ifdef TRACE
@ -121,6 +152,9 @@ char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab)
}
FREE(parm);
}
#ifdef CIDER
} /* analytical vs. numerical model parsing */
#endif
(modtmp)->INPmodUsed = 1;
(modtmp)->INPmodLine->error = err;
}
@ -142,3 +176,240 @@ char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab)
return (err);
}
#ifdef CIDER
/*
* Parse a numerical model by running through the list of original
* input cards which make up the model
* Given:
* 1. First card looks like: .model modname modtype <level=val>
* 2. Other cards look like: +<whitespace>? where ? tells us what
* to do with the next card:
* '#$*' = comment card
* '+' = continue previous card
* other = new card
*/
int
INPparseNumMod( ckt, model, tab, errMessage )
void* ckt;
INPmodel *model;
INPtables *tab;
char **errMessage;
{
card *txtCard; /* Text description of a card */
GENcard *tmpCard; /* Processed description of a card */
IFcardInfo *info; /* Info about the type of card located */
char *line;
char *cardName = NULL; /* name of a card */
char *parm; /* name of a parameter */
int cardType; /* type/index for the current card */
int cardNum = 0; /* number of this card in the overall line */
int lastType = E_MISSING; /* type of previous card */
char *err = NULL, *tmp; /* Strings for error messages */
IFvalue *value;
int error, idx, invert;
/* Chase down to the top of the list of actual cards */
txtCard = model->INPmodLine->actualLine;
/* Skip the first card if it exists since there's nothing interesting */
/* txtCard will be empty if the numerical model is empty */
if (txtCard) txtCard = txtCard->nextcard;
/* Now parse each remaining card */
while (txtCard) {
line = txtCard->line;
cardType = E_MISSING;
cardNum++;
/* Skip the initial '+' and any whitespace. */
line++;
while (*line == ' ' || *line == '\t')
line++;
switch (*line) {
case '*':
case '$':
case '#':
case '\0':
case '\n':
/* comment or empty cards */
lastType = E_MISSING;
break;
case '+':
/* continuation card */
if (lastType >= 0) {
cardType = lastType;
while (*line == '+') line++; /* Skip leading '+'s */
} else {
tmp = (char *)xmalloc((55)*sizeof(char));
(void) sprintf(tmp,
"Error on card %d : illegal continuation \'+\' - ignored",
cardNum);
err = INPerrCat(err,tmp);
lastType = E_MISSING;
break;
}
/* FALL THRU when continuing a card */
default:
if (cardType == E_MISSING) {
/* new command card */
if (cardName) FREE(cardName); /* get rid of old card name */
INPgetTok(&line,&cardName,1); /* get new card name */
if (*cardName) { /* Found a name? */
cardType = INPfindCard(cardName,INPcardTab,INPnumCards);
if (cardType >= 0) {
/* Add card structure to model */
info = INPcardTab[cardType];
error = (*(info->newCard))( (void *)&tmpCard,
model->INPmodfast );
if (error) return(error);
/* Handle parameter-less cards */
} else if (cinprefix( cardName, "title", 3 ) ) {
/* Do nothing */
} else if (cinprefix( cardName, "comment", 3 ) ) {
/* Do nothing */
} else if (cinprefix( cardName, "end", 3 ) ) {
/* Terminate parsing */
txtCard = ((card *) 0);
cardType = E_MISSING;
} else {
/* Error */
tmp =(char *)xmalloc((55+strlen(cardName))*sizeof(char));
(void) sprintf(tmp,
"Error on card %d : unrecognized name (%s) - ignored",
cardNum, cardName );
err = INPerrCat(err,tmp);
}
}
}
if (cardType >= 0) { /* parse the rest of this line */
while (*line) {
/* Strip leading carat from booleans */
if (*line == '^') {
invert = TRUE;
*line++; /* Skip the '^' */
} else {
invert = FALSE;
}
INPgetTok(&line,&parm,1);
if (!*parm)
break;
idx = INPfindParm(parm, info->cardParms, info->numParms);
if (idx == E_MISSING) {
/* parm not found */
tmp = (char *)xmalloc((60+strlen(parm)) * sizeof(char));
(void)sprintf(tmp,
"Error on card %d : unrecognized parameter (%s) - ignored",
cardNum, parm);
err = INPerrCat(err, tmp);
} else if (idx == E_AMBIGUOUS) {
/* parm ambiguous */
tmp = (char *)xmalloc((58+strlen(parm)) * sizeof(char));
(void)sprintf(tmp,
"Error on card %d : ambiguous parameter (%s) - ignored",
cardNum, parm);
err = INPerrCat(err, tmp);
} else {
value = INPgetValue( ckt, &line,
((info->cardParms)[idx]).dataType, tab );
if (invert) { /* invert if it's a boolean entry */
if (((((info->cardParms)[idx]).dataType)&IF_VARTYPES)
== IF_FLAG) {
value->iValue = 0;
} else {
tmp =(char *)xmalloc((63+strlen(parm))*sizeof(char));
(void)sprintf(tmp,
"Error on card %d : non-boolean parameter (%s) - \'^\' ignored",
cardNum, parm);
err = INPerrCat(err, tmp);
}
}
error = (*(info->setCardParm))(
((info->cardParms)[idx]).id, value, tmpCard );
if (error) return(error);
}
FREE(parm);
}
}
lastType = cardType;
break;
}
if (txtCard) txtCard = txtCard->nextcard;
}
*errMessage = err;
return( 0 );
}
/*
* Locate the best match to a card name in an IFcardInfo table
*/
int
INPfindCard( name, table, numCards )
char *name;
IFcardInfo *table[];
int numCards;
{
int test;
int match, bestMatch;
int best;
int length;
length = strlen(name);
/* compare all the names in the card table to this name */
best = E_MISSING;
bestMatch = 0;
for ( test = 0; test < numCards; test++ ) {
match = cimatch( name, table[test]->name );
if ((match == bestMatch ) && (match > 0)){
best = E_AMBIGUOUS;
} else if ((match > bestMatch) && (match == length)) {
best = test;
bestMatch = match;
}
}
return(best);
}
/*
* Locate the best match to a parameter name in an IFparm table
*/
int
INPfindParm( name, table, numParms )
char *name;
IFparm *table;
int numParms;
{
int test, best;
int match, bestMatch;
int id, bestId;
int length;
length = strlen(name);
/* compare all the names in the parameter table to this name */
best = E_MISSING;
bestId = -1;
bestMatch = 0;
for ( test = 0; test < numParms; test++ ) {
match = cimatch( name, table[test].keyword );
if ( (match == length) && (match == strlen(table[test].keyword)) ) {
/* exact match */
best = test;
/* all done */
break;
}
id = table[test].id;
if ((match == bestMatch) && (match > 0) && (id != bestId)) {
best = E_AMBIGUOUS;
} else if ((match > bestMatch) && (match == length)) {
bestMatch = match;
bestId = id;
best = test;
}
}
return(best);
}
#endif /* CIDER */
Loading…
Cancel
Save