|
|
|
@ -56,7 +56,7 @@ static void dotifeval(struct line *deck); |
|
|
|
static int inp_parse_temper(struct line *deck); |
|
|
|
static void inp_parse_temper_trees(void); |
|
|
|
|
|
|
|
static void inp_savecurrents(struct line *deck, struct line *options, wordlist **wl, wordlist *con); |
|
|
|
static wordlist *inp_savecurrents(struct line *deck, struct line *options, wordlist *wl, wordlist *controls); |
|
|
|
|
|
|
|
void line_free_x(struct line *deck, bool recurse); |
|
|
|
void create_circbyline(char *line); |
|
|
|
@ -601,7 +601,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) |
|
|
|
|
|
|
|
/* If user wants all currents saved (.options savecurrents), add .save |
|
|
|
to wl_first with all terminal currents available on selected devices */ |
|
|
|
inp_savecurrents(deck, options, &wl_first, controls); |
|
|
|
wl_first = inp_savecurrents(deck, options, wl_first, controls); |
|
|
|
|
|
|
|
/* now load deck into ft_curckt -- the current circuit. */ |
|
|
|
inp_dodeck(deck, tt, wl_first, FALSE, options, filename); |
|
|
|
@ -1572,122 +1572,98 @@ inp_evaluate_temper(void) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Enable current measurements by the user. Check, if option savecurrents |
|
|
|
is set by the user. We have to do it here prematurely, because options |
|
|
|
will be processed later. |
|
|
|
Then check, if commands 'save' or '.save' are alraedy there. If not, add |
|
|
|
'.save all'. |
|
|
|
Then the deck is scanned for known devices, and their current vectors in form of |
|
|
|
@q1[ib] are added to new .save lines in wl_first. */ |
|
|
|
static void inp_savecurrents(struct line *deck, struct line *options, wordlist **wl, wordlist *con) |
|
|
|
/* |
|
|
|
* Enable current measurements by the user |
|
|
|
* if 'option savecurrents' is set by the user. |
|
|
|
* We have to check for this option here prematurely |
|
|
|
* because options will be processed later. |
|
|
|
* Then append a |
|
|
|
* .save all |
|
|
|
* statement to 'wl' if no other 'save' has been given so far. |
|
|
|
* Then scan the deck for known devices and append |
|
|
|
* .save @q1[ib] |
|
|
|
* statements to 'wl' for all of their current vectors. |
|
|
|
*/ |
|
|
|
|
|
|
|
static wordlist * |
|
|
|
inp_savecurrents(struct line *deck, struct line *options, wordlist *wl, wordlist *controls) |
|
|
|
{ |
|
|
|
struct line *tmp_deck, *tmp_line; |
|
|
|
char beg; |
|
|
|
char *devname = NULL, *devline, *newline; |
|
|
|
bool goon = FALSE, havesave = FALSE; |
|
|
|
wordlist *tmpword; |
|
|
|
wordlist *p; |
|
|
|
|
|
|
|
/* check if option 'savecurrents' is set */ |
|
|
|
for (tmp_line = options; tmp_line; tmp_line = tmp_line->li_next) |
|
|
|
if (strstr(tmp_line->li_line, "savecurrents")) { |
|
|
|
goon = TRUE; |
|
|
|
for (; options; options = options->li_next) |
|
|
|
if (strstr(options->li_line, "savecurrents")) |
|
|
|
break; |
|
|
|
} |
|
|
|
if (!goon) |
|
|
|
return; |
|
|
|
/* check if we have a 'save' command in the .control section */ |
|
|
|
for (tmpword = con; tmpword; tmpword = tmpword->wl_next) |
|
|
|
if(prefix("save", tmpword->wl_word)) { |
|
|
|
havesave = TRUE; |
|
|
|
|
|
|
|
if (!options) |
|
|
|
return wl; |
|
|
|
|
|
|
|
/* search for 'save' command in the .control section */ |
|
|
|
for (p = controls; p; p = p->wl_next) |
|
|
|
if(prefix("save", p->wl_word)) |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
/* check if wl_first is already there */ |
|
|
|
if (*wl) { |
|
|
|
/* check if .save is already in wl_first */ |
|
|
|
for (tmpword = *wl; tmpword; tmpword = tmpword->wl_next) |
|
|
|
if(prefix(".save", tmpword->wl_word)) { |
|
|
|
havesave = TRUE; |
|
|
|
/* search for '.save' in the 'wl' list */ |
|
|
|
if (!p) |
|
|
|
for (p = wl; p; p = p->wl_next) |
|
|
|
if(prefix(".save", p->wl_word)) |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* if we neither have 'save' nor '.save', add '.save all' |
|
|
|
or if we do not have wl_first, add at least a wordline '*' to allow wl_append_word() */ |
|
|
|
if (!(*wl) || !havesave) { |
|
|
|
*wl = TMALLOC(wordlist, 1); |
|
|
|
(*wl)->wl_next = NULL; |
|
|
|
(*wl)->wl_prev = NULL; |
|
|
|
if (havesave) |
|
|
|
(*wl)->wl_word = copy("*"); |
|
|
|
else |
|
|
|
(*wl)->wl_word = copy(".save all"); |
|
|
|
} |
|
|
|
/* if not found, then add '.save all' */ |
|
|
|
if (!p) |
|
|
|
p = wl_cons(copy(".save all"), NULL); |
|
|
|
else |
|
|
|
p = NULL; |
|
|
|
|
|
|
|
/* Scan the deck for devices with their terminals. |
|
|
|
We currently serve bipolars, resistors, MOS1, capacitors, inductors, |
|
|
|
controlled current sources. Others may follow. */ |
|
|
|
for (tmp_deck = deck->li_next; tmp_deck; tmp_deck = tmp_deck->li_next){ |
|
|
|
beg = *(tmp_deck->li_line); |
|
|
|
if ((beg == '*') || (beg == '.')) |
|
|
|
continue; |
|
|
|
switch (beg) { |
|
|
|
case 'm': |
|
|
|
devline = tmp_deck->li_line; |
|
|
|
devname = gettok(&devline); |
|
|
|
/* .save @q1[id] @q1[is] @q1[ig] @q1[ib] */ |
|
|
|
newline = tprintf(".save @%s[id] @%s[is] @%s[ig] @%s[ib]", |
|
|
|
devname, devname, devname, devname); |
|
|
|
wl_append_word(NULL, wl, newline); |
|
|
|
break; |
|
|
|
case 'j': |
|
|
|
devline = tmp_deck->li_line; |
|
|
|
devname = gettok(&devline); |
|
|
|
/* .save @q1[id] @q1[is] @q1[ig] @q1[igd] */ |
|
|
|
newline = tprintf(".save @%s[id] @%s[is] @%s[ig] @%s[igd]", |
|
|
|
devname, devname, devname, devname); |
|
|
|
wl_append_word(NULL, wl, newline); |
|
|
|
break; |
|
|
|
case 'q': |
|
|
|
devline = tmp_deck->li_line; |
|
|
|
devname = gettok(&devline); |
|
|
|
/* .save @q1[ic] @q1[ie] @q1[ib] @q1[is] */ |
|
|
|
newline = tprintf(".save @%s[ic] @%s[ie] @%s[ib] @%s[is]", |
|
|
|
devname, devname, devname, devname); |
|
|
|
wl_append_word(NULL, wl, newline); |
|
|
|
break; |
|
|
|
case 'd': |
|
|
|
devline = tmp_deck->li_line; |
|
|
|
devname = gettok(&devline); |
|
|
|
/* .save @d1[id] */ |
|
|
|
newline = tprintf(".save @%s[id]", devname); |
|
|
|
wl_append_word(NULL, wl, newline); |
|
|
|
break; |
|
|
|
case 'r': |
|
|
|
case 'c': |
|
|
|
case 'l': |
|
|
|
case 'b': |
|
|
|
case 'f': |
|
|
|
case 'g': |
|
|
|
case 'w': |
|
|
|
case 's': |
|
|
|
devline = tmp_deck->li_line; |
|
|
|
devname = gettok(&devline); |
|
|
|
/* .save @r1[i] */ |
|
|
|
newline = tprintf(".save @%s[i]", devname); |
|
|
|
wl_append_word(NULL, wl, newline); |
|
|
|
break; |
|
|
|
case 'i': |
|
|
|
devline = tmp_deck->li_line; |
|
|
|
devname = gettok(&devline); |
|
|
|
/* .save @i1[current] */ |
|
|
|
newline = tprintf(".save @%s[current]", devname); |
|
|
|
wl_append_word(NULL, wl, newline); |
|
|
|
break; |
|
|
|
default: |
|
|
|
; |
|
|
|
} |
|
|
|
tfree(devname); |
|
|
|
* We currently serve bipolars, resistors, MOS1, capacitors, inductors, |
|
|
|
* controlled current sources. Others may follow. |
|
|
|
*/ |
|
|
|
for (deck = deck->li_next; deck; deck = deck->li_next) { |
|
|
|
char *newline, *devname, *devline = deck->li_line; |
|
|
|
|
|
|
|
switch (devline[0]) { |
|
|
|
case 'm': |
|
|
|
devname = gettok(&devline); |
|
|
|
newline = tprintf(".save @%s[id] @%s[is] @%s[ig] @%s[ib]", |
|
|
|
devname, devname, devname, devname); |
|
|
|
break; |
|
|
|
case 'j': |
|
|
|
devname = gettok(&devline); |
|
|
|
newline = tprintf(".save @%s[id] @%s[is] @%s[ig] @%s[igd]", |
|
|
|
devname, devname, devname, devname); |
|
|
|
break; |
|
|
|
case 'q': |
|
|
|
devname = gettok(&devline); |
|
|
|
newline = tprintf(".save @%s[ic] @%s[ie] @%s[ib] @%s[is]", |
|
|
|
devname, devname, devname, devname); |
|
|
|
break; |
|
|
|
case 'd': |
|
|
|
devname = gettok(&devline); |
|
|
|
newline = tprintf(".save @%s[id]", devname); |
|
|
|
break; |
|
|
|
case 'r': |
|
|
|
case 'c': |
|
|
|
case 'l': |
|
|
|
case 'b': |
|
|
|
case 'f': |
|
|
|
case 'g': |
|
|
|
case 'w': |
|
|
|
case 's': |
|
|
|
devname = gettok(&devline); |
|
|
|
newline = tprintf(".save @%s[i]", devname); |
|
|
|
break; |
|
|
|
case 'i': |
|
|
|
devname = gettok(&devline); |
|
|
|
newline = tprintf(".save @%s[current]", devname); |
|
|
|
break; |
|
|
|
default: |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
p = wl_cons(newline, p); |
|
|
|
tfree(devname); |
|
|
|
} |
|
|
|
while((*wl)->wl_prev) |
|
|
|
(*wl) = (*wl)->wl_prev; |
|
|
|
|
|
|
|
return wl_append(wl, wl_reverse(p)); |
|
|
|
} |