📄 postcoms.c
字号:
/**********Copyright 1990 Regents of the University of California. All rights reserved.Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group **********//* * Various post-processor commands having to do with vectors. */#include "spice.h"#include "util.h"#include "misc.h"#include "cpdefs.h"#include "ftedefs.h"#include "fteparse.h"#include "ftedata.h"#include "suffix.h"static int dcomp();static void pvec();static void killplot( );voidcom_let(wl) wordlist *wl;{ char *p, *q, *s; int indices[MAXDIMS]; int numdims; wordlist fake_wl; int need_open; int offset, length; struct pnode *nn; struct dvec *n, *t; int i, cube; int j, depth; int newvec; char *rhs; fake_wl.wl_next = NULL; if (!wl) { com_display((wordlist *) NULL); return; } p = wl_flatten(wl); /* extract indices */ numdims = 0; if (rhs = index(p, '=')) { *rhs++ = 0; } else { fprintf(cp_err, "Error: bad let syntax\n"); return; } if (s = index(p, '[')) { need_open = 0; *s++ = 0; while (!need_open || *s == '[') { depth = 0; if (need_open) s++; for (q = s; *q && (*q != ']' && *q != ',' || depth > 0); q++) { switch (*q) { case '[': depth += 1; break; case ']': depth -= 1; break; } } if (depth != 0 || !*q) { printf("syntax error specifying index\n"); return; } if (*q == ']') need_open = 1; else need_open = 0; if (*q) *q++ = 0; /* evaluate expression between s and q */ fake_wl.wl_word = s; nn = ft_getpnames(&fake_wl, true); t = ft_evaluate(nn); free_pnode(nn); if (!isreal(t) || t->v_link2 || t->v_length != 1 || !t->v_realdata) { fprintf(cp_err, "Error: index is not a scalar.\n"); tfree(p); return; } j = t->v_realdata[0]; /* ignore sanity checks for now */ if (j < 0) { printf("negative index (%d) is not allowed\n", j); tfree(p); /* XXX free data */ return; } indices[numdims++] = j; for (s = q; *s && isspace(*s); s++) ; } } /* vector name at p */ for (q = p + strlen(p) - 1; *q <= ' ' && p <= q; q--) ; *++q = 0; /* sanity check */ if (eq(p, "all") || index(p, '@')) { fprintf(cp_err, "Error: bad variable name %s\n", p); return; } /* evaluate rhs */ fake_wl.wl_word = rhs; nn = ft_getpnames(&fake_wl, true); if (nn == NULL) { /* XXX error message */ tfree(p); return; } t = ft_evaluate(nn); if (!t) { /* XXX error message */ tfree(p); return; } if (t->v_link2) fprintf(cp_err, "Warning: extra wildcard values ignored\n"); n = vec_get(p); if (n) { /* re-allocate? */ /* vec_free(n); */ newvec = 0; } else { if (numdims) { fprintf(cp_err, "Can't assign into a subindex of a new vector\n"); tfree(p); return; } /* create and assign a new vector */ n = alloc(struct dvec); ZERO(n, struct dvec); n->v_name = copy(p); n->v_type = t->v_type; n->v_flags = (t->v_flags | VF_PERMANENT); n->v_length = t->v_length; if (!t->v_numdims) { n->v_numdims = 1; n->v_dims[0] = n->v_length; } else { n->v_numdims = t->v_numdims; for (i = 0; i < t->v_numdims; i++) n->v_dims[i] = t->v_dims[i]; } if (isreal(t)) n->v_realdata = (double *) tmalloc(n->v_length * sizeof(double)); else n->v_compdata = (complex *) tmalloc(n->v_length * sizeof(complex)); newvec = 1; vec_new(n); } /* fix-up dimensions */ if (n->v_numdims < 1) { n->v_numdims = 1; n->v_dims[0] = n->v_length; } /* Compare dimensions */ offset = 0; length = n->v_length; cube = 1; for (i = n->v_numdims - 1; i >= numdims; i--) cube *= n->v_dims[i]; for (i = numdims - 1; i >= 0; i--) { offset += cube * indices[i]; if (i < n->v_numdims) { cube *= n->v_dims[i]; length /= n->v_dims[i]; } } /* length is the size of the unit refered to */ /* cube ends up being the length */ if (length > t->v_length) { fprintf(cp_err, "left-hand expression is too small (need %d)\n", length * cube); if (newvec) n->v_flags &= ~VF_PERMANENT; tfree(p); return; } if (isreal(t) != isreal(n)) { fprintf(cp_err, "Types of vectors are not the same (real vs. complex)\n"); if (newvec) n->v_flags &= ~VF_PERMANENT; tfree(p); return; } else if (isreal(t)) { bcopy((char *) t->v_realdata, (char *) (n->v_realdata + offset), length * sizeof (double)); } else { bcopy((char *) t->v_compdata, (char *) (n->v_compdata + offset), length * sizeof (complex)); } n->v_minsignal = 0.0; /* How do these get reset ??? */ n->v_maxsignal = 0.0; n->v_scale = t->v_scale; if (newvec) cp_addkword(CT_VECTOR, n->v_name); /* XXXX Free t !?! */ tfree(p); return;}/* Undefine vectors. */voidcom_unlet(wl) wordlist *wl;{ while (wl) { vec_remove(wl->wl_word); wl = wl->wl_next; } return;}/* Load in a file. */voidcom_load(wl) wordlist *wl;{ if (!wl) ft_loadfile(ft_rawfile); else while (wl) { ft_loadfile(cp_unquote(wl->wl_word)); wl = wl->wl_next; } /* note: default is to display the vectors in the last (current) plot */ com_display(NULL); return;}/* Print out the value of an expression. When we are figuring out what to * print, link the vectors we want with v_link2... This has to be done * because of the way temporary vectors are linked together with permanent * ones under the plot. */voidcom_print(wl) wordlist *wl;{ struct dvec *v, *lv, *bv, *nv, *vecs = NULL; int i, j, ll, width = DEF_WIDTH, height = DEF_HEIGHT, npoints, lineno; struct pnode *nn; struct plot *p; bool col = true, nobreak = false, noprintscale, plotnames = false; bool optgiven = false; char *s, buf[BSIZE_SP], buf2[BSIZE_SP]; int ngood; if (wl == NULL) return; if (eq(wl->wl_word, "col")) { col = true; optgiven = true; wl = wl->wl_next; } else if (eq(wl->wl_word, "line")) { col = false; optgiven = true; wl = wl->wl_next; } ngood = 0; for (nn = ft_getpnames(wl, true); nn; nn = nn->pn_next) { if (!(v = ft_evaluate(nn))) continue; if (!vecs) vecs = lv = v; else lv->v_link2 = v; for (lv = v; lv->v_link2; lv = lv->v_link2) ; ngood += 1; } if (!ngood) return; /* See whether we really have to print plot names. */ for (v = vecs; v; v = v->v_link2) if (vecs->v_plot != v->v_plot) { plotnames = true; break; } if (!optgiven) { /* Figure out whether col or line should be used... */ col = false; for (v = vecs; v; v = v->v_link2) if (v->v_length > 1) { col = true; break; } } out_init(); if (!col) { for (v = vecs; v; v = v->v_link2) { if (plotnames) { (void) sprintf(buf, "%s.%s", v->v_plot->pl_typename, vec_basename(v)); } else { (void) strcpy(buf, vec_basename(v)); } for (s = buf; *s; s++) ; s--; while (isspace(*s)) { *s = '\0'; s--; } ll = 10; if (v->v_length == 1) { if (isreal(v)) { out_printf("%s = %s\n", buf, printnum(*v->v_realdata)); } else { out_printf("%s = %s,%s\n", buf, copy(printnum(realpart(v->v_compdata))), copy(printnum(imagpart(v->v_compdata)))); } } else { out_printf("%s = ( ", buf); for (i = 0; i < v->v_length; i++) if (isreal(v)) { (void) strcpy(buf, printnum(v->v_realdata[i])); out_send(buf); ll += strlen(buf); ll = (ll + 7) / 8; ll = ll * 8 + 1; if (ll > 60) { out_send("\n\t"); ll = 9; } else out_send("\t"); } else { (void) sprintf(buf, "%s,%s", copy(printnum(realpart(&v->v_compdata[i]))), copy(printnum(imagpart(&v->v_compdata[i])))); out_send(buf); ll += strlen(buf); ll = (ll + 7) / 8; ll = ll * 8 + 1; if (ll > 60) { out_send("\n\t"); ll = 9; } else out_send("\t"); } out_send(")\n"); } } } else { /* Print in columns. */ if (cp_getvar("width", VT_NUM, (char *) &i)) width = i; if (width < 40) width = 40; if (cp_getvar("height", VT_NUM, (char *) &i)) height = i; if (height < 20) height = 20; if (!cp_getvar("nobreak", VT_BOOL, (char *) &nobreak) && !ft_nopage) nobreak = false; else nobreak = true; (void) cp_getvar("noprintscale", VT_BOOL, (char *) &noprintscale); bv = vecs;nextpage: /* Make the first vector of every page be the scale... */ /* XXX But what if there is no scale? e.g. op, pz */ if (!noprintscale && bv->v_plot->pl_ndims) { if (bv->v_plot->pl_scale && !vec_eq(bv, bv->v_plot->pl_scale)) { nv = vec_copy(bv->v_plot->pl_scale); vec_new(nv); nv->v_link2 = bv; bv = nv; } } ll = 8; for (lv = bv; lv; lv = lv->v_link2) { if (isreal(lv)) ll += 16; /* Two tabs for real, */ else ll += 32; /* 4 for complex. */ /* Make sure we have at least 2 vectors per page... */ if ((ll > width) && (lv != bv) && (lv != bv->v_link2)) break; } /* Print the header on the first page only. */ p = bv->v_plot; j = (width - (int) strlen(p->pl_title)) / 2; /* Yes, keep "(int)" */ if (j < 0) j = 0; for (i = 0; i < j; i++) buf2[i] = ' '; buf2[j] = '\0'; out_send(buf2); out_send(p->pl_title); out_send("\n"); out_send(buf2); (void) sprintf(buf, "%s %s", p->pl_name, p->pl_date); j = (width - strlen(buf)) / 2; out_send(buf); out_send("\n"); for (i = 0; i < width; i++) buf2[i] = '-'; buf2[width] = '\n'; buf2[width+1] = '\0'; out_send(buf2); (void) sprintf(buf, "Index "); for (v = bv; v && (v != lv); v = v->v_link2) { if (isreal(v)) (void) sprintf(buf2, "%-16.15s", v->v_name); else (void) sprintf(buf2, "%-32.31s", v->v_name); (void) strcat(buf, buf2); } lineno = 3; j = 0; npoints = 0; for (v = bv; (v && (v != lv)); v = v->v_link2) if (v->v_length > npoints) npoints = v->v_length;pbreak: /* New page. */ out_send(buf); out_send("\n"); for (i = 0; i < width; i++) buf2[i] = '-'; buf2[width] = '\n'; buf2[width+1] = '\0'; out_send(buf2); lineno += 2;loop: while ((j < npoints) && (lineno < height)) {/* out_printf("%d\t", j); */ sprintf(out_pbuf, "%d\t", j); out_send(out_pbuf); for (v = bv; (v && (v != lv)); v = v->v_link2) { if (v->v_length <= j) { if (isreal(v)) out_send("\t\t"); else out_send("\t\t\t\t"); } else { if (isreal(v)) { sprintf(out_pbuf, "%e\t", v->v_realdata[j]); out_send(out_pbuf); } else { sprintf(out_pbuf, "%e,\t%e\t", realpart(&v->v_compdata[j]), imagpart(&v->v_compdata[j])); out_send(out_pbuf); } } } out_send("\n"); j++; lineno++; } if ((j == npoints) && (lv == NULL)) /* No more to print. */ goto done; if (j == npoints) { /* More vectors to print. */ bv = lv; out_send("\f\n"); /* Form feed. */ goto nextpage; } /* Otherwise go to a new page. */ lineno = 0; if (nobreak) goto loop; else out_send("\f\n"); /* Form feed. */ goto pbreak; }done: /* Get rid of the vectors. */ return;}/* Write out some data. write filename expr ... Some cleverness here is * required. If the user mentions a few vectors from various plots, * probably he means for them to be written out seperate plots. In any * case, we have to be sure to write out the scales for everything we * write... */voidcom_write(wl) wordlist *wl;{ char *file, buf[BSIZE_SP]; struct pnode *n; struct dvec *d, *vecs = NULL, *lv = NULL, *end, *vv; static wordlist all = { "all", NULL, NULL } ; struct pnode *names; bool ascii = AsciiRawFile; bool scalefound, appendwrite; struct plot *tpl, newplot; if (wl) { file = wl->wl_word; wl = wl->wl_next; } else file = ft_rawfile; if (cp_getvar("filetype", VT_STRING, buf)) { if (eq(buf, "binary")) ascii = false; else if (eq(buf, "ascii")) ascii = true; else fprintf(cp_err, "Warning: strange file type %s\n", buf); } (void) cp_getvar("appendwrite", VT_BOOL, (char *) &appendwrite); if (wl) names = ft_getpnames(wl, true);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -