measure.c, rewrite do_measure()
This commit is contained in:
parent
155b6134a8
commit
12e19d140b
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue