static double * getlims(wordlist *wl, char *name, int number) { double *d; wordlist *beg, *wk; int n; if (number < 1) return NULL; beg = wl_find(name, wl->wl_next); if (!beg) return NULL; wk = beg->wl_next; d = TMALLOC(double, number); for (n = 0; n < number; n++) { char *ss; double *td; if (!wk) { fprintf(cp_err, "Syntax error: not enough parameters for \"%s\".\n", name); txfree(d); return NULL; } ss = wk->wl_word; td = ft_numparse(&ss, FALSE); if (!td) { fprintf(cp_err, "Syntax error: bad parameters for \"%s\".\n", name); txfree(d); return NULL; } d[n] = *td; wk = wk->wl_next; } wl_delete_slice(beg, wk); return d; }
//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'*/ // bool just_chk_meas /* in: just check measurement if true */ //) static int 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'*/ int just_chk_meas /* in: just check measurement if true */ ) { char *token = gettok(line); //bool return_val = TRUE; int return_val = TRUE; char *equal_ptr, *junk; int err = 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 { /* see if '=' is last char of current token -- implies we need to read value in next token */ if (token[strlen(token) - 1] == '=') { txfree(token); junk = token = gettok(line); *value = INPevaluate(&junk, &err, 1); } else { if ((equal_ptr = strstr(token, "=")) != NULL) { equal_ptr += 1; *value = INPevaluate(&equal_ptr, &err, 1); } else { if (just_chk_meas != TRUE) fprintf(cp_err, "Error: syntax error for measure statement; missing '='!\n"); return_val = FALSE; } } if (err) { if (just_chk_meas != TRUE) fprintf(cp_err, "Error: Bad value.\n"); return_val = FALSE; } } txfree(token); return return_val; }
//bool //do_measure( // char *what, /*in: analysis type*/ // bool chk_only /*in: TRUE if checking for "autostop", FALSE otherwise*/ //) int do_measure( char *what, /*in: analysis type*/ int chk_only /*in: TRUE if checking for "autostop", FALSE otherwise*/ ) { struct line *meas_card, *meas_results = NULL, *end = NULL, *newcard; char *line, *an_name, *an_type, *resname, *meastype, *str_ptr, out_line[1000]; int ok = 0; int fail; int num_failed = 0; double result = 0; // bool first_time = TRUE; // bool measures_passed; int first_time = TRUE; int measures_passed; wordlist *measure_word_list; int precision = measure_get_precision(); #ifdef HAS_PROGREP if (!chk_only) SetAnalyse("meas", 0); #endif 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 (measures_passed); } /* don't allow autostop if no .meas commands are given in the input file */ if ((cp_getvar("autostop", CP_BOOL, NULL)) && (ft_curckt->ci_meas == NULL)) { fprintf(cp_err, "\nWarning: No .meas commands found!\n"); fprintf(cp_err, " Option autostop is not available, ignored!\n\n"); cp_remvar("autostop"); return (FALSE); } /* Evaluating the linked list of .meas cards, assembled from the input deck by fcn inp_spsource() in inp.c:575. A typical .meas card will contain: parameter value nameof card .meas(ure) analysis type tran only tran available currently result name myout defined by user measurement type trig|delay|param|expr|avg|mean|max|min|rms|integ(ral)|when The measurement type determines how to continue the .meas card. param|expr are skipped in first pass through .meas cards and are treated in second pass, all others are treated in fcn get_measure2() (com_measure2.c). */ /* first pass through .meas cards: evaluate everything except param|expr */ for (meas_card = ft_curckt->ci_meas; meas_card != NULL; meas_card = meas_card->li_next) { line = meas_card->li_line; txfree(gettok(&line)); /* discard .meas */ an_type = gettok(&line); resname = gettok(&line); meastype = gettok(&line); if (chkAnalysisType(an_type) != 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); } txfree(an_type); txfree(resname); txfree(meastype); continue; } /* print header before evaluating first .meas line */ else if (first_time) { first_time = FALSE; if (!chk_only && strcmp(an_type, "tran") == 0) { fprintf(stdout, "\n Measurements for Transient Analysis\n\n"); } } /* skip param|expr measurement types for now -- will be done after other measurements */ if (strncmp(meastype, "param", 5) == 0 || strncmp(meastype, "expr", 4) == 0) continue; /* skip .meas line, if analysis type from line and name of analysis performed differ */ if (strcmp(an_name, an_type) != 0) { txfree(an_type); txfree(resname); txfree(meastype); continue; } /* New way of processing measure statements using common code in fcn get_measure2() (com_measure2.c)*/ out_line[0] = '\0'; measure_word_list = measure_parse_line(meas_card->li_line); if (measure_word_list) { fail = get_measure2(measure_word_list, &result, out_line, chk_only); if (fail) { 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); wl_free(measure_word_list); break; } } else { if (!chk_only) nupa_add_param(resname, result); } wl_free(measure_word_list); } else { measures_passed = FALSE; num_failed++; } 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; } } txfree(an_type); txfree(resname); txfree(meastype); } /* end of for loop (first pass through .meas lines) */