//static bool //nameeq(char *n1, char *n2) static int nameeq(char *n1, char *n2) { char buf1[BSIZE_SP], buf2[BSIZE_SP]; char *tmp; if (eq(n1, n2)) return (TRUE); /* n1 or n2 is in the form i(...) or I(...) * This happens in the saved rawfile */ if (ciprefix("i(", n1)) { tmp = n1; while (*tmp != '(') tmp++; tmp++; (void) strcpy(buf1, tmp); tmp = buf1; while (*tmp != ')') tmp++; *tmp = '\0'; (void) strcat(buf1, "#branch"); } else if (isdigit(*n1)) { (void) sprintf(buf1, "v(%s)", n1); } else { (void) strcpy(buf1, n1); } if (ciprefix("i(", n2)) { tmp = n2; while (*tmp != '(') tmp++; tmp++; (void) strcpy(buf2, tmp); tmp = buf2; while (*tmp != ')') tmp++; *tmp = '\0'; (void) strcat(buf2, "#branch"); } else if (isdigit(*n2)) { (void) sprintf(buf2, "v(%s)", n2); } else { (void) strcpy(buf2, n2); } return (cieq(buf1, buf2) ? TRUE : FALSE); }
static char * cannonical_name(char *name, SPICE_DSTRINGPTR dbuf_p) { char *tmp; /* position in string */ char *ptr; /* current position in string */ spice_dstring_reinit(dbuf_p); if (ciprefix("i(",name)) { tmp = name; while (*tmp != '(') tmp++; tmp++; for (ptr = tmp; *ptr; ptr++) if (isupper(*ptr)) tmp = spice_dstring_append_char(dbuf_p, (char)tolower(*ptr)); else tmp = spice_dstring_append_char(dbuf_p, *ptr); while (*tmp != ')') tmp++; *tmp = '\0'; tmp = spice_dstring_append(dbuf_p, "#branch", -1); } else if (isdigit(*name)) { spice_dstring_append(dbuf_p, "v(", -1); spice_dstring_append(dbuf_p, name, -1); tmp = spice_dstring_append_char(dbuf_p, ')'); } else { tmp = spice_dstring_append(dbuf_p, name, -1); } return(tmp); }
static struct plot * setcplot(char *name) { struct plot *pl; for (pl = plot_list; pl; pl = pl->pl_next) if (ciprefix(name, pl->pl_typename)) return pl; return NULL; }
void ft_savemeasure(void) { char *s; wordlist *iline; if (!ft_curckt) /* Shouldn't happen. */ return; for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next) { s = iline->wl_word; if (ciprefix(".measure", s)) { (void) measure_extract_variables(s); } } }
void ft_dotsaves() { wordlist *iline, *wl = NULL; char *s; if (!ft_curckt) /* Shouldn't happen. */ return; for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next) { if (ciprefix(".save", iline->wl_word)) { s = iline->wl_word; (void) gettok(&s); wl = wl_append(wl, gettoks(s)); } } com_save(wl); return; }
void ft_dotsaves(void) { wordlist *iline, *wl = NULL; char *s, *fr; if (!ft_curckt) /* Shouldn't happen. */ return; for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next) if (ciprefix(".save", iline->wl_word)) { s = iline->wl_word; /* skip .save */ fr = gettok(&s); tfree(fr); wl = wl_append(wl, gettoks(s)); } com_save(wl); wl_free(wl); }
struct line * inp_getopts(struct line *deck) { struct line *last = NULL, *opts = NULL, *dd, *next = NULL; for (dd = deck->li_next; dd; dd = next) { next = dd->li_next; if (ciprefix(".opt", dd->li_line)) { inp_casefix(dd->li_line); if (last) last->li_next = dd->li_next; else deck->li_next = dd->li_next; dd->li_next = opts; opts = dd; } else { last = dd; } } return (opts); }
int INP2dot(CKTcircuit *ckt, INPtables *tab, struct card *current, TSKtask *task, CKTnode *gnode) { /* .<something> Many possibilities */ char *token; /* a token from the line, tmalloc'ed */ JOB *foo = NULL; /* pointer to analysis */ /* the part of the current line left to parse */ char *line = current->line; int rtn = 0; INPgetTok(&line, &token, 1); if (strcmp(token, ".model") == 0) { /* don't have to do anything, since models were all done in * pass 1 */ goto quit; } else if ((strcmp(token, ".width") == 0) || strcmp(token, ".print") == 0 || strcmp(token, ".plot") == 0) { /* obsolete - ignore */ LITERR(" Warning: obsolete control card - ignored \n"); goto quit; } else if ((strcmp(token, ".temp") == 0)) { /* .temp temp1 temp2 temp3 temp4 ..... */ /* not yet implemented - warn & ignore */ /* LITERR(" Warning: .TEMP card obsolete - use .options TEMP and TNOM\n"); */ goto quit; } else if ((strcmp(token, ".op") == 0)) { rtn = dot_op(line, ckt, tab, current, task, gnode, foo); goto quit; } else if ((strcmp(token, ".nodeset") == 0)) { goto quit; } else if ((strcmp(token, ".disto") == 0)) { rtn = dot_disto(line, ckt, tab, current, task, gnode, foo); goto quit; } else if ((strcmp(token, ".noise") == 0)) { rtn = dot_noise(line, ckt, tab, current, task, gnode, foo); goto quit; } else if ((strcmp(token, ".four") == 0) || (strcmp(token, ".fourier") == 0)) { /* .four */ /* not implemented - warn & ignore */ LITERR("Use fourier command to obtain fourier analysis\n"); goto quit; } else if ((strcmp(token, ".ic") == 0)) { goto quit; } else if ((strcmp(token, ".ac") == 0)) { rtn = dot_ac(line, ckt, tab, current, task, gnode, foo); goto quit; } else if ((strcmp(token, ".pz") == 0)) { rtn = dot_pz(line, ckt, tab, current, task, gnode, foo); goto quit; } else if ((strcmp(token, ".dc") == 0)) { rtn = dot_dc(line, ckt, tab, current, task, gnode, foo); goto quit; } else if ((strcmp(token, ".tf") == 0)) { rtn = dot_tf(line, ckt, tab, current, task, gnode, foo); goto quit; } else if ((strcmp(token, ".tran") == 0)) { rtn = dot_tran(line, ckt, tab, current, task, gnode, foo); goto quit; #ifdef WITH_PSS /* SP: Steady State Analysis */ } else if ((strcmp(token, ".pss") == 0)) { rtn = dot_pss(line, ckt, tab, current, task, gnode, foo); goto quit; /* SP */ #endif } else if ((strcmp(token, ".subckt") == 0) || (strcmp(token, ".ends") == 0)) { /* not yet implemented - warn & ignore */ LITERR(" Warning: Subcircuits not yet implemented - ignored \n"); goto quit; } else if ((strcmp(token, ".end") == 0)) { /* .end - end of input */ /* not allowed to pay attention to additional input - return */ rtn = 1; goto quit; } else if (strcmp(token, ".sens") == 0) { rtn = dot_sens(line, ckt, tab, current, task, gnode, foo); goto quit; } #ifdef WANT_SENSE2 else if ((strcmp(token, ".sens2") == 0)) { rtn = dot_sens2(line, ckt, tab, current, task, gnode, foo); goto quit; } #endif else if ((strcmp(token, ".probe") == 0)) { /* Maybe generate a "probe" format file in the future. */ goto quit; } else if ((strcmp(token, ".options") == 0)|| (strcmp(token,".option")==0) || (strcmp(token,".opt")==0)) { rtn = dot_options(line, ckt, tab, current, task, gnode, foo); goto quit; } /* Added by H.Tanaka to find .global option */ else if (strcmp(token, ".global") == 0) { rtn = 0; LITERR(" Warning: .global not yet implemented - ignored \n"); goto quit; } /* ignore .meas statements -- these will be handled after analysis */ /* also ignore .param statements */ /* ignore .prot, .unprot */ else if (strcmp(token, ".meas") == 0 || ciprefix(".para", token) || strcmp(token, ".measure") == 0 || strcmp(token, ".prot") == 0 || strcmp(token, ".unprot") == 0) { rtn = 0; goto quit; } LITERR(" unimplemented control card - error \n"); quit: tfree(token); return rtn; }
static void dgen_next(dgen **dgx) { int done; dgen *dg; char *p; int need; wordlist *w; char type, *subckt, *device, *model; char *Top_Level = "\001"; int subckt_len; int head_match; char *word, *dev_name, *mod_name; dg = *dgx; if (!dg) return; /* Prime the "model only" or "device type only" iteration, * required because the filtering (below) may request additional * detail. */ if (!(dg->flags & DGEN_INSTANCE)) { if (!(dg->flags & DGEN_MODEL)) dg->model = NULL; dg->instance = NULL; } need = dg->flags; done = 0; while (!done) { if (dg->instance) { /* next instance */ dg->instance = dg->instance->GENnextInstance; } else if (dg->model) { dg->model = dg->model->GENnextModel; if (dg->model) dg->instance = dg->model->GENinstances; } else if (dg->dev_type_no < DEVmaxnum) { dg->dev_type_no += 1; if (dg->dev_type_no < DEVmaxnum) { dg->model = dg->ckt->CKThead[dg->dev_type_no]; if (dg->model) dg->instance = dg->model->GENinstances; } else { done = 2; break; } } else { done = 2; break; } if (need & DGEN_INSTANCE && !dg->instance) continue; if (need & DGEN_MODEL && !dg->model) continue; /* Filter */ if (!dg->dev_list) { if ((dg->flags & DGEN_ALLDEVS) || ((dg->flags & DGEN_DEFDEVS) && (ft_sim->devices[dg->dev_type_no]->flags & DEV_DEFAULT))) { done = 1; } else { done = 0; } continue; } done = 0; for (w = dg->dev_list; w && !done; w = w->wl_next) { /* assume a match (have to reset done every time * through */ done = 1; word = w->wl_word; if (!word || !*word) { break; } /* Break up word into type, subcircuit, model, device, * must be nodestructive to "word" */ /* type */ if (*word == ':' || *word == '#') type = '\0'; else type = *word++; /* subcircuit */ subckt = word; /* look for last ":" or "#" in word */ for (p = word + strlen(word) /* do '\0' first time */; p != word && *p != ':' && *p != '#'; p--) { ; } if (*p != ':' && *p != '#') { /* No subcircuit name specified */ subckt = NULL; subckt_len = 0; } else { if (p[-1] == ':') { head_match = 1; subckt_len = (int)(p - word) - 1; } else { head_match = 0; subckt_len = (int)(p - word); } if (subckt_len == 0) { /* Top level only */ if (head_match) subckt = NULL; else subckt = Top_Level; } word = p + 1; } /* model or device */ if (*p == '#') { model = word; device = NULL; } else { model = NULL; device = word; } /* Now compare */ if (dg->instance) dev_name = dg->instance->GENname; else dev_name = NULL; if (dg->model) mod_name = dg->model->GENmodName; else mod_name = NULL; if (type) { if (!dev_name) { done = 0; /*printf("No device.\n");*/ need |= DGEN_MODEL; continue; } else if (type != *dev_name) { done = 0; /*printf("Wrong type.\n");*/ /* Bleh ... plan breaks down here */ /* need = DGEN_TYPE; */ continue; } } if (subckt == Top_Level) { if (dev_name && dev_name[1] == ':') { need |= DGEN_INSTANCE; done = 0; /*printf("Wrong level.\n");*/ continue; } } else if (subckt && (!dev_name || !ciprefix(subckt, dev_name + 1))) { need |= DGEN_INSTANCE; done = 0; /*printf("Wrong subckt.\n"); */ continue; } if (device && *device) { need |= DGEN_INSTANCE | DGEN_MODEL; if (!dev_name) { done = 0; /*printf("Didn't get dev name.\n");*/ continue; } else if (strcmp(device, dev_name + 1 + subckt_len)) { done = 0; /*printf("Wrong name.\n");*/ continue; } } else if (model && *model) { if (strcmp(model, mod_name)) { done = 0; need |= DGEN_MODEL; /*printf("Wrong model name.\n");*/ continue; } } break; } } if (done == 2) *dgx = NULL; }
struct plot * raw_read(char *name) { char *title = "default title"; char *date = NULL; struct plot *plots = NULL, *curpl = NULL; char buf[BSIZE_SP], *s, *t, *r; int flags = 0, nvars = 0, npoints = 0, i, j; int ndimpoints, numdims = 0, dims[MAXDIMS]; bool raw_padded = TRUE, is_ascii = FALSE; double junk; struct dvec *v, *nv; struct variable *vv; wordlist *wl, *nwl; FILE *fp, *lastin, *lastout, *lasterr; if ((fp = fopen(name, "rb")) == NULL) { perror(name); controlled_exit(EXIT_FAILURE); } /* Since we call cp_evloop() from here, we have to do this junk. */ lastin = cp_curin; lastout = cp_curout; lasterr = cp_curerr; cp_curin = cp_in; cp_curout = cp_out; cp_curerr = cp_err; cp_pushcontrol(); while (fgets(buf, BSIZE_SP, fp)) { r = strchr(buf, '\n'); if (r && r > buf && r[-1] == '\r') { r[-1] = '\n'; r[0] = '\0'; } /* Figure out what this line is... */ if (ciprefix("title:", buf)) { s = buf; SKIP(s); NONL(s); title = copy(s); } else if (ciprefix("date:", buf)) { s = buf; SKIP(s); NONL(s); date = copy(s); } else if (ciprefix("plotname:", buf)) { s = buf; SKIP(s); NONL(s); if (curpl) { /* reverse commands list */ for (wl = curpl->pl_commands, curpl->pl_commands = NULL; wl && wl->wl_next; wl = nwl) { nwl = wl->wl_next; wl->wl_next = curpl->pl_commands; curpl->pl_commands = wl; } } curpl = alloc(struct plot); curpl->pl_next = plots; plots = curpl; curpl->pl_name = copy(s); if (!date) date = copy(datestring()); curpl->pl_date = date; curpl->pl_title = copy(title); flags = VF_PERMANENT; nvars = npoints = 0; } else if (ciprefix("flags:", buf)) {
static int iplot(struct plot *pl, int id) { int len = pl->pl_scale->v_length; struct dvec *v, *xs = pl->pl_scale; double *lims, dy; double start, stop, step; register int j; bool changed = FALSE; int yt; char *yl = NULL; double xlims[2], ylims[2]; static REQUEST reqst = { checkup_option, NULL }; int inited = 0; char commandline[513]; for (j = 0, v = pl->pl_dvecs; v; v = v->v_next) if (v->v_flags & VF_PLOT) j++; if (!j) return (0); if (ft_grdb) fprintf(cp_err, "Entering iplot, len = %d\n", len); if (len < IPOINTMIN) { /* Nothing yet */ return (0); } else if (len == IPOINTMIN || !id) { resumption = FALSE; /* Draw the grid for the first time, and plot everything. */ lims = ft_minmax(xs, TRUE); xlims[0] = lims[0]; xlims[1] = lims[1]; ylims[0] = HUGE; ylims[1] = - ylims[0]; for (v = pl->pl_dvecs; v; v = v->v_next) if (v->v_flags & VF_PLOT) { lims = ft_minmax(v, TRUE); if (ylims[0] > lims[0]) ylims[0] = lims[0]; if (ylims[1] < lims[1]) ylims[1] = lims[1]; if (!yl) yl = v->v_name; } /* generate a small difference between ymin and ymax to catch the y=const case */ if (ylims[0] == ylims[1]) ylims[1] += 1e-9; if (ft_grdb) fprintf(cp_err, "iplot: after 5, xlims = %G, %G, ylims = %G, %G\n", xlims[0], xlims[1], ylims[0], ylims[1]); for (yt = pl->pl_dvecs->v_type, v = pl->pl_dvecs->v_next; v; v = v->v_next) if ((v->v_flags & VF_PLOT) && (v->v_type != yt)) { yt = SV_NOTYPE; break; } /* note: have command options for iplot to specify xdelta, etc. So don't need static variables hack. Assume default values for now. */ sprintf(commandline, "plot %s", yl); (void) gr_init(xlims, ylims, xs->v_name, pl->pl_title, NULL, j, 0.0, 0.0, GRID_LIN, PLOT_LIN, xs->v_name, yl, xs->v_type, yt, plot_cur->pl_typename, commandline); for (v = pl->pl_dvecs; v; v = v->v_next) if (v->v_flags & VF_PLOT) { gr_start_internal(v, FALSE); ft_graf(v, xs, TRUE); } inited = 1; } else { /* plot the last points and resize if needed */ Input(&reqst, NULL); /* First see if we have to make the screen bigger */ dy = (isreal(xs) ? xs->v_realdata[len - 1] : realpart(xs->v_compdata[len - 1])); if (ft_grdb) fprintf(cp_err, "x = %G\n", dy); if (!if_tranparams(ft_curckt, &start, &stop, &step) || !ciprefix("tran", pl->pl_typename)) { stop = HUGE; start = - stop; } /* checking for x lo */ while (dy < currentgraph->data.xmin) { changed = TRUE; if (ft_grdb) fprintf(cp_err, "resize: xlo %G -> %G\n", currentgraph->data.xmin, currentgraph->data.xmin - (currentgraph->data.xmax - currentgraph->data.xmin) * XFACTOR); /* set the new x lo value */ currentgraph->data.xmin -= (currentgraph->data.xmax - currentgraph->data.xmin) * XFACTOR; if (currentgraph->data.xmin < start) { currentgraph->data.xmin = start; break; } } if (currentgraph->data.xmax < currentgraph->data.xmin) currentgraph->data.xmax = currentgraph->data.xmin; /* checking for x hi */ while (dy > currentgraph->data.xmax) { changed = TRUE; if (ft_grdb) fprintf(cp_err, "resize: xhi %G -> %G\n", currentgraph->data.xmax, currentgraph->data.xmax + (currentgraph->data.xmax - currentgraph->data.xmin) * XFACTOR); /* set the new x hi value */ currentgraph->data.xmax += (currentgraph->data.xmax - currentgraph->data.xmin) * XFACTOR; if (currentgraph->data.xmax > stop) { currentgraph->data.xmax = stop; break; } } /* checking for all y values */ for (v = pl->pl_dvecs; v; v = v->v_next) { if (!(v->v_flags & VF_PLOT)) continue; dy = (isreal(v) ? v->v_realdata[len - 1] : realpart(v->v_compdata[len - 1])); if (ft_grdb) fprintf(cp_err, "y = %G\n", dy); /* checking for y lo */ while (dy < currentgraph->data.ymin) { changed = TRUE; if (ft_grdb) fprintf(cp_err, "resize: ylo %G -> %G\n", currentgraph->data.ymin, currentgraph->data.ymin - (currentgraph->data.ymax - currentgraph->data.ymin) * YFACTOR); /* set the new y lo value */ currentgraph->data.ymin -= (currentgraph->data.ymax - currentgraph->data.ymin) * YFACTOR; /* currentgraph->data.ymin += (dy - currentgraph->data.ymin) * YFACTOR;*/ /* currentgraph->data.ymin = dy; currentgraph->data.ymin *= (1 + YFACTOR); */ } if (currentgraph->data.ymax < currentgraph->data.ymin) currentgraph->data.ymax = currentgraph->data.ymin; /* checking for y hi */ while (dy > currentgraph->data.ymax) { changed = TRUE; if (ft_grdb) fprintf(cp_err, "resize: yhi %G -> %G\n", currentgraph->data.ymax, currentgraph->data.ymax + (currentgraph->data.ymax - currentgraph->data.ymin) * YFACTOR); /* set the new y hi value */ currentgraph->data.ymax += (currentgraph->data.ymax - currentgraph->data.ymin) * YFACTOR; /* currentgraph->data.ymax += (dy - currentgraph->data.ymax) * YFACTOR;*/ /* currentgraph->data.ymax = dy; currentgraph->data.ymax *= (1 + YFACTOR); */ } } if (changed) { /* Redraw everything. */ gr_pmsg("Resizing screen"); gr_resize(currentgraph); #ifndef X_DISPLAY_MISSING gr_redraw(currentgraph); #endif } else { /* Just connect the last two points. This won't be done * with curve interpolation, so it might look funny. */ for (v = pl->pl_dvecs; v; v = v->v_next) if (v->v_flags & VF_PLOT) { gr_point(v, (isreal(xs) ? xs->v_realdata[len - 1] : realpart(xs->v_compdata[len - 1])), (isreal(v) ? v->v_realdata[len - 1] : realpart(v->v_compdata[len - 1])), (isreal(xs) ? xs->v_realdata[len - 2] : realpart(xs->v_compdata[len - 2])), (isreal(v) ? v->v_realdata[len - 2] : realpart(v->v_compdata[len - 2])), len - 1); } } } DevUpdate(); return (inited); }
int ft_savedotargs(void) { wordlist *w, *wl = NULL, *iline, **prev_wl, *w_next; char *name; char *s; int some = 0; static wordlist all = { "all", NULL, NULL }; int isaplot; int i; int status; if (!ft_curckt) /* Shouldn't happen. */ return 0; for (iline = ft_curckt->ci_commands; iline; iline = iline->wl_next) { s = iline->wl_word; if (ciprefix(".plot", s)) isaplot = 1; else isaplot = 0; if (isaplot || ciprefix(".print", s)) { (void) gettok(&s); name = gettok(&s); if ((w = gettoks(s)) == NULL) { fprintf(cp_err, "Warning: no nodes given: %s\n", iline->wl_word); } else { if (isaplot) { prev_wl = &w; for (wl = w; wl; wl = w_next) { w_next = wl->wl_next; for (i = 0; (size_t) i < NUMELEMS(plot_opts); i++) { if (!strcmp(wl->wl_word, plot_opts[i])) { /* skip it */ *prev_wl = w_next; tfree(wl); break; } } if (i == NUMELEMS(plot_opts)) prev_wl = &wl->wl_next; } } some = 1; com_save2(w, name); } } else if (ciprefix(".four", s)) { (void) gettok(&s); (void) gettok(&s); if ((w = gettoks(s)) == NULL) { fprintf(cp_err, "Warning: no nodes given: %s\n", iline->wl_word); } else { some = 1; com_save2(w, "TRAN"); /* A hack */ } } else if (ciprefix(".meas", s)) { status = measure_extract_variables(s); if (!(status)) { some = 1; } } else if (ciprefix(".op", s)) { some = 1; com_save2(&all, "OP"); } else if (ciprefix(".tf", s)) { some = 1; com_save2(&all, "TF"); } } return some; }
static char * fixem(char *string) { char buf[BSIZE_SP], *s, *t; char *ss = string; /* Get rid of ss ? */ if (ciprefix("v(", string) &&strchr(string, ',')) { for (s = string; *s && (*s != ','); s++) ; *s++ = '\0'; for (t = s; *t && (*t != ')'); t++) ; *t = '\0'; if (eq(s, "0")) (void) sprintf(buf, "v(%s)", string + 2); else if (eq(string + 2, "0")) (void) sprintf(buf, "-v(%s)", s); else (void) sprintf(buf, "v(%s)-v(%s)", string + 2, s); } else if (ciprefix("vm(", string) &&strchr(string, ',')) { for (s = string; *s && (*s != ','); s++) ; *s++ = '\0'; for (t = s; *t && (*t != ')'); t++) ; *t = '\0'; if (eq(s, "0")) (void) sprintf(buf, "mag(v(%s))", string + 3); else if (eq(string + 3, "0")) (void) sprintf(buf, "mag(-v(%s))", s); else (void) sprintf(buf, "mag(v(%s)-v(%s))", string + 3, s); } else if (ciprefix("vp(", string) &&strchr(string, ',')) { for (s = string; *s && (*s != ','); s++) ; *s++ = '\0'; for (t = s; *t && (*t != ')'); t++) ; *t = '\0'; if (eq(s, "0")) (void) sprintf(buf, "ph(v(%s))", string + 3); else if (eq(string + 3, "0")) (void) sprintf(buf, "ph(-v(%s))", s); else (void) sprintf(buf, "ph(v(%s)-v(%s))", string + 3, s); } else if (ciprefix("vi(", string) &&strchr(string, ',')) { for (s = string; *s && (*s != ','); s++) ; *s++ = '\0'; for (t = s; *t && (*t != ')'); t++) ; *t = '\0'; if (eq(s, "0")) (void) sprintf(buf, "imag(v(%s))", string + 3); else if (eq(string + 3, "0")) (void) sprintf(buf, "imag(-v(%s))", s); else (void) sprintf(buf, "imag(v(%s)-v(%s))", string + 3, s); } else if (ciprefix("vr(", string) &&strchr(string, ',')) { for (s = string; *s && (*s != ','); s++) ; *s++ = '\0'; for (t = s; *t && (*t != ')'); t++) ; *t = '\0'; if (eq(s, "0")) (void) sprintf(buf, "real(v(%s))", string + 3); else if (eq(string + 3, "0")) (void) sprintf(buf, "real(-v(%s))", s); else (void) sprintf(buf, "real(v(%s)-v(%s))", string + 3, s); } else if (ciprefix("vdb(", string) &&strchr(string, ',')) { for (s = string; *s && (*s != ','); s++) ; *s++ = '\0'; for (t = s; *t && (*t != ')'); t++) ; *t = '\0'; if (eq(s, "0")) (void) sprintf(buf, "db(v(%s))", string + 4); else if (eq(string + 4, "0")) (void) sprintf(buf, "db(-v(%s))", s); else (void) sprintf(buf, "db(v(%s)-v(%s))", string + 4, s); } else if (ciprefix("i(", string)) { for (s = string; *s && (*s != ')'); s++) ; *s = '\0'; string += 2; (void) sprintf(buf, "%s#branch", string); } else { return (string); } tfree(ss); string = copy(buf); return (string); }
int ft_cktcoms(bool terse) { wordlist *coms, *command, all; char *plottype, *s; struct dvec *v; static wordlist twl = { "col", NULL, NULL }; struct plot *pl; int i, found; char numbuf[BSIZE_SP]; /* For printnum*/ all.wl_next = NULL; all.wl_word = "all"; if (!ft_curckt) return 1; plot_cur = setcplot("op"); if (!ft_curckt->ci_commands && !plot_cur) goto nocmds; coms = ft_curckt->ci_commands; cp_interactive = FALSE; /* Listing */ if (ft_listprint) { if (terse) fprintf(cp_err, ".options: no listing, rawfile was generated.\n"); else inp_list(cp_out, ft_curckt->ci_deck, ft_curckt->ci_options, LS_DECK); } /* If there was a .op line, then we have to do the .op output. */ plot_cur = setcplot("op"); if (plot_cur != NULL) { assert(plot_cur->pl_dvecs != NULL); if (plot_cur->pl_dvecs->v_realdata != NULL) { if (terse) { fprintf(cp_out, "OP information in rawfile.\n"); } else { fprintf(cp_out, "\t%-30s%15s\n", "Node", "Voltage"); fprintf(cp_out, "\t%-30s%15s\n", "----", "-------"); fprintf(cp_out, "\t----\t-------\n"); for (v = plot_cur->pl_dvecs; v; v = v->v_next) { if (!isreal(v)) { fprintf(cp_err, "Internal error: op vector %s not real\n", v->v_name); continue; } if ((v->v_type == SV_VOLTAGE) && (*(v->v_name) != '@')) { printnum(numbuf, v->v_realdata[0]); fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf); } } fprintf(cp_out, "\n\tSource\tCurrent\n"); fprintf(cp_out, "\t------\t-------\n\n"); for (v = plot_cur->pl_dvecs; v; v = v->v_next) if (v->v_type == SV_CURRENT) { printnum(numbuf, v->v_realdata[0]); fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf); } fprintf(cp_out, "\n"); if (!ft_nomod) com_showmod(&all); com_show(&all); } } } for (pl = plot_list; pl; pl = pl->pl_next) if (ciprefix("tf", pl->pl_typename)) { if (terse) { fprintf(cp_out, "TF information in rawfile.\n"); break; } plot_cur = pl; fprintf(cp_out, "Transfer function information:\n"); com_print(&all); fprintf(cp_out, "\n"); } /* Now all the '.' lines */ while (coms) { command = cp_lexer(coms->wl_word); if (!command) goto bad; if (eq(command->wl_word, ".width")) { do command = command->wl_next; while (command && !ciprefix("out", command->wl_word)); if (command) { s = strchr(command->wl_word, '='); if (!s || !s[1]) { fprintf(cp_err, "Error: bad line %s\n", coms->wl_word); coms = coms->wl_next; continue; } i = atoi(++s); cp_vset("width", CP_NUM, &i); } } else if (eq(command->wl_word, ".print")) { if (terse) { fprintf(cp_out, ".print line ignored since rawfile was produced.\n"); } else { command = command->wl_next; if (!command) { fprintf(cp_err, "Error: bad line %s\n", coms->wl_word); coms = coms->wl_next; continue; } plottype = command->wl_word; command = command->wl_next; fixdotprint(command); twl.wl_next = command; found = 0; for (pl = plot_list; pl; pl = pl->pl_next) if (ciprefix(plottype, pl->pl_typename)) { plot_cur = pl; com_print(&twl); fprintf(cp_out, "\n"); found = 1; } if (!found) fprintf(cp_err, "Error: .print: no %s analysis found.\n", plottype); } } else if (eq(command->wl_word, ".plot")) { if (terse) { fprintf(cp_out, ".plot line ignored since rawfile was produced.\n"); } else { command = command->wl_next; if (!command) { fprintf(cp_err, "Error: bad line %s\n", coms->wl_word); coms = coms->wl_next; continue; } plottype = command->wl_word; command = command->wl_next; fixdotplot(command); found = 0; for (pl = plot_list; pl; pl = pl->pl_next) if (ciprefix(plottype, pl->pl_typename)) { plot_cur = pl; com_asciiplot(command); fprintf(cp_out, "\n"); found = 1; } if (!found) fprintf(cp_err, "Error: .plot: no %s analysis found.\n", plottype); } } else if (ciprefix(".four", command->wl_word)) { if (terse) { fprintf(cp_out, ".fourier line ignored since rawfile was produced.\n"); } else { int err; plot_cur = setcplot("tran"); err = fourier(command->wl_next, plot_cur); if (!err) fprintf(cp_out, "\n\n"); else fprintf(cp_err, "No transient data available for " "fourier analysis"); } } else if (!eq(command->wl_word, ".save") && !eq(command->wl_word, ".op") && // !eq(command->wl_word, ".measure") && !ciprefix(".meas", command->wl_word) && !eq(command->wl_word, ".tf")) { goto bad; } coms = coms->wl_next; } nocmds: /* Now the node table if (ft_nodesprint) ; */ /* The options */ if (ft_optsprint) { fprintf(cp_out, "Options:\n\n"); cp_vprint(); (void) putc('\n', cp_out); } /* And finally the accounting info. */ if (ft_acctprint) { static wordlist ww = { "everything", NULL, NULL }; com_rusage(&ww); } else if ((!ft_noacctprint) && (!ft_acctprint)) { com_rusage(NULL); } /* absolutely no accounting if noacct is given */ putc('\n', cp_out); return 0; bad: fprintf(cp_err, "Internal Error: ft_cktcoms: bad commands\n"); return 1; }
//void //inp_nutsource(FILE *fp, bool comfile, char *filename) void inp_nutsource(FILE *fp, int comfile, char *filename) { struct line *deck, *dd, *ld; struct line *realdeck, *options = NULL; char *tt = NULL, name[BSIZE_SP], *s, *t; //bool commands = FALSE; int commands = FALSE; wordlist *wl = NULL, *end = NULL; wordlist *controls = NULL; FILE *lastin, *lastout, *lasterr; deck = inp_readall(fp, NULL, comfile, FALSE); /* still to check if . or filename instead of NULL */ if (!deck) return; realdeck = inp_deckcopy(deck); if (!comfile) { /* Save the title before INPgetTitle gets it. */ tt = copy(deck->li_line); if (!deck->li_next) fprintf(cp_err, "Warning: no lines in deck...\n"); } (void) fclose(fp); /* Now save the IO context and start a new control set... After * we are done with the source we'll put the old file descriptors * back. I guess we could use a FILE stack, but since this routine * is recursive anyway... */ lastin = cp_curin; lastout = cp_curout; lasterr = cp_curerr; cp_curin = cp_in; cp_curout = cp_out; cp_curerr = cp_err; cp_pushcontrol(); /* We should now go through the deck and execute front-end * commands and remove them. Front-end commands are enclosed by * the lines .control and .endc, unless comfile * is TRUE, in which case every line must be a front-end command. * There are too many problems with matching the first word on * the line. */ ld = deck; if (comfile) { /* This is easy. */ for (dd = deck; dd; dd = ld) { ld = dd->li_next; if ((dd->li_line[0] == '*') && (dd->li_line[1] != '#')) continue; if (!ciprefix(".control", dd->li_line) && !ciprefix(".endc", dd->li_line)) { if (dd->li_line[0] == '*') (void) cp_evloop(dd->li_line + 2); else (void) cp_evloop(dd->li_line); } tfree(dd->li_line); tfree(dd); } } else { for (dd = deck->li_next; dd; dd = ld->li_next) { if ((dd->li_line[0] == '*') && (dd->li_line[1] != '#')) { ld = dd; continue; } (void) strncpy(name, dd->li_line, BSIZE_SP); for (s = name; *s && isspace(*s); s++) ; for (t = s; *t && !isspace(*t); t++) ; *t = '\0'; if (ciprefix(".control", dd->li_line)) { ld->li_next = dd->li_next; tfree(dd->li_line); tfree(dd); if (commands) fprintf(cp_err, "Warning: redundant .control line\n"); else commands = TRUE; } else if (ciprefix(".endc", dd->li_line)) { ld->li_next = dd->li_next; tfree(dd->li_line); tfree(dd); if (commands) commands = FALSE; else fprintf(cp_err, "Warning: misplaced .endc line\n"); } else if (commands || prefix("*#", dd->li_line)) { controls = wl_cons(NULL, controls); wl = controls; if (prefix("*#", dd->li_line)) wl->wl_word = copy(dd->li_line + 2); else wl->wl_word = dd->li_line; ld->li_next = dd->li_next; tfree(dd); } else if (!*dd->li_line) { /* So blank lines in com files don't get * considered as circuits. */ ld->li_next = dd->li_next; tfree(dd->li_line); tfree(dd); } else { inp_casefix(s); inp_casefix(dd->li_line); if (eq(s, ".width") || ciprefix(".four", s) || eq(s, ".plot") || eq(s, ".print") || eq(s, ".save")) { wl_append_word(&wl, &end, copy(dd->li_line)); ld->li_next = dd->li_next; tfree(dd->li_line); tfree(dd); } else { ld = dd; } } } if (deck->li_next) { /* There is something left after the controls. */ fprintf(cp_out, "\nCircuit: %s\n\n", tt); fprintf(stderr, "\nCircuit: %s\n\n", tt); /* Now expand subcircuit macros. Note that we have to * fix the case before we do this but after we * deal with the commands. */ if (!cp_getvar("nosubckt", CP_BOOL, NULL)) deck->li_next = inp_subcktexpand(deck->li_next); deck->li_actual = realdeck; nutinp_dodeck(deck, tt, wl, FALSE, options, filename); } /* Now that the deck is loaded, do the commands... */ controls = wl_reverse(controls); for (wl = controls; wl; wl = wl->wl_next) (void) cp_evloop(wl->wl_word); wl_free(controls); } /* Now reset everything. Pop the control stack, and fix up the IO * as it was before the source. */ cp_popcontrol(); cp_curin = lastin; cp_curout = lastout; cp_curerr = lasterr; tfree(tt); }
int NOISEan (CKTcircuit *ckt, int restart) { static Ndata *data; /* va, must be static, for continuation of * interrupted(Ctrl-C), longer lasting noise * analysis */ double realVal; double imagVal; int error; int posOutNode; int negOutNode; int step; IFuid freqUid; double freqTol; /* tolerence parameter for finding final frequency; hack */ int i, src_type; NOISEAN *job = (NOISEAN *) ckt->CKTcurJob; GENinstance *inst = CKTfndDev(ckt, job->input); posOutNode = (job->output) -> number; negOutNode = (job->outputRef) -> number; /* see if the source specified is AC */ { //bool ac_given = FALSE; int ac_given = FALSE; if (!inst || inst->GENmodPtr->GENmodType < 0) { SPfrontEnd->IFerrorf (ERR_WARNING, "Noise input source %s not in circuit", job->input); return E_NOTFOUND; } if (inst->GENmodPtr->GENmodType == CKTtypelook("Vsource")) { ac_given = ((VSRCinstance *)inst) -> VSRCacGiven; src_type = SV_VOLTAGE; } else if(inst->GENmodPtr->GENmodType == CKTtypelook("Isource")) { ac_given = ((ISRCinstance *)inst) -> ISRCacGiven; src_type = SV_CURRENT; } else { SPfrontEnd->IFerrorf (ERR_WARNING, "Noise input source %s is not of proper type", job->input); return E_NOTFOUND; } if (!ac_given) { SPfrontEnd->IFerrorf (ERR_WARNING, "Noise input source %s has no AC value", job->input); return E_NOACINPUT; } } if ( (job->NsavFstp == 0.0) || restart) { /* va, NsavFstp is double */ switch (job->NstpType) { case DECADE: job->NfreqDelta = exp(log(10.0)/ job->NnumSteps); break; case OCTAVE: job->NfreqDelta = exp(log(2.0)/ job->NnumSteps); break; case LINEAR: job->NfreqDelta = (job->NstopFreq - job->NstartFreq)/ (job->NnumSteps - 1); break; default: return(E_BADPARM); } /* error = DCop(ckt); */ error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, ckt->CKTdcMaxIter); if (error) return(error); /* Patch to noisean.c by Richard D. McRoberts. */ ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG; error = CKTload(ckt); if(error) return(error); data = TMALLOC(Ndata, 1); step = 0; data->freq = job->NstartFreq; data->outNoiz = 0.0; data->inNoise = 0.0; data->squared = cp_getvar("sqrnoise", CP_BOOL, NULL) ? 1 : 0; /* the current front-end needs the namelist to be fully declared before an OUTpBeginplot */ SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL); data->numPlots = 0; /* we don't have any plots yet */ error = CKTnoise(ckt,N_DENS,N_OPEN,data); if (error) return(error); /* * all names in the namelist have been declared. now start the * plot */ if (src_type == SV_VOLTAGE) fixme_inoise_type = data->squared ? SV_SQR_VOLTAGE_DENSITY : SV_VOLTAGE_DENSITY; else fixme_inoise_type = data->squared ? SV_SQR_CURRENT_DENSITY : SV_CURRENT_DENSITY; fixme_onoise_type = data->squared ? SV_SQR_VOLTAGE_DENSITY : SV_VOLTAGE_DENSITY; if (!data->squared) for (i = 0; i < data->numPlots; i++) data->squared_value[i] = ciprefix("inoise", data->namelist[i]) || ciprefix("onoise", data->namelist[i]); error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob, data->squared ? "Noise Spectral Density Curves - (V^2 or A^2)/Hz" : "Noise Spectral Density Curves", freqUid, IF_REAL, data->numPlots, data->namelist, IF_REAL, &(data->NplotPtr)); if (error) return(error); if (job->NstpType != LINEAR) { SPfrontEnd->OUTattributes (data->NplotPtr, NULL, OUT_SCALE_LOG, NULL); } } else { /* we must have paused before. pick up where we left off */ step = (int)(job->NsavFstp); switch (job->NstpType) { case DECADE: case OCTAVE: data->freq = job->NstartFreq * exp (step * log (job->NfreqDelta)); break; case LINEAR: data->freq = job->NstartFreq + step * job->NfreqDelta; break; default: return(E_BADPARM); } job->NsavFstp = 0; data->outNoiz = job->NsavOnoise; data->inNoise = job->NsavInoise; /* saj resume rawfile fix*/ error = SPfrontEnd->OUTpBeginPlot (NULL, NULL, NULL, NULL, 0, 666, NULL, 666, &(data->NplotPtr)); /*saj*/ } switch (job->NstpType) { case DECADE: case OCTAVE: freqTol = job->NfreqDelta * job->NstopFreq * ckt->CKTreltol; break; case LINEAR: freqTol = job->NfreqDelta * ckt->CKTreltol; break; default: return(E_BADPARM); } data->lstFreq = data->freq; /* do the noise analysis over all frequencies */ while (data->freq <= job->NstopFreq + freqTol) { if(SPfrontEnd->IFpauseTest()) { job->NsavFstp = step; /* save our results */ job->NsavOnoise = data->outNoiz; /* up until now */ job->NsavInoise = data->inNoise; return (E_PAUSE); } ckt->CKTomega = 2.0 * M_PI * data->freq; ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEAC | MODEACNOISE; ckt->noise_input = inst; /* * solve the original AC system to get the transfer * function between the input and output */ NIacIter(ckt); realVal = ckt->CKTrhsOld [posOutNode] - ckt->CKTrhsOld [negOutNode]; imagVal = ckt->CKTirhsOld [posOutNode] - ckt->CKTirhsOld [negOutNode]; data->GainSqInv = 1.0 / MAX(((realVal*realVal) + (imagVal*imagVal)),N_MINGAIN); data->lnGainInv = log(data->GainSqInv); /* set up a block of "common" data so we don't have to * recalculate it for every device */ data->delFreq = data->freq - data->lstFreq; data->lnFreq = log(MAX(data->freq,N_MINLOG)); data->lnLastFreq = log(MAX(data->lstFreq,N_MINLOG)); data->delLnFreq = data->lnFreq - data->lnLastFreq; if ((job->NStpsSm != 0) && ((step % (job->NStpsSm)) == 0)) { data->prtSummary = TRUE; } else { data->prtSummary = FALSE; } /* data->outNumber = 1; */ data->outNumber = 0; /* the frequency will NOT be stored in array[0] as before; instead, * it will be given in refVal.rValue (see later) */ NInzIter(ckt,posOutNode,negOutNode); /* solve the adjoint system */ /* now we use the adjoint system to calculate the noise * contributions of each generator in the circuit */ error = CKTnoise(ckt,N_DENS,N_CALC,data); if (error) return(error); data->lstFreq = data->freq; /* update the frequency */ switch (job->NstpType) { case DECADE: case OCTAVE: data->freq *= job->NfreqDelta; break; case LINEAR: data->freq += job->NfreqDelta; break; default: return(E_INTERN); } step++; } error = CKTnoise(ckt,N_DENS,N_CLOSE,data); if (error) return(error); data->numPlots = 0; data->outNumber = 0; if (job->NstartFreq != job->NstopFreq) { error = CKTnoise(ckt,INT_NOIZ,N_OPEN,data); if (error) return(error); if (src_type == SV_VOLTAGE) fixme_inoise_type = data->squared ? SV_SQR_VOLTAGE : SV_VOLTAGE; else fixme_inoise_type = data->squared ? SV_SQR_CURRENT : SV_CURRENT; fixme_onoise_type = data->squared ? SV_SQR_VOLTAGE : SV_VOLTAGE; if (!data->squared) for (i = 0; i < data->numPlots; i++) data->squared_value[i] = ciprefix("inoise", data->namelist[i]) || ciprefix("onoise", data->namelist[i]); SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob, data->squared ? "Integrated Noise - V^2 or A^2" : "Integrated Noise", NULL, 0, data->numPlots, data->namelist, IF_REAL, &(data->NplotPtr)); error = CKTnoise(ckt,INT_NOIZ,N_CALC,data); if (error) return(error); error = CKTnoise(ckt,INT_NOIZ,N_CLOSE,data); if (error) return(error); } FREE(data); return(OK); }