diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 4514ff826..2982a68ce 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -56,6 +56,7 @@ static struct card *mc_deck = NULL; static struct card *recent_deck = NULL; static void cktislinear(CKTcircuit *ckt, struct card *deck); static void dotifeval(struct card *deck); +static void recifeval(struct card *pdeck); static wordlist *inp_savecurrents(struct card *deck, struct card *options, wordlist *wl, wordlist *controls); @@ -1665,47 +1666,42 @@ com_circbyline(wordlist *wl) create_circbyline(newline); } - /* handle .if('expr') ... .elseif('expr') ... .else ... .endif statements. numparam has evaluated .if('boolean expression') to - .if ( 1.000000000e+000 ) or .elseif ( 0.000000000e+000 ) */ + .if ( 1.000000000e+000 ) or .elseif ( 0.000000000e+000 ). + Evaluation is done recursively, starting with .IF, ending with .ENDIF*/ static void -dotifeval(struct card *deck) +recifeval(struct card *pdeck) { + struct card *nd; int iftrue = 0, elseiftrue = 0, elsetrue = 0, iffound = 0, elseiffound = 0, elsefound = 0; - struct card *dd; - char *dottoken; - char *s, *t; - - /* skip the first line (title line) */ - for (dd = deck->nextcard; dd; dd = dd->nextcard) { - - s = t = dd->line; - - if (*s == '*') - continue; - - dottoken = gettok(&t); - /* find '.if' and read its parameter */ - if (cieq(dottoken, ".if")) { - elsefound = 0; - elseiffound = 0; - iffound = 1; - *s = '*'; - s = dd->line + 3; - iftrue = atoi(s); - } - else if (cieq(dottoken, ".elseif")) { + char *t; + char *s = t = pdeck->line; + /* get parameter to .if */ + s = nexttok(s); + elsefound = 0; + elseiffound = 0; + iffound = 1; + *t = '*'; + s = pdeck->line + 3; + iftrue = atoi(s); + nd = pdeck->nextcard; + + while(nd) { + s = nd->line; + if (ciprefix(".if", nd->line)) + recifeval(nd); + else if (ciprefix(".elseif", nd->line)) { elsefound = 0; elseiffound = 1; iffound = 0; *s = '*'; if (!iftrue) { - s = dd->line + 7; + s = pdeck->line + 7; elseiftrue = atoi(s); } } - else if (cieq(dottoken, ".else")) { + else if (ciprefix(".else", nd->line)) { elsefound = 1; elseiffound = 0; iffound = 0; @@ -1713,23 +1709,49 @@ dotifeval(struct card *deck) elsetrue = 1; *s = '*'; } - else if (cieq(dottoken, ".endif")) { + else if (ciprefix(".endif", nd->line)) { elsefound = elseiffound = iffound = 0; elsetrue = elseiftrue = iftrue = 0; *s = '*'; -// inp_subcktexpand(dd); + return; } else { if (iffound && !iftrue) { *s = '*'; } - else if (elseiffound && !elseiftrue) { + else if (elseiffound && !elseiftrue) { *s = '*'; } - else if (elsefound && !elsetrue) { + else if (elsefound && !elsetrue) { *s = '*'; } } + nd = nd->nextcard; + } +} + +/* Scan through all lines of the deck */ +static void +dotifeval(struct card *deck) +{ + struct card *dd; + char *dottoken; + char *s, *t; + + /* skip the first line (title line) */ + for (dd = deck->nextcard; dd; dd = dd->nextcard) { + + s = t = dd->line; + + if (*s == '*') + continue; + + dottoken = gettok(&t); + /* find '.if', the starter of any .if --- .endif clause, and call the recursive evaluation. + recifeval() returns when .endif is found */ + if (cieq(dottoken, ".if")) { + recifeval(dd); + } tfree(dottoken); } }