2003-12-03 Stefan Jones <stefan.jones@multigig.com>
* configure.in: Change to version 0.2.15 2003-10-31 Stuart Brorson <sdb@cloud9.net> * Integrated readline into ngspice CLI. Code was shamelessly stolen from http://www.btae.mam.gov.tr/~genc/ngspice/ & reworked by SDB. * Fixed makefiles in src/xspice/icm and src/xspice/cmpp to make distclean without barfing.
This commit is contained in:
parent
126a96e4d3
commit
6ee5f43039
13
ChangeLog
13
ChangeLog
|
|
@ -1,3 +1,16 @@
|
|||
2003-12-03 Stefan Jones <stefan.jones@multigig.com>
|
||||
|
||||
* configure.in:
|
||||
Change to version 0.2.15
|
||||
|
||||
2003-10-31 Stuart Brorson <sdb@cloud9.net>
|
||||
|
||||
* Integrated readline into ngspice CLI. Code was shamelessly
|
||||
stolen from http://www.btae.mam.gov.tr/~genc/ngspice/ & reworked by SDB.
|
||||
|
||||
* Fixed makefiles in src/xspice/icm and src/xspice/cmpp to make distclean
|
||||
without barfing.
|
||||
|
||||
2003-09-30 Vera Albrecht <albrecht@danalyse.de>
|
||||
|
||||
* src/include/cktdefs.h src/spicelib/analysis/noisean.c:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
SUBDIRS = doc src man tests
|
||||
|
||||
EXTRA_DIST = FAQ acconfig.h autogen.sh NOTES contrib BUGS
|
||||
EXTRA_DIST = FAQ acconfig.h autogen.sh NOTES BUGS AUTHORS ChangeLog \
|
||||
DEVICES NEWS README README.Tcl
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \
|
||||
config.h.in config.sub configure install-sh \
|
||||
|
|
|
|||
26
configure.in
26
configure.in
|
|
@ -5,7 +5,7 @@ dnl Create a configuration header
|
|||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Initialize automake stuff
|
||||
AM_INIT_AUTOMAKE(tclspice,0.2.14)
|
||||
AM_INIT_AUTOMAKE(tclspice,0.2.15)
|
||||
|
||||
dnl --enable-ftedebug : enable frontend debug macros
|
||||
AC_ARG_ENABLE(ftedebug,
|
||||
|
|
@ -63,6 +63,11 @@ 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 --with-readline: Includes GNU readline support into CLI. Default is "yes".
|
||||
dnl exclude readline libs by saying --with-readline=no at configure time.
|
||||
AC_ARG_WITH(readline,
|
||||
[ --with-readline[=yes/no] Enable GNU readline support for CLI. Default=yes.])
|
||||
|
||||
dnl Enable maintainer commands only if requested
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
|
|
@ -429,14 +434,19 @@ if test "$enable_cluster" = "yes"; then
|
|||
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")
|
||||
)
|
||||
|
||||
dnl ---- Option to include GNU readline support in ngspice CLI ----
|
||||
if test "$with_readline" != "no"; then
|
||||
AC_MSG_RESULT(Checking for readline:)
|
||||
AC_CHECK_HEADERS([readline/readline.h readline/history.h],
|
||||
[AC_DEFINE(HAVE_GNUREADLINE)],
|
||||
[AC_MSG_ERROR(Couldn't find GNU readline headers.)])
|
||||
AC_CHECK_LIB(readline, readline,
|
||||
[LIBS="$LIBS -lreadline"],
|
||||
[AC_MSG_ERROR(Couldn't find readline libraries.)])
|
||||
else
|
||||
AC_MSG_RESULT(GNU readline disabled.)
|
||||
fi
|
||||
|
||||
AC_OUTPUT( \
|
||||
Makefile \
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ libfte_a_SOURCES = \
|
|||
terminal.h \
|
||||
variable.c \
|
||||
variable.h \
|
||||
\
|
||||
arg.c \
|
||||
arg.h \
|
||||
aspice.c \
|
||||
|
|
@ -144,8 +143,8 @@ libfte_a_SOURCES = \
|
|||
runcoms2.h \
|
||||
shyu.c \
|
||||
shyu.h \
|
||||
signal_handler.c\
|
||||
signal_handler.h\
|
||||
signal_handler.c \
|
||||
signal_handler.h \
|
||||
spec.c \
|
||||
spec.h \
|
||||
spiceif.c \
|
||||
|
|
|
|||
|
|
@ -10,6 +10,13 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
|
||||
#include "com_history.h"
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
|
||||
/* Added GNU Readline Support -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
/* static declarations */
|
||||
static wordlist * dohsubst(char *string);
|
||||
|
|
@ -346,8 +353,10 @@ cp_addhistent(int event, wordlist *wlist)
|
|||
cp_lastone->hi_next = NULL;
|
||||
cp_lastone->hi_event = event;
|
||||
cp_lastone->hi_wlist = wl_copy(wlist);
|
||||
#ifndef HAVE_GNUREADLINE
|
||||
freehist(histlength - cp_maxhistlength);
|
||||
histlength++;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -484,10 +493,38 @@ com_history(wordlist *wl)
|
|||
wl = wl->wl_next;
|
||||
rev = TRUE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* Added GNU Readline Support -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
{
|
||||
HIST_ENTRY *he;
|
||||
int i, N;
|
||||
|
||||
N = (wl == NULL) ? history_length : atoi(wl->wl_word);
|
||||
|
||||
if (N < 0) N = 0;
|
||||
if (N > history_length) N = history_length;
|
||||
|
||||
if (rev)
|
||||
for (i = history_length; i > 0 && N; --i, --N) {
|
||||
he = history_get(i);
|
||||
if (!he) return;
|
||||
fprintf(cp_out, "%d\t%s\n", i, he->line);
|
||||
}
|
||||
else
|
||||
for (i = history_length - N + 1; i <= history_length; ++i) {
|
||||
he = history_get(i);
|
||||
if (!he) return;
|
||||
fprintf(cp_out, "%d\t%s\n", i, he->line);
|
||||
}
|
||||
}
|
||||
#else
|
||||
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);
|
||||
#endif /* ifelse HAVE_GNUREADLINE */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -293,7 +293,8 @@ cp_istrue(wordlist *wl)
|
|||
void
|
||||
cp_periodic(void)
|
||||
{
|
||||
ft_setflag = ft_intrpt = FALSE;
|
||||
ft_setflag = FALSE;
|
||||
ft_intrpt = FALSE;
|
||||
ft_ckspace();
|
||||
ft_checkkids();
|
||||
vec_gc();
|
||||
|
|
|
|||
|
|
@ -3,9 +3,15 @@
|
|||
* 1999 E. Rouat
|
||||
************/
|
||||
|
||||
/* See if we have been already included */
|
||||
#ifndef DISPLAY_H_INCLUDED
|
||||
#define DISPLAY_H_INCLUDED
|
||||
|
||||
/* Include a bunch of other stuff to make display.h work */
|
||||
#include <ftedev.h>
|
||||
#include <fteinput.h>
|
||||
#include <graph.h>
|
||||
|
||||
DISPDEVICE *FindDev(char *name);
|
||||
void DevInit(void);
|
||||
int NewViewport(GRAPH *pgraph);
|
||||
|
|
@ -25,6 +31,4 @@ void SaveText(GRAPH *graph, char *text, int x, int y);
|
|||
int DevSwitch(char *devname);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* DISPLAY_H_INCLUDED */
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ static char * mkcname(char what, char *v1, char *v2);
|
|||
* be lost, but that's no great loss.
|
||||
*/
|
||||
|
||||
static jmp_buf matherrbuf;
|
||||
static sigjmp_buf matherrbuf;
|
||||
|
||||
static RETSIGTYPE
|
||||
sig_matherr(void)
|
||||
{
|
||||
fprintf(cp_err, "Error: argument out of range for math function\n");
|
||||
longjmp(matherrbuf, 1);
|
||||
siglongjmp(matherrbuf, 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -221,7 +221,7 @@ doop(char what,
|
|||
/* Some of the math routines generate SIGILL if the argument is
|
||||
* out of range. Catch this here.
|
||||
*/
|
||||
if (setjmp(matherrbuf)) {
|
||||
if (sigsetjmp(matherrbuf, 1)) {
|
||||
return (NULL);
|
||||
}
|
||||
(void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);
|
||||
|
|
@ -701,7 +701,7 @@ apply_func(struct func *func, struct pnode *arg)
|
|||
/* Some of the math routines generate SIGILL if the argument is
|
||||
* out of range. Catch this here.
|
||||
*/
|
||||
if (setjmp(matherrbuf)) {
|
||||
if (sigsetjmp(matherrbuf, 1)) {
|
||||
(void) signal(SIGILL, SIG_DFL);
|
||||
return (NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -472,6 +472,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
/* Now expand subcircuit macros. Note that we have to fix
|
||||
* the case before we do this but after we deal with the
|
||||
* commands. */
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In inp_spsource, about to expand subcircuit using inp_subcktexpand.\n");
|
||||
#endif
|
||||
if (!cp_getvar("nosubckt", VT_BOOL, (char *) &nosubckts))
|
||||
if( (deck->li_next = inp_subcktexpand(deck->li_next)) == NULL ){
|
||||
line_free(realdeck,TRUE);
|
||||
|
|
@ -486,13 +490,23 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
*/
|
||||
#ifdef XSPICE
|
||||
/* gtri - wbk - Translate all SPICE 2G6 polynomial type sources */
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In inp_spsource, about to translate SPICE 2G6 polys using ENHtranslate_poly.\n");
|
||||
#endif
|
||||
deck->li_next = ENHtranslate_poly(deck->li_next);
|
||||
|
||||
/* gtri - end - Translate all SPICE 2G6 polynomial type sources */
|
||||
#endif
|
||||
|
||||
line_free(deck->li_actual,FALSE); /* SJB - free memory used by old li_actual (if any) */
|
||||
deck->li_actual = realdeck;
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In inp_spsource, about to call inp_dodeck to load deck into ft_curckt.\n");
|
||||
#endif
|
||||
/* now call inp_dodeck, which loads deck into ft_curckt -- the current circuit. */
|
||||
inp_dodeck(deck, tt, wl_first, FALSE, options, filename);
|
||||
|
||||
|
|
@ -501,9 +515,8 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In inp_spsource, done with dodeck.\n");
|
||||
printf("In inp_spsource, done with dodeck, about to do commands.\n");
|
||||
#endif
|
||||
|
||||
/* Now that the deck is loaded, do the commands if there are any */
|
||||
if (controls) {
|
||||
for (end = wl = wl_reverse(controls); wl; wl = wl->wl_next)
|
||||
|
|
|
|||
|
|
@ -135,7 +135,10 @@ inp_readall(FILE *fp, struct line **data)
|
|||
int line = 1;
|
||||
FILE *newfp;
|
||||
|
||||
/* gtri - modify - 12/12/90 - wbk - read from mailbox if ipc enabled */
|
||||
/* Must set this to NULL or non-tilde includes segfault. -- Tim Molteno */
|
||||
/* copys = NULL; */ /* This caused a parse error with gcc 2.96. Why??? */
|
||||
|
||||
/* gtri - modify - 12/12/90 - wbk - read from mailbox if ipc enabled */
|
||||
#ifdef XSPICE
|
||||
Ipc_Status_t ipc_status;
|
||||
char ipc_buffer[1025]; /* Had better be big enough */
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include "variable.h"
|
||||
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#endif
|
||||
|
||||
static void byemesg(void);
|
||||
|
||||
void
|
||||
|
|
@ -70,8 +75,9 @@ com_quit(wordlist *wl)
|
|||
clearerr(stdin);
|
||||
*buf = 'y';
|
||||
}
|
||||
if ((*buf == 'y') || (*buf == 'Y') || (*buf == '\n'))
|
||||
if ((*buf == 'y') || (*buf == 'Y') || (*buf == '\n')) {
|
||||
byemesg();
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
|
@ -166,6 +172,18 @@ com_version(wordlist *wl)
|
|||
static void
|
||||
byemesg(void)
|
||||
{
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
extern char gnu_history_file[];
|
||||
|
||||
/* write out command history only when saying goodbye. */
|
||||
if (cp_interactive && (cp_maxhistlength > 0)) {
|
||||
stifle_history(cp_maxhistlength);
|
||||
write_history(gnu_history_file);
|
||||
}
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
printf("%s-%s done\n", ft_sim->simulator, ft_sim->version);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ cp_tildexpand(char *string)
|
|||
{
|
||||
char *result;
|
||||
|
||||
result = tilde_expand(string);
|
||||
result = tildexpand(string);
|
||||
|
||||
if (!result) {
|
||||
if (cp_nonomatch) {
|
||||
|
|
|
|||
|
|
@ -788,6 +788,8 @@ zoomin(GRAPH *graph)
|
|||
graph->commandline, fx0, fx1, fy0, fy1);
|
||||
}
|
||||
|
||||
/* don't use the following if using GNU Readline - AV */
|
||||
#ifndef HAVE_GNUREADLINE
|
||||
/* hack for Gordon Jacobs */
|
||||
/* add to history list if plothistory is set */
|
||||
if (cp_getvar("plothistory", VT_BOOL, (char *) &dummy)) {
|
||||
|
|
@ -795,6 +797,8 @@ zoomin(GRAPH *graph)
|
|||
(void) cp_addhistent(cp_event++, wl);
|
||||
}
|
||||
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
(void) cp_evloop(buf);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,13 +306,13 @@ printres(char *name)
|
|||
|
||||
#define LOG2_PAGESIZE 8
|
||||
|
||||
static jmp_buf env;
|
||||
static sigjmp_buf env;
|
||||
|
||||
static RETSIGTYPE
|
||||
fault(void)
|
||||
{
|
||||
signal(SIGSEGV, (SIGNAL_FUNCTION) fault); /* SysV style */
|
||||
longjmp(env, 1);
|
||||
siglongjmp(env, 1);
|
||||
}
|
||||
#if !defined(__MINGW32__) && !defined(__APPLE_CC__)
|
||||
static void *
|
||||
|
|
@ -342,13 +342,13 @@ baseaddr(void)
|
|||
break;
|
||||
}
|
||||
|
||||
if (setjmp(env)) {
|
||||
if (sigsetjmp(env, 1)) {
|
||||
low = at;
|
||||
continue;
|
||||
} else
|
||||
x = *at;
|
||||
|
||||
if (setjmp(env)) {
|
||||
if (sigsetjmp(env, 1)) {
|
||||
low = at;
|
||||
continue;
|
||||
} else
|
||||
|
|
|
|||
|
|
@ -203,11 +203,11 @@ dosim(char *what, wordlist *wl)
|
|||
ct->ci_inprogress = FALSE;
|
||||
}
|
||||
if (ft_curckt->ci_inprogress && eq(what, "resume")) {
|
||||
ft_setflag = TRUE;
|
||||
ft_setflag = TRUE; /* don't allow abort upon interrupt during run */
|
||||
ft_intrpt = FALSE;
|
||||
fprintf(cp_err, "Warning: resuming run in progress.\n");
|
||||
com_resume((wordlist *) NULL);
|
||||
ft_setflag = FALSE;
|
||||
ft_setflag = FALSE; /* Now allow aborts again */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +215,7 @@ dosim(char *what, wordlist *wl)
|
|||
* set a flag and let spice finish up, then control will be
|
||||
* passed back to the user.
|
||||
*/
|
||||
ft_setflag = TRUE;
|
||||
ft_setflag = TRUE; /* Don't allow abort upon interrupt during run. */
|
||||
ft_intrpt = FALSE;
|
||||
if (dofile) {
|
||||
#ifdef PARALLEL_ARCH
|
||||
|
|
|
|||
|
|
@ -18,10 +18,15 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include <signal.h>
|
||||
#include "signal_handler.h"
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* Added GNU Readline Support 11/3/97 -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
/* from spice3f4 patch to ng-spice. jmr */
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include "fteinput.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
extern jmp_buf jbuf;
|
||||
extern sigjmp_buf jbuf;
|
||||
|
||||
/* The (void) signal handlers... SIGINT is the only one that gets reset (by
|
||||
* cshpar) so it is global. They are ifdef BSD because of the sigmask
|
||||
|
|
@ -32,28 +37,43 @@ extern jmp_buf jbuf;
|
|||
|
||||
extern pid_t getpid (void);
|
||||
|
||||
/* invoke this function upon keyboard interrupt */
|
||||
RETSIGTYPE
|
||||
ft_sigintr(void)
|
||||
{
|
||||
/* fprintf (cp_err, "Received interrupt. Handling it . . . . .\n"); */
|
||||
|
||||
gr_clean();
|
||||
/* Reinstall ft_signintr as the signal handler. */
|
||||
(void) signal( SIGINT, (SIGNAL_FUNCTION) ft_sigintr );
|
||||
|
||||
(void) signal( SIGINT, (SIGNAL_FUNCTION) ft_sigintr );
|
||||
gr_clean(); /* Clean up plot window */
|
||||
|
||||
if (ft_intrpt)
|
||||
fprintf(cp_err, "Interrupt (ouch)\n");
|
||||
if (ft_intrpt) /* check to see if we're being interrupted repeatedly */
|
||||
fprintf(cp_err, "Interrupted again (ouch)\n");
|
||||
else {
|
||||
fprintf(cp_err, "Interrupt\n");
|
||||
fprintf(cp_err, "Interrupted once . . .\n");
|
||||
ft_intrpt = TRUE;
|
||||
}
|
||||
if (ft_setflag)
|
||||
return;
|
||||
/* To restore screen after an interrupt to a plot for instance
|
||||
*/
|
||||
|
||||
if (ft_setflag) {
|
||||
return; /* just return without aborting simulation if ft_setflag = TRUE */
|
||||
}
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* Clean up readline after catching signals */
|
||||
/* One or all of these might be supurfluous */
|
||||
(void) rl_free_line_state();
|
||||
(void) rl_cleanup_after_signal();
|
||||
(void) rl_reset_after_signal();
|
||||
#endif
|
||||
|
||||
/* To restore screen after an interrupt to a plot for instance */
|
||||
cp_interactive = TRUE;
|
||||
cp_resetcontrol();
|
||||
longjmp(jbuf, 1);
|
||||
cp_resetcontrol();
|
||||
|
||||
/* here we jump to the start of command processing in main() after resetting everything. */
|
||||
siglongjmp(jbuf, 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -64,7 +84,7 @@ sigfloat(int sig, int code)
|
|||
fperror("Error", code);
|
||||
rewind(cp_out);
|
||||
(void) signal( SIGFPE, (SIGNAL_FUNCTION) sigfloat );
|
||||
longjmp(jbuf, 1);
|
||||
siglongjmp(jbuf, 1);
|
||||
}
|
||||
|
||||
/* This should give a new prompt if cshpar is waiting for input. */
|
||||
|
|
@ -86,7 +106,7 @@ sigcont(void)
|
|||
{
|
||||
(void) signal(SIGTSTP, (SIGNAL_FUNCTION) sigstop);
|
||||
if (cp_cwait)
|
||||
longjmp(jbuf, 1);
|
||||
siglongjmp(jbuf, 1);
|
||||
}
|
||||
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -133,6 +133,10 @@ inp_subcktexpand(struct line *deck)
|
|||
*/
|
||||
for (c = deck; c; c = c->li_next) { /* iterate on lines in deck */
|
||||
if (prefix(start, c->li_line)) { /* if we find .subckt . . . */
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In inp_subcktexpand, found a .subckt: %s\n", c->li_line);
|
||||
#endif
|
||||
for (s = c->li_line; *s && (*s != '('); s++) /* Iterate charwise along line until ( is found */
|
||||
;
|
||||
if (*s) {
|
||||
|
|
@ -165,6 +169,10 @@ inp_subcktexpand(struct line *deck)
|
|||
|
||||
|
||||
/* doit does the actual splicing in of the .subckt . . . */
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In inp_subcktexpand, about to call doit.\n");
|
||||
#endif
|
||||
ll = doit(deck);
|
||||
|
||||
/* Now check to see if there are still subckt instances undefined... */
|
||||
|
|
@ -209,6 +217,11 @@ doit(struct line *deck)
|
|||
subs = NULL;
|
||||
submod = NULL;
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In doit, about to start first pass through deck.\n");
|
||||
#endif
|
||||
|
||||
/* First pass: xtract all the .subckts and stick pointers to them into sss. */
|
||||
for (last = deck, lc = NULL; last; ) {
|
||||
if (prefix(sbend, last->li_line)) { /* if line == .ends */
|
||||
|
|
@ -326,6 +339,11 @@ doit(struct line *deck)
|
|||
wl->wl_word = gettok(&s); /* wl->wl_word now holds name of model */
|
||||
}
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In doit, about to start second pass through deck.\n");
|
||||
#endif
|
||||
|
||||
error = 0;
|
||||
/* Second pass: do the replacements. */
|
||||
do { /* while (!error && numpasses-- && gotone) */
|
||||
|
|
@ -387,8 +405,8 @@ doit(struct line *deck)
|
|||
lcc = inp_deckcopy(sss->su_def);
|
||||
|
||||
/* Change the names of .models found in .subckts . . . */
|
||||
if (modtranslate(lcc, scname))
|
||||
devmodtranslate(lcc, scname);
|
||||
if (modtranslate(lcc, scname)) /* this translates the model name in the .model line */
|
||||
devmodtranslate(lcc, scname); /* This translates the model name on all components in the deck */
|
||||
|
||||
s = sss->su_args;
|
||||
txfree(gettok(&t)); /* Throw out the subcircuit refdes */
|
||||
|
|
@ -660,7 +678,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
|
|||
nnodes = numnodes(c->li_line);
|
||||
|
||||
while (nnodes-- > 0) {
|
||||
name = gettok(&s);
|
||||
name = gettok_node(&s);
|
||||
if (name == NULL) {
|
||||
fprintf(cp_err, "Error: too few nodes: %s\n",
|
||||
c->li_line);
|
||||
|
|
@ -695,12 +713,12 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
|
|||
printf("In translate, looking at e, f, g, h found poly\n");
|
||||
#endif
|
||||
|
||||
/* move pointer ahead of paren */
|
||||
/* move pointer ahead of ( */
|
||||
if( get_l_paren(&s) == 1 ) {
|
||||
fprintf(cp_err, "Error: no left paren after POLY %s\n",
|
||||
c->li_line);
|
||||
tfree(next_name);
|
||||
goto quit;
|
||||
fprintf(cp_err, "Error: no left paren after POLY %s\n",
|
||||
c->li_line);
|
||||
tfree(next_name);
|
||||
goto quit;
|
||||
}
|
||||
|
||||
nametofree = gettok_noparens(&s);
|
||||
|
|
@ -709,10 +727,10 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
|
|||
|
||||
/* move pointer ahead of ) */
|
||||
if( get_r_paren(&s) == 1 ) {
|
||||
fprintf(cp_err, "Error: no right paren after POLY %s\n",
|
||||
c->li_line);
|
||||
tfree(next_name);
|
||||
goto quit;
|
||||
fprintf(cp_err, "Error: no right paren after POLY %s\n",
|
||||
c->li_line);
|
||||
tfree(next_name);
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* Write POLY(dim) into buffer */
|
||||
|
|
@ -728,7 +746,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
|
|||
/* Now translate the controlling source/nodes */
|
||||
nnodes = dim * numdevs(c->li_line);
|
||||
while (nnodes-- > 0) {
|
||||
nametofree = name = gettok(&s); /* name points to the returned token */
|
||||
nametofree = name = gettok_node(&s); /* name points to the returned token */
|
||||
if (name == NULL) {
|
||||
fprintf(cp_err, "Error: too few devs: %s\n",
|
||||
c->li_line);
|
||||
|
|
@ -788,7 +806,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
|
|||
/*================= Default case ===================*/
|
||||
default: /* this section handles ordinary components */
|
||||
s = c->li_line;
|
||||
nametofree = name = gettok(&s);
|
||||
nametofree = name = gettok_node(&s); /* changed to gettok_node to handle netlists with ( , ) */
|
||||
if (!name)
|
||||
continue;
|
||||
if (!*name) {
|
||||
|
|
@ -817,7 +835,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
|
|||
nnodes = numnodes(c->li_line);
|
||||
|
||||
while (nnodes-- > 0) {
|
||||
name = gettok(&s);
|
||||
name = gettok_node(&s);
|
||||
if (name == NULL) {
|
||||
fprintf(cp_err, "Error: too few nodes: %s\n",
|
||||
c->li_line);
|
||||
|
|
@ -845,7 +863,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
|
|||
*/
|
||||
nnodes = numdevs(c->li_line);
|
||||
while (nnodes-- > 0) {
|
||||
t = name = gettok(&s);
|
||||
t = name = gettok_node(&s);
|
||||
if (name == NULL) {
|
||||
fprintf(cp_err, "Error: too few devs: %s\n",
|
||||
c->li_line);
|
||||
|
|
@ -1117,9 +1135,9 @@ numnodes(char *name)
|
|||
i = 0;
|
||||
s = buf;
|
||||
gotit = 0;
|
||||
txfree(gettok(&s)); /* Skip component name */
|
||||
txfree(gettok(&s)); /* Skip component name */
|
||||
while ((i < n) && (*s) && !gotit) {
|
||||
t = gettok(&s);
|
||||
t = gettok_node(&s); /* get nodenames . . . */
|
||||
for (wl = modnames; wl; wl = wl->wl_next)
|
||||
if (eq(t, wl->wl_word))
|
||||
gotit = 1;
|
||||
|
|
@ -1257,8 +1275,11 @@ modtranslate(struct line *deck, char *subname)
|
|||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Devmodtranslate translates ??????
|
||||
*
|
||||
* Devmodtranslate scans through the deck, and translates the
|
||||
* name of the model in a line held in a .subckt. For example:
|
||||
* before: .subckt U1 . . . .
|
||||
* Q1 c b e 2N3904
|
||||
* after: Q1 c b e U1:2N3904
|
||||
*-------------------------------------------------------------------*/
|
||||
static void
|
||||
devmodtranslate(struct line *deck, char *subname)
|
||||
|
|
@ -1270,9 +1291,14 @@ devmodtranslate(struct line *deck, char *subname)
|
|||
|
||||
for (s = deck; s; s = s->li_next) {
|
||||
t = s->li_line;
|
||||
#ifdef TRACE
|
||||
/* SDB debug stuff */
|
||||
printf("In devmodtranslate, examining line %s.\n", t);
|
||||
#endif
|
||||
|
||||
while (*t && isspace(*t))
|
||||
t++;
|
||||
c = isupper(*t) ? tolower(*t) : *t;
|
||||
c = isupper(*t) ? tolower(*t) : *t; /* set c to first char in line. . . . */
|
||||
found = FALSE;
|
||||
buffer = tmalloc(strlen(t) + strlen(subname) + 4);
|
||||
|
||||
|
|
@ -1280,17 +1306,17 @@ devmodtranslate(struct line *deck, char *subname)
|
|||
|
||||
case 'r':
|
||||
case 'c':
|
||||
name = gettok(&t);
|
||||
name = gettok(&t); /* get refdes */
|
||||
(void) sprintf(buffer,"%s ",name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* get first netname */
|
||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* get second netname */
|
||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
|
||||
if (*t) {
|
||||
if (*t) { /* if there is a model, process it. . . . */
|
||||
name = gettok(&t);
|
||||
/* Now, is this a subcircuit model? */
|
||||
for (wlsub = submod; wlsub; wlsub = wlsub->wl_next) {
|
||||
|
|
@ -1329,13 +1355,13 @@ devmodtranslate(struct line *deck, char *subname)
|
|||
break;
|
||||
|
||||
case 'd':
|
||||
name = gettok(&t);
|
||||
name = gettok(&t); /* get refdes */
|
||||
(void) sprintf(buffer,"%s ",name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* get first attached netname */
|
||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* get second attached netname */
|
||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
|
|
@ -1362,6 +1388,10 @@ devmodtranslate(struct line *deck, char *subname)
|
|||
case 'u':
|
||||
case 'j':
|
||||
case 'z':
|
||||
/* What are these devices anyway? J = JFET, W = trans line (?),
|
||||
and u = IC, but what is Z?.
|
||||
Also, why is 'U' here? A 'U' element can have an arbitrary
|
||||
number of nodes attached. . . . -- SDB. */
|
||||
name = gettok(&t);
|
||||
(void) sprintf(buffer,"%s ",name);
|
||||
name = gettok(&t);
|
||||
|
|
@ -1389,22 +1419,26 @@ devmodtranslate(struct line *deck, char *subname)
|
|||
s->li_line = buffer;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
/* Changed gettok() to gettok_node() on 12.2.2003 by SDB
|
||||
to enable parsing lines like "S1 10 11 (80,51) SLATCH1"
|
||||
which occurr in real Analog Devices SPICE models.
|
||||
*/
|
||||
case 'o': /* what is this element? -- SDB */
|
||||
case 's':
|
||||
case 'm':
|
||||
name = gettok(&t);
|
||||
name = gettok(&t); /* get refdes */
|
||||
(void) sprintf(buffer,"%s ",name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* get first attached netname */
|
||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* get second attached netname */
|
||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* get third attached netname */
|
||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* get fourth attached netname */
|
||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
|
|
@ -1428,19 +1462,19 @@ devmodtranslate(struct line *deck, char *subname)
|
|||
break;
|
||||
|
||||
case 'q':
|
||||
name = gettok(&t);
|
||||
name = gettok(&t); /* get refdes */
|
||||
(void) sprintf(buffer,"%s ",name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* get first attached netname */
|
||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* get second attached netname */
|
||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* get third attached netname */
|
||||
(void) sprintf(buffer + strlen(buffer), "%s ", name);
|
||||
tfree(name);
|
||||
name = gettok(&t);
|
||||
name = gettok_node(&t); /* this can be either a model name or a node name. */
|
||||
|
||||
/* Now, is this a subcircuit model? */
|
||||
for (wlsub = submod; wlsub; wlsub = wlsub->wl_next) {
|
||||
|
|
|
|||
|
|
@ -481,6 +481,11 @@ cp_getvar(char *name, int type, void *retval)
|
|||
{
|
||||
struct variable *v;
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("in cp_getvar, trying to get value of variable %s.\n", name);
|
||||
#endif
|
||||
|
||||
for (v = variables; v; v = v->va_next)
|
||||
if (eq(name, v->va_name))
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ Author: 1987 Jeffrey M. Hsu
|
|||
The display device structure.
|
||||
*/
|
||||
|
||||
#ifndef FTEDEV_H_INCLUDED
|
||||
#define FTEDEV_H_INCLUDED
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int minx, miny;
|
||||
|
|
@ -35,3 +39,6 @@ typedef struct {
|
|||
} DISPDEVICE;
|
||||
|
||||
extern DISPDEVICE *dispdev;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ struct timeb timebegin;
|
|||
|
||||
extern char *gettok(char **s);
|
||||
extern char *gettok_noparens(char **s);
|
||||
extern char *gettok_node(char **s);
|
||||
extern int get_l_paren(char **s);
|
||||
extern int get_r_paren(char **s);
|
||||
extern void appendc(char *s, char c);
|
||||
|
|
@ -133,7 +134,10 @@ extern int scannum(char *str);
|
|||
extern int ciprefix(register char *p, register char *s);
|
||||
extern int cieq(register char *p, register char *s);
|
||||
extern void strtolower(char *str);
|
||||
extern char *tilde_expand(char *string);
|
||||
extern char *tildexpand(char *string);
|
||||
|
||||
extern char *canonicalize_pathname(char *path);
|
||||
extern char *absolute_pathname(char *string, char *dot_path);
|
||||
|
||||
extern char *smktemp(char *id);
|
||||
|
||||
|
|
|
|||
186
src/main.c
186
src/main.c
|
|
@ -27,6 +27,7 @@
|
|||
#include <misc/getopt.h>
|
||||
#include <frontend/resource.h>
|
||||
#include <frontend/variable.h>
|
||||
#include <frontend/display.h> /* added by SDB to pick up Input() fcn */
|
||||
|
||||
/* saj xspice headers */
|
||||
#ifdef XSPICE
|
||||
|
|
@ -39,6 +40,17 @@
|
|||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* Added GNU Readline Support 11/3/97 -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
/* from spice3f4 patch to ng-spice. jmr */
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include "fteinput.h"
|
||||
|
||||
char gnu_history_file[512];
|
||||
static char *application_name;
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
#ifndef HAVE_GETRUSAGE
|
||||
#ifdef HAVE_FTIME
|
||||
#include <sys/timeb.h>
|
||||
|
|
@ -52,10 +64,11 @@ static bool ft_servermode = FALSE;
|
|||
static bool ft_batchmode = FALSE;
|
||||
|
||||
/* Frontend options */
|
||||
bool ft_intrpt = FALSE; /* Set by the (void) signal handlers. */
|
||||
bool ft_setflag = FALSE; /* Don't abort after an interrupt. */
|
||||
bool ft_intrpt = FALSE; /* Set by the (void) signal handlers. TRUE = we've been interrupted. */
|
||||
bool ft_setflag = FALSE; /* TRUE = Don't abort simulation after an interrupt. */
|
||||
char *ft_rawfile = "rawspice.raw";
|
||||
|
||||
|
||||
/* Frontend and circuit options */
|
||||
IFsimulator *ft_sim = NULL;
|
||||
|
||||
|
|
@ -73,7 +86,7 @@ struct variable *(*if_getparam)( );
|
|||
|
||||
|
||||
|
||||
jmp_buf jbuf;
|
||||
sigjmp_buf jbuf;
|
||||
|
||||
static int started = FALSE;
|
||||
|
||||
|
|
@ -100,56 +113,67 @@ extern struct comm nutcp_coms[ ];
|
|||
struct comm *cp_coms = nutcp_coms;
|
||||
static IFfrontEnd nutmeginfo;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
int
|
||||
if_run(char *t, char *w, wordlist *s, char *b)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
int
|
||||
if_sens_run(char *t, char *w, wordlist *s, char *b)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void
|
||||
if_dump(char *ckt, FILE *fp)
|
||||
{}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
char *
|
||||
if_inpdeck(struct line *deck, char **tab)
|
||||
{
|
||||
return ((char *) 0);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
int
|
||||
if_option(char *ckt, char *name, int type, char *value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void if_cktfree(char *ckt, char *tab)
|
||||
{}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void if_setndnames(char *line)
|
||||
{}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
char *
|
||||
if_errstring(int code)
|
||||
{
|
||||
return ("spice error");
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void
|
||||
if_setparam(char *ckt, char *name, char *param, struct variable *val)
|
||||
{}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
bool
|
||||
if_tranparams(struct circ *ckt, double *start, double *stop, double *step)
|
||||
{
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
struct variable *
|
||||
if_getstat(char *n, char *c)
|
||||
{
|
||||
|
|
@ -204,7 +228,7 @@ double CONSTe;
|
|||
IFfrontEnd *SPfrontEnd = NULL;
|
||||
int DEVmaxnum = 0;
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator)
|
||||
{
|
||||
#ifdef SIMULATOR
|
||||
|
|
@ -225,6 +249,7 @@ int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator)
|
|||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Shutdown gracefully. */
|
||||
int
|
||||
shutdown(int exitval)
|
||||
|
|
@ -240,6 +265,87 @@ shutdown(int exitval)
|
|||
exit (exitval);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* Adapted ../lib/cp/lexical.c:prompt() for GNU Readline -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
static char *
|
||||
prompt()
|
||||
{
|
||||
static char pbuf[128];
|
||||
char *p = pbuf, *s;
|
||||
|
||||
if (cp_interactive == FALSE)
|
||||
return;
|
||||
if (cp_promptstring == NULL)
|
||||
s = "-> ";
|
||||
else
|
||||
s = cp_promptstring;
|
||||
if (cp_altprompt)
|
||||
s = cp_altprompt;
|
||||
while (*s) {
|
||||
switch (strip(*s)) {
|
||||
case '!':
|
||||
p += sprintf(p, "%d", where_history() + 1);
|
||||
break;
|
||||
case '\\':
|
||||
if (*(s + 1))
|
||||
p += sprintf(p, "%c", strip(*++s));
|
||||
default:
|
||||
*p = strip(*s); ++p;
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*p = 0;
|
||||
return pbuf;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Process device events in Readline's hook since there is no where
|
||||
else to do it now - AV */
|
||||
int rl_event_func()
|
||||
/* called by GNU readline periodically to know what to do about keypresses */
|
||||
{
|
||||
static REQUEST reqst = { checkup_option, 0 };
|
||||
Input(&reqst, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Added GNU Readline Support -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
void app_rl_readlines()
|
||||
{
|
||||
char *line, *expanded_line;
|
||||
|
||||
/* note that we want some mechanism to detect ctrl-D and expand it to exit */
|
||||
while (1) {
|
||||
history_set_pos(history_length);
|
||||
|
||||
sigsetjmp(jbuf, 1); /* Set location to jump to after handling SIGINT (ctrl-C) */
|
||||
|
||||
line = readline(prompt());
|
||||
if (line && *line) {
|
||||
int s = history_expand(line, &expanded_line);
|
||||
|
||||
if (s == 2) {
|
||||
fprintf(stderr, "-> %s\n", expanded_line);
|
||||
} else if (s == -1) {
|
||||
fprintf(stderr, "readline: %s\n", expanded_line);
|
||||
} else {
|
||||
cp_evloop(expanded_line);
|
||||
add_history(expanded_line);
|
||||
}
|
||||
free(expanded_line);
|
||||
}
|
||||
if (line) free(line);
|
||||
}
|
||||
/* History gets written in ../fte/misccoms.c com_quit */
|
||||
}
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void
|
||||
show_help(void)
|
||||
{
|
||||
|
|
@ -261,6 +367,7 @@ show_help(void)
|
|||
"Report bugs to %s.\n", cp_program, Bug_Addr);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void
|
||||
show_version(void)
|
||||
{
|
||||
|
|
@ -273,6 +380,7 @@ show_version(void)
|
|||
" The NG-Spice Project\n", cp_program, PACKAGE, VERSION);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void
|
||||
append_to_stream(FILE *dest, FILE *source)
|
||||
{
|
||||
|
|
@ -282,6 +390,7 @@ append_to_stream(FILE *dest, FILE *source)
|
|||
while ((i = fread(buf, 1, BSIZE_SP, source)) > 0)
|
||||
fwrite(buf, i, 1, dest);
|
||||
}
|
||||
|
||||
#ifdef SIMULATOR
|
||||
extern int OUTpBeginPlot(), OUTpData(), OUTwBeginPlot(), OUTwReference();
|
||||
extern int OUTwData(), OUTwEnd(), OUTendPlot(), OUTbeginDomain();
|
||||
|
|
@ -305,6 +414,9 @@ append_to_stream(FILE *dest, FILE *source)
|
|||
};
|
||||
#endif
|
||||
|
||||
/* ======================================================= */
|
||||
/* =============== main prog begins here ================ */
|
||||
/* ======================================================= */
|
||||
int
|
||||
#ifdef HAS_WINDOWS
|
||||
xmain(int argc, char **argv)
|
||||
|
|
@ -347,9 +459,6 @@ main(int argc, char **argv)
|
|||
/* mwDoFlush(1); */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/* MFB tends to jump to 0 on errors. This tends to catch it. */
|
||||
if (started) {
|
||||
fprintf(cp_err, "main: Internal Error: jump to zero\n");
|
||||
|
|
@ -357,6 +466,13 @@ main(int argc, char **argv)
|
|||
}
|
||||
started = TRUE;
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
if (!(application_name = strrchr(argv[0],'/')))
|
||||
application_name = argv[0];
|
||||
else
|
||||
++application_name;
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
#ifdef PARALLEL_ARCH
|
||||
PBEGIN_(argc, argv);
|
||||
ARCHme = NODEID_();
|
||||
|
|
@ -401,7 +517,7 @@ main(int argc, char **argv)
|
|||
|
||||
srandom(getpid());
|
||||
|
||||
|
||||
/* --- Process command line options --- */
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
|
|
@ -498,7 +614,7 @@ main(int argc, char **argv)
|
|||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
} /* --- End of command line option processing --- */
|
||||
|
||||
|
||||
#ifdef SIMULATOR
|
||||
|
|
@ -529,7 +645,7 @@ main(int argc, char **argv)
|
|||
ft_cpinit();
|
||||
|
||||
/* To catch interrupts during .spiceinit... */
|
||||
if (setjmp(jbuf) == 1) {
|
||||
if (sigsetjmp(jbuf, 1) == 1) {
|
||||
fprintf(cp_err, "Warning: error executing .spiceinit.\n");
|
||||
if (!ft_batchmode)
|
||||
goto bot;
|
||||
|
|
@ -537,8 +653,12 @@ main(int argc, char **argv)
|
|||
|
||||
/* Set up signal handling */
|
||||
if (!ft_batchmode) {
|
||||
signal(SIGINT, ft_sigintr);
|
||||
signal(SIGFPE, sigfloat);
|
||||
/* Set up interrupt handler */
|
||||
(void) signal(SIGINT, ft_sigintr);
|
||||
|
||||
/* floating point exception */
|
||||
(void) signal(SIGFPE, sigfloat);
|
||||
|
||||
#ifdef SIGTSTP
|
||||
signal(SIGTSTP, sigstop);
|
||||
#endif
|
||||
|
|
@ -611,7 +731,7 @@ bot:
|
|||
* build a circuit for this file. If this is in server mode, don't
|
||||
* process any of these args. */
|
||||
|
||||
if (setjmp(jbuf) == 1)
|
||||
if (sigsetjmp(jbuf, 1) == 1)
|
||||
goto evl;
|
||||
|
||||
|
||||
|
|
@ -657,7 +777,7 @@ bot:
|
|||
}
|
||||
if (ft_batchmode && err)
|
||||
shutdown(EXIT_BAD);
|
||||
}
|
||||
} /* --- if (!ft_servermode && !ft_nutmeg) --- */
|
||||
|
||||
if (!gotone && ft_batchmode && !ft_nutmeg)
|
||||
inp_spsource(circuit_file, FALSE, (char *) NULL);
|
||||
|
|
@ -668,7 +788,8 @@ evl:
|
|||
* so exit. */
|
||||
bool st = FALSE;
|
||||
|
||||
(void) setjmp(jbuf);
|
||||
(void) sigsetjmp(jbuf, 1);
|
||||
|
||||
|
||||
if (st == TRUE) {
|
||||
shutdown(EXIT_BAD);
|
||||
|
|
@ -703,11 +824,34 @@ evl:
|
|||
"no simulations run\n");
|
||||
shutdown(EXIT_BAD);
|
||||
}
|
||||
} else {
|
||||
(void) setjmp(jbuf);
|
||||
} /* --- if (ft_batchmode) --- */
|
||||
else {
|
||||
cp_interactive = TRUE;
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* --- set up readline params --- */
|
||||
strcpy(gnu_history_file, getenv("HOME"));
|
||||
strcat(gnu_history_file, "/.");
|
||||
strcat(gnu_history_file, application_name);
|
||||
strcat(gnu_history_file, "_history");
|
||||
|
||||
using_history();
|
||||
read_history(gnu_history_file);
|
||||
|
||||
rl_readline_name = application_name;
|
||||
rl_instream = cp_in;
|
||||
rl_outstream = cp_out;
|
||||
rl_event_hook = rl_event_func;
|
||||
rl_catch_signals = 0; /* disable readline signal handling */
|
||||
rl_catch_sigwinch = 1; /* allow readline to respond to resized windows */
|
||||
|
||||
/* Here's where we enter the command processing loop */
|
||||
app_rl_readlines();
|
||||
#else
|
||||
while (cp_evloop((char *) NULL) == 1) ;
|
||||
}
|
||||
#endif /* ifelse HAVE_GNUREADLINE */
|
||||
|
||||
} /* --- else (if (ft_batchmode)) --- */
|
||||
|
||||
#else /* ~ SIMULATOR */
|
||||
|
||||
|
|
@ -722,7 +866,7 @@ evl:
|
|||
|
||||
evl:
|
||||
/* Nutmeg "main" */
|
||||
(void) setjmp(jbuf);
|
||||
(void) sigsetjmp(jbuf, 1);
|
||||
cp_interactive = TRUE;
|
||||
while (cp_evloop((char *) NULL) == 1) ;
|
||||
|
||||
|
|
@ -731,3 +875,7 @@ evl:
|
|||
shutdown(EXIT_NORMAL);
|
||||
return EXIT_NORMAL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,9 @@ libmisc_a_SOURCES = \
|
|||
tilde.h \
|
||||
misc_time.c \
|
||||
misc_time.h \
|
||||
wlist.c
|
||||
wlist.c \
|
||||
util.c \
|
||||
util.h
|
||||
|
||||
## Note that the getopt files get compiled unconditionnaly but some
|
||||
## magic #define away the body of their own code if the compilation environment
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ ivars(void)
|
|||
env_overr(&Spice_Exec_Dir, "SPICE_EXEC_DIR");
|
||||
env_overr(&Spice_Lib_Dir, "SPICE_LIB_DIR");
|
||||
|
||||
|
||||
mkvar(&News_File, Spice_Lib_Dir, "news", "SPICE_NEWS");
|
||||
mkvar(&Default_MFB_Cap, Spice_Lib_Dir, "mfbcap", "SPICE_MFBCAP");
|
||||
mkvar(&Help_Path, Spice_Lib_Dir, "helpdir", "SPICE_HELP_DIR");
|
||||
|
|
|
|||
|
|
@ -131,6 +131,13 @@ strtolower(char *str)
|
|||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* gettok skips over whitespace and returns the next token found. This is
|
||||
* the original version. It does not "do the right thing" when you have
|
||||
* parens or commas anywhere in the nodelist. Note that I left this unmodified
|
||||
* since I didn't want to break any fcns which called it from elsewhere than
|
||||
* subckt.c. -- SDB 12.3.2003.
|
||||
*-------------------------------------------------------------------------*/
|
||||
char *
|
||||
gettok(char **s)
|
||||
{
|
||||
|
|
@ -161,9 +168,10 @@ gettok(char **s)
|
|||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* gettok_noparens was added by SDB on 4.21.2003.
|
||||
* It acts like gettok, except that it stops parsing when it hits a paren
|
||||
* (i.e. it treats parens like whitespace). It is used in translate (subckt.c)
|
||||
* while looking for the POLY token.
|
||||
* It acts like gettok, except that it treats parens and commas like
|
||||
* whitespace while looking for the POLY token. That is, it stops
|
||||
* parsing and returns when it finds one of those chars. It is called from
|
||||
* 'translate' (subckt.c).
|
||||
*-------------------------------------------------------------------------*/
|
||||
char *
|
||||
gettok_noparens(char **s)
|
||||
|
|
@ -172,24 +180,78 @@ gettok_noparens(char **s)
|
|||
int i = 0;
|
||||
char c;
|
||||
|
||||
while (isspace(**s))
|
||||
(*s)++;
|
||||
while ( isspace(**s) )
|
||||
(*s)++; /* iterate over whitespace */
|
||||
|
||||
if (!**s)
|
||||
return (NULL);
|
||||
while ((c = **s) && !isspace(c) &&
|
||||
( **s != '(' ) && ( **s != ')' ) ) {
|
||||
return (NULL); /* return NULL if we come to end of line */
|
||||
|
||||
while ((c = **s) &&
|
||||
!isspace(c) &&
|
||||
( **s != '(' ) &&
|
||||
( **s != ')' ) &&
|
||||
( **s != ',')
|
||||
) {
|
||||
buf[i++] = *(*s)++;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
while (isspace(**s))
|
||||
(*s)++;
|
||||
|
||||
/* Now iterate up to next non-whitespace char */
|
||||
while ( isspace(**s) )
|
||||
(*s)++;
|
||||
|
||||
return (copy(buf));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* gettok_node was added by SDB on 12.3.2003
|
||||
* It acts like gettok, except that it treats parens and commas like
|
||||
* whitespace (i.e. it ignores them). Use it when parsing through netnames
|
||||
* (node names) since they may be grouped using ( , ).
|
||||
*-------------------------------------------------------------------------*/
|
||||
char *
|
||||
gettok_node(char **s)
|
||||
{
|
||||
char buf[BSIZE_SP];
|
||||
int i = 0;
|
||||
char c;
|
||||
|
||||
while (isspace(**s) ||
|
||||
( **s == '(' ) ||
|
||||
( **s == ')' ) ||
|
||||
( **s == ',')
|
||||
)
|
||||
(*s)++; /* iterate over whitespace and ( , ) */
|
||||
|
||||
if (!**s)
|
||||
return (NULL); /* return NULL if we come to end of line */
|
||||
|
||||
while ((c = **s) &&
|
||||
!isspace(c) &&
|
||||
( **s != '(' ) &&
|
||||
( **s != ')' ) &&
|
||||
( **s != ',')
|
||||
) { /* collect chars until whitespace or ( , ) */
|
||||
buf[i++] = *(*s)++;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
|
||||
/* Now iterate up to next non-whitespace char */
|
||||
while (isspace(**s) ||
|
||||
( **s == '(' ) ||
|
||||
( **s == ')' ) ||
|
||||
( **s == ',')
|
||||
)
|
||||
(*s)++; /* iterate over whitespace and ( , ) */
|
||||
|
||||
return (copy(buf));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* get_l_paren iterates the pointer forward in a string until it hits
|
||||
* the position after the next left paren "(". It returns 0 if it found a left
|
||||
* paren, and 1 if no left paren is found.
|
||||
* paren, and 1 if no left paren is found. It is called from 'translate'
|
||||
* (subckt.c).
|
||||
*-------------------------------------------------------------------------*/
|
||||
int
|
||||
get_l_paren(char **s)
|
||||
|
|
@ -211,7 +273,8 @@ get_l_paren(char **s)
|
|||
/*-------------------------------------------------------------------------*
|
||||
* get_r_paren iterates the pointer forward in a string until it hits
|
||||
* the position after the next right paren ")". It returns 0 if it found a right
|
||||
* paren, and 1 if no right paren is found.
|
||||
* paren, and 1 if no right paren is found. It is called from 'translate'
|
||||
* (subckt.c).
|
||||
*-------------------------------------------------------------------------*/
|
||||
int
|
||||
get_r_paren(char **s)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/**********
|
||||
Copyright 1991 Regents of the University of California. All rights reserved.
|
||||
Modified: 2002 R. Oktas, <roktas@omu.edu.tr>
|
||||
**********/
|
||||
|
||||
#include <config.h>
|
||||
|
|
@ -15,15 +16,22 @@ Copyright 1991 Regents of the University of California. All rights reserved.
|
|||
#endif
|
||||
|
||||
|
||||
/* XXX To prevent a name collision with `readline's `tilde_expand',
|
||||
the original name: `tilde_expand' has changed to `tildexpand'. This
|
||||
situation naturally brings to mind that `tilde_expand' could be used
|
||||
directly from `readline' (since it will already be included if we
|
||||
wish to activate the `readline' support). Following implementation of
|
||||
'tilde expanding' has some problems which constitutes another good
|
||||
reason why it should be replaced: eg. it returns NULL which should
|
||||
not behave this way, IMHO. Anyway... Don't care for the moment, may
|
||||
be in the future. -- ro */
|
||||
|
||||
|
||||
char *
|
||||
tilde_expand(char *string)
|
||||
tildexpand(char *string)
|
||||
{
|
||||
#ifdef HAVE_PWD_H
|
||||
struct passwd *pw;
|
||||
/*extern struct passwd *getpwuid( );*/
|
||||
char buf[BSIZE_SP];
|
||||
char *k, c;
|
||||
char buf[BSIZE_SP];
|
||||
char *result, *k, c;
|
||||
|
||||
if (!string)
|
||||
return NULL;
|
||||
|
|
@ -37,26 +45,43 @@ tilde_expand(char *string)
|
|||
string += 1;
|
||||
|
||||
if (!*string || *string == '/') {
|
||||
pw = getpwuid(getuid());
|
||||
*buf = 0;
|
||||
/* First try the environment setting. May also make life easier
|
||||
for non-unix platforms, eg. MS-DOS. -- ro */
|
||||
result = getenv("HOME");
|
||||
#ifdef HAVE_PWD_H
|
||||
/* Can't find a result from the environment, let's try
|
||||
the other stuff. -- ro */
|
||||
if (!result) {
|
||||
struct passwd *pw;
|
||||
pw = getpwuid(getuid());
|
||||
if (pw)
|
||||
result = pw->pw_dir;
|
||||
*buf = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
struct passwd *pw;
|
||||
k = buf;
|
||||
while ((c = *string) && c != '/')
|
||||
*k++ = c, string++;
|
||||
*k = 0;
|
||||
pw = getpwnam(buf);
|
||||
if (pw)
|
||||
result = pw->pw_dir;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (pw) {
|
||||
strcpy(buf, pw->pw_dir);
|
||||
if (result) {
|
||||
#ifdef HAVE_PWD_H
|
||||
strcpy(buf, result);
|
||||
if (*string)
|
||||
strcat(buf, string);
|
||||
return copy(buf);
|
||||
|
||||
} else
|
||||
return NULL;
|
||||
|
||||
return copy(buf);
|
||||
|
||||
#else
|
||||
return copy(string);
|
||||
/* Emulate the old behavior to prevent side effects. -- ro */
|
||||
return copy(string);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#ifndef TILDE_H_INCLUDED
|
||||
#define TILDE_H_INCLUDED
|
||||
|
||||
char * tilde_expand(char *string);
|
||||
char * tildexpand(char *string);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ char *Bug_Addr = "";
|
|||
char *Spice_Host = "";
|
||||
char *Spiced_Log = "";
|
||||
|
||||
|
||||
/* dummy declaration so CP.a doesn't pull in lexical.o and other objects */
|
||||
bool cp_interactive = FALSE;
|
||||
|
||||
|
|
@ -110,5 +111,5 @@ cp_getvar(char *n, int t, void *r)
|
|||
char *
|
||||
cp_tildexpand(char *s)
|
||||
{
|
||||
return tilde_expand(s);
|
||||
return tildexpand(s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ Author: 1990 Jaijeet Roychowdury
|
|||
|
||||
#undef DEBUG_LEVEL1
|
||||
|
||||
/* `-u' option showing the usage help is changed to `-h'. -- ro */
|
||||
|
||||
extern void usage();
|
||||
extern void comments();
|
||||
|
|
@ -102,7 +103,7 @@ int
|
|||
use_opt = 1;
|
||||
gotnum=1;
|
||||
break;
|
||||
case 'u':
|
||||
case 'h':
|
||||
usage(pname);
|
||||
exit(1);
|
||||
break;
|
||||
|
|
@ -350,7 +351,7 @@ fprintf(stderr,"Usage: %s -l<line-inductance> -c<line-capacitance>\n",argv[0]);
|
|||
fprintf(stderr," -r<line-resistance> -g<line-conductance> \n");
|
||||
fprintf(stderr," -k<inductive coeff. of coupling> \n");
|
||||
fprintf(stderr," -x<line-to-line capacitance> -o<subckt-name> \n");
|
||||
fprintf(stderr," -n<number of conductors> -L<length> -u\n");
|
||||
fprintf(stderr," -n<number of conductors> -L<length> -h\n");
|
||||
fprintf(stderr,"Example: %s -n4 -l9e-9 -c20e-12 -r5.3 -x5e-12 -k0.7 -otest -L5.4\n\n",argv[0]);
|
||||
|
||||
fprintf(stderr,"See \"Efficient Transient Simulation of Lossy Interconnect\",\n");
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
/* To interupt a spice run */
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
extern jmp_buf jbuf;
|
||||
extern sigjmp_buf jbuf;
|
||||
|
||||
/*Included for the module to access data*/
|
||||
#include <dvec.h>
|
||||
|
|
@ -433,7 +433,7 @@ static int _run(int argc,char **argv){
|
|||
|
||||
/* Catch Ctrl-C to break simulations */
|
||||
oldHandler = signal(SIGINT,ft_sigintr);
|
||||
if(setjmp(jbuf)!=0) {
|
||||
if(sigsetjmp(jbuf, 1)!=0) {
|
||||
signal(SIGINT,oldHandler);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
|
@ -1481,7 +1481,7 @@ int Spice_Init(Tcl_Interp *interp) {
|
|||
/* Read the user config files */
|
||||
/* To catch interrupts during .spiceinit... */
|
||||
old_sigint = signal(SIGINT, ft_sigintr);
|
||||
if (setjmp(jbuf) == 1) {
|
||||
if (sigsetjmp(jbuf, 1) == 1) {
|
||||
fprintf(cp_err, "Warning: error executing .spiceinit.\n");
|
||||
goto bot;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,3 +118,20 @@ makedefs: $(srcdir)/makedefs.in $(top_builddir)/config.status
|
|||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
# Hack by SDB to enable "make mrproper" from top level.
|
||||
# Since there is no Makefile.am for this directory, we need to
|
||||
# incorporate this stuff by hand.
|
||||
MAINTAINERCLEANFILES =
|
||||
|
||||
maintainer-clean: maintainer-clean-generic
|
||||
rm -f `find . -type f -name "*~" -print`
|
||||
rm -f `find . -type f -name "*.orig" -print`
|
||||
rm -f `find . -type f -name "*.rej" -print`
|
||||
rm -fR `find . -type d -name ".deps" -print`
|
||||
|
||||
maintainer-clean-generic: clean
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue