wordlist * cp_varwl(struct variable *var) { wordlist *wl = NULL, *w, *wx = NULL; char buf[BSIZE_SP],*copystring; struct variable *vt; switch(var->va_type) { case VT_BOOL: /* Can't ever be FALSE. */ sprintf(buf, "%s", var->va_bool ? "TRUE" : "FALSE"); break; case VT_NUM: sprintf(buf, "%d", var->va_num); break; case VT_REAL: /* This is a case where printnum isn't too good... */ sprintf(buf, "%G", var->va_real); break; case VT_STRING: /*strcpy(buf, cp_unquote(var->va_string)); DG: memory leak here*/ copystring= cp_unquote(var->va_string);/*DG*/ strcpy(buf,copystring); tfree(copystring); break; case VT_LIST: /* The tricky case. */ for (vt = var->va_vlist; vt; vt = vt->va_next) { w = cp_varwl(vt); if (wl == NULL) wl = wx = w; else { wx->wl_next = w; w->wl_prev = wx; wx = w; } } return (wl); default: fprintf(cp_err, "cp_varwl: Internal Error: bad variable type %d\n", var->va_type); return (NULL); } wl = alloc(struct wordlist); wl->wl_next = wl->wl_prev = NULL; wl->wl_word = copy(buf); return (wl); }
wordlist * cp_varwl(struct variable *var) { wordlist *wl = NULL, *w, *wx = NULL; char *buf; struct variable *vt; switch (var->va_type) { case CP_BOOL: /* Can't ever be FALSE. */ buf = copy(var->va_bool ? "TRUE" : "FALSE"); break; case CP_NUM: buf = tprintf("%d", var->va_num); break; case CP_REAL: /* This is a case where printnum isn't too good... */ buf = tprintf("%G", var->va_real); break; case CP_STRING: buf = cp_unquote(var->va_string); break; case CP_LIST: /* The tricky case. */ for (vt = var->va_vlist; vt; vt = vt->va_next) { w = cp_varwl(vt); if (wl == NULL) { wl = wx = w; } else { wx->wl_next = w; w->wl_prev = wx; wx = w; } } return (wl); default: fprintf(cp_err, "cp_varwl: Internal Error: bad variable type %d\n", var->va_type); return (NULL); } return wl_cons(buf, NULL); }
void raw_write(char *name, struct plot *pl, bool app, bool binary) { FILE *fp; bool realflag = TRUE, writedims; bool raw_padding; int length, numdims, dims[MAXDIMS]; int nvars, i, j, prec; struct dvec *v, *lv; wordlist *wl; struct variable *vv; double dd; char buf[BSIZE_SP]; char *branch; raw_padding = !cp_getvar("nopadding", CP_BOOL, NULL); /* Why bother printing out an empty plot? */ if (!pl->pl_dvecs) { fprintf(cp_err, "Error: plot is empty, nothing written.\n"); return; } if (raw_prec != -1) prec = raw_prec; else prec = DEFPREC; #if defined(__MINGW32__) || defined(_MSC_VER) /* - Binary file binary write - hvogt 15.03.2000 ---------------------*/ if (binary) { if ((fp = fopen(name, app ? "ab" : "wb")) == NULL) { perror(name); return; } fprintf(cp_out, "binary raw file\n"); } else { if ((fp = fopen(name, app ? "a" : "w")) == NULL) { perror(name); return; } fprintf(cp_out, "ASCII raw file\n"); } /* --------------------------------------------------------------------*/ #else if (!(fp = fopen(name, app ? "a" : "w"))) { perror(name); return; } #endif numdims = nvars = length = 0; for (v = pl->pl_dvecs; v; v = v->v_next) { if (iscomplex(v)) realflag = FALSE; nvars++; /* Find the length and dimensions of the longest vector * in the plot. * Be paranoid and assume somewhere we may have * forgotten to set the dimensions of 1-D vectors. */ if (v->v_numdims <= 1) { v->v_numdims = 1; v->v_dims[0] = v->v_length; } if (v->v_length > length) { length = v->v_length; numdims = v->v_numdims; for (j = 0; j < numdims; j++) { dims[j] = v->v_dims[j]; } } } fprintf(fp, "Title: %s\n", pl->pl_title); fprintf(fp, "Date: %s\n", pl->pl_date); fprintf(fp, "Plotname: %s\n", pl->pl_name); fprintf(fp, "Flags: %s%s\n", realflag ? "real" : "complex", raw_padding ? "" : " unpadded"); fprintf(fp, "No. Variables: %d\n", nvars); fprintf(fp, "No. Points: %d\n", length); if (numdims > 1) { dimstring(dims, numdims, buf); fprintf(fp, "Dimensions: %s\n", buf); } for (wl = pl->pl_commands; wl; wl = wl->wl_next) fprintf(fp, "Command: %s\n", wl->wl_word); for (vv = pl->pl_env; vv; vv = vv->va_next) { wl = cp_varwl(vv); if (vv->va_type == CP_BOOL) { fprintf(fp, "Option: %s\n", vv->va_name); } else { fprintf(fp, "Option: %s = ", vv->va_name); if (vv->va_type == CP_LIST) fprintf(fp, "( "); wl_print(wl, fp); if (vv->va_type == CP_LIST) fprintf(fp, " )"); (void) putc('\n', fp); } } /* Before we write the stuff out, make sure that the scale is the first * in the list. */ for (lv = NULL, v = pl->pl_dvecs; v != pl->pl_scale; v = v->v_next) lv = v; if (lv) { lv->v_next = v->v_next; v->v_next = pl->pl_dvecs; pl->pl_dvecs = v; } fprintf(fp, "Variables:\n"); for (i = 0, v = pl->pl_dvecs; v; v = v->v_next) { if (v->v_type == SV_CURRENT) { branch = NULL; if ((branch = strstr(v->v_name, "#branch")) != NULL) { *branch = '\0'; } fprintf(fp, "\t%d\ti(%s)\t%s", i++, v->v_name, ft_typenames(v->v_type)); if (branch != NULL) *branch = '#'; } else if (v->v_type == SV_VOLTAGE) { fprintf(fp, "\t%d\t%s\t%s", i++, v->v_name, ft_typenames(v->v_type)); } else { fprintf(fp, "\t%d\t%s\t%s", i++, v->v_name, ft_typenames(v->v_type)); } if (v->v_flags & VF_MINGIVEN) fprintf(fp, " min=%e", v->v_minsignal); if (v->v_flags & VF_MAXGIVEN) fprintf(fp, " max=%e", v->v_maxsignal); if (v->v_defcolor) fprintf(fp, " color=%s", v->v_defcolor); if (v->v_gridtype) fprintf(fp, " grid=%d", v->v_gridtype); if (v->v_plottype) fprintf(fp, " plot=%d", v->v_plottype); /* Only write dims if they are different from default. */ writedims = FALSE; if (v->v_numdims != numdims) { writedims = TRUE; } else { for (j = 0; j < numdims; j++) if (dims[j] != v->v_dims[j]) writedims = TRUE; } if (writedims) { dimstring(v->v_dims, v->v_numdims, buf); fprintf(fp, " dims=%s", buf); } (void) putc('\n', fp); } if (binary) { fprintf(fp, "Binary:\n"); for (i = 0; i < length; i++) { for (v = pl->pl_dvecs; v; v = v->v_next) { /* Don't run off the end of this vector's data. */ if (i < v->v_length) { if (realflag) { dd = (isreal(v) ? v->v_realdata[i] : realpart(v->v_compdata[i])); (void) fwrite(&dd, sizeof(double), 1, fp); } else if (isreal(v)) { dd = v->v_realdata[i]; (void) fwrite(&dd, sizeof(double), 1, fp); dd = 0.0; (void) fwrite(&dd, sizeof(double), 1, fp); } else { dd = realpart(v->v_compdata[i]); (void) fwrite(&dd, sizeof(double), 1, fp); dd = imagpart(v->v_compdata[i]); (void) fwrite(&dd, sizeof(double), 1, fp); } } else if (raw_padding) { dd = 0.0; if (realflag) { (void) fwrite(&dd, sizeof(double), 1, fp); } else { (void) fwrite(&dd, sizeof(double), 1, fp); (void) fwrite(&dd, sizeof(double), 1, fp); } } } } } else { fprintf(fp, "Values:\n"); for (i = 0; i < length; i++) { fprintf(fp, " %d", i); for (v = pl->pl_dvecs; v; v = v->v_next) { if (i < v->v_length) { if (realflag) fprintf(fp, "\t%.*e\n", prec, isreal(v) ? v->v_realdata[i] : realpart(v->v_compdata[i])); else if (isreal(v)) fprintf(fp, "\t%.*e,0.0\n", prec, v->v_realdata[i]); else fprintf(fp, "\t%.*e,%.*e\n", prec, realpart(v->v_compdata[i]), prec, imagpart(v->v_compdata[i])); } else if (raw_padding) { if (realflag) fprintf(fp, "\t%.*e\n", prec, 0.0); else fprintf(fp, "\t%.*e,%.*e\n", prec, 0.0, prec, 0.0); } } (void) putc('\n', fp); } } (void) fclose(fp); }
/* Evaluate a variable. */ wordlist * vareval(char *string) { struct variable *v; wordlist *wl; char buf[BSIZE_SP], *s; char *oldstring = copy(string); char *range = NULL; int i, up, low; cp_wstrip(string); if ((s = strchr(string, '[')) != NULL) { *s = '\0'; range = s + 1; } switch (*string) { case '$': wl = wl_cons(tprintf("%d", getpid()), NULL); tfree(oldstring); return (wl); case '<': (void) fflush(cp_out); if (!fgets(buf, BSIZE_SP, cp_in)) { clearerr(cp_in); (void) strcpy(buf, "EOF"); } for (s = buf; *s && (*s != '\n'); s++) ; *s = '\0'; wl = cp_lexer(buf); /* This is a hack. */ if (!wl->wl_word) wl->wl_word = copy(""); tfree(oldstring); return (wl); case '?': string++; for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break; if (!v) v = cp_enqvar(string); wl = wl_cons(copy(v ? "1" : "0"), NULL); tfree(oldstring); return (wl); case '#': string++; for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break; if (!v) v = cp_enqvar(string); if (!v) { fprintf(cp_err, "Error: %s: no such variable.\n", string); tfree(oldstring); return (NULL); } if (v->va_type == CP_LIST) for (v = v->va_vlist, i = 0; v; v = v->va_next) i++; else i = (v->va_type != CP_BOOL); wl = wl_cons(tprintf("%d", i), NULL); tfree(oldstring); return (wl); case '\0': wl = wl_cons(copy("$"), NULL); tfree(oldstring); return (wl); } /* The notation var[stuff] has two meanings... If this is a real * variable, then the [] denotes range, but if this is a strange * (e.g, device parameter) variable, it could be anything... */ for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break; if (!v && isdigit_c(*string)) { for (v = variables; v; v = v->va_next) if (eq(v->va_name, "argv")) break; range = string; } if (!v) { range = NULL; string = oldstring; v = cp_enqvar(string); } if (!v && (s = getenv(string)) != NULL) { wl = wl_cons(copy(s), NULL); tfree(oldstring); return (wl); } if (!v) { fprintf(cp_err, "Error: %s: no such variable.\n", string); tfree(oldstring); return (NULL); } wl = cp_varwl(v); /* Now parse and deal with 'range' ... */ if (range) { /* rather crude fix when range itself is a $expression */ wordlist *r = NULL; if (*range == '$') { char *t = ++range; if (*t == '&') t++; while (isalnum_c(*t)) t++; *t = '\0'; r = vareval(range); if (!r || r->wl_next) { fprintf(cp_err, "Error: %s: illegal index.\n", string); tfree(oldstring); wl_free(r); return NULL; } range = r->wl_word; } for (low = 0; isdigit_c(*range); range++) low = low * 10 + *range - '0'; if ((*range == '-') && isdigit_c(range[1])) for (up = 0, range++; isdigit_c(*range); range++) up = up * 10 + *range - '0'; else if (*range == '-') up = wl_length(wl); else up = low; up--, low--; wl = wl_range(wl, low, up); wl_free(r); } tfree(oldstring); return (wl); }