tclspice 0.2.7 import

This commit is contained in:
stefanjones 2002-11-26 11:38:25 +00:00
parent 0a5432d1eb
commit 2c0986a169
1472 changed files with 194862 additions and 19095 deletions

75
AUTHORS
View File

@ -1,39 +1,40 @@
@c This file will be processed with texinfo.
SPICE was originally written at The University of Berkeley (USA).
Since then, there have been many people working on the software.
The following people have contributed in some way:
Giles C. Billingsley,
Mansun Chan,
Wayne A. Christopher,
Glao S. Dezai <dezai@@hotbot.com>,
Daniele Foci <d.foci@@ieee.ing.uniroma1.it>,
Noah Friedman <friedman@@prep.ai.mit.edu>,
David A. Gates,
Alan Gillespie <alan.gillespie@@analog.com>,
JianHui Huang,
Jeffrey M. Hsu,
S. Hwang,
Chris Inbody <cinbody@@cowtown.net>,
Gordon M. Jacobs,
Min-Chie Jeng,
Kenneth H. Keller,
Mathew Lew,
Weidong Liu,
Richard D. McRoberts,
Manfred Metzger <ManfredMetzger@@gmx.de>,
Paolo Nenzi <pnenzi@@ieee.ing.uniroma1.it>,
Gary W. Ng,
Hong June Park,
Arno Peters <A.W.Peters@@ieee.org>,
Serban-Mihai Popescu <serbanp@@ix.netcom.com>,
Thomas L. Quarles,
Emmanuel Rouat <emmanuel.rouat@@wanadoo.fr>,
Jaijeet S. Roychowdhury,
Takayasu Sakurai,
Kanwar Jit Singh,
Andrew Tuckey <Tuckey@@ieee.org>
Michael Widlok <widlok@@uci.agh.edu.pl>,
and many others...
Contributors:
-------------
Giles C. Billingsley
Mansun Chan
Wayne A. Christopher
Noah Friedman <friedman@prep.ai.mit.edu>
David A. Gates
JianHui Huang
Jeffrey M. Hsu
S. Hwang
Gordon M. Jacobs
Min-Chie Jeng
Kenneth H. Keller
Mathew Lew
Weidong Liu
Gary W. Ng
Hong June Park
Thomas L. Quarles
Jaijeet S. Roychowdhury
Takayasu Sakurai
Kanwar Jit Singh
Andrew Tuckey <Tuckey@ieee.org>
NGSPICE is now actively hacked by:
* Glao S. Dezai <dezai@hotbot.com>
* Daniele Foci <d.foci@ieee.ing.uniroma1.it>
* Chris Inbody <cinbody@cowtown.net>
* Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
* Arno Peters <A.W.Peters@ieee.org>
* Serban-Mihai Popescu <serbanp@ix.netcom.com>
* Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Michael Widlok <widlok@uci.agh.edu.pl>
(and many others...)
If you feel you should be on this list, write to
<ngspice-user@lists.sourceforge.net>.

7
BUGS Normal file
View File

@ -0,0 +1,7 @@
This file contais a list of known but not yet fixed bugs in ngspice.
====================================================================
Rework 14:
If you run tests in the test tree, you will discover that some
of them fails because of a different value in "Reference Value".
Anyway, analyses results are not affected.

235
ChangeLog
View File

@ -1,3 +1,238 @@
2001-12-05 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in: removed (unnecessary) macros to handle GNU getopt
(I'm an idiot!)
2001-12-04 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in, main.c: Forgot a bit to handle GNU getopt correctly
2001-11-25 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* configure.in: New way (cleaner) to handle GNU getopt.
2001-01-21 Paolo Nenzi <p.nenzi@ieee.org>
* bsim3soi_dd/*: BSIM3SOI (DD) support added as level 11. Added tests in
tests directory (tests/bsim3soidd/*).
* ???: Integrated patch form Alan Gillespie <Alan.Gillespie@analog.com>
to revert the spice raw format to the spice3 original.
* configure.in: corrected a bug that broke the on line help system.
Help system now works again but its text is a little bit outdated.
* ???: all binaries now have ng prependend, so ngspice can be installed
with other spice flavours.
2000-10-18 Arno W. Peters <A.W.Peters@ieee.org>
* Makefile.am: Changes for notes dir -> NOTES file conversion.
* tests/Makefile.am: Make distcheck target work again.
2000-10-17 Arno W. Peters <A.W.Peters@ieee.org>
* TODO: Little updates.
2000-10-14 Arno W. Peters <A.W.Peters@ieee.org>
* acconfig.h, configure.in, src/frontend/inpcom.c,
src/include/complex.h src/include/macros.h, src/include/memory.h
src/include/ngspice.h, src/maths/cmaths/Makefile.am
src/maths/cmaths/cmath1.c, src/maths/cmaths/cmath2.c
src/maths/cmaths/cmath3.c, src/maths/cmaths/cmath4.c
src/maths/cmaths/test_cx_j.c, src/maths/cmaths/test_cx_mag.c
src/maths/cmaths/test_cx_ph.c, src/misc/alloc.c src/misc/alloc.h:
Added support for the Boehm-Weiser conservative garbage collector.
* NOTES, src/maths/cmaths/cmath.h: Added.
* notes/Linux.changes, notes/dbx, notes/internal, notes/mac_port
notes/porting, notes/spice2: Removed or incorporated into
NOTES.
* *: replaced malloc, realloc and free calls to use tmalloc,
trealloc and txfree.
2000-09-05 Arno W. Peters <A.W.Peters@ieee.org>
* ???: Paolo and I have integrated patches from Alan Gillespie
<Alan.Gillespie@analog.com>.
2000-07-28 Arno W. Peters <A.W.Peters@ieee.org>
* tests/polezero/*.out: Changed the content of these files because
the bug that caused the incorrect pole-zero results have been
traced to src/spicelib/analysis/cktpzstr.c.
2000-07-05 Arno W. Peters <A.W.Peters@ieee.org>
* src/devices/dev.c: Added first_device() and next_device() to
abstract manipulations to the devices list. Now change all the
code that uses direct access to these functions...
2000-07-03 Arno W. Peters <A.W.Peters@ieee.org>
* src/parser/alias.c, src/parser/alias.h: contain frontend alias
command. Moved them to src/frontend/com_alias.c and
src/frontend/com_alias.h. Updated Makefile.am's as appropreate.
* src/parser/front.c, src/parser/front.h, src/parser/history.c,
src/parser/history.h, src/parser/modify.c, src/parser/modify.h,
src/parser/variable.c, src/parser/variable.h: Empty files.
Removed.
* src/include/spconfig.h: Removed spCOMPLEX,
spSEPARATED_COMPLEX_VECTORS and spCOMPATIBILITY defines. This
made including this file from src/include/spmatrix.h unnecessary.
Moved this file to src/maths/sparse/spconfig.h.
* src/include/spmatrix.h: Removed include of
src/include/spconfig.h.
* src/maths/sparse/spalloc.c, src/maths/sparse/spbuild.c,
src/maths/sparse/spcombin.c, src/maths/sparse/spdefs.h,
src/maths/sparse/spfactor.c, src/maths/sparse/spoutput.c,
src/maths/sparse/spsmp.c, src/maths/sparse/spsolve.c,
src/maths/sparse/sputils.c: The other files affected by the
removal of spCOMPLEX, spSEPARATED_COMPLEX_VECTORS and
spCOMPATIBILITY defines. Also: assertions are enabled by
default.
* src/include/smpdefs.h, src/maths/sparse/spsmp.c: SMPmatrix is
now a typedef for void, instead of char. Updated all function
declarations to match this. Also added function prototypes not
previously mentioned in src/include/smpdefs.h.
* src/include/complex.h: Updates of cast from char * to void *
* src/analysis/cktsens.c: Matrixes cannot be created non-complex.
Also added a check to detect an error condition on delta_Y =
spCreate(...).
2000-06-27 Arno W. Peters <A.W.Peters@ieee.org>
* src/parser: Refactored commands from the frontend into the
frontend directory. Major changes to organization, but not to
functionality.
2000-06-19 Arno W. Peters <A.W.Peters@ieee.org>
* src/analysis/cktask.c: moved to src/devices.
* src/analysis/cktbindn.c: moved, renamed to
src/devices/cktbindnode.c.
* src/analysis/cktfdev.c: moved, renamed to
src/devices/cktfinddev.c.
2000-06-18 Arno W. Peters <A.W.Peters@ieee.org>
* AUTHORS, doc/ngspice.texi: Included an acknowledgements
section.
2000-06-16 Arno W. Peters <A.W.Peters@ieee.org>
* src/frontend/doplot.c: Refactored into the following files:
src/frontend/com_asciiplot.c src/frontend/com_asciiplot.h
src/frontend/com_hardcopy.c src/frontend/com_hardcopy.h
src/frontend/com_plot.c src/frontend/com_plot.h
src/frontend/com_xgraph.c src/frontend/com_xgraph.h
src/frontend/plotting/plotit.c src/frontend/plotting/plotit.h
* src/frontend/Makefile.am src/frontend/plotting/Makefile.am:
Updated to match the new files.
2000-06-15 Arno W. Peters <A.W.Peters@ieee.org>
* src/frontend/graphdb.c, src/frontend/graphdb.c,
src/frontend/Makefile.am, src/frontend/plotting/graphdb.c,
src/frontend/plotting/graphdb.c,
src/frontend/plotting/Makefile.am: Moved plotting specific files
into plotting directory.
2000-06-05 Arno W. Peters <A.W.Peters@ieee.org>
* tests/*: Added a little hierarchy to the tests. Removed
config.sh in favor of check.sh. This script does all checking.
Made names of the tests better reflect the circuit under test.
2000-06-03 Arno W. Peters <A.W.Peters@ieee.org>
* src/include/complex.h, src/include/macros.h,
src/include/memory.h, src/maths/sparse/spdefs.h: Moved definitions
of complex into complex.h. There are three different ways to
declare a complex number in Spice. We need further work to reduce
this to only one.
* src/maths/cmaths/Makefile.am, src/maths/cmaths/.cvsignore,
src/maths/cmaths/test_cx_ph.c: Added a new test and updated the
corresponding support files.
2000-06-02 Arno W. Peters <A.W.Peters@ieee.org>
* src/circuit/inp2dot.c: Refactoring introduced a bug in the line
parsing. Passing line as an extra parameter to the refactored
functions fixes the bug.
2000-05-30 Arno W. Peters <A.W.Peters@ieee.org>
* TODO: Updated.
* src/maths/cmaths/Makefile.am, src/maths/cmaths/test_cx_mag.c,
src/maths/cmaths/test_cx_j.c: Added first testcases for complex
math library.
2000-05-25 Arno W. Peters <A.W.Peters@ieee.org>
* src/circuit/inp2dot.c: First refactoring of INP2dot into smaller
functions. Still needs work.
* src/circuit/sperror.c: Reworked, now much simpler.
* src/include/inpdefs.h, src/include/sperror.h: Removed redundancy
in the definition of function prototypes.
2000-05-06 Arno W. Peters <A.W.Peters@ieee.org>
* src/include/fte*: Broken header files into smaller pieces. This
avoids long recompile times as less needs to be rebuilt on changes
to the header files. Adjusted all callers to use the new header
files. Left a warning message in the header file to indicate its
obsolence. You will see this message when compiling.
* src/frontend/*: Reorganized part of the frontend commands into
their own source file. Moved plotting parts into new plotting
directory.
* src/devices/*: Removed all RCS log and rcsid from the devices
source files. They only give extra clutter and all the
information you need is available through CVS.
2000-05-04 Arno W. Peters <A.W.Peters@ieee.org>
* src/maths/ni/nipzmeth.c: Corrected an overeager deletion.
2000-05-03 Arno W. Peters <A.W.Peters@ieee.org>
* source tree: removed most of `#ifdef notdef' and made converted
some function calls from K&R -> ANSI.
2000-05-01 Arno W. Peters <A.W.Peters@ieee.org>
* Added .cvsignore files to prevent CVS from marking generated
files as unknown.
* src/devices/Makefile.am, src/devices/dev.c, src/devices/dev.h,
src/Makefile.am, src/ngspice.c, src/main.c: Refactored devices
initialization code into the devices dir.
* tests/respart.cir, tests/respart.out, tests/respart.sh:
additional tests for resistor.
1999-12-07 Arno Peters <A.W.Peters@ieee.org>
* source tree: Added MAINTAINERCLEANFILES to Makefile.am to

167
DEVICES
View File

@ -1,167 +0,0 @@
DEVICES
-------------------------------------------------------------------------------
This file contains the status of devices available in ng-spice. This file will
be updated every time the device cospecific code is altered/changed.
**************************************
********** Linear devices **********
**************************************
CAP - Capacitor
Initial Release
IND - Inductor
Initial Release
RES - Resistor
This is a modified version of the spice3 resistance model. This model
supports different ac and dc values (ac=...). This changes are
introduced by Serban Popescu. This device needs more testing.
TO BE TESTED AND IMPROVED.
**************************************
******** Distributed elements ********
**************************************
TRA - Transmission line
Initial release
LTRA - Lossy Transmission line
Initial release
URC - Uniform distributed RC line
Initial release
**************************************
********** V/I Sources **********
**************************************
ASRC - Arbitrary Source
Initial Release
CCCS - Current Controlled Current Source
Initial Release
CCVS - Current Controlled Voltage Source
Initial Release
ISRC - Independent Current Source
Initial Release
VCCS - Voltage Controlled Current Source
Initial Release
VCVS - Voltage Controlled Voltage Source
Initial Release
VSRC - Indipendent Voltage Source
Initial Release
**************************************
********* Switches **********
**************************************
CSW - Current controlled switch
Initial release
SW - Voltage controlled switch
Initial release
**************************************
********** Diodes **********
**************************************
DIO - Junction Diode
Initial Release
**************************************
*********** Bipolar Devices **********
**************************************
BJT - Bipolar Junction Transistor
Initial Relelase
**************************************
********** FET Devices **********
**************************************
JFET - Junction Field Effect transistor
Initial Release
JFET2 - Jfet PS model
Initial release. TO BE TESTED
**************************************
********* MES devices *********
**************************************
MES - MESfet model
Initial release
**************************************
********* MOS devices *********
**************************************
MOS1 - Level 1 MOS model
Initial Release
MOS2 - Level 2 MOS model
Initial Release
MOS3 - Level 3 MOS model
Initial Release
MOS6 - Level 6 MOS model
Initial Release
BSIM1 - BSIM model level 1
Initial Release
BSIM2 - BSIM model level 2
Initial Release
BSIM3 - BSIM model level 3
This is the BSIM3v3.2.2 model from Berkeley device group.
You can find some test netlists with results for this model
at http://www-device.eecs.berkeley.edu/~bsim3.
BSIM3v1 - BSIM model level 3
This is the BSIM3v3.1 model modified by Serban Popescu. This
is level 49 model. It is an implementation that supports
HDIF and M parameters. Test netlists are available at the URL
above.
TO BE TESTED AND IMPROVED.
BSIM3v2 - BSIM model level 3
This is the BSIM3v3.2 model. It is proved only for compatibility
with existing netlists and parameters files. As always, tests are
availabe on the Berkeley's device group site (at the above URL).
BSIM4 - BSIM model level 4 (0.18 um)
Initial Release. TO BE TESTED.
**************************************
********** SOI Devices *********
**************************************
BSIM3SOI_DD - SOI model (dynamic depletion)
NOT YET IMPLEMENTED.
BSIM3SOI_FD - SOI model (fully depleted devices)
NOT YET IMPLEMENTED.
BSIM3SOI_PD - SOI model (partially depleted devices)
NOT YET IMPLEMENTED.

530
FAQ
View File

@ -1,299 +1,377 @@
Ngspice F.A.Q.Version 1.0
Maintened by Paolo Nenzi <p.nenzi@ieee.org>
Last update: 05/12/2001
This document contains the Frequently Asked Questions (and Answers)
for ngspice project.
______________________________________________________________________
Table of Contents
NG-Spice F.A.Q.
Frequently Asked Questions
(and Answers)
1. INTRODUCTION AND GENERAL INFORMATION
1.1 What is ngspice?
1.2 Why resurrecting Berkeley's Spice?
1.3 What is the project's goal?
1.4 What you are going to do?
1.5 Legal issues
1.6 What mailing lists exist for ngspice?
1.7 Are the mailing lists archived anywhere?
1.8 What newsgroups exist for ngspice?
1.9 Where can I get a copy of ngspice?
1.10 Where should I look on the World Wide Web for ngspice stuff?
1.11 Where should I look on the World Wide Web for Spice documentation?
Maintened by Daniele Foci <d.foci@ieee.ing.uniroma1.it>
Last update: 29/08/1999
CONTENTS
1. INTRODUCTION AND GENERAL INFORMATION
1.1 What is NG-Spice?
1.2 Why resurrecting Berkeley's Spice?
1.3 What is the project's goal?
1.4 What you are going to do ?
1.5 Legal issues
1.6 What mailing lists exist for NG-Spice?
1.7 Are the mailing lists archived anywhere?
1.8 What newsgroups exist for NG-Spice?
1.9 Where can I get a copy of NG-Spice?
1.10 Where should I look on the World Wide Web for NG-Spice stuff?
2. DEVELOPMENT
2. DEVELOPMENT
2.1 What is the current version?
2.2 What are the latest features in the current release?
2.3 What does it look like ?
2.4 Who are the authors of ng-spice ?
2.3 What does it look like?
2.4 Who are the authors of ngspice?
2.5 How can I report a bug/request for a feature?
2.6 How can I join the development?
3. SOLUTIONS TO COMMON MISCELLANEOUS PROBLEMS
3. SOLUTIONS TO COMMON MISCELLANEOUS PROBLEMS
3.1 What systems are supported?
3.2 I get errors when I try to compile the source code, why?
3.3 This document didn't answer my question. Where else can I look for
an answer?
4. ADMINISTRATIVE INFORMATION AND ACKNOWLEDGEMENTS
3.3 This document didn't answer my question. Where else can I look for an answer?
4. ADMINISTRATIVE INFORMATION AND ACKNOWLEDGEMENTS
4.1 Feedback
4.2 Formats in which this FAQ is available
4.3 Authorship and acknowledgements
4.4 Disclaimer and Copyright
-------------------------------------------------------------------------------
1. INTRODUCTION AND GENERAL INFORMATION
______________________________________________________________________
1.1 What is NG-Spice?
NG-spice is the name of a project and of a program in the project. Spice is
the famous circuit simulator developed by the CAD Group of the University
of California at Berkeley (UCB). The NG prefix has a lot of meanings: Next
Generation, New Good, etc. Choose or invent the one you prefer. The NG-spice
project aims to improve the capabilities of the Spice3 circuit simulator.
The heart of the project is the ng-spice program, a circuit simulator
derived from spice3f5.
1.2 Why resurrecting Berkeley's Spice?
Berkeley's Spice can be considered the father of most circuit simulators
available today. It is an old but still good piece of software, it may not
be the fastest or the most reliable but it's free, it's available in
source code and most of the electrical simulators inherited it's syntax.
On the more technical side, spice3 uses good numerical algorithms
( most commercial implementations have only strengthened them), implements
most of the models for MOSFET submicron designs and has a powerful set of
analyses. On the more "social" side, spice3 it's well introduced in the
academic environment.
1.3 What is the project's goal?
The final goal of NG-spice project is to develop a reliable, fast and
friendly circuit simulator for mixed signal/mixed level simulation.
Easy isn't it ;-).
1.4 What you are going to do?
The NG-spice project is divided in two main overlapping phases. The first
phase is strictly pertinent to the spice3f5 code: during this phase the
original spice3f5 code will be "cleaned" and corrected and small improvements
made to it. In phase one the Autoconf interface will replace the Berkeley's
one and this will lead to a different structure of the sources.
The second phase is the development of improvements in the ngspice code
(the old spice3f5 code cleaned and corrected) and of some programs that will
interface with it, like a schematic editor and a waveform viewer. A list of
proposed improvements follows:
1) The framework (or Graphic User Interface):
Spice is (and should continue to be) a command line or a text tool, but
this makes very difficult to design large circuits. To overcome this
difficulty, a schematic entry tool and a waveform viewer tools are needed.
Nevertheless, there are other tools that can be useful: a parts database,
an editor which higlights the syntax, a symbol editor, etc.
Most of these program already exists in the open source world, so they
need only to be integrated in a common EDA environment.
2) Documentation:
Commercial simulators have very good manuals with tutorials, models
equations explained, example of use, suggestions, etc. This line of
development has the task of providing the final spice user with an ordered
and comprehensive set of information on the program and its features.
The documentation should be useful for the student as well as for the
circuit professional.
3) Improvements to the Spice code:
This is the hard part. The target of this direction is to make ngspice a
commercial grade simulator. This means improving it's speed, its
numerical strenght, include the latest models available and some other
important features:
* Numerical Algorithms:
- More stable algorithms for integration (as Runge-Kutta Methods).
- Better convergence in Operating Point Calculation replacing the
Newton-Raphson algorithm, a modified version of Fixed-Point
Homotopy.
* Devices:
- Behavioral device: enhance the B device of spice3 to accepts IF THEN
ELSE conditions, and digital keywords like DELAY,
HIGHV, LOWV, etc. to simulate simple digital
device.
- Dynamically Loadable Devices: reduce the memory occupied by the
simulator by using shared object code
for devices. Each device is a .so
library that is inserted only if the
circuit contains an element modeled by
the device. If we are simulating CMOS,
we do not need BJT or SOI (in most of
the situations).
- Code Level Modeling: let users write their devices in C and use
them in the simulator.
- Improving device: include additional parameters to some devices as
HDIF, LDIF, etc.
* New types of analysis, oriented to circuits syntesis and optimization:
- Network analysis: given four nodes, extract z,y,s and the other
double bipole paramters.
- Monte Carlo analysis: statistical simulation based on device
tolerances.
- Worst Case analysis: find the worst case of operation of a given
circuit based on device tolerances.
- Parametric analysis: repeat an analysis when one or more parameters
assumes different values.
* Faster handling of sparse matrices.
* Possibility to mesure circuit pameters, like the delay between two
nodes, etc.
* ... whatever else can be judged useful.
11.. IINNTTRROODDUUCCTTIIOONN AANNDD GGEENNEERRAALL IINNFFOORRMMAATTIIOONN
1.5 Legal issues
[not written yet: GPL vs. Berkeley]
11..11.. WWhhaatt iiss nnggssppiiccee??
1.6 What mailing lists exist for NG-Spice?
Ngspice is the name of a project and of a program in the project.
Spice is the famous circuit simulator developed by the CAD Group of
the University of California at Berkeley (UCB). The NG prefix has a
lot of meanings: Next Generation, New Good, etc. Choose or invent the
one you prefer. The ngspice project aims to improve the capabilities
of the Spice3 circuit simulator. The heart of the project is the
ngspice program, a circuit simulator derived from spice3f5.
Only one. Send an empty message to <ng-spice-help@ieee.ing.uniroma1.it> to
have information on subscription.
1.7 Is the mailing lists archived anywhere?
11..22.. WWhhyy rreessuurrrreeccttiinngg BBeerrkkeelleeyy''ss SSppiiccee??
Yes, the list is archived. Send an empty message to
<ng-spice-help@ieee.ing.uniroma1.it> to have information on how to retrieve
old messages.
Berkeley's Spice can be considered the father of most circuit
simulators available today. It is an old but still good piece of
software, it may not be the fastest or the most reliable but it's
free, it's available in source code and most of the electrical
simulators inherited it's syntax. On the more technical side, spice3
uses good numerical algorithms (most commercial implementations have
only strengthened them), implements most of the models for MOSFET
submicron designs and has a powerful set of analyses. On the more
"social" side, spice3 it's well introduced in the academic
environment.
1.8 What newsgroups exist for NG-Spice?
11..33.. WWhhaatt iiss tthhee pprroojjeecctt''ss ggooaall??
The final goal of ngspice project is to develop a reliable, fast and
friendly circuit simulator for mixed signal/mixed level simulation.
Easy isn't it? ;-).
11..44.. WWhhaatt yyoouu aarree ggooiinngg ttoo ddoo??
We are going to develop a circuit simulation program. The line of
development follows two parallel paths:
1. EEnnhhaanncceemmeennttss aanndd bbuugg--ffiixxiinngg ooff tthhee oorriiggiinnaall ssppiiccee33ff55 ccooddee..
2. DDeevveellppppmmeenntt ooff aa nneeww GGPPLL''eedd ssiimmuullaattoorr..
The first phat will lead to a better spice3f5 and nothing more than
this, while the second one will bring us a new simulator,
compatible with its father but more expandable and presumably
faster and numerically stronger.
There is another project in ngspice: the development of one or more
frontend to the new simulator. One of the key issues of our project is
to let users design the front end they want, using the widget set and
the language they prefer. For this reason ngspice differs a lot from
spice3f5: in ngspice there is a clear distinction between the front
end and the back end. In ngspice the front end takes care of the
interaction with the user. It is back-end's task to maintain the
object database, to exchange data with the simulator, etc.
There are various improvements we are planning, some follows:
1. TThhee ffrraammeewwoorrkk ((oorr GGrraapphhiicc UUsseerr IInntteerrffaaccee)):: Spice is (and should
continue to be) a command line or a text tool, but this makes very
difficult to design large circuits. To overcome this difficulty, a
schematic entry tool and a waveform viewer tools are needed.
Nevertheless, there are other tools that can be useful: a parts
database, an editor which higlights the syntax, a symbol editor,
etc. Most of these program already exists in the open source world,
so they need only to be integrated in a common EDA environment.
2. DDooccuummeennttaattiioonn:: Commercial simulators have very good manuals with
tutorials, models equations explained, example of use, suggestions,
etc. This line of development has the task of providing the final
spice user with an ordered and comprehensive set of information on
the program and its features. The documentation should be useful
for the student as well as for the circuit professional.
3. IImmpprroovveemmeennttss ttoo tthhee SSppiiccee ccooddee:: This is the hard part. The target
of this direction is to make ngspice a commercial grade simulator.
This means improving it's speed, its numerical strenght, include
the latest models available and some other important features:
+o Numerical Algorithms:
+o More stable algorithms for integration (as Runge-Kutta
Methods (?) ).
+o Better convergence in Operating Point Calculation adding a
modified version of Fixed-Point Homotopy to the Newton-
Raphson algorithm,
+o Devices:
+o Behavioral device: enhance the B device of spice3 to accepts
IF THEN ELSE conditions, and digital keywords like DELAY,
HIGHV, LOWV, etc. to simulate simple digital macromodels.
+o Dynamically Loadable Devices: reduce the memory occupied by
the simulator by using shared object code for devices. Each
device is a .so library that is inserted only if the circuit
contains an element modeled by the device. If we are
simulating CMOS, we do not need BJT or SOI (in most of the
situations).
+o Code Level Modeling: let users write their devices in C and
use them in the simulator.
+o Improving device: include additional parameters to some
devices as HDIF, LDIF, etc.
+o New types of analysis, oriented to circuits syntesis and
optimization:
+o Network analysis: given four nodes, extract z,y,s and the
other double bipole paramters.
+o Monte Carlo analysis: statistical simulation based on device
tolerances.
+o Worst Case analysis: find the worst case of operation of a
given circuit based on device parameters tolerances.
+o Parametric analysis: repeat an analysis when one or more
parameters assumes different values.
+o Faster handling of sparse matrices.
+o Possibility to mesure circuit pameters, like the delay between
two nodes, etc.
+o Whatever else can be judged useful.
11..55.. LLeeggaall iissssuueess
The improved spice3f5 will be relased under the original Berkeley's
lincese. The new simulator will be released as GPL. Make ngspice a GPL
program, allow us to link a lot of good code laying on the net and
obviously contribute to the GPL community.
11..66.. WWhhaatt mmaaiilliinngg lliissttss eexxiisstt ffoorr nnggssppiiccee??
There are three mailing lists dedicated to the ngspice project. Send
an empty message to the following addresses to get information on
subscription. <ngspice-users-help@lists.sourceforge.net>
<ngspice-devel-help@lists.sourceforge.net>
<ngspice-frontends-help@lists.sourceforge.net>
11..77.. AArree tthhee mmaaiilliinngg lliissttss aarrcchhiivveedd aannyywwhheerree??
Yes, the list are archived. Look at the project's web site to access
archives.
11..88.. WWhhaatt nneewwssggrroouuppss eexxiisstt ffoorr nnggssppiiccee??
None. Sorry.
1.9 Where can I get a copy of NG-Spice?
You can download NG-Spice from:
ftp://ieee.ing.uniroma1.it/pub/ng-spice/distribution/
11..99.. WWhheerree ccaann II ggeett aa ccooppyy ooff nnggssppiiccee??
1.10 Where should I look on the World Wide Web for NG-Spice stuff?
You can download ngspice from:
There is a WWW page for NG-Spice. The URL is:
http://geda.seul.org under the tools section.
<http://sourceforge.net/projects/ngspice>
2. DEVELOPMENT
11..1100.. WWhheerree sshhoouulldd II llooookk oonn tthhee WWoorrlldd WWiiddee WWeebb ffoorr nnggssppiiccee ssttuuffff??
2.1 What is the current version?
Look at the official NG-Spice Web Page
<http://ngspice.sourceforge.net>
0.3 (released on 30/08/1999)
2.2 What are the latest features in the current release?
11..1111.. WWhheerree sshhoouulldd II llooookk oonn tthhee WWoorrlldd WWiiddee WWeebb ffoorr SSppiiccee ddooccuummeennttaa--
ttiioonn??
* New features:
- Autoconf interface.
- BSIM 3.2.2 Model.
- PS jfet Model (jfet level 2).
- Temperature and resistance sweeps.
- "spec" command for spectrum analysis.
50 Circuits analyzed with SPICE
<http://www.dacafe.com/DACafe/EDATools/EDAbooks/SpiceHandBook/01_TOC.html>
* Bug fixes:
- Altermod command connected to the parser.
- Some memory leaks closed.
- Spice3f5 fixes available on the net.
<http://www.dacafe.com/DACafe/EDATools/EDAbooks/SMPS/SMPS.htm>
2.3 What does it look like ?
22.. DDEEVVEELLOOPPMMEENNTT
22..11.. WWhhaatt iiss tthhee ccuurrrreenntt vveerrssiioonn??
rework-14 (released on 10/12/2001)
22..22.. WWhhaatt aarree tthhee llaatteesstt ffeeaattuurreess iinn tthhee ccuurrrreenntt rreelleeaassee??
New features:
+o New functions for vectors: vecmax (find max element in a vector),
vecmin (find minimum element in a vector), vecd (differentiate a
vector).
+o BSIM 4 and support EKV models.
Bug fixes:
+o Some memory leaks closed.
+o Error reporting more verbose
22..33.. WWhhaatt ddooeess iitt llooookk lliikkee??
This is a command line utility, no screenshots!
2.4 Who are the authors of ng-spice ?
22..44.. WWhhoo aarree tthhee aauutthhoorrss ooff nnggssppiiccee??
The development is open to anyone who wish to contribute.
People who contributed are:
* Daniele Foci <d.foci@ieee.ing.uniroma1.it>
* Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
* Arno Peters <A.W.Peters@ieee.org>
* Serban-Mihai Popescu <serbanp@ix.netcom.com>
* Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Michael Widlok <widlok@uci.agh.edu.pl>
This list is surely incomplete (due to open development group), there are
many people who contributed with improvements, pieces of code, bux fixes,
etc. If you have contributed and do not appear, write to:
ng-spice@ieee.ing.uniroma1.it
People who contributed are (in alphabetical order):
+o Daniele Foci <dfoci@ieee.ing.uniroma1.it>
+o Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
+o Arno Peters <A.W.Peters@ieee.org>
+o Serban-Mihai Popescu <serbanp@ix.netcom.com>
+o Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
+o Michael Widlok <twidlok@uci.agh.edu.pl>
This list is surely incomplete (due to open development group), there
are many people who contributed with improvements, pieces of code, bug
fixes, etc. If you have contributed and do not appear, write to:
<ng-spice@ieee.ing.uniroma1.it>
and ask to be included.
2.5 How can I report a bug/request for a feature?
Write in the mailing list.
22..55.. HHooww ccaann II rreeppoorrtt aa bbuugg//rreeqquueesstt ffoorr aa ffeeaattuurree??
2.6 How can I join the development?
Look at the projects summary page: ngspice summary page
To join the development just code the feature you want to add and send your
patch in the mailing list. Before you start coding check the latest
development release of NG-Spice from our CVS. It might be that your feature
has already been implemented.
To access the anonymous CVS do the following:
22..66.. HHooww ccaann II jjooiinn tthhee ddeevveellooppmmeenntt??
1) Install cvs on your machine (version 1.9.x - 1.10.x are just fine).
2) Set one of the following environment variables:
For bash:
export CVSROOT=:pserver:anonymous@ieee.ing.uniroma1.it:/var/services/cvsroot
For csh/tcsh:
setenv CVSROOT :pserver:anonymous@ieee.ing.uniroma1.it:/var/services/cvsroot
3) Login to the cvs server by running:
$> cvs login
The password is 'guest' (without the quotes of course). You will only
have to do this once.
4) Checkout the appropriate files executing the following commands:
$> mkdir somedirectory
$> cd somedirectory
$> cvs co ng-spice
5) Wait for the cvs logout.
To join the development just code the feature you want to add and send
your patch in the mailing list. Before you start coding check the
latest development release of ngspice from our CVS. It might be that
your feature has already been implemented.
3. SOLUTIONS TO COMMON MISCELLANEOUS PROBLEMS
33.. SSOOLLUUTTIIOONNSS TTOO CCOOMMMMOONN MMIISSCCEELLLLAANNEEOOUUSS PPRROOBBLLEEMMSS
3.1 What systems are supported?
33..11.. WWhhaatt ssyysstteemmss aarree ssuuppppoorrtteedd??
This is the updated list:
Hardware O.S. Compiler Functional?
---------------- ------------------ -------------- -----------
i386 Linux (RedHat) gcc yes
i386 Linux (Debian) gcc yes
i386 Linux (SuSE) gcc yes
IBM Risc 6000 AiX lcc no
SUN Solaris 7 gcc yes
SUN Solaris 7 SUN Workshop ?
Hardware O.S. Version Compiler Functional?
---------------- ----------------------- -------------- -----------
???? HP-UX 10.10 gcc 2.95.2 yes
IBM Risc 6000 ??? lcc no
i386 Debian GNU/Linux 2.1 gcc 2.7.2 yes
i386 Red Hat Linux 5.2 gcc 2.7.2 yes
i386 SuSE Linux 6.0 gcc 2.7.2 yes
i386 Linux (SuSE) gcc yes
UltraSPARC Solaris 7 gcc yes
UltraSPARC Solaris 7 SUN Workshop ?
3.2 I get errors when I try to compile the source code, why?
MS-Dos, VMS and MacOS are no longer supported.
33..22.. II ggeett eerrrroorrss wwhheenn II ttrryy ttoo ccoommppiillee tthhee ssoouurrccee ccooddee,, wwhhyy??
[not written yet]
3.3 This document didn't answer my question. Where else can I look for
an answer?
Read old messages from the mailing list archive, search the web site or read
the docs. Upgrade to the latest version of NG-Spice, many problems are fixed
in the new versions. If you still can't find an answer, post your question
to the mailing list.
33..33.. TThhiiss ddooccuummeenntt ddiiddnn''tt aannsswweerr mmyy qquueessttiioonn.. WWhheerree eellssee ccaann II llooookk
ffoorr aann aannsswweerr??
Read old messages from the mailing list archive, search the web site
or read the docs. Upgrade to the latest version of ngspice, many
problems are fixed in the new versions. If you still can't find an
answer, post your question to the mailing list.
4. ADMINISTRATIVE INFORMATION AND ACKNOWLEDGEMENTS
44.. AADDMMIINNIISSTTRRAATTIIVVEE IINNFFOORRMMAATTIIOONN AANNDD AACCKKNNOOWWLLEEDDGGEEMMEENNTTSS
4.1 Feedback
Send your comments about this F.A.Q. to <d.foci@ieee.ing.uniroma1.it>.
Send your comments about NG-Spice to <ng-spice@ieee.ing.uniroma1.it>.
44..11.. FFeeeeddbbaacckk
4.2 Formats in which this FAQ is available
Send your comments about this F.A.Q. to:
This document is available only in ASCII format in the NG-Spice source
Paolo Nenzi <p.nenzi@ieee.org>.
Send your comments about ngspice to:
Paolo Nenzi <p.nenzi@ieee.org>.
44..22.. FFoorrmmaattss iinn wwhhiicchh tthhiiss FFAAQQ iiss aavvaaiillaabbllee
This document is available only in ASCII format in the ngspice source
package.
4.3 Authorship and acknowledgements
44..33.. AAuutthhoorrsshhiipp aanndd aacckknnoowwlleeddggeemmeennttss
Parts of the questions and answers are originate from Paolo Nenzi.
4.4 Disclaimer and Copyright
This document is provided as is. The information in it is not warranted to
be correct: you use it at your own risk.
44..44.. DDiissccllaaiimmeerr aanndd CCooppyyrriigghhtt
This document is provided as is. The information in it is not
warranted to be correct: you use it at your own risk.

View File

@ -2,7 +2,7 @@
SUBDIRS = doc src man tests
EXTRA_DIST = FAQ acconfig.h autogen.sh notes contrib
EXTRA_DIST = FAQ acconfig.h autogen.sh NOTES contrib BUGS
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \
config.h.in config.sub configure install-sh \
@ -13,3 +13,8 @@ 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`
tcl:
cd src && $(MAKE) tcl
tcl_install:
cd src && $(MAKE) tcl_install

224
NEWS
View File

@ -1,16 +1,212 @@
Ng-spice-rework-14
============
This is a major release in terms of bug-fixes. Some enhancements
have been included: BSIM4 model and support for EKV model. The
source code for the latter must be obtained from EKV web site
(see DEVICE for more info). To enable EKV support you have
to obtain the code first and then use the configure switch
"--enable-ekv".
The spice code contains an option to debug frontend code, now
this is available in configure as "--enable-ftedebug".
Ng-spice-rework-13
============
This is a major release in terms of fixes and enhancements.
A garbage collector support has been added. If the configuration
script detects that you have installed GC (Bohem-Weiser conservative
garbage collector), it will use it. Some memory leaks have been
fixed too.
Enhancements to the code comes from Alan's contribute code, a
description of improvements follows (extracted form Alan's mail):
Output File Format Changes -
Rawfile format changed to PSPICE Probe format (Usable with
Demo version of Microsim's Probe).
(NOTE: Do not rely on this, we may revert to the old format
in the next release).
Text mode .OP results even though "rawfile" written.
Internal device nodes are not saved to "rawfile" (reduces
file size). Optionally, these internal nodes can be replaced
by device currents and saved.
DC Convergence Enhancements -
"Source-Stepping" algorithm modified with a "Dynamic" step size.
After each successful step, the node voltages are saved, the
source-factor is increased by the step-factor, and the step-factor
is increased (for the next step). If the step fails, i.e. the
circuit does not converge, the source-factor is set to the value
from the previous successful step, the previously stored node
voltages are restored, the step-factor is reduced, the source
factor is increased by this smaller step-factor, and convergance
is attempted again.
Same thing done for "Gmin-stepping" algorithm.
"Gshunt" option added. This sets the "diagGmin" variable used in
the gmin-stepping algorithm to a non-zero value for the final
solution. (Normally this is set to zero for the final solution).
This helps for circuits with floating nodes (and for some others
too).
The Gmin implementation across the substrate diodes of MOS1, MOS2,
MOS3, MOS6 and BSIM3 devices, and across BJT base-emitter and
base-collector diodes, was incorrect. Correcting this dramatically
improved DC convergance. (I think this also effects BSIM1 and 2
but I haven't fixed them yet !)
The gm, gmb and gds calculations in the MOS3 model were all wrong.
The device equations were fixed, leading to much improved
convergance.
The Vcrit value used for diode voltage limiting was calculated
without taking into account the device area (and in some cases
without using the temperature corrected saturation current).
This could cause floating point overflows, especially in device
models designed to be scaled by a small area, e.g. 2u by 2u diodes
(area=4e-12). This is now fixed for Diode, BJT, MOS1, MOS2, and
MOS3 models.
The diode voltage limiting was modified to add negative voltage
limiting. Negative diode voltages are now limited to 3*Vdp-10,
where Vdp is the voltage from the previous iteration. If Vdp is
positive, then the voltage is limited to -10V. This prevents some
more floating point overflows. (Actually, I'm still playing with
the best values for this).
The Spice3 "fix" for the MOS3 gds discontinuity between the
linear and saturated regions only works if the VMAX parameter
is non-zero. A "tweak" has been added for the VMAX=0 case.
Transient Convergance Enhancements -
Temperature correction of various diode capacitances was implemented
slightly incorrectly, leading to capacitance discontinuities in
simulations at temperatures other than nominal. This affected the
Diode and MOS3 models.
A mistake in the implementation of the MOS3 source-bulk capacitance
model resulted in a charge storage discontinuity. This has been fixed.
The level 2 MOSFET model seems to calculate Von and Vth values for
the threshold and subthreshold values respectively, but then uses
Vbin to calculate the Vdsat voltage used to find the drain current.
However, a jump statement uses Von to decide that the device is in
the "cutoff" region, which means that when this jump allows the
drain current to be calculated, Vdsat can already be well above
zero. This leads to a discontinuity of drain current with respect
to gate voltage. The code is now modified to use Vbin for the jump
decision. It looks like the code should actually use Vth as the
threshold voltage, but since PSPICE and HSPICE both follow the
original Berkeley code, this was left alone.
New Model Parameters -
A PSPICE/HSPICE-like "M" device parameter (i.e. M devices in
parallel) was added to the MOS1,2,3 and BSIM3 mosfet models.
Input Read-in and Checking -
Numbers beginning with a + sign got the input routine confused.
Fixed now.
Attempts to nodeset (or .IC) non-existant nodes are flagged with a
warning.
PWL statements on Voltage or Current sources are now checked for
"non-increasing" time-points at the start of the simulation.
Previously each time-point was checked as it was reached during
the simulation, which could be very annoying if you made a mistake
which caused the simulation to fail after hours of run-time.
A check which was performed at the end of each sub-circuit expansion
was moved to the top level. This check makes sure that all sub-circuits
have been defined, but in its original position, it meant that if a
sub-circuit included ANY .MODEL statements at all, then ALL the models
called in that sub-circuit must also be defined within that
sub-circuit. Now SPICE behaves as expected, i.e. a subcircuit may
define its own models, but may also use models defined at any level
above.
Miscellaneous Fixes/Enhancements -
MOS devices reported only half of the Meyer capacitances, and did not
include overlap capacitances, when reporting to the .OP printout, or
when storing device capacitances to the "rawfile".
The ideal switch devices had no time-step control to stop their
controlling voltages/currents overshooting the switching thresholds.
The time-step control has been modified to use the last two time
points to estimate if the next one will move the controlling
voltage/current past a switching threshold. If this looks likely,
then the time-step is reduced.
The "rawfile" writing routines have been modified to print the
"reference value" to the console during the simulation. This lets
the user see exactly how far and how fast the simulation is
proceeding.
.OP printout tidied up a lot to make the printout clearer.
Analysis order changed to fix a "feature" where, if you ask for
a .OP and a .TRAN in the same simulation, the node voltages
printed out correspond to the .OP, but the device data was from
the last timepoint of the .TRAN
Etc. -
There are other minor bug fixes, and changes to reduce compiler
warnings. There are probably some more significant fixes which
I've forgotten :-)
Ng-spice-rework-12
============
Arno did a great work this summer!
The pole-zero analysis has been corrected. The error was introduced
in an attempt to eliminate compiler warnings. The source has been
reworked and info file have been updated. As you may see, a new dir
called "spicelib" has been created, another step toward the separation
of the simulator from the frontend.
Ng-spice-rework-11
============
Resistor code (device) has been modified to conform to spice3 device
coding standard.
A new step function (U2) has been introduced.
Documentation updated.
Ng-spice-rework-10
============
Added BSIM4 model and closed a couple of serious bugs. Added DEVICES file
to distribution. This file contains the status of device models in this
simulator. Read it, this file can save you a lot of time.
Added BSIM4 model and closed a couple of serious bugs. Added DEVICES
file to distribution. This file contains the status of device models
in this simulator. Read it, this file can save you a lot of time.
Ng-spice-rework-9
============
Thanks to Arno Peters now all device models are dynamically loaed on demand.
Thay are linked as shared libraries. The next step is the dlopen() one which
will make possible to link devices without any recompilation.
Thanks to Arno Peters now all device models are dynamically loaed on
demand. Thay are linked as shared libraries. The next step is the
dlopen() one which will make possible to link devices without any
recompilation.
@ -74,13 +270,13 @@ Ng-spice-rework-6 (29 Jan 2000)
This porting includes:
1) BSIM3V3.1 model as level 49. This is the version modified by Serban Popescu
which understands the M parameter and implements HDIF.
1) BSIM3V3.1 model as level 49. This is the version modified by Serban
Popescu which understands the M parameter and implements HDIF.
2) BSIM3V3.2 model al Level 50. This is the standard Berkeley version.
3) Now the resistor model can accepts two differents values for DC and AC
resistance.
3) Now the resistor model can accepts two differents values for DC and
AC resistance.
@ -94,11 +290,11 @@ Ng-spice-rework-4 (22/12/99)
This porting includes a new feature:
1) dynamically loading of some device code as an experimental feature for
the future GPL simulator. Thanks to Arno Peters and Manu Rouat.
1) dynamically loading of some device code as an experimental feature
for the future GPL simulator. Thanks to Arno Peters and Manu Rouat.
2) Patched the following bug (thanks to Andrew Tuckey for having supplied the
patch).
2) Patched the following bug (thanks to Andrew Tuckey for having
supplied the patch).
* Wsw (current controlled switch) in subckt, parsing bug.
* scale factor in arbitrary source.

69
NOTES Normal file
View File

@ -0,0 +1,69 @@
DEBUGGING SPICE
To avoid a segmentation fault in the initial run, use the following
command in gdb:
setenv SPICE_NO_DATASEG_CHECK "1"
Or, the comparable command in your shell before running gdb. This
disable accurate tracking of how much memory is used.
----------------------------------------------------------------------
USING A GARBAGE COLLECTOR
Get the Boehm-Weiser conservative garbage collector at the following
address:
http://www.hpl.hp.com/personal/Hans_Boehm/gc/
Compile it with 'make liblinuxgc.so' and install libgc.so and gc.h
where the compiler can find them (i.e., /usr/local/lib and
/usr/local/include). Run configure and compile.
----------------------------------------------------------------------
CREATING PATCHES
If you don't have access to anonymous CVS:
# extract the differences
$ diff -ruN ng-spice-rework-x ng-spice > my.patch
where ng-spice-rework-x is the snapshot you used to base your changes
on.
If you do have access to anonymous CVS:
$ cvs diff -u > my.patch
Note: this only works if you haven't added any files. Otherwise, the
first method is better.
Now, send your patch to ng-spice mailing list.
----------------------------------------------------------------------
INCORPORATING PATCHES
# apply the patch
$ patch -p1 < my.patch
# update the automatically generated files
$ sh autogen.sh
----------------------------------------------------------------------
INCOMPATIBILITIES BETWEEN SPICE3 AND SPICE2
The output format of spice3 is slightly different for .print and .plot
lines. Most notably, different traces on plots are not scaled
independently. This is most noticeable on phase/magnitude plots from
an AC analysis (also, phase is displayed in radians). Finally,
frequency for ".PRINT AC" lines is displayed as a complex quantity
with an all-zero imaginary component.
For input, "POLY( )" sources are not supported (the non-linear
dependent source provides a more general replacement). Also, the
".ALTER" line is not supported. The Spice3 parser may be slightly
different on subtle points of reading input (lines need not start at
column 1 for instance).

69
README
View File

@ -1,32 +1,32 @@
README for NGSPICE
------------------
This long message describes what NG-SPICE may become in the (near ?)
This long message describes what NGSPICE may become in the (near ?)
future. I used a question mark because, as you will read, most of the
features of ng-spice are found on Hi-quality commercial products and
features of ngspice are found on Hi-quality commercial products and
(which is the true reason) I have no idea on how can be implemented.
** Why resurrecting Berkeley's Spice ?
Berkeley's spice can be considered the father of most circuit simulator
Berkeley's spice can be considered the father of most circuit simulators
available today. It is an old but still good piece of software. It may not
be the fastest or the most reliable, but it's free, it is available in
source code, and most of the electrical simulators inherited it's syntax.
On the more technical side, spice3f4(5) uses good numerical algorithms
(commercial implementations have only strengthened them), implements most
of the models for MOSFET submicron designs and has a powerful set of
analyses. On the more "social" side: it's weel introduced in the
analyses. On the more "social" side: it's well introduced in the
academic environment.
** What does NG-SPICE mean ?
** What does NGSPICE mean ?
It stands for Next Generation Spice but that's not the official name of
the projest. This projects still lacks a name. NG-SPICE is a temporary
the projest. This projects still lacks a name. NGSPICE is a temporary
name.
** What will NG-SPICE be ?
** What will NGSPICE be ?
Berkeley's Spice lacks in three directions:
@ -51,53 +51,56 @@ Berkeley's Spice lacks in three directions:
program and it's features. The documentation should be useful for the
student as well as for the circuit professional.
* Improvements to the spice code: This is the hard part. Th target of
this direction is to make ng-spice a commercial grade simulator. This
* Improvements to the spice code: This is the hard part. The target of
this direction is to make ngspice a commercial grade simulator. This
means improving it's speed, it's numerical robustness, include the
latest models available and some other important features. I will
describe some of them briefly:
- Analyses -
Network analisys: given four nodes, extract z,y,s and the other
double bipole paramters.
Network analysis: given four nodes, extract z,y,s and the other
double bipole parameters.
Monte Carlo analisys: statistical simulation based on device
tolerances.
Monte Carlo analysis: statistical simulation based on device
parameters tolerances.
Worst Case analisys: find the worst case of operation of a given
circuit based on device tolerances.
Worst Case analysis: find the worst case of operation of a given
circuit based on device parameters tolerances.
Parametric analisys: repeat an analysis when one or more parameters
Parametric analysis: repeat an analysis when one or more parameters
assumes different values.
- Devices -
Behavioral device: enhance the B device of spice3 to accepts IF THEN
ELSE conditions, and digital keywords like DELAY, HIGHV. LOWV, etc to
simulate simple digital device.
simulate simple digital circuits.
Dynamically loading of device: reduce the memory occupied by the
simulator by using shared object code for devices. Each device
simulator using shared object code for devices. Each device
is a .so library that is inserted only if the circuit contains
an element modeled by the device. If we are simulating CMOS,
we do not need BJT or SOI (in most of the situations).
Code Level Modeling: Let users write their devices in C and use
them in the simulator. I have discovered a couple of standars
for doing this at the Sematech ftp site.
for doing this at the Sematech ftp site.
Improving device: Include additional parameters to some devices:
HDIF, LDIF, etc. (Serban, can you explain better).
HDIF, LDIF, etc.
- Numerical Algs -
Integration: include (if necessary) more stable algorithms for
integration. Runge-Kutta Methods ?
integration. What about Runge-Kutta Methods ?
How if we check LKC at every node as convergence test ?
Linearization:
Are there better algorithms for nonlinear equations the the Newton
raphson ?
- Sparse Matrix -
Faster handling of sparse matrices.
Faster handling of sparse matrices: new processors offers generous
caches and vectors operations.
- Options -
@ -136,25 +139,27 @@ MAILING LISTS:
There are three mailing lists dedicated to the development of ngspice.
ng-spice@ieee.ing.uniroma1.it: This list is the list for the users of the
ng-spice simulator.
ngspice-users@lists.sourceforge.net: This list is the list for the users of the
ngspice simulator.
ng-spice-devel@ieee.ing.uniroma1.it: ng-spice development issues.
ngspice-devel@lists.sourceforge.net: ngspice development issues. Developers and
"want to be" developers should
subscribe here.
ng-spice-frontends@ieee.ing.uniroma1.it: issues related to development of
frontends for ng-spice.
ngspice-frontend@list.sourceforge.net: issues related to development of
frontends for ngspice.
To subscribe the list(s), send a message to:
<ng-spice-subscribe@ieee.ing.uniroma1.it>
<ng-spice-devel-subscribe@ieee.ing.uniroma1.it>
<ng-spice-frontends-subscribe@ieee.ing.uniroma1.it>
<ngspice-users-subscribe@lists.sourceforge.net>
<ngspice-devel-subscribe@lists.sourceforge.net>
<ngspice-frontend-subscribe@lists.sourceforge.net>
WEB SITE:
--------
This project is hosted on the IEEE Central & South Italy Section Server.
The home page is http://ieee.ing.uniroma1.it/ngspice
This project is hosted on Sourceforge.
The home page is http://ngspice.sourceforge.net
Manu (emmanuel.rouat@wanadoo.fr)
Paolo (p.nenzi@ieee.org)

View File

@ -8,6 +8,9 @@
/* Define the build date */
#define NGSPICEBUILDDATE none
/* Define if we want garbage collection enabled */
#undef HAVE_LIBGC
/* Define if we have termcap */
#undef HAVE_TERMCAP
@ -22,3 +25,24 @@
/* Define if we want some experimental code */
#undef EXPERIMENTAL_CODE
/* Define if we want noise integration code */
#undef INT_NOISE
/* Undefine HAVE_EKV since it is not included in the standard distribution */
#undef HAVE_EKV
/* Define if we have GNU readline */
#undef HAVE_GNUREADLINE
/* We do not want spurios debug info into non-developer code */
#undef FTEDEBUG
/*The xspice enhancements*/
#undef XSPICE
/*Tcl Spice module*/
#undef TCL_MODULE
/* Spice cluster support */
#undef CLUSTER

View File

@ -2,8 +2,8 @@
# Run this to generate all the initial makefiles, etc.
PROJECT=ng-spice
TEST_TYPE=-d
FILE=src/circuit
TEST_TYPE=-f
FILE=DEVICES
DIE=0
@ -40,34 +40,10 @@ test $TEST_TYPE $FILE || {
exit 1
}
if test -z "$*"; then
echo "I am going to run ./configure with no arguments - if you wish "
echo "to pass any to it, please specify them on the $0 command line."
fi
case $CC in
*lcc | *lcc\ *) am_opt=--include-deps;;
esac
#echo "Running gettextize... Ignore non-fatal messages."
# Hmm, we specify --force here, since otherwise things don't
# get added reliably, but we don't want to overwrite intl
# while making dist.
#echo "no" | gettextize --copy --force
echo "Running libtoolize"
libtoolize --copy --force
aclocal $ACLOCAL_FLAGS
# optionally feature autoheader
(autoheader --version) < /dev/null > /dev/null 2>&1 && autoheader
automake -c -a $am_opt
autoconf
./configure "$@"
echo
echo "Now type 'make' to compile $PROJECT."

View File

@ -1,8 +1,16 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(src/main.c)
dnl Create a configuration header
AM_CONFIG_HEADER(config.h)
dnl Initialize automake stuff
AM_INIT_AUTOMAKE(ng-spice-rework,14)
dnl --enable-ftedebug : enable frontend debug macros
AC_ARG_ENABLE(ftedebug,
[ --enable-ftedebug Enable ngspice frontend debug])
dnl --enable-ansi : try to force --ansi option to the compiler
AC_ARG_ENABLE(ansi,
[ --enable-ansi Force --ansi option for compilation])
@ -27,13 +35,33 @@ dnl --enable-sense2 : define HAVE_SENSE2 for the code
AC_ARG_ENABLE(sense2,
[ --enable-sense2 Use spice2 sensitivity analysis])
dnl --enable-intnoise : define INT_NOISE for the code
AC_ARG_ENABLE(intnoise,
[ --enable-intnoise Enables noise integration in noise analysis])
dnl --enable-smoketest : a smoketest
AC_ARG_ENABLE(smoketest,
[ --enable-smoketest Enables smoketest compile])
dnl --enable-experimental : define EXPERIMENTAL_CODE for the code
AC_ARG_ENABLE(experimental,
[ --enable-experimental Enables some experimental code])
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 Initialize automake stuff
AM_INIT_AUTOMAKE(ng-spice-rework,10)
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-tcl: define TCL_MODULE in the code. This is for tcl support
AC_ARG_ENABLE(tcl,
[ --enable-tcl Compiles the tcl module instead, experimental, see README in src/tcl/README])
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
@ -52,6 +80,7 @@ if test "$enable_debug" = "no"; then
CFLAGS=" "
fi
dnl Not sure that this will work....
if test "$with_checkergcc" = "yes"; then
CC="checkergcc"
@ -68,24 +97,20 @@ if test "$enable_ansi" = "yes"; then
fi
fi
if test "$enable_smoketest" = "yes"; then
dnl CFLAGS="$CFLAGS -Werror"
CFLAGS="$CFLAGS -pedantic -W -Wmissing-prototypes"
CFLAGS="$CFLAGS -Wstrict-prototypes -Wtraditional"
CFLAGS="$CFLAGS -Wconversion -Wshadow -Wpointer-arith"
CFLAGS="$CFLAGS -Wcast-qual -Wcast-align -Wwrite-strings"
CFLAGS="$CFLAGS -Waggregate-return -fshort-enums -fno-common"
CFLAGS="$CFLAGS -Wnested-externs -Dinline= -g -O4"
fi
dnl Chech system we're on , and tune accordingly
AC_CANONICAL_HOST
case "$host" in
*bsd* ) CFLAGS="$CFLAGS";;
*linux*) CFLAGS="$CFLAGS";;
*rs6000* ) CFLAGS="$CFLAGS";;
*sgi* ) CFLAGS="$CFLAGS";;
*sun* ) CFLAGS="$CFLAGS";;
*ultrix* ) CFLAGS="$CFLAGS";;
esac
dnl Checks for programs
@ -93,6 +118,99 @@ AC_LIBTOOL_DLOPEN
AM_PROG_LIBTOOL
dnl
dnl The tclSpice options
dnl
if test "$enable_tcl" = "yes"; then
AC_DEFINE(TCL_MODULE)
with_x=no
AC_MSG_CHECKING([for tclConfig.sh])
tcl_config_sh=""
if test "x$blt_with_tcl" != "x" ; then
for dir in \
$blt_with_tcl
do
if test -r "$dir/tclConfig.sh" ; then
tcl_config_sh="$dir/tclConfig.sh"
break
elif test -r "$dir/lib/tclConfig.sh" ; then
tcl_config_sh="$dir/lib/tclConfig.sh"
break
elif test -r "$dir/unix/tclConfig.sh" ; then
tcl_config_sh="$dir/unix/tclConfig.sh"
break
fi
done
else
for dir in \
$prefix \
$exec_prefix
do
if test -r "$dir/tclConfig.sh" ; then
tcl_config_sh="$dir/tclConfig.sh"
break
elif test -r "$dir/lib/tclConfig.sh" ; then
tcl_config_sh="$dir/lib/tclConfig.sh"
break
elif test -r "$dir/unix/tclConfig.sh" ; then
tcl_config_sh="$dir/unix/tclConfig.sh"
break
fi
done
if test "x$tcl_config_sh" = "x" ; then
for dir in \
`ls -dr /usr/local/tcl/tcl[[7-9]].[[0-9]]* 2>/dev/null` \
/usr/local/tcl \
/usr/local \
/usr
do
if test -r "$dir/tclConfig.sh" ; then
tcl_config_sh="$dir/tclConfig.sh"
break
elif test -r "$dir/lib/tclConfig.sh" ; then
tcl_config_sh="$dir/lib/tclConfig.sh"
break
fi
done
fi
fi
AC_MSG_RESULT([${tcl_config_sh}])
if test "x$tcl_config_sh" = "x" ; then
echo "can't find Tcl configuration script \"tclConfig.sh\""
exit 1
fi
. $tcl_config_sh
AC_MSG_CHECKING(for TCL module BLT)
rm -f conftest.tcl
cat > conftest.tcl << EOF
package require BLT;
exit;
EOF
if (wish conftest.tcl; exit) 2>/dev/null; then
AC_MSG_RESULT(Found)
else
AC_MSG_ERROR(Couldn't find BLT)
fi
rm -f conftest.tcl
else
TCL_PACKAGE_PATH=""
TCL_BUILD_LIB_SPEC=""
fi
AC_SUBST(TCL_PACKAGE_PATH)
AC_SUBST(TCL_BUILD_LIB_SPEC)
dnl Checks for X11 header files and libraries - X11 support can be disabled
dnl by passing the '--without-x' option to configure:
@ -109,8 +227,9 @@ dnl libraries are present (error if they are not)
if test ! "$no_x" = "yes" ; then
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(Xaw,main,X_LIBS="$X_LIBS -lXaw",AC_MSG_ERROR(Couldn't find Xaw 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(Xaw,main,X_LIBS="$X_LIBS -lXaw",AC_MSG_ERROR(Couldn't find Xaw librairies),$X_LIBS $X_EXTRA_LIBS)
fi
@ -126,7 +245,7 @@ AC_SEARCH_LIBS(tputs,ncurses termcap,AC_DEFINE(HAVE_TERMCAP),
AC_HEADER_DIRENT
AC_CHECK_HEADERS(ctype.h unistd.h pwd.h fcntl.h)
AC_CHECK_HEADERS(ctype.h unistd.h pwd.h fcntl.h string.h)
AC_HEADER_SYS_WAIT
AC_HEADER_STAT
@ -158,6 +277,13 @@ AC_CHECK_HEADERS(float.h limits.h values.h)
dnl Check for a few mathematical functions:
AC_CHECK_FUNCS(erfc logb scalb scalbn asinh acosh atanh)
AC_MSG_RESULT(Checking for the presence of the Garbage Collector:)
dnl Check for the garbage collector:
AC_CHECK_LIB(gc,GC_malloc,AC_DEFINE(HAVE_LIBGC) LIBS="$LIBS -lgc")
dnl Check for the asprintf function:
AC_CHECK_FUNCS(asprintf)
# Expand the prefix variable (this is really annoying!)
if eval "test x$prefix = xNONE"; then
@ -167,7 +293,7 @@ else
fi
AC_DEFINE_UNQUOTED(NGSPICEBINDIR, "`echo $dprefix/bin`" )
AC_DEFINE_UNQUOTED(NGSPICEDATADIR, "`echo $dprefix/share/ng-spice`" )
AC_DEFINE_UNQUOTED(NGSPICEDATADIR, "`echo $dprefix/share/ng-spice-rework`" )
AC_DEFINE_UNQUOTED(NGSPICEBUILDDATE, "`date`" )
@ -185,11 +311,75 @@ if test "$enable_predictor" = "yes"; then
AC_DEFINE(PREDICTOR)
AC_MSG_RESULT(PREDICTOR algorithm enabled)
fi
if test "$enable_intnoise" = "yes"; then
AC_DEFINE(INT_NOISE)
AC_MSG_RESULT(Noise integration enabled)
fi
if test "$enable_experimental" = "yes"; then
AC_DEFINE(EXPERIMENTAL_CODE)
AC_MSG_RESULT(EXPERIMENTAL_CODE enabled)
fi
if test "$enable_ftedebug" = "yes"; then
AC_DEFINE(FTEDEBUG)
AC_MSG_RESULT(WARNING: Frontend debug is enabled)
fi
if test "$enable_ekv" = "yes"; then
AC_MSG_RESULT(Model EKV included)
AC_DEFINE(HAVE_EKV)
EKVDIR="ekv"
EKVLIB="spicelib/devices/ekv/libekv.la"
else
EKVDIR=""
EKVLIB=""
fi
AC_SUBST(EKVDIR)
AC_SUBST(EKVLIB)
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 Printout Tcl option
if test "$enable_tcl" = "yes"; then
AC_MSG_RESULT(Tcl module being made, use "make tcl" and "make tcl_install", read README in src/tcl/README)
fi
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,
[ --with-readline Use the readline package: SEE README],
AC_MSG_RESULT(Checking for readline library:)
dnl Check for the readline library:
AC_CHECK_LIB(readline,readline, AC_DEFINE(HAVE_GNUREADLINE) LIBS="$LIBS -lreadline")
)
AC_OUTPUT( \
Makefile \
@ -197,49 +387,78 @@ doc/Makefile \
man/Makefile \
man/man1/Makefile \
src/Makefile \
src/analysis/Makefile \
src/circuit/Makefile \
src/devices/Makefile \
src/devices/asrc/Makefile \
src/devices/bjt/Makefile \
src/devices/bsim1/Makefile \
src/devices/bsim2/Makefile \
src/devices/bsim3v1/Makefile \
src/devices/bsim3/Makefile \
src/devices/bsim4/Makefile \
src/devices/bsim3v2/Makefile \
src/devices/cap/Makefile \
src/devices/cccs/Makefile \
src/devices/ccvs/Makefile \
src/devices/csw/Makefile \
src/devices/devsup/Makefile \
src/devices/dio/Makefile \
src/devices/disto/Makefile \
src/devices/ind/Makefile \
src/devices/isrc/Makefile \
src/devices/jfet/Makefile \
src/devices/jfet2/Makefile \
src/devices/ltra/Makefile \
src/devices/mes/Makefile \
src/devices/mos1/Makefile \
src/devices/mos2/Makefile \
src/devices/mos3/Makefile \
src/devices/mos6/Makefile \
src/devices/res/Makefile \
src/devices/sw/Makefile \
src/devices/tra/Makefile \
src/devices/urc/Makefile \
src/devices/vccs/Makefile \
src/devices/vcvs/Makefile \
src/devices/vsrc/Makefile \
src/spicelib/Makefile \
src/spicelib/analysis/Makefile \
src/spicelib/devices/Makefile \
src/spicelib/devices/asrc/Makefile \
src/spicelib/devices/bjt/Makefile \
src/spicelib/devices/bjt2/Makefile \
src/spicelib/devices/bsim1/Makefile \
src/spicelib/devices/bsim2/Makefile \
src/spicelib/devices/bsim3v1/Makefile \
src/spicelib/devices/bsim3/Makefile \
src/spicelib/devices/bsim4/Makefile \
src/spicelib/devices/bsim3v2/Makefile \
src/spicelib/devices/bsim3soi_pd/Makefile \
src/spicelib/devices/bsim3soi_fd/Makefile \
src/spicelib/devices/bsim3soi_dd/Makefile \
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 \
src/spicelib/devices/isrc/Makefile \
src/spicelib/devices/hfet1/Makefile \
src/spicelib/devices/hfet2/Makefile \
src/spicelib/devices/jfet/Makefile \
src/spicelib/devices/jfet2/Makefile \
src/spicelib/devices/ltra/Makefile \
src/spicelib/devices/mes/Makefile \
src/spicelib/devices/mesa/Makefile \
src/spicelib/devices/mos1/Makefile \
src/spicelib/devices/mos2/Makefile \
src/spicelib/devices/mos3/Makefile \
src/spicelib/devices/mos6/Makefile \
src/spicelib/devices/mos9/Makefile \
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 \
src/spicelib/devices/vsrc/Makefile \
src/spicelib/parser/Makefile \
src/frontend/Makefile \
src/hlp/Makefile \
src/frontend/help/Makefile \
src/frontend/parser/Makefile \
src/frontend/plotting/Makefile \
src/include/Makefile \
src/maths/Makefile \
src/maths/cmaths/Makefile \
src/maths/ni/Makefile \
src/maths/deriv/Makefile \
src/maths/poly/Makefile \
src/maths/sparse/Makefile \
src/misc/Makefile \
src/parser/Makefile \
src/xspice/Makefile \
src/xspice/cm/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 \
tests/resistance/Makefile \
tests/bsim3soipd/Makefile \
tests/bsim3soifd/Makefile \
tests/bsim3soidd/Makefile \
tests/bsim4/Makefile \
tests/mesa/Makefile
)

View File

@ -1,10 +1,16 @@
2000-03-22 Paolo Nenzi <p.nenzi@ieee.org>
2000-10-10 Arno W. Peters <A.W.Peters@ieee.org>
* mslib, spiceprm: Michael Widlok released new version of his
programs.
2000-03-22 Paolo Nenzi <p.nenzi@ieee.org>
* mslib: Major update. M. Widlok sent the new version of it's programs.
* mslib: Major update. M. Widlok sent the new version of it's
programs.
* spiceprm: Major update. See above line.
1999-09-14 Arno <A.W.Peters@ieee.org>
1999-09-14 Arno W. Peters <A.W.Peters@ieee.org>
* mslib: Added.

View File

@ -92,10 +92,11 @@ readlib(struct LSData *lib, FILE * tlib, \
{
char name[BSIZE];
int numi, wflag;
int numi, wflag, nextsub;
numi = 0;
wflag = NOWRITE;
nextsub = 0;
while (fgets(buf, bsizer, lib->filedes))
{
@ -128,7 +129,16 @@ readlib(struct LSData *lib, FILE * tlib, \
case (SUBLLINE):
if (sub)
{
if (checkname(sub, name))
if (wflag==WRITESUB)
{
/* subckt inside subckt
not so funny */
nextsub++;
fputs(buf, tlib);
break;
}
if (checkname(sub, name))
{
wflag = WRITESUB;
numi++;
@ -150,12 +160,20 @@ readlib(struct LSData *lib, FILE * tlib, \
break;
case (ENDSLLINE):
if (wflag == WRITESUB)
if (nextsub)
{
nextsub--;
fputs(buf, tlib);
break;
} else {
if (wflag == WRITESUB)
{
fprintf(tlib, "%s\n* End Subckt\n\n", buf);
}
wflag = NOWRITE;
break;
}
case (CONTLLINE):
if (wflag != NOWRITE)

77
contrib/mslib/liblook Executable file
View File

@ -0,0 +1,77 @@
#!/bin/sh
#set -x -v
# MW. Lib search / show program
# usage liblook libname [text_to_find] [l_before] [l_after]
LIBPATH=/usr/local/lib
function trapper()
{
echo User break!
echo Exiting . . .
unset LIBPATH
exit 1
}
trap trapper SIGINT SIGQUIT
function operror()
{
echo Incorrect parameters: $*, $#
echo Usage: liblook libname [text_to_find] [l_before] [l_after]
unset LIBPATH
exit 2
}
function showlib()
{
if test -f $LIBPATH/$1; then
less $LIBPATH/$1; exit 0; fi
if test -f [C./$1; then
less ./$1; exit 0; fi
echo Searching $1 in ~/ . . .
less $(find ~/ -name $1)
}
function searchlib()
{
if test -f $LIBPATH/$1; then
echo File: $1; echo;
grep -B"$3" -A"$4" --ignore-case -e "$2" $LIBPATH/$1;
echo; exit 0; fi
if test -f ./$1; then
echo File: $1; echo;
grep -B"$3" -A"$4" --ignore-case -e "$2" ./$1;
echo; exit 0; fi
#if *.lib or sth like this
echo Searching $1 in ~/ . . .;echo;
if (grep -B"$3" -A"$4" --ignore-case -e "$2" $(find ~/ -name $1)); then
echo; exit 0; fi
echo Searching $1 in $LIBPATH;echo;
if (grep -B"$3" -A"$4" --ignore-case -e "$2" $(find $LIBPATH -name $1)); then
echo; exit 0; fi
}
# Main body
if test $# -lt 1 -o $# -gt 4; then operror $*; fi
case $# in
1) showlib $*;;
2) searchlib $1 $2 2 2;;
3) searchlib $1 $2 $3 2;;
4) searchlib $1 $2 $3 $4;;
esac
unset LIBPATH
exit 0

70
contrib/mslib/libprm Executable file
View File

@ -0,0 +1,70 @@
#!/bin/sh
#set -x -v
# MW. Lip / Param parsing program for spice
# -n normal, -f full (keep everything), -r replace original file
# -e new addition start with editor, then like normal
export TMPLP=/tmp/LibPrm.$$-
function trapper()
{
echo User break!
echo Exiting . . .
rm -f -v ${TMPLP}*
unset TMPLP
exit 1
}
trap trapper SIGINT SIGQUIT
function operror()
{
echo Incorrect parameters: $*, $#
unset TMPLP
exit 2
}
function repnormpl()
{
mslib $1 ${TMPLP}1
sed -n -e 'p' -e "1r ${TMPLP}1" $1 >${TMPLP}2
spiceprm ${TMPLP}2 $2
}
function keepall()
{
mslib $1
sed -n -e 'p' -e "1r $1.lib" $1 >${TMPLP}2
spiceprm ${TMPLP}2 $2
}
function withedit()
{
joe $1
mslib $1 ${TMPLP}1
sed -n -e 'p' -e "1r ${TMPLP}1" $1 >${TMPLP}2
spiceprm ${TMPLP}2 $2
}
# Main body
if test $# -lt 2 -o $# -gt 3; then operror $*; fi
if !(test -f $2); then operror $*; fi
case $1$# in
-r3) operror $*;;
-n2) repnormpl $2 ${2%.cir}.ckt;;
-n3) repnormpl $2 $3;;
-r2) repnormpl $2 $2;;
-f2) keepall $2 ${2%.cir}.ckt;;
-f3) keepall $2 $3;;
-e2) withedit $2 ${2%.cir}.ckt;;
-e3) withedit $2 $3;;
esac
rm -f ${TMPLP}*
unset TMPLP
exit 0

