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:
stefanjones 2003-07-18 11:50:39 +00:00
parent 14483620d4
commit 54b3079232
32 changed files with 977 additions and 238 deletions

View File

@ -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}

View File

@ -157,7 +157,8 @@ libfte_a_SOURCES = \
vectors.c \
vectors.h \
where.c \
where.h
where.h \
hpgl.c
# TESTS = testcommands
#

View File

@ -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;
}

View File

@ -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. */

View File

@ -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 */

View File

@ -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;

View File

@ -1,4 +1,5 @@
#include <cpdefs.h>
#include <string.h>
int
hcomp(const void *a, const void *b)

315
src/frontend/hpgl.c Normal file
View File

@ -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;
}

View File

@ -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));

View File

@ -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) {

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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(); */

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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);
}

View File

@ -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

View File

@ -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 */

View File

@ -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) {

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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 */
}

View File

@ -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;

View File

@ -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 */

View File

@ -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);