new command 'alterparam', to be used in conjunction with 'mc_source'

add command 'alterparam paramname=pvalue'
  to change a global .param

add command 'alterparam subcktname pname=vpval'
  to change a parameter inside of a subcircuit
This commit is contained in:
h_vogt 2016-07-16 01:09:27 +02:00 committed by Holger Vogt
parent 5c3a6a3829
commit 7dd81327ec
3 changed files with 138 additions and 0 deletions

View File

@ -5,6 +5,7 @@ void com_showmod(wordlist *wl);
void com_show(wordlist *wl);
void com_alter(wordlist *wl);
void com_altermod(wordlist *wl);
void com_alterparam(wordlist *wl);
void com_meas(wordlist *wl);
void com_sysinfo(wordlist *wl);
void com_check_ifparm(wordlist *wl);

View File

@ -373,6 +373,10 @@ struct comm spcp_coms[] = {
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS,
NULL,
"devspecs : parmname value : Alter model parameters." } ,
{ "alterparam", com_alterparam, TRUE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 1, LOTS,
NULL,
"devspecs : parmname value : Alter .param parameters." },
{ "resume", com_resume, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
NULL,

View File

@ -1204,6 +1204,139 @@ com_edit(wordlist *wl)
}
/* alter a parameter, either
subckt param: alterparam subcktname pname=vpval
global .param: alterparam pname=pval
Changes params in mc_deck
To become effective, 'mc_source' has to be called after 'alterparam' */
void
com_alterparam(wordlist *wl)
{
struct card *dd;
char *pname, *pval, *tmp, *subcktname = NULL, *linein, *linefree, *s;
bool found = FALSE;
if (!mc_deck) {
fprintf(cp_err, "Error: No internal deck available\n");
return;
}
linefree = wl_flatten(wl);
linein = skip_ws(linefree);
s = tmp = gettok_char(&linein, '=', FALSE, FALSE);
if (!s) {
fprintf(cp_err, "\nError: Wrong format in line 'alterparam %s'\n command 'alterparam' skipped\n", linefree);
tfree(linefree);
return;
}
linein++; /* skip the '=' */
pval = gettok(&linein);
subcktname = gettok(&tmp);
if (!pval || !subcktname) {
fprintf(cp_err, "\nError: Wrong format in line 'alterparam %s'\n command 'alterparam' skipped\n", linefree);
tfree(pval);
tfree(subcktname);
tfree(linefree);
return;
}
pname = gettok(&tmp);
if (!pname) {
pname = subcktname;
subcktname = NULL;
}
tfree(linefree);
tfree(s);
for (dd = mc_deck->nextcard; dd; dd = dd->nextcard) {
char *curr_line = dd->line;
/* alterparam subcktname pname=vpval
Parameters from within subcircuit are no longer .param lines, but have been added to
the .subckt line as pname=paval and to the x line as pval. pval in the x line takes
precedence when subciruit is called, so has to be replaced here.
Find subcircuit with subcktname.
After params: Count the number of parameters (notok) until parameter pname is found.
When found, search for x-line with subcktname.
Replace parameter value number notok by pval.
*/
if (subcktname) {
/* find subcircuit */
if (ciprefix(".subckt", curr_line)) {
curr_line = nexttok(curr_line); /* skip .subckt */
char *sname = gettok(&curr_line);
if (eq(sname, subcktname)) {
tfree(sname);
curr_line = strstr(curr_line, "params:");
curr_line = skip_non_ws(curr_line); /* skip params: */
/* string to search for */
char *pname_eq = tprintf("%s=", pname);
int notok = 0;
while (*curr_line) {
char *token = gettok(&curr_line);
if (ciprefix(pname_eq, token)) {
tfree(token);
found = TRUE;
break;
}
notok++;
tfree(token);
}
tfree(pname_eq);
if (found) {
/* find x line with same subcircuit name */
struct card *xx;
char *bsubb = tprintf(" %s ", subcktname);
for (xx = mc_deck->nextcard; xx; xx = xx->nextcard) {
char *xline = xx->line;
if (*xline == 'x') {
xline = strstr(xline, bsubb);
if (xline) {
xline = nexttok(xline); /* skip subcktname */
int ii;
for (ii = 0; ii < notok; ii++)
xline = nexttok(xline); /* skip parameter values */
char *beg = copy_substring(xx->line, xline);
xline = nexttok(xline); /* skip parameter value to be replaced */
char *newline = tprintf("%s %s %s", beg, pval, xline);
tfree(xx->line);
xx->line = newline;
tfree(beg);
}
else
continue;
}
}
tfree(bsubb);
}
}
else {
tfree(sname);
continue;
}
}
} /* subcktname */
/* alterparam pname=vpval */
else {
if (ciprefix(".para", curr_line)) {
curr_line = nexttok(curr_line); /* skip .param */
char *name = gettok_char(&curr_line, '=', FALSE, FALSE);
if (eq(name, pname)) {
curr_line = dd->line;
char *start = gettok_char(&curr_line, '=', TRUE, FALSE);
tfree(dd->line);
dd->line = tprintf("%s%s", start, pval);
found = TRUE;
tfree(start);
}
tfree(name);
}
}
}
if (!found)
fprintf(cp_err, "\nError: parameter '%s' not found,\n command 'alterparam' skipped\n", pname);
tfree(pval);
tfree(pname);
tfree(subcktname);
}
static bool
doedit(char *filename)
{