View File

@ -0,0 +1,14 @@
So, this is my idea of using parametrized subckts with spice3f4.
First I create an input file like foo.cir and I include commands for
mslib (*MOD, *SUB, *LIB) in it. Then I run "libprm -n foo.cir". Libprm then
runs mslib first to get all models and subckts form given libraries and then
runs spiceprm to evaluate all used parameters.
This works quite right for me, and I hope that You will find my idea
useful. Spiceprm is not my program (I get it from Internet), but I think
that it will better to enclose all used programs in this packet. Spiceprm
has it's own directory with very good readme and examples. If You want to
find out more about libprm or mslib look for the source code. These are rather
short and easy programs - they are all that I could write in quite short
time.

View File

@ -7,6 +7,9 @@ HDRS= datadef.h
SRCC= inc_main.c inc_inp.c inc_LSD.c
mslib: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
$(OBJS): $(HDRS)
clean:
$(RM) $(OBJS) mslib
$(OBJS): $(HDRS)

View File

@ -1,3 +1,10 @@
-------------------------------
MW. 01-10-2000
Bugs Fixes -
-----------
.subckt inside another parametrized .subckt works right now.
----------------------------------------------------------------------
Version 0.11 January 2, 1996
----------------------------------------------------------------------

View File

@ -163,8 +163,9 @@ sub prm_scan {
}
$hasprm = 0;
undef @list; $sublist = '';
last PRM_TST;
}
last PRM_TST;
# MW. 'last PRM_TST' should be inside 'if' loop to allow nestle subckts.
}
if ($depth) {
push(@list, $_);
@ -248,7 +249,7 @@ sub prm_wr {
last PRMWR_SCAN;
}
if (/^\.ends/) {
if (--$depth == 0) { $sublist = ''; }
if (--$depth == 0) { $sublist = ''; }
else { $sublist =~ s/(\#\w+)$//; }
}
prm_wrline($_);

View File

@ -1,3 +1,15 @@
2001-12-05 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* ngspice.texi: changed (most) references of spice3 to ngspice.
2001-12-04 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* ngspice.texi: corrected a few bugs, and made some chapters readable.
2000-05-22 Paolo Nenzi <p.nenzi@ieee.org>
* ngspice.texi: Added text for u2 function and for resistance ac
paramter.
1999-09-06 Arno Peters <A.W.Peters@ieee.org>
* ngspice.texi: Added TeX equivalents for some formula.

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in
man_MANS = spice.1 nutmeg.1 sconvert.1
man_MANS = ngspice.1 ngnutmeg.1 ngsconvert.1
EXTRA_DIST = $(man_MANS)

1057
man/man1/ngnutmeg.1 Normal file

File diff suppressed because it is too large Load Diff

127
man/man1/ngsconvert.1 Normal file
View File

@ -0,0 +1,127 @@
.\" RCS Info: $Revision$ on $Date$
.\" $Source$
.\" Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
.TH SCONVERT 1 "20 March 1986"
.UC 4
.SH NAME
sconvert \- convert spice formats
.SH SYNOPSIS
.B sconvert fromtype fromfile totype tofile
.br
.B sconvert fromtype totype
.br
.B sconvert
.br
.SH DESCRIPTION
.B Sconvert
translates spice output files among three formats: the old
binary format, a new binary format, and a new ascii format.
The formats are specified by the
.B fromtype
and
.B totype
arguments: `o' for the old format, `b' for the new binary format,
and `a' for the new ascii format.
.B Fromtype
specifies the format to be read, and
.B totype
specifies the format to be written.
If
.B fromfile
and
.B tofile
are given, then they are used as the input and output, otherwise
standard input and output are used. (Note that this second option is
only available on \s-2UNIX\s+2 systems \- on VMS and other systems you must
supply the filenames.)
If no arguments are given, the parameters are prompted for.
.PP
Binary format is the preferred format for general use, as it is
the most economical in terms of space and speed of access, and ascii is
provided to make it easy to modify data files and transfer them
between machines with different floating-point formats.
The old format is provided only
for backward compatibility. The three formats are as follows:
.br
.nf
.B Old:
What Size in Bytes
title 80
date 8
time 8
numoutputs 2
the integer 4 2
variable names --
char[numoutputs][8] numoutputs * 8
types of output numoutputs * 2
node index numoutputs * 2
plot title numoutputs * 24
the actual data numpoints * numoutputs * 8
.B Ascii:
Title: \fITitle Card String\fR
Date: \fIDate\fR
[ Plotname: \fIPlot Name\fR
Flags: \fIcomplex\fR or \fIreal\fR
No. Variables: \fInumoutputs\fR
No. Points: \fInumpoints\fR
Command: \fInutmeg command\fR
Variables: 0 \fIvarname1\fR \fItypename1\fR
1 \fIvarname2\fR \fItypename2\fR
etc...
Values:
0 n n n n ...
1 n n n n ...
And so forth...
] repeated one or more times
.PP
If one of the flags is \fIcomplex\fR, the points look like r,i where r and i
are floating point (in %e format). Otherwise they are in %e format.
Only one of \fIreal\fR and \fIcomplex\fR should appear.
.PP
The lines are guaranteed to be less than 80 columns wide (unless the
plot title or variable names are very long), so this format is safe
to mail between systems like CMS.
.PP
Any number of \fBCommand:\fR lines may appear between the \fBNo. Points:\fR
and the \fBVariables:\fR lines, and whenever the plot is loaded into
\fBnutmeg\fR they will be executed.
.nf
.B Binary:
\fITitle Card\fR (a NULL terminated string)
\fIDate, Time\fR (a NULL terminated string)
[
\fIPlot title\fR (a NULL terminated string)
\fINumber of variables\fR (an int)
\fINumber of data points\fR (an int)
\fIflags\fR (a short)
\fIvariable header struct\fR (repeated numoutputs times)
\fIvariable name\fR (a NULL terminated string)
\fIvariable type\fR (an int)
\fIset of outputs\fR (repeated numpoints times)
] repeated one or more times.
.PP
A set of outputs is a vector of doubles of length numoutputs, or
a vector of real-imaginary pairs of doubles if the data is complex.
.SH "SEE ALSO"
nutmeg(1), spice(1), writedata(3)
.SH AUTHOR
Wayne Christopher (faustus@cad.berkeley.edu)
.SH BUGS
If variable names and the title
and plotname strings have trailing
blanks in them they will be stripped off when the file is read, if
it is in ascii format.
.PP
If a plot title begins with "Title:" \fBnutmeg\fR will be fooled into thinking
that this is an ascii format file. \fBSconvert\fR always requires the
type to be specified, however.

337
man/man1/ngspice.1 Normal file
View File

@ -0,0 +1,337 @@
.\" RCS Info: $Revision$ on $Date$
.\" $Source$
.\" Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
.TH SPICE 1 "20 March 1986"
.ds S \s-2SPICE\s+2\&3
.UC 4
.SH NAME
spice \- circuit simulator
.SH SYNOPSIS
\fBspice [ -n ] [ -t term ] [ -r rawfile] [ -b ]
[ -i ] [ input file ... ]\fR
.SH DESCRIPTION
This manual page describes the commands available for interactive
use of \*S. For details of circuit descriptions and the
process of simulating a circuit, see the \*S User's Manual.
The commands available are a superset of those available for
\fBnutmeg\fR \- only the additional commands available in \*S
are described here. You should be familiar with the manual page for
\fBnutmeg(1)\fR before reading this manual page.
.PP
Arguments are:
.TP
\fB-n\fR (or \fB--no-spiceinit\fR)
Don't try to source the file ".spiceinit" upon startup. Normally \*S
tries to find the file in the current directory, and if it is not found then
in the user's home directory.
.TP
\fB-q\fR (or \fB--completion\fR)
Enable command completion.
.TP
\fB-t term\fR (or \fB--term=term\fR)
The program is being run on a terminal with \fImfb\fR name \fBterm\fR.
.TP
\fB-b\fR (or \fB--batch\fR)
Run in batch mode. \*S will read the standard input or the specified
input file and do the simulation. Note that if the standard input
is not a terminal, \*S will default to batch mode, unless the
-i flag is given.
.TP
\fB-s\fR (or \fB--server\fR)
Run in server mode. This is like batch mode, except that a temporary
rawfile is used and then written to the standard output, preceded by
a line with a single "@", after the simulation is done. This mode
is used by the spice daemon.
.TP
\fB-i\fR (or \fB--interactive\fR)
Run in interactive mode. This is useful if the standard input is
not a terminal but interactive mode is desired. Command completion is
not available unless the standard input is a terminal, however.
.TP
\fB-r rawfile\fR (or \fB--rawfile=file\fR)
Use \fBrawfile\fR as the default file into which the results of
the simulation are saved.
.TP
\fB-c circuitfile\fR (or \fB--circuitfile=circuitfile\fR)
Use \fBcircuitfile\fR as the default input deck.
.TP
\fB-h\fR (or \fB--help\fR)
Display a verbose help on the arguments available to the program.
.TP
\fB-v\fR (or \fB--version\fR)
Display a version number and copyright information of the program.
.PP
Further arguments are taken to be \*S input decks, which are read
and saved. (If batch mode is requested then they are run immediately.)
.PP
\*S will accept any \s-2SPICE\s+2\&2 input decks, and output
ascii plots, fourier analyses, and node printouts as specified
in .plot, .four, and .print cards. If a \fBout\fR parameter
is given on a .width card, the effect is the same as \fBset width = ...\fR.
Since \*S ascii plots do not use multiple ranges, however, if vectors
together on a .plot card have different ranges they will not provide
as much information as they would in \s-2SPICE\s+2\&2. The output
of \*S is also much less verbose than \s-2SPICE\s+2\&2, in that the only
data printed is that requested by the above cards.
.PP
Vector names are the same as in \fBnutmeg\fR, with this addition:
a name such as \fB@name[param]\fR, where \fBname\fR is either
the name of a device instance or model, denotes the value of the
\fBparam\fR parameter of the device or model. See the \*S User's
Manual for details of what parameters are available. The value is a
vector of length 1. This function is also available with the
\fBshow\fR command, and is available with variables for convenience for
command scripts.
.PP
\*S
commands are as follows (these are only those commands not also
available in \fBnutmeg\fR \- consult the \fBnutmeg\fR manual page for
more commands):
.TP
\fBsetcirc [circuit name]\fR
Change the current circuit. The current circuit is the one that is
used for the simulation commands below. When a circuit is loaded
with the \fIsource\fR command (see below) it becomes the
current circuit.
.TP
\fBop [.op card args]\fR
Do an operating point analysis.
.TP
\fBtran [.tran card args]\fR
Do a transient analysis.
.TP
\fBac [.ac card args]\fR
Do an ac analysis.
.TP
\fBdc [.dc card args]\fR
Do a dc transfer curve analysis.
.TP
\fBlisting [logical] [physical] [deck] [expand]\fR
Print a listing of the current circuit. If the \fBlogical\fR argument
is given, the listing is with all continuation lines collapsed
into one line, and if the \fBphysical\fR
argument is given the lines are printed out as they were found in
the file. The default is \fBlogical\fR. A \fBdeck\fR listing is just like
the \fBphysical\fR listing, except without the line numbers it recreates
the input file verbatim (except that it does not preserve case).
If the word \fBexpand\fR is present, the circuit will be printed with all
subcircuits expanded.
.TP
\fBedit [file]\fR
Print the current \*S deck into a file, call up the editor on that file
and allow the user to modify it, and then read it back in, replacing
the origonal deck. If a \fBfilename\fR is given, then edit that file
and load it, making the circuit the current one.
.TP
\fBresume\fR
Resume a simulation after a stop.
.TP
\fBshow \fR
Show a device parameter.
.TP
\fBalter \fR
Alter a device parameter.
.TP
\fBstate\fR
Print the state of the circuit. (This command is largely unimplemented.)
.TP
\fBsave [all] [output ...]\fR or \fB.save [all] [output ...]\fR
Save a set of outputs, discarding the rest. If a node has been mentioned
in a \fBsave\fR command, it will appear in the working plot after
a run has completed, or in the rawfile if spice is run in batch
mode. If a node is traced or plotted (see below) it will
also be saved. For backward compatibility, if there are \fBno\fR save
commands given, all outputs are saved.
.TP
\fBstop [ after n] [ when something cond something ] ... \fR
Set a breakpoint. The argument \fBafter n\fR means stop after \fBn\fR
iteration number \fBn\fR, and the argument
\fBwhen something cond something\fR means
stop when the first \fBsomething\fR is in the given relation with
the second \fBsomething\fR, the possible relations being
\fBeq\fR or = (equal to),
\fBne\fR or <> (not equal to),
\fBgt\fR or > (greater than),
\fBlt\fR or < (less than),
\fBge\fR or >= (greater than or equal to), and
\fBle\fR or <= (less than or equal to).
IO redirection is disabled for the \fBstop\fR command, since the relational
operations conflict with it (it doesn't produce any output anyway).
The \fBsomething\fR\&s above may be node names in
the running circuit, or real values.
If more than one condition is given, e.g.
\fBstop after 4 when v(1) > 4 when v(2) < 2\fR, the conjunction of
the conditions is implied.
.TP
\fBtrace [ node ...]\fR
Trace nodes. Every iteration the value of the node is printed to the
standard output.
.TP
\fBiplot [ node ...]\fR
Incrementally plot the values of the nodes while \*S runs.
.TP
\fBstep [number]\fR
Iterate \fBnumber\fR times, or once, and then stop.
.TP
\fBstatus\fR
Display all of the traces and breakpoints currently in effect.
.TP
\fBdelete [debug number ...]\fR
Delete the specified breakpoints and traces. The \fBdebug numbers\fR
are those shown by the \fBstatus\fR command. (Unless you do
\fBstatus > file\fR, in which case the debug numbers aren't printed.)
.TP
\fBreset\fR
Throw out any intermediate data in the circuit (e.g, after a breakpoint
or after one or more analyses have been done already), and re-parse
the deck. The circuit can then be re-run. (\fBNote\fR: this command
used to be \fBend\fR in \s-2SPICE\s+2 3a5 and earlier versions -- \fBend\fR
is now used for control structures.) The \fBrun\fR command will take
care of this automatically, so this command should not be necessary...
.TP
\fBrun [rawfile]\fR
Run the simulation as specified in the input file. If there were any
of the control cards .ac, .op, .tran, or .dc, they are executed. The output
is put in \fBrawfile\fR if it was given, in addition to being available
interactively.
.TP
\fBsource file\fR
Read the \*S input file \fBfile\fR. \fBNutmeg\fR and \*S commands may be
included in the file, and must be enclosed between the lines
\fI.control\fR and \fI.endc\fR. These commands
are executed immediately after the circuit is loaded, so a control line
of \fIac ...\fR will work the same as the corresponding \fI.ac\fR card.
The first line in any input file is considered a title
line and not parsed but kept as the name of the circuit. The
exception to this rule is the file \fI.spiceinit\fR.
Thus, a \*S command script must begin with a blank line and then with
a \fI.control\fR line.
Also, any line beginning with the characters *# is considered a control
line. This makes it possible to imbed commands in \*S input files
that will be ignored by earlier versions of \s-2SPICE\s+2.
\fINote:\fR in spice3a7 and before, the \fI.control\fR and \fI.endc\fR
lines were not needed, and any line beginning with the name of a front-end
command would be executed.
.TP
\fBlinearize vec ...\fR
Create a new plot with all of the vectors in the current plot, or
only those mentioned if arguments are given. The new vectors
will be interpolated onto a linear time scale, which is determined
by the values of \fBtstep, tstart,\fR and \fBtstop\fR in the
currently active transient analysis. The currently loaded deck
must include a transient analysis (a \fBtran\fR command may be run
interactively before the last \fBreset\fR, alternately), and the
current plot must be from this transient analysis. This command
is needed because \s-2SPICE\s+2\&3 doesn't output the results
from a transient analysis in the same manner that \s-2SPICE\s+2\&2 did.
.PP
There are several \fBset\fR variables that \*S uses but \fBnutmeg\fR
does not. They are:
.IP "" 16
\fBeditor\fR
.br
The editor to use for the \fBedit\fR command.
.IP
\fBmodelcard\fR
.br
The name of the model card (normally \fB.model\fR).
.IP
\fBnoaskquit\fR
.br
Do not check to make sure that there are no circuits suspended and
no plots unsaved. Normally \*S will warn the user when he tries to
quit if this is the case.
.IP
\fBnobjthack\fR
.br
Assume that BJT's have 4 nodes.
.IP
\fBnoparse\fR
.br
Don't attempt to parse decks when they are read in (useful for
debugging). Of course, they
cannot be run if they are not parsed.
.IP
\fBnosubckt\fR
.br
Don't expand subcircuits.
.IP
\fBrenumber\fR
.br
Renumber input lines when a deck has \fB.include\fR's.
.IP
\fBsubend\fR
.br
The card to end subcircuits (normally \fB.ends\fR).
.IP
\fBsubinvoke\fR
.br
The prefix to invoke subcircuits (normally \fBx\fR).
.IP
\fBsubstart\fR
.br
The card to begin subcircuits (normally \fB.subckt\fR).
.PP
There are a number of \fBrusage\fR parameters available, in addition
to the ones available in \fBnutmeg\fR:
.IP "" 16
.PP
If there are subcircuits in the input file, \*S expands instances of them.
A subcircuit is delimited by the cards
.B .subckt
and
.B .ends,
or whatever the value of the variables
.B substart
and
.B subend
is, respectively. An instance of a subcircuit is created by specifying
a device with type 'x' \- the device line is written
.IP
\fBxname node1 node2 ... subcktname\fR
.LP
where the nodes are the node names that replace the formal parameters
on the \fB.subckt\fR line. All nodes that are not formal parameters
are prepended with the name given to the instance and a ':', as are
the names of the devices in the subcircuit. If there are several nested
subcircuits, node and device names look like \fBsubckt1:subckt2:...:name\fR.
If the variable \fBsubinvoke\fR is set, then it is used as the prefix
that specifies instances of subcircuits, instead of 'x'.
.SH "VMS NOTES"
The standard suffix for rawspice files in VMS is ".raw".
.PP
You may have to redefine the value EDITOR if you wish to use the \fBedit\fR
command, since the default for VMS is "vi".
.SH "SEE ALSO"
nutmeg(1), sconvert(1), spice(1), mfb(3), writedata(3)
\*S User's Guide
.SH AUTHORS
\*S: Tom Quarles (quarles@cad.berkeley.edu)
.br
\fBnutmeg\fR / User interface: Wayne Christopher (faustus@cad.berkeley.edu)
.SH BUGS
.PP
\*S will recognise all the notations used in \s-2SPICE\s+2\&2 \fB.plot\fR
cards, and will translate \fBvp(1)\fR into \fBph(v(1))\fR, and so
forth. However, if there are spaces in these names it won't work. Hence
\fBv(1, 2)\fR and \fB(-.5, .5)\fR aren't recognised.
.PP
BJT's can have either 3 or 4 nodes, which makes it difficult for the subcircuit
expansion routines to decide what to rename. If the fourth parameter has
been declared as a model name, then it is assumed that there are 3 nodes,
otherwise it is considered a node. To disable this kludge, you can set
the variable "nobjthack", which will force BJT's to have 4 nodes (for the
purposes of subcircuit expansion, at least).
.PP
The \fB@name[param]\fR notation might not work with \fBtrace, iplot,\fR etc.
yet.
.PP
The first line of a command file (except for the \fI.spiceinit\fR file)
should be a comment. Otherwise \s-2SPICE\s+2 may create an empty circuit
structure.
.SH CAVEATS
.PP
\*S files specified on the command line are read in before the\fB .spiceinit\fR
file is read. Thus if you define aliases there that you call in a
\*S source file mentioned on the command line, they won't be recognised.

View File

@ -1,3 +1,82 @@
2001-12-04 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* maths/cmaths/Makefile.am (noinst_PROGRAMS): test programs
shouldnt get installed
2000-10-13 Arno W. Peters <A.W.Peters@ieee.org>
* ngspice.txt: changes SPICE: to NGSPICE: to restore help
functionality. Thanks go to Michael Widlok for the analysis.
2000-07-21 Arno W. Peters <A.W.Peters@ieee.org>
* src/analysis/*: Moved these files into src/devices/analysis.
The files in this directory implement the analysis and simulation
for electrical circuits.
This is the final step to separating the Spice sources into a
library part and a frontend part. Now, the devices subdirectory
has to be renamed to spicelib and the devices that are now
scattered in that directory should be moved into a new devices
directory.
* configure.in, src/Makefile.am, src/devices/Makefile.am: Files
affected by the move.
2000-07-20 Arno W. Peters <A.W.Peters@ieee.org>
* src/hlp/*: moved these files into src/frontend/help. The files
in this directory implement the help system for the frontend.
* configure.in, src/Makefile.am, src/frontend/Makefile.am: Files
affected by the move.
* src/circuit/*: moved these files into src/devices/parser. The
files in this directory take a model line from the input file and
add the corresponding element to the representation of
the circuit in memory.
* configure.in, src/Makefile.am, src/devices/Makefile.am: Files
affected by the move.
2000-07-18 Arno W. Peters <A.W.Peters@ieee.org>
* main.c: Added the call to the initialization function of the
devices.
2000-07-07 Arno W. Peters <A.W.Peters@ieee.org>
* parser/cshpar.c: Separated out com_chdir(), com_echo(),
com_rehash() and com_shell() and moved them into frontend
directory.
* frontend/com_chdir.c, frontend/com_echo.c, frontend/com_rehash.c,
frontend/com_shell.c: Their new homes.
* parser/quote.c, parser/quote.h: The quote/unquote functions are
used exclusively in the frontend, moved them there.
* frontend/quote.c, frontend/quote.h: Their new location.
* parser/input.c, parser/input.h: Input, output and error streams
handled in the frontend. Moved to the frontend directory.
* frontend/streams.c: Its new home.
* frontend/Makefile.am: Updates for new files.
* frontend/breakp2.c, frontend/newcoms.c, frontend/postcoms.c,
frontend/resource.c, frontend/terminal.h, frontend/variable.c,
frontend/variable.h, frontend/com_compose.c,
frontend/com_display.c, frontend/com_setscale.c,
frontend/com_strcmp.c: Include files update.
* parser/var2.c, parser/var2.h: Empty files, removed.
* parser/Makefile.am: Updates for removed files.
* parser/lexical.c: Small adjustments
2000-04-04 Paolo Nenzi <p.nenzi@ieee.org>
* ngspice.c: Added support for BSIM4.

View File

@ -1,61 +1,64 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = analysis circuit devices frontend hlp maths misc parser include
SUBDIRS = misc maths frontend spicelib include @XSPICEDIR@
bin_PROGRAMS = ngspice nutmeg help sconvert proc2mod multidec makeidx
bin_PROGRAMS = ngspice ngnutmeg nghelp ngsconvert ngproc2mod ngmultidec makeidx
EXTRA_DIST = ngspice.txt ngspice.idx
EXTRA_DIST = ngspice.txt spinit setplot spectrum
helpdatadir = $(pkgdatadir)/helpdir
helpdata_DATA = ngspice.idx ngspice.txt
helpdata_DATA = ngspice.txt
initdatadir = $(pkgdatadir)/scripts
initdata_DATA = spinit setplot spectrum
DYNAMIC_DEVICELIBS = \
devices/asrc/libasrc.la \
devices/bjt/libbjt.la \
devices/bsim1/libbsim1.la \
devices/bsim2/libbsim2.la \
devices/bsim3/libbsim3.la \
devices/bsim4/libbsim4.la \
devices/bsim3v1/libbsim3v1.la \
devices/bsim3v2/libbsim3v2.la \
devices/cap/libcap.la \
devices/cccs/libcccs.la \
devices/ccvs/libccvs.la \
devices/csw/libcsw.la \
devices/devsup/libdevsup.la \
devices/dio/libdio.la \
devices/disto/libdisto.la \
devices/ind/libind.la \
devices/isrc/libisrc.la \
devices/jfet/libjfet.la \
devices/jfet2/libjfet2.la \
devices/ltra/libltra.la \
devices/cccs/libcccs.la \
devices/ccvs/libccvs.la \
devices/csw/libcsw.la \
devices/devsup/libdevsup.la \
devices/dio/libdio.la \
devices/disto/libdisto.la \
devices/ind/libind.la \
devices/isrc/libisrc.la \
devices/jfet/libjfet.la \
devices/jfet2/libjfet2.la \
devices/ltra/libltra.la \
devices/mes/libmes.la \
devices/mos1/libmos1.la \
devices/mos2/libmos2.la \
devices/mos3/libmos3.la \
devices/mos6/libmos6.la \
devices/res/libres.la \
devices/sw/libsw.la \
devices/tra/libtra.la \
devices/urc/liburc.la \
devices/vccs/libvccs.la \
devices/vcvs/libvcvs.la \
devices/vsrc/libvsrc.la
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 \
spicelib/devices/bsim3v1/libbsim3v1.la \
spicelib/devices/bsim3v2/libbsim3v2.la \
spicelib/devices/bsim4/libbsim4.la \
spicelib/devices/cap/libcap.la \
spicelib/devices/bsim3soi_pd/libbsim3soipd.la \
spicelib/devices/bsim3soi_fd/libbsim3soifd.la \
spicelib/devices/bsim3soi_dd/libbsim3soidd.la \
spicelib/devices/cccs/libcccs.la \
spicelib/devices/ccvs/libccvs.la \
spicelib/devices/ccvs/libccvs.la \
spicelib/devices/cpl/libcpl.la \
spicelib/devices/csw/libcsw.la \
spicelib/devices/dio/libdio.la \
@EKVLIB@ \
spicelib/devices/ind/libind.la \
spicelib/devices/isrc/libisrc.la \
spicelib/devices/hfet1/libhfet.la \
spicelib/devices/hfet2/libhfet2.la \
spicelib/devices/jfet/libjfet.la \
spicelib/devices/jfet2/libjfet2.la \
spicelib/devices/ltra/libltra.la \
spicelib/devices/mes/libmes.la \
spicelib/devices/mesa/libmesa.la \
spicelib/devices/mos1/libmos1.la \
spicelib/devices/mos2/libmos2.la \
spicelib/devices/mos3/libmos3.la \
spicelib/devices/mos6/libmos6.la \
spicelib/devices/mos9/libmos9.la \
spicelib/devices/res/libres.la \
spicelib/devices/soi3/libsoi3.la \
spicelib/devices/sw/libsw.la \
spicelib/devices/txl/libtxl.la \
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
## Build ngspice first:
@ -67,75 +70,80 @@ ngspice_SOURCES = \
ngspice_LDADD = \
spice.o \
frontend/libfte.a \
$(DYNAMIC_DEVICELIBS) \
analysis/libckt.a \
parser/libparser.a \
hlp/libhlp.a \
circuit/libinp.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 \
maths/deriv/libderiv.a \
maths/cmaths/libcmaths.a \
maths/poly/libpoly.a \
maths/ni/libni.a \
maths/sparse/libsparse.a \
misc/libmisc.a
misc/libmisc.a
spice.o: main.c
$(COMPILE) -DSIMULATOR -o spice.o -c $(srcdir)/main.c
## nutmeg:
nutmeg_SOURCES = \
ngnutmeg_SOURCES = \
main.c \
conf.c \
conf.h \
nutmeg.c
ngnutmeg.c
nutmeg_LDADD = \
ngnutmeg_LDADD = \
frontend/libfte.a \
parser/libparser.a \
hlp/libhlp.a \
frontend/plotting/libplotting.a \
frontend/parser/libparser.a \
frontend/help/libhlp.a \
maths/cmaths/libcmaths.a \
maths/poly/libpoly.a \
misc/libmisc.a
## help:
help_SOURCES = help.c
nghelp_SOURCES = nghelp.c
help_LDADD = \
hlp/libhlp.a \
parser/libparser.a \
nghelp_LDADD = \
frontend/help/libhlp.a \
frontend/parser/libparser.a \
frontend/libfte.a \
misc/libmisc.a
## sconvert:
sconvert_SOURCES = sconvert.c
ngsconvert_SOURCES = ngsconvert.c
sconvert_LDADD = \
ngsconvert_LDADD = \
frontend/libfte.a \
parser/libparser.a \
misc/libmisc.a
frontend/parser/libparser.a \
misc/libmisc.a
## proc2mod:
proc2mod_SOURCES = proc2mod.c
ngproc2mod_SOURCES = ngproc2mod.c
proc2mod_LDADD = \
parser/libparser.a \
circuit/libinp.a \
ngproc2mod_LDADD = \
frontend/parser/libparser.a \
spicelib/parser/libinp.a \
misc/libmisc.a
## multidec:
multidec_SOURCES = multidec.c
ngmultidec_SOURCES = ngmultidec.c
multidec_LDADD = \
ngmultidec_LDADD = \
maths/sparse/libsparse.a \
misc/libmisc.a
@ -155,8 +163,57 @@ all:
## General Includes and libraries:
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/devices @X_CFLAGS@
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices @X_CFLAGS@
LIBS = @LIBS@ @X_LIBS@ @X_PRE_LIBS@ @X_EXTRA_LIBS@
MAINTAINERCLEANFILES = Makefile.in
CLEANFILES = pkgIndex.tcl libspice.so
TCL_PKG_PATH = @TCL_PACKAGE_PATH@
TCLSPICE_VERSION = 0.2.7
TCL_FILES = libspice.so pkgIndex.tcl
LIBSPICE_OBJS = tclspice.o
pkgIndex.tcl: pkgIndex.tcl.in
rm -f pkgIndex.tcl
sed -e 's;%LIB_DIR%;$(TCL_PKG_PATH);g' pkgIndex.tcl.in | \
sed -e 's;%VERSION%;$(TCLSPICE_VERSION);g' > pkgIndex.tcl
tcl_install: tcl-install-recursive install-tclspice
tcl-install-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) install) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done;
install-tclspice: ${TCL_FILES}
install -c -m 644 libspice.so $(TCL_PKG_PATH)
mkdir -p $(TCL_PKG_PATH)/spice
install -c -m 644 pkgIndex.tcl $(TCL_PKG_PATH)/spice
tclspice.o: tclspice.c
$(COMPILE) -c -fpic tclspice.c -DTCLSPICE_version="\"$(TCLSPICE_VERSION)\""
libspice.so: $(ngspice_OBJECTS) $(LIBSPICE_OBJS) $(ngspice_DEPENDENCIES)
$(LINK) $(ngspice_LDFLAGS) $(ngspice_OBJECTS) $(ngspice_LDADD) $(LIBS) $(LIBSPICE_OBJS) -shared -lpthread
if test -f .libs/$@ ; then \
mv .libs/$@ ./ ;\
rmdir .libs ;\
fi
tcl: tcl-recursive
tcl-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) all) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done;
make ${TCL_FILES}

View File

@ -1,31 +1,230 @@
2001-11-25 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* circuits.h: transfered definition of sstructire 'circ' to ftedefs.h
2001-02-07 Paolo Nenzi <p.nenzi@ieee.org>
* outitf.c: From a message Alan sento to the mailing list:
---------- Forwarded message ----------
Date: Tue, 6 Feb 2001 11:11:56 -0000
From: "Gillespie, Alan" <Alan.Gillespie@analog.com>
Reply-To: ng-spice-devel@ieee.ing.uniroma1.it
To: "Ng-Spice-Devel (E-mail)" <ng-spice-devel@ieee.ing.uniroma1.it>
Subject: [ng-spice-devel] Reference variable update in interactive mode
I've tweaked outitf.c so that the reference variable value
is updated to the screen in interactive mode. I forgot to
save the old version first, though, so I couldn't do a diff,
so I'm just attaching the whole new outitf.c file. Also, I've
updated the documentation as follows :-
Modifications to "outitf.c"
---------------------------
A number of modifications have been applied to outitf.c in
order to achieve the following "improvements" :-
1) Spice3, by default, saved all node voltages, including
nodes internal to the devices. These extra nodes add
dramatically to the amount of data saved, but don't add
significantly to the useful information about the circuit.
So, instead of saving these nodes, a "hack" has been
introduced which checks a new spice option, and either
discards the internal node, or saves some device currents
instead.
2) During long simulations, spice would sit "staring back
blankly", giving no clue as to how well the simulation
was, or wasn't, proceeding. In order to give a little
more feedback, another "hack", in the data writing routine,
writes the value of the reference variable to the error
stream, which is usually the screen. In order to minimize
the CPU time "wasted" doing this, the routine will only
reprint the value if more than a quarter of a second since
the last screen update. The result is that this feedback
adds no significant extra time to performance of the
simulation.
3) The original file writing routines used to write each data
value to the file individually. A buffering scheme was added,
which collects each row of data in a buffer, and the writes
the whole buffer in one call. This gave a significant
performance improvement (up to 20%) on HPUX, with all currents
saved in large circuits, although there was no significant
difference on Windows 95. The improvement has not been
measured on Linux.
4) A check was added to make sure the file write was successful.
Spice3 could easily fill the hard disk, but would continue to
churn away, producing no more useful data. Now it will exit
gracefully. I can't remember why I thought this was important,
but at least it means that a PC with power management will be
able to power down after a long overnight simulation has
ceased to produce any more useful data.
Changes
-------
The routine beginPlot is called at the beginning of the simulation
to select which nodes and variables will be saved. The first
modification is at the point where it checks the "save" list. This
is the list of tokens attached to the .save lines read from the
spice source file. The routine now checks for "allv" and "alli"
as well as "all". "allv" is treated as a synonym for "all". If
"all" or "allv" is found, then a saveall flag is set, and if "alli"
is found then a new savealli flag is set.
Next, the addDataDesc routine is called for every variable to be
saved. This is done by stepping through an array called dataNames[].
I'm not quite sure where this array comes from, but it was quite
easy to add an if statement to stop it calling addDataDesc if
dataNames[i] points to a string containing any of the following -
#internal
#source
#drain
#collector
#emitter
#base
That seems to catch all the internal device nodes.
The next addition is a new pass through the dataNames[] array
specifically looking for those strings. (This pass is only performed
if the savealli flag has been set). When one of the strings is found,
a bunch of if-then-else statements creates a corresponding string
which is submitted to the add addSpecialDesc routine. This saves the
relevant device current. Note that since mosfets have only two
internal nodes, but four terminal currents, and bipolars have three
internal nodes and four terminal currents, some internal nodes have
to save more than one terminal current.
This last change is a clumsy hack, and only works if the devices in
question actually have internal nodes. Resistors and capacitors, for
instance, never have internal nodes, and so their terminal currents
will not cannot be saved with the .save alli card. Also, any bipolar,
mosfet or diodes with zero valued parasitic resistances (rd, rs, rc,
rb, re) will not be allocated internal nodes, and so their terminal
currents will not be saved by this hack, either.
Further down outitf.c, the OUTpData routine is called whenever a
new row of data is ready to be written to file. Near the top of this,
the reference variable is written to file separately from the rest of
the variables. This is a convenient point for a couple of statements
which check the elapsed time since the last update, and write the
reference value to stderr if it's time. Slightly further down the
routine is the section for writing data to a "plot", i.e. retaining
it in memory. A similar statement or two writes the reference value
to the screen for this case, i.e. interactive mode. At the end of the
OUTpData routine, a new check has been added to see if there was an
error writing to the rawfile. If so, the shouldstop flag is set to
TRUE, and the simulation will abort.
Scanning down outitf.c, the next modification is in the fileInit
routine. The first statement initialises the lastclock variable.
This is used later when deciding if it's time to write the reference
value to the screen.
Next, the fileInit_pass2 routine writes the name strings to the start
of the rawfile. At the end of this routine there is now a statement
which checks if this will be a binary rawfile, and if so, it allocates
a row buffer of the correct length.
The fileStartPoint routine seems to be called before each row of data
is written, and so this is a convenient point to reset the buffer
pointer to zero.
The fileAddRealValue and fileAddComplexValue routines now simply write
the relevant values to the buffer, and increment the buffer pointer.
Previously they called the fwrite library routine to actually write
the data. If the rawfile is not a binary one, however, they just write
the text as before.
The fileEndPoint routine was previously empty. Now it actually calls
fwrite to write the whole buffer to the file (if it's a binary file).
Finally the fileEnd routine prints the total number of data points to
the screen, and de-allocates the row buffer (if it was a binary
rawfile).
Congratulations to whoever put these dummy routines in in the first
place, since that allowed the buffering to be added very easily.
2001-01-23 Paolo Nenzi <p.nenzi@ieee.org>
* subckt.c: added some code (very, very experimental)
to support mos devices with variable number of nodes
(5 to 7) in subcircuit expansion. This hack is necessary
since SOI devices can have up to 7 nodes.
2000-11-07 Arno W. Peters <A.W.Peters@ieee.org>
* com_history, com_alias, parser/cshpar.c, parser/complete.c:
Applied patch by Michael Widlok. It fixes command completion and
history list. In the process, Michael also fixed a memory leak.
2000-09-09 Arno W. Peters <A.W.Peters@ieee.org>
* commands.c: Use fourier.h.
* dotcards.c: Update to prevent segfault.
* fourier.c, fourier.h: com_fourier is now calling fourier(), a
function with more parameters.
* dotcards.c: Added assertions to guard a double indirection, now
ngspice will bomb out on an assertion instead of a segfault.
2000-07-18 Arno W. Peters <A.W.Peters@ieee.org>
* com_ahelp.c, com_help.c, com_plot.c, com_set.c, com_unset.c:
Updated header file includes.
* quote.c: Code formatting changes.
2000-07-16 Arno W. Peters <A.W.Peters@ieee.org>
* com_set.h: New header file.
* com_state.c, com_state.h: Separated from debugcom.c.
* com_dump.c, com_dump.h: Separated from debugcom.c.
* debugcom.c, debugcom.h: Removed.
* Makefile.am: Updates for added/removed files.
2000-03-22 Paolo Nenzi <p.nenzi@ieee.org>
* rawfile.c: Applied Michael Widlok patch.
* spiceif.c: Applied Michael Widlok patch.
* rawfile.c: Applied Michael Widlok patch.
* spiceif.c: Applied Michael Widlok patch.
2000-03-12 Paolo Nenzi <p.nenzi@ieee.org>
* x11.c: Cleared the code. Rewmoved some empty return on void functions.
* x11.c: Cleared the code. Rewmoved some empty return on void
functions.
1999-12-20 Paolo Nenzi <p.nenzi@ieee.org>
outif.c:
To fix various "save"-related segmentation faults, make this one-line patch
to outitf.c: line 356, change
unique = devname; to unique = copy(devname);
* outif.c: To fix various "save"-related segmentation faults, make
this one-line patch to outitf.c: line 356, change unique =
devname; to unique = copy(devname);
1999-12-20 Paolo Nenzi <p.nenzi@ieee.org>
subckt.c:
Bug: Current controlled switch subcircuit does not expand
the controlling source correctly: vsrc expands to name:vsrc,
not to v:name:src.
Fix: changed this file to indicate that w device has only 2
not 3 nodes and 1 not zero controlling sources.
* subckt.c: Bug: Current controlled switch subcircuit does not
expand the controlling source correctly: vsrc expands to
name:vsrc, not to v:name:src.
Fix: changed this file to indicate that w device has only 2 not 3
nodes and 1 not zero controlling sources.
1999-09-07 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* *.c: put back static functions declarations back in the .c files (shouldn't
be in .h files!)
* *.c: put back static functions declarations back in the .c files
(shouldn't be in .h files!)
1999-09-07 Arno <A.W.Peters@ieee.org>
@ -34,7 +233,7 @@
* cmath1.c:
* cmath2.c: removed most warnings about possible use of
uninitialized variables. Only two remain in cx_sqrt().
uninitialized variables. Only two remain in cx_sqrt().
1999-09-06 Arno Peters <A.W.Peters@ieee.org>
@ -104,16 +303,14 @@
* resource.c: removed tests on HAS_UNIX_SEGMENT_HACK
* xgraph.c (ft_xgraph):
* options.c (cp_usrset):
* misccoms.c: removed tests on HAS_SYSTEM
* xgraph.c (ft_xgraph), options.c (cp_usrset), misccoms.c: removed
tests on HAS_SYSTEM
* nutinp.c:
* inp.c (com_source):
(doedit): removed tests on HAS_SYSTEM (always true?)
* nutinp.c, inp.c (com_source, doedit): removed tests on
HAS_SYSTEM (always true?)
* doplot.c (com_hardcopy): removed tests on HAS_UNLINK (always true)
(com_hardcopy): removed tests on HAS_SYSTEM (always true?)
* doplot.c (com_hardcopy): removed tests on HAS_UNLINK (always
true), removed tests on HAS_SYSTEM (always true?)
* signal.c:
* evaluate.c (doop):
@ -127,28 +324,22 @@
* aspice.c: changed HAS_WAIT into HAVE_SYS_WAIT_H
* inpcom.c:
* breakp.c: changed HAS_CTYPE into HAVE_CTYPE_H
* inpcom.c, breakp.c: changed HAS_CTYPE into HAVE_CTYPE_H
1999-08-03 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* signal.c:
* resource.c:
* evaluate.c:
* aspice.c: changed SIGNAL_TYPE into RETSIGTYPE
* signal.c, resource.c, evaluate.c, aspice.c: changed SIGNAL_TYPE
into RETSIGTYPE
1999-07-31 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Makefile.am: added @X_CFLAGS@ (X11 header files) to INCLUDES and removed
unused LIBS list.
* Makefile.am: added @X_CFLAGS@ (X11 header files) to INCLUDES and
removed unused LIBS list.
28-07-1999 emmanuel.rouat@wanadoo.fr (Manu Rouat)
* graf.c:
* display.c:
* doplot.c:
* x11.c: changed HAS_X11 define to X_DISPLAY_MISSING, which is supplied
by autoconf in config.h
* graf.c, display.c, doplot.c, x11.c: changed HAS_X11 define
to X_DISPLAY_MISSING, which is supplied by autoconf in config.h
* removed -DWANT_X11 in Makefile.am
* Makefile.am: removed -DWANT_X11

View File

@ -1,125 +1,173 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = plotting help parser
noinst_LIBRARIES = libfte.a
libfte_a_SOURCES = \
agraf.c \
agraf.h \
arg.c \
arg.h \
aspice.c \
aspice.h \
breakp.c \
breakp.h \
breakp2.c \
breakp2.h \
circuits.c \
circuits.h \
clip.c \
clip.h \
compose.c \
compose.h \
cpitf.c \
cpitf.h \
debugcom.c \
debugcom.h \
define.c \
define.h \
device.c \
device.h \
diff.c \
diff.h \
dimens.c \
dimens.h \
display.c \
display.h \
doplot.c \
doplot.h \
dotcards.c \
dotcards.h \
error.c \
error.h \
evaluate.c \
evaluate.h \
fourier.c \
fourier.h \
gens.c \
gens.h \
graf.c \
graf.h \
graphdb.c \
graphdb.h \
grid.c \
grid.h \
inp.c \
inp.h \
inpcom.c \
inpcom.h \
interp.c \
interp.h \
linear.c \
linear.h \
misccoms.c \
misccoms.h \
miscvars.c \
miscvars.h \
mw_coms.c \
mw_coms.h \
newcoms.c \
newcoms.h \
nutctab.c \
nutctab.h \
nutinp.c \
nutinp.h \
nutmegif.c \
nutmegif.h \
options.c \
options.h \
outitf.c \
outitf.h \
parse.c \
parse.h \
plot5.c \
plot5.h \
plotcurv.c \
plotcurv.h \
points.c \
points.h \
postcoms.c \
postcoms.h \
postsc.c \
postsc.h \
rawfile.c \
rawfile.h \
resource.c \
resource.h \
runcoms.c \
runcoms.h \
runcoms2.c \
runcoms2.h \
shyu.c \
shyu.h \
signal_handler.c\
signal_handler.h\
spec.c \
spec.h \
spcmdtab.c \
spiceif.c \
spiceif.h \
subckt.c \
subckt.h \
typesdef.c \
typesdef.h \
vectors.c \
vectors.h \
where.c \
where.h \
x11.c \
x11.h \
xgraph.c \
xgraph.h
commands.c \
commands.h \
com_ahelp.c \
com_ahelp.h \
com_alias.c \
com_alias.h \
com_asciiplot.c \
com_asciiplot.h \
com_cdump.c \
com_cdump.h \
com_chdir.c \
com_compose.c \
com_compose.h \
com_display.c \
com_display.h \
com_dump.c \
com_dump.h \
com_echo.c \
com_ghelp.c \
com_ghelp.h \
com_hardcopy.c \
com_hardcopy.h \
com_help.c \
com_help.h \
com_history.c \
com_history.h \
com_let.c \
com_let.h \
com_option.c \
com_option.h \
com_dl.c \
com_dl.h \
com_plot.c \
com_plot.h \
com_rehash.c \
com_set.c \
com_set.h \
com_setscale.c \
com_setscale.h \
com_shell.c \
com_shift.c \
com_state.c \
com_state.h \
com_strcmp.c \
com_strcmp.h \
com_unset.c \
com_xgraph.c \
com_xgraph.h \
completion.h \
control.h \
control.c \
ftehelp.h \
hcomp.c \
hcomp.h \
init.c \
init.h \
quote.c \
quote.h \
streams.h \
streams.c \
terminal.c \
terminal.h \
variable.c \
variable.h \
\
arg.c \
arg.h \
aspice.c \
aspice.h \
breakp.c \
breakp.h \
breakp2.c \
breakp2.h \
circuits.c \
circuits.h \
cpitf.c \
cpitf.h \
define.c \
define.h \
device.c \
device.h \
diff.c \
diff.h \
dimens.c \
dimens.h \
display.c \
display.h \
dotcards.c \
dotcards.h \
error.c \
error.h \
evaluate.c \
evaluate.h \
fourier.c \
fourier.h \
gens.c \
gens.h \
inp.c \
inp.h \
inpcom.c \
inpcom.h \
interp.c \
interp.h \
linear.c \
linear.h \
misccoms.c \
misccoms.h \
miscvars.c \
miscvars.h \
mw_coms.c \
mw_coms.h \
newcoms.c \
newcoms.h \
nutinp.c \
nutinp.h \
nutmegif.c \
nutmegif.h \
options.c \
options.h \
outitf.c \
outitf.h \
parse.c \
parse.h \
points.c \
points.h \
postcoms.c \
postcoms.h \
postsc.c \
postsc.h \
rawfile.c \
rawfile.h \
resource.c \
resource.h \
runcoms.c \
runcoms.h \
runcoms2.c \
runcoms2.h \
shyu.c \
shyu.h \
signal_handler.c\
signal_handler.h\
spec.c \
spec.h \
spiceif.c \
spiceif.h \
subckt.c \
subckt.h \
typesdef.c \
typesdef.h \
vectors.c \
vectors.h \
where.c \
where.h
# TESTS = testcommands
#
# bin_PROGRAMS = testcommands
#
# testcommands_SOURCES = \
# testcommands.c \
# testcommands.h
#
# testcommands_LDADD = libfte.a plotting/libplotting.a ../misc/libmisc.a
INCLUDES = -I$(top_srcdir)/src/include @X_CFLAGS@

5
src/frontend/README Normal file
View File

@ -0,0 +1,5 @@
This directory contains the code that is behind the commands of the
interactive frontend. Note that every command has a source file
associated with it. The source file is prefixed with `com_' to
distinguish command source files from other supporting code.

View File

@ -8,12 +8,13 @@ Author: 1987 Jeffrey M. Hsu
and prompt the user if necessary.
*/
#include "ngspice.h"
#include "fteinput.h"
#include "cpdefs.h"
#include "fteext.h"
#include "arg.h"
#include <ngspice.h>
#include <fteinput.h>
#include <cpdefs.h>
#include <fteext.h>
#include "arg.h"
#include "variable.h"
static void common(char *string, struct wordlist *wl, struct comm *command);

View File

@ -10,8 +10,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "aspice.h"
#include "aspice.h"
#include "variable.h"
#include "circuits.h"
# ifdef HAVE_SYS_WAIT_H
/* should be more tests here I think */
@ -31,7 +33,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include <signal.h>
#include "fteinp.h"
#include "ftedata.h"
#include "dvec.h"
#ifndef SEEK_SET
@ -174,13 +176,21 @@ sigchild(void)
* whether the exit was normal or not.
*/
#if defined(__NetBSD__)
pid_t status;
#else
union wait status;
#endif
void
ft_checkkids(void)
{
struct proc *p, *lp;
struct proc *p = NULL, *lp = NULL;
char buf[BSIZE_SP];
FILE *fp;
int pid;
int pid = 0;
static bool here = FALSE; /* Don't want to be re-entrant. */
if (!numchanged || here)
@ -189,10 +199,10 @@ ft_checkkids(void)
here = TRUE;
while (numchanged > 0) {
pid = wait((union wait *) NULL);
pid = wait(&status);
if (pid == -1) {
fprintf(cp_err,
"ft_checkkids: Internal Error: should be %d jobs done but there aren't any.\n",
fprintf(cp_err,
"ft_checkkids: Internal Error: should be %d jobs done but there aren't any.\n",
numchanged);
numchanged = 0;
running = NULL;
@ -293,12 +303,6 @@ com_rspice(wordlist *wl)
pid = fork( );
if (pid == 0) {
#ifdef notdef
char com_buf[200];
sprintf(com_buf, "%s %s %s -s", remote_shell, rhost, program);
printf("executing: \"%s\"\n", com_buf);
#endif
/* I am the "server" process */
close(to_serv[1]);
close(from_serv[0]);
@ -381,10 +385,6 @@ com_rspice(wordlist *wl)
fprintf(stderr, "Error reading rawdata: %s\n", buf);
continue;
}
#ifdef notdef
fprintf(stderr, "adjusting rawfile: write \"%d\" at %ld\n",
num, pos);
#endif
if (fseek(out, pos, SEEK_SET))
fprintf(stderr,
"Error adjusting rawfile: write \"%d\" at %ld\n",

View File

@ -10,10 +10,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "ftedebug.h"
#include "breakp.h"
#include "completion.h"
static bool satisfied(struct dbcomm *d, struct plot *plot);
static void printcond(struct dbcomm *d, FILE *fp);
@ -164,6 +165,7 @@ com_iplot(wordlist *wl)
d->db_type = DB_IPLOT;
d->db_nodename1 = copy(s);
}
tfree(s);/*DG: avoid memory leak */
d->db_also = currentdb;
currentdb = d;
wl = wl->wl_next;

View File

@ -10,8 +10,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "ftedebug.h"
#include "quote.h"
#include "breakp2.h"
@ -83,6 +85,7 @@ settrace(wordlist *wl, int what, char *name)
d->db_nodename1 = copy(s);
/* wrd_chtrace(s, TRUE, what); */
}
tfree(s);/*DG avoid memoy leak */
if (dbs) {
for (td = dbs; td->db_next; td = td->db_next)
;

View File

@ -3,32 +3,22 @@ Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
*
* Routines for dealing with the circuit database. This is currently
* unimplemented.
*/
/* Routines for dealing with the circuit database. This is currently
* unimplemented. */
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "circuits.h"
struct circ *ft_curckt = NULL; /* The default active circuit. */
struct circ *ft_circuits = NULL;
struct subcirc *ft_subcircuits = NULL;
/* Now stuff to deal with circuits */
void
ft_setccirc(char *name)
{
}
/* Add a circuit to the circuit list */
void
@ -38,12 +28,3 @@ ft_newcirc(struct circ *ckt)
ft_circuits = ckt;
return;
}
/* Add a new subcircuit to the subcircuit list */
void
ft_newsubcirc(struct subcirc *sckt)
{
}

View File

@ -7,9 +7,16 @@
#define CIRCUITS_H_INCLUDED
void ft_setccirc(char *name);
struct subcirc {
char *sc_name; /* Whatever... */
} ;
extern struct circ *ft_curckt; /* The default active circuit. */
void ft_newcirc(struct circ *ckt);
void ft_newsubcirc(struct subcirc *sckt);
#endif

89
src/frontend/com_ahelp.c Normal file
View File

@ -0,0 +1,89 @@
#include <config.h>
#include <ngspice.h>
#include <bool.h>
#include <wordlist.h>
#include <fteext.h>
#include "variable.h"
#include "com_help.h"
#include "hcomp.h"
#include "ftehelp.h"
#include "plotting/plotting.h"
void
com_ahelp(wordlist *wl)
{
int i, n;
/* assert: number of commands must be less than 512 */
struct comm *cc[512];
int env = 0;
struct comm *com;
int level;
char slevel[256];
if (wl) {
com_help(wl);
return;
}
out_init();
/* determine environment */
if (plot_list->pl_next) { /* plots load */
env |= E_HASPLOTS;
} else {
env |= E_NOPLOTS;
}
/* determine level */
if (cp_getvar("level", VT_STRING, slevel)) {
switch (*slevel) {
case 'b': level = 1;
break;
case 'i': level = 2;
break;
case 'a': level = 4;
break;
default: level = 1;
break;
}
} else {
level = 1;
}
out_printf(
"For a complete description read the Spice3 User's Manual manual.\n");
out_printf(
"For a list of all commands type \"help all\", for a short\n");
out_printf(
"description of \"command\", type \"help command\".\n");
/* sort the commands */
for (n = 0; cp_coms[n].co_func != (void (*)()) NULL; n++) {
cc[n] = &cp_coms[n];
}
qsort((char *) cc, n, sizeof(struct comm *), hcomp);
/* filter the commands */
for (i=0; i< n; i++) {
com = cc[i];
if ((com->co_env < (level << 13)) && (!(com->co_env & 4095) ||
(env & com->co_env))) {
if ((com->co_spiceonly && ft_nutmeg) ||
(com->co_help == (char *) NULL)) {
continue;
}
out_printf("%s ", com->co_comname);
out_printf(com->co_help, cp_program);
out_send("\n");
}
}
out_send("\n");
return;
}

7
src/frontend/com_ahelp.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef _COM_AHELP_H
#define _COM_AHELP_H
void com_ahelp(wordlist *wl);
#endif

241
src/frontend/com_alias.c Normal file
View File

@ -0,0 +1,241 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/* Do alias substitution. */
#include "ngspice.h"
#include "cpdefs.h"
#include "com_alias.h"
struct alias *cp_aliases = NULL;
/* Return NULL if no alias was found. We can get away with just
* calling cp_histsubst now because the line will have gone onto the
* history list by now and cp_histsubst will look in the right place. */
static wordlist *
asubst(wordlist *wlist)
{
struct alias *al;
wordlist *wl, *w = NULL;
char *word;
word = wlist->wl_word;
if (*word == '\\') {
wlist->wl_word++;
return (NULL);
}
for (al = cp_aliases; al; al = al->al_next)
if (eq(word, al->al_name))
break;
if (!al)
return (NULL);
wl = cp_histsubst(wl_copy(al->al_text));
if (cp_didhsubst) {
/* Make sure that we have an up-to-date last history entry. */
wl_free(cp_lastone->hi_wlist);
cp_lastone->hi_wlist = wl_copy(wl);
} else {
/* If it had no history args, then append the rest of the wl */
for (w = wl; w->wl_next; w = w->wl_next);
w->wl_next = wl_copy(wlist->wl_next);
if (w->wl_next)
w->wl_next->wl_prev = w;
}
return (wl);
}
/* MW. This function should not use cp_lastone, see cp_parse in cpshar.c
* Many things are deleted here and memory leak closed */
wordlist *
cp_doalias(wordlist *wlist)
{
int ntries;
wordlist *nwl, *nextc = NULL, *end = NULL;
wordlist *comm;
while (wlist && eq(wlist->wl_word, cp_csep))
wlist = wlist->wl_next;
wlist->wl_prev = NULL;
/* The alias process is going to modify the "last" line typed, so
* save a copy of what it really is and restore it after aliasing
* is done. We have to do tricky things do get around the problems
* with ; ... */
comm = wlist;
do {
end = comm->wl_prev;
comm->wl_prev = NULL;
for (nextc = comm; nextc; nextc = nextc->wl_next)
if (eq(nextc->wl_word, cp_csep)) {
if (nextc->wl_prev)
nextc->wl_prev->wl_next = NULL;
break;
}
for (ntries = 21; ntries; ntries--) {
nwl = asubst(comm);
if (nwl == NULL)
break;
if (eq(nwl->wl_word, comm->wl_word)) {
/* Just once through... */
wl_free(comm);
comm = nwl;
break;
} else {
wl_free(comm);
comm = nwl;
}
}
if (!ntries) {
fprintf(cp_err, "Error: alias loop.\n");
wlist->wl_word = NULL;
return (wlist);
}
comm->wl_prev = end;
if (!end)
wlist = comm;
else
end->wl_next = comm;
while (comm->wl_next)
comm = comm->wl_next;
comm->wl_next = nextc;
if (nextc) {
nextc->wl_prev = comm;
nextc = nextc->wl_next;
comm = nextc;
}
} while (nextc);
return (wlist);
}
/* If we use this, aliases will be in alphabetical order. */
void
cp_setalias(char *word, wordlist *wlist)
{
struct alias *al, *ta;
cp_unalias(word);
cp_addkword(CT_ALIASES, word);
if (cp_aliases == NULL) {
al = cp_aliases = alloc(struct alias);
al->al_next = NULL;
al->al_prev = NULL;
} else {
for (al = cp_aliases; al->al_next; al = al->al_next) {
if (strcmp(al->al_name, word) > 0)
break;
}
/* The new one goes before al */
if (al->al_prev) {
al = al->al_prev;
ta = al->al_next;
al->al_next = alloc(struct alias);
al->al_next->al_prev = al;
al = al->al_next;
al->al_next = ta;
ta->al_prev = al;
} else {
cp_aliases = alloc(struct alias);
cp_aliases->al_next = al;
cp_aliases->al_prev = NULL;
al->al_prev = cp_aliases;
al = cp_aliases;
}
}
al->al_name = copy(word);
al->al_text = wl_copy(wlist);
cp_striplist(al->al_text);
/* We can afford to not worry about the bits, because before the
* keyword lookup is done the alias is evaluated. Make everything
* file completion, just in case... */
cp_addcomm(word, (long) 1, (long) 1, (long) 1, (long) 1);
return;
}
void
cp_unalias(char *word)
{
struct alias *al;
cp_remkword(CT_ALIASES, word);
for (al = cp_aliases; al; al = al->al_next)
if (eq(word, al->al_name))
break;
if (al == NULL)
return;
if (al->al_next)
al->al_next->al_prev = al->al_prev;
if (al->al_prev)
al->al_prev->al_next = al->al_next;
else {
al->al_next->al_prev = NULL;
cp_aliases = al->al_next;
}
wl_free(al->al_text);
tfree(al->al_name);
tfree(al);
cp_remcomm(word);
return;
}
void
cp_paliases(char *word)
{
struct alias *al;
for (al = cp_aliases; al; al = al->al_next)
if ((word == NULL) || eq(al->al_name, word)) {
if (!word)
fprintf(cp_out, "%s\t", al->al_name);
wl_print(al->al_text, cp_out);
(void) putc('\n', cp_out);
}
return;
}
/* The routine for the "alias" command. */
void
com_alias(wordlist *wl)
{
if (wl == NULL)
cp_paliases((char *) NULL);
else if (wl->wl_next == NULL)
cp_paliases(wl->wl_word);
else
cp_setalias(wl->wl_word, wl->wl_next);
return;
}
void
com_unalias(wordlist *wl)
{
struct alias *al, *na;
if (eq(wl->wl_word, "*")) {
for (al = cp_aliases; al; al = na) {
na = al->al_next;
wl_free(al->al_text);
tfree(al->al_name);
tfree(al);
}
cp_aliases = NULL;
wl = wl->wl_next;
}
while (wl != NULL) {
cp_unalias(wl->wl_word);
wl = wl->wl_next;
}
return;
}

16
src/frontend/com_alias.h Normal file
View File

@ -0,0 +1,16 @@
/*************
* Header file for alias.c
* 1999 E. Rouat
************/
#ifndef ALIAS_H_INCLUDED
#define ALIAS_H_INCLUDED
wordlist * cp_doalias(wordlist *wlist);
void cp_setalias(char *word, wordlist *wlist);
void cp_unalias(char *word);
void cp_paliases(char *word);
void com_alias(wordlist *wl);
void com_unalias(wordlist *wl);
#endif

View File

@ -0,0 +1,17 @@
#include <config.h>
#include <ngspice.h>
#include <bool.h>
#include <wordlist.h>
#include "plotting/plotit.h"
#include "com_asciiplot.h"
void
com_asciiplot(wordlist *wl)
{
plotit(wl, (char *) NULL, "lpr");
return;
}

View File

@ -0,0 +1,7 @@
#ifndef _COM_ASCIIPLOT_H
#define _COM_ASCIIPLOT_H
void com_asciiplot(wordlist *wl);
#endif

140
src/frontend/com_cdump.c Normal file
View File

@ -0,0 +1,140 @@
#include <stdio.h>
#include <wordlist.h>
#include "control.h"
#include "streams.h"
static int indent;
static void
tab(int num)
{
int i;
for (i = 0; i < num; i++)
putc(' ', cp_out);
}
static void
dodump(struct control *cc)
{
struct control *tc;
switch (cc->co_type) {
case CO_UNFILLED:
tab(indent);
fprintf(cp_out, "(unfilled)\n");
break;
case CO_STATEMENT:
tab(indent);
wl_print(cc->co_text, cp_out);
putc('\n', cp_out);
break;
case CO_WHILE:
tab(indent);
fprintf(cp_out, "while ");
wl_print(cc->co_cond, cp_out);
putc('\n', cp_out);
indent += 8;
for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc);
indent -= 8;
tab(indent);
fprintf(cp_out, "end\n");
break;
case CO_REPEAT:
tab(indent);
fprintf(cp_out, "repeat ");
if (cc->co_numtimes != -1)
fprintf(cp_out, "%d\n", cc->co_numtimes);
else
putc('\n', cp_out);
indent += 8;
for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc);
indent -= 8;
tab(indent);
fprintf(cp_out, "end\n");
break;
case CO_DOWHILE:
tab(indent);
fprintf(cp_out, "dowhile ");
wl_print(cc->co_cond, cp_out);
putc('\n', cp_out);
indent += 8;
for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc);
indent -= 8;
tab(indent);
fprintf(cp_out, "end\n");
break;
case CO_IF:
tab(indent);
fprintf(cp_out, "if ");
wl_print(cc->co_cond, cp_out);
putc('\n', cp_out);
indent += 8;
for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc);
indent -= 8;
tab(indent);
fprintf(cp_out, "end\n");
break;
case CO_FOREACH:
tab(indent);
fprintf(cp_out, "foreach %s ", cc->co_foreachvar);
wl_print(cc->co_text, cp_out);
putc('\n', cp_out);
indent += 8;
for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc);
indent -= 8;
tab(indent);
fprintf(cp_out, "end\n");
break;
case CO_BREAK:
tab(indent);
if (cc->co_numtimes != 1)
fprintf(cp_out, "break %d\n", cc->co_numtimes);
else
fprintf(cp_out, "break\n");
break;
case CO_CONTINUE:
tab(indent);
if (cc->co_numtimes != 1)
fprintf(cp_out, "continue %d\n",
cc->co_numtimes);
else
fprintf(cp_out, "continue\n");
break;
case CO_LABEL:
tab(indent);
fprintf(cp_out, "label %s\n", cc->co_text->wl_word);
break;
case CO_GOTO:
tab(indent);
fprintf(cp_out, "goto %s\n", cc->co_text->wl_word);
break;
default:
tab(indent);
fprintf(cp_out, "bad type %d\n", cc->co_type);
break;
}
return;
}
void
com_cdump(wordlist *wl)
{
struct control *c;
indent = 0;
for (c = control[stackp]; c; c = c->co_next)
dodump(c);
return;
}

6
src/frontend/com_cdump.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _COM_CDUMP_H
#define _COM_CDUMP_H
void com_cdump(wordlist *wl);
#endif

58
src/frontend/com_chdir.c Normal file
View File

@ -0,0 +1,58 @@
#include <config.h>
#include <ngspice.h>
#include <wordlist.h>
#include "quote.h"
#include "streams.h"
void
com_chdir(wordlist *wl)
{
char *s;
struct passwd *pw;
extern struct passwd *getpwuid(uid_t);
char localbuf[257];
int copied = 0;
s = NULL;
if (wl == NULL) {
s = getenv("HOME");
#ifdef HAVE_PWD_H
if (s == NULL) {
pw = getpwuid(getuid());
if (pw == NULL) {
fprintf(cp_err, "Can't get your password entry\n");
return;
}
s = pw->pw_dir;
}
#endif
} else {
s = cp_unquote(wl->wl_word);
copied = 1;
}
if (*s && chdir(s) == -1)
perror(s);
if (copied)
tfree(s);
#ifdef HAVE_GETCWD
s = getcwd(localbuf, sizeof(localbuf));
if (s)
printf("Current directory: %s\n", s);
else
fprintf(cp_err, "Can't get current working directory.\n");
#endif
return;
}

484
src/frontend/com_compose.c Normal file
View File

@ -0,0 +1,484 @@
/* The 'compose' command. This is a more powerful and convenient form
* of the 'let' command. */
#include <ngspice.h>
#include <complex.h>
#include <dvec.h>
#include <bool.h>
#include <sim.h>
#include <pnode.h>
#include <fteext.h>
#include <cpextern.h>
#include "quote.h"
#include "com_compose.h"
#include "completion.h"
/* Copy the data from a vector into a buffer with larger dimensions. */
static void
dimxpand(struct dvec *v, int *newdims, double *data)
{
complex *cdata = (complex *) data;
bool realflag = isreal(v);
int i, j, o, n, t, u;
int ncount[MAXDIMS], ocount[MAXDIMS];
for (i = 0; i < MAXDIMS; i++)
ncount[i] = ocount[i] = 0;
for (;;) {
for (o = n = i = 0; i < v->v_numdims; i++) {
for (j = i, t = u = 1; j < v->v_numdims; j++) {
t *= v->v_dims[j];
u *= newdims[j];
}
o += ocount[i] * t;
n += ncount[i] * u;
}
if (realflag) {
data[n] = v->v_realdata[o];
} else {
realpart(&cdata[n]) = realpart(&v->v_compdata[o]);
imagpart(&cdata[n]) = imagpart(&v->v_compdata[o]);
}
/* Now find the nextstrchr element... */
for (i = v->v_numdims - 1; i >= 0; i--) {
if ((ocount[i] < v->v_dims[i] - 1) &&
(ncount[i] < newdims[i] - 1)) {
ocount[i]++;
ncount[i]++;
break;
} else
ocount[i] = ncount[i] = 0;
}
if (i < 0)
break;
}
return;
}
/* The general syntax is 'compose name parm = val ...'
* The possible parms are:
* start The value at which the vector should start.
* stop The value at which the vector should end.
* step The difference between sucessive elements.
* lin The number of points, linearly spaced.
* log The number of points, logarithmically spaced.
* dec The number of points per decade, logarithmically spaced.
* center Where to center the range of points.
* span The size of the range of points.
* unif ??
* gauss The number of points in the gaussian distribution.
* mean The mean value for the gass. dist.
* sd The standard deviation for the gauss. dist.
* random The number of randomly selected points.
* pool The name of a vector (must be already defined) to get
* random values -- default is 'unitvec(npoints)'
*
* The case 'compose name values val val ...' takes the values and creates a
* new vector -- the vals may be arbitrary expressions.
*
* NOTE: most of this doesn't work -- there will be plenty of unused variable
* lint messages...
*/
void
com_compose(wordlist *wl)
{
double start = 0.0;
double stop = 0.0;
double step = 0.0;
double lin = 0.0;
double center;
double span;
double mean, sd;
bool startgiven = FALSE, stopgiven = FALSE, stepgiven = FALSE;
bool lingiven = FALSE;
bool loggiven = FALSE, decgiven = FALSE, gaussgiven = FALSE;
bool randmgiven = FALSE;
bool spangiven = FALSE;
bool centergiven = FALSE;
bool meangiven = FALSE;
bool poolgiven = FALSE;
bool sdgiven = FALSE;
int log, dec, gauss, randm;
char *pool;
int i;
char *resname, *s, *var, *val;
double *td, tt;
double *data = NULL;
complex *cdata = NULL;
int length = 0;
int dim, type = SV_NOTYPE, blocksize;
bool realflag = TRUE;
int dims[MAXDIMS];
struct dvec *result, *vecs = NULL, *v, *lv = NULL;
struct pnode *pn, *first_pn;
bool reverse = FALSE;
resname = cp_unquote(wl->wl_word);
vec_remove(resname);
wl = wl->wl_next;
if (eq(wl->wl_word, "values")) {
/* Build up the vector from the rest of the line... */
wl = wl->wl_next;
if (!(pn = ft_getpnames(wl, TRUE)))
return;
first_pn = pn;
while (pn) {
if (!(v = ft_evaluate(pn)))
return;
if (!vecs)
vecs = lv = v;
else
lv->v_link2 = v;
for (lv = v; lv->v_link2; lv = lv->v_link2)
;
pn = pn->pn_next;
}
free_pnode(first_pn);
/* Now make sure these are all of the same dimensionality. We
* can coerce the sizes...
*/
dim = vecs->v_numdims;
if (dim < 2)
dim = (vecs->v_length > 1) ? 1 : 0;
if (dim == MAXDIMS) {
fprintf(cp_err, "Error: max dimensionality is %d\n",
MAXDIMS);
return;
}
for (v = vecs; v; v = v->v_link2)
if (v->v_numdims < 2)
v->v_dims[0] = v->v_length;
for (v = vecs->v_link2, length = 1; v; v = v->v_link2) {
i = v->v_numdims;
if (i < 2)
i = (v->v_length > 1) ? 1 : 0;
if (i != dim) {
fprintf(cp_err,
"Error: all vectors must be of the same dimensionality\n");
return;
}
length++;
if (iscomplex(v))
realflag = FALSE;
}
for (i = 0; i < dim; i++) {
dims[i] = vecs->v_dims[i];
for (v = vecs->v_link2; v; v = v->v_link2)
if (v->v_dims[i] > dims[i])
dims[i] = v->v_dims[i];
}
dim++;
dims[dim - 1] = length;
for (i = 0, blocksize = 1; i < dim - 1; i++)
blocksize *= dims[i];
if (realflag)
data = (double *) tmalloc(sizeof (double) * length *
blocksize);
else
cdata = (complex *) tmalloc(sizeof (complex) * length *
blocksize);
/* Now copy all the data over... If the sizes are too small
* then the extra elements are left as 0.
*/
for (v = vecs, i = 0; v; v = v->v_link2) {
if (dim == 1) {
if (realflag && isreal(v))
data[i] = v->v_realdata[0];
else if (isreal(v)) {
realpart(&cdata[i]) =
realpart(&v->v_compdata[0]);
imagpart(&cdata[i]) = 0.0;
} else {
realpart(&cdata[i]) =
realpart(&v->v_compdata[0]);
imagpart(&cdata[i]) =
imagpart(&v->v_compdata[0]);
}
i++;
continue;
}
dimxpand(v, dims, (realflag ? (data + i * blocksize) :
(double *) (cdata + i * blocksize)));
}
length *= blocksize;
} else {
/* Parse the line... */
while (wl) {
if ((s =strchr(wl->wl_word, '=')) && s[1]) {
/* This is var=val. */
*s = '\0';
var = wl->wl_word;
val = s + 1;
wl = wl->wl_next;
} else if (index(wl->wl_word, '=')) {
/* This is var= val. */
*s = '\0';
var = wl->wl_word;
wl = wl->wl_next;
if (wl) {
val = wl->wl_word;
wl = wl->wl_next;
} else {
fprintf(cp_err, "Error: bad syntax\n");
return;
}
} else {
/* This is var =val or var = val. */
var = wl->wl_word;
wl = wl->wl_next;
if (wl) {
val = wl->wl_word;
if (*val != '=') {
fprintf(cp_err,
"Error: bad syntax\n");
return;
}
val++;
if (!*val) {
wl = wl->wl_next;
if (wl) {
val = wl->wl_word;
} else {
fprintf(cp_err,
"Error: bad syntax\n");
return;
}
}
wl = wl->wl_next;
} else {
fprintf(cp_err, "Error: bad syntax\n");
return;
}
}
if (cieq(var, "start")) {
startgiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
start = *td;
} else if (cieq(var, "stop")) {
stopgiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
stop = *td;
} else if (cieq(var, "step")) {
stepgiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
step = *td;
} else if (cieq(var, "center")) {
centergiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
center = *td;
} else if (cieq(var, "span")) {
spangiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
span = *td;
} else if (cieq(var, "mean")) {
meangiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
mean = *td;
} else if (cieq(var, "sd")) {
sdgiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
sd = *td;
} else if (cieq(var, "lin")) {
lingiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
lin = *td;
} else if (cieq(var, "log")) {
loggiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
log = *td;
} else if (cieq(var, "dec")) {
decgiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
dec = *td;
} else if (cieq(var, "gauss")) {
gaussgiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
gauss = *td;
} else if (cieq(var, "random")) {
randmgiven = TRUE;
if (!(td = ft_numparse(&val, FALSE))) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
return;
}
randm = *td;
} else if (cieq(var, "pool")) {
poolgiven = TRUE;
pool = val;
}
}
#ifdef LINT
/* XXX Now, doesn't this look just a little suspicious */
if (centergiven || spangiven || meangiven || sdgiven ||
poolgiven)
j = k = l = m = q = inds = center + span + mean + sd +
log + dec + gauss + randm + pool;
#endif
/* Now see what we have... start and stop are pretty much
* compatible with everything...
*/
if (stepgiven && (step == 0.0)) {
fprintf(cp_err, "Error: step cannot = 0.0\n");
return;
}
if (startgiven && stopgiven && (start > stop)) {
tt = start;
start = stop;
stop = tt;
reverse = TRUE;
}
if (lingiven + loggiven + decgiven + randmgiven + gaussgiven
> 1) {
fprintf(cp_err,
"Error: can have at most one of (lin, log, dec, random, gauss)\n");
return;
} else if (lingiven + loggiven + decgiven + randmgiven +
gaussgiven == 0) {
/* Hmm, if we have a start, stop, and step we're ok. */
if (startgiven && stopgiven && stepgiven) {
lingiven = TRUE;
lin = (stop - start) / step + 1;
stepgiven = FALSE; /* Problems below... */
} else {
fprintf(cp_err,
"Error: either one of (lin, log, dec, random, gauss) must be given, or all\n");
fprintf(cp_err,
"\tof (start, stop, and step) must be given.\n");
return;
}
}
if (lingiven) {
/* Create a linear sweep... */
data = (double *) tmalloc(sizeof (double) * (int) lin);
if (stepgiven && startgiven && stopgiven) {
if (step != (stop - start) / lin * (reverse ?
-1 : 1)) {
fprintf(cp_err,
"Warning: bad step -- should be %g\n",
(stop - start) / lin *
(reverse ? -1 : 1));
stepgiven = FALSE;
}
}
if (!startgiven) {
if (stopgiven && stepgiven) {
start = stop - step * lin;
} else if (stopgiven) {
start = stop - lin;
} else {
start = 0;
}
startgiven = TRUE;
}
if (!stopgiven) {
if (stepgiven)
stop = start + lin * step;
else
stop = start + lin;
stopgiven = TRUE;
}
if (!stepgiven) {
step = (stop - start) / lin;
}
if (reverse)
for (i = 0, tt = stop; i < lin;
i++, tt -= step)
data[i] = tt;
else
for (i = 0, tt = start; i < lin;
i++, tt += step)
data[i] = tt;
length = lin;
} else if (loggiven || decgiven) {
/* Create a log sweep... */
} else if (randmgiven) {
/* Create a set of random values... */
} else if (gaussgiven) {
/* Create a gaussian distribution... */
}
}
result = alloc(struct dvec);
ZERO(result, struct dvec);
result->v_name = copy(resname);
result->v_type = type;
result->v_flags = (realflag ? VF_REAL : VF_COMPLEX) | VF_PERMANENT;
if (realflag)
result->v_realdata = data;
else
result->v_compdata = cdata;
result->v_length = length;
result->v_numdims = 1;
result->v_dims[0] = length;
vec_new(result);
cp_addkword(CT_VECTOR, result->v_name);
tfree(resname);/*DG: resname has been copied so its remains allocated: memory leak One can remove this and not copy resname*/
return;
}

View File

@ -0,0 +1,10 @@
#ifndef _COM_COMPOSE_H
#define _COM_COMPOSE_H
#include <wordlist.h>
void com_compose(wordlist *wl);
#endif

View File

@ -0,0 +1,80 @@
#include <ngspice.h>
#include <bool.h>
#include <wordlist.h>
#include <fteext.h>
#include <cpextern.h>
#include "com_display.h"
#include "quote.h"
#include "variable.h"
#include "plotting/plotting.h"
#include "plotting/pvec.h"
/* For the sort in display. */
static int
dcomp(const void *d1, const void *d2)
{
struct dvec **v1 = (struct dvec **) d1;
struct dvec **v2 = (struct dvec **) d2;
return (strcmp((*v1)->v_name, (*v2)->v_name));
}
/* Display vector status, etc. Note that this only displays stuff
* from the current plot, and you must do a setplot to see the rest of
* it. */
void
com_display(wordlist *wl)
{
struct dvec *d;
struct dvec **dvs;
int len = 0, i = 0;
bool b;
char *s;
/* Maybe he wants to know about just a few vectors. */
out_init();
while (wl) {
s = cp_unquote(wl->wl_word);
d = vec_get(s);
tfree(s);/*DG to avoid the cp_unquote memory leak */
if (d == NULL)
fprintf(cp_err, "Error: no such vector as %s.\n",
wl->wl_word);
else
while (d) {
pvec(d);
d = d->v_link2;
}
if (wl->wl_next == NULL)
return;
wl = wl->wl_next;
}
if (plot_cur)
for (d = plot_cur->pl_dvecs; d; d = d->v_next)
len++;
if (len == 0) {
fprintf(cp_out, "There are no vectors currently active.\n");
return;
}
out_printf("Here are the vectors currently active:\n\n");
dvs = (struct dvec **) tmalloc(len * (sizeof (struct dvec *)));
for (d = plot_cur->pl_dvecs, i = 0; d; d = d->v_next, i++)
dvs[i] = d;
if (!cp_getvar("nosort", VT_BOOL, (char *) &b))
qsort((char *) dvs, len, sizeof (struct dvec *), dcomp);
out_printf("Title: %s\n", plot_cur->pl_title);
out_printf("Name: %s (%s)\nDate: %s\n\n",
plot_cur->pl_typename, plot_cur->pl_name,
plot_cur->pl_date);
for (i = 0; i < len; i++) {
d = dvs[i];
pvec(d);
}
return;
}

