inpcom.c: agauss in MC with prof. libraries, first part: replace all .param lines with agauss by .func make recursive .param -> .func if agauss is involved
This commit is contained in:
parent
d99252c915
commit
7292dc000e
|
|
@ -141,6 +141,7 @@ static void replace_token(char *string, char *token, int where, int total);
|
|||
static void inp_add_series_resistor(struct line *deck);
|
||||
static void subckt_params_to_param(struct line *deck);
|
||||
static void inp_fix_temper_in_param(struct line *deck);
|
||||
static void inp_fix_agauss_in_param(struct line *deck);
|
||||
|
||||
static char *inp_spawn_brace(char *s);
|
||||
|
||||
|
|
@ -517,6 +518,8 @@ inp_readall(FILE *fp, char *dir_name, bool comfile, bool intfile)
|
|||
rv . line_number = inp_split_multi_param_lines(working, rv . line_number);
|
||||
|
||||
inp_fix_macro_param_func_paren_io(working);
|
||||
inp_fix_agauss_in_param(working);
|
||||
|
||||
inp_fix_temper_in_param(working);
|
||||
|
||||
inp_expand_macros_in_deck(NULL, working);
|
||||
|
|
@ -6114,6 +6117,226 @@ inp_fix_temper_in_param(struct line *deck)
|
|||
}
|
||||
|
||||
|
||||
/* Convert .param lines containing function 'agauss' into .func lines:
|
||||
* .param xxx1 = 'agauss()' ---> .func xxx1() 'agauss()'
|
||||
* Add info about the functions (name, subcircuit depth, number of
|
||||
* subckt) to linked list new_func.
|
||||
* Then scan new_func, for each xxx1 scan all lines of deck,
|
||||
* find all xxx1 and convert them to a function:
|
||||
* xxx1 ---> xxx1()
|
||||
* If this happens to be in another .param line, convert it to .func,
|
||||
* add info to end of new_func and continue scanning.
|
||||
*
|
||||
* In a second step, after subcircuits have been expanded, all occurencies
|
||||
* of agauss in a b-line are replaced by their suitable value (function
|
||||
* eval_agauss_bsource() in inp.c).
|
||||
*/
|
||||
|
||||
static void
|
||||
inp_fix_agauss_in_param(struct line *deck)
|
||||
{
|
||||
int skip_control = 0, subckt_depth = 0, j, *sub_count;
|
||||
char *funcbody, *funcname;
|
||||
struct func_temper *f, *funcs = NULL, **funcs_tail_ptr = &funcs;
|
||||
struct line *card;
|
||||
|
||||
sub_count = TMALLOC(int, 16);
|
||||
for (j = 0; j < 16; j++)
|
||||
sub_count[j] = 0;
|
||||
|
||||
/* first pass:
|
||||
* determine all .param with agauss inside and replace by .func
|
||||
* convert
|
||||
* .param xxx1 = 'agauss(x,y,z) * 25'
|
||||
* to
|
||||
* .func xxx1() 'agauss(x,y,z) * 25'
|
||||
*/
|
||||
card = deck;
|
||||
for (; card; card = card->li_next) {
|
||||
|
||||
char *curr_line = card->li_line;
|
||||
|
||||
if (*curr_line == '*')
|
||||
continue;
|
||||
|
||||
/* determine nested depths of subcircuits */
|
||||
if (ciprefix(".subckt", curr_line)) {
|
||||
subckt_depth++;
|
||||
sub_count[subckt_depth]++;
|
||||
continue;
|
||||
}
|
||||
else if (ciprefix(".ends", curr_line)) {
|
||||
subckt_depth--;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* exclude any command inside .control ... .endc */
|
||||
if (ciprefix(".control", curr_line)) {
|
||||
skip_control++;
|
||||
continue;
|
||||
}
|
||||
else if (ciprefix(".endc", curr_line)) {
|
||||
skip_control--;
|
||||
continue;
|
||||
}
|
||||
else if (skip_control > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ciprefix(".param", curr_line)) {
|
||||
|
||||
char *p, *temper, *equal_ptr, *lhs_b, *lhs_e;
|
||||
|
||||
temper = search_identifier(curr_line, "agauss", curr_line);
|
||||
|
||||
if (!temper)
|
||||
continue;
|
||||
|
||||
equal_ptr = find_assignment(curr_line);
|
||||
|
||||
if (!equal_ptr) {
|
||||
fprintf(stderr, "ERROR: could not find '=' on parameter line '%s'!\n", curr_line);
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* .param lines with `,' separated multiple parameters
|
||||
* must have been split in inp_split_multi_param_lines()
|
||||
*/
|
||||
|
||||
if (find_assignment(equal_ptr + 1)) {
|
||||
fprintf(stderr, "ERROR: internal error on line '%s'!\n", curr_line);
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
lhs_b = skip_non_ws(curr_line); // eat .param
|
||||
lhs_b = skip_ws(lhs_b);
|
||||
|
||||
lhs_e = skip_back_ws(equal_ptr, curr_line);
|
||||
|
||||
/* skip if this is a function already */
|
||||
p = strpbrk(lhs_b, "(,)");
|
||||
if (p && p < lhs_e)
|
||||
continue;
|
||||
|
||||
if (temper < equal_ptr) {
|
||||
fprintf(stderr,
|
||||
"Error: you cannot assign a value to TEMPER\n"
|
||||
" Line no. %d, %s\n",
|
||||
card->li_linenum, curr_line);
|
||||
controlled_exit(EXIT_BAD);
|
||||
}
|
||||
|
||||
funcname = copy_substring(lhs_b, lhs_e);
|
||||
funcbody = copy(equal_ptr + 1);
|
||||
|
||||
*funcs_tail_ptr =
|
||||
inp_new_func(funcname, funcbody, card, sub_count, subckt_depth);
|
||||
funcs_tail_ptr = &(*funcs_tail_ptr)->next;
|
||||
|
||||
tfree(funcbody);
|
||||
}
|
||||
}
|
||||
|
||||
/* second pass:
|
||||
* for each .func entry in `funcs' start the insertion operation:
|
||||
* search each line from the deck which has the suitable
|
||||
* subcircuit nesting data.
|
||||
* for tokens xxx equalling the funcname, replace xxx by xxx().
|
||||
*/
|
||||
|
||||
for (f = funcs; f; f = f->next) {
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
sub_count[j] = 0;
|
||||
|
||||
card = deck;
|
||||
for (; card; card = card->li_next) {
|
||||
|
||||
char *new_str = NULL; /* string we assemble here */
|
||||
char *curr_line = card->li_line;
|
||||
char *firsttok_str;
|
||||
|
||||
if (*curr_line == '*')
|
||||
continue;
|
||||
|
||||
/* determine nested depths of subcircuits */
|
||||
if (ciprefix(".subckt", curr_line)) {
|
||||
subckt_depth++;
|
||||
sub_count[subckt_depth]++;
|
||||
continue;
|
||||
}
|
||||
else if (ciprefix(".ends", curr_line)) {
|
||||
subckt_depth--;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* exclude any command inside .control ... .endc */
|
||||
if (ciprefix(".control", curr_line)) {
|
||||
skip_control++;
|
||||
continue;
|
||||
}
|
||||
else if (ciprefix(".endc", curr_line)) {
|
||||
skip_control--;
|
||||
continue;
|
||||
}
|
||||
else if (skip_control > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if function is not at top level,
|
||||
exclude lines which do not have the same subcircuit
|
||||
nesting depth and number as found in f */
|
||||
if (f->subckt_depth > 0) {
|
||||
if (subckt_depth != f->subckt_depth)
|
||||
continue;
|
||||
if (sub_count[subckt_depth] != f->subckt_count)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* remove first token, ignore it here, restore it later */
|
||||
firsttok_str = gettok(&curr_line);
|
||||
if (*curr_line == '\0') {
|
||||
tfree(firsttok_str);
|
||||
continue;
|
||||
}
|
||||
|
||||
new_str = inp_functionalise_identifier(curr_line, f->funcname);
|
||||
|
||||
if (new_str == curr_line) {
|
||||
tfree(firsttok_str);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* restore first part of the line */
|
||||
new_str = INPstrCat(firsttok_str, new_str, " ");
|
||||
new_str = inp_remove_ws(new_str);
|
||||
|
||||
/* if we have inserted into a .param line, convert to .func */
|
||||
if (prefix(".param", new_str)) {
|
||||
char *new_tmp_str = new_str;
|
||||
txfree(gettok(&new_tmp_str));
|
||||
funcname = gettok_char(&new_tmp_str, '=', FALSE, FALSE);
|
||||
funcbody = copy(new_tmp_str + 1);
|
||||
*funcs_tail_ptr =
|
||||
inp_new_func(funcname, funcbody, card, sub_count, subckt_depth);
|
||||
funcs_tail_ptr = &(*funcs_tail_ptr)->next;
|
||||
tfree(new_str);
|
||||
tfree(funcbody);
|
||||
}
|
||||
else {
|
||||
/* Or just enter new line into deck */
|
||||
card->li_next = xx_new_line(card->li_next, new_str, 0, card->li_linenum);
|
||||
*card->li_line = '*';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* final memory clearance */
|
||||
tfree(sub_count);
|
||||
inp_delete_funcs(funcs);
|
||||
}
|
||||
|
||||
|
||||
/* append "()" to each 'identifier' in 'curr_line',
|
||||
* unless already there */
|
||||
static char *
|
||||
|
|
@ -6158,6 +6381,12 @@ inp_new_func(char *funcname, char *funcbody, struct line *card,
|
|||
|
||||
/* replace line in deck */
|
||||
new_str = tprintf(".func %s() %s", funcname, funcbody);
|
||||
#if 0
|
||||
if (*funcbody == '{')
|
||||
new_str = tprintf(".func %s() %s", funcname, funcbody);
|
||||
else
|
||||
new_str = tprintf(".func %s() {%s}", funcname, funcbody);
|
||||
#endif
|
||||
card->li_next = xx_new_line(card->li_next, new_str, 0, card->li_linenum);
|
||||
*card->li_line = '*';
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue