diff --git a/ChangeLog b/ChangeLog index 1c0bb8b91..3534f3a34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/src/frontend/dotcards.c b/src/frontend/dotcards.c index 29dbdf45b..2e8aca44e 100644 --- a/src/frontend/dotcards.c +++ b/src/frontend/dotcards.c @@ -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; diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 6c0f8ac09..e50fdd4c9 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -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 diff --git a/src/frontend/measure.c b/src/frontend/measure.c index 8b24995a9..9a1732e96 100644 --- a/src/frontend/measure.c +++ b/src/frontend/measure.c @@ -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);