View File

@ -0,0 +1,8 @@
#ifndef _COM_DISPLAY_H
#define _COM_DISPLAY_H
#include <wordlist.h>
void com_display(wordlist *wl);
#endif

24
src/frontend/com_dl.c Executable file
View File

@ -0,0 +1,24 @@
#include <ngspice.h> /* for wl */
#include "ftedefs.h"
#include <devdefs.h> /* solve deps in dev.h*/
#include <../spicelib/devices/dev.h> /*for load library commands*/
#ifdef XSPICE
void com_codemodel(wordlist *wl){
wordlist *ww;
for(ww = wl;ww;ww = ww->wl_next)
if(load_opus(wl->wl_word))
fprintf(cp_err,"Error: Library %s couldn't be loaded!\n",ww->wl_word);
return;
}
#endif
#ifdef DEVLIB
void com_use(wordlist *wl){
wordlist *ww;
for(ww = wl;ww;ww = ww->wl_next)
if(load_dev(wl->wl_word))
fprintf(cp_err,"Error: Library %s couldn't be loaded!\n",ww->wl_word);
return;
}
#endif

12
src/frontend/com_dl.h Executable file
View File

@ -0,0 +1,12 @@
#ifndef _COM_DL_H
#define _COM_DL_H 1
#ifdef XSPICE
void com_codemodel(wordlist *wl);
#endif
#ifdef DEVLIB
void com_use(wordlist *wl);
#endif
#endif

21
src/frontend/com_dump.c Normal file
View File

@ -0,0 +1,21 @@
#include <config.h>
#include <ngspice.h>
#include <bool.h>
#include <wordlist.h>
#include <inpdefs.h>
#include "circuits.h"
#include "com_dump.h"
#include "streams.h"
#include "fteext.h"
void
com_dump(wordlist *wl)
{
if (!ft_curckt || !ft_curckt->ci_ckt) {
fprintf(cp_err, "Error: no circuit loaded.\n");
return;
}
if_dump(ft_curckt->ci_ckt, cp_out);
return;
}

6
src/frontend/com_dump.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _COM_DUMP_H
#define _COM_DUMP_H
void com_dump(wordlist *wl);
#endif

31
src/frontend/com_echo.c Normal file
View File

@ -0,0 +1,31 @@
#include <config.h>
#include <ngspice.h>
#include <wordlist.h>
#include <bool.h>
#include "quote.h"
#include "streams.h"
void
com_echo(wordlist *wlist)
{ char*copyword;
bool nl = TRUE;
if (wlist && eq(wlist->wl_word, "-n")) {
wlist = wlist->wl_next;
nl = FALSE;
}
while (wlist) {
/* fputs(cp_unquote(wlist->wl_word), cp_out); very bad the string allocated by cp_unquote could not be freed: memory leak*/
copyword=cp_unquote(wlist->wl_word);
fputs(copyword, cp_out);
tfree(copyword);
if (wlist->wl_next)
fputs(" ", cp_out);
wlist = wlist->wl_next;
}
if (nl)
fputs("\n", cp_out);
}

70
src/frontend/com_ghelp.c Normal file
View File

@ -0,0 +1,70 @@
#include <ngspice.h>
#include <wordlist.h>
#include <bool.h>
#include <variable.h>
#include <hlpdefs.h>
#include "com_ghelp.h"
#include "com_help.h"
#include "variable.h"
#include "streams.h"
#include "cpextern.h"
void
com_ghelp(wordlist *wl)
{
char *npath;
char *path = Help_Path;
char buf[BSIZE_SP];
int i;
if (cp_getvar("helppath", VT_STRING, buf))
path = copy(buf);
if (!path) {
fprintf(cp_err, "Note: defaulting to old help.\n\n");
com_help(wl);
return;
}
if (!(npath = cp_tildexpand(path))) {
fprintf(cp_err, "Note: can't find help dir %s\n", path);
fprintf(cp_err, "Defaulting to old help.\n\n");
com_help(wl);
return;
}
path = npath;
if (cp_getvar("helpregfont", VT_STRING, buf))
hlp_regfontname = copy(buf);
if (cp_getvar("helpboldfont", VT_STRING, buf))
hlp_boldfontname = copy(buf);
if (cp_getvar("helpitalicfont", VT_STRING, buf))
hlp_italicfontname = copy(buf);
if (cp_getvar("helptitlefont", VT_STRING, buf))
hlp_titlefontname = copy(buf);
if (cp_getvar("helpbuttonfont", VT_STRING, buf))
hlp_buttonfontname = copy(buf);
if (cp_getvar("helpinitxpos", VT_NUM, (char *) &i))
hlp_initxpos = i;
if (cp_getvar("helpinitypos", VT_NUM, (char *) &i))
hlp_initypos = i;
if (cp_getvar("helpbuttonstyle", VT_STRING, buf)) {
if (cieq(buf, "left"))
hlp_buttonstyle = BS_LEFT;
else if (cieq(buf, "center"))
hlp_buttonstyle = BS_CENTER;
else if (cieq(buf, "unif"))
hlp_buttonstyle = BS_UNIF;
else
fprintf(cp_err, "Warning: no such button style %s\n",
buf);
}
if (cp_getvar("width", VT_NUM, (char *) &i))
hlp_width = i;
if (cp_getvar("display", VT_STRING, buf))
hlp_displayname = copy(buf);
else if (cp_getvar("device", VT_STRING, buf))
hlp_displayname = copy(buf);
else
hlp_displayname = NULL;
hlp_main(path, wl);
return;
}

8
src/frontend/com_ghelp.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _COM_GHELP_H
#define _COM_GHELP_H
void com_ghelp(wordlist *wl);
#endif

168
src/frontend/com_hardcopy.c Normal file
View File

@ -0,0 +1,168 @@
#include <config.h>
#include <stdio.h>
#include <ngspice.h>
#include <defines.h>
#include <bool.h>
#include <wordlist.h>
#include <cpdefs.h>
#include <fteinput.h>
#include <ftedev.h>
#include "plotting/plotit.h"
#include "plotting/graphdb.h"
#include "plotting/graf.h"
#include "arg.h"
#include "display.h"
#include "com_hardcopy.h"
#include "variable.h"
/* hardcopy file plotargs, or 'hardcopy file' -- with no other args
* this prompts the user for a window to dump to a plot file. XXX no
* it doesn't. */
void
com_hardcopy(wordlist *wl)
{
char *buf2;
wordlist *process(wordlist *wlist);
char *fname;
char buf[BSIZE_SP], device[BSIZE_SP];
bool tempf = FALSE;
char *devtype;
char format[513];
int printed;
int hc_button;
int foundit;
if (!cp_getvar("hcopydev", VT_STRING, device))
*device = '\0';
if (wl) {
hc_button = 0;
fname = wl->wl_word;
wl = wl->wl_next;
} else {
hc_button = 1;
fname = smktemp("hc");
tempf = TRUE;
}
if (!cp_getvar("hcopydevtype", VT_STRING, buf)) {
devtype = "plot5";
} else {
devtype = buf;
}
/* enable screen plot selection for these display types */
foundit = 0;
#ifndef X_DISPLAY_MISSING
if (!wl && hc_button) {
REQUEST request;
RESPONSE response;
GRAPH *tempgraph;
request.option = click_option;
Input(&request, &response);
if (response.option == error_option) return;
if (response.reply.graph) {
if (DevSwitch(devtype)) return;
tempgraph = CopyGraph(response.reply.graph);
tempgraph->devdep = fname;
if (NewViewport(tempgraph)) {
DevSwitch(NULL);
return;
}
gr_resize(tempgraph);
gr_redraw(tempgraph);
DestroyGraph(tempgraph->graphid);
DevSwitch(NULL);
foundit = 1;
}
}
#endif
if (!foundit) {
if (!wl) {
outmenuprompt("which variable ? ");
if ((buf2 = prompt(cp_in)) == (char *) -1) /* XXXX Sick */
return;
wl = (struct wordlist *) tmalloc(sizeof(struct wordlist));
wl->wl_word = buf2;
wl->wl_next = NULL;
wl = process(wl);
}
if (DevSwitch(devtype)) return;
if (!wl || !plotit(wl, fname, (char *) NULL)) {
printf("com_hardcopy: graph not defined\n");
DevSwitch(NULL); /* remember to switch back */
return;
}
DevSwitch(NULL);
}
printed = 0;
if (*device) {
#ifdef SYSTEM_PLOT5LPR
if (!strcmp(devtype, "plot5") || !strcmp(devtype, "MFB")) {
if (!cp_getvar("lprplot5", VT_STRING, format))
strcpy(format, SYSTEM_PLOT5LPR);
(void) sprintf(buf, format, device, fname);
fprintf(cp_out, "Printing %s on the %s printer.\n", fname, device);
(void) system(buf);
printed = 1;
}
#endif
#ifdef SYSTEM_PSLPR
if (!printed && !strcmp(devtype, "postscript")) {
/* note: check if that was a postscript printer XXX */
if (!cp_getvar("lprps", VT_STRING, format))
strcpy(format, SYSTEM_PSLPR);
(void) sprintf(buf, format, device, fname);
fprintf(cp_out, "Printing %s on the %s printer.\n", fname, device);
(void) system(buf);
printed = 1;
}
#endif
}
if (!printed) {
if (!strcmp(devtype, "plot5")) {
fprintf(cp_out,
"The file \"%s\" may be printed with the Unix \"plot\" command,\n",
fname);
fprintf(cp_out,
"\tor by using the '-g' flag to the Unix lpr command.\n");
} else if (!strcmp(devtype, "postscript")) {
fprintf(cp_out,
"The file \"%s\" may be printed on a postscript printer.\n",
fname);
} else if (!strcmp(devtype, "MFB")) {
fprintf(cp_out,
"The file \"%s\" may be printed on a MFB device.\n",
fname);
}
}
if (tempf && *device)
(void) unlink(fname);
return;
}

View File

@ -0,0 +1,7 @@
#ifndef _COM_HARDCOPY_H
#define _COM_HARDCOPY_H
void com_hardcopy(wordlist *wl);
#endif

87
src/frontend/com_help.c Normal file
View File

@ -0,0 +1,87 @@
#include <config.h>
#include <ngspice.h>
#include <macros.h>
#include <wordlist.h>
#include <cpdefs.h>
#include <bool.h>
#include "hcomp.h"
void
com_help(wordlist *wl)
{
struct comm *c;
struct comm *ccc[512]; /* Should be enough. */
int numcoms, i;
bool allflag = FALSE;
if (wl && eq(wl->wl_word, "all")) {
allflag = TRUE;
wl = NULL; /* XXX Probably right */
}
/* We want to use more mode whether "moremode" is set or not. */
out_moremode = TRUE;
out_init();
out_moremode = FALSE;
if (wl == NULL) {
out_printf("For a complete description "
"read the Spice3 User's Manual.\n");
if (!allflag) {
out_printf("For a list of all commands "
"type \"help all\", for a short\n"
"description of \"command\", "
"type \"help command\".\n");
}
/* Sort the commands */
for (numcoms = 0; cp_coms[numcoms].co_func != NULL; numcoms++)
ccc[numcoms] = &cp_coms[numcoms];
qsort((char *) ccc, numcoms, sizeof (struct comm *), hcomp);
for (i = 0; i < numcoms; i++) {
if ((ccc[i]->co_spiceonly && ft_nutmeg) ||
(ccc[i]->co_help == NULL) ||
(!allflag && !ccc[i]->co_major))
continue;
out_printf("%s ", ccc[i]->co_comname);
out_printf(ccc[i]->co_help, cp_program);
out_send("\n");
}
} else {
while (wl != NULL) {
for (c = &cp_coms[0]; c->co_func != NULL; c++)
if (eq(wl->wl_word, c->co_comname)) {
out_printf("%s ", c->co_comname);
out_printf(c->co_help, cp_program);
if (c->co_spiceonly && ft_nutmeg)
out_send(" (Not available in nutmeg)");
out_send("\n");
break;
}
if (c->co_func == NULL) {
/* See if this is aliased. */
struct alias *al;
for (al = cp_aliases; al; al = al->al_next)
if (eq(al->al_name, wl->wl_word))
break;
if (al == NULL)
fprintf(cp_out, "Sorry, no help for %s.\n",
wl->wl_word);
else {
out_printf("%s is aliased to ", wl->wl_word);
/* Minor badness here... */
wl_print(al->al_text, cp_out);
out_send("\n");
}
}
wl = wl->wl_next;
}
}
out_send("\n");
return;
}

8
src/frontend/com_help.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _COM_HELP_H
#define _COM_HELP_H
void com_help(wordlist *wl);
#endif

493
src/frontend/com_history.c Normal file
View File

@ -0,0 +1,493 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/* Do history substitutions. */
#include <ngspice.h>
#include <cpdefs.h>
#include "com_history.h"
/* static declarations */
static wordlist * dohsubst(char *string);
static wordlist * dohmod(char **string, wordlist *wl);
static wordlist * hpattern(char *buf);
static wordlist * hprefix(char *buf);
static wordlist * getevent(int num);
static void freehist(int num);
static char * dohs(char *pat, char *str);
struct histent *cp_lastone = NULL;
int cp_maxhistlength = 10000; /* Chris Inbody */
char cp_hat = '^';
char cp_bang = '!';
bool cp_didhsubst;
static struct histent *histlist = NULL;
static int histlength = 0;
/* First check for a ^ at the beginning of the line, and then search
* each word for !. Following this can be any of string, number,
* ?string, -number ; then there may be a word specifier, the same as
* csh, and then the : modifiers. For the :s modifier, the syntax is
* :sXoooXnnnX, where X is any character, and ooo and nnn are strings
* not containing X.
*/
wordlist *
cp_histsubst(wordlist *wlist)
{
wordlist *nwl, *w, *n;
char buf[BSIZE_SP], *s, *b;
/* Replace ^old^new with !:s^old^new. */
cp_didhsubst = FALSE;
if (*wlist->wl_word == cp_hat) {
(void) sprintf(buf, "%c%c:s%s", cp_bang, cp_bang,
wlist->wl_word);
tfree(wlist->wl_word);
wlist->wl_word = copy(buf);
}
for (w = wlist; w; w = w->wl_next) {
b = w->wl_word;
for (s = b; *s; s++)
if (*s == cp_bang) {
cp_didhsubst = TRUE;
n = dohsubst(s + 1);
if (!n) {
wlist->wl_word = NULL;
return (wlist);
}
if (b < s) {
(void) sprintf(buf, "%.*s%s", s - b, b,
n->wl_word);
tfree(n->wl_word);
n->wl_word = copy(buf);
}
nwl = wl_splice(w, n);
if (wlist == w)
wlist = n;
w = nwl;
break;
}
}
return (wlist);
}
/* Do a history substitution on one word. Figure out which event is
* being referenced, then do word selections and modifications, and
* then stick anything left over on the end of the last word.
*/
static wordlist *
dohsubst(char *string)
{
wordlist *wl, *nwl;
char buf[BSIZE_SP], *s, *r = NULL, *t;
if (*string == cp_bang) {
if (cp_lastone) {
wl = cp_lastone->hi_wlist;
string++;
} else {
fprintf(cp_err, "0: event not found.\n");
return (NULL);
}
} else {
switch(*string) {
case '-':
wl = getevent(cp_event - scannum(++string));
if (!wl)
return (NULL);
while (isdigit(*string))
string++;
break;
case '?':
(void) strcpy(buf, string + 1);
if ((s =strchr(buf, '?')))
*s = '\0';
wl = hpattern(buf);
if (!wl)
return (NULL);
if (s == NULL) /* No modifiers on this one. */
return (wl_copy(wl));
break;
case '\0': /* Maybe this should be cp_event. */
wl = alloc(struct wordlist);
wl->wl_word = copy("!");
wl->wl_next = NULL;
wl->wl_prev = NULL;
cp_didhsubst = FALSE;
return (wl);
default:
if (isdigit(*string)) {
wl = getevent(scannum(string));
if (!wl)
return (NULL);
while (isdigit(*string))
string++;
} else {
(void) strcpy(buf, string);
for (s = ":^$*-%"; *s; s++) {
t =strchr(buf, *s);
if (t && ((t < r) || !r)) {
r = t;
string += r - buf;
}
}
if (r)
*r = '\0';
else
while (*string)
string++;
if ((buf[0] == '\0') && cp_lastone)
wl = cp_lastone->hi_wlist;
else
wl = hprefix(buf);
if (!wl)
return (NULL);
}
}
}
if (wl == NULL) { /* Shouldn't happen. */
fprintf(cp_err, "Event not found.\n");
return (NULL);
}
nwl = dohmod(&string, wl_copy(wl));
if (!nwl)
return (NULL);
if (*string) {
for (wl = nwl; wl->wl_next; wl = wl->wl_next)
;
(void) sprintf(buf, "%s%s", wl->wl_word, string);
tfree(wl->wl_word);
wl->wl_word = copy(buf);
}
return (nwl);
}
static wordlist *
dohmod(char **string, wordlist *wl)
{
wordlist *w;
char *s;
char *r = NULL, *t;
int numwords, eventlo, eventhi, i;
bool globalsubst;
anothermod:
numwords = wl_length(wl);
globalsubst = FALSE;
eventlo = 0;
eventhi = numwords - 1;
/* Now we know what wordlist we want. Take care of modifiers now. */
r = NULL;
for (s = ":^$*-%"; *s; s++) {
t =strchr(*string, *s);
if (t && ((t < r) || (r == NULL)))
r = t;
}
if (!r) /* No more modifiers. */
return (wl);
*string = r;
if (**string == ':')
(*string)++;
switch(**string) {
case '$': /* Last word. */
eventhi = eventlo = numwords - 1;
break;
case '*': /* Words 1 through $ */
if (numwords == 1)
return (NULL);
eventlo = 1;
eventhi = numwords - 1;
break;
case '-': /* Words 0 through ... */
eventlo = 0;
if (*(*string + 1))
eventhi = scannum(*string + 1);
else
eventhi = numwords - 1;
if (eventhi > numwords - 1)
eventhi = numwords - 1;
break;
case 'p': /* Print the command and don't execute it.
* This doesn't work quite like csh.
*/
wl_print(wl, cp_out);
(void) putc('\n', cp_out);
return (NULL);
case 's': /* Do a substitution. */
for (w = wl; w; w = w->wl_next) {
s = dohs(*string + 1, w->wl_word);
if (s) {
tfree(w->wl_word);
w->wl_word = s;
if (globalsubst == FALSE) {
while (**string)
(*string)++;
break;
}
}
}
/* In case globalsubst is TRUE... */
while (**string)
(*string)++;
break;
default:
if (!isdigit(**string)) {
fprintf(cp_err, "Error: %s: bad modifier.\n",
*string);
return (NULL);
}
i = scannum(*string);
if (i > eventhi) {
fprintf(cp_err, "Error: bad event number %d\n",
i);
return (NULL);
}
eventhi = eventlo = i;
while (isdigit(**string))
(*string)++;
if (**string == '*')
eventhi = numwords - 1;
if (**string == '-') {
if (!isdigit(*(*string + 1)))
eventhi = numwords - 1;
else {
eventhi = scannum(++*string);
while (isdigit(**string))
(*string)++;
}
}
}
/* Now change the word list accordingly and make another pass
* if there is more of the substitute left.
*/
wl = wl_range(wl, eventlo, eventhi);
numwords = wl_length(wl);
if (**string && *++*string)
goto anothermod;
return (wl);
}
/* Look for an event with a pattern in it... */
static wordlist *
hpattern(char *buf)
{
struct histent *hi;
wordlist *wl;
if (*buf == '\0') {
fprintf(cp_err, "Bad pattern specification.\n");
return (NULL);
}
for (hi = cp_lastone; hi; hi = hi->hi_prev)
for (wl = hi->hi_wlist; wl; wl = wl->wl_next)
if (substring(buf, wl->wl_word))
return (hi->hi_wlist);
fprintf(cp_err, "%s: event not found.\n", buf);
return (NULL);
}
static wordlist *
hprefix(char *buf)
{
struct histent *hi;
if (*buf == '\0') {
fprintf(cp_err, "Bad pattern specification.\n");
return (NULL);
}
for (hi = cp_lastone; hi; hi = hi->hi_prev)
if (hi->hi_wlist && prefix(buf, hi->hi_wlist->wl_word))
return (hi->hi_wlist);
fprintf(cp_err, "%s: event not found.\n", buf);
return (NULL);
}
/* Add a wordlist to the history list. (Done after the first parse.) Note
* that if event numbers are given in a random order that's how they'll
* show up in the history list.
*/
void
cp_addhistent(int event, wordlist *wlist)
{
/* MW. This test is not needed if everything works right
if (cp_lastone && !cp_lastone->hi_wlist)
fprintf(cp_err, "Internal error: bad history list\n"); */
if (cp_lastone == NULL) {
/* MW. the begging - initialize histlength*/
histlength = 1;
cp_lastone = histlist = alloc(struct histent);
cp_lastone->hi_prev = NULL;
} else {
cp_lastone->hi_next = alloc(struct histent);
cp_lastone->hi_next->hi_prev = cp_lastone;
cp_lastone = cp_lastone->hi_next;
}
cp_lastone->hi_next = NULL;
cp_lastone->hi_event = event;
cp_lastone->hi_wlist = wl_copy(wlist);
freehist(histlength - cp_maxhistlength);
histlength++;
return;
}
/* Get a copy of the wordlist associated with an event. Error if out
* of range.
*/
static wordlist *
getevent(int num)
{
struct histent *hi;
for (hi = histlist; hi; hi = hi->hi_next)
if (hi->hi_event == num)
break;
if (hi == NULL) {
fprintf(cp_err, "%d: event not found.\n", num);
return (NULL);
}
return (wl_copy(hi->hi_wlist));
}
/* Print out history between eventhi and eventlo.
* This doesn't remember quoting, so 'hodedo' prints as hodedo.
*/
void
cp_hprint(int eventhi, int eventlo, bool rev)
{
struct histent *hi;
if (rev) {
for (hi = histlist; hi->hi_next; hi = hi->hi_next)
;
for (; hi; hi = hi->hi_prev)
if ((hi->hi_event <= eventhi) &&
(hi->hi_event >= eventlo) &&
hi->hi_wlist) {
fprintf(cp_out, "%d\t", hi->hi_event);
wl_print(hi->hi_wlist, cp_out);
(void) putc('\n', cp_out);
}
} else {
for (hi = histlist; hi; hi = hi->hi_next)
if ((hi->hi_event <= eventhi) &&
(hi->hi_event >= eventlo) &&
hi->hi_wlist) {
fprintf(cp_out, "%d\t", hi->hi_event);
wl_print(hi->hi_wlist, cp_out);
(void) putc('\n', cp_out);
}
}
return;
}
/* This just gets rid of the first num entries on the history list, and
* decrements histlength.
*/
static void
freehist(int num)
{
struct histent *hi;
if (num < 1)
return;
histlength -= num;
hi = histlist;
while (num-- && histlist->hi_next)
histlist = histlist->hi_next;
if (histlist->hi_prev) {
histlist->hi_prev->hi_next = NULL;
histlist->hi_prev = NULL;
} else
{
fprintf(cp_err, "Internal error: history list mangled\n");
exit(0); /* Chris Inbody */
}
while (hi->hi_next) {
wl_free(hi->hi_wlist);
hi = hi->hi_next;
tfree(hi->hi_prev);
}
wl_free(hi->hi_wlist);
tfree(hi);
return;
}
/* Do a :s substitution. */
static char *
dohs(char *pat, char *str)
{
char schar, *s, *p, buf[BSIZE_SP];
int i = 0, plen;
bool ok = FALSE;
pat = copy(pat); /* Don't want to mangle anything. */
schar = *pat++;
s =strchr(pat, schar);
if (s == NULL) {
fprintf(cp_err, "Bad substitute.\n");
return (NULL);
}
*s++ = '\0';
p =strchr(s, schar);
if (p)
*p = '\0';
plen = strlen(pat) - 1;
for (i = 0; *str; str++) {
if ((*str == *pat) && prefix(pat, str) && (ok == FALSE)) {
for (p = s; *p; p++)
buf[i++] = *p;
str += plen;
ok = TRUE;
} else
buf[i++] = *str;
}
buf[i] = '\0';
if (ok)
return (copy(buf));
else
return (NULL);
}
/* The "history" command. history [-r] [number] */
void
com_history(wordlist *wl)
{
bool rev = FALSE;
if (wl && eq(wl->wl_word, "-r")) {
wl = wl->wl_next;
rev = TRUE;
}
if (wl == NULL)
cp_hprint(cp_event - 1, cp_event - histlength, rev);
else
cp_hprint(cp_event - 1, cp_event - 1 - atoi(wl->wl_word), rev);
return;
}

View File

@ -0,0 +1,16 @@
/*************
* Header file for history.c
* 1999 E. Rouat
************/
#ifndef _COM_HISTORY_H
#define _COM_HISTORY_H
wordlist * cp_histsubst(wordlist *wlist);
void cp_addhistent(int event, wordlist *wlist);
void cp_hprint(int eventhi, int eventlo, bool rev);
void com_history(wordlist *wl);
#endif

207
src/frontend/com_let.c Normal file
View File

