alter & altermod reinstated

This commit is contained in:
h_vogt 2009-02-08 14:52:16 +00:00
parent 00563de621
commit 7c667e0fd7
3 changed files with 719 additions and 600 deletions

View File

@ -1,3 +1,7 @@
2009-02-07 Holger Vogt
* device.c, inpcom.c
alter and altermod commands reinstated and improved
2009-02-01 Dietmar Warning
* alloc.c, outitf.c: exclude heap usage for windows compile under __MINGW__
* resource.c: meminfo api usage not for commandline version

View File

@ -874,12 +874,128 @@ com_alter_common(wordlist *wl, int do_model)
struct dvec *dv;
struct pnode *names;
/* DIE 2009_02_06 */
char *argument;
char **arglist;
int i=0, step=0, n, wlen, maxelem=3;
wordlist *wl2, *wlin, *wleq;
bool eqfound = FALSE, vecfound = FALSE;
if (!ft_curckt) {
fprintf(cp_err, "Error: no circuit loaded\n");
return;
}
words = wl;
/*
wordlist 'wl' will be splitted into a wordlist wl2 with three elements,
containing
1) '@dev[param]' string (i.e.: the substring before '=' char);
2) '=' string;
3) 'expression' string.
Spaces around the '=' sign have to be removed. This is provided
by inp_remove_excess_ws().
If the 'altermod' argument is 'altermod m1 vth0=0.7', 'm1' has to be kept as the
element in wl2 before splitting inserts the three new elements.
If 'expression' is a vector (e.g. [ 1.0 1.2 1.4 ] ), its elements
in wl2 have to follow the splitting. wl_splice() will take care of this.
*/
wlin = wl;
while(wl){
argument = wl->wl_word;
/* searching for '=' ... */
while(argument[i]!='=' && argument[i]!='\0'){
i++;
}
/* ...and if found split argument into three chars and make a new wordlist */
if(argument[i]!='\0'){
/* We found '=' */
eqfound = TRUE;
arglist = (char**)tmalloc(4*sizeof(char*));
arglist[3] = NULL;
arglist[0] = (char*)tmalloc(i*sizeof(char) + 1);
arglist[2] = (char*)tmalloc(strlen(&argument[i+1])*sizeof(char) + 1);
/* copy argument */
strncpy(arglist[0],argument,i);
arglist[0][i] = '\0';
/* copy equal sign */
arglist[1] = copy("=");
/* copy expression */
strncpy(arglist[2],&argument[i+1],strlen(&argument[i+1])+1);
/* create a new wordlist from array arglist */
wl2 = wl_build(arglist);
/* combine wordlists into wl2, free wl */
wl_splice(wl, wl2);
wl = NULL;
/* free arglist */
for (n=0; n < 3; n++) tfree(arglist[n]);
tfree(arglist);
} else {
/* deal with 'altermod m1 vth0=0.7' by moving
forward beyond 'm1' */
wl = wl->wl_next;
step++;
}
}
if(eqfound) {
/* step back in the wordlist, if we have moved forward, to catch 'm1' */
for(n=step;n>0;n--) wl2 = wl2->wl_prev;
} else {
/* no equal sign found, probably a pre3f4 input format
'alter device value'
'alter device parameter value'
are supported,
'alter device parameter value parameter value [ parameter value ]'
multiple param value pairs are not supported!
*/
wl2 = wlin;
wlen = wl_length(wlin);
/* Return the last element of wlin */
wlin = wl_nthelem(100, wlin); /* no more than 100 vector elements */
if (eq(wlin->wl_word, "]"))/* we have a vector */ {
for (n=0;n<100;n++) {/* no more than 100 vector elements */
wlin=wlin->wl_prev;
maxelem++;
if (eq(wlin->wl_word, "[")) {
vecfound = TRUE;
break;
}
if(wlin->wl_prev==NULL) {
fprintf(cp_err, "Error: '[' is missing.\n");
fprintf(cp_err, "Cannot alter parameters.\n");
return;
}
}
}
if(wlen > maxelem) {
fprintf(cp_err, "Error: Only a single param - value pair supported.\n");
fprintf(cp_err, "Cannot alter parameters.\n");
return;
}
/* add the '=' */
/* create wordlist with '=' */
wleq = (wordlist*)tmalloc(sizeof(wordlist));
wleq->wl_word = copy("=");
/* add the last element (the value of the param - value pair) */
wleq->wl_next = wlin;
/* move back one element to place equal sign */
wlin = wlin->wl_prev;
/* add ' = value' */
wlin->wl_next = wleq;
/* step back until 'alter' or 'altermod' is found,
then move one step forward */
while (!ciprefix(wlin->wl_word,"alter"))
wlin = wlin->wl_prev;
wlin = wlin->wl_next;
wl2 = wlin;
}
/* Everything is ready, parsing of the wordlist starts here. */
words = wl2;
while (words) {
p = words->wl_word;
eqword = words;
@ -890,6 +1006,7 @@ com_alter_common(wordlist *wl, int do_model)
}
if (!words) {
fprintf(cp_err, "Error: no assignment found.\n");
fprintf(cp_err, "Cannot alter parameters.\n");
return;
}
@ -900,7 +1017,7 @@ com_alter_common(wordlist *wl, int do_model)
dev = NULL;
param = NULL;
words = wl;
words = wl2;
while (words != eqword) {
p = words->wl_word;
if (param) {
@ -925,31 +1042,34 @@ com_alter_common(wordlist *wl, int do_model)
}
if (!dev) {
fprintf(cp_err, "Error: no model or device name provided.\n" );
fprintf(cp_err, "Cannot alter parameters.\n");
return;
}
words = eqword->wl_next;
/* skip next line if words is a vector */
if(!eq(words->wl_word, "["))
names = ft_getpnames(words, FALSE);
else names = NULL;
if (!names) {
/* Put this to try to resolve the case of
* alter vin_sin@[sin] = (10 12 3000)
alter @vin[pulse] = [ 0 5 10n 10n 10n 50n 100n ]
*/
char *xsbuf;
int type = IF_REALVEC,i=0;
double *list;
double tmp;
int error;
/* move beyond '[' to allow INPevaluate() */
if(eq(words->wl_word, "[")) words = words->wl_next;
xsbuf = wl_flatten(words);
/* fprintf(cp_err, "Chain converted %s \n",xsbuf); */
dv=(struct dvec *)MALLOC(sizeof(struct dvec));
dv->v_name = (char *)MALLOC(sizeof("real vector"));
dv->v_name = "real vector";
type &= IF_VARTYPES;
if (type == IF_REALVEC)
{
if (type == IF_REALVEC) {
list = (double *)MALLOC(sizeof(double));
tmp = INPevaluate(&xsbuf,&error,1);
while (error == 0)
@ -1024,4 +1144,3 @@ devexpand(char *name)
wl_sort(wl);
return (wl);
}

View File

@ -1338,9 +1338,9 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name)
working->li_next = tmp_ptr;
working = tmp_ptr2;
//end = working;
//working = working->li_next;
//end->li_next = NULL;
/* end = working;
* working = working->li_next;
* end->li_next = NULL; */
continue;
}
@ -1369,13 +1369,10 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name)
tmp_ptr = library_ll_ptr[i][j]->li_next;
library_ll_ptr[i][j]->li_next = working;
// renumber lines
/* renumber lines */
for ( start_lib = working; !ciprefix(".endl", start_lib->li_line); start_lib = start_lib->li_next )
start_lib->li_linenum = line_number++;
start_lib->li_linenum = line_number++; // renumber endl line
//end->li_next = working;
break;
}
}
@ -1804,7 +1801,6 @@ inp_remove_excess_ws(struct line *deck )
struct line *c = deck;
while ( c != NULL ) {
if ( *c->li_line == '*' ) { c = c->li_next; continue; }
if ( ciprefix( "alter", c->li_line ) ) { c = c->li_next; continue; }
c->li_line = inp_remove_ws(c->li_line);
c = c->li_next;
}