which silently dropped the
here->initialized = MIF_FALSE
aspect of the MIFunsetup() function
which caused segfault in testcase
examples/memristor/memristor_x.sp
and use a more robust test for local node numbers.
That is, transform this pattern :
if (here->Node && ...) {
CKTdltNNum(ckt, here->Node);
here->Node = 0;
}
into this :
if (here->Node > 0 && ...)
CKTdltNNum(ckt, here->Node);
here->Node = 0;
The change of "!= 0" ==> "> 0" accounts for rare cases where "Node"
might have been set to -1, (meaning "unconnected")
The unconditional execution of the zero assignment is for those cases
where "Node" might have been assigned to some external or other local Node.
If so, the variable would not be set to zero, confusing the "guarding" if's
in the corresponding XXXsetup() routine.
The Pattern to follow is:
1) unset and delete *all* local Nodes in XXXunsetup()
2) allocate all of them again in a re-invocation of XXXsetup(),
exactly the same way as in the very first invocation.
for almost all other external nodes (notable exception "txl")
src/spicelib/devices/*/*def*.h, declare external node variables const
1) The compiler shall emit an error message if we still mess around
with external node numbers.
2) To mark which elements of the instance struct are meant to be set
externally when parsing the netlist
These "external" node variables are exclusively set via the
overlay struct GENinstance, member GENnode[]
We shall not mess around with these "external" node variables
because it would get rather difficult to avoid bugs considering
re-invocation of the XXXsetup() routine.
This gets interesting for devices with optional ports,
which get copied around depending on the amount of connected ports.
All locally created nodes (CKTmk..() invocations in XXXsetup())
must be deleted in XXXunsetup()
Otherwise CKTmk..() invocations during a following CKTsetup()
will re-emit still used node numbers,
thus accidentally shorting nodes.
This patch fixes the complex cases,
which are external node variables (ports of the instance),
which might be moved over to other external node variables
to cope with optional port connections.
This is fixed by copying the node numbers to local shadow variables
to avoid messing with the external nodes.
Otherwise a following CKTsetup() might again meddle with the external
node variables, at least causing considerable confusion, probably causing
hard to find bugs.
All locally created nodes (CKTmk..() invocations in XXXsetup())
must be deleted in XXXunsetup()
Otherwise CKTmk..() invocations during a following CKTsetup()
will re-emit still used node numbers,
thus accidentally shorting nodes.
This patch fixes a little bit more complex cases,
which are local node variables which will start with value 0
and eventually be set with the result of a CKTmk..() invocations,
but might as well receive a node number from another node variable.
Here CKTdltNNum() must not be invoked if the node number is merely
a copy from another node variable.
All locally created nodes (CKTmk..() invocations in XXXsetup())
must be deleted in XXXunsetup()
Otherwise CKTmk..() invocations during a following CKTsetup()
will re-emit still used node numbers,
thus accidentally shorting nodes.
This patch fixes the simple cases,
which are local node variables which will start with value 0
and eventually be set with the result of a CKTmk..() invocation.
More complex cases evolve, if such a local variable might receive
a node number which origins from another node, or the netlist itself.
Invoke CKTdltNNum() in reverse order of local node creation in XXXsetup()
This fixes a bug at least in mesa and hfet1,
where already destroyed node variables have still been accessed
in the guarding 'if' of a later CKTdltNNum() stanza.
Invoking them in revers order easily prevents such bugs,
and improves readability.
Consider the following silent contracts:
1)
CKTsetup() invocations must be separated by a CKTunsetup() invocation
But CKTsetup() has an internal flag,
which will prevent re-invocation of DEVsetup()
But DEVsetup() will be called during sensitivity analysis,
bypassing this precaution. It is fatal if this will
cause another node allocation (CKTmk..()).
This commit tries to detect such cases.
(Note: many DEVsetup routines (all ?) have their CKTmk..() invocations
guarded to avoid reallocation of local nodes,
see commit f7f454c0a1
bug fix, fix the guard for device generated internal nodes (via CKTmkVolt())
)
FIXME:
DEVsetup() is seriously obfuscated by these guards.
If would be far better, if the sensitivity analysis
wouldn't sidestep into DEVsetup()
consider a device local variant of the CKTisSetup flag
2)
DEVunsetup() must delete all, each and every,
local allocated node in DEVsetup()
Otherwise CKTmk..() invocations in a following CKTsetup() will
return duplicate node numbers, effectively shorting device nodes.
This commit tries to detect incomplete CKTdltNNum() invocations.
3)
DEVunsetup() must not delete a netlist node.
This can easily happen in those devices which have optional ports,
which have code in DEVsetup() which copies node numbers to
local node variables.
This commit tries to detect such errors.
Allow to register a callback function in the cfunc.mod files,
which will be invoked in MIFdestroy.
Usefull to "free" memory which has been allocated locally in a cfunc.mod file.
For developing purpose only, and bound to HAVE_TSEARCH, HAVE_TDESTROY
IFparm descriptors must obey certain contracts,
1) aliases must be grouped together with their associated main descriptor,
and all must have flag IF_REDUNDANT set
2) there shall be no duplicated .id fields except for aliases.
3) aliased entries shall have consistent .dataType fields
check_ifparm will traverse all IFparm sets and report violations
try to make it more robust with regard to
'!=' '<=' '==' don't misinterpret as '='
"atemperaticvariable" don't misinterpret as 'temper'
multiple temper in one expression
https://sourceforge.net/p/ngspice/bugs/315/
longjmp() creates segfault under Windows 10 (VS and MINGW)
somewhere when MainWindowProc() is processing the WM_CLOSE message.
Instead of raising SIGINT, directly call cp_doquit().
return 0 if "askquit" is set and the user declines to "quit".
This continues the simulation, if still active.
When translating an instance_name in a subcircuit instance 'xfoo'
undconditionally express the exception for 'x' instances, which is:
x42 --> xsub.x42
but for all others the first char (the devtype) is prepended
r42 --> r.xsub.r42
Emit an error message when unable to identify a valid modelname token.
If a default model is needed, then create one explicitly:
m1 1 2 3 4 mosdefault
.model mosdefault mos1()
Allow to override the admsXml executable when invoking
autogen.sh and configure.ac
ADMSXML=/foo/bar/baz/admsXml ./autogen.sh --adms
ADMSXML=/foo/bar/baz/admsXml ./configure --enable-adms
alternatively (and more advertised)
./configure ADMSXML=/foo/bar/baz/admsXml --enable-adms
The generated Makefiles remember the given path.
A relative path doesn't make sense of course.
Which is needed to release the allocated circuit nodes in
the corresponding adms generated DEVsetup() routine.
This is required when invoking CKTsetup() more than once
without an intervening "reset".
Tie ports 4 and up to ground, iff not connected.
Actually, I think the model's DEVsetup routine should do this business,
we should pass -1 to denote the fact of being unconnected
If a default model is needed, then create one explicitly:
q1 1 2 3 npndefault
.model npndefault npn()
Note:
This code was buggy anyway because the last token,
which turned out not to be a valid model name,
was silently swallowed.
Thus PARSECALL() didn't parse the whole thing.
Thats a functional change of ngspice.
So far we did cook up a "default" model when we didn't find a model token.
But this was buggy anyway, because in such cases we silently dropped
a token from beeing processed by PARSECALL()
Now, we emit a message, and skip this line alltogether.
Note:
This commit does not change behaviour in any way,
yet one can instantly see some sickness now.
Some of the models definitely do not have 7 nodes,
Actually we would like to fetch the number of terminals from
struct IFdevice, slot terms or slot numNames
But it turns out several models publish bogus values.
For example "B4SOI", which has 7 nodes, but claims to have 8
which can be dropped to the recently fixed INPgetMod(), see
inpgmod.c, INPgetMod(), bug fix, missing 'model' assignment
Note:
there have been INPgetMod() invocations without initialisation,
causing access to non-initialised memory with the unfixed INPgetMod()
If we have _MSC_VER so we have either CONSOLE HAS_WINGUI or SHARED_MODULE
If we have SHARED_MODULE, then we most certainly don't need
the unbuffered read(), which isn't unbuffered on _MSC_VER anyway.
Thus _MSC_VER is sufficient.
concerning the visual sudio variant of the "console" build.
Their _read() returns 0 when a linfeed is read.
Ironically the linefeed seems to be stored into the buffer nontheless.
Because the filehandle is in linebuffered mode anyway,
(the read won't return up until the terminating newline is entered)
we can just as well use getc(), which doesn't seem to suffer
from the same problem in their implementation.
default is 2, maximum verbosity
option indverbosity=1
can be used to prevent check for
"incomplete set of couplings"
option indverbosity=0
can be used to avoid the check altogether
set indverbosity=INTEGER
or
.option indverbosity=INTEGER
works as well