/* data printout to file plotargs */ void com_write_simple(wordlist *wl) { char *fname = NULL; bool tempf = FALSE; if (wl) { fname = wl->wl_word; wl = wl->wl_next; } if (!wl) return; if (cieq(fname, "temp") || cieq(fname, "tmp")) { fname = smktemp("gp"); /* Is this the correct name ? */ tempf = TRUE; } (void) plotit(wl, fname, "writesimple"); /* Leave temp file sitting around so gnuplot can grab it from background. */ if (tempf) tfree(fname); }
struct plot * plot_alloc(char *name) { struct plot *pl = alloc(struct plot), *tp; char *s; struct ccom *ccom; char buf[BSIZE_SP]; ZERO(pl, struct plot); if ((s = ft_plotabbrev(name)) == NULL) s = "unknown"; do { (void) sprintf(buf, "%s%d", s, plot_num); for (tp = plot_list; tp; tp = tp->pl_next) if (cieq(tp->pl_typename, buf)) { plot_num++; break; } } while (tp); pl->pl_typename = copy(buf); cp_addkword(CT_PLOT, buf); /* va: create a new, empty keyword tree for class CT_VECTOR, s=old tree */ ccom = cp_kwswitch(CT_VECTOR, NULL); cp_addkword(CT_VECTOR, "all"); pl->pl_ccom = cp_kwswitch(CT_VECTOR, ccom); /* va: keyword tree is old tree again, new tree is linked to pl->pl_ccom */ return (pl); }
void plot_add(struct plot *pl) { struct dvec *v; struct plot *tp; char *s, buf[BSIZE_SP]; fprintf(cp_out, "Title: %s\nName: %s\nDate: %s\n\n", pl->pl_title, pl->pl_name, pl->pl_date); if (plot_cur) plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom); for (v = pl->pl_dvecs; v; v = v->v_next) cp_addkword(CT_VECTOR, v->v_name); cp_addkword(CT_VECTOR, "all"); if ((s = ft_plotabbrev(pl->pl_name)) == NULL) s = "unknown"; do { (void) sprintf(buf, "%s%d", s, plot_num); for (tp = plot_list; tp; tp = tp->pl_next) if (cieq(tp->pl_typename, buf)) { plot_num++; break; } } while (tp); pl->pl_typename = copy(buf); plot_new(pl); cp_addkword(CT_PLOT, buf); pl->pl_ccom = cp_kwswitch(CT_VECTOR, NULL); plot_setcur(pl->pl_typename); }
void plot_setcur(char *name) { struct plot *pl; if (cieq(name, "new")) { pl = plot_alloc("unknown"); pl->pl_title = copy("Anonymous"); pl->pl_name = copy("unknown"); pl->pl_date = copy(datestring()); plot_new(pl); plot_cur = pl; return; } for (pl = plot_list; pl; pl = pl->pl_next) if (plot_prefix(name, pl->pl_typename)) break; if (!pl) { fprintf(cp_err, "Error: no such plot named %s\n", name); return; } /* va: we skip cp_kwswitch, because it confuses the keyword-tree management for * repeated op-commands. When however cp_kwswitch is necessary for other * reasons, we should hold the original keyword table pointer in an * permanent variable, since it will lost here, and can never tfree'd. if (plot_cur) { plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom); } */ plot_cur = pl; }
/* Callback function called from bg thread in ngspice once upon intialization of the simulation vectors)*/ int ng_initdata(pvecinfoall intdata, void* userdata) { int i; int vn = intdata->veccount; for (i = 0; i < vn; i++) { printf("Vector: %s\n", intdata->vecs[i]->vecname); /* find the location of V(2) */ if (cieq(intdata->vecs[i]->vecname, "V(2)")) vecgetnumber = i; } return 0; }
//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); }
void vec_remove(char *name) { struct dvec *ov; for (ov = plot_cur->pl_dvecs; ov; ov = ov->v_next) if (cieq(name, ov->v_name) && (ov->v_flags & VF_PERMANENT)) break; if (!ov) return; ov->v_flags &= ~VF_PERMANENT; /* Remove from the keyword list. */ cp_remkword(CT_VECTOR, name); }
bool vec_eq(struct dvec *v1, struct dvec *v2) { char *s1, *s2; bool rtn; if (v1->v_plot != v2->v_plot) return (FALSE); s1 = vec_basename(v1); s2 = vec_basename(v2); if (cieq(s1, s2)) rtn = TRUE; else rtn = FALSE; tfree(s1); tfree(s2); return rtn; }
char * vec_basename(struct dvec *v) { char buf[BSIZE_SP], *t, *s; if (strchr(v->v_name, '.')) { if (cieq(v->v_plot->pl_typename, v->v_name)) (void) strcpy(buf, v->v_name + strlen(v->v_name) + 1); else (void) strcpy(buf, v->v_name); } else { (void) strcpy(buf, v->v_name); } strtolower(buf); for (t = buf; isspace(*t); t++) ; s = t; for (t = s; *t; t++) ; while ((t > s) && isspace(t[-1])) *--t = '\0'; return (copy(s)); }
static int beginPlot(JOB *analysisPtr, CKTcircuit *circuitPtr, char *cktName, char *analName, char *refName, int refType, int numNames, char **dataNames, int dataType, bool windowed, runDesc **runp) { runDesc *run; struct save_info *saves; bool *savesused = NULL; int numsaves; int i, j, depind = 0; char namebuf[BSIZE_SP], parambuf[BSIZE_SP], depbuf[BSIZE_SP]; char *ch, tmpname[BSIZE_SP]; bool saveall = TRUE; bool savealli = FALSE; char *an_name; /*to resume a run saj *All it does is reassign the file pointer and return (requires *runp to be NULL if this is not needed) */ if (dataType == 666 && numNames == 666) { run = *runp; run->writeOut = ft_getOutReq(&run->fp, &run->runPlot, &run->binary, run->type, run->name); } else { /*end saj*/ /* Check to see if we want to print informational data. */ if (cp_getvar("printinfo", CP_BOOL, NULL)) fprintf(cp_err, "(debug printing enabled)\n"); /* Check to see if we want to save only interpolated data. */ if (cp_getvar("interp", CP_BOOL, NULL)) { interpolated = TRUE; fprintf(cp_out, "Warning: Interpolated raw file data!\n\n"); } *runp = run = TMALLOC(struct runDesc, 1); /* First fill in some general information. */ run->analysis = analysisPtr; run->circuit = circuitPtr; run->name = copy(cktName); run->type = copy(analName); run->windowed = windowed; run->numData = 0; an_name = spice_analysis_get_name(analysisPtr->JOBtype); ft_curckt->ci_last_an = an_name; /* Now let's see which of these things we need. First toss in the * reference vector. Then toss in anything that getSaves() tells * us to save that we can find in the name list. Finally unpack * the remaining saves into parameters. */ numsaves = ft_getSaves(&saves); if (numsaves) { savesused = TMALLOC(bool, numsaves); saveall = FALSE; for (i = 0; i < numsaves; i++) { if (saves[i].analysis && !cieq(saves[i].analysis, an_name)) { /* ignore this one this time around */ savesused[i] = TRUE; continue; } /* Check for ".save all" and new synonym ".save allv" */ if (cieq(saves[i].name, "all") || cieq(saves[i].name, "allv")) { saveall = TRUE; savesused[i] = TRUE; saves[i].used = 1; continue; } /* And now for the new ".save alli" option */ if (cieq(saves[i].name, "alli")) { savealli = TRUE; savesused[i] = TRUE; saves[i].used = 1; continue; } } } /* Pass 0. */ if (refName) { addDataDesc(run, refName, refType, -1); for (i = 0; i < numsaves; i++) if (!savesused[i] && name_eq(saves[i].name, refName)) { savesused[i] = TRUE; saves[i].used = 1; } } else { run->refIndex = -1; } /* Pass 1. */ if (numsaves && !saveall) { for (i = 0; i < numsaves; i++) if (!savesused[i]) for (j = 0; j < numNames; j++) if (name_eq(saves[i].name, dataNames[j])) { addDataDesc(run, dataNames[j], dataType, j); savesused[i] = TRUE; saves[i].used = 1; break; } } else { for (i = 0; i < numNames; i++) if (!refName || !name_eq(dataNames[i], refName)) /* Save the node as long as it's an internal device node */ if (!strstr(dataNames[i], "#internal") && !strstr(dataNames[i], "#source") && !strstr(dataNames[i], "#drain") && !strstr(dataNames[i], "#collector") && !strstr(dataNames[i], "#emitter") && !strstr(dataNames[i], "#base")) { addDataDesc(run, dataNames[i], dataType, i); } } /* Pass 1 and a bit. This is a new pass which searches for all the internal device nodes, and saves the terminal currents instead */ if (savealli) { depind = 0; for (i = 0; i < numNames; i++) { if (strstr(dataNames[i], "#internal") || strstr(dataNames[i], "#source") || strstr(dataNames[i], "#drain") || strstr(dataNames[i], "#collector") || strstr(dataNames[i], "#emitter") || strstr(dataNames[i], "#base")) { tmpname[0] = '@'; tmpname[1] = '\0'; strncat(tmpname, dataNames[i], BSIZE_SP-1); ch = strchr(tmpname, '#'); if (strstr(ch, "#collector")) { strcpy(ch, "[ic]"); } else if (strstr(ch, "#base")) { strcpy(ch, "[ib]"); } else if (strstr(ch, "#emitter")) { strcpy(ch, "[ie]"); if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) addSpecialDesc(run, tmpname, namebuf, parambuf, depind); strcpy(ch, "[is]"); } else if (strstr(ch, "#drain")) { strcpy(ch, "[id]"); if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) addSpecialDesc(run, tmpname, namebuf, parambuf, depind); strcpy(ch, "[ig]"); } else if (strstr(ch, "#source")) { strcpy(ch, "[is]"); if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) addSpecialDesc(run, tmpname, namebuf, parambuf, depind); strcpy(ch, "[ib]"); } else if (strstr(ch, "#internal") && (tmpname[1] == 'd')) { strcpy(ch, "[id]"); } else { fprintf(cp_err, "Debug: could output current for %s\n", tmpname); continue; } if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) { if (*depbuf) { fprintf(stderr, "Warning : unexpected dependent variable on %s\n", tmpname); } else { addSpecialDesc(run, tmpname, namebuf, parambuf, depind); } } } } } /* Pass 2. */ for (i = 0; i < numsaves; i++) { if (savesused[i]) continue; if (!parseSpecial(saves[i].name, namebuf, parambuf, depbuf)) { if (saves[i].analysis) fprintf(cp_err, "Warning: can't parse '%s': ignored\n", saves[i].name); continue; } /* Now, if there's a dep variable, do we already have it? */ if (*depbuf) { for (j = 0; j < run->numData; j++) if (name_eq(depbuf, run->data[j].name)) break; if (j == run->numData) { /* Better add it. */ for (j = 0; j < numNames; j++) if (name_eq(depbuf, dataNames[j])) break; if (j == numNames) { fprintf(cp_err, "Warning: can't find '%s': value '%s' ignored\n", depbuf, saves[i].name); continue; } addDataDesc(run, dataNames[j], dataType, j); savesused[i] = TRUE; saves[i].used = 1; depind = j; } else { depind = run->data[j].outIndex; } } addSpecialDesc(run, saves[i].name, namebuf, parambuf, depind); } if (numsaves) { for (i = 0; i < numsaves; i++) { tfree(saves[i].analysis); tfree(saves[i].name); } tfree(saves); tfree(savesused); } if (numNames && ((run->numData == 1 && run->refIndex != -1) || (run->numData == 0 && run->refIndex == -1))) { fprintf(cp_err, "Error: no data saved for %s; analysis not run\n", spice_analysis_get_description(analysisPtr->JOBtype)); return E_NOTFOUND; } /* Now that we have our own data structures built up, let's see what * nutmeg wants us to do. */ run->writeOut = ft_getOutReq(&run->fp, &run->runPlot, &run->binary, run->type, run->name); if (run->writeOut) { fileInit(run); } else { plotInit(run); if (refName) run->runPlot->pl_ndims = 1; } } /* define storage for old and new data, to allow interpolation */ if (interpolated && run->circuit->CKTcurJob->JOBtype == 4) { valueold = TMALLOC(double, run->numData); for (i = 0; i < run->numData; i++) valueold[i] = 0.0; valuenew = TMALLOC(double, run->numData); }
void com_meas(wordlist *wl) { /* wl: in, input line of meas command */ char *line_in, *outvar; wordlist *wl_count, *wl_let; char *vec_found, *token, *equal_ptr; wordlist *wl_index; struct dvec *d; int err = 0; int fail; double result = 0; if (!wl) { com_display(NULL); return; } wl_count = wl; /* check each wl entry, if it contain '=' and if the following token is a single valued vector. If yes, replace this vector by its value. Vectors may stem from other meas commands, or be generated elsewhere within the .control .endc script. All other right hand side vectors are treated in com_measure2.c. */ wl_index = wl; while (wl_index) { token = wl_index->wl_word; /* find the vector vec_found, next token after each '=' sign. May be in the next wl_word */ if (token[strlen(token) - 1] == '=') { wl_index = wl_index->wl_next; vec_found = wl_index->wl_word; /* token may be already a value, maybe 'LAST', which we have to keep, or maybe a vector */ if (!cieq(vec_found, "LAST")) { INPevaluate(&vec_found, &err, 1); /* if not a valid number */ if (err) { /* check if vec_found is a valid vector */ d = vec_get(vec_found); /* Only if we have a single valued vector, replacing of the rigt hand side does make sense */ if (d && (d->v_length == 1) && (d->v_numdims == 1)) { /* get its value */ wl_index->wl_word = tprintf("%e", d->v_realdata[0]); tfree(vec_found); } } } } /* may be inside the same wl_word */ else if ((equal_ptr = strstr(token, "=")) != NULL) { vec_found = equal_ptr + 1; if (!cieq(vec_found, "LAST")) { INPevaluate(&vec_found, &err, 1); if (err) { d = vec_get(vec_found); /* Only if we have a single valued vector, replacing of the rigt hand side does make sense */ if (d && (d->v_length == 1) && (d->v_numdims == 1)) { int lhs_len = (int)(equal_ptr - token); wl_index->wl_word = tprintf("%.*s=%e", lhs_len, token, d->v_realdata[0]); tfree(token); } } } } else { ; // nothing } wl_index = wl_index->wl_next; } line_in = wl_flatten(wl); /* get output var name */ wl_count = wl_count->wl_next; if (!wl_count) { fprintf(stdout, " meas %s failed!\n" " unspecified output var name\n\n", line_in); return; } outvar = wl_count->wl_word; fail = get_measure2(wl, &result, NULL, FALSE); if (fail) { fprintf(stdout, " meas %s failed!\n\n", line_in); return; } wl_let = wl_cons(tprintf("%s = %e", outvar, result), NULL); com_let(wl_let); wl_free(wl_let); tfree(line_in); }
void INPpas3(CKTcircuit *ckt, card *data, INPtables *tab, TSKtask *task, IFparm *nodeParms, int numNodeParms) { card *current; int error; /* used by the macros defined above */ char *line; /* the part of the current line left to parse */ char *token=NULL; /* a token from the line */ IFparm *prm; /* pointer to parameter to search through array */ IFvalue ptemp; /* a value structure to package resistance into */ int which; /* which analysis we are performing */ CKTnode *node1; /* the first node's node pointer */ NG_IGNORE(task); #ifdef TRACE /* SDB debug statement */ printf("In INPpas3 . . . \n"); #endif for(current = data; current != NULL; current = current->nextcard) { line = current->line; FREE(token); INPgetTok(&line,&token,1); if (strcmp(token,".nodeset")==0) { which = -1; for(prm = nodeParms; prm < nodeParms + numNodeParms; prm++) { if(strcmp(prm->keyword,"nodeset")==0) { which = prm->id; break; } } if(which == -1) { LITERR("nodeset unknown to simulator. \n"); goto quit; } for(;;) { char *name; /* the node's name */ /* loop until we run out of data */ INPgetTok(&line,&name,1); if( *name == '\0') { FREE(name); break; /* end of line */ } /* If we have 'all = value' , then set all voltage nodes to 'value', except for ground node at node->number 0 */ if ( cieq(name, "all")) { ptemp.rValue = INPevaluate(&line,&error,1); for (node1 = ckt->CKTnodes; node1 != NULL; node1 = node1->next) { if ((node1->type == SP_VOLTAGE) && (node1->number > 0)) IFC(setNodeParm, (ckt, node1, which, &ptemp, NULL)); } FREE(name); break; } /* check to see if in the form V(xxx) and grab the xxx */ if( (*name == 'V' || *name == 'v') && !name[1] ) { /* looks like V - must be V(xx) - get xx now*/ char *nodename; INPgetTok(&line,&nodename,1); if (INPtermInsert(ckt,&nodename,tab,&node1)!=E_EXISTS) fprintf(stderr, "Warning : Nodeset on non-existant node - %s\n", nodename); ptemp.rValue = INPevaluate(&line,&error,1); IFC(setNodeParm, (ckt, node1, which, &ptemp, NULL)); FREE(name); continue; } LITERR(" Error: .nodeset syntax error.\n"); FREE(name); break; } } else if ((strcmp(token,".ic") == 0)) { /* .ic */ which = -1; for(prm = nodeParms; prm < nodeParms + numNodeParms; prm++) { if(strcmp(prm->keyword,"ic")==0) { which = prm->id; break; } } if(which==-1) { LITERR("ic unknown to simulator. \n"); goto quit; } for(;;) { char *name; /* the node's name */ /* loop until we run out of data */ INPgetTok(&line,&name,1); /* check to see if in the form V(xxx) and grab the xxx */ if( *name == '\0') { FREE(name); break; /* end of line */ } if( (*name == 'V' || *name == 'v') && !name[1] ) { /* looks like V - must be V(xx) - get xx now*/ char *nodename; INPgetTok(&line,&nodename,1); if (INPtermInsert(ckt,&nodename,tab,&node1)!=E_EXISTS) fprintf(stderr, "Warning : IC on non-existant node - %s\n", nodename); ptemp.rValue = INPevaluate(&line,&error,1); IFC(setNodeParm, (ckt, node1, which, &ptemp, NULL)); FREE(name); continue; } LITERR(" Error: .ic syntax error.\n"); FREE(name); break; } } } quit: FREE(token); return; }
/* Find a named vector in a plot. We are careful to copy the vector if * v_link2 is set, because otherwise we will get screwed up. */ static struct dvec * findvec(char *word, struct plot *pl) { SPICE_DSTRING dbuf; /* dynamic buffer */ char *lower_name; /* lower case name */ char *node_name; struct dvec *d, *newv = NULL, *end = NULL, *v; if (pl == NULL) return (NULL); if (cieq(word, "all")) { for (d = pl->pl_dvecs; d; d = d->v_next) { if (d->v_flags & VF_PERMANENT) { if (d->v_link2) { v = vec_copy(d); vec_new(v); } else { v = d; } if (end) end->v_link2 = v; else newv = v; end = v; } } return (newv); } if (cieq(word, "allv")) { for (d = pl->pl_dvecs; d; d = d->v_next) { if ((d->v_flags & VF_PERMANENT) && (d->v_type == SV_VOLTAGE)) { if (d->v_link2) { v = vec_copy(d); vec_new(v); } else { v = d; } if (end) end->v_link2 = v; else newv = v; end = v; } } return (newv); } if (cieq(word, "alli")) { for (d = pl->pl_dvecs; d; d = d->v_next) { if ((d->v_flags & VF_PERMANENT) && (d->v_type == SV_CURRENT)) { if (d->v_link2) { v = vec_copy(d); vec_new(v); } else { v = d; } if (end) end->v_link2 = v; else newv = v; end = v; } } return (newv); } if (cieq(word, "ally")) { for (d = pl->pl_dvecs; d; d = d->v_next) { if ((d->v_flags & VF_PERMANENT) && (!cieq(d->v_name, pl->pl_scale->v_name))) { if (d->v_link2) { v = vec_copy(d); vec_new(v); } else { v = d; } if (end) end->v_link2 = v; else newv = v; end = v; } } return (newv); } if (!pl->pl_lookup_valid) vec_rebuild_lookup_table(pl); spice_dstring_init(&dbuf); lower_name = spice_dstring_append_lower(&dbuf, word, -1); for (d = nghash_find(pl->pl_lookup_table, lower_name); d; d = nghash_find_again(pl->pl_lookup_table, lower_name)) { if (d->v_flags & VF_PERMANENT) break; } if (!d) { spice_dstring_reinit(&dbuf); spice_dstring_append(&dbuf, "v(", -1); spice_dstring_append_lower(&dbuf, word, -1); node_name = spice_dstring_append_char(&dbuf, ')'); for (d = nghash_find(pl->pl_lookup_table, node_name); d; d = nghash_find_again(pl->pl_lookup_table, node_name)) { if (d->v_flags & VF_PERMANENT) break; } } spice_dstring_free(&dbuf); #ifdef XSPICE /* gtri - begin - Add processing for getting event-driven vector */ if (!d) d = EVTfindvec(word); /* gtri - end - Add processing for getting event-driven vector */ #endif if (d && d->v_link2) { d = vec_copy(d); vec_new(d); } return (d); }
struct dvec * vec_get(const char *vec_name) { struct dvec *d, *end = NULL, *newv = NULL; struct plot *pl; char buf[BSIZE_SP], *s, *wd, *word, *whole, *name = NULL, *param; int i = 0; struct variable *vv; wd = word = copy(vec_name); /* Gets mangled below... */ if (strchr(word, '.')) { /* Snag the plot... */ for (i = 0, s = word; *s != '.'; i++, s++) buf[i] = *s; buf[i] = '\0'; if (cieq(buf, "all")) { word = ++s; pl = NULL; /* NULL pl signifies a wildcard. */ } else { for (pl = plot_list; pl && !plot_prefix(buf, pl->pl_typename); pl = pl->pl_next) ; if (pl) { word = ++s; } else { /* This used to be an error... */ pl = plot_cur; } } } else { pl = plot_cur; } if (pl) { d = vec_fromplot(word, pl); if (!d) d = vec_fromplot(word, &constantplot); } else { for (pl = plot_list; pl; pl = pl->pl_next) { if (cieq(pl->pl_typename, "const")) continue; d = vec_fromplot(word, pl); if (d) { if (end) end->v_link2 = d; else newv = d; for (end = d; end->v_link2; end = end->v_link2) ; } } d = newv; if (!d) { fprintf(cp_err, "Error: plot wildcard (name %s) matches nothing\n", word); tfree(wd); /* MW. I don't want core leaks here */ return (NULL); } } if (!d && (*word == SPECCHAR)) { /* This is a special quantity... */ if (ft_nutmeg) { fprintf(cp_err, "Error: circuit parameters only available with spice\n"); tfree(wd); /* MW. Memory leak fixed again */ return (NULL); /* va: use NULL */ } whole = copy(word); name = ++word; for (param = name; *param && (*param != '['); param++) ; if (*param) { *param++ = '\0'; for (s = param; *s && *s != ']'; s++) ; *s = '\0'; } else { param = NULL; } if (ft_curckt) { /* * This is what is done in case of "alter r1 resistance = 1234" * r1 resistance, 0 * if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model); */ /* vv = if_getparam (ft_curckt->ci_ckt, &name, param, 0, 0); */ vv = if_getparam(ft_curckt->ci_ckt, &name, param, 0, 0); if (!vv) { tfree(whole); tfree(wd); return (NULL); } } else { fprintf(cp_err, "Error: No circuit loaded.\n"); tfree(whole); tfree(wd); return (NULL); } d = alloc(struct dvec); ZERO(d, struct dvec); d->v_name = copy(whole); /* MW. The same as word before */ d->v_type = SV_NOTYPE; d->v_flags |= VF_REAL; /* No complex values yet... */ d->v_realdata = TMALLOC(double, 1); d->v_length = 1; /* In case the represented variable is a REAL vector this takes * the actual value of the first element of the linked list which * does not make sense. * This is an error. */ /* This will copy the contents of the structure vv in another structure * dvec (FTEDATA.H) that do not have INTEGER so that those parameters * defined as IF_INTEGER are not given their value when using * print @pot[pos_node] * To fix this, it is necessary to define: * OPU( "pos_node", POT_QUEST_POS_NODE, IF_REAL,"Positive node of potenciometer"), * int POTnegNode; // number of negative node of potenciometer (Nodo_3) * case POT_QUEST_POS_NODE: * value->rValue = (double)fast->POTposNode; * return (OK); * Works but with the format 1.00000E0 */ /* We must make a change in format between the data that carries a variable to * put in a dvec. */ /* * #define va_bool va_V.vV_bool * #define va_num va_V.vV_num * #define va_real va_V.vV_real * #define va_string va_V.vV_string * #define va_vlist va_V.vV_list * enum cp_types { * CP_BOOL, * CP_NUM, * CP_REAL, * CP_STRING, * CP_LIST ° }; */ /* The variable is a vector */ if (vv->va_type == CP_LIST) { /* Compute the length of the vector, * used with the parameters of isrc and vsrc */ struct variable *nv; double *list; list = TMALLOC(double, 1); nv = alloc(struct variable); nv = vv->va_vlist; for (i = 1; ; i++) { list = TREALLOC(double, list, i); list[i-1] = nv->va_real; nv = nv->va_next; if (!nv) break; } d->v_realdata = list; d->v_length = i; /* To be able to identify the vector to represent * belongs to a special "conunto" and should be printed in a * special way. */ d->v_dims[1] = 1; } else if (vv->va_type == CP_NUM) { /* Variable is an integer */ *d->v_realdata = (double) vv->va_num; } else if (vv->va_type == CP_REAL) { /* Variable is a real */ if (!(vv->va_next)) { /* Only a real data * usually normal */ *d->v_realdata = vv->va_real; } else { /* Real data set * When you print a model @ [all] * Just print numerical values, not the string */ struct variable *nv; /* We go to print the list of values * nv->va_name = Parameter description * nv->va_string = Parameter * nv->va_real= Value */ nv = vv; for (i = 1; ; i++) { switch (nv->va_type) { case CP_REAL: fprintf(stdout, "%s=%g\n", nv->va_name, nv->va_real); break; case CP_STRING: fprintf(stdout, "%s=%s\n", nv->va_name, nv->va_string); break; case CP_NUM: fprintf(stdout, "%s=%d\n", nv->va_name, nv->va_num); break; default: { fprintf(stderr, "ERROR: enumeration value `CP_BOOL' or `CP_LIST' not handled in vec_get\nAborting...\n"); controlled_exit(EXIT_FAILURE); } } nv = nv->va_next; if (!nv) break; } /* To distinguish those does not take anything for print screen to * make a print or M1 @ @ M1 [all] leaving only the correct data * and not the last */ d->v_rlength = 1; } } tfree(vv->va_name); tfree(vv); /* va: tfree vv->va_name and vv (avoid memory leakages) */ tfree(wd); vec_new(d); tfree(whole); return (d); }
int WIN_Init( ) { char colorstring[BSIZE_SP]; /* Initialization of display descriptor */ dispdev->width = GetSystemMetrics( SM_CXSCREEN); dispdev->height = GetSystemMetrics( SM_CYSCREEN); dispdev->numlinestyles = 5; /* see implications in WinPrint! */ dispdev->numcolors = NumWinColors; /* always, user may have set color0 to white */ /* get background color information from spinit, only "white" is recognized as a suitable option! */ if (cp_getvar("color0", CP_STRING, colorstring)) { if (cieq(colorstring, "white")) isblack = FALSE; else isblack = TRUE; } /* get linewidth information from spinit */ if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth)) linewidth = 0; if (linewidth < 0) linewidth = 0; /* only for the first time: */ if (!IsRegistered) { isblackold = isblack; /* get linewidth information from spinit if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth)) linewidth = 0; if (linewidth < 0) linewidth = 0; */ /* Initialize colors */ if (isblack) { ColorTable[0] = RGB( 0, 0, 0); /* black = background */ ColorTable[1] = RGB(255,255,255); /* white = text and grid */ } else { ColorTable[0] = RGB(255,255,255); /* white = background */ ColorTable[1] = RGB( 0, 0, 0); /* black = text and grid */ } ColorTable[2] = RGB( 0,255, 0); /* green = first line */ ColorTable[3] = RGB(255, 0, 0); /* red */ ColorTable[4] = RGB( 0, 0,255); /* blue */ ColorTable[5] = RGB(255,255, 0); /* yellow */ ColorTable[6] = RGB(255, 0,255); /* violett */ ColorTable[7] = RGB( 0,255,255); /* azur */ ColorTable[8] = RGB(255,128, 0); /* orange */ ColorTable[9] = RGB(128, 64, 0); /* brown */ ColorTable[10]= RGB(128, 0,255); /* light violett */ ColorTable[11]= RGB(255,128,128); /* pink */ /* 2. color bank (with different line style */ if (isblack) ColorTable[12]= RGB(255,255,255); /* white */ else ColorTable[12]= RGB( 0, 0, 0); /* black */ ColorTable[13]= RGB( 0,255, 0); /* green */ ColorTable[14]= RGB(255, 0, 0); /* red */ ColorTable[15]= RGB( 0, 0,255); /* blue */ ColorTable[16]= RGB(255,255, 0); /* yellow */ ColorTable[17]= RGB(255, 0,255); /* violett */ ColorTable[18]= RGB( 0,255,255); /* azur */ ColorTable[19]= RGB(255,128, 0); /* orange */ ColorTable[20]= RGB(128, 64, 0); /* brown */ ColorTable[21]= RGB(128, 0,255); /* light violett */ ColorTable[22]= RGB(255,128,128); /* pink */ /* Ansii fixed font */ PlotFont = GetStockFont( ANSI_FIXED_FONT); /* register window class */ TheWndClass.lpszClassName = WindowName; TheWndClass.hInstance = hInst; TheWndClass.lpfnWndProc = PlotWindowProc; TheWndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; TheWndClass.lpszMenuName = NULL; TheWndClass.hCursor = LoadCursor(NULL, IDC_ARROW); if (isblack) TheWndClass.hbrBackground = GetStockObject( BLACK_BRUSH); else TheWndClass.hbrBackground = GetStockObject( WHITE_BRUSH); TheWndClass.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(2)); TheWndClass.cbClsExtra = 0; TheWndClass.cbWndExtra = sizeof(GRAPH *); if (!RegisterClass(&TheWndClass)) return 1; } /* not first time */ else if (isblackold != isblack) { if (isblack) { ColorTable[0] = RGB( 0, 0, 0); /* black = background */ ColorTable[1] = RGB(255,255,255); /* white = text and grid */ } else { ColorTable[0] = RGB(255,255,255); /* white = background */ ColorTable[1] = RGB( 0, 0, 0); /* black = text and grid */ } if (isblack) ColorTable[12]= RGB(255,255,255); /* white */ else ColorTable[12]= RGB( 0, 0, 0); /* black */ isblackold=isblack; } IsRegistered = 1; /* ready */ return (0); }
void ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, struct dvec *vecs) { FILE *file, *file_data; struct dvec *v, *scale = NULL; double xval, yval, extrange; int i, numVecs, linewidth, err, terminal_type; bool xlog, ylog, nogrid, markers; char buf[BSIZE_SP], pointstyle[BSIZE_SP], *text, plotstyle[BSIZE_SP], terminal[BSIZE_SP]; char filename_data[128]; char filename_plt[128]; sprintf(filename_data, "%s.data", filename); sprintf(filename_plt, "%s.plt", filename); /* Sanity checking. */ for (v = vecs, numVecs = 0; v; v = v->v_link2) numVecs++; if (numVecs == 0) { return; } else if (numVecs > GP_MAXVECTORS) { fprintf(cp_err, "Error: too many vectors for gnuplot.\n"); return; } if (fabs((ylims[1]-ylims[0])/ylims[0]) < 1.0e-6) { fprintf(cp_err, "Error: range min ... max too small for using gnuplot.\n"); fprintf(cp_err, " Consider plotting with offset %g.\n", ylims[0]); return; } extrange = 0.05 * (ylims[1] - ylims[0]); if (!cp_getvar("gnuplot_terminal", CP_STRING, terminal)) { terminal_type = 1; } else { terminal_type = 1; if (cieq(terminal,"png")) terminal_type = 2; } if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth)) linewidth = 1; if (linewidth < 1) linewidth = 1; if (!cp_getvar("pointstyle", CP_STRING, pointstyle)) { markers = FALSE; } else { if (cieq(pointstyle,"markers")) markers = TRUE; else markers = FALSE; } /* Make sure the gridtype is supported. */ switch (gridtype) { case GRID_LIN: nogrid = xlog = ylog = FALSE; break; case GRID_XLOG: xlog = TRUE; nogrid = ylog = FALSE; break; case GRID_YLOG: ylog = TRUE; nogrid = xlog = FALSE; break; case GRID_LOGLOG: xlog = ylog = TRUE; nogrid = FALSE; break; case GRID_NONE: nogrid = TRUE; xlog = ylog = FALSE; break; default: fprintf(cp_err, "Error: grid type unsupported by gnuplot.\n"); return; } /* Open the output gnuplot file. */ if ((file = fopen(filename_plt, "w")) == NULL) { perror(filename); return; } /* Set up the file header. */ #if !defined(__MINGW__) && !defined(_MSC_VER) fprintf(file, "set terminal X11\n"); #endif if (title) { text = cp_unquote(title); fprintf(file, "set title \"%s\"\n", text); tfree(text); } if (xlabel) { text = cp_unquote(xlabel); fprintf(file, "set xlabel \"%s\"\n", text); tfree(text); } if (ylabel) { text = cp_unquote(ylabel); fprintf(file, "set ylabel \"%s\"\n", text); tfree(text); } if (!nogrid) { if (linewidth > 1) fprintf(file, "set grid lw %d \n" , linewidth); else fprintf(file, "set grid\n"); } if (xlog) { fprintf(file, "set logscale x\n"); if (xlims) fprintf(file, "set xrange [%1.0e:%1.0e]\n", pow(10, floor(log10(xlims[0]))), pow(10, ceil(log10(xlims[1])))); fprintf(file, "set xrange [%e:%e]\n", xlims[0], xlims[1]); fprintf(file, "set mxtics 10\n"); fprintf(file, "set grid mxtics\n"); } else { fprintf(file, "unset logscale x \n"); if (xlims) fprintf(file, "set xrange [%e:%e]\n", xlims[0], xlims[1]); } if (ylog) { fprintf(file, "set logscale y \n"); if (ylims) fprintf(file, "set yrange [%1.0e:%1.0e]\n", pow(10, floor(log10(ylims[0]))), pow(10, ceil(log10(ylims[1])))); fprintf(file, "set mytics 10\n"); fprintf(file, "set grid mytics\n"); } else { fprintf(file, "unset logscale y \n"); if (ylims) fprintf(file, "set yrange [%e:%e]\n", ylims[0] - extrange, ylims[1] + extrange); } fprintf(file, "#set xtics 1\n"); fprintf(file, "#set x2tics 1\n"); fprintf(file, "#set ytics 1\n"); fprintf(file, "#set y2tics 1\n"); if (linewidth > 1) fprintf(file, "set border lw %d\n", linewidth); if (plottype == PLOT_COMB) { strcpy(plotstyle, "boxes"); } else if (plottype == PLOT_POINT) { if (markers) { // fprintf(file, "Markers: True\n"); } else { // fprintf(file, "LargePixels: True\n"); } strcpy(plotstyle, "points"); } else { strcpy(plotstyle, "lines"); } /* Open the output gnuplot data file. */ if ((file_data = fopen(filename_data, "w")) == NULL) { perror(filename); return; } fprintf(file, "set format y \"%%g\"\n"); fprintf(file, "set format x \"%%g\"\n"); fprintf(file, "plot "); i = 0; /* Write out the gnuplot command */ for (v = vecs; v; v = v->v_link2) { scale = v->v_scale; if (v->v_name) { i = i + 2; if (i > 2) fprintf(file, ",\\\n"); fprintf(file, "\'%s\' using %d:%d with %s lw %d title \"%s\" ", filename_data, i-1, i, plotstyle, linewidth, v->v_name); } } fprintf(file, "\n"); fprintf(file, "set terminal push\n"); if (terminal_type == 1) { fprintf(file, "set terminal postscript eps color\n"); fprintf(file, "set out \'%s.eps\'\n", filename); } else { fprintf(file, "set terminal png\n"); fprintf(file, "set out \'%s.png\'\n", filename); } fprintf(file, "replot\n"); fprintf(file, "set term pop\n"); fprintf(file, "replot\n"); (void) fclose(file); /* Write out the data and setup arrays */ for (i = 0; i < scale->v_length; i++) { for (v = vecs; v; v = v->v_link2) { scale = v->v_scale; xval = isreal(scale) ? scale->v_realdata[i] : realpart(scale->v_compdata[i]); yval = isreal(v) ? v->v_realdata[i] : realpart(v->v_compdata[i]); fprintf(file_data, "%e %e ", xval, yval); } fprintf(file_data, "\n"); } (void) fclose(file_data); #if defined(__MINGW32__) || defined(_MSC_VER) /* for external fcn system() */ // (void) sprintf(buf, "start /B wgnuplot %s -" , filename_plt); (void) sprintf(buf, "start /B wgnuplot -persist %s " , filename_plt); _flushall(); #else /* for external fcn system() from LINUX environment */ (void) sprintf(buf, "xterm -e gnuplot %s - &", filename_plt); #endif err = system(buf); }
void ft_xgraph(double *xlims, double *ylims, char *filename, char *title, char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, struct dvec *vecs) { FILE *file; struct dvec *v, *scale; double xval, yval; int i, numVecs, linewidth; bool xlog, ylog, nogrid, markers; char buf[BSIZE_SP], pointstyle[BSIZE_SP], *text; /* Sanity checking. */ for (v = vecs, numVecs = 0; v; v = v->v_link2) numVecs++; if (numVecs == 0) { return; } else if (numVecs > XG_MAXVECTORS) { fprintf(cp_err, "Error: too many vectors for Xgraph.\n"); return; } if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth)) linewidth = 1; if (linewidth < 1) linewidth = 1; if (!cp_getvar("pointstyle", CP_STRING, pointstyle)) { markers = FALSE; } else { if (cieq(pointstyle, "markers")) markers = TRUE; else markers = FALSE; } /* Make sure the gridtype is supported. */ switch (gridtype) { case GRID_LIN: nogrid = xlog = ylog = FALSE; break; case GRID_XLOG: xlog = TRUE; nogrid = ylog = FALSE; break; case GRID_YLOG: ylog = TRUE; nogrid = xlog = FALSE; break; case GRID_LOGLOG: xlog = ylog = TRUE; nogrid = FALSE; break; case GRID_NONE: nogrid = TRUE; xlog = ylog = FALSE; break; default: fprintf(cp_err, "Error: grid type unsupported by Xgraph.\n"); return; } /* Open the output file. */ if ((file = fopen(filename, "w")) == NULL) { perror(filename); return; } /* Set up the file header. */ if (title) { text = cp_unquote(title); fprintf(file, "TitleText: %s\n", text); tfree(text); } if (xlabel) { text = cp_unquote(xlabel); fprintf(file, "XUnitText: %s\n", text); tfree(text); } if (ylabel) { text = cp_unquote(ylabel); fprintf(file, "YUnitText: %s\n", text); tfree(text); } if (nogrid) { fprintf(file, "Ticks: True\n"); } if (xlog) { fprintf(file, "LogX: True\n"); if (xlims) { fprintf(file, "XLowLimit: % e\n", log10(xlims[0])); fprintf(file, "XHighLimit: % e\n", log10(xlims[1])); } } else { if (xlims) { fprintf(file, "XLowLimit: % e\n", xlims[0]); fprintf(file, "XHighLimit: % e\n", xlims[1]); } } if (ylog) { fprintf(file, "LogY: True\n"); if (ylims) { fprintf(file, "YLowLimit: % e\n", log10(ylims[0])); fprintf(file, "YHighLimit: % e\n", log10(ylims[1])); } } else { if (ylims) { fprintf(file, "YLowLimit: % e\n", ylims[0]); fprintf(file, "YHighLimit: % e\n", ylims[1]); } } fprintf(file, "LineWidth: %d\n", linewidth); fprintf(file, "BoundBox: True\n"); if (plottype == PLOT_COMB) { fprintf(file, "BarGraph: True\n"); fprintf(file, "NoLines: True\n"); } else if (plottype == PLOT_POINT) { if (markers) fprintf(file, "Markers: True\n"); else fprintf(file, "LargePixels: True\n"); fprintf(file, "NoLines: True\n"); } /* Write out the data. */ for (v = vecs; v; v = v->v_link2) { scale = v->v_scale; if (v->v_name) fprintf(file, "\"%s\"\n", v->v_name); for (i = 0; i < scale->v_length; i++) { xval = isreal(scale) ? scale->v_realdata[i] : realpart(scale->v_compdata[i]); yval = isreal(v) ? v->v_realdata[i] : realpart(v->v_compdata[i]); fprintf(file, "% e % e\n", xval, yval); } fprintf(file, "\n"); } (void) fclose(file); (void) sprintf(buf, "xgraph %s &", filename); (void) system(buf); }
void com_quit(wordlist *wl) { int exitcode = EXIT_NORMAL; bool noask = (wl && wl->wl_word && 1 == sscanf(wl->wl_word, "%d", &exitcode)) || (wl && wl->wl_word && cieq(wl->wl_word, "noask")) || cp_getvar("noaskquit", CP_BOOL, NULL); /* update screen and reset terminal */ gr_clean(); cp_ccon(FALSE); /* Make sure the guy really wants to quit. */ if (!ft_nutmeg) if (!noask && !confirm_quit()) return; /* start to clean up the mess */ #ifdef SHARED_MODULE { wordlist all = { "all", NULL, NULL }; wordlist star = { "*", NULL, NULL }; // com_remcirc(NULL); com_destroy(&all); com_unalias(&star); com_undefine(&star); cp_remvar("history"); cp_remvar("noglob"); cp_remvar("brief"); cp_remvar("sourcepath"); cp_remvar("program"); cp_remvar("prompt"); } #endif #ifdef EXPERIMENTAL_CODE /* Destroy CKT when quit. Add by Gong Ding, [email protected] */ if (!ft_nutmeg) { struct circ *cc; for (cc = ft_circuits; cc; cc = cc->ci_next) if (SIMinfo.deleteCircuit) SIMinfo.deleteCircuit(cc->ci_ckt); } #endif #ifdef SHARED_MODULE /* Destroy CKT when quit. */ if (!ft_nutmeg) { while(ft_curckt) com_remcirc(NULL); } #endif DevSwitch(NULL); DevSwitch(NULL); /* then go away */ #ifdef SHARED_MODULE cp_destroy_keywords(); destroy_ivars(); #endif byemesg(); #ifdef SHARED_MODULE destroy_const_plot(); spice_destroy_devices(); #endif #ifdef SHARED_MODULE /* add 1000 to notify that we exit from 'quit' */ controlled_exit(1000 + exitcode); #else exit(exitcode); #endif }