@ -0,0 +1,207 @@
#include <stddef.h>
#include <dvec.h>
#include <ngspice.h>
#include <fteext.h>
#include <cpextern.h>
#include "com_let.h"
#include "com_display.h"
#include "completion.h"
void
com_let(wordlist *wl)
{
char *p, *q, *s;
int indices[MAXDIMS];
int numdims;
wordlist fake_wl;
int need_open;
int offset, length;
struct pnode *nn;
struct dvec *n, *t;
int i, cube;
int depth;
int newvec;
char *rhs;
fake_wl.wl_next = NULL;
if (!wl) {
com_display((wordlist *) NULL);
return;
}
p = wl_flatten(wl);
/* extract indices */
numdims = 0;
if ((rhs =strchr(p, '='))) {
*rhs++ = 0;
} else {
fprintf(cp_err, "Error: bad let syntax\n");
return;
}
if ((s =strchr(p, '['))) {
need_open = 0;
*s++ = 0;
while (!need_open || *s == '[') {
depth = 0;
if (need_open)
s++;
for (q = s; *q && (*q != ']' && (*q != ',' || depth > 0)); q++) {
switch (*q) {
case '[':
depth += 1;
break;
case ']':
depth -= 1;
break;
}
}
if (depth != 0 || !*q) {
printf("syntax error specifyingstrchr\n");
return;
}
if (*q == ']')
need_open = 1;
else
need_open = 0;
if (*q)
*q++ = 0;
for (s = q; *s && isspace(*s); s++)
;
}
}
/* vector name at p */
for (q = p + strlen(p) - 1; *q <= ' ' && p <= q; q--)
;
*++q = 0;
/* sanity check */
if (eq(p, "all") ||strchr(p, '@')) {
fprintf(cp_err, "Error: bad variable name %s\n", p);
return;
}
/* evaluate rhs */
fake_wl.wl_word = rhs;
nn = ft_getpnames(&fake_wl, TRUE);
if (nn == NULL) {
/* XXX error message */
tfree(p);
return;
}
t = ft_evaluate(nn);
if (!t) {
fprintf(cp_err, "Error: Can't evaluate %s\n", rhs);
tfree(p);
return;
}
if (t->v_link2)
fprintf(cp_err, "Warning: extra wildcard values ignored\n");
n = vec_get(p);
if (n) {
/* re-allocate? */
/* vec_free(n); */
newvec = 0;
} else {
if (numdims) {
fprintf(cp_err, "Can't assign into a subindex of a new vector\n");
tfree(p);
return;
}
/* create and assign a new vector */
n = alloc(struct dvec);
ZERO(n, struct dvec);
n->v_name = copy(p);
n->v_type = t->v_type;
n->v_flags = (t->v_flags | VF_PERMANENT);
n->v_length = t->v_length;
if (!t->v_numdims) {
n->v_numdims = 1;
n->v_dims[0] = n->v_length;
} else {
n->v_numdims = t->v_numdims;
for (i = 0; i < t->v_numdims; i++)
n->v_dims[i] = t->v_dims[i];
}
if (isreal(t))
n->v_realdata = (double *) tmalloc(n->v_length * sizeof(double));
else
n->v_compdata = (complex *) tmalloc(n->v_length * sizeof(complex));
newvec = 1;
vec_new(n);
}
/* fix-up dimensions */
if (n->v_numdims < 1) {
n->v_numdims = 1;
n->v_dims[0] = n->v_length;
}
/* Compare dimensions */
offset = 0;
length = n->v_length;
cube = 1;
for (i = n->v_numdims - 1; i >= numdims; i--)
cube *= n->v_dims[i];
for (i = numdims - 1; i >= 0; i--) {
offset += cube * indices[i];
if (i < n->v_numdims) {
cube *= n->v_dims[i];
length /= n->v_dims[i];
}
}
/* length is the size of the unit refered to */
/* cube ends up being the length */
if (length > t->v_length) {
fprintf(cp_err, "left-hand expression is too small (need %d)\n",
length * cube);
if (newvec)
n->v_flags &= ~VF_PERMANENT;
tfree(p);
return;
}
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;
} else if (isreal(t)) {
bcopy((char *) t->v_realdata, (char *) (n->v_realdata + offset),
length * sizeof (double));
} else {
bcopy((char *) t->v_compdata, (char *) (n->v_compdata + offset),
length * sizeof (complex));
}
n->v_minsignal = 0.0; /* How do these get reset ??? */
n->v_maxsignal = 0.0;
n->v_scale = t->v_scale;
if (newvec)
cp_addkword(CT_VECTOR, n->v_name);
/* XXXX Free t !?! */
tfree(p);
return;
}

8
src/frontend/com_let.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _COM_LET_H
#define _COM_LET_H
#include <wordlist.h>
void com_let(wordlist *wl);
#endif

117
src/frontend/com_option.c Normal file
View File

@ -0,0 +1,117 @@
#include <config.h>
#include "ngspice.h"
#include "cktdefs.h"
#include "ftedefs.h"
#include <bool.h>
#include "circuits.h"
#include <wordlist.h>
#include "variable.h"
/* The option command. Syntax is option [opt ...] [opt = val ...].
* Val may be a string, an int, a float, or a list of the
* form (elt1 elt2 ...). */
void
com_option(wordlist *wl)
{
struct variable *vars;
char *s;
CKTcircuit *circuit = NULL;
if (!ft_curckt) {
fprintf(cp_err, "Error: no circuit loaded\n");
return;
}
circuit = (CKTcircuit *)(ft_curckt->ci_ckt);
if (wl == NULL) {
printf("******************************\n");
printf("* Current simulation options *\n");
printf("******************************\n\n");
printf("Temperatures:\n");
printf("temp = %f\n",circuit->CKTtemp);
printf("tnom = %f\n",circuit->CKTnomTemp);
printf("\nIntegration method summary:\n");
switch (circuit->CKTintegrateMethod)
{
case TRAPEZOIDAL:
printf("Integration Method = TRAPEZOIDAL\n");
break;
case GEAR:
printf("Integration Method = GEAR\n");
break;
default:
printf("Unknown integration method\n");
}
printf("MaxOrder = %d\n", circuit->CKTmaxOrder);
printf("\nTolerances (absolute):\n");
printf("abstol (current) = %f\n", circuit->CKTabstol);
printf("chgtol (charge) = %f\n", circuit->CKTchgtol);
printf("volttol (voltage) = %f\n", circuit->CKTvoltTol);
printf("pivotabstol (pivot) = %f\n", circuit->CKTpivotAbsTol);
printf("\nTolerances (relative):\n");
printf("reltol (current) = %f\n", circuit->CKTreltol);
printf("pivotreltol (pivot) = %f\n", circuit->CKTpivotRelTol);
printf("\nTruncation error:\n");
printf("trtol = %f\n", circuit->CKTtrtol);
#ifdef NEWTRUNC
printf("ltereltol = %f\n", circuit->CKTlteReltol);
printf("lteabstol = %f\n", circuit->CKTlteAbstol);
#endif /* NEWTRUNC */
printf("\nConductances:\n");
printf("gmin (devices) = %f\n", circuit->CKTgmin);
printf("diaggmin (stepping) = %f\n", circuit->CKTdiagGmin);
printf("gshunt = %f\n", circuit->CKTgshunt);
printf("delmin = %f\n", circuit->CKTdelmin);
printf("\nDefault parameters for MOS devices\n");
printf("Default M: %f\n", circuit->CKTdefaultMosM);
printf("Default L: %f\n", circuit->CKTdefaultMosL);
printf("Default W: %f\n", circuit->CKTdefaultMosW);
printf("Default AD: %f\n", circuit->CKTdefaultMosAD);
printf("Default AS: %f\n", circuit->CKTdefaultMosAS);
return;
}
vars = cp_setparse(wl);
/* This is sort of a hassle... */
while (vars) {
switch (vars->va_type) {
case VT_BOOL:
s = (char *) &vars->va_bool;
break;
case VT_NUM:
s = (char *) &vars->va_num;
break;
case VT_REAL:
s = (char *) &vars->va_real;
break;
case VT_STRING:
s = vars->va_string;
break;
case VT_LIST:
s = (char *) vars->va_vlist;
break;
default:
s = (char *) NULL;
}
/* qui deve settare le opzioni di simulazione */
cp_vset(vars->va_name, vars->va_type, s);
vars = vars->va_next;
}
return;
}

View File

@ -0,0 +1,6 @@
#ifndef _COM_OPTION_H
#define _COM_OPTION_H
void com_option(wordlist *wl);
#endif

28
src/frontend/com_plot.c Normal file
View File

@ -0,0 +1,28 @@
#include <config.h>
#include <ngspice.h>
#include <bool.h>
#include <wordlist.h>
#include "plotting/plotit.h"
#include "com_plot.h"
/* plot name ... [xl[imit]] xlo xhi] [yl[imit ylo yhi] [vs xname] */
void
com_plot(wordlist *wl)
{
plotit(wl, (char *) NULL, (char *) NULL);
return;
}
#ifdef TCL_MODULE
void
com_bltplot(wordlist *wl)
{
plotit(wl, (char *) NULL, "blt");
return;
}
#endif

10
src/frontend/com_plot.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef _COM_PLOT_H
#define _COM_PLOT_H
void com_plot(wordlist *wl);
#include <config.h>
#ifdef TCL_MODULE
void com_bltplot(wordlist *wl);
#endif
#endif

24
src/frontend/com_rehash.c Normal file
View File

@ -0,0 +1,24 @@
#include <config.h>
#include <ngspice.h>
#include <wordlist.h>
#include <cpextern.h>
void
com_rehash(wordlist *wl)
{
char *s;
if (!cp_dounixcom) {
fprintf(cp_err, "Error: unixcom not set.\n");
return;
}
s = getenv("PATH");
if (s)
cp_rehash(s, TRUE);
else
fprintf(cp_err, "Error: no PATH in environment.\n");
return;
}

51
src/frontend/com_set.c Normal file
View File

@ -0,0 +1,51 @@
#include <config.h>
#include <ngspice.h>
#include <bool.h>
#include <wordlist.h>
#include "variable.h"
/* The set command. Syntax is set [opt ...] [opt = val ...]. Val may
* be a string, an int, a float, or a list of the form (elt1 elt2
* ...). */
void
com_set(wordlist *wl)
{
struct variable *vars;
char *s;
if (wl == NULL) {
cp_vprint();
return;
}
vars = cp_setparse(wl);
/* This is sort of a hassle... */
while (vars) {
switch (vars->va_type) {
case VT_BOOL:
s = (char *) &vars->va_bool;
break;
case VT_NUM:
s = (char *) &vars->va_num;
break;
case VT_REAL:
s = (char *) &vars->va_real;
break;
case VT_STRING:
s = vars->va_string;
break;
case VT_LIST:
s = (char *) vars->va_vlist;
break;
default:
s = (char *) NULL;
}
cp_vset(vars->va_name, vars->va_type, s);
vars = vars->va_next;
}
return;
}

6
src/frontend/com_set.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _COM_SET_H
#define _COM_SET_H
void com_set(wordlist *wl);
#endif

View File

@ -0,0 +1,37 @@
#include <ngspice.h>
#include <bool.h>
#include <dvec.h>
#include "com_setscale.h"
#include "quote.h"
#include "streams.h"
#include "vectors.h"
#include "plotting/plotting.h"
#include "plotting/pvec.h"
/* Set the default scale to the named vector. If no vector named,
* find and print the default scale. */
void
com_setscale(wordlist *wl)
{
struct dvec *d;
char *s;
if (plot_cur) {
if (wl) {
s = cp_unquote(wl->wl_word);
d = vec_get(s);
if(s) tfree(s);/*DG to avoid the cp_unquote memory leak */
if (d == NULL)
fprintf(cp_err, "Error: no such vector as %s.\n",
wl->wl_word);
else
plot_cur->pl_scale = d;
} else if (plot_cur->pl_scale) {
pvec(plot_cur->pl_scale);
}
} else {
fprintf(cp_err, "Error: no current plot.\n");
}
}

View File

@ -0,0 +1,9 @@
#ifndef _COM_SETSCALE_H
#define _COM_SETSCALE_H
#include <wordlist.h>
void com_setscale(wordlist *wl);
#endif

58
src/frontend/com_shell.c Normal file
View File

@ -0,0 +1,58 @@
#include <config.h>
#include <ngspice.h>
#include <wordlist.h>
#include <cpextern.h>
/* Fork a shell. */
void
com_shell(wordlist *wl)
{
char *com, *shell = NULL;
shell = getenv("SHELL");
if (shell == NULL)
shell = "/bin/csh";
cp_ccon(FALSE);
#ifdef HAVE_VFORK_H
/* XXX Needs to switch process groups. Also, worry about suspend */
/* Only bother for efficiency */
pid = vfork();
if (pid == 0) {
fixdescriptors();
if (wl == NULL) {
execl(shell, shell, 0);
_exit(99);
} else {
com = wl_flatten(wl);
execl("/bin/sh", "sh", "-c", com, 0);
}
} else {
/* XXX Better have all these signals */
svint = signal(SIGINT, SIG_DFL);
svquit = signal(SIGQUIT, SIG_DFL);
svtstp = signal(SIGTSTP, SIG_DFL);
/* XXX Sig on proc group */
do {
r = wait((union wait *) NULL);
} while ((r != pid) && pid != -1);
signal(SIGINT, (SIGNAL_FUNCTION) svint);
signal(SIGQUIT, (SIGNAL_FUNCTION) svquit);
signal(SIGTSTP, (SIGNAL_FUNCTION) svtstp);
}
#else
/* Easier to forget about changing the io descriptors. */
if (wl) {
com = wl_flatten(wl);
system(com);
} else
system(shell);
#endif
return;
}

46
src/frontend/com_shift.c Normal file
View File

@ -0,0 +1,46 @@
#include <config.h>
#include <ngspice.h>
#include <bool.h>
#include <wordlist.h>
#include "variable.h"
#include "streams.h"
/* Shift a list variable, by default argv, one to the left (or more if
* a second argument is given. */
void
com_shift(wordlist *wl)
{
struct variable *v, *vv;
char *n = "argv";
int num = 1;
if (wl) {
n = wl->wl_word;
wl = wl->wl_next;
}
if (wl)
num = scannum(wl->wl_word);
for (v = variables; v; v = v->va_next)
if (eq(v->va_name, n))
break;
if (!v) {
fprintf(cp_err, "Error: %s: no such variable\n", n);
return;
}
if (v->va_type != VT_LIST) {
fprintf(cp_err, "Error: %s not of type list\n", n);
return;
}
for (vv = v->va_vlist; vv && (num > 0); num--)
vv = vv->va_next;
if (num) {
fprintf(cp_err, "Error: variable %s not long enough\n", n);
return;
}
v->va_vlist = vv;
return;
}

31
src/frontend/com_state.c Normal file
View File

@ -0,0 +1,31 @@
#include <config.h>
#include <ngspice.h>
#include <bool.h>
#include <wordlist.h>
#include <ftedefs.h>
#include <inpdefs.h>
#include "circuits.h"
#include "com_state.h"
#include "streams.h"
#include "plotting/plotting.h"
void
com_state(wordlist *wl)
{
if (!ft_curckt) {
fprintf(cp_err, "Error: no circuit loaded.\n");
return;
}
fprintf(cp_out, "Current circuit: %s\n", ft_curckt->ci_name);
if (!ft_curckt->ci_inprogress) {
fprintf(cp_out, "No run in progress.\n");
return;
}
fprintf(cp_out, "Type of run: %s\n", plot_cur->pl_name);
fprintf(cp_out, "Number of points so far: %d\n",
plot_cur->pl_scale->v_length);
fprintf(cp_out, "(That's all this command does so far)\n");
return;
}

7
src/frontend/com_state.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef _COM_STATE_H
#define _COM_STATE_H
void com_state(wordlist *wl);
#endif

28
src/frontend/com_strcmp.c Normal file
View File

@ -0,0 +1,28 @@
#include <config.h>
#include <ngspice.h>
#include <bool.h>
#include <wordlist.h>
#include "com_strcmp.h"
#include "quote.h"
#include "variable.h"
/* This is a truly evil thing */
void
com_strcmp(wordlist *wl)
{
char *var, *s1, *s2;
int i;
var = wl->wl_word;
s1 = cp_unquote(wl->wl_next->wl_word);
s2 = cp_unquote(wl->wl_next->wl_next->wl_word);
i = strcmp(s1, s2);
tfree(s1);/*DG cp_unquote memory leak*/
tfree(s2);
cp_vset(var, VT_NUM, (char *) &i);
return;
}

View File

@ -0,0 +1,7 @@
#ifndef _COM_STRCMP_H
#define _COM_STRCMP_H
void com_strcmp(wordlist *wl);
#endif

30
src/frontend/com_unset.c Normal file
View File

@ -0,0 +1,30 @@
#include <config.h>
#include <ngspice.h>
#include <macros.h>
#include <bool.h>
#include <wordlist.h>
#include "variable.h"
void
com_unset(wordlist *wl)
{
char *name;
struct variable *var, *nv;
if (eq(wl->wl_word, "*")) {
for (var = variables; var; var = nv) {
nv = var->va_next;
cp_remvar(var->va_name);
}
wl = wl->wl_next;
}
while (wl != NULL) {
name = wl->wl_word;
cp_remvar(name);
wl = wl->wl_next;
}
return;
}

41
src/frontend/com_xgraph.c Normal file
View File

@ -0,0 +1,41 @@
#include <stddef.h>
#include <ngspice.h>
#include <bool.h>
#include <wordlist.h>
#include "plotting/plotit.h"
#include "com_xgraph.h"
/* xgraph file plotargs */
void
com_xgraph(wordlist *wl)
{
char *fname;
bool tempf = FALSE;
if (wl) {
fname = wl->wl_word;
wl = wl->wl_next;
}
if (!wl) {
return;
}
if (cieq(fname, "temp") || cieq(fname, "tmp")) {
fname = smktemp("xg");
tempf = TRUE;
}
(void) plotit(wl, fname, "xgraph");
#if 0
/* Leave temp file sitting around so xgraph can grab it from
background. */
if (tempf)
(void) unlink(fname);
#endif
return;
}

View File

@ -0,0 +1,6 @@
#ifndef _COM_XGRAPH_H
#define _COM_XGRAPH_H
void com_xgraph(wordlist *wl);
#endif

820
src/frontend/commands.c Normal file
View File

