Applied Stuart's 12-03-2003 patch. Support for readline (disabled) and for node names in the form (x,y).
This commit is contained in:
parent
4fa3c84d99
commit
b03a70760b
16
ChangeLog
16
ChangeLog
|
|
@ -1,9 +1,23 @@
|
|||
2004-01-10 Paolo Nenzi <p.nenzi@ieee.org>
|
||||
|
||||
* configure.in: changed version to rework-15pre2.
|
||||
|
||||
* src/frontend/{com_history.c, cpitf.c, display.h, evaluate.c,
|
||||
inpcom.c, misccoms.c, parser/glob.c, plotting/x11.c, resource.c,
|
||||
runcoms.c, signal_handler.c, subckt.c, variable.c}
|
||||
src/include/{ftedev.h, ngspice.h}
|
||||
src/misc{ivars.c, Makefile.am, string.c, tilde.c, tilde.h, util.c,
|
||||
util.h}
|
||||
src/{main.c, nghelp.c, ngmultidec.c}
|
||||
configure.in:
|
||||
|
||||
Applied Stuart's patch tclspice-0.2.14_12-03-2003.diff.gz but
|
||||
with libreadline disabled by default. (Stuart Brorson
|
||||
<sdb@cloud9.net>).
|
||||
|
||||
* Fixed makefiles in src/xspice/icm and src/xspice/cmpp to make
|
||||
distclean without barfing. (Stuart Brorson <sdb@cloud9.net>).
|
||||
|
||||
|
||||
* configure.in
|
||||
src/xspice/cmpp/Makefile src/xspice/cmpp/Makefile.in:
|
||||
Make configure automatically set paths for lex yacc and
|
||||
|
|
|
|||
28
configure.in
28
configure.in
|
|
@ -9,7 +9,7 @@ dnl Create a configuration header
|
|||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Initialize automake stuff
|
||||
AM_INIT_AUTOMAKE(ng-spice-rework,15pre1)
|
||||
AM_INIT_AUTOMAKE(ng-spice-rework,15pre2)
|
||||
|
||||
|
||||
dnl --enable-ansi : try to force --ansi option to the compiler
|
||||
|
|
@ -116,6 +116,12 @@ dnl --enable-numparams: define NUMPARAMS in the code. This is for .param support
|
|||
AC_ARG_ENABLE(numparam,
|
||||
[ --enable-numparam Enable numparams library support, experimental *not in standard distribution*])
|
||||
|
||||
dnl --with-readline: Includes GNU readline support into CLI. Default is "no".
|
||||
dnl Including readline into ngspice is a violation of GPL license. It's use
|
||||
dnl is discouraged.
|
||||
AC_ARG_WITH(readline,
|
||||
[ --with-readline[=yes/no] Enable GNU readline support for CLI. Default=no.])
|
||||
|
||||
dnl Enable maintainer commands only if requested
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
|
|
@ -495,13 +501,19 @@ fi
|
|||
AC_SUBST(NUMPARAMDIR)
|
||||
AC_SUBST(NUMPARAMLIB)
|
||||
|
||||
dnl --with-readline : the user wants to use readline library
|
||||
AC_ARG_WITH(readline,
|
||||
[ --with-readline Use the readline library. WARNING: breaks GPL license],
|
||||
AC_MSG_RESULT(Checking for 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" != "yes"; then
|
||||
AC_MSG_RESULT(GNU readline disabled.)
|
||||
|
||||
else
|
||||
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.)])
|
||||
fi
|
||||
|
||||
AC_OUTPUT( \
|
||||
Makefile \
|
||||
|
|
|
|||
|
|
@ -353,10 +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
|
||||
#ifndef HAVE_GNUREADLINE
|
||||
freehist(histlength - cp_maxhistlength);
|
||||
histlength++;
|
||||
#endif
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -493,36 +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;
|
||||
HIST_ENTRY *he;
|
||||
int i, N;
|
||||
|
||||
N = (wl == NULL) ? history_length : atoi(wl->wl_word);
|
||||
N = (wl == NULL) ? history_length : atoi(wl->wl_word);
|
||||
|
||||
if (N < 0) N = 0;
|
||||
if (N > history_length) N = history_length;
|
||||
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);
|
||||
}
|
||||
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
|
||||
#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 */
|
||||
#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,5 @@ void SaveText(GRAPH *graph, char *text, int x, int y);
|
|||
int DevSwitch(char *devname);
|
||||
|
||||
|
||||
#endif /* DISPLAY_H_INCLUDED */
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -296,7 +296,7 @@ doop(char what,
|
|||
tfree(c2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* va: garbage collection */
|
||||
if (arg1->pn_value==NULL && v1!=NULL) vec_free(v1);
|
||||
if (arg2->pn_value==NULL && v2!=NULL) vec_free(v2);
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,11 +131,14 @@ inp_readall(FILE *fp, struct line **data)
|
|||
struct line *end = NULL, *cc = NULL, *prev = NULL, *working, *newcard;
|
||||
char *buffer, *s, *t, c;
|
||||
/* segfault fix */
|
||||
char *copys = NULL;
|
||||
char *copys=NULL;
|
||||
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 */
|
||||
|
|
@ -172,7 +175,7 @@ inp_readall(FILE *fp, struct line **data)
|
|||
/* gtri - end - 12/12/90 */
|
||||
#else
|
||||
while ((buffer = readline(fp))) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
|
|
@ -185,12 +188,15 @@ inp_readall(FILE *fp, struct line **data)
|
|||
|| (strcmp(buffer,"\r\n") == 0) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (*buffer == '@') {
|
||||
tfree(buffer); /* was allocated by readline() */
|
||||
break;
|
||||
}
|
||||
/* loop through 'buffer' until end is reached. Then test for
|
||||
|
||||
|
||||
/* loop through 'buffer' until end is reached. Then test for
|
||||
premature end. If premature end is reached, spew
|
||||
error and zap the line. */
|
||||
for (s = buffer; *s && (*s != '\n'); s++);
|
||||
|
|
@ -201,21 +207,21 @@ inp_readall(FILE *fp, struct line **data)
|
|||
|
||||
if(*(s-1) == '\r') /* Zop the carriage return under windows */
|
||||
*(s-1) = '\0';
|
||||
|
||||
|
||||
/* now handle .include statements */
|
||||
if (ciprefix(".include", buffer)) {
|
||||
for (s = buffer; *s && !isspace(*s); s++)/* advance past non-space chars */
|
||||
for (s = buffer; *s && !isspace(*s); s++) /* advance past non-space chars */
|
||||
;
|
||||
while (isspace(*s)) /* now advance past space chars */
|
||||
while (isspace(*s)) /* now advance past space chars */
|
||||
s++;
|
||||
if (!*s) { /* if at end of line, error */
|
||||
if (!*s) { /* if at end of line, error */
|
||||
fprintf(cp_err, "Error: .include filename missing\n");
|
||||
tfree(buffer); /* was allocated by readline() */
|
||||
continue;
|
||||
} /* Now s points to first char after .include */
|
||||
for (t = s; *t && !isspace(*t); t++) /* now advance past non-space chars */
|
||||
for (t = s; *t && !isspace(*t); t++) /* now advance past non-space chars */
|
||||
;
|
||||
*t = '\0'; /* place \0 and end of file name in buffer */
|
||||
*t = '\0'; /* place \0 and end of file name in buffer */
|
||||
|
||||
if (*s == '~') {
|
||||
copys = cp_tildexpand(s); /* allocates memory, but can also return NULL */
|
||||
|
|
@ -224,8 +230,8 @@ inp_readall(FILE *fp, struct line **data)
|
|||
}
|
||||
}
|
||||
|
||||
/* open file specified by .include statement */
|
||||
if (!(newfp = inp_pathopen(s, "r"))) {
|
||||
/* open file specified by .include statement */
|
||||
if (!(newfp = inp_pathopen(s, "r"))) {
|
||||
perror(s);
|
||||
if(copys) {
|
||||
tfree(copys); /* allocated by the cp_tildexpand() above */
|
||||
|
|
@ -243,16 +249,17 @@ inp_readall(FILE *fp, struct line **data)
|
|||
|
||||
/* Make the .include a comment */
|
||||
*buffer = '*';
|
||||
|
||||
/* now check if this is the first pass (i.e. end points to null) */
|
||||
if (end) { /* end already exists */
|
||||
end->li_next = alloc(struct line); /* create next card */
|
||||
end = end->li_next; /* make end point to next card */
|
||||
if (end) { /* end already exists */
|
||||
end->li_next = alloc(struct line); /* create next card */
|
||||
end = end->li_next; /* make end point to next card */
|
||||
} else {
|
||||
end = cc = alloc(struct line); /* create the deck & end. cc will
|
||||
point to beginning of deck, end to
|
||||
the end */
|
||||
end = cc = alloc(struct line); /* create the deck & end. cc will
|
||||
point to beginning of deck, end to
|
||||
the end */
|
||||
}
|
||||
|
||||
|
||||
/* now fill out rest of struct end. */
|
||||
end->li_next = NULL;
|
||||
end->li_error = NULL;
|
||||
|
|
@ -267,28 +274,29 @@ inp_readall(FILE *fp, struct line **data)
|
|||
|
||||
/* Fix the buffer up a bit. */
|
||||
(void) strncpy(buffer + 1, "end of:", 7);
|
||||
} /* end of .include handling */
|
||||
} /* end of .include handling */
|
||||
|
||||
/* now check if this is the first pass (i.e. end points to null) */
|
||||
if (end) { /* end already exists */
|
||||
end->li_next = alloc(struct line); /* create next card */
|
||||
end = end->li_next; /* point to next card */
|
||||
} else { /* End doesn't exist. Create it. */
|
||||
end = cc = alloc(struct line); /* note that cc points to beginning
|
||||
of deck, end to the end */
|
||||
/* now check if this is the first pass (i.e. end points to null) */
|
||||
if (end) { /* end already exists */
|
||||
end->li_next = alloc(struct line); /* create next card */
|
||||
end = end->li_next; /* point to next card */
|
||||
} else { /* End doesn't exist. Create it. */
|
||||
end = cc = alloc(struct line); /* note that cc points to beginning
|
||||
of deck, end to the end */
|
||||
}
|
||||
|
||||
/* now put buffer into li */
|
||||
|
||||
/* now put buffer into li */
|
||||
end->li_next = NULL;
|
||||
end->li_error = NULL;
|
||||
end->li_actual = NULL;
|
||||
end->li_line = buffer;
|
||||
end->li_linenum = line++;
|
||||
}
|
||||
|
||||
if (!end) { /* No stuff here */
|
||||
*data = NULL;
|
||||
return;
|
||||
} /* end while ((buffer = readline(fp))) */
|
||||
} /* end while ((buffer = readline(fp))) */
|
||||
|
||||
/* This should be freed because we are done with it. */
|
||||
/* tfree(buffer); */
|
||||
|
|
@ -296,8 +304,7 @@ inp_readall(FILE *fp, struct line **data)
|
|||
|
||||
/* Now clean up li: remove comments & stitch together continuation lines. */
|
||||
working = cc->li_next; /* cc points to head of deck. Start with the
|
||||
next card (skip title). */
|
||||
|
||||
next card. */
|
||||
|
||||
while (working) {
|
||||
for (s = working->li_line; (c = *s) && c <= ' '; s++)
|
||||
|
|
@ -306,28 +313,30 @@ inp_readall(FILE *fp, struct line **data)
|
|||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In inp_readall, processing linked list element s = %s . . . \n", s);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
switch (c) {
|
||||
case '#':
|
||||
case '#':
|
||||
case '$':
|
||||
case '*':
|
||||
case '\0':
|
||||
/* this used to be commented out. Why? */
|
||||
/* prev = NULL; */
|
||||
working = working->li_next; /* for these chars, go to next card */
|
||||
/* this used to be commented out. Why? */
|
||||
/* prev = NULL; */
|
||||
working = working->li_next; /* for these chars, go to next card */
|
||||
break;
|
||||
case '+': /* handle continuation */
|
||||
|
||||
case '+': /* handle continuation */
|
||||
if (!prev) {
|
||||
working->li_error = copy(
|
||||
"Illegal continuation line: ignored.");
|
||||
working = working->li_next;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* create buffer and write last and current line into it. */
|
||||
buffer = tmalloc(strlen(prev->li_line) + strlen(s) + 2);
|
||||
(void) sprintf(buffer, "%s %s", prev->li_line, s + 1);
|
||||
(void) sprintf(buffer, "%s %s", prev->li_line, s + 1);
|
||||
|
||||
s = prev->li_line;
|
||||
prev->li_line = buffer;
|
||||
prev->li_next = working->li_next;
|
||||
|
|
@ -349,7 +358,8 @@ inp_readall(FILE *fp, struct line **data)
|
|||
}
|
||||
working = prev->li_next;
|
||||
break;
|
||||
default: /* regular one-line card */
|
||||
|
||||
default: /* regular one-line card */
|
||||
prev = working;
|
||||
working = working->li_next;
|
||||
break;
|
||||
|
|
@ -360,7 +370,6 @@ inp_readall(FILE *fp, struct line **data)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* *
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -15,12 +15,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include "hcomp.h"
|
||||
#include "variable.h"
|
||||
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
extern int gnu_history_lines;
|
||||
extern char gnu_history_file[];
|
||||
#endif
|
||||
|
||||
static void byemesg(void);
|
||||
|
|
@ -77,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;
|
||||
}
|
||||
|
|
@ -86,14 +85,9 @@ com_quit(wordlist *wl)
|
|||
byemesg();
|
||||
} else
|
||||
byemesg();
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* Added GNU Readline Support -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
if (cp_interactive && (cp_maxhistlength > 0)) {
|
||||
stifle_history(cp_maxhistlength);
|
||||
write_history(gnu_history_file);
|
||||
}
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
exit(EXIT_NORMAL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -235,6 +229,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,11 +72,8 @@ cp_tildexpand(char *string)
|
|||
{
|
||||
char *result;
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
result = tildexpand(string);
|
||||
#else
|
||||
result = tilde_expand(string);
|
||||
#endif
|
||||
|
||||
if (!result) {
|
||||
if (cp_nonomatch) {
|
||||
return copy(string);
|
||||
|
|
|
|||
|
|
@ -796,6 +796,7 @@ zoomin(GRAPH *graph)
|
|||
wl = cp_parse(buf);
|
||||
(void) cp_addhistent(cp_event++, wl);
|
||||
}
|
||||
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
(void) cp_evloop(buf);
|
||||
|
|
|
|||
|
|
@ -386,13 +386,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);
|
||||
}
|
||||
|
||||
static void *
|
||||
|
|
@ -425,13 +425,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
|
||||
|
|
@ -245,9 +245,9 @@ dosim(char *what, wordlist *wl)
|
|||
#else
|
||||
else if (!(rawfileFp = fopen(wl->wl_word, "w"))) {
|
||||
setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE);
|
||||
perror(wl->wl_word);
|
||||
ft_setflag = FALSE;
|
||||
return 1;
|
||||
perror(wl->wl_word);
|
||||
ft_setflag = FALSE;
|
||||
return 1;
|
||||
}
|
||||
#endif /* __MINGW32__ */
|
||||
rawfileBinary = !ascii;
|
||||
|
|
@ -261,14 +261,14 @@ dosim(char *what, wordlist *wl)
|
|||
}
|
||||
/*save rawfile name saj*/
|
||||
if(last_used_rawfile)
|
||||
tfree(last_used_rawfile); /* va: we should allways use tfree */
|
||||
tfree(last_used_rawfile);
|
||||
if(rawfileFp){
|
||||
last_used_rawfile = copy(wl->wl_word);
|
||||
}else {
|
||||
last_used_rawfile = NULL;
|
||||
}
|
||||
/*end saj*/
|
||||
|
||||
|
||||
/* Spice calls wrd_init and wrd_end itself */
|
||||
ft_curckt->ci_inprogress = TRUE;
|
||||
if (eq(what,"sens2")) {
|
||||
|
|
@ -282,7 +282,7 @@ dosim(char *what, wordlist *wl)
|
|||
if(g_ipc.enabled)
|
||||
ipc_send_errchk();
|
||||
/* gtri - end - 12/12/90 */
|
||||
#endif
|
||||
#endif
|
||||
} else
|
||||
ft_curckt->ci_inprogress = FALSE;
|
||||
} else {
|
||||
|
|
@ -296,7 +296,7 @@ dosim(char *what, wordlist *wl)
|
|||
if(g_ipc.enabled)
|
||||
ipc_send_errchk();
|
||||
/* gtri - end - 12/12/90 */
|
||||
#endif
|
||||
#endif
|
||||
err = 0;
|
||||
} else if (err == 2) {
|
||||
fprintf(cp_err, "%s simulation(s) aborted\n", what);
|
||||
|
|
@ -322,7 +322,7 @@ dosim(char *what, wordlist *wl)
|
|||
if (wl)
|
||||
wl->wl_prev = NULL;
|
||||
tfree(ww);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,32 +37,45 @@ extern jmp_buf jbuf;
|
|||
|
||||
extern pid_t getpid (void);
|
||||
|
||||
/* not using SIGINT with GNU Readline - AV */
|
||||
#ifndef HAVE_GNUREADLINE
|
||||
/* 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);
|
||||
|
||||
}
|
||||
#endif /* !HAVE_GNUREADLINE */
|
||||
|
||||
|
||||
RETSIGTYPE
|
||||
sigfloat(int sig, int code)
|
||||
|
|
@ -66,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. */
|
||||
|
|
@ -88,7 +106,7 @@ sigcont(void)
|
|||
{
|
||||
(void) signal(SIGTSTP, (SIGNAL_FUNCTION) sigstop);
|
||||
if (cp_cwait)
|
||||
longjmp(jbuf, 1);
|
||||
siglongjmp(jbuf, 1);
|
||||
}
|
||||
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -168,6 +168,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) {
|
||||
|
|
@ -200,6 +204,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... */
|
||||
|
|
@ -259,6 +267,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 */
|
||||
|
|
@ -383,6 +396,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) */
|
||||
|
|
@ -444,8 +462,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 */
|
||||
|
|
@ -735,7 +753,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);
|
||||
|
|
@ -770,12 +788,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);
|
||||
|
|
@ -784,10 +802,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 */
|
||||
|
|
@ -803,7 +821,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);
|
||||
|
|
@ -863,7 +881,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) {
|
||||
|
|
@ -892,7 +910,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);
|
||||
|
|
@ -920,7 +938,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);
|
||||
|
|
@ -1192,9 +1210,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;
|
||||
|
|
@ -1332,8 +1350,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)
|
||||
|
|
@ -1345,9 +1366,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);
|
||||
|
||||
|
|
@ -1355,17 +1381,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) {
|
||||
|
|
@ -1404,13 +1430,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);
|
||||
|
|
@ -1437,6 +1463,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);
|
||||
|
|
@ -1464,22 +1494,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);
|
||||
|
|
@ -1503,19 +1537,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) {
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ cp_vset(char *varname, char type, char *value)
|
|||
cp_maxhistlength = v->va_real;
|
||||
else if (eq(copyvarname, "noclobber"))
|
||||
cp_noclobber = TRUE;
|
||||
else if (eq(varname, "echo")) /*CDHW*/
|
||||
else if (eq(varname, "echo")) /*CDHW*/
|
||||
cp_echo = TRUE; /*CDHW*/
|
||||
else if (eq(copyvarname, "prompt") && (type == VT_STRING))
|
||||
cp_promptstring = copy(v->va_string);
|
||||
|
|
@ -208,10 +208,12 @@ cp_vset(char *varname, char type, char *value)
|
|||
alreadythere = FALSE;
|
||||
if (ft_curckt) {
|
||||
for (u = ft_curckt->ci_vars; u; u = u->va_next)
|
||||
{
|
||||
if (eq(copyvarname, u->va_name)) {
|
||||
alreadythere = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!alreadythere) {
|
||||
v->va_next = ft_curckt->ci_vars;
|
||||
ft_curckt->ci_vars = v;
|
||||
|
|
@ -225,7 +227,7 @@ cp_vset(char *varname, char type, char *value)
|
|||
/* va_next left unchanged */
|
||||
tfree(v->va_name);
|
||||
tfree(v);
|
||||
/* va: old version with memory leaks
|
||||
/* va: old version with memory leaks
|
||||
w = u->va_next;
|
||||
bcopy(v, u, sizeof(*u));
|
||||
u->va_next = w;
|
||||
|
|
@ -291,9 +293,7 @@ cp_setparse(wordlist *wl)
|
|||
*s = '\0';
|
||||
if (*val == '\0') {
|
||||
if (!wl) {
|
||||
fprintf(cp_err,
|
||||
"Error: %s equals what?.\n",
|
||||
name);
|
||||
fprintf(cp_err, "Error: %s equals what?.\n", name);
|
||||
tfree(name);/*DG: cp_unquote Memory leak: free name before exiting*/
|
||||
return (NULL);
|
||||
} else {
|
||||
|
|
@ -343,7 +343,7 @@ cp_setparse(wordlist *wl)
|
|||
}
|
||||
if (balance && !wl) {
|
||||
fprintf(cp_err, "Error: bad set form.\n");
|
||||
tfree(name); /* va: cp_unquote memory leak: free name before exiting */
|
||||
tfree(name); /* va: cp_unquote memory leak: free name before exiting */
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ cp_setparse(wordlist *wl)
|
|||
vv->va_string = copy(val);
|
||||
}
|
||||
tfree(copyval);/*DG: must free ss any way to avoid cp_unquote memory leak */
|
||||
tfree(name); /* va: cp_unquote memory leak: free name for every loop */
|
||||
tfree(name); /* va: cp_unquote memory leak: free name for every loop */
|
||||
}
|
||||
if(name)
|
||||
tfree(name);
|
||||
|
|
@ -485,6 +485,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
|
||||
|
|
|
|||
|
|
@ -127,6 +127,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);
|
||||
|
|
@ -134,11 +135,11 @@ 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);
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
extern char *tildexpand(char *string);
|
||||
#else
|
||||
extern char *tilde_expand(char *string);
|
||||
#endif
|
||||
|
||||
extern char *canonicalize_pathname(char *path);
|
||||
extern char *absolute_pathname(char *string, char *dot_path);
|
||||
|
||||
extern char *smktemp(char *id);
|
||||
|
||||
extern char *copy(char *str);
|
||||
|
|
|
|||
190
src/main.c
190
src/main.c
|
|
@ -5,7 +5,7 @@
|
|||
Author: 1985 Wayne A. Christopher
|
||||
|
||||
The main routine for ngspice */
|
||||
|
||||
|
||||
#include <ngspice.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
#include <misc/getopt.h>
|
||||
#include <frontend/resource.h>
|
||||
#include <frontend/variable.h>
|
||||
//#include "frontend/display.h" /* va */
|
||||
#include <frontend/display.h> /* added by SDB to pick up Input() fcn */
|
||||
|
||||
/* saj xspice headers */
|
||||
#ifdef XSPICE
|
||||
|
|
@ -49,7 +49,10 @@
|
|||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include "fteinput.h"
|
||||
#endif
|
||||
|
||||
char gnu_history_file[512];
|
||||
static char *application_name;
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
#ifndef HAVE_GETRUSAGE
|
||||
#ifdef HAVE_FTIME
|
||||
|
|
@ -68,8 +71,8 @@ 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";
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
|
|
@ -144,7 +147,7 @@ struct variable *(*if_getparam)( );
|
|||
|
||||
|
||||
|
||||
jmp_buf jbuf;
|
||||
sigjmp_buf jbuf;
|
||||
|
||||
static int started = FALSE;
|
||||
|
||||
|
|
@ -171,56 +174,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)
|
||||
{
|
||||
|
|
@ -237,7 +251,7 @@ void com_savesnap(wordlist *wl) { return; }
|
|||
#ifndef SIMULATOR
|
||||
|
||||
#ifdef XSPICE
|
||||
/* saj,dw to get nutmeg to compile, not nice but necessary */
|
||||
/* saj to get nutmeg to compile, not nice but necessary */
|
||||
Ipc_Tiein_t g_ipc;
|
||||
Ipc_Status_t ipc_send_errchk(void ) {
|
||||
Ipc_Status_t x=0;
|
||||
|
|
@ -278,7 +292,7 @@ double CONSTe;
|
|||
IFfrontEnd *SPfrontEnd = NULL;
|
||||
int DEVmaxnum = 0;
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator)
|
||||
{
|
||||
#ifdef SIMULATOR
|
||||
|
|
@ -307,6 +321,7 @@ int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator)
|
|||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Shutdown gracefully. */
|
||||
int
|
||||
shutdown(int exitval)
|
||||
|
|
@ -322,6 +337,8 @@ shutdown(int exitval)
|
|||
exit (exitval);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* Adapted ../lib/cp/lexical.c:prompt() for GNU Readline -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
static char *
|
||||
|
|
@ -340,15 +357,15 @@ prompt()
|
|||
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;
|
||||
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++;
|
||||
}
|
||||
|
|
@ -356,55 +373,51 @@ prompt()
|
|||
return pbuf;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Process device events in Readline's hook since there is no where
|
||||
else to do it now - AV */
|
||||
int rl_event_func()
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/* note that we want some mechanism to detect ctrl-D and expand it to exit */
|
||||
while (1) {
|
||||
history_set_pos(history_length);
|
||||
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_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)
|
||||
{
|
||||
|
|
@ -426,6 +439,7 @@ show_help(void)
|
|||
"Report bugs to %s.\n", cp_program, Bug_Addr);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void
|
||||
show_version(void)
|
||||
{
|
||||
|
|
@ -438,6 +452,7 @@ show_version(void)
|
|||
" The NGSpice Project\n", cp_program, PACKAGE, VERSION);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void
|
||||
append_to_stream(FILE *dest, FILE *source)
|
||||
{
|
||||
|
|
@ -500,6 +515,8 @@ main(int argc, char **argv)
|
|||
FILE *fp;
|
||||
FILE *circuit_file;
|
||||
|
||||
|
||||
|
||||
#ifdef TRACE
|
||||
/* this is used to detect memory leaks during debugging */
|
||||
/* added by SDB during debug . . . . */
|
||||
|
|
@ -524,8 +541,8 @@ main(int argc, char **argv)
|
|||
application_name = argv[0];
|
||||
else
|
||||
++application_name;
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
#ifdef PARALLEL_ARCH
|
||||
PBEGIN_(argc, argv);
|
||||
ARCHme = NODEID_();
|
||||
|
|
@ -553,8 +570,7 @@ main(int argc, char **argv)
|
|||
#ifdef MALLOCTRACE
|
||||
mallocTraceInit("malloc.out");
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_ISATTY) && !defined(HAS_WINDOWS)
|
||||
#if defined(HAVE_ISATTY) && !defined(HAS_WINDOWS)
|
||||
istty = (bool) isatty(fileno(stdin));
|
||||
#endif
|
||||
|
||||
|
|
@ -571,7 +587,7 @@ main(int argc, char **argv)
|
|||
|
||||
srandom(getpid());
|
||||
|
||||
|
||||
/* --- Process command line options --- */
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
|
|
@ -681,7 +697,7 @@ main(int argc, char **argv)
|
|||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
} /* --- End of command line option processing --- */
|
||||
|
||||
|
||||
#ifdef SIMULATOR
|
||||
|
|
@ -712,7 +728,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;
|
||||
|
|
@ -720,13 +736,13 @@ main(int argc, char **argv)
|
|||
|
||||
/* Set up signal handling */
|
||||
if (!ft_batchmode) {
|
||||
/* Set up interrupt handler */
|
||||
(void) signal(SIGINT, ft_sigintr);
|
||||
|
||||
#ifndef HAVE_GNUREADLINE
|
||||
signal(SIGINT, ft_sigintr);
|
||||
#endif
|
||||
/* floating point exception */
|
||||
(void) signal(SIGFPE, sigfloat);
|
||||
|
||||
signal(SIGFPE, sigfloat);
|
||||
#if defined(SIGTSTP) // && !defined(__MINGW32__)
|
||||
#ifdef SIGTSTP
|
||||
signal(SIGTSTP, sigstop);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -761,9 +777,9 @@ main(int argc, char **argv)
|
|||
#define INITSTR "/.spiceinit"
|
||||
#ifdef HAVE_ASPRINTF
|
||||
asprintf(&s, "%s%s", pw->pw_dir,INITSTR);
|
||||
#else /* ~ HAVE_ASPRINTF */ /* va: we use tmalloc */
|
||||
s=(char *) tmalloc(1 + strlen(pw->pw_dir)+strlen(INITSTR));
|
||||
sprintf(s,"%s%s",pw->pw_dir,INITSTR);
|
||||
#else /* ~ HAVE_ASPRINTF */
|
||||
s=(char *) tmalloc(1 + strlen(pw->pw_dir)+strlen(INITSTR));
|
||||
sprintf(s,"%s%s",pw->pw_dir,INITSTR);
|
||||
#endif /* HAVE_ASPRINTF */
|
||||
|
||||
if (access(s, 0) == 0)
|
||||
|
|
@ -800,7 +816,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;
|
||||
|
||||
|
||||
|
|
@ -846,7 +862,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);
|
||||
|
|
@ -857,7 +873,8 @@ evl:
|
|||
* so exit. */
|
||||
bool st = FALSE;
|
||||
|
||||
(void) setjmp(jbuf);
|
||||
(void) sigsetjmp(jbuf, 1);
|
||||
|
||||
|
||||
if (st == TRUE) {
|
||||
shutdown(EXIT_BAD);
|
||||
|
|
@ -878,7 +895,7 @@ evl:
|
|||
* save too much. */
|
||||
cp_interactive = FALSE;
|
||||
if (rflag) {
|
||||
/* saj done already in inp_spsource ft_dotsaves();*/
|
||||
/* saj done already in inp_spsource ft_dotsaves();*/
|
||||
error2 = ft_dorun(ft_rawfile);
|
||||
if (ft_cktcoms(TRUE) || error2)
|
||||
shutdown(EXIT_BAD);
|
||||
|
|
@ -892,15 +909,34 @@ evl:
|
|||
"no simulations run\n");
|
||||
shutdown(EXIT_BAD);
|
||||
}
|
||||
} else {
|
||||
(void) setjmp(jbuf);
|
||||
} /* --- if (ft_batchmode) --- */
|
||||
else {
|
||||
cp_interactive = TRUE;
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
app_rl_readlines();
|
||||
#else
|
||||
/* --- 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 */
|
||||
}
|
||||
#endif /* ifelse HAVE_GNUREADLINE */
|
||||
|
||||
} /* --- else (if (ft_batchmode)) --- */
|
||||
|
||||
#else /* ~ SIMULATOR */
|
||||
|
||||
|
|
@ -915,16 +951,16 @@ evl:
|
|||
|
||||
evl:
|
||||
/* Nutmeg "main" */
|
||||
(void) setjmp(jbuf);
|
||||
(void) sigsetjmp(jbuf, 1);
|
||||
cp_interactive = TRUE;
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
app_rl_readlines();
|
||||
#else
|
||||
while (cp_evloop((char *) NULL) == 1) ;
|
||||
#endif /* ifelse HAVE_GNUREADLINE */
|
||||
|
||||
#endif /* ~ SIMULATOR */
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ mkvar(char **p, char *path_prefix, char *var_dir, char *env_var)
|
|||
asprintf(p, "%s", buffer);
|
||||
else
|
||||
asprintf(p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir);
|
||||
#else /* ~ HAVE_ASPRINTF */ /* va: we use tmalloc */
|
||||
#else /* ~ HAVE_ASPRINTF */
|
||||
if (buffer){
|
||||
*p = (char *) tmalloc(strlen(buffer)+1);
|
||||
sprintf(*p,"%s",buffer);
|
||||
|
|
@ -48,7 +48,7 @@ mkvar(char **p, char *path_prefix, char *var_dir, char *env_var)
|
|||
}
|
||||
else{
|
||||
*p = (char *) tmalloc(strlen(path_prefix) +
|
||||
strlen(DIR_PATHSEP) + strlen(var_dir) + 1);
|
||||
strlen(DIR_PATHSEP) + strlen(var_dir) + 1);
|
||||
sprintf(*p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir);
|
||||
/* asprintf(p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir); */
|
||||
}
|
||||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -192,8 +192,13 @@ register char *p, *s;
|
|||
#endif /* CIDER */
|
||||
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* 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)
|
||||
{
|
||||
|
|
@ -224,9 +229,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)
|
||||
|
|
@ -235,24 +241,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)
|
||||
|
|
@ -274,7 +334,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)
|
||||
|
|
|
|||
106
src/misc/tilde.c
106
src/misc/tilde.c
|
|
@ -15,6 +15,7 @@ Modified: 2002 R. Oktas, <roktas@omu.edu.tr>
|
|||
#include <pwd.h>
|
||||
#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
|
||||
|
|
@ -25,70 +26,13 @@ Modified: 2002 R. Oktas, <roktas@omu.edu.tr>
|
|||
not behave this way, IMHO. Anyway... Don't care for the moment, may
|
||||
be in the future. -- ro */
|
||||
|
||||
/* PN: Since readline patch is not compiled in by default the behaviour
|
||||
described above is not acceptable. I will make two different version
|
||||
of tilde expansion routine, the one choosen depends on HAVE_GNUREADLINE
|
||||
Note: since a readline replacement called libedit is under
|
||||
development at libedit.sourceforge.net, I will switch to it
|
||||
ASAP, since libedit is covered by BSD licnse.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HAVE_GNUREADLINE
|
||||
char *
|
||||
tilde_expand(char *string)
|
||||
{
|
||||
|
||||
#ifdef HAVE_PWD_H
|
||||
struct passwd *pw;
|
||||
/*extern struct passwd *getpwuid( );*/
|
||||
char buf[BSIZE_SP];
|
||||
char *k, c;
|
||||
|
||||
if (!string)
|
||||
return NULL;
|
||||
|
||||
while (*string && isspace(*string))
|
||||
string++;
|
||||
|
||||
if (*string != '~')
|
||||
return copy(string);
|
||||
|
||||
string += 1;
|
||||
|
||||
if (!*string || *string == '/') {
|
||||
pw = getpwuid(getuid());
|
||||
*buf = 0;
|
||||
} else {
|
||||
k = buf;
|
||||
while ((c = *string) && c != '/')
|
||||
*k++ = c, string++;
|
||||
*k = 0;
|
||||
pw = getpwnam(buf);
|
||||
}
|
||||
|
||||
if (pw) {
|
||||
strcpy(buf, pw->pw_dir);
|
||||
if (*string)
|
||||
strcat(buf, string);
|
||||
} else
|
||||
return NULL;
|
||||
|
||||
return copy(buf);
|
||||
|
||||
#else
|
||||
return copy(string);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* HAVE_GNUREADLINE */
|
||||
|
||||
char *
|
||||
tildexpand(char *string)
|
||||
{
|
||||
|
||||
char buf[BSIZE_SP];
|
||||
char *result, *k, c;
|
||||
|
||||
if (!string)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -101,42 +45,44 @@ tildexpand(char *string)
|
|||
string += 1;
|
||||
|
||||
if (!*string || *string == '/') {
|
||||
/* First try the environment setting. May also make life easier
|
||||
for non-unix platforms, eg. MS-DOS. -- ro */
|
||||
result = getenv("HOME");
|
||||
/* 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;
|
||||
}
|
||||
/* 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;
|
||||
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)
|
||||
result = pw->pw_dir;
|
||||
#endif
|
||||
}
|
||||
if (result) {
|
||||
#ifdef HAVE_PWD_H
|
||||
strcpy(buf, result);
|
||||
strcpy(buf, result);
|
||||
if (*string)
|
||||
strcat(buf, string);
|
||||
return copy(buf);
|
||||
return copy(buf);
|
||||
|
||||
} else
|
||||
return NULL;
|
||||
#else
|
||||
|
||||
/* Emulate the old behavior to prevent side effects. -- ro */
|
||||
return copy(string);
|
||||
#else
|
||||
/* Emulate the old behavior to prevent side effects. -- ro */
|
||||
return copy(string);
|
||||
#endif
|
||||
}
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,7 @@
|
|||
#ifndef TILDE_H_INCLUDED
|
||||
#define TILDE_H_INCLUDED
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
char * tildexpand(char *string);
|
||||
#else
|
||||
char * tilde_expand(char *string);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
/*************
|
||||
* Various utility functions.
|
||||
* 2002 R. Oktas, <roktas@omu.edu.tr>
|
||||
************/
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "ngspice.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Stuff for Filename Handling */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Canonicalize PATH, and return a new path. The new path differs from PATH
|
||||
in that:
|
||||
Multple `/'s are collapsed to a single `/'.
|
||||
Leading `./'s and trailing `/.'s are removed.
|
||||
Trailing `/'s are removed.
|
||||
Non-leading `../'s and trailing `..'s are handled by removing
|
||||
portions of the path.
|
||||
|
||||
Stolen from Bash source (slightly modified).
|
||||
Credit goes to Chet Ramey, et al. -- ro */
|
||||
|
||||
char *
|
||||
canonicalize_pathname(char *path)
|
||||
{
|
||||
int i, start;
|
||||
char stub_char;
|
||||
char *result;
|
||||
|
||||
/* The result cannot be larger than the input PATH. */
|
||||
result = copy(path);
|
||||
|
||||
stub_char = (*path == '/') ? '/' : '.';
|
||||
|
||||
/* Walk along RESULT looking for things to compact. */
|
||||
i = 0;
|
||||
while (1) {
|
||||
if (!result[i])
|
||||
break;
|
||||
|
||||
while (result[i] && result[i] != '/')
|
||||
i++;
|
||||
|
||||
start = i++;
|
||||
|
||||
/* If we didn't find any slashes, then there is nothing left to do. */
|
||||
if (!result[start])
|
||||
break;
|
||||
|
||||
/* Handle multiple `/'s in a row. */
|
||||
while (result[i] == '/')
|
||||
i++;
|
||||
|
||||
#if !defined (apollo)
|
||||
if ((start + 1) != i)
|
||||
#else
|
||||
if ((start + 1) != i && (start != 0 || i != 2))
|
||||
#endif /* apollo */
|
||||
{
|
||||
strcpy (result + start + 1, result + i);
|
||||
i = start + 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Handle backslash-quoted `/'. */
|
||||
if (start > 0 && result[start - 1] == '\\')
|
||||
continue;
|
||||
#endif
|
||||
|
||||
/* Check for trailing `/'. */
|
||||
if (start && !result[i]) {
|
||||
zero_last:
|
||||
result[--i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for `../', `./' or trailing `.' by itself. */
|
||||
if (result[i] == '.') {
|
||||
/* Handle trailing `.' by itself. */
|
||||
if (!result[i + 1])
|
||||
goto zero_last;
|
||||
|
||||
/* Handle `./'. */
|
||||
if (result[i + 1] == '/') {
|
||||
strcpy(result + i, result + i + 1);
|
||||
i = (start < 0) ? 0 : start;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle `../' or trailing `..' by itself. */
|
||||
if (result[i + 1] == '.' &&
|
||||
(result[i + 2] == '/' || !result[i + 2])) {
|
||||
while (--start > -1 && result[start] != '/');
|
||||
strcpy(result + start + 1, result + i + 2);
|
||||
i = (start < 0) ? 0 : start;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!*result) {
|
||||
*result = stub_char;
|
||||
result[1] = '\0';
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
/* Turn STRING (a pathname) into an absolute pathname, assuming that
|
||||
DOT_PATH contains the symbolic location of `.'. This always
|
||||
returns a new string, even if STRING was an absolute pathname to
|
||||
begin with.
|
||||
|
||||
Stolen from Bash source (slightly modified).
|
||||
Credit goes to Chet Ramey, et al. -- ro */
|
||||
|
||||
char * absolute_pathname(char *string, char *dot_path)
|
||||
{
|
||||
char *result;
|
||||
int result_len;
|
||||
|
||||
if (!dot_path || *string == '/')
|
||||
result = copy(string);
|
||||
else {
|
||||
if (dot_path && dot_path[0]) {
|
||||
result = tmalloc(2 + strlen(dot_path) + strlen(string));
|
||||
strcpy(result, dot_path);
|
||||
result_len = strlen(result);
|
||||
if (result[result_len - 1] != '/') {
|
||||
result[result_len++] = '/';
|
||||
result[result_len] = '\0';
|
||||
}
|
||||
} else {
|
||||
result = tmalloc(3 + strlen (string));
|
||||
result[0] = '.'; result[1] = '/'; result[2] = '\0';
|
||||
result_len = 2;
|
||||
}
|
||||
|
||||
strcpy(result + result_len, string);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/*************
|
||||
* Header file for util.c
|
||||
* 2002 R. Oktas, <roktas@omu.edu.tr>
|
||||
************/
|
||||
|
||||
#ifndef UTIL_H_INCLUDED
|
||||
#define UTIL_H_INCLUDED
|
||||
|
||||
char *canonicalize_pathname(char *path);
|
||||
char *absolute_pathname(char *string, char *dot_path);
|
||||
|
||||
#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");
|
||||
|
|
|
|||
Loading…
Reference in New Issue