From 12e19d140be291e65420953193d2c1c81fe2cc72 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Sun, 9 Dec 2012 13:13:35 +0100 Subject: [PATCH] measure.c, rewrite do_measure() --- src/frontend/measure.c | 116 ++++++++++++++++------------------- src/include/ngspice/fteext.h | 2 +- 2 files changed, 55 insertions(+), 63 deletions(-) diff --git a/src/frontend/measure.c b/src/frontend/measure.c index b7d3bb9f6..579ea9656 100644 --- a/src/frontend/measure.c +++ b/src/frontend/measure.c @@ -23,12 +23,6 @@ static wordlist *measure_parse_line(char *line); -static bool measure_valid[20000];/* TRUE: if measurement no. [xxx] has been done successfully - (not used anywhere)*/ -static bool just_chk_meas; /* TRUE: only check if measurement can be done successfully, - no output generated (if option autostop is set)*/ -static bool measures_passed; /* TRUE: stop simulation (if option autostop is set)*/ - extern bool ft_batchmode; extern bool rflag; @@ -154,8 +148,6 @@ chkAnalysisType(char *an_type) if (strcmp(an_type, "tran") != 0 && strcmp(an_type, "ac") != 0 && strcmp(an_type, "dc") != 0 && strcmp(an_type, "sp") != 0) return FALSE; - // else if (ft_batchmode == TRUE) - // return FALSE; else return TRUE; } @@ -165,9 +157,10 @@ chkAnalysisType(char *an_type) On error returns FALSE. */ static bool get_double_value( - char **line, /*in|out: pointer to line to be parsed */ - char *name, /*in: xxx e.g. 'val' from 'val=0.5' */ - double *value /*out: return value (e.g. 0.5) from 'val=0.5'*/ + char **line, /*in|out: pointer to line to be parsed */ + char *name, /*in: xxx e.g. 'val' from 'val=0.5' */ + double *value, /*out: return value (e.g. 0.5) from 'val=0.5'*/ + bool just_chk_meas /* in: just check measurement if true */ ) { char *token = gettok(line); @@ -210,43 +203,44 @@ get_double_value( /* Entry point for .meas evaluation. Called in fcn dosim() from runcoms.c:335, after simulation is finished with chk_only set to FALSE. - Called from fcn check_autostop() - with chk_only set to TRUE (no printouts, no params set). */ -void + Called from fcn check_autostop(), + with chk_only set to TRUE (no printouts, no params set). + This function returns TRUE if all measurements are ready and complete; + FALSE otherwise. If called with chk_only, we can exit early if we + fail a test in order to reduce execution time. */ +bool do_measure( char *what, /*in: analysis type*/ bool chk_only /*in: TRUE if checking for "autostop", FALSE otherwise*/ - /*global variable measures_passed - out: set to FALSE if .meas syntax is violated (used with autostop)*/ ) { struct line *meas_card, *meas_results = NULL, *end = NULL, *newcard; char *line, *an_name, *an_type, *resname, *meastype, *str_ptr, out_line[1000]; - int idx = 0, ok = 0; - int fail; + int ok = 0; + int fail; + int num_failed = 0; double result = 0; bool first_time = TRUE; + bool measures_passed; wordlist *measure_word_list; int precision = measure_get_precision(); - #ifdef HAS_WINDOWS if (!chk_only) SetAnalyse("meas", 0); #endif - just_chk_meas = chk_only; - an_name = strdup(what); /* analysis type, e.g. "tran" */ strtolower(an_name); measure_word_list = NULL; + measures_passed = TRUE; /* don't allow .meas if batchmode is set by -b and -r rawfile given */ if (ft_batchmode && rflag) { fprintf(cp_err, "\nNo .measure possible in batch mode (-b) with -r rawfile set!\n"); fprintf(cp_err, "Remove rawfile and use .print or .plot or\n"); fprintf(cp_err, "select interactive mode (optionally with .control section) instead.\n\n"); - return; + return (measures_passed); } /* Evaluating the linked list of .meas cards, assembled from the input deck @@ -274,7 +268,7 @@ do_measure( meastype = gettok(&line); if (chkAnalysisType(an_type) != TRUE) { - if (just_chk_meas != TRUE) { + if (!chk_only) { 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); } @@ -288,9 +282,8 @@ do_measure( else if (first_time) { first_time = FALSE; - if (just_chk_meas != TRUE && strcmp(an_type, "tran") == 0) { + if (!chk_only && strcmp(an_type, "tran") == 0) { fprintf(stdout, "\n Measurements for Transient Analysis\n\n"); - // plot_cur = setcplot("tran"); } } @@ -313,44 +306,48 @@ do_measure( if (measure_word_list) { fail = get_measure2(measure_word_list, &result, out_line, chk_only); if (fail) { - measure_valid[idx++] = FALSE; measures_passed = FALSE; if (!chk_only) fprintf(stderr, " %s failed!\n\n", meas_card->li_line); + num_failed++; + if (chk_only) { + /* added for speed - cleanup last parse and break */ + txfree(an_type); + txfree(resname); + txfree(meastype); + break; + } } else { - if (!(just_chk_meas)) + if (!chk_only) nupa_add_param(resname, result); - measure_valid[idx++] = TRUE; } wl_free(measure_word_list); } else { - measure_valid[idx++] = FALSE; measures_passed = FALSE; + num_failed++; } - newcard = alloc(struct line); - newcard->li_line = strdup(out_line); - newcard->li_next = NULL; + if (!chk_only) { + newcard = alloc(struct line); + newcard->li_line = strdup(out_line); + newcard->li_next = NULL; - if (meas_results == NULL) { - meas_results = end = newcard; - } else { - end->li_next = newcard; - end = newcard; + if (meas_results == NULL) { + meas_results = end = newcard; + } else { + end->li_next = newcard; + end = newcard; + } } txfree(an_type); txfree(resname); txfree(meastype); - /* see if number of measurements exceeds fixed array size of 20,000 */ - if (idx >= 20000) { - fprintf(stderr, "ERROR: number of measurements exceeds 20,000!\nAborting...\n"); - controlled_exit(EXIT_FAILURE); - } - } /* end of for loop (first pass through .meas lines) */ + if (chk_only) + return (measures_passed); /* second pass through .meas cards: now do param|expr .meas statements */ newcard = meas_results; @@ -364,7 +361,7 @@ do_measure( meastype = gettok(&line); if (chkAnalysisType(an_type) != TRUE) { - if (just_chk_meas != TRUE) { + if (!chk_only) { 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); } @@ -383,7 +380,7 @@ do_measure( if (strncmp(meastype, "param", 5) != 0 && strncmp(meastype, "expr", 4) != 0) { - if (just_chk_meas != TRUE) + if (!chk_only) fprintf(stdout, "%s", newcard->li_line); end = newcard; newcard = newcard->li_next; @@ -397,24 +394,24 @@ do_measure( continue; } - if (just_chk_meas != TRUE) + if (!chk_only) fprintf(stdout, "%-20s=", resname); - if (just_chk_meas != TRUE) { + if (!chk_only) { ok = nupa_eval(meas_card->li_line, meas_card->li_linenum, meas_card->li_linenum_orig); if (ok) { str_ptr = strstr(meas_card->li_line, meastype); - if (!get_double_value(&str_ptr, meastype, &result)) { - if (just_chk_meas != TRUE) + if (!get_double_value(&str_ptr, meastype, &result, chk_only)) { + if (!chk_only) fprintf(stdout, " failed\n"); } else { - if (just_chk_meas != TRUE) + if (!chk_only) fprintf(stdout, " %.*e\n", precision, result); nupa_add_param(resname, result); } } else { - if (just_chk_meas != TRUE) + if (!chk_only) fprintf(stdout, " failed\n"); } } @@ -423,35 +420,30 @@ do_measure( txfree(meastype); } - if (just_chk_meas != TRUE) + if (!chk_only) fprintf(stdout, "\n"); txfree(an_name); fflush(stdout); - //nupa_list_params(); + return(measures_passed); } /* called from dctran.c:470, if timepoint is accepted. Returns TRUE if measurement (just a check, no output) has been successful. If TRUE is returned, transient simulation is stopped. - Returns TRUE if "autostop" has been set as an option and if measures_passed not - set to FALSE during calling do_measure. 'what' is set to "tran".*/ + Returns TRUE if "autostop" has been set as an option and if do_measure + passes all tests and thereby returns TRUE. 'what' is set to "tran". */ bool check_autostop(char* what) { bool flag = FALSE; - measures_passed = TRUE; - if (cp_getvar("autostop", CP_BOOL, NULL)) { - do_measure(what, TRUE); - - if (measures_passed == TRUE) - flag = TRUE; - } + if (cp_getvar("autostop", CP_BOOL, NULL)) + flag = do_measure(what, TRUE); return flag; } diff --git a/src/include/ngspice/fteext.h b/src/include/ngspice/fteext.h index 0bef6d4f0..9f93cc3ea 100644 --- a/src/include/ngspice/fteext.h +++ b/src/include/ngspice/fteext.h @@ -266,7 +266,7 @@ extern void spar_write(char *name, struct plot *pl, double val); extern struct plot *raw_read(char *name); /* meas.c */ -extern void do_measure(char *what, bool chk_only); +extern bool do_measure(char *what, bool chk_only); extern bool check_autostop(char *what); /* randnumb.c */