@ -0,0 +1,820 @@
/* NG-SPICE -- An electrical circuit simulator
*
* Copyright (c) 1990 University of California
* Copyright (c) 2000 Arno W. Peters
*
* Permission to use, copy, modify, and distribute this software and
* its documentation without fee, and without a written agreement is
* hereby granted, provided that the above copyright notice, this
* paragraph and the following three paragraphs appear in all copies.
*
* This software program and documentation are copyrighted by their
* authors. The software program and documentation are supplied "as
* is", without any accompanying services from the authors. The
* authors do not warrant that the operation of the program will be
* uninterrupted or error-free. The end-user understands that the
* program was developed for research purposes and is advised not to
* rely exclusively on the program for any reason.
*
* IN NO EVENT SHALL THE AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT,
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
* LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
* DOCUMENTATION, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. THE AUTHORS SPECIFICALLY DISCLAIMS ANY
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
* SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE AUTHORS
* HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS. */
/* Table of available commands. Note that they're sorted so that the
* commands that appear in the spiceinit file are at the top. */
#include <ngspice.h>
#include <ftedefs.h>
#include <cpdefs.h>
#include "ftehelp.h"
#include "commands.h"
#include "com_ahelp.h"
#include "com_asciiplot.h"
#include "com_compose.h"
#include "com_display.h"
#include "com_hardcopy.h"
#include "com_help.h"
#include "com_let.h"
#include "com_plot.h"
#include "com_setscale.h"
#include "com_xgraph.h"
#include "com_state.h"
#include "fourier.h"
#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. */
/* Bool fields: stringargs, spiceonly, major */
struct comm spcp_coms[] = {
{ "let", com_let, FALSE, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
arg_let,
"varname = expr : Assign vector variables." } ,
{ "reshape", com_reshape, FALSE, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
arg_let,
"vector ... [ shape ] : change the dimensions of a vector." } ,
{ "define", com_define, FALSE, FALSE, TRUE,
{ 010000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[[func (args)] stuff] : Define a user-definable function." } ,
{ "set", com_set, FALSE, FALSE, TRUE,
{ 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS,
arg_set,
"[option] [option = value] ... : Set a variable." } ,
#ifdef EXPERIMENTAL_CODE
/* PN support for altering options in interactive mode */
{ "option", com_option, FALSE, TRUE, TRUE,
{ 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,
{ 02, 04, 04, 04 }, E_ADVANCED, 0, LOTS,
(void (*)()) NULL,
"[[word] alias] : Define an alias." } ,
{ "deftype", com_dftype, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 3, LOTS,
(void (*)()) NULL,
"spec name pat ... : Redefine vector and plot types.\n" } ,
{ "plot", com_plot, FALSE, FALSE, TRUE,
{ 041000, 041000, 041000, 041000 }, E_BEGINNING | E_HASPLOTS, 1, LOTS,
arg_plot,
"expr ... [vs expr] [xl xlo xhi] [yl ylo yhi] : Plot things." },
#ifdef TCL_MODULE
{ "bltplot", com_bltplot, FALSE, FALSE, TRUE,
{ 041000, 041000, 041000, 041000 }, E_BEGINNING | E_HASPLOTS, 1, LOTS,
arg_plot,
"expr ... [vs expr] [xl xlo xhi] [yl ylo yhi] : Plot things." },
#endif
{ "display", com_display, FALSE, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 0, LOTS,
arg_display,
": Display vector status." } ,
{ "destroy", com_destroy, FALSE, FALSE, FALSE,
{ 0400, 0400, 0400, 0400 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[plotname] ... : Throw away all the data in the plot." } ,
{ "setplot", com_splot, FALSE, FALSE, TRUE,
{ 0400, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[plotname] : Change the current working plot." } ,
{ "setcirc", com_scirc, FALSE, TRUE, FALSE,
{ 04, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[circuit name] : Change the current circuit." } ,
{ "setscale", com_setscale, FALSE, FALSE, FALSE,
{ 040000, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[vecname] : Change default scale of current working plot." } ,
{ "transpose", com_transpose, FALSE, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"varname ... : Perform matrix transposition on multi-D vectors." } ,
{ "xgraph", com_xgraph, FALSE, FALSE, TRUE,
{ 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"file plotargs : Send plot to Xgraph-11." } ,
{ "hardcopy", com_hardcopy, FALSE, FALSE, TRUE,
{ 1, 041000, 041000, 041000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"file plotargs : Produce hardcopy plots." } ,
{ "asciiplot", com_asciiplot, FALSE, FALSE, TRUE,
{ 041000, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"plotargs : Produce ascii plots." } ,
{ "write", com_write, FALSE, FALSE, TRUE,
{ 1, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"file expr ... : Write data to a file." } ,
{ "compose", com_compose, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 2, LOTS,
(void (*)()) NULL,
"var parm=val ... : Compose a vector." } ,
{ "unlet", com_unlet, FALSE, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"varname ... : Undefine vectors." } ,
{ "print", com_print, FALSE, FALSE, TRUE,
{ 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,
"file ... : Load in data." } ,
{ "cross", com_cross, FALSE, FALSE, TRUE,
{ 040000, 0, 040000, 040000 }, E_DEFHMASK, 2, LOTS,
(void (*)()) NULL,
"vecname number [ vector ... ] : Make a vector in a strange way." } ,
{ "undefine", com_undefine, FALSE, FALSE, FALSE,
{ 010000, 010000, 010000, 010000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[func ...] : Undefine a user-definable function." } ,
{ "op", com_op, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.op line args] : Determine the operating point of the circuit." } ,
{ "tf", com_tf, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.tran line args] : Do a transient analysis." } ,
{ "tran", com_tran, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.tran line args] : Do a transient analysis." } ,
{ "ac", com_ac, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.ac line args] : Do an ac analysis." } ,
{ "dc", com_dc, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.dc line args] : Do a dc analysis." } ,
{ "pz", com_pz, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.pz line args] : Do a pole / zero analysis." } ,
{ "sens", com_sens, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.sens line args] : Do a sensitivity analysis." } ,
{ "disto", com_disto, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.disto line args] : Do an distortion analysis." } ,
{ "noise", com_noise, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.noise line args] : Do a noise analysis." } ,
{ "listing", com_listing, FALSE, TRUE, TRUE,
{ 0100, 0100, 0100, 0100 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[logical] [physical] [deck] : Print the current circuit." } ,
{ "edit", com_edit, FALSE, TRUE, TRUE,
{ 1, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[filename] : Edit a spice deck and then load it in." } ,
{ "dump", com_dump, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Print a dump of the current circuit." } ,
{ "fourier", com_fourier, FALSE, FALSE, TRUE,
{ 0, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"fund_freq vector ... : Do a fourier analysis of some data." } ,
{ "spec", com_spec, FALSE, FALSE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 4, LOTS,
(void (*)()) NULL,
"start_freq stop_freq step_freq vector ... : Create a frequency domain plot." } ,
{ "show", com_show, FALSE, TRUE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"devices ... : parameters ... : Print out device summary." } ,
{ "showmod", com_showmod, FALSE, TRUE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"models ... : parameters ... : Print out model summary." } ,
{ "alter", com_alter, FALSE, TRUE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"devspecs : parmname value : Alter device parameters." } ,
{ "altermod", com_altermod, FALSE, TRUE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"devspecs : parmname value : Alter model parameters." } ,
{ "resume", com_resume, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Continue after a stop." } ,
{ "state", com_state, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"(unimplemented) : Print the state of the circuit." },
{ "stop", com_stop, FALSE, TRUE, FALSE,
{ 04200, 04200, 04200, 04200 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[stop args] : Set a breakpoint." } ,
{ "trace", com_trce, FALSE, TRUE, FALSE,
{ 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[all] [node ...] : Trace a node." } ,
{ "save", com_save, FALSE, TRUE, FALSE,
{ 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[all] [node ...] : Save a spice output." } ,
{ "iplot", com_iplot, FALSE, TRUE, TRUE,
{ 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[all] [node ...] : Incrementally plot a node." } ,
{ "status", com_sttus, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Print the current breakpoints and traces." } ,
{ "delete", com_delete, FALSE, TRUE, FALSE,
{ 020, 020, 020, 020 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[all] [break number ...] : Delete breakpoints and traces." } ,
{ "step", com_step, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[number] : Iterate number times, or one." } ,
{ "reset", com_rset, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Terminate a simulation after a breakpoint (formerly 'end')." } ,
{ "run", com_run, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[rawfile] : Run the simulation as specified in the input file." } ,
{ "aspice", com_aspice, FALSE, FALSE, FALSE,
{ 1, 1, 1, 1 }, E_DEFHMASK, 1, 2,
(void (*)()) NULL,
"file [outfile] : Run a spice job asynchronously." } ,
{ "jobs", com_jobs, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Report on asynchronous spice jobs." } ,
{ "rspice", com_rspice, FALSE, FALSE, FALSE,
{ 1, 1, 1, 1 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[input file] : Run a spice job remotely." } ,
{ "bug", com_bug, FALSE, FALSE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Report a %s bug." } ,
{ "where", com_where, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Print last non-converging node or device" } ,
{ "newhelp", com_ahelp, FALSE, FALSE, TRUE,
{ 010, 010, 010, 010 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[command name] ... : help." },
{ "tutorial", com_ghelp, FALSE, FALSE, TRUE,
{ 023010, 023010, 023010, 023010 }, E_BEGINNING, 0, LOTS,
(void (*)()) NULL,
"[subject] ... : Hierarchical documentation browser." } ,
{ "help", com_ghelp, FALSE, FALSE, TRUE,
{ 023010, 023010, 023010, 023010 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[subject] ... : Hierarchical documentation browser." } ,
{ "oldhelp", com_help, FALSE, FALSE, TRUE,
{ 010, 010, 010, 010 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[command name] ... : Print help." } ,
{ "quit", com_quit, FALSE, FALSE, TRUE,
{ 0, 0, 0, 0 }, E_BEGINNING, 0, 0,
(void (*)()) NULL,
": Quit %s." } ,
{ "source", com_source, FALSE, FALSE, TRUE,
{ 1, 1, 1, 1 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"file : Source a %s file." } ,
{ "shift", com_shift, FALSE, FALSE, FALSE,
{ 020000, 0, 0, 0 }, E_DEFHMASK, 0, 2,
(void (*)()) NULL,
"[var] [number] : Shift argv or the named list var to the left." } ,
{ "unset", com_unset, FALSE, FALSE, FALSE,
{ 020000, 020000, 020000, 020000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"varname ... : Unset a variable." } ,
{ "unalias", com_unalias, FALSE, FALSE, FALSE,
{ 02, 02, 02, 02 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"word ... : Undefine an alias." } ,
{ "history", com_history, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 2,
(void (*)()) NULL,
"[-r] [number] : Print command history." } ,
{ "echo", com_echo, FALSE, FALSE, FALSE,
{ 1, 1, 1, 1 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[stuff ...] : Print stuff." } ,
{ "shell", com_shell, FALSE, FALSE, TRUE,
{ 1, 1, 1, 1 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[args] : Fork a shell, or execute the command." } ,
{ "rusage", com_rusage, FALSE, FALSE, FALSE,
{ 02000, 02000, 02000, 02000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[resource ...] : Print current resource usage." } ,
{ "cd", com_chdir, FALSE, FALSE, FALSE,
{ 1, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[directory] : Change working directory." } ,
{ "version", com_version, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[number] : Print the version number." } ,
{ "diff", com_diff, FALSE, FALSE, FALSE,
{ 0400, 0400, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"plotname plotname [vec ...] : 'diff' two plots." } ,
{ "rehash", com_rehash, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Rebuild the unix command database." } ,
{ "while", NULL, FALSE, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"condition : Execute while the condition is TRUE." } ,
{ "repeat", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0}, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[number] : Repeat number times, or forever." } ,
{ "dowhile", NULL, FALSE, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"condition : Execute while the condition is TRUE." } ,
{ "foreach", NULL, FALSE, FALSE, FALSE,
{ 0, 040000, 040000, 040000 }, E_DEFHMASK, 2, LOTS,
(void (*)()) NULL,
"variable value ... : Do once for each value." } ,
{ "if", NULL, FALSE, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"condition : Execute if the condition is TRUE." } ,
{ "else", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Goes with if." } ,
{ "end", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": End a block." } ,
{ "break", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Break out of a block." } ,
{ "continue", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Continue a loop." } ,
{ "label", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 1, 1,
(void (*)()) NULL,
"word : Create someplace to go to." } ,
{ "goto", NULL, FALSE, FALSE, FALSE,
{ 0100000, 0, 0, 0 }, E_DEFHMASK, 1, 1,
(void (*)()) NULL,
"word : Go to a label." } ,
{ "cdump", com_cdump, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Dump the current control structures." } ,
{ "settype", com_stype, FALSE, FALSE, FALSE,
{ 0200000, 040000, 040000, 040000 }, E_DEFHMASK, 2, LOTS,
(void (*)()) NULL,
"type vec ... : Change the type of a vector." } ,
{ "strcmp", com_strcmp, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 3, 3,
(void (*)()) NULL,
"varname s1 s2 : Set $varname to strcmp(s1, s2)." } ,
{ "linearize", com_linearize, FALSE, TRUE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
" [ vec ... ] : Convert plot into one with linear scale." } ,
{ 0, NULL, FALSE, FALSE, FALSE, { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
NULL }
};
/* Bool fields: stringargs, spiceonly, major */
struct comm nutcp_coms[] = {
{ "let", com_let, FALSE, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
arg_let,
"varname = expr : Assign vector variables." } ,
{ "reshape", com_reshape, FALSE, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
arg_let,
"vector ... [ shape ] : change the dimensions of a vector." } ,
{ "define", com_define, FALSE, FALSE, TRUE,
{ 010000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[[func (args)] stuff] : Define a user-definable function." } ,
{ "set", com_set, FALSE, FALSE, TRUE,
{ 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS,
arg_set,
"[option] [option = value] ... : Set a variable." } ,
#ifdef EXPERIMENTAL_CODE
/* PN support for altering options in interactive mode */
{ "option", com_option, FALSE, TRUE, TRUE,
{ 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS,
arg_set,
"[option] [option = value] ... : Set a simulator option." } ,
#endif
{ "alias", com_alias, FALSE, FALSE, FALSE,
{ 02, 04, 04, 04 }, E_ADVANCED, 0, LOTS,
(void (*)()) NULL,
"[[word] alias] : Define an alias." } ,
{ "deftype", com_dftype, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 3, LOTS,
(void (*)()) NULL,
"spec name pat ... : Redefine vector and plot types.\n" } ,
{ "plot", com_plot, FALSE, FALSE, TRUE,
{ 041000, 041000, 041000, 041000 }, E_BEGINNING | E_HASPLOTS, 1, LOTS,
arg_plot,
"expr ... [vs expr] [xl xlo xhi] [yl ylo yhi] : Plot things." },
{ "display", com_display, FALSE, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 0, LOTS,
arg_display,
": Display vector status." } ,
{ "destroy", com_destroy, FALSE, FALSE, FALSE,
{ 0400, 0400, 0400, 0400 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[plotname] ... : Throw away all the data in the plot." } ,
{ "setplot", com_splot, FALSE, FALSE, TRUE,
{ 0400, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[plotname] : Change the current working plot." } ,
{ "setcirc", NULL, FALSE, TRUE, FALSE,
{ 04, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[circuit name] : Change the current circuit." } ,
{ "setscale", com_setscale, FALSE, FALSE, FALSE,
{ 040000, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[vecname] : Change default scale of current working plot." } ,
{ "transpose", com_transpose, FALSE, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"varname ... : Perform matrix transposition on multi-D vectors." } ,
{ "xgraph", com_xgraph, FALSE, FALSE, TRUE,
{ 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"file plotargs : Send plot to Xgraph-11." } ,
{ "hardcopy", com_hardcopy, FALSE, FALSE, TRUE,
{ 1, 041000, 041000, 041000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"file plotargs : Produce hardcopy plots." } ,
{ "asciiplot", com_asciiplot, FALSE, FALSE, TRUE,
{ 041000, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"plotargs : Produce ascii plots." } ,
{ "write", com_write, FALSE, FALSE, TRUE,
{ 1, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"file expr ... : Write data to a file." } ,
{ "compose", com_compose, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 2, LOTS,
(void (*)()) NULL,
"var parm=val ... : Compose a vector." } ,
{ "unlet", com_unlet, FALSE, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"varname ... : Undefine vectors." } ,
{ "print", com_print, FALSE, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
arg_print,
"[col] expr ... : Print vector values." } ,
{ "load", com_load, FALSE, FALSE, TRUE,
{ 1, 1, 1, 1 }, E_BEGINNING | E_NOPLOTS, 1, LOTS,
arg_load,
"file ... : Load in data." } ,
{ "cross", com_cross, FALSE, FALSE, TRUE,
{ 040000, 0, 040000, 040000 }, E_DEFHMASK, 2, LOTS,
(void (*)()) NULL,
"vecname number [ vector ... ] : Make a vector in a strange way." } ,
{ "undefine", com_undefine, FALSE, FALSE, FALSE,
{ 010000, 010000, 010000, 010000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[func ...] : Undefine a user-definable function." } ,
{ "op", NULL, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.op line args] : Determine the operating point of the circuit." } ,
{ "tran", NULL, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.tran line args] : Do a transient analysis." } ,
{ "ac", NULL, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.ac line args] : Do an ac analysis." } ,
{ "dc", NULL, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.dc line args] : Do a dc analysis." } ,
{ "pz", NULL, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.pz line args] : Do a pole / zero analysis." } ,
{ "sens", NULL, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.ac line args] : Do a sensitivity analysis." } ,
{ "disto", NULL, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.disto line args] : Do an distortion analysis." } ,
{ "noise", NULL, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[.noise line args] : Do a noise analysis." } ,
{ "listing", NULL, FALSE, TRUE, TRUE,
{ 0100, 0100, 0100, 0100 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[logical] [physical] [deck] : Print the current circuit." } ,
{ "edit", NULL, FALSE, TRUE, TRUE,
{ 1, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[filename] : Edit a spice deck and then load it in." } ,
{ "dump", NULL, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Print a dump of the current circuit." } ,
{ "fourier", com_fourier, FALSE, FALSE, TRUE,
{ 0, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"fund_freq vector ... : Do a fourier analysis of some data." } ,
{ "show", NULL, FALSE, TRUE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"devspecs ... : parmspecs ... : Print out device parameters." } ,
{ "alter", NULL, FALSE, TRUE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 3, LOTS,
(void (*)()) NULL,
"devspecs : parmname value : Alter device parameters." } ,
{ "altermod", NULL, FALSE, TRUE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 3, LOTS,
(void (*)()) NULL,
"devspecs : parmname value : Alter model parameters." } ,
{ "resume", NULL, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Continue after a stop." } ,
{ "state", NULL, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"(unimplemented) : Print the state of the circuit." },
{ "stop", NULL, FALSE, TRUE, FALSE,
{ 04200, 04200, 04200, 04200 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[stop args] : Set a breakpoint." } ,
{ "trace", NULL, FALSE, TRUE, FALSE,
{ 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[all] [node ...] : Trace a node." } ,
{ "save", NULL, FALSE, TRUE, FALSE,
{ 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[all] [node ...] : Save a spice output." } ,
{ "iplot", NULL, FALSE, TRUE, TRUE,
{ 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[all] [node ...] : Incrementally plot a node." } ,
{ "status", NULL, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Print the current breakpoints and traces." } ,
{ "delete", NULL, FALSE, TRUE, FALSE,
{ 020, 020, 020, 020 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[all] [break number ...] : Delete breakpoints and traces." } ,
{ "step", NULL, FALSE, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[number] : Iterate number times, or one." } ,
{ "reset", NULL, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Terminate a simulation after a breakpoint (formerly 'end')." } ,
{ "run", NULL, FALSE, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[rawfile] : Run the simulation as specified in the input file." } ,
{ "bug", com_bug, FALSE, FALSE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Report a %s bug." } ,
{ "newhelp", com_ahelp, FALSE, FALSE, TRUE,
{ 010, 010, 010, 010 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[command name] ... : help." },
{ "tutorial", com_ghelp, FALSE, FALSE, TRUE,
{ 023010, 023010, 023010, 023010 }, E_BEGINNING, 0, LOTS,
(void (*)()) NULL,
"[subject] ... : Hierarchical documentation browser." } ,
{ "help", com_ghelp, FALSE, FALSE, TRUE,
{ 023010, 023010, 023010, 023010 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[subject] ... : Hierarchical documentation browser." } ,
{ "oldhelp", com_help, FALSE, FALSE, TRUE,
{ 010, 010, 010, 010 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[command name] ... : Print help." } ,
{ "quit", com_quit, FALSE, FALSE, TRUE,
{ 0, 0, 0, 0 }, E_BEGINNING, 0, 0,
(void (*)()) NULL,
": Quit %s." } ,
{ "source", nutcom_source, FALSE, FALSE, TRUE,
{ 1, 1, 1, 1 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"file : Source a %s file." } ,
{ "shift", com_shift, FALSE, FALSE, FALSE,
{ 020000, 0, 0, 0 }, E_DEFHMASK, 0, 2,
(void (*)()) NULL,
"[var] [number] : Shift argv or the named list var to the left." } ,
{ "unset", com_unset, FALSE, FALSE, FALSE,
{ 020000, 020000, 020000, 020000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"varname ... : Unset a variable." } ,
{ "unalias", com_unalias, FALSE, FALSE, FALSE,
{ 02, 02, 02, 02 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"word ... : Undefine an alias." } ,
{ "history", com_history, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 2,
(void (*)()) NULL,
"[-r] [number] : Print command history." } ,
{ "echo", com_echo, FALSE, FALSE, FALSE,
{ 1, 1, 1, 1 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[stuff ...] : Print stuff." } ,
{ "shell", com_shell, FALSE, FALSE, TRUE,
{ 1, 1, 1, 1 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[args] : Fork a shell, or execute the command." } ,
{ "rusage", com_rusage, FALSE, FALSE, FALSE,
{ 02000, 02000, 02000, 02000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[resource ...] : Print current resource usage." } ,
{ "cd", com_chdir, FALSE, FALSE, FALSE,
{ 1, 0, 0, 0 }, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[directory] : Change working directory." } ,
{ "version", com_version, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"[number] : Print the version number." } ,
{ "diff", com_diff, FALSE, FALSE, FALSE,
{ 0400, 0400, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
"plotname plotname [vec ...] : 'diff' two plots." } ,
{ "rehash", com_rehash, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Rebuild the unix command database." } ,
{ "while", NULL, FALSE, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"condition : Execute while the condition is TRUE." } ,
{ "repeat", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0}, E_DEFHMASK, 0, 1,
(void (*)()) NULL,
"[number] : Repeat number times, or forever." } ,
{ "dowhile", NULL, FALSE, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"condition : Execute while the condition is TRUE." } ,
{ "foreach", NULL, FALSE, FALSE, FALSE,
{ 0, 040000, 040000, 040000 }, E_DEFHMASK, 2, LOTS,
(void (*)()) NULL,
"variable value ... : Do once for each value." } ,
{ "if", NULL, FALSE, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"condition : Execute if the condition is TRUE." } ,
{ "else", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Goes with if." } ,
{ "end", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": End a block." } ,
{ "break", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Break out of a block." } ,
{ "continue", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Continue a loop." } ,
{ "label", NULL, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 1, 1,
(void (*)()) NULL,
"word : Create someplace to go to." } ,
{ "goto", NULL, FALSE, FALSE, FALSE,
{ 0100000, 0, 0, 0 }, E_DEFHMASK, 1, 1,
(void (*)()) NULL,
"word : Go to a label." } ,
{ "cdump", com_cdump, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
(void (*)()) NULL,
": Dump the current control structures." } ,
{ "settype", com_stype, FALSE, FALSE, FALSE,
{ 0200000, 040000, 040000, 040000 }, E_DEFHMASK, 2, LOTS,
(void (*)()) NULL,
"type vec ... : Change the type of a vector." } ,
{ "strcmp", com_strcmp, FALSE, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 3, 3,
(void (*)()) NULL,
"varname s1 s2 : Set $varname to strcmp(s1, s2)." } ,
{ "linearize", NULL, FALSE, TRUE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
" [ vec ... ] : Convert plot into one with linear scale." } ,
{ 0, NULL, FALSE, FALSE, FALSE, { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
NULL }
} ;

8
src/frontend/commands.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _COMMANDS_H
#define _COMMANDS_H
extern struct comm spcp_coms[];
extern struct comm nutcp_coms[];
#endif

25
src/frontend/completion.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef _COMPLETION_H
#define _COMPLETION_H
/* The types for command completion keywords. Note that these
* constants are built into cmdtab.c, so DON'T change them unless you
* want to change all of the bitmasks in cp_coms. Note that this is
* spice- and nutmeg- dependent. */
#define CT_FILENAME 0
#define CT_CKTNAMES 2
#define CT_COMMANDS 3
#define CT_DBNUMS 4
#define CT_DEVNAMES 5
#define CT_LISTINGARGS 6
#define CT_NODENAMES 7
#define CT_PLOT 8
#define CT_PLOTKEYWORDS 9
#define CT_RUSEARGS 10
#define CT_STOPARGS 11
#define CT_UDFUNCS 12
#define CT_VARIABLES 13
#define CT_VECTOR 14
#define CT_TYPENAMES 16
#endif

801
src/frontend/control.c Normal file
View File

@ -0,0 +1,801 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/* The front-end command loop. */
#include <ngspice.h>
#include <cpdefs.h>
#include "control.h"
#include "com_cdump.h"
#include "variable.h"
#include "fteext.h"
/* Return values from doblock(). I am assuming that nobody will use
* these characters in a string. */
#define NORMAL '\001'
#define BROKEN '\002'
#define CONTINUED '\003'
#define NORMAL_STR "\001"
#define BROKEN_STR "\002"
#define CONTINUED_STR "\003"
/* Are we waiting for a command? This lets signal handling be
* more clever. */
bool cp_cwait = FALSE;
char *cp_csep = ";";
bool cp_dounixcom = FALSE;
/* We have to keep the control structures in a stack, so that when we
* do a 'source', we can push a fresh set onto the top... Actually
* there have to be two stacks -- one for the pointer to the list of
* control structs, and one for the 'current command' pointer... */
struct control *control[CONTROLSTACKSIZE];
struct control *cend[CONTROLSTACKSIZE];
int stackp = 0;
/* If there is an argument, give this to cshpar to use instead of
* stdin. In a few places, we call cp_evloop again if it returns 1 and
* exit (or close a file) if it returns 0... Because of the way
* sources are done, we can't allow the control structures to get
* blown away every time we return -- probably every time we type
* source at the keyboard and every time a source returns to keyboard
* input is ok though -- use ft_controlreset. */
static char *noredirect[] = { "stop", NULL } ; /* Only one?? */
static struct control *
findlabel(char *s, struct control *ct)
{
while (ct) {
if ((ct->co_type == CO_LABEL) && eq(s, ct->co_text->wl_word))
break;
ct = ct->co_next;
}
return (ct);
}
/* This is also in cshpar.c ... */
static void
pwlist(wordlist *wlist, char *name)
{
wordlist *wl;
if (!cp_debug)
return;
fprintf(cp_err, "%s : [ ", name);
for (wl = wlist; wl; wl = wl->wl_next)
fprintf(cp_err, "%s ", wl->wl_word);
fprintf(cp_err, "]\n");
return;
}
/* Note that we only do io redirection when we get to here - we also
* postpone some other things until now. */
static void
docommand(wordlist *wlist)
{
char *r, *s, *t;
char *lcom;
int nargs;
int i;
struct comm *command;
wordlist *wl, *nextc, *ee, *rwlist;
if (cp_debug) {
printf("docommand ");
wl_print(wlist, stdout);
putc('\n', stdout);
}
/* Do all the things that used to be done by cshpar when the line
* was read... */
wlist = cp_variablesubst(wlist);
pwlist(wlist, "After variable substitution");
wlist = cp_bquote(wlist);
pwlist(wlist, "After backquote substitution");
wlist = cp_doglob(wlist);
pwlist(wlist, "After globbing");
if (!wlist || !wlist->wl_word)
return;
/* Now loop through all of the commands given. */
rwlist = wlist;
do {
for (nextc = wlist; nextc; nextc = nextc->wl_next)
if (eq(nextc->wl_word, cp_csep))
break;
/* Temporarily hide the rest of the command... */
if (nextc && nextc->wl_prev)
nextc->wl_prev->wl_next = NULL;
ee = wlist->wl_prev;
if (ee)
wlist->wl_prev = NULL;
if (nextc == wlist) {
/* There was no text... */
goto out;
}
/* And do the redirection. */
cp_ioreset();
for (i = 0; noredirect[i]; i++)
if (eq(wlist->wl_word, noredirect[i]))
break;
if (!noredirect[i]) {
if (!(wlist = cp_redirect(wlist))) {
cp_ioreset();
return;
}
}
/* Get rid of all the 8th bits now... */
cp_striplist(wlist);
s = wlist->wl_word;
/* Look for the command in the command list. */
for (i = 0; cp_coms[i].co_comname; i++) {
/* strcmp(cp_coms[i].co_comname, s) ... */
for (t = cp_coms[i].co_comname, r = s; *t && *r;
t++, r++)
if (*t != *r)
break;
if (!*t && !*r)
break;
}
/* Now give the user-supplied command routine a try... */
if (!cp_coms[i].co_func && cp_oddcomm(s, wlist->wl_next))
goto out;
/* If it's not there, try it as a unix command. */
if (!cp_coms[i].co_comname) {
if (cp_dounixcom && cp_unixcom(wlist))
goto out;
fprintf(cp_err,"%s: no such command available in %s\n",
s, cp_program);
goto out;
/* If it's there but spiceonly, and this is nutmeg, error. */
} else if (!cp_coms[i].co_func && ft_nutmeg &&
(cp_coms[i].co_spiceonly)) {
fprintf(cp_err,"%s: command available only in spice\n",
s);
goto out;
}
/* The command was a valid spice/nutmeg command. */
command = &cp_coms[i];
nargs = 0;
for (wl = wlist->wl_next; wl; wl = wl->wl_next)
nargs++;
if (command->co_stringargs) {
lcom = wl_flatten(wlist->wl_next);
(*command->co_func) ((void *)(lcom));
} else {
if (nargs < command->co_minargs) {
if (command->co_argfn) {
(*command->co_argfn) (wlist->wl_next, command);
} else {
fprintf(cp_err, "%s: too few args.\n", s);
}
} else if (nargs > command->co_maxargs) {
fprintf(cp_err, "%s: too many args.\n", s);
} else
(*command->co_func) (wlist->wl_next);
}
/* Now fix the pointers and advance wlist. */
out: wlist->wl_prev = ee;
if (nextc) {
if (nextc->wl_prev)
nextc->wl_prev->wl_next = nextc;
wlist = nextc->wl_next;
}
} while (nextc && wlist);
wl_free(rwlist);
/* Do periodic sorts of things... */
cp_periodic();
cp_ioreset();
return;
}
/* Execute a block. There can be a number of return values from this routine.
* NORMAL indicates a normal termination
* BROKEN indicates a break -- if the caller is a breakable loop,
* terminate it, otherwise pass the break upwards
* CONTINUED indicates a continue -- if the caller is a continuable loop,
* continue, else pass the continue upwards
* Any other return code is considered a pointer to a string which is
* a label somewhere -- if this label is present in the block,
* goto it, otherwise pass it up. Note that this prevents jumping
* into a loop, which is good.
*
* Note that here is where we expand variables, ``, and globs for
* controls.
*
* The 'num' argument is used by break n and continue n. */
static char *
doblock(struct control *bl, int *num)
{
struct control *ch, *cn = NULL;
wordlist *wl;
char *i;
int nn;
switch (bl->co_type) {
case CO_WHILE:
while (bl->co_cond && cp_istrue(bl->co_cond)) {
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
switch (*i) {
case NORMAL:
break;
case BROKEN: /* Break. */
if (nn < 2)
return (NORMAL_STR);
else {
*num = nn - 1;
return (BROKEN_STR);
}
case CONTINUED: /* Continue. */
if (nn < 2) {
cn = NULL;
break;
} else {
*num = nn - 1;
return (CONTINUED_STR);
}
default:
cn = findlabel(i, bl->co_children);
if (!cn)
return (i);
}
}
}
break;
case CO_DOWHILE:
do {
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
switch (*i) {
case NORMAL:
break;
case BROKEN: /* Break. */
if (nn < 2)
return (NORMAL_STR);
else {
*num = nn - 1;
return (BROKEN_STR);
}
case CONTINUED: /* Continue. */
if (nn < 2) {
cn = NULL;
break;
} else {
*num = nn - 1;
return (CONTINUED_STR);
}
default:
cn = findlabel(i, bl->co_children);
if (!cn)
return (i);
}
}
} while (bl->co_cond && cp_istrue(bl->co_cond));
break;
case CO_REPEAT:
while ((bl->co_numtimes > 0) ||
(bl->co_numtimes == -1)) {
if (bl->co_numtimes != -1)
bl->co_numtimes--;
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
switch (*i) {
case NORMAL:
break;
case BROKEN: /* Break. */
if (nn < 2)
return (NORMAL_STR);
else {
*num = nn - 1;
return (BROKEN_STR);
}
case CONTINUED: /* Continue. */
if (nn < 2) {
cn = NULL;
break;
} else {
*num = nn - 1;
return (CONTINUED_STR);
}
default:
cn = findlabel(i, bl->co_children);
if (!cn)
return (i);
}
}
}
break;
case CO_IF:
if (bl->co_cond && cp_istrue(bl->co_cond)) {
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
if (*i > 2) {
cn = findlabel(i,
bl->co_children);
if (!cn)
return (i);
} else if (*i != NORMAL) {
*num = nn;
return (i);
}
}
} else {
for (ch = bl->co_elseblock; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
if (*i > 2) {
cn = findlabel(i,
bl->co_elseblock);
if (!cn)
return (i);
} else if (*i != NORMAL) {
*num = nn;
return (i);
}
}
}
break;
case CO_FOREACH:
for (wl = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(bl->co_text))));
wl;
wl = wl->wl_next) {
cp_vset(bl->co_foreachvar, VT_STRING, wl->wl_word);
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
switch (*i) {
case NORMAL:
break;
case BROKEN: /* Break. */
if (nn < 2)
return (NORMAL_STR);
else {
*num = nn - 1;
return (BROKEN_STR);
}
case CONTINUED: /* Continue. */
if (nn < 2) {
cn = NULL;
break;
} else {
*num = nn - 1;
return (CONTINUED_STR);
}
default:
cn = findlabel(i, bl->co_children);
if (!cn)
return (i);
}
}
}
break;
case CO_BREAK:
if (bl->co_numtimes > 0) {
*num = bl->co_numtimes;
return (BROKEN_STR);
} else {
fprintf(cp_err, "Warning: break %d a no-op\n",
bl->co_numtimes);
return (NORMAL_STR);
}
case CO_CONTINUE:
if (bl->co_numtimes > 0) {
*num = bl->co_numtimes;
return (CONTINUED_STR);
} else {
fprintf(cp_err, "Warning: continue %d a no-op\n",
bl->co_numtimes);
return (NORMAL_STR);
}
case CO_GOTO:
wl = cp_variablesubst(cp_bquote(cp_doglob(
wl_copy(bl->co_text))));
return (wl->wl_word);
case CO_LABEL:
/* Do nothing. */
break;
case CO_STATEMENT:
docommand(wl_copy(bl->co_text));
break;
case CO_UNFILLED:
/* There was probably an error here... */
fprintf(cp_err, "Warning: ignoring previous error\n");
break;
default:
fprintf(cp_err,
"doblock: Internal Error: bad block type %d\n",
bl->co_type);
return (NORMAL_STR);
}
return (NORMAL_STR);
}
/* Get a command. This does all the bookkeeping things like turning
* command completion on and off... */
static wordlist *
getcommand(char *string)
{
wordlist *wlist;
int i = 0, j;
static char buf[64];
struct control *c;
if (cp_debug)
fprintf(cp_err, "calling getcommand %s\n",
string ? string : "");
if (cend[stackp]) {
for (c = cend[stackp]->co_parent; c; c = c->co_parent)
i++;
if (i) {
for (j = 0; j < i; j++)
buf[j] = '>';
buf[j] = ' ';
buf[j + 1] = '\0';
cp_altprompt = buf;
} else
cp_altprompt = NULL;
} else
cp_altprompt = NULL;
cp_cwait = TRUE;
wlist = cp_parse(string);
cp_cwait = FALSE;
if (cp_debug) {
printf("getcommand ");
wl_print(wlist, stdout);
putc('\n', stdout);
}
return (wlist);
}
int
cp_evloop(char *string)
{
wordlist *wlist, *ww;
struct control *x;
char *i;
int nn;
#define newblock cend[stackp]->co_children = alloc(struct control); \
ZERO(cend[stackp]->co_children,struct control), \
cend[stackp]->co_children->co_parent = cend[stackp]; \
cend[stackp] = cend[stackp]->co_children; \
cend[stackp]->co_type = CO_UNFILLED;
for (;;) {
wlist = getcommand(string);
if (wlist == NULL) { /* End of file or end of user input. */
if (cend[stackp]->co_parent && !string) {
cp_resetcontrol();
continue;
} else
return (0);
}
if ((wlist->wl_word == NULL) || (*wlist->wl_word == '\0')) {
/* User just typed return. */
if (string)
return (1);
else {
cp_event--;
continue;
}
}
/* Just a check... */
for (ww = wlist; ww; ww = ww->wl_next)
if (!ww->wl_word) {
fprintf(cp_err,
"cp_evloop: Internal Error: NULL word pointer\n");
continue;
}
/* Add this to the control structure list. If cend->co_type is
* CO_UNFILLED, the last line was the beginning of a block,
* and this is the unfilled first statement. */
if (cend[stackp] && (cend[stackp]->co_type != CO_UNFILLED)) {
cend[stackp]->co_next = alloc(struct control);
ZERO(cend[stackp]->co_next, struct control);
cend[stackp]->co_next->co_prev = cend[stackp];
cend[stackp]->co_next->co_parent =
cend[stackp]->co_parent;
cend[stackp] = cend[stackp]->co_next;
} else if (!cend[stackp]) {
control[stackp] = cend[stackp] = alloc(struct control);
ZERO(cend[stackp], struct control);
}
if (eq(wlist->wl_word, "while")) {
cend[stackp]->co_type = CO_WHILE;
cend[stackp]->co_cond = wlist->wl_next;
if (!cend[stackp]->co_cond) {
fprintf(stderr,
"Error: missing while condition.\n");
}
newblock;
} else if (eq(wlist->wl_word, "dowhile")) {
cend[stackp]->co_type = CO_DOWHILE;
cend[stackp]->co_cond = wlist->wl_next;
if (!cend[stackp]->co_cond) {
fprintf(stderr,
"Error: missing dowhile condition.\n");
}
newblock;
} else if (eq(wlist->wl_word, "repeat")) {
cend[stackp]->co_type = CO_REPEAT;
if (!wlist->wl_next) {
cend[stackp]->co_numtimes = -1;
} else {
char *s;
double *dd;
wlist = cp_variablesubst(cp_bquote(
cp_doglob(wl_copy(wlist))));
s = wlist->wl_next->wl_word;
dd = ft_numparse(&s, FALSE);
if (dd) {
if (*dd < 0) {
fprintf(cp_err,
"Error: can't repeat a negative number of times\n");
*dd = 0.0;
}
cend[stackp]->co_numtimes = (int) *dd;
} else
fprintf(cp_err,
"Error: bad repeat argument %s\n",
wlist->wl_next->wl_word);
}
newblock;
} else if (eq(wlist->wl_word, "if")) {
cend[stackp]->co_type = CO_IF;
cend[stackp]->co_cond = wlist->wl_next;
if (!cend[stackp]->co_cond) {
fprintf(stderr,
"Error: missing if condition.\n");
}
newblock;
} else if (eq(wlist->wl_word, "foreach")) {
cend[stackp]->co_type = CO_FOREACH;
if (wlist->wl_next) {
wlist = wlist->wl_next;
cend[stackp]->co_foreachvar =
copy(wlist->wl_word);
wlist = wlist->wl_next;
} else
fprintf(stderr,
"Error: missing foreach variable.\n");
wlist = cp_doglob(wlist);
cend[stackp]->co_text = wl_copy(wlist);
newblock;
} else if (eq(wlist->wl_word, "label")) {
cend[stackp]->co_type = CO_LABEL;
if (wlist->wl_next) {
cend[stackp]->co_text = wl_copy(wlist->wl_next);
/* I think of everything, don't I? */
cp_addkword(CT_LABEL, wlist->wl_next->wl_word);
if (wlist->wl_next->wl_next)
fprintf(cp_err,
"Warning: ignored extra junk after label.\n");
} else
fprintf(stderr, "Error: missing label.\n");
} else if (eq(wlist->wl_word, "goto")) {
/* Incidentally, this won't work if the values 1 and 2 ever get
* to be valid character pointers -- I think it's reasonably
* safe to assume they aren't... */
cend[stackp]->co_type = CO_GOTO;
if (wlist->wl_next) {
cend[stackp]->co_text = wl_copy(wlist->wl_next);
if (wlist->wl_next->wl_next)
fprintf(cp_err,
"Warning: ignored extra junk after goto.\n");
} else
fprintf(stderr, "Error: missing label.\n");
} else if (eq(wlist->wl_word, "continue")) {
cend[stackp]->co_type = CO_CONTINUE;
if (wlist->wl_next) {
cend[stackp]->co_numtimes = scannum(wlist->
wl_next->wl_word);
if (wlist->wl_next->wl_next)
fprintf(cp_err,
"Warning: ignored extra junk after continue %d.\n",
cend[stackp]->co_numtimes);
} else
cend[stackp]->co_numtimes = 1;
} else if (eq(wlist->wl_word, "break")) {
cend[stackp]->co_type = CO_BREAK;
if (wlist->wl_next) {
cend[stackp]->co_numtimes = scannum(wlist->
wl_next->wl_word);
if (wlist->wl_next->wl_next)
fprintf(cp_err,
"Warning: ignored extra junk after break %d.\n",
cend[stackp]->co_numtimes);
} else
cend[stackp]->co_numtimes = 1;
} else if (eq(wlist->wl_word, "end")) {
/* Throw away this thing. */
if (!cend[stackp]->co_parent) {
fprintf(stderr, "Error: no block to end.\n");
cend[stackp]->co_type = CO_UNFILLED;
} else if (cend[stackp]->co_prev) {
cend[stackp]->co_prev->co_next = NULL;
x = cend[stackp];
cend[stackp] = cend[stackp]->co_parent;
tfree(x);
} else {
x = cend[stackp];
cend[stackp] = cend[stackp]->co_parent;
cend[stackp]->co_children = NULL;
tfree(x);
}
} else if (eq(wlist->wl_word, "else")) {
if (!cend[stackp]->co_parent ||
(cend[stackp]->co_parent->co_type !=
CO_IF)) {
fprintf(stderr, "Error: misplaced else.\n");
cend[stackp]->co_type = CO_UNFILLED;
} else {
if (cend[stackp]->co_prev)
cend[stackp]->co_prev->co_next = NULL;
else
cend[stackp]->co_parent->co_children = NULL;
cend[stackp]->co_parent->co_elseblock = cend[stackp];
cend[stackp]->co_prev = NULL;
}
} else {
cend[stackp]->co_type = CO_STATEMENT;
cend[stackp]->co_text = wlist;
}
if (!cend[stackp]->co_parent) {
x = cend[stackp];
/* We have to toss this do-while loop in here so
* that gotos at the top level will work.
*/
do {
i = doblock(x, &nn);
switch (*i) {
case NORMAL:
break;
case BROKEN:
fprintf(cp_err,
"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");
break;
default:
x = findlabel(i, control[stackp]);
if (!x)
fprintf(cp_err, "Error: label %s not found\n", i);
}
if (x)
x = x->co_next;
} while (x);
}
if (string)
return (1); /* The return value is irrelevant. */
}
}
/* This blows away the control structures... */
void
cp_resetcontrol(void)
{
if (cend[stackp] && cend[stackp]->co_parent)
fprintf(cp_err, "Warning: EOF before block terminated\n");
/* We probably should free the control structures... */
control[0] = cend[0] = NULL;
stackp = 0;
cp_kwswitch(CT_LABEL, (char *) NULL);
return;
}
/* Push or pop a new control structure set... */
void
cp_popcontrol(void)
{
if (cp_debug)
fprintf(cp_err, "pop: stackp: %d -> %d\n", stackp, stackp - 1);
if (stackp < 1)
fprintf(cp_err, "cp_popcontrol: Internal Error: stack empty\n");
else
stackp--;
return;
}
void
cp_pushcontrol(void)
{
if (cp_debug)
fprintf(cp_err, "push: stackp: %d -> %d\n", stackp, stackp + 1);
if (stackp > CONTROLSTACKSIZE - 2) {
fprintf(cp_err, "Error: stack overflow -- max depth = %d\n",
CONTROLSTACKSIZE);
stackp = 0;
} else {
stackp++;
control[stackp] = cend[stackp] = NULL;
}
return;
}
/* And this returns to the top level (for use in the interrupt handlers). */
void
cp_toplevel(void)
{
stackp = 0;
if (cend[stackp])
while (cend[stackp]->co_parent)
cend[stackp] = cend[stackp]->co_parent;
return;
}

45
src/frontend/control.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef _CONTROL_H
#define _CONTROL_H
/* Stuff to do control structures. We keep a history (seperate from
* the cshpar history, for now at least) of commands and their event
* numbers, with a block considered as a statement. In a goto, the
* first word in co_text is where to go, likewise for label. For
* conditional controls, we have to call ft_getpnames and ft_evaluate
* each time, since the dvec pointers will change... Also we should do
* variable and backquote substitution each time... */
struct control {
int co_type; /* One of CO_* ... */
wordlist *co_cond; /* if, while, dowhile */
char *co_foreachvar; /* foreach */
int co_numtimes; /* repeat, break & continue levels */
wordlist *co_text; /* Ordinary text and foreach values. */
struct control *co_parent; /* If this is inside a block. */
struct control *co_children; /* The contents of this block. */
struct control *co_elseblock; /* For if-then-else. */
struct control *co_next;
struct control *co_prev;
} ;
enum co_command {
CO_UNFILLED,
CO_STATEMENT,
CO_WHILE,
CO_DOWHILE,
CO_IF,
CO_FOREACH,
CO_BREAK,
CO_CONTINUE,
CO_LABEL,
CO_GOTO,
CO_REPEAT
};
#define CONTROLSTACKSIZE 256 /* Better be enough. */
extern struct control *control[CONTROLSTACKSIZE];
extern struct control *cend[CONTROLSTACKSIZE];
extern int stackp;
#endif

View File

@ -3,13 +3,22 @@ Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
* SJB 22 May 2001
* Corrected freeing of memory in ft_cpinit()
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteparse.h"
#include "cpitf.h"
#include <terminal.h>
#include "completion.h"
#include "variable.h"
/* Set some standard variables and aliases, etc, and init the ccom stuff. */
@ -19,7 +28,7 @@ ft_cpinit(void)
wordlist *wl;
wordlist wl1, wl2, wl3;
bool found = FALSE, t = TRUE;
char buf[BSIZE_SP], **x, *s, *r;
char buf[BSIZE_SP], **x, *s, *r,*copys;
struct comm *c;
int i;
FILE *fp;
@ -202,11 +211,12 @@ ft_cpinit(void)
/* Now source the standard startup file. */
/* XXX strange */
for (s = cp_tildexpand(Lib_Path); s && *s; ) {
for (copys=s=cp_tildexpand(Lib_Path); s && *s; ) {/*DG*/
while (isspace(*s))
s++;
for (r = buf; *s && !isspace(*s); r++, s++)
*r = *s;
tfree(copys); /* sjb - it's safe to free this here */
(void) strcpy(r, DIR_PATHSEP);
(void) strcat(r, "spinit");
if ((fp = fopen(buf, "r"))) {
@ -232,14 +242,15 @@ ft_cpinit(void)
}
tcap_init( );
/* tfree(copys);*/ /*DG Avoid memory leak*/
/* SJB - must not free here as cp_tildexpande() can return NULL */
return;
}
/* Decide whether a condition is TRUE or not. */
bool
cp_isTRUE(wordlist *wl)
cp_istrue(wordlist *wl)
{
int i;
struct dvec *v;

View File

@ -17,10 +17,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteparse.h"
#include "define.h"
#include "completion.h"
/* static declarations */
static void savetree(struct pnode *pn);
@ -265,7 +266,7 @@ ft_substdef(char *name, struct pnode *args)
struct udfunc *udf;
struct pnode *tp;
char *s;
int arity = 0, rarity;
int arity = 0, rarity = 0;
bool found = FALSE;
if (args)
@ -439,7 +440,7 @@ com_undefine(wordlist *wlist)
*/
void
ft_pnode(struct pn *pn)
ft_pnode(struct pnode *pn)
{
prtree1(pn, cp_err);
}

View File

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/
/*
@ -13,8 +14,10 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "cpdefs.h"
#include "ftedefs.h"
#include "dgen.h"
#include "device.h"
#include "circuits.h"
#include "device.h"
#include "variable.h"
static wordlist *devexpand(char *name);
@ -74,7 +77,7 @@ all_show(wordlist *wl, int mode)
if (!cp_getvar("width", VT_NUM, (char *) &screen_width))
screen_width = DEF_WIDTH;
count = screen_width / 11 - 1;
count = (screen_width - LEFT_WIDTH) / (DEV_WIDTH + 1);
n = 0;
do {
@ -166,7 +169,7 @@ all_show(wordlist *wl, int mode)
i = 0;
do {
printf(" device ");
printf("%*s", LEFT_WIDTH, "device");
j = dgen_for_n(dg, count, printstr, "n", i);
i += 1;
printf("\n");
@ -175,7 +178,7 @@ all_show(wordlist *wl, int mode)
if (ft_sim->devices[dg->dev_type_no]->numModelParms) {
i = 0;
do {
printf(" model ");
printf("%*s", LEFT_WIDTH, "model");
j = dgen_for_n(dg, count, printstr, "m", i);
i += 1;
printf("\n");
@ -188,7 +191,7 @@ all_show(wordlist *wl, int mode)
else if (!params)
param_forall(dg, DGEN_DEFPARAMS);
if (params)
wl_forall(params, listparam, dg);
wl_forall(params, (void *)listparam, (void *)dg);
printf("\n");
} else if (ft_sim->devices[dg->dev_type_no]->numModelParms) {
@ -198,7 +201,7 @@ all_show(wordlist *wl, int mode)
n += 1;
i = 0;
do {
printf(" model ");
printf("%*s", LEFT_WIDTH, "model");
j = dgen_for_n(dg, count, printstr, "m", i);
i += 1;
printf("\n");
@ -210,7 +213,7 @@ all_show(wordlist *wl, int mode)
else if (!params)
param_forall(dg, DGEN_DEFPARAMS);
if (params)
wl_forall(params, listparam, dg);
wl_forall(params, (void *) listparam, (void *)dg);
printf("\n");
}
}
@ -234,16 +237,16 @@ printstr(dgen *dg, char *name)
{
if (*name == 'n') {
if (dg->instance)
printf(" %9.9s", dg->instance->GENname);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname);
else
printf(" <???????>");
printf(" %*s", DEV_WIDTH, "<???????>");
} else if (*name == 'm') {
if (dg->model)
printf(" %9.9s", dg->model->GENmodName);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName);
else
printf(" <???????>");
printf(" %*s", DEV_WIDTH, "<???????>");
} else
printf(" <error> ");
printf(" %*s", DEV_WIDTH, "<error>");
return 0;
}
@ -276,9 +279,10 @@ param_forall(dgen *dg, int flags)
j = 0;
do {
if (!j)
printf("%10.10s", plist[i].keyword);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH,
plist[i].keyword);
else
printf(" ");
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, printvals,
(char *) (plist + i), j);
printf("\n");
@ -321,10 +325,10 @@ listparam(wordlist *p, dgen *dg)
j = 0;
do {
if (!j)
printf("%10.10s", p->wl_word);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
else
printf(" ");
k = dgen_for_n(dg, count, printvals, plist + i, j);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, printvals, (void *)(plist + i), j);
printf("\n");
j += 1;
} while (k > 0);
@ -332,9 +336,9 @@ listparam(wordlist *p, dgen *dg)
j = 0;
do {
if (!j)
printf("%10.10s", p->wl_word);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
else
printf(" ");
printf("%*s", LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, bogus1, 0, j);
printf("\n");
j += 1;
@ -344,9 +348,9 @@ listparam(wordlist *p, dgen *dg)
j = 0;
do {
if (!j)
printf("%10.10s", p->wl_word);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
else
printf(" ");
printf("%*s", LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, bogus2, 0, j);
printf("\n");
j += 1;
@ -356,13 +360,13 @@ listparam(wordlist *p, dgen *dg)
int bogus1(dgen *dg)
{
printf(" ---------");
printf(" %*s", DEV_WIDTH, "---------");
return 0;
}
int bogus2(dgen *dg)
{
printf(" ?????????");
printf(" %*s", DEV_WIDTH, "?????????");
return 0;
}
@ -398,54 +402,54 @@ printvals(dgen *dg, IFparm *p, int i)
if (p->dataType & IF_VECTOR) {
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
case IF_FLAG:
printf(" % 9d", val.v.vec.iVec[i]);
printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]);
break;
case IF_INTEGER:
printf(" % 9d", val.v.vec.iVec[i]);
printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]);
break;
case IF_REAL:
printf(" % 9.3g", val.v.vec.rVec[i]);
printf(" % *.6g", DEV_WIDTH, val.v.vec.rVec[i]);
break;
case IF_COMPLEX:
if (!(i % 2))
printf(" % 9.3g", val.v.vec.cVec[i / 2].real);
printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].real);
else
printf(" % 9.3g", val.v.vec.cVec[i / 2].imag);
printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].imag);
break;
case IF_STRING:
printf(" %9.9s", val.v.vec.sVec[i]);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]);
break;
case IF_INSTANCE:
printf(" %9.9s", val.v.vec.uVec[i]);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]);
break;
default:
printf(" ******** ");
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
}
} else {
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
case IF_FLAG:
printf(" % 9d", val.iValue);
printf(" % *d", DEV_WIDTH, val.iValue);
break;
case IF_INTEGER:
printf(" % 9d", val.iValue);
printf(" % *d", DEV_WIDTH, val.iValue);
break;
case IF_REAL:
printf(" % 9.3g", val.rValue);
printf(" % *.6g", DEV_WIDTH, val.rValue);
break;
case IF_COMPLEX:
if (i % 2)
printf(" % 9.3g", val.cValue.real);
printf(" % *.6g", DEV_WIDTH, val.cValue.real);
else
printf(" % 9.3g", val.cValue.imag);
printf(" % *.6g", DEV_WIDTH, val.cValue.imag);
break;
case IF_STRING:
printf(" %9.9s", val.sValue);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.sValue);
break;
case IF_INSTANCE:
printf(" %9.9s ", val.uValue);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.uValue);
break;
default:
printf(" ******** ");
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
}
}
@ -566,10 +570,6 @@ com_altermod(wordlist *wl)
void
com_alter_common(wordlist *wl, int do_model)
{
#ifdef notdef
struct variable var, *nv, *prev;
double *dd;
#endif
wordlist *eqword, *words;
char *dev, *p;
char *param;
@ -650,78 +650,6 @@ com_alter_common(wordlist *wl, int do_model)
/* Vector data (dv) should get garbage-collected. */
return;
#ifdef notdef
while (wl) {
param = wl->wl_word;
wl = wl->wl_next;
if (!wl) {
val = param;
param = NULL;
} else {
val = wl->wl_word;
wl = wl->wl_next;
}
/* Now figure out what the value should be... */
if (eq(val, "TRUE")) {
var.va_type = VT_BOOL;
var.va_bool = TRUE;
} else if (eq(val, "FALSE")) {
var.va_type = VT_BOOL;
var.va_bool = FALSE;
} else if (eq(val, "[")) {
var.va_type = VT_LIST;
prev = NULL;
while (wl && !eq(wl->wl_word, "]")) {
val = wl->wl_word;
nv = alloc(struct variable);
if (dd = ft_numparse(&val, FALSE)) {
nv->va_type = VT_REAL;
nv->va_real = *dd;
} else {
fprintf(cp_err, "Error: \"%s\" is not a number\n", val);
break;
}
if (!prev)
var.va_vlist = nv;
else
prev->va_next = nv;
nv->va_next = NULL;
wl = wl->wl_next;
prev = nv;
}
if (wl && eq(wl->wl_word, "]")) {
wl = wl->wl_next;
} else {
while (nv) {
prev = nv->va_next;
tfree(nv);
nv = prev;
}
return;
}
} else if (dd = ft_numparse(&val, FALSE)) {
var.va_type = VT_REAL;
var.va_real = *dd;
} else {
var.va_type = VT_STRING;
var.va_string = val;
}
if_setparam(ft_curckt->ci_ckt, &dev, param, &var, do_model);
if (var.va_type == VT_LIST) {
for (nv = var.va_vlist; nv; nv = prev) {
prev = nv->va_next;
tfree(nv);
}
}
}
#endif
}
/* Given a device name, possibly with wildcards, return the matches. */

View File

@ -1,11 +1,15 @@
/*************
* Header file for device.c
* 1999 E. Rouat
* Modified: 2000 AlansFixes
************/
#ifndef DEVICE_H_INCLUDED
#define DEVICE_H_INCLUDED
#define LEFT_WIDTH 11
#define DEV_WIDTH 21
void com_showmod(wordlist *wl);
void com_show(wordlist *wl);
int printstr(dgen *dg, char *name);

View File

@ -1,18 +1,20 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2001 Paolo Nenzi (printnum)
**********/
/*
* Do a 'diff' of two plots.
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "ftecmath.h"
#include <ngspice.h>
#include <ftedefs.h>
#include <dvec.h>
#include <sim.h>
#include "diff.h"
#include "variable.h"
/* Determine if two vectors have the 'same' name. */
@ -21,6 +23,7 @@ static bool
nameeq(char *n1, char *n2)
{
char buf1[BSIZE_SP], buf2[BSIZE_SP];
int i;
if (eq(n1, n2))
@ -50,8 +53,9 @@ com_diff(wordlist *wl)
struct dvec *v1, *v2;
double d1, d2;
complex c1, c2, c3;
register int i, j;
int i, j;
wordlist *tw;
char numbuf[BSIZE_SP],numbuf2[BSIZE_SP] ,numbuf3[BSIZE_SP], numbuf4[BSIZE_SP]; /* For printnum */
if (!cp_getvar("diff_vntol", VT_REAL, (char *) &vntol))
vntol = 1.0e-6;
@ -203,14 +207,16 @@ com_diff(wordlist *wl)
d2 = v2->v_realdata[i];
if (MAX(fabs(d1), fabs(d2)) * reltol +
tol < fabs(d1 - d2)) {
printnum(numbuf, d1);
fprintf(cp_out,
"%s.%s[%d] = %-15s ",
p1->pl_typename, v1->v_name, i,
printnum(d1));
numbuf);
printnum(numbuf, d2);
fprintf(cp_out,
"%s.%s[%d] = %s\n",
p2->pl_typename, v2->v_name, i,
printnum(d2));
numbuf);
}
} else {
c1 = v1->v_compdata[i];
@ -223,14 +229,20 @@ com_diff(wordlist *wl)
cmax = MAX(cm1, cm2);
if (cmax * reltol +
tol < cmag(&c3)) {
printnum(numbuf, realpart(&c1));
printnum(numbuf2, imagpart(&c1));
printnum(numbuf3, realpart(&c2));
printnum(numbuf4, imagpart(&c2));
fprintf(cp_out,
"%s.%s[%d] = %-10s, %-10s %s.%s[%d] = %-10s, %s\n",
p1->pl_typename, v1->v_name, i,
copy(printnum(realpart(&c1))),
copy(printnum(imagpart(&c1))),
numbuf,
numbuf2,
p2->pl_typename, v2->v_name, i,
copy(printnum(realpart(&c2))),
copy(printnum(imagpart(&c2))));
numbuf3,
numbuf4);
}
}
}

View File

@ -3,12 +3,12 @@
* 1999 E. Rouat
************/
#ifndef DIFF_H_INCLUDED
#define DIFF_H_INCLUDED
#ifndef _DIFF_H
#define _DIFF_H
#include <wordlist.h>
void com_diff(wordlist *wl);
#endif

View File

@ -8,21 +8,22 @@ Author: 1992 David A. Gates, U. C. Berkeley CAD Group
*/
#include "ngspice.h"
#include "ftedata.h" /* For MAXDIMS */
#include "dvec.h" /* For MAXDIMS */
#include "dimens.h"
/*
* Create a string of the form "12,1,10".
*/
char *
dimstring(int *data, int length)
void
dimstring(int *data, int length, char *retstring)
{
int i;
char buf[BSIZE_SP];
if (!data || length < 1)
return NULL;
retstring = "";
buf[0] = '\0';
for (i=0; i < length; i++) {
@ -30,26 +31,27 @@ dimstring(int *data, int length)
(i < length - 1) ? "," : "");
}
/* XXX Should I return a copy instead? */
return(buf);
/* qui ci devo fare una copia */
strcpy(retstring, buf);
}
/*
* Create a string of the form "[12][1][10]".
*/
char *
indexstring(int *data, int length)
void
indexstring(int *data, int length, char *retstring)
{
int i;
char buf[BSIZE_SP];
if (!data || length < 1)
return NULL;
retstring = "";
buf[0] = '\0';
for (i=0; i < length; i++) {
sprintf(buf + strlen(buf), "[%d]", data[i]);
}
return(buf);
strcpy(retstring, buf);
}
/*

View File

@ -6,8 +6,8 @@
#ifndef DIMENS_H_INCLUDED
#define DIMENS_H_INCLUDED
char * dimstring(int *data, int length);
char * indexstring(int *data, int length);
void dimstring(int *data, int length, char *retstring);
void indexstring(int *data, int length, char *retstring);
int incindex(int *counts, int numcounts, int *dims, int numdims);
int emptydims(int *data, int length);
int atodims(char *p, int *data, int *outlength);

View File

@ -3,19 +3,22 @@ Copyright 1990 Regents of the University of California. All rights reserved.
**********/
#include "ngspice.h"
#include "ftegraph.h"
#include "ftedev.h"
#include "fteinput.h"
#include "cpdefs.h" /* for VT_STRING */
#include "ftedefs.h" /* for mylog() */
#include <ngspice.h>
#include <graph.h>
#include <ftedev.h>
#include <fteinput.h>
#include <cpdefs.h> /* for VT_STRING */
#include <ftedefs.h> /* for mylog() */
#ifdef TCL_MODULE
#include <tclspice.h>
#endif
#include "display.h"
#include "variable.h"
/* static declarations */
static int gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny);
static void gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny);
static int gen_Input(REQUEST *request, RESPONSE *response);
static int nop(void);
static int nodev(void);
@ -52,7 +55,7 @@ DISPDEVICE device[] = {
nop, nop, nop, nop, nop,
nop, nop, nop,
nop, nop, nop, gen_Input,
nop,},
(void *)nop,},
#ifndef X_DISPLAY_MISSING
{"X11", 0, 0, 1024, 864, 0, 0, X11_Init, X11_NewViewport,
@ -63,6 +66,14 @@ DISPDEVICE device[] = {
gen_DatatoScreen,},
#endif
#ifdef TCL_MODULE
{"Tk", 0, 0, 1024, 864, 0, 0, sp_Tk_Init, sp_Tk_NewViewport,
sp_Tk_Close, sp_Tk_Clear,
sp_Tk_DrawLine, sp_Tk_Arc, sp_Tk_Text, sp_Tk_DefineColor, sp_Tk_DefineLinestyle,
sp_Tk_SetLinestyle, sp_Tk_SetColor, sp_Tk_Update,
nodev, nodev, nodev, nodev,
gen_DatatoScreen,},
#endif
{"plot5", 0, 0, 1000, 1000, 0, 0, Plt5_Init, Plt5_NewViewport,
Plt5_Close, Plt5_Clear,
@ -83,7 +94,7 @@ DISPDEVICE device[] = {
nodev, nodev, nodev, nodev, nodev,
nodev, nodev, nodev,
nodev, nodev, nodev, gen_Input,
nodev,},
(void *)nodev,},
};
@ -135,7 +146,9 @@ DevInit(void)
}
#endif
#ifdef TCL_MODULE
dispdev = FindDev("Tk");
#endif
if (!dispdev) {
externalerror(
@ -230,7 +243,7 @@ void Update(void)
/* note: screen coordinates are relative to window
so need to add viewport offsets */
static int
static void
gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny)
{
@ -276,19 +289,6 @@ void DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny)
}
#ifdef notdef
/*
NDCtoScreen(x0, y0, px, py)
double x0, y0;
int *px, *py;
{
(*(dispdev->NDCtoScreen))(x0, y0, px, py);
}
*/
#endif
void Input(REQUEST *request, RESPONSE *response)
{
@ -311,6 +311,7 @@ gen_Input(REQUEST *request, RESPONSE *response)
response->option = error_option;
break;
}
return 0;
}
/* no operation, do nothing */
@ -335,7 +336,7 @@ void SaveText(GRAPH *graph, char *text, int x, int y)
struct _keyed *keyed;
keyed = (struct _keyed *) calloc(1, sizeof(struct _keyed));
keyed = (struct _keyed *) tmalloc(sizeof(struct _keyed));
if (!graph->keyed) {
graph->keyed = keyed;

View File

@ -1,32 +1,54 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/
/*
* Spice-2 compatibility stuff for .plot, .print, .four, and .width.
*/
#include <config.h>
#include <ngspice.h>
#include <assert.h>
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "dvec.h"
#include "fteinp.h"
#include <sim.h>
#include "circuits.h"
#include "dotcards.h"
#include "variable.h"
#include "fourier.h"
/* Extract all the .save lines */
static void fixdotplot(wordlist *wl);
static void fixdotprint(wordlist *wl);
static char * fixem(char *string);
static bool setcplot(char *name);
static wordlist * gettoks(char *s);
extern void com_save2 (wordlist *wl, char *name);
static struct plot *
setcplot(char *name)
{
struct plot *pl;
for (pl = plot_list; pl; pl = pl->pl_next) {
if (ciprefix(name, pl->pl_typename)) {
return pl;
}
}
return NULL;
}
void
ft_dotsaves(void)
{
@ -145,61 +167,65 @@ ft_cktcoms(bool terse)
static wordlist twl = { "col", NULL, NULL } ;
struct plot *pl;
int i, found;
char numbuf[BSIZE_SP]; /* For printnum*/
all.wl_next = NULL;
all.wl_word = "all";
if (!ft_curckt)
return 1;
if (!ft_curckt->ci_commands)
plot_cur = setcplot("op");
if (!ft_curckt->ci_commands && !plot_cur)
goto nocmds;
coms = ft_curckt->ci_commands;
cp_interactive = FALSE;
/* Circuit name */
fprintf(cp_out, "Circuit: %s\nDate: %s\n\n", ft_curckt->ci_name,
datestring());
fprintf(cp_out, "\n");
/* Listing */
if (ft_listprint) {
if (terse)
fprintf(cp_err, ".options: no listing, rawfile was generated.\n");
else
inp_list(cp_out, ft_curckt->ci_deck, ft_curckt->ci_options,
LS_DECK);
LS_DECK);
}
/* If there was a .op line, then we have to do the .op output. */
if (setcplot("op")) {
if (terse) {
fprintf(cp_out, "OP information in rawfile.\n");
} else {
fprintf(cp_out, "\nOperating point information:\n\n");
fprintf(cp_out, "\tNode\tVoltage\n");
fprintf(cp_out, "\t----\t-------\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next) {
if (!isreal(v)) {
fprintf(cp_err,
"Internal error: op vector %s not real\n",
v->v_name);
continue;
plot_cur = setcplot("op");
if (plot_cur != NULL) {
assert(plot_cur->pl_dvecs != NULL);
if (plot_cur->pl_dvecs->v_realdata!=NULL) {
if (terse) {
fprintf(cp_out, "OP information in rawfile.\n");
} else {
fprintf(cp_out, "\t%-30s%15s\n", "Node", "Voltage");
fprintf(cp_out, "\t%-30s%15s\n", "----", "-------");
fprintf(cp_out, "\t----\t-------\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next) {
if (!isreal(v)) {
fprintf(cp_err,
"Internal error: op vector %s not real\n",
v->v_name);
continue;
}
if ((v->v_type == SV_VOLTAGE) && (*(v->v_name)!='@')) {
printnum(numbuf, v->v_realdata[0]);
fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf);
}
}
if (v->v_type == SV_VOLTAGE)
fprintf(cp_out, "\t%s\t%s\n", v->v_name,
printnum(v->v_realdata[0]));
}
fprintf(cp_out, "\n\tSource\tCurrent\n");
fprintf(cp_out, "\t------\t-------\n\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next)
if (v->v_type == SV_CURRENT)
fprintf(cp_out, "\t%s\t%s\n", v->v_name,
printnum(v->v_realdata[0]));
fprintf(cp_out, "\n");
fprintf(cp_out, "\n\tSource\tCurrent\n");
fprintf(cp_out, "\t------\t-------\n\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next)
if (v->v_type == SV_CURRENT) {
printnum(numbuf, v->v_realdata[0]);
fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf);
}
fprintf(cp_out, "\n");
if (!ft_nomod)
com_showmod(&all);
com_show(&all);
if (!ft_nomod)
com_showmod(&all);
com_show(&all);
}
}
}
@ -238,7 +264,7 @@ ft_cktcoms(bool terse)
} else if (eq(command->wl_word, ".print")) {
if (terse) {
fprintf(cp_out,
".print line ignored since rawfile was produced.\n");
".print line ignored since rawfile was produced.\n");
} else {
command = command->wl_next;
if (!command) {
@ -261,12 +287,12 @@ ft_cktcoms(bool terse)
}
if (!found)
fprintf(cp_err, "Error: .print: no %s analysis found.\n",
plottype);
plottype);
}
} else if (eq(command->wl_word, ".plot")) {
if (terse) {
fprintf(cp_out,
".plot line ignored since rawfile was produced.\n");
".plot line ignored since rawfile was produced.\n");
} else {
command = command->wl_next;
if (!command) {
@ -289,35 +315,40 @@ ft_cktcoms(bool terse)
}
if (!found)
fprintf(cp_err, "Error: .plot: no %s analysis found.\n",
plottype);
plottype);
}
} else if (ciprefix(".four", command->wl_word)) {
if (terse) {
fprintf(cp_out,
".fourier line ignored since rawfile was produced.\n");
} else if (setcplot("tran")) {
com_fourier(command->wl_next);
fprintf(cp_out, "\n\n");
} else
fprintf(cp_err,
"No transient data available for fourier analysis");
".fourier line ignored since rawfile was produced.\n");
} else {
int err;
plot_cur = setcplot("tran");
err = fourier(command->wl_next, plot_cur);
if (!err)
fprintf(cp_out, "\n\n");
else
fprintf(cp_err, "No transient data available for "
"fourier analysis");
}
} else if (!eq(command->wl_word, ".save")
&& !eq(command->wl_word, ".op")
&& !eq(command->wl_word, ".tf"))
&& !eq(command->wl_word, ".op")
&& !eq(command->wl_word, ".tf"))
{
goto bad;
}
coms = coms->wl_next;
}
nocmds:
nocmds:
/* Now the node table */
if (ft_nodesprint)
;
/* The options */
if (ft_optsprint) {
fprintf(cp_err, "Options:\n\n");
fprintf(cp_out, "Options:\n\n");
cp_vprint();
(void) putc('\n', cp_out);
}
@ -329,10 +360,11 @@ nocmds:
} else
com_rusage((wordlist *) NULL);
(void) putc('\n', cp_out);
putc('\n', cp_out);
return 0;
bad: fprintf(cp_err, "Internal Error: ft_cktcoms: bad commands\n");
bad:
fprintf(cp_err, "Internal Error: ft_cktcoms: bad commands\n");
return 1;
}
@ -349,6 +381,7 @@ static void
fixdotplot(wordlist *wl)
{
char buf[BSIZE_SP], *s;
char numbuf[128]; /* Printnum Fix */
double *d, d1, d2;
while (wl) {
@ -379,13 +412,14 @@ fixdotplot(wordlist *wl)
wl->wl_next = alloc(struct wordlist);
wl->wl_next->wl_prev = wl;
wl = wl->wl_next;
(void) strcpy(buf, printnum(d1));
wl->wl_word = copy(buf);
printnum(numbuf, d1);
wl->wl_word = copy(numbuf);
wl->wl_next = alloc(struct wordlist);
wl->wl_next->wl_prev = wl;
wl = wl->wl_next;
(void) strcpy(buf, printnum(d2));
wl->wl_word = copy(buf);
printnum(numbuf, d2);
wl->wl_word = copy(numbuf);
}
wl = wl->wl_next;
}
@ -405,7 +439,8 @@ fixdotprint(wordlist *wl)
static char *
fixem(char *string)
{
char buf[BSIZE_SP], *s, *t, *ss = string;
char buf[BSIZE_SP], *s, *t;
char *ss = string; /* Get rid of ss ? */
if (ciprefix("v(", string) &&strchr(string, ',')) {
for (s = string; *s && (*s != ','); s++)
@ -469,94 +504,6 @@ fixem(char *string)
return (string);
}
/* Don't bother with ccom strangeness here. */
static bool
setcplot(char *name)
{
struct plot *pl;
for (pl = plot_list; pl; pl = pl->pl_next) {
if (ciprefix(name, pl->pl_typename)) {
plot_cur = pl;
return (TRUE);
}
}
return (FALSE);
}
#ifdef notdef
static wordlist *
gettoks(s)
char *s;
{
char *t, *r, buf[64];
wordlist *wl = NULL, *end = NULL;
bool iflag;
while (t = gettok(&s)) {
if (*t == '(' /* ) */) {
/* This is a (upper, lower) thing -- ignore. */
continue;
} else if (!index(t, '(' /*)*/ )) {
if (end) {
end->wl_next = alloc(struct wordlist);
end->wl_next->wl_prev = end;
end = end->wl_next;
} else
wl = end = alloc(struct wordlist);
end->wl_word = copy(t);
} else if (!index(t, ',')) {
iflag = ((*t == 'i') || (*t == 'I')) ? TRUE : FALSE;
while (*t != '(' /*)*/)
t++;
t++;
for (r = t; *r && *r != /*(*/ ')'; r++)
;
*r = '\0';
if (end) {
end->wl_next = alloc(struct wordlist);
end->wl_next->wl_prev = end;
end = end->wl_next;
} else
wl = end = alloc(struct wordlist);
if (iflag) {
(void) sprintf(buf, "%s#branch", t);
t = buf;
}
end->wl_word = copy(t);
} else {
/* The painful case */
while (*t != '(' /*)*/)
t++;
t++;
for (r = t; *r && *r != ','; r++)
;
*r = '\0';
if (end) {
end->wl_next = alloc(struct wordlist);
end->wl_next->wl_prev = end;
end = end->wl_next;
} else
wl = end = alloc(struct wordlist);
end->wl_word = copy(t);
t = r + 1;
for (r = t; *r && *r != /*(*/ ')'; r++)
;
*r = '\0';
if (end) {
end->wl_next = alloc(struct wordlist);
end->wl_next->wl_prev = end;
end = end->wl_next;
} else
wl = end = alloc(struct wordlist);
end->wl_word = copy(t);
}
}
return (wl);
}
#endif
static wordlist *
gettoks(char *s)
{

View File

@ -7,14 +7,13 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
* Convert a parse tree to a list of data vectors.
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "ftedata.h"
#include "fteparse.h"
#include "ftecmath.h"
#include <setjmp.h>
#include <signal.h>
#include <ngspice.h>
#include <ftedefs.h>
#include <dvec.h>
#include "evaluate.h"
@ -22,9 +21,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
static RETSIGTYPE sig_matherr(void);
static struct dvec * apply_func(struct func *func, struct pnode *arg);
static char * mkcname(char what, char *v1, char *v2);
static struct dvec * doop(char what, void *(*func) (/* ??? */),
struct pnode *arg1, struct pnode *arg2);
/* We are careful here to catch SIGILL and recognise them as math errors.
@ -47,7 +43,7 @@ sig_matherr(void)
struct dvec *
ft_evaluate(struct pnode *node)
{
struct dvec *d;
struct dvec *d = NULL;
if (!node)
return (NULL);
@ -81,8 +77,226 @@ ft_evaluate(struct pnode *node)
return (d);
}
/* The binary operations. */
/* Operate on two vectors, and return a third with the data, length, and flags
* fields filled in. Add it to the current plot and get rid of the two args.
*/
static struct dvec *
doop(char what,
void*(*func) (void *data1, void *data2,
short int datatype1, short int datatype2,
int length),
struct pnode *arg1,
struct pnode *arg2)
{
struct dvec *v1, *v2, *res;
complex *c1 = NULL, *c2 = NULL , lc;
double *d1 = NULL, *d2 = NULL, ld;
int length = 0, i;
void *data;
bool free1 = FALSE, free2 = FALSE, relflag = FALSE;
v1 = ft_evaluate(arg1);
v2 = ft_evaluate(arg2);
if (!v1 || !v2)
return (NULL);
/* Now the question is, what do we do when one or both of these
* has more than one vector? This is definitely not a good
* thing. For the time being don't do anything.
*/
if (v1->v_link2 || v2->v_link2) {
fprintf(cp_err, "Warning: no operations on wildcards yet.\n");
if (v1->v_link2 && v2->v_link2)
fprintf(cp_err, "\t(You couldn't do that one anyway)\n");
return (NULL);
}
/* How do we handle operations on multi-dimensional vectors?
* For now, we only allow operations between one-D vectors,
* equivalently shaped multi-D vectors, or a multi-D vector and
* a one-D vector. It's not at all clear what to do in the other cases.
* So only check shape requirement if its an operation between two multi-D
* arrays.
*/
if ((v1->v_numdims > 1) && (v2->v_numdims > 1)) {
if (v1->v_numdims != v2->v_numdims) {
fprintf(cp_err,
"Warning: operands %s and %s have incompatible shapes.\n",
v1->v_name, v2->v_name);
return (NULL);
}
for (i = 1; i < v1->v_numdims; i++) {
if ((v1->v_dims[i] != v2->v_dims[i])) {
fprintf(cp_err,
"Warning: operands %s and %s have incompatible shapes.\n",
v1->v_name, v2->v_name);
return (NULL);
}
}
}
/* This is a bad way to do this. */
switch (what) {
case '=':
case '>':
case '<':
case 'G':
case 'L':
case 'N':
case '&':
case '|':
case '~':
relflag = TRUE;
}
/* Don't bother to do type checking. Maybe this should go in at
* some point.
*/
/* Make sure we have data of the same length. */
length = ((v1->v_length > v2->v_length) ? v1->v_length : v2->v_length);
if (v1->v_length < length) {
free1 = TRUE;
if (isreal(v1)) {
ld = 0.0;
d1 = (double *) tmalloc(length * sizeof (double));
for (i = 0; i < v1->v_length; i++)
d1[i] = v1->v_realdata[i];
if (length > 0)
ld = v1->v_realdata[v1->v_length - 1];
for ( ; i < length; i++)
d1[i] = ld;
} else {
realpart(&lc) = 0.0;
imagpart(&lc) = 0.0;
c1 = (complex *) tmalloc(length * sizeof (complex));
for (i = 0; i < v1->v_length; i++)
c1[i] = v1->v_compdata[i];
if (length > 0)
lc = v1->v_compdata[v1->v_length - 1];
for ( ; i < length; i++)
c1[i] = lc;
}
} else
if (isreal(v1))
d1 = v1->v_realdata;
else
c1 = v1->v_compdata;
if (v2->v_length < length) {
free2 = TRUE;
if (isreal(v2)) {
ld = 0.0;
d2 = (double *) tmalloc(length * sizeof (double));
for (i = 0; i < v2->v_length; i++)
d2[i] = v2->v_realdata[i];
if (length > 0)
ld = v2->v_realdata[v2->v_length - 1];
for ( ; i < length; i++)
d2[i] = ld;
} else {
realpart(&lc) = 0.0;
imagpart(&lc) = 0.0;
c2 = (complex *) tmalloc(length * sizeof (complex));
for (i = 0; i < v2->v_length; i++)
c2[i] = v2->v_compdata[i];
if (length > 0)
lc = v2->v_compdata[v1->v_length - 1];
for ( ; i < length; i++)
c2[i] = lc;
}
} else
if (isreal(v2))
d2 = v2->v_realdata;
else
c2 = v2->v_compdata;
/* Some of the math routines generate SIGILL if the argument is
* out of range. Catch this here.
*/
if (setjmp(matherrbuf)) {
return (NULL);
}
(void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);
/* Now pass the vectors to the appropriate function. */
data = ((*func) ((isreal(v1) ? (void *) d1 : (void *) c1),
(isreal(v2) ? (void *) d2 : (void *) c2),
(isreal(v1) ? VF_REAL : VF_COMPLEX),
(isreal(v2) ? VF_REAL : VF_COMPLEX),
length));
/* Back to normal */
(void) signal(SIGILL, SIG_DFL);
if (!data)
return (NULL);
/* Make up the new vector. */
res = alloc(struct dvec);
ZERO(res,struct dvec);
if (relflag || (isreal(v1) && isreal(v2) && (func != cx_comma))) {
res->v_flags = (v1->v_flags | v2->v_flags |
VF_REAL) & ~ VF_COMPLEX;
res->v_realdata = (double *) data;
} else {
res->v_flags = (v1->v_flags | v2->v_flags |
VF_COMPLEX) & ~ VF_REAL;
res->v_compdata = (complex *) data;
}
res->v_name = mkcname(what, v1->v_name, v2->v_name);
res->v_length = length;
/* This is a non-obvious thing */
if (v1->v_scale != v2->v_scale) {
fprintf(cp_err, "Warning: scales of %s and %s are different.\n",
v1->v_name, v2->v_name);
res->v_scale = NULL;
} else
res->v_scale = v1->v_scale;
/* Copy a few useful things */
res->v_defcolor = v1->v_defcolor;
res->v_gridtype = v1->v_gridtype;
res->v_plottype = v1->v_plottype;
/* Copy dimensions. */
if (v1->v_numdims > v2->v_numdims) {
res->v_numdims = v1->v_numdims;
for (i = 0; i < v1->v_numdims; i++)
res->v_dims[i] = v1->v_dims[i];
} else {
res->v_numdims = v2->v_numdims;
for (i = 0; i < v2->v_numdims; i++)
res->v_dims[i] = v2->v_dims[i];
}
/* This depends somewhat on what the operation is. XXX Should fix */
res->v_type = v1->v_type;
vec_new(res);
/* Free the temporary data areas we used, if we allocated any. */
if (free1) {
if (isreal(v1)) {
tfree(d1);
} else {
tfree(c1);
}
}
if (free2) {
if (isreal(v2)) {
tfree(d2);
} else {
tfree(c2);
}
}
return (res);
}
/* The binary operations. */
struct dvec *
op_plus(struct pnode *arg1, struct pnode *arg2)
{
@ -476,6 +690,11 @@ apply_func(struct func *func, struct pnode *arg)
}
(void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);
#if 0
/* FIXME: The call to (*func->fu_func) has too many arguments;
hence the compiler quits. How to circumvent this (without
losing function prototypes)? For now, these functions have
been disabled. */
if (eq(func->fu_name, "interpolate")
|| eq(func->fu_name, "deriv")) /* Ack */
{
@ -487,13 +706,16 @@ apply_func(struct func *func, struct pnode *arg)
v->v_length, &len, &type,
v->v_plot, plot_cur, v->v_dims[0]));
} else {
#endif
data = ((*func->fu_func) ((isreal(v) ? (void *)
v->v_realdata :
(void *) v->v_compdata),
(short) (isreal(v) ? VF_REAL :
VF_COMPLEX),
v->v_length, &len, &type));
#if 0
}
#endif
/* Back to normal */
(void) signal(SIGILL, SIG_DFL);
@ -586,215 +808,3 @@ mkcname(char what, char *v1, char *v2)
return (s);
}
/* Operate on two vectors, and return a third with the data, length, and flags
* fields filled in. Add it to the current plot and get rid of the two args.
*/
static struct dvec *
doop(char what, void*(*func) (/* ??? */), struct pnode *arg1,
struct pnode *arg2)
{
struct dvec *v1, *v2, *res;
complex *c1, *c2, lc;
double *d1, *d2, ld;
int length, i;
void *data;
bool free1 = FALSE, free2 = FALSE, relflag = FALSE;
v1 = ft_evaluate(arg1);
v2 = ft_evaluate(arg2);
if (!v1 || !v2)
return (NULL);
/* Now the question is, what do we do when one or both of these
* has more than one vector? This is definitely not a good
* thing. For the time being don't do anything.
*/
if (v1->v_link2 || v2->v_link2) {
fprintf(cp_err, "Warning: no operations on wildcards yet.\n");
if (v1->v_link2 && v2->v_link2)
fprintf(cp_err, "\t(You couldn't do that one anyway)\n");
return (NULL);
}
/* How do we handle operations on multi-dimensional vectors?
* For now, we only allow operations between one-D vectors,
* equivalently shaped multi-D vectors, or a multi-D vector and
* a one-D vector. It's not at all clear what to do in the other cases.
* So only check shape requirement if its an operation between two multi-D
* arrays.
*/
if ((v1->v_numdims > 1) && (v2->v_numdims > 1)) {
if (v1->v_numdims != v2->v_numdims) {
fprintf(cp_err,
"Warning: operands %s and %s have incompatible shapes.\n",
v1->v_name, v2->v_name);
return (NULL);
}
for (i = 1; i < v1->v_numdims; i++) {
if ((v1->v_dims[i] != v2->v_dims[i])) {
fprintf(cp_err,
"Warning: operands %s and %s have incompatible shapes.\n",
v1->v_name, v2->v_name);
return (NULL);
}
}
}
/* This is a bad way to do this. */
switch (what) {
case '=':
case '>':
case '<':
case 'G':
case 'L':
case 'N':
case '&':
case '|':
case '~':
relflag = TRUE;
}
/* Don't bother to do type checking. Maybe this should go in at
* some point.
*/
/* Make sure we have data of the same length. */
length = ((v1->v_length > v2->v_length) ? v1->v_length : v2->v_length);
if (v1->v_length < length) {
free1 = TRUE;
if (isreal(v1)) {
ld = 0.0;
d1 = (double *) tmalloc(length * sizeof (double));
for (i = 0; i < v1->v_length; i++)
d1[i] = v1->v_realdata[i];
if (length > 0)
ld = v1->v_realdata[v1->v_length - 1];
for ( ; i < length; i++)
d1[i] = ld;
} else {
realpart(&lc) = 0.0;
imagpart(&lc) = 0.0;
c1 = (complex *) tmalloc(length * sizeof (complex));
for (i = 0; i < v1->v_length; i++)
c1[i] = v1->v_compdata[i];
if (length > 0)
lc = v1->v_compdata[v1->v_length - 1];
for ( ; i < length; i++)
c1[i] = lc;
}
} else
if (isreal(v1))
d1 = v1->v_realdata;
else
c1 = v1->v_compdata;
if (v2->v_length < length) {
free2 = TRUE;
if (isreal(v2)) {
ld = 0.0;
d2 = (double *) tmalloc(length * sizeof (double));
for (i = 0; i < v2->v_length; i++)
d2[i] = v2->v_realdata[i];
if (length > 0)
ld = v2->v_realdata[v2->v_length - 1];
for ( ; i < length; i++)
d2[i] = ld;
} else {
realpart(&lc) = 0.0;
imagpart(&lc) = 0.0;
c2 = (complex *) tmalloc(length * sizeof (complex));
for (i = 0; i < v2->v_length; i++)
c2[i] = v2->v_compdata[i];
if (length > 0)
lc = v2->v_compdata[v1->v_length - 1];
for ( ; i < length; i++)
c2[i] = lc;
}
} else
if (isreal(v2))
d2 = v2->v_realdata;
else
c2 = v2->v_compdata;
/* Some of the math routines generate SIGILL if the argument is
* out of range. Catch this here.
*/
if (setjmp(matherrbuf)) {
return (NULL);
}
(void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);
/* Now pass the vectors to the appropriate function. */
data = ((*func) ((isreal(v1) ? (void *) d1 : (void *) c1),
(isreal(v2) ? (void *) d2 : (void *) c2),
(isreal(v1) ? VF_REAL : VF_COMPLEX),
(isreal(v2) ? VF_REAL : VF_COMPLEX),
length));
/* Back to normal */
(void) signal(SIGILL, SIG_DFL);
if (!data)
return (NULL);
/* Make up the new vector. */
res = alloc(struct dvec);
ZERO(res,struct dvec);
if (relflag || (isreal(v1) && isreal(v2) && (func != cx_comma))) {
res->v_flags = (v1->v_flags | v2->v_flags |
VF_REAL) & ~ VF_COMPLEX;
res->v_realdata = (double *) data;
} else {
res->v_flags = (v1->v_flags | v2->v_flags |
VF_COMPLEX) & ~ VF_REAL;
res->v_compdata = (complex *) data;
}
res->v_name = mkcname(what, v1->v_name, v2->v_name);
res->v_length = length;
/* This is a non-obvious thing */
if (v1->v_scale != v2->v_scale) {
fprintf(cp_err, "Warning: scales of %s and %s are different.\n",
v1->v_name, v2->v_name);
res->v_scale = NULL;
} else
res->v_scale = v1->v_scale;
/* Copy a few useful things */
res->v_defcolor = v1->v_defcolor;
res->v_gridtype = v1->v_gridtype;
res->v_plottype = v1->v_plottype;
/* Copy dimensions. */
if (v1->v_numdims > v2->v_numdims) {
res->v_numdims = v1->v_numdims;
for (i = 0; i < v1->v_numdims; i++)
res->v_dims[i] = v1->v_dims[i];
} else {
res->v_numdims = v2->v_numdims;
for (i = 0; i < v2->v_numdims; i++)
res->v_dims[i] = v2->v_dims[i];
}
/* This depends somewhat on what the operation is. XXX Should fix */
res->v_type = v1->v_type;
vec_new(res);
/* Free the temporary data areas we used, if we allocated any. */
if (free1) {
if (isreal(v1)) {
tfree(d1);
} else {
tfree(c1);
}
}
if (free2) {
if (isreal(v2)) {
tfree(d2);
} else {
tfree(c2);
}
}
return (res);
}

View File

@ -3,8 +3,11 @@
* 1999 E. Rouat
************/
#ifndef EVALUATE_H_INCLUDED
#define EVALUATE_H_INCLUDED
#ifndef _EVALUATE_H
#define _EVALUATE_H
#include <dvec.h>
#include <pnode.h>
struct dvec * ft_evaluate(struct pnode *node);
struct dvec * op_plus(struct pnode *arg1, struct pnode *arg2);

Some files were not shown because too many files have changed in this diff Show More