patch by Bill Swartz
This commit is contained in:
parent
eef75ffab5
commit
2e323531fb
|
|
@ -1,5 +1,6 @@
|
|||
2009-04-14 Holger Vogt
|
||||
* control.c: remove bug no. 2724127 repeat loop inside another loop
|
||||
* control.c: remove bug no. 2724127 repeat loop inside another loop
|
||||
* dotcards.c, inp.c, measure.c: patch submitted by Bill Swartz added
|
||||
|
||||
2009-04-12 Holger Vogt
|
||||
* spicenum.c, xpressn.c: dico and inst_dico no longer removed in nupa_done
|
||||
|
|
|
|||
|
|
@ -83,71 +83,78 @@ static char *plot_opts[ ] = {
|
|||
int
|
||||
ft_savedotargs(void)
|
||||
{
|
||||
wordlist *w, *wl = NULL, *iline, **prev_wl, *w_next;
|
||||
char *name;
|
||||
char *s;
|
||||
int some = 0;
|
||||
static wordlist all = { "all", NULL };
|
||||
int isaplot;
|
||||
int i;
|
||||
wordlist *w, *wl = NULL, *iline, **prev_wl, *w_next;
|
||||
char *name;
|
||||
char *s;
|
||||
int some = 0;
|
||||
static wordlist all = { "all", NULL };
|
||||
int isaplot;
|
||||
int i;
|
||||
|
||||
if (!ft_curckt) /* Shouldn't happen. */
|
||||
return 0;
|
||||
if (!ft_curckt) /* Shouldn't happen. */
|
||||
return 0;
|
||||
|
||||
for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next) {
|
||||
s = iline->wl_word;
|
||||
if (ciprefix(".plot", s))
|
||||
isaplot = 1;
|
||||
else
|
||||
isaplot = 0;
|
||||
for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next) {
|
||||
s = iline->wl_word;
|
||||
if (ciprefix(".plot", s))
|
||||
isaplot = 1;
|
||||
else
|
||||
isaplot = 0;
|
||||
|
||||
if (isaplot || ciprefix(".print", s)) {
|
||||
(void) gettok(&s);
|
||||
name = gettok(&s);
|
||||
if (isaplot || ciprefix(".print", s)) {
|
||||
(void) gettok(&s);
|
||||
name = gettok(&s);
|
||||
|
||||
if (!(w = gettoks(s))) {
|
||||
fprintf(cp_err, "Warning: no nodes given: %s\n",
|
||||
iline->wl_word);
|
||||
} else {
|
||||
if (isaplot) {
|
||||
prev_wl = &w;
|
||||
for (wl = w; wl; wl = w_next) {
|
||||
w_next = wl->wl_next;
|
||||
for (i = 0; i < NUMELEMS(plot_opts); i++) {
|
||||
if (!strcmp(wl->wl_word, plot_opts[i])) {
|
||||
/* skip it */
|
||||
*prev_wl = w_next;
|
||||
tfree(wl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == NUMELEMS(plot_opts))
|
||||
prev_wl = &wl->wl_next;
|
||||
}
|
||||
}
|
||||
some = 1;
|
||||
com_save2(w, name);
|
||||
}
|
||||
} else if (ciprefix(".four", s)) {
|
||||
(void) gettok(&s);
|
||||
(void) gettok(&s);
|
||||
if (!(w = gettoks(s)))
|
||||
fprintf(cp_err, "Warning: no nodes given: %s\n",
|
||||
iline->wl_word);
|
||||
else {
|
||||
some = 1;
|
||||
com_save2(w, "TRAN"); /* A hack */
|
||||
}
|
||||
} else if (ciprefix(".op", s)) {
|
||||
some = 1;
|
||||
com_save2(&all, "OP");
|
||||
} else if (ciprefix(".tf", s)) {
|
||||
some = 1;
|
||||
com_save2(&all, "TF");
|
||||
}
|
||||
}
|
||||
|
||||
return some;
|
||||
if (!(w = gettoks(s))) {
|
||||
fprintf(cp_err, "Warning: no nodes given: %s\n", iline->wl_word);
|
||||
} else {
|
||||
if (isaplot) {
|
||||
prev_wl = &w;
|
||||
for (wl = w; wl; wl = w_next) {
|
||||
w_next = wl->wl_next;
|
||||
for (i = 0; i < NUMELEMS(plot_opts); i++) {
|
||||
if (!strcmp(wl->wl_word, plot_opts[i])) {
|
||||
/* skip it */
|
||||
*prev_wl = w_next;
|
||||
tfree(wl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == NUMELEMS(plot_opts))
|
||||
prev_wl = &wl->wl_next;
|
||||
}
|
||||
}
|
||||
some = 1;
|
||||
com_save2(w, name);
|
||||
}
|
||||
} else if (ciprefix(".four", s)) {
|
||||
(void) gettok(&s);
|
||||
(void) gettok(&s);
|
||||
if (!(w = gettoks(s)))
|
||||
fprintf(cp_err, "Warning: no nodes given: %s\n", iline->wl_word);
|
||||
else {
|
||||
some = 1;
|
||||
com_save2(w, "TRAN"); /* A hack */
|
||||
}
|
||||
} else if (ciprefix(".measure", s)) {
|
||||
(void) gettok(&s);
|
||||
name = gettok(&s);
|
||||
(void) gettok(&s);
|
||||
(void) gettok(&s);
|
||||
if (!(w = gettoks(s))) {
|
||||
fprintf(cp_err, "Warning: no nodes given: %s\n", iline->wl_word);
|
||||
}
|
||||
some = 1;
|
||||
com_save2(w, name);
|
||||
} else if (ciprefix(".op", s)) {
|
||||
some = 1;
|
||||
com_save2(&all, "OP");
|
||||
} else if (ciprefix(".tf", s)) {
|
||||
some = 1;
|
||||
com_save2(&all, "TF");
|
||||
}
|
||||
}
|
||||
return some;
|
||||
}
|
||||
|
||||
/* Execute the .whatever lines found in the deck, after we are done running.
|
||||
|
|
@ -332,6 +339,7 @@ ft_cktcoms(bool terse)
|
|||
}
|
||||
} else if (!eq(command->wl_word, ".save")
|
||||
&& !eq(command->wl_word, ".op")
|
||||
&& !eq(command->wl_word, ".measure")
|
||||
&& !eq(command->wl_word, ".tf"))
|
||||
{
|
||||
goto bad;
|
||||
|
|
|
|||
|
|
@ -387,13 +387,12 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
ld = dd->li_next;
|
||||
if ((dd->li_line[0] == '*') && (dd->li_line[1] != '#'))
|
||||
continue;
|
||||
if (!ciprefix(".control", dd->li_line) &&
|
||||
!ciprefix(".endc", dd->li_line)) {
|
||||
if (!ciprefix(".control", dd->li_line) && !ciprefix(".endc", dd->li_line)) {
|
||||
if (dd->li_line[0] == '*')
|
||||
cp_evloop(dd->li_line + 2);
|
||||
else
|
||||
cp_evloop(dd->li_line);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* free the control deck */
|
||||
line_free(deck,TRUE);
|
||||
|
|
@ -401,11 +400,11 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
} /* end if(comfile) */
|
||||
|
||||
else { /* must be regular deck . . . . */
|
||||
for (dd = deck->li_next; dd; dd = ld->li_next) { /* loop through deck and handle control cards */
|
||||
for (dd = deck->li_next; dd; dd = ld->li_next) { /* loop through deck and handle control cards */
|
||||
|
||||
/* Ignore comment lines, but not lines begining with '*#' */
|
||||
s = dd->li_line;
|
||||
while(isspace(*s)) s++;
|
||||
/* Ignore comment lines, but not lines begining with '*#' */
|
||||
s = dd->li_line;
|
||||
while(isspace(*s)) s++;
|
||||
if ( (*s == '*') && ( (s != dd->li_line) || (s[1] != '#'))) {
|
||||
ld = dd;
|
||||
continue;
|
||||
|
|
@ -420,14 +419,14 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
|
||||
if (ciprefix(".control", dd->li_line)) {
|
||||
ld->li_next = dd->li_next;
|
||||
line_free(dd,FALSE); /* SJB - free this line's memory */
|
||||
line_free(dd,FALSE); /* SJB - free this line's memory */
|
||||
if (commands)
|
||||
fprintf(cp_err, "Warning: redundant .control card\n");
|
||||
else
|
||||
commands = TRUE;
|
||||
} else if (ciprefix(".endc", dd->li_line)) {
|
||||
ld->li_next = dd->li_next;
|
||||
line_free(dd,FALSE); /* SJB - free this line's memory */
|
||||
line_free(dd,FALSE); /* SJB - free this line's memory */
|
||||
if (commands)
|
||||
commands = FALSE;
|
||||
else
|
||||
|
|
@ -479,6 +478,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
|| eq(s, ".print")
|
||||
|| eq(s, ".save")
|
||||
|| eq(s, ".op")
|
||||
|| eq(s, ".measure")
|
||||
|| eq(s, ".tf"))
|
||||
{
|
||||
if (end) {
|
||||
|
|
@ -489,7 +489,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
|
|||
wl_first = end = alloc(struct wordlist);
|
||||
end->wl_word = copy(dd->li_line);
|
||||
|
||||
if (!eq(s, ".op") && !eq(s, ".tf")) {
|
||||
if (!eq(s, ".op") && !eq(s, ".tf") && !eq(s, ".measure")) {
|
||||
ld->li_next = dd->li_next;
|
||||
line_free(dd,FALSE); /* SJB - free this line's memory */
|
||||
} else
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ get_volt_time( struct dvec *time, struct dvec *values, double value, char polari
|
|||
|
||||
static bool
|
||||
measure( char *trig_name, double trig_value, char trig_polarity, int trig_index,
|
||||
char *targ_name, double targ_value, char targ_polarity, int targ_index, double *result,
|
||||
double *trig_time, double *targ_time ) {
|
||||
char *targ_name, double targ_value, char targ_polarity, int targ_index, double *result,
|
||||
double *trig_time, double *targ_time ) {
|
||||
struct dvec *time = vec_get("time");
|
||||
struct dvec *trig = vec_get(trig_name);
|
||||
struct dvec *targ = vec_get(targ_name);
|
||||
|
|
@ -95,101 +95,136 @@ measure( char *trig_name, double trig_value, char trig_polarity, int trig_index,
|
|||
*/
|
||||
static bool
|
||||
measure2( char *meas_type, char *vec_name, char vec_type, double from, double to, double *result, double *result_time ) {
|
||||
struct dvec *time = vec_get("time");
|
||||
struct dvec *vec;
|
||||
int xy_size = 0;
|
||||
double *x, *y, *width, sum1 = 0, sum2 = 0, sum3 = 0;
|
||||
char tmp_vec_name[1000];
|
||||
double prev_result = 0;
|
||||
bool failed = FALSE, first_time = TRUE, constant_y = TRUE;
|
||||
int i;
|
||||
struct dvec *time = vec_get("time");
|
||||
struct dvec *vec;
|
||||
int xy_size = 0;
|
||||
double *x, *y, *width, sum1 = 0, sum2 = 0, sum3 = 0;
|
||||
double init_val;
|
||||
char tmp_vec_name[1000];
|
||||
double prev_result = 0;
|
||||
bool failed = FALSE, first_time = TRUE, constant_y = TRUE;
|
||||
int i, idx, upflag ;
|
||||
|
||||
if ( to < from ) { if ( just_chk_meas != TRUE ) fprintf( stderr, "Error: (measure2) 'to' time (%e) < 'from' time (%e).\n", to, from ); return TRUE; }
|
||||
if ( to < from ) { if ( just_chk_meas != TRUE ) fprintf( stderr, "Error: (measure2) 'to' time (%e) < 'from' time (%e).\n", to, from ); return TRUE; }
|
||||
|
||||
if ( vec_type == 'i' ) {
|
||||
if ( strstr( vec_name, ".v" ) ) sprintf( tmp_vec_name, "v.%s#branch", vec_name );
|
||||
else sprintf( tmp_vec_name, "%s#branch", vec_name );
|
||||
}
|
||||
else sprintf( tmp_vec_name, "%s", vec_name );
|
||||
if ( vec_type == 'i' ) {
|
||||
if ( strstr( vec_name, ".v" ) ) sprintf( tmp_vec_name, "v.%s#branch", vec_name );
|
||||
else sprintf( tmp_vec_name, "%s#branch", vec_name );
|
||||
}
|
||||
else sprintf( tmp_vec_name, "%s", vec_name );
|
||||
|
||||
vec = vec_get( tmp_vec_name );
|
||||
vec = vec_get( tmp_vec_name );
|
||||
|
||||
if ( !time ) { if ( just_chk_meas != TRUE ) fprintf( stderr, "Error: problem accessing vector 'time'!\n" ); return TRUE; }
|
||||
if ( !vec ) { if ( just_chk_meas != TRUE ) fprintf( stderr, "Error: problem accessing vector '%s'!\n", tmp_vec_name ); return TRUE; }
|
||||
if ( !time ) { if ( just_chk_meas != TRUE ) fprintf( stderr, "Error: problem accessing vector 'time'!\n" ); return TRUE; }
|
||||
if ( !vec ) { if ( just_chk_meas != TRUE ) fprintf( stderr, "Error: problem accessing vector '%s'!\n", tmp_vec_name ); return TRUE; }
|
||||
|
||||
if ( strcmp( meas_type, "max" ) == 0 || strcmp( meas_type, "min" ) == 0 ) {
|
||||
for ( i = 0; i < vec->v_length; i++ ) {
|
||||
if ( time->v_realdata[i] >= from && ( i+1 < time->v_length && time->v_realdata[i+1] <= to ) ) {
|
||||
prev_result = *result;
|
||||
if ( first_time ) {
|
||||
first_time = FALSE;
|
||||
*result = vec->v_realdata[i];
|
||||
*result_time = time->v_realdata[i];
|
||||
} else {
|
||||
*result = ( strcmp( meas_type, "max" ) == 0 ) ? MAX( *result, vec->v_realdata[i] ) : MIN( *result, vec->v_realdata[i] );
|
||||
if ( !AlmostEqualUlps( prev_result, *result, 100 ) ) *result_time = time->v_realdata[i];
|
||||
}
|
||||
if ( strcmp( meas_type, "max" ) == 0 || strcmp( meas_type, "min" ) == 0 ) {
|
||||
for ( i = 0; i < vec->v_length; i++ ) {
|
||||
if ( time->v_realdata[i] >= from && ( i+1 < time->v_length && time->v_realdata[i+1] <= to ) ) {
|
||||
prev_result = *result;
|
||||
if ( first_time ) {
|
||||
first_time = FALSE;
|
||||
*result = vec->v_realdata[i];
|
||||
*result_time = time->v_realdata[i];
|
||||
} else {
|
||||
*result = ( strcmp( meas_type, "max" ) == 0 ) ? MAX( *result, vec->v_realdata[i] ) : MIN( *result, vec->v_realdata[i] );
|
||||
if ( !AlmostEqualUlps( prev_result, *result, 100 ) ) *result_time = time->v_realdata[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( strcmp( meas_type, "avg" ) == 0 || strcmp( meas_type, "rms" ) == 0 ||
|
||||
}
|
||||
else if ( strcmp( meas_type, "avg" ) == 0 || strcmp( meas_type, "rms" ) == 0 ||
|
||||
strcmp( meas_type, "integral" ) == 0 || strcmp( meas_type, "integ" ) == 0 ) {
|
||||
x = (double *) tmalloc(time->v_length * sizeof(double));
|
||||
y = (double *) tmalloc(time->v_length * sizeof(double));
|
||||
width = (double *) tmalloc(time->v_length * sizeof(double));
|
||||
x = (double *) tmalloc(time->v_length * sizeof(double));
|
||||
y = (double *) tmalloc(time->v_length * sizeof(double));
|
||||
width = (double *) tmalloc(time->v_length * sizeof(double));
|
||||
|
||||
// create new set of values over interval [from, to] -- interpolate if necessary
|
||||
for ( i = 0; i < vec->v_length; i++ ) {
|
||||
if ( time->v_realdata[i] >= from && time->v_realdata[i] <= to ) {
|
||||
*(x+xy_size) = time->v_realdata[i];
|
||||
*(y+xy_size++) = ( strcmp( meas_type, "avg" ) == 0 || ciprefix( "integ", meas_type ) ) ? vec->v_realdata[i] : pow(vec->v_realdata[i],2);
|
||||
// create new set of values over interval [from, to] -- interpolate if necessary
|
||||
for ( i = 0; i < vec->v_length; i++ ) {
|
||||
if ( time->v_realdata[i] >= from && time->v_realdata[i] <= to ) {
|
||||
*(x+xy_size) = time->v_realdata[i];
|
||||
*(y+xy_size++) = ( strcmp( meas_type, "avg" ) == 0 || ciprefix( "integ", meas_type ) ) ? vec->v_realdata[i] : pow(vec->v_realdata[i],2);
|
||||
}
|
||||
}
|
||||
}
|
||||
// evaluate segment width
|
||||
for ( i = 0; i < xy_size-1; i++ ) *(width+i) = *(x+i+1) - *(x+i);
|
||||
*(width+i++) = 0;
|
||||
*(width+i++) = 0;
|
||||
// evaluate segment width
|
||||
for ( i = 0; i < xy_size-1; i++ ) *(width+i) = *(x+i+1) - *(x+i);
|
||||
*(width+i++) = 0;
|
||||
*(width+i++) = 0;
|
||||
|
||||
// see if y-value constant
|
||||
for ( i = 0; i < xy_size-1; i++ )
|
||||
if ( !AlmostEqualUlps( *(y+i), *(y+i+1), 100 ) ) constant_y = FALSE;
|
||||
// see if y-value constant
|
||||
for ( i = 0; i < xy_size-1; i++ )
|
||||
if ( !AlmostEqualUlps( *(y+i), *(y+i+1), 100 ) ) constant_y = FALSE;
|
||||
|
||||
// Compute Integral (area under curve)
|
||||
i = 0;
|
||||
while ( i < xy_size-1 ) {
|
||||
// Simpson's 3/8 Rule
|
||||
if ( AlmostEqualUlps( *(width+i), *(width+i+1), 100 ) && AlmostEqualUlps( *(width+i), *(width+i+2), 100 ) ) {
|
||||
sum1 += 3*(*(width+i))*(*(y+i) + 3*(*(y+i+1) + *(y+i+2)) + *(y+i+3))/8;
|
||||
i += 3;
|
||||
// Compute Integral (area under curve)
|
||||
i = 0;
|
||||
while ( i < xy_size-1 ) {
|
||||
// Simpson's 3/8 Rule
|
||||
if ( AlmostEqualUlps( *(width+i), *(width+i+1), 100 ) && AlmostEqualUlps( *(width+i), *(width+i+2), 100 ) ) {
|
||||
sum1 += 3*(*(width+i))*(*(y+i) + 3*(*(y+i+1) + *(y+i+2)) + *(y+i+3))/8;
|
||||
i += 3;
|
||||
}
|
||||
// Simpson's 1/3 Rule
|
||||
else if ( AlmostEqualUlps( *(width+i), *(width+i+1), 100 ) ) {
|
||||
sum2 += *(width+i)*(*(y+i) + 4*(*(y+i+1)) + *(y+i+2))/3;
|
||||
i += 2;
|
||||
}
|
||||
// Trapezoidal Rule
|
||||
else if ( !AlmostEqualUlps( *(width+i), *(width+i+1), 100 ) ) {
|
||||
sum3 += *(width+i)*(*(y+i) + *(y+i+1))/2;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
// Simpson's 1/3 Rule
|
||||
else if ( AlmostEqualUlps( *(width+i), *(width+i+1), 100 ) ) {
|
||||
sum2 += *(width+i)*(*(y+i) + 4*(*(y+i+1)) + *(y+i+2))/3;
|
||||
i += 2;
|
||||
}
|
||||
// Trapezoidal Rule
|
||||
else if ( !AlmostEqualUlps( *(width+i), *(width+i+1), 100 ) ) {
|
||||
sum3 += *(width+i)*(*(y+i) + *(y+i+1))/2;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !ciprefix( "integ", meas_type ) ) {
|
||||
*result = (sum1 + sum2 + sum3)/(to - from);
|
||||
if ( !ciprefix( "integ", meas_type ) ) {
|
||||
*result = (sum1 + sum2 + sum3)/(to - from);
|
||||
|
||||
if ( strcmp( meas_type, "rms" ) == 0 ) *result = sqrt(*result);
|
||||
if ( strcmp( meas_type, "avg" ) == 0 && constant_y == TRUE ) *result = *y;
|
||||
}
|
||||
else {
|
||||
*result = ( sum1 + sum2 + sum3 );
|
||||
}
|
||||
txfree(x); txfree(y); txfree(width);
|
||||
}
|
||||
else {
|
||||
if ( just_chk_meas != TRUE ) fprintf( cp_err, "Error: (measure2) unknown meas function '%s'.\n", meas_type );
|
||||
return TRUE;
|
||||
}
|
||||
return failed;
|
||||
if ( strcmp( meas_type, "rms" ) == 0 ) *result = sqrt(*result);
|
||||
if ( strcmp( meas_type, "avg" ) == 0 && constant_y == TRUE ) *result = *y;
|
||||
}
|
||||
else {
|
||||
*result = ( sum1 + sum2 + sum3 );
|
||||
}
|
||||
txfree(x); txfree(y); txfree(width);
|
||||
}
|
||||
else if ( strcmp( meas_type, "when" ) == 0 ){
|
||||
init_val = vec->v_realdata[0] ;
|
||||
if ( AlmostEqualUlps( init_val, from, 100 ) ){
|
||||
/* match right out of the gate. */
|
||||
*result = vec->v_realdata[0];
|
||||
*result_time = time->v_realdata[0];
|
||||
return failed ;
|
||||
}
|
||||
if( init_val < from ){
|
||||
/* search upward */
|
||||
upflag = TRUE ;
|
||||
} else {
|
||||
/* search downward */
|
||||
upflag = FALSE ;
|
||||
}
|
||||
idx = -1 ;
|
||||
for ( i = 0; i < vec->v_length; i++ ) {
|
||||
if ( AlmostEqualUlps( vec->v_realdata[i], from, 100 ) ){
|
||||
idx = i ;
|
||||
break ;
|
||||
} else if( upflag && (vec->v_realdata[i] > from) ){
|
||||
idx = i ;
|
||||
break ;
|
||||
} else if( !(upflag) && (vec->v_realdata[i] < from) ){
|
||||
idx = i ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if( idx < 0 ){
|
||||
return failed;
|
||||
}
|
||||
*result = vec->v_realdata[idx] ;
|
||||
*result_time = interpolate( time, vec, idx-1, i, from, 'x' );
|
||||
}
|
||||
else {
|
||||
if ( just_chk_meas != TRUE ) fprintf( cp_err, "Error: (measure2) unknown meas function '%s'.\n", meas_type );
|
||||
return TRUE;
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -241,7 +276,7 @@ get_double_value( char **line, char *name, double *value ) {
|
|||
char *equal_ptr, *junk;
|
||||
int err;
|
||||
|
||||
if ( strncmp( token, name, strlen(name) ) != 0 ) {
|
||||
if ( name && ( strncmp( token, name, strlen(name) ) != 0 ) ) {
|
||||
if ( just_chk_meas != TRUE ) fprintf( cp_err, "Error: syntax error for measure statement; expecting next field to be '%s'.\n", name );
|
||||
return_val = FALSE;
|
||||
} else {
|
||||
|
|
@ -267,13 +302,51 @@ get_double_value( char **line, char *name, double *value ) {
|
|||
return return_val;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* gettok skips over whitespace and returns the next token found. This is
|
||||
* the original version. It does not "do the right thing" when you have
|
||||
* parens or commas anywhere in the nodelist. Note that I left this unmodified
|
||||
* since I didn't want to break any fcns which called it from elsewhere than
|
||||
* subckt.c. -- SDB 12.3.2003.
|
||||
* Since gettok doesn't work right try a new version that does. WPS.
|
||||
*-------------------------------------------------------------------------*/
|
||||
static char *
|
||||
gettok_paren(char **s)
|
||||
{
|
||||
char buf[BSIZE_SP];
|
||||
int i = 0;
|
||||
char c;
|
||||
int paren;
|
||||
|
||||
paren = 0;
|
||||
while (isspace(**s))
|
||||
(*s)++;
|
||||
if (!**s)
|
||||
return (NULL);
|
||||
while ((c = **s) && !isspace(c)) {
|
||||
if (c == '('/*)*/)
|
||||
paren += 1;
|
||||
else if (c == /*(*/')'){
|
||||
paren -= 1;
|
||||
if( paren <= 0 )
|
||||
break ;
|
||||
} else if (c == ',' && paren < 1)
|
||||
break;
|
||||
buf[i++] = *(*s)++;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
while (isspace(**s) || **s == ',')
|
||||
(*s)++;
|
||||
return (copy(buf));
|
||||
}
|
||||
|
||||
static char*
|
||||
get_vector_name( char **line ) {
|
||||
char *token, *name;
|
||||
|
||||
token = name = gettok(line);
|
||||
token = name = gettok_paren(line);
|
||||
|
||||
*(name + strlen(name) - 1) = '\0';
|
||||
// *(name + strlen(name) - 1) = '\0';
|
||||
name = strdup(name); txfree(token);
|
||||
|
||||
return name;
|
||||
|
|
@ -377,41 +450,61 @@ do_delay_measurement( char *resname, char *out_line, char *line, char *o_line, i
|
|||
static bool
|
||||
do_other_measurement( char *resname, char *out_line, char *meas_type, char *line, char *o_line, int meas_index, double *result ) {
|
||||
|
||||
char *vec_name;
|
||||
char vec_type;
|
||||
double from, to, result_time = 0;
|
||||
int precision = get_measure_precision();
|
||||
bool failed;
|
||||
char *vec_name;
|
||||
char vec_type;
|
||||
double from, to, result_time = 0;
|
||||
int precision = get_measure_precision();
|
||||
bool failed;
|
||||
|
||||
vec_type = *line; line += 2; /* skip over vector type and open paren */
|
||||
vec_name = get_vector_name( &line );
|
||||
if ( vec_type != 'v' && vec_type != 'i' ) {
|
||||
if ( just_chk_meas != TRUE ) {
|
||||
fprintf( cp_err, "Error: unexpected vector type '%c' for .meas!\n", vec_type );
|
||||
fprintf( cp_err, " %s\n", o_line );
|
||||
}
|
||||
txfree(vec_name); return FALSE;
|
||||
}
|
||||
if ( !get_double_value( &line, "from", &from ) ) { if ( just_chk_meas != TRUE ) fprintf( cp_err, " %s\n", o_line ); txfree(vec_name); return FALSE; }
|
||||
if ( !get_double_value( &line, "to", &to ) ) { if ( just_chk_meas != TRUE ) fprintf( cp_err, " %s\n", o_line ); txfree(vec_name); return FALSE; }
|
||||
vec_type = *line; line += 2; /* skip over vector type and open paren */
|
||||
vec_name = get_vector_name( &line );
|
||||
if ( vec_type != 'v' && vec_type != 'i' ) {
|
||||
if ( just_chk_meas != TRUE ) {
|
||||
fprintf( cp_err, "Error: unexpected vector type '%c' for .meas!\n", vec_type );
|
||||
fprintf( cp_err, " %s\n", o_line );
|
||||
}
|
||||
txfree(vec_name);
|
||||
return FALSE;
|
||||
}
|
||||
if ( strcmp( meas_type, "when" ) == 0 ){
|
||||
if ( !get_double_value( &line, NULL, &from ) ) {
|
||||
if ( just_chk_meas != TRUE ) fprintf( cp_err, " %s\n", o_line );
|
||||
txfree(vec_name);
|
||||
return FALSE;
|
||||
}
|
||||
to = from ;
|
||||
} else {
|
||||
if ( !get_double_value( &line, "from", &from ) ) {
|
||||
if ( just_chk_meas != TRUE ) fprintf( cp_err, " %s\n", o_line );
|
||||
txfree(vec_name);
|
||||
return FALSE;
|
||||
}
|
||||
if ( !get_double_value( &line, "to", &to ) ) {
|
||||
if ( just_chk_meas != TRUE ) fprintf( cp_err, " %s\n", o_line );
|
||||
txfree(vec_name);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
failed = measure2( meas_type, vec_name, vec_type, from, to, result, &result_time );
|
||||
failed = measure2( meas_type, vec_name, vec_type, from, to, result, &result_time );
|
||||
|
||||
if ( !failed ) {
|
||||
if ( strcmp( meas_type, "max" ) == 0 || strcmp( meas_type, "min" ) == 0 )
|
||||
sprintf( out_line, "%-15s= %.*e at= %.*e\n", resname, precision, *result, precision, result_time );
|
||||
else
|
||||
sprintf( out_line, "%-15s= %.*e from= %.*e to= %.*e\n", resname, precision, *result, precision, from, precision, to );
|
||||
measure_valid[meas_index] = TRUE;
|
||||
} else {
|
||||
measures_passed = FALSE;
|
||||
sprintf( out_line, "%-15s= failed\n", resname );
|
||||
measure_valid[meas_index] = FALSE;
|
||||
}
|
||||
if ( !failed ) {
|
||||
if ( strcmp( meas_type, "max" ) == 0 || strcmp( meas_type, "min" ) == 0 )
|
||||
sprintf( out_line, "%-15s= %.*e at= %.*e\n", resname, precision, *result, precision, result_time );
|
||||
else if ( strcmp( meas_type, "when" ) == 0 )
|
||||
sprintf( out_line, "%-15s= %.*e\n", resname, precision, result_time ) ;
|
||||
else
|
||||
sprintf( out_line, "%-15s= %.*e from= %.*e to= %.*e\n", resname, precision, *result, precision, from, precision, to );
|
||||
measure_valid[meas_index] = TRUE;
|
||||
} else {
|
||||
measures_passed = FALSE;
|
||||
sprintf( out_line, "%-15s= failed\n", resname );
|
||||
measure_valid[meas_index] = FALSE;
|
||||
}
|
||||
|
||||
txfree(vec_name);
|
||||
txfree(vec_name);
|
||||
|
||||
return ( failed ) ? FALSE : TRUE;
|
||||
return ( failed ) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -420,8 +513,8 @@ do_measure( char *what, bool chk_only ) {
|
|||
char *line, *an_name, *an_type, *resname, *meastype, *str_ptr, out_line[1000];
|
||||
int index = 0, ok = 0;
|
||||
double result = 0;
|
||||
int precision = get_measure_precision();
|
||||
bool first_time = TRUE;
|
||||
int precision = get_measure_precision();
|
||||
|
||||
just_chk_meas = chk_only;
|
||||
|
||||
|
|
@ -437,8 +530,8 @@ do_measure( char *what, bool chk_only ) {
|
|||
|
||||
if ( chkAnalysisType( an_type ) != TRUE ) {
|
||||
if ( just_chk_meas != TRUE ) {
|
||||
fprintf( cp_err, "Error: unrecognized analysis type '%s' for the following .meas statement on line %d:\n", an_type, meas_card->li_linenum );
|
||||
fprintf( cp_err, " %s\n", meas_card->li_line );
|
||||
fprintf( cp_err, "Error: unrecognized analysis type '%s' for the following .meas statement on line %d:\n", an_type, meas_card->li_linenum );
|
||||
fprintf( cp_err, " %s\n", meas_card->li_line );
|
||||
}
|
||||
|
||||
txfree(an_type); txfree(resname); txfree(meastype);
|
||||
|
|
@ -447,7 +540,10 @@ do_measure( char *what, bool chk_only ) {
|
|||
else if ( first_time ) {
|
||||
first_time = FALSE;
|
||||
|
||||
if ( just_chk_meas != TRUE && strcmp( an_type, "tran" ) == 0 ) fprintf( stdout, " Transient Analysis\n\n" );
|
||||
if ( just_chk_meas != TRUE && strcmp( an_type, "tran" ) == 0 ) {
|
||||
fprintf( stdout, " Transient Analysis\n\n" );
|
||||
// plot_cur = setcplot("tran");
|
||||
}
|
||||
}
|
||||
|
||||
/* skip param|expr measurement types for now -- will be done after other measurements */
|
||||
|
|
@ -460,23 +556,23 @@ do_measure( char *what, bool chk_only ) {
|
|||
|
||||
if ( strcmp( meastype, "trig" ) == 0 || strcmp( meastype, "delay" ) == 0 ) {
|
||||
if ( do_delay_measurement( resname, out_line, line, meas_card->li_line, index++, &result ) && just_chk_meas != TRUE ) {
|
||||
nupa_add_param( resname, result );
|
||||
nupa_add_param( resname, result );
|
||||
}
|
||||
}
|
||||
else if ( strcmp( meastype, "avg" ) == 0 || strcmp( meastype, "mean" ) == 0 ||
|
||||
strcmp( meastype, "max" ) == 0 || strcmp( meastype, "min" ) == 0 ||
|
||||
strcmp( meastype, "rms" ) == 0 || strcmp( meastype, "integ" ) == 0 ||
|
||||
strcmp( meastype, "integral" ) == 0 ) {
|
||||
strcmp( meastype, "integral" ) == 0 || strcmp( meastype, "when" ) == 0 ) {
|
||||
if ( do_other_measurement( resname, out_line, meastype, line, meas_card->li_line, index++, &result ) && just_chk_meas != TRUE ) {
|
||||
nupa_add_param( resname, result );
|
||||
nupa_add_param( resname, result );
|
||||
}
|
||||
}
|
||||
else {
|
||||
measures_passed = FALSE;
|
||||
sprintf( out_line, "%-15s= failed\n", resname );
|
||||
if ( just_chk_meas != TRUE ) {
|
||||
fprintf( cp_err, "Error: unsupported measurement type '%s' on line %d:\n", meastype, meas_card->li_linenum );
|
||||
fprintf( cp_err, " %s\n", meas_card->li_line );
|
||||
fprintf( cp_err, "Error: unsupported measurement type '%s' on line %d:\n", meastype, meas_card->li_linenum );
|
||||
fprintf( cp_err, " %s\n", meas_card->li_line );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -510,8 +606,8 @@ do_measure( char *what, bool chk_only ) {
|
|||
|
||||
if ( chkAnalysisType( an_type ) != TRUE ) {
|
||||
if ( just_chk_meas != TRUE ) {
|
||||
fprintf( cp_err, "Error: unrecognized analysis type '%s' for the following .meas statement on line %d:\n", an_type, meas_card->li_linenum );
|
||||
fprintf( cp_err, " %s\n", meas_card->li_line );
|
||||
fprintf( cp_err, "Error: unrecognized analysis type '%s' for the following .meas statement on line %d:\n", an_type, meas_card->li_linenum );
|
||||
fprintf( cp_err, " %s\n", meas_card->li_line );
|
||||
}
|
||||
|
||||
txfree(an_type); txfree(resname); txfree(meastype);
|
||||
|
|
@ -541,17 +637,17 @@ do_measure( char *what, bool chk_only ) {
|
|||
ok = nupa_eval( meas_card->li_line, meas_card->li_linenum );
|
||||
|
||||
if ( ok ) {
|
||||
str_ptr = strstr( meas_card->li_line, meastype );
|
||||
if ( !get_double_value( &str_ptr, meastype, &result ) ) {
|
||||
if ( just_chk_meas != TRUE ) fprintf( stdout, " failed\n" );
|
||||
}
|
||||
else {
|
||||
if ( just_chk_meas != TRUE ) fprintf( stdout, " %.*e\n", precision, result );
|
||||
nupa_add_param( resname, result );
|
||||
}
|
||||
str_ptr = strstr( meas_card->li_line, meastype );
|
||||
if ( !get_double_value( &str_ptr, meastype, &result ) ) {
|
||||
if ( just_chk_meas != TRUE ) fprintf( stdout, " failed\n" );
|
||||
}
|
||||
else {
|
||||
if ( just_chk_meas != TRUE ) fprintf( stdout, " %.*e\n", precision, result );
|
||||
nupa_add_param( resname, result );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( just_chk_meas != TRUE ) fprintf( stdout, " failed\n" );
|
||||
if ( just_chk_meas != TRUE ) fprintf( stdout, " failed\n" );
|
||||
}
|
||||
}
|
||||
txfree(an_type); txfree(resname); txfree(meastype);
|
||||
|
|
|
|||
Loading…
Reference in New Issue