src/frontend/**, whitespace, indentation, ...
untabify delete-trailing-whitespace braces ... checked for object file invariance on linux
This commit is contained in:
parent
f3b5336d3a
commit
7454a6d486
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,14 +7,9 @@
|
|||
#define CIRCUITS_H_INCLUDED
|
||||
|
||||
|
||||
|
||||
struct subcirc {
|
||||
char *sc_name; /* Whatever... */
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
char *sc_name; /* Whatever... */
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
} ;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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...
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ char ErrorMessage[1024];
|
|||
|
||||
|
||||
#ifdef HAS_WINDOWS
|
||||
void winmessage(char* new_msg);
|
||||
void winmessage(char *new_msg);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -7,5 +7,4 @@
|
|||
#define BACKQ_H_INCLUDED
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,5 +7,4 @@
|
|||
#define GLOB_H_INCLUDED
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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') {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,4 @@
|
|||
#define NUMPARSE_H_INCLUDED
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -7,7 +7,4 @@
|
|||
#define UNIXCOM_H_INCLUDED
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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, °ree))
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue