tclspice 0.2.7 import
This commit is contained in:
parent
0a5432d1eb
commit
2c0986a169
75
AUTHORS
75
AUTHORS
|
|
@ -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>.
|
||||
|
|
|
|||
|
|
@ -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
235
ChangeLog
|
|
@ -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
167
DEVICES
|
|
@ -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
530
FAQ
|
|
@ -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.
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
224
NEWS
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
69
README
|
|
@ -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)
|
||||
|
|
|
|||
24
acconfig.h
24
acconfig.h
|
|
@ -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
|
||||
|
|
|
|||
28
autogen.sh
28
autogen.sh
|
|
@ -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."
|
||||
|
||||
|
|
|
|||
329
configure.in
329
configure.in
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
-------------------------------
|
||||
MW. 01-10-2000
|
||||
Bugs Fixes -
|
||||
-----------
|
||||
.subckt inside another parametrized .subckt works right now.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Version 0.11 January 2, 1996
|
||||
----------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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($_);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
861
doc/ngspice.texi
861
doc/ngspice.texi
File diff suppressed because it is too large
Load Diff
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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.
|
||||
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
213
src/Makefile.am
213
src/Makefile.am
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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@
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _COM_AHELP_H
|
||||
#define _COM_AHELP_H
|
||||
|
||||
|
||||
void com_ahelp(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _COM_ASCIIPLOT_H
|
||||
#define _COM_ASCIIPLOT_H
|
||||
|
||||
void com_asciiplot(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _COM_CDUMP_H
|
||||
#define _COM_CDUMP_H
|
||||
|
||||
void com_cdump(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
#ifndef _COM_COMPOSE_H
|
||||
#define _COM_COMPOSE_H
|
||||
|
||||
#include <wordlist.h>
|
||||
|
||||
|
||||
void com_compose(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _COM_DISPLAY_H
|
||||
#define _COM_DISPLAY_H
|
||||
|
||||
#include <wordlist.h>
|
||||
|
||||
void com_display(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _COM_DUMP_H
|
||||
#define _COM_DUMP_H
|
||||
|
||||
void com_dump(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _COM_GHELP_H
|
||||
#define _COM_GHELP_H
|
||||
|
||||
|
||||
void com_ghelp(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _COM_HARDCOPY_H
|
||||
#define _COM_HARDCOPY_H
|
||||
|
||||
|
||||
void com_hardcopy(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _COM_HELP_H
|
||||
#define _COM_HELP_H
|
||||
|
||||
|
||||
void com_help(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _COM_LET_H
|
||||
#define _COM_LET_H
|
||||
|
||||
#include <wordlist.h>
|
||||
|
||||
void com_let(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _COM_OPTION_H
|
||||
#define _COM_OPTION_H
|
||||
|
||||
void com_option(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _COM_SET_H
|
||||
#define _COM_SET_H
|
||||
|
||||
void com_set(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef _COM_SETSCALE_H
|
||||
#define _COM_SETSCALE_H
|
||||
|
||||
#include <wordlist.h>
|
||||
|
||||
|
||||
void com_setscale(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _COM_STATE_H
|
||||
#define _COM_STATE_H
|
||||
|
||||
void com_state(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _COM_STRCMP_H
|
||||
#define _COM_STRCMP_H
|
||||
|
||||
|
||||
void com_strcmp(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _COM_XGRAPH_H
|
||||
#define _COM_XGRAPH_H
|
||||
|
||||
void com_xgraph(wordlist *wl);
|
||||
|
||||
#endif
|
||||
|
|
@ -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 }
|
||||
|
||||
} ;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _COMMANDS_H
|
||||
#define _COMMANDS_H
|
||||
|
||||
|
||||
extern struct comm spcp_coms[];
|
||||
extern struct comm nutcp_coms[];
|
||||
|
||||
#endif
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue