inp.c, inpcom.c: implement a very basic .if/.else block

This commit is contained in:
h_vogt 2013-06-01 19:06:17 +02:00 committed by rlar
parent 91ab0a3c74
commit 05a6ec222e
2 changed files with 103 additions and 2 deletions

View File

@ -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);
}
}

View File

@ -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 = '}';
}
}
}