diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 82ed4cd3b..fd003b026 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -50,6 +50,7 @@ static char *upper(register char *string); static bool doedit(char *filename); static struct line *com_options = NULL; static void cktislinear(CKTcircuit *ckt, struct line *deck); +static void dotifeval(struct line *deck); void line_free_x(struct line *deck, bool recurse); void create_circbyline(char *line); @@ -547,6 +548,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) } } + /* handle .if ... .elseif ... .else ... .endif statements. */ + dotifeval(deck); + /*merge the two option line structs*/ if (!options && com_options) options = com_options; @@ -1202,3 +1206,71 @@ com_circbyline(wordlist *wl) char *newline = wl_flatten(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 ) */ +static void +dotifeval(struct line *deck) +{ + int iftrue = 0, elseiftrue = 0, elsetrue = 0, iffound = 0, elseiffound = 0, elsefound = 0; + struct line *dd; + char *dottoken; + char *s, *t; + + for (dd = deck; dd; dd = dd->li_next) { + + s = t = dd->li_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->li_line + 3; + iftrue = atoi(s); + } + else if (cieq(dottoken, ".elseif")) { + elsefound = 0; + elseiffound = 1; + iffound = 0; + *s = '*'; + if (!iftrue) { + s = dd->li_line + 7; + elseiftrue = atoi(s); + } + } + else if (cieq(dottoken, ".else")) { + elsefound = 1; + elseiffound = 0; + iffound = 0; + if (!iftrue && !elseiftrue) + elsetrue = 1; + *s = '*'; + } + else if (cieq(dottoken, ".endif")) { + elsefound = elseiffound = iffound = 0; + elsetrue = elseiftrue = iftrue = 0; + *s = '*'; +// inp_subcktexpand(dd); + } + else { + if (iffound && !iftrue) { + *s = '*'; + } + else if (elseiffound && !elseiftrue) { + *s = '*'; + } + else if (elsefound && !elsetrue) { + *s = '*'; + } + } + tfree(dottoken); + } +} diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 2f575df94..a363f9bf7 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -96,6 +96,7 @@ static void inp_sort_params(struct line *start_card, struct line *end_card, stru static char *inp_remove_ws(char *s); static void inp_compat(struct line *deck); static void inp_bsource_compat(struct line *deck); +static void inp_dot_if(struct line *deck); static bool chk_for_line_continuation(char *line); static void comment_out_unused_subckt_models(struct line *start_card, int no_of_lines); @@ -736,7 +737,7 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile inp_fix_macro_param_func_paren_io(working); inp_fix_ternary_operator(working); -//tprint(working); + inp_expand_macros_in_deck(NULL, working); inp_fix_param_values(working); @@ -744,8 +745,9 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile be correct at this point */ for (newcard = working; newcard; newcard = newcard->li_next) end = newcard; - +// tprint(cc); inp_reorder_params(subckt_w_params, working, cc, end); + inp_fix_inst_calls_for_numparam(subckt_w_params, working); delete_names(subckt_w_params); @@ -767,6 +769,7 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile working = cc->li_next; /* B source numparam compatibility transformation */ inp_bsource_compat(working); + inp_dot_if(working); } inp_add_series_resistor(working); @@ -5710,3 +5713,29 @@ tprint(struct line *t) fprintf(fd, "%d %d %s\n", t->li_linenum_orig, t->li_linenum, t->li_line); fclose(fd); } + + +/* prepare .if and .elseif for numparam + .if(expression) --> .if{expression} */ +static void +inp_dot_if(struct line *deck) +{ + struct line *card; + + for (card = deck; card; card = card->li_next) { + char *curr_line = card->li_line; + if (*curr_line == '*') + continue; + if (ciprefix(".if", curr_line) || ciprefix(".elseif", curr_line)) { + char *firstbr = strchr(curr_line, '('); + char *lastbr = strrchr(curr_line, ')'); + if ((!firstbr) || (!lastbr)) { + fprintf(cp_err, "Error in netlist line %d\n", card->li_linenum_orig); + fprintf(cp_err, " Bad syntax: %s\n\n", curr_line); + controlled_exit(EXIT_BAD); + } + *firstbr = '{'; + *lastbr = '}'; + } + } +}