src/frontend/**, whitespace, indentation, ...

untabify
delete-trailing-whitespace
braces
...

checked for object file invariance on linux
This commit is contained in:
rlar 2012-09-20 20:30:53 +02:00
parent f3b5336d3a
commit 7454a6d486
119 changed files with 13954 additions and 13128 deletions

View File

@ -4,8 +4,8 @@ Author: 1987 Jeffrey M. Hsu
**********/
/*
This files contains the routines to evalute arguments to a command
and prompt the user if necessary.
This files contains the routines to evalute arguments to a command
and prompt the user if necessary.
*/
#include "ngspice/ngspice.h"
@ -16,119 +16,122 @@ Author: 1987 Jeffrey M. Hsu
#include "arg.h"
#include "variable.h"
static void common(char *string, struct wordlist *wl, struct comm *command);
/* returns a private copy of the string */
char *prompt(FILE *fp)
char *
prompt(FILE *fp)
{
char buf[100];
char *p;
size_t n;
if (!fgets(buf, sizeof(buf), fp))
return NULL;
return NULL;
n = strlen(buf) - 1;
buf[n] = '\0'; /* fgets leaves the \n */
buf[n] = '\0'; /* fgets leaves the \n */
p = TMALLOC(char, n + 1);
strcpy(p, buf);
return p;
}
int countargs(wordlist *wl)
{
int number=0;
int
countargs(wordlist *wl)
{
int number = 0;
wordlist *w;
for (w = wl; w; w = w->wl_next) {
number++ ;
}
return(number);
for (w = wl; w; w = w->wl_next)
number++ ;
return (number);
}
wordlist *process(wordlist *wlist)
{
wordlist *
process(wordlist *wlist)
{
wlist = cp_variablesubst(wlist);
wlist = cp_bquote(wlist);
wlist = cp_doglob(wlist);
return (wlist);
}
void arg_print(wordlist *wl, struct comm *command)
{
void
arg_print(wordlist *wl, struct comm *command)
{
common("which variable", wl, command);
}
void arg_plot(wordlist *wl, struct comm *command)
{
void
arg_plot(wordlist *wl, struct comm *command)
{
common("which variable", wl, command);
}
void arg_load(wordlist *wl, struct comm *command)
void
arg_load(wordlist *wl, struct comm *command)
{
/* just call com_load */
command->co_func (wl);
/* just call com_load */
command->co_func(wl);
}
void arg_let(wordlist *wl, struct comm *command)
{
common("which vector", wl, command);
}
void arg_set(wordlist *wl, struct comm *command)
void
arg_set(wordlist *wl, struct comm *command)
{
common("which variable", wl, command);
}
void arg_display(wordlist *wl, struct comm *command)
void
arg_display(wordlist *wl, struct comm *command)
{
NG_IGNORE(wl);
NG_IGNORE(command);
/* just return; display does the right thing */
}
/* a common prompt routine */
static void
common(char *string, struct wordlist *wl, struct comm *command)
{
struct wordlist *w;
char *buf;
if (!countargs(wl)) {
outmenuprompt(string);
if ((buf = prompt(cp_in)) == NULL) /* prompt aborted */
return; /* don't execute command */
/* do something with the wordlist */
w = wl_cons(buf, NULL);
outmenuprompt(string);
if ((buf = prompt(cp_in)) == NULL) /* prompt aborted */
return; /* don't execute command */
/* do something with the wordlist */
w = wl_cons(buf, NULL);
w = process(w);
/* O.K. now call fn */
command->co_func (w);
w = process(w);
/* O.K. now call fn */
command->co_func(w);
}
}
void
outmenuprompt(char *string)
{
fprintf(cp_out, "%s: ", string);
fflush(cp_out);
return;
fprintf(cp_out, "%s: ", string);
fflush(cp_out);
return;
}

View File

@ -15,8 +15,9 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "variable.h"
#include "circuits.h"
# ifdef HAVE_SYS_WAIT_H
/* should be more tests here I think */
/* should be more tests here I think */
# define OK_ASPICE
# endif
@ -38,11 +39,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "../misc/mktemp.h"
/*
This is required for the GCC pre-processor and might be needed for others
Added to resolve ngspice bug 1293746
http://sourceforge.net/tracker/index.php?func=detail&aid=1293746&group_id=38962&atid=423915
This is required for the GCC pre-processor and might be needed for others
Added to resolve ngspice bug 1293746
http://sourceforge.net/tracker/index.php?func=detail&aid=1293746&group_id=38962&atid=423915
*/
#if !defined(SOLARIS) && defined (__SVR4) && defined(__sun)
#if !defined(SOLARIS) && defined(__SVR4) && defined(__sun)
# define SOLARIS
#endif
@ -54,17 +55,18 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
static RETSIGTYPE sigchild(void);
struct proc {
int pr_pid; /* The pid of the spice job. */
char *pr_rawfile; /* The temporary raw file. */
char *pr_name; /* The name of the spice run. */
char *pr_inpfile; /* The name of the input file. */
char *pr_outfile; /* The name of the (tmp) output file. */
bool pr_saveout; /* Don't (void) unlink the output file */
struct proc *pr_next; /* Link. */
} ;
int pr_pid; /* The pid of the spice job. */
char *pr_rawfile; /* The temporary raw file. */
char *pr_name; /* The name of the spice run. */
char *pr_inpfile; /* The name of the input file. */
char *pr_outfile; /* The name of the (tmp) output file. */
bool pr_saveout; /* Don't (void) unlink the output file */
struct proc *pr_next; /* Link. */
};
static struct proc *running = NULL;
static int numchanged = 0; /* How many children have changed in state. */
static int numchanged = 0; /* How many children have changed in state. */
void
com_aspice(wordlist *wl)
@ -78,11 +80,11 @@ com_aspice(wordlist *wl)
deck = wl->wl_word;
if (!cp_getvar("spicepath", CP_STRING, spicepath)) {
if (!Spice_Path || !*Spice_Path) {
fprintf(cp_err,
"No spice-3 binary is available for the aspice command.\n");
return;
}
if (!Spice_Path || !*Spice_Path) {
fprintf(cp_err,
"No spice-3 binary is available for the aspice command.\n");
return;
}
(void) strcpy(spicepath, Spice_Path);
}
@ -113,11 +115,11 @@ com_aspice(wordlist *wl)
if (pid == 0) {
if (!(freopen(deck, "r", stdin))) {
perror(deck);
exit (EXIT_BAD);
exit(EXIT_BAD);
}
if (!(freopen(output, "w", stdout))) {
perror(output);
exit (EXIT_BAD);
exit(EXIT_BAD);
}
(void) dup2(fileno(stdout), fileno(stderr));
@ -162,18 +164,19 @@ com_jobs(wordlist *wl)
return;
}
static RETSIGTYPE
sigchild(void)
{
numchanged++;
if (ft_asyncdb)
fprintf(cp_err, "%d jobs done now\n", numchanged);
if (cp_cwait) {
if (cp_cwait)
ft_checkkids();
}
return;
}
/* This gets called every once in a while, and checks to see if any
* jobs have finished. If they have it gets the data. The problem is
* that wait(0) is probably more portable, but it can't tell
@ -184,8 +187,10 @@ sigchild(void)
* On posix systems, wait() is:
* pid_t wait(int *status);
*/
int status;
void
ft_checkkids(void)
{
@ -203,47 +208,55 @@ ft_checkkids(void)
while (numchanged > 0) {
pid = wait(&status);
if (pid == -1) {
fprintf(cp_err,
"ft_checkkids: Internal Error: should be %d jobs done but there aren't any.\n",
numchanged);
fprintf(cp_err,
"ft_checkkids: Internal Error: should be %d jobs done but there aren't any.\n",
numchanged);
numchanged = 0;
running = NULL;
here = FALSE;
return;
}
for (p = running; p; p = p->pr_next) {
if (p->pr_pid == pid)
break;
lp = p;
}
if (p == NULL) {
fprintf(cp_err,
"ft_checkkids: Internal Error: Process %d not a job!\n",
"ft_checkkids: Internal Error: Process %d not a job!\n",
(int) pid);
here = FALSE;
return;
}
if (p == running)
running = p->pr_next;
else
lp->pr_next = p->pr_next;
fprintf(cp_out, "Job finished: %.60s\n", p->pr_name);
numchanged--;
ft_loadfile(p->pr_rawfile);
(void) unlink(p->pr_rawfile);
out_init();
if (!(fp = fopen(p->pr_outfile, "r"))) {
perror(p->pr_outfile);
here = FALSE;
return;
}
while (fgets(buf, BSIZE_SP, fp))
out_send(buf);
(void) fclose(fp);
if (!p->pr_saveout)
(void) unlink(p->pr_outfile);
printf("\n-----\n");
}
printf("\n");
#ifdef TIOCSTI
(void) ioctl(0, TIOCSTI, "\022"); /* Reprint the line. */
@ -252,6 +265,7 @@ ft_checkkids(void)
return;
}
/* Run a spice job remotely. See the description of the spice daemon for
* the protocol. This is no longer 4.2 specific.
*/
@ -267,8 +281,8 @@ com_rspice(wordlist *wl)
size_t n;
int to_serv[2], from_serv[2], err_serv[2];
int pid;
long pos;
int num;
long pos;
int num;
char *p;
/* Figure out where the spicedaemon is and connect to it. */
@ -281,50 +295,50 @@ com_rspice(wordlist *wl)
if (*rhost == '\0') {
fprintf(cp_err,
"Error: there is no remote ngspice.host for this site -- set \"rhost\".\n");
return;
"Error: there is no remote ngspice.host for this site -- set \"rhost\".\n");
return;
}
if (*program == '\0') {
fprintf(cp_err,
"Error: there is no remote spice program for this site -- set \"rprogram\".\n");
return;
"Error: there is no remote spice program for this site -- set \"rprogram\".\n");
return;
}
if (pipe(to_serv) < 0) {
perror("pipe to server");
return;
perror("pipe to server");
return;
}
if (pipe(from_serv) < 0) {
perror("pipe from server");
return;
perror("pipe from server");
return;
}
if (pipe(err_serv) < 0) {
perror("2nd pipe from server");
return;
perror("2nd pipe from server");
return;
}
pid = fork( );
pid = fork();
if (pid == 0) {
/* I am the "server" process */
close(to_serv[1]);
close(from_serv[0]);
close(err_serv[0]);
/* I am the "server" process */
close(to_serv[1]);
close(from_serv[0]);
close(err_serv[0]);
fclose(stdin);
fclose(stdout);
fclose(stderr);
fclose(stdin);
fclose(stdout);
fclose(stderr);
dup2(to_serv[0], 0); /* stdin */
dup2(from_serv[1], 1); /* stdout */
dup2(err_serv[1], 2); /* stderr */
dup2(to_serv[0], 0); /* stdin */
dup2(from_serv[1], 1); /* stdout */
dup2(err_serv[1], 2); /* stderr */
execlp(remote_shell, remote_shell, rhost, program, "-s", (void*)0);
/* system(com_buf); */
perror(remote_shell);
exit(-1);
execlp(remote_shell, remote_shell, rhost, program, "-s", (void*)0);
/* system(com_buf); */
perror(remote_shell);
exit(-1);
} else if (pid == -1) {
perror("fork");
return;
perror("fork");
return;
}
/* I am the "client" side */
@ -344,23 +358,23 @@ com_rspice(wordlist *wl)
continue; /* Should be careful */
}
while ((n = fread(buf, 1, BSIZE_SP, inp)) > 0)
(void) fwrite(buf, 1, strlen(buf), srv_input);
/* (void) write(s, buf, n); */
(void) fwrite(buf, 1, strlen(buf), srv_input);
/* (void) write(s, buf, n); */
wl = wl->wl_next;
fclose(inp);
fclose(inp);
}
/* (void) write(s, "@\n", 3);*/
} else {
if (ft_nutmeg || !ft_curckt) {
fprintf(cp_err, "Error: no circuits loaded\n");
fclose(srv_input);
fclose(serv);
fclose(srv_input);
fclose(serv);
return;
}
inp_list(srv_input, ft_curckt->ci_deck, ft_curckt->ci_options,
LS_DECK);
inp_list(srv_input, ft_curckt->ci_deck, ft_curckt->ci_options, LS_DECK);
}
fclose(srv_input);
/* Now wait for things to come through */
@ -369,33 +383,36 @@ com_rspice(wordlist *wl)
break;
fputs(buf, cp_out);
}
outfile = smktemp("rsp");
if ((out = fopen(outfile, "w+")) == NULL) {
perror(outfile);
(void) fclose(serv);
return;
}
if (p)
fputs(buf, out);
while ((n = fread(buf, 1, BSIZE_SP, serv)) != 0) {
fputs(buf, out);
while ((n = fread(buf, 1, BSIZE_SP, serv)) != 0)
(void) fwrite(buf, 1, n, out);
}
/* We hope that positioning info + error messages < pipe size */
while (fgets(buf, BSIZE_SP, err_outp)) {
if (!strncmp("@@@", buf, 3)) {
if (sscanf(buf, "@@@ %ld %d", &pos, &num) != 2) {
fprintf(stderr, "Error reading rawdata: %s\n", buf);
continue;
}
if (fseek(out, pos, SEEK_SET))
fprintf(stderr,
"Error adjusting rawfile: write \"%d\" at %ld\n",
num, pos);
else
fprintf(out, "%d", num);
} else
fprintf(stderr, "%s", buf);
}
while (fgets(buf, BSIZE_SP, err_outp))
if (!strncmp("@@@", buf, 3)) {
if (sscanf(buf, "@@@ %ld %d", &pos, &num) != 2) {
fprintf(stderr, "Error reading rawdata: %s\n", buf);
continue;
}
if (fseek(out, pos, SEEK_SET))
fprintf(stderr,
"Error adjusting rawfile: write \"%d\" at %ld\n",
num, pos);
else
fprintf(out, "%d", num);
} else {
fprintf(stderr, "%s", buf);
}
(void) fclose(out);
(void) fclose(serv);
@ -412,36 +429,36 @@ com_rspice(wordlist *wl)
#else
void
com_aspice(
wordlist *wl)
com_aspice(wordlist *wl)
{
NG_IGNORE(wl);
fprintf(cp_err, "Asynchronous spice jobs are not available.\n");
return;
NG_IGNORE(wl);
fprintf(cp_err, "Asynchronous spice jobs are not available.\n");
return;
}
void
com_jobs(
wordlist *wl)
com_jobs(wordlist *wl)
{
NG_IGNORE(wl);
fprintf(cp_err, "Asynchronous spice jobs are not available.\n");
return;
NG_IGNORE(wl);
fprintf(cp_err, "Asynchronous spice jobs are not available.\n");
return;
}
void
ft_checkkids(void)
{
return;
return;
}
void
com_rspice(
wordlist *wl)
com_rspice(wordlist *wl)
{
NG_IGNORE(wl);
fprintf(cp_err, "Remote spice jobs are not available.\n");
return;
NG_IGNORE(wl);
fprintf(cp_err, "Remote spice jobs are not available.\n");
return;
}
#endif

View File

@ -18,12 +18,14 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "completion.h"
static bool satisfied(struct dbcomm *d, struct plot *plot);
static void printcond(struct dbcomm *d, FILE *fp);
static int howmanysteps = 0;
static int steps = 0;
/* Set a breakpoint. Possible commands are:
* stop after n
* stop when var cond val
@ -41,45 +43,47 @@ com_stop(wordlist *wl)
double *val;
while (wl) {
if (thisone == NULL)
if (thisone == NULL) {
thisone = d = alloc(struct dbcomm);
else {
} else {
d->db_also = alloc(struct dbcomm);
d = d->db_also;
}
/* Figure out what the first condition is. */
d->db_analysis = NULL;
d->db_analysis = NULL;
if (eq(wl->wl_word, "after") && wl->wl_next) {
d->db_type = DB_STOPAFTER;
d->db_number = debugnumber;
if (!wl->wl_next->wl_word)
i = 0;
else {
if (!wl->wl_next->wl_word) {
i = 0;
} else {
#ifdef HAVE_CTYPE_H
for (s = wl->wl_next->wl_word, i = 0; *s; s++)
if (!isdigit(*s))
goto bad;
else
i = i * 10 + (*s - '0');
for (s = wl->wl_next->wl_word, i = 0; *s; s++)
if (!isdigit(*s))
goto bad;
else
i = i * 10 + (*s - '0');
#else
i = atoi(wl->wl_next->wl_word); /* etoi ??? */
i = atoi(wl->wl_next->wl_word); /* etoi ??? */
#endif
}
}
d->db_iteration = i;
wl = wl->wl_next->wl_next;
} else if (eq(wl->wl_word, "when") && wl->wl_next) {
/* cp_lexer(string) will not discriminate '=', so we have
/* cp_lexer(string) will not discriminate '=', so we have
to do it here */
if (strstr(wl->wl_next->wl_word,"=") && (!(wl->wl_next->wl_next) ||
strstr(wl->wl_next->wl_next->wl_word,"when") ||
strstr(wl->wl_next->wl_next->wl_word,"after"))) {
if (strstr(wl->wl_next->wl_word, "=") &&
(!(wl->wl_next->wl_next) ||
strstr(wl->wl_next->wl_next->wl_word, "when") ||
strstr(wl->wl_next->wl_next->wl_word, "after")))
{
/* we have vec=val in a single word */
wordlist * wln;
char** charr = TMALLOC(char*, 4) ;
wordlist *wln;
char **charr = TMALLOC(char*, 4);
char *tok = copy(wl->wl_next->wl_word);
char *tokeq = strstr(tok,"=");
char *tokafter = copy(tokeq+1);
char *tokeq = strstr(tok, "=");
char *tokafter = copy(tokeq + 1);
*tokeq = '\0';
charr[0] = tok;
charr[1] = copy("eq");
@ -89,8 +93,7 @@ com_stop(wordlist *wl)
wl_splice(wl->wl_next, wln);
}
/* continue with parsing the enhanced wordlist */
if (wl->wl_next->wl_next &&
wl->wl_next->wl_next->wl_next) {
if (wl->wl_next->wl_next && wl->wl_next->wl_next->wl_next) {
wl = wl->wl_next;
d->db_number = debugnumber;
d->db_type = DB_STOPWHEN;
@ -127,17 +130,20 @@ com_stop(wordlist *wl)
else
d->db_nodename2 = copy(wl->wl_word);
wl = wl->wl_next;
} else
} else {
goto bad;
}
}
}
if (thisone) {
if (dbs) {
for (d = dbs; d->db_next; d = d->db_next)
;
d->db_next = thisone;
} else
} else {
dbs = thisone;
}
(void) sprintf(buf, "%d", debugnumber);
cp_addkword(CT_DBNUMS, buf);
debugnumber++;
@ -145,10 +151,12 @@ com_stop(wordlist *wl)
return;
bad: fprintf(cp_err, "Syntax error parsing breakpoint specification.\n");
bad:
fprintf(cp_err, "Syntax error parsing breakpoint specification.\n");
return;
}
/* Trace a node (have wrd_point print it). Usage is "trace node ..."*/
void
@ -158,24 +166,24 @@ com_trce(wordlist *wl)
return;
}
/* Incrementally plot a value. This is just like trace. */
void
com_iplot(wordlist *wl)
{
/* settrace(wl, VF_PLOT); */
struct dbcomm *d, *td, *currentdb = NULL;
char *s;
/* We use a modified ad-hoc algorithm here where db_also denotes
vectors on the same command line and db_next denotes
separate iplot commands. */
vectors on the same command line and db_next denotes
separate iplot commands. */
while (wl) {
s = cp_unquote(wl->wl_word);
d = alloc(struct dbcomm);
d->db_analysis = NULL;
d->db_analysis = NULL;
d->db_number = debugnumber++;
if (eq(s, "all")) {
d->db_type = DB_IPLOTALL;
@ -188,17 +196,19 @@ com_iplot(wordlist *wl)
currentdb = d;
wl = wl->wl_next;
}
if (dbs) {
for (td = dbs; td->db_next; td = td->db_next)
;
td->db_next = currentdb;
} else
} else {
dbs = currentdb;
}
return;
}
/* Step a number of iterations. */
void
@ -208,10 +218,13 @@ com_step(wordlist *wl)
steps = howmanysteps = atoi(wl->wl_word);
else
steps = howmanysteps = 1;
com_resume(NULL);
return;
}
/* Print out the currently active breakpoints and traces. If we are printing
* to a file, assume that the file will be used for a later source and leave
* off the event numbers (with UNIX, that is). -- I don't like this.
@ -230,24 +243,19 @@ com_sttus(wordlist *wl)
for (d = dbs; d; d = d->db_next) {
if (d->db_type == DB_TRACENODE) {
if (isatty(fileno(cp_out)))
fprintf(cp_out, "%-4d trace %s", d->db_number,
d->db_nodename1);
fprintf(cp_out, "%-4d trace %s", d->db_number, d->db_nodename1);
else
fprintf(cp_out, "trace %s", d->db_nodename1);
} else if (d->db_type == DB_IPLOT) {
if (isatty(fileno(cp_out))) {
fprintf(cp_out, "%-4d iplot %s", d->db_number,
d->db_nodename1);
} else {
if (isatty(fileno(cp_out)))
fprintf(cp_out, "%-4d iplot %s", d->db_number, d->db_nodename1);
else
fprintf(cp_out, "iplot %s", d->db_nodename1);
}
for (dc = d->db_also; dc; dc = dc->db_also) {
fprintf(cp_out, " %s", dc->db_nodename1);
}
for (dc = d->db_also; dc; dc = dc->db_also)
fprintf(cp_out, " %s", dc->db_nodename1);
} else if (d->db_type == DB_SAVE) {
if (isatty(fileno(cp_out)))
fprintf(cp_out, "%-4d save %s", d->db_number,
d->db_nodename1);
fprintf(cp_out, "%-4d save %s", d->db_number, d->db_nodename1);
else
fprintf(cp_out, "save %s", d->db_nodename1);
} else if (d->db_type == DB_TRACEALL) {
@ -265,8 +273,7 @@ com_sttus(wordlist *wl)
fprintf(cp_out, "%-4d save all", d->db_number);
else
fprintf(cp_out, "save all");
} else if ((d->db_type == DB_STOPAFTER) ||
(d->db_type == DB_STOPWHEN)) {
} else if ((d->db_type == DB_STOPAFTER) || (d->db_type == DB_STOPWHEN)) {
if (isatty(fileno(cp_out)))
fprintf(cp_out, "%-4d stop", d->db_number);
else
@ -275,21 +282,23 @@ com_sttus(wordlist *wl)
} else if ((d->db_type == DB_DEADIPLOT)) {
if (isatty(fileno(cp_out))) {
fprintf(cp_out, "%-4d exiting iplot %s", d->db_number,
d->db_nodename1);
d->db_nodename1);
} else {
fprintf(cp_out, "exiting iplot %s", d->db_nodename1);
}
for (dc = d->db_also; dc; dc = dc->db_also) {
fprintf(cp_out, " %s", dc->db_nodename1);
}
} else
fprintf(cp_err,
"com_sttus: Internal Error: bad db %d\n", d->db_type);
for (dc = d->db_also; dc; dc = dc->db_also)
fprintf(cp_out, " %s", dc->db_nodename1);
} else {
fprintf(cp_err,
"com_sttus: Internal Error: bad db %d\n", d->db_type);
}
(void) putc('\n', cp_out);
}
return;
}
void
dbfree(struct dbcomm *db)
{
@ -301,9 +310,11 @@ dbfree(struct dbcomm *db)
tfree(dd->db_nodename2);
tfree(dd);
}
return;
}
/* Delete breakpoints and traces. Usage is delete [number ...] */
void
@ -326,21 +337,26 @@ com_delete(wordlist *wl)
return;
}
}
while (wl) {
if (wl->wl_word) {
if (wl->wl_word) {
#ifdef HAVE_CTYPE_H
for (s = wl->wl_word, i = 0; *s; s++)
if (!isdigit(*s)) {
fprintf(cp_err, "Error: %s isn't a number.\n",
wl->wl_word);
goto bad;
} else
i = i * 10 + (*s - '0');
for (s = wl->wl_word, i = 0; *s; s++)
if (!isdigit(*s)) {
fprintf(cp_err, "Error: %s isn't a number.\n",
wl->wl_word);
goto bad;
} else {
i = i * 10 + (*s - '0');
}
#else
i = atoi(wl->wl_next->wl_word); /* etoi ??? */
i = atoi(wl->wl_next->wl_word); /* etoi ??? */
#endif
} else
i = 0;
} else {
i = 0;
}
for (d = dbs, dt = NULL; d; d = d->db_next) {
if (d->db_number == i) {
if (dt)
@ -354,11 +370,15 @@ com_delete(wordlist *wl)
}
dt = d;
}
bad: wl = wl->wl_next;
bad:
wl = wl->wl_next;
}
return;
}
/* Writedata calls this routine to see if it should keep going. If it
* returns TRUE, then the run should resume.
*/
@ -378,43 +398,47 @@ ft_bpcheck(struct plot *runplot, int iteration)
for (d = dbs; d; d = d->db_next) {
for (dt = d; dt; dt = dt->db_also) {
switch (dt->db_type) {
case DB_TRACENODE:
case DB_TRACEALL:
case DB_IPLOT:
case DB_DEADIPLOT:
case DB_IPLOTALL:
case DB_SAVE:
case DB_SAVEALL:
case DB_TRACENODE:
case DB_TRACEALL:
case DB_IPLOT:
case DB_DEADIPLOT:
case DB_IPLOTALL:
case DB_SAVE:
case DB_SAVEALL:
goto more;
case DB_STOPAFTER:
if (iteration == dt->db_iteration)
break;
else
goto more;
case DB_STOPAFTER:
if (iteration == dt->db_iteration)
break;
else
goto more;
case DB_STOPWHEN:
/* See if the condition is TRUE. */
if (satisfied(dt, runplot))
break;
else
goto more;
default:
fprintf(cp_err, "ft_bpcheck: Internal Error: bad db %d\n",
dt->db_type);
case DB_STOPWHEN:
/* See if the condition is TRUE. */
if (satisfied(dt, runplot))
break;
else
goto more;
default:
fprintf(cp_err, "ft_bpcheck: Internal Error: bad db %d\n",
dt->db_type);
}
}
if (dt == NULL) {
/* It made it */
fprintf(cp_err, "%-2d: condition met: stop ",
d->db_number);
fprintf(cp_err, "%-2d: condition met: stop ", d->db_number);
printcond(d, cp_err);
(void) putc('\n', cp_err);
return (FALSE);
}
more: /* Just continue */ ;
more: /* Just continue */
;
}
return (TRUE);
}
/* This is called to determine whether a STOPWHEN is TRUE. */
static bool
@ -425,52 +449,52 @@ satisfied(struct dbcomm *d, struct plot *plot)
if (d->db_nodename1) {
if ((v1 = vec_fromplot(d->db_nodename1, plot)) == NULL) {
fprintf(cp_err, "Error: %s: no such node\n",
d->db_nodename1);
fprintf(cp_err, "Error: %s: no such node\n", d->db_nodename1);
return (FALSE);
}
if (isreal(v1))
d1 = v1->v_realdata[v1->v_length - 1];
else
d1 = realpart((v1->v_compdata[v1->v_length - 1]));
} else
} else {
d1 = d->db_value1;
}
if (d->db_nodename2) {
if ((v2 = vec_fromplot(d->db_nodename2, plot)) == NULL) {
fprintf(cp_err, "Error: %s: no such node\n",
d->db_nodename2);
fprintf(cp_err, "Error: %s: no such node\n", d->db_nodename2);
return (FALSE);
}
if (isreal(v2))
d2 = v2->v_realdata[v2->v_length - 1];
else
d2 = realpart((v2->v_compdata[v2->v_length - 1]));
} else
} else {
d2 = d->db_value2;
}
switch (d->db_op) {
case DBC_EQU:
return (AlmostEqualUlps(d1, d2, 3) ? TRUE : FALSE);
// return ((d1 == d2) ? TRUE : FALSE);
case DBC_NEQ:
return ((d1 != d2) ? TRUE : FALSE);
case DBC_GTE:
return ((d1 >= d2) ? TRUE : FALSE);
case DBC_LTE:
return ((d1 <= d2) ? TRUE : FALSE);
case DBC_GT:
return ((d1 > d2) ? TRUE : FALSE);
case DBC_LT:
return ((d1 < d2) ? TRUE : FALSE);
default:
fprintf(cp_err,
"satisfied: Internal Error: bad cond %d\n",
d->db_op);
return (FALSE);
case DBC_EQU:
return (AlmostEqualUlps(d1, d2, 3) ? TRUE : FALSE);
// return ((d1 == d2) ? TRUE : FALSE);
case DBC_NEQ:
return ((d1 != d2) ? TRUE : FALSE);
case DBC_GTE:
return ((d1 >= d2) ? TRUE : FALSE);
case DBC_LTE:
return ((d1 <= d2) ? TRUE : FALSE);
case DBC_GT:
return ((d1 > d2) ? TRUE : FALSE);
case DBC_LT:
return ((d1 < d2) ? TRUE : FALSE);
default:
fprintf(cp_err,
"satisfied: Internal Error: bad cond %d\n", d->db_op);
return (FALSE);
}
}
/* Writedata calls this before it starts a run, to set the proper flags
* on the dvecs. If a change is made during a break, then the routine
* wrd_chtrace is used from these routines. We have to be clever with save:
@ -484,50 +508,51 @@ ft_trquery(void)
return;
}
static void
printcond(struct dbcomm *d, FILE *fp)
{
struct dbcomm *dt;
for (dt = d; dt; dt = dt->db_also) {
if (dt->db_type == DB_STOPAFTER)
if (dt->db_type == DB_STOPAFTER) {
fprintf(fp, " after %d", dt->db_iteration);
else {
} else {
if (dt->db_nodename1)
fprintf(fp, " when %s",
dt->db_nodename1);
fprintf(fp, " when %s", dt->db_nodename1);
else
fprintf(fp, " when %g", dt->db_value1);
switch (dt->db_op) {
case DBC_EQU:
fputs(" =", fp);
break;
case DBC_NEQ:
fputs(" <>", fp);
break;
case DBC_GT:
fputs(" >", fp);
break;
case DBC_LT:
fputs(" <", fp);
break;
case DBC_GTE:
fputs(" >=", fp);
break;
case DBC_LTE:
fputs(" <=", fp);
break;
default:
fprintf(cp_err,
"printcond: Internal Error: bad cond %d",
dt->db_op);
case DBC_EQU:
fputs(" =", fp);
break;
case DBC_NEQ:
fputs(" <>", fp);
break;
case DBC_GT:
fputs(" >", fp);
break;
case DBC_LT:
fputs(" <", fp);
break;
case DBC_GTE:
fputs(" >=", fp);
break;
case DBC_LTE:
fputs(" <=", fp);
break;
default:
fprintf(cp_err,
"printcond: Internal Error: bad cond %d", dt->db_op);
}
if (dt->db_nodename2)
fprintf(fp, " %s", dt->db_nodename2);
else
fprintf(fp, " %g", dt->db_value2);
}
}
return;
}

View File

@ -15,15 +15,17 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "quote.h"
#include "breakp2.h"
/* global linked list to store .save data and breakpoint data */
struct dbcomm *dbs = NULL; /* export for iplot */
/* used in breakp.c and breakp2.c */
int debugnumber = 1;
/* Analyse the data given by the .save card or 'save' command.
Store the data in the global dbs struct.
*/
*/
/* Save a vector. */
@ -34,6 +36,7 @@ com_save(wordlist *wl)
return;
}
/* Save a vector with the analysis type given (name). */
void
com_save2(wordlist *wl, char *name)
@ -42,6 +45,7 @@ com_save2(wordlist *wl, char *name)
return;
}
void
settrace(wordlist *wl, int what, char *name)
{
@ -55,46 +59,52 @@ settrace(wordlist *wl, int what, char *name)
d->db_analysis = name;
if (eq(s, "all")) {
switch (what) {
case VF_PRINT:
d->db_type = DB_TRACEALL;
break;
/* case VF_PLOT:
d->db_type = DB_IPLOTALL;
break; */
case VF_ACCUM:
/* d->db_type = DB_SAVEALL; */
d->db_nodename1 = copy(s);
d->db_type = DB_SAVE;
break;
case VF_PRINT:
d->db_type = DB_TRACEALL;
break;
/* case VF_PLOT:
d->db_type = DB_IPLOTALL;
break; */
case VF_ACCUM:
/* d->db_type = DB_SAVEALL; */
d->db_nodename1 = copy(s);
d->db_type = DB_SAVE;
break;
}
/* wrd_chtrace(NULL, TRUE, what); */
/* wrd_chtrace(NULL, TRUE, what); */
} else {
switch (what) {
case VF_PRINT:
d->db_type = DB_TRACENODE;
break;
/* case VF_PLOT:
d->db_type = DB_IPLOT;
break; */
case VF_ACCUM:
d->db_type = DB_SAVE;
break;
case VF_PRINT:
d->db_type = DB_TRACENODE;
break;
/* case VF_PLOT:
d->db_type = DB_IPLOT;
break; */
case VF_ACCUM:
d->db_type = DB_SAVE;
break;
}
d->db_nodename1 = copy(s);
/* wrd_chtrace(s, TRUE, what); */
/* wrd_chtrace(s, TRUE, what); */
}
tfree(s);/*DG avoid memoy leak */
tfree(s); /*DG avoid memoy leak */
if (dbs) {
for (td = dbs; td->db_next; td = td->db_next)
;
td->db_next = d;
} else
} else {
dbs = d;
}
wl = wl->wl_next;
}
return;
}
/* retrieve the save nodes from dbs into an array */
int
ft_getSaves(struct save_info **savesp)
@ -110,18 +120,18 @@ ft_getSaves(struct save_info **savesp)
if (!count)
return (0);
*savesp = array = TMALLOC(struct save_info, count);
for (d = dbs; d; d = d->db_next)
if (d->db_type == DB_SAVE) {
array[i].used = 0;
if (d->db_analysis)
array[i].analysis = copy(d->db_analysis);
else
array[i].analysis = NULL;
if (d->db_analysis)
array[i].analysis = copy(d->db_analysis);
else
array[i].analysis = NULL;
array[i++].name = copy(d->db_nodename1);
}
}
return (count);
}

View File

@ -7,14 +7,9 @@
#define CIRCUITS_H_INCLUDED
struct subcirc {
char *sc_name; /* Whatever... */
} ;
char *sc_name; /* Whatever... */
};
#endif

View File

@ -26,22 +26,21 @@ com_ahelp(wordlist *wl)
char slevel[256];
if (wl) {
com_help(wl);
return;
com_help(wl);
return;
}
out_init();
/* determine environment */
if (plot_list->pl_next) { /* plots load */
env |= E_HASPLOTS;
} else {
env |= E_NOPLOTS;
}
if (plot_list->pl_next) /* plots load */
env |= E_HASPLOTS;
else
env |= E_NOPLOTS;
/* determine level */
if (cp_getvar("level", CP_STRING, slevel)) {
switch (*slevel) {
switch (*slevel) {
case 'b': level = 1;
break;
case 'i': level = 2;
@ -50,40 +49,40 @@ com_ahelp(wordlist *wl)
break;
default: level = 1;
break;
}
}
} else {
level = 1;
level = 1;
}
out_printf(
"For a complete description read the Spice3 User's Manual manual.\n");
"For a complete description read the Spice3 User's Manual manual.\n");
out_printf(
"For a list of all commands type \"help all\", for a short\n");
"For a list of all commands type \"help all\", for a short\n");
out_printf(
"description of \"command\", type \"help command\".\n");
"description of \"command\", type \"help command\".\n");
/* sort the commands */
for (n = 0; cp_coms[n].co_func != NULL; n++) {
cc[n] = &cp_coms[n];
}
for (n = 0; cp_coms[n].co_func != NULL; n++)
cc[n] = &cp_coms[n];
qsort(cc, (size_t) n, sizeof(struct comm *), hcomp);
/* filter the commands */
for (i=0; i< n; i++) {
com = cc[i];
if ((com->co_env < (level << 13)) && (!(com->co_env & 4095) ||
(env & com->co_env))) {
if ((com->co_spiceonly && ft_nutmeg) || (com->co_help == NULL)) {
continue;
}
out_printf("%s ", com->co_comname);
out_printf(com->co_help, cp_program);
out_send("\n");
}
for (i = 0; i < n; i++) {
com = cc[i];
if ((com->co_env < (level << 13)) &&
(!(com->co_env & 4095) || (env & com->co_env)))
{
if ((com->co_spiceonly && ft_nutmeg) || (com->co_help == NULL))
continue;
out_printf("%s ", com->co_comname);
out_printf(com->co_help, cp_program);
out_send("\n");
}
}
out_send("\n");
return;
}

View File

@ -12,7 +12,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
struct alias *cp_aliases = NULL;
/* Return NULL if no alias was found. We can get away with just
* calling cp_histsubst now because the line will have gone onto the
* history list by now and cp_histsubst will look in the right place. */
@ -28,11 +27,13 @@ asubst(wordlist *wlist)
wlist->wl_word++; /* FIXME !!!, free() will fail !!! */
return (NULL);
}
for (al = cp_aliases; al; al = al->al_next)
if (eq(word, al->al_name))
break;
if (!al)
return (NULL);
wl = cp_histsubst(wl_copy(al->al_text));
if (cp_didhsubst) {
@ -43,13 +44,13 @@ asubst(wordlist *wlist)
/* If it had no history args, then append the rest of the wl */
wl_append(wl, wl_copy(wlist->wl_next));
}
return (wl);
}
/* MW. This function should not use cp_lastone, see cp_parse in cpshar.c
* Many things are deleted here and memory leak closed */
/* MW. This function should not use cp_lastone, see cp_parse in cpshar.c
* Many things are deleted here and memory leak closed */
wordlist *
cp_doalias(wordlist *wlist)
{
@ -68,7 +69,7 @@ cp_doalias(wordlist *wlist)
nextc = wl_find(cp_csep, comm);
if(nextc == comm) { /* skip leading `;' */
if (nextc == comm) { /* skip leading `;' */
comm = comm->wl_next;
continue;
}
@ -120,10 +121,11 @@ cp_setalias(char *word, wordlist *wlist)
cp_unalias(word);
cp_addkword(CT_ALIASES, word);
if (cp_aliases == NULL) {
al = cp_aliases = alloc(struct alias);
al->al_next = NULL;
al->al_prev = NULL;
al->al_next = NULL;
al->al_prev = NULL;
} else {
for (al = cp_aliases; al->al_next; al = al->al_next) {
if (strcmp(al->al_name, word) > 0)
@ -146,6 +148,7 @@ cp_setalias(char *word, wordlist *wlist)
al = cp_aliases;
}
}
al->al_name = copy(word);
al->al_text = wl_copy(wlist);
cp_striplist(al->al_text);
@ -156,32 +159,40 @@ cp_setalias(char *word, wordlist *wlist)
return;
}
void
cp_unalias(char *word)
{
struct alias *al;
cp_remkword(CT_ALIASES, word);
for (al = cp_aliases; al; al = al->al_next)
if (eq(word, al->al_name))
break;
if (al == NULL)
return;
if (al->al_next)
al->al_next->al_prev = al->al_prev;
if (al->al_prev)
if (al->al_prev) {
al->al_prev->al_next = al->al_next;
else {
} else {
al->al_next->al_prev = NULL;
cp_aliases = al->al_next;
}
wl_free(al->al_text);
tfree(al->al_name);
tfree(al);
cp_remcomm(word);
return;
}
void
cp_paliases(char *word)
{
@ -197,6 +208,7 @@ cp_paliases(char *word)
return;
}
/* The routine for the "alias" command. */
void
@ -211,6 +223,7 @@ com_alias(wordlist *wl)
return;
}
void
com_unalias(wordlist *wl)
{
@ -226,10 +239,12 @@ com_unalias(wordlist *wl)
cp_aliases = NULL;
wl = wl->wl_next;
}
while (wl != NULL) {
cp_unalias(wl->wl_word);
wl = wl->wl_next;
}
return;
}

View File

@ -111,7 +111,7 @@ dodump(struct control *cc)
tab(indent);
if (cc->co_numtimes != 1)
fprintf(cp_out, "continue %d\n",
cc->co_numtimes);
cc->co_numtimes);
else
fprintf(cp_out, "continue\n");
break;
@ -128,6 +128,7 @@ dodump(struct control *cc)
fprintf(cp_out, "bad type %d\n", cc->co_type);
break;
}
return;
}
@ -141,59 +142,62 @@ com_cdump(wordlist *wl)
indent = 0;
for (c = control[stackp]; c; c = c->co_next)
dodump(c);
return;
}
/* dump circuit matrix to stdout or file */
void
com_mdump(wordlist *wl)
{
CKTcircuit *ckt = NULL;
char *s;
if (!ft_curckt || !ft_curckt->ci_ckt) {
fprintf(cp_err, "Error: no circuit loaded.\n");
return;
}
ckt = ft_curckt->ci_ckt;
if (ckt->CKTmatrix)
if (wl == NULL)
if (wl == NULL) {
SMPprint(ckt->CKTmatrix , NULL);
else {
} else {
s = cp_unquote(wl->wl_word);
SMPprint(ckt->CKTmatrix , s);
}
else
fprintf(cp_err, "Error: no matrix available.\n");
return;
}
/* dump circuit matrix RHS to stdout or file */
void
com_rdump(wordlist *wl)
{
CKTcircuit *ckt = NULL;
char *s;
if (!ft_curckt || !ft_curckt->ci_ckt) {
fprintf(cp_err, "Error: no circuit loaded.\n");
return;
}
ckt = ft_curckt->ci_ckt;
if ((ckt->CKTmatrix) && (ckt->CKTrhs))
if (wl == NULL)
if (wl == NULL) {
SMPprintRHS(ckt->CKTmatrix , NULL, ckt->CKTrhs, ckt->CKTirhs);
else {
} else {
s = cp_unquote(wl->wl_word);
SMPprintRHS(ckt->CKTmatrix , s, ckt->CKTrhs, ckt->CKTirhs);
}
else
fprintf(cp_err, "Error: no matrix or RHS available.\n");
return;
}

View File

@ -31,21 +31,21 @@ com_chdir(wordlist *wl)
if (wl == NULL) {
s = getenv("HOME");
s = getenv("HOME");
#ifdef HAVE_PWD_H
if (s == NULL) {
pw = getpwuid(getuid());
if (pw == NULL) {
fprintf(cp_err, "Can't get your password entry\n");
return;
}
s = pw->pw_dir;
}
if (s == NULL) {
pw = getpwuid(getuid());
if (pw == NULL) {
fprintf(cp_err, "Can't get your password entry\n");
return;
}
s = pw->pw_dir;
}
#endif
} else {
s = cp_unquote(wl->wl_word);
copied = 1;
copied = 1;
}
@ -54,16 +54,15 @@ com_chdir(wordlist *wl)
perror(s);
if (copied)
tfree(s);
tfree(s);
#ifdef HAVE_GETCWD
s = getcwd(localbuf, sizeof(localbuf));
if (s)
printf("Current directory: %s\n", s);
printf("Current directory: %s\n", s);
else
fprintf(cp_err, "Can't get current working directory.\n");
fprintf(cp_err, "Can't get current working directory.\n");
#endif
return;
}

View File

@ -13,6 +13,7 @@
#include "com_compose.h"
#include "completion.h"
/* Copy the data from a vector into a buffer with larger dimensions. */
static void
dimxpand(struct dvec *v, int *newdims, double *data)
@ -24,7 +25,7 @@ dimxpand(struct dvec *v, int *newdims, double *data)
for (i = 0; i < MAXDIMS; i++)
ncount[i] = ocount[i] = 0;
for (;;) {
for (o = n = i = 0; i < v->v_numdims; i++) {
for (j = i, t = u = 1; j < v->v_numdims; j++) {
@ -41,16 +42,17 @@ dimxpand(struct dvec *v, int *newdims, double *data)
realpart(cdata[n]) = realpart(v->v_compdata[o]);
imagpart(cdata[n]) = imagpart(v->v_compdata[o]);
}
/* Now find the nextstrchr element... */
for (i = v->v_numdims - 1; i >= 0; i--) {
if ((ocount[i] < v->v_dims[i] - 1) &&
(ncount[i] < newdims[i] - 1)) {
for (i = v->v_numdims - 1; i >= 0; i--)
if ((ocount[i] < v->v_dims[i] - 1) && (ncount[i] < newdims[i] - 1)) {
ocount[i]++;
ncount[i]++;
break;
} else
} else {
ocount[i] = ncount[i] = 0;
}
}
if (i < 0)
break;
}
@ -59,8 +61,6 @@ dimxpand(struct dvec *v, int *newdims, double *data)
}
/* The general syntax is 'compose name parm = val ...'
* The possible parms are:
* start The value at which the vector should start.
@ -118,40 +118,46 @@ com_compose(wordlist *wl)
bool realflag = TRUE;
int dims[MAXDIMS];
struct dvec *result, *vecs = NULL, *v, *lv = NULL;
struct pnode *pn, *first_pn=NULL;
struct pnode *pn, *first_pn = NULL;
bool reverse = FALSE;
resname = cp_unquote(wl->wl_word);
vec_remove(resname);
wl = wl->wl_next;
if (eq(wl->wl_word, "values")) {
/* Build up the vector from the rest of the line... */
wl = wl->wl_next;
if ((pn = ft_getpnames(wl, TRUE)) == NULL)
return;
first_pn = pn;
first_pn = pn;
while (pn) {
if ((v = ft_evaluate(pn)) == NULL)
return;
if (!vecs)
vecs = lv = v;
else
lv->v_link2 = v;
for (lv = v; lv->v_link2; lv = lv->v_link2)
;
pn = pn->pn_next;
}
/* Now make sure these are all of the same dimensionality. We
* can coerce the sizes...
*/
dim = vecs->v_numdims;
if (dim < 2)
dim = (vecs->v_length > 1) ? 1 : 0;
if (dim == MAXDIMS) {
fprintf(cp_err, "Error: max dimensionality is %d\n",
MAXDIMS);
return;
}
for (v = vecs; v; v = v->v_link2)
if (v->v_numdims < 2)
v->v_dims[0] = v->v_length;
@ -162,13 +168,14 @@ com_compose(wordlist *wl)
i = (v->v_length > 1) ? 1 : 0;
if (i != dim) {
fprintf(cp_err,
"Error: all vectors must be of the same dimensionality\n");
"Error: all vectors must be of the same dimensionality\n");
return;
}
length++;
if (iscomplex(v))
realflag = FALSE;
}
for (i = 0; i < dim; i++) {
dims[i] = vecs->v_dims[i];
for (v = vecs->v_link2; v; v = v->v_link2)
@ -179,6 +186,7 @@ com_compose(wordlist *wl)
dims[dim - 1] = length;
for (i = 0, blocksize = 1; i < dim - 1; i++)
blocksize *= dims[i];
if (realflag)
data = TMALLOC(double, length * blocksize);
else
@ -189,23 +197,20 @@ com_compose(wordlist *wl)
*/
for (v = vecs, i = 0; v; v = v->v_link2) {
if (dim == 1) {
if (realflag && isreal(v))
if (realflag && isreal(v)) {
data[i] = v->v_realdata[0];
else if (isreal(v)) {
realpart(cdata[i]) =
realpart(v->v_compdata[0]);
} else if (isreal(v)) {
realpart(cdata[i]) = realpart(v->v_compdata[0]);
imagpart(cdata[i]) = 0.0;
} else {
realpart(cdata[i]) =
realpart(v->v_compdata[0]);
imagpart(cdata[i]) =
imagpart(v->v_compdata[0]);
realpart(cdata[i]) = realpart(v->v_compdata[0]);
imagpart(cdata[i]) = imagpart(v->v_compdata[0]);
}
i++;
continue;
}
dimxpand(v, dims, (realflag ? (data + i * blocksize) :
(double *) (cdata + i * blocksize)));
dimxpand(v, dims, (realflag ? (data + i * blocksize) :
(double *) (cdata + i * blocksize)));
}
length *= blocksize;
@ -238,7 +243,7 @@ com_compose(wordlist *wl)
val = wl->wl_word;
if (*val != '=') {
fprintf(cp_err,
"Error: bad syntax\n");
"Error: bad syntax\n");
return;
}
val++;
@ -248,7 +253,7 @@ com_compose(wordlist *wl)
val = wl->wl_word;
} else {
fprintf(cp_err,
"Error: bad syntax\n");
"Error: bad syntax\n");
return;
}
}
@ -262,8 +267,7 @@ com_compose(wordlist *wl)
startgiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
start = *td;
@ -271,8 +275,7 @@ com_compose(wordlist *wl)
stopgiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
stop = *td;
@ -280,8 +283,7 @@ com_compose(wordlist *wl)
stepgiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
step = *td;
@ -289,8 +291,7 @@ com_compose(wordlist *wl)
centergiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
center = *td;
@ -298,8 +299,7 @@ com_compose(wordlist *wl)
spangiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
span = *td;
@ -307,8 +307,7 @@ com_compose(wordlist *wl)
meangiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
mean = *td;
@ -316,8 +315,7 @@ com_compose(wordlist *wl)
sdgiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
sd = *td;
@ -325,8 +323,7 @@ com_compose(wordlist *wl)
lingiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
lin = *td;
@ -334,8 +331,7 @@ com_compose(wordlist *wl)
loggiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
log = (int)(*td);
@ -343,8 +339,7 @@ com_compose(wordlist *wl)
decgiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
dec = (int)(*td);
@ -352,8 +347,7 @@ com_compose(wordlist *wl)
gaussgiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
gauss = (int)(*td);
@ -361,8 +355,7 @@ com_compose(wordlist *wl)
randmgiven = TRUE;
if ((td = ft_numparse(&val, FALSE)) == NULL) {
fprintf(cp_err,
"Error: bad parm %s = %s\n",
var, val);
"Error: bad parm %s = %s\n", var, val);
return;
}
randm = (int)(*td);
@ -373,11 +366,10 @@ com_compose(wordlist *wl)
}
#ifdef LINT
/* XXX Now, doesn't this look just a little suspicious */
if (centergiven || spangiven || meangiven || sdgiven ||
poolgiven)
/* XXX Now, doesn't this look just a little suspicious */
if (centergiven || spangiven || meangiven || sdgiven || poolgiven)
j = k = l = m = q = inds = center + span + mean + sd +
log + dec + gauss + randm + pool;
log + dec + gauss + randm + pool;
#endif
/* Now see what we have... start and stop are pretty much
* compatible with everything...
@ -386,19 +378,19 @@ com_compose(wordlist *wl)
fprintf(cp_err, "Error: step cannot = 0.0\n");
return;
}
if (startgiven && stopgiven && (start > stop)) {
tt = start;
start = stop;
stop = tt;
reverse = TRUE;
}
if (lingiven + loggiven + decgiven + randmgiven + gaussgiven
> 1) {
if (lingiven + loggiven + decgiven + randmgiven + gaussgiven > 1) {
fprintf(cp_err,
"Error: can have at most one of (lin, log, dec, random, gauss)\n");
"Error: can have at most one of (lin, log, dec, random, gauss)\n");
return;
} else if (lingiven + loggiven + decgiven + randmgiven +
gaussgiven == 0) {
} else if (lingiven + loggiven + decgiven + randmgiven + gaussgiven == 0) {
/* Hmm, if we have a start, stop, and step we're ok. */
if (startgiven && stopgiven && stepgiven) {
lingiven = TRUE;
@ -406,33 +398,31 @@ com_compose(wordlist *wl)
stepgiven = FALSE; /* Problems below... */
} else {
fprintf(cp_err,
"Error: either one of (lin, log, dec, random, gauss) must be given, or all\n");
"Error: either one of (lin, log, dec, random, gauss) must be given, or all\n");
fprintf(cp_err,
"\tof (start, stop, and step) must be given.\n");
"\tof (start, stop, and step) must be given.\n");
return;
}
}
if (lingiven) {
/* Create a linear sweep... */
data = TMALLOC(double, (int) lin);
if (stepgiven && startgiven && stopgiven) {
if (step != (stop - start) / lin * (reverse ?
-1 : 1)) {
fprintf(cp_err,
"Warning: bad step -- should be %g\n",
(stop - start) / lin *
(reverse ? -1 : 1));
if (step != (stop - start) / lin * (reverse ? -1 : 1)) {
fprintf(cp_err,
"Warning: bad step -- should be %g\n",
(stop - start) / lin * (reverse ? -1 : 1));
stepgiven = FALSE;
}
}
}
if (!startgiven) {
if (stopgiven && stepgiven) {
if (stopgiven && stepgiven)
start = stop - step * lin;
} else if (stopgiven) {
else if (stopgiven)
start = stop - lin;
} else {
else
start = 0;
}
startgiven = TRUE;
}
if (!stopgiven) {
@ -441,17 +431,15 @@ com_compose(wordlist *wl)
else
stop = start + lin;
stopgiven = TRUE;
}
}
if (!stepgiven) {
step = (stop - start) / lin;
}
if (reverse)
for (i = 0, tt = stop; i < lin;
i++, tt -= step)
for (i = 0, tt = stop; i < lin; i++, tt -= step)
data[i] = tt;
else
for (i = 0, tt = start; i < lin;
i++, tt += step)
for (i = 0, tt = start; i < lin; i++, tt += step)
data[i] = tt;
length = (int)lin;
} else if (loggiven || decgiven) {
@ -462,10 +450,12 @@ com_compose(wordlist *wl)
/* Create a gaussian distribution... */
}
}
result = alloc(struct dvec);
ZERO(result, struct dvec);
result->v_name = copy(resname);
result->v_type = type;
if (realflag) {
result->v_flags = VF_REAL | VF_PERMANENT;
result->v_realdata = data;
@ -473,12 +463,14 @@ com_compose(wordlist *wl)
result->v_flags = VF_COMPLEX | VF_PERMANENT;
result->v_compdata = cdata;
}
result->v_length = length;
result->v_numdims = 1;
result->v_dims[0] = length;
vec_new(result);
cp_addkword(CT_VECTOR, result->v_name);
free_pnode(first_pn);
tfree(resname);/*DG: resname has been copied so its remains allocated: memory leak One can remove this and not copy resname*/
tfree(resname); /*DG: resname has been copied so its remains allocated: memory leak One can remove this and not copy resname*/
return;
}

View File

@ -22,7 +22,6 @@ dcomp(const void *d1, const void *d2)
}
/* Display vector status, etc. Note that this only displays stuff
* from the current plot, and you must do a setplot to see the rest of
* it. */
@ -37,13 +36,13 @@ com_display(wordlist *wl)
/* Maybe he wants to know about just a few vectors. */
out_init();
while (wl) {
s = cp_unquote(wl->wl_word);
d = vec_get(s);
tfree(s);/*DG to avoid the cp_unquote memory leak */
tfree(s); /*DG to avoid the cp_unquote memory leak */
if (d == NULL)
fprintf(cp_err, "Error: no such vector as %s.\n",
wl->wl_word);
fprintf(cp_err, "Error: no such vector as %s.\n", wl->wl_word);
else
while (d) {
pvec(d);
@ -53,27 +52,32 @@ com_display(wordlist *wl)
return;
wl = wl->wl_next;
}
if (plot_cur)
for (d = plot_cur->pl_dvecs; d; d = d->v_next)
len++;
if (len == 0) {
fprintf(cp_out, "There are no vectors currently active.\n");
return;
}
out_printf("Here are the vectors currently active:\n\n");
dvs = TMALLOC(struct dvec *, len);
for (d = plot_cur->pl_dvecs, i = 0; d; d = d->v_next, i++)
dvs[i] = d;
if (!cp_getvar("nosort", CP_BOOL, NULL))
qsort(dvs, (size_t) len, sizeof (struct dvec *), dcomp);
qsort(dvs, (size_t) len, sizeof(struct dvec *), dcomp);
out_printf("Title: %s\n", plot_cur->pl_title);
out_printf("Name: %s (%s)\nDate: %s\n\n",
plot_cur->pl_typename, plot_cur->pl_name,
plot_cur->pl_date);
out_printf("Title: %s\n", plot_cur->pl_title);
out_printf("Name: %s (%s)\nDate: %s\n\n",
plot_cur->pl_typename, plot_cur->pl_name,
plot_cur->pl_date);
for (i = 0; i < len; i++) {
d = dvs[i];
pvec(d);
}
return;
}

View File

@ -4,22 +4,26 @@
#include <../spicelib/devices/dev.h> /*for load library commands*/
#include "com_dl.h"
#ifdef XSPICE
void com_codemodel(wordlist *wl){
wordlist *ww;
for(ww = wl;ww;ww = ww->wl_next)
if(load_opus(wl->wl_word))
fprintf(cp_err,"Error: Library %s couldn't be loaded!\n",ww->wl_word);
return;
}
#endif
#ifdef DEVLIB
void com_use(wordlist *wl){
wordlist *ww;
for(ww = wl;ww;ww = ww->wl_next)
if(load_dev(wl->wl_word))
fprintf(cp_err,"Error: Library %s couldn't be loaded!\n",ww->wl_word);
return;
void com_codemodel(wordlist *wl)
{
wordlist *ww;
for (ww = wl; ww; ww = ww->wl_next)
if (load_opus(wl->wl_word))
fprintf(cp_err, "Error: Library %s couldn't be loaded!\n", ww->wl_word);
return;
}
#endif
#ifdef DEVLIB
void com_use(wordlist *wl)
{
wordlist *ww;
for (ww = wl; ww; ww = ww->wl_next)
if (load_dev(wl->wl_word))
fprintf(cp_err, "Error: Library %s couldn't be loaded!\n", ww->wl_word);
return;
}
#endif

View File

@ -11,6 +11,7 @@
#include "quote.h"
#include "ngspice/cpextern.h"
void
com_echo(wordlist *wlist)
{ char*copyword;
@ -22,15 +23,15 @@ com_echo(wordlist *wlist)
}
while (wlist) {
/* fputs(cp_unquote(wlist->wl_word), cp_out); very bad the string allocated by cp_unquote could not be freed: memory leak*/
copyword=cp_unquote(wlist->wl_word);
fputs(copyword, cp_out);
tfree(copyword);
/* fputs(cp_unquote(wlist->wl_word), cp_out); very bad the string allocated by cp_unquote could not be freed: memory leak*/
copyword = cp_unquote(wlist->wl_word);
fputs(copyword, cp_out);
tfree(copyword);
if (wlist->wl_next)
fputs(" ", cp_out);
wlist = wlist->wl_next;
}
if (nl)
fputs("\n", cp_out);
}

View File

@ -20,8 +20,10 @@ Author: 2008 Holger Vogt
#include "../misc/misc_time.h"
#include "ngspice/fftext.h"
static void fftext(double*, double*, long int, long int, int);
void
com_fft(wordlist *wl)
{
@ -76,85 +78,81 @@ com_fft(wordlist *wl)
/* window functions - should have an average of one */
win = TMALLOC(double, tlen);
{
char window[BSIZE_SP];
double maxt = time[tlen-1];
if (!cp_getvar("specwindow", CP_STRING, window))
strcpy(window,"blackman");
if (eq(window, "none"))
for(i=0; i<tlen; i++) {
win[i] = 1.0;
}
else if (eq(window, "rectangular"))
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0.0;
} else {
char window[BSIZE_SP];
double maxt = time[tlen-1];
if (!cp_getvar("specwindow", CP_STRING, window))
strcpy(window, "blackman");
if (eq(window, "none"))
for (i = 0; i < tlen; i++)
win[i] = 1.0;
}
}
else if (eq(window, "triangle") || eq(window, "bartlet") || eq(window, "bartlett"))
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0.0;
} else {
win[i] = 2.0 - fabs(2+4*(time[i]-maxt)/span);
}
}
else if (eq(window, "hann") || eq(window, "hanning") || eq(window, "cosine"))
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0.0;
} else {
win[i] = 1.0 - cos(2*M_PI*(time[i]-maxt)/span);
}
}
else if (eq(window, "hamming"))
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0.0;
} else {
win[i] = 1.0 - 0.46/0.54*cos(2*M_PI*(time[i]-maxt)/span);
}
}
else if (eq(window, "blackman"))
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = 1.0;
win[i] -= 0.50/0.42*cos(2*M_PI*(time[i]-maxt)/span);
win[i] += 0.08/0.42*cos(4*M_PI*(time[i]-maxt)/span);
}
}
else if (eq(window, "flattop"))
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = 1.0;
win[i] -= 1.93*cos(2*M_PI*(time[i]-maxt)/span);
win[i] += 1.29*cos(4*M_PI*(time[i]-maxt)/span);
win[i] -= 0.388*cos(6*M_PI*(time[i]-maxt)/span);
win[i] += 0.032*cos(8*M_PI*(time[i]-maxt)/span);
}
}
else if (eq(window, "gaussian")) {
if (!cp_getvar("specwindoworder", CP_NUM, &order)) order = 2;
if (order < 2) order = 2;
sigma=1.0/order;
scale=0.83/sigma;
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = scale*exp(-0.5*pow((time[i]-maxt/2)/(sigma*maxt/2),2));
}
}
} else {
fprintf(cp_err, "Warning: unknown window type %s\n", window);
tfree(win);
return;
}
else if (eq(window, "rectangular"))
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span)
win[i] = 0.0;
else
win[i] = 1.0;
}
else if (eq(window, "triangle") || eq(window, "bartlet") || eq(window, "bartlett"))
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span)
win[i] = 0.0;
else
win[i] = 2.0 - fabs(2+4*(time[i]-maxt)/span);
}
else if (eq(window, "hann") || eq(window, "hanning") || eq(window, "cosine"))
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span)
win[i] = 0.0;
else
win[i] = 1.0 - cos(2*M_PI*(time[i]-maxt)/span);
}
else if (eq(window, "hamming"))
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span)
win[i] = 0.0;
else
win[i] = 1.0 - 0.46/0.54*cos(2*M_PI*(time[i]-maxt)/span);
}
else if (eq(window, "blackman"))
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = 1.0;
win[i] -= 0.50/0.42*cos(2*M_PI*(time[i]-maxt)/span);
win[i] += 0.08/0.42*cos(4*M_PI*(time[i]-maxt)/span);
}
}
else if (eq(window, "flattop"))
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = 1.0;
win[i] -= 1.93*cos(2*M_PI*(time[i]-maxt)/span);
win[i] += 1.29*cos(4*M_PI*(time[i]-maxt)/span);
win[i] -= 0.388*cos(6*M_PI*(time[i]-maxt)/span);
win[i] += 0.032*cos(8*M_PI*(time[i]-maxt)/span);
}
}
else if (eq(window, "gaussian")) {
if (!cp_getvar("specwindoworder", CP_NUM, &order))
order = 2;
if (order < 2)
order = 2;
sigma = 1.0/order;
scale = 0.83/sigma;
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span)
win[i] = 0;
else
win[i] = scale*exp(-0.5 * pow((time[i]-maxt/2)/(sigma*maxt/2), 2));
}
} else {
fprintf(cp_err, "Warning: unknown window type %s\n", window);
tfree(win);
return;
}
}
names = ft_getpnames(wl, TRUE);
@ -172,8 +170,7 @@ com_fft(wordlist *wl)
continue;
}
if (!isreal(vec)) {
fprintf(cp_err, "Error: %s isn't real!\n",
vec->v_name);
fprintf(cp_err, "Error: %s isn't real!\n", vec->v_name);
vec = vec->v_link2;
continue;
}
@ -192,8 +189,8 @@ com_fft(wordlist *wl)
}
free_pnode_o(first_name);
if (!ngood) {
tfree(win);
return;
tfree(win);
return;
}
plot_cur = plot_alloc("spectrum");
@ -201,7 +198,7 @@ com_fft(wordlist *wl)
plot_list = plot_cur;
plot_cur->pl_title = copy((plot_cur->pl_next)->pl_title);
plot_cur->pl_name = copy("Spectrum");
plot_cur->pl_date = copy(datestring( ));
plot_cur->pl_date = copy(datestring());
freq = TMALLOC(double, fpts);
f = alloc(struct dvec);
@ -213,23 +210,23 @@ com_fft(wordlist *wl)
f->v_realdata = freq;
vec_new(f);
for (i = 0; i<fpts; i++) freq[i] = i*1.0/span*tlen/size;
for (i = 0; i<fpts; i++)
freq[i] = i*1.0/span*tlen/size;
tdvec = TMALLOC(double *, ngood);
fdvec = TMALLOC(ngcomplex_t *, ngood);
for (i = 0, vec = vlist; i<ngood; i++) {
tdvec[i] = vec->v_realdata; /* real input data */
fdvec[i] = TMALLOC(ngcomplex_t, fpts); /* complex output data */
f = alloc(struct dvec);
ZERO(f, struct dvec);
f->v_name = vec_basename(vec);
f->v_type = SV_NOTYPE;
f->v_flags = (VF_COMPLEX | VF_PERMANENT);
f->v_length = fpts;
f->v_compdata = fdvec[i];
vec_new(f);
vec = vec->v_link2;
tdvec[i] = vec->v_realdata; /* real input data */
fdvec[i] = TMALLOC(ngcomplex_t, fpts); /* complex output data */
f = alloc(struct dvec);
ZERO(f, struct dvec);
f->v_name = vec_basename(vec);
f->v_type = SV_NOTYPE;
f->v_flags = (VF_COMPLEX | VF_PERMANENT);
f->v_length = fpts;
f->v_compdata = fdvec[i];
vec_new(f);
vec = vec->v_link2;
}
sign = 1;
@ -240,22 +237,22 @@ com_fft(wordlist *wl)
reald = TMALLOC(double, size);
imagd = TMALLOC(double, size);
for (i = 0; i<ngood; i++) {
for (j = 0; j < tlen; j++){
for (j = 0; j < tlen; j++) {
reald[j] = tdvec[i][j]*win[j];
imagd[j] = 0.0;
}
for (j = tlen; j < size; j++){
for (j = tlen; j < size; j++) {
reald[j] = 0.0;
imagd[j] = 0.0;
}
#ifdef GREEN
// Green's FFT
// Green's FFT
fftInit(mm);
rffts(reald, mm, 1);
fftFree();
scale = size;
/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
for (j=0;j<fpts;j++){
/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
for (j = 0; j < fpts; j++) {
fdvec[i][j].cx_real = reald[2*j]/scale;
fdvec[i][j].cx_imag = reald[2*j+1]/scale;
}
@ -264,12 +261,13 @@ com_fft(wordlist *wl)
fftext(reald, imagd, size, tlen, sign);
scale = 0.66;
for (j=0;j<fpts;j++){
for (j = 0; j < fpts; j++) {
fdvec[i][j].cx_real = reald[j]/scale;
fdvec[i][j].cx_imag = imagd[j]/scale;
}
#endif
}
tfree(reald);
tfree(imagd);
@ -278,6 +276,7 @@ com_fft(wordlist *wl)
tfree(win);
}
void
com_psd(wordlist *wl)
{
@ -301,27 +300,29 @@ com_psd(wordlist *wl)
fprintf(cp_err, "Error: no vectors loaded.\n");
return;
}
if (!isreal(plot_cur->pl_scale) ||
if (!isreal(plot_cur->pl_scale) ||
((plot_cur->pl_scale)->v_type != SV_TIME)) {
fprintf(cp_err, "Error: fft needs real time scale\n");
return;
}
tlen = (plot_cur->pl_scale)->v_length;
time = (plot_cur->pl_scale)->v_realdata;
span = time[tlen-1] - time[0];
delta_t = span/(tlen - 1);
// get filter length from parameter input
s = wl->wl_word;
ave = ft_numparse(&s, FALSE);
if (!ave || (*ave < 1.0)) {
fprintf(cp_out, "Number of averaged data points: %d\n", 1);
fprintf(cp_out, "Number of averaged data points: %d\n", 1);
smooth = 1;
} else {
smooth = (int)(*ave);
}
else smooth = (int)(*ave);
wl = wl->wl_next;
wl = wl->wl_next;
// size of input vector is power of two and larger than spice vector
size = 1;
mm = 0;
@ -331,96 +332,97 @@ com_psd(wordlist *wl)
}
// output vector has length of size/2
fpts = size>>1;
fpts = size>>1;
// window function
// window function
win = TMALLOC(double, tlen);
{
char window[BSIZE_SP];
double maxt = time[tlen-1];
if (!cp_getvar("specwindow", CP_STRING, window))
strcpy(window,"blackman");
if (eq(window, "none"))
for(i=0; i<tlen; i++) {
win[i] = 1;
}
else if (eq(window, "rectangular"))
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
char window[BSIZE_SP];
double maxt = time[tlen-1];
if (!cp_getvar("specwindow", CP_STRING, window))
strcpy(window, "blackman");
if (eq(window, "none"))
for (i = 0; i < tlen; i++)
win[i] = 1;
}
}
else if (eq(window, "hanning") || eq(window, "cosine"))
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = 1 - cos(2*M_PI*(time[i]-maxt)/span);
}
}
else if (eq(window, "hamming"))
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = 1 - 0.92/1.08*cos(2*M_PI*(time[i]-maxt)/span);
}
}
else if (eq(window, "triangle") || eq(window, "bartlet"))
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = 2 - fabs(2+4*(time[i]-maxt)/span);
}
}
else if (eq(window, "blackman")) {
int order;
if (!cp_getvar("specwindoworder", CP_NUM, &order)) order = 2;
if (order < 2) order = 2; /* only order 2 supported here */
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = 1;
win[i] -= 0.50/0.42*cos(2*M_PI*(time[i]-maxt)/span);
win[i] += 0.08/0.42*cos(4*M_PI*(time[i]-maxt)/span);
}
}
} else if (eq(window, "gaussian")) {
if (!cp_getvar("specwindoworder", CP_NUM, &order)) order = 2;
if (order < 2) order = 2;
sigma=1.0/order;
scale=0.83/sigma;
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = scale*exp(-0.5*pow((time[i]-maxt/2)/(sigma*maxt/2),2));
}
}
/* int order;
double scale;
extern double erfc(double);
if (!cp_getvar("specwindoworder", CP_NUM, &order)) order = 2;
if (order < 2) order = 2;
scale = pow(2*M_PI/order,0.5)*(0.5-erfc(pow(order,0.5)));
for(i=0; i<tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = exp(-0.5*order*(1-2*(maxt-time[i])/span)
*(1-2*(maxt-time[i])/span))/scale;
}
}
*/
} else {
fprintf(cp_err, "Warning: unknown window type %s\n", window);
tfree(win);
return;
}
else if (eq(window, "rectangular"))
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span)
win[i] = 0;
else
win[i] = 1;
}
else if (eq(window, "hanning") || eq(window, "cosine"))
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span)
win[i] = 0;
else
win[i] = 1 - cos(2*M_PI*(time[i]-maxt)/span);
}
else if (eq(window, "hamming"))
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span)
win[i] = 0;
else
win[i] = 1 - 0.92/1.08*cos(2*M_PI*(time[i]-maxt)/span);
}
else if (eq(window, "triangle") || eq(window, "bartlet"))
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span)
win[i] = 0;
else
win[i] = 2 - fabs(2+4*(time[i]-maxt)/span);
}
else if (eq(window, "blackman")) {
int order;
if (!cp_getvar("specwindoworder", CP_NUM, &order))
order = 2;
if (order < 2)
order = 2; /* only order 2 supported here */
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span) {
win[i] = 0;
} else {
win[i] = 1;
win[i] -= 0.50/0.42*cos(2*M_PI*(time[i]-maxt)/span);
win[i] += 0.08/0.42*cos(4*M_PI*(time[i]-maxt)/span);
}
}
} else if (eq(window, "gaussian")) {
if (!cp_getvar("specwindoworder", CP_NUM, &order))
order = 2;
if (order < 2)
order = 2;
sigma = 1.0/order;
scale = 0.83/sigma;
for (i = 0; i < tlen; i++) {
if (maxt-time[i] > span)
win[i] = 0;
else
win[i] = scale*exp(-0.5 * pow((time[i]-maxt/2)/(sigma*maxt/2), 2));
}
/*
* int order;
* double scale;
* extern double erfc(double);
* if (!cp_getvar("specwindoworder", CP_NUM, &order))
* order = 2;
* if (order < 2)
* order = 2;
* scale = pow(2*M_PI/order, 0.5)*(0.5-erfc(pow(order, 0.5)));
* for (i = 0; i < tlen; i++) {
* if (maxt-time[i] > span) {
* win[i] = 0;
* } else {
* win[i] = exp(-0.5*order*(1-2*(maxt-time[i])/span)
* *(1-2*(maxt-time[i])/span))/scale;
* }
* }
*/
} else {
fprintf(cp_err, "Warning: unknown window type %s\n", window);
tfree(win);
return;
}
}
names = ft_getpnames(wl, TRUE);
@ -438,8 +440,7 @@ com_psd(wordlist *wl)
continue;
}
if (!isreal(vec)) {
fprintf(cp_err, "Error: %s isn't real!\n",
vec->v_name);
fprintf(cp_err, "Error: %s isn't real!\n", vec->v_name);
vec = vec->v_link2;
continue;
}
@ -457,16 +458,15 @@ com_psd(wordlist *wl)
}
}
free_pnode_o(first_name);
if (!ngood) {
return;
}
if (!ngood)
return;
plot_cur = plot_alloc("spectrum");
plot_cur->pl_next = plot_list;
plot_list = plot_cur;
plot_cur->pl_title = copy((plot_cur->pl_next)->pl_title);
plot_cur->pl_name = copy("PSD");
plot_cur->pl_date = copy(datestring( ));
plot_cur->pl_date = copy(datestring());
freq = TMALLOC(double, fpts + 1);
f = alloc(struct dvec);
@ -478,22 +478,23 @@ com_psd(wordlist *wl)
f->v_realdata = freq;
vec_new(f);
for (i = 0; i <= fpts; i++) freq[i] = i*1./span*tlen/size;
for (i = 0; i <= fpts; i++)
freq[i] = i*1./span*tlen/size;
tdvec = TMALLOC(double*, ngood);
fdvec = TMALLOC(ngcomplex_t*, ngood);
for (i = 0, vec = vlist; i<ngood; i++) {
tdvec[i] = vec->v_realdata; /* real input data */
fdvec[i] = TMALLOC(ngcomplex_t, fpts + 1); /* complex output data */
f = alloc(struct dvec);
ZERO(f, struct dvec);
f->v_name = vec_basename(vec);
f->v_type = SV_NOTYPE; //vec->v_type;
f->v_flags = (VF_COMPLEX | VF_PERMANENT);
f->v_length = fpts + 1;
f->v_compdata = fdvec[i];
vec_new(f);
vec = vec->v_link2;
tdvec[i] = vec->v_realdata; /* real input data */
fdvec[i] = TMALLOC(ngcomplex_t, fpts + 1); /* complex output data */
f = alloc(struct dvec);
ZERO(f, struct dvec);
f->v_name = vec_basename(vec);
f->v_type = SV_NOTYPE; //vec->v_type;
f->v_flags = (VF_COMPLEX | VF_PERMANENT);
f->v_length = fpts + 1;
f->v_compdata = fdvec[i];
vec_new(f);
vec = vec->v_link2;
}
printf("PSD: Time span: %g s, input length: %lu, zero padding: %lu\n", span, size, size-tlen);
@ -501,169 +502,168 @@ com_psd(wordlist *wl)
sign = 1;
isreal = 1;
reald = TMALLOC(double, size);
imagd = TMALLOC(double, size);
// scale = 0.66;
// scale = 0.66;
for (i = 0; i<ngood; i++) {
double intres;
for (j = 0; j < tlen; j++){
reald[j] = (tdvec[i][j]*win[j]);
imagd[j] = 0.;
}
for (j = tlen; j < size; j++){
reald[j] = 0.;
imagd[j] = 0.;
}
// Green's FFT
for (j = 0; j < tlen; j++) {
reald[j] = (tdvec[i][j]*win[j]);
imagd[j] = 0.;
}
for (j = tlen; j < size; j++) {
reald[j] = 0.;
imagd[j] = 0.;
}
// Green's FFT
fftInit(mm);
rffts(reald, mm, 1);
fftFree();
scaling = size;
/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
intres = (double)size * (double)size;
noipower = fdvec[i][0].cx_real = reald[0]*reald[0]/intres;
fdvec[i][fpts].cx_real = reald[1]*reald[1]/intres;
noipower += fdvec[i][fpts-1].cx_real;
for (j=1; j < fpts; j++){
jj = j<<1;
fdvec[i][j].cx_real = 2.* (reald[jj]*reald[jj] + reald[jj + 1]*reald[jj + 1])/intres;
fdvec[i][j].cx_imag = 0;
noipower += fdvec[i][j].cx_real;
if (!finite(noipower))
break;
noipower += fdvec[i][fpts-1].cx_real;
for (j = 1; j < fpts; j++) {
jj = j<<1;
fdvec[i][j].cx_real = 2.* (reald[jj]*reald[jj] + reald[jj + 1]*reald[jj + 1])/intres;
fdvec[i][j].cx_imag = 0;
noipower += fdvec[i][j].cx_real;
if (!finite(noipower))
break;
}
printf("Total noise power up to Nyquist frequency %5.3e Hz:\n%e V^2 (or A^2), \nnoise voltage or current %e V (or A)\n",
freq[fpts],noipower, sqrt(noipower));
freq[fpts], noipower, sqrt(noipower));
/* smoothing with rectangular window of width "smooth",
plotting V/sqrt(Hz) or I/sqrt(Hz) */
if (smooth < 1)
continue;
hsmooth = smooth>>1;
for (j=0; j<hsmooth; j++){
sum = 0.;
for (jj = 0; jj < hsmooth + j; jj++)
sum += fdvec[i][jj].cx_real;
sum /= (hsmooth + j);
reald[j] = (sqrt(sum)/scaling);
for (j = 0; j < hsmooth; j++) {
sum = 0.;
for (jj = 0; jj < hsmooth + j; jj++)
sum += fdvec[i][jj].cx_real;
sum /= (hsmooth + j);
reald[j] = (sqrt(sum)/scaling);
}
for (j=hsmooth; j<fpts-hsmooth; j++){
sum = 0.;
for (jj = 0; jj < smooth; jj++)
sum += fdvec[i][j-hsmooth+jj].cx_real;
sum /= smooth;
reald[j] = (sqrt(sum)/scaling);
for (j = hsmooth; j < fpts-hsmooth; j++) {
sum = 0.;
for (jj = 0; jj < smooth; jj++)
sum += fdvec[i][j-hsmooth+jj].cx_real;
sum /= smooth;
reald[j] = (sqrt(sum)/scaling);
}
for (j=fpts-hsmooth; j<fpts; j++){
sum = 0.;
for (jj = 0; jj < smooth; jj++)
sum += fdvec[i][j-hsmooth+jj].cx_real;
sum /= (fpts - j + hsmooth - 1);
reald[j] = (sqrt(sum)/scaling);
}
for (j=0; j<fpts; j++)
fdvec[i][j].cx_real = reald[j];
for (j = fpts-hsmooth; j < fpts; j++) {
sum = 0.;
for (jj = 0; jj < smooth; jj++)
sum += fdvec[i][j-hsmooth+jj].cx_real;
sum /= (fpts - j + hsmooth - 1);
reald[j] = (sqrt(sum)/scaling);
}
for (j = 0; j < fpts; j++)
fdvec[i][j].cx_real = reald[j];
}
free(reald);
free(imagd);
tfree(tdvec);
tfree(fdvec);
}
static void fftext(double* x, double* y, long int n, long int nn, int dir)
static void
fftext(double *x, double *y, long int n, long int nn, int dir)
{
/*
http://local.wasp.uwa.edu.au/~pbourke/other/dft/
download 22.05.08
Used with permission from the author Paul Bourke
*/
/*
http://local.wasp.uwa.edu.au/~pbourke/other/dft/
download 22.05.08
Used with permission from the author Paul Bourke
*/
/*
This computes an in-place complex-to-complex FFT
x and y are the real and imaginary arrays
n is the number of points, has to be to the power of 2
nn is the number of points w/o zero padded values
dir = 1 gives forward transform
dir = -1 gives reverse transform
*/
/*
This computes an in-place complex-to-complex FFT
x and y are the real and imaginary arrays
n is the number of points, has to be to the power of 2
nn is the number of points w/o zero padded values
dir = 1 gives forward transform
dir = -1 gives reverse transform
*/
long i,i1,j,k,i2,l,l1,l2;
double c1,c2,tx,ty,t1,t2,u1,u2,z;
int m=0, mm=1;
long i, i1, j, k, i2, l, l1, l2;
double c1, c2, tx, ty, t1, t2, u1, u2, z;
int m = 0, mm = 1;
/* get the exponent to the base of 2 from the number of points */
while (mm < n) {
mm *= 2;
m++;
}
/* get the exponent to the base of 2 from the number of points */
while (mm < n) {
mm *= 2;
m++;
}
/* Do the bit reversal */
i2 = n >> 1;
j = 0;
for (i=0;i<n-1;i++) {
if (i < j) {
tx = x[i];
ty = y[i];
x[i] = x[j];
y[i] = y[j];
x[j] = tx;
y[j] = ty;
}
k = i2;
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
}
/* Do the bit reversal */
i2 = n >> 1;
j = 0;
for (i = 0; i < n-1; i++) {
if (i < j) {
tx = x[i];
ty = y[i];
x[i] = x[j];
y[i] = y[j];
x[j] = tx;
y[j] = ty;
}
k = i2;
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
}
/* Compute the FFT */
c1 = -1.0;
c2 = 0.0;
l2 = 1;
for (l=0;l<m;l++) {
l1 = l2;
l2 <<= 1;
u1 = 1.0;
u2 = 0.0;
for (j=0;j<l1;j++) {
for (i=j;i<n;i+=l2) {
i1 = i + l1;
t1 = u1 * x[i1] - u2 * y[i1];
t2 = u1 * y[i1] + u2 * x[i1];
x[i1] = x[i] - t1;
y[i1] = y[i] - t2;
x[i] += t1;
y[i] += t2;
}
z = u1 * c1 - u2 * c2;
u2 = u1 * c2 + u2 * c1;
u1 = z;
}
c2 = sqrt((1.0 - c1) / 2.0);
if (dir == 1)
c2 = -c2;
c1 = sqrt((1.0 + c1) / 2.0);
}
/* Compute the FFT */
c1 = -1.0;
c2 = 0.0;
l2 = 1;
for (l = 0; l < m; l++) {
l1 = l2;
l2 <<= 1;
u1 = 1.0;
u2 = 0.0;
for (j = 0; j < l1; j++) {
for (i = j; i < n; i += l2) {
i1 = i + l1;
t1 = u1 * x[i1] - u2 * y[i1];
t2 = u1 * y[i1] + u2 * x[i1];
x[i1] = x[i] - t1;
y[i1] = y[i] - t2;
x[i] += t1;
y[i] += t2;
}
z = u1 * c1 - u2 * c2;
u2 = u1 * c2 + u2 * c1;
u1 = z;
}
c2 = sqrt((1.0 - c1) / 2.0);
if (dir == 1)
c2 = -c2;
c1 = sqrt((1.0 + c1) / 2.0);
}
/* Scaling for forward transform */
if (dir == 1) {
double scale = 1.0 / nn;
for (i=0;i<n;i++) {
x[i] *= scale; /* don't consider zero padded values */
y[i] *= scale;
}
}
/* Scaling for forward transform */
if (dir == 1) {
double scale = 1.0 / nn;
for (i = 0; i < n; i++) {
x[i] *= scale; /* don't consider zero padded values */
y[i] *= scale;
}
}
}

View File

@ -21,9 +21,10 @@ com_gnuplot(wordlist *wl)
fname = wl->wl_word;
wl = wl->wl_next;
}
if (!wl) {
return;
}
if (!wl)
return;
if (cieq(fname, "temp") || cieq(fname, "tmp")) {
fname = smktemp("gp"); /* Is this the correct name ? */
tempf = TRUE;
@ -33,13 +34,13 @@ com_gnuplot(wordlist *wl)
/* Leave temp file sitting around so gnuplot can grab it from
background. */
if (tempf) {
if (tempf)
tfree(fname);
}
return;
}
/* data printout to file plotargs */
void
com_write_simple(wordlist *wl)
@ -51,9 +52,10 @@ com_write_simple(wordlist *wl)
fname = wl->wl_word;
wl = wl->wl_next;
}
if (!wl) {
return;
}
if (!wl)
return;
if (cieq(fname, "temp") || cieq(fname, "tmp")) {
fname = smktemp("gp"); /* Is this the correct name ? */
tempf = TRUE;
@ -63,9 +65,8 @@ com_write_simple(wordlist *wl)
/* Leave temp file sitting around so gnuplot can grab it from
background. */
if (tempf) {
if (tempf)
tfree(fname);
}
return;
}

View File

@ -34,7 +34,7 @@ com_hardcopy(wordlist *wl)
#if defined(SYSTEM_PLOT5LPR) || defined(SYSTEM_PSLPR)
char format[513];
#endif
int printed;
int printed;
int hc_button;
int foundit;
@ -51,47 +51,44 @@ com_hardcopy(wordlist *wl)
tempf = TRUE;
}
if (!cp_getvar("hcopydevtype", CP_STRING, buf)) {
if (!cp_getvar("hcopydevtype", CP_STRING, buf))
devtype = "postscript";
} else {
else
devtype = buf;
}
/* enable screen plot selection for these display types */
foundit = 0;
// PushGraphContext(currentgraph);
// PushGraphContext(currentgraph);
#ifdef HAS_WINDOWS
if (!wl && hc_button) {
char* psfname;
GRAPH *tempgraph;
if (DevSwitch(devtype)) return;
char *psfname;
GRAPH *tempgraph;
if (DevSwitch(devtype))
return;
tempgraph = CopyGraph(currentgraph);
/* change .tmp to .ps */
/* change .tmp to .ps */
psfname = strchr(fname, '.');
if(psfname)
{
if (psfname) {
*(psfname + 1) = 'p';
*(psfname + 2) = 's';
*(psfname + 3) = '\0';
*(psfname + 2) = 's';
*(psfname + 3) = '\0';
} else {
fname = realloc(fname, strlen(fname)+4);
strcat(fname, ".ps");
}
else
{
fname=realloc(fname,strlen(fname)+4);
strcat(fname,".ps");
tempgraph->devdep = fname;
if (NewViewport(tempgraph)) {
DevSwitch(NULL);
return;
}
tempgraph->devdep = fname;
if (NewViewport(tempgraph)) {
DevSwitch(NULL);
return;
}
gr_resize(tempgraph);
gr_redraw(tempgraph);
DestroyGraph(tempgraph->graphid);
DevSwitch(NULL);
foundit = 1;
gr_resize(tempgraph);
gr_redraw(tempgraph);
DestroyGraph(tempgraph->graphid);
DevSwitch(NULL);
foundit = 1;
}
#endif
@ -102,38 +99,40 @@ com_hardcopy(wordlist *wl)
REQUEST request;
RESPONSE response;
GRAPH *tempgraph;
request.option = click_option;
Input(&request, &response);
if (response.option == error_option) return;
if (response.option == error_option)
return;
if (response.reply.graph) {
if (DevSwitch(devtype)) return;
tempgraph = CopyGraph(response.reply.graph);
tempgraph->devdep = fname;
if (NewViewport(tempgraph)) {
DevSwitch(NULL);
return;
}
/* save current graphics context */
PushGraphContext(currentgraph);
currentgraph = tempgraph;
/* some operations in gr_resize, gr_redraw, and DevSwitch
will be done on currentgraph, not only on tempgraph */
gr_resize(tempgraph);
gr_redraw(tempgraph);
DevSwitch(NULL);
/* retrieve current graphics context */
PopGraphContext();
DestroyGraph(tempgraph->graphid);
foundit = 1;
}
if (DevSwitch(devtype))
return;
tempgraph = CopyGraph(response.reply.graph);
tempgraph->devdep = fname;
if (NewViewport(tempgraph)) {
DevSwitch(NULL);
return;
}
/* save current graphics context */
PushGraphContext(currentgraph);
currentgraph = tempgraph;
/* some operations in gr_resize, gr_redraw, and DevSwitch
will be done on currentgraph, not only on tempgraph */
gr_resize(tempgraph);
gr_redraw(tempgraph);
DevSwitch(NULL);
/* retrieve current graphics context */
PopGraphContext();
DestroyGraph(tempgraph->graphid);
foundit = 1;
}
}
#endif
/* save current graphics context, because plotit() will create a new
currentgraph */
currentgraph */
PushGraphContext(currentgraph);
if (!foundit) {
@ -148,7 +147,8 @@ com_hardcopy(wordlist *wl)
wl = process(wl);
}
if (DevSwitch(devtype)) return;
if (DevSwitch(devtype))
return;
if (!wl || !plotit(wl, fname, NULL)) {
printf("com_hardcopy: graph not defined\n");
@ -174,7 +174,7 @@ com_hardcopy(wordlist *wl)
#endif
#ifdef SYSTEM_PSLPR
if (!printed && !strcmp(devtype, "postscript")) {
/* note: check if that was a postscript printer XXX */
/* note: check if that was a postscript printer XXX */
if (!cp_getvar("lprps", CP_STRING, format))
strcpy(format, SYSTEM_PSLPR);
(void) sprintf(buf, format, device, fname);
@ -188,18 +188,18 @@ com_hardcopy(wordlist *wl)
if (!printed) {
if (!strcmp(devtype, "plot5")) {
fprintf(cp_out,
"The file \"%s\" may be printed with the Unix \"plot\" command,\n",
fname);
fprintf(cp_out,
"\tor by using the '-g' flag to the Unix lpr command.\n");
"The file \"%s\" may be printed with the Unix \"plot\" command,\n",
fname);
fprintf(cp_out,
"\tor by using the '-g' flag to the Unix lpr command.\n");
} else if (!strcmp(devtype, "postscript")) {
fprintf(cp_out,
"\nThe file \"%s\" may be printed on a postscript printer.\n",
fname);
"\nThe file \"%s\" may be printed on a postscript printer.\n",
fname);
} else if (!strcmp(devtype, "MFB")) {
fprintf(cp_out,
"The file \"%s\" may be printed on a MFB device.\n",
fname);
"The file \"%s\" may be printed on a MFB device.\n",
fname);
}
}

View File

@ -29,25 +29,25 @@ com_help(wordlist *wl)
out_init();
out_moremode = FALSE;
if (wl == NULL) {
out_printf("For a complete description "
"read the Spice3 User's Manual.\n");
out_printf("For a complete description "
"read the Spice3 User's Manual.\n");
if (!allflag) {
out_printf("For a list of all commands "
"type \"help all\", for a short\n"
"description of \"command\", "
"type \"help command\".\n");
}
if (!allflag) {
out_printf("For a list of all commands "
"type \"help all\", for a short\n"
"description of \"command\", "
"type \"help command\".\n");
}
/* Sort the commands */
for (numcoms = 0; cp_coms[numcoms].co_func != NULL; numcoms++)
ccc[numcoms] = &cp_coms[numcoms];
qsort(ccc, (size_t) numcoms, sizeof (struct comm *), hcomp);
qsort(ccc, (size_t) numcoms, sizeof(struct comm *), hcomp);
for (i = 0; i < numcoms; i++) {
if ((ccc[i]->co_spiceonly && ft_nutmeg) ||
(ccc[i]->co_help == NULL) ||
(!allflag && !ccc[i]->co_major))
if ((ccc[i]->co_spiceonly && ft_nutmeg) ||
(ccc[i]->co_help == NULL) ||
(!allflag && !ccc[i]->co_major))
continue;
out_printf("%s ", ccc[i]->co_comname);
out_printf(ccc[i]->co_help, cp_program);
@ -71,10 +71,10 @@ com_help(wordlist *wl)
for (al = cp_aliases; al; al = al->al_next)
if (eq(al->al_name, wl->wl_word))
break;
if (al == NULL)
fprintf(cp_out, "Sorry, no help for %s.\n",
wl->wl_word);
else {
if (al == NULL) {
fprintf(cp_out, "Sorry, no help for %s.\n", wl->wl_word);
} else {
out_printf("%s is aliased to ", wl->wl_word);
/* Minor badness here... */
wl_print(al->al_text, cp_out);
@ -84,6 +84,7 @@ com_help(wordlist *wl)
wl = wl->wl_next;
}
}
out_send("\n");
return;
}

View File

@ -14,27 +14,28 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
/* Added GNU Readline Support -- Andrew Veliath <veliaa@rpi.edu> */
#include <readline/readline.h>
#include <readline/history.h>
#endif /* HAVE_GNUREADLINE */
#endif
#ifdef HAVE_BSDEDITLINE
/* SJB added edit line support 2005-05-05 */
#include <editline/readline.h>
#endif /* HAVE_BSDEDITLINE */
#endif
/* static declarations */
static wordlist * dohsubst(char *string);
static wordlist * dohmod(char **string, wordlist *wl);
static wordlist * hpattern(char *buf);
static wordlist * hprefix(char *buf);
static wordlist * getevent(int num);
static wordlist *dohsubst(char *string);
static wordlist *dohmod(char **string, wordlist *wl);
static wordlist *hpattern(char *buf);
static wordlist *hprefix(char *buf);
static wordlist *getevent(int num);
#if !defined(HAVE_GNUREADLINE) && !defined(HAVE_BSDEDITLINE)
static void freehist(int num);
#endif
static char * dohs(char *pat, char *str);
static char *dohs(char *pat, char *str);
struct histent *cp_lastone = NULL;
int cp_maxhistlength = 10000; /* Chris Inbody */
int cp_maxhistlength = 10000; /* Chris Inbody */
char cp_hat = '^';
char cp_bang = '!';
bool cp_didhsubst;
@ -42,6 +43,7 @@ bool cp_didhsubst;
static struct histent *histlist = NULL;
static int histlength = 0;
/* First check for a ^ at the beginning of the line, and then search
* each word for !. Following this can be any of string, number,
* ?string, -number ; then there may be a word specifier, the same as
@ -60,11 +62,12 @@ cp_histsubst(wordlist *wlist)
cp_didhsubst = FALSE;
if (*wlist->wl_word == cp_hat) {
(void) sprintf(buf, "%c%c:s%s", cp_bang, cp_bang,
wlist->wl_word);
(void) sprintf(buf, "%c%c:s%s", cp_bang, cp_bang,
wlist->wl_word);
tfree(wlist->wl_word);
wlist->wl_word = copy(buf);
}
for (w = wlist; w; w = w->wl_next) {
b = w->wl_word;
for (s = b; *s; s++)
@ -76,8 +79,7 @@ cp_histsubst(wordlist *wlist)
return (wlist);
}
if (b < s) {
(void) sprintf(buf, "%.*s%s", (int)(s-b), b,
n->wl_word);
(void) sprintf(buf, "%.*s%s", (int)(s-b), b, n->wl_word);
tfree(n->wl_word);
n->wl_word = copy(buf);
}
@ -88,9 +90,11 @@ cp_histsubst(wordlist *wlist)
break;
}
}
return (wlist);
}
/* Do a history substitution on one word. Figure out which event is
* being referenced, then do word selections and modifications, and
* then stick anything left over on the end of the last word.
@ -111,9 +115,9 @@ dohsubst(char *string)
return (NULL);
}
} else {
switch(*string) {
switch (*string) {
case '-':
case '-':
wl = getevent(cp_event - scannum(++string));
if (!wl)
return (NULL);
@ -121,7 +125,7 @@ dohsubst(char *string)
string++;
break;
case '?':
case '?':
(void) strcpy(buf, string + 1);
if ((s = strchr(buf, '?')) != NULL)
*s = '\0';
@ -132,12 +136,12 @@ dohsubst(char *string)
return (wl_copy(wl));
break;
case '\0': /* Maybe this should be cp_event. */
case '\0': /* Maybe this should be cp_event. */
wl = wl_cons(copy("!"), NULL);
cp_didhsubst = FALSE;
return (wl);
default:
default:
if (isdigit(*string)) {
wl = getevent(scannum(string));
if (!wl)
@ -147,7 +151,7 @@ dohsubst(char *string)
} else {
(void) strcpy(buf, string);
for (s = ":^$*-%"; *s; s++) {
t =strchr(buf, *s);
t = strchr(buf, *s);
if (t && ((t < r) || !r)) {
r = t;
string += r - buf;
@ -155,7 +159,7 @@ dohsubst(char *string)
}
if (r)
*r = '\0';
else
else
while (*string)
string++;
if ((buf[0] == '\0') && cp_lastone)
@ -167,13 +171,16 @@ dohsubst(char *string)
}
}
}
if (wl == NULL) { /* Shouldn't happen. */
fprintf(cp_err, "Event not found.\n");
return (NULL);
}
nwl = dohmod(&string, wl_copy(wl));
if (!nwl)
return (NULL);
if (*string) {
for (wl = nwl; wl->wl_next; wl = wl->wl_next)
;
@ -181,9 +188,11 @@ dohsubst(char *string)
tfree(wl->wl_word);
wl->wl_word = copy(buf);
}
return (nwl);
}
static wordlist *
dohmod(char **string, wordlist *wl)
{
@ -202,10 +211,11 @@ anothermod:
/* Now we know what wordlist we want. Take care of modifiers now. */
r = NULL;
for (s = ":^$*-%"; *s; s++) {
t =strchr(*string, *s);
t = strchr(*string, *s);
if (t && ((t < r) || (r == NULL)))
r = t;
}
if (!r) /* No more modifiers. */
return (wl);
@ -213,86 +223,89 @@ anothermod:
if (**string == ':')
(*string)++;
switch(**string) {
case '$': /* Last word. */
eventhi = eventlo = numwords - 1;
break;
case '*': /* Words 1 through $ */
if (numwords == 1)
return (NULL);
eventlo = 1;
switch (**string) {
case '$': /* Last word. */
eventhi = eventlo = numwords - 1;
break;
case '*': /* Words 1 through $ */
if (numwords == 1)
return (NULL);
eventlo = 1;
eventhi = numwords - 1;
break;
case '-': /* Words 0 through ... */
eventlo = 0;
if (*(*string + 1))
eventhi = scannum(*string + 1);
else
eventhi = numwords - 1;
break;
case '-': /* Words 0 through ... */
eventlo = 0;
if (*(*string + 1))
eventhi = scannum(*string + 1);
else
eventhi = numwords - 1;
if (eventhi > numwords - 1)
eventhi = numwords - 1;
break;
case 'p': /* Print the command and don't execute it.
if (eventhi > numwords - 1)
eventhi = numwords - 1;
break;
case 'p': /* Print the command and don't execute it.
* This doesn't work quite like csh.
*/
wl_print(wl, cp_out);
(void) putc('\n', cp_out);
return (NULL);
case 's': /* Do a substitution. */
for (w = wl; w; w = w->wl_next) {
s = dohs(*string + 1, w->wl_word);
if (s) {
tfree(w->wl_word);
w->wl_word = s;
if (globalsubst == FALSE) {
while (**string)
(*string)++;
break;
}
}
}
/* In case globalsubst is TRUE... */
while (**string)
(*string)++;
break;
default:
if (!isdigit(**string)) {
fprintf(cp_err, "Error: %s: bad modifier.\n",
*string);
return (NULL);
}
i = scannum(*string);
if (i > eventhi) {
fprintf(cp_err, "Error: bad event number %d\n",
i);
return (NULL);
}
eventhi = eventlo = i;
while (isdigit(**string))
(*string)++;
if (**string == '*')
eventhi = numwords - 1;
if (**string == '-') {
if (!isdigit(*(*string + 1)))
eventhi = numwords - 1;
else {
eventhi = scannum(++*string);
while (isdigit(**string))
wl_print(wl, cp_out);
(void) putc('\n', cp_out);
return (NULL);
case 's': /* Do a substitution. */
for (w = wl; w; w = w->wl_next) {
s = dohs(*string + 1, w->wl_word);
if (s) {
tfree(w->wl_word);
w->wl_word = s;
if (globalsubst == FALSE) {
while (**string)
(*string)++;
break;
}
}
}
}
/* In case globalsubst is TRUE... */
while (**string)
(*string)++;
break;
default:
if (!isdigit(**string)) {
fprintf(cp_err, "Error: %s: bad modifier.\n",
*string);
return (NULL);
}
i = scannum(*string);
if (i > eventhi) {
fprintf(cp_err, "Error: bad event number %d\n",
i);
return (NULL);
}
eventhi = eventlo = i;
while (isdigit(**string))
(*string)++;
if (**string == '*')
eventhi = numwords - 1;
if (**string == '-') {
if (!isdigit(*(*string + 1))) {
eventhi = numwords - 1;
} else {
eventhi = scannum(++*string);
while (isdigit(**string))
(*string)++;
}
}
}
/* Now change the word list accordingly and make another pass
* if there is more of the substitute left.
*/
wl = wl_range(wl, eventlo, eventhi);
numwords = wl_length(wl);
if (**string && *++*string)
goto anothermod;
return (wl);
}
/* Look for an event with a pattern in it... */
static wordlist *
@ -305,14 +318,17 @@ hpattern(char *buf)
fprintf(cp_err, "Bad pattern specification.\n");
return (NULL);
}
for (hi = cp_lastone; hi; hi = hi->hi_prev)
for (wl = hi->hi_wlist; wl; wl = wl->wl_next)
if (substring(buf, wl->wl_word))
return (hi->hi_wlist);
fprintf(cp_err, "%s: event not found.\n", buf);
return (NULL);
}
static wordlist *
hprefix(char *buf)
{
@ -322,13 +338,16 @@ hprefix(char *buf)
fprintf(cp_err, "Bad pattern specification.\n");
return (NULL);
}
for (hi = cp_lastone; hi; hi = hi->hi_prev)
if (hi->hi_wlist && prefix(buf, hi->hi_wlist->wl_word))
return (hi->hi_wlist);
fprintf(cp_err, "%s: event not found.\n", buf);
return (NULL);
}
/* Add a wordlist to the history list. (Done after the first parse.) Note
* that if event numbers are given in a random order that's how they'll
* show up in the history list.
@ -337,14 +356,14 @@ hprefix(char *buf)
void
cp_addhistent(int event, wordlist *wlist)
{
/* MW. This test is not needed if everything works right
if (cp_lastone && !cp_lastone->hi_wlist)
fprintf(cp_err, "Internal error: bad history list\n"); */
/* MW. This test is not needed if everything works right
if (cp_lastone && !cp_lastone->hi_wlist)
fprintf(cp_err, "Internal error: bad history list\n"); */
if (cp_lastone == NULL) {
/* MW. the begging - initialize histlength*/
histlength = 1;
/* MW. the begging - initialize histlength */
histlength = 1;
cp_lastone = histlist = alloc(struct histent);
cp_lastone->hi_prev = NULL;
} else {
@ -352,6 +371,7 @@ cp_addhistent(int event, wordlist *wlist)
cp_lastone->hi_next->hi_prev = cp_lastone;
cp_lastone = cp_lastone->hi_next;
}
cp_lastone->hi_next = NULL;
cp_lastone->hi_event = event;
cp_lastone->hi_wlist = wl_copy(wlist);
@ -362,8 +382,9 @@ cp_addhistent(int event, wordlist *wlist)
return;
}
/* Get a copy of the wordlist associated with an event. Error if out
* of range.
/* Get a copy of the wordlist associated with an event. Error if out
* of range.
*/
static wordlist *
@ -374,14 +395,17 @@ getevent(int num)
for (hi = histlist; hi; hi = hi->hi_next)
if (hi->hi_event == num)
break;
if (hi == NULL) {
fprintf(cp_err, "%d: event not found.\n", num);
return (NULL);
}
return (wl_copy(hi->hi_wlist));
}
/* Print out history between eventhi and eventlo.
/* Print out history between eventhi and eventlo.
* This doesn't remember quoting, so 'hodedo' prints as hodedo.
*/
@ -394,18 +418,20 @@ cp_hprint(int eventhi, int eventlo, bool rev)
for (hi = histlist; hi->hi_next; hi = hi->hi_next)
;
for (; hi; hi = hi->hi_prev)
if ((hi->hi_event <= eventhi) &&
(hi->hi_event >= eventlo) &&
hi->hi_wlist) {
if ((hi->hi_event <= eventhi) &&
(hi->hi_event >= eventlo) &&
hi->hi_wlist)
{
fprintf(cp_out, "%d\t", hi->hi_event);
wl_print(hi->hi_wlist, cp_out);
(void) putc('\n', cp_out);
}
} else {
for (hi = histlist; hi; hi = hi->hi_next)
if ((hi->hi_event <= eventhi) &&
(hi->hi_event >= eventlo) &&
hi->hi_wlist) {
if ((hi->hi_event <= eventhi) &&
(hi->hi_event >= eventlo) &&
hi->hi_wlist)
{
fprintf(cp_out, "%d\t", hi->hi_event);
wl_print(hi->hi_wlist, cp_out);
(void) putc('\n', cp_out);
@ -414,6 +440,7 @@ cp_hprint(int eventhi, int eventlo, bool rev)
return;
}
#if !defined(HAVE_GNUREADLINE) && !defined(HAVE_BSDEDITLINE)
/* This just gets rid of the first num entries on the history list, and
@ -427,29 +454,35 @@ freehist(int num)
if (num < 1)
return;
histlength -= num;
hi = histlist;
while (num-- && histlist->hi_next)
histlist = histlist->hi_next;
if (histlist->hi_prev) {
histlist->hi_prev->hi_next = NULL;
histlist->hi_prev = NULL;
} else
{
} else {
fprintf(cp_err, "Internal error: history list mangled\n");
exit(0); /* Chris Inbody */
}
}
while (hi->hi_next) {
wl_free(hi->hi_wlist);
hi = hi->hi_next;
tfree(hi->hi_prev);
}
wl_free(hi->hi_wlist);
tfree(hi);
return;
}
#endif /* !defined(HAVE_GNUREADLINE) && !defined(HAVE_BSDEDITLINE) */
/* Do a :s substitution. */
static char *
@ -461,15 +494,17 @@ dohs(char *pat, char *str)
pat = copy(pat); /* Don't want to mangle anything. */
schar = *pat++;
s =strchr(pat, schar);
s = strchr(pat, schar);
if (s == NULL) {
fprintf(cp_err, "Bad substitute.\n");
return (NULL);
}
*s++ = '\0';
p =strchr(s, schar);
p = strchr(s, schar);
if (p)
*p = '\0';
plen = (int) strlen(pat) - 1;
for (i = 0; *str; str++) {
if ((*str == *pat) && prefix(pat, str) && (ok == FALSE)) {
@ -477,16 +512,19 @@ dohs(char *pat, char *str)
buf[i++] = *p;
str += plen;
ok = TRUE;
} else
} else {
buf[i++] = *str;
}
}
buf[i] = '\0';
if (ok)
return (copy(buf));
else
return (NULL);
}
/* The "history" command. history [-r] [number] */
void
@ -502,26 +540,30 @@ com_history(wordlist *wl)
#if defined(HAVE_GNUREADLINE) || defined(HAVE_BSDEDITLINE)
/* Added GNU Readline Support -- Andrew Veliath <veliaa@rpi.edu> */
{
HIST_ENTRY *he;
int i, N;
HIST_ENTRY *he;
int i, N;
N = (wl == NULL) ? history_length : atoi(wl->wl_word);
N = (wl == NULL) ? history_length : atoi(wl->wl_word);
if (N < 0) N = 0;
if (N > history_length) N = history_length;
if (N < 0)
N = 0;
if (N > history_length)
N = history_length;
if (rev)
for (i = history_length; i > 0 && N; --i, --N) {
he = history_get(i);
if (!he) return;
fprintf(cp_out, "%d\t%s\n", i, he->line);
}
else
for (i = history_length - N + 1; i <= history_length; ++i) {
he = history_get(i);
if (!he) return;
fprintf(cp_out, "%d\t%s\n", i, he->line);
}
if (rev)
for (i = history_length; i > 0 && N; --i, --N) {
he = history_get(i);
if (!he)
return;
fprintf(cp_out, "%d\t%s\n", i, he->line);
}
else
for (i = history_length - N + 1; i <= history_length; ++i) {
he = history_get(i);
if (!he)
return;
fprintf(cp_out, "%d\t%s\n", i, he->line);
}
}
#else
if (wl == NULL)

View File

@ -14,8 +14,8 @@ void
com_let(wordlist *wl)
{
char *p, *q, *s;
int indices[MAXDIMS];
int numdims;
int indices[MAXDIMS];
int numdims;
wordlist fake_wl;
int need_open;
int offset, length;
@ -38,85 +38,87 @@ com_let(wordlist *wl)
/* extract indices */
numdims = 0;
if ((rhs = strchr(p, '=')) != NULL) {
*rhs++ = 0;
*rhs++ = 0;
} else {
fprintf(cp_err, "Error: bad let syntax\n");
tfree(p);
return;
fprintf(cp_err, "Error: bad let syntax\n");
tfree(p);
return;
}
if ((s = strchr(p, '[')) != NULL) {
need_open = 0;
*s++ = 0;
while (!need_open || *s == '[') {
depth = 0;
if (need_open)
s++;
for (q = s; *q && (*q != ']' && (*q != ',' || depth > 0)); q++) {
switch (*q) {
case '[':
depth += 1;
break;
case ']':
depth -= 1;
break;
}
}
need_open = 0;
*s++ = 0;
while (!need_open || *s == '[') {
depth = 0;
if (need_open)
s++;
for (q = s; *q && (*q != ']' && (*q != ',' || depth > 0)); q++) {
switch (*q) {
case '[':
depth += 1;
break;
case ']':
depth -= 1;
break;
}
}
if (depth != 0 || !*q) {
printf("syntax error specifying index\n");
tfree(p);
return;
}
if (depth != 0 || !*q) {
printf("syntax error specifying index\n");
tfree(p);
return;
}
if (*q == ']')
need_open = 1;
else
need_open = 0;
if (*q)
*q++ = 0;
if (*q == ']')
need_open = 1;
else
need_open = 0;
/* evaluate expression between s and q */
/* va, indexing */
fake_wl.wl_word = s;
nn = ft_getpnames(&fake_wl, TRUE);
if (!nn) {
/* XXX error message */
tfree(p);
return;
}
t = ft_evaluate(nn);
if (!t) {
fprintf(cp_err, "Error: Can't evaluate %s\n", s);
free_pnode(nn);
tfree(p);
return;
}
if (!isreal(t) || t->v_link2 || t->v_length != 1 || !t->v_realdata)
{
fprintf(cp_err, "Error: index is not a scalar.\n");
goto quit;
}
j = (int)floor(t->v_realdata[0]+0.5); /* ignore sanity checks for now, va, which checks? */
if (*q)
*q++ = 0;
if (j < 0) {
printf("negative index (%d) is not allowed\n", j);
goto quit;
}
/* evaluate expression between s and q */
/* va, indexing */
fake_wl.wl_word = s;
nn = ft_getpnames(&fake_wl, TRUE);
if (!nn) {
/* XXX error message */
tfree(p);
return;
}
t = ft_evaluate(nn);
if (!t) {
fprintf(cp_err, "Error: Can't evaluate %s\n", s);
free_pnode(nn);
tfree(p);
return;
}
if (!isreal(t) || t->v_link2 || t->v_length != 1 || !t->v_realdata) {
fprintf(cp_err, "Error: index is not a scalar.\n");
goto quit;
}
j = (int)floor(t->v_realdata[0]+0.5); /* ignore sanity checks for now, va, which checks? */
indices[numdims++] = j;
if (j < 0) {
printf("negative index (%d) is not allowed\n", j);
goto quit;
}
/* va: garbage collection for t, if pnode nn is no simple value */
if (nn!=NULL && nn->pn_value==NULL && t!=NULL) vec_free(t);
free_pnode(nn); /* frees also t, if pnode nn is simple value */
indices[numdims++] = j;
for (s = q; *s && isspace(*s); s++)
;
}
/* va: garbage collection for t, if pnode nn is no simple value */
if (nn != NULL && nn->pn_value == NULL && t != NULL)
vec_free(t);
free_pnode(nn); /* frees also t, if pnode nn is simple value */
for (s = q; *s && isspace(*s); s++)
;
}
}
/* vector name at p */
for (q = p + strlen(p) - 1; *q <= ' ' && p <= q; q--)
;
;
*++q = 0;
@ -131,13 +133,13 @@ com_let(wordlist *wl)
fake_wl.wl_word = rhs;
nn = ft_getpnames(&fake_wl, TRUE);
if (nn == NULL) {
/* XXX error message */
/* XXX error message */
tfree(p);
return;
}
t = ft_evaluate(nn);
if (!t) {
fprintf(cp_err, "Error: Can't evaluate %s\n", rhs);
fprintf(cp_err, "Error: Can't evaluate %s\n", rhs);
free_pnode(nn);
tfree(p);
return;
@ -149,44 +151,44 @@ com_let(wordlist *wl)
n = vec_get(p);
if (n) {
/* re-allocate? */
/* vec_free(n); */
newvec = 0;
/* re-allocate? */
/* vec_free(n); */
newvec = 0;
} else {
if (numdims) {
fprintf(cp_err, "Can't assign into a subindex of a new vector\n");
goto quit;
}
if (numdims) {
fprintf(cp_err, "Can't assign into a subindex of a new vector\n");
goto quit;
}
/* create and assign a new vector */
n = alloc(struct dvec);
ZERO(n, struct dvec);
n->v_name = copy(p);
n->v_type = t->v_type;
n->v_flags = (t->v_flags | VF_PERMANENT);
n->v_length = t->v_length;
/* create and assign a new vector */
n = alloc(struct dvec);
ZERO(n, struct dvec);
n->v_name = copy(p);
n->v_type = t->v_type;
n->v_flags = (t->v_flags | VF_PERMANENT);
n->v_length = t->v_length;
if ((t->v_numdims)<=1) { // changed from "!t->v_numdims" by Friedrich Schmidt
n->v_numdims = 1;
n->v_dims[0] = n->v_length;
} else {
n->v_numdims = t->v_numdims;
for (i = 0; i < t->v_numdims; i++)
n->v_dims[i] = t->v_dims[i];
}
if ((t->v_numdims) <= 1) { // changed from "!t->v_numdims" by Friedrich Schmidt
n->v_numdims = 1;
n->v_dims[0] = n->v_length;
} else {
n->v_numdims = t->v_numdims;
for (i = 0; i < t->v_numdims; i++)
n->v_dims[i] = t->v_dims[i];
}
if (isreal(t))
n->v_realdata = TMALLOC(double, n->v_length);
else
n->v_compdata = TMALLOC(ngcomplex_t, n->v_length);
newvec = 1;
vec_new(n);
if (isreal(t))
n->v_realdata = TMALLOC(double, n->v_length);
else
n->v_compdata = TMALLOC(ngcomplex_t, n->v_length);
newvec = 1;
vec_new(n);
}
/* fix-up dimensions; va, also for v_dims */
if (n->v_numdims < 1 || n->v_dims[0]==0 ) {
n->v_numdims = 1;
n->v_dims[0] = n->v_length;
if (n->v_numdims < 1 || n->v_dims[0] == 0 ) {
n->v_numdims = 1;
n->v_dims[0] = n->v_length;
}
/* Compare dimensions */
@ -195,38 +197,38 @@ com_let(wordlist *wl)
cube = 1;
for (i = n->v_numdims - 1; i >= numdims; i--)
cube *= n->v_dims[i];
cube *= n->v_dims[i];
for (i = numdims - 1; i >= 0; i--) {
offset += cube * indices[i];
if (i < n->v_numdims) {
cube *= n->v_dims[i];
length /= n->v_dims[i];
}
offset += cube * indices[i];
if (i < n->v_numdims) {
cube *= n->v_dims[i];
length /= n->v_dims[i];
}
}
/* length is the size of the unit refered to */
/* cube ends up being the length */
if (length > t->v_length) {
fprintf(cp_err, "left-hand expression is too small (need %d)\n",
length * cube);
if (newvec)
n->v_flags &= ~VF_PERMANENT;
goto quit;
fprintf(cp_err, "left-hand expression is too small (need %d)\n",
length * cube);
if (newvec)
n->v_flags &= ~VF_PERMANENT;
goto quit;
}
if (isreal(t) != isreal(n)) {
fprintf(cp_err,
"Types of vectors are not the same (real vs. complex)\n");
if (newvec)
n->v_flags &= ~VF_PERMANENT;
goto quit;
fprintf(cp_err,
"Types of vectors are not the same (real vs. complex)\n");
if (newvec)
n->v_flags &= ~VF_PERMANENT;
goto quit;
} else if (isreal(t)) {
bcopy(t->v_realdata, n->v_realdata + offset,
(size_t) length * sizeof (double));
bcopy(t->v_realdata, n->v_realdata + offset,
(size_t) length * sizeof(double));
} else {
bcopy(t->v_compdata, n->v_compdata + offset,
(size_t) length * sizeof(ngcomplex_t));
bcopy(t->v_compdata, n->v_compdata + offset,
(size_t) length * sizeof(ngcomplex_t));
}
n->v_minsignal = 0.0; /* How do these get reset ??? */
@ -235,11 +237,12 @@ com_let(wordlist *wl)
n->v_scale = t->v_scale;
if (newvec)
cp_addkword(CT_VECTOR, n->v_name);
cp_addkword(CT_VECTOR, n->v_name);
quit:
/* va: garbage collection for t, if pnode nn is no simple value */
if (nn!=NULL && nn->pn_value==NULL && t!=NULL) vec_free(t);
if (nn != NULL && nn->pn_value == NULL && t != NULL)
vec_free(t);
free_pnode(nn); /* frees also t, if pnode nn is simple value */
tfree(p);
return;

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,9 @@
#include "ngspice/config.h"
extern int measure_get_precision(void) ;
extern int get_measure2(wordlist *wl,double *result,char *out_line, bool auto_check) ;
extern int measure_extract_variables( char *line ) ;
extern int measure_get_precision(void);
extern int get_measure2(wordlist *wl, double *result, char *out_line, bool auto_check);
extern int measure_extract_variables(char *line);
void com_dotmeasure(wordlist *wl);

View File

@ -14,39 +14,37 @@
void
com_option(wordlist *wl)
{
struct variable *vars;
struct variable *vars;
CKTcircuit *circuit = NULL;
if (!ft_curckt) {
fprintf(cp_err, "Error: no circuit loaded\n");
return;
fprintf(cp_err, "Error: no circuit loaded\n");
return;
}
circuit = (ft_curckt->ci_ckt);
if (wl == NULL) {
printf("******************************\n");
printf("* Current simulation options *\n");
printf("******************************\n\n");
printf("Temperatures:\n");
printf("temp = %f\n",circuit->CKTtemp);
printf("tnom = %f\n",circuit->CKTnomTemp);
printf("temp = %f\n", circuit->CKTtemp);
printf("tnom = %f\n", circuit->CKTnomTemp);
printf("\nIntegration method summary:\n");
switch (circuit->CKTintegrateMethod)
{
case TRAPEZOIDAL:
printf("Integration Method = TRAPEZOIDAL\n");
break;
case GEAR:
printf("Integration Method = GEAR\n");
break;
default:
printf("Unknown integration method\n");
}
{
case TRAPEZOIDAL:
printf("Integration Method = TRAPEZOIDAL\n");
break;
case GEAR:
printf("Integration Method = GEAR\n");
break;
default:
printf("Unknown integration method\n");
}
printf("MaxOrder = %d\n", circuit->CKTmaxOrder);
printf("\nTolerances (absolute):\n");
@ -87,28 +85,29 @@ struct variable *vars;
return;
}
vars = cp_setparse(wl);
/* This is sort of a hassle... */
while (vars) {
void *s;
switch (vars->va_type) {
case CP_BOOL:
case CP_BOOL:
s = &vars->va_bool;
break;
case CP_NUM:
case CP_NUM:
s = &vars->va_num;
break;
case CP_REAL:
case CP_REAL:
s = &vars->va_real;
break;
case CP_STRING:
case CP_STRING:
s = vars->va_string;
break;
case CP_LIST:
case CP_LIST:
s = vars->va_vlist;
break;
default:
default:
s = NULL;
}

View File

@ -23,38 +23,37 @@ com_set(wordlist *wl)
vars = cp_setparse(wl);
/* This is sort of a hassle... */
while (vars) {
while (vars) {
void *s;
switch (vars->va_type) {
case CP_BOOL:
case CP_BOOL:
s = &vars->va_bool;
break;
case CP_NUM:
case CP_NUM:
s = &vars->va_num;
break;
case CP_REAL:
case CP_REAL:
s = &vars->va_real;
break;
case CP_STRING:
case CP_STRING:
s = vars->va_string;
break;
case CP_LIST:
case CP_LIST:
s = vars->va_vlist;
break;
default:
s = NULL;
default:
s = NULL;
}
cp_vset(vars->va_name, vars->va_type, s);
oldvar = vars;
oldvar = vars;
vars = vars->va_next;
/* va: avoid memory leak: free oldvar carefully */
/* va: avoid memory leak: free oldvar carefully */
tfree(oldvar->va_name);
if (oldvar->va_type==CP_STRING)
if (oldvar->va_type == CP_STRING)
tfree(oldvar->va_string); /* copied in cp_vset */
/* don't free oldvar->va_list! This structure is used furthermore! */
tfree(oldvar);
}
return;
}

View File

@ -20,19 +20,20 @@ com_setscale(wordlist *wl)
char *s;
if (plot_cur) {
if (wl) {
s = cp_unquote(wl->wl_word);
d = vec_get(s);
if(s) tfree(s);/*DG to avoid the cp_unquote memory leak */
if (d == NULL)
fprintf(cp_err, "Error: no such vector as %s.\n",
wl->wl_word);
else
plot_cur->pl_scale = d;
} else if (plot_cur->pl_scale) {
pvec(plot_cur->pl_scale);
}
if (wl) {
s = cp_unquote(wl->wl_word);
d = vec_get(s);
if (s)
tfree(s);/*DG to avoid the cp_unquote memory leak */
if (d == NULL)
fprintf(cp_err, "Error: no such vector as %s.\n", wl->wl_word);
else
plot_cur->pl_scale = d;
} else if (plot_cur->pl_scale) {
pvec(plot_cur->pl_scale);
}
} else {
fprintf(cp_err, "Error: no current plot.\n");
fprintf(cp_err, "Error: no current plot.\n");
}
}

View File

@ -10,6 +10,7 @@
#include "streams.h"
#include "ngspice/cpextern.h"
/* Fork a shell. */
void
@ -21,44 +22,44 @@ com_shell(wordlist *wl)
if (shell == NULL)
shell = "/bin/csh";
cp_ccon(FALSE);
cp_ccon(FALSE);
#ifdef HAVE_VFORK_H
/* XXX Needs to switch process groups. Also, worry about suspend */
/* Only bother for efficiency */
pid = vfork();
if (pid == 0) {
fixdescriptors();
if (wl == NULL) {
execl(shell, shell, 0);
_exit(99);
} else {
com = wl_flatten(wl);
execl("/bin/sh", "sh", "-c", com, 0);
}
/* XXX Needs to switch process groups. Also, worry about suspend */
/* Only bother for efficiency */
pid = vfork();
if (pid == 0) {
fixdescriptors();
if (wl == NULL) {
execl(shell, shell, 0);
_exit(99);
} else {
/* XXX Better have all these signals */
svint = signal(SIGINT, SIG_DFL);
svquit = signal(SIGQUIT, SIG_DFL);
svtstp = signal(SIGTSTP, SIG_DFL);
/* XXX Sig on proc group */
do {
r = wait(NULL);
} while ((r != pid) && pid != -1);
signal(SIGINT, (SIGNAL_FUNCTION) svint);
signal(SIGQUIT, (SIGNAL_FUNCTION) svquit);
signal(SIGTSTP, (SIGNAL_FUNCTION) svtstp);
com = wl_flatten(wl);
execl("/bin/sh", "sh", "-c", com, 0);
}
} else {
/* XXX Better have all these signals */
svint = signal(SIGINT, SIG_DFL);
svquit = signal(SIGQUIT, SIG_DFL);
svtstp = signal(SIGTSTP, SIG_DFL);
/* XXX Sig on proc group */
do
r = wait(NULL);
while ((r != pid) && pid != -1);
signal(SIGINT, (SIGNAL_FUNCTION) svint);
signal(SIGQUIT, (SIGNAL_FUNCTION) svquit);
signal(SIGTSTP, (SIGNAL_FUNCTION) svtstp);
}
#else
/* Easier to forget about changing the io descriptors. */
if (wl) {
com = wl_flatten(wl);
system(com);
tfree(com);
} else
} else {
system(shell);
}
#endif
return;
}

View File

@ -1,14 +1,14 @@
/* Provide system information
LINUX: /proc file system
Windows: GlobalMemoryStatusEx, GetSystemInfo, GetVersionExA, RegQueryValueExA
Authors: Holger Vogt, Hendrik Vogt
*/
#include "ngspice/config.h"
#include "ngspice/ngspice.h"
#include "ngspice/ngspice.h"
#include "ngspice/cpdefs.h"
#include "ngspice/fteext.h"
#include "com_commands.h"
@ -21,7 +21,7 @@
#ifdef HAVE_WIN32
#define WIN32_LEAN_AND_MEAN
#ifdef __MINGW32__ /* access to GlobalMemoryStatusEx in winbase.h:1558 */
#define WINVER 0x0500
#endif
@ -45,429 +45,436 @@
/* system info */
typedef struct TSI {
char* cpuModelName;
unsigned numPhysicalProcessors;
unsigned numLogicalProcessors;
char* osName;
char *cpuModelName;
unsigned numPhysicalProcessors;
unsigned numLogicalProcessors;
char *osName;
} TesSystemInfo;
/* memory info */
struct sys_memory {
unsigned long long size_m; /* Total memory size */
unsigned long long free_m; /* Free memory */
unsigned long long swap_t; /* Swap total */
unsigned long long swap_f; /* Swap free */
unsigned long long size_m; /* Total memory size */
unsigned long long free_m; /* Free memory */
unsigned long long swap_t; /* Swap total */
unsigned long long swap_f; /* Swap free */
};
static struct sys_memory mem_t_act;
static struct sys_memory mem_t_act;
TesError tesCreateSystemInfo(TesSystemInfo *info);
static int get_sysmem(struct sys_memory *memall);
/* Print to stream the given memory size in a human friendly format */
static void
fprintmem(FILE* stream, unsigned long long memory) {
fprintmem(FILE *stream, unsigned long long memory)
{
if (memory > 1048576)
fprintf(stream, "%8.6f MB", (double)memory /1048576.);
fprintf(stream, "%8.6f MB", (double)memory /1048576.);
else if (memory > 1024)
fprintf(stream, "%5.3f kB", (double)memory / 1024.);
fprintf(stream, "%5.3f kB", (double)memory / 1024.);
else
fprintf(stream, "%u bytes", (unsigned)memory);
fprintf(stream, "%u bytes", (unsigned)memory);
}
static void tesFreeSystemInfo(TesSystemInfo *info) {
if(info != NULL) {
free(info->cpuModelName);
free(info->osName);
}
static void
tesFreeSystemInfo(TesSystemInfo *info)
{
if (info != NULL) {
free(info->cpuModelName);
free(info->osName);
}
}
/* print system info */
void com_sysinfo(wordlist *wl)
void
com_sysinfo(wordlist *wl)
{
int errorcode;
TesSystemInfo* info;
int errorcode;
TesSystemInfo *info;
NG_IGNORE(wl);
NG_IGNORE(wl);
info = TMALLOC(TesSystemInfo, 1);
info = TMALLOC(TesSystemInfo, 1);
errorcode = tesCreateSystemInfo(info);
if (errorcode)
fprintf(cp_err, "No system info available! \n");
else {
fprintf(cp_out, "\nOS: %s\n", info->osName);
fprintf(cp_out, "CPU: %s\n", info->cpuModelName);
if (info->numPhysicalProcessors > 0)
fprintf(cp_out, "Physical processors: %u, ", info->numPhysicalProcessors);
fprintf(cp_out, "Logical processors: %u\n",
info->numLogicalProcessors);
}
#if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
get_sysmem(&mem_t_act);
/* get_sysmem returns bytes */
fprintf(cp_out, "Total DRAM available = ");
fprintmem(cp_out, mem_t_act.size_m);
fprintf(cp_out, ".\n");
fprintf(cp_out, "DRAM currently available = ");
fprintmem(cp_out, mem_t_act.free_m);
fprintf(cp_out, ".\n\n");
errorcode = tesCreateSystemInfo(info);
if (errorcode) {
fprintf(cp_err, "No system info available! \n");
} else {
fprintf(cp_out, "\nOS: %s\n", info->osName);
fprintf(cp_out, "CPU: %s\n", info->cpuModelName);
if (info->numPhysicalProcessors > 0)
fprintf(cp_out, "Physical processors: %u, ", info->numPhysicalProcessors);
fprintf(cp_out, "Logical processors: %u\n",
info->numLogicalProcessors);
}
#if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
get_sysmem(&mem_t_act);
/* get_sysmem returns bytes */
fprintf(cp_out, "Total DRAM available = ");
fprintmem(cp_out, mem_t_act.size_m);
fprintf(cp_out, ".\n");
fprintf(cp_out, "DRAM currently available = ");
fprintmem(cp_out, mem_t_act.free_m);
fprintf(cp_out, ".\n\n");
#endif
tesFreeSystemInfo(info);
tfree(info);
tesFreeSystemInfo(info);
tfree(info);
}
#ifdef HAVE__PROC_MEMINFO
#ifdef HAVE__PROC_MEMINFO
/* Get memory information */
static int get_sysmem(struct sys_memory *memall) {
FILE *fp;
char buffer[2048];
size_t bytes_read;
char *match;
unsigned long mem_got;
static int
get_sysmem(struct sys_memory *memall)
{
FILE *fp;
char buffer[2048];
size_t bytes_read;
char *match;
unsigned long mem_got;
if((fp = fopen("/proc/meminfo", "r")) == NULL) {
perror("fopen(\"/proc/meminfo\")");
return 0;
}
bytes_read = fread (buffer, 1, sizeof (buffer), fp);
fclose (fp);
if (bytes_read == 0 || bytes_read == sizeof (buffer))
return 0;
buffer[bytes_read] = '\0';
if ((fp = fopen("/proc/meminfo", "r")) == NULL) {
perror("fopen(\"/proc/meminfo\")");
return 0;
}
/* Search for string "MemTotal" */
match = strstr (buffer, "MemTotal");
if (match == NULL) /* not found */
return 0;
sscanf (match, "MemTotal: %ld", &mem_got);
memall->size_m = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "MemFree" */
match = strstr (buffer, "MemFree");
if (match == NULL) /* not found */
return 0;
sscanf (match, "MemFree: %ld", &mem_got);
memall->free_m = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "SwapTotal" */
match = strstr (buffer, "SwapTotal");
if (match == NULL) /* not found */
return 0;
sscanf (match, "SwapTotal: %ld", &mem_got);
memall->swap_t = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "SwapFree" */
match = strstr (buffer, "SwapFree");
if (match == NULL) /* not found */
return 0;
sscanf (match, "SwapFree: %ld", &mem_got);
memall->swap_f = mem_got*1024; /* 1MB = 1024KB */
return 1;
bytes_read = fread(buffer, 1, sizeof(buffer), fp);
fclose(fp);
if (bytes_read == 0 || bytes_read == sizeof(buffer))
return 0;
buffer[bytes_read] = '\0';
/* Search for string "MemTotal" */
match = strstr(buffer, "MemTotal");
if (match == NULL) /* not found */
return 0;
sscanf(match, "MemTotal: %ld", &mem_got);
memall->size_m = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "MemFree" */
match = strstr(buffer, "MemFree");
if (match == NULL) /* not found */
return 0;
sscanf(match, "MemFree: %ld", &mem_got);
memall->free_m = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "SwapTotal" */
match = strstr(buffer, "SwapTotal");
if (match == NULL) /* not found */
return 0;
sscanf(match, "SwapTotal: %ld", &mem_got);
memall->swap_t = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "SwapFree" */
match = strstr(buffer, "SwapFree");
if (match == NULL) /* not found */
return 0;
sscanf(match, "SwapFree: %ld", &mem_got);
memall->swap_f = mem_got*1024; /* 1MB = 1024KB */
return 1;
}
/* Return length of first line in a string */
static size_t getLineLength(const char *str) {
const char *p = str;
static size_t
getLineLength(const char *str)
{
const char *p = str;
while(*p && (*p != '\n'))
p++;
while (*p && (*p != '\n'))
p++;
return (size_t) (p - str);
return (size_t) (p - str);
}
/* Checks if number 'match' is found in a vector 'set' of size 'size'
Returns 1 if yes, otherwise, 0 */
static tInt searchInSet(const tInt *set, unsigned size, tInt match) {
unsigned index;
for(index = 0; index < size; index++) {
if(match == set[index]) {
return 1;
}
}
return 0;
static tInt
searchInSet(const tInt *set, unsigned size, tInt match)
{
unsigned index;
for (index = 0; index < size; index++)
if (match == set[index])
return 1;
return 0;
}
/* Get system information */
TesError tesCreateSystemInfo(TesSystemInfo *info) {
FILE *file;
TesError error = TES_SUCCESS;
if(info == NULL)
return TES_INVALID_PARAMS;
info->cpuModelName = NULL;
info->osName = NULL;
info->numLogicalProcessors = info->numPhysicalProcessors = 0;
/* get kernel version string */
file = fopen("/proc/version", "rb");
if(file != NULL) {
size_t size;
/* read bytes and find end of file */
for(size=0; ; size++)
if(EOF == fgetc(file))
break;
TesError
tesCreateSystemInfo(TesSystemInfo *info)
{
FILE *file;
TesError error = TES_SUCCESS;
info->osName = TMALLOC(char, size);
rewind(file);
fread(info->osName, sizeof(char), size, file);
fclose(file);
info->osName[size-1] = '\0';
}
else {
error = TES_FAIL;
}
/* get cpu information */
file = fopen("/proc/cpuinfo", "rb");
if(file != NULL) {
size_t size;
char *inStr;
/* read bytes and find end of file */
for(size=0; ; size++)
if(EOF == fgetc(file))
break;
if (info == NULL)
return TES_INVALID_PARAMS;
info->cpuModelName = NULL;
info->osName = NULL;
info->numLogicalProcessors = info->numPhysicalProcessors = 0;
/* get complete string */
inStr = TMALLOC(char, size+1);
rewind(file);
fread(inStr, sizeof(char), size, file);
inStr[size] = '\0';
{
const char *matchStr = "model name";
/* pointer to first occurrence of model name*/
const char *modelStr = strstr(inStr, matchStr);
if(modelStr != NULL) {
/* search for ':' */
const char *modelPtr = strchr(modelStr, ':');
if(modelPtr != NULL) {
/*length of string from ':' till end of line */
size_t numToEOL = getLineLength(modelPtr);
if(numToEOL > 2) {
/* skip ": "*/
numToEOL-=2;
info->cpuModelName = TMALLOC(char, numToEOL+1);
memcpy(info->cpuModelName, modelPtr+2, numToEOL);
info->cpuModelName[numToEOL] = '\0';
}
}
else {
error = TES_FAIL;
}
}
else {
error = TES_FAIL;
}
}
{
const char *matchStrProc = "processor";
const char *matchStrPhys = "physical id";
char *strPtr = inStr;
unsigned numProcs = 0;
tInt *physIDs;
/* get number of logical processors */
while((strPtr = strstr(strPtr, matchStrProc)) != NULL) {
// numProcs++;
strPtr += strlen(matchStrProc);
if (isblank(*strPtr)) numProcs++;
}
info->numLogicalProcessors = numProcs;
physIDs = TMALLOC(tInt, numProcs);
/* get number of physical CPUs */
numProcs = 0;
strPtr = inStr;
while((strPtr = strstr(strPtr, matchStrProc)) != NULL) {
/* search for first occurrence of physical id */
strPtr = strstr(strPtr, matchStrPhys);
if(strPtr != NULL) {
/* go to ';' */
strPtr = strchr(strPtr, ':');
if(strPtr != NULL) {
tInt buffer = 0;
/* skip ": " */
strPtr += 2;
/* get number */
sscanf(strPtr, "%d", &buffer);
/* If this physical id is unique,
we have another physically available CPU */
if(searchInSet(physIDs, numProcs, buffer) == 0) {
physIDs[numProcs] = buffer;
numProcs++;
}
}
else {
// error = TES_FAIL;
break;
}
}
else {
// error = TES_FAIL;
break;
}
}
info->numPhysicalProcessors = numProcs;
free(physIDs);
}
/* get kernel version string */
file = fopen("/proc/version", "rb");
if (file != NULL) {
size_t size;
/* another test to get number of logical processors
if (info->numLogicalProcessors == 0) {
char* token;
char* cpustr = copy(inStr);
while ((cpustr) && !*cpustr)
if (cieq(gettok(&cpustr), "processor")) {
gettok(&cpustr);
token = gettok(&cpustr);
/* read bytes and find end of file */
for (size = 0; ; size++)
if (EOF == fgetc(file))
break;
info->osName = TMALLOC(char, size);
rewind(file);
fread(info->osName, sizeof(char), size, file);
fclose(file);
info->osName[size-1] = '\0';
} else {
error = TES_FAIL;
}
/* get cpu information */
file = fopen("/proc/cpuinfo", "rb");
if (file != NULL) {
size_t size;
char *inStr;
/* read bytes and find end of file */
for (size = 0; ; size++)
if (EOF == fgetc(file))
break;
/* get complete string */
inStr = TMALLOC(char, size+1);
rewind(file);
fread(inStr, sizeof(char), size, file);
inStr[size] = '\0';
{
const char *matchStr = "model name";
/* pointer to first occurrence of model name*/
const char *modelStr = strstr(inStr, matchStr);
if (modelStr != NULL) {
/* search for ':' */
const char *modelPtr = strchr(modelStr, ':');
if (modelPtr != NULL) {
/*length of string from ':' till end of line */
size_t numToEOL = getLineLength(modelPtr);
if (numToEOL > 2) {
/* skip ": "*/
numToEOL -= 2;
info->cpuModelName = TMALLOC(char, numToEOL+1);
memcpy(info->cpuModelName, modelPtr+2, numToEOL);
info->cpuModelName[numToEOL] = '\0';
}
} else {
error = TES_FAIL;
}
} else {
error = TES_FAIL;
}
info->numLogicalProcessors = atoi(token) + 1;
tfree(cpustr);
}*/
free(inStr);
fclose(file);
}
else {
error = TES_FAIL;
}
}
{
const char *matchStrProc = "processor";
const char *matchStrPhys = "physical id";
char *strPtr = inStr;
unsigned numProcs = 0;
tInt *physIDs;
return error;
/* get number of logical processors */
while ((strPtr = strstr(strPtr, matchStrProc)) != NULL) {
// numProcs++;
strPtr += strlen(matchStrProc);
if (isblank(*strPtr)) numProcs++;
}
info->numLogicalProcessors = numProcs;
physIDs = TMALLOC(tInt, numProcs);
/* get number of physical CPUs */
numProcs = 0;
strPtr = inStr;
while ((strPtr = strstr(strPtr, matchStrProc)) != NULL) {
/* search for first occurrence of physical id */
strPtr = strstr(strPtr, matchStrPhys);
if (strPtr != NULL) {
/* go to ';' */
strPtr = strchr(strPtr, ':');
if (strPtr != NULL) {
tInt buffer = 0;
/* skip ": " */
strPtr += 2;
/* get number */
sscanf(strPtr, "%d", &buffer);
/* If this physical id is unique,
we have another physically available CPU */
if (searchInSet(physIDs, numProcs, buffer) == 0) {
physIDs[numProcs] = buffer;
numProcs++;
}
} else {
// error = TES_FAIL;
break;
}
} else {
// error = TES_FAIL;
break;
}
}
info->numPhysicalProcessors = numProcs;
free(physIDs);
}
/* another test to get number of logical processors
* if (info->numLogicalProcessors == 0) {
* char *token;
* char *cpustr = copy(inStr);
* while ((cpustr) && !*cpustr)
* if (cieq(gettok(&cpustr), "processor")) {
* gettok(&cpustr);
* token = gettok(&cpustr);
* }
*
* info->numLogicalProcessors = atoi(token) + 1;
* tfree(cpustr);
* }
*/
free(inStr);
fclose(file);
} else {
error = TES_FAIL;
}
return error;
}
#elif defined(HAVE_WIN32)
/* get memory information */
static int get_sysmem(struct sys_memory *memall) {
#if ( _WIN32_WINNT >= 0x0500)
MEMORYSTATUSEX ms;
ms.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx( &ms);
memall->size_m = ms.ullTotalPhys;
memall->free_m = ms.ullAvailPhys;
memall->swap_t = ms.ullTotalPageFile;
memall->swap_f = ms.ullAvailPageFile;
static int
get_sysmem(struct sys_memory *memall)
{
#if (_WIN32_WINNT >= 0x0500)
MEMORYSTATUSEX ms;
ms.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&ms);
memall->size_m = ms.ullTotalPhys;
memall->free_m = ms.ullAvailPhys;
memall->swap_t = ms.ullTotalPageFile;
memall->swap_f = ms.ullAvailPageFile;
#else
MEMORYSTATUS ms;
ms.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus( &ms);
memall->size_m = ms.dwTotalPhys;
memall->free_m = ms.dwAvailPhys;
memall->swap_t = ms.dwTotalPageFile;
memall->swap_f = ms.dwAvailPageFile;
#endif /*_WIN32_WINNT 0x0500*/
return 1;
MEMORYSTATUS ms;
ms.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&ms);
memall->size_m = ms.dwTotalPhys;
memall->free_m = ms.dwAvailPhys;
memall->swap_t = ms.dwTotalPageFile;
memall->swap_f = ms.dwAvailPageFile;
#endif
return 1;
}
/* get system information */
TesError tesCreateSystemInfo(TesSystemInfo *info) {
OSVERSIONINFOA version;
char *versionStr = NULL, *procStr, *freeStr;
DWORD major, minor;
DWORD dwLen;
HKEY hkBaseCPU;
LONG lResult;
TesError
tesCreateSystemInfo(TesSystemInfo *info)
{
OSVERSIONINFOA version;
char *versionStr = NULL, *procStr, *freeStr;
DWORD major, minor;
DWORD dwLen;
HKEY hkBaseCPU;
LONG lResult;
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
info->numPhysicalProcessors = 0;
info->numLogicalProcessors = sysinfo.dwNumberOfProcessors; //atoi(getenv("NUMBER_OF_PROCESSORS"));
info->osName = NULL;
info->numPhysicalProcessors = 0;
info->numLogicalProcessors = sysinfo.dwNumberOfProcessors; //atoi(getenv("NUMBER_OF_PROCESSORS"));
info->osName = NULL;
version.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
if (GetVersionExA(&version) == 0)
return TES_FAIL;
version.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
if(GetVersionExA(&version) == 0) {
return TES_FAIL;
}
major = version.dwMajorVersion;
minor = version.dwMinorVersion;
switch(major) {
case 4:
if(minor == 0) {
versionStr = "Windows 95/NT4.0";
}
else if(minor == 10) {
versionStr = "Windows 98";
}
else if (minor == 90) {
versionStr = "Windows ME";
}
break;
case 5:
if(minor == 0) {
versionStr = "Windows 2000";
}
else if(minor == 1) {
versionStr = "Windows XP";
}
else if(minor == 2) {
versionStr = "Windows Server 2003";
}
break;
case 6:
if(minor == 0) {
versionStr = "Windows Vista";
}
else if(minor == 1) {
versionStr = "Windows 7";
}
break;
default:
break;
}
major = version.dwMajorVersion;
minor = version.dwMinorVersion;
switch (major) {
case 4:
if (minor == 0)
versionStr = "Windows 95/NT4.0";
else if (minor == 10)
versionStr = "Windows 98";
else if (minor == 90)
versionStr = "Windows ME";
break;
case 5:
if (minor == 0)
versionStr = "Windows 2000";
else if (minor == 1)
versionStr = "Windows XP";
else if (minor == 2)
versionStr = "Windows Server 2003";
break;
case 6:
if (minor == 0)
versionStr = "Windows Vista";
else if (minor == 1)
versionStr = "Windows 7";
break;
default:
break;
}
if(versionStr != NULL) {
size_t lengthCSD = strlen(version.szCSDVersion);
size_t lengthVer = strlen(versionStr);
if (versionStr != NULL) {
size_t lengthCSD = strlen(version.szCSDVersion);
size_t lengthVer = strlen(versionStr);
info->osName = TMALLOC(char, lengthVer + lengthCSD + 2);
memcpy(info->osName, versionStr, lengthVer);
memcpy(info->osName + lengthVer + 1, version.szCSDVersion, lengthCSD);
info->osName[lengthVer] = ' ';
info->osName[lengthVer + lengthCSD + 1] = '\0';
}
info->osName = TMALLOC(char, lengthVer + lengthCSD + 2);
memcpy(info->osName, versionStr, lengthVer);
memcpy(info->osName + lengthVer + 1, version.szCSDVersion, lengthCSD);
info->osName[lengthVer] = ' ';
info->osName[lengthVer + lengthCSD + 1] = '\0';
}
lResult = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
0,KEY_READ,&hkBaseCPU);
if(lResult != ERROR_SUCCESS) {
info->cpuModelName = NULL;
return TES_FAIL;
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
0, KEY_READ, &hkBaseCPU);
if (lResult != ERROR_SUCCESS) {
info->cpuModelName = NULL;
return TES_FAIL;
}
RegQueryValueExA(hkBaseCPU,"ProcessorNameString",0,0,NULL,&dwLen);
RegQueryValueExA(hkBaseCPU, "ProcessorNameString", 0, 0, NULL, &dwLen);
freeStr = procStr = TMALLOC(char, dwLen + 1);
RegQueryValueExA(hkBaseCPU,"ProcessorNameString",0,0,(LPBYTE)procStr,&dwLen);
RegQueryValueExA(hkBaseCPU, "ProcessorNameString", 0, 0, (LPBYTE)procStr, &dwLen);
procStr[dwLen] = '\0';
while (*procStr == ' ') procStr++;
while (*procStr == ' ')
procStr++;
info->cpuModelName = copy(procStr);
tfree(freeStr);
RegCloseKey(hkBaseCPU);
RegCloseKey(hkBaseCPU);
return TES_SUCCESS;
return TES_SUCCESS;
}
#else
/* no Windows OS, no proc info file system */
TesError tesCreateSystemInfo(TesSystemInfo *info) {
return 1;
TesError
tesCreateSystemInfo(TesSystemInfo *info)
{
return 1;
}
#endif

View File

@ -21,9 +21,10 @@ com_xgraph(wordlist *wl)
fname = wl->wl_word;
wl = wl->wl_next;
}
if (!wl) {
return;
}
if (!wl)
return;
if (cieq(fname, "temp") || cieq(fname, "tmp")) {
fname = smktemp("xg");
tempf = TRUE;

View File

@ -15,7 +15,7 @@
* uninterrupted or error-free. The end-user understands that the
* program was developed for research purposes and is advised not to
* rely exclusively on the program for any reason.
*
*
* IN NO EVENT SHALL THE AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT,
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
* LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
@ -97,7 +97,7 @@
#endif
/* Information about spice commands (struct comm). */
// char *co_comname; /* The name of the command. */
// void (*co_func) (wordlist *wl); /* The function that handles the command. */
// bool co_spiceonly; /* These can't be used from nutmeg. */
@ -121,7 +121,7 @@ struct comm spcp_coms[] = {
{ "define", com_define, FALSE, TRUE,
{ 010000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
NULL,
"[[func (args)] stuff] : Define a user-definable function." } ,
"[[func (args)] stuff] : Define a user-definable function." } ,
{ "set", com_set, FALSE, TRUE,
{ 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS,
arg_set,
@ -129,7 +129,7 @@ struct comm spcp_coms[] = {
/* support for altering options in interactive mode,
using either command 'option' or 'options'*/
using either command 'option' or 'options'*/
{ "option", com_option, TRUE, TRUE,
{ 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS,
arg_set,
@ -322,11 +322,11 @@ struct comm spcp_coms[] = {
{ "fft", com_fft, FALSE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 1, LOTS,
NULL,
"vector ... : Create a frequency domain plot with FFT." } ,
"vector ... : Create a frequency domain plot with FFT." } ,
{ "psd", com_psd, FALSE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 2, LOTS,
NULL,
"vector ... : Create a power spetral density plot with FFT." } ,
"vector ... : Create a power spetral density plot with FFT." } ,
{ "fourier", com_fourier, FALSE, TRUE,
{ 0, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
NULL,
@ -338,7 +338,7 @@ struct comm spcp_coms[] = {
{ "meas", com_meas, FALSE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 1, LOTS,
NULL,
"various ... : User defined signal evaluation." } ,
"various ... : User defined signal evaluation." } ,
{ "show", com_show, TRUE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS,
NULL,
@ -350,7 +350,7 @@ struct comm spcp_coms[] = {
{ "sysinfo", com_sysinfo, TRUE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS,
NULL,
"Print out system info summary." } ,
"Print out system info summary." } ,
{ "alter", com_alter, TRUE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS,
NULL,
@ -603,13 +603,13 @@ struct comm nutcp_coms[] = {
"[option] [option = value] ... : Set a variable." } ,
#ifdef EXPERIMENTAL_CODE
/* PN support for altering options in interactive mode */
/* PN support for altering options in interactive mode */
{ "option", com_option, TRUE, TRUE,
{ 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS,
arg_set,
"[option] [option = value] ... : Set a simulator option." } ,
#endif
#endif
{ "alias", com_alias, FALSE, FALSE,
{ 02, 04, 04, 04 }, E_ADVANCED, 0, LOTS,
NULL,
@ -753,11 +753,11 @@ struct comm nutcp_coms[] = {
{ "fft", com_fft, FALSE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 1, LOTS,
NULL,
"vector ... : Create a frequency domain plot with FFT." } ,
"vector ... : Create a frequency domain plot with FFT." } ,
{ "psd", com_psd, FALSE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 2, LOTS,
NULL,
"vector ... : Create a power spetral density plot with FFT." } ,
"vector ... : Create a power spetral density plot with FFT." } ,
{ "fourier", com_fourier, FALSE, TRUE,
{ 0, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS,
NULL,
@ -959,7 +959,7 @@ struct comm nutcp_coms[] = {
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
NULL,
" [ vec ... ] : Convert plot into one with linear scale." } ,
{ "devhelp",NULL, FALSE, FALSE,
{ "devhelp", NULL, FALSE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, 5 ,
NULL,
" devspecs : show device information." },
@ -971,4 +971,4 @@ struct comm nutcp_coms[] = {
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
NULL,
NULL }
} ;
};

View File

@ -49,19 +49,20 @@ int stackp = 0;
* 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
*/
* 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
*/
/* no redirection after the following commands (we may need more to add here!) */
static char *noredirect[] = { "stop", "define", NULL } ;
static char *noredirect[] = { "stop", "define", NULL };
static struct control *
findlabel(char *s, struct control *ct) {
findlabel(char *s, struct control *ct)
{
while (ct) {
if ((ct->co_type == CO_LABEL) && eq(s, ct->co_text->wl_word))
break;
@ -103,11 +104,14 @@ pwlist_echo(wordlist *wlist, char *name) /*CDHW used to perform function of se
return;
}
/*CDHW Remove control structure and free the memory its hogging CDHW*/
static void ctl_free(struct control *ctrl)
static void
ctl_free(struct control *ctrl)
{
if (!ctrl) return;
if (!ctrl)
return;
wl_free(ctrl->co_cond);
ctrl->co_cond = NULL;
tfree(ctrl->co_foreachvar);
@ -180,12 +184,11 @@ docommand(wordlist *wlist)
for (i = 0; noredirect[i]; i++)
if (eq(wlist->wl_word, noredirect[i]))
break;
if (!noredirect[i]) {
if (!noredirect[i])
if ((wlist = cp_redirect(wlist)) == NULL) {
cp_ioreset();
return;
}
}
/* Get rid of all the 8th bits now... */
cp_striplist(wlist);
@ -207,17 +210,17 @@ docommand(wordlist *wlist)
if (!command->co_comname) {
if (cp_dounixcom && cp_unixcom(wlist))
goto out;
fprintf(cp_err,"%s: no such command available in %s\n",
fprintf(cp_err, "%s: no such command available in %s\n",
s, cp_program);
goto out;
/* If it hasn't been implemented */
} else if (!command->co_func) {
fprintf(cp_err,"%s: command is not implemented\n", s);
fprintf(cp_err, "%s: command is not implemented\n", s);
goto out;
/* If it's there but spiceonly, and this is nutmeg, error. */
} else if (ft_nutmeg && command->co_spiceonly) {
fprintf(cp_err,"%s: command available only in spice\n", s);
fprintf(cp_err, "%s: command available only in spice\n", s);
goto out;
}
@ -237,11 +240,11 @@ docommand(wordlist *wlist)
}
}
out:
out:
wl_append(ee, wlist);
wl_append(wlist, nextc);
if(!ee)
if (!ee)
rwlist = wlist;
wlist = nextc;
@ -279,7 +282,7 @@ doblock(struct control *bl, int *num)
char *i;
int nn;
nn = *num + 1 ; /*CDHW this is a guess... CDHW*/
nn = *num + 1; /*CDHW this is a guess... CDHW*/
switch (bl->co_type) {
case CO_WHILE:
@ -298,9 +301,9 @@ doblock(struct control *bl, int *num)
break;
case BROKEN: /* Break. */
if (nn < 2)
if (nn < 2) {
return (NORMAL_STR);
else {
} else {
*num = nn - 1;
return (BROKEN_STR);
}
@ -334,9 +337,9 @@ doblock(struct control *bl, int *num)
break;
case BROKEN: /* Break. */
if (nn < 2)
if (nn < 2) {
return (NORMAL_STR);
else {
} else {
*num = nn - 1;
return (BROKEN_STR);
}
@ -369,7 +372,7 @@ doblock(struct control *bl, int *num)
bl->co_numtimes = -1: repeat forever
bl->co_timestodo: remaining repeats*/
while ((bl->co_timestodo > 0) ||
(bl->co_timestodo == -1)) {
(bl->co_timestodo == -1)) {
if (!bl->co_children) cp_periodic(); /*CDHW*/
if (bl->co_timestodo != -1) bl->co_timestodo--;
/* loop through all stements inside rpeat ... end */
@ -384,9 +387,9 @@ doblock(struct control *bl, int *num)
case BROKEN: /* Break. */
/* before leaving repeat loop set remaining timestodo to 0 */
bl->co_timestodo = 0;
if (nn < 2)
if (nn < 2) {
return (NORMAL_STR);
else {
} else {
*num = nn - 1;
return (BROKEN_STR);
}
@ -436,8 +439,7 @@ doblock(struct control *bl, int *num)
cn = ch->co_next;
i = doblock(ch, &nn);
if (*i > 2) {
cn = findlabel(i,
bl->co_elseblock);
cn = findlabel(i, bl->co_elseblock);
if (!cn)
return (i);
} else if (*i != NORMAL) {
@ -450,8 +452,8 @@ doblock(struct control *bl, int *num)
case CO_FOREACH:
for (wl = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(bl->co_text))));
wl;
wl = wl->wl_next) {
wl;
wl = wl->wl_next) {
cp_vset(bl->co_foreachvar, CP_STRING, wl->wl_word);
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
@ -462,9 +464,9 @@ doblock(struct control *bl, int *num)
break;
case BROKEN: /* Break. */
if (nn < 2)
if (nn < 2) {
return (NORMAL_STR);
else {
} else {
*num = nn - 1;
return (BROKEN_STR);
}
@ -535,8 +537,9 @@ doblock(struct control *bl, int *num)
return (NORMAL_STR);
}
/* Maxiumum number of cheverons used for the alternative prompt */
#define MAX_CHEVRONS 16
#define MAX_CHEVRONS 16
/* Get the alternate prompt.
Number of chevrons indicates stack depth.
@ -546,7 +549,7 @@ char *
get_alt_prompt(void)
{
int i = 0, j;
static char buf[MAX_CHEVRONS + 2]; /* includes terminating space & null */
static char buf[MAX_CHEVRONS + 2]; /* includes terminating space & null */
struct control *c;
/* if nothing on the command stack return NULL */
@ -562,11 +565,11 @@ get_alt_prompt(void)
/* Avoid overflow of buffer and
indicate when we've limited the chevrons by starting with a '+' */
if(i > MAX_CHEVRONS) {
if (i > MAX_CHEVRONS) {
i = MAX_CHEVRONS;
buf[0]='+';
buf[0] = '+';
} else {
buf[0]='>';
buf[0] = '>';
}
/* return one chevron per command stack depth */
@ -607,6 +610,7 @@ getcommand(char *string)
return (wlist);
}
/* va: TODO: free control structure(s) before overwriting (memory leakage) */
int
cp_evloop(char *string)
@ -631,15 +635,16 @@ cp_evloop(char *string)
if (cend[stackp]->co_parent && !string) {
cp_resetcontrol();
continue;
} else
} else {
return (0);
}
}
if ((wlist->wl_word == NULL) || (*wlist->wl_word == '\0')) {
/* User just typed return. */
wl_free(wlist); /* va, avoid memory leak */
if (string)
if (string) {
return (1);
else {
} else {
cp_event--;
continue;
}
@ -708,10 +713,11 @@ cp_evloop(char *string)
*dd = 0.0;
}
cend[stackp]->co_numtimes = (int) *dd;
} else
} else {
fprintf(cp_err,
"Error: bad repeat argument %s\n",
t->wl_next->wl_word); /* CDHW */
}
wl_free(t);
t = NULL; /* CDHW */
}
@ -733,9 +739,10 @@ cp_evloop(char *string)
cend[stackp]->co_foreachvar =
copy(wlist->wl_word);
wlist = wlist->wl_next;
} else
} else {
fprintf(stderr,
"Error: missing foreach variable.\n");
}
wlist = cp_doglob(wlist); /*CDHW Possible leak around here? */
cend[stackp]->co_text = wl_copy(wlist);
newblock;
@ -748,8 +755,9 @@ cp_evloop(char *string)
if (wlist->wl_next->wl_next)
fprintf(cp_err,
"Warning: ignored extra junk after label.\n");
} else
} 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
@ -761,8 +769,9 @@ cp_evloop(char *string)
if (wlist->wl_next->wl_next)
fprintf(cp_err,
"Warning: ignored extra junk after goto.\n");
} else
} else {
fprintf(stderr, "Error: missing label.\n");
}
} else if (eq(wlist->wl_word, "continue")) {
cend[stackp]->co_type = CO_CONTINUE;
if (wlist->wl_next) {
@ -772,8 +781,9 @@ cp_evloop(char *string)
fprintf(cp_err,
"Warning: ignored extra junk after continue %d.\n",
cend[stackp]->co_numtimes);
} else
} else {
cend[stackp]->co_numtimes = 1;
}
} else if (eq(wlist->wl_word, "break")) {
cend[stackp]->co_type = CO_BREAK;
if (wlist->wl_next) {
@ -783,8 +793,9 @@ cp_evloop(char *string)
fprintf(cp_err,
"Warning: ignored extra junk after break %d.\n",
cend[stackp]->co_numtimes);
} else
} else {
cend[stackp]->co_numtimes = 1;
}
} else if (eq(wlist->wl_word, "end")) {
/* Throw away this thing. */
if (!cend[stackp]->co_parent) {
@ -795,18 +806,18 @@ cp_evloop(char *string)
x = cend[stackp];
cend[stackp] = cend[stackp]->co_parent;
tfree(x);
x=NULL;
x = NULL;
} else {
x = cend[stackp];
cend[stackp] = cend[stackp]->co_parent;
cend[stackp]->co_children = NULL;
tfree(x);
x=NULL;
x = NULL;
}
} else if (eq(wlist->wl_word, "else")) {
if (!cend[stackp]->co_parent ||
(cend[stackp]->co_parent->co_type !=
CO_IF)) {
(cend[stackp]->co_parent->co_type !=
CO_IF)) {
fprintf(stderr, "Error: misplaced else.\n");
cend[stackp]->co_type = CO_UNFILLED;
} else {
@ -852,15 +863,16 @@ cp_evloop(char *string)
}
wl_free(wlist);
wlist = NULL;
if (string) {
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_free_control(void); /* needed by resetcontrol */
void cp_resetcontrol(void)
@ -883,9 +895,9 @@ cp_popcontrol(void)
{
if (cp_debug)
fprintf(cp_err, "pop: stackp: %d -> %d\n", stackp, stackp - 1);
if (stackp < 1)
if (stackp < 1) {
fprintf(cp_err, "cp_popcontrol: Internal Error: stack empty\n");
else {
} else {
/* va: free unused control structure */
ctl_free(control[stackp]);
stackp--;
@ -924,13 +936,14 @@ cp_toplevel(void)
/* va: This totally frees the control structures */
void cp_free_control(void)
void
cp_free_control(void)
{
int i;
for (i=stackp; i>=0; i--) ctl_free(control[i]);
for (i = stackp; i >= 0; i--)
ctl_free(control[i]);
control[0] = cend[0] = NULL;
stackp = 0;
}

View File

@ -268,7 +268,7 @@ ft_cpinit(void)
found = TRUE;
break;
#if defined (HAS_WINDOWS) || defined (__MINGW32__) || defined (_MSC_VER)
#if defined(HAS_WINDOWS) || defined(__MINGW32__) || defined(_MSC_VER)
/* search in local directory where ngspice.exe resides */
#if defined TCL_MODULE
} else if ((fp = fopen("./tclspinit", "r")) != NULL) {
@ -281,8 +281,9 @@ ft_cpinit(void)
found = TRUE;
break;
#endif
} else if (ft_controldb)
} else if (ft_controldb) {
fprintf(cp_err, "Note: can't open \"%s\".\n", buf);
}
}
if (!found)
@ -292,6 +293,7 @@ ft_cpinit(void)
tcap_init();
}
/* Decide whether a condition is TRUE or not. */
bool
@ -332,6 +334,7 @@ cp_istrue(wordlist *wl)
return (FALSE);
}
/* This gets called before every command is executed...
from fcns do_command() or do_block() in control.c */
@ -345,12 +348,14 @@ cp_periodic(void)
vec_gc(); /* remove vectors which do not have permanent flag set (vectors.c) */
}
void
cp_doquit(void)
{
com_quit(NULL);
}
/* This is how we deal with emulation of commands by scripts... If the script
* is found, then set the variables argc and argv and call the script. Note
* that this also allows us to type a filename to load a spice deck...

View File

@ -28,8 +28,8 @@ static void savetree(struct pnode *pn);
static void prdefs(char *name);
static void prtree(struct udfunc *ud);
static void prtree1(struct pnode *pn, FILE *fp);
static struct pnode * trcopy(struct pnode *tree, char *args, struct pnode *nn);
static struct pnode * ntharg(int num, struct pnode *args);
static struct pnode *trcopy(struct pnode *tree, char *args, struct pnode *nn);
static struct pnode *ntharg(int num, struct pnode *args);
static struct udfunc *udfuncs = NULL;
@ -174,7 +174,7 @@ savetree(struct pnode *pn)
pn->pn_value->v_realdata = TMALLOC(double, d->v_length);
bcopy(d->v_realdata,
pn->pn_value->v_realdata,
sizeof (double) * (size_t) d->v_length);
sizeof(double) * (size_t) d->v_length);
} else {
pn->pn_value->v_compdata = TMALLOC(ngcomplex_t, d->v_length);
bcopy(d->v_compdata,
@ -201,7 +201,7 @@ prdefs(char *name)
char *s;
if (name) {
s =strchr(name, '(' /* ) */);
s = strchr(name, '(' /* ) */);
if (s)
*s = '\0';
}
@ -289,9 +289,9 @@ ft_substdef(const char *name, struct pnode *args)
for (udf = udfuncs; udf; udf = udf->ud_next)
if (eq(name, udf->ud_name)) {
if (arity == udf->ud_arity)
if (arity == udf->ud_arity) {
break;
else {
} else {
found = TRUE;
rarity = udf->ud_arity;
}
@ -349,12 +349,16 @@ trcopy(struct pnode *tree, char *args, struct pnode *nn)
while (*s++) /* Get past the last '\0'. */
;
}
if (*s)
return (ntharg(i, nn));
else
return (tree);
} else {
return (tree);
}
} else if (tree->pn_func) {
@ -412,7 +416,7 @@ ntharg(int num, struct pnode *args)
ptry = args;
if (num > 1) {
if (num > 1)
while (--num > 0) {
if (ptry && ptry->pn_op &&
(ptry->pn_op->op_num != PT_OP_COMMA)) {
@ -423,7 +427,6 @@ ntharg(int num, struct pnode *args)
}
ptry = ptry->pn_right;
}
}
if (ptry && ptry->pn_op && (ptry->pn_op->op_num == PT_OP_COMMA))
ptry = ptry->pn_left;

File diff suppressed because it is too large Load Diff

View File

@ -24,46 +24,52 @@ nameeq(char *n1, char *n2)
{
char buf1[BSIZE_SP], buf2[BSIZE_SP];
char *tmp;
if (eq(n1, n2))
return (TRUE);
/* n1 or n2 is in the form i(...) or I(...)
/* n1 or n2 is in the form i(...) or I(...)
* This happens in the saved rawfile
*/
if(ciprefix("i(",n1)) {
if (ciprefix("i(", n1)) {
tmp = n1;
while ( *tmp != '(' ) tmp++;
while (*tmp != '(')
tmp++;
tmp++;
(void) strcpy(buf1, tmp);
(void) strcpy(buf1, tmp);
tmp = buf1;
while ( *tmp != ')' ) tmp++;
*tmp ='\0';
while (*tmp != ')')
tmp++;
*tmp = '\0';
(void) strcat(buf1, "#branch");
} else if (isdigit(*n1))
(void) sprintf(buf1, "v(%s)", n1);
else
(void) strcpy(buf1, n1);
} else if (isdigit(*n1)) {
(void) sprintf(buf1, "v(%s)", n1);
} else {
(void) strcpy(buf1, n1);
}
if(ciprefix("i(",n2)) {
if (ciprefix("i(", n2)) {
tmp = n2;
while ( *tmp != '(' ) tmp++;
while (*tmp != '(')
tmp++;
tmp++;
(void) strcpy(buf2, tmp);
(void) strcpy(buf2, tmp);
tmp = buf2;
while ( *tmp != ')' ) tmp++;
*tmp ='\0';
while (*tmp != ')')
tmp++;
*tmp = '\0';
(void) strcat(buf2, "#branch");
} else if (isdigit(*n2))
(void) sprintf(buf2, "v(%s)", n2);
else
(void) strcpy(buf2, n2);
} else if (isdigit(*n2)) {
(void) sprintf(buf2, "v(%s)", n2);
} else {
(void) strcpy(buf2, n2);
}
return (cieq(buf1, buf2) ? TRUE : FALSE);
}
void
com_diff(wordlist *wl)
{
@ -74,7 +80,7 @@ com_diff(wordlist *wl)
ngcomplex_t c1, c2, c3;
int i, j;
wordlist *tw;
char numbuf[BSIZE_SP],numbuf2[BSIZE_SP] ,numbuf3[BSIZE_SP], numbuf4[BSIZE_SP]; /* For printnum */
char numbuf[BSIZE_SP], numbuf2[BSIZE_SP], numbuf3[BSIZE_SP], numbuf4[BSIZE_SP]; /* For printnum */
if (!cp_getvar("diff_vntol", CP_REAL, &vntol))
vntol = 1.0e-6;
@ -85,12 +91,11 @@ com_diff(wordlist *wl)
/* Let's try to be clever about defaults. This code is ugly. */
if (!wl || !wl->wl_next) {
if (plot_list && plot_list->pl_next &&
!plot_list->pl_next->pl_next) {
if (plot_list && plot_list->pl_next && !plot_list->pl_next->pl_next) {
p1 = plot_list;
p2 = plot_list->pl_next;
if (wl && !eq(wl->wl_word, p1->pl_typename) &&
!eq(wl->wl_word, p2->pl_typename)) {
!eq(wl->wl_word, p2->pl_typename)) {
fprintf(cp_err, "Error: no such plot \"%s\"\n",
wl->wl_word);
return;
@ -109,8 +114,7 @@ com_diff(wordlist *wl)
if (eq(wl->wl_word, p1->pl_typename))
break;
if (!p1) {
fprintf(cp_err, "Error: no such plot %s\n",
wl->wl_word);
fprintf(cp_err, "Error: no such plot %s\n", wl->wl_word);
return;
}
wl = wl->wl_next;
@ -121,8 +125,7 @@ com_diff(wordlist *wl)
if (eq(wl->wl_word, p2->pl_typename))
break;
if (!p2) {
fprintf(cp_err, "Error: no such plot %s\n",
wl->wl_word);
fprintf(cp_err, "Error: no such plot %s\n", wl->wl_word);
return;
}
wl = wl->wl_next;
@ -132,13 +135,13 @@ com_diff(wordlist *wl)
* same type, etc.
*/
if (!eq(p1->pl_name, p2->pl_name))
fprintf(cp_err,
"Warning: plots %s and %s seem to be of different types\n",
p1->pl_typename, p2->pl_typename);
fprintf(cp_err,
"Warning: plots %s and %s seem to be of different types\n",
p1->pl_typename, p2->pl_typename);
if (!eq(p1->pl_title, p2->pl_title))
fprintf(cp_err,
"Warning: plots %s and %s seem to be from different circuits\n",
p1->pl_typename, p2->pl_typename);
fprintf(cp_err,
"Warning: plots %s and %s seem to be from different circuits\n",
p1->pl_typename, p2->pl_typename);
/* This may not be the best way to do this */
for (v1 = p1->pl_dvecs; v1; v1 = v1->v_next)
@ -146,32 +149,31 @@ com_diff(wordlist *wl)
for (v2 = p2->pl_dvecs; v2; v2 = v2->v_next)
v2->v_link2 = NULL;
for (v1 = p1->pl_dvecs; v1; v1 = v1->v_next) {
for (v1 = p1->pl_dvecs; v1; v1 = v1->v_next)
for (v2 = p2->pl_dvecs; v2; v2 = v2->v_next)
if (!v2->v_link2 && nameeq(v1->v_name, v2->v_name) &&
((v1->v_flags & (VF_REAL | VF_COMPLEX)) ==
(v2->v_flags & (VF_REAL | VF_COMPLEX))) &&
(v1->v_type == v2->v_type)) {
(v2->v_flags & (VF_REAL | VF_COMPLEX))) &&
(v1->v_type == v2->v_type))
{
v1->v_link2 = v2;
v2->v_link2 = v1;
break;
}
}
for (v1 = p1->pl_dvecs; v1; v1 = v1->v_next)
if (!v1->v_link2)
fprintf(cp_err,
">>> %s vector %s in %s not in %s, or of wrong type\n",
fprintf(cp_err,
">>> %s vector %s in %s not in %s, or of wrong type\n",
isreal(v1) ? "real" : "complex",
v1->v_name, p1->pl_typename,
p2->pl_typename);
v1->v_name, p1->pl_typename, p2->pl_typename);
for (v2 = p2->pl_dvecs; v2; v2 = v2->v_next)
if (!v2->v_link2)
fprintf(cp_err,
">>> %s vector %s in %s not in %s, or of wrong type\n",
fprintf(cp_err,
">>> %s vector %s in %s not in %s, or of wrong type\n",
isreal(v2) ? "real" : "complex",
v2->v_name, p2->pl_typename,
p1->pl_typename);
v2->v_name, p2->pl_typename, p1->pl_typename);
/* Throw out the ones that aren't in the arg list */
if (wl && !eq(wl->wl_word, "all")) { /* Just in case */
@ -192,7 +194,7 @@ com_diff(wordlist *wl)
v2->v_link2 = NULL;
}
}
/* Now we have all the vectors linked to their twins. Travel
* down each one and print values that differ enough.
*/
@ -207,35 +209,31 @@ com_diff(wordlist *wl)
j = MAX(v1->v_length, v2->v_length);
for (i = 0; i < j; i++) {
if (v1->v_length <= i) {
fprintf(cp_out,
">>> %s is %d long in %s and %d long in %s\n",
fprintf(cp_out,
">>> %s is %d long in %s and %d long in %s\n",
v1->v_name, v1->v_length,
p1->pl_typename, v2->v_length,
p2->pl_typename);
p1->pl_typename, v2->v_length, p2->pl_typename);
break;
} else if (v2->v_length <= i) {
fprintf(cp_out,
">>> %s is %d long in %s and %d long in %s\n",
fprintf(cp_out,
">>> %s is %d long in %s and %d long in %s\n",
v2->v_name, v2->v_length,
p2->pl_typename, v1->v_length,
p1->pl_typename);
p2->pl_typename, v1->v_length, p1->pl_typename);
break;
} else {
if (isreal(v1)) {
d1 = v1->v_realdata[i];
d2 = v2->v_realdata[i];
if (MAX(fabs(d1), fabs(d2)) * reltol +
tol < fabs(d1 - d2)) {
printnum(numbuf, d1);
tol < fabs(d1 - d2)) {
printnum(numbuf, d1);
fprintf(cp_out,
"%s.%s[%d] = %-15s ",
p1->pl_typename, v1->v_name, i,
numbuf);
"%s.%s[%d] = %-15s ",
p1->pl_typename, v1->v_name, i, numbuf);
printnum(numbuf, d2);
fprintf(cp_out,
"%s.%s[%d] = %s\n",
p2->pl_typename, v2->v_name, i,
numbuf);
"%s.%s[%d] = %s\n",
p2->pl_typename, v2->v_name, i, numbuf);
}
} else {
c1 = v1->v_compdata[i];
@ -246,22 +244,21 @@ com_diff(wordlist *wl)
cm1 = cmag(c1);
cm2 = cmag(c2);
cmax = MAX(cm1, cm2);
if (cmax * reltol +
tol < cmag(c3)) {
printnum(numbuf, realpart(c1));
if (cmax * reltol + tol < cmag(c3)) {
printnum(numbuf, realpart(c1));
printnum(numbuf2, imagpart(c1));
printnum(numbuf3, realpart(c2));
printnum(numbuf4, imagpart(c2));
fprintf(cp_out,
"%s.%s[%d] = %-10s, %-10s %s.%s[%d] = %-10s, %s\n",
p1->pl_typename, v1->v_name, i,
numbuf,
numbuf2,
p2->pl_typename, v2->v_name, i,
numbuf3,
numbuf4);
"%s.%s[%d] = %-10s, %-10s %s.%s[%d] = %-10s, %s\n",
p1->pl_typename, v1->v_name, i,
numbuf,
numbuf2,
p2->pl_typename, v2->v_name, i,
numbuf3,
numbuf4);
}
}
}

View File

@ -8,7 +8,7 @@ Author: 1992 David A. Gates, U. C. Berkeley CAD Group
*/
#include "ngspice/ngspice.h"
#include "ngspice/dvec.h" /* For MAXDIMS */
#include "ngspice/dvec.h" /* For MAXDIMS */
#include "dimens.h"
@ -18,42 +18,45 @@ Author: 1992 David A. Gates, U. C. Berkeley CAD Group
void
dimstring(int *data, int length, char *retstring)
{
int i;
int i;
char buf[BSIZE_SP];
if (!data || length < 1)
retstring = "";
retstring = "";
buf[0] = '\0';
for (i=0; i < length; i++) {
sprintf(buf + strlen(buf), "%d%s", data[i],
(i < length - 1) ? "," : "");
}
for (i = 0; i < length; i++)
sprintf(buf + strlen(buf), "%d%s", data[i], (i < length - 1) ? "," : "");
/* XXX Should I return a copy instead? */
/* qui ci devo fare una copia */
strcpy(retstring, buf);
}
/*
* Create a string of the form "[12][1][10]".
*/
void
indexstring(int *data, int length, char *retstring)
{
int i;
int i;
char buf[BSIZE_SP];
if (!data || length < 1)
retstring = "";
retstring = "";
buf[0] = '\0';
for (i=0; i < length; i++) {
sprintf(buf + strlen(buf), "[%d]", data[i]);
}
for (i = 0; i < length; i++)
sprintf(buf + strlen(buf), "[%d]", data[i]);
strcpy(retstring, buf);
}
/*
* Add one to anstrchr into an array with sizes in dims.
* Return 1 when all counters overflow at once.
@ -64,21 +67,23 @@ incindex(int *counts, int numcounts, int *dims, int numdims)
int i, start;
if (!counts || numcounts < 1 || !dims || numdims < 1)
return 0;
return 0;
start = numcounts - 1;
for (i = start; i >= 0; i--) {
if (++counts[i] < dims[i])
break; /* This counter is not maxed out. */
else
counts[i] = 0;
}
for (i = start; i >= 0; i--)
if (++counts[i] < dims[i])
break; /* This counter is not maxed out. */
else
counts[i] = 0;
if (i == 0)
return(1);
return (1);
else
return(0);
return (0);
}
/*
* Count number of empty dimensions in an array.
*/
@ -87,13 +92,14 @@ emptydims(int *data, int length)
{
int i, numempty = 0;
for (i=0; i < length; i++) {
if (data[i] == 0)
numempty++;
}
return(numempty);
for (i = 0; i < length; i++)
if (data[i] == 0)
numempty++;
return (numempty);
}
/*
* Read a string of one of the following forms into a dimensions array:
* [12][1][10]
@ -106,7 +112,7 @@ emptydims(int *data, int length)
* the beginning [ and end ] are ignored if they exist. The only valid
* characters in the string are brackets, commas, spaces, and digits.
* If any dimension is blank, its entry in the array is set to 0.
*
*
* Return 0 on success, 1 on failure.
*/
int
@ -119,86 +125,90 @@ atodims(char *p, int *data, int *outlength)
char sep = '\0';
if (!data || !outlength)
return 1;
return 1;
if (!p) {
*outlength = 0;
return 0;
*outlength = 0;
return 0;
}
while (*p && isspace(*p))
p++;
p++;
if (*p == '[') {
p++;
while (*p && isspace(*p))
p++;
needbracket = 1;
p++;
while (*p && isspace(*p))
p++;
needbracket = 1;
}
while (*p && state != 3) {
switch (state) {
case 0: /* p just at or before a number */
if (length >= MAXDIMS) {
if (length == MAXDIMS)
printf("Error: maximum of %d dimensions allowed.\n",
MAXDIMS);
length += 1;
} else if (!isdigit(*p)) {
data[length++] = 0; /* This position was empty. */
} else {
data[length++] = atoi(p);
while (isdigit(*p))
p++;
}
state = 1;
break;
switch (state) {
case 0: /* p just at or before a number */
if (length >= MAXDIMS) {
if (length == MAXDIMS)
printf("Error: maximum of %d dimensions allowed.\n",
MAXDIMS);
length += 1;
} else if (!isdigit(*p)) {
data[length++] = 0; /* This position was empty. */
} else {
data[length++] = atoi(p);
while (isdigit(*p))
p++;
}
state = 1;
break;
case 1: /* p after a number, looking for ',' or ']' */
if (sep == '\0') {
sep = *p;
}
if (*p == ']' && *p == sep) {
p++;
state = 2;
} else if (*p == ',' && *p == sep) {
p++;
state = 0;
} else /* Funny character following a # */
break;
break;
case 1: /* p after a number, looking for ',' or ']' */
if (sep == '\0')
sep = *p;
case 2: /* p after a ']', either at the end or looking for '[' */
if (*p == '[') {
p++;
state = 0;
} else {
state = 3;
}
break;
}
if (*p == ']' && *p == sep) {
p++;
state = 2;
} else if (*p == ',' && *p == sep) {
p++;
state = 0;
} else { /* Funny character following a # */
break;
}
break;
while (*p && isspace(*p))
p++;
case 2: /* p after a ']', either at the end or looking for '[' */
if (*p == '[') {
p++;
state = 0;
} else {
state = 3;
}
break;
}
while (*p && isspace(*p))
p++;
}
*outlength = length;
if (length > MAXDIMS) {
return(1);
}
if (length > MAXDIMS)
return (1);
if (state == 3) { /* We finished with a closing bracket */
err = !needbracket;
err = !needbracket;
} else if (*p) { /* We finished by hitting a bad character after a # */
err = 1;
} else { /* We finished by exhausting the string */
err = needbracket;
err = 1;
} else { /* We finished by exhausting the string */
err = needbracket;
}
if (err) {
*outlength = 0;
}
return(err);
if (err)
*outlength = 0;
return (err);
}
/*
* Skip to the first character that cannot be part of a dimension string.
*/
@ -206,11 +216,10 @@ char *
skipdims(char *p)
{
if (!p)
return NULL;
return NULL;
while(*p && (*p == '[' || *p == ']' || *p == ','
|| isspace(*p) || isdigit(*p)))
p++;
while (*p && (*p == '[' || *p == ']' || *p == ',' || isspace(*p) || isdigit(*p)))
p++;
return(p);
return (p);
}

View File

@ -11,8 +11,6 @@ void indexstring(int *data, int length, char *retstring);
int incindex(int *counts, int numcounts, int *dims, int numdims);
int emptydims(int *data, int length);
int atodims(char *p, int *data, int *outlength);
char * skipdims(char *p);
char *skipdims(char *p);
#endif

View File

@ -139,14 +139,14 @@ FindDev(char *name)
{
size_t i;
for (i=0; i < NUMELEMS(device); i++)
for (i = 0; i < NUMELEMS(device); i++)
if (strcmp(name, device[i].name) == 0)
return(device + i);
return (device + i);
sprintf(ErrorMessage, "Can't find device %s.", name);
internalerror(ErrorMessage);
return(device + 0);
return (device + 0);
}
@ -190,15 +190,15 @@ DevInit(void)
#if !defined(HAS_WINDOWS) && !defined(TCL_MODULE) && (defined(_MSC_VER) || defined(__MINGW32__))
/* console application under MS Windows */
fprintf
( cp_err,
"Warning: no graphics interface!\n"
" You may use command 'gnuplot'\n"
" if GnuPlot is installed.\n" );
(cp_err,
"Warning: no graphics interface!\n"
" You may use command 'gnuplot'\n"
" if GnuPlot is installed.\n");
#elif !defined(X_DISPLAY_MISSING)
externalerror
( "no graphics interface;\n"
" please check if X-server is running,\n"
" or ngspice is compiled properly (see INSTALL)" );
("no graphics interface;\n"
" please check if X-server is running,\n"
" or ngspice is compiled properly (see INSTALL)");
#endif
dispdev = FindDev("error");
@ -218,61 +218,71 @@ NewViewport(GRAPH *pgraph)
}
void DevClose(void)
void
DevClose(void)
{
dispdev->Close();
}
void DevClear(void)
void
DevClear(void)
{
dispdev->Clear();
}
void DevDrawLine(int x1, int y1, int x2, int y2)
void
DevDrawLine(int x1, int y1, int x2, int y2)
{
dispdev->DrawLine (x1, y1, x2, y2);
}
void DevDrawArc(int x0, int y0, int radius, double theta, double delta_theta)
void
DevDrawArc(int x0, int y0, int radius, double theta, double delta_theta)
{
dispdev->DrawArc (x0, y0, radius, theta, delta_theta);
}
void DevDrawText(char *text, int x, int y)
void
DevDrawText(char *text, int x, int y)
{
dispdev->DrawText (text, x, y);
}
void DefineColor(int colorid, double red, double green, double blue)
void
DefineColor(int colorid, double red, double green, double blue)
{
dispdev->DefineColor (colorid, red, green, blue);
}
void DefineLinestyle(int linestyleid, int mask)
void
DefineLinestyle(int linestyleid, int mask)
{
dispdev->DefineLinestyle (linestyleid, mask);
}
void SetLinestyle(int linestyleid)
void
SetLinestyle(int linestyleid)
{
dispdev->SetLinestyle (linestyleid);
}
void SetColor(int colorid)
void
SetColor(int colorid)
{
dispdev->SetColor (colorid);
}
void DevUpdate(void)
void
DevUpdate(void)
{
if (dispdev)
dispdev->Update();
@ -322,13 +332,15 @@ gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny)
}
void DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny)
void
DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny)
{
dispdev->DatatoScreen (graph, x, y, screenx, screeny);
}
void Input(REQUEST *request, RESPONSE *response)
void
Input(REQUEST *request, RESPONSE *response)
{
dispdev->Input (request, response);
}
@ -349,28 +361,31 @@ gen_Input(REQUEST *request, RESPONSE *response)
break;
}
return(0);
return (0);
}
/* no operation, do nothing */
static int nop(void)
static int
nop(void)
{
return(1); /* so NewViewport will fail */
return (1); /* so NewViewport will fail */
}
static int nodev(void)
static int
nodev(void)
{
sprintf(ErrorMessage,
"This operation is not defined for display type %s.",
dispdev->name);
internalerror(ErrorMessage);
return(1);
return (1);
}
void SaveText(GRAPH *graph, char *text, int x, int y)
void
SaveText(GRAPH *graph, char *text, int x, int y)
{
struct _keyed *keyed = TMALLOC(struct _keyed, 1);
@ -393,7 +408,8 @@ void SaveText(GRAPH *graph, char *text, int x, int y)
/* if given name of a hardcopy device, finds it and switches devices
if given NULL, switches back */
int DevSwitch(char *devname)
int
DevSwitch(char *devname)
{
static DISPDEVICE *lastdev = NULL;
@ -426,5 +442,5 @@ int DevSwitch(char *devname)
}
return(0);
return (0);
}

View File

@ -30,7 +30,7 @@ Modified: 2000 AlansFixes
static void fixdotplot(wordlist *wl);
static void fixdotprint(wordlist *wl);
static char * fixem(char *string);
static char *fixem(char *string);
void ft_savemeasure(void);
@ -39,14 +39,14 @@ setcplot(char *name)
{
struct plot *pl;
for (pl = plot_list; pl; pl = pl->pl_next) {
if (ciprefix(name, pl->pl_typename)) {
for (pl = plot_list; pl; pl = pl->pl_next)
if (ciprefix(name, pl->pl_typename))
return pl;
}
}
return NULL;
}
/* All lines with .width, .plot, .print, .save, .op, .meas, .tf
have been assembled into a wordlist (wl_first) in inp.c:inp_spsource(),
and then stored to ci_commands in inp.c:inp_dodeck().
@ -62,119 +62,120 @@ ft_dotsaves(void)
if (!ft_curckt) /* Shouldn't happen. */
return;
for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next) {
for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next)
if (ciprefix(".save", iline->wl_word)) {
s = iline->wl_word;
(void) gettok(&s);
wl = wl_append(wl, gettoks(s));
}
}
com_save(wl);
return;
}
/* Go through the dot lines given and make up a big "save" command with
* all the node names mentioned. Note that if a node is requested for
* one analysis, it is saved for all of them.
*/
static char *plot_opts[ ] = {
"linear",
"xlog",
"ylog",
"loglog"
};
"linear",
"xlog",
"ylog",
"loglog"
};
int
ft_savedotargs(void)
{
wordlist *w, *wl = NULL, *iline, **prev_wl, *w_next;
char *name;
char *s;
int some = 0;
static wordlist all = { "all", NULL, NULL };
int isaplot;
int i;
int status;
wordlist *w, *wl = NULL, *iline, **prev_wl, *w_next;
char *name;
char *s;
int some = 0;
static wordlist all = { "all", NULL, NULL };
int isaplot;
int i;
int status;
if (!ft_curckt) /* Shouldn't happen. */
return 0;
if (!ft_curckt) /* Shouldn't happen. */
return 0;
for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next) {
s = iline->wl_word;
if (ciprefix(".plot", s))
isaplot = 1;
else
isaplot = 0;
for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next) {
s = iline->wl_word;
if (ciprefix(".plot", s))
isaplot = 1;
else
isaplot = 0;
if (isaplot || ciprefix(".print", s)) {
(void) gettok(&s);
name = gettok(&s);
if (isaplot || ciprefix(".print", s)) {
(void) gettok(&s);
name = gettok(&s);
if ((w = gettoks(s)) == NULL) {
fprintf(cp_err, "Warning: no nodes given: %s\n", iline->wl_word);
} else {
if (isaplot) {
prev_wl = &w;
for (wl = w; wl; wl = w_next) {
w_next = wl->wl_next;
for (i = 0; (size_t) i < NUMELEMS(plot_opts); i++) {
if (!strcmp(wl->wl_word, plot_opts[i])) {
/* skip it */
*prev_wl = w_next;
tfree(wl);
break;
}
}
if (i == NUMELEMS(plot_opts))
prev_wl = &wl->wl_next;
}
if ((w = gettoks(s)) == NULL) {
fprintf(cp_err, "Warning: no nodes given: %s\n", iline->wl_word);
} else {
if (isaplot) {
prev_wl = &w;
for (wl = w; wl; wl = w_next) {
w_next = wl->wl_next;
for (i = 0; (size_t) i < NUMELEMS(plot_opts); i++) {
if (!strcmp(wl->wl_word, plot_opts[i])) {
/* skip it */
*prev_wl = w_next;
tfree(wl);
break;
}
}
if (i == NUMELEMS(plot_opts))
prev_wl = &wl->wl_next;
}
}
some = 1;
com_save2(w, name);
}
} else if (ciprefix(".four", s)) {
(void) gettok(&s);
(void) gettok(&s);
if ((w = gettoks(s)) == NULL) {
fprintf(cp_err, "Warning: no nodes given: %s\n", iline->wl_word);
} else {
some = 1;
com_save2(w, "TRAN"); /* A hack */
}
} else if (ciprefix(".meas", s)) {
status = measure_extract_variables(s);
if (!(status)) {
some = 1;
}
} else if (ciprefix(".op", s)) {
some = 1;
com_save2(w, name);
}
} else if (ciprefix(".four", s)) {
(void) gettok(&s);
(void) gettok(&s);
if ((w = gettoks(s)) == NULL)
fprintf(cp_err, "Warning: no nodes given: %s\n", iline->wl_word);
else {
com_save2(&all, "OP");
} else if (ciprefix(".tf", s)) {
some = 1;
com_save2(w, "TRAN"); /* A hack */
}
} else if (ciprefix(".meas", s)) {
status = measure_extract_variables( s ) ;
if(!(status)){
some = 1;
}
} else if (ciprefix(".op", s)) {
some = 1;
com_save2(&all, "OP");
} else if (ciprefix(".tf", s)) {
some = 1;
com_save2(&all, "TF");
}
}
return some;
com_save2(&all, "TF");
}
}
return some;
}
void
ft_savemeasure(void)
{
char *s;
wordlist *iline;
char *s;
wordlist *iline;
if (!ft_curckt) /* Shouldn't happen. */
return ;
if (!ft_curckt) /* Shouldn't happen. */
return;
for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next) {
s = iline->wl_word;
if (ciprefix(".measure", s)) {
(void) measure_extract_variables( s ) ;
}
}
return ;
for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next) {
s = iline->wl_word;
if (ciprefix(".measure", s)) {
(void) measure_extract_variables(s);
}
}
return;
}
/* Execute the .whatever lines found in the deck, after we are done running.
@ -189,7 +190,7 @@ ft_cktcoms(bool terse)
wordlist *coms, *command, all;
char *plottype, *s;
struct dvec *v;
static wordlist twl = { "col", NULL, NULL } ;
static wordlist twl = { "col", NULL, NULL };
struct plot *pl;
int i, found;
char numbuf[BSIZE_SP]; /* For printnum*/
@ -198,7 +199,7 @@ ft_cktcoms(bool terse)
all.wl_word = "all";
if (!ft_curckt)
return 1;
return 1;
plot_cur = setcplot("op");
if (!ft_curckt->ci_commands && !plot_cur)
@ -208,64 +209,62 @@ ft_cktcoms(bool terse)
/* Listing */
if (ft_listprint) {
if (terse)
fprintf(cp_err, ".options: no listing, rawfile was generated.\n");
else
inp_list(cp_out, ft_curckt->ci_deck, ft_curckt->ci_options,
LS_DECK);
if (terse)
fprintf(cp_err, ".options: no listing, rawfile was generated.\n");
else
inp_list(cp_out, ft_curckt->ci_deck, ft_curckt->ci_options, LS_DECK);
}
/* If there was a .op line, then we have to do the .op output. */
plot_cur = setcplot("op");
if (plot_cur != NULL) {
assert(plot_cur->pl_dvecs != NULL);
if (plot_cur->pl_dvecs->v_realdata!=NULL) {
if (terse) {
fprintf(cp_out, "OP information in rawfile.\n");
} else {
fprintf(cp_out, "\t%-30s%15s\n", "Node", "Voltage");
fprintf(cp_out, "\t%-30s%15s\n", "----", "-------");
fprintf(cp_out, "\t----\t-------\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next) {
if (!isreal(v)) {
fprintf(cp_err,
"Internal error: op vector %s not real\n",
v->v_name);
continue;
}
if ((v->v_type == SV_VOLTAGE) && (*(v->v_name)!='@')) {
printnum(numbuf, v->v_realdata[0]);
fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf);
}
}
fprintf(cp_out, "\n\tSource\tCurrent\n");
fprintf(cp_out, "\t------\t-------\n\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next)
if (v->v_type == SV_CURRENT) {
printnum(numbuf, v->v_realdata[0]);
fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf);
}
fprintf(cp_out, "\n");
assert(plot_cur->pl_dvecs != NULL);
if (plot_cur->pl_dvecs->v_realdata != NULL) {
if (terse) {
fprintf(cp_out, "OP information in rawfile.\n");
} else {
fprintf(cp_out, "\t%-30s%15s\n", "Node", "Voltage");
fprintf(cp_out, "\t%-30s%15s\n", "----", "-------");
fprintf(cp_out, "\t----\t-------\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next) {
if (!isreal(v)) {
fprintf(cp_err,
"Internal error: op vector %s not real\n",
v->v_name);
continue;
}
if ((v->v_type == SV_VOLTAGE) && (*(v->v_name) != '@')) {
printnum(numbuf, v->v_realdata[0]);
fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf);
}
}
fprintf(cp_out, "\n\tSource\tCurrent\n");
fprintf(cp_out, "\t------\t-------\n\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next)
if (v->v_type == SV_CURRENT) {
printnum(numbuf, v->v_realdata[0]);
fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf);
}
fprintf(cp_out, "\n");
if (!ft_nomod)
com_showmod(&all);
com_show(&all);
}
}
if (!ft_nomod)
com_showmod(&all);
com_show(&all);
}
}
}
for (pl = plot_list; pl; pl = pl->pl_next) {
for (pl = plot_list; pl; pl = pl->pl_next)
if (ciprefix("tf", pl->pl_typename)) {
if (terse) {
fprintf(cp_out, "TF information in rawfile.\n");
break;
}
if (terse) {
fprintf(cp_out, "TF information in rawfile.\n");
break;
}
plot_cur = pl;
fprintf(cp_out, "Transfer function information:\n");
com_print(&all);
fprintf(cp_out, "\n");
}
}
fprintf(cp_out, "Transfer function information:\n");
com_print(&all);
fprintf(cp_out, "\n");
}
/* Now all the '.' lines */
while (coms) {
@ -273,11 +272,11 @@ ft_cktcoms(bool terse)
if (!command)
goto bad;
if (eq(command->wl_word, ".width")) {
do {
do
command = command->wl_next;
} while (command && !ciprefix("out", command->wl_word));
while (command && !ciprefix("out", command->wl_word));
if (command) {
s =strchr(command->wl_word, '=');
s = strchr(command->wl_word, '=');
if (!s || !s[1]) {
fprintf(cp_err, "Error: bad line %s\n", coms->wl_word);
coms = coms->wl_next;
@ -288,8 +287,8 @@ ft_cktcoms(bool terse)
}
} else if (eq(command->wl_word, ".print")) {
if (terse) {
fprintf(cp_out,
".print line ignored since rawfile was produced.\n");
fprintf(cp_out,
".print line ignored since rawfile was produced.\n");
} else {
command = command->wl_next;
if (!command) {
@ -301,23 +300,22 @@ ft_cktcoms(bool terse)
command = command->wl_next;
fixdotprint(command);
twl.wl_next = command;
found = 0;
for (pl = plot_list; pl; pl = pl->pl_next) {
if (ciprefix(plottype, pl->pl_typename)) {
plot_cur = pl;
com_print(&twl);
fprintf(cp_out, "\n");
found = 1;
}
}
found = 0;
for (pl = plot_list; pl; pl = pl->pl_next)
if (ciprefix(plottype, pl->pl_typename)) {
plot_cur = pl;
com_print(&twl);
fprintf(cp_out, "\n");
found = 1;
}
if (!found)
fprintf(cp_err, "Error: .print: no %s analysis found.\n",
plottype);
plottype);
}
} else if (eq(command->wl_word, ".plot")) {
if (terse) {
fprintf(cp_out,
".plot line ignored since rawfile was produced.\n");
fprintf(cp_out,
".plot line ignored since rawfile was produced.\n");
} else {
command = command->wl_next;
if (!command) {
@ -329,23 +327,22 @@ ft_cktcoms(bool terse)
plottype = command->wl_word;
command = command->wl_next;
fixdotplot(command);
found = 0;
for (pl = plot_list; pl; pl = pl->pl_next) {
if (ciprefix(plottype, pl->pl_typename)) {
plot_cur = pl;
com_asciiplot(command);
fprintf(cp_out, "\n");
found = 1;
}
}
found = 0;
for (pl = plot_list; pl; pl = pl->pl_next)
if (ciprefix(plottype, pl->pl_typename)) {
plot_cur = pl;
com_asciiplot(command);
fprintf(cp_out, "\n");
found = 1;
}
if (!found)
fprintf(cp_err, "Error: .plot: no %s analysis found.\n",
plottype);
plottype);
}
} else if (ciprefix(".four", command->wl_word)) {
if (terse) {
fprintf(cp_out,
".fourier line ignored since rawfile was produced.\n");
fprintf(cp_out,
".fourier line ignored since rawfile was produced.\n");
} else {
int err;
@ -355,25 +352,25 @@ ft_cktcoms(bool terse)
fprintf(cp_out, "\n\n");
else
fprintf(cp_err, "No transient data available for "
"fourier analysis");
"fourier analysis");
}
} else if (!eq(command->wl_word, ".save")
&& !eq(command->wl_word, ".op")
// && !eq(command->wl_word, ".measure")
&& !ciprefix(".meas", command->wl_word)
&& !eq(command->wl_word, ".tf"))
} else if (!eq(command->wl_word, ".save") &&
!eq(command->wl_word, ".op") &&
// !eq(command->wl_word, ".measure") &&
!ciprefix(".meas", command->wl_word) &&
!eq(command->wl_word, ".tf"))
{
goto bad;
}
coms = coms->wl_next;
}
nocmds:
nocmds:
/* Now the node table
if (ft_nodesprint)
;
if (ft_nodesprint)
;
*/
/* The options */
if (ft_optsprint) {
fprintf(cp_out, "Options:\n\n");
@ -383,20 +380,22 @@ ft_cktcoms(bool terse)
/* And finally the accounting info. */
if (ft_acctprint) {
static wordlist ww = { "everything", NULL, NULL } ;
static wordlist ww = { "everything", NULL, NULL };
com_rusage(&ww);
} else if ((!ft_noacctprint) && (!ft_acctprint))
} else if ((!ft_noacctprint) && (!ft_acctprint)) {
com_rusage(NULL);
}
/* absolutely no accounting if noacct is given */
putc('\n', cp_out);
return 0;
bad:
bad:
fprintf(cp_err, "Internal Error: ft_cktcoms: bad commands\n");
return 1;
}
/* These routines make sure that the arguments to .plot and .print in
* spice2 decks are acceptable to spice3. The things we look for are:
* trailing (a,b) in .plot -> xlimit a b
@ -425,7 +424,7 @@ fixdotplot(wordlist *wl)
if (*s != ',') {
fprintf(cp_err, "Error: bad limits \"%s\"\n",
wl->wl_word);
return;
return;
}
d1 = *d;
s++;
@ -433,7 +432,7 @@ fixdotplot(wordlist *wl)
if ((*s != /*(*/ ')') || s[1]) {
fprintf(cp_err, "Error: bad limits \"%s\"\n",
wl->wl_word);
return;
return;
}
d2 = *d;
tfree(wl->wl_word);
@ -448,6 +447,7 @@ fixdotplot(wordlist *wl)
return;
}
static void
fixdotprint(wordlist *wl)
{
@ -458,6 +458,7 @@ fixdotprint(wordlist *wl)
return;
}
static char *
fixem(char *string)
{
@ -465,53 +466,92 @@ fixem(char *string)
char *ss = string; /* Get rid of ss ? */
if (ciprefix("v(", string) &&strchr(string, ',')) {
for (s = string; *s && (*s != ','); s++) ; *s++ = '\0';
for (t = s; *t && (*t != ')'); t++) ; *t = '\0';
if (eq(s, "0")) (void) sprintf(buf, "v(%s)", string + 2);
for (s = string; *s && (*s != ','); s++)
;
*s++ = '\0';
for (t = s; *t && (*t != ')'); t++)
;
*t = '\0';
if (eq(s, "0"))
(void) sprintf(buf, "v(%s)", string + 2);
else if (eq(string + 2, "0"))
(void) sprintf(buf, "-v(%s)", s);
else (void) sprintf(buf, "v(%s)-v(%s)", string + 2, s);
(void) sprintf(buf, "-v(%s)", s);
else
(void) sprintf(buf, "v(%s)-v(%s)", string + 2, s);
} else if (ciprefix("vm(", string) &&strchr(string, ',')) {
for (s = string; *s && (*s != ','); s++) ; *s++ = '\0';
for (t = s; *t && (*t != ')'); t++) ; *t = '\0';
if (eq(s, "0")) (void) sprintf(buf, "mag(v(%s))", string + 3);
for (s = string; *s && (*s != ','); s++)
;
*s++ = '\0';
for (t = s; *t && (*t != ')'); t++)
;
*t = '\0';
if (eq(s, "0"))
(void) sprintf(buf, "mag(v(%s))", string + 3);
else if (eq(string + 3, "0"))
(void) sprintf(buf, "mag(-v(%s))", s);
else (void) sprintf(buf, "mag(v(%s)-v(%s))", string + 3, s);
(void) sprintf(buf, "mag(-v(%s))", s);
else
(void) sprintf(buf, "mag(v(%s)-v(%s))", string + 3, s);
} else if (ciprefix("vp(", string) &&strchr(string, ',')) {
for (s = string; *s && (*s != ','); s++) ; *s++ = '\0';
for (t = s; *t && (*t != ')'); t++) ; *t = '\0';
if (eq(s, "0")) (void) sprintf(buf, "ph(v(%s))", string + 3);
for (s = string; *s && (*s != ','); s++)
;
*s++ = '\0';
for (t = s; *t && (*t != ')'); t++)
;
*t = '\0';
if (eq(s, "0"))
(void) sprintf(buf, "ph(v(%s))", string + 3);
else if (eq(string + 3, "0"))
(void) sprintf(buf, "ph(-v(%s))", s);
else (void) sprintf(buf, "ph(v(%s)-v(%s))", string + 3, s);
(void) sprintf(buf, "ph(-v(%s))", s);
else
(void) sprintf(buf, "ph(v(%s)-v(%s))", string + 3, s);
} else if (ciprefix("vi(", string) &&strchr(string, ',')) {
for (s = string; *s && (*s != ','); s++) ; *s++ = '\0';
for (t = s; *t && (*t != ')'); t++) ; *t = '\0';
if (eq(s, "0")) (void) sprintf(buf, "imag(v(%s))", string + 3);
for (s = string; *s && (*s != ','); s++)
;
*s++ = '\0';
for (t = s; *t && (*t != ')'); t++)
;
*t = '\0';
if (eq(s, "0"))
(void) sprintf(buf, "imag(v(%s))", string + 3);
else if (eq(string + 3, "0"))
(void) sprintf(buf, "imag(-v(%s))", s);
else (void) sprintf(buf, "imag(v(%s)-v(%s))", string + 3, s);
(void) sprintf(buf, "imag(-v(%s))", s);
else
(void) sprintf(buf, "imag(v(%s)-v(%s))", string + 3, s);
} else if (ciprefix("vr(", string) &&strchr(string, ',')) {
for (s = string; *s && (*s != ','); s++) ; *s++ = '\0';
for (t = s; *t && (*t != ')'); t++) ; *t = '\0';
if (eq(s, "0")) (void) sprintf(buf, "real(v(%s))", string + 3);
for (s = string; *s && (*s != ','); s++)
;
*s++ = '\0';
for (t = s; *t && (*t != ')'); t++)
;
*t = '\0';
if (eq(s, "0"))
(void) sprintf(buf, "real(v(%s))", string + 3);
else if (eq(string + 3, "0"))
(void) sprintf(buf, "real(-v(%s))", s);
else (void) sprintf(buf, "real(v(%s)-v(%s))", string + 3, s);
(void) sprintf(buf, "real(-v(%s))", s);
else
(void) sprintf(buf, "real(v(%s)-v(%s))", string + 3, s);
} else if (ciprefix("vdb(", string) &&strchr(string, ',')) {
for (s = string; *s && (*s != ','); s++) ; *s++ = '\0';
for (t = s; *t && (*t != ')'); t++) ; *t = '\0';
if (eq(s, "0")) (void) sprintf(buf, "db(v(%s))", string + 4);
for (s = string; *s && (*s != ','); s++)
;
*s++ = '\0';
for (t = s; *t && (*t != ')'); t++)
;
*t = '\0';
if (eq(s, "0"))
(void) sprintf(buf, "db(v(%s))", string + 4);
else if (eq(string + 4, "0"))
(void) sprintf(buf, "db(-v(%s))", s);
else (void) sprintf(buf, "db(v(%s)-v(%s))", string + 4, s);
(void) sprintf(buf, "db(-v(%s))", s);
else
(void) sprintf(buf, "db(v(%s)-v(%s))", string + 4, s);
} else if (ciprefix("i(", string)) {
for (s = string; *s && (*s != ')'); s++) ; *s = '\0';
for (s = string; *s && (*s != ')'); s++)
;
*s = '\0';
string += 2;
(void) sprintf(buf, "%s#branch", string);
} else {
return (string);
}
else return (string);
tfree(ss);
string = copy(buf);
@ -523,53 +563,54 @@ fixem(char *string)
wordlist *
gettoks(char *s)
{
char *t;
char *l, *r, *c; /* left, right, center/comma */
wordlist *wl, *list, **prevp;
char *t;
char *l, *r, *c; /* left, right, center/comma */
wordlist *wl, *list, **prevp;
list = NULL;
prevp = &list;
if (strstr( s, "(" )) s = stripWhiteSpacesInsideParens(s);
if (strstr(s, "(")) s = stripWhiteSpacesInsideParens(s);
while ((t = gettok(&s)) != NULL) {
if (*t == '(')
continue;
l =strrchr(t, '('/*)*/);
if (!l) {
wl = wl_cons(copy(t), NULL);
*prevp = wl;
prevp = &wl->wl_next;
continue;
}
if (*t == '(')
continue;
l = strrchr(t, '('/*)*/);
if (!l) {
wl = wl_cons(copy(t), NULL);
*prevp = wl;
prevp = &wl->wl_next;
continue;
}
r =strchr(t, /*(*/')');
r = strchr(t, /*(*/')');
c =strchr(t, ',');
if (!c)
c = r;
c = strchr(t, ',');
if (!c)
c = r;
if (c)
*c = 0;
if (c)
*c = 0;
wl = wl_cons(NULL, NULL);
*prevp = wl;
prevp = &wl->wl_next;
wl = wl_cons(NULL, NULL);
*prevp = wl;
prevp = &wl->wl_next;
if (*(l - 1) == 'i' || *(l - 1) == 'I') {
char buf[513];
sprintf(buf, "%s#branch", l + 1);
wl->wl_word = copy(buf);
c = r = NULL;
} else
wl->wl_word = copy(l + 1);
if (*(l - 1) == 'i' || *(l - 1) == 'I') {
char buf[513];
sprintf(buf, "%s#branch", l + 1);
wl->wl_word = copy(buf);
c = r = NULL;
} else {
wl->wl_word = copy(l + 1);
}
if (c != r) {
*r = 0;
wl = wl_cons(copy(c + 1), NULL);
*prevp = wl;
prevp = &wl->wl_next;
}
if (c != r) {
*r = 0;
wl = wl_cons(copy(c + 1), NULL);
*prevp = wl;
prevp = &wl->wl_next;
}
}
return list;
}

View File

@ -18,7 +18,7 @@ char ErrorMessage[1024];
#ifdef HAS_WINDOWS
void winmessage(char* new_msg);
void winmessage(char *new_msg);
#endif

View File

@ -19,11 +19,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice/sim.h" /* To get SV_VOLTAGE definition */
/* static declarations */
static RETSIGTYPE sig_matherr(void);
static struct dvec * apply_func(struct func *func, struct pnode *arg);
static struct dvec *apply_func(struct func *func, struct pnode *arg);
static struct dvec *ft_ternary(struct pnode *node);
static char * mkcname(char what, char *v1, char *v2);
static char *mkcname(char what, char *v1, char *v2);
/* We are careful here to catch SIGILL and recognise them as math errors.
@ -43,8 +43,8 @@ sig_matherr(void)
/* Note that ft_evaluate will return NULL on invalid expressions. */
/* va: NOTE: ft_evaluate returns a new vector for expressions (func, op, ...)
and an existing vector (node->pn_value) when node->pn_value != NULL.
For garbage collection caller must vec_free() expression-vector. */
and an existing vector (node->pn_value) when node->pn_value != NULL.
For garbage collection caller must vec_free() expression-vector. */
struct dvec *
ft_evaluate(struct pnode *node)
{
@ -60,7 +60,7 @@ ft_evaluate(struct pnode *node)
if (node->pn_op->op_arity == 1)
d = node->pn_op->op_func.unary (node->pn_left);
else if (node->pn_op->op_arity == 2) {
if(node->pn_op->op_num == PT_OP_TERNARY)
if (node->pn_op->op_num == PT_OP_TERNARY)
d = ft_ternary(node);
else
d = node->pn_op->op_func.binary (node->pn_left, node->pn_right);
@ -70,12 +70,11 @@ ft_evaluate(struct pnode *node)
d = NULL;
}
if (d==NULL) {
if (d == NULL)
return NULL;
}
if (node->pn_name && !ft_evdb && d && !d->v_link2) {
if (d->v_name)
if (d->v_name)
tfree(d->v_name); /* patch by Stefan Jones */
d->v_name = copy(node->pn_name);
}
@ -83,8 +82,9 @@ ft_evaluate(struct pnode *node)
if (!d->v_length) {
fprintf(cp_err, "Error: no such vector %s\n", d->v_name);
return (NULL);
} else
} else {
return (d);
}
}
@ -95,7 +95,7 @@ ft_ternary(struct pnode *node)
struct pnode *arg;
int c;
if(!node->pn_right->pn_op || node->pn_right->pn_op->op_func.binary != op_comma)
if (!node->pn_right->pn_op || node->pn_right->pn_op->op_func.binary != op_comma)
{
fprintf(cp_err, "Error: ft_ternary(), daemons ...\n");
return NULL;
@ -103,27 +103,27 @@ ft_ternary(struct pnode *node)
cond = ft_evaluate(node->pn_left);
if(cond->v_link2) {
if (cond->v_link2) {
fprintf(cp_err, "Error: ft_ternary(), whats that ?\n");
return NULL;
}
if(cond->v_numdims != 1) {
if (cond->v_numdims != 1) {
fprintf(cp_err, "Error: ft_ternary(), condition must be scalar, but numdims=%d\n",
cond->v_numdims);
cond->v_numdims);
return NULL;
}
if(cond->v_length != 1) {
if (cond->v_length != 1) {
fprintf(cp_err, "Error: ft_ternary(), condition must be scalar, but length=%d\n",
cond->v_length);
cond->v_length);
return NULL;
}
c = isreal(cond)
? (cond->v_realdata[0] != 0.0)
: ((realpart(cond->v_compdata[0]) != 0.0) ||
(imagpart(cond->v_compdata[0]) != 0.0) );
(imagpart(cond->v_compdata[0]) != 0.0));
arg = c
? node->pn_right->pn_left
@ -148,9 +148,9 @@ ft_ternary(struct pnode *node)
static void *
doop_funcall(
void* (*func) (void *data1, void *data2,
short int datatype1, short int datatype2,
int length),
void * (*func) (void *data1, void *data2,
short int datatype1, short int datatype2,
int length),
void *data1, void *data2,
short int datatype1, short int datatype2,
int length)
@ -167,7 +167,7 @@ doop_funcall(
(void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);
data = func (data1, data2, datatype1, datatype2, length);
data = func(data1, data2, datatype1, datatype2, length);
/* Back to normal */
(void) signal(SIGILL, SIG_DFL);
@ -178,14 +178,14 @@ doop_funcall(
static struct dvec *
doop(char what,
void*(*func) (void *data1, void *data2,
short int datatype1, short int datatype2,
int length),
void * (*func) (void *data1, void *data2,
short int datatype1, short int datatype2,
int length),
struct pnode *arg1,
struct pnode *arg2)
{
struct dvec *v1, *v2, *res;
ngcomplex_t *c1 = NULL, *c2 = NULL , lc;
ngcomplex_t *c1 = NULL, *c2 = NULL, lc;
double *d1 = NULL, *d2 = NULL, ld;
int length = 0, i;
void *data;
@ -217,32 +217,31 @@ doop(char what,
if ((v1->v_numdims > 1) && (v2->v_numdims > 1)) {
if (v1->v_numdims != v2->v_numdims) {
fprintf(cp_err,
"Warning: operands %s and %s have incompatible shapes.\n",
v1->v_name, v2->v_name);
return (NULL);
}
for (i = 1; i < v1->v_numdims; i++) {
if ((v1->v_dims[i] != v2->v_dims[i])) {
fprintf(cp_err,
"Warning: operands %s and %s have incompatible shapes.\n",
v1->v_name, v2->v_name);
return (NULL);
}
for (i = 1; i < v1->v_numdims; i++)
if ((v1->v_dims[i] != v2->v_dims[i])) {
fprintf(cp_err,
"Warning: operands %s and %s have incompatible shapes.\n",
v1->v_name, v2->v_name);
return (NULL);
}
}
}
/* This is a bad way to do this. */
switch (what) {
case '=':
case '>':
case '<':
case 'G':
case 'L':
case 'N':
case '&':
case '|':
case '~':
relflag = TRUE;
case '=':
case '>':
case '<':
case 'G':
case 'L':
case 'N':
case '&':
case '|':
case '~':
relflag = TRUE;
}
/* Type checking is done later */
@ -258,7 +257,7 @@ doop(char what,
d1[i] = v1->v_realdata[i];
if (i > 0)
ld = v1->v_realdata[i - 1];
for ( ; i < length; i++)
for (; i < length; i++)
d1[i] = ld;
} else {
realpart(lc) = 0.0;
@ -268,14 +267,16 @@ doop(char what,
c1[i] = v1->v_compdata[i];
if (i > 0)
lc = v1->v_compdata[i - 1];
for ( ; i < length; i++)
for (; i < length; i++)
c1[i] = lc;
}
} else
} else {
if (isreal(v1))
d1 = v1->v_realdata;
else
c1 = v1->v_compdata;
}
if (v2->v_length < length) {
free2 = TRUE;
if (isreal(v2)) {
@ -285,7 +286,7 @@ doop(char what,
d2[i] = v2->v_realdata[i];
if (i > 0)
ld = v2->v_realdata[i - 1];
for ( ; i < length; i++)
for (; i < length; i++)
d2[i] = ld;
} else {
realpart(lc) = 0.0;
@ -295,29 +296,30 @@ doop(char what,
c2[i] = v2->v_compdata[i];
if (i > 0)
lc = v2->v_compdata[i - 1];
for ( ; i < length; i++)
for (; i < length; i++)
c2[i] = lc;
}
} else
} else {
if (isreal(v2))
d2 = v2->v_realdata;
else
c2 = v2->v_compdata;
}
/* Now pass the vectors to the appropriate function. */
data = doop_funcall
( func,
isreal(v1) ? (void *) d1 : (void *) c1,
isreal(v2) ? (void *) d2 : (void *) c2,
isreal(v1) ? VF_REAL : VF_COMPLEX,
isreal(v2) ? VF_REAL : VF_COMPLEX,
length);
(func,
isreal(v1) ? (void *) d1 : (void *) c1,
isreal(v2) ? (void *) d2 : (void *) c2,
isreal(v1) ? VF_REAL : VF_COMPLEX,
isreal(v2) ? VF_REAL : VF_COMPLEX,
length);
if (!data)
return (NULL);
/* Make up the new vector. */
res = alloc(struct dvec);
ZERO(res,struct dvec);
ZERO(res, struct dvec);
if (relflag || (isreal(v1) && isreal(v2) && (func != cx_comma))) {
res->v_flags = (v1->v_flags | v2->v_flags |
VF_REAL) & ~ VF_COMPLEX;
@ -336,8 +338,9 @@ doop(char what,
fprintf(cp_err, "Warning: scales of %s and %s are different.\n",
v1->v_name, v2->v_name);
res->v_scale = NULL;
} else
} else {
res->v_scale = v1->v_scale;
}
/* Copy a few useful things */
res->v_defcolor = v1->v_defcolor;
@ -361,105 +364,107 @@ doop(char what,
*/
switch (what)
{
case '*': /* Multiplication of two vectors */
switch(v1->v_type)
{
case SV_VOLTAGE:
switch(v2->v_type)
{
case SV_VOLTAGE:
res->v_type = SV_VOLTAGE;
break;
case SV_CURRENT:
res->v_type = SV_POWER;
break;
default:
break;
}
break;
case '*': /* Multiplication of two vectors */
switch (v1->v_type)
{
case SV_VOLTAGE:
switch (v2->v_type)
{
case SV_VOLTAGE:
res->v_type = SV_VOLTAGE;
break;
case SV_CURRENT:
res->v_type = SV_POWER;
break;
default:
break;
}
break;
case SV_CURRENT:
switch(v2->v_type)
{
case SV_VOLTAGE:
res->v_type = SV_POWER;
break;
case SV_CURRENT:
res->v_type = SV_CURRENT;
break;
default:
break;
}
break;
case SV_CURRENT:
switch (v2->v_type)
{
case SV_VOLTAGE:
res->v_type = SV_POWER;
break;
case SV_CURRENT:
res->v_type = SV_CURRENT;
break;
default:
break;
}
break;
default:
break;
}
break;
case '/': /* division of two vectors */
switch(v1->v_type)
{
case SV_VOLTAGE:
switch(v2->v_type)
{
case SV_VOLTAGE:
res->v_type = SV_NOTYPE;
break;
case SV_CURRENT:
res->v_type = SV_IMPEDANCE;
break;
default:
break;
}
break;
default:
break;
}
break;
case '/': /* division of two vectors */
switch (v1->v_type)
{
case SV_VOLTAGE:
switch (v2->v_type)
{
case SV_VOLTAGE:
res->v_type = SV_NOTYPE;
break;
case SV_CURRENT:
res->v_type = SV_IMPEDANCE;
break;
default:
break;
}
break;
case SV_CURRENT:
switch(v2->v_type)
{
case SV_VOLTAGE:
res->v_type = SV_ADMITTANCE;
break;
case SV_CURRENT:
res->v_type = SV_NOTYPE;
break;
default:
break;
}
break;
case SV_CURRENT:
switch (v2->v_type)
{
case SV_VOLTAGE:
res->v_type = SV_ADMITTANCE;
break;
case SV_CURRENT:
res->v_type = SV_NOTYPE;
break;
default:
break;
}
break;
default:
break;
}
default:
break;
}
default:
break;
default:
break;
}
vec_new(res);
/* Free the temporary data areas we used, if we allocated any. */
if (free1) {
if (isreal(v1)) {
if (isreal(v1))
tfree(d1);
} else {
else
tfree(c1);
}
}
if (free2) {
if (isreal(v2)) {
if (isreal(v2))
tfree(d2);
} else {
else
tfree(c2);
}
}
/* va: garbage collection */
if (arg1->pn_value==NULL && v1!=NULL) vec_free(v1);
if (arg2->pn_value==NULL && v2!=NULL) vec_free(v2);
if (arg1->pn_value == NULL && v1 != NULL)
vec_free(v1);
if (arg2->pn_value == NULL && v2 != NULL)
vec_free(v2);
return (res);
}
/* The binary operations. */
struct dvec *
op_plus(struct pnode *arg1, struct pnode *arg2)
@ -551,6 +556,7 @@ op_or(struct pnode *arg1, struct pnode *arg2)
return (doop('|', cx_or, arg1, arg2));
}
/* This is an odd operation. The first argument is the name of a vector, and
* the second is a range in the scale, so that v(1)[[10, 20]] gives all the
* values of v(1) for which the TIME value is between 10 and 20. If there is
@ -562,7 +568,7 @@ op_or(struct pnode *arg1, struct pnode *arg2)
struct dvec *
op_range(struct pnode *arg1, struct pnode *arg2)
{
struct dvec *v, *ind, *res, *scale; /* , *nscale; */
struct dvec *v, *ind, *res, *scale;
double up, low, td;
int len, i, j;
bool rev = FALSE;
@ -571,9 +577,11 @@ op_range(struct pnode *arg1, struct pnode *arg2)
ind = ft_evaluate(arg2);
if (!v || !ind)
return (NULL);
scale = v->v_scale;
if (!scale)
scale = v->v_plot->pl_scale;
if (!scale) {
fprintf(cp_err, "Error: no scale for vector %s\n", v->v_name);
return (NULL);
@ -583,27 +591,30 @@ op_range(struct pnode *arg1, struct pnode *arg2)
fprintf(cp_err, "Error: strange range specification\n");
return (NULL);
}
if (isreal(ind)) {
up = low = *ind->v_realdata;
} else {
up = imagpart(ind->v_compdata[0]);
low = realpart(ind->v_compdata[0]);
}
if (up < low) {
td = up;
up = low;
low = td;
rev = TRUE;
}
for (i = len = 0; i < scale->v_length; i++) {
td = isreal(scale) ? scale->v_realdata[i] :
realpart(scale->v_compdata[i]);
realpart(scale->v_compdata[i]);
if ((td <= up) && (td >= low))
len++;
}
res = alloc(struct dvec);
ZERO(res,struct dvec);
ZERO(res, struct dvec);
res->v_name = mkcname('R', v->v_name, ind->v_name);
res->v_type = v->v_type;
res->v_flags = v->v_flags;
@ -614,9 +625,9 @@ op_range(struct pnode *arg1, struct pnode *arg2)
res->v_length = len;
res->v_scale = /* nscale; */ scale;
/* Dave says get rid of this
res->v_numdims = v->v_numdims;
for (i = 0; i < v->v_numdims; i++)
res->v_dims[i] = v->v_dims[i];
res->v_numdims = v->v_numdims;
for (i = 0; i < v->v_numdims; i++)
res->v_dims[i] = v->v_dims[i];
*/
res->v_numdims = 1;
res->v_dims[0] = len;
@ -629,22 +640,25 @@ op_range(struct pnode *arg1, struct pnode *arg2)
/* Toss in the data */
j = 0;
for (i = (rev ? v->v_length - 1 : 0); i != (rev ? -1 : v->v_length);
rev ? i-- : i++) {
for (i = (rev ? v->v_length - 1 : 0);
i != (rev ? -1 : v->v_length);
rev ? i-- : i++)
{
td = isreal(scale) ? scale->v_realdata[i] :
realpart(scale->v_compdata[i]);
realpart(scale->v_compdata[i]);
if ((td <= up) && (td >= low)) {
if (isreal(res)) {
res->v_realdata[j] = v->v_realdata[i];
} else {
realpart(res->v_compdata[j]) =
realpart(v->v_compdata[i]);
realpart(v->v_compdata[i]);
imagpart(res->v_compdata[j]) =
imagpart(v->v_compdata[i]);
imagpart(v->v_compdata[i]);
}
j++;
}
}
if (j != len)
fprintf(cp_err, "Error: something funny..\n");
@ -656,11 +670,15 @@ op_range(struct pnode *arg1, struct pnode *arg2)
vec_new(res);
/* va: garbage collection */
if (arg1->pn_value==NULL && v!=NULL) vec_free(v);
if (arg2->pn_value==NULL && ind!=NULL) vec_free(ind);
if (arg1->pn_value == NULL && v != NULL)
vec_free(v);
if (arg2->pn_value == NULL && ind != NULL)
vec_free(ind);
return (res);
}
/* This is another operation we do specially -- if the argument is a vector of
* dimension n, n > 0, the result will be either a vector of dimension n - 1,
* or a vector of dimension n with only a certain range of vectors present.
@ -685,8 +703,8 @@ op_ind(struct pnode *arg1, struct pnode *arg2)
j *= v->v_dims[i];
if (v->v_length != j) {
fprintf(cp_err,
"op_ind: Internal Error: len %d should be %d\n",
v->v_length, j);
"op_ind: Internal Error: len %d should be %d\n",
v->v_length, j);
return (NULL);
}
} else {
@ -753,7 +771,7 @@ op_ind(struct pnode *arg1, struct pnode *arg2)
/* Make up the new vector. */
res = alloc(struct dvec);
ZERO(res,struct dvec);
ZERO(res, struct dvec);
res->v_name = mkcname('[', v->v_name, ind->v_name);
res->v_type = v->v_type;
res->v_flags = v->v_flags;
@ -764,12 +782,12 @@ op_ind(struct pnode *arg1, struct pnode *arg2)
res->v_length = length;
res->v_numdims = newdim;
if (up != down) {
for (i = 0; i < newdim; i++)
res->v_dims[i] = v->v_dims[i];
for (i = 0; i < newdim; i++)
res->v_dims[i] = v->v_dims[i];
res->v_dims[0] = up - down + 1;
} else {
for (i = 0; i < newdim; i++)
res->v_dims[i] = v->v_dims[i + 1];
for (i = 0; i < newdim; i++)
res->v_dims[i] = v->v_dims[i + 1];
}
if (isreal(res))
@ -784,10 +802,10 @@ op_ind(struct pnode *arg1, struct pnode *arg2)
else
k = j;
for (i = 0; i < blocksize; i++)
if (isreal(res))
if (isreal(res)) {
res->v_realdata[k * blocksize + i] =
v->v_realdata[(down + j) * blocksize + i];
else {
} else {
realpart(res->v_compdata[k * blocksize + i]) =
realpart(v->v_compdata[(down + j) * blocksize + i]);
imagpart(res->v_compdata[k * blocksize + i]) =
@ -809,11 +827,15 @@ op_ind(struct pnode *arg1, struct pnode *arg2)
vec_new(res);
/* va: garbage collection */
if (arg1->pn_value==NULL && v!=NULL) vec_free(v);
if (arg2->pn_value==NULL && ind!=NULL) vec_free(ind);
if (arg1->pn_value == NULL && v != NULL)
vec_free(v);
if (arg2->pn_value == NULL && ind != NULL)
vec_free(ind);
return (res);
}
/* Apply a function to an argument. Complex functions are called as follows:
* cx_something(data, type, length, &newlength, &newtype),
* and returns a char * that is cast to complex or double.
@ -839,20 +861,22 @@ apply_func_funcall(struct func *func, struct dvec *v, int *newlength, short int
if (eq(func->fu_name, "interpolate") || eq(func->fu_name, "deriv") || eq(func->fu_name, "group_delay")) /* Ack */
{
void *(*f)(void *data, short int type, int length,
int *newlength, short int *newtype, struct plot *, struct plot *, int) = (void *(*)(void *, short int, int, int *, short int *, struct plot *, struct plot *, int)) func->fu_func;
data = f (
isreal(v) ? (void *) v->v_realdata : (void *) v->v_compdata,
(short) (isreal(v) ? VF_REAL : VF_COMPLEX),
v->v_length,
newlength, newtype,
v->v_plot, plot_cur, v->v_dims[0]);
void * (*f) (void *data, short int type, int length,
int *newlength, short int *newtype,
struct plot *, struct plot *, int) =
(void * (*) (void *, short int, int, int *, short int *, struct plot *, struct plot *, int)) func->fu_func;
data = f
(isreal(v) ? (void *) v->v_realdata : (void *) v->v_compdata,
(short) (isreal(v) ? VF_REAL : VF_COMPLEX),
v->v_length,
newlength, newtype,
v->v_plot, plot_cur, v->v_dims[0]);
} else {
data = func->fu_func (
isreal(v) ? (void *) v->v_realdata : (void *) v->v_compdata,
(short) (isreal(v) ? VF_REAL : VF_COMPLEX),
v->v_length,
newlength, newtype);
data = func->fu_func
(isreal(v) ? (void *) v->v_realdata : (void *) v->v_compdata,
(short) (isreal(v) ? VF_REAL : VF_COMPLEX),
v->v_length,
newlength, newtype);
}
/* Back to normal */
@ -903,53 +927,58 @@ apply_func(struct func *func, struct pnode *arg)
return (NULL);
t = alloc(struct dvec);
ZERO(t,struct dvec);
ZERO(t, struct dvec);
t->v_flags = (v->v_flags & ~VF_COMPLEX & ~VF_REAL &
~VF_PERMANENT & ~VF_MINGIVEN & ~VF_MAXGIVEN);
~VF_PERMANENT & ~VF_MINGIVEN & ~VF_MAXGIVEN);
t->v_flags |= type;
#ifdef FTEDEBUG
if (ft_evdb)
fprintf(cp_err,
"apply_func: func %s to %s len %d, type %d\n",
"apply_func: func %s to %s len %d, type %d\n",
func->fu_name, v->v_name, len, type);
#endif
if (isreal(t))
t->v_realdata = (double *) data;
else
t->v_compdata = (ngcomplex_t *) data;
if (eq(func->fu_name, "minus"))
t->v_name = mkcname('a', func->fu_name, v->v_name);
else if (eq(func->fu_name, "not"))
t->v_name = mkcname('c', func->fu_name, v->v_name);
else
t->v_name = mkcname('b', v->v_name, NULL);
t->v_type = v->v_type; /* This is strange too. */
t->v_length = len;
t->v_scale = v->v_scale;
if (isreal(t))
t->v_realdata = (double *) data;
else
t->v_compdata = (ngcomplex_t *) data;
/* Copy a few useful things */
t->v_defcolor = v->v_defcolor;
t->v_gridtype = v->v_gridtype;
t->v_plottype = v->v_plottype;
t->v_numdims = v->v_numdims;
for (i = 0; i < t->v_numdims; i++)
t->v_dims[i] = v->v_dims[i];
if (eq(func->fu_name, "minus"))
t->v_name = mkcname('a', func->fu_name, v->v_name);
else if (eq(func->fu_name, "not"))
t->v_name = mkcname('c', func->fu_name, v->v_name);
else
t->v_name = mkcname('b', v->v_name, NULL);
vec_new(t);
t->v_type = v->v_type; /* This is strange too. */
t->v_length = len;
t->v_scale = v->v_scale;
if (end)
end->v_link2 = t;
else
newv = t;
end = t;
/* Copy a few useful things */
t->v_defcolor = v->v_defcolor;
t->v_gridtype = v->v_gridtype;
t->v_plottype = v->v_plottype;
t->v_numdims = v->v_numdims;
for (i = 0; i < t->v_numdims; i++)
t->v_dims[i] = v->v_dims[i];
vec_new(t);
if (end)
end->v_link2 = t;
else
newv = t;
end = t;
}
/* va: garbage collection */
if (arg->pn_value==NULL && v!=NULL) vec_free(v);
if (arg->pn_value == NULL && v != NULL)
vec_free(v);
return (newv);
}
/* The unary minus operation. */
struct dvec *
@ -964,6 +993,7 @@ op_not(struct pnode *arg)
return (apply_func(&func_not, arg));
}
/* Create a reasonable name for the result of a function application, etc.
* The what values 'a' and 'b' mean "make a function name" and "make a
* unary minus", respectively.
@ -975,18 +1005,17 @@ mkcname(char what, char *v1, char *v2)
char buf[BSIZE_SP], *s;
if (what == 'a')
(void) sprintf(buf, "%s(%s)", v1, v2);
(void) sprintf(buf, "%s(%s)", v1, v2);
else if (what == 'b')
(void) sprintf(buf, "-(%s)", v1);
(void) sprintf(buf, "-(%s)", v1);
else if (what == 'c')
(void) sprintf(buf, "~(%s)", v1);
(void) sprintf(buf, "~(%s)", v1);
else if (what == '[')
(void) sprintf(buf, "%s[%s]", v1, v2);
(void) sprintf(buf, "%s[%s]", v1, v2);
else if (what == 'R')
(void) sprintf(buf, "%s[[%s]]", v1, v2);
(void) sprintf(buf, "%s[[%s]]", v1, v2);
else
(void) sprintf(buf, "(%s)%c(%s)", v1, what, v2);
(void) sprintf(buf, "(%s)%c(%s)", v1, what, v2);
s = copy(buf);
return (s);
}

View File

@ -9,25 +9,24 @@
#include "ngspice/dvec.h"
#include "ngspice/pnode.h"
struct dvec * op_plus(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_minus(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_comma(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_times(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_mod(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_divide(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_power(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_eq(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_gt(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_lt(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_ge(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_le(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_ne(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_and(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_or(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_range(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_ind(struct pnode *arg1, struct pnode *arg2);
struct dvec * op_uminus(struct pnode *arg);
struct dvec * op_not(struct pnode *arg);
struct dvec *op_plus(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_minus(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_comma(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_times(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_mod(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_divide(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_power(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_eq(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_gt(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_lt(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_ge(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_le(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_ne(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_and(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_or(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_range(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_ind(struct pnode *arg1, struct pnode *arg2);
struct dvec *op_uminus(struct pnode *arg);
struct dvec *op_not(struct pnode *arg);
#endif

View File

@ -21,19 +21,18 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "variable.h"
/* static declarations */
static char * pn(double num);
static int CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Value,
double FundFreq, double *Freq, double *Mag, double *Phase, double *nMag,
double *nPhase);
static char *pn(double num);
static int CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Value,
double FundFreq, double *Freq, double *Mag, double *Phase, double *nMag,
double *nPhase);
#define DEF_FOURGRIDSIZE 200
/* CKTfour(ndata,numFreq,thd,Time,Value,FundFreq,Freq,Mag,Phase,nMag,nPhase)
* len 10 ? inp inp inp out out out out out
/* CKTfour(ndata, numFreq, thd, Time, Value, FundFreq, Freq, Mag, Phase, nMag, nPhase)
* len 10 ? inp inp inp out out out out out
*/
/* FIXME: This function leaks memory due to non local exit bypassing
@ -53,7 +52,7 @@ fourier(wordlist *wl, struct plot *current_plot)
int shift;
if (!current_plot)
return 1;
return 1;
sprintf(xbuf, "%1.1e", 0.0);
shift = (int) strlen(xbuf) - 7;
@ -95,14 +94,13 @@ fourier(wordlist *wl, struct plot *current_plot)
names = names->pn_next;
while (vec) {
if (vec->v_length != time->v_length) {
fprintf(cp_err,
"Error: lengths don't match: %d, %d\n",
fprintf(cp_err,
"Error: lengths don't match: %d, %d\n",
vec->v_length, time->v_length);
continue;
}
if (!isreal(vec)) {
fprintf(cp_err, "Error: %s isn't real!\n",
vec->v_name);
fprintf(cp_err, "Error: %s isn't real!\n", vec->v_name);
continue;
}
@ -115,8 +113,7 @@ fourier(wordlist *wl, struct plot *current_plot)
/* Now get the last fund freq... */
d = 1 / fundfreq; /* The wavelength... */
if (dp[1] - dp[0] < d) {
fprintf(cp_err,
"Error: wavelength longer than time span\n");
fprintf(cp_err, "Error: wavelength longer than time span\n");
return 1;
} else if (dp[1] - dp[0] > d) {
dp[0] = dp[1] - d;
@ -125,14 +122,13 @@ fourier(wordlist *wl, struct plot *current_plot)
d = (dp[1] - dp[0]) / fourgridsize;
for (i = 0; i < fourgridsize; i++)
grid[i] = dp[0] + i * d;
/* Now interpolate the stuff... */
if (!ft_interpolate(vec->v_realdata, stuff,
time->v_realdata, vec->v_length,
grid, fourgridsize,
polydegree)) {
fprintf(cp_err,
"Error: can't interpolate\n");
time->v_realdata, vec->v_length,
grid, fourgridsize,
polydegree)) {
fprintf(cp_err, "Error: can't interpolate\n");
return 1;
}
timescale = grid;
@ -143,25 +139,24 @@ fourier(wordlist *wl, struct plot *current_plot)
}
err = CKTfour(fourgridsize, nfreqs, &thd, timescale,
stuff, fundfreq, freq, mag, phase, nmag,
nphase);
stuff, fundfreq, freq, mag, phase, nmag,
nphase);
if (err != OK) {
ft_sperror(err, "fourier");
return 1;
}
fprintf(cp_out, "Fourier analysis for %s:\n",
vec->v_name);
fprintf(cp_out,
" No. Harmonics: %d, THD: %g %%, Gridsize: %d, Interpolation Degree: %d\n\n",
nfreqs, thd, fourgridsize,
polydegree);
fprintf(cp_out, "Fourier analysis for %s:\n", vec->v_name);
fprintf(cp_out,
" No. Harmonics: %d, THD: %g %%, Gridsize: %d, Interpolation Degree: %d\n\n",
nfreqs, thd, fourgridsize,
polydegree);
/* Each field will have width cp_numdgt + 6 (or 7
* with HP-UX) + 1 if there is a - sign.
*/
fw = ((cp_numdgt > 0) ? cp_numdgt : 6) + 5 + shift;
fprintf(cp_out, "Harmonic %-*s %-*s %-*s %-*s %-*s\n",
fw, "Frequency", fw, "Magnitude",
fw, "Frequency", fw, "Magnitude",
fw, "Phase", fw, "Norm. Mag",
fw, "Norm. Phase");
fprintf(cp_out, "-------- %-*s %-*s %-*s %-*s %-*s\n",
@ -170,23 +165,25 @@ fourier(wordlist *wl, struct plot *current_plot)
fw, "-----------");
for (i = 0; i < nfreqs; i++)
fprintf(cp_out,
" %-4d %-*s %-*s %-*s %-*s %-*s\n",
i,
fw, pn(freq[i]),
fw, pn(mag[i]),
fw, pn(phase[i]),
fw, pn(nmag[i]),
fw, pn(nphase[i]));
" %-4d %-*s %-*s %-*s %-*s %-*s\n",
i,
fw, pn(freq[i]),
fw, pn(mag[i]),
fw, pn(phase[i]),
fw, pn(nmag[i]),
fw, pn(nphase[i]));
fputs("\n", cp_out);
vec = vec->v_link2;
}
}
free_pnode(first_name);
tfree(freq);
tfree(mag);
tfree(phase);
tfree(nmag);
tfree(nphase);
return 0;
}
@ -198,7 +195,6 @@ com_fourier(wordlist *wl)
}
static char *
pn(double num)
{
@ -212,6 +208,7 @@ pn(double num)
sprintf(buf, "%.*g", i - 1, num);
else
sprintf(buf, "%.*g", i, num);
return (copy(buf));
}
@ -224,25 +221,25 @@ pn(double num)
* vectors of time and data values to have the fourier analysis
* performed on them. */
static int
CKTfour(int ndata, /* number of entries in the Time and
CKTfour(int ndata, /* number of entries in the Time and
Value arrays */
int numFreq, /* number of harmonics to calculate */
double *thd, /* total harmonic distortion (percent)
int numFreq, /* number of harmonics to calculate */
double *thd, /* total harmonic distortion (percent)
to be returned */
double *Time, /* times at which the voltage/current
double *Time, /* times at which the voltage/current
values were measured*/
double *Value, /* voltage or current vector whose
double *Value, /* voltage or current vector whose
transform is desired */
double FundFreq, /* the fundamental frequency of the
double FundFreq, /* the fundamental frequency of the
analysis */
double *Freq, /* the frequency value of the various
double *Freq, /* the frequency value of the various
harmonics */
double *Mag, /* the Magnitude of the fourier
double *Mag, /* the Magnitude of the fourier
transform */
double *Phase, /* the Phase of the fourier transform */
double *nMag, /* the normalized magnitude of the
double *Phase, /* the Phase of the fourier transform */
double *nMag, /* the normalized magnitude of the
transform: nMag(fund)=1*/
double *nPhase) /* the normalized phase of the
double *nPhase) /* the normalized phase of the
transform: Nphase(fund)=0 */
{
/* Note: we can consider these as a set of arrays. The sizes are:
@ -265,30 +262,31 @@ CKTfour(int ndata, /* number of entries in the Time and
/* clear output/computation arrays */
for(i=0;i<numFreq;i++) {
Mag[i]=0;
Phase[i]=0;
}
for(i=0;i<ndata;i++) {
for(j=0;j<numFreq;j++) {
Mag[j] += (Value[i]*sin(j*2.0*M_PI*i/((double) ndata)));
Phase[j] += (Value[i]*cos(j*2.0*M_PI*i/((double) ndata)));
}
for (i = 0; i < numFreq; i++) {
Mag[i] = 0;
Phase[i] = 0;
}
for (i = 0; i < ndata; i++)
for (j = 0; j < numFreq; j++) {
Mag[j] += Value[i] * sin(j*2.0*M_PI*i/((double)ndata));
Phase[j] += Value[i] * cos(j*2.0*M_PI*i/((double)ndata));
}
Mag[0] = Phase[0]/ndata;
Phase[0]=nMag[0]=nPhase[0]=Freq[0]=0;
Phase[0] = nMag[0] = nPhase[0] = Freq[0] = 0;
*thd = 0;
for(i=1;i<numFreq;i++) {
tmp = Mag[i]*2.0 /ndata;
Phase[i] *= 2.0/ndata;
for (i = 1; i < numFreq; i++) {
tmp = Mag[i] * 2.0 / ndata;
Phase[i] *= 2.0 / ndata;
Freq[i] = i * FundFreq;
Mag[i] = sqrt(tmp*tmp+Phase[i]*Phase[i]);
Phase[i] = atan2(Phase[i],tmp)*180.0/M_PI;
nMag[i] = Mag[i]/Mag[1];
nPhase[i] = Phase[i]-Phase[1];
if(i>1) *thd += nMag[i]*nMag[i];
Mag[i] = sqrt(tmp*tmp + Phase[i]*Phase[i]);
Phase[i] = atan2(Phase[i], tmp) * 180.0/M_PI;
nMag[i] = Mag[i] / Mag[1];
nPhase[i] = Phase[i] - Phase[1];
if (i > 1)
*thd += nMag[i] * nMag[i];
}
*thd = 100*sqrt(*thd);
return(OK);
return (OK);
}

View File

@ -45,9 +45,10 @@ ft_getstat(struct circ *ft_curckt, char *name)
vv->va_type = FTEOPTtbl[i].dataType;
vv->va_name = copy(FTEOPTtbl[i].description);
vv->va_next = NULL;
return(vv);
} else
return (vv);
} else {
return (NULL);
}
}
return (NULL);
} else {
@ -88,7 +89,8 @@ getFTEstat(struct circ *ft_curckt, int id)
break;
default:
tfree(v);
return(NULL);
return (NULL);
}
return(v);
return (v);
}

View File

@ -10,306 +10,304 @@
#include "gens.h"
/* static declarations */
static void dgen_next(dgen **dgx);
void
wl_forall(wordlist *wl, void (*fn)(wordlist*, dgen*), dgen *data)
{
while (wl) {
fn (wl, data);
wl = wl->wl_next;
}
while (wl) {
fn (wl, data);
wl = wl->wl_next;
}
}
dgen *
dgen_init(GENcircuit *ckt, wordlist *wl, int nomix, int flag, int model)
{
dgen *dg, *dg_save;
wordlist **prevp;
dgen *dg, *dg_save;
wordlist **prevp;
NG_IGNORE(nomix);
NG_IGNORE(nomix);
dg = NEW(dgen);
dg->ckt = ckt;
dg->instance = NULL;
dg->model = NULL;
dg->dev_type_no = -1;
dg->dev_list = wl;
dg->flags = 0;
dg_save = dg; /* va: save, to avoid memory leak */
dg = NEW(dgen);
dg->ckt = ckt;
dg->instance = NULL;
dg->model = NULL;
dg->dev_type_no = -1;
dg->dev_list = wl;
dg->flags = 0;
dg_save = dg; /* va: save, to avoid memory leak */
prevp = &wl;
prevp = &wl;
if (model)
dg->flags = (DGEN_ALL & ~ DGEN_INSTANCE) | DGEN_INIT;
else
dg->flags = DGEN_ALL | DGEN_INIT;
if (model)
dg->flags = (DGEN_ALL & ~ DGEN_INSTANCE) | DGEN_INIT;
else
dg->flags = DGEN_ALL | DGEN_INIT;
if (wl)
dg->flags |= flag;
else
dg->flags |= DGEN_DEFDEVS | flag;
if (wl)
dg->flags |= flag;
else
dg->flags |= DGEN_DEFDEVS | flag;
dgen_next(&dg);
/* va: it might be too much tests, but safer is better... */
if (dg!=dg_save && dg==NULL && dg_save!=NULL) tfree(dg_save);
dgen_next(&dg);
/* va: it might be too much tests, but safer is better... */
if (dg != dg_save && dg == NULL && dg_save != NULL)
tfree(dg_save);
return dg;
return dg;
}
int
dgen_for_n(dgen *dg, int n, int (*fn) (dgen*, IFparm*, int), IFparm *data, int subindex)
{
dgen dgx, *dgxp;
int dnum, i, j, k;
dgen dgx, *dgxp;
int dnum, i, j, k;
dgxp = &dgx;
bcopy(dg, dgxp, sizeof(dgx)); /* va: compatible pointer types */
dgxp = &dgx;
bcopy(dg, dgxp, sizeof(dgx)); /* va: compatible pointer types */
dnum = dgxp->dev_type_no;
dnum = dgxp->dev_type_no;
k = 0;
for (i = 0; dgxp && dgxp->dev_type_no == dnum && i < n; i++) {
/*printf("Loop at %d\n", i);*/
j = fn (dgxp, data, subindex);
if (j > k)
k = j;
dgen_next(&dgxp);
}
k = 0;
for (i = 0; dgxp && dgxp->dev_type_no == dnum && i < n; i++) {
/*printf("Loop at %d\n", i);*/
j = fn (dgxp, data, subindex);
if (j > k)
k = j;
dgen_next(&dgxp);
}
return k - subindex;
return k - subindex;
}
void
dgen_nth_next(dgen **p_dg, int n)
{
int i, dnum;
dgen * dg_save=*p_dg; /* va: save, to avoid memory leak */
int i, dnum;
dgen *dg_save = *p_dg; /* va: save, to avoid memory leak */
dnum = (*p_dg)->dev_type_no;
dnum = (*p_dg)->dev_type_no;
for (i = 0; *p_dg && (*p_dg)->dev_type_no == dnum && i < n; i++) {
dgen_next(p_dg);
/* va: it might be too much tests, but safer is better... */
if (*p_dg!=dg_save && *p_dg==NULL && dg_save!=NULL) tfree(dg_save);
}
for (i = 0; *p_dg && (*p_dg)->dev_type_no == dnum && i < n; i++) {
dgen_next(p_dg);
/* va: it might be too much tests, but safer is better... */
if (*p_dg != dg_save && *p_dg == NULL && dg_save != NULL)
tfree(dg_save);
}
}
static void
dgen_next(dgen **dgx)
{
int done;
dgen *dg;
char *p;
int need;
wordlist *w;
char type, *subckt, *device, *model;
char *Top_Level = "\001";
int subckt_len;
int head_match;
char *word, *dev_name, *mod_name;
int done;
dgen *dg;
char *p;
int need;
wordlist *w;
char type, *subckt, *device, *model;
char *Top_Level = "\001";
int subckt_len;
int head_match;
char *word, *dev_name, *mod_name;
dg = *dgx;
if (!dg)
return;
dg = *dgx;
if (!dg)
return;
/* Prime the "model only" or "device type only" iteration,
* required because the filtering (below) may request additional
* detail.
*/
if (!(dg->flags & DGEN_INSTANCE)) {
if (!(dg->flags & DGEN_MODEL))
dg->model = NULL;
dg->instance = NULL;
}
/* Prime the "model only" or "device type only" iteration,
* required because the filtering (below) may request additional
* detail.
*/
if (!(dg->flags & DGEN_INSTANCE)) {
if (!(dg->flags & DGEN_MODEL))
dg->model = NULL;
dg->instance = NULL;
}
need = dg->flags;
done = 0;
need = dg->flags;
done = 0;
while (!done) {
while (!done) {
if (dg->instance) {
/* next instance */
dg->instance = dg->instance->GENnextInstance;
} else if (dg->model) {
dg->model = dg->model->GENnextModel;
if (dg->model)
dg->instance = dg->model->GENinstances;
} else if (dg->dev_type_no < DEVmaxnum) {
dg->dev_type_no += 1;
if (dg->dev_type_no < DEVmaxnum) {
dg->model = ((CKTcircuit *)
(dg->ckt))->CKThead[dg->dev_type_no];
if (dg->model)
dg->instance = dg->model->GENinstances;
} else {
done = 2;
break;
}
} else {
done = 2;
break;
}
if (dg->instance) {
/* next instance */
dg->instance = dg->instance->GENnextInstance;
} else if (dg->model) {
dg->model = dg->model->GENnextModel;
if (dg->model)
dg->instance = dg->model->GENinstances;
} else if (dg->dev_type_no < DEVmaxnum) {
dg->dev_type_no += 1;
if (dg->dev_type_no < DEVmaxnum) {
dg->model = ((CKTcircuit *)(dg->ckt))->CKThead[dg->dev_type_no];
if (dg->model)
dg->instance = dg->model->GENinstances;
} else {
done = 2;
break;
}
} else {
done = 2;
break;
}
if (need & DGEN_INSTANCE && !dg->instance)
continue;
if (need & DGEN_MODEL && !dg->model)
continue;
if (need & DGEN_INSTANCE && !dg->instance)
continue;
if (need & DGEN_MODEL && !dg->model)
continue;
/* Filter */
if (!dg->dev_list) {
if ((dg->flags & DGEN_ALLDEVS)
|| ((dg->flags & DGEN_DEFDEVS)
&& (ft_sim->devices[dg->dev_type_no]->flags
& DEV_DEFAULT)))
{
done = 1;
} else {
done = 0;
}
continue;
}
/* Filter */
if (!dg->dev_list) {
if ((dg->flags & DGEN_ALLDEVS) ||
((dg->flags & DGEN_DEFDEVS) &&
(ft_sim->devices[dg->dev_type_no]->flags & DEV_DEFAULT)))
{
done = 1;
} else {
done = 0;
}
continue;
}
done = 0;
done = 0;
for (w = dg->dev_list; w && !done; w = w->wl_next) {
for (w = dg->dev_list; w && !done; w = w->wl_next) {
/* assume a match (have to reset done every time
* through
*/
done = 1;
word = w->wl_word;
/* assume a match (have to reset done every time
* through
*/
done = 1;
word = w->wl_word;
if (!word || !*word) {
break;
}
if (!word || !*word) {
break;
}
/* Break up word into type, subcircuit, model, device,
* must be nodestructive to "word"
*/
/* Break up word into type, subcircuit, model, device,
* must be nodestructive to "word"
*/
/* type */
if (*word == ':' || *word == '#')
type = '\0';
else
type = *word++;
/* type */
if (*word == ':' || *word == '#')
type = '\0';
else
type = *word++;
/* subcircuit */
/* subcircuit */
subckt = word;
/* look for last ":" or "#" in word */
for (p = word + strlen(word) /* do '\0' first time */;
p != word && *p != ':' && *p != '#'; p--)
{
;
}
subckt = word;
/* look for last ":" or "#" in word */
for (p = word + strlen(word) /* do '\0' first time */;
p != word && *p != ':' && *p != '#'; p--)
{
;
}
if (*p != ':' && *p != '#') {
/* No subcircuit name specified */
subckt = NULL;
subckt_len = 0;
} else {
if (*p != ':' && *p != '#') {
/* No subcircuit name specified */
subckt = NULL;
subckt_len = 0;
} else {
if (p[-1] == ':') {
head_match = 1;
subckt_len = (int)(p - word) - 1;
} else {
head_match = 0;
subckt_len = (int)(p - word);
}
if (p[-1] == ':') {
head_match = 1;
subckt_len = (int)(p - word) - 1;
} else {
head_match = 0;
subckt_len = (int)(p - word);
}
if (subckt_len == 0) {
/* Top level only */
if (head_match)
subckt = NULL;
else
subckt = Top_Level;
}
word = p + 1;
}
if (subckt_len == 0) {
/* Top level only */
if (head_match)
subckt = NULL;
else
subckt = Top_Level;
}
word = p + 1;
}
/* model or device */
/* model or device */
if (*p == '#') {
model = word;
device = NULL;
} else {
model = NULL;
device = word;
}
if (*p == '#') {
model = word;
device = NULL;
} else {
model = NULL;
device = word;
}
/* Now compare */
if (dg->instance)
dev_name = dg->instance->GENname;
else
dev_name = NULL;
/* Now compare */
if (dg->instance)
dev_name = dg->instance->GENname;
else
dev_name = NULL;
if (dg->model)
mod_name = dg->model->GENmodName;
else
mod_name = NULL;
if (dg->model)
mod_name = dg->model->GENmodName;
else
mod_name = NULL;
if (type) {
if (!dev_name) {
done = 0;
/*printf("No device.\n");*/
need |= DGEN_MODEL;
continue;
} else if (type != *dev_name) {
done = 0;
/*printf("Wrong type.\n");*/
/* Bleh ... plan breaks down here */
/* need = DGEN_TYPE; */
continue;
}
}
if (type) {
if (!dev_name) {
done = 0;
/*printf("No device.\n");*/
need |= DGEN_MODEL;
continue;
} else if (type != *dev_name) {
done = 0;
/*printf("Wrong type.\n");*/
/* Bleh ... plan breaks down here */
/* need = DGEN_TYPE; */
continue;
}
}
if (subckt == Top_Level) {
if (dev_name && dev_name[1] == ':') {
need |= DGEN_INSTANCE;
done = 0;
/*printf("Wrong level.\n");*/
continue;
}
} else if (subckt && (!dev_name
|| !ciprefix(subckt, dev_name + 1)))
{
need |= DGEN_INSTANCE;
done = 0;
/*printf("Wrong subckt.\n"); */
continue;
}
if (subckt == Top_Level) {
if (dev_name && dev_name[1] == ':') {
need |= DGEN_INSTANCE;
done = 0;
/*printf("Wrong level.\n");*/
continue;
}
} else if (subckt && (!dev_name || !ciprefix(subckt, dev_name + 1))) {
need |= DGEN_INSTANCE;
done = 0;
/*printf("Wrong subckt.\n"); */
continue;
}
if (device && *device) {
need |= DGEN_INSTANCE | DGEN_MODEL;
if (!dev_name) {
done = 0;
/*printf("Didn't get dev name.\n");*/
continue;
} else if (strcmp(device,
dev_name + 1 + subckt_len))
{
done = 0;
/*printf("Wrong name.\n");*/
continue;
}
} else if (model && *model) {
if (strcmp(model, mod_name)) {
done = 0;
need |= DGEN_MODEL;
/*printf("Wrong model name.\n");*/
continue;
}
}
if (device && *device) {
need |= DGEN_INSTANCE | DGEN_MODEL;
if (!dev_name) {
done = 0;
/*printf("Didn't get dev name.\n");*/
continue;
} else if (strcmp(device, dev_name + 1 + subckt_len)) {
done = 0;
/*printf("Wrong name.\n");*/
continue;
}
} else if (model && *model) {
if (strcmp(model, mod_name)) {
done = 0;
need |= DGEN_MODEL;
/*printf("Wrong model name.\n");*/
continue;
}
}
break;
}
break;
}
}
}
if (done == 2)
*dgx = NULL;
if (done == 2)
*dgx = NULL;
}

View File

@ -65,14 +65,14 @@ typedef struct {
} GLdevdep;
static char *linestyle[] = {
"", /* solid */
"1", /* was 1 - dotted */
"", /* longdashed */
"3", /* shortdashed */
"4", /* longdotdashed */
"5", /* shortdotdashed */
"1"
};
"", /* solid */
"1", /* was 1 - dotted */
"", /* longdashed */
"3", /* shortdashed */
"4", /* longdotdashed */
"5", /* shortdotdashed */
"1"
};
static FILE *plotfile;
extern char psscale[32];
@ -84,6 +84,7 @@ static double tocm = 0.0025;
static double scale; /* Used for fine tuning */
static int hcopygraphid;
int GL_Init(void)
{
if (!cp_getvar("hcopyscale", CP_STRING, psscale)) {
@ -105,30 +106,28 @@ int GL_Init(void)
dispdev->minx = (int)(XOFF * 1.0);
dispdev->miny = (int)(YOFF * 1.0);
return(0);
return (0);
}
/* devdep initially contains name of output file */
int GL_NewViewport(
GRAPH *graph)
{
/* double scaleps, scalex, scaley; */
/* devdep initially contains name of output file */
int
GL_NewViewport(GRAPH *graph)
{
hcopygraphid = graph->graphid;
if ((plotfile = fopen((char*) graph->devdep, "w")) == NULL) {
perror((char*) graph->devdep);
graph->devdep = NULL;
return(1);
graph->devdep = NULL;
return (1);
}
if (graph->absolute.width) {
/* hardcopying from the screen */
/* hardcopying from the screen */
screenflag = 1;
screenflag = 1;
/* scale to fit on 8 1/2 square */
/* scale to fit on 8 1/2 square */
}
@ -147,13 +146,13 @@ GRAPH *graph)
/* start file off with a % */
fprintf(plotfile, "IN;DF;PA;");
fprintf(plotfile, "SI %f,%f;", tocm*jgmult*fontwidth*scale,tocm*jgmult*fontheight*scale);
fprintf(plotfile, "SI %f,%f;", tocm*jgmult*fontwidth*scale, tocm*jgmult*fontheight*scale);
#ifdef notdef
if (!screenflag)
#endif
graph->devdep = TMALLOC(GLdevdep, 1);
graph->devdep = TMALLOC(GLdevdep, 1);
DEVDEP(graph).lastlinestyle = -1;
DEVDEP(graph).lastx = -1;
DEVDEP(graph).lasty = -1;
@ -163,51 +162,52 @@ GRAPH *graph)
return 0;
}
int GL_Close(void)
{
int
GL_Close(void)
{
/* in case GL_Close is called as part of an abort,
w/o having reached GL_NewViewport */
w/o having reached GL_NewViewport */
if (plotfile) {
if (DEVDEP(currentgraph).lastlinestyle != -1) {
DEVDEP(currentgraph).linecount = 0;
}
fclose(plotfile);
plotfile = NULL;
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);
DestroyGraph(hcopygraphid);
currentgraph = FindGraph(1);
}
return 0;
}
int GL_Clear(void)
int
GL_Clear(void)
{
/* do nothing */
return 0;
}
int GL_DrawLine(
int x1, int y1, int x2, int y2)
{
int
GL_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 */
=> will have to give NewViewport a writeable graph XXX */
if (DEVDEP(currentgraph).linecount == 0
|| x1 != DEVDEP(currentgraph).lastx
|| y1 != DEVDEP(currentgraph).lasty)
|| x1 != DEVDEP(currentgraph).lastx
|| y1 != DEVDEP(currentgraph).lasty)
{
fprintf(plotfile, "PU;PA %d , %d ;", jgmult*(x1 + xoff), jgmult*(y1 + yoff));
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));
@ -221,10 +221,10 @@ int x1, int y1, int x2, int y2)
return 0;
}
/* ARGSUSED */
int GL_Arc(
int x0, int y0, int r,
double theta, double delta_theta)
int
GL_Arc(int x0, int y0, int r, double theta, double delta_theta)
{
int x1, y1, angle;
@ -241,14 +241,10 @@ double theta, double delta_theta)
return 0;
}
int GL_Text(
char *text,
int x, int y)
int
GL_Text(char *text, int x, int y)
{
/* int savedlstyle; */
/* move to (x, y) */
fprintf(plotfile, "PU;PA %d , %d;", jgmult*(x+xoff+XTADJ), jgmult*(y+yoff+YTADJ));
@ -257,49 +253,47 @@ int x, int y)
DEVDEP(currentgraph).lastx = -1;
DEVDEP(currentgraph).lasty = -1;
return 0;
}
int
GL_SetLinestyle(
int linestyleid)
{
int
GL_SetLinestyle(int linestyleid)
{
/* special case
get it when GL_Text restores a -1 linestyle */
get it when GL_Text restores a -1 linestyle */
if (linestyleid == -1) {
currentgraph->linestyle = -1;
return 0;
currentgraph->linestyle = -1;
return 0;
}
if (linestyleid < 0 || linestyleid > dispdev->numlinestyles) {
internalerror("bad linestyleid");
return 0;
internalerror("bad linestyleid");
return 0;
}
if (currentgraph->linestyle != linestyleid) {
fprintf(plotfile, "LT %s ;", linestyle[linestyleid]);
currentgraph->linestyle = linestyleid;
fprintf(plotfile, "LT %s ;", linestyle[linestyleid]);
currentgraph->linestyle = linestyleid;
}
return 0;
return 0;
}
/* ARGSUSED */
int GL_SetColor(
int colorid)
{
/*va: unused: static int flag = 0;*/ /* A hack */
/* ARGSUSED */
int
GL_SetColor(int colorid)
{
fprintf(plotfile, "SP %d;", colorid);
return 0;
}
int GL_Update(void)
{
int
GL_Update(void)
{
fflush(plotfile);
return 0;

View File

@ -381,7 +381,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
/* Ignore comment lines, but not lines begining with '*#',
but remove them, if they are in a .control ... .endc section */
s = dd->li_line;
while(isspace(*s))
while (isspace(*s))
s++;
if ((*s == '*') && ((s != dd->li_line) || (s[1] != '#'))) {
if (commands) {
@ -419,9 +419,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
fprintf(cp_err, "Warning: misplaced .endc card\n");
} else if (commands || prefix("*#", dd->li_line)) {
/* more control lines */
if (prefix("*#", dd->li_line))
if (prefix("*#", dd->li_line)) {
s = copy(dd->li_line + 2);
else {
} else {
s = dd->li_line;
dd->li_line = 0; /* SJB - prevent line_free() freeing the string (now pointed at by wl->wl_word) */
}
@ -430,14 +430,14 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
/* Look for set or unset numparams.
If either are found then we evaluate these lines immediately
so they take effect before netlist parsing */
while(isspace(*s)) /* step past any white space */
while (isspace(*s)) /* step past any white space */
s++;
if (ciprefix("set", s))
s += 3;
else if (ciprefix("unset", s))
s += 5;
if (s != dd->li_line) { /* one of the above must have matched */
while(isspace(*s)) /* step past white space */
while (isspace(*s)) /* step past white space */
s++;
if (ciprefix("numparams", s))
cp_evloop(wl->wl_word);
@ -834,8 +834,7 @@ inp_dodeck(
dd->li_linenum_orig, dd->li_line, dd->li_error);
if (ft_stricterror)
controlled_exit(EXIT_BAD);
}
else {
} else {
out_printf("%s\n", p);
}
@ -895,23 +894,23 @@ inp_dodeck(
ct->ci_filename = NULL;
if (!noparse) {
/* for (; options; options = options->li_next) {
for (s = options->li_line; *s && !isspace(*s); s++)
;
ii = cp_interactive;
cp_interactive = FALSE;
wl = cp_lexer(s);
cp_interactive = ii;
if (!wl || !wl->wl_word || !*wl->wl_word)
continue;
if (eev)
eev->va_next = cp_setparse(wl);
else
ct->ci_vars = eev = cp_setparse(wl);
while (eev->va_next)
eev = eev->va_next;
}
/*
* for (; options; options = options->li_next) {
* for (s = options->li_line; *s && !isspace(*s); s++)
* ;
* ii = cp_interactive;
* cp_interactive = FALSE;
* wl = cp_lexer(s);
* cp_interactive = ii;
* if (!wl || !wl->wl_word || !*wl->wl_word)
* continue;
* if (eev)
* eev->va_next = cp_setparse(wl);
* else
* ct->ci_vars = eev = cp_setparse(wl);
* while (eev->va_next)
* eev = eev->va_next;
* }
*/
for (eev = ct->ci_vars; eev; eev = eev->va_next) {
bool one = TRUE; /* FIXME, actually eev->va_bool should be TRUE anyway */
@ -1108,7 +1107,7 @@ com_source(wordlist *wl)
void
inp_source(char *file)
{
static struct wordlist wl = { NULL, NULL, NULL } ;
static struct wordlist wl = { NULL, NULL, NULL };
wl.wl_word = file;
com_source(&wl);
}

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,8 @@
#include "com_commands.h"
#include "com_display.h"
static wordlist *measure_parse_line( char *line ) ;
static wordlist *measure_parse_line(char *line);
static bool measure_valid[20000];/* TRUE: if measurement no. [xxx] has been done successfully
(not used anywhere)*/
@ -31,6 +32,7 @@ static bool measures_passed; /* TRUE: stop simulation (if option autostop is set
extern bool ft_batchmode;
extern bool rflag;
/* measure in interactive mode:
meas command inside .control ... .endc loop or manually entered.
meas has to be followed by the standard tokens (see measure_extract_variables()).
@ -42,12 +44,12 @@ com_meas(wordlist *wl)
{
/* wl: in, input line of meas command */
char *line_in, *outvar, newvec[1000];
wordlist * wl_count, *wl_let;
wordlist *wl_count, *wl_let;
char *vec_found, *token, *equal_ptr, newval[256];
wordlist *wl_index;
struct dvec *d;
int err=0;
int err = 0;
int fail;
double result = 0;
@ -65,22 +67,22 @@ com_meas(wordlist *wl)
treated in com_measure2.c. */
wl_index = wl;
while ( wl_index) {
while (wl_index) {
token = wl_index->wl_word;
/* find the vector vec_found, next token after each '=' sign.
May be in the next wl_word */
if ( *(token + strlen(token) - 1) == '=' ) {
if (*(token + strlen(token) - 1) == '=') {
wl_index = wl_index->wl_next;
vec_found = wl_index->wl_word;
/* token may be already a value, maybe 'LAST', which we have to keep, or maybe a vector */
if (!cieq(vec_found, "LAST")) {
INPevaluate( &vec_found, &err, 1 );
INPevaluate(&vec_found, &err, 1);
/* if not a valid number */
if (err) {
/* check if vec_found is a valid vector */
d = vec_get(vec_found);
/* Only if we have a single valued vector, replacing
of the rigt hand side does make sense */
of the rigt hand side does make sense */
if (d && (d->v_length == 1) && (d->v_numdims == 1)) {
/* get its value */
sprintf(newval, "%e", d->v_realdata[0]);
@ -91,10 +93,10 @@ com_meas(wordlist *wl)
}
}
/* may be inside the same wl_word */
else if ( (equal_ptr = strstr( token, "=" )) != NULL ) {
else if ((equal_ptr = strstr(token, "=")) != NULL) {
vec_found = equal_ptr + 1;
if (!cieq(vec_found, "LAST")) {
INPevaluate( &vec_found, &err, 1 );
INPevaluate(&vec_found, &err, 1);
if (err) {
d = vec_get(vec_found);
/* Only if we have a single valued vector, replacing
@ -102,14 +104,14 @@ com_meas(wordlist *wl)
if (d && (d->v_length == 1) && (d->v_numdims == 1)) {
*equal_ptr = '\0';
sprintf(newval, "%s=%e", token, d->v_realdata[0]);
// memory leak with first part of vec_found ?
// memory leak with first part of vec_found ?
tfree(token);
wl_index->wl_word = copy(newval);
}
}
}
} else {
;// nothing
; // nothing
}
wl_index = wl_index->wl_next;
}
@ -126,7 +128,7 @@ com_meas(wordlist *wl)
}
outvar = wl_count->wl_word;
fail = get_measure2(wl, &result, NULL, FALSE) ;
fail = get_measure2(wl, &result, NULL, FALSE);
if (fail) {
fprintf(stdout, " meas %s failed!\n\n", line_in);
@ -137,19 +139,21 @@ com_meas(wordlist *wl)
wl_let = wl_cons(copy(newvec), NULL);
com_let(wl_let);
wl_free(wl_let);
// fprintf(stdout, "in: %s\n", line_in);
// fprintf(stdout, "in: %s\n", line_in);
}
static bool
chkAnalysisType( char *an_type )
chkAnalysisType(char *an_type)
{
/* only support tran, dc, ac, sp analysis type for now */
if ( strcmp( an_type, "tran" ) != 0 && strcmp( an_type, "ac" ) != 0 &&
strcmp( an_type, "dc" ) != 0 && strcmp( an_type, "sp" ) != 0)
if (strcmp(an_type, "tran") != 0 && strcmp(an_type, "ac") != 0 &&
strcmp(an_type, "dc") != 0 && strcmp(an_type, "sp") != 0)
return FALSE;
// else if (ft_batchmode == TRUE) return FALSE;
else return TRUE;
// else if (ft_batchmode == TRUE)
// return FALSE;
else
return TRUE;
}
@ -165,29 +169,31 @@ get_double_value(
char *token = gettok(line);
bool return_val = TRUE;
char *equal_ptr, *junk;
int err=0;
int err = 0;
if ( name && ( strncmp( token, name, strlen(name) ) != 0 ) ) {
if ( just_chk_meas != TRUE ) fprintf( cp_err, "Error: syntax error for measure statement; expecting next field to be '%s'.\n", name );
if (name && (strncmp(token, name, strlen(name)) != 0)) {
if (just_chk_meas != TRUE) fprintf(cp_err, "Error: syntax error for measure statement; expecting next field to be '%s'.\n", name);
return_val = FALSE;
} else {
/* see if '=' is last char of current token -- implies we need to read value in next token */
if ( *(token + strlen(token) - 1) == '=' ) {
if (*(token + strlen(token) - 1) == '=') {
txfree(token);
junk = token = gettok(line);
*value = INPevaluate( &junk, &err, 1 );
*value = INPevaluate(&junk, &err, 1);
} else {
if ( (equal_ptr = strstr( token, "=" )) != NULL ) {
if ((equal_ptr = strstr(token, "=")) != NULL) {
equal_ptr += 1;
*value = INPevaluate( &equal_ptr, &err, 1 );
*value = INPevaluate(&equal_ptr, &err, 1);
} else {
if ( just_chk_meas != TRUE ) fprintf( cp_err, "Error: syntax error for measure statement; missing '='!\n" );
if (just_chk_meas != TRUE)
fprintf(cp_err, "Error: syntax error for measure statement; missing '='!\n");
return_val = FALSE;
}
}
if ( err ) {
if ( just_chk_meas != TRUE ) fprintf( cp_err, "Error: Bad value.\n" );
if (err) {
if (just_chk_meas != TRUE)
fprintf(cp_err, "Error: Bad value.\n");
return_val = FALSE;
}
}
@ -213,17 +219,17 @@ do_measure(
struct line *meas_card, *meas_results = NULL, *end = NULL, *newcard;
char *line, *an_name, *an_type, *resname, *meastype, *str_ptr, out_line[1000];
int idx = 0, ok = 0;
int fail;
int fail;
double result = 0;
bool first_time = TRUE;
wordlist *measure_word_list ;
int precision = measure_get_precision() ;
wordlist *measure_word_list;
int precision = measure_get_precision();
just_chk_meas = chk_only;
an_name = strdup( what ); /* analysis type, e.g. "tran" */
strtolower( an_name );
measure_word_list = NULL ;
an_name = strdup(what); /* analysis type, e.g. "tran" */
strtolower(an_name);
measure_word_list = NULL;
/* don't allow .meas if batchmode is set by -b and -r rawfile given */
if (ft_batchmode && rflag) {
@ -248,7 +254,7 @@ do_measure(
*/
/* first pass through .meas cards: evaluate everything except param|expr */
for ( meas_card = ft_curckt->ci_meas; meas_card != NULL; meas_card = meas_card->li_next ) {
for (meas_card = ft_curckt->ci_meas; meas_card != NULL; meas_card = meas_card->li_next) {
line = meas_card->li_line;
txfree(gettok(&line)); /* discard .meas */
@ -257,10 +263,10 @@ do_measure(
resname = gettok(&line);
meastype = gettok(&line);
if ( chkAnalysisType( an_type ) != TRUE ) {
if ( just_chk_meas != TRUE ) {
fprintf( cp_err, "Error: unrecognized analysis type '%s' for the following .meas statement on line %d:\n", an_type, meas_card->li_linenum );
fprintf( cp_err, " %s\n", meas_card->li_line );
if (chkAnalysisType(an_type) != TRUE) {
if (just_chk_meas != TRUE) {
fprintf(cp_err, "Error: unrecognized analysis type '%s' for the following .meas statement on line %d:\n", an_type, meas_card->li_linenum);
fprintf(cp_err, " %s\n", meas_card->li_line);
}
txfree(an_type);
@ -269,20 +275,21 @@ do_measure(
continue;
}
/* print header before evaluating first .meas line */
else if ( first_time ) {
else if (first_time) {
first_time = FALSE;
if ( just_chk_meas != TRUE && strcmp( an_type, "tran" ) == 0 ) {
fprintf( stdout, " Transient Analysis\n\n" );
// plot_cur = setcplot("tran");
if (just_chk_meas != TRUE && strcmp(an_type, "tran") == 0) {
fprintf(stdout, " Transient Analysis\n\n");
// plot_cur = setcplot("tran");
}
}
/* skip param|expr measurement types for now -- will be done after other measurements */
if ( strncmp( meastype, "param", 5 ) == 0 || strncmp( meastype, "expr", 4 ) == 0 ) continue;
if (strncmp(meastype, "param", 5) == 0 || strncmp(meastype, "expr", 4) == 0)
continue;
/* skip .meas line, if analysis type from line and name of analysis performed differ */
if ( strcmp( an_name, an_type ) != 0 ) {
if (strcmp(an_name, an_type) != 0) {
txfree(an_type);
txfree(resname);
txfree(meastype);
@ -291,22 +298,21 @@ do_measure(
/* New way of processing measure statements using common code
in fcn get_measure2() (com_measure2.c)*/
out_line[0] = '\0' ;
measure_word_list = measure_parse_line( meas_card->li_line) ;
if( measure_word_list ) {
fail = get_measure2(measure_word_list,&result,out_line,chk_only) ;
if( fail ) {
out_line[0] = '\0';
measure_word_list = measure_parse_line(meas_card->li_line);
if (measure_word_list) {
fail = get_measure2(measure_word_list, &result, out_line, chk_only);
if (fail) {
measure_valid[idx++] = FALSE;
measures_passed = FALSE;
if (!chk_only)
fprintf(stderr, " %s failed!\n\n", meas_card->li_line);
} else {
if(!(just_chk_meas)) {
nupa_add_param( resname, result );
}
if (!(just_chk_meas))
nupa_add_param(resname, result);
measure_valid[idx++] = TRUE;
}
wl_free( measure_word_list ) ;
wl_free(measure_word_list);
} else {
measure_valid[idx++] = FALSE;
measures_passed = FALSE;
@ -316,8 +322,9 @@ do_measure(
newcard->li_line = strdup(out_line);
newcard->li_next = NULL;
if ( meas_results == NULL ) meas_results = end = newcard;
else {
if (meas_results == NULL) {
meas_results = end = newcard;
} else {
end->li_next = newcard;
end = newcard;
}
@ -327,8 +334,8 @@ do_measure(
txfree(meastype);
/* see if number of measurements exceeds fixed array size of 20,000 */
if ( idx >= 20000 ) {
fprintf( stderr, "ERROR: number of measurements exceeds 20,000!\nAborting...\n" );
if (idx >= 20000) {
fprintf(stderr, "ERROR: number of measurements exceeds 20,000!\nAborting...\n");
controlled_exit(EXIT_FAILURE);
}
@ -337,7 +344,7 @@ do_measure(
/* second pass through .meas cards: now do param|expr .meas statements */
newcard = meas_results;
for ( meas_card = ft_curckt->ci_meas; meas_card != NULL; meas_card = meas_card->li_next ) {
for (meas_card = ft_curckt->ci_meas; meas_card != NULL; meas_card = meas_card->li_next) {
line = meas_card->li_line;
txfree(gettok(&line)); /* discard .meas */
@ -346,10 +353,10 @@ do_measure(
resname = gettok(&line);
meastype = gettok(&line);
if ( chkAnalysisType( an_type ) != TRUE ) {
if ( just_chk_meas != TRUE ) {
fprintf( cp_err, "Error: unrecognized analysis type '%s' for the following .meas statement on line %d:\n", an_type, meas_card->li_linenum );
fprintf( cp_err, " %s\n", meas_card->li_line );
if (chkAnalysisType(an_type) != TRUE) {
if (just_chk_meas != TRUE) {
fprintf(cp_err, "Error: unrecognized analysis type '%s' for the following .meas statement on line %d:\n", an_type, meas_card->li_linenum);
fprintf(cp_err, " %s\n", meas_card->li_line);
}
txfree(an_type);
@ -357,21 +364,22 @@ do_measure(
txfree(meastype);
continue;
}
if ( strcmp( an_name, an_type ) != 0 ) {
if (strcmp(an_name, an_type) != 0) {
txfree(an_type);
txfree(resname);
txfree(meastype);
continue;
}
if ( strncmp( meastype, "param", 5 ) != 0 && strncmp( meastype, "expr", 4 ) != 0 ) {
if (strncmp(meastype, "param", 5) != 0 && strncmp(meastype, "expr", 4) != 0) {
if ( just_chk_meas != TRUE ) fprintf( stdout, "%s", newcard->li_line );
if (just_chk_meas != TRUE)
fprintf(stdout, "%s", newcard->li_line);
end = newcard;
newcard = newcard->li_next;
txfree( end->li_line );
txfree( end );
txfree(end->li_line);
txfree(end);
txfree(an_type);
txfree(resname);
@ -379,21 +387,25 @@ do_measure(
continue;
}
if ( just_chk_meas != TRUE ) fprintf( stdout, "%-20s=", resname );
if (just_chk_meas != TRUE)
fprintf(stdout, "%-20s=", resname);
if ( just_chk_meas != TRUE ) {
ok = nupa_eval( meas_card->li_line, meas_card->li_linenum, meas_card->li_linenum_orig );
if (just_chk_meas != TRUE) {
ok = nupa_eval(meas_card->li_line, meas_card->li_linenum, meas_card->li_linenum_orig);
if ( ok ) {
str_ptr = strstr( meas_card->li_line, meastype );
if ( !get_double_value( &str_ptr, meastype, &result ) ) {
if ( just_chk_meas != TRUE ) fprintf( stdout, " failed\n" );
if (ok) {
str_ptr = strstr(meas_card->li_line, meastype);
if (!get_double_value(&str_ptr, meastype, &result)) {
if (just_chk_meas != TRUE)
fprintf(stdout, " failed\n");
} else {
if ( just_chk_meas != TRUE ) fprintf( stdout, " %.*e\n", precision, result );
nupa_add_param( resname, result );
if (just_chk_meas != TRUE)
fprintf(stdout, " %.*e\n", precision, result);
nupa_add_param(resname, result);
}
} else {
if ( just_chk_meas != TRUE ) fprintf( stdout, " failed\n" );
if (just_chk_meas != TRUE)
fprintf(stdout, " failed\n");
}
}
txfree(an_type);
@ -401,11 +413,12 @@ do_measure(
txfree(meastype);
}
if ( just_chk_meas != TRUE ) fprintf( stdout, "\n" );
if (just_chk_meas != TRUE)
fprintf(stdout, "\n");
txfree(an_name);
fflush( stdout );
fflush(stdout);
//nupa_list_params();
}
@ -418,55 +431,57 @@ do_measure(
set to FALSE during calling do_measure. 'what' is set to "tran".*/
bool
check_autostop( char* what )
check_autostop(char* what)
{
bool flag = FALSE;
measures_passed = TRUE;
if ( cp_getvar( "autostop", CP_BOOL, NULL) ) {
do_measure( what, TRUE );
if (cp_getvar("autostop", CP_BOOL, NULL)) {
do_measure(what, TRUE);
if ( measures_passed == TRUE ) flag = TRUE;
if (measures_passed == TRUE)
flag = TRUE;
}
return flag;
}
/* parses the .meas line into a wordlist (without leading .meas) */
static wordlist *measure_parse_line( char *line )
{
size_t len ; /* length of string */
wordlist *wl ; /* build a word list - head of list */
wordlist *new_item ; /* single item of a list */
char *item ; /* parsed item */
char *long_str ; /* concatenated string */
char *extra_item ; /* extra item */
wl = NULL ;
(void) gettok(&line) ;
/* parses the .meas line into a wordlist (without leading .meas) */
static wordlist *
measure_parse_line(char *line)
{
size_t len; /* length of string */
wordlist *wl; /* build a word list - head of list */
wordlist *new_item; /* single item of a list */
char *item; /* parsed item */
char *long_str; /* concatenated string */
char *extra_item; /* extra item */
wl = NULL;
(void) gettok(&line);
do {
item = gettok(&line) ;
if(!(item)) {
break ;
}
len = strlen(item) ;
if( item[len-1] == '=' ) {
item = gettok(&line);
if (!(item))
break;
len = strlen(item);
if (item[len-1] == '=') {
/* We can't end on an equal append the next piece */
extra_item = gettok(&line) ;
if(!(extra_item)) {
break ;
}
len += strlen( extra_item ) + 2 ;
long_str = TMALLOC(char, len) ;
sprintf( long_str, "%s%s", item, extra_item ) ;
txfree( item ) ;
txfree( extra_item ) ;
item = long_str ;
extra_item = gettok(&line);
if (!(extra_item))
break;
len += strlen(extra_item) + 2;
long_str = TMALLOC(char, len);
sprintf(long_str, "%s%s", item, extra_item);
txfree(item);
txfree(extra_item);
item = long_str;
}
new_item = wl_cons(item, NULL);
wl = wl_append(wl, new_item) ;
} while( line && *line ) ;
wl = wl_append(wl, new_item);
} while (line && *line);
return(wl) ;
} /* end measure_parse_line() */
return (wl);
}

View File

@ -49,7 +49,7 @@ com_quit(wordlist *wl)
/* Make sure the guy really wants to quit. */
if (!ft_nutmeg)
if(!noask && !confirm_quit())
if (!noask && !confirm_quit())
return;
/* start to clean up the mess */
@ -65,7 +65,7 @@ com_quit(wordlist *wl)
if (!ft_nutmeg) {
struct circ *cc;
for (cc = ft_circuits; cc; cc = cc->ci_next)
if(SIMinfo.deleteCircuit)
if (SIMinfo.deleteCircuit)
SIMinfo.deleteCircuit(cc->ci_ckt);
}
#endif
@ -167,7 +167,7 @@ com_version(wordlist *wl)
fprintf(cp_out, "** Creation Date: %s\n", Spice_Build_Date);
fprintf(cp_out, "******\n");
} else if (!strncasecmp(s, "-f", 2)) {
} else if (!strncasecmp(s, "-f", 2)) {
fprintf(cp_out,
"******\n"
@ -307,5 +307,5 @@ confirm_quit(void)
*buf = 'y';
}
return((*buf == 'y') || (*buf == 'Y') || (*buf == '\n'));
return ((*buf == 'y') || (*buf == 'Y') || (*buf == '\n'));
}

View File

@ -15,200 +15,205 @@ Copyright 1992 Regents of the University of California. All rights reserved.
#include "newcoms.h"
#include "quote.h"
/*
* reshape v(1) vxx#branch [10]
* reshape v(1) vxx#branch [10,4]
* reshape v(1) [,4]
* reshape v(1) vxx#branch [10]
* reshape v(1) vxx#branch [10,4]
* reshape v(1) [,4]
*/
void
com_reshape(wordlist *wl)
{
wordlist *w, *w2, *wlast, *wsave;
char *p;
struct dvec *dv, *d;
int numdims;
int *dims;
int local_dims[MAXDIMS];
int state;
int empty;
int err;
int missing, nprod, prod;
char *vname;
int i;
wordlist *w, *w2, *wlast, *wsave;
char *p;
struct dvec *dv, *d;
int numdims;
int *dims;
int local_dims[MAXDIMS];
int state;
int empty;
int err;
int missing, nprod, prod;
char *vname;
int i;
do {
if (!wl)
return;
if (!wl)
return;
/* find the first '[' */
/* find the first '[' */
p = NULL;
for (w = wl; w; w = w->wl_next) {
if ((p = strchr(w->wl_word, '[')) != NULL)
break;
}
p = NULL;
for (w = wl; w; w = w->wl_next) {
if ((p = strchr(w->wl_word, '[')) != NULL)
break;
}
if (p && *p) {
if (p != w->wl_word)
w = w->wl_next;
wlast = w;
*p++ = 0;
} else
wlast = NULL;
if (p && *p) {
if (p != w->wl_word)
w = w->wl_next;
wlast = w;
*p++ = 0;
} else {
wlast = NULL;
}
/* get the dimensions */
dims = local_dims;
numdims = 0;
state = 0;
empty = -1;
err = 0;
wsave = NULL;
do {
/* get the dimensions */
dims = local_dims;
numdims = 0;
state = 0;
empty = -1;
err = 0;
wsave = NULL;
do {
if (!p || !*p) {
if (!wlast)
break;
p = wlast->wl_word;
if (state == 2)
wsave = wlast;
else
wsave = NULL;
wlast = wlast->wl_next;
}
if (!p || !*p) {
if (!wlast)
break;
p = wlast->wl_word;
if (state == 2)
wsave = wlast;
else
wsave = NULL;
wlast = wlast->wl_next;
}
while (*p && isspace(*p))
p++;
while (*p && isspace(*p))
p++;
switch (state) {
case 0: /* p just at or before a number */
switch (state) {
case 0: /* p just at or before a number */
if (numdims >= MAXDIMS) {
if (numdims == MAXDIMS)
printf("Maximum of %d dimensions possible\n", MAXDIMS);
numdims += 1;
} else if (!isdigit(*p)) {
if (empty > -1) {
printf("dimensions underspecified at dimension %d\n",
numdims++);
err = 1;
} else {
empty = numdims;
dims[numdims++] = 1;
}
} else {
dims[numdims++] = atoi(p);
while (isdigit(*p))
p++;
}
state = 1;
break;
if (numdims >= MAXDIMS) {
if (numdims == MAXDIMS)
printf("Maximum of %d dimensions possible\n", MAXDIMS);
numdims += 1;
} else if (!isdigit(*p)) {
if (empty > -1) {
printf("dimensions underspecified at dimension %d\n",
numdims++);
err = 1;
} else {
empty = numdims;
dims[numdims++] = 1;
}
} else {
dims[numdims++] = atoi(p);
while (isdigit(*p))
p++;
}
state = 1;
break;
case 1: /* p after a number, looking for ',' or ']' */
if (*p == ']') {
p++;
state = 2;
} else if (*p == ',') {
p++;
state = 0;
} else if (isdigit(*p)) {
state = 0;
break;
} else if (!isspace(*p))
/* error */
state = 4;
break;
case 1: /* p after a number, looking for ',' or ']' */
if (*p == ']') {
p++;
state = 2;
} else if (*p == ',') {
p++;
state = 0;
} else if (isdigit(*p)) {
state = 0;
break;
} else if (!isspace(*p)) {
/* error */
state = 4;
}
break;
case 2: /* p after a ']', either at the end or looking for '[' */
if (*p == '[') {
p++;
state = 0;
} else {
state = 3;
}
}
case 2: /* p after a ']', either at the end or looking for '[' */
if (*p == '[') {
p++;
state = 0;
} else {
state = 3;
}
}
while (*p && isspace(*p))
p++;
while (*p && isspace(*p))
p++;
} while (state < 3);
} while (state < 3);
if (state == 2) {
wlast = wsave;
} else if ((state == 4 || state < 2) && ((state != 0 || p) && *p)) {
printf("syntax error specifying dimensions\n");
return;
}
if (state == 2) {
wlast = wsave;
} else if ((state == 4 || state < 2) && ((state != 0 || p) && *p)) {
printf("syntax error specifying dimensions\n");
return;
}
if (numdims > MAXDIMS)
continue;
if (err)
continue;
if (numdims > MAXDIMS)
continue;
if (err)
continue;
/* Copy dimensions from the first item if none are explicitly given */
if (!numdims) {
/* Copy from the first */
vname = cp_unquote(wl->wl_word);
dv = vec_get(vname);
if (!dv) {
printf("'%s' dimensions vector not found\n", vname);
return;
}
numdims = dv->v_numdims;
dims = dv->v_dims;
wl = wl->wl_next;
empty = -1; /* just in case */
}
/* Copy dimensions from the first item if none are explicitly given */
if (!numdims) {
/* Copy from the first */
vname = cp_unquote(wl->wl_word);
dv = vec_get(vname);
if (!dv) {
printf("'%s' dimensions vector not found\n", vname);
return;
}
numdims = dv->v_numdims;
dims = dv->v_dims;
wl = wl->wl_next;
empty = -1; /* just in case */
}
prod = 1;
for (i = 0; i < numdims; i++)
prod *= dims[i];
prod = 1;
for (i = 0; i < numdims; i++)
prod *= dims[i];
/* resize each vector */
for (w2 = wl; w2 && w2 != w; w2 = w2->wl_next) {
vname = cp_unquote(w2->wl_word);
/* resize each vector */
for (w2 = wl; w2 && w2 != w; w2 = w2->wl_next) {
vname = cp_unquote(w2->wl_word);
dv = vec_get(vname);
if (!dv) {
printf("'%s' vector not found\n", vname);
continue;
}
dv = vec_get(vname);
if (!dv) {
printf("'%s' vector not found\n", vname);
continue;
}
/* The name may expand to several vectors */
for (d = dv; d; d = d->v_link2) {
nprod = 1;
for (i = 0; i < d->v_numdims; i++)
nprod *= d->v_dims[i];
if (nprod != d->v_length) {
printf("dimensions of \"%s\" were inconsistent\n",
d->v_name);
nprod = d->v_length;
}
/* The name may expand to several vectors */
for (d = dv; d; d = d->v_link2) {
nprod = 1;
for (i = 0; i < d->v_numdims; i++)
nprod *= d->v_dims[i];
if (nprod != d->v_length) {
printf("dimensions of \"%s\" were inconsistent\n",
d->v_name);
nprod = d->v_length;
}
missing = nprod / prod;
if (missing * prod != nprod) {
printf("dimensions don't fit \"%s\" (total size = %d)\n",
d->v_name, nprod);
continue;
}
missing = nprod / prod;
if (missing * prod != nprod) {
printf("dimensions don't fit \"%s\" (total size = %d)\n",
d->v_name, nprod);
continue;
}
if (missing > 1 && empty < 0) {
/* last dimension unspecified */
d->v_numdims = numdims + 1;
d->v_dims[numdims] = missing;
} else
d->v_numdims = numdims;
if (missing > 1 && empty < 0) {
/* last dimension unspecified */
d->v_numdims = numdims + 1;
d->v_dims[numdims] = missing;
} else {
d->v_numdims = numdims;
}
/* fill in dimensions */
for (i = 0; i < numdims; i++) {
if (i == empty)
d->v_dims[i] = missing;
else
d->v_dims[i] = dims[i];
}
}
if (vname)
tfree(vname);
}
/* fill in dimensions */
for (i = 0; i < numdims; i++) {
if (i == empty)
d->v_dims[i] = missing;
else
d->v_dims[i] = dims[i];
}
}
if (vname)
tfree(vname);
}
} while ((wl = wlast) != NULL);
}

View File

@ -1,8 +1,8 @@
/* general.h */
/*
include beforehand the following:
#include <stdio.h> // NULL FILE fopen feof fgets fclose fputs fputc gets
#include <stdlib.h>
#include <stdio.h> // NULL FILE fopen feof fgets fclose fputs fputc gets
#include <stdlib.h>
the function code is in 'mystring.c' .
*/
#include "ngspice/dstring.h"
@ -12,26 +12,26 @@
typedef char string[258];
void sfix( SPICE_DSTRINGPTR dstr_p, int len) ;
char * pscopy( SPICE_DSTRINGPTR s, char * a, int i,int j);
char * pscopy_up( SPICE_DSTRINGPTR s, char * a, int i,int j);
bool scopyd( SPICE_DSTRINGPTR a, SPICE_DSTRINGPTR b);
bool scopys( SPICE_DSTRINGPTR a, char *b);
bool scopy_up( SPICE_DSTRINGPTR a, char *str) ;
bool scopy_lower( SPICE_DSTRINGPTR a, char *str) ;
bool ccopy( SPICE_DSTRINGPTR a, char c);
bool sadd( SPICE_DSTRINGPTR s, char * t);
bool nadd( SPICE_DSTRINGPTR s, long n);
bool cadd( SPICE_DSTRINGPTR s, char c);
bool naddll( SPICE_DSTRINGPTR s, long long n);
bool cins( SPICE_DSTRINGPTR s, char c);
bool sins( SPICE_DSTRINGPTR s, char * t);
int cpos( char c, char *s);
int spos_( char * sub, char * s);
bool ci_prefix( register char *p, register char *s );
int length(char * s);
bool steq(char * s, char * t);
bool stne(char * s, char * t);
void sfix(SPICE_DSTRINGPTR dstr_p, int len);
char *pscopy(SPICE_DSTRINGPTR s, char *a, int i, int j);
char *pscopy_up(SPICE_DSTRINGPTR s, char *a, int i, int j);
bool scopyd(SPICE_DSTRINGPTR a, SPICE_DSTRINGPTR b);
bool scopys(SPICE_DSTRINGPTR a, char *b);
bool scopy_up(SPICE_DSTRINGPTR a, char *str);
bool scopy_lower(SPICE_DSTRINGPTR a, char *str);
bool ccopy(SPICE_DSTRINGPTR a, char c);
bool sadd(SPICE_DSTRINGPTR s, char *t);
bool nadd(SPICE_DSTRINGPTR s, long n);
bool cadd(SPICE_DSTRINGPTR s, char c);
bool naddll(SPICE_DSTRINGPTR s, long long n);
bool cins(SPICE_DSTRINGPTR s, char c);
bool sins(SPICE_DSTRINGPTR s, char *t);
int cpos(char c, char *s);
int spos_(char *sub, char *s);
bool ci_prefix(register char *p, register char *s);
int length(char *s);
bool steq(char *s, char *t);
bool stne(char *s, char *t);
void stri(long n, SPICE_DSTRINGPTR s);
char upcase(char c);
@ -39,18 +39,18 @@ char lowcase(char c);
bool alfa(char c);
bool num(char c);
bool alfanum(char c);
char * stupcase( char * s);
char *stupcase(char *s);
/***** primitive input-output ***/
void rs( SPICE_DSTRINGPTR s);
void rs(SPICE_DSTRINGPTR s);
char rc(void);
int freadstr(FILE * f, SPICE_DSTRINGPTR dstr_p);
int freadstr(FILE *f, SPICE_DSTRINGPTR dstr_p);
long np_round(double d); // sjb to avoid clash with round() in math.h
long np_trunc(double x); // sjb to avoid clash with trunc() in math.h
double absf(double x); /* abs */
long absi( long i);
long absi(long i);
void * new(size_t sz);
void dispose(void * p);
void *new(size_t sz);
void dispose(void *p);

View File

@ -21,33 +21,35 @@
#include "ngspice/fteext.h" /* controlled_exit() */
/***** primitive input-output ***/
bool
ci_prefix (register char *p, register char *s)
ci_prefix(register char *p, register char *s)
{
while (*p)
{
if ((isupper (*p) ? tolower (*p) : *p) !=
(isupper (*s) ? tolower (*s) : *s))
while (*p) {
if ((isupper(*p) ? tolower(*p) : *p) !=
(isupper(*s) ? tolower(*s) : *s))
return (0);
p++;
s++;
}
return (1);
}
void
rs ( SPICE_DSTRINGPTR dstr_p)
rs(SPICE_DSTRINGPTR dstr_p)
{
/* basic line input, limit= 80 chars */
char c;
spice_dstring_reinit(dstr_p) ;
spice_dstring_reinit(dstr_p);
do
{
c = (char) fgetc (stdin);
cadd (dstr_p, c);
c = (char) fgetc(stdin);
cadd(dstr_p, c);
}
while (!((c == '\r') || (c == '\n')));
}
@ -71,7 +73,7 @@ rs ( SPICE_DSTRINGPTR dstr_p)
*/
void
sfix ( SPICE_DSTRINGPTR dstr_p, int len)
sfix(SPICE_DSTRINGPTR dstr_p, int len)
/* suppose s is allocated and filled with non-zero stuff */
{
/* This function will now eliminate the max field. The length of
@ -80,90 +82,94 @@ sfix ( SPICE_DSTRINGPTR dstr_p, int len)
* null characters will be present in the string leading up to the
* NULL so this will make it a valid string. */
int j;
char *s ;
char *s;
spice_dstring_setlength( dstr_p, len ) ;
s = spice_dstring_value( dstr_p ) ;
for (j = 0; j < len; j++) /* eliminate null characters ! */
spice_dstring_setlength(dstr_p, len);
s = spice_dstring_value(dstr_p);
for (j = 0; j < len; j++) /* eliminate null characters ! */
if (s[j] == 0)
s[j] = 1;
}
int
length (char *s)
length(char *s)
{
return (int) strlen(s);
}
/* -----------------------------------------------------------------
* Function: add string t to dynamic string dstr_p.
* ----------------------------------------------------------------- */
bool
sadd ( SPICE_DSTRINGPTR dstr_p, char *t)
sadd(SPICE_DSTRINGPTR dstr_p, char *t)
{
spice_dstring_append( dstr_p, t, -1 ) ;
return 1 ;
spice_dstring_append(dstr_p, t, -1);
return 1;
}
/* -----------------------------------------------------------------
* Function: add character c to dynamic string dstr_p.
* ----------------------------------------------------------------- */
bool
cadd ( SPICE_DSTRINGPTR dstr_p, char c)
cadd(SPICE_DSTRINGPTR dstr_p, char c)
{
char tmp_str[2] ;
tmp_str[0] = c ;
tmp_str[1] = '\0' ;
spice_dstring_append( dstr_p, tmp_str, -1 ) ;
return 1 ;
char tmp_str[2];
tmp_str[0] = c;
tmp_str[1] = '\0';
spice_dstring_append(dstr_p, tmp_str, -1);
return 1;
}
/* -----------------------------------------------------------------
* Function: insert character c at front of dynamic string dstr_p
* ----------------------------------------------------------------- */
bool
cins ( SPICE_DSTRINGPTR dstr_p, char c)
cins(SPICE_DSTRINGPTR dstr_p, char c)
{
int i ;
int ls ;
char *s_p ;
int i;
int ls;
char *s_p;
ls = spice_dstring_length(dstr_p) ;
spice_dstring_setlength(dstr_p,ls+2) ; /* make sure we have space for char + EOS */
s_p = spice_dstring_value(dstr_p) ;
ls = spice_dstring_length(dstr_p);
spice_dstring_setlength(dstr_p, ls+2); /* make sure we have space for char + EOS */
s_p = spice_dstring_value(dstr_p);
for (i = ls + 1; i >= 0; i--)
s_p[i + 1] = s_p[i];
s_p[0] = c;
return 1 ;
return 1;
}
/* -----------------------------------------------------------------
* Function: insert string t at front of dynamic string dstr_p
* ----------------------------------------------------------------- */
bool
sins ( SPICE_DSTRINGPTR dstr_p, char *t)
sins(SPICE_DSTRINGPTR dstr_p, char *t)
{
int i ;
int ls ;
int lt ;
char *s_p ;
int i;
int ls;
int lt;
char *s_p;
ls = spice_dstring_length(dstr_p) ;
lt = length (t) ;
spice_dstring_setlength(dstr_p,ls+lt+1) ; /* make sure we have space for string + EOS */
s_p = spice_dstring_value(dstr_p) ;
ls = spice_dstring_length(dstr_p);
lt = length(t);
spice_dstring_setlength(dstr_p, ls+lt+1); /* make sure we have space for string + EOS */
s_p = spice_dstring_value(dstr_p);
for (i = ls + 1; i >= 0; i--)
s_p[i + lt] = s_p[i];
for (i = 0; i < lt; i++)
s_p[i] = t[i];
return 1 ;
return 1;
}
int
cpos (char c, char *s)
cpos(char c, char *s)
/* return position of c in s, or 0 if not found.
* BUG, Pascal inherited: first char is at 1, not 0 !
* No longer! Now position is C-based to make life easier.
@ -174,13 +180,14 @@ cpos (char c, char *s)
i++;
if (s[i] == c)
return i ;
return i;
else
return -1 ;
return -1;
}
char
upcase (char c)
upcase(char c)
{
if ((c >= 'a') && (c <= 'z'))
return (char) (c + 'A' - 'a');
@ -188,256 +195,265 @@ upcase (char c)
return c;
}
/* -----------------------------------------------------------------
* Create copy of the dynamic string. Dynamic strings are always NULL
* terminated.
* ----------------------------------------------------------------- */
bool
scopyd(SPICE_DSTRINGPTR s, SPICE_DSTRINGPTR t) /* returns success flag */
scopyd(SPICE_DSTRINGPTR s, SPICE_DSTRINGPTR t) /* returns success flag */
{
spice_dstring_reinit( s ) ;
spice_dstring_append( s, spice_dstring_value(t), -1 ) ;
return 1 ; /* Dstrings expand to any length */
spice_dstring_reinit(s);
spice_dstring_append(s, spice_dstring_value(t), -1);
return 1; /* Dstrings expand to any length */
}
/* -----------------------------------------------------------------
* Create copy of the string in the dynamic string. Dynamic strings
* are always NULLterminated.
* ----------------------------------------------------------------- */
bool
scopys(SPICE_DSTRINGPTR s, char *t) /* returns success flag */
scopys(SPICE_DSTRINGPTR s, char *t) /* returns success flag */
{
spice_dstring_reinit( s ) ;
spice_dstring_append( s, t, -1 ) ;
return 1 ; /* Dstrings expand to any length */
spice_dstring_reinit(s);
spice_dstring_append(s, t, -1);
return 1; /* Dstrings expand to any length */
}
/* -----------------------------------------------------------------
* Create an upper case copy of a string and store it in a dynamic string.
* Dynamic strings are always NULL * terminated.
* ----------------------------------------------------------------- */
bool
scopy_up (SPICE_DSTRINGPTR dstr_p, char *str) /* returns success flag */
scopy_up(SPICE_DSTRINGPTR dstr_p, char *str) /* returns success flag */
{
char up[2] ; /* short string */
char *ptr ; /* position in string */
char up[2]; /* short string */
char *ptr; /* position in string */
spice_dstring_reinit( dstr_p ) ;
up[1] = '\0' ;
for( ptr = str ; ptr && *ptr ; ptr++ )
{
up[0] = upcase ( *ptr );
spice_dstring_append( dstr_p, up, 1 ) ;
spice_dstring_reinit(dstr_p);
up[1] = '\0';
for (ptr = str; ptr && *ptr; ptr++) {
up[0] = upcase(*ptr);
spice_dstring_append(dstr_p, up, 1);
}
return 1 ; /* Dstrings expand to any length */
return 1; /* Dstrings expand to any length */
}
/* -----------------------------------------------------------------
* Create a lower case copy of a string and store it in a dynamic string.
* Dynamic strings are always NULL * terminated.
* ----------------------------------------------------------------- */
bool
scopy_lower (SPICE_DSTRINGPTR dstr_p, char *str) /* returns success flag */
scopy_lower(SPICE_DSTRINGPTR dstr_p, char *str) /* returns success flag */
{
char low[2] ; /* short string */
char *ptr ; /* position in string */
char low[2]; /* short string */
char *ptr; /* position in string */
spice_dstring_reinit( dstr_p ) ;
low[1] = '\0' ;
for( ptr = str ; ptr && *ptr ; ptr++ )
{
low[0] = lowcase ( *ptr );
spice_dstring_append( dstr_p, low, 1 ) ;
spice_dstring_reinit(dstr_p);
low[1] = '\0';
for (ptr = str; ptr && *ptr; ptr++) {
low[0] = lowcase(*ptr);
spice_dstring_append(dstr_p, low, 1);
}
return 1 ; /* Dstrings expand to any length */
return 1; /* Dstrings expand to any length */
}
bool
ccopy ( SPICE_DSTRINGPTR dstr_p, char c) /* returns success flag */
ccopy(SPICE_DSTRINGPTR dstr_p, char c) /* returns success flag */
{
char *s_p ; /* current string */
char *s_p; /* current string */
sfix ( dstr_p, 1);
s_p = spice_dstring_value(dstr_p) ;
s_p[0] = c ;
return 1 ;
sfix(dstr_p, 1);
s_p = spice_dstring_value(dstr_p);
s_p[0] = c;
return 1;
}
char *
pscopy (SPICE_DSTRINGPTR dstr_p, char *t, int start, int leng)
pscopy(SPICE_DSTRINGPTR dstr_p, char *t, int start, int leng)
/* partial string copy, with C-based start - Because we now have a 0 based
* start and string may copy outselves, we may need to restore the first
* character of the original dstring because resetting string will wipe
* out first character. */
{
int i; /* counter */
int stop ; /* stop value */
char *s_p ; /* value of dynamic string */
int i; /* counter */
int stop; /* stop value */
char *s_p; /* value of dynamic string */
stop = length(t) ;
stop = length(t);
if (start < stop) /* nothing! */
{
if ((start + leng - 1) > stop)
{
// leng = stop - start + 1;
leng = stop - start ;
if (start < stop) { /* nothing! */
if ((start + leng - 1) > stop) {
// leng = stop - start + 1;
leng = stop - start;
}
_spice_dstring_setlength(dstr_p,leng) ;
s_p = spice_dstring_value(dstr_p) ;
_spice_dstring_setlength(dstr_p, leng);
s_p = spice_dstring_value(dstr_p);
for (i = 0; i < leng; i++)
s_p[i] = t[start + i];
s_p[leng] = '\0' ;
s_p[leng] = '\0';
} else {
s_p = spice_dstring_reinit(dstr_p);
}
else
{
s_p = spice_dstring_reinit(dstr_p) ;
}
return s_p ;
return s_p;
}
char *
pscopy_up (SPICE_DSTRINGPTR dstr_p, char *t, int start, int leng)
pscopy_up(SPICE_DSTRINGPTR dstr_p, char *t, int start, int leng)
/* partial string copy to upper case, with C convention for start. */
{
int i; /* counter */
int stop ; /* stop value */
char *s_p ; /* value of dynamic string */
int i; /* counter */
int stop; /* stop value */
char *s_p; /* value of dynamic string */
stop = length(t) ;
stop = length(t);
if (start < stop) /* nothing! */
{
if ((start + leng - 1) > stop)
{
// leng = stop - start + 1;
leng = stop - start ;
if (start < stop) { /* nothing! */
if ((start + leng - 1) > stop) {
// leng = stop - start + 1;
leng = stop - start;
}
_spice_dstring_setlength(dstr_p,leng) ;
s_p = spice_dstring_value(dstr_p) ;
_spice_dstring_setlength(dstr_p, leng);
s_p = spice_dstring_value(dstr_p);
for (i = 0; i < leng; i++)
s_p[i] = upcase ( t[start + i] ) ;
s_p[leng] = '\0' ;
s_p[i] = upcase(t[start + i]);
s_p[leng] = '\0';
} else {
s_p = spice_dstring_reinit(dstr_p);
}
else
{
s_p = spice_dstring_reinit(dstr_p) ;
}
return s_p ;
return s_p;
}
bool
nadd ( SPICE_DSTRINGPTR dstr_p, long n)
nadd(SPICE_DSTRINGPTR dstr_p, long n)
/* append a decimal integer to a string */
{
int d[25];
int j, k ;
char sg; /* the sign */
char load_str[2] ; /* used to load dstring */
int j, k;
char sg; /* the sign */
char load_str[2]; /* used to load dstring */
k = 0;
if (n < 0)
{
if (n < 0) {
n = -n;
sg = '-';
}
else
} else {
sg = '+';
}
while (n > 0)
{
while (n > 0) {
d[k] = n % 10;
k++;
n = n / 10;
}
if (k == 0)
cadd (dstr_p, '0');
else
{
load_str[1] = '\0' ;
if (sg == '-')
{
load_str[0] = sg ;
spice_dstring_append( dstr_p, load_str, 1 ) ;
if (k == 0) {
cadd(dstr_p, '0');
} else {
load_str[1] = '\0';
if (sg == '-') {
load_str[0] = sg;
spice_dstring_append(dstr_p, load_str, 1);
}
for (j = k - 1; j >= 0; j--)
{
for (j = k - 1; j >= 0; j--) {
load_str[0] = (char) ('0' + d[j]);
spice_dstring_append( dstr_p, load_str, 1 ) ;
spice_dstring_append(dstr_p, load_str, 1);
}
}
return 1 ;
return 1;
}
bool
naddll (SPICE_DSTRINGPTR dstr_p, long long n)
naddll(SPICE_DSTRINGPTR dstr_p, long long n)
/* append a decimal integer (but a long long) to a string */
{
int d[25];
int j, k ;
char sg; /* the sign */
char load_str[2] ; /* used to load dstring */
int j, k;
char sg; /* the sign */
char load_str[2]; /* used to load dstring */
k = 0;
if (n < 0)
{
if (n < 0) {
n = -n;
sg = '-';
}
else
} else {
sg = '+';
}
while (n > 0)
{
while (n > 0) {
d[k] = (int) (n % 10);
k++;
n = n / 10;
}
if (k == 0)
cadd (dstr_p, '0');
else
{
load_str[1] = '\0' ;
if (sg == '-')
{
load_str[0] = sg ;
spice_dstring_append( dstr_p, load_str, 1 ) ;
if (k == 0) {
cadd(dstr_p, '0');
} else {
load_str[1] = '\0';
if (sg == '-') {
load_str[0] = sg;
spice_dstring_append(dstr_p, load_str, 1);
}
for (j = k - 1; j >= 0; j--)
{
for (j = k - 1; j >= 0; j--) {
load_str[0] = (char) ('0' + d[j]);
spice_dstring_append( dstr_p, load_str, 1 ) ;
spice_dstring_append(dstr_p, load_str, 1);
}
}
return 1 ;
return 1;
}
void
stri (long n, SPICE_DSTRINGPTR dstr_p)
stri(long n, SPICE_DSTRINGPTR dstr_p)
/* convert integer to string */
{
spice_dstring_reinit( dstr_p ) ;
nadd (dstr_p, n) ;
spice_dstring_reinit(dstr_p);
nadd(dstr_p, n);
}
bool
steq (char *a, char *b) /* string a==b test */
{
return strcmp (a, b) == 0;
}
bool
stne (char *s, char *t)
steq(char *a, char *b) /* string a==b test */
{
return strcmp (s, t) != 0;
return strcmp(a, b) == 0;
}
bool
stne(char *s, char *t)
{
return strcmp(s, t) != 0;
}
char
lowcase (char c)
lowcase(char c)
{
if ((c >= 'A') && (c <= 'Z'))
return (char) (c - 'A' + 'a');
@ -445,93 +461,102 @@ lowcase (char c)
return c;
}
bool
alfa (char c)
{
return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || c == '_'
|| c == '[' || c == ']';
}
bool
num (char c)
alfa(char c)
{
return
((c >= 'a') && (c <= 'z')) ||
((c >= 'A') && (c <= 'Z')) ||
c == '_' || c == '[' || c == ']';
}
bool
num(char c)
{
return (c >= '0') && (c <= '9');
}
bool
alfanum (char c)
alfanum(char c)
{
return alfa (c) || ((c >= '0') && (c <= '9'));
return alfa(c) || ((c >= '0') && (c <= '9'));
}
int
freadstr (FILE * f, SPICE_DSTRINGPTR dstr_p)
freadstr(FILE * f, SPICE_DSTRINGPTR dstr_p)
/* read a line from a file.
was BUG: long lines truncated without warning, ctrl chars are dumped.
Bug no more as we can only run out of memory. Removed max argument.
*/
{
char c;
char str_load[2] ;
int len = 0 ;
char str_load[2];
int len = 0;
str_load[0] = '\0';
str_load[1] = '\0';
spice_dstring_reinit(dstr_p);
str_load[0] = '\0' ;
str_load[1] = '\0' ;
spice_dstring_reinit(dstr_p) ;
do
{
c = (char) fgetc (f); /* tab is the only control char accepted */
if (((c >= ' ') || (c < 0) || (c == '\t')))
{
c = (char) fgetc(f); /* tab is the only control char accepted */
if (((c >= ' ') || (c < 0) || (c == '\t'))) {
str_load[0] = c;
spice_dstring_append( dstr_p, str_load, 1 ) ;
spice_dstring_append(dstr_p, str_load, 1);
}
}
while (!feof (f) && (c != '\n'));
while (!feof(f) && (c != '\n'));
return len ;
return len;
}
char *
stupcase (char *s)
stupcase(char *s)
{
int i = 0;
while (s[i] != '\0')
{
s[i] = upcase (s[i]);
while (s[i] != '\0') {
s[i] = upcase(s[i]);
i++;
}
return s;
}
/***** pointer tricks: app won't use naked malloc(), free() ****/
void
dispose (void *p)
dispose(void *p)
{
if (p != NULL)
free (p);
free(p);
}
void *
new (size_t sz)
new(size_t sz)
{
void *p = tmalloc (sz);
if (p == NULL)
{ /* fatal error */
printf (" new() failure. Program halted.\n");
void *p = tmalloc(sz);
if (p == NULL) { /* fatal error */
printf(" new() failure. Program halted.\n");
controlled_exit(EXIT_FAILURE);
}
return p;
}
/***** elementary math *******/
double
absf (double x)
absf(double x)
{
if (x < 0.0)
return -x;
@ -539,8 +564,9 @@ absf (double x)
return x;
}
long
absi (long i)
absi(long i)
{
if (i >= 0)
return (i);
@ -548,6 +574,7 @@ absi (long i)
return (-i);
}
int
spos_(char *sub, char *s)
/* equivalent to Turbo Pascal pos().
@ -556,42 +583,46 @@ spos_(char *sub, char *s)
{
char *ptr;
if ((ptr = strstr (s, sub)) != NULL)
return (int) (strlen (s) - strlen (ptr));
if ((ptr = strstr(s, sub)) != NULL)
return (int) (strlen(s) - strlen(ptr));
else
return -1 ;
return -1;
}
#ifndef HAVE_LIBM
long
np_round (double x)
np_round(double x)
/* using <math.h>, it would be simpler: floor(x+0.5), see below */
{
double u;
long z;
int n;
// Str (40, s);
SPICE_DSTRING s ;
spice_dstring_init(&s) ;
SPICE_DSTRING s;
spice_dstring_init(&s);
u = 2e9;
if (x > u)
x = u;
else if (x < -u)
x = -u;
n = sprintf (s, "%-12.0f", x);
n = sprintf(s, "%-12.0f", x);
s[n] = 0;
sscanf (s, "%ld", &z);
sscanf(s, "%ld", &z);
return z;
}
long
np_trunc (double x)
np_trunc(double x)
{
long n = np_round (x);
long n = np_round(x);
if ((n > x) && (x >= 0.0))
n--;
else if ((n < x) && (x < 0.0))
@ -600,21 +631,24 @@ np_trunc (double x)
return n;
}
#else /* use floor() and ceil() */
long
np_round (double r)
{
return (long) floor (r + 0.5);
}
long
np_trunc (double r)
np_round(double r)
{
return (long) floor(r + 0.5);
}
long
np_trunc(double r)
{
if (r >= 0.0)
return (long) floor (r);
return (long) floor(r);
else
return (long) ceil (r);
return (long) ceil(r);
}
#endif

View File

@ -1,6 +1,6 @@
/*
* numpaif.h
* external interface to spice frontend subckt.c
* external interface to spice frontend subckt.c
*/
#ifndef NUMPAIF_H
@ -11,7 +11,7 @@
#define NUPASUBDONE 2
#define NUPAEVALDONE 3
extern char * nupa_copy(char *s, int linenum);
extern char *nupa_copy(char *s, int linenum);
extern int nupa_eval(char *s, int linenum, int orig_linenum);
extern int nupa_signal(int sig, char *info);
extern void nupa_scan(char * s, int linenum, int is_subckt);
@ -23,4 +23,4 @@ extern void nupa_copy_inst_dico(void);
extern int dynMaxckt; /* number of lines in deck after expansion */
#endif /* NUMPAIF_H */
#endif

View File

@ -1,5 +1,5 @@
/*
* numparam.h
* numparam.h
*/
/*** interface to spice frontend subckt.c ***/
@ -12,62 +12,68 @@
#define ln(x) log(x)
#define trunc(x) floor(x)
typedef enum {Nodekey='#'} _nNodekey; /* Introduces node symbol */
typedef enum {Intro='&'} _nIntro; /* Introduces preprocessor tokens */
typedef enum {Comment='*'} _nComment; /* Spice Comment lines*/
typedef enum {Psp='{'} _nPsp; /* Ps expression */
typedef enum {Defd=15} _nDefd; /* serial numb. of 'defined' keyword. The others are not used (yet) */
typedef enum {Nodekey = '#'} _nNodekey; /* Introduces node symbol */
typedef enum {Intro = '&'} _nIntro; /* Introduces preprocessor tokens */
typedef enum {Comment = '*'} _nComment; /* Spice Comment lines */
typedef enum {Psp = '{'} _nPsp; /* Ps expression */
typedef enum {Defd = 15} _nDefd; /* serial numb. of 'defined' keyword.
The others are not used (yet) */
typedef char *auxtable; /* dummy */
typedef char * auxtable; /* dummy */
/* -----------------------------------------------------------------
* I believe the entry should be a union of type but I need more info.
* ----------------------------------------------------------------- */
typedef struct _tentry {
char tp; /* type: I)nt R)eal S)tring F)unction M)acro P)ointer */
char *symbol ;
int level; /* subckt nesting level */
double vl; /* float value if defined */
int ivl; /*int value or string buffer index*/
char * sbbase; /* string buffer base address if any */
struct _tentry *pointer ; /* pointer chain */
char tp; /* type: I)nt R)eal S)tring F)unction M)acro P)ointer */
char *symbol;
int level; /* subckt nesting level */
double vl; /* float value if defined */
int ivl; /* int value or string buffer index */
char *sbbase; /* string buffer base address if any */
struct _tentry *pointer; /* pointer chain */
} entry;
typedef struct _tfumas { /*function,macro,string*/
unsigned start /*,stop*/ ; /*buffer index or location */
unsigned start; /*,stop*/ /* buffer index or location */
} fumas;
typedef struct _ttdico {
/* the input scanner data structure */
SPICE_DSTRING srcfile; /* last piece of source file name */
SPICE_DSTRING option; /* one-character translator options */
SPICE_DSTRING lookup_buf ; /* useful temp buffer for quick symbol lookup */
int srcline;
int oldline;
int errcount;
int symbol_stack_alloc ; /* stack allocation */
int stack_depth ; /* current depth of the symbol stack */
NGHASHPTR global_symbols ; /* hash table of globally defined symbols for quick lookup */
NGHASHPTR *local_symbols ; /* stack of locally defined symbols */
NGHASHPTR inst_symbols ; /* instance qualified symbols - after a pop */
char **inst_name ; /* name of subcircuit */
fumas fms[101];
int nfms; /* number of functions & macros */
auxtable nodetab;
char **dynrefptr;
char *dyncategory;
int hs_compatibility; /* allow extra keywords */
typedef struct _ttdico { /* the input scanner data structure */
SPICE_DSTRING srcfile; /* last piece of source file name */
SPICE_DSTRING option; /* one-character translator options */
SPICE_DSTRING lookup_buf; /* useful temp buffer for quick symbol lookup */
int srcline;
int oldline;
int errcount;
int symbol_stack_alloc; /* stack allocation */
int stack_depth; /* current depth of the symbol stack */
NGHASHPTR global_symbols; /* hash table of globally defined symbols
for quick lookup */
NGHASHPTR *local_symbols; /* stack of locally defined symbols */
NGHASHPTR inst_symbols; /* instance qualified symbols - after a pop */
char **inst_name; /* name of subcircuit */
fumas fms[101];
int nfms; /* number of functions & macros */
auxtable nodetab;
char **dynrefptr;
char *dyncategory;
int hs_compatibility; /* allow extra keywords */
} tdico;
void initdico(tdico * dico);
int donedico(tdico * dico);
void dico_free_entry( entry *entry_p ) ;
bool defsubckt( tdico *dico, char * s, int w, char categ);
int findsubckt( tdico *dico, char * s, SPICE_DSTRINGPTR subname);
bool nupa_substitute( tdico *dico, char * s, char * r, bool err);
bool nupa_assignment( tdico *dico, char * s, char mode);
bool nupa_subcktcall( tdico *dico, char * s, char * x, bool err);
void nupa_subcktexit( tdico *dico);
tdico * nupa_fetchinstance(void);
char getidtype( tdico *d, char * s);
entry *attrib( tdico *d, NGHASHPTR htable, char * t, char op );
void initdico(tdico *dico);
int donedico(tdico *dico);
void dico_free_entry(entry *entry_p);
bool defsubckt(tdico *dico, char *s, int w, char categ);
int findsubckt(tdico *dico, char *s, SPICE_DSTRINGPTR subname);
bool nupa_substitute(tdico *dico, char *s, char *r, bool err);
bool nupa_assignment(tdico *dico, char *s, char mode);
bool nupa_subcktcall(tdico *dico, char *s, char *x, bool err);
void nupa_subcktexit(tdico *dico);
tdico *nupa_fetchinstance(void);
char getidtype(tdico *d, char *s);
entry *attrib(tdico *d, NGHASHPTR htable, char *t, char op);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -33,8 +33,8 @@ inp_nutsource(FILE *fp, bool comfile, char *filename)
wordlist *wl = NULL, *end = NULL;
wordlist *controls = NULL;
FILE *lastin, *lastout, *lasterr;
inp_readall(fp, &deck, 0, NULL, comfile) /* still to check if . or filename instead of NULL */;
inp_readall(fp, &deck, 0, NULL, comfile); /* still to check if . or filename instead of NULL */
if (!deck)
return;
@ -49,7 +49,7 @@ inp_nutsource(FILE *fp, bool comfile, char *filename)
(void) fclose(fp);
/* Now save the IO context and start a new control set... After
* we are done with the source we'll put the old file descriptors
* we are done with the source we'll put the old file descriptors
* back. I guess we could use a FILE stack, but since this routine
* is recursive anyway...
*/
@ -62,7 +62,7 @@ inp_nutsource(FILE *fp, bool comfile, char *filename)
cp_pushcontrol();
/* We should now go through the deck and execute front-end
/* We should now go through the deck and execute front-end
* commands and remove them. Front-end commands are enclosed by
* the lines .control and .endc, unless comfile
* is TRUE, in which case every line must be a front-end command.
@ -77,19 +77,18 @@ inp_nutsource(FILE *fp, bool comfile, char *filename)
if ((dd->li_line[0] == '*') && (dd->li_line[1] != '#'))
continue;
if (!ciprefix(".control", dd->li_line) &&
!ciprefix(".endc", dd->li_line)) {
!ciprefix(".endc", dd->li_line)) {
if (dd->li_line[0] == '*')
(void) cp_evloop(dd->li_line + 2);
else
(void) cp_evloop(dd->li_line);
}
}
tfree(dd->li_line);
tfree(dd);
}
}
} else {
for (dd = deck->li_next; dd; dd = ld->li_next) {
if ((dd->li_line[0] == '*') &&
(dd->li_line[1] != '#')) {
if ((dd->li_line[0] == '*') && (dd->li_line[1] != '#')) {
ld = dd;
continue;
}
@ -105,8 +104,7 @@ inp_nutsource(FILE *fp, bool comfile, char *filename)
tfree(dd->li_line);
tfree(dd);
if (commands)
fprintf(cp_err,
"Warning: redundant .control line\n");
fprintf(cp_err, "Warning: redundant .control line\n");
else
commands = TRUE;
} else if (ciprefix(".endc", dd->li_line)) {
@ -116,8 +114,7 @@ inp_nutsource(FILE *fp, bool comfile, char *filename)
if (commands)
commands = FALSE;
else
fprintf(cp_err,
"Warning: misplaced .endc line\n");
fprintf(cp_err, "Warning: misplaced .endc line\n");
} else if (commands || prefix("*#", dd->li_line)) {
controls = wl_cons(NULL, controls);
wl = controls;
@ -138,15 +135,17 @@ inp_nutsource(FILE *fp, bool comfile, char *filename)
inp_casefix(s);
inp_casefix(dd->li_line);
if (eq(s, ".width") || ciprefix(".four", s) ||
eq(s, ".plot") ||
eq(s, ".print") ||
eq(s, ".save")) {
eq(s, ".plot") ||
eq(s, ".print") ||
eq(s, ".save"))
{
wl_append_word(&wl, &end, copy(dd->li_line));
ld->li_next = dd->li_next;
tfree(dd->li_line);
tfree(dd);
} else
} else {
ld = dd;
}
}
}
if (deck->li_next) {
@ -154,13 +153,12 @@ inp_nutsource(FILE *fp, bool comfile, char *filename)
fprintf(cp_out, "\nCircuit: %s\n\n", tt);
fprintf(stderr, "\nCircuit: %s\n\n", tt);
/* Now expand subcircuit macros. Note that we have to
* fix the case before we do this but after we
/* Now expand subcircuit macros. Note that we have to
* fix the case before we do this but after we
* deal with the commands.
*/
if (!cp_getvar("nosubckt", CP_BOOL, NULL))
deck->li_next = inp_subcktexpand(deck->
li_next);
deck->li_next = inp_subcktexpand(deck->li_next);
deck->li_actual = realdeck;
nutinp_dodeck(deck, tt, wl, FALSE, options, filename);
}
@ -185,6 +183,7 @@ inp_nutsource(FILE *fp, bool comfile, char *filename)
return;
}
void
nutcom_source(wordlist *wl)
{
@ -219,8 +218,10 @@ nutcom_source(wordlist *wl)
wl = wl->wl_next;
}
(void) fseek(fp, 0L, SEEK_SET);
} else
} else {
fp = inp_pathopen(wl->wl_word, "r");
}
if (fp == NULL) {
perror(wl->wl_word);
cp_interactive = TRUE;
@ -228,21 +229,26 @@ nutcom_source(wordlist *wl)
}
/* Don't print the title if this is a .spiceinit file. */
if (ft_nutmeg || substring(INITSTR, owl->wl_word)
|| substring(ALT_INITSTR, owl->wl_word))
if (ft_nutmeg ||
substring(INITSTR, owl->wl_word) ||
substring(ALT_INITSTR, owl->wl_word))
{
inp_nutsource(fp, TRUE, tempfile ? NULL : wl->wl_word);
else
} else {
inp_nutsource(fp, FALSE, tempfile ? NULL : wl->wl_word);
}
cp_interactive = inter;
if (tempfile)
(void) unlink(tempfile);
return;
}
void
nutinp_source(char *file)
{
static struct wordlist wl = { NULL, NULL, NULL } ;
static struct wordlist wl = { NULL, NULL, NULL };
wl.wl_word = file;
nutcom_source(&wl);

View File

@ -191,8 +191,9 @@ inp_getopts(struct line *deck)
deck->li_next = dd->li_next;
dd->li_next = opts;
opts = dd;
} else
} else {
last = dd;
}
}
return (opts);
@ -204,7 +205,7 @@ struct line *
inp_getoptsc(char *in_line, struct line *com_options)
{
struct line *next = NULL;
char* line;
char *line;
line = TMALLOC(char, strlen(in_line) + 3);
/* option -> .options */
@ -252,8 +253,9 @@ cp_usrset(struct variable *var, bool isset)
fprintf(cp_err, "Error: bad type for debug var\n");
} else if (var->va_type == CP_STRING) {
setdb(var->va_string);
} else
} else {
fprintf(cp_err, "Error: bad type for debug var\n");
}
#ifndef FTEDEBUG
fprintf(cp_err, "Warning: %s compiled without debug messages\n",
cp_program);

View File

@ -36,7 +36,6 @@ extern char *spice_analysis_get_name(int index);
extern char *spice_analysis_get_description(int index);
/* static declarations */
static int beginPlot(JOB *analysisPtr, CKTcircuit *circuitPtr, char *cktName, char *analName,
char *refName, int refType, int numNames, char **dataNames, int dataType,
bool windowed, runDesc **runp);
@ -86,7 +85,8 @@ OUTpBeginPlot(CKTcircuit *circuitPtr, JOB *analysisPtr,
char *name;
#ifdef PARALLEL_ARCH
if (ARCHme != 0) return(OK);
if (ARCHme != 0)
return (OK);
#endif
if (ft_curckt->ci_ckt == circuitPtr)
@ -109,7 +109,8 @@ OUTwBeginPlot(CKTcircuit *circuitPtr, JOB *analysisPtr,
{
#ifdef PARALLEL_ARCH
if (ARCHme != 0) return(OK);
if (ARCHme != 0)
return (OK);
#endif
return (beginPlot(analysisPtr, circuitPtr, "circuit name",
@ -133,9 +134,9 @@ beginPlot(JOB *analysisPtr, CKTcircuit *circuitPtr, char *cktName, char *analNam
bool savealli = FALSE;
char *an_name;
/*to resume a run saj
*All it does is reassign the file pointer and return (requires *runp to be NULL if this is not needed)
*/
if(dataType == 666 && numNames == 666) {
*All it does is reassign the file pointer and return (requires *runp to be NULL if this is not needed)
*/
if (dataType == 666 && numNames == 666) {
run = *runp;
run->writeOut = ft_getOutReq(&run->fp, &run->runPlot, &run->binary,
run->type, run->name);
@ -211,33 +212,28 @@ beginPlot(JOB *analysisPtr, CKTcircuit *circuitPtr, char *cktName, char *analNam
/* Pass 1. */
if (numsaves && !saveall) {
for (i = 0; i < numsaves; i++) {
if (!savesused[i]) {
for (j = 0; j < numNames; j++) {
for (i = 0; i < numsaves; i++)
if (!savesused[i])
for (j = 0; j < numNames; j++)
if (name_eq(saves[i].name, dataNames[j])) {
addDataDesc(run, dataNames[j], dataType, j);
savesused[i] = TRUE;
saves[i].used = 1;
break;
}
}
}
}
} else {
for (i = 0; i < numNames; i++)
if (!refName || !name_eq(dataNames[i], refName)) {
if (!refName || !name_eq(dataNames[i], refName))
/* Save the node as long as it's an internal device node */
if (!strstr(dataNames[i], "#internal") &&
!strstr(dataNames[i], "#source") &&
!strstr(dataNames[i], "#drain") &&
!strstr(dataNames[i], "#collector") &&
!strstr(dataNames[i], "#emitter") &&
!strstr(dataNames[i], "#base")) {
!strstr(dataNames[i], "#source") &&
!strstr(dataNames[i], "#drain") &&
!strstr(dataNames[i], "#collector") &&
!strstr(dataNames[i], "#emitter") &&
!strstr(dataNames[i], "#base"))
{
addDataDesc(run, dataNames[i], dataType, i);
}
}
}
/* Pass 1 and a bit.
@ -248,11 +244,12 @@ beginPlot(JOB *analysisPtr, CKTcircuit *circuitPtr, char *cktName, char *analNam
depind = 0;
for (i = 0; i < numNames; i++) {
if (strstr(dataNames[i], "#internal") ||
strstr(dataNames[i], "#source") ||
strstr(dataNames[i], "#drain") ||
strstr(dataNames[i], "#collector") ||
strstr(dataNames[i], "#emitter") ||
strstr(dataNames[i], "#base")) {
strstr(dataNames[i], "#source") ||
strstr(dataNames[i], "#drain") ||
strstr(dataNames[i], "#collector") ||
strstr(dataNames[i], "#emitter") ||
strstr(dataNames[i], "#base"))
{
tmpname[0] = '@';
tmpname[1] = '\0';
strncat(tmpname, dataNames[i], BSIZE_SP-1);
@ -286,8 +283,8 @@ beginPlot(JOB *analysisPtr, CKTcircuit *circuitPtr, char *cktName, char *analNam
}
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) {
if (*depbuf) {
fprintf( stderr,
"Warning : unexpected dependent variable on %s\n", tmpname);
fprintf(stderr,
"Warning : unexpected dependent variable on %s\n", tmpname);
} else {
addSpecialDesc(run, tmpname, namebuf, parambuf, depind);
}
@ -347,8 +344,9 @@ beginPlot(JOB *analysisPtr, CKTcircuit *circuitPtr, char *cktName, char *analNam
}
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(analysisPtr->JOBtype));
return E_NOTFOUND;
@ -451,7 +449,8 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
int i;
#ifdef PARALLEL_ARCH
if (ARCHme != 0) return(OK);
if (ARCHme != 0)
return (OK);
#endif
run->pointCount++;
@ -472,8 +471,8 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
fileAddComplexValue(run->fp, run->binary, refValue->cValue);
/* While we're looking at the reference value, print it to the screen
every quarter of a second, to give some feedback without using
too much CPU time */
every quarter of a second, to give some feedback without using
too much CPU time */
#ifndef HAS_WINDOWS
currclock = clock();
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
@ -490,7 +489,8 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
#ifndef HAS_WINDOWS
currclock = clock();
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
fprintf(stderr, " Reference value : % 12.5e\r", refValue->rValue);
fprintf(stderr, " Reference value : % 12.5e\r",
refValue->rValue);
lastclock = currclock;
}
#endif
@ -507,7 +507,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
#endif
if (run->data[i].regular) {
if(run->data[i].type == IF_REAL)
if (run->data[i].type == IF_REAL)
fileAddRealValue(run->fp, run->binary,
valuePtr->v.vec.rVec [run->data[i].outIndex]);
else if (run->data[i].type == IF_COMPLEX)
@ -676,7 +676,8 @@ OUTendPlot(runDesc *plotPtr)
runDesc *run = plotPtr; // FIXME
#ifdef PARALLEL_ARCH
if (ARCHme != 0) return(OK);
if (ARCHme != 0)
return (OK);
#endif
if (run->writeOut) {
@ -828,14 +829,14 @@ fileInit_pass2(runDesc *run)
else
type = SV_VOLTAGE;
if ( type == SV_CURRENT ) {
if (type == SV_CURRENT) {
char *branch = strstr(name, "#branch");
if (branch)
*branch = '\0';
fprintf(run->fp, "\t%d\ti(%s)\t%s", i, name, ft_typenames(type));
if (branch)
*branch = '#';
} else if ( type == SV_VOLTAGE ) {
} else if (type == SV_VOLTAGE) {
fprintf(run->fp, "\t%d\tv(%s)\t%s", i, name, ft_typenames(type));
} else {
fprintf(run->fp, "\t%d\t%s\t%s", i, name, ft_typenames(type));
@ -968,8 +969,9 @@ plotInit(runDesc *run)
if (isdigit(*dd->name)) {
(void) sprintf(buf, "V(%s)", dd->name);
v->v_name = copy(buf);
} else
} else {
v->v_name = copy(dd->name);
}
if (substring("#branch", v->v_name))
v->v_type = SV_CURRENT;
else if (cieq(v->v_name, "time"))
@ -1024,6 +1026,7 @@ plotAddRealValue(dataDesc *desc, double value)
v->v_compdata[v->v_length].cx_real = value;
v->v_compdata[v->v_length].cx_imag = 0.0;
}
v->v_length++;
v->v_dims[0] = v->v_length; /* va, must be updated */
}
@ -1037,6 +1040,7 @@ plotAddComplexValue(dataDesc *desc, IFcomplex value)
v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + 1);
v->v_compdata[v->v_length].cx_real = value.real;
v->v_compdata[v->v_length].cx_imag = value.imag;
v->v_length++;
v->v_dims[0] = v->v_length; /* va, must be updated */
}
@ -1070,6 +1074,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
while (*name && (*name != '['))
*s++ = *name++;
*s = '\0';
if (!*name)
return TRUE;
name++;
@ -1078,6 +1083,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
while (*name && (*name != ',') && (*name != ']'))
*s++ = *name++;
*s = '\0';
if (*name == ']')
return (!name[1] ? TRUE : FALSE);
else if (!*name)
@ -1088,6 +1094,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
while (*name && (*name != ']'))
*s++ = *name++;
*s = '\0';
if (*name && !name[1])
return TRUE;
else

View File

@ -10,20 +10,21 @@
typedef struct dataDesc {
char *name; /* The name of the vector. */
int type; /* The type. */
GRIDTYPE gtype; /* default plot scale */
bool regular; /* Is this given to us? */
int outIndex; /* If regular then the index. */
char *specName; /* The device name if special. */
char *specParamName; /* The parameter name if special. */
int specIndex; /* For sensitivity, if special. */
char *name; /* The name of the vector. */
int type; /* The type. */
GRIDTYPE gtype; /* default plot scale */
bool regular; /* Is this given to us? */
int outIndex; /* If regular then the index. */
char *specName; /* The device name if special. */
char *specParamName; /* The parameter name if special. */
int specIndex; /* For sensitivity, if special. */
int specType;
GENinstance *specFast;
int refIndex; /* The index of our ref vector. */
int refIndex; /* The index of our ref vector. */
struct dvec *vec;
} dataDesc;
struct runDesc {
void *analysis;
CKTcircuit *circuit;
@ -37,12 +38,13 @@ struct runDesc {
bool binary;
struct plot *runPlot;
FILE *fp;
long pointPos; /* where to write pointCount */
long pointPos; /* where to write pointCount */
int pointCount;
int isComplex;
int windowCount;
};
int OUTpBeginPlot(CKTcircuit *circuitPtr, JOB *analysisPtr,
IFuid analName,
IFuid refName, int refType,

View File

@ -17,18 +17,17 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "evaluate.h"
#include "parse.h"
/* static declarations */
static bool checkvalid(struct pnode *pn);
static struct pnode * mkbnode(int opnum, struct pnode *arg1, struct pnode *arg2);
static struct pnode * mkunode(int op, struct pnode *arg);
static struct pnode * mkfnode(const char *func, struct pnode *arg);
static struct pnode * mknnode(double number);
static struct pnode * mksnode(const char *string);
static struct pnode *mkbnode(int opnum, struct pnode *arg1, struct pnode *arg2);
static struct pnode *mkunode(int op, struct pnode *arg);
static struct pnode *mkfnode(const char *func, struct pnode *arg);
static struct pnode *mknnode(double number);
static struct pnode *mksnode(const char *string);
#include "parse-bison.c"
char * db_print_pnode_tree(struct pnode *p, char *print);
char *db_print_pnode_tree(struct pnode *p, char *print);
struct pnode *
@ -45,11 +44,11 @@ ft_getpnames(wordlist *wl, bool check)
xsbuf = sbuf = wl_flatten(wl);
rv = PPparse (&sbuf, &pn);
rv = PPparse(&sbuf, &pn);
tfree(xsbuf);
if(rv)
if (rv)
return (NULL);
if (check && !checkvalid(pn))
@ -68,20 +67,19 @@ checkvalid(struct pnode *pn)
{
while (pn) {
if (pn->pn_value) {
if ((pn->pn_value->v_length == 0) &&
if ((pn->pn_value->v_length == 0) &&
!eq(pn->pn_value->v_name, "list")) {
if (eq(pn->pn_value->v_name, "all"))
fprintf(cp_err,
"Error: %s: no matching vectors.\n",
pn->pn_value->v_name);
"Error: %s: no matching vectors.\n",
pn->pn_value->v_name);
else
fprintf(cp_err,
"Error(parse.c--checkvalid): %s: no such vector.\n",
pn->pn_value->v_name);
"Error(parse.c--checkvalid): %s: no such vector.\n",
pn->pn_value->v_name);
return (FALSE);
}
} else if (pn->pn_func ||
(pn->pn_op && (pn->pn_op->op_arity == 1))) {
} else if (pn->pn_func || (pn->pn_op && (pn->pn_op->op_arity == 1))) {
if (!checkvalid(pn->pn_left))
return (FALSE);
} else if (pn->pn_op && (pn->pn_op->op_arity == 2)) {
@ -89,108 +87,109 @@ checkvalid(struct pnode *pn)
return (FALSE);
if (!checkvalid(pn->pn_right))
return (FALSE);
} else
fprintf(cp_err,
"checkvalid: Internal Error: bad node\n");
} else {
fprintf(cp_err,
"checkvalid: Internal Error: bad node\n");
}
pn = pn->pn_next;
}
return (TRUE);
}
/* Some auxiliary functions for building the parse tree. */
static
struct op ops[] = {
{ PT_OP_PLUS, "+", 2, {(void(*)(void)) op_plus} } ,
{ PT_OP_MINUS, "-", 2, {(void(*)(void)) op_minus} } ,
{ PT_OP_TIMES, "*", 2, {(void(*)(void)) op_times} } ,
{ PT_OP_MOD, "%", 2, {(void(*)(void)) op_mod} } ,
{ PT_OP_DIVIDE, "/", 2, {(void(*)(void)) op_divide} } ,
{ PT_OP_COMMA, ",", 2, {(void(*)(void)) op_comma} } ,
{ PT_OP_POWER, "^", 2, {(void(*)(void)) op_power} } ,
{ PT_OP_EQ, "=", 2, {(void(*)(void)) op_eq} } ,
{ PT_OP_GT, ">", 2, {(void(*)(void)) op_gt} } ,
{ PT_OP_LT, "<", 2, {(void(*)(void)) op_lt} } ,
{ PT_OP_GE, ">=", 2, {(void(*)(void)) op_ge} } ,
{ PT_OP_LE, "<=", 2, {(void(*)(void)) op_le} } ,
{ PT_OP_NE, "<>", 2, {(void(*)(void)) op_ne} } ,
{ PT_OP_AND, "&", 2, {(void(*)(void)) op_and} } ,
{ PT_OP_OR, "|", 2, {(void(*)(void)) op_or} } ,
{ PT_OP_INDX, "[", 2, {(void(*)(void)) op_ind} } ,
{ PT_OP_RANGE, "[[", 2, {(void(*)(void)) op_range} } ,
{ PT_OP_TERNARY, "?:", 2, {NULL} } ,
{ 0, NULL, 0, {NULL} }
} ;
static struct op ops[] = {
{ PT_OP_PLUS, "+", 2, {(void(*)(void)) op_plus} },
{ PT_OP_MINUS, "-", 2, {(void(*)(void)) op_minus} },
{ PT_OP_TIMES, "*", 2, {(void(*)(void)) op_times} },
{ PT_OP_MOD, "%", 2, {(void(*)(void)) op_mod} },
{ PT_OP_DIVIDE, "/", 2, {(void(*)(void)) op_divide} },
{ PT_OP_COMMA, ",", 2, {(void(*)(void)) op_comma} },
{ PT_OP_POWER, "^", 2, {(void(*)(void)) op_power} },
{ PT_OP_EQ, "=", 2, {(void(*)(void)) op_eq} },
{ PT_OP_GT, ">", 2, {(void(*)(void)) op_gt} },
{ PT_OP_LT, "<", 2, {(void(*)(void)) op_lt} },
{ PT_OP_GE, ">=", 2, {(void(*)(void)) op_ge} },
{ PT_OP_LE, "<=", 2, {(void(*)(void)) op_le} },
{ PT_OP_NE, "<>", 2, {(void(*)(void)) op_ne} },
{ PT_OP_AND, "&", 2, {(void(*)(void)) op_and} },
{ PT_OP_OR, "|", 2, {(void(*)(void)) op_or} },
{ PT_OP_INDX, "[", 2, {(void(*)(void)) op_ind} },
{ PT_OP_RANGE, "[[", 2, {(void(*)(void)) op_range} },
{ PT_OP_TERNARY, "?:", 2, {NULL} },
{ 0, NULL, 0, {NULL} }
};
static
struct op uops[] = {
{ PT_OP_UMINUS, "-", 1, {(void(*)(void)) op_uminus} } ,
{ PT_OP_NOT, "~", 1, {(void(*)(void)) op_not} } ,
static struct op uops[] = {
{ PT_OP_UMINUS, "-", 1, {(void(*)(void)) op_uminus} },
{ PT_OP_NOT, "~", 1, {(void(*)(void)) op_not} },
{ 0, NULL, 0, {NULL} }
} ;
};
/* We have 'v' declared as a function, because if we don't then the defines
* we do for vm(), etc won't work. This is caught in evaluate(). Bad kludge.
*/
typedef void* cx_function_t(void*,short int,int,int*,short int*);
typedef void* cx_function_t(void*, short int, int, int*, short int*);
struct func ft_funcs[] = {
{ "mag", cx_mag } ,
{ "magnitude", cx_mag } ,
{ "cph", cx_cph } , /* SJdV */
{ "cphase", cx_cph } , /* SJdV Continious phase*/
{ "ph", cx_ph } ,
{ "phase", cx_ph } ,
{ "j", cx_j } ,
{ "real", cx_real } ,
{ "re", cx_real } ,
{ "imag", cx_imag } ,
{ "im", cx_imag } ,
{ "db", cx_db } ,
{ "log", cx_log } ,
{ "log10", cx_log } ,
{ "ln", cx_ln } ,
{ "exp", cx_exp } ,
{ "abs", cx_mag } ,
{ "sqrt", cx_sqrt } ,
{ "sin", cx_sin } ,
{ "cos", cx_cos } ,
{ "tan", cx_tan } ,
{ "sinh", cx_sinh } ,
{ "cosh", cx_cosh } ,
{ "tanh", cx_tanh } ,
{ "atan", cx_atan } ,
{ "norm", cx_norm } ,
{ "rnd", cx_rnd } ,
{ "sunif", cx_sunif } ,
{ "poisson",cx_poisson } ,
{ "exponential", cx_exponential } ,
{ "sgauss", cx_sgauss } ,
{ "pos", cx_pos } ,
{ "floor", cx_floor } ,
{ "ceil", cx_ceil } ,
{ "mean", cx_mean } ,
{ "avg", cx_avg } , /* A.Roldan 03/06/05 incremental average new function */
{ "group_delay", (cx_function_t*) cx_group_delay } , /* A.Roldan 10/06/05 group delay new function */
{ "vector", cx_vector } ,
{ "unitvec", cx_unitvec } ,
{ "length", cx_length } ,
{ "vecmin", cx_min } ,
{ "vecmax", cx_max } ,
{ "vecd", cx_d } ,
{ "interpolate", (cx_function_t*) cx_interpolate } ,
{ "deriv", (cx_function_t*) cx_deriv } ,
{ "v", NULL } ,
{ NULL, NULL }
} ;
{ "mag", cx_mag },
{ "magnitude", cx_mag },
{ "cph", cx_cph }, /* SJdV */
{ "cphase", cx_cph }, /* SJdV Continious phase*/
{ "ph", cx_ph },
{ "phase", cx_ph },
{ "j", cx_j },
{ "real", cx_real },
{ "re", cx_real },
{ "imag", cx_imag },
{ "im", cx_imag },
{ "db", cx_db },
{ "log", cx_log },
{ "log10", cx_log },
{ "ln", cx_ln },
{ "exp", cx_exp },
{ "abs", cx_mag },
{ "sqrt", cx_sqrt },
{ "sin", cx_sin },
{ "cos", cx_cos },
{ "tan", cx_tan },
{ "sinh", cx_sinh },
{ "cosh", cx_cosh },
{ "tanh", cx_tanh },
{ "atan", cx_atan },
{ "norm", cx_norm },
{ "rnd", cx_rnd },
{ "sunif", cx_sunif },
{ "poisson", cx_poisson },
{ "exponential", cx_exponential },
{ "sgauss", cx_sgauss },
{ "pos", cx_pos },
{ "floor", cx_floor },
{ "ceil", cx_ceil },
{ "mean", cx_mean },
{ "avg", cx_avg }, /* A.Roldan 03/06/05 incremental average new function */
{ "group_delay", (cx_function_t*) cx_group_delay }, /* A.Roldan 10/06/05 group delay new function */
{ "vector", cx_vector },
{ "unitvec", cx_unitvec },
{ "length", cx_length },
{ "vecmin", cx_min },
{ "vecmax", cx_max },
{ "vecd", cx_d },
{ "interpolate", (cx_function_t*) cx_interpolate },
{ "deriv", (cx_function_t*) cx_deriv },
{ "v", NULL },
{ NULL, NULL }
};
struct func func_uminus = { "minus", cx_uminus };
struct func func_not = { "not", cx_not };
/* Binary operator node. */
static struct pnode *
@ -202,23 +201,28 @@ mkbnode(int opnum, struct pnode *arg1, struct pnode *arg2)
for (o = &ops[0]; o->op_name; o++)
if (o->op_num == opnum)
break;
if (!o->op_name)
fprintf(cp_err, "mkbnode: Internal Error: no such op num %d\n",
opnum);
opnum);
p = alloc(struct pnode);
p->pn_use = 0;
p->pn_value = NULL;
p->pn_name = NULL; /* sjb */
p->pn_name = NULL; /* sjb */
p->pn_func = NULL;
p->pn_op = o;
p->pn_left = arg1;
if(p->pn_left) p->pn_left->pn_use++;
if (p->pn_left)
p->pn_left->pn_use++;
p->pn_right = arg2;
if(p->pn_right) p->pn_right->pn_use++;
if (p->pn_right)
p->pn_right->pn_use++;
p->pn_next = NULL;
return (p);
}
/* Unary operator node. */
static struct pnode *
@ -231,6 +235,7 @@ mkunode(int op, struct pnode *arg)
for (o = uops; o->op_name; o++)
if (o->op_num == op)
break;
if (!o->op_name)
fprintf(cp_err, "mkunode: Internal Error: no such op num %d\n",
op);
@ -238,15 +243,17 @@ mkunode(int op, struct pnode *arg)
p->pn_op = o;
p->pn_use = 0;
p->pn_value = NULL;
p->pn_name = NULL; /* sjb */
p->pn_name = NULL; /* sjb */
p->pn_func = NULL;
p->pn_left = arg;
if(p->pn_left) p->pn_left->pn_use++;
if (p->pn_left)
p->pn_left->pn_use++;
p->pn_right = NULL;
p->pn_next = NULL;
return (p);
}
/* Function node. We have to worry about a lot of things here. Something
* like f(a) could be three things -- a call to a standard function, which
* is easiest to deal with, a variable name, in which case we do the
@ -266,22 +273,25 @@ mkfnode(const char *func, struct pnode *arg)
(void) strcpy(buf, func);
strtolower(buf); /* Make sure the case is ok. */
for (f = &ft_funcs[0]; f->fu_name; f++)
if (eq(f->fu_name, buf))
break;
if (f->fu_name == NULL) {
/* Give the user-defined functions a try. */
q = ft_substdef(func, arg);
if (q)
return (q);
}
if ((f->fu_name == NULL) && arg->pn_value) {
/* Kludge -- maybe it is really a variable name. */
(void) sprintf(buf, "%s(%s)", func, arg->pn_value->v_name);
d = vec_get(buf);
if (d == NULL) {
/* Well, too bad. */
fprintf(cp_err, "Error: no such function as %s.\n",
fprintf(cp_err, "Error: no such function as %s.\n",
func);
return (NULL);
}
@ -290,14 +300,14 @@ mkfnode(const char *func, struct pnode *arg)
} else if (f->fu_name == NULL) {
fprintf(cp_err, "Error: no function as %s with that arity.\n",
func);
return (NULL);
return (NULL);
}
if (!f->fu_func && arg->pn_op && arg->pn_op->op_num == PT_OP_COMMA) {
p = mkbnode(PT_OP_MINUS, mkfnode(func, arg->pn_left),
mkfnode(func, arg->pn_right));
tfree(arg);
return p;
p = mkbnode(PT_OP_MINUS, mkfnode(func, arg->pn_left),
mkfnode(func, arg->pn_right));
tfree(arg);
return p;
}
p = alloc(struct pnode);
@ -307,12 +317,14 @@ mkfnode(const char *func, struct pnode *arg)
p->pn_func = f;
p->pn_op = NULL;
p->pn_left = arg;
if(p->pn_left) p->pn_left->pn_use++;
if (p->pn_left)
p->pn_left->pn_use++;
p->pn_right = NULL;
p->pn_next = NULL;
return (p);
}
/* Number node. */
static struct pnode *
@ -352,6 +364,7 @@ mknnode(double number)
return (p);
}
/* String node. */
static struct pnode *
@ -370,7 +383,7 @@ mksnode(const char *string)
v = vec_get(string);
if (v == NULL) {
nv = alloc(struct dvec);
ZERO(nv, struct dvec);
ZERO(nv, struct dvec);
p->pn_value = nv;
nv->v_name = copy(string);
return (p);
@ -388,143 +401,147 @@ mksnode(const char *string)
end = nv;
}
p->pn_value = newv;
/* va: tfree v in case of @xxx[par], because vec_get created a new vec and
nobody will free it elsewhere */
/*if (v && v->v_name && *v->v_name=='@' && isreal(v) && v->v_realdata) {
vec_free(v);
} */
/*if (v && v->v_name && *v->v_name == '@' && isreal(v) && v->v_realdata) {
vec_free(v);
} */
/* The two lines above have been commented out to prevent deletion of @xxx[par]
after execution of only a single command like plot @xxx[par] or write. We need to
monitor if this will lead to excessive memory usage. h_vogt 090221 */
after execution of only a single command like plot @xxx[par] or write. We need to
monitor if this will lead to excessive memory usage. h_vogt 090221 */
return (p);
}
/* Don't call this directly, always use the free_pnode() macro.
/* Don't call this directly, always use the free_pnode() macro.
The linked pnodes do not necessarily form a perfect tree as some nodes get
reused. Hence, in this recursive walk trough the 'tree' we only free node
that have their pn_use value at zero. Nodes that have pn_use values above
zero have the link severed and their pn_use value decremented.
In addition, we don't walk past nodes with pn_use values avoid zero, just
in case we have a circular reference (this probable does not happen in
practice, but it does no harm playing safe) */
practice, but it does no harm playing safe) */
void
free_pnode_x(struct pnode *t)
{
if (!t)
return;
return;
/* don't walk past nodes used elsewhere. We decrement the pn_use value here,
but the link gets severed by the action of the free_pnode() macro */
if(t->pn_use>1)
t->pn_use--;
else {
/* pn_use is now 1, so its safe to free the pnode */
free_pnode(t->pn_left);
free_pnode(t->pn_right);
free_pnode(t->pn_next);
tfree(t->pn_name); /* va: it is a copy() of original string, can be free'd */
if (t->pn_value && !(t->pn_value->v_flags & VF_PERMANENT))
vec_free(t->pn_value); /* patch by Stefan Jones */
tfree(t);
if (t->pn_use > 1) {
t->pn_use--;
} else {
/* pn_use is now 1, so its safe to free the pnode */
free_pnode(t->pn_left);
free_pnode(t->pn_right);
free_pnode(t->pn_next);
tfree(t->pn_name); /* va: it is a copy() of original string, can be free'd */
if (t->pn_value && !(t->pn_value->v_flags & VF_PERMANENT))
vec_free(t->pn_value); /* patch by Stefan Jones */
tfree(t);
}
}
/* here is the original free_node, which is needed in spec.c and com_fft.c */
void
free_pnode_o(struct pnode *t)
{
if (!t)
return;
free_pnode(t->pn_left);
free_pnode(t->pn_right);
free_pnode(t->pn_next);
tfree(t);
if (!t)
return;
free_pnode(t->pn_left);
free_pnode(t->pn_right);
free_pnode(t->pn_next);
tfree(t);
}
static void
db_print_func(FILE *fdst, struct func *f)
{
if(!f) {
fprintf(fdst,"nil");
if (!f) {
fprintf(fdst, "nil");
return;
}
fprintf(fdst,"(func :fu_name %s :fu_func %p)", f->fu_name, f->fu_func);
fprintf(fdst, "(func :fu_name %s :fu_func %p)", f->fu_name, f->fu_func);
}
static void
db_print_op(FILE *fdst, struct op *op)
{
if(!op) {
fprintf(fdst,"nil");
if (!op) {
fprintf(fdst, "nil");
return;
}
fprintf(fdst,"(op :op_num %d :op_name %s :op_arity %d :op_func %p)",
op->op_num, op->op_name, op->op_arity, op->op_func.anonymous);
fprintf(fdst, "(op :op_num %d :op_name %s :op_arity %d :op_func %p)",
op->op_num, op->op_name, op->op_arity, op->op_func.anonymous);
}
static void
db_print_dvec(FILE *fdst, struct dvec *d)
{
if(!d) {
fprintf(fdst,"nil");
if (!d) {
fprintf(fdst, "nil");
return;
}
fprintf(fdst,"(dvec :v_name %s :v_type %d :v_flags %d :v_length %d ...)",
d->v_name, d->v_type, d->v_flags, d->v_length);
fprintf(fdst, "(dvec :v_name %s :v_type %d :v_flags %d :v_length %d ...)",
d->v_name, d->v_type, d->v_flags, d->v_length);
}
static void
db_print_pnode(FILE *fdst, struct pnode *p)
{
if(!p) {
fprintf(fdst,"nil\n");
if (!p) {
fprintf(fdst, "nil\n");
return;
}
if(!p->pn_name && p->pn_value && !p->pn_func && !p->pn_op
&& !p->pn_left && !p->pn_right && !p->pn_next) {
fprintf(fdst,"(pnode-value :pn_use %d", p->pn_use);
fprintf(fdst," :pn_value "); db_print_dvec(fdst, p->pn_value);
fprintf(fdst,")\n");
if (!p->pn_name && p->pn_value && !p->pn_func && !p->pn_op &&
!p->pn_left && !p->pn_right && !p->pn_next)
{
fprintf(fdst, "(pnode-value :pn_use %d", p->pn_use);
fprintf(fdst, " :pn_value "); db_print_dvec(fdst, p->pn_value);
fprintf(fdst, ")\n");
return;
}
if (!p->pn_name && !p->pn_value && p->pn_func && !p->pn_op
&& !p->pn_right && !p->pn_next) {
fprintf(fdst,"(pnode-func :pn_use %d", p->pn_use);
fprintf(fdst,"\n :pn_func "); db_print_func(fdst, p->pn_func);
fprintf(fdst,"\n :pn_left "); db_print_pnode(fdst, p->pn_left);
fprintf(fdst,")\n");
if (!p->pn_name && !p->pn_value && p->pn_func && !p->pn_op &&
!p->pn_right && !p->pn_next)
{
fprintf(fdst, "(pnode-func :pn_use %d", p->pn_use);
fprintf(fdst, "\n :pn_func "); db_print_func(fdst, p->pn_func);
fprintf(fdst, "\n :pn_left "); db_print_pnode(fdst, p->pn_left);
fprintf(fdst, ")\n");
return;
}
if (!p->pn_name && !p->pn_value && !p->pn_func && p->pn_op
&& !p->pn_next) {
fprintf(fdst,"(pnode-op :pn_use %d", p->pn_use);
fprintf(fdst,"\n :pn_op "); db_print_op(fdst, p->pn_op);
fprintf(fdst,"\n :pn_left "); db_print_pnode(fdst, p->pn_left);
fprintf(fdst,"\n :pn_right "); db_print_pnode(fdst, p->pn_right);
fprintf(fdst,")\n");
if (!p->pn_name && !p->pn_value && !p->pn_func && p->pn_op &&
!p->pn_next)
{
fprintf(fdst, "(pnode-op :pn_use %d", p->pn_use);
fprintf(fdst, "\n :pn_op "); db_print_op(fdst, p->pn_op);
fprintf(fdst, "\n :pn_left "); db_print_pnode(fdst, p->pn_left);
fprintf(fdst, "\n :pn_right "); db_print_pnode(fdst, p->pn_right);
fprintf(fdst, ")\n");
return;
}
fprintf(fdst,"(pnode :pn_name \"%s\" pn_use %d", p->pn_name, p->pn_use);
fprintf(fdst,"\n :pn_value "); db_print_dvec(fdst, p->pn_value);
fprintf(fdst,"\n :pn_func "); db_print_func(fdst, p->pn_func);
fprintf(fdst,"\n :pn_op "); db_print_op(fdst, p->pn_op);
fprintf(fdst,"\n :pn_left "); db_print_pnode(fdst, p->pn_left);
fprintf(fdst,"\n :pn_right "); db_print_pnode(fdst, p->pn_right);
fprintf(fdst,"\n :pn_next "); db_print_pnode(fdst, p->pn_next);
fprintf(fdst,"\n)\n");
fprintf(fdst, "(pnode :pn_name \"%s\" pn_use %d", p->pn_name, p->pn_use);
fprintf(fdst, "\n :pn_value "); db_print_dvec(fdst, p->pn_value);
fprintf(fdst, "\n :pn_func "); db_print_func(fdst, p->pn_func);
fprintf(fdst, "\n :pn_op "); db_print_op(fdst, p->pn_op);
fprintf(fdst, "\n :pn_left "); db_print_pnode(fdst, p->pn_left);
fprintf(fdst, "\n :pn_right "); db_print_pnode(fdst, p->pn_right);
fprintf(fdst, "\n :pn_next "); db_print_pnode(fdst, p->pn_next);
fprintf(fdst, "\n)\n");
}
@ -538,10 +555,10 @@ db_print_pnode_tree(struct pnode *p, char *print)
#else
char *buf;
size_t buf_size;
FILE *db_stream = open_memstream (&buf, &buf_size);
FILE *db_stream = open_memstream(&buf, &buf_size);
db_print_pnode(db_stream, p);
fclose(db_stream);
if(print)
if (print)
printf("%s:%d: %s {%s}\n%s\n", __FILE__, __LINE__, __func__, print, buf);
return buf;
#endif
@ -560,7 +577,7 @@ PPlex(YYSTYPE *lvalp, struct PPltype *llocp, char **line)
llocp->start = sbuf;
#define lexer_return(token_, length) \
#define lexer_return(token_, length) \
do { token = token_; sbuf += length; goto done; } while(0)
if ((sbuf[0] == 'g') && (sbuf[1] == 't') &&
@ -610,20 +627,20 @@ PPlex(YYSTYPE *lvalp, struct PPltype *llocp, char **line)
case '>':
case '<':
{
/* Workaround, The Frontend makes "<>" into "< >" */
int j = 1;
while (isspace(sbuf[j]))
j++;
if (((sbuf[j] == '<') || (sbuf[j] == '>')) && (sbuf[0] != sbuf[j])) {
/* Allow both <> and >< for NE. */
lexer_return(TOK_NE, j+1);
} else if (sbuf[1] == '=') {
lexer_return((sbuf[0] == '>') ? TOK_GE : TOK_LE, 2);
} else {
lexer_return(*sbuf, 1);
}
{
/* Workaround, The Frontend makes "<>" into "< >" */
int j = 1;
while (isspace(sbuf[j]))
j++;
if (((sbuf[j] == '<') || (sbuf[j] == '>')) && (sbuf[0] != sbuf[j])) {
/* Allow both <> and >< for NE. */
lexer_return(TOK_NE, j+1);
} else if (sbuf[1] == '=') {
lexer_return((sbuf[0] == '>') ? TOK_GE : TOK_LE, 2);
} else {
lexer_return(*sbuf, 1);
}
}
case '?':
case ':':
@ -646,49 +663,49 @@ PPlex(YYSTYPE *lvalp, struct PPltype *llocp, char **line)
lexer_return(*sbuf, 0);
case '"':
{
char *start = ++sbuf;
while(*sbuf && (*sbuf != '"'))
sbuf++;
lvalp->str = copy_substring(start, sbuf);
if(*sbuf)
sbuf++;
lexer_return(TOK_STR, 0);
}
{
char *start = ++sbuf;
while (*sbuf && (*sbuf != '"'))
sbuf++;
lvalp->str = copy_substring(start, sbuf);
if (*sbuf)
sbuf++;
lexer_return(TOK_STR, 0);
}
default:
{
char *s = sbuf;
double *td = ft_numparse(&s, FALSE);
if ((!s || *s != ':') && td) {
sbuf = s;
lvalp->num = *td;
lexer_return(TOK_NUM, 0);
} else {
int atsign = 0;
char *start = sbuf;
/* It is bad how we have to recognise '[' -- sometimes
* it is part of a word, when it defines a parameter
* name, and otherwise it isn't.
* va, ']' too
*/
for (; *sbuf && !strchr(specials, *sbuf); sbuf++)
if (*sbuf == '@')
atsign = 1;
else if (!atsign && ( *sbuf == '[' || *sbuf == ']' ))
break;
{
char *s = sbuf;
double *td = ft_numparse(&s, FALSE);
if ((!s || *s != ':') && td) {
sbuf = s;
lvalp->num = *td;
lexer_return(TOK_NUM, 0);
} else {
int atsign = 0;
char *start = sbuf;
/* It is bad how we have to recognise '[' -- sometimes
* it is part of a word, when it defines a parameter
* name, and otherwise it isn't.
* va, ']' too
*/
for (; *sbuf && !strchr(specials, *sbuf); sbuf++)
if (*sbuf == '@')
atsign = 1;
else if (!atsign && (*sbuf == '[' || *sbuf == ']'))
break;
lvalp->str = copy_substring(start, sbuf);
lexer_return(TOK_STR, 0);
}
lvalp->str = copy_substring(start, sbuf);
lexer_return(TOK_STR, 0);
}
}
}
done:
if (ft_parsedb) {
if(token == TOK_STR)
if (token == TOK_STR)
fprintf(stderr, "lexer: TOK_STR, \"%s\"\n", lvalp->str);
else if(token == TOK_NUM)
else if (token == TOK_NUM)
fprintf(stderr, "lexer: TOK_NUM, %G\n", lvalp->num);
else
fprintf(stderr, "lexer: token %d\n", token);

View File

@ -4,8 +4,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
*
* Do backquote substitution on a word list.
* Do backquote substitution on a word list.
*/
#include "ngspice/config.h"
@ -18,6 +17,7 @@ static wordlist *backeval(char *string);
char cp_back = '`';
wordlist *
cp_bquote(wordlist *wlist)
{
@ -26,12 +26,13 @@ cp_bquote(wordlist *wlist)
int i;
for (wl = wlist; wl; wl = wl->wl_next) {
t = wl->wl_word;
if (!t)
continue;
i = 0;
loop: s =strchr(t, cp_back);
loop:
s = strchr(t, cp_back);
if (s == NULL)
continue;
while (t < s)
@ -47,28 +48,28 @@ loop: s =strchr(t, cp_back);
/* What the heck, let "echo `foo" work... */
*s = '\0';
t++; /* Get past the second ` */
if ((nwl = backeval(buf)) == NULL) {
if ((nwl = backeval(buf)) == NULL) {
wlist->wl_word = NULL;
return (wlist);
}
(void) strcpy(buf, wbuf);
if (nwl->wl_word) {
(void) strcat(buf, nwl->wl_word);
tfree(nwl->wl_word);
}
nwl->wl_word = copy(buf);
(void) strcpy(tbuf, t);
wl = wl_splice(wl, nwl);
for(wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev)
;
/* MW. We must move to the begging of new wordlist. */
(void) strcpy(buf, wbuf);
if (nwl->wl_word) {
(void) strcat(buf, nwl->wl_word);
tfree(nwl->wl_word);
}
nwl->wl_word = copy(buf);
(void) strcpy(tbuf, t);
wl = wl_splice(wl, nwl);
for (wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev)
;
/* MW. We must move to the begging of new wordlist. */
(void) strcpy(buf, wl->wl_word);
i = (int) strlen(buf);
i = (int) strlen(buf);
(void) strcat(buf, tbuf);
tfree(wl->wl_word);
wl->wl_word = copy(buf);
wl->wl_word = copy(buf);
t = &wl->wl_word[i];
s = wl->wl_word;
for (i = 0; s < t; s++)
@ -78,6 +79,7 @@ loop: s =strchr(t, cp_back);
return (wlist);
}
/* Do a popen with the string, and then reset the file pointers so that
* we can use the first pass of the parser on the output.
*/

View File

@ -7,5 +7,4 @@
#define BACKQ_H_INCLUDED
#endif

View File

@ -36,7 +36,7 @@ Modified: 1999 Paolo Nenzi
#endif
#if !defined(__MINGW32__) && !defined(_MSC_VER)
/* MW. We also need ioctl.h here I think */
/* MW. We also need ioctl.h here I think */
#include <sys/ioctl.h>
#endif
@ -54,42 +54,40 @@ Modified: 1999 Paolo Nenzi
#endif
#define CNTRL_D '\004'
#define ESCAPE '\033'
#define CNTRL_D '\004'
#define ESCAPE '\033'
#define NCLASSES 32
bool cp_nocc; /* Don't do command completion. */
static struct ccom *commands = NULL; /* The available commands. */
static struct ccom *keywords[NCLASSES]; /* Keywords. */
/* static declarations */
#ifdef TIOCSTI /* va, functions used in this branch only */
static struct ccom * getccom(char *first);
static wordlist * ccfilec(char *buf);
static wordlist * ccmatch(char *word, struct ccom **dbase);
#ifdef TIOCSTI /* va, functions used in this branch only */
static struct ccom *getccom(char *first);
static wordlist *ccfilec(char *buf);
static wordlist *ccmatch(char *word, struct ccom **dbase);
static void printem(wordlist *wl);
#endif
static wordlist * cctowl(struct ccom *cc, bool sib);
static struct ccom * clookup(register char *word, struct ccom **dd, bool pref,
bool create);
static wordlist *cctowl(struct ccom *cc, bool sib);
static struct ccom *clookup(register char *word, struct ccom **dd, bool pref,
bool create);
/* MW. I need top node in cdelete */
static void cdelete(struct ccom *node, struct ccom **top);
#ifdef TIOCSTI
void
cp_ccom(wordlist *wlist, char *buf, bool esc)
{
struct ccom *cc;
wordlist *a, *pmatches = NULL;
char wbuf[BSIZE_SP], *s;
int i=0;
int i = 0;
int j, arg;
buf = cp_unquote(copy(buf));
@ -104,14 +102,14 @@ cp_ccom(wordlist *wlist, char *buf, bool esc)
/* First filenames. */
if (cc && (cc->cc_kwords[arg] & 1)) {
pmatches = ccfilec(buf);
s =strrchr(buf, '/');
s = strrchr(buf, '/');
i = (int) strlen(s ? s + 1 : buf);
if ((*buf == '~') && !strchr(buf, '/'))
i--;
}
/* The keywords. */
for (j = 1; j < NCLASSES; j++) {
for (j = 1; j < NCLASSES; j++)
if (cc && (cc->cc_kwords[arg] & (1 << j))) {
/* Find all the matching keywords. */
a = ccmatch(buf, &keywords[j]);
@ -121,15 +119,14 @@ cp_ccom(wordlist *wlist, char *buf, bool esc)
else
pmatches = a;
}
}
wl_sort(pmatches);
} else {
pmatches = ccmatch(buf, &commands);
i = (int) strlen(buf);
}
tfree(buf); /*CDHW*/
tfree(buf); /*CDHW*/
if (!esc) {
printem(pmatches);
wl_free(pmatches);
@ -151,21 +148,23 @@ cp_ccom(wordlist *wlist, char *buf, bool esc)
for (j = 0;; j++, i++) {
wbuf[j] = pmatches->wl_word[i];
for (a = pmatches->wl_next; a; a = a->wl_next)
if (a->wl_word[i] != wbuf[j]) {
(void) putchar('\07');
(void) fflush(cp_out);
wbuf[j] = '\0';
goto found;
}
if (a->wl_word[i] != wbuf[j]) {
(void) putchar('\07');
(void) fflush(cp_out);
wbuf[j] = '\0';
goto found;
}
if (wbuf[j] == '\0')
goto found;
}
found: for (i = 0; wbuf[i]; i++)
found:
for (i = 0; wbuf[i]; i++)
(void) ioctl(fileno(cp_in), TIOCSTI, &wbuf[i]);
wl_free(pmatches);
return;
}
/* Figure out what the command is, given the name. Returns NULL if there
* is no such command in the command list. This is tricky, because we have
* to do a preliminary history and alias parse. (Or at least we should.)
@ -177,7 +176,7 @@ getccom(char *first)
struct alias *al;
int ntries = 21;
/* First look for aliases. Just interested in the first word...
/* First look for aliases. Just interested in the first word...
* Don't bother doing history yet -- that might get complicated.
*/
while (ntries-- > 0) {
@ -196,6 +195,7 @@ getccom(char *first)
return (clookup(first, &commands, FALSE, FALSE));
}
/* Figure out what files match the prefix. */
static wordlist *
@ -209,17 +209,15 @@ ccfilec(char *buf)
buf = copy(buf); /* Don't mangle anything... */
lcomp =strrchr(buf, '/');
lcomp = strrchr(buf, '/');
if (lcomp == NULL) {
dir = ".";
lcomp = buf;
if (*buf == cp_til) { /* User name completion... */
buf++;
while ((pw = getpwent()) != NULL) {
if (prefix(buf, pw->pw_name)) {
while ((pw = getpwent()) != NULL)
if (prefix(buf, pw->pw_name))
wl = wl_cons(copy(pw->pw_name), wl);
}
}
(void) endpwent();
return (wl);
}
@ -233,13 +231,14 @@ ccfilec(char *buf)
return (NULL);
}
}
if (!(wdir = opendir(dir)))
return (NULL);
while ((de = readdir(wdir)) != NULL)
if ((prefix(lcomp, de->d_name)) && (*lcomp ||
(*de->d_name != '.'))) {
if ((prefix(lcomp, de->d_name)) && (*lcomp || (*de->d_name != '.')))
wl = wl_cons(copy(de->d_name), wl);
}
(void) closedir(wdir);
wl_sort(wl);
@ -257,18 +256,22 @@ ccmatch(char *word, struct ccom **dbase)
{
wordlist *wl;
register struct ccom *cc;
cc = clookup(word, dbase, TRUE, FALSE);
if (cc) {
if (*word) /* This is a big drag. */
wl = cctowl(cc, FALSE);
else
wl = cctowl(cc, TRUE);
} else
} else {
wl = NULL;
}
return (wl);
}
/* Print the words in the wordlist in columns. They are already
* sorted... This is a hard thing to do with wordlists...
*/
@ -280,28 +283,30 @@ printem(wordlist *wl)
int maxl = 0, num, i, j, k, width = 79, ncols, nlines;
(void) putchar('\n');
if (wl == NULL) {
if (wl == NULL)
return;
}
num = wl_length(wl);
for (ww = wl; ww; ww = ww->wl_next) {
j = (int) strlen(ww->wl_word);
if (j > maxl)
maxl = j;
}
if (++maxl % 8)
maxl += 8 - (maxl % 8);
ncols = width / maxl;
if (ncols == 0)
ncols = 1;
nlines = num / ncols + (num % ncols ? 1 : 0);
for (k = 0; k < nlines; k++) {
for (i = 0; i < ncols; i++) {
j = i * nlines + k;
if (j < num) {
fprintf(cp_out, "%-*s", maxl,
wl_nthelem(j, wl)->wl_word);
} else
if (j < num)
fprintf(cp_out, "%-*s", maxl, wl_nthelem(j, wl)->wl_word);
else
break;
}
(void) putchar('\n');
@ -310,6 +315,7 @@ printem(wordlist *wl)
}
#else /* if not TIOCSTI */
void
cp_ccom(wordlist *wlist, char *buf, bool esc)
{
@ -318,25 +324,26 @@ cp_ccom(wordlist *wlist, char *buf, bool esc)
NG_IGNORE(esc);
return;
}
#endif
static wordlist *
cctowl(struct ccom *cc, bool sib)
{
wordlist *wl;
if (!cc)
return (NULL);
wl = cctowl(cc->cc_child, TRUE);
if (!cc->cc_invalid) {
if (!cc->cc_invalid)
wl = wl_cons(copy(cc->cc_name), wl);
}
if (sib) {
if (sib)
wl = wl_append(wl, cctowl(cc->cc_sibling, TRUE));
}
return (wl);
}
/* We use this in com_device... */
wordlist *
@ -345,6 +352,7 @@ cp_cctowl(struct ccom *stuff)
return (cctowl(stuff, TRUE));
}
/* Turn on and off the escape break character and cooked mode. */
void
@ -404,24 +412,24 @@ cp_ccon(bool on)
if (ison == TRUE) {
#if HAVE_TCGETATTR
tcgetattr(fileno(cp_in),&OS_Buf);
tcgetattr(fileno(cp_in), &OS_Buf);
#else
(void) ioctl(fileno(cp_in), TERM_GET, &OS_Buf);
(void) ioctl(fileno(cp_in), TERM_GET, &OS_Buf);
#endif
sbuf = OS_Buf;
sbuf.c_cc[VEOF] = 0;
sbuf.c_cc[VEOL] = ESCAPE;
sbuf.c_cc[VEOL2] = CNTRL_D;
sbuf = OS_Buf;
sbuf.c_cc[VEOF] = 0;
sbuf.c_cc[VEOL] = ESCAPE;
sbuf.c_cc[VEOL2] = CNTRL_D;
#if HAVE_TCSETATTR
tcsetattr(fileno(cp_in),TCSANOW,&sbuf);
tcsetattr(fileno(cp_in), TCSANOW, &sbuf);
#else
(void) ioctl(fileno(cp_in), TERM_SET, &sbuf);
(void) ioctl(fileno(cp_in), TERM_SET, &sbuf);
#endif
} else {
#ifdef HAVE_TCSETATTR
tcsetattr(fileno(cp_in),TCSANOW,&OS_Buf);
tcsetattr(fileno(cp_in), TCSANOW, &OS_Buf);
#else
(void) ioctl(fileno(cp_in), TERM_SET, &OS_Buf);
(void) ioctl(fileno(cp_in), TERM_SET, &OS_Buf);
#endif
}
@ -435,6 +443,7 @@ cp_ccon(bool on)
return;
}
/* The following routines deal with the command and keyword databases.
* Say whether a given word exists in the command database.
*/
@ -448,6 +457,7 @@ cp_comlook(char *word)
return (FALSE);
}
/* Add a command to the database, with the given keywords and filename
* flag. */
@ -465,19 +475,21 @@ cp_addcomm(char *word, long int bits0, long int bits1, long int bits2, long int
return;
}
/* Remove a command from the database. */
void
cp_remcomm(char *word)
{
struct ccom *cc;
cc = clookup(word, &commands, FALSE, FALSE);
if (cc)
cdelete(cc, &commands);
return;
}
/* Add a keyword to the database. */
void
@ -490,7 +502,7 @@ cp_addkword(int kw_class, char *word)
kw_class);
return;
}
/* word = copy(word); va: not necessary, clookup copies itself (memory leak) */
/* word = copy(word); va: not necessary, clookup copies itself (memory leak) */
cc = clookup(word, &keywords[kw_class], FALSE, TRUE);
cc->cc_invalid = 0;
return;
@ -501,18 +513,19 @@ void
cp_destroy_keywords(void)
{
int i;
for (i=0; i<NCLASSES; i++)
for (i = 0; i < NCLASSES; i++)
throwaway(keywords[i]);
throwaway(commands);
}
/* Remove a keyword from the database. */
void
cp_remkword(int kw_class, char *word)
{
struct ccom *cc;
if ((kw_class < 1) || (kw_class >= NCLASSES)) {
fprintf(cp_err, "cp_remkword: Internal Error: bad class %d\n",
kw_class);
@ -524,6 +537,7 @@ cp_remkword(int kw_class, char *word)
return;
}
/* This routine is used when there are several keyword sets that are
* to be switched between rapidly. The return value is the old tree at
* that position, and the keyword class given is set to the argument.
@ -556,19 +570,22 @@ cp_ccrestart(bool kwords)
return;
}
void
throwaway(struct ccom *dbase)
{
if (!dbase) return; /* va: security first */
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->cc_name); /* va: also tfree dbase->cc_name (memory leak) */
tfree(dbase);
return;
}
/* Look up a word in the database. Because of the way the tree is set
* up, this also works for looking up all words with a given prefix
* (if the pref arg is TRUE). If create is TRUE, then the node is
@ -584,11 +601,11 @@ clookup(register char *word, struct ccom **dd, bool pref, bool create)
if (!place) {
/* This is the first time we were called. */
if (!create)
if (!create) {
return (NULL);
else {
} else {
*dd = place = alloc(struct ccom);
ZERO(place, struct ccom);
ZERO(place, struct ccom);
buf[0] = *word;
buf[1] = '\0';
place->cc_name = copy(buf);
@ -596,6 +613,7 @@ clookup(register char *word, struct ccom **dd, bool pref, bool create)
place->cc_invalid = 1;
}
}
while (word[ind]) {
/* Walk down the sibling list until we find a node that
* matches 'word' to 'ind' places.
@ -606,7 +624,7 @@ clookup(register char *word, struct ccom **dd, bool pref, bool create)
/* This line doesn't go out that far... */
if (create) {
place->cc_sibling = alloc(struct ccom);
ZERO(place->cc_sibling, struct ccom);
ZERO(place->cc_sibling, struct ccom);
place->cc_sibling->cc_ysibling = place;
place->cc_sibling->cc_parent = place->cc_parent;
place = place->cc_sibling;
@ -622,7 +640,7 @@ clookup(register char *word, struct ccom **dd, bool pref, bool create)
if (create) {
/* Put this one between place and its pred. */
tmpc = alloc(struct ccom);
ZERO(tmpc, struct ccom);
ZERO(tmpc, struct ccom);
tmpc->cc_parent = place->cc_parent;
tmpc->cc_sibling = place;
tmpc->cc_ysibling = place->cc_ysibling;
@ -652,7 +670,7 @@ clookup(register char *word, struct ccom **dd, bool pref, bool create)
/* No children, maybe make one and go on. */
if (create) {
tmpc = alloc(struct ccom);
ZERO(tmpc, struct ccom);
ZERO(tmpc, struct ccom);
tmpc->cc_parent = place;
place->cc_child = tmpc;
place = tmpc;
@ -665,57 +683,63 @@ clookup(register char *word, struct ccom **dd, bool pref, bool create)
} else {
return (NULL);
}
} else
} else {
place = place->cc_child;
}
ind++;
} else
} else {
break;
}
}
if (!pref && !create && place->cc_invalid) {
/* This is no good, we want a real word. */
return (NULL);
}
return (place);
}
/* Delete a node from the tree. Returns the new tree... */
/* MW. It is quite difficoult to free() everything right, but...
/* MW. It is quite difficoult to free() everything right, but...
* Anyway this could be more optimal, I think */
static void
cdelete(struct ccom *node, struct ccom **top)
{
/* if cc_child exist only mark as deleted */
node->cc_invalid = 1;
if (node->cc_child)
return;
/* fix cc_sibling */
if (node->cc_sibling)
node->cc_sibling->cc_ysibling = node->cc_ysibling;
if (node->cc_ysibling)
node->cc_ysibling->cc_sibling = node->cc_sibling;
/* if we have cc_parent, check if it should not be removed too */
if (node->cc_parent) {
/* this node will be free() */
if (node->cc_parent->cc_child == node) {
if (node->cc_ysibling)
node->cc_parent->cc_child = node->cc_ysibling;
else
node->cc_parent->cc_child = node->cc_sibling;
}
if (node->cc_parent->cc_invalid == 1)
/* free parent only if it is invalid */
cdelete(node->cc_parent, top);
}
/* now free() everything and check the top */
if (node == *top)
*top = node->cc_sibling;
tfree(node->cc_name); /* va: we should allways use tfree */
tfree(node);
return;
}
/* if cc_child exist only mark as deleted */
node->cc_invalid = 1;
if (node->cc_child)
return;
/* fix cc_sibling */
if (node->cc_sibling)
node->cc_sibling->cc_ysibling = node->cc_ysibling;
if (node->cc_ysibling)
node->cc_ysibling->cc_sibling = node->cc_sibling;
/* if we have cc_parent, check if it should not be removed too */
if (node->cc_parent) {
/* this node will be free() */
if (node->cc_parent->cc_child == node) {
if (node->cc_ysibling)
node->cc_parent->cc_child = node->cc_ysibling;
else
node->cc_parent->cc_child = node->cc_sibling;
}
/* free parent only if it is invalid */
if (node->cc_parent->cc_invalid == 1)
cdelete(node->cc_parent, top);
}
/* now free() everything and check the top */
if (node == *top)
*top = node->cc_sibling;
tfree(node->cc_name); /* va: we should allways use tfree */
tfree(node);
return;
}

View File

@ -14,18 +14,17 @@
*/
#define NARGS 4
struct ccom {
char *cc_name; /* Command or keyword name. */
long cc_kwords[NARGS]; /* What this command takes. */
char cc_invalid; /* This node has been deleted. */
struct ccom *cc_child; /* Left-most child. */
struct ccom *cc_sibling;/* Right (alph. greater) sibling. */
struct ccom *cc_ysibling;/* Left (alph. less) sibling. */
struct ccom *cc_parent; /* Parent node. */
} ;
char *cc_name; /* Command or keyword name. */
long cc_kwords[NARGS]; /* What this command takes. */
char cc_invalid; /* This node has been deleted. */
struct ccom *cc_child; /* Left-most child. */
struct ccom *cc_sibling; /* Right (alph. greater) sibling. */
struct ccom *cc_ysibling; /* Left (alph. less) sibling. */
struct ccom *cc_parent; /* Parent node. */
};
void throwaway(struct ccom *dbase);

View File

@ -43,7 +43,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
* and command ignoring. Also deal with command completion.
* (2) Do history substitutions. (!, ^)
* (3) Do alias substitution.
*
*
* In front.c these things get done:
* (4) Do variable substitution. ($varname)
* (5) Do backquote substitution. (``)
@ -51,7 +51,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
* (7) Do io redirection.
*/
/* static functions */
static void pwlist(wordlist *wlist, char *name);
@ -91,6 +90,7 @@ cp_parse(char *string)
return (wlist);
}
static void
pwlist(wordlist *wlist, char *name)
{
@ -104,4 +104,3 @@ pwlist(wordlist *wlist, char *name)
fprintf(cp_err, "]\n");
return;
}

View File

@ -32,7 +32,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#endif
char cp_comma = ',';
char cp_ocurl = '{';
char cp_ccurl = '}';
@ -52,7 +51,7 @@ static wordlist *brac2(char *string);
wordlist *
cp_doglob(wordlist *wlist)
{
wordlist *wl;
wordlist *wl;
char *s;
/* Expand {a,b,c} */
@ -76,14 +75,15 @@ cp_doglob(wordlist *wlist)
s = cp_tildexpand(wl->wl_word);
txfree(wl->wl_word); /* sjb - fix memory leak */
if (!s)
*wl->wl_word = '\0'; /* MW. We Con't touch tmalloc addres */
*wl->wl_word = '\0'; /* MW. We Con't touch tmalloc addres */
else
wl->wl_word = s;
wl->wl_word = s;
}
return (wlist);
}
static wordlist *
bracexpand(char *string)
{
@ -145,9 +145,10 @@ brac1(char *string)
}
wl_free(words);
words = newwl;
} else
} else {
for (wl = words; wl; wl = wl->wl_next)
appendc(wl->wl_word, *s);
}
}
return (words);
}
@ -200,17 +201,17 @@ brac2(char *string)
char *
cp_tildexpand(char *string)
{
char *result;
char *result;
result = tildexpand(string);
if (!result) {
if (cp_nonomatch) {
return copy(string);
} else {
return NULL;
}
if (cp_nonomatch)
return copy(string);
else
return NULL;
}
return result;
}
@ -222,6 +223,5 @@ cp_tildexpand(char *string)
bool
cp_globmatch(char *p, char *s)
{
return(!(strcmp(p, s)));
return (!(strcmp(p, s)));
}

View File

@ -7,5 +7,4 @@
#define GLOB_H_INCLUDED
#endif

View File

@ -18,50 +18,53 @@ Author: 1988 Jeffrey M. Hsu
#ifdef _MSC_VER
#include "BaseTsd.h" /* for SSIZE_T */
#define ssize_t SSIZE_T
#ifndef HAS_WINDOWS
#ifndef HAS_WINDOWS
#define read _read /* only for console */
#endif
#endif
/* A special 'getc' so that we can deal with ^D properly. There is no way for
* stdio to know if we have typed a ^D after some other characters, so
* don't use buffering at all
*/
int
inchar(FILE *fp)
{
#ifndef HAS_WINDOWS
#ifndef HAS_WINDOWS
char c;
ssize_t i;
if (cp_interactive && !cp_nocc) {
do {
i = read(fileno(fp), &c, 1);
} while (i == -1 && errno == EINTR);
if (i == 0 || c == '\004')
return (EOF);
else if (i == -1) {
perror("read");
return (EOF);
} else
return ((int) c);
do
i = read(fileno(fp), &c, 1);
while (i == -1 && errno == EINTR);
if (i == 0 || c == '\004') {
return (EOF);
} else if (i == -1) {
perror("read");
return (EOF);
} else {
return ((int) c);
}
} else
#endif
return (getc(fp));
#endif
return (getc(fp));
}
int
int
input(FILE *fp)
{
REQUEST request;
RESPONSE response;
request.option = char_option;
request.fp = fp;
Input(&request, &response);
return(inchar(fp));
Input(&request, &response);
return (inchar(fp));
}

View File

@ -213,8 +213,9 @@ nloop:
goto done;
case '\'':
while (((c = (string ? *string++ : input(cp_inp_cur))) != '\'')
&& (i < NEW_BSIZE_SP - 1)) {
while (((c = (string ? *string++ : input(cp_inp_cur))) != '\'') &&
(i < NEW_BSIZE_SP - 1))
{
if ((c == '\n') || (c == EOF) || (c == ESCAPE))
goto gotchar;
buf[i++] = (char) quote(c);
@ -227,8 +228,9 @@ nloop:
case '`':
d = c;
buf[i++] = (char) d;
while (((c = (string ? *string++ : input(cp_inp_cur))) != d)
&& (i < NEW_BSIZE_SP - 2)) {
while (((c = (string ? *string++ : input(cp_inp_cur))) != d) &&
(i < NEW_BSIZE_SP - 2))
{
if ((c == '\n') || (c == EOF) || (c == ESCAPE))
goto gotchar;
if (c == '\\') {
@ -269,7 +271,7 @@ nloop:
#ifdef TIOCSTI
(void) ioctl(fileno(cp_out), TIOCSTI, linebuf + j);
#else
fputc(linebuf[j], cp_out); /* But you can't edit */
fputc(linebuf[j], cp_out); /* But you can't edit */
#endif
wlist = cw = NULL;
goto nloop;
@ -294,7 +296,7 @@ nloop:
#ifdef TIOCSTI
(void) ioctl(fileno(cp_out), TIOCSTI, linebuf + j);
#else
fputc(linebuf[j], cp_out); /* But you can't edit */
fputc(linebuf[j], cp_out); /* But you can't edit */
#endif
// cp_ccom doesn't mess wlist, read only access to wlist->wl_word
cp_ccom(wlist, buf, TRUE);
@ -327,7 +329,7 @@ nloop:
case '<':
case '>': /* va: <=, >= are unbreakable words */
if(string)
if (string)
if ((i == 0) && (*string == '=')) {
buf[i++] = (char) c;
break;
@ -351,7 +353,7 @@ nloop:
done:
if (wlist->wl_word)
pwlist_echo(wlist,"Command>");
pwlist_echo(wlist, "Command>");
return wlist;
}

View File

@ -25,6 +25,7 @@ power10(double num) /* Chris Inbody */
bool ft_strictnumparse = FALSE;
/* Parse a number. This will handle things like 10M, etc... If the number
* must not end before the end of the string, then whole is TRUE.
* If whole is FALSE and there is more left to the number, the argument
@ -34,6 +35,7 @@ bool ft_strictnumparse = FALSE;
*
* If ft_strictnumparse is TRUE, and whole is FALSE, the first of the
* trailing characters must be a '_'. */
double *
ft_numparse(char **s, bool whole)
{
@ -44,22 +46,22 @@ ft_numparse(char **s, bool whole)
char *string = *s;
/* See if the number begins with + or -. */
if (*string == '+')
if (*string == '+') {
string++;
else if (*string == '-') {
} else if (*string == '-') {
string++;
sign = -1;
}
/* We don't want to recognise "P" as 0P, or .P as 0.0P... */
if ((!isdigit(*string) && *string != '.') ||
((*string == '.') && !isdigit(string[1])))
((*string == '.') && !isdigit(string[1])))
return (NULL);
/* Now accumulate a number. Note ascii dependencies here... */
while (isdigit(*string))
mant = mant * 10.0 + (*string++ - '0');
/* Now maybe a decimal point. */
if (*string == '.') {
string++;
@ -70,81 +72,83 @@ ft_numparse(char **s, bool whole)
/* Now look for the scale factor or the exponent (can't have both). */
switch (*string) {
case 'e':
case 'E':
/* Parse another number. */
case 'e':
case 'E':
/* Parse another number. */
string++;
if (*string == '+') {
exsign = 1;
string++;
if (*string == '+') {
exsign = 1;
string++;
} else if (*string == '-') {
exsign = -1;
string++;
}
while(isdigit(*string))
expo = expo * 10.0 + (*string++ - '0');
if (*string == '.') {
string++;
p = 1;
while (isdigit(*string))
expo += (*string++ - '0') / power10(p++);
}
expo *= exsign;
break;
case 't':
case 'T':
expo = 12.0;
} else if (*string == '-') {
exsign = -1;
string++;
break;
case 'g':
case 'G':
expo = 9.0;
}
while (isdigit(*string))
expo = expo * 10.0 + (*string++ - '0');
if (*string == '.') {
string++;
break;
case 'k':
case 'K':
expo = 3.0;
string++;
break;
case 'u':
case 'U':
p = 1;
while (isdigit(*string))
expo += (*string++ - '0') / power10(p++);
}
expo *= exsign;
break;
case 't':
case 'T':
expo = 12.0;
string++;
break;
case 'g':
case 'G':
expo = 9.0;
string++;
break;
case 'k':
case 'K':
expo = 3.0;
string++;
break;
case 'u':
case 'U':
expo = -6.0;
string++;
break;
case 'n':
case 'N':
expo = -9.0;
string++;
break;
case 'p':
case 'P':
expo = -12.0;
string++;
break;
case 'f':
case 'F':
expo = -15.0;
string++;
break;
case 'm':
case 'M':
/* Can be either m, mil, or meg. */
if (string[1] && string[2] &&
((string[1] == 'e') || (string[1] == 'E')) &&
((string[2] == 'g') || (string[2] == 'G')))
{
expo = 6.0;
string += 3;
} else if (string[1] && string[2] &&
((string[1] == 'i') || (string[1] == 'I')) &&
((string[2] == 'l') || (string[2] == 'L')))
{
expo = -6.0;
mant *= 25.4;
string += 3;
} else {
expo = -3.0;
string++;
break;
case 'n':
case 'N':
expo = -9.0;
string++;
break;
case 'p':
case 'P':
expo = -12.0;
string++;
break;
case 'f':
case 'F':
expo = -15.0;
string++;
break;
case 'm':
case 'M':
/* Can be either m, mil, or meg. */
if (string[1] && string[2] &&
((string[1] == 'e') || (string[1] == 'E')) &&
((string[2] == 'g') || (string[2] == 'G'))) {
expo = 6.0;
string += 3;
} else if (string[1] && string[2] &&
((string[1] == 'i') || (string[1] == 'I')) &&
((string[2] == 'l') || (string[2] == 'L'))) {
expo = -6.0;
mant *= 25.4;
string += 3;
} else {
expo = -3.0;
string++;
}
break;
}
break;
}
if (whole && *string != '\0') {

View File

@ -7,7 +7,4 @@
#define NUMPARSE_H_INCLUDED
#endif

View File

@ -48,7 +48,8 @@ struct hashent {
char *h_name;
char *h_path;
struct hashent *h_next;
} ;
};
#define HASHSIZE 256
@ -56,6 +57,7 @@ static struct hashent *hashtab[HASHSIZE];
static char *dirbuffer;
static int dirlength, dirpos;
/* Create the hash table for the given search path. pathlist is a : seperated
* list of directories. If docc is TRUE, then all the commands found are
* added to the command completion lists.
@ -79,23 +81,23 @@ cp_rehash(char *pathlist, bool docc)
*/
tfree(hh);
}
hashtab[i] = NULL;
hashtab[i] = NULL;
}
while (pathlist && *pathlist) {
/* Copy one path to buf. We have to make sure that the path
* is a full path name.
*/
if (*pathlist == '/')
if (*pathlist == '/') {
i = 0;
else {
} else {
#ifdef HAVE_GETWD
(void) getwd(buf);
#else
# ifdef HAVE_GETCWD
# ifdef HAVE_GETCWD
(void) getcwd(buf, sizeof(buf));
# else
*buf = 0;
*buf = 0;
# endif
#endif
i = strlen(buf);
@ -115,7 +117,7 @@ cp_rehash(char *pathlist, bool docc)
(void) strcat(pbuf, entry->d_name);
/* Now we could make sure that it is really an
* executable, but that is too slow
* (as if "we" really cared).
* (as if "we" really cared).
*/
hh = alloc(struct hashent);
hh->h_name = copy(entry->d_name);
@ -129,19 +131,21 @@ cp_rehash(char *pathlist, bool docc)
while (ht->h_next)
ht = ht->h_next;
ht->h_next = hh;
} else
} else {
hashtab[i] = hh;
}
if (docc) {
/* Add to completion hash table. */
cp_addcomm(entry->d_name, (long) 0, (long) 0, (long) 0,
(long) 0);
cp_addcomm(entry->d_name, (long) 0, (long) 0, (long) 0, (long) 0);
}
}
closedir(pdir);
closedir(pdir);
}
return;
}
/* The return value is FALSE if no command was found, and TRUE if it was. */
bool
@ -165,16 +169,16 @@ cp_unixcom(wordlist *wl)
if (strchr(name, '/'))
return (tryexec(name, argv));
i = hash(name);
for (hh = hashtab[i]; hh; hh = hh->h_next) {
for (hh = hashtab[i]; hh; hh = hh->h_next)
if (eq(name, hh->h_name)) {
(void) sprintf(buf, "%s/%s", hh->h_path, hh->h_name);
if (tryexec(buf, argv))
return (TRUE);
}
}
return (FALSE);
}
static bool
tryexec(char *name, char *argv[])
{
@ -183,33 +187,36 @@ tryexec(char *name, char *argv[])
# else
union wait status;
# endif
int pid, j;
RETSIGTYPE (*svint)( ), (*svquit)( ), (*svtstp)( );
pid = vfork( );
int pid, j;
RETSIGTYPE (*svint)(), (*svquit)(), (*svtstp)();
pid = vfork();
if (pid == 0) {
fixdescriptors();
fixdescriptors();
(void) execv(name, argv);
(void) _exit(120); /* A random value. */
/* NOTREACHED */
} else {
svint = signal(SIGINT, SIG_DFL);
svquit = signal(SIGQUIT, SIG_DFL);
svtstp = signal(SIGTSTP, SIG_DFL);
svint = signal(SIGINT, SIG_DFL);
svquit = signal(SIGQUIT, SIG_DFL);
svtstp = signal(SIGTSTP, SIG_DFL);
do {
j = wait(&status);
} while (j != pid);
(void) signal(SIGINT, (SIGNAL_FUNCTION) svint);
(void) signal(SIGQUIT, (SIGNAL_FUNCTION) svquit);
(void) signal(SIGTSTP, (SIGNAL_FUNCTION) svtstp);
(void) signal(SIGINT, (SIGNAL_FUNCTION) svint);
(void) signal(SIGQUIT, (SIGNAL_FUNCTION) svquit);
(void) signal(SIGTSTP, (SIGNAL_FUNCTION) svtstp);
}
if (WTERMSIG(status) == 0 && WEXITSTATUS(status) == 120)
/*if ((status.w_termsig == 0) && (status.w_retcode == 120)) */
return (FALSE);
/*if ((status.w_termsig == 0) && (status.w_retcode == 120)) */
return (FALSE);
else
return (TRUE);
return (TRUE);
}
static int
hash(register char *str)
{
@ -217,9 +224,11 @@ hash(register char *str)
while (*str)
i += *str++;
return (i % HASHSIZE);
}
/* Debugging. */
void
@ -235,8 +244,10 @@ cp_hstat(void)
return;
}
#else
void
cp_rehash(char *pathlist, bool docc)
{
@ -244,6 +255,7 @@ cp_rehash(char *pathlist, bool docc)
NG_IGNORE(pathlist);
}
bool
cp_unixcom(wordlist *wl)
{
@ -253,7 +265,6 @@ cp_unixcom(wordlist *wl)
return (FALSE);
else
return (TRUE);
}
#endif

View File

@ -7,7 +7,4 @@
#define UNIXCOM_H_INCLUDED
#endif

View File

@ -15,11 +15,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "agraf.h"
#define FUDGE 7
#define MARGIN_BASE 11
#define LCHAR '.'
#define MCHAR 'X'
#define PCHARS "+*=$%!0123456789"
#define FUDGE 7
#define MARGIN_BASE 11
#define LCHAR '.'
#define MCHAR 'X'
#define PCHARS "+*=$%!0123456789"
/* We should really deal with the xlog and delta arguments. This routine is
* full of magic numbers that make the formatting correct.
@ -52,40 +52,43 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
/* ANSI C does not specify how many digits are in an exponent for %c
* We assumed it was 2. If it's more, shift starting position over.
*/
sprintf(buf, "%1.1e", 0.0); /* expect 0.0e+00 */
sprintf(buf, "%1.1e", 0.0); /* expect 0.0e+00 */
shift = (int) strlen(buf) - 7;
margin += shift;
/* Make sure the margin is correct */
omargin = margin;
novalue = cp_getvar("noasciiplotvalue", CP_BOOL, NULL);
if (!novalue &&
!vec_eq(xscale, vecs)) {
if (!novalue && !vec_eq(xscale, vecs))
margin *= 2;
} else
else
novalue = TRUE;
if ((xscale->v_gridtype == GRID_YLOG) ||
(xscale->v_gridtype == GRID_LOGLOG))
if ((xscale->v_gridtype == GRID_YLOG) || (xscale->v_gridtype == GRID_LOGLOG))
ylogscale = TRUE;
if (!cp_getvar("width", CP_NUM, &maxy)) {
maxy = DEF_WIDTH;
}
if (!cp_getvar("width", CP_NUM, &maxy))
maxy = DEF_WIDTH;
if (!cp_getvar("height", CP_NUM, &height))
height = DEF_HEIGHT;
if (ft_nopage)
nobreakp = TRUE;
nobreakp = TRUE;
else
nobreakp = cp_getvar("nobreak", CP_BOOL, NULL);
nobreakp = cp_getvar("nobreak", CP_BOOL, NULL);
maxy -= (margin + FUDGE);
maxx = xscale->v_length;
xrange[0] = xlims[0];
xrange[1] = xlims[1];
yrange[0] = ylims[0];
yrange[1] = ylims[1];
if (maxx < 2) {
fprintf(cp_err,
"Error: asciiplot can't handle scale with length < 2\n");
fprintf(cp_err,
"Error: asciiplot can't handle scale with length < 2\n");
return;
}
@ -94,16 +97,16 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
return;
}
for (v = vecs, i = 0; v; v = v->v_link2) {
for (v = vecs, i = 0; v; v = v->v_link2)
v->v_linestyle = (PCHARS[i] ? PCHARS[i++] : '#');
}
/* Now allocate the field and stuff. */
field = TMALLOC(char, (maxy + 1) * (maxx + 1));
line1 = TMALLOC(char, maxy + margin + FUDGE + 1);
line2 = TMALLOC(char, maxy + margin + FUDGE + 1);
if (!novalue)
values = TMALLOC(double, maxx);
/* Clear the field, put the lines in the right places, and create
* the headers.
*/
@ -117,8 +120,8 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
/* The following is similar to the stuff in grid.c */
if ((xrange[0] > xrange[1]) || (yrange[0] > yrange[1])) {
fprintf(cp_err,
"ft_agraf: Internal Error: bad limits %g, %g, %g, %g\n",
fprintf(cp_err,
"ft_agraf: Internal Error: bad limits %g, %g, %g, %g\n",
xrange[0], xrange[1], yrange[0], yrange[1]);
return;
}
@ -127,7 +130,7 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
if (ylims[1] == 0.0) {
mag = (int) floor(mylog10(- ylims[0]));
tenpowmag = pow(10.0, (double) mag);
} else if (ylims[0] == 0.0) {
} else if (ylims[0] == 0.0) {
mag = (int) floor(mylog10(ylims[1]));
tenpowmag = pow(10.0, (double) mag);
} else {
@ -144,17 +147,17 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
dst = hmt - lmt;
/* This is a strange case; I don't know why it's here. */
if (dst == 11)
if (dst == 11) {
dst = 12;
else if (dst == 1) {
} else if (dst == 1) {
dst = 10;
mag++;
hmt *= 10;
lmt *= 10;
} else if (dst == 0) {
dst = 2;
lmt -= 1;
hmt += 1;
lmt -= 1;
hmt += 1;
}
for (nsp = 4; nsp < 8; nsp++)
@ -176,7 +179,7 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
line1[i + margin + 2 * shift] = '|';
(void) sprintf(buf, "%.2e", j * pow(10.0, (double) mag));
bcopy(buf, &line2[i + margin - ((j < 0) ? 2 : 1) - shift],
strlen(buf));
strlen(buf));
}
line1[i - spacing + margin + 1] = '\0';
@ -184,8 +187,8 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
line2[i] = xscale->v_name[i - 1];
if (!novalue)
for (i = omargin + 1;
i < margin - 2 && (vecs->v_name[i - omargin - 1]);
i++)
i < margin - 2 && (vecs->v_name[i - omargin - 1]);
i++)
line2[i] = vecs->v_name[i - omargin - 1];
/* Now the buffers are all set up properly. Plot points for each
@ -198,29 +201,29 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
for (i = 0; i < maxx; i++) {
if (nointerp)
x = isreal(xscale) ? xscale->v_realdata[i] :
realpart(xscale->v_compdata[i]);
realpart(xscale->v_compdata[i]);
else if (xlog && xrange[0] > 0.0 && xrange[1] > 0.0)
x = xrange[0] * pow( 10.0, mylog10(xrange[1]/xrange[0])
* i / (maxx - 1));
x = xrange[0] * pow(10.0, mylog10(xrange[1]/xrange[0])
* i / (maxx - 1));
else
x = xrange[0] + (xrange[1] - xrange[0]) * i /
(maxx - 1);
(maxx - 1);
while ((isreal(xscale) ? (xscale->v_realdata[upper] < x) :
(realpart(xscale->v_compdata[upper]) < x)) &&
(upper < xscale->v_length - 1))
(upper < xscale->v_length - 1))
upper++;
while ((isreal(xscale) ? (xscale->v_realdata[lower] < x) :
(realpart(xscale->v_compdata[lower]) < x)) &&
(lower < xscale->v_length - 1))
(lower < xscale->v_length - 1))
lower++;
if ((isreal(xscale) ? (xscale->v_realdata[lower] > x) :
(realpart(xscale->v_compdata[lower]) > x)) &&
(lower > 0))
(realpart(xscale->v_compdata[lower]) > x)) &&
(lower > 0))
lower--;
x1 = (isreal(xscale) ? xscale->v_realdata[lower] :
realpart(xscale->v_compdata[lower]));
realpart(xscale->v_compdata[lower]));
x2 = (isreal(xscale) ? xscale->v_realdata[upper] :
realpart(xscale->v_compdata[upper]));
realpart(xscale->v_compdata[upper]));
if (x1 > x2) {
fprintf(cp_err, "Error: X scale (%s) not monotonic\n",
xscale->v_name);
@ -228,9 +231,9 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
}
for (v = vecs; v; v = v->v_link2) {
yy1 = (isreal(v) ? v->v_realdata[lower] :
realpart(v->v_compdata[lower]));
realpart(v->v_compdata[lower]));
y2 = (isreal(v) ? v->v_realdata[upper] :
realpart(v->v_compdata[upper]));
realpart(v->v_compdata[upper]));
if (x1 == x2)
y = yy1;
else
@ -245,7 +248,7 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
field[omaxy * i + ypt] = MCHAR;
}
}
out_init();
for (i = 0; i < omaxy + margin; i++)
out_send("-");
@ -268,8 +271,10 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
out_send("Legend: ");
i = 0;
j = (maxx + margin - 8) / 20;
if (j == 0)
j = 1;
for (v = vecs; v; v = v->v_link2) {
out_printf("%c = %-17s", (char) v->v_linestyle, v->v_name);
if (!(++i % j) && v->v_link2) {
@ -278,45 +283,49 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
}
}
out_send("\n");
for (i = 0; i < omaxy + margin; i++)
out_send("-");
out_send("\n");
i = 0;
out_printf("%s\n%s\n", line2, line1);
curline += 2;
for (i = 0; i < maxx; i++) {
if (nointerp)
x = isreal(xscale) ? xscale->v_realdata[i] :
x = isreal(xscale) ? xscale->v_realdata[i] :
realpart(xscale->v_compdata[i]);
else if (xlog && xrange[0] > 0.0 && xrange[1] > 0.0)
x = xrange[0] * pow( 10.0, mylog10(xrange[1]/xrange[0])
* i / (maxx - 1));
else
x = xrange[0] + (xrange[1] - xrange[0]) * i / (maxx - 1);
if (x < 0.0) {
x = xrange[0] * pow(10.0, mylog10(xrange[1]/xrange[0])
* i / (maxx - 1));
else
x = xrange[0] + (xrange[1] - xrange[0]) * i / (maxx - 1);
if (x < 0.0)
out_printf("%.3e ", x);
} else {
else
out_printf(" %.3e ", x);
}
if (!novalue) {
if (values[i] < 0.0) {
if (values[i] < 0.0)
out_printf("%.3e ", values[i]);
} else {
else
out_printf(" %.3e ", values[i]);
}
}
cb = field[(i + 1) * omaxy];
field[(i + 1) * omaxy] = '\0';
out_send(&field[i * omaxy]);
field[(i + 1) * omaxy] = cb;
out_send("\n");
if (((curline++ % height) == 0) && (i < maxx - 1) &&
!nobreakp) {
out_printf("%s\n%s\n\014\n%s\n%s\n", line1, line2,
line2, line1);
if (((curline++ % height) == 0) && (i < maxx - 1) && !nobreakp) {
out_printf("%s\n%s\n\014\n%s\n%s\n",
line1, line2, line2, line1);
curline += 5;
}
}
out_printf("%s\n%s\n", line1, line2);
tfree(field);
@ -324,5 +333,6 @@ ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, s
tfree(line2);
if (!novalue)
tfree(values);
return;
}

View File

@ -11,8 +11,8 @@
#include "ngspice/plot.h"
void ft_agraf(double *xlims, double *ylims, struct dvec *xscale,
struct plot *plot, struct dvec *vecs,
double xdel, double ydel, bool xlog, bool ylog,
bool nointerp);
struct plot *plot, struct dvec *vecs,
double xdel, double ydel, bool xlog, bool ylog,
bool nointerp);
#endif

View File

@ -58,10 +58,11 @@ clip_line(int *pX1, int *pY1, int *pX2, int *pY2, int l, int b, int r, int t)
int x2 = *pX2;
int y2 = *pY2;
int x = 0, y = 0;
int c,c1,c2;
int c, c1, c2;
CODE(x1, y1, c1);
CODE(x2, y2, c2);
CODE(x1,y1,c1);
CODE(x2,y2,c2);
while (c1 || c2) {
if (c1 & c2)
return (TRUE); /* Line is invisible. */
@ -83,11 +84,11 @@ clip_line(int *pX1, int *pY1, int *pX2, int *pY2, int l, int b, int r, int t)
if (c == c1) {
x1 = x;
y1 = y;
CODE(x,y,c1);
CODE(x, y, c1);
} else {
x2 = x;
y2 = y;
CODE(x,y,c2);
y2 = y;
CODE(x, y, c2);
}
}
*pX1 = x1;
@ -97,6 +98,7 @@ clip_line(int *pX1, int *pY1, int *pX2, int *pY2, int l, int b, int r, int t)
return (FALSE); /* Line is at least partially visible.*/
}
/* This routine will clip a line to a circle, returning TRUE if the line
* is entirely outside the circle. Note that we have to be careful not
* to switch the points around, since in grid.c we need to know which is
@ -115,13 +117,13 @@ clip_to_circle(int *x1, int *y1, int *x2, int *y2, int cx, int cy, int rad)
/* Get the angles between the origin and the endpoints. */
if ((*x1-cx) || (*y1-cy))
theta1 = atan2((double) *y1 - cy, (double) *x1 - cx);
theta1 = atan2((double) *y1 - cy, (double) *x1 - cx);
else
theta1 = M_PI;
theta1 = M_PI;
if ((*x2-cx) || (*y2-cy))
theta2 = atan2((double) *y2 - cy, (double) *x2 - cx);
theta2 = atan2((double) *y2 - cy, (double) *x2 - cx);
else
theta2 = M_PI;
theta2 = M_PI;
if (theta1 < 0.0)
theta1 = 2 * M_PI + theta1;
@ -152,8 +154,7 @@ clip_to_circle(int *x1, int *y1, int *x2, int *y2, int cx, int cy, int rad)
/* Figure out the distances between the points */
a = sqrt((double) ((*x1 - cx) * (*x1 - cx) + (*y1 - cy) * (*y1 - cy)));
b = sqrt((double) ((*x2 - cx) * (*x2 - cx) + (*y2 - cy) * (*y2 - cy)));
c = sqrt((double) ((*x1 - *x2) * (*x1 - *x2) +
(*y1 - *y2) * (*y1 - *y2)));
c = sqrt((double) ((*x1 - *x2) * (*x1 - *x2) + (*y1 - *y2) * (*y1 - *y2)));
/* We have three cases now -- either the midpoint of the line is
* closest to the origon, or point 1 or point 2 is. Actually the
@ -198,6 +199,7 @@ clip_to_circle(int *x1, int *y1, int *x2, int *y2, int cx, int cy, int rad)
*x1 = (int)(cx + rad * cos(theta1 + beta));
*y1 = (int)(cy + rad * sin(theta1 + beta));
}
if (b > rad) {
tt = (c * c + b * b - a * a) / (2 * b * c);
if (tt > 1.0)
@ -212,6 +214,7 @@ clip_to_circle(int *x1, int *y1, int *x2, int *y2, int cx, int cy, int rad)
*x2 = (int)(cx + rad * cos(theta2 - beta));
*y2 = (int)(cy + rad * sin(theta2 - beta));
}
if (flip) {
i = *x1;
*x1 = *x2;
@ -220,5 +223,6 @@ clip_to_circle(int *x1, int *y1, int *x2, int *y2, int cx, int cy, int rad)
*y1 = *y2;
*y2 = i;
}
return (FALSE);
}

View File

@ -20,10 +20,10 @@
#define GP_MAXVECTORS 64
void
ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, struct dvec *vecs)
{
FILE *file, *file_data;
struct dvec *v, *scale = NULL;
double xval, yval;
@ -38,13 +38,13 @@ ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlab
sprintf(filename_plt, "%s.plt", filename);
/* Sanity checking. */
for ( v = vecs, numVecs = 0; v; v = v->v_link2 ) {
for (v = vecs, numVecs = 0; v; v = v->v_link2)
numVecs++;
}
if (numVecs == 0) {
return;
} else if (numVecs > GP_MAXVECTORS) {
fprintf( cp_err, "Error: too many vectors for gnuplot.\n" );
fprintf(cp_err, "Error: too many vectors for gnuplot.\n");
return;
}
if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth))
@ -54,11 +54,10 @@ ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlab
if (!cp_getvar("pointstyle", CP_STRING, pointstyle)) {
markers = FALSE;
} else {
if (cieq(pointstyle,"markers")) {
if (cieq(pointstyle,"markers"))
markers = TRUE;
} else {
else
markers = FALSE;
}
}
@ -84,7 +83,7 @@ ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlab
xlog = ylog = FALSE;
break;
default:
fprintf( cp_err, "Error: grid type unsupported by gnuplot.\n" );
fprintf(cp_err, "Error: grid type unsupported by gnuplot.\n");
return;
}
@ -97,63 +96,59 @@ ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlab
/* Set up the file header. */
if (title) {
text = cp_unquote(title);
fprintf( file, "set title \"%s\"\n", text );
fprintf(file, "set title \"%s\"\n", text);
tfree(text);
}
if (xlabel) {
text = cp_unquote(xlabel);
fprintf( file, "set xlabel \"%s\"\n", text );
fprintf(file, "set xlabel \"%s\"\n", text);
tfree(text);
}
if (ylabel) {
text = cp_unquote(ylabel);
fprintf( file, "set ylabel \"%s\"\n", text );
fprintf(file, "set ylabel \"%s\"\n", text);
tfree(text);
}
if (!nogrid) {
if (linewidth > 1)
fprintf( file, "set grid lw %d \n" , linewidth );
fprintf(file, "set grid lw %d \n" , linewidth);
else
fprintf( file, "set grid\n" );
fprintf(file, "set grid\n");
}
if (xlog) {
fprintf( file, "set logscale x\n" );
if (xlims) {
fprintf( file, "set xrange [%e:%e]\n", xlims[0], xlims[1] );
}
fprintf(file, "set logscale x\n");
if (xlims)
fprintf(file, "set xrange [%e:%e]\n", xlims[0], xlims[1]);
} else {
fprintf( file, "unset logscale x \n" );
if (xlims) {
fprintf( file, "set xrange [%e:%e]\n", xlims[0], xlims[1] );
}
fprintf(file, "unset logscale x \n");
if (xlims)
fprintf(file, "set xrange [%e:%e]\n", xlims[0], xlims[1]);
}
if (ylog) {
fprintf( file, "set logscale y \n" );
if (ylims) {
fprintf( file, "set yrange [%e:%e]\n", ylims[0], ylims[1] );
}
fprintf(file, "set logscale y \n");
if (ylims)
fprintf(file, "set yrange [%e:%e]\n", ylims[0], ylims[1]);
} else {
fprintf( file, "unset logscale y \n" );
if (ylims) {
fprintf( file, "set yrange [%e:%e]\n", ylims[0], ylims[1] );
}
fprintf(file, "unset logscale y \n");
if (ylims)
fprintf(file, "set yrange [%e:%e]\n", ylims[0], ylims[1]);
}
fprintf( file, "#set xtics 1\n" );
fprintf( file, "#set x2tics 1\n" );
fprintf( file, "#set ytics 1\n" );
fprintf( file, "#set y2tics 1\n" );
fprintf(file, "#set xtics 1\n");
fprintf(file, "#set x2tics 1\n");
fprintf(file, "#set ytics 1\n");
fprintf(file, "#set y2tics 1\n");
if (linewidth > 1)
fprintf( file, "set border lw %d\n", linewidth );
fprintf(file, "set border lw %d\n", linewidth);
if (plottype == PLOT_COMB) {
strcpy(plotstyle, "boxes");
} else if (plottype == PLOT_POINT) {
if (markers) {
// fprintf( file, "Markers: True\n" );
// fprintf(file, "Markers: True\n");
} else {
// fprintf( file, "LargePixels: True\n" );
// fprintf(file, "LargePixels: True\n");
}
strcpy(plotstyle, "points");
} else {
@ -166,11 +161,11 @@ ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlab
return;
}
fprintf( file, "plot " );
fprintf(file, "plot ");
i = 0;
/* Write out the gnuplot command */
for ( v = vecs; v; v = v->v_link2 ) {
for (v = vecs; v; v = v->v_link2) {
scale = v->v_scale;
if (v->v_name) {
i = i + 2;
@ -179,19 +174,19 @@ ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlab
filename_data, i-1, i, plotstyle, linewidth, v->v_name);
}
}
fprintf( file, "\n");
fprintf (file, "set terminal push\n");
fprintf (file, "set terminal postscript eps color\n");
fprintf (file, "set out \'%s.eps\'\n", filename);
fprintf (file, "replot\n");
fprintf (file, "set term pop\n");
fprintf (file, "replot\n");
fprintf(file, "\n");
fprintf(file, "set terminal push\n");
fprintf(file, "set terminal postscript eps color\n");
fprintf(file, "set out \'%s.eps\'\n", filename);
fprintf(file, "replot\n");
fprintf(file, "set term pop\n");
fprintf(file, "replot\n");
(void) fclose( file );
(void) fclose(file);
/* Write out the data and setup arrays */
for ( i = 0; i < scale->v_length; i++ ) {
for ( v = vecs; v; v = v->v_link2 ) {
for (i = 0; i < scale->v_length; i++) {
for (v = vecs; v; v = v->v_link2) {
scale = v->v_scale;
xval = isreal(scale) ?
@ -200,35 +195,34 @@ ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlab
yval = isreal(v) ?
v->v_realdata[i] : realpart(v->v_compdata[i]);
fprintf( file_data, "% e % e ", xval, yval );
fprintf(file_data, "% e % e ", xval, yval);
}
fprintf( file_data, "\n");
fprintf(file_data, "\n");
}
(void) fclose( file_data );
(void) fclose(file_data);
#if defined(__MINGW32__) || defined(_MSC_VER)
/* for external fcn system() */
// (void) sprintf( buf, "start /B wgnuplot %s -" , filename_plt );
(void) sprintf( buf, "start /B wgnuplot -persist %s " , filename_plt );
// (void) sprintf(buf, "start /B wgnuplot %s -" , filename_plt);
(void) sprintf(buf, "start /B wgnuplot -persist %s " , filename_plt);
_flushall();
#else
/* for external fcn system() from LINUX environment */
(void) sprintf( buf, "xterm -e gnuplot %s - &", filename_plt );
(void) sprintf(buf, "xterm -e gnuplot %s - &", filename_plt);
#endif
err = system( buf );
err = system(buf);
return;
}
/* simple printout of data into a file, similar to data table in ft_gnuplot
command: wrsimple file vecs
*/
void
ft_writesimple(double *xlims, double *ylims, char *filename, char *title, char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, struct dvec *vecs)
{
FILE *file_data;
struct dvec *v, *scale = NULL;
double xval;
@ -249,12 +243,11 @@ ft_writesimple(double *xlims, double *ylims, char *filename, char *title, char *
appendwrite = cp_getvar("appendwrite", CP_BOOL, NULL);
/* Sanity checking. */
for ( v = vecs, numVecs = 0; v; v = v->v_link2 ) {
for (v = vecs, numVecs = 0; v; v = v->v_link2)
numVecs++;
}
if (numVecs == 0) {
if (numVecs == 0)
return;
}
/* Open the output data file. */
if ((file_data = fopen(filename_data, appendwrite ? "a" : "w")) == NULL) {
@ -263,27 +256,26 @@ ft_writesimple(double *xlims, double *ylims, char *filename, char *title, char *
}
i = 0;
for ( v = vecs; v; v = v->v_link2 ) {
for (v = vecs; v; v = v->v_link2)
scale = v->v_scale;
}
/* Write out the data as simple arrays */
for ( i = 0; i < scale->v_length; i++ ) {
for ( v = vecs; v; v = v->v_link2 ) {
for (i = 0; i < scale->v_length; i++) {
for (v = vecs; v; v = v->v_link2) {
scale = v->v_scale;
xval = isreal(scale) ?
scale->v_realdata[i] : realpart(scale->v_compdata[i]);
if (isreal(v))
fprintf( file_data, "% e % e ", xval, v->v_realdata[i] );
fprintf(file_data, "% e % e ", xval, v->v_realdata[i]);
else
fprintf( file_data, "% e % e % e ", xval, realpart(v->v_compdata[i]), imagpart(v->v_compdata[i]) );
fprintf(file_data, "% e % e % e ", xval, realpart(v->v_compdata[i]), imagpart(v->v_compdata[i]));
}
fprintf( file_data, "\n");
fprintf(file_data, "\n");
}
(void) fclose( file_data );
(void) fclose(file_data);
return;
}

View File

@ -6,14 +6,13 @@
#ifndef GNUPLOT_H_INCLUDED
#define GNUPLOT_H_INCLUDED
void ft_gnuplot(double *xlims, double *ylims, char *filename, char *title,
char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype,
struct dvec *vecs);
void ft_gnuplot(double *xlims, double *ylims, char *filename, char *title,
char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype,
struct dvec *vecs);
void ft_writesimple(double *xlims, double *ylims, char *filename, char *title,
char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype,
struct dvec *vecs);
void ft_writesimple(double *xlims, double *ylims, char *filename, char *title,
char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype,
struct dvec *vecs);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -9,18 +9,18 @@
#include "ngspice/graph.h"
int gr_init(double *xlims, double *ylims,
char *xname, char *plotname,
char *hcopy,
int nplots,
double xdelta, double ydelta,
GRIDTYPE gridtype,
PLOTTYPE plottype,
char *xlabel, char *ylabel,
int xtype, int ytype,
char *pname, char *commandline);
char *xname, char *plotname,
char *hcopy,
int nplots,
double xdelta, double ydelta,
GRIDTYPE gridtype,
PLOTTYPE plottype,
char *xlabel, char *ylabel,
int xtype, int ytype,
char *pname, char *commandline);
void gr_point(struct dvec *dv,
double newx, double newy,
double oldx, double oldy, int np);
double newx, double newy,
double oldx, double oldy, int np);
void gr_start(struct dvec *dv);
void gr_relinestyle(GRAPH *graph);
void drawlegend(GRAPH *graph, int plotno, struct dvec *dv);
@ -34,6 +34,6 @@ void gr_restoretext(GRAPH *graph);
void reset_trace(void);
void gr_iplot(struct plot *plot);
void gr_end_iplot(void);
double * readtics(char *string);
double *readtics(char *string);
#endif /* GRAF_H */
#endif

View File

@ -3,7 +3,7 @@ Copyright 1990 Regents of the University of California. All rights reserved.
**********/
/*
Manage graph data structure.
Manage graph data structure.
*/
#include "ngspice/ngspice.h"
@ -28,10 +28,11 @@ GRAPH *currentgraph;
/* linked list of graphs */
typedef struct listgraph {
/* we use GRAPH here instead of a pointer to save a tmalloc */
/* we use GRAPH here instead of a pointer to save a tmalloc */
GRAPH graph;
struct listgraph *next;
} LISTGRAPH;
#define NEWLISTGRAPH TMALLOC(LISTGRAPH, 1)
#define NUMGBUCKETS 16
@ -56,57 +57,56 @@ static int RunningId = 1;
/* returns NULL on error */
GRAPH *NewGraph(void)
GRAPH *
NewGraph(void)
{
GRAPH *pgraph;
LISTGRAPH *list;
int BucketId = RunningId % NUMGBUCKETS;
if ((list = NEWLISTGRAPH) == NULL) {
internalerror("can't allocate a listgraph");
return(NULL);
internalerror("can't allocate a listgraph");
return (NULL);
}
pgraph = &list->graph;
SETGRAPH(pgraph, RunningId);
if (!GBucket[BucketId].list) {
GBucket[BucketId].list = list;
GBucket[BucketId].list = list;
} else {
/* insert at front of current list */
list->next = GBucket[BucketId].list;
GBucket[BucketId].list = list;
/* insert at front of current list */
list->next = GBucket[BucketId].list;
GBucket[BucketId].list = list;
}
RunningId++ ;
return(pgraph);
RunningId++;
return (pgraph);
}
/* Given graph id, return graph */
GRAPH *FindGraph(int id)
{
/* Given graph id, return graph */
GRAPH *
FindGraph(int id)
{
LISTGRAPH *list;
for (list = GBucket[id % NUMGBUCKETS].list;
list && list->graph.graphid != id;
list = list->next)
;
list && list->graph.graphid != id;
list = list->next)
;
if (list)
return(&list->graph);
return (&list->graph);
else
return(NULL);
return (NULL);
}
GRAPH *CopyGraph(GRAPH *graph)
{
GRAPH *
CopyGraph(GRAPH *graph)
{
GRAPH *ret;
struct _keyed *k;
struct dveclist *link, *newlink;
@ -117,34 +117,32 @@ GRAPH *CopyGraph(GRAPH *graph)
ret->graphid = RunningId - 1; /* restore id */
/* copy keyed */
for (ret->keyed = NULL, k = graph->keyed; k; k = k->next) {
SaveText(ret, k->text, k->x, k->y);
}
for (ret->keyed = NULL, k = graph->keyed; k; k = k->next)
SaveText(ret, k->text, k->x, k->y);
/* copy dvecs */
ret->plotdata = NULL;
for (link = graph->plotdata; link; link = link->next) {
newlink = TMALLOC(struct dveclist, 1);
newlink->next = ret->plotdata;
newlink->vector = vec_copy(link->vector);
/* vec_copy doesn't set v_color or v_linestyle */
newlink->vector->v_color = link->vector->v_color;
newlink->vector->v_linestyle = link->vector->v_linestyle;
newlink->vector->v_flags |= VF_PERMANENT;
ret->plotdata = newlink;
newlink = TMALLOC(struct dveclist, 1);
newlink->next = ret->plotdata;
newlink->vector = vec_copy(link->vector);
/* vec_copy doesn't set v_color or v_linestyle */
newlink->vector->v_color = link->vector->v_color;
newlink->vector->v_linestyle = link->vector->v_linestyle;
newlink->vector->v_flags |= VF_PERMANENT;
ret->plotdata = newlink;
}
ret->commandline = copy(graph->commandline);
ret->plotname = copy(graph->plotname);
return(ret);
return (ret);
}
int
DestroyGraph(int id)
{
LISTGRAPH *list, *lastlist;
struct _keyed *k, *nextk;
struct dveclist *d, *nextd;
@ -153,129 +151,126 @@ DestroyGraph(int id)
list = GBucket[id % NUMGBUCKETS].list;
lastlist = NULL;
while (list) {
if (list->graph.graphid == id) { /* found it */
if (list->graph.graphid == id) { /* found it */
/* Fix the iplot/trace dbs list */
for (db = dbs; db && db->db_graphid != id; db = db->db_next)
;
/* Fix the iplot/trace dbs list */
for (db = dbs; db && db->db_graphid != id; db = db->db_next)
;
if (db && (db->db_type == DB_IPLOT
|| db->db_type == DB_IPLOTALL)) {
db->db_type = DB_DEADIPLOT;
/* Delete this later */
return(0);
}
if (db && (db->db_type == DB_IPLOT ||
db->db_type == DB_IPLOTALL))
{
db->db_type = DB_DEADIPLOT;
/* Delete this later */
return (0);
}
/* adjust bucket pointers */
if (lastlist) {
lastlist->next = list->next;
} else {
GBucket[id % NUMGBUCKETS].list = list->next;
/* adjust bucket pointers */
if (lastlist)
lastlist->next = list->next;
else
GBucket[id % NUMGBUCKETS].list = list->next;
/* run through and de-allocate dynamically allocated keyed list */
k = list->graph.keyed;
while (k) {
nextk = k->next;
tfree(k->text);
tfree(k);
k = nextk;
}
/* de-allocate dveclist */
d = list->graph.plotdata;
while (d) {
nextd = d->next;
tfree(d->vector->v_name);
if (isreal(d->vector))
tfree(d->vector->v_realdata);
else
tfree(d->vector->v_compdata);
tfree(d->vector);
tfree(d);
d = nextd;
}
tfree(list->graph.commandline);
tfree(list->graph.plotname);
/* If device dependent space allocated, free it. */
if (list->graph.devdep)
tfree(list->graph.devdep);
tfree(list);
return (1);
}
/* run through and de-allocate dynamically allocated keyed list */
k=list->graph.keyed;
while (k) {
nextk = k->next;
tfree(k->text);
tfree(k);
k = nextk;
}
/* de-allocate dveclist */
d = list->graph.plotdata;
while (d) {
nextd = d->next;
tfree(d->vector->v_name);
if (isreal(d->vector)) {
tfree(d->vector->v_realdata);
} else {
tfree(d->vector->v_compdata);
}
tfree(d->vector);
tfree(d);
d = nextd;
}
tfree(list->graph.commandline);
tfree(list->graph.plotname);
/* If device dependent space allocated, free it. */
if (list->graph.devdep)
tfree(list->graph.devdep);
tfree(list);
return(1);
}
lastlist = list;
list = list->next;
lastlist = list;
list = list->next;
}
internalerror("tried to destroy non-existent graph");
return (0);
}
/* free up all dynamically allocated data structures */
void
FreeGraphs(void)
{
GBUCKET *gbucket;
LISTGRAPH *list, *deadl;
for (gbucket = GBucket; gbucket < &GBucket[NUMGBUCKETS]; gbucket++) {
list = gbucket->list;
while (list) {
deadl = list;
list = list->next;
tfree(deadl);
}
list = gbucket->list;
while (list) {
deadl = list;
list = list->next;
tfree(deadl);
}
}
}
void
SetGraphContext(int graphid)
{
currentgraph = FindGraph(graphid);
}
typedef struct gcstack {
GRAPH *pgraph;
struct gcstack *next;
} GCSTACK;
GCSTACK *gcstacktop;
#define NEWGCSTACK TMALLOC(GCSTACK, 1)
/* note: This Push and Pop has tricky semantics.
Push(graph) will push the currentgraph onto the stack
and set currentgraph to graph.
Pop() simply sets currentgraph to the top of the stack and pops stack.
Push(graph) will push the currentgraph onto the stack
and set currentgraph to graph.
Pop() simply sets currentgraph to the top of the stack and pops stack.
*/
void
PushGraphContext(GRAPH *graph)
{
GCSTACK *gcstack = NEWGCSTACK;
if (!gcstacktop) {
gcstacktop = gcstack;
gcstacktop = gcstack;
} else {
gcstack->next = gcstacktop;
gcstacktop = gcstack;
gcstack->next = gcstacktop;
gcstacktop = gcstack;
}
gcstacktop->pgraph = currentgraph;
currentgraph = graph;
}
void
PopGraphContext(void)
{
GCSTACK *dead;
currentgraph = gcstacktop->pgraph;

View File

@ -12,6 +12,4 @@ void SetGraphContext(int graphid);
void PushGraphContext(GRAPH *graph);
void PopGraphContext(void);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ Copyright 1990 Regents of the University of California. All rights reserved.
#include "graf.h"
#include "ngspice/fteext.h"
static FILE *plotfile;
#define putsi(a) \
@ -20,14 +21,16 @@ static FILE *plotfile;
#define SOLID 0
static char *linestyle[] = { "solid", "dotted", "longdashed", "shortdashed",
"dotdashed" };
static char *linestyle[] = {
"solid", "dotted", "longdashed", "shortdashed", "dotdashed" };
static int currentlinestyle = SOLID;
int
int
Plt5_Init(void)
{
dispdev->numlinestyles = 4;
dispdev->numcolors = 2;
@ -35,113 +38,114 @@ Plt5_Init(void)
dispdev->width = 1000;
dispdev->height = 1000;
return(0);
return (0);
}
int
Plt5_NewViewport(GRAPH *graph)
{
if ((plotfile = fopen((char*) graph->devdep, "w")) == NULL) {
graph->devdep = NULL;
perror((char*) graph->devdep);
return(1);
graph->devdep = NULL;
perror((char*) graph->devdep);
return (1);
}
if (graph->absolute.width) {
/* hardcopying from the scree,
ie, we are passed a copy of an existing graph */
putc('s', plotfile);
putsi(0);
putsi(0);
putsi(graph->absolute.width);
putsi(graph->absolute.height);
/* hardcopying from the scree,
ie, we are passed a copy of an existing graph */
putc('s', plotfile);
putsi(0);
putsi(0);
putsi(graph->absolute.width);
putsi(graph->absolute.height);
/* re-scale linestyles */
gr_relinestyle(graph);
/* re-scale linestyles */
gr_relinestyle(graph);
} else {
/* scale space */
putc('s', plotfile);
putsi(0);
putsi(0);
putsi(dispdev->width);
putsi(dispdev->height);
/* scale space */
putc('s', plotfile);
putsi(0);
putsi(0);
putsi(dispdev->width);
putsi(dispdev->height);
/* reasonable values, used in gr_ for placement */
graph->fontwidth = 12;
graph->fontheight = 24;
/* reasonable values, used in gr_ for placement */
graph->fontwidth = 12;
graph->fontheight = 24;
graph->absolute.width = dispdev->width;
graph->absolute.height = dispdev->height;
graph->absolute.width = dispdev->width;
graph->absolute.height = dispdev->height;
}
/* set to NULL so graphdb doesn't incorrectly de-allocate it */
graph->devdep = NULL;
return(0);
return (0);
}
int
Plt5_Close(void)
{
/* in case Plt5_Close is called as part of an abort,
w/o having reached Plt5_NewViewport */
w/o having reached Plt5_NewViewport */
if (plotfile)
fclose(plotfile);
return 0;
}
int
Plt5_Clear(void)
{
/* do nothing */
return 0;
}
int
Plt5_DrawLine(int x1, int y1, int x2, int y2)
{
putc('l', plotfile);
putsi(x1);
putsi(y1);
putsi(x2);
putsi(y2);
return 0;
}
int
Plt5_Arc(int xc, int yc, int radius, double theta, double delta_theta)
{
int x0,y0,x1,y1;
int x0, y0, x1, y1;
if(delta_theta < 0) {
if (delta_theta < 0) {
theta += delta_theta;
delta_theta = -delta_theta;
}
if((2*M_PI - delta_theta)*radius < 0.5) {
if ((2*M_PI - delta_theta)*radius < 0.5) {
putc('c', plotfile);
putsi(xc);
putsi(yc);
putsi(radius);
putc('c', plotfile);
putsi(xc);
putsi(yc);
putsi(radius);
return 0;
return 0;
}
while(delta_theta*radius > 0.5) {
while (delta_theta*radius > 0.5) {
double delta_phi = M_PI/2;
if(delta_phi > delta_theta)
if (delta_phi > delta_theta)
delta_phi = delta_theta;
x0 = xc + (int)(radius * cos(theta));
@ -164,14 +168,14 @@ Plt5_Arc(int xc, int yc, int radius, double theta, double delta_theta)
return 0;
}
int
Plt5_Text(char *text, int x, int y)
{
int savedlstyle;
/* set linestyle to solid
or may get funny color text on some plotters */
or may get funny color text on some plotters */
savedlstyle = currentlinestyle;
Plt5_SetLinestyle(SOLID);
@ -185,23 +189,26 @@ Plt5_Text(char *text, int x, int y)
/* restore old linestyle */
Plt5_SetLinestyle(savedlstyle);
return 0;
}
int
Plt5_SetLinestyle(int linestyleid)
{
if (linestyleid < 0 || linestyleid > dispdev->numlinestyles) {
internalerror("bad linestyleid");
return 0;
internalerror("bad linestyleid");
return 0;
}
putc('f', plotfile);
fprintf(plotfile, "%s\n", linestyle[linestyleid]);
currentlinestyle = linestyleid;
return 0;
}
/* ARGSUSED */
int
Plt5_SetColor(int colorid)
@ -212,11 +219,10 @@ Plt5_SetColor(int colorid)
return 0;
}
int
Plt5_Update(void)
{
fflush(plotfile);
return 0;
}

View File

@ -17,4 +17,4 @@ disp_fn_SetLinestyle_t Plt5_SetLinestyle;
disp_fn_SetColor_t Plt5_SetColor;
disp_fn_Update_t Plt5_Update;
#endif /* PLOT5_H_INCLUDED */
#endif

View File

@ -1,6 +1,6 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
@ -18,8 +18,8 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "plotcurv.h"
static void plotinterval(struct dvec *v, double lo, double hi, register double *coeffs,
int degree, bool rotated);
static void plotinterval(struct dvec *v, double lo, double hi, register double *coeffs,
int degree, bool rotated);
/* Plot the vector v, with scale xs. If we are doing curve-fitting, then
@ -35,18 +35,20 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
register double *xdata, *ydata;
bool rot, increasing = FALSE;
double dx = 0.0, dy = 0.0, lx = 0.0, ly = 0.0;
int dir;
int dir;
/* if already started, use saved degree */
if (nostart) {
degree = currentgraph->degree;
degree = currentgraph->degree;
} else {
if (!cp_getvar("polydegree", CP_NUM, &degree))
degree = 1;
currentgraph->degree = degree;
}
if (degree > v->v_length)
degree = v->v_length;
if (degree < 1) {
fprintf(cp_err, "Error: polydegree is %d, can't plot...\n",
degree);
@ -55,33 +57,32 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
if (!cp_getvar("gridsize", CP_NUM, &gridsize))
gridsize = 0;
if ((gridsize < 0) || (gridsize > 10000)) {
fprintf(cp_err, "Error: bad grid size %d\n", gridsize);
return;
}
if (gridsize && xs) {
if( isreal(xs) ) {
increasing = (xs->v_realdata[0] < xs->v_realdata[1]);
for (i = 0; i < xs->v_length - 1; i++)
if (increasing != (xs->v_realdata[i] <
xs->v_realdata[i + 1])) {
fprintf(cp_err,
"Warning: scale not monotonic, gridsize not relevant.\n");
gridsize = 0;
break;
}
} else {
increasing = (realpart (xs->v_compdata[0]) <
realpart(xs->v_compdata[1]));
for (i = 0; i < xs->v_length - 1; i++)
if (increasing != (realpart(xs->v_compdata[i]) <
realpart(xs->v_compdata[i + 1]))) {
fprintf(cp_err,
"Warning: scale not monotonic, gridsize not relevant.\n");
gridsize = 0;
break;
}
}
if (isreal(xs)) {
increasing = (xs->v_realdata[0] < xs->v_realdata[1]);
for (i = 0; i < xs->v_length - 1; i++)
if (increasing != (xs->v_realdata[i] < xs->v_realdata[i + 1])) {
fprintf(cp_err,
"Warning: scale not monotonic, gridsize not relevant.\n");
gridsize = 0;
break;
}
} else {
increasing = (realpart(xs->v_compdata[0]) < realpart(xs->v_compdata[1]));
for (i = 0; i < xs->v_length - 1; i++)
if (increasing != (realpart(xs->v_compdata[i]) < realpart(xs->v_compdata[i + 1]))) {
fprintf(cp_err,
"Warning: scale not monotonic, gridsize not relevant.\n");
gridsize = 0;
break;
}
}
}
if (!nostart)
@ -92,58 +93,58 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
if (!xs) {
for (i = 0; i < v->v_length; i++) {
/* We should do the one - point case too!
* Important for pole-zero for example
*/
if( v->v_length == 1 ) {
j = 0;
} else {
j = i-1;
if( i == 0 )
continue;
}
/* We should do the one - point case too!
* Important for pole-zero for example
*/
if (v->v_length == 1) {
j = 0;
} else {
j = i-1;
if (i == 0)
continue;
}
if (isreal(v)) {
/* This isn't good but we may as well do
* something useful.
*/
gr_point(v, v->v_realdata[i],
0.0, /* v->v_realdata[i], */
v->v_realdata[j],
0.0, /* v->v_realdata[j], */
(j==i ? 1 : i));
0.0, /* v->v_realdata[i], */
v->v_realdata[j],
0.0, /* v->v_realdata[j], */
(j == i ? 1 : i));
} else {
gr_point(v, realpart(v->v_compdata[i]),
imagpart(v->v_compdata[i]),
realpart(v->v_compdata[j]),
imagpart(v->v_compdata[j]), (j==i ? 1 : i));
imagpart(v->v_compdata[i]),
realpart(v->v_compdata[j]),
imagpart(v->v_compdata[j]), (j == i ? 1 : i));
}
}
}
gr_end(v);
return;
}
xs->v_flags |= VF_PERMANENT;
/* First check the simple case, where we don't have to do any
/* First check the simple case, where we don't have to do any
* interpolation.
*/
if ((degree == 1) && (gridsize == 0)) {
dir = 0;
dir = 0;
for (i = 0, j = v->v_length; i < j; i++) {
dx = isreal(xs) ? xs->v_realdata[i] :
realpart(xs->v_compdata[i]);
dy = isreal(v) ? v->v_realdata[i] :
realpart(v->v_compdata[i]);
if ((i == 0 || (dir > 0 ? lx > dx : dir < 0 ? lx < dx : 0))
&& xs->v_plot && xs->v_plot->pl_scale == xs)
{
gr_point(v, dx, dy, lx, ly, 0);
} else {
gr_point(v, dx, dy, lx, ly, i);
if (!dir)
dir = lx > dx ? -1 : lx < dx ? 1 : 0;
}
dx = isreal(xs) ? xs->v_realdata[i] :
realpart(xs->v_compdata[i]);
dy = isreal(v) ? v->v_realdata[i] :
realpart(v->v_compdata[i]);
if ((i == 0 || (dir > 0 ? lx > dx : dir < 0 ? lx < dx : 0)) &&
xs->v_plot && xs->v_plot->pl_scale == xs)
{
gr_point(v, dx, dy, lx, ly, 0);
} else {
gr_point(v, dx, dy, lx, ly, i);
if (!dir)
dir = lx > dx ? -1 : lx < dx ? 1 : 0;
}
lx = dx;
ly = dy;
}
@ -160,21 +161,22 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
/* This is done quite differently from what we do below... */
gridbuf = TMALLOC(double, gridsize);
result = TMALLOC(double, gridsize);
if (isreal(v))
if (isreal(v)) {
ydata = v->v_realdata;
else {
} else {
ydata = TMALLOC(double, v->v_length);
for (i = 0; i < v->v_length; i++)
ydata[i] = realpart(v->v_compdata[i]);
}
if (isreal(xs))
if (isreal(xs)) {
xdata = xs->v_realdata;
else {
} else {
xdata = TMALLOC(double, xs->v_length);
for (i = 0; i < xs->v_length; i++)
xdata[i] = realpart(xs->v_compdata[i]);
}
mm = ft_minmax(xs, TRUE);
dx = (mm[1] - mm[0]) / gridsize;
if (increasing)
@ -184,7 +186,7 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
for (i = 0, dy = mm[1]; i < gridsize; i++, dy -= dx)
gridbuf[i] = dy;
if (!ft_interpolate(ydata, result, xdata, v->v_length, gridbuf,
gridsize, degree)) {
gridsize, degree)) {
fprintf(cp_err, "Error: can't put %s on gridsize %d\n",
v->v_name, gridsize);
return;
@ -194,8 +196,8 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
* the actual data...
*/
for (i = 0; i < gridsize; i++)
gr_point(v, gridbuf[i], result[i], gridbuf[i ? (i - 1)
: i], result[i ? (i - 1) : i], -1);
gr_point(v, gridbuf[i], result[i],
gridbuf[i ? (i - 1) : i], result[i ? (i - 1) : i], -1);
gr_end(v);
tfree(gridbuf);
tfree(result);
@ -206,7 +208,7 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
return;
}
/* We need to do curve fitting now. First get some scratch
/* We need to do curve fitting now. First get some scratch
* space
*/
scratch = TMALLOC(double, (degree + 1) * (degree + 2));
@ -221,6 +223,7 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
else
for (i = 0; i <= degree; i++)
ydata[i] = realpart(v->v_compdata[i]);
if (isreal(xs))
bcopy(xs->v_realdata, xdata, (size_t)(degree + 1) * sizeof(double));
else
@ -246,13 +249,11 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
/* Plot this part of the curve... */
for (i = 0; i < degree; i++)
if (rot)
plotinterval(v, ydata[i], ydata[i + 1], result, degree,
TRUE);
plotinterval(v, ydata[i], ydata[i + 1], result, degree, TRUE);
else
plotinterval(v, xdata[i], xdata[i + 1], result, degree,
FALSE);
plotinterval(v, xdata[i], xdata[i + 1], result, degree, FALSE);
/* Now plot the rest, piece by piece... l is the
/* Now plot the rest, piece by piece... l is the
* last element under consideration.
*/
length = v->v_length;
@ -263,10 +264,12 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
xdata[i] = xdata[i + 1];
ydata[i] = ydata[i + 1];
}
if (isreal(v))
ydata[i] = v->v_realdata[l];
else
ydata[i] = realpart(v->v_compdata[l]);
if (isreal(xs))
xdata[i] = xs->v_realdata[l];
else
@ -279,26 +282,30 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
break;
}
if (--degree == 0) {
fprintf(cp_err,
"plotcurve: Internal Error: ack...\n");
fprintf(cp_err,
"plotcurve: Internal Error: ack...\n");
return;
}
}
if (rot)
plotinterval(v, ydata[degree - 1], ydata[degree],
result, degree, TRUE);
plotinterval(v, ydata[degree - 1], ydata[degree],
result, degree, TRUE);
else
plotinterval(v, xdata[degree - 1], xdata[degree],
result, degree, FALSE);
result, degree, FALSE);
}
tfree(scratch);
tfree(xdata);
tfree(ydata);
tfree(result);
gr_end(v);
return;
}
#define GRANULARITY 10
static void
@ -309,10 +316,10 @@ plotinterval(struct dvec *v, double lo, double hi, register double *coeffs, int
int steps;
/*
fprintf(cp_err, "plotinterval(%s, %G, %G, [ ", v->v_name, lo, hi);
for (i = 0; i <= degree; i++)
fprintf(cp_err, "%G ", coeffs[i]);
fprintf(cp_err, "], %d, %s)\n\r", degree, rotated ? "TRUE" : "FALSE");
fprintf(cp_err, "plotinterval(%s, %G, %G, [ ", v->v_name, lo, hi);
for (i = 0; i <= degree; i++)
fprintf(cp_err, "%G ", coeffs[i]);
fprintf(cp_err, "], %d, %s)\n\r", degree, rotated ? "TRUE" : "FALSE");
*/
/* This is a problem -- how do we know what granularity to use? If
@ -335,5 +342,6 @@ plotinterval(struct dvec *v, double lo, double hi, register double *coeffs, int
ly = dy;
/* fprintf(cp_err, "plot (%G, %G)\n\r", dx, dy); */
}
return;
}

View File

@ -34,12 +34,12 @@ getlims(wordlist *wl, char *name, int number)
wordlist *beg, *wk;
int n;
if(number < 1)
if (number < 1)
return NULL;
beg = wl_find(name, wl->wl_next);
if(!beg)
if (!beg)
return NULL;
wk = beg->wl_next;
@ -277,15 +277,15 @@ plotit(wordlist *wl, char *hcopy, char *devname)
/* add title, xlabel or ylabel, if available, with quotes '' */
if (nxlabel) {
sprintf(cline, "%s xlabel '%s'", cline, nxlabel);
tfree (nxlabel);
tfree(nxlabel);
}
if (nylabel) {
sprintf(cline, "%s ylabel '%s'", cline, nylabel);
tfree (nylabel);
tfree(nylabel);
}
if (ntitle) {
sprintf(cline, "%s title '%s'", cline, ntitle);
tfree (ntitle);
tfree(ntitle);
}
/* Now extract all the parameters. */
@ -350,73 +350,73 @@ plotit(wordlist *wl, char *hcopy, char *devname)
* here because we want to catch all the grid types.
*/
if (getflag(wl, "lingrid")) {
if (gfound)
if (gfound) {
fprintf(cp_err, "Warning: too many grid types given\n");
else {
} else {
gtype = GRID_LIN;
gfound = TRUE;
}
}
if (getflag(wl, "loglog")) {
if (gfound)
if (gfound) {
fprintf(cp_err, "Warning: too many grid types given\n");
else {
} else {
gtype = GRID_LOGLOG;
gfound = TRUE;
}
}
if (getflag(wl, "nogrid")) {
if (gfound)
if (gfound) {
fprintf(cp_err, "Warning: too many grid types given\n");
else {
} else {
gtype = GRID_NONE;
gfound = TRUE;
}
}
if (getflag(wl, "linear")) {
if (gfound)
if (gfound) {
fprintf(cp_err, "Warning: too many grid types given\n");
else {
} else {
gtype = GRID_LIN;
gfound = TRUE;
}
}
if (getflag(wl, "xlog")) {
if (gfound)
if (gfound) {
fprintf(cp_err, "Warning: too many grid types given\n");
else {
} else {
gtype = GRID_XLOG;
gfound = TRUE;
}
}
if (getflag(wl, "ylog")) {
if (gfound)
if (gfound) {
fprintf(cp_err, "Warning: too many grid types given\n");
else {
} else {
gtype = GRID_YLOG;
gfound = TRUE;
}
}
if (getflag(wl, "polar")) {
if (gfound)
if (gfound) {
fprintf(cp_err, "Warning: too many grid types given\n");
else {
} else {
gtype = GRID_POLAR;
gfound = TRUE;
}
}
if (getflag(wl, "smith")) {
if (gfound)
if (gfound) {
fprintf(cp_err, "Warning: too many grid types given\n");
else {
} else {
gtype = GRID_SMITH;
gfound = TRUE;
}
}
if (getflag(wl, "smithgrid")) {
if (gfound)
if (gfound) {
fprintf(cp_err, "Warning: too many grid types given\n");
else {
} else {
gtype = GRID_SMITHGRID;
gfound = TRUE;
}
@ -445,32 +445,33 @@ plotit(wordlist *wl, char *hcopy, char *devname)
gtype = GRID_LIN;
}
gfound = TRUE;
} else
} else {
gtype = GRID_LIN;
}
}
/* Now get the point type. */
if (getflag(wl, "linplot")) {
if (pfound)
if (pfound) {
fprintf(cp_err, "Warning: too many plot types given\n");
else {
} else {
ptype = PLOT_LIN;
pfound = TRUE;
}
}
if (getflag(wl, "combplot")) {
if (pfound)
if (pfound) {
fprintf(cp_err, "Warning: too many plot types given\n");
else {
} else {
ptype = PLOT_COMB;
pfound = TRUE;
}
}
if (getflag(wl, "pointplot")) {
if (pfound)
if (pfound) {
fprintf(cp_err, "Warning: too many plot types given\n");
else {
} else {
ptype = PLOT_POINT;
pfound = TRUE;
}
@ -489,8 +490,9 @@ plotit(wordlist *wl, char *hcopy, char *devname)
ptype = PLOT_LIN;
}
pfound = TRUE;
} else
} else {
ptype = PLOT_LIN;
}
}
if (!sameflag || !xlabel)
@ -634,8 +636,9 @@ plotit(wordlist *wl, char *hcopy, char *devname)
gtype = GRID_YLOG;
}
for (d = vecs; d; d = d->v_link2)
if (d->v_gridtype == GRID_SMITH || d->v_gridtype == GRID_SMITHGRID
|| d->v_gridtype == GRID_POLAR)
if (d->v_gridtype == GRID_SMITH ||
d->v_gridtype == GRID_SMITHGRID ||
d->v_gridtype == GRID_POLAR)
{
gtype = d->v_gridtype;
break;
@ -667,11 +670,8 @@ plotit(wordlist *wl, char *hcopy, char *devname)
goto quit;
}
if ((gtype == GRID_POLAR) || (gtype == GRID_SMITH
|| gtype == GRID_SMITHGRID))
{
if ((gtype == GRID_POLAR) || (gtype == GRID_SMITH || gtype == GRID_SMITHGRID))
oneval = TRUE;
}
/* If we are plotting scalars, make sure there is enough
* data to fit on the screen.
@ -881,8 +881,7 @@ plotit(wordlist *wl, char *hcopy, char *devname)
xlims[1] = rad;
ylims[0] = - rad;
ylims[1] = rad;
} else if ((!xlim || !ylim) && (gtype == GRID_SMITH
|| gtype == GRID_SMITHGRID))
} else if ((!xlim || !ylim) && (gtype == GRID_SMITH || gtype == GRID_SMITHGRID))
{
xlims[0] = -1.0;
xlims[1] = 1.0;
@ -890,9 +889,9 @@ plotit(wordlist *wl, char *hcopy, char *devname)
ylims[1] = 1.0;
}
if(xlim)
if (xlim)
tfree(xlim);
if(ylim)
if (ylim)
tfree(ylim);
/* We don't want to try to deal with smith plots for asciiplot. */
@ -925,7 +924,7 @@ plotit(wordlist *wl, char *hcopy, char *devname)
for (i = 0, ttime = tstart; i < newlen; i++, ttime += tstep)
newscale[i] = ttime;
for (v = vecs; v; v= v->v_link2) {
for (v = vecs; v; v = v->v_link2) {
double *newdata = TMALLOC(double, newlen);
if (!ft_interpolate(v->v_realdata, newdata,

View File

@ -7,10 +7,11 @@
struct plot constantplot = {
"Constant values", Spice_Build_Date, "constants",
"const", NULL, NULL, NULL, NULL, NULL, NULL, TRUE, 0
} ;
};
struct plot *plot_cur = &constantplot;
struct plot *plot_list = &constantplot;
int plotl_changed; /* TRUE after a load */
int plot_num = 1;

View File

@ -6,24 +6,28 @@
#include "pvec.h"
#include "dimens.h"
void
pvec(struct dvec *d)
{
char buf[BSIZE_SP], buf2[BSIZE_SP], buf3[BSIZE_SP];
sprintf(buf, " %-20s: %s, %s, %d long",
d->v_name,
ft_typenames(d->v_type),
isreal(d) ? "real" : "complex",
d->v_length);
d->v_name,
ft_typenames(d->v_type),
isreal(d) ? "real" : "complex",
d->v_length);
if (d->v_flags & VF_MINGIVEN) {
sprintf(buf2, ", min = %g", d->v_minsignal);
strcat(buf, buf2);
}
if (d->v_flags & VF_MAXGIVEN) {
sprintf(buf2, ", max = %g", d->v_maxsignal);
strcat(buf, buf2);
}
switch (d->v_gridtype) {
case GRID_LOGLOG:
strcat(buf, ", grid = loglog");
@ -48,7 +52,7 @@ pvec(struct dvec *d)
case GRID_SMITHGRID:
strcat(buf, ", grid = smithgrid (not xformed)");
break;
default: /* va: GRID_NONE or GRID_LIN */
break;
}
@ -66,25 +70,28 @@ pvec(struct dvec *d)
default: /* va: PLOT_LIN, */
break;
}
if (d->v_defcolor) {
sprintf(buf2, ", color = %s", d->v_defcolor);
strcat(buf, buf2);
}
if (d->v_scale) {
sprintf(buf2, ", scale = %s", d->v_scale->v_name);
strcat(buf, buf2);
}
if (d->v_numdims > 1) {
dimstring(d->v_dims, d->v_numdims, buf3);
sprintf(buf2, ", dims = [%s]", buf3);
dimstring(d->v_dims, d->v_numdims, buf3);
sprintf(buf2, ", dims = [%s]", buf3);
strcat(buf, buf2);
}
if (d->v_plot->pl_scale == d) {
if (d->v_plot->pl_scale == d)
strcat(buf, " [default scale]\n");
} else {
else
strcat(buf, "\n");
}
out_send(buf);
return;
}

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,6 @@ disp_fn_Clear_t X11_Clear;
int X11_Input(REQUEST *request, RESPONSE *response);
#endif /* X_DISPLAY_MISSING */
#endif
#endif /* X11_H_INCLUDED */
#endif

View File

@ -20,7 +20,6 @@ Author: 1992 David A. Gates, U. C. Berkeley CAD Group
void
ft_xgraph(double *xlims, double *ylims, char *filename, char *title, char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, struct dvec *vecs)
{
FILE *file;
struct dvec *v, *scale;
double xval, yval;
@ -29,138 +28,142 @@ ft_xgraph(double *xlims, double *ylims, char *filename, char *title, char *xlabe
char buf[BSIZE_SP], pointstyle[BSIZE_SP], *text;
/* Sanity checking. */
for ( v = vecs, numVecs = 0; v; v = v->v_link2 ) {
numVecs++;
}
for (v = vecs, numVecs = 0; v; v = v->v_link2)
numVecs++;
if (numVecs == 0) {
return;
return;
} else if (numVecs > XG_MAXVECTORS) {
fprintf( cp_err, "Error: too many vectors for Xgraph.\n" );
return;
fprintf(cp_err, "Error: too many vectors for Xgraph.\n");
return;
}
if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth))
linewidth = 1;
if (linewidth < 1) linewidth = 1;
if (linewidth < 1)
linewidth = 1;
if (!cp_getvar("pointstyle", CP_STRING, pointstyle)) {
markers = FALSE;
} else {
if (cieq(pointstyle,"markers")) {
markers = TRUE;
} else {
markers = FALSE;
}
if (cieq(pointstyle, "markers"))
markers = TRUE;
else
markers = FALSE;
}
/* Make sure the gridtype is supported. */
switch (gridtype) {
case GRID_LIN:
nogrid = xlog = ylog = FALSE;
break;
nogrid = xlog = ylog = FALSE;
break;
case GRID_XLOG:
xlog = TRUE;
nogrid = ylog = FALSE;
break;
xlog = TRUE;
nogrid = ylog = FALSE;
break;
case GRID_YLOG:
ylog = TRUE;
nogrid = xlog = FALSE;
break;
ylog = TRUE;
nogrid = xlog = FALSE;
break;
case GRID_LOGLOG:
xlog = ylog = TRUE;
nogrid = FALSE;
break;
xlog = ylog = TRUE;
nogrid = FALSE;
break;
case GRID_NONE:
nogrid = TRUE;
xlog = ylog = FALSE;
break;
nogrid = TRUE;
xlog = ylog = FALSE;
break;
default:
fprintf( cp_err, "Error: grid type unsupported by Xgraph.\n" );
return;
fprintf(cp_err, "Error: grid type unsupported by Xgraph.\n");
return;
}
/* Open the output file. */
if ((file = fopen(filename, "w")) == NULL) {
perror(filename);
return;
perror(filename);
return;
}
/* Set up the file header. */
if (title) {
text = cp_unquote(title);
fprintf( file, "TitleText: %s\n", text );
tfree(text);
text = cp_unquote(title);
fprintf(file, "TitleText: %s\n", text);
tfree(text);
}
if (xlabel) {
text = cp_unquote(xlabel);
fprintf( file, "XUnitText: %s\n", text );
tfree(text);
text = cp_unquote(xlabel);
fprintf(file, "XUnitText: %s\n", text);
tfree(text);
}
if (ylabel) {
text = cp_unquote(ylabel);
fprintf( file, "YUnitText: %s\n", text );
tfree(text);
text = cp_unquote(ylabel);
fprintf(file, "YUnitText: %s\n", text);
tfree(text);
}
if (nogrid) {
fprintf( file, "Ticks: True\n" );
fprintf(file, "Ticks: True\n");
}
if (xlog) {
fprintf( file, "LogX: True\n" );
if (xlims) {
fprintf( file, "XLowLimit: % e\n", log10(xlims[0]) );
fprintf( file, "XHighLimit: % e\n", log10(xlims[1]) );
}
fprintf(file, "LogX: True\n");
if (xlims) {
fprintf(file, "XLowLimit: % e\n", log10(xlims[0]));
fprintf(file, "XHighLimit: % e\n", log10(xlims[1]));
}
} else {
if (xlims) {
fprintf( file, "XLowLimit: % e\n", xlims[0] );
fprintf( file, "XHighLimit: % e\n", xlims[1] );
}
if (xlims) {
fprintf(file, "XLowLimit: % e\n", xlims[0]);
fprintf(file, "XHighLimit: % e\n", xlims[1]);
}
}
if (ylog) {
fprintf( file, "LogY: True\n" );
if (ylims) {
fprintf( file, "YLowLimit: % e\n", log10(ylims[0]) );
fprintf( file, "YHighLimit: % e\n", log10(ylims[1]) );
}
fprintf(file, "LogY: True\n");
if (ylims) {
fprintf(file, "YLowLimit: % e\n", log10(ylims[0]));
fprintf(file, "YHighLimit: % e\n", log10(ylims[1]));
}
} else {
if (ylims) {
fprintf( file, "YLowLimit: % e\n", ylims[0] );
fprintf( file, "YHighLimit: % e\n", ylims[1] );
}
if (ylims) {
fprintf(file, "YLowLimit: % e\n", ylims[0]);
fprintf(file, "YHighLimit: % e\n", ylims[1]);
}
}
fprintf( file, "LineWidth: %d\n", linewidth );
fprintf( file, "BoundBox: True\n" );
fprintf(file, "LineWidth: %d\n", linewidth);
fprintf(file, "BoundBox: True\n");
if (plottype == PLOT_COMB) {
fprintf( file, "BarGraph: True\n" );
fprintf( file, "NoLines: True\n" );
fprintf(file, "BarGraph: True\n");
fprintf(file, "NoLines: True\n");
} else if (plottype == PLOT_POINT) {
if (markers) {
fprintf( file, "Markers: True\n" );
} else {
fprintf( file, "LargePixels: True\n" );
}
fprintf( file, "NoLines: True\n" );
if (markers)
fprintf(file, "Markers: True\n");
else
fprintf(file, "LargePixels: True\n");
fprintf(file, "NoLines: True\n");
}
/* Write out the data. */
for ( v = vecs; v; v = v->v_link2 ) {
scale = v->v_scale;
if (v->v_name) {
fprintf( file, "\"%s\"\n", v->v_name );
}
for ( i = 0; i < scale->v_length; i++ ) {
xval = isreal(scale) ?
scale->v_realdata[i] : realpart(scale->v_compdata[i]);
yval = isreal(v) ?
v->v_realdata[i] : realpart(v->v_compdata[i]);
fprintf( file, "% e % e\n", xval, yval );
}
fprintf( file, "\n" );
}
(void) fclose( file );
(void) sprintf( buf, "xgraph %s &", filename );
(void) system( buf );
for (v = vecs; v; v = v->v_link2) {
scale = v->v_scale;
if (v->v_name)
fprintf(file, "\"%s\"\n", v->v_name);
for (i = 0; i < scale->v_length; i++) {
xval = isreal(scale) ?
scale->v_realdata[i] : realpart(scale->v_compdata[i]);
yval = isreal(v) ?
v->v_realdata[i] : realpart(v->v_compdata[i]);
fprintf(file, "% e % e\n", xval, yval);
}
fprintf(file, "\n");
}
(void) fclose(file);
(void) sprintf(buf, "xgraph %s &", filename);
(void) system(buf);
return;
}

View File

@ -6,11 +6,8 @@
#ifndef XGRAPH_H_INCLUDED
#define XGRAPH_H_INCLUDED
void ft_xgraph(double *xlims, double *ylims, char *filename, char *title,
char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype,
struct dvec *vecs);
void ft_xgraph(double *xlims, double *ylims, char *filename, char *title,
char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype,
struct dvec *vecs);
#endif

View File

@ -1,6 +1,6 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
#include "ngspice/ngspice.h"
@ -18,7 +18,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
* the imag parts. */
double *
ft_minmax(struct dvec *v, bool real)
{
@ -44,6 +43,7 @@ ft_minmax(struct dvec *v, bool real)
return (res);
}
/* Figure out where a point should go, given the limits of the plotting
* area and the type of scale (log or linear).
*/
@ -61,13 +61,14 @@ ft_findpoint(double pt, double *lims, int maxp, int minp, bool islog)
tl = mylog10(lims[0]);
th = mylog10(lims[1]);
return (int)(((mylog10(pt) - tl) / (th - tl)) *
(maxp - minp) + minp);
(maxp - minp) + minp);
} else {
return (int)(((pt - lims[0]) / (lims[1] - lims[0])) *
(maxp - minp) + minp);
(maxp - minp) + minp);
}
}
/* Will report the minimum and maximum in "reflection coefficient" space
*/
@ -83,14 +84,14 @@ ft_SMITHminmax(struct dvec *v, bool yval)
for (i = 0; i < v->v_length; i++) {
if (isreal(v))
SMITH_tfm( v->v_realdata[i], 0.0, &d, &d2 );
else
SMITH_tfm( realpart(v->v_compdata[i]), imagpart(v->v_compdata[i]),
&d, &d2 );
SMITH_tfm(v->v_realdata[i], 0.0, &d, &d2);
else
SMITH_tfm(realpart(v->v_compdata[i]), imagpart(v->v_compdata[i]),
&d, &d2);
/* Are we are looking for min/max X or Y ralue
*/
if( yval )
d = d2;
if (yval)
d = d2;
if (d < res[0])
res[0] = d;
@ -100,14 +101,15 @@ ft_SMITHminmax(struct dvec *v, bool yval)
return (res);
}
int
SMITH_tfm(double re, double im, double *x, double *y)
{
double dnom;
double dnom;
dnom = (re + 1) * (re + 1) + im * im;
*x = (re * re + im * im - 1) / dnom;
*y = 2 * im / dnom;
dnom = (re + 1) * (re + 1) + im * im;
*x = (re * re + im * im - 1) / dnom;
*y = 2 * im / dnom;
return 0;
return 0;
}

View File

@ -1,6 +1,6 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
@ -23,10 +23,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "variable.h"
#include "parser/complete.h" /* va: throwaway */
/* static declarations */
static void killplot(struct plot *pl);
static void DelPlotWindows(struct plot *pl);
void
com_unlet(wordlist *wl)
{
@ -37,18 +38,19 @@ com_unlet(wordlist *wl)
return;
}
/* Load in a file. */
void
com_load(wordlist *wl)
{
char *copypath;
char *copypath;
if (!wl)
ft_loadfile(ft_rawfile);
else
while (wl) {
/*ft_loadfile(cp_unquote(wl->wl_word)); DG: bad memory leak*/
copypath=cp_unquote(wl->wl_word);/*DG*/
copypath = cp_unquote(wl->wl_word);/*DG*/
ft_loadfile(copypath);
tfree(copypath);
wl = wl->wl_next;
@ -60,6 +62,7 @@ char *copypath;
return;
}
/* Print out the value of an expression. When we are figuring out what to
* print, link the vectors we want with v_link2... This has to be done
* because of the way temporary vectors are linked together with permanent
@ -75,7 +78,7 @@ com_print(wordlist *wl)
struct plot *p;
bool col = TRUE, nobreak = FALSE, noprintscale, plotnames = FALSE;
bool optgiven = FALSE;
char *s, *buf, *buf2; /*, buf[BSIZE_SP], buf2[BSIZE_SP];*/
char *s, *buf, *buf2; /*, buf[BSIZE_SP], buf2[BSIZE_SP];*/
char numbuf[BSIZE_SP], numbuf2[BSIZE_SP]; /* Printnum buffers */
int ngood;
@ -83,8 +86,8 @@ com_print(wordlist *wl)
return;
buf = TMALLOC(char, BSIZE_SP);
buf2 = TMALLOC(char, BSIZE_SP);
buf2 = TMALLOC(char, BSIZE_SP);
if (eq(wl->wl_word, "col")) {
col = TRUE;
optgiven = TRUE;
@ -117,7 +120,7 @@ com_print(wordlist *wl)
plotnames = TRUE;
break;
}
if (!optgiven) {
/* Figure out whether col or line should be used... */
col = FALSE;
@ -125,29 +128,28 @@ com_print(wordlist *wl)
if (v->v_length > 1) {
col = TRUE;
/* Improvement made to print cases @[sin] = (0 12 13 100K) */
if ( (v->v_plot->pl_scale && v->v_length != v->v_plot->pl_scale->v_length) && ( (*(v->v_name))=='@') )
if ((v->v_plot->pl_scale && v->v_length != v->v_plot->pl_scale->v_length) && (*(v->v_name) == '@'))
{
col = FALSE;
}
break;
}
/* With this I have found that the vector has less elements than the SCALE vector
* in the linked PLOT. But now I must make sure in case of a print @vin[sin] or
* @vin[pulse]
* for it appear that the v->v_name begins with '@'
* And then be in this case.
*/
/* With this I have found that the vector has less elements than the SCALE vector
* in the linked PLOT. But now I must make sure in case of a print @vin[sin] or
* @vin[pulse]
* for it appear that the v->v_name begins with '@'
* And then be in this case.
*/
}
out_init();
if (!col) {
for (v = vecs; v; v = v->v_link2) {
if (plotnames) {
(void) sprintf(buf, "%s.%s", v->v_plot->pl_typename,
vec_basename(v));
} else {
if (plotnames)
(void) sprintf(buf, "%s.%s", v->v_plot->pl_typename, vec_basename(v));
else
(void) strcpy(buf, vec_basename(v));
}
for (s = buf; *s; s++)
;
s--;
@ -157,31 +159,26 @@ com_print(wordlist *wl)
}
ll = 10;
/* v->v_rlength = 1 when it comes to make a print @ M1 and does not want to come out on screen
* Multiplier factor [m]=1
* @M1 = 0,00e+00
* In any other case rlength not used for anything and only applies in the copy of the vectors.
*/
if (v->v_rlength == 0)
{
if (v->v_length == 1)
{
if (isreal(v))
{
/* v->v_rlength = 1 when it comes to make a print @ M1 and does not want to come out on screen
* Multiplier factor [m]=1
* @M1 = 0,00e+00
* In any other case rlength not used for anything and only applies in the copy of the vectors.
*/
if (v->v_rlength == 0) {
if (v->v_length == 1) {
if (isreal(v)) {
printnum(numbuf, *v->v_realdata);
out_printf("%s = %s\n", buf, numbuf);
} else {
printnum(numbuf, realpart(v->v_compdata[0]));
printnum(numbuf, realpart(v->v_compdata[0]));
printnum(numbuf2, imagpart(v->v_compdata[0]));
out_printf("%s = %s,%s\n", buf,
numbuf,
numbuf2);
out_printf("%s = %s,%s\n", buf, numbuf, numbuf2);
}
} else {
out_printf("%s = ( ", buf);
for (i = 0; i < v->v_length; i++)
if (isreal(v)) {
printnum(numbuf, v->v_realdata[i]);
(void) strcpy(buf, numbuf);
out_send(buf);
@ -191,15 +188,14 @@ com_print(wordlist *wl)
if (ll > 60) {
out_send("\n\t");
ll = 9;
} else
} else {
out_send("\t");
}
} else {
/*DG*/
printnum(numbuf, realpart(v->v_compdata[i]));
/*DG*/
printnum(numbuf, realpart(v->v_compdata[i]));
printnum(numbuf2, imagpart(v->v_compdata[i]));
(void) sprintf(buf, "%s,%s",
numbuf,
numbuf2);
(void) sprintf(buf, "%s,%s", numbuf, numbuf2);
out_send(buf);
ll += (int) strlen(buf);
ll = (ll + 7) / 8;
@ -207,10 +203,11 @@ com_print(wordlist *wl)
if (ll > 60) {
out_send("\n\t");
ll = 9;
} else
} else {
out_send("\t");
}
}
out_send(")\n");
out_send(")\n");
} //end if (v->v_length == 1)
} //end if (v->v_rlength == 1)
}
@ -219,10 +216,10 @@ com_print(wordlist *wl)
width = i;
if (width < 40)
width = 40;
if (width > BSIZE_SP - 2) {
if (width > BSIZE_SP - 2) {
buf = TREALLOC(char, buf, width + 1);
buf2 = TREALLOC(char, buf2, width + 1);
}
buf2 = TREALLOC(char, buf2, width + 1);
}
if (cp_getvar("height", CP_NUM, &i))
height = i;
if (height < 20)
@ -234,17 +231,17 @@ com_print(wordlist *wl)
nobreak = TRUE;
noprintscale = cp_getvar("noprintscale", CP_BOOL, NULL);
bv = vecs;
nextpage:
nextpage:
/* Make the first vector of every page be the scale... */
/* XXX But what if there is no scale? e.g. op, pz */
if (!noprintscale && bv->v_plot->pl_ndims) {
/* XXX But what if there is no scale? e.g. op, pz */
if (!noprintscale && bv->v_plot->pl_ndims)
if (bv->v_plot->pl_scale && !vec_eq(bv, bv->v_plot->pl_scale)) {
nv = vec_copy(bv->v_plot->pl_scale);
vec_new(nv);
nv->v_link2 = bv;
bv = nv;
}
}
ll = 8;
for (lv = bv; lv; lv = lv->v_link2) {
if (isreal(lv))
@ -258,7 +255,7 @@ nextpage:
/* Print the header on the first page only. */
p = bv->v_plot;
j = (width - (int) strlen(p->pl_title)) / 2; /* Yes, keep "(int)" */
j = (width - (int) strlen(p->pl_title)) / 2; /* Yes, keep "(int)" */
if (j < 0)
j = 0;
for (i = 0; i < j; i++)
@ -279,26 +276,22 @@ nextpage:
out_send(buf2);
(void) sprintf(buf, "Index ");
for (v = bv; v && (v != lv); v = v->v_link2) {
if (isreal(v))
if (isreal(v)) {
(void) sprintf(buf2, "%-16.15s", v->v_name);
else
{
/* The frequency vector is complex but often with imaginary part = 0,
* this prevents to print two columns.
*/
if(eq(v->v_name, "frequency"))
{
if(imagpart(v->v_compdata[0])==0.0)
{
} else {
/* The frequency vector is complex but often with imaginary part = 0,
* this prevents to print two columns.
*/
if (eq(v->v_name, "frequency")) {
if (imagpart(v->v_compdata[0]) == 0.0)
(void) sprintf(buf2, "%-16.15s", v->v_name);
}
else
(void) sprintf(buf2, "%-32.31s", v->v_name);
}
else
} else {
(void) sprintf(buf2, "%-32.31s", v->v_name);
}
}
(void) strcat(buf, buf2);
(void) strcat(buf, buf2);
}
lineno = 3;
j = 0;
@ -306,7 +299,7 @@ nextpage:
for (v = bv; (v && (v != lv)); v = v->v_link2)
if (v->v_length > npoints)
npoints = v->v_length;
pbreak: /* New page. */
pbreak: /* New page. */
out_send(buf);
out_send("\n");
for (i = 0; i < width; i++)
@ -315,7 +308,7 @@ pbreak: /* New page. */
buf2[width+1] = '\0';
out_send(buf2);
lineno += 2;
loop:
loop:
while ((j < npoints) && (lineno < height)) {
out_printf("%d\t", j);
for (v = bv; (v && (v != lv)); v = v->v_link2) {
@ -325,23 +318,18 @@ loop:
else
out_send("\t\t\t\t");
} else {
if (isreal(v))
{
printnum(numbuf, v->v_realdata[j]);
if (isreal(v)) {
printnum(numbuf, v->v_realdata[j]);
out_printf("%s\t", numbuf);
}
else
{
/* In case of a single frequency and have a real part avoids print imaginary part equals 0. */
if(eq(v->v_name, "frequency") &&
imagpart(v->v_compdata[j]) == 0.0)
} else {
/* In case of a single frequency and have a real part avoids print imaginary part equals 0. */
if (eq(v->v_name, "frequency") &&
imagpart(v->v_compdata[j]) == 0.0)
{
printnum(numbuf, realpart(v->v_compdata[j]));
out_printf("%s\t", numbuf);
}
else
{
printnum(numbuf, realpart(v->v_compdata[j]));
printnum(numbuf, realpart(v->v_compdata[j]));
out_printf("%s\t", numbuf);
} else {
printnum(numbuf, realpart(v->v_compdata[j]));
printnum(numbuf2, imagpart(v->v_compdata[j]));
out_printf("%s,\t%s\t", numbuf, numbuf2);
}
@ -375,6 +363,7 @@ done:
return;
}
/* Write out some data. write filename expr ... Some cleverness here is
* required. If the user mentions a few vectors from various plots,
* probably he means for them to be written out seperate plots. In any
@ -388,7 +377,7 @@ com_write(wordlist *wl)
char *file, buf[BSIZE_SP];
struct pnode *n;
struct dvec *d, *vecs = NULL, *lv = NULL, *end, *vv;
static wordlist all = { "all", NULL, NULL } ;
static wordlist all = { "all", NULL, NULL };
struct pnode *names;
bool ascii = AsciiRawFile;
bool scalefound, appendwrite;
@ -397,14 +386,16 @@ com_write(wordlist *wl)
if (wl) {
file = wl->wl_word;
wl = wl->wl_next;
} else
} else {
file = ft_rawfile;
}
if (cp_getvar("filetype", CP_STRING, buf)) {
if (eq(buf, "binary"))
ascii = FALSE;
else if (eq(buf, "ascii"))
ascii = TRUE;
else
else
fprintf(cp_err, "Warning: strange file type %s\n", buf);
}
appendwrite = cp_getvar("appendwrite", CP_BOOL, NULL);
@ -413,8 +404,10 @@ com_write(wordlist *wl)
names = ft_getpnames(wl, TRUE);
else
names = ft_getpnames(&all, TRUE);
if (names == NULL)
return;
for (n = names; n; n = n->pn_next) {
d = ft_evaluate(n);
if (!d)
@ -433,7 +426,7 @@ com_write(wordlist *wl)
tpl = vecs->v_plot;
tpl->pl_written = TRUE;
end = NULL;
bcopy(tpl, &newplot, sizeof (struct plot));
bcopy(tpl, &newplot, sizeof(struct plot));
scalefound = FALSE;
/* Figure out how many vectors are in this plot. Also look
@ -471,15 +464,14 @@ com_write(wordlist *wl)
newplot.pl_dvecs = newplot.pl_scale;
}
/* Now let's go through and make sure that everything that
/* Now let's go through and make sure that everything that
* has its own scale has it in the plot.
*/
for (;;) {
scalefound = FALSE;
for (d = newplot.pl_dvecs; d; d = d->v_next) {
if (d->v_scale) {
for (vv = newplot.pl_dvecs; vv; vv =
vv->v_next)
for (vv = newplot.pl_dvecs; vv; vv = vv->v_next)
if (vec_eq(vv, d->v_scale))
break;
/* We have to grab it... */
@ -489,6 +481,7 @@ com_write(wordlist *wl)
scalefound = TRUE;
}
}
if (!scalefound)
break;
/* Otherwise loop through again... */
@ -505,42 +498,46 @@ com_write(wordlist *wl)
if (lv) {
lv->v_link2 = d->v_link2;
d = lv;
} else
} else {
vecs = d->v_link2;
} else
}
} else {
lv = d;
}
/* If there are more plots we want them appended... */
appendwrite = TRUE;
}
return;
}
/* Write scattering parameters into a file with Touchstone File Format Version 1
with command wrs2p file .
Format info from http://www.eda.org/ibis/touchstone_ver2.0/touchstone_ver2_0.pdf
See example 13 on page 15: Two port, ASCII, real-imaginary
Check if S11, S21, S12, S22 and frequency vectors are available
Check if vector Rbase is available
Call spar_write()
*/
with command wrs2p file .
Format info from http://www.eda.org/ibis/touchstone_ver2.0/touchstone_ver2_0.pdf
See example 13 on page 15: Two port, ASCII, real-imaginary
Check if S11, S21, S12, S22 and frequency vectors are available
Check if vector Rbase is available
Call spar_write()
*/
void
com_write_sparam(wordlist *wl)
{
char *file;
char* sbuf[6];
char *sbuf[6];
wordlist *wl_sparam;
struct pnode *n;
struct dvec *d, *vecs = NULL, *lv = NULL, *end, *vv, *Rbasevec=NULL;
struct dvec *d, *vecs = NULL, *lv = NULL, *end, *vv, *Rbasevec = NULL;
struct pnode *names;
bool scalefound, appendwrite=FALSE;
bool scalefound, appendwrite = FALSE;
struct plot *tpl, newplot;
double Rbaseval;
if (wl) {
if (wl)
file = wl->wl_word;
} else
else
file = "s_param.s2p";
/* generate wordlist with all vectors required*/
sbuf[0] = "frequency";
sbuf[1] = "S11";
@ -553,21 +550,25 @@ com_write_sparam(wordlist *wl)
names = ft_getpnames(wl_sparam, TRUE);
if (names == NULL)
return;
for (n = names; n; n = n->pn_next) {
d = ft_evaluate(n);
if (!d)
return;
if (vecs)
lv->v_link2 = d;
else
vecs = d;
for (lv = d; lv->v_link2; lv = lv->v_link2)
;
}
Rbasevec = vec_get("Rbase");
if (Rbasevec)
if (Rbasevec) {
Rbaseval = Rbasevec->v_realdata[0];
else {
} else {
fprintf(stderr, "Error: No Rbase vector given\n");
return;
}
@ -578,7 +579,7 @@ com_write_sparam(wordlist *wl)
tpl = vecs->v_plot;
tpl->pl_written = TRUE;
end = NULL;
bcopy(tpl, &newplot, sizeof (struct plot));
bcopy(tpl, &newplot, sizeof(struct plot));
scalefound = FALSE;
/* Figure out how many vectors are in this plot. Also look
@ -616,15 +617,14 @@ com_write_sparam(wordlist *wl)
newplot.pl_dvecs = newplot.pl_scale;
}
/* Now let's go through and make sure that everything that
/* Now let's go through and make sure that everything that
* has its own scale has it in the plot.
*/
for (;;) {
scalefound = FALSE;
for (d = newplot.pl_dvecs; d; d = d->v_next) {
if (d->v_scale) {
for (vv = newplot.pl_dvecs; vv; vv =
vv->v_next)
for (vv = newplot.pl_dvecs; vv; vv = vv->v_next)
if (vec_eq(vv, d->v_scale))
break;
/* We have to grab it... */
@ -647,10 +647,12 @@ com_write_sparam(wordlist *wl)
if (lv) {
lv->v_link2 = d->v_link2;
d = lv;
} else
} else {
vecs = d->v_link2;
} else
}
} else {
lv = d;
}
/* If there are more plots we want them appended... */
appendwrite = TRUE;
}
@ -673,8 +675,7 @@ com_transpose(wordlist *wl)
d = vec_get(s);
tfree(s); /*DG: Avoid Memory Leak */
if (d == NULL)
fprintf(cp_err, "Error: no such vector as %s.\n",
wl->wl_word);
fprintf(cp_err, "Error: no such vector as %s.\n", wl->wl_word);
else
while (d) {
vec_transpose(d);
@ -686,6 +687,7 @@ com_transpose(wordlist *wl)
}
}
/* Take a set of vectors and form a new vector of the nth elements of each. */
void
com_cross(wordlist *wl)
@ -713,20 +715,23 @@ com_cross(wordlist *wl)
while (pn) {
if ((n = ft_evaluate(pn)) == NULL)
return;
if (!vecs)
vecs = lv = n;
else
lv->v_link2 = n;
for (lv = n; lv->v_link2; lv = lv->v_link2)
;
pn = pn->pn_next;
}
for (n = vecs, i = 0; n; n = n->v_link2) {
if (iscomplex(n))
comp = TRUE;
i++;
}
vec_remove(newvec);
v = alloc(struct dvec);
v->v_name = copy(newvec);
@ -745,18 +750,18 @@ com_cross(wordlist *wl)
for (n = vecs, i = 0; n; n = n->v_link2, i++)
if (n->v_length > ind) {
if (comp) {
realpart(v->v_compdata[i]) =
realpart(n->v_compdata[ind]);
imagpart(v->v_compdata[i]) =
imagpart(n->v_compdata[ind]);
} else
realpart(v->v_compdata[i]) = realpart(n->v_compdata[ind]);
imagpart(v->v_compdata[i]) = imagpart(n->v_compdata[ind]);
} else {
v->v_realdata[i] = n->v_realdata[ind];
}
} else {
if (comp) {
realpart(v->v_compdata[i]) = 0.0;
imagpart(v->v_compdata[i]) = 0.0;
} else
} else {
v->v_realdata[i] = 0.0;
}
}
vec_new(v);
v->v_flags |= VF_PERMANENT;
@ -764,50 +769,46 @@ com_cross(wordlist *wl)
return;
}
void
com_destroy(wordlist *wl)
{
struct plot *pl, *npl = NULL;
if (!wl) {
DelPlotWindows(plot_cur);
killplot(plot_cur);
}
else if (eq(wl->wl_word, "all")) {
DelPlotWindows(plot_cur);
killplot(plot_cur);
} else if (eq(wl->wl_word, "all")) {
for (pl = plot_list; pl; pl = npl) {
npl = pl->pl_next;
if (!eq(pl->pl_typename, "const"))
{
DelPlotWindows(pl);
if (!eq(pl->pl_typename, "const")) {
DelPlotWindows(pl);
killplot(pl);
} else {
plot_num = 1;
}
else
{
plot_num=1;
}
}
} else {
while (wl) {
for (pl = plot_list; pl; pl = pl->pl_next)
if (eq(pl->pl_typename, wl->wl_word))
break;
if (pl)
{
if (pl) {
DelPlotWindows(pl);
killplot(pl);
}
else
} else {
fprintf(cp_err, "Error: no such plot %s\n", wl->wl_word);
}
wl = wl->wl_next;
}
}
return;
}
static void
killplot(struct plot *pl)
{
struct dvec *v, *nv = NULL;
struct plot *op;
@ -831,7 +832,7 @@ killplot(struct plot *pl)
break;
if (!op)
fprintf(cp_err,
"Internal Error: kill plot -- not in list\n");
"Internal Error: kill plot -- not in list\n");
op->pl_next = pl->pl_next;
if (pl == plot_cur)
plot_cur = op;
@ -842,44 +843,46 @@ killplot(struct plot *pl)
wl_free(pl->pl_commands);
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);
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;
}
/* delete all windows with graphs dedrived from a given plot */
/* delete all windows with graphs dedrived from a given plot */
static void
DelPlotWindows(struct plot *pl)
{
/* do this only if windows or X11 is defined */
/* do this only if windows or X11 is defined */
#if defined(HAS_WINDOWS) || !defined(X_DISPLAY_MISSING)
GRAPH *dgraph;
int n;
/* find and remove all graph structures derived from a given plot */
for (n=1; n < 100; n++) { /* should be no more than 100 */
dgraph = FindGraph(n);
if(dgraph) {
if (ciprefix(pl->pl_typename, dgraph->plotname))
RemoveWindow(dgraph);
}
/* We have to run through all potential graph ids. If some numbers are
already missing, 'else break;' might miss the plotwindow to be removed. */
/* else
break; */
}
GRAPH *dgraph;
int n;
/* find and remove all graph structures derived from a given plot */
for (n = 1; n < 100; n++) { /* should be no more than 100 */
dgraph = FindGraph(n);
if (dgraph) {
if (ciprefix(pl->pl_typename, dgraph->plotname))
RemoveWindow(dgraph);
}
/* We have to run through all potential graph ids. If some numbers are
already missing, 'else break;' might miss the plotwindow to be removed. */
/* else
break;
*/
}
#else
NG_IGNORE(pl);
#endif
}
void
com_splot(wordlist *wl)
{
@ -896,7 +899,7 @@ com_splot(wordlist *wl)
fprintf(cp_out, "%s%s\t%s (%s)\n",
(pl == plot_cur) ? "Current " : "\t",
pl->pl_typename, pl->pl_title, pl->pl_name);
fprintf(cp_out, "? ");
if (!fgets(buf, BSIZE_SP, cp_in)) {
clearerr(cp_in);
@ -909,4 +912,3 @@ com_splot(wordlist *wl)
plot_setcur(s);
return;
}

View File

@ -4,7 +4,7 @@ Author: 1988 Jeffrey M. Hsu
**********/
/*
Postscript driver
Postscript driver
*/
#include "ngspice/ngspice.h"
@ -19,9 +19,9 @@ Author: 1988 Jeffrey M. Hsu
#include "variable.h"
#include "plotting/graphdb.h"
#define RAD_TO_DEG (180.0 / M_PI)
#define RAD_TO_DEG (180.0 / M_PI)
#define DEVDEP(g) (*((PSdevdep *) (g)->devdep))
#define MAX_PS_LINES 1000
#define MAX_PS_LINES 1000
#define SOLID 0
#define DOTTED 1
@ -41,16 +41,17 @@ Author: 1988 Jeffrey M. Hsu
#define FONTHEIGHT 14 /* printer default fontheight */
typedef struct {
int lastlinestyle, lastcolor; /* initial invalid value */
int lastx, lasty, linecount;
int lastlinestyle, lastcolor; /* initial invalid value */
int lastx, lasty, linecount;
} PSdevdep;
static char *linestyle[] = {
"[]", /* solid */
"[1 2]", /* dotted */
"[7 7]", /* longdashed */
"[3 3]", /* shortdashed */
"[7 2 2 2]", /* longdotdashed */
"[7 2 2 2]", /* longdotdashed */
"[3 2 1 2]", /* shortdotdashed */
"[8 3 2 3]",
"[14 2]",
@ -66,7 +67,7 @@ static int screenflag = 0;
static int colorflag = 0;
static int setbgcolor = 0;
static int settxcolor = -1;
static double scale; /* Used for fine tuning */
static double scale; /* Used for fine tuning */
static int xtadj; /* text adjustment x */
static int ytadj; /* text adjustment y */
static int hcopygraphid;
@ -76,28 +77,29 @@ void PS_LinestyleColor(int linestyleid, int colorid);
void PS_SelectColor(int colorid);
void PS_Stroke(void);
/* Set scale, color and size of the plot */
int
PS_Init(void)
{
char pswidth[30], psheight[30];
if (!cp_getvar("hcopyscale", CP_STRING, psscale)) {
scale = 1.0;
} else {
sscanf(psscale, "%lf", &scale);
if ((scale <= 0) || (scale > 10))
scale = 1.0;
scale = 1.0;
}
dispdev->numlinestyles = NUMELEMS(linestyle);
/* plot color */
dispdev->numlinestyles = NUMELEMS(linestyle);
/* plot color */
if (!cp_getvar("hcopypscolor", CP_NUM, &setbgcolor)) {
/* if not set, set plot to b&w and use line styles */
colorflag = 0;
dispdev->numcolors = 2;
} else {
/* get backgroung color and set plot to color */
/* get backgroung color and set plot to color */
colorflag = 1;
dispdev->numcolors = 21; /* don't know what the maximum should be */
cp_getvar("hcopypstxcolor", CP_NUM, &settxcolor);
@ -123,7 +125,7 @@ PS_Init(void)
dispdev->height = 10000;
}
/* The following side effects have to be considered
/* The following side effects have to be considered
* when the printer is called by com_hardcopy !
* gr_init:
* viewportxoff = 8 * fontwidth
@ -155,27 +157,27 @@ PS_Init(void)
dispdev->minx = (int)(XOFF / scale);
dispdev->miny = (int)(YOFF / scale);
return(0);
return (0);
}
/* Plot and fill bounding box */
int
PS_NewViewport(GRAPH *graph)
{
int x1,x2,y1,y2;
int x1, x2, y1, y2;
hcopygraphid = graph->graphid;
/* devdep initially contains name of output file */
if ((plotfile = fopen((char*)graph->devdep, "w")) == NULL) {
perror((char*)graph->devdep);
graph->devdep = NULL;
return(1);
graph->devdep = NULL;
return (1);
}
if (graph->absolute.width) {
/* hardcopying from the screen */
/* hardcopying from the screen */
screenflag = 1;
screenflag = 1;
}
/* reasonable values, used in gr_ for placement */
@ -198,23 +200,23 @@ PS_NewViewport(GRAPH *graph)
/* 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",x1,y1,x2,y2);
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){
if (colorflag == 1) {
/* set the background to color given in spinit (or 0) */
PS_SelectColor(setbgcolor);
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");
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\n",
psfont, (int) (fontsize * scale));
psfont, (int) (fontsize * scale));
graph->devdep = TMALLOC(PSdevdep, 1);
DEVDEP(graph).lastlinestyle = -1;
@ -228,12 +230,12 @@ PS_NewViewport(GRAPH *graph)
return 0;
}
int
PS_Close(void)
{
/* in case PS_Close is called as part of an abort,
w/o having reached PS_NewViewport */
w/o having reached PS_NewViewport */
if (plotfile) {
PS_Stroke();
fprintf(plotfile, "showpage\n%%%%EOF\n");
@ -250,6 +252,7 @@ PS_Close(void)
return 0;
}
int
PS_Clear(void)
{
@ -257,22 +260,24 @@ PS_Clear(void)
return 0;
}
int
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 */
=> will have to give NewViewport a writeable graph XXX */
if (DEVDEP(currentgraph).linecount > MAX_PS_LINES
|| DEVDEP(currentgraph).linecount == 0
|| x1 != DEVDEP(currentgraph).lastx
|| y1 != DEVDEP(currentgraph).lasty){
if (DEVDEP(currentgraph).linecount > MAX_PS_LINES ||
DEVDEP(currentgraph).linecount == 0 ||
x1 != DEVDEP(currentgraph).lastx ||
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);
DEVDEP(currentgraph).linecount += 1;
@ -283,6 +288,7 @@ PS_DrawLine(int x1, int y1, int x2, int y2)
return 0;
}
int
PS_Arc(int x0, int y0, int r, double theta, double delta_theta)
{
@ -297,32 +303,33 @@ PS_Arc(int x0, int y0, int r, double theta, double delta_theta)
fprintf(plotfile, "%f %f moveto ", x1+(double)xoff, y1+(double)yoff);
fprintf(plotfile, "%d %d %d %f %f arc\n", x0+xoff, y0+yoff, r,
angle1, angle2);
angle1, angle2);
fprintf(plotfile, "stroke\n");
DEVDEP(currentgraph).linecount = 0;
return 0;
}
int
PS_Text(char *text, int x, int y)
{
int savedlstyle, savedcolor;
/* set linestyle to solid
or may get funny color text on some plotters */
or may get funny color text on some plotters */
savedlstyle = currentgraph->linestyle;
savedcolor = currentgraph->currentcolor;
PS_SetLinestyle(SOLID);
/* set text color to black if background is not white */
if (setbgcolor > 0)
PS_SetColor(0);
PS_SetColor(0);
else
PS_SetColor(1);
PS_SetColor(1);
/* if color is given by set hcopytxpscolor=settxcolor, give it a try */
if (settxcolor >= 0)
PS_SetColor(settxcolor);
PS_SetColor(settxcolor);
/* stroke the path if there's an open one */
PS_Stroke();
/* move to (x, y) */
@ -339,15 +346,15 @@ PS_Text(char *text, int x, int y)
return 0;
}
/* PS_DefineColor */
/* PS_DefineLinestyle */
int
PS_SetLinestyle(int linestyleid)
{
/* special case
get it when PS_Text restores a -1 linestyle */
get it when PS_Text restores a -1 linestyle */
if (linestyleid == -1) {
currentgraph->linestyle = -1;
return 0;
@ -361,6 +368,7 @@ PS_SetLinestyle(int linestyleid)
return 0;
}
int
PS_SetColor(int colorid)
{
@ -368,6 +376,7 @@ PS_SetColor(int colorid)
return 0;
}
int
PS_Update(void)
{
@ -375,127 +384,129 @@ PS_Update(void)
return 0;
}
/**************** 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";
int 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 */
char colorN[30] = "", colorstring[30] = "";
char rgb[30], s_red[30] = "0x", s_green[30] = "0x", s_blue[30] = "0x";
int 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, CP_STRING, colorstring)){
for (i=0; colorstring[i]; i++)
if (colorstring[i] == '/' || colorstring[i] == ':')
colorstring[i] = ' ';
/* Extract the rgbcolor, format is: "rgb:<red>/<green>/<blue>" */
sprintf(colorN, "color%d", colorid);
if (cp_getvar(colorN, CP_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]));
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,"%x",&red);
sscanf(s_green,"%x",&green);
sscanf(s_blue,"%x",&blue);
scale= (1 << (strlen(s_blue) - 2) * 4) - 1;
sprintf(colorstring,"%1.3f %1.3f %1.3f",
(double) red/scale, (double) green/scale, (double) blue/scale);
strcpy(pscolor, colorstring);
if ((strlen(s_blue) == strlen(s_red) && strlen(s_green) == strlen(s_red))
&& (strlen(s_blue) > 2) && (strlen(s_blue) < 7)) {
sscanf(s_red, "%x", &red);
sscanf(s_green, "%x", &green);
sscanf(s_blue, "%x", &blue);
scale = (1 << (strlen(s_blue) - 2) * 4) - 1;
sprintf(colorstring, "%1.3f %1.3f %1.3f",
(double) red/scale, (double) green/scale, (double) 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);
}
}
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;
/* 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 */
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 if (linestyleid == -1)
genstyle=0;
else
genstyle=linestyleid;
}
int gencolor = 0, genstyle = 0;
/* change color if nessecary */
if (colorflag == 1 && gencolor != DEVDEP(currentgraph).lastcolor){
/* if background is white, set all white line colors to black */
if ((setbgcolor == 1) && (gencolor == 1))
PS_SelectColor(0);
else
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;
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 if (linestyleid == -1)
genstyle = 0;
else
genstyle = linestyleid;
}
/* change color if nessecary */
if (colorflag == 1 && gencolor != DEVDEP(currentgraph).lastcolor) {
/* if background is white, set all white line colors to black */
if ((setbgcolor == 1) && (gencolor == 1))
PS_SelectColor(0);
else
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;
}
/* strokes an open path */
if (DEVDEP(currentgraph).linecount > 0) {
fprintf(plotfile, "stroke\n");
DEVDEP(currentgraph).linecount = 0;
}
}

View File

@ -23,28 +23,30 @@ cp_wstrip(char *str)
char c, d;
if (str)
while ((c = *str) != '\0') { /* assign and test */
d = (char) strip(c);
if (c != d)
*str = d;
str++;
}
while ((c = *str) != '\0') { /* assign and test */
d = (char) strip(c);
if (c != d)
*str = d;
str++;
}
return;
}
/* Quote all characters in a word. */
void
cp_quoteword(char *str)
{
if (str)
while (*str) {
*str = (char) quote(*str);
str++;
}
while (*str) {
*str = (char) quote(*str);
str++;
}
return;
}
/* Print a word (strip the word first). */
void
@ -58,6 +60,7 @@ cp_printword(char *string, FILE *fp)
return;
}
/* (Destructively) strip all the words in a wlist. */
void
@ -70,6 +73,7 @@ cp_striplist(wordlist *wlist)
return;
}
/* Remove the "" from a string. */
char *
@ -77,17 +81,20 @@ cp_unquote(char *string)
{
char *s;
size_t l;
if (string) {
l = strlen(string);
s = TMALLOC(char, l + 1);
if (l>=2 && *string == '"' && string[l-1] == '"') {
strncpy(s,string+1,l-2);
s[l-2] = '\0';
} else
strcpy(s,string);
return (s);
} else
return 0;
if (string) {
l = strlen(string);
s = TMALLOC(char, l + 1);
if (l >= 2 && *string == '"' && string[l-1] == '"') {
strncpy(s, string+1, l-2);
s[l-2] = '\0';
} else {
strcpy(s, string);
}
return (s);
} else {
return 0;
}
}

View File

@ -17,7 +17,7 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "variable.h"
#include "../misc/misc_time.h"
/* static declarations */
static void fixdims(struct dvec *v, char *s);
@ -27,7 +27,7 @@ int raw_prec = -1; /* How many sigfigs to use, default 15 (max). */
#ifdef HAS_WINDOWS
#undef fscanf /* redo I/O from WINMAIN.C here
otherwise reading ASCII will not work */
otherwise reading ASCII will not work */
#endif
@ -62,25 +62,25 @@ raw_write(char *name, struct plot *pl, bool app, bool binary)
prec = DEFPREC;
#if defined(__MINGW32__) || defined(_MSC_VER)
/* - Binary file binary write - hvogt 15.03.2000 ---------------------*/
if (binary) {
if ((fp = fopen(name, app ? "ab" : "wb")) == NULL) {
perror(name);
return;
}
fprintf(cp_out,"binary raw file\n");
} else {
fprintf(cp_out, "binary raw file\n");
} else {
if ((fp = fopen(name, app ? "a" : "w")) == NULL) {
perror(name);
return;
}
fprintf(cp_out,"ASCII raw file\n");
fprintf(cp_out, "ASCII raw file\n");
}
/* --------------------------------------------------------------------*/
#else
if (!(fp = fopen(name, app ? "a" : "w"))) {
perror(name);
return;
@ -115,7 +115,7 @@ raw_write(char *name, struct plot *pl, bool app, bool binary)
fprintf(fp, "Date: %s\n", pl->pl_date);
fprintf(fp, "Plotname: %s\n", pl->pl_name);
fprintf(fp, "Flags: %s%s\n",
realflag ? "real" : "complex", raw_padding ? "" : " unpadded" );
realflag ? "real" : "complex", raw_padding ? "" : " unpadded");
fprintf(fp, "No. Variables: %d\n", nvars);
fprintf(fp, "No. Points: %d\n", length);
if (numdims > 1) {
@ -154,14 +154,14 @@ raw_write(char *name, struct plot *pl, bool app, bool binary)
fprintf(fp, "Variables:\n");
for (i = 0, v = pl->pl_dvecs; v; v = v->v_next) {
if ( strcmp( ft_typenames(v->v_type), "current" ) == 0 ) {
if (strcmp(ft_typenames(v->v_type), "current") == 0) {
branch = NULL;
if ((branch = strstr( v->v_name, "#branch" )) != NULL) {
if ((branch = strstr(v->v_name, "#branch")) != NULL) {
*branch = '\0';
}
fprintf(fp, "\t%d\ti(%s)\t%s", i++, v->v_name, ft_typenames(v->v_type));
if ( branch != NULL ) *branch = '#';
} else if ( strcmp( ft_typenames(v->v_type), "voltage" ) == 0 ) {
if (branch != NULL) *branch = '#';
} else if (strcmp(ft_typenames(v->v_type), "voltage") == 0) {
fprintf(fp, "\t%d\t%s\t%s", i++, v->v_name, ft_typenames(v->v_type));
} else {
fprintf(fp, "\t%d\t%s\t%s", i++, v->v_name, ft_typenames(v->v_type));
@ -187,7 +187,7 @@ raw_write(char *name, struct plot *pl, bool app, bool binary)
}
if (writedims) {
dimstring(v->v_dims, v->v_numdims, buf);
fprintf(fp, " dims=%s",buf);
fprintf(fp, " dims=%s", buf);
}
(void) putc('\n', fp);
}
@ -201,33 +201,25 @@ raw_write(char *name, struct plot *pl, bool app, bool binary)
if (realflag) {
dd = (isreal(v) ? v->v_realdata[i] :
realpart(v->v_compdata[i]));
(void) fwrite(&dd, sizeof
(double), 1, fp);
(void) fwrite(&dd, sizeof(double), 1, fp);
} else if (isreal(v)) {
dd = v->v_realdata[i];
(void) fwrite(&dd, sizeof
(double), 1, fp);
(void) fwrite(&dd, sizeof(double), 1, fp);
dd = 0.0;
(void) fwrite(&dd, sizeof
(double), 1, fp);
(void) fwrite(&dd, sizeof(double), 1, fp);
} else {
dd = realpart(v->v_compdata[i]);
(void) fwrite(&dd, sizeof
(double), 1, fp);
(void) fwrite(&dd, sizeof(double), 1, fp);
dd = imagpart(v->v_compdata[i]);
(void) fwrite(&dd, sizeof
(double), 1, fp);
(void) fwrite(&dd, sizeof(double), 1, fp);
}
} else if (raw_padding) {
dd = 0.0;
if (realflag) {
(void) fwrite(&dd, sizeof
(double), 1, fp);
(void) fwrite(&dd, sizeof(double), 1, fp);
} else {
(void) fwrite(&dd, sizeof
(double), 1, fp);
(void) fwrite(&dd, sizeof
(double), 1, fp);
(void) fwrite(&dd, sizeof(double), 1, fp);
(void) fwrite(&dd, sizeof(double), 1, fp);
}
}
}
@ -251,12 +243,10 @@ raw_write(char *name, struct plot *pl, bool app, bool binary)
prec,
imagpart(v->v_compdata[i]));
} else if (raw_padding) {
if (realflag) {
if (realflag)
fprintf(fp, "\t%.*e\n", prec, 0.0);
} else {
fprintf(fp, "\t%.*e,%.*e\n",
prec, 0.0, prec, 0.0);
}
else
fprintf(fp, "\t%.*e,%.*e\n", prec, 0.0, prec, 0.0);
}
}
(void) putc('\n', fp);
@ -266,6 +256,7 @@ raw_write(char *name, struct plot *pl, bool app, bool binary)
return;
}
/* Read a raw file. Returns a list of plot structures. This routine should be
* very flexible about what it expects to see in the rawfile. Really all we
* require is that there be one variables and one values section per plot
@ -306,8 +297,8 @@ raw_read(char *name) {
struct plot *plots = NULL, *curpl = NULL;
char buf[BSIZE_SP], buf2[BSIZE_SP], *s, *t, *r;
int flags = 0, nvars = 0, npoints = 0, i, j;
int ndimpoints, numdims=0, dims[MAXDIMS];
bool raw_padded = TRUE, is_ascii=FALSE;
int ndimpoints, numdims = 0, dims[MAXDIMS];
bool raw_padded = TRUE, is_ascii = FALSE;
double junk;
struct dvec *v, *nv;
struct variable *vv;
@ -332,7 +323,7 @@ raw_read(char *name) {
while (fgets(buf, BSIZE_SP, fp)) {
r = strchr(buf, '\n');
if(r && r > buf && r[-1] == '\r') {
if (r && r > buf && r[-1] == '\r') {
r[-1] = '\n';
r[0] = '\0';
}
@ -352,9 +343,10 @@ raw_read(char *name) {
SKIP(s);
NONL(s);
if (curpl) { /* reverse commands list */
for (wl=curpl->pl_commands,
curpl->pl_commands=NULL; wl &&
wl->wl_next; wl=nwl) {
for (wl = curpl->pl_commands, curpl->pl_commands = NULL;
wl && wl->wl_next;
wl = nwl)
{
nwl = wl->wl_next;
wl->wl_next = curpl->pl_commands;
curpl->pl_commands = wl;
@ -365,7 +357,7 @@ raw_read(char *name) {
plots = curpl;
curpl->pl_name = copy(s);
if (!date)
date = copy(datestring( ));
date = copy(datestring());
curpl->pl_date = date;
curpl->pl_title = copy(title);
flags = VF_PERMANENT;
@ -383,9 +375,7 @@ raw_read(char *name) {
else if (cieq(t, "padded"))
raw_padded = TRUE;
else
fprintf(cp_err,
"Warning: unknown flag %s\n",
t);
fprintf(cp_err, "Warning: unknown flag %s\n", t);
}
} else if (ciprefix("no. variables:", buf)) {
s = buf;
@ -418,9 +408,8 @@ raw_read(char *name) {
/* Let's just make sure that the no. of points
* and the dimensions are consistent.
*/
for (j = 0, ndimpoints = 1; j < numdims; j++) {
for (j = 0, ndimpoints = 1; j < numdims; j++)
ndimpoints *= dims[j];
}
if (ndimpoints != npoints) {
fprintf(cp_err,
@ -435,9 +424,9 @@ raw_read(char *name) {
if (curpl) {
curpl->pl_commands = wl_cons(copy(s), curpl->pl_commands);
wl = curpl->pl_commands;
} else
fprintf(cp_err,
"Error: misplaced Command: line\n");
} else {
fprintf(cp_err, "Error: misplaced Command: line\n");
}
/* Now execute the command if we can. */
(void) cp_evloop(s);
} else if (ciprefix("option:", buf)) {
@ -447,15 +436,15 @@ raw_read(char *name) {
if (curpl) {
wl = cp_lexer(s);
for (vv = curpl->pl_env; vv && vv->va_next;
vv = vv->va_next)
vv = vv->va_next)
;
if (vv)
vv->va_next = cp_setparse(wl);
else
curpl->pl_env = cp_setparse(wl);
} else
fprintf(cp_err,
"Error: misplaced Option: line\n");
} else {
fprintf(cp_err, "Error: misplaced Option: line\n");
}
} else if (ciprefix("variables:", buf)) {
/* We reverse the dvec list eventually... */
if (!curpl) {
@ -487,19 +476,17 @@ raw_read(char *name) {
v->v_numdims = 0;
/* Length and dims might be changed by options. */
if (!i)
if (!i) {
curpl->pl_scale = v;
else {
} else {
(void) fgets(buf, BSIZE_SP, fp);
s = buf;
}
(void) gettok(&s); /* The strchr field. */
if ((t = gettok(&s)) != NULL)
if ((t = gettok(&s)) != NULL) {
v->v_name = t;
else {
fprintf(cp_err,
"Error: bad var line %s\n",
buf);
} else {
fprintf(cp_err, "Error: bad var line %s\n", buf);
/* MW. v_name must be valid in the case that no. points = 0 */
v->v_name = "no vars\n";
}
@ -507,51 +494,37 @@ raw_read(char *name) {
if (t)
v->v_type = ft_typnum(t);
else
fprintf(cp_err,
"Error: bad var line %s\n",
buf);
fprintf(cp_err, "Error: bad var line %s\n", buf);
/* Fix the name... */
if (isdigit(*v->v_name) && (r = ft_typabbrev(v
->v_type)) != NULL) {
(void) sprintf(buf2, "%s(%s)", r,
v->v_name);
if (isdigit(*v->v_name) && (r = ft_typabbrev(v ->v_type)) != NULL) {
(void) sprintf(buf2, "%s(%s)", r, v->v_name);
v->v_name = copy(buf2);
}
/* Now come the strange options... */
while ((t = gettok(&s)) != NULL) {
if (ciprefix("min=", t)) {
if (sscanf(t + 4, "%lf",
&v->v_minsignal) != 1)
fprintf(cp_err,
"Error: bad arg %s\n",
t);
if (sscanf(t + 4, "%lf", &v->v_minsignal) != 1)
fprintf(cp_err, "Error: bad arg %s\n", t);
v->v_flags |= VF_MINGIVEN;
} else if (ciprefix("max=", t)) {
if (sscanf(t + 4, "%lf",
&v->v_maxsignal) != 1)
fprintf(cp_err,
"Error: bad arg %s\n",
t);
if (sscanf(t + 4, "%lf", &v->v_maxsignal) != 1)
fprintf(cp_err, "Error: bad arg %s\n", t);
v->v_flags |= VF_MAXGIVEN;
} else if (ciprefix("color=", t)) {
v->v_defcolor = copy(t + 6);
} else if (ciprefix("scale=", t)) {
// This cast is bad, but...
v->v_scale = (struct dvec *)
copy(t + 6);
v->v_scale = (struct dvec *) copy(t + 6);
} else if (ciprefix("grid=", t)) {
v->v_gridtype = (GRIDTYPE)
scannum(t + 5);
v->v_gridtype = (GRIDTYPE) scannum(t + 5);
} else if (ciprefix("plot=", t)) {
v->v_plottype = (PLOTTYPE)
scannum(t + 5);
v->v_plottype = (PLOTTYPE) scannum(t + 5);
} else if (ciprefix("dims=", t)) {
fixdims(v, t + 5);
} else {
fprintf(cp_err,
"Warning: bad var param %s\n",
t);
fprintf(cp_err, "Warning: bad var param %s\n", t);
}
}
/* Now we default any missing dimensions. */
@ -569,8 +542,9 @@ raw_read(char *name) {
else
v->v_compdata = TMALLOC(ngcomplex_t, npoints);
}
} else if (ciprefix("values:", buf) ||
ciprefix("binary:", buf)) {
} else if (ciprefix("values:", buf) || ciprefix("binary:", buf)) {
if (!curpl) {
fprintf(cp_err, "Error: no plot name given\n");
plots = NULL;
@ -578,8 +552,7 @@ raw_read(char *name) {
}
/* We'd better reverse the dvec list now... */
for (v = curpl->pl_dvecs, curpl->pl_dvecs = NULL; v;
v = nv) {
for (v = curpl->pl_dvecs, curpl->pl_dvecs = NULL; v; v = nv) {
nv = v->v_next;
v->v_next = curpl->pl_dvecs;
curpl->pl_dvecs = v;
@ -588,25 +561,26 @@ raw_read(char *name) {
/* And fix the scale pointers. */
for (v = curpl->pl_dvecs; v; v = v->v_next) {
if (v->v_scale) {
for (nv = curpl->pl_dvecs; nv; nv =
nv->v_next)
if (cieq((char *) v->v_scale, // This cast is bad, but...
nv->v_name)) {
for (nv = curpl->pl_dvecs; nv; nv = nv->v_next)
// This cast is bad, but...
if (cieq((char *) v->v_scale, nv->v_name)) {
v->v_scale = nv;
break;
}
if (!nv) {
// This cast is bad, but...
fprintf(cp_err,
"Error: no such vector %s\n",
(char *) v->v_scale); // This cast is bad, but...
"Error: no such vector %s\n", (char *) v->v_scale);
v->v_scale = NULL;
}
}
}
if ((*buf == 'v') || (*buf == 'V'))
is_ascii=TRUE;
is_ascii = TRUE;
else
is_ascii=FALSE;
is_ascii = FALSE;
for (i = 0; i < npoints; i++) {
if (is_ascii) {
/* It's an ASCII file. */
@ -614,8 +588,7 @@ raw_read(char *name) {
for (v = curpl->pl_dvecs; v; v = v->v_next) {
if (i < v->v_length) {
if (flags & VF_REAL) {
if (fscanf(fp, " %lf",
&v->v_realdata[i]) != 1)
if (fscanf(fp, " %lf", &v->v_realdata[i]) != 1)
GETOUT();
} else {
if (fscanf(fp, " %lf, %lf",
@ -625,12 +598,10 @@ raw_read(char *name) {
}
} else if (raw_padded) {
if (flags & VF_REAL) {
if (fscanf(fp, " %lf",
&junk) != 1)
if (fscanf(fp, " %lf", &junk) != 1)
GETOUT();
} else {
if (fscanf(fp, " %lf, %lf",
&junk, &junk) != 2)
if (fscanf(fp, " %lf, %lf", &junk, &junk) != 2)
GETOUT();
}
}
@ -641,27 +612,27 @@ raw_read(char *name) {
if (i < v->v_length) {
if (flags & VF_REAL) {
if (fread(&v->v_realdata[i],
sizeof (double), 1, fp) != 1)
sizeof(double), 1, fp) != 1)
GETOUT();
} else {
if (fread(&v->v_compdata[i].cx_real,
sizeof (double), 1, fp) != 1)
sizeof(double), 1, fp) != 1)
GETOUT();
if (fread(&v->v_compdata[i].cx_imag,
sizeof (double), 1, fp) != 1)
sizeof(double), 1, fp) != 1)
GETOUT();
}
} else if (raw_padded) {
if (flags & VF_REAL) {
if (fread(&junk,
sizeof (double), 1, fp) != 1)
sizeof(double), 1, fp) != 1)
GETOUT();
} else {
if (fread(&junk,
sizeof (double), 1, fp) != 1)
sizeof(double), 1, fp) != 1)
GETOUT();
if (fread(&junk,
sizeof (double), 1, fp) != 1)
sizeof(double), 1, fp) != 1)
GETOUT();
}
}
@ -675,16 +646,17 @@ raw_read(char *name) {
}
if (*s) {
fprintf(cp_err,
"Error: strange line in rawfile:\n %s\n load aborted.\n", buf);
"Error: strange line in rawfile:\n %s\n load aborted.\n", buf);
return (NULL);
}
}
}
if (curpl) { /* reverse commands list */
for (wl=curpl->pl_commands,
curpl->pl_commands=NULL; wl &&
wl->wl_next; wl=nwl) {
for (wl = curpl->pl_commands, curpl->pl_commands = NULL;
wl && wl->wl_next;
wl = nwl)
{
nwl = wl->wl_next;
wl->wl_next = curpl->pl_commands;
curpl->pl_commands = wl;
@ -700,6 +672,7 @@ raw_read(char *name) {
return (plots);
}
/* s is a string of the form d1,d2,d3... */
static void
@ -720,18 +693,18 @@ fixdims(struct dvec *v, char *s)
* have serious problems with this vector. Try to fix
* by setting to default dimensions when we return.
*/
for (i = 0, ndimpoints = 1; i < v->v_numdims; i++) {
for (i = 0, ndimpoints = 1; i < v->v_numdims; i++)
ndimpoints *= v->v_dims[i];
}
if (ndimpoints > v->v_length) {
if (ndimpoints > v->v_length)
v->v_numdims = 0;
} else {
else
v->v_length = ndimpoints;
}
return;
}
/* Write a s-param file according to format Touchstone Vers. 1. */
void
@ -757,17 +730,17 @@ spar_write(char *name, struct plot *pl, double Rbaseval)
for (v = pl->pl_dvecs; v; v = v->v_next) {
/* All vectors have to have same length,
only dimension 1 is allowed */
if (length == 0) {
only dimension 1 is allowed */
if (length == 0)
length = v->v_length;
}
if (length != v->v_length) {
fprintf(stderr,"Error writing s2p: lentgth of vector %s differs from length of vector 'frequency'\n",
fprintf(stderr, "Error writing s2p: lentgth of vector %s differs from length of vector 'frequency'\n",
v->v_name);
return;
}
if (v->v_numdims != 1) {
fprintf(stderr,"Error writing s2p: Dimension of vector %s greater than 1\n",v->v_name);
fprintf(stderr, "Error writing s2p: Dimension of vector %s greater than 1\n", v->v_name);
return;
}
@ -776,17 +749,17 @@ spar_write(char *name, struct plot *pl, double Rbaseval)
* Be paranoid and assume somewhere we may have
* forgotten to set the dimensions of 1-D vectors.
if (v->v_numdims <= 1) {
v->v_numdims = 1;
v->v_dims[0] = v->v_length;
}
if (v->v_length > length) {
length = v->v_length;
numdims = v->v_numdims;
for (j = 0; j < numdims; j++) {
dims[j] = v->v_dims[j];
}
}*/
if (v->v_numdims <= 1) {
v->v_numdims = 1;
v->v_dims[0] = v->v_length;
}
if (v->v_length > length) {
length = v->v_length;
numdims = v->v_numdims;
for (j = 0; j < numdims; j++) {
dims[j] = v->v_dims[j];
}
}*/
}
if ((fp = fopen(name, "w")) == NULL) {
@ -799,9 +772,9 @@ spar_write(char *name, struct plot *pl, double Rbaseval)
fprintf(fp, "!Generated by ngspice at %s\n", pl->pl_date);
fprintf(fp, "# Hz S RI R %g\n", Rbaseval);
fprintf(fp, "!%-*.5s %-*.5s %-*.5s %-*.5s %-*.5s %-*.5s %-*.5s %-*.5s %-*.5s\n",
prec+8,"freq",
prec+8,"ReS11",prec+8,"ImS11",prec+8,"ReS21",prec+8,"ImS21",
prec+8,"ReS12",prec+8,"ImS12",prec+8,"ReS22",prec+8,"ImS22");
prec+8, "freq",
prec+8, "ReS11", prec+8, "ImS11", prec+8, "ReS21", prec+8, "ImS21",
prec+8, "ReS12", prec+8, "ImS12", prec+8, "ReS22", prec+8, "ImS22");
/* Before we write the stuff out, make sure that the scale is the first
* in the list.
@ -815,7 +788,7 @@ spar_write(char *name, struct plot *pl, double Rbaseval)
}
/* print frequency first as real value, the real and imag part of
S11, S21, S12, S22 respectively */
S11, S21, S12, S22 respectively */
for (i = 0; i < length; i++) {
for (v = pl->pl_dvecs; v; v = v->v_next) {
if (i < v->v_length) {

View File

@ -41,7 +41,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#ifdef HAVE_WIN32
#define WIN32_LEAN_AND_MEAN
#ifdef __MINGW32__ /* access to GlobalMemoryStatusEx in winbase.h:1558 */
#define WINVER 0x0500
#endif
@ -51,11 +51,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
* However, BOOLEAN is not used by this file so we can work round this problem
* by undefining BOOLEAN before including windows.h
* SJB - April 2005
*/
*/
#undef BOOLEAN
#include <windows.h>
/* At least Windows 2000 is needed
* Undefine _WIN32_WINNT 0x0500 if you want to compile under Windows ME
/* At least Windows 2000 is needed
* Undefine _WIN32_WINNT 0x0500 if you want to compile under Windows ME
* and older (not tested under Windows ME or 98!)
*/
#if defined(__MINGW32__) || (_MSC_VER > 1200) /* Exclude VC++ 6.0 from using the psapi */
@ -64,41 +64,43 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#endif /* HAVE_WIN32 */
/* Uncheck the following definition if you want to get the old usage information
#undef HAVE__PROC_MEMINFO
/* Uncheck the following definition if you want to get the old usage information
#undef HAVE__PROC_MEMINFO
*/
/* static declarations */
static void printres(char *name);
static void fprintmem(FILE* stream, unsigned long long memory);
#if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
static void printres(char *name);
static void fprintmem(FILE *stream, unsigned long long memory);
#if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
static int get_procm(struct proc_mem *memall);
static int get_sysmem(struct sys_mem *memall);
struct sys_mem mem_t, mem_t_act;
struct sys_mem mem_t, mem_t_act;
struct proc_mem mem_ng, mem_ng_act;
#else
static RETSIGTYPE fault(void);
static void * baseaddr(void);
static void *baseaddr(void);
#endif
char *startdata;
char *enddata;
void
init_rlimits(void)
{
# if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
# if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
get_procm(&mem_ng);
get_sysmem(&mem_t);
# else
startdata = (char *) baseaddr( );
startdata = (char *) baseaddr();
enddata = sbrk(0);
# endif
}
void
init_time(void)
{
@ -107,7 +109,7 @@ init_time(void)
# ifdef HAVE_TIMES
# else
# ifdef HAVE_FTIME
ftime(&timebegin);
ftime(&timebegin);
# endif
# endif
#endif
@ -117,17 +119,17 @@ init_time(void)
void
com_rusage(wordlist *wl)
{
char* copyword;
char *copyword;
/* Fill in the SPICE accounting structure... */
if (wl && (eq(wl->wl_word, "everything") || eq(wl->wl_word, "all"))) {
printres(NULL);
} else if (wl) {
for (; wl; wl = wl->wl_next) {
/* printres(cp_unquote(wl->wl_word)); DG: bad, memory leak*/
copyword=cp_unquote(wl->wl_word);/*DG*/
printres(copyword);
tfree(copyword);
/* printres(cp_unquote(wl->wl_word)); DG: bad, memory leak*/
copyword = cp_unquote(wl->wl_word);/*DG*/
printres(copyword);
tfree(copyword);
if (wl->wl_next)
(void) putc('\n', cp_out);
}
@ -141,6 +143,7 @@ char* copyword;
return;
}
/* Find out if the user is approaching his maximum data size.
If usage is withing 90% of total available then a warning message is sent
to the error stream (cp_err) */
@ -149,11 +152,11 @@ ft_ckspace(void)
{
unsigned long long usage, limit;
#if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
#if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
get_procm(&mem_ng_act);
usage = mem_ng_act.size;
limit = mem_t.free;
#else
limit = mem_t.free;
#else
static size_t old_usage = 0;
char *hi;
@ -167,28 +170,29 @@ ft_ckspace(void)
/* SYSVRLIMIT */
limit = ulimit(3, 0L) - (enddata - startdata);
#endif /* HAVE_GETRLIMIT */
hi=sbrk(0);
hi = sbrk(0);
usage = (size_t) (hi - enddata);
if (usage <= old_usage)
return;
return;
old_usage = usage;
#endif /* not HAS_WINDOWS */
if ((double)usage > (double)limit * 0.9) {
fprintf(cp_err, "Warning - approaching max data size: ");
fprintf(cp_err, "current size = ");
fprintmem(cp_err, usage);
fprintf(cp_err,", limit = ");
fprintmem(cp_err, limit);
fprintf(cp_err,"\n");
fprintf(cp_err, "current size = ");
fprintmem(cp_err, usage);
fprintf(cp_err, ", limit = ");
fprintmem(cp_err, limit);
fprintf(cp_err, "\n");
}
return;
}
/* Print out one piece of resource usage information. */
static void
@ -196,14 +200,14 @@ printres(char *name)
{
#ifdef CIDER
char *paramname = NULL;
#endif
#endif
bool yy = FALSE;
static long lastsec = 0, lastusec = 0;
struct variable *v, *vfree = NULL;
char *cpu_elapsed;
char *cpu_elapsed;
if (!name || eq(name, "totalcputime") || eq(name, "cputime")) {
int total, totalu;
int total, totalu;
#ifdef ipsc
# define NO_RUDATA
@ -214,27 +218,27 @@ printres(char *name)
struct rusage ruse;
memset(&ruse, 0, sizeof(ruse));
ret = getrusage(RUSAGE_SELF, &ruse);
if(ret == -1) {
perror("getrusage(): ");
}
total = ruse.ru_utime.tv_sec + ruse.ru_stime.tv_sec;
totalu = (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec) / 1000;
cpu_elapsed = "CPU";
if (ret == -1)
perror("getrusage(): ");
total = ruse.ru_utime.tv_sec + ruse.ru_stime.tv_sec;
totalu = (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec) / 1000;
cpu_elapsed = "CPU";
# else
# ifdef HAVE_TIMES
struct tms ruse;
realt = times(&ruse);
total = (ruse.tms_utime + ruse.tms_stime)/ HZ;
totalu = (ruse.tms_utime + ruse.tms_utime) * 1000 / HZ;
cpu_elapsed = "CPU";
struct tms ruse;
realt = times(&ruse);
total = (ruse.tms_utime + ruse.tms_stime)/ HZ;
totalu = (ruse.tms_utime + ruse.tms_utime) * 1000 / HZ;
cpu_elapsed = "CPU";
# else
# ifdef HAVE_FTIME
struct timeb timenow;
/* int sec, msec; sjb */
ftime(&timenow);
timediff(&timenow, &timebegin, &total, &totalu);
/* totalu /= 1000; hvogt */
cpu_elapsed = "elapsed";
struct timeb timenow;
/* int sec, msec; sjb */
ftime(&timenow);
timediff(&timenow, &timebegin, &total, &totalu);
/* totalu /= 1000; hvogt */
cpu_elapsed = "elapsed";
# else
# define NO_RUDATA
# endif
@ -244,47 +248,47 @@ printres(char *name)
#ifndef NO_RUDATA
if (!name || eq(name, "totalcputime")) {
total += totalu / 1000;
totalu %= 1000;
fprintf(cp_out, "Total %s time: %u.%03u seconds.\n",
cpu_elapsed, total, totalu);
}
if (!name || eq(name, "totalcputime")) {
total += totalu / 1000;
totalu %= 1000;
fprintf(cp_out, "Total %s time: %u.%03u seconds.\n",
cpu_elapsed, total, totalu);
}
if (!name || eq(name, "cputime")) {
lastusec = totalu - lastusec;
lastsec = total - lastsec;
while (lastusec < 0) {
lastusec += 1000;
lastsec -= 1;
}
while (lastusec > 1000) {
lastusec -= 1000;
lastsec += 1;
}
if (!name || eq(name, "cputime")) {
lastusec = totalu - lastusec;
lastsec = total - lastsec;
while (lastusec < 0) {
lastusec += 1000;
lastsec -= 1;
}
while (lastusec > 1000) {
lastusec -= 1000;
lastsec += 1;
}
#ifndef HAVE_WIN32
fprintf(cp_out, "%s time since last call: %lu.%03lu seconds.\n",
cpu_elapsed, lastsec, lastusec);
fprintf(cp_out, "%s time since last call: %lu.%03lu seconds.\n",
cpu_elapsed, lastsec, lastusec);
#endif
lastsec = total;
lastusec = totalu;
}
lastsec = total;
lastusec = totalu;
}
#ifdef XSPICE
/* gtri - add - 12/12/90 - wbk - record cpu time used for ipc */
/* gtri - add - 12/12/90 - wbk - record cpu time used for ipc */
g_ipc.cpu_time = (double) lastusec;
g_ipc.cpu_time /= 1.0e6;
g_ipc.cpu_time += (double) lastsec;
/* gtri - end - 12/12/90 */
#endif
yy = TRUE;
yy = TRUE;
#else
if (!name || eq(name, "totalcputime"))
fprintf(cp_out, "Total CPU time: ??.??? seconds.\n");
if (!name || eq(name, "cputime"))
fprintf(cp_out, "CPU time since last call: ??.??? seconds.\n");
yy = TRUE;
if (!name || eq(name, "totalcputime"))
fprintf(cp_out, "Total CPU time: ??.??? seconds.\n");
if (!name || eq(name, "cputime"))
fprintf(cp_out, "CPU time since last call: ??.??? seconds.\n");
yy = TRUE;
#endif
}
@ -292,84 +296,84 @@ printres(char *name)
if (!name || eq(name, "space")) {
#ifdef ipsc
size_t usage = 0, limit = 0;
NXINFO cur = nxinfo, start = nxinfo_snap;
size_t usage = 0, limit = 0;
NXINFO cur = nxinfo, start = nxinfo_snap;
usage = cur.dataend - cur.datastart;
limit = start.availmem;
usage = cur.dataend - cur.datastart;
limit = start.availmem;
#else /* ipsc */
# ifdef HAVE_GETRLIMIT
size_t usage = 0, limit = 0;
size_t usage = 0, limit = 0;
struct rlimit rld;
char *hi;
getrlimit(RLIMIT_DATA, &rld);
limit = rld.rlim_cur - (size_t)(enddata - startdata);
limit = rld.rlim_cur - (size_t)(enddata - startdata);
hi = (char*) sbrk(0);
usage = (size_t) (hi - enddata);
usage = (size_t) (hi - enddata);
# else /* HAVE_GETRLIMIT */
# ifdef HAVE_ULIMIT
size_t usage = 0, limit = 0;
size_t usage = 0, limit = 0;
char *hi;
limit = ulimit(3, 0L) - (size_t)(enddata - startdata);
limit = ulimit(3, 0L) - (size_t)(enddata - startdata);
hi = sbrk(0);
usage = (size_t) (hi - enddata);
usage = (size_t) (hi - enddata);
# endif /* HAVE_ULIMIT */
# endif /* HAVE_GETRLIMIT */
#endif /* ipsc */
#if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
get_procm(&mem_ng_act);
get_sysmem(&mem_t_act);
#if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
get_procm(&mem_ng_act);
get_sysmem(&mem_t_act);
/* get_sysmem returns bytes */
fprintf(cp_out, "Total DRAM available = ");
fprintmem(cp_out, mem_t_act.size);
fprintf(cp_out, ".\n");
fprintf(cp_out, "DRAM currently available = ");
fprintmem(cp_out, mem_t_act.free);
fprintf(cp_out, ".\n");
fprintf(cp_out, "Total DRAM available = ");
fprintmem(cp_out, mem_t_act.size);
fprintf(cp_out, ".\n");
fprintf(cp_out, "DRAM currently available = ");
fprintmem(cp_out, mem_t_act.free);
fprintf(cp_out, ".\n");
/* get_procm returns Kilobytes */
fprintf(cp_out, "Total ngspice program size = ");
fprintmem(cp_out, mem_ng_act.size*1024);
fprintf(cp_out, ".\n");
#if defined(HAVE__PROC_MEMINFO)
fprintf(cp_out, "Resident set size = ");
fprintmem(cp_out, mem_ng_act.resident*1024);
fprintf(cp_out, ".\n");
fprintf(cp_out, "Shared ngspice pages = ");
fprintmem(cp_out, mem_ng_act.shared*1024);
fprintf(cp_out, ".\n");
fprintf(cp_out, "Text (code) pages = ");
fprintmem(cp_out, mem_ng_act.trs*1024);
fprintf(cp_out, ".\n");
fprintf(cp_out, "Stack = ");
fprintmem(cp_out, mem_ng_act.drs*1024);
fprintf(cp_out, ".\n");
fprintf(cp_out, "Library pages = ");
fprintmem(cp_out, mem_ng_act.lrs*1024);
fprintf(cp_out, ".\n");
/* not used
fprintf(cp_out, "Dirty pages = ");
fprintmem(cp_out, all_memory.dt * 1024);
fprintf(cp_out, ".\n"); */
#endif /* HAVE__PROC_MEMINFO */
fprintf(cp_out, "Total ngspice program size = ");
fprintmem(cp_out, mem_ng_act.size*1024);
fprintf(cp_out, ".\n");
#if defined(HAVE__PROC_MEMINFO)
fprintf(cp_out, "Resident set size = ");
fprintmem(cp_out, mem_ng_act.resident*1024);
fprintf(cp_out, ".\n");
fprintf(cp_out, "Shared ngspice pages = ");
fprintmem(cp_out, mem_ng_act.shared*1024);
fprintf(cp_out, ".\n");
fprintf(cp_out, "Text (code) pages = ");
fprintmem(cp_out, mem_ng_act.trs*1024);
fprintf(cp_out, ".\n");
fprintf(cp_out, "Stack = ");
fprintmem(cp_out, mem_ng_act.drs*1024);
fprintf(cp_out, ".\n");
fprintf(cp_out, "Library pages = ");
fprintmem(cp_out, mem_ng_act.lrs*1024);
fprintf(cp_out, ".\n");
/* not used
fprintf(cp_out, "Dirty pages = ");
fprintmem(cp_out, all_memory.dt * 1024);
fprintf(cp_out, ".\n"); */
#endif /* HAVE__PROC_MEMINFO */
#else /* HAS_WINDOWS or HAVE__PROC_MEMINFO */
fprintf(cp_out, "Current dynamic memory usage = ");
fprintmem(cp_out, usage);
fprintf(cp_out, ",\n");
fprintf(cp_out, "Dynamic memory limit = ");
fprintmem(cp_out, limit);
fprintf(cp_out, ".\n");
fprintf(cp_out, "Current dynamic memory usage = ");
fprintmem(cp_out, usage);
fprintf(cp_out, ",\n");
fprintf(cp_out, "Dynamic memory limit = ");
fprintmem(cp_out, limit);
fprintf(cp_out, ".\n");
#endif
yy = TRUE;
}
@ -380,24 +384,22 @@ printres(char *name)
struct rusage ruse;
memset(&ruse, 0, sizeof(ruse));
ret = getrusage(RUSAGE_SELF, &ruse);
if(ret == -1) {
perror("getrusage(): ");
}
fprintf(cp_out,
"%lu page faults, %lu vol + %lu invol = %lu context switches.\n",
ruse.ru_majflt, ruse.ru_nvcsw, ruse.ru_nivcsw,
if (ret == -1)
perror("getrusage(): ");
fprintf(cp_out,
"%lu page faults, %lu vol + %lu invol = %lu context switches.\n",
ruse.ru_majflt, ruse.ru_nvcsw, ruse.ru_nivcsw,
ruse.ru_nvcsw + ruse.ru_nivcsw);
yy = TRUE;
#endif
}
}
/* PN Now get all the frontend resource stuff */
if (ft_curckt) {
if (name && eq(name, "task")) {
if (name && eq(name, "task"))
vfree = v = ft_getstat(ft_curckt, NULL);
} else {
else
vfree = v = ft_getstat(ft_curckt, name);
}
if (name && v) {
fprintf(cp_out, "%s= ", v->va_name);
@ -418,29 +420,30 @@ printres(char *name)
}
}
if(vfree)
if (vfree)
free_struct_variable(vfree);
/* Now get all the spice resource stuff. */
if (ft_curckt && ft_curckt->ci_ckt) {
#ifdef CIDER
/* begin cider integration */
if (!name || eq(name, "circuit") || eq(name, "task")) {
paramname = NULL;
} else {
paramname = name;
}
vfree = v = if_getstat(ft_curckt->ci_ckt, paramname);
if (paramname && v) {
/* begin cider integration */
if (!name || eq(name, "circuit") || eq(name, "task"))
paramname = NULL;
else
paramname = name;
vfree = v = if_getstat(ft_curckt->ci_ckt, paramname);
if (paramname && v) {
/* end cider integration */
#else /* ~CIDER */
if (name && eq(name, "task"))
vfree = v = if_getstat(ft_curckt->ci_ckt, NULL);
else
vfree = v = if_getstat(ft_curckt->ci_ckt, name);
if (name && v) {
#endif
#else /* ~CIDER */
if (name && eq(name, "task"))
vfree = v = if_getstat(ft_curckt->ci_ckt, NULL);
else
vfree = v = if_getstat(ft_curckt->ci_ckt, name);
if (name && v) {
#endif
fprintf(cp_out, "%s = ", v->va_name);
wl_print(cp_varwl(v), cp_out);
(void) putc('\n', cp_out);
@ -461,69 +464,70 @@ printres(char *name)
#ifdef CIDER
/* begin cider integration */
/* Now print out interesting stuff about numerical devices. */
if (!name || eq(name, "devices")) {
(void) NDEVacct(ft_curckt->ci_ckt, cp_out);
yy = TRUE;
}
/* end cider integration */
if (!name || eq(name, "devices")) {
(void) NDEVacct(ft_curckt->ci_ckt, cp_out);
yy = TRUE;
}
/* end cider integration */
#endif
}
if (!yy) {
fprintf(cp_err, "Note: no resource usage information for '%s',\n",
name);
fprintf(cp_err, "Note: no resource usage information for '%s',\n", name);
fprintf(cp_err, "\tor no active circuit available\n");
}
if(vfree) free_struct_variable(vfree);
if (vfree)
free_struct_variable(vfree);
return;
}
/* Print to stream the given memory size in a human friendly format */
static void
fprintmem(FILE* stream, unsigned long long memory) {
fprintmem(FILE *stream, unsigned long long memory) {
if (memory > 1048576)
fprintf(stream, "%8.6f MB", (double)memory / 1048576.);
else if (memory > 1024)
fprintf(stream, "%5.3f kB", (double)memory / 1024.);
fprintf(stream, "%8.6f MB", (double)memory / 1048576.);
else if (memory > 1024)
fprintf(stream, "%5.3f kB", (double)memory / 1024.);
else
fprintf(stream, "%llu bytes", memory);
fprintf(stream, "%llu bytes", memory);
}
#if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
#if defined(HAVE_WIN32) || defined(HAVE__PROC_MEMINFO)
static int get_procm(struct proc_mem *memall) {
#if defined (_MSC_VER) || defined(__MINGW32__)
#if defined(_MSC_VER) || defined(__MINGW32__)
#if (_WIN32_WINNT >= 0x0500) && defined(HAS_WINDOWS)
/* Use Windows API function to obtain size of memory - more accurate */
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
DWORD procid = GetCurrentProcessId();
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, procid );
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, procid);
if (NULL == hProcess)
return 0;
/* psapi library required */
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) {
if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
memall->size = pmc.WorkingSetSize/1024;
memall->resident = pmc.QuotaNonPagedPoolUsage/1024;
memall->trs = pmc.QuotaPagedPoolUsage/1024;
}
else {
CloseHandle( hProcess );
} else {
CloseHandle(hProcess);
return 0;
}
CloseHandle( hProcess );
#else
CloseHandle(hProcess);
#else
/* Use Windows GlobalMemoryStatus or /proc/memory to obtain size of memory - not accurate */
get_sysmem(&mem_t_act); /* size is the difference between free memory at start time and now */
if (mem_t.free > mem_t_act.free) /* it can happen that that ngspice is */
memall->size = (mem_t.free - mem_t_act.free)/1024; /* to small compared to os memory usage */
if (mem_t.free > mem_t_act.free) /* it can happen that that ngspice is */
memall->size = (mem_t.free - mem_t_act.free)/1024; /* to small compared to os memory usage */
else
memall->size = 0; /* sure, it is more */
memall->size = 0; /* sure, it is more */
memall->resident = 0;
memall->trs = 0;
#endif /* _WIN32_WINNT 0x0500 && HAS_WINDOWS */
@ -532,97 +536,101 @@ static int get_procm(struct proc_mem *memall) {
FILE *fp;
char buffer[1024], fibuf[100];
size_t bytes_read;
(void) sprintf(fibuf, "/proc/%d/statm", getpid());
if((fp = fopen(fibuf, "r")) == NULL) {
perror("fopen(\"/proc/%d/statm\")");
return 0;
(void) sprintf(fibuf, "/proc/%d/statm", getpid());
if ((fp = fopen(fibuf, "r")) == NULL) {
perror("fopen(\"/proc/%d/statm\")");
return 0;
}
bytes_read = fread (buffer, 1, sizeof (buffer), fp);
fclose (fp);
if (bytes_read == 0 || bytes_read == sizeof (buffer))
return 0;
bytes_read = fread(buffer, 1, sizeof(buffer), fp);
fclose(fp);
if (bytes_read == 0 || bytes_read == sizeof(buffer))
return 0;
buffer[bytes_read] = '\0';
sscanf (buffer, "%llu %llu %llu %llu %llu %llu %llu", &memall->size, &memall->resident, &memall->shared, &memall->trs, &memall->drs, &memall->lrs, &memall->dt);
sscanf(buffer, "%llu %llu %llu %llu %llu %llu %llu", &memall->size, &memall->resident, &memall->shared, &memall->trs, &memall->drs, &memall->lrs, &memall->dt);
#endif
return 1;
return 1;
}
static int get_sysmem(struct sys_mem *memall) {
static int
get_sysmem(struct sys_mem *memall)
{
#ifdef HAVE_WIN32
#if ( _WIN32_WINNT >= 0x0500)
MEMORYSTATUSEX ms;
ms.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx( &ms);
memall->size = ms.ullTotalPhys;
memall->free = ms.ullAvailPhys;
memall->swap_t = ms.ullTotalPageFile;
memall->swap_f = ms.ullAvailPageFile;
#if (_WIN32_WINNT >= 0x0500)
MEMORYSTATUSEX ms;
ms.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&ms);
memall->size = ms.ullTotalPhys;
memall->free = ms.ullAvailPhys;
memall->swap_t = ms.ullTotalPageFile;
memall->swap_f = ms.ullAvailPageFile;
#else
MEMORYSTATUS ms;
ms.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus( &ms);
memall->size = ms.dwTotalPhys;
memall->free = ms.dwAvailPhys;
memall->swap_t = ms.dwTotalPageFile;
memall->swap_f = ms.dwAvailPageFile;
MEMORYSTATUS ms;
ms.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&ms);
memall->size = ms.dwTotalPhys;
memall->free = ms.dwAvailPhys;
memall->swap_t = ms.dwTotalPageFile;
memall->swap_f = ms.dwAvailPageFile;
#endif /*_WIN32_WINNT 0x0500*/
#else
FILE *fp;
char buffer[2048];
size_t bytes_read;
char *match;
unsigned long long mem_got;
FILE *fp;
char buffer[2048];
size_t bytes_read;
char *match;
unsigned long long mem_got;
if((fp = fopen("/proc/meminfo", "r")) == NULL) {
perror("fopen(\"/proc/meminfo\")");
return 0;
}
bytes_read = fread (buffer, 1, sizeof (buffer), fp);
fclose (fp);
if (bytes_read == 0 || bytes_read == sizeof (buffer))
return 0;
buffer[bytes_read] = '\0';
if ((fp = fopen("/proc/meminfo", "r")) == NULL) {
perror("fopen(\"/proc/meminfo\")");
return 0;
}
/* Search for string "MemTotal" */
match = strstr (buffer, "MemTotal");
if (match == NULL) /* not found */
return 0;
sscanf (match, "MemTotal: %llu", &mem_got);
memall->size = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "MemFree" */
match = strstr (buffer, "MemFree");
if (match == NULL) /* not found */
return 0;
sscanf (match, "MemFree: %llu", &mem_got);
memall->free = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "SwapTotal" */
match = strstr (buffer, "SwapTotal");
if (match == NULL) /* not found */
return 0;
sscanf (match, "SwapTotal: %llu", &mem_got);
memall->swap_t = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "SwapFree" */
match = strstr (buffer, "SwapFree");
if (match == NULL) /* not found */
return 0;
sscanf (match, "SwapFree: %llu", &mem_got);
memall->swap_f = mem_got*1024; /* 1MB = 1024KB */
#endif
return 1;
bytes_read = fread(buffer, 1, sizeof(buffer), fp);
fclose(fp);
if (bytes_read == 0 || bytes_read == sizeof(buffer))
return 0;
buffer[bytes_read] = '\0';
/* Search for string "MemTotal" */
match = strstr(buffer, "MemTotal");
if (match == NULL) /* not found */
return 0;
sscanf(match, "MemTotal: %llu", &mem_got);
memall->size = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "MemFree" */
match = strstr(buffer, "MemFree");
if (match == NULL) /* not found */
return 0;
sscanf(match, "MemFree: %llu", &mem_got);
memall->free = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "SwapTotal" */
match = strstr(buffer, "SwapTotal");
if (match == NULL) /* not found */
return 0;
sscanf(match, "SwapTotal: %llu", &mem_got);
memall->swap_t = mem_got*1024; /* 1MB = 1024KB */
/* Search for string "SwapFree" */
match = strstr(buffer, "SwapFree");
if (match == NULL) /* not found */
return 0;
sscanf(match, "SwapFree: %llu", &mem_got);
memall->swap_f = mem_got*1024; /* 1MB = 1024KB */
#endif
return 1;
}
#else
#include <signal.h>
#include <setjmp.h>
/*
* baseaddr( ) returns the base address of the data segment on most Unix
* baseaddr() returns the base address of the data segment on most Unix
* systems. It's an ugly hack for info that should be provided by the OS.
*/
@ -630,17 +638,19 @@ static int get_sysmem(struct sys_mem *memall) {
* too small doesn't hurt
*/
#define LOG2_PAGESIZE 8
#define LOG2_PAGESIZE 8
static JMP_BUF env;
static JMP_BUF env;
static RETSIGTYPE
fault(void)
{
signal(SIGSEGV, (SIGNAL_FUNCTION) fault); /* SysV style */
signal(SIGSEGV, (SIGNAL_FUNCTION) fault); /* SysV style */
LONGJMP(env, 1);
}
static void *
baseaddr(void)
{
@ -649,10 +659,10 @@ baseaddr(void)
#else
char *low, *high, *at;
long x;
RETSIGTYPE (*orig_signal)( );
RETSIGTYPE (*orig_signal)();
if (getenv("SPICE_NO_DATASEG_CHECK"))
return 0;
return 0;
low = 0;
high = (char *) ((unsigned long) sbrk(0) & ~((1 << LOG2_PAGESIZE) - 1));
@ -661,27 +671,28 @@ baseaddr(void)
for (;;) {
at = (char *) ((((long)low >> LOG2_PAGESIZE)
+ ((long)high >> LOG2_PAGESIZE))
<< (LOG2_PAGESIZE - 1));
at = (char *) ((((long)low >> LOG2_PAGESIZE) +
((long)high >> LOG2_PAGESIZE))
<< (LOG2_PAGESIZE - 1));
if (at == low || at == high) {
break;
}
if (at == low || at == high)
break;
if (SETJMP(env, 1)) {
low = at;
continue;
} else
x = *at;
if (SETJMP(env, 1)) {
low = at;
continue;
} else {
x = *at;
}
if (SETJMP(env, 1)) {
low = at;
continue;
} else
*at = x;
if (SETJMP(env, 1)) {
low = at;
continue;
} else {
*at = x;
}
high = at;
high = at;
}
@ -695,12 +706,10 @@ baseaddr(void)
#endif
# ifdef notdef
main( )
main()
{
printf("testing\n");
printf("baseaddr: %#8x topaddr: %#8x\n", baseaddr( ), sbrk(0));
printf("baseaddr: %#8x topaddr: %#8x\n", baseaddr(), sbrk(0));
}
# endif

View File

@ -28,7 +28,7 @@ Modified: 2000 AlansFixes
/* gtri - end - 12/12/90 */
#endif
/* static declarations */
static int dosim(char *what, wordlist *wl);
/* Routines for the commands op, tran, ac, dc, listing, device, state,
@ -59,9 +59,10 @@ com_scirc(wordlist *wl)
fprintf(cp_err, "Error: there aren't any circuits loaded.\n");
return;
}
if (wl == NULL) {
fprintf(cp_out,
"\tType the number of the desired circuit:\n\n");
fprintf(cp_out,
"\tType the number of the desired circuit:\n\n");
for (p = ft_circuits; p; p = p->ci_next) {
if (ft_curckt == p)
fprintf(cp_out, "Current");
@ -76,35 +77,36 @@ com_scirc(wordlist *wl)
for (p = ft_circuits; --i > 0; p = p->ci_next)
;
} else {
for (p = ft_circuits; p; p = p->ci_next)
j++;
for (p = ft_circuits; p; p = p->ci_next)
j++;
p=NULL;
if ((sscanf(wl->wl_word, " %d ", &i) != 1) || (i < 0) || (i > j));
else
for (p = ft_circuits; --i > 0; p = p->ci_next)
;
p = NULL;
if ((sscanf(wl->wl_word, " %d ", &i) != 1) || (i < 0) || (i > j))
;
else
for (p = ft_circuits; --i > 0; p = p->ci_next)
;
/* for (p = ft_circuits; p; p = p->ci_next)
* if (ciprefix(wl->wl_word, p->ci_name))
* break;
*/
if (p == NULL)
{
fprintf(cp_err, "Warning: no such circuit \"%s\"\n",wl->wl_word);
* break;
*/
if (p == NULL) {
fprintf(cp_err, "Warning: no such circuit \"%s\"\n", wl->wl_word);
return;
}
fprintf(cp_out, "\t%s\n", p->ci_name);
}
if (ft_curckt) {
/* Actually this can't be FALSE */
ft_curckt->ci_devices =
cp_kwswitch(CT_DEVNAMES, p->ci_devices);
ft_curckt->ci_devices =
cp_kwswitch(CT_DEVNAMES, p->ci_devices);
ft_curckt->ci_nodes = cp_kwswitch(CT_NODENAMES, p->ci_nodes);
}
ft_curckt = p;
return;
}
void
com_pz(wordlist *wl)
{
@ -112,6 +114,7 @@ com_pz(wordlist *wl)
return;
}
void
com_op(wordlist *wl)
{
@ -119,6 +122,7 @@ com_op(wordlist *wl)
return;
}
void
com_dc(wordlist *wl)
{
@ -126,6 +130,7 @@ com_dc(wordlist *wl)
return;
}
void
com_ac(wordlist *wl)
{
@ -133,6 +138,7 @@ com_ac(wordlist *wl)
return;
}
void
com_tf(wordlist *wl)
{
@ -140,6 +146,7 @@ com_tf(wordlist *wl)
return;
}
void
com_tran(wordlist *wl)
{
@ -147,6 +154,7 @@ com_tran(wordlist *wl)
return;
}
void
com_sens(wordlist *wl)
{
@ -154,6 +162,7 @@ com_sens(wordlist *wl)
return;
}
void
com_disto(wordlist *wl)
{
@ -161,6 +170,7 @@ com_disto(wordlist *wl)
return;
}
void
com_noise(wordlist *wl)
{
@ -168,9 +178,10 @@ com_noise(wordlist *wl)
return;
}
#ifdef WITH_PSS
/* SP: Steady State Analysis */
void
void
com_pss(wordlist *wl)
{
dosim("pss", wl);
@ -179,227 +190,230 @@ com_pss(wordlist *wl)
/* SP */
#endif
static int
dosim(
char *what, /* in: command (pz,op,dc,ac,tf,tran,sens,disto,noise,run) */
wordlist *wl /* in: command option */
/* global variables in: ft_curckt, ft_circuits,
out: ft_setflag, ft_intrpt, rawfileFp, rawfileBinary,
last_used_rawfile
char *what, /* in: command (pz,op,dc,ac,tf,tran,sens,disto,noise,run) */
wordlist *wl /* in: command option */
/* global variables in: ft_curckt, ft_circuits,
out: ft_setflag, ft_intrpt, rawfileFp, rawfileBinary,
last_used_rawfile
*/
)
)
{
wordlist *ww = NULL;
bool dofile = FALSE;
char buf[BSIZE_SP];
struct circ *ct;
int err = 0;
/* set file type to binary or to what is given by environmental
variable SPICE_ASCIIRAWFILE in ivars.c */
bool ascii = AsciiRawFile;
if (eq(what, "run") && wl)
dofile = TRUE;
/* add "what" to beginning of wordlist wl, except "what" equals "run"
and a rawfile name is given (in wl) */
if (!dofile) {
ww = wl_cons(copy(what), wl);
}
/* reset output file type according to variable given in spinit */
if (cp_getvar("filetype", CP_STRING, buf)) {
if (eq(buf, "binary"))
ascii = FALSE;
else if (eq(buf, "ascii"))
ascii = TRUE;
else {
fprintf(cp_err,
"Warning: strange file type \"%s\" (using \"ascii\")\n", buf);
ascii = TRUE;
}
}
wordlist *ww = NULL;
bool dofile = FALSE;
char buf[BSIZE_SP];
struct circ *ct;
int err = 0;
/* set file type to binary or to what is given by environmental
variable SPICE_ASCIIRAWFILE in ivars.c */
bool ascii = AsciiRawFile;
if (eq(what, "run") && wl)
dofile = TRUE;
/* add "what" to beginning of wordlist wl, except "what" equals "run"
and a rawfile name is given (in wl) */
if (!dofile) {
ww = wl_cons(copy(what), wl);
}
/* reset output file type according to variable given in spinit */
if (cp_getvar("filetype", CP_STRING, buf)) {
if (eq(buf, "binary"))
ascii = FALSE;
else if (eq(buf, "ascii"))
ascii = TRUE;
else {
fprintf(cp_err,
"Warning: strange file type \"%s\" (using \"ascii\")\n", buf);
ascii = TRUE;
}
}
if (!ft_curckt) {
fprintf(cp_err, "Error: there aren't any circuits loaded.\n");
return 1;
} else if (ft_curckt->ci_ckt == NULL) { /* Set noparse? */
fprintf(cp_err, "Error: circuit not parsed.\n");
return 1;
}
for (ct = ft_circuits; ct; ct = ct->ci_next)
if (ct->ci_inprogress && (ct != ft_curckt)) {
fprintf(cp_err,
"Warning: losing old state for circuit '%s'\n",
ct->ci_name);
ct->ci_inprogress = FALSE;
}
/* "resume" will never occur in ngspice */
if (ft_curckt->ci_inprogress && eq(what, "resume")) {
ft_setflag = TRUE; /* don't allow abort upon interrupt during run */
ft_intrpt = FALSE;
fprintf(cp_err, "Warning: resuming run in progress.\n");
com_resume(NULL);
ft_setflag = FALSE; /* Now allow aborts again */
return 0;
}
if (!ft_curckt) {
fprintf(cp_err, "Error: there aren't any circuits loaded.\n");
return 1;
} else if (ft_curckt->ci_ckt == NULL) { /* Set noparse? */
fprintf(cp_err, "Error: circuit not parsed.\n");
return 1;
}
for (ct = ft_circuits; ct; ct = ct->ci_next)
if (ct->ci_inprogress && (ct != ft_curckt)) {
fprintf(cp_err,
"Warning: losing old state for circuit '%s'\n",
ct->ci_name);
ct->ci_inprogress = FALSE;
}
/* "resume" will never occur in ngspice */
if (ft_curckt->ci_inprogress && eq(what, "resume")) {
ft_setflag = TRUE; /* don't allow abort upon interrupt during run */
ft_intrpt = FALSE;
fprintf(cp_err, "Warning: resuming run in progress.\n");
com_resume(NULL);
ft_setflag = FALSE; /* Now allow aborts again */
return 0;
}
/* From now on until the next prompt, an interrupt will just
* set a flag and let spice finish up, then control will be
* passed back to the user.
*/
ft_setflag = TRUE; /* Don't allow abort upon interrupt during run. */
ft_intrpt = FALSE;
/* command "run" is given with rawfile name in wl */
if (dofile) {
/* From now on until the next prompt, an interrupt will just
* set a flag and let spice finish up, then control will be
* passed back to the user.
*/
ft_setflag = TRUE; /* Don't allow abort upon interrupt during run. */
ft_intrpt = FALSE;
/* command "run" is given with rawfile name in wl */
if (dofile) {
#ifdef PARALLEL_ARCH
if (ARCHme == 0) {
if (ARCHme == 0) {
#endif /* PARALLEL_ARCH */
if (!*wl->wl_word)
rawfileFp = stdout;
if (!*wl->wl_word)
rawfileFp = stdout;
#if defined(__MINGW32__) || defined(_MSC_VER)
/* ask if binary or ASCII, open file with wb or w */
else if (ascii) {
if((rawfileFp = fopen(wl->wl_word, "w")) == NULL) {
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")) == NULL) {
perror(wl->wl_word);
ft_setflag = FALSE;
return 1;
}
fprintf(cp_out,"binary raw file\n");
}
/* ask if binary or ASCII, open file with wb or w */
else if (ascii) {
if ((rawfileFp = fopen(wl->wl_word, "w")) == NULL) {
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")) == NULL) {
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;
}
#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;
rawfileBinary = !ascii;
#ifdef PARALLEL_ARCH
} else {
rawfileFp = NULL;
}
} else {
rawfileFp = NULL;
}
#endif /* PARALLEL_ARCH */
} else {
rawfileFp = NULL;
}
} else {
rawfileFp = NULL;
}
/*save rawfile name */
if(last_used_rawfile)
tfree(last_used_rawfile);
if(rawfileFp){
last_used_rawfile = copy(wl->wl_word);
} else {
last_used_rawfile = NULL;
}
/*save rawfile name */
if (last_used_rawfile)
tfree(last_used_rawfile);
if (rawfileFp)
last_used_rawfile = copy(wl->wl_word);
else
last_used_rawfile = NULL;
ft_curckt->ci_inprogress = TRUE;
/* "sens2" not used in ngspice */
if (eq(what,"sens2")) {
if (if_sens_run(ft_curckt->ci_ckt, ww, ft_curckt->ci_symtab) == 1) {
/* The circuit was interrupted somewhere. */
fprintf(cp_err, "%s simulation interrupted\n", what);
ft_curckt->ci_inprogress = TRUE;
/* "sens2" not used in ngspice */
if (eq(what, "sens2")) {
if (if_sens_run(ft_curckt->ci_ckt, ww, ft_curckt->ci_symtab) == 1) {
/* The circuit was interrupted somewhere. */
fprintf(cp_err, "%s simulation interrupted\n", what);
#ifdef XSPICE
/* gtri - add - 12/12/90 - wbk - record error and return errchk */
g_ipc.run_error = IPC_TRUE;
if(g_ipc.enabled)
ipc_send_errchk();
/* gtri - end - 12/12/90 */
/* gtri - add - 12/12/90 - wbk - record error and return errchk */
g_ipc.run_error = IPC_TRUE;
if (g_ipc.enabled)
ipc_send_errchk();
/* gtri - end - 12/12/90 */
#endif
} else
ft_curckt->ci_inprogress = FALSE;
/* Do a run of the circuit */
} else {
err = if_run(ft_curckt->ci_ckt, what, ww, ft_curckt->ci_symtab);
if (err == 1) {
/* The circuit was interrupted somewhere. */
fprintf(cp_err, "%s simulation interrupted\n", what);
} else {
ft_curckt->ci_inprogress = FALSE;
}
/* Do a run of the circuit */
} else {
err = if_run(ft_curckt->ci_ckt, what, ww, ft_curckt->ci_symtab);
if (err == 1) {
/* The circuit was interrupted somewhere. */
fprintf(cp_err, "%s simulation interrupted\n", what);
#ifdef XSPICE
/* record error and return errchk */
g_ipc.run_error = IPC_TRUE;
if(g_ipc.enabled)
ipc_send_errchk();
/* gtri - end - 12/12/90 */
/* record error and return errchk */
g_ipc.run_error = IPC_TRUE;
if (g_ipc.enabled)
ipc_send_errchk();
/* gtri - end - 12/12/90 */
#endif
err = 0;
} else if (err == 2) {
fprintf(cp_err, "%s simulation(s) aborted\n", what);
ft_curckt->ci_inprogress = FALSE;
err = 1;
} else
ft_curckt->ci_inprogress = FALSE;
}
/* close the rawfile */
if (rawfileFp){
if (ftell(rawfileFp)==0) {
(void) fclose(rawfileFp);
(void) unlink(wl->wl_word);
} else {
(void) fclose(rawfileFp);
}
}
ft_curckt->ci_runonce = TRUE;
ft_setflag = FALSE;
err = 0;
} else if (err == 2) {
fprintf(cp_err, "%s simulation(s) aborted\n", what);
ft_curckt->ci_inprogress = FALSE;
err = 1;
} else {
ft_curckt->ci_inprogress = FALSE;
}
}
/* close the rawfile */
if (rawfileFp) {
if (ftell(rawfileFp) == 0) {
(void) fclose(rawfileFp);
(void) unlink(wl->wl_word);
} else {
(void) fclose(rawfileFp);
}
}
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);
}
/* 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);
}
/* execute the .measure statements */
if ( !err && ft_curckt->ci_last_an && ft_curckt->ci_meas)
do_measure( ft_curckt->ci_last_an, FALSE );
/* execute the .measure statements */
if (!err && ft_curckt->ci_last_an && ft_curckt->ci_meas)
do_measure(ft_curckt->ci_last_an, FALSE);
return err;
return err;
}
/* Usage is run [filename] */
void
com_run(wordlist *wl)
{
/* ft_getsaves(); */
/* ft_getsaves(); */
dosim("run", wl);
return;
}
int
ft_dorun(char *file)
{
static wordlist wl = { NULL, NULL, NULL } ;
static wordlist wl = { NULL, NULL, NULL };
wl.wl_word = file;
if (file)
return dosim("run", &wl);
else {
else
return dosim("run", NULL);
}
}
/* ARGSUSED */ /* until the else clause gets put back */
bool
ft_getOutReq(FILE **fpp, struct plot **plotp, bool *binp, char *name, char *title)
{
NG_IGNORE(title);
NG_IGNORE(name);
NG_IGNORE(plotp);
NG_IGNORE(title);
NG_IGNORE(name);
NG_IGNORE(plotp);
if (rawfileFp) {
*fpp = rawfileFp;
*binp = rawfileBinary;
return (TRUE);
} else {
return (FALSE);
}
if (rawfileFp) {
*fpp = rawfileFp;
*binp = rawfileBinary;
return (TRUE);
} else {
return (FALSE);
}
}

Some files were not shown because too many files have changed in this diff Show More