2003-07-18 Vera Albrecht <albrecht@danalyse.de>
* src/{main.c,tclspice.c}
src/frontend/{Makefile.am,control.c,control.h,display.c,dotcards.c,
hcomp.c,hpgl.c,outitf.c,parse.c,postcoms.c,postsc.c,runcoms.c,
spiceif.c,variable.c,variable.h,parser/complete.c,plotting/pvec.c}
src/include/{cktdefs.h,ngspice.h}
src/misc/{ivars.c,string.c,stringutil.h}
src/spicelib/analysis/{acan.c,ckt.h,dcop.c}
src/spicelib/devices/bsim3/b3temp.c
src/spicelib/parser/{ifnewuid.c,inp2dot.c,inperror.c} :
Memory leaks and some WINDOWS compile fixes.
This commit is contained in:
parent
14483620d4
commit
54b3079232
13
ChangeLog
13
ChangeLog
|
|
@ -1,3 +1,16 @@
|
|||
2003-07-18 Vera Albrecht <albrecht@danalyse.de>
|
||||
|
||||
* src/{main.c,tclspice.c}
|
||||
src/frontend/{Makefile.am,control.c,control.h,display.c,dotcards.c,
|
||||
hcomp.c,hpgl.c,outitf.c,parse.c,postcoms.c,postsc.c,runcoms.c,
|
||||
spiceif.c,variable.c,variable.h,parser/complete.c,plotting/pvec.c}
|
||||
src/include/{cktdefs.h,ngspice.h}
|
||||
src/misc/{ivars.c,string.c,stringutil.h}
|
||||
src/spicelib/analysis/{acan.c,ckt.h,dcop.c}
|
||||
src/spicelib/devices/bsim3/b3temp.c
|
||||
src/spicelib/parser/{ifnewuid.c,inp2dot.c,inperror.c} :
|
||||
Memory leaks and some WINDOWS compile fixes.
|
||||
|
||||
2003-07-17 Stefan Jones <stefan.jones@multigig.com>
|
||||
|
||||
* src/frontend/{subckt.c,vectors.c}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,8 @@ libfte_a_SOURCES = \
|
|||
vectors.c \
|
||||
vectors.h \
|
||||
where.c \
|
||||
where.h
|
||||
where.h \
|
||||
hpgl.c
|
||||
|
||||
# TESTS = testcommands
|
||||
#
|
||||
|
|
|
|||
|
|
@ -47,6 +47,14 @@ int stackp = 0;
|
|||
* blown away every time we return -- probably every time we type
|
||||
* source at the keyboard and every time a source returns to keyboard
|
||||
* input is ok though -- use ft_controlreset. */
|
||||
|
||||
/* Notes by CDHW:
|
||||
* This routine leaked like a sieve because each getcommand() created a
|
||||
* wordlist that was never freed because it might have been added into
|
||||
* the control structure. I've tackled this by making sure that everything
|
||||
* put into the cend[stackp] is a copy. This means that wlist can be
|
||||
* destroyed safely
|
||||
*/
|
||||
|
||||
static char *noredirect[] = { "stop", NULL } ; /* Only one?? */
|
||||
|
||||
|
|
@ -79,6 +87,37 @@ pwlist(wordlist *wlist, char *name)
|
|||
}
|
||||
|
||||
|
||||
/* CDHW defined functions */
|
||||
|
||||
static void
|
||||
pwlist_echo(wlist, name) /*CDHW used to perform function of set echo */
|
||||
wordlist *wlist;
|
||||
char *name;
|
||||
{
|
||||
wordlist *wl;
|
||||
|
||||
if ((!cp_echo)||cp_debug) /* cpdebug prints the same info */
|
||||
return;
|
||||
fprintf(cp_err, "%s ", name);
|
||||
for (wl = wlist; wl; wl = wl->wl_next)
|
||||
fprintf(cp_err, "%s ", wl->wl_word);
|
||||
fprintf(cp_err, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*CDHW Remove control structure and free the memory its hogging CDHW*/
|
||||
|
||||
void ctl_free(struct control *ctrl) {
|
||||
if (!ctrl) return;
|
||||
wl_free(ctrl->co_cond); ctrl->co_cond = NULL;
|
||||
tfree(ctrl->co_foreachvar); ctrl->co_foreachvar = NULL;
|
||||
wl_free(ctrl->co_text); ctrl->co_text = NULL;
|
||||
ctl_free(ctrl->co_children); ctrl->co_children = NULL;
|
||||
ctl_free(ctrl->co_elseblock); ctrl->co_elseblock = NULL;
|
||||
ctl_free(ctrl->co_next); ctrl->co_next = NULL;
|
||||
tfree(ctrl); ctrl = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Note that we only do io redirection when we get to here - we also
|
||||
* postpone some other things until now. */
|
||||
|
|
@ -108,8 +147,10 @@ docommand(wordlist *wlist)
|
|||
|
||||
wlist = cp_doglob(wlist);
|
||||
pwlist(wlist, "After globbing");
|
||||
|
||||
pwlist_echo(wlist, "Becomes >");
|
||||
|
||||
if (!wlist || !wlist->wl_word)
|
||||
if (!wlist || !wlist->wl_word) /*CDHW need to free wlist in second case? CDHW*/
|
||||
return;
|
||||
|
||||
/* Now loop through all of the commands given. */
|
||||
|
|
@ -185,7 +226,7 @@ docommand(wordlist *wlist)
|
|||
for (wl = wlist->wl_next; wl; wl = wl->wl_next)
|
||||
nargs++;
|
||||
if (command->co_stringargs) {
|
||||
lcom = wl_flatten(wlist->wl_next);
|
||||
lcom = wl_flatten(wlist->wl_next); /*CDHW lcom will need freeing CDHW*/
|
||||
(*command->co_func) ((void *)(lcom));
|
||||
} else {
|
||||
if (nargs < command->co_minargs) {
|
||||
|
|
@ -196,8 +237,9 @@ docommand(wordlist *wlist)
|
|||
}
|
||||
} else if (nargs > command->co_maxargs) {
|
||||
fprintf(cp_err, "%s: too many args.\n", s);
|
||||
} else
|
||||
} else {
|
||||
(*command->co_func) (wlist->wl_next);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now fix the pointers and advance wlist. */
|
||||
|
|
@ -241,10 +283,17 @@ doblock(struct control *bl, int *num)
|
|||
wordlist *wl;
|
||||
char *i;
|
||||
int nn;
|
||||
|
||||
|
||||
nn = *num + 1 ; /*CDHW this is a guess... CDHW*/
|
||||
|
||||
switch (bl->co_type) {
|
||||
case CO_WHILE:
|
||||
if (!bl->co_children) {
|
||||
fprintf(cp_err, "Warning: Executing empty 'while' block.\n");
|
||||
fprintf(cp_err, " (Use a label statement as a no-op to suppress this warning.)\n");
|
||||
}
|
||||
while (bl->co_cond && cp_istrue(bl->co_cond)) {
|
||||
if (!bl->co_children) cp_periodic(); /*CDHW*/
|
||||
for (ch = bl->co_children; ch; ch = cn) {
|
||||
cn = ch->co_next;
|
||||
i = doblock(ch, &nn);
|
||||
|
|
@ -316,10 +365,21 @@ doblock(struct control *bl, int *num)
|
|||
break;
|
||||
|
||||
case CO_REPEAT:
|
||||
while ((bl->co_numtimes > 0) ||
|
||||
(bl->co_numtimes == -1)) {
|
||||
if (!bl->co_children) {
|
||||
fprintf(cp_err, "Warning: Executing empty 'repeat' block.\n");
|
||||
fprintf(cp_err, " (Use a label statement as a no-op to suppress this warning.)\n");
|
||||
}
|
||||
if (!bl->co_timestodo) bl->co_timestodo = bl->co_numtimes;
|
||||
/*...CDHW*/
|
||||
while ((bl->co_timestodo > 0) ||
|
||||
(bl->co_timestodo == -1)) {
|
||||
if (bl->co_numtimes != -1)
|
||||
bl->co_numtimes--;
|
||||
|
||||
if (!bl->co_children) cp_periodic(); /*CDHW*/
|
||||
|
||||
if (bl->co_timestodo != -1) bl->co_timestodo--;
|
||||
|
||||
for (ch = bl->co_children; ch; ch = cn) {
|
||||
cn = ch->co_next;
|
||||
i = doblock(ch, &nn);
|
||||
|
|
@ -447,11 +507,12 @@ doblock(struct control *bl, int *num)
|
|||
|
||||
case CO_GOTO:
|
||||
wl = cp_variablesubst(cp_bquote(cp_doglob(
|
||||
wl_copy(bl->co_text))));
|
||||
wl_copy(bl->co_text)))); /*CDHW Leak ? CDHW*/
|
||||
return (wl->wl_word);
|
||||
|
||||
case CO_LABEL:
|
||||
/* Do nothing. */
|
||||
cp_periodic(); /*CDHW needed to avoid lock-ups when loop contains only a label CDHW*/
|
||||
break;
|
||||
|
||||
case CO_STATEMENT:
|
||||
|
|
@ -511,7 +572,7 @@ getcommand(char *string)
|
|||
return (wlist);
|
||||
}
|
||||
|
||||
|
||||
/* va: TODO: free control structure(s) before overwriting (memory leakage) */
|
||||
int
|
||||
cp_evloop(char *string)
|
||||
{
|
||||
|
|
@ -556,7 +617,9 @@ cp_evloop(char *string)
|
|||
|
||||
/* Add this to the control structure list. If cend->co_type is
|
||||
* CO_UNFILLED, the last line was the beginning of a block,
|
||||
* and this is the unfilled first statement. */
|
||||
* and this is the unfilled first statement.
|
||||
*/
|
||||
/* va: TODO: free old structure and its content, before overwriting */
|
||||
if (cend[stackp] && (cend[stackp]->co_type != CO_UNFILLED)) {
|
||||
cend[stackp]->co_next = alloc(struct control);
|
||||
ZERO(cend[stackp]->co_next, struct control);
|
||||
|
|
@ -574,15 +637,16 @@ cp_evloop(char *string)
|
|||
cend[stackp]->co_cond = wlist->wl_next;
|
||||
if (!cend[stackp]->co_cond) {
|
||||
fprintf(stderr,
|
||||
"Error: missing while condition.\n");
|
||||
"Error: missing while condition, 'false' will be assumed.\n");
|
||||
}
|
||||
newblock;
|
||||
} else if (eq(wlist->wl_word, "dowhile")) {
|
||||
cend[stackp]->co_type = CO_DOWHILE;
|
||||
cend[stackp]->co_cond = wlist->wl_next;
|
||||
if (!cend[stackp]->co_cond) {
|
||||
/* va: prevent misinterpretation as trigraph sequence with \-sign */
|
||||
fprintf(stderr,
|
||||
"Error: missing dowhile condition.\n");
|
||||
"Error: missing dowhile condition, '?\?\?' will be assumed.\n");
|
||||
}
|
||||
newblock;
|
||||
} else if (eq(wlist->wl_word, "repeat")) {
|
||||
|
|
@ -592,10 +656,11 @@ cp_evloop(char *string)
|
|||
} else {
|
||||
char *s;
|
||||
double *dd;
|
||||
wlist = cp_variablesubst(cp_bquote(
|
||||
cp_doglob(wl_copy(wlist))));
|
||||
s = wlist->wl_next->wl_word;
|
||||
|
||||
struct wordlist *t; /*CDHW*/
|
||||
/*CDHW wlist = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(wlist)))); Wrong order? Leak? CDHW*/
|
||||
t = cp_doglob(cp_bquote(cp_variablesubst(wl_copy(wlist)))); /*CDHW leak from cp_doglob? */
|
||||
s = t->wl_next->wl_word;
|
||||
|
||||
dd = ft_numparse(&s, FALSE);
|
||||
if (dd) {
|
||||
if (*dd < 0) {
|
||||
|
|
@ -607,7 +672,8 @@ cp_evloop(char *string)
|
|||
} else
|
||||
fprintf(cp_err,
|
||||
"Error: bad repeat argument %s\n",
|
||||
wlist->wl_next->wl_word);
|
||||
t->wl_next->wl_word); /* CDHW */
|
||||
wl_free(t); t = NULL; /* CDHW */
|
||||
}
|
||||
newblock;
|
||||
} else if (eq(wlist->wl_word, "if")) {
|
||||
|
|
@ -618,6 +684,7 @@ cp_evloop(char *string)
|
|||
"Error: missing if condition.\n");
|
||||
}
|
||||
newblock;
|
||||
|
||||
} else if (eq(wlist->wl_word, "foreach")) {
|
||||
cend[stackp]->co_type = CO_FOREACH;
|
||||
if (wlist->wl_next) {
|
||||
|
|
@ -628,7 +695,7 @@ cp_evloop(char *string)
|
|||
} else
|
||||
fprintf(stderr,
|
||||
"Error: missing foreach variable.\n");
|
||||
wlist = cp_doglob(wlist);
|
||||
wlist = cp_doglob(wlist); /*CDHW Possible leak around here? */
|
||||
cend[stackp]->co_text = wl_copy(wlist);
|
||||
newblock;
|
||||
} else if (eq(wlist->wl_word, "label")) {
|
||||
|
|
@ -642,6 +709,7 @@ cp_evloop(char *string)
|
|||
"Warning: ignored extra junk after label.\n");
|
||||
} else
|
||||
fprintf(stderr, "Error: missing label.\n");
|
||||
|
||||
} else if (eq(wlist->wl_word, "goto")) {
|
||||
/* Incidentally, this won't work if the values 1 and 2 ever get
|
||||
* to be valid character pointers -- I think it's reasonably
|
||||
|
|
@ -685,12 +753,12 @@ cp_evloop(char *string)
|
|||
cend[stackp]->co_prev->co_next = NULL;
|
||||
x = cend[stackp];
|
||||
cend[stackp] = cend[stackp]->co_parent;
|
||||
tfree(x);
|
||||
tfree(x); x=NULL;
|
||||
} else {
|
||||
x = cend[stackp];
|
||||
cend[stackp] = cend[stackp]->co_parent;
|
||||
cend[stackp]->co_children = NULL;
|
||||
tfree(x);
|
||||
tfree(x); x=NULL;
|
||||
}
|
||||
} else if (eq(wlist->wl_word, "else")) {
|
||||
if (!cend[stackp]->co_parent ||
|
||||
|
|
@ -708,14 +776,15 @@ cp_evloop(char *string)
|
|||
}
|
||||
} else {
|
||||
cend[stackp]->co_type = CO_STATEMENT;
|
||||
cend[stackp]->co_text = wlist;
|
||||
cend[stackp]->co_text = wl_copy(wlist);
|
||||
}
|
||||
|
||||
if (!cend[stackp]->co_parent) {
|
||||
x = cend[stackp];
|
||||
/* We have to toss this do-while loop in here so
|
||||
* that gotos at the top level will work.
|
||||
*/
|
||||
do {
|
||||
do { nn = 0; /* CDHW */
|
||||
i = doblock(x, &nn);
|
||||
switch (*i) {
|
||||
case NORMAL:
|
||||
|
|
@ -737,15 +806,20 @@ cp_evloop(char *string)
|
|||
x = x->co_next;
|
||||
} while (x);
|
||||
}
|
||||
if (string)
|
||||
wl_free(wlist); wlist = NULL;
|
||||
if (string) {
|
||||
return (1); /* The return value is irrelevant. */
|
||||
}
|
||||
}
|
||||
wl_free(wlist); wlist = NULL;
|
||||
return (0); /* va: which value? */
|
||||
}
|
||||
|
||||
/* This blows away the control structures... */
|
||||
void
|
||||
cp_resetcontrol(void)
|
||||
{
|
||||
fprintf(cp_err, "Warning: clearing control structures\n");
|
||||
if (cend[stackp] && cend[stackp]->co_parent)
|
||||
fprintf(cp_err, "Warning: EOF before block terminated\n");
|
||||
/* We probably should free the control structures... */
|
||||
|
|
@ -764,8 +838,9 @@ cp_popcontrol(void)
|
|||
fprintf(cp_err, "pop: stackp: %d -> %d\n", stackp, stackp - 1);
|
||||
if (stackp < 1)
|
||||
fprintf(cp_err, "cp_popcontrol: Internal Error: stack empty\n");
|
||||
else
|
||||
else {
|
||||
stackp--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -797,5 +872,3 @@ cp_toplevel(void)
|
|||
cend[stackp] = cend[stackp]->co_parent;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ struct control {
|
|||
wordlist *co_cond; /* if, while, dowhile */
|
||||
char *co_foreachvar; /* foreach */
|
||||
int co_numtimes; /* repeat, break & continue levels */
|
||||
int co_timestodo;
|
||||
wordlist *co_text; /* Ordinary text and foreach values. */
|
||||
struct control *co_parent; /* If this is inside a block. */
|
||||
struct control *co_children; /* The contents of this block. */
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ static int nop(void);
|
|||
static int nodev(void);
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
extern int X11_Init(void), X11_NewViewport(GRAPH *graph), X11_Close(void), X11_Clear(void),
|
||||
X11_DrawLine(int x1, int y1, int x2, int y2), X11_Arc(int x0, int y0, int radius, double theta1, double theta2), X11_Text(char *text, int x, int y), X11_DefineColor(int colorid, double red, double green, double blue),
|
||||
|
|
@ -34,9 +32,17 @@ extern int X11_Init(void), X11_NewViewport(GRAPH *graph), X11_Close(void), X11_
|
|||
X11_Input(REQUEST *request, RESPONSE *response);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_WINDOWS /* Grafik-IO über MS Windows */
|
||||
extern int WIN_Init(), WIN_NewViewport(), WIN_Close(), WIN_Clear(),
|
||||
WIN_DrawLine(), WIN_Arc(), WIN_Text(), WIN_DefineColor(),
|
||||
WIN_DefineLinestyle(), WIN_SetLinestyle(), WIN_SetColor(),
|
||||
WIN_Update(), WIN_DiagramReady();
|
||||
|
||||
|
||||
|
||||
extern int WPRINT_Init(), WPRINT_NewViewport(), WPRINT_Close(), WPRINT_Clear(),
|
||||
WPRINT_DrawLine(), WPRINT_Arc(), WPRINT_Text(), WPRINT_DefineColor(),
|
||||
WPRINT_DefineLinestyle(), WPRINT_SetLinestyle(), WPRINT_SetColor(),
|
||||
WPRINT_Update(), WPRINT_DiagramReady();
|
||||
#endif
|
||||
|
||||
extern int Plt5_Init(void), Plt5_NewViewport(GRAPH *graph), Plt5_Close(void), Plt5_Clear(void),
|
||||
Plt5_DrawLine(int x1, int y1, int x2, int y2), Plt5_Arc(int x0, int y0, int radius, double theta1, double theta2), Plt5_Text(char *text, int x, int y),
|
||||
|
|
@ -48,6 +54,11 @@ extern int PS_Init(void), PS_NewViewport(GRAPH *graph), PS_Close(void), PS_Clea
|
|||
PS_DefineLinestyle(), PS_SetLinestyle(int linestyleid), PS_SetColor(int colorid),
|
||||
PS_Update(void);
|
||||
|
||||
extern int GL_Init(void), GL_NewViewport(GRAPH *graph), GL_Close(void), GL_Clear(void),
|
||||
GL_DrawLine(int x1, int y1, int x2, int y2), GL_Arc(int x0, int y0, int r, double theta1, double theta2), GL_Text(char *text, int x, int y),
|
||||
GL_DefineLinestyle(), GL_SetLinestyle(int linestyleid), GL_SetColor(int colorid),
|
||||
GL_Update(void);
|
||||
|
||||
DISPDEVICE device[] = {
|
||||
|
||||
{"error", 0, 0, 0, 0, 0, 0, nop, nop,
|
||||
|
|
@ -66,6 +77,23 @@ DISPDEVICE device[] = {
|
|||
gen_DatatoScreen,},
|
||||
#endif
|
||||
|
||||
#ifdef HAS_WINDOWS /* Grafik-IO über MS Windows */
|
||||
{"Windows", 0, 0, 1000, 1000, 0, 0, WIN_Init, WIN_NewViewport,
|
||||
WIN_Close, WIN_Clear,
|
||||
WIN_DrawLine, WIN_Arc, WIN_Text, WIN_DefineColor, WIN_DefineLinestyle,
|
||||
WIN_SetLinestyle, WIN_SetColor, WIN_Update,
|
||||
nodev, nodev, nodev, gen_Input,
|
||||
gen_DatatoScreen, WIN_DiagramReady},
|
||||
|
||||
// Achtung: Namen "WinPrint" nicht ändern!
|
||||
{"WinPrint", 0, 0, 1000, 1000, 0, 0, WPRINT_Init, WPRINT_NewViewport,
|
||||
WPRINT_Close, WPRINT_Clear,
|
||||
WPRINT_DrawLine, WPRINT_Arc, WPRINT_Text, WPRINT_DefineColor, WPRINT_DefineLinestyle,
|
||||
WPRINT_SetLinestyle, WPRINT_SetColor, WPRINT_Update,
|
||||
nodev, nodev, nodev, nodev,
|
||||
gen_DatatoScreen, WPRINT_DiagramReady},
|
||||
#endif
|
||||
|
||||
#ifdef TCL_MODULE
|
||||
{"Tk", 0, 0, 1024, 864, 0, 0, sp_Tk_Init, sp_Tk_NewViewport,
|
||||
sp_Tk_Close, sp_Tk_Clear,
|
||||
|
|
@ -89,6 +117,13 @@ DISPDEVICE device[] = {
|
|||
nodev, nodev, nodev, nodev,
|
||||
gen_DatatoScreen,},
|
||||
|
||||
{"hpgl", 0, 0, 1000, 1000, 0, 0, GL_Init, GL_NewViewport,
|
||||
GL_Close, GL_Clear,
|
||||
GL_DrawLine, GL_Arc, GL_Text, nodev, nodev,
|
||||
GL_SetLinestyle, GL_SetColor, GL_Update,
|
||||
nodev, nodev, nodev, nodev,
|
||||
gen_DatatoScreen,},
|
||||
|
||||
{"printf", 0, 0, 24, 80, 0, 0, nodev, nodev,
|
||||
nodev, nodev,
|
||||
nodev, nodev, nodev, nodev, nodev,
|
||||
|
|
@ -99,6 +134,7 @@ DISPDEVICE device[] = {
|
|||
};
|
||||
|
||||
DISPDEVICE *dispdev = device + NUMELEMS(device) - 1;
|
||||
// DISPDEVICE *dispdev = device ; /* GCC257 stuertzt hier ab */
|
||||
|
||||
#define XtNumber(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
|
|
@ -124,8 +160,9 @@ DISPDEVICE *FindDev(char *name)
|
|||
void
|
||||
DevInit(void)
|
||||
{
|
||||
|
||||
char buf[128];
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
char buf[128]; /* va: used with NOT X_DISPLAY_MISSING only */
|
||||
#endif /* X_DISPLAY_MISSING */
|
||||
|
||||
/* note: do better determination */
|
||||
|
||||
|
|
@ -139,10 +176,13 @@ DevInit(void)
|
|||
#ifndef X_DISPLAY_MISSING
|
||||
/* determine display type */
|
||||
if (getenv("DISPLAY") || cp_getvar("display", VT_STRING, buf)) {
|
||||
|
||||
#ifndef X_DISPLAY_MISSING
|
||||
dispdev = FindDev("X11");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_WINDOWS
|
||||
if (!dispdev) {
|
||||
dispdev = FindDev("Windows");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -159,7 +199,6 @@ DevInit(void)
|
|||
"Warning: can't initialize display device for graphics.\n");
|
||||
dispdev = FindDev("error");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* NewViewport is responsible for filling in graph->viewport */
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ ft_cktcoms(bool terse)
|
|||
static void
|
||||
fixdotplot(wordlist *wl)
|
||||
{
|
||||
char buf[BSIZE_SP], *s;
|
||||
char *s;
|
||||
char numbuf[128]; /* Printnum Fix */
|
||||
double *d, d1, d2;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <cpdefs.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
hcomp(const void *a, const void *b)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,315 @@
|
|||
/**********
|
||||
Author: Jim Groves
|
||||
**********/
|
||||
|
||||
/*
|
||||
HPGL driver
|
||||
*/
|
||||
|
||||
/*
|
||||
1000 plotter units / inch - 1pu = 0.025mm 1pu = 1mil
|
||||
|
||||
SP - select pen
|
||||
PU - pen up (PU x,y)
|
||||
PD - pen down (PD x,y)
|
||||
LT - line type
|
||||
0 dots only at plotted points
|
||||
1 . . . . .
|
||||
2 ___ ___ ___ ___
|
||||
3 ---- ---- ---- ----
|
||||
4 ----- . ----- . ----- . -----.
|
||||
5 ---- - ---- - ---- -
|
||||
6 --- - - --- - - --- - - --- - -
|
||||
null - solid line
|
||||
IN - initialize
|
||||
DF - default values (PA, solid line, set 0)
|
||||
PA - plot absolute
|
||||
SI - absolute character size (SI width, height) in cm
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "ngspice.h"
|
||||
#include "cpdefs.h"
|
||||
#include "graph.h"
|
||||
#include "ftedbgra.h"
|
||||
#include "ftedev.h"
|
||||
#include "fteinput.h"
|
||||
|
||||
#include "variable.h"
|
||||
|
||||
#define RAD_TO_DEG (180.0 / M_PI)
|
||||
#define DEVDEP(g) (*((GLdevdep *) (g)->devdep))
|
||||
#define MAX_GL_LINES 9999
|
||||
#define SOLID 0
|
||||
#define DOTTED 1
|
||||
|
||||
#define gtype graph->grid.gridtype
|
||||
#define xoff dispdev->minx
|
||||
#define yoff dispdev->miny
|
||||
#define XOFF 25 /* printer left margin */
|
||||
#define YOFF 28 /* printer bottom margin */
|
||||
#define XTADJ 0 /* printer text adjustment x */
|
||||
#define YTADJ 0 /* printer text adjustment y */
|
||||
|
||||
#define DELXMAX 360 /* printer gridsize divisible by 10, [7-2] */
|
||||
#define DELYMAX 360 /* printer gridsize divisible by [10-8], [6-2] */
|
||||
|
||||
#define FONTWIDTH 6 /* printer default fontwidth */
|
||||
#define FONTHEIGHT 8 /* printer default fontheight */
|
||||
|
||||
typedef struct {
|
||||
int lastlinestyle; /* initial invalid value */
|
||||
int lastx, lasty, linecount;
|
||||
} GLdevdep;
|
||||
|
||||
static char *linestyle[] = {
|
||||
"", /* solid */
|
||||
"1", /* was 1 - dotted */
|
||||
"", /* longdashed */
|
||||
"3", /* shortdashed */
|
||||
"4", /* longdotdashed */
|
||||
"5", /* shortdotdashed */
|
||||
"1"
|
||||
};
|
||||
|
||||
static FILE *plotfile;
|
||||
char psfont[128], psfontsize[32], psscale[32];
|
||||
static int fontwidth = FONTWIDTH;
|
||||
static int fontheight = FONTHEIGHT;
|
||||
static int jgmult = 10;
|
||||
static int screenflag = 0;
|
||||
static double tocm = 0.0025;
|
||||
static double scale; /* Used for fine tuning */
|
||||
static int hcopygraphid;
|
||||
|
||||
extern int DestroyGraph (int id);
|
||||
extern void internalerror (char *message);
|
||||
|
||||
int GL_Init()
|
||||
{
|
||||
if (!cp_getvar("hcopyscale", VT_STRING, psscale)) {
|
||||
scale = 1.0;
|
||||
} else {
|
||||
sscanf(psscale, "%lf", &scale);
|
||||
if ((scale <= 0) || (scale > 10))
|
||||
scale = 1.0;
|
||||
}
|
||||
|
||||
dispdev->numlinestyles = NUMELEMS(linestyle);
|
||||
dispdev->numcolors = 6;
|
||||
|
||||
dispdev->width = DELXMAX * scale;
|
||||
dispdev->height = DELYMAX * scale;
|
||||
|
||||
|
||||
screenflag = 0;
|
||||
dispdev->minx = XOFF * 1.0;
|
||||
dispdev->miny = YOFF * 1.0;
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
/* devdep initially contains name of output file */
|
||||
int GL_NewViewport(graph)
|
||||
GRAPH *graph;
|
||||
{
|
||||
/* double scaleps, scalex, scaley; */
|
||||
|
||||
hcopygraphid = graph->graphid;
|
||||
|
||||
if (!(plotfile = fopen(graph->devdep, "w"))) {
|
||||
perror(graph->devdep);
|
||||
graph->devdep = (char *) NULL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (graph->absolute.width) {
|
||||
/* hardcopying from the screen */
|
||||
|
||||
screenflag = 1;
|
||||
|
||||
/* scale to fit on 8 1/2 square */
|
||||
|
||||
}
|
||||
|
||||
/* reasonable values, used in gr_ for placement */
|
||||
graph->fontwidth = fontwidth * scale; /* was 12, p.w.h. */
|
||||
graph->fontheight = fontheight * scale; /* was 24, p.w.h. */
|
||||
|
||||
graph->absolute.width = dispdev->width;
|
||||
graph->absolute.height = dispdev->height;
|
||||
/* Also done in gr_init, if called . . . */
|
||||
graph->viewportxoff = 16 * fontwidth;
|
||||
graph->viewportyoff = 8 * fontheight;
|
||||
|
||||
xoff = XOFF;
|
||||
yoff = YOFF;
|
||||
|
||||
/* start file off with a % */
|
||||
fprintf(plotfile, "IN;DF;PA;");
|
||||
fprintf(plotfile, "SI %f,%f;", tocm*jgmult*fontwidth*scale,tocm*jgmult*fontheight*scale);
|
||||
|
||||
#ifdef notdef
|
||||
if (!screenflag)
|
||||
#endif
|
||||
|
||||
graph->devdep = tmalloc(sizeof(GLdevdep));
|
||||
DEVDEP(graph).lastlinestyle = -1;
|
||||
DEVDEP(graph).lastx = -1;
|
||||
DEVDEP(graph).lasty = -1;
|
||||
DEVDEP(graph).linecount = 0;
|
||||
graph->linestyle = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GL_Close()
|
||||
{
|
||||
|
||||
/* in case GL_Close is called as part of an abort,
|
||||
w/o having reached GL_NewViewport */
|
||||
if (plotfile) {
|
||||
if (DEVDEP(currentgraph).lastlinestyle != -1) {
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
fclose(plotfile);
|
||||
plotfile = NULL;
|
||||
}
|
||||
/* In case of hardcopy command destroy the hardcopy graph
|
||||
* and reset currentgraph to graphid 1, if possible
|
||||
*/
|
||||
if (!screenflag) {
|
||||
DestroyGraph(hcopygraphid);
|
||||
currentgraph = FindGraph(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GL_Clear()
|
||||
{
|
||||
|
||||
/* do nothing */
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GL_DrawLine(x1, y1, x2, y2)
|
||||
int x1, y1, x2, y2;
|
||||
{
|
||||
|
||||
/* note: this is not extendible to more than one graph
|
||||
=> will have to give NewViewport a writeable graph XXX */
|
||||
|
||||
|
||||
if (DEVDEP(currentgraph).linecount == 0
|
||||
|| x1 != DEVDEP(currentgraph).lastx
|
||||
|| y1 != DEVDEP(currentgraph).lasty)
|
||||
{
|
||||
fprintf(plotfile, "PU;PA %d , %d ;", jgmult*(x1 + xoff), jgmult*(y1 + yoff));
|
||||
}
|
||||
if (x1 != x2 || y1 != y2) {
|
||||
fprintf(plotfile, "PD;PA %d , %d ;", jgmult*(x2 + xoff), jgmult*(y2 + yoff));
|
||||
DEVDEP(currentgraph).linecount += 1;
|
||||
}
|
||||
|
||||
DEVDEP(currentgraph).lastx = x2;
|
||||
DEVDEP(currentgraph).lasty = y2;
|
||||
DEVDEP(currentgraph).lastlinestyle = currentgraph->linestyle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int GL_Arc(x0, y0, r, theta1, theta2)
|
||||
int x0, y0, r;
|
||||
double theta1, theta2;
|
||||
{
|
||||
double x1, y1;
|
||||
double angle1, angle2;
|
||||
|
||||
while (theta1 >= theta2)
|
||||
theta2 += 2 * M_PI;
|
||||
|
||||
angle1 = (double) (RAD_TO_DEG * theta1);
|
||||
angle2 = (double) (RAD_TO_DEG * theta2);
|
||||
x1 = (double) x0 + r * cos(theta1);
|
||||
y1 = (double) y0 + r * sin(theta1);
|
||||
/*
|
||||
fprintf(plotfile, "%lf %lf moveto ", x1+(double)xoff, y1+(double)yoff);
|
||||
fprintf(plotfile, "%d %d %d %lf %lf arc\n", x0+xoff, y0+yoff, r,
|
||||
angle1, angle2);
|
||||
fprintf(plotfile, "stroke\n");
|
||||
*/
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GL_Text(text, x, y)
|
||||
char *text;
|
||||
int x, y;
|
||||
{
|
||||
|
||||
/* int savedlstyle; */
|
||||
|
||||
|
||||
/* move to (x, y) */
|
||||
|
||||
fprintf(plotfile, "PU;PA %d , %d;", jgmult*(x+xoff+XTADJ), jgmult*(y+yoff+YTADJ));
|
||||
fprintf(plotfile, "LB %s \x03", text);
|
||||
|
||||
DEVDEP(currentgraph).lastx = -1;
|
||||
DEVDEP(currentgraph).lasty = -1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
GL_SetLinestyle(linestyleid)
|
||||
int linestyleid;
|
||||
{
|
||||
|
||||
/* special case
|
||||
get it when GL_Text restores a -1 linestyle */
|
||||
if (linestyleid == -1) {
|
||||
currentgraph->linestyle = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (linestyleid < 0 || linestyleid > dispdev->numlinestyles) {
|
||||
internalerror("bad linestyleid");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (currentgraph->linestyle != linestyleid) {
|
||||
fprintf(plotfile, "LT %s ;", linestyle[linestyleid]);
|
||||
currentgraph->linestyle = linestyleid;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int GL_SetColor(colorid)
|
||||
int colorid;
|
||||
{
|
||||
/*va: unused: static int flag = 0;*/ /* A hack */
|
||||
|
||||
fprintf(plotfile, "SP %d;", colorid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GL_Update()
|
||||
{
|
||||
|
||||
fflush(plotfile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -337,10 +337,8 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
}
|
||||
|
||||
if (numNames &&
|
||||
(run->numData == 1
|
||||
&& run->refIndex != -1
|
||||
|| run->numData == 0
|
||||
&& run->refIndex == -1))
|
||||
( (run->numData == 1 && run->refIndex != -1)
|
||||
|| (run->numData == 0 && run->refIndex == -1)))
|
||||
{
|
||||
fprintf(cp_err, "Error: no data saved for %s; analysis not run\n",
|
||||
spice_analysis_get_description(((JOB *) analysisPtr)->JOBtype));
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static struct pnode * mkunode(int op, struct pnode *arg);
|
|||
static struct pnode * mkfnode(char *func, struct pnode *arg);
|
||||
static struct pnode * mknnode(double number);
|
||||
static struct pnode * mksnode(char *string);
|
||||
static void print_elem(struct element *elem); /* va: for debugging */
|
||||
void print_elem(struct element *elem); /* va: for debugging */
|
||||
|
||||
|
||||
static int lasttoken = END, lasttype;
|
||||
|
|
@ -557,7 +557,7 @@ makepnode(struct element *elem)
|
|||
}
|
||||
}
|
||||
|
||||
static void print_elem(struct element *elem)
|
||||
void print_elem(struct element *elem)
|
||||
{
|
||||
printf("e_token = %d", elem->e_token);
|
||||
if (elem->e_token == VALUE) {
|
||||
|
|
|
|||
|
|
@ -125,6 +125,9 @@ cp_ccom(wordlist *wlist, char *buf, bool esc)
|
|||
pmatches = ccmatch(buf, &commands);
|
||||
i = strlen(buf);
|
||||
}
|
||||
|
||||
tfree(buf); /*CDHW*/
|
||||
|
||||
if (!esc) {
|
||||
printem(pmatches);
|
||||
wl_free(pmatches);
|
||||
|
|
@ -574,10 +577,12 @@ cp_ccrestart(bool kwords)
|
|||
void
|
||||
throwaway(struct ccom *dbase)
|
||||
{
|
||||
if (!dbase) return; /* va: security first */
|
||||
if (dbase->cc_child)
|
||||
throwaway(dbase->cc_child);
|
||||
if (dbase->cc_sibling)
|
||||
throwaway(dbase->cc_sibling);
|
||||
tfree(dbase->cc_name); /* va: also tfree dbase->cc_name (memory leak) */
|
||||
tfree(dbase);
|
||||
return;
|
||||
}
|
||||
|
|
@ -727,8 +732,8 @@ cdelete(struct ccom *node, struct ccom **top)
|
|||
/* now free() everything and check the top */
|
||||
if (node == *top)
|
||||
*top = node->cc_sibling;
|
||||
free(node->cc_name);
|
||||
free(node);
|
||||
tfree(node->cc_name); /* va: we should allways use tfree */
|
||||
tfree(node);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ pvec(struct dvec *d)
|
|||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (d->v_plottype) {
|
||||
|
|
@ -62,6 +63,7 @@ pvec(struct dvec *d)
|
|||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (d->v_defcolor) {
|
||||
sprintf(buf2, ", color = %s", d->v_defcolor);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include "postcoms.h"
|
||||
#include "quote.h"
|
||||
#include "variable.h"
|
||||
#include "parser/complete.h"
|
||||
|
||||
/* static declarations */
|
||||
static void killplot(struct plot *pl);
|
||||
|
|
@ -609,10 +610,12 @@ killplot(struct plot *pl)
|
|||
fprintf(cp_err, "Error: can't destroy the constant plot\n");
|
||||
return;
|
||||
}
|
||||
/* pl_dvecs, pl_scale */
|
||||
for (v = pl->pl_dvecs; v; v = nv) {
|
||||
nv = v->v_next;
|
||||
vec_free(v);
|
||||
}
|
||||
/* unlink from plot_list (linked via pl_next) */
|
||||
if (pl == plot_list) {
|
||||
plot_list = pl->pl_next;
|
||||
if (pl == plot_cur)
|
||||
|
|
@ -632,9 +635,17 @@ killplot(struct plot *pl)
|
|||
tfree(pl->pl_name);
|
||||
tfree(pl->pl_typename);
|
||||
wl_free(pl->pl_commands);
|
||||
|
||||
/* Never mind about the rest... */
|
||||
|
||||
tfree(pl->pl_date); /* va: also tfree (memory leak) */
|
||||
if (pl->pl_ccom) /* va: also tfree (memory leak) */
|
||||
{
|
||||
throwaway((struct ccom *)pl->pl_ccom);
|
||||
}
|
||||
if (pl->pl_env) /* The 'environment' for this plot. */
|
||||
{
|
||||
/* va: HOW to do? */
|
||||
printf("va: killplot should tfree pl->pl_env=(%p)\n", pl->pl_env); fflush(stdout);
|
||||
}
|
||||
tfree(pl); /* va: also tfree pl itself (memory leak) */
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ Author: 1988 Jeffrey M. Hsu
|
|||
#define FONTHEIGHT 14 /* printer default fontheight */
|
||||
|
||||
typedef struct {
|
||||
int lastlinestyle; /* initial invalid value */
|
||||
int lastlinestyle, lastcolor; /* initial invalid value */
|
||||
int lastx, lasty, linecount;
|
||||
} PSdevdep;
|
||||
|
||||
|
|
@ -56,11 +56,12 @@ static char *linestyle[] = {
|
|||
};
|
||||
|
||||
static FILE *plotfile;
|
||||
char psfont[128], psfontsize[32], psscale[32];
|
||||
char psfont[128], psfontsize[32], psscale[32], pscolor[32];
|
||||
static int fontsize = FONTSIZE;
|
||||
static int fontwidth = FONTWIDTH;
|
||||
static int fontheight = FONTHEIGHT;
|
||||
static int screenflag = 0;
|
||||
static int colorflag = 0;
|
||||
static double scale; /* Used for fine tuning */
|
||||
static int xtadj; /* text adjustment x */
|
||||
static int ytadj; /* text adjustment y */
|
||||
|
|
@ -68,12 +69,16 @@ static int hcopygraphid;
|
|||
|
||||
|
||||
extern int DestroyGraph (int id);
|
||||
int PS_SetLinestyle (int linestyleid);
|
||||
extern void internalerror (char *message);
|
||||
void PS_LinestyleColor(int linestyleid, int colorid);
|
||||
void PS_SelectColor(int colorid);
|
||||
void PS_Stroke(void);
|
||||
|
||||
int
|
||||
PS_Init(void)
|
||||
{
|
||||
char pswidth[30], psheight[30];
|
||||
|
||||
if (!cp_getvar("hcopyscale", VT_STRING, psscale)) {
|
||||
scale = 1.0;
|
||||
} else {
|
||||
|
|
@ -82,11 +87,35 @@ PS_Init(void)
|
|||
scale = 1.0;
|
||||
}
|
||||
|
||||
dispdev->numlinestyles = NUMELEMS(linestyle);
|
||||
if (!cp_getvar("hcopypscolor", VT_STRING, pscolor)) {
|
||||
colorflag = 0;
|
||||
dispdev->numcolors = 2;
|
||||
dispdev->numlinestyles = NUMELEMS(linestyle);
|
||||
} else {
|
||||
colorflag = 1;
|
||||
dispdev->numcolors = 18; /* don't know what the maximum should be */
|
||||
dispdev->numlinestyles = 1;
|
||||
}
|
||||
pscolor[0]='\0';
|
||||
|
||||
if (!cp_getvar("hcopywidth", VT_STRING, pswidth)) {
|
||||
dispdev->width = 7.75 * 72.0 * scale; /* (8 1/2 - 3/4) * 72 */
|
||||
} else {
|
||||
sscanf(pswidth, "%d", &(dispdev->width));
|
||||
if (dispdev->width <= 100)
|
||||
dispdev->width = 100;
|
||||
if (dispdev->width >= 10000)
|
||||
dispdev->width = 10000;
|
||||
}
|
||||
if (!cp_getvar("hcopyheight", VT_STRING, psheight)) {
|
||||
dispdev->height = dispdev->width;
|
||||
} else {
|
||||
sscanf(psheight, "%d", &(dispdev->height));
|
||||
if (dispdev->height <= 100)
|
||||
dispdev->height = 100;
|
||||
if (dispdev->height >= 10000)
|
||||
dispdev->height = 10000;
|
||||
}
|
||||
|
||||
/* The following side effects have to be considered
|
||||
* when the printer is called by com_hardcopy !
|
||||
|
|
@ -128,6 +157,7 @@ PS_Init(void)
|
|||
int
|
||||
PS_NewViewport(GRAPH *graph)
|
||||
{
|
||||
int x1,x2,y1,y2;
|
||||
hcopygraphid = graph->graphid;
|
||||
|
||||
if (!(plotfile = fopen(graph->devdep, "w"))) {
|
||||
|
|
@ -155,24 +185,37 @@ PS_NewViewport(GRAPH *graph)
|
|||
xoff = scale * XOFF;
|
||||
yoff = scale * YOFF;
|
||||
|
||||
x1 = 0.75 * 72;
|
||||
y1 = x1;
|
||||
x2 = graph->absolute.width + .75 * 72;
|
||||
y2 = graph->absolute.height + .75 * 72;
|
||||
/* start file off with a % */
|
||||
fprintf(plotfile, "%%!PS-Adobe-3.0 EPSF-3.0\n");
|
||||
fprintf(plotfile, "%%%%Creator: nutmeg\n");
|
||||
fprintf(plotfile, "%%%%BoundingBox: %d %d %d %d\n",
|
||||
(int) (.75 * 72), (int) (.75 * 72),
|
||||
(int) (8.5 * 72), (int) (8.5 * 72));
|
||||
fprintf(plotfile, "%%%%BoundingBox: %d %d %d %d\n",x1,y1,x2,y2);
|
||||
|
||||
fprintf(plotfile, "%g %g scale\n", 1.0 / scale, 1.0 / scale);
|
||||
|
||||
if (colorflag == 1){ /* set the background to color0 */
|
||||
PS_SelectColor(0);
|
||||
fprintf(plotfile,"%s setrgbcolor\n",pscolor);
|
||||
fprintf(plotfile,"newpath\n");
|
||||
fprintf(plotfile,"%d %d moveto %d %d lineto\n",x1,y1,x2,y1);
|
||||
fprintf(plotfile,"%d %d lineto %d %d lineto\n",x2,y2,x1,y2);
|
||||
fprintf(plotfile,"closepath fill\n");
|
||||
}
|
||||
|
||||
/* set up a reasonable font */
|
||||
fprintf(plotfile, "/%s findfont %d scalefont setfont\n",
|
||||
fprintf(plotfile, "/%s findfont %d scalefont setfont\n\n",
|
||||
psfont, (int) (fontsize * scale));
|
||||
|
||||
graph->devdep = tmalloc(sizeof(PSdevdep));
|
||||
DEVDEP(graph).lastlinestyle = -1;
|
||||
DEVDEP(graph).lastcolor = -1;
|
||||
DEVDEP(graph).lastx = -1;
|
||||
DEVDEP(graph).lasty = -1;
|
||||
DEVDEP(graph).linecount = 0;
|
||||
PS_SelectColor(0);
|
||||
graph->linestyle = -1;
|
||||
|
||||
return 0;
|
||||
|
|
@ -185,12 +228,8 @@ PS_Close(void)
|
|||
/* in case PS_Close is called as part of an abort,
|
||||
w/o having reached PS_NewViewport */
|
||||
if (plotfile) {
|
||||
if (DEVDEP(currentgraph).lastlinestyle != -1) {
|
||||
/* haven't stroked last path */
|
||||
fprintf(plotfile, "stroke\n");
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
fprintf(plotfile, "showpage\n");
|
||||
PS_Stroke();
|
||||
fprintf(plotfile, "showpage\n%%%%EOF\n");
|
||||
fclose(plotfile);
|
||||
plotfile = NULL;
|
||||
}
|
||||
|
|
@ -218,19 +257,14 @@ PS_DrawLine(int x1, int y1, int x2, int y2)
|
|||
/* note: this is not extendible to more than one graph
|
||||
=> will have to give NewViewport a writeable graph XXX */
|
||||
|
||||
if (DEVDEP(currentgraph).lastlinestyle != currentgraph->linestyle
|
||||
|| DEVDEP(currentgraph).linecount > MAX_PS_LINES)
|
||||
{
|
||||
fprintf(plotfile, "stroke\n");
|
||||
fprintf(plotfile, "newpath\n");
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
|
||||
if (DEVDEP(currentgraph).linecount == 0
|
||||
if (DEVDEP(currentgraph).linecount > MAX_PS_LINES
|
||||
|| DEVDEP(currentgraph).linecount == 0
|
||||
|| x1 != DEVDEP(currentgraph).lastx
|
||||
|| y1 != DEVDEP(currentgraph).lasty)
|
||||
{
|
||||
fprintf(plotfile, "%d %d moveto ", x1 + xoff, y1 + yoff);
|
||||
|| y1 != DEVDEP(currentgraph).lasty){
|
||||
PS_Stroke();
|
||||
fprintf(plotfile, "newpath\n");
|
||||
fprintf(plotfile, "%d %d moveto\n", x1 + xoff, y1 + yoff);
|
||||
DEVDEP(currentgraph).linecount += 1;
|
||||
}
|
||||
if (x1 != x2 || y1 != y2) {
|
||||
fprintf(plotfile, "%d %d lineto\n", x2 + xoff, y2 + yoff);
|
||||
|
|
@ -239,17 +273,14 @@ PS_DrawLine(int x1, int y1, int x2, int y2)
|
|||
|
||||
DEVDEP(currentgraph).lastx = x2;
|
||||
DEVDEP(currentgraph).lasty = y2;
|
||||
DEVDEP(currentgraph).lastlinestyle = currentgraph->linestyle;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PS_Arc(int x0, int y0, int r, double theta1, double theta2)
|
||||
{
|
||||
double x1, y1;
|
||||
double angle1, angle2;
|
||||
|
||||
PS_Stroke();
|
||||
while (theta1 >= theta2)
|
||||
theta2 += 2 * M_PI;
|
||||
|
||||
|
|
@ -269,19 +300,18 @@ PS_Arc(int x0, int y0, int r, double theta1, double theta2)
|
|||
void
|
||||
PS_Text(char *text, int x, int y)
|
||||
{
|
||||
|
||||
int savedlstyle;
|
||||
int savedlstyle, savedcolor;
|
||||
|
||||
/* set linestyle to solid
|
||||
or may get funny color text on some plotters */
|
||||
savedlstyle = currentgraph->linestyle;
|
||||
PS_SetLinestyle(SOLID);
|
||||
savedcolor = currentgraph->currentcolor;
|
||||
|
||||
if (DEVDEP(currentgraph).linecount) {
|
||||
fprintf(plotfile, "stroke\n");
|
||||
fprintf(plotfile, "newpath\n");
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
PS_SetLinestyle(SOLID);
|
||||
PS_SetColor(1);
|
||||
|
||||
/* stroke the path if there's an open one */
|
||||
PS_Stroke();
|
||||
/* move to (x, y) */
|
||||
fprintf(plotfile, "%d %d moveto\n", x + xoff + xtadj, y + yoff + ytadj);
|
||||
fprintf(plotfile, "(%s) show\n", text);
|
||||
|
|
@ -290,10 +320,14 @@ PS_Text(char *text, int x, int y)
|
|||
DEVDEP(currentgraph).lasty = -1;
|
||||
|
||||
/* restore old linestyle */
|
||||
PS_SetLinestyle(savedlstyle);
|
||||
|
||||
PS_SetColor(savedcolor);
|
||||
PS_SetLinestyle(savedlstyle);
|
||||
}
|
||||
|
||||
/* PS_DefineColor */
|
||||
/* PS_DefineLinestyle */
|
||||
|
||||
int
|
||||
PS_SetLinestyle(int linestyleid)
|
||||
{
|
||||
|
|
@ -304,48 +338,141 @@ PS_SetLinestyle(int linestyleid)
|
|||
currentgraph->linestyle = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (linestyleid < 0 || linestyleid > dispdev->numlinestyles) {
|
||||
internalerror("bad linestyleid");
|
||||
internalerror("bad linestyleid inside PS_SetLinestyle");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (currentgraph->linestyle != linestyleid) {
|
||||
if (DEVDEP(currentgraph).lastlinestyle != -1) {
|
||||
fprintf(plotfile, "stroke\n");
|
||||
fprintf(plotfile, "newpath\n");
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
PS_LinestyleColor(linestyleid, currentgraph->currentcolor);
|
||||
return 0;
|
||||
}
|
||||
fprintf(plotfile, "%s 0 setdash\n", linestyle[linestyleid]);
|
||||
currentgraph->linestyle = linestyleid;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PS_SetColor(int colorid)
|
||||
{
|
||||
static int flag = 0; /* A hack */
|
||||
|
||||
/* XXXX Set line style dotted for smith grids */
|
||||
if ((colorid == 18) || (colorid == 19)) {
|
||||
PS_SetLinestyle(DOTTED);
|
||||
flag = 1;
|
||||
}
|
||||
if (flag && (colorid == 1)) {
|
||||
PS_SetLinestyle(SOLID);
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
PS_LinestyleColor(currentgraph->linestyle, colorid);
|
||||
}
|
||||
|
||||
void
|
||||
PS_Update(void)
|
||||
{
|
||||
|
||||
fflush(plotfile);
|
||||
|
||||
fflush(plotfile);
|
||||
}
|
||||
|
||||
/**************** PRIVAT FUNCTIONS OF PS FRONTEND *****************************/
|
||||
|
||||
void
|
||||
PS_SelectColor(int colorid) /* should be replaced by PS_DefineColor */
|
||||
{
|
||||
char colorN[30]="", colorstring[30]="";
|
||||
char rgb[30], s_red[30]="0x", s_green[30]="0x", s_blue[30]="0x";
|
||||
long red=0, green=0, blue=0, scale=1;
|
||||
int i;
|
||||
typedef struct { int red, green, blue;} COLOR;
|
||||
/* duplicated colors from src/frontend/plotting/x11.c in rgb-style */
|
||||
const COLOR colors[]= {{ 0, 0, 0}, /*0: black */
|
||||
{255, 255, 255}, /*1: white */
|
||||
{255, 0, 0}, /*2: red */
|
||||
{ 0, 0, 255}, /*3: blue */
|
||||
{255, 165, 0}, /*4: orange */
|
||||
{ 0, 255, 0}, /*5: green */
|
||||
{255, 192, 203}, /*6: pink */
|
||||
{165, 42, 42}, /*7: brown */
|
||||
{240, 230, 140}, /*8: khaki */
|
||||
{221, 160, 221}, /*9: plum */
|
||||
{218, 112, 214}, /*10: orchid */
|
||||
{238, 130, 238}, /*11: violet */
|
||||
{176, 48, 96}, /*12: maroon */
|
||||
{ 64, 224, 208}, /*13: turqoise */
|
||||
{160, 82, 45}, /*14: sienna */
|
||||
{255, 127, 80}, /*15: coral */
|
||||
{ 0, 255, 255}, /*16: cyan */
|
||||
{255, 0, 255}, /*17: magenta */
|
||||
/*{255, 215, 0}, 18: gold */
|
||||
{ 96, 96, 96}, /*18: gray for smith grid */
|
||||
/*{255, 255, 0}, 19: yello */
|
||||
{150, 150, 150}, /*19: gray for smith grid */
|
||||
{128, 128, 128}}; /*20: gray for normal grid */
|
||||
|
||||
/* Extract the rgbcolor, format is: "rgb:<red>/<green>/<blue>" */
|
||||
sprintf(colorN, "color%d",colorid);
|
||||
if (cp_getvar(colorN, VT_STRING, colorstring)){
|
||||
for (i=0; colorstring[i]; i++)
|
||||
if (colorstring[i] == '/' || colorstring[i] == ':')
|
||||
colorstring[i] = ' ';
|
||||
|
||||
sscanf(colorstring,"%s %s %s %s",rgb, &(s_red[2]), &(s_green[2]), &(s_blue[2]));
|
||||
|
||||
if ((strlen(s_blue) == strlen(s_red) && strlen(s_green) == strlen(s_red))
|
||||
&& (strlen(s_blue) > 2) && (strlen(s_blue) < 7)){
|
||||
sscanf(s_red,"%lx",&red);
|
||||
sscanf(s_green,"%lx",&green);
|
||||
sscanf(s_blue,"%lx",&blue);
|
||||
scale= (1 << (strlen(s_blue) - 2) * 4) - 1;
|
||||
sprintf(colorstring,"%1.3f %1.3f %1.3f",
|
||||
(float) red/scale, (float) green/scale, (float) blue/scale);
|
||||
strcpy(pscolor, colorstring);
|
||||
}
|
||||
}
|
||||
if (colorid < 0 || colorid > 20) {
|
||||
internalerror("bad colorid inside PS_SelectColor");
|
||||
}else if (scale == 1){ /* colorN is not an rgbstring, use default color */
|
||||
sprintf(colorstring,"%1.3f %1.3f %1.3f",colors[colorid].red/255.0,
|
||||
colors[colorid].green/255.0, colors[colorid].blue/255.0) ;
|
||||
strcpy(pscolor, colorstring);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PS_LinestyleColor(int linestyleid, int colorid)
|
||||
{
|
||||
/* we have some different linestyles and colors:
|
||||
- color and linestyle we got via function call
|
||||
- color and linestyle we used last time for drawing
|
||||
- generated color and linestyle we'll use for drawing this time */
|
||||
/* these are the rules:
|
||||
DOTTED and colored ps -> color20 (used for grid) and SOLID
|
||||
color18 or 19 and black-white -> linestyle is DOTTED */
|
||||
|
||||
int gencolor=0,genstyle=0;
|
||||
|
||||
if (colorflag == 1){
|
||||
genstyle = SOLID;
|
||||
if (linestyleid==DOTTED)
|
||||
gencolor = 20;
|
||||
else
|
||||
gencolor = colorid;
|
||||
} else { /* colorflag == 0 -> mono*/
|
||||
if ((colorid == 18) || (colorid == 19))
|
||||
genstyle=DOTTED;
|
||||
else
|
||||
genstyle=linestyleid;
|
||||
}
|
||||
|
||||
/* change color if nessecary */
|
||||
if (colorflag == 1 && gencolor != DEVDEP(currentgraph).lastcolor){
|
||||
PS_SelectColor(gencolor);
|
||||
PS_Stroke();
|
||||
fprintf(plotfile,"%s setrgbcolor\n",pscolor);
|
||||
DEVDEP(currentgraph).lastcolor = gencolor;
|
||||
}
|
||||
currentgraph->currentcolor = colorid;
|
||||
|
||||
/* change linestyle if nessecary */
|
||||
if (colorflag == 0 && genstyle != DEVDEP(currentgraph).lastlinestyle){
|
||||
PS_Stroke();
|
||||
fprintf(plotfile, "%s 0 setdash\n", linestyle[genstyle]);
|
||||
DEVDEP(currentgraph).lastlinestyle= genstyle;
|
||||
}
|
||||
currentgraph->linestyle = linestyleid;
|
||||
}
|
||||
|
||||
void
|
||||
PS_Stroke(void)
|
||||
{
|
||||
/* strokes an open path */
|
||||
if (DEVDEP(currentgraph).linecount > 0) {
|
||||
fprintf(plotfile, "stroke\n");
|
||||
DEVDEP(currentgraph).linecount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -223,12 +223,33 @@ dosim(char *what, wordlist *wl)
|
|||
#endif /* PARALLEL_ARCH */
|
||||
if (!*wl->wl_word)
|
||||
rawfileFp = stdout;
|
||||
#ifdef __MINGW32__
|
||||
// ask if binary or ASCII, open file with w or wb hvogt 15.3.2000
|
||||
else if (ascii) {
|
||||
if(!(rawfileFp = fopen(wl->wl_word, "w"))) {
|
||||
perror(wl->wl_word);
|
||||
ft_setflag = FALSE;
|
||||
return 1;
|
||||
}
|
||||
fprintf(cp_out,"ASCII raw file\n");
|
||||
}
|
||||
else if (!ascii) {
|
||||
if(!(rawfileFp = fopen(wl->wl_word, "wb"))) {
|
||||
perror(wl->wl_word);
|
||||
ft_setflag = FALSE;
|
||||
return 1;
|
||||
}
|
||||
fprintf(cp_out,"binary raw file\n");
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
#else
|
||||
else if (!(rawfileFp = fopen(wl->wl_word, "w"))) {
|
||||
setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE);
|
||||
perror(wl->wl_word);
|
||||
ft_setflag = FALSE;
|
||||
return 1;
|
||||
}
|
||||
#endif /* __MINGW32__ */
|
||||
rawfileBinary = !ascii;
|
||||
#ifdef PARALLEL_ARCH
|
||||
} else {
|
||||
|
|
@ -239,7 +260,8 @@ dosim(char *what, wordlist *wl)
|
|||
rawfileFp = NULL;
|
||||
}
|
||||
/*save rawfile name saj*/
|
||||
if(last_used_rawfile) free((void *)last_used_rawfile);
|
||||
if(last_used_rawfile)
|
||||
tfree(last_used_rawfile);
|
||||
if(rawfileFp){
|
||||
last_used_rawfile = copy(wl->wl_word);
|
||||
}else {
|
||||
|
|
@ -293,6 +315,14 @@ dosim(char *what, wordlist *wl)
|
|||
}
|
||||
ft_curckt->ci_runonce = TRUE;
|
||||
ft_setflag = FALSE;
|
||||
|
||||
/* va: garbage collection: unlink first word (inserted here) and tfree it */
|
||||
if (!dofile) {
|
||||
tfree(ww->wl_word);
|
||||
if (wl)
|
||||
wl->wl_prev = NULL;
|
||||
tfree(ww);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ if_run(char *t, char *what, wordlist *args, char *tab)
|
|||
int j;
|
||||
int which = -1;
|
||||
IFuid specUid,optUid;
|
||||
char *s;
|
||||
|
||||
|
||||
/* First parse the line... */
|
||||
|
|
@ -168,7 +169,9 @@ if_run(char *t, char *what, wordlist *args, char *tab)
|
|||
|| eq(what,"tf")
|
||||
|| eq(what, "noise"))
|
||||
{
|
||||
(void) sprintf(buf, ".%s", wl_flatten(args));
|
||||
s = wl_flatten(args); /* va: tfree char's tmalloc'ed in wl_flatten */
|
||||
(void) sprintf(buf, ".%s", s);
|
||||
tfree(s);
|
||||
deck.li_next = deck.li_actual = NULL;
|
||||
deck.li_error = NULL;
|
||||
deck.li_linenum = 0;
|
||||
|
|
@ -301,6 +304,7 @@ if_run(char *t, char *what, wordlist *args, char *tab)
|
|||
||(eq(what, "sens"))
|
||||
||(eq(what,"tf"))
|
||||
||(eq(what, "run")) ) {
|
||||
ft_curckt->ci_curOpt = ft_curckt->ci_defOpt;
|
||||
if ((err = (*(ft_sim->doAnalyses))(ckt, 1, ft_curckt->ci_curTask))!=OK){
|
||||
ft_sperror(err, "doAnalyses");
|
||||
/* wrd_end(); */
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ bool cp_noglob = TRUE;
|
|||
bool cp_nonomatch = FALSE;
|
||||
bool cp_noclobber = FALSE;
|
||||
bool cp_ignoreeof = FALSE;
|
||||
bool cp_echo = FALSE; /* CDHW */
|
||||
|
||||
struct variable *variables = NULL;
|
||||
|
||||
|
|
@ -156,6 +157,8 @@ 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*/
|
||||
cp_echo = TRUE; /*CDHW*/
|
||||
else if (eq(copyvarname, "prompt") && (type == VT_STRING))
|
||||
cp_promptstring = copy(v->va_string);
|
||||
else if (eq(copyvarname, "ignoreeof"))
|
||||
|
|
@ -205,17 +208,30 @@ 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;
|
||||
} else {
|
||||
/* va: avoid memory leak within bcopy */
|
||||
if (u->va_type==VT_STRING) tfree(u->va_string);
|
||||
else if (u->va_type==VT_LIST) tfree(u->va_vlist);
|
||||
u->va_V = v->va_V;
|
||||
/* va_name is the same string */
|
||||
u->va_type = v->va_type;
|
||||
/* va_next left unchanged */
|
||||
tfree(v->va_name);
|
||||
tfree(v);
|
||||
/* va: old version with memory leaks
|
||||
w = u->va_next;
|
||||
bcopy(v, u, sizeof(*u));
|
||||
u->va_next = w;
|
||||
*/
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -234,7 +250,7 @@ cp_vset(char *varname, char type, char *value)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/*CDHW This needs leak checking carefully CDHW*/
|
||||
struct variable *
|
||||
cp_setparse(wordlist *wl)
|
||||
{
|
||||
|
|
@ -245,8 +261,6 @@ cp_setparse(wordlist *wl)
|
|||
int balance;
|
||||
|
||||
while (wl) {
|
||||
if(name)
|
||||
tfree(name);
|
||||
name = cp_unquote(wl->wl_word);
|
||||
wl = wl->wl_next;
|
||||
if (((wl == NULL) || (*wl->wl_word != '=')) &&
|
||||
|
|
@ -277,9 +291,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 {
|
||||
|
|
@ -329,6 +341,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 */
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
|
@ -358,9 +371,8 @@ 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 */
|
||||
}
|
||||
if(name)
|
||||
tfree(name);
|
||||
return (vars);
|
||||
}
|
||||
|
||||
|
|
@ -395,6 +407,8 @@ cp_remvar(char *varname)
|
|||
cp_nonomatch = FALSE;
|
||||
else if (eq(varname, "noclobber"))
|
||||
cp_noclobber = FALSE;
|
||||
else if (eq(varname, "echo")) /*CDHW*/
|
||||
cp_echo = FALSE; /*CDHW*/
|
||||
else if (eq(varname, "prompt")){
|
||||
/* cp_promptstring = ""; Memory leak here the last allocated reference wil be lost*/
|
||||
if(cp_promptstring) {
|
||||
|
|
@ -561,7 +575,7 @@ cp_variablesubst(wordlist *wlist)
|
|||
{
|
||||
wordlist *wl, *nwl;
|
||||
char *s, *t, buf[BSIZE_SP], wbuf[BSIZE_SP], tbuf[BSIZE_SP];
|
||||
/* MW. tbuf holds curret word after wl_splice() calls free() on it */
|
||||
/* MW. tbuf holds current word after wl_splice() calls free() on it */
|
||||
int i;
|
||||
|
||||
for (wl = wlist; wl; wl = wl->wl_next) {
|
||||
|
|
@ -595,7 +609,7 @@ cp_variablesubst(wordlist *wlist)
|
|||
}
|
||||
|
||||
(void) strcpy(tbuf, t); /* MW. Save t*/
|
||||
if (!(wl = wl_splice(wl, nwl)))
|
||||
if (!(wl = wl_splice(wl, nwl))) /*CDHW this frees wl CDHW*/
|
||||
return (NULL);
|
||||
/* This is bad... */
|
||||
for (wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev)
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ extern bool cp_noglob;
|
|||
extern bool cp_nonomatch;
|
||||
extern bool cp_noclobber;
|
||||
extern bool cp_ignoreeof;
|
||||
extern bool cp_echo;
|
||||
|
||||
// extern struct variable *variables;
|
||||
wordlist * cp_varwl(struct variable *var);
|
||||
|
|
|
|||
|
|
@ -282,6 +282,7 @@ extern int CKTdestroy( void *);
|
|||
extern int CKTdltAnal( void *, void *, void *);
|
||||
extern int CKTdltInst( void *, void *);
|
||||
extern int CKTdltMod( void *, void *);
|
||||
extern int CKTdltNNum(void *, int );
|
||||
extern int CKTdltNod( void *, void *);
|
||||
extern int CKTdoJob( void *, int , void *);
|
||||
extern void CKTdump( CKTcircuit *, double, void *);
|
||||
|
|
@ -344,7 +345,7 @@ extern int DCOaskQuest( CKTcircuit *, void *, int , IFvalue *);
|
|||
extern int DCOsetParm( CKTcircuit *, void *, int , IFvalue *);
|
||||
extern int DCTaskQuest( CKTcircuit *, void *, int , IFvalue *);
|
||||
extern int DCTsetParm( CKTcircuit *, void *, int , IFvalue *);
|
||||
extern int DCop( CKTcircuit *);
|
||||
extern int DCop( CKTcircuit *, int );
|
||||
extern int DCtrCurv( CKTcircuit *, int );
|
||||
extern int DCtran( CKTcircuit *, int );
|
||||
extern int DISTOan(CKTcircuit *, int);
|
||||
|
|
|
|||
|
|
@ -103,6 +103,11 @@ struct timeb timebegin;
|
|||
#ifdef HAVE_INDEX
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
#else /* va: no index, but strchr */
|
||||
#ifdef HAVE_STRCHR
|
||||
#define index strchr
|
||||
#define rindex strrchr
|
||||
#endif /* va: no index, but strchr */
|
||||
#endif
|
||||
|
||||
#ifdef HAS_TIME_
|
||||
|
|
@ -115,6 +120,10 @@ struct timeb timebegin;
|
|||
#define index strchr
|
||||
#endif
|
||||
|
||||
#ifdef HAS_WINDOWS
|
||||
#include "wstdio.h"
|
||||
#endif
|
||||
|
||||
extern char *gettok(char **s);
|
||||
extern char *gettok_noparens(char **s);
|
||||
extern int get_l_paren(char **s);
|
||||
|
|
|
|||
18
src/main.c
18
src/main.c
|
|
@ -45,6 +45,8 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
extern void DevInit(void);
|
||||
|
||||
/* Main options */
|
||||
static bool ft_servermode = FALSE;
|
||||
static bool ft_batchmode = FALSE;
|
||||
|
|
@ -210,7 +212,7 @@ int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator)
|
|||
SIMinfo.numDevices = DEVmaxnum = num_devices();
|
||||
SIMinfo.devices = devices_ptr();
|
||||
SIMinfo.numAnalyses = spice_num_analysis();
|
||||
SIMinfo.analyses = spice_analysis_ptr();
|
||||
SIMinfo.analyses = (IFanalysis **)spice_analysis_ptr();
|
||||
#endif /* SIMULATOR */
|
||||
|
||||
SPfrontEnd = frontEnd;
|
||||
|
|
@ -302,8 +304,13 @@ append_to_stream(FILE *dest, FILE *source)
|
|||
OUTattributes
|
||||
};
|
||||
#endif
|
||||
|
||||
int
|
||||
#ifdef HAS_WINDOWS
|
||||
xmain(int argc, char **argv)
|
||||
#else
|
||||
main(int argc, char **argv)
|
||||
#endif
|
||||
{
|
||||
int c;
|
||||
int err;
|
||||
|
|
@ -377,7 +384,7 @@ main(int argc, char **argv)
|
|||
#ifdef MALLOCTRACE
|
||||
mallocTraceInit("malloc.out");
|
||||
#endif
|
||||
#ifdef HAVE_ISATTY
|
||||
#if defined(HAVE_ISATTY) && !defined(HAS_WINDOWS)
|
||||
istty = (bool) isatty(fileno(stdin));
|
||||
#endif
|
||||
|
||||
|
|
@ -566,11 +573,8 @@ main(int argc, char **argv)
|
|||
asprintf(&s, "%s/.spiceinit", pw->pw_dir);
|
||||
#else /* ~ HAVE_ASPRINTF */
|
||||
#define INITSTR "/.spiceinit"
|
||||
if ( (s=(char *) malloc(1 + strlen(pw->pw_dir)+strlen(INITSTR))) == NULL){
|
||||
fprintf(stderr,"malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
sprintf(s,"%s%s",pw->pw_dir,INITSTR);
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -42,19 +42,13 @@ mkvar(char **p, char *path_prefix, char *var_dir, char *env_var)
|
|||
asprintf(p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir);
|
||||
#else /* ~ HAVE_ASPRINTF */
|
||||
if (buffer){
|
||||
if ( (*p = (char *) malloc(strlen(buffer)+1)) == NULL){
|
||||
fprintf(stderr,"malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
p = (char *) tmalloc(strlen(buffer)+1);
|
||||
sprintf(*p,"%s",buffer);
|
||||
/* asprintf(p, "%s", buffer); */
|
||||
}
|
||||
else{
|
||||
if ( (*p = (char *) malloc(strlen(path_prefix) +
|
||||
strlen(DIR_PATHSEP) + strlen(var_dir) + 1)) == NULL){
|
||||
fprintf(stderr,"malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
ip = (char *) tmalloc(strlen(path_prefix) +
|
||||
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); */
|
||||
}
|
||||
|
|
@ -89,9 +83,9 @@ ivars(void)
|
|||
void
|
||||
cleanvars(void)
|
||||
{
|
||||
txfree(News_File);
|
||||
txfree(Default_MFB_Cap);
|
||||
txfree(Help_Path);
|
||||
txfree(Lib_Path);
|
||||
txfree(Spice_Path);
|
||||
tfree(News_File);
|
||||
tfree(Default_MFB_Cap);
|
||||
tfree(Help_Path);
|
||||
tfree(Lib_Path);
|
||||
tfree(Spice_Path);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,8 +235,10 @@ get_r_paren(char **s)
|
|||
|
||||
#ifndef bcopy
|
||||
void
|
||||
bcopy(register char *from, register char *to, register int num)
|
||||
bcopy(const void *vfrom, void *vto, size_t num)
|
||||
{
|
||||
register const char *from=vfrom;
|
||||
register char *to=vto;
|
||||
while (num-- > 0)
|
||||
*to++ = *from++;
|
||||
return;
|
||||
|
|
@ -246,12 +248,13 @@ bcopy(register char *from, register char *to, register int num)
|
|||
#ifndef bzero
|
||||
/* can't declare void here, because we've already used it in this file */
|
||||
/* and haven't declared it void before the use */
|
||||
int
|
||||
bzero(register char *ptr, register int num)
|
||||
void
|
||||
bzero(void *vptr, size_t num)
|
||||
{
|
||||
register char *ptr=vptr;
|
||||
while (num-- > 0)
|
||||
*ptr++ = '\0';
|
||||
return (0);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ char * rindex(register char *s,register char c );
|
|||
|
||||
#ifndef HAVE_BCOPY
|
||||
|
||||
void bcopy(register char *from, register char *to, register int num);
|
||||
int bzero(register char *ptr, register int num);
|
||||
void bcopy(const void *from, void *to, size_t num);
|
||||
void bzero(void *ptr, size_t num);
|
||||
|
||||
#endif /* HAVE_BCOPY */
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
(*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,(void*)ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,(IFuid)NULL,IF_REAL,numNames,nameList,
|
||||
IF_REAL,&acPlot);
|
||||
tfree(nameList);
|
||||
|
||||
|
||||
ipc_send_dcop_prefix();
|
||||
|
|
@ -169,6 +170,7 @@ ACan(CKTcircuit *ckt, int restart)
|
|||
(void*)ckt->CKTcurJob,
|
||||
ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList,
|
||||
IF_COMPLEX,&acPlot);
|
||||
tfree(nameList);
|
||||
if(error) return(error);
|
||||
|
||||
if (((ACAN*)ckt->CKTcurJob)->ACstepType != LINEAR) {
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ int DCOaskQuest( CKTcircuit *, void *, int , IFvalue *);
|
|||
int DCOsetParm( CKTcircuit *, void *, int , IFvalue *);
|
||||
int DCTaskQuest( CKTcircuit *, void *, int , IFvalue *);
|
||||
int DCTsetParm( CKTcircuit *, void *, int , IFvalue *);
|
||||
int DCop( CKTcircuit *);
|
||||
int DCop( CKTcircuit *, int );
|
||||
int DCtrCurv( CKTcircuit *, int );
|
||||
int DCtran( CKTcircuit *, int );
|
||||
int DISTOan(CKTcircuit *, int);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Modified: 2000 AlansFixes
|
|||
|
||||
|
||||
int
|
||||
DCop(CKTcircuit *ckt)
|
||||
DCop(CKTcircuit *ckt, int notused)
|
||||
{
|
||||
int CKTload(CKTcircuit *ckt);
|
||||
int converged;
|
||||
|
|
@ -26,6 +26,7 @@ DCop(CKTcircuit *ckt)
|
|||
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
|
||||
(void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname,
|
||||
(IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&plot);
|
||||
tfree(nameList);
|
||||
if(error) return(error);
|
||||
|
||||
converged = CKTop(ckt,
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ int Size_Not_Found;
|
|||
{ model->BSIM3GatesidewallJctPotential = 0.1;
|
||||
fprintf(stderr, "Given pbswg is less than 0.1. Pbswg is set to 0.1.\n");
|
||||
}
|
||||
FREE(model->pSizeDependParamKnot);
|
||||
model->pSizeDependParamKnot = NULL;
|
||||
pLastKnot = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,12 +33,8 @@ IFnewUid(void *ckt, IFuid * newuid, IFuid olduid, char *suffix, int type,
|
|||
#ifdef HAVE_ASPRINTF
|
||||
asprintf(&newname, "%s#%s", (char *) olduid, suffix);
|
||||
#else /* ~ HAVE_ASPRINTF */
|
||||
if ( (newname = (char *) malloc(strlen((char *) olduid) +
|
||||
strlen(suffix) + 2)) /* 2 = strlen("#\0") */
|
||||
== NULL){
|
||||
fprintf(stderr,"malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
newname = (char *) tmalloc(strlen((char *) olduid) +
|
||||
strlen(suffix) + 2); /* 2 = strlen("#\0") */
|
||||
sprintf(newname, "%s#%s", (char *) olduid, suffix);
|
||||
#endif /* HAVE_ASPRINTF */
|
||||
|
||||
|
|
@ -47,10 +43,7 @@ IFnewUid(void *ckt, IFuid * newuid, IFuid olduid, char *suffix, int type,
|
|||
#ifdef HAVE_ASPRINTF
|
||||
asprintf(&newname, "%s", suffix);
|
||||
#else /* ~ HAVE_ASPRINTF */
|
||||
if ( (newname = (char *) malloc(strlen(suffix) + 2 )) == NULL){
|
||||
fprintf(stderr,"malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
newname = (char *) tmalloc(strlen(suffix) + 1 );
|
||||
sprintf(newname, "%s", suffix);
|
||||
#endif /* HAVE_ASPRINTF */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@ dot_ac(char *line, void *ckt, INPtables *tab, card *current,
|
|||
INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */
|
||||
ptemp.iValue = 1;
|
||||
GCA(INPapName, (ckt, which, foo, steptype, &ptemp));
|
||||
tfree(steptype);
|
||||
parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* number of points */
|
||||
GCA(INPapName, (ckt, which, foo, "numsteps", parm));
|
||||
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */
|
||||
|
|
@ -306,11 +307,11 @@ dot_dc(char *line, void *ckt, INPtables *tab, card *current,
|
|||
INPinsert(&name, tab);
|
||||
ptemp.uValue = name;
|
||||
GCA(INPapName, (ckt, which, foo, "name2", &ptemp));
|
||||
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstart1 */
|
||||
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstart2 */
|
||||
GCA(INPapName, (ckt, which, foo, "start2", parm));
|
||||
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstop1 */
|
||||
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstop2 */
|
||||
GCA(INPapName, (ckt, which, foo, "stop2", parm));
|
||||
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vinc1 */
|
||||
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vinc2 */
|
||||
GCA(INPapName, (ckt, which, foo, "step2", parm));
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -40,18 +40,12 @@ char *INPerror(int type)
|
|||
asprintf(&ebuf, "%s\n", val);
|
||||
#else /* ~ HAVE_ASPRINTF */
|
||||
if (errRtn){
|
||||
if ( (ebuf = (char *) malloc(strlen(val) +
|
||||
strlen(errRtn) + 25)) == NULL){
|
||||
fprintf(stderr,"malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
ebuf = (char *) tmalloc(strlen(val) +
|
||||
strlen(errRtn) + 25);
|
||||
sprintf(ebuf, "%s detected in routine \"%s\"\n", val, errRtn);
|
||||
}
|
||||
else{
|
||||
if ( (ebuf = (char *) malloc(strlen(val) + 2)) == NULL){
|
||||
fprintf(stderr,"malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
ebuf = (char *) tmalloc(strlen(val) + 2);
|
||||
sprintf(ebuf, "%s\n", val);
|
||||
}
|
||||
#endif /* HAVE_ASPRINTF */
|
||||
|
|
|
|||
217
src/tclspice.c
217
src/tclspice.c
|
|
@ -22,6 +22,14 @@
|
|||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif /* HAVE_STRING_H */
|
||||
#ifdef __MINGW32__
|
||||
#include <stdarg.h>
|
||||
#include <windef.h>
|
||||
#include <winbase.h> /* Sleep */
|
||||
#define srandom(a) srand(a) /* srandom */
|
||||
#else
|
||||
#include <unistd.h> /* usleep */
|
||||
#endif /* __MINGW32__ */
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
|
|
@ -52,9 +60,23 @@ extern jmp_buf jbuf;
|
|||
#include <dvec.h>
|
||||
#include <plot.h>
|
||||
#include <tcl.h>
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
#undef WIN32
|
||||
#endif
|
||||
#include <blt.h>
|
||||
#include <sim.h>
|
||||
|
||||
/* defines for Tcl support
|
||||
* Tcl 8.3 and Tcl 8.4 support,
|
||||
* suggested by http://mini.net/tcl/3669, 07.03.03 */
|
||||
#ifndef CONST84
|
||||
#define CONST84
|
||||
#endif /* CONST84 */
|
||||
/* Arguments of Tcl_CmpProc for Tcl/Tk 8.4.x */
|
||||
#define TCL_CMDPROCARGS(clientData,interp,argc,argv) \
|
||||
(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
|
||||
|
||||
/*For get_output*/
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
|
@ -90,8 +112,7 @@ static int ownVectors = 0;
|
|||
static Tcl_Interp *spice_interp=NULL;
|
||||
#define save_interp() \
|
||||
do {\
|
||||
if ((spice_interp = Tcl_GetMaster(interp)) == NULL)\
|
||||
spice_interp = interp;\
|
||||
spice_interp = interp;\
|
||||
} while(0)
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
@ -106,11 +127,10 @@ static int blt_vnum = 0;
|
|||
|
||||
/*Native Tcl functions */
|
||||
|
||||
static int spice_header(ClientData clientData, Tcl_Interp *interp,
|
||||
int args, char **argv){
|
||||
static int spice_header TCL_CMDPROCARGS(clientData,interp,argc,argv){
|
||||
char buf[256];
|
||||
char *date, *name, *title;
|
||||
if (args != 1) {
|
||||
if (argc != 1) {
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::spice_header",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
|
@ -126,12 +146,11 @@ static int spice_header(ClientData clientData, Tcl_Interp *interp,
|
|||
}
|
||||
|
||||
|
||||
static int spice_data(ClientData clientData, Tcl_Interp *interp,
|
||||
int args, char **argv){
|
||||
static int spice_data TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
char buf[256];
|
||||
int i, type;
|
||||
char *name;
|
||||
if (args != 1) {
|
||||
if (argc != 1) {
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::spice_data",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
|
@ -230,17 +249,16 @@ void blt_relink(int index,void *tmp){
|
|||
/* This copys the last Spice state vector to the given blt_vector
|
||||
* arg1: blt_vector
|
||||
*/
|
||||
static int lastVector(ClientData clientData, Tcl_Interp *interp,
|
||||
int args, char **argv){
|
||||
static int lastVector TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
Blt_Vector *vec;
|
||||
char *blt;
|
||||
int i;
|
||||
double *V;
|
||||
if (args != 2) {
|
||||
if (argc != 2) {
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::lastVector vecName",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
blt = argv[1];
|
||||
blt = (char *)argv[1];
|
||||
if(Blt_GetVector(interp,blt,&vec)){
|
||||
Tcl_SetResult(interp, "Bad blt vector ",TCL_STATIC);
|
||||
Tcl_AppendResult(interp, (char *)blt, TCL_STATIC);
|
||||
|
|
@ -267,20 +285,19 @@ static int lastVector(ClientData clientData, Tcl_Interp *interp,
|
|||
*arg3: start copy index, optional
|
||||
*arg4: end copy index. optional
|
||||
*/
|
||||
static int spicetoblt(ClientData clientData, Tcl_Interp *interp,
|
||||
int args, char **argv){
|
||||
static int spicetoblt TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
Blt_Vector *vec;
|
||||
int index, i;
|
||||
char *blt, *var;
|
||||
int start=0,end=-1,len;
|
||||
|
||||
if (args < 3 || args > 5) {
|
||||
if (argc < 3 || argc > 5) {
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::spicetoblt spice_variable vecName ?start? ?end?",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
var = argv[1];
|
||||
blt = argv[2];
|
||||
var = (char *)argv[1];
|
||||
blt = (char *)argv[2];
|
||||
|
||||
for(i=0;i < blt_vnum && strcmp(var,vectors[i].name);i++);
|
||||
|
||||
|
|
@ -297,9 +314,9 @@ static int spicetoblt(ClientData clientData, Tcl_Interp *interp,
|
|||
}
|
||||
|
||||
|
||||
if(args >= 4)
|
||||
if(argc >= 4)
|
||||
start = atoi(argv[3]);
|
||||
if(args == 5)
|
||||
if(argc == 5)
|
||||
end = atoi(argv[4]);
|
||||
if(vectors[index].length) {
|
||||
pthread_mutex_lock(&vectors[index].mutex);
|
||||
|
|
@ -353,7 +370,11 @@ static int _thread_stop(){
|
|||
while(!fl_exited && timeout < 100){
|
||||
ft_intrpt = TRUE;
|
||||
timeout++;
|
||||
sleep(1);
|
||||
#ifdef __MINGW32__
|
||||
Sleep(10); /* va: windows native */
|
||||
#else
|
||||
usleep(10000);
|
||||
#endif
|
||||
}
|
||||
if(!fl_exited) {
|
||||
fprintf(stderr,"couldn't stop tclspice\n");
|
||||
|
|
@ -369,14 +390,14 @@ static int _thread_stop(){
|
|||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int _run(int args,char **argv){
|
||||
static int _run(int argc,char **argv){
|
||||
char buf[1024] = "", *string;
|
||||
int i;
|
||||
sighandler_t oldHandler;
|
||||
bool fl_bg = FALSE;
|
||||
/* run task in background if preceeded by "bg"*/
|
||||
if(!strcmp(argv[0],"bg")) {
|
||||
args--;
|
||||
argc--;
|
||||
argv = &argv[1];
|
||||
fl_bg = TRUE;
|
||||
}
|
||||
|
|
@ -389,7 +410,7 @@ static int _run(int args,char **argv){
|
|||
}
|
||||
|
||||
/*build a char * to pass to cp_evloop */
|
||||
for(i=0;i<args;i++) {
|
||||
for(i=0;i<argc;i++) {
|
||||
strcat(buf,argv[i]);
|
||||
strcat(buf," ");
|
||||
}
|
||||
|
|
@ -409,7 +430,7 @@ static int _run(int args,char **argv){
|
|||
} else
|
||||
/* backwards compatability with old command */
|
||||
if(!strcmp(argv[0],"stop"))
|
||||
if(args > 1)
|
||||
if(argc > 1)
|
||||
cp_evloop(buf);
|
||||
else{
|
||||
_thread_stop();
|
||||
|
|
@ -432,28 +453,26 @@ static int _run(int args,char **argv){
|
|||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int _tcl_dispatch(ClientData clientData, Tcl_Interp *interp,
|
||||
int args, char **argv){
|
||||
static int _tcl_dispatch TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
int i;
|
||||
save_interp();
|
||||
/* Looks backwards through the first command and strips the :: part */
|
||||
for(i = strlen(argv[0])-1;i > 0;i--)
|
||||
if(argv[0][i] == *":")
|
||||
argv[0] += i + 1;
|
||||
return _run(args,argv);
|
||||
return _run(argc,(char **)argv);
|
||||
}
|
||||
|
||||
|
||||
/* Runs the spice command given in spice <cmd>*/
|
||||
static int _spice_dispatch(ClientData clientData, Tcl_Interp *interp,
|
||||
int args, char **argv){
|
||||
static int _spice_dispatch TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
save_interp();
|
||||
if(args == 1) return TCL_OK;
|
||||
return _run(args-1,&argv[1]);
|
||||
if(argc == 1) return TCL_OK;
|
||||
return _run(argc-1,(char **)&argv[1]);
|
||||
}
|
||||
|
||||
/*Checks if spice is runnuing in the background */
|
||||
static int running(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int running TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
Tcl_SetObjResult(interp,Tcl_NewIntObj((long) (fl_running && !fl_exited)));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
|
@ -477,7 +496,7 @@ inline static struct plot * get_plot(int plot){
|
|||
}
|
||||
|
||||
/*Outputs the names of all variables in the plot */
|
||||
static int plot_variables(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int plot_variables TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
struct plot *pl;
|
||||
int plot;
|
||||
struct dvec *v;
|
||||
|
|
@ -501,7 +520,7 @@ static int plot_variables(ClientData clientData, Tcl_Interp *interp, int argc, c
|
|||
}
|
||||
|
||||
/*returns the value of a variable */
|
||||
static int plot_get_value(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int plot_get_value TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
struct plot *pl;
|
||||
struct dvec *v;
|
||||
char *name;
|
||||
|
|
@ -512,7 +531,7 @@ static int plot_get_value(ClientData clientData, Tcl_Interp *interp, int argc, c
|
|||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
name = argv[1];
|
||||
name = (char *)argv[1];
|
||||
plot = atoi(argv[2]);
|
||||
index = atoi(argv[3]);
|
||||
|
||||
|
|
@ -536,7 +555,7 @@ static int plot_get_value(ClientData clientData, Tcl_Interp *interp, int argc, c
|
|||
|
||||
|
||||
/*The length of the first vector in a plot*/
|
||||
static int plot_datapoints(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int plot_datapoints TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
struct plot *pl;
|
||||
struct dvec *v;
|
||||
int plot;
|
||||
|
|
@ -561,11 +580,11 @@ static int plot_datapoints(ClientData clientData, Tcl_Interp *interp, int argc,
|
|||
|
||||
/*These functions give you infomation about a plot*/
|
||||
|
||||
static int plot_title(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int plot_title TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
struct plot *pl;
|
||||
int plot;
|
||||
if (argc != 2) {
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::plot_nvars plot",TCL_STATIC);
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::plot_title plot",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -579,12 +598,12 @@ static int plot_title(ClientData clientData, Tcl_Interp *interp, int argc, char
|
|||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int plot_date(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int plot_date TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
struct plot *pl;
|
||||
|
||||
int plot;
|
||||
if (argc != 2) {
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::plot_nvars plot",TCL_STATIC);
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::plot_date plot",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -598,11 +617,11 @@ static int plot_date(ClientData clientData, Tcl_Interp *interp, int argc, char *
|
|||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int plot_name(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int plot_name TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
struct plot *pl;
|
||||
int plot;
|
||||
if (argc != 2) {
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::plot_nvars plot",TCL_STATIC);
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::plot_name plot",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -618,7 +637,7 @@ static int plot_name(ClientData clientData, Tcl_Interp *interp, int argc, char *
|
|||
|
||||
/*number of variables in a plot*/
|
||||
|
||||
static int plot_nvars(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int plot_nvars TCL_CMDPROCARGS(clientData,interp,argc,argv){
|
||||
struct plot *pl;
|
||||
struct dvec *v;
|
||||
int plot;
|
||||
|
|
@ -647,7 +666,7 @@ static int plot_nvars(ClientData clientData, Tcl_Interp *interp, int argc, char
|
|||
/*******************************************/
|
||||
|
||||
/*Runs a tcl script and returns the output*/
|
||||
static int get_output(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
|
||||
static int get_output TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
FILE *pipein;
|
||||
int tmp_1,tmp_2=0;
|
||||
char buf[1024];
|
||||
|
|
@ -707,7 +726,7 @@ static int get_output(ClientData clientData, Tcl_Interp *interp, int argc, char
|
|||
/* Returns the current value of a parameter
|
||||
* has lots of memory leaks
|
||||
*/
|
||||
static int get_param(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int get_param TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
wordlist *wl= NULL;
|
||||
char *device, *param;
|
||||
struct variable *v;
|
||||
|
|
@ -721,8 +740,8 @@ static int get_param(ClientData clientData, Tcl_Interp *interp, int argc, char *
|
|||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
device = argv[1];
|
||||
param = argv[2];
|
||||
device = (char *)argv[1];
|
||||
param = (char *)argv[2];
|
||||
/* copied from old_show(wordlist *) */
|
||||
v = (*if_getparam)(ft_curckt->ci_ckt,
|
||||
&device, param, 0, 0);
|
||||
|
|
@ -744,15 +763,96 @@ static int get_param(ClientData clientData, Tcl_Interp *interp, int argc, char *
|
|||
|
||||
}
|
||||
|
||||
/* va - added
|
||||
call: s. errormessage
|
||||
returns: param == all: list of all model parameters of device/model
|
||||
param == name: description of given model parameter
|
||||
*/
|
||||
int get_mod_param TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
char *name;
|
||||
char *paramname;
|
||||
GENinstance *devptr=(GENinstance *)NULL;
|
||||
GENmodel *modptr=(GENmodel *)NULL;
|
||||
IFdevice *device;
|
||||
IFparm *opt;
|
||||
IFvalue pv;
|
||||
int i, err, typecode=-1;
|
||||
char buf[128];
|
||||
bool found;
|
||||
|
||||
if (argc < 2 || argc >3) {
|
||||
Tcl_SetResult(interp,
|
||||
"Wrong # args. spice::get_mod_param device|model [all|param]", TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (ft_curckt==NULL) {
|
||||
Tcl_SetResult(interp, "No circuit loaded ",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
name = (char *)argv[1];
|
||||
if (argc>2) {
|
||||
paramname=(char *)argv[2];
|
||||
} else {
|
||||
paramname="all";
|
||||
}
|
||||
if (name==NULL || name[0]=='\0') {
|
||||
Tcl_SetResult(interp, "No model or device name provided.",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/* get the unique IFuid for name (device/model) */
|
||||
INPretrieve(&name,(INPtables *)ft_curckt->ci_symtab);
|
||||
err = (*(ft_sim->findInstance))(ft_curckt->ci_ckt,&typecode,(void **)&devptr,name,NULL,NULL);
|
||||
if (err != OK) {
|
||||
typecode = -1;
|
||||
devptr = (void *)NULL;
|
||||
err = (*(ft_sim->findModel))(ft_curckt->ci_ckt,&typecode,(void **)&modptr,name);
|
||||
}
|
||||
if (err != OK) {
|
||||
sprintf(buf,"No such device or model name %s",name);
|
||||
Tcl_SetResult(interp,buf,TCL_VOLATILE);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
device = ft_sim->devices[typecode];
|
||||
found = FALSE;
|
||||
for (i = 0; i < *(device->numModelParms); i++) {
|
||||
opt = &device->modelParms[i];
|
||||
if (opt->dataType != (IF_SET|IF_ASK|IF_REAL)) continue; /* only real IO-parameter */
|
||||
if (strcmp(paramname,"all")==0) {
|
||||
Tcl_AppendElement(interp,opt->keyword);
|
||||
found=TRUE;
|
||||
} else if (strcmp(paramname,opt->keyword)==0) {
|
||||
if (devptr)
|
||||
err = (*(ft_sim->askInstanceQuest))(ft_curckt->ci_ckt, (void *)devptr,
|
||||
opt->id, &pv, (IFvalue *)NULL);
|
||||
else
|
||||
err = (*(ft_sim->askModelQuest))(ft_curckt->ci_ckt, (void *)modptr,
|
||||
opt->id, &pv, (IFvalue *)NULL);
|
||||
if (err==OK) {
|
||||
sprintf(buf,"%g",pv.rValue); /* dataType is here always real */
|
||||
Tcl_SetResult(interp,buf,TCL_VOLATILE);
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found!=TRUE) {
|
||||
sprintf(buf,"unknown parameter %s",paramname);
|
||||
Tcl_SetResult(interp,buf,TCL_VOLATILE);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/* Direct control over the step size
|
||||
* Spice will still adjust it to keep accuracy wuithin reltol and abstol
|
||||
*/
|
||||
static int delta(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int delta TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
if (argc < 1 ||argc > 2) {
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::delta ?value?",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (!ft_curckt) {
|
||||
if (ft_curckt==NULL) {
|
||||
Tcl_SetResult(interp, "No circuit loaded ",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
|
@ -769,13 +869,13 @@ static int delta(ClientData clientData, Tcl_Interp *interp, int argc, char *argv
|
|||
/* Direct control over the maximum stepsize
|
||||
* Spice will still adjust it to keep accuracy wuithin reltol and abstol
|
||||
*/
|
||||
static int maxstep(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int maxstep TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
TRANan *job;
|
||||
if (argc < 1 ||argc > 2) {
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::maxstep ?value?",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (!ft_curckt) {
|
||||
if (ft_curckt == NULL) {
|
||||
Tcl_SetResult(interp, "No circuit loaded ",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
|
@ -809,7 +909,7 @@ int sp_Tk_Init(void) {
|
|||
|
||||
#include <graph.h>
|
||||
int sp_Tk_NewViewport(GRAPH *graph) {
|
||||
char *result;
|
||||
const char *result;
|
||||
int width, height, fontwidth, fontheight;
|
||||
graph->devdep = (char *) NULL;
|
||||
|
||||
|
|
@ -1087,7 +1187,7 @@ static int resetTriggers() {
|
|||
*arg2: Vmax
|
||||
*arg3: 1 / -1 for +ive(voltage goes +ive) or -ive trigger
|
||||
*/
|
||||
static int registerTrigger(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int registerTrigger TCL_CMDPROCARGS(clientData,interp,argc,argv){
|
||||
int i, index;
|
||||
char *var;
|
||||
struct watch *tmp;
|
||||
|
|
@ -1097,7 +1197,7 @@ static int registerTrigger(ClientData clientData, Tcl_Interp *interp, int argc,
|
|||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
var = argv[1];
|
||||
var = (char *)argv[1];
|
||||
|
||||
for(i=0;i < blt_vnum && strcmp(var,vectors[i].name);i++);
|
||||
|
||||
|
|
@ -1132,7 +1232,7 @@ static int registerTrigger(ClientData clientData, Tcl_Interp *interp, int argc,
|
|||
*arg0: Vector name
|
||||
*arg1: type
|
||||
*/
|
||||
static int unregisterTrigger(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int unregisterTrigger TCL_CMDPROCARGS(clientData,interp,argc,argv){
|
||||
int i, index, type;
|
||||
char *var;
|
||||
struct watch *tmp;
|
||||
|
|
@ -1143,7 +1243,7 @@ static int unregisterTrigger(ClientData clientData, Tcl_Interp *interp, int argc
|
|||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
var = argv[1];
|
||||
var = (char *)argv[1];
|
||||
|
||||
for(i=0;i < blt_vnum && strcmp(var,vectors[i].name);i++);
|
||||
|
||||
|
|
@ -1183,7 +1283,7 @@ static int unregisterTrigger(ClientData clientData, Tcl_Interp *interp, int argc
|
|||
/* returns:
|
||||
"vecName" "time" "stepNumber" "type"
|
||||
*/
|
||||
static int popTriggerEvent(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int popTriggerEvent TCL_CMDPROCARGS(clientData,interp,argc,argv){
|
||||
|
||||
if (argc != 1) {
|
||||
Tcl_SetResult(interp, "Wrong # args. spice::popTriggerEvent",TCL_STATIC);
|
||||
|
|
@ -1221,7 +1321,7 @@ static int popTriggerEvent(ClientData clientData, Tcl_Interp *interp, int argc,
|
|||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int listTriggers(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){
|
||||
static int listTriggers TCL_CMDPROCARGS(clientData,interp,argc,argv){
|
||||
struct watch *tmp;
|
||||
Tcl_Obj *list;
|
||||
|
||||
|
|
@ -1327,6 +1427,7 @@ int Spice_Init(Tcl_Interp *interp) {
|
|||
Tcl_CreateCommand(interp, TCLSPICE_prefix "bg", _tcl_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "halt", _tcl_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "get_param", get_param, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "get_mod_param", get_mod_param, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "delta", delta, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "maxstep", maxstep, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "running", running, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
|
|
|
|||
Loading…
Reference in New Issue